UNPKG

docx4js-fork

Version:
341 lines (298 loc) 31.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _jszip = require("jszip"); var _jszip2 = _interopRequireDefault(_jszip); var _cheerio = require("cheerio"); var _cheerio2 = _interopRequireDefault(_cheerio); require("./cheerio-fn"); var _htmlparser = require("htmlparser2"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var normalize = function normalize(path) { return path.split("/").filter(function (a) { return a != "."; }).reduceRight(function (n, a) { if (a == "..") { n.r++; } else if (n.r) { n.r--; } else { n.trimed.unshift(a); } return n; }, { trimed: [], r: 0 }).trimed.join("/"); }; /** * document parser * * @example * Document.load(file) * .then(doc=>doc.parse()) */ var ZipDocument = function () { function ZipDocument(parts, raw, props) { _classCallCheck(this, ZipDocument); this.parts = parts; this.raw = raw; this.props = props; this._shouldReleased = new Map(); } _createClass(ZipDocument, [{ key: "normalizePath", value: function normalizePath() { return normalize.apply(undefined, arguments); } }, { key: "getPart", value: function getPart(name) { name = normalize(name); return this.parts[name]; } }, { key: "getDataPart", value: function getDataPart(name) { name = normalize(name); var part = this.parts[name]; var crc32 = part._data.crc32; var data = part.asUint8Array(); //unsafe call, part._data is changed data.crc32 = part._data.crc32 = crc32; //so keep crc32 on part._data for future return data; } }, { key: "getDataPartAsUrl", value: function getDataPartAsUrl(name) { var type = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "*/*"; name = normalize(name); var part = this.parts[name]; var crc32 = part._data.crc32; if (!this._shouldReleased.has(crc32)) { this._shouldReleased.set(crc32, URL.createObjectURL(new Blob([this.getDataPart(name)], { type: type }))); } return this._shouldReleased.get(crc32); } }, { key: "getPartCrc32", value: function getPartCrc32(name) { name = normalize(name); var part = this.parts[name]; var crc32 = part._data.crc32; return crc32; } }, { key: "release", value: function release() { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this._shouldReleased[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var _step$value = _slicedToArray(_step.value, 2), url = _step$value[1]; URL.revokeObjectURL(url); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } }, { key: "getObjectPart", value: function getObjectPart(name) { name = normalize(name); var part = this.parts[name]; if (!part) return null;else if (part.cheerio) return part;else { var $ = Object.assign(this.parts[name] = this.constructor.parseXml(part.asText()), { part: name }); Object.assign($.root()[0].attribs, { part: name }); $.prototype.part = function () { return name; }; return $; } } }, { key: "$", value: function $(node) { var root = function root(a) { return a.root || a.parent && root(a.parent); }; return this.getObjectPart(root(node).attribs.part)(node); } }, { key: "parse", value: function parse(domHandler) {} }, { key: "render", value: function render() {} }, { key: "serialize", value: function serialize() { var _this = this; var newDoc = new _jszip2.default(); Object.keys(this.parts).forEach(function (path) { var part = _this.parts[path]; if (part.cheerio) { newDoc.file(path, part.xml()); } else { newDoc.file(path, part._data, part.options); } }); return newDoc; } }, { key: "save", value: function save(file, options) { file = file || this.props.name || Date.now() + ".docx"; var newDoc = this.serialize(); if (typeof document != "undefined" && window.URL && window.URL.createObjectURL) { var data = newDoc.generate(_extends({}, options, { type: "blob", mimeType: this.constructor.mime })); var url = window.URL.createObjectURL(data); var link = document.createElement("a"); document.body.appendChild(link); link.download = file; link.href = url; link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); } else { var _ret = function () { var data = newDoc.generate(_extends({}, options, { type: "nodebuffer" })); return { v: new Promise(function (resolve, reject) { return require("f" + "s").writeFile(file, data, function (error) { error ? reject(error) : resolve(data); }); }) }; }(); if ((typeof _ret === "undefined" ? "undefined" : _typeof(_ret)) === "object") return _ret.v; } } }, { key: "clone", value: function clone() { var _this2 = this; var zip = new _jszip2.default(); var props = props ? JSON.parse(JSON.stringify(this.props)) : props; var parts = Object.keys(this.parts).reduce(function (state, k) { var v = _this2.parts[k]; if (v.cheerio) { zip.file(v.name, v.xml(), v.options); state[k] = zip.file(v.name); } else { zip.file(v.name, v._data, v.options); state[k] = zip.file(v.name); } return state; }, {}); return new this.constructor(parts, zip, props); } /** * a helper to load document file * @param inputFile {File} - a html input file, or nodejs file * @return {Promise} */ }], [{ key: "load", value: function load(inputFile) { var DocumentSelf = this; if (inputFile instanceof ZipDocument) return Promise.resolve(inputFile); return new Promise(function (resolve, reject) { function parse(data) { var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; try { (function () { var raw = new _jszip2.default(data), parts = {}; raw.filter(function (path, file) { return parts[path] = file; }); resolve(new DocumentSelf(parts, raw, props)); })(); } catch (error) { reject(error); } } if (typeof inputFile == 'string') { //file name require('fs').readFile(inputFile, function (error, data) { if (error) reject(error);else if (data) { parse(data, { name: inputFile.split(/[\/\\]/).pop().replace(/\.docx$/i, '') }); } }); } else if (inputFile instanceof Blob) { var reader = new FileReader(); reader.onload = function (e) { parse(e.target.result, inputFile.name ? { name: inputFile.name.replace(/\.docx$/i, ''), lastModified: inputFile.lastModified, size: inputFile.size } : { size: inputFile.size }); }; reader.readAsArrayBuffer(inputFile); } else { parse(inputFile); } }); } }, { key: "create", value: function create() { return this.load(__dirname + "/../templates/blank." + this.ext); } }, { key: "parseXml", value: function parseXml(data) { try { var opt = { xmlMode: true, decodeEntities: false }; var handler = new ContentDomHandler(opt); new _htmlparser.Parser(handler, opt).end(data); var parsed = _cheerio2.default.load(handler.dom, opt); if (typeof parsed.cheerio == "undefined") parsed.cheerio = "customized"; return parsed; } catch (error) { console.error(error); return null; } } }]); return ZipDocument; }(); ZipDocument.ext = "unknown"; ZipDocument.mime = "application/zip"; exports.default = ZipDocument; var ContentDomHandler = function (_DomHandler) { _inherits(ContentDomHandler, _DomHandler); function ContentDomHandler() { _classCallCheck(this, ContentDomHandler); return _possibleConstructorReturn(this, (ContentDomHandler.__proto__ || Object.getPrototypeOf(ContentDomHandler)).apply(this, arguments)); } _createClass(ContentDomHandler, [{ key: "_addDomElement", value: function _addDomElement(el) { if (el.type == "text" && (el.data[0] == '\r' || el.data[0] == '\n')) ; //remove format whitespaces else return _get(ContentDomHandler.prototype.__proto__ || Object.getPrototypeOf(ContentDomHandler.prototype), "_addDomElement", this).call(this, el); } }]); return ContentDomHandler; }(_htmlparser.DomHandler); module.exports = exports['default']; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kb2N1bWVudC5qcyJdLCJuYW1lcyI6WyJub3JtYWxpemUiLCJwYXRoIiwic3BsaXQiLCJmaWx0ZXIiLCJhIiwicmVkdWNlUmlnaHQiLCJuIiwiciIsInRyaW1lZCIsInVuc2hpZnQiLCJqb2luIiwiWmlwRG9jdW1lbnQiLCJwYXJ0cyIsInJhdyIsInByb3BzIiwiX3Nob3VsZFJlbGVhc2VkIiwiTWFwIiwiYXJndW1lbnRzIiwibmFtZSIsInBhcnQiLCJjcmMzMiIsIl9kYXRhIiwiZGF0YSIsImFzVWludDhBcnJheSIsInR5cGUiLCJoYXMiLCJzZXQiLCJVUkwiLCJjcmVhdGVPYmplY3RVUkwiLCJCbG9iIiwiZ2V0RGF0YVBhcnQiLCJnZXQiLCJ1cmwiLCJyZXZva2VPYmplY3RVUkwiLCJjaGVlcmlvIiwiJCIsIk9iamVjdCIsImFzc2lnbiIsImNvbnN0cnVjdG9yIiwicGFyc2VYbWwiLCJhc1RleHQiLCJyb290IiwiYXR0cmlicyIsInByb3RvdHlwZSIsIm5vZGUiLCJwYXJlbnQiLCJnZXRPYmplY3RQYXJ0IiwiZG9tSGFuZGxlciIsIm5ld0RvYyIsImtleXMiLCJmb3JFYWNoIiwiZmlsZSIsInhtbCIsIm9wdGlvbnMiLCJEYXRlIiwibm93Iiwic2VyaWFsaXplIiwiZG9jdW1lbnQiLCJ3aW5kb3ciLCJnZW5lcmF0ZSIsIm1pbWVUeXBlIiwibWltZSIsImxpbmsiLCJjcmVhdGVFbGVtZW50IiwiYm9keSIsImFwcGVuZENoaWxkIiwiZG93bmxvYWQiLCJocmVmIiwiY2xpY2siLCJyZW1vdmVDaGlsZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwicmVxdWlyZSIsIndyaXRlRmlsZSIsImVycm9yIiwiemlwIiwiSlNPTiIsInBhcnNlIiwic3RyaW5naWZ5IiwicmVkdWNlIiwic3RhdGUiLCJrIiwidiIsImlucHV0RmlsZSIsIkRvY3VtZW50U2VsZiIsInJlYWRGaWxlIiwicG9wIiwicmVwbGFjZSIsInJlYWRlciIsIkZpbGVSZWFkZXIiLCJvbmxvYWQiLCJlIiwidGFyZ2V0IiwicmVzdWx0IiwibGFzdE1vZGlmaWVkIiwic2l6ZSIsInJlYWRBc0FycmF5QnVmZmVyIiwibG9hZCIsIl9fZGlybmFtZSIsImV4dCIsIm9wdCIsInhtbE1vZGUiLCJkZWNvZGVFbnRpdGllcyIsImhhbmRsZXIiLCJDb250ZW50RG9tSGFuZGxlciIsImVuZCIsInBhcnNlZCIsImRvbSIsImNvbnNvbGUiLCJlbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOzs7O0FBQ0E7Ozs7QUFDQTs7QUFDQTs7Ozs7Ozs7OztBQUVBLElBQU1BLFlBQVUsU0FBVkEsU0FBVTtBQUFBLFFBQU1DLEtBQUtDLEtBQUwsQ0FBVyxHQUFYLEVBQWdCQyxNQUFoQixDQUF1QjtBQUFBLFNBQUdDLEtBQUcsR0FBTjtBQUFBLEVBQXZCLEVBQ3BCQyxXQURvQixDQUNSLFVBQUNDLENBQUQsRUFBR0YsQ0FBSCxFQUFPO0FBQ25CLE1BQUdBLEtBQUcsSUFBTixFQUFXO0FBQ1ZFLEtBQUVDLENBQUY7QUFDQSxHQUZELE1BRU0sSUFBR0QsRUFBRUMsQ0FBTCxFQUFPO0FBQ1pELEtBQUVDLENBQUY7QUFDQSxHQUZLLE1BRUQ7QUFDSkQsS0FBRUUsTUFBRixDQUFTQyxPQUFULENBQWlCTCxDQUFqQjtBQUNBO0FBQ0QsU0FBT0UsQ0FBUDtBQUNBLEVBVm9CLEVBVW5CLEVBQUNFLFFBQU8sRUFBUixFQUFXRCxHQUFFLENBQWIsRUFWbUIsRUFVRkMsTUFWRSxDQVVLRSxJQVZMLENBVVUsR0FWVixDQUFOO0FBQUEsQ0FBaEI7QUFXQTs7Ozs7Ozs7SUFPcUJDLFc7QUFJcEIsc0JBQVlDLEtBQVosRUFBa0JDLEdBQWxCLEVBQXNCQyxLQUF0QixFQUE0QjtBQUFBOztBQUMzQixPQUFLRixLQUFMLEdBQVdBLEtBQVg7QUFDQSxPQUFLQyxHQUFMLEdBQVNBLEdBQVQ7QUFDQSxPQUFLQyxLQUFMLEdBQVdBLEtBQVg7QUFDQSxPQUFLQyxlQUFMLEdBQXFCLElBQUlDLEdBQUosRUFBckI7QUFDQTs7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LEVBQWNDLGdCQUFnQixLQUE5QixFQUFSO0FBQ0EsUUFBSUMsVUFBUSxJQUFJQyxpQkFBSixDQUFzQkosR0FBdEIsQ0FBWjtBQUNBLDJCQUFXRyxPQUFYLEVBQW1CSCxHQUFuQixFQUF3QkssR0FBeEIsQ0FBNEJwRixJQUE1QjtBQUNBLFFBQUlxRixTQUFPLGtCQUFNVCxJQUFOLENBQVdNLFFBQVFJLEdBQW5CLEVBQXVCUCxHQUF2QixDQUFYO0FBQ0EsUUFBRyxPQUFPTSxPQUFPekUsT0FBZCxJQUF3QixXQUEzQixFQUNDeUUsT0FBT3pFLE9BQVAsR0FBZSxZQUFmO0FBQ0QsV0FBT3lFLE1BQVA7QUFDQSxJQVJELENBUUMsT0FBTWhDLEtBQU4sRUFBWTtBQUNaa0MsWUFBUWxDLEtBQVIsQ0FBY0EsS0FBZDtBQUNBLFdBQU8sSUFBUDtBQUNBO0FBQ0Q7Ozs7OztBQXhNbUJoRSxXLENBQ2J5RixHLEdBQUksUztBQURTekYsVyxDQUVia0QsSSxHQUFLLGlCO2tCQUZRbEQsVzs7SUEyTWY4RixpQjs7Ozs7Ozs7Ozs7aUNBQ1VLLEUsRUFBRztBQUNqQixPQUFHQSxHQUFHdEYsSUFBSCxJQUFTLE1BQVQsS0FBb0JzRixHQUFHeEYsSUFBSCxDQUFRLENBQVIsS0FBWSxJQUFaLElBQW9Cd0YsR0FBR3hGLElBQUgsQ0FBUSxDQUFSLEtBQVksSUFBcEQsQ0FBSCxFQUNDLENBREQsQ0FDRTtBQURGLFFBR0MsNElBQTRCd0YsRUFBNUI7QUFDRCIsImZpbGUiOiJkb2N1bWVudC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBKU1ppcCBmcm9tICdqc3ppcCdcclxuaW1wb3J0IGNoZWVyIGZyb20gXCJjaGVlcmlvXCJcclxuaW1wb3J0IFwiLi9jaGVlcmlvLWZuXCJcclxuaW1wb3J0IHtQYXJzZXIsIERvbUhhbmRsZXJ9IGZyb20gXCJodG1scGFyc2VyMlwiXHJcblxyXG5jb25zdCBub3JtYWxpemU9cGF0aD0+cGF0aC5zcGxpdChcIi9cIikuZmlsdGVyKGE9PmEhPVwiLlwiKVxyXG5cdC5yZWR1Y2VSaWdodCgobixhKT0+e1xyXG5cdFx0aWYoYT09XCIuLlwiKXtcclxuXHRcdFx0bi5yKytcclxuXHRcdH1lbHNlIGlmKG4ucil7XHJcblx0XHRcdG4uci0tXHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0bi50cmltZWQudW5zaGlmdChhKVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIG5cclxuXHR9LHt0cmltZWQ6W10scjowfSkudHJpbWVkLmpvaW4oXCIvXCIpXHJcbi8qKlxyXG4gKiAgZG9jdW1lbnQgcGFyc2VyXHJcbiAqXHJcbiAqICBAZXhhbXBsZVxyXG4gKiAgRG9jdW1lbnQubG9hZChmaWxlKVxyXG4gKiAgXHQudGhlbihkb2M9PmRvYy5wYXJzZSgpKVxyXG4gKi9cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgWmlwRG9jdW1lbnR7XHJcblx0c3RhdGljIGV4dD1cInVua25vd25cIlxyXG5cdHN0YXRpYyBtaW1lPVwiYXBwbGljYXRpb24vemlwXCJcclxuXHJcblx0Y29uc3RydWN0b3IocGFydHMscmF3LHByb3BzKXtcclxuXHRcdHRoaXMucGFydHM9cGFydHNcclxuXHRcdHRoaXMucmF3PXJhd1xyXG5cdFx0dGhpcy5wcm9wcz1wcm9wc1xyXG5cdFx0dGhpcy5fc2hvdWxkUmVsZWFzZWQ9bmV3IE1hcCgpXHJcblx0fVxyXG5cclxuXHRub3JtYWxpemVQYXRoKCl7XHJcblx0XHRyZXR1cm4gbm9ybWFsaXplKC4uLmFyZ3VtZW50cylcclxuXHR9XHJcblxyXG5cdGdldFBhcnQobmFtZSl7XHJcblx0XHRuYW1lPW5vcm1hbGl6ZShuYW1lKVxyXG5cdFx0cmV0dXJuIHRoaXMucGFydHNbbmFtZV1cclxuXHR9XHJcblxyXG5cdGdldERhdGFQYXJ0KG5hbWUpe1xyXG5cdFx0bmFtZT1ub3JtYWxpemUobmFtZSlcclxuXHRcdGxldCBwYXJ0PXRoaXMucGFydHNbbmFtZV1cclxuXHRcdGxldCBjcmMzMj1wYXJ0Ll9kYXRhLmNyYzMyXHJcblx0XHRsZXQgZGF0YT1wYXJ0LmFzVWludDhBcnJheSgpLy91bnNhZmUgY2FsbCwgcGFydC5fZGF0YSBpcyBjaGFuZ2VkXHJcblx0XHRkYXRhLmNyYzMyPXBhcnQuX2RhdGEuY3JjMzI9Y3JjMzIvL3NvIGtlZXAgY3JjMzIgb24gcGFydC5fZGF0YSBmb3IgZnV0dXJlXHJcblx0XHRyZXR1cm4gZGF0YVxyXG5cdH1cclxuXHJcblx0Z2V0RGF0YVBhcnRBc1VybChuYW1lLHR5cGU9XCIqLypcIil7XHJcblx0XHRuYW1lPW5vcm1hbGl6ZShuYW1lKVxyXG5cdFx0bGV0IHBhcnQ9dGhpcy5wYXJ0c1tuYW1lXVxyXG5cdFx0bGV0IGNyYzMyPXBhcnQuX2RhdGEuY3JjMzJcclxuXHRcdGlmKCF0aGlzLl9zaG91bGRSZWxlYXNlZC5oYXMoY3JjMzIpKXtcclxuXHRcdFx0dGhpcy5fc2hvdWxkUmVsZWFzZWQuc2V0KGNyYzMyLFVSTC5jcmVhdGVPYmplY3RVUkwobmV3IEJsb2IoW3RoaXMuZ2V0RGF0YVBhcnQobmFtZSldLHt0eXBlfSkpKVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHRoaXMuX3Nob3VsZFJlbGVhc2VkLmdldChjcmMzMilcclxuXHR9XHJcblxyXG5cdGdldFBhcnRDcmMzMihuYW1lKXtcclxuXHRcdG5hbWU9bm9ybWFsaXplKG5hbWUpXHJcblx0XHRsZXQgcGFydD10aGlzLnBhcnRzW25hbWVdXHJcblx0XHRsZXQgY3JjMzI9cGFydC5fZGF0YS5jcmMzMlxyXG5cdFx0cmV0dXJuIGNyYzMyXHJcblx0fVxyXG5cclxuXHRyZWxlYXNlKCl7XHJcblx0XHRmb3IobGV0IFssIHVybF0gb2YgdGhpcy5fc2hvdWxkUmVsZWFzZWQpe1xyXG5cdFx0XHRVUkwucmV2b2tlT2JqZWN0VVJMKHVybClcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGdldE9iamVjdFBhcnQobmFtZSl7XHJcblx0XHRuYW1lPW5vcm1hbGl6ZShuYW1lKVxyXG5cdFx0Y29uc3QgcGFydD10aGlzLnBhcnRzW25hbWVdXHJcblx0XHRpZighcGFydClcclxuXHRcdFx0cmV0dXJuIG51bGxcclxuXHRcdGVsc2UgaWYocGFydC5jaGVlcmlvKVxyXG5cdFx0XHRyZXR1cm4gcGFydFxyXG5cdFx0ZWxzZXtcclxuXHRcdFx0Y29uc3QgJD1PYmplY3QuYXNzaWduKHRoaXMucGFydHNbbmFtZV09dGhpcy5jb25zdHJ1Y3Rvci5wYXJzZVhtbChwYXJ0LmFzVGV4dCgpKSx7cGFydDpuYW1lfSlcclxuXHRcdFx0T2JqZWN0LmFzc2lnbigkLnJvb3QoKVswXS5hdHRyaWJzLHtwYXJ0Om5hbWV9KVxyXG5cdFx0XHQkLnByb3RvdHlwZS5wYXJ0PSgpPT5uYW1lXHJcblx0XHRcdHJldHVybiAkXHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQkKG5vZGUpe1xyXG4gICAgICAgIGNvbnN0IHJvb3Q9YT0+YS5yb290IHx8IChhLnBhcmVudCAmJiByb290KGEucGFyZW50KSlcclxuXHRcdHJldHVybiB0aGlzLmdldE9iamVjdFBhcnQocm9vdChub2RlKS5hdHRyaWJzLnBhcnQpKG5vZGUpXHJcbiAgICB9XHJcblxyXG5cdHBhcnNlKGRvbUhhbmRsZXIpe1xyXG5cclxuXHR9XHJcblxyXG5cdHJlbmRlcigpe1xyXG5cclxuXHR9XHJcblxyXG5cdHNlcmlhbGl6ZSgpe1xyXG5cdFx0bGV0IG5ld0RvYz1uZXcgSlNaaXAoKVxyXG5cdFx0T2JqZWN0LmtleXModGhpcy5wYXJ0cykuZm9yRWFjaChwYXRoPT57XHJcblx0XHRcdGxldCBwYXJ0PXRoaXMucGFydHNbcGF0aF1cclxuXHRcdFx0aWYocGFydC5jaGVlcmlvKXtcclxuXHRcdFx0XHRuZXdEb2MuZmlsZShwYXRoLHBhcnQueG1sKCkpXHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdG5ld0RvYy5maWxlKHBhdGgscGFydC5fZGF0YSwgcGFydC5vcHRpb25zKVxyXG5cdFx0XHR9XHJcblx0XHR9KVxyXG5cdFx0cmV0dXJuIG5ld0RvY1xyXG5cdH1cclxuXHJcblx0c2F2ZShmaWxlLG9wdGlvbnMpe1xyXG5cdFx0ZmlsZT1maWxlfHx0aGlzLnByb3BzLm5hbWV8fGAke0RhdGUubm93KCl9LmRvY3hgXHJcblxyXG5cdFx0bGV0IG5ld0RvYz10aGlzLnNlcmlhbGl6ZSgpXHJcblxyXG5cdFx0aWYodHlwZW9mKGRvY3VtZW50KSE9XCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cuVVJMICYmIHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKXtcclxuXHRcdFx0bGV0IGRhdGE9bmV3RG9jLmdlbmVyYXRlKHsuLi5vcHRpb25zLHR5cGU6XCJibG9iXCIsbWltZVR5cGU6dGhpcy5jb25zdHJ1Y3Rvci5taW1lfSlcclxuXHRcdFx0bGV0IHVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKGRhdGEpXHJcblx0XHRcdGxldCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImFcIik7XHJcblx0XHRcdGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluaylcclxuXHRcdFx0bGluay5kb3dubG9hZCA9IGZpbGVcclxuXHRcdFx0bGluay5ocmVmID0gdXJsO1xyXG5cdFx0XHRsaW5rLmNsaWNrKClcclxuXHRcdFx0ZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChsaW5rKVxyXG5cdFx0XHR3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpXHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0bGV0IGRhdGE9bmV3RG9jLmdlbmVyYXRlKHsuLi5vcHRpb25zLHR5cGU6XCJub2RlYnVmZmVyXCJ9KVxyXG5cdFx0XHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUscmVqZWN0KT0+XHJcblx0XHRcdFx0cmVxdWlyZShcImZcIitcInNcIikud3JpdGVGaWxlKGZpbGUsZGF0YSxlcnJvcj0+e1xyXG5cdFx0XHRcdFx0ZXJyb3IgPyByZWplY3QoZXJyb3IpIDogcmVzb2x2ZShkYXRhKVxyXG5cdFx0XHRcdH0pXHJcblx0XHRcdClcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGNsb25lKCl7XHJcblx0XHRsZXQgemlwPW5ldyBKU1ppcCgpXHJcblx0XHRsZXQgcHJvcHM9IHByb3BzID8gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLnByb3BzKSkgOiBwcm9wc1xyXG5cdFx0bGV0IHBhcnRzPU9iamVjdC5rZXlzKHRoaXMucGFydHMpLnJlZHVjZSgoc3RhdGUsIGspPT57XHJcblx0XHRcdGxldCB2PXRoaXMucGFydHNba11cclxuXHRcdFx0aWYodi5jaGVlcmlvKXtcclxuXHRcdFx0XHR6aXAuZmlsZSh2Lm5hbWUsdi54bWwoKSx2Lm9wdGlvbnMpXHJcblx0XHRcdFx0c3RhdGVba109emlwLmZpbGUodi5uYW1lKVxyXG5cdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHR6aXAuZmlsZSh2Lm5hbWUsdi5fZGF0YSx2Lm9wdGlvbnMpXHJcblx0XHRcdFx0c3RhdGVba109emlwLmZpbGUodi5uYW1lKVxyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBzdGF0ZVxyXG5cdFx0fSx7fSlcclxuXHRcdHJldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3RvcihwYXJ0cyx6aXAsIHByb3BzKVxyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogIGEgaGVscGVyIHRvIGxvYWQgZG9jdW1lbnQgZmlsZVxyXG5cclxuXHQgKiAgQHBhcmFtIGlucHV0RmlsZSB7RmlsZX0gLSBhIGh0bWwgaW5wdXQgZmlsZSwgb3Igbm9kZWpzIGZpbGVcclxuXHQgKiAgQHJldHVybiB7UHJvbWlzZX1cclxuXHQgKi9cclxuXHJcblx0c3RhdGljIGxvYWQoaW5wdXRGaWxlKXtcclxuXHRcdGNvbnN0IERvY3VtZW50U2VsZj10aGlzXHJcblxyXG5cdFx0aWYoaW5wdXRGaWxlIGluc3RhbmNlb2YgWmlwRG9jdW1lbnQpXHJcblx0XHRcdHJldHVybiBQcm9taXNlLnJlc29sdmUoaW5wdXRGaWxlKVxyXG5cclxuXHRcdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KT0+e1xyXG5cdFx0XHRmdW5jdGlvbiBwYXJzZShkYXRhLCBwcm9wcz17fSl7XHJcblx0XHRcdFx0dHJ5e1xyXG5cdFx0XHRcdFx0bGV0IHJhdz1uZXcgSlNaaXAoZGF0YSkscGFydHM9e31cclxuXHRcdFx0XHRcdHJhdy5maWx0ZXIoKHBhdGgsZmlsZSk9PnBhcnRzW3BhdGhdPWZpbGUpXHJcblx0XHRcdFx0XHRyZXNvbHZlKG5ldyBEb2N1bWVudFNlbGYocGFydHMscmF3LHByb3BzKSlcclxuXHRcdFx0XHR9Y2F0Y2goZXJyb3Ipe1xyXG5cdFx0XHRcdFx0cmVqZWN0KGVycm9yKVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYodHlwZW9mIGlucHV0RmlsZT09J3N0cmluZycpey8vZmlsZSBuYW1lXHJcblx0XHRcdFx0cmVxdWlyZSgnZnMnKS5yZWFkRmlsZShpbnB1dEZpbGUsZnVuY3Rpb24oZXJyb3IsIGRhdGEpe1xyXG5cdFx0XHRcdFx0aWYoZXJyb3IpXHJcblx0XHRcdFx0XHRcdHJlamVjdChlcnJvcik7XHJcblx0XHRcdFx0XHRlbHNlIGlmKGRhdGEpe1xyXG5cdFx0XHRcdFx0XHRwYXJzZShkYXRhLCB7bmFtZTppbnB1dEZpbGUuc3BsaXQoL1tcXC9cXFxcXS8pLnBvcCgpLnJlcGxhY2UoL1xcLmRvY3gkL2ksJycpfSlcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9KVxyXG5cdFx0XHR9ZWxzZSBpZihpbnB1dEZpbGUgaW5zdGFuY2VvZiBCbG9iKXtcclxuXHRcdFx0XHR2YXIgcmVhZGVyPW5ldyBGaWxlUmVhZGVyKCk7XHJcblx0XHRcdFx0cmVhZGVyLm9ubG9hZD1mdW5jdGlvbihlKXtcclxuXHRcdFx0XHRcdHBhcnNlKGUudGFyZ2V0LnJlc3VsdCwgKGlucHV0RmlsZS5uYW1lID8ge1xyXG5cdFx0XHRcdFx0XHRcdG5hbWU6aW5wdXRGaWxlLm5hbWUucmVwbGFjZSgvXFwuZG9jeCQvaSwnJyksXHJcblx0XHRcdFx0XHRcdFx0bGFzdE1vZGlmaWVkOmlucHV0RmlsZS5sYXN0TW9kaWZpZWQsXHJcblx0XHRcdFx0XHRcdFx0c2l6ZTppbnB1dEZpbGUuc2l6ZVxyXG5cdFx0XHRcdFx0XHR9IDoge3NpemU6aW5wdXRGaWxlLnNpemV9KSlcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGlucHV0RmlsZSk7XHJcblx0XHRcdH1lbHNlIHtcclxuXHRcdFx0XHRwYXJzZShpbnB1dEZpbGUpXHJcblx0XHRcdH1cclxuXHRcdH0pXHJcblx0fVxyXG5cclxuXHRzdGF0aWMgY3JlYXRlKCl7XHJcblx0XHRyZXR1cm4gdGhpcy5sb2FkKGAke19fZGlybmFtZX0vLi4vdGVtcGxhdGVzL2JsYW5rLiR7dGhpcy5leHR9YClcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBwYXJzZVhtbChkYXRhKXtcclxuXHRcdHRyeXtcclxuXHRcdFx0bGV0IG9wdD17eG1sTW9kZTp0cnVlLGRlY29kZUVudGl0aWVzOiBmYWxzZX1cclxuXHRcdFx0bGV0IGhhbmRsZXI9bmV3IENvbnRlbnREb21IYW5kbGVyKG9wdClcclxuXHRcdFx0bmV3IFBhcnNlcihoYW5kbGVyLG9wdCkuZW5kKGRhdGEpXHJcblx0XHRcdGxldCBwYXJzZWQ9Y2hlZXIubG9hZChoYW5kbGVyLmRvbSxvcHQpXHJcblx0XHRcdGlmKHR5cGVvZihwYXJzZWQuY2hlZXJpbyk9PVwidW5kZWZpbmVkXCIpXHJcblx0XHRcdFx0cGFyc2VkLmNoZWVyaW89XCJjdXN0b21pemVkXCJcclxuXHRcdFx0cmV0dXJuIHBhcnNlZFxyXG5cdFx0fWNhdGNoKGVycm9yKXtcclxuXHRcdFx0Y29uc29sZS5lcnJvcihlcnJvcilcclxuXHRcdFx0cmV0dXJuIG51bGxcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmNsYXNzIENvbnRlbnREb21IYW5kbGVyIGV4dGVuZHMgRG9tSGFuZGxlcntcclxuXHRfYWRkRG9tRWxlbWVudChlbCl7XHJcblx0XHRpZihlbC50eXBlPT1cInRleHRcIiAmJiAoZWwuZGF0YVswXT09J1xccicgfHwgZWwuZGF0YVswXT09J1xcbicpKVxyXG5cdFx0XHQ7Ly9yZW1vdmUgZm9ybWF0IHdoaXRlc3BhY2VzXHJcblx0XHRlbHNlXHJcblx0XHRcdHJldHVybiBzdXBlci5fYWRkRG9tRWxlbWVudChlbClcclxuXHR9XHJcbn1cclxuIl19