{"version":3,"sources":["jsdelivr-header.js","/gh/bgrins/filereader.js@master/filereader.js"],"names":[],"mappings":"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","file":"/gh/bgrins/filereader.js@master/filereader.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /gh/bgrins/filereader.js@master/filereader.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/*!\nFileReader.js - v0.99\nA lightweight wrapper for common FileReader usage.\nCopyright 2014 Brian Grinstead - MIT License.\nSee http://github.com/bgrins/filereader.js for documentation.\n*/\n\n(function(window, document) {\n\n    var FileReader = window.FileReader;\n    var FileReaderSyncSupport = false;\n    var workerScript = \"self.addEventListener('message', function(e) { var data=e.data; try { var reader = new FileReaderSync; postMessage({ result: reader[data.readAs](data.file), extra: data.extra, file: data.file})} catch(e){ postMessage({ result:'error', extra:data.extra, file:data.file}); } }, false);\";\n    var syncDetectionScript = \"onmessage = function(e) { postMessage(!!FileReaderSync); };\";\n    var fileReaderEvents = ['loadstart', 'progress', 'load', 'abort', 'error', 'loadend'];\n    var sync = false;\n    var FileReaderJS = window.FileReaderJS = {\n        enabled: false,\n        setupInput: setupInput,\n        setupDrop: setupDrop,\n        setupClipboard: setupClipboard,\n        setSync: function (value) {\n            sync = value;\n\n            if (sync && !FileReaderSyncSupport) {\n                checkFileReaderSyncSupport();\n            }\n        },\n        getSync: function() {\n            return sync && FileReaderSyncSupport;\n        },\n        output: [],\n        opts: {\n            dragClass: \"drag\",\n            accept: false,\n            readAsDefault: 'DataURL',\n            readAsMap: {\n            },\n            on: {\n                loadstart: noop,\n                progress: noop,\n                load: noop,\n                abort: noop,\n                error: noop,\n                loadend: noop,\n                skip: noop,\n                groupstart: noop,\n                groupend: noop,\n                beforestart: noop\n            }\n        }\n    };\n\n    // Setup jQuery plugin (if available)\n    if (typeof(jQuery) !== \"undefined\") {\n        jQuery.fn.fileReaderJS = function(opts) {\n            return this.each(function() {\n                if (jQuery(this).is(\"input\")) {\n                    setupInput(this, opts);\n                }\n                else {\n                    setupDrop(this, opts);\n                }\n            });\n        };\n\n        jQuery.fn.fileClipboard = function(opts) {\n            return this.each(function() {\n                setupClipboard(this, opts);\n            });\n        };\n    }\n\n    // Not all browsers support the FileReader interface. Return with the enabled bit = false.\n    if (!FileReader) {\n        return;\n    }\n\n\n    // makeWorker is a little wrapper for generating web workers from strings\n    function makeWorker(script) {\n        var URL = window.URL || window.webkitURL;\n        var Blob = window.Blob;\n        var Worker = window.Worker;\n\n        if (!URL || !Blob || !Worker || !script) {\n            return null;\n        }\n\n        var blob = new Blob([script]);\n        var worker = new Worker(URL.createObjectURL(blob));\n        return worker;\n    }\n\n    // setupClipboard: bind to clipboard events (intended for document.body)\n    function setupClipboard(element, opts) {\n\n        if (!FileReaderJS.enabled) {\n            return;\n        }\n        var instanceOptions = extend(extend({}, FileReaderJS.opts), opts);\n\n        element.addEventListener(\"paste\", onpaste, false);\n\n        function onpaste(e) {\n            var files = [];\n            var clipboardData = e.clipboardData || {};\n            var items = clipboardData.items || [];\n\n            for (var i = 0; i < items.length; i++) {\n                var file = items[i].getAsFile();\n\n                if (file) {\n\n                    // Create a fake file name for images from clipboard, since this data doesn't get sent\n                    var matches = new RegExp(\"/\\(.*\\)\").exec(file.type);\n                    if (!file.name && matches) {\n                        var extension = matches[1];\n                        file.name = \"clipboard\" + i + \".\" + extension;\n                    }\n\n                    files.push(file);\n                }\n            }\n\n            if (files.length) {\n                processFileList(e, files, instanceOptions);\n                e.preventDefault();\n                e.stopPropagation();\n            }\n        }\n    }\n\n    // setupInput: bind the 'change' event to an input[type=file]\n    function setupInput(input, opts) {\n\n        if (!FileReaderJS.enabled) {\n            return;\n        }\n        var instanceOptions = extend(extend({}, FileReaderJS.opts), opts);\n\n        input.addEventListener(\"change\", inputChange, false);\n        input.addEventListener(\"drop\", inputDrop, false);\n\n        function inputChange(e) {\n            processFileList(e, input.files, instanceOptions);\n        }\n\n        function inputDrop(e) {\n            e.stopPropagation();\n            e.preventDefault();\n            processFileList(e, e.dataTransfer.files, instanceOptions);\n        }\n    }\n\n    // setupDrop: bind the 'drop' event for a DOM element\n    function setupDrop(dropbox, opts) {\n\n        if (!FileReaderJS.enabled) {\n            return;\n        }\n        var instanceOptions = extend(extend({}, FileReaderJS.opts), opts);\n        var dragClass = instanceOptions.dragClass;\n        var initializedOnBody = false;\n\n        // Bind drag events to the dropbox to add the class while dragging, and accept the drop data transfer.\n        dropbox.addEventListener(\"dragenter\", onlyWithFiles(dragenter), false);\n        dropbox.addEventListener(\"dragleave\", onlyWithFiles(dragleave), false);\n        dropbox.addEventListener(\"dragover\", onlyWithFiles(dragover), false);\n        dropbox.addEventListener(\"drop\", onlyWithFiles(drop), false);\n\n        // Bind to body to prevent the dropbox events from firing when it was initialized on the page.\n        document.body.addEventListener(\"dragstart\", bodydragstart, true);\n        document.body.addEventListener(\"dragend\", bodydragend, true);\n        document.body.addEventListener(\"drop\", bodydrop, false);\n\n        function bodydragend(e) {\n            initializedOnBody = false;\n        }\n\n        function bodydragstart(e) {\n            initializedOnBody = true;\n        }\n\n        function bodydrop(e) {\n            if (e.dataTransfer.files && e.dataTransfer.files.length ){\n                e.stopPropagation();\n                e.preventDefault();\n            }\n        }\n\n        function onlyWithFiles(fn) {\n            return function() {\n                if (!initializedOnBody) {\n                    fn.apply(this, arguments);\n                }\n            };\n        }\n\n        function drop(e) {\n            e.stopPropagation();\n            e.preventDefault();\n            if (dragClass) {\n                removeClass(dropbox, dragClass);\n            }\n            processFileList(e, e.dataTransfer.files, instanceOptions);\n        }\n\n        function dragenter(e) {\n            e.stopPropagation();\n            e.preventDefault();\n            if (dragClass) {\n                addClass(dropbox, dragClass);\n            }\n        }\n\n        function dragleave(e) {\n            if (dragClass) {\n                removeClass(dropbox, dragClass);\n            }\n        }\n\n        function dragover(e) {\n            e.stopPropagation();\n            e.preventDefault();\n            if (dragClass) {\n                addClass(dropbox, dragClass);\n            }\n        }\n    }\n\n    // setupCustomFileProperties: modify the file object with extra properties\n    function setupCustomFileProperties(files, groupID) {\n        for (var i = 0; i < files.length; i++) {\n            var file = files[i];\n            file.extra = {\n                nameNoExtension: file.name.substring(0, file.name.lastIndexOf('.')),\n                extension: file.name.substring(file.name.lastIndexOf('.') + 1),\n                fileID: i,\n                uniqueID: getUniqueID(),\n                groupID: groupID,\n                prettySize: prettySize(file.size)\n            };\n        }\n    }\n\n    // getReadAsMethod: return method name for 'readAs*' - http://www.w3.org/TR/FileAPI/#reading-a-file\n    function getReadAsMethod(type, readAsMap, readAsDefault) {\n        for (var r in readAsMap) {\n            if (type.match(new RegExp(r))) {\n                return 'readAs' + readAsMap[r];\n            }\n        }\n        return 'readAs' + readAsDefault;\n    }\n\n    // processFileList: read the files with FileReader, send off custom events.\n    function processFileList(e, files, opts) {\n\n        var filesLeft = files.length;\n        var group = {\n            groupID: getGroupID(),\n            files: files,\n            started: new Date()\n        };\n\n        function groupEnd() {\n            group.ended = new Date();\n            opts.on.groupend(group);\n        }\n\n        function groupFileDone() {\n            if (--filesLeft === 0) {\n                groupEnd();\n            }\n        }\n\n        FileReaderJS.output.push(group);\n        setupCustomFileProperties(files, group.groupID);\n\n        opts.on.groupstart(group);\n\n        // No files in group - end immediately\n        if (!files.length) {\n            groupEnd();\n            return;\n        }\n\n        var supportsSync = sync && FileReaderSyncSupport;\n        var syncWorker;\n\n        // Only initialize the synchronous worker if the option is enabled - to prevent the overhead\n        if (supportsSync) {\n            syncWorker = makeWorker(workerScript);\n            syncWorker.onmessage = function(e) {\n                var file = e.data.file;\n                var result = e.data.result;\n\n                // Workers seem to lose the custom property on the file object.\n                if (!file.extra) {\n                    file.extra = e.data.extra;\n                }\n\n                file.extra.ended = new Date();\n\n                // Call error or load event depending on success of the read from the worker.\n                opts.on[result === \"error\" ? \"error\" : \"load\"]({ target: { result: result } }, file);\n                groupFileDone();\n            };\n        }\n\n        Array.prototype.forEach.call(files, function(file) {\n\n            file.extra.started = new Date();\n\n            if (opts.accept && !file.type.match(new RegExp(opts.accept))) {\n                opts.on.skip(file);\n                groupFileDone();\n                return;\n            }\n\n            if (opts.on.beforestart(file) === false) {\n                opts.on.skip(file);\n                groupFileDone();\n                return;\n            }\n\n            var readAs = getReadAsMethod(file.type, opts.readAsMap, opts.readAsDefault);\n\n            if (syncWorker) {\n                syncWorker.postMessage({\n                    file: file,\n                    extra: file.extra,\n                    readAs: readAs\n                });\n            }\n            else {\n\n                var reader = new FileReader();\n                reader.originalEvent = e;\n\n                fileReaderEvents.forEach(function(eventName) {\n                    reader['on' + eventName] = function(e) {\n                        if (eventName == 'load' || eventName == 'error') {\n                            file.extra.ended = new Date();\n                        }\n                        opts.on[eventName](e, file);\n                        if (eventName == 'loadend') {\n                            groupFileDone();\n                        }\n                    };\n                });\n                reader[readAs](file);\n            }\n        });\n    }\n\n    // checkFileReaderSyncSupport: Create a temporary worker and see if FileReaderSync exists\n    function checkFileReaderSyncSupport() {\n        var worker = makeWorker(syncDetectionScript);\n        if (worker) {\n            worker.onmessage =function(e) {\n                FileReaderSyncSupport = e.data;\n            };\n            worker.postMessage({});\n        }\n    }\n\n    // noop: do nothing\n    function noop() {\n\n    }\n\n    // extend: used to make deep copies of options object\n    function extend(destination, source) {\n        for (var property in source) {\n            if (source[property] && source[property].constructor &&\n                source[property].constructor === Object) {\n                destination[property] = destination[property] || {};\n                arguments.callee(destination[property], source[property]);\n            }\n            else {\n                destination[property] = source[property];\n            }\n        }\n        return destination;\n    }\n\n    // hasClass: does an element have the css class?\n    function hasClass(el, name) {\n        return new RegExp(\"(?:^|\\\\s+)\" + name + \"(?:\\\\s+|$)\").test(el.className);\n    }\n\n    // addClass: add the css class for the element.\n    function addClass(el, name) {\n        if (!hasClass(el, name)) {\n          el.className = el.className ? [el.className, name].join(' ') : name;\n        }\n    }\n\n    // removeClass: remove the css class from the element.\n    function removeClass(el, name) {\n        if (hasClass(el, name)) {\n          var c = el.className;\n          el.className = c.replace(new RegExp(\"(?:^|\\\\s+)\" + name + \"(?:\\\\s+|$)\", \"g\"), \" \").replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n        }\n    }\n\n    // prettySize: convert bytes to a more readable string.\n    function prettySize(bytes) {\n        var s = ['bytes', 'kb', 'MB', 'GB', 'TB', 'PB'];\n        var e = Math.floor(Math.log(bytes)/Math.log(1024));\n        return (bytes/Math.pow(1024, Math.floor(e))).toFixed(2)+\" \"+s[e];\n    }\n\n    // getGroupID: generate a unique int ID for groups.\n    var getGroupID = (function(id) {\n        return function() {\n            return id++;\n        };\n    })(0);\n\n    // getUniqueID: generate a unique int ID for files\n    var getUniqueID = (function(id) {\n        return function() {\n            return id++;\n        };\n    })(0);\n\n    // The interface is supported, bind the FileReaderJS callbacks\n    FileReaderJS.enabled = true;\n\n})(this, document);"]}