From d698771b7aef89ab8cc1c29163a20c9efc604b68 Mon Sep 17 00:00:00 2001 From: Adrian Vollmer Date: Sat, 24 Sep 2022 19:29:34 +0200 Subject: [PATCH] init --- .gitignore | 46 ++++++++ LICENSE | 25 ++++ README.rst | 19 ++++ requirements.txt | 1 + setup.cfg | 46 ++++++++ setup.py | 9 ++ src/__init__.py | 0 src/__main__.py | 10 ++ src/app.py | 193 +++++++++++++++++++++++++++++++ src/args.py | 37 ++++++ src/embed.py | 232 ++++++++++++++++++++++++++++++++++++++ src/init.css | 60 ++++++++++ src/init.html | 1 + src/init.js | 88 +++++++++++++++ src/inject.js | 185 ++++++++++++++++++++++++++++++ src/pako.min.js | 2 + src/sphinxext/__init__.py | 8 ++ test-requirements.txt | 2 + tests/conftest.py | 9 ++ tox.ini | 32 ++++++ 20 files changed, 1005 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.rst create mode 100644 requirements.txt create mode 100644 setup.cfg create mode 100644 setup.py create mode 100644 src/__init__.py create mode 100644 src/__main__.py create mode 100644 src/app.py create mode 100644 src/args.py create mode 100644 src/embed.py create mode 100644 src/init.css create mode 100644 src/init.html create mode 100644 src/init.js create mode 100644 src/inject.js create mode 100644 src/pako.min.js create mode 100644 src/sphinxext/__init__.py create mode 100644 test-requirements.txt create mode 100644 tests/conftest.py create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a38518f --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +*.py[cod] + +# C extensions +*.so + +# Packages +*.egg* +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +cover/ +.coverage* +.tox +.venv +.pytest_cache/ +.mypy_cache/ + +# Translations +*.mo + +# Complexity +output/*.html +output/*/index.html + +# pbr +AUTHORS +ChangeLog + +# Editors +*~ +.*.swp +.*sw? diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..58c7830 --- /dev/null +++ b/LICENSE @@ -0,0 +1,25 @@ +Copyright (c) 2022 by Adrian Vollmer +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..10cbaa3 --- /dev/null +++ b/README.rst @@ -0,0 +1,19 @@ +======================================== +sphinxcontrib-sphinx-self-contained-html +======================================== + +.. image:: https://travis-ci.org/AdrianVollmer/sphinxcontrib-sphinx-self-contained-html.svg?branch=master + :target: https://travis-ci.org/AdrianVollmer/sphinxcontrib-sphinx-self-contained-html + +A Sphinx extension that allows generating completely self-contained HTML documents + +Overview +-------- + +Add a longer description here. + +Links +----- + +- Source: https://github.com/AdrianVollmer/sphinxcontrib-sphinx-self-contained-html +- Bugs: https://github.com/AdrianVollmer/sphinxcontrib-sphinx-self-contained-html/issues diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..1d45dc6 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pbr diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..90dee15 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,46 @@ +[metadata] +name = self-contained-html +summary = Convert distributed HTML docs to completely self-contained HTML docs +description_file = README.rst +author = Adrian Vollmer +author_email = computerfluesterer@protonmail.com +home_page = https://github.com/AdrianVollmer/self-contained-html +classifier = + Development Status :: 3 - Alpha + Environment :: Console + Environment :: Web Environment + Framework :: Sphinx :: Extension + Intended Audience :: Developers + License :: OSI Approved :: BSD License + Operating System :: OS Independent + Programming Language :: Python + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 + Topic :: Documentation + Topic :: Documentation :: Sphinx + Topic :: Utilities + +[options.entry_points] +console_scripts = + bundle-html = src.__main__:main + +[files] +packages = src + +[mypy] +python_version = 3.8 +show_column_numbers = True +show_error_context = True +ignore_missing_imports = True +follow_imports = skip +incremental = True +check_untyped_defs = True +warn_unused_ignores = True + +[flake8] +show-source = True +builtins = unicode +max-line-length = 100 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..f7fce87 --- /dev/null +++ b/setup.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +import setuptools + + +setuptools.setup( + setup_requires=['pbr'], + pbr=True, +) diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/__main__.py b/src/__main__.py new file mode 100644 index 0000000..697e138 --- /dev/null +++ b/src/__main__.py @@ -0,0 +1,10 @@ +def main(): + from .args import parse_args + args = parse_args() + + from .embed import embed_assets + embed_assets(args.path) + + +if __name__ == "__main__": + pass diff --git a/src/app.py b/src/app.py new file mode 100644 index 0000000..671a922 --- /dev/null +++ b/src/app.py @@ -0,0 +1,193 @@ +""" +Embed HTML assets. + +It creates an HTML file that has three script tags: + +1. A virtual file tree containing all assets in zipped form +2. The pako JS library to unzip the assets +3. Some boostrap code that fixes the HTML so it loads all assets from the +virtual file tree instead of the file system + +TODO: +* JS dependencies like mathjax don't work +* CSS delay noticable when using fonts +* CSS files can import other files with `@import` + +Author: Adrian Vollmer + +""" + +import base64 +from fnmatch import fnmatch +import json +import logging +import os +from pathlib import Path +import zlib + +SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__)) + +logger = logging.getLogger(__name__) + + +def embed_assets(index_file): + base_dir = os.path.dirname(index_file) + base_name = os.path.basename(index_file) + new_base_name = 'SELF_CONTAINED_' + base_name + result_file = os.path.join(base_dir, new_base_name) + file_tree = load_filetree(base_dir, exclude_pattern=new_base_name) + + file_tree = json.dumps(file_tree) + logger.debug('total asset size: %d' % len(file_tree)) + file_tree = deflate(file_tree) + logger.debug('total asset size (compressed): %d' % len(file_tree)) + + remote_resources = [] + + data = { + 'start_page': base_name, + 'file_tree': file_tree, + 'remote_resources': remote_resources, + } + + init_script = os.path.join(SCRIPT_PATH, 'init.js') + init_script = open(init_script, 'r').read() + + init_css = os.path.join(SCRIPT_PATH, 'init.css') + init_css = open(init_css, 'r').read() + + pako = os.path.join(SCRIPT_PATH, 'pako.min.js') + pako = open(pako, 'r').read() + + data = json.dumps(data) + + body = os.path.join(SCRIPT_PATH, 'init.html') + body = open(body, 'r').read() + + result = """ + + +{head} +{body} + + + + +""".format( + lang='en', + head='', + style=init_css, + data=data, + pako=pako, + body=body, + init_script=init_script, + ) + + with open(result_file, 'w') as fp: + fp.write(result) + + return result_file + + +def pack_file(filename): + _, ext = os.path.splitext(filename) + ext = ext.lower()[1:] + data = open(filename, 'rb').read() + if ext == 'css': + # assuming all CSS files have names ending in '.css' + data = embed_css_resources(data, filename) + + if ext in [ + 'png', 'jpg', 'jpeg', 'woff', 'woff2', 'eot', 'ttf', 'gif', 'ico', + ]: + # JSON doesn't allow binary data + data = base64.b64encode(data) + try: + data = data.decode() + except UnicodeError: + data = base64.b64encode(data).decode() + print(len(data), filename) + return data + + +def deflate(data): + data = zlib.compress(data.encode()) + data = base64.b64encode(data).decode() + return data + + +def embed_css_resources(css, rel_dir): + """Replace url() with url(data:;base64, ...)""" + # TODO handle @import + # This uses some heuristics which could technically fail + import re + + # Quotes are optional. But then URLs can contain escaped characters. + regex = ( + rb'''(?Purl\(['"]?(?P.*?)['"]?\))''' + rb'''(\s*format\(['"](?P.*?)['"]\))?''' + ) + + replace_rules = {} + + for m in re.finditer(regex, css): + if re.match(b'''['"]?data:.*''', m['url']): + continue + + path = m['url'].decode() + + if '?' in path: + path = path.split('?')[0] + if '#' in path: + path = path.split('#')[0] + + path = os.path.dirname(rel_dir) + '/' + path + + content = open(path, 'rb').read() + + # If it's binary, determine mime type and encode in base64 + if m['format']: + mime_type = 'font/' + m['format'].decode() + elif path[-3:].lower() == 'eot': + mime_type = 'font/eot' + elif path[-3:].lower() == 'css': + mime_type = 'text/css' + content = embed_css_resources(content, rel_dir) + else: + from io import BytesIO + from sphinx.util.images import guess_mimetype_for_stream + mime_type = guess_mimetype_for_stream(BytesIO(content)) + if not mime_type: + logger.error('Unable to determine mime type: %s' % path) + mime_type = 'application/octet-stream' + content = base64.b64encode(content) + + replace_rules[m['url_statement']] = \ + b'url("data:%(mime_type)s;charset=utf-8;base64, %(content)s")' % { + b'content': content, + b'mime_type': mime_type.encode(), + } + + for orig, new in replace_rules.items(): + css = css.replace(orig, new) + + return css + + +def load_filetree(base_dir, exclude_pattern=None): + """Load entire directory in a dict""" + + result = {} + base_dir = Path(base_dir) + for path in base_dir.rglob('*'): + if exclude_pattern and fnmatch(path.name, exclude_pattern): + continue + if path.is_file(): + key = '/' + path.relative_to(base_dir).as_posix() + result[key] = pack_file( + path.as_posix() + ) + logger.debug('Packed file %s [%d]' % (key, len(result[key]))) + + return result + diff --git a/src/args.py b/src/args.py new file mode 100644 index 0000000..b4398b5 --- /dev/null +++ b/src/args.py @@ -0,0 +1,37 @@ +import argparse + +try: + # importlib.metadata is present in Python 3.8 and later + import importlib.metadata as importlib_metadata +except ImportError: + # use the shim package importlib-metadata pre-3.8 + import importlib_metadata as importlib_metadata + +try: + __version__ = importlib_metadata.version(__package__ or __name__) + # __summary__ = importlib_metadata.metadata(__package__ or __name__)['summary'] + __summary__ = "Convert distributed HTML docs to completely self-contained HTML docs" +except importlib_metadata.PackageNotFoundError: + __version__ = "??" + __summary__ = "??" + + +parser = argparse.ArgumentParser( + description=__summary__, +) + +parser.add_argument( + '-v', '--version', action='version', + version=__version__, +) + +parser.add_argument( + 'path', + help='path to the root HTML file', +) + + +def parse_args(argv=None): + args = parser.parse_args(argv) + + return args diff --git a/src/embed.py b/src/embed.py new file mode 100644 index 0000000..e60d3b3 --- /dev/null +++ b/src/embed.py @@ -0,0 +1,232 @@ +""" +Embed HTML assets. + +It creates an HTML file that has three script tags: + +1. A virtual file tree containing all assets in zipped form +2. The pako JS library to unzip the assets +3. Some boostrap code that fixes the HTML so it loads all assets from the +virtual file tree instead of the file system + +TODO: +* JS dependencies like mathjax don't work +* CSS delay noticable when using fonts +* CSS files can import other files with `@import` + +Author: Adrian Vollmer + +""" + +import base64 +from fnmatch import fnmatch +import json +import logging +import os +from pathlib import Path +import zlib + +SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__)) + +logger = logging.getLogger(__name__) + + +def embed_assets(index_file): + + init_files = {} + for filename in [ + 'init.js', + 'inject.js', + 'init.css', + 'init.html', + 'pako.min.js', + ]: + path = os.path.join(SCRIPT_PATH, filename) + init_files[filename] = open(path, 'r').read() + + base_dir = os.path.dirname(index_file) + base_name = os.path.basename(index_file) + new_base_name = 'SELF_CONTAINED_' + base_name + result_file = os.path.join(base_dir, new_base_name) + + file_tree = load_filetree(base_dir, init_files['inject.js'], exclude_pattern=new_base_name) + file_tree = json.dumps(file_tree) + logger.debug('total asset size: %d' % len(file_tree)) + file_tree = deflate(file_tree) + logger.debug('total asset size (compressed): %d' % len(file_tree)) + + remote_resources = [] + + data = { + 'current_path': base_name, + 'file_tree': file_tree, + 'remote_resources': remote_resources, + } + data = json.dumps(data) + + result = """ + + + +{body} + + + + +""".format( + style=init_files['init.css'], + init_js=init_files['init.js'], + pako=init_files['pako.min.js'], + body=init_files['init.html'], + data=data, + ) + + with open(result_file, 'w') as fp: + fp.write(result) + + return result_file + + +def pack_file(filename, js): + _, ext = os.path.splitext(filename) + ext = ext.lower()[1:] + data = open(filename, 'rb').read() + if ext == 'css': + # assuming all CSS files have names ending in '.css' + data = embed_css_resources(data, filename) + + elif ext in [ + 'png', 'jpg', 'jpeg', 'woff', 'woff2', 'eot', 'ttf', 'gif', 'ico', + ]: + # JSON doesn't allow binary data + data = base64.b64encode(data) + + elif ext in ['html', 'htm']: + data = embed_html_resources(data, os.path.dirname(filename), js).encode() + + if not isinstance(data, str): + try: + data = data.decode() + except UnicodeError: + data = base64.b64encode(data).decode() + + logger.debug('loaded file: %s [%d]' % (filename, len(data))) + + return data + + +def deflate(data): + data = zlib.compress(data.encode()) + data = base64.b64encode(data).decode() + return data + + +def embed_html_resources(html, base_dir, js): + """Embed fonts in preload links to avoid jumps when loading""" + # This cannot be done in JavaScript, it would be too late + + # TODO set body.display = None? + + import bs4 + soup = bs4.BeautifulSoup(html, 'lxml') + + for link in soup.select('head > link[rel="preload"][as="font"]'): + # Get filename relative to resource + filename = os.path.join( + base_dir, + link['href'], # TODO convert from POSIX + ) + link['href'] = to_data_uri(filename, mime_type=link['type']) + + script = soup.new_tag("script") + script.string = js + soup.find('body').append(script) + + return str(soup) + + +def to_data_uri(filename, mime_type=None): + data = open(filename, 'br').read() + data = base64.b64encode(data) + if not mime_type: + mime_type = 'application/octet-stream' + return "data:%s;charset=utf-8;base64, %s" % ( + mime_type, + data.decode(), + ) + + +def embed_css_resources(css, filename): + """Replace url() with url(data:;base64, ...)""" + # TODO handle @import + # This uses some heuristics which could technically fail + import re + + # Quotes are optional. But then URLs can contain escaped characters. + regex = ( + rb'''(?Purl\(['"]?(?P.*?)['"]?\))''' + rb'''(\s*format\(['"](?P.*?)['"]\))?''' + ) + + replace_rules = {} + + for m in re.finditer(regex, css): + if re.match(b'''['"]?data:.*''', m['url']): + continue + + path = m['url'].decode() + + if '?' in path: + path = path.split('?')[0] + if '#' in path: + path = path.split('#')[0] + + path = os.path.dirname(filename) + '/' + path + + content = open(path, 'rb').read() + + # If it's binary, determine mime type and encode in base64 + if m['format']: + mime_type = 'font/' + m['format'].decode() + elif path[-3:].lower() == 'eot': + mime_type = 'font/eot' + elif path[-3:].lower() == 'css': + mime_type = 'text/css' + content = embed_css_resources(content, filename) + else: + from io import BytesIO + from sphinx.util.images import guess_mimetype_for_stream + mime_type = guess_mimetype_for_stream(BytesIO(content)) + if not mime_type: + logger.error('Unable to determine mime type: %s' % path) + mime_type = 'application/octet-stream' + content = base64.b64encode(content) + + replace_rules[m['url_statement']] = \ + b'url("data:%(mime_type)s;charset=utf-8;base64, %(content)s")' % { + b'content': content, + b'mime_type': mime_type.encode(), + } + + for orig, new in replace_rules.items(): + css = css.replace(orig, new) + + return css + + +def load_filetree(base_dir, js, exclude_pattern=None): + """Load entire directory in a dict""" + + result = {} + base_dir = Path(base_dir) + for path in base_dir.rglob('*'): + if exclude_pattern and fnmatch(path.name, exclude_pattern): + continue + if path.is_file(): + key = path.relative_to(base_dir).as_posix() + result[key] = pack_file( + path.as_posix(), + js, + ) + logger.debug('Packed file %s [%d]' % (key, len(result[key]))) + + return result diff --git a/src/init.css b/src/init.css new file mode 100644 index 0000000..5147362 --- /dev/null +++ b/src/init.css @@ -0,0 +1,60 @@ +#main { + /* TODO rename main to avoid collisions*/ + position:fixed; + top:0; left:0; bottom:0; right:0; + width:100%; + height:100%; + border:none; + margin:0; + padding:0; + overflow:hidden; + z-index:-1; +} +.lds-ripple { + display: block; + position: relative; + width: 80px; + height: 80px; + margin: auto; + z-index:1; +} +.lds-ripple div { + position: absolute; + border: 4px solid #aaa; + opacity: 1; + border-radius: 50%; + animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite; +} +.lds-ripple div:nth-child(2) { + animation-delay: -0.5s; +} +@keyframes lds-ripple { + 0% { + top: 36px; + left: 36px; + width: 0; + height: 0; + opacity: 0; + } + 4.9% { + top: 36px; + left: 36px; + width: 0; + height: 0; + opacity: 0; + } + 5% { + top: 36px; + left: 36px; + width: 0; + height: 0; + opacity: 1; + } + 100% { + top: 0px; + left: 0px; + width: 72px; + height: 72px; + opacity: 0; + } +} diff --git a/src/init.html b/src/init.html new file mode 100644 index 0000000..41b8a2b --- /dev/null +++ b/src/init.html @@ -0,0 +1 @@ +
diff --git a/src/init.js b/src/init.js new file mode 100644 index 0000000..fe62982 --- /dev/null +++ b/src/init.js @@ -0,0 +1,88 @@ +var _ArrayBufferToBase64 = function (array_buffer) { + var binary = ''; + var bytes = new Uint8Array(array_buffer); + var len = bytes.byteLength; + for (var i = 0; i < len; i++) { + binary += String.fromCharCode(bytes[i]) + } + return window.btoa(binary); +}; + + +var _base64ToArrayBuffer = function (base64) { + if (!base64) { return []} + var binary_string = window.atob(base64); + var len = binary_string.length; + var bytes = new Uint8Array(len); + for (var i = 0; i < len; i++) { + bytes[i] = binary_string.charCodeAt(i); + } + return bytes.buffer; +}; + +var createIframe = function() { + var iframe = document.getElementById('main'); + if (iframe) { iframe.remove() }; + iframe = document.createElement("iframe"); + window.document.body.prepend(iframe); + iframe.setAttribute('src', '#'); + iframe.setAttribute('name', 'main'); + iframe.setAttribute('id', 'main'); + iframe.style.display = 'none'; + return iframe; +} + +var load_virtual_page = (function (path, get_params, anchor) { + const data = window.data.file_tree[path]; + var iframe = createIframe(); + if (get_params) { iframe.src = path + '?' + get_params; } + else { iframe.src = path; } + iframe.contentDocument.write(data); + if (anchor) { iframe.contentDocument.location.hash = anchor; } + window.data.current_path = path; +}); + +window.onload = function() { + // Set up the virtual file tree + var FT = window.data.file_tree; + FT = _base64ToArrayBuffer(FT); + FT = pako.inflate(FT) + FT = new TextDecoder("utf-8").decode(FT); + FT = JSON.parse(FT); + window.data.file_tree = FT; + + // Set up message listener + window.addEventListener("message", (evnt) => { + console.log("Received message in parent", evnt); + if (evnt.data.action == 'set_title') { + // iframe has finished loading and sent us its title + // parent sets the title and responds with the data object + window.document.title = evnt.data.argument; + var iframe = document.getElementById('main'); + iframe.contentWindow.postMessage({ + action: "set_data", + argument: window.data, + }, "*"); + } else if (evnt.data.action == 'virtual_click') { + // user has clicked on a link in the iframe + var iframe = document.getElementById('main'); + iframe.remove() + var loading = document.getElementById('loading-indicator'); + loading.style.display = ''; + load_virtual_page( + evnt.data.argument.path, + evnt.data.argument.get_parameters, + evnt.data.argument.anchor, + ); + } else if (evnt.data.action == 'show_iframe') { + // iframe finished fixing the document + var iframe = document.getElementById('main'); + iframe.style.display = ''; + var loading = document.getElementById('loading-indicator'); + loading.style.display = 'none'; + } + }, false); + + // Load first page + load_virtual_page(window.data.current_path, "", ""); +} diff --git a/src/inject.js b/src/inject.js new file mode 100644 index 0000000..70d9fd1 --- /dev/null +++ b/src/inject.js @@ -0,0 +1,185 @@ +var embed_css = function(origin) { + Array.from(document.querySelectorAll("link")).forEach( link => { + if (link.getAttribute('rel') == 'stylesheet') { + const style = document.createElement("style"); + var href = link.getAttribute('href'); + let [path, get_parameters, anchor] = split_url(href); + path = normalize_path(path); + style.innerText = retrieve_file(path); + link.replaceWith(style); + }; + }); +}; + + +var embed_js = function(origin) { + Array.from(document.querySelectorAll("script")).forEach( oldScript => { + const newScript = document.createElement("script"); + Array.from(oldScript.attributes).forEach( attr => { + newScript.setAttribute(attr.name, attr.value); + }); + try { + if (newScript.hasAttribute('src') && is_virtual(newScript.getAttribute('src'))) { + var src = newScript.getAttribute('src'); + let [path, get_parameters, anchor] = split_url(src); + path = normalize_path(path); + var src = retrieve_file(path); + newScript.appendChild(document.createTextNode(src)); + newScript.removeAttribute('src'); + oldScript.parentNode.replaceChild(newScript, oldScript); + } + } catch (e) { + // Make sure all scripts are loaded + console.error(e); + } + }); +}; + + +var split_url = function(url) { + // Return a list of three elements: path, GET parameters, anchor + var anchor = url.split('#')[1] || ""; + var get_parameters = url.split('#')[0].split('?')[1] || ""; + var path = url.split('#')[0]; + path = path.split('?')[0]; + let result = [path, get_parameters, anchor]; + // console.log("Split URL", url, result); + return result; +} + + +var virtual_click = function(evnt) { + // Handle GET parameters and anchors + console.log("Virtual click", evnt); + var a = evnt.currentTarget; + let [path, get_parameters, anchor] = split_url(a.getAttribute('href')); + path = normalize_path(path); + + window.parent.postMessage({ + action: "virtual_click", + argument: { + path: path, + get_parameters: get_parameters, + anchor: anchor, + } + }, '*'); + evnt.preventDefault(); + evnt.stopPropagation(); + return false; +}; + +var fix_links = function(origin) { + Array.from(document.querySelectorAll("a")).forEach( a => { + if (is_virtual(a.getAttribute('href'))) { + a.addEventListener('click', virtual_click); + } + }); +}; + +var fix_forms = function(origin) { + Array.from(document.querySelectorAll("form")).forEach( form => { + var href = form.getAttribute('action'); + if (is_virtual(href)) { + // TODO test this + // let [path, get_parameters, anchor] = split_url(href); + // path = normalize_path(path); + // var new_href = to_blob(retrieve_file(path), 'text/html'); + // if (get_parameters) { new_href += '?' + get_parameters; } + // if (anchor) { new_href += '?' + anchor; } + // form.action = new_href; + } + }); +}; + + +var embed_img = function(origin) { + Array.from(document.querySelectorAll("img")).forEach( img => { + if (img.hasAttribute('src')) { + const src = img.getAttribute('src'); + if (is_virtual(src)) { + var path = normalize_path(src); + const file = retrieve_file(path); + // TODO handle mime type + if (file.startsWith(' { + if (component == '..') { + if (array) { + array.pop(); + } + } else if (component == '.') { + } else { + if (component) { array.push(component); } + } + }); + + result = array.join('/'); + // console.log(`Normalized path: ${path} -> ${result} (@${window.data.current_path})`); + return result; +}; + + +// Set up message listener +window.addEventListener("message", (evnt) => { + console.log("Received message in iframe", evnt); + if (evnt.data.action == 'set_data') { + window.data = evnt.data.argument; + console.log("Received data from parent", window.data); + // dynamically fix elements on this page + try { + embed_css(); + fix_links(); + fix_forms(); + embed_img(); + embed_js(); + } finally { + window.parent.postMessage({ + action: "show_iframe", + argument: "", + }, '*'); + } + } +}, false); + +// Set parent window title +window.parent.postMessage({ + action: "set_title", + argument: window.document.querySelector('head>title').innerText +}, '*'); diff --git a/src/pako.min.js b/src/pako.min.js new file mode 100644 index 0000000..5f0fee1 --- /dev/null +++ b/src/pako.min.js @@ -0,0 +1,2 @@ +/*! pako 2.0.4 https://github.com/nodeca/pako @license (MIT AND Zlib) */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).pako={})}(this,(function(t){"use strict";function e(t){let e=t.length;for(;--e>=0;)t[e]=0}const a=256,i=286,n=30,s=15,r=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]),l=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),o=new Uint8Array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]),h=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),d=new Array(576);e(d);const _=new Array(60);e(_);const f=new Array(512);e(f);const c=new Array(256);e(c);const u=new Array(29);e(u);const w=new Array(n);function b(t,e,a,i,n){this.static_tree=t,this.extra_bits=e,this.extra_base=a,this.elems=i,this.max_length=n,this.has_stree=t&&t.length}let g,p,m;function k(t,e){this.dyn_tree=t,this.max_code=0,this.stat_desc=e}e(w);const v=t=>t<256?f[t]:f[256+(t>>>7)],y=(t,e)=>{t.pending_buf[t.pending++]=255&e,t.pending_buf[t.pending++]=e>>>8&255},x=(t,e,a)=>{t.bi_valid>16-a?(t.bi_buf|=e<>16-t.bi_valid,t.bi_valid+=a-16):(t.bi_buf|=e<{x(t,a[2*e],a[2*e+1])},A=(t,e)=>{let a=0;do{a|=1&t,t>>>=1,a<<=1}while(--e>0);return a>>>1},E=(t,e,a)=>{const i=new Array(16);let n,r,l=0;for(n=1;n<=s;n++)i[n]=l=l+a[n-1]<<1;for(r=0;r<=e;r++){let e=t[2*r+1];0!==e&&(t[2*r]=A(i[e]++,e))}},R=t=>{let e;for(e=0;e{t.bi_valid>8?y(t,t.bi_buf):t.bi_valid>0&&(t.pending_buf[t.pending++]=t.bi_buf),t.bi_buf=0,t.bi_valid=0},U=(t,e,a,i)=>{const n=2*e,s=2*a;return t[n]{const i=t.heap[a];let n=a<<1;for(;n<=t.heap_len&&(n{let n,s,o,h,d=0;if(0!==t.last_lit)do{n=t.pending_buf[t.d_buf+2*d]<<8|t.pending_buf[t.d_buf+2*d+1],s=t.pending_buf[t.l_buf+d],d++,0===n?z(t,s,e):(o=c[s],z(t,o+a+1,e),h=r[o],0!==h&&(s-=u[o],x(t,s,h)),n--,o=v(n),z(t,o,i),h=l[o],0!==h&&(n-=w[o],x(t,n,h)))}while(d{const a=e.dyn_tree,i=e.stat_desc.static_tree,n=e.stat_desc.has_stree,r=e.stat_desc.elems;let l,o,h,d=-1;for(t.heap_len=0,t.heap_max=573,l=0;l>1;l>=1;l--)S(t,a,l);h=r;do{l=t.heap[1],t.heap[1]=t.heap[t.heap_len--],S(t,a,1),o=t.heap[1],t.heap[--t.heap_max]=l,t.heap[--t.heap_max]=o,a[2*h]=a[2*l]+a[2*o],t.depth[h]=(t.depth[l]>=t.depth[o]?t.depth[l]:t.depth[o])+1,a[2*l+1]=a[2*o+1]=h,t.heap[1]=h++,S(t,a,1)}while(t.heap_len>=2);t.heap[--t.heap_max]=t.heap[1],((t,e)=>{const a=e.dyn_tree,i=e.max_code,n=e.stat_desc.static_tree,r=e.stat_desc.has_stree,l=e.stat_desc.extra_bits,o=e.stat_desc.extra_base,h=e.stat_desc.max_length;let d,_,f,c,u,w,b=0;for(c=0;c<=s;c++)t.bl_count[c]=0;for(a[2*t.heap[t.heap_max]+1]=0,d=t.heap_max+1;d<573;d++)_=t.heap[d],c=a[2*a[2*_+1]+1]+1,c>h&&(c=h,b++),a[2*_+1]=c,_>i||(t.bl_count[c]++,u=0,_>=o&&(u=l[_-o]),w=a[2*_],t.opt_len+=w*(c+u),r&&(t.static_len+=w*(n[2*_+1]+u)));if(0!==b){do{for(c=h-1;0===t.bl_count[c];)c--;t.bl_count[c]--,t.bl_count[c+1]+=2,t.bl_count[h]--,b-=2}while(b>0);for(c=h;0!==c;c--)for(_=t.bl_count[c];0!==_;)f=t.heap[--d],f>i||(a[2*f+1]!==c&&(t.opt_len+=(c-a[2*f+1])*a[2*f],a[2*f+1]=c),_--)}})(t,e),E(a,d,t.bl_count)},O=(t,e,a)=>{let i,n,s=-1,r=e[1],l=0,o=7,h=4;for(0===r&&(o=138,h=3),e[2*(a+1)+1]=65535,i=0;i<=a;i++)n=r,r=e[2*(i+1)+1],++l{let i,n,s=-1,r=e[1],l=0,o=7,h=4;for(0===r&&(o=138,h=3),i=0;i<=a;i++)if(n=r,r=e[2*(i+1)+1],!(++l{x(t,0+(i?1:0),3),((t,e,a,i)=>{Z(t),i&&(y(t,a),y(t,~a)),t.pending_buf.set(t.window.subarray(e,e+a),t.pending),t.pending+=a})(t,e,a,!0)};var N={_tr_init:t=>{F||((()=>{let t,e,a,h,k;const v=new Array(16);for(a=0,h=0;h<28;h++)for(u[h]=a,t=0;t<1<>=7;h{let s,r,l=0;t.level>0?(2===t.strm.data_type&&(t.strm.data_type=(t=>{let e,i=4093624447;for(e=0;e<=31;e++,i>>>=1)if(1&i&&0!==t.dyn_ltree[2*e])return 0;if(0!==t.dyn_ltree[18]||0!==t.dyn_ltree[20]||0!==t.dyn_ltree[26])return 1;for(e=32;e{let e;for(O(t,t.dyn_ltree,t.l_desc.max_code),O(t,t.dyn_dtree,t.d_desc.max_code),T(t,t.bl_desc),e=18;e>=3&&0===t.bl_tree[2*h[e]+1];e--);return t.opt_len+=3*(e+1)+5+5+4,e})(t),s=t.opt_len+3+7>>>3,r=t.static_len+3+7>>>3,r<=s&&(s=r)):s=r=i+5,i+4<=s&&-1!==e?L(t,e,i,n):4===t.strategy||r===s?(x(t,2+(n?1:0),3),D(t,d,_)):(x(t,4+(n?1:0),3),((t,e,a,i)=>{let n;for(x(t,e-257,5),x(t,a-1,5),x(t,i-4,4),n=0;n(t.pending_buf[t.d_buf+2*t.last_lit]=e>>>8&255,t.pending_buf[t.d_buf+2*t.last_lit+1]=255&e,t.pending_buf[t.l_buf+t.last_lit]=255&i,t.last_lit++,0===e?t.dyn_ltree[2*i]++:(t.matches++,e--,t.dyn_ltree[2*(c[i]+a+1)]++,t.dyn_dtree[2*v(e)]++),t.last_lit===t.lit_bufsize-1),_tr_align:t=>{x(t,2,3),z(t,256,d),(t=>{16===t.bi_valid?(y(t,t.bi_buf),t.bi_buf=0,t.bi_valid=0):t.bi_valid>=8&&(t.pending_buf[t.pending++]=255&t.bi_buf,t.bi_buf>>=8,t.bi_valid-=8)})(t)}};var B=(t,e,a,i)=>{let n=65535&t|0,s=t>>>16&65535|0,r=0;for(;0!==a;){r=a>2e3?2e3:a,a-=r;do{n=n+e[i++]|0,s=s+n|0}while(--r);n%=65521,s%=65521}return n|s<<16|0};const C=new Uint32Array((()=>{let t,e=[];for(var a=0;a<256;a++){t=a;for(var i=0;i<8;i++)t=1&t?3988292384^t>>>1:t>>>1;e[a]=t}return e})());var M=(t,e,a,i)=>{const n=C,s=i+a;t^=-1;for(let a=i;a>>8^n[255&(t^e[a])];return-1^t},H={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"},j={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_MEM_ERROR:-4,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8};const{_tr_init:K,_tr_stored_block:P,_tr_flush_block:Y,_tr_tally:G,_tr_align:X}=N,{Z_NO_FLUSH:W,Z_PARTIAL_FLUSH:q,Z_FULL_FLUSH:J,Z_FINISH:Q,Z_BLOCK:V,Z_OK:$,Z_STREAM_END:tt,Z_STREAM_ERROR:et,Z_DATA_ERROR:at,Z_BUF_ERROR:it,Z_DEFAULT_COMPRESSION:nt,Z_FILTERED:st,Z_HUFFMAN_ONLY:rt,Z_RLE:lt,Z_FIXED:ot,Z_DEFAULT_STRATEGY:ht,Z_UNKNOWN:dt,Z_DEFLATED:_t}=j,ft=258,ct=262,ut=103,wt=113,bt=666,gt=(t,e)=>(t.msg=H[e],e),pt=t=>(t<<1)-(t>4?9:0),mt=t=>{let e=t.length;for(;--e>=0;)t[e]=0};let kt=(t,e,a)=>(e<{const e=t.state;let a=e.pending;a>t.avail_out&&(a=t.avail_out),0!==a&&(t.output.set(e.pending_buf.subarray(e.pending_out,e.pending_out+a),t.next_out),t.next_out+=a,e.pending_out+=a,t.total_out+=a,t.avail_out-=a,e.pending-=a,0===e.pending&&(e.pending_out=0))},yt=(t,e)=>{Y(t,t.block_start>=0?t.block_start:-1,t.strstart-t.block_start,e),t.block_start=t.strstart,vt(t.strm)},xt=(t,e)=>{t.pending_buf[t.pending++]=e},zt=(t,e)=>{t.pending_buf[t.pending++]=e>>>8&255,t.pending_buf[t.pending++]=255&e},At=(t,e,a,i)=>{let n=t.avail_in;return n>i&&(n=i),0===n?0:(t.avail_in-=n,e.set(t.input.subarray(t.next_in,t.next_in+n),a),1===t.state.wrap?t.adler=B(t.adler,e,n,a):2===t.state.wrap&&(t.adler=M(t.adler,e,n,a)),t.next_in+=n,t.total_in+=n,n)},Et=(t,e)=>{let a,i,n=t.max_chain_length,s=t.strstart,r=t.prev_length,l=t.nice_match;const o=t.strstart>t.w_size-ct?t.strstart-(t.w_size-ct):0,h=t.window,d=t.w_mask,_=t.prev,f=t.strstart+ft;let c=h[s+r-1],u=h[s+r];t.prev_length>=t.good_match&&(n>>=2),l>t.lookahead&&(l=t.lookahead);do{if(a=e,h[a+r]===u&&h[a+r-1]===c&&h[a]===h[s]&&h[++a]===h[s+1]){s+=2,a++;do{}while(h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&h[++s]===h[++a]&&sr){if(t.match_start=e,r=i,i>=l)break;c=h[s+r-1],u=h[s+r]}}}while((e=_[e&d])>o&&0!=--n);return r<=t.lookahead?r:t.lookahead},Rt=t=>{const e=t.w_size;let a,i,n,s,r;do{if(s=t.window_size-t.lookahead-t.strstart,t.strstart>=e+(e-ct)){t.window.set(t.window.subarray(e,e+e),0),t.match_start-=e,t.strstart-=e,t.block_start-=e,i=t.hash_size,a=i;do{n=t.head[--a],t.head[a]=n>=e?n-e:0}while(--i);i=e,a=i;do{n=t.prev[--a],t.prev[a]=n>=e?n-e:0}while(--i);s+=e}if(0===t.strm.avail_in)break;if(i=At(t.strm,t.window,t.strstart+t.lookahead,s),t.lookahead+=i,t.lookahead+t.insert>=3)for(r=t.strstart-t.insert,t.ins_h=t.window[r],t.ins_h=kt(t,t.ins_h,t.window[r+1]);t.insert&&(t.ins_h=kt(t,t.ins_h,t.window[r+3-1]),t.prev[r&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=r,r++,t.insert--,!(t.lookahead+t.insert<3)););}while(t.lookahead{let a,i;for(;;){if(t.lookahead=3&&(t.ins_h=kt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),0!==a&&t.strstart-a<=t.w_size-ct&&(t.match_length=Et(t,a)),t.match_length>=3)if(i=G(t,t.strstart-t.match_start,t.match_length-3),t.lookahead-=t.match_length,t.match_length<=t.max_lazy_match&&t.lookahead>=3){t.match_length--;do{t.strstart++,t.ins_h=kt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart}while(0!=--t.match_length);t.strstart++}else t.strstart+=t.match_length,t.match_length=0,t.ins_h=t.window[t.strstart],t.ins_h=kt(t,t.ins_h,t.window[t.strstart+1]);else i=G(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++;if(i&&(yt(t,!1),0===t.strm.avail_out))return 1}return t.insert=t.strstart<2?t.strstart:2,e===Q?(yt(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(yt(t,!1),0===t.strm.avail_out)?1:2},Ut=(t,e)=>{let a,i,n;for(;;){if(t.lookahead=3&&(t.ins_h=kt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart),t.prev_length=t.match_length,t.prev_match=t.match_start,t.match_length=2,0!==a&&t.prev_length4096)&&(t.match_length=2)),t.prev_length>=3&&t.match_length<=t.prev_length){n=t.strstart+t.lookahead-3,i=G(t,t.strstart-1-t.prev_match,t.prev_length-3),t.lookahead-=t.prev_length-1,t.prev_length-=2;do{++t.strstart<=n&&(t.ins_h=kt(t,t.ins_h,t.window[t.strstart+3-1]),a=t.prev[t.strstart&t.w_mask]=t.head[t.ins_h],t.head[t.ins_h]=t.strstart)}while(0!=--t.prev_length);if(t.match_available=0,t.match_length=2,t.strstart++,i&&(yt(t,!1),0===t.strm.avail_out))return 1}else if(t.match_available){if(i=G(t,0,t.window[t.strstart-1]),i&&yt(t,!1),t.strstart++,t.lookahead--,0===t.strm.avail_out)return 1}else t.match_available=1,t.strstart++,t.lookahead--}return t.match_available&&(i=G(t,0,t.window[t.strstart-1]),t.match_available=0),t.insert=t.strstart<2?t.strstart:2,e===Q?(yt(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(yt(t,!1),0===t.strm.avail_out)?1:2};function St(t,e,a,i,n){this.good_length=t,this.max_lazy=e,this.nice_length=a,this.max_chain=i,this.func=n}const Dt=[new St(0,0,0,0,((t,e)=>{let a=65535;for(a>t.pending_buf_size-5&&(a=t.pending_buf_size-5);;){if(t.lookahead<=1){if(Rt(t),0===t.lookahead&&e===W)return 1;if(0===t.lookahead)break}t.strstart+=t.lookahead,t.lookahead=0;const i=t.block_start+a;if((0===t.strstart||t.strstart>=i)&&(t.lookahead=t.strstart-i,t.strstart=i,yt(t,!1),0===t.strm.avail_out))return 1;if(t.strstart-t.block_start>=t.w_size-ct&&(yt(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===Q?(yt(t,!0),0===t.strm.avail_out?3:4):(t.strstart>t.block_start&&(yt(t,!1),t.strm.avail_out),1)})),new St(4,4,8,4,Zt),new St(4,5,16,8,Zt),new St(4,6,32,32,Zt),new St(4,4,16,16,Ut),new St(8,16,32,32,Ut),new St(8,16,128,128,Ut),new St(8,32,128,256,Ut),new St(32,128,258,1024,Ut),new St(32,258,258,4096,Ut)];function Tt(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=_t,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new Uint16Array(1146),this.dyn_dtree=new Uint16Array(122),this.bl_tree=new Uint16Array(78),mt(this.dyn_ltree),mt(this.dyn_dtree),mt(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new Uint16Array(16),this.heap=new Uint16Array(573),mt(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new Uint16Array(573),mt(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}const Ot=t=>{if(!t||!t.state)return gt(t,et);t.total_in=t.total_out=0,t.data_type=dt;const e=t.state;return e.pending=0,e.pending_out=0,e.wrap<0&&(e.wrap=-e.wrap),e.status=e.wrap?42:wt,t.adler=2===e.wrap?0:1,e.last_flush=W,K(e),$},It=t=>{const e=Ot(t);var a;return e===$&&((a=t.state).window_size=2*a.w_size,mt(a.head),a.max_lazy_match=Dt[a.level].max_lazy,a.good_match=Dt[a.level].good_length,a.nice_match=Dt[a.level].nice_length,a.max_chain_length=Dt[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=2,a.match_available=0,a.ins_h=0),e},Ft=(t,e,a,i,n,s)=>{if(!t)return et;let r=1;if(e===nt&&(e=6),i<0?(r=0,i=-i):i>15&&(r=2,i-=16),n<1||n>9||a!==_t||i<8||i>15||e<0||e>9||s<0||s>ot)return gt(t,et);8===i&&(i=9);const l=new Tt;return t.state=l,l.strm=t,l.wrap=r,l.gzhead=null,l.w_bits=i,l.w_size=1<Ft(t,e,_t,15,8,ht),deflateInit2:Ft,deflateReset:It,deflateResetKeep:Ot,deflateSetHeader:(t,e)=>t&&t.state?2!==t.state.wrap?et:(t.state.gzhead=e,$):et,deflate:(t,e)=>{let a,i;if(!t||!t.state||e>V||e<0)return t?gt(t,et):et;const n=t.state;if(!t.output||!t.input&&0!==t.avail_in||n.status===bt&&e!==Q)return gt(t,0===t.avail_out?it:et);n.strm=t;const s=n.last_flush;if(n.last_flush=e,42===n.status)if(2===n.wrap)t.adler=0,xt(n,31),xt(n,139),xt(n,8),n.gzhead?(xt(n,(n.gzhead.text?1:0)+(n.gzhead.hcrc?2:0)+(n.gzhead.extra?4:0)+(n.gzhead.name?8:0)+(n.gzhead.comment?16:0)),xt(n,255&n.gzhead.time),xt(n,n.gzhead.time>>8&255),xt(n,n.gzhead.time>>16&255),xt(n,n.gzhead.time>>24&255),xt(n,9===n.level?2:n.strategy>=rt||n.level<2?4:0),xt(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(xt(n,255&n.gzhead.extra.length),xt(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(t.adler=M(t.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(xt(n,0),xt(n,0),xt(n,0),xt(n,0),xt(n,0),xt(n,9===n.level?2:n.strategy>=rt||n.level<2?4:0),xt(n,3),n.status=wt);else{let e=_t+(n.w_bits-8<<4)<<8,a=-1;a=n.strategy>=rt||n.level<2?0:n.level<6?1:6===n.level?2:3,e|=a<<6,0!==n.strstart&&(e|=32),e+=31-e%31,n.status=wt,zt(n,e),0!==n.strstart&&(zt(n,t.adler>>>16),zt(n,65535&t.adler)),t.adler=1}if(69===n.status)if(n.gzhead.extra){for(a=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>a&&(t.adler=M(t.adler,n.pending_buf,n.pending-a,a)),vt(t),a=n.pending,n.pending!==n.pending_buf_size));)xt(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>a&&(t.adler=M(t.adler,n.pending_buf,n.pending-a,a)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){a=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>a&&(t.adler=M(t.adler,n.pending_buf,n.pending-a,a)),vt(t),a=n.pending,n.pending===n.pending_buf_size)){i=1;break}i=n.gzindexa&&(t.adler=M(t.adler,n.pending_buf,n.pending-a,a)),0===i&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){a=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>a&&(t.adler=M(t.adler,n.pending_buf,n.pending-a,a)),vt(t),a=n.pending,n.pending===n.pending_buf_size)){i=1;break}i=n.gzindexa&&(t.adler=M(t.adler,n.pending_buf,n.pending-a,a)),0===i&&(n.status=ut)}else n.status=ut;if(n.status===ut&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&vt(t),n.pending+2<=n.pending_buf_size&&(xt(n,255&t.adler),xt(n,t.adler>>8&255),t.adler=0,n.status=wt)):n.status=wt),0!==n.pending){if(vt(t),0===t.avail_out)return n.last_flush=-1,$}else if(0===t.avail_in&&pt(e)<=pt(s)&&e!==Q)return gt(t,it);if(n.status===bt&&0!==t.avail_in)return gt(t,it);if(0!==t.avail_in||0!==n.lookahead||e!==W&&n.status!==bt){let a=n.strategy===rt?((t,e)=>{let a;for(;;){if(0===t.lookahead&&(Rt(t),0===t.lookahead)){if(e===W)return 1;break}if(t.match_length=0,a=G(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++,a&&(yt(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===Q?(yt(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(yt(t,!1),0===t.strm.avail_out)?1:2})(n,e):n.strategy===lt?((t,e)=>{let a,i,n,s;const r=t.window;for(;;){if(t.lookahead<=ft){if(Rt(t),t.lookahead<=ft&&e===W)return 1;if(0===t.lookahead)break}if(t.match_length=0,t.lookahead>=3&&t.strstart>0&&(n=t.strstart-1,i=r[n],i===r[++n]&&i===r[++n]&&i===r[++n])){s=t.strstart+ft;do{}while(i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&i===r[++n]&&nt.lookahead&&(t.match_length=t.lookahead)}if(t.match_length>=3?(a=G(t,1,t.match_length-3),t.lookahead-=t.match_length,t.strstart+=t.match_length,t.match_length=0):(a=G(t,0,t.window[t.strstart]),t.lookahead--,t.strstart++),a&&(yt(t,!1),0===t.strm.avail_out))return 1}return t.insert=0,e===Q?(yt(t,!0),0===t.strm.avail_out?3:4):t.last_lit&&(yt(t,!1),0===t.strm.avail_out)?1:2})(n,e):Dt[n.level].func(n,e);if(3!==a&&4!==a||(n.status=bt),1===a||3===a)return 0===t.avail_out&&(n.last_flush=-1),$;if(2===a&&(e===q?X(n):e!==V&&(P(n,0,0,!1),e===J&&(mt(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),vt(t),0===t.avail_out))return n.last_flush=-1,$}return e!==Q?$:n.wrap<=0?tt:(2===n.wrap?(xt(n,255&t.adler),xt(n,t.adler>>8&255),xt(n,t.adler>>16&255),xt(n,t.adler>>24&255),xt(n,255&t.total_in),xt(n,t.total_in>>8&255),xt(n,t.total_in>>16&255),xt(n,t.total_in>>24&255)):(zt(n,t.adler>>>16),zt(n,65535&t.adler)),vt(t),n.wrap>0&&(n.wrap=-n.wrap),0!==n.pending?$:tt)},deflateEnd:t=>{if(!t||!t.state)return et;const e=t.state.status;return 42!==e&&69!==e&&73!==e&&91!==e&&e!==ut&&e!==wt&&e!==bt?gt(t,et):(t.state=null,e===wt?gt(t,at):$)},deflateSetDictionary:(t,e)=>{let a=e.length;if(!t||!t.state)return et;const i=t.state,n=i.wrap;if(2===n||1===n&&42!==i.status||i.lookahead)return et;if(1===n&&(t.adler=B(t.adler,e,a,0)),i.wrap=0,a>=i.w_size){0===n&&(mt(i.head),i.strstart=0,i.block_start=0,i.insert=0);let t=new Uint8Array(i.w_size);t.set(e.subarray(a-i.w_size,a),0),e=t,a=i.w_size}const s=t.avail_in,r=t.next_in,l=t.input;for(t.avail_in=a,t.next_in=0,t.input=e,Rt(i);i.lookahead>=3;){let t=i.strstart,e=i.lookahead-2;do{i.ins_h=kt(i,i.ins_h,i.window[t+3-1]),i.prev[t&i.w_mask]=i.head[i.ins_h],i.head[i.ins_h]=t,t++}while(--e);i.strstart=t,i.lookahead=2,Rt(i)}return i.strstart+=i.lookahead,i.block_start=i.strstart,i.insert=i.lookahead,i.lookahead=0,i.match_length=i.prev_length=2,i.match_available=0,t.next_in=r,t.input=l,t.avail_in=s,i.wrap=n,$},deflateInfo:"pako deflate (from Nodeca project)"};const Nt=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var Bt=function(t){const e=Array.prototype.slice.call(arguments,1);for(;e.length;){const a=e.shift();if(a){if("object"!=typeof a)throw new TypeError(a+"must be non-object");for(const e in a)Nt(a,e)&&(t[e]=a[e])}}return t},Ct=t=>{let e=0;for(let a=0,i=t.length;a=252?6:t>=248?5:t>=240?4:t>=224?3:t>=192?2:1;Ht[254]=Ht[254]=1;var jt=t=>{if("function"==typeof TextEncoder&&TextEncoder.prototype.encode)return(new TextEncoder).encode(t);let e,a,i,n,s,r=t.length,l=0;for(n=0;n>>6,e[s++]=128|63&a):a<65536?(e[s++]=224|a>>>12,e[s++]=128|a>>>6&63,e[s++]=128|63&a):(e[s++]=240|a>>>18,e[s++]=128|a>>>12&63,e[s++]=128|a>>>6&63,e[s++]=128|63&a);return e},Kt=(t,e)=>{const a=e||t.length;if("function"==typeof TextDecoder&&TextDecoder.prototype.decode)return(new TextDecoder).decode(t.subarray(0,e));let i,n;const s=new Array(2*a);for(n=0,i=0;i4)s[n++]=65533,i+=r-1;else{for(e&=2===r?31:3===r?15:7;r>1&&i1?s[n++]=65533:e<65536?s[n++]=e:(e-=65536,s[n++]=55296|e>>10&1023,s[n++]=56320|1023&e)}}return((t,e)=>{if(e<65534&&t.subarray&&Mt)return String.fromCharCode.apply(null,t.length===e?t:t.subarray(0,e));let a="";for(let i=0;i{(e=e||t.length)>t.length&&(e=t.length);let a=e-1;for(;a>=0&&128==(192&t[a]);)a--;return a<0||0===a?e:a+Ht[t[a]]>e?a:e};var Yt=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0};const Gt=Object.prototype.toString,{Z_NO_FLUSH:Xt,Z_SYNC_FLUSH:Wt,Z_FULL_FLUSH:qt,Z_FINISH:Jt,Z_OK:Qt,Z_STREAM_END:Vt,Z_DEFAULT_COMPRESSION:$t,Z_DEFAULT_STRATEGY:te,Z_DEFLATED:ee}=j;function ae(t){this.options=Bt({level:$t,method:ee,chunkSize:16384,windowBits:15,memLevel:8,strategy:te},t||{});let e=this.options;e.raw&&e.windowBits>0?e.windowBits=-e.windowBits:e.gzip&&e.windowBits>0&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new Yt,this.strm.avail_out=0;let a=Lt.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(a!==Qt)throw new Error(H[a]);if(e.header&&Lt.deflateSetHeader(this.strm,e.header),e.dictionary){let t;if(t="string"==typeof e.dictionary?jt(e.dictionary):"[object ArrayBuffer]"===Gt.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,a=Lt.deflateSetDictionary(this.strm,t),a!==Qt)throw new Error(H[a]);this._dict_set=!0}}function ie(t,e){const a=new ae(e);if(a.push(t,!0),a.err)throw a.msg||H[a.err];return a.result}ae.prototype.push=function(t,e){const a=this.strm,i=this.options.chunkSize;let n,s;if(this.ended)return!1;for(s=e===~~e?e:!0===e?Jt:Xt,"string"==typeof t?a.input=jt(t):"[object ArrayBuffer]"===Gt.call(t)?a.input=new Uint8Array(t):a.input=t,a.next_in=0,a.avail_in=a.input.length;;)if(0===a.avail_out&&(a.output=new Uint8Array(i),a.next_out=0,a.avail_out=i),(s===Wt||s===qt)&&a.avail_out<=6)this.onData(a.output.subarray(0,a.next_out)),a.avail_out=0;else{if(n=Lt.deflate(a,s),n===Vt)return a.next_out>0&&this.onData(a.output.subarray(0,a.next_out)),n=Lt.deflateEnd(this.strm),this.onEnd(n),this.ended=!0,n===Qt;if(0!==a.avail_out){if(s>0&&a.next_out>0)this.onData(a.output.subarray(0,a.next_out)),a.avail_out=0;else if(0===a.avail_in)break}else this.onData(a.output)}return!0},ae.prototype.onData=function(t){this.chunks.push(t)},ae.prototype.onEnd=function(t){t===Qt&&(this.result=Ct(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg};var ne={Deflate:ae,deflate:ie,deflateRaw:function(t,e){return(e=e||{}).raw=!0,ie(t,e)},gzip:function(t,e){return(e=e||{}).gzip=!0,ie(t,e)},constants:j};var se=function(t,e){let a,i,n,s,r,l,o,h,d,_,f,c,u,w,b,g,p,m,k,v,y,x,z,A;const E=t.state;a=t.next_in,z=t.input,i=a+(t.avail_in-5),n=t.next_out,A=t.output,s=n-(e-t.avail_out),r=n+(t.avail_out-257),l=E.dmax,o=E.wsize,h=E.whave,d=E.wnext,_=E.window,f=E.hold,c=E.bits,u=E.lencode,w=E.distcode,b=(1<>>24,f>>>=m,c-=m,m=p>>>16&255,0===m)A[n++]=65535&p;else{if(!(16&m)){if(0==(64&m)){p=u[(65535&p)+(f&(1<>>=m,c-=m),c<15&&(f+=z[a++]<>>24,f>>>=m,c-=m,m=p>>>16&255,!(16&m)){if(0==(64&m)){p=w[(65535&p)+(f&(1<l){t.msg="invalid distance too far back",E.mode=30;break t}if(f>>>=m,c-=m,m=n-s,v>m){if(m=v-m,m>h&&E.sane){t.msg="invalid distance too far back",E.mode=30;break t}if(y=0,x=_,0===d){if(y+=o-m,m2;)A[n++]=x[y++],A[n++]=x[y++],A[n++]=x[y++],k-=3;k&&(A[n++]=x[y++],k>1&&(A[n++]=x[y++]))}else{y=n-v;do{A[n++]=A[y++],A[n++]=A[y++],A[n++]=A[y++],k-=3}while(k>2);k&&(A[n++]=A[y++],k>1&&(A[n++]=A[y++]))}break}}break}}while(a>3,a-=k,c-=k<<3,f&=(1<{const o=l.bits;let h,d,_,f,c,u,w=0,b=0,g=0,p=0,m=0,k=0,v=0,y=0,x=0,z=0,A=null,E=0;const R=new Uint16Array(16),Z=new Uint16Array(16);let U,S,D,T=null,O=0;for(w=0;w<=re;w++)R[w]=0;for(b=0;b=1&&0===R[p];p--);if(m>p&&(m=p),0===p)return n[s++]=20971520,n[s++]=20971520,l.bits=1,0;for(g=1;g0&&(0===t||1!==p))return-1;for(Z[1]=0,w=1;w852||2===t&&x>592)return 1;for(;;){U=w-v,r[b]u?(S=T[O+r[b]],D=A[E+r[b]]):(S=96,D=0),h=1<>v)+d]=U<<24|S<<16|D|0}while(0!==d);for(h=1<>=1;if(0!==h?(z&=h-1,z+=h):z=0,b++,0==--R[w]){if(w===p)break;w=e[a+r[b]]}if(w>m&&(z&f)!==_){for(0===v&&(v=m),c+=g,k=w-v,y=1<852||2===t&&x>592)return 1;_=z&f,n[_]=m<<24|k<<16|c-s|0}}return 0!==z&&(n[c+z]=w-v<<24|64<<16|0),l.bits=m,0};const{Z_FINISH:fe,Z_BLOCK:ce,Z_TREES:ue,Z_OK:we,Z_STREAM_END:be,Z_NEED_DICT:ge,Z_STREAM_ERROR:pe,Z_DATA_ERROR:me,Z_MEM_ERROR:ke,Z_BUF_ERROR:ve,Z_DEFLATED:ye}=j,xe=12,ze=30,Ae=t=>(t>>>24&255)+(t>>>8&65280)+((65280&t)<<8)+((255&t)<<24);function Ee(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new Uint16Array(320),this.work=new Uint16Array(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}const Re=t=>{if(!t||!t.state)return pe;const e=t.state;return t.total_in=t.total_out=e.total=0,t.msg="",e.wrap&&(t.adler=1&e.wrap),e.mode=1,e.last=0,e.havedict=0,e.dmax=32768,e.head=null,e.hold=0,e.bits=0,e.lencode=e.lendyn=new Int32Array(852),e.distcode=e.distdyn=new Int32Array(592),e.sane=1,e.back=-1,we},Ze=t=>{if(!t||!t.state)return pe;const e=t.state;return e.wsize=0,e.whave=0,e.wnext=0,Re(t)},Ue=(t,e)=>{let a;if(!t||!t.state)return pe;const i=t.state;return e<0?(a=0,e=-e):(a=1+(e>>4),e<48&&(e&=15)),e&&(e<8||e>15)?pe:(null!==i.window&&i.wbits!==e&&(i.window=null),i.wrap=a,i.wbits=e,Ze(t))},Se=(t,e)=>{if(!t)return pe;const a=new Ee;t.state=a,a.window=null;const i=Ue(t,e);return i!==we&&(t.state=null),i};let De,Te,Oe=!0;const Ie=t=>{if(Oe){De=new Int32Array(512),Te=new Int32Array(32);let e=0;for(;e<144;)t.lens[e++]=8;for(;e<256;)t.lens[e++]=9;for(;e<280;)t.lens[e++]=7;for(;e<288;)t.lens[e++]=8;for(_e(1,t.lens,0,288,De,0,t.work,{bits:9}),e=0;e<32;)t.lens[e++]=5;_e(2,t.lens,0,32,Te,0,t.work,{bits:5}),Oe=!1}t.lencode=De,t.lenbits=9,t.distcode=Te,t.distbits=5},Fe=(t,e,a,i)=>{let n;const s=t.state;return null===s.window&&(s.wsize=1<=s.wsize?(s.window.set(e.subarray(a-s.wsize,a),0),s.wnext=0,s.whave=s.wsize):(n=s.wsize-s.wnext,n>i&&(n=i),s.window.set(e.subarray(a-i,a-i+n),s.wnext),(i-=n)?(s.window.set(e.subarray(a-i,a),0),s.wnext=i,s.whave=s.wsize):(s.wnext+=n,s.wnext===s.wsize&&(s.wnext=0),s.whaveSe(t,15),inflateInit2:Se,inflate:(t,e)=>{let a,i,n,s,r,l,o,h,d,_,f,c,u,w,b,g,p,m,k,v,y,x,z=0;const A=new Uint8Array(4);let E,R;const Z=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);if(!t||!t.state||!t.output||!t.input&&0!==t.avail_in)return pe;a=t.state,a.mode===xe&&(a.mode=13),r=t.next_out,n=t.output,o=t.avail_out,s=t.next_in,i=t.input,l=t.avail_in,h=a.hold,d=a.bits,_=l,f=o,x=we;t:for(;;)switch(a.mode){case 1:if(0===a.wrap){a.mode=13;break}for(;d<16;){if(0===l)break t;l--,h+=i[s++]<>>8&255,a.check=M(a.check,A,2,0),h=0,d=0,a.mode=2;break}if(a.flags=0,a.head&&(a.head.done=!1),!(1&a.wrap)||(((255&h)<<8)+(h>>8))%31){t.msg="incorrect header check",a.mode=ze;break}if((15&h)!==ye){t.msg="unknown compression method",a.mode=ze;break}if(h>>>=4,d-=4,y=8+(15&h),0===a.wbits)a.wbits=y;else if(y>a.wbits){t.msg="invalid window size",a.mode=ze;break}a.dmax=1<>8&1),512&a.flags&&(A[0]=255&h,A[1]=h>>>8&255,a.check=M(a.check,A,2,0)),h=0,d=0,a.mode=3;case 3:for(;d<32;){if(0===l)break t;l--,h+=i[s++]<>>8&255,A[2]=h>>>16&255,A[3]=h>>>24&255,a.check=M(a.check,A,4,0)),h=0,d=0,a.mode=4;case 4:for(;d<16;){if(0===l)break t;l--,h+=i[s++]<>8),512&a.flags&&(A[0]=255&h,A[1]=h>>>8&255,a.check=M(a.check,A,2,0)),h=0,d=0,a.mode=5;case 5:if(1024&a.flags){for(;d<16;){if(0===l)break t;l--,h+=i[s++]<>>8&255,a.check=M(a.check,A,2,0)),h=0,d=0}else a.head&&(a.head.extra=null);a.mode=6;case 6:if(1024&a.flags&&(c=a.length,c>l&&(c=l),c&&(a.head&&(y=a.head.extra_len-a.length,a.head.extra||(a.head.extra=new Uint8Array(a.head.extra_len)),a.head.extra.set(i.subarray(s,s+c),y)),512&a.flags&&(a.check=M(a.check,i,c,s)),l-=c,s+=c,a.length-=c),a.length))break t;a.length=0,a.mode=7;case 7:if(2048&a.flags){if(0===l)break t;c=0;do{y=i[s+c++],a.head&&y&&a.length<65536&&(a.head.name+=String.fromCharCode(y))}while(y&&c>9&1,a.head.done=!0),t.adler=a.check=0,a.mode=xe;break;case 10:for(;d<32;){if(0===l)break t;l--,h+=i[s++]<>>=7&d,d-=7&d,a.mode=27;break}for(;d<3;){if(0===l)break t;l--,h+=i[s++]<>>=1,d-=1,3&h){case 0:a.mode=14;break;case 1:if(Ie(a),a.mode=20,e===ue){h>>>=2,d-=2;break t}break;case 2:a.mode=17;break;case 3:t.msg="invalid block type",a.mode=ze}h>>>=2,d-=2;break;case 14:for(h>>>=7&d,d-=7&d;d<32;){if(0===l)break t;l--,h+=i[s++]<>>16^65535)){t.msg="invalid stored block lengths",a.mode=ze;break}if(a.length=65535&h,h=0,d=0,a.mode=15,e===ue)break t;case 15:a.mode=16;case 16:if(c=a.length,c){if(c>l&&(c=l),c>o&&(c=o),0===c)break t;n.set(i.subarray(s,s+c),r),l-=c,s+=c,o-=c,r+=c,a.length-=c;break}a.mode=xe;break;case 17:for(;d<14;){if(0===l)break t;l--,h+=i[s++]<>>=5,d-=5,a.ndist=1+(31&h),h>>>=5,d-=5,a.ncode=4+(15&h),h>>>=4,d-=4,a.nlen>286||a.ndist>30){t.msg="too many length or distance symbols",a.mode=ze;break}a.have=0,a.mode=18;case 18:for(;a.have>>=3,d-=3}for(;a.have<19;)a.lens[Z[a.have++]]=0;if(a.lencode=a.lendyn,a.lenbits=7,E={bits:a.lenbits},x=_e(0,a.lens,0,19,a.lencode,0,a.work,E),a.lenbits=E.bits,x){t.msg="invalid code lengths set",a.mode=ze;break}a.have=0,a.mode=19;case 19:for(;a.have>>24,g=z>>>16&255,p=65535&z,!(b<=d);){if(0===l)break t;l--,h+=i[s++]<>>=b,d-=b,a.lens[a.have++]=p;else{if(16===p){for(R=b+2;d>>=b,d-=b,0===a.have){t.msg="invalid bit length repeat",a.mode=ze;break}y=a.lens[a.have-1],c=3+(3&h),h>>>=2,d-=2}else if(17===p){for(R=b+3;d>>=b,d-=b,y=0,c=3+(7&h),h>>>=3,d-=3}else{for(R=b+7;d>>=b,d-=b,y=0,c=11+(127&h),h>>>=7,d-=7}if(a.have+c>a.nlen+a.ndist){t.msg="invalid bit length repeat",a.mode=ze;break}for(;c--;)a.lens[a.have++]=y}}if(a.mode===ze)break;if(0===a.lens[256]){t.msg="invalid code -- missing end-of-block",a.mode=ze;break}if(a.lenbits=9,E={bits:a.lenbits},x=_e(1,a.lens,0,a.nlen,a.lencode,0,a.work,E),a.lenbits=E.bits,x){t.msg="invalid literal/lengths set",a.mode=ze;break}if(a.distbits=6,a.distcode=a.distdyn,E={bits:a.distbits},x=_e(2,a.lens,a.nlen,a.ndist,a.distcode,0,a.work,E),a.distbits=E.bits,x){t.msg="invalid distances set",a.mode=ze;break}if(a.mode=20,e===ue)break t;case 20:a.mode=21;case 21:if(l>=6&&o>=258){t.next_out=r,t.avail_out=o,t.next_in=s,t.avail_in=l,a.hold=h,a.bits=d,se(t,f),r=t.next_out,n=t.output,o=t.avail_out,s=t.next_in,i=t.input,l=t.avail_in,h=a.hold,d=a.bits,a.mode===xe&&(a.back=-1);break}for(a.back=0;z=a.lencode[h&(1<>>24,g=z>>>16&255,p=65535&z,!(b<=d);){if(0===l)break t;l--,h+=i[s++]<>m)],b=z>>>24,g=z>>>16&255,p=65535&z,!(m+b<=d);){if(0===l)break t;l--,h+=i[s++]<>>=m,d-=m,a.back+=m}if(h>>>=b,d-=b,a.back+=b,a.length=p,0===g){a.mode=26;break}if(32&g){a.back=-1,a.mode=xe;break}if(64&g){t.msg="invalid literal/length code",a.mode=ze;break}a.extra=15&g,a.mode=22;case 22:if(a.extra){for(R=a.extra;d>>=a.extra,d-=a.extra,a.back+=a.extra}a.was=a.length,a.mode=23;case 23:for(;z=a.distcode[h&(1<>>24,g=z>>>16&255,p=65535&z,!(b<=d);){if(0===l)break t;l--,h+=i[s++]<>m)],b=z>>>24,g=z>>>16&255,p=65535&z,!(m+b<=d);){if(0===l)break t;l--,h+=i[s++]<>>=m,d-=m,a.back+=m}if(h>>>=b,d-=b,a.back+=b,64&g){t.msg="invalid distance code",a.mode=ze;break}a.offset=p,a.extra=15&g,a.mode=24;case 24:if(a.extra){for(R=a.extra;d>>=a.extra,d-=a.extra,a.back+=a.extra}if(a.offset>a.dmax){t.msg="invalid distance too far back",a.mode=ze;break}a.mode=25;case 25:if(0===o)break t;if(c=f-o,a.offset>c){if(c=a.offset-c,c>a.whave&&a.sane){t.msg="invalid distance too far back",a.mode=ze;break}c>a.wnext?(c-=a.wnext,u=a.wsize-c):u=a.wnext-c,c>a.length&&(c=a.length),w=a.window}else w=n,u=r-a.offset,c=a.length;c>o&&(c=o),o-=c,a.length-=c;do{n[r++]=w[u++]}while(--c);0===a.length&&(a.mode=21);break;case 26:if(0===o)break t;n[r++]=a.length,o--,a.mode=21;break;case 27:if(a.wrap){for(;d<32;){if(0===l)break t;l--,h|=i[s++]<{if(!t||!t.state)return pe;let e=t.state;return e.window&&(e.window=null),t.state=null,we},inflateGetHeader:(t,e)=>{if(!t||!t.state)return pe;const a=t.state;return 0==(2&a.wrap)?pe:(a.head=e,e.done=!1,we)},inflateSetDictionary:(t,e)=>{const a=e.length;let i,n,s;return t&&t.state?(i=t.state,0!==i.wrap&&11!==i.mode?pe:11===i.mode&&(n=1,n=B(n,e,a,0),n!==i.check)?me:(s=Fe(t,e,a,a),s?(i.mode=31,ke):(i.havedict=1,we))):pe},inflateInfo:"pako inflate (from Nodeca project)"};var Ne=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1};const Be=Object.prototype.toString,{Z_NO_FLUSH:Ce,Z_FINISH:Me,Z_OK:He,Z_STREAM_END:je,Z_NEED_DICT:Ke,Z_STREAM_ERROR:Pe,Z_DATA_ERROR:Ye,Z_MEM_ERROR:Ge}=j;function Xe(t){this.options=Bt({chunkSize:65536,windowBits:15,to:""},t||{});const e=this.options;e.raw&&e.windowBits>=0&&e.windowBits<16&&(e.windowBits=-e.windowBits,0===e.windowBits&&(e.windowBits=-15)),!(e.windowBits>=0&&e.windowBits<16)||t&&t.windowBits||(e.windowBits+=32),e.windowBits>15&&e.windowBits<48&&0==(15&e.windowBits)&&(e.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new Yt,this.strm.avail_out=0;let a=Le.inflateInit2(this.strm,e.windowBits);if(a!==He)throw new Error(H[a]);if(this.header=new Ne,Le.inflateGetHeader(this.strm,this.header),e.dictionary&&("string"==typeof e.dictionary?e.dictionary=jt(e.dictionary):"[object ArrayBuffer]"===Be.call(e.dictionary)&&(e.dictionary=new Uint8Array(e.dictionary)),e.raw&&(a=Le.inflateSetDictionary(this.strm,e.dictionary),a!==He)))throw new Error(H[a])}function We(t,e){const a=new Xe(e);if(a.push(t),a.err)throw a.msg||H[a.err];return a.result}Xe.prototype.push=function(t,e){const a=this.strm,i=this.options.chunkSize,n=this.options.dictionary;let s,r,l;if(this.ended)return!1;for(r=e===~~e?e:!0===e?Me:Ce,"[object ArrayBuffer]"===Be.call(t)?a.input=new Uint8Array(t):a.input=t,a.next_in=0,a.avail_in=a.input.length;;){for(0===a.avail_out&&(a.output=new Uint8Array(i),a.next_out=0,a.avail_out=i),s=Le.inflate(a,r),s===Ke&&n&&(s=Le.inflateSetDictionary(a,n),s===He?s=Le.inflate(a,r):s===Ye&&(s=Ke));a.avail_in>0&&s===je&&a.state.wrap>0&&0!==t[a.next_in];)Le.inflateReset(a),s=Le.inflate(a,r);switch(s){case Pe:case Ye:case Ke:case Ge:return this.onEnd(s),this.ended=!0,!1}if(l=a.avail_out,a.next_out&&(0===a.avail_out||s===je))if("string"===this.options.to){let t=Pt(a.output,a.next_out),e=a.next_out-t,n=Kt(a.output,t);a.next_out=e,a.avail_out=i-e,e&&a.output.set(a.output.subarray(t,t+e),0),this.onData(n)}else this.onData(a.output.length===a.next_out?a.output:a.output.subarray(0,a.next_out));if(s!==He||0!==l){if(s===je)return s=Le.inflateEnd(this.strm),this.onEnd(s),this.ended=!0,!0;if(0===a.avail_in)break}}return!0},Xe.prototype.onData=function(t){this.chunks.push(t)},Xe.prototype.onEnd=function(t){t===He&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=Ct(this.chunks)),this.chunks=[],this.err=t,this.msg=this.strm.msg};var qe={Inflate:Xe,inflate:We,inflateRaw:function(t,e){return(e=e||{}).raw=!0,We(t,e)},ungzip:We,constants:j};const{Deflate:Je,deflate:Qe,deflateRaw:Ve,gzip:$e}=ne,{Inflate:ta,inflate:ea,inflateRaw:aa,ungzip:ia}=qe;var na=Je,sa=Qe,ra=Ve,la=$e,oa=ta,ha=ea,da=aa,_a=ia,fa=j,ca={Deflate:na,deflate:sa,deflateRaw:ra,gzip:la,Inflate:oa,inflate:ha,inflateRaw:da,ungzip:_a,constants:fa};t.Deflate=na,t.Inflate=oa,t.constants=fa,t.default=ca,t.deflate=sa,t.deflateRaw=ra,t.gzip=la,t.inflate=ha,t.inflateRaw=da,t.ungzip=_a,Object.defineProperty(t,"__esModule",{value:!0})})); diff --git a/src/sphinxext/__init__.py b/src/sphinxext/__init__.py new file mode 100644 index 0000000..4767bb6 --- /dev/null +++ b/src/sphinxext/__init__.py @@ -0,0 +1,8 @@ +def setup(app): + app.add_config_value('html_embed_assets', False, 'html') + + return { + 'version': '0.1', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000..55ff9de --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,2 @@ +pytest +sphinx diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..c1009dd --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,9 @@ +""" + pytest config for sphinxcontrib/sphinx-self-contained-html/tests + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + :copyright: Copyright 2017 by Adrian Vollmer + :license: BSD, see LICENSE for details. +""" + +pytest_plugins = 'sphinx.testing.fixtures' diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..5acb1a6 --- /dev/null +++ b/tox.ini @@ -0,0 +1,32 @@ +[tox] +minversion = 2.0 +envlist = py{34,35,36,py},style + +[testenv] +deps = -r{toxinidir}/test-requirements.txt +commands= + pytest + +[testenv:mypy] +description = + Run type checks. +deps = + mypy +commands= + mypy sphinxcontrib + +[testenv:style] +description = + Run style checks. +deps = + flake8 + isort + yapf +commands = + isort -rc -c -df sphinxcontrib tests + yapf -rd sphinxcontrib tests + flake8 sphinxcontrib tests setup.py + +[travis] +python = + 3.6: py36, mypy, style