UNPKG

kepler.gl.geoiq

Version:

kepler.gl is a webgl based application to visualize large scale location data in the browser

551 lines (462 loc) 62.6 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _window = _interopRequireDefault(require("global/window")); var _document = _interopRequireDefault(require("global/document")); var _console = _interopRequireDefault(require("global/console")); var _miniSvgDataUri = _interopRequireDefault(require("mini-svg-data-uri")); var _userFeedbacks = require("../constants/user-feedbacks"); var _domUtils = require("./dom-utils"); // Copyright (c) 2023 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. /** * This file is copied from https://github.com/tsayen/dom-to-image * Modified by heshan0131 to allow loading external stylesheets and inline webfonts */ var inliner = newInliner(); var fontFaces = newFontFaces(); var images = newImages(); // Default impl options var defaultOptions = { // Default is to fail on error, no placeholder imagePlaceholder: undefined, // Default cache bust is false, it will use the cache cacheBust: false }; var domtoimage = { toSvg: toSvg, toPng: toPng, toJpeg: toJpeg, toBlob: toBlob, toPixelData: toPixelData, impl: { fontFaces: fontFaces, images: images, inliner: inliner, options: {} } }; /** * @param {Node} node - The DOM Node object to render * @param {Object} options - Rendering options * @param {Function} options.filter - Should return true if passed node should be included in the output * (excluding node means excluding it's children as well). Not called on the root node. * @param {String} options.bgcolor - color for the background, any valid CSS color value. * @param {Number} options.width - width to be applied to node before rendering. * @param {Number} options.height - height to be applied to node before rendering. * @param {Object} options.style - an object whose properties to be copied to node's style before rendering. * @param {Number} options.quality - a Number between 0 and 1 indicating image quality (applicable to JPEG only), defaults to 1.0. * @param {String} options.imagePlaceholder - dataURL to use as a placeholder for failed images, default behaviour is to fail fast on images we can't fetch * @param {Boolean} options.cacheBust - set to true to cache bust by appending the time to the request url * @return {Promise} - A promise that is fulfilled with a SVG image data URL * */ function toSvg(node, options) { options = options || {}; copyOptions(options); return Promise.resolve(node).then(function (nd) { return cloneNode(nd, options.filter, true); }).then(embedFonts).then(inlineImages).then(applyOptions).then(function (clone) { return makeSvgDataUri(clone, options.width || (0, _domUtils.getWidth)(node), options.height || (0, _domUtils.getHeight)(node)); }); function applyOptions(clone) { if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; if (options.width) clone.style.width = "".concat(options.width, "px"); if (options.height) clone.style.height = "".concat(options.height, "px"); if (options.style) Object.keys(options.style).forEach(function (property) { clone.style[property] = options.style[property]; }); return clone; } } /** * @param {Node} node - The DOM Node object to render * @param {Object} options - Rendering options, @see {@link toSvg} * @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data. * */ function toPixelData(node, options) { return draw(node, options || {}).then(function (canvas) { return canvas.getContext('2d').getImageData(0, 0, (0, _domUtils.getWidth)(node), (0, _domUtils.getHeight)(node)).data; }); } /** * @param {Node} node - The DOM Node object to render * @param {Object} options - Rendering options, @see {@link toSvg} * @return {Promise} - A promise that is fulfilled with a PNG image data URL * */ function toPng(node, options) { return draw(node, options || {}).then(function (canvas) { return canvas.toDataURL(); }); } /** * @param {Node} node - The DOM Node object to render * @param {Object} options - Rendering options, @see {@link toSvg} * @return {Promise} - A promise that is fulfilled with a JPEG image data URL * */ function toJpeg(node, options) { options = options || {}; return draw(node, options).then(function (canvas) { return canvas.toDataURL('image/jpeg', options.quality || 1.0); }); } /** * @param {Node} node - The DOM Node object to render * @param {Object} options - Rendering options, @see {@link toSvg} * @return {Promise} - A promise that is fulfilled with a PNG image blob * */ function toBlob(node, options) { return draw(node, options || {}).then(_domUtils.canvasToBlob); } function copyOptions(options) { // Copy options to impl options for use in impl if (typeof options.imagePlaceholder === 'undefined') { domtoimage.impl.options.imagePlaceholder = defaultOptions.imagePlaceholder; } else { domtoimage.impl.options.imagePlaceholder = options.imagePlaceholder; } if (typeof options.cacheBust === 'undefined') { domtoimage.impl.options.cacheBust = defaultOptions.cacheBust; } else { domtoimage.impl.options.cacheBust = options.cacheBust; } } function draw(domNode, options) { return toSvg(domNode, options).then(_domUtils.makeImage).then((0, _domUtils.delay)(100)).then(function (image) { var canvas = newCanvas(domNode); canvas.getContext('2d').drawImage(image, 0, 0); return canvas; }); function newCanvas(dNode) { var canvas = _document["default"].createElement('canvas'); canvas.width = options.width || (0, _domUtils.getWidth)(dNode); canvas.height = options.height || (0, _domUtils.getHeight)(dNode); if (options.bgcolor) { var ctx = canvas.getContext('2d'); ctx.fillStyle = options.bgcolor; ctx.fillRect(0, 0, canvas.width, canvas.height); } return canvas; } } function cloneNode(node, filter, root) { if (!root && filter && !filter(node)) { return Promise.resolve(); } return Promise.resolve(node).then(makeNodeCopy).then(function (clone) { return cloneChildren(node, clone, filter); }).then(function (clone) { return (0, _domUtils.processClone)(node, clone); }); function makeNodeCopy(nd) { if (nd instanceof _window["default"].HTMLCanvasElement) { return (0, _domUtils.makeImage)(nd.toDataURL()); } return nd.cloneNode(false); } function cloneChildrenInOrder(parent, arrChildren, flt) { var done = Promise.resolve(); arrChildren.forEach(function (child) { done = done.then(function () { return cloneNode(child, flt); }).then(function (childClone) { if (childClone) { parent.appendChild(childClone); } }); }); return done; } function cloneChildren(original, clone, flt) { var children = original.childNodes; if (children.length === 0) { return Promise.resolve(clone); } return cloneChildrenInOrder(clone, (0, _domUtils.asArray)(children), flt).then(function () { return clone; }); } } function embedFonts(node) { return fontFaces.resolveAll().then(function (cssText) { var styleNode = _document["default"].createElement('style'); node.appendChild(styleNode); styleNode.appendChild(_document["default"].createTextNode(cssText)); return node; }); } function inlineImages(node) { return images.inlineAll(node).then(function () { return node; }); } function makeSvgDataUri(node, width, height) { return Promise.resolve(node).then(function (nd) { nd.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); var serializedString = new _window["default"].XMLSerializer().serializeToString(nd); var xhtml = (0, _domUtils.escapeXhtml)(serializedString); var foreignObject = "<foreignObject x=\"0\" y=\"0\" width=\"100%\" height=\"100%\">".concat(xhtml, "</foreignObject>"); var svgStr = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"".concat(width, "\" height=\"").concat(height, "\">").concat(foreignObject, "</svg>"); // Optimizing SVGs in data URIs // see https://codepen.io/tigt/post/optimizing-svgs-in-data-uris // the best way of encoding SVG in a data: URI is data:image/svg+xml,[actual data]. // We don’t need the ;charset=utf-8 parameter because the given SVG is ASCII. return (0, _miniSvgDataUri["default"])(svgStr); }); } function newInliner() { var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; return { inlineAll: inlineAll, shouldProcess: shouldProcess, impl: { readUrls: readUrls, inline: inline } }; function shouldProcess(string) { return string.search(URL_REGEX) !== -1; } function readUrls(string) { var result = []; var match; while ((match = URL_REGEX.exec(string)) !== null) { result.push(match[1]); } return result.filter(function (url) { return !(0, _domUtils.isDataUrl)(url); }); } function urlAsRegex(url0) { return new RegExp("(url\\(['\"]?)(".concat((0, _domUtils.escape)(url0), ")(['\"]?\\))"), 'g'); } function inline(string, url, baseUrl, get) { return Promise.resolve(url).then(function (ul) { return baseUrl ? (0, _domUtils.resolveUrl)(ul, baseUrl) : ul; }).then(function (ul) { return typeof get === 'function' ? get(ul) : (0, _domUtils.getAndEncode)(ul, domtoimage.impl.options); }).then(function (data) { return (0, _domUtils.dataAsUrl)(data, (0, _domUtils.mimeType)(url)); }).then(function (dataUrl) { return string.replace(urlAsRegex(url), "$1".concat(dataUrl, "$3")); }); } function inlineAll(string, baseUrl, get) { if (!shouldProcess(string) || (0, _domUtils.isSrcAsDataUrl)(string)) { return Promise.resolve(string); } return Promise.resolve(string).then(readUrls).then(function (urls) { var done = Promise.resolve(string); urls.forEach(function (url) { done = done.then(function (str) { return inline(str, url, baseUrl, get); }); }); return done; }); } } function newFontFaces() { return { resolveAll: resolveAll, impl: { readAll: readAll } }; function resolveAll() { return readAll(_document["default"]).then(function (webFonts) { return Promise.all(webFonts.map(function (webFont) { return webFont.resolve(); })); }).then(function (cssStrings) { return cssStrings.join('\n'); }); } function readAll() { return Promise.resolve((0, _domUtils.asArray)(_document["default"].styleSheets)).then(loadExternalStyleSheets).then(getCssRules).then(selectWebFontRules).then(function (rules) { return rules.map(newWebFont); }); function selectWebFontRules(cssRules) { return cssRules.filter(function (rule) { return rule.type === _window["default"].CSSRule.FONT_FACE_RULE; }).filter(function (rule) { return inliner.shouldProcess(rule.style.getPropertyValue('src')); }); } function loadExternalStyleSheets(styleSheets) { return Promise.all(styleSheets.map(function (sheet) { if (sheet.href) { // cloudfont doesn't have allow origin header properly set // error response will remain in cache var cache = sheet.href.includes('uber-fonts') ? 'no-cache' : 'default'; return _window["default"].fetch(sheet.href, { credentials: 'omit', cache: cache }).then(function (response) { return response.text(); }).then(setBaseHref(sheet.href)).then(toStyleSheet)["catch"](function (err) { // Handle any error that occurred in any of the previous // promises in the chain. stylesheet failed to load should not stop // the process, hence result in only a warning, instead of reject _console["default"].warn(_userFeedbacks.IMAGE_EXPORT_ERRORS.styleSheet, sheet.href); _console["default"].log(err); return; }); } return Promise.resolve(sheet); })); function setBaseHref(base) { base = base.split('/'); base.pop(); base = base.join('/'); function addBaseHrefToUrl(match, p1) { var url = /^http/i.test(p1) ? p1 : concatAndResolveUrl(base, p1); return "url('".concat(url, "')"); } // Source: http://stackoverflow.com/a/2676231/3786856 function concatAndResolveUrl(url, concat) { var url1 = url.split('/'); var url2 = concat.split('/'); var url3 = []; for (var i = 0, l = url1.length; i < l; i++) { if (url1[i] === '..') { url3.pop(); } else if (url1[i] !== '.') { url3.push(url1[i]); } } for (var _i2 = 0, _l2 = url2.length; _i2 < _l2; _i2++) { if (url2[_i2] === '..') { url3.pop(); } else if (url2[_i2] !== '.') { url3.push(url2[_i2]); } } return url3.join('/'); } return function (text) { return (0, _domUtils.isSrcAsDataUrl)(text) ? text : text.replace(/url\(['"]?([^'"]+?)['"]?\)/g, addBaseHrefToUrl); }; } function toStyleSheet(text) { var doc = _document["default"].implementation.createHTMLDocument(''); var styleElement = _document["default"].createElement('style'); styleElement.textContent = text; doc.body.appendChild(styleElement); return styleElement.sheet; } } function getCssRules(styleSheets) { var cssRules = []; styleSheets.forEach(function (sheet) { // try...catch because browser may not able to enumerate rules for cross-domain sheets if (!sheet) { return; } var rules; try { rules = sheet.rules || sheet.cssRules; } catch (e) { _console["default"].log("'Can't read the css rules of: ".concat(sheet.href), e); return; } if (rules && (0, _typeof2["default"])(rules) === 'object') { try { (0, _domUtils.asArray)(rules || []).forEach(cssRules.push.bind(cssRules)); } catch (e) { _console["default"].log("Error while reading CSS rules from ".concat(sheet.href), e); return; } } else { _console["default"].log('getCssRules can not find cssRules'); return; } }); return cssRules; } function newWebFont(webFontRule) { return { resolve: function resolve() { var baseUrl = (webFontRule.parentStyleSheet || {}).href; return inliner.inlineAll(webFontRule.cssText, baseUrl); }, src: function src() { return webFontRule.style.getPropertyValue('src'); } }; } } } function newImages() { return { inlineAll: inlineAll, impl: { newImage: newImage } }; function newImage(element) { function inline(get) { if (element.src) { return Promise.resolve(); } return Promise.resolve(element.src).then(function (ul) { return typeof get === 'function' ? get(ul) : (0, _domUtils.getAndEncode)(ul, domtoimage.impl.options); }).then(function (data) { return (0, _domUtils.dataAsUrl)(data, (0, _domUtils.mimeType)(element.src)); }).then(function (dataUrl) { return new Promise(function (resolve, reject) { element.onload = resolve; element.onerror = reject; element.src = dataUrl; }); }); } return { inline: inline }; } function inlineAll(node) { if (!(node instanceof Element)) { return Promise.resolve(node); } return inlineBackground(node).then(function () { if (node instanceof HTMLImageElement) { return newImage(node).inline(); } return Promise.all((0, _domUtils.asArray)(node.childNodes).map(function (child) { return inlineAll(child); })); }); function inlineBackground(nd) { var background = nd.style.getPropertyValue('background'); if (!background) { return Promise.resolve(nd); } return inliner.inlineAll(background).then(function (inlined) { nd.style.setProperty('background', inlined, nd.style.getPropertyPriority('background')); }).then(function () { return nd; }); } } } var _default = exports["default"] = domtoimage; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9kb20tdG8taW1hZ2UuanMiXSwibmFtZXMiOlsiaW5saW5lciIsIm5ld0lubGluZXIiLCJmb250RmFjZXMiLCJuZXdGb250RmFjZXMiLCJpbWFnZXMiLCJuZXdJbWFnZXMiLCJkZWZhdWx0T3B0aW9ucyIsImltYWdlUGxhY2Vob2xkZXIiLCJ1bmRlZmluZWQiLCJjYWNoZUJ1c3QiLCJkb210b2ltYWdlIiwidG9TdmciLCJ0b1BuZyIsInRvSnBlZyIsInRvQmxvYiIsInRvUGl4ZWxEYXRhIiwiaW1wbCIsIm9wdGlvbnMiLCJub2RlIiwiY29weU9wdGlvbnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInRoZW4iLCJuZCIsImNsb25lTm9kZSIsImZpbHRlciIsImVtYmVkRm9udHMiLCJpbmxpbmVJbWFnZXMiLCJhcHBseU9wdGlvbnMiLCJjbG9uZSIsIm1ha2VTdmdEYXRhVXJpIiwid2lkdGgiLCJoZWlnaHQiLCJiZ2NvbG9yIiwic3R5bGUiLCJiYWNrZ3JvdW5kQ29sb3IiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsInByb3BlcnR5IiwiZHJhdyIsImNhbnZhcyIsImdldENvbnRleHQiLCJnZXRJbWFnZURhdGEiLCJkYXRhIiwidG9EYXRhVVJMIiwicXVhbGl0eSIsImNhbnZhc1RvQmxvYiIsImRvbU5vZGUiLCJtYWtlSW1hZ2UiLCJpbWFnZSIsIm5ld0NhbnZhcyIsImRyYXdJbWFnZSIsImROb2RlIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50IiwiY3R4IiwiZmlsbFN0eWxlIiwiZmlsbFJlY3QiLCJyb290IiwibWFrZU5vZGVDb3B5IiwiY2xvbmVDaGlsZHJlbiIsIndpbmRvdyIsIkhUTUxDYW52YXNFbGVtZW50IiwiY2xvbmVDaGlsZHJlbkluT3JkZXIiLCJwYXJlbnQiLCJhcnJDaGlsZHJlbiIsImZsdCIsImRvbmUiLCJjaGlsZCIsImNoaWxkQ2xvbmUiLCJhcHBlbmRDaGlsZCIsIm9yaWdpbmFsIiwiY2hpbGRyZW4iLCJjaGlsZE5vZGVzIiwibGVuZ3RoIiwicmVzb2x2ZUFsbCIsImNzc1RleHQiLCJzdHlsZU5vZGUiLCJjcmVhdGVUZXh0Tm9kZSIsImlubGluZUFsbCIsInNldEF0dHJpYnV0ZSIsInNlcmlhbGl6ZWRTdHJpbmciLCJYTUxTZXJpYWxpemVyIiwic2VyaWFsaXplVG9TdHJpbmciLCJ4aHRtbCIsImZvcmVpZ25PYmplY3QiLCJzdmdTdHIiLCJVUkxfUkVHRVgiLCJzaG91bGRQcm9jZXNzIiwicmVhZFVybHMiLCJpbmxpbmUiLCJzdHJpbmciLCJzZWFyY2giLCJyZXN1bHQiLCJtYXRjaCIsImV4ZWMiLCJwdXNoIiwidXJsIiwidXJsQXNSZWdleCIsInVybDAiLCJSZWdFeHAiLCJiYXNlVXJsIiwiZ2V0IiwidWwiLCJkYXRhVXJsIiwicmVwbGFjZSIsInVybHMiLCJzdHIiLCJyZWFkQWxsIiwid2ViRm9udHMiLCJhbGwiLCJtYXAiLCJ3ZWJGb250IiwiY3NzU3RyaW5ncyIsImpvaW4iLCJzdHlsZVNoZWV0cyIsImxvYWRFeHRlcm5hbFN0eWxlU2hlZXRzIiwiZ2V0Q3NzUnVsZXMiLCJzZWxlY3RXZWJGb250UnVsZXMiLCJydWxlcyIsIm5ld1dlYkZvbnQiLCJjc3NSdWxlcyIsInJ1bGUiLCJ0eXBlIiwiQ1NTUnVsZSIsIkZPTlRfRkFDRV9SVUxFIiwiZ2V0UHJvcGVydHlWYWx1ZSIsInNoZWV0IiwiaHJlZiIsImNhY2hlIiwiaW5jbHVkZXMiLCJmZXRjaCIsImNyZWRlbnRpYWxzIiwicmVzcG9uc2UiLCJ0ZXh0Iiwic2V0QmFzZUhyZWYiLCJ0b1N0eWxlU2hlZXQiLCJlcnIiLCJjb25zb2xlIiwid2FybiIsIklNQUdFX0VYUE9SVF9FUlJPUlMiLCJzdHlsZVNoZWV0IiwibG9nIiwiYmFzZSIsInNwbGl0IiwicG9wIiwiYWRkQmFzZUhyZWZUb1VybCIsInAxIiwidGVzdCIsImNvbmNhdEFuZFJlc29sdmVVcmwiLCJjb25jYXQiLCJ1cmwxIiwidXJsMiIsInVybDMiLCJpIiwibCIsImRvYyIsImltcGxlbWVudGF0aW9uIiwiY3JlYXRlSFRNTERvY3VtZW50Iiwic3R5bGVFbGVtZW50IiwidGV4dENvbnRlbnQiLCJib2R5IiwiZSIsImJpbmQiLCJ3ZWJGb250UnVsZSIsInBhcmVudFN0eWxlU2hlZXQiLCJzcmMiLCJuZXdJbWFnZSIsImVsZW1lbnQiLCJyZWplY3QiLCJvbmxvYWQiLCJvbmVycm9yIiwiRWxlbWVudCIsImlubGluZUJhY2tncm91bmQiLCJIVE1MSW1hZ2VFbGVtZW50IiwiYmFja2dyb3VuZCIsImlubGluZWQiLCJzZXRQcm9wZXJ0eSIsImdldFByb3BlcnR5UHJpb3JpdHkiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O0FBeUJBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQTlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7OztBQTRCQSxJQUFNQSxPQUFPLEdBQUdDLFVBQVUsRUFBMUI7QUFDQSxJQUFNQyxTQUFTLEdBQUdDLFlBQVksRUFBOUI7QUFDQSxJQUFNQyxNQUFNLEdBQUdDLFNBQVMsRUFBeEIsQyxDQUNBOztBQUNBLElBQU1DLGNBQWMsR0FBRztBQUNyQjtBQUNBQyxFQUFBQSxnQkFBZ0IsRUFBRUMsU0FGRztBQUdyQjtBQUNBQyxFQUFBQSxTQUFTLEVBQUU7QUFKVSxDQUF2QjtBQU9BLElBQU1DLFVBQVUsR0FBRztBQUNqQkMsRUFBQUEsS0FBSyxFQUFMQSxLQURpQjtBQUVqQkMsRUFBQUEsS0FBSyxFQUFMQSxLQUZpQjtBQUdqQkMsRUFBQUEsTUFBTSxFQUFOQSxNQUhpQjtBQUlqQkMsRUFBQUEsTUFBTSxFQUFOQSxNQUppQjtBQUtqQkMsRUFBQUEsV0FBVyxFQUFYQSxXQUxpQjtBQU1qQkMsRUFBQUEsSUFBSSxFQUFFO0FBQ0pkLElBQUFBLFNBQVMsRUFBVEEsU0FESTtBQUVKRSxJQUFBQSxNQUFNLEVBQU5BLE1BRkk7QUFHSkosSUFBQUEs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Q2YsZUFBTzVKLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQkUsRUFBaEIsQ0FBUDtBQUNEOztBQUVELGFBQU92QixPQUFPLENBQ1hnRixTQURJLENBQ01nRyxVQUROLEVBRUoxSixJQUZJLENBRUMsVUFBQTJKLE9BQU8sRUFBSTtBQUNmMUosUUFBQUEsRUFBRSxDQUFDVyxLQUFILENBQVNnSixXQUFULENBQ0UsWUFERixFQUVFRCxPQUZGLEVBR0UxSixFQUFFLENBQUNXLEtBQUgsQ0FBU2lKLG1CQUFULENBQTZCLFlBQTdCLENBSEY7QUFLRCxPQVJJLEVBU0o3SixJQVRJLENBU0M7QUFBQSxlQUFNQyxFQUFOO0FBQUEsT0FURCxDQUFQO0FBVUQ7QUFDRjtBQUNGOztvQ0FFY2IsVSIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgMjAyMyBVYmVyIFRlY2hub2xvZ2llcywgSW5jLlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbi8vIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbi8vIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuLy8gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4vLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbi8vIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4vLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyBUSEUgU09GVFdBUkUuXG5cbi8qKlxuICogVGhpcyBmaWxlIGlzIGNvcGllZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS90c2F5ZW4vZG9tLXRvLWltYWdlXG4gKiBNb2RpZmllZCBieSBoZXNoYW4wMTMxIHRvIGFsbG93IGxvYWRpbmcgZXh0ZXJuYWwgc3R5bGVzaGVldHMgYW5kIGlubGluZSB3ZWJmb250c1xuICovXG5cbmltcG9ydCB3aW5kb3cgZnJvbSAnZ2xvYmFsL3dpbmRvdyc7XG5pbXBvcnQgZG9jdW1lbnQgZnJvbSAnZ2xvYmFsL2RvY3VtZW50JztcbmltcG9ydCBjb25zb2xlIGZyb20gJ2dsb2JhbC9jb25zb2xlJztcbmltcG9ydCBzdmdUb01pbmlEYXRhVVJJIGZyb20gJ21pbmktc3ZnLWRhdGEtdXJpJztcbmltcG9ydCB7SU1BR0VfRVhQT1JUX0VSUk9SU30gZnJvbSAnY29uc3RhbnRzL3VzZXItZmVlZGJhY2tzJztcbmltcG9ydCB7XG4gIGNhbnZhc1RvQmxvYixcbiAgZXNjYXBlLFxuICBlc2NhcGVYaHRtbCxcbiAgZGVsYXksXG4gIHByb2Nlc3NDbG9uZSxcbiAgYXNBcnJheSxcbiAgbWFrZUltYWdlLFxuICBtaW1lVHlwZSxcbiAgZGF0YUFzVXJsLFxuICBpc0RhdGFVcmwsXG4gIGlzU3JjQXNEYXRhVXJsLFxuICByZXNvbHZlVXJsLFxuICBnZXRXaWR0aCxcbiAgZ2V0SGVpZ2h0LFxuICBnZXRBbmRFbmNvZGVcbn0gZnJvbSAnLi9kb20tdXRpbHMnO1xuXG5jb25zdCBpbmxpbmVyID0gbmV3SW5saW5lcigpO1xuY29uc3QgZm9udEZhY2VzID0gbmV3Rm9udEZhY2VzKCk7XG5jb25zdCBpbWFnZXMgPSBuZXdJbWFnZXMoKTtcbi8vIERlZmF1bHQgaW1wbCBvcHRpb25zXG5jb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgLy8gRGVmYXVsdCBpcyB0byBmYWlsIG9uIGVycm9yLCBubyBwbGFjZWhvbGRlclxuICBpbWFnZVBsYWNlaG9sZGVyOiB1bmRlZmluZWQsXG4gIC8vIERlZmF1bHQgY2FjaGUgYnVzdCBpcyBmYWxzZSwgaXQgd2lsbCB1c2UgdGhlIGNhY2hlXG4gIGNhY2hlQnVzdDogZmFsc2Vcbn07XG5cbmNvbnN0IGRvbXRvaW1hZ2UgPSB7XG4gIHRvU3ZnLFxuICB0b1BuZyxcbiAgdG9KcGVnLFxuICB0b0Jsb2IsXG4gIHRvUGl4ZWxEYXRhLFxuICBpbXBsOiB7XG4gICAgZm9udEZhY2VzLFxuICAgIGltYWdlcyxcbiAgICBpbmxpbmVyLFxuICAgIG9wdGlvbnM6IHt9XG4gIH1cbn07XG5cbi8qKlxuICAgKiBAcGFyYW0ge05vZGV9IG5vZGUgLSBUaGUgRE9NIE5vZGUgb2JqZWN0IHRvIHJlbmRlclxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFJlbmRlcmluZyBvcHRpb25zXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdGlvbnMuZmlsdGVyIC0gU2hvdWxkIHJldHVybiB0cnVlIGlmIHBhc3NlZCBub2RlIHNob3VsZCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0XG4gICAqICAgICAgICAgIChleGNsdWRpbmcgbm9kZSBtZWFucyBleGNsdWRpbmcgaXQncyBjaGlsZHJlbiBhcyB3ZWxsKS4gTm90IGNhbGxlZCBvbiB0aGUgcm9vdCBub2RlLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gb3B0aW9ucy5iZ2NvbG9yIC0gY29sb3IgZm9yIHRoZSBiYWNrZ3JvdW5kLCBhbnkgdmFsaWQgQ1NTIGNvbG9yIHZhbHVlLlxuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy53aWR0aCAtIHdpZHRoIHRvIGJlIGFwcGxpZWQgdG8gbm9kZSBiZWZvcmUgcmVuZGVyaW5nLlxuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5oZWlnaHQgLSBoZWlnaHQgdG8gYmUgYXBwbGllZCB0byBub2RlIGJlZm9yZSByZW5kZXJpbmcuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLnN0eWxlIC0gYW4gb2JqZWN0IHdob3NlIHByb3BlcnRpZXMgdG8gYmUgY29waWVkIHRvIG5vZGUncyBzdHlsZSBiZWZvcmUgcmVuZGVyaW5nLlxuICAgKiBAcGFyYW0ge051bWJlcn0gb3B0aW9ucy5xdWFsaXR5IC0gYSBOdW1iZXIgYmV0d2VlbiAwIGFuZCAxIGluZGljYXRpbmcgaW1hZ2UgcXVhbGl0eSAoYXBwbGljYWJsZSB0byBKUEVHIG9ubHkpLFxuICAgICAgICAgICAgICBkZWZhdWx0cyB0byAxLjAuXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gb3B0aW9ucy5pbWFnZVBsYWNlaG9sZGVyIC0gZGF0YVVSTCB0byB1c2UgYXMgYSBwbGFjZWhvbGRlciBmb3IgZmFpbGVkIGltYWdlcywgZGVmYXVsdCBiZWhhdmlvdXIgaXMgdG8gZmFpbCBmYXN0IG9uIGltYWdlcyB3ZSBjYW4ndCBmZXRjaFxuICAgICogQHBhcmFtIHtCb29sZWFufSBvcHRpb25zLmNhY2hlQnVzdCAtIHNldCB0byB0cnVlIHRvIGNhY2hlIGJ1c3QgYnkgYXBwZW5kaW5nIHRoZSB0aW1lIHRvIHRoZSByZXF1ZXN0IHVybFxuICAgICogQHJldHVybiB7UHJvbWlzZX0gLSBBIHByb21pc2UgdGhhdCBpcyBmdWxmaWxsZWQgd2l0aCBhIFNWRyBpbWFnZSBkYXRhIFVSTFxuICAgICogKi9cbmZ1bmN0aW9uIHRvU3ZnKG5vZGUsIG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gIGNvcHlPcHRpb25zKG9wdGlvbnMpO1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5vZGUpXG4gICAgLnRoZW4obmQgPT4gY2xvbmVOb2RlKG5kLCBvcHRpb25zLmZpbHRlciwgdHJ1ZSkpXG4gICAgLnRoZW4oZW1iZWRGb250cylcbiAgICAudGhlbihpbmxpbmVJbWFnZXMpXG4gICAgLnRoZW4oYXBwbHlPcHRpb25zKVxuICAgIC50aGVuKGNsb25lID0+XG4gICAgICBtYWtlU3ZnRGF0YVVyaShcbiAgICAgICAgY2xvbmUsXG4gICAgICAgIG9wdGlvbnMud2lkdGggfHwgZ2V0V2lkdGgobm9kZSksXG4gICAgICAgIG9wdGlvbnMuaGVpZ2h0IHx8IGdldEhlaWdodChub2RlKVxuICAgICAgKVxuICAgICk7XG5cbiAgZnVuY3Rpb24gYXBwbHlPcHRpb25zKGNsb25lKSB7XG4gICAgaWYgKG9wdGlvbnMuYmdjb2xvcikgY2xvbmUuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gb3B0aW9ucy5iZ2NvbG9yO1xuXG4gICAgaWYgKG9wdGlvbnMud2lkdGgpIGNsb25lLnN0eWxlLndpZHRoID0gYCR7b3B0aW9ucy53aWR0aH1weGA7XG4gICAgaWYgKG9wdGlvbnMuaGVpZ2h0KSBjbG9uZS5zdHlsZS5oZWlnaHQgPSBgJHtvcHRpb25zLmhlaWdodH1weGA7XG5cbiAgICBpZiAob3B0aW9ucy5zdHlsZSlcbiAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMuc3R5bGUpLmZvckVhY2goKHByb3BlcnR5KSA9PiB7XG4gICAgICAgIGNsb25lLnN0eWxlW3Byb3BlcnR5XSA9IG9wdGlvbnMuc3R5bGVbcHJvcGVydHldO1xuICAgICAgfSk7XG5cbiAgICByZXR1cm4gY2xvbmU7XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgLSBUaGUgRE9NIE5vZGUgb2JqZWN0IHRvIHJlbmRlclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBSZW5kZXJpbmcgb3B0aW9ucywgQHNlZSB7QGxpbmsgdG9Tdmd9XG4gKiBAcmV0dXJuIHtQcm9taXNlfSAtIEEgcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCB3aXRoIGEgVWludDhBcnJheSBjb250YWluaW5nIFJHQkEgcGl4ZWwgZGF0YS5cbiAqICovXG5mdW5jdGlvbiB0b1BpeGVsRGF0YShub2RlLCBvcHRpb25zKSB7XG4gIHJldHVybiBkcmF3KG5vZGUsIG9wdGlvbnMgfHwge30pLnRoZW4oY2FudmFzID0+XG4gICAgY2FudmFzXG4gICAgICAuZ2V0Q29udGV4dCgnMmQnKVxuICAgICAgLmdldEltYWdlRGF0YSgwLCAwLCBnZXRXaWR0aChub2RlKSwgZ2V0SGVpZ2h0KG5vZGUpKS5kYXRhXG4gICk7XG59XG5cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlIC0gVGhlIERPTSBOb2RlIG9iamVjdCB0byByZW5kZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gUmVuZGVyaW5nIG9wdGlvbnMsIEBzZWUge0BsaW5rIHRvU3ZnfVxuICogQHJldHVybiB7UHJvbWlzZX0gLSBBIHByb21pc2UgdGhhdCBpcyBmdWxmaWxsZWQgd2l0aCBhIFBORyBpbWFnZSBkYXRhIFVSTFxuICogKi9cbmZ1bmN0aW9uIHRvUG5nKG5vZGUsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGRyYXcobm9kZSwgb3B0aW9ucyB8fCB7fSkudGhlbihjYW52YXMgPT4gY2FudmFzLnRvRGF0YVVSTCgpKTtcbn1cblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IG5vZGUgLSBUaGUgRE9NIE5vZGUgb2JqZWN0IHRvIHJlbmRlclxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBSZW5kZXJpbmcgb3B0aW9ucywgQHNlZSB7QGxpbmsgdG9Tdmd9XG4gKiBAcmV0dXJuIHtQcm9taXNlfSAtIEEgcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCB3aXRoIGEgSlBFRyBpbWFnZSBkYXRhIFVSTFxuICogKi9cbmZ1bmN0aW9uIHRvSnBlZyhub2RlLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICByZXR1cm4gZHJhdyhub2RlLCBvcHRpb25zKS50aGVuKGNhbnZhcyA9PiBjYW52YXMudG9EYXRhVVJMKCdpbWFnZS9qcGVnJywgb3B0aW9ucy5xdWFsaXR5IHx8IDEuMCkpO1xufVxuXG4vKipcbiAqIEBwYXJhbSB7Tm9kZX0gbm9kZSAtIFRoZSBET00gTm9kZSBvYmplY3QgdG8gcmVuZGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIFJlbmRlcmluZyBvcHRpb25zLCBAc2VlIHtAbGluayB0b1N2Z31cbiAqIEByZXR1cm4ge1Byb21pc2V9IC0gQSBwcm9taXNlIHRoYXQgaXMgZnVsZmlsbGVkIHdpdGggYSBQTkcgaW1hZ2UgYmxvYlxuICogKi9cbmZ1bmN0aW9uIHRvQmxvYihub2RlLCBvcHRpb25zKSB7XG4gIHJldHVybiBkcmF3KG5vZGUsIG9wdGlvbnMgfHwge30pLnRoZW4oY2FudmFzVG9CbG9iKTtcbn1cblxuZnVuY3Rpb24gY29weU9wdGlvbnMob3B0aW9ucykge1xuICAvLyBDb3B5IG9wdGlvbnMgdG8gaW1wbCBvcHRpb25zIGZvciB1c2UgaW4gaW1wbFxuICBpZiAodHlwZW9mIG9wdGlvbnMuaW1hZ2VQbGFjZWhvbGRlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBkb210b2ltYWdlLmltcGwub3B0aW9ucy5pbWFnZVBsYWNlaG9sZGVyID1cbiAgICAgIGRlZmF1bHRPcHRpb25zLmltYWdlUGxhY2Vob2xkZXI7XG4gIH0gZWxzZSB7XG4gICAgZG9tdG9pbWFnZS5pbXBsLm9wdGlvbnMuaW1hZ2VQbGFjZWhvbGRlciA9IG9wdGlvbnMuaW1hZ2VQbGFjZWhvbGRlcjtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5jYWNoZUJ1c3QgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgZG9tdG9pbWFnZS5pbXBsLm9wdGlvbnMuY2FjaGVCdXN0ID0gZGVmYXVsdE9wdGlvbnMuY2FjaGVCdXN0O1xuICB9IGVsc2Uge1xuICAgIGRvbXRvaW1hZ2UuaW1wbC5vcHRpb25zLmNhY2hlQnVzdCA9IG9wdGlvbnMuY2FjaGVCdXN0O1xuICB9XG59XG5cbmZ1bmN0aW9uIGRyYXcoZG9tTm9kZSwgb3B0aW9ucykge1xuICByZXR1cm4gdG9TdmcoZG9tTm9kZSwgb3B0aW9ucylcbiAgICAudGhlbihtYWtlSW1hZ2UpXG4gICAgLnRoZW4oZGVsYXkoMTAwKSlcbiAgICAudGhlbihpbWFnZSA9PiB7XG4gICAgICBjb25zdCBjYW52YXMgPSBuZXdDYW52YXMoZG9tTm9kZSk7XG4gICAgICBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKS5kcmF3SW1hZ2UoaW1hZ2UsIDAsIDApO1xuICAgICAgcmV0dXJuIGNhbnZhcztcbiAgICB9KTtcblxuICBmdW5jdGlvbiBuZXdDYW52YXMoZE5vZGUpIHtcbiAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBjYW52YXMud2lkdGggPSBvcHRpb25zLndpZHRoIHx8IGdldFdpZHRoKGROb2RlKTtcbiAgICBjYW52YXMuaGVpZ2h0ID0gb3B0aW9ucy5oZWlnaHQgfHwgZ2V0SGVpZ2h0KGROb2RlKTtcblxuICAgIGlmIChvcHRpb25zLmJnY29sb3IpIHtcbiAgICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgY3R4LmZpbGxTdHlsZSA9IG9wdGlvbnMuYmdjb2xvcjtcbiAgICAgIGN0eC5maWxsUmVjdCgwLCAwLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpO1xuICAgIH1cblxuICAgIHJldHVybiBjYW52YXM7XG4gIH1cbn1cblxuZnVuY3Rpb24gY2xvbmVOb2RlKG5vZGUsIGZpbHRlciwgcm9vdCkge1xuICBpZiAoIXJvb3QgJiYgZmlsdGVyICYmICFmaWx0ZXIobm9kZSkpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5vZGUpXG4gICAgLnRoZW4obWFrZU5vZGVDb3B5KVxuICAgIC50aGVuKGNsb25lID0+IGNsb25lQ2hpbGRyZW4obm9kZSwgY2xvbmUsIGZpbHRlcikpXG4gICAgLnRoZW4oY2xvbmUgPT4gcHJvY2Vzc0Nsb25lKG5vZGUsIGNsb25lKSk7XG5cbiAgZnVuY3Rpb24gbWFrZU5vZGVDb3B5KG5kKSB7XG4gICAgaWYgKG5kIGluc3RhbmNlb2Ygd2luZG93LkhUTUxDYW52YXNFbGVtZW50KSB7XG4gICAgICByZXR1cm4gbWFrZUltYWdlKG5kLnRvRGF0YVVSTCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5kLmNsb25lTm9kZShmYWxzZSk7XG4gIH1cblxuICBmdW5jdGlvbiBjbG9uZUNoaWxkcmVuSW5PcmRlcihwYXJlbnQsIGFyckNoaWxkcmVuLCBmbHQpIHtcbiAgICBsZXQgZG9uZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGFyckNoaWxkcmVu