docx4js-fork
Version:
javascript docx parser
341 lines (298 loc) • 31.2 kB
JavaScript
;
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