From a8ef5ec75b409d9a00f835291dcfe02320aca602 Mon Sep 17 00:00:00 2001 From: djmaze Date: Wed, 12 Aug 2020 11:49:40 +0200 Subject: [PATCH] Bugfix: Email addressparser Cleanup vendor scripts --- README.md | 18 +- dev/Common/Utils.js | 30 +- dev/External/ko.js | 22 +- dev/Model/Email.js | 52 +- dev/View/Popup/Compose.js | 2 +- vendors/inputosaurus/inputosaurus.js | 127 +-- vendors/jua/jua.js | 1067 +++++++++++++------------- vendors/jua/jua.min.js | 2 +- vendors/keymaster/keymaster.js | 34 +- vendors/qr.js/qr.js | 263 +------ vendors/qr.js/qr.min.js | 2 +- 11 files changed, 651 insertions(+), 968 deletions(-) diff --git a/README.md b/README.md index 590b21e06..35f44c5d8 100644 --- a/README.md +++ b/README.md @@ -75,23 +75,23 @@ Things might work in Edge 15-18, Firefox 47-62 and Chrome 54-68 due to one polyf |js/* |1.14.0 |native |gzip 1.14 |gzip | |----------- |--------: |--------: |--------: |--------: | -|admin.js |2.130.942 |1.133.275 | 485.481 | 274.632 | -|app.js |4.184.455 |2.844.189 | 932.725 | 664.075 | +|admin.js |2.130.942 |1.130.247 | 485.481 | 273.277 | +|app.js |4.184.455 |2.840.968 | 932.725 | 662.061 | |boot.js | 671.522 | 44.029 | 169.502 | 15.460 | -|libs.js | 647.614 | 431.049 | 194.728 | 132.315 | +|libs.js | 647.614 | 426.949 | 194.728 | 131.409 | |polyfills.js | 325.834 | 0 | 71.825 | 0 | -|TOTAL js |7.960.367 |4.452.542 |1.854.261 |1.086.482 | +|TOTAL js |7.960.367 |4.442.193 |1.854.261 |1.082.207 | |js/min/* |1.14.0 |native |gzip 1.14 |gzip | |--------------- |--------: |--------: |--------: |--------: | -|admin.min.js | 252.147 | 153.095 | 73.657 | 43.734 | -|app.min.js | 511.202 | 378.695 |140.462 | 99.511 | +|admin.min.js | 252.147 | 152.759 | 73.657 | 43.564 | +|app.min.js | 511.202 | 378.335 |140.462 | 99.341 | |boot.min.js | 66.007 | 5.589 | 22.567 | 2.333 | -|libs.min.js | 572.545 | 387.636 |176.720 |122.519 | +|libs.min.js | 572.545 | 385.139 |176.720 |121.907 | |polyfills.min.js | 32.452 | 0 | 11.312 | 0 | -|TOTAL js/min |1.434.353 | 925.015 |424.718 |268.097 | +|TOTAL js/min |1.434.353 | 921.822 |424.718 |267.145 | -509.338 bytes (156.621 gzip) is not much, but it feels faster. +512.531 bytes (157.573 gzip) is not much, but it feels faster. |css/* |1.14.0 |native | diff --git a/dev/Common/Utils.js b/dev/Common/Utils.js index 6eb91ccf5..f0f188cd9 100644 --- a/dev/Common/Utils.js +++ b/dev/Common/Utils.js @@ -7,19 +7,15 @@ import { Mime } from 'Common/Mime'; const $ = jQuery, $div = $('
'), - isArray = Array.isArray; - -var htmlspecialchars = ((de,se,gt,lt,sq,dq,bt) => { - return (str, quote_style = 3, double_encode = true) => { - str = (''+str) - .replace(double_encode?de:se,'&') - .replace(gt,'<') - .replace(lt,'>') - .replace(bt,'`'); - if (quote_style & 1) { str = str.replace(sq,'''); } - return (quote_style & 2) ? str.replace(dq,'"') : str; - }; -})(/&/g,/&(?![\w#]+;)/gi,//g,/'/g,/"/g,/`/g); + isArray = Array.isArray, + htmlmap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' + }, + htmlspecialchars = str => (''+str).replace(/[&<>"']/g, m => htmlmap[m]); /** * @param {*} value @@ -89,15 +85,13 @@ export function simpleQueryParser(queryString) { * @returns {string} */ export function fakeMd5(len = 32) { - const line = '0123456789abcdefghijklmnopqrstuvwxyz', - lineLen = line.length; + const line = '0123456789abcdefghijklmnopqrstuvwxyz'; len = pInt(len); let result = ''; - while (result.length < len) { - result += line.substr(Math.round(Math.random() * lineLen), 1); - } + while (len--) + result += line.substr(Math.round(Math.random() * 36), 1); return result; } diff --git a/dev/External/ko.js b/dev/External/ko.js index 1b4c90b94..b4609240d 100644 --- a/dev/External/ko.js +++ b/dev/External/ko.js @@ -747,35 +747,33 @@ ko.bindingHandlers.emailsTags = { $el = $(element), fValue = fValueAccessor(), fAllBindings = fAllBindingsAccessor(), - fAutoCompleteSource = fAllBindings.autoCompleteSource || null, - inputDelimiters = [',', ';', '\n'], - fFocusCallback = (value) => { - if (fValue && fValue.focused) { - fValue.focused(!!value); - } - }; + inputDelimiters = [',', ';', '\n']; $el.inputosaurus({ parseOnBlur: true, allowDragAndDrop: true, - focusCallback: fFocusCallback, + focusCallback: value => { + if (fValue && fValue.focused) { + fValue.focused(!!value); + } + }, inputDelimiters: inputDelimiters, - autoCompleteSource: fAutoCompleteSource, - splitHook: (value) => { + autoCompleteSource: fAllBindings.autoCompleteSource || null, + splitHook: value => { const v = value.trim(); if (v && inputDelimiters.includes(v.substr(-1))) { return EmailModel.splitEmailLine(value); } return null; }, - parseHook: (input) => + parseHook: input => input.map(inputValue => { const values = EmailModel.parseEmailLine(inputValue); return values.length ? values : inputValue; }).flat(Infinity).map( item => (item.toLine ? [item.toLine(false), item] : [item, null]) ), - change: (event) => { + change: event => { $el.data('EmailsTagsValue', event.target.value); fValue(event.target.value); } diff --git a/dev/Model/Email.js b/dev/Model/Email.js index 147b29cc1..ac1adb1b8 100644 --- a/dev/Model/Email.js +++ b/dev/Model/Email.js @@ -1,4 +1,4 @@ -import { encodeHtml, isNonEmptyArray } from 'Common/Utils'; +import { encodeHtml } from 'Common/Utils'; 'use strict'; @@ -64,12 +64,10 @@ function _handleAddress(tokens) { comment: [], group: [], text: [] - - // Filter out , (comments) and regular text }; - for (var i = 0, len = tokens.length; i < len; i++) { - var token = tokens[i]; + // Filter out , (comments) and regular text + tokens.forEach(token => { if (token.type === 'operator') { switch (token.value) { case '<': @@ -85,12 +83,10 @@ function _handleAddress(tokens) { default: state = 'text'; } - } else { - if (token.value) { - data[state].push(token.value); - } + } else if (token.value) { + data[state].push(token.value); } - } + }); // If there is no text but a comment, replace the two if (!data.text.length && data.comment.length) { @@ -108,25 +104,25 @@ function _handleAddress(tokens) { } else { // If no address was found, try to detect one from regular text if (!data.address.length && data.text.length) { - for (var _i = data.text.length - 1; _i >= 0; _i--) { - if (data.text[_i].match(/^[^@\s]+@[^@\s]+$/)) { - data.address = data.text.splice(_i, 1); + var i = data.text.length; + while (i--) { + if (data.text[i].match(/^[^@\s]+@[^@\s]+$/)) { + data.address = data.text.splice(i, 1); break; } } - var _regexHandler = function _regexHandler(address) { - if (!data.address.length) { - data.address = [address.trim()]; - return ' '; - } - return address; - }; - // still no address if (!data.address.length) { - for (var _i2 = data.text.length - 1; _i2 >= 0; _i2--) { - data.text[_i2] = data.text[_i2].replace(/\s*\b[^@\s]+@[^@\s]+\b\s*/, _regexHandler).trim(); + i = data.text.length; + while (i--) { + data.text[i] = data.text[i].replace(/\s*\b[^@\s]+@[^@\s]+\b\s*/, address => { + if (!data.address.length) { + data.address = [address.trim()]; + return ''; + } + return address.trim(); + }); if (data.address.length) { break; } @@ -202,8 +198,8 @@ class Tokenizer } tokenize() { - var list = [], i = this.str.length; - while (i--) this.checkChar(this.str[i]); + var list = []; + [...this.str].forEach(c => this.checkChar(c)); this.list.forEach(node => { node.value = (node.value || '').toString().trim(); @@ -420,7 +416,7 @@ class EmailModel { static splitEmailLine(line) { const parsedResult = addressparser(line); - if (isNonEmptyArray(parsedResult)) { + if (parsedResult.length) { const result = []; let exists = false; parsedResult.forEach((item) => { @@ -443,7 +439,7 @@ class EmailModel { static parseEmailLine(line) { const parsedResult = addressparser(line); - if (isNonEmptyArray(parsedResult)) { + if (parsedResult.length) { return parsedResult.map(item => item.address ? new EmailModel(item.address.replace(/^[<]+(.*)[>]+$/g, '$1'), item.name || '') : null ).filter(value => !!value); @@ -463,7 +459,7 @@ class EmailModel { } const result = addressparser(emailAddress); - if (isNonEmptyArray(result) && result[0]) { + if (result.length) { this.name = result[0].name || ''; this.email = result[0].address || ''; this.clearDuplicateName(); diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index 8942314ab..160dcbbc1 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -1401,7 +1401,7 @@ class ComposePopupView extends AbstractViewNext { } }); - this.addAttachmentEnabled(true).dragAndDropEnabled(oJua.isDragAndDropSupported()); + this.addAttachmentEnabled(true).dragAndDropEnabled(true); } else { this.addAttachmentEnabled(false).dragAndDropEnabled(false); } diff --git a/vendors/inputosaurus/inputosaurus.js b/vendors/inputosaurus/inputosaurus.js index 6686daa8b..ab5ba5ec2 100644 --- a/vendors/inputosaurus/inputosaurus.js +++ b/vendors/inputosaurus/inputosaurus.js @@ -18,7 +18,7 @@ */ -(function($) { +($ => { var inputosaurustext = { @@ -39,22 +39,12 @@ // the value tags are created on the fly when an inputDelimiter is detected inputDelimiters : [',', ';'], - // this separator is used to rejoin all input items back to the value of the original - outputDelimiter : ',', - - allowDuplicates : false, - allowDragAndDrop : true, focusCallback : null, parseOnBlur : false, - // optional wrapper for widget - wrapperElement : null, - - width : null, - // simply passing an autoComplete source (array, string or function) will instantiate autocomplete functionality autoCompleteSource : '', @@ -65,17 +55,14 @@ // the array of tag names is passed and expected to be returned as an array after manipulation parseHook : null, - elementHook : null, - - // define a placeholder to display when the input is empty - placeholder: null + splitHook : null }, _create: function() { var widget = this, els = {}, o = widget.options, - placeholder = o.placeholder || this.element.attr('placeholder') || null; + placeholder = this.element.attr('placeholder') || null; this._chosenValues = []; @@ -85,7 +72,7 @@ if (this.options.allowDragAndDrop) { els.ul.droppable({ - 'drop': function(event, ui) { + 'drop': (event, ui) => { ui.draggable.addClass('inputosaurus-dropped'); els.input.val(ui.draggable.data('inputosaurus-value')); @@ -106,9 +93,9 @@ els.origInputCont = $('
  • '); els.lastEdit = ''; - els.input.on('focus', function () { + els.input.on('focus', () => { widget._focusTrigger(true); - }).on('blur', function () { + }).on('blur', () => { widget._focusTrigger(false); }); @@ -116,21 +103,15 @@ if (placeholder) { o.placeholder = placeholder; els.input.attr('placeholder', o.placeholder); - if (o.width) { - els.input.css('min-width', o.width - 50); - } } - o.wrapperElement && o.wrapperElement.append(els.ul); - this.element.replaceWith(o.wrapperElement || els.ul); + this.element.replaceWith(els.ul); els.origInputCont.append(this.element).hide(); els.inputCont.append(els.input); els.ul.append(els.inputCont); els.ul.append(els.origInputCont); - o.width && els.ul.css('width', o.width); - this.elements = els; widget._attachEvents(); @@ -148,13 +129,10 @@ _focusTrigger : function (bValue) { var widget = this; - window.clearTimeout(this._focusTriggerTimer); - this._focusTriggerTimer = window.setTimeout(function () { + clearTimeout(this._focusTriggerTimer); + this._focusTriggerTimer = setTimeout(() => { widget.elements.ul[!bValue ? 'removeClass' : 'addClass']('inputosaurus-focused'); - if (widget.options.focusCallback) - { - widget.options.focusCallback(bValue); - } + widget.options.focusCallback(bValue); }, 10); }, @@ -169,7 +147,7 @@ source : this.options.autoCompleteSource, minLength : 1, autoFocus : true, - select : function(ev, ui){ + select : (ev, ui) => { ev.preventDefault(); widget.elements.input.val(ui.item.value); widget.parseInput(); @@ -190,9 +168,7 @@ } } }, - focus: function () { - return false; - } + focus: () => false }); } }, @@ -210,12 +186,6 @@ } }, - /*_closeAutoCompleteMenu : function() { - if(this.options.autoCompleteSource){ - this.elements.input.autocomplete('close'); - } - },*/ - parseInput : function(ev) { var widget = (ev && ev.data.widget) || this, val, @@ -226,11 +196,7 @@ val = widget.elements.input.val(); if (val) { - if ($.isFunction(widget.options.splitHook)) { - hook = widget.options.splitHook(val); - } else { - delimiterFound = widget._containsDelimiter(val); - } + hook = widget.options.splitHook(val); } if (hook) { @@ -246,15 +212,13 @@ values.push(val); } - $.isFunction(widget.options.parseHook) && (values = widget.options.parseHook(values)); + values = widget.options.parseHook(values); if(values.length){ widget._setChosen(values); widget.elements.input.val(''); widget._resizeInput(); } - - widget._resetPlaceholder(); }, _inputFocus : function(ev) { @@ -284,7 +248,7 @@ // reposition autoComplete menu as
      grows and shrinks vertically if(widget.options.autoCompleteSource){ - setTimeout(function(){widget._autoCompleteMenuPosition.call(widget);}, 200); + setTimeout(()=>widget._autoCompleteMenuPosition.call(widget), 200); } }, @@ -297,7 +261,7 @@ var widget = (ev && ev.data.widget) || this; inputosaurustext.fakeSpan.text(widget.elements.input.val()); -// window.setTimeout(function () { +// setTimeout(function () { var txtWidth = 25 + inputosaurustext.fakeSpan.width(); txtWidth = txtWidth > 50 ? txtWidth : 50; txtWidth = txtWidth < 500 ? txtWidth : 500; @@ -305,18 +269,6 @@ // }, 1); }, - // resets placeholder on representative input - _resetPlaceholder: function () { - var placeholder = this.options.placeholder, - input = this.elements.input, - width = this.options.width || 'inherit'; - if (placeholder && this.element.val().length === 0) { - input.attr('placeholder', placeholder).css('min-width', width - 50) - }else { - input.attr('placeholder', '').css('min-width', 'inherit') - } - }, - // if our input contains no value and backspace has been pressed, select the last tag _inputBackspace : function(ev) { var widget = (ev && ev.data.widget) || this, @@ -349,7 +301,7 @@ next = false ; - $.each(widget._chosenValues, function(i,v) { + $.each(widget._chosenValues, (i,v) => { if (v.key === tagKey) { tagName = v.value; @@ -369,15 +321,13 @@ $li.after(widget.elements.inputCont); widget.elements.input.val(tagName); - window.setTimeout(function () { - widget.elements.input.select(); - }, 100); + setTimeout(() => widget.elements.input.select(), 100); widget._removeTag(ev); widget._resizeInput(ev); }, - _tagKeypress : function(ev) { + _tagKeypress : ev => { var widget = ev.data.widget; switch(ev.which){ @@ -439,7 +389,7 @@ var found = false; - $.each(this.options.inputDelimiters, function(k,v) { + $.each(this.options.inputDelimiters, (k,v) => { if(tagStr.indexOf(v) !== -1){ found = v; } @@ -455,7 +405,7 @@ return false; } - $.each(valArr, function(k,a) { + $.each(valArr, (k,a) => { var v = '', exists = false, lastIndex = -1, obj = { @@ -466,7 +416,7 @@ v = $.trim(a[0]); - $.each(self._chosenValues, function(kk, vv) { + $.each(self._chosenValues, (kk, vv) => { if (vv.value === self.elements.lastEdit) { lastIndex = kk; @@ -475,7 +425,7 @@ vv.value === v && (exists = true); }); - if(v !== '' && a && a[1] && (!exists || self.options.allowDuplicates)){ + if(v !== '' && a && a[1] && !exists){ obj.key = 'mi_' + Math.random().toString( 16 ).slice( 2, 10 ); obj.value = v; @@ -505,11 +455,10 @@ }, _buildValue : function() { - var widget = this, - value = ''; + var value = ''; - $.each(this._chosenValues, function(k,v) { - value += value.length ? widget.options.outputDelimiter + v.value : v.value; + $.each(this._chosenValues, (k,v) => { + value += value.length ? ',' + v.value : v.value; }); return value; @@ -542,14 +491,10 @@ $li.draggable({ 'revert': 'invalid', 'revertDuration': 200, - 'start': function(event, ui) { - ui.helper.__widget = widget; - } + 'start': (event, ui) => ui.helper.__widget = widget }); } - $.isFunction(this.options.elementHook) && (this.options.elementHook($li, obj)); - return $li; } }, @@ -559,7 +504,7 @@ this.elements.ul.find('li:not(.inputosaurus-required)').remove(); - $.each(this._chosenValues, function(k, v) { + $.each(this._chosenValues, (k, v) => { var el = self._createTag(v.value, v.key, v.obj); if (el) { self.elements.ul.find('li.inputosaurus-input').before(el); @@ -573,7 +518,7 @@ widget = (ev && ev.data.widget) || this; - $.each(widget._chosenValues, function(k,v) { + $.each(widget._chosenValues, (k,v) => { if(key === v.key){ indexFound = k; } @@ -584,9 +529,7 @@ widget._setValue(widget._buildValue()); $(ev.currentTarget).closest('li').remove(); - window.setTimeout(function () { - widget.elements.input.focus(); - }, 100); + setTimeout(() => widget.elements.input.focus(), 100); }, _removeDraggedTag : function ($li) { @@ -596,7 +539,7 @@ indexFound = false ; - $.each(widget._chosenValues, function(k,v) { + $.each(widget._chosenValues, (k,v) => { if (key === v.key) { indexFound = k; @@ -634,12 +577,10 @@ } }, - _tagFocus : function(ev) { - $(ev.currentTarget).parent()[ev.type === 'focusout' ? 'removeClass' : 'addClass']('inputosaurus-selected'); - }, + _tagFocus : ev => $(ev.currentTarget).parent()[ev.type === 'focusout' ? 'removeClass' : 'addClass']('inputosaurus-selected'), refresh : function() { - var delim = this.options.outputDelimiter, + var delim = ',', val = this.element.val(), values = []; @@ -659,7 +600,7 @@ if (values.length) { this._chosenValues = []; - $.isFunction(this.options.parseHook) && (values = this.options.parseHook(values)); + values = this.options.parseHook(values); this._setChosen(values); this._renderTags(); diff --git a/vendors/jua/jua.js b/vendors/jua/jua.js index fe504fc9b..909b231af 100644 --- a/vendors/jua/jua.js +++ b/vendors/jua/jua.js @@ -7,7 +7,67 @@ $ = jQuery; const - defined = v => undefined !== v; + defined = v => undefined !== v, + /** + * @param {*} aItems + * @param {Function} fFileCallback + * @param {number=} iLimit = 20 + * @param {Function=} fLimitCallback + */ + getDataFromFiles = (aItems, fFileCallback, iLimit, fLimitCallback) => + { + if (aItems && aItems.length) + { + var + iInputLimit = 0, + oFile = null, + bUseLimit = false, + bCallLimit = false + ; + + iLimit = defined(iLimit) ? parseInt(iLimit || 0, 10) : iDefLimit; + iInputLimit = iLimit; + bUseLimit = 0 < iLimit; + Array.from(aItems).forEach(oItem => { + if (oItem) + { + if (!bUseLimit) { + if (0 <= --iLimit) + { + oFile = Utils.getDataFromFile(oItem); + oFile && fFileCallback(oFile); + } + } + else if (!bCallLimit) + { + if (0 > iLimit && fLimitCallback) + { + bCallLimit = true; + fLimitCallback(iInputLimit); + } + } + } + }); + } + }, + /** + * @param {number=} iLen + * @return {string} + */ + fakeMd5 = iLen => + { + var + sResult = '', + sLine = '0123456789abcdefghijklmnopqrstuvwxyz' + ; + + iLen = defined(iLen) ? parseInt(iLen || 0, 10) : 32; + + while (iLen--) + sResult += sLine.substr(Math.round(Math.random() * 36), 1); + + return sResult; + }; var Utils = { /** @@ -78,30 +138,9 @@ }, /** - * @param {number=} iLen * @return {string} */ - fakeMd5 : iLen => - { - var - sResult = '', - sLine = '0123456789abcdefghijklmnopqrstuvwxyz' - ; - - iLen = defined(iLen) ? parseInt(iLen || 0, 10) : 32; - - while (sResult.length < iLen) - { - sResult += sLine.substr(Math.round(Math.random() * sLine.length), 1); - } - - return sResult; - }, - - /** - * @return {string} - */ - getNewUid : () => 'jua-uid-' + Utils.fakeMd5(16) + '-' + (new Date()).getTime().toString(), + getNewUid : () => 'jua-uid-' + fakeMd5(16) + '-' + (new Date()).getTime().toString(), /** * @param {*} oFile @@ -134,57 +173,6 @@ }; }, - /** - * @param {*} aItems - * @param {Function} fFileCallback - * @param {number=} iLimit = 20 - * @param {Function=} fLimitCallback - */ - getDataFromFiles : (aItems, fFileCallback, iLimit, fLimitCallback) => - { - var - iInputLimit = 0, - iLen = 0, - iIndex = 0, - oItem = null, - oFile = null, - bUseLimit = false, - bCallLimit = false - ; - - iLimit = defined(iLimit) ? parseInt(iLimit || 0, 10) : iDefLimit; - iInputLimit = iLimit; - bUseLimit = 0 < iLimit; - - aItems = aItems && 0 < aItems.length ? aItems : null; - if (aItems) - { - for (iIndex = 0, iLen = aItems.length; iIndex < iLen; iIndex++) - { - oItem = aItems[iIndex]; - if (oItem) - { - if (!bUseLimit || 0 <= --iLimit) - { - oFile = Utils.getDataFromFile(oItem); - if (oFile) - { - fFileCallback(oFile); - } - } - else if (bUseLimit && !bCallLimit) - { - if (0 > iLimit && fLimitCallback) - { - bCallLimit = true; - fLimitCallback(iInputLimit); - } - } - } - } - } - }, - /** * @param {*} oInput * @param {Function} fFileCallback @@ -193,10 +181,10 @@ */ getDataFromInput : (oInput, fFileCallback, iLimit, fLimitCallback) => { - var aFiles = oInput && oInput.files && 0 < oInput.files.length ? oInput.files : null; + var aFiles = oInput && 0 < oInput.files.length ? oInput.files : null; if (aFiles) { - Utils.getDataFromFiles(aFiles, fFileCallback, iLimit, fLimitCallback); + getDataFromFiles(aFiles, fFileCallback, iLimit, fLimitCallback); } else { @@ -249,10 +237,7 @@ aFiles = (Utils.getValue(oEvent, 'files', null) || (oEvent.dataTransfer ? Utils.getValue(oEvent.dataTransfer, 'files', null) : null)); - if (aFiles && 0 < aFiles.length) - { - Utils.getDataFromFiles(aFiles, fFileCallback, iLimit, fLimitCallback); - } + getDataFromFiles(aFiles, fFileCallback, iLimit, fLimitCallback); } }, @@ -306,12 +291,186 @@ * @param {Jua} oJua * @param {Object} oOptions */ - function AjaxDriver(oJua, oOptions) + class AjaxDriver { - this.oXhrs = {}; - this.oUids = {}; - this.oJua = oJua; - this.oOptions = oOptions; + constructor(oJua, oOptions) + { + this.oXhrs = {}; + this.oUids = {}; + this.oJua = oJua; + this.oOptions = oOptions; + } + + /** + * @param {string} sUid + */ + regTaskUid(sUid) + { + this.oUids[sUid] = true; + } + + /** + * @param {string} sUid + * @param {?} oFileInfo + * @param {Function} fCallback + */ + uploadTask(sUid, oFileInfo, fCallback) + { + if (false === this.oUids[sUid] || !oFileInfo || !oFileInfo['File']) + { + fCallback(null, sUid); + return false; + } + + try + { + var + self = this, + oXhr = new XMLHttpRequest(), + oFormData = new FormData(), + sAction = Utils.getValue(this.oOptions, 'action', ''), + aHidden = Utils.getValue(this.oOptions, 'hidden', {}), + fStartFunction = this.oJua.getEvent('onStart'), + fCompleteFunction = this.oJua.getEvent('onComplete'), + fProgressFunction = this.oJua.getEvent('onProgress') + ; + + oXhr.open('POST', sAction, true); + + if (fProgressFunction && oXhr.upload) + { + oXhr.upload.onprogress = function (oEvent) { + if (oEvent && oEvent.lengthComputable && defined(oEvent.loaded) && defined(oEvent.total)) + { + fProgressFunction(sUid, oEvent.loaded, oEvent.total); + } + }; + } + + oXhr.onreadystatechange = function () { + if (4 === oXhr.readyState && 200 === oXhr.status) + { + if (fCompleteFunction) + { + var + bResult = false, + oResult = null + ; + + try + { + oResult = JSON.parse(oXhr.responseText); + bResult = true; + } + catch (oException) + { + oResult = null; + } + + fCompleteFunction(sUid, bResult, oResult); + } + + if (defined(self.oXhrs[sUid])) + { + self.oXhrs[sUid] = null; + } + + fCallback(null, sUid); + } + else + { + if (4 === oXhr.readyState) + { + fCompleteFunction(sUid, false, null); + fCallback(null, sUid); + } + } + }; + + if (fStartFunction) + { + fStartFunction(sUid); + } + + oFormData.append('jua-post-type', 'ajax'); + oFormData.append(Utils.getValue(this.oOptions, 'name', 'juaFile'), oFileInfo['File']); + $.each(aHidden, function (sKey, sValue) { + oFormData.append(sKey, Utils.getStringOrCallFunction(sValue, [oFileInfo])); + }); + + oXhr.send(oFormData); + + this.oXhrs[sUid] = oXhr; + return true; + } + catch (oError) + { + } + + fCallback(null, sUid); + return false; + } + + generateNewInput(oClickElement) + { + var + self = this, + oLabel = null, + oInput = null + ; + + if (oClickElement) + { + oInput = Utils.getNewInput('', !Utils.getValue(this.oOptions, 'disableMultiple', false)); + oLabel = Utils.createNextLabel(); + oLabel.append(oInput); + + $(oClickElement).append(oLabel); + + oInput + .on('click', function () { + var fOn = self.oJua.getEvent('onDialog'); + if (fOn) + { + fOn(); + } + }) + .on('change', function () { + Utils.getDataFromInput(this, function (oFile) { + self.oJua.addNewFile(oFile); + self.generateNewInput(oClickElement); + + setTimeout(function () { + oLabel.remove(); + }, 10); + }, + Utils.getValue(self.oOptions, 'multipleSizeLimit', iDefLimit), + self.oJua.getEvent('onLimitReached') + ); + }) + ; + } + } + + cancel(sUid) + { + this.oUids[sUid] = false; + if (this.oXhrs[sUid]) + { + try + { + if (this.oXhrs[sUid].abort) + { + this.oXhrs[sUid].abort(); + } + } + catch (oError) + { + } + + this.oXhrs[sUid] = null; + } + } } /** @@ -334,181 +493,6 @@ */ AjaxDriver.prototype.oOptions = {}; - /** - * @return {boolean} - */ - AjaxDriver.prototype.isDragAndDropSupported = () => true; - - /** - * @param {string} sUid - */ - AjaxDriver.prototype.regTaskUid = function (sUid) - { - this.oUids[sUid] = true; - }; - - /** - * @param {string} sUid - * @param {?} oFileInfo - * @param {Function} fCallback - */ - AjaxDriver.prototype.uploadTask = function (sUid, oFileInfo, fCallback) - { - if (false === this.oUids[sUid] || !oFileInfo || !oFileInfo['File']) - { - fCallback(null, sUid); - return false; - } - - try - { - var - self = this, - oXhr = new XMLHttpRequest(), - oFormData = new FormData(), - sAction = Utils.getValue(this.oOptions, 'action', ''), - aHidden = Utils.getValue(this.oOptions, 'hidden', {}), - fStartFunction = this.oJua.getEvent('onStart'), - fCompleteFunction = this.oJua.getEvent('onComplete'), - fProgressFunction = this.oJua.getEvent('onProgress') - ; - - oXhr.open('POST', sAction, true); - - if (fProgressFunction && oXhr.upload) - { - oXhr.upload.onprogress = function (oEvent) { - if (oEvent && oEvent.lengthComputable && defined(oEvent.loaded) && defined(oEvent.total)) - { - fProgressFunction(sUid, oEvent.loaded, oEvent.total); - } - }; - } - - oXhr.onreadystatechange = function () { - if (4 === oXhr.readyState && 200 === oXhr.status) - { - if (fCompleteFunction) - { - var - bResult = false, - oResult = null - ; - - try - { - oResult = JSON.parse(oXhr.responseText); - bResult = true; - } - catch (oException) - { - oResult = null; - } - - fCompleteFunction(sUid, bResult, oResult); - } - - if (defined(self.oXhrs[sUid])) - { - self.oXhrs[sUid] = null; - } - - fCallback(null, sUid); - } - else - { - if (4 === oXhr.readyState) - { - fCompleteFunction(sUid, false, null); - fCallback(null, sUid); - } - } - }; - - if (fStartFunction) - { - fStartFunction(sUid); - } - - oFormData.append('jua-post-type', 'ajax'); - oFormData.append(Utils.getValue(this.oOptions, 'name', 'juaFile'), oFileInfo['File']); - $.each(aHidden, function (sKey, sValue) { - oFormData.append(sKey, Utils.getStringOrCallFunction(sValue, [oFileInfo])); - }); - - oXhr.send(oFormData); - - this.oXhrs[sUid] = oXhr; - return true; - } - catch (oError) - { - } - - fCallback(null, sUid); - return false; - }; - - AjaxDriver.prototype.generateNewInput = function (oClickElement) - { - var - self = this, - oLabel = null, - oInput = null - ; - - if (oClickElement) - { - oInput = Utils.getNewInput('', !Utils.getValue(this.oOptions, 'disableMultiple', false)); - oLabel = Utils.createNextLabel(); - oLabel.append(oInput); - - $(oClickElement).append(oLabel); - - oInput - .on('click', function () { - var fOn = self.oJua.getEvent('onDialog'); - if (fOn) - { - fOn(); - } - }) - .on('change', function () { - Utils.getDataFromInput(this, function (oFile) { - self.oJua.addNewFile(oFile); - self.generateNewInput(oClickElement); - - setTimeout(function () { - oLabel.remove(); - }, 10); - }, - Utils.getValue(self.oOptions, 'multipleSizeLimit', iDefLimit), - self.oJua.getEvent('onLimitReached') - ); - }) - ; - } - }; - - AjaxDriver.prototype.cancel = function (sUid) - { - this.oUids[sUid] = false; - if (this.oXhrs[sUid]) - { - try - { - if (this.oXhrs[sUid].abort) - { - this.oXhrs[sUid].abort(); - } - } - catch (oError) - { - } - - this.oXhrs[sUid] = null; - } - }; function queue(a) { function l() { @@ -547,168 +531,85 @@ * @constructor * @param {Object=} oOptions */ - function Jua(oOptions) + class Jua { - oOptions = defined(oOptions) ? oOptions : {}; - - var - self = this, - - $ = jQuery - ; - - self.bEnableDnD = true; - - self.oEvents = { - 'onDialog': null, - 'onSelect': null, - 'onStart': null, - 'onComplete': null, - 'onCompleteAll': null, - 'onProgress': null, - 'onDragEnter': null, - 'onDragLeave': null, - 'onDrop': null, - 'onBodyDragEnter': null, - 'onBodyDragLeave': null, - 'onLimitReached': null - }; - - self.oOptions = { - 'action': '', - 'name': '', - 'hidden': {}, - 'queueSize': 10, - 'clickElement': false, - 'dragAndDropElement': false, - 'dragAndDropBodyElement': false, - 'disableDragAndDrop': false, - 'disableMultiple': false, - 'disableDocumentDropPrevent': false, - 'multipleSizeLimit': 50 - }; - Object.entries(oOptions).forEach(([key, value])=>self.oOptions[key]=value); - - self.oQueue = queue(parseInt(Utils.getValue(self.oOptions, 'queueSize', 10) || 0, 10)); - if (self.runEvent('onCompleteAll')) + constructor(oOptions) { - self.oQueue.await(function () { - self.runEvent('onCompleteAll'); - }); - } + oOptions = defined(oOptions) ? oOptions : {}; - self.oDriver = new AjaxDriver(self, self.oOptions); + var + self = this, - self.oClickElement = Utils.getValue(self.oOptions, 'clickElement', null); + $ = jQuery + ; - if (self.oClickElement) - { - $(self.oClickElement).css({ - 'position': 'relative', - 'overflow': 'hidden' - }); + self.bEnableDnD = true; - if ('inline' === $(this.oClickElement).css('display')) + self.oEvents = { + 'onDialog': null, + 'onSelect': null, + 'onStart': null, + 'onComplete': null, + 'onCompleteAll': null, + 'onProgress': null, + 'onDragEnter': null, + 'onDragLeave': null, + 'onDrop': null, + 'onBodyDragEnter': null, + 'onBodyDragLeave': null, + 'onLimitReached': null + }; + + self.oOptions = { + 'action': '', + 'name': '', + 'hidden': {}, + 'queueSize': 10, + 'clickElement': false, + 'dragAndDropElement': false, + 'dragAndDropBodyElement': false, + 'disableDragAndDrop': false, + 'disableMultiple': false, + 'disableDocumentDropPrevent': false, + 'multipleSizeLimit': 50 + }; + Object.entries(oOptions).forEach(([key, value])=>self.oOptions[key]=value); + + self.oQueue = queue(parseInt(Utils.getValue(self.oOptions, 'queueSize', 10) || 0, 10)); + if (self.runEvent('onCompleteAll')) { - $(this.oClickElement).css('display', 'inline-block'); + self.oQueue.await(function () { + self.runEvent('onCompleteAll'); + }); } - this.oDriver.generateNewInput(this.oClickElement); - } + self.oDriver = new AjaxDriver(self, self.oOptions); - if (this.oDriver.isDragAndDropSupported() && Utils.getValue(this.oOptions, 'dragAndDropElement', false)) - { - (function (self) { - var - $doc = $(document), - oBigDropZone = $(Utils.getValue(self.oOptions, 'dragAndDropBodyElement', false) || $doc), - oDragAndDropElement = Utils.getValue(self.oOptions, 'dragAndDropElement', false), - fHandleDragOver = function (oEvent) { - if (self.bEnableDnD && oEvent) - { - oEvent = Utils.getEvent(oEvent); - if (oEvent && oEvent.dataTransfer && Utils.eventContainsFiles(oEvent)) - { - try - { - var sEffect = oEvent.dataTransfer.effectAllowed; + self.oClickElement = Utils.getValue(self.oOptions, 'clickElement', null); - Utils.mainClearTimeout(self.iDocTimer); + if (self.oClickElement) + { + $(self.oClickElement).css({ + 'position': 'relative', + 'overflow': 'hidden' + }); - oEvent.dataTransfer.dropEffect = (sEffect === 'move' || sEffect === 'linkMove') ? 'move' : 'copy'; - - oEvent.stopPropagation(); - oEvent.preventDefault(); - - oBigDropZone.trigger('dragover', oEvent); - } - catch (oExc) {} - } - } - }, - fHandleDrop = function (oEvent) { - if (self.bEnableDnD && oEvent) - { - oEvent = Utils.getEvent(oEvent); - if (oEvent && Utils.eventContainsFiles(oEvent)) - { - oEvent.preventDefault(); - - Utils.getDataFromDragEvent(oEvent, function (oFile) { - if (oFile) - { - self.runEvent('onDrop', [oFile, oEvent]); - self.addNewFile(oFile); - Utils.mainClearTimeout(self.iDocTimer); - } - }, - Utils.getValue(self.oOptions, 'multipleSizeLimit', iDefLimit), - self.getEvent('onLimitReached') - ); - } - } - - self.runEvent('onDragLeave', [oEvent]); - }, - fHandleDragEnter = function (oEvent) { - if (self.bEnableDnD && oEvent) - { - oEvent = Utils.getEvent(oEvent); - if (oEvent && Utils.eventContainsFiles(oEvent)) - { - Utils.mainClearTimeout(self.iDocTimer); - - oEvent.preventDefault(); - self.runEvent('onDragEnter', [oDragAndDropElement, oEvent]); - } - } - }, - fHandleDragLeave = function (oEvent) { - if (self.bEnableDnD && oEvent) - { - oEvent = Utils.getEvent(oEvent); - if (oEvent) - { - var oRelatedTarget = document['elementFromPoint'] ? document['elementFromPoint'](oEvent['clientX'], oEvent['clientY']) : null; - if (oRelatedTarget && Utils.contains(this, oRelatedTarget)) - { - return; - } - - Utils.mainClearTimeout(self.iDocTimer); - self.runEvent('onDragLeave', [oDragAndDropElement, oEvent]); - } - - return; - } - } - ; - - if (oDragAndDropElement) + if ('inline' === $(this.oClickElement).css('display')) { - if (!Utils.getValue(self.oOptions, 'disableDocumentDropPrevent', false)) - { - $doc.on('dragover', function (oEvent) { + $(this.oClickElement).css('display', 'inline-block'); + } + + this.oDriver.generateNewInput(this.oClickElement); + } + + if (Utils.getValue(this.oOptions, 'dragAndDropElement', false)) + { + (function (self) { + var + $doc = $(document), + oBigDropZone = $(Utils.getValue(self.oOptions, 'dragAndDropBodyElement', false) || $doc), + oDragAndDropElement = Utils.getValue(self.oOptions, 'dragAndDropElement', false), + fHandleDragOver = function (oEvent) { if (self.bEnableDnD && oEvent) { oEvent = Utils.getEvent(oEvent); @@ -716,86 +617,244 @@ { try { - oEvent.dataTransfer.dropEffect = 'none'; + var sEffect = oEvent.dataTransfer.effectAllowed; + + Utils.mainClearTimeout(self.iDocTimer); + + oEvent.dataTransfer.dropEffect = (sEffect === 'move' || sEffect === 'linkMove') ? 'move' : 'copy'; + + oEvent.stopPropagation(); oEvent.preventDefault(); + + oBigDropZone.trigger('dragover', oEvent); } catch (oExc) {} } } - }); - } + }, + fHandleDrop = function (oEvent) { + if (self.bEnableDnD && oEvent) + { + oEvent = Utils.getEvent(oEvent); + if (oEvent && Utils.eventContainsFiles(oEvent)) + { + oEvent.preventDefault(); - if (oBigDropZone && oBigDropZone[0]) - { - oBigDropZone - .on('dragover', function (oEvent) { - if (self.bEnableDnD && oEvent) + Utils.getDataFromDragEvent(oEvent, function (oFile) { + if (oFile) + { + self.runEvent('onDrop', [oFile, oEvent]); + self.addNewFile(oFile); + Utils.mainClearTimeout(self.iDocTimer); + } + }, + Utils.getValue(self.oOptions, 'multipleSizeLimit', iDefLimit), + self.getEvent('onLimitReached') + ); + } + } + + self.runEvent('onDragLeave', [oEvent]); + }, + fHandleDragEnter = function (oEvent) { + if (self.bEnableDnD && oEvent) + { + oEvent = Utils.getEvent(oEvent); + if (oEvent && Utils.eventContainsFiles(oEvent)) { Utils.mainClearTimeout(self.iDocTimer); - } - }) - .on('dragenter', function (oEvent) { - if (self.bEnableDnD && oEvent) - { - oEvent = Utils.getEvent(oEvent); - if (oEvent && Utils.eventContainsFiles(oEvent)) - { - Utils.mainClearTimeout(self.iDocTimer); - oEvent.preventDefault(); - self.runEvent('onBodyDragEnter', [oEvent]); - } + oEvent.preventDefault(); + self.runEvent('onDragEnter', [oDragAndDropElement, oEvent]); } - }) - .on('dragleave', function (oEvent) { + } + }, + fHandleDragLeave = function (oEvent) { + if (self.bEnableDnD && oEvent) + { + oEvent = Utils.getEvent(oEvent); + if (oEvent) + { + var oRelatedTarget = document['elementFromPoint'] ? document['elementFromPoint'](oEvent['clientX'], oEvent['clientY']) : null; + if (oRelatedTarget && Utils.contains(this, oRelatedTarget)) + { + return; + } + + Utils.mainClearTimeout(self.iDocTimer); + self.runEvent('onDragLeave', [oDragAndDropElement, oEvent]); + } + + return; + } + } + ; + + if (oDragAndDropElement) + { + if (!Utils.getValue(self.oOptions, 'disableDocumentDropPrevent', false)) + { + $doc.on('dragover', function (oEvent) { if (self.bEnableDnD && oEvent) { oEvent = Utils.getEvent(oEvent); - if (oEvent) + if (oEvent && oEvent.dataTransfer && Utils.eventContainsFiles(oEvent)) { - Utils.mainClearTimeout(self.iDocTimer); - self.iDocTimer = setTimeout(function () { - self.runEvent('onBodyDragLeave', [oEvent]); - }, 200); - } - } - }) - .on('drop', function (oEvent) { - if (self.bEnableDnD && oEvent) - { - oEvent = Utils.getEvent(oEvent); - if (oEvent) - { - var bFiles = Utils.eventContainsFiles(oEvent); - if (bFiles) + try { + oEvent.dataTransfer.dropEffect = 'none'; oEvent.preventDefault(); } - - self.runEvent('onBodyDragLeave', [oEvent]); - - return !bFiles; + catch (oExc) {} } } + }); + } - return false; - }) + if (oBigDropZone && oBigDropZone[0]) + { + oBigDropZone + .on('dragover', function (oEvent) { + if (self.bEnableDnD && oEvent) + { + Utils.mainClearTimeout(self.iDocTimer); + } + }) + .on('dragenter', function (oEvent) { + if (self.bEnableDnD && oEvent) + { + oEvent = Utils.getEvent(oEvent); + if (oEvent && Utils.eventContainsFiles(oEvent)) + { + Utils.mainClearTimeout(self.iDocTimer); + oEvent.preventDefault(); + + self.runEvent('onBodyDragEnter', [oEvent]); + } + } + }) + .on('dragleave', function (oEvent) { + if (self.bEnableDnD && oEvent) + { + oEvent = Utils.getEvent(oEvent); + if (oEvent) + { + Utils.mainClearTimeout(self.iDocTimer); + self.iDocTimer = setTimeout(function () { + self.runEvent('onBodyDragLeave', [oEvent]); + }, 200); + } + } + }) + .on('drop', function (oEvent) { + if (self.bEnableDnD && oEvent) + { + oEvent = Utils.getEvent(oEvent); + if (oEvent) + { + var bFiles = Utils.eventContainsFiles(oEvent); + if (bFiles) + { + oEvent.preventDefault(); + } + + self.runEvent('onBodyDragLeave', [oEvent]); + + return !bFiles; + } + } + + return false; + }) + ; + } + + $(oDragAndDropElement) + .on('dragenter', fHandleDragEnter) + .on('dragover', fHandleDragOver) + .on('dragleave', fHandleDragLeave) + .on('drop', fHandleDrop) ; } - $(oDragAndDropElement) - .on('dragenter', fHandleDragEnter) - .on('dragover', fHandleDragOver) - .on('dragleave', fHandleDragLeave) - .on('drop', fHandleDrop) - ; - } - - }(self)); + }(self)); + } + else + { + self.bEnableDnD = false; + } } - else + + /** + * @param {string} sName + * @param {Function} fFunc + */ + on(sName, fFunc) { - self.bEnableDnD = false; + this.oEvents[sName] = fFunc; + return this; + } + + /** + * @param {string} sName + * @param {string=} aArgs + */ + runEvent(sName, aArgs) + { + if (this.oEvents[sName]) + { + this.oEvents[sName].apply(null, aArgs || []); + } + } + + /** + * @param {string} sName + */ + getEvent(sName) + { + return this.oEvents[sName] || null; + } + + /** + * @param {string} sUid + */ + cancel(sUid) + { + this.oDriver.cancel(sUid); + } + + /** + * @param {boolean} bEnabled + */ + setDragAndDropEnabledStatus(bEnabled) + { + this.bEnableDnD = !!bEnabled; + } + + /** + * @param {Object} oFileInfo + */ + addNewFile(oFileInfo) + { + this.addFile(Utils.getNewUid(), oFileInfo); + } + + /** + * @param {string} sUid + * @param {Object} oFileInfo + */ + addFile(sUid, oFileInfo) + { + var fOnSelect = this.getEvent('onSelect'); + if (oFileInfo && (!fOnSelect || (false !== fOnSelect(sUid, oFileInfo)))) + { + this.oDriver.regTaskUid(sUid); + this.oQueue.defer(Utils.scopeBind(this.oDriver.uploadTask, this.oDriver), sUid, oFileInfo); + } + else + { + this.oDriver.cancel(sUid); + } } } @@ -829,86 +888,6 @@ */ Jua.prototype.oDriver = null; - /** - * @param {string} sName - * @param {Function} fFunc - */ - Jua.prototype.on = function (sName, fFunc) - { - this.oEvents[sName] = fFunc; - return this; - }; - - /** - * @param {string} sName - * @param {string=} aArgs - */ - Jua.prototype.runEvent = function (sName, aArgs) - { - if (this.oEvents[sName]) - { - this.oEvents[sName].apply(null, aArgs || []); - } - }; - - /** - * @param {string} sName - */ - Jua.prototype.getEvent = function (sName) - { - return this.oEvents[sName] || null; - }; - - /** - * @param {string} sUid - */ - Jua.prototype.cancel = function (sUid) - { - this.oDriver.cancel(sUid); - }; - - /** - * @param {boolean} bEnabled - */ - Jua.prototype.setDragAndDropEnabledStatus = function (bEnabled) - { - this.bEnableDnD = !!bEnabled; - }; - - /** - * @return {boolean} - */ - Jua.prototype.isDragAndDropSupported = function () - { - return this.oDriver.isDragAndDropSupported(); - }; - - /** - * @param {Object} oFileInfo - */ - Jua.prototype.addNewFile = function (oFileInfo) - { - this.addFile(Utils.getNewUid(), oFileInfo); - }; - - /** - * @param {string} sUid - * @param {Object} oFileInfo - */ - Jua.prototype.addFile = function (sUid, oFileInfo) - { - var fOnSelect = this.getEvent('onSelect'); - if (oFileInfo && (!fOnSelect || (false !== fOnSelect(sUid, oFileInfo)))) - { - this.oDriver.regTaskUid(sUid); - this.oQueue.defer(Utils.scopeBind(this.oDriver.uploadTask, this.oDriver), sUid, oFileInfo); - } - else - { - this.oDriver.cancel(sUid); - } - }; - window.Jua = Jua; })(); diff --git a/vendors/jua/jua.min.js b/vendors/jua/jua.min.js index 28445e744..bb1f5fa99 100644 --- a/vendors/jua/jua.min.js +++ b/vendors/jua/jua.min.js @@ -1,2 +1,2 @@ /* RainLoop Webmail (c) RainLoop Team | MIT */ -(()=>{"use strict";var e=20,t=jQuery;const n=e=>void 0!==e;var o={contains:(e,t)=>!(!e||!t)&&(e===t||(e.contains?e.contains(t):!!t.compareDocumentPosition&&!!(8&t.compareDocumentPosition(e)))),mainClearTimeout:e=>{0(e=e&&(e.originalEvent?e.originalEvent:e)||window.event).dataTransfer?e:null,getValue:(e,t,o)=>e&&t&&n(e[t])?e[t]:o,scopeBind:(e,t)=>(...o)=>e.apply(n(t)?t:null,Array.prototype.slice.call(o)),fakeMd5:e=>{var t="",o="0123456789abcdefghijklmnopqrstuvwxyz";for(e=n(e)?parseInt(e||0,10):32;t.length"jua-uid-"+o.fakeMd5(16)+"-"+(new Date).getTime().toString(),getDataFromFile:e=>{var t=n(e.fileName)?e.fileName:n(e.name)?e.name:null,o=n(e.fileSize)?e.fileSize:n(e.size)?e.size:null,i=n(e.type)?e.type:null;return"/"===t.charAt(0)&&(t=t.substr(1)),i||0!==o?{FileName:t,Size:o,Type:i,Folder:"",File:e}:null},getDataFromFiles:(t,i,r,a)=>{var l,u,s=0,p=0,c=null,d=null,g=!1;if(l=r=n(r)?parseInt(r||0,10):e,u=0r&&a&&(g=!0,a(l)))},getDataFromInput:(e,t,n,i)=>{var r=e&&e.files&&0{var t=!1;if(e&&e.dataTransfer&&e.dataTransfer.types&&e.dataTransfer.types.length)for(var n=0,o=e.dataTransfer.types.length;n{var r=null;(e=o.getEvent(e))&&o.eventContainsFiles(e)&&(r=o.getValue(e,"files",null)||(e.dataTransfer?o.getValue(e.dataTransfer,"files",null):null))&&0t('').css({opacity:0}),createNextInput:()=>t(''),getNewInput:(e,t)=>{e=n(e)?e.toString():"";var i=o.createNextInput();return 0t.isFunction(e)?e.apply(null,Array.isArray(n)?n:[]).toString():e.toString()};function i(e,t){this.oXhrs={},this.oUids={},this.oJua=e,this.oOptions=t}function r(t){t=n(t)?t:{};var r=this,a=jQuery;r.bEnableDnD=!0,r.oEvents={onDialog:null,onSelect:null,onStart:null,onComplete:null,onCompleteAll:null,onProgress:null,onDragEnter:null,onDragLeave:null,onDrop:null,onBodyDragEnter:null,onBodyDragLeave:null,onLimitReached:null},r.oOptions={action:"",name:"",hidden:{},queueSize:10,clickElement:!1,dragAndDropElement:!1,dragAndDropBodyElement:!1,disableDragAndDrop:!1,disableMultiple:!1,disableDocumentDropPrevent:!1,multipleSizeLimit:50},Object.entries(t).forEach(([e,t])=>r.oOptions[e]=t),r.oQueue=function(e){function t(){if(n&&r{};return arguments.length<1&&(e=1/0),i.defer=function(){if(!u){var e=arguments;e.index=++l,o?(o.next=e,o=o.next):n=o=e,++a,t()}return i},i.await=function(e){return p=e,a||p(u,s),i},i}(parseInt(o.getValue(r.oOptions,"queueSize",10)||0,10)),r.runEvent("onCompleteAll")&&r.oQueue.await(function(){r.runEvent("onCompleteAll")}),r.oDriver=new i(r,r.oOptions),r.oClickElement=o.getValue(r.oOptions,"clickElement",null),r.oClickElement&&(a(r.oClickElement).css({position:"relative",overflow:"hidden"}),"inline"===a(this.oClickElement).css("display")&&a(this.oClickElement).css("display","inline-block"),this.oDriver.generateNewInput(this.oClickElement)),this.oDriver.isDragAndDropSupported()&&o.getValue(this.oOptions,"dragAndDropElement",!1)?function(t){var n=a(document),i=a(o.getValue(t.oOptions,"dragAndDropBodyElement",!1)||n),r=o.getValue(t.oOptions,"dragAndDropElement",!1);r&&(o.getValue(t.oOptions,"disableDocumentDropPrevent",!1)||n.on("dragover",function(e){if(t.bEnableDnD&&e&&(e=o.getEvent(e))&&e.dataTransfer&&o.eventContainsFiles(e))try{e.dataTransfer.dropEffect="none",e.preventDefault()}catch(e){}}),i&&i[0]&&i.on("dragover",function(e){t.bEnableDnD&&e&&o.mainClearTimeout(t.iDocTimer)}).on("dragenter",function(e){t.bEnableDnD&&e&&(e=o.getEvent(e))&&o.eventContainsFiles(e)&&(o.mainClearTimeout(t.iDocTimer),e.preventDefault(),t.runEvent("onBodyDragEnter",[e]))}).on("dragleave",function(e){t.bEnableDnD&&e&&(e=o.getEvent(e))&&(o.mainClearTimeout(t.iDocTimer),t.iDocTimer=setTimeout(function(){t.runEvent("onBodyDragLeave",[e])},200))}).on("drop",function(e){if(t.bEnableDnD&&e&&(e=o.getEvent(e))){var n=o.eventContainsFiles(e);return n&&e.preventDefault(),t.runEvent("onBodyDragLeave",[e]),!n}return!1}),a(r).on("dragenter",function(e){t.bEnableDnD&&e&&(e=o.getEvent(e))&&o.eventContainsFiles(e)&&(o.mainClearTimeout(t.iDocTimer),e.preventDefault(),t.runEvent("onDragEnter",[r,e]))}).on("dragover",function(e){if(t.bEnableDnD&&e&&(e=o.getEvent(e))&&e.dataTransfer&&o.eventContainsFiles(e))try{var n=e.dataTransfer.effectAllowed;o.mainClearTimeout(t.iDocTimer),e.dataTransfer.dropEffect="move"===n||"linkMove"===n?"move":"copy",e.stopPropagation(),e.preventDefault(),i.trigger("dragover",e)}catch(e){}}).on("dragleave",function(e){if(t.bEnableDnD&&e&&(e=o.getEvent(e))){var n=document.elementFromPoint?document.elementFromPoint(e.clientX,e.clientY):null;if(n&&o.contains(this,n))return;o.mainClearTimeout(t.iDocTimer),t.runEvent("onDragLeave",[r,e])}}).on("drop",function(n){t.bEnableDnD&&n&&(n=o.getEvent(n))&&o.eventContainsFiles(n)&&(n.preventDefault(),o.getDataFromDragEvent(n,function(e){e&&(t.runEvent("onDrop",[e,n]),t.addNewFile(e),o.mainClearTimeout(t.iDocTimer))},o.getValue(t.oOptions,"multipleSizeLimit",e),t.getEvent("onLimitReached"))),t.runEvent("onDragLeave",[n])}))}(r):r.bEnableDnD=!1}i.prototype.oXhrs={},i.prototype.oUids={},i.prototype.oJua=null,i.prototype.oOptions={},i.prototype.isDragAndDropSupported=(()=>!0),i.prototype.regTaskUid=function(e){this.oUids[e]=!0},i.prototype.uploadTask=function(e,i,r){if(!1===this.oUids[e]||!i||!i.File)return r(null,e),!1;try{var a=this,l=new XMLHttpRequest,u=new FormData,s=o.getValue(this.oOptions,"action",""),p=o.getValue(this.oOptions,"hidden",{}),c=this.oJua.getEvent("onStart"),d=this.oJua.getEvent("onComplete"),g=this.oJua.getEvent("onProgress");return l.open("POST",s,!0),g&&l.upload&&(l.upload.onprogress=function(t){t&&t.lengthComputable&&n(t.loaded)&&n(t.total)&&g(e,t.loaded,t.total)}),l.onreadystatechange=function(){if(4===l.readyState&&200===l.status){if(d){var t=!1,o=null;try{o=JSON.parse(l.responseText),t=!0}catch(e){o=null}d(e,t,o)}n(a.oXhrs[e])&&(a.oXhrs[e]=null),r(null,e)}else 4===l.readyState&&(d(e,!1,null),r(null,e))},c&&c(e),u.append("jua-post-type","ajax"),u.append(o.getValue(this.oOptions,"name","juaFile"),i.File),t.each(p,function(e,t){u.append(e,o.getStringOrCallFunction(t,[i]))}),l.send(u),this.oXhrs[e]=l,!0}catch(e){}return r(null,e),!1},i.prototype.generateNewInput=function(n){var i=this,r=null,a=null;n&&(a=o.getNewInput("",!o.getValue(this.oOptions,"disableMultiple",!1)),(r=o.createNextLabel()).append(a),t(n).append(r),a.on("click",function(){var e=i.oJua.getEvent("onDialog");e&&e()}).on("change",function(){o.getDataFromInput(this,function(e){i.oJua.addNewFile(e),i.generateNewInput(n),setTimeout(function(){r.remove()},10)},o.getValue(i.oOptions,"multipleSizeLimit",e),i.oJua.getEvent("onLimitReached"))}))},i.prototype.cancel=function(e){if(this.oUids[e]=!1,this.oXhrs[e]){try{this.oXhrs[e].abort&&this.oXhrs[e].abort()}catch(e){}this.oXhrs[e]=null}},r.prototype.bEnableDnD=!0,r.prototype.iDocTimer=0,r.prototype.oOptions={},r.prototype.oEvents={},r.prototype.oQueue=null,r.prototype.oDriver=null,r.prototype.on=function(e,t){return this.oEvents[e]=t,this},r.prototype.runEvent=function(e,t){this.oEvents[e]&&this.oEvents[e].apply(null,t||[])},r.prototype.getEvent=function(e){return this.oEvents[e]||null},r.prototype.cancel=function(e){this.oDriver.cancel(e)},r.prototype.setDragAndDropEnabledStatus=function(e){this.bEnableDnD=!!e},r.prototype.isDragAndDropSupported=function(){return this.oDriver.isDragAndDropSupported()},r.prototype.addNewFile=function(e){this.addFile(o.getNewUid(),e)},r.prototype.addFile=function(e,t){var n=this.getEvent("onSelect");!t||n&&!1===n(e,t)?this.oDriver.cancel(e):(this.oDriver.regTaskUid(e),this.oQueue.defer(o.scopeBind(this.oDriver.uploadTask,this.oDriver),e,t))},window.Jua=r})(); +(()=>{"use strict";var e=20,t=jQuery;const n=e=>void 0!==e,o=(t,o,i,r)=>{if(t&&t.length){var l,u,s=null,p=!1;i=n(i)?parseInt(i||0,10):e,l=i,u=0{e&&(u?p||0>i&&r&&(p=!0,r(l)):0<=--i&&(s=a.getDataFromFile(e))&&o(s))})}};var a={contains:(e,t)=>!(!e||!t)&&(e===t||(e.contains?e.contains(t):!!t.compareDocumentPosition&&!!(8&t.compareDocumentPosition(e)))),mainClearTimeout:e=>{0(e=e&&(e.originalEvent?e.originalEvent:e)||window.event).dataTransfer?e:null,getValue:(e,t,o)=>e&&t&&n(e[t])?e[t]:o,scopeBind:(e,t)=>(...o)=>e.apply(n(t)?t:null,Array.prototype.slice.call(o)),getNewUid:()=>"jua-uid-"+(e=>{var t="";for(e=n(e)?parseInt(e||0,10):32;e--;)t+="0123456789abcdefghijklmnopqrstuvwxyz".substr(Math.round(36*Math.random()),1);return t})(16)+"-"+(new Date).getTime().toString(),getDataFromFile:e=>{var t=n(e.fileName)?e.fileName:n(e.name)?e.name:null,o=n(e.fileSize)?e.fileSize:n(e.size)?e.size:null,a=n(e.type)?e.type:null;return"/"===t.charAt(0)&&(t=t.substr(1)),a||0!==o?{FileName:t,Size:o,Type:a,Folder:"",File:e}:null},getDataFromInput:(e,t,n,a)=>{var i=e&&0{var t=!1;if(e&&e.dataTransfer&&e.dataTransfer.types&&e.dataTransfer.types.length)for(var n=0,o=e.dataTransfer.types.length;n{var r=null;(e=a.getEvent(e))&&a.eventContainsFiles(e)&&(r=a.getValue(e,"files",null)||(e.dataTransfer?a.getValue(e.dataTransfer,"files",null):null),o(r,t,n,i))},createNextLabel:()=>t('').css({opacity:0}),createNextInput:()=>t(''),getNewInput:(e,t)=>{e=n(e)?e.toString():"";var o=a.createNextInput();return 0t.isFunction(e)?e.apply(null,Array.isArray(n)?n:[]).toString():e.toString()};class i{constructor(e,t){this.oXhrs={},this.oUids={},this.oJua=e,this.oOptions=t}regTaskUid(e){this.oUids[e]=!0}uploadTask(e,o,i){if(!1===this.oUids[e]||!o||!o.File)return i(null,e),!1;try{var r=this,l=new XMLHttpRequest,u=new FormData,s=a.getValue(this.oOptions,"action",""),p=a.getValue(this.oOptions,"hidden",{}),c=this.oJua.getEvent("onStart"),d=this.oJua.getEvent("onComplete"),g=this.oJua.getEvent("onProgress");return l.open("POST",s,!0),g&&l.upload&&(l.upload.onprogress=function(t){t&&t.lengthComputable&&n(t.loaded)&&n(t.total)&&g(e,t.loaded,t.total)}),l.onreadystatechange=function(){if(4===l.readyState&&200===l.status){if(d){var t=!1,o=null;try{o=JSON.parse(l.responseText),t=!0}catch(e){o=null}d(e,t,o)}n(r.oXhrs[e])&&(r.oXhrs[e]=null),i(null,e)}else 4===l.readyState&&(d(e,!1,null),i(null,e))},c&&c(e),u.append("jua-post-type","ajax"),u.append(a.getValue(this.oOptions,"name","juaFile"),o.File),t.each(p,function(e,t){u.append(e,a.getStringOrCallFunction(t,[o]))}),l.send(u),this.oXhrs[e]=l,!0}catch(e){}return i(null,e),!1}generateNewInput(n){var o=this,i=null,r=null;n&&(r=a.getNewInput("",!a.getValue(this.oOptions,"disableMultiple",!1)),(i=a.createNextLabel()).append(r),t(n).append(i),r.on("click",function(){var e=o.oJua.getEvent("onDialog");e&&e()}).on("change",function(){a.getDataFromInput(this,function(e){o.oJua.addNewFile(e),o.generateNewInput(n),setTimeout(function(){i.remove()},10)},a.getValue(o.oOptions,"multipleSizeLimit",e),o.oJua.getEvent("onLimitReached"))}))}cancel(e){if(this.oUids[e]=!1,this.oXhrs[e]){try{this.oXhrs[e].abort&&this.oXhrs[e].abort()}catch(e){}this.oXhrs[e]=null}}}i.prototype.oXhrs={},i.prototype.oUids={},i.prototype.oJua=null,i.prototype.oOptions={};class r{constructor(t){t=n(t)?t:{};var o=this,r=jQuery;o.bEnableDnD=!0,o.oEvents={onDialog:null,onSelect:null,onStart:null,onComplete:null,onCompleteAll:null,onProgress:null,onDragEnter:null,onDragLeave:null,onDrop:null,onBodyDragEnter:null,onBodyDragLeave:null,onLimitReached:null},o.oOptions={action:"",name:"",hidden:{},queueSize:10,clickElement:!1,dragAndDropElement:!1,dragAndDropBodyElement:!1,disableDragAndDrop:!1,disableMultiple:!1,disableDocumentDropPrevent:!1,multipleSizeLimit:50},Object.entries(t).forEach(([e,t])=>o.oOptions[e]=t),o.oQueue=function(e){function t(){if(n&&i{};return arguments.length<1&&(e=1/0),a.defer=function(){if(!u){var e=arguments;e.index=++l,o?(o.next=e,o=o.next):n=o=e,++r,t()}return a},a.await=function(e){return p=e,r||p(u,s),a},a}(parseInt(a.getValue(o.oOptions,"queueSize",10)||0,10)),o.runEvent("onCompleteAll")&&o.oQueue.await(function(){o.runEvent("onCompleteAll")}),o.oDriver=new i(o,o.oOptions),o.oClickElement=a.getValue(o.oOptions,"clickElement",null),o.oClickElement&&(r(o.oClickElement).css({position:"relative",overflow:"hidden"}),"inline"===r(this.oClickElement).css("display")&&r(this.oClickElement).css("display","inline-block"),this.oDriver.generateNewInput(this.oClickElement)),a.getValue(this.oOptions,"dragAndDropElement",!1)?function(t){var n=r(document),o=r(a.getValue(t.oOptions,"dragAndDropBodyElement",!1)||n),i=a.getValue(t.oOptions,"dragAndDropElement",!1);i&&(a.getValue(t.oOptions,"disableDocumentDropPrevent",!1)||n.on("dragover",function(e){if(t.bEnableDnD&&e&&(e=a.getEvent(e))&&e.dataTransfer&&a.eventContainsFiles(e))try{e.dataTransfer.dropEffect="none",e.preventDefault()}catch(e){}}),o&&o[0]&&o.on("dragover",function(e){t.bEnableDnD&&e&&a.mainClearTimeout(t.iDocTimer)}).on("dragenter",function(e){t.bEnableDnD&&e&&(e=a.getEvent(e))&&a.eventContainsFiles(e)&&(a.mainClearTimeout(t.iDocTimer),e.preventDefault(),t.runEvent("onBodyDragEnter",[e]))}).on("dragleave",function(e){t.bEnableDnD&&e&&(e=a.getEvent(e))&&(a.mainClearTimeout(t.iDocTimer),t.iDocTimer=setTimeout(function(){t.runEvent("onBodyDragLeave",[e])},200))}).on("drop",function(e){if(t.bEnableDnD&&e&&(e=a.getEvent(e))){var n=a.eventContainsFiles(e);return n&&e.preventDefault(),t.runEvent("onBodyDragLeave",[e]),!n}return!1}),r(i).on("dragenter",function(e){t.bEnableDnD&&e&&(e=a.getEvent(e))&&a.eventContainsFiles(e)&&(a.mainClearTimeout(t.iDocTimer),e.preventDefault(),t.runEvent("onDragEnter",[i,e]))}).on("dragover",function(e){if(t.bEnableDnD&&e&&(e=a.getEvent(e))&&e.dataTransfer&&a.eventContainsFiles(e))try{var n=e.dataTransfer.effectAllowed;a.mainClearTimeout(t.iDocTimer),e.dataTransfer.dropEffect="move"===n||"linkMove"===n?"move":"copy",e.stopPropagation(),e.preventDefault(),o.trigger("dragover",e)}catch(e){}}).on("dragleave",function(e){if(t.bEnableDnD&&e&&(e=a.getEvent(e))){var n=document.elementFromPoint?document.elementFromPoint(e.clientX,e.clientY):null;if(n&&a.contains(this,n))return;a.mainClearTimeout(t.iDocTimer),t.runEvent("onDragLeave",[i,e])}}).on("drop",function(n){t.bEnableDnD&&n&&(n=a.getEvent(n))&&a.eventContainsFiles(n)&&(n.preventDefault(),a.getDataFromDragEvent(n,function(e){e&&(t.runEvent("onDrop",[e,n]),t.addNewFile(e),a.mainClearTimeout(t.iDocTimer))},a.getValue(t.oOptions,"multipleSizeLimit",e),t.getEvent("onLimitReached"))),t.runEvent("onDragLeave",[n])}))}(o):o.bEnableDnD=!1}on(e,t){return this.oEvents[e]=t,this}runEvent(e,t){this.oEvents[e]&&this.oEvents[e].apply(null,t||[])}getEvent(e){return this.oEvents[e]||null}cancel(e){this.oDriver.cancel(e)}setDragAndDropEnabledStatus(e){this.bEnableDnD=!!e}addNewFile(e){this.addFile(a.getNewUid(),e)}addFile(e,t){var n=this.getEvent("onSelect");!t||n&&!1===n(e,t)?this.oDriver.cancel(e):(this.oDriver.regTaskUid(e),this.oQueue.defer(a.scopeBind(this.oDriver.uploadTask,this.oDriver),e,t))}}r.prototype.bEnableDnD=!0,r.prototype.iDocTimer=0,r.prototype.oOptions={},r.prototype.oEvents={},r.prototype.oQueue=null,r.prototype.oDriver=null,window.Jua=r})(); diff --git a/vendors/keymaster/keymaster.js b/vendors/keymaster/keymaster.js index 978db77fd..046732465 100644 --- a/vendors/keymaster/keymaster.js +++ b/vendors/keymaster/keymaster.js @@ -44,7 +44,11 @@ // parse and assign shortcut function assignKey(key, scope, method){ - var keys = getKeys(key), mods; + key = key.replace(/\s/g, ''); + var keys = key.split(','), mods; + if ((keys[keys.length - 1]) == '') { + keys[keys.length - 2] += ','; + } if (method === undefined) { method = scope; scope = 'all'; @@ -56,12 +60,12 @@ mods = []; key = keys[i].split('+'); if (key.length > 1){ - mods = getMods(key); + mods = key.slice(0, key.length - 1); + mods.forEach((mod, mi) => mods[mi] = _MODIFIERS[mod]); key = [key[key.length-1]]; } // convert to keycode and... - key = key[0]; - key = code(key); + key = code(key[0]); // ...store handler if (!(key in _handlers)) _handlers[key] = []; @@ -78,25 +82,7 @@ // initialize key. to false for(k in _MODIFIERS) assignKey[k] = false; - // set current scope (default 'all') - const - setScope = scope => { _scope = scope || 'all' }, - getScope = () => _scope || 'all', - // abstract key logic for assign and unassign - getKeys = key => { - key = key.replace(/\s/g, ''); - var keys = key.split(','); - if ((keys[keys.length - 1]) == '') { - keys[keys.length - 2] += ','; - } - return keys; - }, - // abstract mods logic for assign and unassign - getMods = key => { - var mods = key.slice(0, key.length - 1); - mods.forEach((mod, mi) => mods[mi] = _MODIFIERS[mod]); - return mods; - }; + const getScope = () => _scope || 'all'; // set the handlers globally on document document.addEventListener('keydown', event => { @@ -170,7 +156,7 @@ // set window.key and window.key.set/get, and the default filter global.key = assignKey; - global.key.setScope = setScope; + global.key.setScope = scope => { _scope = scope || 'all' }; global.key.getScope = getScope; global.key.filter = event => { var tagName = event.target.tagName; diff --git a/vendors/qr.js/qr.js b/vendors/qr.js/qr.js index da088031b..7c7c36592 100644 --- a/vendors/qr.js/qr.js +++ b/vendors/qr.js/qr.js @@ -20,10 +20,6 @@ 16, 18, 20, 22, 24, 26, 28, 20, 22, 24, 24, 26, 28, 28, 22, 24, 24, 26, 26, 28, 28, 24, 24, 26, 26, 26, 28, 28, 24, 26, 26, 26, 28, 28 ]; - // Default MIME type. - var DEFAULT_MIME = 'image/png'; - // MIME used to initiate a browser download prompt when `qr.save` is called. - var DOWNLOAD_MIME = 'image/octet-stream'; // There are four elements per version. The first two indicate the number of blocks, then the // data width, and finally the ECC width. var ECC_BLOCKS = [ @@ -131,8 +127,6 @@ 0x9a6, 0x683, 0x8c9, 0x7ec, 0xec4, 0x1e1, 0xfab, 0x08e, 0xc1a, 0x33f, 0xd75, 0x250, 0x9d5, 0x6f0, 0x8ba, 0x79f, 0xb0b, 0x42e, 0xa64, 0x541, 0xc69 ]; - // Mode for node.js file system file writes. - var WRITE_MODE = parseInt('0666', 8); // Private variables // ----------------- @@ -153,16 +147,10 @@ var frameBuffer = []; // Fixed part of the image. var frameMask = []; - // File system within the node.js environment. - var fs; - // Constructor for `img` elements in the node.js environment. - var Image; // Indicates whether or not this script is running in node.js. var inNode = false; // Generator polynomial. var polynomial = []; - // Save the previous value of the `qr` variable. - var previousQr = root.qr; // Data input buffer. var stringBuffer = []; // Version for the data. @@ -173,92 +161,14 @@ // Private functions // ----------------- - // Create a new canvas using `document.createElement` unless script is running in node.js, in - // which case the `canvas` module is used. - function createCanvas() { - return inNode ? new Canvas() : root.document.createElement('canvas'); - } - - // Create a new image using `document.createElement` unless script is running in node.js, in - // which case the `canvas` module is used. - function createImage() { - return inNode ? new Image() : root.document.createElement('img'); - } - - // Force the canvas image to be downloaded in the browser. - // Optionally, a `callback` function can be specified which will be called upon completed. Since - // this is not an asynchronous operation, this is merely convenient and helps simplify the - // calling code. - function download(cvs, data, callback) { - var mime = data.mime || DEFAULT_MIME; - - root.location.href = cvs.toDataURL(mime).replace(mime, DOWNLOAD_MIME); - - if (typeof callback === 'function') callback(); - } - // Normalize the `data` that is provided to the main API. - function normalizeData(data) { + const normalizeData = data => { if (typeof data === 'string') data = { value: data }; return data || {}; - } - - // Asynchronously write the data of the rendered canvas to a given file path. - function writeFile(cvs, data, callback) { - if (typeof data.path !== 'string') { - return callback(new TypeError('Invalid path type: ' + typeof data.path)); - } - - var fd, buff; - - // Write the buffer to the open file stream once both prerequisites are met. - function writeBuffer() { - fs.write(fd, buff, 0, buff.length, 0, function (error) { - fs.close(fd); - - callback(error); - }); - } - - // Create a buffer of the canvas' data. - cvs.toBuffer(function (error, _buff) { - if (error) return callback(error); - - buff = _buff; - if (fd) { - writeBuffer(); - } - }); - - // Open a stream for the file to be written. - fs.open(data.path, 'w', WRITE_MODE, function (error, _fd) { - if (error) return callback(error); - - fd = _fd; - if (buff) { - writeBuffer(); - } - }); - } - - // Write the data of the rendered canvas to a given file path. - function writeFileSync(cvs, data) { - if (typeof data.path !== 'string') { - throw new TypeError('Invalid path type: ' + typeof data.path); - } - - var buff = cvs.toBuffer(); - var fd = fs.openSync(data.path, 'w', WRITE_MODE); - - try { - fs.writeSync(fd, buff, 0, buff.length, 0); - } finally { - fs.closeSync(fd); - } - } + }, // Set bit to indicate cell in frame is immutable (symmetric around diagonal). - function setMask(x, y) { + setMask = (x, y) => { var bit; if (x > y) { @@ -274,11 +184,11 @@ bit += x; frameMask[bit] = 1; - } + }, // Enter alignment pattern. Foreground colour to frame, background to mask. Frame will be merged // with mask later. - function addAlignment(x, y) { + addAlignment = (x, y) => { var i; frameBuffer[x + width * y] = 1; @@ -296,21 +206,21 @@ setMask(x - i, y - 1); setMask(x + i, y + 1); } - } + }, // Exponentiation mod N. - function modN(x) { + modN = x => { while (x >= 255) { x -= 255; x = (x >> 8) + (x & 255); } return x; - } + }, // Calculate and append `ecc` data to the `data` block. If block is in the string buffer the // indices to buffers are used. - function appendData(data, dataLength, ecc, eccLength) { + appendData = (data, dataLength, ecc, eccLength) => { var bit, i, j; for (i = 0; i < eccLength; i++) { @@ -334,10 +244,10 @@ stringBuffer[ecc + eccLength - 1] = bit === 255 ? 0 : GALOIS_EXPONENT[modN(bit + polynomial[0])]; } - } + }, // Check mask since symmetricals use half. - function isMasked(x, y) { + isMasked = (x, y) => { var bit; if (x > y) { @@ -352,10 +262,10 @@ bit += x; return frameMask[bit] === 1; - } + }, // Apply the selected mask out of the 8 options. - function applyMask(mask) { + applyMask = mask => { var x, y, r3x, r3y; switch (mask) { @@ -463,11 +373,11 @@ break; } - } + }, // Using the table for the length of each run, calculate the amount of bad image. Long runs or // those that look like finders are called twice; once for X and Y. - function getBadRuns(length) { + getBadRuns = length => { var badRuns = 0; var i; @@ -492,10 +402,10 @@ } return badRuns; - } + }, // Calculate how bad the masked image is (e.g. blocks, imbalance, runs, or finders). - function checkBadness() { + checkBadness = () => { var b, b1, bad, big, bw, count, h, x, y; bad = bw = count = 0; @@ -566,10 +476,10 @@ } return bad; - } + }, // Generate the encoded QR image for the string provided. - function generateFrame(str) { + generateFrame = str => { var i, j, k, m, t, v, x, y; // Find the smallest version that fits the string. @@ -975,13 +885,13 @@ // Finally, return the image data. return frameBuffer; - } + }; // qr.js setup // ----------- // Build the publicly exposed API. - var qr = { + root.qr = { // Constants // --------- @@ -992,12 +902,13 @@ // QR functions // ------------ - // Generate the QR code using the data provided and render it on to a `` element. + // Generate the QR code using the data provided and render it on to a `` element before + // returning its data URI. // If no `` element is specified in the argument provided a new one will be created and // used. // ECC (error correction capacity) determines how many intential errors are contained in the QR // code. - canvas: function(data) { + toDataURL: data => { data = normalizeData(data); // Module size of the generated QR code (i.e. 1-10). @@ -1006,7 +917,7 @@ size *= 25; // `` element used to render the QR code. - var cvs = data.canvas || createCanvas(); + var cvs = inNode ? new Canvas() : document.createElement('canvas'); // Retreive the 2D context of the canvas. var c2d = cvs.getContext('2d'); // Ensure the canvas has the correct dimensions. @@ -1047,131 +958,9 @@ } } - return cvs; - }, - - // Generate the QR code using the data provided and render it on to a `` element. - // If no `` element is specified in the argument provided a new one will be created and - // used. - // ECC (error correction capacity) determines how many intential errors are contained in the QR - // code. - image: function(data) { - data = normalizeData(data); - - // `` element only which the QR code is rendered. - var cvs = this.canvas(data); - // `` element used to display the QR code. - var img = data.image || createImage(); - - // Apply the QR code to `img`. - img.src = cvs.toDataURL(data.mime || DEFAULT_MIME); - img.height = cvs.height; - img.width = cvs.width; - - return img; - }, - - // Generate the QR code using the data provided and render it on to a `` element and - // save it as an image file. - // If no `` element is specified in the argument provided a new one will be created and - // used. - // ECC (error correction capacity) determines how many intential errors are contained in the QR - // code. - // If called in a browser the `path` property/argument is ignored and will simply prompt the - // user to choose a location and file name. However, if called within node.js the file will be - // saved to specified path. - // A `callback` function must be provided which will be called once the saving process has - // started. If an error occurs it will be passed as the first argument to this function, - // otherwise this argument will be `null`. - save: function(data, path, callback) { - data = normalizeData(data); - - switch (typeof path) { - case 'function': - callback = path; - path = null; - break; - case 'string': - data.path = path; - break; - } - - // Callback function is required. - if (typeof callback !== 'function') { - throw new TypeError('Invalid callback type: ' + typeof callback); - } - - var completed = false; - // `` element only which the QR code is rendered. - var cvs = this.canvas(data); - - // Simple function to try and ensure that the `callback` function is only called once. - function done(error) { - if (!completed) { - completed = true; - - callback(error); - } - } - - if (inNode) { - writeFile(cvs, data, done); - } else { - download(cvs, data, done); - } - }, - - // Generate the QR code using the data provided and render it on to a `` element and - // save it as an image file. - // If no `` element is specified in the argument provided a new one will be created and - // used. - // ECC (error correction capacity) determines how many intential errors are contained in the QR - // code. - // If called in a browser the `path` property/argument is ignored and will simply prompt the - // user to choose a location and file name. However, if called within node.js the file will be - // saved to specified path. - saveSync: function(data, path) { - data = normalizeData(data); - - if (typeof path === 'string') data.path = path; - - // `` element only which the QR code is rendered. - var cvs = this.canvas(data); - - if (inNode) { - writeFileSync(cvs, data); - } else { - download(cvs, data); - } - }, - - // Generate the QR code using the data provided and render it on to a `` element before - // returning its data URI. - // If no `` element is specified in the argument provided a new one will be created and - // used. - // ECC (error correction capacity) determines how many intential errors are contained in the QR - // code. - toDataURL: function(data) { - data = normalizeData(data); - - return this.canvas(data).toDataURL(data.mime || DEFAULT_MIME); - }, - - // Utility functions - // ----------------- - - // Run qr.js in *noConflict* mode, returning the `qr` variable to its previous owner. - // Returns a reference to `qr`. - noConflict: function() { - root.qr = previousQr; - return this; + return cvs.toDataURL('image/png'); } }; - // Support - // ------- - - root.qr = qr; - })(this); diff --git a/vendors/qr.js/qr.min.js b/vendors/qr.js/qr.min.js index ec94a416b..784482cb9 100644 --- a/vendors/qr.js/qr.min.js +++ b/vendors/qr.js/qr.min.js @@ -1,4 +1,4 @@ /*! qr-js v1.1.4 | (c) 2015 Alasdair Mercer | GPL v3 License jsqrencode | (c) 2010 tz@execpc.com | GPL v3 License */ -(r=>{"use strict";var o,f,e,t,n,a,i,c,l,s=[0,11,15,19,23,27,31,16,18,20,22,24,26,28,20,22,24,24,26,28,28,22,24,24,26,26,28,28,24,24,26,26,26,28,28,24,26,26,26,28,28],u="image/png",h="image/octet-stream",v=[1,0,19,7,1,0,16,10,1,0,13,13,1,0,9,17,1,0,34,10,1,0,28,16,1,0,22,22,1,0,16,28,1,0,55,15,1,0,44,26,2,0,17,18,2,0,13,22,1,0,80,20,2,0,32,18,2,0,24,26,4,0,9,16,1,0,108,26,2,0,43,24,2,2,15,18,2,2,11,22,2,0,68,18,4,0,27,16,4,0,19,24,4,0,15,28,2,0,78,20,4,0,31,18,2,4,14,18,4,1,13,26,2,0,97,24,2,2,38,22,4,2,18,22,4,2,14,26,2,0,116,30,3,2,36,22,4,4,16,20,4,4,12,24,2,2,68,18,4,1,43,26,6,2,19,24,6,2,15,28,4,0,81,20,1,4,50,30,4,4,22,28,3,8,12,24,2,2,92,24,6,2,36,22,4,6,20,26,7,4,14,28,4,0,107,26,8,1,37,22,8,4,20,24,12,4,11,22,3,1,115,30,4,5,40,24,11,5,16,20,11,5,12,24,5,1,87,22,5,5,41,24,5,7,24,30,11,7,12,24,5,1,98,24,7,3,45,28,15,2,19,24,3,13,15,30,1,5,107,28,10,1,46,28,1,15,22,28,2,17,14,28,5,1,120,30,9,4,43,26,17,1,22,28,2,19,14,28,3,4,113,28,3,11,44,26,17,4,21,26,9,16,13,26,3,5,107,28,3,13,41,26,15,5,24,30,15,10,15,28,4,4,116,28,17,0,42,26,17,6,22,28,19,6,16,30,2,7,111,28,17,0,46,28,7,16,24,30,34,0,13,24,4,5,121,30,4,14,47,28,11,14,24,30,16,14,15,30,6,4,117,30,6,14,45,28,11,16,24,30,30,2,16,30,8,4,106,26,8,13,47,28,7,22,24,30,22,13,15,30,10,2,114,28,19,4,46,28,28,6,22,28,33,4,16,30,8,4,122,30,22,3,45,28,8,26,23,30,12,28,15,30,3,10,117,30,3,23,45,28,4,31,24,30,11,31,15,30,7,7,116,30,21,7,45,28,1,37,23,30,19,26,15,30,5,10,115,30,19,10,47,28,15,25,24,30,23,25,15,30,13,3,115,30,2,29,46,28,42,1,24,30,23,28,15,30,17,0,115,30,10,23,46,28,10,35,24,30,19,35,15,30,17,1,115,30,14,21,46,28,29,19,24,30,11,46,15,30,13,6,115,30,14,23,46,28,44,7,24,30,59,1,16,30,12,7,121,30,12,26,47,28,39,14,24,30,22,41,15,30,6,14,121,30,6,34,47,28,46,10,24,30,2,64,15,30,17,4,122,30,29,14,46,28,49,10,24,30,24,46,15,30,4,18,122,30,13,32,46,28,48,14,24,30,42,32,15,30,20,4,117,30,40,7,47,28,43,22,24,30,10,67,15,30,19,6,118,30,18,31,47,28,34,34,24,30,20,61,15,30],p={L:1,M:2,Q:3,H:4},y=[30660,29427,32170,30877,26159,25368,27713,26998,21522,20773,24188,23371,17913,16590,20375,19104,13663,12392,16177,14854,9396,8579,11994,11245,5769,5054,7399,6608,1890,597,3340,2107],g=[1,2,4,8,16,32,64,128,29,58,116,232,205,135,19,38,76,152,45,90,180,117,234,201,143,3,6,12,24,48,96,192,157,39,78,156,37,74,148,53,106,212,181,119,238,193,159,35,70,140,5,10,20,40,80,160,93,186,105,210,185,111,222,161,95,190,97,194,153,47,94,188,101,202,137,15,30,60,120,240,253,231,211,187,107,214,177,127,254,225,223,163,91,182,113,226,217,175,67,134,17,34,68,136,13,26,52,104,208,189,103,206,129,31,62,124,248,237,199,147,59,118,236,197,151,51,102,204,133,23,46,92,184,109,218,169,79,158,33,66,132,21,42,84,168,77,154,41,82,164,85,170,73,146,57,114,228,213,183,115,230,209,191,99,198,145,63,126,252,229,215,179,123,246,241,255,227,219,171,75,150,49,98,196,149,55,110,220,165,87,174,65,130,25,50,100,200,141,7,14,28,56,112,224,221,167,83,166,81,162,89,178,121,242,249,239,195,155,43,86,172,69,138,9,18,36,72,144,61,122,244,245,247,243,251,235,203,139,11,22,44,88,176,125,250,233,207,131,27,54,108,216,173,71,142,0],w=[255,0,1,25,2,50,26,198,3,223,51,238,27,104,199,75,4,100,224,14,52,141,239,129,28,193,105,248,200,8,76,113,5,138,101,47,225,36,15,33,53,147,142,218,240,18,130,69,29,181,194,125,106,39,249,185,201,154,9,120,77,228,114,166,6,191,139,98,102,221,48,253,226,152,37,179,16,145,34,136,54,208,148,206,143,150,219,189,241,210,19,92,131,56,70,64,30,66,182,163,195,72,126,110,107,58,40,84,250,133,186,61,202,94,155,159,10,21,121,43,78,212,229,172,115,243,167,87,7,112,192,247,140,128,99,13,103,74,222,237,49,197,254,24,227,165,153,119,38,184,180,124,17,68,146,217,35,32,137,46,55,63,209,91,149,188,207,205,144,135,151,178,220,252,190,97,242,86,211,171,20,42,93,158,132,60,57,83,71,109,65,162,31,45,67,216,183,123,164,118,196,23,73,236,127,12,111,246,108,161,59,82,41,157,85,170,251,96,134,177,187,204,62,90,203,89,95,176,156,169,160,81,11,245,22,235,122,117,44,215,79,174,213,233,230,231,173,232,116,214,244,234,168,80,88,175],d=3,m=3,b=40,k=10,R=[3220,1468,2713,1235,3062,1890,2119,1549,2344,2936,1117,2583,1330,2470,1667,2249,2028,3780,481,4011,142,3098,831,3445,592,2517,1776,2234,1951,2827,1070,2660,1345,3177],S=parseInt("0666",8),E=[],L=[],I=1,U=[],C=[],D=!1,q=[],z=r.qr,M=[];function T(o,f,e){var t=f.mime||u;r.location.href=o.toDataURL(t).replace(t,h),"function"==typeof e&&e()}function B(r){return"string"==typeof r&&(r={value:r}),r||{}}function x(r,o){var f;r>o&&(f=r,r=o,o=f),f=o,f*=o,f+=o,f>>=1,C[f+=r]=1}function A(r,o){var f;for(U[r+l*o]=1,f=-2;f<2;f++)U[r+f+l*(o-2)]=1,U[r-2+l*(o+f+1)]=1,U[r+2+l*(o+f)]=1,U[r+f+1+l*(o+2)]=1;for(f=0;f<2;f++)x(r-1,o+f),x(r+1,o-f),x(r-f,o-1),x(r+f,o+1)}function H(r){for(;r>=255;)r=((r-=255)>>8)+(255&r);return r}function N(r,o,f,e){var t,n,a;for(n=0;no&&(f=r,r=o,o=f),f=o,f+=o*o,f>>=1,1===C[f+=r]}function Q(r){var o,f,e,t;switch(r){case 0:for(f=0;f>1&1,o=0;o=5&&(f+=d+E[o]-5);for(o=3;or||3*E[o-3]>=4*E[o]||3*E[o+3]>=4*E[o])&&(f+=b);return f}function W(){var r,o,f,e,t,n,a,i,c;for(f=t=n=0,c=0;cl*l;)e-=l*l,n++;for(f+=n*k,i=0;i=1&&a.size<=10?a.size:4;i*=25;var u=a.canvas||(D?new o:r.document.createElement("canvas")),h=u.getContext("2d");h.canvas.width=i,h.canvas.height=i,h.fillStyle=a.background||"#fff",h.fillRect(0,0,i,i),I=p[a.level&&a.level.toUpperCase()||"L"];var d=function(r){var o,a,i,u,h,p,d,m;h=r.length,c=0;do{if(i=4*(I-1)+16*(++c-1),t=v[i++],n=v[i++],f=v[i++],e=v[i],h<=(i=f*(t+n)+n-3+(c<=9)))break}while(c<40);for(l=17+4*c,p=f+(f+e)*(t+n)+n,h=0;h1)for(h=s[c],m=l-7;;){for(d=l-7;d>h-3&&(A(d,m),!(d6)for(h=R[c-7],i=17,d=0;d<6;d++)for(m=0;m<3;m++,i--)1&(i>11?c>>i-12:h>>i)?(U[5-d+l*(2-m+l-11)]=1,U[2-m+l-11+l*(5-d)]=1):(x(5-d,2-m+l-11),x(2-m+l-11,5-d));for(m=0;m=(d=f*(t+n)+n)-2&&(p=d-2,c>9&&p--),o=p,c>9){for(M[o+2]=0,M[o+3]=0;o--;)h=M[o],M[o+3]|=255&h<<4,M[o+2]=h>>4;M[2]|=255&p<<4,M[1]=p>>4,M[0]=64|p>>12}else{for(M[o+1]=0,M[o+2]=0;o--;)h=M[o],M[o+2]|=255&h<<4,M[o+1]=h>>4;M[1]|=255&p<<4,M[0]=64|p>>4}for(o=p+3-(c<10);o0;a--)q[a]=q[a]?q[a-1]^g[H(w[q[a]]+o)]:q[a-1];q[0]=g[H(w[q[0]]+o)]}for(o=0;o<=e;o++)q[o]=w[q[o]];for(i=d,m=0,o=0;o>=1)1&m&&(U[l-1-i+8*l]=1,i<6?U[8+l*i]=1:U[8+l*(i+1)]=1);for(i=0;i<7;i++,m>>=1)1&m&&(U[8+l*(l-7+i)]=1,i?U[6-i+8*l]=1:U[7+8*l]=1);return U}(a.value||"");h.lineWidth=1;var m=i;m/=l,m=Math.floor(m);var b,k,S=Math.floor((i-m*l)/2);for(h.clearRect(0,0,i,i),h.fillStyle=a.background||"#fff",h.fillRect(0,0,i,i),h.fillStyle=a.foreground||"#000",b=0;b{"use strict";var f,o,e,a,t,l,i=[0,11,15,19,23,27,31,16,18,20,22,24,26,28,20,22,24,24,26,28,28,22,24,24,26,26,28,28,24,24,26,26,26,28,28,24,26,26,26,28,28],c=[1,0,19,7,1,0,16,10,1,0,13,13,1,0,9,17,1,0,34,10,1,0,28,16,1,0,22,22,1,0,16,28,1,0,55,15,1,0,44,26,2,0,17,18,2,0,13,22,1,0,80,20,2,0,32,18,2,0,24,26,4,0,9,16,1,0,108,26,2,0,43,24,2,2,15,18,2,2,11,22,2,0,68,18,4,0,27,16,4,0,19,24,4,0,15,28,2,0,78,20,4,0,31,18,2,4,14,18,4,1,13,26,2,0,97,24,2,2,38,22,4,2,18,22,4,2,14,26,2,0,116,30,3,2,36,22,4,4,16,20,4,4,12,24,2,2,68,18,4,1,43,26,6,2,19,24,6,2,15,28,4,0,81,20,1,4,50,30,4,4,22,28,3,8,12,24,2,2,92,24,6,2,36,22,4,6,20,26,7,4,14,28,4,0,107,26,8,1,37,22,8,4,20,24,12,4,11,22,3,1,115,30,4,5,40,24,11,5,16,20,11,5,12,24,5,1,87,22,5,5,41,24,5,7,24,30,11,7,12,24,5,1,98,24,7,3,45,28,15,2,19,24,3,13,15,30,1,5,107,28,10,1,46,28,1,15,22,28,2,17,14,28,5,1,120,30,9,4,43,26,17,1,22,28,2,19,14,28,3,4,113,28,3,11,44,26,17,4,21,26,9,16,13,26,3,5,107,28,3,13,41,26,15,5,24,30,15,10,15,28,4,4,116,28,17,0,42,26,17,6,22,28,19,6,16,30,2,7,111,28,17,0,46,28,7,16,24,30,34,0,13,24,4,5,121,30,4,14,47,28,11,14,24,30,16,14,15,30,6,4,117,30,6,14,45,28,11,16,24,30,30,2,16,30,8,4,106,26,8,13,47,28,7,22,24,30,22,13,15,30,10,2,114,28,19,4,46,28,28,6,22,28,33,4,16,30,8,4,122,30,22,3,45,28,8,26,23,30,12,28,15,30,3,10,117,30,3,23,45,28,4,31,24,30,11,31,15,30,7,7,116,30,21,7,45,28,1,37,23,30,19,26,15,30,5,10,115,30,19,10,47,28,15,25,24,30,23,25,15,30,13,3,115,30,2,29,46,28,42,1,24,30,23,28,15,30,17,0,115,30,10,23,46,28,10,35,24,30,19,35,15,30,17,1,115,30,14,21,46,28,29,19,24,30,11,46,15,30,13,6,115,30,14,23,46,28,44,7,24,30,59,1,16,30,12,7,121,30,12,26,47,28,39,14,24,30,22,41,15,30,6,14,121,30,6,34,47,28,46,10,24,30,2,64,15,30,17,4,122,30,29,14,46,28,49,10,24,30,24,46,15,30,4,18,122,30,13,32,46,28,48,14,24,30,42,32,15,30,20,4,117,30,40,7,47,28,43,22,24,30,10,67,15,30,19,6,118,30,18,31,47,28,34,34,24,30,20,61,15,30],s={L:1,M:2,Q:3,H:4},n=[30660,29427,32170,30877,26159,25368,27713,26998,21522,20773,24188,23371,17913,16590,20375,19104,13663,12392,16177,14854,9396,8579,11994,11245,5769,5054,7399,6608,1890,597,3340,2107],v=[1,2,4,8,16,32,64,128,29,58,116,232,205,135,19,38,76,152,45,90,180,117,234,201,143,3,6,12,24,48,96,192,157,39,78,156,37,74,148,53,106,212,181,119,238,193,159,35,70,140,5,10,20,40,80,160,93,186,105,210,185,111,222,161,95,190,97,194,153,47,94,188,101,202,137,15,30,60,120,240,253,231,211,187,107,214,177,127,254,225,223,163,91,182,113,226,217,175,67,134,17,34,68,136,13,26,52,104,208,189,103,206,129,31,62,124,248,237,199,147,59,118,236,197,151,51,102,204,133,23,46,92,184,109,218,169,79,158,33,66,132,21,42,84,168,77,154,41,82,164,85,170,73,146,57,114,228,213,183,115,230,209,191,99,198,145,63,126,252,229,215,179,123,246,241,255,227,219,171,75,150,49,98,196,149,55,110,220,165,87,174,65,130,25,50,100,200,141,7,14,28,56,112,224,221,167,83,166,81,162,89,178,121,242,249,239,195,155,43,86,172,69,138,9,18,36,72,144,61,122,244,245,247,243,251,235,203,139,11,22,44,88,176,125,250,233,207,131,27,54,108,216,173,71,142,0],h=[255,0,1,25,2,50,26,198,3,223,51,238,27,104,199,75,4,100,224,14,52,141,239,129,28,193,105,248,200,8,76,113,5,138,101,47,225,36,15,33,53,147,142,218,240,18,130,69,29,181,194,125,106,39,249,185,201,154,9,120,77,228,114,166,6,191,139,98,102,221,48,253,226,152,37,179,16,145,34,136,54,208,148,206,143,150,219,189,241,210,19,92,131,56,70,64,30,66,182,163,195,72,126,110,107,58,40,84,250,133,186,61,202,94,155,159,10,21,121,43,78,212,229,172,115,243,167,87,7,112,192,247,140,128,99,13,103,74,222,237,49,197,254,24,227,165,153,119,38,184,180,124,17,68,146,217,35,32,137,46,55,63,209,91,149,188,207,205,144,135,151,178,220,252,190,97,242,86,211,171,20,42,93,158,132,60,57,83,71,109,65,162,31,45,67,216,183,123,164,118,196,23,73,236,127,12,111,246,108,161,59,82,41,157,85,170,251,96,134,177,187,204,62,90,203,89,95,176,156,169,160,81,11,245,22,235,122,117,44,215,79,174,213,233,230,231,173,232,116,214,244,234,168,80,88,175],u=[3220,1468,2713,1235,3062,1890,2119,1549,2344,2936,1117,2583,1330,2470,1667,2249,2028,3780,481,4011,142,3098,831,3445,592,2517,1776,2234,1951,2827,1070,2660,1345,3177],b=[],k=[],d=1,g=[],R=[],p=[],w=[];const y=(r,f)=>{var o;r>f&&(o=r,r=f,f=o),o=f,o*=f,o+=f,o>>=1,R[o+=r]=1},L=(r,f)=>{var o;for(g[r+l*f]=1,o=-2;o<2;o++)g[r+o+l*(f-2)]=1,g[r-2+l*(f+o+1)]=1,g[r+2+l*(f+o)]=1,g[r+o+1+l*(f+2)]=1;for(o=0;o<2;o++)y(r-1,f+o),y(r+1,f-o),y(r-o,f-1),y(r+o,f+1)},S=r=>{for(;r>=255;)r=((r-=255)>>8)+(255&r);return r},m=(r,f,o,e)=>{var a,t,l;for(t=0;t{var o;return r>f&&(o=r,r=f,f=o),o=f,o+=f*f,o>>=1,1===R[o+=r]},C=r=>{var f,o,e,a;switch(r){case 0:for(o=0;o>1&1,f=0;f{var f,o=0;for(f=0;f<=r;f++)b[f]>=5&&(o+=3+b[f]-5);for(f=3;fr||3*b[f-3]>=4*b[f]||3*b[f+3]>=4*b[f])&&(o+=40);return o},U=()=>{var r,f,o,e,a,t,i,c,s;for(o=a=t=0,s=0;sl*l;)e-=l*l,t++;for(o+=10*t,c=0;c{var b=(r=(r=>("string"==typeof r&&(r={value:r}),r||{}))(r)).size>=1&&r.size<=10?r.size:4;b*=25;var M=document.createElement("canvas"),D=M.getContext("2d");D.canvas.width=b,D.canvas.height=b,D.fillStyle=r.background||"#fff",D.fillRect(0,0,b,b),d=s[r.level&&r.level.toUpperCase()||"L"];var E=(r=>{var s,b,M,D,E,q,x,A;E=r.length,t=0;do{if(M=4*(d-1)+16*(++t-1),e=c[M++],a=c[M++],f=c[M++],o=c[M],E<=(M=f*(e+a)+a-3+(t<=9)))break}while(t<40);for(l=17+4*t,q=f+(f+o)*(e+a)+a,E=0;E1)for(E=i[t],A=l-7;;){for(x=l-7;x>E-3&&(L(x,A),!(x6)for(E=u[t-7],M=17,x=0;x<6;x++)for(A=0;A<3;A++,M--)1&(M>11?t>>M-12:E>>M)?(g[5-x+l*(2-A+l-11)]=1,g[2-A+l-11+l*(5-x)]=1):(y(5-x,2-A+l-11),y(2-A+l-11,5-x));for(A=0;A=(x=f*(e+a)+a)-2&&(q=x-2,t>9&&q--),s=q,t>9){for(w[s+2]=0,w[s+3]=0;s--;)E=w[s],w[s+3]|=255&E<<4,w[s+2]=E>>4;w[2]|=255&q<<4,w[1]=q>>4,w[0]=64|q>>12}else{for(w[s+1]=0,w[s+2]=0;s--;)E=w[s],w[s+2]|=255&E<<4,w[s+1]=E>>4;w[1]|=255&q<<4,w[0]=64|q>>4}for(s=q+3-(t<10);s0;b--)p[b]=p[b]?p[b-1]^v[S(h[p[b]]+s)]:p[b-1];p[0]=v[S(h[p[0]]+s)]}for(s=0;s<=o;s++)p[s]=h[p[s]];for(M=x,A=0,s=0;s>=1)1&A&&(g[l-1-M+8*l]=1,M<6?g[8+l*M]=1:g[8+l*(M+1)]=1);for(M=0;M<7;M++,A>>=1)1&A&&(g[8+l*(l-7+M)]=1,M?g[6-M+8*l]=1:g[7+8*l]=1);return g})(r.value||"");D.lineWidth=1;var q=b;q/=l,q=Math.floor(q);var x,A,H=Math.floor((b-q*l)/2);for(D.clearRect(0,0,b,b),D.fillStyle=r.background||"#fff",D.fillRect(0,0,b,b),D.fillStyle=r.foreground||"#000",x=0;x