docx4js-fork
Version:
javascript docx parser
373 lines (335 loc) • 48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _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 _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 _officeDocument = require("../officeDocument");
var _officeDocument2 = _interopRequireDefault(_officeDocument);
var _part = require("../part");
var _part2 = _interopRequireDefault(_part);
var _drawml = require("../drawml");
var _drawml2 = _interopRequireDefault(_drawml);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
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; }
var OfficeDocument = function (_Base) {
_inherits(OfficeDocument, _Base);
function OfficeDocument() {
_classCallCheck(this, OfficeDocument);
return _possibleConstructorReturn(this, (OfficeDocument.__proto__ || Object.getPrototypeOf(OfficeDocument)).apply(this, arguments));
}
_createClass(OfficeDocument, [{
key: "_init",
value: function _init() {
_get(OfficeDocument.prototype.__proto__ || Object.getPrototypeOf(OfficeDocument.prototype), "_init", this).call(this);
this._assignRel("tableStyles,viewProps,presProps".split(","));
}
}, {
key: "render",
value: function render(createElement) {
var identify = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.constructor.identify.bind(this.constructor);
if (this.tableStyles) {
this.renderNode(this.tableStyles.root().children().get(0), createElement, identify);
}
return this.renderNode(this.content("p\\:presentation").get(0), createElement, identify);
}
}, {
key: "slide",
value: function slide(_ref) {
var id = _ref.id,
rid = _ref["r:id"];
return this.getRel(rid);
}
}, {
key: "master",
value: function master(_ref2) {
var id = _ref2.id,
rid = _ref2["r:id"];
return this.slide.apply(this, arguments);
}
}, {
key: "notesMaster",
value: function notesMaster() {
return this.slide.apply(this, arguments);
}
}, {
key: "handoutMaster",
value: function handoutMaster() {
return this.slide.apply(this, arguments);
}
}, {
key: "masterPartOfLayout",
value: function masterPartOfLayout(wXmlLayoutIdInMaster) {
var masterRoot = this.$(wXmlLayoutIdInMaster).root().get(0);
var masterPartName = masterRoot.attribs.part;
return this.doc.getRelObject(masterPartName);
}
}]);
return OfficeDocument;
}(_officeDocument2.default);
OfficeDocument.identities = {
presentation: function presentation(wXml, officeDocument) {
var $ = officeDocument.content("p\\:presentation");
var content = "p\\:handoutMasterIdLst,p\\:notesMasterIdLst,p\\:sldIdLst,p\\:sldMasterIdLst";
var children = $.children(content).toArray();
var orders = { "p:sldMasterIdLst": 1, "p:sldIdLst": 2 };
children.sort(function (a, b) {
return (orders[a.name] || 99) - (orders[b.name] || 99);
});
var sz = function sz(_ref3) {
var _ref3$attribs = _ref3.attribs,
cx = _ref3$attribs.cx,
cy = _ref3$attribs.cy;
return { width: officeDocument.doc.emu2Px(cx), height: officeDocument.doc.emu2Px(cy) };
};
var props = $.props(_extends({}, (0, _drawml2.default)(officeDocument), {
__filter: ":not(" + content + ",a\\:extLst)",
sldSz: sz,
notesSz: sz
}));
return _extends({}, props, { type: "document", children: children });
},
sldMasterId: function sldMasterId(wXml, officeDocument) {
var content = "p\\:sldLayoutIdLst,p\\:cSld";
var $ = officeDocument.master(wXml.attribs);
var $master = $("p\\:sldMaster");
var props = $master.props(_extends({}, (0, _drawml2.default)(officeDocument), {
__filter: ":not(" + content + ",a\\:extLst)"
}));
var children = $master.children(content).toArray();
var orders = { "p:sldLayoutLst": 1, "p:cSld": 2 };
children.sort(function (a, b) {
return (orders[a.name] || 99) - (orders[b.name] || 99);
});
return _extends({}, props, { part: $.part, children: children, type: "slideMaster" });
},
sldId: function sldId(wXml, officeDocument) {
var content = "p\\:cSld";
var $ = officeDocument.slide(wXml.attribs);
var $slide = $('p\\:sld');
var props = $slide.props(_extends({}, (0, _drawml2.default)(officeDocument), {
__filter: ":not(" + content + ",a\\:extLst)"
}));
var children = $slide.children(content).toArray();
var slidePart = officeDocument.getRelPart(wXml.attribs["r:id"]);
var layoutTarget = officeDocument.doc.normalizePath(slidePart.normalizePath(slidePart.getRelTarget("slideLayout")));
var layoutPart = new _part2.default(layoutTarget, officeDocument.doc);
var masterTarget = officeDocument.doc.normalizePath(layoutPart.normalizePath(layoutPart.getRelTarget("slideMaster")));
return _extends({}, props, { part: $.part, layout: layoutTarget, master: masterTarget, children: children, type: "slide" });
},
notesMasterId: function notesMasterId(wXml, officeDocument) {
var $ = officeDocument.notesMaster(wXml.attribs);
return { part: $.part, type: "noteMaster" };
},
handoutMasterId: function handoutMasterId(wXml, officeDocument) {
var $ = officeDocument.handoutMaster(wXml.attribs);
return { part: $.part, type: "handoutMaster" };
},
sldLayoutId: function sldLayoutId(wXml, officeDocument) {
//in master
var content = "p\\:cSld";
var master = officeDocument.$(wXml).part();
var $ = new _part2.default(master, officeDocument.doc).getRel(wXml.attribs["r:id"]);
var $layout = $("p\\:sldLayout");
var props = $layout.props({ __filter: ":not(" + content + ",a\\:extLst)" });
var children = $layout.children(content).toArray();
return _extends({}, props, { part: $.part, master: master, children: children, type: "slideLayout" });
},
spTree: function spTree(wXml, officeDocument) {
var content = ":not(p\\:nvGrpSpPr,p\\:grpSpPr)";
var $ = officeDocument.$(wXml);
var children = $.children(content).toArray();
var props = officeDocument.$(wXml).props(_extends({}, (0, _drawml2.default)(officeDocument), {
__filter: "p\\:nvGrpSpPr,p\\:grpSpPr",
tidy: function tidy(_ref4) {
var grpSpPr = _ref4.grpSpPr,
_ref4$nvGrpSpPr = _ref4.nvGrpSpPr,
_ref4$nvGrpSpPr$cNvPr = _ref4$nvGrpSpPr.cNvPr,
cNvPr = _ref4$nvGrpSpPr$cNvPr === undefined ? {} : _ref4$nvGrpSpPr$cNvPr,
_ref4$nvGrpSpPr$cNvSp = _ref4$nvGrpSpPr.cNvSpPr,
cNvSpPr = _ref4$nvGrpSpPr$cNvSp === undefined ? {} : _ref4$nvGrpSpPr$cNvSp,
_ref4$nvGrpSpPr$nvPr = _ref4$nvGrpSpPr.nvPr,
nvPr = _ref4$nvGrpSpPr$nvPr === undefined ? {} : _ref4$nvGrpSpPr$nvPr,
others = _objectWithoutProperties(_ref4, ["grpSpPr", "nvGrpSpPr"]);
return _extends({}, grpSpPr, cNvPr, cNvSpPr, nvPr, others);
}
}));
return _extends({}, props, { type: "spTree", children: children });
},
pic: function pic(wXml, officeDocument) {
var props = officeDocument.$(wXml).props(_extends({}, (0, _drawml2.default)(officeDocument), {
tidy: function tidy(_ref5) {
var spPr = _ref5.spPr,
_ref5$nvPicPr = _ref5.nvPicPr,
_ref5$nvPicPr$cNvPr = _ref5$nvPicPr.cNvPr,
cNvPr = _ref5$nvPicPr$cNvPr === undefined ? {} : _ref5$nvPicPr$cNvPr,
_ref5$nvPicPr$cNvSpPr = _ref5$nvPicPr.cNvSpPr,
cNvSpPr = _ref5$nvPicPr$cNvSpPr === undefined ? {} : _ref5$nvPicPr$cNvSpPr,
_ref5$nvPicPr$nvPr = _ref5$nvPicPr.nvPr,
nvPr = _ref5$nvPicPr$nvPr === undefined ? {} : _ref5$nvPicPr$nvPr,
others = _objectWithoutProperties(_ref5, ["spPr", "nvPicPr"]);
return _extends({}, spPr, cNvPr, cNvSpPr, nvPr, others);
}
}));
return _extends({}, props, { type: "picture" });
},
sp: function sp(wXml, officeDocument) {
var content = "p\\:txBody";
var $ = officeDocument.$(wXml);
var children = $.children(content).toArray();
var commonProps = (0, _drawml2.default)(officeDocument);
var names = _extends({ spLocks: "locks", ph: "placeholder" }, commonProps.names);
var props = $.props(_extends({}, commonProps, {
__filter: ":not(" + content + ",a\\:extLst)",
names: names,
ph: function ph(_ref6) {
var _ref6$attribs = _ref6.attribs,
_ref6$attribs$type = _ref6$attribs.type,
type = _ref6$attribs$type === undefined ? "body" : _ref6$attribs$type,
idx = _ref6$attribs.idx;
return { type: type, idx: idx };
},
tidy: function tidy(_ref7) {
var spPr = _ref7.spPr,
_ref7$nvSpPr = _ref7.nvSpPr,
_ref7$nvSpPr$cNvPr = _ref7$nvSpPr.cNvPr,
cNvPr = _ref7$nvSpPr$cNvPr === undefined ? {} : _ref7$nvSpPr$cNvPr,
_ref7$nvSpPr$cNvSpPr = _ref7$nvSpPr.cNvSpPr,
cNvSpPr = _ref7$nvSpPr$cNvSpPr === undefined ? {} : _ref7$nvSpPr$cNvSpPr,
_ref7$nvSpPr$nvPr = _ref7$nvSpPr.nvPr,
nvPr = _ref7$nvSpPr$nvPr === undefined ? {} : _ref7$nvSpPr$nvPr;
return _extends({}, spPr, cNvPr, cNvSpPr, nvPr);
}
}));
var txBody = OfficeDocument.identities.txBody(children[0], officeDocument);
return _extends({}, props, { children: children }, txBody, { type: "shape" });
},
txBody: function txBody(wXml, officeDocument) {
var content = "a\\:p";
var $ = officeDocument.$(wXml);
var children = $.children("a\\:p").toArray();
var textStyle = $.props(_extends({}, (0, _drawml2.default)(officeDocument), {
lnSpcReduction: function lnSpcReduction(v) {
return parseInt(v);
},
fontScale: function fontScale(v) {
return parseInt(v);
},
__filter: ":not(a\\:p,a\\:extLst)",
tidy: function tidy(_ref8) {
var _ref8$lstStyle = _ref8.lstStyle,
lstStyle = _ref8$lstStyle === undefined ? {} : _ref8$lstStyle,
_ref8$bodyPr = _ref8.bodyPr,
bodyPr = _ref8$bodyPr === undefined ? {} : _ref8$bodyPr,
others = _objectWithoutProperties(_ref8, ["lstStyle", "bodyPr"]);
return _extends({}, others, bodyPr, lstStyle);
}
}));
return { textStyle: textStyle, children: children, type: "txBody" };
},
p: function p(wXml, officeDocument) {
var content = ":not(a\\:pPr,a\\:endParaRPr)";
var $ = officeDocument.$(wXml);
var children = $.children(content).toArray();
var style = $.children("a\\:pPr").props((0, _drawml2.default)(officeDocument));
var defaultStyle = $.children("a\\:endParaRPr").props((0, _drawml2.default)(officeDocument));
return { style: _extends({ lvl: 0 }, style), defaultStyle: defaultStyle, children: children, type: "p" };
},
r: function r(wXml, officeDocument) {
var content = ":not(a\\:rPr)";
var $ = officeDocument.$(wXml);
var children = $.children(content).toArray();
var style = $.children("a\\:rPr").props(_extends({}, (0, _drawml2.default)(officeDocument)));
return { style: style, children: children, type: "r" };
},
chart: function chart(wXml, officeDocument) {
return { type: "chart" };
},
relIds: function relIds(wXml, officeDocument) {
return { type: "diagram" };
},
graphicFrame: function graphicFrame(wXml, officeDocument) {
var content = "a\\:graphic";
var $ = officeDocument.$(wXml);
var children = $.children(content).toArray();
var props = $.props(_extends({}, (0, _drawml2.default)(officeDocument), {
__filter: ":not(" + content + ",a\\:extLst)",
tidy: function tidy(_ref9) {
var spPr = _ref9.spPr,
_ref9$nvGraphicFrameP = _ref9.nvGraphicFramePr,
_ref9$nvGraphicFrameP2 = _ref9$nvGraphicFrameP.cNvPr,
cNvPr = _ref9$nvGraphicFrameP2 === undefined ? {} : _ref9$nvGraphicFrameP2,
_ref9$nvGraphicFrameP3 = _ref9$nvGraphicFrameP.cNvSpPr,
cNvSpPr = _ref9$nvGraphicFrameP3 === undefined ? {} : _ref9$nvGraphicFrameP3,
_ref9$nvGraphicFrameP4 = _ref9$nvGraphicFrameP.nvPr,
nvPr = _ref9$nvGraphicFrameP4 === undefined ? {} : _ref9$nvGraphicFrameP4,
others = _objectWithoutProperties(_ref9, ["spPr", "nvGraphicFramePr"]);
return _extends({}, spPr, cNvPr, cNvSpPr, nvPr, others);
}
}));
return _extends({}, props, { children: children, type: "graphicFrame" });
},
tbl: function tbl(wXml, officeDocument) {
var content = "a\\:tr";
var $ = officeDocument.$(wXml);
var children = $.children(content).toArray();
var props = $.props(_extends({}, (0, _drawml2.default)(officeDocument), {
__filter: ":not(" + content + ", a\\:extLst)",
tableStyleId: function tableStyleId(_ref10) {
var children = _ref10.children;
return children.find(function (a) {
return a.data;
}).data;
},
tblGrid: function tblGrid(_ref11) {
var children = _ref11.children;
return children.filter(function (a) {
return a.name;
}).reduce(function (cols, _ref12) {
var w = _ref12.attribs.w;
cols.push(officeDocument.doc.emu2Px(w));
return cols;
}, []);
},
tidy: function tidy(_ref13) {
var tblPr = _ref13.tblPr,
cols = _ref13.tblGrid,
others = _objectWithoutProperties(_ref13, ["tblPr", "tblGrid"]);
return _extends({}, tblPr, { cols: cols }, others);
}
}));
return _extends({}, props, { children: children, type: "tbl" });
},
tblStyle: function tblStyle(wXml, officeDocument) {
var $ = officeDocument.$(wXml);
var props = $.props((0, _drawml2.default)(officeDocument));
return _extends({}, props, { type: "tblStyle" });
},
tr: function tr(wXml, officeDocument) {
var $ = officeDocument.$(wXml);
var props = $.props(_extends({}, (0, _drawml2.default)(officeDocument), {
__filter: ":not(*)",
h: function h(v) {
return officeDocument.doc.emu2Px(v);
},
names: { h: "height" }
}));
return _extends({}, props, { children: wXml.children, type: "tr" });
},
tc: function tc(wXml, officeDocument) {
var content = "a\\:txBody";
var $ = officeDocument.$(wXml);
var children = $.children(content).toArray();
var props = $.props({
__filter: ":not(" + content + ",a\\:extLst)"
});
return _extends({}, props, { type: "tc", children: children });
}
};
exports.default = OfficeDocument;
module.exports = exports['default'];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9vcGVueG1sL3BwdHgvb2ZmaWNlRG9jdW1lbnQuanMiXSwibmFtZXMiOlsiT2ZmaWNlRG9jdW1lbnQiLCJfYXNzaWduUmVsIiwic3BsaXQiLCJjcmVhdGVFbGVtZW50IiwiaWRlbnRpZnkiLCJjb25zdHJ1Y3RvciIsImJpbmQiLCJ0YWJsZVN0eWxlcyIsInJlbmRlck5vZGUiLCJyb290IiwiY2hpbGRyZW4iLCJnZXQiLCJjb250ZW50IiwiaWQiLCJyaWQiLCJnZXRSZWwiLCJzbGlkZSIsImFyZ3VtZW50cyIsIndYbWxMYXlvdXRJZEluTWFzdGVyIiwibWFzdGVyUm9vdCIsIiQiLCJtYXN0ZXJQYXJ0TmFtZSIsImF0dHJpYnMiLCJwYXJ0IiwiZG9jIiwiZ2V0UmVsT2JqZWN0IiwiaWRlbnRpdGllcyIsInByZXNlbnRhdGlvbiIsIndYbWwiLCJvZmZpY2VEb2N1bWVudCIsInRvQXJyYXkiLCJvcmRlcnMiLCJzb3J0IiwiYSIsImIiLCJuYW1lIiwic3oiLCJjeCIsImN5Iiwid2lkdGgiLCJlbXUyUHgiLCJoZWlnaHQiLCJwcm9wcyIsIl9fZmlsdGVyIiwic2xkU3oiLCJub3Rlc1N6IiwidHlwZSIsInNsZE1hc3RlcklkIiwibWFzdGVyIiwiJG1hc3RlciIsInNsZElkIiwiJHNsaWRlIiwic2xpZGVQYXJ0IiwiZ2V0UmVsUGFydCIsImxheW91dFRhcmdldCIsIm5vcm1hbGl6ZVBhdGgiLCJnZXRSZWxUYXJnZXQiLCJsYXlvdXRQYXJ0IiwibWFzdGVyVGFyZ2V0IiwibGF5b3V0Iiwibm90ZXNNYXN0ZXJJZCIsIm5vdGVzTWFzdGVyIiwiaGFuZG91dE1hc3RlcklkIiwiaGFuZG91dE1hc3RlciIsInNsZExheW91dElkIiwiJGxheW91dCIsInNwVHJlZSIsInRpZHkiLCJncnBTcFByIiwibnZHcnBTcFByIiwiY052UHIiLCJjTnZTcFByIiwibnZQciIsIm90aGVycyIsInBpYyIsInNwUHIiLCJudlBpY1ByIiwic3AiLCJjb21tb25Qcm9wcyIsIm5hbWVzIiwic3BMb2NrcyIsInBoIiwiaWR4IiwibnZTcFByIiwidHhCb2R5IiwidGV4dFN0eWxlIiwibG5TcGNSZWR1Y3Rpb24iLCJwYXJzZUludCIsInYiLCJmb250U2NhbGUiLCJsc3RTdHlsZSIsImJvZHlQciIsInAiLCJzdHlsZSIsImRlZmF1bHRTdHlsZSIsImx2bCIsInIiLCJjaGFydCIsInJlbElkcyIsImdyYXBoaWNGcmFtZSIsIm52R3JhcGhpY0ZyYW1lUHIiLCJ0YmwiLCJ0YWJsZVN0eWxlSWQiLCJmaW5kIiwiZGF0YSIsInRibEdyaWQiLCJmaWx0ZXIiLCJyZWR1Y2UiLCJjb2xzIiwidyIsInB1c2giLCJ0YmxQciIsInRibFN0eWxlIiwidHIiLCJoIiwidGMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7SUFFcUJBLGM7Ozs7Ozs7Ozs7O2dDQUNWO0FBQ0g7QUFDQSxpQkFBS0MsVUFBTCxDQUFnQixrQ0FBa0NDLEtBQWxDLENBQXdDLEdBQXhDLENBQWhCO0FBQ0g7OzsrQkFFTUMsYSxFQUF5RTtBQUFBLGdCQUExREMsUUFBMEQsdUVBQWpELEtBQUtDLFdBQUwsQ0FBaUJELFFBQWpCLENBQTBCRSxJQUExQixDQUErQixLQUFLRCxXQUFwQyxDQUFpRDs7QUFDNUUsZ0JBQUcsS0FBS0UsV0FBUixFQUFvQjtBQUNoQixxQkFBS0MsVUFBTCxDQUFnQixLQUFLRCxXQUFMLENBQWlCRSxJQUFqQixHQUF3QkMsUUFBeEIsR0FBbUNDLEdBQW5DLENBQXVDLENBQXZDLENBQWhCLEVBQTJEUixhQUEzRCxFQUEwRUMsUUFBMUU7QUFDSDtBQUNELG1CQUFPLEtBQUtJLFVBQUwsQ0FBZ0IsS0FBS0ksT0FBTCxDQUFhLGtCQUFiLEVBQWlDRCxHQUFqQyxDQUFxQyxDQUFyQyxDQUFoQixFQUF5RFIsYUFBekQsRUFBd0VDLFFBQXhFLENBQVA7QUFDSDs7O29DQUVxQjtBQUFBLGdCQUFmUyxFQUFlLFFBQWZBLEVBQWU7QUFBQSxnQkFBTEMsR0FB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QXpMSyxFQXlMVTtBQUNwQixZQUFNVCxJQUFFUyxlQUFlVCxDQUFmLENBQWlCUSxJQUFqQixDQUFSO0FBQ0EsWUFBTWMsUUFBTXRCLEVBQUVzQixLQUFGLGNBQ0wsc0JBQU9iLGNBQVAsQ0FESztBQUVSYyxzQkFBUyxTQUZEO0FBR1J1RSxlQUFFO0FBQUEsdUJBQUdyRixlQUFlTCxHQUFmLENBQW1CZ0IsTUFBbkIsQ0FBMEJnRCxDQUExQixDQUFIO0FBQUEsYUFITTtBQUlSVCxtQkFBTSxFQUFDbUMsR0FBRSxRQUFIO0FBSkUsV0FBWjtBQU1BLDRCQUFXeEUsS0FBWCxJQUFrQmhDLFVBQVNrQixLQUFLbEIsUUFBaEMsRUFBMENvQyxNQUFLLElBQS9DO0FBQ0gsS0FsTWE7QUFvTWRxRSxNQXBNYyxjQW9NWHZGLElBcE1XLEVBb01MQyxjQXBNSyxFQW9NVTtBQUNwQixZQUFNakIsVUFBUSxZQUFkO0FBQ0EsWUFBTVEsSUFBRVMsZUFBZVQsQ0FBZixDQUFpQlEsSUFBakIsQ0FBUjtBQUNBLFlBQU1sQixXQUFTVSxFQUFFVixRQUFGLENBQVdFLE9BQVgsRUFBb0JrQixPQUFwQixFQUFmO0FBQ0EsWUFBTVksUUFBTXRCLEVBQUVzQixLQUFGLENBQVE7QUFDaEJDLGdDQUFpQi9CLE9BQWpCO0FBRGdCLFNBQVIsQ0FBWjtBQUdBLDRCQUFXOEIsS0FBWCxJQUFrQkksTUFBSyxJQUF2QixFQUE2QnBDLGtCQUE3QjtBQUNIO0FBNU1hLEM7a0JBbkNEVixjIiwiZmlsZSI6Im9mZmljZURvY3VtZW50LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEJhc2UgZnJvbSBcIi4uL29mZmljZURvY3VtZW50XCJcclxuaW1wb3J0IFBhcnQgZnJvbSBcIi4uL3BhcnRcIlxyXG5pbXBvcnQgZHJhd21sIGZyb20gXCIuLi9kcmF3bWxcIlxyXG5cclxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgT2ZmaWNlRG9jdW1lbnQgZXh0ZW5kcyBCYXNle1xyXG4gICAgX2luaXQoKXtcclxuICAgICAgICBzdXBlci5faW5pdCgpXHJcbiAgICAgICAgdGhpcy5fYXNzaWduUmVsKFwidGFibGVTdHlsZXMsdmlld1Byb3BzLHByZXNQcm9wc1wiLnNwbGl0KFwiLFwiKSlcclxuICAgIH1cclxuXHJcbiAgICByZW5kZXIoY3JlYXRlRWxlbWVudCwgaWRlbnRpZnk9dGhpcy5jb25zdHJ1Y3Rvci5pZGVudGlmeS5iaW5kKHRoaXMuY29uc3RydWN0b3IpKXtcclxuICAgICAgICBpZih0aGlzLnRhYmxlU3R5bGVzKXtcclxuICAgICAgICAgICAgdGhpcy5yZW5kZXJOb2RlKHRoaXMudGFibGVTdHlsZXMucm9vdCgpLmNoaWxkcmVuKCkuZ2V0KDApLCBjcmVhdGVFbGVtZW50LCBpZGVudGlmeSlcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVuZGVyTm9kZSh0aGlzLmNvbnRlbnQoXCJwXFxcXDpwcmVzZW50YXRpb25cIikuZ2V0KDApLCBjcmVhdGVFbGVtZW50LCBpZGVudGlmeSlcclxuICAgIH1cclxuXHJcbiAgICBzbGlkZSh7aWQsXCJyOmlkXCI6cmlkfSl7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UmVsKHJpZClcclxuICAgIH1cclxuXHJcbiAgICBtYXN0ZXIoe2lkLFwicjppZFwiOnJpZH0pe1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNsaWRlKC4uLmFyZ3VtZW50cylcclxuICAgIH1cclxuXHJcbiAgICBub3Rlc01hc3Rlcigpe1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNsaWRlKC4uLmFyZ3VtZW50cylcclxuICAgIH1cclxuXHJcbiAgICBoYW5kb3V0TWFzdGVyKCl7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2xpZGUoLi4uYXJndW1lbnRzKVxyXG4gICAgfVxyXG5cclxuICAgIG1hc3RlclBhcnRPZkxheW91dCh3WG1sTGF5b3V0SWRJbk1hc3Rlcil7XHJcbiAgICAgICAgY29uc3QgbWFzdGVyUm9vdD10aGlzLiQod1htbExheW91dElkSW5NYXN0ZXIpLnJvb3QoKS5nZXQoMClcclxuICAgICAgICBjb25zdCB7cGFydDptYXN0ZXJQYXJ0TmFtZX09bWFzdGVyUm9vdC5hdHRyaWJzXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZG9jLmdldFJlbE9iamVjdChtYXN0ZXJQYXJ0TmFtZSlcclxuICAgIH1cclxuXHJcbiAgICBzdGF0aWMgaWRlbnRpdGllcz17XHJcbiAgICAgICAgcHJlc2VudGF0aW9uKHdYbWwsb2ZmaWNlRG9jdW1lbnQpe1xyXG5cdFx0XHRjb25zdCAkPW9mZmljZURvY3VtZW50LmNvbnRlbnQoXCJwXFxcXDpwcmVzZW50YXRpb25cIilcclxuICAgICAgICAgICAgY29uc3QgY29udGVudD1cInBcXFxcOmhhbmRvdXRNYXN0ZXJJZExzdCxwXFxcXDpub3Rlc01hc3RlcklkTHN0LHBcXFxcOnNsZElkTHN0LHBcXFxcOnNsZE1hc3RlcklkTHN0XCJcclxuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW49JC5jaGlsZHJlbihjb250ZW50KS50b0FycmF5KClcclxuICAgICAgICAgICAgY29uc3Qgb3JkZXJzPXtcInA6c2xkTWFzdGVySWRMc3RcIjoxLCBcInA6c2xkSWRMc3RcIjoyfVxyXG4gICAgICAgICAgICBjaGlsZHJlbi5zb3J0KChhLGIpPT4ob3JkZXJzW2EubmFtZV18fDk5KS0ob3JkZXJzW2IubmFtZV18fDk5KSlcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHN6PSh7YXR0cmliczp7Y3gsY3l9fSk9Pih7d2lkdGg6b2ZmaWNlRG9jdW1lbnQuZG9jLmVtdTJQeChjeCksaGVpZ2h0Om9mZmljZURvY3VtZW50LmRvYy5lbXUyUHgoY3kpfSlcclxuICAgICAgICAgICAgY29uc3QgcHJvcHM9JC5wcm9wcyh7XHJcbiAgICAgICAgICAgICAgICAuLi5kcmF3bWwob2ZmaWNlRG9jdW1lbnQpLFxyXG4gICAgICAgICAgICAgICAgX19maWx0ZXI6YDpub3QoJHtjb250ZW50fSxhXFxcXDpleHRMc3QpYCxcclxuICAgICAgICAgICAgICAgIHNsZFN6OnN6LCBcclxuICAgICAgICAgICAgICAgIG5vdGVzU3o6c3osXHJcbiAgICAgICAgICAgIH0pXHJcblxyXG4gICAgICAgICAgICByZXR1cm4gey4uLnByb3BzLCB0eXBlOlwiZG9jdW1lbnRcIixjaGlsZHJlbn1cclxuXHRcdH0sXHJcblxyXG4gICAgICAgIHNsZE1hc3RlcklkKHdYbWwsIG9mZmljZURvY3VtZW50KXtcclxuICAgICAgICAgICAgY29uc3QgY29udGVudD1cInBcXFxcOnNsZExheW91dElkTHN0LHBcXFxcOmNTbGRcIlxyXG4gICAgICAgICAgICBjb25zdCAkPW9mZmljZURvY3VtZW50Lm1hc3Rlcih3WG1sLmF0dHJpYnMpXHJcbiAgICAgICAgICAgIGNvbnN0ICRtYXN0ZXI9JChcInBcXFxcOnNsZE1hc3RlclwiKVxyXG4gICAgICAgICAgICBjb25zdCBwcm9wcz0kbWFzdGVyLnByb3BzKHtcclxuICAgICAgICAgICAgICAgIC4uLmRyYXdtbChvZmZpY2VEb2N1bWVudCksXHJcbiAgICAgICAgICAgICAgICBfX2ZpbHRlcjpgOm5vdCgke2NvbnRlbnR9LGFcXFxcOmV4dExzdClgLFxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbj0kbWFzdGVyLmNoaWxkcmVuKGNvbnRlbnQpLnRvQXJyYXkoKVxyXG4gICAgICAgICAgICBjb25zdCBvcmRlcnM9e1wicDpzbGRMYXlvdXRMc3RcIjoxLCBcInA6Y1NsZFwiOjJ9XHJcbiAgICAgICAgICAgIGNoaWxkcmVuLnNvcnQoKGEsYik9PihvcmRlcnNbYS5uYW1lXXx8OTkpLShvcmRlcnNbYi5uYW1lXXx8OTkpKVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHsuLi5wcm9wcywgcGFydDogJC5wYXJ0LCBjaGlsZHJlbix0eXBlOlwic2xpZGVNYXN0ZXJcIn1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzbGRJZCh3WG1sLG9mZmljZURvY3VtZW50KXtcclxuICAgICAgICAgICAgY29uc3QgY29udGVudD1cInBcXFxcOmNTbGRcIlxyXG4gICAgICAgICAgICBjb25zdCAkPW9mZmljZURvY3VtZW50LnNsaWRlKHdYbWwuYXR0cmlicylcclxuICAgICAgICAgICAgY29uc3QgJHNsaWRlPSQoJ3BcXFxcOnNsZCcpXHJcbiAgICAgICAgICAgIGNvbnN0IHByb3BzPSRzbGlkZS5wcm9wcyh7XHJcbiAgICAgICAgICAgICAgICAuLi5kcmF3bWwob2ZmaWNlRG9jdW1lbnQpLFxyXG4gICAgICAgICAgICAgICAgX19maWx0ZXI6YDpub3QoJHtjb250ZW50fSxhXFxcXDpleHRMc3QpYCxcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW49JHNsaWRlLmNoaWxkcmVuKGNvbnRlbnQpLnRvQXJyYXkoKVxyXG5cclxuICAgICAgICAgICAgY29uc3Qgc2xpZGVQYXJ0PW9mZmljZURvY3VtZW50LmdldFJlbFBhcnQod1htbC5hdHRyaWJzW1wicjppZFwiXSlcclxuICAgICAgICAgICAgY29uc3QgbGF5b3V0VGFyZ2V0PW9mZmljZURvY3VtZW50LmRvYy5ub3JtYWxpemVQYXRoKHNsaWRlUGFydC5ub3JtYWxpemVQYXRoKHNsaWRlUGFydC5nZXRSZWxUYXJnZXQoXCJzbGlkZUxheW91dFwiKSkpXHJcbiAgICAgICAgICAgIGNvbnN0IGxheW91dFBhcnQ9bmV3IFBhcnQobGF5b3V0VGFyZ2V0LG9mZmljZURvY3VtZW50LmRvYylcclxuICAgICAgICAgICAgY29uc3QgbWFzdGVyVGFyZ2V0PW9mZmljZURvY3VtZW50LmRvYy5ub3JtYWxpemVQYXRoKGxheW91dFBhcnQubm9ybWFsaXplUGF0aChsYXlvdXRQYXJ0LmdldFJlbFRhcmdldChcInNsaWRlTWFzdGVyXCIpKSlcclxuICAgICAgICAgICAgcmV0dXJuIHsuLi5wcm9wcyxwYXJ0OiQucGFydCwgbGF5b3V0OmxheW91dFRhcmdldCwgbWFzdGVyOm1hc3RlclRhcmdldCwgY2hpbGRyZW4sIHR5cGU6XCJzbGlkZVwifVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIG5vdGVzTWFzdGVySWQod1htbCwgb2ZmaWNlRG9jdW1lbnQpe1xyXG4gICAgICAgICAgICBjb25zdCAkPW9mZmljZURvY3VtZW50Lm5vdGVzTWFzdGVyKHdYbWwuYXR0cmlicylcclxuICAgICAgICAgICAgcmV0dXJuIHtwYXJ0OiQucGFydCx0eXBlOlwibm90ZU1hc3RlclwiLH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBoYW5kb3V0TWFzdGVySWQod1htbCwgb2ZmaWNlRG9jdW1lbnQpe1xyXG4gICAgICAgICAgICBjb25zdCAkPW9mZmljZURvY3VtZW50LmhhbmRvdXRNYXN0ZXIod1htbC5hdHRyaWJzKVxyXG4gICAgICAgICAgICByZXR1cm4ge3BhcnQ6JC5wYXJ0LHR5cGU6XCJoYW5kb3V0TWFzdGVyXCIsIH1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzbGRMYXlvdXRJZCh3WG1sLG9mZmljZURvY3VtZW50KXsvL2luIG1hc3RlclxyXG4gICAgICAgICAgICBjb25zdCBjb250ZW50PVwicFxcXFw6Y1NsZFwiXHJcbiAgICAgICAgICAgIGNvbnN0IG1hc3Rlcj1vZmZpY2VEb2N1bWVudC4kKHdYbWwpLnBhcnQoKVxyXG4gICAgICAgICAgICBjb25zdCAkPW5ldyBQYXJ0KG1hc3RlcixvZmZpY2VEb2N1bWVudC5kb2MpLmdldFJlbCh3WG1sLmF0dHJpYnNbXCJyOmlkXCJdKVxyXG4gICAgICAgICAgICBjb25zdCAkbGF5b3V0PSQoXCJwXFxcXDpzbGRMYXlvdXRcIilcclxuICAgICAgICAgICAgY29uc3QgcHJvcHM9JGxheW91dC5wcm9wcyh7X19maWx0ZXI6YDpub3QoJHtjb250ZW50fSxhXFxcXDpleHRMc3QpYH0pXHJcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkcmVuPSRsYXlvdXQuY2hpbGRyZW4oY29udGVudCkudG9BcnJheSgpXHJcblxyXG4gICAgICAgICAgICByZXR1cm4gey4uLnByb3BzLHBhcnQ6JC5wYXJ0LCBtYXN0ZXIsIGNoaWxkcmVuLCB0eXBlOlwic2xpZGVMYXlvdXRcIiwgfVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIHNwVHJlZSh3WG1sLG9mZmljZURvY3VtZW50KXtcclxuICAgICAgICAgICAgY29uc3QgY29udGVudD1cIjpub3QocFxcXFw6bnZHcnBTcFByLHBcXFxcOmdycFNwUHIpXCJcclxuICAgICAgICAgICAgY29uc3QgJD1vZmZpY2VEb2N1bWVudC4kKHdYbWwpXHJcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkcmVuPSQuY2hpbGRyZW4oY29udGVudCkudG9BcnJheSgpXHJcbiAgICAgICAgICAgIGNvbnN0IHByb3BzPW9mZmljZURvY3VtZW50LiQod1htbCkucHJvcHMoe1xyXG4gICAgICAgICAgICAgICAgLi4uZHJhd21sKG9mZmljZURvY3VtZW50KSxcclxuICAgICAgICAgICAgICAgIF9fZmlsdGVyOmBwXFxcXDpudkdycFNwUHIscFxcXFw6Z3JwU3BQcmAsXHJcbiAgICAgICAgICAgICAgICB0aWR5Oih7Z3JwU3BQciwgbnZHcnBTcFByOntjTnZQcj17fSxjTnZTcFByPXt9LG52UHI9e319LCAuLi5vdGhlcnN9KT0+KHsuLi5ncnBTcFByLCAuLi5jTnZQciwuLi5jTnZTcFByLC4uLm52UHIsLi4ub3RoZXJzfSlcclxuICAgICAgICAgICAgfSlcclxuXHJcbiAgICAgICAgICAgIHJldHVybiB7Li4ucHJvcHMsdHlwZTpcInNwVHJlZVwiLCBjaGlsZHJlbn1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBwaWMod1htbCwgb2ZmaWNlRG9jdW1lbnQpe1xyXG4gICAgICAgICAgICBjb25zdCBwcm9wcz1vZmZpY2VEb2N1bWVudC4kKHdYbWwpLnByb3BzKHtcclxuICAgICAgICAgICAgICAgIC4uLmRyYXdtbChvZmZpY2VEb2N1bWVudCksXHJcbiAgICAgICAgICAgICAgICB0aWR5Oih7c3BQciwgbnZQaWNQcjp7Y052UHI9e30sY052U3BQcj17fSxudlByPXt9fSwgLi4ub3RoZXJzfSk9Pih7Li4uc3BQciwgLi4uY052UHIsLi4uY052U3BQciwuLi5udlByLC4uLm90aGVyc30pXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIHJldHVybiB7Li4ucHJvcHMsdHlwZTpcInBpY3R1cmVcIn1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzcCh3WG1sLCBvZmZpY2VEb2N1bWVudCl7XHJcbiAgICAgICAgICAgIGNvbnN0IGNvbnRlbnQ9XCJwXFxcXDp0eEJvZHlcIlxyXG5cdFx0XHRjb25zdCAkPW9mZmljZURvY3VtZW50LiQod1htbClcclxuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW49JC5jaGlsZHJlbihjb250ZW50KS50b0FycmF5KClcclxuICAgICAgICAgICAgY29uc3QgY29tbW9uUHJvcHM9ZHJhd21sKG9mZmljZURvY3VtZW50KVxyXG4gICAgICAgICAgICBjb25zdCBuYW1lcz17c3BMb2NrczpcImxvY2tzXCIsIHBoOlwicGxhY2Vob2xkZXJcIiwgLi4uY29tbW9uUHJvcHMubmFtZXN9XHJcbiAgICAgICAgICAgIGNvbnN0IHByb3BzPSQucHJvcHMoe1xyXG4gICAgICAgICAgICAgICAgLi4uY29tbW9uUHJvcHMsXHJcbiAgICAgICAgICAgICAgICBfX2ZpbHRlcjpgOm5vdCgke2NvbnRlbnR9LGFcXFxcOmV4dExzdClgLFxyXG4gICAgICAgICAgICAgICAgbmFtZXMsXHJcbiAgICAgICAgICAgICAgICBwaDooe2F0dHJpYnM6e3R5cGU9XCJib2R5XCIsaWR4fX0pPT4oe3R5cGUsaWR4fSksXHJcbiAgICAgICAgICAgICAgICB0aWR5Oih7c3BQciwgbnZTcFByOntjTnZQcj17fSxjTnZTcFByPXt9LG52UHI9e319fSk9Pih7Li4uc3BQciwgLi4uY052UHIsLi4uY052U3BQciwuLi5udlByfSlcclxuICAgICAgICAgICAgfSlcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHR4Qm9keT1PZmZpY2VEb2N1bWVudC5pZGVudGl0aWVzLnR4Qm9keShjaGlsZHJlblswXSxvZmZpY2VEb2N1bWVudClcclxuICAgICAgICAgICAgcmV0dXJuIHsuLi5wcm9wcywgY2hpbGRyZW4sIC4uLnR4Qm9keSwgdHlwZTpcInNoYXBlXCJ9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgdHhCb2R5KHdYbWwsIG9mZmljZURvY3VtZW50KXtcclxuICAgICAgICAgICAgY29uc3QgY29udGVudD1cImFcXFxcOnBcIlxyXG5cdFx0XHRjb25zdCAkPW9mZmljZURvY3VtZW50LiQod1htbClcclxuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW49JC5jaGlsZHJlbihcImFcXFxcOnBcIikudG9BcnJheSgpXHJcbiAgICAgICAgICAgIGNvbnN0IHRleHRTdHlsZT0kLnByb3BzKHtcclxuICAgICAgICAgICAgICAgIC4uLmRyYXdtbChvZmZpY2VEb2N1bWVudCksXHJcbiAgICAgICAgICAgICAgICBsblNwY1JlZHVjdGlvbjp2PT5wYXJzZUludCh2KSxcclxuICAgICAgICAgICAgICAgIGZvbnRTY2FsZTogdj0+cGFyc2VJbnQodiksXHJcbiAgICAgICAgICAgICAgICBfX2ZpbHRlcjpgOm5vdChhXFxcXDpwLGFcXFxcOmV4dExzdClgLFxyXG4gICAgICAgICAgICAgICAgdGlkeTooe2xzdFN0eWxlPXt9LGJvZHlQcj17fSwuLi5vdGhlcnN9KT0+KHsuLi5vdGhlcnMsIC4uLmJvZHlQciwgLi4ubHN0U3R5bGV9KVxyXG4gICAgICAgICAgICB9KVxyXG5cdFx0XHRyZXR1cm4ge3RleHRTdHlsZSwgY2hpbGRyZW4sIHR5cGU6XCJ0eEJvZHlcIn1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBwKHdYbWwsIG9mZmljZURvY3VtZW50KXtcclxuICAgICAgICAgICAgY29uc3QgY29udGVudD1cIjpub3QoYVxcXFw6cFByLGFcXFxcOmVuZFBhcmFSUHIpXCJcclxuICAgICAgICAgICAgY29uc3QgJD1vZmZpY2VEb2N1bWVudC4kKHdYbWwpXHJcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkcmVuPSQuY2hpbGRyZW4oY29udGVudCkudG9BcnJheSgpXHJcbiAgICAgICAgICAgIGNvbnN0IHN0eWxlPSQuY2hpbGRyZW4oXCJhXFxcXDpwUHJcIikucHJvcHMoZHJhd21sKG9mZmljZURvY3VtZW50KSlcclxuICAgICAgICAgICAgY29uc3QgZGVmYXVsdFN0eWxlPSQuY2hpbGRyZW4oXCJhXFxcXDplbmRQYXJhUlByXCIpLnByb3BzKGRyYXdtbChvZmZpY2VEb2N1bWVudCkpXHJcbiAgICAgICAgICAgIHJldHVybiB7c3R5bGU6e2x2bDowLCAuLi5zdHlsZX0sIGRlZmF1bHRTdHlsZSwgY2hpbGRyZW4sIHR5cGU6XCJwXCJ9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgcih3WG1sLG9mZmljZURvY3VtZW50KXtcclxuICAgICAgICAgICAgY29uc3QgY29udGVudD1cIjpub3QoYVxcXFw6clByKVwiXHJcbiAgICAgICAgICAgIGNvbnN0ICQ9b2ZmaWNlRG9jdW1lbnQuJCh3WG1sKVxyXG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbj0kLmNoaWxkcmVuKGNvbnRlbnQpLnRvQXJyYXkoKVxyXG4gICAgICAgICAgICBjb25zdCBzdHlsZT0kLmNoaWxkcmVuKFwiYVxcXFw6clByXCIpLnByb3BzKHsuLi5kcmF3bWwob2ZmaWNlRG9jdW1lbnQpfSlcclxuICAgICAgICAgICAgcmV0dXJuIHtzdHlsZSwgY2hpbGRyZW4sIHR5cGU6XCJyXCJ9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgY2hhcnQod1htbCwgb2ZmaWNlRG9jdW1lbnQpe1xyXG4gICAgICAgICAgICByZXR1cm4ge3R5cGU6IFwiY2hhcnRcIn1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICByZWxJZHMod1htbCwgb2ZmaWNlRG9jdW1lbnQpe1xyXG4gICAgICAgICAgICByZXR1cm4ge3R5cGU6XCJkaWFncmFtXCJ9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgZ3JhcGhpY0ZyYW1lKHdYbWwsIG9mZmljZURvY3VtZW50KXtcclxuICAgICAgICAgICAgY29uc3QgY29udGVudD1cImFcXFxcOmdyYXBoaWNcIlxyXG4gICAgICAgICAgICBjb25zdCAkPW9mZmljZURvY3VtZW50LiQod1htbClcclxuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW49JC5jaGlsZHJlbihjb250ZW50KS50b0FycmF5KClcclxuICAgICAgICAgICAgY29uc3QgcHJvcHM9JC5wcm9wcyh7XHJcbiAgICAgICAgICAgICAgICAuLi5kcmF3bWwob2ZmaWNlRG9jdW1lbnQpLFxyXG4gICAgICAgICAgICAgICAgX19maWx0ZXI6YDpub3QoJHtjb250ZW50fSxhXFxcXDpleHRMc3QpYCxcclxuICAgICAgICAgICAgICAgIHRpZHk6KHtzcFByLCBudkdyYXBoaWNGcmFtZVByOntjTnZQcj17fSxjTnZTcFByPXt9LG52UHI9e319LCAuLi5vdGhlcnN9KT0+KHsuLi5zcFByLCAuLi5jTnZQciwuLi5jTnZTcFByLC4uLm52UHIsLi4ub3RoZXJzfSlcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgcmV0dXJuIHsuLi5wcm9wcywgY2hpbGRyZW4sIHR5cGU6XCJncmFwaGljRnJhbWVcIn1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICB0Ymwod1htbCwgb2ZmaWNlRG9jdW1lbnQpe1xyXG4gICAgICAgICAgICBjb25zdCBjb250ZW50PVwiYVxcXFw6dHJcIlxyXG4gICAgICAgICAgICBjb25zdCAkPW9mZmljZURvY3VtZW50LiQod1htbClcclxuICAgICAgICAgICAgY29uc3QgY2hpbGRyZW49JC5jaGlsZHJlbihjb250ZW50KS50b0FycmF5KClcclxuICAgICAgICAgICAgY29uc3QgcHJvcHM9JC5wcm9wcyh7XHJcbiAgICAgICAgICAgICAgICAuLi5kcmF3bWwob2ZmaWNlRG9jdW1lbnQpLFxyXG4gICAgICAgICAgICAgICAgX19maWx0ZXI6YDpub3QoJHtjb250ZW50fSwgYVxcXFw6ZXh0THN0KWAsXHJcbiAgICAgICAgICAgICAgICB0YWJsZVN0eWxlSWQ6KHtjaGlsZHJlbn0pPT5jaGlsZHJlbi5maW5kKGE9PmEuZGF0YSkuZGF0YSxcclxuICAgICAgICAgICAgICAgIHRibEdyaWQ6KHtjaGlsZHJlbn0pPT5jaGlsZHJlbi5maWx0ZXIoYT0+YS5uYW1lKS5yZWR1Y2UoKGNvbHMse2F0dHJpYnM6e3d9fSk9PntcclxuICAgICAgICAgICAgICAgICAgICBjb2xzLnB1c2gob2ZmaWNlRG9jdW1lbnQuZG9jLmVtdTJQeCh3KSlcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29sc1xyXG4gICAgICAgICAgICAgICAgfSxbXSksXHJcbiAgICAgICAgICAgICAgICB0aWR5Oih7dGJsUHIsIHRibEdyaWQ6Y29scywgLi4ub3RoZXJzfSk9Pih7Li4udGJsUHIsIGNvbHMsIC4uLm90aGVyc30pXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIHJldHVybiB7Li4ucHJvcHMsIGNoaWxkcmVuLCB0eXBlOlwidGJsXCJ9XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgdGJsU3R5bGUod1htbCwgb2ZmaWNlRG9jdW1lbnQpe1xyXG4gICAgICAgICAgICBjb25zdCAkPW9mZmljZURvY3VtZW50LiQod1htbClcclxuICAgICAgICAgICAgY29uc3QgcHJvcHM9JC5wcm9wcyhkcmF3bWwob2ZmaWNlRG9jdW1lbnQpKVxyXG4gICAgICAgICAgICByZXR1cm4gey4uLnByb3BzLCB0eXBlOlwidGJsU3R5bGVcIn1cclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICB0cih3WG1sLCBvZmZpY2VEb2N1bWVudCl7XHJcbiAgICAgICAgICAgIGNvbnN0ICQ9b2ZmaWNlRG9jdW1lbnQuJCh3WG1sKVxyXG4gICAgICAgICAgICBjb25zdCBwcm9wcz0kLnByb3BzKHtcclxuICAgICAgICAgICAgICAgIC4uLmRyYXdtbChvZmZpY2VEb2N1bWVudCksXHJcbiAgICAgICAgICAgICAgICBfX2ZpbHRlcjpcIjpub3QoKilcIixcclxuICAgICAgICAgICAgICAgIGg6dj0+b2ZmaWNlRG9jdW1lbnQuZG9jLmVtdTJQeCh2KSxcclxuICAgICAgICAgICAgICAgIG5hbWVzOntoOlwiaGVpZ2h0XCJ9XHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIHJldHVybiB7Li4ucHJvcHMsIGNoaWxkcmVuOndYbWwuY2hpbGRyZW4sIHR5cGU6XCJ0clwifVxyXG4gICAgICAgIH0sXHJcblxyXG4gICAgICAgIHRjKHdYbWwsIG9mZmljZURvY3VtZW50KXtcclxuICAgICAgICAgICAgY29uc3QgY29udGVudD1cImFcXFxcOnR4Qm9keVwiXHJcbiAgICAgICAgICAgIGNvbnN0ICQ9b2ZmaWNlRG9jdW1lbnQuJCh3WG1sKVxyXG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbj0kLmNoaWxkcmVuKGNvbnRlbnQpLnRvQXJyYXkoKVxyXG4gICAgICAgICAgICBjb25zdCBwcm9wcz0kLnByb3BzKHtcclxuICAgICAgICAgICAgICAgIF9fZmlsdGVyOmA6bm90KCR7Y29udGVudH0sYVxcXFw6ZXh0THN0KWBcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgcmV0dXJuIHsuLi5wcm9wcywgdHlwZTpcInRjXCIsIGNoaWxkcmVufVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufSJdfQ==