1664 lines
212 KiB
JavaScript
1664 lines
212 KiB
JavaScript
var __create = Object.create;
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __getProtoOf = Object.getPrototypeOf;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
var __commonJS = (cb, mod) => function __require() {
|
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
// If the importer is in node compatibility mode or this is not an ESM
|
|
// file that has been converted to a CommonJS file using a Babel-
|
|
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
mod
|
|
));
|
|
|
|
// node_modules/dayjs/dayjs.min.js
|
|
var require_dayjs_min = __commonJS({
|
|
"node_modules/dayjs/dayjs.min.js"(exports, module) {
|
|
!function(t, e) {
|
|
"object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e();
|
|
}(exports, function() {
|
|
"use strict";
|
|
var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = { name: "en", weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"), months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"), ordinal: function(t2) {
|
|
var e2 = ["th", "st", "nd", "rd"], n2 = t2 % 100;
|
|
return "[" + t2 + (e2[(n2 - 20) % 10] || e2[n2] || e2[0]) + "]";
|
|
} }, m = /* @__PURE__ */ __name(function(t2, e2, n2) {
|
|
var r2 = String(t2);
|
|
return !r2 || r2.length >= e2 ? t2 : "" + Array(e2 + 1 - r2.length).join(n2) + t2;
|
|
}, "m"), v = { s: m, z: function(t2) {
|
|
var e2 = -t2.utcOffset(), n2 = Math.abs(e2), r2 = Math.floor(n2 / 60), i2 = n2 % 60;
|
|
return (e2 <= 0 ? "+" : "-") + m(r2, 2, "0") + ":" + m(i2, 2, "0");
|
|
}, m: /* @__PURE__ */ __name(function t2(e2, n2) {
|
|
if (e2.date() < n2.date())
|
|
return -t2(n2, e2);
|
|
var r2 = 12 * (n2.year() - e2.year()) + (n2.month() - e2.month()), i2 = e2.clone().add(r2, c), s2 = n2 - i2 < 0, u2 = e2.clone().add(r2 + (s2 ? -1 : 1), c);
|
|
return +(-(r2 + (n2 - i2) / (s2 ? i2 - u2 : u2 - i2)) || 0);
|
|
}, "t"), a: function(t2) {
|
|
return t2 < 0 ? Math.ceil(t2) || 0 : Math.floor(t2);
|
|
}, p: function(t2) {
|
|
return { M: c, y: h, w: o, d: a, D: d, h: u, m: s, s: i, ms: r, Q: f }[t2] || String(t2 || "").toLowerCase().replace(/s$/, "");
|
|
}, u: function(t2) {
|
|
return void 0 === t2;
|
|
} }, g = "en", D = {};
|
|
D[g] = M;
|
|
var p = "$isDayjsObject", S = /* @__PURE__ */ __name(function(t2) {
|
|
return t2 instanceof _ || !(!t2 || !t2[p]);
|
|
}, "S"), w = /* @__PURE__ */ __name(function t2(e2, n2, r2) {
|
|
var i2;
|
|
if (!e2)
|
|
return g;
|
|
if ("string" == typeof e2) {
|
|
var s2 = e2.toLowerCase();
|
|
D[s2] && (i2 = s2), n2 && (D[s2] = n2, i2 = s2);
|
|
var u2 = e2.split("-");
|
|
if (!i2 && u2.length > 1)
|
|
return t2(u2[0]);
|
|
} else {
|
|
var a2 = e2.name;
|
|
D[a2] = e2, i2 = a2;
|
|
}
|
|
return !r2 && i2 && (g = i2), i2 || !r2 && g;
|
|
}, "t"), O = /* @__PURE__ */ __name(function(t2, e2) {
|
|
if (S(t2))
|
|
return t2.clone();
|
|
var n2 = "object" == typeof e2 ? e2 : {};
|
|
return n2.date = t2, n2.args = arguments, new _(n2);
|
|
}, "O"), b = v;
|
|
b.l = w, b.i = S, b.w = function(t2, e2) {
|
|
return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset });
|
|
};
|
|
var _ = function() {
|
|
function M2(t2) {
|
|
this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true;
|
|
}
|
|
__name(M2, "M");
|
|
var m2 = M2.prototype;
|
|
return m2.parse = function(t2) {
|
|
this.$d = function(t3) {
|
|
var e2 = t3.date, n2 = t3.utc;
|
|
if (null === e2)
|
|
return /* @__PURE__ */ new Date(NaN);
|
|
if (b.u(e2))
|
|
return /* @__PURE__ */ new Date();
|
|
if (e2 instanceof Date)
|
|
return new Date(e2);
|
|
if ("string" == typeof e2 && !/Z$/i.test(e2)) {
|
|
var r2 = e2.match($);
|
|
if (r2) {
|
|
var i2 = r2[2] - 1 || 0, s2 = (r2[7] || "0").substring(0, 3);
|
|
return n2 ? new Date(Date.UTC(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2)) : new Date(r2[1], i2, r2[3] || 1, r2[4] || 0, r2[5] || 0, r2[6] || 0, s2);
|
|
}
|
|
}
|
|
return new Date(e2);
|
|
}(t2), this.init();
|
|
}, m2.init = function() {
|
|
var t2 = this.$d;
|
|
this.$y = t2.getFullYear(), this.$M = t2.getMonth(), this.$D = t2.getDate(), this.$W = t2.getDay(), this.$H = t2.getHours(), this.$m = t2.getMinutes(), this.$s = t2.getSeconds(), this.$ms = t2.getMilliseconds();
|
|
}, m2.$utils = function() {
|
|
return b;
|
|
}, m2.isValid = function() {
|
|
return !(this.$d.toString() === l);
|
|
}, m2.isSame = function(t2, e2) {
|
|
var n2 = O(t2);
|
|
return this.startOf(e2) <= n2 && n2 <= this.endOf(e2);
|
|
}, m2.isAfter = function(t2, e2) {
|
|
return O(t2) < this.startOf(e2);
|
|
}, m2.isBefore = function(t2, e2) {
|
|
return this.endOf(e2) < O(t2);
|
|
}, m2.$g = function(t2, e2, n2) {
|
|
return b.u(t2) ? this[e2] : this.set(n2, t2);
|
|
}, m2.unix = function() {
|
|
return Math.floor(this.valueOf() / 1e3);
|
|
}, m2.valueOf = function() {
|
|
return this.$d.getTime();
|
|
}, m2.startOf = function(t2, e2) {
|
|
var n2 = this, r2 = !!b.u(e2) || e2, f2 = b.p(t2), l2 = /* @__PURE__ */ __name(function(t3, e3) {
|
|
var i2 = b.w(n2.$u ? Date.UTC(n2.$y, e3, t3) : new Date(n2.$y, e3, t3), n2);
|
|
return r2 ? i2 : i2.endOf(a);
|
|
}, "l"), $2 = /* @__PURE__ */ __name(function(t3, e3) {
|
|
return b.w(n2.toDate()[t3].apply(n2.toDate("s"), (r2 ? [0, 0, 0, 0] : [23, 59, 59, 999]).slice(e3)), n2);
|
|
}, "$"), y2 = this.$W, M3 = this.$M, m3 = this.$D, v2 = "set" + (this.$u ? "UTC" : "");
|
|
switch (f2) {
|
|
case h:
|
|
return r2 ? l2(1, 0) : l2(31, 11);
|
|
case c:
|
|
return r2 ? l2(1, M3) : l2(0, M3 + 1);
|
|
case o:
|
|
var g2 = this.$locale().weekStart || 0, D2 = (y2 < g2 ? y2 + 7 : y2) - g2;
|
|
return l2(r2 ? m3 - D2 : m3 + (6 - D2), M3);
|
|
case a:
|
|
case d:
|
|
return $2(v2 + "Hours", 0);
|
|
case u:
|
|
return $2(v2 + "Minutes", 1);
|
|
case s:
|
|
return $2(v2 + "Seconds", 2);
|
|
case i:
|
|
return $2(v2 + "Milliseconds", 3);
|
|
default:
|
|
return this.clone();
|
|
}
|
|
}, m2.endOf = function(t2) {
|
|
return this.startOf(t2, false);
|
|
}, m2.$set = function(t2, e2) {
|
|
var n2, o2 = b.p(t2), f2 = "set" + (this.$u ? "UTC" : ""), l2 = (n2 = {}, n2[a] = f2 + "Date", n2[d] = f2 + "Date", n2[c] = f2 + "Month", n2[h] = f2 + "FullYear", n2[u] = f2 + "Hours", n2[s] = f2 + "Minutes", n2[i] = f2 + "Seconds", n2[r] = f2 + "Milliseconds", n2)[o2], $2 = o2 === a ? this.$D + (e2 - this.$W) : e2;
|
|
if (o2 === c || o2 === h) {
|
|
var y2 = this.clone().set(d, 1);
|
|
y2.$d[l2]($2), y2.init(), this.$d = y2.set(d, Math.min(this.$D, y2.daysInMonth())).$d;
|
|
} else
|
|
l2 && this.$d[l2]($2);
|
|
return this.init(), this;
|
|
}, m2.set = function(t2, e2) {
|
|
return this.clone().$set(t2, e2);
|
|
}, m2.get = function(t2) {
|
|
return this[b.p(t2)]();
|
|
}, m2.add = function(r2, f2) {
|
|
var d2, l2 = this;
|
|
r2 = Number(r2);
|
|
var $2 = b.p(f2), y2 = /* @__PURE__ */ __name(function(t2) {
|
|
var e2 = O(l2);
|
|
return b.w(e2.date(e2.date() + Math.round(t2 * r2)), l2);
|
|
}, "y");
|
|
if ($2 === c)
|
|
return this.set(c, this.$M + r2);
|
|
if ($2 === h)
|
|
return this.set(h, this.$y + r2);
|
|
if ($2 === a)
|
|
return y2(1);
|
|
if ($2 === o)
|
|
return y2(7);
|
|
var M3 = (d2 = {}, d2[s] = e, d2[u] = n, d2[i] = t, d2)[$2] || 1, m3 = this.$d.getTime() + r2 * M3;
|
|
return b.w(m3, this);
|
|
}, m2.subtract = function(t2, e2) {
|
|
return this.add(-1 * t2, e2);
|
|
}, m2.format = function(t2) {
|
|
var e2 = this, n2 = this.$locale();
|
|
if (!this.isValid())
|
|
return n2.invalidDate || l;
|
|
var r2 = t2 || "YYYY-MM-DDTHH:mm:ssZ", i2 = b.z(this), s2 = this.$H, u2 = this.$m, a2 = this.$M, o2 = n2.weekdays, c2 = n2.months, f2 = n2.meridiem, h2 = /* @__PURE__ */ __name(function(t3, n3, i3, s3) {
|
|
return t3 && (t3[n3] || t3(e2, r2)) || i3[n3].slice(0, s3);
|
|
}, "h"), d2 = /* @__PURE__ */ __name(function(t3) {
|
|
return b.s(s2 % 12 || 12, t3, "0");
|
|
}, "d"), $2 = f2 || function(t3, e3, n3) {
|
|
var r3 = t3 < 12 ? "AM" : "PM";
|
|
return n3 ? r3.toLowerCase() : r3;
|
|
};
|
|
return r2.replace(y, function(t3, r3) {
|
|
return r3 || function(t4) {
|
|
switch (t4) {
|
|
case "YY":
|
|
return String(e2.$y).slice(-2);
|
|
case "YYYY":
|
|
return b.s(e2.$y, 4, "0");
|
|
case "M":
|
|
return a2 + 1;
|
|
case "MM":
|
|
return b.s(a2 + 1, 2, "0");
|
|
case "MMM":
|
|
return h2(n2.monthsShort, a2, c2, 3);
|
|
case "MMMM":
|
|
return h2(c2, a2);
|
|
case "D":
|
|
return e2.$D;
|
|
case "DD":
|
|
return b.s(e2.$D, 2, "0");
|
|
case "d":
|
|
return String(e2.$W);
|
|
case "dd":
|
|
return h2(n2.weekdaysMin, e2.$W, o2, 2);
|
|
case "ddd":
|
|
return h2(n2.weekdaysShort, e2.$W, o2, 3);
|
|
case "dddd":
|
|
return o2[e2.$W];
|
|
case "H":
|
|
return String(s2);
|
|
case "HH":
|
|
return b.s(s2, 2, "0");
|
|
case "h":
|
|
return d2(1);
|
|
case "hh":
|
|
return d2(2);
|
|
case "a":
|
|
return $2(s2, u2, true);
|
|
case "A":
|
|
return $2(s2, u2, false);
|
|
case "m":
|
|
return String(u2);
|
|
case "mm":
|
|
return b.s(u2, 2, "0");
|
|
case "s":
|
|
return String(e2.$s);
|
|
case "ss":
|
|
return b.s(e2.$s, 2, "0");
|
|
case "SSS":
|
|
return b.s(e2.$ms, 3, "0");
|
|
case "Z":
|
|
return i2;
|
|
}
|
|
return null;
|
|
}(t3) || i2.replace(":", "");
|
|
});
|
|
}, m2.utcOffset = function() {
|
|
return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
|
|
}, m2.diff = function(r2, d2, l2) {
|
|
var $2, y2 = this, M3 = b.p(d2), m3 = O(r2), v2 = (m3.utcOffset() - this.utcOffset()) * e, g2 = this - m3, D2 = /* @__PURE__ */ __name(function() {
|
|
return b.m(y2, m3);
|
|
}, "D");
|
|
switch (M3) {
|
|
case h:
|
|
$2 = D2() / 12;
|
|
break;
|
|
case c:
|
|
$2 = D2();
|
|
break;
|
|
case f:
|
|
$2 = D2() / 3;
|
|
break;
|
|
case o:
|
|
$2 = (g2 - v2) / 6048e5;
|
|
break;
|
|
case a:
|
|
$2 = (g2 - v2) / 864e5;
|
|
break;
|
|
case u:
|
|
$2 = g2 / n;
|
|
break;
|
|
case s:
|
|
$2 = g2 / e;
|
|
break;
|
|
case i:
|
|
$2 = g2 / t;
|
|
break;
|
|
default:
|
|
$2 = g2;
|
|
}
|
|
return l2 ? $2 : b.a($2);
|
|
}, m2.daysInMonth = function() {
|
|
return this.endOf(c).$D;
|
|
}, m2.$locale = function() {
|
|
return D[this.$L];
|
|
}, m2.locale = function(t2, e2) {
|
|
if (!t2)
|
|
return this.$L;
|
|
var n2 = this.clone(), r2 = w(t2, e2, true);
|
|
return r2 && (n2.$L = r2), n2;
|
|
}, m2.clone = function() {
|
|
return b.w(this.$d, this);
|
|
}, m2.toDate = function() {
|
|
return new Date(this.valueOf());
|
|
}, m2.toJSON = function() {
|
|
return this.isValid() ? this.toISOString() : null;
|
|
}, m2.toISOString = function() {
|
|
return this.$d.toISOString();
|
|
}, m2.toString = function() {
|
|
return this.$d.toUTCString();
|
|
}, M2;
|
|
}(), k = _.prototype;
|
|
return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) {
|
|
k[t2[1]] = function(e2) {
|
|
return this.$g(e2, t2[0], t2[1]);
|
|
};
|
|
}), O.extend = function(t2, e2) {
|
|
return t2.$i || (t2(e2, _, O), t2.$i = true), O;
|
|
}, O.locale = w, O.isDayjs = S, O.unix = function(t2) {
|
|
return O(1e3 * t2);
|
|
}, O.en = D[g], O.Ls = D, O.p = {}, O;
|
|
});
|
|
}
|
|
});
|
|
|
|
// node_modules/dayjs/plugin/utc.js
|
|
var require_utc = __commonJS({
|
|
"node_modules/dayjs/plugin/utc.js"(exports, module) {
|
|
!function(t, i) {
|
|
"object" == typeof exports && "undefined" != typeof module ? module.exports = i() : "function" == typeof define && define.amd ? define(i) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_utc = i();
|
|
}(exports, function() {
|
|
"use strict";
|
|
var t = "minute", i = /[+-]\d\d(?::?\d\d)?/g, e = /([+-]|\d\d)/g;
|
|
return function(s, f, n) {
|
|
var u = f.prototype;
|
|
n.utc = function(t2) {
|
|
var i2 = { date: t2, utc: true, args: arguments };
|
|
return new f(i2);
|
|
}, u.utc = function(i2) {
|
|
var e2 = n(this.toDate(), { locale: this.$L, utc: true });
|
|
return i2 ? e2.add(this.utcOffset(), t) : e2;
|
|
}, u.local = function() {
|
|
return n(this.toDate(), { locale: this.$L, utc: false });
|
|
};
|
|
var r = u.parse;
|
|
u.parse = function(t2) {
|
|
t2.utc && (this.$u = true), this.$utils().u(t2.$offset) || (this.$offset = t2.$offset), r.call(this, t2);
|
|
};
|
|
var o = u.init;
|
|
u.init = function() {
|
|
if (this.$u) {
|
|
var t2 = this.$d;
|
|
this.$y = t2.getUTCFullYear(), this.$M = t2.getUTCMonth(), this.$D = t2.getUTCDate(), this.$W = t2.getUTCDay(), this.$H = t2.getUTCHours(), this.$m = t2.getUTCMinutes(), this.$s = t2.getUTCSeconds(), this.$ms = t2.getUTCMilliseconds();
|
|
} else
|
|
o.call(this);
|
|
};
|
|
var a = u.utcOffset;
|
|
u.utcOffset = function(s2, f2) {
|
|
var n2 = this.$utils().u;
|
|
if (n2(s2))
|
|
return this.$u ? 0 : n2(this.$offset) ? a.call(this) : this.$offset;
|
|
if ("string" == typeof s2 && (s2 = function(t2) {
|
|
void 0 === t2 && (t2 = "");
|
|
var s3 = t2.match(i);
|
|
if (!s3)
|
|
return null;
|
|
var f3 = ("" + s3[0]).match(e) || ["-", 0, 0], n3 = f3[0], u3 = 60 * +f3[1] + +f3[2];
|
|
return 0 === u3 ? 0 : "+" === n3 ? u3 : -u3;
|
|
}(s2), null === s2))
|
|
return this;
|
|
var u2 = Math.abs(s2) <= 16 ? 60 * s2 : s2;
|
|
if (0 === u2)
|
|
return this.utc(f2);
|
|
var r2 = this.clone();
|
|
if (f2)
|
|
return r2.$offset = u2, r2.$u = false, r2;
|
|
var o2 = this.$u ? this.toDate().getTimezoneOffset() : -1 * this.utcOffset();
|
|
return (r2 = this.local().add(u2 + o2, t)).$offset = u2, r2.$x.$localOffset = o2, r2;
|
|
};
|
|
var h = u.format;
|
|
u.format = function(t2) {
|
|
var i2 = t2 || (this.$u ? "YYYY-MM-DDTHH:mm:ss[Z]" : "");
|
|
return h.call(this, i2);
|
|
}, u.valueOf = function() {
|
|
var t2 = this.$utils().u(this.$offset) ? 0 : this.$offset + (this.$x.$localOffset || this.$d.getTimezoneOffset());
|
|
return this.$d.valueOf() - 6e4 * t2;
|
|
}, u.isUTC = function() {
|
|
return !!this.$u;
|
|
}, u.toISOString = function() {
|
|
return this.toDate().toISOString();
|
|
}, u.toString = function() {
|
|
return this.toDate().toUTCString();
|
|
};
|
|
var l = u.toDate;
|
|
u.toDate = function(t2) {
|
|
return "s" === t2 && this.$offset ? n(this.format("YYYY-MM-DD HH:mm:ss:SSS")).toDate() : l.call(this);
|
|
};
|
|
var c = u.diff;
|
|
u.diff = function(t2, i2, e2) {
|
|
if (t2 && this.$u === t2.$u)
|
|
return c.call(this, t2, i2, e2);
|
|
var s2 = this.local(), f2 = n(t2).local();
|
|
return c.call(s2, f2, i2, e2);
|
|
};
|
|
};
|
|
});
|
|
}
|
|
});
|
|
|
|
// node_modules/dayjs/plugin/timezone.js
|
|
var require_timezone = __commonJS({
|
|
"node_modules/dayjs/plugin/timezone.js"(exports, module) {
|
|
!function(t, e) {
|
|
"object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs_plugin_timezone = e();
|
|
}(exports, function() {
|
|
"use strict";
|
|
var t = { year: 0, month: 1, day: 2, hour: 3, minute: 4, second: 5 }, e = {};
|
|
return function(n, i, o) {
|
|
var r, a = /* @__PURE__ */ __name(function(t2, n2, i2) {
|
|
void 0 === i2 && (i2 = {});
|
|
var o2 = new Date(t2), r2 = function(t3, n3) {
|
|
void 0 === n3 && (n3 = {});
|
|
var i3 = n3.timeZoneName || "short", o3 = t3 + "|" + i3, r3 = e[o3];
|
|
return r3 || (r3 = new Intl.DateTimeFormat("en-US", { hour12: false, timeZone: t3, year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", timeZoneName: i3 }), e[o3] = r3), r3;
|
|
}(n2, i2);
|
|
return r2.formatToParts(o2);
|
|
}, "a"), u = /* @__PURE__ */ __name(function(e2, n2) {
|
|
for (var i2 = a(e2, n2), r2 = [], u2 = 0; u2 < i2.length; u2 += 1) {
|
|
var f2 = i2[u2], s2 = f2.type, m = f2.value, c = t[s2];
|
|
c >= 0 && (r2[c] = parseInt(m, 10));
|
|
}
|
|
var d = r2[3], l = 24 === d ? 0 : d, h = r2[0] + "-" + r2[1] + "-" + r2[2] + " " + l + ":" + r2[4] + ":" + r2[5] + ":000", v = +e2;
|
|
return (o.utc(h).valueOf() - (v -= v % 1e3)) / 6e4;
|
|
}, "u"), f = i.prototype;
|
|
f.tz = function(t2, e2) {
|
|
void 0 === t2 && (t2 = r);
|
|
var n2, i2 = this.utcOffset(), a2 = this.toDate(), u2 = a2.toLocaleString("en-US", { timeZone: t2 }), f2 = Math.round((a2 - new Date(u2)) / 1e3 / 60), s2 = 15 * -Math.round(a2.getTimezoneOffset() / 15) - f2;
|
|
if (!Number(s2))
|
|
n2 = this.utcOffset(0, e2);
|
|
else if (n2 = o(u2, { locale: this.$L }).$set("millisecond", this.$ms).utcOffset(s2, true), e2) {
|
|
var m = n2.utcOffset();
|
|
n2 = n2.add(i2 - m, "minute");
|
|
}
|
|
return n2.$x.$timezone = t2, n2;
|
|
}, f.offsetName = function(t2) {
|
|
var e2 = this.$x.$timezone || o.tz.guess(), n2 = a(this.valueOf(), e2, { timeZoneName: t2 }).find(function(t3) {
|
|
return "timezonename" === t3.type.toLowerCase();
|
|
});
|
|
return n2 && n2.value;
|
|
};
|
|
var s = f.startOf;
|
|
f.startOf = function(t2, e2) {
|
|
if (!this.$x || !this.$x.$timezone)
|
|
return s.call(this, t2, e2);
|
|
var n2 = o(this.format("YYYY-MM-DD HH:mm:ss:SSS"), { locale: this.$L });
|
|
return s.call(n2, t2, e2).tz(this.$x.$timezone, true);
|
|
}, o.tz = function(t2, e2, n2) {
|
|
var i2 = n2 && e2, a2 = n2 || e2 || r, f2 = u(+o(), a2);
|
|
if ("string" != typeof t2)
|
|
return o(t2).tz(a2);
|
|
var s2 = function(t3, e3, n3) {
|
|
var i3 = t3 - 60 * e3 * 1e3, o2 = u(i3, n3);
|
|
if (e3 === o2)
|
|
return [i3, e3];
|
|
var r2 = u(i3 -= 60 * (o2 - e3) * 1e3, n3);
|
|
return o2 === r2 ? [i3, o2] : [t3 - 60 * Math.min(o2, r2) * 1e3, Math.max(o2, r2)];
|
|
}(o.utc(t2, i2).valueOf(), f2, a2), m = s2[0], c = s2[1], d = o(m).utcOffset(c);
|
|
return d.$x.$timezone = a2, d;
|
|
}, o.tz.guess = function() {
|
|
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
}, o.tz.setDefault = function(t2) {
|
|
r = t2;
|
|
};
|
|
};
|
|
});
|
|
}
|
|
});
|
|
|
|
// node_modules/dayjs/plugin/isoWeek.js
|
|
var require_isoWeek = __commonJS({
|
|
"node_modules/dayjs/plugin/isoWeek.js"(exports, module) {
|
|
!function(e, t) {
|
|
"object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = "undefined" != typeof globalThis ? globalThis : e || self).dayjs_plugin_isoWeek = t();
|
|
}(exports, function() {
|
|
"use strict";
|
|
var e = "day";
|
|
return function(t, i, s) {
|
|
var a = /* @__PURE__ */ __name(function(t2) {
|
|
return t2.add(4 - t2.isoWeekday(), e);
|
|
}, "a"), d = i.prototype;
|
|
d.isoWeekYear = function() {
|
|
return a(this).year();
|
|
}, d.isoWeek = function(t2) {
|
|
if (!this.$utils().u(t2))
|
|
return this.add(7 * (t2 - this.isoWeek()), e);
|
|
var i2, d2, n2, o, r = a(this), u = (i2 = this.isoWeekYear(), d2 = this.$u, n2 = (d2 ? s.utc : s)().year(i2).startOf("year"), o = 4 - n2.isoWeekday(), n2.isoWeekday() > 4 && (o += 7), n2.add(o, e));
|
|
return r.diff(u, "week") + 1;
|
|
}, d.isoWeekday = function(e2) {
|
|
return this.$utils().u(e2) ? this.day() || 7 : this.day(this.day() % 7 ? e2 : e2 - 7);
|
|
};
|
|
var n = d.startOf;
|
|
d.startOf = function(e2, t2) {
|
|
var i2 = this.$utils(), s2 = !!i2.u(t2) || t2;
|
|
return "isoweek" === i2.p(e2) ? s2 ? this.date(this.date() - (this.isoWeekday() - 1)).startOf("day") : this.date(this.date() - 1 - (this.isoWeekday() - 1) + 7).endOf("day") : n.bind(this)(e2, t2);
|
|
};
|
|
};
|
|
});
|
|
}
|
|
});
|
|
|
|
// src/core/RenderBuilder.ts
|
|
function buildPipeline(renderers) {
|
|
return {
|
|
async run(context) {
|
|
for (const renderer of renderers) {
|
|
await renderer.render(context);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
__name(buildPipeline, "buildPipeline");
|
|
|
|
// src/core/FilterTemplate.ts
|
|
var _FilterTemplate = class _FilterTemplate {
|
|
constructor(dateService, entityResolver) {
|
|
this.dateService = dateService;
|
|
this.entityResolver = entityResolver;
|
|
this.fields = [];
|
|
}
|
|
/**
|
|
* Tilføj felt til template
|
|
* @param idProperty - Property-navn (bruges på både event og column.dataset)
|
|
* @param derivedFrom - Hvis feltet udledes fra anden property (f.eks. date fra start)
|
|
*/
|
|
addField(idProperty, derivedFrom) {
|
|
this.fields.push({ idProperty, derivedFrom });
|
|
return this;
|
|
}
|
|
/**
|
|
* Parse dot-notation string into components
|
|
* @example 'resource.teamId' → { entityType: 'resource', property: 'teamId', foreignKey: 'resourceId' }
|
|
*/
|
|
parseDotNotation(idProperty) {
|
|
if (!idProperty.includes("."))
|
|
return null;
|
|
const [entityType, property] = idProperty.split(".");
|
|
return {
|
|
entityType,
|
|
property,
|
|
foreignKey: entityType + "Id"
|
|
// Convention: resource → resourceId
|
|
};
|
|
}
|
|
/**
|
|
* Get dataset key for column lookup
|
|
* For dot-notation 'resource.teamId', we look for 'teamId' in dataset
|
|
*/
|
|
getDatasetKey(idProperty) {
|
|
const dotNotation = this.parseDotNotation(idProperty);
|
|
if (dotNotation) {
|
|
return dotNotation.property;
|
|
}
|
|
return idProperty;
|
|
}
|
|
/**
|
|
* Byg nøgle fra kolonne
|
|
* Læser værdier fra column.dataset[idProperty]
|
|
* For dot-notation, uses the property part (resource.teamId → teamId)
|
|
*/
|
|
buildKeyFromColumn(column) {
|
|
return this.fields.map((f) => {
|
|
const key = this.getDatasetKey(f.idProperty);
|
|
return column.dataset[key] || "";
|
|
}).join(":");
|
|
}
|
|
/**
|
|
* Byg nøgle fra event
|
|
* Læser værdier fra event[idProperty] eller udleder fra derivedFrom
|
|
* For dot-notation, resolves via EntityResolver
|
|
*/
|
|
buildKeyFromEvent(event) {
|
|
const eventRecord = event;
|
|
return this.fields.map((f) => {
|
|
const dotNotation = this.parseDotNotation(f.idProperty);
|
|
if (dotNotation) {
|
|
return this.resolveDotNotation(eventRecord, dotNotation);
|
|
}
|
|
if (f.derivedFrom) {
|
|
const sourceValue = eventRecord[f.derivedFrom];
|
|
if (sourceValue instanceof Date) {
|
|
return this.dateService.getDateKey(sourceValue);
|
|
}
|
|
return String(sourceValue || "");
|
|
}
|
|
return String(eventRecord[f.idProperty] || "");
|
|
}).join(":");
|
|
}
|
|
/**
|
|
* Resolve dot-notation reference via EntityResolver
|
|
*/
|
|
resolveDotNotation(eventRecord, dotNotation) {
|
|
if (!this.entityResolver) {
|
|
console.warn(`FilterTemplate: EntityResolver required for dot-notation '${dotNotation.entityType}.${dotNotation.property}'`);
|
|
return "";
|
|
}
|
|
const foreignId = eventRecord[dotNotation.foreignKey];
|
|
if (!foreignId)
|
|
return "";
|
|
const entity = this.entityResolver.resolve(dotNotation.entityType, String(foreignId));
|
|
if (!entity)
|
|
return "";
|
|
return String(entity[dotNotation.property] || "");
|
|
}
|
|
/**
|
|
* Match event mod kolonne
|
|
*/
|
|
matches(event, column) {
|
|
return this.buildKeyFromEvent(event) === this.buildKeyFromColumn(column);
|
|
}
|
|
};
|
|
__name(_FilterTemplate, "FilterTemplate");
|
|
var FilterTemplate = _FilterTemplate;
|
|
|
|
// src/core/CalendarOrchestrator.ts
|
|
var _CalendarOrchestrator = class _CalendarOrchestrator {
|
|
constructor(allRenderers, eventRenderer, scheduleRenderer, headerDrawerRenderer, dateService, entityServices) {
|
|
this.allRenderers = allRenderers;
|
|
this.eventRenderer = eventRenderer;
|
|
this.scheduleRenderer = scheduleRenderer;
|
|
this.headerDrawerRenderer = headerDrawerRenderer;
|
|
this.dateService = dateService;
|
|
this.entityServices = entityServices;
|
|
}
|
|
async render(viewConfig, container) {
|
|
const headerContainer = container.querySelector("swp-calendar-header");
|
|
const columnContainer = container.querySelector("swp-day-columns");
|
|
if (!headerContainer || !columnContainer) {
|
|
throw new Error("Missing swp-calendar-header or swp-day-columns");
|
|
}
|
|
const filter = {};
|
|
for (const grouping of viewConfig.groupings) {
|
|
filter[grouping.type] = grouping.values;
|
|
}
|
|
const filterTemplate = new FilterTemplate(this.dateService);
|
|
for (const grouping of viewConfig.groupings) {
|
|
if (grouping.idProperty) {
|
|
filterTemplate.addField(grouping.idProperty, grouping.derivedFrom);
|
|
}
|
|
}
|
|
const { parentChildMap, childType } = await this.resolveBelongsTo(viewConfig.groupings, filter);
|
|
const context = { headerContainer, columnContainer, filter, groupings: viewConfig.groupings, parentChildMap, childType };
|
|
headerContainer.innerHTML = "";
|
|
columnContainer.innerHTML = "";
|
|
const levels = viewConfig.groupings.map((g) => g.type).join(" ");
|
|
headerContainer.dataset.levels = levels;
|
|
const activeRenderers = this.selectRenderers(viewConfig);
|
|
const pipeline = buildPipeline(activeRenderers);
|
|
await pipeline.run(context);
|
|
await this.scheduleRenderer.render(container, filter);
|
|
await this.eventRenderer.render(container, filter, filterTemplate);
|
|
await this.headerDrawerRenderer.render(container, filter, filterTemplate);
|
|
}
|
|
selectRenderers(viewConfig) {
|
|
const types = viewConfig.groupings.map((g) => g.type);
|
|
return types.map((type) => this.allRenderers.find((r) => r.type === type)).filter((r) => r !== void 0);
|
|
}
|
|
/**
|
|
* Resolve belongsTo relations to build parent-child map
|
|
* e.g., belongsTo: 'team.resourceIds' → { team1: ['EMP001', 'EMP002'], team2: [...] }
|
|
* Also returns the childType (the grouping type that has belongsTo)
|
|
*/
|
|
async resolveBelongsTo(groupings, filter) {
|
|
const childGrouping = groupings.find((g) => g.belongsTo);
|
|
if (!childGrouping?.belongsTo)
|
|
return {};
|
|
const [entityType, property] = childGrouping.belongsTo.split(".");
|
|
if (!entityType || !property)
|
|
return {};
|
|
const parentIds = filter[entityType] || [];
|
|
if (parentIds.length === 0)
|
|
return {};
|
|
const service = this.entityServices.find(
|
|
(s) => s.entityType.toLowerCase() === entityType
|
|
);
|
|
if (!service)
|
|
return {};
|
|
const allEntities = await service.getAll();
|
|
const entities = allEntities.filter(
|
|
(e) => parentIds.includes(e.id)
|
|
);
|
|
const map = {};
|
|
for (const entity of entities) {
|
|
const entityRecord = entity;
|
|
const children = entityRecord[property] || [];
|
|
map[entityRecord.id] = children;
|
|
}
|
|
return { parentChildMap: map, childType: childGrouping.type };
|
|
}
|
|
};
|
|
__name(_CalendarOrchestrator, "CalendarOrchestrator");
|
|
var CalendarOrchestrator = _CalendarOrchestrator;
|
|
|
|
// src/core/NavigationAnimator.ts
|
|
var _NavigationAnimator = class _NavigationAnimator {
|
|
constructor(headerTrack, contentTrack, headerDrawer) {
|
|
this.headerTrack = headerTrack;
|
|
this.contentTrack = contentTrack;
|
|
this.headerDrawer = headerDrawer;
|
|
}
|
|
async slide(direction, renderFn) {
|
|
const out = direction === "left" ? "-100%" : "100%";
|
|
const into = direction === "left" ? "100%" : "-100%";
|
|
await this.animateOut(out);
|
|
await renderFn();
|
|
await this.animateIn(into);
|
|
}
|
|
async animateOut(translate) {
|
|
const animations = [
|
|
this.headerTrack.animate(
|
|
[{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }],
|
|
{ duration: 200, easing: "ease-in" }
|
|
).finished,
|
|
this.contentTrack.animate(
|
|
[{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }],
|
|
{ duration: 200, easing: "ease-in" }
|
|
).finished
|
|
];
|
|
if (this.headerDrawer) {
|
|
animations.push(
|
|
this.headerDrawer.animate(
|
|
[{ transform: "translateX(0)" }, { transform: `translateX(${translate})` }],
|
|
{ duration: 200, easing: "ease-in" }
|
|
).finished
|
|
);
|
|
}
|
|
await Promise.all(animations);
|
|
}
|
|
async animateIn(translate) {
|
|
const animations = [
|
|
this.headerTrack.animate(
|
|
[{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }],
|
|
{ duration: 200, easing: "ease-out" }
|
|
).finished,
|
|
this.contentTrack.animate(
|
|
[{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }],
|
|
{ duration: 200, easing: "ease-out" }
|
|
).finished
|
|
];
|
|
if (this.headerDrawer) {
|
|
animations.push(
|
|
this.headerDrawer.animate(
|
|
[{ transform: `translateX(${translate})` }, { transform: "translateX(0)" }],
|
|
{ duration: 200, easing: "ease-out" }
|
|
).finished
|
|
);
|
|
}
|
|
await Promise.all(animations);
|
|
}
|
|
};
|
|
__name(_NavigationAnimator, "NavigationAnimator");
|
|
var NavigationAnimator = _NavigationAnimator;
|
|
|
|
// src/features/date/DateRenderer.ts
|
|
var _DateRenderer = class _DateRenderer {
|
|
constructor(dateService) {
|
|
this.dateService = dateService;
|
|
this.type = "date";
|
|
}
|
|
render(context) {
|
|
const dates = context.filter["date"] || [];
|
|
const resourceIds = context.filter["resource"] || [];
|
|
const dateGrouping = context.groupings?.find((g) => g.type === "date");
|
|
const hideHeader = dateGrouping?.hideHeader === true;
|
|
const iterations = resourceIds.length || 1;
|
|
let columnCount = 0;
|
|
for (let r = 0; r < iterations; r++) {
|
|
const resourceId = resourceIds[r];
|
|
for (const dateStr of dates) {
|
|
const date = this.dateService.parseISO(dateStr);
|
|
const segments = { date: dateStr };
|
|
if (resourceId)
|
|
segments.resource = resourceId;
|
|
const columnKey = this.dateService.buildColumnKey(segments);
|
|
const header = document.createElement("swp-day-header");
|
|
header.dataset.date = dateStr;
|
|
header.dataset.columnKey = columnKey;
|
|
if (resourceId) {
|
|
header.dataset.resourceId = resourceId;
|
|
}
|
|
if (hideHeader) {
|
|
header.dataset.hidden = "true";
|
|
}
|
|
header.innerHTML = `
|
|
<swp-day-name>${this.dateService.getDayName(date, "short")}</swp-day-name>
|
|
<swp-day-date>${date.getDate()}</swp-day-date>
|
|
`;
|
|
context.headerContainer.appendChild(header);
|
|
const column = document.createElement("swp-day-column");
|
|
column.dataset.date = dateStr;
|
|
column.dataset.columnKey = columnKey;
|
|
if (resourceId) {
|
|
column.dataset.resourceId = resourceId;
|
|
}
|
|
column.innerHTML = "<swp-events-layer></swp-events-layer>";
|
|
context.columnContainer.appendChild(column);
|
|
columnCount++;
|
|
}
|
|
}
|
|
const container = context.columnContainer.closest("swp-calendar-container");
|
|
if (container) {
|
|
container.style.setProperty("--grid-columns", String(columnCount));
|
|
}
|
|
}
|
|
};
|
|
__name(_DateRenderer, "DateRenderer");
|
|
var DateRenderer = _DateRenderer;
|
|
|
|
// src/core/DateService.ts
|
|
var import_dayjs = __toESM(require_dayjs_min(), 1);
|
|
var import_utc = __toESM(require_utc(), 1);
|
|
var import_timezone = __toESM(require_timezone(), 1);
|
|
var import_isoWeek = __toESM(require_isoWeek(), 1);
|
|
import_dayjs.default.extend(import_utc.default);
|
|
import_dayjs.default.extend(import_timezone.default);
|
|
import_dayjs.default.extend(import_isoWeek.default);
|
|
var _DateService = class _DateService {
|
|
constructor(config, baseDate) {
|
|
this.config = config;
|
|
this.timezone = config.timezone;
|
|
this.baseDate = baseDate ? (0, import_dayjs.default)(baseDate) : (0, import_dayjs.default)();
|
|
}
|
|
/**
|
|
* Set a fixed base date (useful for demos with static mock data)
|
|
*/
|
|
setBaseDate(date) {
|
|
this.baseDate = (0, import_dayjs.default)(date);
|
|
}
|
|
/**
|
|
* Get the current base date (either fixed or today)
|
|
*/
|
|
getBaseDate() {
|
|
return this.baseDate.toDate();
|
|
}
|
|
parseISO(isoString) {
|
|
return (0, import_dayjs.default)(isoString).toDate();
|
|
}
|
|
getDayName(date, format = "short") {
|
|
return new Intl.DateTimeFormat(this.config.locale, { weekday: format }).format(date);
|
|
}
|
|
/**
|
|
* Get dates starting from a day offset
|
|
* @param dayOffset - Day offset from base date
|
|
* @param count - Number of consecutive days to return
|
|
* @returns Array of date strings in YYYY-MM-DD format
|
|
*/
|
|
getDatesFromOffset(dayOffset, count) {
|
|
const startDate = this.baseDate.add(dayOffset, "day");
|
|
return Array.from(
|
|
{ length: count },
|
|
(_, i) => startDate.add(i, "day").format("YYYY-MM-DD")
|
|
);
|
|
}
|
|
/**
|
|
* Get specific weekdays from the week containing the offset date
|
|
* @param dayOffset - Day offset from base date
|
|
* @param workDays - Array of ISO weekday numbers (1=Monday, 7=Sunday)
|
|
* @returns Array of date strings in YYYY-MM-DD format
|
|
*/
|
|
getWorkDaysFromOffset(dayOffset, workDays) {
|
|
const targetDate = this.baseDate.add(dayOffset, "day");
|
|
const monday = targetDate.startOf("week").add(1, "day");
|
|
return workDays.map((isoDay) => {
|
|
const daysFromMonday = isoDay === 7 ? 6 : isoDay - 1;
|
|
return monday.add(daysFromMonday, "day").format("YYYY-MM-DD");
|
|
});
|
|
}
|
|
// Legacy methods for backwards compatibility
|
|
getWeekDates(weekOffset = 0, days = 7) {
|
|
return this.getDatesFromOffset(weekOffset * 7, days);
|
|
}
|
|
getWorkWeekDates(weekOffset, workDays) {
|
|
return this.getWorkDaysFromOffset(weekOffset * 7, workDays);
|
|
}
|
|
// ============================================
|
|
// FORMATTING
|
|
// ============================================
|
|
formatTime(date, showSeconds = false) {
|
|
const pattern = showSeconds ? "HH:mm:ss" : "HH:mm";
|
|
return (0, import_dayjs.default)(date).format(pattern);
|
|
}
|
|
formatTimeRange(start, end) {
|
|
return `${this.formatTime(start)} - ${this.formatTime(end)}`;
|
|
}
|
|
formatDate(date) {
|
|
return (0, import_dayjs.default)(date).format("YYYY-MM-DD");
|
|
}
|
|
getDateKey(date) {
|
|
return this.formatDate(date);
|
|
}
|
|
// ============================================
|
|
// COLUMN KEY
|
|
// ============================================
|
|
/**
|
|
* Build a uniform columnKey from grouping segments
|
|
* Handles any combination of date, resource, team, etc.
|
|
*
|
|
* @example
|
|
* buildColumnKey({ date: '2025-12-09' }) → "2025-12-09"
|
|
* buildColumnKey({ date: '2025-12-09', resource: 'EMP001' }) → "2025-12-09:EMP001"
|
|
*/
|
|
buildColumnKey(segments) {
|
|
const date = segments.date;
|
|
const others = Object.entries(segments).filter(([k]) => k !== "date").sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v);
|
|
return date ? [date, ...others].join(":") : others.join(":");
|
|
}
|
|
/**
|
|
* Parse a columnKey back into segments
|
|
* Assumes format: "date:resource:..." or just "date"
|
|
*/
|
|
parseColumnKey(columnKey) {
|
|
const parts = columnKey.split(":");
|
|
return {
|
|
date: parts[0],
|
|
resource: parts[1]
|
|
};
|
|
}
|
|
/**
|
|
* Extract dateKey from columnKey (first segment)
|
|
*/
|
|
getDateFromColumnKey(columnKey) {
|
|
return columnKey.split(":")[0];
|
|
}
|
|
// ============================================
|
|
// TIME CALCULATIONS
|
|
// ============================================
|
|
timeToMinutes(timeString) {
|
|
const parts = timeString.split(":").map(Number);
|
|
const hours = parts[0] || 0;
|
|
const minutes = parts[1] || 0;
|
|
return hours * 60 + minutes;
|
|
}
|
|
minutesToTime(totalMinutes) {
|
|
const hours = Math.floor(totalMinutes / 60);
|
|
const minutes = totalMinutes % 60;
|
|
return (0, import_dayjs.default)().hour(hours).minute(minutes).format("HH:mm");
|
|
}
|
|
getMinutesSinceMidnight(date) {
|
|
const d = (0, import_dayjs.default)(date);
|
|
return d.hour() * 60 + d.minute();
|
|
}
|
|
// ============================================
|
|
// UTC CONVERSIONS
|
|
// ============================================
|
|
toUTC(localDate) {
|
|
return import_dayjs.default.tz(localDate, this.timezone).utc().toISOString();
|
|
}
|
|
fromUTC(utcString) {
|
|
return import_dayjs.default.utc(utcString).tz(this.timezone).toDate();
|
|
}
|
|
// ============================================
|
|
// DATE CREATION
|
|
// ============================================
|
|
createDateAtTime(baseDate, timeString) {
|
|
const totalMinutes = this.timeToMinutes(timeString);
|
|
const hours = Math.floor(totalMinutes / 60);
|
|
const minutes = totalMinutes % 60;
|
|
return (0, import_dayjs.default)(baseDate).startOf("day").hour(hours).minute(minutes).toDate();
|
|
}
|
|
getISOWeekDay(date) {
|
|
return (0, import_dayjs.default)(date).isoWeekday();
|
|
}
|
|
};
|
|
__name(_DateService, "DateService");
|
|
var DateService = _DateService;
|
|
|
|
// src/utils/PositionUtils.ts
|
|
function calculateEventPosition(start, end, config) {
|
|
const startMinutes = start.getHours() * 60 + start.getMinutes();
|
|
const endMinutes = end.getHours() * 60 + end.getMinutes();
|
|
const dayStartMinutes = config.dayStartHour * 60;
|
|
const minuteHeight = config.hourHeight / 60;
|
|
const top = (startMinutes - dayStartMinutes) * minuteHeight;
|
|
const height = (endMinutes - startMinutes) * minuteHeight;
|
|
return { top, height };
|
|
}
|
|
__name(calculateEventPosition, "calculateEventPosition");
|
|
function minutesToPixels(minutes, config) {
|
|
return minutes / 60 * config.hourHeight;
|
|
}
|
|
__name(minutesToPixels, "minutesToPixels");
|
|
function pixelsToMinutes(pixels, config) {
|
|
return pixels / config.hourHeight * 60;
|
|
}
|
|
__name(pixelsToMinutes, "pixelsToMinutes");
|
|
function snapToGrid(pixels, config) {
|
|
const snapPixels = minutesToPixels(config.snapInterval, config);
|
|
return Math.round(pixels / snapPixels) * snapPixels;
|
|
}
|
|
__name(snapToGrid, "snapToGrid");
|
|
|
|
// src/constants/CoreEvents.ts
|
|
var CoreEvents = {
|
|
// Lifecycle events
|
|
INITIALIZED: "core:initialized",
|
|
READY: "core:ready",
|
|
DESTROYED: "core:destroyed",
|
|
// View events
|
|
VIEW_CHANGED: "view:changed",
|
|
VIEW_RENDERED: "view:rendered",
|
|
// Navigation events
|
|
DATE_CHANGED: "nav:date-changed",
|
|
NAVIGATION_COMPLETED: "nav:navigation-completed",
|
|
// Data events
|
|
DATA_LOADING: "data:loading",
|
|
DATA_LOADED: "data:loaded",
|
|
DATA_ERROR: "data:error",
|
|
// Grid events
|
|
GRID_RENDERED: "grid:rendered",
|
|
GRID_CLICKED: "grid:clicked",
|
|
// Event management
|
|
EVENT_CREATED: "event:created",
|
|
EVENT_UPDATED: "event:updated",
|
|
EVENT_DELETED: "event:deleted",
|
|
EVENT_SELECTED: "event:selected",
|
|
// Event drag-drop
|
|
EVENT_DRAG_START: "event:drag-start",
|
|
EVENT_DRAG_MOVE: "event:drag-move",
|
|
EVENT_DRAG_END: "event:drag-end",
|
|
EVENT_DRAG_CANCEL: "event:drag-cancel",
|
|
EVENT_DRAG_COLUMN_CHANGE: "event:drag-column-change",
|
|
// Header drag (timed → header conversion)
|
|
EVENT_DRAG_ENTER_HEADER: "event:drag-enter-header",
|
|
EVENT_DRAG_MOVE_HEADER: "event:drag-move-header",
|
|
EVENT_DRAG_LEAVE_HEADER: "event:drag-leave-header",
|
|
// Event resize
|
|
EVENT_RESIZE_START: "event:resize-start",
|
|
EVENT_RESIZE_END: "event:resize-end",
|
|
// Edge scroll
|
|
EDGE_SCROLL_TICK: "edge-scroll:tick",
|
|
EDGE_SCROLL_STARTED: "edge-scroll:started",
|
|
EDGE_SCROLL_STOPPED: "edge-scroll:stopped",
|
|
// System events
|
|
ERROR: "system:error",
|
|
// Sync events
|
|
SYNC_STARTED: "sync:started",
|
|
SYNC_COMPLETED: "sync:completed",
|
|
SYNC_FAILED: "sync:failed",
|
|
// Entity events - for audit and sync
|
|
ENTITY_SAVED: "entity:saved",
|
|
ENTITY_DELETED: "entity:deleted",
|
|
// Audit events
|
|
AUDIT_LOGGED: "audit:logged",
|
|
// Rendering events
|
|
EVENTS_RENDERED: "events:rendered"
|
|
};
|
|
|
|
// src/features/event/EventLayoutEngine.ts
|
|
function eventsOverlap(a, b) {
|
|
return a.start < b.end && a.end > b.start;
|
|
}
|
|
__name(eventsOverlap, "eventsOverlap");
|
|
function eventsWithinThreshold(a, b, thresholdMinutes) {
|
|
const thresholdMs = thresholdMinutes * 60 * 1e3;
|
|
const startToStartDiff = Math.abs(a.start.getTime() - b.start.getTime());
|
|
if (startToStartDiff <= thresholdMs)
|
|
return true;
|
|
const bStartsBeforeAEnds = a.end.getTime() - b.start.getTime();
|
|
if (bStartsBeforeAEnds > 0 && bStartsBeforeAEnds <= thresholdMs)
|
|
return true;
|
|
const aStartsBeforeBEnds = b.end.getTime() - a.start.getTime();
|
|
if (aStartsBeforeBEnds > 0 && aStartsBeforeBEnds <= thresholdMs)
|
|
return true;
|
|
return false;
|
|
}
|
|
__name(eventsWithinThreshold, "eventsWithinThreshold");
|
|
function findOverlapGroups(events) {
|
|
if (events.length === 0)
|
|
return [];
|
|
const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime());
|
|
const used = /* @__PURE__ */ new Set();
|
|
const groups = [];
|
|
for (const event of sorted) {
|
|
if (used.has(event.id))
|
|
continue;
|
|
const group = [event];
|
|
used.add(event.id);
|
|
let expanded = true;
|
|
while (expanded) {
|
|
expanded = false;
|
|
for (const candidate of sorted) {
|
|
if (used.has(candidate.id))
|
|
continue;
|
|
const connects = group.some((member) => eventsOverlap(member, candidate));
|
|
if (connects) {
|
|
group.push(candidate);
|
|
used.add(candidate.id);
|
|
expanded = true;
|
|
}
|
|
}
|
|
}
|
|
groups.push(group);
|
|
}
|
|
return groups;
|
|
}
|
|
__name(findOverlapGroups, "findOverlapGroups");
|
|
function findGridCandidates(events, thresholdMinutes) {
|
|
if (events.length === 0)
|
|
return [];
|
|
const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime());
|
|
const used = /* @__PURE__ */ new Set();
|
|
const groups = [];
|
|
for (const event of sorted) {
|
|
if (used.has(event.id))
|
|
continue;
|
|
const group = [event];
|
|
used.add(event.id);
|
|
let expanded = true;
|
|
while (expanded) {
|
|
expanded = false;
|
|
for (const candidate of sorted) {
|
|
if (used.has(candidate.id))
|
|
continue;
|
|
const connects = group.some(
|
|
(member) => eventsWithinThreshold(member, candidate, thresholdMinutes)
|
|
);
|
|
if (connects) {
|
|
group.push(candidate);
|
|
used.add(candidate.id);
|
|
expanded = true;
|
|
}
|
|
}
|
|
}
|
|
groups.push(group);
|
|
}
|
|
return groups;
|
|
}
|
|
__name(findGridCandidates, "findGridCandidates");
|
|
function calculateStackLevels(events) {
|
|
const levels = /* @__PURE__ */ new Map();
|
|
const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime());
|
|
for (const event of sorted) {
|
|
let maxOverlappingLevel = -1;
|
|
for (const [id, level] of levels) {
|
|
const other = events.find((e) => e.id === id);
|
|
if (other && eventsOverlap(event, other)) {
|
|
maxOverlappingLevel = Math.max(maxOverlappingLevel, level);
|
|
}
|
|
}
|
|
levels.set(event.id, maxOverlappingLevel + 1);
|
|
}
|
|
return levels;
|
|
}
|
|
__name(calculateStackLevels, "calculateStackLevels");
|
|
function allocateColumns(events) {
|
|
const sorted = [...events].sort((a, b) => a.start.getTime() - b.start.getTime());
|
|
const columns = [];
|
|
for (const event of sorted) {
|
|
let placed = false;
|
|
for (const column of columns) {
|
|
const canFit = !column.some((e) => eventsOverlap(event, e));
|
|
if (canFit) {
|
|
column.push(event);
|
|
placed = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!placed) {
|
|
columns.push([event]);
|
|
}
|
|
}
|
|
return columns;
|
|
}
|
|
__name(allocateColumns, "allocateColumns");
|
|
function calculateColumnLayout(events, config) {
|
|
const thresholdMinutes = config.gridStartThresholdMinutes ?? 10;
|
|
const result = {
|
|
grids: [],
|
|
stacked: []
|
|
};
|
|
if (events.length === 0)
|
|
return result;
|
|
const overlapGroups = findOverlapGroups(events);
|
|
for (const overlapGroup of overlapGroups) {
|
|
if (overlapGroup.length === 1) {
|
|
result.stacked.push({
|
|
event: overlapGroup[0],
|
|
stackLevel: 0
|
|
});
|
|
continue;
|
|
}
|
|
const gridSubgroups = findGridCandidates(overlapGroup, thresholdMinutes);
|
|
const largestGridCandidate = gridSubgroups.reduce((max, g) => g.length > max.length ? g : max, gridSubgroups[0]);
|
|
if (largestGridCandidate.length === overlapGroup.length) {
|
|
const columns = allocateColumns(overlapGroup);
|
|
const earliest = overlapGroup.reduce((min, e) => e.start < min.start ? e : min, overlapGroup[0]);
|
|
const position = calculateEventPosition(earliest.start, earliest.end, config);
|
|
result.grids.push({
|
|
events: overlapGroup,
|
|
columns,
|
|
stackLevel: 0,
|
|
position: { top: position.top }
|
|
});
|
|
} else {
|
|
const levels = calculateStackLevels(overlapGroup);
|
|
for (const event of overlapGroup) {
|
|
result.stacked.push({
|
|
event,
|
|
stackLevel: levels.get(event.id) ?? 0
|
|
});
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
__name(calculateColumnLayout, "calculateColumnLayout");
|
|
|
|
// src/features/event/EventRenderer.ts
|
|
var _EventRenderer = class _EventRenderer {
|
|
constructor(eventService, dateService, gridConfig, eventBus) {
|
|
this.eventService = eventService;
|
|
this.dateService = dateService;
|
|
this.gridConfig = gridConfig;
|
|
this.eventBus = eventBus;
|
|
this.container = null;
|
|
this.setupListeners();
|
|
}
|
|
/**
|
|
* Setup listeners for drag-drop and update events
|
|
*/
|
|
setupListeners() {
|
|
this.eventBus.on(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, (e) => {
|
|
const payload = e.detail;
|
|
this.handleColumnChange(payload);
|
|
});
|
|
this.eventBus.on(CoreEvents.EVENT_DRAG_MOVE, (e) => {
|
|
const payload = e.detail;
|
|
this.updateDragTimestamp(payload);
|
|
});
|
|
this.eventBus.on(CoreEvents.EVENT_UPDATED, (e) => {
|
|
const payload = e.detail;
|
|
this.handleEventUpdated(payload);
|
|
});
|
|
this.eventBus.on(CoreEvents.EVENT_DRAG_END, (e) => {
|
|
const payload = e.detail;
|
|
this.handleDragEnd(payload);
|
|
});
|
|
this.eventBus.on(CoreEvents.EVENT_DRAG_LEAVE_HEADER, (e) => {
|
|
const payload = e.detail;
|
|
this.handleDragLeaveHeader(payload);
|
|
});
|
|
}
|
|
/**
|
|
* Handle EVENT_DRAG_END - remove element if dropped in header
|
|
*/
|
|
handleDragEnd(payload) {
|
|
if (payload.target === "header") {
|
|
const element = this.container?.querySelector(`swp-content-viewport swp-event[data-event-id="${payload.swpEvent.eventId}"]`);
|
|
element?.remove();
|
|
}
|
|
}
|
|
/**
|
|
* Handle header item leaving header - create swp-event in grid
|
|
*/
|
|
handleDragLeaveHeader(payload) {
|
|
if (payload.source !== "header")
|
|
return;
|
|
if (!payload.targetColumn || !payload.start || !payload.end)
|
|
return;
|
|
if (payload.element) {
|
|
payload.element.classList.add("drag-ghost");
|
|
payload.element.style.opacity = "0.3";
|
|
payload.element.style.pointerEvents = "none";
|
|
}
|
|
const event = {
|
|
id: payload.eventId,
|
|
title: payload.title || "",
|
|
description: "",
|
|
start: payload.start,
|
|
end: payload.end,
|
|
type: "customer",
|
|
allDay: false,
|
|
syncStatus: "pending"
|
|
};
|
|
const element = this.createEventElement(event);
|
|
let eventsLayer = payload.targetColumn.querySelector("swp-events-layer");
|
|
if (!eventsLayer) {
|
|
eventsLayer = document.createElement("swp-events-layer");
|
|
payload.targetColumn.appendChild(eventsLayer);
|
|
}
|
|
eventsLayer.appendChild(element);
|
|
element.classList.add("dragging");
|
|
}
|
|
/**
|
|
* Handle EVENT_UPDATED - re-render affected columns
|
|
*/
|
|
async handleEventUpdated(payload) {
|
|
if (payload.sourceColumnKey !== payload.targetColumnKey) {
|
|
await this.rerenderColumn(payload.sourceColumnKey);
|
|
}
|
|
await this.rerenderColumn(payload.targetColumnKey);
|
|
}
|
|
/**
|
|
* Re-render a single column with fresh data from IndexedDB
|
|
*/
|
|
async rerenderColumn(columnKey) {
|
|
const column = this.findColumn(columnKey);
|
|
if (!column)
|
|
return;
|
|
const date = column.dataset.date;
|
|
const resourceId = column.dataset.resourceId;
|
|
if (!date)
|
|
return;
|
|
const startDate = new Date(date);
|
|
const endDate = new Date(date);
|
|
endDate.setHours(23, 59, 59, 999);
|
|
const events = resourceId ? await this.eventService.getByResourceAndDateRange(resourceId, startDate, endDate) : await this.eventService.getByDateRange(startDate, endDate);
|
|
const timedEvents = events.filter(
|
|
(event) => !event.allDay && this.dateService.getDateKey(event.start) === date
|
|
);
|
|
let eventsLayer = column.querySelector("swp-events-layer");
|
|
if (!eventsLayer) {
|
|
eventsLayer = document.createElement("swp-events-layer");
|
|
column.appendChild(eventsLayer);
|
|
}
|
|
eventsLayer.innerHTML = "";
|
|
const layout = calculateColumnLayout(timedEvents, this.gridConfig);
|
|
layout.grids.forEach((grid) => {
|
|
const groupEl = this.renderGridGroup(grid);
|
|
eventsLayer.appendChild(groupEl);
|
|
});
|
|
layout.stacked.forEach((item) => {
|
|
const eventEl = this.renderStackedEvent(item.event, item.stackLevel);
|
|
eventsLayer.appendChild(eventEl);
|
|
});
|
|
}
|
|
/**
|
|
* Find a column element by columnKey
|
|
*/
|
|
findColumn(columnKey) {
|
|
if (!this.container)
|
|
return null;
|
|
return this.container.querySelector(`swp-day-column[data-column-key="${columnKey}"]`);
|
|
}
|
|
/**
|
|
* Handle event moving to a new column during drag
|
|
*/
|
|
handleColumnChange(payload) {
|
|
const eventsLayer = payload.newColumn.querySelector("swp-events-layer");
|
|
if (!eventsLayer)
|
|
return;
|
|
eventsLayer.appendChild(payload.element);
|
|
payload.element.style.top = `${payload.currentY}px`;
|
|
}
|
|
/**
|
|
* Update timestamp display during drag (snapped to grid)
|
|
*/
|
|
updateDragTimestamp(payload) {
|
|
const timeEl = payload.element.querySelector("swp-event-time");
|
|
if (!timeEl)
|
|
return;
|
|
const snappedY = snapToGrid(payload.currentY, this.gridConfig);
|
|
const minutesFromGridStart = pixelsToMinutes(snappedY, this.gridConfig);
|
|
const startMinutes = this.gridConfig.dayStartHour * 60 + minutesFromGridStart;
|
|
const height = parseFloat(payload.element.style.height) || this.gridConfig.hourHeight;
|
|
const durationMinutes = pixelsToMinutes(height, this.gridConfig);
|
|
const start = this.minutesToDate(startMinutes);
|
|
const end = this.minutesToDate(startMinutes + durationMinutes);
|
|
timeEl.textContent = this.dateService.formatTimeRange(start, end);
|
|
}
|
|
/**
|
|
* Convert minutes since midnight to a Date object (today)
|
|
*/
|
|
minutesToDate(minutes) {
|
|
const date = /* @__PURE__ */ new Date();
|
|
date.setHours(Math.floor(minutes / 60) % 24, minutes % 60, 0, 0);
|
|
return date;
|
|
}
|
|
/**
|
|
* Render events for visible dates into day columns
|
|
* @param container - Calendar container element
|
|
* @param filter - Filter with 'date' and optionally 'resource' arrays
|
|
* @param filterTemplate - Template for matching events to columns
|
|
*/
|
|
async render(container, filter, filterTemplate) {
|
|
this.container = container;
|
|
const visibleDates = filter["date"] || [];
|
|
if (visibleDates.length === 0)
|
|
return;
|
|
const startDate = new Date(visibleDates[0]);
|
|
const endDate = new Date(visibleDates[visibleDates.length - 1]);
|
|
endDate.setHours(23, 59, 59, 999);
|
|
const events = await this.eventService.getByDateRange(startDate, endDate);
|
|
const dayColumns = container.querySelector("swp-day-columns");
|
|
if (!dayColumns)
|
|
return;
|
|
const columns = dayColumns.querySelectorAll("swp-day-column");
|
|
columns.forEach((column) => {
|
|
const columnEl = column;
|
|
const columnEvents = events.filter((event) => filterTemplate.matches(event, columnEl));
|
|
let eventsLayer = column.querySelector("swp-events-layer");
|
|
if (!eventsLayer) {
|
|
eventsLayer = document.createElement("swp-events-layer");
|
|
column.appendChild(eventsLayer);
|
|
}
|
|
eventsLayer.innerHTML = "";
|
|
const timedEvents = columnEvents.filter((event) => !event.allDay);
|
|
const layout = calculateColumnLayout(timedEvents, this.gridConfig);
|
|
layout.grids.forEach((grid) => {
|
|
const groupEl = this.renderGridGroup(grid);
|
|
eventsLayer.appendChild(groupEl);
|
|
});
|
|
layout.stacked.forEach((item) => {
|
|
const eventEl = this.renderStackedEvent(item.event, item.stackLevel);
|
|
eventsLayer.appendChild(eventEl);
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Create a single event element
|
|
*
|
|
* CLEAN approach:
|
|
* - Only data-id for lookup
|
|
* - Visible content in innerHTML only
|
|
*/
|
|
createEventElement(event) {
|
|
const element = document.createElement("swp-event");
|
|
element.dataset.eventId = event.id;
|
|
if (event.resourceId) {
|
|
element.dataset.resourceId = event.resourceId;
|
|
}
|
|
const position = calculateEventPosition(event.start, event.end, this.gridConfig);
|
|
element.style.top = `${position.top}px`;
|
|
element.style.height = `${position.height}px`;
|
|
const colorClass = this.getColorClass(event);
|
|
if (colorClass) {
|
|
element.classList.add(colorClass);
|
|
}
|
|
element.innerHTML = `
|
|
<swp-event-time>${this.dateService.formatTimeRange(event.start, event.end)}</swp-event-time>
|
|
<swp-event-title>${this.escapeHtml(event.title)}</swp-event-title>
|
|
${event.description ? `<swp-event-description>${this.escapeHtml(event.description)}</swp-event-description>` : ""}
|
|
`;
|
|
return element;
|
|
}
|
|
/**
|
|
* Get color class based on metadata.color or event type
|
|
*/
|
|
getColorClass(event) {
|
|
if (event.metadata?.color) {
|
|
return `is-${event.metadata.color}`;
|
|
}
|
|
const typeColors = {
|
|
"customer": "is-blue",
|
|
"vacation": "is-green",
|
|
"break": "is-amber",
|
|
"meeting": "is-purple",
|
|
"blocked": "is-red"
|
|
};
|
|
return typeColors[event.type] || "is-blue";
|
|
}
|
|
/**
|
|
* Escape HTML to prevent XSS
|
|
*/
|
|
escapeHtml(text) {
|
|
const div = document.createElement("div");
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
}
|
|
/**
|
|
* Render a GRID group with side-by-side columns
|
|
* Used when multiple events start at the same time
|
|
*/
|
|
renderGridGroup(layout) {
|
|
const group = document.createElement("swp-event-group");
|
|
group.classList.add(`cols-${layout.columns.length}`);
|
|
group.style.top = `${layout.position.top}px`;
|
|
if (layout.stackLevel > 0) {
|
|
group.style.marginLeft = `${layout.stackLevel * 15}px`;
|
|
group.style.zIndex = `${100 + layout.stackLevel}`;
|
|
}
|
|
let maxBottom = 0;
|
|
for (const event of layout.events) {
|
|
const pos = calculateEventPosition(event.start, event.end, this.gridConfig);
|
|
const eventBottom = pos.top + pos.height;
|
|
if (eventBottom > maxBottom)
|
|
maxBottom = eventBottom;
|
|
}
|
|
const groupHeight = maxBottom - layout.position.top;
|
|
group.style.height = `${groupHeight}px`;
|
|
layout.columns.forEach((columnEvents) => {
|
|
const wrapper = document.createElement("div");
|
|
wrapper.style.position = "relative";
|
|
columnEvents.forEach((event) => {
|
|
const eventEl = this.createEventElement(event);
|
|
const pos = calculateEventPosition(event.start, event.end, this.gridConfig);
|
|
eventEl.style.top = `${pos.top - layout.position.top}px`;
|
|
eventEl.style.position = "absolute";
|
|
eventEl.style.left = "0";
|
|
eventEl.style.right = "0";
|
|
wrapper.appendChild(eventEl);
|
|
});
|
|
group.appendChild(wrapper);
|
|
});
|
|
return group;
|
|
}
|
|
/**
|
|
* Render a STACKED event with margin-left offset
|
|
* Used for overlapping events that don't start at the same time
|
|
*/
|
|
renderStackedEvent(event, stackLevel) {
|
|
const element = this.createEventElement(event);
|
|
element.dataset.stackLink = JSON.stringify({ stackLevel });
|
|
if (stackLevel > 0) {
|
|
element.style.marginLeft = `${stackLevel * 15}px`;
|
|
element.style.zIndex = `${100 + stackLevel}`;
|
|
}
|
|
return element;
|
|
}
|
|
};
|
|
__name(_EventRenderer, "EventRenderer");
|
|
var EventRenderer = _EventRenderer;
|
|
|
|
// src/core/BaseGroupingRenderer.ts
|
|
var _BaseGroupingRenderer = class _BaseGroupingRenderer {
|
|
/**
|
|
* Main render method - handles common logic
|
|
*/
|
|
async render(context) {
|
|
const allowedIds = context.filter[this.type] || [];
|
|
if (allowedIds.length === 0)
|
|
return;
|
|
const entities = await this.getEntities(allowedIds);
|
|
const dateCount = context.filter["date"]?.length || 1;
|
|
const childIds = context.childType ? context.filter[context.childType] || [] : [];
|
|
for (const entity of entities) {
|
|
const entityChildIds = context.parentChildMap?.[entity.id] || [];
|
|
const childCount = entityChildIds.filter((id) => childIds.includes(id)).length;
|
|
const colspan = childCount * dateCount;
|
|
const header = document.createElement(this.config.elementTag);
|
|
header.dataset[this.config.idAttribute] = entity.id;
|
|
header.style.setProperty(this.config.colspanVar, String(colspan));
|
|
this.renderHeader(entity, header, context);
|
|
context.headerContainer.appendChild(header);
|
|
}
|
|
}
|
|
/**
|
|
* Override this method for custom header rendering
|
|
* Default: just sets textContent to display name
|
|
*/
|
|
renderHeader(entity, header, _context) {
|
|
header.textContent = this.getDisplayName(entity);
|
|
}
|
|
/**
|
|
* Helper to render a single entity header.
|
|
* Can be used by subclasses that override render() but want consistent header creation.
|
|
*/
|
|
createHeader(entity, context) {
|
|
const header = document.createElement(this.config.elementTag);
|
|
header.dataset[this.config.idAttribute] = entity.id;
|
|
this.renderHeader(entity, header, context);
|
|
return header;
|
|
}
|
|
};
|
|
__name(_BaseGroupingRenderer, "BaseGroupingRenderer");
|
|
var BaseGroupingRenderer = _BaseGroupingRenderer;
|
|
|
|
// src/features/resource/ResourceRenderer.ts
|
|
var _ResourceRenderer = class _ResourceRenderer extends BaseGroupingRenderer {
|
|
constructor(resourceService) {
|
|
super();
|
|
this.resourceService = resourceService;
|
|
this.type = "resource";
|
|
this.config = {
|
|
elementTag: "swp-resource-header",
|
|
idAttribute: "resourceId",
|
|
colspanVar: "--resource-cols"
|
|
};
|
|
}
|
|
getEntities(ids) {
|
|
return this.resourceService.getByIds(ids);
|
|
}
|
|
getDisplayName(entity) {
|
|
return entity.displayName;
|
|
}
|
|
/**
|
|
* Override render to handle:
|
|
* 1. Special ordering when parentChildMap exists (resources grouped by parent)
|
|
* 2. Different colspan calculation (just dateCount, not childCount * dateCount)
|
|
*/
|
|
async render(context) {
|
|
const resourceIds = context.filter["resource"] || [];
|
|
const dateCount = context.filter["date"]?.length || 1;
|
|
let orderedResourceIds;
|
|
if (context.parentChildMap) {
|
|
orderedResourceIds = [];
|
|
for (const childIds of Object.values(context.parentChildMap)) {
|
|
for (const childId of childIds) {
|
|
if (resourceIds.includes(childId)) {
|
|
orderedResourceIds.push(childId);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
orderedResourceIds = resourceIds;
|
|
}
|
|
const resources = await this.getEntities(orderedResourceIds);
|
|
const resourceMap = new Map(resources.map((r) => [r.id, r]));
|
|
for (const resourceId of orderedResourceIds) {
|
|
const resource = resourceMap.get(resourceId);
|
|
if (!resource)
|
|
continue;
|
|
const header = this.createHeader(resource, context);
|
|
header.style.gridColumn = `span ${dateCount}`;
|
|
context.headerContainer.appendChild(header);
|
|
}
|
|
}
|
|
};
|
|
__name(_ResourceRenderer, "ResourceRenderer");
|
|
var ResourceRenderer = _ResourceRenderer;
|
|
|
|
// src/features/team/TeamRenderer.ts
|
|
var _TeamRenderer = class _TeamRenderer extends BaseGroupingRenderer {
|
|
constructor(teamService) {
|
|
super();
|
|
this.teamService = teamService;
|
|
this.type = "team";
|
|
this.config = {
|
|
elementTag: "swp-team-header",
|
|
idAttribute: "teamId",
|
|
colspanVar: "--team-cols"
|
|
};
|
|
}
|
|
getEntities(ids) {
|
|
return this.teamService.getByIds(ids);
|
|
}
|
|
getDisplayName(entity) {
|
|
return entity.name;
|
|
}
|
|
};
|
|
__name(_TeamRenderer, "TeamRenderer");
|
|
var TeamRenderer = _TeamRenderer;
|
|
|
|
// src/features/timeaxis/TimeAxisRenderer.ts
|
|
var _TimeAxisRenderer = class _TimeAxisRenderer {
|
|
render(container, startHour = 6, endHour = 20) {
|
|
container.innerHTML = "";
|
|
for (let hour = startHour; hour <= endHour; hour++) {
|
|
const marker = document.createElement("swp-hour-marker");
|
|
marker.textContent = `${hour.toString().padStart(2, "0")}:00`;
|
|
container.appendChild(marker);
|
|
}
|
|
}
|
|
};
|
|
__name(_TimeAxisRenderer, "TimeAxisRenderer");
|
|
var TimeAxisRenderer = _TimeAxisRenderer;
|
|
export {
|
|
CalendarOrchestrator,
|
|
DateRenderer,
|
|
DateService,
|
|
EventRenderer,
|
|
NavigationAnimator,
|
|
ResourceRenderer,
|
|
TeamRenderer,
|
|
TimeAxisRenderer,
|
|
buildPipeline
|
|
};
|
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vbm9kZV9tb2R1bGVzL2RheWpzL2RheWpzLm1pbi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvZGF5anMvcGx1Z2luL3V0Yy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvZGF5anMvcGx1Z2luL3RpbWV6b25lLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9kYXlqcy9wbHVnaW4vaXNvV2Vlay5qcyIsICIuLi8uLi9zcmMvY29yZS9SZW5kZXJCdWlsZGVyLnRzIiwgIi4uLy4uL3NyYy9jb3JlL0ZpbHRlclRlbXBsYXRlLnRzIiwgIi4uLy4uL3NyYy9jb3JlL0NhbGVuZGFyT3JjaGVzdHJhdG9yLnRzIiwgIi4uLy4uL3NyYy9jb3JlL05hdmlnYXRpb25BbmltYXRvci50cyIsICIuLi8uLi9zcmMvZmVhdHVyZXMvZGF0ZS9EYXRlUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL2NvcmUvRGF0ZVNlcnZpY2UudHMiLCAiLi4vLi4vc3JjL3V0aWxzL1Bvc2l0aW9uVXRpbHMudHMiLCAiLi4vLi4vc3JjL2NvbnN0YW50cy9Db3JlRXZlbnRzLnRzIiwgIi4uLy4uL3NyYy9mZWF0dXJlcy9ldmVudC9FdmVudExheW91dEVuZ2luZS50cyIsICIuLi8uLi9zcmMvZmVhdHVyZXMvZXZlbnQvRXZlbnRSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvY29yZS9CYXNlR3JvdXBpbmdSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvZmVhdHVyZXMvcmVzb3VyY2UvUmVzb3VyY2VSZW5kZXJlci50cyIsICIuLi8uLi9zcmMvZmVhdHVyZXMvdGVhbS9UZWFtUmVuZGVyZXIudHMiLCAiLi4vLi4vc3JjL2ZlYXR1cmVzL3RpbWVheGlzL1RpbWVBeGlzUmVuZGVyZXIudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKGUpOih0PVwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6dHx8c2VsZikuZGF5anM9ZSgpfSh0aGlzLChmdW5jdGlvbigpe1widXNlIHN0cmljdFwiO3ZhciB0PTFlMyxlPTZlNCxuPTM2ZTUscj1cIm1pbGxpc2Vjb25kXCIsaT1cInNlY29uZFwiLHM9XCJtaW51dGVcIix1PVwiaG91clwiLGE9XCJkYXlcIixvPVwid2Vla1wiLGM9XCJtb250aFwiLGY9XCJxdWFydGVyXCIsaD1cInllYXJcIixkPVwiZGF0ZVwiLGw9XCJJbnZhbGlkIERhdGVcIiwkPS9eKFxcZHs0fSlbLS9dPyhcXGR7MSwyfSk/Wy0vXT8oXFxkezAsMn0pW1R0XFxzXSooXFxkezEsMn0pPzo/KFxcZHsxLDJ9KT86PyhcXGR7MSwyfSk/Wy46XT8oXFxkKyk/JC8seT0vXFxbKFteXFxdXSspXXxZezEsNH18TXsxLDR9fER7MSwyfXxkezEsNH18SHsxLDJ9fGh7MSwyfXxhfEF8bXsxLDJ9fHN7MSwyfXxaezEsMn18U1NTL2csTT17bmFtZTpcImVuXCIsd2Vla2RheXM6XCJTdW5kYXlfTW9uZGF5X1R1ZXNkYXlfV2VkbmVzZGF5X1RodXJzZGF5X0ZyaWRheV9TYXR1cmRheVwiLnNwbGl0KFwiX1wiKSxtb250aHM6XCJKYW51YXJ5X0ZlYnJ1YXJ5X01hcmNoX0FwcmlsX01heV9KdW5lX0p1bHlfQXVndXN0X1NlcHRlbWJlcl9PY3RvYmVyX05vdmVtYmVyX0RlY2VtYmVyXCIuc3BsaXQoXCJfXCIpLG9yZGluYWw6ZnVuY3Rpb24odCl7dmFyIGU9W1widGhcIixcInN0XCIsXCJuZFwiLFwicmRcIl0sbj10JTEwMDtyZXR1cm5cIltcIit0KyhlWyhuLTIwKSUxMF18fGVbbl18fGVbMF0pK1wiXVwifX0sbT1mdW5jdGlvbih0LGUsbil7dmFyIHI9U3RyaW5nKHQpO3JldHVybiFyfHxyLmxlbmd0aD49ZT90OlwiXCIrQXJyYXkoZSsxLXIubGVuZ3RoKS5qb2luKG4pK3R9LHY9e3M6bSx6OmZ1bmN0aW9uKHQpe3ZhciBlPS10LnV0Y09mZnNldCgpLG49TWF0aC5hYnMoZSkscj1NYXRoLmZsb29yKG4vNjApLGk9biU2MDtyZXR1cm4oZTw9MD9cIitcIjpcIi1cIikrbShyLDIsXCIwXCIpK1wiOlwiK20oaSwyLFwiMFwiKX0sbTpmdW5jdGlvbiB0KGUsbil7aWYoZS5kYXRlKCk8bi5kYXRlKCkpcmV0dXJuLXQobixlKTt2YXIgcj0xMioobi55ZWFyKCktZS55ZWFyKCkpKyhuLm1vbnRoKCktZS5tb250aCgpKSxpPWUuY2xvbmUoKS5hZGQocixjKSxzPW4taTwwLHU9ZS5jbG9uZSgpLmFkZChyKyhzPy0xOjEpLGMpO3JldHVybisoLShyKyhuLWkpLyhzP2ktdTp1LWkpKXx8MCl9LGE6ZnVuY3Rpb24odCl7cmV0dXJuIHQ8MD9NYXRoLmNlaWwodCl8fDA6TWF0aC5mbG9vcih0KX0scDpmdW5jdGlvbih0KXtyZXR1cm57TTpjLHk6aCx3Om8sZDphLEQ6ZCxoOnUsbTpzLHM6aSxtczpyLFE6Zn1bdF18fFN0cmluZyh0fHxcIlwiKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL3MkLyxcIlwiKX0sdTpmdW5jdGlvbih0KXtyZXR1cm4gdm9pZCAwPT09dH19LGc9XCJlblwiLEQ9e307RFtnXT1NO3ZhciBwPVwiJGlzRGF5anNPYmplY3RcIixTPWZ1bmN0aW9uKHQpe3JldHVybiB0IGluc3RhbmNlb2YgX3x8ISghdHx8IXRbcF0pfSx3PWZ1bmN0aW9uIHQoZSxuLHIpe3ZhciBpO2lmKCFlKXJldHVybiBnO2lmKFwic3RyaW5nXCI9PXR5cGVvZiBlKXt2YXIgcz1lLnRvTG93ZXJDYXNlKCk7RFtzXSYmKGk9cyksbiYmKERbc109bixpPXMpO3ZhciB1PWUuc3BsaXQoXCItXCIpO2lmKCFpJiZ1Lmxlbmd0aD4xKXJldHVybiB0KHVbMF0pfWVsc2V7dmFyIGE9ZS5uYW1lO0RbYV09ZSxpPWF9cmV0dXJuIXImJmkmJihnPWkpLGl8fCFyJiZnfSxPPWZ1bmN0aW9uKHQsZSl7aWYoUyh0KSlyZXR1cm4gdC5jbG9uZSgpO3ZhciBuPVwib2JqZWN0XCI9PXR5cGVvZiBlP2U6e307cmV0dXJuIG4uZGF0ZT10LG4uYXJncz1hcmd1bWVudHMsbmV3IF8obil9LGI9djtiLmw9dyxiLmk9UyxiLnc9ZnVuY3Rpb24odCxlKXtyZXR1cm4gTyh0LHtsb2NhbGU6ZS4kTCx1dGM6ZS4kdSx4OmUuJHgsJG9mZnNldDplLiRvZmZzZXR9KX07dmFyIF89ZnVuY3Rpb24oKXtmdW5jdGlvbiBNKHQpe3RoaXMuJEw9dyh0LmxvY2FsZSxudWxsLCEwKSx0aGlzLnBhcnNlKHQpLHRoaXMuJHg9dGhpcy4keHx8dC54fHx7fSx0aGlzW3BdPSEwfXZhciBtPU0ucHJvdG90eXBlO3JldHVybiBtLnBhcnNlPWZ1bmN0aW9uKHQpe3RoaXMuJGQ9ZnVuY3Rpb24odCl7dmFyIGU9dC5kYXRlLG49dC51dGM7aWYobnVsbD09PWUpcmV0dXJuIG5ldyBEYXRlKE5hTik7aWYoYi51KGUpKXJldHVybiBuZXcgRGF0ZTtpZihlIGluc3RhbmNlb2YgRGF0ZSlyZXR1cm4gbmV3IERhdGUoZSk7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGUmJiEvWiQvaS50ZXN0KGUpKXt2YXIgcj1lLm1hdGNoKCQpO2lmKHIpe3ZhciBpPXJbMl0tMXx8MCxzPShyWzddfHxcIjBcIikuc3Vic3RyaW5nKDAsMyk7cmV0dXJuIG4/bmV3IERhdGUoRGF0ZS5VVEMoclsxXSxpLHJbM118fDEscls0XXx8MCxyWzVdfHwwLHJbNl18fDAscykpOm5ldyBEYXRlKHJbMV0saSxyWzNdfHwxLHJbNF18fDAscls1XXx8MCxyWzZdfHwwLHMpfX1yZXR1cm4gbmV3IERhdGUoZSl9KHQpLHRoaXMuaW5pdCgpfSxtLmluaXQ9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLiRkO3RoaXMuJHk9dC5nZXRGdWxsWWVhcigpLHRoaXMuJE09dC5nZXRNb250aCgpLHRoaXMuJEQ9dC5nZXREYXRlKCksdGhpcy4kVz10LmdldERheSgpLHRoaXMuJEg9dC5nZXRIb3VycygpLHRoaXMuJG09dC5nZXRNaW51dGVzKCksdGhpcy4kcz10LmdldFNlY29uZHMoKSx0aGlzLiRtcz10LmdldE1pbGxpc2Vjb25kcygpfSxtLiR1dGlscz1mdW5jdGlvbigpe3JldHVybiBifSxtLmlzVmFsaWQ9ZnVuY3Rpb24oKXtyZXR1cm4hKHRoaXMuJGQudG9TdHJpbmcoKT09PWwpfSxtLmlzU2FtZT1mdW5jdGlvbih0LGUpe3ZhciBuPU8odCk7cmV0dXJuIHRoaXMuc3RhcnRPZihlKTw9biYmbjw9dGhpcy5lbmRPZihlKX0sbS5pc0FmdGVyPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIE8odCk8dGhpcy5zdGFydE9mKGUpfSxtLmlzQmVmb3JlPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMuZW5kT2YoZSk8Tyh0KX0sbS4kZz1mdW5jdGlvbih0LGUsbil7cmV0dXJuIGIudSh0KT90aGlzW2VdOnRoaXMuc2V0KG4sdCl9LG0udW5peD1mdW5jdGlvbigpe3JldHVybiBNYXRoLmZsb29yKHRoaXMudmFsdWVPZigpLzFlMyl9LG0udmFsdWVPZj1mdW5jdGlvbigpe3JldHVybiB0aGlzLiRkLmdldFRpbWUoKX0sbS5zdGFydE9mPWZ1bmN0aW9uKHQsZSl7dmFyIG49dGhpcyxyPSEhYi51KGUpfHxlLGY9Yi5wKHQpLGw9ZnVuY3Rpb24odCxlKXt2YXIgaT1iLncobi4kdT9EYXRlLlVUQyhuLiR5LGUsdCk6bmV3IERhdGUobi4keSxlLHQpLG4pO3JldHVybiByP2k6aS5lbmRPZihhKX0sJD1mdW5jdGlvbih0LGUpe3JldHVybiBiLncobi50b0RhdGUoKVt0XS5hcHBseShuLnRvRGF0ZShcInNcIiksKHI/WzAsMCwwLDBdOlsyMyw1OSw1OSw5OTldKS5zbGljZShlKSksbil9LHk9dGhpcy4kVyxNPXRoaXMuJE0sbT10aGlzLiRELHY9XCJzZXRcIisodGhpcy4kdT9cIlVUQ1wiOlwiXCIpO3N3aXRjaChmKXtjYXNlIGg6cmV0dXJuIHI/bCgxLDApOmwoMzEsMTEpO2Nhc2UgYzpyZXR1cm4gcj9sKDEsTSk6bCgwLE0rMSk7Y2FzZSBvOnZhciBnPXRoaXMuJGxvY2FsZSgpLndlZWtTdGFydHx8MCxEPSh5PGc/eSs3OnkpLWc7cmV0dXJuIGwocj9tLUQ6bSsoNi1EKSxNKTtjYXNlIGE6Y2FzZSBkOnJldHVybiAkKHYrXCJIb3Vyc1wiLDApO2Nhc2UgdTpyZXR1cm4gJCh2K1wiTWludXRlc1wiLDEpO2Nhc2UgczpyZXR1cm4gJCh2K1wiU2Vjb25kc1wiLDIpO2Nhc2UgaTpyZXR1cm4gJCh2K1wiTWlsbGlzZWNvbmRzXCIsMyk7ZGVmYXVsdDpyZXR1cm4gdGhpcy5jbG9uZSgpfX0sbS5lbmRPZj1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5zdGFydE9mKHQsITEpfSxtLiRzZXQ9ZnVuY3Rpb24odCxlKXt2YXIgbixvPWIucCh0KSxmPVwic2V0XCIrKHRoaXMuJHU/XCJVVENcIjpcIlwiKSxsPShuPXt9LG5bYV09ZitcIkRhdGVcIixuW2RdPWYrXCJEYXRlXCIsbltjXT1mK1wiTW9udGhcIixuW2hdPWYrXCJGdWxsWWVhclwiLG5bdV09ZitcIkhvdXJzXCIsbltzXT1mK1wiTWludXRlc1wiLG5baV09ZitcIlNlY29uZHNcIixuW3JdPWYrXCJNaWxsaXNlY29uZHNcIixuKVtvXSwkPW89PT1hP3RoaXMuJEQrKGUtdGhpcy4kVyk6ZTtpZihvPT09Y3x8bz09PWgpe3ZhciB5PXRoaXMuY2xvbmUoKS5zZXQoZCwxKTt5LiRkW2xdKCQpLHkuaW5pdCgpLHRoaXMuJGQ9eS5zZXQoZCxNYXRoLm1pbih0aGlzLiRELHkuZGF5c0luTW9udGgoKSkpLiRkfWVsc2UgbCYmdGhpcy4kZFtsXSgkKTtyZXR1cm4gdGhpcy5pbml0KCksdGhpc30sbS5zZXQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5jbG9uZSgpLiRzZXQodCxlKX0sbS5nZXQ9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXNbYi5wKHQpXSgpfSxtLmFkZD1mdW5jdGlvbihyLGYpe3ZhciBkLGw9dGhpcztyPU51bWJlcihyKTt2YXIgJD1iLnAoZikseT1mdW5jdGlvbih0KXt2YXIgZT1PKGwpO3JldHVybiBiLncoZS5kYXRlKGUuZGF0ZSgpK01hdGgucm91bmQodCpyKSksbCl9O2lmKCQ9PT1jKXJldHVybiB0aGlzLnNldChjLHRoaXMuJE0rcik7aWYoJD09PWgpcmV0dXJuIHRoaXMuc2V0KGgsdGhpcy4keStyKTtpZigkPT09YSlyZXR1cm4geSgxKTtpZigkPT09bylyZXR1cm4geSg3KTt2YXIgTT0oZD17fSxkW3NdPWUsZFt1XT1uLGRbaV09dCxkKVskXXx8MSxtPXRoaXMuJGQuZ2V0VGltZSgpK3IqTTtyZXR1cm4gYi53KG0sdGhpcyl9LG0uc3VidHJhY3Q9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5hZGQoLTEqdCxlKX0sbS5mb3JtYXQ9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcyxuPXRoaXMuJGxvY2FsZSgpO2lmKCF0aGlzLmlzVmFsaWQoKSlyZXR1cm4gbi5pbnZhbGlkRGF0ZXx8bDt2YXIgcj10fHxcIllZWVktTU0tRERUSEg6bW06c3NaXCIsaT1iLnoodGhpcykscz10aGlzLiRILHU9dGhpcy4kbSxhPXRoaXMuJE0sbz1uLndlZWtkYXlzLGM9bi5tb250aHMsZj1uLm1lcmlkaWVtLGg9ZnVuY3Rpb24odCxuLGkscyl7cmV0dXJuIHQmJih0W25dfHx0KGUscikpfHxpW25dLnNsaWNlKDAscyl9LGQ9ZnVuY3Rpb24odCl7cmV0dXJuIGIucyhzJTEyfHwxMix0LFwiMFwiKX0sJD1mfHxmdW5jdGlvbih0LGUsbil7dmFyIHI9dDwxMj9cIkFNXCI6XCJQTVwiO3JldHVybiBuP3IudG9Mb3dlckNhc2UoKTpyfTtyZXR1cm4gci5yZXBsYWNlKHksKGZ1bmN0aW9uKHQscil7cmV0dXJuIHJ8fGZ1bmN0aW9uKHQpe3N3aXRjaCh0KXtjYXNlXCJZWVwiOnJldHVybiBTdHJpbmcoZS4keSkuc2xpY2UoLTIpO2Nhc2VcIllZWVlcIjpyZXR1cm4gYi5zKGUuJHksNCxcIjBcIik7Y2FzZVwiTVwiOnJldHVybiBhKzE7Y2FzZVwiTU1cIjpyZXR1cm4gYi5zKGErMSwyLFwiMFwiKTtjYXNlXCJNTU1cIjpyZXR1cm4gaChuLm1vbnRoc1Nob3J0LGEsYywzKTtjYXNlXCJNTU1NXCI6cmV0dXJuIGgoYyxhKTtjYXNlXCJEXCI6cmV0dXJuIGUuJEQ7Y2FzZVwiRERcIjpyZXR1cm4gYi5zKGUuJEQsMixcIjBcIik7Y2FzZVwiZFwiOnJldHVybiBTdHJpbmcoZS4kVyk7Y2FzZVwiZGRcIjpyZXR1cm4gaChuLndlZWtkYXlzTWluLGUuJFcsbywyKTtjYXNlXCJkZGRcIjpyZXR1cm4gaChuLndlZWtkYXlzU2hvcnQsZS4kVyxvLDMpO2Nhc2VcImRkZGRcIjpyZXR1cm4gb1tlLiRXXTtjYXNlXCJIXCI6cmV0dXJuIFN0cmluZyhzKTtjYXNlXCJISFwiOnJldHVybiBiLnMocywyLFwiMFwiKTtjYXNlXCJoXCI6cmV0dXJuIGQoMSk7Y2FzZVwiaGhcIjpyZXR1cm4gZCgyKTtjYXNlXCJhXCI6cmV0dXJuICQocyx1LCEwKTtjYXNlXCJBXCI6cmV0dXJuICQocyx1LCExKTtjYXNlXCJtXCI6cmV0dXJuIFN0cmluZyh1KTtjYXNlXCJtbVwiOnJldHVybiBiLnModSwyLFwiMFwiKTtjYXNlXCJzXCI6cmV0dXJuIFN0cmluZyhlLiRzKTtjYXNlXCJzc1wiOnJldHVybiBiLnMoZS4kcywyLFwiMFwiKTtjYXNlXCJTU1NcIjpyZXR1cm4gYi5zKGUuJG1zLDMsXCIwXCIpO2Nhc2VcIlpcIjpyZXR1cm4gaX1yZXR1cm4gbnVsbH0odCl8fGkucmVwbGFjZShcIjpcIixcIlwiKX0pKX0sbS51dGNPZmZzZXQ9ZnVuY3Rpb24oKXtyZXR1cm4gMTUqLU1hdGgucm91bmQodGhpcy4kZC5nZXRUaW1lem9uZU9mZnNldCgpLzE1KX0sbS5kaWZmPWZ1bmN0aW9uKHIsZCxsKXt2YXIgJCx5PXRoaXMsTT1iLnAoZCksbT1PKHIpLHY9KG0udXRjT2Zmc2V0KCktdGhpcy51dGNPZmZzZXQoKSkqZSxnPXRoaXMtbSxEPWZ1bmN0aW9uKCl7cmV0dXJuIGIubSh5LG0pfTtzd2l0Y2goTSl7Y2FzZSBoOiQ9RCgpLzEyO2JyZWFrO2Nhc2UgYzokPUQoKTticmVhaztjYXNlIGY6JD1EKCkvMzticmVhaztjYXNlIG86JD0oZy12KS82MDQ4ZTU7YnJlYWs7Y2FzZSBhOiQ9KGctdikvODY0ZTU7YnJlYWs7Y2FzZSB1OiQ9Zy9uO2JyZWFrO2Nhc2UgczokPWcvZTticmVhaztjYXNlIGk6JD1nL3Q7YnJlYWs7ZGVmYXVsdDokPWd9cmV0dXJuIGw/JDpiLmEoJCl9LG0uZGF5c0luTW9udGg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lbmRPZihjKS4kRH0sbS4kbG9jYWxlPWZ1bmN0aW9uKCl7cmV0dXJuIERbdGhpcy4kTF19LG0ubG9jYWxlPWZ1bmN0aW9uKHQsZSl7aWYoIXQpcmV0dXJuIHRoaXMuJEw7dmFyIG49dGhpcy5jbG9uZSgpLHI9dyh0LGUsITApO3JldHVybiByJiYobi4kTD1yKSxufSxtLmNsb25lPWZ1bmN0aW9uKCl7cmV0dXJuIGIudyh0aGlzLiRkLHRoaXMpfSxtLnRvRGF0ZT1mdW5jdGlvbigpe3JldHVybiBuZXcgRGF0ZSh0aGlzLnZhbHVlT2YoKSl9LG0udG9KU09OPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaXNWYWxpZCgpP3RoaXMudG9JU09TdHJpbmcoKTpudWxsfSxtLnRvSVNPU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuJGQudG9JU09TdHJpbmcoKX0sbS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLiRkLnRvVVRDU3RyaW5nKCl9LE19KCksaz1fLnByb3RvdHlwZTtyZXR1cm4gTy5wcm90b3R5cGU9ayxbW1wiJG1zXCIscl0sW1wiJHNcIixpXSxbXCIkbVwiLHNdLFtcIiRIXCIsdV0sW1wiJFdcIixhXSxbXCIkTVwiLGNdLFtcIiR5XCIsaF0sW1wiJERcIixkXV0uZm9yRWFjaCgoZnVuY3Rpb24odCl7a1t0WzFdXT1mdW5jdGlvbihlKXtyZXR1cm4gdGhpcy4kZyhlLHRbMF0sdFsxXSl9fSkpLE8uZXh0ZW5kPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQuJGl8fCh0KGUsXyxPKSx0LiRpPSEwKSxPfSxPLmxvY2FsZT13LE8uaXNEYXlqcz1TLE8udW5peD1mdW5jdGlvbih0KXtyZXR1cm4gTygxZTMqdCl9LE8uZW49RFtnXSxPLkxzPUQsTy5wPXt9LE99KSk7IiwgIiFmdW5jdGlvbih0LGkpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWkoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKGkpOih0PVwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6dHx8c2VsZikuZGF5anNfcGx1Z2luX3V0Yz1pKCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHQ9XCJtaW51dGVcIixpPS9bKy1dXFxkXFxkKD86Oj9cXGRcXGQpPy9nLGU9LyhbKy1dfFxcZFxcZCkvZztyZXR1cm4gZnVuY3Rpb24ocyxmLG4pe3ZhciB1PWYucHJvdG90eXBlO24udXRjPWZ1bmN0aW9uKHQpe3ZhciBpPXtkYXRlOnQsdXRjOiEwLGFyZ3M6YXJndW1lbnRzfTtyZXR1cm4gbmV3IGYoaSl9LHUudXRjPWZ1bmN0aW9uKGkpe3ZhciBlPW4odGhpcy50b0RhdGUoKSx7bG9jYWxlOnRoaXMuJEwsdXRjOiEwfSk7cmV0dXJuIGk/ZS5hZGQodGhpcy51dGNPZmZzZXQoKSx0KTplfSx1LmxvY2FsPWZ1bmN0aW9uKCl7cmV0dXJuIG4odGhpcy50b0RhdGUoKSx7bG9jYWxlOnRoaXMuJEwsdXRjOiExfSl9O3ZhciByPXUucGFyc2U7dS5wYXJzZT1mdW5jdGlvbih0KXt0LnV0YyYmKHRoaXMuJHU9ITApLHRoaXMuJHV0aWxzKCkudSh0LiRvZmZzZXQpfHwodGhpcy4kb2Zmc2V0PXQuJG9mZnNldCksci5jYWxsKHRoaXMsdCl9O3ZhciBvPXUuaW5pdDt1LmluaXQ9ZnVuY3Rpb24oKXtpZih0aGlzLiR1KXt2YXIgdD10aGlzLiRkO3RoaXMuJHk9dC5nZXRVVENGdWxsWWVhcigpLHRoaXMuJE09dC5nZXRVVENNb250aCgpLHRoaXMuJEQ9dC5nZXRVVENEYXRlKCksdGhpcy4kVz10LmdldFVUQ0RheSgpLHRoaXMuJEg9dC5nZXRVVENIb3VycygpLHRoaXMuJG09dC5nZXRVVENNaW51dGVzKCksdGhpcy4kcz10LmdldFVUQ1NlY29uZHMoKSx0aGlzLiRtcz10LmdldFVUQ01pbGxpc2Vjb25kcygpfWVsc2Ugby5jYWxsKHRoaXMpfTt2YXIgYT11LnV0Y09mZnNldDt1LnV0Y09mZnNldD1mdW5jdGlvbihzLGYpe3ZhciBuPXRoaXMuJHV0aWxzKCkudTtpZihuKHMpKXJldHVybiB0aGlzLiR1PzA6bih0aGlzLiRvZmZzZXQpP2EuY2FsbCh0aGlzKTp0aGlzLiRvZmZzZXQ7aWYoXCJzdHJpbmdcIj09dHlwZW9mIHMmJihzPWZ1bmN0aW9uKHQpe3ZvaWQgMD09PXQmJih0PVwiXCIpO3ZhciBzPXQubWF0Y2goaSk7aWYoIXMpcmV0dXJuIG51bGw7dmFyIGY9KFwiXCIrc1swXSkubWF0Y2goZSl8fFtcIi1cIiwwLDBdLG49ZlswXSx1PTYwKitmWzFdKyArZlsyXTtyZXR1cm4gMD09PXU/MDpcIitcIj09PW4/dTotdX0ocyksbnVsbD09PXMpKXJldHVybiB0aGlzO3ZhciB1PU1hdGguYWJzKHMpPD0xNj82MCpzOnM7aWYoMD09PXUpcmV0dXJuIHRoaXMudXRjKGYpO3ZhciByPXRoaXMuY2xvbmUoKTtpZihmKXJldHVybiByLiRvZmZzZXQ9dSxyLiR1PSExLHI7dmFyIG89dGhpcy4kdT90aGlzLnRvRGF0ZSgpLmdldFRpbWV6b25lT2Zmc2V0KCk6LTEqdGhpcy51dGNPZmZzZXQoKTtyZXR1cm4ocj10aGlzLmxvY2FsKCkuYWRkKHUrbyx0KSkuJG9mZnNldD11LHIuJHguJGxvY2FsT2Zmc2V0PW8scn07dmFyIGg9dS5mb3JtYXQ7dS5mb3JtYXQ9ZnVuY3Rpb24odCl7dmFyIGk9dHx8KHRoaXMuJHU/XCJZWVlZLU1NLUREVEhIOm1tOnNzW1pdXCI6XCJcIik7cmV0dXJuIGguY2FsbCh0aGlzLGkpfSx1LnZhbHVlT2Y9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLiR1dGlscygpLnUodGhpcy4kb2Zmc2V0KT8wOnRoaXMuJG9mZnNldCsodGhpcy4keC4kbG9jYWxPZmZzZXR8fHRoaXMuJGQuZ2V0VGltZXpvbmVPZmZzZXQoKSk7cmV0dXJuIHRoaXMuJGQudmFsdWVPZigpLTZlNCp0fSx1LmlzVVRDPWZ1bmN0aW9uKCl7cmV0dXJuISF0aGlzLiR1fSx1LnRvSVNPU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudG9EYXRlKCkudG9JU09TdHJpbmcoKX0sdS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRvRGF0ZSgpLnRvVVRDU3RyaW5nKCl9O3ZhciBsPXUudG9EYXRlO3UudG9EYXRlPWZ1bmN0aW9uKHQpe3JldHVyblwic1wiPT09dCYmdGhpcy4kb2Zmc2V0P24odGhpcy5mb3JtYXQoXCJZWVlZLU1NLUREIEhIOm1tOnNzOlNTU1wiKSkudG9EYXRlKCk6bC5jYWxsKHRoaXMpfTt2YXIgYz11LmRpZmY7dS5kaWZmPWZ1bmN0aW9uKHQsaSxlKXtpZih0JiZ0aGlzLiR1PT09dC4kdSlyZXR1cm4gYy5jYWxsKHRoaXMsdCxpLGUpO3ZhciBzPXRoaXMubG9jYWwoKSxmPW4odCkubG9jYWwoKTtyZXR1cm4gYy5jYWxsKHMsZixpLGUpfX19KSk7IiwgIiFmdW5jdGlvbih0LGUpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPWUoKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKGUpOih0PVwidW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWxUaGlzP2dsb2JhbFRoaXM6dHx8c2VsZikuZGF5anNfcGx1Z2luX3RpbWV6b25lPWUoKX0odGhpcywoZnVuY3Rpb24oKXtcInVzZSBzdHJpY3RcIjt2YXIgdD17eWVhcjowLG1vbnRoOjEsZGF5OjIsaG91cjozLG1pbnV0ZTo0LHNlY29uZDo1fSxlPXt9O3JldHVybiBmdW5jdGlvbihuLGksbyl7dmFyIHIsYT1mdW5jdGlvbih0LG4saSl7dm9pZCAwPT09aSYmKGk9e30pO3ZhciBvPW5ldyBEYXRlKHQpLHI9ZnVuY3Rpb24odCxuKXt2b2lkIDA9PT1uJiYobj17fSk7dmFyIGk9bi50aW1lWm9uZU5hbWV8fFwic2hvcnRcIixvPXQrXCJ8XCIraSxyPWVbb107cmV0dXJuIHJ8fChyPW5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KFwiZW4tVVNcIix7aG91cjEyOiExLHRpbWVab25lOnQseWVhcjpcIm51bWVyaWNcIixtb250aDpcIjItZGlnaXRcIixkYXk6XCIyLWRpZ2l0XCIsaG91cjpcIjItZGlnaXRcIixtaW51dGU6XCIyLWRpZ2l0XCIsc2Vjb25kOlwiMi1kaWdpdFwiLHRpbWVab25lTmFtZTppfSksZVtvXT1yKSxyfShuLGkpO3JldHVybiByLmZvcm1hdFRvUGFydHMobyl9LHU9ZnVuY3Rpb24oZSxuKXtmb3IodmFyIGk9YShlLG4pLHI9W10sdT0wO3U8aS5sZW5ndGg7dSs9MSl7dmFyIGY9aVt1XSxzPWYudHlwZSxtPWYudmFsdWUsYz10W3NdO2M+PTAmJihyW2NdPXBhcnNlSW50KG0sMTApKX12YXIgZD1yWzNdLGw9MjQ9PT1kPzA6ZCxoPXJbMF0rXCItXCIrclsxXStcIi1cIityWzJdK1wiIFwiK2wrXCI6XCIrcls0XStcIjpcIityWzVdK1wiOjAwMFwiLHY9K2U7cmV0dXJuKG8udXRjKGgpLnZhbHVlT2YoKS0odi09diUxZTMpKS82ZTR9LGY9aS5wcm90b3R5cGU7Zi50ej1mdW5jdGlvbih0LGUpe3ZvaWQgMD09PXQmJih0PXIpO3ZhciBuLGk9dGhpcy51dGNPZmZzZXQoKSxhPXRoaXMudG9EYXRlKCksdT1hLnRvTG9jYWxlU3RyaW5nKFwiZW4tVVNcIix7dGltZVpvbmU6dH0pLGY9TWF0aC5yb3VuZCgoYS1uZXcgRGF0ZSh1KSkvMWUzLzYwKSxzPTE1Ki1NYXRoLnJvdW5kKGEuZ2V0VGltZXpvbmVPZmZzZXQoKS8xNSktZjtpZighTnVtYmVyKHMpKW49dGhpcy51dGNPZmZzZXQoMCxlKTtlbHNlIGlmKG49byh1LHtsb2NhbGU6dGhpcy4kTH0pLiRzZXQoXCJtaWxsaXNlY29uZFwiLHRoaXMuJG1zKS51dGNPZmZzZXQocywhMCksZSl7dmFyIG09bi51dGNPZmZzZXQoKTtuPW4uYWRkKGktbSxcIm1pbnV0ZVwiKX1yZXR1cm4gbi4keC4kdGltZXpvbmU9dCxufSxmLm9mZnNldE5hbWU9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy4keC4kdGltZXpvbmV8fG8udHouZ3Vlc3MoKSxuPWEodGhpcy52YWx1ZU9mKCksZSx7dGltZVpvbmVOYW1lOnR9KS5maW5kKChmdW5jdGlvbih0KXtyZXR1cm5cInRpbWV6b25lbmFtZVwiPT09dC50eXBlLnRvTG93ZXJDYXNlKCl9KSk7cmV0dXJuIG4mJm4udmFsdWV9O3ZhciBzPWYuc3RhcnRPZjtmLnN0YXJ0T2Y9ZnVuY3Rpb24odCxlKXtpZighdGhpcy4keHx8IXRoaXMuJHguJHRpbWV6b25lKXJldHVybiBzLmNhbGwodGhpcyx0LGUpO3ZhciBuPW8odGhpcy5mb3JtYXQoXCJZWVlZLU1NLUREIEhIOm1tOnNzOlNTU1wiKSx7bG9jYWxlOnRoaXMuJEx9KTtyZXR1cm4gcy5jYWxsKG4sdCxlKS50eih0aGlzLiR4LiR0aW1lem9uZSwhMCl9LG8udHo9ZnVuY3Rpb24odCxlLG4pe3ZhciBpPW4mJmUsYT1ufHxlfHxyLGY9dSgrbygpLGEpO2lmKFwic3RyaW5nXCIhPXR5cGVvZiB0KXJldHVybiBvKHQpLnR6KGEpO3ZhciBzPWZ1bmN0aW9uKHQsZSxuKXt2YXIgaT10LTYwKmUqMWUzLG89dShpLG4pO2lmKGU9PT1vKXJldHVybltpLGVdO3ZhciByPXUoaS09NjAqKG8tZSkqMWUzLG4pO3JldHVybiBvPT09cj9baSxvXTpbdC02MCpNYXRoLm1pbihvLHIpKjFlMyxNYXRoLm1heChvLHIpXX0oby51dGModCxpKS52YWx1ZU9mKCksZixhKSxtPXNbMF0sYz1zWzFdLGQ9byhtKS51dGNPZmZzZXQoYyk7cmV0dXJuIGQuJHguJHRpbWV6b25lPWEsZH0sby50ei5ndWVzcz1mdW5jdGlvbigpe3JldHVybiBJbnRsLkRhdGVUaW1lRm9ybWF0KCkucmVzb2x2ZWRPcHRpb25zKCkudGltZVpvbmV9LG8udHouc2V0RGVmYXVsdD1mdW5jdGlvbih0KXtyPXR9fX0pKTsiLCAiIWZ1bmN0aW9uKGUsdCl7XCJvYmplY3RcIj09dHlwZW9mIGV4cG9ydHMmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBtb2R1bGU/bW9kdWxlLmV4cG9ydHM9dCgpOlwiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUodCk6KGU9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGdsb2JhbFRoaXM/Z2xvYmFsVGhpczplfHxzZWxmKS5kYXlqc19wbHVnaW5faXNvV2Vlaz10KCl9KHRoaXMsKGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGU9XCJkYXlcIjtyZXR1cm4gZnVuY3Rpb24odCxpLHMpe3ZhciBhPWZ1bmN0aW9uKHQpe3JldHVybiB0LmFkZCg0LXQuaXNvV2Vla2RheSgpLGUpfSxkPWkucHJvdG90eXBlO2QuaXNvV2Vla1llYXI9ZnVuY3Rpb24oKXtyZXR1cm4gYSh0aGlzKS55ZWFyKCl9LGQuaXNvV2Vlaz1mdW5jdGlvbih0KXtpZighdGhpcy4kdXRpbHMoKS51KHQpKXJldHVybiB0aGlzLmFkZCg3Kih0LXRoaXMuaXNvV2VlaygpKSxlKTt2YXIgaSxkLG4sbyxyPWEodGhpcyksdT0oaT10aGlzLmlzb1dlZWtZZWFyKCksZD10aGlzLiR1LG49KGQ/cy51dGM6cykoKS55ZWFyKGkpLnN0YXJ0T2YoXCJ5ZWFyXCIpLG89NC1uLmlzb1dlZWtkYXkoKSxuLmlzb1dlZWtkYXkoKT40JiYobys9Nyksbi5hZGQobyxlKSk7cmV0dXJuIHIuZGlmZih1LFwid2Vla1wiKSsxfSxkLmlzb1dlZWtkYXk9ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMuJHV0aWxzKCkudShlKT90aGlzLmRheSgpfHw3OnRoaXMuZGF5KHRoaXMuZGF5KCklNz9lOmUtNyl9O3ZhciBuPWQuc3RhcnRPZjtkLnN0YXJ0T2Y9ZnVuY3Rpb24oZSx0KXt2YXIgaT10aGlzLiR1dGlscygpLHM9ISFpLnUodCl8fHQ7cmV0dXJuXCJpc293ZWVrXCI9PT1pLnAoZSk/cz90aGlzLmRhdGUodGhpcy5kYXRlKCktKHRoaXMuaXNvV2Vla2RheSgpLTEpKS5zdGFydE9mKFwiZGF5XCIpOnRoaXMuZGF0ZSh0aGlzLmRhdGUoKS0xLSh0aGlzLmlzb1dlZWtkYXkoKS0xKSs3KS5lbmRPZihcImRheVwiKTpuLmJpbmQodGhpcykoZSx0KX19fSkpOyIsICJpbXBvcnQgeyBJUmVuZGVyZXIsIElSZW5kZXJDb250ZXh0IH0gZnJvbSAnLi9JR3JvdXBpbmdSZW5kZXJlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGlwZWxpbmUge1xuICBydW4oY29udGV4dDogSVJlbmRlckNvbnRleHQpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRQaXBlbGluZShyZW5kZXJlcnM6IElSZW5kZXJlcltdKTogUGlwZWxpbmUge1xuICByZXR1cm4ge1xuICAgIGFzeW5jIHJ1bihjb250ZXh0OiBJUmVuZGVyQ29udGV4dCkge1xuICAgICAgZm9yIChjb25zdCByZW5kZXJlciBvZiByZW5kZXJlcnMpIHtcbiAgICAgICAgYXdhaXQgcmVuZGVyZXIucmVuZGVyKGNvbnRleHQpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cbiIsICJpbXBvcnQgeyBJQ2FsZW5kYXJFdmVudCB9IGZyb20gJy4uL3R5cGVzL0NhbGVuZGFyVHlwZXMnO1xyXG5pbXBvcnQgeyBEYXRlU2VydmljZSB9IGZyb20gJy4vRGF0ZVNlcnZpY2UnO1xyXG5pbXBvcnQgeyBJRW50aXR5UmVzb2x2ZXIgfSBmcm9tICcuL0lFbnRpdHlSZXNvbHZlcic7XHJcblxyXG4vKipcclxuICogRmllbGQgZGVmaW5pdGlvbiBmb3IgRmlsdGVyVGVtcGxhdGVcclxuICovXHJcbmludGVyZmFjZSBJRmlsdGVyRmllbGQge1xyXG4gIGlkUHJvcGVydHk6IHN0cmluZztcclxuICBkZXJpdmVkRnJvbT86IHN0cmluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIFBhcnNlZCBkb3Qtbm90YXRpb24gcmVmZXJlbmNlXHJcbiAqL1xyXG5pbnRlcmZhY2UgSURvdE5vdGF0aW9uIHtcclxuICBlbnRpdHlUeXBlOiBzdHJpbmc7ICAgLy8gZS5nLiwgJ3Jlc291cmNlJ1xyXG4gIHByb3BlcnR5OiBzdHJpbmc7ICAgICAvLyBlLmcuLCAndGVhbUlkJ1xyXG4gIGZvcmVpZ25LZXk6IHN0cmluZzsgICAvLyBlLmcuLCAncmVzb3VyY2VJZCdcclxufVxyXG5cclxuLyoqXHJcbiAqIEZpbHRlclRlbXBsYXRlIC0gQnlnZ2VyIG5cdTAwRjhnbGVyIHRpbCBldmVudC1rb2xvbm5lIG1hdGNoaW5nXHJcbiAqXHJcbiAqIFZpZXdDb25maWcgZGVmaW5lcmVyIGh2aWxrZSBmZWx0ZXIgKGlkUHJvcGVydGllcykgZGVyIGluZGdcdTAwRTVyIGkga29sb25uZW5zIG5cdTAwRjhnbGUuXHJcbiAqIFNhbW1lIHRlbXBsYXRlIGJydWdlcyB0aWwgYXQgYnlnZ2Ugblx1MDBGOGdsZSBmb3IgYlx1MDBFNWRlIGtvbG9ubmUgb2cgZXZlbnQuXHJcbiAqXHJcbiAqIFN1cHBvcnRzIGRvdC1ub3RhdGlvbiBmb3IgaGllcmFyY2hpY2FsIHJlbGF0aW9uczpcclxuICogLSAncmVzb3VyY2UudGVhbUlkJyBcdTIxOTIgbG9va3MgdXAgZXZlbnQucmVzb3VyY2VJZCBcdTIxOTIgcmVzb3VyY2UgZW50aXR5IFx1MjE5MiB0ZWFtSWRcclxuICpcclxuICogUHJpbmNpcDogS29sb25uZW5zIG5cdTAwRjhnbGUtdGVtcGxhdGUgYmVzdGVtbWVyIGh2YWQgZGVyIG1hdGNoZXMgcFx1MDBFNS5cclxuICpcclxuICogQHNlZSBkb2NzL2ZpbHRlci10ZW1wbGF0ZS5tZFxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEZpbHRlclRlbXBsYXRlIHtcclxuICBwcml2YXRlIGZpZWxkczogSUZpbHRlckZpZWxkW10gPSBbXTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGRhdGVTZXJ2aWNlOiBEYXRlU2VydmljZSxcclxuICAgIHByaXZhdGUgZW50aXR5UmVzb2x2ZXI/OiBJRW50aXR5UmVzb2x2ZXJcclxuICApIHt9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRpbGZcdTAwRjhqIGZlbHQgdGlsIHRlbXBsYXRlXHJcbiAgICogQHBhcmFtIGlkUHJvcGVydHkgLSBQcm9wZXJ0eS1uYXZuIChicnVnZXMgcFx1MDBFNSBiXHUwMEU1ZGUgZXZlbnQgb2cgY29sdW1uLmRhdGFzZXQpXHJcbiAgICogQHBhcmFtIGRlcml2ZWRGcm9tIC0gSHZpcyBmZWx0ZXQgdWRsZWRlcyBmcmEgYW5kZW4gcHJvcGVydHkgKGYuZWtzLiBkYXRlIGZyYSBzdGFydClcclxuICAgKi9cclxuICBhZGRGaWVsZChpZFByb3BlcnR5OiBzdHJpbmcsIGRlcml2ZWRGcm9tPzogc3RyaW5nKTogdGhpcyB7XHJcbiAgICB0aGlzLmZpZWxkcy5wdXNoKHsgaWRQcm9wZXJ0eSwgZGVyaXZlZEZyb20gfSk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFBhcnNlIGRvdC1ub3RhdGlvbiBzdHJpbmcgaW50byBjb21wb25lbnRzXHJcbiAgICogQGV4YW1wbGUgJ3Jlc291cmNlLnRlYW1JZCcgXHUyMTkyIHsgZW50aXR5VHlwZTogJ3Jlc291cmNlJywgcHJvcGVydHk6ICd0ZWFtSWQnLCBmb3JlaWduS2V5OiAncmVzb3VyY2VJZCcgfVxyXG4gICAqL1xyXG4gIHByaXZhdGUgcGFyc2VEb3ROb3RhdGlvbihpZFByb3BlcnR5OiBzdHJpbmcpOiBJRG90Tm90YXRpb24gfCBudWxsIHtcclxuICAgIGlmICghaWRQcm9wZXJ0eS5pbmNsdWRlcygnLicpKSByZXR1cm4gbnVsbDtcclxuICAgIGNvbnN0IFtlbnRpdHlUeXBlLCBwcm9wZXJ0eV0gPSBpZFByb3BlcnR5LnNwbGl0KCcuJyk7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBlbnRpdHlUeXBlLFxyXG4gICAgICBwcm9wZXJ0eSxcclxuICAgICAgZm9yZWlnbktleTogZW50aXR5VHlwZSArICdJZCcgLy8gQ29udmVudGlvbjogcmVzb3VyY2UgXHUyMTkyIHJlc291cmNlSWRcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgZGF0YXNldCBrZXkgZm9yIGNvbHVtbiBsb29rdXBcclxuICAgKiBGb3IgZG90LW5vdGF0aW9uICdyZXNvdXJjZS50ZWFtSWQnLCB3ZSBsb29rIGZvciAndGVhbUlkJyBpbiBkYXRhc2V0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXREYXRhc2V0S2V5KGlkUHJvcGVydHk6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBkb3ROb3RhdGlvbiA9IHRoaXMucGFyc2VEb3ROb3RhdGlvbihpZFByb3BlcnR5KTtcclxuICAgIGlmIChkb3ROb3RhdGlvbikge1xyXG4gICAgICByZXR1cm4gZG90Tm90YXRpb24ucHJvcGVydHk7IC8vICd0ZWFtSWQnXHJcbiAgICB9XHJcbiAgICByZXR1cm4gaWRQcm9wZXJ0eTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEJ5ZyBuXHUwMEY4Z2xlIGZyYSBrb2xvbm5lXHJcbiAgICogTFx1MDBFNnNlciB2XHUwMEU2cmRpZXIgZnJhIGNvbHVtbi5kYXRhc2V0W2lkUHJvcGVydHldXHJcbiAgICogRm9yIGRvdC1ub3RhdGlvbiwgdXNlcyB0aGUgcHJvcGVydHkgcGFydCAocmVzb3VyY2UudGVhbUlkIFx1MjE5MiB0ZWFtSWQpXHJcbiAgICovXHJcbiAgYnVpbGRLZXlGcm9tQ29sdW1uKGNvbHVtbjogSFRNTEVsZW1lbnQpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuZmllbGRzXHJcbiAgICAgIC5tYXAoZiA9PiB7XHJcbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5nZXREYXRhc2V0S2V5KGYuaWRQcm9wZXJ0eSk7XHJcbiAgICAgICAgcmV0dXJuIGNvbHVtbi5kYXRhc2V0W2tleV0gfHwgJyc7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5qb2luKCc6Jyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBCeWcgblx1MDBGOGdsZSBmcmEgZXZlbnRcclxuICAgKiBMXHUwMEU2c2VyIHZcdTAwRTZyZGllciBmcmEgZXZlbnRbaWRQcm9wZXJ0eV0gZWxsZXIgdWRsZWRlciBmcmEgZGVyaXZlZEZyb21cclxuICAgKiBGb3IgZG90LW5vdGF0aW9uLCByZXNvbHZlcyB2aWEgRW50aXR5UmVzb2x2ZXJcclxuICAgKi9cclxuICBidWlsZEtleUZyb21FdmVudChldmVudDogSUNhbGVuZGFyRXZlbnQpOiBzdHJpbmcge1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcclxuICAgIGNvbnN0IGV2ZW50UmVjb3JkID0gZXZlbnQgYXMgYW55O1xyXG4gICAgcmV0dXJuIHRoaXMuZmllbGRzXHJcbiAgICAgIC5tYXAoZiA9PiB7XHJcbiAgICAgICAgLy8gQ2hlY2sgZm9yIGRvdC1ub3RhdGlvbiAoZS5nLiwgJ3Jlc291cmNlLnRlYW1JZCcpXHJcbiAgICAgICAgY29uc3QgZG90Tm90YXRpb24gPSB0aGlzLnBhcnNlRG90Tm90YXRpb24oZi5pZFByb3BlcnR5KTtcclxuICAgICAgICBpZiAoZG90Tm90YXRpb24pIHtcclxuICAgICAgICAgIHJldHVybiB0aGlzLnJlc29sdmVEb3ROb3RhdGlvbihldmVudFJlY29yZCwgZG90Tm90YXRpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGYuZGVyaXZlZEZyb20pIHtcclxuICAgICAgICAgIC8vIFVkbGVkIHZcdTAwRTZyZGkgKGYuZWtzLiBkYXRlIGZyYSBzdGFydClcclxuICAgICAgICAgIGNvbnN0IHNvdXJjZVZhbHVlID0gZXZlbnRSZWNvcmRbZi5kZXJpdmVkRnJvbV07XHJcbiAgICAgICAgICBpZiAoc291cmNlVmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGVTZXJ2aWNlLmdldERhdGVLZXkoc291cmNlVmFsdWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIFN0cmluZyhzb3VyY2VWYWx1ZSB8fCAnJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBTdHJpbmcoZXZlbnRSZWNvcmRbZi5pZFByb3BlcnR5XSB8fCAnJyk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5qb2luKCc6Jyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXNvbHZlIGRvdC1ub3RhdGlvbiByZWZlcmVuY2UgdmlhIEVudGl0eVJlc29sdmVyXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZXNvbHZlRG90Tm90YXRpb24oZXZlbnRSZWNvcmQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBkb3ROb3RhdGlvbjogSURvdE5vdGF0aW9uKTogc3RyaW5nIHtcclxuICAgIGlmICghdGhpcy5lbnRpdHlSZXNvbHZlcikge1xyXG4gICAgICBjb25zb2xlLndhcm4oYEZpbHRlclRlbXBsYXRlOiBFbnRpdHlSZXNvbHZlciByZXF1aXJlZCBmb3IgZG90LW5vdGF0aW9uICcke2RvdE5vdGF0aW9uLmVudGl0eVR5cGV9LiR7ZG90Tm90YXRpb24ucHJvcGVydHl9J2ApO1xyXG4gICAgICByZXR1cm4gJyc7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gR2V0IGZvcmVpZ24ga2V5IHZhbHVlIGZyb20gZXZlbnQgKGUuZy4sIHJlc291cmNlSWQpXHJcbiAgICBjb25zdCBmb3JlaWduSWQgPSBldmVudFJlY29yZFtkb3ROb3RhdGlvbi5mb3JlaWduS2V5XTtcclxuICAgIGlmICghZm9yZWlnbklkKSByZXR1cm4gJyc7XHJcblxyXG4gICAgLy8gUmVzb2x2ZSBlbnRpdHlcclxuICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZW50aXR5UmVzb2x2ZXIucmVzb2x2ZShkb3ROb3RhdGlvbi5lbnRpdHlUeXBlLCBTdHJpbmcoZm9yZWlnbklkKSk7XHJcbiAgICBpZiAoIWVudGl0eSkgcmV0dXJuICcnO1xyXG5cclxuICAgIC8vIFJldHVybiBwcm9wZXJ0eSB2YWx1ZSBmcm9tIGVudGl0eVxyXG4gICAgcmV0dXJuIFN0cmluZyhlbnRpdHlbZG90Tm90YXRpb24ucHJvcGVydHldIHx8ICcnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1hdGNoIGV2ZW50IG1vZCBrb2xvbm5lXHJcbiAgICovXHJcbiAgbWF0Y2hlcyhldmVudDogSUNhbGVuZGFyRXZlbnQsIGNvbHVtbjogSFRNTEVsZW1lbnQpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmJ1aWxkS2V5RnJvbUV2ZW50KGV2ZW50KSA9PT0gdGhpcy5idWlsZEtleUZyb21Db2x1bW4oY29sdW1uKTtcclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IElSZW5kZXJlciwgSVJlbmRlckNvbnRleHQgfSBmcm9tICcuL0lHcm91cGluZ1JlbmRlcmVyJztcclxuaW1wb3J0IHsgYnVpbGRQaXBlbGluZSB9IGZyb20gJy4vUmVuZGVyQnVpbGRlcic7XHJcbmltcG9ydCB7IEV2ZW50UmVuZGVyZXIgfSBmcm9tICcuLi9mZWF0dXJlcy9ldmVudC9FdmVudFJlbmRlcmVyJztcclxuaW1wb3J0IHsgU2NoZWR1bGVSZW5kZXJlciB9IGZyb20gJy4uL2ZlYXR1cmVzL3NjaGVkdWxlL1NjaGVkdWxlUmVuZGVyZXInO1xyXG5pbXBvcnQgeyBIZWFkZXJEcmF3ZXJSZW5kZXJlciB9IGZyb20gJy4uL2ZlYXR1cmVzL2hlYWRlcmRyYXdlci9IZWFkZXJEcmF3ZXJSZW5kZXJlcic7XHJcbmltcG9ydCB7IFZpZXdDb25maWcsIEdyb3VwaW5nQ29uZmlnIH0gZnJvbSAnLi9WaWV3Q29uZmlnJztcclxuaW1wb3J0IHsgRmlsdGVyVGVtcGxhdGUgfSBmcm9tICcuL0ZpbHRlclRlbXBsYXRlJztcclxuaW1wb3J0IHsgRGF0ZVNlcnZpY2UgfSBmcm9tICcuL0RhdGVTZXJ2aWNlJztcclxuaW1wb3J0IHsgSUVudGl0eVNlcnZpY2UgfSBmcm9tICcuLi9zdG9yYWdlL0lFbnRpdHlTZXJ2aWNlJztcclxuaW1wb3J0IHsgSVN5bmMgfSBmcm9tICcuLi90eXBlcy9DYWxlbmRhclR5cGVzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBDYWxlbmRhck9yY2hlc3RyYXRvciB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGFsbFJlbmRlcmVyczogSVJlbmRlcmVyW10sXHJcbiAgICBwcml2YXRlIGV2ZW50UmVuZGVyZXI6IEV2ZW50UmVuZGVyZXIsXHJcbiAgICBwcml2YXRlIHNjaGVkdWxlUmVuZGVyZXI6IFNjaGVkdWxlUmVuZGVyZXIsXHJcbiAgICBwcml2YXRlIGhlYWRlckRyYXdlclJlbmRlcmVyOiBIZWFkZXJEcmF3ZXJSZW5kZXJlcixcclxuICAgIHByaXZhdGUgZGF0ZVNlcnZpY2U6IERhdGVTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBlbnRpdHlTZXJ2aWNlczogSUVudGl0eVNlcnZpY2U8SVN5bmM+W11cclxuICApIHt9XHJcblxyXG4gIGFzeW5jIHJlbmRlcih2aWV3Q29uZmlnOiBWaWV3Q29uZmlnLCBjb250YWluZXI6IEhUTUxFbGVtZW50KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBoZWFkZXJDb250YWluZXIgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWNhbGVuZGFyLWhlYWRlcicpIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgY29uc3QgY29sdW1uQ29udGFpbmVyID0gY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1kYXktY29sdW1ucycpIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgaWYgKCFoZWFkZXJDb250YWluZXIgfHwgIWNvbHVtbkNvbnRhaW5lcikge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3Npbmcgc3dwLWNhbGVuZGFyLWhlYWRlciBvciBzd3AtZGF5LWNvbHVtbnMnKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBCeWcgZmlsdGVyIGZyYSB2aWV3Q29uZmlnXHJcbiAgICBjb25zdCBmaWx0ZXI6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHt9O1xyXG4gICAgZm9yIChjb25zdCBncm91cGluZyBvZiB2aWV3Q29uZmlnLmdyb3VwaW5ncykge1xyXG4gICAgICBmaWx0ZXJbZ3JvdXBpbmcudHlwZV0gPSBncm91cGluZy52YWx1ZXM7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQnlnIEZpbHRlclRlbXBsYXRlIGZyYSB2aWV3Q29uZmlnIGdyb3VwaW5ncyAoa3VuIGRlIG1lZCBpZFByb3BlcnR5KVxyXG4gICAgY29uc3QgZmlsdGVyVGVtcGxhdGUgPSBuZXcgRmlsdGVyVGVtcGxhdGUodGhpcy5kYXRlU2VydmljZSk7XHJcbiAgICBmb3IgKGNvbnN0IGdyb3VwaW5nIG9mIHZpZXdDb25maWcuZ3JvdXBpbmdzKSB7XHJcbiAgICAgIGlmIChncm91cGluZy5pZFByb3BlcnR5KSB7XHJcbiAgICAgICAgZmlsdGVyVGVtcGxhdGUuYWRkRmllbGQoZ3JvdXBpbmcuaWRQcm9wZXJ0eSwgZ3JvdXBpbmcuZGVyaXZlZEZyb20pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmVzb2x2ZSBiZWxvbmdzVG8gcmVsYXRpb25zIChlLmcuLCB0ZWFtLnJlc291cmNlSWRzKVxyXG4gICAgY29uc3QgeyBwYXJlbnRDaGlsZE1hcCwgY2hpbGRUeXBlIH0gPSBhd2FpdCB0aGlzLnJlc29sdmVCZWxvbmdzVG8odmlld0NvbmZpZy5ncm91cGluZ3MsIGZpbHRlcik7XHJcblxyXG4gICAgY29uc3QgY29udGV4dDogSVJlbmRlckNvbnRleHQgPSB7IGhlYWRlckNvbnRhaW5lciwgY29sdW1uQ29udGFpbmVyLCBmaWx0ZXIsIGdyb3VwaW5nczogdmlld0NvbmZpZy5ncm91cGluZ3MsIHBhcmVudENoaWxkTWFwLCBjaGlsZFR5cGUgfTtcclxuXHJcbiAgICAvLyBDbGVhclxyXG4gICAgaGVhZGVyQ29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xyXG4gICAgY29sdW1uQ29udGFpbmVyLmlubmVySFRNTCA9ICcnO1xyXG5cclxuICAgIC8vIFNcdTAwRTZ0IGRhdGEtbGV2ZWxzIGF0dHJpYnV0IGZvciBDU1MgZ3JpZC1yb3cgc3R5bGluZ1xyXG4gICAgY29uc3QgbGV2ZWxzID0gdmlld0NvbmZpZy5ncm91cGluZ3MubWFwKGcgPT4gZy50eXBlKS5qb2luKCcgJyk7XHJcbiAgICBoZWFkZXJDb250YWluZXIuZGF0YXNldC5sZXZlbHMgPSBsZXZlbHM7XHJcblxyXG4gICAgLy8gVlx1MDBFNmxnIHJlbmRlcmVycyBiYXNlcmV0IHBcdTAwRTUgZ3JvdXBpbmdzIHR5cGVzXHJcbiAgICBjb25zdCBhY3RpdmVSZW5kZXJlcnMgPSB0aGlzLnNlbGVjdFJlbmRlcmVycyh2aWV3Q29uZmlnKTtcclxuXHJcbiAgICAvLyBCeWcgb2cga1x1MDBGOHIgcGlwZWxpbmVcclxuICAgIGNvbnN0IHBpcGVsaW5lID0gYnVpbGRQaXBlbGluZShhY3RpdmVSZW5kZXJlcnMpO1xyXG4gICAgYXdhaXQgcGlwZWxpbmUucnVuKGNvbnRleHQpO1xyXG5cclxuICAgIC8vIFJlbmRlciBzY2hlZHVsZSB1bmF2YWlsYWJsZSB6b25lcyAoZlx1MDBGOHIgZXZlbnRzKVxyXG4gICAgYXdhaXQgdGhpcy5zY2hlZHVsZVJlbmRlcmVyLnJlbmRlcihjb250YWluZXIsIGZpbHRlcik7XHJcblxyXG4gICAgLy8gUmVuZGVyIHRpbWVkIGV2ZW50cyBpbiBncmlkIChtZWQgZmlsdGVyVGVtcGxhdGUgdGlsIG1hdGNoaW5nKVxyXG4gICAgYXdhaXQgdGhpcy5ldmVudFJlbmRlcmVyLnJlbmRlcihjb250YWluZXIsIGZpbHRlciwgZmlsdGVyVGVtcGxhdGUpO1xyXG5cclxuICAgIC8vIFJlbmRlciBhbGxEYXkgZXZlbnRzIGluIGhlYWRlciBkcmF3ZXIgKG1lZCBmaWx0ZXJUZW1wbGF0ZSB0aWwgbWF0Y2hpbmcpXHJcbiAgICBhd2FpdCB0aGlzLmhlYWRlckRyYXdlclJlbmRlcmVyLnJlbmRlcihjb250YWluZXIsIGZpbHRlciwgZmlsdGVyVGVtcGxhdGUpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZWxlY3RSZW5kZXJlcnModmlld0NvbmZpZzogVmlld0NvbmZpZyk6IElSZW5kZXJlcltdIHtcclxuICAgIGNvbnN0IHR5cGVzID0gdmlld0NvbmZpZy5ncm91cGluZ3MubWFwKGcgPT4gZy50eXBlKTtcclxuICAgIC8vIFNvcnRcdTAwRTlyIHJlbmRlcmVycyBpIHNhbW1lIHJcdTAwRTZra2VmXHUwMEY4bGdlIHNvbSB2aWV3Q29uZmlnLmdyb3VwaW5nc1xyXG4gICAgcmV0dXJuIHR5cGVzXHJcbiAgICAgIC5tYXAodHlwZSA9PiB0aGlzLmFsbFJlbmRlcmVycy5maW5kKHIgPT4gci50eXBlID09PSB0eXBlKSlcclxuICAgICAgLmZpbHRlcigocik6IHIgaXMgSVJlbmRlcmVyID0+IHIgIT09IHVuZGVmaW5lZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXNvbHZlIGJlbG9uZ3NUbyByZWxhdGlvbnMgdG8gYnVpbGQgcGFyZW50LWNoaWxkIG1hcFxyXG4gICAqIGUuZy4sIGJlbG9uZ3NUbzogJ3RlYW0ucmVzb3VyY2VJZHMnIFx1MjE5MiB7IHRlYW0xOiBbJ0VNUDAwMScsICdFTVAwMDInXSwgdGVhbTI6IFsuLi5dIH1cclxuICAgKiBBbHNvIHJldHVybnMgdGhlIGNoaWxkVHlwZSAodGhlIGdyb3VwaW5nIHR5cGUgdGhhdCBoYXMgYmVsb25nc1RvKVxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcmVzb2x2ZUJlbG9uZ3NUbyhcclxuICAgIGdyb3VwaW5nczogR3JvdXBpbmdDb25maWdbXSxcclxuICAgIGZpbHRlcjogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+XHJcbiAgKTogUHJvbWlzZTx7IHBhcmVudENoaWxkTWFwPzogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+OyBjaGlsZFR5cGU/OiBzdHJpbmcgfT4ge1xyXG4gICAgLy8gRmluZCBncm91cGluZyB3aXRoIGJlbG9uZ3NUb1xyXG4gICAgY29uc3QgY2hpbGRHcm91cGluZyA9IGdyb3VwaW5ncy5maW5kKGcgPT4gZy5iZWxvbmdzVG8pO1xyXG4gICAgaWYgKCFjaGlsZEdyb3VwaW5nPy5iZWxvbmdzVG8pIHJldHVybiB7fTtcclxuXHJcbiAgICAvLyBQYXJzZSBiZWxvbmdzVG86ICd0ZWFtLnJlc291cmNlSWRzJ1xyXG4gICAgY29uc3QgW2VudGl0eVR5cGUsIHByb3BlcnR5XSA9IGNoaWxkR3JvdXBpbmcuYmVsb25nc1RvLnNwbGl0KCcuJyk7XHJcbiAgICBpZiAoIWVudGl0eVR5cGUgfHwgIXByb3BlcnR5KSByZXR1cm4ge307XHJcblxyXG4gICAgLy8gR2V0IHBhcmVudCBJRHMgZnJvbSBmaWx0ZXJcclxuICAgIGNvbnN0IHBhcmVudElkcyA9IGZpbHRlcltlbnRpdHlUeXBlXSB8fCBbXTtcclxuICAgIGlmIChwYXJlbnRJZHMubGVuZ3RoID09PSAwKSByZXR1cm4ge307XHJcblxyXG4gICAgLy8gRmluZCBzZXJ2aWNlIGR5bmFtaXNrIGJhc2VyZXQgcFx1MDBFNSBlbnRpdHlUeXBlIChpbmdlbiBoYXJkY29kZWQgdHlwZSBjaGVjaylcclxuICAgIGNvbnN0IHNlcnZpY2UgPSB0aGlzLmVudGl0eVNlcnZpY2VzLmZpbmQocyA9PlxyXG4gICAgICBzLmVudGl0eVR5cGUudG9Mb3dlckNhc2UoKSA9PT0gZW50aXR5VHlwZVxyXG4gICAgKTtcclxuICAgIGlmICghc2VydmljZSkgcmV0dXJuIHt9O1xyXG5cclxuICAgIC8vIEhlbnQgYWxsZSBlbnRpdGllcyBvZyBmaWx0cmVyIHBcdTAwRTUgcGFyZW50SWRzXHJcbiAgICBjb25zdCBhbGxFbnRpdGllcyA9IGF3YWl0IHNlcnZpY2UuZ2V0QWxsKCk7XHJcbiAgICBjb25zdCBlbnRpdGllcyA9IGFsbEVudGl0aWVzLmZpbHRlcihlID0+XHJcbiAgICAgIHBhcmVudElkcy5pbmNsdWRlcygoZSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KS5pZCBhcyBzdHJpbmcpXHJcbiAgICApO1xyXG5cclxuICAgIC8vIEJ5ZyBwYXJlbnQtY2hpbGQgbWFwXHJcbiAgICBjb25zdCBtYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPiA9IHt9O1xyXG4gICAgZm9yIChjb25zdCBlbnRpdHkgb2YgZW50aXRpZXMpIHtcclxuICAgICAgY29uc3QgZW50aXR5UmVjb3JkID0gZW50aXR5IGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XHJcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gKGVudGl0eVJlY29yZFtwcm9wZXJ0eV0gYXMgc3RyaW5nW10pIHx8IFtdO1xyXG4gICAgICBtYXBbZW50aXR5UmVjb3JkLmlkIGFzIHN0cmluZ10gPSBjaGlsZHJlbjtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4geyBwYXJlbnRDaGlsZE1hcDogbWFwLCBjaGlsZFR5cGU6IGNoaWxkR3JvdXBpbmcudHlwZSB9O1xyXG4gIH1cclxufVxyXG4iLCAiZXhwb3J0IGNsYXNzIE5hdmlnYXRpb25BbmltYXRvciB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGhlYWRlclRyYWNrOiBIVE1MRWxlbWVudCxcclxuICAgIHByaXZhdGUgY29udGVudFRyYWNrOiBIVE1MRWxlbWVudCxcclxuICAgIHByaXZhdGUgaGVhZGVyRHJhd2VyOiBIVE1MRWxlbWVudCB8IG51bGxcclxuICApIHt9XHJcblxyXG4gIGFzeW5jIHNsaWRlKGRpcmVjdGlvbjogJ2xlZnQnIHwgJ3JpZ2h0JywgcmVuZGVyRm46ICgpID0+IFByb21pc2U8dm9pZD4pOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IG91dCA9IGRpcmVjdGlvbiA9PT0gJ2xlZnQnID8gJy0xMDAlJyA6ICcxMDAlJztcclxuICAgIGNvbnN0IGludG8gPSBkaXJlY3Rpb24gPT09ICdsZWZ0JyA/ICcxMDAlJyA6ICctMTAwJSc7XHJcblxyXG4gICAgYXdhaXQgdGhpcy5hbmltYXRlT3V0KG91dCk7XHJcbiAgICBhd2FpdCByZW5kZXJGbigpO1xyXG4gICAgYXdhaXQgdGhpcy5hbmltYXRlSW4oaW50byk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGFuaW1hdGVPdXQodHJhbnNsYXRlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGFuaW1hdGlvbnMgPSBbXHJcbiAgICAgIHRoaXMuaGVhZGVyVHJhY2suYW5pbWF0ZShcclxuICAgICAgICBbeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDApJyB9LCB7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZVgoJHt0cmFuc2xhdGV9KWAgfV0sXHJcbiAgICAgICAgeyBkdXJhdGlvbjogMjAwLCBlYXNpbmc6ICdlYXNlLWluJyB9XHJcbiAgICAgICkuZmluaXNoZWQsXHJcbiAgICAgIHRoaXMuY29udGVudFRyYWNrLmFuaW1hdGUoXHJcbiAgICAgICAgW3sgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKScgfSwgeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGVYKCR7dHJhbnNsYXRlfSlgIH1dLFxyXG4gICAgICAgIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1pbicgfVxyXG4gICAgICApLmZpbmlzaGVkXHJcbiAgICBdO1xyXG5cclxuICAgIGlmICh0aGlzLmhlYWRlckRyYXdlcikge1xyXG4gICAgICBhbmltYXRpb25zLnB1c2goXHJcbiAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXIuYW5pbWF0ZShcclxuICAgICAgICAgIFt7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCknIH0sIHsgdHJhbnNmb3JtOiBgdHJhbnNsYXRlWCgke3RyYW5zbGF0ZX0pYCB9XSxcclxuICAgICAgICAgIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1pbicgfVxyXG4gICAgICAgICkuZmluaXNoZWRcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBhd2FpdCBQcm9taXNlLmFsbChhbmltYXRpb25zKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgYW5pbWF0ZUluKHRyYW5zbGF0ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCBhbmltYXRpb25zID0gW1xyXG4gICAgICB0aGlzLmhlYWRlclRyYWNrLmFuaW1hdGUoXHJcbiAgICAgICAgW3sgdHJhbnNmb3JtOiBgdHJhbnNsYXRlWCgke3RyYW5zbGF0ZX0pYCB9LCB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMCknIH1dLFxyXG4gICAgICAgIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1vdXQnIH1cclxuICAgICAgKS5maW5pc2hlZCxcclxuICAgICAgdGhpcy5jb250ZW50VHJhY2suYW5pbWF0ZShcclxuICAgICAgICBbeyB0cmFuc2Zvcm06IGB0cmFuc2xhdGVYKCR7dHJhbnNsYXRlfSlgIH0sIHsgdHJhbnNmb3JtOiAndHJhbnNsYXRlWCgwKScgfV0sXHJcbiAgICAgICAgeyBkdXJhdGlvbjogMjAwLCBlYXNpbmc6ICdlYXNlLW91dCcgfVxyXG4gICAgICApLmZpbmlzaGVkXHJcbiAgICBdO1xyXG5cclxuICAgIGlmICh0aGlzLmhlYWRlckRyYXdlcikge1xyXG4gICAgICBhbmltYXRpb25zLnB1c2goXHJcbiAgICAgICAgdGhpcy5oZWFkZXJEcmF3ZXIuYW5pbWF0ZShcclxuICAgICAgICAgIFt7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZVgoJHt0cmFuc2xhdGV9KWAgfSwgeyB0cmFuc2Zvcm06ICd0cmFuc2xhdGVYKDApJyB9XSxcclxuICAgICAgICAgIHsgZHVyYXRpb246IDIwMCwgZWFzaW5nOiAnZWFzZS1vdXQnIH1cclxuICAgICAgICApLmZpbmlzaGVkXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoYW5pbWF0aW9ucyk7XHJcbiAgfVxyXG59XHJcbiIsICJpbXBvcnQgeyBJUmVuZGVyZXIsIElSZW5kZXJDb250ZXh0IH0gZnJvbSAnLi4vLi4vY29yZS9JR3JvdXBpbmdSZW5kZXJlcic7XHJcbmltcG9ydCB7IERhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29yZS9EYXRlU2VydmljZSc7XHJcblxyXG5leHBvcnQgY2xhc3MgRGF0ZVJlbmRlcmVyIGltcGxlbWVudHMgSVJlbmRlcmVyIHtcclxuICByZWFkb25seSB0eXBlID0gJ2RhdGUnO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGRhdGVTZXJ2aWNlOiBEYXRlU2VydmljZSkge31cclxuXHJcbiAgcmVuZGVyKGNvbnRleHQ6IElSZW5kZXJDb250ZXh0KTogdm9pZCB7XHJcbiAgICBjb25zdCBkYXRlcyA9IGNvbnRleHQuZmlsdGVyWydkYXRlJ10gfHwgW107XHJcbiAgICBjb25zdCByZXNvdXJjZUlkcyA9IGNvbnRleHQuZmlsdGVyWydyZXNvdXJjZSddIHx8IFtdO1xyXG5cclxuICAgIC8vIENoZWNrIGlmIGRhdGUgaGVhZGVycyBzaG91bGQgYmUgaGlkZGVuIChlLmcuLCBpbiBkYXkgdmlldylcclxuICAgIGNvbnN0IGRhdGVHcm91cGluZyA9IGNvbnRleHQuZ3JvdXBpbmdzPy5maW5kKGcgPT4gZy50eXBlID09PSAnZGF0ZScpO1xyXG4gICAgY29uc3QgaGlkZUhlYWRlciA9IGRhdGVHcm91cGluZz8uaGlkZUhlYWRlciA9PT0gdHJ1ZTtcclxuXHJcbiAgICAvLyBSZW5kZXIgZGF0ZXMgZm9yIEhWRVIgcmVzb3VyY2UgKGVsbGVyIDEgZ2FuZyBodmlzIGluZ2VuIHJlc291cmNlcylcclxuICAgIGNvbnN0IGl0ZXJhdGlvbnMgPSByZXNvdXJjZUlkcy5sZW5ndGggfHwgMTtcclxuICAgIGxldCBjb2x1bW5Db3VudCA9IDA7XHJcblxyXG4gICAgZm9yIChsZXQgciA9IDA7IHIgPCBpdGVyYXRpb25zOyByKyspIHtcclxuICAgICAgY29uc3QgcmVzb3VyY2VJZCA9IHJlc291cmNlSWRzW3JdOyAvLyB1bmRlZmluZWQgaHZpcyBpbmdlbiByZXNvdXJjZXNcclxuXHJcbiAgICAgIGZvciAoY29uc3QgZGF0ZVN0ciBvZiBkYXRlcykge1xyXG4gICAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmRhdGVTZXJ2aWNlLnBhcnNlSVNPKGRhdGVTdHIpO1xyXG5cclxuICAgICAgICAvLyBCdWlsZCBjb2x1bW5LZXkgZm9yIHVuaWZvcm0gaWRlbnRpZmljYXRpb25cclxuICAgICAgICBjb25zdCBzZWdtZW50czogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgZGF0ZTogZGF0ZVN0ciB9O1xyXG4gICAgICAgIGlmIChyZXNvdXJjZUlkKSBzZWdtZW50cy5yZXNvdXJjZSA9IHJlc291cmNlSWQ7XHJcbiAgICAgICAgY29uc3QgY29sdW1uS2V5ID0gdGhpcy5kYXRlU2VydmljZS5idWlsZENvbHVtbktleShzZWdtZW50cyk7XHJcblxyXG4gICAgICAgIC8vIEhlYWRlclxyXG4gICAgICAgIGNvbnN0IGhlYWRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1kYXktaGVhZGVyJyk7XHJcbiAgICAgICAgaGVhZGVyLmRhdGFzZXQuZGF0ZSA9IGRhdGVTdHI7XHJcbiAgICAgICAgaGVhZGVyLmRhdGFzZXQuY29sdW1uS2V5ID0gY29sdW1uS2V5O1xyXG4gICAgICAgIGlmIChyZXNvdXJjZUlkKSB7XHJcbiAgICAgICAgICBoZWFkZXIuZGF0YXNldC5yZXNvdXJjZUlkID0gcmVzb3VyY2VJZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGhpZGVIZWFkZXIpIHtcclxuICAgICAgICAgIGhlYWRlci5kYXRhc2V0LmhpZGRlbiA9ICd0cnVlJztcclxuICAgICAgICB9XHJcbiAgICAgICAgaGVhZGVyLmlubmVySFRNTCA9IGBcclxuICAgICAgICAgIDxzd3AtZGF5LW5hbWU+JHt0aGlzLmRhdGVTZXJ2aWNlLmdldERheU5hbWUoZGF0ZSwgJ3Nob3J0Jyl9PC9zd3AtZGF5LW5hbWU+XHJcbiAgICAgICAgICA8c3dwLWRheS1kYXRlPiR7ZGF0ZS5nZXREYXRlKCl9PC9zd3AtZGF5LWRhdGU+XHJcbiAgICAgICAgYDtcclxuICAgICAgICBjb250ZXh0LmhlYWRlckNvbnRhaW5lci5hcHBlbmRDaGlsZChoZWFkZXIpO1xyXG5cclxuICAgICAgICAvLyBDb2x1bW5cclxuICAgICAgICBjb25zdCBjb2x1bW4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZGF5LWNvbHVtbicpO1xyXG4gICAgICAgIGNvbHVtbi5kYXRhc2V0LmRhdGUgPSBkYXRlU3RyO1xyXG4gICAgICAgIGNvbHVtbi5kYXRhc2V0LmNvbHVtbktleSA9IGNvbHVtbktleTtcclxuICAgICAgICBpZiAocmVzb3VyY2VJZCkge1xyXG4gICAgICAgICAgY29sdW1uLmRhdGFzZXQucmVzb3VyY2VJZCA9IHJlc291cmNlSWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbHVtbi5pbm5lckhUTUwgPSAnPHN3cC1ldmVudHMtbGF5ZXI+PC9zd3AtZXZlbnRzLWxheWVyPic7XHJcbiAgICAgICAgY29udGV4dC5jb2x1bW5Db250YWluZXIuYXBwZW5kQ2hpbGQoY29sdW1uKTtcclxuXHJcbiAgICAgICAgY29sdW1uQ291bnQrKztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFNldCBncmlkIGNvbHVtbnMgb24gY29udGFpbmVyXHJcbiAgICBjb25zdCBjb250YWluZXIgPSBjb250ZXh0LmNvbHVtbkNvbnRhaW5lci5jbG9zZXN0KCdzd3AtY2FsZW5kYXItY29udGFpbmVyJyk7XHJcbiAgICBpZiAoY29udGFpbmVyKSB7XHJcbiAgICAgIChjb250YWluZXIgYXMgSFRNTEVsZW1lbnQpLnN0eWxlLnNldFByb3BlcnR5KCctLWdyaWQtY29sdW1ucycsIFN0cmluZyhjb2x1bW5Db3VudCkpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCAiaW1wb3J0IGRheWpzIGZyb20gJ2RheWpzJztcclxuaW1wb3J0IHV0YyBmcm9tICdkYXlqcy9wbHVnaW4vdXRjJztcclxuaW1wb3J0IHRpbWV6b25lIGZyb20gJ2RheWpzL3BsdWdpbi90aW1lem9uZSc7XHJcbmltcG9ydCBpc29XZWVrIGZyb20gJ2RheWpzL3BsdWdpbi9pc29XZWVrJztcclxuaW1wb3J0IHsgSVRpbWVGb3JtYXRDb25maWcgfSBmcm9tICcuL0lUaW1lRm9ybWF0Q29uZmlnJztcclxuXHJcbi8vIEVuYWJsZSBkYXlqcyBwbHVnaW5zXHJcbmRheWpzLmV4dGVuZCh1dGMpO1xyXG5kYXlqcy5leHRlbmQodGltZXpvbmUpO1xyXG5kYXlqcy5leHRlbmQoaXNvV2Vlayk7XHJcblxyXG5leHBvcnQgY2xhc3MgRGF0ZVNlcnZpY2Uge1xyXG4gIHByaXZhdGUgdGltZXpvbmU6IHN0cmluZztcclxuICBwcml2YXRlIGJhc2VEYXRlOiBkYXlqcy5EYXlqcztcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjb25maWc6IElUaW1lRm9ybWF0Q29uZmlnLCBiYXNlRGF0ZT86IERhdGUpIHtcclxuICAgIHRoaXMudGltZXpvbmUgPSBjb25maWcudGltZXpvbmU7XHJcbiAgICAvLyBBbGxvdyBzZXR0aW5nIGEgZml4ZWQgYmFzZSBkYXRlIGZvciBkZW1vL3Rlc3RpbmcgcHVycG9zZXNcclxuICAgIHRoaXMuYmFzZURhdGUgPSBiYXNlRGF0ZSA/IGRheWpzKGJhc2VEYXRlKSA6IGRheWpzKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXQgYSBmaXhlZCBiYXNlIGRhdGUgKHVzZWZ1bCBmb3IgZGVtb3Mgd2l0aCBzdGF0aWMgbW9jayBkYXRhKVxyXG4gICAqL1xyXG4gIHNldEJhc2VEYXRlKGRhdGU6IERhdGUpOiB2b2lkIHtcclxuICAgIHRoaXMuYmFzZURhdGUgPSBkYXlqcyhkYXRlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgY3VycmVudCBiYXNlIGRhdGUgKGVpdGhlciBmaXhlZCBvciB0b2RheSlcclxuICAgKi9cclxuICBnZXRCYXNlRGF0ZSgpOiBEYXRlIHtcclxuICAgIHJldHVybiB0aGlzLmJhc2VEYXRlLnRvRGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgcGFyc2VJU08oaXNvU3RyaW5nOiBzdHJpbmcpOiBEYXRlIHtcclxuICAgIHJldHVybiBkYXlqcyhpc29TdHJpbmcpLnRvRGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgZ2V0RGF5TmFtZShkYXRlOiBEYXRlLCBmb3JtYXQ6ICdzaG9ydCcgfCAnbG9uZycgPSAnc2hvcnQnKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBuZXcgSW50bC5EYXRlVGltZUZvcm1hdCh0aGlzLmNvbmZpZy5sb2NhbGUsIHsgd2Vla2RheTogZm9ybWF0IH0pLmZvcm1hdChkYXRlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBkYXRlcyBzdGFydGluZyBmcm9tIGEgZGF5IG9mZnNldFxyXG4gICAqIEBwYXJhbSBkYXlPZmZzZXQgLSBEYXkgb2Zmc2V0IGZyb20gYmFzZSBkYXRlXHJcbiAgICogQHBhcmFtIGNvdW50IC0gTnVtYmVyIG9mIGNvbnNlY3V0aXZlIGRheXMgdG8gcmV0dXJuXHJcbiAgICogQHJldHVybnMgQXJyYXkgb2YgZGF0ZSBzdHJpbmdzIGluIFlZWVktTU0tREQgZm9ybWF0XHJcbiAgICovXHJcbiAgZ2V0RGF0ZXNGcm9tT2Zmc2V0KGRheU9mZnNldDogbnVtYmVyLCBjb3VudDogbnVtYmVyKTogc3RyaW5nW10ge1xyXG4gICAgY29uc3Qgc3RhcnREYXRlID0gdGhpcy5iYXNlRGF0ZS5hZGQoZGF5T2Zmc2V0LCAnZGF5Jyk7XHJcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh7IGxlbmd0aDogY291bnQgfSwgKF8sIGkpID0+XHJcbiAgICAgIHN0YXJ0RGF0ZS5hZGQoaSwgJ2RheScpLmZvcm1hdCgnWVlZWS1NTS1ERCcpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHNwZWNpZmljIHdlZWtkYXlzIGZyb20gdGhlIHdlZWsgY29udGFpbmluZyB0aGUgb2Zmc2V0IGRhdGVcclxuICAgKiBAcGFyYW0gZGF5T2Zmc2V0IC0gRGF5IG9mZnNldCBmcm9tIGJhc2UgZGF0ZVxyXG4gICAqIEBwYXJhbSB3b3JrRGF5cyAtIEFycmF5IG9mIElTTyB3ZWVrZGF5IG51bWJlcnMgKDE9TW9uZGF5LCA3PVN1bmRheSlcclxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBkYXRlIHN0cmluZ3MgaW4gWVlZWS1NTS1ERCBmb3JtYXRcclxuICAgKi9cclxuICBnZXRXb3JrRGF5c0Zyb21PZmZzZXQoZGF5T2Zmc2V0OiBudW1iZXIsIHdvcmtEYXlzOiBudW1iZXJbXSk6IHN0cmluZ1tdIHtcclxuICAgIC8vIEdldCB0aGUgZGF0ZSBhdCBvZmZzZXQsIHRoZW4gZmluZCBpdHMgd2VlaydzIE1vbmRheVxyXG4gICAgY29uc3QgdGFyZ2V0RGF0ZSA9IHRoaXMuYmFzZURhdGUuYWRkKGRheU9mZnNldCwgJ2RheScpO1xyXG4gICAgY29uc3QgbW9uZGF5ID0gdGFyZ2V0RGF0ZS5zdGFydE9mKCd3ZWVrJykuYWRkKDEsICdkYXknKTtcclxuXHJcbiAgICByZXR1cm4gd29ya0RheXMubWFwKGlzb0RheSA9PiB7XHJcbiAgICAgIC8vIElTTzogMT1Nb25kYXksIDc9U3VuZGF5IFx1MjE5MiBkYXlzIGZyb20gTW9uZGF5OiAwLTZcclxuICAgICAgY29uc3QgZGF5c0Zyb21Nb25kYXkgPSBpc29EYXkgPT09IDcgPyA2IDogaXNvRGF5IC0gMTtcclxuICAgICAgcmV0dXJuIG1vbmRheS5hZGQoZGF5c0Zyb21Nb25kYXksICdkYXknKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8gTGVnYWN5IG1ldGhvZHMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XHJcbiAgZ2V0V2Vla0RhdGVzKHdlZWtPZmZzZXQgPSAwLCBkYXlzID0gNyk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiB0aGlzLmdldERhdGVzRnJvbU9mZnNldCh3ZWVrT2Zmc2V0ICogNywgZGF5cyk7XHJcbiAgfVxyXG5cclxuICBnZXRXb3JrV2Vla0RhdGVzKHdlZWtPZmZzZXQ6IG51bWJlciwgd29ya0RheXM6IG51bWJlcltdKTogc3RyaW5nW10ge1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0V29ya0RheXNGcm9tT2Zmc2V0KHdlZWtPZmZzZXQgKiA3LCB3b3JrRGF5cyk7XHJcbiAgfVxyXG5cclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gIC8vIEZPUk1BVFRJTkdcclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICBmb3JtYXRUaW1lKGRhdGU6IERhdGUsIHNob3dTZWNvbmRzID0gZmFsc2UpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgcGF0dGVybiA9IHNob3dTZWNvbmRzID8gJ0hIOm1tOnNzJyA6ICdISDptbSc7XHJcbiAgICByZXR1cm4gZGF5anMoZGF0ZSkuZm9ybWF0KHBhdHRlcm4pO1xyXG4gIH1cclxuXHJcbiAgZm9ybWF0VGltZVJhbmdlKHN0YXJ0OiBEYXRlLCBlbmQ6IERhdGUpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGAke3RoaXMuZm9ybWF0VGltZShzdGFydCl9IC0gJHt0aGlzLmZvcm1hdFRpbWUoZW5kKX1gO1xyXG4gIH1cclxuXHJcbiAgZm9ybWF0RGF0ZShkYXRlOiBEYXRlKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBkYXlqcyhkYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcclxuICB9XHJcblxyXG4gIGdldERhdGVLZXkoZGF0ZTogRGF0ZSk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5mb3JtYXREYXRlKGRhdGUpO1xyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAvLyBDT0xVTU4gS0VZXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgLyoqXHJcbiAgICogQnVpbGQgYSB1bmlmb3JtIGNvbHVtbktleSBmcm9tIGdyb3VwaW5nIHNlZ21lbnRzXHJcbiAgICogSGFuZGxlcyBhbnkgY29tYmluYXRpb24gb2YgZGF0ZSwgcmVzb3VyY2UsIHRlYW0sIGV0Yy5cclxuICAgKlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogYnVpbGRDb2x1bW5LZXkoeyBkYXRlOiAnMjAyNS0xMi0wOScgfSkgXHUyMTkyIFwiMjAyNS0xMi0wOVwiXHJcbiAgICogYnVpbGRDb2x1bW5LZXkoeyBkYXRlOiAnMjAyNS0xMi0wOScsIHJlc291cmNlOiAnRU1QMDAxJyB9KSBcdTIxOTIgXCIyMDI1LTEyLTA5OkVNUDAwMVwiXHJcbiAgICovXHJcbiAgYnVpbGRDb2x1bW5LZXkoc2VnbWVudHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pOiBzdHJpbmcge1xyXG4gICAgLy8gQWx3YXlzIHB1dCBkYXRlIGZpcnN0IGlmIHByZXNlbnQsIHRoZW4gb3RoZXIgc2VnbWVudHMgYWxwaGFiZXRpY2FsbHlcclxuICAgIGNvbnN0IGRhdGUgPSBzZWdtZW50cy5kYXRlO1xyXG4gICAgY29uc3Qgb3RoZXJzID0gT2JqZWN0LmVudHJpZXMoc2VnbWVudHMpXHJcbiAgICAgIC5maWx0ZXIoKFtrXSkgPT4gayAhPT0gJ2RhdGUnKVxyXG4gICAgICAuc29ydCgoW2FdLCBbYl0pID0+IGEubG9jYWxlQ29tcGFyZShiKSlcclxuICAgICAgLm1hcCgoWywgdl0pID0+IHYpO1xyXG5cclxuICAgIHJldHVybiBkYXRlID8gW2RhdGUsIC4uLm90aGVyc10uam9pbignOicpIDogb3RoZXJzLmpvaW4oJzonKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFBhcnNlIGEgY29sdW1uS2V5IGJhY2sgaW50byBzZWdtZW50c1xyXG4gICAqIEFzc3VtZXMgZm9ybWF0OiBcImRhdGU6cmVzb3VyY2U6Li4uXCIgb3IganVzdCBcImRhdGVcIlxyXG4gICAqL1xyXG4gIHBhcnNlQ29sdW1uS2V5KGNvbHVtbktleTogc3RyaW5nKTogeyBkYXRlOiBzdHJpbmc7IHJlc291cmNlPzogc3RyaW5nIH0ge1xyXG4gICAgY29uc3QgcGFydHMgPSBjb2x1bW5LZXkuc3BsaXQoJzonKTtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGRhdGU6IHBhcnRzWzBdLFxyXG4gICAgICByZXNvdXJjZTogcGFydHNbMV1cclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFeHRyYWN0IGRhdGVLZXkgZnJvbSBjb2x1bW5LZXkgKGZpcnN0IHNlZ21lbnQpXHJcbiAgICovXHJcbiAgZ2V0RGF0ZUZyb21Db2x1bW5LZXkoY29sdW1uS2V5OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGNvbHVtbktleS5zcGxpdCgnOicpWzBdO1xyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAvLyBUSU1FIENBTENVTEFUSU9OU1xyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIHRpbWVUb01pbnV0ZXModGltZVN0cmluZzogc3RyaW5nKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IHBhcnRzID0gdGltZVN0cmluZy5zcGxpdCgnOicpLm1hcChOdW1iZXIpO1xyXG4gICAgY29uc3QgaG91cnMgPSBwYXJ0c1swXSB8fCAwO1xyXG4gICAgY29uc3QgbWludXRlcyA9IHBhcnRzWzFdIHx8IDA7XHJcbiAgICByZXR1cm4gaG91cnMgKiA2MCArIG1pbnV0ZXM7XHJcbiAgfVxyXG5cclxuICBtaW51dGVzVG9UaW1lKHRvdGFsTWludXRlczogbnVtYmVyKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IGhvdXJzID0gTWF0aC5mbG9vcih0b3RhbE1pbnV0ZXMgLyA2MCk7XHJcbiAgICBjb25zdCBtaW51dGVzID0gdG90YWxNaW51dGVzICUgNjA7XHJcbiAgICByZXR1cm4gZGF5anMoKS5ob3VyKGhvdXJzKS5taW51dGUobWludXRlcykuZm9ybWF0KCdISDptbScpO1xyXG4gIH1cclxuXHJcbiAgZ2V0TWludXRlc1NpbmNlTWlkbmlnaHQoZGF0ZTogRGF0ZSk6IG51bWJlciB7XHJcbiAgICBjb25zdCBkID0gZGF5anMoZGF0ZSk7XHJcbiAgICByZXR1cm4gZC5ob3VyKCkgKiA2MCArIGQubWludXRlKCk7XHJcbiAgfVxyXG5cclxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxyXG4gIC8vIFVUQyBDT05WRVJTSU9OU1xyXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIHRvVVRDKGxvY2FsRGF0ZTogRGF0ZSk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gZGF5anMudHoobG9jYWxEYXRlLCB0aGlzLnRpbWV6b25lKS51dGMoKS50b0lTT1N0cmluZygpO1xyXG4gIH1cclxuXHJcbiAgZnJvbVVUQyh1dGNTdHJpbmc6IHN0cmluZyk6IERhdGUge1xyXG4gICAgcmV0dXJuIGRheWpzLnV0Yyh1dGNTdHJpbmcpLnR6KHRoaXMudGltZXpvbmUpLnRvRGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuICAvLyBEQVRFIENSRUFUSU9OXHJcbiAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgY3JlYXRlRGF0ZUF0VGltZShiYXNlRGF0ZTogRGF0ZSB8IHN0cmluZywgdGltZVN0cmluZzogc3RyaW5nKTogRGF0ZSB7XHJcbiAgICBjb25zdCB0b3RhbE1pbnV0ZXMgPSB0aGlzLnRpbWVUb01pbnV0ZXModGltZVN0cmluZyk7XHJcbiAgICBjb25zdCBob3VycyA9IE1hdGguZmxvb3IodG90YWxNaW51dGVzIC8gNjApO1xyXG4gICAgY29uc3QgbWludXRlcyA9IHRvdGFsTWludXRlcyAlIDYwO1xyXG4gICAgcmV0dXJuIGRheWpzKGJhc2VEYXRlKS5zdGFydE9mKCdkYXknKS5ob3VyKGhvdXJzKS5taW51dGUobWludXRlcykudG9EYXRlKCk7XHJcbiAgfVxyXG5cclxuICBnZXRJU09XZWVrRGF5KGRhdGU6IERhdGUgfCBzdHJpbmcpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIGRheWpzKGRhdGUpLmlzb1dlZWtkYXkoKTsgIC8vIDE9TW9uZGF5LCA3PVN1bmRheVxyXG4gIH1cclxufVxyXG4iLCAiLyoqXG4gKiBQb3NpdGlvblV0aWxzIC0gUGl4ZWwvcG9zaXRpb24gY2FsY3VsYXRpb25zIGZvciBjYWxlbmRhciBncmlkXG4gKlxuICogUkVTUE9OU0lCSUxJVFk6IENvbnZlcnQgYmV0d2VlbiB0aW1lIGFuZCBwaXhlbCBwb3NpdGlvbnNcbiAqIE5PVEU6IERhdGUgZm9ybWF0dGluZyBiZWxvbmdzIGluIERhdGVTZXJ2aWNlLCBub3QgaGVyZVxuICovXG5cbmltcG9ydCB7IElHcmlkQ29uZmlnIH0gZnJvbSAnLi4vY29yZS9JR3JpZENvbmZpZyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXZlbnRQb3NpdGlvbiB7XG4gIHRvcDogbnVtYmVyOyAgICAvLyBwaXhlbHMgZnJvbSBkYXkgc3RhcnRcbiAgaGVpZ2h0OiBudW1iZXI7IC8vIHBpeGVsc1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBwaXhlbCBwb3NpdGlvbiBmb3IgYW4gZXZlbnQgYmFzZWQgb24gaXRzIHRpbWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxjdWxhdGVFdmVudFBvc2l0aW9uKFxuICBzdGFydDogRGF0ZSxcbiAgZW5kOiBEYXRlLFxuICBjb25maWc6IElHcmlkQ29uZmlnXG4pOiBFdmVudFBvc2l0aW9uIHtcbiAgY29uc3Qgc3RhcnRNaW51dGVzID0gc3RhcnQuZ2V0SG91cnMoKSAqIDYwICsgc3RhcnQuZ2V0TWludXRlcygpO1xuICBjb25zdCBlbmRNaW51dGVzID0gZW5kLmdldEhvdXJzKCkgKiA2MCArIGVuZC5nZXRNaW51dGVzKCk7XG5cbiAgY29uc3QgZGF5U3RhcnRNaW51dGVzID0gY29uZmlnLmRheVN0YXJ0SG91ciAqIDYwO1xuICBjb25zdCBtaW51dGVIZWlnaHQgPSBjb25maWcuaG91ckhlaWdodCAvIDYwO1xuXG4gIGNvbnN0IHRvcCA9IChzdGFydE1pbnV0ZXMgLSBkYXlTdGFydE1pbnV0ZXMpICogbWludXRlSGVpZ2h0O1xuICBjb25zdCBoZWlnaHQgPSAoZW5kTWludXRlcyAtIHN0YXJ0TWludXRlcykgKiBtaW51dGVIZWlnaHQ7XG5cbiAgcmV0dXJuIHsgdG9wLCBoZWlnaHQgfTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IG1pbnV0ZXMgdG8gcGl4ZWxzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtaW51dGVzVG9QaXhlbHMobWludXRlczogbnVtYmVyLCBjb25maWc6IElHcmlkQ29uZmlnKTogbnVtYmVyIHtcbiAgcmV0dXJuIChtaW51dGVzIC8gNjApICogY29uZmlnLmhvdXJIZWlnaHQ7XG59XG5cbi8qKlxuICogQ29udmVydCBwaXhlbHMgdG8gbWludXRlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGl4ZWxzVG9NaW51dGVzKHBpeGVsczogbnVtYmVyLCBjb25maWc6IElHcmlkQ29uZmlnKTogbnVtYmVyIHtcbiAgcmV0dXJuIChwaXhlbHMgLyBjb25maWcuaG91ckhlaWdodCkgKiA2MDtcbn1cblxuLyoqXG4gKiBTbmFwIHBpeGVsIHBvc2l0aW9uIHRvIGdyaWQgaW50ZXJ2YWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNuYXBUb0dyaWQocGl4ZWxzOiBudW1iZXIsIGNvbmZpZzogSUdyaWRDb25maWcpOiBudW1iZXIge1xuICBjb25zdCBzbmFwUGl4ZWxzID0gbWludXRlc1RvUGl4ZWxzKGNvbmZpZy5zbmFwSW50ZXJ2YWwsIGNvbmZpZyk7XG4gIHJldHVybiBNYXRoLnJvdW5kKHBpeGVscyAvIHNuYXBQaXhlbHMpICogc25hcFBpeGVscztcbn1cbiIsICIvKipcbiAqIENvcmVFdmVudHMgLSBDb25zb2xpZGF0ZWQgZXNzZW50aWFsIGV2ZW50cyBmb3IgdGhlIGNhbGVuZGFyXG4gKi9cbmV4cG9ydCBjb25zdCBDb3JlRXZlbnRzID0ge1xuICAvLyBMaWZlY3ljbGUgZXZlbnRzXG4gIElOSVRJQUxJWkVEOiAnY29yZTppbml0aWFsaXplZCcsXG4gIFJFQURZOiAnY29yZTpyZWFkeScsXG4gIERFU1RST1lFRDogJ2NvcmU6ZGVzdHJveWVkJyxcblxuICAvLyBWaWV3IGV2ZW50c1xuICBWSUVXX0NIQU5HRUQ6ICd2aWV3OmNoYW5nZWQnLFxuICBWSUVXX1JFTkRFUkVEOiAndmlldzpyZW5kZXJlZCcsXG5cbiAgLy8gTmF2aWdhdGlvbiBldmVudHNcbiAgREFURV9DSEFOR0VEOiAnbmF2OmRhdGUtY2hhbmdlZCcsXG4gIE5BVklHQVRJT05fQ09NUExFVEVEOiAnbmF2Om5hdmlnYXRpb24tY29tcGxldGVkJyxcblxuICAvLyBEYXRhIGV2ZW50c1xuICBEQVRBX0xPQURJTkc6ICdkYXRhOmxvYWRpbmcnLFxuICBEQVRBX0xPQURFRDogJ2RhdGE6bG9hZGVkJyxcbiAgREFUQV9FUlJPUjogJ2RhdGE6ZXJyb3InLFxuXG4gIC8vIEdyaWQgZXZlbnRzXG4gIEdSSURfUkVOREVSRUQ6ICdncmlkOnJlbmRlcmVkJyxcbiAgR1JJRF9DTElDS0VEOiAnZ3JpZDpjbGlja2VkJyxcblxuICAvLyBFdmVudCBtYW5hZ2VtZW50XG4gIEVWRU5UX0NSRUFURUQ6ICdldmVudDpjcmVhdGVkJyxcbiAgRVZFTlRfVVBEQVRFRDogJ2V2ZW50OnVwZGF0ZWQnLFxuICBFVkVOVF9ERUxFVEVEOiAnZXZlbnQ6ZGVsZXRlZCcsXG4gIEVWRU5UX1NFTEVDVEVEOiAnZXZlbnQ6c2VsZWN0ZWQnLFxuXG4gIC8vIEV2ZW50IGRyYWctZHJvcFxuICBFVkVOVF9EUkFHX1NUQVJUOiAnZXZlbnQ6ZHJhZy1zdGFydCcsXG4gIEVWRU5UX0RSQUdfTU9WRTogJ2V2ZW50OmRyYWctbW92ZScsXG4gIEVWRU5UX0RSQUdfRU5EOiAnZXZlbnQ6ZHJhZy1lbmQnLFxuICBFVkVOVF9EUkFHX0NBTkNFTDogJ2V2ZW50OmRyYWctY2FuY2VsJyxcbiAgRVZFTlRfRFJBR19DT0xVTU5fQ0hBTkdFOiAnZXZlbnQ6ZHJhZy1jb2x1bW4tY2hhbmdlJyxcblxuICAvLyBIZWFkZXIgZHJhZyAodGltZWQgXHUyMTkyIGhlYWRlciBjb252ZXJzaW9uKVxuICBFVkVOVF9EUkFHX0VOVEVSX0hFQURFUjogJ2V2ZW50OmRyYWctZW50ZXItaGVhZGVyJyxcbiAgRVZFTlRfRFJBR19NT1ZFX0hFQURFUjogJ2V2ZW50OmRyYWctbW92ZS1oZWFkZXInLFxuICBFVkVOVF9EUkFHX0xFQVZFX0hFQURFUjogJ2V2ZW50OmRyYWctbGVhdmUtaGVhZGVyJyxcblxuICAvLyBFdmVudCByZXNpemVcbiAgRVZFTlRfUkVTSVpFX1NUQVJUOiAnZXZlbnQ6cmVzaXplLXN0YXJ0JyxcbiAgRVZFTlRfUkVTSVpFX0VORDogJ2V2ZW50OnJlc2l6ZS1lbmQnLFxuXG4gIC8vIEVkZ2Ugc2Nyb2xsXG4gIEVER0VfU0NST0xMX1RJQ0s6ICdlZGdlLXNjcm9sbDp0aWNrJyxcbiAgRURHRV9TQ1JPTExfU1RBUlRFRDogJ2VkZ2Utc2Nyb2xsOnN0YXJ0ZWQnLFxuICBFREdFX1NDUk9MTF9TVE9QUEVEOiAnZWRnZS1zY3JvbGw6c3RvcHBlZCcsXG5cbiAgLy8gU3lzdGVtIGV2ZW50c1xuICBFUlJPUjogJ3N5c3RlbTplcnJvcicsXG5cbiAgLy8gU3luYyBldmVudHNcbiAgU1lOQ19TVEFSVEVEOiAnc3luYzpzdGFydGVkJyxcbiAgU1lOQ19DT01QTEVURUQ6ICdzeW5jOmNvbXBsZXRlZCcsXG4gIFNZTkNfRkFJTEVEOiAnc3luYzpmYWlsZWQnLFxuXG4gIC8vIEVudGl0eSBldmVudHMgLSBmb3IgYXVkaXQgYW5kIHN5bmNcbiAgRU5USVRZX1NBVkVEOiAnZW50aXR5OnNhdmVkJyxcbiAgRU5USVRZX0RFTEVURUQ6ICdlbnRpdHk6ZGVsZXRlZCcsXG5cbiAgLy8gQXVkaXQgZXZlbnRzXG4gIEFVRElUX0xPR0dFRDogJ2F1ZGl0OmxvZ2dlZCcsXG5cbiAgLy8gUmVuZGVyaW5nIGV2ZW50c1xuICBFVkVOVFNfUkVOREVSRUQ6ICdldmVudHM6cmVuZGVyZWQnXG59IGFzIGNvbnN0O1xuIiwgIi8qKlxyXG4gKiBFdmVudExheW91dEVuZ2luZSAtIFNpbXBsaWZpZWQgc3RhY2tpbmcvZ3JvdXBpbmcgYWxnb3JpdGhtXHJcbiAqXHJcbiAqIFN1cHBvcnRzIHR3byBsYXlvdXQgbW9kZXM6XHJcbiAqIC0gR1JJRDogRXZlbnRzIHN0YXJ0aW5nIGF0IHNhbWUgdGltZSByZW5kZXJlZCBzaWRlLWJ5LXNpZGVcclxuICogLSBTVEFDS0lORzogT3ZlcmxhcHBpbmcgZXZlbnRzIHdpdGggbWFyZ2luLWxlZnQgb2Zmc2V0ICgxNXB4IHBlciBsZXZlbClcclxuICpcclxuICogTm8gcHJldi9uZXh0IGNoYWlucywgc2luZ2xlLXBhc3MgZ3JlZWR5IGFsZ29yaXRobVxyXG4gKi9cclxuXHJcbmltcG9ydCB7IElDYWxlbmRhckV2ZW50IH0gZnJvbSAnLi4vLi4vdHlwZXMvQ2FsZW5kYXJUeXBlcyc7XHJcbmltcG9ydCB7IElHcmlkQ29uZmlnIH0gZnJvbSAnLi4vLi4vY29yZS9JR3JpZENvbmZpZyc7XHJcbmltcG9ydCB7IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24gfSBmcm9tICcuLi8uLi91dGlscy9Qb3NpdGlvblV0aWxzJztcclxuaW1wb3J0IHsgSUNvbHVtbkxheW91dCwgSUdyaWRHcm91cExheW91dCwgSVN0YWNrZWRFdmVudExheW91dCB9IGZyb20gJy4vRXZlbnRMYXlvdXRUeXBlcyc7XHJcblxyXG4vKipcclxuICogQ2hlY2sgaWYgdHdvIGV2ZW50cyBvdmVybGFwIChzdHJpY3QgLSB0b3VjaGluZyBhdCBib3VuZGFyeSA9IE5PVCBvdmVybGFwcGluZylcclxuICogVGhpcyBtYXRjaGVzIFNjZW5hcmlvIDg6IGVuZD09PXN0YXJ0IGlzIE5PVCBvdmVybGFwXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZXZlbnRzT3ZlcmxhcChhOiBJQ2FsZW5kYXJFdmVudCwgYjogSUNhbGVuZGFyRXZlbnQpOiBib29sZWFuIHtcclxuICByZXR1cm4gYS5zdGFydCA8IGIuZW5kICYmIGEuZW5kID4gYi5zdGFydDtcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIHR3byBldmVudHMgYXJlIHdpdGhpbiB0aHJlc2hvbGQgZm9yIGdyaWQgZ3JvdXBpbmcuXHJcbiAqIFRoaXMgaW5jbHVkZXM6XHJcbiAqIDEuIFN0YXJ0LXRvLXN0YXJ0OiBFdmVudHMgc3RhcnQgd2l0aGluIHRocmVzaG9sZCBvZiBlYWNoIG90aGVyXHJcbiAqIDIuIEVuZC10by1zdGFydDogT25lIGV2ZW50IHN0YXJ0cyB3aXRoaW4gdGhyZXNob2xkIGJlZm9yZSBhbm90aGVyIGVuZHNcclxuICovXHJcbmZ1bmN0aW9uIGV2ZW50c1dpdGhpblRocmVzaG9sZChhOiBJQ2FsZW5kYXJFdmVudCwgYjogSUNhbGVuZGFyRXZlbnQsIHRocmVzaG9sZE1pbnV0ZXM6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gIGNvbnN0IHRocmVzaG9sZE1zID0gdGhyZXNob2xkTWludXRlcyAqIDYwICogMTAwMDtcclxuXHJcbiAgLy8gU3RhcnQtdG8tc3RhcnQ6IGJvdGggZXZlbnRzIHN0YXJ0IHdpdGhpbiB0aHJlc2hvbGRcclxuICBjb25zdCBzdGFydFRvU3RhcnREaWZmID0gTWF0aC5hYnMoYS5zdGFydC5nZXRUaW1lKCkgLSBiLnN0YXJ0LmdldFRpbWUoKSk7XHJcbiAgaWYgKHN0YXJ0VG9TdGFydERpZmYgPD0gdGhyZXNob2xkTXMpIHJldHVybiB0cnVlO1xyXG5cclxuICAvLyBFbmQtdG8tc3RhcnQ6IG9uZSBldmVudCBzdGFydHMgd2l0aGluIHRocmVzaG9sZCBiZWZvcmUgdGhlIG90aGVyIGVuZHNcclxuICAvLyBCIHN0YXJ0cyB3aXRoaW4gdGhyZXNob2xkIGJlZm9yZSBBIGVuZHNcclxuICBjb25zdCBiU3RhcnRzQmVmb3JlQUVuZHMgPSBhLmVuZC5nZXRUaW1lKCkgLSBiLnN0YXJ0LmdldFRpbWUoKTtcclxuICBpZiAoYlN0YXJ0c0JlZm9yZUFFbmRzID4gMCAmJiBiU3RhcnRzQmVmb3JlQUVuZHMgPD0gdGhyZXNob2xkTXMpIHJldHVybiB0cnVlO1xyXG5cclxuICAvLyBBIHN0YXJ0cyB3aXRoaW4gdGhyZXNob2xkIGJlZm9yZSBCIGVuZHNcclxuICBjb25zdCBhU3RhcnRzQmVmb3JlQkVuZHMgPSBiLmVuZC5nZXRUaW1lKCkgLSBhLnN0YXJ0LmdldFRpbWUoKTtcclxuICBpZiAoYVN0YXJ0c0JlZm9yZUJFbmRzID4gMCAmJiBhU3RhcnRzQmVmb3JlQkVuZHMgPD0gdGhyZXNob2xkTXMpIHJldHVybiB0cnVlO1xyXG5cclxuICByZXR1cm4gZmFsc2U7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiBhbGwgZXZlbnRzIGluIGEgZ3JvdXAgc3RhcnQgd2l0aGluIHRocmVzaG9sZCBvZiBlYWNoIG90aGVyXHJcbiAqL1xyXG5mdW5jdGlvbiBhbGxTdGFydFdpdGhpblRocmVzaG9sZChldmVudHM6IElDYWxlbmRhckV2ZW50W10sIHRocmVzaG9sZE1pbnV0ZXM6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gIGlmIChldmVudHMubGVuZ3RoIDw9IDEpIHJldHVybiB0cnVlO1xyXG5cclxuICAvLyBGaW5kIGVhcmxpZXN0IGFuZCBsYXRlc3Qgc3RhcnQgdGltZXNcclxuICBsZXQgZWFybGllc3QgPSBldmVudHNbMF0uc3RhcnQuZ2V0VGltZSgpO1xyXG4gIGxldCBsYXRlc3QgPSBldmVudHNbMF0uc3RhcnQuZ2V0VGltZSgpO1xyXG5cclxuICBmb3IgKGNvbnN0IGV2ZW50IG9mIGV2ZW50cykge1xyXG4gICAgY29uc3QgdGltZSA9IGV2ZW50LnN0YXJ0LmdldFRpbWUoKTtcclxuICAgIGlmICh0aW1lIDwgZWFybGllc3QpIGVhcmxpZXN0ID0gdGltZTtcclxuICAgIGlmICh0aW1lID4gbGF0ZXN0KSBsYXRlc3QgPSB0aW1lO1xyXG4gIH1cclxuXHJcbiAgY29uc3QgZGlmZk1pbnV0ZXMgPSAobGF0ZXN0IC0gZWFybGllc3QpIC8gKDEwMDAgKiA2MCk7XHJcbiAgcmV0dXJuIGRpZmZNaW51dGVzIDw9IHRocmVzaG9sZE1pbnV0ZXM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGaW5kIGdyb3VwcyBvZiBvdmVybGFwcGluZyBldmVudHMgKGNvbm5lY3RlZCBieSBvdmVybGFwIGNoYWluKVxyXG4gKiBFdmVudHMgYXJlIGdyb3VwZWQgaWYgdGhleSBvdmVybGFwIHdpdGggYW55IGV2ZW50IGluIHRoZSBncm91cFxyXG4gKi9cclxuZnVuY3Rpb24gZmluZE92ZXJsYXBHcm91cHMoZXZlbnRzOiBJQ2FsZW5kYXJFdmVudFtdKTogSUNhbGVuZGFyRXZlbnRbXVtdIHtcclxuICBpZiAoZXZlbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xyXG5cclxuICBjb25zdCBzb3J0ZWQgPSBbLi4uZXZlbnRzXS5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0LmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpKTtcclxuICBjb25zdCB1c2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XHJcbiAgY29uc3QgZ3JvdXBzOiBJQ2FsZW5kYXJFdmVudFtdW10gPSBbXTtcclxuXHJcbiAgZm9yIChjb25zdCBldmVudCBvZiBzb3J0ZWQpIHtcclxuICAgIGlmICh1c2VkLmhhcyhldmVudC5pZCkpIGNvbnRpbnVlO1xyXG5cclxuICAgIC8vIFN0YXJ0IGEgbmV3IGdyb3VwIHdpdGggdGhpcyBldmVudFxyXG4gICAgY29uc3QgZ3JvdXA6IElDYWxlbmRhckV2ZW50W10gPSBbZXZlbnRdO1xyXG4gICAgdXNlZC5hZGQoZXZlbnQuaWQpO1xyXG5cclxuICAgIC8vIEV4cGFuZCBncm91cCBieSBmaW5kaW5nIGFsbCBjb25uZWN0ZWQgZXZlbnRzICh2aWEgb3ZlcmxhcClcclxuICAgIGxldCBleHBhbmRlZCA9IHRydWU7XHJcbiAgICB3aGlsZSAoZXhwYW5kZWQpIHtcclxuICAgICAgZXhwYW5kZWQgPSBmYWxzZTtcclxuICAgICAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2Ygc29ydGVkKSB7XHJcbiAgICAgICAgaWYgKHVzZWQuaGFzKGNhbmRpZGF0ZS5pZCkpIGNvbnRpbnVlO1xyXG5cclxuICAgICAgICAvLyBDaGVjayBpZiBjYW5kaWRhdGUgb3ZlcmxhcHMgd2l0aCBhbnkgZXZlbnQgaW4gZ3JvdXBcclxuICAgICAgICBjb25zdCBjb25uZWN0cyA9IGdyb3VwLnNvbWUobWVtYmVyID0+IGV2ZW50c092ZXJsYXAobWVtYmVyLCBjYW5kaWRhdGUpKTtcclxuXHJcbiAgICAgICAgaWYgKGNvbm5lY3RzKSB7XHJcbiAgICAgICAgICBncm91cC5wdXNoKGNhbmRpZGF0ZSk7XHJcbiAgICAgICAgICB1c2VkLmFkZChjYW5kaWRhdGUuaWQpO1xyXG4gICAgICAgICAgZXhwYW5kZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdyb3Vwcy5wdXNoKGdyb3VwKTtcclxuICB9XHJcblxyXG4gIHJldHVybiBncm91cHM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGaW5kIGdyaWQgY2FuZGlkYXRlcyB3aXRoaW4gYSBncm91cCAtIGV2ZW50cyBjb25uZWN0ZWQgdmlhIHRocmVzaG9sZCBjaGFpblxyXG4gKiBVc2VzIFYxIGxvZ2ljOiBldmVudHMgYXJlIGNvbm5lY3RlZCBpZiB3aXRoaW4gdGhyZXNob2xkIChubyBvdmVybGFwIHJlcXVpcmVtZW50KVxyXG4gKi9cclxuZnVuY3Rpb24gZmluZEdyaWRDYW5kaWRhdGVzKFxyXG4gIGV2ZW50czogSUNhbGVuZGFyRXZlbnRbXSxcclxuICB0aHJlc2hvbGRNaW51dGVzOiBudW1iZXJcclxuKTogSUNhbGVuZGFyRXZlbnRbXVtdIHtcclxuICBpZiAoZXZlbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xyXG5cclxuICBjb25zdCBzb3J0ZWQgPSBbLi4uZXZlbnRzXS5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0LmdldFRpbWUoKSAtIGIuc3RhcnQuZ2V0VGltZSgpKTtcclxuICBjb25zdCB1c2VkID0gbmV3IFNldDxzdHJpbmc+KCk7XHJcbiAgY29uc3QgZ3JvdXBzOiBJQ2FsZW5kYXJFdmVudFtdW10gPSBbXTtcclxuXHJcbiAgZm9yIChjb25zdCBldmVudCBvZiBzb3J0ZWQpIHtcclxuICAgIGlmICh1c2VkLmhhcyhldmVudC5pZCkpIGNvbnRpbnVlO1xyXG5cclxuICAgIGNvbnN0IGdyb3VwOiBJQ2FsZW5kYXJFdmVudFtdID0gW2V2ZW50XTtcclxuICAgIHVzZWQuYWRkKGV2ZW50LmlkKTtcclxuXHJcbiAgICAvLyBFeHBhbmQgYnkgdGhyZXNob2xkIGNoYWluIChWMSBsb2dpYzogbm8gb3ZlcmxhcCByZXF1aXJlbWVudCwganVzdCB0aHJlc2hvbGQpXHJcbiAgICBsZXQgZXhwYW5kZWQgPSB0cnVlO1xyXG4gICAgd2hpbGUgKGV4cGFuZGVkKSB7XHJcbiAgICAgIGV4cGFuZGVkID0gZmFsc2U7XHJcbiAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIHNvcnRlZCkge1xyXG4gICAgICAgIGlmICh1c2VkLmhhcyhjYW5kaWRhdGUuaWQpKSBjb250aW51ZTtcclxuXHJcbiAgICAgICAgY29uc3QgY29ubmVjdHMgPSBncm91cC5zb21lKG1lbWJlciA9PlxyXG4gICAgICAgICAgZXZlbnRzV2l0aGluVGhyZXNob2xkKG1lbWJlciwgY2FuZGlkYXRlLCB0aHJlc2hvbGRNaW51dGVzKVxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIGlmIChjb25uZWN0cykge1xyXG4gICAgICAgICAgZ3JvdXAucHVzaChjYW5kaWRhdGUpO1xyXG4gICAgICAgICAgdXNlZC5hZGQoY2FuZGlkYXRlLmlkKTtcclxuICAgICAgICAgIGV4cGFuZGVkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBncm91cHMucHVzaChncm91cCk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZ3JvdXBzO1xyXG59XHJcblxyXG4vKipcclxuICogQ2FsY3VsYXRlIHN0YWNrIGxldmVscyBmb3Igb3ZlcmxhcHBpbmcgZXZlbnRzIHVzaW5nIGdyZWVkeSBhbGdvcml0aG1cclxuICogRm9yIGVhY2ggZXZlbnQ6IGxldmVsID0gbWF4KG92ZXJsYXBwaW5nIGFscmVhZHktcHJvY2Vzc2VkIGV2ZW50cykgKyAxXHJcbiAqL1xyXG5mdW5jdGlvbiBjYWxjdWxhdGVTdGFja0xldmVscyhldmVudHM6IElDYWxlbmRhckV2ZW50W10pOiBNYXA8c3RyaW5nLCBudW1iZXI+IHtcclxuICBjb25zdCBsZXZlbHMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xyXG4gIGNvbnN0IHNvcnRlZCA9IFsuLi5ldmVudHNdLnNvcnQoKGEsIGIpID0+IGEuc3RhcnQuZ2V0VGltZSgpIC0gYi5zdGFydC5nZXRUaW1lKCkpO1xyXG5cclxuICBmb3IgKGNvbnN0IGV2ZW50IG9mIHNvcnRlZCkge1xyXG4gICAgbGV0IG1heE92ZXJsYXBwaW5nTGV2ZWwgPSAtMTtcclxuXHJcbiAgICAvLyBGaW5kIG1heCBsZXZlbCBhbW9uZyBvdmVybGFwcGluZyBldmVudHMgYWxyZWFkeSBwcm9jZXNzZWRcclxuICAgIGZvciAoY29uc3QgW2lkLCBsZXZlbF0gb2YgbGV2ZWxzKSB7XHJcbiAgICAgIGNvbnN0IG90aGVyID0gZXZlbnRzLmZpbmQoZSA9PiBlLmlkID09PSBpZCk7XHJcbiAgICAgIGlmIChvdGhlciAmJiBldmVudHNPdmVybGFwKGV2ZW50LCBvdGhlcikpIHtcclxuICAgICAgICBtYXhPdmVybGFwcGluZ0xldmVsID0gTWF0aC5tYXgobWF4T3ZlcmxhcHBpbmdMZXZlbCwgbGV2ZWwpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgbGV2ZWxzLnNldChldmVudC5pZCwgbWF4T3ZlcmxhcHBpbmdMZXZlbCArIDEpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGxldmVscztcclxufVxyXG5cclxuLyoqXHJcbiAqIEFsbG9jYXRlIGV2ZW50cyB0byBjb2x1bW5zIGZvciBHUklEIGxheW91dCB1c2luZyBncmVlZHkgYWxnb3JpdGhtXHJcbiAqIE5vbi1vdmVybGFwcGluZyBldmVudHMgY2FuIHNoYXJlIGEgY29sdW1uIHRvIG1pbmltaXplIHRvdGFsIGNvbHVtbnNcclxuICovXHJcbmZ1bmN0aW9uIGFsbG9jYXRlQ29sdW1ucyhldmVudHM6IElDYWxlbmRhckV2ZW50W10pOiBJQ2FsZW5kYXJFdmVudFtdW10ge1xyXG4gIGNvbnN0IHNvcnRlZCA9IFsuLi5ldmVudHNdLnNvcnQoKGEsIGIpID0+IGEuc3RhcnQuZ2V0VGltZSgpIC0gYi5zdGFydC5nZXRUaW1lKCkpO1xyXG4gIGNvbnN0IGNvbHVtbnM6IElDYWxlbmRhckV2ZW50W11bXSA9IFtdO1xyXG5cclxuICBmb3IgKGNvbnN0IGV2ZW50IG9mIHNvcnRlZCkge1xyXG4gICAgLy8gRmluZCBmaXJzdCBjb2x1bW4gd2hlcmUgZXZlbnQgZG9lc24ndCBvdmVybGFwIHdpdGggZXhpc3RpbmcgZXZlbnRzXHJcbiAgICBsZXQgcGxhY2VkID0gZmFsc2U7XHJcbiAgICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBjb2x1bW5zKSB7XHJcbiAgICAgIGNvbnN0IGNhbkZpdCA9ICFjb2x1bW4uc29tZShlID0+IGV2ZW50c092ZXJsYXAoZXZlbnQsIGUpKTtcclxuICAgICAgaWYgKGNhbkZpdCkge1xyXG4gICAgICAgIGNvbHVtbi5wdXNoKGV2ZW50KTtcclxuICAgICAgICBwbGFjZWQgPSB0cnVlO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gTm8gc3VpdGFibGUgY29sdW1uIGZvdW5kLCBjcmVhdGUgbmV3IG9uZVxyXG4gICAgaWYgKCFwbGFjZWQpIHtcclxuICAgICAgY29sdW1ucy5wdXNoKFtldmVudF0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGNvbHVtbnM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBNYWluIGVudHJ5IHBvaW50OiBDYWxjdWxhdGUgY29tcGxldGUgbGF5b3V0IGZvciBhIGNvbHVtbidzIGV2ZW50c1xyXG4gKlxyXG4gKiBBbGdvcml0aG06XHJcbiAqIDEuIEZpbmQgb3ZlcmxhcCBncm91cHMgKGV2ZW50cyBjb25uZWN0ZWQgYnkgb3ZlcmxhcCBjaGFpbilcclxuICogMi4gRm9yIGVhY2ggb3ZlcmxhcCBncm91cCwgZmluZCBncmlkIGNhbmRpZGF0ZXMgKGV2ZW50cyB3aXRoaW4gdGhyZXNob2xkIGNoYWluKVxyXG4gKiAzLiBJZiBhbGwgZXZlbnRzIGluIG92ZXJsYXAgZ3JvdXAgZm9ybSBhIHNpbmdsZSBncmlkIGNhbmRpZGF0ZSBcdTIxOTIgR1JJRCBtb2RlXHJcbiAqIDQuIE90aGVyd2lzZSBcdTIxOTIgU1RBQ0tJTkcgbW9kZSB3aXRoIGNhbGN1bGF0ZWQgbGV2ZWxzXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY2FsY3VsYXRlQ29sdW1uTGF5b3V0KFxyXG4gIGV2ZW50czogSUNhbGVuZGFyRXZlbnRbXSxcclxuICBjb25maWc6IElHcmlkQ29uZmlnXHJcbik6IElDb2x1bW5MYXlvdXQge1xyXG4gIGNvbnN0IHRocmVzaG9sZE1pbnV0ZXMgPSBjb25maWcuZ3JpZFN0YXJ0VGhyZXNob2xkTWludXRlcyA/PyAxMDtcclxuXHJcbiAgY29uc3QgcmVzdWx0OiBJQ29sdW1uTGF5b3V0ID0ge1xyXG4gICAgZ3JpZHM6IFtdLFxyXG4gICAgc3RhY2tlZDogW11cclxuICB9O1xyXG5cclxuICBpZiAoZXZlbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHJlc3VsdDtcclxuXHJcbiAgLy8gRmluZCBhbGwgb3ZlcmxhcHBpbmcgZXZlbnQgZ3JvdXBzXHJcbiAgY29uc3Qgb3ZlcmxhcEdyb3VwcyA9IGZpbmRPdmVybGFwR3JvdXBzKGV2ZW50cyk7XHJcblxyXG4gIGZvciAoY29uc3Qgb3ZlcmxhcEdyb3VwIG9mIG92ZXJsYXBHcm91cHMpIHtcclxuICAgIGlmIChvdmVybGFwR3JvdXAubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgIC8vIFNpbmdsZSBldmVudCAtIG5vIGdyb3VwaW5nIG5lZWRlZFxyXG4gICAgICByZXN1bHQuc3RhY2tlZC5wdXNoKHtcclxuICAgICAgICBldmVudDogb3ZlcmxhcEdyb3VwWzBdLFxyXG4gICAgICAgIHN0YWNrTGV2ZWw6IDBcclxuICAgICAgfSk7XHJcbiAgICAgIGNvbnRpbnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFdpdGhpbiB0aGlzIG92ZXJsYXAgZ3JvdXAsIGZpbmQgZ3JpZCBjYW5kaWRhdGVzICh0aHJlc2hvbGQtY29ubmVjdGVkIHN1Ymdyb3VwcylcclxuICAgIGNvbnN0IGdyaWRTdWJncm91cHMgPSBmaW5kR3JpZENhbmRpZGF0ZXMob3ZlcmxhcEdyb3VwLCB0aHJlc2hvbGRNaW51dGVzKTtcclxuXHJcbiAgICAvLyBDaGVjayBpZiB0aGUgRU5USVJFIG92ZXJsYXAgZ3JvdXAgZm9ybXMgYSBzaW5nbGUgZ3JpZCBjYW5kaWRhdGVcclxuICAgIC8vIFRoaXMgaGFwcGVucyB3aGVuIGFsbCBldmVudHMgYXJlIGNvbm5lY3RlZCB2aWEgdGhyZXNob2xkIGNoYWluXHJcbiAgICBjb25zdCBsYXJnZXN0R3JpZENhbmRpZGF0ZSA9IGdyaWRTdWJncm91cHMucmVkdWNlKChtYXgsIGcpID0+XHJcbiAgICAgIGcubGVuZ3RoID4gbWF4Lmxlbmd0aCA/IGcgOiBtYXgsIGdyaWRTdWJncm91cHNbMF0pO1xyXG5cclxuICAgIGlmIChsYXJnZXN0R3JpZENhbmRpZGF0ZS5sZW5ndGggPT09IG92ZXJsYXBHcm91cC5sZW5ndGgpIHtcclxuICAgICAgLy8gQWxsIGV2ZW50cyBpbiBvdmVybGFwIGdyb3VwIGFyZSBjb25uZWN0ZWQgdmlhIHRocmVzaG9sZCBjaGFpbiBcdTIxOTIgR1JJRCBtb2RlXHJcbiAgICAgIGNvbnN0IGNvbHVtbnMgPSBhbGxvY2F0ZUNvbHVtbnMob3ZlcmxhcEdyb3VwKTtcclxuICAgICAgY29uc3QgZWFybGllc3QgPSBvdmVybGFwR3JvdXAucmVkdWNlKChtaW4sIGUpID0+XHJcbiAgICAgICAgZS5zdGFydCA8IG1pbi5zdGFydCA/IGUgOiBtaW4sIG92ZXJsYXBHcm91cFswXSk7XHJcbiAgICAgIGNvbnN0IHBvc2l0aW9uID0gY2FsY3VsYXRlRXZlbnRQb3NpdGlvbihlYXJsaWVzdC5zdGFydCwgZWFybGllc3QuZW5kLCBjb25maWcpO1xyXG5cclxuICAgICAgcmVzdWx0LmdyaWRzLnB1c2goe1xyXG4gICAgICAgIGV2ZW50czogb3ZlcmxhcEdyb3VwLFxyXG4gICAgICAgIGNvbHVtbnMsXHJcbiAgICAgICAgc3RhY2tMZXZlbDogMCxcclxuICAgICAgICBwb3NpdGlvbjogeyB0b3A6IHBvc2l0aW9uLnRvcCB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gTm90IGFsbCBldmVudHMgY29ubmVjdGVkIHZpYSB0aHJlc2hvbGQgXHUyMTkyIFNUQUNLSU5HIG1vZGVcclxuICAgICAgY29uc3QgbGV2ZWxzID0gY2FsY3VsYXRlU3RhY2tMZXZlbHMob3ZlcmxhcEdyb3VwKTtcclxuICAgICAgZm9yIChjb25zdCBldmVudCBvZiBvdmVybGFwR3JvdXApIHtcclxuICAgICAgICByZXN1bHQuc3RhY2tlZC5wdXNoKHtcclxuICAgICAgICAgIGV2ZW50LFxyXG4gICAgICAgICAgc3RhY2tMZXZlbDogbGV2ZWxzLmdldChldmVudC5pZCkgPz8gMFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcbiIsICJpbXBvcnQgeyBJQ2FsZW5kYXJFdmVudCwgSUV2ZW50QnVzLCBJRXZlbnRVcGRhdGVkUGF5bG9hZCB9IGZyb20gJy4uLy4uL3R5cGVzL0NhbGVuZGFyVHlwZXMnO1xyXG5pbXBvcnQgeyBFdmVudFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zdG9yYWdlL2V2ZW50cy9FdmVudFNlcnZpY2UnO1xyXG5pbXBvcnQgeyBEYXRlU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvRGF0ZVNlcnZpY2UnO1xyXG5pbXBvcnQgeyBJR3JpZENvbmZpZyB9IGZyb20gJy4uLy4uL2NvcmUvSUdyaWRDb25maWcnO1xyXG5pbXBvcnQgeyBjYWxjdWxhdGVFdmVudFBvc2l0aW9uLCBzbmFwVG9HcmlkLCBwaXhlbHNUb01pbnV0ZXMgfSBmcm9tICcuLi8uLi91dGlscy9Qb3NpdGlvblV0aWxzJztcclxuaW1wb3J0IHsgQ29yZUV2ZW50cyB9IGZyb20gJy4uLy4uL2NvbnN0YW50cy9Db3JlRXZlbnRzJztcclxuaW1wb3J0IHsgSURyYWdDb2x1bW5DaGFuZ2VQYXlsb2FkLCBJRHJhZ01vdmVQYXlsb2FkLCBJRHJhZ0VuZFBheWxvYWQsIElEcmFnTGVhdmVIZWFkZXJQYXlsb2FkIH0gZnJvbSAnLi4vLi4vdHlwZXMvRHJhZ1R5cGVzJztcclxuaW1wb3J0IHsgY2FsY3VsYXRlQ29sdW1uTGF5b3V0IH0gZnJvbSAnLi9FdmVudExheW91dEVuZ2luZSc7XHJcbmltcG9ydCB7IElHcmlkR3JvdXBMYXlvdXQgfSBmcm9tICcuL0V2ZW50TGF5b3V0VHlwZXMnO1xyXG5pbXBvcnQgeyBGaWx0ZXJUZW1wbGF0ZSB9IGZyb20gJy4uLy4uL2NvcmUvRmlsdGVyVGVtcGxhdGUnO1xyXG5cclxuLyoqXHJcbiAqIEV2ZW50UmVuZGVyZXIgLSBSZW5kZXJzIGNhbGVuZGFyIGV2ZW50cyB0byB0aGUgRE9NXHJcbiAqXHJcbiAqIENMRUFOIGFwcHJvYWNoOlxyXG4gKiAtIE9ubHkgZGF0YS1pZCBhdHRyaWJ1dGUgb24gZXZlbnQgZWxlbWVudFxyXG4gKiAtIGlubmVySFRNTCBjb250YWlucyBvbmx5IHZpc2libGUgY29udGVudFxyXG4gKiAtIEV2ZW50IGRhdGEgcmV0cmlldmVkIHZpYSBFdmVudFNlcnZpY2Ugd2hlbiBuZWVkZWRcclxuICovXHJcbmV4cG9ydCBjbGFzcyBFdmVudFJlbmRlcmVyIHtcclxuICBwcml2YXRlIGNvbnRhaW5lcjogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGV2ZW50U2VydmljZTogRXZlbnRTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBkYXRlU2VydmljZTogRGF0ZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGdyaWRDb25maWc6IElHcmlkQ29uZmlnLFxyXG4gICAgcHJpdmF0ZSBldmVudEJ1czogSUV2ZW50QnVzXHJcbiAgKSB7XHJcbiAgICB0aGlzLnNldHVwTGlzdGVuZXJzKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXR1cCBsaXN0ZW5lcnMgZm9yIGRyYWctZHJvcCBhbmQgdXBkYXRlIGV2ZW50c1xyXG4gICAqL1xyXG4gIHByaXZhdGUgc2V0dXBMaXN0ZW5lcnMoKTogdm9pZCB7XHJcbiAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfRFJBR19DT0xVTU5fQ0hBTkdFLCAoZSkgPT4ge1xyXG4gICAgICBjb25zdCBwYXlsb2FkID0gKGUgYXMgQ3VzdG9tRXZlbnQ8SURyYWdDb2x1bW5DaGFuZ2VQYXlsb2FkPikuZGV0YWlsO1xyXG4gICAgICB0aGlzLmhhbmRsZUNvbHVtbkNoYW5nZShwYXlsb2FkKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX01PVkUsIChlKSA9PiB7XHJcbiAgICAgIGNvbnN0IHBheWxvYWQgPSAoZSBhcyBDdXN0b21FdmVudDxJRHJhZ01vdmVQYXlsb2FkPikuZGV0YWlsO1xyXG4gICAgICB0aGlzLnVwZGF0ZURyYWdUaW1lc3RhbXAocGF5bG9hZCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmV2ZW50QnVzLm9uKENvcmVFdmVudHMuRVZFTlRfVVBEQVRFRCwgKGUpID0+IHtcclxuICAgICAgY29uc3QgcGF5bG9hZCA9IChlIGFzIEN1c3RvbUV2ZW50PElFdmVudFVwZGF0ZWRQYXlsb2FkPikuZGV0YWlsO1xyXG4gICAgICB0aGlzLmhhbmRsZUV2ZW50VXBkYXRlZChwYXlsb2FkKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuZXZlbnRCdXMub24oQ29yZUV2ZW50cy5FVkVOVF9EUkFHX0VORCwgKGUpID0+IHtcclxuICAgICAgY29uc3QgcGF5bG9hZCA9IChlIGFzIEN1c3RvbUV2ZW50PElEcmFnRW5kUGF5bG9hZD4pLmRldGFpbDtcclxuICAgICAgdGhpcy5oYW5kbGVEcmFnRW5kKHBheWxvYWQpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5ldmVudEJ1cy5vbihDb3JlRXZlbnRzLkVWRU5UX0RSQUdfTEVBVkVfSEVBREVSLCAoZSkgPT4ge1xyXG4gICAgICBjb25zdCBwYXlsb2FkID0gKGUgYXMgQ3VzdG9tRXZlbnQ8SURyYWdMZWF2ZUhlYWRlclBheWxvYWQ+KS5kZXRhaWw7XHJcbiAgICAgIHRoaXMuaGFuZGxlRHJhZ0xlYXZlSGVhZGVyKHBheWxvYWQpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgRVZFTlRfRFJBR19FTkQgLSByZW1vdmUgZWxlbWVudCBpZiBkcm9wcGVkIGluIGhlYWRlclxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlRHJhZ0VuZChwYXlsb2FkOiBJRHJhZ0VuZFBheWxvYWQpOiB2b2lkIHtcclxuICAgIGlmIChwYXlsb2FkLnRhcmdldCA9PT0gJ2hlYWRlcicpIHtcclxuICAgICAgLy8gRXZlbnQgd2FzIGRyb3BwZWQgaW4gaGVhZGVyIGRyYXdlciAtIHJlbW92ZSBmcm9tIGdyaWRcclxuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuY29udGFpbmVyPy5xdWVyeVNlbGVjdG9yKGBzd3AtY29udGVudC12aWV3cG9ydCBzd3AtZXZlbnRbZGF0YS1ldmVudC1pZD1cIiR7cGF5bG9hZC5zd3BFdmVudC5ldmVudElkfVwiXWApO1xyXG4gICAgICBlbGVtZW50Py5yZW1vdmUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZSBoZWFkZXIgaXRlbSBsZWF2aW5nIGhlYWRlciAtIGNyZWF0ZSBzd3AtZXZlbnQgaW4gZ3JpZFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlRHJhZ0xlYXZlSGVhZGVyKHBheWxvYWQ6IElEcmFnTGVhdmVIZWFkZXJQYXlsb2FkKTogdm9pZCB7XHJcbiAgICAvLyBPbmx5IGhhbmRsZSB3aGVuIHNvdXJjZSBpcyBoZWFkZXIgKGhlYWRlciBpdGVtIGRyYWdnZWQgdG8gZ3JpZClcclxuICAgIGlmIChwYXlsb2FkLnNvdXJjZSAhPT0gJ2hlYWRlcicpIHJldHVybjtcclxuICAgIGlmICghcGF5bG9hZC50YXJnZXRDb2x1bW4gfHwgIXBheWxvYWQuc3RhcnQgfHwgIXBheWxvYWQuZW5kKSByZXR1cm47XHJcblxyXG4gICAgLy8gVHVybiBoZWFkZXIgaXRlbSBpbnRvIGdob3N0IChzdGF5cyB2aXNpYmxlIGJ1dCBmYWRlZClcclxuICAgIGlmIChwYXlsb2FkLmVsZW1lbnQpIHtcclxuICAgICAgcGF5bG9hZC5lbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2RyYWctZ2hvc3QnKTtcclxuICAgICAgcGF5bG9hZC5lbGVtZW50LnN0eWxlLm9wYWNpdHkgPSAnMC4zJztcclxuICAgICAgcGF5bG9hZC5lbGVtZW50LnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ3JlYXRlIGV2ZW50IG9iamVjdCBmcm9tIGhlYWRlciBpdGVtIGRhdGFcclxuICAgIGNvbnN0IGV2ZW50OiBJQ2FsZW5kYXJFdmVudCA9IHtcclxuICAgICAgaWQ6IHBheWxvYWQuZXZlbnRJZCxcclxuICAgICAgdGl0bGU6IHBheWxvYWQudGl0bGUgfHwgJycsXHJcbiAgICAgIGRlc2NyaXB0aW9uOiAnJyxcclxuICAgICAgc3RhcnQ6IHBheWxvYWQuc3RhcnQsXHJcbiAgICAgIGVuZDogcGF5bG9hZC5lbmQsXHJcbiAgICAgIHR5cGU6ICdjdXN0b21lcicsXHJcbiAgICAgIGFsbERheTogZmFsc2UsXHJcbiAgICAgIHN5bmNTdGF0dXM6ICdwZW5kaW5nJ1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBDcmVhdGUgc3dwLWV2ZW50IGVsZW1lbnQgdXNpbmcgZXhpc3RpbmcgbWV0aG9kXHJcbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5jcmVhdGVFdmVudEVsZW1lbnQoZXZlbnQpO1xyXG5cclxuICAgIC8vIEFkZCB0byB0YXJnZXQgY29sdW1uXHJcbiAgICBsZXQgZXZlbnRzTGF5ZXIgPSBwYXlsb2FkLnRhcmdldENvbHVtbi5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnRzLWxheWVyJyk7XHJcbiAgICBpZiAoIWV2ZW50c0xheWVyKSB7XHJcbiAgICAgIGV2ZW50c0xheWVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3dwLWV2ZW50cy1sYXllcicpO1xyXG4gICAgICBwYXlsb2FkLnRhcmdldENvbHVtbi5hcHBlbmRDaGlsZChldmVudHNMYXllcik7XHJcbiAgICB9XHJcbiAgICBldmVudHNMYXllci5hcHBlbmRDaGlsZChlbGVtZW50KTtcclxuXHJcbiAgICAvLyBNYXJrIGFzIGRyYWdnaW5nIHNvIERyYWdEcm9wTWFuYWdlciBjYW4gY29udGludWUgd2l0aCBpdFxyXG4gICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkcmFnZ2luZycpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIEVWRU5UX1VQREFURUQgLSByZS1yZW5kZXIgYWZmZWN0ZWQgY29sdW1uc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlRXZlbnRVcGRhdGVkKHBheWxvYWQ6IElFdmVudFVwZGF0ZWRQYXlsb2FkKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAvLyBSZS1yZW5kZXIgc291cmNlIGNvbHVtbiAoaWYgZGlmZmVyZW50IGZyb20gdGFyZ2V0KVxyXG4gICAgaWYgKHBheWxvYWQuc291cmNlQ29sdW1uS2V5ICE9PSBwYXlsb2FkLnRhcmdldENvbHVtbktleSkge1xyXG4gICAgICBhd2FpdCB0aGlzLnJlcmVuZGVyQ29sdW1uKHBheWxvYWQuc291cmNlQ29sdW1uS2V5KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZS1yZW5kZXIgdGFyZ2V0IGNvbHVtblxyXG4gICAgYXdhaXQgdGhpcy5yZXJlbmRlckNvbHVtbihwYXlsb2FkLnRhcmdldENvbHVtbktleSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZS1yZW5kZXIgYSBzaW5nbGUgY29sdW1uIHdpdGggZnJlc2ggZGF0YSBmcm9tIEluZGV4ZWREQlxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcmVyZW5kZXJDb2x1bW4oY29sdW1uS2V5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGNvbHVtbiA9IHRoaXMuZmluZENvbHVtbihjb2x1bW5LZXkpO1xyXG4gICAgaWYgKCFjb2x1bW4pIHJldHVybjtcclxuXHJcbiAgICAvLyBSZWFkIGRhdGUgYW5kIHJlc291cmNlSWQgZGlyZWN0bHkgZnJvbSBjb2x1bW4gYXR0cmlidXRlcyAoY29sdW1uS2V5IGlzIG9wYXF1ZSlcclxuICAgIGNvbnN0IGRhdGUgPSBjb2x1bW4uZGF0YXNldC5kYXRlO1xyXG4gICAgY29uc3QgcmVzb3VyY2VJZCA9IGNvbHVtbi5kYXRhc2V0LnJlc291cmNlSWQ7XHJcblxyXG4gICAgaWYgKCFkYXRlKSByZXR1cm47XHJcblxyXG4gICAgLy8gR2V0IGRhdGUgcmFuZ2UgZm9yIHRoaXMgZGF5XHJcbiAgICBjb25zdCBzdGFydERhdGUgPSBuZXcgRGF0ZShkYXRlKTtcclxuICAgIGNvbnN0IGVuZERhdGUgPSBuZXcgRGF0ZShkYXRlKTtcclxuICAgIGVuZERhdGUuc2V0SG91cnMoMjMsIDU5LCA1OSwgOTk5KTtcclxuXHJcbiAgICAvLyBGZXRjaCBldmVudHMgZnJvbSBJbmRleGVkREJcclxuICAgIGNvbnN0IGV2ZW50cyA9IHJlc291cmNlSWRcclxuICAgICAgPyBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXRCeVJlc291cmNlQW5kRGF0ZVJhbmdlKHJlc291cmNlSWQsIHN0YXJ0RGF0ZSwgZW5kRGF0ZSlcclxuICAgICAgOiBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXRCeURhdGVSYW5nZShzdGFydERhdGUsIGVuZERhdGUpO1xyXG5cclxuICAgIC8vIEZpbHRlciB0byB0aW1lZCBldmVudHMgYW5kIG1hdGNoIGRhdGUgZXhhY3RseVxyXG4gICAgY29uc3QgdGltZWRFdmVudHMgPSBldmVudHMuZmlsdGVyKGV2ZW50ID0+XHJcbiAgICAgICFldmVudC5hbGxEYXkgJiYgdGhpcy5kYXRlU2VydmljZS5nZXREYXRlS2V5KGV2ZW50LnN0YXJ0KSA9PT0gZGF0ZVxyXG4gICAgKTtcclxuXHJcbiAgICAvLyBHZXQgb3IgY3JlYXRlIGV2ZW50cyBsYXllclxyXG4gICAgbGV0IGV2ZW50c0xheWVyID0gY29sdW1uLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1ldmVudHMtbGF5ZXInKTtcclxuICAgIGlmICghZXZlbnRzTGF5ZXIpIHtcclxuICAgICAgZXZlbnRzTGF5ZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZXZlbnRzLWxheWVyJyk7XHJcbiAgICAgIGNvbHVtbi5hcHBlbmRDaGlsZChldmVudHNMYXllcik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2xlYXIgZXhpc3RpbmcgZXZlbnRzXHJcbiAgICBldmVudHNMYXllci5pbm5lckhUTUwgPSAnJztcclxuXHJcbiAgICAvLyBDYWxjdWxhdGUgbGF5b3V0IHdpdGggc3RhY2tpbmcvZ3JvdXBpbmdcclxuICAgIGNvbnN0IGxheW91dCA9IGNhbGN1bGF0ZUNvbHVtbkxheW91dCh0aW1lZEV2ZW50cywgdGhpcy5ncmlkQ29uZmlnKTtcclxuXHJcbiAgICAvLyBSZW5kZXIgR1JJRCBncm91cHNcclxuICAgIGxheW91dC5ncmlkcy5mb3JFYWNoKGdyaWQgPT4ge1xyXG4gICAgICBjb25zdCBncm91cEVsID0gdGhpcy5yZW5kZXJHcmlkR3JvdXAoZ3JpZCk7XHJcbiAgICAgIGV2ZW50c0xheWVyIS5hcHBlbmRDaGlsZChncm91cEVsKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIFJlbmRlciBTVEFDS0VEIGV2ZW50c1xyXG4gICAgbGF5b3V0LnN0YWNrZWQuZm9yRWFjaChpdGVtID0+IHtcclxuICAgICAgY29uc3QgZXZlbnRFbCA9IHRoaXMucmVuZGVyU3RhY2tlZEV2ZW50KGl0ZW0uZXZlbnQsIGl0ZW0uc3RhY2tMZXZlbCk7XHJcbiAgICAgIGV2ZW50c0xheWVyIS5hcHBlbmRDaGlsZChldmVudEVsKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRmluZCBhIGNvbHVtbiBlbGVtZW50IGJ5IGNvbHVtbktleVxyXG4gICAqL1xyXG4gIHByaXZhdGUgZmluZENvbHVtbihjb2x1bW5LZXk6IHN0cmluZyk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XHJcbiAgICBpZiAoIXRoaXMuY29udGFpbmVyKSByZXR1cm4gbnVsbDtcclxuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKGBzd3AtZGF5LWNvbHVtbltkYXRhLWNvbHVtbi1rZXk9XCIke2NvbHVtbktleX1cIl1gKSBhcyBIVE1MRWxlbWVudDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZSBldmVudCBtb3ZpbmcgdG8gYSBuZXcgY29sdW1uIGR1cmluZyBkcmFnXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBoYW5kbGVDb2x1bW5DaGFuZ2UocGF5bG9hZDogSURyYWdDb2x1bW5DaGFuZ2VQYXlsb2FkKTogdm9pZCB7XHJcbiAgICBjb25zdCBldmVudHNMYXllciA9IHBheWxvYWQubmV3Q29sdW1uLnF1ZXJ5U2VsZWN0b3IoJ3N3cC1ldmVudHMtbGF5ZXInKTtcclxuICAgIGlmICghZXZlbnRzTGF5ZXIpIHJldHVybjtcclxuXHJcbiAgICAvLyBNb3ZlIGVsZW1lbnQgdG8gbmV3IGNvbHVtblxyXG4gICAgZXZlbnRzTGF5ZXIuYXBwZW5kQ2hpbGQocGF5bG9hZC5lbGVtZW50KTtcclxuXHJcbiAgICAvLyBQcmVzZXJ2ZSBZIHBvc2l0aW9uXHJcbiAgICBwYXlsb2FkLmVsZW1lbnQuc3R5bGUudG9wID0gYCR7cGF5bG9hZC5jdXJyZW50WX1weGA7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBVcGRhdGUgdGltZXN0YW1wIGRpc3BsYXkgZHVyaW5nIGRyYWcgKHNuYXBwZWQgdG8gZ3JpZClcclxuICAgKi9cclxuICBwcml2YXRlIHVwZGF0ZURyYWdUaW1lc3RhbXAocGF5bG9hZDogSURyYWdNb3ZlUGF5bG9hZCk6IHZvaWQge1xyXG4gICAgY29uc3QgdGltZUVsID0gcGF5bG9hZC5lbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ3N3cC1ldmVudC10aW1lJyk7XHJcbiAgICBpZiAoIXRpbWVFbCkgcmV0dXJuO1xyXG5cclxuICAgIC8vIFNuYXAgcG9zaXRpb24gdG8gZ3JpZCBpbnRlcnZhbFxyXG4gICAgY29uc3Qgc25hcHBlZFkgPSBzbmFwVG9HcmlkKHBheWxvYWQuY3VycmVudFksIHRoaXMuZ3JpZENvbmZpZyk7XHJcblxyXG4gICAgLy8gQ2FsY3VsYXRlIG5ldyBzdGFydCB0aW1lXHJcbiAgICBjb25zdCBtaW51dGVzRnJvbUdyaWRTdGFydCA9IHBpeGVsc1RvTWludXRlcyhzbmFwcGVkWSwgdGhpcy5ncmlkQ29uZmlnKTtcclxuICAgIGNvbnN0IHN0YXJ0TWludXRlcyA9ICh0aGlzLmdyaWRDb25maWcuZGF5U3RhcnRIb3VyICogNjApICsgbWludXRlc0Zyb21HcmlkU3RhcnQ7XHJcblxyXG4gICAgLy8gS2VlcCBvcmlnaW5hbCBkdXJhdGlvbiAoZnJvbSBlbGVtZW50IGhlaWdodClcclxuICAgIGNvbnN0IGhlaWdodCA9IHBhcnNlRmxvYXQocGF5bG9hZC5lbGVtZW50LnN0eWxlLmhlaWdodCkgfHwgdGhpcy5ncmlkQ29uZmlnLmhvdXJIZWlnaHQ7XHJcbiAgICBjb25zdCBkdXJhdGlvbk1pbnV0ZXMgPSBwaXhlbHNUb01pbnV0ZXMoaGVpZ2h0LCB0aGlzLmdyaWRDb25maWcpO1xyXG5cclxuICAgIC8vIENyZWF0ZSBEYXRlIG9iamVjdHMgZm9yIGNvbnNpc3RlbnQgZm9ybWF0dGluZyB2aWEgRGF0ZVNlcnZpY2VcclxuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5taW51dGVzVG9EYXRlKHN0YXJ0TWludXRlcyk7XHJcbiAgICBjb25zdCBlbmQgPSB0aGlzLm1pbnV0ZXNUb0RhdGUoc3RhcnRNaW51dGVzICsgZHVyYXRpb25NaW51dGVzKTtcclxuXHJcbiAgICB0aW1lRWwudGV4dENvbnRlbnQgPSB0aGlzLmRhdGVTZXJ2aWNlLmZvcm1hdFRpbWVSYW5nZShzdGFydCwgZW5kKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbnZlcnQgbWludXRlcyBzaW5jZSBtaWRuaWdodCB0byBhIERhdGUgb2JqZWN0ICh0b2RheSlcclxuICAgKi9cclxuICBwcml2YXRlIG1pbnV0ZXNUb0RhdGUobWludXRlczogbnVtYmVyKTogRGF0ZSB7XHJcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcclxuICAgIGRhdGUuc2V0SG91cnMoTWF0aC5mbG9vcihtaW51dGVzIC8gNjApICUgMjQsIG1pbnV0ZXMgJSA2MCwgMCwgMCk7XHJcbiAgICByZXR1cm4gZGF0ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlbmRlciBldmVudHMgZm9yIHZpc2libGUgZGF0ZXMgaW50byBkYXkgY29sdW1uc1xyXG4gICAqIEBwYXJhbSBjb250YWluZXIgLSBDYWxlbmRhciBjb250YWluZXIgZWxlbWVudFxyXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgd2l0aCAnZGF0ZScgYW5kIG9wdGlvbmFsbHkgJ3Jlc291cmNlJyBhcnJheXNcclxuICAgKiBAcGFyYW0gZmlsdGVyVGVtcGxhdGUgLSBUZW1wbGF0ZSBmb3IgbWF0Y2hpbmcgZXZlbnRzIHRvIGNvbHVtbnNcclxuICAgKi9cclxuICBhc3luYyByZW5kZXIoY29udGFpbmVyOiBIVE1MRWxlbWVudCwgZmlsdGVyOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4sIGZpbHRlclRlbXBsYXRlOiBGaWx0ZXJUZW1wbGF0ZSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgLy8gU3RvcmUgY29udGFpbmVyIHJlZmVyZW5jZSBmb3IgbGF0ZXIgcmUtcmVuZGVyc1xyXG4gICAgdGhpcy5jb250YWluZXIgPSBjb250YWluZXI7XHJcblxyXG4gICAgY29uc3QgdmlzaWJsZURhdGVzID0gZmlsdGVyWydkYXRlJ10gfHwgW107XHJcblxyXG4gICAgaWYgKHZpc2libGVEYXRlcy5sZW5ndGggPT09IDApIHJldHVybjtcclxuXHJcbiAgICAvLyBHZXQgZGF0ZSByYW5nZSBmb3IgcXVlcnlcclxuICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IG5ldyBEYXRlKHZpc2libGVEYXRlc1swXSk7XHJcbiAgICBjb25zdCBlbmREYXRlID0gbmV3IERhdGUodmlzaWJsZURhdGVzW3Zpc2libGVEYXRlcy5sZW5ndGggLSAxXSk7XHJcbiAgICBlbmREYXRlLnNldEhvdXJzKDIzLCA1OSwgNTksIDk5OSk7XHJcblxyXG4gICAgLy8gRmV0Y2ggZXZlbnRzIGZyb20gSW5kZXhlZERCXHJcbiAgICBjb25zdCBldmVudHMgPSBhd2FpdCB0aGlzLmV2ZW50U2VydmljZS5nZXRCeURhdGVSYW5nZShzdGFydERhdGUsIGVuZERhdGUpO1xyXG5cclxuICAgIC8vIEZpbmQgZGF5IGNvbHVtbnNcclxuICAgIGNvbnN0IGRheUNvbHVtbnMgPSBjb250YWluZXIucXVlcnlTZWxlY3Rvcignc3dwLWRheS1jb2x1bW5zJyk7XHJcbiAgICBpZiAoIWRheUNvbHVtbnMpIHJldHVybjtcclxuXHJcbiAgICBjb25zdCBjb2x1bW5zID0gZGF5Q29sdW1ucy5xdWVyeVNlbGVjdG9yQWxsKCdzd3AtZGF5LWNvbHVtbicpO1xyXG5cclxuICAgIC8vIFJlbmRlciBldmVudHMgaW50byBlYWNoIGNvbHVtbiBiYXNlZCBvbiBGaWx0ZXJUZW1wbGF0ZSBtYXRjaGluZ1xyXG4gICAgY29sdW1ucy5mb3JFYWNoKGNvbHVtbiA9PiB7XHJcbiAgICAgIGNvbnN0IGNvbHVtbkVsID0gY29sdW1uIGFzIEhUTUxFbGVtZW50O1xyXG5cclxuICAgICAgLy8gVXNlIEZpbHRlclRlbXBsYXRlIGZvciBtYXRjaGluZyAtIG9ubHkgZmllbGRzIGluIHRlbXBsYXRlIGFyZSBjaGVja2VkXHJcbiAgICAgIGNvbnN0IGNvbHVtbkV2ZW50cyA9IGV2ZW50cy5maWx0ZXIoZXZlbnQgPT4gZmlsdGVyVGVtcGxhdGUubWF0Y2hlcyhldmVudCwgY29sdW1uRWwpKTtcclxuXHJcbiAgICAgIC8vIEdldCBvciBjcmVhdGUgZXZlbnRzIGxheWVyXHJcbiAgICAgIGxldCBldmVudHNMYXllciA9IGNvbHVtbi5xdWVyeVNlbGVjdG9yKCdzd3AtZXZlbnRzLWxheWVyJyk7XHJcbiAgICAgIGlmICghZXZlbnRzTGF5ZXIpIHtcclxuICAgICAgICBldmVudHNMYXllciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1ldmVudHMtbGF5ZXInKTtcclxuICAgICAgICBjb2x1bW4uYXBwZW5kQ2hpbGQoZXZlbnRzTGF5ZXIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBDbGVhciBleGlzdGluZyBldmVudHNcclxuICAgICAgZXZlbnRzTGF5ZXIuaW5uZXJIVE1MID0gJyc7XHJcblxyXG4gICAgICAvLyBGaWx0ZXIgdG8gdGltZWQgZXZlbnRzIG9ubHlcclxuICAgICAgY29uc3QgdGltZWRFdmVudHMgPSBjb2x1bW5FdmVudHMuZmlsdGVyKGV2ZW50ID0+ICFldmVudC5hbGxEYXkpO1xyXG5cclxuICAgICAgLy8gQ2FsY3VsYXRlIGxheW91dCB3aXRoIHN0YWNraW5nL2dyb3VwaW5nXHJcbiAgICAgIGNvbnN0IGxheW91dCA9IGNhbGN1bGF0ZUNvbHVtbkxheW91dCh0aW1lZEV2ZW50cywgdGhpcy5ncmlkQ29uZmlnKTtcclxuXHJcbiAgICAgIC8vIFJlbmRlciBHUklEIGdyb3VwcyAoc2ltdWx0YW5lb3VzIGV2ZW50cyBzaWRlLWJ5LXNpZGUpXHJcbiAgICAgIGxheW91dC5ncmlkcy5mb3JFYWNoKGdyaWQgPT4ge1xyXG4gICAgICAgIGNvbnN0IGdyb3VwRWwgPSB0aGlzLnJlbmRlckdyaWRHcm91cChncmlkKTtcclxuICAgICAgICBldmVudHNMYXllciEuYXBwZW5kQ2hpbGQoZ3JvdXBFbCk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gUmVuZGVyIFNUQUNLRUQgZXZlbnRzIChvdmVybGFwcGluZyB3aXRoIG1hcmdpbiBvZmZzZXQpXHJcbiAgICAgIGxheW91dC5zdGFja2VkLmZvckVhY2goaXRlbSA9PiB7XHJcbiAgICAgICAgY29uc3QgZXZlbnRFbCA9IHRoaXMucmVuZGVyU3RhY2tlZEV2ZW50KGl0ZW0uZXZlbnQsIGl0ZW0uc3RhY2tMZXZlbCk7XHJcbiAgICAgICAgZXZlbnRzTGF5ZXIhLmFwcGVuZENoaWxkKGV2ZW50RWwpO1xyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlIGEgc2luZ2xlIGV2ZW50IGVsZW1lbnRcclxuICAgKlxyXG4gICAqIENMRUFOIGFwcHJvYWNoOlxyXG4gICAqIC0gT25seSBkYXRhLWlkIGZvciBsb29rdXBcclxuICAgKiAtIFZpc2libGUgY29udGVudCBpbiBpbm5lckhUTUwgb25seVxyXG4gICAqL1xyXG4gIHByaXZhdGUgY3JlYXRlRXZlbnRFbGVtZW50KGV2ZW50OiBJQ2FsZW5kYXJFdmVudCk6IEhUTUxFbGVtZW50IHtcclxuICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZXZlbnQnKTtcclxuXHJcbiAgICAvLyBEYXRhIGF0dHJpYnV0ZXMgZm9yIFN3cEV2ZW50IGNvbXBhdGliaWxpdHlcclxuICAgIGVsZW1lbnQuZGF0YXNldC5ldmVudElkID0gZXZlbnQuaWQ7XHJcbiAgICBpZiAoZXZlbnQucmVzb3VyY2VJZCkge1xyXG4gICAgICBlbGVtZW50LmRhdGFzZXQucmVzb3VyY2VJZCA9IGV2ZW50LnJlc291cmNlSWQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2FsY3VsYXRlIHBvc2l0aW9uXHJcbiAgICBjb25zdCBwb3NpdGlvbiA9IGNhbGN1bGF0ZUV2ZW50UG9zaXRpb24oZXZlbnQuc3RhcnQsIGV2ZW50LmVuZCwgdGhpcy5ncmlkQ29uZmlnKTtcclxuICAgIGVsZW1lbnQuc3R5bGUudG9wID0gYCR7cG9zaXRpb24udG9wfXB4YDtcclxuICAgIGVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7cG9zaXRpb24uaGVpZ2h0fXB4YDtcclxuXHJcbiAgICAvLyBDb2xvciBjbGFzcyBiYXNlZCBvbiBldmVudCB0eXBlXHJcbiAgICBjb25zdCBjb2xvckNsYXNzID0gdGhpcy5nZXRDb2xvckNsYXNzKGV2ZW50KTtcclxuICAgIGlmIChjb2xvckNsYXNzKSB7XHJcbiAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChjb2xvckNsYXNzKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBWaXNpYmxlIGNvbnRlbnQgb25seVxyXG4gICAgZWxlbWVudC5pbm5lckhUTUwgPSBgXHJcbiAgICAgIDxzd3AtZXZlbnQtdGltZT4ke3RoaXMuZGF0ZVNlcnZpY2UuZm9ybWF0VGltZVJhbmdlKGV2ZW50LnN0YXJ0LCBldmVudC5lbmQpfTwvc3dwLWV2ZW50LXRpbWU+XHJcbiAgICAgIDxzd3AtZXZlbnQtdGl0bGU+JHt0aGlzLmVzY2FwZUh0bWwoZXZlbnQudGl0bGUpfTwvc3dwLWV2ZW50LXRpdGxlPlxyXG4gICAgICAke2V2ZW50LmRlc2NyaXB0aW9uID8gYDxzd3AtZXZlbnQtZGVzY3JpcHRpb24+JHt0aGlzLmVzY2FwZUh0bWwoZXZlbnQuZGVzY3JpcHRpb24pfTwvc3dwLWV2ZW50LWRlc2NyaXB0aW9uPmAgOiAnJ31cclxuICAgIGA7XHJcblxyXG4gICAgcmV0dXJuIGVsZW1lbnQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgY29sb3IgY2xhc3MgYmFzZWQgb24gbWV0YWRhdGEuY29sb3Igb3IgZXZlbnQgdHlwZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0Q29sb3JDbGFzcyhldmVudDogSUNhbGVuZGFyRXZlbnQpOiBzdHJpbmcge1xyXG4gICAgLy8gQ2hlY2sgbWV0YWRhdGEuY29sb3IgZmlyc3RcclxuICAgIGlmIChldmVudC5tZXRhZGF0YT8uY29sb3IpIHtcclxuICAgICAgcmV0dXJuIGBpcy0ke2V2ZW50Lm1ldGFkYXRhLmNvbG9yfWA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRmFsbGJhY2sgdG8gdHlwZS1iYXNlZCBjb2xvclxyXG4gICAgY29uc3QgdHlwZUNvbG9yczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcclxuICAgICAgJ2N1c3RvbWVyJzogJ2lzLWJsdWUnLFxyXG4gICAgICAndmFjYXRpb24nOiAnaXMtZ3JlZW4nLFxyXG4gICAgICAnYnJlYWsnOiAnaXMtYW1iZXInLFxyXG4gICAgICAnbWVldGluZyc6ICdpcy1wdXJwbGUnLFxyXG4gICAgICAnYmxvY2tlZCc6ICdpcy1yZWQnXHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIHR5cGVDb2xvcnNbZXZlbnQudHlwZV0gfHwgJ2lzLWJsdWUnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRXNjYXBlIEhUTUwgdG8gcHJldmVudCBYU1NcclxuICAgKi9cclxuICBwcml2YXRlIGVzY2FwZUh0bWwodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xyXG4gICAgZGl2LnRleHRDb250ZW50ID0gdGV4dDtcclxuICAgIHJldHVybiBkaXYuaW5uZXJIVE1MO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVuZGVyIGEgR1JJRCBncm91cCB3aXRoIHNpZGUtYnktc2lkZSBjb2x1bW5zXHJcbiAgICogVXNlZCB3aGVuIG11bHRpcGxlIGV2ZW50cyBzdGFydCBhdCB0aGUgc2FtZSB0aW1lXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZW5kZXJHcmlkR3JvdXAobGF5b3V0OiBJR3JpZEdyb3VwTGF5b3V0KTogSFRNTEVsZW1lbnQge1xyXG4gICAgY29uc3QgZ3JvdXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzd3AtZXZlbnQtZ3JvdXAnKTtcclxuICAgIGdyb3VwLmNsYXNzTGlzdC5hZGQoYGNvbHMtJHtsYXlvdXQuY29sdW1ucy5sZW5ndGh9YCk7XHJcbiAgICBncm91cC5zdHlsZS50b3AgPSBgJHtsYXlvdXQucG9zaXRpb24udG9wfXB4YDtcclxuXHJcbiAgICAvLyBTdGFjayBsZXZlbCBzdHlsaW5nIGZvciBlbnRpcmUgZ3JvdXAgKGlmIG5lc3RlZCBpbiBhbm90aGVyIGV2ZW50KVxyXG4gICAgaWYgKGxheW91dC5zdGFja0xldmVsID4gMCkge1xyXG4gICAgICBncm91cC5zdHlsZS5tYXJnaW5MZWZ0ID0gYCR7bGF5b3V0LnN0YWNrTGV2ZWwgKiAxNX1weGA7XHJcbiAgICAgIGdyb3VwLnN0eWxlLnpJbmRleCA9IGAkezEwMCArIGxheW91dC5zdGFja0xldmVsfWA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2FsY3VsYXRlIHRoZSBoZWlnaHQgbmVlZGVkIGZvciB0aGUgZ3JvdXAgKHRhbGxlc3QgZXZlbnQpXHJcbiAgICBsZXQgbWF4Qm90dG9tID0gMDtcclxuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgbGF5b3V0LmV2ZW50cykge1xyXG4gICAgICBjb25zdCBwb3MgPSBjYWxjdWxhdGVFdmVudFBvc2l0aW9uKGV2ZW50LnN0YXJ0LCBldmVudC5lbmQsIHRoaXMuZ3JpZENvbmZpZyk7XHJcbiAgICAgIGNvbnN0IGV2ZW50Qm90dG9tID0gcG9zLnRvcCArIHBvcy5oZWlnaHQ7XHJcbiAgICAgIGlmIChldmVudEJvdHRvbSA+IG1heEJvdHRvbSkgbWF4Qm90dG9tID0gZXZlbnRCb3R0b207XHJcbiAgICB9XHJcbiAgICBjb25zdCBncm91cEhlaWdodCA9IG1heEJvdHRvbSAtIGxheW91dC5wb3NpdGlvbi50b3A7XHJcbiAgICBncm91cC5zdHlsZS5oZWlnaHQgPSBgJHtncm91cEhlaWdodH1weGA7XHJcblxyXG4gICAgLy8gQ3JlYXRlIHdyYXBwZXIgZGl2IGZvciBlYWNoIGNvbHVtblxyXG4gICAgbGF5b3V0LmNvbHVtbnMuZm9yRWFjaChjb2x1bW5FdmVudHMgPT4ge1xyXG4gICAgICBjb25zdCB3cmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgIHdyYXBwZXIuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xyXG5cclxuICAgICAgY29sdW1uRXZlbnRzLmZvckVhY2goZXZlbnQgPT4ge1xyXG4gICAgICAgIGNvbnN0IGV2ZW50RWwgPSB0aGlzLmNyZWF0ZUV2ZW50RWxlbWVudChldmVudCk7XHJcbiAgICAgICAgLy8gUG9zaXRpb24gcmVsYXRpdmUgdG8gZ3JvdXAgdG9wXHJcbiAgICAgICAgY29uc3QgcG9zID0gY2FsY3VsYXRlRXZlbnRQb3NpdGlvbihldmVudC5zdGFydCwgZXZlbnQuZW5kLCB0aGlzLmdyaWRDb25maWcpO1xyXG4gICAgICAgIGV2ZW50RWwuc3R5bGUudG9wID0gYCR7cG9zLnRvcCAtIGxheW91dC5wb3NpdGlvbi50b3B9cHhgO1xyXG4gICAgICAgIGV2ZW50RWwuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xyXG4gICAgICAgIGV2ZW50RWwuc3R5bGUubGVmdCA9ICcwJztcclxuICAgICAgICBldmVudEVsLnN0eWxlLnJpZ2h0ID0gJzAnO1xyXG4gICAgICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQoZXZlbnRFbCk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgZ3JvdXAuYXBwZW5kQ2hpbGQod3JhcHBlcik7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gZ3JvdXA7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZW5kZXIgYSBTVEFDS0VEIGV2ZW50IHdpdGggbWFyZ2luLWxlZnQgb2Zmc2V0XHJcbiAgICogVXNlZCBmb3Igb3ZlcmxhcHBpbmcgZXZlbnRzIHRoYXQgZG9uJ3Qgc3RhcnQgYXQgdGhlIHNhbWUgdGltZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgcmVuZGVyU3RhY2tlZEV2ZW50KGV2ZW50OiBJQ2FsZW5kYXJFdmVudCwgc3RhY2tMZXZlbDogbnVtYmVyKTogSFRNTEVsZW1lbnQge1xyXG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuY3JlYXRlRXZlbnRFbGVtZW50KGV2ZW50KTtcclxuXHJcbiAgICAvLyBBZGQgc3RhY2sgbWV0YWRhdGEgZm9yIGRyYWctZHJvcCBhbmQgb3RoZXIgZmVhdHVyZXNcclxuICAgIGVsZW1lbnQuZGF0YXNldC5zdGFja0xpbmsgPSBKU09OLnN0cmluZ2lmeSh7IHN0YWNrTGV2ZWwgfSk7XHJcblxyXG4gICAgLy8gVmlzdWFsIHN0eWxpbmcgYmFzZWQgb24gc3RhY2sgbGV2ZWxcclxuICAgIGlmIChzdGFja0xldmVsID4gMCkge1xyXG4gICAgICBlbGVtZW50LnN0eWxlLm1hcmdpbkxlZnQgPSBgJHtzdGFja0xldmVsICogMTV9cHhgO1xyXG4gICAgICBlbGVtZW50LnN0eWxlLnpJbmRleCA9IGAkezEwMCArIHN0YWNrTGV2ZWx9YDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZWxlbWVudDtcclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IElSZW5kZXJlciwgSVJlbmRlckNvbnRleHQgfSBmcm9tICcuL0lHcm91cGluZ1JlbmRlcmVyJztcclxuXHJcbi8qKlxyXG4gKiBFbnRpdHkgbXVzdCBoYXZlIGlkXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElHcm91cGluZ0VudGl0eSB7XHJcbiAgaWQ6IHN0cmluZztcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbmZpZ3VyYXRpb24gZm9yIGEgZ3JvdXBpbmcgcmVuZGVyZXJcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSUdyb3VwaW5nUmVuZGVyZXJDb25maWcge1xyXG4gIGVsZW1lbnRUYWc6IHN0cmluZzsgICAgICAvLyBlLmcuLCAnc3dwLXRlYW0taGVhZGVyJ1xyXG4gIGlkQXR0cmlidXRlOiBzdHJpbmc7ICAgICAvLyBlLmcuLCAndGVhbUlkJyAtPiBkYXRhLXRlYW0taWRcclxuICBjb2xzcGFuVmFyOiBzdHJpbmc7ICAgICAgLy8gZS5nLiwgJy0tdGVhbS1jb2xzJ1xyXG59XHJcblxyXG4vKipcclxuICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgZ3JvdXBpbmcgcmVuZGVyZXJzXHJcbiAqXHJcbiAqIEhhbmRsZXM6XHJcbiAqIC0gRmV0Y2hpbmcgZW50aXRpZXMgYnkgSURzXHJcbiAqIC0gQ2FsY3VsYXRpbmcgY29sc3BhbiBmcm9tIHBhcmVudENoaWxkTWFwXHJcbiAqIC0gQ3JlYXRpbmcgaGVhZGVyIGVsZW1lbnRzXHJcbiAqIC0gQXBwZW5kaW5nIHRvIGNvbnRhaW5lclxyXG4gKlxyXG4gKiBTdWJjbGFzc2VzIG92ZXJyaWRlOlxyXG4gKiAtIHJlbmRlckhlYWRlcigpIGZvciBjdXN0b20gY29udGVudFxyXG4gKiAtIGdldERpc3BsYXlOYW1lKCkgZm9yIGVudGl0eSBkaXNwbGF5IHRleHRcclxuICovXHJcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlR3JvdXBpbmdSZW5kZXJlcjxUIGV4dGVuZHMgSUdyb3VwaW5nRW50aXR5PiBpbXBsZW1lbnRzIElSZW5kZXJlciB7XHJcbiAgYWJzdHJhY3QgcmVhZG9ubHkgdHlwZTogc3RyaW5nO1xyXG4gIHByb3RlY3RlZCBhYnN0cmFjdCByZWFkb25seSBjb25maWc6IElHcm91cGluZ1JlbmRlcmVyQ29uZmlnO1xyXG5cclxuICAvKipcclxuICAgKiBGZXRjaCBlbnRpdGllcyBmcm9tIHNlcnZpY2VcclxuICAgKi9cclxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgZ2V0RW50aXRpZXMoaWRzOiBzdHJpbmdbXSk6IFByb21pc2U8VFtdPjtcclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGRpc3BsYXkgbmFtZSBmb3IgZW50aXR5XHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldERpc3BsYXlOYW1lKGVudGl0eTogVCk6IHN0cmluZztcclxuXHJcbiAgLyoqXHJcbiAgICogTWFpbiByZW5kZXIgbWV0aG9kIC0gaGFuZGxlcyBjb21tb24gbG9naWNcclxuICAgKi9cclxuICBhc3luYyByZW5kZXIoY29udGV4dDogSVJlbmRlckNvbnRleHQpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGNvbnN0IGFsbG93ZWRJZHMgPSBjb250ZXh0LmZpbHRlclt0aGlzLnR5cGVdIHx8IFtdO1xyXG4gICAgaWYgKGFsbG93ZWRJZHMubGVuZ3RoID09PSAwKSByZXR1cm47XHJcblxyXG4gICAgY29uc3QgZW50aXRpZXMgPSBhd2FpdCB0aGlzLmdldEVudGl0aWVzKGFsbG93ZWRJZHMpO1xyXG4gICAgY29uc3QgZGF0ZUNvdW50ID0gY29udGV4dC5maWx0ZXJbJ2RhdGUnXT8ubGVuZ3RoIHx8IDE7XHJcbiAgICBjb25zdCBjaGlsZElkcyA9IGNvbnRleHQuY2hpbGRUeXBlID8gY29udGV4dC5maWx0ZXJbY29udGV4dC5jaGlsZFR5cGVdIHx8IFtdIDogW107XHJcblxyXG4gICAgZm9yIChjb25zdCBlbnRpdHkgb2YgZW50aXRpZXMpIHtcclxuICAgICAgY29uc3QgZW50aXR5Q2hpbGRJZHMgPSBjb250ZXh0LnBhcmVudENoaWxkTWFwPy5bZW50aXR5LmlkXSB8fCBbXTtcclxuICAgICAgY29uc3QgY2hpbGRDb3VudCA9IGVudGl0eUNoaWxkSWRzLmZpbHRlcihpZCA9PiBjaGlsZElkcy5pbmNsdWRlcyhpZCkpLmxlbmd0aDtcclxuICAgICAgY29uc3QgY29sc3BhbiA9IGNoaWxkQ291bnQgKiBkYXRlQ291bnQ7XHJcblxyXG4gICAgICBjb25zdCBoZWFkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuY29uZmlnLmVsZW1lbnRUYWcpO1xyXG4gICAgICBoZWFkZXIuZGF0YXNldFt0aGlzLmNvbmZpZy5pZEF0dHJpYnV0ZV0gPSBlbnRpdHkuaWQ7XHJcbiAgICAgIGhlYWRlci5zdHlsZS5zZXRQcm9wZXJ0eSh0aGlzLmNvbmZpZy5jb2xzcGFuVmFyLCBTdHJpbmcoY29sc3BhbikpO1xyXG5cclxuICAgICAgLy8gQWxsb3cgc3ViY2xhc3MgdG8gY3VzdG9taXplIGhlYWRlciBjb250ZW50XHJcbiAgICAgIHRoaXMucmVuZGVySGVhZGVyKGVudGl0eSwgaGVhZGVyLCBjb250ZXh0KTtcclxuXHJcbiAgICAgIGNvbnRleHQuaGVhZGVyQ29udGFpbmVyLmFwcGVuZENoaWxkKGhlYWRlcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBPdmVycmlkZSB0aGlzIG1ldGhvZCBmb3IgY3VzdG9tIGhlYWRlciByZW5kZXJpbmdcclxuICAgKiBEZWZhdWx0OiBqdXN0IHNldHMgdGV4dENvbnRlbnQgdG8gZGlzcGxheSBuYW1lXHJcbiAgICovXHJcbiAgcHJvdGVjdGVkIHJlbmRlckhlYWRlcihlbnRpdHk6IFQsIGhlYWRlcjogSFRNTEVsZW1lbnQsIF9jb250ZXh0OiBJUmVuZGVyQ29udGV4dCk6IHZvaWQge1xyXG4gICAgaGVhZGVyLnRleHRDb250ZW50ID0gdGhpcy5nZXREaXNwbGF5TmFtZShlbnRpdHkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGVscGVyIHRvIHJlbmRlciBhIHNpbmdsZSBlbnRpdHkgaGVhZGVyLlxyXG4gICAqIENhbiBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMgdGhhdCBvdmVycmlkZSByZW5kZXIoKSBidXQgd2FudCBjb25zaXN0ZW50IGhlYWRlciBjcmVhdGlvbi5cclxuICAgKi9cclxuICBwcm90ZWN0ZWQgY3JlYXRlSGVhZGVyKGVudGl0eTogVCwgY29udGV4dDogSVJlbmRlckNvbnRleHQpOiBIVE1MRWxlbWVudCB7XHJcbiAgICBjb25zdCBoZWFkZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRoaXMuY29uZmlnLmVsZW1lbnRUYWcpO1xyXG4gICAgaGVhZGVyLmRhdGFzZXRbdGhpcy5jb25maWcuaWRBdHRyaWJ1dGVdID0gZW50aXR5LmlkO1xyXG4gICAgdGhpcy5yZW5kZXJIZWFkZXIoZW50aXR5LCBoZWFkZXIsIGNvbnRleHQpO1xyXG4gICAgcmV0dXJuIGhlYWRlcjtcclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IElSZW5kZXJDb250ZXh0IH0gZnJvbSAnLi4vLi4vY29yZS9JR3JvdXBpbmdSZW5kZXJlcic7XHJcbmltcG9ydCB7IEJhc2VHcm91cGluZ1JlbmRlcmVyLCBJR3JvdXBpbmdSZW5kZXJlckNvbmZpZyB9IGZyb20gJy4uLy4uL2NvcmUvQmFzZUdyb3VwaW5nUmVuZGVyZXInO1xyXG5pbXBvcnQgeyBSZXNvdXJjZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zdG9yYWdlL3Jlc291cmNlcy9SZXNvdXJjZVNlcnZpY2UnO1xyXG5pbXBvcnQgeyBJUmVzb3VyY2UgfSBmcm9tICcuLi8uLi90eXBlcy9DYWxlbmRhclR5cGVzJztcclxuXHJcbmV4cG9ydCBjbGFzcyBSZXNvdXJjZVJlbmRlcmVyIGV4dGVuZHMgQmFzZUdyb3VwaW5nUmVuZGVyZXI8SVJlc291cmNlPiB7XHJcbiAgcmVhZG9ubHkgdHlwZSA9ICdyZXNvdXJjZSc7XHJcblxyXG4gIHByb3RlY3RlZCByZWFkb25seSBjb25maWc6IElHcm91cGluZ1JlbmRlcmVyQ29uZmlnID0ge1xyXG4gICAgZWxlbWVudFRhZzogJ3N3cC1yZXNvdXJjZS1oZWFkZXInLFxyXG4gICAgaWRBdHRyaWJ1dGU6ICdyZXNvdXJjZUlkJyxcclxuICAgIGNvbHNwYW5WYXI6ICctLXJlc291cmNlLWNvbHMnXHJcbiAgfTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZXNvdXJjZVNlcnZpY2U6IFJlc291cmNlU2VydmljZSkge1xyXG4gICAgc3VwZXIoKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBnZXRFbnRpdGllcyhpZHM6IHN0cmluZ1tdKTogUHJvbWlzZTxJUmVzb3VyY2VbXT4ge1xyXG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2VTZXJ2aWNlLmdldEJ5SWRzKGlkcyk7XHJcbiAgfVxyXG5cclxuICBwcm90ZWN0ZWQgZ2V0RGlzcGxheU5hbWUoZW50aXR5OiBJUmVzb3VyY2UpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGVudGl0eS5kaXNwbGF5TmFtZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE92ZXJyaWRlIHJlbmRlciB0byBoYW5kbGU6XHJcbiAgICogMS4gU3BlY2lhbCBvcmRlcmluZyB3aGVuIHBhcmVudENoaWxkTWFwIGV4aXN0cyAocmVzb3VyY2VzIGdyb3VwZWQgYnkgcGFyZW50KVxyXG4gICAqIDIuIERpZmZlcmVudCBjb2xzcGFuIGNhbGN1bGF0aW9uIChqdXN0IGRhdGVDb3VudCwgbm90IGNoaWxkQ291bnQgKiBkYXRlQ291bnQpXHJcbiAgICovXHJcbiAgYXN5bmMgcmVuZGVyKGNvbnRleHQ6IElSZW5kZXJDb250ZXh0KTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCByZXNvdXJjZUlkcyA9IGNvbnRleHQuZmlsdGVyWydyZXNvdXJjZSddIHx8IFtdO1xyXG4gICAgY29uc3QgZGF0ZUNvdW50ID0gY29udGV4dC5maWx0ZXJbJ2RhdGUnXT8ubGVuZ3RoIHx8IDE7XHJcblxyXG4gICAgLy8gRGV0ZXJtaW5lIHJlbmRlciBvcmRlciBiYXNlZCBvbiBwYXJlbnRDaGlsZE1hcFxyXG4gICAgLy8gSWYgcGFyZW50Q2hpbGRNYXAgZXhpc3RzLCByZW5kZXIgcmVzb3VyY2VzIGdyb3VwZWQgYnkgcGFyZW50IChlLmcuLCB0ZWFtKVxyXG4gICAgLy8gT3RoZXJ3aXNlLCByZW5kZXIgaW4gZmlsdGVyIG9yZGVyXHJcbiAgICBsZXQgb3JkZXJlZFJlc291cmNlSWRzOiBzdHJpbmdbXTtcclxuXHJcbiAgICBpZiAoY29udGV4dC5wYXJlbnRDaGlsZE1hcCkge1xyXG4gICAgICAvLyBSZW5kZXIgcmVzb3VyY2VzIGluIHBhcmVudC1jaGlsZCBvcmRlclxyXG4gICAgICBvcmRlcmVkUmVzb3VyY2VJZHMgPSBbXTtcclxuICAgICAgZm9yIChjb25zdCBjaGlsZElkcyBvZiBPYmplY3QudmFsdWVzKGNvbnRleHQucGFyZW50Q2hpbGRNYXApKSB7XHJcbiAgICAgICAgZm9yIChjb25zdCBjaGlsZElkIG9mIGNoaWxkSWRzKSB7XHJcbiAgICAgICAgICBpZiAocmVzb3VyY2VJZHMuaW5jbHVkZXMoY2hpbGRJZCkpIHtcclxuICAgICAgICAgICAgb3JkZXJlZFJlc291cmNlSWRzLnB1c2goY2hpbGRJZCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBvcmRlcmVkUmVzb3VyY2VJZHMgPSByZXNvdXJjZUlkcztcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCByZXNvdXJjZXMgPSBhd2FpdCB0aGlzLmdldEVudGl0aWVzKG9yZGVyZWRSZXNvdXJjZUlkcyk7XHJcblxyXG4gICAgLy8gQ3JlYXRlIGEgbWFwIGZvciBxdWljayBsb29rdXAgdG8gcHJlc2VydmUgb3JkZXJcclxuICAgIGNvbnN0IHJlc291cmNlTWFwID0gbmV3IE1hcChyZXNvdXJjZXMubWFwKHIgPT4gW3IuaWQsIHJdKSk7XHJcblxyXG4gICAgZm9yIChjb25zdCByZXNvdXJjZUlkIG9mIG9yZGVyZWRSZXNvdXJjZUlkcykge1xyXG4gICAgICBjb25zdCByZXNvdXJjZSA9IHJlc291cmNlTWFwLmdldChyZXNvdXJjZUlkKTtcclxuICAgICAgaWYgKCFyZXNvdXJjZSkgY29udGludWU7XHJcblxyXG4gICAgICBjb25zdCBoZWFkZXIgPSB0aGlzLmNyZWF0ZUhlYWRlcihyZXNvdXJjZSwgY29udGV4dCk7XHJcbiAgICAgIGhlYWRlci5zdHlsZS5ncmlkQ29sdW1uID0gYHNwYW4gJHtkYXRlQ291bnR9YDtcclxuICAgICAgY29udGV4dC5oZWFkZXJDb250YWluZXIuYXBwZW5kQ2hpbGQoaGVhZGVyKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB7IEJhc2VHcm91cGluZ1JlbmRlcmVyLCBJR3JvdXBpbmdSZW5kZXJlckNvbmZpZyB9IGZyb20gJy4uLy4uL2NvcmUvQmFzZUdyb3VwaW5nUmVuZGVyZXInO1xyXG5pbXBvcnQgeyBUZWFtU2VydmljZSB9IGZyb20gJy4uLy4uL3N0b3JhZ2UvdGVhbXMvVGVhbVNlcnZpY2UnO1xyXG5pbXBvcnQgeyBJVGVhbSB9IGZyb20gJy4uLy4uL3R5cGVzL0NhbGVuZGFyVHlwZXMnO1xyXG5cclxuZXhwb3J0IGNsYXNzIFRlYW1SZW5kZXJlciBleHRlbmRzIEJhc2VHcm91cGluZ1JlbmRlcmVyPElUZWFtPiB7XHJcbiAgcmVhZG9ubHkgdHlwZSA9ICd0ZWFtJztcclxuXHJcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbmZpZzogSUdyb3VwaW5nUmVuZGVyZXJDb25maWcgPSB7XHJcbiAgICBlbGVtZW50VGFnOiAnc3dwLXRlYW0taGVhZGVyJyxcclxuICAgIGlkQXR0cmlidXRlOiAndGVhbUlkJyxcclxuICAgIGNvbHNwYW5WYXI6ICctLXRlYW0tY29scydcclxuICB9O1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHRlYW1TZXJ2aWNlOiBUZWFtU2VydmljZSkge1xyXG4gICAgc3VwZXIoKTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBnZXRFbnRpdGllcyhpZHM6IHN0cmluZ1tdKTogUHJvbWlzZTxJVGVhbVtdPiB7XHJcbiAgICByZXR1cm4gdGhpcy50ZWFtU2VydmljZS5nZXRCeUlkcyhpZHMpO1xyXG4gIH1cclxuXHJcbiAgcHJvdGVjdGVkIGdldERpc3BsYXlOYW1lKGVudGl0eTogSVRlYW0pOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIGVudGl0eS5uYW1lO1xyXG4gIH1cclxufVxyXG4iLCAiZXhwb3J0IGNsYXNzIFRpbWVBeGlzUmVuZGVyZXIge1xyXG4gIHJlbmRlcihjb250YWluZXI6IEhUTUxFbGVtZW50LCBzdGFydEhvdXIgPSA2LCBlbmRIb3VyID0gMjApOiB2b2lkIHtcclxuICAgIGNvbnRhaW5lci5pbm5lckhUTUwgPSAnJztcclxuICAgIGZvciAobGV0IGhvdXIgPSBzdGFydEhvdXI7IGhvdXIgPD0gZW5kSG91cjsgaG91cisrKSB7XHJcbiAgICAgIGNvbnN0IG1hcmtlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N3cC1ob3VyLW1hcmtlcicpO1xyXG4gICAgICBtYXJrZXIudGV4dENvbnRlbnQgPSBgJHtob3VyLnRvU3RyaW5nKCkucGFkU3RhcnQoMiwgJzAnKX06MDBgO1xyXG4gICAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQobWFya2VyKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQSxLQUFDLFNBQVMsR0FBRSxHQUFFO0FBQUMsa0JBQVUsT0FBTyxXQUFTLGVBQWEsT0FBTyxTQUFPLE9BQU8sVUFBUSxFQUFFLElBQUUsY0FBWSxPQUFPLFVBQVEsT0FBTyxNQUFJLE9BQU8sQ0FBQyxLQUFHLElBQUUsZUFBYSxPQUFPLGFBQVcsYUFBVyxLQUFHLE1BQU0sUUFBTSxFQUFFO0FBQUEsSUFBQyxFQUFFLFNBQU0sV0FBVTtBQUFDO0FBQWEsVUFBSSxJQUFFLEtBQUksSUFBRSxLQUFJLElBQUUsTUFBSyxJQUFFLGVBQWMsSUFBRSxVQUFTLElBQUUsVUFBUyxJQUFFLFFBQU8sSUFBRSxPQUFNLElBQUUsUUFBTyxJQUFFLFNBQVEsSUFBRSxXQUFVLElBQUUsUUFBTyxJQUFFLFFBQU8sSUFBRSxnQkFBZSxJQUFFLDhGQUE2RixJQUFFLHVGQUFzRixJQUFFLEVBQUMsTUFBSyxNQUFLLFVBQVMsMkRBQTJELE1BQU0sR0FBRyxHQUFFLFFBQU8sd0ZBQXdGLE1BQU0sR0FBRyxHQUFFLFNBQVEsU0FBU0EsSUFBRTtBQUFDLFlBQUlDLEtBQUUsQ0FBQyxNQUFLLE1BQUssTUFBSyxJQUFJLEdBQUVDLEtBQUVGLEtBQUU7QUFBSSxlQUFNLE1BQUlBLE1BQUdDLElBQUdDLEtBQUUsTUFBSSxFQUFFLEtBQUdELEdBQUVDLEVBQUMsS0FBR0QsR0FBRSxDQUFDLEtBQUc7QUFBQSxNQUFHLEVBQUMsR0FBRSxJQUFFLGdDQUFTRCxJQUFF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QUFPLE9BQU87QUFBQSxFQUNoQjtBQUNGO0FBcEI4RDtBQUF2RCxJQUFNLGVBQU47OztBQ0pBLElBQU0sb0JBQU4sTUFBTSxrQkFBaUI7QUFBQSxFQUM1QixPQUFPLFdBQXdCLFlBQVksR0FBRyxVQUFVLElBQVU7QUFDaEUsY0FBVSxZQUFZO0FBQ3RCLGFBQVMsT0FBTyxXQUFXLFFBQVEsU0FBUyxRQUFRO0FBQ2xELFlBQU0sU0FBUyxTQUFTLGNBQWMsaUJBQWlCO0FBQ3ZELGFBQU8sY0FBYyxHQUFHLEtBQUssU0FBUyxFQUFFLFNBQVMsR0FBRyxHQUFHLENBQUM7QUFDeEQsZ0JBQVUsWUFBWSxNQUFNO0FBQUEsSUFDOUI7QUFBQSxFQUNGO0FBQ0Y7QUFUOEI7QUFBdkIsSUFBTSxtQkFBTjsiLAogICJuYW1lcyI6IFsidCIsICJlIiwgIm4iLCAiciIsICJpIiwgInMiLCAidSIsICJhIiwgIk0iLCAibSIsICJmIiwgImwiLCAiJCIsICJ5IiwgInYiLCAiZyIsICJEIiwgIm8iLCAiZCIsICJjIiwgImgiLCAidCIsICJpIiwgImUiLCAicyIsICJmIiwgIm4iLCAidSIsICJyIiwgIm8iLCAidCIsICJuIiwgImkiLCAibyIsICJyIiwgImUiLCAidSIsICJmIiwgInMiLCAiYSIsICJ0IiwgImkiLCAiZCIsICJuIiwgImUiLCAicyIsICJkYXlqcyIsICJ1dGMiLCAidGltZXpvbmUiLCAiaXNvV2VlayJdCn0K
|