// Polyfill for Navigator.clipboard.writeText
if (!navigator.clipboard) {
    navigator.clipboard = {
        writeText: text => {

            // A <span> contains the text to copy
            const span = document.createElement('span');
            span.innerText = text;
            span.style.whiteSpace = 'pre'; // Preserve consecutive spaces and newlines

            // Paint the span outside the viewport
            span.style.position = 'absolute';
            span.style.left = '-9999px';
            span.style.top = '-9999px';

            const win = window;
            const selection = win.getSelection();
            win.document.body.appendChild(span);

            const range = win.document.createRange();
            selection.removeAllRanges();
            range.selectNode(span);
            selection.addRange(range);

            let success = false;
            try {
                success = win.document.execCommand('copy');
            } catch (err) {
                return Promise.error();
            }

            selection.removeAllRanges();
            span.remove();

            return Promise.resolve();
        }
    }
}

const zipper = (() => {

    let zipWriter;
    return {
        createNewZipWriter() {
            zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"), { bufferedWrite: true, level: 0 });
        },
        addFile(file, options) {
            return zipWriter.add(file.name, new zip.BlobReader(file), options);
        },
        async getBlobURL() {
            if (zipWriter) {
                const blobURL = URL.createObjectURL(await zipWriter.close());
                zipWriter = null;
                return blobURL;
            } else {
                throw new Error("Zip file closed");
            }
        },
        async getZipFile(filename = "archive.zip") {
            if (zipWriter) {
                const file = new File([await zipWriter.close()], filename, {type: "application/zip"});
                zipWriter = null;
                return file;
            } else {
                throw new Error("Zip file closed");
            }
        },
        async getEntries(file, options) {
            return await (new zip.ZipReader(new zip.BlobReader(file))).getEntries(options);
        },
        async getData(entry, options) {
            return await entry.getData(new zip.BlobWriter(), options);
        },
    };

})();

const mime = (() => {

    return {
        getMimeByFilename(filename) {
            try {
                const arr = filename.split('.');
                const suffix = arr[arr.length - 1].toLowerCase();
                return {
                    "cpl": "application/cpl+xml",
                    "gpx": "application/gpx+xml",
                    "gz": "application/gzip",
                    "jar": "application/java-archive",
                    "war": "application/java-archive",
                    "ear": "application/java-archive",
                    "class": "application/java-vm",
                    "js": "application/javascript",
                    "mjs": "application/javascript",
                    "json": "application/json",
                    "map": "application/json",
                    "webmanifest": "application/manifest+json",
                    "doc": "application/msword",
                    "dot": "application/msword",
                    "wiz": "application/msword",
                    "bin": "application/octet-stream",
                    "dms": "application/octet-stream",
                    "lrf": "application/octet-stream",
                    "mar": "application/octet-stream",
                    "so": "application/octet-stream",
                    "dist": "application/octet-stream",
                    "distz": "application/octet-stream",
                    "pkg": "application/octet-stream",
                    "bpk": "application/octet-stream",
                    "dump": "application/octet-stream",
                    "elc": "application/octet-stream",
                    "deploy": "application/octet-stream",
                    "img": "application/octet-stream",
                    "msp": "application/octet-stream",
                    "msm": "application/octet-stream",
                    "buffer": "application/octet-stream",
                    "oda": "application/oda",
                    "oxps": "application/oxps",
                    "pdf": "application/pdf",
                    "asc": "application/pgp-signature",
                    "sig": "application/pgp-signature",
                    "prf": "application/pics-rules",
                    "p7c": "application/pkcs7-mime",
                    "cer": "application/pkix-cert",
                    "ai": "application/postscript",
                    "eps": "application/postscript",
                    "ps": "application/postscript",
                    "apk": "application/vnd.android.package-archive",
                    "m3u8": "application/vnd.apple.mpegurl",
                    "pkpass": "application/vnd.apple.pkpass",
                    "kml": "application/vnd.google-earth.kml+xml",
                    "kmz": "application/vnd.google-earth.kmz",
                    "cab": "application/vnd.ms-cab-compressed",
                    "xls": "application/vnd.ms-excel",
                    "xlm": "application/vnd.ms-excel",
                    "xla": "application/vnd.ms-excel",
                    "xlc": "application/vnd.ms-excel",
                    "xlt": "application/vnd.ms-excel",
                    "xlw": "application/vnd.ms-excel",
                    "msg": "application/vnd.ms-outlook",
                    "ppt": "application/vnd.ms-powerpoint",
                    "pot": "application/vnd.ms-powerpoint",
                    "ppa": "application/vnd.ms-powerpoint",
                    "pps": "application/vnd.ms-powerpoint",
                    "pwz": "application/vnd.ms-powerpoint",
                    "mpp": "application/vnd.ms-project",
                    "mpt": "application/vnd.ms-project",
                    "xps": "application/vnd.ms-xpsdocument",
                    "odb": "application/vnd.oasis.opendocument.database",
                    "ods": "application/vnd.oasis.opendocument.spreadsheet",
                    "odt": "application/vnd.oasis.opendocument.text",
                    "osm": "application/vnd.openstreetmap.data+xml",
                    "pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
                    "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                    "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                    "pcap": "application/vnd.tcpdump.pcap",
                    "cap": "application/vnd.tcpdump.pcap",
                    "dmp": "application/vnd.tcpdump.pcap",
                    "wpd": "application/vnd.wordperfect",
                    "wasm": "application/wasm",
                    "7z": "application/x-7z-compressed",
                    "dmg": "application/x-apple-diskimage",
                    "bcpio": "application/x-bcpio",
                    "torrent": "application/x-bittorrent",
                    "cbr": "application/x-cbr",
                    "cba": "application/x-cbr",
                    "cbt": "application/x-cbr",
                    "cbz": "application/x-cbr",
                    "cb7": "application/x-cbr",
                    "vcd": "application/x-cdlink",
                    "crx": "application/x-chrome-extension",
                    "cpio": "application/x-cpio",
                    "csh": "application/x-csh",
                    "deb": "application/x-debian-package",
                    "udeb": "application/x-debian-package",
                    "dvi": "application/x-dvi",
                    "arc": "application/x-freearc",
                    "gtar": "application/x-gtar",
                    "hdf": "application/x-hdf",
                    "h5": "application/x-hdf5",
                    "php": "application/x-httpd-php",
                    "iso": "application/x-iso9660-image",
                    "key": "application/x-iwork-keynote-sffkey",
                    "numbers": "application/x-iwork-numbers-sffnumbers",
                    "pages": "application/x-iwork-pages-sffpages",
                    "latex": "application/x-latex",
                    "run": "application/x-makeself",
                    "mif": "application/x-mif",
                    "lnk": "application/x-ms-shortcut",
                    "mdb": "application/x-msaccess",
                    "exe": "application/x-msdownload",
                    "dll": "application/x-msdownload",
                    "com": "application/x-msdownload",
                    "bat": "application/x-msdownload",
                    "msi": "application/x-msdownload",
                    "pub": "application/x-mspublisher",
                    "cdf": "application/x-netcdf",
                    "nc": "application/x-netcdf",
                    "pl": "application/x-perl",
                    "pm": "application/x-perl",
                    "prc": "application/x-pilot",
                    "pdb": "application/x-pilot",
                    "p12": "application/x-pkcs12",
                    "pfx": "application/x-pkcs12",
                    "ram": "application/x-pn-realaudio",
                    "pyc": "application/x-python-code",
                    "pyo": "application/x-python-code",
                    "rar": "application/x-rar-compressed",
                    "rpm": "application/x-redhat-package-manager",
                    "sh": "application/x-sh",
                    "shar": "application/x-shar",
                    "swf": "application/x-shockwave-flash",
                    "sql": "application/x-sql",
                    "srt": "application/x-subrip",
                    "sv4cpio": "application/x-sv4cpio",
                    "sv4crc": "application/x-sv4crc",
                    "gam": "application/x-tads",
                    "tar": "application/x-tar",
                    "tcl": "application/x-tcl",
                    "tex": "application/x-tex",
                    "roff": "application/x-troff",
                    "t": "application/x-troff",
                    "tr": "application/x-troff",
                    "man": "application/x-troff-man",
                    "me": "application/x-troff-me",
                    "ms": "application/x-troff-ms",
                    "ustar": "application/x-ustar",
                    "src": "application/x-wais-source",
                    "xpi": "application/x-xpinstall",
                    "xhtml": "application/xhtml+xml",
                    "xht": "application/xhtml+xml",
                    "xsl": "application/xml",
                    "rdf": "application/xml",
                    "wsdl": "application/xml",
                    "xpdl": "application/xml",
                    "zip": "application/zip",
                    "3gp": "audio/3gp",
                    "3gpp": "audio/3gpp",
                    "3g2": "audio/3gpp2",
                    "3gpp2": "audio/3gpp2",
                    "aac": "audio/aac",
                    "adts": "audio/aac",
                    "loas": "audio/aac",
                    "ass": "audio/aac",
                    "au": "audio/basic",
                    "snd": "audio/basic",
                    "mid": "audio/midi",
                    "midi": "audio/midi",
                    "kar": "audio/midi",
                    "rmi": "audio/midi",
                    "mpga": "audio/mpeg",
                    "mp2": "audio/mpeg",
                    "mp2a": "audio/mpeg",
                    "mp3": "audio/mpeg",
                    "m2a": "audio/mpeg",
                    "m3a": "audio/mpeg",
                    "oga": "audio/ogg",
                    "ogg": "audio/ogg",
                    "spx": "audio/ogg",
                    "opus": "audio/opus",
                    "aif": "audio/x-aiff",
                    "aifc": "audio/x-aiff",
                    "aiff": "audio/x-aiff",
                    "flac": "audio/x-flac",
                    "m4a": "audio/x-m4a",
                    "m3u": "audio/x-mpegurl",
                    "wma": "audio/x-ms-wma",
                    "ra": "audio/x-pn-realaudio",
                    "wav": "audio/x-wav",
                    "otf": "font/otf",
                    "ttf": "font/ttf",
                    "woff": "font/woff",
                    "woff2": "font/woff2",
                    "emf": "image/emf",
                    "gif": "image/gif",
                    "heic": "image/heic",
                    "heif": "image/heif",
                    "ief": "image/ief",
                    "jpeg": "image/jpeg",
                    "jpg": "image/jpeg",
                    "pict": "image/pict",
                    "pct": "image/pict",
                    "pic": "image/pict",
                    "png": "image/png",
                    "svg": "image/svg+xml",
                    "svgz": "image/svg+xml",
                    "tif": "image/tiff",
                    "tiff": "image/tiff",
                    "psd": "image/vnd.adobe.photoshop",
                    "djvu": "image/vnd.djvu",
                    "djv": "image/vnd.djvu",
                    "dwg": "image/vnd.dwg",
                    "dxf": "image/vnd.dxf",
                    "dds": "image/vnd.ms-dds",
                    "webp": "image/webp",
                    "3ds": "image/x-3ds",
                    "ras": "image/x-cmu-raster",
                    "ico": "image/x-icon",
                    "bmp": "image/x-ms-bmp",
                    "pnm": "image/x-portable-anymap",
                    "pbm": "image/x-portable-bitmap",
                    "pgm": "image/x-portable-graymap",
                    "ppm": "image/x-portable-pixmap",
                    "rgb": "image/x-rgb",
                    "tga": "image/x-tga",
                    "xbm": "image/x-xbitmap",
                    "xpm": "image/x-xpixmap",
                    "xwd": "image/x-xwindowdump",
                    "eml": "message/rfc822",
                    "mht": "message/rfc822",
                    "mhtml": "message/rfc822",
                    "nws": "message/rfc822",
                    "obj": "model/obj",
                    "stl": "model/stl",
                    "dae": "model/vnd.collada+xml",
                    "ics": "text/calendar",
                    "ifb": "text/calendar",
                    "css": "text/css",
                    "csv": "text/csv",
                    "html": "text/html",
                    "htm": "text/html",
                    "shtml": "text/html",
                    "markdown": "text/markdown",
                    "md": "text/markdown",
                    "txt": "text/plain",
                    "text": "text/plain",
                    "conf": "text/plain",
                    "def": "text/plain",
                    "list": "text/plain",
                    "log": "text/plain",
                    "in": "text/plain",
                    "ini": "text/plain",
                    "rtx": "text/richtext",
                    "rtf": "text/rtf",
                    "tsv": "text/tab-separated-values",
                    "c": "text/x-c",
                    "cc": "text/x-c",
                    "cxx": "text/x-c",
                    "cpp": "text/x-c",
                    "h": "text/x-c",
                    "hh": "text/x-c",
                    "dic": "text/x-c",
                    "java": "text/x-java-source",
                    "lua": "text/x-lua",
                    "py": "text/x-python",
                    "etx": "text/x-setext",
                    "sgm": "text/x-sgml",
                    "sgml": "text/x-sgml",
                    "vcf": "text/x-vcard",
                    "xml": "text/xml",
                    "xul": "text/xul",
                    "yaml": "text/yaml",
                    "yml": "text/yaml",
                    "ts": "video/mp2t",
                    "mp4": "video/mp4",
                    "mp4v": "video/mp4",
                    "mpg4": "video/mp4",
                    "mpeg": "video/mpeg",
                    "m1v": "video/mpeg",
                    "mpa": "video/mpeg",
                    "mpe": "video/mpeg",
                    "mpg": "video/mpeg",
                    "mov": "video/quicktime",
                    "qt": "video/quicktime",
                    "webm": "video/webm",
                    "flv": "video/x-flv",
                    "m4v": "video/x-m4v",
                    "asf": "video/x-ms-asf",
                    "asx": "video/x-ms-asf",
                    "vob": "video/x-ms-vob",
                    "wmv": "video/x-ms-wmv",
                    "avi": "video/x-msvideo",
                    "*": "video/x-sgi-movie",
                }[suffix] || '';
            } catch (e) {
                console.error(e);
                return '';
            }
        }
    };

})();

/*
    cyrb53 (c) 2018 bryc (github.com/bryc)
    A fast and simple hash function with decent collision resistance.
    Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity.
    Public domain. Attribution appreciated.
*/
const cyrb53 = function(str, seed = 0) {
    let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
    for (let i = 0, ch; i < str.length; i++) {
        ch = str.charCodeAt(i);
        h1 = Math.imul(h1 ^ ch, 2654435761);
        h2 = Math.imul(h2 ^ ch, 1597334677);
    }
    h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909);
    h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909);
    return 4294967296 * (2097151 & h2) + (h1>>>0);
};

function onlyUnique (value, index, array) {
    return array.indexOf(value) === index;
}

function getUrlWithoutArguments() {
    return `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
}
