diff --git a/README.md b/README.md index 001b42f..3eb2feb 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,7 @@ npm run build-dev 4. Choose how to annotate proteins (this will prob, because of https://github.com/MICommunity/ComplexViewer/issues/80): - myComplexViewer.setAnnotations("MI features"); //show features from MI data - myComplexViewer.setAnnotations("UniprotKB"); //show annotations from uniprot - myComplexViewer.setAnnotations("SuperFamily"); //from SuperFamily - myComplexViewer.setAnnotations("None"); //no annotations - myComplexViewer.setAnnotations("Interactor"); //colour bars and circles according to interactor (may help indicate stoichiometry) + // todo doc - see index.html for example, old way of doing should still be working 5. To change dataset without creating a new instance of the app, call the clear function, then call the readMijson() function with the new data: diff --git a/css/style.css b/css/style.css index da07ffc..50a24bf 100755 --- a/css/style.css +++ b/css/style.css @@ -57,54 +57,54 @@ } /*tables*/ -table { - width: 100%; - font-size: 0.9em; - left: auto; - position: relative; - margin-left: auto; - margin-right: auto; - border-collapse: collapse; - /* - background-color: rgba(255, 255, 255, 1); - */ - text-align: left; -} +/*table {*/ +/* width: 100%;*/ +/* font-size: 0.9em;*/ +/* left: auto;*/ +/* position: relative;*/ +/* margin-left: auto;*/ +/* margin-right: auto;*/ +/* border-collapse: collapse;*/ +/* !**/ +/* background-color: rgba(255, 255, 255, 1);*/ +/* *!*/ +/* text-align: left;*/ +/*}*/ -thead { - margin-top: 10px; - margin-bottom: 10px; -} +/*thead {*/ +/* margin-top: 10px;*/ +/* margin-bottom: 10px;*/ +/*}*/ -th { - padding-left: 5px; - padding-right: 5px; - vertical-align: middle; - height: 30px; -} +/*th {*/ +/* padding-left: 5px;*/ +/* padding-right: 5px;*/ +/* vertical-align: middle;*/ +/* height: 30px;*/ +/*}*/ -td { - padding-left: 5px; - padding-right: 5px; - vertical-align: middle; - text-align: left; -} +/*td {*/ +/* padding-left: 5px;*/ +/* padding-right: 5px;*/ +/* vertical-align: middle;*/ +/* text-align: left;*/ +/*}*/ -th:first-child { - padding-left: 10px; -} +/*th:first-child {*/ +/* padding-left: 10px;*/ +/*}*/ -th:last-child { - padding-right: 10px; -} +/*th:last-child {*/ +/* padding-right: 10px;*/ +/*}*/ -td:first-child { - padding-left: 10px; -} +/*td:first-child {*/ +/* padding-left: 10px;*/ +/*}*/ -td:last-child { - padding-right: 10px; -} +/*td:last-child {*/ +/* padding-right: 10px;*/ +/*}*/ /* fa */ @@ -152,19 +152,19 @@ body, input, select, textarea, button { color: #fff; } -.tableContainer a { - color: #091D42; - text-decoration: underline; - -webkit-transition: all 200ms ease-in-out; - -moz-transition: all 200ms ease-in-out; - -o-transition: all 200ms ease-in-out; - transition: all 200ms ease-in-out; -} +/*.tableContainer a {*/ +/* color: #091D42;*/ +/* text-decoration: underline;*/ +/* -webkit-transition: all 200ms ease-in-out;*/ +/* -moz-transition: all 200ms ease-in-out;*/ +/* -o-transition: all 200ms ease-in-out;*/ +/* transition: all 200ms ease-in-out;*/ +/*}*/ -.tableContainer a:hover { - color: #ffffff !important; - background-color: #091D42; -} +/*.tableContainer a:hover {*/ +/* color: #ffffff !important;*/ +/* background-color: #091D42;*/ +/*}*/ #main { @@ -184,49 +184,6 @@ body, input, select, textarea, button { padding-left: 10px; } - -/* -#networkDiv { - width:100%; - height:100%; - display:block; -} -*/ - -/*.bar rect { - fill: steelblue; -} - -.bar text { - fill: #fff; -} - -.resize path { - fill: #888; - stroke: #000; - stroke-width: 2px; -} - -.axis path, .axis line { - fill: none; - stroke: #000; - stroke-width: 1px; -} - -.panelInner th { - font-weight: 400; - color: #039; - height: 30px; -} - -.panelInner thead td { - color: #091D42; -} - -.panelInner td, .helpPanel td { - color: #777; -}*/ - .controls { background: #ecedf2; color: #091D42; @@ -240,33 +197,27 @@ body, input, select, textarea, button { /* margin-right: 0.5em;*/ /*}*/ -label.horizontalFlow input[type=number] { - margin-left: 0.2em; -} - -/* See http://jsfiddle.net/7jx02upg/1/ */ -label.horizontalFlow input[type=radio], label.horizontalFlow input[type=checkbox] { - /*vertical-align: normal;*/ -} +/*label.horizontalFlow input[type=number] {*/ +/* margin-left: 0.2em;*/ +/*}*/ -/* +/*!* See http://jsfiddle.net/7jx02upg/1/ *!*/ +/*label.horizontalFlow input[type=radio], label.horizontalFlow input[type=checkbox] {*/ +/* !*vertical-align: normal;*!*/ +/*}*/ -/* span.noBreak asks for no line-breaks internally */ +/*!* */ -span.noBreak select { - margin-left: 0.5em; -} +/*!* span.noBreak asks for no line-breaks internally *!*/ -/* and then put spaces after labels to give a known place for content to break */ +/*span.noBreak select {*/ +/* margin-left: 0.5em;*/ +/*}*/ -A.btn { - text-decoration: none; -} +/*!* and then put spaces after labels to give a known place for content to break *!*/ -/* For use with Split.js */ +/*A.btn {*/ +/* text-decoration: none;*/ +/*}*/ -.btn:disabled { - color: gray; - border-color: gray; -} diff --git a/data/index.js b/data/index.js index 2a10fc3..a6db25e 100644 --- a/data/index.js +++ b/data/index.js @@ -1,5 +1,10 @@ // eslint-disable-next-line no-unused-vars const exampleIndex = [ + { + "ac": "CPX-1920", + "name": "~CPX-1920", + "url": "https://www.ebi.ac.uk/complexportal/complex/CPX-1920", + }, { "ac": "EBI-9008420", "name": "Hemoglobin HbA complex", @@ -10,11 +15,6 @@ const exampleIndex = [ "name": "EBI-12598622", "url": "https://ebi-intact.github.io/intact-view/details/interaction/EBI-12598622", }, - { - "ac": "CPX-1920", - "name": "~CPX-1920", - "url": "https://www.ebi.ac.uk/complexportal/complex/CPX-1920", - }, { "ac": "EBI-4371590", "name": "EBI-4371590", diff --git a/dist/complexviewer.js b/dist/complexviewer.js index a0186e7..f63fd56 100644 --- a/dist/complexviewer.js +++ b/dist/complexviewer.js @@ -103,7 +103,7 @@ return /******/ (function(modules) { // webpackBootstrap /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { -eval("// Imports\nvar ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.i, \".protein {\\n cursor: crosshair;\\n}\\n\\n.link {\\n /*\\n cursor: crosshair;\\n */\\n}\\n\\n/*you need this to stop horrible looking flickering of text as you drag*/\\nsvg {\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n user-select: none;\\n}\\n\\n.xlv_text {\\n /*font-weight: bold;*/\\n text-shadow: -1px -1px 0 white,\\n 1px -1px 0 white,\\n -1px 1px 0 white,\\n 1px 1px 0 white;\\n /* -2px -1px 0 white,\\n 2px -1px 0 white,\\n -2px 1px 0 white,\\n 2px 1px 0 white;*/\\n}\\n\\n.proteinLabel {\\n font-size: 10pt;\\n /*font-weight: bold;*/\\n}\\n\\n.custom-menu-margin {\\n padding: 20px;\\n display: none;\\n z-index: 10000;\\n position: absolute;\\n}\\n\\n.custom-menu {\\n overflow: hidden;\\n border: 1px solid #CCC;\\n white-space: nowrap;\\n /*\\n font-family: sans-serif;\\n*/\\n background: #FFF;\\n color: #333;\\n list-style: none;\\n padding: 0;\\n margin: 0;\\n pointer-events: all;\\n}\\n\\n.custom-menu li {\\n padding: 8px 12px;\\n cursor: pointer;\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n user-select: none;\\n}\\n\\n.custom-menu li:hover {\\n background-color: #DEF;\\n}\\n\\n.barScale {\\n display: inline;\\n padding-left: 10px;\\n}\\n\", \"\"]);\n// Exports\nmodule.exports = exports;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3NyYy9jc3MveGluZXQuY3NzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9jc3MveGluZXQuY3NzP2Y0YzQiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xudmFyIF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyA9IHJlcXVpcmUoXCIuLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCIpO1xuZXhwb3J0cyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhmYWxzZSk7XG4vLyBNb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi5wcm90ZWluIHtcXG4gICAgY3Vyc29yOiBjcm9zc2hhaXI7XFxufVxcblxcbi5saW5rIHtcXG4gICAgLypcXG4gICAgICAgY3Vyc29yOiBjcm9zc2hhaXI7XFxuICAgICovXFxufVxcblxcbi8qeW91IG5lZWQgdGhpcyB0byBzdG9wIGhvcnJpYmxlIGxvb2tpbmcgZmxpY2tlcmluZyBvZiB0ZXh0IGFzIHlvdSBkcmFnKi9cXG5zdmcge1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuXFxuLnhsdl90ZXh0IHtcXG4gICAgLypmb250LXdlaWdodDogYm9sZDsqL1xcbiAgICB0ZXh0LXNoYWRvdzogLTFweCAtMXB4IDAgd2hpdGUsXFxuICAgIDFweCAtMXB4IDAgd2hpdGUsXFxuICAgIC0xcHggMXB4IDAgd2hpdGUsXFxuICAgIDFweCAxcHggMCB3aGl0ZTtcXG4gICAgLyogICAtMnB4IC0xcHggMCB3aGl0ZSxcXG4gICAgICAgIDJweCAtMXB4IDAgd2hpdGUsXFxuICAgICAgICAtMnB4IDFweCAwIHdoaXRlLFxcbiAgICAgICAgMnB4IDFweCAwIHdoaXRlOyovXFxufVxcblxcbi5wcm90ZWluTGFiZWwge1xcbiAgICBmb250LXNpemU6IDEwcHQ7XFxuICAgIC8qZm9udC13ZWlnaHQ6IGJvbGQ7Ki9cXG59XFxuXFxuLmN1c3RvbS1tZW51LW1hcmdpbiB7XFxuICAgIHBhZGRpbmc6IDIwcHg7XFxuICAgIGRpc3BsYXk6IG5vbmU7XFxuICAgIHotaW5kZXg6IDEwMDAwO1xcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XFxufVxcblxcbi5jdXN0b20tbWVudSB7XFxuICAgIG92ZXJmbG93OiBoaWRkZW47XFxuICAgIGJvcmRlcjogMXB4IHNvbGlkICNDQ0M7XFxuICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XFxuICAgIC8qXFxuICBmb250LWZhbWlseTogc2Fucy1zZXJpZjtcXG4qL1xcbiAgICBiYWNrZ3JvdW5kOiAjRkZGO1xcbiAgICBjb2xvcjogIzMzMztcXG4gICAgbGlzdC1zdHlsZTogbm9uZTtcXG4gICAgcGFkZGluZzogMDtcXG4gICAgbWFyZ2luOiAwO1xcbiAgICBwb2ludGVyLWV2ZW50czogYWxsO1xcbn1cXG5cXG4uY3VzdG9tLW1lbnUgbGkge1xcbiAgICBwYWRkaW5nOiA4cHggMTJweDtcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuXFxuLmN1c3RvbS1tZW51IGxpOmhvdmVyIHtcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogI0RFRjtcXG59XFxuXFxuLmJhclNjYWxlIHtcXG4gICAgZGlzcGxheTogaW5saW5lO1xcbiAgICBwYWRkaW5nLWxlZnQ6IDEwcHg7XFxufVxcblwiLCBcIlwiXSk7XG4vLyBFeHBvcnRzXG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHM7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/css-loader/dist/cjs.js!./src/css/xinet.css\n"); +eval("// Imports\nvar ___CSS_LOADER_API_IMPORT___ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\nexports = ___CSS_LOADER_API_IMPORT___(false);\n// Module\nexports.push([module.i, \"/*you need this to stop horrible looking flickering of text as you drag*/\\nsvg {\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n user-select: none;\\n}\\n\\n.highlight {\\n stroke: #ffff99;\\n}\\n\\n.link {\\n stroke-linecap: round;\\n stroke: black;\\n}\\n\\n.certain-link {\\n opacity: 0.6;\\n stroke-opacity: 0.6;\\n}\\n\\n.uncertain-link {\\n opacity: 0.2;\\n stroke-opacity: 0.6;\\n}\\n\\n.link-line {\\n stroke-width: 1;\\n}\\n\\n.link-highlight {\\n stroke-width: 10;\\n stroke-opacity: 0;\\n}\\n\\n.complex-outline {\\n stroke: white;\\n stroke-linejoin: round;\\n stroke-width: 7;\\n}\\n\\n.linked-complex {\\n stroke: black;\\n stroke-linejoin: round;\\n stroke-width: 1;\\n}\\n\\nfeature-link {\\n fill: black;\\n}\\n\\n.protein {\\n cursor: crosshair;\\n}\\n\\n/*todo - seperate out outline*/\\n.label {\\n font-size: 10pt;\\n /*font-weight: bold;*/\\n\\n /*color: #fff;*/\\n /*text-shadow: white 0px 0px 1px;*/\\n -webkit-font-smoothing: antialiased;\\n\\n /*text-shadow: #fff 0px 0px 1px, #fff 0px 0px 1px, #fff 0px 0px 1px,*/\\n /*#fff 0px 0px 1px, #fff 0px 0px 1px, #fff 0px 0px 1px;*/\\n\\n text-shadow: -1px -1px 0 white,\\n 1px -1px 0 white,\\n -1px 1px 0 white,\\n 1px 1px 0 white;\\n /*-2px -1px 0 white,*/\\n /* 2px -1px 0 white,*/\\n /* -2px 1px 0 white,*/\\n /* 2px 1px 0 white;*/\\n fill: black;\\n text-anchor: end;\\n}\\n\\n.tooltip{\\n text-anchor: start;\\n}\\n\\n.outline {\\n stroke: black;\\n stroke-width: 1;\\n stroke-opacity: 1;\\n fill: white;\\n fill-opacity: 1;\\n}\\n\\n.participant-highlight {\\n stroke-width: 5;\\n fill: none;\\n}\\n\\n/*for protein bar scale*/\\n.tick {\\n stroke: black;\\n}\\n\\n.tick-labels {\\n font-size: 8pt;\\n text-anchor: middle;\\n}\\n\\n/*not working right*/\\n.sequence {\\n font-family: 'Courier New', monospace;\\n font-size: 10px;\\n text-anchor: middle;\\n}\\n\\n.custom-menu-margin {\\n padding: 20px;\\n display: none;\\n z-index: 10000;\\n position: absolute;\\n}\\n\\n.custom-menu {\\n overflow: hidden;\\n border: 1px solid #CCC;\\n white-space: nowrap;\\n background: #FFF;\\n color: #333;\\n list-style: none;\\n padding: 0;\\n margin: 0;\\n pointer-events: all;\\n}\\n\\n.custom-menu li {\\n padding: 8px 12px;\\n cursor: pointer;\\n -webkit-user-select: none;\\n -moz-user-select: none;\\n user-select: none;\\n}\\n\\n.custom-menu li:hover {\\n background-color: #DEF;\\n}\\n\\n.barScale {\\n display: inline;\\n padding-left: 10px;\\n}\\n\\n.tooltip-background {\\n fill-opacity: 0.75;\\n stroke-opacity: 1;\\n stroke-width: 1;\\n}\\n\\n.tooltip-sub-background {\\n fill: white;\\n stroke: white;\\n opacity: 1;\\n stroke-width: 1;\\n}\", \"\"]);\n// Exports\nmodule.exports = exports;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L2Nqcy5qcyEuL3NyYy9jc3MveGluZXQuY3NzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9jc3MveGluZXQuY3NzP2Y0YzQiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gSW1wb3J0c1xudmFyIF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyA9IHJlcXVpcmUoXCIuLi8uLi9ub2RlX21vZHVsZXMvY3NzLWxvYWRlci9kaXN0L3J1bnRpbWUvYXBpLmpzXCIpO1xuZXhwb3J0cyA9IF9fX0NTU19MT0FERVJfQVBJX0lNUE9SVF9fXyhmYWxzZSk7XG4vLyBNb2R1bGVcbmV4cG9ydHMucHVzaChbbW9kdWxlLmlkLCBcIi8qeW91IG5lZWQgdGhpcyB0byBzdG9wIGhvcnJpYmxlIGxvb2tpbmcgZmxpY2tlcmluZyBvZiB0ZXh0IGFzIHlvdSBkcmFnKi9cXG5zdmcge1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuXFxuLmhpZ2hsaWdodCB7XFxuICAgIHN0cm9rZTogI2ZmZmY5OTtcXG59XFxuXFxuLmxpbmsge1xcbiAgICBzdHJva2UtbGluZWNhcDogcm91bmQ7XFxuICAgIHN0cm9rZTogYmxhY2s7XFxufVxcblxcbi5jZXJ0YWluLWxpbmsge1xcbiAgICBvcGFjaXR5OiAwLjY7XFxuICAgIHN0cm9rZS1vcGFjaXR5OiAwLjY7XFxufVxcblxcbi51bmNlcnRhaW4tbGluayB7XFxuICAgIG9wYWNpdHk6IDAuMjtcXG4gICAgc3Ryb2tlLW9wYWNpdHk6IDAuNjtcXG59XFxuXFxuLmxpbmstbGluZSB7XFxuICAgIHN0cm9rZS13aWR0aDogMTtcXG59XFxuXFxuLmxpbmstaGlnaGxpZ2h0IHtcXG4gICAgc3Ryb2tlLXdpZHRoOiAxMDtcXG4gICAgc3Ryb2tlLW9wYWNpdHk6IDA7XFxufVxcblxcbi5jb21wbGV4LW91dGxpbmUge1xcbiAgICBzdHJva2U6IHdoaXRlO1xcbiAgICBzdHJva2UtbGluZWpvaW46IHJvdW5kO1xcbiAgICBzdHJva2Utd2lkdGg6IDc7XFxufVxcblxcbi5saW5rZWQtY29tcGxleCB7XFxuICAgIHN0cm9rZTogYmxhY2s7XFxuICAgIHN0cm9rZS1saW5lam9pbjogcm91bmQ7XFxuICAgIHN0cm9rZS13aWR0aDogMTtcXG59XFxuXFxuZmVhdHVyZS1saW5rIHtcXG4gICAgZmlsbDogYmxhY2s7XFxufVxcblxcbi5wcm90ZWluIHtcXG4gICAgY3Vyc29yOiBjcm9zc2hhaXI7XFxufVxcblxcbi8qdG9kbyAtIHNlcGVyYXRlIG91dCBvdXRsaW5lKi9cXG4ubGFiZWwge1xcbiAgICBmb250LXNpemU6IDEwcHQ7XFxuICAgIC8qZm9udC13ZWlnaHQ6IGJvbGQ7Ki9cXG5cXG4gICAgLypjb2xvcjogI2ZmZjsqL1xcbiAgICAvKnRleHQtc2hhZG93OiB3aGl0ZSAwcHggMHB4IDFweDsqL1xcbiAgICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDtcXG5cXG4gICAgLyp0ZXh0LXNoYWRvdzogI2ZmZiAwcHggMHB4IDFweCwgICAjZmZmIDBweCAwcHggMXB4LCAgICNmZmYgMHB4IDBweCAxcHgsKi9cXG4gICAgLyojZmZmIDBweCAwcHggMXB4LCAgICNmZmYgMHB4IDBweCAxcHgsICAgI2ZmZiAwcHggMHB4IDFweDsqL1xcblxcbiAgICB0ZXh0LXNoYWRvdzogLTFweCAtMXB4IDAgd2hpdGUsXFxuICAgIDFweCAtMXB4IDAgd2hpdGUsXFxuICAgIC0xcHggMXB4IDAgd2hpdGUsXFxuICAgIDFweCAxcHggMCB3aGl0ZTtcXG4gICAgICAgLyotMnB4IC0xcHggMCB3aGl0ZSwqL1xcbiAgICAgICAvKiAycHggLTFweCAwIHdoaXRlLCovXFxuICAgICAgIC8qIC0ycHggMXB4IDAgd2hpdGUsKi9cXG4gICAgICAgLyogMnB4IDFweCAwIHdoaXRlOyovXFxuICAgIGZpbGw6IGJsYWNrO1xcbiAgICB0ZXh0LWFuY2hvcjogZW5kO1xcbn1cXG5cXG4udG9vbHRpcHtcXG4gICAgdGV4dC1hbmNob3I6IHN0YXJ0O1xcbn1cXG5cXG4ub3V0bGluZSB7XFxuICAgIHN0cm9rZTogYmxhY2s7XFxuICAgIHN0cm9rZS13aWR0aDogMTtcXG4gICAgc3Ryb2tlLW9wYWNpdHk6IDE7XFxuICAgIGZpbGw6IHdoaXRlO1xcbiAgICBmaWxsLW9wYWNpdHk6IDE7XFxufVxcblxcbi5wYXJ0aWNpcGFudC1oaWdobGlnaHQge1xcbiAgICBzdHJva2Utd2lkdGg6IDU7XFxuICAgIGZpbGw6IG5vbmU7XFxufVxcblxcbi8qZm9yIHByb3RlaW4gYmFyIHNjYWxlKi9cXG4udGljayB7XFxuICAgIHN0cm9rZTogYmxhY2s7XFxufVxcblxcbi50aWNrLWxhYmVscyB7XFxuICAgIGZvbnQtc2l6ZTogOHB0O1xcbiAgICB0ZXh0LWFuY2hvcjogbWlkZGxlO1xcbn1cXG5cXG4vKm5vdCB3b3JraW5nIHJpZ2h0Ki9cXG4uc2VxdWVuY2Uge1xcbiAgICBmb250LWZhbWlseTogJ0NvdXJpZXIgTmV3JywgbW9ub3NwYWNlO1xcbiAgICBmb250LXNpemU6IDEwcHg7XFxuICAgIHRleHQtYW5jaG9yOiBtaWRkbGU7XFxufVxcblxcbi5jdXN0b20tbWVudS1tYXJnaW4ge1xcbiAgICBwYWRkaW5nOiAyMHB4O1xcbiAgICBkaXNwbGF5OiBub25lO1xcbiAgICB6LWluZGV4OiAxMDAwMDtcXG4gICAgcG9zaXRpb246IGFic29sdXRlO1xcbn1cXG5cXG4uY3VzdG9tLW1lbnUge1xcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjQ0NDO1xcbiAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xcbiAgICBiYWNrZ3JvdW5kOiAjRkZGO1xcbiAgICBjb2xvcjogIzMzMztcXG4gICAgbGlzdC1zdHlsZTogbm9uZTtcXG4gICAgcGFkZGluZzogMDtcXG4gICAgbWFyZ2luOiAwO1xcbiAgICBwb2ludGVyLWV2ZW50czogYWxsO1xcbn1cXG5cXG4uY3VzdG9tLW1lbnUgbGkge1xcbiAgICBwYWRkaW5nOiA4cHggMTJweDtcXG4gICAgY3Vyc29yOiBwb2ludGVyO1xcbiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lO1xcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcXG59XFxuXFxuLmN1c3RvbS1tZW51IGxpOmhvdmVyIHtcXG4gICAgYmFja2dyb3VuZC1jb2xvcjogI0RFRjtcXG59XFxuXFxuLmJhclNjYWxlIHtcXG4gICAgZGlzcGxheTogaW5saW5lO1xcbiAgICBwYWRkaW5nLWxlZnQ6IDEwcHg7XFxufVxcblxcbi50b29sdGlwLWJhY2tncm91bmQge1xcbiAgICBmaWxsLW9wYWNpdHk6IDAuNzU7XFxuICAgIHN0cm9rZS1vcGFjaXR5OiAxO1xcbiAgICBzdHJva2Utd2lkdGg6IDE7XFxufVxcblxcbi50b29sdGlwLXN1Yi1iYWNrZ3JvdW5kIHtcXG4gICAgZmlsbDogd2hpdGU7XFxuICAgIHN0cm9rZTogd2hpdGU7XFxuICAgIG9wYWNpdHk6IDE7XFxuICAgIHN0cm9rZS13aWR0aDogMTtcXG59XCIsIFwiXCJdKTtcbi8vIEV4cG9ydHNcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cztcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/css-loader/dist/cjs.js!./src/css/xinet.css\n"); /***/ }), @@ -1130,7 +1130,7 @@ eval("var api = __webpack_require__(/*! ../../node_modules/style-loader/dist/run /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"fetchAnnotations\", function() { return fetchAnnotations; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"chooseColors\", function() { return chooseColors; });\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! d3-scale-chromatic */ \"./node_modules/d3-scale-chromatic/src/index.js\");\n/* harmony import */ var _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./viz/interactor/annotation */ \"./src/js/viz/interactor/annotation.js\");\n/* harmony import */ var _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./viz/sequence-datum */ \"./src/js/viz/sequence-datum.js\");\n\n\n\n\n\n\n//todo - cache annotations in memory\nfunction fetchAnnotations(annotationChoice, /*App*/ app, callback) {\n annotationChoice = annotationChoice.toUpperCase();\n // we only show annotations on proteins\n const proteins = Array.from(app.participants.values()).filter(function (value) {\n return value.type === \"protein\";\n });\n\n function clearHighlights(){\n for (let prot of proteins){\n prot.showHighlight(false);\n }\n }\n let protsAnnotated = 0;\n const molCount = proteins.length;\n\n if (annotationChoice === \"INTERACTOR\") {\n if (app.proteinCount < 21) {\n for (let prot of proteins) {\n const annotation = new _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__[\"Annotation\"](prot.json.label, new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, 1 + \"-\" + prot.size));\n let annotations = prot.annotationSets.get(annotationChoice);\n if (typeof annotationSet === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(annotationChoice, annotations);\n }\n annotations.push(annotation);\n }\n // app.annotationSetsShown.set(\"INTERACTOR\", true);\n } else {\n alert(\"Too many (> 20) - can't color by interactor.\");\n }\n callback();\n } else if (annotationChoice.toUpperCase() === \"SUPERFAMILY\") {\n for (let prot of proteins) {\n getSuperFamFeatures(prot, function () {\n protsAnnotated++;\n if (protsAnnotated === molCount) {\n // clearHighlights();\n callback();\n }\n });\n }\n } else if (annotationChoice.toUpperCase() === \"UNIPROTKB\") {\n for (let prot of proteins) {\n getUniProtFeatures(prot, function () {\n protsAnnotated++;\n if (protsAnnotated === molCount) {\n // clearHighlights();\n callback();\n }\n });\n }\n }\n}\n\nfunction extractUniprotAccession(id) {\n const uniprotAccRegex = new RegExp(\"[OPQ][0-9][A-Z0-9]{3}[0-9]|[A-NR-Z][0-9]([A-Z][A-Z0-9]{2}[0-9]){1,2}\", \"i\");\n const match = uniprotAccRegex.exec(id);\n return match[0];\n}\n\nfunction getUniProtFeatures(prot, callback) {\n const url = \"https://www.ebi.ac.uk/proteins/api/proteins/\" + extractUniprotAccession(prot.id);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"json\"](url, function (json) {\n let annotations = prot.annotationSets.get(\"UNIPROTKB\");\n if (typeof annotations === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(\"UNIPROTKB\", annotations);\n }\n var uniprotJsonFeatures = json.features.filter(function (ft) {\n return ft.type === \"DOMAIN\";\n });\n for (let feature of uniprotJsonFeatures) {\n feature.seqDatum = new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, feature.begin + \"-\" + feature.end);\n annotations.push(feature);\n }\n // prot.showHighlight(true);\n callback();\n });\n}\n\nfunction getSuperFamFeatures(prot, callback) {\n const url = \"https://supfam.mrc-lmb.cam.ac.uk/SUPERFAMILY/cgi-bin/das/up/features?segment=\" + extractUniprotAccession(prot.id);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"xml\"](url, function (xml) {\n let annotations = prot.annotationSets.get(\"SUPERFAMILY\");\n if (typeof annotations === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(\"SUPERFAMILY\", annotations);\n }\n const xmlDoc = new DOMParser().parseFromString(new XMLSerializer().serializeToString(xml), \"text/xml\");\n const xmlFeatures = xmlDoc.getElementsByTagName(\"FEATURE\");\n for (let xmlFeature of xmlFeatures) {\n const type = xmlFeature.getElementsByTagName(\"TYPE\")[0]; //might need to watch for text nodes getting mixed in here\n const category = type.getAttribute(\"category\");\n if (category === \"miscellaneous\") {\n const name = type.getAttribute(\"id\");\n const start = xmlFeature.getElementsByTagName(\"START\")[0].textContent;\n const end = xmlFeature.getElementsByTagName(\"END\")[0].textContent;\n annotations.push(new _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__[\"Annotation\"](name, new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, start + \"-\" + end)));\n }\n }\n //~ console.log(JSON.stringify(features));\n // prot.showHighlight(true);\n callback();\n });\n}\n\nfunction chooseColors(app) {\n const categories = new Set();\n for (let participant of app.participants.values()) {\n for (let [annotationType, annotationSet] of participant.annotationSets) {\n if (app.annotationSetsShown.get(annotationType) === true) {\n for (let annotation of annotationSet.values()) {\n categories.add(annotation.description);\n }\n }\n }\n }\n\n let colorScheme;\n if (categories.size < 11) {\n colorScheme = d3__WEBPACK_IMPORTED_MODULE_0__[\"scale\"].ordinal().range(d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_1__[\"schemeTableau10\"]);//colorbrewer.Dark2[catCount].slice().reverse());\n // } else if (catCount < 13) {\n // // var reversed = colorbrewer.Paired[catCount];//.slice().reverse();\n // colorScheme = d3.scale.ordinal().range(d3_chromatic.schemeSet3);\n } else {\n colorScheme = d3__WEBPACK_IMPORTED_MODULE_0__[\"scale\"].category20();\n }\n\n for (let participant of app.participants.values()) {\n for (let [annotationType, annotations] of participant.annotationSets) {\n if (app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n\n let color;\n if (anno.description === \"No annotations\") {\n color = \"#eeeeee\";\n } else {\n color = colorScheme(anno.description);\n }\n\n //ToDO - way more of these are being created than needed\n app.createHatchedFill(\"checkers_\" + anno.description, color);\n const checkedFill = \"url('#checkers_\" + anno.description + \"')\";\n if (anno.fuzzyStart) {\n anno.fuzzyStart.setAttribute(\"fill\", checkedFill);\n // anno.fuzzyStart.setAttribute(\"stroke\", color);\n }\n if (anno.certain) {\n anno.certain.setAttribute(\"fill\", color);\n // anno.certain.setAttribute(\"stroke\", color);\n }\n if (anno.fuzzyEnd) {\n anno.fuzzyEnd.setAttribute(\"fill\", checkedFill);\n // anno.fuzzyEnd.setAttribute(\"stroke\", color);\n }\n }\n }\n }\n }\n\n app.featureColors = colorScheme;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvYW5ub3RhdGlvbnMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb21wbGV4dmlld2VyLy4vc3JjL2pzL2Fubm90YXRpb25zLmpzP2Y5OTIiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZDMgZnJvbSBcImQzXCI7XG5pbXBvcnQgKiBhcyBkM19jaHJvbWF0aWMgZnJvbSBcImQzLXNjYWxlLWNocm9tYXRpY1wiO1xuaW1wb3J0IHtBbm5vdGF0aW9ufSBmcm9tIFwiLi92aXovaW50ZXJhY3Rvci9hbm5vdGF0aW9uXCI7XG5pbXBvcnQge1NlcXVlbmNlRGF0dW19IGZyb20gXCIuL3Zpei9zZXF1ZW5jZS1kYXR1bVwiO1xuXG5cbi8vdG9kbyAtIGNhY2hlIGFubm90YXRpb25zIGluIG1lbW9yeVxuZXhwb3J0IGZ1bmN0aW9uIGZldGNoQW5ub3RhdGlvbnMoYW5ub3RhdGlvbkNob2ljZSwgLypBcHAqLyBhcHAsIGNhbGxiYWNrKSB7XG4gICAgYW5ub3RhdGlvbkNob2ljZSA9IGFubm90YXRpb25DaG9pY2UudG9VcHBlckNhc2UoKTtcbiAgICAvLyB3ZSBvbmx5IHNob3cgYW5ub3RhdGlvbnMgb24gcHJvdGVpbnNcbiAgICBjb25zdCBwcm90ZWlucyA9IEFycmF5LmZyb20oYXBwLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkuZmlsdGVyKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUudHlwZSA9PT0gXCJwcm90ZWluXCI7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBjbGVhckhpZ2hsaWdodHMoKXtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucyl7XG4gICAgICAgICAgICBwcm90LnNob3dIaWdobGlnaHQoZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBwcm90c0Fubm90YXRlZCA9IDA7XG4gICAgY29uc3QgbW9sQ291bnQgPSBwcm90ZWlucy5sZW5ndGg7XG5cbiAgICBpZiAoYW5ub3RhdGlvbkNob2ljZSA9PT0gXCJJTlRFUkFDVE9SXCIpIHtcbiAgICAgICAgaWYgKGFwcC5wcm90ZWluQ291bnQgPCAyMSkge1xuICAgICAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFubm90YXRpb24gPSBuZXcgQW5ub3RhdGlvbihwcm90Lmpzb24ubGFiZWwsIG5ldyBTZXF1ZW5jZURhdHVtKG51bGwsIDEgKyBcIi1cIiArIHByb3Quc2l6ZSkpO1xuICAgICAgICAgICAgICAgIGxldCBhbm5vdGF0aW9ucyA9IHByb3QuYW5ub3RhdGlvblNldHMuZ2V0KGFubm90YXRpb25DaG9pY2UpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgYW5ub3RhdGlvblNldCA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgICAgICAgICBhbm5vdGF0aW9ucyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBwcm90LmFubm90YXRpb25TZXRzLnNldChhbm5vdGF0aW9uQ2hvaWNlLCBhbm5vdGF0aW9ucyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGFubm90YXRpb25zLnB1c2goYW5ub3RhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBhcHAuYW5ub3RhdGlvblNldHNTaG93bi5zZXQoXCJJTlRFUkFDVE9SXCIsIHRydWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWxlcnQoXCJUb28gbWFueSAoPiAyMCkgLSBjYW4ndCBjb2xvciBieSBpbnRlcmFjdG9yLlwiKTtcbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH0gZWxzZSBpZiAoYW5ub3RhdGlvbkNob2ljZS50b1VwcGVyQ2FzZSgpID09PSBcIlNVUEVSRkFNSUxZXCIpIHtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucykge1xuICAgICAgICAgICAgZ2V0U3VwZXJGYW1GZWF0dXJlcyhwcm90LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvdHNBbm5vdGF0ZWQrKztcbiAgICAgICAgICAgICAgICBpZiAocHJvdHNBbm5vdGF0ZWQgPT09IG1vbENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNsZWFySGlnaGxpZ2h0cygpO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChhbm5vdGF0aW9uQ2hvaWNlLnRvVXBwZXJDYXNlKCkgPT09IFwiVU5JUFJPVEtCXCIpIHtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucykge1xuICAgICAgICAgICAgZ2V0VW5pUHJvdEZlYXR1cmVzKHByb3QsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBwcm90c0Fubm90YXRlZCsrO1xuICAgICAgICAgICAgICAgIGlmIChwcm90c0Fubm90YXRlZCA9PT0gbW9sQ291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gY2xlYXJIaWdobGlnaHRzKCk7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKGlkKSB7XG4gICAgY29uc3QgdW5pcHJvdEFjY1JlZ2V4ID0gbmV3IFJlZ0V4cChcIltPUFFdWzAtOV1bQS1aMC05XXszfVswLTldfFtBLU5SLVpdWzAtOV0oW0EtWl1bQS1aMC05XXsyfVswLTldKXsxLDJ9XCIsIFwiaVwiKTtcbiAgICBjb25zdCBtYXRjaCA9IHVuaXByb3RBY2NSZWdleC5leGVjKGlkKTtcbiAgICByZXR1cm4gbWF0Y2hbMF07XG59XG5cbmZ1bmN0aW9uIGdldFVuaVByb3RGZWF0dXJlcyhwcm90LCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHVybCA9IFwiaHR0cHM6Ly93d3cuZWJpLmFjLnVrL3Byb3RlaW5zL2FwaS9wcm90ZWlucy9cIiArIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKHByb3QuaWQpO1xuICAgIGQzLmpzb24odXJsLCBmdW5jdGlvbiAoanNvbikge1xuICAgICAgICBsZXQgYW5ub3RhdGlvbnMgPSBwcm90LmFubm90YXRpb25TZXRzLmdldChcIlVOSVBST1RLQlwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbm5vdGF0aW9ucyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIHByb3QuYW5ub3RhdGlvblNldHMuc2V0KFwiVU5JUFJPVEtCXCIsIGFubm90YXRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdW5pcHJvdEpzb25GZWF0dXJlcyA9IGpzb24uZmVhdHVyZXMuZmlsdGVyKGZ1bmN0aW9uIChmdCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ0LnR5cGUgPT09IFwiRE9NQUlOXCI7XG4gICAgICAgIH0pO1xuICAgICAgICBmb3IgKGxldCBmZWF0dXJlIG9mIHVuaXByb3RKc29uRmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGZlYXR1cmUuc2VxRGF0dW0gPSBuZXcgU2VxdWVuY2VEYXR1bShudWxsLCBmZWF0dXJlLmJlZ2luICsgXCItXCIgKyBmZWF0dXJlLmVuZCk7XG4gICAgICAgICAgICBhbm5vdGF0aW9ucy5wdXNoKGZlYXR1cmUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHByb3Quc2hvd0hpZ2hsaWdodCh0cnVlKTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0U3VwZXJGYW1GZWF0dXJlcyhwcm90LCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHVybCA9IFwiaHR0cHM6Ly9zdXBmYW0ubXJjLWxtYi5jYW0uYWMudWsvU1VQRVJGQU1JTFkvY2dpLWJpbi9kYXMvdXAvZmVhdHVyZXM/c2VnbWVudD1cIiArIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKHByb3QuaWQpO1xuICAgIGQzLnhtbCh1cmwsIGZ1bmN0aW9uICh4bWwpIHtcbiAgICAgICAgbGV0IGFubm90YXRpb25zID0gcHJvdC5hbm5vdGF0aW9uU2V0cy5nZXQoXCJTVVBFUkZBTUlMWVwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbm5vdGF0aW9ucyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIHByb3QuYW5ub3RhdGlvblNldHMuc2V0KFwiU1VQRVJGQU1JTFlcIiwgYW5ub3RhdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHhtbERvYyA9IG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcobmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyh4bWwpLCBcInRleHQveG1sXCIpO1xuICAgICAgICBjb25zdCB4bWxGZWF0dXJlcyA9IHhtbERvYy5nZXRFbGVtZW50c0J5VGFnTmFtZShcIkZFQVRVUkVcIik7XG4gICAgICAgIGZvciAobGV0IHhtbEZlYXR1cmUgb2YgeG1sRmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSB4bWxGZWF0dXJlLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiVFlQRVwiKVswXTsgLy9taWdodCBuZWVkIHRvIHdhdGNoIGZvciB0ZXh0IG5vZGVzIGdldHRpbmcgbWl4ZWQgaW4gaGVyZVxuICAgICAgICAgICAgY29uc3QgY2F0ZWdvcnkgPSB0eXBlLmdldEF0dHJpYnV0ZShcImNhdGVnb3J5XCIpO1xuICAgICAgICAgICAgaWYgKGNhdGVnb3J5ID09PSBcIm1pc2NlbGxhbmVvdXNcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSB0eXBlLmdldEF0dHJpYnV0ZShcImlkXCIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0geG1sRmVhdHVyZS5nZXRFbGVtZW50c0J5VGFnTmFtZShcIlNUQVJUXCIpWzBdLnRleHRDb250ZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IGVuZCA9IHhtbEZlYXR1cmUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJFTkRcIilbMF0udGV4dENvbnRlbnQ7XG4gICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMucHVzaChuZXcgQW5ub3RhdGlvbihuYW1lLCBuZXcgU2VxdWVuY2VEYXR1bShudWxsLCBzdGFydCArIFwiLVwiICsgZW5kKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vfiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShmZWF0dXJlcykpO1xuICAgICAgICAvLyBwcm90LnNob3dIaWdobGlnaHQodHJ1ZSk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaG9vc2VDb2xvcnMoYXBwKSB7XG4gICAgY29uc3QgY2F0ZWdvcmllcyA9IG5ldyBTZXQoKTtcbiAgICBmb3IgKGxldCBwYXJ0aWNpcGFudCBvZiBhcHAucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgICAgIGZvciAobGV0IFthbm5vdGF0aW9uVHlwZSwgYW5ub3RhdGlvblNldF0gb2YgcGFydGljaXBhbnQuYW5ub3RhdGlvblNldHMpIHtcbiAgICAgICAgICAgIGlmIChhcHAuYW5ub3RhdGlvblNldHNTaG93bi5nZXQoYW5ub3RhdGlvblR5cGUpID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYW5ub3RhdGlvbiBvZiBhbm5vdGF0aW9uU2V0LnZhbHVlcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhdGVnb3JpZXMuYWRkKGFubm90YXRpb24uZGVzY3JpcHRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxldCBjb2xvclNjaGVtZTtcbiAgICBpZiAoY2F0ZWdvcmllcy5zaXplIDwgMTEpIHtcbiAgICAgICAgY29sb3JTY2hlbWUgPSBkMy5zY2FsZS5vcmRpbmFsKCkucmFuZ2UoZDNfY2hyb21hdGljLnNjaGVtZVRhYmxlYXUxMCk7Ly9jb2xvcmJyZXdlci5EYXJrMltjYXRDb3VudF0uc2xpY2UoKS5yZXZlcnNlKCkpO1xuICAgICAgICAvLyB9IGVsc2UgaWYgKGNhdENvdW50IDwgMTMpIHtcbiAgICAgICAgLy8gICAgIC8vIHZhciByZXZlcnNlZCA9IGNvbG9yYnJld2VyLlBhaXJlZFtjYXRDb3VudF07Ly8uc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgICAgIC8vICAgICBjb2xvclNjaGVtZSA9IGQzLnNjYWxlLm9yZGluYWwoKS5yYW5nZShkM19jaHJvbWF0aWMuc2NoZW1lU2V0Myk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29sb3JTY2hlbWUgPSBkMy5zY2FsZS5jYXRlZ29yeTIwKCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgYXBwLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkge1xuICAgICAgICBmb3IgKGxldCBbYW5ub3RhdGlvblR5cGUsIGFubm90YXRpb25zXSBvZiBwYXJ0aWNpcGFudC5hbm5vdGF0aW9uU2V0cykge1xuICAgICAgICAgICAgaWYgKGFwcC5hbm5vdGF0aW9uU2V0c1Nob3duLmdldChhbm5vdGF0aW9uVHlwZSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBhbm5vIG9mIGFubm90YXRpb25zKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbG9yO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5kZXNjcmlwdGlvbiA9PT0gXCJObyBhbm5vdGF0aW9uc1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IFwiI2VlZWVlZVwiO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb2xvclNjaGVtZShhbm5vLmRlc2NyaXB0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vVG9ETyAtIHdheSBtb3JlIG9mIHRoZXNlIGFyZSBiZWluZyBjcmVhdGVkIHRoYW4gbmVlZGVkXG4gICAgICAgICAgICAgICAgICAgIGFwcC5jcmVhdGVIYXRjaGVkRmlsbChcImNoZWNrZXJzX1wiICsgYW5uby5kZXNjcmlwdGlvbiwgY29sb3IpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGVja2VkRmlsbCA9IFwidXJsKCcjY2hlY2tlcnNfXCIgKyBhbm5vLmRlc2NyaXB0aW9uICsgXCInKVwiO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eVN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmZ1enp5U3RhcnQuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBjaGVja2VkRmlsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbm5vLmZ1enp5U3RhcnQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5jZXJ0YWluKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBjb2xvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eUVuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIGNoZWNrZWRGaWxsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFubm8uZnV6enlFbmQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFwcC5mZWF0dXJlQ29sb3JzID0gY29sb3JTY2hlbWU7XG59Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/annotations.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"fetchAnnotations\", function() { return fetchAnnotations; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"chooseColors\", function() { return chooseColors; });\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! d3-scale-chromatic */ \"./node_modules/d3-scale-chromatic/src/index.js\");\n/* harmony import */ var _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./viz/interactor/annotation */ \"./src/js/viz/interactor/annotation.js\");\n/* harmony import */ var _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./viz/sequence-datum */ \"./src/js/viz/sequence-datum.js\");\n\n\n\n\n\n\n//todo - cache annotations in memory\nfunction fetchAnnotations(annotationChoice, /*App*/ app, callback) {\n annotationChoice = annotationChoice.toUpperCase();\n // we only show annotations on proteins\n const proteins = Array.from(app.participants.values()).filter(function (value) {\n return value.type === \"protein\";\n });\n\n function clearHighlights(){\n for (let prot of proteins){\n prot.showHighlight(false);\n }\n }\n let protsAnnotated = 0;\n const molCount = proteins.length;\n\n if (annotationChoice === \"INTERACTOR\") { //todo - move this out of here\n if (app.proteinCount < 21) {\n for (let prot of proteins) {\n const annotation = new _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__[\"Annotation\"](prot.json.label, new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, 1 + \"-\" + prot.size));\n let annotations = prot.annotationSets.get(annotationChoice);\n if (typeof annotationSet === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(annotationChoice, annotations);\n }\n annotations.push(annotation);\n }\n // app.annotationSetsShown.set(\"INTERACTOR\", true);\n } else {\n // alert(\"Too many (> 20) - can't color by interactor.\"); // people are gong to complain about why arent my interactor colours showing up\n }\n callback();\n } else if (annotationChoice.toUpperCase() === \"SUPERFAMILY\") {\n for (let prot of proteins) {\n getSuperFamFeatures(prot, function () {\n protsAnnotated++;\n if (protsAnnotated === molCount) {\n // clearHighlights();\n callback();\n }\n });\n }\n } else if (annotationChoice.toUpperCase() === \"UNIPROTKB\") {\n for (let prot of proteins) {\n getUniProtFeatures(prot, function () {\n protsAnnotated++;\n if (protsAnnotated === molCount) {\n // clearHighlights();\n callback();\n }\n });\n }\n }\n}\n\nfunction extractUniprotAccession(id) {\n const uniprotAccRegex = new RegExp(\"[OPQ][0-9][A-Z0-9]{3}[0-9]|[A-NR-Z][0-9]([A-Z][A-Z0-9]{2}[0-9]){1,2}\", \"i\");\n const match = uniprotAccRegex.exec(id);\n return match[0];\n}\n\nfunction getUniProtFeatures(prot, callback) {\n const url = \"https://www.ebi.ac.uk/proteins/api/proteins/\" + extractUniprotAccession(prot.id);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"json\"](url, function (json) {\n let annotations = prot.annotationSets.get(\"UNIPROTKB\");\n if (typeof annotations === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(\"UNIPROTKB\", annotations);\n }\n var uniprotJsonFeatures = json.features.filter(function (ft) {\n return ft.type === \"DOMAIN\";\n });\n for (let feature of uniprotJsonFeatures) {\n feature.seqDatum = new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, feature.begin + \"-\" + feature.end);\n annotations.push(feature);\n }\n // prot.showHighlight(true);\n callback();\n });\n}\n\nfunction getSuperFamFeatures(prot, callback) {\n const url = \"https://supfam.mrc-lmb.cam.ac.uk/SUPERFAMILY/cgi-bin/das/up/features?segment=\" + extractUniprotAccession(prot.id);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"xml\"](url, function (xml) {\n let annotations = prot.annotationSets.get(\"SUPERFAMILY\");\n if (typeof annotations === \"undefined\") {\n annotations = [];\n prot.annotationSets.set(\"SUPERFAMILY\", annotations);\n }\n const xmlDoc = new DOMParser().parseFromString(new XMLSerializer().serializeToString(xml), \"text/xml\");\n const xmlFeatures = xmlDoc.getElementsByTagName(\"FEATURE\");\n for (let xmlFeature of xmlFeatures) {\n const type = xmlFeature.getElementsByTagName(\"TYPE\")[0]; //might need to watch for text nodes getting mixed in here\n const category = type.getAttribute(\"category\");\n if (category === \"miscellaneous\") {\n const name = type.getAttribute(\"id\");\n const start = xmlFeature.getElementsByTagName(\"START\")[0].textContent;\n const end = xmlFeature.getElementsByTagName(\"END\")[0].textContent;\n annotations.push(new _viz_interactor_annotation__WEBPACK_IMPORTED_MODULE_2__[\"Annotation\"](name, new _viz_sequence_datum__WEBPACK_IMPORTED_MODULE_3__[\"SequenceDatum\"](null, start + \"-\" + end)));\n }\n }\n //~ console.log(JSON.stringify(features));\n // prot.showHighlight(true);\n callback();\n });\n}\n\nfunction chooseColors(app) {\n const categories = new Set();\n for (let participant of app.participants.values()) {\n for (let [annotationType, annotationSet] of participant.annotationSets) {\n if (app.annotationSetsShown.get(annotationType) === true) {\n for (let annotation of annotationSet.values()) {\n categories.add(annotation.description);\n }\n }\n }\n }\n\n let colorScheme;\n if (categories.size < 11) {\n colorScheme = d3__WEBPACK_IMPORTED_MODULE_0__[\"scale\"].ordinal().range(d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_1__[\"schemeTableau10\"]);//colorbrewer.Dark2[catCount].slice().reverse());\n // } else if (catCount < 13) {\n // // var reversed = colorbrewer.Paired[catCount];//.slice().reverse();\n // colorScheme = d3.scale.ordinal().range(d3_chromatic.schemeSet3);\n } else {\n colorScheme = d3__WEBPACK_IMPORTED_MODULE_0__[\"scale\"].category20();\n }\n\n for (let participant of app.participants.values()) {\n for (let [annotationType, annotations] of participant.annotationSets) {\n if (app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n\n let color;\n if (anno.description === \"No annotations\") {\n color = \"#eeeeee\";\n } else {\n color = colorScheme(anno.description);\n }\n\n //ToDO - way more of these are being created than needed\n app.createHatchedFill(\"checkers_\" + anno.description, color);\n const checkedFill = \"url('#checkers_\" + anno.description + \"')\";\n if (anno.fuzzyStart) {\n anno.fuzzyStart.setAttribute(\"fill\", checkedFill);\n // anno.fuzzyStart.setAttribute(\"stroke\", color);\n }\n if (anno.certain) {\n anno.certain.setAttribute(\"fill\", color);\n // anno.certain.setAttribute(\"stroke\", color);\n }\n if (anno.fuzzyEnd) {\n anno.fuzzyEnd.setAttribute(\"fill\", checkedFill);\n // anno.fuzzyEnd.setAttribute(\"stroke\", color);\n }\n }\n }\n }\n }\n\n app.featureColors = colorScheme;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvYW5ub3RhdGlvbnMuanMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb21wbGV4dmlld2VyLy4vc3JjL2pzL2Fubm90YXRpb25zLmpzP2Y5OTIiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZDMgZnJvbSBcImQzXCI7XG5pbXBvcnQgKiBhcyBkM19jaHJvbWF0aWMgZnJvbSBcImQzLXNjYWxlLWNocm9tYXRpY1wiO1xuaW1wb3J0IHtBbm5vdGF0aW9ufSBmcm9tIFwiLi92aXovaW50ZXJhY3Rvci9hbm5vdGF0aW9uXCI7XG5pbXBvcnQge1NlcXVlbmNlRGF0dW19IGZyb20gXCIuL3Zpei9zZXF1ZW5jZS1kYXR1bVwiO1xuXG5cbi8vdG9kbyAtIGNhY2hlIGFubm90YXRpb25zIGluIG1lbW9yeVxuZXhwb3J0IGZ1bmN0aW9uIGZldGNoQW5ub3RhdGlvbnMoYW5ub3RhdGlvbkNob2ljZSwgLypBcHAqLyBhcHAsIGNhbGxiYWNrKSB7XG4gICAgYW5ub3RhdGlvbkNob2ljZSA9IGFubm90YXRpb25DaG9pY2UudG9VcHBlckNhc2UoKTtcbiAgICAvLyB3ZSBvbmx5IHNob3cgYW5ub3RhdGlvbnMgb24gcHJvdGVpbnNcbiAgICBjb25zdCBwcm90ZWlucyA9IEFycmF5LmZyb20oYXBwLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkuZmlsdGVyKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUudHlwZSA9PT0gXCJwcm90ZWluXCI7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBjbGVhckhpZ2hsaWdodHMoKXtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucyl7XG4gICAgICAgICAgICBwcm90LnNob3dIaWdobGlnaHQoZmFsc2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBwcm90c0Fubm90YXRlZCA9IDA7XG4gICAgY29uc3QgbW9sQ291bnQgPSBwcm90ZWlucy5sZW5ndGg7XG5cbiAgICBpZiAoYW5ub3RhdGlvbkNob2ljZSA9PT0gXCJJTlRFUkFDVE9SXCIpIHsgLy90b2RvIC0gbW92ZSB0aGlzIG91dCBvZiBoZXJlXG4gICAgICAgIGlmIChhcHAucHJvdGVpbkNvdW50IDwgMjEpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHByb3Qgb2YgcHJvdGVpbnMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhbm5vdGF0aW9uID0gbmV3IEFubm90YXRpb24ocHJvdC5qc29uLmxhYmVsLCBuZXcgU2VxdWVuY2VEYXR1bShudWxsLCAxICsgXCItXCIgKyBwcm90LnNpemUpKTtcbiAgICAgICAgICAgICAgICBsZXQgYW5ub3RhdGlvbnMgPSBwcm90LmFubm90YXRpb25TZXRzLmdldChhbm5vdGF0aW9uQ2hvaWNlKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGFubm90YXRpb25TZXQgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgcHJvdC5hbm5vdGF0aW9uU2V0cy5zZXQoYW5ub3RhdGlvbkNob2ljZSwgYW5ub3RhdGlvbnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBhbm5vdGF0aW9ucy5wdXNoKGFubm90YXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gYXBwLmFubm90YXRpb25TZXRzU2hvd24uc2V0KFwiSU5URVJBQ1RPUlwiLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGFsZXJ0KFwiVG9vIG1hbnkgKD4gMjApIC0gY2FuJ3QgY29sb3IgYnkgaW50ZXJhY3Rvci5cIik7IC8vIHBlb3BsZSBhcmUgZ29uZyB0byBjb21wbGFpbiBhYm91dCB3aHkgYXJlbnQgbXkgaW50ZXJhY3RvciBjb2xvdXJzIHNob3dpbmcgdXBcbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH0gZWxzZSBpZiAoYW5ub3RhdGlvbkNob2ljZS50b1VwcGVyQ2FzZSgpID09PSBcIlNVUEVSRkFNSUxZXCIpIHtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucykge1xuICAgICAgICAgICAgZ2V0U3VwZXJGYW1GZWF0dXJlcyhwcm90LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcHJvdHNBbm5vdGF0ZWQrKztcbiAgICAgICAgICAgICAgICBpZiAocHJvdHNBbm5vdGF0ZWQgPT09IG1vbENvdW50KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGNsZWFySGlnaGxpZ2h0cygpO1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChhbm5vdGF0aW9uQ2hvaWNlLnRvVXBwZXJDYXNlKCkgPT09IFwiVU5JUFJPVEtCXCIpIHtcbiAgICAgICAgZm9yIChsZXQgcHJvdCBvZiBwcm90ZWlucykge1xuICAgICAgICAgICAgZ2V0VW5pUHJvdEZlYXR1cmVzKHByb3QsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBwcm90c0Fubm90YXRlZCsrO1xuICAgICAgICAgICAgICAgIGlmIChwcm90c0Fubm90YXRlZCA9PT0gbW9sQ291bnQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gY2xlYXJIaWdobGlnaHRzKCk7XG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKGlkKSB7XG4gICAgY29uc3QgdW5pcHJvdEFjY1JlZ2V4ID0gbmV3IFJlZ0V4cChcIltPUFFdWzAtOV1bQS1aMC05XXszfVswLTldfFtBLU5SLVpdWzAtOV0oW0EtWl1bQS1aMC05XXsyfVswLTldKXsxLDJ9XCIsIFwiaVwiKTtcbiAgICBjb25zdCBtYXRjaCA9IHVuaXByb3RBY2NSZWdleC5leGVjKGlkKTtcbiAgICByZXR1cm4gbWF0Y2hbMF07XG59XG5cbmZ1bmN0aW9uIGdldFVuaVByb3RGZWF0dXJlcyhwcm90LCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHVybCA9IFwiaHR0cHM6Ly93d3cuZWJpLmFjLnVrL3Byb3RlaW5zL2FwaS9wcm90ZWlucy9cIiArIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKHByb3QuaWQpO1xuICAgIGQzLmpzb24odXJsLCBmdW5jdGlvbiAoanNvbikge1xuICAgICAgICBsZXQgYW5ub3RhdGlvbnMgPSBwcm90LmFubm90YXRpb25TZXRzLmdldChcIlVOSVBST1RLQlwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbm5vdGF0aW9ucyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIHByb3QuYW5ub3RhdGlvblNldHMuc2V0KFwiVU5JUFJPVEtCXCIsIGFubm90YXRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdW5pcHJvdEpzb25GZWF0dXJlcyA9IGpzb24uZmVhdHVyZXMuZmlsdGVyKGZ1bmN0aW9uIChmdCkge1xuICAgICAgICAgICAgcmV0dXJuIGZ0LnR5cGUgPT09IFwiRE9NQUlOXCI7XG4gICAgICAgIH0pO1xuICAgICAgICBmb3IgKGxldCBmZWF0dXJlIG9mIHVuaXByb3RKc29uRmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGZlYXR1cmUuc2VxRGF0dW0gPSBuZXcgU2VxdWVuY2VEYXR1bShudWxsLCBmZWF0dXJlLmJlZ2luICsgXCItXCIgKyBmZWF0dXJlLmVuZCk7XG4gICAgICAgICAgICBhbm5vdGF0aW9ucy5wdXNoKGZlYXR1cmUpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHByb3Quc2hvd0hpZ2hsaWdodCh0cnVlKTtcbiAgICAgICAgY2FsbGJhY2soKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0U3VwZXJGYW1GZWF0dXJlcyhwcm90LCBjYWxsYmFjaykge1xuICAgIGNvbnN0IHVybCA9IFwiaHR0cHM6Ly9zdXBmYW0ubXJjLWxtYi5jYW0uYWMudWsvU1VQRVJGQU1JTFkvY2dpLWJpbi9kYXMvdXAvZmVhdHVyZXM/c2VnbWVudD1cIiArIGV4dHJhY3RVbmlwcm90QWNjZXNzaW9uKHByb3QuaWQpO1xuICAgIGQzLnhtbCh1cmwsIGZ1bmN0aW9uICh4bWwpIHtcbiAgICAgICAgbGV0IGFubm90YXRpb25zID0gcHJvdC5hbm5vdGF0aW9uU2V0cy5nZXQoXCJTVVBFUkZBTUlMWVwiKTtcbiAgICAgICAgaWYgKHR5cGVvZiBhbm5vdGF0aW9ucyA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgYW5ub3RhdGlvbnMgPSBbXTtcbiAgICAgICAgICAgIHByb3QuYW5ub3RhdGlvblNldHMuc2V0KFwiU1VQRVJGQU1JTFlcIiwgYW5ub3RhdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHhtbERvYyA9IG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcobmV3IFhNTFNlcmlhbGl6ZXIoKS5zZXJpYWxpemVUb1N0cmluZyh4bWwpLCBcInRleHQveG1sXCIpO1xuICAgICAgICBjb25zdCB4bWxGZWF0dXJlcyA9IHhtbERvYy5nZXRFbGVtZW50c0J5VGFnTmFtZShcIkZFQVRVUkVcIik7XG4gICAgICAgIGZvciAobGV0IHhtbEZlYXR1cmUgb2YgeG1sRmVhdHVyZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSB4bWxGZWF0dXJlLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiVFlQRVwiKVswXTsgLy9taWdodCBuZWVkIHRvIHdhdGNoIGZvciB0ZXh0IG5vZGVzIGdldHRpbmcgbWl4ZWQgaW4gaGVyZVxuICAgICAgICAgICAgY29uc3QgY2F0ZWdvcnkgPSB0eXBlLmdldEF0dHJpYnV0ZShcImNhdGVnb3J5XCIpO1xuICAgICAgICAgICAgaWYgKGNhdGVnb3J5ID09PSBcIm1pc2NlbGxhbmVvdXNcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWUgPSB0eXBlLmdldEF0dHJpYnV0ZShcImlkXCIpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0geG1sRmVhdHVyZS5nZXRFbGVtZW50c0J5VGFnTmFtZShcIlNUQVJUXCIpWzBdLnRleHRDb250ZW50O1xuICAgICAgICAgICAgICAgIGNvbnN0IGVuZCA9IHhtbEZlYXR1cmUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJFTkRcIilbMF0udGV4dENvbnRlbnQ7XG4gICAgICAgICAgICAgICAgYW5ub3RhdGlvbnMucHVzaChuZXcgQW5ub3RhdGlvbihuYW1lLCBuZXcgU2VxdWVuY2VEYXR1bShudWxsLCBzdGFydCArIFwiLVwiICsgZW5kKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vfiBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShmZWF0dXJlcykpO1xuICAgICAgICAvLyBwcm90LnNob3dIaWdobGlnaHQodHJ1ZSk7XG4gICAgICAgIGNhbGxiYWNrKCk7XG4gICAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjaG9vc2VDb2xvcnMoYXBwKSB7XG4gICAgY29uc3QgY2F0ZWdvcmllcyA9IG5ldyBTZXQoKTtcbiAgICBmb3IgKGxldCBwYXJ0aWNpcGFudCBvZiBhcHAucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgICAgIGZvciAobGV0IFthbm5vdGF0aW9uVHlwZSwgYW5ub3RhdGlvblNldF0gb2YgcGFydGljaXBhbnQuYW5ub3RhdGlvblNldHMpIHtcbiAgICAgICAgICAgIGlmIChhcHAuYW5ub3RhdGlvblNldHNTaG93bi5nZXQoYW5ub3RhdGlvblR5cGUpID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgYW5ub3RhdGlvbiBvZiBhbm5vdGF0aW9uU2V0LnZhbHVlcygpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNhdGVnb3JpZXMuYWRkKGFubm90YXRpb24uZGVzY3JpcHRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGxldCBjb2xvclNjaGVtZTtcbiAgICBpZiAoY2F0ZWdvcmllcy5zaXplIDwgMTEpIHtcbiAgICAgICAgY29sb3JTY2hlbWUgPSBkMy5zY2FsZS5vcmRpbmFsKCkucmFuZ2UoZDNfY2hyb21hdGljLnNjaGVtZVRhYmxlYXUxMCk7Ly9jb2xvcmJyZXdlci5EYXJrMltjYXRDb3VudF0uc2xpY2UoKS5yZXZlcnNlKCkpO1xuICAgICAgICAvLyB9IGVsc2UgaWYgKGNhdENvdW50IDwgMTMpIHtcbiAgICAgICAgLy8gICAgIC8vIHZhciByZXZlcnNlZCA9IGNvbG9yYnJld2VyLlBhaXJlZFtjYXRDb3VudF07Ly8uc2xpY2UoKS5yZXZlcnNlKCk7XG4gICAgICAgIC8vICAgICBjb2xvclNjaGVtZSA9IGQzLnNjYWxlLm9yZGluYWwoKS5yYW5nZShkM19jaHJvbWF0aWMuc2NoZW1lU2V0Myk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgY29sb3JTY2hlbWUgPSBkMy5zY2FsZS5jYXRlZ29yeTIwKCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgYXBwLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkge1xuICAgICAgICBmb3IgKGxldCBbYW5ub3RhdGlvblR5cGUsIGFubm90YXRpb25zXSBvZiBwYXJ0aWNpcGFudC5hbm5vdGF0aW9uU2V0cykge1xuICAgICAgICAgICAgaWYgKGFwcC5hbm5vdGF0aW9uU2V0c1Nob3duLmdldChhbm5vdGF0aW9uVHlwZSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBhbm5vIG9mIGFubm90YXRpb25zKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbG9yO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5kZXNjcmlwdGlvbiA9PT0gXCJObyBhbm5vdGF0aW9uc1wiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IFwiI2VlZWVlZVwiO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb2xvclNjaGVtZShhbm5vLmRlc2NyaXB0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vVG9ETyAtIHdheSBtb3JlIG9mIHRoZXNlIGFyZSBiZWluZyBjcmVhdGVkIHRoYW4gbmVlZGVkXG4gICAgICAgICAgICAgICAgICAgIGFwcC5jcmVhdGVIYXRjaGVkRmlsbChcImNoZWNrZXJzX1wiICsgYW5uby5kZXNjcmlwdGlvbiwgY29sb3IpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGVja2VkRmlsbCA9IFwidXJsKCcjY2hlY2tlcnNfXCIgKyBhbm5vLmRlc2NyaXB0aW9uICsgXCInKVwiO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eVN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmZ1enp5U3RhcnQuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBjaGVja2VkRmlsbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbm5vLmZ1enp5U3RhcnQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5jZXJ0YWluKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBjb2xvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eUVuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIGNoZWNrZWRGaWxsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFubm8uZnV6enlFbmQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGNvbG9yKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFwcC5mZWF0dXJlQ29sb3JzID0gY29sb3JTY2hlbWU7XG59Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/annotations.js\n"); /***/ }), @@ -1142,7 +1142,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"App\", function() { return App; });\n/* harmony import */ var _css_xinet_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../css/xinet.css */ \"./src/css/xinet.css\");\n/* harmony import */ var _css_xinet_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_xinet_css__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../package.json */ \"./package.json\");\nvar _package_json__WEBPACK_IMPORTED_MODULE_1___namespace = /*#__PURE__*/__webpack_require__.t(/*! ../../package.json */ \"./package.json\", 1);\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! d3-scale-chromatic */ \"./node_modules/d3-scale-chromatic/src/index.js\");\n/* harmony import */ var _cola__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./cola */ \"./src/js/cola.js\");\n/* harmony import */ var _cola__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_cola__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _read_mijson__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./read-mijson */ \"./src/js/read-mijson.js\");\n/* harmony import */ var _annotations__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./annotations */ \"./src/js/annotations.js\");\n/* harmony import */ var _color_scheme_key__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./color-scheme-key */ \"./src/js/color-scheme-key.js\");\n/* harmony import */ var _viz_link_nary_link__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./viz/link/nary-link */ \"./src/js/viz/link/nary-link.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./config */ \"./src/js/config.js\");\n// eslint-disable-next-line no-unused-vars\n\n\n\n\n\n\n\n\n// import {SymbolKey} from \"./symbol-key\";\n\n\n\n\n// could refactor everything to use ES6 class syntax\n// but https://benmccormick.org/2015/04/07/es6-classes-and-backbone-js\n// \"ES6 classes don’t support adding properties directly to the class instance, only functions/methods\"\n// so backbone doesn't work\n// so continuing to use prototypical inheritance in things for time being\n\nfunction App(/*HTMLDivElement*/networkDiv) {\n // this.debug = true; // things aren't exactly lined up in the bounding boxes cola is using, to do so breaks symetery of some things\n this.el = networkDiv;\n\n this.STATES = {};\n this.STATES.MOUSE_UP = 0; //start state, also set when mouse up on svgElement\n this.STATES.PANNING = 1; //set by mouse down on svgElement - left button, no shift or util\n this.STATES.DRAGGING = 2; //set by mouse down on Protein or Link\n this.STATES.ROTATING = 3; //set by mouse down on Rotator, drag?\n this.STATES.SELECTING = 4; //set by mouse down on svgElement- right button or left button shift or util, drag\n\n //avoids prob with 'save - web page complete'\n this.el.textContent = \"\"; //https://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript\n\n this.d3cola = _cola__WEBPACK_IMPORTED_MODULE_4__[\"d3adaptor\"]();\n\n const customMenuSel = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](this.el)\n .append(\"div\").classed(\"custom-menu-margin\", true)\n .append(\"div\").classed(\"custom-menu\", true)\n .append(\"ul\");\n\n const self = this;\n const collapse = customMenuSel.append(\"li\").classed(\"collapse\", true); //.append(\"button\");\n collapse.text(\"Collapse\");\n collapse[0][0].onclick = function (evt) {\n self.collapseProtein(evt);\n };\n const scaleButtonsListItemSel = customMenuSel.append(\"li\").text(\"Scale: \");\n\n this.barScales = [0.01, 0.2, 1, 2, 4, 8];\n const scaleButtons = scaleButtonsListItemSel.selectAll(\"ul.custom-menu\")\n .data(this.barScales)\n .enter()\n .append(\"div\")\n .attr(\"class\", \"barScale\")\n .append(\"label\");\n scaleButtons.append(\"span\")\n .text(function (d) {\n if (d === 8) return \"AA\";\n else return d;\n });\n scaleButtons.append(\"input\")\n // .attr (\"id\", function(d) { return d*100; })\n .attr(\"class\", function (d) {\n return \"scaleButton scaleButton_\" + (d * 100);\n })\n .attr(\"name\", \"scaleButtons\")\n .attr(\"type\", \"radio\")\n .on(\"change\", function (d) {\n self.preventDefaultsAndStopPropagation(d);\n self.contextMenuProt.setStickScale(d, self.contextMenuPoint);\n });\n\n const contextMenu = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".custom-menu-margin\").node();\n contextMenu.onmouseout = function (evt) {\n let e = evt.relatedTarget;\n do {\n if (e === this) return;\n e = e.parentNode;\n } while (e);\n self.contextMenuProt = null;\n d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](this).style(\"display\", \"none\");\n };\n\n\n //create SVG element\n this.svgElement = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"svg\");\n this.svgElement.setAttribute(\"id\", \"complexViewerSVG\");\n\n //add listeners\n this.svgElement.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.svgElement.onmousemove = function (evt) {\n self.mouseMove(evt);\n };\n this.svgElement.onmouseup = function (evt) {\n self.mouseUp(evt);\n };\n this.svgElement.onmouseout = function (evt) {\n self.hideTooltip(evt);\n };\n this.lastMouseUp = new Date().getTime();\n /*this.svgElement.ontouchstart = function(evt) {\n self.touchStart(evt);\n };\n this.svgElement.ontouchmove = function(evt) {\n self.touchMove(evt);\n };\n this.svgElement.ontouchend = function(evt) {\n self.touchEnd(evt);\n };\n */\n\n this.el.oncontextmenu = function (evt) {\n if (evt.preventDefault) { // necessary for addEventListener, works with traditional\n evt.preventDefault();\n }\n evt.returnValue = false; // necessary for attachEvent, works with traditional\n return false; // works with traditional, not with attachEvent or addEventListener\n };\n\n //legend changed callbacks\n this.colorSchemeKeyDivs = new Set();\n\n this.el.appendChild(this.svgElement);\n\n // various groups needed\n this.container = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.container.setAttribute(\"id\", \"container\");\n\n const svg = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](this.svgElement);\n this.defs = svg.append(\"defs\");\n this.createHatchedFill(\"checkers_uncertain\", \"black\");\n\n //markers\n const data = [{\n id: 1,\n name: \"diamond\",\n path: \"M 0,-7.0710768 L 0,7.0710589 L 7.0710462,0 z\",\n viewbox: \"-15 -15 25 25\",\n transform: \"scale(1.5) translate(-5,0)\",\n color: \"black\"\n }];\n\n this.defs.selectAll(\"marker\")\n .data(data)\n .enter()\n .append(\"svg:marker\")\n .attr(\"id\", function (d) {\n return \"marker_\" + d.name;\n })\n .attr(\"markerHeight\", 15)\n .attr(\"markerWidth\", 15)\n .attr(\"markerUnits\", \"userSpaceOnUse\")\n .attr(\"orient\", \"auto\")\n .attr(\"refX\", 0)\n .attr(\"refY\", 0)\n .attr(\"viewBox\", function (d) {\n return d.viewbox;\n })\n .append(\"svg:path\")\n .attr(\"d\", function (d) {\n return d.path;\n })\n .attr(\"fill\", function (d) {\n return d.color;\n })\n .attr(\"transform\", function (d) {\n return d.transform;\n });\n\n this.acknowledgement = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n const ackText = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"text\");\n ackText.innerHTML = \"ComplexViewer \"\n + _package_json__WEBPACK_IMPORTED_MODULE_1__[\"version\"] + \"by Rappsilber Laboratory\";\n\n this.acknowledgement.appendChild(ackText);\n ackText.classList.add(\"xlv_text\");\n ackText.setAttribute(\"font-size\", \"8pt\");\n this.svgElement.appendChild(this.acknowledgement);\n\n this.naryLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.naryLinks.setAttribute(\"id\", \"naryLinks\");\n this.container.appendChild(this.naryLinks);\n\n this.p_pLinksWide = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.p_pLinksWide.setAttribute(\"id\", \"p_pLinksWide\");\n this.container.appendChild(this.p_pLinksWide);\n\n this.highlights = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.highlights.setAttribute(\"class\", \"highlights\"); //interactors also contain highlight groups\n this.container.appendChild(this.highlights);\n\n this.res_resLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.res_resLinks.setAttribute(\"id\", \"res_resLinks\");\n this.container.appendChild(this.res_resLinks);\n\n this.p_pLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.p_pLinks.setAttribute(\"id\", \"p_pLinks\");\n this.container.appendChild(this.p_pLinks);\n\n this.proteinUpper = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.proteinUpper.setAttribute(\"id\", \"proteinUpper\");\n this.container.appendChild(this.proteinUpper);\n\n this.selfRes_resLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"g\");\n this.selfRes_resLinks.setAttribute(\"id\", \"res_resLinks\");\n this.container.appendChild(this.selfRes_resLinks);\n\n this.svgElement.appendChild(this.container);\n\n //showing title as tooltips is NOT part of svg spec (even though some browsers do this)\n //also more responsive / more control if we do out own\n this.tooltip = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"text\");\n this.tooltip.setAttribute(\"x\", \"0\");\n this.tooltip.setAttribute(\"y\", \"0\");\n this.tooltip.setAttribute(\"class\", \"xlv_text\");\n const tooltipTextNode = document.createTextNode(\"tooltip\");\n\n this.tooltip.appendChild(tooltipTextNode);\n\n this.tooltip_bg = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"rect\");\n this.tooltip_bg.setAttribute(\"class\", \"tooltip_bg\");\n\n this.tooltip_bg.setAttribute(\"fill-opacity\", \"0.75\");\n this.tooltip_bg.setAttribute(\"stroke-opacity\", \"1\");\n this.tooltip_bg.setAttribute(\"stroke-width\", \"1\");\n\n this.tooltip_subBg = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_9__[\"svgns\"], \"rect\");\n this.tooltip_subBg.setAttribute(\"fill\", \"white\");\n this.tooltip_subBg.setAttribute(\"stroke\", \"white\");\n this.tooltip_subBg.setAttribute(\"class\", \"tooltip_bg\");\n this.tooltip_subBg.setAttribute(\"opacity\", \"1\");\n this.tooltip_subBg.setAttribute(\"stroke-width\", \"1\");\n\n this.svgElement.appendChild(this.tooltip_subBg);\n this.svgElement.appendChild(this.tooltip_bg);\n this.svgElement.appendChild(this.tooltip);\n\n this.clear();\n}\n\nApp.prototype.createHatchedFill = function (name, color) {\n const pattern = this.defs.append(\"pattern\")\n .attr(\"id\", name)\n .attr(\"patternUnits\", \"userSpaceOnUse\")\n .attr(\"x\", 0)\n .attr(\"y\", 0)\n .attr(\"width\", 12)\n .attr(\"height\", 12)\n .attr(\"patternTransform\", \"rotate(45)\");\n\n pattern.append(\"rect\")\n .attr(\"x\", 0)\n .attr(\"y\", 2)\n .attr(\"width\", 12)\n .attr(\"height\", 4)\n .attr(\"fill\", color);\n\n pattern.append(\"rect\")\n .attr(\"x\", 0)\n .attr(\"y\", 8)\n .attr(\"width\", 12)\n .attr(\"height\", 4)\n .attr(\"fill\", color);\n};\n\nApp.prototype.clear = function () {\n this.d3cola.stop();\n\n this.annotationSetsShown = new Map();\n // this.annotationSetsShown.set(\"MI FEATURES\", true);\n\n //lighten colors\n const complexColors = [];\n for (let c of d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_3__[\"schemePastel2\"]) {//colorbrewer.Pastel2[8]) {\n const hsl = d3__WEBPACK_IMPORTED_MODULE_2__[\"hsl\"](c);\n hsl.l = 0.9;\n complexColors.push(hsl + \"\");\n }\n\n _viz_link_nary_link__WEBPACK_IMPORTED_MODULE_8__[\"NaryLink\"].naryColors = d3__WEBPACK_IMPORTED_MODULE_2__[\"scale\"].ordinal().range(complexColors);\n this.defs.selectAll(\".feature_checkers\").remove();\n\n this.naryLinks.textContent = \"\";\n this.p_pLinksWide.textContent = \"\";\n this.highlights.textContent = \"\";\n this.p_pLinks.textContent = \"\";\n this.res_resLinks.textContent = \"\";\n this.proteinUpper.textContent = \"\";\n this.selfRes_resLinks.textContent = \"\";\n\n // if we are dragging something at the moment - this will be the element that is dragged\n this.dragElement = null;\n // from where did we start dragging\n this.dragStart = {};\n\n this.participants = new Map();\n this.allNaryLinks = new Map();\n this.allBinaryLinks = new Map();\n this.allUnaryLinks = new Map();\n this.allSequenceLinks = new Map();\n this.complexes = [];\n\n this.proteinCount = 0;\n this.z = 1;\n this.hideTooltip();\n this.state = this.STATES.MOUSE_UP;\n};\n\nApp.prototype.collapseProtein = function () {\n d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".custom-menu-margin\").style(\"display\", \"none\");\n this.contextMenuProt.setForm(0, this.contextMenuPoint);\n this.contextMenuProt = null;\n};\n\nApp.prototype.init = function () {\n this.d3cola.stop();\n\n // let i = 0;\n for (let participant of this.participants.values()) {\n if (participant.type != \"complex\") {\n // let pos = rotatePointAboutPoint([0, -500], [0, 0], (360 / this.participants.size * i));\n participant.setPosition(-500, -500);//pos[0], pos[1]);\n // if (participant.type === \"protein\") {\n // participant.setPositionalFeatures();\n // }\n }\n // i++;\n }\n this.updateAnnotations();\n this.checkLinks(); //totally needed, not sure why tbh todo - check this out\n this.setAllLinkCoordinates(); // just to move them off screen at first\n\n let maxSeqLength = 0;\n for (let participant of this.participants.values()) {\n if (participant.size > maxSeqLength) {\n maxSeqLength = participant.size;\n }\n }\n const width = this.svgElement.parentNode.clientWidth;\n const defaultPixPerRes = width * 0.8 / maxSeqLength;\n //console.log(\"defaultPixPerRes:\" + defaultPixPerRes);\n // https://stackoverflow.com/questions/12141150/from-list-of-integers-get-number-closest-to-a-given-value/12141511#12141511\n function takeClosest(myList, myNumber) {\n const bisect = d3__WEBPACK_IMPORTED_MODULE_2__[\"bisector\"](function (d) {\n return d;\n }).left;\n const pos = bisect(myList, myNumber);\n if (pos === 0 || pos === 1) {\n return myList[1]; // don't return smallest scale as default\n }\n if (pos === myList.length) {\n return myList[myList.length - 1];\n }\n return myList[pos - 1];\n }\n\n this.defaultBarScale = takeClosest(this.barScales, defaultPixPerRes);\n //console.log(\"default bar scale: \" + this.defaultBarScale)\n\n for (let participant of this.participants.values()) {\n if (participant.type !== \"complex\") {\n this.proteinUpper.appendChild(participant.upperGroup);\n if (participant.json.type.name === \"protein\") {\n // participant.initSelfLinkSVG(); // todo - may not even do anything, not sure its working\n participant.stickZoom = this.defaultBarScale;\n if (this.participants.size < 4) {\n participant.toStickNoTransition();\n }\n }\n }\n }\n\n this.autoLayout();\n};\n\nApp.prototype.zoomToExtent = function () {\n const width = this.svgElement.parentNode.clientWidth;\n const height = this.svgElement.parentNode.clientHeight;\n const bbox = this.container.getBBox();\n let xr = (width / bbox.width).toFixed(4) - 0;\n let yr = (height / bbox.height).toFixed(4) - 0;\n let scaleFactor;\n if (yr < xr) {\n scaleFactor = yr;\n } else {\n scaleFactor = xr;\n }\n if (scaleFactor < 1) { ///didn't fit in div\n //console.log(\"no fit\", scaleFactor);\n xr = (width - 40) / (bbox.width);\n yr = (height - 40) / (bbox.height);\n let scaleFactor;\n if (yr < xr) {\n scaleFactor = yr;\n } else {\n scaleFactor = xr;\n }\n\n if (scaleFactor > this.z) {\n scaleFactor = this.z;\n }\n\n //bbox.x + x = 0;\n let x = -bbox.x + (20 / scaleFactor);\n //box.y + y = 0\n let y = -bbox.y + (20 / scaleFactor);\n this.container.setAttribute(\"transform\", \"scale(\" + scaleFactor + \") translate(\" + x + \" \" + y + \") \");\n this.z = this.container.getCTM().inverse().a;\n } else {\n //console.log(\"fit\", scaleFactor);\n // this.container.setAttribute(\"transform\", \"scale(\" + 1 + \") translate(\" + -(width/2) + \" \" + -bbox.y + \")\");\n const deltaWidth = width - bbox.width;\n const deltaHeight = height - bbox.height;\n //bbox.x + x = deltaWidth /2;\n let x = (deltaWidth / 2) - bbox.x;\n //box.y + y = deltaHeight / 2\n let y = (deltaHeight / 2) - bbox.y;\n this.container.setAttribute(\"transform\", \"scale(\" + 1 + \") translate(\" + x + \" \" + y + \")\");\n this.z = 1;\n }\n\n //todo - following could be tided up by using acknowledgement bbox or positioning att's of text\n this.acknowledgement.setAttribute(\"transform\", \"translate(\" + (width - 150) + \", \" + (height - 30) + \")\");\n};\n\n//listeners also attached to mouse events by Interactor (and Rotator) and Link, those consume their events\n//mouse down on svgElement must be allowed to propogate (to fire event on Prots/Links)\n\nApp.prototype.mouseDown = function (evt) {\n //prevent default, but allow propogation\n evt.preventDefault();\n this.d3cola.stop();\n const p = this.getEventPoint(evt); // seems to be correct, see below\n this.dragStart = this.mouseToSVG(p.x, p.y);\n return false;\n};\n\n// dragging/rotation/panning/selecting\nApp.prototype.mouseMove = function (evt) {\n const p = this.getEventPoint(evt); // seems to be correct, see below\n const c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement != null) { //dragging or rotating\n this.hideTooltip();\n const dx = this.dragStart.x - c.x;\n const dy = this.dragStart.y - c.y;\n\n if (this.state === this.STATES.DRAGGING) {\n // we are currently dragging things around\n let ox, oy, nx, ny;\n if (!this.dragElement.ix) {\n for (let participant of this.dragElement.participants) {\n participant.changePosition(dx, dy);\n }\n this.setAllLinkCoordinates();\n } else {\n ox = this.dragElement.ix;\n oy = this.dragElement.iy;\n nx = ox - dx;\n ny = oy - dy;\n this.dragElement.setPosition(nx, ny);\n this.dragElement.setAllLinkCoordinates();\n }\n this.dragStart = c;\n } else { //not dragging or rotating yet, maybe we should start\n // don't start dragging just on a click - we need to move the mouse a bit first\n if (Math.sqrt(dx * dx + dy * dy) > (5 * this.z)) {\n this.state = this.STATES.DRAGGING;\n\n }\n }\n } else {\n this.showTooltip(p);\n }\n return false;\n};\n\n// this ends all dragging and rotating\nApp.prototype.mouseUp = function (evt) {\n const time = new Date().getTime();\n //console.log(\"Mouse up: \" + evt.srcElement + \" \" + (time - this.lastMouseUp));\n this.preventDefaultsAndStopPropagation(evt);\n //eliminate some spurious mouse up events\n if ((time - this.lastMouseUp) > 150) {\n\n const p = this.getEventPoint(evt); // seems to be correct, see below\n const c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement && this.dragElement.type === \"protein\") { /// todo be consistent about how to check if thing is protein\n if (!(this.state === this.STATES.DRAGGING || this.state === this.STATES.ROTATING)) { //not dragging or rotating\n if (this.dragElement.form === 0) {\n this.dragElement.setForm(1);\n } else {\n this.contextMenuProt = this.dragElement;\n this.contextMenuPoint = c;\n const menu = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".custom-menu-margin\");\n menu.style(\"top\", (evt.pageY - 20) + \"px\").style(\"left\", (evt.pageX - 20) + \"px\").style(\"display\", \"block\");\n d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".scaleButton_\" + (this.dragElement.stickZoom * 100)).property(\"checked\", true);\n }\n }\n }\n }\n\n this.dragElement = null;\n this.state = this.STATES.MOUSE_UP;\n\n this.lastMouseUp = time;\n return false;\n};\n\n//gets mouse position\nApp.prototype.getEventPoint = function (evt) {\n const p = this.svgElement.createSVGPoint();\n let element = this.svgElement.parentNode;\n let top = 0,\n left = 0;\n do {\n top += element.offsetTop || 0;\n left += element.offsetLeft || 0;\n element = element.offsetParent;\n } while (element);\n p.x = evt.pageX - left;\n p.y = evt.pageY - top;\n return p;\n};\n\n//stop event propogation and defaults; only do what we ask\nApp.prototype.preventDefaultsAndStopPropagation = function (evt) {\n if (evt.stopPropagation)\n evt.stopPropagation();\n if (evt.cancelBubble != null)\n evt.cancelBubble = true;\n if (evt.preventDefault)\n evt.preventDefault();\n};\n\n/**\n * Handle touchstart event.\n\n App.prototype.touchStart = function(evt) {\n //prevent default, but allow propogation\n evt.preventDefault();\n\n //stop force layout\n if (typeof this.d3cola !== 'undefined' && this.d3cola != null) {\n this.d3cola.stop();\n }\n\n var p = this.getTouchEventPoint(evt); // seems to be correct, see below\n this.dragStart = this.mouseToSVG(p.x, p.y);\n};\n\n // dragging/rotation/panning/selecting\n App.prototype.touchMove = function(evt) {\n // if (this.sequenceInitComplete) { // just being cautious\n var p = this.getTouchEventPoint(evt); // seems to be correct, see below\n var c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement != null) { //dragging or rotating\n this.hideTooltip();\n var dx = this.dragStart.x - c.x;\n var dy = this.dragStart.y - c.y;\n\n if (this.state === this.STATES.DRAGGING) {\n // we are currently dragging things around\n var ox, oy, nx, ny;\n if (typeof this.dragElement.ix=== 'undefined') { // if not an Interactor\n var nodes = this.dragElement.interactors;\n var nodeCount = nodes.length;\n for (var i = 0; i < nodeCount; i++) {\n var protein = nodes[i];\n ox = protein.cx;\n oy = protein.cy;\n nx = ox - dx;\n ny = oy - dy;\n protein.setPosition(nx, ny);\n protein.setAllLinkCoordinates();\n }\n for (i = 0; i < nodeCount; i++) {\n nodes[i].setAllLinkCoordinates();\n }\n } else {\n ox = this.dragElement.cx;\n oy = this.dragElement.cy;\n nx = ox - dx;\n ny = oy - dy;\n this.dragElement.setPosition(nx, ny);\n this.dragElement.setAllLinkCoordinates();\n }\n this.dragStart = c;\n } else { //not dragging or rotating yet, maybe we should start\n // don't start dragging just on a click - we need to move the mouse a bit first\n if (Math.sqrt(dx * dx + dy * dy) > (5 * this.z)) {\n this.state = this.STATES.DRAGGING;\n\n }\n }\n } else {\n this.showTooltip(p);\n }\n return false;\n};\n\n// this ends all dragging and rotating\nApp.prototype.touchEnd = function(evt) {\n var time = new Date().getTime();\n //console.log(\"Mouse up: \" + evt.srcElement + \" \" + (time - this.lastMouseUp));\n this.preventDefaultsAndStopPropagation(evt);\n //eliminate some spurious mouse up events\n if ((time - this.lastMouseUp) > 150) {\n\n var p = this.getTouchEventPoint(evt); // seems to be correct, see below\n var c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement != null) {\n if (!(this.state === this.STATES.DRAGGING || this.state === this.STATES.ROTATING)) { //not dragging or rotating\n if (this.dragElement.form === 0) {\n this.dragElement.setForm(1);\n } else {\n this.contextMenuProt = this.dragElement;\n this.contextMenuPoint = c;\n var menu = d3.select(\".custom-menu-margin\")\n menu.style(\"top\", (evt.pageY - 20) + \"px\").style(\"left\", (evt.pageX - 20) + \"px\").style(\"display\", \"block\");\n d3.select(\".scaleButton_\" + (this.dragElement.stickZoom * 100)).property(\"checked\", true)\n }\n }\n }\n }\n\n this.dragElement = null;\n this.whichRotator = -1;\n this.state = this.STATES.MOUSE_UP;\n\n this.lastMouseUp = time;\n return false;\n};\n\n//gets mouse position\nApp.prototype.getTouchEventPoint = function(evt) {\n var p = this.svgElement.createSVGPoint();\n var element = this.svgElement.parentNode;\n var top = 0,\n left = 0;\n do {\n top += element.offsetTop || 0;\n left += element.offsetLeft || 0;\n element = element.offsetParent;\n } while (element);\n p.x = evt.touches[0].pageX - left;\n p.y = evt.touches[0].pageY - top;\n return p;\n};\n */\nApp.prototype.autoLayout = function () {\n this.d3cola.stop();\n const self = this;\n\n // needed to ensure consistent results\n for (let p of self.participants.values()) {\n delete p.x;\n delete p.y;\n delete p.px;\n delete p.py;\n delete p.bounds;\n p.fixed = 0;\n }\n\n //// prune leaves from network then layout, then add back leaves and layout again (fixes haemoglobin)\n const pruned = [];\n for (let participant of self.participants.values()) {\n if (participant.binaryLinks.size > 2 && participant.type !== \"complex\") {\n pruned.push(participant);\n }\n }\n const allNodesExceptComplexes = Array.from(self.participants.values()).filter(function (value) {\n return value.type !== \"complex\";\n });\n\n if (pruned.length < allNodesExceptComplexes.length\n && pruned.length > 3 && self.participants.size < 9) {\n // <9 include hemoglobin, possibly some other small cases, but is catious, tends to mess other things up\n // console.log(prunedIn);\n doLayout(pruned, true);\n } else {\n doLayout(allNodesExceptComplexes, self.complexes.length > 0);\n }\n\n function doLayout(nodes, preRun) {\n const layoutObj = {}; // todo get rid\n layoutObj.nodes = nodes;\n layoutObj.links = [];\n\n const molLookUp = {};\n let mi = 0;\n for (let mol of nodes) {\n molLookUp[mol.id] = mi;\n mi++;\n }\n\n for (let binaryLink of self.allBinaryLinks.values()) {\n const fromMol = binaryLink.participants[0];\n const toMol = binaryLink.participants[1];\n // if (preRun || (fromMol.binaryLinks.size === 4 || toMol.binaryLinks.size == 4)) {\n const source = fromMol; //molLookUp[fromMol.id];\n const target = toMol; //molLookUp[toMol.id];\n\n if (source !== target && nodes.indexOf(source) !== -1 && nodes.indexOf(target) !== -1) { // todo - check what this is doing\n const linkObj = {};\n linkObj.source = molLookUp[fromMol.id];\n linkObj.target = molLookUp[toMol.id];\n linkObj.id = binaryLink.id;\n layoutObj.links.push(linkObj);\n }\n // }\n }\n\n const groups = [];\n if (!preRun && self.complexes) {\n for (let g of self.complexes) {\n g.leaves = [];\n g.groups = [];\n for (let interactor of g.naryLink.participants) {\n if (interactor.type !== \"complex\") {\n g.leaves.push(layoutObj.nodes.indexOf(interactor));\n }\n }\n groups.push(g);\n }\n for (let g of self.complexes) {\n for (let interactor of g.naryLink.participants) {\n if (interactor.type === \"complex\") {\n //console.log(groups.indexOf(interactor));\n g.groups.push(groups.indexOf(interactor));\n }\n }\n }\n }\n\n // if (preRun) {\n // layoutObj.nodes = layoutObj.nodes.concat(prunedOut);\n // }\n\n // self.d3cola.convergenceThreshold = 0.01;\n //console.log(\"groups\", groups);\n delete self.d3cola._lastStress;\n delete self.d3cola._alpha;\n delete self.d3cola._descent;\n delete self.d3cola._rootGroup;\n\n let linkLength = (nodes.length < 30) ? 30 : 20;\n const width = self.svgElement.parentNode.clientWidth;\n const height = self.svgElement.parentNode.clientHeight;\n //console.log(\"**\", layoutObj);\n self.d3cola.size([height - 40, width - 40])\n .nodes(layoutObj.nodes).groups(groups).links(layoutObj.links).avoidOverlaps(true);\n let groupDebugSel, participantDebugSel;\n if (self.debug) {\n groupDebugSel = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](self.container).selectAll(\".group\")\n .data(groups);\n\n groupDebugSel.enter().append(\"rect\")\n .classed(\"group\", true)\n .attr({\n rx: 5,\n ry: 5\n })\n .style(\"stroke\", \"blue\")\n .style(\"fill\", \"none\");\n\n participantDebugSel = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](self.container).selectAll(\".node\")\n .data(layoutObj.nodes);\n\n participantDebugSel.enter().append(\"rect\")\n .classed(\"node\", true)\n .attr({\n rx: 5,\n ry: 5\n })\n .style(\"stroke\", \"red\")\n .style(\"fill\", \"none\");\n\n groupDebugSel.exit().remove();\n participantDebugSel.exit().remove();\n }\n\n const startTime = Date.now();\n self.d3cola.symmetricDiffLinkLengths(linkLength)\n .on(\"tick\", function () {\n if (Date.now() - startTime > 400) {//!preRun) {\n const nodes = self.d3cola.nodes();\n for (let node of nodes) {\n node.setPosition(node.x, node.y);\n }\n self.setAllLinkCoordinates();\n self.zoomToExtent();\n if (self.debug) {\n groupDebugSel.attr({\n x: function (d) {\n return d.bounds.x;// + (width / 2);\n },\n y: function (d) {\n return d.bounds.y;// + (height / 2);\n },\n width: function (d) {\n return d.bounds.width();\n },\n height: function (d) {\n return d.bounds.height();\n }\n });\n\n participantDebugSel.attr({\n x: function (d) {\n return d.bounds.x;// + (width / 2);\n },\n y: function (d) {\n return d.bounds.y;// + (height / 2);\n },\n width: function (d) {\n return d.bounds.width();\n },\n height: function (d) {\n return d.bounds.height();\n }\n });\n }\n }\n })\n .on(\"end\", function () {\n if (preRun) {\n // alert(\"initial run complete\");\n // // for (let p of layoutObj.nodes) {\n // // p.fixed = 1;\n // // }\n // // let nodesExceptComplexes = Array.from(self.participants.values());\n // // allNodesExceptComplexes = allNodesExceptComplexes.filter(function (value) {\n // // return value.type !== \"complex\";\n // // });\n doLayout(allNodesExceptComplexes, false);\n } else {\n for (let node of nodes) {\n node.setPosition(node.x, node.y);\n }\n self.setAllLinkCoordinates();\n self.zoomToExtent();\n }\n });\n if (preRun) {\n self.d3cola.start(23, 23, 0, 0, true);//, false, false);\n } else {\n self.d3cola.start(0, 23, 23, 0, true);//, false, false);\n }\n }\n};\n\nApp.prototype.getSVG = function () { //todo - update after styling of svg is moved to css\n let svgXml = this.svgElement.outerHTML.replace(//i, \"\"); //take out white background fill\n const viewBox = \"viewBox=\\\"0 0 \" + this.svgElement.parentNode.clientWidth + \" \" + this.svgElement.parentNode.clientHeight + \"\\\" \";\n svgXml = svgXml.replace(\"\" +\n \"\" +\n svgXml;\n};\n\n// transform the mouse-position into a position on the svg\nApp.prototype.mouseToSVG = function (x, y) {\n const p = this.svgElement.createSVGPoint();\n p.x = x;\n p.y = y;\n return p.matrixTransform(this.container.getCTM().inverse());\n};\n\n// reads MI JSON format\nApp.prototype.readMIJSON = function (miJson, expand = true) {\n Object(_read_mijson__WEBPACK_IMPORTED_MODULE_5__[\"readMijson\"])(miJson, this, expand);\n};\n\nApp.prototype.checkLinks = function () {\n function checkAll(linkMap) {\n for (let link of linkMap.values()) {\n link.check();\n }\n }\n\n checkAll(this.allNaryLinks);\n checkAll(this.allBinaryLinks);\n checkAll(this.allUnaryLinks);\n checkAll(this.allSequenceLinks);\n};\n\nApp.prototype.setAllLinkCoordinates = function () {\n function setAll(linkMap) {\n for (let link of linkMap.values()) {\n link.setLinkCoordinates(true); // true means don't propogate changes from naryLink up to complex, everythings getting refreshed anyway\n }\n }\n\n setAll(this.allNaryLinks);\n setAll(this.allBinaryLinks);\n setAll(this.allUnaryLinks);\n setAll(this.allSequenceLinks);\n};\n\nApp.prototype.showTooltip = function (p) {\n let ttX, ttY;\n const length = this.tooltip.getComputedTextLength() + 16;\n const width = this.svgElement.parentNode.clientWidth;\n const height = this.svgElement.parentNode.clientHeight;\n if (p.x + 20 + length < width) {\n ttX = p.x;\n } else {\n ttX = width - length - 20;\n }\n\n if (p.y + 60 < height) {\n ttY = p.y;\n } else {\n ttY = height - 60;\n }\n this.tooltip.setAttribute(\"x\", ttX + 22);\n this.tooltip.setAttribute(\"y\", ttY + 47);\n this.tooltip_bg.setAttribute(\"x\", ttX + 16);\n this.tooltip_bg.setAttribute(\"y\", ttY + 28);\n this.tooltip_subBg.setAttribute(\"x\", ttX + 16);\n this.tooltip_subBg.setAttribute(\"y\", ttY + 28);\n};\n\nApp.prototype.setTooltip = function (text, color) {\n if (text) {\n this.tooltip.firstChild.data = text.toString().replace(/&(quot);/g, \"\\\"\");\n this.tooltip.setAttribute(\"display\", \"block\");\n const length = this.tooltip.getComputedTextLength();\n this.tooltip_bg.setAttribute(\"width\", length + 16);\n this.tooltip_subBg.setAttribute(\"width\", length + 16);\n if (typeof color !== \"undefined\" && color != null) {\n this.tooltip_bg.setAttribute(\"fill\", color);\n this.tooltip_bg.setAttribute(\"stroke\", color);\n this.tooltip_bg.setAttribute(\"fill-opacity\", \"0.5\");\n } else {\n this.tooltip_bg.setAttribute(\"fill\", \"white\");\n this.tooltip_bg.setAttribute(\"stroke\", \"grey\");\n }\n this.tooltip_bg.setAttribute(\"height\", \"28\");\n this.tooltip_subBg.setAttribute(\"height\", \"28\");\n this.tooltip_bg.setAttribute(\"display\", \"block\");\n this.tooltip_subBg.setAttribute(\"display\", \"block\");\n } else {\n this.hideTooltip();\n }\n};\n\nApp.prototype.hideTooltip = function () {\n this.tooltip.setAttribute(\"display\", \"none\");\n this.tooltip_bg.setAttribute(\"display\", \"none\");\n this.tooltip_subBg.setAttribute(\"display\", \"none\");\n};\n\nApp.prototype.addColorSchemeKey = function (/*HTMLDivElement*/ div) {\n this.colorSchemeKeyDivs.add(div);\n _color_scheme_key__WEBPACK_IMPORTED_MODULE_7__[\"update\"](div, this);\n};\n\nApp.prototype.removeColorSchemeKey = function (/*HTMLDivElement*/ colorSchemeKeyDiv) {\n this.colorSchemeKeyDivs.remove(colorSchemeKeyDiv);\n colorSchemeKeyDiv.textContent = \"\";\n};\n\n//for backwards compatibility (noe?), tbh i might have made a bit of a mess here\nApp.prototype.setAnnotations = function (annoChoice) {\n annoChoice = annoChoice.toUpperCase();\n for (let annoType of this.annotationSetsShown.keys()) {\n this.showAnnotations(annoType, annoChoice === annoType);\n }\n this.showAnnotations(annoChoice, true);\n};\n\nApp.prototype.showAnnotations = function (annoChoice, show) {\n annoChoice = annoChoice.toUpperCase();\n const self = this;\n let setShown = this.annotationSetsShown.get(annoChoice);\n if (typeof setShown === \"undefined\" && annoChoice !== \"MIFEATURES\") {\n Object(_annotations__WEBPACK_IMPORTED_MODULE_6__[\"fetchAnnotations\"])(annoChoice, this, function () {\n self.annotationSetsShown.set(annoChoice, show);\n self.updateAnnotations();\n });\n } else {\n this.annotationSetsShown.set(annoChoice, show);\n this.updateAnnotations();\n }\n};\n\nApp.prototype.updateAnnotations = function () {\n // //clear all annot's\n for (let mol of this.participants.values()) {\n if (mol.id.indexOf(\"uniprotkb_\") === 0) { //LIMIT IT TO PROTEINS\n mol.clearPositionalFeatures();\n }\n }\n Object(_annotations__WEBPACK_IMPORTED_MODULE_6__[\"chooseColors\"])(this);\n this.colorSchemeChanged();\n\n for (let mol of this.participants.values()) {\n if (mol.id.indexOf(\"uniprotkb_\") === 0) { //LIMIT IT TO PROTEINS\n mol.setPositionalFeatures();\n }\n }\n Object(_annotations__WEBPACK_IMPORTED_MODULE_6__[\"chooseColors\"])(this);\n this.colorSchemeChanged();\n};\n\nApp.prototype.colorSchemeChanged = function () {\n for (let div of this.colorSchemeKeyDivs) {\n _color_scheme_key__WEBPACK_IMPORTED_MODULE_7__[\"update\"](div, this);\n }\n};\n\nApp.prototype.getComplexColors = function () {\n return _viz_link_nary_link__WEBPACK_IMPORTED_MODULE_8__[\"NaryLink\"].naryColors;\n};\n\nApp.prototype.getFeatureColors = function () {\n return this.featureColors;\n};\n\nApp.prototype.collapseAll = function () {\n for (let participant of this.participants.values()) {\n if (participant.form === 1) {\n participant.setForm(0);\n }\n }\n};\n\nApp.prototype.expandAll = function () {\n for (let participant of this.participants.values()) {\n if (participant.form === 0) {\n participant.setForm(1);\n }\n }\n};\n\n//from noe\nApp.prototype.expandAndCollapseSelection = function (moleculesSelected) {\n const molecules = this.molecules.values();\n for (var m = 0; m < molecules.length; m++) {\n var molecule = molecules[m];\n var molecule_id = molecule.json.identifier.id;\n if (moleculesSelected.includes(molecule_id)) {\n if (molecule.form === 0) {\n molecule.setForm(1);\n }\n } else if (molecule.form === 1) {\n molecule.setForm(0);\n }\n }\n};\n\n\n// export function makeSymbolKey(targetDiv){\n// new SymbolKey(targetDiv);\n// }\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvYXBwLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy9hcHAuanM/OTBlOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbmltcG9ydCAqIGFzIGNzcyBmcm9tIFwiLi4vY3NzL3hpbmV0LmNzc1wiO1xuaW1wb3J0IHt2ZXJzaW9ufSBmcm9tIFwiLi4vLi4vcGFja2FnZS5qc29uXCI7XG5pbXBvcnQgKiBhcyBkMyBmcm9tIFwiZDNcIjtcbmltcG9ydCAqIGFzIGQzX2Nocm9tYXRpYyBmcm9tIFwiZDMtc2NhbGUtY2hyb21hdGljXCI7XG5pbXBvcnQgKiBhcyBjb2xhIGZyb20gXCIuL2NvbGFcIjtcbmltcG9ydCB7cmVhZE1panNvbn0gZnJvbSBcIi4vcmVhZC1taWpzb25cIjtcbmltcG9ydCB7Y2hvb3NlQ29sb3JzLCBmZXRjaEFubm90YXRpb25zfSBmcm9tIFwiLi9hbm5vdGF0aW9uc1wiO1xuXG4vLyBpbXBvcnQge1N5bWJvbEtleX0gZnJvbSBcIi4vc3ltYm9sLWtleVwiO1xuaW1wb3J0ICogYXMgQ29sb3JTY2hlbWVLZXkgZnJvbSBcIi4vY29sb3Itc2NoZW1lLWtleVwiO1xuaW1wb3J0IHtOYXJ5TGlua30gZnJvbSBcIi4vdml6L2xpbmsvbmFyeS1saW5rXCI7XG5pbXBvcnQge3N2Z25zfSBmcm9tIFwiLi9jb25maWdcIjtcblxuLy8gY291bGQgcmVmYWN0b3IgZXZlcnl0aGluZyB0byB1c2UgRVM2IGNsYXNzIHN5bnRheFxuLy8gYnV0IGh0dHBzOi8vYmVubWNjb3JtaWNrLm9yZy8yMDE1LzA0LzA3L2VzNi1jbGFzc2VzLWFuZC1iYWNrYm9uZS1qc1xuLy8gXCJFUzYgY2xhc3NlcyBkb27igJl0IHN1cHBvcnQgYWRkaW5nIHByb3BlcnRpZXMgZGlyZWN0bHkgdG8gdGhlIGNsYXNzIGluc3RhbmNlLCBvbmx5IGZ1bmN0aW9ucy9tZXRob2RzXCJcbi8vIHNvIGJhY2tib25lIGRvZXNuJ3Qgd29ya1xuLy8gc28gY29udGludWluZyB0byB1c2UgcHJvdG90eXBpY2FsIGluaGVyaXRhbmNlIGluIHRoaW5ncyBmb3IgdGltZSBiZWluZ1xuXG5leHBvcnQgZnVuY3Rpb24gQXBwKC8qSFRNTERpdkVsZW1lbnQqL25ldHdvcmtEaXYpIHtcbiAgICAvLyB0aGlzLmRlYnVnID0gdHJ1ZTsgLy8gdGhpbmdzIGFyZW4ndCBleGFjdGx5IGxpbmVkIHVwIGluIHRoZSBib3VuZGluZyBib3hlcyBjb2xhIGlzIHVzaW5nLCB0byBkbyBzbyBicmVha3Mgc3ltZXRlcnkgb2Ygc29tZSB0aGluZ3NcbiAgICB0aGlzLmVsID0gbmV0d29ya0RpdjtcblxuICAgIHRoaXMuU1RBVEVTID0ge307XG4gICAgdGhpcy5TVEFURVMuTU9VU0VfVVAgPSAwOyAvL3N0YXJ0IHN0YXRlLCBhbHNvIHNldCB3aGVuIG1vdXNlIHVwIG9uIHN2Z0VsZW1lbnRcbiAgICB0aGlzLlNUQVRFUy5QQU5OSU5HID0gMTsgLy9zZXQgYnkgbW91c2UgZG93biBvbiBzdmdFbGVtZW50IC0gbGVmdCBidXR0b24sIG5vIHNoaWZ0IG9yIHV0aWxcbiAgICB0aGlzLlNUQVRFUy5EUkFHR0lORyA9IDI7IC8vc2V0IGJ5IG1vdXNlIGRvd24gb24gUHJvdGVpbiBvciBMaW5rXG4gICAgdGhpcy5TVEFURVMuUk9UQVRJTkcgPSAzOyAvL3NldCBieSBtb3VzZSBkb3duIG9uIFJvdGF0b3IsIGRyYWc/XG4gICAgdGhpcy5TVEFURVMuU0VMRUNUSU5HID0gNDsgLy9zZXQgYnkgbW91c2UgZG93biBvbiBzdmdFbGVtZW50LSByaWdodCBidXR0b24gb3IgbGVmdCBidXR0b24gc2hpZnQgb3IgdXRpbCwgZHJhZ1xuXG4gICAgLy9hdm9pZHMgcHJvYiB3aXRoICdzYXZlIC0gd2ViIHBhZ2UgY29tcGxldGUnXG4gICAgdGhpcy5lbC50ZXh0Q29udGVudCA9IFwiXCI7IC8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzk1NTIyOS9yZW1vdmUtYWxsLWNoaWxkLWVsZW1lbnRzLW9mLWEtZG9tLW5vZGUtaW4tamF2YXNjcmlwdFxuXG4gICAgdGhpcy5kM2NvbGEgPSBjb2xhLmQzYWRhcHRvcigpO1xuXG4gICAgY29uc3QgY3VzdG9tTWVudVNlbCA9IGQzLnNlbGVjdCh0aGlzLmVsKVxuICAgICAgICAuYXBwZW5kKFwiZGl2XCIpLmNsYXNzZWQoXCJjdXN0b20tbWVudS1tYXJnaW5cIiwgdHJ1ZSlcbiAgICAgICAgLmFwcGVuZChcImRpdlwiKS5jbGFzc2VkKFwiY3VzdG9tLW1lbnVcIiwgdHJ1ZSlcbiAgICAgICAgLmFwcGVuZChcInVsXCIpO1xuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3QgY29sbGFwc2UgPSBjdXN0b21NZW51U2VsLmFwcGVuZChcImxpXCIpLmNsYXNzZWQoXCJjb2xsYXBzZVwiLCB0cnVlKTsgLy8uYXBwZW5kKFwiYnV0dG9uXCIpO1xuICAgIGNvbGxhcHNlLnRleHQoXCJDb2xsYXBzZVwiKTtcbiAgICBjb2xsYXBzZVswXVswXS5vbmNsaWNrID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLmNvbGxhcHNlUHJvdGVpbihldnQpO1xuICAgIH07XG4gICAgY29uc3Qgc2NhbGVCdXR0b25zTGlzdEl0ZW1TZWwgPSBjdXN0b21NZW51U2VsLmFwcGVuZChcImxpXCIpLnRleHQoXCJTY2FsZTogXCIpO1xuXG4gICAgdGhpcy5iYXJTY2FsZXMgPSBbMC4wMSwgMC4yLCAxLCAyLCA0LCA4XTtcbiAgICBjb25zdCBzY2FsZUJ1dHRvbnMgPSBzY2FsZUJ1dHRvbnNMaXN0SXRlbVNlbC5zZWxlY3RBbGwoXCJ1bC5jdXN0b20tbWVudVwiKVxuICAgICAgICAuZGF0YSh0aGlzLmJhclNjYWxlcylcbiAgICAgICAgLmVudGVyKClcbiAgICAgICAgLmFwcGVuZChcImRpdlwiKVxuICAgICAgICAuYXR0cihcImNsYXNzXCIsIFwiYmFyU2NhbGVcIilcbiAgICAgICAgLmFwcGVuZChcImxhYmVsXCIpO1xuICAgIHNjYWxlQnV0dG9ucy5hcHBlbmQoXCJzcGFuXCIpXG4gICAgICAgIC50ZXh0KGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICBpZiAoZCA9PT0gOCkgcmV0dXJuIFwiQUFcIjtcbiAgICAgICAgICAgIGVsc2UgcmV0dXJuIGQ7XG4gICAgICAgIH0pO1xuICAgIHNjYWxlQnV0dG9ucy5hcHBlbmQoXCJpbnB1dFwiKVxuICAgICAgICAvLyAuYXR0ciAoXCJpZFwiLCBmdW5jdGlvbihkKSB7IHJldHVybiBkKjEwMDsgfSlcbiAgICAgICAgLmF0dHIoXCJjbGFzc1wiLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgcmV0dXJuIFwic2NhbGVCdXR0b24gc2NhbGVCdXR0b25fXCIgKyAoZCAqIDEwMCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5hdHRyKFwibmFtZVwiLCBcInNjYWxlQnV0dG9uc1wiKVxuICAgICAgICAuYXR0cihcInR5cGVcIiwgXCJyYWRpb1wiKVxuICAgICAgICAub24oXCJjaGFuZ2VcIiwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHNlbGYucHJldmVudERlZmF1bHRzQW5kU3RvcFByb3BhZ2F0aW9uKGQpO1xuICAgICAgICAgICAgc2VsZi5jb250ZXh0TWVudVByb3Quc2V0U3RpY2tTY2FsZShkLCBzZWxmLmNvbnRleHRNZW51UG9pbnQpO1xuICAgICAgICB9KTtcblxuICAgIGNvbnN0IGNvbnRleHRNZW51ID0gZDMuc2VsZWN0KFwiLmN1c3RvbS1tZW51LW1hcmdpblwiKS5ub2RlKCk7XG4gICAgY29udGV4dE1lbnUub25tb3VzZW91dCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgbGV0IGUgPSBldnQucmVsYXRlZFRhcmdldDtcbiAgICAgICAgZG8ge1xuICAgICAgICAgICAgaWYgKGUgPT09IHRoaXMpIHJldHVybjtcbiAgICAgICAgICAgIGUgPSBlLnBhcmVudE5vZGU7XG4gICAgICAgIH0gd2hpbGUgKGUpO1xuICAgICAgICBzZWxmLmNvbnRleHRNZW51UHJvdCA9IG51bGw7XG4gICAgICAgIGQzLnNlbGVjdCh0aGlzKS5zdHlsZShcImRpc3BsYXlcIiwgXCJub25lXCIpO1xuICAgIH07XG5cblxuICAgIC8vY3JlYXRlIFNWRyBlbGVtZW50XG4gICAgdGhpcy5zdmdFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInN2Z1wiKTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQuc2V0QXR0cmlidXRlKFwiaWRcIiwgXCJjb21wbGV4Vmlld2VyU1ZHXCIpO1xuXG4gICAgLy9hZGQgbGlzdGVuZXJzXG4gICAgdGhpcy5zdmdFbGVtZW50Lm9ubW91c2Vkb3duID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlRG93bihldnQpO1xuICAgIH07XG4gICAgdGhpcy5zdmdFbGVtZW50Lm9ubW91c2Vtb3ZlID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlTW92ZShldnQpO1xuICAgIH07XG4gICAgdGhpcy5zdmdFbGVtZW50Lm9ubW91c2V1cCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5tb3VzZVVwKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQub25tb3VzZW91dCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5oaWRlVG9vbHRpcChldnQpO1xuICAgIH07XG4gICAgdGhpcy5sYXN0TW91c2VVcCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIC8qdGhpcy5zdmdFbGVtZW50Lm9udG91Y2hzdGFydCA9IGZ1bmN0aW9uKGV2dCkge1xuICAgICAgICBzZWxmLnRvdWNoU3RhcnQoZXZ0KTtcbiAgICB9O1xuICAgIHRoaXMuc3ZnRWxlbWVudC5vbnRvdWNobW92ZSA9IGZ1bmN0aW9uKGV2dCkge1xuICAgICAgICBzZWxmLnRvdWNoTW92ZShldnQpO1xuICAgIH07XG4gICAgdGhpcy5zdmdFbGVtZW50Lm9udG91Y2hlbmQgPSBmdW5jdGlvbihldnQpIHtcbiAgICAgICAgc2VsZi50b3VjaEVuZChldnQpO1xuICAgIH07XG4gICAgKi9cblxuICAgIHRoaXMuZWwub25jb250ZXh0bWVudSA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgaWYgKGV2dC5wcmV2ZW50RGVmYXVsdCkgeyAvLyBuZWNlc3NhcnkgZm9yIGFkZEV2ZW50TGlzdGVuZXIsIHdvcmtzIHdpdGggdHJhZGl0aW9uYWxcbiAgICAgICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgICAgIGV2dC5yZXR1cm5WYWx1ZSA9IGZhbHNlOyAvLyBuZWNlc3NhcnkgZm9yIGF0dGFjaEV2ZW50LCB3b3JrcyB3aXRoIHRyYWRpdGlvbmFsXG4gICAgICAgIHJldHVybiBmYWxzZTsgLy8gd29ya3Mgd2l0aCB0cmFkaXRpb25hbCwgbm90IHdpdGggYXR0YWNoRXZlbnQgb3IgYWRkRXZlbnRMaXN0ZW5lclxuICAgIH07XG5cbiAgICAvL2xlZ2VuZCBjaGFuZ2VkIGNhbGxiYWNrc1xuICAgIHRoaXMuY29sb3JTY2hlbWVLZXlEaXZzID0gbmV3IFNldCgpO1xuXG4gICAgdGhpcy5lbC5hcHBlbmRDaGlsZCh0aGlzLnN2Z0VsZW1lbnQpO1xuXG4gICAgLy8gdmFyaW91cyBncm91cHMgbmVlZGVkXG4gICAgdGhpcy5jb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwiZ1wiKTtcbiAgICB0aGlzLmNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBcImNvbnRhaW5lclwiKTtcblxuICAgIGNvbnN0IHN2ZyA9IGQzLnNlbGVjdCh0aGlzLnN2Z0VsZW1lbnQpO1xuICAgIHRoaXMuZGVmcyA9IHN2Zy5hcHBlbmQoXCJkZWZzXCIpO1xuICAgIHRoaXMuY3JlYXRlSGF0Y2hlZEZpbGwoXCJjaGVja2Vyc191bmNlcnRhaW5cIiwgXCJibGFja1wiKTtcblxuICAgIC8vbWFya2Vyc1xuICAgIGNvbnN0IGRhdGEgPSBbe1xuICAgICAgICBpZDogMSxcbiAgICAgICAgbmFtZTogXCJkaWFtb25kXCIsXG4gICAgICAgIHBhdGg6IFwiTSAwLC03LjA3MTA3NjggTCAgMCw3LjA3MTA1ODkgTCA3LjA3MTA0NjIsMCAgelwiLFxuICAgICAgICB2aWV3Ym94OiBcIi0xNSAtMTUgMjUgMjVcIixcbiAgICAgICAgdHJhbnNmb3JtOiBcInNjYWxlKDEuNSkgdHJhbnNsYXRlKC01LDApXCIsXG4gICAgICAgIGNvbG9yOiBcImJsYWNrXCJcbiAgICB9XTtcblxuICAgIHRoaXMuZGVmcy5zZWxlY3RBbGwoXCJtYXJrZXJcIilcbiAgICAgICAgLmRhdGEoZGF0YSlcbiAgICAgICAgLmVudGVyKClcbiAgICAgICAgLmFwcGVuZChcInN2ZzptYXJrZXJcIilcbiAgICAgICAgLmF0dHIoXCJpZFwiLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgcmV0dXJuIFwibWFya2VyX1wiICsgZC5uYW1lO1xuICAgICAgICB9KVxuICAgICAgICAuYXR0cihcIm1hcmtlckhlaWdodFwiLCAxNSlcbiAgICAgICAgLmF0dHIoXCJtYXJrZXJXaWR0aFwiLCAxNSlcbiAgICAgICAgLmF0dHIoXCJtYXJrZXJVbml0c1wiLCBcInVzZXJTcGFjZU9uVXNlXCIpXG4gICAgICAgIC5hdHRyKFwib3JpZW50XCIsIFwiYXV0b1wiKVxuICAgICAgICAuYXR0cihcInJlZlhcIiwgMClcbiAgICAgICAgLmF0dHIoXCJyZWZZXCIsIDApXG4gICAgICAgIC5hdHRyKFwidmlld0JveFwiLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgcmV0dXJuIGQudmlld2JveDtcbiAgICAgICAgfSlcbiAgICAgICAgLmFwcGVuZChcInN2ZzpwYXRoXCIpXG4gICAgICAgIC5hdHRyKFwiZFwiLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgcmV0dXJuIGQucGF0aDtcbiAgICAgICAgfSlcbiAgICAgICAgLmF0dHIoXCJmaWxsXCIsIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICByZXR1cm4gZC5jb2xvcjtcbiAgICAgICAgfSlcbiAgICAgICAgLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHJldHVybiBkLnRyYW5zZm9ybTtcbiAgICAgICAgfSk7XG5cbiAgICB0aGlzLmFja25vd2xlZGdlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJnXCIpO1xuICAgIGNvbnN0IGFja1RleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwidGV4dFwiKTtcbiAgICBhY2tUZXh0LmlubmVySFRNTCA9IFwiPGEgaHJlZj0naHR0cHM6Ly9hY2FkZW1pYy5vdXAuY29tL2Jpb2luZm9ybWF0aWNzL2FydGljbGUvMzMvMjIvMzY3My80MDYxMjgwJyB0YXJnZXQ9J19ibGFuayc+PHRzcGFuIHg9JzAnIGR5PScxLjJlbScgc3R5bGU9J3RleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lJz5Db21wbGV4Vmlld2VyIFwiXG4gICAgICAgICsgdmVyc2lvbiArIFwiPC90c3Bhbj48L2E+PHRzcGFuIHg9JzAnIGR5PScxLjJlbSc+YnkgPGEgaHJlZj0naHR0cDovL3JhcHBzaWxiZXJsYWIub3JnLycgdGFyZ2V0PSdfYmxhbmsnPlJhcHBzaWxiZXIgTGFib3JhdG9yeTwvYT48L3RzcGFuPlwiO1xuXG4gICAgdGhpcy5hY2tub3dsZWRnZW1lbnQuYXBwZW5kQ2hpbGQoYWNrVGV4dCk7XG4gICAgYWNrVGV4dC5jbGFzc0xpc3QuYWRkKFwieGx2X3RleHRcIik7XG4gICAgYWNrVGV4dC5zZXRBdHRyaWJ1dGUoXCJmb250LXNpemVcIiwgXCI4cHRcIik7XG4gICAgdGhpcy5zdmdFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuYWNrbm93bGVkZ2VtZW50KTtcblxuICAgIHRoaXMubmFyeUxpbmtzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5uYXJ5TGlua3Muc2V0QXR0cmlidXRlKFwiaWRcIiwgXCJuYXJ5TGlua3NcIik7XG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5uYXJ5TGlua3MpO1xuXG4gICAgdGhpcy5wX3BMaW5rc1dpZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwiZ1wiKTtcbiAgICB0aGlzLnBfcExpbmtzV2lkZS5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBcInBfcExpbmtzV2lkZVwiKTtcbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLnBfcExpbmtzV2lkZSk7XG5cbiAgICB0aGlzLmhpZ2hsaWdodHMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwiZ1wiKTtcbiAgICB0aGlzLmhpZ2hsaWdodHMuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgXCJoaWdobGlnaHRzXCIpOyAvL2ludGVyYWN0b3JzIGFsc28gY29udGFpbiBoaWdobGlnaHQgZ3JvdXBzXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5oaWdobGlnaHRzKTtcblxuICAgIHRoaXMucmVzX3Jlc0xpbmtzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5yZXNfcmVzTGlua3Muc2V0QXR0cmlidXRlKFwiaWRcIiwgXCJyZXNfcmVzTGlua3NcIik7XG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5yZXNfcmVzTGlua3MpO1xuXG4gICAgdGhpcy5wX3BMaW5rcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJnXCIpO1xuICAgIHRoaXMucF9wTGlua3Muc2V0QXR0cmlidXRlKFwiaWRcIiwgXCJwX3BMaW5rc1wiKTtcbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLnBfcExpbmtzKTtcblxuICAgIHRoaXMucHJvdGVpblVwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5wcm90ZWluVXBwZXIuc2V0QXR0cmlidXRlKFwiaWRcIiwgXCJwcm90ZWluVXBwZXJcIik7XG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5wcm90ZWluVXBwZXIpO1xuXG4gICAgdGhpcy5zZWxmUmVzX3Jlc0xpbmtzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5zZWxmUmVzX3Jlc0xpbmtzLnNldEF0dHJpYnV0ZShcImlkXCIsIFwicmVzX3Jlc0xpbmtzXCIpO1xuICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuc2VsZlJlc19yZXNMaW5rcyk7XG5cbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5jb250YWluZXIpO1xuXG4gICAgLy9zaG93aW5nIHRpdGxlIGFzIHRvb2x0aXBzIGlzIE5PVCBwYXJ0IG9mIHN2ZyBzcGVjIChldmVuIHRob3VnaCBzb21lIGJyb3dzZXJzIGRvIHRoaXMpXG4gICAgLy9hbHNvIG1vcmUgcmVzcG9uc2l2ZSAvIG1vcmUgY29udHJvbCBpZiB3ZSBkbyBvdXQgb3duXG4gICAgdGhpcy50b29sdGlwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInRleHRcIik7XG4gICAgdGhpcy50b29sdGlwLnNldEF0dHJpYnV0ZShcInhcIiwgXCIwXCIpO1xuICAgIHRoaXMudG9vbHRpcC5zZXRBdHRyaWJ1dGUoXCJ5XCIsIFwiMFwiKTtcbiAgICB0aGlzLnRvb2x0aXAuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgXCJ4bHZfdGV4dFwiKTtcbiAgICBjb25zdCB0b29sdGlwVGV4dE5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcInRvb2x0aXBcIik7XG5cbiAgICB0aGlzLnRvb2x0aXAuYXBwZW5kQ2hpbGQodG9vbHRpcFRleHROb2RlKTtcblxuICAgIHRoaXMudG9vbHRpcF9iZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJyZWN0XCIpO1xuICAgIHRoaXMudG9vbHRpcF9iZy5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBcInRvb2x0aXBfYmdcIik7XG5cbiAgICB0aGlzLnRvb2x0aXBfYmcuc2V0QXR0cmlidXRlKFwiZmlsbC1vcGFjaXR5XCIsIFwiMC43NVwiKTtcbiAgICB0aGlzLnRvb2x0aXBfYmcuc2V0QXR0cmlidXRlKFwic3Ryb2tlLW9wYWNpdHlcIiwgXCIxXCIpO1xuICAgIHRoaXMudG9vbHRpcF9iZy5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgXCIxXCIpO1xuXG4gICAgdGhpcy50b29sdGlwX3N1YkJnID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInJlY3RcIik7XG4gICAgdGhpcy50b29sdGlwX3N1YkJnLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJ3aGl0ZVwiKTtcbiAgICB0aGlzLnRvb2x0aXBfc3ViQmcuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwid2hpdGVcIik7XG4gICAgdGhpcy50b29sdGlwX3N1YkJnLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIFwidG9vbHRpcF9iZ1wiKTtcbiAgICB0aGlzLnRvb2x0aXBfc3ViQmcuc2V0QXR0cmlidXRlKFwib3BhY2l0eVwiLCBcIjFcIik7XG4gICAgdGhpcy50b29sdGlwX3N1YkJnLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBcIjFcIik7XG5cbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy50b29sdGlwX3N1YkJnKTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy50b29sdGlwX2JnKTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy50b29sdGlwKTtcblxuICAgIHRoaXMuY2xlYXIoKTtcbn1cblxuQXBwLnByb3RvdHlwZS5jcmVhdGVIYXRjaGVkRmlsbCA9IGZ1bmN0aW9uIChuYW1lLCBjb2xvcikge1xuICAgIGNvbnN0IHBhdHRlcm4gPSB0aGlzLmRlZnMuYXBwZW5kKFwicGF0dGVyblwiKVxuICAgICAgICAuYXR0cihcImlkXCIsIG5hbWUpXG4gICAgICAgIC5hdHRyKFwicGF0dGVyblVuaXRzXCIsIFwidXNlclNwYWNlT25Vc2VcIilcbiAgICAgICAgLmF0dHIoXCJ4XCIsIDApXG4gICAgICAgIC5hdHRyKFwieVwiLCAwKVxuICAgICAgICAuYXR0cihcIndpZHRoXCIsIDEyKVxuICAgICAgICAuYXR0cihcImhlaWdodFwiLCAxMilcbiAgICAgICAgLmF0dHIoXCJwYXR0ZXJuVHJhbnNmb3JtXCIsIFwicm90YXRlKDQ1KVwiKTtcblxuICAgIHBhdHRlcm4uYXBwZW5kKFwicmVjdFwiKVxuICAgICAgICAuYXR0cihcInhcIiwgMClcbiAgICAgICAgLmF0dHIoXCJ5XCIsIDIpXG4gICAgICAgIC5hdHRyKFwid2lkdGhcIiwgMTIpXG4gICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIDQpXG4gICAgICAgIC5hdHRyKFwiZmlsbFwiLCBjb2xvcik7XG5cbiAgICBwYXR0ZXJuLmFwcGVuZChcInJlY3RcIilcbiAgICAgICAgLmF0dHIoXCJ4XCIsIDApXG4gICAgICAgIC5hdHRyKFwieVwiLCA4KVxuICAgICAgICAuYXR0cihcIndpZHRoXCIsIDEyKVxuICAgICAgICAuYXR0cihcImhlaWdodFwiLCA0KVxuICAgICAgICAuYXR0cihcImZpbGxcIiwgY29sb3IpO1xufTtcblxuQXBwLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmQzY29sYS5zdG9wKCk7XG5cbiAgICB0aGlzLmFubm90YXRpb25TZXRzU2hvd24gPSBuZXcgTWFwKCk7XG4gICAgLy8gdGhpcy5hbm5vdGF0aW9uU2V0c1Nob3duLnNldChcIk1JIEZFQVRVUkVTXCIsIHRydWUpO1xuXG4gICAgLy9saWdodGVuIGNvbG9yc1xuICAgIGNvbnN0IGNvbXBsZXhDb2xvcnMgPSBbXTtcbiAgICBmb3IgKGxldCBjIG9mIGQzX2Nocm9tYXRpYy5zY2hlbWVQYXN0ZWwyKSB7Ly9jb2xvcmJyZXdlci5QYXN0ZWwyWzhdKSB7XG4gICAgICAgIGNvbnN0IGhzbCA9IGQzLmhzbChjKTtcbiAgICAgICAgaHNsLmwgPSAwLjk7XG4gICAgICAgIGNvbXBsZXhDb2xvcnMucHVzaChoc2wgKyBcIlwiKTtcbiAgICB9XG5cbiAgICBOYXJ5TGluay5uYXJ5Q29sb3JzID0gZDMuc2NhbGUub3JkaW5hbCgpLnJhbmdlKGNvbXBsZXhDb2xvcnMpO1xuICAgIHRoaXMuZGVmcy5zZWxlY3RBbGwoXCIuZmVhdHVyZV9jaGVja2Vyc1wiKS5yZW1vdmUoKTtcblxuICAgIHRoaXMubmFyeUxpbmtzLnRleHRDb250ZW50ID0gXCJcIjtcbiAgICB0aGlzLnBfcExpbmtzV2lkZS50ZXh0Q29udGVudCA9IFwiXCI7XG4gICAgdGhpcy5oaWdobGlnaHRzLnRleHRDb250ZW50ID0gXCJcIjtcbiAgICB0aGlzLnBfcExpbmtzLnRleHRDb250ZW50ID0gXCJcIjtcbiAgICB0aGlzLnJlc19yZXNMaW5rcy50ZXh0Q29udGVudCA9IFwiXCI7XG4gICAgdGhpcy5wcm90ZWluVXBwZXIudGV4dENvbnRlbnQgPSBcIlwiO1xuICAgIHRoaXMuc2VsZlJlc19yZXNMaW5rcy50ZXh0Q29udGVudCA9IFwiXCI7XG5cbiAgICAvLyBpZiB3ZSBhcmUgZHJhZ2dpbmcgc29tZXRoaW5nIGF0IHRoZSBtb21lbnQgLSB0aGlzIHdpbGwgYmUgdGhlIGVsZW1lbnQgdGhhdCBpcyBkcmFnZ2VkXG4gICAgdGhpcy5kcmFnRWxlbWVudCA9IG51bGw7XG4gICAgLy8gZnJvbSB3aGVyZSBkaWQgd2Ugc3RhcnQgZHJhZ2dpbmdcbiAgICB0aGlzLmRyYWdTdGFydCA9IHt9O1xuXG4gICAgdGhpcy5wYXJ0aWNpcGFudHMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5hbGxOYXJ5TGlua3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5hbGxCaW5hcnlMaW5rcyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmFsbFVuYXJ5TGlua3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5hbGxTZXF1ZW5jZUxpbmtzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuY29tcGxleGVzID0gW107XG5cbiAgICB0aGlzLnByb3RlaW5Db3VudCA9IDA7XG4gICAgdGhpcy56ID0gMTtcbiAgICB0aGlzLmhpZGVUb29sdGlwKCk7XG4gICAgdGhpcy5zdGF0ZSA9IHRoaXMuU1RBVEVTLk1PVVNFX1VQO1xufTtcblxuQXBwLnByb3RvdHlwZS5jb2xsYXBzZVByb3RlaW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgZDMuc2VsZWN0KFwiLmN1c3RvbS1tZW51LW1hcmdpblwiKS5zdHlsZShcImRpc3BsYXlcIiwgXCJub25lXCIpO1xuICAgIHRoaXMuY29udGV4dE1lbnVQcm90LnNldEZvcm0oMCwgdGhpcy5jb250ZXh0TWVudVBvaW50KTtcbiAgICB0aGlzLmNvbnRleHRNZW51UHJvdCA9IG51bGw7XG59O1xuXG5BcHAucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5kM2NvbGEuc3RvcCgpO1xuXG4gICAgLy8gbGV0IGkgPSAwO1xuICAgIGZvciAobGV0IHBhcnRpY2lwYW50IG9mIHRoaXMucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgICAgIGlmIChwYXJ0aWNpcGFudC50eXBlICE9IFwiY29tcGxleFwiKSB7XG4gICAgICAgICAgICAvLyBsZXQgcG9zID0gcm90YXRlUG9pbnRBYm91dFBvaW50KFswLCAtNTAwXSwgWzAsIDBdLCAoMzYwIC8gdGhpcy5wYXJ0aWNpcGFudHMuc2l6ZSAqIGkpKTtcbiAgICAgICAgICAgIHBhcnRpY2lwYW50LnNldFBvc2l0aW9uKC01MDAsIC01MDApOy8vcG9zWzBdLCBwb3NbMV0pO1xuICAgICAgICAgICAgLy8gaWYgKHBhcnRpY2lwYW50LnR5cGUgPT09IFwicHJvdGVpblwiKSB7XG4gICAgICAgICAgICAvLyAgICAgcGFydGljaXBhbnQuc2V0UG9zaXRpb25hbEZlYXR1cmVzKCk7XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gaSsrO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZUFubm90YXRpb25zKCk7XG4gICAgdGhpcy5jaGVja0xpbmtzKCk7IC8vdG90YWxseSBuZWVkZWQsIG5vdCBzdXJlIHdoeSB0YmggdG9kbyAtIGNoZWNrIHRoaXMgb3V0XG4gICAgdGhpcy5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTsgLy8ganVzdCB0byBtb3ZlIHRoZW0gb2ZmIHNjcmVlbiBhdCBmaXJzdFxuXG4gICAgbGV0IG1heFNlcUxlbmd0aCA9IDA7XG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgdGhpcy5wYXJ0aWNpcGFudHMudmFsdWVzKCkpIHtcbiAgICAgICAgaWYgKHBhcnRpY2lwYW50LnNpemUgPiBtYXhTZXFMZW5ndGgpIHtcbiAgICAgICAgICAgIG1heFNlcUxlbmd0aCA9IHBhcnRpY2lwYW50LnNpemU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLnN2Z0VsZW1lbnQucGFyZW50Tm9kZS5jbGllbnRXaWR0aDtcbiAgICBjb25zdCBkZWZhdWx0UGl4UGVyUmVzID0gd2lkdGggKiAwLjggLyBtYXhTZXFMZW5ndGg7XG4gICAgLy9jb25zb2xlLmxvZyhcImRlZmF1bHRQaXhQZXJSZXM6XCIgKyBkZWZhdWx0UGl4UGVyUmVzKTtcbiAgICAvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMjE0MTE1MC9mcm9tLWxpc3Qtb2YtaW50ZWdlcnMtZ2V0LW51bWJlci1jbG9zZXN0LXRvLWEtZ2l2ZW4tdmFsdWUvMTIxNDE1MTEjMTIxNDE1MTFcbiAgICBmdW5jdGlvbiB0YWtlQ2xvc2VzdChteUxpc3QsIG15TnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IGJpc2VjdCA9IGQzLmJpc2VjdG9yKGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICByZXR1cm4gZDtcbiAgICAgICAgfSkubGVmdDtcbiAgICAgICAgY29uc3QgcG9zID0gYmlzZWN0KG15TGlzdCwgbXlOdW1iZXIpO1xuICAgICAgICBpZiAocG9zID09PSAwIHx8IHBvcyA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIG15TGlzdFsxXTsgLy8gZG9uJ3QgcmV0dXJuIHNtYWxsZXN0IHNjYWxlIGFzIGRlZmF1bHRcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zID09PSBteUxpc3QubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gbXlMaXN0W215TGlzdC5sZW5ndGggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbXlMaXN0W3BvcyAtIDFdO1xuICAgIH1cblxuICAgIHRoaXMuZGVmYXVsdEJhclNjYWxlID0gdGFrZUNsb3Nlc3QodGhpcy5iYXJTY2FsZXMsIGRlZmF1bHRQaXhQZXJSZXMpO1xuICAgIC8vY29uc29sZS5sb2coXCJkZWZhdWx0IGJhciBzY2FsZTogXCIgKyB0aGlzLmRlZmF1bHRCYXJTY2FsZSlcblxuICAgIGZvciAobGV0IHBhcnRpY2lwYW50IG9mIHRoaXMucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgICAgIGlmIChwYXJ0aWNpcGFudC50eXBlICE9PSBcImNvbXBsZXhcIikge1xuICAgICAgICAgICAgdGhpcy5wcm90ZWluVXBwZXIuYXBwZW5kQ2hpbGQocGFydGljaXBhbnQudXBwZXJHcm91cCk7XG4gICAgICAgICAgICBpZiAocGFydGljaXBhbnQuanNvbi50eXBlLm5hbWUgPT09IFwicHJvdGVpblwiKSB7XG4gICAgICAgICAgICAgICAgLy8gcGFydGljaXBhbnQuaW5pdFNlbGZMaW5rU1ZHKCk7IC8vIHRvZG8gLSBtYXkgbm90IGV2ZW4gZG8gYW55dGhpbmcsIG5vdCBzdXJlIGl0cyB3b3JraW5nXG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnQuc3RpY2tab29tID0gdGhpcy5kZWZhdWx0QmFyU2NhbGU7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucGFydGljaXBhbnRzLnNpemUgPCA0KSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50LnRvU3RpY2tOb1RyYW5zaXRpb24oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmF1dG9MYXlvdXQoKTtcbn07XG5cbkFwcC5wcm90b3R5cGUuem9vbVRvRXh0ZW50ID0gZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHdpZHRoID0gdGhpcy5zdmdFbGVtZW50LnBhcmVudE5vZGUuY2xpZW50V2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5zdmdFbGVtZW50LnBhcmVudE5vZGUuY2xpZW50SGVpZ2h0O1xuICAgIGNvbnN0IGJib3ggPSB0aGlzLmNvbnRhaW5lci5nZXRCQm94KCk7XG4gICAgbGV0IHhyID0gKHdpZHRoIC8gYmJveC53aWR0aCkudG9GaXhlZCg0KSAtIDA7XG4gICAgbGV0IHlyID0gKGhlaWdodCAvIGJib3guaGVpZ2h0KS50b0ZpeGVkKDQpIC0gMDtcbiAgICBsZXQgc2NhbGVGYWN0b3I7XG4gICAgaWYgKHlyIDwgeHIpIHtcbiAgICAgICAgc2NhbGVGYWN0b3IgPSB5cjtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzY2FsZUZhY3RvciA9IHhyO1xuICAgIH1cbiAgICBpZiAoc2NhbGVGYWN0b3IgPCAxKSB7IC8vL2RpZG4ndCBmaXQgaW4gZGl2XG4gICAgICAgIC8vY29uc29sZS5sb2coXCJubyBmaXRcIiwgc2NhbGVGYWN0b3IpO1xuICAgICAgICB4ciA9ICh3aWR0aCAtIDQwKSAvIChiYm94LndpZHRoKTtcbiAgICAgICAgeXIgPSAoaGVpZ2h0IC0gNDApIC8gKGJib3guaGVpZ2h0KTtcbiAgICAgICAgbGV0IHNjYWxlRmFjdG9yO1xuICAgICAgICBpZiAoeXIgPCB4cikge1xuICAgICAgICAgICAgc2NhbGVGYWN0b3IgPSB5cjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNjYWxlRmFjdG9yID0geHI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2NhbGVGYWN0b3IgPiB0aGlzLnopIHtcbiAgICAgICAgICAgIHNjYWxlRmFjdG9yID0gdGhpcy56O1xuICAgICAgICB9XG5cbiAgICAgICAgLy9iYm94LnggKyB4ID0gMDtcbiAgICAgICAgbGV0IHggPSAtYmJveC54ICsgKDIwIC8gc2NhbGVGYWN0b3IpO1xuICAgICAgICAvL2JveC55ICsgeSA9IDBcbiAgICAgICAgbGV0IHkgPSAtYmJveC55ICsgKDIwIC8gc2NhbGVGYWN0b3IpO1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgXCJzY2FsZShcIiArIHNjYWxlRmFjdG9yICsgXCIpIHRyYW5zbGF0ZShcIiArIHggKyBcIiBcIiArIHkgKyBcIikgXCIpO1xuICAgICAgICB0aGlzLnogPSB0aGlzLmNvbnRhaW5lci5nZXRDVE0oKS5pbnZlcnNlKCkuYTtcbiAgICB9IGVsc2Uge1xuICAgICAgICAvL2NvbnNvbGUubG9nKFwiZml0XCIsIHNjYWxlRmFjdG9yKTtcbiAgICAgICAgLy8gdGhpcy5jb250YWluZXIuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIFwic2NhbGUoXCIgKyAxICsgXCIpIHRyYW5zbGF0ZShcIiArIC0od2lkdGgvMikgKyBcIiBcIiArIC1iYm94LnkgKyBcIilcIik7XG4gICAgICAgIGNvbnN0IGRlbHRhV2lkdGggPSB3aWR0aCAtIGJib3gud2lkdGg7XG4gICAgICAgIGNvbnN0IGRlbHRhSGVpZ2h0ID0gaGVpZ2h0IC0gYmJveC5oZWlnaHQ7XG4gICAgICAgIC8vYmJveC54ICsgeCA9IGRlbHRhV2lkdGggLzI7XG4gICAgICAgIGxldCB4ID0gKGRlbHRhV2lkdGggLyAyKSAtIGJib3gueDtcbiAgICAgICAgLy9ib3gueSArIHkgPSBkZWx0YUhlaWdodCAvIDJcbiAgICAgICAgbGV0IHkgPSAoZGVsdGFIZWlnaHQgLyAyKSAtIGJib3gueTtcbiAgICAgICAgdGhpcy5jb250YWluZXIuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIFwic2NhbGUoXCIgKyAxICsgXCIpIHRyYW5zbGF0ZShcIiArIHggKyBcIiBcIiArIHkgKyBcIilcIik7XG4gICAgICAgIHRoaXMueiA9IDE7XG4gICAgfVxuXG4gICAgLy90b2RvIC0gZm9sbG93aW5nIGNvdWxkIGJlIHRpZGVkIHVwIGJ5IHVzaW5nIGFja25vd2xlZGdlbWVudCBiYm94IG9yIHBvc2l0aW9uaW5nIGF0dCdzIG9mIHRleHRcbiAgICB0aGlzLmFja25vd2xlZGdlbWVudC5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyAod2lkdGggLSAxNTApICsgXCIsIFwiICsgKGhlaWdodCAtIDMwKSArIFwiKVwiKTtcbn07XG5cbi8vbGlzdGVuZXJzIGFsc28gYXR0YWNoZWQgdG8gbW91c2UgZXZlbnRzIGJ5IEludGVyYWN0b3IgKGFuZCBSb3RhdG9yKSBhbmQgTGluaywgdGhvc2UgY29uc3VtZSB0aGVpciBldmVudHNcbi8vbW91c2UgZG93biBvbiBzdmdFbGVtZW50IG11c3QgYmUgYWxsb3dlZCB0byBwcm9wb2dhdGUgKHRvIGZpcmUgZXZlbnQgb24gUHJvdHMvTGlua3MpXG5cbkFwcC5wcm90b3R5cGUubW91c2VEb3duID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIC8vcHJldmVudCBkZWZhdWx0LCBidXQgYWxsb3cgcHJvcG9nYXRpb25cbiAgICBldnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLmQzY29sYS5zdG9wKCk7XG4gICAgY29uc3QgcCA9IHRoaXMuZ2V0RXZlbnRQb2ludChldnQpOyAvLyBzZWVtcyB0byBiZSBjb3JyZWN0LCBzZWUgYmVsb3dcbiAgICB0aGlzLmRyYWdTdGFydCA9IHRoaXMubW91c2VUb1NWRyhwLngsIHAueSk7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuLy8gZHJhZ2dpbmcvcm90YXRpb24vcGFubmluZy9zZWxlY3RpbmdcbkFwcC5wcm90b3R5cGUubW91c2VNb3ZlID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIGNvbnN0IHAgPSB0aGlzLmdldEV2ZW50UG9pbnQoZXZ0KTsgLy8gc2VlbXMgdG8gYmUgY29ycmVjdCwgc2VlIGJlbG93XG4gICAgY29uc3QgYyA9IHRoaXMubW91c2VUb1NWRyhwLngsIHAueSk7XG5cbiAgICBpZiAodGhpcy5kcmFnRWxlbWVudCAhPSBudWxsKSB7IC8vZHJhZ2dpbmcgb3Igcm90YXRpbmdcbiAgICAgICAgdGhpcy5oaWRlVG9vbHRpcCgpO1xuICAgICAgICBjb25zdCBkeCA9IHRoaXMuZHJhZ1N0YXJ0LnggLSBjLng7XG4gICAgICAgIGNvbnN0IGR5ID0gdGhpcy5kcmFnU3RhcnQueSAtIGMueTtcblxuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gdGhpcy5TVEFURVMuRFJBR0dJTkcpIHtcbiAgICAgICAgICAgIC8vIHdlIGFyZSBjdXJyZW50bHkgZHJhZ2dpbmcgdGhpbmdzIGFyb3VuZFxuICAgICAgICAgICAgbGV0IG94LCBveSwgbngsIG55O1xuICAgICAgICAgICAgaWYgKCF0aGlzLmRyYWdFbGVtZW50Lml4KSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgdGhpcy5kcmFnRWxlbWVudC5wYXJ0aWNpcGFudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnQuY2hhbmdlUG9zaXRpb24oZHgsIGR5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb3ggPSB0aGlzLmRyYWdFbGVtZW50Lml4O1xuICAgICAgICAgICAgICAgIG95ID0gdGhpcy5kcmFnRWxlbWVudC5peTtcbiAgICAgICAgICAgICAgICBueCA9IG94IC0gZHg7XG4gICAgICAgICAgICAgICAgbnkgPSBveSAtIGR5O1xuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0VsZW1lbnQuc2V0UG9zaXRpb24obngsIG55KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdFbGVtZW50LnNldEFsbExpbmtDb29yZGluYXRlcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kcmFnU3RhcnQgPSBjO1xuICAgICAgICB9IGVsc2UgeyAvL25vdCBkcmFnZ2luZyBvciByb3RhdGluZyB5ZXQsIG1heWJlIHdlIHNob3VsZCBzdGFydFxuICAgICAgICAgICAgLy8gZG9uJ3Qgc3RhcnQgZHJhZ2dpbmcganVzdCBvbiBhIGNsaWNrIC0gd2UgbmVlZCB0byBtb3ZlIHRoZSBtb3VzZSBhIGJpdCBmaXJzdFxuICAgICAgICAgICAgaWYgKE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSkgPiAoNSAqIHRoaXMueikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gdGhpcy5TVEFURVMuRFJBR0dJTkc7XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2hvd1Rvb2x0aXAocCk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbi8vIHRoaXMgZW5kcyBhbGwgZHJhZ2dpbmcgYW5kIHJvdGF0aW5nXG5BcHAucHJvdG90eXBlLm1vdXNlVXAgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgY29uc3QgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIC8vY29uc29sZS5sb2coXCJNb3VzZSB1cDogXCIgKyBldnQuc3JjRWxlbWVudCArIFwiIFwiICsgKHRpbWUgLSB0aGlzLmxhc3RNb3VzZVVwKSk7XG4gICAgdGhpcy5wcmV2ZW50RGVmYXVsdHNBbmRTdG9wUHJvcGFnYXRpb24oZXZ0KTtcbiAgICAvL2VsaW1pbmF0ZSBzb21lIHNwdXJpb3VzIG1vdXNlIHVwIGV2ZW50c1xuICAgIGlmICgodGltZSAtIHRoaXMubGFzdE1vdXNlVXApID4gMTUwKSB7XG5cbiAgICAgICAgY29uc3QgcCA9IHRoaXMuZ2V0RXZlbnRQb2ludChldnQpOyAvLyBzZWVtcyB0byBiZSBjb3JyZWN0LCBzZWUgYmVsb3dcbiAgICAgICAgY29uc3QgYyA9IHRoaXMubW91c2VUb1NWRyhwLngsIHAueSk7XG5cbiAgICAgICAgaWYgKHRoaXMuZHJhZ0VsZW1lbnQgJiYgdGhpcy5kcmFnRWxlbWVudC50eXBlID09PSBcInByb3RlaW5cIikgeyAvLy8gdG9kbyBiZSBjb25zaXN0ZW50IGFib3V0IGhvdyB0byBjaGVjayBpZiB0aGluZyBpcyBwcm90ZWluXG4gICAgICAgICAgICBpZiAoISh0aGlzLnN0YXRlID09PSB0aGlzLlNUQVRFUy5EUkFHR0lORyB8fCB0aGlzLnN0YXRlID09PSB0aGlzLlNUQVRFUy5ST1RBVElORykpIHsgLy9ub3QgZHJhZ2dpbmcgb3Igcm90YXRpbmdcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kcmFnRWxlbWVudC5mb3JtID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0VsZW1lbnQuc2V0Rm9ybSgxKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHRNZW51UHJvdCA9IHRoaXMuZHJhZ0VsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dE1lbnVQb2ludCA9IGM7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1lbnUgPSBkMy5zZWxlY3QoXCIuY3VzdG9tLW1lbnUtbWFyZ2luXCIpO1xuICAgICAgICAgICAgICAgICAgICBtZW51LnN0eWxlKFwidG9wXCIsIChldnQucGFnZVkgLSAyMCkgKyBcInB4XCIpLnN0eWxlKFwibGVmdFwiLCAoZXZ0LnBhZ2VYIC0gMjApICsgXCJweFwiKS5zdHlsZShcImRpc3BsYXlcIiwgXCJibG9ja1wiKTtcbiAgICAgICAgICAgICAgICAgICAgZDMuc2VsZWN0KFwiLnNjYWxlQnV0dG9uX1wiICsgKHRoaXMuZHJhZ0VsZW1lbnQuc3RpY2tab29tICogMTAwKSkucHJvcGVydHkoXCJjaGVja2VkXCIsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZHJhZ0VsZW1lbnQgPSBudWxsO1xuICAgIHRoaXMuc3RhdGUgPSB0aGlzLlNUQVRFUy5NT1VTRV9VUDtcblxuICAgIHRoaXMubGFzdE1vdXNlVXAgPSB0aW1lO1xuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbi8vZ2V0cyBtb3VzZSBwb3NpdGlvblxuQXBwLnByb3RvdHlwZS5nZXRFdmVudFBvaW50ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIGNvbnN0IHAgPSB0aGlzLnN2Z0VsZW1lbnQuY3JlYXRlU1ZHUG9pbnQoKTtcbiAgICBsZXQgZWxlbWVudCA9IHRoaXMuc3ZnRWxlbWVudC5wYXJlbnROb2RlO1xuICAgIGxldCB0b3AgPSAwLFxuICAgICAgICBsZWZ0ID0gMDtcbiAgICBkbyB7XG4gICAgICAgIHRvcCArPSBlbGVtZW50Lm9mZnNldFRvcCB8fCAwO1xuICAgICAgICBsZWZ0ICs9IGVsZW1lbnQub2Zmc2V0TGVmdCB8fCAwO1xuICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5vZmZzZXRQYXJlbnQ7XG4gICAgfSB3aGlsZSAoZWxlbWVudCk7XG4gICAgcC54ID0gZXZ0LnBhZ2VYIC0gbGVmdDtcbiAgICBwLnkgPSBldnQucGFnZVkgLSB0b3A7XG4gICAgcmV0dXJuIHA7XG59O1xuXG4vL3N0b3AgZXZlbnQgcHJvcG9nYXRpb24gYW5kIGRlZmF1bHRzOyBvbmx5IGRvIHdoYXQgd2UgYXNrXG5BcHAucHJvdG90eXBlLnByZXZlbnREZWZhdWx0c0FuZFN0b3BQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICBpZiAoZXZ0LnN0b3BQcm9wYWdhdGlvbilcbiAgICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmIChldnQuY2FuY2VsQnViYmxlICE9IG51bGwpXG4gICAgICAgIGV2dC5jYW5jZWxCdWJibGUgPSB0cnVlO1xuICAgIGlmIChldnQucHJldmVudERlZmF1bHQpXG4gICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xufTtcblxuLyoqXG4gKiBIYW5kbGUgdG91Y2hzdGFydCBldmVudC5cblxuIEFwcC5wcm90b3R5cGUudG91Y2hTdGFydCA9IGZ1bmN0aW9uKGV2dCkge1xuICAgIC8vcHJldmVudCBkZWZhdWx0LCBidXQgYWxsb3cgcHJvcG9nYXRpb25cbiAgICBldnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIC8vc3RvcCBmb3JjZSBsYXlvdXRcbiAgICBpZiAodHlwZW9mIHRoaXMuZDNjb2xhICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLmQzY29sYSAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuZDNjb2xhLnN0b3AoKTtcbiAgICB9XG5cbiAgICB2YXIgcCA9IHRoaXMuZ2V0VG91Y2hFdmVudFBvaW50KGV2dCk7IC8vIHNlZW1zIHRvIGJlIGNvcnJlY3QsIHNlZSBiZWxvd1xuICAgIHRoaXMuZHJhZ1N0YXJ0ID0gdGhpcy5tb3VzZVRvU1ZHKHAueCwgcC55KTtcbn07XG5cbiAvLyBkcmFnZ2luZy9yb3RhdGlvbi9wYW5uaW5nL3NlbGVjdGluZ1xuIEFwcC5wcm90b3R5cGUudG91Y2hNb3ZlID0gZnVuY3Rpb24oZXZ0KSB7XG4gICAgLy8gaWYgKHRoaXMuc2VxdWVuY2VJbml0Q29tcGxldGUpIHsgLy8ganVzdCBiZWluZyBjYXV0aW91c1xuICAgIHZhciBwID0gdGhpcy5nZXRUb3VjaEV2ZW50UG9pbnQoZXZ0KTsgLy8gc2VlbXMgdG8gYmUgY29ycmVjdCwgc2VlIGJlbG93XG4gICAgdmFyIGMgPSB0aGlzLm1vdXNlVG9TVkcocC54LCBwLnkpO1xuXG4gICAgaWYgKHRoaXMuZHJhZ0VsZW1lbnQgIT0gbnVsbCkgeyAvL2RyYWdnaW5nIG9yIHJvdGF0aW5nXG4gICAgICAgIHRoaXMuaGlkZVRvb2x0aXAoKTtcbiAgICAgICAgdmFyIGR4ID0gdGhpcy5kcmFnU3RhcnQueCAtIGMueDtcbiAgICAgICAgdmFyIGR5ID0gdGhpcy5kcmFnU3RhcnQueSAtIGMueTtcblxuICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gdGhpcy5TVEFURVMuRFJBR0dJTkcpIHtcbiAgICAgICAgICAgIC8vIHdlIGFyZSBjdXJyZW50bHkgZHJhZ2dpbmcgdGhpbmdzIGFyb3VuZFxuICAgICAgICAgICAgdmFyIG94LCBveSwgbngsIG55O1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmRyYWdFbGVtZW50Lml4PT09ICd1bmRlZmluZWQnKSB7IC8vIGlmIG5vdCBhbiBJbnRlcmFjdG9yXG4gICAgICAgICAgICAgICAgdmFyIG5vZGVzID0gdGhpcy5kcmFnRWxlbWVudC5pbnRlcmFjdG9ycztcbiAgICAgICAgICAgICAgICB2YXIgbm9kZUNvdW50ID0gbm9kZXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZUNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHByb3RlaW4gPSBub2Rlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgb3ggPSBwcm90ZWluLmN4O1xuICAgICAgICAgICAgICAgICAgICBveSA9IHByb3RlaW4uY3k7XG4gICAgICAgICAgICAgICAgICAgIG54ID0gb3ggLSBkeDtcbiAgICAgICAgICAgICAgICAgICAgbnkgPSBveSAtIGR5O1xuICAgICAgICAgICAgICAgICAgICBwcm90ZWluLnNldFBvc2l0aW9uKG54LCBueSk7XG4gICAgICAgICAgICAgICAgICAgIHByb3RlaW4uc2V0QWxsTGlua0Nvb3JkaW5hdGVzKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBub2RlQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBub2Rlc1tpXS5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG94ID0gdGhpcy5kcmFnRWxlbWVudC5jeDtcbiAgICAgICAgICAgICAgICBveSA9IHRoaXMuZHJhZ0VsZW1lbnQuY3k7XG4gICAgICAgICAgICAgICAgbnggPSBveCAtIGR4O1xuICAgICAgICAgICAgICAgIG55ID0gb3kgLSBkeTtcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdFbGVtZW50LnNldFBvc2l0aW9uKG54LCBueSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnRWxlbWVudC5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZHJhZ1N0YXJ0ID0gYztcbiAgICAgICAgfSBlbHNlIHsgLy9ub3QgZHJhZ2dpbmcgb3Igcm90YXRpbmcgeWV0LCBtYXliZSB3ZSBzaG91bGQgc3RhcnRcbiAgICAgICAgICAgIC8vIGRvbid0IHN0YXJ0IGRyYWdnaW5nIGp1c3Qgb24gYSBjbGljayAtIHdlIG5lZWQgdG8gbW92ZSB0aGUgbW91c2UgYSBiaXQgZmlyc3RcbiAgICAgICAgICAgIGlmIChNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpID4gKDUgKiB0aGlzLnopKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IHRoaXMuU1RBVEVTLkRSQUdHSU5HO1xuXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNob3dUb29sdGlwKHApO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG4vLyB0aGlzIGVuZHMgYWxsIGRyYWdnaW5nIGFuZCByb3RhdGluZ1xuQXBwLnByb3RvdHlwZS50b3VjaEVuZCA9IGZ1bmN0aW9uKGV2dCkge1xuICAgIHZhciB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgLy9jb25zb2xlLmxvZyhcIk1vdXNlIHVwOiBcIiArIGV2dC5zcmNFbGVtZW50ICsgXCIgXCIgKyAodGltZSAtIHRoaXMubGFzdE1vdXNlVXApKTtcbiAgICB0aGlzLnByZXZlbnREZWZhdWx0c0FuZFN0b3BQcm9wYWdhdGlvbihldnQpO1xuICAgIC8vZWxpbWluYXRlIHNvbWUgc3B1cmlvdXMgbW91c2UgdXAgZXZlbnRzXG4gICAgaWYgKCh0aW1lIC0gdGhpcy5sYXN0TW91c2VVcCkgPiAxNTApIHtcblxuICAgICAgICB2YXIgcCA9IHRoaXMuZ2V0VG91Y2hFdmVudFBvaW50KGV2dCk7IC8vIHNlZW1zIHRvIGJlIGNvcnJlY3QsIHNlZSBiZWxvd1xuICAgICAgICB2YXIgYyA9IHRoaXMubW91c2VUb1NWRyhwLngsIHAueSk7XG5cbiAgICAgICAgaWYgKHRoaXMuZHJhZ0VsZW1lbnQgIT0gbnVsbCkge1xuICAgICAgICAgICAgaWYgKCEodGhpcy5zdGF0ZSA9PT0gdGhpcy5TVEFURVMuRFJBR0dJTkcgfHwgdGhpcy5zdGF0ZSA9PT0gdGhpcy5TVEFURVMuUk9UQVRJTkcpKSB7IC8vbm90IGRyYWdnaW5nIG9yIHJvdGF0aW5nXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ0VsZW1lbnQuZm9ybSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdFbGVtZW50LnNldEZvcm0oMSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0TWVudVByb3QgPSB0aGlzLmRyYWdFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHRNZW51UG9pbnQgPSBjO1xuICAgICAgICAgICAgICAgICAgICB2YXIgbWVudSA9IGQzLnNlbGVjdChcIi5jdXN0b20tbWVudS1tYXJnaW5cIilcbiAgICAgICAgICAgICAgICAgICAgbWVudS5zdHlsZShcInRvcFwiLCAoZXZ0LnBhZ2VZIC0gMjApICsgXCJweFwiKS5zdHlsZShcImxlZnRcIiwgKGV2dC5wYWdlWCAtIDIwKSArIFwicHhcIikuc3R5bGUoXCJkaXNwbGF5XCIsIFwiYmxvY2tcIik7XG4gICAgICAgICAgICAgICAgICAgIGQzLnNlbGVjdChcIi5zY2FsZUJ1dHRvbl9cIiArICh0aGlzLmRyYWdFbGVtZW50LnN0aWNrWm9vbSAqIDEwMCkpLnByb3BlcnR5KFwiY2hlY2tlZFwiLCB0cnVlKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZHJhZ0VsZW1lbnQgPSBudWxsO1xuICAgIHRoaXMud2hpY2hSb3RhdG9yID0gLTE7XG4gICAgdGhpcy5zdGF0ZSA9IHRoaXMuU1RBVEVTLk1PVVNFX1VQO1xuXG4gICAgdGhpcy5sYXN0TW91c2VVcCA9IHRpbWU7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuLy9nZXRzIG1vdXNlIHBvc2l0aW9uXG5BcHAucHJvdG90eXBlLmdldFRvdWNoRXZlbnRQb2ludCA9IGZ1bmN0aW9uKGV2dCkge1xuICAgIHZhciBwID0gdGhpcy5zdmdFbGVtZW50LmNyZWF0ZVNWR1BvaW50KCk7XG4gICAgdmFyIGVsZW1lbnQgPSB0aGlzLnN2Z0VsZW1lbnQucGFyZW50Tm9kZTtcbiAgICB2YXIgdG9wID0gMCxcbiAgICAgICAgbGVmdCA9IDA7XG4gICAgZG8ge1xuICAgICAgICB0b3AgKz0gZWxlbWVudC5vZmZzZXRUb3AgfHwgMDtcbiAgICAgICAgbGVmdCArPSBlbGVtZW50Lm9mZnNldExlZnQgfHwgMDtcbiAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQub2Zmc2V0UGFyZW50O1xuICAgIH0gd2hpbGUgKGVsZW1lbnQpO1xuICAgIHAueCA9IGV2dC50b3VjaGVzWzBdLnBhZ2VYIC0gbGVmdDtcbiAgICBwLnkgPSBldnQudG91Y2hlc1swXS5wYWdlWSAtIHRvcDtcbiAgICByZXR1cm4gcDtcbn07XG4gKi9cbkFwcC5wcm90b3R5cGUuYXV0b0xheW91dCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmQzY29sYS5zdG9wKCk7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICAvLyBuZWVkZWQgdG8gZW5zdXJlIGNvbnNpc3RlbnQgcmVzdWx0c1xuICAgIGZvciAobGV0IHAgb2Ygc2VsZi5wYXJ0aWNpcGFudHMudmFsdWVzKCkpIHtcbiAgICAgICAgZGVsZXRlIHAueDtcbiAgICAgICAgZGVsZXRlIHAueTtcbiAgICAgICAgZGVsZXRlIHAucHg7XG4gICAgICAgIGRlbGV0ZSBwLnB5O1xuICAgICAgICBkZWxldGUgcC5ib3VuZHM7XG4gICAgICAgIHAuZml4ZWQgPSAwO1xuICAgIH1cblxuICAgIC8vLy8gcHJ1bmUgbGVhdmVzIGZyb20gbmV0d29yayB0aGVuIGxheW91dCwgdGhlbiBhZGQgYmFjayBsZWF2ZXMgYW5kIGxheW91dCBhZ2FpbiAoZml4ZXMgaGFlbW9nbG9iaW4pXG4gICAgY29uc3QgcHJ1bmVkID0gW107XG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2Ygc2VsZi5wYXJ0aWNpcGFudHMudmFsdWVzKCkpIHtcbiAgICAgICAgaWYgKHBhcnRpY2lwYW50LmJpbmFyeUxpbmtzLnNpemUgPiAyICYmIHBhcnRpY2lwYW50LnR5cGUgIT09IFwiY29tcGxleFwiKSB7XG4gICAgICAgICAgICBwcnVuZWQucHVzaChwYXJ0aWNpcGFudCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgYWxsTm9kZXNFeGNlcHRDb21wbGV4ZXMgPSBBcnJheS5mcm9tKHNlbGYucGFydGljaXBhbnRzLnZhbHVlcygpKS5maWx0ZXIoZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAgIHJldHVybiB2YWx1ZS50eXBlICE9PSBcImNvbXBsZXhcIjtcbiAgICB9KTtcblxuICAgIGlmIChwcnVuZWQubGVuZ3RoIDwgYWxsTm9kZXNFeGNlcHRDb21wbGV4ZXMubGVuZ3RoXG4gICAgICAgICYmIHBydW5lZC5sZW5ndGggPiAzICYmIHNlbGYucGFydGljaXBhbnRzLnNpemUgPCA5KSB7XG4gICAgICAgIC8vIDw5IGluY2x1ZGUgaGVtb2dsb2JpbiwgcG9zc2libHkgc29tZSBvdGhlciBzbWFsbCBjYXNlcywgYnV0IGlzIGNhdGlvdXMsIHRlbmRzIHRvIG1lc3Mgb3RoZXIgdGhpbmdzIHVwXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHBydW5lZEluKTtcbiAgICAgICAgZG9MYXlvdXQocHJ1bmVkLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBkb0xheW91dChhbGxOb2Rlc0V4Y2VwdENvbXBsZXhlcywgc2VsZi5jb21wbGV4ZXMubGVuZ3RoID4gMCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZG9MYXlvdXQobm9kZXMsIHByZVJ1bikge1xuICAgICAgICBjb25zdCBsYXlvdXRPYmogPSB7fTsgLy8gdG9kbyBnZXQgcmlkXG4gICAgICAgIGxheW91dE9iai5ub2RlcyA9IG5vZGVzO1xuICAgICAgICBsYXlvdXRPYmoubGlua3MgPSBbXTtcblxuICAgICAgICBjb25zdCBtb2xMb29rVXAgPSB7fTtcbiAgICAgICAgbGV0IG1pID0gMDtcbiAgICAgICAgZm9yIChsZXQgbW9sIG9mIG5vZGVzKSB7XG4gICAgICAgICAgICBtb2xMb29rVXBbbW9sLmlkXSA9IG1pO1xuICAgICAgICAgICAgbWkrKztcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAobGV0IGJpbmFyeUxpbmsgb2Ygc2VsZi5hbGxCaW5hcnlMaW5rcy52YWx1ZXMoKSkge1xuICAgICAgICAgICAgY29uc3QgZnJvbU1vbCA9IGJpbmFyeUxpbmsucGFydGljaXBhbnRzWzBdO1xuICAgICAgICAgICAgY29uc3QgdG9Nb2wgPSBiaW5hcnlMaW5rLnBhcnRpY2lwYW50c1sxXTtcbiAgICAgICAgICAgIC8vIGlmIChwcmVSdW4gfHwgKGZyb21Nb2wuYmluYXJ5TGlua3Muc2l6ZSA9PT0gNCB8fCB0b01vbC5iaW5hcnlMaW5rcy5zaXplID09IDQpKSB7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2UgPSBmcm9tTW9sOyAvL21vbExvb2tVcFtmcm9tTW9sLmlkXTtcbiAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHRvTW9sOyAvL21vbExvb2tVcFt0b01vbC5pZF07XG5cbiAgICAgICAgICAgIGlmIChzb3VyY2UgIT09IHRhcmdldCAmJiBub2Rlcy5pbmRleE9mKHNvdXJjZSkgIT09IC0xICYmIG5vZGVzLmluZGV4T2YodGFyZ2V0KSAhPT0gLTEpIHsgLy8gdG9kbyAtIGNoZWNrIHdoYXQgdGhpcyBpcyBkb2luZ1xuICAgICAgICAgICAgICAgIGNvbnN0IGxpbmtPYmogPSB7fTtcbiAgICAgICAgICAgICAgICBsaW5rT2JqLnNvdXJjZSA9IG1vbExvb2tVcFtmcm9tTW9sLmlkXTtcbiAgICAgICAgICAgICAgICBsaW5rT2JqLnRhcmdldCA9IG1vbExvb2tVcFt0b01vbC5pZF07XG4gICAgICAgICAgICAgICAgbGlua09iai5pZCA9IGJpbmFyeUxpbmsuaWQ7XG4gICAgICAgICAgICAgICAgbGF5b3V0T2JqLmxpbmtzLnB1c2gobGlua09iaik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBncm91cHMgPSBbXTtcbiAgICAgICAgaWYgKCFwcmVSdW4gJiYgc2VsZi5jb21wbGV4ZXMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGcgb2Ygc2VsZi5jb21wbGV4ZXMpIHtcbiAgICAgICAgICAgICAgICBnLmxlYXZlcyA9IFtdO1xuICAgICAgICAgICAgICAgIGcuZ3JvdXBzID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaW50ZXJhY3RvciBvZiBnLm5hcnlMaW5rLnBhcnRpY2lwYW50cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW50ZXJhY3Rvci50eXBlICE9PSBcImNvbXBsZXhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgZy5sZWF2ZXMucHVzaChsYXlvdXRPYmoubm9kZXMuaW5kZXhPZihpbnRlcmFjdG9yKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZ3JvdXBzLnB1c2goZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBnIG9mIHNlbGYuY29tcGxleGVzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaW50ZXJhY3RvciBvZiBnLm5hcnlMaW5rLnBhcnRpY2lwYW50cykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW50ZXJhY3Rvci50eXBlID09PSBcImNvbXBsZXhcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhncm91cHMuaW5kZXhPZihpbnRlcmFjdG9yKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBnLmdyb3Vwcy5wdXNoKGdyb3Vwcy5pbmRleE9mKGludGVyYWN0b3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIChwcmVSdW4pIHtcbiAgICAgICAgLy8gICAgbGF5b3V0T2JqLm5vZGVzID0gbGF5b3V0T2JqLm5vZGVzLmNvbmNhdChwcnVuZWRPdXQpO1xuICAgICAgICAvLyB9XG5cbiAgICAgICAgLy8gc2VsZi5kM2NvbGEuY29udmVyZ2VuY2VUaHJlc2hvbGQgPSAwLjAxO1xuICAgICAgICAvL2NvbnNvbGUubG9nKFwiZ3JvdXBzXCIsIGdyb3Vwcyk7XG4gICAgICAgIGRlbGV0ZSBzZWxmLmQzY29sYS5fbGFzdFN0cmVzcztcbiAgICAgICAgZGVsZXRlIHNlbGYuZDNjb2xhLl9hbHBoYTtcbiAgICAgICAgZGVsZXRlIHNlbGYuZDNjb2xhLl9kZXNjZW50O1xuICAgICAgICBkZWxldGUgc2VsZi5kM2NvbGEuX3Jvb3RHcm91cDtcblxuICAgICAgICBsZXQgbGlua0xlbmd0aCA9IChub2Rlcy5sZW5ndGggPCAzMCkgPyAzMCA6IDIwO1xuICAgICAgICBjb25zdCB3aWR0aCA9IHNlbGYuc3ZnRWxlbWVudC5wYXJlbnROb2RlLmNsaWVudFdpZHRoO1xuICAgICAgICBjb25zdCBoZWlnaHQgPSBzZWxmLnN2Z0VsZW1lbnQucGFyZW50Tm9kZS5jbGllbnRIZWlnaHQ7XG4gICAgICAgIC8vY29uc29sZS5sb2coXCIqKlwiLCBsYXlvdXRPYmopO1xuICAgICAgICBzZWxmLmQzY29sYS5zaXplKFtoZWlnaHQgLSA0MCwgd2lkdGggLSA0MF0pXG4gICAgICAgICAgICAubm9kZXMobGF5b3V0T2JqLm5vZGVzKS5ncm91cHMoZ3JvdXBzKS5saW5rcyhsYXlvdXRPYmoubGlua3MpLmF2b2lkT3ZlcmxhcHModHJ1ZSk7XG4gICAgICAgIGxldCBncm91cERlYnVnU2VsLCBwYXJ0aWNpcGFudERlYnVnU2VsO1xuICAgICAgICBpZiAoc2VsZi5kZWJ1Zykge1xuICAgICAgICAgICAgZ3JvdXBEZWJ1Z1NlbCA9IGQzLnNlbGVjdChzZWxmLmNvbnRhaW5lcikuc2VsZWN0QWxsKFwiLmdyb3VwXCIpXG4gICAgICAgICAgICAgICAgLmRhdGEoZ3JvdXBzKTtcblxuICAgICAgICAgICAgZ3JvdXBEZWJ1Z1NlbC5lbnRlcigpLmFwcGVuZChcInJlY3RcIilcbiAgICAgICAgICAgICAgICAuY2xhc3NlZChcImdyb3VwXCIsIHRydWUpXG4gICAgICAgICAgICAgICAgLmF0dHIoe1xuICAgICAgICAgICAgICAgICAgICByeDogNSxcbiAgICAgICAgICAgICAgICAgICAgcnk6IDVcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5zdHlsZShcInN0cm9rZVwiLCBcImJsdWVcIilcbiAgICAgICAgICAgICAgICAuc3R5bGUoXCJmaWxsXCIsIFwibm9uZVwiKTtcblxuICAgICAgICAgICAgcGFydGljaXBhbnREZWJ1Z1NlbCA9IGQzLnNlbGVjdChzZWxmLmNvbnRhaW5lcikuc2VsZWN0QWxsKFwiLm5vZGVcIilcbiAgICAgICAgICAgICAgICAuZGF0YShsYXlvdXRPYmoubm9kZXMpO1xuXG4gICAgICAgICAgICBwYXJ0aWNpcGFudERlYnVnU2VsLmVudGVyKCkuYXBwZW5kKFwicmVjdFwiKVxuICAgICAgICAgICAgICAgIC5jbGFzc2VkKFwibm9kZVwiLCB0cnVlKVxuICAgICAgICAgICAgICAgIC5hdHRyKHtcbiAgICAgICAgICAgICAgICAgICAgcng6IDUsXG4gICAgICAgICAgICAgICAgICAgIHJ5OiA1XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuc3R5bGUoXCJzdHJva2VcIiwgXCJyZWRcIilcbiAgICAgICAgICAgICAgICAuc3R5bGUoXCJmaWxsXCIsIFwibm9uZVwiKTtcblxuICAgICAgICAgICAgZ3JvdXBEZWJ1Z1NlbC5leGl0KCkucmVtb3ZlKCk7XG4gICAgICAgICAgICBwYXJ0aWNpcGFudERlYnVnU2VsLmV4aXQoKS5yZW1vdmUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICAgIHNlbGYuZDNjb2xhLnN5bW1ldHJpY0RpZmZMaW5rTGVuZ3RocyhsaW5rTGVuZ3RoKVxuICAgICAgICAgICAgLm9uKFwidGlja1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKERhdGUubm93KCkgLSBzdGFydFRpbWUgPiA0MDApIHsvLyFwcmVSdW4pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZXMgPSBzZWxmLmQzY29sYS5ub2RlcygpO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBub2RlIG9mIG5vZGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnNldFBvc2l0aW9uKG5vZGUueCwgbm9kZS55KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldEFsbExpbmtDb29yZGluYXRlcygpO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21Ub0V4dGVudCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5kZWJ1Zykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBEZWJ1Z1NlbC5hdHRyKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZC5ib3VuZHMueDsvLyArICh3aWR0aCAvIDIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGQuYm91bmRzLnk7Ly8gKyAoaGVpZ2h0IC8gMik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGQuYm91bmRzLndpZHRoKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkLmJvdW5kcy5oZWlnaHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnREZWJ1Z1NlbC5hdHRyKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4OiBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZC5ib3VuZHMueDsvLyArICh3aWR0aCAvIDIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGQuYm91bmRzLnk7Ly8gKyAoaGVpZ2h0IC8gMik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aDogZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGQuYm91bmRzLndpZHRoKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkLmJvdW5kcy5oZWlnaHQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAub24oXCJlbmRcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChwcmVSdW4pIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gYWxlcnQoXCJpbml0aWFsIHJ1biBjb21wbGV0ZVwiKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgIC8vIGZvciAobGV0IHAgb2YgbGF5b3V0T2JqLm5vZGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vICAgICAvLyAgICAgICAgIHAuZml4ZWQgPSAxO1xuICAgICAgICAgICAgICAgICAgICAvLyAgICAgLy8gfVxuICAgICAgICAgICAgICAgICAgICAvLyAgICAgLy8gbGV0IG5vZGVzRXhjZXB0Q29tcGxleGVzID0gQXJyYXkuZnJvbShzZWxmLnBhcnRpY2lwYW50cy52YWx1ZXMoKSk7XG4gICAgICAgICAgICAgICAgICAgIC8vICAgICAvLyBhbGxOb2Rlc0V4Y2VwdENvbXBsZXhlcyA9IGFsbE5vZGVzRXhjZXB0Q29tcGxleGVzLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgIC8vICAgICByZXR1cm4gdmFsdWUudHlwZSAhPT0gXCJjb21wbGV4XCI7XG4gICAgICAgICAgICAgICAgICAgIC8vICAgICAvLyB9KTtcbiAgICAgICAgICAgICAgICAgICAgZG9MYXlvdXQoYWxsTm9kZXNFeGNlcHRDb21wbGV4ZXMsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBub2RlIG9mIG5vZGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnNldFBvc2l0aW9uKG5vZGUueCwgbm9kZS55KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldEFsbExpbmtDb29yZGluYXRlcygpO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21Ub0V4dGVudCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICBpZiAocHJlUnVuKSB7XG4gICAgICAgICAgICBzZWxmLmQzY29sYS5zdGFydCgyMywgMjMsIDAsIDAsIHRydWUpOy8vLCBmYWxzZSwgZmFsc2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5kM2NvbGEuc3RhcnQoMCwgMjMsIDIzLCAwLCB0cnVlKTsvLywgZmFsc2UsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbkFwcC5wcm90b3R5cGUuZ2V0U1ZHID0gZnVuY3Rpb24gKCkgeyAvL3RvZG8gLSB1cGRhdGUgYWZ0ZXIgc3R5bGluZyBvZiBzdmcgaXMgbW92ZWQgdG8gY3NzXG4gICAgbGV0IHN2Z1htbCA9IHRoaXMuc3ZnRWxlbWVudC5vdXRlckhUTUwucmVwbGFjZSgvPHJlY3QgLio/XFwvcmVjdD4vaSwgXCJcIik7IC8vdGFrZSBvdXQgd2hpdGUgYmFja2dyb3VuZCBmaWxsXG4gICAgY29uc3Qgdmlld0JveCA9IFwidmlld0JveD1cXFwiMCAwIFwiICsgdGhpcy5zdmdFbGVtZW50LnBhcmVudE5vZGUuY2xpZW50V2lkdGggKyBcIiBcIiArIHRoaXMuc3ZnRWxlbWVudC5wYXJlbnROb2RlLmNsaWVudEhlaWdodCArIFwiXFxcIiBcIjtcbiAgICBzdmdYbWwgPSBzdmdYbWwucmVwbGFjZShcIjxzdmcgXCIsIFwiPHN2ZyB4bWxucz1cXFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcXFwiIHhtbG5zOnhsaW5rPVxcXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXFxcIiB4bWxuczpldj1cXFwiaHR0cDovL3d3dy53My5vcmcvMjAwMS94bWwtZXZlbnRzXFxcIiBcIiArIHZpZXdCb3gpO1xuXG4gICAgcmV0dXJuIFwiPD94bWwgdmVyc2lvbj1cXFwiMS4wXFxcIiBlbmNvZGluZz1cXFwiVVRGLThcXFwiIHN0YW5kYWxvbmU9XFxcIm5vXFxcIj8+XCIgK1xuICAgICAgICBcIjwhRE9DVFlQRSBzdmcgUFVCTElDIFxcXCItLy9XM0MvL0RURCBTVkcgMS4xLy9FTlxcXCIgXFxcImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZFxcXCI+XCIgK1xuICAgICAgICBzdmdYbWw7XG59O1xuXG4vLyB0cmFuc2Zvcm0gdGhlIG1vdXNlLXBvc2l0aW9uIGludG8gYSBwb3NpdGlvbiBvbiB0aGUgc3ZnXG5BcHAucHJvdG90eXBlLm1vdXNlVG9TVkcgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIGNvbnN0IHAgPSB0aGlzLnN2Z0VsZW1lbnQuY3JlYXRlU1ZHUG9pbnQoKTtcbiAgICBwLnggPSB4O1xuICAgIHAueSA9IHk7XG4gICAgcmV0dXJuIHAubWF0cml4VHJhbnNmb3JtKHRoaXMuY29udGFpbmVyLmdldENUTSgpLmludmVyc2UoKSk7XG59O1xuXG4vLyByZWFkcyBNSSBKU09OIGZvcm1hdFxuQXBwLnByb3RvdHlwZS5yZWFkTUlKU09OID0gZnVuY3Rpb24gKG1pSnNvbiwgZXhwYW5kID0gdHJ1ZSkge1xuICAgIHJlYWRNaWpzb24obWlKc29uLCB0aGlzLCBleHBhbmQpO1xufTtcblxuQXBwLnByb3RvdHlwZS5jaGVja0xpbmtzID0gZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIGNoZWNrQWxsKGxpbmtNYXApIHtcbiAgICAgICAgZm9yIChsZXQgbGluayBvZiBsaW5rTWFwLnZhbHVlcygpKSB7XG4gICAgICAgICAgICBsaW5rLmNoZWNrKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjaGVja0FsbCh0aGlzLmFsbE5hcnlMaW5rcyk7XG4gICAgY2hlY2tBbGwodGhpcy5hbGxCaW5hcnlMaW5rcyk7XG4gICAgY2hlY2tBbGwodGhpcy5hbGxVbmFyeUxpbmtzKTtcbiAgICBjaGVja0FsbCh0aGlzLmFsbFNlcXVlbmNlTGlua3MpO1xufTtcblxuQXBwLnByb3RvdHlwZS5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gc2V0QWxsKGxpbmtNYXApIHtcbiAgICAgICAgZm9yIChsZXQgbGluayBvZiBsaW5rTWFwLnZhbHVlcygpKSB7XG4gICAgICAgICAgICBsaW5rLnNldExpbmtDb29yZGluYXRlcyh0cnVlKTsgLy8gdHJ1ZSBtZWFucyBkb24ndCBwcm9wb2dhdGUgY2hhbmdlcyBmcm9tIG5hcnlMaW5rIHVwIHRvIGNvbXBsZXgsIGV2ZXJ5dGhpbmdzIGdldHRpbmcgcmVmcmVzaGVkIGFueXdheVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0QWxsKHRoaXMuYWxsTmFyeUxpbmtzKTtcbiAgICBzZXRBbGwodGhpcy5hbGxCaW5hcnlMaW5rcyk7XG4gICAgc2V0QWxsKHRoaXMuYWxsVW5hcnlMaW5rcyk7XG4gICAgc2V0QWxsKHRoaXMuYWxsU2VxdWVuY2VMaW5rcyk7XG59O1xuXG5BcHAucHJvdG90eXBlLnNob3dUb29sdGlwID0gZnVuY3Rpb24gKHApIHtcbiAgICBsZXQgdHRYLCB0dFk7XG4gICAgY29uc3QgbGVuZ3RoID0gdGhpcy50b29sdGlwLmdldENvbXB1dGVkVGV4dExlbmd0aCgpICsgMTY7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLnN2Z0VsZW1lbnQucGFyZW50Tm9kZS5jbGllbnRXaWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLnN2Z0VsZW1lbnQucGFyZW50Tm9kZS5jbGllbnRIZWlnaHQ7XG4gICAgaWYgKHAueCArIDIwICsgbGVuZ3RoIDwgd2lkdGgpIHtcbiAgICAgICAgdHRYID0gcC54O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHR0WCA9IHdpZHRoIC0gbGVuZ3RoIC0gMjA7XG4gICAgfVxuXG4gICAgaWYgKHAueSArIDYwIDwgaGVpZ2h0KSB7XG4gICAgICAgIHR0WSA9IHAueTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0dFkgPSBoZWlnaHQgLSA2MDtcbiAgICB9XG4gICAgdGhpcy50b29sdGlwLnNldEF0dHJpYnV0ZShcInhcIiwgdHRYICsgMjIpO1xuICAgIHRoaXMudG9vbHRpcC5zZXRBdHRyaWJ1dGUoXCJ5XCIsIHR0WSArIDQ3KTtcbiAgICB0aGlzLnRvb2x0aXBfYmcuc2V0QXR0cmlidXRlKFwieFwiLCB0dFggKyAxNik7XG4gICAgdGhpcy50b29sdGlwX2JnLnNldEF0dHJpYnV0ZShcInlcIiwgdHRZICsgMjgpO1xuICAgIHRoaXMudG9vbHRpcF9zdWJCZy5zZXRBdHRyaWJ1dGUoXCJ4XCIsIHR0WCArIDE2KTtcbiAgICB0aGlzLnRvb2x0aXBfc3ViQmcuc2V0QXR0cmlidXRlKFwieVwiLCB0dFkgKyAyOCk7XG59O1xuXG5BcHAucHJvdG90eXBlLnNldFRvb2x0aXAgPSBmdW5jdGlvbiAodGV4dCwgY29sb3IpIHtcbiAgICBpZiAodGV4dCkge1xuICAgICAgICB0aGlzLnRvb2x0aXAuZmlyc3RDaGlsZC5kYXRhID0gdGV4dC50b1N0cmluZygpLnJlcGxhY2UoLyYocXVvdCk7L2csIFwiXFxcIlwiKTtcbiAgICAgICAgdGhpcy50b29sdGlwLnNldEF0dHJpYnV0ZShcImRpc3BsYXlcIiwgXCJibG9ja1wiKTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gdGhpcy50b29sdGlwLmdldENvbXB1dGVkVGV4dExlbmd0aCgpO1xuICAgICAgICB0aGlzLnRvb2x0aXBfYmcuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgbGVuZ3RoICsgMTYpO1xuICAgICAgICB0aGlzLnRvb2x0aXBfc3ViQmcuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgbGVuZ3RoICsgMTYpO1xuICAgICAgICBpZiAodHlwZW9mIGNvbG9yICE9PSBcInVuZGVmaW5lZFwiICYmIGNvbG9yICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcF9iZy5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIGNvbG9yKTtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcF9iZy5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgY29sb3IpO1xuICAgICAgICAgICAgdGhpcy50b29sdGlwX2JnLnNldEF0dHJpYnV0ZShcImZpbGwtb3BhY2l0eVwiLCBcIjAuNVwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcF9iZy5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwid2hpdGVcIik7XG4gICAgICAgICAgICB0aGlzLnRvb2x0aXBfYmcuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwiZ3JleVwiKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRvb2x0aXBfYmcuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIFwiMjhcIik7XG4gICAgICAgIHRoaXMudG9vbHRpcF9zdWJCZy5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgXCIyOFwiKTtcbiAgICAgICAgdGhpcy50b29sdGlwX2JnLnNldEF0dHJpYnV0ZShcImRpc3BsYXlcIiwgXCJibG9ja1wiKTtcbiAgICAgICAgdGhpcy50b29sdGlwX3N1YkJnLnNldEF0dHJpYnV0ZShcImRpc3BsYXlcIiwgXCJibG9ja1wiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmhpZGVUb29sdGlwKCk7XG4gICAgfVxufTtcblxuQXBwLnByb3RvdHlwZS5oaWRlVG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRvb2x0aXAuc2V0QXR0cmlidXRlKFwiZGlzcGxheVwiLCBcIm5vbmVcIik7XG4gICAgdGhpcy50b29sdGlwX2JnLnNldEF0dHJpYnV0ZShcImRpc3BsYXlcIiwgXCJub25lXCIpO1xuICAgIHRoaXMudG9vbHRpcF9zdWJCZy5zZXRBdHRyaWJ1dGUoXCJkaXNwbGF5XCIsIFwibm9uZVwiKTtcbn07XG5cbkFwcC5wcm90b3R5cGUuYWRkQ29sb3JTY2hlbWVLZXkgPSBmdW5jdGlvbiAoLypIVE1MRGl2RWxlbWVudCovIGRpdikge1xuICAgIHRoaXMuY29sb3JTY2hlbWVLZXlEaXZzLmFkZChkaXYpO1xuICAgIENvbG9yU2NoZW1lS2V5LnVwZGF0ZShkaXYsIHRoaXMpO1xufTtcblxuQXBwLnByb3RvdHlwZS5yZW1vdmVDb2xvclNjaGVtZUtleSA9IGZ1bmN0aW9uICgvKkhUTUxEaXZFbGVtZW50Ki8gY29sb3JTY2hlbWVLZXlEaXYpIHtcbiAgICB0aGlzLmNvbG9yU2NoZW1lS2V5RGl2cy5yZW1vdmUoY29sb3JTY2hlbWVLZXlEaXYpO1xuICAgIGNvbG9yU2NoZW1lS2V5RGl2LnRleHRDb250ZW50ID0gXCJcIjtcbn07XG5cbi8vZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IChub2U/KSwgdGJoIGkgbWlnaHQgaGF2ZSBtYWRlIGEgYml0IG9mIGEgbWVzcyBoZXJlXG5BcHAucHJvdG90eXBlLnNldEFubm90YXRpb25zID0gZnVuY3Rpb24gKGFubm9DaG9pY2UpIHtcbiAgICBhbm5vQ2hvaWNlID0gYW5ub0Nob2ljZS50b1VwcGVyQ2FzZSgpO1xuICAgIGZvciAobGV0IGFubm9UeXBlIG9mIHRoaXMuYW5ub3RhdGlvblNldHNTaG93bi5rZXlzKCkpIHtcbiAgICAgICAgdGhpcy5zaG93QW5ub3RhdGlvbnMoYW5ub1R5cGUsIGFubm9DaG9pY2UgPT09IGFubm9UeXBlKTtcbiAgICB9XG4gICAgdGhpcy5zaG93QW5ub3RhdGlvbnMoYW5ub0Nob2ljZSwgdHJ1ZSk7XG59O1xuXG5BcHAucHJvdG90eXBlLnNob3dBbm5vdGF0aW9ucyA9IGZ1bmN0aW9uIChhbm5vQ2hvaWNlLCBzaG93KSB7XG4gICAgYW5ub0Nob2ljZSA9IGFubm9DaG9pY2UudG9VcHBlckNhc2UoKTtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBsZXQgc2V0U2hvd24gPSB0aGlzLmFubm90YXRpb25TZXRzU2hvd24uZ2V0KGFubm9DaG9pY2UpO1xuICAgIGlmICh0eXBlb2Ygc2V0U2hvd24gPT09IFwidW5kZWZpbmVkXCIgJiYgYW5ub0Nob2ljZSAhPT0gXCJNSUZFQVRVUkVTXCIpIHtcbiAgICAgICAgZmV0Y2hBbm5vdGF0aW9ucyhhbm5vQ2hvaWNlLCB0aGlzLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzZWxmLmFubm90YXRpb25TZXRzU2hvd24uc2V0KGFubm9DaG9pY2UsIHNob3cpO1xuICAgICAgICAgICAgc2VsZi51cGRhdGVBbm5vdGF0aW9ucygpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFubm90YXRpb25TZXRzU2hvd24uc2V0KGFubm9DaG9pY2UsIHNob3cpO1xuICAgICAgICB0aGlzLnVwZGF0ZUFubm90YXRpb25zKCk7XG4gICAgfVxufTtcblxuQXBwLnByb3RvdHlwZS51cGRhdGVBbm5vdGF0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyAvL2NsZWFyIGFsbCBhbm5vdCdzXG4gICAgZm9yIChsZXQgbW9sIG9mIHRoaXMucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgICAgIGlmIChtb2wuaWQuaW5kZXhPZihcInVuaXByb3RrYl9cIikgPT09IDApIHsgLy9MSU1JVCBJVCBUTyBQUk9URUlOU1xuICAgICAgICAgICAgbW9sLmNsZWFyUG9zaXRpb25hbEZlYXR1cmVzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hvb3NlQ29sb3JzKHRoaXMpO1xuICAgIHRoaXMuY29sb3JTY2hlbWVDaGFuZ2VkKCk7XG5cbiAgICBmb3IgKGxldCBtb2wgb2YgdGhpcy5wYXJ0aWNpcGFudHMudmFsdWVzKCkpIHtcbiAgICAgICAgaWYgKG1vbC5pZC5pbmRleE9mKFwidW5pcHJvdGtiX1wiKSA9PT0gMCkgeyAvL0xJTUlUIElUIFRPIFBST1RFSU5TXG4gICAgICAgICAgICBtb2wuc2V0UG9zaXRpb25hbEZlYXR1cmVzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hvb3NlQ29sb3JzKHRoaXMpO1xuICAgIHRoaXMuY29sb3JTY2hlbWVDaGFuZ2VkKCk7XG59O1xuXG5BcHAucHJvdG90eXBlLmNvbG9yU2NoZW1lQ2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKGxldCBkaXYgb2YgdGhpcy5jb2xvclNjaGVtZUtleURpdnMpIHtcbiAgICAgICAgQ29sb3JTY2hlbWVLZXkudXBkYXRlKGRpdiwgdGhpcyk7XG4gICAgfVxufTtcblxuQXBwLnByb3RvdHlwZS5nZXRDb21wbGV4Q29sb3JzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBOYXJ5TGluay5uYXJ5Q29sb3JzO1xufTtcblxuQXBwLnByb3RvdHlwZS5nZXRGZWF0dXJlQ29sb3JzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZlYXR1cmVDb2xvcnM7XG59O1xuXG5BcHAucHJvdG90eXBlLmNvbGxhcHNlQWxsID0gZnVuY3Rpb24gKCkge1xuICAgIGZvciAobGV0IHBhcnRpY2lwYW50IG9mIHRoaXMucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgICAgIGlmIChwYXJ0aWNpcGFudC5mb3JtID09PSAxKSB7XG4gICAgICAgICAgICBwYXJ0aWNpcGFudC5zZXRGb3JtKDApO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuQXBwLnByb3RvdHlwZS5leHBhbmRBbGwgPSBmdW5jdGlvbiAoKSB7XG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgdGhpcy5wYXJ0aWNpcGFudHMudmFsdWVzKCkpIHtcbiAgICAgICAgaWYgKHBhcnRpY2lwYW50LmZvcm0gPT09IDApIHtcbiAgICAgICAgICAgIHBhcnRpY2lwYW50LnNldEZvcm0oMSk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG4vL2Zyb20gbm9lXG5BcHAucHJvdG90eXBlLmV4cGFuZEFuZENvbGxhcHNlU2VsZWN0aW9uID0gZnVuY3Rpb24gKG1vbGVjdWxlc1NlbGVjdGVkKSB7XG4gICAgY29uc3QgbW9sZWN1bGVzID0gdGhpcy5tb2xlY3VsZXMudmFsdWVzKCk7XG4gICAgZm9yICh2YXIgbSA9IDA7IG0gPCBtb2xlY3VsZXMubGVuZ3RoOyBtKyspIHtcbiAgICAgICAgdmFyIG1vbGVjdWxlID0gbW9sZWN1bGVzW21dO1xuICAgICAgICB2YXIgbW9sZWN1bGVfaWQgPSBtb2xlY3VsZS5qc29uLmlkZW50aWZpZXIuaWQ7XG4gICAgICAgIGlmIChtb2xlY3VsZXNTZWxlY3RlZC5pbmNsdWRlcyhtb2xlY3VsZV9pZCkpIHtcbiAgICAgICAgICAgIGlmIChtb2xlY3VsZS5mb3JtID09PSAwKSB7XG4gICAgICAgICAgICAgICAgbW9sZWN1bGUuc2V0Rm9ybSgxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChtb2xlY3VsZS5mb3JtID09PSAxKSB7XG4gICAgICAgICAgICBtb2xlY3VsZS5zZXRGb3JtKDApO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuXG4vLyBleHBvcnQgZnVuY3Rpb24gbWFrZVN5bWJvbEtleSh0YXJnZXREaXYpe1xuLy8gICAgIG5ldyBTeW1ib2xLZXkodGFyZ2V0RGl2KTtcbi8vIH1cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/js/app.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"App\", function() { return App; });\n/* harmony import */ var _css_xinet_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../css/xinet.css */ \"./src/css/xinet.css\");\n/* harmony import */ var _css_xinet_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_xinet_css__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _package_json__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../package.json */ \"./package.json\");\nvar _package_json__WEBPACK_IMPORTED_MODULE_1___namespace = /*#__PURE__*/__webpack_require__.t(/*! ../../package.json */ \"./package.json\", 1);\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! d3-scale-chromatic */ \"./node_modules/d3-scale-chromatic/src/index.js\");\n/* harmony import */ var _cola__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./cola */ \"./src/js/cola.js\");\n/* harmony import */ var _cola__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_cola__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _read_mijson__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./read-mijson */ \"./src/js/read-mijson.js\");\n/* harmony import */ var _annotations__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./annotations */ \"./src/js/annotations.js\");\n/* harmony import */ var _svgexp__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./svgexp */ \"./src/js/svgexp.js\");\n/* harmony import */ var _color_scheme_key__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./color-scheme-key */ \"./src/js/color-scheme-key.js\");\n/* harmony import */ var _viz_link_nary_link__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./viz/link/nary-link */ \"./src/js/viz/link/nary-link.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./config */ \"./src/js/config.js\");\n// eslint-disable-next-line no-unused-vars\n\n\n\n\n\n\n\n\n\n// import {SymbolKey} from \"./symbol-key\";\n\n\n\n\n// could refactor everything to use ES6 class syntax\n// but https://benmccormick.org/2015/04/07/es6-classes-and-backbone-js\n// \"ES6 classes don’t support adding properties directly to the class instance, only functions/methods\"\n// so backbone doesn't work\n// so continuing to use prototypical inheritance in things for time being\n\nfunction App(/*HTMLDivElement*/networkDiv) {\n // this.debug = true; // things aren't exactly lined up in the bounding boxes cola is using, to do so breaks symetery of some things\n this.el = networkDiv;\n\n this.STATES = {};\n this.STATES.MOUSE_UP = 0; //start state, also set when mouse up on svgElement\n this.STATES.PANNING = 1; //set by mouse down on svgElement - left button, no shift or util\n this.STATES.DRAGGING = 2; //set by mouse down on Protein or Link\n this.STATES.ROTATING = 3; //set by mouse down on Rotator, drag?\n this.STATES.SELECTING = 4; //set by mouse down on svgElement- right button or left button shift or util, drag\n\n //avoids prob with 'save - web page complete'\n this.el.textContent = \"\"; //https://stackoverflow.com/questions/3955229/remove-all-child-elements-of-a-dom-node-in-javascript\n\n this.d3cola = _cola__WEBPACK_IMPORTED_MODULE_4__[\"d3adaptor\"]();\n\n const customMenuSel = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](this.el)\n .append(\"div\").classed(\"custom-menu-margin\", true)\n .append(\"div\").classed(\"custom-menu\", true)\n .append(\"ul\");\n\n const self = this;\n const collapse = customMenuSel.append(\"li\").classed(\"collapse\", true); //.append(\"button\");\n collapse.text(\"Collapse\");\n collapse[0][0].onclick = function (evt) {\n self.collapseProtein(evt);\n };\n const scaleButtonsListItemSel = customMenuSel.append(\"li\").text(\"Scale: \");\n\n this.barScales = [0.01, 0.2, 1, 2, 4, 8];\n const scaleButtons = scaleButtonsListItemSel.selectAll(\"ul.custom-menu\")\n .data(this.barScales)\n .enter()\n .append(\"div\")\n .attr(\"class\", \"barScale\")\n .append(\"label\");\n scaleButtons.append(\"span\")\n .text(function (d) {\n if (d === 8) return \"AA\";\n else return d;\n });\n scaleButtons.append(\"input\")\n // .attr (\"id\", function(d) { return d*100; })\n .attr(\"class\", function (d) {\n return \"scaleButton scaleButton_\" + (d * 100);\n })\n .attr(\"name\", \"scaleButtons\")\n .attr(\"type\", \"radio\")\n .on(\"change\", function (d) {\n self.preventDefaultsAndStopPropagation(d);\n self.contextMenuProt.setStickScale(d, self.contextMenuPoint);\n });\n\n const contextMenu = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".custom-menu-margin\").node();\n contextMenu.onmouseout = function (evt) {\n let e = evt.relatedTarget;\n do {\n if (e === this) return;\n e = e.parentNode;\n } while (e);\n self.contextMenuProt = null;\n d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](this).style(\"display\", \"none\");\n };\n\n\n //create SVG element\n this.svgElement = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"svg\");\n this.svgElement.setAttribute(\"id\", \"complexViewerSVG\");\n\n //add listeners\n this.svgElement.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.svgElement.onmousemove = function (evt) {\n self.mouseMove(evt);\n };\n this.svgElement.onmouseup = function (evt) {\n self.mouseUp(evt);\n };\n this.svgElement.onmouseout = function (evt) {\n self.hideTooltip(evt);\n };\n this.lastMouseUp = new Date().getTime();\n /*this.svgElement.ontouchstart = function(evt) {\n self.touchStart(evt);\n };\n this.svgElement.ontouchmove = function(evt) {\n self.touchMove(evt);\n };\n this.svgElement.ontouchend = function(evt) {\n self.touchEnd(evt);\n };\n */\n\n this.el.oncontextmenu = function (evt) {\n if (evt.preventDefault) { // necessary for addEventListener, works with traditional\n evt.preventDefault();\n }\n evt.returnValue = false; // necessary for attachEvent, works with traditional\n return false; // works with traditional, not with attachEvent or addEventListener\n };\n\n //legend changed callbacks\n this.colorSchemeKeyDivs = new Set();\n\n this.el.appendChild(this.svgElement);\n\n // various groups needed\n this.container = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"g\");\n this.container.setAttribute(\"id\", \"container\");\n\n const svg = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](this.svgElement);\n this.defs = svg.append(\"defs\");\n\n this.acknowledgement = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"g\");\n const ackText = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"text\");\n ackText.innerHTML = \"ComplexViewer \"\n + _package_json__WEBPACK_IMPORTED_MODULE_1__[\"version\"] + \"by Rappsilber Laboratory\";\n\n this.acknowledgement.appendChild(ackText);\n ackText.setAttribute(\"font-size\", \"8pt\");\n this.svgElement.appendChild(this.acknowledgement);\n\n this.naryLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"g\");\n this.naryLinks.setAttribute(\"id\", \"naryLinks\");\n this.container.appendChild(this.naryLinks);\n\n this.p_pLinksWide = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"g\");\n this.p_pLinksWide.setAttribute(\"id\", \"p_pLinksWide\");\n this.container.appendChild(this.p_pLinksWide);\n\n this.highlights = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"g\");\n this.highlights.setAttribute(\"class\", \"highlights\"); //interactors also contain highlight groups\n this.container.appendChild(this.highlights);\n\n this.res_resLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"g\");\n this.res_resLinks.setAttribute(\"id\", \"res_resLinks\");\n this.container.appendChild(this.res_resLinks);\n\n this.p_pLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"g\");\n this.p_pLinks.setAttribute(\"id\", \"p_pLinks\");\n this.container.appendChild(this.p_pLinks);\n\n this.proteinUpper = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"g\");\n this.proteinUpper.setAttribute(\"id\", \"proteinUpper\");\n this.container.appendChild(this.proteinUpper);\n\n this.selfRes_resLinks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"g\");\n this.selfRes_resLinks.setAttribute(\"id\", \"res_resLinks\");\n this.container.appendChild(this.selfRes_resLinks);\n\n this.svgElement.appendChild(this.container);\n\n //showing title as tooltips is NOT part of svg spec (even though some browsers do this)\n //also more responsive / more control if we do out own\n this.tooltip = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"text\");\n this.tooltip.setAttribute(\"x\", \"0\");\n this.tooltip.setAttribute(\"y\", \"0\");\n const tooltipTextNode = document.createTextNode(\"tooltip\");\n this.tooltip.classList.add(\"label\", \"tooltip\");\n\n this.tooltip.appendChild(tooltipTextNode);\n\n this.tooltip_bg = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"rect\");\n this.tooltip_bg.classList.add(\"tooltip-background\");\n\n this.tooltip_subBg = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_10__[\"svgns\"], \"rect\");\n this.tooltip_subBg.classList.add(\"tooltip-sub-background\");\n\n this.svgElement.appendChild(this.tooltip_subBg);\n this.svgElement.appendChild(this.tooltip_bg);\n this.svgElement.appendChild(this.tooltip);\n\n this.clear();\n}\n\nApp.prototype.createHatchedFill = function (name, color) {\n if (!this.checkedHatchNames.has(name)) {\n const pattern = this.defs.append(\"pattern\")\n .attr(\"id\", name)\n .attr(\"patternUnits\", \"userSpaceOnUse\")\n .attr(\"x\", 0)\n .attr(\"y\", 0)\n .attr(\"width\", 12)\n .attr(\"height\", 12)\n .attr(\"patternTransform\", \"rotate(45)\");\n\n pattern.append(\"rect\")\n .attr(\"x\", 0)\n .attr(\"y\", 2)\n .attr(\"width\", 12)\n .attr(\"height\", 4)\n .attr(\"fill\", color);\n\n pattern.append(\"rect\")\n .attr(\"x\", 0)\n .attr(\"y\", 8)\n .attr(\"width\", 12)\n .attr(\"height\", 4)\n .attr(\"fill\", color);\n\n this.checkedHatchNames.add(name);\n }\n};\n\nApp.prototype.clear = function () {\n this.d3cola.stop();\n\n this.annotationSetsShown = new Map();\n // this.annotationSetsShown.set(\"MI FEATURES\", true);\n\n this.checkedHatchNames = new Set();\n\n //lighten colors\n const complexColors = [];\n for (let c of d3_scale_chromatic__WEBPACK_IMPORTED_MODULE_3__[\"schemePastel2\"]) {//colorbrewer.Pastel2[8]) {\n const hsl = d3__WEBPACK_IMPORTED_MODULE_2__[\"hsl\"](c);\n hsl.l = 0.9;\n complexColors.push(hsl + \"\");\n }\n\n _viz_link_nary_link__WEBPACK_IMPORTED_MODULE_9__[\"NaryLink\"].naryColors = d3__WEBPACK_IMPORTED_MODULE_2__[\"scale\"].ordinal().range(complexColors);\n this.defs.selectAll(\".feature_checkers\").remove();\n\n this.naryLinks.textContent = \"\";\n this.p_pLinksWide.textContent = \"\";\n this.highlights.textContent = \"\";\n this.p_pLinks.textContent = \"\";\n this.res_resLinks.textContent = \"\";\n this.proteinUpper.textContent = \"\";\n this.selfRes_resLinks.textContent = \"\";\n\n // if we are dragging something at the moment - this will be the element that is dragged\n this.dragElement = null;\n // from where did we start dragging\n this.dragStart = {};\n\n this.participants = new Map();\n this.allNaryLinks = new Map();\n this.allBinaryLinks = new Map();\n this.allUnaryLinks = new Map();\n this.allSequenceLinks = new Map();\n this.complexes = [];\n\n this.proteinCount = 0;\n this.z = 1;\n this.hideTooltip();\n this.state = this.STATES.MOUSE_UP;\n};\n\nApp.prototype.collapseProtein = function () {\n d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".custom-menu-margin\").style(\"display\", \"none\");\n this.contextMenuProt.setForm(0, this.contextMenuPoint);\n this.contextMenuProt = null;\n};\n\nApp.prototype.init = function () {\n this.d3cola.stop();\n\n for (let participant of this.participants.values()) {\n if (participant.type != \"complex\") {\n participant.setPosition(-500, -500);\n }\n }\n this.updateAnnotations();\n this.checkLinks(); //totally needed, not sure why tbh todo - check this out\n this.setAllLinkCoordinates(); // just to move them off screen at first\n\n let maxSeqLength = 0;\n for (let participant of this.participants.values()) {\n if (participant.size > maxSeqLength) {\n maxSeqLength = participant.size;\n }\n }\n const width = this.svgElement.parentNode.clientWidth;\n const defaultPixPerRes = width * 0.8 / maxSeqLength;\n //console.log(\"defaultPixPerRes:\" + defaultPixPerRes);\n // https://stackoverflow.com/questions/12141150/from-list-of-integers-get-number-closest-to-a-given-value/12141511#12141511\n function takeClosest(myList, myNumber) {\n const bisect = d3__WEBPACK_IMPORTED_MODULE_2__[\"bisector\"](function (d) {\n return d;\n }).left;\n const pos = bisect(myList, myNumber);\n if (pos === 0 || pos === 1) {\n return myList[1]; // don't return smallest scale as default\n }\n if (pos === myList.length) {\n return myList[myList.length - 1];\n }\n return myList[pos - 1];\n }\n\n this.defaultBarScale = takeClosest(this.barScales, defaultPixPerRes);\n //console.log(\"default bar scale: \" + this.defaultBarScale)\n\n for (let participant of this.participants.values()) {\n if (participant.type !== \"complex\") {\n this.proteinUpper.appendChild(participant.upperGroup);\n if (participant.json.type.name === \"protein\") {\n // participant.initSelfLinkSVG(); // todo - may not even do anything, not sure its working\n participant.stickZoom = this.defaultBarScale;\n if (this.participants.size < 4) {\n participant.toStickNoTransition();\n }\n }\n }\n }\n\n this.autoLayout();\n};\n\nApp.prototype.zoomToExtent = function () {\n const width = this.svgElement.parentNode.clientWidth;\n const height = this.svgElement.parentNode.clientHeight;\n const bbox = this.container.getBBox();\n let xr = (width / bbox.width).toFixed(4) - 0;\n let yr = (height / bbox.height).toFixed(4) - 0;\n let scaleFactor;\n if (yr < xr) {\n scaleFactor = yr;\n } else {\n scaleFactor = xr;\n }\n if (scaleFactor < 1) { ///didn't fit in div\n //console.log(\"no fit\", scaleFactor);\n xr = (width - 40) / (bbox.width);\n yr = (height - 40) / (bbox.height);\n let scaleFactor;\n if (yr < xr) {\n scaleFactor = yr;\n } else {\n scaleFactor = xr;\n }\n\n if (scaleFactor > this.z) {\n scaleFactor = this.z;\n }\n\n //bbox.x + x = 0;\n let x = -bbox.x + (20 / scaleFactor);\n //box.y + y = 0\n let y = -bbox.y + (20 / scaleFactor);\n this.container.setAttribute(\"transform\", \"scale(\" + scaleFactor + \") translate(\" + x + \" \" + y + \") \");\n this.z = this.container.getCTM().inverse().a;\n } else {\n //console.log(\"fit\", scaleFactor);\n // this.container.setAttribute(\"transform\", \"scale(\" + 1 + \") translate(\" + -(width/2) + \" \" + -bbox.y + \")\");\n const deltaWidth = width - bbox.width;\n const deltaHeight = height - bbox.height;\n //bbox.x + x = deltaWidth /2;\n let x = (deltaWidth / 2) - bbox.x;\n //box.y + y = deltaHeight / 2\n let y = (deltaHeight / 2) - bbox.y;\n this.container.setAttribute(\"transform\", \"scale(\" + 1 + \") translate(\" + x + \" \" + y + \")\");\n this.z = 1;\n }\n\n //todo - following could be tided up by using acknowledgement bbox or positioning att's of text\n this.acknowledgement.setAttribute(\"transform\", \"translate(\" + (width - 150) + \", \" + (height - 30) + \")\");\n};\n\n//listeners also attached to mouse events by Interactor (and Rotator) and Link, those consume their events\n//mouse down on svgElement must be allowed to propogate (to fire event on Prots/Links)\n\nApp.prototype.mouseDown = function (evt) {\n //prevent default, but allow propogation\n evt.preventDefault();\n this.d3cola.stop();\n const p = this.getEventPoint(evt); // seems to be correct, see below\n this.dragStart = this.mouseToSVG(p.x, p.y);\n return false;\n};\n\n// dragging/rotation/panning/selecting\nApp.prototype.mouseMove = function (evt) {\n const p = this.getEventPoint(evt); // seems to be correct, see below\n const c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement != null) { //dragging or rotating\n this.hideTooltip();\n const dx = this.dragStart.x - c.x;\n const dy = this.dragStart.y - c.y;\n\n if (this.state === this.STATES.DRAGGING) {\n // we are currently dragging things around\n let ox, oy, nx, ny;\n if (!this.dragElement.ix) {\n for (let participant of this.dragElement.participants) {\n participant.changePosition(dx, dy);\n }\n this.setAllLinkCoordinates();\n } else {\n ox = this.dragElement.ix;\n oy = this.dragElement.iy;\n nx = ox - dx;\n ny = oy - dy;\n this.dragElement.setPosition(nx, ny);\n this.dragElement.setAllLinkCoordinates();\n }\n this.dragStart = c;\n } else { //not dragging or rotating yet, maybe we should start\n // don't start dragging just on a click - we need to move the mouse a bit first\n if (Math.sqrt(dx * dx + dy * dy) > (5 * this.z)) {\n this.state = this.STATES.DRAGGING;\n\n }\n }\n } else {\n this.showTooltip(p);\n }\n return false;\n};\n\n// this ends all dragging and rotating\nApp.prototype.mouseUp = function (evt) {\n const time = new Date().getTime();\n //console.log(\"Mouse up: \" + evt.srcElement + \" \" + (time - this.lastMouseUp));\n this.preventDefaultsAndStopPropagation(evt);\n //eliminate some spurious mouse up events\n if ((time - this.lastMouseUp) > 150) {\n\n const p = this.getEventPoint(evt); // seems to be correct, see below\n const c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement && this.dragElement.type === \"protein\") { /// todo be consistent about how to check if thing is protein\n if (!(this.state === this.STATES.DRAGGING || this.state === this.STATES.ROTATING)) { //not dragging or rotating\n if (this.dragElement.form === 0) {\n this.dragElement.setForm(1);\n } else {\n this.contextMenuProt = this.dragElement;\n this.contextMenuPoint = c;\n const menu = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".custom-menu-margin\");\n menu.style(\"top\", (evt.pageY - 20) + \"px\").style(\"left\", (evt.pageX - 20) + \"px\").style(\"display\", \"block\");\n d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](\".scaleButton_\" + (this.dragElement.stickZoom * 100)).property(\"checked\", true);\n }\n }\n }\n }\n\n this.dragElement = null;\n this.state = this.STATES.MOUSE_UP;\n\n this.lastMouseUp = time;\n return false;\n};\n\n//gets mouse position\nApp.prototype.getEventPoint = function (evt) {\n const p = this.svgElement.createSVGPoint();\n let element = this.svgElement.parentNode;\n let top = 0,\n left = 0;\n do {\n top += element.offsetTop || 0;\n left += element.offsetLeft || 0;\n element = element.offsetParent;\n } while (element);\n p.x = evt.pageX - left;\n p.y = evt.pageY - top;\n return p;\n};\n\n//stop event propogation and defaults; only do what we ask\nApp.prototype.preventDefaultsAndStopPropagation = function (evt) {\n if (evt.stopPropagation)\n evt.stopPropagation();\n if (evt.cancelBubble != null)\n evt.cancelBubble = true;\n if (evt.preventDefault)\n evt.preventDefault();\n};\n\n/**\n * Handle touchstart event.\n\n App.prototype.touchStart = function(evt) {\n //prevent default, but allow propogation\n evt.preventDefault();\n\n //stop force layout\n if (typeof this.d3cola !== 'undefined' && this.d3cola != null) {\n this.d3cola.stop();\n }\n\n var p = this.getTouchEventPoint(evt); // seems to be correct, see below\n this.dragStart = this.mouseToSVG(p.x, p.y);\n};\n\n // dragging/rotation/panning/selecting\n App.prototype.touchMove = function(evt) {\n // if (this.sequenceInitComplete) { // just being cautious\n var p = this.getTouchEventPoint(evt); // seems to be correct, see below\n var c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement != null) { //dragging or rotating\n this.hideTooltip();\n var dx = this.dragStart.x - c.x;\n var dy = this.dragStart.y - c.y;\n\n if (this.state === this.STATES.DRAGGING) {\n // we are currently dragging things around\n var ox, oy, nx, ny;\n if (typeof this.dragElement.ix=== 'undefined') { // if not an Interactor\n var nodes = this.dragElement.interactors;\n var nodeCount = nodes.length;\n for (var i = 0; i < nodeCount; i++) {\n var protein = nodes[i];\n ox = protein.cx;\n oy = protein.cy;\n nx = ox - dx;\n ny = oy - dy;\n protein.setPosition(nx, ny);\n protein.setAllLinkCoordinates();\n }\n for (i = 0; i < nodeCount; i++) {\n nodes[i].setAllLinkCoordinates();\n }\n } else {\n ox = this.dragElement.cx;\n oy = this.dragElement.cy;\n nx = ox - dx;\n ny = oy - dy;\n this.dragElement.setPosition(nx, ny);\n this.dragElement.setAllLinkCoordinates();\n }\n this.dragStart = c;\n } else { //not dragging or rotating yet, maybe we should start\n // don't start dragging just on a click - we need to move the mouse a bit first\n if (Math.sqrt(dx * dx + dy * dy) > (5 * this.z)) {\n this.state = this.STATES.DRAGGING;\n\n }\n }\n } else {\n this.showTooltip(p);\n }\n return false;\n};\n\n// this ends all dragging and rotating\nApp.prototype.touchEnd = function(evt) {\n var time = new Date().getTime();\n //console.log(\"Mouse up: \" + evt.srcElement + \" \" + (time - this.lastMouseUp));\n this.preventDefaultsAndStopPropagation(evt);\n //eliminate some spurious mouse up events\n if ((time - this.lastMouseUp) > 150) {\n\n var p = this.getTouchEventPoint(evt); // seems to be correct, see below\n var c = this.mouseToSVG(p.x, p.y);\n\n if (this.dragElement != null) {\n if (!(this.state === this.STATES.DRAGGING || this.state === this.STATES.ROTATING)) { //not dragging or rotating\n if (this.dragElement.form === 0) {\n this.dragElement.setForm(1);\n } else {\n this.contextMenuProt = this.dragElement;\n this.contextMenuPoint = c;\n var menu = d3.select(\".custom-menu-margin\")\n menu.style(\"top\", (evt.pageY - 20) + \"px\").style(\"left\", (evt.pageX - 20) + \"px\").style(\"display\", \"block\");\n d3.select(\".scaleButton_\" + (this.dragElement.stickZoom * 100)).property(\"checked\", true)\n }\n }\n }\n }\n\n this.dragElement = null;\n this.whichRotator = -1;\n this.state = this.STATES.MOUSE_UP;\n\n this.lastMouseUp = time;\n return false;\n};\n\n//gets mouse position\nApp.prototype.getTouchEventPoint = function(evt) {\n var p = this.svgElement.createSVGPoint();\n var element = this.svgElement.parentNode;\n var top = 0,\n left = 0;\n do {\n top += element.offsetTop || 0;\n left += element.offsetLeft || 0;\n element = element.offsetParent;\n } while (element);\n p.x = evt.touches[0].pageX - left;\n p.y = evt.touches[0].pageY - top;\n return p;\n};\n */\nApp.prototype.autoLayout = function () {\n this.d3cola.stop();\n const self = this;\n\n // needed to ensure consistent results\n for (let p of self.participants.values()) {\n delete p.x;\n delete p.y;\n delete p.px;\n delete p.py;\n delete p.bounds;\n p.fixed = 0;\n }\n\n //// prune leaves from network then layout, then add back leaves and layout again (fixes haemoglobin)\n const pruned = [];\n for (let participant of self.participants.values()) {\n if (participant.binaryLinks.size > 2 && participant.type !== \"complex\") {\n pruned.push(participant);\n }\n }\n const allNodesExceptComplexes = Array.from(self.participants.values()).filter(function (value) {\n return value.type !== \"complex\";\n });\n\n if (pruned.length < allNodesExceptComplexes.length\n && pruned.length > 3 && self.participants.size < 9) {\n // <9 include hemoglobin, possibly some other small cases, but is catious, tends to mess other things up\n // console.log(prunedIn);\n doLayout(pruned, true);\n } else {\n doLayout(allNodesExceptComplexes, self.complexes.length > 0);\n }\n\n function doLayout(nodes, preRun) {\n const layoutObj = {}; // todo get rid\n layoutObj.nodes = nodes;\n layoutObj.links = [];\n\n const molLookUp = {};\n let mi = 0;\n for (let mol of nodes) {\n molLookUp[mol.id] = mi;\n mi++;\n }\n\n for (let binaryLink of self.allBinaryLinks.values()) {\n const fromMol = binaryLink.participants[0];\n const toMol = binaryLink.participants[1];\n // if (preRun || (fromMol.binaryLinks.size === 4 || toMol.binaryLinks.size == 4)) {\n const source = fromMol; //molLookUp[fromMol.id];\n const target = toMol; //molLookUp[toMol.id];\n\n if (source !== target && nodes.indexOf(source) !== -1 && nodes.indexOf(target) !== -1) { // todo - check what this is doing\n const linkObj = {};\n linkObj.source = molLookUp[fromMol.id];\n linkObj.target = molLookUp[toMol.id];\n linkObj.id = binaryLink.id;\n layoutObj.links.push(linkObj);\n }\n // }\n }\n\n const groups = [];\n if (!preRun && self.complexes) {\n for (let g of self.complexes) {\n g.leaves = [];\n g.groups = [];\n for (let interactor of g.naryLink.participants) {\n if (interactor.type !== \"complex\") {\n g.leaves.push(layoutObj.nodes.indexOf(interactor));\n }\n }\n groups.push(g);\n }\n for (let g of self.complexes) {\n for (let interactor of g.naryLink.participants) {\n if (interactor.type === \"complex\") {\n //console.log(groups.indexOf(interactor));\n g.groups.push(groups.indexOf(interactor));\n }\n }\n }\n }\n\n //console.log(\"groups\", groups);\n delete self.d3cola._lastStress;\n delete self.d3cola._alpha;\n delete self.d3cola._descent;\n delete self.d3cola._rootGroup;\n\n let linkLength = (nodes.length < 30) ? 30 : 20;\n const width = self.svgElement.parentNode.clientWidth;\n const height = self.svgElement.parentNode.clientHeight;\n //console.log(\"**\", layoutObj);\n self.d3cola.size([height - 40, width - 40])\n .nodes(layoutObj.nodes).groups(groups).links(layoutObj.links).avoidOverlaps(true);\n let groupDebugSel, participantDebugSel;\n if (self.debug) {\n groupDebugSel = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](self.container).selectAll(\".group\")\n .data(groups);\n\n groupDebugSel.enter().append(\"rect\")\n .classed(\"group\", true)\n .attr({\n rx: 5,\n ry: 5\n })\n .style(\"stroke\", \"blue\")\n .style(\"fill\", \"none\");\n\n participantDebugSel = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](self.container).selectAll(\".node\")\n .data(layoutObj.nodes);\n\n participantDebugSel.enter().append(\"rect\")\n .classed(\"node\", true)\n .attr({\n rx: 5,\n ry: 5\n })\n .style(\"stroke\", \"red\")\n .style(\"fill\", \"none\");\n\n groupDebugSel.exit().remove();\n participantDebugSel.exit().remove();\n }\n\n const startTime = Date.now();\n self.d3cola.symmetricDiffLinkLengths(linkLength)\n .on(\"tick\", function () {\n if (Date.now() - startTime > 750) {//!preRun) {\n const nodes = self.d3cola.nodes();\n for (let node of nodes) {\n node.setPosition(node.x, node.y);\n }\n self.setAllLinkCoordinates();\n self.zoomToExtent();\n if (self.debug) {\n groupDebugSel.attr({\n x: function (d) {\n return d.bounds.x;// + (width / 2);\n },\n y: function (d) {\n return d.bounds.y;// + (height / 2);\n },\n width: function (d) {\n return d.bounds.width();\n },\n height: function (d) {\n return d.bounds.height();\n }\n });\n\n participantDebugSel.attr({\n x: function (d) {\n return d.bounds.x;// + (width / 2);\n },\n y: function (d) {\n return d.bounds.y;// + (height / 2);\n },\n width: function (d) {\n return d.bounds.width();\n },\n height: function (d) {\n return d.bounds.height();\n }\n });\n }\n }\n })\n .on(\"end\", function () {\n if (preRun) {\n // alert(\"initial run complete\");\n // // for (let p of layoutObj.nodes) {\n // // p.fixed = 1;\n // // }\n doLayout(allNodesExceptComplexes, false);\n } else {\n for (let node of nodes) {\n node.setPosition(node.x, node.y);\n }\n self.setAllLinkCoordinates();\n self.zoomToExtent();\n }\n });\n if (preRun) {\n self.d3cola.start(23, 23, 0, 0, true);//, false, false);\n } else {\n self.d3cola.start(0, 23, 23, 0, true);//, false, false);\n }\n }\n};\n\nApp.prototype.getSVG = function () { //todo - somewhat broken, annotations missing\n var svgSel = d3__WEBPACK_IMPORTED_MODULE_2__[\"select\"](this.el).selectAll(\"svg\");\n var svgArr = [svgSel.node()];\n var svgStrings = _svgexp__WEBPACK_IMPORTED_MODULE_7__[\"svgUtils\"].capture(svgArr);\n var svgXML = _svgexp__WEBPACK_IMPORTED_MODULE_7__[\"svgUtils\"].makeXMLStr(new XMLSerializer(), svgStrings[0]);\n\n return svgXML;\n\n // var fileName = this.filenameStateString().substring(0, 240);\n // download(svgXML, 'application/svg', fileName + \".svg\");\n\n};\n\n// App.prototype.getSVG = function () {\n// let svgXml = this.svgElement.outerHTML.replace(//i, \"\"); //take out white background fill\n// const viewBox = \"viewBox=\\\"0 0 \" + this.svgElement.parentNode.clientWidth + \" \" + this.svgElement.parentNode.clientHeight + \"\\\" \";\n// svgXml = svgXml.replace(\"\" +\n// \"\" +\n// svgXml;\n// };\n\n// transform the mouse-position into a position on the svg\nApp.prototype.mouseToSVG = function (x, y) {\n const p = this.svgElement.createSVGPoint();\n p.x = x;\n p.y = y;\n return p.matrixTransform(this.container.getCTM().inverse());\n};\n\n// reads MI JSON format\nApp.prototype.readMIJSON = function (miJson, expand = true) {\n Object(_read_mijson__WEBPACK_IMPORTED_MODULE_5__[\"readMijson\"])(miJson, this, expand);\n};\n\nApp.prototype.checkLinks = function () {\n for (let link of this.allNaryLinks.values()) {\n link.check();\n }\n for (let link of this.allBinaryLinks.values()) {\n link.check();\n }\n for (let link of this.allUnaryLinks.values()) {\n link.check();\n }\n for (let link of this.allSequenceLinks.values()) {\n link.check();\n }\n};\n\nApp.prototype.setAllLinkCoordinates = function () {\n for (let link of this.allNaryLinks.values()) {\n link.setLinkCoordinates();\n }\n for (let link of this.allBinaryLinks.values()) {\n link.setLinkCoordinates();\n }\n for (let link of this.allUnaryLinks.values()) {\n link.setLinkCoordinates();\n }\n for (let link of this.allSequenceLinks.values()) {\n link.setLinkCoordinates();\n }\n};\n\nApp.prototype.showTooltip = function (p) {\n let ttX, ttY;\n const length = this.tooltip.getComputedTextLength() + 16;\n const width = this.svgElement.parentNode.clientWidth;\n const height = this.svgElement.parentNode.clientHeight;\n if (p.x + 20 + length < width) {\n ttX = p.x;\n } else {\n ttX = width - length - 20;\n }\n\n if (p.y + 60 < height) {\n ttY = p.y;\n } else {\n ttY = height - 60;\n }\n this.tooltip.setAttribute(\"x\", ttX + 22);\n this.tooltip.setAttribute(\"y\", ttY + 47);\n this.tooltip_bg.setAttribute(\"x\", ttX + 16);\n this.tooltip_bg.setAttribute(\"y\", ttY + 28);\n this.tooltip_subBg.setAttribute(\"x\", ttX + 16);\n this.tooltip_subBg.setAttribute(\"y\", ttY + 28);\n};\n\nApp.prototype.setTooltip = function (text, color) {\n if (text) {\n this.tooltip.firstChild.data = text.toString().replace(/&(quot);/g, \"\\\"\");\n this.tooltip.setAttribute(\"display\", \"block\");\n const length = this.tooltip.getComputedTextLength();\n this.tooltip_bg.setAttribute(\"width\", length + 16);\n this.tooltip_subBg.setAttribute(\"width\", length + 16);\n if (typeof color !== \"undefined\" && color != null) {\n this.tooltip_bg.setAttribute(\"fill\", color);\n this.tooltip_bg.setAttribute(\"stroke\", color);\n this.tooltip_bg.setAttribute(\"fill-opacity\", \"0.5\");\n } else {\n this.tooltip_bg.setAttribute(\"fill\", \"white\");\n this.tooltip_bg.setAttribute(\"stroke\", \"grey\");\n }\n // todo - whats this height for?\n this.tooltip_bg.setAttribute(\"height\", \"28\");\n this.tooltip_subBg.setAttribute(\"height\", \"28\");\n this.tooltip_bg.setAttribute(\"display\", \"block\");\n this.tooltip_subBg.setAttribute(\"display\", \"block\");\n } else {\n this.hideTooltip();\n }\n};\n\nApp.prototype.hideTooltip = function () {\n this.tooltip.setAttribute(\"display\", \"none\");\n this.tooltip_bg.setAttribute(\"display\", \"none\");\n this.tooltip_subBg.setAttribute(\"display\", \"none\");\n};\n\nApp.prototype.addColorSchemeKey = function (/*HTMLDivElement*/ div) {\n this.colorSchemeKeyDivs.add(div);\n _color_scheme_key__WEBPACK_IMPORTED_MODULE_8__[\"update\"](div, this);\n};\n\nApp.prototype.removeColorSchemeKey = function (/*HTMLDivElement*/ colorSchemeKeyDiv) {\n this.colorSchemeKeyDivs.remove(colorSchemeKeyDiv);\n colorSchemeKeyDiv.textContent = \"\";\n};\n\n//for backwards compatibility (noe?), tbh i might have made a bit of a mess here\nApp.prototype.setAnnotations = function (annoChoice) {\n annoChoice = annoChoice.toUpperCase();\n for (let annoType of this.annotationSetsShown.keys()) {\n this.showAnnotations(annoType, annoChoice === annoType);\n }\n this.showAnnotations(annoChoice, true);\n};\n\nApp.prototype.showAnnotations = function (annoChoice, show) {\n annoChoice = annoChoice.toUpperCase();\n const self = this;\n let setShown = this.annotationSetsShown.get(annoChoice);\n if (typeof setShown === \"undefined\" && annoChoice !== \"MIFEATURES\") {\n Object(_annotations__WEBPACK_IMPORTED_MODULE_6__[\"fetchAnnotations\"])(annoChoice, this, function () {\n self.annotationSetsShown.set(annoChoice, show);\n self.updateAnnotations();\n });\n } else {\n this.annotationSetsShown.set(annoChoice, show);\n this.updateAnnotations();\n }\n};\n\nApp.prototype.updateAnnotations = function () {\n // //clear all annot's\n for (let mol of this.participants.values()) {\n if (mol.id.indexOf(\"uniprotkb_\") === 0) { //LIMIT IT TO PROTEINS\n mol.clearPositionalFeatures();\n }\n }\n Object(_annotations__WEBPACK_IMPORTED_MODULE_6__[\"chooseColors\"])(this);\n this.colorSchemeChanged();\n\n for (let mol of this.participants.values()) {\n if (mol.id.indexOf(\"uniprotkb_\") === 0) { //LIMIT IT TO PROTEINS\n mol.setPositionalFeatures();\n }\n }\n Object(_annotations__WEBPACK_IMPORTED_MODULE_6__[\"chooseColors\"])(this);\n this.colorSchemeChanged();\n};\n\nApp.prototype.colorSchemeChanged = function () {\n for (let div of this.colorSchemeKeyDivs) {\n _color_scheme_key__WEBPACK_IMPORTED_MODULE_8__[\"update\"](div, this);\n }\n};\n\nApp.prototype.getComplexColors = function () {\n return _viz_link_nary_link__WEBPACK_IMPORTED_MODULE_9__[\"NaryLink\"].naryColors;\n};\n\nApp.prototype.getFeatureColors = function () {\n return this.featureColors;\n};\n\nApp.prototype.collapseAll = function () {\n for (let participant of this.participants.values()) {\n if (participant.form === 1) {\n participant.setForm(0);\n }\n }\n};\n\nApp.prototype.expandAll = function () {\n for (let participant of this.participants.values()) {\n if (participant.form === 0) {\n participant.setForm(1);\n }\n }\n};\n\n//from noe\nApp.prototype.expandAndCollapseSelection = function (moleculesSelected) {\n for (let participant of this.participants.values()) {\n const molecule_id = participant.json.identifier.id;\n if (moleculesSelected.includes(molecule_id)) {\n if (participant.form === 0) {\n participant.setForm(1);\n }\n } else if (participant.form === 1) {\n participant.setForm(0);\n }\n }\n};\n\n// export function makeSymbolKey(targetDiv){\n// new SymbolKey(targetDiv);\n// }//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvYXBwLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy9hcHAuanM/OTBlOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbmltcG9ydCAqIGFzIGNzcyBmcm9tIFwiLi4vY3NzL3hpbmV0LmNzc1wiO1xuaW1wb3J0IHt2ZXJzaW9ufSBmcm9tIFwiLi4vLi4vcGFja2FnZS5qc29uXCI7XG5pbXBvcnQgKiBhcyBkMyBmcm9tIFwiZDNcIjtcbmltcG9ydCAqIGFzIGQzX2Nocm9tYXRpYyBmcm9tIFwiZDMtc2NhbGUtY2hyb21hdGljXCI7XG5pbXBvcnQgKiBhcyBjb2xhIGZyb20gXCIuL2NvbGFcIjtcbmltcG9ydCB7cmVhZE1panNvbn0gZnJvbSBcIi4vcmVhZC1taWpzb25cIjtcbmltcG9ydCB7Y2hvb3NlQ29sb3JzLCBmZXRjaEFubm90YXRpb25zfSBmcm9tIFwiLi9hbm5vdGF0aW9uc1wiO1xuaW1wb3J0IHtzdmdVdGlsc30gZnJvbSBcIi4vc3ZnZXhwXCI7XG5cbi8vIGltcG9ydCB7U3ltYm9sS2V5fSBmcm9tIFwiLi9zeW1ib2wta2V5XCI7XG5pbXBvcnQgKiBhcyBDb2xvclNjaGVtZUtleSBmcm9tIFwiLi9jb2xvci1zY2hlbWUta2V5XCI7XG5pbXBvcnQge05hcnlMaW5rfSBmcm9tIFwiLi92aXovbGluay9uYXJ5LWxpbmtcIjtcbmltcG9ydCB7c3ZnbnN9IGZyb20gXCIuL2NvbmZpZ1wiO1xuXG4vLyBjb3VsZCByZWZhY3RvciBldmVyeXRoaW5nIHRvIHVzZSBFUzYgY2xhc3Mgc3ludGF4XG4vLyBidXQgaHR0cHM6Ly9iZW5tY2Nvcm1pY2sub3JnLzIwMTUvMDQvMDcvZXM2LWNsYXNzZXMtYW5kLWJhY2tib25lLWpzXG4vLyBcIkVTNiBjbGFzc2VzIGRvbuKAmXQgc3VwcG9ydCBhZGRpbmcgcHJvcGVydGllcyBkaXJlY3RseSB0byB0aGUgY2xhc3MgaW5zdGFuY2UsIG9ubHkgZnVuY3Rpb25zL21ldGhvZHNcIlxuLy8gc28gYmFja2JvbmUgZG9lc24ndCB3b3JrXG4vLyBzbyBjb250aW51aW5nIHRvIHVzZSBwcm90b3R5cGljYWwgaW5oZXJpdGFuY2UgaW4gdGhpbmdzIGZvciB0aW1lIGJlaW5nXG5cbmV4cG9ydCBmdW5jdGlvbiBBcHAoLypIVE1MRGl2RWxlbWVudCovbmV0d29ya0Rpdikge1xuICAgIC8vIHRoaXMuZGVidWcgPSB0cnVlOyAvLyB0aGluZ3MgYXJlbid0IGV4YWN0bHkgbGluZWQgdXAgaW4gdGhlIGJvdW5kaW5nIGJveGVzIGNvbGEgaXMgdXNpbmcsIHRvIGRvIHNvIGJyZWFrcyBzeW1ldGVyeSBvZiBzb21lIHRoaW5nc1xuICAgIHRoaXMuZWwgPSBuZXR3b3JrRGl2O1xuXG4gICAgdGhpcy5TVEFURVMgPSB7fTtcbiAgICB0aGlzLlNUQVRFUy5NT1VTRV9VUCA9IDA7IC8vc3RhcnQgc3RhdGUsIGFsc28gc2V0IHdoZW4gbW91c2UgdXAgb24gc3ZnRWxlbWVudFxuICAgIHRoaXMuU1RBVEVTLlBBTk5JTkcgPSAxOyAvL3NldCBieSBtb3VzZSBkb3duIG9uIHN2Z0VsZW1lbnQgLSBsZWZ0IGJ1dHRvbiwgbm8gc2hpZnQgb3IgdXRpbFxuICAgIHRoaXMuU1RBVEVTLkRSQUdHSU5HID0gMjsgLy9zZXQgYnkgbW91c2UgZG93biBvbiBQcm90ZWluIG9yIExpbmtcbiAgICB0aGlzLlNUQVRFUy5ST1RBVElORyA9IDM7IC8vc2V0IGJ5IG1vdXNlIGRvd24gb24gUm90YXRvciwgZHJhZz9cbiAgICB0aGlzLlNUQVRFUy5TRUxFQ1RJTkcgPSA0OyAvL3NldCBieSBtb3VzZSBkb3duIG9uIHN2Z0VsZW1lbnQtIHJpZ2h0IGJ1dHRvbiBvciBsZWZ0IGJ1dHRvbiBzaGlmdCBvciB1dGlsLCBkcmFnXG5cbiAgICAvL2F2b2lkcyBwcm9iIHdpdGggJ3NhdmUgLSB3ZWIgcGFnZSBjb21wbGV0ZSdcbiAgICB0aGlzLmVsLnRleHRDb250ZW50ID0gXCJcIjsgLy9odHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zOTU1MjI5L3JlbW92ZS1hbGwtY2hpbGQtZWxlbWVudHMtb2YtYS1kb20tbm9kZS1pbi1qYXZhc2NyaXB0XG5cbiAgICB0aGlzLmQzY29sYSA9IGNvbGEuZDNhZGFwdG9yKCk7XG5cbiAgICBjb25zdCBjdXN0b21NZW51U2VsID0gZDMuc2VsZWN0KHRoaXMuZWwpXG4gICAgICAgIC5hcHBlbmQoXCJkaXZcIikuY2xhc3NlZChcImN1c3RvbS1tZW51LW1hcmdpblwiLCB0cnVlKVxuICAgICAgICAuYXBwZW5kKFwiZGl2XCIpLmNsYXNzZWQoXCJjdXN0b20tbWVudVwiLCB0cnVlKVxuICAgICAgICAuYXBwZW5kKFwidWxcIik7XG5cbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBjb25zdCBjb2xsYXBzZSA9IGN1c3RvbU1lbnVTZWwuYXBwZW5kKFwibGlcIikuY2xhc3NlZChcImNvbGxhcHNlXCIsIHRydWUpOyAvLy5hcHBlbmQoXCJidXR0b25cIik7XG4gICAgY29sbGFwc2UudGV4dChcIkNvbGxhcHNlXCIpO1xuICAgIGNvbGxhcHNlWzBdWzBdLm9uY2xpY2sgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYuY29sbGFwc2VQcm90ZWluKGV2dCk7XG4gICAgfTtcbiAgICBjb25zdCBzY2FsZUJ1dHRvbnNMaXN0SXRlbVNlbCA9IGN1c3RvbU1lbnVTZWwuYXBwZW5kKFwibGlcIikudGV4dChcIlNjYWxlOiBcIik7XG5cbiAgICB0aGlzLmJhclNjYWxlcyA9IFswLjAxLCAwLjIsIDEsIDIsIDQsIDhdO1xuICAgIGNvbnN0IHNjYWxlQnV0dG9ucyA9IHNjYWxlQnV0dG9uc0xpc3RJdGVtU2VsLnNlbGVjdEFsbChcInVsLmN1c3RvbS1tZW51XCIpXG4gICAgICAgIC5kYXRhKHRoaXMuYmFyU2NhbGVzKVxuICAgICAgICAuZW50ZXIoKVxuICAgICAgICAuYXBwZW5kKFwiZGl2XCIpXG4gICAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJiYXJTY2FsZVwiKVxuICAgICAgICAuYXBwZW5kKFwibGFiZWxcIik7XG4gICAgc2NhbGVCdXR0b25zLmFwcGVuZChcInNwYW5cIilcbiAgICAgICAgLnRleHQoZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIGlmIChkID09PSA4KSByZXR1cm4gXCJBQVwiO1xuICAgICAgICAgICAgZWxzZSByZXR1cm4gZDtcbiAgICAgICAgfSk7XG4gICAgc2NhbGVCdXR0b25zLmFwcGVuZChcImlucHV0XCIpXG4gICAgICAgIC8vIC5hdHRyIChcImlkXCIsIGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGQqMTAwOyB9KVxuICAgICAgICAuYXR0cihcImNsYXNzXCIsIGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJzY2FsZUJ1dHRvbiBzY2FsZUJ1dHRvbl9cIiArIChkICogMTAwKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmF0dHIoXCJuYW1lXCIsIFwic2NhbGVCdXR0b25zXCIpXG4gICAgICAgIC5hdHRyKFwidHlwZVwiLCBcInJhZGlvXCIpXG4gICAgICAgIC5vbihcImNoYW5nZVwiLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgc2VsZi5wcmV2ZW50RGVmYXVsdHNBbmRTdG9wUHJvcGFnYXRpb24oZCk7XG4gICAgICAgICAgICBzZWxmLmNvbnRleHRNZW51UHJvdC5zZXRTdGlja1NjYWxlKGQsIHNlbGYuY29udGV4dE1lbnVQb2ludCk7XG4gICAgICAgIH0pO1xuXG4gICAgY29uc3QgY29udGV4dE1lbnUgPSBkMy5zZWxlY3QoXCIuY3VzdG9tLW1lbnUtbWFyZ2luXCIpLm5vZGUoKTtcbiAgICBjb250ZXh0TWVudS5vbm1vdXNlb3V0ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBsZXQgZSA9IGV2dC5yZWxhdGVkVGFyZ2V0O1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICBpZiAoZSA9PT0gdGhpcykgcmV0dXJuO1xuICAgICAgICAgICAgZSA9IGUucGFyZW50Tm9kZTtcbiAgICAgICAgfSB3aGlsZSAoZSk7XG4gICAgICAgIHNlbGYuY29udGV4dE1lbnVQcm90ID0gbnVsbDtcbiAgICAgICAgZDMuc2VsZWN0KHRoaXMpLnN0eWxlKFwiZGlzcGxheVwiLCBcIm5vbmVcIik7XG4gICAgfTtcblxuXG4gICAgLy9jcmVhdGUgU1ZHIGVsZW1lbnRcbiAgICB0aGlzLnN2Z0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwic3ZnXCIpO1xuICAgIHRoaXMuc3ZnRWxlbWVudC5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBcImNvbXBsZXhWaWV3ZXJTVkdcIik7XG5cbiAgICAvL2FkZCBsaXN0ZW5lcnNcbiAgICB0aGlzLnN2Z0VsZW1lbnQub25tb3VzZWRvd24gPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VEb3duKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQub25tb3VzZW1vdmUgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VNb3ZlKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQub25tb3VzZXVwID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlVXAoZXZ0KTtcbiAgICB9O1xuICAgIHRoaXMuc3ZnRWxlbWVudC5vbm1vdXNlb3V0ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLmhpZGVUb29sdGlwKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLmxhc3RNb3VzZVVwID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgLyp0aGlzLnN2Z0VsZW1lbnQub250b3VjaHN0YXJ0ID0gZnVuY3Rpb24oZXZ0KSB7XG4gICAgICAgIHNlbGYudG91Y2hTdGFydChldnQpO1xuICAgIH07XG4gICAgdGhpcy5zdmdFbGVtZW50Lm9udG91Y2htb3ZlID0gZnVuY3Rpb24oZXZ0KSB7XG4gICAgICAgIHNlbGYudG91Y2hNb3ZlKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLnN2Z0VsZW1lbnQub250b3VjaGVuZCA9IGZ1bmN0aW9uKGV2dCkge1xuICAgICAgICBzZWxmLnRvdWNoRW5kKGV2dCk7XG4gICAgfTtcbiAgICAqL1xuXG4gICAgdGhpcy5lbC5vbmNvbnRleHRtZW51ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBpZiAoZXZ0LnByZXZlbnREZWZhdWx0KSB7IC8vIG5lY2Vzc2FyeSBmb3IgYWRkRXZlbnRMaXN0ZW5lciwgd29ya3Mgd2l0aCB0cmFkaXRpb25hbFxuICAgICAgICAgICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICAgICAgZXZ0LnJldHVyblZhbHVlID0gZmFsc2U7IC8vIG5lY2Vzc2FyeSBmb3IgYXR0YWNoRXZlbnQsIHdvcmtzIHdpdGggdHJhZGl0aW9uYWxcbiAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyB3b3JrcyB3aXRoIHRyYWRpdGlvbmFsLCBub3Qgd2l0aCBhdHRhY2hFdmVudCBvciBhZGRFdmVudExpc3RlbmVyXG4gICAgfTtcblxuICAgIC8vbGVnZW5kIGNoYW5nZWQgY2FsbGJhY2tzXG4gICAgdGhpcy5jb2xvclNjaGVtZUtleURpdnMgPSBuZXcgU2V0KCk7XG5cbiAgICB0aGlzLmVsLmFwcGVuZENoaWxkKHRoaXMuc3ZnRWxlbWVudCk7XG5cbiAgICAvLyB2YXJpb3VzIGdyb3VwcyBuZWVkZWRcbiAgICB0aGlzLmNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJnXCIpO1xuICAgIHRoaXMuY29udGFpbmVyLnNldEF0dHJpYnV0ZShcImlkXCIsIFwiY29udGFpbmVyXCIpO1xuXG4gICAgY29uc3Qgc3ZnID0gZDMuc2VsZWN0KHRoaXMuc3ZnRWxlbWVudCk7XG4gICAgdGhpcy5kZWZzID0gc3ZnLmFwcGVuZChcImRlZnNcIik7XG5cbiAgICB0aGlzLmFja25vd2xlZGdlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJnXCIpO1xuICAgIGNvbnN0IGFja1RleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwidGV4dFwiKTtcbiAgICBhY2tUZXh0LmlubmVySFRNTCA9IFwiPGEgaHJlZj0naHR0cHM6Ly9hY2FkZW1pYy5vdXAuY29tL2Jpb2luZm9ybWF0aWNzL2FydGljbGUvMzMvMjIvMzY3My80MDYxMjgwJyB0YXJnZXQ9J19ibGFuayc+PHRzcGFuIHg9JzAnIGR5PScxLjJlbScgc3R5bGU9J3RleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lJz5Db21wbGV4Vmlld2VyIFwiXG4gICAgICAgICsgdmVyc2lvbiArIFwiPC90c3Bhbj48L2E+PHRzcGFuIHg9JzAnIGR5PScxLjJlbSc+YnkgPGEgaHJlZj0naHR0cDovL3JhcHBzaWxiZXJsYWIub3JnLycgdGFyZ2V0PSdfYmxhbmsnPlJhcHBzaWxiZXIgTGFib3JhdG9yeTwvYT48L3RzcGFuPlwiO1xuXG4gICAgdGhpcy5hY2tub3dsZWRnZW1lbnQuYXBwZW5kQ2hpbGQoYWNrVGV4dCk7XG4gICAgYWNrVGV4dC5zZXRBdHRyaWJ1dGUoXCJmb250LXNpemVcIiwgXCI4cHRcIik7XG4gICAgdGhpcy5zdmdFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuYWNrbm93bGVkZ2VtZW50KTtcblxuICAgIHRoaXMubmFyeUxpbmtzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5uYXJ5TGlua3Muc2V0QXR0cmlidXRlKFwiaWRcIiwgXCJuYXJ5TGlua3NcIik7XG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5uYXJ5TGlua3MpO1xuXG4gICAgdGhpcy5wX3BMaW5rc1dpZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwiZ1wiKTtcbiAgICB0aGlzLnBfcExpbmtzV2lkZS5zZXRBdHRyaWJ1dGUoXCJpZFwiLCBcInBfcExpbmtzV2lkZVwiKTtcbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLnBfcExpbmtzV2lkZSk7XG5cbiAgICB0aGlzLmhpZ2hsaWdodHMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwiZ1wiKTtcbiAgICB0aGlzLmhpZ2hsaWdodHMuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgXCJoaWdobGlnaHRzXCIpOyAvL2ludGVyYWN0b3JzIGFsc28gY29udGFpbiBoaWdobGlnaHQgZ3JvdXBzXG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5oaWdobGlnaHRzKTtcblxuICAgIHRoaXMucmVzX3Jlc0xpbmtzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5yZXNfcmVzTGlua3Muc2V0QXR0cmlidXRlKFwiaWRcIiwgXCJyZXNfcmVzTGlua3NcIik7XG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5yZXNfcmVzTGlua3MpO1xuXG4gICAgdGhpcy5wX3BMaW5rcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJnXCIpO1xuICAgIHRoaXMucF9wTGlua3Muc2V0QXR0cmlidXRlKFwiaWRcIiwgXCJwX3BMaW5rc1wiKTtcbiAgICB0aGlzLmNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLnBfcExpbmtzKTtcblxuICAgIHRoaXMucHJvdGVpblVwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5wcm90ZWluVXBwZXIuc2V0QXR0cmlidXRlKFwiaWRcIiwgXCJwcm90ZWluVXBwZXJcIik7XG4gICAgdGhpcy5jb250YWluZXIuYXBwZW5kQ2hpbGQodGhpcy5wcm90ZWluVXBwZXIpO1xuXG4gICAgdGhpcy5zZWxmUmVzX3Jlc0xpbmtzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5zZWxmUmVzX3Jlc0xpbmtzLnNldEF0dHJpYnV0ZShcImlkXCIsIFwicmVzX3Jlc0xpbmtzXCIpO1xuICAgIHRoaXMuY29udGFpbmVyLmFwcGVuZENoaWxkKHRoaXMuc2VsZlJlc19yZXNMaW5rcyk7XG5cbiAgICB0aGlzLnN2Z0VsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy5jb250YWluZXIpO1xuXG4gICAgLy9zaG93aW5nIHRpdGxlIGFzIHRvb2x0aXBzIGlzIE5PVCBwYXJ0IG9mIHN2ZyBzcGVjIChldmVuIHRob3VnaCBzb21lIGJyb3dzZXJzIGRvIHRoaXMpXG4gICAgLy9hbHNvIG1vcmUgcmVzcG9uc2l2ZSAvIG1vcmUgY29udHJvbCBpZiB3ZSBkbyBvdXQgb3duXG4gICAgdGhpcy50b29sdGlwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInRleHRcIik7XG4gICAgdGhpcy50b29sdGlwLnNldEF0dHJpYnV0ZShcInhcIiwgXCIwXCIpO1xuICAgIHRoaXMudG9vbHRpcC5zZXRBdHRyaWJ1dGUoXCJ5XCIsIFwiMFwiKTtcbiAgICBjb25zdCB0b29sdGlwVGV4dE5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcInRvb2x0aXBcIik7XG4gICAgdGhpcy50b29sdGlwLmNsYXNzTGlzdC5hZGQoXCJsYWJlbFwiLCBcInRvb2x0aXBcIik7XG5cbiAgICB0aGlzLnRvb2x0aXAuYXBwZW5kQ2hpbGQodG9vbHRpcFRleHROb2RlKTtcblxuICAgIHRoaXMudG9vbHRpcF9iZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJyZWN0XCIpO1xuICAgIHRoaXMudG9vbHRpcF9iZy5jbGFzc0xpc3QuYWRkKFwidG9vbHRpcC1iYWNrZ3JvdW5kXCIpO1xuXG4gICAgdGhpcy50b29sdGlwX3N1YkJnID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInJlY3RcIik7XG4gICAgdGhpcy50b29sdGlwX3N1YkJnLmNsYXNzTGlzdC5hZGQoXCJ0b29sdGlwLXN1Yi1iYWNrZ3JvdW5kXCIpO1xuXG4gICAgdGhpcy5zdmdFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudG9vbHRpcF9zdWJCZyk7XG4gICAgdGhpcy5zdmdFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudG9vbHRpcF9iZyk7XG4gICAgdGhpcy5zdmdFbGVtZW50LmFwcGVuZENoaWxkKHRoaXMudG9vbHRpcCk7XG5cbiAgICB0aGlzLmNsZWFyKCk7XG59XG5cbkFwcC5wcm90b3R5cGUuY3JlYXRlSGF0Y2hlZEZpbGwgPSBmdW5jdGlvbiAobmFtZSwgY29sb3IpIHtcbiAgICBpZiAoIXRoaXMuY2hlY2tlZEhhdGNoTmFtZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgIGNvbnN0IHBhdHRlcm4gPSB0aGlzLmRlZnMuYXBwZW5kKFwicGF0dGVyblwiKVxuICAgICAgICAgICAgLmF0dHIoXCJpZFwiLCBuYW1lKVxuICAgICAgICAgICAgLmF0dHIoXCJwYXR0ZXJuVW5pdHNcIiwgXCJ1c2VyU3BhY2VPblVzZVwiKVxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIDApXG4gICAgICAgICAgICAuYXR0cihcInlcIiwgMClcbiAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgMTIpXG4gICAgICAgICAgICAuYXR0cihcImhlaWdodFwiLCAxMilcbiAgICAgICAgICAgIC5hdHRyKFwicGF0dGVyblRyYW5zZm9ybVwiLCBcInJvdGF0ZSg0NSlcIik7XG5cbiAgICAgICAgcGF0dGVybi5hcHBlbmQoXCJyZWN0XCIpXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgMClcbiAgICAgICAgICAgIC5hdHRyKFwieVwiLCAyKVxuICAgICAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCAxMilcbiAgICAgICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIDQpXG4gICAgICAgICAgICAuYXR0cihcImZpbGxcIiwgY29sb3IpO1xuXG4gICAgICAgIHBhdHRlcm4uYXBwZW5kKFwicmVjdFwiKVxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIDApXG4gICAgICAgICAgICAuYXR0cihcInlcIiwgOClcbiAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgMTIpXG4gICAgICAgICAgICAuYXR0cihcImhlaWdodFwiLCA0KVxuICAgICAgICAgICAgLmF0dHIoXCJmaWxsXCIsIGNvbG9yKTtcblxuICAgICAgICB0aGlzLmNoZWNrZWRIYXRjaE5hbWVzLmFkZChuYW1lKTtcbiAgICB9XG59O1xuXG5BcHAucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZDNjb2xhLnN0b3AoKTtcblxuICAgIHRoaXMuYW5ub3RhdGlvblNldHNTaG93biA9IG5ldyBNYXAoKTtcbiAgICAvLyB0aGlzLmFubm90YXRpb25TZXRzU2hvd24uc2V0KFwiTUkgRkVBVFVSRVNcIiwgdHJ1ZSk7XG5cbiAgICB0aGlzLmNoZWNrZWRIYXRjaE5hbWVzID0gbmV3IFNldCgpO1xuXG4gICAgLy9saWdodGVuIGNvbG9yc1xuICAgIGNvbnN0IGNvbXBsZXhDb2xvcnMgPSBbXTtcbiAgICBmb3IgKGxldCBjIG9mIGQzX2Nocm9tYXRpYy5zY2hlbWVQYXN0ZWwyKSB7Ly9jb2xvcmJyZXdlci5QYXN0ZWwyWzhdKSB7XG4gICAgICAgIGNvbnN0IGhzbCA9IGQzLmhzbChjKTtcbiAgICAgICAgaHNsLmwgPSAwLjk7XG4gICAgICAgIGNvbXBsZXhDb2xvcnMucHVzaChoc2wgKyBcIlwiKTtcbiAgICB9XG5cbiAgICBOYXJ5TGluay5uYXJ5Q29sb3JzID0gZDMuc2NhbGUub3JkaW5hbCgpLnJhbmdlKGNvbXBsZXhDb2xvcnMpO1xuICAgIHRoaXMuZGVmcy5zZWxlY3RBbGwoXCIuZmVhdHVyZV9jaGVja2Vyc1wiKS5yZW1vdmUoKTtcblxuICAgIHRoaXMubmFyeUxpbmtzLnRleHRDb250ZW50ID0gXCJcIjtcbiAgICB0aGlzLnBfcExpbmtzV2lkZS50ZXh0Q29udGVudCA9IFwiXCI7XG4gICAgdGhpcy5oaWdobGlnaHRzLnRleHRDb250ZW50ID0gXCJcIjtcbiAgICB0aGlzLnBfcExpbmtzLnRleHRDb250ZW50ID0gXCJcIjtcbiAgICB0aGlzLnJlc19yZXNMaW5rcy50ZXh0Q29udGVudCA9IFwiXCI7XG4gICAgdGhpcy5wcm90ZWluVXBwZXIudGV4dENvbnRlbnQgPSBcIlwiO1xuICAgIHRoaXMuc2VsZlJlc19yZXNMaW5rcy50ZXh0Q29udGVudCA9IFwiXCI7XG5cbiAgICAvLyBpZiB3ZSBhcmUgZHJhZ2dpbmcgc29tZXRoaW5nIGF0IHRoZSBtb21lbnQgLSB0aGlzIHdpbGwgYmUgdGhlIGVsZW1lbnQgdGhhdCBpcyBkcmFnZ2VkXG4gICAgdGhpcy5kcmFnRWxlbWVudCA9IG51bGw7XG4gICAgLy8gZnJvbSB3aGVyZSBkaWQgd2Ugc3RhcnQgZHJhZ2dpbmdcbiAgICB0aGlzLmRyYWdTdGFydCA9IHt9O1xuXG4gICAgdGhpcy5wYXJ0aWNpcGFudHMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5hbGxOYXJ5TGlua3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5hbGxCaW5hcnlMaW5rcyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmFsbFVuYXJ5TGlua3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5hbGxTZXF1ZW5jZUxpbmtzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuY29tcGxleGVzID0gW107XG5cbiAgICB0aGlzLnByb3RlaW5Db3VudCA9IDA7XG4gICAgdGhpcy56ID0gMTtcbiAgICB0aGlzLmhpZGVUb29sdGlwKCk7XG4gICAgdGhpcy5zdGF0ZSA9IHRoaXMuU1RBVEVTLk1PVVNFX1VQO1xufTtcblxuQXBwLnByb3RvdHlwZS5jb2xsYXBzZVByb3RlaW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgZDMuc2VsZWN0KFwiLmN1c3RvbS1tZW51LW1hcmdpblwiKS5zdHlsZShcImRpc3BsYXlcIiwgXCJub25lXCIpO1xuICAgIHRoaXMuY29udGV4dE1lbnVQcm90LnNldEZvcm0oMCwgdGhpcy5jb250ZXh0TWVudVBvaW50KTtcbiAgICB0aGlzLmNvbnRleHRNZW51UHJvdCA9IG51bGw7XG59O1xuXG5BcHAucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5kM2NvbGEuc3RvcCgpO1xuXG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgdGhpcy5wYXJ0aWNpcGFudHMudmFsdWVzKCkpIHtcbiAgICAgICAgaWYgKHBhcnRpY2lwYW50LnR5cGUgIT0gXCJjb21wbGV4XCIpIHtcbiAgICAgICAgICAgIHBhcnRpY2lwYW50LnNldFBvc2l0aW9uKC01MDAsIC01MDApO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRoaXMudXBkYXRlQW5ub3RhdGlvbnMoKTtcbiAgICB0aGlzLmNoZWNrTGlua3MoKTsgLy90b3RhbGx5IG5lZWRlZCwgbm90IHN1cmUgd2h5IHRiaCB0b2RvIC0gY2hlY2sgdGhpcyBvdXRcbiAgICB0aGlzLnNldEFsbExpbmtDb29yZGluYXRlcygpOyAvLyBqdXN0IHRvIG1vdmUgdGhlbSBvZmYgc2NyZWVuIGF0IGZpcnN0XG5cbiAgICBsZXQgbWF4U2VxTGVuZ3RoID0gMDtcbiAgICBmb3IgKGxldCBwYXJ0aWNpcGFudCBvZiB0aGlzLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkge1xuICAgICAgICBpZiAocGFydGljaXBhbnQuc2l6ZSA+IG1heFNlcUxlbmd0aCkge1xuICAgICAgICAgICAgbWF4U2VxTGVuZ3RoID0gcGFydGljaXBhbnQuc2l6ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCB3aWR0aCA9IHRoaXMuc3ZnRWxlbWVudC5wYXJlbnROb2RlLmNsaWVudFdpZHRoO1xuICAgIGNvbnN0IGRlZmF1bHRQaXhQZXJSZXMgPSB3aWR0aCAqIDAuOCAvIG1heFNlcUxlbmd0aDtcbiAgICAvL2NvbnNvbGUubG9nKFwiZGVmYXVsdFBpeFBlclJlczpcIiArIGRlZmF1bHRQaXhQZXJSZXMpO1xuICAgIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEyMTQxMTUwL2Zyb20tbGlzdC1vZi1pbnRlZ2Vycy1nZXQtbnVtYmVyLWNsb3Nlc3QtdG8tYS1naXZlbi12YWx1ZS8xMjE0MTUxMSMxMjE0MTUxMVxuICAgIGZ1bmN0aW9uIHRha2VDbG9zZXN0KG15TGlzdCwgbXlOdW1iZXIpIHtcbiAgICAgICAgY29uc3QgYmlzZWN0ID0gZDMuYmlzZWN0b3IoZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgIHJldHVybiBkO1xuICAgICAgICB9KS5sZWZ0O1xuICAgICAgICBjb25zdCBwb3MgPSBiaXNlY3QobXlMaXN0LCBteU51bWJlcik7XG4gICAgICAgIGlmIChwb3MgPT09IDAgfHwgcG9zID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gbXlMaXN0WzFdOyAvLyBkb24ndCByZXR1cm4gc21hbGxlc3Qgc2NhbGUgYXMgZGVmYXVsdFxuICAgICAgICB9XG4gICAgICAgIGlmIChwb3MgPT09IG15TGlzdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBteUxpc3RbbXlMaXN0Lmxlbmd0aCAtIDFdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBteUxpc3RbcG9zIC0gMV07XG4gICAgfVxuXG4gICAgdGhpcy5kZWZhdWx0QmFyU2NhbGUgPSB0YWtlQ2xvc2VzdCh0aGlzLmJhclNjYWxlcywgZGVmYXVsdFBpeFBlclJlcyk7XG4gICAgLy9jb25zb2xlLmxvZyhcImRlZmF1bHQgYmFyIHNjYWxlOiBcIiArIHRoaXMuZGVmYXVsdEJhclNjYWxlKVxuXG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgdGhpcy5wYXJ0aWNpcGFudHMudmFsdWVzKCkpIHtcbiAgICAgICAgaWYgKHBhcnRpY2lwYW50LnR5cGUgIT09IFwiY29tcGxleFwiKSB7XG4gICAgICAgICAgICB0aGlzLnByb3RlaW5VcHBlci5hcHBlbmRDaGlsZChwYXJ0aWNpcGFudC51cHBlckdyb3VwKTtcbiAgICAgICAgICAgIGlmIChwYXJ0aWNpcGFudC5qc29uLnR5cGUubmFtZSA9PT0gXCJwcm90ZWluXCIpIHtcbiAgICAgICAgICAgICAgICAvLyBwYXJ0aWNpcGFudC5pbml0U2VsZkxpbmtTVkcoKTsgLy8gdG9kbyAtIG1heSBub3QgZXZlbiBkbyBhbnl0aGluZywgbm90IHN1cmUgaXRzIHdvcmtpbmdcbiAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudC5zdGlja1pvb20gPSB0aGlzLmRlZmF1bHRCYXJTY2FsZTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wYXJ0aWNpcGFudHMuc2l6ZSA8IDQpIHtcbiAgICAgICAgICAgICAgICAgICAgcGFydGljaXBhbnQudG9TdGlja05vVHJhbnNpdGlvbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuYXV0b0xheW91dCgpO1xufTtcblxuQXBwLnByb3RvdHlwZS56b29tVG9FeHRlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLnN2Z0VsZW1lbnQucGFyZW50Tm9kZS5jbGllbnRXaWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLnN2Z0VsZW1lbnQucGFyZW50Tm9kZS5jbGllbnRIZWlnaHQ7XG4gICAgY29uc3QgYmJveCA9IHRoaXMuY29udGFpbmVyLmdldEJCb3goKTtcbiAgICBsZXQgeHIgPSAod2lkdGggLyBiYm94LndpZHRoKS50b0ZpeGVkKDQpIC0gMDtcbiAgICBsZXQgeXIgPSAoaGVpZ2h0IC8gYmJveC5oZWlnaHQpLnRvRml4ZWQoNCkgLSAwO1xuICAgIGxldCBzY2FsZUZhY3RvcjtcbiAgICBpZiAoeXIgPCB4cikge1xuICAgICAgICBzY2FsZUZhY3RvciA9IHlyO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHNjYWxlRmFjdG9yID0geHI7XG4gICAgfVxuICAgIGlmIChzY2FsZUZhY3RvciA8IDEpIHsgLy8vZGlkbid0IGZpdCBpbiBkaXZcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcIm5vIGZpdFwiLCBzY2FsZUZhY3Rvcik7XG4gICAgICAgIHhyID0gKHdpZHRoIC0gNDApIC8gKGJib3gud2lkdGgpO1xuICAgICAgICB5ciA9IChoZWlnaHQgLSA0MCkgLyAoYmJveC5oZWlnaHQpO1xuICAgICAgICBsZXQgc2NhbGVGYWN0b3I7XG4gICAgICAgIGlmICh5ciA8IHhyKSB7XG4gICAgICAgICAgICBzY2FsZUZhY3RvciA9IHlyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2NhbGVGYWN0b3IgPSB4cjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzY2FsZUZhY3RvciA+IHRoaXMueikge1xuICAgICAgICAgICAgc2NhbGVGYWN0b3IgPSB0aGlzLno7XG4gICAgICAgIH1cblxuICAgICAgICAvL2Jib3gueCArIHggPSAwO1xuICAgICAgICBsZXQgeCA9IC1iYm94LnggKyAoMjAgLyBzY2FsZUZhY3Rvcik7XG4gICAgICAgIC8vYm94LnkgKyB5ID0gMFxuICAgICAgICBsZXQgeSA9IC1iYm94LnkgKyAoMjAgLyBzY2FsZUZhY3Rvcik7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBcInNjYWxlKFwiICsgc2NhbGVGYWN0b3IgKyBcIikgdHJhbnNsYXRlKFwiICsgeCArIFwiIFwiICsgeSArIFwiKSBcIik7XG4gICAgICAgIHRoaXMueiA9IHRoaXMuY29udGFpbmVyLmdldENUTSgpLmludmVyc2UoKS5hO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vY29uc29sZS5sb2coXCJmaXRcIiwgc2NhbGVGYWN0b3IpO1xuICAgICAgICAvLyB0aGlzLmNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgXCJzY2FsZShcIiArIDEgKyBcIikgdHJhbnNsYXRlKFwiICsgLSh3aWR0aC8yKSArIFwiIFwiICsgLWJib3gueSArIFwiKVwiKTtcbiAgICAgICAgY29uc3QgZGVsdGFXaWR0aCA9IHdpZHRoIC0gYmJveC53aWR0aDtcbiAgICAgICAgY29uc3QgZGVsdGFIZWlnaHQgPSBoZWlnaHQgLSBiYm94LmhlaWdodDtcbiAgICAgICAgLy9iYm94LnggKyB4ID0gZGVsdGFXaWR0aCAvMjtcbiAgICAgICAgbGV0IHggPSAoZGVsdGFXaWR0aCAvIDIpIC0gYmJveC54O1xuICAgICAgICAvL2JveC55ICsgeSA9IGRlbHRhSGVpZ2h0IC8gMlxuICAgICAgICBsZXQgeSA9IChkZWx0YUhlaWdodCAvIDIpIC0gYmJveC55O1xuICAgICAgICB0aGlzLmNvbnRhaW5lci5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgXCJzY2FsZShcIiArIDEgKyBcIikgdHJhbnNsYXRlKFwiICsgeCArIFwiIFwiICsgeSArIFwiKVwiKTtcbiAgICAgICAgdGhpcy56ID0gMTtcbiAgICB9XG5cbiAgICAvL3RvZG8gLSBmb2xsb3dpbmcgY291bGQgYmUgdGlkZWQgdXAgYnkgdXNpbmcgYWNrbm93bGVkZ2VtZW50IGJib3ggb3IgcG9zaXRpb25pbmcgYXR0J3Mgb2YgdGV4dFxuICAgIHRoaXMuYWNrbm93bGVkZ2VtZW50LnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIiArICh3aWR0aCAtIDE1MCkgKyBcIiwgXCIgKyAoaGVpZ2h0IC0gMzApICsgXCIpXCIpO1xufTtcblxuLy9saXN0ZW5lcnMgYWxzbyBhdHRhY2hlZCB0byBtb3VzZSBldmVudHMgYnkgSW50ZXJhY3RvciAoYW5kIFJvdGF0b3IpIGFuZCBMaW5rLCB0aG9zZSBjb25zdW1lIHRoZWlyIGV2ZW50c1xuLy9tb3VzZSBkb3duIG9uIHN2Z0VsZW1lbnQgbXVzdCBiZSBhbGxvd2VkIHRvIHByb3BvZ2F0ZSAodG8gZmlyZSBldmVudCBvbiBQcm90cy9MaW5rcylcblxuQXBwLnByb3RvdHlwZS5tb3VzZURvd24gPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgLy9wcmV2ZW50IGRlZmF1bHQsIGJ1dCBhbGxvdyBwcm9wb2dhdGlvblxuICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuZDNjb2xhLnN0b3AoKTtcbiAgICBjb25zdCBwID0gdGhpcy5nZXRFdmVudFBvaW50KGV2dCk7IC8vIHNlZW1zIHRvIGJlIGNvcnJlY3QsIHNlZSBiZWxvd1xuICAgIHRoaXMuZHJhZ1N0YXJ0ID0gdGhpcy5tb3VzZVRvU1ZHKHAueCwgcC55KTtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG4vLyBkcmFnZ2luZy9yb3RhdGlvbi9wYW5uaW5nL3NlbGVjdGluZ1xuQXBwLnByb3RvdHlwZS5tb3VzZU1vdmUgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgY29uc3QgcCA9IHRoaXMuZ2V0RXZlbnRQb2ludChldnQpOyAvLyBzZWVtcyB0byBiZSBjb3JyZWN0LCBzZWUgYmVsb3dcbiAgICBjb25zdCBjID0gdGhpcy5tb3VzZVRvU1ZHKHAueCwgcC55KTtcblxuICAgIGlmICh0aGlzLmRyYWdFbGVtZW50ICE9IG51bGwpIHsgLy9kcmFnZ2luZyBvciByb3RhdGluZ1xuICAgICAgICB0aGlzLmhpZGVUb29sdGlwKCk7XG4gICAgICAgIGNvbnN0IGR4ID0gdGhpcy5kcmFnU3RhcnQueCAtIGMueDtcbiAgICAgICAgY29uc3QgZHkgPSB0aGlzLmRyYWdTdGFydC55IC0gYy55O1xuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlID09PSB0aGlzLlNUQVRFUy5EUkFHR0lORykge1xuICAgICAgICAgICAgLy8gd2UgYXJlIGN1cnJlbnRseSBkcmFnZ2luZyB0aGluZ3MgYXJvdW5kXG4gICAgICAgICAgICBsZXQgb3gsIG95LCBueCwgbnk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuZHJhZ0VsZW1lbnQuaXgpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBwYXJ0aWNpcGFudCBvZiB0aGlzLmRyYWdFbGVtZW50LnBhcnRpY2lwYW50cykge1xuICAgICAgICAgICAgICAgICAgICBwYXJ0aWNpcGFudC5jaGFuZ2VQb3NpdGlvbihkeCwgZHkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnNldEFsbExpbmtDb29yZGluYXRlcygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBveCA9IHRoaXMuZHJhZ0VsZW1lbnQuaXg7XG4gICAgICAgICAgICAgICAgb3kgPSB0aGlzLmRyYWdFbGVtZW50Lml5O1xuICAgICAgICAgICAgICAgIG54ID0gb3ggLSBkeDtcbiAgICAgICAgICAgICAgICBueSA9IG95IC0gZHk7XG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnRWxlbWVudC5zZXRQb3NpdGlvbihueCwgbnkpO1xuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0VsZW1lbnQuc2V0QWxsTGlua0Nvb3JkaW5hdGVzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmRyYWdTdGFydCA9IGM7XG4gICAgICAgIH0gZWxzZSB7IC8vbm90IGRyYWdnaW5nIG9yIHJvdGF0aW5nIHlldCwgbWF5YmUgd2Ugc2hvdWxkIHN0YXJ0XG4gICAgICAgICAgICAvLyBkb24ndCBzdGFydCBkcmFnZ2luZyBqdXN0IG9uIGEgY2xpY2sgLSB3ZSBuZWVkIHRvIG1vdmUgdGhlIG1vdXNlIGEgYml0IGZpcnN0XG4gICAgICAgICAgICBpZiAoTWF0aC5zcXJ0KGR4ICogZHggKyBkeSAqIGR5KSA+ICg1ICogdGhpcy56KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUgPSB0aGlzLlNUQVRFUy5EUkFHR0lORztcblxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zaG93VG9vbHRpcChwKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuLy8gdGhpcyBlbmRzIGFsbCBkcmFnZ2luZyBhbmQgcm90YXRpbmdcbkFwcC5wcm90b3R5cGUubW91c2VVcCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICBjb25zdCB0aW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gICAgLy9jb25zb2xlLmxvZyhcIk1vdXNlIHVwOiBcIiArIGV2dC5zcmNFbGVtZW50ICsgXCIgXCIgKyAodGltZSAtIHRoaXMubGFzdE1vdXNlVXApKTtcbiAgICB0aGlzLnByZXZlbnREZWZhdWx0c0FuZFN0b3BQcm9wYWdhdGlvbihldnQpO1xuICAgIC8vZWxpbWluYXRlIHNvbWUgc3B1cmlvdXMgbW91c2UgdXAgZXZlbnRzXG4gICAgaWYgKCh0aW1lIC0gdGhpcy5sYXN0TW91c2VVcCkgPiAxNTApIHtcblxuICAgICAgICBjb25zdCBwID0gdGhpcy5nZXRFdmVudFBvaW50KGV2dCk7IC8vIHNlZW1zIHRvIGJlIGNvcnJlY3QsIHNlZSBiZWxvd1xuICAgICAgICBjb25zdCBjID0gdGhpcy5tb3VzZVRvU1ZHKHAueCwgcC55KTtcblxuICAgICAgICBpZiAodGhpcy5kcmFnRWxlbWVudCAmJiB0aGlzLmRyYWdFbGVtZW50LnR5cGUgPT09IFwicHJvdGVpblwiKSB7IC8vLyB0b2RvIGJlIGNvbnNpc3RlbnQgYWJvdXQgaG93IHRvIGNoZWNrIGlmIHRoaW5nIGlzIHByb3RlaW5cbiAgICAgICAgICAgIGlmICghKHRoaXMuc3RhdGUgPT09IHRoaXMuU1RBVEVTLkRSQUdHSU5HIHx8IHRoaXMuc3RhdGUgPT09IHRoaXMuU1RBVEVTLlJPVEFUSU5HKSkgeyAvL25vdCBkcmFnZ2luZyBvciByb3RhdGluZ1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRyYWdFbGVtZW50LmZvcm0gPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kcmFnRWxlbWVudC5zZXRGb3JtKDEpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dE1lbnVQcm90ID0gdGhpcy5kcmFnRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0TWVudVBvaW50ID0gYztcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVudSA9IGQzLnNlbGVjdChcIi5jdXN0b20tbWVudS1tYXJnaW5cIik7XG4gICAgICAgICAgICAgICAgICAgIG1lbnUuc3R5bGUoXCJ0b3BcIiwgKGV2dC5wYWdlWSAtIDIwKSArIFwicHhcIikuc3R5bGUoXCJsZWZ0XCIsIChldnQucGFnZVggLSAyMCkgKyBcInB4XCIpLnN0eWxlKFwiZGlzcGxheVwiLCBcImJsb2NrXCIpO1xuICAgICAgICAgICAgICAgICAgICBkMy5zZWxlY3QoXCIuc2NhbGVCdXR0b25fXCIgKyAodGhpcy5kcmFnRWxlbWVudC5zdGlja1pvb20gKiAxMDApKS5wcm9wZXJ0eShcImNoZWNrZWRcIiwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5kcmFnRWxlbWVudCA9IG51bGw7XG4gICAgdGhpcy5zdGF0ZSA9IHRoaXMuU1RBVEVTLk1PVVNFX1VQO1xuXG4gICAgdGhpcy5sYXN0TW91c2VVcCA9IHRpbWU7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuLy9nZXRzIG1vdXNlIHBvc2l0aW9uXG5BcHAucHJvdG90eXBlLmdldEV2ZW50UG9pbnQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgY29uc3QgcCA9IHRoaXMuc3ZnRWxlbWVudC5jcmVhdGVTVkdQb2ludCgpO1xuICAgIGxldCBlbGVtZW50ID0gdGhpcy5zdmdFbGVtZW50LnBhcmVudE5vZGU7XG4gICAgbGV0IHRvcCA9IDAsXG4gICAgICAgIGxlZnQgPSAwO1xuICAgIGRvIHtcbiAgICAgICAgdG9wICs9IGVsZW1lbnQub2Zmc2V0VG9wIHx8IDA7XG4gICAgICAgIGxlZnQgKz0gZWxlbWVudC5vZmZzZXRMZWZ0IHx8IDA7XG4gICAgICAgIGVsZW1lbnQgPSBlbGVtZW50Lm9mZnNldFBhcmVudDtcbiAgICB9IHdoaWxlIChlbGVtZW50KTtcbiAgICBwLnggPSBldnQucGFnZVggLSBsZWZ0O1xuICAgIHAueSA9IGV2dC5wYWdlWSAtIHRvcDtcbiAgICByZXR1cm4gcDtcbn07XG5cbi8vc3RvcCBldmVudCBwcm9wb2dhdGlvbiBhbmQgZGVmYXVsdHM7IG9ubHkgZG8gd2hhdCB3ZSBhc2tcbkFwcC5wcm90b3R5cGUucHJldmVudERlZmF1bHRzQW5kU3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIGlmIChldnQuc3RvcFByb3BhZ2F0aW9uKVxuICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKGV2dC5jYW5jZWxCdWJibGUgIT0gbnVsbClcbiAgICAgICAgZXZ0LmNhbmNlbEJ1YmJsZSA9IHRydWU7XG4gICAgaWYgKGV2dC5wcmV2ZW50RGVmYXVsdClcbiAgICAgICAgZXZ0LnByZXZlbnREZWZhdWx0KCk7XG59O1xuXG4vKipcbiAqIEhhbmRsZSB0b3VjaHN0YXJ0IGV2ZW50LlxuXG4gQXBwLnByb3RvdHlwZS50b3VjaFN0YXJ0ID0gZnVuY3Rpb24oZXZ0KSB7XG4gICAgLy9wcmV2ZW50IGRlZmF1bHQsIGJ1dCBhbGxvdyBwcm9wb2dhdGlvblxuICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgLy9zdG9wIGZvcmNlIGxheW91dFxuICAgIGlmICh0eXBlb2YgdGhpcy5kM2NvbGEgIT09ICd1bmRlZmluZWQnICYmIHRoaXMuZDNjb2xhICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5kM2NvbGEuc3RvcCgpO1xuICAgIH1cblxuICAgIHZhciBwID0gdGhpcy5nZXRUb3VjaEV2ZW50UG9pbnQoZXZ0KTsgLy8gc2VlbXMgdG8gYmUgY29ycmVjdCwgc2VlIGJlbG93XG4gICAgdGhpcy5kcmFnU3RhcnQgPSB0aGlzLm1vdXNlVG9TVkcocC54LCBwLnkpO1xufTtcblxuIC8vIGRyYWdnaW5nL3JvdGF0aW9uL3Bhbm5pbmcvc2VsZWN0aW5nXG4gQXBwLnByb3RvdHlwZS50b3VjaE1vdmUgPSBmdW5jdGlvbihldnQpIHtcbiAgICAvLyBpZiAodGhpcy5zZXF1ZW5jZUluaXRDb21wbGV0ZSkgeyAvLyBqdXN0IGJlaW5nIGNhdXRpb3VzXG4gICAgdmFyIHAgPSB0aGlzLmdldFRvdWNoRXZlbnRQb2ludChldnQpOyAvLyBzZWVtcyB0byBiZSBjb3JyZWN0LCBzZWUgYmVsb3dcbiAgICB2YXIgYyA9IHRoaXMubW91c2VUb1NWRyhwLngsIHAueSk7XG5cbiAgICBpZiAodGhpcy5kcmFnRWxlbWVudCAhPSBudWxsKSB7IC8vZHJhZ2dpbmcgb3Igcm90YXRpbmdcbiAgICAgICAgdGhpcy5oaWRlVG9vbHRpcCgpO1xuICAgICAgICB2YXIgZHggPSB0aGlzLmRyYWdTdGFydC54IC0gYy54O1xuICAgICAgICB2YXIgZHkgPSB0aGlzLmRyYWdTdGFydC55IC0gYy55O1xuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlID09PSB0aGlzLlNUQVRFUy5EUkFHR0lORykge1xuICAgICAgICAgICAgLy8gd2UgYXJlIGN1cnJlbnRseSBkcmFnZ2luZyB0aGluZ3MgYXJvdW5kXG4gICAgICAgICAgICB2YXIgb3gsIG95LCBueCwgbnk7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMuZHJhZ0VsZW1lbnQuaXg9PT0gJ3VuZGVmaW5lZCcpIHsgLy8gaWYgbm90IGFuIEludGVyYWN0b3JcbiAgICAgICAgICAgICAgICB2YXIgbm9kZXMgPSB0aGlzLmRyYWdFbGVtZW50LmludGVyYWN0b3JzO1xuICAgICAgICAgICAgICAgIHZhciBub2RlQ291bnQgPSBub2Rlcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcHJvdGVpbiA9IG5vZGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICBveCA9IHByb3RlaW4uY3g7XG4gICAgICAgICAgICAgICAgICAgIG95ID0gcHJvdGVpbi5jeTtcbiAgICAgICAgICAgICAgICAgICAgbnggPSBveCAtIGR4O1xuICAgICAgICAgICAgICAgICAgICBueSA9IG95IC0gZHk7XG4gICAgICAgICAgICAgICAgICAgIHByb3RlaW4uc2V0UG9zaXRpb24obngsIG55KTtcbiAgICAgICAgICAgICAgICAgICAgcHJvdGVpbi5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG5vZGVDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGVzW2ldLnNldEFsbExpbmtDb29yZGluYXRlcygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgb3ggPSB0aGlzLmRyYWdFbGVtZW50LmN4O1xuICAgICAgICAgICAgICAgIG95ID0gdGhpcy5kcmFnRWxlbWVudC5jeTtcbiAgICAgICAgICAgICAgICBueCA9IG94IC0gZHg7XG4gICAgICAgICAgICAgICAgbnkgPSBveSAtIGR5O1xuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0VsZW1lbnQuc2V0UG9zaXRpb24obngsIG55KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdFbGVtZW50LnNldEFsbExpbmtDb29yZGluYXRlcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kcmFnU3RhcnQgPSBjO1xuICAgICAgICB9IGVsc2UgeyAvL25vdCBkcmFnZ2luZyBvciByb3RhdGluZyB5ZXQsIG1heWJlIHdlIHNob3VsZCBzdGFydFxuICAgICAgICAgICAgLy8gZG9uJ3Qgc3RhcnQgZHJhZ2dpbmcganVzdCBvbiBhIGNsaWNrIC0gd2UgbmVlZCB0byBtb3ZlIHRoZSBtb3VzZSBhIGJpdCBmaXJzdFxuICAgICAgICAgICAgaWYgKE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSkgPiAoNSAqIHRoaXMueikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gdGhpcy5TVEFURVMuRFJBR0dJTkc7XG5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2hvd1Rvb2x0aXAocCk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbi8vIHRoaXMgZW5kcyBhbGwgZHJhZ2dpbmcgYW5kIHJvdGF0aW5nXG5BcHAucHJvdG90eXBlLnRvdWNoRW5kID0gZnVuY3Rpb24oZXZ0KSB7XG4gICAgdmFyIHRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAvL2NvbnNvbGUubG9nKFwiTW91c2UgdXA6IFwiICsgZXZ0LnNyY0VsZW1lbnQgKyBcIiBcIiArICh0aW1lIC0gdGhpcy5sYXN0TW91c2VVcCkpO1xuICAgIHRoaXMucHJldmVudERlZmF1bHRzQW5kU3RvcFByb3BhZ2F0aW9uKGV2dCk7XG4gICAgLy9lbGltaW5hdGUgc29tZSBzcHVyaW91cyBtb3VzZSB1cCBldmVudHNcbiAgICBpZiAoKHRpbWUgLSB0aGlzLmxhc3RNb3VzZVVwKSA+IDE1MCkge1xuXG4gICAgICAgIHZhciBwID0gdGhpcy5nZXRUb3VjaEV2ZW50UG9pbnQoZXZ0KTsgLy8gc2VlbXMgdG8gYmUgY29ycmVjdCwgc2VlIGJlbG93XG4gICAgICAgIHZhciBjID0gdGhpcy5tb3VzZVRvU1ZHKHAueCwgcC55KTtcblxuICAgICAgICBpZiAodGhpcy5kcmFnRWxlbWVudCAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoISh0aGlzLnN0YXRlID09PSB0aGlzLlNUQVRFUy5EUkFHR0lORyB8fCB0aGlzLnN0YXRlID09PSB0aGlzLlNUQVRFUy5ST1RBVElORykpIHsgLy9ub3QgZHJhZ2dpbmcgb3Igcm90YXRpbmdcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kcmFnRWxlbWVudC5mb3JtID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZHJhZ0VsZW1lbnQuc2V0Rm9ybSgxKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHRNZW51UHJvdCA9IHRoaXMuZHJhZ0VsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dE1lbnVQb2ludCA9IGM7XG4gICAgICAgICAgICAgICAgICAgIHZhciBtZW51ID0gZDMuc2VsZWN0KFwiLmN1c3RvbS1tZW51LW1hcmdpblwiKVxuICAgICAgICAgICAgICAgICAgICBtZW51LnN0eWxlKFwidG9wXCIsIChldnQucGFnZVkgLSAyMCkgKyBcInB4XCIpLnN0eWxlKFwibGVmdFwiLCAoZXZ0LnBhZ2VYIC0gMjApICsgXCJweFwiKS5zdHlsZShcImRpc3BsYXlcIiwgXCJibG9ja1wiKTtcbiAgICAgICAgICAgICAgICAgICAgZDMuc2VsZWN0KFwiLnNjYWxlQnV0dG9uX1wiICsgKHRoaXMuZHJhZ0VsZW1lbnQuc3RpY2tab29tICogMTAwKSkucHJvcGVydHkoXCJjaGVja2VkXCIsIHRydWUpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5kcmFnRWxlbWVudCA9IG51bGw7XG4gICAgdGhpcy53aGljaFJvdGF0b3IgPSAtMTtcbiAgICB0aGlzLnN0YXRlID0gdGhpcy5TVEFURVMuTU9VU0VfVVA7XG5cbiAgICB0aGlzLmxhc3RNb3VzZVVwID0gdGltZTtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG4vL2dldHMgbW91c2UgcG9zaXRpb25cbkFwcC5wcm90b3R5cGUuZ2V0VG91Y2hFdmVudFBvaW50ID0gZnVuY3Rpb24oZXZ0KSB7XG4gICAgdmFyIHAgPSB0aGlzLnN2Z0VsZW1lbnQuY3JlYXRlU1ZHUG9pbnQoKTtcbiAgICB2YXIgZWxlbWVudCA9IHRoaXMuc3ZnRWxlbWVudC5wYXJlbnROb2RlO1xuICAgIHZhciB0b3AgPSAwLFxuICAgICAgICBsZWZ0ID0gMDtcbiAgICBkbyB7XG4gICAgICAgIHRvcCArPSBlbGVtZW50Lm9mZnNldFRvcCB8fCAwO1xuICAgICAgICBsZWZ0ICs9IGVsZW1lbnQub2Zmc2V0TGVmdCB8fCAwO1xuICAgICAgICBlbGVtZW50ID0gZWxlbWVudC5vZmZzZXRQYXJlbnQ7XG4gICAgfSB3aGlsZSAoZWxlbWVudCk7XG4gICAgcC54ID0gZXZ0LnRvdWNoZXNbMF0ucGFnZVggLSBsZWZ0O1xuICAgIHAueSA9IGV2dC50b3VjaGVzWzBdLnBhZ2VZIC0gdG9wO1xuICAgIHJldHVybiBwO1xufTtcbiAqL1xuQXBwLnByb3RvdHlwZS5hdXRvTGF5b3V0ID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZDNjb2xhLnN0b3AoKTtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIC8vIG5lZWRlZCB0byBlbnN1cmUgY29uc2lzdGVudCByZXN1bHRzXG4gICAgZm9yIChsZXQgcCBvZiBzZWxmLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkge1xuICAgICAgICBkZWxldGUgcC54O1xuICAgICAgICBkZWxldGUgcC55O1xuICAgICAgICBkZWxldGUgcC5weDtcbiAgICAgICAgZGVsZXRlIHAucHk7XG4gICAgICAgIGRlbGV0ZSBwLmJvdW5kcztcbiAgICAgICAgcC5maXhlZCA9IDA7XG4gICAgfVxuXG4gICAgLy8vLyBwcnVuZSBsZWF2ZXMgZnJvbSBuZXR3b3JrIHRoZW4gbGF5b3V0LCB0aGVuIGFkZCBiYWNrIGxlYXZlcyBhbmQgbGF5b3V0IGFnYWluIChmaXhlcyBoYWVtb2dsb2JpbilcbiAgICBjb25zdCBwcnVuZWQgPSBbXTtcbiAgICBmb3IgKGxldCBwYXJ0aWNpcGFudCBvZiBzZWxmLnBhcnRpY2lwYW50cy52YWx1ZXMoKSkge1xuICAgICAgICBpZiAocGFydGljaXBhbnQuYmluYXJ5TGlua3Muc2l6ZSA+IDIgJiYgcGFydGljaXBhbnQudHlwZSAhPT0gXCJjb21wbGV4XCIpIHtcbiAgICAgICAgICAgIHBydW5lZC5wdXNoKHBhcnRpY2lwYW50KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBhbGxOb2Rlc0V4Y2VwdENvbXBsZXhlcyA9IEFycmF5LmZyb20oc2VsZi5wYXJ0aWNpcGFudHMudmFsdWVzKCkpLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlLnR5cGUgIT09IFwiY29tcGxleFwiO1xuICAgIH0pO1xuXG4gICAgaWYgKHBydW5lZC5sZW5ndGggPCBhbGxOb2Rlc0V4Y2VwdENvbXBsZXhlcy5sZW5ndGhcbiAgICAgICAgJiYgcHJ1bmVkLmxlbmd0aCA+IDMgJiYgc2VsZi5wYXJ0aWNpcGFudHMuc2l6ZSA8IDkpIHtcbiAgICAgICAgLy8gPDkgaW5jbHVkZSBoZW1vZ2xvYmluLCBwb3NzaWJseSBzb21lIG90aGVyIHNtYWxsIGNhc2VzLCBidXQgaXMgY2F0aW91cywgdGVuZHMgdG8gbWVzcyBvdGhlciB0aGluZ3MgdXBcbiAgICAgICAgLy8gY29uc29sZS5sb2cocHJ1bmVkSW4pO1xuICAgICAgICBkb0xheW91dChwcnVuZWQsIHRydWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGRvTGF5b3V0KGFsbE5vZGVzRXhjZXB0Q29tcGxleGVzLCBzZWxmLmNvbXBsZXhlcy5sZW5ndGggPiAwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBkb0xheW91dChub2RlcywgcHJlUnVuKSB7XG4gICAgICAgIGNvbnN0IGxheW91dE9iaiA9IHt9OyAvLyB0b2RvIGdldCByaWRcbiAgICAgICAgbGF5b3V0T2JqLm5vZGVzID0gbm9kZXM7XG4gICAgICAgIGxheW91dE9iai5saW5rcyA9IFtdO1xuXG4gICAgICAgIGNvbnN0IG1vbExvb2tVcCA9IHt9O1xuICAgICAgICBsZXQgbWkgPSAwO1xuICAgICAgICBmb3IgKGxldCBtb2wgb2Ygbm9kZXMpIHtcbiAgICAgICAgICAgIG1vbExvb2tVcFttb2wuaWRdID0gbWk7XG4gICAgICAgICAgICBtaSsrO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgYmluYXJ5TGluayBvZiBzZWxmLmFsbEJpbmFyeUxpbmtzLnZhbHVlcygpKSB7XG4gICAgICAgICAgICBjb25zdCBmcm9tTW9sID0gYmluYXJ5TGluay5wYXJ0aWNpcGFudHNbMF07XG4gICAgICAgICAgICBjb25zdCB0b01vbCA9IGJpbmFyeUxpbmsucGFydGljaXBhbnRzWzFdO1xuICAgICAgICAgICAgLy8gaWYgKHByZVJ1biB8fCAoZnJvbU1vbC5iaW5hcnlMaW5rcy5zaXplID09PSA0IHx8IHRvTW9sLmJpbmFyeUxpbmtzLnNpemUgPT0gNCkpIHtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IGZyb21Nb2w7IC8vbW9sTG9va1VwW2Zyb21Nb2wuaWRdO1xuICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gdG9Nb2w7IC8vbW9sTG9va1VwW3RvTW9sLmlkXTtcblxuICAgICAgICAgICAgaWYgKHNvdXJjZSAhPT0gdGFyZ2V0ICYmIG5vZGVzLmluZGV4T2Yoc291cmNlKSAhPT0gLTEgJiYgbm9kZXMuaW5kZXhPZih0YXJnZXQpICE9PSAtMSkgeyAvLyB0b2RvIC0gY2hlY2sgd2hhdCB0aGlzIGlzIGRvaW5nXG4gICAgICAgICAgICAgICAgY29uc3QgbGlua09iaiA9IHt9O1xuICAgICAgICAgICAgICAgIGxpbmtPYmouc291cmNlID0gbW9sTG9va1VwW2Zyb21Nb2wuaWRdO1xuICAgICAgICAgICAgICAgIGxpbmtPYmoudGFyZ2V0ID0gbW9sTG9va1VwW3RvTW9sLmlkXTtcbiAgICAgICAgICAgICAgICBsaW5rT2JqLmlkID0gYmluYXJ5TGluay5pZDtcbiAgICAgICAgICAgICAgICBsYXlvdXRPYmoubGlua3MucHVzaChsaW5rT2JqKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGdyb3VwcyA9IFtdO1xuICAgICAgICBpZiAoIXByZVJ1biAmJiBzZWxmLmNvbXBsZXhlcykge1xuICAgICAgICAgICAgZm9yIChsZXQgZyBvZiBzZWxmLmNvbXBsZXhlcykge1xuICAgICAgICAgICAgICAgIGcubGVhdmVzID0gW107XG4gICAgICAgICAgICAgICAgZy5ncm91cHMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpbnRlcmFjdG9yIG9mIGcubmFyeUxpbmsucGFydGljaXBhbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnRlcmFjdG9yLnR5cGUgIT09IFwiY29tcGxleFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBnLmxlYXZlcy5wdXNoKGxheW91dE9iai5ub2Rlcy5pbmRleE9mKGludGVyYWN0b3IpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBncm91cHMucHVzaChnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGcgb2Ygc2VsZi5jb21wbGV4ZXMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpbnRlcmFjdG9yIG9mIGcubmFyeUxpbmsucGFydGljaXBhbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnRlcmFjdG9yLnR5cGUgPT09IFwiY29tcGxleFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvL2NvbnNvbGUubG9nKGdyb3Vwcy5pbmRleE9mKGludGVyYWN0b3IpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGcuZ3JvdXBzLnB1c2goZ3JvdXBzLmluZGV4T2YoaW50ZXJhY3RvcikpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy9jb25zb2xlLmxvZyhcImdyb3Vwc1wiLCBncm91cHMpO1xuICAgICAgICBkZWxldGUgc2VsZi5kM2NvbGEuX2xhc3RTdHJlc3M7XG4gICAgICAgIGRlbGV0ZSBzZWxmLmQzY29sYS5fYWxwaGE7XG4gICAgICAgIGRlbGV0ZSBzZWxmLmQzY29sYS5fZGVzY2VudDtcbiAgICAgICAgZGVsZXRlIHNlbGYuZDNjb2xhLl9yb290R3JvdXA7XG5cbiAgICAgICAgbGV0IGxpbmtMZW5ndGggPSAobm9kZXMubGVuZ3RoIDwgMzApID8gMzAgOiAyMDtcbiAgICAgICAgY29uc3Qgd2lkdGggPSBzZWxmLnN2Z0VsZW1lbnQucGFyZW50Tm9kZS5jbGllbnRXaWR0aDtcbiAgICAgICAgY29uc3QgaGVpZ2h0ID0gc2VsZi5zdmdFbGVtZW50LnBhcmVudE5vZGUuY2xpZW50SGVpZ2h0O1xuICAgICAgICAvL2NvbnNvbGUubG9nKFwiKipcIiwgbGF5b3V0T2JqKTtcbiAgICAgICAgc2VsZi5kM2NvbGEuc2l6ZShbaGVpZ2h0IC0gNDAsIHdpZHRoIC0gNDBdKVxuICAgICAgICAgICAgLm5vZGVzKGxheW91dE9iai5ub2RlcykuZ3JvdXBzKGdyb3VwcykubGlua3MobGF5b3V0T2JqLmxpbmtzKS5hdm9pZE92ZXJsYXBzKHRydWUpO1xuICAgICAgICBsZXQgZ3JvdXBEZWJ1Z1NlbCwgcGFydGljaXBhbnREZWJ1Z1NlbDtcbiAgICAgICAgaWYgKHNlbGYuZGVidWcpIHtcbiAgICAgICAgICAgIGdyb3VwRGVidWdTZWwgPSBkMy5zZWxlY3Qoc2VsZi5jb250YWluZXIpLnNlbGVjdEFsbChcIi5ncm91cFwiKVxuICAgICAgICAgICAgICAgIC5kYXRhKGdyb3Vwcyk7XG5cbiAgICAgICAgICAgIGdyb3VwRGVidWdTZWwuZW50ZXIoKS5hcHBlbmQoXCJyZWN0XCIpXG4gICAgICAgICAgICAgICAgLmNsYXNzZWQoXCJncm91cFwiLCB0cnVlKVxuICAgICAgICAgICAgICAgIC5hdHRyKHtcbiAgICAgICAgICAgICAgICAgICAgcng6IDUsXG4gICAgICAgICAgICAgICAgICAgIHJ5OiA1XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuc3R5bGUoXCJzdHJva2VcIiwgXCJibHVlXCIpXG4gICAgICAgICAgICAgICAgLnN0eWxlKFwiZmlsbFwiLCBcIm5vbmVcIik7XG5cbiAgICAgICAgICAgIHBhcnRpY2lwYW50RGVidWdTZWwgPSBkMy5zZWxlY3Qoc2VsZi5jb250YWluZXIpLnNlbGVjdEFsbChcIi5ub2RlXCIpXG4gICAgICAgICAgICAgICAgLmRhdGEobGF5b3V0T2JqLm5vZGVzKTtcblxuICAgICAgICAgICAgcGFydGljaXBhbnREZWJ1Z1NlbC5lbnRlcigpLmFwcGVuZChcInJlY3RcIilcbiAgICAgICAgICAgICAgICAuY2xhc3NlZChcIm5vZGVcIiwgdHJ1ZSlcbiAgICAgICAgICAgICAgICAuYXR0cih7XG4gICAgICAgICAgICAgICAgICAgIHJ4OiA1LFxuICAgICAgICAgICAgICAgICAgICByeTogNVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLnN0eWxlKFwic3Ryb2tlXCIsIFwicmVkXCIpXG4gICAgICAgICAgICAgICAgLnN0eWxlKFwiZmlsbFwiLCBcIm5vbmVcIik7XG5cbiAgICAgICAgICAgIGdyb3VwRGVidWdTZWwuZXhpdCgpLnJlbW92ZSgpO1xuICAgICAgICAgICAgcGFydGljaXBhbnREZWJ1Z1NlbC5leGl0KCkucmVtb3ZlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICBzZWxmLmQzY29sYS5zeW1tZXRyaWNEaWZmTGlua0xlbmd0aHMobGlua0xlbmd0aClcbiAgICAgICAgICAgIC5vbihcInRpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChEYXRlLm5vdygpIC0gc3RhcnRUaW1lID4gNzUwKSB7Ly8hcHJlUnVuKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGVzID0gc2VsZi5kM2NvbGEubm9kZXMoKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgbm9kZSBvZiBub2Rlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5zZXRQb3NpdGlvbihub2RlLngsIG5vZGUueSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc2VsZi5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi56b29tVG9FeHRlbnQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuZGVidWcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwRGVidWdTZWwuYXR0cih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGQuYm91bmRzLng7Ly8gKyAod2lkdGggLyAyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkLmJvdW5kcy55Oy8vICsgKGhlaWdodCAvIDIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkLmJvdW5kcy53aWR0aCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZC5ib3VuZHMuaGVpZ2h0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIHBhcnRpY2lwYW50RGVidWdTZWwuYXR0cih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGQuYm91bmRzLng7Ly8gKyAod2lkdGggLyAyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHk6IGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkLmJvdW5kcy55Oy8vICsgKGhlaWdodCAvIDIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGZ1bmN0aW9uIChkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkLmJvdW5kcy53aWR0aCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZC5ib3VuZHMuaGVpZ2h0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLm9uKFwiZW5kXCIsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJlUnVuKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFsZXJ0KFwiaW5pdGlhbCBydW4gY29tcGxldGVcIik7XG4gICAgICAgICAgICAgICAgICAgIC8vICAgICAvLyBmb3IgKGxldCBwIG9mIGxheW91dE9iai5ub2Rlcykge1xuICAgICAgICAgICAgICAgICAgICAvLyAgICAgLy8gICAgICAgICBwLmZpeGVkID0gMTtcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgIC8vIH1cbiAgICAgICAgICAgICAgICAgICAgZG9MYXlvdXQoYWxsTm9kZXNFeGNlcHRDb21wbGV4ZXMsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBub2RlIG9mIG5vZGVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnNldFBvc2l0aW9uKG5vZGUueCwgbm9kZS55KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldEFsbExpbmtDb29yZGluYXRlcygpO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLnpvb21Ub0V4dGVudCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICBpZiAocHJlUnVuKSB7XG4gICAgICAgICAgICBzZWxmLmQzY29sYS5zdGFydCgyMywgMjMsIDAsIDAsIHRydWUpOy8vLCBmYWxzZSwgZmFsc2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VsZi5kM2NvbGEuc3RhcnQoMCwgMjMsIDIzLCAwLCB0cnVlKTsvLywgZmFsc2UsIGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cbkFwcC5wcm90b3R5cGUuZ2V0U1ZHID0gZnVuY3Rpb24gKCkgeyAvL3RvZG8gLSBzb21ld2hhdCBicm9rZW4sIGFubm90YXRpb25zIG1pc3NpbmdcbiAgICB2YXIgc3ZnU2VsID0gZDMuc2VsZWN0KHRoaXMuZWwpLnNlbGVjdEFsbChcInN2Z1wiKTtcbiAgICB2YXIgc3ZnQXJyID0gW3N2Z1NlbC5ub2RlKCldO1xuICAgIHZhciBzdmdTdHJpbmdzID0gc3ZnVXRpbHMuY2FwdHVyZShzdmdBcnIpO1xuICAgIHZhciBzdmdYTUwgPSBzdmdVdGlscy5tYWtlWE1MU3RyKG5ldyBYTUxTZXJpYWxpemVyKCksIHN2Z1N0cmluZ3NbMF0pO1xuXG4gICAgcmV0dXJuIHN2Z1hNTDtcblxuICAgIC8vIHZhciBmaWxlTmFtZSA9IHRoaXMuZmlsZW5hbWVTdGF0ZVN0cmluZygpLnN1YnN0cmluZygwLCAyNDApO1xuICAgIC8vIGRvd25sb2FkKHN2Z1hNTCwgJ2FwcGxpY2F0aW9uL3N2ZycsIGZpbGVOYW1lICsgXCIuc3ZnXCIpO1xuXG59O1xuXG4vLyBBcHAucHJvdG90eXBlLmdldFNWRyA9IGZ1bmN0aW9uICgpIHtcbi8vICAgICBsZXQgc3ZnWG1sID0gdGhpcy5zdmdFbGVtZW50Lm91dGVySFRNTC5yZXBsYWNlKC88cmVjdCAuKj9cXC9yZWN0Pi9pLCBcIlwiKTsgLy90YWtlIG91dCB3aGl0ZSBiYWNrZ3JvdW5kIGZpbGxcbi8vICAgICBjb25zdCB2aWV3Qm94ID0gXCJ2aWV3Qm94PVxcXCIwIDAgXCIgKyB0aGlzLnN2Z0VsZW1lbnQucGFyZW50Tm9kZS5jbGllbnRXaWR0aCArIFwiIFwiICsgdGhpcy5zdmdFbGVtZW50LnBhcmVudE5vZGUuY2xpZW50SGVpZ2h0ICsgXCJcXFwiIFwiO1xuLy8gICAgIHN2Z1htbCA9IHN2Z1htbC5yZXBsYWNlKFwiPHN2ZyBcIiwgXCI8c3ZnIHhtbG5zPVxcXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1xcXCIgeG1sbnM6eGxpbms9XFxcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcXFwiIHhtbG5zOmV2PVxcXCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL3htbC1ldmVudHNcXFwiIFwiICsgdmlld0JveCk7XG4vL1xuLy8gICAgIHJldHVybiBcIjw/eG1sIHZlcnNpb249XFxcIjEuMFxcXCIgZW5jb2Rpbmc9XFxcIlVURi04XFxcIiBzdGFuZGFsb25lPVxcXCJub1xcXCI/PlwiICtcbi8vICAgICAgICAgXCI8IURPQ1RZUEUgc3ZnIFBVQkxJQyBcXFwiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU5cXFwiIFxcXCJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGRcXFwiPlwiICtcbi8vICAgICAgICAgc3ZnWG1sO1xuLy8gfTtcblxuLy8gdHJhbnNmb3JtIHRoZSBtb3VzZS1wb3NpdGlvbiBpbnRvIGEgcG9zaXRpb24gb24gdGhlIHN2Z1xuQXBwLnByb3RvdHlwZS5tb3VzZVRvU1ZHID0gZnVuY3Rpb24gKHgsIHkpIHtcbiAgICBjb25zdCBwID0gdGhpcy5zdmdFbGVtZW50LmNyZWF0ZVNWR1BvaW50KCk7XG4gICAgcC54ID0geDtcbiAgICBwLnkgPSB5O1xuICAgIHJldHVybiBwLm1hdHJpeFRyYW5zZm9ybSh0aGlzLmNvbnRhaW5lci5nZXRDVE0oKS5pbnZlcnNlKCkpO1xufTtcblxuLy8gcmVhZHMgTUkgSlNPTiBmb3JtYXRcbkFwcC5wcm90b3R5cGUucmVhZE1JSlNPTiA9IGZ1bmN0aW9uIChtaUpzb24sIGV4cGFuZCA9IHRydWUpIHtcbiAgICByZWFkTWlqc29uKG1pSnNvbiwgdGhpcywgZXhwYW5kKTtcbn07XG5cbkFwcC5wcm90b3R5cGUuY2hlY2tMaW5rcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKGxldCBsaW5rIG9mIHRoaXMuYWxsTmFyeUxpbmtzLnZhbHVlcygpKSB7XG4gICAgICAgIGxpbmsuY2hlY2soKTtcbiAgICB9XG4gICAgZm9yIChsZXQgbGluayBvZiB0aGlzLmFsbEJpbmFyeUxpbmtzLnZhbHVlcygpKSB7XG4gICAgICAgIGxpbmsuY2hlY2soKTtcbiAgICB9XG4gICAgZm9yIChsZXQgbGluayBvZiB0aGlzLmFsbFVuYXJ5TGlua3MudmFsdWVzKCkpIHtcbiAgICAgICAgbGluay5jaGVjaygpO1xuICAgIH1cbiAgICBmb3IgKGxldCBsaW5rIG9mIHRoaXMuYWxsU2VxdWVuY2VMaW5rcy52YWx1ZXMoKSkge1xuICAgICAgICBsaW5rLmNoZWNrKCk7XG4gICAgfVxufTtcblxuQXBwLnByb3RvdHlwZS5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgZm9yIChsZXQgbGluayBvZiB0aGlzLmFsbE5hcnlMaW5rcy52YWx1ZXMoKSkge1xuICAgICAgICBsaW5rLnNldExpbmtDb29yZGluYXRlcygpO1xuICAgIH1cbiAgICBmb3IgKGxldCBsaW5rIG9mIHRoaXMuYWxsQmluYXJ5TGlua3MudmFsdWVzKCkpIHtcbiAgICAgICAgbGluay5zZXRMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICB9XG4gICAgZm9yIChsZXQgbGluayBvZiB0aGlzLmFsbFVuYXJ5TGlua3MudmFsdWVzKCkpIHtcbiAgICAgICAgbGluay5zZXRMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICB9XG4gICAgZm9yIChsZXQgbGluayBvZiB0aGlzLmFsbFNlcXVlbmNlTGlua3MudmFsdWVzKCkpIHtcbiAgICAgICAgbGluay5zZXRMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICB9XG59O1xuXG5BcHAucHJvdG90eXBlLnNob3dUb29sdGlwID0gZnVuY3Rpb24gKHApIHtcbiAgICBsZXQgdHRYLCB0dFk7XG4gICAgY29uc3QgbGVuZ3RoID0gdGhpcy50b29sdGlwLmdldENvbXB1dGVkVGV4dExlbmd0aCgpICsgMTY7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLnN2Z0VsZW1lbnQucGFyZW50Tm9kZS5jbGllbnRXaWR0aDtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLnN2Z0VsZW1lbnQucGFyZW50Tm9kZS5jbGllbnRIZWlnaHQ7XG4gICAgaWYgKHAueCArIDIwICsgbGVuZ3RoIDwgd2lkdGgpIHtcbiAgICAgICAgdHRYID0gcC54O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHR0WCA9IHdpZHRoIC0gbGVuZ3RoIC0gMjA7XG4gICAgfVxuXG4gICAgaWYgKHAueSArIDYwIDwgaGVpZ2h0KSB7XG4gICAgICAgIHR0WSA9IHAueTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0dFkgPSBoZWlnaHQgLSA2MDtcbiAgICB9XG4gICAgdGhpcy50b29sdGlwLnNldEF0dHJpYnV0ZShcInhcIiwgdHRYICsgMjIpO1xuICAgIHRoaXMudG9vbHRpcC5zZXRBdHRyaWJ1dGUoXCJ5XCIsIHR0WSArIDQ3KTtcbiAgICB0aGlzLnRvb2x0aXBfYmcuc2V0QXR0cmlidXRlKFwieFwiLCB0dFggKyAxNik7XG4gICAgdGhpcy50b29sdGlwX2JnLnNldEF0dHJpYnV0ZShcInlcIiwgdHRZICsgMjgpO1xuICAgIHRoaXMudG9vbHRpcF9zdWJCZy5zZXRBdHRyaWJ1dGUoXCJ4XCIsIHR0WCArIDE2KTtcbiAgICB0aGlzLnRvb2x0aXBfc3ViQmcuc2V0QXR0cmlidXRlKFwieVwiLCB0dFkgKyAyOCk7XG59O1xuXG5BcHAucHJvdG90eXBlLnNldFRvb2x0aXAgPSBmdW5jdGlvbiAodGV4dCwgY29sb3IpIHtcbiAgICBpZiAodGV4dCkge1xuICAgICAgICB0aGlzLnRvb2x0aXAuZmlyc3RDaGlsZC5kYXRhID0gdGV4dC50b1N0cmluZygpLnJlcGxhY2UoLyYocXVvdCk7L2csIFwiXFxcIlwiKTtcbiAgICAgICAgdGhpcy50b29sdGlwLnNldEF0dHJpYnV0ZShcImRpc3BsYXlcIiwgXCJibG9ja1wiKTtcbiAgICAgICAgY29uc3QgbGVuZ3RoID0gdGhpcy50b29sdGlwLmdldENvbXB1dGVkVGV4dExlbmd0aCgpO1xuICAgICAgICB0aGlzLnRvb2x0aXBfYmcuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgbGVuZ3RoICsgMTYpO1xuICAgICAgICB0aGlzLnRvb2x0aXBfc3ViQmcuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgbGVuZ3RoICsgMTYpO1xuICAgICAgICBpZiAodHlwZW9mIGNvbG9yICE9PSBcInVuZGVmaW5lZFwiICYmIGNvbG9yICE9IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcF9iZy5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIGNvbG9yKTtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcF9iZy5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgY29sb3IpO1xuICAgICAgICAgICAgdGhpcy50b29sdGlwX2JnLnNldEF0dHJpYnV0ZShcImZpbGwtb3BhY2l0eVwiLCBcIjAuNVwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudG9vbHRpcF9iZy5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwid2hpdGVcIik7XG4gICAgICAgICAgICB0aGlzLnRvb2x0aXBfYmcuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwiZ3JleVwiKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0b2RvIC0gd2hhdHMgdGhpcyBoZWlnaHQgZm9yP1xuICAgICAgICB0aGlzLnRvb2x0aXBfYmcuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIFwiMjhcIik7XG4gICAgICAgIHRoaXMudG9vbHRpcF9zdWJCZy5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgXCIyOFwiKTtcbiAgICAgICAgdGhpcy50b29sdGlwX2JnLnNldEF0dHJpYnV0ZShcImRpc3BsYXlcIiwgXCJibG9ja1wiKTtcbiAgICAgICAgdGhpcy50b29sdGlwX3N1YkJnLnNldEF0dHJpYnV0ZShcImRpc3BsYXlcIiwgXCJibG9ja1wiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmhpZGVUb29sdGlwKCk7XG4gICAgfVxufTtcblxuQXBwLnByb3RvdHlwZS5oaWRlVG9vbHRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnRvb2x0aXAuc2V0QXR0cmlidXRlKFwiZGlzcGxheVwiLCBcIm5vbmVcIik7XG4gICAgdGhpcy50b29sdGlwX2JnLnNldEF0dHJpYnV0ZShcImRpc3BsYXlcIiwgXCJub25lXCIpO1xuICAgIHRoaXMudG9vbHRpcF9zdWJCZy5zZXRBdHRyaWJ1dGUoXCJkaXNwbGF5XCIsIFwibm9uZVwiKTtcbn07XG5cbkFwcC5wcm90b3R5cGUuYWRkQ29sb3JTY2hlbWVLZXkgPSBmdW5jdGlvbiAoLypIVE1MRGl2RWxlbWVudCovIGRpdikge1xuICAgIHRoaXMuY29sb3JTY2hlbWVLZXlEaXZzLmFkZChkaXYpO1xuICAgIENvbG9yU2NoZW1lS2V5LnVwZGF0ZShkaXYsIHRoaXMpO1xufTtcblxuQXBwLnByb3RvdHlwZS5yZW1vdmVDb2xvclNjaGVtZUtleSA9IGZ1bmN0aW9uICgvKkhUTUxEaXZFbGVtZW50Ki8gY29sb3JTY2hlbWVLZXlEaXYpIHtcbiAgICB0aGlzLmNvbG9yU2NoZW1lS2V5RGl2cy5yZW1vdmUoY29sb3JTY2hlbWVLZXlEaXYpO1xuICAgIGNvbG9yU2NoZW1lS2V5RGl2LnRleHRDb250ZW50ID0gXCJcIjtcbn07XG5cbi8vZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IChub2U/KSwgdGJoIGkgbWlnaHQgaGF2ZSBtYWRlIGEgYml0IG9mIGEgbWVzcyBoZXJlXG5BcHAucHJvdG90eXBlLnNldEFubm90YXRpb25zID0gZnVuY3Rpb24gKGFubm9DaG9pY2UpIHtcbiAgICBhbm5vQ2hvaWNlID0gYW5ub0Nob2ljZS50b1VwcGVyQ2FzZSgpO1xuICAgIGZvciAobGV0IGFubm9UeXBlIG9mIHRoaXMuYW5ub3RhdGlvblNldHNTaG93bi5rZXlzKCkpIHtcbiAgICAgICAgdGhpcy5zaG93QW5ub3RhdGlvbnMoYW5ub1R5cGUsIGFubm9DaG9pY2UgPT09IGFubm9UeXBlKTtcbiAgICB9XG4gICAgdGhpcy5zaG93QW5ub3RhdGlvbnMoYW5ub0Nob2ljZSwgdHJ1ZSk7XG59O1xuXG5BcHAucHJvdG90eXBlLnNob3dBbm5vdGF0aW9ucyA9IGZ1bmN0aW9uIChhbm5vQ2hvaWNlLCBzaG93KSB7XG4gICAgYW5ub0Nob2ljZSA9IGFubm9DaG9pY2UudG9VcHBlckNhc2UoKTtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBsZXQgc2V0U2hvd24gPSB0aGlzLmFubm90YXRpb25TZXRzU2hvd24uZ2V0KGFubm9DaG9pY2UpO1xuICAgIGlmICh0eXBlb2Ygc2V0U2hvd24gPT09IFwidW5kZWZpbmVkXCIgJiYgYW5ub0Nob2ljZSAhPT0gXCJNSUZFQVRVUkVTXCIpIHtcbiAgICAgICAgZmV0Y2hBbm5vdGF0aW9ucyhhbm5vQ2hvaWNlLCB0aGlzLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBzZWxmLmFubm90YXRpb25TZXRzU2hvd24uc2V0KGFubm9DaG9pY2UsIHNob3cpO1xuICAgICAgICAgICAgc2VsZi51cGRhdGVBbm5vdGF0aW9ucygpO1xuICAgICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFubm90YXRpb25TZXRzU2hvd24uc2V0KGFubm9DaG9pY2UsIHNob3cpO1xuICAgICAgICB0aGlzLnVwZGF0ZUFubm90YXRpb25zKCk7XG4gICAgfVxufTtcblxuQXBwLnByb3RvdHlwZS51cGRhdGVBbm5vdGF0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyAvL2NsZWFyIGFsbCBhbm5vdCdzXG4gICAgZm9yIChsZXQgbW9sIG9mIHRoaXMucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgICAgIGlmIChtb2wuaWQuaW5kZXhPZihcInVuaXByb3RrYl9cIikgPT09IDApIHsgLy9MSU1JVCBJVCBUTyBQUk9URUlOU1xuICAgICAgICAgICAgbW9sLmNsZWFyUG9zaXRpb25hbEZlYXR1cmVzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hvb3NlQ29sb3JzKHRoaXMpO1xuICAgIHRoaXMuY29sb3JTY2hlbWVDaGFuZ2VkKCk7XG5cbiAgICBmb3IgKGxldCBtb2wgb2YgdGhpcy5wYXJ0aWNpcGFudHMudmFsdWVzKCkpIHtcbiAgICAgICAgaWYgKG1vbC5pZC5pbmRleE9mKFwidW5pcHJvdGtiX1wiKSA9PT0gMCkgeyAvL0xJTUlUIElUIFRPIFBST1RFSU5TXG4gICAgICAgICAgICBtb2wuc2V0UG9zaXRpb25hbEZlYXR1cmVzKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2hvb3NlQ29sb3JzKHRoaXMpO1xuICAgIHRoaXMuY29sb3JTY2hlbWVDaGFuZ2VkKCk7XG59O1xuXG5BcHAucHJvdG90eXBlLmNvbG9yU2NoZW1lQ2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKGxldCBkaXYgb2YgdGhpcy5jb2xvclNjaGVtZUtleURpdnMpIHtcbiAgICAgICAgQ29sb3JTY2hlbWVLZXkudXBkYXRlKGRpdiwgdGhpcyk7XG4gICAgfVxufTtcblxuQXBwLnByb3RvdHlwZS5nZXRDb21wbGV4Q29sb3JzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBOYXJ5TGluay5uYXJ5Q29sb3JzO1xufTtcblxuQXBwLnByb3RvdHlwZS5nZXRGZWF0dXJlQ29sb3JzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZlYXR1cmVDb2xvcnM7XG59O1xuXG5BcHAucHJvdG90eXBlLmNvbGxhcHNlQWxsID0gZnVuY3Rpb24gKCkge1xuICAgIGZvciAobGV0IHBhcnRpY2lwYW50IG9mIHRoaXMucGFydGljaXBhbnRzLnZhbHVlcygpKSB7XG4gICAgICAgIGlmIChwYXJ0aWNpcGFudC5mb3JtID09PSAxKSB7XG4gICAgICAgICAgICBwYXJ0aWNpcGFudC5zZXRGb3JtKDApO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuQXBwLnByb3RvdHlwZS5leHBhbmRBbGwgPSBmdW5jdGlvbiAoKSB7XG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgdGhpcy5wYXJ0aWNpcGFudHMudmFsdWVzKCkpIHtcbiAgICAgICAgaWYgKHBhcnRpY2lwYW50LmZvcm0gPT09IDApIHtcbiAgICAgICAgICAgIHBhcnRpY2lwYW50LnNldEZvcm0oMSk7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG4vL2Zyb20gbm9lXG5BcHAucHJvdG90eXBlLmV4cGFuZEFuZENvbGxhcHNlU2VsZWN0aW9uID0gZnVuY3Rpb24gKG1vbGVjdWxlc1NlbGVjdGVkKSB7XG4gICAgZm9yIChsZXQgcGFydGljaXBhbnQgb2YgdGhpcy5wYXJ0aWNpcGFudHMudmFsdWVzKCkpIHtcbiAgICAgICAgY29uc3QgbW9sZWN1bGVfaWQgPSBwYXJ0aWNpcGFudC5qc29uLmlkZW50aWZpZXIuaWQ7XG4gICAgICAgIGlmIChtb2xlY3VsZXNTZWxlY3RlZC5pbmNsdWRlcyhtb2xlY3VsZV9pZCkpIHtcbiAgICAgICAgICAgIGlmIChwYXJ0aWNpcGFudC5mb3JtID09PSAwKSB7XG4gICAgICAgICAgICAgICAgcGFydGljaXBhbnQuc2V0Rm9ybSgxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChwYXJ0aWNpcGFudC5mb3JtID09PSAxKSB7XG4gICAgICAgICAgICBwYXJ0aWNpcGFudC5zZXRGb3JtKDApO1xuICAgICAgICB9XG4gICAgfVxufTtcblxuLy8gZXhwb3J0IGZ1bmN0aW9uIG1ha2VTeW1ib2xLZXkodGFyZ2V0RGl2KXtcbi8vICAgICBuZXcgU3ltYm9sS2V5KHRhcmdldERpdik7XG4vLyB9Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/app.js\n"); /***/ }), @@ -1165,7 +1165,7 @@ eval("var require;var require;(function(f){if(true){module.exports=f()}else { va /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"update\", function() { return update; });\n//import * as RGBColor from \"rgbcolor\";\n\nfunction update(/*HTMLDivElement*/ div, /*App*/app) {\n div.textContent = \"\";\n\n const complexColorScheme = app.getComplexColors();\n const complexColorTable = document.createElement(\"table\");\n complexColorTable.classList.add(\"color_key\", \"complex_colors\");\n const th = complexColorTable.createTHead();\n th.textContent = \"Complexes\";\n const ccDomain = complexColorScheme.domain();\n const ccRange = complexColorScheme.range();\n for (let i = 0; i < ccDomain.length; i++) {\n const tr = complexColorTable.insertRow();\n const tc1 = tr.insertCell();\n tc1.style.backgroundColor = ccRange[i % 6];\n const tc2 = tr.insertCell();\n tc2.textContent = ccDomain[i];\n console.log(i + \" \" + ccDomain[i] + \" \" + ccRange[i]);\n }\n div.appendChild(complexColorTable);\n\n const featureColorScheme = app.getFeatureColors();\n if (featureColorScheme) {\n const featureColorTable = document.createElement(\"table\");\n featureColorTable.classList.add(\"color_key\", \"feature_colors\");\n const th2 = featureColorTable.createTHead();\n th2.textContent = \"Features\";\n const domain = featureColorScheme.domain();\n const range = featureColorScheme.range();\n for (let i = 0; i < domain.length; i++) {\n const tr = featureColorTable.insertRow();\n const tc1 = tr.insertCell();\n // make transparent version of color\n //const temp = new RGBColor(range[i % 20]).;\n tc1.style.backgroundColor = range[i % 20];//\"rgba(\" + temp.r + \",\" + temp.g + \",\" + temp.b + \", 0.6)\";\n const tc2 = tr.insertCell();\n tc2.textContent = domain[i];\n }\n div.appendChild(featureColorTable);\n }\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvY29sb3Itc2NoZW1lLWtleS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvY29sb3Itc2NoZW1lLWtleS5qcz8wYTllIl0sInNvdXJjZXNDb250ZW50IjpbIi8vaW1wb3J0ICogYXMgUkdCQ29sb3IgZnJvbSBcInJnYmNvbG9yXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGUoLypIVE1MRGl2RWxlbWVudCovIGRpdiwgLypBcHAqL2FwcCkge1xuICAgIGRpdi50ZXh0Q29udGVudCA9IFwiXCI7XG5cbiAgICBjb25zdCBjb21wbGV4Q29sb3JTY2hlbWUgPSBhcHAuZ2V0Q29tcGxleENvbG9ycygpO1xuICAgIGNvbnN0IGNvbXBsZXhDb2xvclRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRhYmxlXCIpO1xuICAgIGNvbXBsZXhDb2xvclRhYmxlLmNsYXNzTGlzdC5hZGQoXCJjb2xvcl9rZXlcIiwgXCJjb21wbGV4X2NvbG9yc1wiKTtcbiAgICBjb25zdCB0aCA9IGNvbXBsZXhDb2xvclRhYmxlLmNyZWF0ZVRIZWFkKCk7XG4gICAgdGgudGV4dENvbnRlbnQgPSBcIkNvbXBsZXhlc1wiO1xuICAgIGNvbnN0IGNjRG9tYWluID0gY29tcGxleENvbG9yU2NoZW1lLmRvbWFpbigpO1xuICAgIGNvbnN0IGNjUmFuZ2UgPSBjb21wbGV4Q29sb3JTY2hlbWUucmFuZ2UoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNjRG9tYWluLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHRyID0gY29tcGxleENvbG9yVGFibGUuaW5zZXJ0Um93KCk7XG4gICAgICAgIGNvbnN0IHRjMSA9IHRyLmluc2VydENlbGwoKTtcbiAgICAgICAgdGMxLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGNjUmFuZ2VbaSAlIDZdO1xuICAgICAgICBjb25zdCB0YzIgPSB0ci5pbnNlcnRDZWxsKCk7XG4gICAgICAgIHRjMi50ZXh0Q29udGVudCA9IGNjRG9tYWluW2ldO1xuICAgICAgICBjb25zb2xlLmxvZyhpICsgXCIgXCIgKyBjY0RvbWFpbltpXSArIFwiIFwiICsgY2NSYW5nZVtpXSk7XG4gICAgfVxuICAgIGRpdi5hcHBlbmRDaGlsZChjb21wbGV4Q29sb3JUYWJsZSk7XG5cbiAgICBjb25zdCBmZWF0dXJlQ29sb3JTY2hlbWUgPSBhcHAuZ2V0RmVhdHVyZUNvbG9ycygpO1xuICAgIGlmIChmZWF0dXJlQ29sb3JTY2hlbWUpIHtcbiAgICAgICAgY29uc3QgZmVhdHVyZUNvbG9yVGFibGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGFibGVcIik7XG4gICAgICAgIGZlYXR1cmVDb2xvclRhYmxlLmNsYXNzTGlzdC5hZGQoXCJjb2xvcl9rZXlcIiwgXCJmZWF0dXJlX2NvbG9yc1wiKTtcbiAgICAgICAgY29uc3QgdGgyID0gZmVhdHVyZUNvbG9yVGFibGUuY3JlYXRlVEhlYWQoKTtcbiAgICAgICAgdGgyLnRleHRDb250ZW50ID0gXCJGZWF0dXJlc1wiO1xuICAgICAgICBjb25zdCBkb21haW4gPSBmZWF0dXJlQ29sb3JTY2hlbWUuZG9tYWluKCk7XG4gICAgICAgIGNvbnN0IHJhbmdlID0gZmVhdHVyZUNvbG9yU2NoZW1lLnJhbmdlKCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZG9tYWluLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCB0ciA9IGZlYXR1cmVDb2xvclRhYmxlLmluc2VydFJvdygpO1xuICAgICAgICAgICAgY29uc3QgdGMxID0gdHIuaW5zZXJ0Q2VsbCgpO1xuICAgICAgICAgICAgLy8gbWFrZSB0cmFuc3BhcmVudCB2ZXJzaW9uIG9mIGNvbG9yXG4gICAgICAgICAgICAvL2NvbnN0IHRlbXAgPSBuZXcgUkdCQ29sb3IocmFuZ2VbaSAlIDIwXSkuO1xuICAgICAgICAgICAgdGMxLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IHJhbmdlW2kgJSAyMF07Ly9cInJnYmEoXCIgKyB0ZW1wLnIgKyBcIixcIiArIHRlbXAuZyArIFwiLFwiICsgdGVtcC5iICsgXCIsIDAuNilcIjtcbiAgICAgICAgICAgIGNvbnN0IHRjMiA9IHRyLmluc2VydENlbGwoKTtcbiAgICAgICAgICAgIHRjMi50ZXh0Q29udGVudCA9IGRvbWFpbltpXTtcbiAgICAgICAgfVxuICAgICAgICBkaXYuYXBwZW5kQ2hpbGQoZmVhdHVyZUNvbG9yVGFibGUpO1xuICAgIH1cbn0iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/color-scheme-key.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"update\", function() { return update; });\n//import * as RGBColor from \"rgbcolor\";\n\nfunction update(/*HTMLDivElement*/ div, /*App*/app) {\n div.textContent = \"\";\n\n const complexColorScheme = app.getComplexColors();\n const complexColorTable = document.createElement(\"table\");\n complexColorTable.classList.add(\"color_key\", \"complex_colors\");\n const th = complexColorTable.createTHead();\n th.textContent = \"Complexes\";\n const ccDomain = complexColorScheme.domain();\n const ccRange = complexColorScheme.range();\n for (let i = 0; i < ccDomain.length; i++) {\n const tr = complexColorTable.insertRow();\n const tc1 = tr.insertCell();\n tc1.style.backgroundColor = ccRange[i % 6];\n const tc2 = tr.insertCell();\n tc2.textContent = ccDomain[i];\n //console.log(i + \" \" + ccDomain[i] + \" \" + ccRange[i]);\n }\n div.appendChild(complexColorTable);\n\n const featureColorScheme = app.getFeatureColors();\n if (featureColorScheme) {\n const featureColorTable = document.createElement(\"table\");\n featureColorTable.classList.add(\"color_key\", \"feature_colors\");\n const th2 = featureColorTable.createTHead();\n th2.textContent = \"Features\";\n const domain = featureColorScheme.domain();\n const range = featureColorScheme.range();\n for (let i = 0; i < domain.length; i++) {\n const tr = featureColorTable.insertRow();\n const tc1 = tr.insertCell();\n // make transparent version of color\n //const temp = new RGBColor(range[i % 20]).;\n tc1.style.backgroundColor = range[i % 20];//\"rgba(\" + temp.r + \",\" + temp.g + \",\" + temp.b + \", 0.6)\";\n const tc2 = tr.insertCell();\n tc2.textContent = domain[i];\n }\n div.appendChild(featureColorTable);\n }\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvY29sb3Itc2NoZW1lLWtleS5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvY29sb3Itc2NoZW1lLWtleS5qcz8wYTllIl0sInNvdXJjZXNDb250ZW50IjpbIi8vaW1wb3J0ICogYXMgUkdCQ29sb3IgZnJvbSBcInJnYmNvbG9yXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGUoLypIVE1MRGl2RWxlbWVudCovIGRpdiwgLypBcHAqL2FwcCkge1xuICAgIGRpdi50ZXh0Q29udGVudCA9IFwiXCI7XG5cbiAgICBjb25zdCBjb21wbGV4Q29sb3JTY2hlbWUgPSBhcHAuZ2V0Q29tcGxleENvbG9ycygpO1xuICAgIGNvbnN0IGNvbXBsZXhDb2xvclRhYmxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInRhYmxlXCIpO1xuICAgIGNvbXBsZXhDb2xvclRhYmxlLmNsYXNzTGlzdC5hZGQoXCJjb2xvcl9rZXlcIiwgXCJjb21wbGV4X2NvbG9yc1wiKTtcbiAgICBjb25zdCB0aCA9IGNvbXBsZXhDb2xvclRhYmxlLmNyZWF0ZVRIZWFkKCk7XG4gICAgdGgudGV4dENvbnRlbnQgPSBcIkNvbXBsZXhlc1wiO1xuICAgIGNvbnN0IGNjRG9tYWluID0gY29tcGxleENvbG9yU2NoZW1lLmRvbWFpbigpO1xuICAgIGNvbnN0IGNjUmFuZ2UgPSBjb21wbGV4Q29sb3JTY2hlbWUucmFuZ2UoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNjRG9tYWluLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHRyID0gY29tcGxleENvbG9yVGFibGUuaW5zZXJ0Um93KCk7XG4gICAgICAgIGNvbnN0IHRjMSA9IHRyLmluc2VydENlbGwoKTtcbiAgICAgICAgdGMxLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGNjUmFuZ2VbaSAlIDZdO1xuICAgICAgICBjb25zdCB0YzIgPSB0ci5pbnNlcnRDZWxsKCk7XG4gICAgICAgIHRjMi50ZXh0Q29udGVudCA9IGNjRG9tYWluW2ldO1xuICAgICAgICAvL2NvbnNvbGUubG9nKGkgKyBcIiBcIiArIGNjRG9tYWluW2ldICsgXCIgXCIgKyBjY1JhbmdlW2ldKTtcbiAgICB9XG4gICAgZGl2LmFwcGVuZENoaWxkKGNvbXBsZXhDb2xvclRhYmxlKTtcblxuICAgIGNvbnN0IGZlYXR1cmVDb2xvclNjaGVtZSA9IGFwcC5nZXRGZWF0dXJlQ29sb3JzKCk7XG4gICAgaWYgKGZlYXR1cmVDb2xvclNjaGVtZSkge1xuICAgICAgICBjb25zdCBmZWF0dXJlQ29sb3JUYWJsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ0YWJsZVwiKTtcbiAgICAgICAgZmVhdHVyZUNvbG9yVGFibGUuY2xhc3NMaXN0LmFkZChcImNvbG9yX2tleVwiLCBcImZlYXR1cmVfY29sb3JzXCIpO1xuICAgICAgICBjb25zdCB0aDIgPSBmZWF0dXJlQ29sb3JUYWJsZS5jcmVhdGVUSGVhZCgpO1xuICAgICAgICB0aDIudGV4dENvbnRlbnQgPSBcIkZlYXR1cmVzXCI7XG4gICAgICAgIGNvbnN0IGRvbWFpbiA9IGZlYXR1cmVDb2xvclNjaGVtZS5kb21haW4oKTtcbiAgICAgICAgY29uc3QgcmFuZ2UgPSBmZWF0dXJlQ29sb3JTY2hlbWUucmFuZ2UoKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkb21haW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHRyID0gZmVhdHVyZUNvbG9yVGFibGUuaW5zZXJ0Um93KCk7XG4gICAgICAgICAgICBjb25zdCB0YzEgPSB0ci5pbnNlcnRDZWxsKCk7XG4gICAgICAgICAgICAvLyBtYWtlIHRyYW5zcGFyZW50IHZlcnNpb24gb2YgY29sb3JcbiAgICAgICAgICAgIC8vY29uc3QgdGVtcCA9IG5ldyBSR0JDb2xvcihyYW5nZVtpICUgMjBdKS47XG4gICAgICAgICAgICB0YzEuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gcmFuZ2VbaSAlIDIwXTsvL1wicmdiYShcIiArIHRlbXAuciArIFwiLFwiICsgdGVtcC5nICsgXCIsXCIgKyB0ZW1wLmIgKyBcIiwgMC42KVwiO1xuICAgICAgICAgICAgY29uc3QgdGMyID0gdHIuaW5zZXJ0Q2VsbCgpO1xuICAgICAgICAgICAgdGMyLnRleHRDb250ZW50ID0gZG9tYWluW2ldO1xuICAgICAgICB9XG4gICAgICAgIGRpdi5hcHBlbmRDaGlsZChmZWF0dXJlQ29sb3JUYWJsZSk7XG4gICAgfVxufSJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/js/color-scheme-key.js\n"); /***/ }), @@ -1173,11 +1173,11 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /*!**************************!*\ !*** ./src/js/config.js ***! \**************************/ -/*! exports provided: svgns, highlightColour, LABEL_Y, rotatePointAboutPoint */ +/*! exports provided: svgns, LABEL_Y, rotatePointAboutPoint */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"svgns\", function() { return svgns; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"highlightColour\", function() { return highlightColour; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"LABEL_Y\", function() { return LABEL_Y; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"rotatePointAboutPoint\", function() { return rotatePointAboutPoint; });\nconst svgns = \"http://www.w3.org/2000/svg\";//, // namespace for svg elements\n// xlinkNS: 'http://www.w3.org/1999/xlink', // namespace for xlink, for use/defs elements\n\nconst highlightColour = \"#ffff99\"; //, //\"#fdc086\"); // todo use css\n\nconst LABEL_Y = -5; // todo this isn't needed\n// selectedColour: '#ffff99',\n//\n// Polymer: {\n// STICKHEIGHT: 20,\n// MAXSIZE: 20,\n// transitionTime: 650\n// }\n// };\nfunction rotatePointAboutPoint (p, o, theta) {\n theta = (theta / 360) * Math.PI * 2; //TODO: change theta arg to radians not degrees\n const rx = Math.cos(theta) * (p[0] - o[0]) - Math.sin(theta) * (p[1] - o[1]) + o[0];\n const ry = Math.sin(theta) * (p[0] - o[0]) + Math.cos(theta) * (p[1] - o[1]) + o[1];\n return [rx, ry];\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvY29uZmlnLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy9jb25maWcuanM/MTRhYyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3Qgc3ZnbnMgPSBcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI7Ly8sIC8vIG5hbWVzcGFjZSBmb3Igc3ZnIGVsZW1lbnRzXG4vLyAgICAgeGxpbmtOUzogJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnLCAvLyBuYW1lc3BhY2UgZm9yIHhsaW5rLCBmb3IgdXNlL2RlZnMgZWxlbWVudHNcblxuZXhwb3J0IGNvbnN0IGhpZ2hsaWdodENvbG91ciA9IFwiI2ZmZmY5OVwiOyAvLywgLy9cIiNmZGMwODZcIik7IC8vIHRvZG8gdXNlIGNzc1xuXG5leHBvcnQgY29uc3QgTEFCRUxfWSA9IC01OyAvLyB0b2RvIHRoaXMgaXNuJ3QgbmVlZGVkXG4vLyAgICAgc2VsZWN0ZWRDb2xvdXI6ICcjZmZmZjk5Jyxcbi8vXG4vLyAgICAgUG9seW1lcjoge1xuLy8gICAgICAgICBTVElDS0hFSUdIVDogMjAsXG4vLyAgICAgICAgIE1BWFNJWkU6IDIwLFxuLy8gICAgICAgICB0cmFuc2l0aW9uVGltZTogNjUwXG4vLyAgICAgfVxuLy8gfTtcbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVQb2ludEFib3V0UG9pbnQgKHAsIG8sIHRoZXRhKSB7XG4gICAgdGhldGEgPSAodGhldGEgLyAzNjApICogTWF0aC5QSSAqIDI7IC8vVE9ETzogY2hhbmdlIHRoZXRhIGFyZyB0byByYWRpYW5zIG5vdCBkZWdyZWVzXG4gICAgY29uc3QgcnggPSBNYXRoLmNvcyh0aGV0YSkgKiAocFswXSAtIG9bMF0pIC0gTWF0aC5zaW4odGhldGEpICogKHBbMV0gLSBvWzFdKSArIG9bMF07XG4gICAgY29uc3QgcnkgPSBNYXRoLnNpbih0aGV0YSkgKiAocFswXSAtIG9bMF0pICsgTWF0aC5jb3ModGhldGEpICogKHBbMV0gLSBvWzFdKSArIG9bMV07XG4gICAgcmV0dXJuIFtyeCwgcnldO1xufSJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/config.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"svgns\", function() { return svgns; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"LABEL_Y\", function() { return LABEL_Y; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"rotatePointAboutPoint\", function() { return rotatePointAboutPoint; });\nconst svgns = \"http://www.w3.org/2000/svg\";//, // namespace for svg elements\n// xlinkNS: 'http://www.w3.org/1999/xlink', // namespace for xlink, for use/defs elements\n\nconst LABEL_Y = -5; // todo this isn't needed\n// selectedColour: '#ffff99',\n//\n// Polymer: {\n// STICKHEIGHT: 20,\n// MAXSIZE: 20,\n// transitionTime: 650\n// }\n// };\nfunction rotatePointAboutPoint (p, o, theta) {\n theta = (theta / 360) * Math.PI * 2; //TODO: change theta arg to radians not degrees\n const rx = Math.cos(theta) * (p[0] - o[0]) - Math.sin(theta) * (p[1] - o[1]) + o[0];\n const ry = Math.sin(theta) * (p[0] - o[0]) + Math.cos(theta) * (p[1] - o[1]) + o[1];\n return [rx, ry];\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvY29uZmlnLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy9jb25maWcuanM/MTRhYyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3Qgc3ZnbnMgPSBcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI7Ly8sIC8vIG5hbWVzcGFjZSBmb3Igc3ZnIGVsZW1lbnRzXG4vLyAgICAgeGxpbmtOUzogJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnLCAvLyBuYW1lc3BhY2UgZm9yIHhsaW5rLCBmb3IgdXNlL2RlZnMgZWxlbWVudHNcblxuZXhwb3J0IGNvbnN0IExBQkVMX1kgPSAtNTsgLy8gdG9kbyB0aGlzIGlzbid0IG5lZWRlZFxuLy8gICAgIHNlbGVjdGVkQ29sb3VyOiAnI2ZmZmY5OScsXG4vL1xuLy8gICAgIFBvbHltZXI6IHtcbi8vICAgICAgICAgU1RJQ0tIRUlHSFQ6IDIwLFxuLy8gICAgICAgICBNQVhTSVpFOiAyMCxcbi8vICAgICAgICAgdHJhbnNpdGlvblRpbWU6IDY1MFxuLy8gICAgIH1cbi8vIH07XG5leHBvcnQgZnVuY3Rpb24gcm90YXRlUG9pbnRBYm91dFBvaW50IChwLCBvLCB0aGV0YSkge1xuICAgIHRoZXRhID0gKHRoZXRhIC8gMzYwKSAqIE1hdGguUEkgKiAyOyAvL1RPRE86IGNoYW5nZSB0aGV0YSBhcmcgdG8gcmFkaWFucyBub3QgZGVncmVlc1xuICAgIGNvbnN0IHJ4ID0gTWF0aC5jb3ModGhldGEpICogKHBbMF0gLSBvWzBdKSAtIE1hdGguc2luKHRoZXRhKSAqIChwWzFdIC0gb1sxXSkgKyBvWzBdO1xuICAgIGNvbnN0IHJ5ID0gTWF0aC5zaW4odGhldGEpICogKHBbMF0gLSBvWzBdKSArIE1hdGguY29zKHRoZXRhKSAqIChwWzFdIC0gb1sxXSkgKyBvWzFdO1xuICAgIHJldHVybiBbcngsIHJ5XTtcbn0iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/config.js\n"); /***/ }), @@ -1205,6 +1205,18 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ }), +/***/ "./src/js/svgexp.js": +/*!**************************!*\ + !*** ./src/js/svgexp.js ***! + \**************************/ +/*! exports provided: svgUtils */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"svgUtils\", function() { return svgUtils; });\n/**\n * Created by cs22 on 04/12/14.\n */\n\nconst svgUtils = {\n \n capture: function (svgElems) {\n return svgElems.map (function(svg) { return svgUtils.makeSVGDoc (svg); });\n },\n\n getAllSVGElements: function () {\n // search through all document objects, including those in iframes\n var allIFrames = [].slice.apply (document.getElementsByTagName('iframe'));\n var docs = [document];\n allIFrames.forEach (function (iframe) {\n try {\n docs.push (iframe.contentDocument || iframe.contentWindow.document);\n }\n catch (e) {\n console.log (\"Protected cross-domain IFrame\", iframe);\n }\n });\n\n var allSvgs = [];\n docs.forEach (function(doc) {\n var allDocSvgs = [].slice.apply (doc.getElementsByTagName('svg'));\n allSvgs.push.apply (allSvgs, allDocSvgs);\n });\n return allSvgs;\n },\n\n\n makeSVGDoc: function (svgElem) {\n // clone node\n var cloneSVG = svgElem.cloneNode (true);\n var ownerDoc = cloneSVG.ownerDocument || document;\n svgUtils.pruneInvisibleSubtrees (cloneSVG, svgElem);\n\n // find all styles inherited/referenced at or below this node\n var styles = svgUtils.usedStyles (svgElem, true, true);\n\n // collect relevant info on parent chain of svg node\n var predecessorInfo = svgUtils.parentChain (svgElem, styles);\n \n var addDummy = function (dummySVGElem, cloneSVG, origSVG, transferAttr) {\n dummySVGElem.appendChild (cloneSVG);\n Object.keys(transferAttr).forEach (function (attr) {\n var val = cloneSVG.getAttribute (attr) || cloneSVG.style [attr] || svgUtils.getComputedStyleCssText (origSVG, attr);\n if (val != null) {\n dummySVGElem.setAttribute (attr, val);\n var attrVal = transferAttr[attr];\n if (attrVal.replace) {\n cloneSVG.setAttribute (attr, attrVal.replace);\n } else if (attrVal.delete) {\n cloneSVG.removeAttribute (attr);\n }\n }\n });\n };\n\n // make a chain of dummy svg nodes to include classes / ids of parent chain of our original svg\n // this means any styles referenced within the svg that depend on the presence of these classes/ids are fired\n var transferAttr = {width: {replace: \"100%\"}, height: {replace: \"100%\"}, xmlns: {delete: true}};\n var parentAdded = false;\n for (var p = 0; p < predecessorInfo.length; p++) {\n var pinf = predecessorInfo [p];\n //var dummySVGElem = ownerDoc.createElement (\"svg\");\n var dummySVGElem = ownerDoc.createElementNS (\"http://www.w3.org/2000/svg\", \"svg\");\n var empty = true;\n Object.keys(pinf).forEach (function (key) {\n if (pinf[key]) {\n dummySVGElem.setAttribute (key, pinf[key]);\n empty = false;\n }\n });\n // If the dummy svg has no relevant id, classes or computed style then ignore it, otherwise make it the new root\n if (!empty) {\n addDummy (dummySVGElem, cloneSVG, svgElem, transferAttr);\n cloneSVG = dummySVGElem;\n parentAdded = true;\n }\n }\n\n // if no dummy parent added in previous section, but our svg isn't root then add one as placeholder\n if (svgElem.parentNode != null && !parentAdded) {\n var dummySVGElem = ownerDoc.createElementNS (\"http://www.w3.org/2000/svg\", \"svg\");\n addDummy (dummySVGElem, cloneSVG, svgElem, transferAttr);\n cloneSVG = dummySVGElem;\n parentAdded = true;\n }\n\n // Copy svg's computed style (it's style context) if a dummy parent node has been introduced\n if (parentAdded) {\n cloneSVG.setAttribute (\"style\", svgUtils.getComputedStyleCssText (svgElem));\n }\n\n cloneSVG.setAttribute (\"version\", \"1.1\");\n //cloneSVG.setAttribute (\"xmlns\", \"http://www.w3.org/2000/svg\"); // XMLSerializer does this\n //cloneSVG.setAttribute (\"xmlns:xlink\", \"http://www.w3.org/1999/xlink\"); // when I used setAttributeNS it ballsed up\n\t\t// however using these attributeNS calls work, and stops errors in IE11. Win.\n\t\tcloneSVG.setAttributeNS (\"http://www.w3.org/2000/xmlns/\", \"xmlns\", \"http://www.w3.org/2000/svg\"); // XMLSerializer does this\n cloneSVG.setAttributeNS (\"http://www.w3.org/2000/xmlns/\", \"xmlns:xlink\", \"http://www.w3.org/1999/xlink\"); // when I used setAttributeNS it ballsed up\n\n\n var styleElem = ownerDoc.createElement (\"style\");\n styleElem.setAttribute (\"type\", \"text/css\");\n var styleText = ownerDoc.createTextNode (styles.join(\"\\n\"));\n styleElem.appendChild (styleText);\n cloneSVG.insertBefore (styleElem, cloneSVG.firstChild);\n\n return cloneSVG;\n },\n \n // Because firefox returns cssText as empty\n // https://bugzilla.mozilla.org/show_bug.cgi?id=137687\n getComputedStyleCssText: function (element, field) {\n var style = window.getComputedStyle(element);\n if (field) {\n return style[field];\n }\n\n if (style.cssText != \"\") {\n return style.cssText;\n }\n\n var cssText = \"\";\n for (var i = 0; i < style.length; i++) {\n var styleName = style[i];\n var propVal = style.getPropertyValue(styleName);\n cssText += styleName + \": \" + propVal + \"; \";\n }\n\n return cssText;\n },\n \n doPruneInvisible: true,\n \n pruneConditionSets: [{\"display\": \"none\"}, {\"visibility\": \"hidden\"}, {\"opacity\": \"0\"}, {\"fill-opacity\": \"0\", \"stroke-opacity\": \"0\"}, {\"fill-opacity\": \"0\", \"stroke\": \"none\"}, {\"fill\": \"none\", \"stroke-opacity\": \"0\"}],\n \n pruneInvisibleSubtrees: function (clonedElement, matchingOriginalElement) {\n if (svgUtils.doPruneInvisible) {\n var style = window.getComputedStyle (matchingOriginalElement); // cloned (unattached) nodes in chrome at least don't have computed styles\n var prune = false;\n \n svgUtils.pruneConditionSets.forEach (function (conditionSet) {\n if (!prune) {\n var allConditionsMet = true;\n Object.keys(conditionSet).forEach (function (condition) {\n var condVal = conditionSet[condition];\n var eStyle = style[condition];\n var eAttr = matchingOriginalElement.getAttribute(condition);\n if (!(eStyle === condVal || (!eStyle && eAttr === condVal))) {\n allConditionsMet = false; \n }\n });\n prune = allConditionsMet;\n }\n });\n if (prune && clonedElement.parentNode) {\n clonedElement.parentNode.removeChild (clonedElement);\n //console.log (\"removed\", clonedElement);\n } else {\n var clonedChildren = clonedElement.children;\n var matchingOriginalChildren = matchingOriginalElement.children;\n //console.log (\"kept\", clonedElement, style.display, style.visibility, style.opacity, style[\"stroke-opacity\"], style[\"fill-opacity\"], style);\n //console.log (element, \"children\", children);\n if (clonedChildren && clonedChildren.length) {\n // count backwards because removing a child will break the 'i' counter if we go forwards\n // e.g. if children=[A,B,C,D] and i=2, if we delete[C] then children becomes [A,B,D],\n // and when i then increments to 3, expecting D, instead we find the end of loop, and don't test D\n // PS. And if we fixed that we'd then need a separate counter for the original child elements anyways so backwards it is\n for (var i = clonedChildren.length; --i >= 0;) {\n svgUtils.pruneInvisibleSubtrees (clonedChildren[i], matchingOriginalChildren[i]);\n }\n }\n }\n }\n },\n\n parentChain: function (elem, styles) {\n // Capture id / classes of svg's parent chain.\n var ownerDoc = elem.ownerDocument || document;\n var elemArr = [];\n while (elem.parentNode !== ownerDoc && elem.parentNode !== null) {\n elem = elem.parentNode;\n elemArr.push ({id: elem.id, class: elem.getAttribute(\"class\") || \"\"});\n }\n\n // see if id or element class are referenced in any styles collected below the svg node\n // if not, null the id / class as they're not going to be relevant\n elemArr.forEach (function (elemData) {\n var presences = {id: false, class: false};\n var classes = elemData.class.split(\" \").filter(function(a) { return a.length > 0; }); // v1.13: may be multiple classes in a containing class attribute\n styles.forEach (function (style) {\n for (var c = 0; c < classes.length; c++) {\n if (style.indexOf (\".\"+classes[c]) >= 0) {\n presences.class = true;\n break; // no need to keep looking through rest of classtypes if one is needed\n }\n }\n if (elemData.id && style.indexOf (\"#\"+elemData.id) >= 0) {\n presences.id = true;\n }\n });\n Object.keys(presences).forEach (function (presence) {\n if (!presences[presence]) { elemData[presence] = undefined; }\n });\n });\n\n return elemArr;\n },\n\n // code adapted from user adardesign's answer in http://stackoverflow.com/questions/13204785/is-it-possible-to-read-the-styles-of-css-classes-not-being-used-in-the-dom-using\n usedStyles: function (elem, subtree, both) {\n var needed = [], rule;\n var ownerDoc = elem.ownerDocument || document;\n var CSSSheets = ownerDoc.styleSheets;\n\n for(var j=0; j < CSSSheets.length; j++){\n\t\t\t// stop accessing empty style sheets (1.15), catch security exceptions (1.20)\n\t\t\ttry{\n\t\t\t\tif (CSSSheets[j].cssRules == null) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t\n for(var i=0; i < CSSSheets[j].cssRules.length; i++){\n rule = CSSSheets[j].cssRules[i];\n var match = false;\n // Issue reported, css rule '[ng:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak, .ng-hide:not(.ng-hide-animate)' gives error\n // It's the [ng:cloak] bit that does the damage\n // Fix found from https://github.com/exupero/saveSvgAsPng/issues/11 - but the css rule isn't applied\n try {\n if (subtree) {\n match = elem.querySelectorAll(rule.selectorText).length > 0;\n }\n if (!subtree || both) {\n match |= elem.matches(rule.selectorText);\n }\n }\n catch (err) {\n console.warn (\"CSS selector error: \"+rule.selectorText+\". Often angular issue.\", err);\n }\n if (match) { needed.push (rule.cssText); }\n }\n }\n\n return needed;\n },\n \n makeXMLStr: function (xmls, svgDoc) {\n var xmlStr = xmls.serializeToString(svgDoc);\n // serializing adds an xmlns attribute to the style element ('cos it thinks we want xhtml), which knackers it for inkscape, here we chop it out\n xmlStr = xmlStr.split(\"xmlns=\\\"http://www.w3.org/1999/xhtml\\\"\").join(\"\");\n return xmlStr;\n },\n\n // saveSVGDocs: function (svgDocs) {\n // var xmls = new XMLSerializer();\n // svgDocs.forEach (function (svgDoc, i) {\n // var xmlStr = svgUtils.makeXMLStr (xmls, svgDoc);\n // var blob = new Blob([xmlStr], {type: \"image/svg+xml\"});\n // saveAs(blob, \"saved\"+i+\".svg\");\n // });\n // },\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvc3ZnZXhwLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy9zdmdleHAuanM/YWQ5ZCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENyZWF0ZWQgYnkgY3MyMiBvbiAwNC8xMi8xNC5cbiAqL1xuXG5leHBvcnQgY29uc3Qgc3ZnVXRpbHMgPSB7XG4gICAgXG4gICAgY2FwdHVyZTogZnVuY3Rpb24gKHN2Z0VsZW1zKSB7XG4gICAgICAgIHJldHVybiBzdmdFbGVtcy5tYXAgKGZ1bmN0aW9uKHN2ZykgeyByZXR1cm4gc3ZnVXRpbHMubWFrZVNWR0RvYyAoc3ZnKTsgfSk7XG4gICAgfSxcblxuICAgIGdldEFsbFNWR0VsZW1lbnRzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIHNlYXJjaCB0aHJvdWdoIGFsbCBkb2N1bWVudCBvYmplY3RzLCBpbmNsdWRpbmcgdGhvc2UgaW4gaWZyYW1lc1xuICAgICAgICB2YXIgYWxsSUZyYW1lcyA9IFtdLnNsaWNlLmFwcGx5IChkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaWZyYW1lJykpO1xuICAgICAgICB2YXIgZG9jcyA9IFtkb2N1bWVudF07XG4gICAgICAgIGFsbElGcmFtZXMuZm9yRWFjaCAoZnVuY3Rpb24gKGlmcmFtZSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBkb2NzLnB1c2ggKGlmcmFtZS5jb250ZW50RG9jdW1lbnQgfHwgaWZyYW1lLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyAoXCJQcm90ZWN0ZWQgY3Jvc3MtZG9tYWluIElGcmFtZVwiLCBpZnJhbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB2YXIgYWxsU3ZncyA9IFtdO1xuICAgICAgICBkb2NzLmZvckVhY2ggKGZ1bmN0aW9uKGRvYykge1xuICAgICAgICAgICAgdmFyIGFsbERvY1N2Z3MgPSBbXS5zbGljZS5hcHBseSAoZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzdmcnKSk7XG4gICAgICAgICAgICBhbGxTdmdzLnB1c2guYXBwbHkgKGFsbFN2Z3MsIGFsbERvY1N2Z3MpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGFsbFN2Z3M7XG4gICAgfSxcblxuXG4gICAgbWFrZVNWR0RvYzogZnVuY3Rpb24gKHN2Z0VsZW0pIHtcbiAgICAgICAgLy8gY2xvbmUgbm9kZVxuICAgICAgICB2YXIgY2xvbmVTVkcgPSBzdmdFbGVtLmNsb25lTm9kZSAodHJ1ZSk7XG4gICAgICAgIHZhciBvd25lckRvYyA9IGNsb25lU1ZHLm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQ7XG4gICAgICAgIHN2Z1V0aWxzLnBydW5lSW52aXNpYmxlU3VidHJlZXMgKGNsb25lU1ZHLCBzdmdFbGVtKTtcblxuICAgICAgICAvLyBmaW5kIGFsbCBzdHlsZXMgaW5oZXJpdGVkL3JlZmVyZW5jZWQgYXQgb3IgYmVsb3cgdGhpcyBub2RlXG4gICAgICAgIHZhciBzdHlsZXMgPSBzdmdVdGlscy51c2VkU3R5bGVzIChzdmdFbGVtLCB0cnVlLCB0cnVlKTtcblxuICAgICAgICAvLyBjb2xsZWN0IHJlbGV2YW50IGluZm8gb24gcGFyZW50IGNoYWluIG9mIHN2ZyBub2RlXG4gICAgICAgIHZhciBwcmVkZWNlc3NvckluZm8gPSBzdmdVdGlscy5wYXJlbnRDaGFpbiAoc3ZnRWxlbSwgc3R5bGVzKTtcbiAgICAgICAgXG4gICAgICAgIHZhciBhZGREdW1teSA9IGZ1bmN0aW9uIChkdW1teVNWR0VsZW0sIGNsb25lU1ZHLCBvcmlnU1ZHLCB0cmFuc2ZlckF0dHIpIHtcbiAgICAgICAgICAgIGR1bW15U1ZHRWxlbS5hcHBlbmRDaGlsZCAoY2xvbmVTVkcpO1xuICAgICAgICAgICAgT2JqZWN0LmtleXModHJhbnNmZXJBdHRyKS5mb3JFYWNoIChmdW5jdGlvbiAoYXR0cikge1xuICAgICAgICAgICAgICAgIHZhciB2YWwgPSBjbG9uZVNWRy5nZXRBdHRyaWJ1dGUgKGF0dHIpIHx8IGNsb25lU1ZHLnN0eWxlIFthdHRyXSB8fCBzdmdVdGlscy5nZXRDb21wdXRlZFN0eWxlQ3NzVGV4dCAob3JpZ1NWRywgYXR0cik7XG4gICAgICAgICAgICAgICAgaWYgKHZhbCAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGR1bW15U1ZHRWxlbS5zZXRBdHRyaWJ1dGUgKGF0dHIsIHZhbCk7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhdHRyVmFsID0gdHJhbnNmZXJBdHRyW2F0dHJdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXR0clZhbC5yZXBsYWNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjbG9uZVNWRy5zZXRBdHRyaWJ1dGUgKGF0dHIsIGF0dHJWYWwucmVwbGFjZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoYXR0clZhbC5kZWxldGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsb25lU1ZHLnJlbW92ZUF0dHJpYnV0ZSAoYXR0cik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBtYWtlIGEgY2hhaW4gb2YgZHVtbXkgc3ZnIG5vZGVzIHRvIGluY2x1ZGUgY2xhc3NlcyAvIGlkcyBvZiBwYXJlbnQgY2hhaW4gb2Ygb3VyIG9yaWdpbmFsIHN2Z1xuICAgICAgICAvLyB0aGlzIG1lYW5zIGFueSBzdHlsZXMgcmVmZXJlbmNlZCB3aXRoaW4gdGhlIHN2ZyB0aGF0IGRlcGVuZCBvbiB0aGUgcHJlc2VuY2Ugb2YgdGhlc2UgY2xhc3Nlcy9pZHMgYXJlIGZpcmVkXG4gICAgICAgIHZhciB0cmFuc2ZlckF0dHIgPSB7d2lkdGg6IHtyZXBsYWNlOiBcIjEwMCVcIn0sIGhlaWdodDoge3JlcGxhY2U6IFwiMTAwJVwifSwgeG1sbnM6IHtkZWxldGU6IHRydWV9fTtcbiAgICAgICAgdmFyIHBhcmVudEFkZGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAodmFyIHAgPSAwOyBwIDwgcHJlZGVjZXNzb3JJbmZvLmxlbmd0aDsgcCsrKSB7XG4gICAgICAgICAgICB2YXIgcGluZiA9IHByZWRlY2Vzc29ySW5mbyBbcF07XG4gICAgICAgICAgICAvL3ZhciBkdW1teVNWR0VsZW0gPSBvd25lckRvYy5jcmVhdGVFbGVtZW50IChcInN2Z1wiKTtcbiAgICAgICAgICAgIHZhciBkdW1teVNWR0VsZW0gPSBvd25lckRvYy5jcmVhdGVFbGVtZW50TlMgKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiwgXCJzdmdcIik7XG4gICAgICAgICAgICB2YXIgZW1wdHkgPSB0cnVlO1xuICAgICAgICAgICAgT2JqZWN0LmtleXMocGluZikuZm9yRWFjaCAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgICAgICAgICAgIGlmIChwaW5mW2tleV0pIHtcbiAgICAgICAgICAgICAgICAgICAgZHVtbXlTVkdFbGVtLnNldEF0dHJpYnV0ZSAoa2V5LCBwaW5mW2tleV0pO1xuICAgICAgICAgICAgICAgICAgICBlbXB0eSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGR1bW15IHN2ZyBoYXMgbm8gcmVsZXZhbnQgaWQsIGNsYXNzZXMgb3IgY29tcHV0ZWQgc3R5bGUgdGhlbiBpZ25vcmUgaXQsIG90aGVyd2lzZSBtYWtlIGl0IHRoZSBuZXcgcm9vdFxuICAgICAgICAgICAgaWYgKCFlbXB0eSkge1xuICAgICAgICAgICAgICAgIGFkZER1bW15IChkdW1teVNWR0VsZW0sIGNsb25lU1ZHLCBzdmdFbGVtLCB0cmFuc2ZlckF0dHIpO1xuICAgICAgICAgICAgICAgIGNsb25lU1ZHID0gZHVtbXlTVkdFbGVtO1xuICAgICAgICAgICAgICAgIHBhcmVudEFkZGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIG5vIGR1bW15IHBhcmVudCBhZGRlZCBpbiBwcmV2aW91cyBzZWN0aW9uLCBidXQgb3VyIHN2ZyBpc24ndCByb290IHRoZW4gYWRkIG9uZSBhcyBwbGFjZWhvbGRlclxuICAgICAgICBpZiAoc3ZnRWxlbS5wYXJlbnROb2RlICE9IG51bGwgJiYgIXBhcmVudEFkZGVkKSB7XG4gICAgICAgICAgICB2YXIgZHVtbXlTVkdFbGVtID0gb3duZXJEb2MuY3JlYXRlRWxlbWVudE5TIChcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwic3ZnXCIpO1xuICAgICAgICAgICAgYWRkRHVtbXkgKGR1bW15U1ZHRWxlbSwgY2xvbmVTVkcsIHN2Z0VsZW0sIHRyYW5zZmVyQXR0cik7XG4gICAgICAgICAgICBjbG9uZVNWRyA9IGR1bW15U1ZHRWxlbTtcbiAgICAgICAgICAgIHBhcmVudEFkZGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvcHkgc3ZnJ3MgY29tcHV0ZWQgc3R5bGUgKGl0J3Mgc3R5bGUgY29udGV4dCkgaWYgYSBkdW1teSBwYXJlbnQgbm9kZSBoYXMgYmVlbiBpbnRyb2R1Y2VkXG4gICAgICAgIGlmIChwYXJlbnRBZGRlZCkge1xuICAgICAgICAgICAgY2xvbmVTVkcuc2V0QXR0cmlidXRlIChcInN0eWxlXCIsIHN2Z1V0aWxzLmdldENvbXB1dGVkU3R5bGVDc3NUZXh0IChzdmdFbGVtKSk7XG4gICAgICAgIH1cblxuICAgICAgICBjbG9uZVNWRy5zZXRBdHRyaWJ1dGUgKFwidmVyc2lvblwiLCBcIjEuMVwiKTtcbiAgICAgICAgLy9jbG9uZVNWRy5zZXRBdHRyaWJ1dGUgKFwieG1sbnNcIiwgXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiKTsgICAgLy8gWE1MU2VyaWFsaXplciBkb2VzIHRoaXNcbiAgICAgICAgLy9jbG9uZVNWRy5zZXRBdHRyaWJ1dGUgKFwieG1sbnM6eGxpbmtcIiwgXCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIpOyAgLy8gd2hlbiBJIHVzZWQgc2V0QXR0cmlidXRlTlMgaXQgYmFsbHNlZCB1cFxuXHRcdC8vIGhvd2V2ZXIgdXNpbmcgdGhlc2UgYXR0cmlidXRlTlMgY2FsbHMgd29yaywgYW5kIHN0b3BzIGVycm9ycyBpbiBJRTExLiBXaW4uXG5cdFx0Y2xvbmVTVkcuc2V0QXR0cmlidXRlTlMgKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC94bWxucy9cIiwgXCJ4bWxuc1wiLCBcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIpOyAgICAvLyBYTUxTZXJpYWxpemVyIGRvZXMgdGhpc1xuICAgICAgICBjbG9uZVNWRy5zZXRBdHRyaWJ1dGVOUyAoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zL1wiLCBcInhtbG5zOnhsaW5rXCIsIFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlua1wiKTsgIC8vIHdoZW4gSSB1c2VkIHNldEF0dHJpYnV0ZU5TIGl0IGJhbGxzZWQgdXBcblxuXG4gICAgICAgIHZhciBzdHlsZUVsZW0gPSBvd25lckRvYy5jcmVhdGVFbGVtZW50IChcInN0eWxlXCIpO1xuICAgICAgICBzdHlsZUVsZW0uc2V0QXR0cmlidXRlIChcInR5cGVcIiwgXCJ0ZXh0L2Nzc1wiKTtcbiAgICAgICAgdmFyIHN0eWxlVGV4dCA9IG93bmVyRG9jLmNyZWF0ZVRleHROb2RlIChzdHlsZXMuam9pbihcIlxcblwiKSk7XG4gICAgICAgIHN0eWxlRWxlbS5hcHBlbmRDaGlsZCAoc3R5bGVUZXh0KTtcbiAgICAgICAgY2xvbmVTVkcuaW5zZXJ0QmVmb3JlIChzdHlsZUVsZW0sIGNsb25lU1ZHLmZpcnN0Q2hpbGQpO1xuXG4gICAgICAgIHJldHVybiBjbG9uZVNWRztcbiAgICB9LFxuICAgIFxuICAgIC8vIEJlY2F1c2UgZmlyZWZveCByZXR1cm5zIGNzc1RleHQgYXMgZW1wdHlcbiAgICAvLyBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzc2ODdcbiAgICBnZXRDb21wdXRlZFN0eWxlQ3NzVGV4dDogZnVuY3Rpb24gKGVsZW1lbnQsIGZpZWxkKSB7XG4gICAgICAgIHZhciBzdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICAgICAgICBpZiAoZmllbGQpIHtcbiAgICAgICAgICAgIHJldHVybiBzdHlsZVtmaWVsZF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc3R5bGUuY3NzVGV4dCAhPSBcIlwiKSB7XG4gICAgICAgICAgICByZXR1cm4gc3R5bGUuY3NzVGV4dDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjc3NUZXh0ID0gXCJcIjtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHlsZS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdmFyIHN0eWxlTmFtZSA9IHN0eWxlW2ldO1xuICAgICAgICAgICAgdmFyIHByb3BWYWwgPSBzdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKHN0eWxlTmFtZSk7XG4gICAgICAgICAgICBjc3NUZXh0ICs9IHN0eWxlTmFtZSArIFwiOiBcIiArIHByb3BWYWwgKyBcIjsgXCI7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY3NzVGV4dDtcbiAgICB9LFxuICAgIFxuICAgIGRvUHJ1bmVJbnZpc2libGU6IHRydWUsXG4gICAgXG4gICAgcHJ1bmVDb25kaXRpb25TZXRzOiBbe1wiZGlzcGxheVwiOiBcIm5vbmVcIn0sIHtcInZpc2liaWxpdHlcIjogXCJoaWRkZW5cIn0sIHtcIm9wYWNpdHlcIjogXCIwXCJ9LCB7XCJmaWxsLW9wYWNpdHlcIjogXCIwXCIsIFwic3Ryb2tlLW9wYWNpdHlcIjogXCIwXCJ9LCB7XCJmaWxsLW9wYWNpdHlcIjogXCIwXCIsIFwic3Ryb2tlXCI6IFwibm9uZVwifSwge1wiZmlsbFwiOiBcIm5vbmVcIiwgXCJzdHJva2Utb3BhY2l0eVwiOiBcIjBcIn1dLFxuICAgIFxuICAgIHBydW5lSW52aXNpYmxlU3VidHJlZXM6IGZ1bmN0aW9uIChjbG9uZWRFbGVtZW50LCBtYXRjaGluZ09yaWdpbmFsRWxlbWVudCkge1xuICAgICAgICBpZiAoc3ZnVXRpbHMuZG9QcnVuZUludmlzaWJsZSkge1xuICAgICAgICAgICAgdmFyIHN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUgKG1hdGNoaW5nT3JpZ2luYWxFbGVtZW50KTsgIC8vIGNsb25lZCAodW5hdHRhY2hlZCkgbm9kZXMgaW4gY2hyb21lIGF0IGxlYXN0IGRvbid0IGhhdmUgY29tcHV0ZWQgc3R5bGVzXG4gICAgICAgICAgICB2YXIgcHJ1bmUgPSBmYWxzZTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgc3ZnVXRpbHMucHJ1bmVDb25kaXRpb25TZXRzLmZvckVhY2ggKGZ1bmN0aW9uIChjb25kaXRpb25TZXQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXBydW5lKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhbGxDb25kaXRpb25zTWV0ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmtleXMoY29uZGl0aW9uU2V0KS5mb3JFYWNoIChmdW5jdGlvbiAoY29uZGl0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY29uZFZhbCA9IGNvbmRpdGlvblNldFtjb25kaXRpb25dO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVTdHlsZSA9IHN0eWxlW2NvbmRpdGlvbl07XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZUF0dHIgPSBtYXRjaGluZ09yaWdpbmFsRWxlbWVudC5nZXRBdHRyaWJ1dGUoY29uZGl0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGVTdHlsZSA9PT0gY29uZFZhbCB8fCAoIWVTdHlsZSAmJiBlQXR0ciA9PT0gY29uZFZhbCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxsQ29uZGl0aW9uc01ldCA9IGZhbHNlOyBcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIHBydW5lID0gYWxsQ29uZGl0aW9uc01ldDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmIChwcnVuZSAmJiBjbG9uZWRFbGVtZW50LnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICBjbG9uZWRFbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQgKGNsb25lZEVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2cgKFwicmVtb3ZlZFwiLCBjbG9uZWRFbGVtZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIGNsb25lZENoaWxkcmVuID0gY2xvbmVkRWxlbWVudC5jaGlsZHJlbjtcbiAgICAgICAgICAgICAgICB2YXIgbWF0Y2hpbmdPcmlnaW5hbENoaWxkcmVuID0gbWF0Y2hpbmdPcmlnaW5hbEVsZW1lbnQuY2hpbGRyZW47XG4gICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyAoXCJrZXB0XCIsIGNsb25lZEVsZW1lbnQsIHN0eWxlLmRpc3BsYXksIHN0eWxlLnZpc2liaWxpdHksIHN0eWxlLm9wYWNpdHksIHN0eWxlW1wic3Ryb2tlLW9wYWNpdHlcIl0sIHN0eWxlW1wiZmlsbC1vcGFjaXR5XCJdLCBzdHlsZSk7XG4gICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyAoZWxlbWVudCwgXCJjaGlsZHJlblwiLCBjaGlsZHJlbik7XG4gICAgICAgICAgICAgICAgaWYgKGNsb25lZENoaWxkcmVuICYmIGNsb25lZENoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBjb3VudCBiYWNrd2FyZHMgYmVjYXVzZSByZW1vdmluZyBhIGNoaWxkIHdpbGwgYnJlYWsgdGhlICdpJyBjb3VudGVyIGlmIHdlIGdvIGZvcndhcmRzXG4gICAgICAgICAgICAgICAgICAgIC8vIGUuZy4gaWYgY2hpbGRyZW49W0EsQixDLERdIGFuZCBpPTIsIGlmIHdlIGRlbGV0ZVtDXSB0aGVuIGNoaWxkcmVuIGJlY29tZXMgW0EsQixEXSxcbiAgICAgICAgICAgICAgICAgICAgLy8gYW5kIHdoZW4gaSB0aGVuIGluY3JlbWVudHMgdG8gMywgZXhwZWN0aW5nIEQsIGluc3RlYWQgd2UgZmluZCB0aGUgZW5kIG9mIGxvb3AsIGFuZCBkb24ndCB0ZXN0IERcbiAgICAgICAgICAgICAgICAgICAgLy8gUFMuIEFuZCBpZiB3ZSBmaXhlZCB0aGF0IHdlJ2QgdGhlbiBuZWVkIGEgc2VwYXJhdGUgY291bnRlciBmb3IgdGhlIG9yaWdpbmFsIGNoaWxkIGVsZW1lbnRzIGFueXdheXMgc28gYmFja3dhcmRzIGl0IGlzXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSBjbG9uZWRDaGlsZHJlbi5sZW5ndGg7IC0taSA+PSAwOykge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3ZnVXRpbHMucHJ1bmVJbnZpc2libGVTdWJ0cmVlcyAoY2xvbmVkQ2hpbGRyZW5baV0sIG1hdGNoaW5nT3JpZ2luYWxDaGlsZHJlbltpXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcGFyZW50Q2hhaW46IGZ1bmN0aW9uIChlbGVtLCBzdHlsZXMpIHtcbiAgICAgICAgLy8gQ2FwdHVyZSBpZCAvIGNsYXNzZXMgb2Ygc3ZnJ3MgcGFyZW50IGNoYWluLlxuICAgICAgICB2YXIgb3duZXJEb2MgPSBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQ7XG4gICAgICAgIHZhciBlbGVtQXJyID0gW107XG4gICAgICAgIHdoaWxlIChlbGVtLnBhcmVudE5vZGUgIT09IG93bmVyRG9jICYmIGVsZW0ucGFyZW50Tm9kZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgZWxlbSA9IGVsZW0ucGFyZW50Tm9kZTtcbiAgICAgICAgICAgIGVsZW1BcnIucHVzaCAoe2lkOiBlbGVtLmlkLCBjbGFzczogZWxlbS5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKSB8fCBcIlwifSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzZWUgaWYgaWQgb3IgZWxlbWVudCBjbGFzcyBhcmUgcmVmZXJlbmNlZCBpbiBhbnkgc3R5bGVzIGNvbGxlY3RlZCBiZWxvdyB0aGUgc3ZnIG5vZGVcbiAgICAgICAgLy8gaWYgbm90LCBudWxsIHRoZSBpZCAvIGNsYXNzIGFzIHRoZXkncmUgbm90IGdvaW5nIHRvIGJlIHJlbGV2YW50XG4gICAgICAgIGVsZW1BcnIuZm9yRWFjaCAoZnVuY3Rpb24gKGVsZW1EYXRhKSB7XG4gICAgICAgICAgICB2YXIgcHJlc2VuY2VzID0ge2lkOiBmYWxzZSwgY2xhc3M6IGZhbHNlfTtcbiAgICAgICAgICAgIHZhciBjbGFzc2VzID0gZWxlbURhdGEuY2xhc3Muc3BsaXQoXCIgXCIpLmZpbHRlcihmdW5jdGlvbihhKSB7IHJldHVybiBhLmxlbmd0aCA+IDA7IH0pOyAgIC8vIHYxLjEzOiBtYXkgYmUgbXVsdGlwbGUgY2xhc3NlcyBpbiBhIGNvbnRhaW5pbmcgY2xhc3MgYXR0cmlidXRlXG4gICAgICAgICAgICBzdHlsZXMuZm9yRWFjaCAoZnVuY3Rpb24gKHN0eWxlKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgYyA9IDA7IGMgPCBjbGFzc2VzLmxlbmd0aDsgYysrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdHlsZS5pbmRleE9mIChcIi5cIitjbGFzc2VzW2NdKSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwcmVzZW5jZXMuY2xhc3MgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7ICAvLyBubyBuZWVkIHRvIGtlZXAgbG9va2luZyB0aHJvdWdoIHJlc3Qgb2YgY2xhc3N0eXBlcyBpZiBvbmUgaXMgbmVlZGVkXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGVsZW1EYXRhLmlkICYmIHN0eWxlLmluZGV4T2YgKFwiI1wiK2VsZW1EYXRhLmlkKSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHByZXNlbmNlcy5pZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhwcmVzZW5jZXMpLmZvckVhY2ggKGZ1bmN0aW9uIChwcmVzZW5jZSkge1xuICAgICAgICAgICAgICAgIGlmICghcHJlc2VuY2VzW3ByZXNlbmNlXSkgeyBlbGVtRGF0YVtwcmVzZW5jZV0gPSB1bmRlZmluZWQ7IH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gZWxlbUFycjtcbiAgICB9LFxuXG4gICAgLy8gY29kZSBhZGFwdGVkIGZyb20gdXNlciBhZGFyZGVzaWduJ3MgYW5zd2VyIGluIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTMyMDQ3ODUvaXMtaXQtcG9zc2libGUtdG8tcmVhZC10aGUtc3R5bGVzLW9mLWNzcy1jbGFzc2VzLW5vdC1iZWluZy11c2VkLWluLXRoZS1kb20tdXNpbmdcbiAgICB1c2VkU3R5bGVzOiBmdW5jdGlvbiAoZWxlbSwgc3VidHJlZSwgYm90aCkge1xuICAgICAgICB2YXIgbmVlZGVkID0gW10sIHJ1bGU7XG4gICAgICAgIHZhciBvd25lckRvYyA9IGVsZW0ub3duZXJEb2N1bWVudCB8fCBkb2N1bWVudDtcbiAgICAgICAgdmFyIENTU1NoZWV0cyA9IG93bmVyRG9jLnN0eWxlU2hlZXRzO1xuXG4gICAgICAgIGZvcih2YXIgaj0wOyBqIDwgQ1NTU2hlZXRzLmxlbmd0aDsgaisrKXtcblx0XHRcdC8vIHN0b3AgYWNjZXNzaW5nIGVtcHR5IHN0eWxlIHNoZWV0cyAoMS4xNSksIGNhdGNoIHNlY3VyaXR5IGV4Y2VwdGlvbnMgKDEuMjApXG5cdFx0XHR0cnl7XG5cdFx0XHRcdGlmIChDU1NTaGVldHNbal0uY3NzUnVsZXMgPT0gbnVsbCkge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cdFx0XHRcbiAgICAgICAgICAgIGZvcih2YXIgaT0wOyBpIDwgQ1NTU2hlZXRzW2pdLmNzc1J1bGVzLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgICAgICBydWxlID0gQ1NTU2hlZXRzW2pdLmNzc1J1bGVzW2ldO1xuICAgICAgICAgICAgICAgIHZhciBtYXRjaCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIC8vIElzc3VlIHJlcG9ydGVkLCBjc3MgcnVsZSAnW25nOmNsb2FrXSwgW25nLWNsb2FrXSwgW2RhdGEtbmctY2xvYWtdLCBbeC1uZy1jbG9ha10sIC5uZy1jbG9haywgLngtbmctY2xvYWssIC5uZy1oaWRlOm5vdCgubmctaGlkZS1hbmltYXRlKScgZ2l2ZXMgZXJyb3JcbiAgICAgICAgICAgICAgICAvLyBJdCdzIHRoZSBbbmc6Y2xvYWtdIGJpdCB0aGF0IGRvZXMgdGhlIGRhbWFnZVxuICAgICAgICAgICAgICAgIC8vIEZpeCBmb3VuZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9leHVwZXJvL3NhdmVTdmdBc1BuZy9pc3N1ZXMvMTEgLSBidXQgdGhlIGNzcyBydWxlIGlzbid0IGFwcGxpZWRcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3VidHJlZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2ggPSBlbGVtLnF1ZXJ5U2VsZWN0b3JBbGwocnVsZS5zZWxlY3RvclRleHQpLmxlbmd0aCA+IDA7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdWJ0cmVlIHx8IGJvdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hdGNoIHw9IGVsZW0ubWF0Y2hlcyhydWxlLnNlbGVjdG9yVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4gKFwiQ1NTIHNlbGVjdG9yIGVycm9yOiBcIitydWxlLnNlbGVjdG9yVGV4dCtcIi4gT2Z0ZW4gYW5ndWxhciBpc3N1ZS5cIiwgZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7IG5lZWRlZC5wdXNoIChydWxlLmNzc1RleHQpOyB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmVlZGVkO1xuICAgIH0sXG4gICAgXG4gICAgbWFrZVhNTFN0cjogZnVuY3Rpb24gKHhtbHMsIHN2Z0RvYykge1xuICAgICAgICB2YXIgeG1sU3RyID0geG1scy5zZXJpYWxpemVUb1N0cmluZyhzdmdEb2MpO1xuICAgICAgICAvLyBzZXJpYWxpemluZyBhZGRzIGFuIHhtbG5zIGF0dHJpYnV0ZSB0byB0aGUgc3R5bGUgZWxlbWVudCAoJ2NvcyBpdCB0aGlua3Mgd2Ugd2FudCB4aHRtbCksIHdoaWNoIGtuYWNrZXJzIGl0IGZvciBpbmtzY2FwZSwgaGVyZSB3ZSBjaG9wIGl0IG91dFxuICAgICAgICB4bWxTdHIgPSB4bWxTdHIuc3BsaXQoXCJ4bWxucz1cXFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFxcXCJcIikuam9pbihcIlwiKTtcbiAgICAgICAgcmV0dXJuIHhtbFN0cjtcbiAgICB9LFxuXG4gICAgLy8gc2F2ZVNWR0RvY3M6IGZ1bmN0aW9uIChzdmdEb2NzKSB7XG4gICAgLy8gICAgIHZhciB4bWxzID0gbmV3IFhNTFNlcmlhbGl6ZXIoKTtcbiAgICAvLyAgICAgc3ZnRG9jcy5mb3JFYWNoIChmdW5jdGlvbiAoc3ZnRG9jLCBpKSB7XG4gICAgLy8gICAgICAgICB2YXIgeG1sU3RyID0gc3ZnVXRpbHMubWFrZVhNTFN0ciAoeG1scywgc3ZnRG9jKTtcbiAgICAvLyAgICAgICAgIHZhciBibG9iID0gbmV3IEJsb2IoW3htbFN0cl0sIHt0eXBlOiBcImltYWdlL3N2Zyt4bWxcIn0pO1xuICAgIC8vICAgICAgICAgc2F2ZUFzKGJsb2IsIFwic2F2ZWRcIitpK1wiLnN2Z1wiKTtcbiAgICAvLyAgICAgfSk7XG4gICAgLy8gfSxcbn07Il0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/svgexp.js\n"); + +/***/ }), + /***/ "./src/js/viz/interactor/annotation.js": /*!*********************************************!*\ !*** ./src/js/viz/interactor/annotation.js ***! @@ -1213,7 +1225,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Annotation\", function() { return Annotation; });\n//constructor for annotations\nfunction Annotation(annotationName, seqDatum) {\n console.log(\"**\", annotationName, seqDatum);\n this.description = annotationName.trim();\n this.seqDatum = seqDatum;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvYW5ub3RhdGlvbi5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2ludGVyYWN0b3IvYW5ub3RhdGlvbi5qcz8yYTZkIl0sInNvdXJjZXNDb250ZW50IjpbIi8vY29uc3RydWN0b3IgZm9yIGFubm90YXRpb25zXG5leHBvcnQgZnVuY3Rpb24gQW5ub3RhdGlvbihhbm5vdGF0aW9uTmFtZSwgc2VxRGF0dW0pIHtcbiAgICBjb25zb2xlLmxvZyhcIioqXCIsIGFubm90YXRpb25OYW1lLCBzZXFEYXR1bSk7XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IGFubm90YXRpb25OYW1lLnRyaW0oKTtcbiAgICB0aGlzLnNlcURhdHVtID0gc2VxRGF0dW07XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/annotation.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Annotation\", function() { return Annotation; });\n//constructor for annotations\nfunction Annotation(annotationName, seqDatum) {\n // console.log(\"**\", annotationName, seqDatum);\n this.description = annotationName.trim();\n this.seqDatum = seqDatum;\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvYW5ub3RhdGlvbi5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2ludGVyYWN0b3IvYW5ub3RhdGlvbi5qcz8yYTZkIl0sInNvdXJjZXNDb250ZW50IjpbIi8vY29uc3RydWN0b3IgZm9yIGFubm90YXRpb25zXG5leHBvcnQgZnVuY3Rpb24gQW5ub3RhdGlvbihhbm5vdGF0aW9uTmFtZSwgc2VxRGF0dW0pIHtcbiAgICAvLyBjb25zb2xlLmxvZyhcIioqXCIsIGFubm90YXRpb25OYW1lLCBzZXFEYXR1bSk7XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IGFubm90YXRpb25OYW1lLnRyaW0oKTtcbiAgICB0aGlzLnNlcURhdHVtID0gc2VxRGF0dW07XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/annotation.js\n"); /***/ }), @@ -1249,7 +1261,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Complex\", function() { return Complex; });\n/* harmony import */ var _interactor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./interactor */ \"./src/js/viz/interactor/interactor.js\");\n/* harmony import */ var point2d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! point2d */ \"./node_modules/point2d/index.js\");\n/* harmony import */ var point2d__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(point2d__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var intersectionjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! intersectionjs */ \"./node_modules/intersectionjs/intersection.js\");\n/* harmony import */ var intersectionjs__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(intersectionjs__WEBPACK_IMPORTED_MODULE_2__);\n\n\n\n\nfunction Complex(id, app) {\n this.init(id, app);\n this.type = \"complex\";\n this.padding = 20;\n\n // const self = this;\n // // its bad if you end up with these getting called\n // Object.defineProperty(this, \"width\", {\n // get: function height() {\n // return self.naryLink.path.getBBox().width;\n // //return 160;\n // }\n // });\n // Object.defineProperty(this, \"height\", {\n // get: function height() {\n // return self.naryLink.path.getBBox().height;\n // //return 160;\n // }\n // });\n}\n\nComplex.prototype = new _interactor__WEBPACK_IMPORTED_MODULE_0__[\"Interactor\"]();\n\n// Complex.prototype = {\n// get width() {\n// return this.naryLink.path.getBBox().width;\n// },\n// get height() {\n// return this.naryLink.path.getBBox().height;\n// },\n// };\n\nComplex.prototype.initLink = function (naryLink) {\n this.naryLink = naryLink;\n naryLink.path.setAttribute(\"stroke\", \"white\");\n naryLink.path.setAttribute(\"stroke-linejoin\", \"round\");\n naryLink.path.setAttribute(\"stroke-width\", 4);\n};\n\nComplex.prototype.getPosition = function (originPoint) {\n const mapped = this.naryLink.mapped;//getMappedCoordinates();\n const mc = mapped.length;\n let xSum = 0,\n ySum = 0;\n for (let m = 0; m < mc; m++) {\n xSum += mapped[m][0];\n ySum += mapped[m][1];\n }\n let center = [xSum / mc, ySum / mc];\n if (originPoint) {\n // if (participant.type === \"complex\"){\n // startPoint = participant.getPosition();\n let naryPath = this.naryLink.hull;\n let iPath = [];\n for (let p of naryPath) {\n iPath.push(new point2d__WEBPACK_IMPORTED_MODULE_1__(p[0], p[1]));\n }\n let a1 = new point2d__WEBPACK_IMPORTED_MODULE_1__(center[0], center[1]);\n let a2 = new point2d__WEBPACK_IMPORTED_MODULE_1__(originPoint[0], originPoint[1]);\n let intersect = intersectionjs__WEBPACK_IMPORTED_MODULE_2__[\"intersectLinePolygon\"](a1, a2, iPath);\n if (intersect.points[0]) {\n return [intersect.points[0].x, intersect.points[0].y];\n }\n }\n return center;\n};\n\nComplex.prototype.setPosition = function () {\n console.error(\"bad - called setPosition on \", this);\n};\n\nComplex.prototype.changePosition = function (dx, dy) {\n for (let participant of this.naryLink.participants){\n participant.changePosition(dx, dy);\n }\n};\n\nComplex.prototype.getResidueCoordinates = function () {\n return this.getPosition();\n};\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvY29tcGxleC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2ludGVyYWN0b3IvY29tcGxleC5qcz8zOTQ4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SW50ZXJhY3Rvcn0gZnJvbSBcIi4vaW50ZXJhY3RvclwiO1xuaW1wb3J0ICogYXMgUG9pbnQyRCBmcm9tIFwicG9pbnQyZFwiO1xuaW1wb3J0ICogYXMgSW50ZXJzZWN0aW9uIGZyb20gXCJpbnRlcnNlY3Rpb25qc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gQ29tcGxleChpZCwgYXBwKSB7XG4gICAgdGhpcy5pbml0KGlkLCBhcHApO1xuICAgIHRoaXMudHlwZSA9IFwiY29tcGxleFwiO1xuICAgIHRoaXMucGFkZGluZyA9IDIwO1xuXG4gICAgLy8gY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgLy8gLy8gaXRzIGJhZCBpZiB5b3UgZW5kIHVwIHdpdGggdGhlc2UgZ2V0dGluZyBjYWxsZWRcbiAgICAvLyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJ3aWR0aFwiLCB7XG4gICAgLy8gICAgIGdldDogZnVuY3Rpb24gaGVpZ2h0KCkge1xuICAgIC8vICAgICAgICAgcmV0dXJuIHNlbGYubmFyeUxpbmsucGF0aC5nZXRCQm94KCkud2lkdGg7XG4gICAgLy8gICAgICAgICAvL3JldHVybiAxNjA7XG4gICAgLy8gICAgIH1cbiAgICAvLyB9KTtcbiAgICAvLyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJoZWlnaHRcIiwge1xuICAgIC8vICAgICBnZXQ6IGZ1bmN0aW9uIGhlaWdodCgpIHtcbiAgICAvLyAgICAgICAgIHJldHVybiBzZWxmLm5hcnlMaW5rLnBhdGguZ2V0QkJveCgpLmhlaWdodDtcbiAgICAvLyAgICAgICAgIC8vcmV0dXJuIDE2MDtcbiAgICAvLyAgICAgfVxuICAgIC8vIH0pO1xufVxuXG5Db21wbGV4LnByb3RvdHlwZSA9IG5ldyBJbnRlcmFjdG9yKCk7XG5cbi8vIENvbXBsZXgucHJvdG90eXBlID0ge1xuLy8gICAgIGdldCB3aWR0aCgpIHtcbi8vICAgICAgICAgcmV0dXJuIHRoaXMubmFyeUxpbmsucGF0aC5nZXRCQm94KCkud2lkdGg7XG4vLyAgICAgfSxcbi8vICAgICBnZXQgaGVpZ2h0KCkge1xuLy8gICAgICAgICByZXR1cm4gdGhpcy5uYXJ5TGluay5wYXRoLmdldEJCb3goKS5oZWlnaHQ7XG4vLyAgICAgfSxcbi8vIH07XG5cbkNvbXBsZXgucHJvdG90eXBlLmluaXRMaW5rID0gZnVuY3Rpb24gKG5hcnlMaW5rKSB7XG4gICAgdGhpcy5uYXJ5TGluayA9IG5hcnlMaW5rO1xuICAgIG5hcnlMaW5rLnBhdGguc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwid2hpdGVcIik7XG4gICAgbmFyeUxpbmsucGF0aC5zZXRBdHRyaWJ1dGUoXCJzdHJva2UtbGluZWpvaW5cIiwgXCJyb3VuZFwiKTtcbiAgICBuYXJ5TGluay5wYXRoLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCA0KTtcbn07XG5cbkNvbXBsZXgucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gKG9yaWdpblBvaW50KSB7XG4gICAgY29uc3QgbWFwcGVkID0gdGhpcy5uYXJ5TGluay5tYXBwZWQ7Ly9nZXRNYXBwZWRDb29yZGluYXRlcygpO1xuICAgIGNvbnN0IG1jID0gbWFwcGVkLmxlbmd0aDtcbiAgICBsZXQgeFN1bSA9IDAsXG4gICAgICAgIHlTdW0gPSAwO1xuICAgIGZvciAobGV0IG0gPSAwOyBtIDwgbWM7IG0rKykge1xuICAgICAgICB4U3VtICs9IG1hcHBlZFttXVswXTtcbiAgICAgICAgeVN1bSArPSBtYXBwZWRbbV1bMV07XG4gICAgfVxuICAgIGxldCBjZW50ZXIgPSBbeFN1bSAvIG1jLCB5U3VtIC8gbWNdO1xuICAgIGlmIChvcmlnaW5Qb2ludCkge1xuICAgIC8vIGlmIChwYXJ0aWNpcGFudC50eXBlID09PSBcImNvbXBsZXhcIil7XG4gICAgLy8gICAgIHN0YXJ0UG9pbnQgPSBwYXJ0aWNpcGFudC5nZXRQb3NpdGlvbigpO1xuICAgICAgICBsZXQgbmFyeVBhdGggPSB0aGlzLm5hcnlMaW5rLmh1bGw7XG4gICAgICAgIGxldCBpUGF0aCA9IFtdO1xuICAgICAgICBmb3IgKGxldCBwIG9mIG5hcnlQYXRoKSB7XG4gICAgICAgICAgICBpUGF0aC5wdXNoKG5ldyBQb2ludDJEKHBbMF0sIHBbMV0pKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYTEgPSBuZXcgUG9pbnQyRChjZW50ZXJbMF0sIGNlbnRlclsxXSk7XG4gICAgICAgIGxldCBhMiA9IG5ldyBQb2ludDJEKG9yaWdpblBvaW50WzBdLCBvcmlnaW5Qb2ludFsxXSk7XG4gICAgICAgIGxldCBpbnRlcnNlY3QgPSBJbnRlcnNlY3Rpb24uaW50ZXJzZWN0TGluZVBvbHlnb24oYTEsIGEyLCBpUGF0aCk7XG4gICAgICAgIGlmIChpbnRlcnNlY3QucG9pbnRzWzBdKSB7XG4gICAgICAgICAgICByZXR1cm4gW2ludGVyc2VjdC5wb2ludHNbMF0ueCwgaW50ZXJzZWN0LnBvaW50c1swXS55XTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY2VudGVyO1xufTtcblxuQ29tcGxleC5wcm90b3R5cGUuc2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5lcnJvcihcImJhZCAtIGNhbGxlZCBzZXRQb3NpdGlvbiBvbiBcIiwgdGhpcyk7XG59O1xuXG5Db21wbGV4LnByb3RvdHlwZS5jaGFuZ2VQb3NpdGlvbiA9IGZ1bmN0aW9uIChkeCwgZHkpIHtcbiAgICBmb3IgKGxldCBwYXJ0aWNpcGFudCBvZiB0aGlzLm5hcnlMaW5rLnBhcnRpY2lwYW50cyl7XG4gICAgICAgIHBhcnRpY2lwYW50LmNoYW5nZVBvc2l0aW9uKGR4LCBkeSk7XG4gICAgfVxufTtcblxuQ29tcGxleC5wcm90b3R5cGUuZ2V0UmVzaWR1ZUNvb3JkaW5hdGVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdldFBvc2l0aW9uKCk7XG59O1xuXG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/complex.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Complex\", function() { return Complex; });\n/* harmony import */ var _interactor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./interactor */ \"./src/js/viz/interactor/interactor.js\");\n/* harmony import */ var point2d__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! point2d */ \"./node_modules/point2d/index.js\");\n/* harmony import */ var point2d__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(point2d__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var intersectionjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! intersectionjs */ \"./node_modules/intersectionjs/intersection.js\");\n/* harmony import */ var intersectionjs__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(intersectionjs__WEBPACK_IMPORTED_MODULE_2__);\n\n\n\n\nfunction Complex(id, app) {\n this.init(id, app);\n this.type = \"complex\";\n this.padding = 22;\n\n // const self = this;\n // // its bad if you end up with these getting called\n // Object.defineProperty(this, \"width\", {\n // get: function height() {\n // return self.naryLink.path.getBBox().width;\n // //return 160;\n // }\n // });\n // Object.defineProperty(this, \"height\", {\n // get: function height() {\n // return self.naryLink.path.getBBox().height;\n // //return 160;\n // }\n // });\n}\n\nComplex.prototype = new _interactor__WEBPACK_IMPORTED_MODULE_0__[\"Interactor\"]();\n\nComplex.prototype.initLink = function (naryLink) {\n this.naryLink = naryLink;\n this.naryLink.path.classList.add(\"complex-outline\");\n};\n\nComplex.prototype.setLinked = function () {\n\n this.naryLink.path2.classList.add(\"linked-complex\");\n};\n\n\nComplex.prototype.getPosition = function (originPoint) {\n const mapped = this.naryLink.mapped;//getMappedCoordinates();\n const mc = mapped.length;\n let xSum = 0,\n ySum = 0;\n for (let m = 0; m < mc; m++) {\n xSum += mapped[m][0];\n ySum += mapped[m][1];\n }\n let center = [xSum / mc, ySum / mc];\n if (originPoint) {\n // if (participant.type === \"complex\"){\n // startPoint = participant.getPosition();\n let naryPath = this.naryLink.hull;\n let iPath = [];\n for (let p of naryPath) {\n iPath.push(new point2d__WEBPACK_IMPORTED_MODULE_1__(p[0], p[1]));\n }\n let a1 = new point2d__WEBPACK_IMPORTED_MODULE_1__(center[0], center[1]);\n let a2 = new point2d__WEBPACK_IMPORTED_MODULE_1__(originPoint[0], originPoint[1]);\n let intersect = intersectionjs__WEBPACK_IMPORTED_MODULE_2__[\"intersectLinePolygon\"](a1, a2, iPath);\n if (intersect.points[0]) {\n return [intersect.points[0].x, intersect.points[0].y];\n }\n this.setLinked();\n }\n return center;\n};\n\nComplex.prototype.setPosition = function () {\n console.error(\"bad - called setPosition on \", this);\n};\n\nComplex.prototype.changePosition = function (dx, dy) {\n for (let participant of this.naryLink.participants){\n participant.changePosition(dx, dy);\n }\n};\n\nComplex.prototype.getResidueCoordinates = function () {\n return this.getPosition();\n};\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvY29tcGxleC5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2ludGVyYWN0b3IvY29tcGxleC5qcz8zOTQ4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SW50ZXJhY3Rvcn0gZnJvbSBcIi4vaW50ZXJhY3RvclwiO1xuaW1wb3J0ICogYXMgUG9pbnQyRCBmcm9tIFwicG9pbnQyZFwiO1xuaW1wb3J0ICogYXMgSW50ZXJzZWN0aW9uIGZyb20gXCJpbnRlcnNlY3Rpb25qc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gQ29tcGxleChpZCwgYXBwKSB7XG4gICAgdGhpcy5pbml0KGlkLCBhcHApO1xuICAgIHRoaXMudHlwZSA9IFwiY29tcGxleFwiO1xuICAgIHRoaXMucGFkZGluZyA9IDIyO1xuXG4gICAgLy8gY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgLy8gLy8gaXRzIGJhZCBpZiB5b3UgZW5kIHVwIHdpdGggdGhlc2UgZ2V0dGluZyBjYWxsZWRcbiAgICAvLyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJ3aWR0aFwiLCB7XG4gICAgLy8gICAgIGdldDogZnVuY3Rpb24gaGVpZ2h0KCkge1xuICAgIC8vICAgICAgICAgcmV0dXJuIHNlbGYubmFyeUxpbmsucGF0aC5nZXRCQm94KCkud2lkdGg7XG4gICAgLy8gICAgICAgICAvL3JldHVybiAxNjA7XG4gICAgLy8gICAgIH1cbiAgICAvLyB9KTtcbiAgICAvLyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJoZWlnaHRcIiwge1xuICAgIC8vICAgICBnZXQ6IGZ1bmN0aW9uIGhlaWdodCgpIHtcbiAgICAvLyAgICAgICAgIHJldHVybiBzZWxmLm5hcnlMaW5rLnBhdGguZ2V0QkJveCgpLmhlaWdodDtcbiAgICAvLyAgICAgICAgIC8vcmV0dXJuIDE2MDtcbiAgICAvLyAgICAgfVxuICAgIC8vIH0pO1xufVxuXG5Db21wbGV4LnByb3RvdHlwZSA9IG5ldyBJbnRlcmFjdG9yKCk7XG5cbkNvbXBsZXgucHJvdG90eXBlLmluaXRMaW5rID0gZnVuY3Rpb24gKG5hcnlMaW5rKSB7XG4gICAgdGhpcy5uYXJ5TGluayA9IG5hcnlMaW5rO1xuICAgIHRoaXMubmFyeUxpbmsucGF0aC5jbGFzc0xpc3QuYWRkKFwiY29tcGxleC1vdXRsaW5lXCIpO1xufTtcblxuQ29tcGxleC5wcm90b3R5cGUuc2V0TGlua2VkID0gZnVuY3Rpb24gKCkge1xuXG4gICAgdGhpcy5uYXJ5TGluay5wYXRoMi5jbGFzc0xpc3QuYWRkKFwibGlua2VkLWNvbXBsZXhcIik7XG59O1xuXG5cbkNvbXBsZXgucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gKG9yaWdpblBvaW50KSB7XG4gICAgY29uc3QgbWFwcGVkID0gdGhpcy5uYXJ5TGluay5tYXBwZWQ7Ly9nZXRNYXBwZWRDb29yZGluYXRlcygpO1xuICAgIGNvbnN0IG1jID0gbWFwcGVkLmxlbmd0aDtcbiAgICBsZXQgeFN1bSA9IDAsXG4gICAgICAgIHlTdW0gPSAwO1xuICAgIGZvciAobGV0IG0gPSAwOyBtIDwgbWM7IG0rKykge1xuICAgICAgICB4U3VtICs9IG1hcHBlZFttXVswXTtcbiAgICAgICAgeVN1bSArPSBtYXBwZWRbbV1bMV07XG4gICAgfVxuICAgIGxldCBjZW50ZXIgPSBbeFN1bSAvIG1jLCB5U3VtIC8gbWNdO1xuICAgIGlmIChvcmlnaW5Qb2ludCkge1xuICAgIC8vIGlmIChwYXJ0aWNpcGFudC50eXBlID09PSBcImNvbXBsZXhcIil7XG4gICAgLy8gICAgIHN0YXJ0UG9pbnQgPSBwYXJ0aWNpcGFudC5nZXRQb3NpdGlvbigpO1xuICAgICAgICBsZXQgbmFyeVBhdGggPSB0aGlzLm5hcnlMaW5rLmh1bGw7XG4gICAgICAgIGxldCBpUGF0aCA9IFtdO1xuICAgICAgICBmb3IgKGxldCBwIG9mIG5hcnlQYXRoKSB7XG4gICAgICAgICAgICBpUGF0aC5wdXNoKG5ldyBQb2ludDJEKHBbMF0sIHBbMV0pKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYTEgPSBuZXcgUG9pbnQyRChjZW50ZXJbMF0sIGNlbnRlclsxXSk7XG4gICAgICAgIGxldCBhMiA9IG5ldyBQb2ludDJEKG9yaWdpblBvaW50WzBdLCBvcmlnaW5Qb2ludFsxXSk7XG4gICAgICAgIGxldCBpbnRlcnNlY3QgPSBJbnRlcnNlY3Rpb24uaW50ZXJzZWN0TGluZVBvbHlnb24oYTEsIGEyLCBpUGF0aCk7XG4gICAgICAgIGlmIChpbnRlcnNlY3QucG9pbnRzWzBdKSB7XG4gICAgICAgICAgICByZXR1cm4gW2ludGVyc2VjdC5wb2ludHNbMF0ueCwgaW50ZXJzZWN0LnBvaW50c1swXS55XTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldExpbmtlZCgpO1xuICAgIH1cbiAgICByZXR1cm4gY2VudGVyO1xufTtcblxuQ29tcGxleC5wcm90b3R5cGUuc2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgY29uc29sZS5lcnJvcihcImJhZCAtIGNhbGxlZCBzZXRQb3NpdGlvbiBvbiBcIiwgdGhpcyk7XG59O1xuXG5Db21wbGV4LnByb3RvdHlwZS5jaGFuZ2VQb3NpdGlvbiA9IGZ1bmN0aW9uIChkeCwgZHkpIHtcbiAgICBmb3IgKGxldCBwYXJ0aWNpcGFudCBvZiB0aGlzLm5hcnlMaW5rLnBhcnRpY2lwYW50cyl7XG4gICAgICAgIHBhcnRpY2lwYW50LmNoYW5nZVBvc2l0aW9uKGR4LCBkeSk7XG4gICAgfVxufTtcblxuQ29tcGxleC5wcm90b3R5cGUuZ2V0UmVzaWR1ZUNvb3JkaW5hdGVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmdldFBvc2l0aW9uKCk7XG59O1xuXG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/complex.js\n"); /***/ }), @@ -1285,7 +1297,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Interactor\", function() { return Interactor; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"trig\", function() { return trig; });\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n\n\nfunction Interactor() {\n}\n\nInteractor.prototype = {\n get width() {\n // console.log(this.upperGroup.getBBox().width);\n return this.upperGroup.getBBox().width;\n },\n get height() {\n return 40;//this.upperGroup.getBBox().height;\n },\n};\n\nInteractor.prototype.init = function (id, app, json, name){\n this.id = id;\n this.app = app;\n this.json = json;\n this.name = name;\n\n //annotations indexed by annotation set name (\"MI FEATURES\", \"SUPERFAMILY\", etc)\n this.annotationSets = new Map();\n\n //links\n this.naryLinks = new Map();\n this.binaryLinks = new Map();\n this.sequenceLinks = new Map();\n};\n\nInteractor.prototype.initLabel = function (){\n\n this.labelSVG = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_0__[\"svgns\"], \"text\");\n this.labelSVG.setAttribute(\"text-anchor\", \"end\");\n this.labelSVG.setAttribute(\"fill\", \"black\");\n this.labelSVG.setAttribute(\"x\", \"0\");\n this.labelSVG.setAttribute(\"y\", \"10\");\n this.labelSVG.setAttribute(\"class\", \"xlv_text proteinLabel\");\n this.labelSVG.setAttribute(\"font-family\", \"Arial\");\n this.labelSVG.setAttribute(\"font-size\", \"16\");\n\n //choose label text\n if (this.name) {\n this.labelText = this.name;\n } else {\n this.labelText = this.id;\n }\n if (this.labelText.length > 25) {\n this.labelText = this.labelText.substr(0, 16) + \"...\";\n }\n\n this.labelText = this.name;\n this.labelTextNode = document.createTextNode(this.labelText);\n this.labelSVG.appendChild(this.labelTextNode);\n this.labelSVG.setAttribute(\"transform\",\n \"translate( -\" + this.getSymbolRadius() + \" \" + _config__WEBPACK_IMPORTED_MODULE_0__[\"LABEL_Y\"] + \")\");\n this.upperGroup.appendChild(this.labelSVG);\n};\n\nInteractor.prototype.initOutline = function (){\n this.outline.setAttribute(\"stroke\", \"black\");\n this.outline.setAttribute(\"stroke-width\", \"1\");\n this.outline.setAttribute(\"stroke-opacity\", \"1\");\n this.outline.setAttribute(\"fill-opacity\", \"1\");\n this.outline.setAttribute(\"fill\", \"#ffffff\");\n //append outline\n this.upperGroup.appendChild(this.outline);\n};\n\nInteractor.prototype.initListeners = function (){\n // events\n const self = this;\n // this.upperGroup.setAttribute('pointer-events','all');\n this.upperGroup.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.upperGroup.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.upperGroup.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.upperGroup.ontouchstart = function (evt) {\n // self.touchStart(evt);\n // };\n\n //~ this.upperGroup.ontouchmove = function(evt) {};\n //~ this.upperGroup.ontouchend = function(evt) {\n //~ self.ctrl.message(\"protein touch end\");\n //~ self.mouseOut(evt);\n //~ };\n //~ this.upperGroup.ontouchenter = function(evt) {\n //~ self.message(\"protein touch enter\");\n //~ self.touchStart(evt);\n //~ };\n //~ this.upperGroup.ontouchleave = function(evt) {\n //~ self.message(\"protein touch leave\");\n //~ self.mouseOut(evt);\n //~ };\n //~ this.upperGroup.ontouchcancel = function(evt) {\n //~ self.message(\"protein touch cancel\");\n //~ self.mouseOut(evt);\n //~ };\n};\n\nInteractor.prototype.addStoichiometryLabel = function (stoichiometry) {\n if (this.labelSVG) { //complexes don't have labels (yet?)\n // noinspection JSUndefinedPropertyAssignment\n this.labelSVG.childNodes[0].data = this.labelSVG.childNodes[0].data + \" [\" + stoichiometry + \"]\";\n }\n};\n\nInteractor.prototype.mouseDown = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt); //see MouseEvents.js\n this.app.d3cola.stop();\n this.app.dragElement = this;\n const p = this.app.getEventPoint(evt);\n this.app.dragStart = this.app.mouseToSVG(p.x, p.y);\n return false;\n};\n\n//// TODO: test on touch screen\n// Interactor.prototype.touchStart = function(evt) {\n// this.util.preventDefaultsAndStopPropagation(evt); //see MouseEvents.js\n// if (this.util.d3cola !== undefined) {\n// this.util.d3cola.stop();\n// }\n// this.util.dragElement = this;\n// //store start location\n// var p = this.util.getTouchEventPoint(evt);\n// this.util.dragStart = this.util.mouseToSVG(p.x, p.y);\n// return false;\n// };\n\nInteractor.prototype.mouseOver = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt);\n this.showHighlight(true);\n //~ this.util.setTooltip(this.id);\n return false;\n};\n\nInteractor.prototype.mouseOut = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt);\n this.showHighlight(false);\n this.app.hideTooltip();\n return false;\n};\n\nInteractor.prototype.getSymbolRadius = function () {\n return 15;\n};\n\n\nInteractor.prototype.showHighlight = function () {\n};\n\nInteractor.prototype.getPosition = function () {\n return [this.ix, this.iy]; // todo - type of return is kind of inconsistent\n};\n\nInteractor.prototype.setPosition = function (x, y) {\n this.px = this.ix;\n this.py = this.iy;\n this.ix = x;\n this.iy = y;\n this.upperGroup.setAttribute(\"transform\", \"translate(\" + this.ix + \" \" + this.iy + \")\");\n};\n\nInteractor.prototype.changePosition = function (x, y) {\n this.px = this.ix;\n this.py = this.iy;\n this.ix -= x;\n this.iy -= y;\n this.upperGroup.setAttribute(\"transform\", \"translate(\" + this.ix + \" \" + this.iy + \")\");\n // this.setAllLinkCoordinates(); // todo - look at calls\n};\n\nInteractor.prototype.getAggregateSelfLinkPath = function () {\n const intraR = this.getSymbolRadius() + 7;\n const sectorSize = 45;\n const arcStart = trig(intraR, 25 + sectorSize);\n const arcEnd = trig(intraR, -25 + sectorSize);\n const cp1 = trig(intraR, 40 + sectorSize);\n const cp2 = trig(intraR, -40 + sectorSize);\n return \"M 0,0 \" +\n \"Q \" + cp1.x + \",\" + -cp1.y + \" \" + arcStart.x + \",\" + -arcStart.y +\n \" A \" + intraR + \" \" + intraR + \" 0 0 1 \" + arcEnd.x + \",\" + -arcEnd.y +\n \" Q \" + cp2.x + \",\" + -cp2.y + \" 0,0\";\n};\n\nInteractor.prototype.checkLinks = function () {\n function checkAll(linkMap) {\n for (let link of linkMap.values()) {\n link.check();\n }\n }\n\n // checkAll(this.naryLinks); // hacked out to fix ordering of nLinks\n checkAll(this.binaryLinks);\n checkAll(this.sequenceLinks);\n if (this.selfLink) {\n this.selfLink.check();\n }\n};\n\n// update all lines (e.g after a move)\nInteractor.prototype.setAllLinkCoordinates = function () {\n for (let link of this.naryLinks.values()) {\n link.setLinkCoordinates();\n }\n for (let link of this.binaryLinks.values()) {\n link.setLinkCoordinates();\n }\n if (this.selfLink) {\n this.selfLink.setLinkCoordinates();\n }\n for (let link of this.sequenceLinks.values()) {\n link.setLinkCoordinates();\n }\n};\n\nfunction trig (radius, angleDegrees) {\n //x = rx + radius * cos(theta) and y = ry + radius * sin(theta)\n const radians = (angleDegrees / 360) * Math.PI * 2;\n return {\n x: (radius * Math.cos(radians)),\n y: (radius * Math.sin(radians))\n };\n}\n//\n// Interactor.prototype.setForm = function () {\n// };\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvaW50ZXJhY3Rvci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2ludGVyYWN0b3IvaW50ZXJhY3Rvci5qcz9lODA4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7TEFCRUxfWSwgc3ZnbnN9IGZyb20gXCIuLi8uLi9jb25maWdcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIEludGVyYWN0b3IoKSB7XG59XG5cbkludGVyYWN0b3IucHJvdG90eXBlID0ge1xuICAgIGdldCB3aWR0aCgpIHtcbiAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy51cHBlckdyb3VwLmdldEJCb3goKS53aWR0aCk7XG4gICAgICAgIHJldHVybiB0aGlzLnVwcGVyR3JvdXAuZ2V0QkJveCgpLndpZHRoO1xuICAgIH0sXG4gICAgZ2V0IGhlaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIDQwOy8vdGhpcy51cHBlckdyb3VwLmdldEJCb3goKS5oZWlnaHQ7XG4gICAgfSxcbn07XG5cbkludGVyYWN0b3IucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoaWQsIGFwcCwganNvbiwgbmFtZSl7XG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMuYXBwID0gYXBwO1xuICAgIHRoaXMuanNvbiA9IGpzb247XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcblxuICAgIC8vYW5ub3RhdGlvbnMgaW5kZXhlZCBieSBhbm5vdGF0aW9uIHNldCBuYW1lIChcIk1JIEZFQVRVUkVTXCIsIFwiU1VQRVJGQU1JTFlcIiwgZXRjKVxuICAgIHRoaXMuYW5ub3RhdGlvblNldHMgPSBuZXcgTWFwKCk7XG5cbiAgICAvL2xpbmtzXG4gICAgdGhpcy5uYXJ5TGlua3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5iaW5hcnlMaW5rcyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLnNlcXVlbmNlTGlua3MgPSBuZXcgTWFwKCk7XG59O1xuXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5pbml0TGFiZWwgPSBmdW5jdGlvbiAoKXtcblxuICAgIHRoaXMubGFiZWxTVkcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwidGV4dFwiKTtcbiAgICB0aGlzLmxhYmVsU1ZHLnNldEF0dHJpYnV0ZShcInRleHQtYW5jaG9yXCIsIFwiZW5kXCIpO1xuICAgIHRoaXMubGFiZWxTVkcuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcImJsYWNrXCIpO1xuICAgIHRoaXMubGFiZWxTVkcuc2V0QXR0cmlidXRlKFwieFwiLCBcIjBcIik7XG4gICAgdGhpcy5sYWJlbFNWRy5zZXRBdHRyaWJ1dGUoXCJ5XCIsIFwiMTBcIik7XG4gICAgdGhpcy5sYWJlbFNWRy5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBcInhsdl90ZXh0IHByb3RlaW5MYWJlbFwiKTtcbiAgICB0aGlzLmxhYmVsU1ZHLnNldEF0dHJpYnV0ZShcImZvbnQtZmFtaWx5XCIsIFwiQXJpYWxcIik7XG4gICAgdGhpcy5sYWJlbFNWRy5zZXRBdHRyaWJ1dGUoXCJmb250LXNpemVcIiwgXCIxNlwiKTtcblxuICAgIC8vY2hvb3NlIGxhYmVsIHRleHRcbiAgICBpZiAodGhpcy5uYW1lKSB7XG4gICAgICAgIHRoaXMubGFiZWxUZXh0ID0gdGhpcy5uYW1lO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubGFiZWxUZXh0ID0gdGhpcy5pZDtcbiAgICB9XG4gICAgaWYgKHRoaXMubGFiZWxUZXh0Lmxlbmd0aCA+IDI1KSB7XG4gICAgICAgIHRoaXMubGFiZWxUZXh0ID0gdGhpcy5sYWJlbFRleHQuc3Vic3RyKDAsIDE2KSArIFwiLi4uXCI7XG4gICAgfVxuXG4gICAgdGhpcy5sYWJlbFRleHQgPSB0aGlzLm5hbWU7XG4gICAgdGhpcy5sYWJlbFRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGhpcy5sYWJlbFRleHQpO1xuICAgIHRoaXMubGFiZWxTVkcuYXBwZW5kQ2hpbGQodGhpcy5sYWJlbFRleHROb2RlKTtcbiAgICB0aGlzLmxhYmVsU1ZHLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLFxuICAgICAgICBcInRyYW5zbGF0ZSggLVwiICsgdGhpcy5nZXRTeW1ib2xSYWRpdXMoKSArIFwiIFwiICsgTEFCRUxfWSArIFwiKVwiKTtcbiAgICB0aGlzLnVwcGVyR3JvdXAuYXBwZW5kQ2hpbGQodGhpcy5sYWJlbFNWRyk7XG59O1xuXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5pbml0T3V0bGluZSA9IGZ1bmN0aW9uICgpe1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgXCJibGFja1wiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIFwiMVwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLW9wYWNpdHlcIiwgXCIxXCIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJmaWxsLW9wYWNpdHlcIiwgXCIxXCIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwiI2ZmZmZmZlwiKTtcbiAgICAvL2FwcGVuZCBvdXRsaW5lXG4gICAgdGhpcy51cHBlckdyb3VwLmFwcGVuZENoaWxkKHRoaXMub3V0bGluZSk7XG59O1xuXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5pbml0TGlzdGVuZXJzID0gZnVuY3Rpb24gKCl7XG4gICAgLy8gZXZlbnRzXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgLy8gICAgdGhpcy51cHBlckdyb3VwLnNldEF0dHJpYnV0ZSgncG9pbnRlci1ldmVudHMnLCdhbGwnKTtcbiAgICB0aGlzLnVwcGVyR3JvdXAub25tb3VzZWRvd24gPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VEb3duKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLnVwcGVyR3JvdXAub25tb3VzZW92ZXIgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdmVyKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLnVwcGVyR3JvdXAub25tb3VzZW91dCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5tb3VzZU91dChldnQpO1xuICAgIH07XG4gICAgLy8gdGhpcy51cHBlckdyb3VwLm9udG91Y2hzdGFydCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAvLyAgICAgc2VsZi50b3VjaFN0YXJ0KGV2dCk7XG4gICAgLy8gfTtcblxuICAgIC8vfiB0aGlzLnVwcGVyR3JvdXAub250b3VjaG1vdmUgPSBmdW5jdGlvbihldnQpIHt9O1xuICAgIC8vfiB0aGlzLnVwcGVyR3JvdXAub250b3VjaGVuZCA9IGZ1bmN0aW9uKGV2dCkge1xuICAgIC8vfiBzZWxmLmN0cmwubWVzc2FnZShcInByb3RlaW4gdG91Y2ggZW5kXCIpO1xuICAgIC8vfiBzZWxmLm1vdXNlT3V0KGV2dCk7XG4gICAgLy9+IH07XG4gICAgLy9+IHRoaXMudXBwZXJHcm91cC5vbnRvdWNoZW50ZXIgPSBmdW5jdGlvbihldnQpIHtcbiAgICAvL34gc2VsZi5tZXNzYWdlKFwicHJvdGVpbiB0b3VjaCBlbnRlclwiKTtcbiAgICAvL34gc2VsZi50b3VjaFN0YXJ0KGV2dCk7XG4gICAgLy9+IH07XG4gICAgLy9+IHRoaXMudXBwZXJHcm91cC5vbnRvdWNobGVhdmUgPSBmdW5jdGlvbihldnQpIHtcbiAgICAvL34gc2VsZi5tZXNzYWdlKFwicHJvdGVpbiB0b3VjaCBsZWF2ZVwiKTtcbiAgICAvL34gc2VsZi5tb3VzZU91dChldnQpO1xuICAgIC8vfiB9O1xuICAgIC8vfiB0aGlzLnVwcGVyR3JvdXAub250b3VjaGNhbmNlbCA9IGZ1bmN0aW9uKGV2dCkge1xuICAgIC8vfiBzZWxmLm1lc3NhZ2UoXCJwcm90ZWluIHRvdWNoIGNhbmNlbFwiKTtcbiAgICAvL34gc2VsZi5tb3VzZU91dChldnQpO1xuICAgIC8vfiB9O1xufTtcblxuSW50ZXJhY3Rvci5wcm90b3R5cGUuYWRkU3RvaWNoaW9tZXRyeUxhYmVsID0gZnVuY3Rpb24gKHN0b2ljaGlvbWV0cnkpIHtcbiAgICBpZiAodGhpcy5sYWJlbFNWRykgeyAvL2NvbXBsZXhlcyBkb24ndCBoYXZlIGxhYmVscyAoeWV0PylcbiAgICAgICAgLy8gbm9pbnNwZWN0aW9uIEpTVW5kZWZpbmVkUHJvcGVydHlBc3NpZ25tZW50XG4gICAgICAgIHRoaXMubGFiZWxTVkcuY2hpbGROb2Rlc1swXS5kYXRhID0gdGhpcy5sYWJlbFNWRy5jaGlsZE5vZGVzWzBdLmRhdGEgKyBcIiBbXCIgKyBzdG9pY2hpb21ldHJ5ICsgXCJdXCI7XG4gICAgfVxufTtcblxuSW50ZXJhY3Rvci5wcm90b3R5cGUubW91c2VEb3duID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIHRoaXMuYXBwLnByZXZlbnREZWZhdWx0c0FuZFN0b3BQcm9wYWdhdGlvbihldnQpOyAvL3NlZSBNb3VzZUV2ZW50cy5qc1xuICAgIHRoaXMuYXBwLmQzY29sYS5zdG9wKCk7XG4gICAgdGhpcy5hcHAuZHJhZ0VsZW1lbnQgPSB0aGlzO1xuICAgIGNvbnN0IHAgPSB0aGlzLmFwcC5nZXRFdmVudFBvaW50KGV2dCk7XG4gICAgdGhpcy5hcHAuZHJhZ1N0YXJ0ID0gdGhpcy5hcHAubW91c2VUb1NWRyhwLngsIHAueSk7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuLy8vLyBUT0RPOiB0ZXN0IG9uIHRvdWNoIHNjcmVlblxuLy8gSW50ZXJhY3Rvci5wcm90b3R5cGUudG91Y2hTdGFydCA9IGZ1bmN0aW9uKGV2dCkge1xuLy8gICAgIHRoaXMudXRpbC5wcmV2ZW50RGVmYXVsdHNBbmRTdG9wUHJvcGFnYXRpb24oZXZ0KTsgLy9zZWUgTW91c2VFdmVudHMuanNcbi8vICAgICBpZiAodGhpcy51dGlsLmQzY29sYSAhPT0gdW5kZWZpbmVkKSB7XG4vLyAgICAgICAgIHRoaXMudXRpbC5kM2NvbGEuc3RvcCgpO1xuLy8gICAgIH1cbi8vICAgICB0aGlzLnV0aWwuZHJhZ0VsZW1lbnQgPSB0aGlzO1xuLy8gICAgIC8vc3RvcmUgc3RhcnQgbG9jYXRpb25cbi8vICAgICB2YXIgcCA9IHRoaXMudXRpbC5nZXRUb3VjaEV2ZW50UG9pbnQoZXZ0KTtcbi8vICAgICB0aGlzLnV0aWwuZHJhZ1N0YXJ0ID0gdGhpcy51dGlsLm1vdXNlVG9TVkcocC54LCBwLnkpO1xuLy8gICAgIHJldHVybiBmYWxzZTtcbi8vIH07XG5cbkludGVyYWN0b3IucHJvdG90eXBlLm1vdXNlT3ZlciA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICB0aGlzLmFwcC5wcmV2ZW50RGVmYXVsdHNBbmRTdG9wUHJvcGFnYXRpb24oZXZ0KTtcbiAgICB0aGlzLnNob3dIaWdobGlnaHQodHJ1ZSk7XG4gICAgLy9+IHRoaXMudXRpbC5zZXRUb29sdGlwKHRoaXMuaWQpO1xuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbkludGVyYWN0b3IucHJvdG90eXBlLm1vdXNlT3V0ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIHRoaXMuYXBwLnByZXZlbnREZWZhdWx0c0FuZFN0b3BQcm9wYWdhdGlvbihldnQpO1xuICAgIHRoaXMuc2hvd0hpZ2hsaWdodChmYWxzZSk7XG4gICAgdGhpcy5hcHAuaGlkZVRvb2x0aXAoKTtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5nZXRTeW1ib2xSYWRpdXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIDE1O1xufTtcblxuXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5zaG93SGlnaGxpZ2h0ID0gZnVuY3Rpb24gKCkge1xufTtcblxuSW50ZXJhY3Rvci5wcm90b3R5cGUuZ2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFt0aGlzLml4LCB0aGlzLml5XTsgLy8gdG9kbyAtIHR5cGUgb2YgcmV0dXJuIGlzIGtpbmQgb2YgaW5jb25zaXN0ZW50XG59O1xuXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5zZXRQb3NpdGlvbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgdGhpcy5weCA9IHRoaXMuaXg7XG4gICAgdGhpcy5weSA9IHRoaXMuaXk7XG4gICAgdGhpcy5peCA9IHg7XG4gICAgdGhpcy5peSA9IHk7XG4gICAgdGhpcy51cHBlckdyb3VwLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIiArIHRoaXMuaXggKyBcIiBcIiArIHRoaXMuaXkgKyBcIilcIik7XG59O1xuXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5jaGFuZ2VQb3NpdGlvbiA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgdGhpcy5weCA9IHRoaXMuaXg7XG4gICAgdGhpcy5weSA9IHRoaXMuaXk7XG4gICAgdGhpcy5peCAtPSB4O1xuICAgIHRoaXMuaXkgLT0geTtcbiAgICB0aGlzLnVwcGVyR3JvdXAuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgdGhpcy5peCArIFwiIFwiICsgdGhpcy5peSArIFwiKVwiKTtcbiAgICAvLyB0aGlzLnNldEFsbExpbmtDb29yZGluYXRlcygpOyAvLyB0b2RvIC0gbG9vayBhdCBjYWxsc1xufTtcblxuSW50ZXJhY3Rvci5wcm90b3R5cGUuZ2V0QWdncmVnYXRlU2VsZkxpbmtQYXRoID0gZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGludHJhUiA9IHRoaXMuZ2V0U3ltYm9sUmFkaXVzKCkgKyA3O1xuICAgIGNvbnN0IHNlY3RvclNpemUgPSA0NTtcbiAgICBjb25zdCBhcmNTdGFydCA9IHRyaWcoaW50cmFSLCAyNSArIHNlY3RvclNpemUpO1xuICAgIGNvbnN0IGFyY0VuZCA9IHRyaWcoaW50cmFSLCAtMjUgKyBzZWN0b3JTaXplKTtcbiAgICBjb25zdCBjcDEgPSB0cmlnKGludHJhUiwgNDAgKyBzZWN0b3JTaXplKTtcbiAgICBjb25zdCBjcDIgPSB0cmlnKGludHJhUiwgLTQwICsgc2VjdG9yU2l6ZSk7XG4gICAgcmV0dXJuIFwiTSAwLDAgXCIgK1xuICAgICAgICBcIlEgXCIgKyBjcDEueCArIFwiLFwiICsgLWNwMS55ICsgXCIgXCIgKyBhcmNTdGFydC54ICsgXCIsXCIgKyAtYXJjU3RhcnQueSArXG4gICAgICAgIFwiIEEgXCIgKyBpbnRyYVIgKyBcIiBcIiArIGludHJhUiArIFwiIDAgMCAxIFwiICsgYXJjRW5kLnggKyBcIixcIiArIC1hcmNFbmQueSArXG4gICAgICAgIFwiIFEgXCIgKyBjcDIueCArIFwiLFwiICsgLWNwMi55ICsgXCIgMCwwXCI7XG59O1xuXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5jaGVja0xpbmtzID0gZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIGNoZWNrQWxsKGxpbmtNYXApIHtcbiAgICAgICAgZm9yIChsZXQgbGluayBvZiBsaW5rTWFwLnZhbHVlcygpKSB7XG4gICAgICAgICAgICBsaW5rLmNoZWNrKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjaGVja0FsbCh0aGlzLm5hcnlMaW5rcyk7IC8vIGhhY2tlZCBvdXQgdG8gZml4IG9yZGVyaW5nIG9mIG5MaW5rc1xuICAgIGNoZWNrQWxsKHRoaXMuYmluYXJ5TGlua3MpO1xuICAgIGNoZWNrQWxsKHRoaXMuc2VxdWVuY2VMaW5rcyk7XG4gICAgaWYgKHRoaXMuc2VsZkxpbmspIHtcbiAgICAgICAgdGhpcy5zZWxmTGluay5jaGVjaygpO1xuICAgIH1cbn07XG5cbi8vIHVwZGF0ZSBhbGwgbGluZXMgKGUuZyBhZnRlciBhIG1vdmUpXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgZm9yIChsZXQgbGluayBvZiB0aGlzLm5hcnlMaW5rcy52YWx1ZXMoKSkge1xuICAgICAgICBsaW5rLnNldExpbmtDb29yZGluYXRlcygpO1xuICAgIH1cbiAgICBmb3IgKGxldCBsaW5rIG9mIHRoaXMuYmluYXJ5TGlua3MudmFsdWVzKCkpIHtcbiAgICAgICAgbGluay5zZXRMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2VsZkxpbmspIHtcbiAgICAgICAgdGhpcy5zZWxmTGluay5zZXRMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICB9XG4gICAgZm9yIChsZXQgbGluayBvZiB0aGlzLnNlcXVlbmNlTGlua3MudmFsdWVzKCkpIHtcbiAgICAgICAgICAgIGxpbmsuc2V0TGlua0Nvb3JkaW5hdGVzKCk7XG4gICAgfVxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHRyaWcgKHJhZGl1cywgYW5nbGVEZWdyZWVzKSB7XG4gICAgLy94ID0gcnggKyByYWRpdXMgKiBjb3ModGhldGEpIGFuZCB5ID0gcnkgKyByYWRpdXMgKiBzaW4odGhldGEpXG4gICAgY29uc3QgcmFkaWFucyA9IChhbmdsZURlZ3JlZXMgLyAzNjApICogTWF0aC5QSSAqIDI7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeDogKHJhZGl1cyAqIE1hdGguY29zKHJhZGlhbnMpKSxcbiAgICAgICAgeTogKHJhZGl1cyAqIE1hdGguc2luKHJhZGlhbnMpKVxuICAgIH07XG59XG4vL1xuLy8gSW50ZXJhY3Rvci5wcm90b3R5cGUuc2V0Rm9ybSA9IGZ1bmN0aW9uICgpIHtcbi8vIH07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/interactor.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Interactor\", function() { return Interactor; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"trig\", function() { return trig; });\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n\n\nfunction Interactor() {\n}\n\nInteractor.prototype = {\n get width() {\n // console.log(this.upperGroup.getBBox().width);\n return this.upperGroup.getBBox().width;\n },\n get height() {\n return 40;//this.upperGroup.getBBox().height;\n },\n};\n\nInteractor.prototype.init = function (id, app, json, name){\n this.id = id;\n this.app = app;\n this.json = json;\n this.name = name;\n\n //todo - think 'type' should be a property here (except for complex, can just return json.type.name)\n\n //annotations indexed by annotation set name (\"MIFEATURES\", \"SUPERFAMILY\", etc)\n this.annotationSets = new Map();\n //links\n this.naryLinks = new Map();\n this.binaryLinks = new Map();\n this.sequenceLinks = new Map();\n};\n\nInteractor.prototype.initLabel = function (){\n this.labelSVG = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_0__[\"svgns\"], \"text\");\n this.labelSVG.setAttribute(\"x\", \"0\"); // css?\n this.labelSVG.setAttribute(\"y\", \"10\");\n this.labelSVG.classList.add(\"label\");\n //choose label text\n if (this.name) {\n this.labelText = this.name;\n } else {\n this.labelText = this.id;\n }\n if (this.labelText.length > 25) {\n this.labelText = this.labelText.substr(0, 16) + \"...\";\n }\n this.labelText = this.name;\n this.labelTextNode = document.createTextNode(this.labelText);\n this.labelSVG.appendChild(this.labelTextNode);\n this.labelSVG.setAttribute(\"transform\",\n \"translate( -\" + this.getSymbolRadius() + \" \" + _config__WEBPACK_IMPORTED_MODULE_0__[\"LABEL_Y\"] + \")\");\n this.upperGroup.appendChild(this.labelSVG);\n};\n\nInteractor.prototype.initOutline = function (){\n this.outline.classList.add(\"outline\");\n this.upperGroup.appendChild(this.outline);\n};\n\nInteractor.prototype.initListeners = function (){\n // events\n const self = this;\n // this.upperGroup.setAttribute('pointer-events','all');\n this.upperGroup.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.upperGroup.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.upperGroup.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.upperGroup.ontouchstart = function (evt) {\n // self.touchStart(evt);\n // };\n\n //~ this.upperGroup.ontouchmove = function(evt) {};\n //~ this.upperGroup.ontouchend = function(evt) {\n //~ self.ctrl.message(\"protein touch end\");\n //~ self.mouseOut(evt);\n //~ };\n //~ this.upperGroup.ontouchenter = function(evt) {\n //~ self.message(\"protein touch enter\");\n //~ self.touchStart(evt);\n //~ };\n //~ this.upperGroup.ontouchleave = function(evt) {\n //~ self.message(\"protein touch leave\");\n //~ self.mouseOut(evt);\n //~ };\n //~ this.upperGroup.ontouchcancel = function(evt) {\n //~ self.message(\"protein touch cancel\");\n //~ self.mouseOut(evt);\n //~ };\n};\n\nInteractor.prototype.addStoichiometryLabel = function (stoichiometry) {\n if (this.labelSVG) { //complexes don't have labels (yet?)\n // noinspection JSUndefinedPropertyAssignment\n this.labelSVG.childNodes[0].data = this.labelSVG.childNodes[0].data + \" [\" + stoichiometry + \"]\";\n }\n};\n\nInteractor.prototype.mouseDown = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt); //see MouseEvents.js\n this.app.d3cola.stop();\n this.app.dragElement = this;\n const p = this.app.getEventPoint(evt);\n this.app.dragStart = this.app.mouseToSVG(p.x, p.y);\n return false;\n};\n\n//// TODO: test on touch screen\n// Interactor.prototype.touchStart = function(evt) {\n// this.util.preventDefaultsAndStopPropagation(evt); //see MouseEvents.js\n// if (this.util.d3cola !== undefined) {\n// this.util.d3cola.stop();\n// }\n// this.util.dragElement = this;\n// //store start location\n// var p = this.util.getTouchEventPoint(evt);\n// this.util.dragStart = this.util.mouseToSVG(p.x, p.y);\n// return false;\n// };\n\nInteractor.prototype.mouseOver = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt);\n this.showHighlight(true);\n //~ this.util.setTooltip(this.id);\n return false;\n};\n\nInteractor.prototype.mouseOut = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt);\n this.showHighlight(false);\n this.app.hideTooltip();\n return false;\n};\n\nInteractor.prototype.getSymbolRadius = function () {\n return 15;\n};\n\n\nInteractor.prototype.showHighlight = function () {\n};\n\nInteractor.prototype.getPosition = function () {\n return [this.ix, this.iy]; // todo - type of return is kind of inconsistent\n};\n\nInteractor.prototype.setPosition = function (x, y) {\n this.px = this.ix;\n this.py = this.iy;\n this.ix = x;\n this.iy = y;\n this.upperGroup.setAttribute(\"transform\", \"translate(\" + this.ix + \" \" + this.iy + \")\");\n};\n\nInteractor.prototype.changePosition = function (x, y) {\n this.px = this.ix;\n this.py = this.iy;\n this.ix -= x;\n this.iy -= y;\n this.upperGroup.setAttribute(\"transform\", \"translate(\" + this.ix + \" \" + this.iy + \")\");\n // this.setAllLinkCoordinates(); // todo - look at calls\n};\n\nInteractor.prototype.getAggregateSelfLinkPath = function () {\n const intraR = this.getSymbolRadius() + 7;\n const sectorSize = 45;\n const arcStart = trig(intraR, 25 + sectorSize);\n const arcEnd = trig(intraR, -25 + sectorSize);\n const cp1 = trig(intraR, 40 + sectorSize);\n const cp2 = trig(intraR, -40 + sectorSize);\n return \"M 0,0 \" +\n \"Q \" + cp1.x + \",\" + -cp1.y + \" \" + arcStart.x + \",\" + -arcStart.y +\n \" A \" + intraR + \" \" + intraR + \" 0 0 1 \" + arcEnd.x + \",\" + -arcEnd.y +\n \" Q \" + cp2.x + \",\" + -cp2.y + \" 0,0\";\n};\n\nInteractor.prototype.checkLinks = function () {\n function checkAll(linkMap) {\n for (let link of linkMap.values()) {\n link.check();\n }\n }\n\n // checkAll(this.naryLinks); // hacked out to fix ordering of nLinks\n checkAll(this.binaryLinks);\n checkAll(this.sequenceLinks);\n if (this.selfLink) {\n this.selfLink.check();\n }\n};\n\n// update all lines (e.g after a move)\nInteractor.prototype.setAllLinkCoordinates = function () {\n for (let link of this.naryLinks.values()) {\n link.setLinkCoordinates();\n }\n for (let link of this.binaryLinks.values()) {\n link.setLinkCoordinates();\n }\n if (this.selfLink) {\n this.selfLink.setLinkCoordinates();\n }\n for (let link of this.sequenceLinks.values()) {\n link.setLinkCoordinates();\n }\n};\n\nfunction trig (radius, angleDegrees) {\n //x = rx + radius * cos(theta) and y = ry + radius * sin(theta)\n const radians = (angleDegrees / 360) * Math.PI * 2;\n return {\n x: (radius * Math.cos(radians)),\n y: (radius * Math.sin(radians))\n };\n}\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvaW50ZXJhY3Rvci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2ludGVyYWN0b3IvaW50ZXJhY3Rvci5qcz9lODA4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7TEFCRUxfWSwgc3ZnbnN9IGZyb20gXCIuLi8uLi9jb25maWdcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIEludGVyYWN0b3IoKSB7XG59XG5cbkludGVyYWN0b3IucHJvdG90eXBlID0ge1xuICAgIGdldCB3aWR0aCgpIHtcbiAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy51cHBlckdyb3VwLmdldEJCb3goKS53aWR0aCk7XG4gICAgICAgIHJldHVybiB0aGlzLnVwcGVyR3JvdXAuZ2V0QkJveCgpLndpZHRoO1xuICAgIH0sXG4gICAgZ2V0IGhlaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIDQwOy8vdGhpcy51cHBlckdyb3VwLmdldEJCb3goKS5oZWlnaHQ7XG4gICAgfSxcbn07XG5cbkludGVyYWN0b3IucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbiAoaWQsIGFwcCwganNvbiwgbmFtZSl7XG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMuYXBwID0gYXBwO1xuICAgIHRoaXMuanNvbiA9IGpzb247XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcblxuICAgIC8vdG9kbyAtIHRoaW5rICd0eXBlJyBzaG91bGQgYmUgIGEgcHJvcGVydHkgaGVyZSAoZXhjZXB0IGZvciBjb21wbGV4LCBjYW4ganVzdCByZXR1cm4ganNvbi50eXBlLm5hbWUpXG5cbiAgICAvL2Fubm90YXRpb25zIGluZGV4ZWQgYnkgYW5ub3RhdGlvbiBzZXQgbmFtZSAoXCJNSUZFQVRVUkVTXCIsIFwiU1VQRVJGQU1JTFlcIiwgZXRjKVxuICAgIHRoaXMuYW5ub3RhdGlvblNldHMgPSBuZXcgTWFwKCk7XG4gICAgLy9saW5rc1xuICAgIHRoaXMubmFyeUxpbmtzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuYmluYXJ5TGlua3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5zZXF1ZW5jZUxpbmtzID0gbmV3IE1hcCgpO1xufTtcblxuSW50ZXJhY3Rvci5wcm90b3R5cGUuaW5pdExhYmVsID0gZnVuY3Rpb24gKCl7XG4gICAgdGhpcy5sYWJlbFNWRyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJ0ZXh0XCIpO1xuICAgIHRoaXMubGFiZWxTVkcuc2V0QXR0cmlidXRlKFwieFwiLCBcIjBcIik7IC8vIGNzcz9cbiAgICB0aGlzLmxhYmVsU1ZHLnNldEF0dHJpYnV0ZShcInlcIiwgXCIxMFwiKTtcbiAgICB0aGlzLmxhYmVsU1ZHLmNsYXNzTGlzdC5hZGQoXCJsYWJlbFwiKTtcbiAgICAvL2Nob29zZSBsYWJlbCB0ZXh0XG4gICAgaWYgKHRoaXMubmFtZSkge1xuICAgICAgICB0aGlzLmxhYmVsVGV4dCA9IHRoaXMubmFtZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmxhYmVsVGV4dCA9IHRoaXMuaWQ7XG4gICAgfVxuICAgIGlmICh0aGlzLmxhYmVsVGV4dC5sZW5ndGggPiAyNSkge1xuICAgICAgICB0aGlzLmxhYmVsVGV4dCA9IHRoaXMubGFiZWxUZXh0LnN1YnN0cigwLCAxNikgKyBcIi4uLlwiO1xuICAgIH1cbiAgICB0aGlzLmxhYmVsVGV4dCA9IHRoaXMubmFtZTtcbiAgICB0aGlzLmxhYmVsVGV4dE5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0aGlzLmxhYmVsVGV4dCk7XG4gICAgdGhpcy5sYWJlbFNWRy5hcHBlbmRDaGlsZCh0aGlzLmxhYmVsVGV4dE5vZGUpO1xuICAgIHRoaXMubGFiZWxTVkcuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsXG4gICAgICAgIFwidHJhbnNsYXRlKCAtXCIgKyB0aGlzLmdldFN5bWJvbFJhZGl1cygpICsgXCIgXCIgKyBMQUJFTF9ZICsgXCIpXCIpO1xuICAgIHRoaXMudXBwZXJHcm91cC5hcHBlbmRDaGlsZCh0aGlzLmxhYmVsU1ZHKTtcbn07XG5cbkludGVyYWN0b3IucHJvdG90eXBlLmluaXRPdXRsaW5lID0gZnVuY3Rpb24gKCl7XG4gICAgdGhpcy5vdXRsaW5lLmNsYXNzTGlzdC5hZGQoXCJvdXRsaW5lXCIpO1xuICAgIHRoaXMudXBwZXJHcm91cC5hcHBlbmRDaGlsZCh0aGlzLm91dGxpbmUpO1xufTtcblxuSW50ZXJhY3Rvci5wcm90b3R5cGUuaW5pdExpc3RlbmVycyA9IGZ1bmN0aW9uICgpe1xuICAgIC8vIGV2ZW50c1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIC8vICAgIHRoaXMudXBwZXJHcm91cC5zZXRBdHRyaWJ1dGUoJ3BvaW50ZXItZXZlbnRzJywnYWxsJyk7XG4gICAgdGhpcy51cHBlckdyb3VwLm9ubW91c2Vkb3duID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlRG93bihldnQpO1xuICAgIH07XG4gICAgdGhpcy51cHBlckdyb3VwLm9ubW91c2VvdmVyID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlT3ZlcihldnQpO1xuICAgIH07XG4gICAgdGhpcy51cHBlckdyb3VwLm9ubW91c2VvdXQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdXQoZXZ0KTtcbiAgICB9O1xuICAgIC8vIHRoaXMudXBwZXJHcm91cC5vbnRvdWNoc3RhcnQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgLy8gICAgIHNlbGYudG91Y2hTdGFydChldnQpO1xuICAgIC8vIH07XG5cbiAgICAvL34gdGhpcy51cHBlckdyb3VwLm9udG91Y2htb3ZlID0gZnVuY3Rpb24oZXZ0KSB7fTtcbiAgICAvL34gdGhpcy51cHBlckdyb3VwLm9udG91Y2hlbmQgPSBmdW5jdGlvbihldnQpIHtcbiAgICAvL34gc2VsZi5jdHJsLm1lc3NhZ2UoXCJwcm90ZWluIHRvdWNoIGVuZFwiKTtcbiAgICAvL34gc2VsZi5tb3VzZU91dChldnQpO1xuICAgIC8vfiB9O1xuICAgIC8vfiB0aGlzLnVwcGVyR3JvdXAub250b3VjaGVudGVyID0gZnVuY3Rpb24oZXZ0KSB7XG4gICAgLy9+IHNlbGYubWVzc2FnZShcInByb3RlaW4gdG91Y2ggZW50ZXJcIik7XG4gICAgLy9+IHNlbGYudG91Y2hTdGFydChldnQpO1xuICAgIC8vfiB9O1xuICAgIC8vfiB0aGlzLnVwcGVyR3JvdXAub250b3VjaGxlYXZlID0gZnVuY3Rpb24oZXZ0KSB7XG4gICAgLy9+IHNlbGYubWVzc2FnZShcInByb3RlaW4gdG91Y2ggbGVhdmVcIik7XG4gICAgLy9+IHNlbGYubW91c2VPdXQoZXZ0KTtcbiAgICAvL34gfTtcbiAgICAvL34gdGhpcy51cHBlckdyb3VwLm9udG91Y2hjYW5jZWwgPSBmdW5jdGlvbihldnQpIHtcbiAgICAvL34gc2VsZi5tZXNzYWdlKFwicHJvdGVpbiB0b3VjaCBjYW5jZWxcIik7XG4gICAgLy9+IHNlbGYubW91c2VPdXQoZXZ0KTtcbiAgICAvL34gfTtcbn07XG5cbkludGVyYWN0b3IucHJvdG90eXBlLmFkZFN0b2ljaGlvbWV0cnlMYWJlbCA9IGZ1bmN0aW9uIChzdG9pY2hpb21ldHJ5KSB7XG4gICAgaWYgKHRoaXMubGFiZWxTVkcpIHsgLy9jb21wbGV4ZXMgZG9uJ3QgaGF2ZSBsYWJlbHMgKHlldD8pXG4gICAgICAgIC8vIG5vaW5zcGVjdGlvbiBKU1VuZGVmaW5lZFByb3BlcnR5QXNzaWdubWVudFxuICAgICAgICB0aGlzLmxhYmVsU1ZHLmNoaWxkTm9kZXNbMF0uZGF0YSA9IHRoaXMubGFiZWxTVkcuY2hpbGROb2Rlc1swXS5kYXRhICsgXCIgW1wiICsgc3RvaWNoaW9tZXRyeSArIFwiXVwiO1xuICAgIH1cbn07XG5cbkludGVyYWN0b3IucHJvdG90eXBlLm1vdXNlRG93biA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICB0aGlzLmFwcC5wcmV2ZW50RGVmYXVsdHNBbmRTdG9wUHJvcGFnYXRpb24oZXZ0KTsgLy9zZWUgTW91c2VFdmVudHMuanNcbiAgICB0aGlzLmFwcC5kM2NvbGEuc3RvcCgpO1xuICAgIHRoaXMuYXBwLmRyYWdFbGVtZW50ID0gdGhpcztcbiAgICBjb25zdCBwID0gdGhpcy5hcHAuZ2V0RXZlbnRQb2ludChldnQpO1xuICAgIHRoaXMuYXBwLmRyYWdTdGFydCA9IHRoaXMuYXBwLm1vdXNlVG9TVkcocC54LCBwLnkpO1xuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbi8vLy8gVE9ETzogdGVzdCBvbiB0b3VjaCBzY3JlZW5cbi8vIEludGVyYWN0b3IucHJvdG90eXBlLnRvdWNoU3RhcnQgPSBmdW5jdGlvbihldnQpIHtcbi8vICAgICB0aGlzLnV0aWwucHJldmVudERlZmF1bHRzQW5kU3RvcFByb3BhZ2F0aW9uKGV2dCk7IC8vc2VlIE1vdXNlRXZlbnRzLmpzXG4vLyAgICAgaWYgKHRoaXMudXRpbC5kM2NvbGEgIT09IHVuZGVmaW5lZCkge1xuLy8gICAgICAgICB0aGlzLnV0aWwuZDNjb2xhLnN0b3AoKTtcbi8vICAgICB9XG4vLyAgICAgdGhpcy51dGlsLmRyYWdFbGVtZW50ID0gdGhpcztcbi8vICAgICAvL3N0b3JlIHN0YXJ0IGxvY2F0aW9uXG4vLyAgICAgdmFyIHAgPSB0aGlzLnV0aWwuZ2V0VG91Y2hFdmVudFBvaW50KGV2dCk7XG4vLyAgICAgdGhpcy51dGlsLmRyYWdTdGFydCA9IHRoaXMudXRpbC5tb3VzZVRvU1ZHKHAueCwgcC55KTtcbi8vICAgICByZXR1cm4gZmFsc2U7XG4vLyB9O1xuXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5tb3VzZU92ZXIgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgdGhpcy5hcHAucHJldmVudERlZmF1bHRzQW5kU3RvcFByb3BhZ2F0aW9uKGV2dCk7XG4gICAgdGhpcy5zaG93SGlnaGxpZ2h0KHRydWUpO1xuICAgIC8vfiB0aGlzLnV0aWwuc2V0VG9vbHRpcCh0aGlzLmlkKTtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5JbnRlcmFjdG9yLnByb3RvdHlwZS5tb3VzZU91dCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICB0aGlzLmFwcC5wcmV2ZW50RGVmYXVsdHNBbmRTdG9wUHJvcGFnYXRpb24oZXZ0KTtcbiAgICB0aGlzLnNob3dIaWdobGlnaHQoZmFsc2UpO1xuICAgIHRoaXMuYXBwLmhpZGVUb29sdGlwKCk7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuSW50ZXJhY3Rvci5wcm90b3R5cGUuZ2V0U3ltYm9sUmFkaXVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAxNTtcbn07XG5cblxuSW50ZXJhY3Rvci5wcm90b3R5cGUuc2hvd0hpZ2hsaWdodCA9IGZ1bmN0aW9uICgpIHtcbn07XG5cbkludGVyYWN0b3IucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBbdGhpcy5peCwgdGhpcy5peV07IC8vIHRvZG8gLSB0eXBlIG9mIHJldHVybiBpcyBraW5kIG9mIGluY29uc2lzdGVudFxufTtcblxuSW50ZXJhY3Rvci5wcm90b3R5cGUuc2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIHRoaXMucHggPSB0aGlzLml4O1xuICAgIHRoaXMucHkgPSB0aGlzLml5O1xuICAgIHRoaXMuaXggPSB4O1xuICAgIHRoaXMuaXkgPSB5O1xuICAgIHRoaXMudXBwZXJHcm91cC5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyB0aGlzLml4ICsgXCIgXCIgKyB0aGlzLml5ICsgXCIpXCIpO1xufTtcblxuSW50ZXJhY3Rvci5wcm90b3R5cGUuY2hhbmdlUG9zaXRpb24gPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgIHRoaXMucHggPSB0aGlzLml4O1xuICAgIHRoaXMucHkgPSB0aGlzLml5O1xuICAgIHRoaXMuaXggLT0geDtcbiAgICB0aGlzLml5IC09IHk7XG4gICAgdGhpcy51cHBlckdyb3VwLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIiArIHRoaXMuaXggKyBcIiBcIiArIHRoaXMuaXkgKyBcIilcIik7XG4gICAgLy8gdGhpcy5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTsgLy8gdG9kbyAtIGxvb2sgYXQgY2FsbHNcbn07XG5cbkludGVyYWN0b3IucHJvdG90eXBlLmdldEFnZ3JlZ2F0ZVNlbGZMaW5rUGF0aCA9IGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBpbnRyYVIgPSB0aGlzLmdldFN5bWJvbFJhZGl1cygpICsgNztcbiAgICBjb25zdCBzZWN0b3JTaXplID0gNDU7XG4gICAgY29uc3QgYXJjU3RhcnQgPSB0cmlnKGludHJhUiwgMjUgKyBzZWN0b3JTaXplKTtcbiAgICBjb25zdCBhcmNFbmQgPSB0cmlnKGludHJhUiwgLTI1ICsgc2VjdG9yU2l6ZSk7XG4gICAgY29uc3QgY3AxID0gdHJpZyhpbnRyYVIsIDQwICsgc2VjdG9yU2l6ZSk7XG4gICAgY29uc3QgY3AyID0gdHJpZyhpbnRyYVIsIC00MCArIHNlY3RvclNpemUpO1xuICAgIHJldHVybiBcIk0gMCwwIFwiICtcbiAgICAgICAgXCJRIFwiICsgY3AxLnggKyBcIixcIiArIC1jcDEueSArIFwiIFwiICsgYXJjU3RhcnQueCArIFwiLFwiICsgLWFyY1N0YXJ0LnkgK1xuICAgICAgICBcIiBBIFwiICsgaW50cmFSICsgXCIgXCIgKyBpbnRyYVIgKyBcIiAwIDAgMSBcIiArIGFyY0VuZC54ICsgXCIsXCIgKyAtYXJjRW5kLnkgK1xuICAgICAgICBcIiBRIFwiICsgY3AyLnggKyBcIixcIiArIC1jcDIueSArIFwiIDAsMFwiO1xufTtcblxuSW50ZXJhY3Rvci5wcm90b3R5cGUuY2hlY2tMaW5rcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBjaGVja0FsbChsaW5rTWFwKSB7XG4gICAgICAgIGZvciAobGV0IGxpbmsgb2YgbGlua01hcC52YWx1ZXMoKSkge1xuICAgICAgICAgICAgbGluay5jaGVjaygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2hlY2tBbGwodGhpcy5uYXJ5TGlua3MpOyAvLyBoYWNrZWQgb3V0IHRvIGZpeCBvcmRlcmluZyBvZiBuTGlua3NcbiAgICBjaGVja0FsbCh0aGlzLmJpbmFyeUxpbmtzKTtcbiAgICBjaGVja0FsbCh0aGlzLnNlcXVlbmNlTGlua3MpO1xuICAgIGlmICh0aGlzLnNlbGZMaW5rKSB7XG4gICAgICAgIHRoaXMuc2VsZkxpbmsuY2hlY2soKTtcbiAgICB9XG59O1xuXG4vLyB1cGRhdGUgYWxsIGxpbmVzIChlLmcgYWZ0ZXIgYSBtb3ZlKVxuSW50ZXJhY3Rvci5wcm90b3R5cGUuc2V0QWxsTGlua0Nvb3JkaW5hdGVzID0gZnVuY3Rpb24gKCkge1xuICAgIGZvciAobGV0IGxpbmsgb2YgdGhpcy5uYXJ5TGlua3MudmFsdWVzKCkpIHtcbiAgICAgICAgbGluay5zZXRMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICB9XG4gICAgZm9yIChsZXQgbGluayBvZiB0aGlzLmJpbmFyeUxpbmtzLnZhbHVlcygpKSB7XG4gICAgICAgIGxpbmsuc2V0TGlua0Nvb3JkaW5hdGVzKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnNlbGZMaW5rKSB7XG4gICAgICAgIHRoaXMuc2VsZkxpbmsuc2V0TGlua0Nvb3JkaW5hdGVzKCk7XG4gICAgfVxuICAgIGZvciAobGV0IGxpbmsgb2YgdGhpcy5zZXF1ZW5jZUxpbmtzLnZhbHVlcygpKSB7XG4gICAgICAgICAgICBsaW5rLnNldExpbmtDb29yZGluYXRlcygpO1xuICAgIH1cbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmlnIChyYWRpdXMsIGFuZ2xlRGVncmVlcykge1xuICAgIC8veCA9IHJ4ICsgcmFkaXVzICogY29zKHRoZXRhKSBhbmQgeSA9IHJ5ICsgcmFkaXVzICogc2luKHRoZXRhKVxuICAgIGNvbnN0IHJhZGlhbnMgPSAoYW5nbGVEZWdyZWVzIC8gMzYwKSAqIE1hdGguUEkgKiAyO1xuICAgIHJldHVybiB7XG4gICAgICAgIHg6IChyYWRpdXMgKiBNYXRoLmNvcyhyYWRpYW5zKSksXG4gICAgICAgIHk6IChyYWRpdXMgKiBNYXRoLnNpbihyYWRpYW5zKSlcbiAgICB9O1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/interactor.js\n"); /***/ }), @@ -1297,7 +1309,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"MoleculeSet\", function() { return MoleculeSet; });\n/* harmony import */ var _interactor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./interactor */ \"./src/js/viz/interactor/interactor.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n\n\n\nfunction MoleculeSet(id, app, json, name) {\n this.init(id, app, json, name);\n this.upperGroup = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"g\");\n this.initLabel();\n this.outline = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"rect\");\n this.outline.setAttribute(\"x\", \"-20\");\n this.outline.setAttribute(\"y\", \"-10\");\n this.outline.setAttribute(\"width\", \"40\");\n this.outline.setAttribute(\"height\", \"20\");\n this.outline.setAttribute(\"rx\", \"5\");\n this.outline.setAttribute(\"ry\", \"5\");\n this.outline.setAttribute(\"stroke\", \"black\");\n this.outline.setAttribute(\"stroke-width\", \"4\");\n this.outline.setAttribute(\"stroke-opacity\", \"1\");\n this.outline.setAttribute(\"fill-opacity\", \"1\");\n this.outline.setAttribute(\"fill\", \"#ffffff\");\n //append outline\n this.upperGroup.appendChild(this.outline);\n this.upperLine = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"rect\");\n this.upperLine.setAttribute(\"x\", \"-20\");\n this.upperLine.setAttribute(\"y\", \"-10\");\n this.upperLine.setAttribute(\"width\", \"40\");\n this.upperLine.setAttribute(\"height\", \"20\");\n this.upperLine.setAttribute(\"rx\", \"5\");\n this.upperLine.setAttribute(\"ry\", \"5\");\n this.upperLine.setAttribute(\"stroke\", \"white\");\n this.upperLine.setAttribute(\"stroke-width\", \"2\");\n this.upperLine.setAttribute(\"stroke-opacity\", \"1\");\n this.upperLine.setAttribute(\"fill\", \"none\");\n this.upperGroup.appendChild(this.upperLine);\n this.initListeners();\n}\n\nMoleculeSet.prototype = new _interactor__WEBPACK_IMPORTED_MODULE_0__[\"Interactor\"]();\n\nMoleculeSet.prototype.getSymbolRadius = function () {\n return 25;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvbW9sZWN1bGUtc2V0LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy92aXovaW50ZXJhY3Rvci9tb2xlY3VsZS1zZXQuanM/YjZhMiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0ludGVyYWN0b3J9IGZyb20gXCIuL2ludGVyYWN0b3JcIjtcbmltcG9ydCB7c3ZnbnN9IGZyb20gXCIuLi8uLi9jb25maWdcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIE1vbGVjdWxlU2V0KGlkLCBhcHAsIGpzb24sIG5hbWUpIHtcbiAgICB0aGlzLmluaXQoaWQsIGFwcCwganNvbiwgbmFtZSk7XG4gICAgdGhpcy51cHBlckdyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5pbml0TGFiZWwoKTtcbiAgICB0aGlzLm91dGxpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwicmVjdFwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwieFwiLCBcIi0yMFwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwieVwiLCBcIi0xMFwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgXCI0MFwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIFwiMjBcIik7XG4gICAgdGhpcy5vdXRsaW5lLnNldEF0dHJpYnV0ZShcInJ4XCIsIFwiNVwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwicnlcIiwgXCI1XCIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgXCJibGFja1wiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIFwiNFwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLW9wYWNpdHlcIiwgXCIxXCIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJmaWxsLW9wYWNpdHlcIiwgXCIxXCIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwiI2ZmZmZmZlwiKTtcbiAgICAvL2FwcGVuZCBvdXRsaW5lXG4gICAgdGhpcy51cHBlckdyb3VwLmFwcGVuZENoaWxkKHRoaXMub3V0bGluZSk7XG4gICAgdGhpcy51cHBlckxpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwicmVjdFwiKTtcbiAgICB0aGlzLnVwcGVyTGluZS5zZXRBdHRyaWJ1dGUoXCJ4XCIsIFwiLTIwXCIpO1xuICAgIHRoaXMudXBwZXJMaW5lLnNldEF0dHJpYnV0ZShcInlcIiwgXCItMTBcIik7XG4gICAgdGhpcy51cHBlckxpbmUuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgXCI0MFwiKTtcbiAgICB0aGlzLnVwcGVyTGluZS5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgXCIyMFwiKTtcbiAgICB0aGlzLnVwcGVyTGluZS5zZXRBdHRyaWJ1dGUoXCJyeFwiLCBcIjVcIik7XG4gICAgdGhpcy51cHBlckxpbmUuc2V0QXR0cmlidXRlKFwicnlcIiwgXCI1XCIpO1xuICAgIHRoaXMudXBwZXJMaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBcIndoaXRlXCIpO1xuICAgIHRoaXMudXBwZXJMaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBcIjJcIik7XG4gICAgdGhpcy51cHBlckxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLW9wYWNpdHlcIiwgXCIxXCIpO1xuICAgIHRoaXMudXBwZXJMaW5lLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJub25lXCIpO1xuICAgIHRoaXMudXBwZXJHcm91cC5hcHBlbmRDaGlsZCh0aGlzLnVwcGVyTGluZSk7XG4gICAgdGhpcy5pbml0TGlzdGVuZXJzKCk7XG59XG5cbk1vbGVjdWxlU2V0LnByb3RvdHlwZSA9IG5ldyBJbnRlcmFjdG9yKCk7XG5cbk1vbGVjdWxlU2V0LnByb3RvdHlwZS5nZXRTeW1ib2xSYWRpdXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIDI1O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/molecule-set.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"MoleculeSet\", function() { return MoleculeSet; });\n/* harmony import */ var _interactor__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./interactor */ \"./src/js/viz/interactor/interactor.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n\n\n\nfunction MoleculeSet(id, app, json, name) {\n this.init(id, app, json, name);\n this.upperGroup = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"g\");\n this.initLabel();\n this.outline = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"rect\");\n this.outline.setAttribute(\"x\", \"-20\");\n this.outline.setAttribute(\"y\", \"-10\");\n this.outline.setAttribute(\"width\", \"40\");\n this.outline.setAttribute(\"height\", \"20\");\n this.outline.setAttribute(\"rx\", \"5\");\n this.outline.setAttribute(\"ry\", \"5\");\n //todo - css... (initOutline hasn't been called so it doesn't have outlin in its classList)\n this.outline.setAttribute(\"stroke\", \"black\");\n this.outline.setAttribute(\"stroke-width\", \"4\");\n this.outline.setAttribute(\"stroke-opacity\", \"1\");\n this.outline.setAttribute(\"fill-opacity\", \"1\");\n this.outline.setAttribute(\"fill\", \"#ffffff\");\n //append outline\n this.upperGroup.appendChild(this.outline);\n this.upperLine = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"rect\");\n this.upperLine.setAttribute(\"x\", \"-20\");\n this.upperLine.setAttribute(\"y\", \"-10\");\n this.upperLine.setAttribute(\"width\", \"40\");\n this.upperLine.setAttribute(\"height\", \"20\");\n this.upperLine.setAttribute(\"rx\", \"5\");\n this.upperLine.setAttribute(\"ry\", \"5\");\n this.upperLine.setAttribute(\"stroke\", \"white\");\n this.upperLine.setAttribute(\"stroke-width\", \"2\");\n this.upperLine.setAttribute(\"stroke-opacity\", \"1\");\n this.upperLine.setAttribute(\"fill\", \"none\");\n this.upperGroup.appendChild(this.upperLine);\n this.initListeners();\n}\n\nMoleculeSet.prototype = new _interactor__WEBPACK_IMPORTED_MODULE_0__[\"Interactor\"]();\n\nMoleculeSet.prototype.getSymbolRadius = function () {\n return 25;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvbW9sZWN1bGUtc2V0LmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy92aXovaW50ZXJhY3Rvci9tb2xlY3VsZS1zZXQuanM/YjZhMiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0ludGVyYWN0b3J9IGZyb20gXCIuL2ludGVyYWN0b3JcIjtcbmltcG9ydCB7c3ZnbnN9IGZyb20gXCIuLi8uLi9jb25maWdcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIE1vbGVjdWxlU2V0KGlkLCBhcHAsIGpzb24sIG5hbWUpIHtcbiAgICB0aGlzLmluaXQoaWQsIGFwcCwganNvbiwgbmFtZSk7XG4gICAgdGhpcy51cHBlckdyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5pbml0TGFiZWwoKTtcbiAgICB0aGlzLm91dGxpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwicmVjdFwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwieFwiLCBcIi0yMFwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwieVwiLCBcIi0xMFwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgXCI0MFwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIFwiMjBcIik7XG4gICAgdGhpcy5vdXRsaW5lLnNldEF0dHJpYnV0ZShcInJ4XCIsIFwiNVwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwicnlcIiwgXCI1XCIpO1xuICAgIC8vdG9kbyAtIGNzcy4uLiAoaW5pdE91dGxpbmUgaGFzbid0IGJlZW4gY2FsbGVkIHNvIGl0IGRvZXNuJ3QgaGF2ZSBvdXRsaW4gaW4gaXRzIGNsYXNzTGlzdClcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwiYmxhY2tcIik7XG4gICAgdGhpcy5vdXRsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBcIjRcIik7XG4gICAgdGhpcy5vdXRsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS1vcGFjaXR5XCIsIFwiMVwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwiZmlsbC1vcGFjaXR5XCIsIFwiMVwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcIiNmZmZmZmZcIik7XG4gICAgLy9hcHBlbmQgb3V0bGluZVxuICAgIHRoaXMudXBwZXJHcm91cC5hcHBlbmRDaGlsZCh0aGlzLm91dGxpbmUpO1xuICAgIHRoaXMudXBwZXJMaW5lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInJlY3RcIik7XG4gICAgdGhpcy51cHBlckxpbmUuc2V0QXR0cmlidXRlKFwieFwiLCBcIi0yMFwiKTtcbiAgICB0aGlzLnVwcGVyTGluZS5zZXRBdHRyaWJ1dGUoXCJ5XCIsIFwiLTEwXCIpO1xuICAgIHRoaXMudXBwZXJMaW5lLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIFwiNDBcIik7XG4gICAgdGhpcy51cHBlckxpbmUuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIFwiMjBcIik7XG4gICAgdGhpcy51cHBlckxpbmUuc2V0QXR0cmlidXRlKFwicnhcIiwgXCI1XCIpO1xuICAgIHRoaXMudXBwZXJMaW5lLnNldEF0dHJpYnV0ZShcInJ5XCIsIFwiNVwiKTtcbiAgICB0aGlzLnVwcGVyTGluZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgXCJ3aGl0ZVwiKTtcbiAgICB0aGlzLnVwcGVyTGluZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgXCIyXCIpO1xuICAgIHRoaXMudXBwZXJMaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS1vcGFjaXR5XCIsIFwiMVwiKTtcbiAgICB0aGlzLnVwcGVyTGluZS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwibm9uZVwiKTtcbiAgICB0aGlzLnVwcGVyR3JvdXAuYXBwZW5kQ2hpbGQodGhpcy51cHBlckxpbmUpO1xuICAgIHRoaXMuaW5pdExpc3RlbmVycygpO1xufVxuXG5Nb2xlY3VsZVNldC5wcm90b3R5cGUgPSBuZXcgSW50ZXJhY3RvcigpO1xuXG5Nb2xlY3VsZVNldC5wcm90b3R5cGUuZ2V0U3ltYm9sUmFkaXVzID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAyNTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/molecule-set.js\n"); /***/ }), @@ -1309,7 +1321,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Polymer\", function() { return Polymer; });\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _interactor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./interactor */ \"./src/js/viz/interactor/interactor.js\");\n/* harmony import */ var _annotation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./annotation */ \"./src/js/viz/interactor/annotation.js\");\n/* harmony import */ var _sequence_datum__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../sequence-datum */ \"./src/js/viz/sequence-datum.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n // transitions and other stuff\n\n\n\n\n\nPolymer.STICKHEIGHT = 20; //height of stick in pixels\nPolymer.MAXSIZE = 0; // residue count of longest sequence\nPolymer.transitionTime = 650;\n\nfunction Polymer() {\n}\n\nPolymer.prototype = new _interactor__WEBPACK_IMPORTED_MODULE_1__[\"Interactor\"]();\n\n//sequence = amino acids in UPPERCASE, digits or lowercase can be used for modification info\nPolymer.prototype.setSequence = function (sequence) {\n //remove modification site info from sequence\n this.sequence = sequence.replace(/[^A-Z]/g, \"\");\n this.size = this.sequence.length;\n};\n\nPolymer.prototype.getSymbolRadius = function () {\n return 15;\n};\n\nPolymer.prototype.showHighlight = function (show) {\n if (show === true) {\n this.highlight.setAttribute(\"stroke-opacity\", \"1\");\n } else {\n this.highlight.setAttribute(\"stroke-opacity\", \"0\");\n }\n};\n\nPolymer.minXDist = 30;\nPolymer.prototype.setStickScale = function (scale, svgP) {\n const oldScale = this.stickZoom;\n\n //dist from centre\n const dx = (this.ix - svgP.x);\n const dy = (this.iy - svgP.y);\n\n // new dist from centre\n const nx = dx * scale / oldScale;\n const ny = dy * scale / oldScale;\n\n //required change\n const rx = nx - dx;\n let ry = ny - dy;\n\n if (this.rotation === 0 || this.rotation === 180) {\n ry = 0;\n }\n\n //new pos\n const x = this.ix + rx;\n const y = this.iy + ry;\n\n this.stickZoom = scale;\n this.scale();\n this.setPosition(x, y);\n this.setAllLinkCoordinates();\n};\n\nPolymer.prototype.scale = function () {\n const protLength = (this.size) * this.stickZoom;\n if (this.form === 1) {\n const labelTransform = d3__WEBPACK_IMPORTED_MODULE_0__[\"transform\"](this.labelSVG.getAttribute(\"transform\"));\n const k = this.app.svgElement.createSVGMatrix().rotate(labelTransform.rotate)\n .translate((-(((this.size / 2) * this.stickZoom) + (this.nTerminusFeature ? 25 : 10))), _config__WEBPACK_IMPORTED_MODULE_4__[\"LABEL_Y\"]); //.scale(z).translate(-c.x, -c.y);\n this.labelSVG.transform.baseVal.initialize(this.app.svgElement.createSVGTransformFromMatrix(k));\n\n for (let [annotationType, annotations] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n if (anno.fuzzyStart) {\n anno.fuzzyStart.setAttribute(\"d\", this.getAnnotationRectPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n }\n if (anno.certain) {\n let tempBegin = anno.seqDatum.begin; //todo - might be better to have seperate att in SequenceData for end of uncertain start\n let tempEnd = anno.seqDatum.end;\n if (anno.seqDatum.uncertainBegin) {\n tempBegin += 1;\n }\n if (anno.seqDatum.uncertainEnd) {\n tempEnd -= 1;\n }\n anno.certain.setAttribute(\"d\", this.getAnnotationRectPath(tempBegin, tempEnd, anno));\n }\n if (anno.fuzzyEnd) {\n anno.fuzzyEnd.setAttribute(\"d\", this.getAnnotationRectPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n }\n }\n }\n }\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.background)\n .attr(\"width\", protLength)\n .attr(\"x\", this.getResXwithStickZoom(0.5));\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.outline)\n .attr(\"width\", protLength)\n .attr(\"x\", this.getResXwithStickZoom(0.5));\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.highlight)\n .attr(\"width\", protLength + 5)\n .attr(\"x\", this.getResXwithStickZoom(0.5) - 2.5);\n\n\n this.setScaleGroup();\n }\n};\n\nPolymer.prototype.setScaleGroup = function () {\n this.upperGroup.appendChild(this.ticks); //will do nothing if this.ticks already appended to this.uppergroup\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.ticks).selectAll(\"*\").remove();\n\n this.scaleLabels = [];\n const ScaleTicksPerLabel = 2; // varies with scale?\n let tick = -1;\n const lastTickX = this.getResXwithStickZoom(this.size);\n\n for (let res = 1; res <= this.size; res++) {\n if (res === 1 ||\n ((res % 100 === 0) && (200 * this.stickZoom > Polymer.minXDist)) ||\n ((res % 10 === 0) && (20 * this.stickZoom > Polymer.minXDist))\n ) {\n const tx = this.getResXwithStickZoom(res);\n if (this.stickZoom >= 8 || res !== 1) {\n tickAt(this, tx);\n }\n tick = (tick + 1) % ScaleTicksPerLabel;\n // does this one get a label?\n if (tick === 0) { // && tx > 20) {\n if ((tx + Polymer.minXDist) < lastTickX) {\n scaleLabelAt(this, res, tx);\n }\n }\n }\n if (this.stickZoom >= 8) {\n const seqLabelGroup = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"g\");\n seqLabelGroup.setAttribute(\"transform\", \"translate(\" + this.getResXwithStickZoom(res) + \" \" + 0 + \")\");\n const seqLabel = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"text\");\n seqLabel.setAttribute(\"font-family\", \"'Courier New', monospace\");\n seqLabel.setAttribute(\"font-size\", \"10px\");\n seqLabel.setAttribute(\"text-anchor\", \"middle\");\n seqLabel.setAttribute(\"x\", \"0\");\n seqLabel.setAttribute(\"y\", \"3\");\n seqLabel.appendChild(document.createTextNode(this.sequence[res - 1]));\n seqLabelGroup.appendChild(seqLabel);\n this.scaleLabels.push(seqLabel);\n this.ticks.appendChild(seqLabelGroup);\n }\n }\n scaleLabelAt(this, this.size, lastTickX);\n if (this.stickZoom >= 8) {\n tickAt(this, lastTickX);\n }\n\n function scaleLabelAt(self, text, tickX) {\n const scaleLabelGroup = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"g\");\n scaleLabelGroup.setAttribute(\"transform\", \"translate(\" + tickX + \" \" + 0 + \")\");\n const scaleLabel = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"text\");\n scaleLabel.setAttribute(\"class\", \"xlv_text\");\n // scaleLabel.setAttribute(\"font-family\", \"'Courier New', monospace\");\n scaleLabel.setAttribute(\"font-size\", \"8pt\"); // todo css...\n scaleLabel.setAttribute(\"text-anchor\", \"middle\");\n scaleLabel.setAttribute(\"x\", \"0\");\n scaleLabel.setAttribute(\"y\", Polymer.STICKHEIGHT + 4);\n scaleLabel.appendChild(document.createTextNode(text));\n scaleLabelGroup.appendChild(scaleLabel);\n self.scaleLabels.push(scaleLabel);\n self.ticks.appendChild(scaleLabelGroup);\n }\n\n function tickAt(self, tickX) {\n const tick = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"line\");\n tick.setAttribute(\"x1\", tickX);\n tick.setAttribute(\"y1\", \"5\");\n tick.setAttribute(\"x2\", tickX);\n tick.setAttribute(\"y2\", \"10\");\n tick.setAttribute(\"stroke\", \"black\");\n self.ticks.appendChild(tick);\n }\n};\n\nPolymer.prototype.setForm = function (form, svgP) {\n if (this.busy !== true) {\n if (form === 1) {\n if (this.form !== 1) {\n this.toStick();\n }\n } else {\n // if (this.form !== 0) {\n this.toCircle(svgP);\n // var r = this.getSymbolRadius();\n\n }\n // }\n }\n};\n\nPolymer.prototype.toCircle = function (svgP) {\n //svgP = null;// temp hack - you can uncomment this is you experience things 'flying off screen'\n this.busy = true;\n\n const r = this.getSymbolRadius();\n //\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.background).transition()\n .attr(\"x\", -r).attr(\"y\", -r)\n .attr(\"width\", r * 2).attr(\"height\", r * 2)\n .attr(\"rx\", r).attr(\"ry\", r)\n .duration(Polymer.transitionTime);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.outline).transition()\n .attr(\"x\", -r).attr(\"y\", -r)\n .attr(\"width\", r * 2).attr(\"height\", r * 2)\n .attr(\"rx\", r).attr(\"ry\", r)\n .duration(Polymer.transitionTime);\n // d3.select(this.annotationsSvgGroup).transition()\n // .attr(\"transform\", \"scale(1, 1)\")\n // .duration(Polymer.transitionTime);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.highlight).transition()\n .attr(\"x\", -r).attr(\"y\", -r)\n .attr(\"width\", r * 2).attr(\"height\", r * 2)\n .attr(\"rx\", r).attr(\"ry\", r)\n .duration(Polymer.transitionTime);\n\n const stickZoomInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](this.stickZoom, 0);\n // var rotationInterpol = d3.interpolate((this.rotation > 180) ? this.rotation - 360 : this.rotation, 0);\n const labelTransform = d3__WEBPACK_IMPORTED_MODULE_0__[\"transform\"](this.labelSVG.getAttribute(\"transform\"));\n const labelStartPoint = labelTransform.translate[0];\n const labelTranslateInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](labelStartPoint, -(r + 5));\n\n let xInterpol = null,\n yInterpol = null;\n if (typeof svgP !== \"undefined\" && svgP !== null) {\n xInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](this.ix, svgP.x);\n yInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](this.iy, svgP.y);\n }\n\n const self = this;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.ticks).transition().attr(\"opacity\", 0).duration(Polymer.transitionTime / 4)\n .each(\"end\",\n function () {\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this).selectAll(\"*\").remove();\n }\n );\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.highlight).transition()\n .attr(\"width\", (r * 2) + 5).attr(\"height\", (r * 2) + 5)\n .attr(\"x\", -r - 2.5).attr(\"y\", -r - 2.5)\n .attr(\"rx\", r + 2.5).attr(\"ry\", r + 2.5)\n .duration(Polymer.transitionTime);\n\n function changeFuzzyStartToArcPath(anno) {\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](anno.fuzzyStart).attr(\"d\", self.getAnnotationPieSliceArcPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n }\n\n function changeCertainToArcPath(anno) {\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](anno.certain).attr(\"d\", self.getAnnotationPieSliceArcPath(anno.seqDatum.begin, anno.seqDatum.end, anno));\n }\n\n function changeFuzzyEndToArcPath(anno) {\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](anno.fuzzyEnd).attr(\"d\", self.getAnnotationPieSliceArcPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n }\n\n for (let [annotationType, annotations] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n if (anno.fuzzyStart) {\n const fuzzyStart = anno.fuzzyStart;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyStart).transition().attr(\"d\", this.getAnnotationPieSliceApproximatePath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno))\n .duration(Polymer.transitionTime).each(\"end\",\n function () {\n changeFuzzyStartToArcPath(anno);\n }\n );\n }\n\n if (anno.certain) {\n const certain = anno.certain;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](certain).transition().attr(\"d\", this.getAnnotationPieSliceApproximatePath(anno.seqDatum.begin, anno.seqDatum.end, anno))\n .duration(Polymer.transitionTime).each(\"end\",\n function () {\n changeCertainToArcPath(anno);\n }\n );\n }\n\n if (anno.fuzzyEnd) {\n const fuzzyEnd = anno.fuzzyEnd;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyEnd).transition().attr(\"d\", this.getAnnotationPieSliceApproximatePath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno))\n .duration(Polymer.transitionTime).each(\"end\",\n function () {\n changeFuzzyEndToArcPath(anno);\n }\n );\n }\n }\n }\n }\n\n const originalStickZoom = this.stickZoom;\n const originalRotation = this.rotation;\n const cubicInOut = d3__WEBPACK_IMPORTED_MODULE_0__[\"ease\"](\"cubic-in-out\");\n d3__WEBPACK_IMPORTED_MODULE_0__[\"timer\"](function (elapsed) {\n return update(elapsed / Polymer.transitionTime);\n });\n\n function update(interp) {\n const labelTransform = d3__WEBPACK_IMPORTED_MODULE_0__[\"transform\"](self.labelSVG.getAttribute(\"transform\"));\n const k = self.app.svgElement.createSVGMatrix().rotate(labelTransform.rotate).translate(labelTranslateInterpol(cubicInOut(interp)), _config__WEBPACK_IMPORTED_MODULE_4__[\"LABEL_Y\"]); //.scale(z).translate(-c.x, -c.y);\n self.labelSVG.transform.baseVal.initialize(self.app.svgElement.createSVGTransformFromMatrix(k));\n //~\n if (xInterpol !== null) {\n self.setPosition(xInterpol(cubicInOut(interp)), yInterpol(cubicInOut(interp)));\n }\n\n self.stickZoom = stickZoomInterpol(cubicInOut(interp));\n self.setAllLinkCoordinates();\n\n if (interp === 1) { // finished - tidy up\n self.form = 0;\n self.checkLinks();\n self.stickZoom = originalStickZoom;\n self.rotation = originalRotation;\n self.busy = false;\n return true;\n } else if (interp > 1) {\n return update(1);\n } else {\n return false;\n }\n }\n};\n\nPolymer.prototype.toStick = function () {\n this.busy = true;\n this.form = 1;\n\n //remove prot-prot links - would it be better if checkLinks did this? - think not\n const c = this.binaryLinks.values().length;\n for (let l = 0; l < c; l++) {\n const link = this.binaryLinks.values()[l];\n //out with the old\n if (link.shown) {\n link.hide();\n }\n }\n\n const protLength = this.size * this.stickZoom;\n const r = this.getSymbolRadius();\n\n const lengthInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"]((2 * r), protLength);\n const stickZoomInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](0, this.stickZoom);\n const labelTranslateInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](-(r + 5), -(((this.size / 2) * this.stickZoom) + (this.nTerminusFeature ? 25 : 10)));\n\n const origStickZoom = this.stickZoom;\n this.stickZoom = 0;\n this.checkLinks(this.binaryLinks);\n this.checkLinks(this.selfLink);\n this.checkLinks(this.sequenceLinks);\n this.stickZoom = origStickZoom;\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.background).transition() //.attr(\"stroke-opacity\", 1)\n .attr(\"height\", Polymer.STICKHEIGHT)\n .attr(\"y\", -Polymer.STICKHEIGHT / 2)\n .attr(\"rx\", 0).attr(\"ry\", 0)\n .duration(Polymer.transitionTime);\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.outline).transition() //.attr(\"stroke-opacity\", 1)\n .attr(\"height\", Polymer.STICKHEIGHT)\n .attr(\"y\", -Polymer.STICKHEIGHT / 2)\n .attr(\"rx\", 0).attr(\"ry\", 0)\n .duration(Polymer.transitionTime);\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.highlight).transition()\n .attr(\"width\", protLength + 5).attr(\"height\", Polymer.STICKHEIGHT + 5)\n .attr(\"x\", this.getResXwithStickZoom(0.5) - 2.5).attr(\"y\", (-Polymer.STICKHEIGHT / 2) - 2.5)\n .attr(\"rx\", 0).attr(\"ry\", 0)\n .duration(Polymer.transitionTime);\n\n for (let [annotationType, annotations] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n if (anno.fuzzyStart) {\n const fuzzyStart = anno.fuzzyStart;\n fuzzyStart.setAttribute(\"d\", this.getAnnotationPieSliceApproximatePath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyStart).transition().attr(\"d\", this.getAnnotationRectPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno))\n .duration(Polymer.transitionTime);\n }\n if (anno.certain) {\n const certain = anno.certain;\n let tempBegin = anno.seqDatum.begin; //todo - might be better to have seperate att in SequenceData for end of uncertain start\n let tempEnd = anno.seqDatum.end;\n if (anno.seqDatum.uncertainBegin) {\n tempBegin += 1;\n }\n if (anno.seqDatum.uncertainEnd) {\n tempEnd -= 1;\n }\n\n certain.setAttribute(\"d\", this.getAnnotationPieSliceApproximatePath(tempBegin, tempEnd, anno));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](certain).transition().attr(\"d\", this.getAnnotationRectPath(tempBegin, tempEnd, anno))\n .duration(Polymer.transitionTime);\n }\n if (anno.fuzzyEnd) {\n const fuzzyEnd = anno.fuzzyEnd;\n fuzzyEnd.setAttribute(\"d\", this.getAnnotationPieSliceApproximatePath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyEnd).transition().attr(\"d\", this.getAnnotationRectPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno))\n .duration(Polymer.transitionTime);\n }\n }\n }\n }\n\n const self = this;\n const cubicInOut = d3__WEBPACK_IMPORTED_MODULE_0__[\"ease\"](\"cubic-in-out\");\n d3__WEBPACK_IMPORTED_MODULE_0__[\"timer\"](function (elapsed) {\n return update(elapsed / Polymer.transitionTime);\n });\n\n function update(interp) {\n const labelTransform = d3__WEBPACK_IMPORTED_MODULE_0__[\"transform\"](self.labelSVG.getAttribute(\"transform\"));\n const k = self.app.svgElement.createSVGMatrix().rotate(labelTransform.rotate).translate(labelTranslateInterpol(cubicInOut(interp)), _config__WEBPACK_IMPORTED_MODULE_4__[\"LABEL_Y\"]); //.scale(z).translate(-c.x, -c.y);\n self.labelSVG.transform.baseVal.initialize(self.app.svgElement.createSVGTransformFromMatrix(k));\n\n const currentLength = lengthInterpol(cubicInOut(interp));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.highlight).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.outline).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.background).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n self.stickZoom = stickZoomInterpol(cubicInOut(interp));\n self.setAllLinkCoordinates();\n\n if (interp === 1) { // finished - tidy up\n self.busy = false;\n return true;\n } else if (interp > 1) {\n return update(1);\n } else {\n return false;\n }\n }\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.ticks).attr(\"opacity\", 0);\n this.setScaleGroup();\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.ticks).transition().attr(\"opacity\", 1)\n .delay(Polymer.transitionTime * 0.8).duration(Polymer.transitionTime / 2);\n};\n\n\nPolymer.prototype.toStickNoTransition = function () { //todo tidy\n this.busy = true;\n this.form = 1;\n\n //remove prot-prot links - would it be better if checkLinks did this? - think not\n const c = this.binaryLinks.values().length;\n for (let l = 0; l < c; l++) {\n const link = this.binaryLinks.values()[l];\n //out with the old\n if (link.shown) {\n link.hide();\n }\n }\n\n const protLength = this.size * this.stickZoom;\n const r = this.getSymbolRadius();\n\n const lengthInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"]((2 * r), protLength);\n const labelTranslateInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](-(r + 5), -(((this.size / 2) * this.stickZoom) + (this.nTerminusFeature ? 25 : 10)));\n\n this.checkLinks(this.binaryLinks);\n this.checkLinks(this.selfLink);\n this.checkLinks(this.sequenceLinks);\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.background)\n .attr(\"height\", Polymer.STICKHEIGHT)\n .attr(\"y\", -Polymer.STICKHEIGHT / 2)\n .attr(\"rx\", 0).attr(\"ry\", 0);\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.outline)\n .attr(\"height\", Polymer.STICKHEIGHT)\n .attr(\"y\", -Polymer.STICKHEIGHT / 2)\n .attr(\"rx\", 0).attr(\"ry\", 0);\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.highlight)\n .attr(\"width\", protLength + 5).attr(\"height\", Polymer.STICKHEIGHT + 5)\n .attr(\"x\", this.getResXwithStickZoom(0.5) - 2.5).attr(\"y\", (-Polymer.STICKHEIGHT / 2) - 2.5)\n .attr(\"rx\", 0).attr(\"ry\", 0);\n\n for (let [annotationType, annotations] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n if (anno.fuzzyStart) {\n const fuzzyStart = anno.fuzzyStart;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyStart).attr(\"d\", this.getAnnotationRectPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n }\n if (anno.certain) {\n let tempBegin = anno.seqDatum.begin; //todo - might be better to have seperate att in SequenceData for end of uncertain start\n let tempEnd = anno.seqDatum.end;\n if (anno.seqDatum.uncertainBegin) {\n tempBegin += 1;\n }\n if (anno.seqDatum.uncertainEnd) {\n tempEnd -= 1;\n }\n anno.certain.setAttribute(\"d\", this.getAnnotationRectPath(tempBegin, tempEnd, anno));\n }\n if (anno.fuzzyEnd) {\n const fuzzyEnd = anno.fuzzyEnd;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyEnd) /*.transition()*/ .attr(\"d\", this.getAnnotationRectPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n }\n }\n }\n }\n\n const self = this;\n\n const labelTransform = d3__WEBPACK_IMPORTED_MODULE_0__[\"transform\"](self.labelSVG.getAttribute(\"transform\"));\n const k = self.app.svgElement.createSVGMatrix().rotate(labelTransform.rotate).translate(labelTranslateInterpol(1), _config__WEBPACK_IMPORTED_MODULE_4__[\"LABEL_Y\"]); //.scale(z).translate(-c.x, -c.y);\n self.labelSVG.transform.baseVal.initialize(self.app.svgElement.createSVGTransformFromMatrix(k));\n\n const currentLength = lengthInterpol(1);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.highlight).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.outline).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.background).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n self.setAllLinkCoordinates();\n\n this.setScaleGroup();\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.ticks).attr(\"opacity\", 1);\n\n self.busy = false;\n};\n\nPolymer.prototype.getResXwithStickZoom = function (r) {\n // if (isNaN(r)) {\n // console.error(\"NOT NUMBER\");\n // }\n if (r === \"n-n\") {\n return (-this.size / 2 * this.stickZoom) - 20;\n } else if (r === \"c-c\") {\n return (this.size / 2 * this.stickZoom) + 20;\n } else {\n return (r - (this.size / 2)) * this.stickZoom;\n }\n};\n\n//calculate the coordinates of a residue (relative to this.util.container)\nPolymer.prototype.getResidueCoordinates = function (r, yOff) {\n if (typeof r === \"undefined\") {\n console.error(\"ERROR: residue number is undefined\");\n }\n let x = this.getResXwithStickZoom(r * 1);// * this.app.z;\n // console.log(\"***\", this.app.z);\n // coz prots don't scale, don't multiple by app.z\n let y;\n if (x !== 0) {\n const l = Math.abs(x);\n const a = Math.acos(x / l);\n const rotRad = (this.rotation / 360) * Math.PI * 2;\n x = l * Math.cos(rotRad + a);\n y = l * Math.sin(rotRad + a);\n if (typeof yOff !== \"undefined\") {\n x += yOff /** this.app.z*/ * Math.cos(rotRad + (Math.PI / 2));\n y += yOff /** this.app.z*/ * Math.sin(rotRad + (Math.PI / 2));\n }\n } else {\n y = yOff;\n }\n x += this.ix;\n y += this.iy;\n return [x, y];\n};\n\nPolymer.prototype.clearPositionalFeatures = function () {\n this.annotations = [];\n this.annotationTypes = [];\n if (this.annotationsSvgGroup) d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.annotationsSvgGroup).selectAll(\"*\").remove();\n};\n\nPolymer.prototype.setPositionalFeatures = function () {\n const self = this;\n\n const toolTipFunc = function (evt) {\n const el = (evt.target.correspondingUseElement) ? evt.target.correspondingUseElement : evt.target;\n self.app.preventDefaultsAndStopPropagation(evt);\n self.app.setTooltip(el.name, el.getAttribute(\"fill\"));\n self.showHighlight(true);\n };\n\n const annotationTypesSet = new Set();\n\n for (let [annotationType, annotationSet] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let annotation of annotationSet.values()) {\n\n if (annotation.seqDatum.sequenceDatumString !== \"n-n\" && annotation.seqDatum.sequenceDatumString !== \"c-c\") {\n annotationTypesSet.add(annotation.description);\n }\n }\n }\n }\n this.annotationTypes = Array.from(annotationTypesSet.values()).sort();\n\n for (let [annotationType, annotationSet] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotationSet.values()) {\n let text = anno.description + \" [\" + (anno.seqDatum ? anno.seqDatum.toString() : anno.seqDatum.begin + \" - \" + anno.seqDatum.end) + \"]\";\n if (anno.description === \"No annotations\") {\n text = \"No annotations\";\n }\n if (anno.seqDatum.uncertainBegin) {\n anno.fuzzyStart = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"path\");\n if (this.form === 0) {\n anno.fuzzyStart.setAttribute(\"d\", this.getAnnotationPieSliceArcPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n } else {\n anno.fuzzyStart.setAttribute(\"d\", this.getAnnotationRectPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n }\n anno.fuzzyStart.setAttribute(\"stroke\", \"none\");//-width\", \"1\"); // todo - should be css\n // anno.fuzzyStart.setAttribute(\"fill-opacity\", \"0.6\");\n anno.fuzzyStart.name = text;\n anno.fuzzyStart.onmouseover = toolTipFunc;\n this.annotationsSvgGroup.appendChild(anno.fuzzyStart);\n }\n\n if (anno.seqDatum.begin && anno.seqDatum.end) {\n anno.certain = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"path\");\n let tempBegin = anno.seqDatum.begin; //todo - might be better to have seperate att in SequenceData for end of uncertain start\n let tempEnd = anno.seqDatum.end;\n if (anno.seqDatum.uncertainBegin) {\n tempBegin += 1;\n }\n if (anno.seqDatum.uncertainEnd) {\n tempEnd -= 1;\n }\n if (this.form === 0) {\n anno.certain.setAttribute(\"d\", this.getAnnotationPieSliceArcPath(tempBegin, tempEnd, anno));\n } else {\n anno.certain.setAttribute(\"d\", this.getAnnotationRectPath(tempBegin, tempEnd, anno));\n }\n anno.certain.setAttribute(\"stroke\", \"none\");//-width\", \"1\");\n // anno.certain.setAttribute(\"fill-opacity\", \"0.6\");\n anno.certain.name = text;\n anno.certain.onmouseover = toolTipFunc;\n this.annotationsSvgGroup.appendChild(anno.certain);\n }\n if (anno.seqDatum.uncertainEnd) {\n anno.fuzzyEnd = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"path\");\n if (this.form === 0) {\n anno.fuzzyEnd.setAttribute(\"d\", this.getAnnotationPieSliceArcPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n } else {\n anno.fuzzyEnd.setAttribute(\"d\", this.getAnnotationRectPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n }\n anno.fuzzyEnd.setAttribute(\"stroke\", \"none\"); //-width\", \"1\");\n // anno.fuzzyEnd.setAttribute(\"fill-opacity\", \"0.6\");\n anno.fuzzyEnd.name = text;\n anno.fuzzyEnd.onmouseover = toolTipFunc;\n this.annotationsSvgGroup.appendChild(anno.fuzzyEnd);\n }\n }\n }\n }\n};\n\nPolymer.stepsInArc = 5;\n\nPolymer.prototype.getAnnotationPieSliceArcPath = function (startRes, endRes, annotation) {\n const radius = this.getSymbolRadius();// - 2;\n\n let top, bottom, rungHeight;\n const rung = this.annotationTypes.indexOf(annotation.description);\n // console.log(\"rung\", rung, this.annotationTypes);\n if (rung === -1) {\n bottom = 0;\n top = radius;\n } else {\n //Math.sqrt(this.participant.size / Math.PI) * 0.6\n rungHeight = radius / this.annotationTypes.length;\n bottom = (rung * rungHeight);\n top = bottom + rungHeight;\n //\n // bottom = Math.sqrt(rung / this.annotationTypes.length) * radius;\n // top = Math.sqrt(rung + 1 / this.annotationTypes.length) * radius;\n }\n\n // var startAngle = ((startRes - 1) / this.size) * 360;\n // var endAngle = ((endRes - 1) / this.size) * 360;\n let startAngle, endAngle;\n if (startRes === \"n-n\") {\n startAngle = -20; //((startRes - 1) / this.size) * 360;\n endAngle = 0;//((endRes - 1) / this.size) * 360;\n } else if (endRes === \"c-c\") {\n startAngle = 0;//((startRes - 1) / this.size) * 360;\n endAngle = +20; //((endRes) / this.size) * 360;\n } else {\n startAngle = ((startRes - 1) / this.size) * 360;\n endAngle = ((endRes - 1) / this.size) * 360;\n }\n // const arcStart = trig(radius, startAngle - 90);\n // const arcEnd = trig(radius, endAngle - 90);\n let largeArch = 0;\n if ((endAngle - startAngle) > 180 || (endAngle === startAngle)) {\n largeArch = 1;\n }\n\n const p1 = Object(_config__WEBPACK_IMPORTED_MODULE_4__[\"rotatePointAboutPoint\"])([0, bottom], [0, 0], startAngle - 180);\n const p2 = Object(_config__WEBPACK_IMPORTED_MODULE_4__[\"rotatePointAboutPoint\"])([0, top], [0, 0], startAngle - 180);\n const p3 = Object(_config__WEBPACK_IMPORTED_MODULE_4__[\"rotatePointAboutPoint\"])([0, top], [0, 0], endAngle - 180);\n const p4 = Object(_config__WEBPACK_IMPORTED_MODULE_4__[\"rotatePointAboutPoint\"])([0, bottom], [0, 0], endAngle - 180);\n\n //const r = (bottom + top) / 2;\n const path = \"M\" + p1[0] + \",\" + p1[1] + \" L\" + p2[0] + \",\" + p2[1]\n + \" A\" + top + \",\" + top + \" 0 \" + largeArch + \" 1 \" + p3[0] + \",\" + p3[1] + \" L\" + p4[0] + \",\" + p4[1]\n + \" A\" + bottom + \",\" + bottom + \" 0 \" + largeArch + \" 0 \" + p1[0] + \",\" + p1[1] + \" Z\";\n console.log(\"**\", path);\n return path;\n // return \"M0,0 L\" + arcStart.x + \",\" + arcStart.y + \" A\" + radius + \",\" +\n // radius + \" 0 \" + largeArch + \" 1 \" + arcEnd.x + \",\" + arcEnd.y + \" Z\";\n};\n\nPolymer.prototype.getAnnotationPieSliceApproximatePath = function (startRes, endRes, annotation) {\n\n // let top, bottom, rungHeight;\n // const rung = this.annotationTypes.indexOf(annotation.description);\n // // console.log(\"rung\", rung, this.annotationTypes);\n // if (rung === -1) {\n // bottom = Polymer.STICKHEIGHT / 2;\n // top = -Polymer.STICKHEIGHT / 2;\n // } else {\n // rungHeight = Polymer.STICKHEIGHT / this.annotationTypes.length;\n // top = (-Polymer.STICKHEIGHT / 2) + (rung * rungHeight);\n // bottom = top + rungHeight;\n // }\n\n //approximate pie slice\n let startAngle, endAngle;\n if (startRes === \"n-n\") {\n startAngle = -20; //((startRes - 1) / this.size) * 360;\n endAngle = 0;//((endRes) / this.size) * 360;\n } else if (endRes === \"c-c\") {\n startAngle = 0;//((startRes - 1) / this.size) * 360;\n endAngle = +20; //((endRes) / this.size) * 360;\n } else {\n startAngle = ((startRes - 1) / this.size) * 360;\n endAngle = ((endRes) / this.size) * 360;\n }\n const pieRadius = this.getSymbolRadius() - 2;\n // var arcStart = Interactor.trig(pieRadius, startAngle - 90);\n // var arcEnd = Interactor.trig(pieRadius, endAngle - 90);\n let approximatePiePath = \"M 0,0\";\n const stepsInArc = 5;\n for (let sia = 0; sia <= Polymer.stepsInArc; sia++) {\n const angle = startAngle + ((endAngle - startAngle) * (sia / stepsInArc));\n const siaCoord = Object(_interactor__WEBPACK_IMPORTED_MODULE_1__[\"trig\"])(pieRadius, angle - 90);\n approximatePiePath += \" L \" + siaCoord.x + \",\" + siaCoord.y;\n }\n approximatePiePath += \" L \" + 0 + \",\" + 0;\n approximatePiePath += \" Z\";\n return approximatePiePath;\n};\n\nPolymer.prototype.getAnnotationRectPath = function (startRes, endRes, annotation) {\n //domain as rectangle path\n let top, bottom, rungHeight;\n const rung = this.annotationTypes.indexOf(annotation.description);\n // console.log(\"rung\", rung, this.annotationTypes);\n if (rung === -1) {\n bottom = Polymer.STICKHEIGHT / 2;\n top = -Polymer.STICKHEIGHT / 2;\n } else {\n rungHeight = Polymer.STICKHEIGHT / this.annotationTypes.length;\n top = (-Polymer.STICKHEIGHT / 2) + (rung * rungHeight);\n bottom = top + rungHeight;\n }\n\n let annotX, annotSize, annotLength;\n if (startRes === \"n-n\") {\n annotX = this.getResXwithStickZoom(0.5) - 20;\n // var annotSize = (1 + (endRes - startRes));\n annotLength = 20;//annotSize * this.stickZoom;\n } else if (endRes === \"c-c\") {\n annotX = this.getResXwithStickZoom(this.size + 0.5);\n // var annotSize = (1 + (endRes - startRes));\n annotLength = 20;//annotSize * this.stickZoom;\n } else {\n annotX = this.getResXwithStickZoom(startRes - 0.5);\n annotSize = (1 + (endRes - startRes));\n annotLength = annotSize * this.stickZoom;\n }\n let rectPath = \"M \" + annotX + \",\" + bottom;\n for (let sia = 0; sia <= Polymer.stepsInArc; sia++) {\n const step = annotX + (annotLength * (sia / Polymer.stepsInArc));\n rectPath += \" L \" + step + \",\" + top;\n }\n rectPath += \" L \" + (annotX + annotLength) + \",\" + bottom +\n \" Z\";\n return rectPath;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvcG9seW1lci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2ludGVyYWN0b3IvcG9seW1lci5qcz8wNGY2Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGQzIGZyb20gXCJkM1wiOyAvLyB0cmFuc2l0aW9ucyBhbmQgb3RoZXIgc3R1ZmZcbmltcG9ydCB7SW50ZXJhY3RvciwgdHJpZ30gZnJvbSBcIi4vaW50ZXJhY3RvclwiO1xuaW1wb3J0IHtBbm5vdGF0aW9ufSBmcm9tIFwiLi9hbm5vdGF0aW9uXCI7XG5pbXBvcnQge1NlcXVlbmNlRGF0dW19IGZyb20gXCIuLi9zZXF1ZW5jZS1kYXR1bVwiO1xuaW1wb3J0IHtzdmducywgTEFCRUxfWSwgcm90YXRlUG9pbnRBYm91dFBvaW50fSBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XG5cblBvbHltZXIuU1RJQ0tIRUlHSFQgPSAyMDsgLy9oZWlnaHQgb2Ygc3RpY2sgaW4gcGl4ZWxzXG5Qb2x5bWVyLk1BWFNJWkUgPSAwOyAvLyByZXNpZHVlIGNvdW50IG9mIGxvbmdlc3Qgc2VxdWVuY2VcblBvbHltZXIudHJhbnNpdGlvblRpbWUgPSA2NTA7XG5cbmV4cG9ydCBmdW5jdGlvbiBQb2x5bWVyKCkge1xufVxuXG5Qb2x5bWVyLnByb3RvdHlwZSA9IG5ldyBJbnRlcmFjdG9yKCk7XG5cbi8vc2VxdWVuY2UgPSBhbWlubyBhY2lkcyBpbiBVUFBFUkNBU0UsIGRpZ2l0cyBvciBsb3dlcmNhc2UgY2FuIGJlIHVzZWQgZm9yIG1vZGlmaWNhdGlvbiBpbmZvXG5Qb2x5bWVyLnByb3RvdHlwZS5zZXRTZXF1ZW5jZSA9IGZ1bmN0aW9uIChzZXF1ZW5jZSkge1xuICAgIC8vcmVtb3ZlIG1vZGlmaWNhdGlvbiBzaXRlIGluZm8gZnJvbSBzZXF1ZW5jZVxuICAgIHRoaXMuc2VxdWVuY2UgPSBzZXF1ZW5jZS5yZXBsYWNlKC9bXkEtWl0vZywgXCJcIik7XG4gICAgdGhpcy5zaXplID0gdGhpcy5zZXF1ZW5jZS5sZW5ndGg7XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS5nZXRTeW1ib2xSYWRpdXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIDE1O1xufTtcblxuUG9seW1lci5wcm90b3R5cGUuc2hvd0hpZ2hsaWdodCA9IGZ1bmN0aW9uIChzaG93KSB7XG4gICAgaWYgKHNob3cgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5oaWdobGlnaHQuc2V0QXR0cmlidXRlKFwic3Ryb2tlLW9wYWNpdHlcIiwgXCIxXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcInN0cm9rZS1vcGFjaXR5XCIsIFwiMFwiKTtcbiAgICB9XG59O1xuXG5Qb2x5bWVyLm1pblhEaXN0ID0gMzA7XG5Qb2x5bWVyLnByb3RvdHlwZS5zZXRTdGlja1NjYWxlID0gZnVuY3Rpb24gKHNjYWxlLCBzdmdQKSB7XG4gICAgY29uc3Qgb2xkU2NhbGUgPSB0aGlzLnN0aWNrWm9vbTtcblxuICAgIC8vZGlzdCBmcm9tIGNlbnRyZVxuICAgIGNvbnN0IGR4ID0gKHRoaXMuaXggLSBzdmdQLngpO1xuICAgIGNvbnN0IGR5ID0gKHRoaXMuaXkgLSBzdmdQLnkpO1xuXG4gICAgLy8gbmV3IGRpc3QgZnJvbSBjZW50cmVcbiAgICBjb25zdCBueCA9IGR4ICogc2NhbGUgLyBvbGRTY2FsZTtcbiAgICBjb25zdCBueSA9IGR5ICogc2NhbGUgLyBvbGRTY2FsZTtcblxuICAgIC8vcmVxdWlyZWQgY2hhbmdlXG4gICAgY29uc3QgcnggPSBueCAtIGR4O1xuICAgIGxldCByeSA9IG55IC0gZHk7XG5cbiAgICBpZiAodGhpcy5yb3RhdGlvbiA9PT0gMCB8fCB0aGlzLnJvdGF0aW9uID09PSAxODApIHtcbiAgICAgICAgcnkgPSAwO1xuICAgIH1cblxuICAgIC8vbmV3IHBvc1xuICAgIGNvbnN0IHggPSB0aGlzLml4ICsgcng7XG4gICAgY29uc3QgeSA9IHRoaXMuaXkgKyByeTtcblxuICAgIHRoaXMuc3RpY2tab29tID0gc2NhbGU7XG4gICAgdGhpcy5zY2FsZSgpO1xuICAgIHRoaXMuc2V0UG9zaXRpb24oeCwgeSk7XG4gICAgdGhpcy5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTtcbn07XG5cblBvbHltZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHByb3RMZW5ndGggPSAodGhpcy5zaXplKSAqIHRoaXMuc3RpY2tab29tO1xuICAgIGlmICh0aGlzLmZvcm0gPT09IDEpIHtcbiAgICAgICAgY29uc3QgbGFiZWxUcmFuc2Zvcm0gPSBkMy50cmFuc2Zvcm0odGhpcy5sYWJlbFNWRy5nZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIikpO1xuICAgICAgICBjb25zdCBrID0gdGhpcy5hcHAuc3ZnRWxlbWVudC5jcmVhdGVTVkdNYXRyaXgoKS5yb3RhdGUobGFiZWxUcmFuc2Zvcm0ucm90YXRlKVxuICAgICAgICAgICAgLnRyYW5zbGF0ZSgoLSgoKHRoaXMuc2l6ZSAvIDIpICogdGhpcy5zdGlja1pvb20pICsgKHRoaXMublRlcm1pbnVzRmVhdHVyZSA/IDI1IDogMTApKSksIExBQkVMX1kpOyAvLy5zY2FsZSh6KS50cmFuc2xhdGUoLWMueCwgLWMueSk7XG4gICAgICAgIHRoaXMubGFiZWxTVkcudHJhbnNmb3JtLmJhc2VWYWwuaW5pdGlhbGl6ZSh0aGlzLmFwcC5zdmdFbGVtZW50LmNyZWF0ZVNWR1RyYW5zZm9ybUZyb21NYXRyaXgoaykpO1xuXG4gICAgICAgIGZvciAobGV0IFthbm5vdGF0aW9uVHlwZSwgYW5ub3RhdGlvbnNdIG9mIHRoaXMuYW5ub3RhdGlvblNldHMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFwcC5hbm5vdGF0aW9uU2V0c1Nob3duLmdldChhbm5vdGF0aW9uVHlwZSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBhbm5vIG9mIGFubm90YXRpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhbm5vLmZ1enp5U3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlTdGFydC5zZXRBdHRyaWJ1dGUoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblJlY3RQYXRoKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluQmVnaW4sIGFubm8uc2VxRGF0dW0uYmVnaW4sIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5jZXJ0YWluKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdGVtcEJlZ2luID0gYW5uby5zZXFEYXR1bS5iZWdpbjsgLy90b2RvIC0gbWlnaHQgYmUgYmV0dGVyIHRvIGhhdmUgc2VwZXJhdGUgYXR0IGluIFNlcXVlbmNlRGF0YSBmb3IgZW5kIG9mIHVuY2VydGFpbiBzdGFydFxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRlbXBFbmQgPSBhbm5vLnNlcURhdHVtLmVuZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbm5vLnNlcURhdHVtLnVuY2VydGFpbkJlZ2luKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcEJlZ2luICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRW5kIC09IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25SZWN0UGF0aCh0ZW1wQmVnaW4sIHRlbXBFbmQsIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eUVuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZC5zZXRBdHRyaWJ1dGUoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblJlY3RQYXRoKGFubm8uc2VxRGF0dW0uZW5kLCBhbm5vLnNlcURhdHVtLnVuY2VydGFpbkVuZCwgYW5ubykpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZDMuc2VsZWN0KHRoaXMuYmFja2dyb3VuZClcbiAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgcHJvdExlbmd0aClcbiAgICAgICAgICAgIC5hdHRyKFwieFwiLCB0aGlzLmdldFJlc1h3aXRoU3RpY2tab29tKDAuNSkpO1xuXG4gICAgICAgIGQzLnNlbGVjdCh0aGlzLm91dGxpbmUpXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIHByb3RMZW5ndGgpXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbSgwLjUpKTtcblxuICAgICAgICBkMy5zZWxlY3QodGhpcy5oaWdobGlnaHQpXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIHByb3RMZW5ndGggKyA1KVxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIHRoaXMuZ2V0UmVzWHdpdGhTdGlja1pvb20oMC41KSAtIDIuNSk7XG5cblxuICAgICAgICB0aGlzLnNldFNjYWxlR3JvdXAoKTtcbiAgICB9XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS5zZXRTY2FsZUdyb3VwID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudXBwZXJHcm91cC5hcHBlbmRDaGlsZCh0aGlzLnRpY2tzKTsgLy93aWxsIGRvIG5vdGhpbmcgaWYgdGhpcy50aWNrcyBhbHJlYWR5IGFwcGVuZGVkIHRvIHRoaXMudXBwZXJncm91cFxuICAgIGQzLnNlbGVjdCh0aGlzLnRpY2tzKS5zZWxlY3RBbGwoXCIqXCIpLnJlbW92ZSgpO1xuXG4gICAgdGhpcy5zY2FsZUxhYmVscyA9IFtdO1xuICAgIGNvbnN0IFNjYWxlVGlja3NQZXJMYWJlbCA9IDI7IC8vIHZhcmllcyB3aXRoIHNjYWxlP1xuICAgIGxldCB0aWNrID0gLTE7XG4gICAgY29uc3QgbGFzdFRpY2tYID0gdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbSh0aGlzLnNpemUpO1xuXG4gICAgZm9yIChsZXQgcmVzID0gMTsgcmVzIDw9IHRoaXMuc2l6ZTsgcmVzKyspIHtcbiAgICAgICAgaWYgKHJlcyA9PT0gMSB8fFxuICAgICAgICAgICAgKChyZXMgJSAxMDAgPT09IDApICYmICgyMDAgKiB0aGlzLnN0aWNrWm9vbSA+IFBvbHltZXIubWluWERpc3QpKSB8fFxuICAgICAgICAgICAgKChyZXMgJSAxMCA9PT0gMCkgJiYgKDIwICogdGhpcy5zdGlja1pvb20gPiBQb2x5bWVyLm1pblhEaXN0KSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBjb25zdCB0eCA9IHRoaXMuZ2V0UmVzWHdpdGhTdGlja1pvb20ocmVzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0aWNrWm9vbSA+PSA4IHx8IHJlcyAhPT0gMSkge1xuICAgICAgICAgICAgICAgIHRpY2tBdCh0aGlzLCB0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aWNrID0gKHRpY2sgKyAxKSAlIFNjYWxlVGlja3NQZXJMYWJlbDtcbiAgICAgICAgICAgIC8vIGRvZXMgdGhpcyBvbmUgZ2V0IGEgbGFiZWw/XG4gICAgICAgICAgICBpZiAodGljayA9PT0gMCkgeyAvLyAmJiB0eCA+IDIwKSB7XG4gICAgICAgICAgICAgICAgaWYgKCh0eCArIFBvbHltZXIubWluWERpc3QpIDwgbGFzdFRpY2tYKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjYWxlTGFiZWxBdCh0aGlzLCByZXMsIHR4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RpY2tab29tID49IDgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNlcUxhYmVsR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwiZ1wiKTtcbiAgICAgICAgICAgIHNlcUxhYmVsR3JvdXAuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbShyZXMpICsgXCIgXCIgKyAwICsgXCIpXCIpO1xuICAgICAgICAgICAgY29uc3Qgc2VxTGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwidGV4dFwiKTtcbiAgICAgICAgICAgIHNlcUxhYmVsLnNldEF0dHJpYnV0ZShcImZvbnQtZmFtaWx5XCIsIFwiJ0NvdXJpZXIgTmV3JywgbW9ub3NwYWNlXCIpO1xuICAgICAgICAgICAgc2VxTGFiZWwuc2V0QXR0cmlidXRlKFwiZm9udC1zaXplXCIsIFwiMTBweFwiKTtcbiAgICAgICAgICAgIHNlcUxhYmVsLnNldEF0dHJpYnV0ZShcInRleHQtYW5jaG9yXCIsIFwibWlkZGxlXCIpO1xuICAgICAgICAgICAgc2VxTGFiZWwuc2V0QXR0cmlidXRlKFwieFwiLCBcIjBcIik7XG4gICAgICAgICAgICBzZXFMYWJlbC5zZXRBdHRyaWJ1dGUoXCJ5XCIsIFwiM1wiKTtcbiAgICAgICAgICAgIHNlcUxhYmVsLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRoaXMuc2VxdWVuY2VbcmVzIC0gMV0pKTtcbiAgICAgICAgICAgIHNlcUxhYmVsR3JvdXAuYXBwZW5kQ2hpbGQoc2VxTGFiZWwpO1xuICAgICAgICAgICAgdGhpcy5zY2FsZUxhYmVscy5wdXNoKHNlcUxhYmVsKTtcbiAgICAgICAgICAgIHRoaXMudGlja3MuYXBwZW5kQ2hpbGQoc2VxTGFiZWxHcm91cCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2NhbGVMYWJlbEF0KHRoaXMsIHRoaXMuc2l6ZSwgbGFzdFRpY2tYKTtcbiAgICBpZiAodGhpcy5zdGlja1pvb20gPj0gOCkge1xuICAgICAgICB0aWNrQXQodGhpcywgbGFzdFRpY2tYKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzY2FsZUxhYmVsQXQoc2VsZiwgdGV4dCwgdGlja1gpIHtcbiAgICAgICAgY29uc3Qgc2NhbGVMYWJlbEdyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgICAgIHNjYWxlTGFiZWxHcm91cC5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyB0aWNrWCArIFwiIFwiICsgMCArIFwiKVwiKTtcbiAgICAgICAgY29uc3Qgc2NhbGVMYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJ0ZXh0XCIpO1xuICAgICAgICBzY2FsZUxhYmVsLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIFwieGx2X3RleHRcIik7XG4gICAgICAgIC8vIHNjYWxlTGFiZWwuc2V0QXR0cmlidXRlKFwiZm9udC1mYW1pbHlcIiwgXCInQ291cmllciBOZXcnLCBtb25vc3BhY2VcIik7XG4gICAgICAgIHNjYWxlTGFiZWwuc2V0QXR0cmlidXRlKFwiZm9udC1zaXplXCIsIFwiOHB0XCIpOyAvLyB0b2RvIGNzcy4uLlxuICAgICAgICBzY2FsZUxhYmVsLnNldEF0dHJpYnV0ZShcInRleHQtYW5jaG9yXCIsIFwibWlkZGxlXCIpO1xuICAgICAgICBzY2FsZUxhYmVsLnNldEF0dHJpYnV0ZShcInhcIiwgXCIwXCIpO1xuICAgICAgICBzY2FsZUxhYmVsLnNldEF0dHJpYnV0ZShcInlcIiwgUG9seW1lci5TVElDS0hFSUdIVCArIDQpO1xuICAgICAgICBzY2FsZUxhYmVsLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpKTtcbiAgICAgICAgc2NhbGVMYWJlbEdyb3VwLmFwcGVuZENoaWxkKHNjYWxlTGFiZWwpO1xuICAgICAgICBzZWxmLnNjYWxlTGFiZWxzLnB1c2goc2NhbGVMYWJlbCk7XG4gICAgICAgIHNlbGYudGlja3MuYXBwZW5kQ2hpbGQoc2NhbGVMYWJlbEdyb3VwKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0aWNrQXQoc2VsZiwgdGlja1gpIHtcbiAgICAgICAgY29uc3QgdGljayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJsaW5lXCIpO1xuICAgICAgICB0aWNrLnNldEF0dHJpYnV0ZShcIngxXCIsIHRpY2tYKTtcbiAgICAgICAgdGljay5zZXRBdHRyaWJ1dGUoXCJ5MVwiLCBcIjVcIik7XG4gICAgICAgIHRpY2suc2V0QXR0cmlidXRlKFwieDJcIiwgdGlja1gpO1xuICAgICAgICB0aWNrLnNldEF0dHJpYnV0ZShcInkyXCIsIFwiMTBcIik7XG4gICAgICAgIHRpY2suc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwiYmxhY2tcIik7XG4gICAgICAgIHNlbGYudGlja3MuYXBwZW5kQ2hpbGQodGljayk7XG4gICAgfVxufTtcblxuUG9seW1lci5wcm90b3R5cGUuc2V0Rm9ybSA9IGZ1bmN0aW9uIChmb3JtLCBzdmdQKSB7XG4gICAgaWYgKHRoaXMuYnVzeSAhPT0gdHJ1ZSkge1xuICAgICAgICBpZiAoZm9ybSA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuZm9ybSAhPT0gMSkge1xuICAgICAgICAgICAgICAgIHRoaXMudG9TdGljaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaWYgKHRoaXMuZm9ybSAhPT0gMCkge1xuICAgICAgICAgICAgdGhpcy50b0NpcmNsZShzdmdQKTtcbiAgICAgICAgICAgIC8vIHZhciByID0gdGhpcy5nZXRTeW1ib2xSYWRpdXMoKTtcblxuICAgICAgICB9XG4gICAgICAgIC8vIH1cbiAgICB9XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS50b0NpcmNsZSA9IGZ1bmN0aW9uIChzdmdQKSB7XG4gICAgLy9zdmdQID0gbnVsbDsvLyB0ZW1wIGhhY2sgLSB5b3UgY2FuIHVuY29tbWVudCB0aGlzIGlzIHlvdSBleHBlcmllbmNlIHRoaW5ncyAnZmx5aW5nIG9mZiBzY3JlZW4nXG4gICAgdGhpcy5idXN5ID0gdHJ1ZTtcblxuICAgIGNvbnN0IHIgPSB0aGlzLmdldFN5bWJvbFJhZGl1cygpO1xuICAgIC8vXG4gICAgZDMuc2VsZWN0KHRoaXMuYmFja2dyb3VuZCkudHJhbnNpdGlvbigpXG4gICAgICAgIC5hdHRyKFwieFwiLCAtcikuYXR0cihcInlcIiwgLXIpXG4gICAgICAgIC5hdHRyKFwid2lkdGhcIiwgciAqIDIpLmF0dHIoXCJoZWlnaHRcIiwgciAqIDIpXG4gICAgICAgIC5hdHRyKFwicnhcIiwgcikuYXR0cihcInJ5XCIsIHIpXG4gICAgICAgIC5kdXJhdGlvbihQb2x5bWVyLnRyYW5zaXRpb25UaW1lKTtcbiAgICBkMy5zZWxlY3QodGhpcy5vdXRsaW5lKS50cmFuc2l0aW9uKClcbiAgICAgICAgLmF0dHIoXCJ4XCIsIC1yKS5hdHRyKFwieVwiLCAtcilcbiAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCByICogMikuYXR0cihcImhlaWdodFwiLCByICogMilcbiAgICAgICAgLmF0dHIoXCJyeFwiLCByKS5hdHRyKFwicnlcIiwgcilcbiAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuICAgIC8vIGQzLnNlbGVjdCh0aGlzLmFubm90YXRpb25zU3ZnR3JvdXApLnRyYW5zaXRpb24oKVxuICAgIC8vICAgICAuYXR0cihcInRyYW5zZm9ybVwiLCBcInNjYWxlKDEsIDEpXCIpXG4gICAgLy8gICAgIC5kdXJhdGlvbihQb2x5bWVyLnRyYW5zaXRpb25UaW1lKTtcbiAgICBkMy5zZWxlY3QodGhpcy5oaWdobGlnaHQpLnRyYW5zaXRpb24oKVxuICAgICAgICAuYXR0cihcInhcIiwgLXIpLmF0dHIoXCJ5XCIsIC1yKVxuICAgICAgICAuYXR0cihcIndpZHRoXCIsIHIgKiAyKS5hdHRyKFwiaGVpZ2h0XCIsIHIgKiAyKVxuICAgICAgICAuYXR0cihcInJ4XCIsIHIpLmF0dHIoXCJyeVwiLCByKVxuICAgICAgICAuZHVyYXRpb24oUG9seW1lci50cmFuc2l0aW9uVGltZSk7XG5cbiAgICBjb25zdCBzdGlja1pvb21JbnRlcnBvbCA9IGQzLmludGVycG9sYXRlKHRoaXMuc3RpY2tab29tLCAwKTtcbiAgICAvLyB2YXIgcm90YXRpb25JbnRlcnBvbCA9IGQzLmludGVycG9sYXRlKCh0aGlzLnJvdGF0aW9uID4gMTgwKSA/IHRoaXMucm90YXRpb24gLSAzNjAgOiB0aGlzLnJvdGF0aW9uLCAwKTtcbiAgICBjb25zdCBsYWJlbFRyYW5zZm9ybSA9IGQzLnRyYW5zZm9ybSh0aGlzLmxhYmVsU1ZHLmdldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiKSk7XG4gICAgY29uc3QgbGFiZWxTdGFydFBvaW50ID0gbGFiZWxUcmFuc2Zvcm0udHJhbnNsYXRlWzBdO1xuICAgIGNvbnN0IGxhYmVsVHJhbnNsYXRlSW50ZXJwb2wgPSBkMy5pbnRlcnBvbGF0ZShsYWJlbFN0YXJ0UG9pbnQsIC0ociArIDUpKTtcblxuICAgIGxldCB4SW50ZXJwb2wgPSBudWxsLFxuICAgICAgICB5SW50ZXJwb2wgPSBudWxsO1xuICAgIGlmICh0eXBlb2Ygc3ZnUCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBzdmdQICE9PSBudWxsKSB7XG4gICAgICAgIHhJbnRlcnBvbCA9IGQzLmludGVycG9sYXRlKHRoaXMuaXgsIHN2Z1AueCk7XG4gICAgICAgIHlJbnRlcnBvbCA9IGQzLmludGVycG9sYXRlKHRoaXMuaXksIHN2Z1AueSk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgZDMuc2VsZWN0KHRoaXMudGlja3MpLnRyYW5zaXRpb24oKS5hdHRyKFwib3BhY2l0eVwiLCAwKS5kdXJhdGlvbihQb2x5bWVyLnRyYW5zaXRpb25UaW1lIC8gNClcbiAgICAgICAgLmVhY2goXCJlbmRcIixcbiAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBkMy5zZWxlY3QodGhpcykuc2VsZWN0QWxsKFwiKlwiKS5yZW1vdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgKTtcblxuICAgIGQzLnNlbGVjdCh0aGlzLmhpZ2hsaWdodCkudHJhbnNpdGlvbigpXG4gICAgICAgIC5hdHRyKFwid2lkdGhcIiwgKHIgKiAyKSArIDUpLmF0dHIoXCJoZWlnaHRcIiwgKHIgKiAyKSArIDUpXG4gICAgICAgIC5hdHRyKFwieFwiLCAtciAtIDIuNSkuYXR0cihcInlcIiwgLXIgLSAyLjUpXG4gICAgICAgIC5hdHRyKFwicnhcIiwgciArIDIuNSkuYXR0cihcInJ5XCIsIHIgKyAyLjUpXG4gICAgICAgIC5kdXJhdGlvbihQb2x5bWVyLnRyYW5zaXRpb25UaW1lKTtcblxuICAgIGZ1bmN0aW9uIGNoYW5nZUZ1enp5U3RhcnRUb0FyY1BhdGgoYW5ubykge1xuICAgICAgICBkMy5zZWxlY3QoYW5uby5mdXp6eVN0YXJ0KS5hdHRyKFwiZFwiLCBzZWxmLmdldEFubm90YXRpb25QaWVTbGljZUFyY1BhdGgoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5CZWdpbiwgYW5uby5zZXFEYXR1bS5iZWdpbiwgYW5ubykpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNoYW5nZUNlcnRhaW5Ub0FyY1BhdGgoYW5ubykge1xuICAgICAgICBkMy5zZWxlY3QoYW5uby5jZXJ0YWluKS5hdHRyKFwiZFwiLCBzZWxmLmdldEFubm90YXRpb25QaWVTbGljZUFyY1BhdGgoYW5uby5zZXFEYXR1bS5iZWdpbiwgYW5uby5zZXFEYXR1bS5lbmQsIGFubm8pKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGFuZ2VGdXp6eUVuZFRvQXJjUGF0aChhbm5vKSB7XG4gICAgICAgIGQzLnNlbGVjdChhbm5vLmZ1enp5RW5kKS5hdHRyKFwiZFwiLCBzZWxmLmdldEFubm90YXRpb25QaWVTbGljZUFyY1BhdGgoYW5uby5zZXFEYXR1bS5lbmQsIGFubm8uc2VxRGF0dW0udW5jZXJ0YWluRW5kLCBhbm5vKSk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgW2Fubm90YXRpb25UeXBlLCBhbm5vdGF0aW9uc10gb2YgdGhpcy5hbm5vdGF0aW9uU2V0cykge1xuICAgICAgICBpZiAodGhpcy5hcHAuYW5ub3RhdGlvblNldHNTaG93bi5nZXQoYW5ub3RhdGlvblR5cGUpID09PSB0cnVlKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBhbm5vIG9mIGFubm90YXRpb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFubm8uZnV6enlTdGFydCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmdXp6eVN0YXJ0ID0gYW5uby5mdXp6eVN0YXJ0O1xuICAgICAgICAgICAgICAgICAgICBkMy5zZWxlY3QoZnV6enlTdGFydCkudHJhbnNpdGlvbigpLmF0dHIoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblBpZVNsaWNlQXBwcm94aW1hdGVQYXRoKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluQmVnaW4sIGFubm8uc2VxRGF0dW0uYmVnaW4sIGFubm8pKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpLmVhY2goXCJlbmRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VGdXp6eVN0YXJ0VG9BcmNQYXRoKGFubm8pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChhbm5vLmNlcnRhaW4pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2VydGFpbiA9IGFubm8uY2VydGFpbjtcbiAgICAgICAgICAgICAgICAgICAgZDMuc2VsZWN0KGNlcnRhaW4pLnRyYW5zaXRpb24oKS5hdHRyKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25QaWVTbGljZUFwcHJveGltYXRlUGF0aChhbm5vLnNlcURhdHVtLmJlZ2luLCBhbm5vLnNlcURhdHVtLmVuZCwgYW5ubykpXG4gICAgICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oUG9seW1lci50cmFuc2l0aW9uVGltZSkuZWFjaChcImVuZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUNlcnRhaW5Ub0FyY1BhdGgoYW5ubyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGFubm8uZnV6enlFbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnV6enlFbmQgPSBhbm5vLmZ1enp5RW5kO1xuICAgICAgICAgICAgICAgICAgICBkMy5zZWxlY3QoZnV6enlFbmQpLnRyYW5zaXRpb24oKS5hdHRyKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25QaWVTbGljZUFwcHJveGltYXRlUGF0aChhbm5vLnNlcURhdHVtLmVuZCwgYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQsIGFubm8pKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpLmVhY2goXCJlbmRcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2VGdXp6eUVuZFRvQXJjUGF0aChhbm5vKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBvcmlnaW5hbFN0aWNrWm9vbSA9IHRoaXMuc3RpY2tab29tO1xuICAgIGNvbnN0IG9yaWdpbmFsUm90YXRpb24gPSB0aGlzLnJvdGF0aW9uO1xuICAgIGNvbnN0IGN1YmljSW5PdXQgPSBkMy5lYXNlKFwiY3ViaWMtaW4tb3V0XCIpO1xuICAgIGQzLnRpbWVyKGZ1bmN0aW9uIChlbGFwc2VkKSB7XG4gICAgICAgIHJldHVybiB1cGRhdGUoZWxhcHNlZCAvIFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gdXBkYXRlKGludGVycCkge1xuICAgICAgICBjb25zdCBsYWJlbFRyYW5zZm9ybSA9IGQzLnRyYW5zZm9ybShzZWxmLmxhYmVsU1ZHLmdldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiKSk7XG4gICAgICAgIGNvbnN0IGsgPSBzZWxmLmFwcC5zdmdFbGVtZW50LmNyZWF0ZVNWR01hdHJpeCgpLnJvdGF0ZShsYWJlbFRyYW5zZm9ybS5yb3RhdGUpLnRyYW5zbGF0ZShsYWJlbFRyYW5zbGF0ZUludGVycG9sKGN1YmljSW5PdXQoaW50ZXJwKSksIExBQkVMX1kpOyAvLy5zY2FsZSh6KS50cmFuc2xhdGUoLWMueCwgLWMueSk7XG4gICAgICAgIHNlbGYubGFiZWxTVkcudHJhbnNmb3JtLmJhc2VWYWwuaW5pdGlhbGl6ZShzZWxmLmFwcC5zdmdFbGVtZW50LmNyZWF0ZVNWR1RyYW5zZm9ybUZyb21NYXRyaXgoaykpO1xuICAgICAgICAvL35cbiAgICAgICAgaWYgKHhJbnRlcnBvbCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgc2VsZi5zZXRQb3NpdGlvbih4SW50ZXJwb2woY3ViaWNJbk91dChpbnRlcnApKSwgeUludGVycG9sKGN1YmljSW5PdXQoaW50ZXJwKSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VsZi5zdGlja1pvb20gPSBzdGlja1pvb21JbnRlcnBvbChjdWJpY0luT3V0KGludGVycCkpO1xuICAgICAgICBzZWxmLnNldEFsbExpbmtDb29yZGluYXRlcygpO1xuXG4gICAgICAgIGlmIChpbnRlcnAgPT09IDEpIHsgLy8gZmluaXNoZWQgLSB0aWR5IHVwXG4gICAgICAgICAgICBzZWxmLmZvcm0gPSAwO1xuICAgICAgICAgICAgc2VsZi5jaGVja0xpbmtzKCk7XG4gICAgICAgICAgICBzZWxmLnN0aWNrWm9vbSA9IG9yaWdpbmFsU3RpY2tab29tO1xuICAgICAgICAgICAgc2VsZi5yb3RhdGlvbiA9IG9yaWdpbmFsUm90YXRpb247XG4gICAgICAgICAgICBzZWxmLmJ1c3kgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKGludGVycCA+IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB1cGRhdGUoMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS50b1N0aWNrID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYnVzeSA9IHRydWU7XG4gICAgdGhpcy5mb3JtID0gMTtcblxuICAgIC8vcmVtb3ZlIHByb3QtcHJvdCBsaW5rcyAtIHdvdWxkIGl0IGJlIGJldHRlciBpZiBjaGVja0xpbmtzIGRpZCB0aGlzPyAtIHRoaW5rIG5vdFxuICAgIGNvbnN0IGMgPSB0aGlzLmJpbmFyeUxpbmtzLnZhbHVlcygpLmxlbmd0aDtcbiAgICBmb3IgKGxldCBsID0gMDsgbCA8IGM7IGwrKykge1xuICAgICAgICBjb25zdCBsaW5rID0gdGhpcy5iaW5hcnlMaW5rcy52YWx1ZXMoKVtsXTtcbiAgICAgICAgLy9vdXQgd2l0aCB0aGUgb2xkXG4gICAgICAgIGlmIChsaW5rLnNob3duKSB7XG4gICAgICAgICAgICBsaW5rLmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHByb3RMZW5ndGggPSB0aGlzLnNpemUgKiB0aGlzLnN0aWNrWm9vbTtcbiAgICBjb25zdCByID0gdGhpcy5nZXRTeW1ib2xSYWRpdXMoKTtcblxuICAgIGNvbnN0IGxlbmd0aEludGVycG9sID0gZDMuaW50ZXJwb2xhdGUoKDIgKiByKSwgcHJvdExlbmd0aCk7XG4gICAgY29uc3Qgc3RpY2tab29tSW50ZXJwb2wgPSBkMy5pbnRlcnBvbGF0ZSgwLCB0aGlzLnN0aWNrWm9vbSk7XG4gICAgY29uc3QgbGFiZWxUcmFuc2xhdGVJbnRlcnBvbCA9IGQzLmludGVycG9sYXRlKC0ociArIDUpLCAtKCgodGhpcy5zaXplIC8gMikgKiB0aGlzLnN0aWNrWm9vbSkgKyAodGhpcy5uVGVybWludXNGZWF0dXJlID8gMjUgOiAxMCkpKTtcblxuICAgIGNvbnN0IG9yaWdTdGlja1pvb20gPSB0aGlzLnN0aWNrWm9vbTtcbiAgICB0aGlzLnN0aWNrWm9vbSA9IDA7XG4gICAgdGhpcy5jaGVja0xpbmtzKHRoaXMuYmluYXJ5TGlua3MpO1xuICAgIHRoaXMuY2hlY2tMaW5rcyh0aGlzLnNlbGZMaW5rKTtcbiAgICB0aGlzLmNoZWNrTGlua3ModGhpcy5zZXF1ZW5jZUxpbmtzKTtcbiAgICB0aGlzLnN0aWNrWm9vbSA9IG9yaWdTdGlja1pvb207XG5cbiAgICBkMy5zZWxlY3QodGhpcy5iYWNrZ3JvdW5kKS50cmFuc2l0aW9uKCkgLy8uYXR0cihcInN0cm9rZS1vcGFjaXR5XCIsIDEpXG4gICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIFBvbHltZXIuU1RJQ0tIRUlHSFQpXG4gICAgICAgIC5hdHRyKFwieVwiLCAtUG9seW1lci5TVElDS0hFSUdIVCAvIDIpXG4gICAgICAgIC5hdHRyKFwicnhcIiwgMCkuYXR0cihcInJ5XCIsIDApXG4gICAgICAgIC5kdXJhdGlvbihQb2x5bWVyLnRyYW5zaXRpb25UaW1lKTtcblxuICAgIGQzLnNlbGVjdCh0aGlzLm91dGxpbmUpLnRyYW5zaXRpb24oKSAvLy5hdHRyKFwic3Ryb2tlLW9wYWNpdHlcIiwgMSlcbiAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgUG9seW1lci5TVElDS0hFSUdIVClcbiAgICAgICAgLmF0dHIoXCJ5XCIsIC1Qb2x5bWVyLlNUSUNLSEVJR0hUIC8gMilcbiAgICAgICAgLmF0dHIoXCJyeFwiLCAwKS5hdHRyKFwicnlcIiwgMClcbiAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuXG4gICAgZDMuc2VsZWN0KHRoaXMuaGlnaGxpZ2h0KS50cmFuc2l0aW9uKClcbiAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBwcm90TGVuZ3RoICsgNSkuYXR0cihcImhlaWdodFwiLCBQb2x5bWVyLlNUSUNLSEVJR0hUICsgNSlcbiAgICAgICAgLmF0dHIoXCJ4XCIsIHRoaXMuZ2V0UmVzWHdpdGhTdGlja1pvb20oMC41KSAtIDIuNSkuYXR0cihcInlcIiwgKC1Qb2x5bWVyLlNUSUNLSEVJR0hUIC8gMikgLSAyLjUpXG4gICAgICAgIC5hdHRyKFwicnhcIiwgMCkuYXR0cihcInJ5XCIsIDApXG4gICAgICAgIC5kdXJhdGlvbihQb2x5bWVyLnRyYW5zaXRpb25UaW1lKTtcblxuICAgIGZvciAobGV0IFthbm5vdGF0aW9uVHlwZSwgYW5ub3RhdGlvbnNdIG9mIHRoaXMuYW5ub3RhdGlvblNldHMpIHtcbiAgICAgICAgaWYgKHRoaXMuYXBwLmFubm90YXRpb25TZXRzU2hvd24uZ2V0KGFubm90YXRpb25UeXBlKSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgZm9yIChsZXQgYW5ubyBvZiBhbm5vdGF0aW9ucykge1xuICAgICAgICAgICAgICAgIGlmIChhbm5vLmZ1enp5U3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnV6enlTdGFydCA9IGFubm8uZnV6enlTdGFydDtcbiAgICAgICAgICAgICAgICAgICAgZnV6enlTdGFydC5zZXRBdHRyaWJ1dGUoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblBpZVNsaWNlQXBwcm94aW1hdGVQYXRoKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluQmVnaW4sIGFubm8uc2VxRGF0dW0uYmVnaW4sIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgZDMuc2VsZWN0KGZ1enp5U3RhcnQpLnRyYW5zaXRpb24oKS5hdHRyKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25SZWN0UGF0aChhbm5vLnNlcURhdHVtLnVuY2VydGFpbkJlZ2luLCBhbm5vLnNlcURhdHVtLmJlZ2luLCBhbm5vKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbihQb2x5bWVyLnRyYW5zaXRpb25UaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGFubm8uY2VydGFpbikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjZXJ0YWluID0gYW5uby5jZXJ0YWluO1xuICAgICAgICAgICAgICAgICAgICBsZXQgdGVtcEJlZ2luID0gYW5uby5zZXFEYXR1bS5iZWdpbjsgLy90b2RvIC0gbWlnaHQgYmUgYmV0dGVyIHRvIGhhdmUgc2VwZXJhdGUgYXR0IGluIFNlcXVlbmNlRGF0YSBmb3IgZW5kIG9mIHVuY2VydGFpbiBzdGFydFxuICAgICAgICAgICAgICAgICAgICBsZXQgdGVtcEVuZCA9IGFubm8uc2VxRGF0dW0uZW5kO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5CZWdpbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVtcEJlZ2luICs9IDE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluRW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRW5kIC09IDE7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjZXJ0YWluLnNldEF0dHJpYnV0ZShcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUGllU2xpY2VBcHByb3hpbWF0ZVBhdGgodGVtcEJlZ2luLCB0ZW1wRW5kLCBhbm5vKSk7XG4gICAgICAgICAgICAgICAgICAgIGQzLnNlbGVjdChjZXJ0YWluKS50cmFuc2l0aW9uKCkuYXR0cihcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUmVjdFBhdGgodGVtcEJlZ2luLCB0ZW1wRW5kLCBhbm5vKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbihQb2x5bWVyLnRyYW5zaXRpb25UaW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGFubm8uZnV6enlFbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnV6enlFbmQgPSBhbm5vLmZ1enp5RW5kO1xuICAgICAgICAgICAgICAgICAgICBmdXp6eUVuZC5zZXRBdHRyaWJ1dGUoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblBpZVNsaWNlQXBwcm94aW1hdGVQYXRoKGFubm8uc2VxRGF0dW0uZW5kLCBhbm5vLnNlcURhdHVtLnVuY2VydGFpbkVuZCwgYW5ubykpO1xuICAgICAgICAgICAgICAgICAgICBkMy5zZWxlY3QoZnV6enlFbmQpLnRyYW5zaXRpb24oKS5hdHRyKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25SZWN0UGF0aChhbm5vLnNlcURhdHVtLmVuZCwgYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQsIGFubm8pKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGNvbnN0IGN1YmljSW5PdXQgPSBkMy5lYXNlKFwiY3ViaWMtaW4tb3V0XCIpO1xuICAgIGQzLnRpbWVyKGZ1bmN0aW9uIChlbGFwc2VkKSB7XG4gICAgICAgIHJldHVybiB1cGRhdGUoZWxhcHNlZCAvIFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gdXBkYXRlKGludGVycCkge1xuICAgICAgICBjb25zdCBsYWJlbFRyYW5zZm9ybSA9IGQzLnRyYW5zZm9ybShzZWxmLmxhYmVsU1ZHLmdldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiKSk7XG4gICAgICAgIGNvbnN0IGsgPSBzZWxmLmFwcC5zdmdFbGVtZW50LmNyZWF0ZVNWR01hdHJpeCgpLnJvdGF0ZShsYWJlbFRyYW5zZm9ybS5yb3RhdGUpLnRyYW5zbGF0ZShsYWJlbFRyYW5zbGF0ZUludGVycG9sKGN1YmljSW5PdXQoaW50ZXJwKSksIExBQkVMX1kpOyAvLy5zY2FsZSh6KS50cmFuc2xhdGUoLWMueCwgLWMueSk7XG4gICAgICAgIHNlbGYubGFiZWxTVkcudHJhbnNmb3JtLmJhc2VWYWwuaW5pdGlhbGl6ZShzZWxmLmFwcC5zdmdFbGVtZW50LmNyZWF0ZVNWR1RyYW5zZm9ybUZyb21NYXRyaXgoaykpO1xuXG4gICAgICAgIGNvbnN0IGN1cnJlbnRMZW5ndGggPSBsZW5ndGhJbnRlcnBvbChjdWJpY0luT3V0KGludGVycCkpO1xuICAgICAgICBkMy5zZWxlY3Qoc2VsZi5oaWdobGlnaHQpLmF0dHIoXCJ3aWR0aFwiLCBjdXJyZW50TGVuZ3RoKS5hdHRyKFwieFwiLCAtKGN1cnJlbnRMZW5ndGggLyAyKSArICgwLjUgKiBzZWxmLnN0aWNrWm9vbSkpO1xuICAgICAgICBkMy5zZWxlY3Qoc2VsZi5vdXRsaW5lKS5hdHRyKFwid2lkdGhcIiwgY3VycmVudExlbmd0aCkuYXR0cihcInhcIiwgLShjdXJyZW50TGVuZ3RoIC8gMikgKyAoMC41ICogc2VsZi5zdGlja1pvb20pKTtcbiAgICAgICAgZDMuc2VsZWN0KHNlbGYuYmFja2dyb3VuZCkuYXR0cihcIndpZHRoXCIsIGN1cnJlbnRMZW5ndGgpLmF0dHIoXCJ4XCIsIC0oY3VycmVudExlbmd0aCAvIDIpICsgKDAuNSAqIHNlbGYuc3RpY2tab29tKSk7XG4gICAgICAgIHNlbGYuc3RpY2tab29tID0gc3RpY2tab29tSW50ZXJwb2woY3ViaWNJbk91dChpbnRlcnApKTtcbiAgICAgICAgc2VsZi5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTtcblxuICAgICAgICBpZiAoaW50ZXJwID09PSAxKSB7IC8vIGZpbmlzaGVkIC0gdGlkeSB1cFxuICAgICAgICAgICAgc2VsZi5idXN5ID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChpbnRlcnAgPiAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdXBkYXRlKDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZDMuc2VsZWN0KHRoaXMudGlja3MpLmF0dHIoXCJvcGFjaXR5XCIsIDApO1xuICAgIHRoaXMuc2V0U2NhbGVHcm91cCgpO1xuICAgIGQzLnNlbGVjdCh0aGlzLnRpY2tzKS50cmFuc2l0aW9uKCkuYXR0cihcIm9wYWNpdHlcIiwgMSlcbiAgICAgICAgLmRlbGF5KFBvbHltZXIudHJhbnNpdGlvblRpbWUgKiAwLjgpLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUgLyAyKTtcbn07XG5cblxuUG9seW1lci5wcm90b3R5cGUudG9TdGlja05vVHJhbnNpdGlvbiA9IGZ1bmN0aW9uICgpIHsgLy90b2RvIHRpZHlcbiAgICB0aGlzLmJ1c3kgPSB0cnVlO1xuICAgIHRoaXMuZm9ybSA9IDE7XG5cbiAgICAvL3JlbW92ZSBwcm90LXByb3QgbGlua3MgLSB3b3VsZCBpdCBiZSBiZXR0ZXIgaWYgY2hlY2tMaW5rcyBkaWQgdGhpcz8gLSB0aGluayBub3RcbiAgICBjb25zdCBjID0gdGhpcy5iaW5hcnlMaW5rcy52YWx1ZXMoKS5sZW5ndGg7XG4gICAgZm9yIChsZXQgbCA9IDA7IGwgPCBjOyBsKyspIHtcbiAgICAgICAgY29uc3QgbGluayA9IHRoaXMuYmluYXJ5TGlua3MudmFsdWVzKClbbF07XG4gICAgICAgIC8vb3V0IHdpdGggdGhlIG9sZFxuICAgICAgICBpZiAobGluay5zaG93bikge1xuICAgICAgICAgICAgbGluay5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBwcm90TGVuZ3RoID0gdGhpcy5zaXplICogdGhpcy5zdGlja1pvb207XG4gICAgY29uc3QgciA9IHRoaXMuZ2V0U3ltYm9sUmFkaXVzKCk7XG5cbiAgICBjb25zdCBsZW5ndGhJbnRlcnBvbCA9IGQzLmludGVycG9sYXRlKCgyICogciksIHByb3RMZW5ndGgpO1xuICAgIGNvbnN0IGxhYmVsVHJhbnNsYXRlSW50ZXJwb2wgPSBkMy5pbnRlcnBvbGF0ZSgtKHIgKyA1KSwgLSgoKHRoaXMuc2l6ZSAvIDIpICogdGhpcy5zdGlja1pvb20pICsgKHRoaXMublRlcm1pbnVzRmVhdHVyZSA/IDI1IDogMTApKSk7XG5cbiAgICB0aGlzLmNoZWNrTGlua3ModGhpcy5iaW5hcnlMaW5rcyk7XG4gICAgdGhpcy5jaGVja0xpbmtzKHRoaXMuc2VsZkxpbmspO1xuICAgIHRoaXMuY2hlY2tMaW5rcyh0aGlzLnNlcXVlbmNlTGlua3MpO1xuXG4gICAgZDMuc2VsZWN0KHRoaXMuYmFja2dyb3VuZClcbiAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgUG9seW1lci5TVElDS0hFSUdIVClcbiAgICAgICAgLmF0dHIoXCJ5XCIsIC1Qb2x5bWVyLlNUSUNLSEVJR0hUIC8gMilcbiAgICAgICAgLmF0dHIoXCJyeFwiLCAwKS5hdHRyKFwicnlcIiwgMCk7XG5cbiAgICBkMy5zZWxlY3QodGhpcy5vdXRsaW5lKVxuICAgICAgICAuYXR0cihcImhlaWdodFwiLCBQb2x5bWVyLlNUSUNLSEVJR0hUKVxuICAgICAgICAuYXR0cihcInlcIiwgLVBvbHltZXIuU1RJQ0tIRUlHSFQgLyAyKVxuICAgICAgICAuYXR0cihcInJ4XCIsIDApLmF0dHIoXCJyeVwiLCAwKTtcblxuICAgIGQzLnNlbGVjdCh0aGlzLmhpZ2hsaWdodClcbiAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBwcm90TGVuZ3RoICsgNSkuYXR0cihcImhlaWdodFwiLCBQb2x5bWVyLlNUSUNLSEVJR0hUICsgNSlcbiAgICAgICAgLmF0dHIoXCJ4XCIsIHRoaXMuZ2V0UmVzWHdpdGhTdGlja1pvb20oMC41KSAtIDIuNSkuYXR0cihcInlcIiwgKC1Qb2x5bWVyLlNUSUNLSEVJR0hUIC8gMikgLSAyLjUpXG4gICAgICAgIC5hdHRyKFwicnhcIiwgMCkuYXR0cihcInJ5XCIsIDApO1xuXG4gICAgZm9yIChsZXQgW2Fubm90YXRpb25UeXBlLCBhbm5vdGF0aW9uc10gb2YgdGhpcy5hbm5vdGF0aW9uU2V0cykge1xuICAgICAgICBpZiAodGhpcy5hcHAuYW5ub3RhdGlvblNldHNTaG93bi5nZXQoYW5ub3RhdGlvblR5cGUpID09PSB0cnVlKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBhbm5vIG9mIGFubm90YXRpb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFubm8uZnV6enlTdGFydCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmdXp6eVN0YXJ0ID0gYW5uby5mdXp6eVN0YXJ0O1xuICAgICAgICAgICAgICAgICAgICBkMy5zZWxlY3QoZnV6enlTdGFydCkuYXR0cihcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUmVjdFBhdGgoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5CZWdpbiwgYW5uby5zZXFEYXR1bS5iZWdpbiwgYW5ubykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYW5uby5jZXJ0YWluKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB0ZW1wQmVnaW4gPSBhbm5vLnNlcURhdHVtLmJlZ2luOyAvL3RvZG8gLSBtaWdodCBiZSBiZXR0ZXIgdG8gaGF2ZSBzZXBlcmF0ZSBhdHQgaW4gU2VxdWVuY2VEYXRhIGZvciBlbmQgb2YgdW5jZXJ0YWluIHN0YXJ0XG4gICAgICAgICAgICAgICAgICAgIGxldCB0ZW1wRW5kID0gYW5uby5zZXFEYXR1bS5lbmQ7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhbm5vLnNlcURhdHVtLnVuY2VydGFpbkJlZ2luKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wQmVnaW4gKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBFbmQgLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25SZWN0UGF0aCh0ZW1wQmVnaW4sIHRlbXBFbmQsIGFubm8pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGFubm8uZnV6enlFbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZnV6enlFbmQgPSBhbm5vLmZ1enp5RW5kO1xuICAgICAgICAgICAgICAgICAgICBkMy5zZWxlY3QoZnV6enlFbmQpIC8qLnRyYW5zaXRpb24oKSovIC5hdHRyKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25SZWN0UGF0aChhbm5vLnNlcURhdHVtLmVuZCwgYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQsIGFubm8pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGNvbnN0IGxhYmVsVHJhbnNmb3JtID0gZDMudHJhbnNmb3JtKHNlbGYubGFiZWxTVkcuZ2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIpKTtcbiAgICBjb25zdCBrID0gc2VsZi5hcHAuc3ZnRWxlbWVudC5jcmVhdGVTVkdNYXRyaXgoKS5yb3RhdGUobGFiZWxUcmFuc2Zvcm0ucm90YXRlKS50cmFuc2xhdGUobGFiZWxUcmFuc2xhdGVJbnRlcnBvbCgxKSwgTEFCRUxfWSk7IC8vLnNjYWxlKHopLnRyYW5zbGF0ZSgtYy54LCAtYy55KTtcbiAgICBzZWxmLmxhYmVsU1ZHLnRyYW5zZm9ybS5iYXNlVmFsLmluaXRpYWxpemUoc2VsZi5hcHAuc3ZnRWxlbWVudC5jcmVhdGVTVkdUcmFuc2Zvcm1Gcm9tTWF0cml4KGspKTtcblxuICAgIGNvbnN0IGN1cnJlbnRMZW5ndGggPSBsZW5ndGhJbnRlcnBvbCgxKTtcbiAgICBkMy5zZWxlY3Qoc2VsZi5oaWdobGlnaHQpLmF0dHIoXCJ3aWR0aFwiLCBjdXJyZW50TGVuZ3RoKS5hdHRyKFwieFwiLCAtKGN1cnJlbnRMZW5ndGggLyAyKSArICgwLjUgKiBzZWxmLnN0aWNrWm9vbSkpO1xuICAgIGQzLnNlbGVjdChzZWxmLm91dGxpbmUpLmF0dHIoXCJ3aWR0aFwiLCBjdXJyZW50TGVuZ3RoKS5hdHRyKFwieFwiLCAtKGN1cnJlbnRMZW5ndGggLyAyKSArICgwLjUgKiBzZWxmLnN0aWNrWm9vbSkpO1xuICAgIGQzLnNlbGVjdChzZWxmLmJhY2tncm91bmQpLmF0dHIoXCJ3aWR0aFwiLCBjdXJyZW50TGVuZ3RoKS5hdHRyKFwieFwiLCAtKGN1cnJlbnRMZW5ndGggLyAyKSArICgwLjUgKiBzZWxmLnN0aWNrWm9vbSkpO1xuICAgIHNlbGYuc2V0QWxsTGlua0Nvb3JkaW5hdGVzKCk7XG5cbiAgICB0aGlzLnNldFNjYWxlR3JvdXAoKTtcbiAgICBkMy5zZWxlY3QodGhpcy50aWNrcykuYXR0cihcIm9wYWNpdHlcIiwgMSk7XG5cbiAgICBzZWxmLmJ1c3kgPSBmYWxzZTtcbn07XG5cblBvbHltZXIucHJvdG90eXBlLmdldFJlc1h3aXRoU3RpY2tab29tID0gZnVuY3Rpb24gKHIpIHtcbiAgICAvLyBpZiAoaXNOYU4ocikpIHtcbiAgICAvLyAgICAgY29uc29sZS5lcnJvcihcIk5PVCBOVU1CRVJcIik7XG4gICAgLy8gfVxuICAgIGlmIChyID09PSBcIm4tblwiKSB7XG4gICAgICAgIHJldHVybiAoLXRoaXMuc2l6ZSAvIDIgKiB0aGlzLnN0aWNrWm9vbSkgLSAyMDtcbiAgICB9IGVsc2UgaWYgKHIgPT09IFwiYy1jXCIpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnNpemUgLyAyICogdGhpcy5zdGlja1pvb20pICsgMjA7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIChyIC0gKHRoaXMuc2l6ZSAvIDIpKSAqIHRoaXMuc3RpY2tab29tO1xuICAgIH1cbn07XG5cbi8vY2FsY3VsYXRlIHRoZSAgY29vcmRpbmF0ZXMgb2YgYSByZXNpZHVlIChyZWxhdGl2ZSB0byB0aGlzLnV0aWwuY29udGFpbmVyKVxuUG9seW1lci5wcm90b3R5cGUuZ2V0UmVzaWR1ZUNvb3JkaW5hdGVzID0gZnVuY3Rpb24gKHIsIHlPZmYpIHtcbiAgICBpZiAodHlwZW9mIHIgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkVSUk9SOiByZXNpZHVlIG51bWJlciBpcyB1bmRlZmluZWRcIik7XG4gICAgfVxuICAgIGxldCB4ID0gdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbShyICogMSk7Ly8gKiB0aGlzLmFwcC56O1xuICAgIC8vIGNvbnNvbGUubG9nKFwiKioqXCIsIHRoaXMuYXBwLnopO1xuICAgIC8vIGNveiBwcm90cyBkb24ndCBzY2FsZSwgZG9uJ3QgbXVsdGlwbGUgYnkgYXBwLnpcbiAgICBsZXQgeTtcbiAgICBpZiAoeCAhPT0gMCkge1xuICAgICAgICBjb25zdCBsID0gTWF0aC5hYnMoeCk7XG4gICAgICAgIGNvbnN0IGEgPSBNYXRoLmFjb3MoeCAvIGwpO1xuICAgICAgICBjb25zdCByb3RSYWQgPSAodGhpcy5yb3RhdGlvbiAvIDM2MCkgKiBNYXRoLlBJICogMjtcbiAgICAgICAgeCA9IGwgKiBNYXRoLmNvcyhyb3RSYWQgKyBhKTtcbiAgICAgICAgeSA9IGwgKiBNYXRoLnNpbihyb3RSYWQgKyBhKTtcbiAgICAgICAgaWYgKHR5cGVvZiB5T2ZmICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB4ICs9IHlPZmYgLyoqIHRoaXMuYXBwLnoqLyAqIE1hdGguY29zKHJvdFJhZCArIChNYXRoLlBJIC8gMikpO1xuICAgICAgICAgICAgeSArPSB5T2ZmIC8qKiB0aGlzLmFwcC56Ki8gKiBNYXRoLnNpbihyb3RSYWQgKyAoTWF0aC5QSSAvIDIpKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHkgPSB5T2ZmO1xuICAgIH1cbiAgICB4ICs9IHRoaXMuaXg7XG4gICAgeSArPSB0aGlzLml5O1xuICAgIHJldHVybiBbeCwgeV07XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS5jbGVhclBvc2l0aW9uYWxGZWF0dXJlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmFubm90YXRpb25zID0gW107XG4gICAgdGhpcy5hbm5vdGF0aW9uVHlwZXMgPSBbXTtcbiAgICBpZiAodGhpcy5hbm5vdGF0aW9uc1N2Z0dyb3VwKSBkMy5zZWxlY3QodGhpcy5hbm5vdGF0aW9uc1N2Z0dyb3VwKS5zZWxlY3RBbGwoXCIqXCIpLnJlbW92ZSgpO1xufTtcblxuUG9seW1lci5wcm90b3R5cGUuc2V0UG9zaXRpb25hbEZlYXR1cmVzID0gZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgY29uc3QgdG9vbFRpcEZ1bmMgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIGNvbnN0IGVsID0gKGV2dC50YXJnZXQuY29ycmVzcG9uZGluZ1VzZUVsZW1lbnQpID8gZXZ0LnRhcmdldC5jb3JyZXNwb25kaW5nVXNlRWxlbWVudCA6IGV2dC50YXJnZXQ7XG4gICAgICAgIHNlbGYuYXBwLnByZXZlbnREZWZhdWx0c0FuZFN0b3BQcm9wYWdhdGlvbihldnQpO1xuICAgICAgICBzZWxmLmFwcC5zZXRUb29sdGlwKGVsLm5hbWUsIGVsLmdldEF0dHJpYnV0ZShcImZpbGxcIikpO1xuICAgICAgICBzZWxmLnNob3dIaWdobGlnaHQodHJ1ZSk7XG4gICAgfTtcblxuICAgIGNvbnN0IGFubm90YXRpb25UeXBlc1NldCA9IG5ldyBTZXQoKTtcblxuICAgIGZvciAobGV0IFthbm5vdGF0aW9uVHlwZSwgYW5ub3RhdGlvblNldF0gb2YgdGhpcy5hbm5vdGF0aW9uU2V0cykge1xuICAgICAgICBpZiAodGhpcy5hcHAuYW5ub3RhdGlvblNldHNTaG93bi5nZXQoYW5ub3RhdGlvblR5cGUpID09PSB0cnVlKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBhbm5vdGF0aW9uIG9mIGFubm90YXRpb25TZXQudmFsdWVzKCkpIHtcblxuICAgICAgICAgICAgICAgIGlmIChhbm5vdGF0aW9uLnNlcURhdHVtLnNlcXVlbmNlRGF0dW1TdHJpbmcgIT09IFwibi1uXCIgJiYgYW5ub3RhdGlvbi5zZXFEYXR1bS5zZXF1ZW5jZURhdHVtU3RyaW5nICE9PSBcImMtY1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIGFubm90YXRpb25UeXBlc1NldC5hZGQoYW5ub3RhdGlvbi5kZXNjcmlwdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHRoaXMuYW5ub3RhdGlvblR5cGVzID0gQXJyYXkuZnJvbShhbm5vdGF0aW9uVHlwZXNTZXQudmFsdWVzKCkpLnNvcnQoKTtcblxuICAgIGZvciAobGV0IFthbm5vdGF0aW9uVHlwZSwgYW5ub3RhdGlvblNldF0gb2YgdGhpcy5hbm5vdGF0aW9uU2V0cykge1xuICAgICAgICBpZiAodGhpcy5hcHAuYW5ub3RhdGlvblNldHNTaG93bi5nZXQoYW5ub3RhdGlvblR5cGUpID09PSB0cnVlKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBhbm5vIG9mIGFubm90YXRpb25TZXQudmFsdWVzKCkpIHtcbiAgICAgICAgICAgICAgICBsZXQgdGV4dCA9IGFubm8uZGVzY3JpcHRpb24gKyBcIiBbXCIgKyAoYW5uby5zZXFEYXR1bSA/IGFubm8uc2VxRGF0dW0udG9TdHJpbmcoKSA6IGFubm8uc2VxRGF0dW0uYmVnaW4gKyBcIiAtIFwiICsgYW5uby5zZXFEYXR1bS5lbmQpICsgXCJdXCI7XG4gICAgICAgICAgICAgICAgaWYgKGFubm8uZGVzY3JpcHRpb24gPT09IFwiTm8gYW5ub3RhdGlvbnNcIikge1xuICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gXCJObyBhbm5vdGF0aW9uc1wiO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5CZWdpbikge1xuICAgICAgICAgICAgICAgICAgICBhbm5vLmZ1enp5U3RhcnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwicGF0aFwiKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZm9ybSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eVN0YXJ0LnNldEF0dHJpYnV0ZShcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUGllU2xpY2VBcmNQYXRoKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluQmVnaW4sIGFubm8uc2VxRGF0dW0uYmVnaW4sIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlTdGFydC5zZXRBdHRyaWJ1dGUoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblJlY3RQYXRoKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluQmVnaW4sIGFubm8uc2VxRGF0dW0uYmVnaW4sIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhbm5vLmZ1enp5U3RhcnQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwibm9uZVwiKTsvLy13aWR0aFwiLCBcIjFcIik7IC8vIHRvZG8gLSBzaG91bGQgYmUgY3NzXG4gICAgICAgICAgICAgICAgICAgIC8vIGFubm8uZnV6enlTdGFydC5zZXRBdHRyaWJ1dGUoXCJmaWxsLW9wYWNpdHlcIiwgXCIwLjZcIik7XG4gICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlTdGFydC5uYW1lID0gdGV4dDtcbiAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eVN0YXJ0Lm9ubW91c2VvdmVyID0gdG9vbFRpcEZ1bmM7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYW5ub3RhdGlvbnNTdmdHcm91cC5hcHBlbmRDaGlsZChhbm5vLmZ1enp5U3RhcnQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChhbm5vLnNlcURhdHVtLmJlZ2luICYmIGFubm8uc2VxRGF0dW0uZW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGFubm8uY2VydGFpbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJwYXRoXCIpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgdGVtcEJlZ2luID0gYW5uby5zZXFEYXR1bS5iZWdpbjsgLy90b2RvIC0gbWlnaHQgYmUgYmV0dGVyIHRvIGhhdmUgc2VwZXJhdGUgYXR0IGluIFNlcXVlbmNlRGF0YSBmb3IgZW5kIG9mIHVuY2VydGFpbiBzdGFydFxuICAgICAgICAgICAgICAgICAgICBsZXQgdGVtcEVuZCA9IGFubm8uc2VxRGF0dW0uZW5kO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5CZWdpbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVtcEJlZ2luICs9IDE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluRW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRW5kIC09IDE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZm9ybSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5jZXJ0YWluLnNldEF0dHJpYnV0ZShcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUGllU2xpY2VBcmNQYXRoKHRlbXBCZWdpbiwgdGVtcEVuZCwgYW5ubykpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5jZXJ0YWluLnNldEF0dHJpYnV0ZShcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUmVjdFBhdGgodGVtcEJlZ2luLCB0ZW1wRW5kLCBhbm5vKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYW5uby5jZXJ0YWluLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBcIm5vbmVcIik7Ly8td2lkdGhcIiwgXCIxXCIpO1xuICAgICAgICAgICAgICAgICAgICAvLyBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZmlsbC1vcGFjaXR5XCIsIFwiMC42XCIpO1xuICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4ubmFtZSA9IHRleHQ7XG4gICAgICAgICAgICAgICAgICAgIGFubm8uY2VydGFpbi5vbm1vdXNlb3ZlciA9IHRvb2xUaXBGdW5jO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFubm90YXRpb25zU3ZnR3JvdXAuYXBwZW5kQ2hpbGQoYW5uby5jZXJ0YWluKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluRW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlFbmQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwicGF0aFwiKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZm9ybSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZC5zZXRBdHRyaWJ1dGUoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblBpZVNsaWNlQXJjUGF0aChhbm5vLnNlcURhdHVtLmVuZCwgYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQsIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlFbmQuc2V0QXR0cmlidXRlKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25SZWN0UGF0aChhbm5vLnNlcURhdHVtLmVuZCwgYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQsIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhbm5vLmZ1enp5RW5kLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBcIm5vbmVcIik7IC8vLXdpZHRoXCIsIFwiMVwiKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gYW5uby5mdXp6eUVuZC5zZXRBdHRyaWJ1dGUoXCJmaWxsLW9wYWNpdHlcIiwgXCIwLjZcIik7XG4gICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlFbmQubmFtZSA9IHRleHQ7XG4gICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlFbmQub25tb3VzZW92ZXIgPSB0b29sVGlwRnVuYztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hbm5vdGF0aW9uc1N2Z0dyb3VwLmFwcGVuZENoaWxkKGFubm8uZnV6enlFbmQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn07XG5cblBvbHltZXIuc3RlcHNJbkFyYyA9IDU7XG5cblBvbHltZXIucHJvdG90eXBlLmdldEFubm90YXRpb25QaWVTbGljZUFyY1BhdGggPSBmdW5jdGlvbiAoc3RhcnRSZXMsIGVuZFJlcywgYW5ub3RhdGlvbikge1xuICAgIGNvbnN0IHJhZGl1cyA9IHRoaXMuZ2V0U3ltYm9sUmFkaXVzKCk7Ly8gLSAyO1xuXG4gICAgbGV0IHRvcCwgYm90dG9tLCBydW5nSGVpZ2h0O1xuICAgIGNvbnN0IHJ1bmcgPSB0aGlzLmFubm90YXRpb25UeXBlcy5pbmRleE9mKGFubm90YXRpb24uZGVzY3JpcHRpb24pO1xuICAgIC8vIGNvbnNvbGUubG9nKFwicnVuZ1wiLCBydW5nLCB0aGlzLmFubm90YXRpb25UeXBlcyk7XG4gICAgaWYgKHJ1bmcgPT09IC0xKSB7XG4gICAgICAgIGJvdHRvbSA9IDA7XG4gICAgICAgIHRvcCA9IHJhZGl1cztcbiAgICB9IGVsc2Uge1xuICAgICAgICAvL01hdGguc3FydCh0aGlzLnBhcnRpY2lwYW50LnNpemUgLyBNYXRoLlBJKSAqIDAuNlxuICAgICAgICBydW5nSGVpZ2h0ID0gcmFkaXVzIC8gdGhpcy5hbm5vdGF0aW9uVHlwZXMubGVuZ3RoO1xuICAgICAgICBib3R0b20gPSAocnVuZyAqIHJ1bmdIZWlnaHQpO1xuICAgICAgICB0b3AgPSBib3R0b20gKyBydW5nSGVpZ2h0O1xuICAgICAgICAvL1xuICAgICAgICAvLyBib3R0b20gPSBNYXRoLnNxcnQocnVuZyAvIHRoaXMuYW5ub3RhdGlvblR5cGVzLmxlbmd0aCkgKiByYWRpdXM7XG4gICAgICAgIC8vIHRvcCA9IE1hdGguc3FydChydW5nICsgMSAvIHRoaXMuYW5ub3RhdGlvblR5cGVzLmxlbmd0aCkgKiByYWRpdXM7XG4gICAgfVxuXG4gICAgLy8gdmFyIHN0YXJ0QW5nbGUgPSAoKHN0YXJ0UmVzIC0gMSkgLyB0aGlzLnNpemUpICogMzYwO1xuICAgIC8vIHZhciBlbmRBbmdsZSA9ICgoZW5kUmVzIC0gMSkgLyB0aGlzLnNpemUpICogMzYwO1xuICAgIGxldCBzdGFydEFuZ2xlLCBlbmRBbmdsZTtcbiAgICBpZiAoc3RhcnRSZXMgPT09IFwibi1uXCIpIHtcbiAgICAgICAgc3RhcnRBbmdsZSA9IC0yMDsgLy8oKHN0YXJ0UmVzIC0gMSkgLyB0aGlzLnNpemUpICogMzYwO1xuICAgICAgICBlbmRBbmdsZSA9IDA7Ly8oKGVuZFJlcyAtIDEpIC8gdGhpcy5zaXplKSAqIDM2MDtcbiAgICB9IGVsc2UgaWYgKGVuZFJlcyA9PT0gXCJjLWNcIikge1xuICAgICAgICBzdGFydEFuZ2xlID0gMDsvLygoc3RhcnRSZXMgLSAxKSAvIHRoaXMuc2l6ZSkgKiAzNjA7XG4gICAgICAgIGVuZEFuZ2xlID0gKzIwOyAvLygoZW5kUmVzKSAvIHRoaXMuc2l6ZSkgKiAzNjA7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgc3RhcnRBbmdsZSA9ICgoc3RhcnRSZXMgLSAxKSAvIHRoaXMuc2l6ZSkgKiAzNjA7XG4gICAgICAgIGVuZEFuZ2xlID0gKChlbmRSZXMgLSAxKSAvIHRoaXMuc2l6ZSkgKiAzNjA7XG4gICAgfVxuICAgIC8vIGNvbnN0IGFyY1N0YXJ0ID0gdHJpZyhyYWRpdXMsIHN0YXJ0QW5nbGUgLSA5MCk7XG4gICAgLy8gY29uc3QgYXJjRW5kID0gdHJpZyhyYWRpdXMsIGVuZEFuZ2xlIC0gOTApO1xuICAgIGxldCBsYXJnZUFyY2ggPSAwO1xuICAgIGlmICgoZW5kQW5nbGUgLSBzdGFydEFuZ2xlKSA+IDE4MCB8fCAoZW5kQW5nbGUgPT09IHN0YXJ0QW5nbGUpKSB7XG4gICAgICAgIGxhcmdlQXJjaCA9IDE7XG4gICAgfVxuXG4gICAgY29uc3QgcDEgPSByb3RhdGVQb2ludEFib3V0UG9pbnQoWzAsIGJvdHRvbV0sIFswLCAwXSwgc3RhcnRBbmdsZSAtIDE4MCk7XG4gICAgY29uc3QgcDIgPSByb3RhdGVQb2ludEFib3V0UG9pbnQoWzAsIHRvcF0sIFswLCAwXSwgc3RhcnRBbmdsZSAtIDE4MCk7XG4gICAgY29uc3QgcDMgPSByb3RhdGVQb2ludEFib3V0UG9pbnQoWzAsIHRvcF0sIFswLCAwXSwgZW5kQW5nbGUgLSAxODApO1xuICAgIGNvbnN0IHA0ID0gcm90YXRlUG9pbnRBYm91dFBvaW50KFswLCBib3R0b21dLCBbMCwgMF0sIGVuZEFuZ2xlIC0gMTgwKTtcblxuICAgIC8vY29uc3QgciA9IChib3R0b20gKyB0b3ApIC8gMjtcbiAgICBjb25zdCBwYXRoID0gXCJNXCIgKyBwMVswXSArIFwiLFwiICsgcDFbMV0gKyBcIiBMXCIgKyBwMlswXSArIFwiLFwiICsgcDJbMV1cbiAgICAgICAgKyBcIiBBXCIgKyB0b3AgKyBcIixcIiArIHRvcCArIFwiIDAgXCIgKyBsYXJnZUFyY2ggKyBcIiAxIFwiICsgcDNbMF0gKyBcIixcIiArIHAzWzFdICsgXCIgTFwiICsgcDRbMF0gKyBcIixcIiArIHA0WzFdXG4gICAgICAgICsgXCIgQVwiICsgYm90dG9tICsgXCIsXCIgKyBib3R0b20gKyBcIiAwIFwiICsgbGFyZ2VBcmNoICsgXCIgMCBcIiArIHAxWzBdICsgXCIsXCIgKyBwMVsxXSArIFwiIFpcIjtcbiAgICBjb25zb2xlLmxvZyhcIioqXCIsIHBhdGgpO1xuICAgIHJldHVybiBwYXRoO1xuICAgIC8vIHJldHVybiBcIk0wLDAgTFwiICsgYXJjU3RhcnQueCArIFwiLFwiICsgYXJjU3RhcnQueSArIFwiIEFcIiArIHJhZGl1cyArIFwiLFwiICtcbiAgICAvLyAgICAgcmFkaXVzICsgXCIgMCBcIiArIGxhcmdlQXJjaCArIFwiIDEgXCIgKyBhcmNFbmQueCArIFwiLFwiICsgYXJjRW5kLnkgKyBcIiBaXCI7XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS5nZXRBbm5vdGF0aW9uUGllU2xpY2VBcHByb3hpbWF0ZVBhdGggPSBmdW5jdGlvbiAoc3RhcnRSZXMsIGVuZFJlcywgYW5ub3RhdGlvbikge1xuXG4gICAgLy8gbGV0IHRvcCwgYm90dG9tLCBydW5nSGVpZ2h0O1xuICAgIC8vIGNvbnN0IHJ1bmcgPSB0aGlzLmFubm90YXRpb25UeXBlcy5pbmRleE9mKGFubm90YXRpb24uZGVzY3JpcHRpb24pO1xuICAgIC8vIC8vIGNvbnNvbGUubG9nKFwicnVuZ1wiLCBydW5nLCB0aGlzLmFubm90YXRpb25UeXBlcyk7XG4gICAgLy8gaWYgKHJ1bmcgPT09IC0xKSB7XG4gICAgLy8gICAgIGJvdHRvbSA9IFBvbHltZXIuU1RJQ0tIRUlHSFQgLyAyO1xuICAgIC8vICAgICB0b3AgPSAtUG9seW1lci5TVElDS0hFSUdIVCAvIDI7XG4gICAgLy8gfSBlbHNlIHtcbiAgICAvLyAgICAgcnVuZ0hlaWdodCA9IFBvbHltZXIuU1RJQ0tIRUlHSFQgLyB0aGlzLmFubm90YXRpb25UeXBlcy5sZW5ndGg7XG4gICAgLy8gICAgIHRvcCA9ICgtUG9seW1lci5TVElDS0hFSUdIVCAvIDIpICsgKHJ1bmcgKiBydW5nSGVpZ2h0KTtcbiAgICAvLyAgICAgYm90dG9tID0gdG9wICsgcnVuZ0hlaWdodDtcbiAgICAvLyB9XG5cbiAgICAvL2FwcHJveGltYXRlIHBpZSBzbGljZVxuICAgIGxldCBzdGFydEFuZ2xlLCBlbmRBbmdsZTtcbiAgICBpZiAoc3RhcnRSZXMgPT09IFwibi1uXCIpIHtcbiAgICAgICAgc3RhcnRBbmdsZSA9IC0yMDsgLy8oKHN0YXJ0UmVzIC0gMSkgLyB0aGlzLnNpemUpICogMzYwO1xuICAgICAgICBlbmRBbmdsZSA9IDA7Ly8oKGVuZFJlcykgLyB0aGlzLnNpemUpICogMzYwO1xuICAgIH0gZWxzZSBpZiAoZW5kUmVzID09PSBcImMtY1wiKSB7XG4gICAgICAgIHN0YXJ0QW5nbGUgPSAwOy8vKChzdGFydFJlcyAtIDEpIC8gdGhpcy5zaXplKSAqIDM2MDtcbiAgICAgICAgZW5kQW5nbGUgPSArMjA7IC8vKChlbmRSZXMpIC8gdGhpcy5zaXplKSAqIDM2MDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzdGFydEFuZ2xlID0gKChzdGFydFJlcyAtIDEpIC8gdGhpcy5zaXplKSAqIDM2MDtcbiAgICAgICAgZW5kQW5nbGUgPSAoKGVuZFJlcykgLyB0aGlzLnNpemUpICogMzYwO1xuICAgIH1cbiAgICBjb25zdCBwaWVSYWRpdXMgPSB0aGlzLmdldFN5bWJvbFJhZGl1cygpIC0gMjtcbiAgICAvLyB2YXIgYXJjU3RhcnQgPSBJbnRlcmFjdG9yLnRyaWcocGllUmFkaXVzLCBzdGFydEFuZ2xlIC0gOTApO1xuICAgIC8vIHZhciBhcmNFbmQgPSBJbnRlcmFjdG9yLnRyaWcocGllUmFkaXVzLCBlbmRBbmdsZSAtIDkwKTtcbiAgICBsZXQgYXBwcm94aW1hdGVQaWVQYXRoID0gXCJNIDAsMFwiO1xuICAgIGNvbnN0IHN0ZXBzSW5BcmMgPSA1O1xuICAgIGZvciAobGV0IHNpYSA9IDA7IHNpYSA8PSBQb2x5bWVyLnN0ZXBzSW5BcmM7IHNpYSsrKSB7XG4gICAgICAgIGNvbnN0IGFuZ2xlID0gc3RhcnRBbmdsZSArICgoZW5kQW5nbGUgLSBzdGFydEFuZ2xlKSAqIChzaWEgLyBzdGVwc0luQXJjKSk7XG4gICAgICAgIGNvbnN0IHNpYUNvb3JkID0gdHJpZyhwaWVSYWRpdXMsIGFuZ2xlIC0gOTApO1xuICAgICAgICBhcHByb3hpbWF0ZVBpZVBhdGggKz0gXCIgTCBcIiArIHNpYUNvb3JkLnggKyBcIixcIiArIHNpYUNvb3JkLnk7XG4gICAgfVxuICAgIGFwcHJveGltYXRlUGllUGF0aCArPSBcIiBMIFwiICsgMCArIFwiLFwiICsgMDtcbiAgICBhcHByb3hpbWF0ZVBpZVBhdGggKz0gXCIgIFpcIjtcbiAgICByZXR1cm4gYXBwcm94aW1hdGVQaWVQYXRoO1xufTtcblxuUG9seW1lci5wcm90b3R5cGUuZ2V0QW5ub3RhdGlvblJlY3RQYXRoID0gZnVuY3Rpb24gKHN0YXJ0UmVzLCBlbmRSZXMsIGFubm90YXRpb24pIHtcbiAgICAvL2RvbWFpbiBhcyByZWN0YW5nbGUgcGF0aFxuICAgIGxldCB0b3AsIGJvdHRvbSwgcnVuZ0hlaWdodDtcbiAgICBjb25zdCBydW5nID0gdGhpcy5hbm5vdGF0aW9uVHlwZXMuaW5kZXhPZihhbm5vdGF0aW9uLmRlc2NyaXB0aW9uKTtcbiAgICAvLyBjb25zb2xlLmxvZyhcInJ1bmdcIiwgcnVuZywgdGhpcy5hbm5vdGF0aW9uVHlwZXMpO1xuICAgIGlmIChydW5nID09PSAtMSkge1xuICAgICAgICBib3R0b20gPSBQb2x5bWVyLlNUSUNLSEVJR0hUIC8gMjtcbiAgICAgICAgdG9wID0gLVBvbHltZXIuU1RJQ0tIRUlHSFQgLyAyO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJ1bmdIZWlnaHQgPSBQb2x5bWVyLlNUSUNLSEVJR0hUIC8gdGhpcy5hbm5vdGF0aW9uVHlwZXMubGVuZ3RoO1xuICAgICAgICB0b3AgPSAoLVBvbHltZXIuU1RJQ0tIRUlHSFQgLyAyKSArIChydW5nICogcnVuZ0hlaWdodCk7XG4gICAgICAgIGJvdHRvbSA9IHRvcCArIHJ1bmdIZWlnaHQ7XG4gICAgfVxuXG4gICAgbGV0IGFubm90WCwgYW5ub3RTaXplLCBhbm5vdExlbmd0aDtcbiAgICBpZiAoc3RhcnRSZXMgPT09IFwibi1uXCIpIHtcbiAgICAgICAgYW5ub3RYID0gdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbSgwLjUpIC0gMjA7XG4gICAgICAgIC8vIHZhciBhbm5vdFNpemUgPSAoMSArIChlbmRSZXMgLSBzdGFydFJlcykpO1xuICAgICAgICBhbm5vdExlbmd0aCA9IDIwOy8vYW5ub3RTaXplICogdGhpcy5zdGlja1pvb207XG4gICAgfSBlbHNlIGlmIChlbmRSZXMgPT09IFwiYy1jXCIpIHtcbiAgICAgICAgYW5ub3RYID0gdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbSh0aGlzLnNpemUgKyAwLjUpO1xuICAgICAgICAvLyB2YXIgYW5ub3RTaXplID0gKDEgKyAoZW5kUmVzIC0gc3RhcnRSZXMpKTtcbiAgICAgICAgYW5ub3RMZW5ndGggPSAyMDsvL2Fubm90U2l6ZSAqIHRoaXMuc3RpY2tab29tO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGFubm90WCA9IHRoaXMuZ2V0UmVzWHdpdGhTdGlja1pvb20oc3RhcnRSZXMgLSAwLjUpO1xuICAgICAgICBhbm5vdFNpemUgPSAoMSArIChlbmRSZXMgLSBzdGFydFJlcykpO1xuICAgICAgICBhbm5vdExlbmd0aCA9IGFubm90U2l6ZSAqIHRoaXMuc3RpY2tab29tO1xuICAgIH1cbiAgICBsZXQgcmVjdFBhdGggPSBcIk0gXCIgKyBhbm5vdFggKyBcIixcIiArIGJvdHRvbTtcbiAgICBmb3IgKGxldCBzaWEgPSAwOyBzaWEgPD0gUG9seW1lci5zdGVwc0luQXJjOyBzaWErKykge1xuICAgICAgICBjb25zdCBzdGVwID0gYW5ub3RYICsgKGFubm90TGVuZ3RoICogKHNpYSAvIFBvbHltZXIuc3RlcHNJbkFyYykpO1xuICAgICAgICByZWN0UGF0aCArPSBcIiBMIFwiICsgc3RlcCArIFwiLFwiICsgdG9wO1xuICAgIH1cbiAgICByZWN0UGF0aCArPSBcIiBMIFwiICsgKGFubm90WCArIGFubm90TGVuZ3RoKSArIFwiLFwiICsgYm90dG9tICtcbiAgICAgICAgXCIgWlwiO1xuICAgIHJldHVybiByZWN0UGF0aDtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/polymer.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Polymer\", function() { return Polymer; });\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _interactor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./interactor */ \"./src/js/viz/interactor/interactor.js\");\n/* harmony import */ var _annotation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./annotation */ \"./src/js/viz/interactor/annotation.js\");\n/* harmony import */ var _sequence_datum__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../sequence-datum */ \"./src/js/viz/sequence-datum.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n // transitions and other stuff\n\n\n\n\n\nPolymer.STICKHEIGHT = 20; //height of stick in pixels\nPolymer.MAXSIZE = 0; // residue count of longest sequence\nPolymer.transitionTime = 650;\n\nfunction Polymer() {\n}\n\nPolymer.prototype = new _interactor__WEBPACK_IMPORTED_MODULE_1__[\"Interactor\"]();\n\n//sequence = amino acids in UPPERCASE, digits or lowercase can be used for modification info\nPolymer.prototype.setSequence = function (sequence) {\n //remove modification site info from sequence\n this.sequence = sequence.replace(/[^A-Z]/g, \"\");\n this.size = this.sequence.length;\n};\n\nPolymer.prototype.getSymbolRadius = function () {\n return 15;\n};\n\nPolymer.prototype.showHighlight = function (show) {\n if (show === true) {\n this.highlight.setAttribute(\"stroke-opacity\", \"1\");\n } else {\n this.highlight.setAttribute(\"stroke-opacity\", \"0\");\n }\n};\n\nPolymer.minXDist = 30;\nPolymer.prototype.setStickScale = function (scale, svgP) {\n const oldScale = this.stickZoom;\n\n //dist from centre\n const dx = (this.ix - svgP.x);\n const dy = (this.iy - svgP.y);\n\n // new dist from centre\n const nx = dx * scale / oldScale;\n const ny = dy * scale / oldScale;\n\n //required change\n const rx = nx - dx;\n let ry = ny - dy;\n\n if (this.rotation === 0 || this.rotation === 180) {\n ry = 0;\n }\n\n //new pos\n const x = this.ix + rx;\n const y = this.iy + ry;\n\n this.stickZoom = scale;\n this.scale();\n this.setPosition(x, y);\n this.setAllLinkCoordinates();\n};\n\nPolymer.prototype.scale = function () {\n const protLength = (this.size) * this.stickZoom;\n if (this.form === 1) {\n const labelTransform = d3__WEBPACK_IMPORTED_MODULE_0__[\"transform\"](this.labelSVG.getAttribute(\"transform\"));\n const k = this.app.svgElement.createSVGMatrix().rotate(labelTransform.rotate)\n .translate((-(((this.size / 2) * this.stickZoom) + (this.nTerminusFeature ? 25 : 10))), _config__WEBPACK_IMPORTED_MODULE_4__[\"LABEL_Y\"]); //.scale(z).translate(-c.x, -c.y);\n this.labelSVG.transform.baseVal.initialize(this.app.svgElement.createSVGTransformFromMatrix(k));\n\n for (let [annotationType, annotations] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n if (anno.fuzzyStart) {\n anno.fuzzyStart.setAttribute(\"d\", this.getAnnotationRectPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n }\n if (anno.certain) {\n let tempBegin = anno.seqDatum.begin; //todo - might be better to have seperate att in SequenceData for end of uncertain start\n let tempEnd = anno.seqDatum.end;\n if (anno.seqDatum.uncertainBegin) {\n tempBegin += 1;\n }\n if (anno.seqDatum.uncertainEnd) {\n tempEnd -= 1;\n }\n anno.certain.setAttribute(\"d\", this.getAnnotationRectPath(tempBegin, tempEnd, anno));\n }\n if (anno.fuzzyEnd) {\n anno.fuzzyEnd.setAttribute(\"d\", this.getAnnotationRectPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n }\n }\n }\n }\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.background)\n .attr(\"width\", protLength)\n .attr(\"x\", this.getResXwithStickZoom(0.5));\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.outline)\n .attr(\"width\", protLength)\n .attr(\"x\", this.getResXwithStickZoom(0.5));\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.highlight)\n .attr(\"width\", protLength + 5)\n .attr(\"x\", this.getResXwithStickZoom(0.5) - 2.5);\n\n\n this.setScaleGroup();\n }\n};\n\nPolymer.prototype.setScaleGroup = function () {\n this.upperGroup.appendChild(this.ticks); //will do nothing if this.ticks already appended to this.uppergroup\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.ticks).selectAll(\"*\").remove();\n\n this.scaleLabels = [];\n const ScaleTicksPerLabel = 2; // varies with scale?\n let tick = -1;\n const lastTickX = this.getResXwithStickZoom(this.size);\n\n for (let res = 1; res <= this.size; res++) {\n if (res === 1 ||\n ((res % 100 === 0) && (200 * this.stickZoom > Polymer.minXDist)) ||\n ((res % 10 === 0) && (20 * this.stickZoom > Polymer.minXDist))\n ) {\n const tx = this.getResXwithStickZoom(res);\n if (this.stickZoom >= 8 || res !== 1) {\n tickAt(this, tx);\n }\n tick = (tick + 1) % ScaleTicksPerLabel;\n // does this one get a label?\n if (tick === 0) { // && tx > 20) {\n if ((tx + Polymer.minXDist) < lastTickX) {\n scaleLabelAt(this, res, tx);\n }\n }\n }\n if (this.stickZoom >= 8) {\n const seqLabelGroup = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"g\");\n seqLabelGroup.setAttribute(\"transform\", \"translate(\" + this.getResXwithStickZoom(res) + \" \" + 0 + \")\");\n const seqLabel = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"text\");\n seqLabel.classList.add(\"label\", \"sequence\");\n //css?\n seqLabel.setAttribute(\"x\", \"0\");\n seqLabel.setAttribute(\"y\", \"3\");\n seqLabel.appendChild(document.createTextNode(this.sequence[res - 1]));\n seqLabelGroup.appendChild(seqLabel);\n this.scaleLabels.push(seqLabel);\n this.ticks.appendChild(seqLabelGroup);\n }\n }\n scaleLabelAt(this, this.size, lastTickX);\n if (this.stickZoom >= 8) {\n tickAt(this, lastTickX);\n }\n\n function scaleLabelAt(self, text, tickX) {\n const scaleLabelGroup = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"g\");\n scaleLabelGroup.setAttribute(\"transform\", \"translate(\" + tickX + \" \" + 0 + \")\");\n const scaleLabel = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"text\");\n scaleLabel.classList.add(\"label\", \"scale-label\");\n scaleLabel.setAttribute(\"x\", \"0\");\n scaleLabel.setAttribute(\"y\", Polymer.STICKHEIGHT + 4);\n scaleLabel.appendChild(document.createTextNode(text));\n scaleLabelGroup.appendChild(scaleLabel);\n self.scaleLabels.push(scaleLabel);\n self.ticks.appendChild(scaleLabelGroup);\n }\n\n function tickAt(self, tickX) {\n const tick = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"line\");\n tick.classList.add(\"tick\");\n tick.setAttribute(\"x1\", tickX);\n tick.setAttribute(\"y1\", \"5\");\n tick.setAttribute(\"x2\", tickX);\n tick.setAttribute(\"y2\", \"10\");\n self.ticks.appendChild(tick);\n }\n};\n\nPolymer.prototype.setForm = function (form, svgP) {\n if (this.busy !== true) {\n if (form === 1) {\n if (this.form !== 1) {\n this.toStick();\n }\n } else {\n // if (this.form !== 0) {\n this.toCircle(svgP);\n // var r = this.getSymbolRadius();\n\n }\n // }\n }\n};\n\nPolymer.prototype.toCircle = function (svgP) {\n //svgP = null;// temp hack - you can uncomment this is you experience things 'flying off screen'\n this.busy = true;\n\n const r = this.getSymbolRadius();\n //\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.background).transition()\n .attr(\"x\", -r).attr(\"y\", -r)\n .attr(\"width\", r * 2).attr(\"height\", r * 2)\n .attr(\"rx\", r).attr(\"ry\", r)\n .duration(Polymer.transitionTime);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.outline).transition()\n .attr(\"x\", -r).attr(\"y\", -r)\n .attr(\"width\", r * 2).attr(\"height\", r * 2)\n .attr(\"rx\", r).attr(\"ry\", r)\n .duration(Polymer.transitionTime);\n // d3.select(this.annotationsSvgGroup).transition()\n // .attr(\"transform\", \"scale(1, 1)\")\n // .duration(Polymer.transitionTime);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.highlight).transition()\n .attr(\"x\", -r).attr(\"y\", -r)\n .attr(\"width\", r * 2).attr(\"height\", r * 2)\n .attr(\"rx\", r).attr(\"ry\", r)\n .duration(Polymer.transitionTime);\n\n const stickZoomInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](this.stickZoom, 0);\n // var rotationInterpol = d3.interpolate((this.rotation > 180) ? this.rotation - 360 : this.rotation, 0);\n const labelTransform = d3__WEBPACK_IMPORTED_MODULE_0__[\"transform\"](this.labelSVG.getAttribute(\"transform\"));\n const labelStartPoint = labelTransform.translate[0];\n const labelTranslateInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](labelStartPoint, -(r + 5));\n\n let xInterpol = null,\n yInterpol = null;\n if (typeof svgP !== \"undefined\" && svgP !== null) {\n xInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](this.ix, svgP.x);\n yInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](this.iy, svgP.y);\n }\n\n const self = this;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.ticks).transition().attr(\"opacity\", 0).duration(Polymer.transitionTime / 4)\n .each(\"end\",\n function () {\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this).selectAll(\"*\").remove();\n }\n );\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.highlight).transition()\n .attr(\"width\", (r * 2) + 5).attr(\"height\", (r * 2) + 5)\n .attr(\"x\", -r - 2.5).attr(\"y\", -r - 2.5)\n .attr(\"rx\", r + 2.5).attr(\"ry\", r + 2.5)\n .duration(Polymer.transitionTime);\n\n function changeFuzzyStartToArcPath(anno) {\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](anno.fuzzyStart).attr(\"d\", self.getAnnotationPieSliceArcPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n }\n\n function changeCertainToArcPath(anno) {\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](anno.certain).attr(\"d\", self.getAnnotationPieSliceArcPath(anno.seqDatum.begin, anno.seqDatum.end, anno));\n }\n\n function changeFuzzyEndToArcPath(anno) {\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](anno.fuzzyEnd).attr(\"d\", self.getAnnotationPieSliceArcPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n }\n\n for (let [annotationType, annotations] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n if (anno.fuzzyStart) {\n const fuzzyStart = anno.fuzzyStart;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyStart).transition().attr(\"d\", this.getAnnotationPieSliceApproximatePath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno))\n .duration(Polymer.transitionTime).each(\"end\",\n function () {\n changeFuzzyStartToArcPath(anno);\n }\n );\n }\n\n if (anno.certain) {\n const certain = anno.certain;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](certain).transition().attr(\"d\", this.getAnnotationPieSliceApproximatePath(anno.seqDatum.begin, anno.seqDatum.end, anno))\n .duration(Polymer.transitionTime).each(\"end\",\n function () {\n changeCertainToArcPath(anno);\n }\n );\n }\n\n if (anno.fuzzyEnd) {\n const fuzzyEnd = anno.fuzzyEnd;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyEnd).transition().attr(\"d\", this.getAnnotationPieSliceApproximatePath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno))\n .duration(Polymer.transitionTime).each(\"end\",\n function () {\n changeFuzzyEndToArcPath(anno);\n }\n );\n }\n }\n }\n }\n\n const originalStickZoom = this.stickZoom;\n const originalRotation = this.rotation;\n const cubicInOut = d3__WEBPACK_IMPORTED_MODULE_0__[\"ease\"](\"cubic-in-out\");\n d3__WEBPACK_IMPORTED_MODULE_0__[\"timer\"](function (elapsed) {\n return update(elapsed / Polymer.transitionTime);\n });\n\n function update(interp) {\n const labelTransform = d3__WEBPACK_IMPORTED_MODULE_0__[\"transform\"](self.labelSVG.getAttribute(\"transform\"));\n const k = self.app.svgElement.createSVGMatrix().rotate(labelTransform.rotate).translate(labelTranslateInterpol(cubicInOut(interp)), _config__WEBPACK_IMPORTED_MODULE_4__[\"LABEL_Y\"]); //.scale(z).translate(-c.x, -c.y);\n self.labelSVG.transform.baseVal.initialize(self.app.svgElement.createSVGTransformFromMatrix(k));\n //~\n if (xInterpol !== null) {\n self.setPosition(xInterpol(cubicInOut(interp)), yInterpol(cubicInOut(interp)));\n }\n\n self.stickZoom = stickZoomInterpol(cubicInOut(interp));\n self.setAllLinkCoordinates();\n\n if (interp === 1) { // finished - tidy up\n self.form = 0;\n self.checkLinks();\n self.stickZoom = originalStickZoom;\n self.rotation = originalRotation;\n self.busy = false;\n return true;\n } else if (interp > 1) {\n return update(1);\n } else {\n return false;\n }\n }\n};\n\nPolymer.prototype.toStick = function () {\n this.busy = true;\n this.form = 1;\n\n //remove prot-prot links - would it be better if checkLinks did this? - think not\n const c = this.binaryLinks.values().length;\n for (let l = 0; l < c; l++) {\n const link = this.binaryLinks.values()[l];\n //out with the old\n if (link.shown) {\n link.hide();\n }\n }\n\n const protLength = this.size * this.stickZoom;\n const r = this.getSymbolRadius();\n\n const lengthInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"]((2 * r), protLength);\n const stickZoomInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](0, this.stickZoom);\n const labelTranslateInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](-(r + 5), -(((this.size / 2) * this.stickZoom) + (this.nTerminusFeature ? 25 : 10)));\n\n const origStickZoom = this.stickZoom;\n this.stickZoom = 0;\n this.checkLinks(this.binaryLinks);\n this.checkLinks(this.selfLink);\n this.checkLinks(this.sequenceLinks);\n this.stickZoom = origStickZoom;\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.background).transition() //.attr(\"stroke-opacity\", 1)\n .attr(\"height\", Polymer.STICKHEIGHT)\n .attr(\"y\", -Polymer.STICKHEIGHT / 2)\n .attr(\"rx\", 0).attr(\"ry\", 0)\n .duration(Polymer.transitionTime);\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.outline).transition() //.attr(\"stroke-opacity\", 1)\n .attr(\"height\", Polymer.STICKHEIGHT)\n .attr(\"y\", -Polymer.STICKHEIGHT / 2)\n .attr(\"rx\", 0).attr(\"ry\", 0)\n .duration(Polymer.transitionTime);\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.highlight).transition()\n .attr(\"width\", protLength + 5).attr(\"height\", Polymer.STICKHEIGHT + 5)\n .attr(\"x\", this.getResXwithStickZoom(0.5) - 2.5).attr(\"y\", (-Polymer.STICKHEIGHT / 2) - 2.5)\n .attr(\"rx\", 0).attr(\"ry\", 0)\n .duration(Polymer.transitionTime);\n\n for (let [annotationType, annotations] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n if (anno.fuzzyStart) {\n const fuzzyStart = anno.fuzzyStart;\n fuzzyStart.setAttribute(\"d\", this.getAnnotationPieSliceApproximatePath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyStart).transition().attr(\"d\", this.getAnnotationRectPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno))\n .duration(Polymer.transitionTime);\n }\n if (anno.certain) {\n const certain = anno.certain;\n let tempBegin = anno.seqDatum.begin; //todo - might be better to have seperate att in SequenceData for end of uncertain start\n let tempEnd = anno.seqDatum.end;\n if (anno.seqDatum.uncertainBegin) {\n tempBegin += 1;\n }\n if (anno.seqDatum.uncertainEnd) {\n tempEnd -= 1;\n }\n\n certain.setAttribute(\"d\", this.getAnnotationPieSliceApproximatePath(tempBegin, tempEnd, anno));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](certain).transition().attr(\"d\", this.getAnnotationRectPath(tempBegin, tempEnd, anno))\n .duration(Polymer.transitionTime);\n }\n if (anno.fuzzyEnd) {\n const fuzzyEnd = anno.fuzzyEnd;\n fuzzyEnd.setAttribute(\"d\", this.getAnnotationPieSliceApproximatePath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyEnd).transition().attr(\"d\", this.getAnnotationRectPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno))\n .duration(Polymer.transitionTime);\n }\n }\n }\n }\n\n const self = this;\n const cubicInOut = d3__WEBPACK_IMPORTED_MODULE_0__[\"ease\"](\"cubic-in-out\");\n d3__WEBPACK_IMPORTED_MODULE_0__[\"timer\"](function (elapsed) {\n return update(elapsed / Polymer.transitionTime);\n });\n\n function update(interp) {\n const labelTransform = d3__WEBPACK_IMPORTED_MODULE_0__[\"transform\"](self.labelSVG.getAttribute(\"transform\"));\n const k = self.app.svgElement.createSVGMatrix().rotate(labelTransform.rotate).translate(labelTranslateInterpol(cubicInOut(interp)), _config__WEBPACK_IMPORTED_MODULE_4__[\"LABEL_Y\"]); //.scale(z).translate(-c.x, -c.y);\n self.labelSVG.transform.baseVal.initialize(self.app.svgElement.createSVGTransformFromMatrix(k));\n\n const currentLength = lengthInterpol(cubicInOut(interp));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.highlight).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.outline).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.background).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n self.stickZoom = stickZoomInterpol(cubicInOut(interp));\n self.setAllLinkCoordinates();\n\n if (interp === 1) { // finished - tidy up\n self.busy = false;\n return true;\n } else if (interp > 1) {\n return update(1);\n } else {\n return false;\n }\n }\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.ticks).attr(\"opacity\", 0);\n this.setScaleGroup();\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.ticks).transition().attr(\"opacity\", 1)\n .delay(Polymer.transitionTime * 0.8).duration(Polymer.transitionTime / 2);\n};\n\n\nPolymer.prototype.toStickNoTransition = function () { //todo tidy\n this.busy = true;\n this.form = 1;\n\n //remove prot-prot links - would it be better if checkLinks did this? - think not\n const c = this.binaryLinks.values().length;\n for (let l = 0; l < c; l++) {\n const link = this.binaryLinks.values()[l];\n //out with the old\n if (link.shown) {\n link.hide();\n }\n }\n\n const protLength = this.size * this.stickZoom;\n const r = this.getSymbolRadius();\n\n const lengthInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"]((2 * r), protLength);\n const labelTranslateInterpol = d3__WEBPACK_IMPORTED_MODULE_0__[\"interpolate\"](-(r + 5), -(((this.size / 2) * this.stickZoom) + (this.nTerminusFeature ? 25 : 10)));\n\n this.checkLinks(this.binaryLinks);\n this.checkLinks(this.selfLink);\n this.checkLinks(this.sequenceLinks);\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.background)\n .attr(\"height\", Polymer.STICKHEIGHT)\n .attr(\"y\", -Polymer.STICKHEIGHT / 2)\n .attr(\"rx\", 0).attr(\"ry\", 0);\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.outline)\n .attr(\"height\", Polymer.STICKHEIGHT)\n .attr(\"y\", -Polymer.STICKHEIGHT / 2)\n .attr(\"rx\", 0).attr(\"ry\", 0);\n\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.highlight)\n .attr(\"width\", protLength + 5).attr(\"height\", Polymer.STICKHEIGHT + 5)\n .attr(\"x\", this.getResXwithStickZoom(0.5) - 2.5).attr(\"y\", (-Polymer.STICKHEIGHT / 2) - 2.5)\n .attr(\"rx\", 0).attr(\"ry\", 0);\n\n for (let [annotationType, annotations] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotations) {\n if (anno.fuzzyStart) {\n const fuzzyStart = anno.fuzzyStart;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyStart).attr(\"d\", this.getAnnotationRectPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n }\n if (anno.certain) {\n let tempBegin = anno.seqDatum.begin; //todo - might be better to have seperate att in SequenceData for end of uncertain start\n let tempEnd = anno.seqDatum.end;\n if (anno.seqDatum.uncertainBegin) {\n tempBegin += 1;\n }\n if (anno.seqDatum.uncertainEnd) {\n tempEnd -= 1;\n }\n anno.certain.setAttribute(\"d\", this.getAnnotationRectPath(tempBegin, tempEnd, anno));\n }\n if (anno.fuzzyEnd) {\n const fuzzyEnd = anno.fuzzyEnd;\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](fuzzyEnd) /*.transition()*/ .attr(\"d\", this.getAnnotationRectPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n }\n }\n }\n }\n\n const self = this;\n\n const labelTransform = d3__WEBPACK_IMPORTED_MODULE_0__[\"transform\"](self.labelSVG.getAttribute(\"transform\"));\n const k = self.app.svgElement.createSVGMatrix().rotate(labelTransform.rotate).translate(labelTranslateInterpol(1), _config__WEBPACK_IMPORTED_MODULE_4__[\"LABEL_Y\"]); //.scale(z).translate(-c.x, -c.y);\n self.labelSVG.transform.baseVal.initialize(self.app.svgElement.createSVGTransformFromMatrix(k));\n\n const currentLength = lengthInterpol(1);\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.highlight).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.outline).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](self.background).attr(\"width\", currentLength).attr(\"x\", -(currentLength / 2) + (0.5 * self.stickZoom));\n self.setAllLinkCoordinates();\n\n this.setScaleGroup();\n d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.ticks).attr(\"opacity\", 1);\n\n self.busy = false;\n};\n\nPolymer.prototype.getResXwithStickZoom = function (r) {\n // if (isNaN(r)) {\n // console.error(\"NOT NUMBER\");\n // }\n if (r === \"n-n\") {\n return (-this.size / 2 * this.stickZoom) - 20;\n } else if (r === \"c-c\") {\n return (this.size / 2 * this.stickZoom) + 20;\n } else {\n return (r - (this.size / 2)) * this.stickZoom;\n }\n};\n\n//calculate the coordinates of a residue (relative to this.util.container)\nPolymer.prototype.getResidueCoordinates = function (r, yOff) {\n if (typeof r === \"undefined\") {\n console.error(\"ERROR: residue number is undefined\");\n }\n let x = this.getResXwithStickZoom(r * 1);// * this.app.z;\n // console.log(\"***\", this.app.z);\n // coz prots don't scale, don't multiple by app.z\n let y;\n if (x !== 0) {\n const l = Math.abs(x);\n const a = Math.acos(x / l);\n const rotRad = (this.rotation / 360) * Math.PI * 2;\n x = l * Math.cos(rotRad + a);\n y = l * Math.sin(rotRad + a);\n if (typeof yOff !== \"undefined\") {\n x += yOff /** this.app.z*/ * Math.cos(rotRad + (Math.PI / 2));\n y += yOff /** this.app.z*/ * Math.sin(rotRad + (Math.PI / 2));\n }\n } else {\n y = yOff;\n }\n x += this.ix;\n y += this.iy;\n return [x, y];\n};\n\nPolymer.prototype.clearPositionalFeatures = function () {\n this.annotations = [];\n this.annotationTypes = [];\n if (this.annotationsSvgGroup) d3__WEBPACK_IMPORTED_MODULE_0__[\"select\"](this.annotationsSvgGroup).selectAll(\"*\").remove();\n};\n\nPolymer.prototype.setPositionalFeatures = function () {\n const self = this;\n\n const toolTipFunc = function (evt) {\n const el = (evt.target.correspondingUseElement) ? evt.target.correspondingUseElement : evt.target;\n self.app.preventDefaultsAndStopPropagation(evt);\n self.app.setTooltip(el.name, el.getAttribute(\"fill\"));\n self.showHighlight(true);\n };\n\n const annotationTypesSet = new Set();\n\n for (let [annotationType, annotationSet] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let annotation of annotationSet.values()) {\n\n if (annotation.seqDatum.sequenceDatumString !== \"n-n\" && annotation.seqDatum.sequenceDatumString !== \"c-c\") {\n annotationTypesSet.add(annotation.description);\n }\n }\n }\n }\n this.annotationTypes = Array.from(annotationTypesSet.values()).sort();\n\n for (let [annotationType, annotationSet] of this.annotationSets) {\n if (this.app.annotationSetsShown.get(annotationType) === true) {\n for (let anno of annotationSet.values()) {\n let text = anno.description + \" [\" + (anno.seqDatum ? anno.seqDatum.toString() : anno.seqDatum.begin + \" - \" + anno.seqDatum.end) + \"]\";\n if (anno.description === \"No annotations\") {\n text = \"No annotations\";\n }\n if (anno.seqDatum.uncertainBegin) {\n anno.fuzzyStart = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"path\");\n if (this.form === 0) {\n anno.fuzzyStart.setAttribute(\"d\", this.getAnnotationPieSliceArcPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n } else {\n anno.fuzzyStart.setAttribute(\"d\", this.getAnnotationRectPath(anno.seqDatum.uncertainBegin, anno.seqDatum.begin, anno));\n }\n anno.fuzzyStart.setAttribute(\"stroke\", \"none\");//-width\", \"1\"); // todo - should be css\n // anno.fuzzyStart.setAttribute(\"fill-opacity\", \"0.6\");\n anno.fuzzyStart.name = text;\n anno.fuzzyStart.onmouseover = toolTipFunc;\n this.annotationsSvgGroup.appendChild(anno.fuzzyStart);\n }\n\n if (anno.seqDatum.begin && anno.seqDatum.end) {\n anno.certain = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"path\");\n let tempBegin = anno.seqDatum.begin; //todo - might be better to have seperate att in SequenceData for end of uncertain start\n let tempEnd = anno.seqDatum.end;\n if (anno.seqDatum.uncertainBegin) {\n tempBegin += 1;\n }\n if (anno.seqDatum.uncertainEnd) {\n tempEnd -= 1;\n }\n if (this.form === 0) {\n anno.certain.setAttribute(\"d\", this.getAnnotationPieSliceArcPath(tempBegin, tempEnd, anno));\n } else {\n anno.certain.setAttribute(\"d\", this.getAnnotationRectPath(tempBegin, tempEnd, anno));\n }\n anno.certain.setAttribute(\"stroke\", \"none\");//-width\", \"1\");\n // anno.certain.setAttribute(\"fill-opacity\", \"0.6\");\n anno.certain.name = text;\n anno.certain.onmouseover = toolTipFunc;\n this.annotationsSvgGroup.appendChild(anno.certain);\n }\n if (anno.seqDatum.uncertainEnd) {\n anno.fuzzyEnd = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_4__[\"svgns\"], \"path\");\n if (this.form === 0) {\n anno.fuzzyEnd.setAttribute(\"d\", this.getAnnotationPieSliceArcPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n } else {\n anno.fuzzyEnd.setAttribute(\"d\", this.getAnnotationRectPath(anno.seqDatum.end, anno.seqDatum.uncertainEnd, anno));\n }\n anno.fuzzyEnd.setAttribute(\"stroke\", \"none\"); //-width\", \"1\");\n // anno.fuzzyEnd.setAttribute(\"fill-opacity\", \"0.6\");\n anno.fuzzyEnd.name = text;\n anno.fuzzyEnd.onmouseover = toolTipFunc;\n this.annotationsSvgGroup.appendChild(anno.fuzzyEnd);\n }\n }\n }\n }\n};\n\nPolymer.stepsInArc = 5;\n\nPolymer.prototype.getAnnotationPieSliceArcPath = function (startRes, endRes, annotation) {\n const radius = this.getSymbolRadius();// - 2;\n\n let top, bottom, rungHeight;\n const rung = this.annotationTypes.indexOf(annotation.description);\n // console.log(\"rung\", rung, this.annotationTypes);\n if (rung === -1) {\n bottom = 0;\n top = radius;\n } else {\n //Math.sqrt(this.participant.size / Math.PI) * 0.6\n rungHeight = radius / this.annotationTypes.length;\n bottom = (rung * rungHeight);\n top = bottom + rungHeight;\n //\n // bottom = Math.sqrt(rung / this.annotationTypes.length) * radius;\n // top = Math.sqrt(rung + 1 / this.annotationTypes.length) * radius;\n }\n\n // var startAngle = ((startRes - 1) / this.size) * 360;\n // var endAngle = ((endRes - 1) / this.size) * 360;\n let startAngle, endAngle;\n if (startRes === \"n-n\") {\n startAngle = -20; //((startRes - 1) / this.size) * 360;\n endAngle = 0;//((endRes - 1) / this.size) * 360;\n } else if (endRes === \"c-c\") {\n startAngle = 0;//((startRes - 1) / this.size) * 360;\n endAngle = +20; //((endRes) / this.size) * 360;\n } else {\n startAngle = ((startRes - 1) / this.size) * 360;\n endAngle = ((endRes - 1) / this.size) * 360;\n }\n // const arcStart = trig(radius, startAngle - 90);\n // const arcEnd = trig(radius, endAngle - 90);\n let largeArch = 0;\n if ((endAngle - startAngle) > 180 || (endAngle === startAngle)) {\n largeArch = 1;\n }\n\n const p1 = Object(_config__WEBPACK_IMPORTED_MODULE_4__[\"rotatePointAboutPoint\"])([0, bottom], [0, 0], startAngle - 180);\n const p2 = Object(_config__WEBPACK_IMPORTED_MODULE_4__[\"rotatePointAboutPoint\"])([0, top], [0, 0], startAngle - 180);\n const p3 = Object(_config__WEBPACK_IMPORTED_MODULE_4__[\"rotatePointAboutPoint\"])([0, top], [0, 0], endAngle - 180);\n const p4 = Object(_config__WEBPACK_IMPORTED_MODULE_4__[\"rotatePointAboutPoint\"])([0, bottom], [0, 0], endAngle - 180);\n\n //const r = (bottom + top) / 2;\n const path = \"M\" + p1[0] + \",\" + p1[1] + \" L\" + p2[0] + \",\" + p2[1]\n + \" A\" + top + \",\" + top + \" 0 \" + largeArch + \" 1 \" + p3[0] + \",\" + p3[1] + \" L\" + p4[0] + \",\" + p4[1]\n + \" A\" + bottom + \",\" + bottom + \" 0 \" + largeArch + \" 0 \" + p1[0] + \",\" + p1[1] + \" Z\";\n // console.log(\"**\", path);\n return path;\n // return \"M0,0 L\" + arcStart.x + \",\" + arcStart.y + \" A\" + radius + \",\" +\n // radius + \" 0 \" + largeArch + \" 1 \" + arcEnd.x + \",\" + arcEnd.y + \" Z\";\n};\n\nPolymer.prototype.getAnnotationPieSliceApproximatePath = function (startRes, endRes, annotation) {\n\n // let top, bottom, rungHeight;\n // const rung = this.annotationTypes.indexOf(annotation.description);\n // // console.log(\"rung\", rung, this.annotationTypes);\n // if (rung === -1) {\n // bottom = Polymer.STICKHEIGHT / 2;\n // top = -Polymer.STICKHEIGHT / 2;\n // } else {\n // rungHeight = Polymer.STICKHEIGHT / this.annotationTypes.length;\n // top = (-Polymer.STICKHEIGHT / 2) + (rung * rungHeight);\n // bottom = top + rungHeight;\n // }\n\n //approximate pie slice\n let startAngle, endAngle;\n if (startRes === \"n-n\") {\n startAngle = -20; //((startRes - 1) / this.size) * 360;\n endAngle = 0;//((endRes) / this.size) * 360;\n } else if (endRes === \"c-c\") {\n startAngle = 0;//((startRes - 1) / this.size) * 360;\n endAngle = +20; //((endRes) / this.size) * 360;\n } else {\n startAngle = ((startRes - 1) / this.size) * 360;\n endAngle = ((endRes) / this.size) * 360;\n }\n const pieRadius = this.getSymbolRadius() - 2;\n // var arcStart = Interactor.trig(pieRadius, startAngle - 90);\n // var arcEnd = Interactor.trig(pieRadius, endAngle - 90);\n let approximatePiePath = \"M 0,0\";\n const stepsInArc = 5;\n for (let sia = 0; sia <= Polymer.stepsInArc; sia++) {\n const angle = startAngle + ((endAngle - startAngle) * (sia / stepsInArc));\n const siaCoord = Object(_interactor__WEBPACK_IMPORTED_MODULE_1__[\"trig\"])(pieRadius, angle - 90);\n approximatePiePath += \" L \" + siaCoord.x + \",\" + siaCoord.y;\n }\n approximatePiePath += \" L \" + 0 + \",\" + 0;\n approximatePiePath += \" Z\";\n return approximatePiePath;\n};\n\nPolymer.prototype.getAnnotationRectPath = function (startRes, endRes, annotation) {\n //domain as rectangle path\n let top, bottom, rungHeight;\n const rung = this.annotationTypes.indexOf(annotation.description);\n // console.log(\"rung\", rung, this.annotationTypes);\n if (rung === -1) {\n bottom = Polymer.STICKHEIGHT / 2;\n top = -Polymer.STICKHEIGHT / 2;\n } else {\n rungHeight = Polymer.STICKHEIGHT / this.annotationTypes.length;\n top = (-Polymer.STICKHEIGHT / 2) + (rung * rungHeight);\n bottom = top + rungHeight;\n }\n\n let annotX, annotSize, annotLength;\n if (startRes === \"n-n\") {\n annotX = this.getResXwithStickZoom(0.5) - 20;\n // var annotSize = (1 + (endRes - startRes));\n annotLength = 20;//annotSize * this.stickZoom;\n } else if (endRes === \"c-c\") {\n annotX = this.getResXwithStickZoom(this.size + 0.5);\n // var annotSize = (1 + (endRes - startRes));\n annotLength = 20;//annotSize * this.stickZoom;\n } else {\n annotX = this.getResXwithStickZoom(startRes - 0.5);\n annotSize = (1 + (endRes - startRes));\n annotLength = annotSize * this.stickZoom;\n }\n let rectPath = \"M \" + annotX + \",\" + bottom;\n for (let sia = 0; sia <= Polymer.stepsInArc; sia++) {\n const step = annotX + (annotLength * (sia / Polymer.stepsInArc));\n rectPath += \" L \" + step + \",\" + top;\n }\n rectPath += \" L \" + (annotX + annotLength) + \",\" + bottom +\n \" Z\";\n return rectPath;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvcG9seW1lci5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2ludGVyYWN0b3IvcG9seW1lci5qcz8wNGY2Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGQzIGZyb20gXCJkM1wiOyAvLyB0cmFuc2l0aW9ucyBhbmQgb3RoZXIgc3R1ZmZcbmltcG9ydCB7SW50ZXJhY3RvciwgdHJpZ30gZnJvbSBcIi4vaW50ZXJhY3RvclwiO1xuaW1wb3J0IHtBbm5vdGF0aW9ufSBmcm9tIFwiLi9hbm5vdGF0aW9uXCI7XG5pbXBvcnQge1NlcXVlbmNlRGF0dW19IGZyb20gXCIuLi9zZXF1ZW5jZS1kYXR1bVwiO1xuaW1wb3J0IHtzdmducywgTEFCRUxfWSwgcm90YXRlUG9pbnRBYm91dFBvaW50fSBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XG5cblBvbHltZXIuU1RJQ0tIRUlHSFQgPSAyMDsgLy9oZWlnaHQgb2Ygc3RpY2sgaW4gcGl4ZWxzXG5Qb2x5bWVyLk1BWFNJWkUgPSAwOyAvLyByZXNpZHVlIGNvdW50IG9mIGxvbmdlc3Qgc2VxdWVuY2VcblBvbHltZXIudHJhbnNpdGlvblRpbWUgPSA2NTA7XG5cbmV4cG9ydCBmdW5jdGlvbiBQb2x5bWVyKCkge1xufVxuXG5Qb2x5bWVyLnByb3RvdHlwZSA9IG5ldyBJbnRlcmFjdG9yKCk7XG5cbi8vc2VxdWVuY2UgPSBhbWlubyBhY2lkcyBpbiBVUFBFUkNBU0UsIGRpZ2l0cyBvciBsb3dlcmNhc2UgY2FuIGJlIHVzZWQgZm9yIG1vZGlmaWNhdGlvbiBpbmZvXG5Qb2x5bWVyLnByb3RvdHlwZS5zZXRTZXF1ZW5jZSA9IGZ1bmN0aW9uIChzZXF1ZW5jZSkge1xuICAgIC8vcmVtb3ZlIG1vZGlmaWNhdGlvbiBzaXRlIGluZm8gZnJvbSBzZXF1ZW5jZVxuICAgIHRoaXMuc2VxdWVuY2UgPSBzZXF1ZW5jZS5yZXBsYWNlKC9bXkEtWl0vZywgXCJcIik7XG4gICAgdGhpcy5zaXplID0gdGhpcy5zZXF1ZW5jZS5sZW5ndGg7XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS5nZXRTeW1ib2xSYWRpdXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIDE1O1xufTtcblxuUG9seW1lci5wcm90b3R5cGUuc2hvd0hpZ2hsaWdodCA9IGZ1bmN0aW9uIChzaG93KSB7XG4gICAgaWYgKHNob3cgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5oaWdobGlnaHQuc2V0QXR0cmlidXRlKFwic3Ryb2tlLW9wYWNpdHlcIiwgXCIxXCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcInN0cm9rZS1vcGFjaXR5XCIsIFwiMFwiKTtcbiAgICB9XG59O1xuXG5Qb2x5bWVyLm1pblhEaXN0ID0gMzA7XG5Qb2x5bWVyLnByb3RvdHlwZS5zZXRTdGlja1NjYWxlID0gZnVuY3Rpb24gKHNjYWxlLCBzdmdQKSB7XG4gICAgY29uc3Qgb2xkU2NhbGUgPSB0aGlzLnN0aWNrWm9vbTtcblxuICAgIC8vZGlzdCBmcm9tIGNlbnRyZVxuICAgIGNvbnN0IGR4ID0gKHRoaXMuaXggLSBzdmdQLngpO1xuICAgIGNvbnN0IGR5ID0gKHRoaXMuaXkgLSBzdmdQLnkpO1xuXG4gICAgLy8gbmV3IGRpc3QgZnJvbSBjZW50cmVcbiAgICBjb25zdCBueCA9IGR4ICogc2NhbGUgLyBvbGRTY2FsZTtcbiAgICBjb25zdCBueSA9IGR5ICogc2NhbGUgLyBvbGRTY2FsZTtcblxuICAgIC8vcmVxdWlyZWQgY2hhbmdlXG4gICAgY29uc3QgcnggPSBueCAtIGR4O1xuICAgIGxldCByeSA9IG55IC0gZHk7XG5cbiAgICBpZiAodGhpcy5yb3RhdGlvbiA9PT0gMCB8fCB0aGlzLnJvdGF0aW9uID09PSAxODApIHtcbiAgICAgICAgcnkgPSAwO1xuICAgIH1cblxuICAgIC8vbmV3IHBvc1xuICAgIGNvbnN0IHggPSB0aGlzLml4ICsgcng7XG4gICAgY29uc3QgeSA9IHRoaXMuaXkgKyByeTtcblxuICAgIHRoaXMuc3RpY2tab29tID0gc2NhbGU7XG4gICAgdGhpcy5zY2FsZSgpO1xuICAgIHRoaXMuc2V0UG9zaXRpb24oeCwgeSk7XG4gICAgdGhpcy5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTtcbn07XG5cblBvbHltZXIucHJvdG90eXBlLnNjYWxlID0gZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IHByb3RMZW5ndGggPSAodGhpcy5zaXplKSAqIHRoaXMuc3RpY2tab29tO1xuICAgIGlmICh0aGlzLmZvcm0gPT09IDEpIHtcbiAgICAgICAgY29uc3QgbGFiZWxUcmFuc2Zvcm0gPSBkMy50cmFuc2Zvcm0odGhpcy5sYWJlbFNWRy5nZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIikpO1xuICAgICAgICBjb25zdCBrID0gdGhpcy5hcHAuc3ZnRWxlbWVudC5jcmVhdGVTVkdNYXRyaXgoKS5yb3RhdGUobGFiZWxUcmFuc2Zvcm0ucm90YXRlKVxuICAgICAgICAgICAgLnRyYW5zbGF0ZSgoLSgoKHRoaXMuc2l6ZSAvIDIpICogdGhpcy5zdGlja1pvb20pICsgKHRoaXMublRlcm1pbnVzRmVhdHVyZSA/IDI1IDogMTApKSksIExBQkVMX1kpOyAvLy5zY2FsZSh6KS50cmFuc2xhdGUoLWMueCwgLWMueSk7XG4gICAgICAgIHRoaXMubGFiZWxTVkcudHJhbnNmb3JtLmJhc2VWYWwuaW5pdGlhbGl6ZSh0aGlzLmFwcC5zdmdFbGVtZW50LmNyZWF0ZVNWR1RyYW5zZm9ybUZyb21NYXRyaXgoaykpO1xuXG4gICAgICAgIGZvciAobGV0IFthbm5vdGF0aW9uVHlwZSwgYW5ub3RhdGlvbnNdIG9mIHRoaXMuYW5ub3RhdGlvblNldHMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFwcC5hbm5vdGF0aW9uU2V0c1Nob3duLmdldChhbm5vdGF0aW9uVHlwZSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBhbm5vIG9mIGFubm90YXRpb25zKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhbm5vLmZ1enp5U3RhcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlTdGFydC5zZXRBdHRyaWJ1dGUoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblJlY3RQYXRoKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluQmVnaW4sIGFubm8uc2VxRGF0dW0uYmVnaW4sIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5jZXJ0YWluKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgdGVtcEJlZ2luID0gYW5uby5zZXFEYXR1bS5iZWdpbjsgLy90b2RvIC0gbWlnaHQgYmUgYmV0dGVyIHRvIGhhdmUgc2VwZXJhdGUgYXR0IGluIFNlcXVlbmNlRGF0YSBmb3IgZW5kIG9mIHVuY2VydGFpbiBzdGFydFxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRlbXBFbmQgPSBhbm5vLnNlcURhdHVtLmVuZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhbm5vLnNlcURhdHVtLnVuY2VydGFpbkJlZ2luKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcEJlZ2luICs9IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wRW5kIC09IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25SZWN0UGF0aCh0ZW1wQmVnaW4sIHRlbXBFbmQsIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eUVuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZC5zZXRBdHRyaWJ1dGUoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblJlY3RQYXRoKGFubm8uc2VxRGF0dW0uZW5kLCBhbm5vLnNlcURhdHVtLnVuY2VydGFpbkVuZCwgYW5ubykpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZDMuc2VsZWN0KHRoaXMuYmFja2dyb3VuZClcbiAgICAgICAgICAgIC5hdHRyKFwid2lkdGhcIiwgcHJvdExlbmd0aClcbiAgICAgICAgICAgIC5hdHRyKFwieFwiLCB0aGlzLmdldFJlc1h3aXRoU3RpY2tab29tKDAuNSkpO1xuXG4gICAgICAgIGQzLnNlbGVjdCh0aGlzLm91dGxpbmUpXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIHByb3RMZW5ndGgpXG4gICAgICAgICAgICAuYXR0cihcInhcIiwgdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbSgwLjUpKTtcblxuICAgICAgICBkMy5zZWxlY3QodGhpcy5oaWdobGlnaHQpXG4gICAgICAgICAgICAuYXR0cihcIndpZHRoXCIsIHByb3RMZW5ndGggKyA1KVxuICAgICAgICAgICAgLmF0dHIoXCJ4XCIsIHRoaXMuZ2V0UmVzWHdpdGhTdGlja1pvb20oMC41KSAtIDIuNSk7XG5cblxuICAgICAgICB0aGlzLnNldFNjYWxlR3JvdXAoKTtcbiAgICB9XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS5zZXRTY2FsZUdyb3VwID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudXBwZXJHcm91cC5hcHBlbmRDaGlsZCh0aGlzLnRpY2tzKTsgLy93aWxsIGRvIG5vdGhpbmcgaWYgdGhpcy50aWNrcyBhbHJlYWR5IGFwcGVuZGVkIHRvIHRoaXMudXBwZXJncm91cFxuICAgIGQzLnNlbGVjdCh0aGlzLnRpY2tzKS5zZWxlY3RBbGwoXCIqXCIpLnJlbW92ZSgpO1xuXG4gICAgdGhpcy5zY2FsZUxhYmVscyA9IFtdO1xuICAgIGNvbnN0IFNjYWxlVGlja3NQZXJMYWJlbCA9IDI7IC8vIHZhcmllcyB3aXRoIHNjYWxlP1xuICAgIGxldCB0aWNrID0gLTE7XG4gICAgY29uc3QgbGFzdFRpY2tYID0gdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbSh0aGlzLnNpemUpO1xuXG4gICAgZm9yIChsZXQgcmVzID0gMTsgcmVzIDw9IHRoaXMuc2l6ZTsgcmVzKyspIHtcbiAgICAgICAgaWYgKHJlcyA9PT0gMSB8fFxuICAgICAgICAgICAgKChyZXMgJSAxMDAgPT09IDApICYmICgyMDAgKiB0aGlzLnN0aWNrWm9vbSA+IFBvbHltZXIubWluWERpc3QpKSB8fFxuICAgICAgICAgICAgKChyZXMgJSAxMCA9PT0gMCkgJiYgKDIwICogdGhpcy5zdGlja1pvb20gPiBQb2x5bWVyLm1pblhEaXN0KSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBjb25zdCB0eCA9IHRoaXMuZ2V0UmVzWHdpdGhTdGlja1pvb20ocmVzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0aWNrWm9vbSA+PSA4IHx8IHJlcyAhPT0gMSkge1xuICAgICAgICAgICAgICAgIHRpY2tBdCh0aGlzLCB0eCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aWNrID0gKHRpY2sgKyAxKSAlIFNjYWxlVGlja3NQZXJMYWJlbDtcbiAgICAgICAgICAgIC8vIGRvZXMgdGhpcyBvbmUgZ2V0IGEgbGFiZWw/XG4gICAgICAgICAgICBpZiAodGljayA9PT0gMCkgeyAvLyAmJiB0eCA+IDIwKSB7XG4gICAgICAgICAgICAgICAgaWYgKCh0eCArIFBvbHltZXIubWluWERpc3QpIDwgbGFzdFRpY2tYKSB7XG4gICAgICAgICAgICAgICAgICAgIHNjYWxlTGFiZWxBdCh0aGlzLCByZXMsIHR4KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RpY2tab29tID49IDgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNlcUxhYmVsR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwiZ1wiKTtcbiAgICAgICAgICAgIHNlcUxhYmVsR3JvdXAuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbShyZXMpICsgXCIgXCIgKyAwICsgXCIpXCIpO1xuICAgICAgICAgICAgY29uc3Qgc2VxTGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwidGV4dFwiKTtcbiAgICAgICAgICAgIHNlcUxhYmVsLmNsYXNzTGlzdC5hZGQoXCJsYWJlbFwiLCBcInNlcXVlbmNlXCIpO1xuICAgICAgICAgICAgLy9jc3M/XG4gICAgICAgICAgICBzZXFMYWJlbC5zZXRBdHRyaWJ1dGUoXCJ4XCIsIFwiMFwiKTtcbiAgICAgICAgICAgIHNlcUxhYmVsLnNldEF0dHJpYnV0ZShcInlcIiwgXCIzXCIpO1xuICAgICAgICAgICAgc2VxTGFiZWwuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGhpcy5zZXF1ZW5jZVtyZXMgLSAxXSkpO1xuICAgICAgICAgICAgc2VxTGFiZWxHcm91cC5hcHBlbmRDaGlsZChzZXFMYWJlbCk7XG4gICAgICAgICAgICB0aGlzLnNjYWxlTGFiZWxzLnB1c2goc2VxTGFiZWwpO1xuICAgICAgICAgICAgdGhpcy50aWNrcy5hcHBlbmRDaGlsZChzZXFMYWJlbEdyb3VwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzY2FsZUxhYmVsQXQodGhpcywgdGhpcy5zaXplLCBsYXN0VGlja1gpO1xuICAgIGlmICh0aGlzLnN0aWNrWm9vbSA+PSA4KSB7XG4gICAgICAgIHRpY2tBdCh0aGlzLCBsYXN0VGlja1gpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNjYWxlTGFiZWxBdChzZWxmLCB0ZXh0LCB0aWNrWCkge1xuICAgICAgICBjb25zdCBzY2FsZUxhYmVsR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwiZ1wiKTtcbiAgICAgICAgc2NhbGVMYWJlbEdyb3VwLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBcInRyYW5zbGF0ZShcIiArIHRpY2tYICsgXCIgXCIgKyAwICsgXCIpXCIpO1xuICAgICAgICBjb25zdCBzY2FsZUxhYmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInRleHRcIik7XG4gICAgICAgIHNjYWxlTGFiZWwuY2xhc3NMaXN0LmFkZChcImxhYmVsXCIsIFwic2NhbGUtbGFiZWxcIik7XG4gICAgICAgIHNjYWxlTGFiZWwuc2V0QXR0cmlidXRlKFwieFwiLCBcIjBcIik7XG4gICAgICAgIHNjYWxlTGFiZWwuc2V0QXR0cmlidXRlKFwieVwiLCBQb2x5bWVyLlNUSUNLSEVJR0hUICsgNCk7XG4gICAgICAgIHNjYWxlTGFiZWwuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dCkpO1xuICAgICAgICBzY2FsZUxhYmVsR3JvdXAuYXBwZW5kQ2hpbGQoc2NhbGVMYWJlbCk7XG4gICAgICAgIHNlbGYuc2NhbGVMYWJlbHMucHVzaChzY2FsZUxhYmVsKTtcbiAgICAgICAgc2VsZi50aWNrcy5hcHBlbmRDaGlsZChzY2FsZUxhYmVsR3JvdXApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRpY2tBdChzZWxmLCB0aWNrWCkge1xuICAgICAgICBjb25zdCB0aWNrID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImxpbmVcIik7XG4gICAgICAgIHRpY2suY2xhc3NMaXN0LmFkZChcInRpY2tcIik7XG4gICAgICAgIHRpY2suc2V0QXR0cmlidXRlKFwieDFcIiwgdGlja1gpO1xuICAgICAgICB0aWNrLnNldEF0dHJpYnV0ZShcInkxXCIsIFwiNVwiKTtcbiAgICAgICAgdGljay5zZXRBdHRyaWJ1dGUoXCJ4MlwiLCB0aWNrWCk7XG4gICAgICAgIHRpY2suc2V0QXR0cmlidXRlKFwieTJcIiwgXCIxMFwiKTtcbiAgICAgICAgc2VsZi50aWNrcy5hcHBlbmRDaGlsZCh0aWNrKTtcbiAgICB9XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS5zZXRGb3JtID0gZnVuY3Rpb24gKGZvcm0sIHN2Z1ApIHtcbiAgICBpZiAodGhpcy5idXN5ICE9PSB0cnVlKSB7XG4gICAgICAgIGlmIChmb3JtID09PSAxKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5mb3JtICE9PSAxKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50b1N0aWNrKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBpZiAodGhpcy5mb3JtICE9PSAwKSB7XG4gICAgICAgICAgICB0aGlzLnRvQ2lyY2xlKHN2Z1ApO1xuICAgICAgICAgICAgLy8gdmFyIHIgPSB0aGlzLmdldFN5bWJvbFJhZGl1cygpO1xuXG4gICAgICAgIH1cbiAgICAgICAgLy8gfVxuICAgIH1cbn07XG5cblBvbHltZXIucHJvdG90eXBlLnRvQ2lyY2xlID0gZnVuY3Rpb24gKHN2Z1ApIHtcbiAgICAvL3N2Z1AgPSBudWxsOy8vIHRlbXAgaGFjayAtIHlvdSBjYW4gdW5jb21tZW50IHRoaXMgaXMgeW91IGV4cGVyaWVuY2UgdGhpbmdzICdmbHlpbmcgb2ZmIHNjcmVlbidcbiAgICB0aGlzLmJ1c3kgPSB0cnVlO1xuXG4gICAgY29uc3QgciA9IHRoaXMuZ2V0U3ltYm9sUmFkaXVzKCk7XG4gICAgLy9cbiAgICBkMy5zZWxlY3QodGhpcy5iYWNrZ3JvdW5kKS50cmFuc2l0aW9uKClcbiAgICAgICAgLmF0dHIoXCJ4XCIsIC1yKS5hdHRyKFwieVwiLCAtcilcbiAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCByICogMikuYXR0cihcImhlaWdodFwiLCByICogMilcbiAgICAgICAgLmF0dHIoXCJyeFwiLCByKS5hdHRyKFwicnlcIiwgcilcbiAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuICAgIGQzLnNlbGVjdCh0aGlzLm91dGxpbmUpLnRyYW5zaXRpb24oKVxuICAgICAgICAuYXR0cihcInhcIiwgLXIpLmF0dHIoXCJ5XCIsIC1yKVxuICAgICAgICAuYXR0cihcIndpZHRoXCIsIHIgKiAyKS5hdHRyKFwiaGVpZ2h0XCIsIHIgKiAyKVxuICAgICAgICAuYXR0cihcInJ4XCIsIHIpLmF0dHIoXCJyeVwiLCByKVxuICAgICAgICAuZHVyYXRpb24oUG9seW1lci50cmFuc2l0aW9uVGltZSk7XG4gICAgLy8gZDMuc2VsZWN0KHRoaXMuYW5ub3RhdGlvbnNTdmdHcm91cCkudHJhbnNpdGlvbigpXG4gICAgLy8gICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIFwic2NhbGUoMSwgMSlcIilcbiAgICAvLyAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuICAgIGQzLnNlbGVjdCh0aGlzLmhpZ2hsaWdodCkudHJhbnNpdGlvbigpXG4gICAgICAgIC5hdHRyKFwieFwiLCAtcikuYXR0cihcInlcIiwgLXIpXG4gICAgICAgIC5hdHRyKFwid2lkdGhcIiwgciAqIDIpLmF0dHIoXCJoZWlnaHRcIiwgciAqIDIpXG4gICAgICAgIC5hdHRyKFwicnhcIiwgcikuYXR0cihcInJ5XCIsIHIpXG4gICAgICAgIC5kdXJhdGlvbihQb2x5bWVyLnRyYW5zaXRpb25UaW1lKTtcblxuICAgIGNvbnN0IHN0aWNrWm9vbUludGVycG9sID0gZDMuaW50ZXJwb2xhdGUodGhpcy5zdGlja1pvb20sIDApO1xuICAgIC8vIHZhciByb3RhdGlvbkludGVycG9sID0gZDMuaW50ZXJwb2xhdGUoKHRoaXMucm90YXRpb24gPiAxODApID8gdGhpcy5yb3RhdGlvbiAtIDM2MCA6IHRoaXMucm90YXRpb24sIDApO1xuICAgIGNvbnN0IGxhYmVsVHJhbnNmb3JtID0gZDMudHJhbnNmb3JtKHRoaXMubGFiZWxTVkcuZ2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIpKTtcbiAgICBjb25zdCBsYWJlbFN0YXJ0UG9pbnQgPSBsYWJlbFRyYW5zZm9ybS50cmFuc2xhdGVbMF07XG4gICAgY29uc3QgbGFiZWxUcmFuc2xhdGVJbnRlcnBvbCA9IGQzLmludGVycG9sYXRlKGxhYmVsU3RhcnRQb2ludCwgLShyICsgNSkpO1xuXG4gICAgbGV0IHhJbnRlcnBvbCA9IG51bGwsXG4gICAgICAgIHlJbnRlcnBvbCA9IG51bGw7XG4gICAgaWYgKHR5cGVvZiBzdmdQICE9PSBcInVuZGVmaW5lZFwiICYmIHN2Z1AgIT09IG51bGwpIHtcbiAgICAgICAgeEludGVycG9sID0gZDMuaW50ZXJwb2xhdGUodGhpcy5peCwgc3ZnUC54KTtcbiAgICAgICAgeUludGVycG9sID0gZDMuaW50ZXJwb2xhdGUodGhpcy5peSwgc3ZnUC55KTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBkMy5zZWxlY3QodGhpcy50aWNrcykudHJhbnNpdGlvbigpLmF0dHIoXCJvcGFjaXR5XCIsIDApLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUgLyA0KVxuICAgICAgICAuZWFjaChcImVuZFwiLFxuICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGQzLnNlbGVjdCh0aGlzKS5zZWxlY3RBbGwoXCIqXCIpLnJlbW92ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgZDMuc2VsZWN0KHRoaXMuaGlnaGxpZ2h0KS50cmFuc2l0aW9uKClcbiAgICAgICAgLmF0dHIoXCJ3aWR0aFwiLCAociAqIDIpICsgNSkuYXR0cihcImhlaWdodFwiLCAociAqIDIpICsgNSlcbiAgICAgICAgLmF0dHIoXCJ4XCIsIC1yIC0gMi41KS5hdHRyKFwieVwiLCAtciAtIDIuNSlcbiAgICAgICAgLmF0dHIoXCJyeFwiLCByICsgMi41KS5hdHRyKFwicnlcIiwgciArIDIuNSlcbiAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuXG4gICAgZnVuY3Rpb24gY2hhbmdlRnV6enlTdGFydFRvQXJjUGF0aChhbm5vKSB7XG4gICAgICAgIGQzLnNlbGVjdChhbm5vLmZ1enp5U3RhcnQpLmF0dHIoXCJkXCIsIHNlbGYuZ2V0QW5ub3RhdGlvblBpZVNsaWNlQXJjUGF0aChhbm5vLnNlcURhdHVtLnVuY2VydGFpbkJlZ2luLCBhbm5vLnNlcURhdHVtLmJlZ2luLCBhbm5vKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hhbmdlQ2VydGFpblRvQXJjUGF0aChhbm5vKSB7XG4gICAgICAgIGQzLnNlbGVjdChhbm5vLmNlcnRhaW4pLmF0dHIoXCJkXCIsIHNlbGYuZ2V0QW5ub3RhdGlvblBpZVNsaWNlQXJjUGF0aChhbm5vLnNlcURhdHVtLmJlZ2luLCBhbm5vLnNlcURhdHVtLmVuZCwgYW5ubykpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNoYW5nZUZ1enp5RW5kVG9BcmNQYXRoKGFubm8pIHtcbiAgICAgICAgZDMuc2VsZWN0KGFubm8uZnV6enlFbmQpLmF0dHIoXCJkXCIsIHNlbGYuZ2V0QW5ub3RhdGlvblBpZVNsaWNlQXJjUGF0aChhbm5vLnNlcURhdHVtLmVuZCwgYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQsIGFubm8pKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBbYW5ub3RhdGlvblR5cGUsIGFubm90YXRpb25zXSBvZiB0aGlzLmFubm90YXRpb25TZXRzKSB7XG4gICAgICAgIGlmICh0aGlzLmFwcC5hbm5vdGF0aW9uU2V0c1Nob3duLmdldChhbm5vdGF0aW9uVHlwZSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGFubm8gb2YgYW5ub3RhdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eVN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZ1enp5U3RhcnQgPSBhbm5vLmZ1enp5U3RhcnQ7XG4gICAgICAgICAgICAgICAgICAgIGQzLnNlbGVjdChmdXp6eVN0YXJ0KS50cmFuc2l0aW9uKCkuYXR0cihcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUGllU2xpY2VBcHByb3hpbWF0ZVBhdGgoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5CZWdpbiwgYW5uby5zZXFEYXR1bS5iZWdpbiwgYW5ubykpXG4gICAgICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oUG9seW1lci50cmFuc2l0aW9uVGltZSkuZWFjaChcImVuZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUZ1enp5U3RhcnRUb0FyY1BhdGgoYW5ubyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGFubm8uY2VydGFpbikge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjZXJ0YWluID0gYW5uby5jZXJ0YWluO1xuICAgICAgICAgICAgICAgICAgICBkMy5zZWxlY3QoY2VydGFpbikudHJhbnNpdGlvbigpLmF0dHIoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblBpZVNsaWNlQXBwcm94aW1hdGVQYXRoKGFubm8uc2VxRGF0dW0uYmVnaW4sIGFubm8uc2VxRGF0dW0uZW5kLCBhbm5vKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC5kdXJhdGlvbihQb2x5bWVyLnRyYW5zaXRpb25UaW1lKS5lYWNoKFwiZW5kXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhbmdlQ2VydGFpblRvQXJjUGF0aChhbm5vKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eUVuZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmdXp6eUVuZCA9IGFubm8uZnV6enlFbmQ7XG4gICAgICAgICAgICAgICAgICAgIGQzLnNlbGVjdChmdXp6eUVuZCkudHJhbnNpdGlvbigpLmF0dHIoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblBpZVNsaWNlQXBwcm94aW1hdGVQYXRoKGFubm8uc2VxRGF0dW0uZW5kLCBhbm5vLnNlcURhdHVtLnVuY2VydGFpbkVuZCwgYW5ubykpXG4gICAgICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oUG9seW1lci50cmFuc2l0aW9uVGltZSkuZWFjaChcImVuZFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5nZUZ1enp5RW5kVG9BcmNQYXRoKGFubm8pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG9yaWdpbmFsU3RpY2tab29tID0gdGhpcy5zdGlja1pvb207XG4gICAgY29uc3Qgb3JpZ2luYWxSb3RhdGlvbiA9IHRoaXMucm90YXRpb247XG4gICAgY29uc3QgY3ViaWNJbk91dCA9IGQzLmVhc2UoXCJjdWJpYy1pbi1vdXRcIik7XG4gICAgZDMudGltZXIoZnVuY3Rpb24gKGVsYXBzZWQpIHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZShlbGFwc2VkIC8gUG9seW1lci50cmFuc2l0aW9uVGltZSk7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiB1cGRhdGUoaW50ZXJwKSB7XG4gICAgICAgIGNvbnN0IGxhYmVsVHJhbnNmb3JtID0gZDMudHJhbnNmb3JtKHNlbGYubGFiZWxTVkcuZ2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIpKTtcbiAgICAgICAgY29uc3QgayA9IHNlbGYuYXBwLnN2Z0VsZW1lbnQuY3JlYXRlU1ZHTWF0cml4KCkucm90YXRlKGxhYmVsVHJhbnNmb3JtLnJvdGF0ZSkudHJhbnNsYXRlKGxhYmVsVHJhbnNsYXRlSW50ZXJwb2woY3ViaWNJbk91dChpbnRlcnApKSwgTEFCRUxfWSk7IC8vLnNjYWxlKHopLnRyYW5zbGF0ZSgtYy54LCAtYy55KTtcbiAgICAgICAgc2VsZi5sYWJlbFNWRy50cmFuc2Zvcm0uYmFzZVZhbC5pbml0aWFsaXplKHNlbGYuYXBwLnN2Z0VsZW1lbnQuY3JlYXRlU1ZHVHJhbnNmb3JtRnJvbU1hdHJpeChrKSk7XG4gICAgICAgIC8vflxuICAgICAgICBpZiAoeEludGVycG9sICE9PSBudWxsKSB7XG4gICAgICAgICAgICBzZWxmLnNldFBvc2l0aW9uKHhJbnRlcnBvbChjdWJpY0luT3V0KGludGVycCkpLCB5SW50ZXJwb2woY3ViaWNJbk91dChpbnRlcnApKSk7XG4gICAgICAgIH1cblxuICAgICAgICBzZWxmLnN0aWNrWm9vbSA9IHN0aWNrWm9vbUludGVycG9sKGN1YmljSW5PdXQoaW50ZXJwKSk7XG4gICAgICAgIHNlbGYuc2V0QWxsTGlua0Nvb3JkaW5hdGVzKCk7XG5cbiAgICAgICAgaWYgKGludGVycCA9PT0gMSkgeyAvLyBmaW5pc2hlZCAtIHRpZHkgdXBcbiAgICAgICAgICAgIHNlbGYuZm9ybSA9IDA7XG4gICAgICAgICAgICBzZWxmLmNoZWNrTGlua3MoKTtcbiAgICAgICAgICAgIHNlbGYuc3RpY2tab29tID0gb3JpZ2luYWxTdGlja1pvb207XG4gICAgICAgICAgICBzZWxmLnJvdGF0aW9uID0gb3JpZ2luYWxSb3RhdGlvbjtcbiAgICAgICAgICAgIHNlbGYuYnVzeSA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAoaW50ZXJwID4gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHVwZGF0ZSgxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbn07XG5cblBvbHltZXIucHJvdG90eXBlLnRvU3RpY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5idXN5ID0gdHJ1ZTtcbiAgICB0aGlzLmZvcm0gPSAxO1xuXG4gICAgLy9yZW1vdmUgcHJvdC1wcm90IGxpbmtzIC0gd291bGQgaXQgYmUgYmV0dGVyIGlmIGNoZWNrTGlua3MgZGlkIHRoaXM/IC0gdGhpbmsgbm90XG4gICAgY29uc3QgYyA9IHRoaXMuYmluYXJ5TGlua3MudmFsdWVzKCkubGVuZ3RoO1xuICAgIGZvciAobGV0IGwgPSAwOyBsIDwgYzsgbCsrKSB7XG4gICAgICAgIGNvbnN0IGxpbmsgPSB0aGlzLmJpbmFyeUxpbmtzLnZhbHVlcygpW2xdO1xuICAgICAgICAvL291dCB3aXRoIHRoZSBvbGRcbiAgICAgICAgaWYgKGxpbmsuc2hvd24pIHtcbiAgICAgICAgICAgIGxpbmsuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcHJvdExlbmd0aCA9IHRoaXMuc2l6ZSAqIHRoaXMuc3RpY2tab29tO1xuICAgIGNvbnN0IHIgPSB0aGlzLmdldFN5bWJvbFJhZGl1cygpO1xuXG4gICAgY29uc3QgbGVuZ3RoSW50ZXJwb2wgPSBkMy5pbnRlcnBvbGF0ZSgoMiAqIHIpLCBwcm90TGVuZ3RoKTtcbiAgICBjb25zdCBzdGlja1pvb21JbnRlcnBvbCA9IGQzLmludGVycG9sYXRlKDAsIHRoaXMuc3RpY2tab29tKTtcbiAgICBjb25zdCBsYWJlbFRyYW5zbGF0ZUludGVycG9sID0gZDMuaW50ZXJwb2xhdGUoLShyICsgNSksIC0oKCh0aGlzLnNpemUgLyAyKSAqIHRoaXMuc3RpY2tab29tKSArICh0aGlzLm5UZXJtaW51c0ZlYXR1cmUgPyAyNSA6IDEwKSkpO1xuXG4gICAgY29uc3Qgb3JpZ1N0aWNrWm9vbSA9IHRoaXMuc3RpY2tab29tO1xuICAgIHRoaXMuc3RpY2tab29tID0gMDtcbiAgICB0aGlzLmNoZWNrTGlua3ModGhpcy5iaW5hcnlMaW5rcyk7XG4gICAgdGhpcy5jaGVja0xpbmtzKHRoaXMuc2VsZkxpbmspO1xuICAgIHRoaXMuY2hlY2tMaW5rcyh0aGlzLnNlcXVlbmNlTGlua3MpO1xuICAgIHRoaXMuc3RpY2tab29tID0gb3JpZ1N0aWNrWm9vbTtcblxuICAgIGQzLnNlbGVjdCh0aGlzLmJhY2tncm91bmQpLnRyYW5zaXRpb24oKSAvLy5hdHRyKFwic3Ryb2tlLW9wYWNpdHlcIiwgMSlcbiAgICAgICAgLmF0dHIoXCJoZWlnaHRcIiwgUG9seW1lci5TVElDS0hFSUdIVClcbiAgICAgICAgLmF0dHIoXCJ5XCIsIC1Qb2x5bWVyLlNUSUNLSEVJR0hUIC8gMilcbiAgICAgICAgLmF0dHIoXCJyeFwiLCAwKS5hdHRyKFwicnlcIiwgMClcbiAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuXG4gICAgZDMuc2VsZWN0KHRoaXMub3V0bGluZSkudHJhbnNpdGlvbigpIC8vLmF0dHIoXCJzdHJva2Utb3BhY2l0eVwiLCAxKVxuICAgICAgICAuYXR0cihcImhlaWdodFwiLCBQb2x5bWVyLlNUSUNLSEVJR0hUKVxuICAgICAgICAuYXR0cihcInlcIiwgLVBvbHltZXIuU1RJQ0tIRUlHSFQgLyAyKVxuICAgICAgICAuYXR0cihcInJ4XCIsIDApLmF0dHIoXCJyeVwiLCAwKVxuICAgICAgICAuZHVyYXRpb24oUG9seW1lci50cmFuc2l0aW9uVGltZSk7XG5cbiAgICBkMy5zZWxlY3QodGhpcy5oaWdobGlnaHQpLnRyYW5zaXRpb24oKVxuICAgICAgICAuYXR0cihcIndpZHRoXCIsIHByb3RMZW5ndGggKyA1KS5hdHRyKFwiaGVpZ2h0XCIsIFBvbHltZXIuU1RJQ0tIRUlHSFQgKyA1KVxuICAgICAgICAuYXR0cihcInhcIiwgdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbSgwLjUpIC0gMi41KS5hdHRyKFwieVwiLCAoLVBvbHltZXIuU1RJQ0tIRUlHSFQgLyAyKSAtIDIuNSlcbiAgICAgICAgLmF0dHIoXCJyeFwiLCAwKS5hdHRyKFwicnlcIiwgMClcbiAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuXG4gICAgZm9yIChsZXQgW2Fubm90YXRpb25UeXBlLCBhbm5vdGF0aW9uc10gb2YgdGhpcy5hbm5vdGF0aW9uU2V0cykge1xuICAgICAgICBpZiAodGhpcy5hcHAuYW5ub3RhdGlvblNldHNTaG93bi5nZXQoYW5ub3RhdGlvblR5cGUpID09PSB0cnVlKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBhbm5vIG9mIGFubm90YXRpb25zKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFubm8uZnV6enlTdGFydCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmdXp6eVN0YXJ0ID0gYW5uby5mdXp6eVN0YXJ0O1xuICAgICAgICAgICAgICAgICAgICBmdXp6eVN0YXJ0LnNldEF0dHJpYnV0ZShcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUGllU2xpY2VBcHByb3hpbWF0ZVBhdGgoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5CZWdpbiwgYW5uby5zZXFEYXR1bS5iZWdpbiwgYW5ubykpO1xuICAgICAgICAgICAgICAgICAgICBkMy5zZWxlY3QoZnV6enlTdGFydCkudHJhbnNpdGlvbigpLmF0dHIoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblJlY3RQYXRoKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluQmVnaW4sIGFubm8uc2VxRGF0dW0uYmVnaW4sIGFubm8pKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYW5uby5jZXJ0YWluKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNlcnRhaW4gPSBhbm5vLmNlcnRhaW47XG4gICAgICAgICAgICAgICAgICAgIGxldCB0ZW1wQmVnaW4gPSBhbm5vLnNlcURhdHVtLmJlZ2luOyAvL3RvZG8gLSBtaWdodCBiZSBiZXR0ZXIgdG8gaGF2ZSBzZXBlcmF0ZSBhdHQgaW4gU2VxdWVuY2VEYXRhIGZvciBlbmQgb2YgdW5jZXJ0YWluIHN0YXJ0XG4gICAgICAgICAgICAgICAgICAgIGxldCB0ZW1wRW5kID0gYW5uby5zZXFEYXR1bS5lbmQ7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhbm5vLnNlcURhdHVtLnVuY2VydGFpbkJlZ2luKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wQmVnaW4gKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBFbmQgLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25QaWVTbGljZUFwcHJveGltYXRlUGF0aCh0ZW1wQmVnaW4sIHRlbXBFbmQsIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgZDMuc2VsZWN0KGNlcnRhaW4pLnRyYW5zaXRpb24oKS5hdHRyKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25SZWN0UGF0aCh0ZW1wQmVnaW4sIHRlbXBFbmQsIGFubm8pKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmR1cmF0aW9uKFBvbHltZXIudHJhbnNpdGlvblRpbWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eUVuZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmdXp6eUVuZCA9IGFubm8uZnV6enlFbmQ7XG4gICAgICAgICAgICAgICAgICAgIGZ1enp5RW5kLnNldEF0dHJpYnV0ZShcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUGllU2xpY2VBcHByb3hpbWF0ZVBhdGgoYW5uby5zZXFEYXR1bS5lbmQsIGFubm8uc2VxRGF0dW0udW5jZXJ0YWluRW5kLCBhbm5vKSk7XG4gICAgICAgICAgICAgICAgICAgIGQzLnNlbGVjdChmdXp6eUVuZCkudHJhbnNpdGlvbigpLmF0dHIoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblJlY3RQYXRoKGFubm8uc2VxRGF0dW0uZW5kLCBhbm5vLnNlcURhdHVtLnVuY2VydGFpbkVuZCwgYW5ubykpXG4gICAgICAgICAgICAgICAgICAgICAgICAuZHVyYXRpb24oUG9seW1lci50cmFuc2l0aW9uVGltZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgY29uc3QgY3ViaWNJbk91dCA9IGQzLmVhc2UoXCJjdWJpYy1pbi1vdXRcIik7XG4gICAgZDMudGltZXIoZnVuY3Rpb24gKGVsYXBzZWQpIHtcbiAgICAgICAgcmV0dXJuIHVwZGF0ZShlbGFwc2VkIC8gUG9seW1lci50cmFuc2l0aW9uVGltZSk7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiB1cGRhdGUoaW50ZXJwKSB7XG4gICAgICAgIGNvbnN0IGxhYmVsVHJhbnNmb3JtID0gZDMudHJhbnNmb3JtKHNlbGYubGFiZWxTVkcuZ2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIpKTtcbiAgICAgICAgY29uc3QgayA9IHNlbGYuYXBwLnN2Z0VsZW1lbnQuY3JlYXRlU1ZHTWF0cml4KCkucm90YXRlKGxhYmVsVHJhbnNmb3JtLnJvdGF0ZSkudHJhbnNsYXRlKGxhYmVsVHJhbnNsYXRlSW50ZXJwb2woY3ViaWNJbk91dChpbnRlcnApKSwgTEFCRUxfWSk7IC8vLnNjYWxlKHopLnRyYW5zbGF0ZSgtYy54LCAtYy55KTtcbiAgICAgICAgc2VsZi5sYWJlbFNWRy50cmFuc2Zvcm0uYmFzZVZhbC5pbml0aWFsaXplKHNlbGYuYXBwLnN2Z0VsZW1lbnQuY3JlYXRlU1ZHVHJhbnNmb3JtRnJvbU1hdHJpeChrKSk7XG5cbiAgICAgICAgY29uc3QgY3VycmVudExlbmd0aCA9IGxlbmd0aEludGVycG9sKGN1YmljSW5PdXQoaW50ZXJwKSk7XG4gICAgICAgIGQzLnNlbGVjdChzZWxmLmhpZ2hsaWdodCkuYXR0cihcIndpZHRoXCIsIGN1cnJlbnRMZW5ndGgpLmF0dHIoXCJ4XCIsIC0oY3VycmVudExlbmd0aCAvIDIpICsgKDAuNSAqIHNlbGYuc3RpY2tab29tKSk7XG4gICAgICAgIGQzLnNlbGVjdChzZWxmLm91dGxpbmUpLmF0dHIoXCJ3aWR0aFwiLCBjdXJyZW50TGVuZ3RoKS5hdHRyKFwieFwiLCAtKGN1cnJlbnRMZW5ndGggLyAyKSArICgwLjUgKiBzZWxmLnN0aWNrWm9vbSkpO1xuICAgICAgICBkMy5zZWxlY3Qoc2VsZi5iYWNrZ3JvdW5kKS5hdHRyKFwid2lkdGhcIiwgY3VycmVudExlbmd0aCkuYXR0cihcInhcIiwgLShjdXJyZW50TGVuZ3RoIC8gMikgKyAoMC41ICogc2VsZi5zdGlja1pvb20pKTtcbiAgICAgICAgc2VsZi5zdGlja1pvb20gPSBzdGlja1pvb21JbnRlcnBvbChjdWJpY0luT3V0KGludGVycCkpO1xuICAgICAgICBzZWxmLnNldEFsbExpbmtDb29yZGluYXRlcygpO1xuXG4gICAgICAgIGlmIChpbnRlcnAgPT09IDEpIHsgLy8gZmluaXNoZWQgLSB0aWR5IHVwXG4gICAgICAgICAgICBzZWxmLmJ1c3kgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKGludGVycCA+IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB1cGRhdGUoMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBkMy5zZWxlY3QodGhpcy50aWNrcykuYXR0cihcIm9wYWNpdHlcIiwgMCk7XG4gICAgdGhpcy5zZXRTY2FsZUdyb3VwKCk7XG4gICAgZDMuc2VsZWN0KHRoaXMudGlja3MpLnRyYW5zaXRpb24oKS5hdHRyKFwib3BhY2l0eVwiLCAxKVxuICAgICAgICAuZGVsYXkoUG9seW1lci50cmFuc2l0aW9uVGltZSAqIDAuOCkuZHVyYXRpb24oUG9seW1lci50cmFuc2l0aW9uVGltZSAvIDIpO1xufTtcblxuXG5Qb2x5bWVyLnByb3RvdHlwZS50b1N0aWNrTm9UcmFuc2l0aW9uID0gZnVuY3Rpb24gKCkgeyAvL3RvZG8gdGlkeVxuICAgIHRoaXMuYnVzeSA9IHRydWU7XG4gICAgdGhpcy5mb3JtID0gMTtcblxuICAgIC8vcmVtb3ZlIHByb3QtcHJvdCBsaW5rcyAtIHdvdWxkIGl0IGJlIGJldHRlciBpZiBjaGVja0xpbmtzIGRpZCB0aGlzPyAtIHRoaW5rIG5vdFxuICAgIGNvbnN0IGMgPSB0aGlzLmJpbmFyeUxpbmtzLnZhbHVlcygpLmxlbmd0aDtcbiAgICBmb3IgKGxldCBsID0gMDsgbCA8IGM7IGwrKykge1xuICAgICAgICBjb25zdCBsaW5rID0gdGhpcy5iaW5hcnlMaW5rcy52YWx1ZXMoKVtsXTtcbiAgICAgICAgLy9vdXQgd2l0aCB0aGUgb2xkXG4gICAgICAgIGlmIChsaW5rLnNob3duKSB7XG4gICAgICAgICAgICBsaW5rLmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHByb3RMZW5ndGggPSB0aGlzLnNpemUgKiB0aGlzLnN0aWNrWm9vbTtcbiAgICBjb25zdCByID0gdGhpcy5nZXRTeW1ib2xSYWRpdXMoKTtcblxuICAgIGNvbnN0IGxlbmd0aEludGVycG9sID0gZDMuaW50ZXJwb2xhdGUoKDIgKiByKSwgcHJvdExlbmd0aCk7XG4gICAgY29uc3QgbGFiZWxUcmFuc2xhdGVJbnRlcnBvbCA9IGQzLmludGVycG9sYXRlKC0ociArIDUpLCAtKCgodGhpcy5zaXplIC8gMikgKiB0aGlzLnN0aWNrWm9vbSkgKyAodGhpcy5uVGVybWludXNGZWF0dXJlID8gMjUgOiAxMCkpKTtcblxuICAgIHRoaXMuY2hlY2tMaW5rcyh0aGlzLmJpbmFyeUxpbmtzKTtcbiAgICB0aGlzLmNoZWNrTGlua3ModGhpcy5zZWxmTGluayk7XG4gICAgdGhpcy5jaGVja0xpbmtzKHRoaXMuc2VxdWVuY2VMaW5rcyk7XG5cbiAgICBkMy5zZWxlY3QodGhpcy5iYWNrZ3JvdW5kKVxuICAgICAgICAuYXR0cihcImhlaWdodFwiLCBQb2x5bWVyLlNUSUNLSEVJR0hUKVxuICAgICAgICAuYXR0cihcInlcIiwgLVBvbHltZXIuU1RJQ0tIRUlHSFQgLyAyKVxuICAgICAgICAuYXR0cihcInJ4XCIsIDApLmF0dHIoXCJyeVwiLCAwKTtcblxuICAgIGQzLnNlbGVjdCh0aGlzLm91dGxpbmUpXG4gICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIFBvbHltZXIuU1RJQ0tIRUlHSFQpXG4gICAgICAgIC5hdHRyKFwieVwiLCAtUG9seW1lci5TVElDS0hFSUdIVCAvIDIpXG4gICAgICAgIC5hdHRyKFwicnhcIiwgMCkuYXR0cihcInJ5XCIsIDApO1xuXG4gICAgZDMuc2VsZWN0KHRoaXMuaGlnaGxpZ2h0KVxuICAgICAgICAuYXR0cihcIndpZHRoXCIsIHByb3RMZW5ndGggKyA1KS5hdHRyKFwiaGVpZ2h0XCIsIFBvbHltZXIuU1RJQ0tIRUlHSFQgKyA1KVxuICAgICAgICAuYXR0cihcInhcIiwgdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbSgwLjUpIC0gMi41KS5hdHRyKFwieVwiLCAoLVBvbHltZXIuU1RJQ0tIRUlHSFQgLyAyKSAtIDIuNSlcbiAgICAgICAgLmF0dHIoXCJyeFwiLCAwKS5hdHRyKFwicnlcIiwgMCk7XG5cbiAgICBmb3IgKGxldCBbYW5ub3RhdGlvblR5cGUsIGFubm90YXRpb25zXSBvZiB0aGlzLmFubm90YXRpb25TZXRzKSB7XG4gICAgICAgIGlmICh0aGlzLmFwcC5hbm5vdGF0aW9uU2V0c1Nob3duLmdldChhbm5vdGF0aW9uVHlwZSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGFubm8gb2YgYW5ub3RhdGlvbnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eVN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZ1enp5U3RhcnQgPSBhbm5vLmZ1enp5U3RhcnQ7XG4gICAgICAgICAgICAgICAgICAgIGQzLnNlbGVjdChmdXp6eVN0YXJ0KS5hdHRyKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25SZWN0UGF0aChhbm5vLnNlcURhdHVtLnVuY2VydGFpbkJlZ2luLCBhbm5vLnNlcURhdHVtLmJlZ2luLCBhbm5vKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChhbm5vLmNlcnRhaW4pIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRlbXBCZWdpbiA9IGFubm8uc2VxRGF0dW0uYmVnaW47IC8vdG9kbyAtIG1pZ2h0IGJlIGJldHRlciB0byBoYXZlIHNlcGVyYXRlIGF0dCBpbiBTZXF1ZW5jZURhdGEgZm9yIGVuZCBvZiB1bmNlcnRhaW4gc3RhcnRcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRlbXBFbmQgPSBhbm5vLnNlcURhdHVtLmVuZDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFubm8uc2VxRGF0dW0udW5jZXJ0YWluQmVnaW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBCZWdpbiArPSAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChhbm5vLnNlcURhdHVtLnVuY2VydGFpbkVuZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVtcEVuZCAtPSAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFubm8uY2VydGFpbi5zZXRBdHRyaWJ1dGUoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblJlY3RQYXRoKHRlbXBCZWdpbiwgdGVtcEVuZCwgYW5ubykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYW5uby5mdXp6eUVuZCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmdXp6eUVuZCA9IGFubm8uZnV6enlFbmQ7XG4gICAgICAgICAgICAgICAgICAgIGQzLnNlbGVjdChmdXp6eUVuZCkgLyoudHJhbnNpdGlvbigpKi8gLmF0dHIoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblJlY3RQYXRoKGFubm8uc2VxRGF0dW0uZW5kLCBhbm5vLnNlcURhdHVtLnVuY2VydGFpbkVuZCwgYW5ubykpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgY29uc3QgbGFiZWxUcmFuc2Zvcm0gPSBkMy50cmFuc2Zvcm0oc2VsZi5sYWJlbFNWRy5nZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIikpO1xuICAgIGNvbnN0IGsgPSBzZWxmLmFwcC5zdmdFbGVtZW50LmNyZWF0ZVNWR01hdHJpeCgpLnJvdGF0ZShsYWJlbFRyYW5zZm9ybS5yb3RhdGUpLnRyYW5zbGF0ZShsYWJlbFRyYW5zbGF0ZUludGVycG9sKDEpLCBMQUJFTF9ZKTsgLy8uc2NhbGUoeikudHJhbnNsYXRlKC1jLngsIC1jLnkpO1xuICAgIHNlbGYubGFiZWxTVkcudHJhbnNmb3JtLmJhc2VWYWwuaW5pdGlhbGl6ZShzZWxmLmFwcC5zdmdFbGVtZW50LmNyZWF0ZVNWR1RyYW5zZm9ybUZyb21NYXRyaXgoaykpO1xuXG4gICAgY29uc3QgY3VycmVudExlbmd0aCA9IGxlbmd0aEludGVycG9sKDEpO1xuICAgIGQzLnNlbGVjdChzZWxmLmhpZ2hsaWdodCkuYXR0cihcIndpZHRoXCIsIGN1cnJlbnRMZW5ndGgpLmF0dHIoXCJ4XCIsIC0oY3VycmVudExlbmd0aCAvIDIpICsgKDAuNSAqIHNlbGYuc3RpY2tab29tKSk7XG4gICAgZDMuc2VsZWN0KHNlbGYub3V0bGluZSkuYXR0cihcIndpZHRoXCIsIGN1cnJlbnRMZW5ndGgpLmF0dHIoXCJ4XCIsIC0oY3VycmVudExlbmd0aCAvIDIpICsgKDAuNSAqIHNlbGYuc3RpY2tab29tKSk7XG4gICAgZDMuc2VsZWN0KHNlbGYuYmFja2dyb3VuZCkuYXR0cihcIndpZHRoXCIsIGN1cnJlbnRMZW5ndGgpLmF0dHIoXCJ4XCIsIC0oY3VycmVudExlbmd0aCAvIDIpICsgKDAuNSAqIHNlbGYuc3RpY2tab29tKSk7XG4gICAgc2VsZi5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTtcblxuICAgIHRoaXMuc2V0U2NhbGVHcm91cCgpO1xuICAgIGQzLnNlbGVjdCh0aGlzLnRpY2tzKS5hdHRyKFwib3BhY2l0eVwiLCAxKTtcblxuICAgIHNlbGYuYnVzeSA9IGZhbHNlO1xufTtcblxuUG9seW1lci5wcm90b3R5cGUuZ2V0UmVzWHdpdGhTdGlja1pvb20gPSBmdW5jdGlvbiAocikge1xuICAgIC8vIGlmIChpc05hTihyKSkge1xuICAgIC8vICAgICBjb25zb2xlLmVycm9yKFwiTk9UIE5VTUJFUlwiKTtcbiAgICAvLyB9XG4gICAgaWYgKHIgPT09IFwibi1uXCIpIHtcbiAgICAgICAgcmV0dXJuICgtdGhpcy5zaXplIC8gMiAqIHRoaXMuc3RpY2tab29tKSAtIDIwO1xuICAgIH0gZWxzZSBpZiAociA9PT0gXCJjLWNcIikge1xuICAgICAgICByZXR1cm4gKHRoaXMuc2l6ZSAvIDIgKiB0aGlzLnN0aWNrWm9vbSkgKyAyMDtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gKHIgLSAodGhpcy5zaXplIC8gMikpICogdGhpcy5zdGlja1pvb207XG4gICAgfVxufTtcblxuLy9jYWxjdWxhdGUgdGhlICBjb29yZGluYXRlcyBvZiBhIHJlc2lkdWUgKHJlbGF0aXZlIHRvIHRoaXMudXRpbC5jb250YWluZXIpXG5Qb2x5bWVyLnByb3RvdHlwZS5nZXRSZXNpZHVlQ29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAociwgeU9mZikge1xuICAgIGlmICh0eXBlb2YgciA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiRVJST1I6IHJlc2lkdWUgbnVtYmVyIGlzIHVuZGVmaW5lZFwiKTtcbiAgICB9XG4gICAgbGV0IHggPSB0aGlzLmdldFJlc1h3aXRoU3RpY2tab29tKHIgKiAxKTsvLyAqIHRoaXMuYXBwLno7XG4gICAgLy8gY29uc29sZS5sb2coXCIqKipcIiwgdGhpcy5hcHAueik7XG4gICAgLy8gY296IHByb3RzIGRvbid0IHNjYWxlLCBkb24ndCBtdWx0aXBsZSBieSBhcHAuelxuICAgIGxldCB5O1xuICAgIGlmICh4ICE9PSAwKSB7XG4gICAgICAgIGNvbnN0IGwgPSBNYXRoLmFicyh4KTtcbiAgICAgICAgY29uc3QgYSA9IE1hdGguYWNvcyh4IC8gbCk7XG4gICAgICAgIGNvbnN0IHJvdFJhZCA9ICh0aGlzLnJvdGF0aW9uIC8gMzYwKSAqIE1hdGguUEkgKiAyO1xuICAgICAgICB4ID0gbCAqIE1hdGguY29zKHJvdFJhZCArIGEpO1xuICAgICAgICB5ID0gbCAqIE1hdGguc2luKHJvdFJhZCArIGEpO1xuICAgICAgICBpZiAodHlwZW9mIHlPZmYgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgIHggKz0geU9mZiAvKiogdGhpcy5hcHAueiovICogTWF0aC5jb3Mocm90UmFkICsgKE1hdGguUEkgLyAyKSk7XG4gICAgICAgICAgICB5ICs9IHlPZmYgLyoqIHRoaXMuYXBwLnoqLyAqIE1hdGguc2luKHJvdFJhZCArIChNYXRoLlBJIC8gMikpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgeSA9IHlPZmY7XG4gICAgfVxuICAgIHggKz0gdGhpcy5peDtcbiAgICB5ICs9IHRoaXMuaXk7XG4gICAgcmV0dXJuIFt4LCB5XTtcbn07XG5cblBvbHltZXIucHJvdG90eXBlLmNsZWFyUG9zaXRpb25hbEZlYXR1cmVzID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuYW5ub3RhdGlvbnMgPSBbXTtcbiAgICB0aGlzLmFubm90YXRpb25UeXBlcyA9IFtdO1xuICAgIGlmICh0aGlzLmFubm90YXRpb25zU3ZnR3JvdXApIGQzLnNlbGVjdCh0aGlzLmFubm90YXRpb25zU3ZnR3JvdXApLnNlbGVjdEFsbChcIipcIikucmVtb3ZlKCk7XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS5zZXRQb3NpdGlvbmFsRmVhdHVyZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG5cbiAgICBjb25zdCB0b29sVGlwRnVuYyA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgY29uc3QgZWwgPSAoZXZ0LnRhcmdldC5jb3JyZXNwb25kaW5nVXNlRWxlbWVudCkgPyBldnQudGFyZ2V0LmNvcnJlc3BvbmRpbmdVc2VFbGVtZW50IDogZXZ0LnRhcmdldDtcbiAgICAgICAgc2VsZi5hcHAucHJldmVudERlZmF1bHRzQW5kU3RvcFByb3BhZ2F0aW9uKGV2dCk7XG4gICAgICAgIHNlbGYuYXBwLnNldFRvb2x0aXAoZWwubmFtZSwgZWwuZ2V0QXR0cmlidXRlKFwiZmlsbFwiKSk7XG4gICAgICAgIHNlbGYuc2hvd0hpZ2hsaWdodCh0cnVlKTtcbiAgICB9O1xuXG4gICAgY29uc3QgYW5ub3RhdGlvblR5cGVzU2V0ID0gbmV3IFNldCgpO1xuXG4gICAgZm9yIChsZXQgW2Fubm90YXRpb25UeXBlLCBhbm5vdGF0aW9uU2V0XSBvZiB0aGlzLmFubm90YXRpb25TZXRzKSB7XG4gICAgICAgIGlmICh0aGlzLmFwcC5hbm5vdGF0aW9uU2V0c1Nob3duLmdldChhbm5vdGF0aW9uVHlwZSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGFubm90YXRpb24gb2YgYW5ub3RhdGlvblNldC52YWx1ZXMoKSkge1xuXG4gICAgICAgICAgICAgICAgaWYgKGFubm90YXRpb24uc2VxRGF0dW0uc2VxdWVuY2VEYXR1bVN0cmluZyAhPT0gXCJuLW5cIiAmJiBhbm5vdGF0aW9uLnNlcURhdHVtLnNlcXVlbmNlRGF0dW1TdHJpbmcgIT09IFwiYy1jXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgYW5ub3RhdGlvblR5cGVzU2V0LmFkZChhbm5vdGF0aW9uLmRlc2NyaXB0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5hbm5vdGF0aW9uVHlwZXMgPSBBcnJheS5mcm9tKGFubm90YXRpb25UeXBlc1NldC52YWx1ZXMoKSkuc29ydCgpO1xuXG4gICAgZm9yIChsZXQgW2Fubm90YXRpb25UeXBlLCBhbm5vdGF0aW9uU2V0XSBvZiB0aGlzLmFubm90YXRpb25TZXRzKSB7XG4gICAgICAgIGlmICh0aGlzLmFwcC5hbm5vdGF0aW9uU2V0c1Nob3duLmdldChhbm5vdGF0aW9uVHlwZSkgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGFubm8gb2YgYW5ub3RhdGlvblNldC52YWx1ZXMoKSkge1xuICAgICAgICAgICAgICAgIGxldCB0ZXh0ID0gYW5uby5kZXNjcmlwdGlvbiArIFwiIFtcIiArIChhbm5vLnNlcURhdHVtID8gYW5uby5zZXFEYXR1bS50b1N0cmluZygpIDogYW5uby5zZXFEYXR1bS5iZWdpbiArIFwiIC0gXCIgKyBhbm5vLnNlcURhdHVtLmVuZCkgKyBcIl1cIjtcbiAgICAgICAgICAgICAgICBpZiAoYW5uby5kZXNjcmlwdGlvbiA9PT0gXCJObyBhbm5vdGF0aW9uc1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHQgPSBcIk5vIGFubm90YXRpb25zXCI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChhbm5vLnNlcURhdHVtLnVuY2VydGFpbkJlZ2luKSB7XG4gICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlTdGFydCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJwYXRoXCIpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmZ1enp5U3RhcnQuc2V0QXR0cmlidXRlKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25QaWVTbGljZUFyY1BhdGgoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5CZWdpbiwgYW5uby5zZXFEYXR1bS5iZWdpbiwgYW5ubykpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eVN0YXJ0LnNldEF0dHJpYnV0ZShcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUmVjdFBhdGgoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5CZWdpbiwgYW5uby5zZXFEYXR1bS5iZWdpbiwgYW5ubykpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlTdGFydC5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgXCJub25lXCIpOy8vLXdpZHRoXCIsIFwiMVwiKTsgLy8gdG9kbyAtIHNob3VsZCBiZSBjc3NcbiAgICAgICAgICAgICAgICAgICAgLy8gYW5uby5mdXp6eVN0YXJ0LnNldEF0dHJpYnV0ZShcImZpbGwtb3BhY2l0eVwiLCBcIjAuNlwiKTtcbiAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eVN0YXJ0Lm5hbWUgPSB0ZXh0O1xuICAgICAgICAgICAgICAgICAgICBhbm5vLmZ1enp5U3RhcnQub25tb3VzZW92ZXIgPSB0b29sVGlwRnVuYztcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hbm5vdGF0aW9uc1N2Z0dyb3VwLmFwcGVuZENoaWxkKGFubm8uZnV6enlTdGFydCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKGFubm8uc2VxRGF0dW0uYmVnaW4gJiYgYW5uby5zZXFEYXR1bS5lbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgYW5uby5jZXJ0YWluID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInBhdGhcIik7XG4gICAgICAgICAgICAgICAgICAgIGxldCB0ZW1wQmVnaW4gPSBhbm5vLnNlcURhdHVtLmJlZ2luOyAvL3RvZG8gLSBtaWdodCBiZSBiZXR0ZXIgdG8gaGF2ZSBzZXBlcmF0ZSBhdHQgaW4gU2VxdWVuY2VEYXRhIGZvciBlbmQgb2YgdW5jZXJ0YWluIHN0YXJ0XG4gICAgICAgICAgICAgICAgICAgIGxldCB0ZW1wRW5kID0gYW5uby5zZXFEYXR1bS5lbmQ7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhbm5vLnNlcURhdHVtLnVuY2VydGFpbkJlZ2luKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ZW1wQmVnaW4gKz0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBFbmQgLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25QaWVTbGljZUFyY1BhdGgodGVtcEJlZ2luLCB0ZW1wRW5kLCBhbm5vKSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwiZFwiLCB0aGlzLmdldEFubm90YXRpb25SZWN0UGF0aCh0ZW1wQmVnaW4sIHRlbXBFbmQsIGFubm8pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBhbm5vLmNlcnRhaW4uc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwibm9uZVwiKTsvLy13aWR0aFwiLCBcIjFcIik7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFubm8uY2VydGFpbi5zZXRBdHRyaWJ1dGUoXCJmaWxsLW9wYWNpdHlcIiwgXCIwLjZcIik7XG4gICAgICAgICAgICAgICAgICAgIGFubm8uY2VydGFpbi5uYW1lID0gdGV4dDtcbiAgICAgICAgICAgICAgICAgICAgYW5uby5jZXJ0YWluLm9ubW91c2VvdmVyID0gdG9vbFRpcEZ1bmM7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYW5ub3RhdGlvbnNTdmdHcm91cC5hcHBlbmRDaGlsZChhbm5vLmNlcnRhaW4pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoYW5uby5zZXFEYXR1bS51bmNlcnRhaW5FbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJwYXRoXCIpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbm5vLmZ1enp5RW5kLnNldEF0dHJpYnV0ZShcImRcIiwgdGhpcy5nZXRBbm5vdGF0aW9uUGllU2xpY2VBcmNQYXRoKGFubm8uc2VxRGF0dW0uZW5kLCBhbm5vLnNlcURhdHVtLnVuY2VydGFpbkVuZCwgYW5ubykpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZC5zZXRBdHRyaWJ1dGUoXCJkXCIsIHRoaXMuZ2V0QW5ub3RhdGlvblJlY3RQYXRoKGFubm8uc2VxRGF0dW0uZW5kLCBhbm5vLnNlcURhdHVtLnVuY2VydGFpbkVuZCwgYW5ubykpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGFubm8uZnV6enlFbmQuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwibm9uZVwiKTsgLy8td2lkdGhcIiwgXCIxXCIpO1xuICAgICAgICAgICAgICAgICAgICAvLyBhbm5vLmZ1enp5RW5kLnNldEF0dHJpYnV0ZShcImZpbGwtb3BhY2l0eVwiLCBcIjAuNlwiKTtcbiAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZC5uYW1lID0gdGV4dDtcbiAgICAgICAgICAgICAgICAgICAgYW5uby5mdXp6eUVuZC5vbm1vdXNlb3ZlciA9IHRvb2xUaXBGdW5jO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFubm90YXRpb25zU3ZnR3JvdXAuYXBwZW5kQ2hpbGQoYW5uby5mdXp6eUVuZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufTtcblxuUG9seW1lci5zdGVwc0luQXJjID0gNTtcblxuUG9seW1lci5wcm90b3R5cGUuZ2V0QW5ub3RhdGlvblBpZVNsaWNlQXJjUGF0aCA9IGZ1bmN0aW9uIChzdGFydFJlcywgZW5kUmVzLCBhbm5vdGF0aW9uKSB7XG4gICAgY29uc3QgcmFkaXVzID0gdGhpcy5nZXRTeW1ib2xSYWRpdXMoKTsvLyAtIDI7XG5cbiAgICBsZXQgdG9wLCBib3R0b20sIHJ1bmdIZWlnaHQ7XG4gICAgY29uc3QgcnVuZyA9IHRoaXMuYW5ub3RhdGlvblR5cGVzLmluZGV4T2YoYW5ub3RhdGlvbi5kZXNjcmlwdGlvbik7XG4gICAgLy8gY29uc29sZS5sb2coXCJydW5nXCIsIHJ1bmcsIHRoaXMuYW5ub3RhdGlvblR5cGVzKTtcbiAgICBpZiAocnVuZyA9PT0gLTEpIHtcbiAgICAgICAgYm90dG9tID0gMDtcbiAgICAgICAgdG9wID0gcmFkaXVzO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vTWF0aC5zcXJ0KHRoaXMucGFydGljaXBhbnQuc2l6ZSAvIE1hdGguUEkpICogMC42XG4gICAgICAgIHJ1bmdIZWlnaHQgPSByYWRpdXMgLyB0aGlzLmFubm90YXRpb25UeXBlcy5sZW5ndGg7XG4gICAgICAgIGJvdHRvbSA9IChydW5nICogcnVuZ0hlaWdodCk7XG4gICAgICAgIHRvcCA9IGJvdHRvbSArIHJ1bmdIZWlnaHQ7XG4gICAgICAgIC8vXG4gICAgICAgIC8vIGJvdHRvbSA9IE1hdGguc3FydChydW5nIC8gdGhpcy5hbm5vdGF0aW9uVHlwZXMubGVuZ3RoKSAqIHJhZGl1cztcbiAgICAgICAgLy8gdG9wID0gTWF0aC5zcXJ0KHJ1bmcgKyAxIC8gdGhpcy5hbm5vdGF0aW9uVHlwZXMubGVuZ3RoKSAqIHJhZGl1cztcbiAgICB9XG5cbiAgICAvLyB2YXIgc3RhcnRBbmdsZSA9ICgoc3RhcnRSZXMgLSAxKSAvIHRoaXMuc2l6ZSkgKiAzNjA7XG4gICAgLy8gdmFyIGVuZEFuZ2xlID0gKChlbmRSZXMgLSAxKSAvIHRoaXMuc2l6ZSkgKiAzNjA7XG4gICAgbGV0IHN0YXJ0QW5nbGUsIGVuZEFuZ2xlO1xuICAgIGlmIChzdGFydFJlcyA9PT0gXCJuLW5cIikge1xuICAgICAgICBzdGFydEFuZ2xlID0gLTIwOyAvLygoc3RhcnRSZXMgLSAxKSAvIHRoaXMuc2l6ZSkgKiAzNjA7XG4gICAgICAgIGVuZEFuZ2xlID0gMDsvLygoZW5kUmVzIC0gMSkgLyB0aGlzLnNpemUpICogMzYwO1xuICAgIH0gZWxzZSBpZiAoZW5kUmVzID09PSBcImMtY1wiKSB7XG4gICAgICAgIHN0YXJ0QW5nbGUgPSAwOy8vKChzdGFydFJlcyAtIDEpIC8gdGhpcy5zaXplKSAqIDM2MDtcbiAgICAgICAgZW5kQW5nbGUgPSArMjA7IC8vKChlbmRSZXMpIC8gdGhpcy5zaXplKSAqIDM2MDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBzdGFydEFuZ2xlID0gKChzdGFydFJlcyAtIDEpIC8gdGhpcy5zaXplKSAqIDM2MDtcbiAgICAgICAgZW5kQW5nbGUgPSAoKGVuZFJlcyAtIDEpIC8gdGhpcy5zaXplKSAqIDM2MDtcbiAgICB9XG4gICAgLy8gY29uc3QgYXJjU3RhcnQgPSB0cmlnKHJhZGl1cywgc3RhcnRBbmdsZSAtIDkwKTtcbiAgICAvLyBjb25zdCBhcmNFbmQgPSB0cmlnKHJhZGl1cywgZW5kQW5nbGUgLSA5MCk7XG4gICAgbGV0IGxhcmdlQXJjaCA9IDA7XG4gICAgaWYgKChlbmRBbmdsZSAtIHN0YXJ0QW5nbGUpID4gMTgwIHx8IChlbmRBbmdsZSA9PT0gc3RhcnRBbmdsZSkpIHtcbiAgICAgICAgbGFyZ2VBcmNoID0gMTtcbiAgICB9XG5cbiAgICBjb25zdCBwMSA9IHJvdGF0ZVBvaW50QWJvdXRQb2ludChbMCwgYm90dG9tXSwgWzAsIDBdLCBzdGFydEFuZ2xlIC0gMTgwKTtcbiAgICBjb25zdCBwMiA9IHJvdGF0ZVBvaW50QWJvdXRQb2ludChbMCwgdG9wXSwgWzAsIDBdLCBzdGFydEFuZ2xlIC0gMTgwKTtcbiAgICBjb25zdCBwMyA9IHJvdGF0ZVBvaW50QWJvdXRQb2ludChbMCwgdG9wXSwgWzAsIDBdLCBlbmRBbmdsZSAtIDE4MCk7XG4gICAgY29uc3QgcDQgPSByb3RhdGVQb2ludEFib3V0UG9pbnQoWzAsIGJvdHRvbV0sIFswLCAwXSwgZW5kQW5nbGUgLSAxODApO1xuXG4gICAgLy9jb25zdCByID0gKGJvdHRvbSArIHRvcCkgLyAyO1xuICAgIGNvbnN0IHBhdGggPSBcIk1cIiArIHAxWzBdICsgXCIsXCIgKyBwMVsxXSArIFwiIExcIiArIHAyWzBdICsgXCIsXCIgKyBwMlsxXVxuICAgICAgICArIFwiIEFcIiArIHRvcCArIFwiLFwiICsgdG9wICsgXCIgMCBcIiArIGxhcmdlQXJjaCArIFwiIDEgXCIgKyBwM1swXSArIFwiLFwiICsgcDNbMV0gKyBcIiBMXCIgKyBwNFswXSArIFwiLFwiICsgcDRbMV1cbiAgICAgICAgKyBcIiBBXCIgKyBib3R0b20gKyBcIixcIiArIGJvdHRvbSArIFwiIDAgXCIgKyBsYXJnZUFyY2ggKyBcIiAwIFwiICsgcDFbMF0gKyBcIixcIiArIHAxWzFdICsgXCIgWlwiO1xuICAgIC8vIGNvbnNvbGUubG9nKFwiKipcIiwgcGF0aCk7XG4gICAgcmV0dXJuIHBhdGg7XG4gICAgLy8gcmV0dXJuIFwiTTAsMCBMXCIgKyBhcmNTdGFydC54ICsgXCIsXCIgKyBhcmNTdGFydC55ICsgXCIgQVwiICsgcmFkaXVzICsgXCIsXCIgK1xuICAgIC8vICAgICByYWRpdXMgKyBcIiAwIFwiICsgbGFyZ2VBcmNoICsgXCIgMSBcIiArIGFyY0VuZC54ICsgXCIsXCIgKyBhcmNFbmQueSArIFwiIFpcIjtcbn07XG5cblBvbHltZXIucHJvdG90eXBlLmdldEFubm90YXRpb25QaWVTbGljZUFwcHJveGltYXRlUGF0aCA9IGZ1bmN0aW9uIChzdGFydFJlcywgZW5kUmVzLCBhbm5vdGF0aW9uKSB7XG5cbiAgICAvLyBsZXQgdG9wLCBib3R0b20sIHJ1bmdIZWlnaHQ7XG4gICAgLy8gY29uc3QgcnVuZyA9IHRoaXMuYW5ub3RhdGlvblR5cGVzLmluZGV4T2YoYW5ub3RhdGlvbi5kZXNjcmlwdGlvbik7XG4gICAgLy8gLy8gY29uc29sZS5sb2coXCJydW5nXCIsIHJ1bmcsIHRoaXMuYW5ub3RhdGlvblR5cGVzKTtcbiAgICAvLyBpZiAocnVuZyA9PT0gLTEpIHtcbiAgICAvLyAgICAgYm90dG9tID0gUG9seW1lci5TVElDS0hFSUdIVCAvIDI7XG4gICAgLy8gICAgIHRvcCA9IC1Qb2x5bWVyLlNUSUNLSEVJR0hUIC8gMjtcbiAgICAvLyB9IGVsc2Uge1xuICAgIC8vICAgICBydW5nSGVpZ2h0ID0gUG9seW1lci5TVElDS0hFSUdIVCAvIHRoaXMuYW5ub3RhdGlvblR5cGVzLmxlbmd0aDtcbiAgICAvLyAgICAgdG9wID0gKC1Qb2x5bWVyLlNUSUNLSEVJR0hUIC8gMikgKyAocnVuZyAqIHJ1bmdIZWlnaHQpO1xuICAgIC8vICAgICBib3R0b20gPSB0b3AgKyBydW5nSGVpZ2h0O1xuICAgIC8vIH1cblxuICAgIC8vYXBwcm94aW1hdGUgcGllIHNsaWNlXG4gICAgbGV0IHN0YXJ0QW5nbGUsIGVuZEFuZ2xlO1xuICAgIGlmIChzdGFydFJlcyA9PT0gXCJuLW5cIikge1xuICAgICAgICBzdGFydEFuZ2xlID0gLTIwOyAvLygoc3RhcnRSZXMgLSAxKSAvIHRoaXMuc2l6ZSkgKiAzNjA7XG4gICAgICAgIGVuZEFuZ2xlID0gMDsvLygoZW5kUmVzKSAvIHRoaXMuc2l6ZSkgKiAzNjA7XG4gICAgfSBlbHNlIGlmIChlbmRSZXMgPT09IFwiYy1jXCIpIHtcbiAgICAgICAgc3RhcnRBbmdsZSA9IDA7Ly8oKHN0YXJ0UmVzIC0gMSkgLyB0aGlzLnNpemUpICogMzYwO1xuICAgICAgICBlbmRBbmdsZSA9ICsyMDsgLy8oKGVuZFJlcykgLyB0aGlzLnNpemUpICogMzYwO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXJ0QW5nbGUgPSAoKHN0YXJ0UmVzIC0gMSkgLyB0aGlzLnNpemUpICogMzYwO1xuICAgICAgICBlbmRBbmdsZSA9ICgoZW5kUmVzKSAvIHRoaXMuc2l6ZSkgKiAzNjA7XG4gICAgfVxuICAgIGNvbnN0IHBpZVJhZGl1cyA9IHRoaXMuZ2V0U3ltYm9sUmFkaXVzKCkgLSAyO1xuICAgIC8vIHZhciBhcmNTdGFydCA9IEludGVyYWN0b3IudHJpZyhwaWVSYWRpdXMsIHN0YXJ0QW5nbGUgLSA5MCk7XG4gICAgLy8gdmFyIGFyY0VuZCA9IEludGVyYWN0b3IudHJpZyhwaWVSYWRpdXMsIGVuZEFuZ2xlIC0gOTApO1xuICAgIGxldCBhcHByb3hpbWF0ZVBpZVBhdGggPSBcIk0gMCwwXCI7XG4gICAgY29uc3Qgc3RlcHNJbkFyYyA9IDU7XG4gICAgZm9yIChsZXQgc2lhID0gMDsgc2lhIDw9IFBvbHltZXIuc3RlcHNJbkFyYzsgc2lhKyspIHtcbiAgICAgICAgY29uc3QgYW5nbGUgPSBzdGFydEFuZ2xlICsgKChlbmRBbmdsZSAtIHN0YXJ0QW5nbGUpICogKHNpYSAvIHN0ZXBzSW5BcmMpKTtcbiAgICAgICAgY29uc3Qgc2lhQ29vcmQgPSB0cmlnKHBpZVJhZGl1cywgYW5nbGUgLSA5MCk7XG4gICAgICAgIGFwcHJveGltYXRlUGllUGF0aCArPSBcIiBMIFwiICsgc2lhQ29vcmQueCArIFwiLFwiICsgc2lhQ29vcmQueTtcbiAgICB9XG4gICAgYXBwcm94aW1hdGVQaWVQYXRoICs9IFwiIEwgXCIgKyAwICsgXCIsXCIgKyAwO1xuICAgIGFwcHJveGltYXRlUGllUGF0aCArPSBcIiAgWlwiO1xuICAgIHJldHVybiBhcHByb3hpbWF0ZVBpZVBhdGg7XG59O1xuXG5Qb2x5bWVyLnByb3RvdHlwZS5nZXRBbm5vdGF0aW9uUmVjdFBhdGggPSBmdW5jdGlvbiAoc3RhcnRSZXMsIGVuZFJlcywgYW5ub3RhdGlvbikge1xuICAgIC8vZG9tYWluIGFzIHJlY3RhbmdsZSBwYXRoXG4gICAgbGV0IHRvcCwgYm90dG9tLCBydW5nSGVpZ2h0O1xuICAgIGNvbnN0IHJ1bmcgPSB0aGlzLmFubm90YXRpb25UeXBlcy5pbmRleE9mKGFubm90YXRpb24uZGVzY3JpcHRpb24pO1xuICAgIC8vIGNvbnNvbGUubG9nKFwicnVuZ1wiLCBydW5nLCB0aGlzLmFubm90YXRpb25UeXBlcyk7XG4gICAgaWYgKHJ1bmcgPT09IC0xKSB7XG4gICAgICAgIGJvdHRvbSA9IFBvbHltZXIuU1RJQ0tIRUlHSFQgLyAyO1xuICAgICAgICB0b3AgPSAtUG9seW1lci5TVElDS0hFSUdIVCAvIDI7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcnVuZ0hlaWdodCA9IFBvbHltZXIuU1RJQ0tIRUlHSFQgLyB0aGlzLmFubm90YXRpb25UeXBlcy5sZW5ndGg7XG4gICAgICAgIHRvcCA9ICgtUG9seW1lci5TVElDS0hFSUdIVCAvIDIpICsgKHJ1bmcgKiBydW5nSGVpZ2h0KTtcbiAgICAgICAgYm90dG9tID0gdG9wICsgcnVuZ0hlaWdodDtcbiAgICB9XG5cbiAgICBsZXQgYW5ub3RYLCBhbm5vdFNpemUsIGFubm90TGVuZ3RoO1xuICAgIGlmIChzdGFydFJlcyA9PT0gXCJuLW5cIikge1xuICAgICAgICBhbm5vdFggPSB0aGlzLmdldFJlc1h3aXRoU3RpY2tab29tKDAuNSkgLSAyMDtcbiAgICAgICAgLy8gdmFyIGFubm90U2l6ZSA9ICgxICsgKGVuZFJlcyAtIHN0YXJ0UmVzKSk7XG4gICAgICAgIGFubm90TGVuZ3RoID0gMjA7Ly9hbm5vdFNpemUgKiB0aGlzLnN0aWNrWm9vbTtcbiAgICB9IGVsc2UgaWYgKGVuZFJlcyA9PT0gXCJjLWNcIikge1xuICAgICAgICBhbm5vdFggPSB0aGlzLmdldFJlc1h3aXRoU3RpY2tab29tKHRoaXMuc2l6ZSArIDAuNSk7XG4gICAgICAgIC8vIHZhciBhbm5vdFNpemUgPSAoMSArIChlbmRSZXMgLSBzdGFydFJlcykpO1xuICAgICAgICBhbm5vdExlbmd0aCA9IDIwOy8vYW5ub3RTaXplICogdGhpcy5zdGlja1pvb207XG4gICAgfSBlbHNlIHtcbiAgICAgICAgYW5ub3RYID0gdGhpcy5nZXRSZXNYd2l0aFN0aWNrWm9vbShzdGFydFJlcyAtIDAuNSk7XG4gICAgICAgIGFubm90U2l6ZSA9ICgxICsgKGVuZFJlcyAtIHN0YXJ0UmVzKSk7XG4gICAgICAgIGFubm90TGVuZ3RoID0gYW5ub3RTaXplICogdGhpcy5zdGlja1pvb207XG4gICAgfVxuICAgIGxldCByZWN0UGF0aCA9IFwiTSBcIiArIGFubm90WCArIFwiLFwiICsgYm90dG9tO1xuICAgIGZvciAobGV0IHNpYSA9IDA7IHNpYSA8PSBQb2x5bWVyLnN0ZXBzSW5BcmM7IHNpYSsrKSB7XG4gICAgICAgIGNvbnN0IHN0ZXAgPSBhbm5vdFggKyAoYW5ub3RMZW5ndGggKiAoc2lhIC8gUG9seW1lci5zdGVwc0luQXJjKSk7XG4gICAgICAgIHJlY3RQYXRoICs9IFwiIEwgXCIgKyBzdGVwICsgXCIsXCIgKyB0b3A7XG4gICAgfVxuICAgIHJlY3RQYXRoICs9IFwiIEwgXCIgKyAoYW5ub3RYICsgYW5ub3RMZW5ndGgpICsgXCIsXCIgKyBib3R0b20gK1xuICAgICAgICBcIiBaXCI7XG4gICAgcmV0dXJuIHJlY3RQYXRoO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/polymer.js\n"); /***/ }), @@ -1321,7 +1333,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Protein\", function() { return Protein; });\n/* harmony import */ var _polymer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./polymer */ \"./src/js/viz/interactor/polymer.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n\n\n\nfunction Protein(id, /*App*/ app, json, name) {\n this.init(id, app, json, name);\n this.type = \"protein\"; // this isn't absolutely necessary, could do without it\n\n this.upperGroup = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"g\");\n this.rotation = 0;\n this.stickZoom = 1;\n this.form = 0; // 0 = blob, 1 = stick\n\n //make highlight\n this.highlight = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"rect\");\n this.highlight.setAttribute(\"stroke\", _config__WEBPACK_IMPORTED_MODULE_1__[\"highlightColour\"]);\n this.highlight.setAttribute(\"stroke-width\", \"5\");\n this.highlight.setAttribute(\"fill\", \"none\");\n this.upperGroup.appendChild(this.highlight);\n\n //make background\n //http://stackoverflow.com/questions/17437408/how-do-i-change-a-circle-to-a-square-using-d3\n this.background = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"rect\");\n this.background.setAttribute(\"fill\", \"#FFFFFF\");\n this.upperGroup.appendChild(this.background);\n //create label - we will move this svg element around when protein form changes\n this.initLabel();\n //ticks (and amino acid letters)\n this.ticks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"g\");\n //svg group for annotations\n this.annotationsSvgGroup = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"g\");\n this.annotationsSvgGroup.setAttribute(\"opacity\", \"1\");\n this.upperGroup.appendChild(this.annotationsSvgGroup);\n\n //make outline\n this.outline = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"rect\");\n this.outline.setAttribute(\"stroke\", \"black\");\n this.outline.setAttribute(\"stroke-width\", \"1\");\n this.outline.setAttribute(\"fill\", \"none\");\n this.upperGroup.appendChild(this.outline);\n\n this.scaleLabels = [];\n\n //since form is set to 0, make this a circle, this stuff is equivalent to\n // end result of toCircle but without transition\n const r = this.getSymbolRadius();\n\n this.outline.setAttribute(\"x\", -r);\n this.outline.setAttribute(\"y\", -r);\n this.outline.setAttribute(\"width\", r * 2);\n this.outline.setAttribute(\"height\", r * 2);\n this.outline.setAttribute(\"rx\", r);\n this.outline.setAttribute(\"ry\", r);\n\n this.background.setAttribute(\"x\", -r);\n this.background.setAttribute(\"y\", -r);\n this.background.setAttribute(\"width\", r * 2);\n this.background.setAttribute(\"height\", r * 2);\n this.background.setAttribute(\"rx\", r);\n this.background.setAttribute(\"ry\", r);\n\n this.annotationsSvgGroup.setAttribute(\"transform\", \"scale(1, 1)\");\n\n this.highlight.setAttribute(\"width\", (r * 2) + 5);\n this.highlight.setAttribute(\"height\", (r * 2) + 5);\n this.highlight.setAttribute(\"x\", -r - 2.5);\n this.highlight.setAttribute(\"y\", -r - 2.5);\n this.highlight.setAttribute(\"rx\", r + 2.5);\n this.highlight.setAttribute(\"ry\", r + 2.5);\n this.highlight.setAttribute(\"stroke-opacity\", \"0\");\n\n this.labelSVG.setAttribute(\"transform\", \"translate(\" + (-(r + 5)) + \",\" + \"-5)\");\n\n this.initListeners();\n\n const self = this;\n Object.defineProperty(this, \"height\", {\n get: function height() {\n return self.form == 1? 120:40;\n //return 160;\n }\n });\n\n this.showHighlight(false);\n}\n\nProtein.prototype = new _polymer__WEBPACK_IMPORTED_MODULE_0__[\"Polymer\"]();\n\n/*\nProtein.prototype.showData = function(evt) {\n const url = \"http://www.uniprot.org/uniprot/\" + this.json.identifier.id;\n window.open(url, '_blank');\n}\n*/\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvcHJvdGVpbi5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2ludGVyYWN0b3IvcHJvdGVpbi5qcz9kMmFiIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7UG9seW1lcn0gZnJvbSBcIi4vcG9seW1lclwiO1xuaW1wb3J0IHtzdmducywgaGlnaGxpZ2h0Q29sb3VyfSBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBQcm90ZWluKGlkLCAvKkFwcCovIGFwcCwganNvbiwgbmFtZSkge1xuICAgIHRoaXMuaW5pdChpZCwgYXBwLCBqc29uLCBuYW1lKTtcbiAgICB0aGlzLnR5cGUgPSBcInByb3RlaW5cIjsgLy8gdGhpcyBpc24ndCBhYnNvbHV0ZWx5IG5lY2Vzc2FyeSwgY291bGQgZG8gd2l0aG91dCBpdFxuXG4gICAgdGhpcy51cHBlckdyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5yb3RhdGlvbiA9IDA7XG4gICAgdGhpcy5zdGlja1pvb20gPSAxO1xuICAgIHRoaXMuZm9ybSA9IDA7IC8vIDAgPSBibG9iLCAxID0gc3RpY2tcblxuICAgIC8vbWFrZSBoaWdobGlnaHRcbiAgICB0aGlzLmhpZ2hsaWdodCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJyZWN0XCIpO1xuICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBoaWdobGlnaHRDb2xvdXIpO1xuICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBcIjVcIik7XG4gICAgdGhpcy5oaWdobGlnaHQuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcIm5vbmVcIik7XG4gICAgdGhpcy51cHBlckdyb3VwLmFwcGVuZENoaWxkKHRoaXMuaGlnaGxpZ2h0KTtcblxuICAgIC8vbWFrZSBiYWNrZ3JvdW5kXG4gICAgLy9odHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE3NDM3NDA4L2hvdy1kby1pLWNoYW5nZS1hLWNpcmNsZS10by1hLXNxdWFyZS11c2luZy1kM1xuICAgIHRoaXMuYmFja2dyb3VuZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJyZWN0XCIpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwiI0ZGRkZGRlwiKTtcbiAgICB0aGlzLnVwcGVyR3JvdXAuYXBwZW5kQ2hpbGQodGhpcy5iYWNrZ3JvdW5kKTtcbiAgICAvL2NyZWF0ZSBsYWJlbCAtIHdlIHdpbGwgbW92ZSB0aGlzIHN2ZyBlbGVtZW50IGFyb3VuZCB3aGVuIHByb3RlaW4gZm9ybSBjaGFuZ2VzXG4gICAgdGhpcy5pbml0TGFiZWwoKTtcbiAgICAvL3RpY2tzIChhbmQgYW1pbm8gYWNpZCBsZXR0ZXJzKVxuICAgIHRoaXMudGlja3MgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwiZ1wiKTtcbiAgICAvL3N2ZyBncm91cCBmb3IgYW5ub3RhdGlvbnNcbiAgICB0aGlzLmFubm90YXRpb25zU3ZnR3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwiZ1wiKTtcbiAgICB0aGlzLmFubm90YXRpb25zU3ZnR3JvdXAuc2V0QXR0cmlidXRlKFwib3BhY2l0eVwiLCBcIjFcIik7XG4gICAgdGhpcy51cHBlckdyb3VwLmFwcGVuZENoaWxkKHRoaXMuYW5ub3RhdGlvbnNTdmdHcm91cCk7XG5cbiAgICAvL21ha2Ugb3V0bGluZVxuICAgIHRoaXMub3V0bGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJyZWN0XCIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgXCJibGFja1wiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIFwiMVwiKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcIm5vbmVcIik7XG4gICAgdGhpcy51cHBlckdyb3VwLmFwcGVuZENoaWxkKHRoaXMub3V0bGluZSk7XG5cbiAgICB0aGlzLnNjYWxlTGFiZWxzID0gW107XG5cbiAgICAvL3NpbmNlIGZvcm0gaXMgc2V0IHRvIDAsIG1ha2UgdGhpcyBhIGNpcmNsZSwgdGhpcyBzdHVmZiBpcyBlcXVpdmFsZW50IHRvXG4gICAgLy8gZW5kIHJlc3VsdCBvZiB0b0NpcmNsZSBidXQgd2l0aG91dCB0cmFuc2l0aW9uXG4gICAgY29uc3QgciA9IHRoaXMuZ2V0U3ltYm9sUmFkaXVzKCk7XG5cbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwieFwiLCAtcik7XG4gICAgdGhpcy5vdXRsaW5lLnNldEF0dHJpYnV0ZShcInlcIiwgLXIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCByICogMik7XG4gICAgdGhpcy5vdXRsaW5lLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCByICogMik7XG4gICAgdGhpcy5vdXRsaW5lLnNldEF0dHJpYnV0ZShcInJ4XCIsIHIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJyeVwiLCByKTtcblxuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoXCJ4XCIsIC1yKTtcbiAgICB0aGlzLmJhY2tncm91bmQuc2V0QXR0cmlidXRlKFwieVwiLCAtcik7XG4gICAgdGhpcy5iYWNrZ3JvdW5kLnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIHIgKiAyKTtcbiAgICB0aGlzLmJhY2tncm91bmQuc2V0QXR0cmlidXRlKFwiaGVpZ2h0XCIsIHIgKiAyKTtcbiAgICB0aGlzLmJhY2tncm91bmQuc2V0QXR0cmlidXRlKFwicnhcIiwgcik7XG4gICAgdGhpcy5iYWNrZ3JvdW5kLnNldEF0dHJpYnV0ZShcInJ5XCIsIHIpO1xuXG4gICAgdGhpcy5hbm5vdGF0aW9uc1N2Z0dyb3VwLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCBcInNjYWxlKDEsIDEpXCIpO1xuXG4gICAgdGhpcy5oaWdobGlnaHQuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgKHIgKiAyKSArIDUpO1xuICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCAociAqIDIpICsgNSk7XG4gICAgdGhpcy5oaWdobGlnaHQuc2V0QXR0cmlidXRlKFwieFwiLCAtciAtIDIuNSk7XG4gICAgdGhpcy5oaWdobGlnaHQuc2V0QXR0cmlidXRlKFwieVwiLCAtciAtIDIuNSk7XG4gICAgdGhpcy5oaWdobGlnaHQuc2V0QXR0cmlidXRlKFwicnhcIiwgciArIDIuNSk7XG4gICAgdGhpcy5oaWdobGlnaHQuc2V0QXR0cmlidXRlKFwicnlcIiwgciArIDIuNSk7XG4gICAgdGhpcy5oaWdobGlnaHQuc2V0QXR0cmlidXRlKFwic3Ryb2tlLW9wYWNpdHlcIiwgXCIwXCIpO1xuXG4gICAgdGhpcy5sYWJlbFNWRy5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgXCJ0cmFuc2xhdGUoXCIgKyAoLShyICsgNSkpICsgXCIsXCIgKyBcIi01KVwiKTtcblxuICAgIHRoaXMuaW5pdExpc3RlbmVycygpO1xuXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwiaGVpZ2h0XCIsIHtcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiBoZWlnaHQoKSB7XG4gICAgICAgICAgICByZXR1cm4gc2VsZi5mb3JtID09IDE/IDEyMDo0MDtcbiAgICAgICAgICAgIC8vcmV0dXJuIDE2MDtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5zaG93SGlnaGxpZ2h0KGZhbHNlKTtcbn1cblxuUHJvdGVpbi5wcm90b3R5cGUgPSBuZXcgUG9seW1lcigpO1xuXG4vKlxuUHJvdGVpbi5wcm90b3R5cGUuc2hvd0RhdGEgPSBmdW5jdGlvbihldnQpIHtcbiAgICBjb25zdCB1cmwgPSBcImh0dHA6Ly93d3cudW5pcHJvdC5vcmcvdW5pcHJvdC9cIiArIHRoaXMuanNvbi5pZGVudGlmaWVyLmlkO1xuICAgIHdpbmRvdy5vcGVuKHVybCwgJ19ibGFuaycpO1xufVxuKi9cbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/protein.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Protein\", function() { return Protein; });\n/* harmony import */ var _polymer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./polymer */ \"./src/js/viz/interactor/polymer.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n\n\n\nfunction Protein(id, /*App*/ app, json, name) {\n this.init(id, app, json, name);\n this.type = \"protein\"; // this isn't absolutely necessary, could do without it\n\n this.upperGroup = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"g\");\n this.rotation = 0;\n this.stickZoom = 1;\n this.form = 0; // 0 = blob, 1 = stick\n\n //make highlight\n this.highlight = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"rect\");\n this.highlight.classList.add(\"highlight\", \"participant-highlight\");\n this.upperGroup.appendChild(this.highlight);\n\n //make background\n //http://stackoverflow.com/questions/17437408/how-do-i-change-a-circle-to-a-square-using-d3\n this.background = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"rect\");\n this.background.setAttribute(\"fill\", \"#FFFFFF\");\n this.upperGroup.appendChild(this.background);\n //create label - we will move this svg element around when protein form changes\n this.initLabel();\n //ticks (and amino acid letters)\n this.ticks = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"g\");\n //svg group for annotations\n this.annotationsSvgGroup = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"g\");\n this.annotationsSvgGroup.setAttribute(\"opacity\", \"1\");\n this.upperGroup.appendChild(this.annotationsSvgGroup);\n\n //make outline\n this.outline = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"rect\");\n // css...\n this.outline.setAttribute(\"stroke\", \"black\");\n this.outline.setAttribute(\"stroke-width\", \"1\");\n this.outline.setAttribute(\"fill\", \"none\");\n this.upperGroup.appendChild(this.outline);\n\n this.scaleLabels = [];\n\n //since form is set to 0, make this a circle, this stuff is equivalent to\n // end result of toCircle but without transition\n const r = this.getSymbolRadius();\n\n this.outline.setAttribute(\"x\", -r);\n this.outline.setAttribute(\"y\", -r);\n this.outline.setAttribute(\"width\", r * 2);\n this.outline.setAttribute(\"height\", r * 2);\n this.outline.setAttribute(\"rx\", r);\n this.outline.setAttribute(\"ry\", r);\n\n this.background.setAttribute(\"x\", -r);\n this.background.setAttribute(\"y\", -r);\n this.background.setAttribute(\"width\", r * 2);\n this.background.setAttribute(\"height\", r * 2);\n this.background.setAttribute(\"rx\", r);\n this.background.setAttribute(\"ry\", r);\n\n this.annotationsSvgGroup.setAttribute(\"transform\", \"scale(1, 1)\");\n\n this.highlight.setAttribute(\"width\", (r * 2) + 5);\n this.highlight.setAttribute(\"height\", (r * 2) + 5);\n this.highlight.setAttribute(\"x\", -r - 2.5);\n this.highlight.setAttribute(\"y\", -r - 2.5);\n this.highlight.setAttribute(\"rx\", r + 2.5);\n this.highlight.setAttribute(\"ry\", r + 2.5);\n this.highlight.setAttribute(\"stroke-opacity\", \"0\");\n\n this.labelSVG.setAttribute(\"transform\", \"translate(\" + (-(r + 5)) + \",\" + \"-5)\");\n\n this.initListeners();\n\n const self = this;\n Object.defineProperty(this, \"height\", {\n get: function height() {\n return self.form == 1? 120:40;\n //return 160;\n }\n });\n\n this.showHighlight(false);\n}\n\nProtein.prototype = new _polymer__WEBPACK_IMPORTED_MODULE_0__[\"Polymer\"]();\n\n/*\nProtein.prototype.showData = function(evt) {\n const url = \"http://www.uniprot.org/uniprot/\" + this.json.identifier.id;\n window.open(url, '_blank');\n}\n*/\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2ludGVyYWN0b3IvcHJvdGVpbi5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2ludGVyYWN0b3IvcHJvdGVpbi5qcz9kMmFiIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7UG9seW1lcn0gZnJvbSBcIi4vcG9seW1lclwiO1xuaW1wb3J0IHtzdmduc30gZnJvbSBcIi4uLy4uL2NvbmZpZ1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gUHJvdGVpbihpZCwgLypBcHAqLyBhcHAsIGpzb24sIG5hbWUpIHtcbiAgICB0aGlzLmluaXQoaWQsIGFwcCwganNvbiwgbmFtZSk7XG4gICAgdGhpcy50eXBlID0gXCJwcm90ZWluXCI7IC8vIHRoaXMgaXNuJ3QgYWJzb2x1dGVseSBuZWNlc3NhcnksIGNvdWxkIGRvIHdpdGhvdXQgaXRcblxuICAgIHRoaXMudXBwZXJHcm91cCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJnXCIpO1xuICAgIHRoaXMucm90YXRpb24gPSAwO1xuICAgIHRoaXMuc3RpY2tab29tID0gMTtcbiAgICB0aGlzLmZvcm0gPSAwOyAvLyAwID0gYmxvYiwgMSA9IHN0aWNrXG5cbiAgICAvL21ha2UgaGlnaGxpZ2h0XG4gICAgdGhpcy5oaWdobGlnaHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwicmVjdFwiKTtcbiAgICB0aGlzLmhpZ2hsaWdodC5jbGFzc0xpc3QuYWRkKFwiaGlnaGxpZ2h0XCIsIFwicGFydGljaXBhbnQtaGlnaGxpZ2h0XCIpO1xuICAgIHRoaXMudXBwZXJHcm91cC5hcHBlbmRDaGlsZCh0aGlzLmhpZ2hsaWdodCk7XG5cbiAgICAvL21ha2UgYmFja2dyb3VuZFxuICAgIC8vaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xNzQzNzQwOC9ob3ctZG8taS1jaGFuZ2UtYS1jaXJjbGUtdG8tYS1zcXVhcmUtdXNpbmctZDNcbiAgICB0aGlzLmJhY2tncm91bmQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwicmVjdFwiKTtcbiAgICB0aGlzLmJhY2tncm91bmQuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcIiNGRkZGRkZcIik7XG4gICAgdGhpcy51cHBlckdyb3VwLmFwcGVuZENoaWxkKHRoaXMuYmFja2dyb3VuZCk7XG4gICAgLy9jcmVhdGUgbGFiZWwgLSB3ZSB3aWxsIG1vdmUgdGhpcyBzdmcgZWxlbWVudCBhcm91bmQgd2hlbiBwcm90ZWluIGZvcm0gY2hhbmdlc1xuICAgIHRoaXMuaW5pdExhYmVsKCk7XG4gICAgLy90aWNrcyAoYW5kIGFtaW5vIGFjaWQgbGV0dGVycylcbiAgICB0aGlzLnRpY2tzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgLy9zdmcgZ3JvdXAgZm9yIGFubm90YXRpb25zXG4gICAgdGhpcy5hbm5vdGF0aW9uc1N2Z0dyb3VwID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcImdcIik7XG4gICAgdGhpcy5hbm5vdGF0aW9uc1N2Z0dyb3VwLnNldEF0dHJpYnV0ZShcIm9wYWNpdHlcIiwgXCIxXCIpO1xuICAgIHRoaXMudXBwZXJHcm91cC5hcHBlbmRDaGlsZCh0aGlzLmFubm90YXRpb25zU3ZnR3JvdXApO1xuXG4gICAgLy9tYWtlIG91dGxpbmVcbiAgICB0aGlzLm91dGxpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwicmVjdFwiKTtcbiAgICAvLyBjc3MuLi5cbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwiYmxhY2tcIik7XG4gICAgdGhpcy5vdXRsaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBcIjFcIik7XG4gICAgdGhpcy5vdXRsaW5lLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJub25lXCIpO1xuICAgIHRoaXMudXBwZXJHcm91cC5hcHBlbmRDaGlsZCh0aGlzLm91dGxpbmUpO1xuXG4gICAgdGhpcy5zY2FsZUxhYmVscyA9IFtdO1xuXG4gICAgLy9zaW5jZSBmb3JtIGlzIHNldCB0byAwLCBtYWtlIHRoaXMgYSBjaXJjbGUsIHRoaXMgc3R1ZmYgaXMgZXF1aXZhbGVudCB0b1xuICAgIC8vIGVuZCByZXN1bHQgb2YgdG9DaXJjbGUgYnV0IHdpdGhvdXQgdHJhbnNpdGlvblxuICAgIGNvbnN0IHIgPSB0aGlzLmdldFN5bWJvbFJhZGl1cygpO1xuXG4gICAgdGhpcy5vdXRsaW5lLnNldEF0dHJpYnV0ZShcInhcIiwgLXIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJ5XCIsIC1yKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwid2lkdGhcIiwgciAqIDIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgciAqIDIpO1xuICAgIHRoaXMub3V0bGluZS5zZXRBdHRyaWJ1dGUoXCJyeFwiLCByKTtcbiAgICB0aGlzLm91dGxpbmUuc2V0QXR0cmlidXRlKFwicnlcIiwgcik7XG5cbiAgICB0aGlzLmJhY2tncm91bmQuc2V0QXR0cmlidXRlKFwieFwiLCAtcik7XG4gICAgdGhpcy5iYWNrZ3JvdW5kLnNldEF0dHJpYnV0ZShcInlcIiwgLXIpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoXCJ3aWR0aFwiLCByICogMik7XG4gICAgdGhpcy5iYWNrZ3JvdW5kLnNldEF0dHJpYnV0ZShcImhlaWdodFwiLCByICogMik7XG4gICAgdGhpcy5iYWNrZ3JvdW5kLnNldEF0dHJpYnV0ZShcInJ4XCIsIHIpO1xuICAgIHRoaXMuYmFja2dyb3VuZC5zZXRBdHRyaWJ1dGUoXCJyeVwiLCByKTtcblxuICAgIHRoaXMuYW5ub3RhdGlvbnNTdmdHcm91cC5zZXRBdHRyaWJ1dGUoXCJ0cmFuc2Zvcm1cIiwgXCJzY2FsZSgxLCAxKVwiKTtcblxuICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcIndpZHRoXCIsIChyICogMikgKyA1KTtcbiAgICB0aGlzLmhpZ2hsaWdodC5zZXRBdHRyaWJ1dGUoXCJoZWlnaHRcIiwgKHIgKiAyKSArIDUpO1xuICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcInhcIiwgLXIgLSAyLjUpO1xuICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcInlcIiwgLXIgLSAyLjUpO1xuICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcInJ4XCIsIHIgKyAyLjUpO1xuICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcInJ5XCIsIHIgKyAyLjUpO1xuICAgIHRoaXMuaGlnaGxpZ2h0LnNldEF0dHJpYnV0ZShcInN0cm9rZS1vcGFjaXR5XCIsIFwiMFwiKTtcblxuICAgIHRoaXMubGFiZWxTVkcuc2V0QXR0cmlidXRlKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICsgKC0ociArIDUpKSArIFwiLFwiICsgXCItNSlcIik7XG5cbiAgICB0aGlzLmluaXRMaXN0ZW5lcnMoKTtcblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcImhlaWdodFwiLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gaGVpZ2h0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuZm9ybSA9PSAxPyAxMjA6NDA7XG4gICAgICAgICAgICAvL3JldHVybiAxNjA7XG4gICAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuc2hvd0hpZ2hsaWdodChmYWxzZSk7XG59XG5cblByb3RlaW4ucHJvdG90eXBlID0gbmV3IFBvbHltZXIoKTtcblxuLypcblByb3RlaW4ucHJvdG90eXBlLnNob3dEYXRhID0gZnVuY3Rpb24oZXZ0KSB7XG4gICAgY29uc3QgdXJsID0gXCJodHRwOi8vd3d3LnVuaXByb3Qub3JnL3VuaXByb3QvXCIgKyB0aGlzLmpzb24uaWRlbnRpZmllci5pZDtcbiAgICB3aW5kb3cub3Blbih1cmwsICdfYmxhbmsnKTtcbn1cbiovXG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/viz/interactor/protein.js\n"); /***/ }), @@ -1357,7 +1369,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"FeatureLink\", function() { return FeatureLink; });\n/* harmony import */ var _link__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./link */ \"./src/js/viz/link/link.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n\n\n// import * as Point2D from \"point2d\";\n// import * as Intersection from \"intersectionjs\";\n\nfunction FeatureLink(id, fromFeatPos, toFeatPos, app) {\n this.init(id, fromFeatPos, toFeatPos, app);\n}\n\nFeatureLink.prototype = new _link__WEBPACK_IMPORTED_MODULE_0__[\"Link\"]();\n\nFeatureLink.prototype.init = function (id, fromFeatPos, toFeatPos, app) {\n this.id = id;\n this.app = app;\n this.fromSequenceData = fromFeatPos;\n this.toSequenceData = toFeatPos;\n\n this.participants = [this.fromSequenceData[0].participant, this.toSequenceData[0].participant]; //*\n // *potentially, this over simplifies the situation,\n // but there is a workaround in way ReadMiJson init's links so OK for now\n\n this.glyph = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"path\");\n this.uncertainGlyph = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"path\");\n // this.highlightGlyph = document.createElementNS(svgns, \"path\");\n this.glyph.setAttribute(\"stroke-linecap\", \"round\");\n this.uncertainGlyph.setAttribute(\"stroke-linecap\", \"round\");\n // this.highlightGlyph.setAttribute(\"stroke-linecap\", \"round\");\n this.glyph.setAttribute(\"class\", \"link\");\n this.glyph.setAttribute(\"fill\", \"black\");//\"#E08214\");\n this.glyph.setAttribute(\"opacity\", \"0.6\");\n this.glyph.setAttribute(\"stroke\", \"black\");//\"\"#A08214\");// // TODO: will look better with this line partly removed\n this.glyph.setAttribute(\"stroke-opacity\", \"0.6\");\n this.glyph.setAttribute(\"stroke-width\", \"1\");\n this.uncertainGlyph.setAttribute(\"class\", \"link\");\n this.uncertainGlyph.setAttribute(\"fill\", \"black\");//url('#checkers_uncertain')\");//\"#A01284\");\n this.uncertainGlyph.setAttribute(\"stroke\", \"black\");//\"none\");//\"#A01284\");\n this.uncertainGlyph.setAttribute(\"stroke-opacity\", \"0.2\");\n this.uncertainGlyph.setAttribute(\"fill-opacity\", \"0.2\");\n // this.highlightGlyph.setAttribute(\"class\", \"link\");\n // this.highlightGlyph.setAttribute(\"fill\", \"none\");\n // this.highlightGlyph.setAttribute(\"stroke\", highlightColour);\n // this.highlightGlyph.setAttribute(\"stroke-width\", \"10\");\n // this.highlightGlyph.setAttribute(\"stroke-opacity\", \"0\");\n\n //set the events for it\n const self = this;\n this.uncertainGlyph.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.uncertainGlyph.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.uncertainGlyph.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n this.glyph.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.glyph.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.glyph.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.highlightGlyph.onmousedown = function (evt) {\n // self.mouseDown(evt);\n // };\n // this.highlightGlyph.onmouseover = function (evt) {\n // self.mouseOver(evt);\n // };\n // this.highlightGlyph.onmouseout = function (evt) {\n // self.mouseOut(evt);\n // };\n};\n\n//andAlternatives means highlight alternative links in case of site ambiguity\n// FeatureLink.prototype.showHighlight = function (show) {\n// if (show) {\n// this.highlightGlyph.setAttribute(\"stroke-opacity\", \"1\");\n// } else {\n// this.highlightGlyph.setAttribute(\"stroke-opacity\", \"0\");\n// }\n// };\n\n//used when filter changed\nFeatureLink.prototype.check = function () {\n if (this.anyParticipantIsBar() === true) {\n this.show();\n return true;\n } else {\n this.hide();\n return false;\n }\n};\n\nFeatureLink.prototype.anyParticipantIsBar = function () {\n const ic = this.participants.length;\n for (let i = 0; i < ic; i++) {\n if (this.participants[i].form === 1) {\n return true;\n }\n }\n return false;\n};\n\nFeatureLink.prototype.show = function () {\n // //this.glyph.setAttribute(\"stroke-width\", this.util.z * xiNET.linkWidth);\n // this.uncertainGlyph.setAttribute(\"stroke-width\", this.util.z * 10);\n // this.highlightGlyph.setAttribute(\"stroke-width\", this.util.z * 10);\n this.setLinkCoordinates();\n let containingGroup = this.app.res_resLinks;\n if (this.participants[0] === this.participants[1]) {\n containingGroup = this.app.selfRes_resLinks;\n }\n // containingGroup.appendChild(this.highlightGlyph);\n containingGroup.appendChild(this.glyph);\n containingGroup.appendChild(this.uncertainGlyph);\n};\n\nFeatureLink.prototype.hide = function () {\n this.glyph.remove();\n this.uncertainGlyph.remove();\n};\n\n// update the links(polygons/lines) to fit to the protein\nFeatureLink.prototype.setLinkCoordinates = function () {\n function isNumber(thing) {\n return (!isNaN(parseFloat(thing)) && isFinite(thing));\n }\n\n function getSegment(midPoint, controlPoint, startRes, endRes, participant, yOffset, originPoint) {\n let startPoint, endPoint;\n if (!participant.form) { // tests if form = undefined or 0 //TODO: maybe change this, its confusing\n startPoint = participant.getPosition(originPoint);\n endPoint = startPoint;\n } else {\n startPoint = participant.getResidueCoordinates(startRes, yOffset);\n endPoint = participant.getResidueCoordinates(endRes, yOffset);\n }\n return \" Q\" + controlPoint[0] + \",\" + controlPoint[1] + \" \" + startPoint[0] + \",\" + startPoint[1] +\n \" L\" + endPoint[0] + \",\" + endPoint[1] +\n \" Q\" + controlPoint[0] + \",\" + controlPoint[1] + \" \" + midPoint[0] + \",\" + midPoint[1];\n }\n\n function sequenceDataMidPoint(sequenceData, participant) {\n //get the smallest start and the biggest end\n let lowestLinkedRes = null,\n highestLinkedRes = null;\n const sdCount = sequenceData.length;\n for (let s = 0; s < sdCount; s++) {\n const seqDatum = sequenceData[s];\n if (!isNaN(parseFloat(seqDatum.begin)) && isFinite(seqDatum.begin)) {\n // noinspection PointlessArithmeticExpressionJS\n const start = seqDatum.begin * 1; // the * 1 is necessary (type conversion)\n if (lowestLinkedRes === null || start < lowestLinkedRes) {\n lowestLinkedRes = start;\n }\n }\n if (!isNaN(parseFloat(seqDatum.uncertainBegin)) && isFinite(seqDatum.uncertainBegin)) {\n const uncertainBegin = seqDatum.uncertainBegin * 1;\n if (lowestLinkedRes === null || uncertainBegin < lowestLinkedRes) {\n lowestLinkedRes = uncertainBegin;\n }\n }\n if (!isNaN(parseFloat(seqDatum.end)) && isFinite(seqDatum.end)) {\n const end = seqDatum.end * 1;\n if (highestLinkedRes === null || end > highestLinkedRes) {\n highestLinkedRes = end;\n }\n }\n if (!isNaN(parseFloat(seqDatum.uncertainEnd)) && isFinite(seqDatum.uncertainEnd)) {\n const uncertainEnd = seqDatum.uncertainEnd * 1;\n if (highestLinkedRes === null || uncertainEnd > highestLinkedRes) {\n highestLinkedRes = uncertainEnd;\n }\n }\n }\n return participant.getResidueCoordinates((lowestLinkedRes + highestLinkedRes) / 2, 0);\n }\n\n const fromParticipant = this.fromSequenceData[0].participant;\n const toParticipant = this.toSequenceData[0].participant;\n //calculate mid points of from and to sequence data\n let fMid, tMid;\n\n if (fromParticipant.form) {\n fMid = sequenceDataMidPoint(this.fromSequenceData, fromParticipant);\n }\n if (toParticipant.form) {\n tMid = sequenceDataMidPoint(this.toSequenceData, toParticipant);\n }\n if (!fromParticipant.form) { // if not (undefined or 0)\n fMid = fromParticipant.getPosition(tMid);//toOriginPoint);\n }\n if (!toParticipant.form) {// if not (undefined or 0)\n tMid = toParticipant.getPosition(fMid);//fromOriginPoint);\n }\n\n const fromOriginPoint = fMid;//null;//[fromParticipant.cy, fromParticipant.cy];\n const toOriginPoint = tMid;//null;//[toParticipant.cy, toParticipant.cy];\n\n // if (!fromParticipant.form) { // if not (undefined or 0)\n // fMid = fromParticipant.getPosition();//toOriginPoint);\n // } else {\n // fMid = sequenceDataMidPoint(this.fromSequenceData, fromParticipant);\n // }\n // if (!toParticipant.form) {// if not (undefined or 0)\n // tMid = toParticipant.getPosition();//fromOriginPoint);\n // } else {\n // tMid = sequenceDataMidPoint(this.toSequenceData, toParticipant);\n // }\n\n //calculate angle from fromParticipant mid point to toParticipant mid point\n const deltaX = fMid[0] - tMid[0];\n const deltaY = fMid[1] - tMid[1];\n const angleBetweenMidPoints = Math.atan2(deltaY, deltaX);\n //todo: tidy up trig code so everything is always in radian\n let abmpDeg = angleBetweenMidPoints / (2 * Math.PI) * 360;\n if (abmpDeg < 0) {\n abmpDeg += 360;\n }\n\n //out is value we use to decide which side of bar the link glyph is drawn\n //first for 'from' participant\n let out = (abmpDeg - fromParticipant.rotation);\n if (out < 0) {\n out += 360;\n }\n let fyOffset = 10;\n if (out < 180) {\n fyOffset = -10;\n }\n let fRotRad = (fromParticipant.rotation / 360) * Math.PI * 2;\n if (out > 180) {\n fRotRad -= Math.PI;\n }\n //now for 'to' participant\n out = (abmpDeg - toParticipant.rotation);\n if (out < 0) {\n out += 360;\n }\n let tyOffset = 10;\n if (out > 180) {\n tyOffset = -10;\n }\n let tRotRad = (toParticipant.rotation / 360) * Math.PI * 2;\n if (out < 180) {\n tRotRad -= Math.PI;\n }\n\n let ftMid = [fMid[0] + (30 * Math.sin(fRotRad) * this.app.z),\n fMid[1] - (30 * Math.cos(fRotRad) * this.app.z)\n ];\n if (!fromParticipant.form) { // if not (undefined or 0)\n ftMid = fMid;\n }\n\n let ttMid = [tMid[0] + (30 * Math.sin(tRotRad) * this.app.z),\n tMid[1] - (30 * Math.cos(tRotRad) * this.app.z)\n ];\n if (!toParticipant.form) { // if not (undefined or 0)\n ttMid = tMid;\n }\n\n const triPointMid = [(ftMid[0] + ttMid[0]) / 2, (ftMid[1] + ttMid[1]) / 2];\n const fSDCount = this.fromSequenceData.length;\n const tSDCount = this.toSequenceData.length;\n let seqDatum;//, highlightStartRes, highlightEndRes;\n let glyphPath = \"M\" + triPointMid[0] + \",\" + triPointMid[1];\n let uncertainGlyphPath = \"M\" + triPointMid[0] + \",\" + triPointMid[1];\n // let highlightGlyphPath = \"M\" + triPointMid[0] + \",\" + triPointMid[1];\n for (let f = 0; f < fSDCount; f++) {\n seqDatum = this.fromSequenceData[f];\n if (isNumber(seqDatum.begin) && isNumber(seqDatum.end)) {\n glyphPath += getSegment(triPointMid, ftMid, seqDatum.begin, seqDatum.end, fromParticipant, fyOffset, toOriginPoint);\n }\n // highlightStartRes = seqDatum.begin;\n // highlightEndRes = seqDatum.end;\n if (isNumber(seqDatum.uncertainBegin)) {\n uncertainGlyphPath += getSegment(triPointMid, ftMid,\n seqDatum.uncertainBegin, seqDatum.begin, fromParticipant, fyOffset, toOriginPoint);\n // highlightStartRes = seqDatum.uncertainBegin;\n }\n if (isNumber(seqDatum.uncertainEnd)) {\n uncertainGlyphPath += getSegment(triPointMid, ftMid,\n seqDatum.end, seqDatum.uncertainEnd, fromParticipant, fyOffset, toOriginPoint);\n // highlightEndRes = seqDatum.uncertainEnd;\n }\n // highlightGlyphPath += getPathSegments(triPointMid, ftMid,\n // highlightStartRes, highlightEndRes, fromParticipant, fyOffset);\n }\n for (let t = 0; t < tSDCount; t++) {\n seqDatum = this.toSequenceData[t];\n if (isNumber(seqDatum.begin) && isNumber(seqDatum.end)) {\n glyphPath += getSegment(triPointMid, ttMid, seqDatum.begin, seqDatum.end, toParticipant, tyOffset, fromOriginPoint);\n }\n // highlightStartRes = seqDatum.begin;\n // highlightEndRes = seqDatum.end;\n if (isNumber(seqDatum.uncertainBegin)) {\n uncertainGlyphPath += getSegment(triPointMid, ttMid,\n seqDatum.uncertainBegin, seqDatum.begin, toParticipant, tyOffset, fromOriginPoint);\n // highlightStartRes = seqDatum.uncertainBegin;\n }\n if (isNumber(seqDatum.uncertainEnd)) {\n uncertainGlyphPath += getSegment(triPointMid, ttMid,\n seqDatum.end, seqDatum.uncertainEnd, toParticipant, tyOffset, fromOriginPoint);\n // highlightEndRes = seqDatum.uncertainEnd;\n }\n // highlightGlyphPath += getPathSegments(triPointMid, ttMid,\n // highlightStartRes, highlightEndRes, toParticipant, tyOffset);\n }\n\n if (!this.glyph) {\n this.initSVG();\n }\n\n this.glyph.setAttribute(\"d\", glyphPath);\n this.uncertainGlyph.setAttribute(\"d\", uncertainGlyphPath);\n // this.highlightGlyph.setAttribute(\"d\", highlightGlyphPath);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2xpbmsvZmVhdHVyZS1saW5rLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy92aXovbGluay9mZWF0dXJlLWxpbmsuanM/MWE1MCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0xpbmt9IGZyb20gXCIuL2xpbmtcIjtcbmltcG9ydCB7c3ZnbnN9IGZyb20gXCIuLi8uLi9jb25maWdcIjtcbi8vIGltcG9ydCAqIGFzIFBvaW50MkQgZnJvbSBcInBvaW50MmRcIjtcbi8vIGltcG9ydCAqIGFzIEludGVyc2VjdGlvbiBmcm9tIFwiaW50ZXJzZWN0aW9uanNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIEZlYXR1cmVMaW5rKGlkLCBmcm9tRmVhdFBvcywgdG9GZWF0UG9zLCBhcHApIHtcbiAgICB0aGlzLmluaXQoaWQsIGZyb21GZWF0UG9zLCB0b0ZlYXRQb3MsIGFwcCk7XG59XG5cbkZlYXR1cmVMaW5rLnByb3RvdHlwZSA9IG5ldyBMaW5rKCk7XG5cbkZlYXR1cmVMaW5rLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKGlkLCBmcm9tRmVhdFBvcywgdG9GZWF0UG9zLCBhcHApIHtcbiAgICB0aGlzLmlkID0gaWQ7XG4gICAgdGhpcy5hcHAgPSBhcHA7XG4gICAgdGhpcy5mcm9tU2VxdWVuY2VEYXRhID0gZnJvbUZlYXRQb3M7XG4gICAgdGhpcy50b1NlcXVlbmNlRGF0YSA9IHRvRmVhdFBvcztcblxuICAgIHRoaXMucGFydGljaXBhbnRzID0gW3RoaXMuZnJvbVNlcXVlbmNlRGF0YVswXS5wYXJ0aWNpcGFudCwgdGhpcy50b1NlcXVlbmNlRGF0YVswXS5wYXJ0aWNpcGFudF07IC8vKlxuICAgIC8vICpwb3RlbnRpYWxseSwgdGhpcyBvdmVyIHNpbXBsaWZpZXMgdGhlIHNpdHVhdGlvbixcbiAgICAvLyBidXQgdGhlcmUgaXMgYSB3b3JrYXJvdW5kIGluIHdheSBSZWFkTWlKc29uIGluaXQncyBsaW5rcyBzbyBPSyBmb3Igbm93XG5cbiAgICB0aGlzLmdseXBoID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInBhdGhcIik7XG4gICAgdGhpcy51bmNlcnRhaW5HbHlwaCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJwYXRoXCIpO1xuICAgIC8vIHRoaXMuaGlnaGxpZ2h0R2x5cGggPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoc3ZnbnMsIFwicGF0aFwiKTtcbiAgICB0aGlzLmdseXBoLnNldEF0dHJpYnV0ZShcInN0cm9rZS1saW5lY2FwXCIsIFwicm91bmRcIik7XG4gICAgdGhpcy51bmNlcnRhaW5HbHlwaC5zZXRBdHRyaWJ1dGUoXCJzdHJva2UtbGluZWNhcFwiLCBcInJvdW5kXCIpO1xuICAgIC8vIHRoaXMuaGlnaGxpZ2h0R2x5cGguc2V0QXR0cmlidXRlKFwic3Ryb2tlLWxpbmVjYXBcIiwgXCJyb3VuZFwiKTtcbiAgICB0aGlzLmdseXBoLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIFwibGlua1wiKTtcbiAgICB0aGlzLmdseXBoLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJibGFja1wiKTsvL1wiI0UwODIxNFwiKTtcbiAgICB0aGlzLmdseXBoLnNldEF0dHJpYnV0ZShcIm9wYWNpdHlcIiwgXCIwLjZcIik7XG4gICAgdGhpcy5nbHlwaC5zZXRBdHRyaWJ1dGUoXCJzdHJva2VcIiwgXCJibGFja1wiKTsvL1wiXCIjQTA4MjE0XCIpOy8vIC8vIFRPRE86IHdpbGwgbG9vayBiZXR0ZXIgd2l0aCB0aGlzIGxpbmUgcGFydGx5IHJlbW92ZWRcbiAgICB0aGlzLmdseXBoLnNldEF0dHJpYnV0ZShcInN0cm9rZS1vcGFjaXR5XCIsIFwiMC42XCIpO1xuICAgIHRoaXMuZ2x5cGguc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIFwiMVwiKTtcbiAgICB0aGlzLnVuY2VydGFpbkdseXBoLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIFwibGlua1wiKTtcbiAgICB0aGlzLnVuY2VydGFpbkdseXBoLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJibGFja1wiKTsvL3VybCgnI2NoZWNrZXJzX3VuY2VydGFpbicpXCIpOy8vXCIjQTAxMjg0XCIpO1xuICAgIHRoaXMudW5jZXJ0YWluR2x5cGguc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwiYmxhY2tcIik7Ly9cIm5vbmVcIik7Ly9cIiNBMDEyODRcIik7XG4gICAgdGhpcy51bmNlcnRhaW5HbHlwaC5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utb3BhY2l0eVwiLCBcIjAuMlwiKTtcbiAgICB0aGlzLnVuY2VydGFpbkdseXBoLnNldEF0dHJpYnV0ZShcImZpbGwtb3BhY2l0eVwiLCBcIjAuMlwiKTtcbiAgICAvLyB0aGlzLmhpZ2hsaWdodEdseXBoLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIFwibGlua1wiKTtcbiAgICAvLyB0aGlzLmhpZ2hsaWdodEdseXBoLnNldEF0dHJpYnV0ZShcImZpbGxcIiwgXCJub25lXCIpO1xuICAgIC8vIHRoaXMuaGlnaGxpZ2h0R2x5cGguc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIGhpZ2hsaWdodENvbG91cik7XG4gICAgLy8gdGhpcy5oaWdobGlnaHRHbHlwaC5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgXCIxMFwiKTtcbiAgICAvLyB0aGlzLmhpZ2hsaWdodEdseXBoLnNldEF0dHJpYnV0ZShcInN0cm9rZS1vcGFjaXR5XCIsIFwiMFwiKTtcblxuICAgIC8vc2V0IHRoZSBldmVudHMgZm9yIGl0XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy51bmNlcnRhaW5HbHlwaC5vbm1vdXNlZG93biA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5tb3VzZURvd24oZXZ0KTtcbiAgICB9O1xuICAgIHRoaXMudW5jZXJ0YWluR2x5cGgub25tb3VzZW92ZXIgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdmVyKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLnVuY2VydGFpbkdseXBoLm9ubW91c2VvdXQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdXQoZXZ0KTtcbiAgICB9O1xuICAgIHRoaXMuZ2x5cGgub25tb3VzZWRvd24gPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VEb3duKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLmdseXBoLm9ubW91c2VvdmVyID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlT3ZlcihldnQpO1xuICAgIH07XG4gICAgdGhpcy5nbHlwaC5vbm1vdXNlb3V0ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlT3V0KGV2dCk7XG4gICAgfTtcbiAgICAvLyB0aGlzLmhpZ2hsaWdodEdseXBoLm9ubW91c2Vkb3duID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIC8vICAgICBzZWxmLm1vdXNlRG93bihldnQpO1xuICAgIC8vIH07XG4gICAgLy8gdGhpcy5oaWdobGlnaHRHbHlwaC5vbm1vdXNlb3ZlciA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAvLyAgICAgc2VsZi5tb3VzZU92ZXIoZXZ0KTtcbiAgICAvLyB9O1xuICAgIC8vIHRoaXMuaGlnaGxpZ2h0R2x5cGgub25tb3VzZW91dCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAvLyAgICAgc2VsZi5tb3VzZU91dChldnQpO1xuICAgIC8vIH07XG59O1xuXG4vL2FuZEFsdGVybmF0aXZlcyBtZWFucyBoaWdobGlnaHQgYWx0ZXJuYXRpdmUgbGlua3MgaW4gY2FzZSBvZiBzaXRlIGFtYmlndWl0eVxuLy8gRmVhdHVyZUxpbmsucHJvdG90eXBlLnNob3dIaWdobGlnaHQgPSBmdW5jdGlvbiAoc2hvdykge1xuLy8gICAgIGlmIChzaG93KSB7XG4vLyAgICAgICAgIHRoaXMuaGlnaGxpZ2h0R2x5cGguc2V0QXR0cmlidXRlKFwic3Ryb2tlLW9wYWNpdHlcIiwgXCIxXCIpO1xuLy8gICAgIH0gZWxzZSB7XG4vLyAgICAgICAgIHRoaXMuaGlnaGxpZ2h0R2x5cGguc2V0QXR0cmlidXRlKFwic3Ryb2tlLW9wYWNpdHlcIiwgXCIwXCIpO1xuLy8gICAgIH1cbi8vIH07XG5cbi8vdXNlZCB3aGVuIGZpbHRlciBjaGFuZ2VkXG5GZWF0dXJlTGluay5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuYW55UGFydGljaXBhbnRJc0JhcigpID09PSB0cnVlKSB7XG4gICAgICAgIHRoaXMuc2hvdygpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn07XG5cbkZlYXR1cmVMaW5rLnByb3RvdHlwZS5hbnlQYXJ0aWNpcGFudElzQmFyID0gZnVuY3Rpb24gKCkge1xuICAgIGNvbnN0IGljID0gdGhpcy5wYXJ0aWNpcGFudHMubGVuZ3RoO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaWM7IGkrKykge1xuICAgICAgICBpZiAodGhpcy5wYXJ0aWNpcGFudHNbaV0uZm9ybSA9PT0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuRmVhdHVyZUxpbmsucHJvdG90eXBlLnNob3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgLy8gLy90aGlzLmdseXBoLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCB0aGlzLnV0aWwueiAqIHhpTkVULmxpbmtXaWR0aCk7XG4gICAgLy8gdGhpcy51bmNlcnRhaW5HbHlwaC5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgdGhpcy51dGlsLnogKiAxMCk7XG4gICAgLy8gdGhpcy5oaWdobGlnaHRHbHlwaC5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgdGhpcy51dGlsLnogKiAxMCk7XG4gICAgdGhpcy5zZXRMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICBsZXQgY29udGFpbmluZ0dyb3VwID0gdGhpcy5hcHAucmVzX3Jlc0xpbmtzO1xuICAgIGlmICh0aGlzLnBhcnRpY2lwYW50c1swXSA9PT0gdGhpcy5wYXJ0aWNpcGFudHNbMV0pIHtcbiAgICAgICAgY29udGFpbmluZ0dyb3VwID0gdGhpcy5hcHAuc2VsZlJlc19yZXNMaW5rcztcbiAgICB9XG4gICAgLy8gY29udGFpbmluZ0dyb3VwLmFwcGVuZENoaWxkKHRoaXMuaGlnaGxpZ2h0R2x5cGgpO1xuICAgIGNvbnRhaW5pbmdHcm91cC5hcHBlbmRDaGlsZCh0aGlzLmdseXBoKTtcbiAgICBjb250YWluaW5nR3JvdXAuYXBwZW5kQ2hpbGQodGhpcy51bmNlcnRhaW5HbHlwaCk7XG59O1xuXG5GZWF0dXJlTGluay5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmdseXBoLnJlbW92ZSgpO1xuICAgIHRoaXMudW5jZXJ0YWluR2x5cGgucmVtb3ZlKCk7XG59O1xuXG4vLyB1cGRhdGUgdGhlIGxpbmtzKHBvbHlnb25zL2xpbmVzKSB0byBmaXQgdG8gdGhlIHByb3RlaW5cbkZlYXR1cmVMaW5rLnByb3RvdHlwZS5zZXRMaW5rQ29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gaXNOdW1iZXIodGhpbmcpIHtcbiAgICAgICAgcmV0dXJuICghaXNOYU4ocGFyc2VGbG9hdCh0aGluZykpICYmIGlzRmluaXRlKHRoaW5nKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0U2VnbWVudChtaWRQb2ludCwgY29udHJvbFBvaW50LCBzdGFydFJlcywgZW5kUmVzLCBwYXJ0aWNpcGFudCwgeU9mZnNldCwgb3JpZ2luUG9pbnQpIHtcbiAgICAgICAgbGV0IHN0YXJ0UG9pbnQsIGVuZFBvaW50O1xuICAgICAgICBpZiAoIXBhcnRpY2lwYW50LmZvcm0pIHsgLy8gdGVzdHMgaWYgZm9ybSA9IHVuZGVmaW5lZCBvciAwIC8vVE9ETzogbWF5YmUgY2hhbmdlIHRoaXMsIGl0cyBjb25mdXNpbmdcbiAgICAgICAgICAgIHN0YXJ0UG9pbnQgPSBwYXJ0aWNpcGFudC5nZXRQb3NpdGlvbihvcmlnaW5Qb2ludCk7XG4gICAgICAgICAgICBlbmRQb2ludCA9IHN0YXJ0UG9pbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdGFydFBvaW50ID0gcGFydGljaXBhbnQuZ2V0UmVzaWR1ZUNvb3JkaW5hdGVzKHN0YXJ0UmVzLCB5T2Zmc2V0KTtcbiAgICAgICAgICAgIGVuZFBvaW50ID0gcGFydGljaXBhbnQuZ2V0UmVzaWR1ZUNvb3JkaW5hdGVzKGVuZFJlcywgeU9mZnNldCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFwiIFFcIiArIGNvbnRyb2xQb2ludFswXSArIFwiLFwiICsgY29udHJvbFBvaW50WzFdICsgXCIgXCIgKyBzdGFydFBvaW50WzBdICsgXCIsXCIgKyBzdGFydFBvaW50WzFdICtcbiAgICAgICAgICAgIFwiIExcIiArIGVuZFBvaW50WzBdICsgXCIsXCIgKyBlbmRQb2ludFsxXSArXG4gICAgICAgICAgICBcIiBRXCIgKyBjb250cm9sUG9pbnRbMF0gKyBcIixcIiArIGNvbnRyb2xQb2ludFsxXSArIFwiIFwiICsgbWlkUG9pbnRbMF0gKyBcIixcIiArIG1pZFBvaW50WzFdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNlcXVlbmNlRGF0YU1pZFBvaW50KHNlcXVlbmNlRGF0YSwgcGFydGljaXBhbnQpIHtcbiAgICAgICAgLy9nZXQgdGhlIHNtYWxsZXN0IHN0YXJ0IGFuZCB0aGUgYmlnZ2VzdCBlbmRcbiAgICAgICAgbGV0IGxvd2VzdExpbmtlZFJlcyA9IG51bGwsXG4gICAgICAgICAgICBoaWdoZXN0TGlua2VkUmVzID0gbnVsbDtcbiAgICAgICAgY29uc3Qgc2RDb3VudCA9IHNlcXVlbmNlRGF0YS5sZW5ndGg7XG4gICAgICAgIGZvciAobGV0IHMgPSAwOyBzIDwgc2RDb3VudDsgcysrKSB7XG4gICAgICAgICAgICBjb25zdCBzZXFEYXR1bSA9IHNlcXVlbmNlRGF0YVtzXTtcbiAgICAgICAgICAgIGlmICghaXNOYU4ocGFyc2VGbG9hdChzZXFEYXR1bS5iZWdpbikpICYmIGlzRmluaXRlKHNlcURhdHVtLmJlZ2luKSkge1xuICAgICAgICAgICAgICAgIC8vIG5vaW5zcGVjdGlvbiBQb2ludGxlc3NBcml0aG1ldGljRXhwcmVzc2lvbkpTXG4gICAgICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSBzZXFEYXR1bS5iZWdpbiAqIDE7IC8vIHRoZSAqIDEgaXMgbmVjZXNzYXJ5ICh0eXBlIGNvbnZlcnNpb24pXG4gICAgICAgICAgICAgICAgaWYgKGxvd2VzdExpbmtlZFJlcyA9PT0gbnVsbCB8fCBzdGFydCA8IGxvd2VzdExpbmtlZFJlcykge1xuICAgICAgICAgICAgICAgICAgICBsb3dlc3RMaW5rZWRSZXMgPSBzdGFydDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWlzTmFOKHBhcnNlRmxvYXQoc2VxRGF0dW0udW5jZXJ0YWluQmVnaW4pKSAmJiBpc0Zpbml0ZShzZXFEYXR1bS51bmNlcnRhaW5CZWdpbikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB1bmNlcnRhaW5CZWdpbiA9IHNlcURhdHVtLnVuY2VydGFpbkJlZ2luICogMTtcbiAgICAgICAgICAgICAgICBpZiAobG93ZXN0TGlua2VkUmVzID09PSBudWxsIHx8IHVuY2VydGFpbkJlZ2luIDwgbG93ZXN0TGlua2VkUmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvd2VzdExpbmtlZFJlcyA9IHVuY2VydGFpbkJlZ2luO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaXNOYU4ocGFyc2VGbG9hdChzZXFEYXR1bS5lbmQpKSAmJiBpc0Zpbml0ZShzZXFEYXR1bS5lbmQpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZW5kID0gc2VxRGF0dW0uZW5kICogMTtcbiAgICAgICAgICAgICAgICBpZiAoaGlnaGVzdExpbmtlZFJlcyA9PT0gbnVsbCB8fCBlbmQgPiBoaWdoZXN0TGlua2VkUmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGhpZ2hlc3RMaW5rZWRSZXMgPSBlbmQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc05hTihwYXJzZUZsb2F0KHNlcURhdHVtLnVuY2VydGFpbkVuZCkpICYmIGlzRmluaXRlKHNlcURhdHVtLnVuY2VydGFpbkVuZCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB1bmNlcnRhaW5FbmQgPSBzZXFEYXR1bS51bmNlcnRhaW5FbmQgKiAxO1xuICAgICAgICAgICAgICAgIGlmIChoaWdoZXN0TGlua2VkUmVzID09PSBudWxsIHx8IHVuY2VydGFpbkVuZCA+IGhpZ2hlc3RMaW5rZWRSZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgaGlnaGVzdExpbmtlZFJlcyA9IHVuY2VydGFpbkVuZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcnRpY2lwYW50LmdldFJlc2lkdWVDb29yZGluYXRlcygobG93ZXN0TGlua2VkUmVzICsgaGlnaGVzdExpbmtlZFJlcykgLyAyLCAwKTtcbiAgICB9XG5cbiAgICBjb25zdCBmcm9tUGFydGljaXBhbnQgPSB0aGlzLmZyb21TZXF1ZW5jZURhdGFbMF0ucGFydGljaXBhbnQ7XG4gICAgY29uc3QgdG9QYXJ0aWNpcGFudCA9IHRoaXMudG9TZXF1ZW5jZURhdGFbMF0ucGFydGljaXBhbnQ7XG4gICAgLy9jYWxjdWxhdGUgbWlkIHBvaW50cyBvZiBmcm9tIGFuZCB0byBzZXF1ZW5jZSBkYXRhXG4gICAgbGV0IGZNaWQsIHRNaWQ7XG5cbiAgICBpZiAoZnJvbVBhcnRpY2lwYW50LmZvcm0pICB7XG4gICAgICAgIGZNaWQgPSBzZXF1ZW5jZURhdGFNaWRQb2ludCh0aGlzLmZyb21TZXF1ZW5jZURhdGEsIGZyb21QYXJ0aWNpcGFudCk7XG4gICAgfVxuICAgIGlmICh0b1BhcnRpY2lwYW50LmZvcm0pICB7XG4gICAgICAgIHRNaWQgPSBzZXF1ZW5jZURhdGFNaWRQb2ludCh0aGlzLnRvU2VxdWVuY2VEYXRhLCB0b1BhcnRpY2lwYW50KTtcbiAgICB9XG4gICAgaWYgKCFmcm9tUGFydGljaXBhbnQuZm9ybSkgeyAvLyBpZiBub3QgKHVuZGVmaW5lZCBvciAwKVxuICAgICAgICBmTWlkID0gZnJvbVBhcnRpY2lwYW50LmdldFBvc2l0aW9uKHRNaWQpOy8vdG9PcmlnaW5Qb2ludCk7XG4gICAgfVxuICAgIGlmICghdG9QYXJ0aWNpcGFudC5mb3JtKSB7Ly8gaWYgbm90ICh1bmRlZmluZWQgb3IgMClcbiAgICAgICAgdE1pZCA9IHRvUGFydGljaXBhbnQuZ2V0UG9zaXRpb24oZk1pZCk7Ly9mcm9tT3JpZ2luUG9pbnQpO1xuICAgIH1cblxuICAgIGNvbnN0IGZyb21PcmlnaW5Qb2ludCA9IGZNaWQ7Ly9udWxsOy8vW2Zyb21QYXJ0aWNpcGFudC5jeSwgZnJvbVBhcnRpY2lwYW50LmN5XTtcbiAgICBjb25zdCB0b09yaWdpblBvaW50ID0gdE1pZDsvL251bGw7Ly9bdG9QYXJ0aWNpcGFudC5jeSwgdG9QYXJ0aWNpcGFudC5jeV07XG5cbiAgICAvLyBpZiAoIWZyb21QYXJ0aWNpcGFudC5mb3JtKSB7IC8vIGlmIG5vdCAodW5kZWZpbmVkIG9yIDApXG4gICAgLy8gICAgIGZNaWQgPSBmcm9tUGFydGljaXBhbnQuZ2V0UG9zaXRpb24oKTsvL3RvT3JpZ2luUG9pbnQpO1xuICAgIC8vIH0gZWxzZSB7XG4gICAgLy8gICAgIGZNaWQgPSBzZXF1ZW5jZURhdGFNaWRQb2ludCh0aGlzLmZyb21TZXF1ZW5jZURhdGEsIGZyb21QYXJ0aWNpcGFudCk7XG4gICAgLy8gfVxuICAgIC8vIGlmICghdG9QYXJ0aWNpcGFudC5mb3JtKSB7Ly8gaWYgbm90ICh1bmRlZmluZWQgb3IgMClcbiAgICAvLyAgICAgdE1pZCA9IHRvUGFydGljaXBhbnQuZ2V0UG9zaXRpb24oKTsvL2Zyb21PcmlnaW5Qb2ludCk7XG4gICAgLy8gfSBlbHNlIHtcbiAgICAvLyAgICAgdE1pZCA9IHNlcXVlbmNlRGF0YU1pZFBvaW50KHRoaXMudG9TZXF1ZW5jZURhdGEsIHRvUGFydGljaXBhbnQpO1xuICAgIC8vIH1cblxuICAgIC8vY2FsY3VsYXRlIGFuZ2xlIGZyb20gZnJvbVBhcnRpY2lwYW50IG1pZCBwb2ludCB0byB0b1BhcnRpY2lwYW50IG1pZCBwb2ludFxuICAgIGNvbnN0IGRlbHRhWCA9IGZNaWRbMF0gLSB0TWlkWzBdO1xuICAgIGNvbnN0IGRlbHRhWSA9IGZNaWRbMV0gLSB0TWlkWzFdO1xuICAgIGNvbnN0IGFuZ2xlQmV0d2Vlbk1pZFBvaW50cyA9IE1hdGguYXRhbjIoZGVsdGFZLCBkZWx0YVgpO1xuICAgIC8vdG9kbzogdGlkeSB1cCB0cmlnIGNvZGUgc28gZXZlcnl0aGluZyBpcyBhbHdheXMgaW4gcmFkaWFuXG4gICAgbGV0IGFibXBEZWcgPSBhbmdsZUJldHdlZW5NaWRQb2ludHMgLyAoMiAqIE1hdGguUEkpICogMzYwO1xuICAgIGlmIChhYm1wRGVnIDwgMCkge1xuICAgICAgICBhYm1wRGVnICs9IDM2MDtcbiAgICB9XG5cbiAgICAvL291dCBpcyB2YWx1ZSB3ZSB1c2UgdG8gZGVjaWRlIHdoaWNoIHNpZGUgb2YgYmFyIHRoZSBsaW5rIGdseXBoIGlzIGRyYXduXG4gICAgLy9maXJzdCBmb3IgJ2Zyb20nIHBhcnRpY2lwYW50XG4gICAgbGV0IG91dCA9IChhYm1wRGVnIC0gZnJvbVBhcnRpY2lwYW50LnJvdGF0aW9uKTtcbiAgICBpZiAob3V0IDwgMCkge1xuICAgICAgICBvdXQgKz0gMzYwO1xuICAgIH1cbiAgICBsZXQgZnlPZmZzZXQgPSAxMDtcbiAgICBpZiAob3V0IDwgMTgwKSB7XG4gICAgICAgIGZ5T2Zmc2V0ID0gLTEwO1xuICAgIH1cbiAgICBsZXQgZlJvdFJhZCA9IChmcm9tUGFydGljaXBhbnQucm90YXRpb24gLyAzNjApICogTWF0aC5QSSAqIDI7XG4gICAgaWYgKG91dCA+IDE4MCkge1xuICAgICAgICBmUm90UmFkIC09IE1hdGguUEk7XG4gICAgfVxuICAgIC8vbm93IGZvciAndG8nIHBhcnRpY2lwYW50XG4gICAgb3V0ID0gKGFibXBEZWcgLSB0b1BhcnRpY2lwYW50LnJvdGF0aW9uKTtcbiAgICBpZiAob3V0IDwgMCkge1xuICAgICAgICBvdXQgKz0gMzYwO1xuICAgIH1cbiAgICBsZXQgdHlPZmZzZXQgPSAxMDtcbiAgICBpZiAob3V0ID4gMTgwKSB7XG4gICAgICAgIHR5T2Zmc2V0ID0gLTEwO1xuICAgIH1cbiAgICBsZXQgdFJvdFJhZCA9ICh0b1BhcnRpY2lwYW50LnJvdGF0aW9uIC8gMzYwKSAqIE1hdGguUEkgKiAyO1xuICAgIGlmIChvdXQgPCAxODApIHtcbiAgICAgICAgdFJvdFJhZCAtPSBNYXRoLlBJO1xuICAgIH1cblxuICAgIGxldCBmdE1pZCA9IFtmTWlkWzBdICsgKDMwICogTWF0aC5zaW4oZlJvdFJhZCkgKiB0aGlzLmFwcC56KSxcbiAgICAgICAgZk1pZFsxXSAtICgzMCAqIE1hdGguY29zKGZSb3RSYWQpICogdGhpcy5hcHAueilcbiAgICBdO1xuICAgIGlmICghZnJvbVBhcnRpY2lwYW50LmZvcm0pIHsgLy8gaWYgbm90ICh1bmRlZmluZWQgb3IgMClcbiAgICAgICAgZnRNaWQgPSBmTWlkO1xuICAgIH1cblxuICAgIGxldCB0dE1pZCA9IFt0TWlkWzBdICsgKDMwICogTWF0aC5zaW4odFJvdFJhZCkgKiB0aGlzLmFwcC56KSxcbiAgICAgICAgdE1pZFsxXSAtICgzMCAqIE1hdGguY29zKHRSb3RSYWQpICogdGhpcy5hcHAueilcbiAgICBdO1xuICAgIGlmICghdG9QYXJ0aWNpcGFudC5mb3JtKSB7IC8vIGlmIG5vdCAodW5kZWZpbmVkIG9yIDApXG4gICAgICAgIHR0TWlkID0gdE1pZDtcbiAgICB9XG5cbiAgICBjb25zdCB0cmlQb2ludE1pZCA9IFsoZnRNaWRbMF0gKyB0dE1pZFswXSkgLyAyLCAoZnRNaWRbMV0gKyB0dE1pZFsxXSkgLyAyXTtcbiAgICBjb25zdCBmU0RDb3VudCA9IHRoaXMuZnJvbVNlcXVlbmNlRGF0YS5sZW5ndGg7XG4gICAgY29uc3QgdFNEQ291bnQgPSB0aGlzLnRvU2VxdWVuY2VEYXRhLmxlbmd0aDtcbiAgICBsZXQgc2VxRGF0dW07Ly8sIGhpZ2hsaWdodFN0YXJ0UmVzLCBoaWdobGlnaHRFbmRSZXM7XG4gICAgbGV0IGdseXBoUGF0aCA9IFwiTVwiICsgdHJpUG9pbnRNaWRbMF0gKyBcIixcIiArIHRyaVBvaW50TWlkWzFdO1xuICAgIGxldCB1bmNlcnRhaW5HbHlwaFBhdGggPSBcIk1cIiArIHRyaVBvaW50TWlkWzBdICsgXCIsXCIgKyB0cmlQb2ludE1pZFsxXTtcbiAgICAvLyBsZXQgaGlnaGxpZ2h0R2x5cGhQYXRoID0gXCJNXCIgKyB0cmlQb2ludE1pZFswXSArIFwiLFwiICsgdHJpUG9pbnRNaWRbMV07XG4gICAgZm9yIChsZXQgZiA9IDA7IGYgPCBmU0RDb3VudDsgZisrKSB7XG4gICAgICAgIHNlcURhdHVtID0gdGhpcy5mcm9tU2VxdWVuY2VEYXRhW2ZdO1xuICAgICAgICBpZiAoaXNOdW1iZXIoc2VxRGF0dW0uYmVnaW4pICAmJiBpc051bWJlcihzZXFEYXR1bS5lbmQpKSB7XG4gICAgICAgICAgICBnbHlwaFBhdGggKz0gZ2V0U2VnbWVudCh0cmlQb2ludE1pZCwgZnRNaWQsIHNlcURhdHVtLmJlZ2luLCBzZXFEYXR1bS5lbmQsIGZyb21QYXJ0aWNpcGFudCwgZnlPZmZzZXQsIHRvT3JpZ2luUG9pbnQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGhpZ2hsaWdodFN0YXJ0UmVzID0gc2VxRGF0dW0uYmVnaW47XG4gICAgICAgIC8vIGhpZ2hsaWdodEVuZFJlcyA9IHNlcURhdHVtLmVuZDtcbiAgICAgICAgaWYgKGlzTnVtYmVyKHNlcURhdHVtLnVuY2VydGFpbkJlZ2luKSkge1xuICAgICAgICAgICAgdW5jZXJ0YWluR2x5cGhQYXRoICs9IGdldFNlZ21lbnQodHJpUG9pbnRNaWQsIGZ0TWlkLFxuICAgICAgICAgICAgICAgIHNlcURhdHVtLnVuY2VydGFpbkJlZ2luLCBzZXFEYXR1bS5iZWdpbiwgZnJvbVBhcnRpY2lwYW50LCBmeU9mZnNldCwgdG9PcmlnaW5Qb2ludCk7XG4gICAgICAgICAgICAvLyBoaWdobGlnaHRTdGFydFJlcyA9IHNlcURhdHVtLnVuY2VydGFpbkJlZ2luO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc051bWJlcihzZXFEYXR1bS51bmNlcnRhaW5FbmQpKSB7XG4gICAgICAgICAgICB1bmNlcnRhaW5HbHlwaFBhdGggKz0gZ2V0U2VnbWVudCh0cmlQb2ludE1pZCwgZnRNaWQsXG4gICAgICAgICAgICAgICAgc2VxRGF0dW0uZW5kLCBzZXFEYXR1bS51bmNlcnRhaW5FbmQsIGZyb21QYXJ0aWNpcGFudCwgZnlPZmZzZXQsIHRvT3JpZ2luUG9pbnQpO1xuICAgICAgICAgICAgLy8gaGlnaGxpZ2h0RW5kUmVzID0gc2VxRGF0dW0udW5jZXJ0YWluRW5kO1xuICAgICAgICB9XG4gICAgICAgIC8vIGhpZ2hsaWdodEdseXBoUGF0aCArPSBnZXRQYXRoU2VnbWVudHModHJpUG9pbnRNaWQsIGZ0TWlkLFxuICAgICAgICAvLyAgICAgaGlnaGxpZ2h0U3RhcnRSZXMsIGhpZ2hsaWdodEVuZFJlcywgZnJvbVBhcnRpY2lwYW50LCBmeU9mZnNldCk7XG4gICAgfVxuICAgIGZvciAobGV0IHQgPSAwOyB0IDwgdFNEQ291bnQ7IHQrKykge1xuICAgICAgICBzZXFEYXR1bSA9IHRoaXMudG9TZXF1ZW5jZURhdGFbdF07XG4gICAgICAgIGlmIChpc051bWJlcihzZXFEYXR1bS5iZWdpbikgJiYgaXNOdW1iZXIoc2VxRGF0dW0uZW5kKSkge1xuICAgICAgICAgICAgZ2x5cGhQYXRoICs9IGdldFNlZ21lbnQodHJpUG9pbnRNaWQsIHR0TWlkLCBzZXFEYXR1bS5iZWdpbiwgc2VxRGF0dW0uZW5kLCB0b1BhcnRpY2lwYW50LCB0eU9mZnNldCwgZnJvbU9yaWdpblBvaW50KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBoaWdobGlnaHRTdGFydFJlcyA9IHNlcURhdHVtLmJlZ2luO1xuICAgICAgICAvLyBoaWdobGlnaHRFbmRSZXMgPSBzZXFEYXR1bS5lbmQ7XG4gICAgICAgIGlmIChpc051bWJlcihzZXFEYXR1bS51bmNlcnRhaW5CZWdpbikpIHtcbiAgICAgICAgICAgIHVuY2VydGFpbkdseXBoUGF0aCArPSBnZXRTZWdtZW50KHRyaVBvaW50TWlkLCB0dE1pZCxcbiAgICAgICAgICAgICAgICBzZXFEYXR1bS51bmNlcnRhaW5CZWdpbiwgc2VxRGF0dW0uYmVnaW4sIHRvUGFydGljaXBhbnQsIHR5T2Zmc2V0LCBmcm9tT3JpZ2luUG9pbnQpO1xuICAgICAgICAgICAgLy8gaGlnaGxpZ2h0U3RhcnRSZXMgPSBzZXFEYXR1bS51bmNlcnRhaW5CZWdpbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNOdW1iZXIoc2VxRGF0dW0udW5jZXJ0YWluRW5kKSkge1xuICAgICAgICAgICAgdW5jZXJ0YWluR2x5cGhQYXRoICs9IGdldFNlZ21lbnQodHJpUG9pbnRNaWQsIHR0TWlkLFxuICAgICAgICAgICAgICAgIHNlcURhdHVtLmVuZCwgc2VxRGF0dW0udW5jZXJ0YWluRW5kLCB0b1BhcnRpY2lwYW50LCB0eU9mZnNldCwgZnJvbU9yaWdpblBvaW50KTtcbiAgICAgICAgICAgIC8vIGhpZ2hsaWdodEVuZFJlcyA9IHNlcURhdHVtLnVuY2VydGFpbkVuZDtcbiAgICAgICAgfVxuICAgICAgICAvLyBoaWdobGlnaHRHbHlwaFBhdGggKz0gZ2V0UGF0aFNlZ21lbnRzKHRyaVBvaW50TWlkLCB0dE1pZCxcbiAgICAgICAgLy8gICAgIGhpZ2hsaWdodFN0YXJ0UmVzLCBoaWdobGlnaHRFbmRSZXMsIHRvUGFydGljaXBhbnQsIHR5T2Zmc2V0KTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuZ2x5cGgpIHtcbiAgICAgICAgdGhpcy5pbml0U1ZHKCk7XG4gICAgfVxuXG4gICAgdGhpcy5nbHlwaC5zZXRBdHRyaWJ1dGUoXCJkXCIsIGdseXBoUGF0aCk7XG4gICAgdGhpcy51bmNlcnRhaW5HbHlwaC5zZXRBdHRyaWJ1dGUoXCJkXCIsIHVuY2VydGFpbkdseXBoUGF0aCk7XG4gICAgLy8gdGhpcy5oaWdobGlnaHRHbHlwaC5zZXRBdHRyaWJ1dGUoXCJkXCIsIGhpZ2hsaWdodEdseXBoUGF0aCk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Iiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/viz/link/feature-link.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"FeatureLink\", function() { return FeatureLink; });\n/* harmony import */ var _link__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./link */ \"./src/js/viz/link/link.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n\n\n// import * as Point2D from \"point2d\";\n// import * as Intersection from \"intersectionjs\";\n\nfunction FeatureLink(id, fromFeatPos, toFeatPos, app) {\n this.init(id, fromFeatPos, toFeatPos, app);\n}\n\nFeatureLink.prototype = new _link__WEBPACK_IMPORTED_MODULE_0__[\"Link\"]();\n\nFeatureLink.prototype.init = function (id, fromFeatPos, toFeatPos, app) {\n this.id = id;\n this.app = app;\n this.fromSequenceData = fromFeatPos;\n this.toSequenceData = toFeatPos;\n\n this.participants = [this.fromSequenceData[0].participant, this.toSequenceData[0].participant]; //*\n // *potentially, this over simplifies the situation,\n // but there is a workaround in way ReadMiJson init's links so OK for now\n\n this.glyph = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"path\");\n this.uncertainGlyph = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_1__[\"svgns\"], \"path\");\n this.glyph.classList.add(\"link\", \"feature-link\", \"certain-link\");\n this.uncertainGlyph.classList.add(\"link\", \"feature-link\", \"uncertain-link\");\n\n //set the events for it\n const self = this;\n this.uncertainGlyph.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.uncertainGlyph.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.uncertainGlyph.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n this.glyph.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.glyph.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.glyph.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.highlightGlyph.onmousedown = function (evt) {\n // self.mouseDown(evt);\n // };\n // this.highlightGlyph.onmouseover = function (evt) {\n // self.mouseOver(evt);\n // };\n // this.highlightGlyph.onmouseout = function (evt) {\n // self.mouseOut(evt);\n // };\n};\n\n//andAlternatives means highlight alternative links in case of site ambiguity\n// FeatureLink.prototype.showHighlight = function (show) {\n// if (show) {\n// this.highlightGlyph.setAttribute(\"stroke-opacity\", \"1\");\n// } else {\n// this.highlightGlyph.setAttribute(\"stroke-opacity\", \"0\");\n// }\n// };\n\n//used when filter changed\nFeatureLink.prototype.check = function () {\n if (this.anyParticipantIsBar() === true) {\n this.show();\n return true;\n } else {\n this.hide();\n return false;\n }\n};\n\nFeatureLink.prototype.anyParticipantIsBar = function () {\n const ic = this.participants.length;\n for (let i = 0; i < ic; i++) {\n if (this.participants[i].form === 1) {\n return true;\n }\n }\n return false;\n};\n\nFeatureLink.prototype.show = function () {\n // //this.glyph.setAttribute(\"stroke-width\", this.util.z * xiNET.linkWidth);\n // this.uncertainGlyph.setAttribute(\"stroke-width\", this.util.z * 10);\n // this.highlightGlyph.setAttribute(\"stroke-width\", this.util.z * 10);\n this.setLinkCoordinates();\n let containingGroup = this.app.res_resLinks;\n if (this.participants[0] === this.participants[1]) {\n containingGroup = this.app.selfRes_resLinks;\n }\n // containingGroup.appendChild(this.highlightGlyph);\n containingGroup.appendChild(this.glyph);\n containingGroup.appendChild(this.uncertainGlyph);\n};\n\nFeatureLink.prototype.hide = function () {\n this.glyph.remove();\n this.uncertainGlyph.remove();\n};\n\n// update the links(polygons/lines) to fit to the protein\nFeatureLink.prototype.setLinkCoordinates = function () {\n function isNumber(thing) {\n return (!isNaN(parseFloat(thing)) && isFinite(thing));\n }\n\n function getSegment(midPoint, controlPoint, startRes, endRes, participant, yOffset, originPoint) {\n let startPoint, endPoint;\n if (!participant.form) { // tests if form = undefined or 0 //TODO: maybe change this, its confusing\n startPoint = participant.getPosition(originPoint);\n endPoint = startPoint;\n } else {\n startPoint = participant.getResidueCoordinates(startRes, yOffset);\n endPoint = participant.getResidueCoordinates(endRes, yOffset);\n }\n return \" Q\" + controlPoint[0] + \",\" + controlPoint[1] + \" \" + startPoint[0] + \",\" + startPoint[1] +\n \" L\" + endPoint[0] + \",\" + endPoint[1] +\n \" Q\" + controlPoint[0] + \",\" + controlPoint[1] + \" \" + midPoint[0] + \",\" + midPoint[1];\n }\n\n function sequenceDataMidPoint(sequenceData, participant) {\n //get the smallest start and the biggest end\n let lowestLinkedRes = null,\n highestLinkedRes = null;\n const sdCount = sequenceData.length;\n for (let s = 0; s < sdCount; s++) {\n const seqDatum = sequenceData[s];\n if (!isNaN(parseFloat(seqDatum.begin)) && isFinite(seqDatum.begin)) {\n // noinspection PointlessArithmeticExpressionJS\n const start = seqDatum.begin * 1; // the * 1 is necessary (type conversion)\n if (lowestLinkedRes === null || start < lowestLinkedRes) {\n lowestLinkedRes = start;\n }\n }\n if (!isNaN(parseFloat(seqDatum.uncertainBegin)) && isFinite(seqDatum.uncertainBegin)) {\n const uncertainBegin = seqDatum.uncertainBegin * 1;\n if (lowestLinkedRes === null || uncertainBegin < lowestLinkedRes) {\n lowestLinkedRes = uncertainBegin;\n }\n }\n if (!isNaN(parseFloat(seqDatum.end)) && isFinite(seqDatum.end)) {\n const end = seqDatum.end * 1;\n if (highestLinkedRes === null || end > highestLinkedRes) {\n highestLinkedRes = end;\n }\n }\n if (!isNaN(parseFloat(seqDatum.uncertainEnd)) && isFinite(seqDatum.uncertainEnd)) {\n const uncertainEnd = seqDatum.uncertainEnd * 1;\n if (highestLinkedRes === null || uncertainEnd > highestLinkedRes) {\n highestLinkedRes = uncertainEnd;\n }\n }\n }\n return participant.getResidueCoordinates((lowestLinkedRes + highestLinkedRes) / 2, 0);\n }\n\n const fromParticipant = this.fromSequenceData[0].participant;\n const toParticipant = this.toSequenceData[0].participant;\n //calculate mid points of from and to sequence data\n let fMid, tMid;\n\n if (fromParticipant.form) {\n fMid = sequenceDataMidPoint(this.fromSequenceData, fromParticipant);\n }\n if (toParticipant.form) {\n tMid = sequenceDataMidPoint(this.toSequenceData, toParticipant);\n }\n if (!fromParticipant.form) { // if not (undefined or 0)\n fMid = fromParticipant.getPosition(tMid);//toOriginPoint);\n }\n if (!toParticipant.form) {// if not (undefined or 0)\n tMid = toParticipant.getPosition(fMid);//fromOriginPoint);\n }\n\n const fromOriginPoint = fMid;//null;//[fromParticipant.cy, fromParticipant.cy];\n const toOriginPoint = tMid;//null;//[toParticipant.cy, toParticipant.cy];\n\n // if (!fromParticipant.form) { // if not (undefined or 0)\n // fMid = fromParticipant.getPosition();//toOriginPoint);\n // } else {\n // fMid = sequenceDataMidPoint(this.fromSequenceData, fromParticipant);\n // }\n // if (!toParticipant.form) {// if not (undefined or 0)\n // tMid = toParticipant.getPosition();//fromOriginPoint);\n // } else {\n // tMid = sequenceDataMidPoint(this.toSequenceData, toParticipant);\n // }\n\n //calculate angle from fromParticipant mid point to toParticipant mid point\n const deltaX = fMid[0] - tMid[0];\n const deltaY = fMid[1] - tMid[1];\n const angleBetweenMidPoints = Math.atan2(deltaY, deltaX);\n //todo: tidy up trig code so everything is always in radian\n let abmpDeg = angleBetweenMidPoints / (2 * Math.PI) * 360;\n if (abmpDeg < 0) {\n abmpDeg += 360;\n }\n\n //out is value we use to decide which side of bar the link glyph is drawn\n //first for 'from' participant\n let out = (abmpDeg - fromParticipant.rotation);\n if (out < 0) {\n out += 360;\n }\n let fyOffset = 10;\n if (out < 180) {\n fyOffset = -10;\n }\n let fRotRad = (fromParticipant.rotation / 360) * Math.PI * 2;\n if (out > 180) {\n fRotRad -= Math.PI;\n }\n //now for 'to' participant\n out = (abmpDeg - toParticipant.rotation);\n if (out < 0) {\n out += 360;\n }\n let tyOffset = 10;\n if (out > 180) {\n tyOffset = -10;\n }\n let tRotRad = (toParticipant.rotation / 360) * Math.PI * 2;\n if (out < 180) {\n tRotRad -= Math.PI;\n }\n\n let ftMid = [fMid[0] + (30 * Math.sin(fRotRad) * this.app.z),\n fMid[1] - (30 * Math.cos(fRotRad) * this.app.z)\n ];\n if (!fromParticipant.form) { // if not (undefined or 0)\n ftMid = fMid;\n }\n\n let ttMid = [tMid[0] + (30 * Math.sin(tRotRad) * this.app.z),\n tMid[1] - (30 * Math.cos(tRotRad) * this.app.z)\n ];\n if (!toParticipant.form) { // if not (undefined or 0)\n ttMid = tMid;\n }\n\n const triPointMid = [(ftMid[0] + ttMid[0]) / 2, (ftMid[1] + ttMid[1]) / 2];\n const fSDCount = this.fromSequenceData.length;\n const tSDCount = this.toSequenceData.length;\n let seqDatum;//, highlightStartRes, highlightEndRes;\n let glyphPath = \"M\" + triPointMid[0] + \",\" + triPointMid[1];\n let uncertainGlyphPath = \"M\" + triPointMid[0] + \",\" + triPointMid[1];\n // let highlightGlyphPath = \"M\" + triPointMid[0] + \",\" + triPointMid[1];\n for (let f = 0; f < fSDCount; f++) {\n seqDatum = this.fromSequenceData[f];\n if (isNumber(seqDatum.begin) && isNumber(seqDatum.end) || fromParticipant.type === \"complex\") {\n glyphPath += getSegment(triPointMid, ftMid, seqDatum.begin, seqDatum.end, fromParticipant, fyOffset, toOriginPoint);\n }\n // highlightStartRes = seqDatum.begin;\n // highlightEndRes = seqDatum.end;\n if (isNumber(seqDatum.uncertainBegin)) {\n uncertainGlyphPath += getSegment(triPointMid, ftMid,\n seqDatum.uncertainBegin, seqDatum.begin, fromParticipant, fyOffset, toOriginPoint);\n // highlightStartRes = seqDatum.uncertainBegin;\n }\n if (isNumber(seqDatum.uncertainEnd)) {\n uncertainGlyphPath += getSegment(triPointMid, ftMid,\n seqDatum.end, seqDatum.uncertainEnd, fromParticipant, fyOffset, toOriginPoint);\n // highlightEndRes = seqDatum.uncertainEnd;\n }\n // highlightGlyphPath += getPathSegments(triPointMid, ftMid,\n // highlightStartRes, highlightEndRes, fromParticipant, fyOffset);\n }\n for (let t = 0; t < tSDCount; t++) {\n seqDatum = this.toSequenceData[t];\n if (isNumber(seqDatum.begin) && isNumber(seqDatum.end) || toParticipant.type === \"complex\") {\n glyphPath += getSegment(triPointMid, ttMid, seqDatum.begin, seqDatum.end, toParticipant, tyOffset, fromOriginPoint);\n }\n // highlightStartRes = seqDatum.begin;\n // highlightEndRes = seqDatum.end;\n if (isNumber(seqDatum.uncertainBegin)) {\n uncertainGlyphPath += getSegment(triPointMid, ttMid,\n seqDatum.uncertainBegin, seqDatum.begin, toParticipant, tyOffset, fromOriginPoint);\n // highlightStartRes = seqDatum.uncertainBegin;\n }\n if (isNumber(seqDatum.uncertainEnd)) {\n uncertainGlyphPath += getSegment(triPointMid, ttMid,\n seqDatum.end, seqDatum.uncertainEnd, toParticipant, tyOffset, fromOriginPoint);\n // highlightEndRes = seqDatum.uncertainEnd;\n }\n // highlightGlyphPath += getPathSegments(triPointMid, ttMid,\n // highlightStartRes, highlightEndRes, toParticipant, tyOffset);\n }\n\n if (!this.glyph) {\n this.initSVG();\n }\n\n this.glyph.setAttribute(\"d\", glyphPath);\n this.uncertainGlyph.setAttribute(\"d\", uncertainGlyphPath);\n // this.highlightGlyph.setAttribute(\"d\", highlightGlyphPath);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2xpbmsvZmVhdHVyZS1saW5rLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy92aXovbGluay9mZWF0dXJlLWxpbmsuanM/MWE1MCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0xpbmt9IGZyb20gXCIuL2xpbmtcIjtcbmltcG9ydCB7c3ZnbnN9IGZyb20gXCIuLi8uLi9jb25maWdcIjtcbi8vIGltcG9ydCAqIGFzIFBvaW50MkQgZnJvbSBcInBvaW50MmRcIjtcbi8vIGltcG9ydCAqIGFzIEludGVyc2VjdGlvbiBmcm9tIFwiaW50ZXJzZWN0aW9uanNcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIEZlYXR1cmVMaW5rKGlkLCBmcm9tRmVhdFBvcywgdG9GZWF0UG9zLCBhcHApIHtcbiAgICB0aGlzLmluaXQoaWQsIGZyb21GZWF0UG9zLCB0b0ZlYXRQb3MsIGFwcCk7XG59XG5cbkZlYXR1cmVMaW5rLnByb3RvdHlwZSA9IG5ldyBMaW5rKCk7XG5cbkZlYXR1cmVMaW5rLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKGlkLCBmcm9tRmVhdFBvcywgdG9GZWF0UG9zLCBhcHApIHtcbiAgICB0aGlzLmlkID0gaWQ7XG4gICAgdGhpcy5hcHAgPSBhcHA7XG4gICAgdGhpcy5mcm9tU2VxdWVuY2VEYXRhID0gZnJvbUZlYXRQb3M7XG4gICAgdGhpcy50b1NlcXVlbmNlRGF0YSA9IHRvRmVhdFBvcztcblxuICAgIHRoaXMucGFydGljaXBhbnRzID0gW3RoaXMuZnJvbVNlcXVlbmNlRGF0YVswXS5wYXJ0aWNpcGFudCwgdGhpcy50b1NlcXVlbmNlRGF0YVswXS5wYXJ0aWNpcGFudF07IC8vKlxuICAgIC8vICpwb3RlbnRpYWxseSwgdGhpcyBvdmVyIHNpbXBsaWZpZXMgdGhlIHNpdHVhdGlvbixcbiAgICAvLyBidXQgdGhlcmUgaXMgYSB3b3JrYXJvdW5kIGluIHdheSBSZWFkTWlKc29uIGluaXQncyBsaW5rcyBzbyBPSyBmb3Igbm93XG5cbiAgICB0aGlzLmdseXBoID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInBhdGhcIik7XG4gICAgdGhpcy51bmNlcnRhaW5HbHlwaCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJwYXRoXCIpO1xuICAgIHRoaXMuZ2x5cGguY2xhc3NMaXN0LmFkZChcImxpbmtcIiwgXCJmZWF0dXJlLWxpbmtcIiwgXCJjZXJ0YWluLWxpbmtcIik7XG4gICAgdGhpcy51bmNlcnRhaW5HbHlwaC5jbGFzc0xpc3QuYWRkKFwibGlua1wiLCBcImZlYXR1cmUtbGlua1wiLCBcInVuY2VydGFpbi1saW5rXCIpO1xuXG4gICAgLy9zZXQgdGhlIGV2ZW50cyBmb3IgaXRcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICB0aGlzLnVuY2VydGFpbkdseXBoLm9ubW91c2Vkb3duID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlRG93bihldnQpO1xuICAgIH07XG4gICAgdGhpcy51bmNlcnRhaW5HbHlwaC5vbm1vdXNlb3ZlciA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5tb3VzZU92ZXIoZXZ0KTtcbiAgICB9O1xuICAgIHRoaXMudW5jZXJ0YWluR2x5cGgub25tb3VzZW91dCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5tb3VzZU91dChldnQpO1xuICAgIH07XG4gICAgdGhpcy5nbHlwaC5vbm1vdXNlZG93biA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5tb3VzZURvd24oZXZ0KTtcbiAgICB9O1xuICAgIHRoaXMuZ2x5cGgub25tb3VzZW92ZXIgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdmVyKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLmdseXBoLm9ubW91c2VvdXQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdXQoZXZ0KTtcbiAgICB9O1xuICAgIC8vIHRoaXMuaGlnaGxpZ2h0R2x5cGgub25tb3VzZWRvd24gPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgLy8gICAgIHNlbGYubW91c2VEb3duKGV2dCk7XG4gICAgLy8gfTtcbiAgICAvLyB0aGlzLmhpZ2hsaWdodEdseXBoLm9ubW91c2VvdmVyID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIC8vICAgICBzZWxmLm1vdXNlT3ZlcihldnQpO1xuICAgIC8vIH07XG4gICAgLy8gdGhpcy5oaWdobGlnaHRHbHlwaC5vbm1vdXNlb3V0ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIC8vICAgICBzZWxmLm1vdXNlT3V0KGV2dCk7XG4gICAgLy8gfTtcbn07XG5cbi8vYW5kQWx0ZXJuYXRpdmVzIG1lYW5zIGhpZ2hsaWdodCBhbHRlcm5hdGl2ZSBsaW5rcyBpbiBjYXNlIG9mIHNpdGUgYW1iaWd1aXR5XG4vLyBGZWF0dXJlTGluay5wcm90b3R5cGUuc2hvd0hpZ2hsaWdodCA9IGZ1bmN0aW9uIChzaG93KSB7XG4vLyAgICAgaWYgKHNob3cpIHtcbi8vICAgICAgICAgdGhpcy5oaWdobGlnaHRHbHlwaC5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utb3BhY2l0eVwiLCBcIjFcIik7XG4vLyAgICAgfSBlbHNlIHtcbi8vICAgICAgICAgdGhpcy5oaWdobGlnaHRHbHlwaC5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utb3BhY2l0eVwiLCBcIjBcIik7XG4vLyAgICAgfVxuLy8gfTtcblxuLy91c2VkIHdoZW4gZmlsdGVyIGNoYW5nZWRcbkZlYXR1cmVMaW5rLnByb3RvdHlwZS5jaGVjayA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5hbnlQYXJ0aWNpcGFudElzQmFyKCkgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5zaG93KCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufTtcblxuRmVhdHVyZUxpbmsucHJvdG90eXBlLmFueVBhcnRpY2lwYW50SXNCYXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgaWMgPSB0aGlzLnBhcnRpY2lwYW50cy5sZW5ndGg7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpYzsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLnBhcnRpY2lwYW50c1tpXS5mb3JtID09PSAxKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5GZWF0dXJlTGluay5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyAvL3RoaXMuZ2x5cGguc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIHRoaXMudXRpbC56ICogeGlORVQubGlua1dpZHRoKTtcbiAgICAvLyB0aGlzLnVuY2VydGFpbkdseXBoLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCB0aGlzLnV0aWwueiAqIDEwKTtcbiAgICAvLyB0aGlzLmhpZ2hsaWdodEdseXBoLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCB0aGlzLnV0aWwueiAqIDEwKTtcbiAgICB0aGlzLnNldExpbmtDb29yZGluYXRlcygpO1xuICAgIGxldCBjb250YWluaW5nR3JvdXAgPSB0aGlzLmFwcC5yZXNfcmVzTGlua3M7XG4gICAgaWYgKHRoaXMucGFydGljaXBhbnRzWzBdID09PSB0aGlzLnBhcnRpY2lwYW50c1sxXSkge1xuICAgICAgICBjb250YWluaW5nR3JvdXAgPSB0aGlzLmFwcC5zZWxmUmVzX3Jlc0xpbmtzO1xuICAgIH1cbiAgICAvLyBjb250YWluaW5nR3JvdXAuYXBwZW5kQ2hpbGQodGhpcy5oaWdobGlnaHRHbHlwaCk7XG4gICAgY29udGFpbmluZ0dyb3VwLmFwcGVuZENoaWxkKHRoaXMuZ2x5cGgpO1xuICAgIGNvbnRhaW5pbmdHcm91cC5hcHBlbmRDaGlsZCh0aGlzLnVuY2VydGFpbkdseXBoKTtcbn07XG5cbkZlYXR1cmVMaW5rLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZ2x5cGgucmVtb3ZlKCk7XG4gICAgdGhpcy51bmNlcnRhaW5HbHlwaC5yZW1vdmUoKTtcbn07XG5cbi8vIHVwZGF0ZSB0aGUgbGlua3MocG9seWdvbnMvbGluZXMpIHRvIGZpdCB0byB0aGUgcHJvdGVpblxuRmVhdHVyZUxpbmsucHJvdG90eXBlLnNldExpbmtDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBpc051bWJlcih0aGluZykge1xuICAgICAgICByZXR1cm4gKCFpc05hTihwYXJzZUZsb2F0KHRoaW5nKSkgJiYgaXNGaW5pdGUodGhpbmcpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRTZWdtZW50KG1pZFBvaW50LCBjb250cm9sUG9pbnQsIHN0YXJ0UmVzLCBlbmRSZXMsIHBhcnRpY2lwYW50LCB5T2Zmc2V0LCBvcmlnaW5Qb2ludCkge1xuICAgICAgICBsZXQgc3RhcnRQb2ludCwgZW5kUG9pbnQ7XG4gICAgICAgIGlmICghcGFydGljaXBhbnQuZm9ybSkgeyAvLyB0ZXN0cyBpZiBmb3JtID0gdW5kZWZpbmVkIG9yIDAgLy9UT0RPOiBtYXliZSBjaGFuZ2UgdGhpcywgaXRzIGNvbmZ1c2luZ1xuICAgICAgICAgICAgc3RhcnRQb2ludCA9IHBhcnRpY2lwYW50LmdldFBvc2l0aW9uKG9yaWdpblBvaW50KTtcbiAgICAgICAgICAgIGVuZFBvaW50ID0gc3RhcnRQb2ludDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0YXJ0UG9pbnQgPSBwYXJ0aWNpcGFudC5nZXRSZXNpZHVlQ29vcmRpbmF0ZXMoc3RhcnRSZXMsIHlPZmZzZXQpO1xuICAgICAgICAgICAgZW5kUG9pbnQgPSBwYXJ0aWNpcGFudC5nZXRSZXNpZHVlQ29vcmRpbmF0ZXMoZW5kUmVzLCB5T2Zmc2V0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gXCIgUVwiICsgY29udHJvbFBvaW50WzBdICsgXCIsXCIgKyBjb250cm9sUG9pbnRbMV0gKyBcIiBcIiArIHN0YXJ0UG9pbnRbMF0gKyBcIixcIiArIHN0YXJ0UG9pbnRbMV0gK1xuICAgICAgICAgICAgXCIgTFwiICsgZW5kUG9pbnRbMF0gKyBcIixcIiArIGVuZFBvaW50WzFdICtcbiAgICAgICAgICAgIFwiIFFcIiArIGNvbnRyb2xQb2ludFswXSArIFwiLFwiICsgY29udHJvbFBvaW50WzFdICsgXCIgXCIgKyBtaWRQb2ludFswXSArIFwiLFwiICsgbWlkUG9pbnRbMV07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2VxdWVuY2VEYXRhTWlkUG9pbnQoc2VxdWVuY2VEYXRhLCBwYXJ0aWNpcGFudCkge1xuICAgICAgICAvL2dldCB0aGUgc21hbGxlc3Qgc3RhcnQgYW5kIHRoZSBiaWdnZXN0IGVuZFxuICAgICAgICBsZXQgbG93ZXN0TGlua2VkUmVzID0gbnVsbCxcbiAgICAgICAgICAgIGhpZ2hlc3RMaW5rZWRSZXMgPSBudWxsO1xuICAgICAgICBjb25zdCBzZENvdW50ID0gc2VxdWVuY2VEYXRhLmxlbmd0aDtcbiAgICAgICAgZm9yIChsZXQgcyA9IDA7IHMgPCBzZENvdW50OyBzKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHNlcURhdHVtID0gc2VxdWVuY2VEYXRhW3NdO1xuICAgICAgICAgICAgaWYgKCFpc05hTihwYXJzZUZsb2F0KHNlcURhdHVtLmJlZ2luKSkgJiYgaXNGaW5pdGUoc2VxRGF0dW0uYmVnaW4pKSB7XG4gICAgICAgICAgICAgICAgLy8gbm9pbnNwZWN0aW9uIFBvaW50bGVzc0FyaXRobWV0aWNFeHByZXNzaW9uSlNcbiAgICAgICAgICAgICAgICBjb25zdCBzdGFydCA9IHNlcURhdHVtLmJlZ2luICogMTsgLy8gdGhlICogMSBpcyBuZWNlc3NhcnkgKHR5cGUgY29udmVyc2lvbilcbiAgICAgICAgICAgICAgICBpZiAobG93ZXN0TGlua2VkUmVzID09PSBudWxsIHx8IHN0YXJ0IDwgbG93ZXN0TGlua2VkUmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvd2VzdExpbmtlZFJlcyA9IHN0YXJ0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaXNOYU4ocGFyc2VGbG9hdChzZXFEYXR1bS51bmNlcnRhaW5CZWdpbikpICYmIGlzRmluaXRlKHNlcURhdHVtLnVuY2VydGFpbkJlZ2luKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHVuY2VydGFpbkJlZ2luID0gc2VxRGF0dW0udW5jZXJ0YWluQmVnaW4gKiAxO1xuICAgICAgICAgICAgICAgIGlmIChsb3dlc3RMaW5rZWRSZXMgPT09IG51bGwgfHwgdW5jZXJ0YWluQmVnaW4gPCBsb3dlc3RMaW5rZWRSZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgbG93ZXN0TGlua2VkUmVzID0gdW5jZXJ0YWluQmVnaW47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc05hTihwYXJzZUZsb2F0KHNlcURhdHVtLmVuZCkpICYmIGlzRmluaXRlKHNlcURhdHVtLmVuZCkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbmQgPSBzZXFEYXR1bS5lbmQgKiAxO1xuICAgICAgICAgICAgICAgIGlmIChoaWdoZXN0TGlua2VkUmVzID09PSBudWxsIHx8IGVuZCA+IGhpZ2hlc3RMaW5rZWRSZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgaGlnaGVzdExpbmtlZFJlcyA9IGVuZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWlzTmFOKHBhcnNlRmxvYXQoc2VxRGF0dW0udW5jZXJ0YWluRW5kKSkgJiYgaXNGaW5pdGUoc2VxRGF0dW0udW5jZXJ0YWluRW5kKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHVuY2VydGFpbkVuZCA9IHNlcURhdHVtLnVuY2VydGFpbkVuZCAqIDE7XG4gICAgICAgICAgICAgICAgaWYgKGhpZ2hlc3RMaW5rZWRSZXMgPT09IG51bGwgfHwgdW5jZXJ0YWluRW5kID4gaGlnaGVzdExpbmtlZFJlcykge1xuICAgICAgICAgICAgICAgICAgICBoaWdoZXN0TGlua2VkUmVzID0gdW5jZXJ0YWluRW5kO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcGFydGljaXBhbnQuZ2V0UmVzaWR1ZUNvb3JkaW5hdGVzKChsb3dlc3RMaW5rZWRSZXMgKyBoaWdoZXN0TGlua2VkUmVzKSAvIDIsIDApO1xuICAgIH1cblxuICAgIGNvbnN0IGZyb21QYXJ0aWNpcGFudCA9IHRoaXMuZnJvbVNlcXVlbmNlRGF0YVswXS5wYXJ0aWNpcGFudDtcbiAgICBjb25zdCB0b1BhcnRpY2lwYW50ID0gdGhpcy50b1NlcXVlbmNlRGF0YVswXS5wYXJ0aWNpcGFudDtcbiAgICAvL2NhbGN1bGF0ZSBtaWQgcG9pbnRzIG9mIGZyb20gYW5kIHRvIHNlcXVlbmNlIGRhdGFcbiAgICBsZXQgZk1pZCwgdE1pZDtcblxuICAgIGlmIChmcm9tUGFydGljaXBhbnQuZm9ybSkgIHtcbiAgICAgICAgZk1pZCA9IHNlcXVlbmNlRGF0YU1pZFBvaW50KHRoaXMuZnJvbVNlcXVlbmNlRGF0YSwgZnJvbVBhcnRpY2lwYW50KTtcbiAgICB9XG4gICAgaWYgKHRvUGFydGljaXBhbnQuZm9ybSkgIHtcbiAgICAgICAgdE1pZCA9IHNlcXVlbmNlRGF0YU1pZFBvaW50KHRoaXMudG9TZXF1ZW5jZURhdGEsIHRvUGFydGljaXBhbnQpO1xuICAgIH1cbiAgICBpZiAoIWZyb21QYXJ0aWNpcGFudC5mb3JtKSB7IC8vIGlmIG5vdCAodW5kZWZpbmVkIG9yIDApXG4gICAgICAgIGZNaWQgPSBmcm9tUGFydGljaXBhbnQuZ2V0UG9zaXRpb24odE1pZCk7Ly90b09yaWdpblBvaW50KTtcbiAgICB9XG4gICAgaWYgKCF0b1BhcnRpY2lwYW50LmZvcm0pIHsvLyBpZiBub3QgKHVuZGVmaW5lZCBvciAwKVxuICAgICAgICB0TWlkID0gdG9QYXJ0aWNpcGFudC5nZXRQb3NpdGlvbihmTWlkKTsvL2Zyb21PcmlnaW5Qb2ludCk7XG4gICAgfVxuXG4gICAgY29uc3QgZnJvbU9yaWdpblBvaW50ID0gZk1pZDsvL251bGw7Ly9bZnJvbVBhcnRpY2lwYW50LmN5LCBmcm9tUGFydGljaXBhbnQuY3ldO1xuICAgIGNvbnN0IHRvT3JpZ2luUG9pbnQgPSB0TWlkOy8vbnVsbDsvL1t0b1BhcnRpY2lwYW50LmN5LCB0b1BhcnRpY2lwYW50LmN5XTtcblxuICAgIC8vIGlmICghZnJvbVBhcnRpY2lwYW50LmZvcm0pIHsgLy8gaWYgbm90ICh1bmRlZmluZWQgb3IgMClcbiAgICAvLyAgICAgZk1pZCA9IGZyb21QYXJ0aWNpcGFudC5nZXRQb3NpdGlvbigpOy8vdG9PcmlnaW5Qb2ludCk7XG4gICAgLy8gfSBlbHNlIHtcbiAgICAvLyAgICAgZk1pZCA9IHNlcXVlbmNlRGF0YU1pZFBvaW50KHRoaXMuZnJvbVNlcXVlbmNlRGF0YSwgZnJvbVBhcnRpY2lwYW50KTtcbiAgICAvLyB9XG4gICAgLy8gaWYgKCF0b1BhcnRpY2lwYW50LmZvcm0pIHsvLyBpZiBub3QgKHVuZGVmaW5lZCBvciAwKVxuICAgIC8vICAgICB0TWlkID0gdG9QYXJ0aWNpcGFudC5nZXRQb3NpdGlvbigpOy8vZnJvbU9yaWdpblBvaW50KTtcbiAgICAvLyB9IGVsc2Uge1xuICAgIC8vICAgICB0TWlkID0gc2VxdWVuY2VEYXRhTWlkUG9pbnQodGhpcy50b1NlcXVlbmNlRGF0YSwgdG9QYXJ0aWNpcGFudCk7XG4gICAgLy8gfVxuXG4gICAgLy9jYWxjdWxhdGUgYW5nbGUgZnJvbSBmcm9tUGFydGljaXBhbnQgbWlkIHBvaW50IHRvIHRvUGFydGljaXBhbnQgbWlkIHBvaW50XG4gICAgY29uc3QgZGVsdGFYID0gZk1pZFswXSAtIHRNaWRbMF07XG4gICAgY29uc3QgZGVsdGFZID0gZk1pZFsxXSAtIHRNaWRbMV07XG4gICAgY29uc3QgYW5nbGVCZXR3ZWVuTWlkUG9pbnRzID0gTWF0aC5hdGFuMihkZWx0YVksIGRlbHRhWCk7XG4gICAgLy90b2RvOiB0aWR5IHVwIHRyaWcgY29kZSBzbyBldmVyeXRoaW5nIGlzIGFsd2F5cyBpbiByYWRpYW5cbiAgICBsZXQgYWJtcERlZyA9IGFuZ2xlQmV0d2Vlbk1pZFBvaW50cyAvICgyICogTWF0aC5QSSkgKiAzNjA7XG4gICAgaWYgKGFibXBEZWcgPCAwKSB7XG4gICAgICAgIGFibXBEZWcgKz0gMzYwO1xuICAgIH1cblxuICAgIC8vb3V0IGlzIHZhbHVlIHdlIHVzZSB0byBkZWNpZGUgd2hpY2ggc2lkZSBvZiBiYXIgdGhlIGxpbmsgZ2x5cGggaXMgZHJhd25cbiAgICAvL2ZpcnN0IGZvciAnZnJvbScgcGFydGljaXBhbnRcbiAgICBsZXQgb3V0ID0gKGFibXBEZWcgLSBmcm9tUGFydGljaXBhbnQucm90YXRpb24pO1xuICAgIGlmIChvdXQgPCAwKSB7XG4gICAgICAgIG91dCArPSAzNjA7XG4gICAgfVxuICAgIGxldCBmeU9mZnNldCA9IDEwO1xuICAgIGlmIChvdXQgPCAxODApIHtcbiAgICAgICAgZnlPZmZzZXQgPSAtMTA7XG4gICAgfVxuICAgIGxldCBmUm90UmFkID0gKGZyb21QYXJ0aWNpcGFudC5yb3RhdGlvbiAvIDM2MCkgKiBNYXRoLlBJICogMjtcbiAgICBpZiAob3V0ID4gMTgwKSB7XG4gICAgICAgIGZSb3RSYWQgLT0gTWF0aC5QSTtcbiAgICB9XG4gICAgLy9ub3cgZm9yICd0bycgcGFydGljaXBhbnRcbiAgICBvdXQgPSAoYWJtcERlZyAtIHRvUGFydGljaXBhbnQucm90YXRpb24pO1xuICAgIGlmIChvdXQgPCAwKSB7XG4gICAgICAgIG91dCArPSAzNjA7XG4gICAgfVxuICAgIGxldCB0eU9mZnNldCA9IDEwO1xuICAgIGlmIChvdXQgPiAxODApIHtcbiAgICAgICAgdHlPZmZzZXQgPSAtMTA7XG4gICAgfVxuICAgIGxldCB0Um90UmFkID0gKHRvUGFydGljaXBhbnQucm90YXRpb24gLyAzNjApICogTWF0aC5QSSAqIDI7XG4gICAgaWYgKG91dCA8IDE4MCkge1xuICAgICAgICB0Um90UmFkIC09IE1hdGguUEk7XG4gICAgfVxuXG4gICAgbGV0IGZ0TWlkID0gW2ZNaWRbMF0gKyAoMzAgKiBNYXRoLnNpbihmUm90UmFkKSAqIHRoaXMuYXBwLnopLFxuICAgICAgICBmTWlkWzFdIC0gKDMwICogTWF0aC5jb3MoZlJvdFJhZCkgKiB0aGlzLmFwcC56KVxuICAgIF07XG4gICAgaWYgKCFmcm9tUGFydGljaXBhbnQuZm9ybSkgeyAvLyBpZiBub3QgKHVuZGVmaW5lZCBvciAwKVxuICAgICAgICBmdE1pZCA9IGZNaWQ7XG4gICAgfVxuXG4gICAgbGV0IHR0TWlkID0gW3RNaWRbMF0gKyAoMzAgKiBNYXRoLnNpbih0Um90UmFkKSAqIHRoaXMuYXBwLnopLFxuICAgICAgICB0TWlkWzFdIC0gKDMwICogTWF0aC5jb3ModFJvdFJhZCkgKiB0aGlzLmFwcC56KVxuICAgIF07XG4gICAgaWYgKCF0b1BhcnRpY2lwYW50LmZvcm0pIHsgLy8gaWYgbm90ICh1bmRlZmluZWQgb3IgMClcbiAgICAgICAgdHRNaWQgPSB0TWlkO1xuICAgIH1cblxuICAgIGNvbnN0IHRyaVBvaW50TWlkID0gWyhmdE1pZFswXSArIHR0TWlkWzBdKSAvIDIsIChmdE1pZFsxXSArIHR0TWlkWzFdKSAvIDJdO1xuICAgIGNvbnN0IGZTRENvdW50ID0gdGhpcy5mcm9tU2VxdWVuY2VEYXRhLmxlbmd0aDtcbiAgICBjb25zdCB0U0RDb3VudCA9IHRoaXMudG9TZXF1ZW5jZURhdGEubGVuZ3RoO1xuICAgIGxldCBzZXFEYXR1bTsvLywgaGlnaGxpZ2h0U3RhcnRSZXMsIGhpZ2hsaWdodEVuZFJlcztcbiAgICBsZXQgZ2x5cGhQYXRoID0gXCJNXCIgKyB0cmlQb2ludE1pZFswXSArIFwiLFwiICsgdHJpUG9pbnRNaWRbMV07XG4gICAgbGV0IHVuY2VydGFpbkdseXBoUGF0aCA9IFwiTVwiICsgdHJpUG9pbnRNaWRbMF0gKyBcIixcIiArIHRyaVBvaW50TWlkWzFdO1xuICAgIC8vIGxldCBoaWdobGlnaHRHbHlwaFBhdGggPSBcIk1cIiArIHRyaVBvaW50TWlkWzBdICsgXCIsXCIgKyB0cmlQb2ludE1pZFsxXTtcbiAgICBmb3IgKGxldCBmID0gMDsgZiA8IGZTRENvdW50OyBmKyspIHtcbiAgICAgICAgc2VxRGF0dW0gPSB0aGlzLmZyb21TZXF1ZW5jZURhdGFbZl07XG4gICAgICAgIGlmIChpc051bWJlcihzZXFEYXR1bS5iZWdpbikgICYmIGlzTnVtYmVyKHNlcURhdHVtLmVuZCkgfHwgZnJvbVBhcnRpY2lwYW50LnR5cGUgPT09IFwiY29tcGxleFwiKSB7XG4gICAgICAgICAgICBnbHlwaFBhdGggKz0gZ2V0U2VnbWVudCh0cmlQb2ludE1pZCwgZnRNaWQsIHNlcURhdHVtLmJlZ2luLCBzZXFEYXR1bS5lbmQsIGZyb21QYXJ0aWNpcGFudCwgZnlPZmZzZXQsIHRvT3JpZ2luUG9pbnQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGhpZ2hsaWdodFN0YXJ0UmVzID0gc2VxRGF0dW0uYmVnaW47XG4gICAgICAgIC8vIGhpZ2hsaWdodEVuZFJlcyA9IHNlcURhdHVtLmVuZDtcbiAgICAgICAgaWYgKGlzTnVtYmVyKHNlcURhdHVtLnVuY2VydGFpbkJlZ2luKSkge1xuICAgICAgICAgICAgdW5jZXJ0YWluR2x5cGhQYXRoICs9IGdldFNlZ21lbnQodHJpUG9pbnRNaWQsIGZ0TWlkLFxuICAgICAgICAgICAgICAgIHNlcURhdHVtLnVuY2VydGFpbkJlZ2luLCBzZXFEYXR1bS5iZWdpbiwgZnJvbVBhcnRpY2lwYW50LCBmeU9mZnNldCwgdG9PcmlnaW5Qb2ludCk7XG4gICAgICAgICAgICAvLyBoaWdobGlnaHRTdGFydFJlcyA9IHNlcURhdHVtLnVuY2VydGFpbkJlZ2luO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc051bWJlcihzZXFEYXR1bS51bmNlcnRhaW5FbmQpKSB7XG4gICAgICAgICAgICB1bmNlcnRhaW5HbHlwaFBhdGggKz0gZ2V0U2VnbWVudCh0cmlQb2ludE1pZCwgZnRNaWQsXG4gICAgICAgICAgICAgICAgc2VxRGF0dW0uZW5kLCBzZXFEYXR1bS51bmNlcnRhaW5FbmQsIGZyb21QYXJ0aWNpcGFudCwgZnlPZmZzZXQsIHRvT3JpZ2luUG9pbnQpO1xuICAgICAgICAgICAgLy8gaGlnaGxpZ2h0RW5kUmVzID0gc2VxRGF0dW0udW5jZXJ0YWluRW5kO1xuICAgICAgICB9XG4gICAgICAgIC8vIGhpZ2hsaWdodEdseXBoUGF0aCArPSBnZXRQYXRoU2VnbWVudHModHJpUG9pbnRNaWQsIGZ0TWlkLFxuICAgICAgICAvLyAgICAgaGlnaGxpZ2h0U3RhcnRSZXMsIGhpZ2hsaWdodEVuZFJlcywgZnJvbVBhcnRpY2lwYW50LCBmeU9mZnNldCk7XG4gICAgfVxuICAgIGZvciAobGV0IHQgPSAwOyB0IDwgdFNEQ291bnQ7IHQrKykge1xuICAgICAgICBzZXFEYXR1bSA9IHRoaXMudG9TZXF1ZW5jZURhdGFbdF07XG4gICAgICAgIGlmIChpc051bWJlcihzZXFEYXR1bS5iZWdpbikgJiYgaXNOdW1iZXIoc2VxRGF0dW0uZW5kKSB8fCB0b1BhcnRpY2lwYW50LnR5cGUgPT09IFwiY29tcGxleFwiKSB7XG4gICAgICAgICAgICBnbHlwaFBhdGggKz0gZ2V0U2VnbWVudCh0cmlQb2ludE1pZCwgdHRNaWQsIHNlcURhdHVtLmJlZ2luLCBzZXFEYXR1bS5lbmQsIHRvUGFydGljaXBhbnQsIHR5T2Zmc2V0LCBmcm9tT3JpZ2luUG9pbnQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGhpZ2hsaWdodFN0YXJ0UmVzID0gc2VxRGF0dW0uYmVnaW47XG4gICAgICAgIC8vIGhpZ2hsaWdodEVuZFJlcyA9IHNlcURhdHVtLmVuZDtcbiAgICAgICAgaWYgKGlzTnVtYmVyKHNlcURhdHVtLnVuY2VydGFpbkJlZ2luKSkge1xuICAgICAgICAgICAgdW5jZXJ0YWluR2x5cGhQYXRoICs9IGdldFNlZ21lbnQodHJpUG9pbnRNaWQsIHR0TWlkLFxuICAgICAgICAgICAgICAgIHNlcURhdHVtLnVuY2VydGFpbkJlZ2luLCBzZXFEYXR1bS5iZWdpbiwgdG9QYXJ0aWNpcGFudCwgdHlPZmZzZXQsIGZyb21PcmlnaW5Qb2ludCk7XG4gICAgICAgICAgICAvLyBoaWdobGlnaHRTdGFydFJlcyA9IHNlcURhdHVtLnVuY2VydGFpbkJlZ2luO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc051bWJlcihzZXFEYXR1bS51bmNlcnRhaW5FbmQpKSB7XG4gICAgICAgICAgICB1bmNlcnRhaW5HbHlwaFBhdGggKz0gZ2V0U2VnbWVudCh0cmlQb2ludE1pZCwgdHRNaWQsXG4gICAgICAgICAgICAgICAgc2VxRGF0dW0uZW5kLCBzZXFEYXR1bS51bmNlcnRhaW5FbmQsIHRvUGFydGljaXBhbnQsIHR5T2Zmc2V0LCBmcm9tT3JpZ2luUG9pbnQpO1xuICAgICAgICAgICAgLy8gaGlnaGxpZ2h0RW5kUmVzID0gc2VxRGF0dW0udW5jZXJ0YWluRW5kO1xuICAgICAgICB9XG4gICAgICAgIC8vIGhpZ2hsaWdodEdseXBoUGF0aCArPSBnZXRQYXRoU2VnbWVudHModHJpUG9pbnRNaWQsIHR0TWlkLFxuICAgICAgICAvLyAgICAgaGlnaGxpZ2h0U3RhcnRSZXMsIGhpZ2hsaWdodEVuZFJlcywgdG9QYXJ0aWNpcGFudCwgdHlPZmZzZXQpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5nbHlwaCkge1xuICAgICAgICB0aGlzLmluaXRTVkcoKTtcbiAgICB9XG5cbiAgICB0aGlzLmdseXBoLnNldEF0dHJpYnV0ZShcImRcIiwgZ2x5cGhQYXRoKTtcbiAgICB0aGlzLnVuY2VydGFpbkdseXBoLnNldEF0dHJpYnV0ZShcImRcIiwgdW5jZXJ0YWluR2x5cGhQYXRoKTtcbiAgICAvLyB0aGlzLmhpZ2hsaWdodEdseXBoLnNldEF0dHJpYnV0ZShcImRcIiwgaGlnaGxpZ2h0R2x5cGhQYXRoKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/viz/link/feature-link.js\n"); /***/ }), @@ -1369,7 +1381,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Link\", function() { return Link; });\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n\nfunction Link () {}\n\nLink.prototype.highlightParticipants = function (show) {\n for (let participant of this.participants) {\n participant.showHighlight(show);\n }\n};\n\nLink.prototype.initSVG = function () {\n this.line.setAttribute(\"class\", \"link\");\n this.line.setAttribute(\"fill\", \"none\");\n this.line.setAttribute(\"stroke\", \"black\");\n this.line.setAttribute(\"stroke-width\", \"1\");\n this.line.setAttribute(\"stroke-linecap\", \"round\");\n this.highlightLine.setAttribute(\"class\", \"link\");\n this.highlightLine.setAttribute(\"fill\", \"none\");\n this.highlightLine.setAttribute(\"stroke\", _config__WEBPACK_IMPORTED_MODULE_0__[\"highlightColour\"]);\n this.highlightLine.setAttribute(\"stroke-width\", \"10\");\n this.highlightLine.setAttribute(\"stroke-linecap\", \"round\");\n this.highlightLine.setAttribute(\"stroke-opacity\", \"0\");\n //set the events for it\n const self = this;\n this.line.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.line.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.line.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.line.ontouchstart = function (evt) {\n // self.touchStart(evt);\n // };\n\n this.highlightLine.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.highlightLine.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.highlightLine.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.highlightLine.ontouchstart = function (evt) {\n // self.touchStart(evt);\n // };\n};\n// event handler for starting dragging or rotation (or flipping internal links)\nLink.prototype.mouseDown = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt); //see MouseEvents.js\n //stop layout\n this.app.d3cola.stop();\n this.app.dragElement = this;\n //store start location\n const p = this.app.getEventPoint(evt); // seems to be correct, see above\n this.app.dragStart = this.app.mouseToSVG(p.x, p.y);\n return false;\n};\n\nLink.prototype.mouseOver = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt);\n this.app.setTooltip(this.getToolTip(), this.color);\n return false;\n};\n\nLink.prototype.getToolTip = function () {\n return this.id;\n};\n\nLink.prototype.mouseOut = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt);\n this.app.hideTooltip();\n return false;\n};\n\n/*\nLink.prototype.touchStart = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt); //see MouseEvents.js\n //if a force layout exists then stop it\n if (this.app.layout !== undefined) {\n this.app.layout.stop();\n }\n this.app.dragElement = this;\n this.app.clearSelection();\n // this.setSelected(true);\n //store start location\n const p = this.app.getTouchEventPoint(evt); // seems to be correct, see above\n this.app.dragStart = this.app.mouseToSVG(p.x, p.y);\n //~ this.showData();\n return false;\n};*/\n\n//used by BinaryLink and UnaryLink\nLink.prototype.hide = function () {\n this.highlightLine.remove();\n this.line.remove();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2xpbmsvbGluay5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2xpbmsvbGluay5qcz8xMmU5Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7aGlnaGxpZ2h0Q29sb3VyfSBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XG5leHBvcnQgZnVuY3Rpb24gTGluayAoKSB7fVxuXG5MaW5rLnByb3RvdHlwZS5oaWdobGlnaHRQYXJ0aWNpcGFudHMgPSBmdW5jdGlvbiAoc2hvdykge1xuICAgIGZvciAobGV0IHBhcnRpY2lwYW50IG9mIHRoaXMucGFydGljaXBhbnRzKSB7XG4gICAgICAgIHBhcnRpY2lwYW50LnNob3dIaWdobGlnaHQoc2hvdyk7XG4gICAgfVxufTtcblxuTGluay5wcm90b3R5cGUuaW5pdFNWRyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmxpbmUuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgXCJsaW5rXCIpO1xuICAgIHRoaXMubGluZS5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwibm9uZVwiKTtcbiAgICB0aGlzLmxpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlXCIsIFwiYmxhY2tcIik7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS13aWR0aFwiLCBcIjFcIik7XG4gICAgdGhpcy5saW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZS1saW5lY2FwXCIsIFwicm91bmRcIik7XG4gICAgdGhpcy5oaWdobGlnaHRMaW5lLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsIFwibGlua1wiKTtcbiAgICB0aGlzLmhpZ2hsaWdodExpbmUuc2V0QXR0cmlidXRlKFwiZmlsbFwiLCBcIm5vbmVcIik7XG4gICAgdGhpcy5oaWdobGlnaHRMaW5lLnNldEF0dHJpYnV0ZShcInN0cm9rZVwiLCBoaWdobGlnaHRDb2xvdXIpO1xuICAgIHRoaXMuaGlnaGxpZ2h0TGluZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgXCIxMFwiKTtcbiAgICB0aGlzLmhpZ2hsaWdodExpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLWxpbmVjYXBcIiwgXCJyb3VuZFwiKTtcbiAgICB0aGlzLmhpZ2hsaWdodExpbmUuc2V0QXR0cmlidXRlKFwic3Ryb2tlLW9wYWNpdHlcIiwgXCIwXCIpO1xuICAgIC8vc2V0IHRoZSBldmVudHMgZm9yIGl0XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5saW5lLm9ubW91c2Vkb3duID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlRG93bihldnQpO1xuICAgIH07XG4gICAgdGhpcy5saW5lLm9ubW91c2VvdmVyID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlT3ZlcihldnQpO1xuICAgIH07XG4gICAgdGhpcy5saW5lLm9ubW91c2VvdXQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdXQoZXZ0KTtcbiAgICB9O1xuICAgIC8vIHRoaXMubGluZS5vbnRvdWNoc3RhcnQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgLy8gICAgIHNlbGYudG91Y2hTdGFydChldnQpO1xuICAgIC8vIH07XG5cbiAgICB0aGlzLmhpZ2hsaWdodExpbmUub25tb3VzZWRvd24gPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VEb3duKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLmhpZ2hsaWdodExpbmUub25tb3VzZW92ZXIgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdmVyKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLmhpZ2hsaWdodExpbmUub25tb3VzZW91dCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5tb3VzZU91dChldnQpO1xuICAgIH07XG4gICAgLy8gdGhpcy5oaWdobGlnaHRMaW5lLm9udG91Y2hzdGFydCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAvLyAgICAgc2VsZi50b3VjaFN0YXJ0KGV2dCk7XG4gICAgLy8gfTtcbn07XG4vLyBldmVudCBoYW5kbGVyIGZvciBzdGFydGluZyBkcmFnZ2luZyBvciByb3RhdGlvbiAob3IgZmxpcHBpbmcgaW50ZXJuYWwgbGlua3MpXG5MaW5rLnByb3RvdHlwZS5tb3VzZURvd24gPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgdGhpcy5hcHAucHJldmVudERlZmF1bHRzQW5kU3RvcFByb3BhZ2F0aW9uKGV2dCk7IC8vc2VlIE1vdXNlRXZlbnRzLmpzXG4gICAgLy9zdG9wIGxheW91dFxuICAgIHRoaXMuYXBwLmQzY29sYS5zdG9wKCk7XG4gICAgdGhpcy5hcHAuZHJhZ0VsZW1lbnQgPSB0aGlzO1xuICAgIC8vc3RvcmUgc3RhcnQgbG9jYXRpb25cbiAgICBjb25zdCBwID0gdGhpcy5hcHAuZ2V0RXZlbnRQb2ludChldnQpOyAvLyBzZWVtcyB0byBiZSBjb3JyZWN0LCBzZWUgYWJvdmVcbiAgICB0aGlzLmFwcC5kcmFnU3RhcnQgPSB0aGlzLmFwcC5tb3VzZVRvU1ZHKHAueCwgcC55KTtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5MaW5rLnByb3RvdHlwZS5tb3VzZU92ZXIgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgdGhpcy5hcHAucHJldmVudERlZmF1bHRzQW5kU3RvcFByb3BhZ2F0aW9uKGV2dCk7XG4gICAgdGhpcy5hcHAuc2V0VG9vbHRpcCh0aGlzLmdldFRvb2xUaXAoKSwgdGhpcy5jb2xvcik7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuTGluay5wcm90b3R5cGUuZ2V0VG9vbFRpcCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5pZDtcbn07XG5cbkxpbmsucHJvdG90eXBlLm1vdXNlT3V0ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIHRoaXMuYXBwLnByZXZlbnREZWZhdWx0c0FuZFN0b3BQcm9wYWdhdGlvbihldnQpO1xuICAgIHRoaXMuYXBwLmhpZGVUb29sdGlwKCk7XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcblxuLypcbkxpbmsucHJvdG90eXBlLnRvdWNoU3RhcnQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgdGhpcy5hcHAucHJldmVudERlZmF1bHRzQW5kU3RvcFByb3BhZ2F0aW9uKGV2dCk7IC8vc2VlIE1vdXNlRXZlbnRzLmpzXG4gICAgLy9pZiBhIGZvcmNlIGxheW91dCBleGlzdHMgdGhlbiBzdG9wIGl0XG4gICAgaWYgKHRoaXMuYXBwLmxheW91dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuYXBwLmxheW91dC5zdG9wKCk7XG4gICAgfVxuICAgIHRoaXMuYXBwLmRyYWdFbGVtZW50ID0gdGhpcztcbiAgICB0aGlzLmFwcC5jbGVhclNlbGVjdGlvbigpO1xuICAgIC8vICAgIHRoaXMuc2V0U2VsZWN0ZWQodHJ1ZSk7XG4gICAgLy9zdG9yZSBzdGFydCBsb2NhdGlvblxuICAgIGNvbnN0IHAgPSB0aGlzLmFwcC5nZXRUb3VjaEV2ZW50UG9pbnQoZXZ0KTsgLy8gc2VlbXMgdG8gYmUgY29ycmVjdCwgc2VlIGFib3ZlXG4gICAgdGhpcy5hcHAuZHJhZ1N0YXJ0ID0gdGhpcy5hcHAubW91c2VUb1NWRyhwLngsIHAueSk7XG4gICAgLy9+IHRoaXMuc2hvd0RhdGEoKTtcbiAgICByZXR1cm4gZmFsc2U7XG59OyovXG5cbi8vdXNlZCBieSBCaW5hcnlMaW5rIGFuZCBVbmFyeUxpbmtcbkxpbmsucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5oaWdobGlnaHRMaW5lLnJlbW92ZSgpO1xuICAgIHRoaXMubGluZS5yZW1vdmUoKTtcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTsiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./src/js/viz/link/link.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Link\", function() { return Link; });\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n\nfunction Link () {}\n\nLink.prototype.highlightParticipants = function (show) {\n for (let participant of this.participants) {\n participant.showHighlight(show);\n }\n};\n\nLink.prototype.initSVG = function () {\n this.line.classList.add(\"link\",\"link-line\");//, \"certain-link\");\n this.highlightLine.classList.add(\"link\", \"highlight\", \"link-highlight\");\n //set the events for it\n const self = this;\n this.line.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.line.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.line.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.line.ontouchstart = function (evt) {\n // self.touchStart(evt);\n // };\n\n this.highlightLine.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.highlightLine.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.highlightLine.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.highlightLine.ontouchstart = function (evt) {\n // self.touchStart(evt);\n // };\n};\n// event handler for starting dragging or rotation (or flipping internal links)\nLink.prototype.mouseDown = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt); //see MouseEvents.js\n //stop layout\n this.app.d3cola.stop();\n this.app.dragElement = this;\n //store start location\n const p = this.app.getEventPoint(evt); // seems to be correct, see above\n this.app.dragStart = this.app.mouseToSVG(p.x, p.y);\n return false;\n};\n\nLink.prototype.mouseOver = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt);\n this.app.setTooltip(this.getToolTip(), this.color);\n return false;\n};\n\nLink.prototype.getToolTip = function () {\n return this.id;\n};\n\nLink.prototype.mouseOut = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt);\n this.app.hideTooltip();\n return false;\n};\n\n/*\nLink.prototype.touchStart = function (evt) {\n this.app.preventDefaultsAndStopPropagation(evt); //see MouseEvents.js\n //if a force layout exists then stop it\n if (this.app.layout !== undefined) {\n this.app.layout.stop();\n }\n this.app.dragElement = this;\n this.app.clearSelection();\n // this.setSelected(true);\n //store start location\n const p = this.app.getTouchEventPoint(evt); // seems to be correct, see above\n this.app.dragStart = this.app.mouseToSVG(p.x, p.y);\n //~ this.showData();\n return false;\n};*/\n\n//used by BinaryLink and UnaryLink\nLink.prototype.hide = function () {\n this.highlightLine.remove();\n this.line.remove();\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2xpbmsvbGluay5qcy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL2NvbXBsZXh2aWV3ZXIvLi9zcmMvanMvdml6L2xpbmsvbGluay5qcz8xMmU5Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7aGlnaGxpZ2h0Q29sb3VyfSBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XG5leHBvcnQgZnVuY3Rpb24gTGluayAoKSB7fVxuXG5MaW5rLnByb3RvdHlwZS5oaWdobGlnaHRQYXJ0aWNpcGFudHMgPSBmdW5jdGlvbiAoc2hvdykge1xuICAgIGZvciAobGV0IHBhcnRpY2lwYW50IG9mIHRoaXMucGFydGljaXBhbnRzKSB7XG4gICAgICAgIHBhcnRpY2lwYW50LnNob3dIaWdobGlnaHQoc2hvdyk7XG4gICAgfVxufTtcblxuTGluay5wcm90b3R5cGUuaW5pdFNWRyA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmxpbmUuY2xhc3NMaXN0LmFkZChcImxpbmtcIixcImxpbmstbGluZVwiKTsvLywgXCJjZXJ0YWluLWxpbmtcIik7XG4gICAgdGhpcy5oaWdobGlnaHRMaW5lLmNsYXNzTGlzdC5hZGQoXCJsaW5rXCIsIFwiaGlnaGxpZ2h0XCIsIFwibGluay1oaWdobGlnaHRcIik7XG4gICAgLy9zZXQgdGhlIGV2ZW50cyBmb3IgaXRcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICB0aGlzLmxpbmUub25tb3VzZWRvd24gPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VEb3duKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLmxpbmUub25tb3VzZW92ZXIgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdmVyKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLmxpbmUub25tb3VzZW91dCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5tb3VzZU91dChldnQpO1xuICAgIH07XG4gICAgLy8gdGhpcy5saW5lLm9udG91Y2hzdGFydCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAvLyAgICAgc2VsZi50b3VjaFN0YXJ0KGV2dCk7XG4gICAgLy8gfTtcblxuICAgIHRoaXMuaGlnaGxpZ2h0TGluZS5vbm1vdXNlZG93biA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5tb3VzZURvd24oZXZ0KTtcbiAgICB9O1xuICAgIHRoaXMuaGlnaGxpZ2h0TGluZS5vbm1vdXNlb3ZlciA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAgICAgc2VsZi5tb3VzZU92ZXIoZXZ0KTtcbiAgICB9O1xuICAgIHRoaXMuaGlnaGxpZ2h0TGluZS5vbm1vdXNlb3V0ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlT3V0KGV2dCk7XG4gICAgfTtcbiAgICAvLyB0aGlzLmhpZ2hsaWdodExpbmUub250b3VjaHN0YXJ0ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgIC8vICAgICBzZWxmLnRvdWNoU3RhcnQoZXZ0KTtcbiAgICAvLyB9O1xufTtcbi8vIGV2ZW50IGhhbmRsZXIgZm9yIHN0YXJ0aW5nIGRyYWdnaW5nIG9yIHJvdGF0aW9uIChvciBmbGlwcGluZyBpbnRlcm5hbCBsaW5rcylcbkxpbmsucHJvdG90eXBlLm1vdXNlRG93biA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICB0aGlzLmFwcC5wcmV2ZW50RGVmYXVsdHNBbmRTdG9wUHJvcGFnYXRpb24oZXZ0KTsgLy9zZWUgTW91c2VFdmVudHMuanNcbiAgICAvL3N0b3AgbGF5b3V0XG4gICAgdGhpcy5hcHAuZDNjb2xhLnN0b3AoKTtcbiAgICB0aGlzLmFwcC5kcmFnRWxlbWVudCA9IHRoaXM7XG4gICAgLy9zdG9yZSBzdGFydCBsb2NhdGlvblxuICAgIGNvbnN0IHAgPSB0aGlzLmFwcC5nZXRFdmVudFBvaW50KGV2dCk7IC8vIHNlZW1zIHRvIGJlIGNvcnJlY3QsIHNlZSBhYm92ZVxuICAgIHRoaXMuYXBwLmRyYWdTdGFydCA9IHRoaXMuYXBwLm1vdXNlVG9TVkcocC54LCBwLnkpO1xuICAgIHJldHVybiBmYWxzZTtcbn07XG5cbkxpbmsucHJvdG90eXBlLm1vdXNlT3ZlciA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICB0aGlzLmFwcC5wcmV2ZW50RGVmYXVsdHNBbmRTdG9wUHJvcGFnYXRpb24oZXZ0KTtcbiAgICB0aGlzLmFwcC5zZXRUb29sdGlwKHRoaXMuZ2V0VG9vbFRpcCgpLCB0aGlzLmNvbG9yKTtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG5MaW5rLnByb3RvdHlwZS5nZXRUb29sVGlwID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmlkO1xufTtcblxuTGluay5wcm90b3R5cGUubW91c2VPdXQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgdGhpcy5hcHAucHJldmVudERlZmF1bHRzQW5kU3RvcFByb3BhZ2F0aW9uKGV2dCk7XG4gICAgdGhpcy5hcHAuaGlkZVRvb2x0aXAoKTtcbiAgICByZXR1cm4gZmFsc2U7XG59O1xuXG4vKlxuTGluay5wcm90b3R5cGUudG91Y2hTdGFydCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICB0aGlzLmFwcC5wcmV2ZW50RGVmYXVsdHNBbmRTdG9wUHJvcGFnYXRpb24oZXZ0KTsgLy9zZWUgTW91c2VFdmVudHMuanNcbiAgICAvL2lmIGEgZm9yY2UgbGF5b3V0IGV4aXN0cyB0aGVuIHN0b3AgaXRcbiAgICBpZiAodGhpcy5hcHAubGF5b3V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhpcy5hcHAubGF5b3V0LnN0b3AoKTtcbiAgICB9XG4gICAgdGhpcy5hcHAuZHJhZ0VsZW1lbnQgPSB0aGlzO1xuICAgIHRoaXMuYXBwLmNsZWFyU2VsZWN0aW9uKCk7XG4gICAgLy8gICAgdGhpcy5zZXRTZWxlY3RlZCh0cnVlKTtcbiAgICAvL3N0b3JlIHN0YXJ0IGxvY2F0aW9uXG4gICAgY29uc3QgcCA9IHRoaXMuYXBwLmdldFRvdWNoRXZlbnRQb2ludChldnQpOyAvLyBzZWVtcyB0byBiZSBjb3JyZWN0LCBzZWUgYWJvdmVcbiAgICB0aGlzLmFwcC5kcmFnU3RhcnQgPSB0aGlzLmFwcC5tb3VzZVRvU1ZHKHAueCwgcC55KTtcbiAgICAvL34gdGhpcy5zaG93RGF0YSgpO1xuICAgIHJldHVybiBmYWxzZTtcbn07Ki9cblxuLy91c2VkIGJ5IEJpbmFyeUxpbmsgYW5kIFVuYXJ5TGlua1xuTGluay5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmhpZ2hsaWdodExpbmUucmVtb3ZlKCk7XG4gICAgdGhpcy5saW5lLnJlbW92ZSgpO1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOyIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/js/viz/link/link.js\n"); /***/ }), @@ -1381,7 +1393,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) * /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"NaryLink\", function() { return NaryLink; });\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _link__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./link */ \"./src/js/viz/link/link.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n //used for d3.geom.hull\n\n\n\n//NaryLink.naryColors; // init'ed in clear function of util\nNaryLink.orbitNodes = 20;\nNaryLink.orbitRadius = 20;\n\nfunction NaryLink(id, app) {\n this.id = id;\n this.participants = [];\n this.sequenceLinks = new Map();\n this.binaryLinks = new Map();\n this.unaryLinks = new Map();\n this.app = app;\n // this.tooltip = this.id;\n this.initSVG();\n}\n\nNaryLink.prototype = new _link__WEBPACK_IMPORTED_MODULE_1__[\"Link\"]();\n\n/*\nNaryLink.prototype.getTotalParticipantCount = function () {\n let result = 0;\n const c = this.participants.length;\n for (let p = 0; p < c; p++) {\n const participant = this.participants[p];\n //console.log(\"! \" + typeof participant);\n if (participant.type !== \"complex\") {\n result++;\n } else {\n result += participant.naryLink.getTotalParticipantCount();\n }\n }\n return result;\n};\n*/\n\nNaryLink.prototype.initSVG = function () {\n this.path = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_2__[\"svgns\"], \"path\");\n this.color = NaryLink.naryColors(this.id);\n this.path.setAttribute(\"fill\", this.color);\n //set the events for it\n const self = this;\n this.path.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.path.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.path.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.path.ontouchstart = function (evt) {\n // self.touchStart(evt);\n // };\n};\n\nNaryLink.prototype.showHighlight = function (show) {\n this.highlightParticipants(show);\n};\n\nNaryLink.prototype.check = function () {\n this.show();\n return true;\n};\n\nNaryLink.prototype.show = function () {\n // this.path.setAttribute(\"stroke-width\", this.app.z);\n this.setLinkCoordinates();\n this.app.naryLinks.appendChild(this.path);\n};\n\nNaryLink.prototype.hide = function () {\n};\n\nNaryLink.prototype.setLinkCoordinates = function (dontPropogate) {\n // Uses d3.geom.hull to calculate a bounding path around an array of vertices\n const calculateHullPath = function (values) {\n const hullPath = d3__WEBPACK_IMPORTED_MODULE_0__[\"geom\"].hull(values);\n self.hull = hullPath; //hack?\n return \"M\" + hullPath.join(\"L\") + \"Z\";\n };\n const self = this; // TODO: - tidy hack above?\n this.mapped = this.orbitNodes(this.getMappedCoordinates());\n const hullValues = calculateHullPath(this.mapped);\n if (hullValues) {\n this.path.setAttribute(\"d\", hullValues);\n }\n if (this.complex && !dontPropogate) {\n this.complex.setAllLinkCoordinates();\n }\n};\n\nNaryLink.prototype.getMappedCoordinates = function () {\n const participants = this.participants;\n let mapped = [];\n const ic = participants.length;\n for (let i = 0; i < ic; i++) {\n const participant = participants[i];\n if (participant.type === \"complex\") {\n mapped = mapped.concat(this.orbitNodes(participant.naryLink.getMappedCoordinates()));\n } else if (participant.form === 1) {\n const start = participant.getResidueCoordinates(0);\n const end = participant.getResidueCoordinates(participant.size);\n if (!isNaN(start[0]) && !isNaN(start[1]) &&\n !isNaN(end[0]) && !isNaN(end[1])) {\n mapped.push(start);\n mapped.push(end);\n } else {\n mapped.push(participant.getPosition());\n }\n } else {\n mapped.push(participant.getPosition());\n }\n }\n return mapped;\n};\n\n//'orbit' nodes - several nodes around participant positions to give margin\nNaryLink.prototype.orbitNodes = function (mapped) {\n\n\n const orbitNodes = [];\n const mc = mapped.length;\n for (let mi = 0; mi < mc; mi++) {\n const m = mapped[mi];\n for (let o = 0; o < NaryLink.orbitNodes; o++) {\n const angle = (360 / NaryLink.orbitNodes) * o;\n const p = [m[0] + NaryLink.orbitRadius, m[1]];\n orbitNodes.push(Object(_config__WEBPACK_IMPORTED_MODULE_2__[\"rotatePointAboutPoint\"])(p, m, angle));\n }\n }\n return orbitNodes;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2xpbmsvbmFyeS1saW5rLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy92aXovbGluay9uYXJ5LWxpbmsuanM/NmYzYiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBkMyBmcm9tIFwiZDNcIjsgLy91c2VkIGZvciBkMy5nZW9tLmh1bGxcbmltcG9ydCB7TGlua30gZnJvbSBcIi4vbGlua1wiO1xuaW1wb3J0IHtzdmducywgcm90YXRlUG9pbnRBYm91dFBvaW50fSBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XG5cbi8vTmFyeUxpbmsubmFyeUNvbG9yczsgLy8gaW5pdCdlZCBpbiBjbGVhciBmdW5jdGlvbiBvZiB1dGlsXG5OYXJ5TGluay5vcmJpdE5vZGVzID0gMjA7XG5OYXJ5TGluay5vcmJpdFJhZGl1cyA9IDIwO1xuXG5leHBvcnQgZnVuY3Rpb24gTmFyeUxpbmsoaWQsIGFwcCkge1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICB0aGlzLnBhcnRpY2lwYW50cyA9IFtdO1xuICAgIHRoaXMuc2VxdWVuY2VMaW5rcyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmJpbmFyeUxpbmtzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5hcnlMaW5rcyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmFwcCA9IGFwcDtcbiAgICAvLyB0aGlzLnRvb2x0aXAgPSB0aGlzLmlkO1xuICAgIHRoaXMuaW5pdFNWRygpO1xufVxuXG5OYXJ5TGluay5wcm90b3R5cGUgPSBuZXcgTGluaygpO1xuXG4vKlxuTmFyeUxpbmsucHJvdG90eXBlLmdldFRvdGFsUGFydGljaXBhbnRDb3VudCA9IGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgcmVzdWx0ID0gMDtcbiAgICBjb25zdCBjID0gdGhpcy5wYXJ0aWNpcGFudHMubGVuZ3RoO1xuICAgIGZvciAobGV0IHAgPSAwOyBwIDwgYzsgcCsrKSB7XG4gICAgICAgIGNvbnN0IHBhcnRpY2lwYW50ID0gdGhpcy5wYXJ0aWNpcGFudHNbcF07XG4gICAgICAgIC8vY29uc29sZS5sb2coXCIhIFwiICsgdHlwZW9mIHBhcnRpY2lwYW50KTtcbiAgICAgICAgaWYgKHBhcnRpY2lwYW50LnR5cGUgIT09IFwiY29tcGxleFwiKSB7XG4gICAgICAgICAgICByZXN1bHQrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc3VsdCArPSBwYXJ0aWNpcGFudC5uYXJ5TGluay5nZXRUb3RhbFBhcnRpY2lwYW50Q291bnQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbiovXG5cbk5hcnlMaW5rLnByb3RvdHlwZS5pbml0U1ZHID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucGF0aCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJwYXRoXCIpO1xuICAgIHRoaXMuY29sb3IgPSBOYXJ5TGluay5uYXJ5Q29sb3JzKHRoaXMuaWQpO1xuICAgIHRoaXMucGF0aC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3IpO1xuICAgIC8vc2V0IHRoZSBldmVudHMgZm9yIGl0XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5wYXRoLm9ubW91c2Vkb3duID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlRG93bihldnQpO1xuICAgIH07XG4gICAgdGhpcy5wYXRoLm9ubW91c2VvdmVyID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlT3ZlcihldnQpO1xuICAgIH07XG4gICAgdGhpcy5wYXRoLm9ubW91c2VvdXQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdXQoZXZ0KTtcbiAgICB9O1xuICAgIC8vIHRoaXMucGF0aC5vbnRvdWNoc3RhcnQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgLy8gICAgIHNlbGYudG91Y2hTdGFydChldnQpO1xuICAgIC8vIH07XG59O1xuXG5OYXJ5TGluay5wcm90b3R5cGUuc2hvd0hpZ2hsaWdodCA9IGZ1bmN0aW9uIChzaG93KSB7XG4gICAgdGhpcy5oaWdobGlnaHRQYXJ0aWNpcGFudHMoc2hvdyk7XG59O1xuXG5OYXJ5TGluay5wcm90b3R5cGUuY2hlY2sgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5zaG93KCk7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuXG5OYXJ5TGluay5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICAvLyB0aGlzLnBhdGguc2V0QXR0cmlidXRlKFwic3Ryb2tlLXdpZHRoXCIsIHRoaXMuYXBwLnopO1xuICAgIHRoaXMuc2V0TGlua0Nvb3JkaW5hdGVzKCk7XG4gICAgdGhpcy5hcHAubmFyeUxpbmtzLmFwcGVuZENoaWxkKHRoaXMucGF0aCk7XG59O1xuXG5OYXJ5TGluay5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbn07XG5cbk5hcnlMaW5rLnByb3RvdHlwZS5zZXRMaW5rQ29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoZG9udFByb3BvZ2F0ZSkge1xuICAgIC8vIFVzZXMgZDMuZ2VvbS5odWxsIHRvIGNhbGN1bGF0ZSBhIGJvdW5kaW5nIHBhdGggYXJvdW5kIGFuIGFycmF5IG9mIHZlcnRpY2VzXG4gICAgY29uc3QgY2FsY3VsYXRlSHVsbFBhdGggPSBmdW5jdGlvbiAodmFsdWVzKSB7XG4gICAgICAgIGNvbnN0IGh1bGxQYXRoID0gZDMuZ2VvbS5odWxsKHZhbHVlcyk7XG4gICAgICAgIHNlbGYuaHVsbCA9IGh1bGxQYXRoOyAvL2hhY2s/XG4gICAgICAgIHJldHVybiBcIk1cIiArIGh1bGxQYXRoLmpvaW4oXCJMXCIpICsgXCJaXCI7XG4gICAgfTtcbiAgICBjb25zdCBzZWxmID0gdGhpczsgLy8gVE9ETzogLSB0aWR5IGhhY2sgYWJvdmU/XG4gICAgdGhpcy5tYXBwZWQgPSB0aGlzLm9yYml0Tm9kZXModGhpcy5nZXRNYXBwZWRDb29yZGluYXRlcygpKTtcbiAgICBjb25zdCBodWxsVmFsdWVzID0gY2FsY3VsYXRlSHVsbFBhdGgodGhpcy5tYXBwZWQpO1xuICAgIGlmIChodWxsVmFsdWVzKSB7XG4gICAgICAgIHRoaXMucGF0aC5zZXRBdHRyaWJ1dGUoXCJkXCIsIGh1bGxWYWx1ZXMpO1xuICAgIH1cbiAgICBpZiAodGhpcy5jb21wbGV4ICYmICFkb250UHJvcG9nYXRlKSB7XG4gICAgICAgIHRoaXMuY29tcGxleC5zZXRBbGxMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICB9XG59O1xuXG5OYXJ5TGluay5wcm90b3R5cGUuZ2V0TWFwcGVkQ29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgcGFydGljaXBhbnRzID0gdGhpcy5wYXJ0aWNpcGFudHM7XG4gICAgbGV0IG1hcHBlZCA9IFtdO1xuICAgIGNvbnN0IGljID0gcGFydGljaXBhbnRzLmxlbmd0aDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGljOyBpKyspIHtcbiAgICAgICAgY29uc3QgcGFydGljaXBhbnQgPSBwYXJ0aWNpcGFudHNbaV07XG4gICAgICAgIGlmIChwYXJ0aWNpcGFudC50eXBlID09PSBcImNvbXBsZXhcIikge1xuICAgICAgICAgICAgbWFwcGVkID0gbWFwcGVkLmNvbmNhdCh0aGlzLm9yYml0Tm9kZXMocGFydGljaXBhbnQubmFyeUxpbmsuZ2V0TWFwcGVkQ29vcmRpbmF0ZXMoKSkpO1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnRpY2lwYW50LmZvcm0gPT09IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gcGFydGljaXBhbnQuZ2V0UmVzaWR1ZUNvb3JkaW5hdGVzKDApO1xuICAgICAgICAgICAgY29uc3QgZW5kID0gcGFydGljaXBhbnQuZ2V0UmVzaWR1ZUNvb3JkaW5hdGVzKHBhcnRpY2lwYW50LnNpemUpO1xuICAgICAgICAgICAgaWYgKCFpc05hTihzdGFydFswXSkgJiYgIWlzTmFOKHN0YXJ0WzFdKSAmJlxuICAgICAgICAgICAgICAgICFpc05hTihlbmRbMF0pICYmICFpc05hTihlbmRbMV0pKSB7XG4gICAgICAgICAgICAgICAgbWFwcGVkLnB1c2goc3RhcnQpO1xuICAgICAgICAgICAgICAgIG1hcHBlZC5wdXNoKGVuZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1hcHBlZC5wdXNoKHBhcnRpY2lwYW50LmdldFBvc2l0aW9uKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbWFwcGVkLnB1c2gocGFydGljaXBhbnQuZ2V0UG9zaXRpb24oKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hcHBlZDtcbn07XG5cbi8vJ29yYml0JyBub2RlcyAtIHNldmVyYWwgbm9kZXMgYXJvdW5kIHBhcnRpY2lwYW50IHBvc2l0aW9ucyB0byBnaXZlIG1hcmdpblxuTmFyeUxpbmsucHJvdG90eXBlLm9yYml0Tm9kZXMgPSBmdW5jdGlvbiAobWFwcGVkKSB7XG5cblxuICAgIGNvbnN0IG9yYml0Tm9kZXMgPSBbXTtcbiAgICBjb25zdCBtYyA9IG1hcHBlZC5sZW5ndGg7XG4gICAgZm9yIChsZXQgbWkgPSAwOyBtaSA8IG1jOyBtaSsrKSB7XG4gICAgICAgIGNvbnN0IG0gPSBtYXBwZWRbbWldO1xuICAgICAgICBmb3IgKGxldCBvID0gMDsgbyA8IE5hcnlMaW5rLm9yYml0Tm9kZXM7IG8rKykge1xuICAgICAgICAgICAgY29uc3QgYW5nbGUgPSAoMzYwIC8gTmFyeUxpbmsub3JiaXROb2RlcykgKiBvO1xuICAgICAgICAgICAgY29uc3QgcCA9IFttWzBdICsgTmFyeUxpbmsub3JiaXRSYWRpdXMsIG1bMV1dO1xuICAgICAgICAgICAgb3JiaXROb2Rlcy5wdXNoKHJvdGF0ZVBvaW50QWJvdXRQb2ludChwLCBtLCBhbmdsZSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvcmJpdE5vZGVzO1xufTsiXSwibWFwcGluZ3MiOiJBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/js/viz/link/nary-link.js\n"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"NaryLink\", function() { return NaryLink; });\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! d3 */ \"./node_modules/d3/d3.js\");\n/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(d3__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _link__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./link */ \"./src/js/viz/link/link.js\");\n/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../config */ \"./src/js/config.js\");\n //used for d3.geom.hull\n\n\n\n//NaryLink.naryColors; // init'ed in clear function of util\nNaryLink.orbitNodes = 20;\nNaryLink.orbitRadius = 22;\n\nfunction NaryLink(id, app) {\n this.id = id;\n this.participants = [];\n this.sequenceLinks = new Map();\n this.binaryLinks = new Map();\n this.unaryLinks = new Map();\n this.app = app;\n // this.tooltip = this.id;\n this.initSVG();\n}\n\nNaryLink.prototype = new _link__WEBPACK_IMPORTED_MODULE_1__[\"Link\"]();\n\n/*\nNaryLink.prototype.getTotalParticipantCount = function () {\n let result = 0;\n const c = this.participants.length;\n for (let p = 0; p < c; p++) {\n const participant = this.participants[p];\n //console.log(\"! \" + typeof participant);\n if (participant.type !== \"complex\") {\n result++;\n } else {\n result += participant.naryLink.getTotalParticipantCount();\n }\n }\n return result;\n};\n*/\n\nNaryLink.prototype.initSVG = function () {\n this.path = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_2__[\"svgns\"], \"path\");\n this.color = NaryLink.naryColors(this.id);\n this.path.setAttribute(\"fill\", this.color);\n //set the events for it\n const self = this;\n this.path.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.path.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.path.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.path.ontouchstart = function (evt) {\n // self.touchStart(evt);\n // };\n // todo - prob better way todo this\n this.path2 = document.createElementNS(_config__WEBPACK_IMPORTED_MODULE_2__[\"svgns\"], \"path\");\n this.path2.setAttribute(\"fill\", \"none\");\n //set the events for it\n this.path2.onmousedown = function (evt) {\n self.mouseDown(evt);\n };\n this.path2.onmouseover = function (evt) {\n self.mouseOver(evt);\n };\n this.path2.onmouseout = function (evt) {\n self.mouseOut(evt);\n };\n // this.path2.ontouchstart = function (evt) {\n // self.touchStart(evt);\n // };\n};\n\nNaryLink.prototype.showHighlight = function (show) {\n this.highlightParticipants(show);\n};\n\nNaryLink.prototype.check = function () {\n this.show();\n return true;\n};\n\nNaryLink.prototype.show = function () {\n // this.path.setAttribute(\"stroke-width\", this.app.z);\n this.setLinkCoordinates();\n this.app.naryLinks.appendChild(this.path);\n this.app.naryLinks.appendChild(this.path2);\n};\n\nNaryLink.prototype.hide = function () {\n};\n\nNaryLink.prototype.setLinkCoordinates = function (dontPropogate) {\n // Uses d3.geom.hull to calculate a bounding path around an array of vertices\n const calculateHullPath = function (values) {\n const hullPath = d3__WEBPACK_IMPORTED_MODULE_0__[\"geom\"].hull(values);\n self.hull = hullPath; //hack?\n return \"M\" + hullPath.join(\"L\") + \"Z\";\n };\n const self = this; // TODO: - tidy hack above?\n this.mapped = this.orbitNodes(this.getMappedCoordinates());\n const hullValues = calculateHullPath(this.mapped);\n if (hullValues) {\n this.path.setAttribute(\"d\", hullValues);\n this.path2.setAttribute(\"d\", hullValues);\n }\n if (this.complex && !dontPropogate) {\n this.complex.setAllLinkCoordinates();\n }\n};\n\nNaryLink.prototype.getMappedCoordinates = function () {\n const participants = this.participants;\n let mapped = [];\n const ic = participants.length;\n for (let i = 0; i < ic; i++) {\n const participant = participants[i];\n if (participant.type === \"complex\") {\n mapped = mapped.concat(this.orbitNodes(participant.naryLink.getMappedCoordinates()));\n } else if (participant.form === 1) {\n const start = participant.getResidueCoordinates(0);\n const end = participant.getResidueCoordinates(participant.size);\n if (!isNaN(start[0]) && !isNaN(start[1]) &&\n !isNaN(end[0]) && !isNaN(end[1])) {\n mapped.push(start);\n mapped.push(end);\n } else {\n mapped.push(participant.getPosition());\n }\n } else {\n mapped.push(participant.getPosition());\n }\n }\n return mapped;\n};\n\n//'orbit' nodes - several nodes around participant positions to give margin\nNaryLink.prototype.orbitNodes = function (mapped) {\n\n\n const orbitNodes = [];\n const mc = mapped.length;\n for (let mi = 0; mi < mc; mi++) {\n const m = mapped[mi];\n for (let o = 0; o < NaryLink.orbitNodes; o++) {\n const angle = (360 / NaryLink.orbitNodes) * o;\n const p = [m[0] + NaryLink.orbitRadius, m[1]];\n orbitNodes.push(Object(_config__WEBPACK_IMPORTED_MODULE_2__[\"rotatePointAboutPoint\"])(p, m, angle));\n }\n }\n return orbitNodes;\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvanMvdml6L2xpbmsvbmFyeS1saW5rLmpzLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vY29tcGxleHZpZXdlci8uL3NyYy9qcy92aXovbGluay9uYXJ5LWxpbmsuanM/NmYzYiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBkMyBmcm9tIFwiZDNcIjsgLy91c2VkIGZvciBkMy5nZW9tLmh1bGxcbmltcG9ydCB7TGlua30gZnJvbSBcIi4vbGlua1wiO1xuaW1wb3J0IHtzdmducywgcm90YXRlUG9pbnRBYm91dFBvaW50fSBmcm9tIFwiLi4vLi4vY29uZmlnXCI7XG5cbi8vTmFyeUxpbmsubmFyeUNvbG9yczsgLy8gaW5pdCdlZCBpbiBjbGVhciBmdW5jdGlvbiBvZiB1dGlsXG5OYXJ5TGluay5vcmJpdE5vZGVzID0gMjA7XG5OYXJ5TGluay5vcmJpdFJhZGl1cyA9IDIyO1xuXG5leHBvcnQgZnVuY3Rpb24gTmFyeUxpbmsoaWQsIGFwcCkge1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICB0aGlzLnBhcnRpY2lwYW50cyA9IFtdO1xuICAgIHRoaXMuc2VxdWVuY2VMaW5rcyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmJpbmFyeUxpbmtzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMudW5hcnlMaW5rcyA9IG5ldyBNYXAoKTtcbiAgICB0aGlzLmFwcCA9IGFwcDtcbiAgICAvLyB0aGlzLnRvb2x0aXAgPSB0aGlzLmlkO1xuICAgIHRoaXMuaW5pdFNWRygpO1xufVxuXG5OYXJ5TGluay5wcm90b3R5cGUgPSBuZXcgTGluaygpO1xuXG4vKlxuTmFyeUxpbmsucHJvdG90eXBlLmdldFRvdGFsUGFydGljaXBhbnRDb3VudCA9IGZ1bmN0aW9uICgpIHtcbiAgICBsZXQgcmVzdWx0ID0gMDtcbiAgICBjb25zdCBjID0gdGhpcy5wYXJ0aWNpcGFudHMubGVuZ3RoO1xuICAgIGZvciAobGV0IHAgPSAwOyBwIDwgYzsgcCsrKSB7XG4gICAgICAgIGNvbnN0IHBhcnRpY2lwYW50ID0gdGhpcy5wYXJ0aWNpcGFudHNbcF07XG4gICAgICAgIC8vY29uc29sZS5sb2coXCIhIFwiICsgdHlwZW9mIHBhcnRpY2lwYW50KTtcbiAgICAgICAgaWYgKHBhcnRpY2lwYW50LnR5cGUgIT09IFwiY29tcGxleFwiKSB7XG4gICAgICAgICAgICByZXN1bHQrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc3VsdCArPSBwYXJ0aWNpcGFudC5uYXJ5TGluay5nZXRUb3RhbFBhcnRpY2lwYW50Q291bnQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcbiovXG5cbk5hcnlMaW5rLnByb3RvdHlwZS5pbml0U1ZHID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMucGF0aCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhzdmducywgXCJwYXRoXCIpO1xuICAgIHRoaXMuY29sb3IgPSBOYXJ5TGluay5uYXJ5Q29sb3JzKHRoaXMuaWQpO1xuICAgIHRoaXMucGF0aC5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIHRoaXMuY29sb3IpO1xuICAgIC8vc2V0IHRoZSBldmVudHMgZm9yIGl0XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5wYXRoLm9ubW91c2Vkb3duID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlRG93bihldnQpO1xuICAgIH07XG4gICAgdGhpcy5wYXRoLm9ubW91c2VvdmVyID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlT3ZlcihldnQpO1xuICAgIH07XG4gICAgdGhpcy5wYXRoLm9ubW91c2VvdXQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VPdXQoZXZ0KTtcbiAgICB9O1xuICAgIC8vIHRoaXMucGF0aC5vbnRvdWNoc3RhcnQgPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgLy8gICAgIHNlbGYudG91Y2hTdGFydChldnQpO1xuICAgIC8vIH07XG4gICAgLy8gdG9kbyAtIHByb2IgYmV0dGVyIHdheSB0b2RvIHRoaXNcbiAgICB0aGlzLnBhdGgyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKHN2Z25zLCBcInBhdGhcIik7XG4gICAgdGhpcy5wYXRoMi5zZXRBdHRyaWJ1dGUoXCJmaWxsXCIsIFwibm9uZVwiKTtcbiAgICAvL3NldCB0aGUgZXZlbnRzIGZvciBpdFxuICAgIHRoaXMucGF0aDIub25tb3VzZWRvd24gPSBmdW5jdGlvbiAoZXZ0KSB7XG4gICAgICAgIHNlbGYubW91c2VEb3duKGV2dCk7XG4gICAgfTtcbiAgICB0aGlzLnBhdGgyLm9ubW91c2VvdmVyID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlT3ZlcihldnQpO1xuICAgIH07XG4gICAgdGhpcy5wYXRoMi5vbm1vdXNlb3V0ID0gZnVuY3Rpb24gKGV2dCkge1xuICAgICAgICBzZWxmLm1vdXNlT3V0KGV2dCk7XG4gICAgfTtcbiAgICAvLyB0aGlzLnBhdGgyLm9udG91Y2hzdGFydCA9IGZ1bmN0aW9uIChldnQpIHtcbiAgICAvLyAgICAgc2VsZi50b3VjaFN0YXJ0KGV2dCk7XG4gICAgLy8gfTtcbn07XG5cbk5hcnlMaW5rLnByb3RvdHlwZS5zaG93SGlnaGxpZ2h0ID0gZnVuY3Rpb24gKHNob3cpIHtcbiAgICB0aGlzLmhpZ2hsaWdodFBhcnRpY2lwYW50cyhzaG93KTtcbn07XG5cbk5hcnlMaW5rLnByb3RvdHlwZS5jaGVjayA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLnNob3coKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5cbk5hcnlMaW5rLnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xuICAgIC8vIHRoaXMucGF0aC5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgdGhpcy5hcHAueik7XG4gICAgdGhpcy5zZXRMaW5rQ29vcmRpbmF0ZXMoKTtcbiAgICB0aGlzLmFwcC5uYXJ5TGlua3MuYXBwZW5kQ2hpbGQodGhpcy5wYXRoKTtcbiAgICB0aGlzLmFwcC5uYXJ5TGlua3MuYXBwZW5kQ2hpbGQodGhpcy5wYXRoMik7XG59O1xuXG5OYXJ5TGluay5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uICgpIHtcbn07XG5cbk5hcnlMaW5rLnByb3RvdHlwZS5zZXRMaW5rQ29vcmRpbmF0ZXMgPSBmdW5jdGlvbiAoZG9udFByb3BvZ2F0ZSkge1xuICAgIC8vIFVzZXMgZDMuZ2VvbS5odWxsIHRvIGNhbGN1bGF0ZSBhIGJvdW5kaW5nIHBhdGggYXJvdW5kIGFuIGFycmF5IG9mIHZlcnRpY2VzXG4gICAgY29uc3QgY2FsY3VsYXRlSHVsbFBhdGggPSBmdW5jdGlvbiAodmFsdWVzKSB7XG4gICAgICAgIGNvbnN0IGh1bGxQYXRoID0gZDMuZ2VvbS5odWxsKHZhbHVlcyk7XG4gICAgICAgIHNlbGYuaHVsbCA9IGh1bGxQYXRoOyAvL2hhY2s/XG4gICAgICAgIHJldHVybiBcIk1cIiArIGh1bGxQYXRoLmpvaW4oXCJMXCIpICsgXCJaXCI7XG4gICAgfTtcbiAgICBjb25zdCBzZWxmID0gdGhpczsgLy8gVE9ETzogLSB0aWR5IGhhY2sgYWJvdmU/XG4gICAgdGhpcy5tYXBwZWQgPSB0aGlzLm9yYml0Tm9kZXModGhpcy5nZXRNYXBwZWRDb29yZGluYXRlcygpKTtcbiAgICBjb25zdCBodWxsVmFsdWVzID0gY2FsY3VsYXRlSHVsbFBhdGgodGhpcy5tYXBwZWQpO1xuICAgIGlmIChodWxsVmFsdWVzKSB7XG4gICAgICAgIHRoaXMucGF0aC5zZXRBdHRyaWJ1dGUoXCJkXCIsIGh1bGxWYWx1ZXMpO1xuICAgICAgICB0aGlzLnBhdGgyLnNldEF0dHJpYnV0ZShcImRcIiwgaHVsbFZhbHVlcyk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbXBsZXggJiYgIWRvbnRQcm9wb2dhdGUpIHtcbiAgICAgICAgdGhpcy5jb21wbGV4LnNldEFsbExpbmtDb29yZGluYXRlcygpO1xuICAgIH1cbn07XG5cbk5hcnlMaW5rLnByb3RvdHlwZS5nZXRNYXBwZWRDb29yZGluYXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBwYXJ0aWNpcGFudHMgPSB0aGlzLnBhcnRpY2lwYW50cztcbiAgICBsZXQgbWFwcGVkID0gW107XG4gICAgY29uc3QgaWMgPSBwYXJ0aWNpcGFudHMubGVuZ3RoO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaWM7IGkrKykge1xuICAgICAgICBjb25zdCBwYXJ0aWNpcGFudCA9IHBhcnRpY2lwYW50c1tpXTtcbiAgICAgICAgaWYgKHBhcnRpY2lwYW50LnR5cGUgPT09IFwiY29tcGxleFwiKSB7XG4gICAgICAgICAgICBtYXBwZWQgPSBtYXBwZWQuY29uY2F0KHRoaXMub3JiaXROb2RlcyhwYXJ0aWNpcGFudC5uYXJ5TGluay5nZXRNYXBwZWRDb29yZGluYXRlcygpKSk7XG4gICAgICAgIH0gZWxzZSBpZiAocGFydGljaXBhbnQuZm9ybSA9PT0gMSkge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnQgPSBwYXJ0aWNpcGFudC5nZXRSZXNpZHVlQ29vcmRpbmF0ZXMoMCk7XG4gICAgICAgICAgICBjb25zdCBlbmQgPSBwYXJ0aWNpcGFudC5nZXRSZXNpZHVlQ29vcmRpbmF0ZXMocGFydGljaXBhbnQuc2l6ZSk7XG4gICAgICAgICAgICBpZiAoIWlzTmFOKHN0YXJ0WzBdKSAmJiAhaXNOYU4oc3RhcnRbMV0pICYmXG4gICAgICAgICAgICAgICAgIWlzTmFOKGVuZFswXSkgJiYgIWlzTmFOKGVuZFsxXSkpIHtcbiAgICAgICAgICAgICAgICBtYXBwZWQucHVzaChzdGFydCk7XG4gICAgICAgICAgICAgICAgbWFwcGVkLnB1c2goZW5kKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbWFwcGVkLnB1c2gocGFydGljaXBhbnQuZ2V0UG9zaXRpb24oKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBtYXBwZWQucHVzaChwYXJ0aWNpcGFudC5nZXRQb3NpdGlvbigpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbWFwcGVkO1xufTtcblxuLy8nb3JiaXQnIG5vZGVzIC0gc2V2ZXJhbCBub2RlcyBhcm91bmQgcGFydGljaXBhbnQgcG9zaXRpb25zIHRvIGdpdmUgbWFyZ2luXG5OYXJ5TGluay5wcm90b3R5cGUub3JiaXROb2RlcyA9IGZ1bmN0aW9uIChtYXBwZWQpIHtcblxuXG4gICAgY29uc3Qgb3JiaXROb2RlcyA9IFtdO1xuICAgIGNvbnN0IG1jID0gbWFwcGVkLmxlbmd0aDtcbiAgICBmb3IgKGxldCBtaSA9IDA7IG1pIDwgbWM7IG1pKyspIHtcbiAgICAgICAgY29uc3QgbSA9IG1hcHBlZFttaV07XG4gICAgICAgIGZvciAobGV0IG8gPSAwOyBvIDwgTmFyeUxpbmsub3JiaXROb2RlczsgbysrKSB7XG4gICAgICAgICAgICBjb25zdCBhbmdsZSA9ICgzNjAgLyBOYXJ5TGluay5vcmJpdE5vZGVzKSAqIG87XG4gICAgICAgICAgICBjb25zdCBwID0gW21bMF0gKyBOYXJ5TGluay5vcmJpdFJhZGl1cywgbVsxXV07XG4gICAgICAgICAgICBvcmJpdE5vZGVzLnB1c2gocm90YXRlUG9pbnRBYm91dFBvaW50KHAsIG0sIGFuZ2xlKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9yYml0Tm9kZXM7XG59OyJdLCJtYXBwaW5ncyI6IkFBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/js/viz/link/nary-link.js\n"); /***/ }), diff --git a/index.html b/index.html index 3674613..4c024bf 100644 --- a/index.html +++ b/index.html @@ -168,7 +168,7 @@

> 6), + 0x80 | (charcode & 0x3f)); + } else if (charcode < 0xd800 || charcode >= 0xe000) { + array.push(0xe0 | (charcode >> 12), + 0x80 | ((charcode >> 6) & 0x3f), + 0x80 | (charcode & 0x3f)); + } + // surrogate pair + else { + i++; + // UTF-16 encodes 0x10000-0x10FFFF by + // subtracting 0x10000 and splitting the + // 20 bits of 0x0-0xFFFFF into two halves + charcode = 0x10000 + (((charcode & 0x3ff) << 10) | + (binary.charCodeAt(i) & 0x3ff)); + array.push(0xf0 | (charcode >> 18), + 0x80 | ((charcode >> 12) & 0x3f), + 0x80 | ((charcode >> 6) & 0x3f), + 0x80 | (charcode & 0x3f)); + } + } + } + + return new Blob([new Uint8Array(array)], { + type: newContentType + }); + } + + var blob = dataURItoBlob(content); + + if (navigator.msSaveOrOpenBlob) { + navigator.msSaveOrOpenBlob(blob, fileName); + } else { + var a = document.createElement("a"); + a.href = window.URL.createObjectURL(blob); + // Give filename you wish to download + a.download = fileName; + a.style.display = "none"; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + window.URL.revokeObjectURL(a.href); // clear up url reference to blob so it can be g.c.'ed + } + + blob = null; } //]]> diff --git a/src/css/xinet.css b/src/css/xinet.css index 68101ca..ec88cd8 100644 --- a/src/css/xinet.css +++ b/src/css/xinet.css @@ -1,13 +1,3 @@ -.protein { - cursor: crosshair; -} - -.link { - /* - cursor: crosshair; - */ -} - /*you need this to stop horrible looking flickering of text as you drag*/ svg { -webkit-user-select: none; @@ -15,21 +5,110 @@ svg { user-select: none; } -.xlv_text { +.highlight { + stroke: #ffff99; +} + +.link { + stroke-linecap: round; + stroke: black; +} + +.certain-link { + opacity: 0.6; + stroke-opacity: 0.6; +} + +.uncertain-link { + opacity: 0.2; + stroke-opacity: 0.6; +} + +.link-line { + stroke-width: 1; +} + +.link-highlight { + stroke-width: 10; + stroke-opacity: 0; +} + +.complex-outline { + stroke: white; + stroke-linejoin: round; + stroke-width: 7; +} + +.linked-complex { + stroke: black; + stroke-linejoin: round; + stroke-width: 1; +} + +feature-link { + fill: black; +} + +.protein { + cursor: crosshair; +} + +/*todo - seperate out outline*/ +.label { + font-size: 10pt; /*font-weight: bold;*/ + + /*color: #fff;*/ + /*text-shadow: white 0px 0px 1px;*/ + -webkit-font-smoothing: antialiased; + + /*text-shadow: #fff 0px 0px 1px, #fff 0px 0px 1px, #fff 0px 0px 1px,*/ + /*#fff 0px 0px 1px, #fff 0px 0px 1px, #fff 0px 0px 1px;*/ + text-shadow: -1px -1px 0 white, 1px -1px 0 white, -1px 1px 0 white, 1px 1px 0 white; - /* -2px -1px 0 white, - 2px -1px 0 white, - -2px 1px 0 white, - 2px 1px 0 white;*/ + /*-2px -1px 0 white,*/ + /* 2px -1px 0 white,*/ + /* -2px 1px 0 white,*/ + /* 2px 1px 0 white;*/ + fill: black; + text-anchor: end; } -.proteinLabel { - font-size: 10pt; - /*font-weight: bold;*/ +.tooltip{ + text-anchor: start; +} + +.outline { + stroke: black; + stroke-width: 1; + stroke-opacity: 1; + fill: white; + fill-opacity: 1; +} + +.participant-highlight { + stroke-width: 5; + fill: none; +} + +/*for protein bar scale*/ +.tick { + stroke: black; +} + +.tick-labels { + font-size: 8pt; + text-anchor: middle; +} + +/*not working right*/ +.sequence { + font-family: 'Courier New', monospace; + font-size: 10px; + text-anchor: middle; } .custom-menu-margin { @@ -43,9 +122,6 @@ svg { overflow: hidden; border: 1px solid #CCC; white-space: nowrap; - /* - font-family: sans-serif; -*/ background: #FFF; color: #333; list-style: none; @@ -70,3 +146,16 @@ svg { display: inline; padding-left: 10px; } + +.tooltip-background { + fill-opacity: 0.75; + stroke-opacity: 1; + stroke-width: 1; +} + +.tooltip-sub-background { + fill: white; + stroke: white; + opacity: 1; + stroke-width: 1; +} \ No newline at end of file diff --git a/src/js/annotations.js b/src/js/annotations.js index d109900..de51838 100644 --- a/src/js/annotations.js +++ b/src/js/annotations.js @@ -20,7 +20,7 @@ export function fetchAnnotations(annotationChoice, /*App*/ app, callback) { let protsAnnotated = 0; const molCount = proteins.length; - if (annotationChoice === "INTERACTOR") { + if (annotationChoice === "INTERACTOR") { //todo - move this out of here if (app.proteinCount < 21) { for (let prot of proteins) { const annotation = new Annotation(prot.json.label, new SequenceDatum(null, 1 + "-" + prot.size)); @@ -33,7 +33,7 @@ export function fetchAnnotations(annotationChoice, /*App*/ app, callback) { } // app.annotationSetsShown.set("INTERACTOR", true); } else { - alert("Too many (> 20) - can't color by interactor."); + // alert("Too many (> 20) - can't color by interactor."); // people are gong to complain about why arent my interactor colours showing up } callback(); } else if (annotationChoice.toUpperCase() === "SUPERFAMILY") { diff --git a/src/js/app.js b/src/js/app.js index 0e4990a..6a4f8a6 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -6,6 +6,7 @@ import * as d3_chromatic from "d3-scale-chromatic"; import * as cola from "./cola"; import {readMijson} from "./read-mijson"; import {chooseColors, fetchAnnotations} from "./annotations"; +import {svgUtils} from "./svgexp"; // import {SymbolKey} from "./symbol-key"; import * as ColorSchemeKey from "./color-scheme-key"; @@ -131,44 +132,6 @@ export function App(/*HTMLDivElement*/networkDiv) { const svg = d3.select(this.svgElement); this.defs = svg.append("defs"); - this.createHatchedFill("checkers_uncertain", "black"); - - //markers - const data = [{ - id: 1, - name: "diamond", - path: "M 0,-7.0710768 L 0,7.0710589 L 7.0710462,0 z", - viewbox: "-15 -15 25 25", - transform: "scale(1.5) translate(-5,0)", - color: "black" - }]; - - this.defs.selectAll("marker") - .data(data) - .enter() - .append("svg:marker") - .attr("id", function (d) { - return "marker_" + d.name; - }) - .attr("markerHeight", 15) - .attr("markerWidth", 15) - .attr("markerUnits", "userSpaceOnUse") - .attr("orient", "auto") - .attr("refX", 0) - .attr("refY", 0) - .attr("viewBox", function (d) { - return d.viewbox; - }) - .append("svg:path") - .attr("d", function (d) { - return d.path; - }) - .attr("fill", function (d) { - return d.color; - }) - .attr("transform", function (d) { - return d.transform; - }); this.acknowledgement = document.createElementNS(svgns, "g"); const ackText = document.createElementNS(svgns, "text"); @@ -176,7 +139,6 @@ export function App(/*HTMLDivElement*/networkDiv) { + version + "by Rappsilber Laboratory"; this.acknowledgement.appendChild(ackText); - ackText.classList.add("xlv_text"); ackText.setAttribute("font-size", "8pt"); this.svgElement.appendChild(this.acknowledgement); @@ -215,24 +177,16 @@ export function App(/*HTMLDivElement*/networkDiv) { this.tooltip = document.createElementNS(svgns, "text"); this.tooltip.setAttribute("x", "0"); this.tooltip.setAttribute("y", "0"); - this.tooltip.setAttribute("class", "xlv_text"); const tooltipTextNode = document.createTextNode("tooltip"); + this.tooltip.classList.add("label", "tooltip"); this.tooltip.appendChild(tooltipTextNode); this.tooltip_bg = document.createElementNS(svgns, "rect"); - this.tooltip_bg.setAttribute("class", "tooltip_bg"); - - this.tooltip_bg.setAttribute("fill-opacity", "0.75"); - this.tooltip_bg.setAttribute("stroke-opacity", "1"); - this.tooltip_bg.setAttribute("stroke-width", "1"); + this.tooltip_bg.classList.add("tooltip-background"); this.tooltip_subBg = document.createElementNS(svgns, "rect"); - this.tooltip_subBg.setAttribute("fill", "white"); - this.tooltip_subBg.setAttribute("stroke", "white"); - this.tooltip_subBg.setAttribute("class", "tooltip_bg"); - this.tooltip_subBg.setAttribute("opacity", "1"); - this.tooltip_subBg.setAttribute("stroke-width", "1"); + this.tooltip_subBg.classList.add("tooltip-sub-background"); this.svgElement.appendChild(this.tooltip_subBg); this.svgElement.appendChild(this.tooltip_bg); @@ -242,28 +196,32 @@ export function App(/*HTMLDivElement*/networkDiv) { } App.prototype.createHatchedFill = function (name, color) { - const pattern = this.defs.append("pattern") - .attr("id", name) - .attr("patternUnits", "userSpaceOnUse") - .attr("x", 0) - .attr("y", 0) - .attr("width", 12) - .attr("height", 12) - .attr("patternTransform", "rotate(45)"); - - pattern.append("rect") - .attr("x", 0) - .attr("y", 2) - .attr("width", 12) - .attr("height", 4) - .attr("fill", color); - - pattern.append("rect") - .attr("x", 0) - .attr("y", 8) - .attr("width", 12) - .attr("height", 4) - .attr("fill", color); + if (!this.checkedHatchNames.has(name)) { + const pattern = this.defs.append("pattern") + .attr("id", name) + .attr("patternUnits", "userSpaceOnUse") + .attr("x", 0) + .attr("y", 0) + .attr("width", 12) + .attr("height", 12) + .attr("patternTransform", "rotate(45)"); + + pattern.append("rect") + .attr("x", 0) + .attr("y", 2) + .attr("width", 12) + .attr("height", 4) + .attr("fill", color); + + pattern.append("rect") + .attr("x", 0) + .attr("y", 8) + .attr("width", 12) + .attr("height", 4) + .attr("fill", color); + + this.checkedHatchNames.add(name); + } }; App.prototype.clear = function () { @@ -272,6 +230,8 @@ App.prototype.clear = function () { this.annotationSetsShown = new Map(); // this.annotationSetsShown.set("MI FEATURES", true); + this.checkedHatchNames = new Set(); + //lighten colors const complexColors = []; for (let c of d3_chromatic.schemePastel2) {//colorbrewer.Pastel2[8]) { @@ -318,16 +278,10 @@ App.prototype.collapseProtein = function () { App.prototype.init = function () { this.d3cola.stop(); - // let i = 0; for (let participant of this.participants.values()) { if (participant.type != "complex") { - // let pos = rotatePointAboutPoint([0, -500], [0, 0], (360 / this.participants.size * i)); - participant.setPosition(-500, -500);//pos[0], pos[1]); - // if (participant.type === "protein") { - // participant.setPositionalFeatures(); - // } + participant.setPosition(-500, -500); } - // i++; } this.updateAnnotations(); this.checkLinks(); //totally needed, not sure why tbh todo - check this out @@ -739,11 +693,6 @@ App.prototype.autoLayout = function () { } } - // if (preRun) { - // layoutObj.nodes = layoutObj.nodes.concat(prunedOut); - // } - - // self.d3cola.convergenceThreshold = 0.01; //console.log("groups", groups); delete self.d3cola._lastStress; delete self.d3cola._alpha; @@ -789,7 +738,7 @@ App.prototype.autoLayout = function () { const startTime = Date.now(); self.d3cola.symmetricDiffLinkLengths(linkLength) .on("tick", function () { - if (Date.now() - startTime > 400) {//!preRun) { + if (Date.now() - startTime > 750) {//!preRun) { const nodes = self.d3cola.nodes(); for (let node of nodes) { node.setPosition(node.x, node.y); @@ -835,10 +784,6 @@ App.prototype.autoLayout = function () { // // for (let p of layoutObj.nodes) { // // p.fixed = 1; // // } - // // let nodesExceptComplexes = Array.from(self.participants.values()); - // // allNodesExceptComplexes = allNodesExceptComplexes.filter(function (value) { - // // return value.type !== "complex"; - // // }); doLayout(allNodesExceptComplexes, false); } else { for (let node of nodes) { @@ -856,16 +801,29 @@ App.prototype.autoLayout = function () { } }; -App.prototype.getSVG = function () { //todo - update after styling of svg is moved to css - let svgXml = this.svgElement.outerHTML.replace(//i, ""); //take out white background fill - const viewBox = "viewBox=\"0 0 " + this.svgElement.parentNode.clientWidth + " " + this.svgElement.parentNode.clientHeight + "\" "; - svgXml = svgXml.replace("" + - "" + - svgXml; }; +// App.prototype.getSVG = function () { +// let svgXml = this.svgElement.outerHTML.replace(//i, ""); //take out white background fill +// const viewBox = "viewBox=\"0 0 " + this.svgElement.parentNode.clientWidth + " " + this.svgElement.parentNode.clientHeight + "\" "; +// svgXml = svgXml.replace("" + +// "" + +// svgXml; +// }; + // transform the mouse-position into a position on the svg App.prototype.mouseToSVG = function (x, y) { const p = this.svgElement.createSVGPoint(); @@ -880,29 +838,33 @@ App.prototype.readMIJSON = function (miJson, expand = true) { }; App.prototype.checkLinks = function () { - function checkAll(linkMap) { - for (let link of linkMap.values()) { - link.check(); - } + for (let link of this.allNaryLinks.values()) { + link.check(); + } + for (let link of this.allBinaryLinks.values()) { + link.check(); + } + for (let link of this.allUnaryLinks.values()) { + link.check(); + } + for (let link of this.allSequenceLinks.values()) { + link.check(); } - - checkAll(this.allNaryLinks); - checkAll(this.allBinaryLinks); - checkAll(this.allUnaryLinks); - checkAll(this.allSequenceLinks); }; App.prototype.setAllLinkCoordinates = function () { - function setAll(linkMap) { - for (let link of linkMap.values()) { - link.setLinkCoordinates(true); // true means don't propogate changes from naryLink up to complex, everythings getting refreshed anyway - } + for (let link of this.allNaryLinks.values()) { + link.setLinkCoordinates(); + } + for (let link of this.allBinaryLinks.values()) { + link.setLinkCoordinates(); + } + for (let link of this.allUnaryLinks.values()) { + link.setLinkCoordinates(); + } + for (let link of this.allSequenceLinks.values()) { + link.setLinkCoordinates(); } - - setAll(this.allNaryLinks); - setAll(this.allBinaryLinks); - setAll(this.allUnaryLinks); - setAll(this.allSequenceLinks); }; App.prototype.showTooltip = function (p) { @@ -944,6 +906,7 @@ App.prototype.setTooltip = function (text, color) { this.tooltip_bg.setAttribute("fill", "white"); this.tooltip_bg.setAttribute("stroke", "grey"); } + // todo - whats this height for? this.tooltip_bg.setAttribute("height", "28"); this.tooltip_subBg.setAttribute("height", "28"); this.tooltip_bg.setAttribute("display", "block"); @@ -1044,21 +1007,18 @@ App.prototype.expandAll = function () { //from noe App.prototype.expandAndCollapseSelection = function (moleculesSelected) { - const molecules = this.molecules.values(); - for (var m = 0; m < molecules.length; m++) { - var molecule = molecules[m]; - var molecule_id = molecule.json.identifier.id; + for (let participant of this.participants.values()) { + const molecule_id = participant.json.identifier.id; if (moleculesSelected.includes(molecule_id)) { - if (molecule.form === 0) { - molecule.setForm(1); + if (participant.form === 0) { + participant.setForm(1); } - } else if (molecule.form === 1) { - molecule.setForm(0); + } else if (participant.form === 1) { + participant.setForm(0); } } }; - // export function makeSymbolKey(targetDiv){ // new SymbolKey(targetDiv); -// } +// } \ No newline at end of file diff --git a/src/js/color-scheme-key.js b/src/js/color-scheme-key.js index 4dc7b9b..b4a0e4c 100644 --- a/src/js/color-scheme-key.js +++ b/src/js/color-scheme-key.js @@ -16,7 +16,7 @@ export function update(/*HTMLDivElement*/ div, /*App*/app) { tc1.style.backgroundColor = ccRange[i % 6]; const tc2 = tr.insertCell(); tc2.textContent = ccDomain[i]; - console.log(i + " " + ccDomain[i] + " " + ccRange[i]); + //console.log(i + " " + ccDomain[i] + " " + ccRange[i]); } div.appendChild(complexColorTable); diff --git a/src/js/config.js b/src/js/config.js index 7f5815c..1eef32c 100644 --- a/src/js/config.js +++ b/src/js/config.js @@ -1,8 +1,6 @@ export const svgns = "http://www.w3.org/2000/svg";//, // namespace for svg elements // xlinkNS: 'http://www.w3.org/1999/xlink', // namespace for xlink, for use/defs elements -export const highlightColour = "#ffff99"; //, //"#fdc086"); // todo use css - export const LABEL_Y = -5; // todo this isn't needed // selectedColour: '#ffff99', // diff --git a/src/js/svgexp.js b/src/js/svgexp.js new file mode 100644 index 0000000..8ca2827 --- /dev/null +++ b/src/js/svgexp.js @@ -0,0 +1,268 @@ +/** + * Created by cs22 on 04/12/14. + */ + +export const svgUtils = { + + capture: function (svgElems) { + return svgElems.map (function(svg) { return svgUtils.makeSVGDoc (svg); }); + }, + + getAllSVGElements: function () { + // search through all document objects, including those in iframes + var allIFrames = [].slice.apply (document.getElementsByTagName('iframe')); + var docs = [document]; + allIFrames.forEach (function (iframe) { + try { + docs.push (iframe.contentDocument || iframe.contentWindow.document); + } + catch (e) { + console.log ("Protected cross-domain IFrame", iframe); + } + }); + + var allSvgs = []; + docs.forEach (function(doc) { + var allDocSvgs = [].slice.apply (doc.getElementsByTagName('svg')); + allSvgs.push.apply (allSvgs, allDocSvgs); + }); + return allSvgs; + }, + + + makeSVGDoc: function (svgElem) { + // clone node + var cloneSVG = svgElem.cloneNode (true); + var ownerDoc = cloneSVG.ownerDocument || document; + svgUtils.pruneInvisibleSubtrees (cloneSVG, svgElem); + + // find all styles inherited/referenced at or below this node + var styles = svgUtils.usedStyles (svgElem, true, true); + + // collect relevant info on parent chain of svg node + var predecessorInfo = svgUtils.parentChain (svgElem, styles); + + var addDummy = function (dummySVGElem, cloneSVG, origSVG, transferAttr) { + dummySVGElem.appendChild (cloneSVG); + Object.keys(transferAttr).forEach (function (attr) { + var val = cloneSVG.getAttribute (attr) || cloneSVG.style [attr] || svgUtils.getComputedStyleCssText (origSVG, attr); + if (val != null) { + dummySVGElem.setAttribute (attr, val); + var attrVal = transferAttr[attr]; + if (attrVal.replace) { + cloneSVG.setAttribute (attr, attrVal.replace); + } else if (attrVal.delete) { + cloneSVG.removeAttribute (attr); + } + } + }); + }; + + // make a chain of dummy svg nodes to include classes / ids of parent chain of our original svg + // this means any styles referenced within the svg that depend on the presence of these classes/ids are fired + var transferAttr = {width: {replace: "100%"}, height: {replace: "100%"}, xmlns: {delete: true}}; + var parentAdded = false; + for (var p = 0; p < predecessorInfo.length; p++) { + var pinf = predecessorInfo [p]; + //var dummySVGElem = ownerDoc.createElement ("svg"); + var dummySVGElem = ownerDoc.createElementNS ("http://www.w3.org/2000/svg", "svg"); + var empty = true; + Object.keys(pinf).forEach (function (key) { + if (pinf[key]) { + dummySVGElem.setAttribute (key, pinf[key]); + empty = false; + } + }); + // If the dummy svg has no relevant id, classes or computed style then ignore it, otherwise make it the new root + if (!empty) { + addDummy (dummySVGElem, cloneSVG, svgElem, transferAttr); + cloneSVG = dummySVGElem; + parentAdded = true; + } + } + + // if no dummy parent added in previous section, but our svg isn't root then add one as placeholder + if (svgElem.parentNode != null && !parentAdded) { + var dummySVGElem = ownerDoc.createElementNS ("http://www.w3.org/2000/svg", "svg"); + addDummy (dummySVGElem, cloneSVG, svgElem, transferAttr); + cloneSVG = dummySVGElem; + parentAdded = true; + } + + // Copy svg's computed style (it's style context) if a dummy parent node has been introduced + if (parentAdded) { + cloneSVG.setAttribute ("style", svgUtils.getComputedStyleCssText (svgElem)); + } + + cloneSVG.setAttribute ("version", "1.1"); + //cloneSVG.setAttribute ("xmlns", "http://www.w3.org/2000/svg"); // XMLSerializer does this + //cloneSVG.setAttribute ("xmlns:xlink", "http://www.w3.org/1999/xlink"); // when I used setAttributeNS it ballsed up + // however using these attributeNS calls work, and stops errors in IE11. Win. + cloneSVG.setAttributeNS ("http://www.w3.org/2000/xmlns/", "xmlns", "http://www.w3.org/2000/svg"); // XMLSerializer does this + cloneSVG.setAttributeNS ("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); // when I used setAttributeNS it ballsed up + + + var styleElem = ownerDoc.createElement ("style"); + styleElem.setAttribute ("type", "text/css"); + var styleText = ownerDoc.createTextNode (styles.join("\n")); + styleElem.appendChild (styleText); + cloneSVG.insertBefore (styleElem, cloneSVG.firstChild); + + return cloneSVG; + }, + + // Because firefox returns cssText as empty + // https://bugzilla.mozilla.org/show_bug.cgi?id=137687 + getComputedStyleCssText: function (element, field) { + var style = window.getComputedStyle(element); + if (field) { + return style[field]; + } + + if (style.cssText != "") { + return style.cssText; + } + + var cssText = ""; + for (var i = 0; i < style.length; i++) { + var styleName = style[i]; + var propVal = style.getPropertyValue(styleName); + cssText += styleName + ": " + propVal + "; "; + } + + return cssText; + }, + + doPruneInvisible: true, + + pruneConditionSets: [{"display": "none"}, {"visibility": "hidden"}, {"opacity": "0"}, {"fill-opacity": "0", "stroke-opacity": "0"}, {"fill-opacity": "0", "stroke": "none"}, {"fill": "none", "stroke-opacity": "0"}], + + pruneInvisibleSubtrees: function (clonedElement, matchingOriginalElement) { + if (svgUtils.doPruneInvisible) { + var style = window.getComputedStyle (matchingOriginalElement); // cloned (unattached) nodes in chrome at least don't have computed styles + var prune = false; + + svgUtils.pruneConditionSets.forEach (function (conditionSet) { + if (!prune) { + var allConditionsMet = true; + Object.keys(conditionSet).forEach (function (condition) { + var condVal = conditionSet[condition]; + var eStyle = style[condition]; + var eAttr = matchingOriginalElement.getAttribute(condition); + if (!(eStyle === condVal || (!eStyle && eAttr === condVal))) { + allConditionsMet = false; + } + }); + prune = allConditionsMet; + } + }); + if (prune && clonedElement.parentNode) { + clonedElement.parentNode.removeChild (clonedElement); + //console.log ("removed", clonedElement); + } else { + var clonedChildren = clonedElement.children; + var matchingOriginalChildren = matchingOriginalElement.children; + //console.log ("kept", clonedElement, style.display, style.visibility, style.opacity, style["stroke-opacity"], style["fill-opacity"], style); + //console.log (element, "children", children); + if (clonedChildren && clonedChildren.length) { + // count backwards because removing a child will break the 'i' counter if we go forwards + // e.g. if children=[A,B,C,D] and i=2, if we delete[C] then children becomes [A,B,D], + // and when i then increments to 3, expecting D, instead we find the end of loop, and don't test D + // PS. And if we fixed that we'd then need a separate counter for the original child elements anyways so backwards it is + for (var i = clonedChildren.length; --i >= 0;) { + svgUtils.pruneInvisibleSubtrees (clonedChildren[i], matchingOriginalChildren[i]); + } + } + } + } + }, + + parentChain: function (elem, styles) { + // Capture id / classes of svg's parent chain. + var ownerDoc = elem.ownerDocument || document; + var elemArr = []; + while (elem.parentNode !== ownerDoc && elem.parentNode !== null) { + elem = elem.parentNode; + elemArr.push ({id: elem.id, class: elem.getAttribute("class") || ""}); + } + + // see if id or element class are referenced in any styles collected below the svg node + // if not, null the id / class as they're not going to be relevant + elemArr.forEach (function (elemData) { + var presences = {id: false, class: false}; + var classes = elemData.class.split(" ").filter(function(a) { return a.length > 0; }); // v1.13: may be multiple classes in a containing class attribute + styles.forEach (function (style) { + for (var c = 0; c < classes.length; c++) { + if (style.indexOf ("."+classes[c]) >= 0) { + presences.class = true; + break; // no need to keep looking through rest of classtypes if one is needed + } + } + if (elemData.id && style.indexOf ("#"+elemData.id) >= 0) { + presences.id = true; + } + }); + Object.keys(presences).forEach (function (presence) { + if (!presences[presence]) { elemData[presence] = undefined; } + }); + }); + + return elemArr; + }, + + // code adapted from user adardesign's answer in http://stackoverflow.com/questions/13204785/is-it-possible-to-read-the-styles-of-css-classes-not-being-used-in-the-dom-using + usedStyles: function (elem, subtree, both) { + var needed = [], rule; + var ownerDoc = elem.ownerDocument || document; + var CSSSheets = ownerDoc.styleSheets; + + for(var j=0; j < CSSSheets.length; j++){ + // stop accessing empty style sheets (1.15), catch security exceptions (1.20) + try{ + if (CSSSheets[j].cssRules == null) { + continue; + } + } catch (err) { + continue; + } + + for(var i=0; i < CSSSheets[j].cssRules.length; i++){ + rule = CSSSheets[j].cssRules[i]; + var match = false; + // Issue reported, css rule '[ng:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak, .ng-hide:not(.ng-hide-animate)' gives error + // It's the [ng:cloak] bit that does the damage + // Fix found from https://github.com/exupero/saveSvgAsPng/issues/11 - but the css rule isn't applied + try { + if (subtree) { + match = elem.querySelectorAll(rule.selectorText).length > 0; + } + if (!subtree || both) { + match |= elem.matches(rule.selectorText); + } + } + catch (err) { + console.warn ("CSS selector error: "+rule.selectorText+". Often angular issue.", err); + } + if (match) { needed.push (rule.cssText); } + } + } + + return needed; + }, + + makeXMLStr: function (xmls, svgDoc) { + var xmlStr = xmls.serializeToString(svgDoc); + // serializing adds an xmlns attribute to the style element ('cos it thinks we want xhtml), which knackers it for inkscape, here we chop it out + xmlStr = xmlStr.split("xmlns=\"http://www.w3.org/1999/xhtml\"").join(""); + return xmlStr; + }, + + // saveSVGDocs: function (svgDocs) { + // var xmls = new XMLSerializer(); + // svgDocs.forEach (function (svgDoc, i) { + // var xmlStr = svgUtils.makeXMLStr (xmls, svgDoc); + // var blob = new Blob([xmlStr], {type: "image/svg+xml"}); + // saveAs(blob, "saved"+i+".svg"); + // }); + // }, +}; \ No newline at end of file diff --git a/src/js/viz/interactor/annotation.js b/src/js/viz/interactor/annotation.js index 90f8413..05cd5d3 100644 --- a/src/js/viz/interactor/annotation.js +++ b/src/js/viz/interactor/annotation.js @@ -1,6 +1,6 @@ //constructor for annotations export function Annotation(annotationName, seqDatum) { - console.log("**", annotationName, seqDatum); + // console.log("**", annotationName, seqDatum); this.description = annotationName.trim(); this.seqDatum = seqDatum; } diff --git a/src/js/viz/interactor/complex.js b/src/js/viz/interactor/complex.js index 387895b..72f875f 100644 --- a/src/js/viz/interactor/complex.js +++ b/src/js/viz/interactor/complex.js @@ -5,7 +5,7 @@ import * as Intersection from "intersectionjs"; export function Complex(id, app) { this.init(id, app); this.type = "complex"; - this.padding = 20; + this.padding = 22; // const self = this; // // its bad if you end up with these getting called @@ -25,22 +25,17 @@ export function Complex(id, app) { Complex.prototype = new Interactor(); -// Complex.prototype = { -// get width() { -// return this.naryLink.path.getBBox().width; -// }, -// get height() { -// return this.naryLink.path.getBBox().height; -// }, -// }; - Complex.prototype.initLink = function (naryLink) { this.naryLink = naryLink; - naryLink.path.setAttribute("stroke", "white"); - naryLink.path.setAttribute("stroke-linejoin", "round"); - naryLink.path.setAttribute("stroke-width", 4); + this.naryLink.path.classList.add("complex-outline"); }; +Complex.prototype.setLinked = function () { + + this.naryLink.path2.classList.add("linked-complex"); +}; + + Complex.prototype.getPosition = function (originPoint) { const mapped = this.naryLink.mapped;//getMappedCoordinates(); const mc = mapped.length; @@ -65,6 +60,7 @@ Complex.prototype.getPosition = function (originPoint) { if (intersect.points[0]) { return [intersect.points[0].x, intersect.points[0].y]; } + this.setLinked(); } return center; }; diff --git a/src/js/viz/interactor/interactor.js b/src/js/viz/interactor/interactor.js index df81e64..81aa5af 100644 --- a/src/js/viz/interactor/interactor.js +++ b/src/js/viz/interactor/interactor.js @@ -19,9 +19,10 @@ Interactor.prototype.init = function (id, app, json, name){ this.json = json; this.name = name; - //annotations indexed by annotation set name ("MI FEATURES", "SUPERFAMILY", etc) - this.annotationSets = new Map(); + //todo - think 'type' should be a property here (except for complex, can just return json.type.name) + //annotations indexed by annotation set name ("MIFEATURES", "SUPERFAMILY", etc) + this.annotationSets = new Map(); //links this.naryLinks = new Map(); this.binaryLinks = new Map(); @@ -29,16 +30,10 @@ Interactor.prototype.init = function (id, app, json, name){ }; Interactor.prototype.initLabel = function (){ - this.labelSVG = document.createElementNS(svgns, "text"); - this.labelSVG.setAttribute("text-anchor", "end"); - this.labelSVG.setAttribute("fill", "black"); - this.labelSVG.setAttribute("x", "0"); + this.labelSVG.setAttribute("x", "0"); // css? this.labelSVG.setAttribute("y", "10"); - this.labelSVG.setAttribute("class", "xlv_text proteinLabel"); - this.labelSVG.setAttribute("font-family", "Arial"); - this.labelSVG.setAttribute("font-size", "16"); - + this.labelSVG.classList.add("label"); //choose label text if (this.name) { this.labelText = this.name; @@ -48,7 +43,6 @@ Interactor.prototype.initLabel = function (){ if (this.labelText.length > 25) { this.labelText = this.labelText.substr(0, 16) + "..."; } - this.labelText = this.name; this.labelTextNode = document.createTextNode(this.labelText); this.labelSVG.appendChild(this.labelTextNode); @@ -58,12 +52,7 @@ Interactor.prototype.initLabel = function (){ }; Interactor.prototype.initOutline = function (){ - this.outline.setAttribute("stroke", "black"); - this.outline.setAttribute("stroke-width", "1"); - this.outline.setAttribute("stroke-opacity", "1"); - this.outline.setAttribute("fill-opacity", "1"); - this.outline.setAttribute("fill", "#ffffff"); - //append outline + this.outline.classList.add("outline"); this.upperGroup.appendChild(this.outline); }; @@ -227,6 +216,3 @@ export function trig (radius, angleDegrees) { y: (radius * Math.sin(radians)) }; } -// -// Interactor.prototype.setForm = function () { -// }; diff --git a/src/js/viz/interactor/molecule-set.js b/src/js/viz/interactor/molecule-set.js index d20068c..0c70a59 100644 --- a/src/js/viz/interactor/molecule-set.js +++ b/src/js/viz/interactor/molecule-set.js @@ -12,6 +12,7 @@ export function MoleculeSet(id, app, json, name) { this.outline.setAttribute("height", "20"); this.outline.setAttribute("rx", "5"); this.outline.setAttribute("ry", "5"); + //todo - css... (initOutline hasn't been called so it doesn't have outlin in its classList) this.outline.setAttribute("stroke", "black"); this.outline.setAttribute("stroke-width", "4"); this.outline.setAttribute("stroke-opacity", "1"); diff --git a/src/js/viz/interactor/polymer.js b/src/js/viz/interactor/polymer.js index 0e5486f..5ef3247 100644 --- a/src/js/viz/interactor/polymer.js +++ b/src/js/viz/interactor/polymer.js @@ -141,9 +141,8 @@ Polymer.prototype.setScaleGroup = function () { const seqLabelGroup = document.createElementNS(svgns, "g"); seqLabelGroup.setAttribute("transform", "translate(" + this.getResXwithStickZoom(res) + " " + 0 + ")"); const seqLabel = document.createElementNS(svgns, "text"); - seqLabel.setAttribute("font-family", "'Courier New', monospace"); - seqLabel.setAttribute("font-size", "10px"); - seqLabel.setAttribute("text-anchor", "middle"); + seqLabel.classList.add("label", "sequence"); + //css? seqLabel.setAttribute("x", "0"); seqLabel.setAttribute("y", "3"); seqLabel.appendChild(document.createTextNode(this.sequence[res - 1])); @@ -161,10 +160,7 @@ Polymer.prototype.setScaleGroup = function () { const scaleLabelGroup = document.createElementNS(svgns, "g"); scaleLabelGroup.setAttribute("transform", "translate(" + tickX + " " + 0 + ")"); const scaleLabel = document.createElementNS(svgns, "text"); - scaleLabel.setAttribute("class", "xlv_text"); - // scaleLabel.setAttribute("font-family", "'Courier New', monospace"); - scaleLabel.setAttribute("font-size", "8pt"); // todo css... - scaleLabel.setAttribute("text-anchor", "middle"); + scaleLabel.classList.add("label", "scale-label"); scaleLabel.setAttribute("x", "0"); scaleLabel.setAttribute("y", Polymer.STICKHEIGHT + 4); scaleLabel.appendChild(document.createTextNode(text)); @@ -175,11 +171,11 @@ Polymer.prototype.setScaleGroup = function () { function tickAt(self, tickX) { const tick = document.createElementNS(svgns, "line"); + tick.classList.add("tick"); tick.setAttribute("x1", tickX); tick.setAttribute("y1", "5"); tick.setAttribute("x2", tickX); tick.setAttribute("y2", "10"); - tick.setAttribute("stroke", "black"); self.ticks.appendChild(tick); } }; @@ -712,7 +708,7 @@ Polymer.prototype.getAnnotationPieSliceArcPath = function (startRes, endRes, ann const path = "M" + p1[0] + "," + p1[1] + " L" + p2[0] + "," + p2[1] + " A" + top + "," + top + " 0 " + largeArch + " 1 " + p3[0] + "," + p3[1] + " L" + p4[0] + "," + p4[1] + " A" + bottom + "," + bottom + " 0 " + largeArch + " 0 " + p1[0] + "," + p1[1] + " Z"; - console.log("**", path); + // console.log("**", path); return path; // return "M0,0 L" + arcStart.x + "," + arcStart.y + " A" + radius + "," + // radius + " 0 " + largeArch + " 1 " + arcEnd.x + "," + arcEnd.y + " Z"; diff --git a/src/js/viz/interactor/protein.js b/src/js/viz/interactor/protein.js index fafff5b..d12566f 100644 --- a/src/js/viz/interactor/protein.js +++ b/src/js/viz/interactor/protein.js @@ -1,5 +1,5 @@ import {Polymer} from "./polymer"; -import {svgns, highlightColour} from "../../config"; +import {svgns} from "../../config"; export function Protein(id, /*App*/ app, json, name) { this.init(id, app, json, name); @@ -12,9 +12,7 @@ export function Protein(id, /*App*/ app, json, name) { //make highlight this.highlight = document.createElementNS(svgns, "rect"); - this.highlight.setAttribute("stroke", highlightColour); - this.highlight.setAttribute("stroke-width", "5"); - this.highlight.setAttribute("fill", "none"); + this.highlight.classList.add("highlight", "participant-highlight"); this.upperGroup.appendChild(this.highlight); //make background @@ -33,6 +31,7 @@ export function Protein(id, /*App*/ app, json, name) { //make outline this.outline = document.createElementNS(svgns, "rect"); + // css... this.outline.setAttribute("stroke", "black"); this.outline.setAttribute("stroke-width", "1"); this.outline.setAttribute("fill", "none"); diff --git a/src/js/viz/link/feature-link.js b/src/js/viz/link/feature-link.js index 4a24f3b..f9ff631 100644 --- a/src/js/viz/link/feature-link.js +++ b/src/js/viz/link/feature-link.js @@ -21,26 +21,8 @@ FeatureLink.prototype.init = function (id, fromFeatPos, toFeatPos, app) { this.glyph = document.createElementNS(svgns, "path"); this.uncertainGlyph = document.createElementNS(svgns, "path"); - // this.highlightGlyph = document.createElementNS(svgns, "path"); - this.glyph.setAttribute("stroke-linecap", "round"); - this.uncertainGlyph.setAttribute("stroke-linecap", "round"); - // this.highlightGlyph.setAttribute("stroke-linecap", "round"); - this.glyph.setAttribute("class", "link"); - this.glyph.setAttribute("fill", "black");//"#E08214"); - this.glyph.setAttribute("opacity", "0.6"); - this.glyph.setAttribute("stroke", "black");//""#A08214");// // TODO: will look better with this line partly removed - this.glyph.setAttribute("stroke-opacity", "0.6"); - this.glyph.setAttribute("stroke-width", "1"); - this.uncertainGlyph.setAttribute("class", "link"); - this.uncertainGlyph.setAttribute("fill", "black");//url('#checkers_uncertain')");//"#A01284"); - this.uncertainGlyph.setAttribute("stroke", "black");//"none");//"#A01284"); - this.uncertainGlyph.setAttribute("stroke-opacity", "0.2"); - this.uncertainGlyph.setAttribute("fill-opacity", "0.2"); - // this.highlightGlyph.setAttribute("class", "link"); - // this.highlightGlyph.setAttribute("fill", "none"); - // this.highlightGlyph.setAttribute("stroke", highlightColour); - // this.highlightGlyph.setAttribute("stroke-width", "10"); - // this.highlightGlyph.setAttribute("stroke-opacity", "0"); + this.glyph.classList.add("link", "feature-link", "certain-link"); + this.uncertainGlyph.classList.add("link", "feature-link", "uncertain-link"); //set the events for it const self = this; @@ -271,7 +253,7 @@ FeatureLink.prototype.setLinkCoordinates = function () { // let highlightGlyphPath = "M" + triPointMid[0] + "," + triPointMid[1]; for (let f = 0; f < fSDCount; f++) { seqDatum = this.fromSequenceData[f]; - if (isNumber(seqDatum.begin) && isNumber(seqDatum.end)) { + if (isNumber(seqDatum.begin) && isNumber(seqDatum.end) || fromParticipant.type === "complex") { glyphPath += getSegment(triPointMid, ftMid, seqDatum.begin, seqDatum.end, fromParticipant, fyOffset, toOriginPoint); } // highlightStartRes = seqDatum.begin; @@ -291,7 +273,7 @@ FeatureLink.prototype.setLinkCoordinates = function () { } for (let t = 0; t < tSDCount; t++) { seqDatum = this.toSequenceData[t]; - if (isNumber(seqDatum.begin) && isNumber(seqDatum.end)) { + if (isNumber(seqDatum.begin) && isNumber(seqDatum.end) || toParticipant.type === "complex") { glyphPath += getSegment(triPointMid, ttMid, seqDatum.begin, seqDatum.end, toParticipant, tyOffset, fromOriginPoint); } // highlightStartRes = seqDatum.begin; diff --git a/src/js/viz/link/link.js b/src/js/viz/link/link.js index fdaafb3..fe6b36c 100644 --- a/src/js/viz/link/link.js +++ b/src/js/viz/link/link.js @@ -8,17 +8,8 @@ Link.prototype.highlightParticipants = function (show) { }; Link.prototype.initSVG = function () { - this.line.setAttribute("class", "link"); - this.line.setAttribute("fill", "none"); - this.line.setAttribute("stroke", "black"); - this.line.setAttribute("stroke-width", "1"); - this.line.setAttribute("stroke-linecap", "round"); - this.highlightLine.setAttribute("class", "link"); - this.highlightLine.setAttribute("fill", "none"); - this.highlightLine.setAttribute("stroke", highlightColour); - this.highlightLine.setAttribute("stroke-width", "10"); - this.highlightLine.setAttribute("stroke-linecap", "round"); - this.highlightLine.setAttribute("stroke-opacity", "0"); + this.line.classList.add("link","link-line");//, "certain-link"); + this.highlightLine.classList.add("link", "highlight", "link-highlight"); //set the events for it const self = this; this.line.onmousedown = function (evt) { diff --git a/src/js/viz/link/nary-link.js b/src/js/viz/link/nary-link.js index 80c8de8..6df479a 100644 --- a/src/js/viz/link/nary-link.js +++ b/src/js/viz/link/nary-link.js @@ -4,7 +4,7 @@ import {svgns, rotatePointAboutPoint} from "../../config"; //NaryLink.naryColors; // init'ed in clear function of util NaryLink.orbitNodes = 20; -NaryLink.orbitRadius = 20; +NaryLink.orbitRadius = 22; export function NaryLink(id, app) { this.id = id; @@ -54,6 +54,22 @@ NaryLink.prototype.initSVG = function () { // this.path.ontouchstart = function (evt) { // self.touchStart(evt); // }; + // todo - prob better way todo this + this.path2 = document.createElementNS(svgns, "path"); + this.path2.setAttribute("fill", "none"); + //set the events for it + this.path2.onmousedown = function (evt) { + self.mouseDown(evt); + }; + this.path2.onmouseover = function (evt) { + self.mouseOver(evt); + }; + this.path2.onmouseout = function (evt) { + self.mouseOut(evt); + }; + // this.path2.ontouchstart = function (evt) { + // self.touchStart(evt); + // }; }; NaryLink.prototype.showHighlight = function (show) { @@ -69,6 +85,7 @@ NaryLink.prototype.show = function () { // this.path.setAttribute("stroke-width", this.app.z); this.setLinkCoordinates(); this.app.naryLinks.appendChild(this.path); + this.app.naryLinks.appendChild(this.path2); }; NaryLink.prototype.hide = function () { @@ -86,6 +103,7 @@ NaryLink.prototype.setLinkCoordinates = function (dontPropogate) { const hullValues = calculateHullPath(this.mapped); if (hullValues) { this.path.setAttribute("d", hullValues); + this.path2.setAttribute("d", hullValues); } if (this.complex && !dontPropogate) { this.complex.setAllLinkCoordinates();