docx4js-fork
Version:
javascript docx parser
283 lines (242 loc) • 29 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _ole = require("./ole");
var OLE = _interopRequireWildcard(_ole);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* name: ABSOLUTE path of a part, word.xml, ppt/slides/slide1.xml
* folder:absolute folder, ends with "/" or totally empty ""
* relName:absolute path of a relationship part
*/
var Part = function () {
function Part(name, doc) {
_classCallCheck(this, Part);
this.name = name;
this.doc = doc;
var folder = "";
var relName = "_rels/" + name + ".rels";
var i = name.lastIndexOf('/');
if (i !== -1) {
folder = name.substring(0, i + 1);
relName = folder + "_rels/" + name.substring(i + 1) + ".rels";
}
if (doc.parts[relName]) {
this.folder = folder;
this.relName = relName;
Object.defineProperty(this, "rels", {
get: function get() {
return this.doc.getObjectPart(this.relName);
}
});
}
this._init();
}
_createClass(Part, [{
key: "_init",
value: function _init() {
Object.defineProperty(this, "content", {
configurable: true,
get: function get() {
return this.doc.getObjectPart(this.name);
}
});
}
}, {
key: "normalizePath",
value: function normalizePath() {
var path = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
if (path.startsWith("/")) return path.substr(1);
return this.folder + path;
}
}, {
key: "getRelPart",
value: function getRelPart(id) {
var rel = this.rels("Relationship[Id=\"" + id + "\"]");
var target = rel.attr("Target");
return new Part(this.normalizePath(target), this.doc);
}
}, {
key: "getRelTarget",
value: function getRelTarget(type) {
return this.rels("[Type$=\"" + type + "\"]").attr("Target");
}
}, {
key: "getRelObject",
value: function getRelObject(target) {
return this.doc.getObjectPart(this.normalizePath(target));
}
}, {
key: "getRel",
value: function getRel(id) {
var rel = this.rels("Relationship[Id=\"" + id + "\"]");
var target = rel.attr("Target");
if (rel.attr("TargetMode") === 'External') return { url: target };
switch (rel.attr("Type").split("/").pop()) {
case 'image':
var url = this.doc.getDataPartAsUrl(this.normalizePath(target), "image/*");
var crc32 = this.doc.getPartCrc32(this.normalizePath(target));
return { url: url, crc32: crc32 };
default:
if (target.endsWith(".xml")) return this.getRelObject(target);else return this.doc.getPart(this.normalizePath(target));
}
}
}, {
key: "_nextrId",
value: function _nextrId() {
return Math.max.apply(Math, _toConsumableArray(this.rels('Relationship').toArray().map(function (a) {
return parseInt(a.attribs.Id.substring(3));
}))) + 1;
}
}, {
key: "add",
value: function add(type, target, data) {
var rId = "rId" + this._nextrId();
this.rels("Relationships").append("<Relationship Id=\"" + rId + "\" type=\"" + type + "\" target=\"" + target + "\"/>");
var partName = this.normalizePath(target);
this.doc.raw.file(partName, data);
this.doc.parts[partName] = this.doc.raw.file(partName);
return rId;
}
}, {
key: "addImage",
value: function addImage(data) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { ext: "jpg", mime: "image/jpg" },
ext = _ref.ext,
mime = _ref.mime;
var type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
var id = "rId" + this._nextrId();
var targetName = "media/image" + (Math.max.apply(Math, [0].concat(_toConsumableArray(this.rels("Relationship[Type$='image']").toArray().map(function (t) {
return parseInt(t.attribs.Target.match(/\d+\./) || [0]);
})))) + 1) + "." + ext;
var partName = this.normalizePath(targetName);
this.doc.raw.file(partName, data);
this.doc.parts[partName] = this.doc.raw.file(partName);
this.rels("Relationships").append("<Relationship Id=\"" + id + "\" Type=\"" + type + "\" Target=\"" + targetName + "\"/>");
var DefaultTypes = this.doc.getObjectPart("[Content_Types].xml")("Types");
var extType = DefaultTypes.find(">Default[Extension='" + ext + "']");
if (extType.length == 0) {
DefaultTypes.prepend("<Default Extension=\"" + ext + "\" ContentType=\"" + mime + "\"/>");
}
return id;
}
}, {
key: "addExternalImage",
value: function addExternalImage(url) {
var type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
var id = "rId" + this._nextrId();
this.rels("Relationships").append("<Relationship Id=\"" + id + "\" Type=\"" + type + "\" TargetMode=\"External\" Target=\"" + url + "\"/>");
return id;
}
}, {
key: "addChunk",
value: function addChunk(data, relationshipType, contentType, ext) {
relationshipType = relationshipType || "http://schemas.openxmlformats.org/officeDocument/2006/relationships/aFChunk";
contentType = contentType || this.doc.constructor.mime;
ext = ext || this.doc.constructor.ext;
var id = this._nextrId();
var rId = "rId" + id;
var targetName = "chunk/chunk" + id + "." + ext;
var partName = this.normalizePath(targetName);
this.doc.raw.file(partName, data);
this.doc.parts[partName] = this.doc.raw.file(partName);
this.rels("Relationships").append("<Relationship Id=\"" + rId + "\" Type=\"" + relationshipType + "\" Target=\"" + targetName + "\"/>");
this.doc.contentTypes.append("<Override PartName=\"/" + partName + "\" ContentType=\"" + contentType + "\"/>");
return rId;
}
}, {
key: "getRelOleObject",
value: function getRelOleObject(rid) {
var rel = this.rels("Relationship[Id=" + rid + "]");
var type = rel.attr("Type");
var targetName = rel.attr("Target");
var data = this.doc.getDataPart(this.normalizePath(targetName));
switch (type.split("/").pop()) {
case "oleObject":
try {
return OLE.parse(data);
} catch (error) {
return data;
}
default:
return data;
}
}
}, {
key: "removeRel",
value: function removeRel(id) {
var rel = this.rels("Relationship[Id=\"" + id + "\"]");
if (rel.attr("TargetMode") !== "External") {
var partName = this.normalizePath(rel.attr("Target"));
this.doc.contentTypes.find("[PartName='/" + partName + "']").remove();
this.doc.raw.remove(partName);
delete this.doc.parts[partName];
}
rel.remove();
}
}, {
key: "renderNode",
value: function renderNode(node) {
var createElement = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function (type, props, children) {
type, props, children;
};
var _this = this;
var identify = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function (node) {
return node.name.split(":").pop();
};
var extra = arguments[3];
var tagName = node.name,
children = node.children,
id = node.id,
parent = node.parent;
if (node.type == "text") {
return node.data;
}
var type = tagName;
var props = {};
if (identify) {
var model = identify(node, this);
if (!model) return null;
if (typeof model == "string") {
type = model;
} else {
var content = void 0;
var _model = model;
type = _model.type;
content = _model.children;
props = _objectWithoutProperties(_model, ["type", "children"]);
if (content !== undefined) children = content;
}
}
props.key = id;
props.node = node;
props.type = type;
if (extra) Object.assign(props, extra);
var childElements = children;
if (Array.isArray(children)) {
if (children.length) {
childElements = children.map(function (a) {
return a ? _this.renderNode(a, createElement, identify) : null;
}).filter(function (a) {
return !!a;
});
}
}
return createElement(type, props, childElements);
}
}, {
key: "$",
value: function $(node) {
return this.doc.$(node);
}
}]);
return Part;
}();
exports.default = Part;
module.exports = exports['default'];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcGVueG1sL3BhcnQuanMiXSwibmFtZXMiOlsiT0xFIiwiUGFydCIsIm5hbWUiLCJkb2MiLCJmb2xkZXIiLCJyZWxOYW1lIiwiaSIsImxhc3RJbmRleE9mIiwic3Vic3RyaW5nIiwicGFydHMiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldCIsImdldE9iamVjdFBhcnQiLCJfaW5pdCIsImNvbmZpZ3VyYWJsZSIsInBhdGgiLCJzdGFydHNXaXRoIiwic3Vic3RyIiwiaWQiLCJyZWwiLCJyZWxzIiwidGFyZ2V0IiwiYXR0ciIsIm5vcm1hbGl6ZVBhdGgiLCJ0eXBlIiwidXJsIiwic3BsaXQiLCJwb3AiLCJnZXREYXRhUGFydEFzVXJsIiwiY3JjMzIiLCJnZXRQYXJ0Q3JjMzIiLCJlbmRzV2l0aCIsImdldFJlbE9iamVjdCIsImdldFBhcnQiLCJNYXRoIiwibWF4IiwidG9BcnJheSIsIm1hcCIsInBhcnNlSW50IiwiYSIsImF0dHJpYnMiLCJJZCIsImRhdGEiLCJySWQiLCJfbmV4dHJJZCIsImFwcGVuZCIsInBhcnROYW1lIiwicmF3IiwiZmlsZSIsImV4dCIsIm1pbWUiLCJ0YXJnZXROYW1lIiwidCIsIlRhcmdldCIsIm1hdGNoIiwiRGVmYXVsdFR5cGVzIiwiZXh0VHlwZSIsImZpbmQiLCJsZW5ndGgiLCJwcmVwZW5kIiwicmVsYXRpb25zaGlwVHlwZSIsImNvbnRlbnRUeXBlIiwiY29uc3RydWN0b3IiLCJjb250ZW50VHlwZXMiLCJyaWQiLCJnZXREYXRhUGFydCIsInBhcnNlIiwiZXJyb3IiLCJyZW1vdmUiLCJub2RlIiwiY3JlYXRlRWxlbWVudCIsInByb3BzIiwiY2hpbGRyZW4iLCJpZGVudGlmeSIsImV4dHJhIiwidGFnTmFtZSIsInBhcmVudCIsIm1vZGVsIiwiY29udGVudCIsInVuZGVmaW5lZCIsImtleSIsImFzc2lnbiIsImNoaWxkRWxlbWVudHMiLCJBcnJheSIsImlzQXJyYXkiLCJyZW5kZXJOb2RlIiwiZmlsdGVy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QUlRLGdCQUFjVixRQUFsQjtBQUNBLE9BQUdXLE1BQU1DLE9BQU4sQ0FBY1osUUFBZCxDQUFILEVBQTJCO0FBQzFCLFFBQUdBLFNBQVNkLE1BQVosRUFBbUI7QUFDbEJ3QixxQkFBY1YsU0FBU25DLEdBQVQsQ0FBYTtBQUFBLGFBQUdFLElBQUksTUFBSzhDLFVBQUwsQ0FBZ0I5QyxDQUFoQixFQUFrQitCLGFBQWxCLEVBQWdDRyxRQUFoQyxDQUFKLEdBQWdELElBQW5EO0FBQUEsTUFBYixFQUFzRWEsTUFBdEUsQ0FBNkU7QUFBQSxhQUFHLENBQUMsQ0FBQy9DLENBQUw7QUFBQSxNQUE3RSxDQUFkO0FBQ0E7QUFDRDs7QUFFRCxVQUFPK0IsY0FDTDlDLElBREssRUFFTCtDLEtBRkssRUFHTFcsYUFISyxDQUFQO0FBS0E7OztvQkFFQ2IsSSxFQUFLO0FBQ04sVUFBTyxLQUFLbkUsR0FBTCxDQUFTcUYsQ0FBVCxDQUFXbEIsSUFBWCxDQUFQO0FBQ0E7Ozs7OztrQkEzTm1CckUsSSIsImZpbGUiOiJwYXJ0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgT0xFIGZyb20gXCIuL29sZVwiXHJcblxyXG4vKipcclxuICogbmFtZTogQUJTT0xVVEUgcGF0aCBvZiBhIHBhcnQsIHdvcmQueG1sLCBwcHQvc2xpZGVzL3NsaWRlMS54bWxcclxuICogZm9sZGVyOmFic29sdXRlIGZvbGRlciwgZW5kcyB3aXRoIFwiL1wiIG9yIHRvdGFsbHkgZW1wdHkgXCJcIlxyXG4gKiByZWxOYW1lOmFic29sdXRlIHBhdGggb2YgYSByZWxhdGlvbnNoaXAgcGFydFxyXG4gKi9cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUGFydHtcclxuXHRjb25zdHJ1Y3RvcihuYW1lLGRvYyl7XHJcblx0XHR0aGlzLm5hbWU9bmFtZVxyXG5cdFx0dGhpcy5kb2M9ZG9jXHJcblxyXG5cdFx0bGV0IGZvbGRlcj1cIlwiXHJcblx0XHRsZXQgcmVsTmFtZT1cIl9yZWxzL1wiK25hbWUrXCIucmVsc1wiXHJcblx0XHRsZXQgaT1uYW1lLmxhc3RJbmRleE9mKCcvJylcclxuXHJcblx0XHRpZihpIT09LTEpe1xyXG5cdFx0XHRmb2xkZXI9bmFtZS5zdWJzdHJpbmcoMCxpKzEpXHJcblx0XHRcdHJlbE5hbWU9Zm9sZGVyK1wiX3JlbHMvXCIrbmFtZS5zdWJzdHJpbmcoaSsxKStcIi5yZWxzXCI7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYoZG9jLnBhcnRzW3JlbE5hbWVdKXtcclxuXHRcdFx0dGhpcy5mb2xkZXI9Zm9sZGVyXHJcblx0XHRcdHRoaXMucmVsTmFtZT1yZWxOYW1lXHJcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLFwicmVsc1wiLHtcclxuXHRcdFx0XHRnZXQoKXtcclxuXHRcdFx0XHRcdHJldHVybiB0aGlzLmRvYy5nZXRPYmplY3RQYXJ0KHRoaXMucmVsTmFtZSlcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pXHJcblx0XHR9XHJcblx0XHR0aGlzLl9pbml0KClcclxuXHR9XHJcblxyXG5cdF9pbml0KCl7XHJcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyxcImNvbnRlbnRcIix7XHJcblx0XHRcdGNvbmZpZ3VyYWJsZTp0cnVlLFxyXG5cdFx0XHRnZXQoKXtcclxuXHRcdFx0XHRyZXR1cm4gdGhpcy5kb2MuZ2V0T2JqZWN0UGFydCh0aGlzLm5hbWUpXHJcblx0XHRcdH1cclxuXHRcdH0pXHJcblx0fVxyXG5cclxuXHRub3JtYWxpemVQYXRoKHBhdGg9XCJcIil7XHJcblx0XHRpZihwYXRoLnN0YXJ0c1dpdGgoXCIvXCIpKVxyXG5cdFx0XHRyZXR1cm4gcGF0aC5zdWJzdHIoMSlcclxuXHRcdHJldHVybiB0aGlzLmZvbGRlcitwYXRoXHJcblx0fVxyXG5cclxuXHRnZXRSZWxQYXJ0KGlkKXtcclxuXHRcdHZhciByZWw9dGhpcy5yZWxzKGBSZWxhdGlvbnNoaXBbSWQ9XCIke2lkfVwiXWApXHJcblx0XHR2YXIgdGFyZ2V0PXJlbC5hdHRyKFwiVGFyZ2V0XCIpXHJcblx0XHRyZXR1cm4gbmV3IFBhcnQodGhpcy5ub3JtYWxpemVQYXRoKHRhcmdldCksdGhpcy5kb2MpXHJcblx0fVxyXG5cclxuXHRnZXRSZWxUYXJnZXQodHlwZSl7XHJcblx0XHRyZXR1cm4gdGhpcy5yZWxzKGBbVHlwZSQ9XCIke3R5cGV9XCJdYCkuYXR0cihcIlRhcmdldFwiKVxyXG5cdH1cclxuXHJcblx0Z2V0UmVsT2JqZWN0KHRhcmdldCl7XHJcblx0XHRyZXR1cm4gdGhpcy5kb2MuZ2V0T2JqZWN0UGFydCh0aGlzLm5vcm1hbGl6ZVBhdGgodGFyZ2V0KSlcclxuXHR9XHJcblxyXG5cdGdldFJlbChpZCl7XHJcblx0XHR2YXIgcmVsPXRoaXMucmVscyhgUmVsYXRpb25zaGlwW0lkPVwiJHtpZH1cIl1gKVxyXG5cdFx0dmFyIHRhcmdldD1yZWwuYXR0cihcIlRhcmdldFwiKVxyXG5cdFx0aWYocmVsLmF0dHIoXCJUYXJnZXRNb2RlXCIpPT09J0V4dGVybmFsJylcclxuXHRcdFx0cmV0dXJuIHt1cmw6dGFyZ2V0fVxyXG5cclxuXHRcdHN3aXRjaChyZWwuYXR0cihcIlR5cGVcIikuc3BsaXQoXCIvXCIpLnBvcCgpKXtcclxuXHRcdGNhc2UgJ2ltYWdlJzpcclxuXHRcdFx0bGV0IHVybD10aGlzLmRvYy5nZXREYXRhUGFydEFzVXJsKHRoaXMubm9ybWFsaXplUGF0aCh0YXJnZXQpLCBcImltYWdlLypcIilcclxuXHRcdFx0bGV0IGNyYzMyPXRoaXMuZG9jLmdldFBhcnRDcmMzMih0aGlzLm5vcm1hbGl6ZVBhdGgodGFyZ2V0KSlcclxuXHRcdFx0cmV0dXJuIHt1cmwsY3JjMzJ9XHJcblx0XHRkZWZhdWx0OlxyXG5cdFx0XHRpZih0YXJnZXQuZW5kc1dpdGgoXCIueG1sXCIpKVxyXG5cdFx0XHRcdHJldHVybiB0aGlzLmdldFJlbE9iamVjdCh0YXJnZXQpXHJcblx0XHRcdGVsc2VcclxuXHRcdFx0XHRyZXR1cm4gdGhpcy5kb2MuZ2V0UGFydCh0aGlzLm5vcm1hbGl6ZVBhdGgodGFyZ2V0KSlcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdF9uZXh0cklkKCl7XHJcblx0XHRyZXR1cm4gTWF0aC5tYXgoLi4udGhpcy5yZWxzKCdSZWxhdGlvbnNoaXAnKS50b0FycmF5KCkubWFwKGE9PnBhcnNlSW50KGEuYXR0cmlicy5JZC5zdWJzdHJpbmcoMykpKSkrMVxyXG5cdH1cclxuXHJcblx0YWRkKHR5cGUsdGFyZ2V0LGRhdGEpe1xyXG5cdFx0Y29uc3QgcklkPWBySWQke3RoaXMuX25leHRySWQoKX1gXHJcblx0XHR0aGlzLnJlbHMoXCJSZWxhdGlvbnNoaXBzXCIpXHJcblx0XHRcdC5hcHBlbmQoYDxSZWxhdGlvbnNoaXAgSWQ9XCIke3JJZH1cIiB0eXBlPVwiJHt0eXBlfVwiIHRhcmdldD1cIiR7dGFyZ2V0fVwiLz5gKVxyXG5cdFx0Y29uc3QgcGFydE5hbWU9dGhpcy5ub3JtYWxpemVQYXRoKHRhcmdldClcclxuXHRcdHRoaXMuZG9jLnJhdy5maWxlKHBhcnROYW1lLCBkYXRhKVxyXG5cdFx0dGhpcy5kb2MucGFydHNbcGFydE5hbWVdPXRoaXMuZG9jLnJhdy5maWxlKHBhcnROYW1lKVxyXG5cdFx0cmV0dXJuIHJJZFxyXG5cdH1cclxuXHJcblx0YWRkSW1hZ2UoZGF0YSwge2V4dCxtaW1lfT17ZXh0OlwianBnXCIsbWltZTpcImltYWdlL2pwZ1wifSl7XHJcblx0XHRjb25zdCB0eXBlPVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwcy9pbWFnZVwiXHJcblx0XHRsZXQgaWQ9YHJJZCR7dGhpcy5fbmV4dHJJZCgpfWBcclxuXHJcblx0XHRsZXQgdGFyZ2V0TmFtZT1cIm1lZGlhL2ltYWdlXCIrKE1hdGgubWF4KDAsLi4udGhpcy5yZWxzKFwiUmVsYXRpb25zaGlwW1R5cGUkPSdpbWFnZSddXCIpLnRvQXJyYXkoKS5tYXAodD0+e1xyXG5cdFx0XHRyZXR1cm4gcGFyc2VJbnQodC5hdHRyaWJzLlRhcmdldC5tYXRjaCgvXFxkK1xcLi8pfHxbMF0pXHJcblx0XHR9KSkrMSkrXCIuXCIrZXh0O1xyXG5cclxuXHRcdGxldCBwYXJ0TmFtZT10aGlzLm5vcm1hbGl6ZVBhdGgodGFyZ2V0TmFtZSlcclxuXHRcdHRoaXMuZG9jLnJhdy5maWxlKHBhcnROYW1lLCBkYXRhKVxyXG5cdFx0dGhpcy5kb2MucGFydHNbcGFydE5hbWVdPXRoaXMuZG9jLnJhdy5maWxlKHBhcnROYW1lKVxyXG5cclxuXHRcdHRoaXMucmVscyhcIlJlbGF0aW9uc2hpcHNcIilcclxuXHRcdFx0LmFwcGVuZChgPFJlbGF0aW9uc2hpcCBJZD1cIiR7aWR9XCIgVHlwZT1cIiR7dHlwZX1cIiBUYXJnZXQ9XCIke3RhcmdldE5hbWV9XCIvPmApXHJcblxyXG5cdFx0Y29uc3QgRGVmYXVsdFR5cGVzPXRoaXMuZG9jLmdldE9iamVjdFBhcnQoXCJbQ29udGVudF9UeXBlc10ueG1sXCIpKGBUeXBlc2ApXHJcblx0XHRjb25zdCBleHRUeXBlPURlZmF1bHRUeXBlcy5maW5kKGA+RGVmYXVsdFtFeHRlbnNpb249JyR7ZXh0fSddYClcclxuXHRcdGlmKGV4dFR5cGUubGVuZ3RoPT0wKXtcclxuXHRcdFx0RGVmYXVsdFR5cGVzLnByZXBlbmQoYDxEZWZhdWx0IEV4dGVuc2lvbj1cIiR7ZXh0fVwiIENvbnRlbnRUeXBlPVwiJHttaW1lfVwiLz5gKVxyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGlkXHJcblx0fVxyXG5cclxuXHRhZGRFeHRlcm5hbEltYWdlKHVybCl7XHJcblx0XHRjb25zdCB0eXBlPVwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwcy9pbWFnZVwiXHJcblxyXG5cdFx0bGV0IGlkPWBySWQke3RoaXMuX25leHRySWQoKX1gXHJcblxyXG5cdFx0dGhpcy5yZWxzKFwiUmVsYXRpb25zaGlwc1wiKVxyXG5cdFx0XHQuYXBwZW5kKGA8UmVsYXRpb25zaGlwIElkPVwiJHtpZH1cIiBUeXBlPVwiJHt0eXBlfVwiIFRhcmdldE1vZGU9XCJFeHRlcm5hbFwiIFRhcmdldD1cIiR7dXJsfVwiLz5gKVxyXG5cclxuXHRcdHJldHVybiBpZFxyXG5cdH1cclxuXHJcblx0YWRkQ2h1bmsoZGF0YSwgcmVsYXRpb25zaGlwVHlwZSwgY29udGVudFR5cGUsIGV4dCl7XHJcblx0XHRyZWxhdGlvbnNoaXBUeXBlPXJlbGF0aW9uc2hpcFR5cGV8fFwiaHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL29mZmljZURvY3VtZW50LzIwMDYvcmVsYXRpb25zaGlwcy9hRkNodW5rXCJcclxuXHRcdGNvbnRlbnRUeXBlPWNvbnRlbnRUeXBlfHx0aGlzLmRvYy5jb25zdHJ1Y3Rvci5taW1lXHJcblx0XHRleHQ9ZXh0fHx0aGlzLmRvYy5jb25zdHJ1Y3Rvci5leHRcclxuXHJcblx0XHRsZXQgaWQ9dGhpcy5fbmV4dHJJZCgpXHJcblx0XHRsZXQgcklkPWBySWQke2lkfWBcclxuXHRcdGxldCB0YXJnZXROYW1lPWBjaHVuay9jaHVuayR7aWR9LiR7ZXh0fWBcclxuXHJcblx0XHRsZXQgcGFydE5hbWU9dGhpcy5ub3JtYWxpemVQYXRoKHRhcmdldE5hbWUpXHJcblx0XHR0aGlzLmRvYy5yYXcuZmlsZShwYXJ0TmFtZSwgZGF0YSlcclxuXHRcdHRoaXMuZG9jLnBhcnRzW3BhcnROYW1lXT10aGlzLmRvYy5yYXcuZmlsZShwYXJ0TmFtZSlcclxuXHJcblx0XHR0aGlzLnJlbHMoXCJSZWxhdGlvbnNoaXBzXCIpXHJcblx0XHRcdC5hcHBlbmQoYDxSZWxhdGlvbnNoaXAgSWQ9XCIke3JJZH1cIiBUeXBlPVwiJHtyZWxhdGlvbnNoaXBUeXBlfVwiIFRhcmdldD1cIiR7dGFyZ2V0TmFtZX1cIi8+YClcclxuXHJcblx0XHR0aGlzLmRvYy5jb250ZW50VHlwZXNcclxuXHRcdFx0LmFwcGVuZChgPE92ZXJyaWRlIFBhcnROYW1lPVwiLyR7cGFydE5hbWV9XCIgQ29udGVudFR5cGU9XCIke2NvbnRlbnRUeXBlfVwiLz5gKVxyXG5cclxuXHRcdHJldHVybiBySWRcclxuXHR9XHJcblxyXG5cdGdldFJlbE9sZU9iamVjdChyaWQpe1xyXG5cdFx0bGV0IHJlbD10aGlzLnJlbHMoYFJlbGF0aW9uc2hpcFtJZD0ke3JpZH1dYClcclxuXHRcdGxldCB0eXBlPXJlbC5hdHRyKFwiVHlwZVwiKVxyXG5cdFx0bGV0IHRhcmdldE5hbWU9cmVsLmF0dHIoXCJUYXJnZXRcIilcclxuXHRcdGxldCBkYXRhPXRoaXMuZG9jLmdldERhdGFQYXJ0KHRoaXMubm9ybWFsaXplUGF0aCh0YXJnZXROYW1lKSlcclxuXHRcdHN3aXRjaCh0eXBlLnNwbGl0KFwiL1wiKS5wb3AoKSl7XHJcblx0XHRcdGNhc2UgXCJvbGVPYmplY3RcIjpcclxuXHRcdFx0XHR0cnl7XHJcblx0XHRcdFx0XHRyZXR1cm4gT0xFLnBhcnNlKGRhdGEpXHJcblx0XHRcdFx0fWNhdGNoKGVycm9yKXtcclxuXHRcdFx0XHRcdHJldHVybiBkYXRhXHJcblx0XHRcdFx0fVxyXG5cdFx0XHRkZWZhdWx0OlxyXG5cdFx0XHRcdHJldHVybiBkYXRhXHJcblx0XHR9XHJcblxyXG5cdH1cclxuXHJcblx0cmVtb3ZlUmVsKGlkKXtcclxuXHRcdGxldCByZWw9dGhpcy5yZWxzKGBSZWxhdGlvbnNoaXBbSWQ9XCIke2lkfVwiXWApXHJcblx0XHRpZihyZWwuYXR0cihcIlRhcmdldE1vZGVcIikhPT1cIkV4dGVybmFsXCIpe1xyXG5cdFx0XHRsZXQgcGFydE5hbWU9dGhpcy5ub3JtYWxpemVQYXRoKHJlbC5hdHRyKFwiVGFyZ2V0XCIpKVxyXG5cdFx0XHR0aGlzLmRvYy5jb250ZW50VHlwZXMuZmluZChgW1BhcnROYW1lPScvJHtwYXJ0TmFtZX0nXWApLnJlbW92ZSgpXHJcblx0XHRcdHRoaXMuZG9jLnJhdy5yZW1vdmUocGFydE5hbWUpXHJcblx0XHRcdGRlbGV0ZSB0aGlzLmRvYy5wYXJ0c1twYXJ0TmFtZV1cclxuXHRcdH1cclxuXHRcdHJlbC5yZW1vdmUoKVxyXG5cdH1cclxuXHJcblx0cmVuZGVyTm9kZShub2RlLCBjcmVhdGVFbGVtZW50PSh0eXBlLHByb3BzLGNoaWxkcmVuKT0+e3R5cGUscHJvcHMsY2hpbGRyZW59LGlkZW50aWZ5PW5vZGU9Pm5vZGUubmFtZS5zcGxpdChcIjpcIikucG9wKCksIGV4dHJhKXtcclxuXHRcdGxldCB7bmFtZTp0YWdOYW1lLCBjaGlsZHJlbixpZCwgcGFyZW50fT1ub2RlXHJcblx0XHRpZihub2RlLnR5cGU9PVwidGV4dFwiKXtcclxuXHRcdFx0cmV0dXJuIG5vZGUuZGF0YVxyXG5cdFx0fVxyXG5cclxuXHRcdGxldCB0eXBlPXRhZ05hbWVcclxuXHRcdGxldCBwcm9wcz17fVxyXG5cclxuXHRcdGlmKGlkZW50aWZ5KXtcclxuXHRcdFx0bGV0IG1vZGVsPWlkZW50aWZ5KG5vZGUsdGhpcylcclxuXHRcdFx0aWYoIW1vZGVsKVxyXG5cdFx0XHRcdHJldHVybiBudWxsXHJcblxyXG5cdFx0XHRpZih0eXBlb2YobW9kZWwpPT1cInN0cmluZ1wiKXtcclxuXHRcdFx0XHR0eXBlPW1vZGVsXHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdGxldCBjb250ZW50O1xyXG5cdFx0XHRcdCh7dHlwZSwgY2hpbGRyZW46Y29udGVudCwgLi4ucHJvcHN9PW1vZGVsKTtcclxuXHRcdFx0XHRpZihjb250ZW50IT09dW5kZWZpbmVkKVxyXG5cdFx0XHRcdFx0Y2hpbGRyZW49Y29udGVudFxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRwcm9wcy5rZXk9aWRcclxuXHRcdHByb3BzLm5vZGU9bm9kZVxyXG5cdFx0cHJvcHMudHlwZT10eXBlXHJcblxyXG5cdFx0aWYoZXh0cmEpXHJcblx0XHRcdE9iamVjdC5hc3NpZ24ocHJvcHMsZXh0cmEpXHJcblxyXG5cdFx0bGV0IGNoaWxkRWxlbWVudHM9Y2hpbGRyZW5cclxuXHRcdGlmKEFycmF5LmlzQXJyYXkoY2hpbGRyZW4pKXtcclxuXHRcdFx0aWYoY2hpbGRyZW4ubGVuZ3RoKXtcclxuXHRcdFx0XHRjaGlsZEVsZW1lbnRzPWNoaWxkcmVuLm1hcChhPT5hID8gdGhpcy5yZW5kZXJOb2RlKGEsY3JlYXRlRWxlbWVudCxpZGVudGlmeSkgOiBudWxsKS5maWx0ZXIoYT0+ISFhKVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGNyZWF0ZUVsZW1lbnQoXHJcblx0XHRcdFx0dHlwZSxcclxuXHRcdFx0XHRwcm9wcyxcclxuXHRcdFx0XHRjaGlsZEVsZW1lbnRzXHJcblx0XHRcdClcclxuXHR9XHJcblxyXG5cdCQobm9kZSl7XHJcblx0XHRyZXR1cm4gdGhpcy5kb2MuJChub2RlKVxyXG5cdH1cclxufVxyXG4iXX0=