From 25f80a1a9f5cd67c33ceccc50f99c1b2c167f5cd Mon Sep 17 00:00:00 2001 From: Chris Ian Fiel Date: Sun, 14 Jun 2026 12:01:11 +0800 Subject: [PATCH] Release Pageden Obsidian plugin 0.1.0 --- .gitignore | 1 + LICENSE | 21 + README.md | 87 + main.js | 44064 ++++++++++++++++++++++++++++++++++++++++++++++++ manifest.json | 9 + styles.css | 78 + versions.json | 3 + 7 files changed, 44263 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 main.js create mode 100644 manifest.json create mode 100644 styles.css create mode 100644 versions.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..16bc36b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 PageDen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..361c00f --- /dev/null +++ b/README.md @@ -0,0 +1,87 @@ +# Pageden for Obsidian + +Connect an Obsidian vault to Pageden, a server-owned Markdown workspace for teams and AI agents. +Use it to browse remote documents, download folders into your vault, sync local edits back to +Pageden, and import an existing vault into a workspace. + +## Requirements + +- Obsidian 1.5.0 or newer. +- A Pageden workspace. The hosted server defaults to `https://go.pageden.app`. +- Network access to your Pageden server. + +## Commands + +- `Pageden: Validate connection` +- `Pageden: Browse remote documents` +- `Pageden: Search remote documents` +- `Pageden: Open live document` +- `Pageden: Push active document` +- `Pageden: Sync now` +- `Pageden: Download a Pageden folder` +- `Pageden: Download all Pageden documents` +- `Pageden: Import this vault to Pageden` +- `Pageden: Resolve conflict for this note` +- `Pageden: Log in with device code` + +## Setup + +1. Open Obsidian settings. +2. Go to **Community plugins** and enable Pageden. +3. Open **Pageden** settings. +4. Keep the default server URL, or enter your self-hosted Pageden server. +5. Click **Connect to Pageden** and approve the login in your browser. +6. Pick the workspace to sync with this vault. + +## Settings Reference + +- Server URL, default `https://go.pageden.app` +- Personal access token from the web app's Obsidian token screen, or a token from device-code login +- Workspace ID +- Local folder, default `Remote Docs` +- Background sync toggle +- Sync interval in minutes + +Downloaded files are written under the local folder. Sync metadata is stored in +`.server-meta.json` next to the plugin files and is keyed by `documentId`. + +## Sync Behavior + +Pushes send the recorded `baseVersion`, LF-canonicalized content, and checksum. On a conflict, +the local file is left untouched and the server copy is written as `*.conflict.md`. + +New local Markdown notes can also be created in Pageden. Put the note inside the configured +local folder, for example `Remote Docs/team/plan.md`, then run `Pageden: Push active document`. +The plugin creates any missing remote folders, creates the document, and records sync metadata +so later edits use normal push/pull conflict checks. Background sync also auto-creates new +unlinked notes that are saved under the configured local folder. + +Remote search uses the server's permission-filtered `GET /search` endpoint and can download a +matching document into the configured local folder. + +## Live Documents + +Live document mode opens a custom Pageden editor pane inside Obsidian instead of editing a +downloaded Markdown file. It joins the same Yjs/WebSocket room as the web app's Live mode, merges +simultaneous edits, and autosaves the merged Markdown through the normal revision API. Use this +when you want Google Docs-style co-editing; use downloaded files + background sync when you want +the native Obsidian vault/file workflow. + +## Attachments + +Attachment sync follows Markdown links such as `![diagram](diagram.png)` and Obsidian embeds +such as `![[diagram.png]]`. Downloading or pulling a document writes server attachments beside +the local Markdown file. Pushing a document uploads changed referenced local attachments and +deletes remote attachments only when a previously tracked local attachment file was removed. + +## Privacy And Network Access + +Pageden for Obsidian communicates with the Pageden server configured in settings. Document +content, metadata, attachment files, and sync state are sent to that server when you download, +push, import, or use live editing. The plugin does not send data to unrelated third-party +services. + +## Source + +The plugin is developed in the main PageDen repository and published here as a standalone +community plugin package. diff --git a/main.js b/main.js new file mode 100644 index 0000000..f3bd808 --- /dev/null +++ b/main.js @@ -0,0 +1,44064 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all2) => { + for (var name in all2) + __defProp(target, name, { get: all2[name], enumerable: true }); +}; +var __copyProps = (to, from3, except, desc) => { + if (from3 && typeof from3 === "object" || typeof from3 === "function") { + for (let key of __getOwnPropNames(from3)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from3[key], enumerable: !(desc = __getOwnPropDesc(from3, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/main.ts +var main_exports = {}; +__export(main_exports, { + default: () => PagedenPlugin +}); +module.exports = __toCommonJS(main_exports); +var import_obsidian4 = require("obsidian"); + +// ../../node_modules/.pnpm/orderedmap@2.1.1/node_modules/orderedmap/dist/index.js +function OrderedMap(content) { + this.content = content; +} +OrderedMap.prototype = { + constructor: OrderedMap, + find: function(key) { + for (var i = 0; i < this.content.length; i += 2) + if (this.content[i] === key) return i; + return -1; + }, + // :: (string) → ?any + // Retrieve the value stored under `key`, or return undefined when + // no such key exists. + get: function(key) { + var found3 = this.find(key); + return found3 == -1 ? void 0 : this.content[found3 + 1]; + }, + // :: (string, any, ?string) → OrderedMap + // Create a new map by replacing the value of `key` with a new + // value, or adding a binding to the end of the map. If `newKey` is + // given, the key of the binding will be replaced with that key. + update: function(key, value, newKey) { + var self = newKey && newKey != key ? this.remove(newKey) : this; + var found3 = self.find(key), content = self.content.slice(); + if (found3 == -1) { + content.push(newKey || key, value); + } else { + content[found3 + 1] = value; + if (newKey) content[found3] = newKey; + } + return new OrderedMap(content); + }, + // :: (string) → OrderedMap + // Return a map with the given key removed, if it existed. + remove: function(key) { + var found3 = this.find(key); + if (found3 == -1) return this; + var content = this.content.slice(); + content.splice(found3, 2); + return new OrderedMap(content); + }, + // :: (string, any) → OrderedMap + // Add a new key to the start of the map. + addToStart: function(key, value) { + return new OrderedMap([key, value].concat(this.remove(key).content)); + }, + // :: (string, any) → OrderedMap + // Add a new key to the end of the map. + addToEnd: function(key, value) { + var content = this.remove(key).content.slice(); + content.push(key, value); + return new OrderedMap(content); + }, + // :: (string, string, any) → OrderedMap + // Add a key after the given key. If `place` is not found, the new + // key is added to the end. + addBefore: function(place, key, value) { + var without = this.remove(key), content = without.content.slice(); + var found3 = without.find(place); + content.splice(found3 == -1 ? content.length : found3, 0, key, value); + return new OrderedMap(content); + }, + // :: ((key: string, value: any)) + // Call the given function for each key/value pair in the map, in + // order. + forEach: function(f) { + for (var i = 0; i < this.content.length; i += 2) + f(this.content[i], this.content[i + 1]); + }, + // :: (union) → OrderedMap + // Create a new map by prepending the keys in this map that don't + // appear in `map` before the keys in `map`. + prepend: function(map4) { + map4 = OrderedMap.from(map4); + if (!map4.size) return this; + return new OrderedMap(map4.content.concat(this.subtract(map4).content)); + }, + // :: (union) → OrderedMap + // Create a new map by appending the keys in this map that don't + // appear in `map` after the keys in `map`. + append: function(map4) { + map4 = OrderedMap.from(map4); + if (!map4.size) return this; + return new OrderedMap(this.subtract(map4).content.concat(map4.content)); + }, + // :: (union) → OrderedMap + // Create a map containing all the keys in this map that don't + // appear in `map`. + subtract: function(map4) { + var result = this; + map4 = OrderedMap.from(map4); + for (var i = 0; i < map4.content.length; i += 2) + result = result.remove(map4.content[i]); + return result; + }, + // :: () → Object + // Turn ordered map into a plain object. + toObject: function() { + var result = {}; + this.forEach(function(key, value) { + result[key] = value; + }); + return result; + }, + // :: number + // The amount of keys in this map. + get size() { + return this.content.length >> 1; + } +}; +OrderedMap.from = function(value) { + if (value instanceof OrderedMap) return value; + var content = []; + if (value) for (var prop in value) content.push(prop, value[prop]); + return new OrderedMap(content); +}; +var dist_default = OrderedMap; + +// ../../node_modules/.pnpm/prosemirror-model@1.25.7/node_modules/prosemirror-model/dist/index.js +function findDiffStart(a, b2, pos) { + for (let i = 0; ; i++) { + if (i == a.childCount || i == b2.childCount) + return a.childCount == b2.childCount ? null : pos; + let childA = a.child(i), childB = b2.child(i); + if (childA == childB) { + pos += childA.nodeSize; + continue; + } + if (!childA.sameMarkup(childB)) + return pos; + if (childA.isText && childA.text != childB.text) { + for (let j2 = 0; childA.text[j2] == childB.text[j2]; j2++) + pos++; + return pos; + } + if (childA.content.size || childB.content.size) { + let inner = findDiffStart(childA.content, childB.content, pos + 1); + if (inner != null) + return inner; + } + pos += childA.nodeSize; + } +} +function findDiffEnd(a, b2, posA, posB) { + for (let iA = a.childCount, iB = b2.childCount; ; ) { + if (iA == 0 || iB == 0) + return iA == iB ? null : { a: posA, b: posB }; + let childA = a.child(--iA), childB = b2.child(--iB), size2 = childA.nodeSize; + if (childA == childB) { + posA -= size2; + posB -= size2; + continue; + } + if (!childA.sameMarkup(childB)) + return { a: posA, b: posB }; + if (childA.isText && childA.text != childB.text) { + let same = 0, minSize = Math.min(childA.text.length, childB.text.length); + while (same < minSize && childA.text[childA.text.length - same - 1] == childB.text[childB.text.length - same - 1]) { + same++; + posA--; + posB--; + } + return { a: posA, b: posB }; + } + if (childA.content.size || childB.content.size) { + let inner = findDiffEnd(childA.content, childB.content, posA - 1, posB - 1); + if (inner) + return inner; + } + posA -= size2; + posB -= size2; + } +} +var Fragment = class _Fragment2 { + /** + @internal + */ + constructor(content, size2) { + this.content = content; + this.size = size2 || 0; + if (size2 == null) + for (let i = 0; i < content.length; i++) + this.size += content[i].nodeSize; + } + /** + Invoke a callback for all descendant nodes between the given two + positions (relative to start of this fragment). Doesn't descend + into a node when the callback returns `false`. + */ + nodesBetween(from3, to, f, nodeStart = 0, parent) { + for (let i = 0, pos = 0; pos < to; i++) { + let child = this.content[i], end = pos + child.nodeSize; + if (end > from3 && f(child, nodeStart + pos, parent || null, i) !== false && child.content.size) { + let start = pos + 1; + child.nodesBetween(Math.max(0, from3 - start), Math.min(child.content.size, to - start), f, nodeStart + start); + } + pos = end; + } + } + /** + Call the given callback for every descendant node. `pos` will be + relative to the start of the fragment. The callback may return + `false` to prevent traversal of a given node's children. + */ + descendants(f) { + this.nodesBetween(0, this.size, f); + } + /** + Extract the text between `from` and `to`. See the same method on + [`Node`](https://prosemirror.net/docs/ref/#model.Node.textBetween). + */ + textBetween(from3, to, blockSeparator, leafText) { + let text2 = "", first2 = true; + this.nodesBetween(from3, to, (node, pos) => { + let nodeText = node.isText ? node.text.slice(Math.max(from3, pos) - pos, to - pos) : !node.isLeaf ? "" : leafText ? typeof leafText === "function" ? leafText(node) : leafText : node.type.spec.leafText ? node.type.spec.leafText(node) : ""; + if (node.isBlock && (node.isLeaf && nodeText || node.isTextblock) && blockSeparator) { + if (first2) + first2 = false; + else + text2 += blockSeparator; + } + text2 += nodeText; + }, 0); + return text2; + } + /** + Create a new fragment containing the combined content of this + fragment and the other. + */ + append(other) { + if (!other.size) + return this; + if (!this.size) + return other; + let last2 = this.lastChild, first2 = other.firstChild, content = this.content.slice(), i = 0; + if (last2.isText && last2.sameMarkup(first2)) { + content[content.length - 1] = last2.withText(last2.text + first2.text); + i = 1; + } + for (; i < other.content.length; i++) + content.push(other.content[i]); + return new _Fragment2(content, this.size + other.size); + } + /** + Cut out the sub-fragment between the two given positions. + */ + cut(from3, to = this.size) { + if (from3 == 0 && to == this.size) + return this; + let result = [], size2 = 0; + if (to > from3) + for (let i = 0, pos = 0; pos < to; i++) { + let child = this.content[i], end = pos + child.nodeSize; + if (end > from3) { + if (pos < from3 || end > to) { + if (child.isText) + child = child.cut(Math.max(0, from3 - pos), Math.min(child.text.length, to - pos)); + else + child = child.cut(Math.max(0, from3 - pos - 1), Math.min(child.content.size, to - pos - 1)); + } + result.push(child); + size2 += child.nodeSize; + } + pos = end; + } + return new _Fragment2(result, size2); + } + /** + @internal + */ + cutByIndex(from3, to) { + if (from3 == to) + return _Fragment2.empty; + if (from3 == 0 && to == this.content.length) + return this; + return new _Fragment2(this.content.slice(from3, to)); + } + /** + Create a new fragment in which the node at the given index is + replaced by the given node. + */ + replaceChild(index, node) { + let current = this.content[index]; + if (current == node) + return this; + let copy3 = this.content.slice(); + let size2 = this.size + node.nodeSize - current.nodeSize; + copy3[index] = node; + return new _Fragment2(copy3, size2); + } + /** + Create a new fragment by prepending the given node to this + fragment. + */ + addToStart(node) { + return new _Fragment2([node].concat(this.content), this.size + node.nodeSize); + } + /** + Create a new fragment by appending the given node to this + fragment. + */ + addToEnd(node) { + return new _Fragment2(this.content.concat(node), this.size + node.nodeSize); + } + /** + Compare this fragment to another one. + */ + eq(other) { + if (this.content.length != other.content.length) + return false; + for (let i = 0; i < this.content.length; i++) + if (!this.content[i].eq(other.content[i])) + return false; + return true; + } + /** + The first child of the fragment, or `null` if it is empty. + */ + get firstChild() { + return this.content.length ? this.content[0] : null; + } + /** + The last child of the fragment, or `null` if it is empty. + */ + get lastChild() { + return this.content.length ? this.content[this.content.length - 1] : null; + } + /** + The number of child nodes in this fragment. + */ + get childCount() { + return this.content.length; + } + /** + Get the child node at the given index. Raise an error when the + index is out of range. + */ + child(index) { + let found3 = this.content[index]; + if (!found3) + throw new RangeError("Index " + index + " out of range for " + this); + return found3; + } + /** + Get the child node at the given index, if it exists. + */ + maybeChild(index) { + return this.content[index] || null; + } + /** + Call `f` for every child node, passing the node, its offset + into this parent node, and its index. + */ + forEach(f) { + for (let i = 0, p = 0; i < this.content.length; i++) { + let child = this.content[i]; + f(child, p, i); + p += child.nodeSize; + } + } + /** + Find the first position at which this fragment and another + fragment differ, or `null` if they are the same. + */ + findDiffStart(other, pos = 0) { + return findDiffStart(this, other, pos); + } + /** + Find the first position, searching from the end, at which this + fragment and the given fragment differ, or `null` if they are + the same. Since this position will not be the same in both + nodes, an object with two separate positions is returned. + */ + findDiffEnd(other, pos = this.size, otherPos = other.size) { + return findDiffEnd(this, other, pos, otherPos); + } + /** + Find the index and inner offset corresponding to a given relative + position in this fragment. The result object will be reused + (overwritten) the next time the function is called. @internal + */ + findIndex(pos) { + if (pos == 0) + return retIndex(0, pos); + if (pos == this.size) + return retIndex(this.content.length, pos); + if (pos > this.size || pos < 0) + throw new RangeError(`Position ${pos} outside of fragment (${this})`); + for (let i = 0, curPos = 0; ; i++) { + let cur = this.child(i), end = curPos + cur.nodeSize; + if (end >= pos) { + if (end == pos) + return retIndex(i + 1, end); + return retIndex(i, curPos); + } + curPos = end; + } + } + /** + Return a debugging string that describes this fragment. + */ + toString() { + return "<" + this.toStringInner() + ">"; + } + /** + @internal + */ + toStringInner() { + return this.content.join(", "); + } + /** + Create a JSON-serializeable representation of this fragment. + */ + toJSON() { + return this.content.length ? this.content.map((n) => n.toJSON()) : null; + } + /** + Deserialize a fragment from its JSON representation. + */ + static fromJSON(schema, value) { + if (!value) + return _Fragment2.empty; + if (!Array.isArray(value)) + throw new RangeError("Invalid input for Fragment.fromJSON"); + return _Fragment2.fromArray(value.map(schema.nodeFromJSON)); + } + /** + Build a fragment from an array of nodes. Ensures that adjacent + text nodes with the same marks are joined together. + */ + static fromArray(array) { + if (!array.length) + return _Fragment2.empty; + let joined, size2 = 0; + for (let i = 0; i < array.length; i++) { + let node = array[i]; + size2 += node.nodeSize; + if (i && node.isText && array[i - 1].sameMarkup(node)) { + if (!joined) + joined = array.slice(0, i); + joined[joined.length - 1] = node.withText(joined[joined.length - 1].text + node.text); + } else if (joined) { + joined.push(node); + } + } + return new _Fragment2(joined || array, size2); + } + /** + Create a fragment from something that can be interpreted as a + set of nodes. For `null`, it returns the empty fragment. For a + fragment, the fragment itself. For a node or array of nodes, a + fragment containing those nodes. + */ + static from(nodes) { + if (!nodes) + return _Fragment2.empty; + if (nodes instanceof _Fragment2) + return nodes; + if (Array.isArray(nodes)) + return this.fromArray(nodes); + if (nodes.attrs) + return new _Fragment2([nodes], nodes.nodeSize); + throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : "")); + } +}; +Fragment.empty = new Fragment([], 0); +var found = { index: 0, offset: 0 }; +function retIndex(index, offset) { + found.index = index; + found.offset = offset; + return found; +} +function compareDeep(a, b2) { + if (a === b2) + return true; + if (!(a && typeof a == "object") || !(b2 && typeof b2 == "object")) + return false; + let array = Array.isArray(a); + if (Array.isArray(b2) != array) + return false; + if (array) { + if (a.length != b2.length) + return false; + for (let i = 0; i < a.length; i++) + if (!compareDeep(a[i], b2[i])) + return false; + } else { + for (let p in a) + if (!(p in b2) || !compareDeep(a[p], b2[p])) + return false; + for (let p in b2) + if (!(p in a)) + return false; + } + return true; +} +var Mark = class _Mark3 { + /** + @internal + */ + constructor(type, attrs) { + this.type = type; + this.attrs = attrs; + } + /** + Given a set of marks, create a new set which contains this one as + well, in the right position. If this mark is already in the set, + the set itself is returned. If any marks that are set to be + [exclusive](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) with this mark are present, + those are replaced by this one. + */ + addToSet(set) { + let copy3, placed = false; + for (let i = 0; i < set.length; i++) { + let other = set[i]; + if (this.eq(other)) + return set; + if (this.type.excludes(other.type)) { + if (!copy3) + copy3 = set.slice(0, i); + } else if (other.type.excludes(this.type)) { + return set; + } else { + if (!placed && other.type.rank > this.type.rank) { + if (!copy3) + copy3 = set.slice(0, i); + copy3.push(this); + placed = true; + } + if (copy3) + copy3.push(other); + } + } + if (!copy3) + copy3 = set.slice(); + if (!placed) + copy3.push(this); + return copy3; + } + /** + Remove this mark from the given set, returning a new set. If this + mark is not in the set, the set itself is returned. + */ + removeFromSet(set) { + for (let i = 0; i < set.length; i++) + if (this.eq(set[i])) + return set.slice(0, i).concat(set.slice(i + 1)); + return set; + } + /** + Test whether this mark is in the given set of marks. + */ + isInSet(set) { + for (let i = 0; i < set.length; i++) + if (this.eq(set[i])) + return true; + return false; + } + /** + Test whether this mark has the same type and attributes as + another mark. + */ + eq(other) { + return this == other || this.type == other.type && compareDeep(this.attrs, other.attrs); + } + /** + Convert this mark to a JSON-serializeable representation. + */ + toJSON() { + let obj = { type: this.type.name }; + for (let _2 in this.attrs) { + obj.attrs = this.attrs; + break; + } + return obj; + } + /** + Deserialize a mark from JSON. + */ + static fromJSON(schema, json) { + if (!json) + throw new RangeError("Invalid input for Mark.fromJSON"); + let type = schema.marks[json.type]; + if (!type) + throw new RangeError(`There is no mark type ${json.type} in this schema`); + let mark = type.create(json.attrs); + type.checkAttrs(mark.attrs); + return mark; + } + /** + Test whether two sets of marks are identical. + */ + static sameSet(a, b2) { + if (a == b2) + return true; + if (a.length != b2.length) + return false; + for (let i = 0; i < a.length; i++) + if (!a[i].eq(b2[i])) + return false; + return true; + } + /** + Create a properly sorted mark set from null, a single mark, or an + unsorted array of marks. + */ + static setFrom(marks) { + if (!marks || Array.isArray(marks) && marks.length == 0) + return _Mark3.none; + if (marks instanceof _Mark3) + return [marks]; + let copy3 = marks.slice(); + copy3.sort((a, b2) => a.type.rank - b2.type.rank); + return copy3; + } +}; +Mark.none = []; +var ReplaceError = class extends Error { +}; +var Slice = class _Slice2 { + /** + Create a slice. When specifying a non-zero open depth, you must + make sure that there are nodes of at least that depth at the + appropriate side of the fragment—i.e. if the fragment is an + empty paragraph node, `openStart` and `openEnd` can't be greater + than 1. + + It is not necessary for the content of open nodes to conform to + the schema's content constraints, though it should be a valid + start/end/middle for such a node, depending on which sides are + open. + */ + constructor(content, openStart, openEnd) { + this.content = content; + this.openStart = openStart; + this.openEnd = openEnd; + } + /** + The size this slice would add when inserted into a document. + */ + get size() { + return this.content.size - this.openStart - this.openEnd; + } + /** + @internal + */ + insertAt(pos, fragment) { + let content = insertInto(this.content, pos + this.openStart, fragment, this.openStart + 1, this.openEnd + 1); + return content && new _Slice2(content, this.openStart, this.openEnd); + } + /** + @internal + */ + removeBetween(from3, to) { + return new _Slice2(removeRange(this.content, from3 + this.openStart, to + this.openStart), this.openStart, this.openEnd); + } + /** + Tests whether this slice is equal to another slice. + */ + eq(other) { + return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd; + } + /** + @internal + */ + toString() { + return this.content + "(" + this.openStart + "," + this.openEnd + ")"; + } + /** + Convert a slice to a JSON-serializable representation. + */ + toJSON() { + if (!this.content.size) + return null; + let json = { content: this.content.toJSON() }; + if (this.openStart > 0) + json.openStart = this.openStart; + if (this.openEnd > 0) + json.openEnd = this.openEnd; + return json; + } + /** + Deserialize a slice from its JSON representation. + */ + static fromJSON(schema, json) { + if (!json) + return _Slice2.empty; + let openStart = json.openStart || 0, openEnd = json.openEnd || 0; + if (typeof openStart != "number" || typeof openEnd != "number") + throw new RangeError("Invalid input for Slice.fromJSON"); + return new _Slice2(Fragment.fromJSON(schema, json.content), openStart, openEnd); + } + /** + Create a slice from a fragment by taking the maximum possible + open value on both side of the fragment. + */ + static maxOpen(fragment, openIsolating = true) { + let openStart = 0, openEnd = 0; + for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild) + openStart++; + for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild) + openEnd++; + return new _Slice2(fragment, openStart, openEnd); + } +}; +Slice.empty = new Slice(Fragment.empty, 0, 0); +function removeRange(content, from3, to) { + let { index, offset } = content.findIndex(from3), child = content.maybeChild(index); + let { index: indexTo, offset: offsetTo } = content.findIndex(to); + if (offset == from3 || child.isText) { + if (offsetTo != to && !content.child(indexTo).isText) + throw new RangeError("Removing non-flat range"); + return content.cut(0, from3).append(content.cut(to)); + } + if (index != indexTo) + throw new RangeError("Removing non-flat range"); + return content.replaceChild(index, child.copy(removeRange(child.content, from3 - offset - 1, to - offset - 1))); +} +function insertInto(content, dist, insert, openStart, openEnd, parent) { + let { index, offset } = content.findIndex(dist), child = content.maybeChild(index); + if (offset == dist || child.isText) { + if (parent && openStart <= 0 && openEnd <= 0 && !parent.canReplace(index, index, insert)) + return null; + return content.cut(0, dist).append(insert).append(content.cut(dist)); + } + let inner = insertInto(child.content, dist - offset - 1, insert, index == 0 ? openStart - 1 : 0, index == content.childCount - 1 ? openEnd - 1 : 0, child); + return inner && content.replaceChild(index, child.copy(inner)); +} +function replace($from, $to, slice2) { + if (slice2.openStart > $from.depth) + throw new ReplaceError("Inserted content deeper than insertion position"); + if ($from.depth - slice2.openStart != $to.depth - slice2.openEnd) + throw new ReplaceError("Inconsistent open depths"); + return replaceOuter($from, $to, slice2, 0); +} +function replaceOuter($from, $to, slice2, depth) { + let index = $from.index(depth), node = $from.node(depth); + if (index == $to.index(depth) && depth < $from.depth - slice2.openStart) { + let inner = replaceOuter($from, $to, slice2, depth + 1); + return node.copy(node.content.replaceChild(index, inner)); + } else if (!slice2.content.size) { + return close(node, replaceTwoWay($from, $to, depth)); + } else if (!slice2.openStart && !slice2.openEnd && $from.depth == depth && $to.depth == depth) { + let parent = $from.parent, content = parent.content; + return close(parent, content.cut(0, $from.parentOffset).append(slice2.content).append(content.cut($to.parentOffset))); + } else { + let { start, end } = prepareSliceForReplace(slice2, $from); + return close(node, replaceThreeWay($from, start, end, $to, depth)); + } +} +function checkJoin(main, sub) { + if (!sub.type.compatibleContent(main.type)) + throw new ReplaceError("Cannot join " + sub.type.name + " onto " + main.type.name); +} +function joinable($before, $after, depth) { + let node = $before.node(depth); + checkJoin(node, $after.node(depth)); + return node; +} +function addNode(child, target) { + let last2 = target.length - 1; + if (last2 >= 0 && child.isText && child.sameMarkup(target[last2])) + target[last2] = child.withText(target[last2].text + child.text); + else + target.push(child); +} +function addRange($start, $end, depth, target) { + let node = ($end || $start).node(depth); + let startIndex = 0, endIndex = $end ? $end.index(depth) : node.childCount; + if ($start) { + startIndex = $start.index(depth); + if ($start.depth > depth) { + startIndex++; + } else if ($start.textOffset) { + addNode($start.nodeAfter, target); + startIndex++; + } + } + for (let i = startIndex; i < endIndex; i++) + addNode(node.child(i), target); + if ($end && $end.depth == depth && $end.textOffset) + addNode($end.nodeBefore, target); +} +function close(node, content) { + node.type.checkContent(content); + return node.copy(content); +} +function replaceThreeWay($from, $start, $end, $to, depth) { + let openStart = $from.depth > depth && joinable($from, $start, depth + 1); + let openEnd = $to.depth > depth && joinable($end, $to, depth + 1); + let content = []; + addRange(null, $from, depth, content); + if (openStart && openEnd && $start.index(depth) == $end.index(depth)) { + checkJoin(openStart, openEnd); + addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content); + } else { + if (openStart) + addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content); + addRange($start, $end, depth, content); + if (openEnd) + addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content); + } + addRange($to, null, depth, content); + return new Fragment(content); +} +function replaceTwoWay($from, $to, depth) { + let content = []; + addRange(null, $from, depth, content); + if ($from.depth > depth) { + let type = joinable($from, $to, depth + 1); + addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content); + } + addRange($to, null, depth, content); + return new Fragment(content); +} +function prepareSliceForReplace(slice2, $along) { + let extra = $along.depth - slice2.openStart, parent = $along.node(extra); + let node = parent.copy(slice2.content); + for (let i = extra - 1; i >= 0; i--) + node = $along.node(i).copy(Fragment.from(node)); + return { + start: node.resolveNoCache(slice2.openStart + extra), + end: node.resolveNoCache(node.content.size - slice2.openEnd - extra) + }; +} +var ResolvedPos = class _ResolvedPos2 { + /** + @internal + */ + constructor(pos, path, parentOffset) { + this.pos = pos; + this.path = path; + this.parentOffset = parentOffset; + this.depth = path.length / 3 - 1; + } + /** + @internal + */ + resolveDepth(val) { + if (val == null) + return this.depth; + if (val < 0) + return this.depth + val; + return val; + } + /** + The parent node that the position points into. Note that even if + a position points into a text node, that node is not considered + the parent—text nodes are ‘flat’ in this model, and have no content. + */ + get parent() { + return this.node(this.depth); + } + /** + The root node in which the position was resolved. + */ + get doc() { + return this.node(0); + } + /** + The ancestor node at the given level. `p.node(p.depth)` is the + same as `p.parent`. + */ + node(depth) { + return this.path[this.resolveDepth(depth) * 3]; + } + /** + The index into the ancestor at the given level. If this points + at the 3rd node in the 2nd paragraph on the top level, for + example, `p.index(0)` is 1 and `p.index(1)` is 2. + */ + index(depth) { + return this.path[this.resolveDepth(depth) * 3 + 1]; + } + /** + The index pointing after this position into the ancestor at the + given level. + */ + indexAfter(depth) { + depth = this.resolveDepth(depth); + return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1); + } + /** + The (absolute) position at the start of the node at the given + level. + */ + start(depth) { + depth = this.resolveDepth(depth); + return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1; + } + /** + The (absolute) position at the end of the node at the given + level. + */ + end(depth) { + depth = this.resolveDepth(depth); + return this.start(depth) + this.node(depth).content.size; + } + /** + The (absolute) position directly before the wrapping node at the + given level, or, when `depth` is `this.depth + 1`, the original + position. + */ + before(depth) { + depth = this.resolveDepth(depth); + if (!depth) + throw new RangeError("There is no position before the top-level node"); + return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1]; + } + /** + The (absolute) position directly after the wrapping node at the + given level, or the original position when `depth` is `this.depth + 1`. + */ + after(depth) { + depth = this.resolveDepth(depth); + if (!depth) + throw new RangeError("There is no position after the top-level node"); + return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize; + } + /** + When this position points into a text node, this returns the + distance between the position and the start of the text node. + Will be zero for positions that point between nodes. + */ + get textOffset() { + return this.pos - this.path[this.path.length - 1]; + } + /** + Get the node directly after the position, if any. If the position + points into a text node, only the part of that node after the + position is returned. + */ + get nodeAfter() { + let parent = this.parent, index = this.index(this.depth); + if (index == parent.childCount) + return null; + let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index); + return dOff ? parent.child(index).cut(dOff) : child; + } + /** + Get the node directly before the position, if any. If the + position points into a text node, only the part of that node + before the position is returned. + */ + get nodeBefore() { + let index = this.index(this.depth); + let dOff = this.pos - this.path[this.path.length - 1]; + if (dOff) + return this.parent.child(index).cut(0, dOff); + return index == 0 ? null : this.parent.child(index - 1); + } + /** + Get the position at the given index in the parent node at the + given depth (which defaults to `this.depth`). + */ + posAtIndex(index, depth) { + depth = this.resolveDepth(depth); + let node = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1; + for (let i = 0; i < index; i++) + pos += node.child(i).nodeSize; + return pos; + } + /** + Get the marks at this position, factoring in the surrounding + marks' [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) property. If the + position is at the start of a non-empty node, the marks of the + node after it (if any) are returned. + */ + marks() { + let parent = this.parent, index = this.index(); + if (parent.content.size == 0) + return Mark.none; + if (this.textOffset) + return parent.child(index).marks; + let main = parent.maybeChild(index - 1), other = parent.maybeChild(index); + if (!main) { + let tmp = main; + main = other; + other = tmp; + } + let marks = main.marks; + for (var i = 0; i < marks.length; i++) + if (marks[i].type.spec.inclusive === false && (!other || !marks[i].isInSet(other.marks))) + marks = marks[i--].removeFromSet(marks); + return marks; + } + /** + Get the marks after the current position, if any, except those + that are non-inclusive and not present at position `$end`. This + is mostly useful for getting the set of marks to preserve after a + deletion. Will return `null` if this position is at the end of + its parent node or its parent node isn't a textblock (in which + case no marks should be preserved). + */ + marksAcross($end) { + let after = this.parent.maybeChild(this.index()); + if (!after || !after.isInline) + return null; + let marks = after.marks, next2 = $end.parent.maybeChild($end.index()); + for (var i = 0; i < marks.length; i++) + if (marks[i].type.spec.inclusive === false && (!next2 || !marks[i].isInSet(next2.marks))) + marks = marks[i--].removeFromSet(marks); + return marks; + } + /** + The depth up to which this position and the given (non-resolved) + position share the same parent nodes. + */ + sharedDepth(pos) { + for (let depth = this.depth; depth > 0; depth--) + if (this.start(depth) <= pos && this.end(depth) >= pos) + return depth; + return 0; + } + /** + Returns a range based on the place where this position and the + given position diverge around block content. If both point into + the same textblock, for example, a range around that textblock + will be returned. If they point into different blocks, the range + around those blocks in their shared ancestor is returned. You can + pass in an optional predicate that will be called with a parent + node to see if a range into that parent is acceptable. + */ + blockRange(other = this, pred) { + if (other.pos < this.pos) + return other.blockRange(this); + for (let d2 = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d2 >= 0; d2--) + if (other.pos <= this.end(d2) && (!pred || pred(this.node(d2)))) + return new NodeRange(this, other, d2); + return null; + } + /** + Query whether the given position shares the same parent node. + */ + sameParent(other) { + return this.pos - this.parentOffset == other.pos - other.parentOffset; + } + /** + Return the greater of this and the given position. + */ + max(other) { + return other.pos > this.pos ? other : this; + } + /** + Return the smaller of this and the given position. + */ + min(other) { + return other.pos < this.pos ? other : this; + } + /** + @internal + */ + toString() { + let str = ""; + for (let i = 1; i <= this.depth; i++) + str += (str ? "/" : "") + this.node(i).type.name + "_" + this.index(i - 1); + return str + ":" + this.parentOffset; + } + /** + @internal + */ + static resolve(doc4, pos) { + if (!(pos >= 0 && pos <= doc4.content.size)) + throw new RangeError("Position " + pos + " out of range"); + let path = []; + let start = 0, parentOffset = pos; + for (let node = doc4; ; ) { + let { index, offset } = node.content.findIndex(parentOffset); + let rem = parentOffset - offset; + path.push(node, index, start + offset); + if (!rem) + break; + node = node.child(index); + if (node.isText) + break; + parentOffset = rem - 1; + start += offset + 1; + } + return new _ResolvedPos2(pos, path, parentOffset); + } + /** + @internal + */ + static resolveCached(doc4, pos) { + let cache = resolveCache.get(doc4); + if (cache) { + for (let i = 0; i < cache.elts.length; i++) { + let elt = cache.elts[i]; + if (elt.pos == pos) + return elt; + } + } else { + resolveCache.set(doc4, cache = new ResolveCache()); + } + let result = cache.elts[cache.i] = _ResolvedPos2.resolve(doc4, pos); + cache.i = (cache.i + 1) % resolveCacheSize; + return result; + } +}; +var ResolveCache = class { + constructor() { + this.elts = []; + this.i = 0; + } +}; +var resolveCacheSize = 12; +var resolveCache = /* @__PURE__ */ new WeakMap(); +var NodeRange = class { + /** + Construct a node range. `$from` and `$to` should point into the + same node until at least the given `depth`, since a node range + denotes an adjacent set of nodes in a single parent node. + */ + constructor($from, $to, depth) { + this.$from = $from; + this.$to = $to; + this.depth = depth; + } + /** + The position at the start of the range. + */ + get start() { + return this.$from.before(this.depth + 1); + } + /** + The position at the end of the range. + */ + get end() { + return this.$to.after(this.depth + 1); + } + /** + The parent node that the range points into. + */ + get parent() { + return this.$from.node(this.depth); + } + /** + The start index of the range in the parent node. + */ + get startIndex() { + return this.$from.index(this.depth); + } + /** + The end index of the range in the parent node. + */ + get endIndex() { + return this.$to.indexAfter(this.depth); + } +}; +var emptyAttrs = /* @__PURE__ */ Object.create(null); +var Node = class _Node3 { + /** + @internal + */ + constructor(type, attrs, content, marks = Mark.none) { + this.type = type; + this.attrs = attrs; + this.marks = marks; + this.content = content || Fragment.empty; + } + /** + The array of this node's child nodes. + */ + get children() { + return this.content.content; + } + /** + The size of this node, as defined by the integer-based [indexing + scheme](https://prosemirror.net/docs/guide/#doc.indexing). For text nodes, this is the + amount of characters. For other leaf nodes, it is one. For + non-leaf nodes, it is the size of the content plus two (the + start and end token). + */ + get nodeSize() { + return this.isLeaf ? 1 : 2 + this.content.size; + } + /** + The number of children that the node has. + */ + get childCount() { + return this.content.childCount; + } + /** + Get the child node at the given index. Raises an error when the + index is out of range. + */ + child(index) { + return this.content.child(index); + } + /** + Get the child node at the given index, if it exists. + */ + maybeChild(index) { + return this.content.maybeChild(index); + } + /** + Call `f` for every child node, passing the node, its offset + into this parent node, and its index. + */ + forEach(f) { + this.content.forEach(f); + } + /** + Invoke a callback for all descendant nodes recursively overlapping + the given two positions that are relative to start of this + node's content. This includes all ancestors of the nodes + containing the two positions. The callback is invoked with the + node, its position relative to the original node (method receiver), + its parent node, and its child index. When the callback returns + false for a given node, that node's children will not be + recursed over. The last parameter can be used to specify a + starting position to count from. + */ + nodesBetween(from3, to, f, startPos = 0) { + this.content.nodesBetween(from3, to, f, startPos, this); + } + /** + Call the given callback for every descendant node. Doesn't + descend into a node when the callback returns `false`. + */ + descendants(f) { + this.nodesBetween(0, this.content.size, f); + } + /** + Concatenates all the text nodes found in this fragment and its + children. + */ + get textContent() { + return this.isLeaf && this.type.spec.leafText ? this.type.spec.leafText(this) : this.textBetween(0, this.content.size, ""); + } + /** + Get all text between positions `from` and `to`. When + `blockSeparator` is given, it will be inserted to separate text + from different block nodes. If `leafText` is given, it'll be + inserted for every non-text leaf node encountered, otherwise + [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used. + */ + textBetween(from3, to, blockSeparator, leafText) { + return this.content.textBetween(from3, to, blockSeparator, leafText); + } + /** + Returns this node's first child, or `null` if there are no + children. + */ + get firstChild() { + return this.content.firstChild; + } + /** + Returns this node's last child, or `null` if there are no + children. + */ + get lastChild() { + return this.content.lastChild; + } + /** + Test whether two nodes represent the same piece of document. + */ + eq(other) { + return this == other || this.sameMarkup(other) && this.content.eq(other.content); + } + /** + Compare the markup (type, attributes, and marks) of this node to + those of another. Returns `true` if both have the same markup. + */ + sameMarkup(other) { + return this.hasMarkup(other.type, other.attrs, other.marks); + } + /** + Check whether this node's markup correspond to the given type, + attributes, and marks. + */ + hasMarkup(type, attrs, marks) { + return this.type == type && compareDeep(this.attrs, attrs || type.defaultAttrs || emptyAttrs) && Mark.sameSet(this.marks, marks || Mark.none); + } + /** + Create a new node with the same markup as this node, containing + the given content (or empty, if no content is given). + */ + copy(content = null) { + if (content == this.content) + return this; + return new _Node3(this.type, this.attrs, content, this.marks); + } + /** + Create a copy of this node, with the given set of marks instead + of the node's own marks. + */ + mark(marks) { + return marks == this.marks ? this : new _Node3(this.type, this.attrs, this.content, marks); + } + /** + Create a copy of this node with only the content between the + given positions. If `to` is not given, it defaults to the end of + the node. + */ + cut(from3, to = this.content.size) { + if (from3 == 0 && to == this.content.size) + return this; + return this.copy(this.content.cut(from3, to)); + } + /** + Cut out the part of the document between the given positions, and + return it as a `Slice` object. + */ + slice(from3, to = this.content.size, includeParents = false) { + if (from3 == to) + return Slice.empty; + let $from = this.resolve(from3), $to = this.resolve(to); + let depth = includeParents ? 0 : $from.sharedDepth(to); + let start = $from.start(depth), node = $from.node(depth); + let content = node.content.cut($from.pos - start, $to.pos - start); + return new Slice(content, $from.depth - depth, $to.depth - depth); + } + /** + Replace the part of the document between the given positions with + the given slice. The slice must 'fit', meaning its open sides + must be able to connect to the surrounding content, and its + content nodes must be valid children for the node they are placed + into. If any of this is violated, an error of type + [`ReplaceError`](https://prosemirror.net/docs/ref/#model.ReplaceError) is thrown. + */ + replace(from3, to, slice2) { + return replace(this.resolve(from3), this.resolve(to), slice2); + } + /** + Find the node directly after the given position. + */ + nodeAt(pos) { + for (let node = this; ; ) { + let { index, offset } = node.content.findIndex(pos); + node = node.maybeChild(index); + if (!node) + return null; + if (offset == pos || node.isText) + return node; + pos -= offset + 1; + } + } + /** + Find the (direct) child node after the given offset, if any, + and return it along with its index and offset relative to this + node. + */ + childAfter(pos) { + let { index, offset } = this.content.findIndex(pos); + return { node: this.content.maybeChild(index), index, offset }; + } + /** + Find the (direct) child node before the given offset, if any, + and return it along with its index and offset relative to this + node. + */ + childBefore(pos) { + if (pos == 0) + return { node: null, index: 0, offset: 0 }; + let { index, offset } = this.content.findIndex(pos); + if (offset < pos) + return { node: this.content.child(index), index, offset }; + let node = this.content.child(index - 1); + return { node, index: index - 1, offset: offset - node.nodeSize }; + } + /** + Resolve the given position in the document, returning an + [object](https://prosemirror.net/docs/ref/#model.ResolvedPos) with information about its context. + */ + resolve(pos) { + return ResolvedPos.resolveCached(this, pos); + } + /** + @internal + */ + resolveNoCache(pos) { + return ResolvedPos.resolve(this, pos); + } + /** + Test whether a given mark or mark type occurs in this document + between the two given positions. + */ + rangeHasMark(from3, to, type) { + let found3 = false; + if (to > from3) + this.nodesBetween(from3, to, (node) => { + if (type.isInSet(node.marks)) + found3 = true; + return !found3; + }); + return found3; + } + /** + True when this is a block (non-inline node) + */ + get isBlock() { + return this.type.isBlock; + } + /** + True when this is a textblock node, a block node with inline + content. + */ + get isTextblock() { + return this.type.isTextblock; + } + /** + True when this node allows inline content. + */ + get inlineContent() { + return this.type.inlineContent; + } + /** + True when this is an inline node (a text node or a node that can + appear among text). + */ + get isInline() { + return this.type.isInline; + } + /** + True when this is a text node. + */ + get isText() { + return this.type.isText; + } + /** + True when this is a leaf node. + */ + get isLeaf() { + return this.type.isLeaf; + } + /** + True when this is an atom, i.e. when it does not have directly + editable content. This is usually the same as `isLeaf`, but can + be configured with the [`atom` property](https://prosemirror.net/docs/ref/#model.NodeSpec.atom) + on a node's spec (typically used when the node is displayed as + an uneditable [node view](https://prosemirror.net/docs/ref/#view.NodeView)). + */ + get isAtom() { + return this.type.isAtom; + } + /** + Return a string representation of this node for debugging + purposes. + */ + toString() { + if (this.type.spec.toDebugString) + return this.type.spec.toDebugString(this); + let name = this.type.name; + if (this.content.size) + name += "(" + this.content.toStringInner() + ")"; + return wrapMarks(this.marks, name); + } + /** + Get the content match in this node at the given index. + */ + contentMatchAt(index) { + let match2 = this.type.contentMatch.matchFragment(this.content, 0, index); + if (!match2) + throw new Error("Called contentMatchAt on a node with invalid content"); + return match2; + } + /** + Test whether replacing the range between `from` and `to` (by + child index) with the given replacement fragment (which defaults + to the empty fragment) would leave the node's content valid. You + can optionally pass `start` and `end` indices into the + replacement fragment. + */ + canReplace(from3, to, replacement = Fragment.empty, start = 0, end = replacement.childCount) { + let one = this.contentMatchAt(from3).matchFragment(replacement, start, end); + let two = one && one.matchFragment(this.content, to); + if (!two || !two.validEnd) + return false; + for (let i = start; i < end; i++) + if (!this.type.allowsMarks(replacement.child(i).marks)) + return false; + return true; + } + /** + Test whether replacing the range `from` to `to` (by index) with + a node of the given type would leave the node's content valid. + */ + canReplaceWith(from3, to, type, marks) { + if (marks && !this.type.allowsMarks(marks)) + return false; + let start = this.contentMatchAt(from3).matchType(type); + let end = start && start.matchFragment(this.content, to); + return end ? end.validEnd : false; + } + /** + Test whether the given node's content could be appended to this + node. If that node is empty, this will only return true if there + is at least one node type that can appear in both nodes (to avoid + merging completely incompatible nodes). + */ + canAppend(other) { + if (other.content.size) + return this.canReplace(this.childCount, this.childCount, other.content); + else + return this.type.compatibleContent(other.type); + } + /** + Check whether this node and its descendants conform to the + schema, and raise an exception when they do not. + */ + check() { + this.type.checkContent(this.content); + this.type.checkAttrs(this.attrs); + let copy3 = Mark.none; + for (let i = 0; i < this.marks.length; i++) { + let mark = this.marks[i]; + mark.type.checkAttrs(mark.attrs); + copy3 = mark.addToSet(copy3); + } + if (!Mark.sameSet(copy3, this.marks)) + throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map((m2) => m2.type.name)}`); + this.content.forEach((node) => node.check()); + } + /** + Return a JSON-serializeable representation of this node. + */ + toJSON() { + let obj = { type: this.type.name }; + for (let _2 in this.attrs) { + obj.attrs = this.attrs; + break; + } + if (this.content.size) + obj.content = this.content.toJSON(); + if (this.marks.length) + obj.marks = this.marks.map((n) => n.toJSON()); + return obj; + } + /** + Deserialize a node from its JSON representation. + */ + static fromJSON(schema, json) { + if (!json) + throw new RangeError("Invalid input for Node.fromJSON"); + let marks = void 0; + if (json.marks) { + if (!Array.isArray(json.marks)) + throw new RangeError("Invalid mark data for Node.fromJSON"); + marks = json.marks.map(schema.markFromJSON); + } + if (json.type == "text") { + if (typeof json.text != "string") + throw new RangeError("Invalid text node in JSON"); + return schema.text(json.text, marks); + } + let content = Fragment.fromJSON(schema, json.content); + let node = schema.nodeType(json.type).create(json.attrs, content, marks); + node.type.checkAttrs(node.attrs); + return node; + } +}; +Node.prototype.text = void 0; +var TextNode = class _TextNode extends Node { + /** + @internal + */ + constructor(type, attrs, content, marks) { + super(type, attrs, null, marks); + if (!content) + throw new RangeError("Empty text nodes are not allowed"); + this.text = content; + } + toString() { + if (this.type.spec.toDebugString) + return this.type.spec.toDebugString(this); + return wrapMarks(this.marks, JSON.stringify(this.text)); + } + get textContent() { + return this.text; + } + textBetween(from3, to) { + return this.text.slice(from3, to); + } + get nodeSize() { + return this.text.length; + } + mark(marks) { + return marks == this.marks ? this : new _TextNode(this.type, this.attrs, this.text, marks); + } + withText(text2) { + if (text2 == this.text) + return this; + return new _TextNode(this.type, this.attrs, text2, this.marks); + } + cut(from3 = 0, to = this.text.length) { + if (from3 == 0 && to == this.text.length) + return this; + return this.withText(this.text.slice(from3, to)); + } + eq(other) { + return this.sameMarkup(other) && this.text == other.text; + } + toJSON() { + let base2 = super.toJSON(); + base2.text = this.text; + return base2; + } +}; +function wrapMarks(marks, str) { + for (let i = marks.length - 1; i >= 0; i--) + str = marks[i].type.name + "(" + str + ")"; + return str; +} +var ContentMatch = class _ContentMatch2 { + /** + @internal + */ + constructor(validEnd) { + this.validEnd = validEnd; + this.next = []; + this.wrapCache = []; + } + /** + @internal + */ + static parse(string, nodeTypes) { + let stream = new TokenStream(string, nodeTypes); + if (stream.next == null) + return _ContentMatch2.empty; + let expr = parseExpr(stream); + if (stream.next) + stream.err("Unexpected trailing text"); + let match2 = dfa(nfa(expr)); + checkForDeadEnds(match2, stream); + return match2; + } + /** + Match a node type, returning a match after that node if + successful. + */ + matchType(type) { + for (let i = 0; i < this.next.length; i++) + if (this.next[i].type == type) + return this.next[i].next; + return null; + } + /** + Try to match a fragment. Returns the resulting match when + successful. + */ + matchFragment(frag, start = 0, end = frag.childCount) { + let cur = this; + for (let i = start; cur && i < end; i++) + cur = cur.matchType(frag.child(i).type); + return cur; + } + /** + @internal + */ + get inlineContent() { + return this.next.length != 0 && this.next[0].type.isInline; + } + /** + Get the first matching node type at this match position that can + be generated. + */ + get defaultType() { + for (let i = 0; i < this.next.length; i++) { + let { type } = this.next[i]; + if (!(type.isText || type.hasRequiredAttrs())) + return type; + } + return null; + } + /** + @internal + */ + compatible(other) { + for (let i = 0; i < this.next.length; i++) + for (let j2 = 0; j2 < other.next.length; j2++) + if (this.next[i].type == other.next[j2].type) + return true; + return false; + } + /** + Try to match the given fragment, and if that fails, see if it can + be made to match by inserting nodes in front of it. When + successful, return a fragment of inserted nodes (which may be + empty if nothing had to be inserted). When `toEnd` is true, only + return a fragment if the resulting match goes to the end of the + content expression. + */ + fillBefore(after, toEnd = false, startIndex = 0) { + let seen = [this]; + function search(match2, types) { + let finished = match2.matchFragment(after, startIndex); + if (finished && (!toEnd || finished.validEnd)) + return Fragment.from(types.map((tp) => tp.createAndFill())); + for (let i = 0; i < match2.next.length; i++) { + let { type, next: next2 } = match2.next[i]; + if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next2) == -1) { + seen.push(next2); + let found3 = search(next2, types.concat(type)); + if (found3) + return found3; + } + } + return null; + } + return search(this, []); + } + /** + Find a set of wrapping node types that would allow a node of the + given type to appear at this position. The result may be empty + (when it fits directly) and will be null when no such wrapping + exists. + */ + findWrapping(target) { + for (let i = 0; i < this.wrapCache.length; i += 2) + if (this.wrapCache[i] == target) + return this.wrapCache[i + 1]; + let computed = this.computeWrapping(target); + this.wrapCache.push(target, computed); + return computed; + } + /** + @internal + */ + computeWrapping(target) { + let seen = /* @__PURE__ */ Object.create(null), active = [{ match: this, type: null, via: null }]; + while (active.length) { + let current = active.shift(), match2 = current.match; + if (match2.matchType(target)) { + let result = []; + for (let obj = current; obj.type; obj = obj.via) + result.push(obj.type); + return result.reverse(); + } + for (let i = 0; i < match2.next.length; i++) { + let { type, next: next2 } = match2.next[i]; + if (!type.isLeaf && !type.hasRequiredAttrs() && !(type.name in seen) && (!current.type || next2.validEnd)) { + active.push({ match: type.contentMatch, type, via: current }); + seen[type.name] = true; + } + } + } + return null; + } + /** + The number of outgoing edges this node has in the finite + automaton that describes the content expression. + */ + get edgeCount() { + return this.next.length; + } + /** + Get the _n_​th outgoing edge from this node in the finite + automaton that describes the content expression. + */ + edge(n) { + if (n >= this.next.length) + throw new RangeError(`There's no ${n}th edge in this content match`); + return this.next[n]; + } + /** + @internal + */ + toString() { + let seen = []; + function scan(m2) { + seen.push(m2); + for (let i = 0; i < m2.next.length; i++) + if (seen.indexOf(m2.next[i].next) == -1) + scan(m2.next[i].next); + } + scan(this); + return seen.map((m2, i) => { + let out = i + (m2.validEnd ? "*" : " ") + " "; + for (let i2 = 0; i2 < m2.next.length; i2++) + out += (i2 ? ", " : "") + m2.next[i2].type.name + "->" + seen.indexOf(m2.next[i2].next); + return out; + }).join("\n"); + } +}; +ContentMatch.empty = new ContentMatch(true); +var TokenStream = class { + constructor(string, nodeTypes) { + this.string = string; + this.nodeTypes = nodeTypes; + this.inline = null; + this.pos = 0; + this.tokens = string.split(/\s*(?=\b|\W|$)/); + if (this.tokens[this.tokens.length - 1] == "") + this.tokens.pop(); + if (this.tokens[0] == "") + this.tokens.shift(); + } + get next() { + return this.tokens[this.pos]; + } + eat(tok) { + return this.next == tok && (this.pos++ || true); + } + err(str) { + throw new SyntaxError(str + " (in content expression '" + this.string + "')"); + } +}; +function parseExpr(stream) { + let exprs = []; + do { + exprs.push(parseExprSeq(stream)); + } while (stream.eat("|")); + return exprs.length == 1 ? exprs[0] : { type: "choice", exprs }; +} +function parseExprSeq(stream) { + let exprs = []; + do { + exprs.push(parseExprSubscript(stream)); + } while (stream.next && stream.next != ")" && stream.next != "|"); + return exprs.length == 1 ? exprs[0] : { type: "seq", exprs }; +} +function parseExprSubscript(stream) { + let expr = parseExprAtom(stream); + for (; ; ) { + if (stream.eat("+")) + expr = { type: "plus", expr }; + else if (stream.eat("*")) + expr = { type: "star", expr }; + else if (stream.eat("?")) + expr = { type: "opt", expr }; + else if (stream.eat("{")) + expr = parseExprRange(stream, expr); + else + break; + } + return expr; +} +function parseNum(stream) { + if (/\D/.test(stream.next)) + stream.err("Expected number, got '" + stream.next + "'"); + let result = Number(stream.next); + stream.pos++; + return result; +} +function parseExprRange(stream, expr) { + let min2 = parseNum(stream), max2 = min2; + if (stream.eat(",")) { + if (stream.next != "}") + max2 = parseNum(stream); + else + max2 = -1; + } + if (!stream.eat("}")) + stream.err("Unclosed braced range"); + return { type: "range", min: min2, max: max2, expr }; +} +function resolveName(stream, name) { + let types = stream.nodeTypes, type = types[name]; + if (type) + return [type]; + let result = []; + for (let typeName in types) { + let type2 = types[typeName]; + if (type2.isInGroup(name)) + result.push(type2); + } + if (result.length == 0) + stream.err("No node type or group '" + name + "' found"); + return result; +} +function parseExprAtom(stream) { + if (stream.eat("(")) { + let expr = parseExpr(stream); + if (!stream.eat(")")) + stream.err("Missing closing paren"); + return expr; + } else if (!/\W/.test(stream.next)) { + let exprs = resolveName(stream, stream.next).map((type) => { + if (stream.inline == null) + stream.inline = type.isInline; + else if (stream.inline != type.isInline) + stream.err("Mixing inline and block content"); + return { type: "name", value: type }; + }); + stream.pos++; + return exprs.length == 1 ? exprs[0] : { type: "choice", exprs }; + } else { + stream.err("Unexpected token '" + stream.next + "'"); + } +} +function nfa(expr) { + let nfa3 = [[]]; + connect(compile(expr, 0), node()); + return nfa3; + function node() { + return nfa3.push([]) - 1; + } + function edge(from3, to, term) { + let edge2 = { term, to }; + nfa3[from3].push(edge2); + return edge2; + } + function connect(edges, to) { + edges.forEach((edge2) => edge2.to = to); + } + function compile(expr2, from3) { + if (expr2.type == "choice") { + return expr2.exprs.reduce((out, expr3) => out.concat(compile(expr3, from3)), []); + } else if (expr2.type == "seq") { + for (let i = 0; ; i++) { + let next2 = compile(expr2.exprs[i], from3); + if (i == expr2.exprs.length - 1) + return next2; + connect(next2, from3 = node()); + } + } else if (expr2.type == "star") { + let loop = node(); + edge(from3, loop); + connect(compile(expr2.expr, loop), loop); + return [edge(loop)]; + } else if (expr2.type == "plus") { + let loop = node(); + connect(compile(expr2.expr, from3), loop); + connect(compile(expr2.expr, loop), loop); + return [edge(loop)]; + } else if (expr2.type == "opt") { + return [edge(from3)].concat(compile(expr2.expr, from3)); + } else if (expr2.type == "range") { + let cur = from3; + for (let i = 0; i < expr2.min; i++) { + let next2 = node(); + connect(compile(expr2.expr, cur), next2); + cur = next2; + } + if (expr2.max == -1) { + connect(compile(expr2.expr, cur), cur); + } else { + for (let i = expr2.min; i < expr2.max; i++) { + let next2 = node(); + edge(cur, next2); + connect(compile(expr2.expr, cur), next2); + cur = next2; + } + } + return [edge(cur)]; + } else if (expr2.type == "name") { + return [edge(from3, void 0, expr2.value)]; + } else { + throw new Error("Unknown expr type"); + } + } +} +function cmp(a, b2) { + return b2 - a; +} +function nullFrom(nfa3, node) { + let result = []; + scan(node); + return result.sort(cmp); + function scan(node2) { + let edges = nfa3[node2]; + if (edges.length == 1 && !edges[0].term) + return scan(edges[0].to); + result.push(node2); + for (let i = 0; i < edges.length; i++) { + let { term, to } = edges[i]; + if (!term && result.indexOf(to) == -1) + scan(to); + } + } +} +function dfa(nfa3) { + let labeled = /* @__PURE__ */ Object.create(null); + return explore(nullFrom(nfa3, 0)); + function explore(states) { + let out = []; + states.forEach((node) => { + nfa3[node].forEach(({ term, to }) => { + if (!term) + return; + let set; + for (let i = 0; i < out.length; i++) + if (out[i][0] == term) + set = out[i][1]; + nullFrom(nfa3, to).forEach((node2) => { + if (!set) + out.push([term, set = []]); + if (set.indexOf(node2) == -1) + set.push(node2); + }); + }); + }); + let state = labeled[states.join(",")] = new ContentMatch(states.indexOf(nfa3.length - 1) > -1); + for (let i = 0; i < out.length; i++) { + let states2 = out[i][1].sort(cmp); + state.next.push({ type: out[i][0], next: labeled[states2.join(",")] || explore(states2) }); + } + return state; + } +} +function checkForDeadEnds(match2, stream) { + for (let i = 0, work = [match2]; i < work.length; i++) { + let state = work[i], dead = !state.validEnd, nodes = []; + for (let j2 = 0; j2 < state.next.length; j2++) { + let { type, next: next2 } = state.next[j2]; + nodes.push(type.name); + if (dead && !(type.isText || type.hasRequiredAttrs())) + dead = false; + if (work.indexOf(next2) == -1) + work.push(next2); + } + if (dead) + stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)"); + } +} +function defaultAttrs(attrs) { + let defaults2 = /* @__PURE__ */ Object.create(null); + for (let attrName in attrs) { + let attr = attrs[attrName]; + if (!attr.hasDefault) + return null; + defaults2[attrName] = attr.default; + } + return defaults2; +} +function computeAttrs(attrs, value) { + let built = /* @__PURE__ */ Object.create(null); + for (let name in attrs) { + let given = value && value[name]; + if (given === void 0) { + let attr = attrs[name]; + if (attr.hasDefault) + given = attr.default; + else + throw new RangeError("No value supplied for attribute " + name); + } + built[name] = given; + } + return built; +} +function checkAttrs(attrs, values, type, name) { + for (let name2 in values) + if (!(name2 in attrs)) + throw new RangeError(`Unsupported attribute ${name2} for ${type} of type ${name2}`); + for (let name2 in attrs) { + let attr = attrs[name2]; + if (attr.validate) + attr.validate(values[name2]); + } +} +function initAttrs(typeName, attrs) { + let result = /* @__PURE__ */ Object.create(null); + if (attrs) + for (let name in attrs) + result[name] = new Attribute(typeName, name, attrs[name]); + return result; +} +var NodeType = class _NodeType { + /** + @internal + */ + constructor(name, schema, spec) { + this.name = name; + this.schema = schema; + this.spec = spec; + this.markSet = null; + this.groups = spec.group ? spec.group.split(" ") : []; + this.attrs = initAttrs(name, spec.attrs); + this.defaultAttrs = defaultAttrs(this.attrs); + this.contentMatch = null; + this.inlineContent = null; + this.isBlock = !(spec.inline || name == "text"); + this.isText = name == "text"; + } + /** + True if this is an inline type. + */ + get isInline() { + return !this.isBlock; + } + /** + True if this is a textblock type, a block that contains inline + content. + */ + get isTextblock() { + return this.isBlock && this.inlineContent; + } + /** + True for node types that allow no content. + */ + get isLeaf() { + return this.contentMatch == ContentMatch.empty; + } + /** + True when this node is an atom, i.e. when it does not have + directly editable content. + */ + get isAtom() { + return this.isLeaf || !!this.spec.atom; + } + /** + Return true when this node type is part of the given + [group](https://prosemirror.net/docs/ref/#model.NodeSpec.group). + */ + isInGroup(group) { + return this.groups.indexOf(group) > -1; + } + /** + The node type's [whitespace](https://prosemirror.net/docs/ref/#model.NodeSpec.whitespace) option. + */ + get whitespace() { + return this.spec.whitespace || (this.spec.code ? "pre" : "normal"); + } + /** + Tells you whether this node type has any required attributes. + */ + hasRequiredAttrs() { + for (let n in this.attrs) + if (this.attrs[n].isRequired) + return true; + return false; + } + /** + Indicates whether this node allows some of the same content as + the given node type. + */ + compatibleContent(other) { + return this == other || this.contentMatch.compatible(other.contentMatch); + } + /** + @internal + */ + computeAttrs(attrs) { + if (!attrs && this.defaultAttrs) + return this.defaultAttrs; + else + return computeAttrs(this.attrs, attrs); + } + /** + Create a `Node` of this type. The given attributes are + checked and defaulted (you can pass `null` to use the type's + defaults entirely, if no required attributes exist). `content` + may be a `Fragment`, a node, an array of nodes, or + `null`. Similarly `marks` may be `null` to default to the empty + set of marks. + */ + create(attrs = null, content, marks) { + if (this.isText) + throw new Error("NodeType.create can't construct text nodes"); + return new Node(this, this.computeAttrs(attrs), Fragment.from(content), Mark.setFrom(marks)); + } + /** + Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but check the given content + against the node type's content restrictions, and throw an error + if it doesn't match. + */ + createChecked(attrs = null, content, marks) { + content = Fragment.from(content); + this.checkContent(content); + return new Node(this, this.computeAttrs(attrs), content, Mark.setFrom(marks)); + } + /** + Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but see if it is + necessary to add nodes to the start or end of the given fragment + to make it fit the node. If no fitting wrapping can be found, + return null. Note that, due to the fact that required nodes can + always be created, this will always succeed if you pass null or + `Fragment.empty` as content. + */ + createAndFill(attrs = null, content, marks) { + attrs = this.computeAttrs(attrs); + content = Fragment.from(content); + if (content.size) { + let before = this.contentMatch.fillBefore(content); + if (!before) + return null; + content = before.append(content); + } + let matched = this.contentMatch.matchFragment(content); + let after = matched && matched.fillBefore(Fragment.empty, true); + if (!after) + return null; + return new Node(this, attrs, content.append(after), Mark.setFrom(marks)); + } + /** + Returns true if the given fragment is valid content for this node + type. + */ + validContent(content) { + let result = this.contentMatch.matchFragment(content); + if (!result || !result.validEnd) + return false; + for (let i = 0; i < content.childCount; i++) + if (!this.allowsMarks(content.child(i).marks)) + return false; + return true; + } + /** + Throws a RangeError if the given fragment is not valid content for this + node type. + @internal + */ + checkContent(content) { + if (!this.validContent(content)) + throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`); + } + /** + @internal + */ + checkAttrs(attrs) { + checkAttrs(this.attrs, attrs, "node", this.name); + } + /** + Check whether the given mark type is allowed in this node. + */ + allowsMarkType(markType) { + return this.markSet == null || this.markSet.indexOf(markType) > -1; + } + /** + Test whether the given set of marks are allowed in this node. + */ + allowsMarks(marks) { + if (this.markSet == null) + return true; + for (let i = 0; i < marks.length; i++) + if (!this.allowsMarkType(marks[i].type)) + return false; + return true; + } + /** + Removes the marks that are not allowed in this node from the given set. + */ + allowedMarks(marks) { + if (this.markSet == null) + return marks; + let copy3; + for (let i = 0; i < marks.length; i++) { + if (!this.allowsMarkType(marks[i].type)) { + if (!copy3) + copy3 = marks.slice(0, i); + } else if (copy3) { + copy3.push(marks[i]); + } + } + return !copy3 ? marks : copy3.length ? copy3 : Mark.none; + } + /** + @internal + */ + static compile(nodes, schema) { + let result = /* @__PURE__ */ Object.create(null); + nodes.forEach((name, spec) => result[name] = new _NodeType(name, schema, spec)); + let topType = schema.spec.topNode || "doc"; + if (!result[topType]) + throw new RangeError("Schema is missing its top node type ('" + topType + "')"); + if (!result.text) + throw new RangeError("Every schema needs a 'text' type"); + for (let _2 in result.text.attrs) + throw new RangeError("The text node type should not have attributes"); + return result; + } +}; +function validateType(typeName, attrName, type) { + let types = type.split("|"); + return (value) => { + let name = value === null ? "null" : typeof value; + if (types.indexOf(name) < 0) + throw new RangeError(`Expected value of type ${types} for attribute ${attrName} on type ${typeName}, got ${name}`); + }; +} +var Attribute = class { + constructor(typeName, attrName, options) { + this.hasDefault = Object.prototype.hasOwnProperty.call(options, "default"); + this.default = options.default; + this.validate = typeof options.validate == "string" ? validateType(typeName, attrName, options.validate) : options.validate; + } + get isRequired() { + return !this.hasDefault; + } +}; +var MarkType = class _MarkType { + /** + @internal + */ + constructor(name, rank, schema, spec) { + this.name = name; + this.rank = rank; + this.schema = schema; + this.spec = spec; + this.attrs = initAttrs(name, spec.attrs); + this.excluded = null; + let defaults2 = defaultAttrs(this.attrs); + this.instance = defaults2 ? new Mark(this, defaults2) : null; + } + /** + Create a mark of this type. `attrs` may be `null` or an object + containing only some of the mark's attributes. The others, if + they have defaults, will be added. + */ + create(attrs = null) { + if (!attrs && this.instance) + return this.instance; + return new Mark(this, computeAttrs(this.attrs, attrs)); + } + /** + @internal + */ + static compile(marks, schema) { + let result = /* @__PURE__ */ Object.create(null), rank = 0; + marks.forEach((name, spec) => result[name] = new _MarkType(name, rank++, schema, spec)); + return result; + } + /** + When there is a mark of this type in the given set, a new set + without it is returned. Otherwise, the input set is returned. + */ + removeFromSet(set) { + for (var i = 0; i < set.length; i++) + if (set[i].type == this) { + set = set.slice(0, i).concat(set.slice(i + 1)); + i--; + } + return set; + } + /** + Tests whether there is a mark of this type in the given set. + */ + isInSet(set) { + for (let i = 0; i < set.length; i++) + if (set[i].type == this) + return set[i]; + } + /** + @internal + */ + checkAttrs(attrs) { + checkAttrs(this.attrs, attrs, "mark", this.name); + } + /** + Queries whether a given mark type is + [excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one. + */ + excludes(other) { + return this.excluded.indexOf(other) > -1; + } +}; +var Schema = class { + /** + Construct a schema from a schema [specification](https://prosemirror.net/docs/ref/#model.SchemaSpec). + */ + constructor(spec) { + this.linebreakReplacement = null; + this.cached = /* @__PURE__ */ Object.create(null); + let instanceSpec = this.spec = {}; + for (let prop in spec) + instanceSpec[prop] = spec[prop]; + instanceSpec.nodes = dist_default.from(spec.nodes), instanceSpec.marks = dist_default.from(spec.marks || {}), this.nodes = NodeType.compile(this.spec.nodes, this); + this.marks = MarkType.compile(this.spec.marks, this); + let contentExprCache = /* @__PURE__ */ Object.create(null); + for (let prop in this.nodes) { + if (prop in this.marks) + throw new RangeError(prop + " can not be both a node and a mark"); + let type = this.nodes[prop], contentExpr = type.spec.content || "", markExpr = type.spec.marks; + type.contentMatch = contentExprCache[contentExpr] || (contentExprCache[contentExpr] = ContentMatch.parse(contentExpr, this.nodes)); + type.inlineContent = type.contentMatch.inlineContent; + if (type.spec.linebreakReplacement) { + if (this.linebreakReplacement) + throw new RangeError("Multiple linebreak nodes defined"); + if (!type.isInline || !type.isLeaf) + throw new RangeError("Linebreak replacement nodes must be inline leaf nodes"); + this.linebreakReplacement = type; + } + type.markSet = markExpr == "_" ? null : markExpr ? gatherMarks(this, markExpr.split(" ")) : markExpr == "" || !type.inlineContent ? [] : null; + } + for (let prop in this.marks) { + let type = this.marks[prop], excl = type.spec.excludes; + type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" ")); + } + this.nodeFromJSON = (json) => Node.fromJSON(this, json); + this.markFromJSON = (json) => Mark.fromJSON(this, json); + this.topNodeType = this.nodes[this.spec.topNode || "doc"]; + this.cached.wrappings = /* @__PURE__ */ Object.create(null); + } + /** + Create a node in this schema. The `type` may be a string or a + `NodeType` instance. Attributes will be extended with defaults, + `content` may be a `Fragment`, `null`, a `Node`, or an array of + nodes. + */ + node(type, attrs = null, content, marks) { + if (typeof type == "string") + type = this.nodeType(type); + else if (!(type instanceof NodeType)) + throw new RangeError("Invalid node type: " + type); + else if (type.schema != this) + throw new RangeError("Node type from different schema used (" + type.name + ")"); + return type.createChecked(attrs, content, marks); + } + /** + Create a text node in the schema. Empty text nodes are not + allowed. + */ + text(text2, marks) { + let type = this.nodes.text; + return new TextNode(type, type.defaultAttrs, text2, Mark.setFrom(marks)); + } + /** + Create a mark with the given type and attributes. + */ + mark(type, attrs) { + if (typeof type == "string") + type = this.marks[type]; + return type.create(attrs); + } + /** + @internal + */ + nodeType(name) { + let found3 = this.nodes[name]; + if (!found3) + throw new RangeError("Unknown node type: " + name); + return found3; + } +}; +function gatherMarks(schema, marks) { + let found3 = []; + for (let i = 0; i < marks.length; i++) { + let name = marks[i], mark = schema.marks[name], ok = mark; + if (mark) { + found3.push(mark); + } else { + for (let prop in schema.marks) { + let mark2 = schema.marks[prop]; + if (name == "_" || mark2.spec.group && mark2.spec.group.split(" ").indexOf(name) > -1) + found3.push(ok = mark2); + } + } + if (!ok) + throw new SyntaxError("Unknown mark type: '" + marks[i] + "'"); + } + return found3; +} +function isTagRule(rule) { + return rule.tag != null; +} +function isStyleRule(rule) { + return rule.style != null; +} +var DOMParser2 = class _DOMParser { + /** + Create a parser that targets the given schema, using the given + parsing rules. + */ + constructor(schema, rules3) { + this.schema = schema; + this.rules = rules3; + this.tags = []; + this.styles = []; + let matchedStyles = this.matchedStyles = []; + rules3.forEach((rule) => { + if (isTagRule(rule)) { + this.tags.push(rule); + } else if (isStyleRule(rule)) { + let prop = /[^=]*/.exec(rule.style)[0]; + if (matchedStyles.indexOf(prop) < 0) + matchedStyles.push(prop); + this.styles.push(rule); + } + }); + this.normalizeLists = !this.tags.some((r) => { + if (!/^(ul|ol)\b/.test(r.tag) || !r.node) + return false; + let node = schema.nodes[r.node]; + return node.contentMatch.matchType(node); + }); + } + /** + Parse a document from the content of a DOM node. + */ + parse(dom, options = {}) { + let context = new ParseContext(this, options, false); + context.addAll(dom, Mark.none, options.from, options.to); + return context.finish(); + } + /** + Parses the content of the given DOM node, like + [`parse`](https://prosemirror.net/docs/ref/#model.DOMParser.parse), and takes the same set of + options. But unlike that method, which produces a whole node, + this one returns a slice that is open at the sides, meaning that + the schema constraints aren't applied to the start of nodes to + the left of the input and the end of nodes at the end. + */ + parseSlice(dom, options = {}) { + let context = new ParseContext(this, options, true); + context.addAll(dom, Mark.none, options.from, options.to); + return Slice.maxOpen(context.finish()); + } + /** + @internal + */ + matchTag(dom, context, after) { + for (let i = after ? this.tags.indexOf(after) + 1 : 0; i < this.tags.length; i++) { + let rule = this.tags[i]; + if (matches(dom, rule.tag) && (rule.namespace === void 0 || dom.namespaceURI == rule.namespace) && (!rule.context || context.matchesContext(rule.context))) { + if (rule.getAttrs) { + let result = rule.getAttrs(dom); + if (result === false) + continue; + rule.attrs = result || void 0; + } + return rule; + } + } + } + /** + @internal + */ + matchStyle(prop, value, context, after) { + for (let i = after ? this.styles.indexOf(after) + 1 : 0; i < this.styles.length; i++) { + let rule = this.styles[i], style2 = rule.style; + if (style2.indexOf(prop) != 0 || rule.context && !context.matchesContext(rule.context) || // Test that the style string either precisely matches the prop, + // or has an '=' sign after the prop, followed by the given + // value. + style2.length > prop.length && (style2.charCodeAt(prop.length) != 61 || style2.slice(prop.length + 1) != value)) + continue; + if (rule.getAttrs) { + let result = rule.getAttrs(value); + if (result === false) + continue; + rule.attrs = result || void 0; + } + return rule; + } + } + /** + @internal + */ + static schemaRules(schema) { + let result = []; + function insert(rule) { + let priority = rule.priority == null ? 50 : rule.priority, i = 0; + for (; i < result.length; i++) { + let next2 = result[i], nextPriority = next2.priority == null ? 50 : next2.priority; + if (nextPriority < priority) + break; + } + result.splice(i, 0, rule); + } + for (let name in schema.marks) { + let rules3 = schema.marks[name].spec.parseDOM; + if (rules3) + rules3.forEach((rule) => { + insert(rule = copy(rule)); + if (!(rule.mark || rule.ignore || rule.clearMark)) + rule.mark = name; + }); + } + for (let name in schema.nodes) { + let rules3 = schema.nodes[name].spec.parseDOM; + if (rules3) + rules3.forEach((rule) => { + insert(rule = copy(rule)); + if (!(rule.node || rule.ignore || rule.mark)) + rule.node = name; + }); + } + return result; + } + /** + Construct a DOM parser using the parsing rules listed in a + schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by + [priority](https://prosemirror.net/docs/ref/#model.GenericParseRule.priority). + */ + static fromSchema(schema) { + return schema.cached.domParser || (schema.cached.domParser = new _DOMParser(schema, _DOMParser.schemaRules(schema))); + } +}; +var blockTags = { + address: true, + article: true, + aside: true, + blockquote: true, + canvas: true, + dd: true, + div: true, + dl: true, + fieldset: true, + figcaption: true, + figure: true, + footer: true, + form: true, + h1: true, + h2: true, + h3: true, + h4: true, + h5: true, + h6: true, + header: true, + hgroup: true, + hr: true, + li: true, + noscript: true, + ol: true, + output: true, + p: true, + pre: true, + section: true, + table: true, + tfoot: true, + ul: true +}; +var ignoreTags = { + head: true, + noscript: true, + object: true, + script: true, + style: true, + title: true +}; +var listTags = { ol: true, ul: true }; +var OPT_PRESERVE_WS = 1; +var OPT_PRESERVE_WS_FULL = 2; +var OPT_OPEN_LEFT = 4; +function wsOptionsFor(type, preserveWhitespace, base2) { + if (preserveWhitespace != null) + return (preserveWhitespace ? OPT_PRESERVE_WS : 0) | (preserveWhitespace === "full" ? OPT_PRESERVE_WS_FULL : 0); + return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base2 & ~OPT_OPEN_LEFT; +} +var NodeContext = class { + constructor(type, attrs, marks, solid, match2, options) { + this.type = type; + this.attrs = attrs; + this.marks = marks; + this.solid = solid; + this.options = options; + this.content = []; + this.activeMarks = Mark.none; + this.match = match2 || (options & OPT_OPEN_LEFT ? null : type.contentMatch); + } + findWrapping(node) { + if (!this.match) { + if (!this.type) + return []; + let fill = this.type.contentMatch.fillBefore(Fragment.from(node)); + if (fill) { + this.match = this.type.contentMatch.matchFragment(fill); + } else { + let start = this.type.contentMatch, wrap2; + if (wrap2 = start.findWrapping(node.type)) { + this.match = start; + return wrap2; + } else { + return null; + } + } + } + return this.match.findWrapping(node.type); + } + finish(openEnd) { + if (!(this.options & OPT_PRESERVE_WS)) { + let last2 = this.content[this.content.length - 1], m2; + if (last2 && last2.isText && (m2 = /[ \t\r\n\u000c]+$/.exec(last2.text))) { + let text2 = last2; + if (last2.text.length == m2[0].length) + this.content.pop(); + else + this.content[this.content.length - 1] = text2.withText(text2.text.slice(0, text2.text.length - m2[0].length)); + } + } + let content = Fragment.from(this.content); + if (!openEnd && this.match) + content = content.append(this.match.fillBefore(Fragment.empty, true)); + return this.type ? this.type.create(this.attrs, content, this.marks) : content; + } + inlineContext(node) { + if (this.type) + return this.type.inlineContent; + if (this.content.length) + return this.content[0].isInline; + return node.parentNode && !blockTags.hasOwnProperty(node.parentNode.nodeName.toLowerCase()); + } +}; +var ParseContext = class { + constructor(parser, options, isOpen) { + this.parser = parser; + this.options = options; + this.isOpen = isOpen; + this.open = 0; + this.localPreserveWS = false; + let topNode = options.topNode, topContext; + let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0); + if (topNode) + topContext = new NodeContext(topNode.type, topNode.attrs, Mark.none, true, options.topMatch || topNode.type.contentMatch, topOptions); + else if (isOpen) + topContext = new NodeContext(null, null, Mark.none, true, null, topOptions); + else + topContext = new NodeContext(parser.schema.topNodeType, null, Mark.none, true, null, topOptions); + this.nodes = [topContext]; + this.find = options.findPositions; + this.needsBlock = false; + } + get top() { + return this.nodes[this.open]; + } + // Add a DOM node to the content. Text is inserted as text node, + // otherwise, the node is passed to `addElement` or, if it has a + // `style` attribute, `addElementWithStyles`. + addDOM(dom, marks) { + if (dom.nodeType == 3) + this.addTextNode(dom, marks); + else if (dom.nodeType == 1) + this.addElement(dom, marks); + } + addTextNode(dom, marks) { + let value = dom.nodeValue; + let top = this.top, preserveWS = top.options & OPT_PRESERVE_WS_FULL ? "full" : this.localPreserveWS || (top.options & OPT_PRESERVE_WS) > 0; + let { schema } = this.parser; + if (preserveWS === "full" || top.inlineContext(dom) || /[^ \t\r\n\u000c]/.test(value)) { + if (!preserveWS) { + value = value.replace(/[ \t\r\n\u000c]+/g, " "); + if (/^[ \t\r\n\u000c]/.test(value) && this.open == this.nodes.length - 1) { + let nodeBefore = top.content[top.content.length - 1]; + let domNodeBefore = dom.previousSibling; + if (!nodeBefore || domNodeBefore && domNodeBefore.nodeName == "BR" || nodeBefore.isText && /[ \t\r\n\u000c]$/.test(nodeBefore.text)) + value = value.slice(1); + } + } else if (preserveWS === "full") { + value = value.replace(/\r\n?/g, "\n"); + } else if (schema.linebreakReplacement && /[\r\n]/.test(value) && this.top.findWrapping(schema.linebreakReplacement.create())) { + let lines = value.split(/\r?\n|\r/); + for (let i = 0; i < lines.length; i++) { + if (i) + this.insertNode(schema.linebreakReplacement.create(), marks, true); + if (lines[i]) + this.insertNode(schema.text(lines[i]), marks, !/\S/.test(lines[i])); + } + value = ""; + } else { + value = value.replace(/\r?\n|\r/g, " "); + } + if (value) + this.insertNode(schema.text(value), marks, !/\S/.test(value)); + this.findInText(dom); + } else { + this.findInside(dom); + } + } + // Try to find a handler for the given tag and use that to parse. If + // none is found, the element's content nodes are added directly. + addElement(dom, marks, matchAfter) { + let outerWS = this.localPreserveWS, top = this.top; + if (dom.tagName == "PRE" || /pre/.test(dom.style && dom.style.whiteSpace)) + this.localPreserveWS = true; + let name = dom.nodeName.toLowerCase(), ruleID; + if (listTags.hasOwnProperty(name) && this.parser.normalizeLists) + normalizeList(dom); + let rule = this.options.ruleFromNode && this.options.ruleFromNode(dom) || (ruleID = this.parser.matchTag(dom, this, matchAfter)); + out: if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) { + this.findInside(dom); + this.ignoreFallback(dom, marks); + } else if (!rule || rule.skip || rule.closeParent) { + if (rule && rule.closeParent) + this.open = Math.max(0, this.open - 1); + else if (rule && rule.skip.nodeType) + dom = rule.skip; + let sync, oldNeedsBlock = this.needsBlock; + if (blockTags.hasOwnProperty(name)) { + if (top.content.length && top.content[0].isInline && this.open) { + this.open--; + top = this.top; + } + sync = true; + if (!top.type) + this.needsBlock = true; + } else if (!dom.firstChild) { + this.leafFallback(dom, marks); + break out; + } + let innerMarks = rule && rule.skip ? marks : this.readStyles(dom, marks); + if (innerMarks) + this.addAll(dom, innerMarks); + if (sync) + this.sync(top); + this.needsBlock = oldNeedsBlock; + } else { + let innerMarks = this.readStyles(dom, marks); + if (innerMarks) + this.addElementByRule(dom, rule, innerMarks, rule.consuming === false ? ruleID : void 0); + } + this.localPreserveWS = outerWS; + } + // Called for leaf DOM nodes that would otherwise be ignored + leafFallback(dom, marks) { + if (dom.nodeName == "BR" && this.top.type && this.top.type.inlineContent) + this.addTextNode(dom.ownerDocument.createTextNode("\n"), marks); + } + // Called for ignored nodes + ignoreFallback(dom, marks) { + if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent)) + this.findPlace(this.parser.schema.text("-"), marks, true); + } + // Run any style parser associated with the node's styles. Either + // return an updated array of marks, or null to indicate some of the + // styles had a rule with `ignore` set. + readStyles(dom, marks) { + let styles = dom.style; + if (styles && styles.length) + for (let i = 0; i < this.parser.matchedStyles.length; i++) { + let name = this.parser.matchedStyles[i], value = styles.getPropertyValue(name); + if (value) + for (let after = void 0; ; ) { + let rule = this.parser.matchStyle(name, value, this, after); + if (!rule) + break; + if (rule.ignore) + return null; + if (rule.clearMark) + marks = marks.filter((m2) => !rule.clearMark(m2)); + else + marks = marks.concat(this.parser.schema.marks[rule.mark].create(rule.attrs)); + if (rule.consuming === false) + after = rule; + else + break; + } + } + return marks; + } + // Look up a handler for the given node. If none are found, return + // false. Otherwise, apply it, use its return value to drive the way + // the node's content is wrapped, and return true. + addElementByRule(dom, rule, marks, continueAfter) { + let sync, nodeType; + if (rule.node) { + nodeType = this.parser.schema.nodes[rule.node]; + if (!nodeType.isLeaf) { + let inner = this.enter(nodeType, rule.attrs || null, marks, rule.preserveWhitespace); + if (inner) { + sync = true; + marks = inner; + } + } else if (!this.insertNode(nodeType.create(rule.attrs), marks, dom.nodeName == "BR")) { + this.leafFallback(dom, marks); + } + } else { + let markType = this.parser.schema.marks[rule.mark]; + marks = marks.concat(markType.create(rule.attrs)); + } + let startIn = this.top; + if (nodeType && nodeType.isLeaf) { + this.findInside(dom); + } else if (continueAfter) { + this.addElement(dom, marks, continueAfter); + } else if (rule.getContent) { + this.findInside(dom); + rule.getContent(dom, this.parser.schema).forEach((node) => this.insertNode(node, marks, false)); + } else { + let contentDOM = dom; + if (typeof rule.contentElement == "string") + contentDOM = dom.querySelector(rule.contentElement); + else if (typeof rule.contentElement == "function") + contentDOM = rule.contentElement(dom); + else if (rule.contentElement) + contentDOM = rule.contentElement; + this.findAround(dom, contentDOM, true); + this.addAll(contentDOM, marks); + this.findAround(dom, contentDOM, false); + } + if (sync && this.sync(startIn)) + this.open--; + } + // Add all child nodes between `startIndex` and `endIndex` (or the + // whole node, if not given). If `sync` is passed, use it to + // synchronize after every block element. + addAll(parent, marks, startIndex, endIndex) { + let index = startIndex || 0; + for (let dom = startIndex ? parent.childNodes[startIndex] : parent.firstChild, end = endIndex == null ? null : parent.childNodes[endIndex]; dom != end; dom = dom.nextSibling, ++index) { + this.findAtPoint(parent, index); + this.addDOM(dom, marks); + } + this.findAtPoint(parent, index); + } + // Try to find a way to fit the given node type into the current + // context. May add intermediate wrappers and/or leave non-solid + // nodes that we're in. + findPlace(node, marks, cautious) { + let route, sync; + for (let depth = this.open, penalty = 0; depth >= 0; depth--) { + let cx = this.nodes[depth]; + let found3 = cx.findWrapping(node); + if (found3 && (!route || route.length > found3.length + penalty)) { + route = found3; + sync = cx; + if (!found3.length) + break; + } + if (cx.solid) { + if (cautious) + break; + penalty += 2; + } + } + if (!route) + return null; + this.sync(sync); + for (let i = 0; i < route.length; i++) + marks = this.enterInner(route[i], null, marks, false); + return marks; + } + // Try to insert the given node, adjusting the context when needed. + insertNode(node, marks, cautious) { + if (node.isInline && this.needsBlock && !this.top.type) { + let block = this.textblockFromContext(); + if (block) + marks = this.enterInner(block, null, marks); + } + let innerMarks = this.findPlace(node, marks, cautious); + if (innerMarks) { + this.closeExtra(); + let top = this.top; + if (top.match) + top.match = top.match.matchType(node.type); + let nodeMarks = Mark.none; + for (let m2 of innerMarks.concat(node.marks)) + if (top.type ? top.type.allowsMarkType(m2.type) : markMayApply(m2.type, node.type)) + nodeMarks = m2.addToSet(nodeMarks); + top.content.push(node.mark(nodeMarks)); + return true; + } + return false; + } + // Try to start a node of the given type, adjusting the context when + // necessary. + enter(type, attrs, marks, preserveWS) { + let innerMarks = this.findPlace(type.create(attrs), marks, false); + if (innerMarks) + innerMarks = this.enterInner(type, attrs, marks, true, preserveWS); + return innerMarks; + } + // Open a node of the given type + enterInner(type, attrs, marks, solid = false, preserveWS) { + this.closeExtra(); + let top = this.top; + top.match = top.match && top.match.matchType(type); + let options = wsOptionsFor(type, preserveWS, top.options); + if (top.options & OPT_OPEN_LEFT && top.content.length == 0) + options |= OPT_OPEN_LEFT; + let applyMarks = Mark.none; + marks = marks.filter((m2) => { + if (top.type ? top.type.allowsMarkType(m2.type) : markMayApply(m2.type, type)) { + applyMarks = m2.addToSet(applyMarks); + return false; + } + return true; + }); + this.nodes.push(new NodeContext(type, attrs, applyMarks, solid, null, options)); + this.open++; + return marks; + } + // Make sure all nodes above this.open are finished and added to + // their parents + closeExtra(openEnd = false) { + let i = this.nodes.length - 1; + if (i > this.open) { + for (; i > this.open; i--) + this.nodes[i - 1].content.push(this.nodes[i].finish(openEnd)); + this.nodes.length = this.open + 1; + } + } + finish() { + this.open = 0; + this.closeExtra(this.isOpen); + return this.nodes[0].finish(!!(this.isOpen || this.options.topOpen)); + } + sync(to) { + for (let i = this.open; i >= 0; i--) { + if (this.nodes[i] == to) { + this.open = i; + return true; + } else if (this.localPreserveWS) { + this.nodes[i].options |= OPT_PRESERVE_WS; + } + } + return false; + } + get currentPos() { + this.closeExtra(); + let pos = 0; + for (let i = this.open; i >= 0; i--) { + let content = this.nodes[i].content; + for (let j2 = content.length - 1; j2 >= 0; j2--) + pos += content[j2].nodeSize; + if (i) + pos++; + } + return pos; + } + findAtPoint(parent, offset) { + if (this.find) + for (let i = 0; i < this.find.length; i++) { + if (this.find[i].node == parent && this.find[i].offset == offset) + this.find[i].pos = this.currentPos; + } + } + findInside(parent) { + if (this.find) + for (let i = 0; i < this.find.length; i++) { + if (this.find[i].pos == null && parent.nodeType == 1 && parent.contains(this.find[i].node)) + this.find[i].pos = this.currentPos; + } + } + findAround(parent, content, before) { + if (parent != content && this.find) + for (let i = 0; i < this.find.length; i++) { + if (this.find[i].pos == null && parent.nodeType == 1 && parent.contains(this.find[i].node)) { + let pos = content.compareDocumentPosition(this.find[i].node); + if (pos & (before ? 2 : 4)) + this.find[i].pos = this.currentPos; + } + } + } + findInText(textNode) { + if (this.find) + for (let i = 0; i < this.find.length; i++) { + if (this.find[i].node == textNode) + this.find[i].pos = this.currentPos - (textNode.nodeValue.length - this.find[i].offset); + } + } + // Determines whether the given context string matches this context. + matchesContext(context) { + if (context.indexOf("|") > -1) + return context.split(/\s*\|\s*/).some(this.matchesContext, this); + let parts = context.split("/"); + let option = this.options.context; + let useRoot = !this.isOpen && (!option || option.parent.type == this.nodes[0].type); + let minDepth = -(option ? option.depth + 1 : 0) + (useRoot ? 0 : 1); + let match2 = (i, depth) => { + for (; i >= 0; i--) { + let part = parts[i]; + if (part == "") { + if (i == parts.length - 1 || i == 0) + continue; + for (; depth >= minDepth; depth--) + if (match2(i - 1, depth)) + return true; + return false; + } else { + let next2 = depth > 0 || depth == 0 && useRoot ? this.nodes[depth].type : option && depth >= minDepth ? option.node(depth - minDepth).type : null; + if (!next2 || next2.name != part && !next2.isInGroup(part)) + return false; + depth--; + } + } + return true; + }; + return match2(parts.length - 1, this.open); + } + textblockFromContext() { + let $context = this.options.context; + if ($context) + for (let d2 = $context.depth; d2 >= 0; d2--) { + let deflt = $context.node(d2).contentMatchAt($context.indexAfter(d2)).defaultType; + if (deflt && deflt.isTextblock && deflt.defaultAttrs) + return deflt; + } + for (let name in this.parser.schema.nodes) { + let type = this.parser.schema.nodes[name]; + if (type.isTextblock && type.defaultAttrs) + return type; + } + } +}; +function normalizeList(dom) { + for (let child = dom.firstChild, prevItem = null; child; child = child.nextSibling) { + let name = child.nodeType == 1 ? child.nodeName.toLowerCase() : null; + if (name && listTags.hasOwnProperty(name) && prevItem) { + prevItem.appendChild(child); + child = prevItem; + } else if (name == "li") { + prevItem = child; + } else if (name) { + prevItem = null; + } + } +} +function matches(dom, selector) { + return (dom.matches || dom.msMatchesSelector || dom.webkitMatchesSelector || dom.mozMatchesSelector).call(dom, selector); +} +function copy(obj) { + let copy3 = {}; + for (let prop in obj) + copy3[prop] = obj[prop]; + return copy3; +} +function markMayApply(markType, nodeType) { + let nodes = nodeType.schema.nodes; + for (let name in nodes) { + let parent = nodes[name]; + if (!parent.allowsMarkType(markType)) + continue; + let seen = [], scan = (match2) => { + seen.push(match2); + for (let i = 0; i < match2.edgeCount; i++) { + let { type, next: next2 } = match2.edge(i); + if (type == nodeType) + return true; + if (seen.indexOf(next2) < 0 && scan(next2)) + return true; + } + }; + if (scan(parent.contentMatch)) + return true; + } +} +var DOMSerializer = class _DOMSerializer { + /** + Create a serializer. `nodes` should map node names to functions + that take a node and return a description of the corresponding + DOM. `marks` does the same for mark names, but also gets an + argument that tells it whether the mark's content is block or + inline content (for typical use, it'll always be inline). A mark + serializer may be `null` to indicate that marks of that type + should not be serialized. + */ + constructor(nodes, marks) { + this.nodes = nodes; + this.marks = marks; + } + /** + Serialize the content of this fragment to a DOM fragment. When + not in the browser, the `document` option, containing a DOM + document, should be passed so that the serializer can create + nodes. + */ + serializeFragment(fragment, options = {}, target) { + if (!target) + target = doc(options).createDocumentFragment(); + let top = target, active = []; + fragment.forEach((node) => { + if (active.length || node.marks.length) { + let keep = 0, rendered = 0; + while (keep < active.length && rendered < node.marks.length) { + let next2 = node.marks[rendered]; + if (!this.marks[next2.type.name]) { + rendered++; + continue; + } + if (!next2.eq(active[keep][0]) || next2.type.spec.spanning === false) + break; + keep++; + rendered++; + } + while (keep < active.length) + top = active.pop()[1]; + while (rendered < node.marks.length) { + let add = node.marks[rendered++]; + let markDOM = this.serializeMark(add, node.isInline, options); + if (markDOM) { + active.push([add, top]); + top.appendChild(markDOM.dom); + top = markDOM.contentDOM || markDOM.dom; + } + } + } + top.appendChild(this.serializeNodeInner(node, options)); + }); + return target; + } + /** + @internal + */ + serializeNodeInner(node, options) { + if (node.isText) + return doc(options).createTextNode(node.text); + let { dom, contentDOM } = renderSpec(doc(options), this.nodes[node.type.name](node), null, node.attrs); + if (contentDOM) { + if (node.isLeaf) + throw new RangeError("Content hole not allowed in a leaf node spec"); + this.serializeFragment(node.content, options, contentDOM); + } + return dom; + } + /** + Serialize this node to a DOM node. This can be useful when you + need to serialize a part of a document, as opposed to the whole + document. To serialize a whole document, use + [`serializeFragment`](https://prosemirror.net/docs/ref/#model.DOMSerializer.serializeFragment) on + its [content](https://prosemirror.net/docs/ref/#model.Node.content). + */ + serializeNode(node, options = {}) { + let dom = this.serializeNodeInner(node, options); + for (let i = node.marks.length - 1; i >= 0; i--) { + let wrap2 = this.serializeMark(node.marks[i], node.isInline, options); + if (wrap2) { + (wrap2.contentDOM || wrap2.dom).appendChild(dom); + dom = wrap2.dom; + } + } + return dom; + } + /** + @internal + */ + serializeMark(mark, inline, options = {}) { + let toDOM = this.marks[mark.type.name]; + return toDOM && renderSpec(doc(options), toDOM(mark, inline), null, mark.attrs); + } + static renderSpec(doc4, structure, xmlNS = null, blockArraysIn) { + if (typeof structure == "string") + return { dom: doc4.createTextNode(structure) }; + return renderSpec(doc4, structure, xmlNS, blockArraysIn); + } + /** + Build a serializer using the [`toDOM`](https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM) + properties in a schema's node and mark specs. + */ + static fromSchema(schema) { + return schema.cached.domSerializer || (schema.cached.domSerializer = new _DOMSerializer(this.nodesFromSchema(schema), this.marksFromSchema(schema))); + } + /** + Gather the serializers in a schema's node specs into an object. + This can be useful as a base to build a custom serializer from. + */ + static nodesFromSchema(schema) { + let result = gatherToDOM(schema.nodes); + if (!result.text) + result.text = (node) => node.text; + return result; + } + /** + Gather the serializers in a schema's mark specs into an object. + */ + static marksFromSchema(schema) { + return gatherToDOM(schema.marks); + } +}; +function gatherToDOM(obj) { + let result = {}; + for (let name in obj) { + let toDOM = obj[name].spec.toDOM; + if (toDOM) + result[name] = toDOM; + } + return result; +} +function doc(options) { + return options.document || window.document; +} +var suspiciousAttributeCache = /* @__PURE__ */ new WeakMap(); +function suspiciousAttributes(attrs) { + let value = suspiciousAttributeCache.get(attrs); + if (value === void 0) + suspiciousAttributeCache.set(attrs, value = suspiciousAttributesInner(attrs)); + return value; +} +function suspiciousAttributesInner(attrs) { + let result = null; + function scan(value) { + if (value && typeof value == "object") { + if (Array.isArray(value)) { + if (typeof value[0] == "string") { + if (!result) + result = []; + result.push(value); + } else { + for (let i = 0; i < value.length; i++) + scan(value[i]); + } + } else { + for (let prop in value) + scan(value[prop]); + } + } + } + scan(attrs); + return result; +} +function renderSpec(doc4, structure, xmlNS, blockArraysIn) { + if (structure.nodeType == 1) + return { dom: structure }; + if (structure.dom && structure.dom.nodeType == 1) + return structure; + let tagName = structure[0], suspicious; + if (typeof tagName != "string") + throw new RangeError("Invalid array passed to renderSpec"); + if (blockArraysIn && (suspicious = suspiciousAttributes(blockArraysIn)) && suspicious.indexOf(structure) > -1) + throw new RangeError("Using an array from an attribute object as a DOM spec. This may be an attempted cross site scripting attack."); + let space = tagName.indexOf(" "); + if (space > 0) { + xmlNS = tagName.slice(0, space); + tagName = tagName.slice(space + 1); + } + let contentDOM; + let dom = xmlNS ? doc4.createElementNS(xmlNS, tagName) : doc4.createElement(tagName); + let attrs = structure[1], start = 1; + if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) { + start = 2; + for (let name in attrs) + if (attrs[name] != null) { + let space2 = name.indexOf(" "); + if (space2 > 0) + dom.setAttributeNS(name.slice(0, space2), name.slice(space2 + 1), attrs[name]); + else if (name == "style" && dom.style) + dom.style.cssText = attrs[name]; + else + dom.setAttribute(name, attrs[name]); + } + } + for (let i = start; i < structure.length; i++) { + let child = structure[i]; + if (child === 0) { + if (i < structure.length - 1 || i > start) + throw new RangeError("Content hole must be the only child of its parent node"); + return { dom, contentDOM: dom }; + } else if (typeof child == "string") { + dom.appendChild(doc4.createTextNode(child)); + } else { + let { dom: inner, contentDOM: innerContent } = renderSpec(doc4, child, xmlNS, blockArraysIn); + dom.appendChild(inner); + if (innerContent) { + if (contentDOM) + throw new RangeError("Multiple content holes"); + contentDOM = innerContent; + } + } + } + return { dom, contentDOM }; +} + +// ../../node_modules/.pnpm/prosemirror-transform@1.12.0/node_modules/prosemirror-transform/dist/index.js +var lower16 = 65535; +var factor16 = Math.pow(2, 16); +function makeRecover(index, offset) { + return index + offset * factor16; +} +function recoverIndex(value) { + return value & lower16; +} +function recoverOffset(value) { + return (value - (value & lower16)) / factor16; +} +var DEL_BEFORE = 1; +var DEL_AFTER = 2; +var DEL_ACROSS = 4; +var DEL_SIDE = 8; +var MapResult = class { + /** + @internal + */ + constructor(pos, delInfo, recover) { + this.pos = pos; + this.delInfo = delInfo; + this.recover = recover; + } + /** + Tells you whether the position was deleted, that is, whether the + step removed the token on the side queried (via the `assoc`) + argument from the document. + */ + get deleted() { + return (this.delInfo & DEL_SIDE) > 0; + } + /** + Tells you whether the token before the mapped position was deleted. + */ + get deletedBefore() { + return (this.delInfo & (DEL_BEFORE | DEL_ACROSS)) > 0; + } + /** + True when the token after the mapped position was deleted. + */ + get deletedAfter() { + return (this.delInfo & (DEL_AFTER | DEL_ACROSS)) > 0; + } + /** + Tells whether any of the steps mapped through deletes across the + position (including both the token before and after the + position). + */ + get deletedAcross() { + return (this.delInfo & DEL_ACROSS) > 0; + } +}; +var StepMap = class _StepMap2 { + /** + Create a position map. The modifications to the document are + represented as an array of numbers, in which each group of three + represents a modified chunk as `[start, oldSize, newSize]`. + */ + constructor(ranges, inverted = false) { + this.ranges = ranges; + this.inverted = inverted; + if (!ranges.length && _StepMap2.empty) + return _StepMap2.empty; + } + /** + @internal + */ + recover(value) { + let diff = 0, index = recoverIndex(value); + if (!this.inverted) + for (let i = 0; i < index; i++) + diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]; + return this.ranges[index * 3] + diff + recoverOffset(value); + } + mapResult(pos, assoc = 1) { + return this._map(pos, assoc, false); + } + map(pos, assoc = 1) { + return this._map(pos, assoc, true); + } + /** + @internal + */ + _map(pos, assoc, simple) { + let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (let i = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) + break; + let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize; + if (pos <= end) { + let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc; + let result = start + diff + (side < 0 ? 0 : newSize); + if (simple) + return result; + let recover = pos == (assoc < 0 ? start : end) ? null : makeRecover(i / 3, pos - start); + let del2 = pos == start ? DEL_AFTER : pos == end ? DEL_BEFORE : DEL_ACROSS; + if (assoc < 0 ? pos != start : pos != end) + del2 |= DEL_SIDE; + return new MapResult(result, del2, recover); + } + diff += newSize - oldSize; + } + return simple ? pos + diff : new MapResult(pos + diff, 0, null); + } + /** + @internal + */ + touches(pos, recover) { + let diff = 0, index = recoverIndex(recover); + let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (let i = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) + break; + let oldSize = this.ranges[i + oldIndex], end = start + oldSize; + if (pos <= end && i == index * 3) + return true; + diff += this.ranges[i + newIndex] - oldSize; + } + return false; + } + /** + Calls the given function on each of the changed ranges included in + this map. + */ + forEach(f) { + let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (let i = 0, diff = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff); + let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]; + f(oldStart, oldStart + oldSize, newStart, newStart + newSize); + diff += newSize - oldSize; + } + } + /** + Create an inverted version of this map. The result can be used to + map positions in the post-step document to the pre-step document. + */ + invert() { + return new _StepMap2(this.ranges, !this.inverted); + } + /** + @internal + */ + toString() { + return (this.inverted ? "-" : "") + JSON.stringify(this.ranges); + } + /** + Create a map that moves all positions by offset `n` (which may be + negative). This can be useful when applying steps meant for a + sub-document to a larger document, or vice-versa. + */ + static offset(n) { + return n == 0 ? _StepMap2.empty : new _StepMap2(n < 0 ? [0, -n, 0] : [0, 0, n]); + } +}; +StepMap.empty = new StepMap([]); +var Mapping = class _Mapping { + /** + Create a new mapping with the given position maps. + */ + constructor(maps, mirror, from3 = 0, to = maps ? maps.length : 0) { + this.mirror = mirror; + this.from = from3; + this.to = to; + this._maps = maps || []; + this.ownData = !(maps || mirror); + } + /** + The step maps in this mapping. + */ + get maps() { + return this._maps; + } + /** + Create a mapping that maps only through a part of this one. + */ + slice(from3 = 0, to = this.maps.length) { + return new _Mapping(this._maps, this.mirror, from3, to); + } + /** + Add a step map to the end of this mapping. If `mirrors` is + given, it should be the index of the step map that is the mirror + image of this one. + */ + appendMap(map4, mirrors) { + if (!this.ownData) { + this._maps = this._maps.slice(); + this.mirror = this.mirror && this.mirror.slice(); + this.ownData = true; + } + this.to = this._maps.push(map4); + if (mirrors != null) + this.setMirror(this._maps.length - 1, mirrors); + } + /** + Add all the step maps in a given mapping to this one (preserving + mirroring information). + */ + appendMapping(mapping) { + for (let i = 0, startSize = this._maps.length; i < mapping._maps.length; i++) { + let mirr = mapping.getMirror(i); + this.appendMap(mapping._maps[i], mirr != null && mirr < i ? startSize + mirr : void 0); + } + } + /** + Finds the offset of the step map that mirrors the map at the + given offset, in this mapping (as per the second argument to + `appendMap`). + */ + getMirror(n) { + if (this.mirror) { + for (let i = 0; i < this.mirror.length; i++) + if (this.mirror[i] == n) + return this.mirror[i + (i % 2 ? -1 : 1)]; + } + } + /** + @internal + */ + setMirror(n, m2) { + if (!this.mirror) + this.mirror = []; + this.mirror.push(n, m2); + } + /** + Append the inverse of the given mapping to this one. + */ + appendMappingInverted(mapping) { + for (let i = mapping.maps.length - 1, totalSize = this._maps.length + mapping._maps.length; i >= 0; i--) { + let mirr = mapping.getMirror(i); + this.appendMap(mapping._maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : void 0); + } + } + /** + Create an inverted version of this mapping. + */ + invert() { + let inverse = new _Mapping(); + inverse.appendMappingInverted(this); + return inverse; + } + /** + Map a position through this mapping. + */ + map(pos, assoc = 1) { + if (this.mirror) + return this._map(pos, assoc, true); + for (let i = this.from; i < this.to; i++) + pos = this._maps[i].map(pos, assoc); + return pos; + } + /** + Map a position through this mapping, returning a mapping + result. + */ + mapResult(pos, assoc = 1) { + return this._map(pos, assoc, false); + } + /** + @internal + */ + _map(pos, assoc, simple) { + let delInfo = 0; + for (let i = this.from; i < this.to; i++) { + let map4 = this._maps[i], result = map4.mapResult(pos, assoc); + if (result.recover != null) { + let corr = this.getMirror(i); + if (corr != null && corr > i && corr < this.to) { + i = corr; + pos = this._maps[corr].recover(result.recover); + continue; + } + } + delInfo |= result.delInfo; + pos = result.pos; + } + return simple ? pos : new MapResult(pos, delInfo, null); + } +}; +var stepsByID = /* @__PURE__ */ Object.create(null); +var Step = class { + /** + Get the step map that represents the changes made by this step, + and which can be used to transform between positions in the old + and the new document. + */ + getMap() { + return StepMap.empty; + } + /** + Try to merge this step with another one, to be applied directly + after it. Returns the merged step when possible, null if the + steps can't be merged. + */ + merge(other) { + return null; + } + /** + Deserialize a step from its JSON representation. Will call + through to the step class' own implementation of this method. + */ + static fromJSON(schema, json) { + if (!json || !json.stepType) + throw new RangeError("Invalid input for Step.fromJSON"); + let type = stepsByID[json.stepType]; + if (!type) + throw new RangeError(`No step type ${json.stepType} defined`); + return type.fromJSON(schema, json); + } + /** + To be able to serialize steps to JSON, each step needs a string + ID to attach to its JSON representation. Use this method to + register an ID for your step classes. Try to pick something + that's unlikely to clash with steps from other modules. + */ + static jsonID(id2, stepClass) { + if (id2 in stepsByID) + throw new RangeError("Duplicate use of step JSON ID " + id2); + stepsByID[id2] = stepClass; + stepClass.prototype.jsonID = id2; + return stepClass; + } +}; +var StepResult = class _StepResult2 { + /** + @internal + */ + constructor(doc4, failed) { + this.doc = doc4; + this.failed = failed; + } + /** + Create a successful step result. + */ + static ok(doc4) { + return new _StepResult2(doc4, null); + } + /** + Create a failed step result. + */ + static fail(message) { + return new _StepResult2(null, message); + } + /** + Call [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) with the given + arguments. Create a successful result if it succeeds, and a + failed one if it throws a `ReplaceError`. + */ + static fromReplace(doc4, from3, to, slice2) { + try { + return _StepResult2.ok(doc4.replace(from3, to, slice2)); + } catch (e) { + if (e instanceof ReplaceError) + return _StepResult2.fail(e.message); + throw e; + } + } +}; +function mapFragment(fragment, f, parent) { + let mapped = []; + for (let i = 0; i < fragment.childCount; i++) { + let child = fragment.child(i); + if (child.content.size) + child = child.copy(mapFragment(child.content, f, child)); + if (child.isInline) + child = f(child, parent, i); + mapped.push(child); + } + return Fragment.fromArray(mapped); +} +var AddMarkStep = class _AddMarkStep2 extends Step { + /** + Create a mark step. + */ + constructor(from3, to, mark) { + super(); + this.from = from3; + this.to = to; + this.mark = mark; + } + apply(doc4) { + let oldSlice = doc4.slice(this.from, this.to), $from = doc4.resolve(this.from); + let parent = $from.node($from.sharedDepth(this.to)); + let slice2 = new Slice(mapFragment(oldSlice.content, (node, parent2) => { + if (!node.isAtom || !parent2.type.allowsMarkType(this.mark.type)) + return node; + return node.mark(this.mark.addToSet(node.marks)); + }, parent), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc4, this.from, this.to, slice2); + } + invert() { + return new RemoveMarkStep(this.from, this.to, this.mark); + } + map(mapping) { + let from3 = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from3.deleted && to.deleted || from3.pos >= to.pos) + return null; + return new _AddMarkStep2(from3.pos, to.pos, this.mark); + } + merge(other) { + if (other instanceof _AddMarkStep2 && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) + return new _AddMarkStep2(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark); + return null; + } + toJSON() { + return { + stepType: "addMark", + mark: this.mark.toJSON(), + from: this.from, + to: this.to + }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for AddMarkStep.fromJSON"); + return new _AddMarkStep2(json.from, json.to, schema.markFromJSON(json.mark)); + } +}; +Step.jsonID("addMark", AddMarkStep); +var RemoveMarkStep = class _RemoveMarkStep2 extends Step { + /** + Create a mark-removing step. + */ + constructor(from3, to, mark) { + super(); + this.from = from3; + this.to = to; + this.mark = mark; + } + apply(doc4) { + let oldSlice = doc4.slice(this.from, this.to); + let slice2 = new Slice(mapFragment(oldSlice.content, (node) => { + return node.mark(this.mark.removeFromSet(node.marks)); + }, doc4), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc4, this.from, this.to, slice2); + } + invert() { + return new AddMarkStep(this.from, this.to, this.mark); + } + map(mapping) { + let from3 = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from3.deleted && to.deleted || from3.pos >= to.pos) + return null; + return new _RemoveMarkStep2(from3.pos, to.pos, this.mark); + } + merge(other) { + if (other instanceof _RemoveMarkStep2 && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) + return new _RemoveMarkStep2(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark); + return null; + } + toJSON() { + return { + stepType: "removeMark", + mark: this.mark.toJSON(), + from: this.from, + to: this.to + }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for RemoveMarkStep.fromJSON"); + return new _RemoveMarkStep2(json.from, json.to, schema.markFromJSON(json.mark)); + } +}; +Step.jsonID("removeMark", RemoveMarkStep); +var AddNodeMarkStep = class _AddNodeMarkStep2 extends Step { + /** + Create a node mark step. + */ + constructor(pos, mark) { + super(); + this.pos = pos; + this.mark = mark; + } + apply(doc4) { + let node = doc4.nodeAt(this.pos); + if (!node) + return StepResult.fail("No node at mark step's position"); + let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks)); + return StepResult.fromReplace(doc4, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1)); + } + invert(doc4) { + let node = doc4.nodeAt(this.pos); + if (node) { + let newSet = this.mark.addToSet(node.marks); + if (newSet.length == node.marks.length) { + for (let i = 0; i < node.marks.length; i++) + if (!node.marks[i].isInSet(newSet)) + return new _AddNodeMarkStep2(this.pos, node.marks[i]); + return new _AddNodeMarkStep2(this.pos, this.mark); + } + } + return new RemoveNodeMarkStep(this.pos, this.mark); + } + map(mapping) { + let pos = mapping.mapResult(this.pos, 1); + return pos.deletedAfter ? null : new _AddNodeMarkStep2(pos.pos, this.mark); + } + toJSON() { + return { stepType: "addNodeMark", pos: this.pos, mark: this.mark.toJSON() }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.pos != "number") + throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON"); + return new _AddNodeMarkStep2(json.pos, schema.markFromJSON(json.mark)); + } +}; +Step.jsonID("addNodeMark", AddNodeMarkStep); +var RemoveNodeMarkStep = class _RemoveNodeMarkStep2 extends Step { + /** + Create a mark-removing step. + */ + constructor(pos, mark) { + super(); + this.pos = pos; + this.mark = mark; + } + apply(doc4) { + let node = doc4.nodeAt(this.pos); + if (!node) + return StepResult.fail("No node at mark step's position"); + let updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks)); + return StepResult.fromReplace(doc4, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1)); + } + invert(doc4) { + let node = doc4.nodeAt(this.pos); + if (!node || !this.mark.isInSet(node.marks)) + return this; + return new AddNodeMarkStep(this.pos, this.mark); + } + map(mapping) { + let pos = mapping.mapResult(this.pos, 1); + return pos.deletedAfter ? null : new _RemoveNodeMarkStep2(pos.pos, this.mark); + } + toJSON() { + return { stepType: "removeNodeMark", pos: this.pos, mark: this.mark.toJSON() }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.pos != "number") + throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON"); + return new _RemoveNodeMarkStep2(json.pos, schema.markFromJSON(json.mark)); + } +}; +Step.jsonID("removeNodeMark", RemoveNodeMarkStep); +var ReplaceStep = class _ReplaceStep2 extends Step { + /** + The given `slice` should fit the 'gap' between `from` and + `to`—the depths must line up, and the surrounding nodes must be + able to be joined with the open sides of the slice. When + `structure` is true, the step will fail if the content between + from and to is not just a sequence of closing and then opening + tokens (this is to guard against rebased replace steps + overwriting something they weren't supposed to). + */ + constructor(from3, to, slice2, structure = false) { + super(); + this.from = from3; + this.to = to; + this.slice = slice2; + this.structure = structure; + } + apply(doc4) { + if (this.structure && contentBetween(doc4, this.from, this.to)) + return StepResult.fail("Structure replace would overwrite content"); + return StepResult.fromReplace(doc4, this.from, this.to, this.slice); + } + getMap() { + return new StepMap([this.from, this.to - this.from, this.slice.size]); + } + invert(doc4) { + return new _ReplaceStep2(this.from, this.from + this.slice.size, doc4.slice(this.from, this.to)); + } + map(mapping) { + let to = mapping.mapResult(this.to, -1); + let from3 = this.from == this.to && _ReplaceStep2.MAP_BIAS < 0 ? to : mapping.mapResult(this.from, 1); + if (from3.deletedAcross && to.deletedAcross) + return null; + return new _ReplaceStep2(from3.pos, Math.max(from3.pos, to.pos), this.slice, this.structure); + } + merge(other) { + if (!(other instanceof _ReplaceStep2) || other.structure || this.structure) + return null; + if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { + let slice2 = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd); + return new _ReplaceStep2(this.from, this.to + (other.to - other.from), slice2, this.structure); + } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { + let slice2 = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd); + return new _ReplaceStep2(other.from, this.to, slice2, this.structure); + } else { + return null; + } + } + toJSON() { + let json = { stepType: "replace", from: this.from, to: this.to }; + if (this.slice.size) + json.slice = this.slice.toJSON(); + if (this.structure) + json.structure = true; + return json; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for ReplaceStep.fromJSON"); + return new _ReplaceStep2(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure); + } +}; +ReplaceStep.MAP_BIAS = 1; +Step.jsonID("replace", ReplaceStep); +var ReplaceAroundStep = class _ReplaceAroundStep2 extends Step { + /** + Create a replace-around step with the given range and gap. + `insert` should be the point in the slice into which the content + of the gap should be moved. `structure` has the same meaning as + it has in the [`ReplaceStep`](https://prosemirror.net/docs/ref/#transform.ReplaceStep) class. + */ + constructor(from3, to, gapFrom, gapTo, slice2, insert, structure = false) { + super(); + this.from = from3; + this.to = to; + this.gapFrom = gapFrom; + this.gapTo = gapTo; + this.slice = slice2; + this.insert = insert; + this.structure = structure; + } + apply(doc4) { + if (this.structure && (contentBetween(doc4, this.from, this.gapFrom) || contentBetween(doc4, this.gapTo, this.to))) + return StepResult.fail("Structure gap-replace would overwrite content"); + let gap = doc4.slice(this.gapFrom, this.gapTo); + if (gap.openStart || gap.openEnd) + return StepResult.fail("Gap is not a flat range"); + let inserted = this.slice.insertAt(this.insert, gap.content); + if (!inserted) + return StepResult.fail("Content does not fit in gap"); + return StepResult.fromReplace(doc4, this.from, this.to, inserted); + } + getMap() { + return new StepMap([ + this.from, + this.gapFrom - this.from, + this.insert, + this.gapTo, + this.to - this.gapTo, + this.slice.size - this.insert + ]); + } + invert(doc4) { + let gap = this.gapTo - this.gapFrom; + return new _ReplaceAroundStep2(this.from, this.from + this.slice.size + gap, this.from + this.insert, this.from + this.insert + gap, doc4.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), this.gapFrom - this.from, this.structure); + } + map(mapping) { + let from3 = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + let gapFrom = this.from == this.gapFrom ? from3.pos : mapping.map(this.gapFrom, -1); + let gapTo = this.to == this.gapTo ? to.pos : mapping.map(this.gapTo, 1); + if (from3.deletedAcross && to.deletedAcross || gapFrom < from3.pos || gapTo > to.pos) + return null; + return new _ReplaceAroundStep2(from3.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure); + } + toJSON() { + let json = { + stepType: "replaceAround", + from: this.from, + to: this.to, + gapFrom: this.gapFrom, + gapTo: this.gapTo, + insert: this.insert + }; + if (this.slice.size) + json.slice = this.slice.toJSON(); + if (this.structure) + json.structure = true; + return json; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number" || typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") + throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON"); + return new _ReplaceAroundStep2(json.from, json.to, json.gapFrom, json.gapTo, Slice.fromJSON(schema, json.slice), json.insert, !!json.structure); + } +}; +Step.jsonID("replaceAround", ReplaceAroundStep); +function contentBetween(doc4, from3, to) { + let $from = doc4.resolve(from3), dist = to - from3, depth = $from.depth; + while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { + depth--; + dist--; + } + if (dist > 0) { + let next2 = $from.node(depth).maybeChild($from.indexAfter(depth)); + while (dist > 0) { + if (!next2 || next2.isLeaf) + return true; + next2 = next2.firstChild; + dist--; + } + } + return false; +} +function addMark(tr2, from3, to, mark) { + let removed = [], added = []; + let removing, adding; + tr2.doc.nodesBetween(from3, to, (node, pos, parent) => { + if (!node.isInline) + return; + let marks = node.marks; + if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) { + let start = Math.max(pos, from3), end = Math.min(pos + node.nodeSize, to); + let newSet = mark.addToSet(marks); + for (let i = 0; i < marks.length; i++) { + if (!marks[i].isInSet(newSet)) { + if (removing && removing.to == start && removing.mark.eq(marks[i])) + removing.to = end; + else + removed.push(removing = new RemoveMarkStep(start, end, marks[i])); + } + } + if (adding && adding.to == start) + adding.to = end; + else + added.push(adding = new AddMarkStep(start, end, mark)); + } + }); + removed.forEach((s) => tr2.step(s)); + added.forEach((s) => tr2.step(s)); +} +function removeMark(tr2, from3, to, mark) { + let matched = [], step = 0; + tr2.doc.nodesBetween(from3, to, (node, pos) => { + if (!node.isInline) + return; + step++; + let toRemove = null; + if (mark instanceof MarkType) { + let set = node.marks, found3; + while (found3 = mark.isInSet(set)) { + (toRemove || (toRemove = [])).push(found3); + set = found3.removeFromSet(set); + } + } else if (mark) { + if (mark.isInSet(node.marks)) + toRemove = [mark]; + } else { + toRemove = node.marks; + } + if (toRemove && toRemove.length) { + let end = Math.min(pos + node.nodeSize, to); + for (let i = 0; i < toRemove.length; i++) { + let style2 = toRemove[i], found3; + for (let j2 = 0; j2 < matched.length; j2++) { + let m2 = matched[j2]; + if (m2.step == step - 1 && style2.eq(matched[j2].style)) + found3 = m2; + } + if (found3) { + found3.to = end; + found3.step = step; + } else { + matched.push({ style: style2, from: Math.max(pos, from3), to: end, step }); + } + } + } + }); + matched.forEach((m2) => tr2.step(new RemoveMarkStep(m2.from, m2.to, m2.style))); +} +function clearIncompatible(tr2, pos, parentType, match2 = parentType.contentMatch, clearNewlines = true) { + let node = tr2.doc.nodeAt(pos); + let replSteps = [], cur = pos + 1; + for (let i = 0; i < node.childCount; i++) { + let child = node.child(i), end = cur + child.nodeSize; + let allowed = match2.matchType(child.type); + if (!allowed) { + replSteps.push(new ReplaceStep(cur, end, Slice.empty)); + } else { + match2 = allowed; + for (let j2 = 0; j2 < child.marks.length; j2++) + if (!parentType.allowsMarkType(child.marks[j2].type)) + tr2.step(new RemoveMarkStep(cur, end, child.marks[j2])); + if (clearNewlines && child.isText && parentType.whitespace != "pre") { + let m2, newline = /\r?\n|\r/g, slice2; + while (m2 = newline.exec(child.text)) { + if (!slice2) + slice2 = new Slice(Fragment.from(parentType.schema.text(" ", parentType.allowedMarks(child.marks))), 0, 0); + replSteps.push(new ReplaceStep(cur + m2.index, cur + m2.index + m2[0].length, slice2)); + } + } + } + cur = end; + } + if (!match2.validEnd) { + let fill = match2.fillBefore(Fragment.empty, true); + tr2.replace(cur, cur, new Slice(fill, 0, 0)); + } + for (let i = replSteps.length - 1; i >= 0; i--) + tr2.step(replSteps[i]); +} +function canCut(node, start, end) { + return (start == 0 || node.canReplace(start, node.childCount)) && (end == node.childCount || node.canReplace(0, end)); +} +function liftTarget(range) { + let parent = range.parent; + let content = parent.content.cutByIndex(range.startIndex, range.endIndex); + for (let depth = range.depth, contentBefore = 0, contentAfter = 0; ; --depth) { + let node = range.$from.node(depth); + let index = range.$from.index(depth) + contentBefore, endIndex = range.$to.indexAfter(depth) - contentAfter; + if (depth < range.depth && node.canReplace(index, endIndex, content)) + return depth; + if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) + break; + if (index) + contentBefore = 1; + if (endIndex < node.childCount) + contentAfter = 1; + } + return null; +} +function lift(tr2, range, target) { + let { $from, $to, depth } = range; + let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1); + let start = gapStart, end = gapEnd; + let before = Fragment.empty, openStart = 0; + for (let d2 = depth, splitting = false; d2 > target; d2--) + if (splitting || $from.index(d2) > 0) { + splitting = true; + before = Fragment.from($from.node(d2).copy(before)); + openStart++; + } else { + start--; + } + let after = Fragment.empty, openEnd = 0; + for (let d2 = depth, splitting = false; d2 > target; d2--) + if (splitting || $to.after(d2 + 1) < $to.end(d2)) { + splitting = true; + after = Fragment.from($to.node(d2).copy(after)); + openEnd++; + } else { + end++; + } + tr2.step(new ReplaceAroundStep(start, end, gapStart, gapEnd, new Slice(before.append(after), openStart, openEnd), before.size - openStart, true)); +} +function findWrapping(range, nodeType, attrs = null, innerRange = range) { + let around = findWrappingOutside(range, nodeType); + let inner = around && findWrappingInside(innerRange, nodeType); + if (!inner) + return null; + return around.map(withAttrs).concat({ type: nodeType, attrs }).concat(inner.map(withAttrs)); +} +function withAttrs(type) { + return { type, attrs: null }; +} +function findWrappingOutside(range, type) { + let { parent, startIndex, endIndex } = range; + let around = parent.contentMatchAt(startIndex).findWrapping(type); + if (!around) + return null; + let outer = around.length ? around[0] : type; + return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null; +} +function findWrappingInside(range, type) { + let { parent, startIndex, endIndex } = range; + let inner = parent.child(startIndex); + let inside = type.contentMatch.findWrapping(inner.type); + if (!inside) + return null; + let lastType = inside.length ? inside[inside.length - 1] : type; + let innerMatch = lastType.contentMatch; + for (let i = startIndex; innerMatch && i < endIndex; i++) + innerMatch = innerMatch.matchType(parent.child(i).type); + if (!innerMatch || !innerMatch.validEnd) + return null; + return inside; +} +function wrap(tr2, range, wrappers) { + let content = Fragment.empty; + for (let i = wrappers.length - 1; i >= 0; i--) { + if (content.size) { + let match2 = wrappers[i].type.contentMatch.matchFragment(content); + if (!match2 || !match2.validEnd) + throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper"); + } + content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content)); + } + let start = range.start, end = range.end; + tr2.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true)); +} +function setBlockType(tr2, from3, to, type, attrs) { + if (!type.isTextblock) + throw new RangeError("Type given to setBlockType should be a textblock"); + let mapFrom = tr2.steps.length; + tr2.doc.nodesBetween(from3, to, (node, pos) => { + let attrsHere = typeof attrs == "function" ? attrs(node) : attrs; + if (node.isTextblock && !node.hasMarkup(type, attrsHere) && canChangeType(tr2.doc, tr2.mapping.slice(mapFrom).map(pos), type)) { + let convertNewlines = null; + if (type.schema.linebreakReplacement) { + let pre = type.whitespace == "pre", supportLinebreak = !!type.contentMatch.matchType(type.schema.linebreakReplacement); + if (pre && !supportLinebreak) + convertNewlines = false; + else if (!pre && supportLinebreak) + convertNewlines = true; + } + if (convertNewlines === false) + replaceLinebreaks(tr2, node, pos, mapFrom); + clearIncompatible(tr2, tr2.mapping.slice(mapFrom).map(pos, 1), type, void 0, convertNewlines === null); + let mapping = tr2.mapping.slice(mapFrom); + let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1); + tr2.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, new Slice(Fragment.from(type.create(attrsHere, null, node.marks)), 0, 0), 1, true)); + if (convertNewlines === true) + replaceNewlines(tr2, node, pos, mapFrom); + return false; + } + }); +} +function replaceNewlines(tr2, node, pos, mapFrom) { + node.forEach((child, offset) => { + if (child.isText) { + let m2, newline = /\r?\n|\r/g; + while (m2 = newline.exec(child.text)) { + let start = tr2.mapping.slice(mapFrom).map(pos + 1 + offset + m2.index); + tr2.replaceWith(start, start + 1, node.type.schema.linebreakReplacement.create()); + } + } + }); +} +function replaceLinebreaks(tr2, node, pos, mapFrom) { + node.forEach((child, offset) => { + if (child.type == child.type.schema.linebreakReplacement) { + let start = tr2.mapping.slice(mapFrom).map(pos + 1 + offset); + tr2.replaceWith(start, start + 1, node.type.schema.text("\n")); + } + }); +} +function canChangeType(doc4, pos, type) { + let $pos = doc4.resolve(pos), index = $pos.index(); + return $pos.parent.canReplaceWith(index, index + 1, type); +} +function setNodeMarkup(tr2, pos, type, attrs, marks) { + let node = tr2.doc.nodeAt(pos); + if (!node) + throw new RangeError("No node at given position"); + if (!type) + type = node.type; + let newNode = type.create(attrs, null, marks || node.marks); + if (node.isLeaf) + return tr2.replaceWith(pos, pos + node.nodeSize, newNode); + if (!type.validContent(node.content)) + throw new RangeError("Invalid content for node type " + type.name); + tr2.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, new Slice(Fragment.from(newNode), 0, 0), 1, true)); +} +function canSplit(doc4, pos, depth = 1, typesAfter) { + let $pos = doc4.resolve(pos), base2 = $pos.depth - depth; + let innerType = typesAfter && typesAfter[typesAfter.length - 1] || $pos.parent; + if (base2 < 0 || $pos.parent.type.spec.isolating || !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) + return false; + for (let d2 = $pos.depth - 1, i = depth - 2; d2 > base2; d2--, i--) { + let node = $pos.node(d2), index2 = $pos.index(d2); + if (node.type.spec.isolating) + return false; + let rest = node.content.cutByIndex(index2, node.childCount); + let overrideChild = typesAfter && typesAfter[i + 1]; + if (overrideChild) + rest = rest.replaceChild(0, overrideChild.type.create(overrideChild.attrs)); + let after = typesAfter && typesAfter[i] || node; + if (!node.canReplace(index2 + 1, node.childCount) || !after.type.validContent(rest)) + return false; + } + let index = $pos.indexAfter(base2); + let baseType = typesAfter && typesAfter[0]; + return $pos.node(base2).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base2 + 1).type); +} +function split(tr2, pos, depth = 1, typesAfter) { + let $pos = tr2.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty; + for (let d2 = $pos.depth, e = $pos.depth - depth, i = depth - 1; d2 > e; d2--, i--) { + before = Fragment.from($pos.node(d2).copy(before)); + let typeAfter = typesAfter && typesAfter[i]; + after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d2).copy(after)); + } + tr2.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true)); +} +function canJoin(doc4, pos) { + let $pos = doc4.resolve(pos), index = $pos.index(); + return joinable2($pos.nodeBefore, $pos.nodeAfter) && $pos.parent.canReplace(index, index + 1); +} +function canAppendWithSubstitutedLinebreaks(a, b2) { + if (!b2.content.size) + a.type.compatibleContent(b2.type); + let match2 = a.contentMatchAt(a.childCount); + let { linebreakReplacement } = a.type.schema; + for (let i = 0; i < b2.childCount; i++) { + let child = b2.child(i); + let type = child.type == linebreakReplacement ? a.type.schema.nodes.text : child.type; + match2 = match2.matchType(type); + if (!match2) + return false; + if (!a.type.allowsMarks(child.marks)) + return false; + } + return match2.validEnd; +} +function joinable2(a, b2) { + return !!(a && b2 && !a.isLeaf && canAppendWithSubstitutedLinebreaks(a, b2)); +} +function joinPoint(doc4, pos, dir = -1) { + let $pos = doc4.resolve(pos); + for (let d2 = $pos.depth; ; d2--) { + let before, after, index = $pos.index(d2); + if (d2 == $pos.depth) { + before = $pos.nodeBefore; + after = $pos.nodeAfter; + } else if (dir > 0) { + before = $pos.node(d2 + 1); + index++; + after = $pos.node(d2).maybeChild(index); + } else { + before = $pos.node(d2).maybeChild(index - 1); + after = $pos.node(d2 + 1); + } + if (before && !before.isTextblock && joinable2(before, after) && $pos.node(d2).canReplace(index, index + 1)) + return pos; + if (d2 == 0) + break; + pos = dir < 0 ? $pos.before(d2) : $pos.after(d2); + } +} +function join(tr2, pos, depth) { + let convertNewlines = null; + let { linebreakReplacement } = tr2.doc.type.schema; + let $before = tr2.doc.resolve(pos - depth), beforeType = $before.node().type; + if (linebreakReplacement && beforeType.inlineContent) { + let pre = beforeType.whitespace == "pre"; + let supportLinebreak = !!beforeType.contentMatch.matchType(linebreakReplacement); + if (pre && !supportLinebreak) + convertNewlines = false; + else if (!pre && supportLinebreak) + convertNewlines = true; + } + let mapFrom = tr2.steps.length; + if (convertNewlines === false) { + let $after = tr2.doc.resolve(pos + depth); + replaceLinebreaks(tr2, $after.node(), $after.before(), mapFrom); + } + if (beforeType.inlineContent) + clearIncompatible(tr2, pos + depth - 1, beforeType, $before.node().contentMatchAt($before.index()), convertNewlines == null); + let mapping = tr2.mapping.slice(mapFrom), start = mapping.map(pos - depth); + tr2.step(new ReplaceStep(start, mapping.map(pos + depth, -1), Slice.empty, true)); + if (convertNewlines === true) { + let $full = tr2.doc.resolve(start); + replaceNewlines(tr2, $full.node(), $full.before(), tr2.steps.length); + } + return tr2; +} +function insertPoint(doc4, pos, nodeType) { + let $pos = doc4.resolve(pos); + if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) + return pos; + if ($pos.parentOffset == 0) + for (let d2 = $pos.depth - 1; d2 >= 0; d2--) { + let index = $pos.index(d2); + if ($pos.node(d2).canReplaceWith(index, index, nodeType)) + return $pos.before(d2 + 1); + if (index > 0) + return null; + } + if ($pos.parentOffset == $pos.parent.content.size) + for (let d2 = $pos.depth - 1; d2 >= 0; d2--) { + let index = $pos.indexAfter(d2); + if ($pos.node(d2).canReplaceWith(index, index, nodeType)) + return $pos.after(d2 + 1); + if (index < $pos.node(d2).childCount) + return null; + } + return null; +} +function dropPoint(doc4, pos, slice2) { + let $pos = doc4.resolve(pos); + if (!slice2.content.size) + return pos; + let content = slice2.content; + for (let i = 0; i < slice2.openStart; i++) + content = content.firstChild.content; + for (let pass = 1; pass <= (slice2.openStart == 0 && slice2.size ? 2 : 1); pass++) { + for (let d2 = $pos.depth; d2 >= 0; d2--) { + let bias = d2 == $pos.depth ? 0 : $pos.pos <= ($pos.start(d2 + 1) + $pos.end(d2 + 1)) / 2 ? -1 : 1; + let insertPos = $pos.index(d2) + (bias > 0 ? 1 : 0); + let parent = $pos.node(d2), fits = false; + if (pass == 1) { + fits = parent.canReplace(insertPos, insertPos, content); + } else { + let wrapping = parent.contentMatchAt(insertPos).findWrapping(content.firstChild.type); + fits = wrapping && parent.canReplaceWith(insertPos, insertPos, wrapping[0]); + } + if (fits) + return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d2 + 1) : $pos.after(d2 + 1); + } + } + return null; +} +function replaceStep(doc4, from3, to = from3, slice2 = Slice.empty) { + if (from3 == to && !slice2.size) + return null; + let $from = doc4.resolve(from3), $to = doc4.resolve(to); + if (fitsTrivially($from, $to, slice2)) + return new ReplaceStep(from3, to, slice2); + return new Fitter($from, $to, slice2).fit(); +} +function fitsTrivially($from, $to, slice2) { + return !slice2.openStart && !slice2.openEnd && $from.start() == $to.start() && $from.parent.canReplace($from.index(), $to.index(), slice2.content); +} +var Fitter = class { + constructor($from, $to, unplaced) { + this.$from = $from; + this.$to = $to; + this.unplaced = unplaced; + this.frontier = []; + this.placed = Fragment.empty; + for (let i = 0; i <= $from.depth; i++) { + let node = $from.node(i); + this.frontier.push({ + type: node.type, + match: node.contentMatchAt($from.indexAfter(i)) + }); + } + for (let i = $from.depth; i > 0; i--) + this.placed = Fragment.from($from.node(i).copy(this.placed)); + } + get depth() { + return this.frontier.length - 1; + } + fit() { + while (this.unplaced.size) { + let fit = this.findFittable(); + if (fit) + this.placeNodes(fit); + else + this.openMore() || this.dropNode(); + } + let moveInline = this.mustMoveInline(), placedSize = this.placed.size - this.depth - this.$from.depth; + let $from = this.$from, $to = this.close(moveInline < 0 ? this.$to : $from.doc.resolve(moveInline)); + if (!$to) + return null; + let content = this.placed, openStart = $from.depth, openEnd = $to.depth; + while (openStart && openEnd && content.childCount == 1) { + content = content.firstChild.content; + openStart--; + openEnd--; + } + let slice2 = new Slice(content, openStart, openEnd); + if (moveInline > -1) + return new ReplaceAroundStep($from.pos, moveInline, this.$to.pos, this.$to.end(), slice2, placedSize); + if (slice2.size || $from.pos != this.$to.pos) + return new ReplaceStep($from.pos, $to.pos, slice2); + return null; + } + // Find a position on the start spine of `this.unplaced` that has + // content that can be moved somewhere on the frontier. Returns two + // depths, one for the slice and one for the frontier. + findFittable() { + let startDepth = this.unplaced.openStart; + for (let cur = this.unplaced.content, d2 = 0, openEnd = this.unplaced.openEnd; d2 < startDepth; d2++) { + let node = cur.firstChild; + if (cur.childCount > 1) + openEnd = 0; + if (node.type.spec.isolating && openEnd <= d2) { + startDepth = d2; + break; + } + cur = node.content; + } + for (let pass = 1; pass <= 2; pass++) { + for (let sliceDepth = pass == 1 ? startDepth : this.unplaced.openStart; sliceDepth >= 0; sliceDepth--) { + let fragment, parent = null; + if (sliceDepth) { + parent = contentAt(this.unplaced.content, sliceDepth - 1).firstChild; + fragment = parent.content; + } else { + fragment = this.unplaced.content; + } + let first2 = fragment.firstChild; + for (let frontierDepth = this.depth; frontierDepth >= 0; frontierDepth--) { + let { type, match: match2 } = this.frontier[frontierDepth], wrap2, inject = null; + if (pass == 1 && (first2 ? match2.matchType(first2.type) || (inject = match2.fillBefore(Fragment.from(first2), false)) : parent && type.compatibleContent(parent.type))) + return { sliceDepth, frontierDepth, parent, inject }; + else if (pass == 2 && first2 && (wrap2 = match2.findWrapping(first2.type))) + return { sliceDepth, frontierDepth, parent, wrap: wrap2 }; + if (parent && match2.matchType(parent.type)) + break; + } + } + } + } + openMore() { + let { content, openStart, openEnd } = this.unplaced; + let inner = contentAt(content, openStart); + if (!inner.childCount || inner.firstChild.isLeaf) + return false; + this.unplaced = new Slice(content, openStart + 1, Math.max(openEnd, inner.size + openStart >= content.size - openEnd ? openStart + 1 : 0)); + return true; + } + dropNode() { + let { content, openStart, openEnd } = this.unplaced; + let inner = contentAt(content, openStart); + if (inner.childCount <= 1 && openStart > 0) { + let openAtEnd = content.size - openStart <= openStart + inner.size; + this.unplaced = new Slice(dropFromFragment(content, openStart - 1, 1), openStart - 1, openAtEnd ? openStart - 1 : openEnd); + } else { + this.unplaced = new Slice(dropFromFragment(content, openStart, 1), openStart, openEnd); + } + } + // Move content from the unplaced slice at `sliceDepth` to the + // frontier node at `frontierDepth`. Close that frontier node when + // applicable. + placeNodes({ sliceDepth, frontierDepth, parent, inject, wrap: wrap2 }) { + while (this.depth > frontierDepth) + this.closeFrontierNode(); + if (wrap2) + for (let i = 0; i < wrap2.length; i++) + this.openFrontierNode(wrap2[i]); + let slice2 = this.unplaced, fragment = parent ? parent.content : slice2.content; + let openStart = slice2.openStart - sliceDepth; + let taken = 0, add = []; + let { match: match2, type } = this.frontier[frontierDepth]; + if (inject) { + for (let i = 0; i < inject.childCount; i++) + add.push(inject.child(i)); + match2 = match2.matchFragment(inject); + } + let openEndCount = fragment.size + sliceDepth - (slice2.content.size - slice2.openEnd); + while (taken < fragment.childCount) { + let next2 = fragment.child(taken), matches2 = match2.matchType(next2.type); + if (!matches2) + break; + taken++; + if (taken > 1 || openStart == 0 || next2.content.size) { + match2 = matches2; + add.push(closeNodeStart(next2.mark(type.allowedMarks(next2.marks)), taken == 1 ? openStart : 0, taken == fragment.childCount ? openEndCount : -1)); + } + } + let toEnd = taken == fragment.childCount; + if (!toEnd) + openEndCount = -1; + this.placed = addToFragment(this.placed, frontierDepth, Fragment.from(add)); + this.frontier[frontierDepth].match = match2; + if (toEnd && openEndCount < 0 && parent && parent.type == this.frontier[this.depth].type && this.frontier.length > 1) + this.closeFrontierNode(); + for (let i = 0, cur = fragment; i < openEndCount; i++) { + let node = cur.lastChild; + this.frontier.push({ type: node.type, match: node.contentMatchAt(node.childCount) }); + cur = node.content; + } + this.unplaced = !toEnd ? new Slice(dropFromFragment(slice2.content, sliceDepth, taken), slice2.openStart, slice2.openEnd) : sliceDepth == 0 ? Slice.empty : new Slice(dropFromFragment(slice2.content, sliceDepth - 1, 1), sliceDepth - 1, openEndCount < 0 ? slice2.openEnd : sliceDepth - 1); + } + mustMoveInline() { + if (!this.$to.parent.isTextblock) + return -1; + let top = this.frontier[this.depth], level; + if (!top.type.isTextblock || !contentAfterFits(this.$to, this.$to.depth, top.type, top.match, false) || this.$to.depth == this.depth && (level = this.findCloseLevel(this.$to)) && level.depth == this.depth) + return -1; + let { depth } = this.$to, after = this.$to.after(depth); + while (depth > 1 && after == this.$to.end(--depth)) + ++after; + return after; + } + findCloseLevel($to) { + scan: for (let i = Math.min(this.depth, $to.depth); i >= 0; i--) { + let { match: match2, type } = this.frontier[i]; + let dropInner = i < $to.depth && $to.end(i + 1) == $to.pos + ($to.depth - (i + 1)); + let fit = contentAfterFits($to, i, type, match2, dropInner); + if (!fit) + continue; + for (let d2 = i - 1; d2 >= 0; d2--) { + let { match: match3, type: type2 } = this.frontier[d2]; + let matches2 = contentAfterFits($to, d2, type2, match3, true); + if (!matches2 || matches2.childCount) + continue scan; + } + return { depth: i, fit, move: dropInner ? $to.doc.resolve($to.after(i + 1)) : $to }; + } + } + close($to) { + let close3 = this.findCloseLevel($to); + if (!close3) + return null; + while (this.depth > close3.depth) + this.closeFrontierNode(); + if (close3.fit.childCount) + this.placed = addToFragment(this.placed, close3.depth, close3.fit); + $to = close3.move; + for (let d2 = close3.depth + 1; d2 <= $to.depth; d2++) { + let node = $to.node(d2), add = node.type.contentMatch.fillBefore(node.content, true, $to.index(d2)); + this.openFrontierNode(node.type, node.attrs, add); + } + return $to; + } + openFrontierNode(type, attrs = null, content) { + let top = this.frontier[this.depth]; + top.match = top.match.matchType(type); + this.placed = addToFragment(this.placed, this.depth, Fragment.from(type.create(attrs, content))); + this.frontier.push({ type, match: type.contentMatch }); + } + closeFrontierNode() { + let open = this.frontier.pop(); + let add = open.match.fillBefore(Fragment.empty, true); + if (add.childCount) + this.placed = addToFragment(this.placed, this.frontier.length, add); + } +}; +function dropFromFragment(fragment, depth, count) { + if (depth == 0) + return fragment.cutByIndex(count, fragment.childCount); + return fragment.replaceChild(0, fragment.firstChild.copy(dropFromFragment(fragment.firstChild.content, depth - 1, count))); +} +function addToFragment(fragment, depth, content) { + if (depth == 0) + return fragment.append(content); + return fragment.replaceChild(fragment.childCount - 1, fragment.lastChild.copy(addToFragment(fragment.lastChild.content, depth - 1, content))); +} +function contentAt(fragment, depth) { + for (let i = 0; i < depth; i++) + fragment = fragment.firstChild.content; + return fragment; +} +function closeNodeStart(node, openStart, openEnd) { + if (openStart <= 0) + return node; + let frag = node.content; + if (openStart > 1) + frag = frag.replaceChild(0, closeNodeStart(frag.firstChild, openStart - 1, frag.childCount == 1 ? openEnd - 1 : 0)); + if (openStart > 0) { + frag = node.type.contentMatch.fillBefore(frag).append(frag); + if (openEnd <= 0) + frag = frag.append(node.type.contentMatch.matchFragment(frag).fillBefore(Fragment.empty, true)); + } + return node.copy(frag); +} +function contentAfterFits($to, depth, type, match2, open) { + let node = $to.node(depth), index = open ? $to.indexAfter(depth) : $to.index(depth); + if (index == node.childCount && !type.compatibleContent(node.type)) + return null; + let fit = match2.fillBefore(node.content, true, index); + return fit && !invalidMarks(type, node.content, index) ? fit : null; +} +function invalidMarks(type, fragment, start) { + for (let i = start; i < fragment.childCount; i++) + if (!type.allowsMarks(fragment.child(i).marks)) + return true; + return false; +} +function definesContent(type) { + return type.spec.defining || type.spec.definingForContent; +} +function replaceRange(tr2, from3, to, slice2) { + if (!slice2.size) + return tr2.deleteRange(from3, to); + let $from = tr2.doc.resolve(from3), $to = tr2.doc.resolve(to); + if (fitsTrivially($from, $to, slice2)) + return tr2.step(new ReplaceStep(from3, to, slice2)); + let targetDepths = coveredDepths($from, $to); + if (targetDepths[targetDepths.length - 1] == 0) + targetDepths.pop(); + let preferredTarget = -($from.depth + 1); + targetDepths.unshift(preferredTarget); + for (let d2 = $from.depth, pos = $from.pos - 1; d2 > 0; d2--, pos--) { + let spec = $from.node(d2).type.spec; + if (spec.defining || spec.definingAsContext || spec.isolating) + break; + if (targetDepths.indexOf(d2) > -1) + preferredTarget = d2; + else if ($from.before(d2) == pos) + targetDepths.splice(1, 0, -d2); + } + let preferredTargetIndex = targetDepths.indexOf(preferredTarget); + let leftNodes = [], preferredDepth = slice2.openStart; + for (let content = slice2.content, i = 0; ; i++) { + let node = content.firstChild; + leftNodes.push(node); + if (i == slice2.openStart) + break; + content = node.content; + } + for (let d2 = preferredDepth - 1; d2 >= 0; d2--) { + let leftNode = leftNodes[d2], def = definesContent(leftNode.type); + if (def && !leftNode.sameMarkup($from.node(Math.abs(preferredTarget) - 1))) + preferredDepth = d2; + else if (def || !leftNode.type.isTextblock) + break; + } + for (let j2 = slice2.openStart; j2 >= 0; j2--) { + let openDepth = (j2 + preferredDepth + 1) % (slice2.openStart + 1); + let insert = leftNodes[openDepth]; + if (!insert) + continue; + for (let i = 0; i < targetDepths.length; i++) { + let targetDepth = targetDepths[(i + preferredTargetIndex) % targetDepths.length], expand = true; + if (targetDepth < 0) { + expand = false; + targetDepth = -targetDepth; + } + let parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1); + if (parent.canReplaceWith(index, index, insert.type, insert.marks)) + return tr2.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, new Slice(closeFragment(slice2.content, 0, slice2.openStart, openDepth), openDepth, slice2.openEnd)); + } + } + let startSteps = tr2.steps.length; + for (let i = targetDepths.length - 1; i >= 0; i--) { + tr2.replace(from3, to, slice2); + if (tr2.steps.length > startSteps) + break; + let depth = targetDepths[i]; + if (depth < 0) + continue; + from3 = $from.before(depth); + to = $to.after(depth); + } +} +function closeFragment(fragment, depth, oldOpen, newOpen, parent) { + if (depth < oldOpen) { + let first2 = fragment.firstChild; + fragment = fragment.replaceChild(0, first2.copy(closeFragment(first2.content, depth + 1, oldOpen, newOpen, first2))); + } + if (depth > newOpen) { + let match2 = parent.contentMatchAt(0); + let start = match2.fillBefore(fragment).append(fragment); + fragment = start.append(match2.matchFragment(start).fillBefore(Fragment.empty, true)); + } + return fragment; +} +function replaceRangeWith(tr2, from3, to, node) { + if (!node.isInline && from3 == to && tr2.doc.resolve(from3).parent.content.size) { + let point = insertPoint(tr2.doc, from3, node.type); + if (point != null) + from3 = to = point; + } + tr2.replaceRange(from3, to, new Slice(Fragment.from(node), 0, 0)); +} +function deleteRange(tr2, from3, to) { + let $from = tr2.doc.resolve(from3), $to = tr2.doc.resolve(to); + if ($from.parent.isTextblock && $to.parent.isTextblock && $from.start() != $to.start() && $from.parentOffset == 0 && $to.parentOffset == 0) { + let shared = $from.sharedDepth(to), isolated = false; + for (let d2 = $from.depth; d2 > shared; d2--) + if ($from.node(d2).type.spec.isolating) + isolated = true; + for (let d2 = $to.depth; d2 > shared; d2--) + if ($to.node(d2).type.spec.isolating) + isolated = true; + if (!isolated) { + for (let d2 = $from.depth; d2 > 0 && from3 == $from.start(d2); d2--) + from3 = $from.before(d2); + for (let d2 = $to.depth; d2 > 0 && to == $to.start(d2); d2--) + to = $to.before(d2); + $from = tr2.doc.resolve(from3); + $to = tr2.doc.resolve(to); + } + } + let covered = coveredDepths($from, $to); + for (let i = 0; i < covered.length; i++) { + let depth = covered[i], last2 = i == covered.length - 1; + if (last2 && depth == 0 || $from.node(depth).type.contentMatch.validEnd) + return tr2.delete($from.start(depth), $to.end(depth)); + if (depth > 0 && (last2 || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) + return tr2.delete($from.before(depth), $to.after(depth)); + } + for (let d2 = 1; d2 <= $from.depth && d2 <= $to.depth; d2++) { + if (from3 - $from.start(d2) == $from.depth - d2 && to > $from.end(d2) && $to.end(d2) - to != $to.depth - d2 && $from.start(d2 - 1) == $to.start(d2 - 1) && $from.node(d2 - 1).canReplace($from.index(d2 - 1), $to.index(d2 - 1))) + return tr2.delete($from.before(d2), to); + } + tr2.delete(from3, to); +} +function coveredDepths($from, $to) { + let result = [], minDepth = Math.min($from.depth, $to.depth); + for (let d2 = minDepth; d2 >= 0; d2--) { + let start = $from.start(d2); + if (start < $from.pos - ($from.depth - d2) || $to.end(d2) > $to.pos + ($to.depth - d2) || $from.node(d2).type.spec.isolating || $to.node(d2).type.spec.isolating) + break; + if (start == $to.start(d2) || d2 == $from.depth && d2 == $to.depth && $from.parent.inlineContent && $to.parent.inlineContent && d2 && $to.start(d2 - 1) == start - 1) + result.push(d2); + } + return result; +} +var AttrStep = class _AttrStep2 extends Step { + /** + Construct an attribute step. + */ + constructor(pos, attr, value) { + super(); + this.pos = pos; + this.attr = attr; + this.value = value; + } + apply(doc4) { + let node = doc4.nodeAt(this.pos); + if (!node) + return StepResult.fail("No node at attribute step's position"); + let attrs = /* @__PURE__ */ Object.create(null); + for (let name in node.attrs) + attrs[name] = node.attrs[name]; + attrs[this.attr] = this.value; + let updated = node.type.create(attrs, null, node.marks); + return StepResult.fromReplace(doc4, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1)); + } + getMap() { + return StepMap.empty; + } + invert(doc4) { + return new _AttrStep2(this.pos, this.attr, doc4.nodeAt(this.pos).attrs[this.attr]); + } + map(mapping) { + let pos = mapping.mapResult(this.pos, 1); + return pos.deletedAfter ? null : new _AttrStep2(pos.pos, this.attr, this.value); + } + toJSON() { + return { stepType: "attr", pos: this.pos, attr: this.attr, value: this.value }; + } + static fromJSON(schema, json) { + if (typeof json.pos != "number" || typeof json.attr != "string") + throw new RangeError("Invalid input for AttrStep.fromJSON"); + return new _AttrStep2(json.pos, json.attr, json.value); + } +}; +Step.jsonID("attr", AttrStep); +var DocAttrStep = class _DocAttrStep2 extends Step { + /** + Construct an attribute step. + */ + constructor(attr, value) { + super(); + this.attr = attr; + this.value = value; + } + apply(doc4) { + let attrs = /* @__PURE__ */ Object.create(null); + for (let name in doc4.attrs) + attrs[name] = doc4.attrs[name]; + attrs[this.attr] = this.value; + let updated = doc4.type.create(attrs, doc4.content, doc4.marks); + return StepResult.ok(updated); + } + getMap() { + return StepMap.empty; + } + invert(doc4) { + return new _DocAttrStep2(this.attr, doc4.attrs[this.attr]); + } + map(mapping) { + return this; + } + toJSON() { + return { stepType: "docAttr", attr: this.attr, value: this.value }; + } + static fromJSON(schema, json) { + if (typeof json.attr != "string") + throw new RangeError("Invalid input for DocAttrStep.fromJSON"); + return new _DocAttrStep2(json.attr, json.value); + } +}; +Step.jsonID("docAttr", DocAttrStep); +var TransformError = class extends Error { +}; +TransformError = function TransformError2(message) { + let err = Error.call(this, message); + err.__proto__ = TransformError2.prototype; + return err; +}; +TransformError.prototype = Object.create(Error.prototype); +TransformError.prototype.constructor = TransformError; +TransformError.prototype.name = "TransformError"; +var Transform = class { + /** + Create a transform that starts with the given document. + */ + constructor(doc4) { + this.doc = doc4; + this.steps = []; + this.docs = []; + this.mapping = new Mapping(); + } + /** + The starting document. + */ + get before() { + return this.docs.length ? this.docs[0] : this.doc; + } + /** + Apply a new step in this transform, saving the result. Throws an + error when the step fails. + */ + step(step) { + let result = this.maybeStep(step); + if (result.failed) + throw new TransformError(result.failed); + return this; + } + /** + Try to apply a step in this transformation, ignoring it if it + fails. Returns the step result. + */ + maybeStep(step) { + let result = step.apply(this.doc); + if (!result.failed) + this.addStep(step, result.doc); + return result; + } + /** + True when the document has been changed (when there are any + steps). + */ + get docChanged() { + return this.steps.length > 0; + } + /** + Return a single range, in post-transform document positions, + that covers all content changed by this transform. Returns null + if no replacements are made. Note that this will ignore changes + that add/remove marks without replacing the underlying content. + */ + changedRange() { + let from3 = 1e9, to = -1e9; + for (let i = 0; i < this.mapping.maps.length; i++) { + let map4 = this.mapping.maps[i]; + if (i) { + from3 = map4.map(from3, 1); + to = map4.map(to, -1); + } + map4.forEach((_f, _t2, fromB, toB) => { + from3 = Math.min(from3, fromB); + to = Math.max(to, toB); + }); + } + return from3 == 1e9 ? null : { from: from3, to }; + } + /** + @internal + */ + addStep(step, doc4) { + this.docs.push(this.doc); + this.steps.push(step); + this.mapping.appendMap(step.getMap()); + this.doc = doc4; + } + /** + Replace the part of the document between `from` and `to` with the + given `slice`. + */ + replace(from3, to = from3, slice2 = Slice.empty) { + let step = replaceStep(this.doc, from3, to, slice2); + if (step) + this.step(step); + return this; + } + /** + Replace the given range with the given content, which may be a + fragment, node, or array of nodes. + */ + replaceWith(from3, to, content) { + return this.replace(from3, to, new Slice(Fragment.from(content), 0, 0)); + } + /** + Delete the content between the given positions. + */ + delete(from3, to) { + return this.replace(from3, to, Slice.empty); + } + /** + Insert the given content at the given position. + */ + insert(pos, content) { + return this.replaceWith(pos, pos, content); + } + /** + Replace a range of the document with a given slice, using + `from`, `to`, and the slice's + [`openStart`](https://prosemirror.net/docs/ref/#model.Slice.openStart) property as hints, rather + than fixed start and end points. This method may grow the + replaced area or close open nodes in the slice in order to get a + fit that is more in line with WYSIWYG expectations, by dropping + fully covered parent nodes of the replaced region when they are + marked [non-defining as + context](https://prosemirror.net/docs/ref/#model.NodeSpec.definingAsContext), or including an + open parent node from the slice that _is_ marked as [defining + its content](https://prosemirror.net/docs/ref/#model.NodeSpec.definingForContent). + + This is the method, for example, to handle paste. The similar + [`replace`](https://prosemirror.net/docs/ref/#transform.Transform.replace) method is a more + primitive tool which will _not_ move the start and end of its given + range, and is useful in situations where you need more precise + control over what happens. + */ + replaceRange(from3, to, slice2) { + replaceRange(this, from3, to, slice2); + return this; + } + /** + Replace the given range with a node, but use `from` and `to` as + hints, rather than precise positions. When from and to are the same + and are at the start or end of a parent node in which the given + node doesn't fit, this method may _move_ them out towards a parent + that does allow the given node to be placed. When the given range + completely covers a parent node, this method may completely replace + that parent node. + */ + replaceRangeWith(from3, to, node) { + replaceRangeWith(this, from3, to, node); + return this; + } + /** + Delete the given range, expanding it to cover fully covered + parent nodes until a valid replace is found. + */ + deleteRange(from3, to) { + deleteRange(this, from3, to); + return this; + } + /** + Split the content in the given range off from its parent, if there + is sibling content before or after it, and move it up the tree to + the depth specified by `target`. You'll probably want to use + [`liftTarget`](https://prosemirror.net/docs/ref/#transform.liftTarget) to compute `target`, to make + sure the lift is valid. + */ + lift(range, target) { + lift(this, range, target); + return this; + } + /** + Join the blocks around the given position. If depth is 2, their + last and first siblings are also joined, and so on. + */ + join(pos, depth = 1) { + join(this, pos, depth); + return this; + } + /** + Wrap the given [range](https://prosemirror.net/docs/ref/#model.NodeRange) in the given set of wrappers. + The wrappers are assumed to be valid in this position, and should + probably be computed with [`findWrapping`](https://prosemirror.net/docs/ref/#transform.findWrapping). + */ + wrap(range, wrappers) { + wrap(this, range, wrappers); + return this; + } + /** + Set the type of all textblocks (partly) between `from` and `to` to + the given node type with the given attributes. + */ + setBlockType(from3, to = from3, type, attrs = null) { + setBlockType(this, from3, to, type, attrs); + return this; + } + /** + Change the type, attributes, and/or marks of the node at `pos`. + When `type` isn't given, the existing node type is preserved, + */ + setNodeMarkup(pos, type, attrs = null, marks) { + setNodeMarkup(this, pos, type, attrs, marks); + return this; + } + /** + Set a single attribute on a given node to a new value. + The `pos` addresses the document content. Use `setDocAttribute` + to set attributes on the document itself. + */ + setNodeAttribute(pos, attr, value) { + this.step(new AttrStep(pos, attr, value)); + return this; + } + /** + Set a single attribute on the document to a new value. + */ + setDocAttribute(attr, value) { + this.step(new DocAttrStep(attr, value)); + return this; + } + /** + Add a mark to the node at position `pos`. + */ + addNodeMark(pos, mark) { + this.step(new AddNodeMarkStep(pos, mark)); + return this; + } + /** + Remove a mark (or all marks of the given type) from the node at + position `pos`. + */ + removeNodeMark(pos, mark) { + let node = this.doc.nodeAt(pos); + if (!node) + throw new RangeError("No node at position " + pos); + if (mark instanceof Mark) { + if (mark.isInSet(node.marks)) + this.step(new RemoveNodeMarkStep(pos, mark)); + } else { + let set = node.marks, found3, steps = []; + while (found3 = mark.isInSet(set)) { + steps.push(new RemoveNodeMarkStep(pos, found3)); + set = found3.removeFromSet(set); + } + for (let i = steps.length - 1; i >= 0; i--) + this.step(steps[i]); + } + return this; + } + /** + Split the node at the given position, and optionally, if `depth` is + greater than one, any number of nodes above that. By default, the + parts split off will inherit the node type of the original node. + This can be changed by passing an array of types and attributes to + use after the split (with the outermost nodes coming first). + */ + split(pos, depth = 1, typesAfter) { + split(this, pos, depth, typesAfter); + return this; + } + /** + Add the given mark to the inline content between `from` and `to`. + */ + addMark(from3, to, mark) { + addMark(this, from3, to, mark); + return this; + } + /** + Remove marks from inline nodes between `from` and `to`. When + `mark` is a single mark, remove precisely that mark. When it is + a mark type, remove all marks of that type. When it is null, + remove all marks of any type. + */ + removeMark(from3, to, mark) { + removeMark(this, from3, to, mark); + return this; + } + /** + Removes all marks and nodes from the content of the node at + `pos` that don't match the given new parent node type. Accepts + an optional starting [content match](https://prosemirror.net/docs/ref/#model.ContentMatch) as + third argument. + */ + clearIncompatible(pos, parentType, match2) { + clearIncompatible(this, pos, parentType, match2); + return this; + } +}; + +// ../../node_modules/.pnpm/prosemirror-state@1.4.4/node_modules/prosemirror-state/dist/index.js +var classesById = /* @__PURE__ */ Object.create(null); +var Selection = class { + /** + Initialize a selection with the head and anchor and ranges. If no + ranges are given, constructs a single range across `$anchor` and + `$head`. + */ + constructor($anchor, $head, ranges) { + this.$anchor = $anchor; + this.$head = $head; + this.ranges = ranges || [new SelectionRange($anchor.min($head), $anchor.max($head))]; + } + /** + The selection's anchor, as an unresolved position. + */ + get anchor() { + return this.$anchor.pos; + } + /** + The selection's head. + */ + get head() { + return this.$head.pos; + } + /** + The lower bound of the selection's main range. + */ + get from() { + return this.$from.pos; + } + /** + The upper bound of the selection's main range. + */ + get to() { + return this.$to.pos; + } + /** + The resolved lower bound of the selection's main range. + */ + get $from() { + return this.ranges[0].$from; + } + /** + The resolved upper bound of the selection's main range. + */ + get $to() { + return this.ranges[0].$to; + } + /** + Indicates whether the selection contains any content. + */ + get empty() { + let ranges = this.ranges; + for (let i = 0; i < ranges.length; i++) + if (ranges[i].$from.pos != ranges[i].$to.pos) + return false; + return true; + } + /** + Get the content of this selection as a slice. + */ + content() { + return this.$from.doc.slice(this.from, this.to, true); + } + /** + Replace the selection with a slice or, if no slice is given, + delete the selection. Will append to the given transaction. + */ + replace(tr2, content = Slice.empty) { + let lastNode = content.content.lastChild, lastParent = null; + for (let i = 0; i < content.openEnd; i++) { + lastParent = lastNode; + lastNode = lastNode.lastChild; + } + let mapFrom = tr2.steps.length, ranges = this.ranges; + for (let i = 0; i < ranges.length; i++) { + let { $from, $to } = ranges[i], mapping = tr2.mapping.slice(mapFrom); + tr2.replaceRange(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content); + if (i == 0) + selectionToInsertionEnd(tr2, mapFrom, (lastNode ? lastNode.isInline : lastParent && lastParent.isTextblock) ? -1 : 1); + } + } + /** + Replace the selection with the given node, appending the changes + to the given transaction. + */ + replaceWith(tr2, node) { + let mapFrom = tr2.steps.length, ranges = this.ranges; + for (let i = 0; i < ranges.length; i++) { + let { $from, $to } = ranges[i], mapping = tr2.mapping.slice(mapFrom); + let from3 = mapping.map($from.pos), to = mapping.map($to.pos); + if (i) { + tr2.deleteRange(from3, to); + } else { + tr2.replaceRangeWith(from3, to, node); + selectionToInsertionEnd(tr2, mapFrom, node.isInline ? -1 : 1); + } + } + } + /** + Find a valid cursor or leaf node selection starting at the given + position and searching back if `dir` is negative, and forward if + positive. When `textOnly` is true, only consider cursor + selections. Will return null when no valid selection position is + found. + */ + static findFrom($pos, dir, textOnly = false) { + let inner = $pos.parent.inlineContent ? new TextSelection($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly); + if (inner) + return inner; + for (let depth = $pos.depth - 1; depth >= 0; depth--) { + let found3 = dir < 0 ? findSelectionIn($pos.node(0), $pos.node(depth), $pos.before(depth + 1), $pos.index(depth), dir, textOnly) : findSelectionIn($pos.node(0), $pos.node(depth), $pos.after(depth + 1), $pos.index(depth) + 1, dir, textOnly); + if (found3) + return found3; + } + return null; + } + /** + Find a valid cursor or leaf node selection near the given + position. Searches forward first by default, but if `bias` is + negative, it will search backwards first. + */ + static near($pos, bias = 1) { + return this.findFrom($pos, bias) || this.findFrom($pos, -bias) || new AllSelection($pos.node(0)); + } + /** + Find the cursor or leaf node selection closest to the start of + the given document. Will return an + [`AllSelection`](https://prosemirror.net/docs/ref/#state.AllSelection) if no valid position + exists. + */ + static atStart(doc4) { + return findSelectionIn(doc4, doc4, 0, 0, 1) || new AllSelection(doc4); + } + /** + Find the cursor or leaf node selection closest to the end of the + given document. + */ + static atEnd(doc4) { + return findSelectionIn(doc4, doc4, doc4.content.size, doc4.childCount, -1) || new AllSelection(doc4); + } + /** + Deserialize the JSON representation of a selection. Must be + implemented for custom classes (as a static class method). + */ + static fromJSON(doc4, json) { + if (!json || !json.type) + throw new RangeError("Invalid input for Selection.fromJSON"); + let cls = classesById[json.type]; + if (!cls) + throw new RangeError(`No selection type ${json.type} defined`); + return cls.fromJSON(doc4, json); + } + /** + To be able to deserialize selections from JSON, custom selection + classes must register themselves with an ID string, so that they + can be disambiguated. Try to pick something that's unlikely to + clash with classes from other modules. + */ + static jsonID(id2, selectionClass) { + if (id2 in classesById) + throw new RangeError("Duplicate use of selection JSON ID " + id2); + classesById[id2] = selectionClass; + selectionClass.prototype.jsonID = id2; + return selectionClass; + } + /** + Get a [bookmark](https://prosemirror.net/docs/ref/#state.SelectionBookmark) for this selection, + which is a value that can be mapped without having access to a + current document, and later resolved to a real selection for a + given document again. (This is used mostly by the history to + track and restore old selections.) The default implementation of + this method just converts the selection to a text selection and + returns the bookmark for that. + */ + getBookmark() { + return TextSelection.between(this.$anchor, this.$head).getBookmark(); + } +}; +Selection.prototype.visible = true; +var SelectionRange = class { + /** + Create a range. + */ + constructor($from, $to) { + this.$from = $from; + this.$to = $to; + } +}; +var warnedAboutTextSelection = false; +function checkTextSelection($pos) { + if (!warnedAboutTextSelection && !$pos.parent.inlineContent) { + warnedAboutTextSelection = true; + console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")"); + } +} +var TextSelection = class _TextSelection2 extends Selection { + /** + Construct a text selection between the given points. + */ + constructor($anchor, $head = $anchor) { + checkTextSelection($anchor); + checkTextSelection($head); + super($anchor, $head); + } + /** + Returns a resolved position if this is a cursor selection (an + empty text selection), and null otherwise. + */ + get $cursor() { + return this.$anchor.pos == this.$head.pos ? this.$head : null; + } + map(doc4, mapping) { + let $head = doc4.resolve(mapping.map(this.head)); + if (!$head.parent.inlineContent) + return Selection.near($head); + let $anchor = doc4.resolve(mapping.map(this.anchor)); + return new _TextSelection2($anchor.parent.inlineContent ? $anchor : $head, $head); + } + replace(tr2, content = Slice.empty) { + super.replace(tr2, content); + if (content == Slice.empty) { + let marks = this.$from.marksAcross(this.$to); + if (marks) + tr2.ensureMarks(marks); + } + } + eq(other) { + return other instanceof _TextSelection2 && other.anchor == this.anchor && other.head == this.head; + } + getBookmark() { + return new TextBookmark(this.anchor, this.head); + } + toJSON() { + return { type: "text", anchor: this.anchor, head: this.head }; + } + /** + @internal + */ + static fromJSON(doc4, json) { + if (typeof json.anchor != "number" || typeof json.head != "number") + throw new RangeError("Invalid input for TextSelection.fromJSON"); + return new _TextSelection2(doc4.resolve(json.anchor), doc4.resolve(json.head)); + } + /** + Create a text selection from non-resolved positions. + */ + static create(doc4, anchor, head = anchor) { + let $anchor = doc4.resolve(anchor); + return new this($anchor, head == anchor ? $anchor : doc4.resolve(head)); + } + /** + Return a text selection that spans the given positions or, if + they aren't text positions, find a text selection near them. + `bias` determines whether the method searches forward (default) + or backwards (negative number) first. Will fall back to calling + [`Selection.near`](https://prosemirror.net/docs/ref/#state.Selection^near) when the document + doesn't contain a valid text position. + */ + static between($anchor, $head, bias) { + let dPos = $anchor.pos - $head.pos; + if (!bias || dPos) + bias = dPos >= 0 ? 1 : -1; + if (!$head.parent.inlineContent) { + let found3 = Selection.findFrom($head, bias, true) || Selection.findFrom($head, -bias, true); + if (found3) + $head = found3.$head; + else + return Selection.near($head, bias); + } + if (!$anchor.parent.inlineContent) { + if (dPos == 0) { + $anchor = $head; + } else { + $anchor = (Selection.findFrom($anchor, -bias, true) || Selection.findFrom($anchor, bias, true)).$anchor; + if ($anchor.pos < $head.pos != dPos < 0) + $anchor = $head; + } + } + return new _TextSelection2($anchor, $head); + } +}; +Selection.jsonID("text", TextSelection); +var TextBookmark = class _TextBookmark2 { + constructor(anchor, head) { + this.anchor = anchor; + this.head = head; + } + map(mapping) { + return new _TextBookmark2(mapping.map(this.anchor), mapping.map(this.head)); + } + resolve(doc4) { + return TextSelection.between(doc4.resolve(this.anchor), doc4.resolve(this.head)); + } +}; +var NodeSelection = class _NodeSelection2 extends Selection { + /** + Create a node selection. Does not verify the validity of its + argument. + */ + constructor($pos) { + let node = $pos.nodeAfter; + let $end = $pos.node(0).resolve($pos.pos + node.nodeSize); + super($pos, $end); + this.node = node; + } + map(doc4, mapping) { + let { deleted, pos } = mapping.mapResult(this.anchor); + let $pos = doc4.resolve(pos); + if (deleted) + return Selection.near($pos); + return new _NodeSelection2($pos); + } + content() { + return new Slice(Fragment.from(this.node), 0, 0); + } + eq(other) { + return other instanceof _NodeSelection2 && other.anchor == this.anchor; + } + toJSON() { + return { type: "node", anchor: this.anchor }; + } + getBookmark() { + return new NodeBookmark(this.anchor); + } + /** + @internal + */ + static fromJSON(doc4, json) { + if (typeof json.anchor != "number") + throw new RangeError("Invalid input for NodeSelection.fromJSON"); + return new _NodeSelection2(doc4.resolve(json.anchor)); + } + /** + Create a node selection from non-resolved positions. + */ + static create(doc4, from3) { + return new _NodeSelection2(doc4.resolve(from3)); + } + /** + Determines whether the given node may be selected as a node + selection. + */ + static isSelectable(node) { + return !node.isText && node.type.spec.selectable !== false; + } +}; +NodeSelection.prototype.visible = false; +Selection.jsonID("node", NodeSelection); +var NodeBookmark = class _NodeBookmark2 { + constructor(anchor) { + this.anchor = anchor; + } + map(mapping) { + let { deleted, pos } = mapping.mapResult(this.anchor); + return deleted ? new TextBookmark(pos, pos) : new _NodeBookmark2(pos); + } + resolve(doc4) { + let $pos = doc4.resolve(this.anchor), node = $pos.nodeAfter; + if (node && NodeSelection.isSelectable(node)) + return new NodeSelection($pos); + return Selection.near($pos); + } +}; +var AllSelection = class _AllSelection2 extends Selection { + /** + Create an all-selection over the given document. + */ + constructor(doc4) { + super(doc4.resolve(0), doc4.resolve(doc4.content.size)); + } + replace(tr2, content = Slice.empty) { + if (content == Slice.empty) { + tr2.delete(0, tr2.doc.content.size); + let sel = Selection.atStart(tr2.doc); + if (!sel.eq(tr2.selection)) + tr2.setSelection(sel); + } else { + super.replace(tr2, content); + } + } + toJSON() { + return { type: "all" }; + } + /** + @internal + */ + static fromJSON(doc4) { + return new _AllSelection2(doc4); + } + map(doc4) { + return new _AllSelection2(doc4); + } + eq(other) { + return other instanceof _AllSelection2; + } + getBookmark() { + return AllBookmark; + } +}; +Selection.jsonID("all", AllSelection); +var AllBookmark = { + map() { + return this; + }, + resolve(doc4) { + return new AllSelection(doc4); + } +}; +function findSelectionIn(doc4, node, pos, index, dir, text2 = false) { + if (node.inlineContent) + return TextSelection.create(doc4, pos); + for (let i = index - (dir > 0 ? 0 : 1); dir > 0 ? i < node.childCount : i >= 0; i += dir) { + let child = node.child(i); + if (!child.isAtom) { + let inner = findSelectionIn(doc4, child, pos + dir, dir < 0 ? child.childCount : 0, dir, text2); + if (inner) + return inner; + } else if (!text2 && NodeSelection.isSelectable(child)) { + return NodeSelection.create(doc4, pos - (dir < 0 ? child.nodeSize : 0)); + } + pos += child.nodeSize * dir; + } + return null; +} +function selectionToInsertionEnd(tr2, startLen, bias) { + let last2 = tr2.steps.length - 1; + if (last2 < startLen) + return; + let step = tr2.steps[last2]; + if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) + return; + let map4 = tr2.mapping.maps[last2], end; + map4.forEach((_from, _to, _newFrom, newTo) => { + if (end == null) + end = newTo; + }); + tr2.setSelection(Selection.near(tr2.doc.resolve(end), bias)); +} +var UPDATED_SEL = 1; +var UPDATED_MARKS = 2; +var UPDATED_SCROLL = 4; +var Transaction = class extends Transform { + /** + @internal + */ + constructor(state) { + super(state.doc); + this.curSelectionFor = 0; + this.updated = 0; + this.meta = /* @__PURE__ */ Object.create(null); + this.time = Date.now(); + this.curSelection = state.selection; + this.storedMarks = state.storedMarks; + } + /** + The transaction's current selection. This defaults to the editor + selection [mapped](https://prosemirror.net/docs/ref/#state.Selection.map) through the steps in the + transaction, but can be overwritten with + [`setSelection`](https://prosemirror.net/docs/ref/#state.Transaction.setSelection). + */ + get selection() { + if (this.curSelectionFor < this.steps.length) { + this.curSelection = this.curSelection.map(this.doc, this.mapping.slice(this.curSelectionFor)); + this.curSelectionFor = this.steps.length; + } + return this.curSelection; + } + /** + Update the transaction's current selection. Will determine the + selection that the editor gets when the transaction is applied. + */ + setSelection(selection) { + if (selection.$from.doc != this.doc) + throw new RangeError("Selection passed to setSelection must point at the current document"); + this.curSelection = selection; + this.curSelectionFor = this.steps.length; + this.updated = (this.updated | UPDATED_SEL) & ~UPDATED_MARKS; + this.storedMarks = null; + return this; + } + /** + Whether the selection was explicitly updated by this transaction. + */ + get selectionSet() { + return (this.updated & UPDATED_SEL) > 0; + } + /** + Set the current stored marks. + */ + setStoredMarks(marks) { + this.storedMarks = marks; + this.updated |= UPDATED_MARKS; + return this; + } + /** + Make sure the current stored marks or, if that is null, the marks + at the selection, match the given set of marks. Does nothing if + this is already the case. + */ + ensureMarks(marks) { + if (!Mark.sameSet(this.storedMarks || this.selection.$from.marks(), marks)) + this.setStoredMarks(marks); + return this; + } + /** + Add a mark to the set of stored marks. + */ + addStoredMark(mark) { + return this.ensureMarks(mark.addToSet(this.storedMarks || this.selection.$head.marks())); + } + /** + Remove a mark or mark type from the set of stored marks. + */ + removeStoredMark(mark) { + return this.ensureMarks(mark.removeFromSet(this.storedMarks || this.selection.$head.marks())); + } + /** + Whether the stored marks were explicitly set for this transaction. + */ + get storedMarksSet() { + return (this.updated & UPDATED_MARKS) > 0; + } + /** + @internal + */ + addStep(step, doc4) { + super.addStep(step, doc4); + this.updated = this.updated & ~UPDATED_MARKS; + this.storedMarks = null; + } + /** + Update the timestamp for the transaction. + */ + setTime(time) { + this.time = time; + return this; + } + /** + Replace the current selection with the given slice. + */ + replaceSelection(slice2) { + this.selection.replace(this, slice2); + return this; + } + /** + Replace the selection with the given node. When `inheritMarks` is + true and the content is inline, it inherits the marks from the + place where it is inserted. + */ + replaceSelectionWith(node, inheritMarks = true) { + let selection = this.selection; + if (inheritMarks) + node = node.mark(this.storedMarks || (selection.empty ? selection.$from.marks() : selection.$from.marksAcross(selection.$to) || Mark.none)); + selection.replaceWith(this, node); + return this; + } + /** + Delete the selection. + */ + deleteSelection() { + this.selection.replace(this); + return this; + } + /** + Replace the given range, or the selection if no range is given, + with a text node containing the given string. + */ + insertText(text2, from3, to) { + let schema = this.doc.type.schema; + if (from3 == null) { + if (!text2) + return this.deleteSelection(); + return this.replaceSelectionWith(schema.text(text2), true); + } else { + if (to == null) + to = from3; + if (!text2) + return this.deleteRange(from3, to); + let marks = this.storedMarks; + if (!marks) { + let $from = this.doc.resolve(from3); + marks = to == from3 ? $from.marks() : $from.marksAcross(this.doc.resolve(to)); + } + this.replaceRangeWith(from3, to, schema.text(text2, marks)); + if (!this.selection.empty && this.selection.to == from3 + text2.length) + this.setSelection(Selection.near(this.selection.$to)); + return this; + } + } + /** + Store a metadata property in this transaction, keyed either by + name or by plugin. + */ + setMeta(key, value) { + this.meta[typeof key == "string" ? key : key.key] = value; + return this; + } + /** + Retrieve a metadata property for a given name or plugin. + */ + getMeta(key) { + return this.meta[typeof key == "string" ? key : key.key]; + } + /** + Returns true if this transaction doesn't contain any metadata, + and can thus safely be extended. + */ + get isGeneric() { + for (let _2 in this.meta) + return false; + return true; + } + /** + Indicate that the editor should scroll the selection into view + when updated to the state produced by this transaction. + */ + scrollIntoView() { + this.updated |= UPDATED_SCROLL; + return this; + } + /** + True when this transaction has had `scrollIntoView` called on it. + */ + get scrolledIntoView() { + return (this.updated & UPDATED_SCROLL) > 0; + } +}; +function bind(f, self) { + return !self || !f ? f : f.bind(self); +} +var FieldDesc = class { + constructor(name, desc, self) { + this.name = name; + this.init = bind(desc.init, self); + this.apply = bind(desc.apply, self); + } +}; +var baseFields = [ + new FieldDesc("doc", { + init(config) { + return config.doc || config.schema.topNodeType.createAndFill(); + }, + apply(tr2) { + return tr2.doc; + } + }), + new FieldDesc("selection", { + init(config, instance) { + return config.selection || Selection.atStart(instance.doc); + }, + apply(tr2) { + return tr2.selection; + } + }), + new FieldDesc("storedMarks", { + init(config) { + return config.storedMarks || null; + }, + apply(tr2, _marks, _old, state) { + return state.selection.$cursor ? tr2.storedMarks : null; + } + }), + new FieldDesc("scrollToSelection", { + init() { + return 0; + }, + apply(tr2, prev) { + return tr2.scrolledIntoView ? prev + 1 : prev; + } + }) +]; +var Configuration = class { + constructor(schema, plugins) { + this.schema = schema; + this.plugins = []; + this.pluginsByKey = /* @__PURE__ */ Object.create(null); + this.fields = baseFields.slice(); + if (plugins) + plugins.forEach((plugin) => { + if (this.pluginsByKey[plugin.key]) + throw new RangeError("Adding different instances of a keyed plugin (" + plugin.key + ")"); + this.plugins.push(plugin); + this.pluginsByKey[plugin.key] = plugin; + if (plugin.spec.state) + this.fields.push(new FieldDesc(plugin.key, plugin.spec.state, plugin)); + }); + } +}; +var EditorState = class _EditorState { + /** + @internal + */ + constructor(config) { + this.config = config; + } + /** + The schema of the state's document. + */ + get schema() { + return this.config.schema; + } + /** + The plugins that are active in this state. + */ + get plugins() { + return this.config.plugins; + } + /** + Apply the given transaction to produce a new state. + */ + apply(tr2) { + return this.applyTransaction(tr2).state; + } + /** + @internal + */ + filterTransaction(tr2, ignore = -1) { + for (let i = 0; i < this.config.plugins.length; i++) + if (i != ignore) { + let plugin = this.config.plugins[i]; + if (plugin.spec.filterTransaction && !plugin.spec.filterTransaction.call(plugin, tr2, this)) + return false; + } + return true; + } + /** + Verbose variant of [`apply`](https://prosemirror.net/docs/ref/#state.EditorState.apply) that + returns the precise transactions that were applied (which might + be influenced by the [transaction + hooks](https://prosemirror.net/docs/ref/#state.PluginSpec.filterTransaction) of + plugins) along with the new state. + */ + applyTransaction(rootTr) { + if (!this.filterTransaction(rootTr)) + return { state: this, transactions: [] }; + let trs = [rootTr], newState = this.applyInner(rootTr), seen = null; + for (; ; ) { + let haveNew = false; + for (let i = 0; i < this.config.plugins.length; i++) { + let plugin = this.config.plugins[i]; + if (plugin.spec.appendTransaction) { + let n = seen ? seen[i].n : 0, oldState = seen ? seen[i].state : this; + let tr2 = n < trs.length && plugin.spec.appendTransaction.call(plugin, n ? trs.slice(n) : trs, oldState, newState); + if (tr2 && newState.filterTransaction(tr2, i)) { + tr2.setMeta("appendedTransaction", rootTr); + if (!seen) { + seen = []; + for (let j2 = 0; j2 < this.config.plugins.length; j2++) + seen.push(j2 < i ? { state: newState, n: trs.length } : { state: this, n: 0 }); + } + trs.push(tr2); + newState = newState.applyInner(tr2); + haveNew = true; + } + if (seen) + seen[i] = { state: newState, n: trs.length }; + } + } + if (!haveNew) + return { state: newState, transactions: trs }; + } + } + /** + @internal + */ + applyInner(tr2) { + if (!tr2.before.eq(this.doc)) + throw new RangeError("Applying a mismatched transaction"); + let newInstance = new _EditorState(this.config), fields = this.config.fields; + for (let i = 0; i < fields.length; i++) { + let field = fields[i]; + newInstance[field.name] = field.apply(tr2, this[field.name], this, newInstance); + } + return newInstance; + } + /** + Accessor that constructs and returns a new [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state. + */ + get tr() { + return new Transaction(this); + } + /** + Create a new state. + */ + static create(config) { + let $config = new Configuration(config.doc ? config.doc.type.schema : config.schema, config.plugins); + let instance = new _EditorState($config); + for (let i = 0; i < $config.fields.length; i++) + instance[$config.fields[i].name] = $config.fields[i].init(config, instance); + return instance; + } + /** + Create a new state based on this one, but with an adjusted set + of active plugins. State fields that exist in both sets of + plugins are kept unchanged. Those that no longer exist are + dropped, and those that are new are initialized using their + [`init`](https://prosemirror.net/docs/ref/#state.StateField.init) method, passing in the new + configuration object.. + */ + reconfigure(config) { + let $config = new Configuration(this.schema, config.plugins); + let fields = $config.fields, instance = new _EditorState($config); + for (let i = 0; i < fields.length; i++) { + let name = fields[i].name; + instance[name] = this.hasOwnProperty(name) ? this[name] : fields[i].init(config, instance); + } + return instance; + } + /** + Serialize this state to JSON. If you want to serialize the state + of plugins, pass an object mapping property names to use in the + resulting JSON object to plugin objects. The argument may also be + a string or number, in which case it is ignored, to support the + way `JSON.stringify` calls `toString` methods. + */ + toJSON(pluginFields) { + let result = { doc: this.doc.toJSON(), selection: this.selection.toJSON() }; + if (this.storedMarks) + result.storedMarks = this.storedMarks.map((m2) => m2.toJSON()); + if (pluginFields && typeof pluginFields == "object") + for (let prop in pluginFields) { + if (prop == "doc" || prop == "selection") + throw new RangeError("The JSON fields `doc` and `selection` are reserved"); + let plugin = pluginFields[prop], state = plugin.spec.state; + if (state && state.toJSON) + result[prop] = state.toJSON.call(plugin, this[plugin.key]); + } + return result; + } + /** + Deserialize a JSON representation of a state. `config` should + have at least a `schema` field, and should contain array of + plugins to initialize the state with. `pluginFields` can be used + to deserialize the state of plugins, by associating plugin + instances with the property names they use in the JSON object. + */ + static fromJSON(config, json, pluginFields) { + if (!json) + throw new RangeError("Invalid input for EditorState.fromJSON"); + if (!config.schema) + throw new RangeError("Required config field 'schema' missing"); + let $config = new Configuration(config.schema, config.plugins); + let instance = new _EditorState($config); + $config.fields.forEach((field) => { + if (field.name == "doc") { + instance.doc = Node.fromJSON(config.schema, json.doc); + } else if (field.name == "selection") { + instance.selection = Selection.fromJSON(instance.doc, json.selection); + } else if (field.name == "storedMarks") { + if (json.storedMarks) + instance.storedMarks = json.storedMarks.map(config.schema.markFromJSON); + } else { + if (pluginFields) + for (let prop in pluginFields) { + let plugin = pluginFields[prop], state = plugin.spec.state; + if (plugin.key == field.name && state && state.fromJSON && Object.prototype.hasOwnProperty.call(json, prop)) { + instance[field.name] = state.fromJSON.call(plugin, config, json[prop], instance); + return; + } + } + instance[field.name] = field.init(config, instance); + } + }); + return instance; + } +}; +function bindProps(obj, self, target) { + for (let prop in obj) { + let val = obj[prop]; + if (val instanceof Function) + val = val.bind(self); + else if (prop == "handleDOMEvents") + val = bindProps(val, self, {}); + target[prop] = val; + } + return target; +} +var Plugin = class { + /** + Create a plugin. + */ + constructor(spec) { + this.spec = spec; + this.props = {}; + if (spec.props) + bindProps(spec.props, this, this.props); + this.key = spec.key ? spec.key.key : createKey("plugin"); + } + /** + Extract the plugin's state field from an editor state. + */ + getState(state) { + return state[this.key]; + } +}; +var keys = /* @__PURE__ */ Object.create(null); +function createKey(name) { + if (name in keys) + return name + "$" + ++keys[name]; + keys[name] = 0; + return name + "$"; +} +var PluginKey = class { + /** + Create a plugin key. + */ + constructor(name = "key") { + this.key = createKey(name); + } + /** + Get the active plugin with this key, if any, from an editor + state. + */ + get(state) { + return state.config.pluginsByKey[this.key]; + } + /** + Get the plugin's state from an editor state. + */ + getState(state) { + return state[this.key]; + } +}; + +// ../../node_modules/.pnpm/prosemirror-commands@1.7.1/node_modules/prosemirror-commands/dist/index.js +var deleteSelection = (state, dispatch) => { + if (state.selection.empty) + return false; + if (dispatch) + dispatch(state.tr.deleteSelection().scrollIntoView()); + return true; +}; +function atBlockStart(state, view) { + let { $cursor } = state.selection; + if (!$cursor || (view ? !view.endOfTextblock("backward", state) : $cursor.parentOffset > 0)) + return null; + return $cursor; +} +var joinBackward = (state, dispatch, view) => { + let $cursor = atBlockStart(state, view); + if (!$cursor) + return false; + let $cut = findCutBefore($cursor); + if (!$cut) { + let range = $cursor.blockRange(), target = range && liftTarget(range); + if (target == null) + return false; + if (dispatch) + dispatch(state.tr.lift(range, target).scrollIntoView()); + return true; + } + let before = $cut.nodeBefore; + if (deleteBarrier(state, $cut, dispatch, -1)) + return true; + if ($cursor.parent.content.size == 0 && (textblockAt(before, "end") || NodeSelection.isSelectable(before))) { + for (let depth = $cursor.depth; ; depth--) { + let delStep = replaceStep(state.doc, $cursor.before(depth), $cursor.after(depth), Slice.empty); + if (delStep && delStep.slice.size < delStep.to - delStep.from) { + if (dispatch) { + let tr2 = state.tr.step(delStep); + tr2.setSelection(textblockAt(before, "end") ? Selection.findFrom(tr2.doc.resolve(tr2.mapping.map($cut.pos, -1)), -1) : NodeSelection.create(tr2.doc, $cut.pos - before.nodeSize)); + dispatch(tr2.scrollIntoView()); + } + return true; + } + if (depth == 1 || $cursor.node(depth - 1).childCount > 1) + break; + } + } + if (before.isAtom && $cut.depth == $cursor.depth - 1) { + if (dispatch) + dispatch(state.tr.delete($cut.pos - before.nodeSize, $cut.pos).scrollIntoView()); + return true; + } + return false; +}; +var joinTextblockBackward = (state, dispatch, view) => { + let $cursor = atBlockStart(state, view); + if (!$cursor) + return false; + let $cut = findCutBefore($cursor); + return $cut ? joinTextblocksAround(state, $cut, dispatch) : false; +}; +var joinTextblockForward = (state, dispatch, view) => { + let $cursor = atBlockEnd(state, view); + if (!$cursor) + return false; + let $cut = findCutAfter($cursor); + return $cut ? joinTextblocksAround(state, $cut, dispatch) : false; +}; +function joinTextblocksAround(state, $cut, dispatch) { + let before = $cut.nodeBefore, beforeText = before, beforePos = $cut.pos - 1; + for (; !beforeText.isTextblock; beforePos--) { + if (beforeText.type.spec.isolating) + return false; + let child = beforeText.lastChild; + if (!child) + return false; + beforeText = child; + } + let after = $cut.nodeAfter, afterText = after, afterPos = $cut.pos + 1; + for (; !afterText.isTextblock; afterPos++) { + if (afterText.type.spec.isolating) + return false; + let child = afterText.firstChild; + if (!child) + return false; + afterText = child; + } + let step = replaceStep(state.doc, beforePos, afterPos, Slice.empty); + if (!step || step.from != beforePos || step instanceof ReplaceStep && step.slice.size >= afterPos - beforePos) + return false; + if (dispatch) { + let tr2 = state.tr.step(step); + tr2.setSelection(TextSelection.create(tr2.doc, beforePos)); + dispatch(tr2.scrollIntoView()); + } + return true; +} +function textblockAt(node, side, only = false) { + for (let scan = node; scan; scan = side == "start" ? scan.firstChild : scan.lastChild) { + if (scan.isTextblock) + return true; + if (only && scan.childCount != 1) + return false; + } + return false; +} +var selectNodeBackward = (state, dispatch, view) => { + let { $head, empty: empty2 } = state.selection, $cut = $head; + if (!empty2) + return false; + if ($head.parent.isTextblock) { + if (view ? !view.endOfTextblock("backward", state) : $head.parentOffset > 0) + return false; + $cut = findCutBefore($head); + } + let node = $cut && $cut.nodeBefore; + if (!node || !NodeSelection.isSelectable(node)) + return false; + if (dispatch) + dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos - node.nodeSize)).scrollIntoView()); + return true; +}; +function findCutBefore($pos) { + if (!$pos.parent.type.spec.isolating) + for (let i = $pos.depth - 1; i >= 0; i--) { + if ($pos.index(i) > 0) + return $pos.doc.resolve($pos.before(i + 1)); + if ($pos.node(i).type.spec.isolating) + break; + } + return null; +} +function atBlockEnd(state, view) { + let { $cursor } = state.selection; + if (!$cursor || (view ? !view.endOfTextblock("forward", state) : $cursor.parentOffset < $cursor.parent.content.size)) + return null; + return $cursor; +} +var joinForward = (state, dispatch, view) => { + let $cursor = atBlockEnd(state, view); + if (!$cursor) + return false; + let $cut = findCutAfter($cursor); + if (!$cut) + return false; + let after = $cut.nodeAfter; + if (deleteBarrier(state, $cut, dispatch, 1)) + return true; + if ($cursor.parent.content.size == 0 && (textblockAt(after, "start") || NodeSelection.isSelectable(after))) { + let delStep = replaceStep(state.doc, $cursor.before(), $cursor.after(), Slice.empty); + if (delStep && delStep.slice.size < delStep.to - delStep.from) { + if (dispatch) { + let tr2 = state.tr.step(delStep); + tr2.setSelection(textblockAt(after, "start") ? Selection.findFrom(tr2.doc.resolve(tr2.mapping.map($cut.pos)), 1) : NodeSelection.create(tr2.doc, tr2.mapping.map($cut.pos))); + dispatch(tr2.scrollIntoView()); + } + return true; + } + } + if (after.isAtom && $cut.depth == $cursor.depth - 1) { + if (dispatch) + dispatch(state.tr.delete($cut.pos, $cut.pos + after.nodeSize).scrollIntoView()); + return true; + } + return false; +}; +var selectNodeForward = (state, dispatch, view) => { + let { $head, empty: empty2 } = state.selection, $cut = $head; + if (!empty2) + return false; + if ($head.parent.isTextblock) { + if (view ? !view.endOfTextblock("forward", state) : $head.parentOffset < $head.parent.content.size) + return false; + $cut = findCutAfter($head); + } + let node = $cut && $cut.nodeAfter; + if (!node || !NodeSelection.isSelectable(node)) + return false; + if (dispatch) + dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos)).scrollIntoView()); + return true; +}; +function findCutAfter($pos) { + if (!$pos.parent.type.spec.isolating) + for (let i = $pos.depth - 1; i >= 0; i--) { + let parent = $pos.node(i); + if ($pos.index(i) + 1 < parent.childCount) + return $pos.doc.resolve($pos.after(i + 1)); + if (parent.type.spec.isolating) + break; + } + return null; +} +var joinUp = (state, dispatch) => { + let sel = state.selection, nodeSel = sel instanceof NodeSelection, point; + if (nodeSel) { + if (sel.node.isTextblock || !canJoin(state.doc, sel.from)) + return false; + point = sel.from; + } else { + point = joinPoint(state.doc, sel.from, -1); + if (point == null) + return false; + } + if (dispatch) { + let tr2 = state.tr.join(point); + if (nodeSel) + tr2.setSelection(NodeSelection.create(tr2.doc, point - state.doc.resolve(point).nodeBefore.nodeSize)); + dispatch(tr2.scrollIntoView()); + } + return true; +}; +var joinDown = (state, dispatch) => { + let sel = state.selection, point; + if (sel instanceof NodeSelection) { + if (sel.node.isTextblock || !canJoin(state.doc, sel.to)) + return false; + point = sel.to; + } else { + point = joinPoint(state.doc, sel.to, 1); + if (point == null) + return false; + } + if (dispatch) + dispatch(state.tr.join(point).scrollIntoView()); + return true; +}; +var lift2 = (state, dispatch) => { + let { $from, $to } = state.selection; + let range = $from.blockRange($to), target = range && liftTarget(range); + if (target == null) + return false; + if (dispatch) + dispatch(state.tr.lift(range, target).scrollIntoView()); + return true; +}; +var newlineInCode = (state, dispatch) => { + let { $head, $anchor } = state.selection; + if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) + return false; + if (dispatch) + dispatch(state.tr.insertText("\n").scrollIntoView()); + return true; +}; +function defaultBlockAt(match2) { + for (let i = 0; i < match2.edgeCount; i++) { + let { type } = match2.edge(i); + if (type.isTextblock && !type.hasRequiredAttrs()) + return type; + } + return null; +} +var exitCode = (state, dispatch) => { + let { $head, $anchor } = state.selection; + if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) + return false; + let above = $head.node(-1), after = $head.indexAfter(-1), type = defaultBlockAt(above.contentMatchAt(after)); + if (!type || !above.canReplaceWith(after, after, type)) + return false; + if (dispatch) { + let pos = $head.after(), tr2 = state.tr.replaceWith(pos, pos, type.createAndFill()); + tr2.setSelection(Selection.near(tr2.doc.resolve(pos), 1)); + dispatch(tr2.scrollIntoView()); + } + return true; +}; +var createParagraphNear = (state, dispatch) => { + let sel = state.selection, { $from, $to } = sel; + if (sel instanceof AllSelection || $from.parent.inlineContent || $to.parent.inlineContent) + return false; + let type = defaultBlockAt($to.parent.contentMatchAt($to.indexAfter())); + if (!type || !type.isTextblock) + return false; + if (dispatch) { + let side = (!$from.parentOffset && $to.index() < $to.parent.childCount ? $from : $to).pos; + let tr2 = state.tr.insert(side, type.createAndFill()); + tr2.setSelection(TextSelection.create(tr2.doc, side + 1)); + dispatch(tr2.scrollIntoView()); + } + return true; +}; +var liftEmptyBlock = (state, dispatch) => { + let { $cursor } = state.selection; + if (!$cursor || $cursor.parent.content.size) + return false; + if ($cursor.depth > 1 && $cursor.after() != $cursor.end(-1)) { + let before = $cursor.before(); + if (canSplit(state.doc, before)) { + if (dispatch) + dispatch(state.tr.split(before).scrollIntoView()); + return true; + } + } + let range = $cursor.blockRange(), target = range && liftTarget(range); + if (target == null) + return false; + if (dispatch) + dispatch(state.tr.lift(range, target).scrollIntoView()); + return true; +}; +function splitBlockAs(splitNode) { + return (state, dispatch) => { + let { $from, $to } = state.selection; + if (state.selection instanceof NodeSelection && state.selection.node.isBlock) { + if (!$from.parentOffset || !canSplit(state.doc, $from.pos)) + return false; + if (dispatch) + dispatch(state.tr.split($from.pos).scrollIntoView()); + return true; + } + if (!$from.depth) + return false; + let types = []; + let splitDepth, deflt, atEnd = false, atStart = false; + for (let d2 = $from.depth; ; d2--) { + let node = $from.node(d2); + if (node.isBlock) { + atEnd = $from.end(d2) == $from.pos + ($from.depth - d2); + atStart = $from.start(d2) == $from.pos - ($from.depth - d2); + deflt = defaultBlockAt($from.node(d2 - 1).contentMatchAt($from.indexAfter(d2 - 1))); + let splitType = splitNode && splitNode($to.parent, atEnd, $from); + types.unshift(splitType || (atEnd && deflt ? { type: deflt } : null)); + splitDepth = d2; + break; + } else { + if (d2 == 1) + return false; + types.unshift(null); + } + } + let tr2 = state.tr; + if (state.selection instanceof TextSelection || state.selection instanceof AllSelection) + tr2.deleteSelection(); + let splitPos = tr2.mapping.map($from.pos); + let can = canSplit(tr2.doc, splitPos, types.length, types); + if (!can) { + types[0] = deflt ? { type: deflt } : null; + can = canSplit(tr2.doc, splitPos, types.length, types); + } + if (!can) + return false; + tr2.split(splitPos, types.length, types); + if (!atEnd && atStart && $from.node(splitDepth).type != deflt) { + let first2 = tr2.mapping.map($from.before(splitDepth)), $first = tr2.doc.resolve(first2); + if (deflt && $from.node(splitDepth - 1).canReplaceWith($first.index(), $first.index() + 1, deflt)) + tr2.setNodeMarkup(tr2.mapping.map($from.before(splitDepth)), deflt); + } + if (dispatch) + dispatch(tr2.scrollIntoView()); + return true; + }; +} +var splitBlock = splitBlockAs(); +var selectParentNode = (state, dispatch) => { + let { $from, to } = state.selection, pos; + let same = $from.sharedDepth(to); + if (same == 0) + return false; + pos = $from.before(same); + if (dispatch) + dispatch(state.tr.setSelection(NodeSelection.create(state.doc, pos))); + return true; +}; +var selectAll = (state, dispatch) => { + if (dispatch) + dispatch(state.tr.setSelection(new AllSelection(state.doc))); + return true; +}; +function joinMaybeClear(state, $pos, dispatch) { + let before = $pos.nodeBefore, after = $pos.nodeAfter, index = $pos.index(); + if (!before || !after || !before.type.compatibleContent(after.type)) + return false; + if (!before.content.size && $pos.parent.canReplace(index - 1, index)) { + if (dispatch) + dispatch(state.tr.delete($pos.pos - before.nodeSize, $pos.pos).scrollIntoView()); + return true; + } + if (!$pos.parent.canReplace(index, index + 1) || !(after.isTextblock || canJoin(state.doc, $pos.pos))) + return false; + if (dispatch) + dispatch(state.tr.join($pos.pos).scrollIntoView()); + return true; +} +function deleteBarrier(state, $cut, dispatch, dir) { + let before = $cut.nodeBefore, after = $cut.nodeAfter, conn, match2; + let isolated = before.type.spec.isolating || after.type.spec.isolating; + if (!isolated && joinMaybeClear(state, $cut, dispatch)) + return true; + let canDelAfter = !isolated && $cut.parent.canReplace($cut.index(), $cut.index() + 1); + if (canDelAfter && (conn = (match2 = before.contentMatchAt(before.childCount)).findWrapping(after.type)) && match2.matchType(conn[0] || after.type).validEnd) { + if (dispatch) { + let end = $cut.pos + after.nodeSize, wrap2 = Fragment.empty; + for (let i = conn.length - 1; i >= 0; i--) + wrap2 = Fragment.from(conn[i].create(null, wrap2)); + wrap2 = Fragment.from(before.copy(wrap2)); + let tr2 = state.tr.step(new ReplaceAroundStep($cut.pos - 1, end, $cut.pos, end, new Slice(wrap2, 1, 0), conn.length, true)); + let $joinAt = tr2.doc.resolve(end + 2 * conn.length); + if ($joinAt.nodeAfter && $joinAt.nodeAfter.type == before.type && canJoin(tr2.doc, $joinAt.pos)) + tr2.join($joinAt.pos); + dispatch(tr2.scrollIntoView()); + } + return true; + } + let selAfter = after.type.spec.isolating || dir > 0 && isolated ? null : Selection.findFrom($cut, 1); + let range = selAfter && selAfter.$from.blockRange(selAfter.$to), target = range && liftTarget(range); + if (target != null && target >= $cut.depth) { + if (dispatch) + dispatch(state.tr.lift(range, target).scrollIntoView()); + return true; + } + if (canDelAfter && textblockAt(after, "start", true) && textblockAt(before, "end")) { + let at = before, wrap2 = []; + for (; ; ) { + wrap2.push(at); + if (at.isTextblock) + break; + at = at.lastChild; + } + let afterText = after, afterDepth = 1; + for (; !afterText.isTextblock; afterText = afterText.firstChild) + afterDepth++; + if (at.canReplace(at.childCount, at.childCount, afterText.content)) { + if (dispatch) { + let end = Fragment.empty; + for (let i = wrap2.length - 1; i >= 0; i--) + end = Fragment.from(wrap2[i].copy(end)); + let tr2 = state.tr.step(new ReplaceAroundStep($cut.pos - wrap2.length, $cut.pos + after.nodeSize, $cut.pos + afterDepth, $cut.pos + after.nodeSize - afterDepth, new Slice(end, wrap2.length, 0), 0, true)); + dispatch(tr2.scrollIntoView()); + } + return true; + } + } + return false; +} +function selectTextblockSide(side) { + return function(state, dispatch) { + let sel = state.selection, $pos = side < 0 ? sel.$from : sel.$to; + let depth = $pos.depth; + while ($pos.node(depth).isInline) { + if (!depth) + return false; + depth--; + } + if (!$pos.node(depth).isTextblock) + return false; + if (dispatch) + dispatch(state.tr.setSelection(TextSelection.create(state.doc, side < 0 ? $pos.start(depth) : $pos.end(depth)))); + return true; + }; +} +var selectTextblockStart = selectTextblockSide(-1); +var selectTextblockEnd = selectTextblockSide(1); +function wrapIn(nodeType, attrs = null) { + return function(state, dispatch) { + let { $from, $to } = state.selection; + let range = $from.blockRange($to), wrapping = range && findWrapping(range, nodeType, attrs); + if (!wrapping) + return false; + if (dispatch) + dispatch(state.tr.wrap(range, wrapping).scrollIntoView()); + return true; + }; +} +function setBlockType2(nodeType, attrs = null) { + return function(state, dispatch) { + let applicable = false; + for (let i = 0; i < state.selection.ranges.length && !applicable; i++) { + let { $from: { pos: from3 }, $to: { pos: to } } = state.selection.ranges[i]; + state.doc.nodesBetween(from3, to, (node, pos) => { + if (applicable) + return false; + if (!node.isTextblock || node.hasMarkup(nodeType, attrs)) + return; + if (node.type == nodeType) { + applicable = true; + } else { + let $pos = state.doc.resolve(pos), index = $pos.index(); + applicable = $pos.parent.canReplaceWith(index, index + 1, nodeType); + } + }); + } + if (!applicable) + return false; + if (dispatch) { + let tr2 = state.tr; + for (let i = 0; i < state.selection.ranges.length; i++) { + let { $from: { pos: from3 }, $to: { pos: to } } = state.selection.ranges[i]; + tr2.setBlockType(from3, to, nodeType, attrs); + } + dispatch(tr2.scrollIntoView()); + } + return true; + }; +} +function chainCommands(...commands) { + return function(state, dispatch, view) { + for (let i = 0; i < commands.length; i++) + if (commands[i](state, dispatch, view)) + return true; + return false; + }; +} +var backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward); +var del = chainCommands(deleteSelection, joinForward, selectNodeForward); +var pcBaseKeymap = { + "Enter": chainCommands(newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock), + "Mod-Enter": exitCode, + "Backspace": backspace, + "Mod-Backspace": backspace, + "Shift-Backspace": backspace, + "Delete": del, + "Mod-Delete": del, + "Mod-a": selectAll +}; +var macBaseKeymap = { + "Ctrl-h": pcBaseKeymap["Backspace"], + "Alt-Backspace": pcBaseKeymap["Mod-Backspace"], + "Ctrl-d": pcBaseKeymap["Delete"], + "Ctrl-Alt-Backspace": pcBaseKeymap["Mod-Delete"], + "Alt-Delete": pcBaseKeymap["Mod-Delete"], + "Alt-d": pcBaseKeymap["Mod-Delete"], + "Ctrl-a": selectTextblockStart, + "Ctrl-e": selectTextblockEnd +}; +for (let key in pcBaseKeymap) + macBaseKeymap[key] = pcBaseKeymap[key]; +var mac = typeof navigator != "undefined" ? /Mac|iP(hone|[oa]d)/.test(navigator.platform) : typeof os != "undefined" && os.platform ? os.platform() == "darwin" : false; + +// ../../node_modules/.pnpm/prosemirror-schema-list@1.5.1/node_modules/prosemirror-schema-list/dist/index.js +function wrapInList(listType, attrs = null) { + return function(state, dispatch) { + let { $from, $to } = state.selection; + let range = $from.blockRange($to); + if (!range) + return false; + let tr2 = dispatch ? state.tr : null; + if (!wrapRangeInList(tr2, range, listType, attrs)) + return false; + if (dispatch) + dispatch(tr2.scrollIntoView()); + return true; + }; +} +function wrapRangeInList(tr2, range, listType, attrs = null) { + let doJoin = false, outerRange = range, doc4 = range.$from.doc; + if (range.depth >= 2 && range.$from.node(range.depth - 1).type.compatibleContent(listType) && range.startIndex == 0) { + if (range.$from.index(range.depth - 1) == 0) + return false; + let $insert = doc4.resolve(range.start - 2); + outerRange = new NodeRange($insert, $insert, range.depth); + if (range.endIndex < range.parent.childCount) + range = new NodeRange(range.$from, doc4.resolve(range.$to.end(range.depth)), range.depth); + doJoin = true; + } + let wrap2 = findWrapping(outerRange, listType, attrs, range); + if (!wrap2) + return false; + if (tr2) + doWrapInList(tr2, range, wrap2, doJoin, listType); + return true; +} +function doWrapInList(tr2, range, wrappers, joinBefore, listType) { + let content = Fragment.empty; + for (let i = wrappers.length - 1; i >= 0; i--) + content = Fragment.from(wrappers[i].type.create(wrappers[i].attrs, content)); + tr2.step(new ReplaceAroundStep(range.start - (joinBefore ? 2 : 0), range.end, range.start, range.end, new Slice(content, 0, 0), wrappers.length, true)); + let found3 = 0; + for (let i = 0; i < wrappers.length; i++) + if (wrappers[i].type == listType) + found3 = i + 1; + let splitDepth = wrappers.length - found3; + let splitPos = range.start + wrappers.length - (joinBefore ? 2 : 0), parent = range.parent; + for (let i = range.startIndex, e = range.endIndex, first2 = true; i < e; i++, first2 = false) { + if (!first2 && canSplit(tr2.doc, splitPos, splitDepth)) { + tr2.split(splitPos, splitDepth); + splitPos += 2 * splitDepth; + } + splitPos += parent.child(i).nodeSize; + } + return tr2; +} +function liftListItem(itemType) { + return function(state, dispatch) { + let { $from, $to } = state.selection; + let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType); + if (!range) + return false; + if (!dispatch) + return true; + if ($from.node(range.depth - 1).type == itemType) + return liftToOuterList(state, dispatch, itemType, range); + else + return liftOutOfList(state, dispatch, range); + }; +} +function liftToOuterList(state, dispatch, itemType, range) { + let tr2 = state.tr, end = range.end, endOfList = range.$to.end(range.depth); + if (end < endOfList) { + tr2.step(new ReplaceAroundStep(end - 1, endOfList, end, endOfList, new Slice(Fragment.from(itemType.create(null, range.parent.copy())), 1, 0), 1, true)); + range = new NodeRange(tr2.doc.resolve(range.$from.pos), tr2.doc.resolve(endOfList), range.depth); + } + const target = liftTarget(range); + if (target == null) + return false; + tr2.lift(range, target); + let $after = tr2.doc.resolve(tr2.mapping.map(end, -1) - 1); + if (canJoin(tr2.doc, $after.pos) && $after.nodeBefore.type == $after.nodeAfter.type) + tr2.join($after.pos); + dispatch(tr2.scrollIntoView()); + return true; +} +function liftOutOfList(state, dispatch, range) { + let tr2 = state.tr, list = range.parent; + for (let pos = range.end, i = range.endIndex - 1, e = range.startIndex; i > e; i--) { + pos -= list.child(i).nodeSize; + tr2.delete(pos - 1, pos + 1); + } + let $start = tr2.doc.resolve(range.start), item = $start.nodeAfter; + if (tr2.mapping.map(range.end) != range.start + $start.nodeAfter.nodeSize) + return false; + let atStart = range.startIndex == 0, atEnd = range.endIndex == list.childCount; + let parent = $start.node(-1), indexBefore = $start.index(-1); + if (!parent.canReplace(indexBefore + (atStart ? 0 : 1), indexBefore + 1, item.content.append(atEnd ? Fragment.empty : Fragment.from(list)))) + return false; + let start = $start.pos, end = start + item.nodeSize; + tr2.step(new ReplaceAroundStep(start - (atStart ? 1 : 0), end + (atEnd ? 1 : 0), start + 1, end - 1, new Slice((atStart ? Fragment.empty : Fragment.from(list.copy(Fragment.empty))).append(atEnd ? Fragment.empty : Fragment.from(list.copy(Fragment.empty))), atStart ? 0 : 1, atEnd ? 0 : 1), atStart ? 0 : 1)); + dispatch(tr2.scrollIntoView()); + return true; +} +function sinkListItem(itemType) { + return function(state, dispatch) { + let { $from, $to } = state.selection; + let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType); + if (!range) + return false; + let startIndex = range.startIndex; + if (startIndex == 0) + return false; + let parent = range.parent, nodeBefore = parent.child(startIndex - 1); + if (nodeBefore.type != itemType) + return false; + if (dispatch) { + let nestedBefore = nodeBefore.lastChild && nodeBefore.lastChild.type == parent.type; + let inner = Fragment.from(nestedBefore ? itemType.create() : null); + let slice2 = new Slice(Fragment.from(itemType.create(null, Fragment.from(parent.type.create(null, inner)))), nestedBefore ? 3 : 1, 0); + let before = range.start, after = range.end; + dispatch(state.tr.step(new ReplaceAroundStep(before - (nestedBefore ? 3 : 1), after, before, after, slice2, 1, true)).scrollIntoView()); + } + return true; + }; +} + +// ../../node_modules/.pnpm/prosemirror-view@1.41.8/node_modules/prosemirror-view/dist/index.js +var domIndex = function(node) { + for (var index = 0; ; index++) { + node = node.previousSibling; + if (!node) + return index; + } +}; +var parentNode = function(node) { + let parent = node.assignedSlot || node.parentNode; + return parent && parent.nodeType == 11 ? parent.host : parent; +}; +var reusedRange = null; +var textRange = function(node, from3, to) { + let range = reusedRange || (reusedRange = document.createRange()); + range.setEnd(node, to == null ? node.nodeValue.length : to); + range.setStart(node, from3 || 0); + return range; +}; +var clearReusedRange = function() { + reusedRange = null; +}; +var isEquivalentPosition = function(node, off, targetNode, targetOff) { + return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || scanFor(node, off, targetNode, targetOff, 1)); +}; +var atomElements = /^(img|br|input|textarea|hr)$/i; +function scanFor(node, off, targetNode, targetOff, dir) { + var _a; + for (; ; ) { + if (node == targetNode && off == targetOff) + return true; + if (off == (dir < 0 ? 0 : nodeSize(node))) { + let parent = node.parentNode; + if (!parent || parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") + return false; + off = domIndex(node) + (dir < 0 ? 0 : 1); + node = parent; + } else if (node.nodeType == 1) { + let child = node.childNodes[off + (dir < 0 ? -1 : 0)]; + if (child.nodeType == 1 && child.contentEditable == "false") { + if ((_a = child.pmViewDesc) === null || _a === void 0 ? void 0 : _a.ignoreForSelection) + off += dir; + else + return false; + } else { + node = child; + off = dir < 0 ? nodeSize(node) : 0; + } + } else { + return false; + } + } +} +function nodeSize(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; +} +function textNodeBefore$1(node, offset) { + for (; ; ) { + if (node.nodeType == 3 && offset) + return node; + if (node.nodeType == 1 && offset > 0) { + if (node.contentEditable == "false") + return null; + node = node.childNodes[offset - 1]; + offset = nodeSize(node); + } else if (node.parentNode && !hasBlockDesc(node)) { + offset = domIndex(node); + node = node.parentNode; + } else { + return null; + } + } +} +function textNodeAfter$1(node, offset) { + for (; ; ) { + if (node.nodeType == 3 && offset < node.nodeValue.length) + return node; + if (node.nodeType == 1 && offset < node.childNodes.length) { + if (node.contentEditable == "false") + return null; + node = node.childNodes[offset]; + offset = 0; + } else if (node.parentNode && !hasBlockDesc(node)) { + offset = domIndex(node) + 1; + node = node.parentNode; + } else { + return null; + } + } +} +function isOnEdge(node, offset, parent) { + for (let atStart = offset == 0, atEnd = offset == nodeSize(node); atStart || atEnd; ) { + if (node == parent) + return true; + let index = domIndex(node); + node = node.parentNode; + if (!node) + return false; + atStart = atStart && index == 0; + atEnd = atEnd && index == nodeSize(node); + } +} +function hasBlockDesc(dom) { + let desc; + for (let cur = dom; cur; cur = cur.parentNode) + if (desc = cur.pmViewDesc) + break; + return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom); +} +var selectionCollapsed = function(domSel) { + return domSel.focusNode && isEquivalentPosition(domSel.focusNode, domSel.focusOffset, domSel.anchorNode, domSel.anchorOffset); +}; +function keyEvent(keyCode, key) { + let event = document.createEvent("Event"); + event.initEvent("keydown", true, true); + event.keyCode = keyCode; + event.key = event.code = key; + return event; +} +function deepActiveElement(doc4) { + let elt = doc4.activeElement; + while (elt && elt.shadowRoot) + elt = elt.shadowRoot.activeElement; + return elt; +} +function caretFromPoint(doc4, x2, y2) { + if (doc4.caretPositionFromPoint) { + try { + let pos = doc4.caretPositionFromPoint(x2, y2); + if (pos) + return { node: pos.offsetNode, offset: Math.min(nodeSize(pos.offsetNode), pos.offset) }; + } catch (_2) { + } + } + if (doc4.caretRangeFromPoint) { + let range = doc4.caretRangeFromPoint(x2, y2); + if (range) + return { node: range.startContainer, offset: Math.min(nodeSize(range.startContainer), range.startOffset) }; + } +} +var nav = typeof navigator != "undefined" ? navigator : null; +var doc2 = typeof document != "undefined" ? document : null; +var agent = nav && nav.userAgent || ""; +var ie_edge = /Edge\/(\d+)/.exec(agent); +var ie_upto10 = /MSIE \d/.exec(agent); +var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent); +var ie = !!(ie_upto10 || ie_11up || ie_edge); +var ie_version = ie_upto10 ? document.documentMode : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0; +var gecko = !ie && /gecko\/(\d+)/i.test(agent); +gecko && +(/Firefox\/(\d+)/.exec(agent) || [0, 0])[1]; +var _chrome = !ie && /Chrome\/(\d+)/.exec(agent); +var chrome = !!_chrome; +var chrome_version = _chrome ? +_chrome[1] : 0; +var safari = !ie && !!nav && /Apple Computer/.test(nav.vendor); +var ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2); +var mac2 = ios || (nav ? /Mac/.test(nav.platform) : false); +var windows = nav ? /Win/.test(nav.platform) : false; +var android = /Android \d/.test(agent); +var webkit = !!doc2 && "webkitFontSmoothing" in doc2.documentElement.style; +var webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0; +function windowRect(doc4) { + let vp = doc4.defaultView && doc4.defaultView.visualViewport; + if (vp) + return { + left: 0, + right: vp.width, + top: 0, + bottom: vp.height + }; + return { + left: 0, + right: doc4.documentElement.clientWidth, + top: 0, + bottom: doc4.documentElement.clientHeight + }; +} +function getSide(value, side) { + return typeof value == "number" ? value : value[side]; +} +function clientRect(node) { + let rect = node.getBoundingClientRect(); + let scaleX = rect.width / node.offsetWidth || 1; + let scaleY = rect.height / node.offsetHeight || 1; + return { + left: rect.left, + right: rect.left + node.clientWidth * scaleX, + top: rect.top, + bottom: rect.top + node.clientHeight * scaleY + }; +} +function scrollRectIntoView(view, rect, startDOM) { + let scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5; + let doc4 = view.dom.ownerDocument; + for (let parent = startDOM || view.dom; ; ) { + if (!parent) + break; + if (parent.nodeType != 1) { + parent = parentNode(parent); + continue; + } + let elt = parent; + let atTop = elt == doc4.body; + let bounding = atTop ? windowRect(doc4) : clientRect(elt); + let moveX = 0, moveY = 0; + if (rect.top < bounding.top + getSide(scrollThreshold, "top")) + moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top")); + else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) + moveY = rect.bottom - rect.top > bounding.bottom - bounding.top ? rect.top + getSide(scrollMargin, "top") - bounding.top : rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom"); + if (rect.left < bounding.left + getSide(scrollThreshold, "left")) + moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left")); + else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) + moveX = rect.right - bounding.right + getSide(scrollMargin, "right"); + if (moveX || moveY) { + if (atTop) { + doc4.defaultView.scrollBy(moveX, moveY); + } else { + let startX = elt.scrollLeft, startY = elt.scrollTop; + if (moveY) + elt.scrollTop += moveY; + if (moveX) + elt.scrollLeft += moveX; + let dX = elt.scrollLeft - startX, dY = elt.scrollTop - startY; + rect = { left: rect.left - dX, top: rect.top - dY, right: rect.right - dX, bottom: rect.bottom - dY }; + } + } + let pos = atTop ? "fixed" : getComputedStyle(parent).position; + if (/^(fixed|sticky)$/.test(pos)) + break; + parent = pos == "absolute" ? parent.offsetParent : parentNode(parent); + } +} +function storeScrollPos(view) { + let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top); + let refDOM, refTop; + for (let x2 = (rect.left + rect.right) / 2, y2 = startY + 1; y2 < Math.min(innerHeight, rect.bottom); y2 += 5) { + let dom = view.root.elementFromPoint(x2, y2); + if (!dom || dom == view.dom || !view.dom.contains(dom)) + continue; + let localRect = dom.getBoundingClientRect(); + if (localRect.top >= startY - 20) { + refDOM = dom; + refTop = localRect.top; + break; + } + } + return { refDOM, refTop, stack: scrollStack(view.dom) }; +} +function scrollStack(dom) { + let stack = [], doc4 = dom.ownerDocument; + for (let cur = dom; cur; cur = parentNode(cur)) { + stack.push({ dom: cur, top: cur.scrollTop, left: cur.scrollLeft }); + if (dom == doc4) + break; + } + return stack; +} +function resetScrollPos({ refDOM, refTop, stack }) { + let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0; + restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop); +} +function restoreScrollStack(stack, dTop) { + for (let i = 0; i < stack.length; i++) { + let { dom, top, left } = stack[i]; + if (dom.scrollTop != top + dTop) + dom.scrollTop = top + dTop; + if (dom.scrollLeft != left) + dom.scrollLeft = left; + } +} +var preventScrollSupported = null; +function focusPreventScroll(dom) { + if (dom.setActive) + return dom.setActive(); + if (preventScrollSupported) + return dom.focus(preventScrollSupported); + let stored = scrollStack(dom); + dom.focus(preventScrollSupported == null ? { + get preventScroll() { + preventScrollSupported = { preventScroll: true }; + return true; + } + } : void 0); + if (!preventScrollSupported) { + preventScrollSupported = false; + restoreScrollStack(stored, 0); + } +} +function findOffsetInNode(node, coords) { + let closest, dxClosest = 2e8, coordsClosest, offset = 0; + let rowBot = coords.top, rowTop = coords.top; + let firstBelow, coordsBelow; + for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) { + let rects; + if (child.nodeType == 1) + rects = child.getClientRects(); + else if (child.nodeType == 3) + rects = textRange(child).getClientRects(); + else + continue; + for (let i = 0; i < rects.length; i++) { + let rect = rects[i]; + if (rect.top <= rowBot && rect.bottom >= rowTop) { + rowBot = Math.max(rect.bottom, rowBot); + rowTop = Math.min(rect.top, rowTop); + let dx = rect.left > coords.left ? rect.left - coords.left : rect.right < coords.left ? coords.left - rect.right : 0; + if (dx < dxClosest) { + closest = child; + dxClosest = dx; + coordsClosest = dx && closest.nodeType == 3 ? { + left: rect.right < coords.left ? rect.right : rect.left, + top: coords.top + } : coords; + if (child.nodeType == 1 && dx) + offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0); + continue; + } + } else if (rect.top > coords.top && !firstBelow && rect.left <= coords.left && rect.right >= coords.left) { + firstBelow = child; + coordsBelow = { left: Math.max(rect.left, Math.min(rect.right, coords.left)), top: rect.top }; + } + if (!closest && (coords.left >= rect.right && coords.top >= rect.top || coords.left >= rect.left && coords.top >= rect.bottom)) + offset = childIndex + 1; + } + } + if (!closest && firstBelow) { + closest = firstBelow; + coordsClosest = coordsBelow; + dxClosest = 0; + } + if (closest && closest.nodeType == 3) + return findOffsetInText(closest, coordsClosest); + if (!closest || dxClosest && closest.nodeType == 1) + return { node, offset }; + return findOffsetInNode(closest, coordsClosest); +} +function findOffsetInText(node, coords) { + let len = node.nodeValue.length; + let range = document.createRange(), result; + for (let i = 0; i < len; i++) { + range.setEnd(node, i + 1); + range.setStart(node, i); + let rect = singleRect(range, 1); + if (rect.top == rect.bottom) + continue; + if (inRect(coords, rect)) { + result = { node, offset: i + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) }; + break; + } + } + range.detach(); + return result || { node, offset: 0 }; +} +function inRect(coords, rect) { + return coords.left >= rect.left - 1 && coords.left <= rect.right + 1 && coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1; +} +function targetKludge(dom, coords) { + let parent = dom.parentNode; + if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) + return parent; + return dom; +} +function posFromElement(view, elt, coords) { + let { node, offset } = findOffsetInNode(elt, coords), bias = -1; + if (node.nodeType == 1 && !node.firstChild) { + let rect = node.getBoundingClientRect(); + bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1; + } + return view.docView.posFromDOM(node, offset, bias); +} +function posFromCaret(view, node, offset, coords) { + let outsideBlock = -1; + for (let cur = node, sawBlock = false; ; ) { + if (cur == view.dom) + break; + let desc = view.docView.nearestDesc(cur, true), rect; + if (!desc) + return null; + if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM) && // Ignore elements with zero-size bounding rectangles + ((rect = desc.dom.getBoundingClientRect()).width || rect.height)) { + if (desc.node.isBlock && desc.parent && !/^T(R|BODY|HEAD|FOOT)$/.test(desc.dom.nodeName)) { + if (!sawBlock && rect.left > coords.left || rect.top > coords.top) + outsideBlock = desc.posBefore; + else if (!sawBlock && rect.right < coords.left || rect.bottom < coords.top) + outsideBlock = desc.posAfter; + sawBlock = true; + } + if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) { + let before = desc.node.isBlock ? coords.top < (rect.top + rect.bottom) / 2 : coords.left < (rect.left + rect.right) / 2; + return before ? desc.posBefore : desc.posAfter; + } + } + cur = desc.dom.parentNode; + } + return outsideBlock > -1 ? outsideBlock : view.docView.posFromDOM(node, offset, -1); +} +function elementFromPoint(element2, coords, box) { + let len = element2.childNodes.length; + if (len && box.top < box.bottom) { + for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i = startI; ; ) { + let child = element2.childNodes[i]; + if (child.nodeType == 1) { + let rects = child.getClientRects(); + for (let j2 = 0; j2 < rects.length; j2++) { + let rect = rects[j2]; + if (inRect(coords, rect)) + return elementFromPoint(child, coords, rect); + } + } + if ((i = (i + 1) % len) == startI) + break; + } + } + return element2; +} +function posAtCoords(view, coords) { + let doc4 = view.dom.ownerDocument, node, offset = 0; + let caret = caretFromPoint(doc4, coords.left, coords.top); + if (caret) + ({ node, offset } = caret); + let elt = (view.root.elementFromPoint ? view.root : doc4).elementFromPoint(coords.left, coords.top); + let pos; + if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) { + let box = view.dom.getBoundingClientRect(); + if (!inRect(coords, box)) + return null; + elt = elementFromPoint(view.dom, coords, box); + if (!elt) + return null; + } + if (safari) { + for (let p = elt; node && p; p = parentNode(p)) + if (p.draggable) + node = void 0; + } + elt = targetKludge(elt, coords); + if (node) { + if (gecko && node.nodeType == 1) { + offset = Math.min(offset, node.childNodes.length); + if (offset < node.childNodes.length) { + let next2 = node.childNodes[offset], box; + if (next2.nodeName == "IMG" && (box = next2.getBoundingClientRect()).right <= coords.left && box.bottom > coords.top) + offset++; + } + } + let prev; + if (webkit && offset && node.nodeType == 1 && (prev = node.childNodes[offset - 1]).nodeType == 1 && prev.contentEditable == "false" && prev.getBoundingClientRect().top >= coords.top) + offset--; + if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && coords.top > node.lastChild.getBoundingClientRect().bottom) + pos = view.state.doc.content.size; + else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") + pos = posFromCaret(view, node, offset, coords); + } + if (pos == null) + pos = posFromElement(view, elt, coords); + let desc = view.docView.nearestDesc(elt, true); + return { pos, inside: desc ? desc.posAtStart - desc.border : -1 }; +} +function nonZero(rect) { + return rect.top < rect.bottom || rect.left < rect.right; +} +function singleRect(target, bias) { + let rects = target.getClientRects(); + if (rects.length) { + let first2 = rects[bias < 0 ? 0 : rects.length - 1]; + if (nonZero(first2)) + return first2; + } + return Array.prototype.find.call(rects, nonZero) || target.getBoundingClientRect(); +} +var BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; +function coordsAtPos(view, pos, side) { + let { node, offset, atom } = view.docView.domFromPos(pos, side < 0 ? -1 : 1); + let supportEmptyRange = webkit || gecko; + if (node.nodeType == 3) { + if (supportEmptyRange && (BIDI.test(node.nodeValue) || (side < 0 ? !offset : offset == node.nodeValue.length))) { + let rect = singleRect(textRange(node, offset, offset), side); + if (gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) { + let rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1); + if (rectBefore.top == rect.top) { + let rectAfter = singleRect(textRange(node, offset, offset + 1), -1); + if (rectAfter.top != rect.top) + return flattenV(rectAfter, rectAfter.left < rectBefore.left); + } + } + return rect; + } else { + let from3 = offset, to = offset, takeSide = side < 0 ? 1 : -1; + if (side < 0 && !offset) { + to++; + takeSide = -1; + } else if (side >= 0 && offset == node.nodeValue.length) { + from3--; + takeSide = 1; + } else if (side < 0) { + from3--; + } else { + to++; + } + return flattenV(singleRect(textRange(node, from3, to), takeSide), takeSide < 0); + } + } + let $dom = view.state.doc.resolve(pos - (atom || 0)); + if (!$dom.parent.inlineContent) { + if (atom == null && offset && (side < 0 || offset == nodeSize(node))) { + let before = node.childNodes[offset - 1]; + if (before.nodeType == 1) + return flattenH(before.getBoundingClientRect(), false); + } + if (atom == null && offset < nodeSize(node)) { + let after = node.childNodes[offset]; + if (after.nodeType == 1) + return flattenH(after.getBoundingClientRect(), true); + } + return flattenH(node.getBoundingClientRect(), side >= 0); + } + if (atom == null && offset && (side < 0 || offset == nodeSize(node))) { + let before = node.childNodes[offset - 1]; + let target = before.nodeType == 3 ? textRange(before, nodeSize(before) - (supportEmptyRange ? 0 : 1)) : before.nodeType == 1 && (before.nodeName != "BR" || !before.nextSibling) ? before : null; + if (target) + return flattenV(singleRect(target, 1), false); + } + if (atom == null && offset < nodeSize(node)) { + let after = node.childNodes[offset]; + while (after.pmViewDesc && after.pmViewDesc.ignoreForCoords) + after = after.nextSibling; + let target = !after ? null : after.nodeType == 3 ? textRange(after, 0, supportEmptyRange ? 0 : 1) : after.nodeType == 1 ? after : null; + if (target) + return flattenV(singleRect(target, -1), true); + } + return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, -side), side >= 0); +} +function flattenV(rect, left) { + if (rect.width == 0) + return rect; + let x2 = left ? rect.left : rect.right; + return { top: rect.top, bottom: rect.bottom, left: x2, right: x2 }; +} +function flattenH(rect, top) { + if (rect.height == 0) + return rect; + let y2 = top ? rect.top : rect.bottom; + return { top: y2, bottom: y2, left: rect.left, right: rect.right }; +} +function withFlushedState(view, state, f) { + let viewState = view.state, active = view.root.activeElement; + if (viewState != state) + view.updateState(state); + if (active != view.dom) + view.focus(); + try { + return f(); + } finally { + if (viewState != state) + view.updateState(viewState); + if (active != view.dom && active) + active.focus(); + } +} +function endOfTextblockVertical(view, state, dir) { + let sel = state.selection; + let $pos = dir == "up" ? sel.$from : sel.$to; + return withFlushedState(view, state, () => { + let { node: dom } = view.docView.domFromPos($pos.pos, dir == "up" ? -1 : 1); + for (; ; ) { + let nearest = view.docView.nearestDesc(dom, true); + if (!nearest) + break; + if (nearest.node.isBlock) { + dom = nearest.contentDOM || nearest.dom; + break; + } + dom = nearest.dom.parentNode; + } + let coords = coordsAtPos(view, $pos.pos, 1); + for (let child = dom.firstChild; child; child = child.nextSibling) { + let boxes; + if (child.nodeType == 1) + boxes = child.getClientRects(); + else if (child.nodeType == 3) + boxes = textRange(child, 0, child.nodeValue.length).getClientRects(); + else + continue; + for (let i = 0; i < boxes.length; i++) { + let box = boxes[i]; + if (box.bottom > box.top + 1 && (dir == "up" ? coords.top - box.top > (box.bottom - coords.top) * 2 : box.bottom - coords.bottom > (coords.bottom - box.top) * 2)) + return false; + } + } + return true; + }); +} +var maybeRTL = /[\u0590-\u08ac]/; +function endOfTextblockHorizontal(view, state, dir) { + let { $head } = state.selection; + if (!$head.parent.isTextblock) + return false; + let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size; + let sel = view.domSelection(); + if (!sel) + return $head.pos == $head.start() || $head.pos == $head.end(); + if (!maybeRTL.test($head.parent.textContent) || !sel.modify) + return dir == "left" || dir == "backward" ? atStart : atEnd; + return withFlushedState(view, state, () => { + let { focusNode: oldNode, focusOffset: oldOff, anchorNode, anchorOffset } = view.domSelectionRange(); + let oldBidiLevel = sel.caretBidiLevel; + sel.modify("move", dir, "character"); + let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom; + let { focusNode: newNode, focusOffset: newOff } = view.domSelectionRange(); + let result = newNode && !parentDOM.contains(newNode.nodeType == 1 ? newNode : newNode.parentNode) || oldNode == newNode && oldOff == newOff; + try { + sel.collapse(anchorNode, anchorOffset); + if (oldNode && (oldNode != anchorNode || oldOff != anchorOffset) && sel.extend) + sel.extend(oldNode, oldOff); + } catch (_2) { + } + if (oldBidiLevel != null) + sel.caretBidiLevel = oldBidiLevel; + return result; + }); +} +var cachedState = null; +var cachedDir = null; +var cachedResult = false; +function endOfTextblock(view, state, dir) { + if (cachedState == state && cachedDir == dir) + return cachedResult; + cachedState = state; + cachedDir = dir; + return cachedResult = dir == "up" || dir == "down" ? endOfTextblockVertical(view, state, dir) : endOfTextblockHorizontal(view, state, dir); +} +var NOT_DIRTY = 0; +var CHILD_DIRTY = 1; +var CONTENT_DIRTY = 2; +var NODE_DIRTY = 3; +var ViewDesc = class { + constructor(parent, children, dom, contentDOM) { + this.parent = parent; + this.children = children; + this.dom = dom; + this.contentDOM = contentDOM; + this.dirty = NOT_DIRTY; + dom.pmViewDesc = this; + } + // Used to check whether a given description corresponds to a + // widget/mark/node. + matchesWidget(widget) { + return false; + } + matchesMark(mark) { + return false; + } + matchesNode(node, outerDeco, innerDeco) { + return false; + } + matchesHack(nodeName) { + return false; + } + // When parsing in-editor content (in domchange.js), we allow + // descriptions to determine the parse rules that should be used to + // parse them. + parseRule() { + return null; + } + // Used by the editor's event handler to ignore events that come + // from certain descs. + stopEvent(event) { + return false; + } + // The size of the content represented by this desc. + get size() { + let size2 = 0; + for (let i = 0; i < this.children.length; i++) + size2 += this.children[i].size; + return size2; + } + // For block nodes, this represents the space taken up by their + // start/end tokens. + get border() { + return 0; + } + destroy() { + this.parent = void 0; + if (this.dom.pmViewDesc == this) + this.dom.pmViewDesc = void 0; + for (let i = 0; i < this.children.length; i++) + this.children[i].destroy(); + } + posBeforeChild(child) { + for (let i = 0, pos = this.posAtStart; ; i++) { + let cur = this.children[i]; + if (cur == child) + return pos; + pos += cur.size; + } + } + get posBefore() { + return this.parent.posBeforeChild(this); + } + get posAtStart() { + return this.parent ? this.parent.posBeforeChild(this) + this.border : 0; + } + get posAfter() { + return this.posBefore + this.size; + } + get posAtEnd() { + return this.posAtStart + this.size - 2 * this.border; + } + localPosFromDOM(dom, offset, bias) { + if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) { + if (bias < 0) { + let domBefore, desc; + if (dom == this.contentDOM) { + domBefore = dom.childNodes[offset - 1]; + } else { + while (dom.parentNode != this.contentDOM) + dom = dom.parentNode; + domBefore = dom.previousSibling; + } + while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) + domBefore = domBefore.previousSibling; + return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart; + } else { + let domAfter, desc; + if (dom == this.contentDOM) { + domAfter = dom.childNodes[offset]; + } else { + while (dom.parentNode != this.contentDOM) + dom = dom.parentNode; + domAfter = dom.nextSibling; + } + while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) + domAfter = domAfter.nextSibling; + return domAfter ? this.posBeforeChild(desc) : this.posAtEnd; + } + } + let atEnd; + if (dom == this.dom && this.contentDOM) { + atEnd = offset > domIndex(this.contentDOM); + } else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) { + atEnd = dom.compareDocumentPosition(this.contentDOM) & 2; + } else if (this.dom.firstChild) { + if (offset == 0) + for (let search = dom; ; search = search.parentNode) { + if (search == this.dom) { + atEnd = false; + break; + } + if (search.previousSibling) + break; + } + if (atEnd == null && offset == dom.childNodes.length) + for (let search = dom; ; search = search.parentNode) { + if (search == this.dom) { + atEnd = true; + break; + } + if (search.nextSibling) + break; + } + } + return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart; + } + nearestDesc(dom, onlyNodes = false) { + for (let first2 = true, cur = dom; cur; cur = cur.parentNode) { + let desc = this.getDesc(cur), nodeDOM; + if (desc && (!onlyNodes || desc.node)) { + if (first2 && (nodeDOM = desc.nodeDOM) && !(nodeDOM.nodeType == 1 ? nodeDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) : nodeDOM == dom)) + first2 = false; + else + return desc; + } + } + } + getDesc(dom) { + let desc = dom.pmViewDesc; + for (let cur = desc; cur; cur = cur.parent) + if (cur == this) + return desc; + } + posFromDOM(dom, offset, bias) { + for (let scan = dom; scan; scan = scan.parentNode) { + let desc = this.getDesc(scan); + if (desc) + return desc.localPosFromDOM(dom, offset, bias); + } + return -1; + } + // Find the desc for the node after the given pos, if any. (When a + // parent node overrode rendering, there might not be one.) + descAt(pos) { + for (let i = 0, offset = 0; i < this.children.length; i++) { + let child = this.children[i], end = offset + child.size; + if (offset == pos && end != offset) { + while (!child.border && child.children.length) { + for (let i2 = 0; i2 < child.children.length; i2++) { + let inner = child.children[i2]; + if (inner.size) { + child = inner; + break; + } + } + } + return child; + } + if (pos < end) + return child.descAt(pos - offset - child.border); + offset = end; + } + } + domFromPos(pos, side) { + if (!this.contentDOM) + return { node: this.dom, offset: 0, atom: pos + 1 }; + let i = 0, offset = 0; + for (let curPos = 0; i < this.children.length; i++) { + let child = this.children[i], end = curPos + child.size; + if (end > pos || child instanceof TrailingHackViewDesc) { + offset = pos - curPos; + break; + } + curPos = end; + } + if (offset) + return this.children[i].domFromPos(offset - this.children[i].border, side); + for (let prev; i && !(prev = this.children[i - 1]).size && prev instanceof WidgetViewDesc && prev.side >= 0; i--) { + } + if (side <= 0) { + let prev, enter2 = true; + for (; ; i--, enter2 = false) { + prev = i ? this.children[i - 1] : null; + if (!prev || prev.dom.parentNode == this.contentDOM) + break; + } + if (prev && side && enter2 && !prev.border && !prev.domAtom) + return prev.domFromPos(prev.size, side); + return { node: this.contentDOM, offset: prev ? domIndex(prev.dom) + 1 : 0 }; + } else { + let next2, enter2 = true; + for (; ; i++, enter2 = false) { + next2 = i < this.children.length ? this.children[i] : null; + if (!next2 || next2.dom.parentNode == this.contentDOM) + break; + } + if (next2 && enter2 && !next2.border && !next2.domAtom) + return next2.domFromPos(0, side); + return { node: this.contentDOM, offset: next2 ? domIndex(next2.dom) : this.contentDOM.childNodes.length }; + } + } + // Used to find a DOM range in a single parent for a given changed + // range. + parseRange(from3, to, base2 = 0) { + if (this.children.length == 0) + return { node: this.contentDOM, from: from3, to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length }; + let fromOffset = -1, toOffset = -1; + for (let offset = base2, i = 0; ; i++) { + let child = this.children[i], end = offset + child.size; + if (fromOffset == -1 && from3 <= end) { + let childBase = offset + child.border; + if (from3 >= childBase && to <= end - child.border && child.node && child.contentDOM && this.contentDOM.contains(child.contentDOM)) + return child.parseRange(from3, to, childBase); + from3 = offset; + for (let j2 = i; j2 > 0; j2--) { + let prev = this.children[j2 - 1]; + if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { + fromOffset = domIndex(prev.dom) + 1; + break; + } + from3 -= prev.size; + } + if (fromOffset == -1) + fromOffset = 0; + } + if (fromOffset > -1 && (end > to || i == this.children.length - 1)) { + to = end; + for (let j2 = i + 1; j2 < this.children.length; j2++) { + let next2 = this.children[j2]; + if (next2.size && next2.dom.parentNode == this.contentDOM && !next2.emptyChildAt(-1)) { + toOffset = domIndex(next2.dom); + break; + } + to += next2.size; + } + if (toOffset == -1) + toOffset = this.contentDOM.childNodes.length; + break; + } + offset = end; + } + return { node: this.contentDOM, from: from3, to, fromOffset, toOffset }; + } + emptyChildAt(side) { + if (this.border || !this.contentDOM || !this.children.length) + return false; + let child = this.children[side < 0 ? 0 : this.children.length - 1]; + return child.size == 0 || child.emptyChildAt(side); + } + domAfterPos(pos) { + let { node, offset } = this.domFromPos(pos, 0); + if (node.nodeType != 1 || offset == node.childNodes.length) + throw new RangeError("No node after pos " + pos); + return node.childNodes[offset]; + } + // View descs are responsible for setting any selection that falls + // entirely inside of them, so that custom implementations can do + // custom things with the selection. Note that this falls apart when + // a selection starts in such a node and ends in another, in which + // case we just use whatever domFromPos produces as a best effort. + setSelection(anchor, head, view, force = false) { + let from3 = Math.min(anchor, head), to = Math.max(anchor, head); + for (let i = 0, offset = 0; i < this.children.length; i++) { + let child = this.children[i], end = offset + child.size; + if (from3 > offset && to < end) + return child.setSelection(anchor - offset - child.border, head - offset - child.border, view, force); + offset = end; + } + let anchorDOM = this.domFromPos(anchor, anchor ? -1 : 1); + let headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1); + let domSel = view.root.getSelection(); + let selRange = view.domSelectionRange(); + let brKludge = false; + if ((gecko || safari) && anchor == head) { + let { node, offset } = anchorDOM; + if (node.nodeType == 3) { + brKludge = !!(offset && node.nodeValue[offset - 1] == "\n"); + if (brKludge && offset == node.nodeValue.length) { + for (let scan = node, after; scan; scan = scan.parentNode) { + if (after = scan.nextSibling) { + if (after.nodeName == "BR") + anchorDOM = headDOM = { node: after.parentNode, offset: domIndex(after) + 1 }; + break; + } + let desc = scan.pmViewDesc; + if (desc && desc.node && desc.node.isBlock) + break; + } + } + } else { + let prev = node.childNodes[offset - 1]; + brKludge = prev && (prev.nodeName == "BR" || prev.contentEditable == "false"); + } + } + if (gecko && selRange.focusNode && selRange.focusNode != headDOM.node && selRange.focusNode.nodeType == 1) { + let after = selRange.focusNode.childNodes[selRange.focusOffset]; + if (after && after.contentEditable == "false") + force = true; + } + if (!(force || brKludge && safari) && isEquivalentPosition(anchorDOM.node, anchorDOM.offset, selRange.anchorNode, selRange.anchorOffset) && isEquivalentPosition(headDOM.node, headDOM.offset, selRange.focusNode, selRange.focusOffset)) + return; + let domSelExtended = false; + if ((domSel.extend || anchor == head) && !(brKludge && gecko)) { + domSel.collapse(anchorDOM.node, anchorDOM.offset); + try { + if (anchor != head) + domSel.extend(headDOM.node, headDOM.offset); + domSelExtended = true; + } catch (_2) { + } + } + if (!domSelExtended) { + if (anchor > head) { + let tmp = anchorDOM; + anchorDOM = headDOM; + headDOM = tmp; + } + let range = document.createRange(); + range.setEnd(headDOM.node, headDOM.offset); + range.setStart(anchorDOM.node, anchorDOM.offset); + domSel.removeAllRanges(); + domSel.addRange(range); + } + } + ignoreMutation(mutation) { + return !this.contentDOM && mutation.type != "selection"; + } + get contentLost() { + return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM); + } + // Remove a subtree of the element tree that has been touched + // by a DOM change, so that the next update will redraw it. + markDirty(from3, to) { + for (let offset = 0, i = 0; i < this.children.length; i++) { + let child = this.children[i], end = offset + child.size; + if (offset == end ? from3 <= end && to >= offset : from3 < end && to > offset) { + let startInside = offset + child.border, endInside = end - child.border; + if (from3 >= startInside && to <= endInside) { + this.dirty = from3 == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY; + if (from3 == startInside && to == endInside && (child.contentLost || child.dom.parentNode != this.contentDOM)) + child.dirty = NODE_DIRTY; + else + child.markDirty(from3 - startInside, to - startInside); + return; + } else { + child.dirty = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM && !child.children.length ? CONTENT_DIRTY : NODE_DIRTY; + } + } + offset = end; + } + this.dirty = CONTENT_DIRTY; + } + markParentsDirty() { + let level = 1; + for (let node = this.parent; node; node = node.parent, level++) { + let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY; + if (node.dirty < dirty) + node.dirty = dirty; + } + } + get domAtom() { + return false; + } + get ignoreForCoords() { + return false; + } + get ignoreForSelection() { + return false; + } + isText(text2) { + return false; + } +}; +var WidgetViewDesc = class extends ViewDesc { + constructor(parent, widget, view, pos) { + let self, dom = widget.type.toDOM; + if (typeof dom == "function") + dom = dom(view, () => { + if (!self) + return pos; + if (self.parent) + return self.parent.posBeforeChild(self); + }); + if (!widget.type.spec.raw) { + if (dom.nodeType != 1) { + let wrap2 = document.createElement("span"); + wrap2.appendChild(dom); + dom = wrap2; + } + dom.contentEditable = "false"; + dom.classList.add("ProseMirror-widget"); + } + super(parent, [], dom, null); + this.widget = widget; + this.widget = widget; + self = this; + } + matchesWidget(widget) { + return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type); + } + parseRule() { + return { ignore: true }; + } + stopEvent(event) { + let stop = this.widget.spec.stopEvent; + return stop ? stop(event) : false; + } + ignoreMutation(mutation) { + return mutation.type != "selection" || this.widget.spec.ignoreSelection; + } + destroy() { + this.widget.type.destroy(this.dom); + super.destroy(); + } + get domAtom() { + return true; + } + get ignoreForSelection() { + return !!this.widget.type.spec.relaxedSide; + } + get side() { + return this.widget.type.side; + } +}; +var CompositionViewDesc = class extends ViewDesc { + constructor(parent, dom, textDOM, text2) { + super(parent, [], dom, null); + this.textDOM = textDOM; + this.text = text2; + } + get size() { + return this.text.length; + } + localPosFromDOM(dom, offset) { + if (dom != this.textDOM) + return this.posAtStart + (offset ? this.size : 0); + return this.posAtStart + offset; + } + domFromPos(pos) { + return { node: this.textDOM, offset: pos }; + } + ignoreMutation(mut) { + return mut.type === "characterData" && mut.target.nodeValue == mut.oldValue; + } +}; +var MarkViewDesc = class _MarkViewDesc extends ViewDesc { + constructor(parent, mark, dom, contentDOM, spec) { + super(parent, [], dom, contentDOM); + this.mark = mark; + this.spec = spec; + } + static create(parent, mark, inline, view) { + let custom = view.nodeViews[mark.type.name]; + let spec = custom && custom(mark, view, inline); + if (!spec || !spec.dom) + spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline), null, mark.attrs); + return new _MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom, spec); + } + parseRule() { + if (this.dirty & NODE_DIRTY || this.mark.type.spec.reparseInView) + return null; + return { mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM }; + } + matchesMark(mark) { + return this.dirty != NODE_DIRTY && this.mark.eq(mark); + } + markDirty(from3, to) { + super.markDirty(from3, to); + if (this.dirty != NOT_DIRTY) { + let parent = this.parent; + while (!parent.node) + parent = parent.parent; + if (parent.dirty < this.dirty) + parent.dirty = this.dirty; + this.dirty = NOT_DIRTY; + } + } + slice(from3, to, view) { + let copy3 = _MarkViewDesc.create(this.parent, this.mark, true, view); + let nodes = this.children, size2 = this.size; + if (to < size2) + nodes = replaceNodes(nodes, to, size2, view); + if (from3 > 0) + nodes = replaceNodes(nodes, 0, from3, view); + for (let i = 0; i < nodes.length; i++) + nodes[i].parent = copy3; + copy3.children = nodes; + return copy3; + } + ignoreMutation(mutation) { + return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation); + } + destroy() { + if (this.spec.destroy) + this.spec.destroy(); + super.destroy(); + } +}; +var NodeViewDesc = class _NodeViewDesc extends ViewDesc { + constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) { + super(parent, [], dom, contentDOM); + this.node = node; + this.outerDeco = outerDeco; + this.innerDeco = innerDeco; + this.nodeDOM = nodeDOM; + } + // By default, a node is rendered using the `toDOM` method from the + // node type spec. But client code can use the `nodeViews` spec to + // supply a custom node view, which can influence various aspects of + // the way the node works. + // + // (Using subclassing for this was intentionally decided against, + // since it'd require exposing a whole slew of finicky + // implementation details to the user code that they probably will + // never need.) + static create(parent, node, outerDeco, innerDeco, view, pos) { + let custom = view.nodeViews[node.type.name], descObj; + let spec = custom && custom(node, view, () => { + if (!descObj) + return pos; + if (descObj.parent) + return descObj.parent.posBeforeChild(descObj); + }, outerDeco, innerDeco); + let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM; + if (node.isText) { + if (!dom) + dom = document.createTextNode(node.text); + else if (dom.nodeType != 3) + throw new RangeError("Text must be rendered as a DOM text node"); + } else if (!dom) { + let spec2 = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node), null, node.attrs); + ({ dom, contentDOM } = spec2); + } + if (!contentDOM && !node.isText && dom.nodeName != "BR") { + if (!dom.hasAttribute("contenteditable")) + dom.contentEditable = "false"; + if (node.type.spec.draggable) + dom.draggable = true; + } + let nodeDOM = dom; + dom = applyOuterDeco(dom, outerDeco, node); + if (spec) + return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec, view, pos + 1); + else if (node.isText) + return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view); + else + return new _NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, view, pos + 1); + } + parseRule() { + if (this.node.type.spec.reparseInView) + return null; + let rule = { node: this.node.type.name, attrs: this.node.attrs }; + if (this.node.type.whitespace == "pre") + rule.preserveWhitespace = "full"; + if (!this.contentDOM) { + rule.getContent = () => this.node.content; + } else if (!this.contentLost) { + rule.contentElement = this.contentDOM; + } else { + for (let i = this.children.length - 1; i >= 0; i--) { + let child = this.children[i]; + if (this.dom.contains(child.dom.parentNode)) { + rule.contentElement = child.dom.parentNode; + break; + } + } + if (!rule.contentElement) + rule.getContent = () => Fragment.empty; + } + return rule; + } + matchesNode(node, outerDeco, innerDeco) { + return this.dirty == NOT_DIRTY && node.eq(this.node) && sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco); + } + get size() { + return this.node.nodeSize; + } + get border() { + return this.node.isLeaf ? 0 : 1; + } + // Syncs `this.children` to match `this.node.content` and the local + // decorations, possibly introducing nesting for marks. Then, in a + // separate step, syncs the DOM inside `this.contentDOM` to + // `this.children`. + updateChildren(view, pos) { + let inline = this.node.inlineContent, off = pos; + let composition = view.composing ? this.localCompositionInfo(view, pos) : null; + let localComposition = composition && composition.pos > -1 ? composition : null; + let compositionInChild = composition && composition.pos < 0; + let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view); + iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => { + if (widget.spec.marks) + updater.syncToMarks(widget.spec.marks, inline, view, i); + else if (widget.type.side >= 0 && !insideNode) + updater.syncToMarks(i == this.node.childCount ? Mark.none : this.node.child(i).marks, inline, view, i); + updater.placeWidget(widget, view, off); + }, (child, outerDeco, innerDeco, i) => { + updater.syncToMarks(child.marks, inline, view, i); + let compIndex; + if (updater.findNodeMatch(child, outerDeco, innerDeco, i)) ; + else if (compositionInChild && view.state.selection.from > off && view.state.selection.to < off + child.nodeSize && (compIndex = updater.findIndexWithChild(composition.node)) > -1 && updater.updateNodeAt(child, outerDeco, innerDeco, compIndex, view)) ; + else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i, off)) ; + else { + updater.addNode(child, outerDeco, innerDeco, view, off); + } + off += child.nodeSize; + }); + updater.syncToMarks([], inline, view, 0); + if (this.node.isTextblock) + updater.addTextblockHacks(); + updater.destroyRest(); + if (updater.changed || this.dirty == CONTENT_DIRTY) { + if (localComposition) + this.protectLocalComposition(view, localComposition); + renderDescs(this.contentDOM, this.children, view); + if (ios) + iosHacks(this.dom); + } + } + localCompositionInfo(view, pos) { + let { from: from3, to } = view.state.selection; + if (!(view.state.selection instanceof TextSelection) || from3 < pos || to > pos + this.node.content.size) + return null; + let textNode = view.input.compositionNode; + if (!textNode || !this.dom.contains(textNode.parentNode)) + return null; + if (this.node.inlineContent) { + let text2 = textNode.nodeValue; + let textPos = findTextInFragment(this.node.content, text2, from3 - pos, to - pos); + return textPos < 0 ? null : { node: textNode, pos: textPos, text: text2 }; + } else { + return { node: textNode, pos: -1, text: "" }; + } + } + protectLocalComposition(view, { node, pos, text: text2 }) { + if (this.getDesc(node)) + return; + let topNode = node; + for (; ; topNode = topNode.parentNode) { + if (topNode.parentNode == this.contentDOM) + break; + while (topNode.previousSibling) + topNode.parentNode.removeChild(topNode.previousSibling); + while (topNode.nextSibling) + topNode.parentNode.removeChild(topNode.nextSibling); + if (topNode.pmViewDesc) + topNode.pmViewDesc = void 0; + } + let desc = new CompositionViewDesc(this, topNode, node, text2); + view.input.compositionNodes.push(desc); + this.children = replaceNodes(this.children, pos, pos + text2.length, view, desc); + } + // If this desc must be updated to match the given node decoration, + // do so and return true. + update(node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY || !node.sameMarkup(this.node)) + return false; + this.updateInner(node, outerDeco, innerDeco, view); + return true; + } + updateInner(node, outerDeco, innerDeco, view) { + this.updateOuterDeco(outerDeco); + this.node = node; + this.innerDeco = innerDeco; + if (this.contentDOM) + this.updateChildren(view, this.posAtStart); + this.dirty = NOT_DIRTY; + } + updateOuterDeco(outerDeco) { + if (sameOuterDeco(outerDeco, this.outerDeco)) + return; + let needsWrap = this.nodeDOM.nodeType != 1; + let oldDOM = this.dom; + this.dom = patchOuterDeco(this.dom, this.nodeDOM, computeOuterDeco(this.outerDeco, this.node, needsWrap), computeOuterDeco(outerDeco, this.node, needsWrap)); + if (this.dom != oldDOM) { + oldDOM.pmViewDesc = void 0; + this.dom.pmViewDesc = this; + } + this.outerDeco = outerDeco; + } + // Mark this node as being the selected node. + selectNode() { + if (this.nodeDOM.nodeType == 1) { + this.nodeDOM.classList.add("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) + this.nodeDOM.draggable = true; + } + } + // Remove selected node marking from this node. + deselectNode() { + if (this.nodeDOM.nodeType == 1) { + this.nodeDOM.classList.remove("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) + this.nodeDOM.removeAttribute("draggable"); + } + } + get domAtom() { + return this.node.isAtom; + } +}; +function docViewDesc(doc4, outerDeco, innerDeco, dom, view) { + applyOuterDeco(dom, outerDeco, doc4); + let docView = new NodeViewDesc(void 0, doc4, outerDeco, innerDeco, dom, dom, dom, view, 0); + if (docView.contentDOM) + docView.updateChildren(view, 0); + return docView; +} +var TextViewDesc = class _TextViewDesc extends NodeViewDesc { + constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) { + super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view, 0); + } + parseRule() { + let skip = this.nodeDOM.parentNode; + while (skip && skip != this.dom && !skip.pmIsDeco) + skip = skip.parentNode; + return { skip: skip || true }; + } + update(node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY || this.dirty != NOT_DIRTY && !this.inParent() || !node.sameMarkup(this.node)) + return false; + this.updateOuterDeco(outerDeco); + if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue) { + this.nodeDOM.nodeValue = node.text; + if (view.trackWrites == this.nodeDOM) + view.trackWrites = null; + } + this.node = node; + this.dirty = NOT_DIRTY; + return true; + } + inParent() { + let parentDOM = this.parent.contentDOM; + for (let n = this.nodeDOM; n; n = n.parentNode) + if (n == parentDOM) + return true; + return false; + } + domFromPos(pos) { + return { node: this.nodeDOM, offset: pos }; + } + localPosFromDOM(dom, offset, bias) { + if (dom == this.nodeDOM) + return this.posAtStart + Math.min(offset, this.node.text.length); + return super.localPosFromDOM(dom, offset, bias); + } + ignoreMutation(mutation) { + return mutation.type != "characterData" && mutation.type != "selection"; + } + slice(from3, to, view) { + let node = this.node.cut(from3, to), dom = document.createTextNode(node.text); + return new _TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view); + } + markDirty(from3, to) { + super.markDirty(from3, to); + if (this.dom != this.nodeDOM && (from3 == 0 || to == this.nodeDOM.nodeValue.length)) + this.dirty = NODE_DIRTY; + } + get domAtom() { + return false; + } + isText(text2) { + return this.node.text == text2; + } +}; +var TrailingHackViewDesc = class extends ViewDesc { + parseRule() { + return { ignore: true }; + } + matchesHack(nodeName) { + return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName; + } + get domAtom() { + return true; + } + get ignoreForCoords() { + return this.dom.nodeName == "IMG"; + } +}; +var CustomNodeViewDesc = class extends NodeViewDesc { + constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) { + super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos); + this.spec = spec; + } + // A custom `update` method gets to decide whether the update goes + // through. If it does, and there's a `contentDOM` node, our logic + // updates the children. + update(node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY) + return false; + if (this.spec.update && (this.node.type == node.type || this.spec.multiType)) { + let result = this.spec.update(node, outerDeco, innerDeco); + if (result) + this.updateInner(node, outerDeco, innerDeco, view); + return result; + } else if (!this.contentDOM && !node.isLeaf) { + return false; + } else { + return super.update(node, outerDeco, innerDeco, view); + } + } + selectNode() { + this.spec.selectNode ? this.spec.selectNode() : super.selectNode(); + } + deselectNode() { + this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode(); + } + setSelection(anchor, head, view, force) { + this.spec.setSelection ? this.spec.setSelection(anchor, head, view.root) : super.setSelection(anchor, head, view, force); + } + destroy() { + if (this.spec.destroy) + this.spec.destroy(); + super.destroy(); + } + stopEvent(event) { + return this.spec.stopEvent ? this.spec.stopEvent(event) : false; + } + ignoreMutation(mutation) { + return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation); + } +}; +function renderDescs(parentDOM, descs, view) { + let dom = parentDOM.firstChild, written = false; + for (let i = 0; i < descs.length; i++) { + let desc = descs[i], childDOM = desc.dom; + if (childDOM.parentNode == parentDOM) { + while (childDOM != dom) { + dom = rm(dom); + written = true; + } + dom = dom.nextSibling; + } else { + written = true; + parentDOM.insertBefore(childDOM, dom); + } + if (desc instanceof MarkViewDesc) { + let pos = dom ? dom.previousSibling : parentDOM.lastChild; + renderDescs(desc.contentDOM, desc.children, view); + dom = pos ? pos.nextSibling : parentDOM.firstChild; + } + } + while (dom) { + dom = rm(dom); + written = true; + } + if (written && view.trackWrites == parentDOM) + view.trackWrites = null; +} +var OuterDecoLevel = function(nodeName) { + if (nodeName) + this.nodeName = nodeName; +}; +OuterDecoLevel.prototype = /* @__PURE__ */ Object.create(null); +var noDeco = [new OuterDecoLevel()]; +function computeOuterDeco(outerDeco, node, needsWrap) { + if (outerDeco.length == 0) + return noDeco; + let top = needsWrap ? noDeco[0] : new OuterDecoLevel(), result = [top]; + for (let i = 0; i < outerDeco.length; i++) { + let attrs = outerDeco[i].type.attrs; + if (!attrs) + continue; + if (attrs.nodeName) + result.push(top = new OuterDecoLevel(attrs.nodeName)); + for (let name in attrs) { + let val = attrs[name]; + if (val == null) + continue; + if (needsWrap && result.length == 1) + result.push(top = new OuterDecoLevel(node.isInline ? "span" : "div")); + if (name == "class") + top.class = (top.class ? top.class + " " : "") + val; + else if (name == "style") + top.style = (top.style ? top.style + ";" : "") + val; + else if (name != "nodeName") + top[name] = val; + } + } + return result; +} +function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) { + if (prevComputed == noDeco && curComputed == noDeco) + return nodeDOM; + let curDOM = nodeDOM; + for (let i = 0; i < curComputed.length; i++) { + let deco = curComputed[i], prev = prevComputed[i]; + if (i) { + let parent; + if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && (parent = curDOM.parentNode) && parent.nodeName.toLowerCase() == deco.nodeName) { + curDOM = parent; + } else { + parent = document.createElement(deco.nodeName); + parent.pmIsDeco = true; + parent.appendChild(curDOM); + prev = noDeco[0]; + curDOM = parent; + } + } + patchAttributes(curDOM, prev || noDeco[0], deco); + } + return curDOM; +} +function patchAttributes(dom, prev, cur) { + for (let name in prev) + if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) + dom.removeAttribute(name); + for (let name in cur) + if (name != "class" && name != "style" && name != "nodeName" && cur[name] != prev[name]) + dom.setAttribute(name, cur[name]); + if (prev.class != cur.class) { + let prevList = prev.class ? prev.class.split(" ").filter(Boolean) : []; + let curList = cur.class ? cur.class.split(" ").filter(Boolean) : []; + for (let i = 0; i < prevList.length; i++) + if (curList.indexOf(prevList[i]) == -1) + dom.classList.remove(prevList[i]); + for (let i = 0; i < curList.length; i++) + if (prevList.indexOf(curList[i]) == -1) + dom.classList.add(curList[i]); + if (dom.classList.length == 0) + dom.removeAttribute("class"); + } + if (prev.style != cur.style) { + if (prev.style) { + let prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m2; + while (m2 = prop.exec(prev.style)) + dom.style.removeProperty(m2[1]); + } + if (cur.style) + dom.style.cssText += cur.style; + } +} +function applyOuterDeco(dom, deco, node) { + return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1)); +} +function sameOuterDeco(a, b2) { + if (a.length != b2.length) + return false; + for (let i = 0; i < a.length; i++) + if (!a[i].type.eq(b2[i].type)) + return false; + return true; +} +function rm(dom) { + let next2 = dom.nextSibling; + dom.parentNode.removeChild(dom); + return next2; +} +var ViewTreeUpdater = class { + constructor(top, lock, view) { + this.lock = lock; + this.view = view; + this.index = 0; + this.stack = []; + this.changed = false; + this.top = top; + this.preMatch = preMatch(top.node.content, top); + } + // Destroy and remove the children between the given indices in + // `this.top`. + destroyBetween(start, end) { + if (start == end) + return; + for (let i = start; i < end; i++) + this.top.children[i].destroy(); + this.top.children.splice(start, end - start); + this.changed = true; + } + // Destroy all remaining children in `this.top`. + destroyRest() { + this.destroyBetween(this.index, this.top.children.length); + } + // Sync the current stack of mark descs with the given array of + // marks, reusing existing mark descs when possible. + syncToMarks(marks, inline, view, parentIndex) { + let keep = 0, depth = this.stack.length >> 1; + let maxKeep = Math.min(depth, marks.length); + while (keep < maxKeep && (keep == depth - 1 ? this.top : this.stack[keep + 1 << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) + keep++; + while (keep < depth) { + this.destroyRest(); + this.top.dirty = NOT_DIRTY; + this.index = this.stack.pop(); + this.top = this.stack.pop(); + depth--; + } + while (depth < marks.length) { + this.stack.push(this.top, this.index + 1); + let found3 = -1, scanTo = this.top.children.length; + if (parentIndex < this.preMatch.index) + scanTo = Math.min(this.index + 3, scanTo); + for (let i = this.index; i < scanTo; i++) { + let next2 = this.top.children[i]; + if (next2.matchesMark(marks[depth]) && !this.isLocked(next2.dom)) { + found3 = i; + break; + } + } + if (found3 > -1) { + if (found3 > this.index) { + this.changed = true; + this.destroyBetween(this.index, found3); + } + this.top = this.top.children[this.index]; + } else { + let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view); + this.top.children.splice(this.index, 0, markDesc); + this.top = markDesc; + this.changed = true; + } + this.index = 0; + depth++; + } + } + // Try to find a node desc matching the given data. Skip over it and + // return true when successful. + findNodeMatch(node, outerDeco, innerDeco, index) { + let found3 = -1, targetDesc; + if (index >= this.preMatch.index && (targetDesc = this.preMatch.matches[index - this.preMatch.index]).parent == this.top && targetDesc.matchesNode(node, outerDeco, innerDeco)) { + found3 = this.top.children.indexOf(targetDesc, this.index); + } else { + for (let i = this.index, e = Math.min(this.top.children.length, i + 5); i < e; i++) { + let child = this.top.children[i]; + if (child.matchesNode(node, outerDeco, innerDeco) && !this.preMatch.matched.has(child)) { + found3 = i; + break; + } + } + } + if (found3 < 0) + return false; + this.destroyBetween(this.index, found3); + this.index++; + return true; + } + updateNodeAt(node, outerDeco, innerDeco, index, view) { + let child = this.top.children[index]; + if (child.dirty == NODE_DIRTY && child.dom == child.contentDOM) + child.dirty = CONTENT_DIRTY; + if (!child.update(node, outerDeco, innerDeco, view)) + return false; + this.destroyBetween(this.index, index); + this.index++; + return true; + } + findIndexWithChild(domNode) { + for (; ; ) { + let parent = domNode.parentNode; + if (!parent) + return -1; + if (parent == this.top.contentDOM) { + let desc = domNode.pmViewDesc; + if (desc) + for (let i = this.index; i < this.top.children.length; i++) { + if (this.top.children[i] == desc) + return i; + } + return -1; + } + domNode = parent; + } + } + // Try to update the next node, if any, to the given data. Checks + // pre-matches to avoid overwriting nodes that could still be used. + updateNextNode(node, outerDeco, innerDeco, view, index, pos) { + for (let i = this.index; i < this.top.children.length; i++) { + let next2 = this.top.children[i]; + if (next2 instanceof NodeViewDesc) { + let preMatch2 = this.preMatch.matched.get(next2); + if (preMatch2 != null && preMatch2 != index) + return false; + let nextDOM = next2.dom, updated; + let locked = this.isLocked(nextDOM) && !(node.isText && next2.node && next2.node.isText && next2.nodeDOM.nodeValue == node.text && next2.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next2.outerDeco)); + if (!locked && next2.update(node, outerDeco, innerDeco, view)) { + this.destroyBetween(this.index, i); + if (next2.dom != nextDOM) + this.changed = true; + this.index++; + return true; + } else if (!locked && (updated = this.recreateWrapper(next2, node, outerDeco, innerDeco, view, pos))) { + this.destroyBetween(this.index, i); + this.top.children[this.index] = updated; + if (updated.contentDOM) { + updated.dirty = CONTENT_DIRTY; + updated.updateChildren(view, pos + 1); + updated.dirty = NOT_DIRTY; + } + this.changed = true; + this.index++; + return true; + } + break; + } + } + return false; + } + // When a node with content is replaced by a different node with + // identical content, move over its children. + recreateWrapper(next2, node, outerDeco, innerDeco, view, pos) { + if (next2.dirty || node.isAtom || !next2.children.length || !next2.node.content.eq(node.content) || !sameOuterDeco(outerDeco, next2.outerDeco) || !innerDeco.eq(next2.innerDeco)) + return null; + let wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos); + if (wrapper.contentDOM) { + wrapper.children = next2.children; + next2.children = []; + for (let ch of wrapper.children) + ch.parent = wrapper; + } + next2.destroy(); + return wrapper; + } + // Insert the node as a newly created node desc. + addNode(node, outerDeco, innerDeco, view, pos) { + let desc = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos); + if (desc.contentDOM) + desc.updateChildren(view, pos + 1); + this.top.children.splice(this.index++, 0, desc); + this.changed = true; + } + placeWidget(widget, view, pos) { + let next2 = this.index < this.top.children.length ? this.top.children[this.index] : null; + if (next2 && next2.matchesWidget(widget) && (widget == next2.widget || !next2.widget.type.toDOM.parentNode)) { + this.index++; + } else { + let desc = new WidgetViewDesc(this.top, widget, view, pos); + this.top.children.splice(this.index++, 0, desc); + this.changed = true; + } + } + // Make sure a textblock looks and behaves correctly in + // contentEditable. + addTextblockHacks() { + let lastChild = this.top.children[this.index - 1], parent = this.top; + while (lastChild instanceof MarkViewDesc) { + parent = lastChild; + lastChild = parent.children[parent.children.length - 1]; + } + if (!lastChild || // Empty textblock + !(lastChild instanceof TextViewDesc) || /\n$/.test(lastChild.node.text) || this.view.requiresGeckoHackNode && /\s$/.test(lastChild.node.text)) { + if ((safari || chrome) && lastChild && lastChild.dom.contentEditable == "false") + this.addHackNode("IMG", parent); + this.addHackNode("BR", this.top); + } + } + addHackNode(nodeName, parent) { + if (parent == this.top && this.index < parent.children.length && parent.children[this.index].matchesHack(nodeName)) { + this.index++; + } else { + let dom = document.createElement(nodeName); + if (nodeName == "IMG") { + dom.className = "ProseMirror-separator"; + dom.alt = ""; + } + if (nodeName == "BR") + dom.className = "ProseMirror-trailingBreak"; + let hack = new TrailingHackViewDesc(this.top, [], dom, null); + if (parent != this.top) + parent.children.push(hack); + else + parent.children.splice(this.index++, 0, hack); + this.changed = true; + } + } + isLocked(node) { + return this.lock && (node == this.lock || node.nodeType == 1 && node.contains(this.lock.parentNode)); + } +}; +function preMatch(frag, parentDesc) { + let curDesc = parentDesc, descI = curDesc.children.length; + let fI = frag.childCount, matched = /* @__PURE__ */ new Map(), matches2 = []; + outer: while (fI > 0) { + let desc; + for (; ; ) { + if (descI) { + let next2 = curDesc.children[descI - 1]; + if (next2 instanceof MarkViewDesc) { + curDesc = next2; + descI = next2.children.length; + } else { + desc = next2; + descI--; + break; + } + } else if (curDesc == parentDesc) { + break outer; + } else { + descI = curDesc.parent.children.indexOf(curDesc); + curDesc = curDesc.parent; + } + } + let node = desc.node; + if (!node) + continue; + if (node != frag.child(fI - 1)) + break; + --fI; + matched.set(desc, fI); + matches2.push(desc); + } + return { index: fI, matched, matches: matches2.reverse() }; +} +function compareSide(a, b2) { + return a.type.side - b2.type.side; +} +function iterDeco(parent, deco, onWidget, onNode) { + let locals = deco.locals(parent), offset = 0; + if (locals.length == 0) { + for (let i = 0; i < parent.childCount; i++) { + let child = parent.child(i); + onNode(child, locals, deco.forChild(offset, child), i); + offset += child.nodeSize; + } + return; + } + let decoIndex = 0, active = [], restNode = null; + for (let parentIndex = 0; ; ) { + let widget, widgets; + while (decoIndex < locals.length && locals[decoIndex].to == offset) { + let next2 = locals[decoIndex++]; + if (next2.widget) { + if (!widget) + widget = next2; + else + (widgets || (widgets = [widget])).push(next2); + } + } + if (widget) { + if (widgets) { + widgets.sort(compareSide); + for (let i = 0; i < widgets.length; i++) + onWidget(widgets[i], parentIndex, !!restNode); + } else { + onWidget(widget, parentIndex, !!restNode); + } + } + let child, index; + if (restNode) { + index = -1; + child = restNode; + restNode = null; + } else if (parentIndex < parent.childCount) { + index = parentIndex; + child = parent.child(parentIndex++); + } else { + break; + } + for (let i = 0; i < active.length; i++) + if (active[i].to <= offset) + active.splice(i--, 1); + while (decoIndex < locals.length && locals[decoIndex].from <= offset && locals[decoIndex].to > offset) + active.push(locals[decoIndex++]); + let end = offset + child.nodeSize; + if (child.isText) { + let cutAt = end; + if (decoIndex < locals.length && locals[decoIndex].from < cutAt) + cutAt = locals[decoIndex].from; + for (let i = 0; i < active.length; i++) + if (active[i].to < cutAt) + cutAt = active[i].to; + if (cutAt < end) { + restNode = child.cut(cutAt - offset); + child = child.cut(0, cutAt - offset); + end = cutAt; + index = -1; + } + } else { + while (decoIndex < locals.length && locals[decoIndex].to < end) + decoIndex++; + } + let outerDeco = child.isInline && !child.isLeaf ? active.filter((d2) => !d2.inline) : active.slice(); + onNode(child, outerDeco, deco.forChild(offset, child), index); + offset = end; + } +} +function iosHacks(dom) { + if (dom.nodeName == "UL" || dom.nodeName == "OL") { + let oldCSS = dom.style.cssText; + dom.style.cssText = oldCSS + "; list-style: square !important"; + window.getComputedStyle(dom).listStyle; + dom.style.cssText = oldCSS; + } +} +function findTextInFragment(frag, text2, from3, to) { + for (let i = 0, pos = 0; i < frag.childCount && pos <= to; ) { + let child = frag.child(i++), childStart = pos; + pos += child.nodeSize; + if (!child.isText) + continue; + let str = child.text; + while (i < frag.childCount) { + let next2 = frag.child(i++); + pos += next2.nodeSize; + if (!next2.isText) + break; + str += next2.text; + } + if (pos >= from3) { + if (pos >= to && str.slice(to - text2.length - childStart, to - childStart) == text2) + return to - text2.length; + let found3 = childStart < to ? str.lastIndexOf(text2, to - childStart - 1) : -1; + if (found3 >= 0 && found3 + text2.length + childStart >= from3) + return childStart + found3; + if (from3 == to && str.length >= to + text2.length - childStart && str.slice(to - childStart, to - childStart + text2.length) == text2) + return to; + } + } + return -1; +} +function replaceNodes(nodes, from3, to, view, replacement) { + let result = []; + for (let i = 0, off = 0; i < nodes.length; i++) { + let child = nodes[i], start = off, end = off += child.size; + if (start >= to || end <= from3) { + result.push(child); + } else { + if (start < from3) + result.push(child.slice(0, from3 - start, view)); + if (replacement) { + result.push(replacement); + replacement = void 0; + } + if (end > to) + result.push(child.slice(to - start, child.size, view)); + } + } + return result; +} +function selectionFromDOM(view, origin = null) { + let domSel = view.domSelectionRange(), doc4 = view.state.doc; + if (!domSel.focusNode) + return null; + let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0; + let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1); + if (head < 0) + return null; + let $head = doc4.resolve(head), anchor, selection; + if (selectionCollapsed(domSel)) { + anchor = head; + while (nearestDesc && !nearestDesc.node) + nearestDesc = nearestDesc.parent; + let nearestDescNode = nearestDesc.node; + if (nearestDesc && nearestDescNode.isAtom && NodeSelection.isSelectable(nearestDescNode) && nearestDesc.parent && !(nearestDescNode.isInline && isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) { + let pos = nearestDesc.posBefore; + selection = new NodeSelection(head == pos ? $head : doc4.resolve(pos)); + } + } else { + if (domSel instanceof view.dom.ownerDocument.defaultView.Selection && domSel.rangeCount > 1) { + let min2 = head, max2 = head; + for (let i = 0; i < domSel.rangeCount; i++) { + let range = domSel.getRangeAt(i); + min2 = Math.min(min2, view.docView.posFromDOM(range.startContainer, range.startOffset, 1)); + max2 = Math.max(max2, view.docView.posFromDOM(range.endContainer, range.endOffset, -1)); + } + if (min2 < 0) + return null; + [anchor, head] = max2 == view.state.selection.anchor ? [max2, min2] : [min2, max2]; + $head = doc4.resolve(head); + } else { + anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1); + } + if (anchor < 0) + return null; + } + let $anchor = doc4.resolve(anchor); + if (!selection) { + let bias = origin == "pointer" || view.state.selection.head < $head.pos && !inWidget ? 1 : -1; + selection = selectionBetween(view, $anchor, $head, bias); + } + return selection; +} +function editorOwnsSelection(view) { + return view.editable ? view.hasFocus() : hasSelection(view) && document.activeElement && document.activeElement.contains(view.dom); +} +function selectionToDOM(view, force = false) { + let sel = view.state.selection; + syncNodeSelection(view, sel); + if (!editorOwnsSelection(view)) + return; + if (!force && view.input.mouseDown && view.input.mouseDown.allowDefault && chrome) { + let domSel = view.domSelectionRange(), curSel = view.domObserver.currentSelection; + if (domSel.anchorNode && curSel.anchorNode && isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset, curSel.anchorNode, curSel.anchorOffset)) { + view.input.mouseDown.delayedSelectionSync = true; + view.domObserver.setCurSelection(); + return; + } + } + view.domObserver.disconnectSelection(); + if (view.cursorWrapper) { + selectCursorWrapper(view); + } else { + let { anchor, head } = sel, resetEditableFrom, resetEditableTo; + if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) { + if (!sel.$from.parent.inlineContent) + resetEditableFrom = temporarilyEditableNear(view, sel.from); + if (!sel.empty && !sel.$from.parent.inlineContent) + resetEditableTo = temporarilyEditableNear(view, sel.to); + } + view.docView.setSelection(anchor, head, view, force); + if (brokenSelectBetweenUneditable) { + if (resetEditableFrom) + resetEditable(resetEditableFrom); + if (resetEditableTo) + resetEditable(resetEditableTo); + } + if (sel.visible) { + view.dom.classList.remove("ProseMirror-hideselection"); + } else { + view.dom.classList.add("ProseMirror-hideselection"); + if ("onselectionchange" in document) + removeClassOnSelectionChange(view); + } + } + view.domObserver.setCurSelection(); + view.domObserver.connectSelection(); +} +var brokenSelectBetweenUneditable = safari || chrome && chrome_version < 63; +function temporarilyEditableNear(view, pos) { + let { node, offset } = view.docView.domFromPos(pos, 0); + let after = offset < node.childNodes.length ? node.childNodes[offset] : null; + let before = offset ? node.childNodes[offset - 1] : null; + if (safari && after && after.contentEditable == "false") + return setEditable(after); + if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { + if (after) + return setEditable(after); + else if (before) + return setEditable(before); + } +} +function setEditable(element2) { + element2.contentEditable = "true"; + if (safari && element2.draggable) { + element2.draggable = false; + element2.wasDraggable = true; + } + return element2; +} +function resetEditable(element2) { + element2.contentEditable = "false"; + if (element2.wasDraggable) { + element2.draggable = true; + element2.wasDraggable = null; + } +} +function removeClassOnSelectionChange(view) { + let doc4 = view.dom.ownerDocument; + doc4.removeEventListener("selectionchange", view.input.hideSelectionGuard); + let domSel = view.domSelectionRange(); + let node = domSel.anchorNode, offset = domSel.anchorOffset; + doc4.addEventListener("selectionchange", view.input.hideSelectionGuard = () => { + if (domSel.anchorNode != node || domSel.anchorOffset != offset) { + doc4.removeEventListener("selectionchange", view.input.hideSelectionGuard); + setTimeout(() => { + if (!editorOwnsSelection(view) || view.state.selection.visible) + view.dom.classList.remove("ProseMirror-hideselection"); + }, 20); + } + }); +} +function selectCursorWrapper(view) { + let domSel = view.domSelection(); + if (!domSel) + return; + let node = view.cursorWrapper.dom, img = node.nodeName == "IMG"; + if (img) + domSel.collapse(node.parentNode, domIndex(node) + 1); + else + domSel.collapse(node, 0); + if (!img && !view.state.selection.visible && ie && ie_version <= 11) { + node.disabled = true; + node.disabled = false; + } +} +function syncNodeSelection(view, sel) { + if (sel instanceof NodeSelection) { + let desc = view.docView.descAt(sel.from); + if (desc != view.lastSelectedViewDesc) { + clearNodeSelection(view); + if (desc) + desc.selectNode(); + view.lastSelectedViewDesc = desc; + } + } else { + clearNodeSelection(view); + } +} +function clearNodeSelection(view) { + if (view.lastSelectedViewDesc) { + if (view.lastSelectedViewDesc.parent) + view.lastSelectedViewDesc.deselectNode(); + view.lastSelectedViewDesc = void 0; + } +} +function selectionBetween(view, $anchor, $head, bias) { + return view.someProp("createSelectionBetween", (f) => f(view, $anchor, $head)) || TextSelection.between($anchor, $head, bias); +} +function hasFocusAndSelection(view) { + if (view.editable && !view.hasFocus()) + return false; + return hasSelection(view); +} +function hasSelection(view) { + let sel = view.domSelectionRange(); + if (!sel.anchorNode) + return false; + try { + return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)); + } catch (_2) { + return false; + } +} +function anchorInRightPlace(view) { + let anchorDOM = view.docView.domFromPos(view.state.selection.anchor, 0); + let domSel = view.domSelectionRange(); + return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset); +} +function moveSelectionBlock(state, dir) { + let { $anchor, $head } = state.selection; + let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head); + let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null; + return $start && Selection.findFrom($start, dir); +} +function apply(view, sel) { + view.dispatch(view.state.tr.setSelection(sel).scrollIntoView()); + return true; +} +function selectHorizontally(view, dir, mods) { + let sel = view.state.selection; + if (sel instanceof TextSelection) { + if (mods.indexOf("s") > -1) { + let { $head } = sel, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter; + if (!node || node.isText || !node.isLeaf) + return false; + let $newHead = view.state.doc.resolve($head.pos + node.nodeSize * (dir < 0 ? -1 : 1)); + return apply(view, new TextSelection(sel.$anchor, $newHead)); + } else if (!sel.empty) { + return false; + } else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) { + let next2 = moveSelectionBlock(view.state, dir); + if (next2 && next2 instanceof NodeSelection) + return apply(view, next2); + return false; + } else if (!(mac2 && mods.indexOf("m") > -1)) { + let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc; + if (!node || node.isText) + return false; + let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos; + if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) + return false; + if (NodeSelection.isSelectable(node)) { + return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head)); + } else if (webkit) { + return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize))); + } else { + return false; + } + } + } else if (sel instanceof NodeSelection && sel.node.isInline) { + return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from)); + } else { + let next2 = moveSelectionBlock(view.state, dir); + if (next2) + return apply(view, next2); + return false; + } +} +function nodeLen(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; +} +function isIgnorable(dom, dir) { + let desc = dom.pmViewDesc; + return desc && desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR"); +} +function skipIgnoredNodes(view, dir) { + return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view); +} +function skipIgnoredNodesBefore(view) { + let sel = view.domSelectionRange(); + let node = sel.focusNode, offset = sel.focusOffset; + if (!node) + return; + let moveNode, moveOffset, force = false; + if (gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset], -1)) + force = true; + for (; ; ) { + if (offset > 0) { + if (node.nodeType != 1) { + break; + } else { + let before = node.childNodes[offset - 1]; + if (isIgnorable(before, -1)) { + moveNode = node; + moveOffset = --offset; + } else if (before.nodeType == 3) { + node = before; + offset = node.nodeValue.length; + } else + break; + } + } else if (isBlockNode(node)) { + break; + } else { + let prev = node.previousSibling; + while (prev && isIgnorable(prev, -1)) { + moveNode = node.parentNode; + moveOffset = domIndex(prev); + prev = prev.previousSibling; + } + if (!prev) { + node = node.parentNode; + if (node == view.dom) + break; + offset = 0; + } else { + node = prev; + offset = nodeLen(node); + } + } + } + if (force) + setSelFocus(view, node, offset); + else if (moveNode) + setSelFocus(view, moveNode, moveOffset); +} +function skipIgnoredNodesAfter(view) { + let sel = view.domSelectionRange(); + let node = sel.focusNode, offset = sel.focusOffset; + if (!node) + return; + let len = nodeLen(node); + let moveNode, moveOffset; + for (; ; ) { + if (offset < len) { + if (node.nodeType != 1) + break; + let after = node.childNodes[offset]; + if (isIgnorable(after, 1)) { + moveNode = node; + moveOffset = ++offset; + } else + break; + } else if (isBlockNode(node)) { + break; + } else { + let next2 = node.nextSibling; + while (next2 && isIgnorable(next2, 1)) { + moveNode = next2.parentNode; + moveOffset = domIndex(next2) + 1; + next2 = next2.nextSibling; + } + if (!next2) { + node = node.parentNode; + if (node == view.dom) + break; + offset = len = 0; + } else { + node = next2; + offset = 0; + len = nodeLen(node); + } + } + } + if (moveNode) + setSelFocus(view, moveNode, moveOffset); +} +function isBlockNode(dom) { + let desc = dom.pmViewDesc; + return desc && desc.node && desc.node.isBlock; +} +function textNodeAfter(node, offset) { + while (node && offset == node.childNodes.length && !hasBlockDesc(node)) { + offset = domIndex(node) + 1; + node = node.parentNode; + } + while (node && offset < node.childNodes.length) { + let next2 = node.childNodes[offset]; + if (next2.nodeType == 3) + return next2; + if (next2.nodeType == 1 && next2.contentEditable == "false") + break; + node = next2; + offset = 0; + } +} +function textNodeBefore(node, offset) { + while (node && !offset && !hasBlockDesc(node)) { + offset = domIndex(node); + node = node.parentNode; + } + while (node && offset) { + let next2 = node.childNodes[offset - 1]; + if (next2.nodeType == 3) + return next2; + if (next2.nodeType == 1 && next2.contentEditable == "false") + break; + node = next2; + offset = node.childNodes.length; + } +} +function setSelFocus(view, node, offset) { + if (node.nodeType != 3) { + let before, after; + if (after = textNodeAfter(node, offset)) { + node = after; + offset = 0; + } else if (before = textNodeBefore(node, offset)) { + node = before; + offset = before.nodeValue.length; + } + } + let sel = view.domSelection(); + if (!sel) + return; + if (selectionCollapsed(sel)) { + let range = document.createRange(); + range.setEnd(node, offset); + range.setStart(node, offset); + sel.removeAllRanges(); + sel.addRange(range); + } else if (sel.extend) { + sel.extend(node, offset); + } + view.domObserver.setCurSelection(); + let { state } = view; + setTimeout(() => { + if (view.state == state) + selectionToDOM(view); + }, 50); +} +function findDirection(view, pos) { + let $pos = view.state.doc.resolve(pos); + if (!(chrome || windows) && $pos.parent.inlineContent) { + let coords = view.coordsAtPos(pos); + if (pos > $pos.start()) { + let before = view.coordsAtPos(pos - 1); + let mid = (before.top + before.bottom) / 2; + if (mid > coords.top && mid < coords.bottom && Math.abs(before.left - coords.left) > 1) + return before.left < coords.left ? "ltr" : "rtl"; + } + if (pos < $pos.end()) { + let after = view.coordsAtPos(pos + 1); + let mid = (after.top + after.bottom) / 2; + if (mid > coords.top && mid < coords.bottom && Math.abs(after.left - coords.left) > 1) + return after.left > coords.left ? "ltr" : "rtl"; + } + } + let computed = getComputedStyle(view.dom).direction; + return computed == "rtl" ? "rtl" : "ltr"; +} +function selectVertically(view, dir, mods) { + let sel = view.state.selection; + if (sel instanceof TextSelection && !sel.empty || mods.indexOf("s") > -1) + return false; + if (mac2 && mods.indexOf("m") > -1) + return false; + let { $from, $to } = sel; + if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) { + let next2 = moveSelectionBlock(view.state, dir); + if (next2 && next2 instanceof NodeSelection) + return apply(view, next2); + } + if (!$from.parent.inlineContent) { + let side = dir < 0 ? $from : $to; + let beyond = sel instanceof AllSelection ? Selection.near(side, dir) : Selection.findFrom(side, dir); + return beyond ? apply(view, beyond) : false; + } + return false; +} +function stopNativeHorizontalDelete(view, dir) { + if (!(view.state.selection instanceof TextSelection)) + return true; + let { $head, $anchor, empty: empty2 } = view.state.selection; + if (!$head.sameParent($anchor)) + return true; + if (!empty2) + return false; + if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) + return true; + let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter); + if (nextNode && !nextNode.isText) { + let tr2 = view.state.tr; + if (dir < 0) + tr2.delete($head.pos - nextNode.nodeSize, $head.pos); + else + tr2.delete($head.pos, $head.pos + nextNode.nodeSize); + view.dispatch(tr2); + return true; + } + return false; +} +function switchEditable(view, node, state) { + view.domObserver.stop(); + node.contentEditable = state; + view.domObserver.start(); +} +function safariDownArrowBug(view) { + if (!safari || view.state.selection.$head.parentOffset > 0) + return false; + let { focusNode, focusOffset } = view.domSelectionRange(); + if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && focusNode.firstChild && focusNode.firstChild.contentEditable == "false") { + let child = focusNode.firstChild; + switchEditable(view, child, "true"); + setTimeout(() => switchEditable(view, child, "false"), 20); + } + return false; +} +function getMods(event) { + let result = ""; + if (event.ctrlKey) + result += "c"; + if (event.metaKey) + result += "m"; + if (event.altKey) + result += "a"; + if (event.shiftKey) + result += "s"; + return result; +} +function captureKeyDown(view, event) { + let code = event.keyCode, mods = getMods(event); + if (code == 8 || mac2 && code == 72 && mods == "c") { + return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodes(view, -1); + } else if (code == 46 && !event.shiftKey || mac2 && code == 68 && mods == "c") { + return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodes(view, 1); + } else if (code == 13 || code == 27) { + return true; + } else if (code == 37 || mac2 && code == 66 && mods == "c") { + let dir = code == 37 ? findDirection(view, view.state.selection.from) == "ltr" ? -1 : 1 : -1; + return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir); + } else if (code == 39 || mac2 && code == 70 && mods == "c") { + let dir = code == 39 ? findDirection(view, view.state.selection.from) == "ltr" ? 1 : -1 : 1; + return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir); + } else if (code == 38 || mac2 && code == 80 && mods == "c") { + return selectVertically(view, -1, mods) || skipIgnoredNodes(view, -1); + } else if (code == 40 || mac2 && code == 78 && mods == "c") { + return safariDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodes(view, 1); + } else if (mods == (mac2 ? "m" : "c") && (code == 66 || code == 73 || code == 89 || code == 90)) { + return true; + } + return false; +} +function serializeForClipboard(view, slice2) { + view.someProp("transformCopied", (f) => { + slice2 = f(slice2, view); + }); + let context = [], { content, openStart, openEnd } = slice2; + while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) { + openStart--; + openEnd--; + let node = content.firstChild; + context.push(node.type.name, node.attrs != node.type.defaultAttrs ? node.attrs : null); + content = node.content; + } + let serializer = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema); + let doc4 = detachedDoc(), wrap2 = doc4.createElement("div"); + wrap2.appendChild(serializer.serializeFragment(content, { document: doc4 })); + let firstChild = wrap2.firstChild, needsWrap, wrappers = 0; + while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) { + for (let i = needsWrap.length - 1; i >= 0; i--) { + let wrapper = doc4.createElement(needsWrap[i]); + while (wrap2.firstChild) + wrapper.appendChild(wrap2.firstChild); + wrap2.appendChild(wrapper); + wrappers++; + } + firstChild = wrap2.firstChild; + } + if (firstChild && firstChild.nodeType == 1) + firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`); + let text2 = view.someProp("clipboardTextSerializer", (f) => f(slice2, view)) || slice2.content.textBetween(0, slice2.content.size, "\n\n"); + return { dom: wrap2, text: text2, slice: slice2 }; +} +function parseFromClipboard(view, text2, html, plainText, $context) { + let inCode = $context.parent.type.spec.code; + let dom, slice2; + if (!html && !text2) + return null; + let asText = !!text2 && (plainText || inCode || !html); + if (asText) { + view.someProp("transformPastedText", (f) => { + text2 = f(text2, inCode || plainText, view); + }); + if (inCode) { + slice2 = new Slice(Fragment.from(view.state.schema.text(text2.replace(/\r\n?/g, "\n"))), 0, 0); + view.someProp("transformPasted", (f) => { + slice2 = f(slice2, view, true); + }); + return slice2; + } + let parsed = view.someProp("clipboardTextParser", (f) => f(text2, $context, plainText, view)); + if (parsed) { + slice2 = parsed; + } else { + let marks = $context.marks(); + let { schema } = view.state, serializer = DOMSerializer.fromSchema(schema); + dom = document.createElement("div"); + text2.split(/(?:\r\n?|\n)+/).forEach((block) => { + let p = dom.appendChild(document.createElement("p")); + if (block) + p.appendChild(serializer.serializeNode(schema.text(block, marks))); + }); + } + } else { + view.someProp("transformPastedHTML", (f) => { + html = f(html, view); + }); + dom = readHTML(html); + if (webkit) + restoreReplacedSpaces(dom); + } + let contextNode = dom && dom.querySelector("[data-pm-slice]"); + let sliceData = contextNode && /^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(contextNode.getAttribute("data-pm-slice") || ""); + if (sliceData && sliceData[3]) + for (let i = +sliceData[3]; i > 0; i--) { + let child = dom.firstChild; + while (child && child.nodeType != 1) + child = child.nextSibling; + if (!child) + break; + dom = child; + } + if (!slice2) { + let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser2.fromSchema(view.state.schema); + slice2 = parser.parseSlice(dom, { + preserveWhitespace: !!(asText || sliceData), + context: $context, + ruleFromNode(dom2) { + if (dom2.nodeName == "BR" && !dom2.nextSibling && dom2.parentNode && !inlineParents.test(dom2.parentNode.nodeName)) + return { ignore: true }; + return null; + } + }); + } + if (sliceData) { + slice2 = addContext(closeSlice(slice2, +sliceData[1], +sliceData[2]), sliceData[4]); + } else { + slice2 = Slice.maxOpen(normalizeSiblings(slice2.content, $context), true); + if (slice2.openStart || slice2.openEnd) { + let openStart = 0, openEnd = 0; + for (let node = slice2.content.firstChild; openStart < slice2.openStart && !node.type.spec.isolating; openStart++, node = node.firstChild) { + } + for (let node = slice2.content.lastChild; openEnd < slice2.openEnd && !node.type.spec.isolating; openEnd++, node = node.lastChild) { + } + slice2 = closeSlice(slice2, openStart, openEnd); + } + } + view.someProp("transformPasted", (f) => { + slice2 = f(slice2, view, asText); + }); + return slice2; +} +var inlineParents = /^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i; +function normalizeSiblings(fragment, $context) { + if (fragment.childCount < 2) + return fragment; + for (let d2 = $context.depth; d2 >= 0; d2--) { + let parent = $context.node(d2); + let match2 = parent.contentMatchAt($context.index(d2)); + let lastWrap, result = []; + fragment.forEach((node) => { + if (!result) + return; + let wrap2 = match2.findWrapping(node.type), inLast; + if (!wrap2) + return result = null; + if (inLast = result.length && lastWrap.length && addToSibling(wrap2, lastWrap, node, result[result.length - 1], 0)) { + result[result.length - 1] = inLast; + } else { + if (result.length) + result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length); + let wrapped = withWrappers(node, wrap2); + result.push(wrapped); + match2 = match2.matchType(wrapped.type); + lastWrap = wrap2; + } + }); + if (result) + return Fragment.from(result); + } + return fragment; +} +function withWrappers(node, wrap2, from3 = 0) { + for (let i = wrap2.length - 1; i >= from3; i--) + node = wrap2[i].create(null, Fragment.from(node)); + return node; +} +function addToSibling(wrap2, lastWrap, node, sibling, depth) { + if (depth < wrap2.length && depth < lastWrap.length && wrap2[depth] == lastWrap[depth]) { + let inner = addToSibling(wrap2, lastWrap, node, sibling.lastChild, depth + 1); + if (inner) + return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner)); + let match2 = sibling.contentMatchAt(sibling.childCount); + if (match2.matchType(depth == wrap2.length - 1 ? node.type : wrap2[depth + 1])) + return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap2, depth + 1)))); + } +} +function closeRight(node, depth) { + if (depth == 0) + return node; + let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1)); + let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true); + return node.copy(fragment.append(fill)); +} +function closeRange(fragment, side, from3, to, depth, openEnd) { + let node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content; + if (fragment.childCount > 1) + openEnd = 0; + if (depth < to - 1) + inner = closeRange(inner, side, from3, to, depth + 1, openEnd); + if (depth >= from3) + inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, openEnd <= depth).append(inner) : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)); + return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner)); +} +function closeSlice(slice2, openStart, openEnd) { + if (openStart < slice2.openStart) + slice2 = new Slice(closeRange(slice2.content, -1, openStart, slice2.openStart, 0, slice2.openEnd), openStart, slice2.openEnd); + if (openEnd < slice2.openEnd) + slice2 = new Slice(closeRange(slice2.content, 1, openEnd, slice2.openEnd, 0, 0), slice2.openStart, openEnd); + return slice2; +} +var wrapMap = { + thead: ["table"], + tbody: ["table"], + tfoot: ["table"], + caption: ["table"], + colgroup: ["table"], + col: ["table", "colgroup"], + tr: ["table", "tbody"], + td: ["table", "tbody", "tr"], + th: ["table", "tbody", "tr"] +}; +var _detachedDoc = null; +function detachedDoc() { + return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title")); +} +var _policy = null; +function maybeWrapTrusted(html) { + let trustedTypes = window.trustedTypes; + if (!trustedTypes) + return html; + if (!_policy) + _policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s }); + return _policy.createHTML(html); +} +function readHTML(html) { + let metas = /^(\s*]*>)*/.exec(html); + if (metas) + html = html.slice(metas[0].length); + let elt = detachedDoc().createElement("div"); + let firstTag = /<([a-z][^>\s]+)/i.exec(html), wrap2; + if (wrap2 = firstTag && wrapMap[firstTag[1].toLowerCase()]) + html = wrap2.map((n) => "<" + n + ">").join("") + html + wrap2.map((n) => "").reverse().join(""); + elt.innerHTML = maybeWrapTrusted(html); + if (wrap2) + for (let i = 0; i < wrap2.length; i++) + elt = elt.querySelector(wrap2[i]) || elt; + return elt; +} +function restoreReplacedSpaces(dom) { + let nodes = dom.querySelectorAll(chrome ? "span:not([class]):not([style])" : "span.Apple-converted-space"); + for (let i = 0; i < nodes.length; i++) { + let node = nodes[i]; + if (node.childNodes.length == 1 && node.textContent == "\xA0" && node.parentNode) + node.parentNode.replaceChild(dom.ownerDocument.createTextNode(" "), node); + } +} +function addContext(slice2, context) { + if (!slice2.size) + return slice2; + let schema = slice2.content.firstChild.type.schema, array; + try { + array = JSON.parse(context); + } catch (e) { + return slice2; + } + let { content, openStart, openEnd } = slice2; + for (let i = array.length - 2; i >= 0; i -= 2) { + let type = schema.nodes[array[i]]; + if (!type || type.hasRequiredAttrs()) + break; + content = Fragment.from(type.create(array[i + 1], content)); + openStart++; + openEnd++; + } + return new Slice(content, openStart, openEnd); +} +var handlers = {}; +var editHandlers = {}; +var passiveHandlers = { touchstart: true, touchmove: true }; +var InputState = class { + constructor() { + this.shiftKey = false; + this.mouseDown = null; + this.lastKeyCode = null; + this.lastKeyCodeTime = 0; + this.lastClick = { time: 0, x: 0, y: 0, type: "", button: 0 }; + this.lastSelectionOrigin = null; + this.lastSelectionTime = 0; + this.lastIOSEnter = 0; + this.lastIOSEnterFallbackTimeout = -1; + this.lastFocus = 0; + this.lastTouch = 0; + this.lastChromeDelete = 0; + this.composing = false; + this.compositionNode = null; + this.composingTimeout = -1; + this.compositionNodes = []; + this.compositionEndedAt = -2e8; + this.compositionID = 1; + this.badSafariComposition = false; + this.compositionPendingChanges = 0; + this.domChangeCount = 0; + this.eventHandlers = /* @__PURE__ */ Object.create(null); + this.hideSelectionGuard = null; + } +}; +function initInput(view) { + for (let event in handlers) { + let handler = handlers[event]; + view.dom.addEventListener(event, view.input.eventHandlers[event] = (event2) => { + if (eventBelongsToView(view, event2) && !runCustomHandler(view, event2) && (view.editable || !(event2.type in editHandlers))) + handler(view, event2); + }, passiveHandlers[event] ? { passive: true } : void 0); + } + if (safari) + view.dom.addEventListener("input", () => null); + ensureListeners(view); +} +function setSelectionOrigin(view, origin) { + view.input.lastSelectionOrigin = origin; + view.input.lastSelectionTime = Date.now(); +} +function destroyInput(view) { + view.domObserver.stop(); + for (let type in view.input.eventHandlers) + view.dom.removeEventListener(type, view.input.eventHandlers[type]); + clearTimeout(view.input.composingTimeout); + clearTimeout(view.input.lastIOSEnterFallbackTimeout); +} +function ensureListeners(view) { + view.someProp("handleDOMEvents", (currentHandlers) => { + for (let type in currentHandlers) + if (!view.input.eventHandlers[type]) + view.dom.addEventListener(type, view.input.eventHandlers[type] = (event) => runCustomHandler(view, event)); + }); +} +function runCustomHandler(view, event) { + return view.someProp("handleDOMEvents", (handlers2) => { + let handler = handlers2[event.type]; + return handler ? handler(view, event) || event.defaultPrevented : false; + }); +} +function eventBelongsToView(view, event) { + if (!event.bubbles) + return true; + if (event.defaultPrevented) + return false; + for (let node = event.target; node != view.dom; node = node.parentNode) + if (!node || node.nodeType == 11 || node.pmViewDesc && node.pmViewDesc.stopEvent(event)) + return false; + return true; +} +function dispatchEvent(view, event) { + if (!runCustomHandler(view, event) && handlers[event.type] && (view.editable || !(event.type in editHandlers))) + handlers[event.type](view, event); +} +editHandlers.keydown = (view, _event) => { + let event = _event; + view.input.shiftKey = event.keyCode == 16 || event.shiftKey; + if (inOrNearComposition(view, event)) + return; + view.input.lastKeyCode = event.keyCode; + view.input.lastKeyCodeTime = Date.now(); + if (android && chrome && event.keyCode == 13) + return; + if (event.keyCode != 229) + view.domObserver.forceFlush(); + if (ios && event.keyCode == 13 && !event.ctrlKey && !event.altKey && !event.metaKey) { + let now = Date.now(); + view.input.lastIOSEnter = now; + view.input.lastIOSEnterFallbackTimeout = setTimeout(() => { + if (view.input.lastIOSEnter == now) { + view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter"))); + view.input.lastIOSEnter = 0; + } + }, 200); + } else if (view.someProp("handleKeyDown", (f) => f(view, event)) || captureKeyDown(view, event)) { + event.preventDefault(); + } else { + setSelectionOrigin(view, "key"); + } +}; +editHandlers.keyup = (view, event) => { + if (event.keyCode == 16) + view.input.shiftKey = false; +}; +editHandlers.keypress = (view, _event) => { + let event = _event; + if (inOrNearComposition(view, event) || !event.charCode || event.ctrlKey && !event.altKey || mac2 && event.metaKey) + return; + if (view.someProp("handleKeyPress", (f) => f(view, event))) { + event.preventDefault(); + return; + } + let sel = view.state.selection; + if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) { + let text2 = String.fromCharCode(event.charCode); + let deflt = () => view.state.tr.insertText(text2).scrollIntoView(); + if (!/[\r\n]/.test(text2) && !view.someProp("handleTextInput", (f) => f(view, sel.$from.pos, sel.$to.pos, text2, deflt))) + view.dispatch(deflt()); + event.preventDefault(); + } +}; +function eventCoords(event) { + return { left: event.clientX, top: event.clientY }; +} +function isNear(event, click) { + let dx = click.x - event.clientX, dy = click.y - event.clientY; + return dx * dx + dy * dy < 100; +} +function runHandlerOnContext(view, propName, pos, inside, event) { + if (inside == -1) + return false; + let $pos = view.state.doc.resolve(inside); + for (let i = $pos.depth + 1; i > 0; i--) { + if (view.someProp(propName, (f) => i > $pos.depth ? f(view, pos, $pos.nodeAfter, $pos.before(i), event, true) : f(view, pos, $pos.node(i), $pos.before(i), event, false))) + return true; + } + return false; +} +function updateSelection(view, selection, origin) { + if (!view.focused) + view.focus(); + if (view.state.selection.eq(selection)) + return; + let tr2 = view.state.tr.setSelection(selection); + if (origin == "pointer") + tr2.setMeta("pointer", true); + view.dispatch(tr2); +} +function selectClickedLeaf(view, inside) { + if (inside == -1) + return false; + let $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter; + if (node && node.isAtom && NodeSelection.isSelectable(node)) { + updateSelection(view, new NodeSelection($pos), "pointer"); + return true; + } + return false; +} +function selectClickedNode(view, inside) { + if (inside == -1) + return false; + let sel = view.state.selection, selectedNode, selectAt; + if (sel instanceof NodeSelection) + selectedNode = sel.node; + let $pos = view.state.doc.resolve(inside); + for (let i = $pos.depth + 1; i > 0; i--) { + let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); + if (NodeSelection.isSelectable(node)) { + if (selectedNode && sel.$from.depth > 0 && i >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) + selectAt = $pos.before(sel.$from.depth); + else + selectAt = $pos.before(i); + break; + } + } + if (selectAt != null) { + updateSelection(view, NodeSelection.create(view.state.doc, selectAt), "pointer"); + return true; + } else { + return false; + } +} +function handleSingleClick(view, pos, inside, event, selectNode) { + return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || view.someProp("handleClick", (f) => f(view, pos, event)) || (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside)); +} +function handleDoubleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || view.someProp("handleDoubleClick", (f) => f(view, pos, event)); +} +function handleTripleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || view.someProp("handleTripleClick", (f) => f(view, pos, event)) || defaultTripleClick(view, inside, event); +} +function defaultTripleClick(view, inside, event) { + if (event.button != 0) + return false; + let doc4 = view.state.doc; + if (inside == -1) { + if (doc4.inlineContent) { + updateSelection(view, TextSelection.create(doc4, 0, doc4.content.size), "pointer"); + return true; + } + return false; + } + let $pos = doc4.resolve(inside); + for (let i = $pos.depth + 1; i > 0; i--) { + let node = i > $pos.depth ? $pos.nodeAfter : $pos.node(i); + let nodePos = $pos.before(i); + if (node.inlineContent) + updateSelection(view, TextSelection.create(doc4, nodePos + 1, nodePos + 1 + node.content.size), "pointer"); + else if (NodeSelection.isSelectable(node)) + updateSelection(view, NodeSelection.create(doc4, nodePos), "pointer"); + else + continue; + return true; + } +} +function forceDOMFlush(view) { + return endComposition(view); +} +var selectNodeModifier = mac2 ? "metaKey" : "ctrlKey"; +handlers.mousedown = (view, _event) => { + let event = _event; + view.input.shiftKey = event.shiftKey; + let flushed = forceDOMFlush(view); + let now = Date.now(), type = "singleClick"; + if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier] && view.input.lastClick.button == event.button) { + if (view.input.lastClick.type == "singleClick") + type = "doubleClick"; + else if (view.input.lastClick.type == "doubleClick") + type = "tripleClick"; + } + view.input.lastClick = { time: now, x: event.clientX, y: event.clientY, type, button: event.button }; + let pos = view.posAtCoords(eventCoords(event)); + if (!pos) + return; + if (type == "singleClick") { + if (view.input.mouseDown) + view.input.mouseDown.done(); + view.input.mouseDown = new MouseDown(view, pos, event, !!flushed); + } else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) { + event.preventDefault(); + } else { + setSelectionOrigin(view, "pointer"); + } +}; +var MouseDown = class { + constructor(view, pos, event, flushed) { + this.view = view; + this.pos = pos; + this.event = event; + this.flushed = flushed; + this.delayedSelectionSync = false; + this.mightDrag = null; + this.startDoc = view.state.doc; + this.selectNode = !!event[selectNodeModifier]; + this.allowDefault = event.shiftKey; + let targetNode, targetPos; + if (pos.inside > -1) { + targetNode = view.state.doc.nodeAt(pos.inside); + targetPos = pos.inside; + } else { + let $pos = view.state.doc.resolve(pos.pos); + targetNode = $pos.parent; + targetPos = $pos.depth ? $pos.before() : 0; + } + const target = flushed ? null : event.target; + const targetDesc = target ? view.docView.nearestDesc(target, true) : null; + this.target = targetDesc && targetDesc.nodeDOM.nodeType == 1 ? targetDesc.nodeDOM : null; + let { selection } = view.state; + if (event.button == 0 && (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos)) + this.mightDrag = { + node: targetNode, + pos: targetPos, + addAttr: !!(this.target && !this.target.draggable), + setUneditable: !!(this.target && gecko && !this.target.hasAttribute("contentEditable")) + }; + if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) + this.target.draggable = true; + if (this.mightDrag.setUneditable) + setTimeout(() => { + if (this.view.input.mouseDown == this) + this.target.setAttribute("contentEditable", "false"); + }, 20); + this.view.domObserver.start(); + } + view.root.addEventListener("mouseup", this.up = this.up.bind(this)); + view.root.addEventListener("mousemove", this.move = this.move.bind(this)); + setSelectionOrigin(view, "pointer"); + } + done() { + this.view.root.removeEventListener("mouseup", this.up); + this.view.root.removeEventListener("mousemove", this.move); + if (this.mightDrag && this.target) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) + this.target.removeAttribute("draggable"); + if (this.mightDrag.setUneditable) + this.target.removeAttribute("contentEditable"); + this.view.domObserver.start(); + } + if (this.delayedSelectionSync) + setTimeout(() => selectionToDOM(this.view)); + this.view.input.mouseDown = null; + } + up(event) { + this.done(); + if (!this.view.dom.contains(event.target)) + return; + let pos = this.pos; + if (this.view.state.doc != this.startDoc) + pos = this.view.posAtCoords(eventCoords(event)); + this.updateAllowDefault(event); + if (this.allowDefault || !pos) { + setSelectionOrigin(this.view, "pointer"); + } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) { + event.preventDefault(); + } else if (event.button == 0 && (this.flushed || // Safari ignores clicks on draggable elements + safari && this.mightDrag && !this.mightDrag.node.isAtom || // Chrome will sometimes treat a node selection as a + // cursor, but still report that the node is selected + // when asked through getSelection. You'll then get a + // situation where clicking at the point where that + // (hidden) cursor is doesn't change the selection, and + // thus doesn't get a reaction from ProseMirror. This + // works around that. + chrome && !this.view.state.selection.visible && Math.min(Math.abs(pos.pos - this.view.state.selection.from), Math.abs(pos.pos - this.view.state.selection.to)) <= 2)) { + updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer"); + event.preventDefault(); + } else { + setSelectionOrigin(this.view, "pointer"); + } + } + move(event) { + this.updateAllowDefault(event); + setSelectionOrigin(this.view, "pointer"); + if (event.buttons == 0) + this.done(); + } + updateAllowDefault(event) { + if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || Math.abs(this.event.y - event.clientY) > 4)) + this.allowDefault = true; + } +}; +handlers.touchstart = (view) => { + view.input.lastTouch = Date.now(); + forceDOMFlush(view); + setSelectionOrigin(view, "pointer"); +}; +handlers.touchmove = (view) => { + view.input.lastTouch = Date.now(); + setSelectionOrigin(view, "pointer"); +}; +handlers.contextmenu = (view) => forceDOMFlush(view); +function inOrNearComposition(view, event) { + if (view.composing) + return true; + if (safari && Math.abs(event.timeStamp - view.input.compositionEndedAt) < 500) { + view.input.compositionEndedAt = -2e8; + return true; + } + return false; +} +var timeoutComposition = android ? 5e3 : -1; +editHandlers.compositionstart = editHandlers.compositionupdate = (view) => { + if (!view.composing) { + view.domObserver.flush(); + let { state } = view, $pos = state.selection.$to; + if (state.selection instanceof TextSelection && (state.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some((m2) => m2.type.spec.inclusive === false) || chrome && windows && selectionBeforeUneditable(view))) { + view.markCursor = view.state.storedMarks || $pos.marks(); + endComposition(view, true); + view.markCursor = null; + } else { + endComposition(view, !state.selection.empty); + if (gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) { + let sel = view.domSelectionRange(); + for (let node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0; ) { + let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]; + if (!before) + break; + if (before.nodeType == 3) { + let sel2 = view.domSelection(); + if (sel2) + sel2.collapse(before, before.nodeValue.length); + break; + } else { + node = before; + offset = -1; + } + } + } + } + view.input.composing = true; + } + scheduleComposeEnd(view, timeoutComposition); +}; +function selectionBeforeUneditable(view) { + let { focusNode, focusOffset } = view.domSelectionRange(); + if (!focusNode || focusNode.nodeType != 1 || focusOffset >= focusNode.childNodes.length) + return false; + let next2 = focusNode.childNodes[focusOffset]; + return next2.nodeType == 1 && next2.contentEditable == "false"; +} +editHandlers.compositionend = (view, event) => { + if (view.composing) { + view.input.composing = false; + view.input.compositionEndedAt = event.timeStamp; + view.input.compositionPendingChanges = view.domObserver.pendingRecords().length ? view.input.compositionID : 0; + view.input.compositionNode = null; + if (view.input.badSafariComposition) + view.domObserver.forceFlush(); + else if (view.input.compositionPendingChanges) + Promise.resolve().then(() => view.domObserver.flush()); + view.input.compositionID++; + scheduleComposeEnd(view, 20); + } +}; +function scheduleComposeEnd(view, delay) { + clearTimeout(view.input.composingTimeout); + if (delay > -1) + view.input.composingTimeout = setTimeout(() => endComposition(view), delay); +} +function clearComposition(view) { + if (view.composing) { + view.input.composing = false; + view.input.compositionEndedAt = timestampFromCustomEvent(); + } + while (view.input.compositionNodes.length > 0) + view.input.compositionNodes.pop().markParentsDirty(); +} +function findCompositionNode(view) { + let sel = view.domSelectionRange(); + if (!sel.focusNode) + return null; + let textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset); + let textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset); + if (textBefore && textAfter && textBefore != textAfter) { + let descAfter = textAfter.pmViewDesc, lastChanged = view.domObserver.lastChangedTextNode; + if (textBefore == lastChanged || textAfter == lastChanged) + return lastChanged; + if (!descAfter || !descAfter.isText(textAfter.nodeValue)) { + return textAfter; + } else if (view.input.compositionNode == textAfter) { + let descBefore = textBefore.pmViewDesc; + if (!(!descBefore || !descBefore.isText(textBefore.nodeValue))) + return textAfter; + } + } + return textBefore || textAfter; +} +function timestampFromCustomEvent() { + let event = document.createEvent("Event"); + event.initEvent("event", true, true); + return event.timeStamp; +} +function endComposition(view, restarting = false) { + if (android && view.domObserver.flushingSoon >= 0) + return; + view.domObserver.forceFlush(); + clearComposition(view); + if (restarting || view.docView && view.docView.dirty) { + let sel = selectionFromDOM(view), cur = view.state.selection; + if (sel && !sel.eq(cur)) + view.dispatch(view.state.tr.setSelection(sel)); + else if ((view.markCursor || restarting) && !cur.$from.node(cur.$from.sharedDepth(cur.to)).inlineContent) + view.dispatch(view.state.tr.deleteSelection()); + else + view.updateState(view.state); + return true; + } + return false; +} +function captureCopy(view, dom) { + if (!view.dom.parentNode) + return; + let wrap2 = view.dom.parentNode.appendChild(document.createElement("div")); + wrap2.appendChild(dom); + wrap2.style.cssText = "position: fixed; left: -10000px; top: 10px"; + let sel = getSelection(), range = document.createRange(); + range.selectNodeContents(dom); + view.dom.blur(); + sel.removeAllRanges(); + sel.addRange(range); + setTimeout(() => { + if (wrap2.parentNode) + wrap2.parentNode.removeChild(wrap2); + view.focus(); + }, 50); +} +var brokenClipboardAPI = ie && ie_version < 15 || ios && webkit_version < 604; +handlers.copy = editHandlers.cut = (view, _event) => { + let event = _event; + let sel = view.state.selection, cut2 = event.type == "cut"; + if (sel.empty) + return; + let data = brokenClipboardAPI ? null : event.clipboardData; + let slice2 = sel.content(), { dom, text: text2 } = serializeForClipboard(view, slice2); + if (data) { + event.preventDefault(); + data.clearData(); + data.setData("text/html", dom.innerHTML); + data.setData("text/plain", text2); + } else { + captureCopy(view, dom); + } + if (cut2) + view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut")); +}; +function sliceSingleNode(slice2) { + return slice2.openStart == 0 && slice2.openEnd == 0 && slice2.content.childCount == 1 ? slice2.content.firstChild : null; +} +function capturePaste(view, event) { + if (!view.dom.parentNode) + return; + let plainText = view.input.shiftKey || view.state.selection.$from.parent.type.spec.code; + let target = view.dom.parentNode.appendChild(document.createElement(plainText ? "textarea" : "div")); + if (!plainText) + target.contentEditable = "true"; + target.style.cssText = "position: fixed; left: -10000px; top: 10px"; + target.focus(); + let plain = view.input.shiftKey && view.input.lastKeyCode != 45; + setTimeout(() => { + view.focus(); + if (target.parentNode) + target.parentNode.removeChild(target); + if (plainText) + doPaste(view, target.value, null, plain, event); + else + doPaste(view, target.textContent, target.innerHTML, plain, event); + }, 50); +} +function doPaste(view, text2, html, preferPlain, event) { + let slice2 = parseFromClipboard(view, text2, html, preferPlain, view.state.selection.$from); + if (view.someProp("handlePaste", (f) => f(view, event, slice2 || Slice.empty))) + return true; + if (!slice2) + return false; + let singleNode = sliceSingleNode(slice2); + let tr2 = singleNode ? view.state.tr.replaceSelectionWith(singleNode, preferPlain) : view.state.tr.replaceSelection(slice2); + view.dispatch(tr2.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); + return true; +} +function getText(clipboardData) { + let text2 = clipboardData.getData("text/plain") || clipboardData.getData("Text"); + if (text2) + return text2; + let uris = clipboardData.getData("text/uri-list"); + return uris ? uris.replace(/\r?\n/g, " ") : ""; +} +editHandlers.paste = (view, _event) => { + let event = _event; + if (view.composing && !android) + return; + let data = brokenClipboardAPI ? null : event.clipboardData; + let plain = view.input.shiftKey && view.input.lastKeyCode != 45; + if (data && doPaste(view, getText(data), data.getData("text/html"), plain, event)) + event.preventDefault(); + else + capturePaste(view, event); +}; +var Dragging = class { + constructor(slice2, move, node) { + this.slice = slice2; + this.move = move; + this.node = node; + } +}; +var dragCopyModifier = mac2 ? "altKey" : "ctrlKey"; +function dragMoves(view, event) { + let copy3; + view.someProp("dragCopies", (test) => { + copy3 = copy3 || test(event); + }); + return copy3 != null ? !copy3 : !event[dragCopyModifier]; +} +handlers.dragstart = (view, _event) => { + let event = _event; + let mouseDown = view.input.mouseDown; + if (mouseDown) + mouseDown.done(); + if (!event.dataTransfer) + return; + let sel = view.state.selection; + let pos = sel.empty ? null : view.posAtCoords(eventCoords(event)); + let node; + if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1 : sel.to)) ; + else if (mouseDown && mouseDown.mightDrag) { + node = NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos); + } else if (event.target && event.target.nodeType == 1) { + let desc = view.docView.nearestDesc(event.target, true); + if (desc && desc.node.type.spec.draggable && desc != view.docView) + node = NodeSelection.create(view.state.doc, desc.posBefore); + } + let draggedSlice = (node || view.state.selection).content(); + let { dom, text: text2, slice: slice2 } = serializeForClipboard(view, draggedSlice); + if (!event.dataTransfer.files.length || !chrome || chrome_version > 120) + event.dataTransfer.clearData(); + event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML); + event.dataTransfer.effectAllowed = "copyMove"; + if (!brokenClipboardAPI) + event.dataTransfer.setData("text/plain", text2); + view.dragging = new Dragging(slice2, dragMoves(view, event), node); +}; +handlers.dragend = (view) => { + let dragging = view.dragging; + window.setTimeout(() => { + if (view.dragging == dragging) + view.dragging = null; + }, 50); +}; +editHandlers.dragover = editHandlers.dragenter = (_2, e) => e.preventDefault(); +editHandlers.drop = (view, event) => { + try { + handleDrop(view, event, view.dragging); + } finally { + view.dragging = null; + } +}; +function handleDrop(view, event, dragging) { + if (!event.dataTransfer) + return; + let eventPos = view.posAtCoords(eventCoords(event)); + if (!eventPos) + return; + let $mouse = view.state.doc.resolve(eventPos.pos); + let slice2 = dragging && dragging.slice; + if (slice2) { + view.someProp("transformPasted", (f) => { + slice2 = f(slice2, view, false); + }); + } else { + slice2 = parseFromClipboard(view, getText(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse); + } + let move = !!(dragging && dragMoves(view, event)); + if (view.someProp("handleDrop", (f) => f(view, event, slice2 || Slice.empty, move))) { + event.preventDefault(); + return; + } + if (!slice2) + return; + event.preventDefault(); + let insertPos = slice2 ? dropPoint(view.state.doc, $mouse.pos, slice2) : $mouse.pos; + if (insertPos == null) + insertPos = $mouse.pos; + let tr2 = view.state.tr; + if (move) { + let { node } = dragging; + if (node) + node.replace(tr2); + else + tr2.deleteSelection(); + } + let pos = tr2.mapping.map(insertPos); + let isNode2 = slice2.openStart == 0 && slice2.openEnd == 0 && slice2.content.childCount == 1; + let beforeInsert = tr2.doc; + if (isNode2) + tr2.replaceRangeWith(pos, pos, slice2.content.firstChild); + else + tr2.replaceRange(pos, pos, slice2); + if (tr2.doc.eq(beforeInsert)) + return; + let $pos = tr2.doc.resolve(pos); + if (isNode2 && NodeSelection.isSelectable(slice2.content.firstChild) && $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice2.content.firstChild)) { + tr2.setSelection(new NodeSelection($pos)); + } else { + let end = tr2.mapping.map(insertPos); + tr2.mapping.maps[tr2.mapping.maps.length - 1].forEach((_from, _to, _newFrom, newTo) => end = newTo); + tr2.setSelection(selectionBetween(view, $pos, tr2.doc.resolve(end))); + } + view.focus(); + view.dispatch(tr2.setMeta("uiEvent", "drop")); +} +handlers.focus = (view) => { + view.input.lastFocus = Date.now(); + if (!view.focused) { + view.domObserver.stop(); + view.dom.classList.add("ProseMirror-focused"); + view.domObserver.start(); + view.focused = true; + setTimeout(() => { + if (view.docView && view.hasFocus() && !view.domObserver.currentSelection.eq(view.domSelectionRange())) + selectionToDOM(view); + }, 20); + } +}; +handlers.blur = (view, _event) => { + let event = _event; + if (view.focused) { + view.domObserver.stop(); + view.dom.classList.remove("ProseMirror-focused"); + view.domObserver.start(); + if (event.relatedTarget && view.dom.contains(event.relatedTarget)) + view.domObserver.currentSelection.clear(); + view.focused = false; + } +}; +handlers.beforeinput = (view, _event) => { + let event = _event; + if (chrome && android && event.inputType == "deleteContentBackward") { + view.domObserver.flushSoon(); + let { domChangeCount } = view.input; + setTimeout(() => { + if (view.input.domChangeCount != domChangeCount) + return; + view.dom.blur(); + view.focus(); + if (view.someProp("handleKeyDown", (f) => f(view, keyEvent(8, "Backspace")))) + return; + let { $cursor } = view.state.selection; + if ($cursor && $cursor.pos > 0) + view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView()); + }, 50); + } +}; +for (let prop in editHandlers) + handlers[prop] = editHandlers[prop]; +function compareObjs(a, b2) { + if (a == b2) + return true; + for (let p in a) + if (a[p] !== b2[p]) + return false; + for (let p in b2) + if (!(p in a)) + return false; + return true; +} +var WidgetType = class _WidgetType { + constructor(toDOM, spec) { + this.toDOM = toDOM; + this.spec = spec || noSpec; + this.side = this.spec.side || 0; + } + map(mapping, span, offset, oldOffset) { + let { pos, deleted } = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1); + return deleted ? null : new Decoration(pos - offset, pos - offset, this); + } + valid() { + return true; + } + eq(other) { + return this == other || other instanceof _WidgetType && (this.spec.key && this.spec.key == other.spec.key || this.toDOM == other.toDOM && compareObjs(this.spec, other.spec)); + } + destroy(node) { + if (this.spec.destroy) + this.spec.destroy(node); + } +}; +var InlineType = class _InlineType { + constructor(attrs, spec) { + this.attrs = attrs; + this.spec = spec || noSpec; + } + map(mapping, span, offset, oldOffset) { + let from3 = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset; + let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset; + return from3 >= to ? null : new Decoration(from3, to, this); + } + valid(_2, span) { + return span.from < span.to; + } + eq(other) { + return this == other || other instanceof _InlineType && compareObjs(this.attrs, other.attrs) && compareObjs(this.spec, other.spec); + } + static is(span) { + return span.type instanceof _InlineType; + } + destroy() { + } +}; +var NodeType2 = class _NodeType { + constructor(attrs, spec) { + this.attrs = attrs; + this.spec = spec || noSpec; + } + map(mapping, span, offset, oldOffset) { + let from3 = mapping.mapResult(span.from + oldOffset, 1); + if (from3.deleted) + return null; + let to = mapping.mapResult(span.to + oldOffset, -1); + if (to.deleted || to.pos <= from3.pos) + return null; + return new Decoration(from3.pos - offset, to.pos - offset, this); + } + valid(node, span) { + let { index, offset } = node.content.findIndex(span.from), child; + return offset == span.from && !(child = node.child(index)).isText && offset + child.nodeSize == span.to; + } + eq(other) { + return this == other || other instanceof _NodeType && compareObjs(this.attrs, other.attrs) && compareObjs(this.spec, other.spec); + } + destroy() { + } +}; +var Decoration = class _Decoration { + /** + @internal + */ + constructor(from3, to, type) { + this.from = from3; + this.to = to; + this.type = type; + } + /** + @internal + */ + copy(from3, to) { + return new _Decoration(from3, to, this.type); + } + /** + @internal + */ + eq(other, offset = 0) { + return this.type.eq(other.type) && this.from + offset == other.from && this.to + offset == other.to; + } + /** + @internal + */ + map(mapping, offset, oldOffset) { + return this.type.map(mapping, this, offset, oldOffset); + } + /** + Creates a widget decoration, which is a DOM node that's shown in + the document at the given position. It is recommended that you + delay rendering the widget by passing a function that will be + called when the widget is actually drawn in a view, but you can + also directly pass a DOM node. `getPos` can be used to find the + widget's current document position. + */ + static widget(pos, toDOM, spec) { + return new _Decoration(pos, pos, new WidgetType(toDOM, spec)); + } + /** + Creates an inline decoration, which adds the given attributes to + each inline node between `from` and `to`. + */ + static inline(from3, to, attrs, spec) { + return new _Decoration(from3, to, new InlineType(attrs, spec)); + } + /** + Creates a node decoration. `from` and `to` should point precisely + before and after a node in the document. That node, and only that + node, will receive the given attributes. + */ + static node(from3, to, attrs, spec) { + return new _Decoration(from3, to, new NodeType2(attrs, spec)); + } + /** + The spec provided when creating this decoration. Can be useful + if you've stored extra information in that object. + */ + get spec() { + return this.type.spec; + } + /** + @internal + */ + get inline() { + return this.type instanceof InlineType; + } + /** + @internal + */ + get widget() { + return this.type instanceof WidgetType; + } +}; +var none = []; +var noSpec = {}; +var DecorationSet = class _DecorationSet { + /** + @internal + */ + constructor(local, children) { + this.local = local.length ? local : none; + this.children = children.length ? children : none; + } + /** + Create a set of decorations, using the structure of the given + document. This will consume (modify) the `decorations` array, so + you must make a copy if you want need to preserve that. + */ + static create(doc4, decorations) { + return decorations.length ? buildTree(decorations, doc4, 0, noSpec) : empty; + } + /** + Find all decorations in this set which touch the given range + (including decorations that start or end directly at the + boundaries) and match the given predicate on their spec. When + `start` and `end` are omitted, all decorations in the set are + considered. When `predicate` isn't given, all decorations are + assumed to match. + */ + find(start, end, predicate) { + let result = []; + this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate); + return result; + } + findInner(start, end, result, offset, predicate) { + for (let i = 0; i < this.local.length; i++) { + let span = this.local[i]; + if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) + result.push(span.copy(span.from + offset, span.to + offset)); + } + for (let i = 0; i < this.children.length; i += 3) { + if (this.children[i] < end && this.children[i + 1] > start) { + let childOff = this.children[i] + 1; + this.children[i + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate); + } + } + } + /** + Map the set of decorations in response to a change in the + document. + */ + map(mapping, doc4, options) { + if (this == empty || mapping.maps.length == 0) + return this; + return this.mapInner(mapping, doc4, 0, 0, options || noSpec); + } + /** + @internal + */ + mapInner(mapping, node, offset, oldOffset, options) { + let newLocal; + for (let i = 0; i < this.local.length; i++) { + let mapped = this.local[i].map(mapping, offset, oldOffset); + if (mapped && mapped.type.valid(node, mapped)) + (newLocal || (newLocal = [])).push(mapped); + else if (options.onRemove) + options.onRemove(this.local[i].spec); + } + if (this.children.length) + return mapChildren(this.children, newLocal || [], mapping, node, offset, oldOffset, options); + else + return newLocal ? new _DecorationSet(newLocal.sort(byPos), none) : empty; + } + /** + Add the given array of decorations to the ones in the set, + producing a new set. Consumes the `decorations` array. Needs + access to the current document to create the appropriate tree + structure. + */ + add(doc4, decorations) { + if (!decorations.length) + return this; + if (this == empty) + return _DecorationSet.create(doc4, decorations); + return this.addInner(doc4, decorations, 0); + } + addInner(doc4, decorations, offset) { + let children, childIndex = 0; + doc4.forEach((childNode, childOffset) => { + let baseOffset = childOffset + offset, found3; + if (!(found3 = takeSpansForNode(decorations, childNode, baseOffset))) + return; + if (!children) + children = this.children.slice(); + while (childIndex < children.length && children[childIndex] < childOffset) + childIndex += 3; + if (children[childIndex] == childOffset) + children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found3, baseOffset + 1); + else + children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found3, childNode, baseOffset + 1, noSpec)); + childIndex += 3; + }); + let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset); + for (let i = 0; i < local.length; i++) + if (!local[i].type.valid(doc4, local[i])) + local.splice(i--, 1); + return new _DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, children || this.children); + } + /** + Create a new set that contains the decorations in this set, minus + the ones in the given array. + */ + remove(decorations) { + if (decorations.length == 0 || this == empty) + return this; + return this.removeInner(decorations, 0); + } + removeInner(decorations, offset) { + let children = this.children, local = this.local; + for (let i = 0; i < children.length; i += 3) { + let found3; + let from3 = children[i] + offset, to = children[i + 1] + offset; + for (let j2 = 0, span; j2 < decorations.length; j2++) + if (span = decorations[j2]) { + if (span.from > from3 && span.to < to) { + decorations[j2] = null; + (found3 || (found3 = [])).push(span); + } + } + if (!found3) + continue; + if (children == this.children) + children = this.children.slice(); + let removed = children[i + 2].removeInner(found3, from3 + 1); + if (removed != empty) { + children[i + 2] = removed; + } else { + children.splice(i, 3); + i -= 3; + } + } + if (local.length) { + for (let i = 0, span; i < decorations.length; i++) + if (span = decorations[i]) { + for (let j2 = 0; j2 < local.length; j2++) + if (local[j2].eq(span, offset)) { + if (local == this.local) + local = this.local.slice(); + local.splice(j2--, 1); + } + } + } + if (children == this.children && local == this.local) + return this; + return local.length || children.length ? new _DecorationSet(local, children) : empty; + } + forChild(offset, node) { + if (this == empty) + return this; + if (node.isLeaf) + return _DecorationSet.empty; + let child, local; + for (let i = 0; i < this.children.length; i += 3) + if (this.children[i] >= offset) { + if (this.children[i] == offset) + child = this.children[i + 2]; + break; + } + let start = offset + 1, end = start + node.content.size; + for (let i = 0; i < this.local.length; i++) { + let dec = this.local[i]; + if (dec.from < end && dec.to > start && dec.type instanceof InlineType) { + let from3 = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start; + if (from3 < to) + (local || (local = [])).push(dec.copy(from3, to)); + } + } + if (local) { + let localSet = new _DecorationSet(local.sort(byPos), none); + return child ? new DecorationGroup([localSet, child]) : localSet; + } + return child || empty; + } + /** + @internal + */ + eq(other) { + if (this == other) + return true; + if (!(other instanceof _DecorationSet) || this.local.length != other.local.length || this.children.length != other.children.length) + return false; + for (let i = 0; i < this.local.length; i++) + if (!this.local[i].eq(other.local[i])) + return false; + for (let i = 0; i < this.children.length; i += 3) + if (this.children[i] != other.children[i] || this.children[i + 1] != other.children[i + 1] || !this.children[i + 2].eq(other.children[i + 2])) + return false; + return true; + } + /** + @internal + */ + locals(node) { + return removeOverlap(this.localsInner(node)); + } + /** + @internal + */ + localsInner(node) { + if (this == empty) + return none; + if (node.inlineContent || !this.local.some(InlineType.is)) + return this.local; + let result = []; + for (let i = 0; i < this.local.length; i++) { + if (!(this.local[i].type instanceof InlineType)) + result.push(this.local[i]); + } + return result; + } + forEachSet(f) { + f(this); + } +}; +DecorationSet.empty = new DecorationSet([], []); +DecorationSet.removeOverlap = removeOverlap; +var empty = DecorationSet.empty; +var DecorationGroup = class _DecorationGroup { + constructor(members) { + this.members = members; + } + map(mapping, doc4) { + const mappedDecos = this.members.map((member) => member.map(mapping, doc4, noSpec)); + return _DecorationGroup.from(mappedDecos); + } + forChild(offset, child) { + if (child.isLeaf) + return DecorationSet.empty; + let found3 = []; + for (let i = 0; i < this.members.length; i++) { + let result = this.members[i].forChild(offset, child); + if (result == empty) + continue; + if (result instanceof _DecorationGroup) + found3 = found3.concat(result.members); + else + found3.push(result); + } + return _DecorationGroup.from(found3); + } + eq(other) { + if (!(other instanceof _DecorationGroup) || other.members.length != this.members.length) + return false; + for (let i = 0; i < this.members.length; i++) + if (!this.members[i].eq(other.members[i])) + return false; + return true; + } + locals(node) { + let result, sorted = true; + for (let i = 0; i < this.members.length; i++) { + let locals = this.members[i].localsInner(node); + if (!locals.length) + continue; + if (!result) { + result = locals; + } else { + if (sorted) { + result = result.slice(); + sorted = false; + } + for (let j2 = 0; j2 < locals.length; j2++) + result.push(locals[j2]); + } + } + return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none; + } + // Create a group for the given array of decoration sets, or return + // a single set when possible. + static from(members) { + switch (members.length) { + case 0: + return empty; + case 1: + return members[0]; + default: + return new _DecorationGroup(members.every((m2) => m2 instanceof DecorationSet) ? members : members.reduce((r, m2) => r.concat(m2 instanceof DecorationSet ? m2 : m2.members), [])); + } + } + forEachSet(f) { + for (let i = 0; i < this.members.length; i++) + this.members[i].forEachSet(f); + } +}; +function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) { + let children = oldChildren.slice(); + for (let i = 0, baseOffset = oldOffset; i < mapping.maps.length; i++) { + let moved = 0; + mapping.maps[i].forEach((oldStart, oldEnd, newStart, newEnd) => { + let dSize = newEnd - newStart - (oldEnd - oldStart); + for (let i2 = 0; i2 < children.length; i2 += 3) { + let end = children[i2 + 1]; + if (end < 0 || oldStart > end + baseOffset - moved) + continue; + let start = children[i2] + baseOffset - moved; + if (oldEnd >= start) { + children[i2 + 1] = oldStart <= start ? -2 : -1; + } else if (oldStart >= baseOffset && dSize) { + children[i2] += dSize; + children[i2 + 1] += dSize; + } + } + moved += dSize; + }); + baseOffset = mapping.maps[i].map(baseOffset, -1); + } + let mustRebuild = false; + for (let i = 0; i < children.length; i += 3) + if (children[i + 1] < 0) { + if (children[i + 1] == -2) { + mustRebuild = true; + children[i + 1] = -1; + continue; + } + let from3 = mapping.map(oldChildren[i] + oldOffset), fromLocal = from3 - offset; + if (fromLocal < 0 || fromLocal >= node.content.size) { + mustRebuild = true; + continue; + } + let to = mapping.map(oldChildren[i + 1] + oldOffset, -1), toLocal = to - offset; + let { index, offset: childOffset } = node.content.findIndex(fromLocal); + let childNode = node.maybeChild(index); + if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) { + let mapped = children[i + 2].mapInner(mapping, childNode, from3 + 1, oldChildren[i] + oldOffset + 1, options); + if (mapped != empty) { + children[i] = fromLocal; + children[i + 1] = toLocal; + children[i + 2] = mapped; + } else { + children[i + 1] = -2; + mustRebuild = true; + } + } else { + mustRebuild = true; + } + } + if (mustRebuild) { + let decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal, mapping, offset, oldOffset, options); + let built = buildTree(decorations, node, 0, options); + newLocal = built.local; + for (let i = 0; i < children.length; i += 3) + if (children[i + 1] < 0) { + children.splice(i, 3); + i -= 3; + } + for (let i = 0, j2 = 0; i < built.children.length; i += 3) { + let from3 = built.children[i]; + while (j2 < children.length && children[j2] < from3) + j2 += 3; + children.splice(j2, 0, built.children[i], built.children[i + 1], built.children[i + 2]); + } + } + return new DecorationSet(newLocal.sort(byPos), children); +} +function moveSpans(spans, offset) { + if (!offset || !spans.length) + return spans; + let result = []; + for (let i = 0; i < spans.length; i++) { + let span = spans[i]; + result.push(new Decoration(span.from + offset, span.to + offset, span.type)); + } + return result; +} +function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) { + function gather(set, oldOffset2) { + for (let i = 0; i < set.local.length; i++) { + let mapped = set.local[i].map(mapping, offset, oldOffset2); + if (mapped) + decorations.push(mapped); + else if (options.onRemove) + options.onRemove(set.local[i].spec); + } + for (let i = 0; i < set.children.length; i += 3) + gather(set.children[i + 2], set.children[i] + oldOffset2 + 1); + } + for (let i = 0; i < children.length; i += 3) + if (children[i + 1] == -1) + gather(children[i + 2], oldChildren[i] + oldOffset + 1); + return decorations; +} +function takeSpansForNode(spans, node, offset) { + if (node.isLeaf) + return null; + let end = offset + node.nodeSize, found3 = null; + for (let i = 0, span; i < spans.length; i++) { + if ((span = spans[i]) && span.from > offset && span.to < end) { + (found3 || (found3 = [])).push(span); + spans[i] = null; + } + } + return found3; +} +function withoutNulls(array) { + let result = []; + for (let i = 0; i < array.length; i++) + if (array[i] != null) + result.push(array[i]); + return result; +} +function buildTree(spans, node, offset, options) { + let children = [], hasNulls = false; + node.forEach((childNode, localStart) => { + let found3 = takeSpansForNode(spans, childNode, localStart + offset); + if (found3) { + hasNulls = true; + let subtree = buildTree(found3, childNode, offset + localStart + 1, options); + if (subtree != empty) + children.push(localStart, localStart + childNode.nodeSize, subtree); + } + }); + let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos); + for (let i = 0; i < locals.length; i++) + if (!locals[i].type.valid(node, locals[i])) { + if (options.onRemove) + options.onRemove(locals[i].spec); + locals.splice(i--, 1); + } + return locals.length || children.length ? new DecorationSet(locals, children) : empty; +} +function byPos(a, b2) { + return a.from - b2.from || a.to - b2.to; +} +function removeOverlap(spans) { + let working = spans; + for (let i = 0; i < working.length - 1; i++) { + let span = working[i]; + if (span.from != span.to) + for (let j2 = i + 1; j2 < working.length; j2++) { + let next2 = working[j2]; + if (next2.from == span.from) { + if (next2.to != span.to) { + if (working == spans) + working = spans.slice(); + working[j2] = next2.copy(next2.from, span.to); + insertAhead(working, j2 + 1, next2.copy(span.to, next2.to)); + } + continue; + } else { + if (next2.from < span.to) { + if (working == spans) + working = spans.slice(); + working[i] = span.copy(span.from, next2.from); + insertAhead(working, j2, span.copy(next2.from, span.to)); + } + break; + } + } + } + return working; +} +function insertAhead(array, i, deco) { + while (i < array.length && byPos(deco, array[i]) > 0) + i++; + array.splice(i, 0, deco); +} +function viewDecorations(view) { + let found3 = []; + view.someProp("decorations", (f) => { + let result = f(view.state); + if (result && result != empty) + found3.push(result); + }); + if (view.cursorWrapper) + found3.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco])); + return DecorationGroup.from(found3); +} +var observeOptions = { + childList: true, + characterData: true, + characterDataOldValue: true, + attributes: true, + attributeOldValue: true, + subtree: true +}; +var useCharData = ie && ie_version <= 11; +var SelectionState = class { + constructor() { + this.anchorNode = null; + this.anchorOffset = 0; + this.focusNode = null; + this.focusOffset = 0; + } + set(sel) { + this.anchorNode = sel.anchorNode; + this.anchorOffset = sel.anchorOffset; + this.focusNode = sel.focusNode; + this.focusOffset = sel.focusOffset; + } + clear() { + this.anchorNode = this.focusNode = null; + } + eq(sel) { + return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset; + } +}; +var DOMObserver = class { + constructor(view, handleDOMChange) { + this.view = view; + this.handleDOMChange = handleDOMChange; + this.queue = []; + this.flushingSoon = -1; + this.observer = null; + this.currentSelection = new SelectionState(); + this.onCharData = null; + this.suppressingSelectionUpdates = false; + this.lastChangedTextNode = null; + this.observer = window.MutationObserver && new window.MutationObserver((mutations) => { + for (let i = 0; i < mutations.length; i++) + this.queue.push(mutations[i]); + if (ie && ie_version <= 11 && mutations.some((m2) => m2.type == "childList" && m2.removedNodes.length || m2.type == "characterData" && m2.oldValue.length > m2.target.nodeValue.length)) { + this.flushSoon(); + } else if (safari && view.composing && mutations.some((m2) => m2.type == "childList" && m2.target.nodeName == "TR")) { + view.input.badSafariComposition = true; + this.flushSoon(); + } else { + this.flush(); + } + }); + if (useCharData) { + this.onCharData = (e) => { + this.queue.push({ target: e.target, type: "characterData", oldValue: e.prevValue }); + this.flushSoon(); + }; + } + this.onSelectionChange = this.onSelectionChange.bind(this); + } + flushSoon() { + if (this.flushingSoon < 0) + this.flushingSoon = window.setTimeout(() => { + this.flushingSoon = -1; + this.flush(); + }, 20); + } + forceFlush() { + if (this.flushingSoon > -1) { + window.clearTimeout(this.flushingSoon); + this.flushingSoon = -1; + this.flush(); + } + } + start() { + if (this.observer) { + this.observer.takeRecords(); + this.observer.observe(this.view.dom, observeOptions); + } + if (this.onCharData) + this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData); + this.connectSelection(); + } + stop() { + if (this.observer) { + let take = this.observer.takeRecords(); + if (take.length) { + for (let i = 0; i < take.length; i++) + this.queue.push(take[i]); + window.setTimeout(() => this.flush(), 20); + } + this.observer.disconnect(); + } + if (this.onCharData) + this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData); + this.disconnectSelection(); + } + connectSelection() { + this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); + } + disconnectSelection() { + this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); + } + suppressSelectionUpdates() { + this.suppressingSelectionUpdates = true; + setTimeout(() => this.suppressingSelectionUpdates = false, 50); + } + onSelectionChange() { + if (!hasFocusAndSelection(this.view)) + return; + if (this.suppressingSelectionUpdates) + return selectionToDOM(this.view); + if (ie && ie_version <= 11 && !this.view.state.selection.empty) { + let sel = this.view.domSelectionRange(); + if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) + return this.flushSoon(); + } + this.flush(); + } + setCurSelection() { + this.currentSelection.set(this.view.domSelectionRange()); + } + ignoreSelectionChange(sel) { + if (!sel.focusNode) + return true; + let ancestors = /* @__PURE__ */ new Set(), container; + for (let scan = sel.focusNode; scan; scan = parentNode(scan)) + ancestors.add(scan); + for (let scan = sel.anchorNode; scan; scan = parentNode(scan)) + if (ancestors.has(scan)) { + container = scan; + break; + } + let desc = container && this.view.docView.nearestDesc(container); + if (desc && desc.ignoreMutation({ + type: "selection", + target: container.nodeType == 3 ? container.parentNode : container + })) { + this.setCurSelection(); + return true; + } + } + pendingRecords() { + if (this.observer) + for (let mut of this.observer.takeRecords()) + this.queue.push(mut); + return this.queue; + } + flush() { + let { view } = this; + if (!view.docView || this.flushingSoon > -1) + return; + let mutations = this.pendingRecords(); + if (mutations.length) + this.queue = []; + let sel = view.domSelectionRange(); + let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel); + let from3 = -1, to = -1, typeOver = false, added = []; + if (view.editable) { + for (let i = 0; i < mutations.length; i++) { + let result = this.registerMutation(mutations[i], added); + if (result) { + from3 = from3 < 0 ? result.from : Math.min(result.from, from3); + to = to < 0 ? result.to : Math.max(result.to, to); + if (result.typeOver) + typeOver = true; + } + } + } + if (added.some((n) => n.nodeName == "BR") && (view.input.lastKeyCode == 8 || view.input.lastKeyCode == 46)) { + for (let node of added) + if (node.nodeName == "BR" && node.parentNode) { + let after = node.nextSibling; + while (after && after.nodeType == 1) { + if (after.contentEditable == "false") { + node.parentNode.removeChild(node); + break; + } + after = after.firstChild; + } + } + } else if (gecko && added.length) { + let brs = added.filter((n) => n.nodeName == "BR"); + if (brs.length == 2) { + let [a, b2] = brs; + if (a.parentNode && a.parentNode.parentNode == b2.parentNode) + b2.remove(); + else + a.remove(); + } else { + let { focusNode } = this.currentSelection; + for (let br of brs) { + let parent = br.parentNode; + if (parent && parent.nodeName == "LI" && (!focusNode || blockParent(view, focusNode) != parent)) + br.remove(); + } + } + } + let readSel = null; + if (from3 < 0 && newSel && view.input.lastFocus > Date.now() - 200 && Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 && selectionCollapsed(sel) && (readSel = selectionFromDOM(view)) && readSel.eq(Selection.near(view.state.doc.resolve(0), 1))) { + view.input.lastFocus = 0; + selectionToDOM(view); + this.currentSelection.set(sel); + view.scrollToSelection(); + } else if (from3 > -1 || newSel) { + if (from3 > -1) { + view.docView.markDirty(from3, to); + checkCSS(view); + } + if (view.input.badSafariComposition) { + view.input.badSafariComposition = false; + fixUpBadSafariComposition(view, added); + } + this.handleDOMChange(from3, to, typeOver, added); + if (view.docView && view.docView.dirty) + view.updateState(view.state); + else if (!this.currentSelection.eq(sel)) + selectionToDOM(view); + this.currentSelection.set(sel); + } + } + registerMutation(mut, added) { + if (added.indexOf(mut.target) > -1) + return null; + let desc = this.view.docView.nearestDesc(mut.target); + if (mut.type == "attributes" && (desc == this.view.docView || mut.attributeName == "contenteditable" || // Firefox sometimes fires spurious events for null/empty styles + mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style"))) + return null; + if (!desc || desc.ignoreMutation(mut)) + return null; + if (mut.type == "childList") { + for (let i = 0; i < mut.addedNodes.length; i++) { + let node = mut.addedNodes[i]; + added.push(node); + if (node.nodeType == 3) + this.lastChangedTextNode = node; + } + if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target)) + return { from: desc.posBefore, to: desc.posAfter }; + let prev = mut.previousSibling, next2 = mut.nextSibling; + if (ie && ie_version <= 11 && mut.addedNodes.length) { + for (let i = 0; i < mut.addedNodes.length; i++) { + let { previousSibling, nextSibling } = mut.addedNodes[i]; + if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) + prev = previousSibling; + if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) + next2 = nextSibling; + } + } + let fromOffset = prev && prev.parentNode == mut.target ? domIndex(prev) + 1 : 0; + let from3 = desc.localPosFromDOM(mut.target, fromOffset, -1); + let toOffset = next2 && next2.parentNode == mut.target ? domIndex(next2) : mut.target.childNodes.length; + let to = desc.localPosFromDOM(mut.target, toOffset, 1); + return { from: from3, to }; + } else if (mut.type == "attributes") { + return { from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border }; + } else { + this.lastChangedTextNode = mut.target; + return { + from: desc.posAtStart, + to: desc.posAtEnd, + // An event was generated for a text change that didn't change + // any text. Mark the dom change to fall back to assuming the + // selection was typed over with an identical value if it can't + // find another change. + typeOver: mut.target.nodeValue == mut.oldValue + }; + } + } +}; +var cssChecked = /* @__PURE__ */ new WeakMap(); +var cssCheckWarned = false; +function checkCSS(view) { + if (cssChecked.has(view)) + return; + cssChecked.set(view, null); + if (["normal", "nowrap", "pre-line"].indexOf(getComputedStyle(view.dom).whiteSpace) !== -1) { + view.requiresGeckoHackNode = gecko; + if (cssCheckWarned) + return; + console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."); + cssCheckWarned = true; + } +} +function rangeToSelectionRange(view, range) { + let anchorNode = range.startContainer, anchorOffset = range.startOffset; + let focusNode = range.endContainer, focusOffset = range.endOffset; + let currentAnchor = view.domAtPos(view.state.selection.anchor); + if (isEquivalentPosition(currentAnchor.node, currentAnchor.offset, focusNode, focusOffset)) + [anchorNode, anchorOffset, focusNode, focusOffset] = [focusNode, focusOffset, anchorNode, anchorOffset]; + return { anchorNode, anchorOffset, focusNode, focusOffset }; +} +function safariShadowSelectionRange(view, selection) { + if (selection.getComposedRanges) { + let range = selection.getComposedRanges(view.root)[0]; + if (range) + return rangeToSelectionRange(view, range); + } + let found3; + function read(event) { + event.preventDefault(); + event.stopImmediatePropagation(); + found3 = event.getTargetRanges()[0]; + } + view.dom.addEventListener("beforeinput", read, true); + document.execCommand("indent"); + view.dom.removeEventListener("beforeinput", read, true); + return found3 ? rangeToSelectionRange(view, found3) : null; +} +function blockParent(view, node) { + for (let p = node.parentNode; p && p != view.dom; p = p.parentNode) { + let desc = view.docView.nearestDesc(p, true); + if (desc && desc.node.isBlock) + return p; + } + return null; +} +function fixUpBadSafariComposition(view, addedNodes) { + var _a; + let { focusNode, focusOffset } = view.domSelectionRange(); + for (let node of addedNodes) { + if (((_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.nodeName) == "TR") { + let nextCell2 = node.nextSibling; + while (nextCell2 && (nextCell2.nodeName != "TD" && nextCell2.nodeName != "TH")) + nextCell2 = nextCell2.nextSibling; + if (nextCell2) { + let parent = nextCell2; + for (; ; ) { + let first2 = parent.firstChild; + if (!first2 || first2.nodeType != 1 || first2.contentEditable == "false" || /^(BR|IMG)$/.test(first2.nodeName)) + break; + parent = first2; + } + parent.insertBefore(node, parent.firstChild); + if (focusNode == node) + view.domSelection().collapse(node, focusOffset); + } else { + node.parentNode.removeChild(node); + } + } + } +} +function parseBetween(view, from_, to_) { + let { node: parent, fromOffset, toOffset, from: from3, to } = view.docView.parseRange(from_, to_); + let domSel = view.domSelectionRange(); + let find3; + let anchor = domSel.anchorNode; + if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) { + find3 = [{ node: anchor, offset: domSel.anchorOffset }]; + if (!selectionCollapsed(domSel)) + find3.push({ node: domSel.focusNode, offset: domSel.focusOffset }); + } + if (chrome && view.input.lastKeyCode === 8) { + for (let off = toOffset; off > fromOffset; off--) { + let node = parent.childNodes[off - 1], desc = node.pmViewDesc; + if (node.nodeName == "BR" && !desc) { + toOffset = off; + break; + } + if (!desc || desc.size) + break; + } + } + let startDoc = view.state.doc; + let parser = view.someProp("domParser") || DOMParser2.fromSchema(view.state.schema); + let $from = startDoc.resolve(from3); + let sel = null, doc4 = parser.parse(parent, { + topNode: $from.parent, + topMatch: $from.parent.contentMatchAt($from.index()), + topOpen: true, + from: fromOffset, + to: toOffset, + preserveWhitespace: $from.parent.type.whitespace == "pre" ? "full" : true, + findPositions: find3, + ruleFromNode, + context: $from + }); + if (find3 && find3[0].pos != null) { + let anchor2 = find3[0].pos, head = find3[1] && find3[1].pos; + if (head == null) + head = anchor2; + sel = { anchor: anchor2 + from3, head: head + from3 }; + } + return { doc: doc4, sel, from: from3, to }; +} +function ruleFromNode(dom) { + let desc = dom.pmViewDesc; + if (desc) { + return desc.parseRule(); + } else if (dom.nodeName == "BR" && dom.parentNode) { + if (safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) { + let skip = document.createElement("div"); + skip.appendChild(document.createElement("li")); + return { skip }; + } else if (dom.parentNode.lastChild == dom || safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) { + return { ignore: true }; + } + } else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) { + return { ignore: true }; + } + return null; +} +var isInline = /^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|img|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i; +function readDOMChange(view, from3, to, typeOver, addedNodes) { + let compositionID = view.input.compositionPendingChanges || (view.composing ? view.input.compositionID : 0); + view.input.compositionPendingChanges = 0; + if (from3 < 0) { + let origin = view.input.lastSelectionTime > Date.now() - 50 ? view.input.lastSelectionOrigin : null; + let newSel = selectionFromDOM(view, origin); + if (newSel && !view.state.selection.eq(newSel)) { + if (chrome && android && view.input.lastKeyCode === 13 && Date.now() - 100 < view.input.lastKeyCodeTime && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) + return; + let tr2 = view.state.tr.setSelection(newSel); + if (origin == "pointer") + tr2.setMeta("pointer", true); + else if (origin == "key") + tr2.scrollIntoView(); + if (compositionID) + tr2.setMeta("composition", compositionID); + view.dispatch(tr2); + } + return; + } + let $before = view.state.doc.resolve(from3); + let shared = $before.sharedDepth(to); + from3 = $before.before(shared + 1); + to = view.state.doc.resolve(to).after(shared + 1); + let sel = view.state.selection; + let parse = parseBetween(view, from3, to); + let doc4 = view.state.doc, compare = doc4.slice(parse.from, parse.to); + let preferredPos, preferredSide; + if (view.input.lastKeyCode === 8 && Date.now() - 100 < view.input.lastKeyCodeTime) { + preferredPos = view.state.selection.to; + preferredSide = "end"; + } else { + preferredPos = view.state.selection.from; + preferredSide = "start"; + } + view.input.lastKeyCode = null; + let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide); + if (change) + view.input.domChangeCount++; + if ((ios && view.input.lastIOSEnter > Date.now() - 225 || android) && addedNodes.some((n) => n.nodeType == 1 && !isInline.test(n.nodeName)) && (!change || change.endA >= change.endB) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) { + view.input.lastIOSEnter = 0; + return; + } + if (!change) { + if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) { + change = { start: sel.from, endA: sel.to, endB: sel.to }; + } else { + if (parse.sel) { + let sel2 = resolveSelection(view, view.state.doc, parse.sel); + if (sel2 && !sel2.eq(view.state.selection)) { + let tr2 = view.state.tr.setSelection(sel2); + if (compositionID) + tr2.setMeta("composition", compositionID); + view.dispatch(tr2); + } + } + return; + } + } + if (view.state.selection.from < view.state.selection.to && change.start == change.endB && view.state.selection instanceof TextSelection) { + if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2 && view.state.selection.from >= parse.from) { + change.start = view.state.selection.from; + } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2 && view.state.selection.to <= parse.to) { + change.endB += view.state.selection.to - change.endA; + change.endA = view.state.selection.to; + } + } + if (ie && ie_version <= 11 && change.endB == change.start + 1 && change.endA == change.start && change.start > parse.from && parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == " \xA0") { + change.start--; + change.endA--; + change.endB--; + } + let $from = parse.doc.resolveNoCache(change.start - parse.from); + let $to = parse.doc.resolveNoCache(change.endB - parse.from); + let $fromA = doc4.resolve(change.start); + let inlineChange = $from.sameParent($to) && $from.parent.inlineContent && $fromA.end() >= change.endA; + if ((ios && view.input.lastIOSEnter > Date.now() - 225 && (!inlineChange || addedNodes.some((n) => n.nodeName == "DIV" || n.nodeName == "P")) || !inlineChange && $from.pos < parse.doc.content.size && (!$from.sameParent($to) || !$from.parent.inlineContent) && $from.pos < $to.pos && !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", ""))) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(13, "Enter")))) { + view.input.lastIOSEnter = 0; + return; + } + if (view.state.selection.anchor > change.start && looksLikeBackspace(doc4, change.start, change.endA, $from, $to) && view.someProp("handleKeyDown", (f) => f(view, keyEvent(8, "Backspace")))) { + if (android && chrome) + view.domObserver.suppressSelectionUpdates(); + return; + } + if (chrome && change.endB == change.start) + view.input.lastChromeDelete = Date.now(); + if (android && !inlineChange && $from.start() != $to.start() && $to.parentOffset == 0 && $from.depth == $to.depth && parse.sel && parse.sel.anchor == parse.sel.head && parse.sel.head == change.endA) { + change.endB -= 2; + $to = parse.doc.resolveNoCache(change.endB - parse.from); + setTimeout(() => { + view.someProp("handleKeyDown", function(f) { + return f(view, keyEvent(13, "Enter")); + }); + }, 20); + } + let chFrom = change.start, chTo = change.endA; + let mkTr = (base2) => { + let tr2 = base2 || view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from)); + if (parse.sel) { + let sel2 = resolveSelection(view, tr2.doc, parse.sel); + if (sel2 && !(chrome && view.composing && sel2.empty && (change.start != change.endB || view.input.lastChromeDelete < Date.now() - 100) && (sel2.head == chFrom || sel2.head == tr2.mapping.map(chTo) - 1) || ie && sel2.empty && sel2.head == chFrom)) + tr2.setSelection(sel2); + } + if (compositionID) + tr2.setMeta("composition", compositionID); + return tr2.scrollIntoView(); + }; + let markChange; + if (inlineChange) { + if ($from.pos == $to.pos) { + if (ie && ie_version <= 11 && $from.parentOffset == 0) { + view.domObserver.suppressSelectionUpdates(); + setTimeout(() => selectionToDOM(view), 20); + } + let tr2 = mkTr(view.state.tr.delete(chFrom, chTo)); + let marks = doc4.resolve(change.start).marksAcross(doc4.resolve(change.endA)); + if (marks) + tr2.ensureMarks(marks); + view.dispatch(tr2); + } else if ( + // Adding or removing a mark + change.endA == change.endB && (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), $fromA.parent.content.cut($fromA.parentOffset, change.endA - $fromA.start()))) + ) { + let tr2 = mkTr(view.state.tr); + if (markChange.type == "add") + tr2.addMark(chFrom, chTo, markChange.mark); + else + tr2.removeMark(chFrom, chTo, markChange.mark); + view.dispatch(tr2); + } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) { + let text2 = $from.parent.textBetween($from.parentOffset, $to.parentOffset); + let deflt = () => mkTr(view.state.tr.insertText(text2, chFrom, chTo)); + if (!view.someProp("handleTextInput", (f) => f(view, chFrom, chTo, text2, deflt))) + view.dispatch(deflt()); + } else { + view.dispatch(mkTr()); + } + } else { + view.dispatch(mkTr()); + } +} +function resolveSelection(view, doc4, parsedSel) { + if (Math.max(parsedSel.anchor, parsedSel.head) > doc4.content.size) + return null; + return selectionBetween(view, doc4.resolve(parsedSel.anchor), doc4.resolve(parsedSel.head)); +} +function isMarkChange(cur, prev) { + let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks; + let added = curMarks, removed = prevMarks, type, mark, update; + for (let i = 0; i < prevMarks.length; i++) + added = prevMarks[i].removeFromSet(added); + for (let i = 0; i < curMarks.length; i++) + removed = curMarks[i].removeFromSet(removed); + if (added.length == 1 && removed.length == 0) { + mark = added[0]; + type = "add"; + update = (node) => node.mark(mark.addToSet(node.marks)); + } else if (added.length == 0 && removed.length == 1) { + mark = removed[0]; + type = "remove"; + update = (node) => node.mark(mark.removeFromSet(node.marks)); + } else { + return null; + } + let updated = []; + for (let i = 0; i < prev.childCount; i++) + updated.push(update(prev.child(i))); + if (Fragment.from(updated).eq(cur)) + return { mark, type }; +} +function looksLikeBackspace(old, start, end, $newStart, $newEnd) { + if ( + // The content must have shrunk + end - start <= $newEnd.pos - $newStart.pos || // newEnd must point directly at or after the end of the block that newStart points into + skipClosingAndOpening($newStart, true, false) < $newEnd.pos + ) + return false; + let $start = old.resolve(start); + if (!$newStart.parent.isTextblock) { + let after = $start.nodeAfter; + return after != null && end == start + after.nodeSize; + } + if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) + return false; + let $next = old.resolve(skipClosingAndOpening($start, true, true)); + if (!$next.parent.isTextblock || $next.pos > end || skipClosingAndOpening($next, true, false) < end) + return false; + return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content); +} +function skipClosingAndOpening($pos, fromEnd, mayOpen) { + let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos; + while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) { + depth--; + end++; + fromEnd = false; + } + if (mayOpen) { + let next2 = $pos.node(depth).maybeChild($pos.indexAfter(depth)); + while (next2 && !next2.isLeaf) { + next2 = next2.firstChild; + end++; + } + } + return end; +} +function findDiff(a, b2, pos, preferredPos, preferredSide) { + let start = a.findDiffStart(b2, pos); + if (start == null) + return null; + let { a: endA, b: endB } = a.findDiffEnd(b2, pos + a.size, pos + b2.size); + if (preferredSide == "end") { + let adjust = Math.max(0, start - Math.min(endA, endB)); + preferredPos -= endA + adjust - start; + } + if (endA < start && a.size < b2.size) { + let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0; + start -= move; + if (start && start < b2.size && isSurrogatePair(b2.textBetween(start - 1, start + 1))) + start += move ? 1 : -1; + endB = start + (endB - endA); + endA = start; + } else if (endB < start) { + let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0; + start -= move; + if (start && start < a.size && isSurrogatePair(a.textBetween(start - 1, start + 1))) + start += move ? 1 : -1; + endA = start + (endA - endB); + endB = start; + } + return { start, endA, endB }; +} +function isSurrogatePair(str) { + if (str.length != 2) + return false; + let a = str.charCodeAt(0), b2 = str.charCodeAt(1); + return a >= 56320 && a <= 57343 && b2 >= 55296 && b2 <= 56319; +} +var EditorView = class { + /** + Create a view. `place` may be a DOM node that the editor should + be appended to, a function that will place it into the document, + or an object whose `mount` property holds the node to use as the + document container. If it is `null`, the editor will not be + added to the document. + */ + constructor(place, props) { + this._root = null; + this.focused = false; + this.trackWrites = null; + this.mounted = false; + this.markCursor = null; + this.cursorWrapper = null; + this.lastSelectedViewDesc = void 0; + this.input = new InputState(); + this.prevDirectPlugins = []; + this.pluginViews = []; + this.requiresGeckoHackNode = false; + this.dragging = null; + this._props = props; + this.state = props.state; + this.directPlugins = props.plugins || []; + this.directPlugins.forEach(checkStateComponent); + this.dispatch = this.dispatch.bind(this); + this.dom = place && place.mount || document.createElement("div"); + if (place) { + if (place.appendChild) + place.appendChild(this.dom); + else if (typeof place == "function") + place(this.dom); + else if (place.mount) + this.mounted = true; + } + this.editable = getEditable(this); + updateCursorWrapper(this); + this.nodeViews = buildNodeViews(this); + this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this); + this.domObserver = new DOMObserver(this, (from3, to, typeOver, added) => readDOMChange(this, from3, to, typeOver, added)); + this.domObserver.start(); + initInput(this); + this.updatePluginViews(); + } + /** + Holds `true` when a + [composition](https://w3c.github.io/uievents/#events-compositionevents) + is active. + */ + get composing() { + return this.input.composing; + } + /** + The view's current [props](https://prosemirror.net/docs/ref/#view.EditorProps). + */ + get props() { + if (this._props.state != this.state) { + let prev = this._props; + this._props = {}; + for (let name in prev) + this._props[name] = prev[name]; + this._props.state = this.state; + } + return this._props; + } + /** + Update the view's props. Will immediately cause an update to + the DOM. + */ + update(props) { + if (props.handleDOMEvents != this._props.handleDOMEvents) + ensureListeners(this); + let prevProps = this._props; + this._props = props; + if (props.plugins) { + props.plugins.forEach(checkStateComponent); + this.directPlugins = props.plugins; + } + this.updateStateInner(props.state, prevProps); + } + /** + Update the view by updating existing props object with the object + given as argument. Equivalent to `view.update(Object.assign({}, + view.props, props))`. + */ + setProps(props) { + let updated = {}; + for (let name in this._props) + updated[name] = this._props[name]; + updated.state = this.state; + for (let name in props) + updated[name] = props[name]; + this.update(updated); + } + /** + Update the editor's `state` prop, without touching any of the + other props. + */ + updateState(state) { + this.updateStateInner(state, this._props); + } + updateStateInner(state, prevProps) { + var _a; + let prev = this.state, redraw = false, updateSel = false; + if (state.storedMarks && this.composing) { + clearComposition(this); + updateSel = true; + } + this.state = state; + let pluginsChanged = prev.plugins != state.plugins || this._props.plugins != prevProps.plugins; + if (pluginsChanged || this._props.plugins != prevProps.plugins || this._props.nodeViews != prevProps.nodeViews) { + let nodeViews = buildNodeViews(this); + if (changedNodeViews(nodeViews, this.nodeViews)) { + this.nodeViews = nodeViews; + redraw = true; + } + } + if (pluginsChanged || prevProps.handleDOMEvents != this._props.handleDOMEvents) { + ensureListeners(this); + } + this.editable = getEditable(this); + updateCursorWrapper(this); + let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this); + let scroll = prev.plugins != state.plugins && !prev.doc.eq(state.doc) ? "reset" : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve"; + let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco); + if (updateDoc || !state.selection.eq(prev.selection)) + updateSel = true; + let oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this); + if (updateSel) { + this.domObserver.stop(); + let forceSelUpdate = updateDoc && (ie || chrome) && !this.composing && !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection); + if (updateDoc) { + let chromeKludge = chrome ? this.trackWrites = this.domSelectionRange().focusNode : null; + if (this.composing) + this.input.compositionNode = findCompositionNode(this); + if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) { + this.docView.updateOuterDeco(outerDeco); + this.docView.destroy(); + this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this); + } + if (chromeKludge && (!this.trackWrites || !this.dom.contains(this.trackWrites))) + forceSelUpdate = true; + } + if (forceSelUpdate || !(this.input.mouseDown && this.domObserver.currentSelection.eq(this.domSelectionRange()) && anchorInRightPlace(this))) { + selectionToDOM(this, forceSelUpdate); + } else { + syncNodeSelection(this, state.selection); + this.domObserver.setCurSelection(); + } + this.domObserver.start(); + } + this.updatePluginViews(prev); + if (((_a = this.dragging) === null || _a === void 0 ? void 0 : _a.node) && !prev.doc.eq(state.doc)) + this.updateDraggedNode(this.dragging, prev); + if (scroll == "reset") { + this.dom.scrollTop = 0; + } else if (scroll == "to selection") { + this.scrollToSelection(); + } else if (oldScrollPos) { + resetScrollPos(oldScrollPos); + } + } + /** + @internal + */ + scrollToSelection() { + let startDOM = this.domSelectionRange().focusNode; + if (!startDOM || !this.dom.contains(startDOM.nodeType == 1 ? startDOM : startDOM.parentNode)) ; + else if (this.someProp("handleScrollToSelection", (f) => f(this))) ; + else if (this.state.selection instanceof NodeSelection) { + let target = this.docView.domAfterPos(this.state.selection.from); + if (target.nodeType == 1) + scrollRectIntoView(this, target.getBoundingClientRect(), startDOM); + } else { + scrollRectIntoView(this, this.coordsAtPos(this.state.selection.head, 1), startDOM); + } + } + destroyPluginViews() { + let view; + while (view = this.pluginViews.pop()) + if (view.destroy) + view.destroy(); + } + updatePluginViews(prevState) { + if (!prevState || prevState.plugins != this.state.plugins || this.directPlugins != this.prevDirectPlugins) { + this.prevDirectPlugins = this.directPlugins; + this.destroyPluginViews(); + for (let i = 0; i < this.directPlugins.length; i++) { + let plugin = this.directPlugins[i]; + if (plugin.spec.view) + this.pluginViews.push(plugin.spec.view(this)); + } + for (let i = 0; i < this.state.plugins.length; i++) { + let plugin = this.state.plugins[i]; + if (plugin.spec.view) + this.pluginViews.push(plugin.spec.view(this)); + } + } else { + for (let i = 0; i < this.pluginViews.length; i++) { + let pluginView = this.pluginViews[i]; + if (pluginView.update) + pluginView.update(this, prevState); + } + } + } + updateDraggedNode(dragging, prev) { + let sel = dragging.node, found3 = -1; + if (sel.from < this.state.doc.content.size && this.state.doc.nodeAt(sel.from) == sel.node) { + found3 = sel.from; + } else { + let movedPos = sel.from + (this.state.doc.content.size - prev.doc.content.size); + let moved = movedPos > 0 && movedPos < this.state.doc.content.size && this.state.doc.nodeAt(movedPos); + if (moved == sel.node) + found3 = movedPos; + } + this.dragging = new Dragging(dragging.slice, dragging.move, found3 < 0 ? void 0 : NodeSelection.create(this.state.doc, found3)); + } + someProp(propName, f) { + let prop = this._props && this._props[propName], value; + if (prop != null && (value = f ? f(prop) : prop)) + return value; + for (let i = 0; i < this.directPlugins.length; i++) { + let prop2 = this.directPlugins[i].props[propName]; + if (prop2 != null && (value = f ? f(prop2) : prop2)) + return value; + } + let plugins = this.state.plugins; + if (plugins) + for (let i = 0; i < plugins.length; i++) { + let prop2 = plugins[i].props[propName]; + if (prop2 != null && (value = f ? f(prop2) : prop2)) + return value; + } + } + /** + Query whether the view has focus. + */ + hasFocus() { + if (ie) { + let node = this.root.activeElement; + if (node == this.dom) + return true; + if (!node || !this.dom.contains(node)) + return false; + while (node && this.dom != node && this.dom.contains(node)) { + if (node.contentEditable == "false") + return false; + node = node.parentElement; + } + return true; + } + return this.root.activeElement == this.dom; + } + /** + Focus the editor. + */ + focus() { + this.domObserver.stop(); + if (this.editable) + focusPreventScroll(this.dom); + selectionToDOM(this); + this.domObserver.start(); + } + /** + Get the document root in which the editor exists. This will + usually be the top-level `document`, but might be a [shadow + DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM) + root if the editor is inside one. + */ + get root() { + let cached = this._root; + if (cached == null) + for (let search = this.dom.parentNode; search; search = search.parentNode) { + if (search.nodeType == 9 || search.nodeType == 11 && search.host) { + if (!search.getSelection) + Object.getPrototypeOf(search).getSelection = () => search.ownerDocument.getSelection(); + return this._root = search; + } + } + return cached || document; + } + /** + When an existing editor view is moved to a new document or + shadow tree, call this to make it recompute its root. + */ + updateRoot() { + this._root = null; + } + /** + Given a pair of viewport coordinates, return the document + position that corresponds to them. May return null if the given + coordinates aren't inside of the editor. When an object is + returned, its `pos` property is the position nearest to the + coordinates, and its `inside` property holds the position of the + inner node that the position falls inside of, or -1 if it is at + the top level, not in any node. + */ + posAtCoords(coords) { + return posAtCoords(this, coords); + } + /** + Returns the viewport rectangle at a given document position. + `left` and `right` will be the same number, as this returns a + flat cursor-ish rectangle. If the position is between two things + that aren't directly adjacent, `side` determines which element + is used. When < 0, the element before the position is used, + otherwise the element after. + */ + coordsAtPos(pos, side = 1) { + return coordsAtPos(this, pos, side); + } + /** + Find the DOM position that corresponds to the given document + position. When `side` is negative, find the position as close as + possible to the content before the position. When positive, + prefer positions close to the content after the position. When + zero, prefer as shallow a position as possible. + + Note that you should **not** mutate the editor's internal DOM, + only inspect it (and even that is usually not necessary). + */ + domAtPos(pos, side = 0) { + return this.docView.domFromPos(pos, side); + } + /** + Find the DOM node that represents the document node after the + given position. May return `null` when the position doesn't point + in front of a node or if the node is inside an opaque node view. + + This is intended to be able to call things like + `getBoundingClientRect` on that DOM node. Do **not** mutate the + editor DOM directly, or add styling this way, since that will be + immediately overriden by the editor as it redraws the node. + */ + nodeDOM(pos) { + let desc = this.docView.descAt(pos); + return desc ? desc.nodeDOM : null; + } + /** + Find the document position that corresponds to a given DOM + position. (Whenever possible, it is preferable to inspect the + document structure directly, rather than poking around in the + DOM, but sometimes—for example when interpreting an event + target—you don't have a choice.) + + The `bias` parameter can be used to influence which side of a DOM + node to use when the position is inside a leaf node. + */ + posAtDOM(node, offset, bias = -1) { + let pos = this.docView.posFromDOM(node, offset, bias); + if (pos == null) + throw new RangeError("DOM position not inside the editor"); + return pos; + } + /** + Find out whether the selection is at the end of a textblock when + moving in a given direction. When, for example, given `"left"`, + it will return true if moving left from the current cursor + position would leave that position's parent textblock. Will apply + to the view's current state by default, but it is possible to + pass a different state. + */ + endOfTextblock(dir, state) { + return endOfTextblock(this, state || this.state, dir); + } + /** + Run the editor's paste logic with the given HTML string. The + `event`, if given, will be passed to the + [`handlePaste`](https://prosemirror.net/docs/ref/#view.EditorProps.handlePaste) hook. + */ + pasteHTML(html, event) { + return doPaste(this, "", html, false, event || new ClipboardEvent("paste")); + } + /** + Run the editor's paste logic with the given plain-text input. + */ + pasteText(text2, event) { + return doPaste(this, text2, null, true, event || new ClipboardEvent("paste")); + } + /** + Serialize the given slice as it would be if it was copied from + this editor. Returns a DOM element that contains a + representation of the slice as its children, a textual + representation, and the transformed slice (which can be + different from the given input due to hooks like + [`transformCopied`](https://prosemirror.net/docs/ref/#view.EditorProps.transformCopied)). + */ + serializeForClipboard(slice2) { + return serializeForClipboard(this, slice2); + } + /** + Removes the editor from the DOM and destroys all [node + views](https://prosemirror.net/docs/ref/#view.NodeView). + */ + destroy() { + if (!this.docView) + return; + destroyInput(this); + this.destroyPluginViews(); + if (this.mounted) { + this.docView.update(this.state.doc, [], viewDecorations(this), this); + this.dom.textContent = ""; + } else if (this.dom.parentNode) { + this.dom.parentNode.removeChild(this.dom); + } + this.docView.destroy(); + this.docView = null; + clearReusedRange(); + } + /** + This is true when the view has been + [destroyed](https://prosemirror.net/docs/ref/#view.EditorView.destroy) (and thus should not be + used anymore). + */ + get isDestroyed() { + return this.docView == null; + } + /** + Used for testing. + */ + dispatchEvent(event) { + return dispatchEvent(this, event); + } + /** + @internal + */ + domSelectionRange() { + let sel = this.domSelection(); + if (!sel) + return { focusNode: null, focusOffset: 0, anchorNode: null, anchorOffset: 0 }; + return safari && this.root.nodeType === 11 && deepActiveElement(this.dom.ownerDocument) == this.dom && safariShadowSelectionRange(this, sel) || sel; + } + /** + @internal + */ + domSelection() { + return this.root.getSelection(); + } +}; +EditorView.prototype.dispatch = function(tr2) { + let dispatchTransaction = this._props.dispatchTransaction; + if (dispatchTransaction) + dispatchTransaction.call(this, tr2); + else + this.updateState(this.state.apply(tr2)); +}; +function computeDocDeco(view) { + let attrs = /* @__PURE__ */ Object.create(null); + attrs.class = "ProseMirror"; + attrs.contenteditable = String(view.editable); + view.someProp("attributes", (value) => { + if (typeof value == "function") + value = value(view.state); + if (value) + for (let attr in value) { + if (attr == "class") + attrs.class += " " + value[attr]; + else if (attr == "style") + attrs.style = (attrs.style ? attrs.style + ";" : "") + value[attr]; + else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") + attrs[attr] = String(value[attr]); + } + }); + if (!attrs.translate) + attrs.translate = "no"; + return [Decoration.node(0, view.state.doc.content.size, attrs)]; +} +function updateCursorWrapper(view) { + if (view.markCursor) { + let dom = document.createElement("img"); + dom.className = "ProseMirror-separator"; + dom.setAttribute("mark-placeholder", "true"); + dom.setAttribute("alt", ""); + view.cursorWrapper = { dom, deco: Decoration.widget(view.state.selection.from, dom, { raw: true, marks: view.markCursor }) }; + } else { + view.cursorWrapper = null; + } +} +function getEditable(view) { + return !view.someProp("editable", (value) => value(view.state) === false); +} +function selectionContextChanged(sel1, sel2) { + let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head)); + return sel1.$anchor.start(depth) != sel2.$anchor.start(depth); +} +function buildNodeViews(view) { + let result = /* @__PURE__ */ Object.create(null); + function add(obj) { + for (let prop in obj) + if (!Object.prototype.hasOwnProperty.call(result, prop)) + result[prop] = obj[prop]; + } + view.someProp("nodeViews", add); + view.someProp("markViews", add); + return result; +} +function changedNodeViews(a, b2) { + let nA = 0, nB = 0; + for (let prop in a) { + if (a[prop] != b2[prop]) + return true; + nA++; + } + for (let _2 in b2) + nB++; + return nA != nB; +} +function checkStateComponent(plugin) { + if (plugin.spec.state || plugin.spec.filterTransaction || plugin.spec.appendTransaction) + throw new RangeError("Plugins passed directly to the view must not have a state component"); +} + +// ../../node_modules/.pnpm/w3c-keyname@2.2.8/node_modules/w3c-keyname/index.js +var base = { + 8: "Backspace", + 9: "Tab", + 10: "Enter", + 12: "NumLock", + 13: "Enter", + 16: "Shift", + 17: "Control", + 18: "Alt", + 20: "CapsLock", + 27: "Escape", + 32: " ", + 33: "PageUp", + 34: "PageDown", + 35: "End", + 36: "Home", + 37: "ArrowLeft", + 38: "ArrowUp", + 39: "ArrowRight", + 40: "ArrowDown", + 44: "PrintScreen", + 45: "Insert", + 46: "Delete", + 59: ";", + 61: "=", + 91: "Meta", + 92: "Meta", + 106: "*", + 107: "+", + 108: ",", + 109: "-", + 110: ".", + 111: "/", + 144: "NumLock", + 145: "ScrollLock", + 160: "Shift", + 161: "Shift", + 162: "Control", + 163: "Control", + 164: "Alt", + 165: "Alt", + 173: "-", + 186: ";", + 187: "=", + 188: ",", + 189: "-", + 190: ".", + 191: "/", + 192: "`", + 219: "[", + 220: "\\", + 221: "]", + 222: "'" +}; +var shift = { + 48: ")", + 49: "!", + 50: "@", + 51: "#", + 52: "$", + 53: "%", + 54: "^", + 55: "&", + 56: "*", + 57: "(", + 59: ":", + 61: "+", + 173: "_", + 186: ":", + 187: "+", + 188: "<", + 189: "_", + 190: ">", + 191: "?", + 192: "~", + 219: "{", + 220: "|", + 221: "}", + 222: '"' +}; +var mac3 = typeof navigator != "undefined" && /Mac/.test(navigator.platform); +var ie2 = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); +for (i = 0; i < 10; i++) base[48 + i] = base[96 + i] = String(i); +var i; +for (i = 1; i <= 24; i++) base[i + 111] = "F" + i; +var i; +for (i = 65; i <= 90; i++) { + base[i] = String.fromCharCode(i + 32); + shift[i] = String.fromCharCode(i); +} +var i; +for (code in base) if (!shift.hasOwnProperty(code)) shift[code] = base[code]; +var code; +function keyName(event) { + var ignoreKey = mac3 && event.metaKey && event.shiftKey && !event.ctrlKey && !event.altKey || ie2 && event.shiftKey && event.key && event.key.length == 1 || event.key == "Unidentified"; + var name = !ignoreKey && event.key || (event.shiftKey ? shift : base)[event.keyCode] || event.key || "Unidentified"; + if (name == "Esc") name = "Escape"; + if (name == "Del") name = "Delete"; + if (name == "Left") name = "ArrowLeft"; + if (name == "Up") name = "ArrowUp"; + if (name == "Right") name = "ArrowRight"; + if (name == "Down") name = "ArrowDown"; + return name; +} + +// ../../node_modules/.pnpm/prosemirror-keymap@1.2.3/node_modules/prosemirror-keymap/dist/index.js +var mac4 = typeof navigator != "undefined" && /Mac|iP(hone|[oa]d)/.test(navigator.platform); +var windows2 = typeof navigator != "undefined" && /Win/.test(navigator.platform); +function normalizeKeyName(name) { + let parts = name.split(/-(?!$)/), result = parts[parts.length - 1]; + if (result == "Space") + result = " "; + let alt, ctrl, shift2, meta; + for (let i = 0; i < parts.length - 1; i++) { + let mod = parts[i]; + if (/^(cmd|meta|m)$/i.test(mod)) + meta = true; + else if (/^a(lt)?$/i.test(mod)) + alt = true; + else if (/^(c|ctrl|control)$/i.test(mod)) + ctrl = true; + else if (/^s(hift)?$/i.test(mod)) + shift2 = true; + else if (/^mod$/i.test(mod)) { + if (mac4) + meta = true; + else + ctrl = true; + } else + throw new Error("Unrecognized modifier name: " + mod); + } + if (alt) + result = "Alt-" + result; + if (ctrl) + result = "Ctrl-" + result; + if (meta) + result = "Meta-" + result; + if (shift2) + result = "Shift-" + result; + return result; +} +function normalize(map4) { + let copy3 = /* @__PURE__ */ Object.create(null); + for (let prop in map4) + copy3[normalizeKeyName(prop)] = map4[prop]; + return copy3; +} +function modifiers(name, event, shift2 = true) { + if (event.altKey) + name = "Alt-" + name; + if (event.ctrlKey) + name = "Ctrl-" + name; + if (event.metaKey) + name = "Meta-" + name; + if (shift2 && event.shiftKey) + name = "Shift-" + name; + return name; +} +function keymap(bindings) { + return new Plugin({ props: { handleKeyDown: keydownHandler(bindings) } }); +} +function keydownHandler(bindings) { + let map4 = normalize(bindings); + return function(view, event) { + let name = keyName(event), baseName, direct = map4[modifiers(name, event)]; + if (direct && direct(view.state, view.dispatch, view)) + return true; + if (name.length == 1 && name != " ") { + if (event.shiftKey) { + let noShift = map4[modifiers(name, event, false)]; + if (noShift && noShift(view.state, view.dispatch, view)) + return true; + } + if ((event.altKey || event.metaKey || event.ctrlKey) && // Ctrl-Alt may be used for AltGr on Windows + !(windows2 && event.ctrlKey && event.altKey) && (baseName = base[event.keyCode]) && baseName != name) { + let fromCode = map4[modifiers(baseName, event)]; + if (fromCode && fromCode(view.state, view.dispatch, view)) + return true; + } + } + return false; + }; +} + +// ../../node_modules/.pnpm/@tiptap+core@3.26.0_@tiptap+pm@3.26.0/node_modules/@tiptap/core/dist/index.js +var __defProp2 = Object.defineProperty; +var __export2 = (target, all2) => { + for (var name in all2) + __defProp2(target, name, { get: all2[name], enumerable: true }); +}; +function createChainableState(config) { + const { state, transaction } = config; + let { selection } = transaction; + let { doc: doc4 } = transaction; + let { storedMarks } = transaction; + return { + ...state, + apply: state.apply.bind(state), + applyTransaction: state.applyTransaction.bind(state), + plugins: state.plugins, + schema: state.schema, + reconfigure: state.reconfigure.bind(state), + toJSON: state.toJSON.bind(state), + get storedMarks() { + return storedMarks; + }, + get selection() { + return selection; + }, + get doc() { + return doc4; + }, + get tr() { + selection = transaction.selection; + doc4 = transaction.doc; + storedMarks = transaction.storedMarks; + return transaction; + } + }; +} +var CommandManager = class { + constructor(props) { + this.editor = props.editor; + this.rawCommands = this.editor.extensionManager.commands; + this.customState = props.state; + } + get hasCustomState() { + return !!this.customState; + } + get state() { + return this.customState || this.editor.state; + } + get commands() { + const { rawCommands, editor, state } = this; + const { view } = editor; + const { tr: tr2 } = state; + const props = this.buildProps(tr2); + return Object.fromEntries( + Object.entries(rawCommands).map(([name, command2]) => { + const method = (...args2) => { + const callback = command2(...args2)(props); + if (!tr2.getMeta("preventDispatch") && !this.hasCustomState) { + view.dispatch(tr2); + } + return callback; + }; + return [name, method]; + }) + ); + } + get chain() { + return () => this.createChain(); + } + get can() { + return () => this.createCan(); + } + createChain(startTr, shouldDispatch = true) { + const { rawCommands, editor, state } = this; + const { view } = editor; + const callbacks = []; + const hasStartTransaction = !!startTr; + const tr2 = startTr || state.tr; + const run32 = () => { + if (!hasStartTransaction && shouldDispatch && !tr2.getMeta("preventDispatch") && !this.hasCustomState) { + view.dispatch(tr2); + } + return callbacks.every((callback) => callback === true); + }; + const chain = { + ...Object.fromEntries( + Object.entries(rawCommands).map(([name, command2]) => { + const chainedCommand = (...args2) => { + const props = this.buildProps(tr2, shouldDispatch); + const callback = command2(...args2)(props); + callbacks.push(callback); + return chain; + }; + return [name, chainedCommand]; + }) + ), + run: run32 + }; + return chain; + } + createCan(startTr) { + const { rawCommands, state } = this; + const dispatch = false; + const tr2 = startTr || state.tr; + const props = this.buildProps(tr2, dispatch); + const formattedCommands = Object.fromEntries( + Object.entries(rawCommands).map(([name, command2]) => { + return [name, (...args2) => command2(...args2)({ ...props, dispatch: void 0 })]; + }) + ); + return { + ...formattedCommands, + chain: () => this.createChain(tr2, dispatch) + }; + } + buildProps(tr2, shouldDispatch = true) { + const { rawCommands, editor, state } = this; + const { view } = editor; + const props = { + tr: tr2, + editor, + view, + state: createChainableState({ + state, + transaction: tr2 + }), + dispatch: shouldDispatch ? () => void 0 : void 0, + chain: () => this.createChain(tr2, shouldDispatch), + can: () => this.createCan(tr2), + get commands() { + return Object.fromEntries( + Object.entries(rawCommands).map(([name, command2]) => { + return [name, (...args2) => command2(...args2)(props)]; + }) + ); + } + }; + return props; + } +}; +var commands_exports = {}; +__export2(commands_exports, { + blur: () => blur, + clearContent: () => clearContent, + clearNodes: () => clearNodes, + command: () => command, + createParagraphNear: () => createParagraphNear2, + cut: () => cut, + deleteCurrentNode: () => deleteCurrentNode, + deleteNode: () => deleteNode, + deleteRange: () => deleteRange2, + deleteSelection: () => deleteSelection2, + enter: () => enter, + exitCode: () => exitCode2, + extendMarkRange: () => extendMarkRange, + first: () => first, + focus: () => focus, + forEach: () => forEach, + insertContent: () => insertContent, + insertContentAt: () => insertContentAt, + joinBackward: () => joinBackward2, + joinDown: () => joinDown2, + joinForward: () => joinForward2, + joinItemBackward: () => joinItemBackward, + joinItemForward: () => joinItemForward, + joinTextblockBackward: () => joinTextblockBackward2, + joinTextblockForward: () => joinTextblockForward2, + joinUp: () => joinUp2, + keyboardShortcut: () => keyboardShortcut, + lift: () => lift3, + liftEmptyBlock: () => liftEmptyBlock2, + liftListItem: () => liftListItem2, + newlineInCode: () => newlineInCode2, + resetAttributes: () => resetAttributes, + scrollIntoView: () => scrollIntoView, + selectAll: () => selectAll2, + selectNodeBackward: () => selectNodeBackward2, + selectNodeForward: () => selectNodeForward2, + selectParentNode: () => selectParentNode2, + selectTextblockEnd: () => selectTextblockEnd2, + selectTextblockStart: () => selectTextblockStart2, + setContent: () => setContent, + setMark: () => setMark, + setMeta: () => setMeta, + setNode: () => setNode, + setNodeSelection: () => setNodeSelection, + setTextDirection: () => setTextDirection, + setTextSelection: () => setTextSelection, + sinkListItem: () => sinkListItem2, + splitBlock: () => splitBlock2, + splitListItem: () => splitListItem, + toggleList: () => toggleList, + toggleMark: () => toggleMark, + toggleNode: () => toggleNode, + toggleWrap: () => toggleWrap, + undoInputRule: () => undoInputRule, + unsetAllMarks: () => unsetAllMarks, + unsetMark: () => unsetMark, + unsetTextDirection: () => unsetTextDirection, + updateAttributes: () => updateAttributes, + wrapIn: () => wrapIn2, + wrapInList: () => wrapInList2 +}); +var blur = () => ({ editor, view }) => { + requestAnimationFrame(() => { + var _a; + if (!editor.isDestroyed) { + ; + view.dom.blur(); + (_a = window == null ? void 0 : window.getSelection()) == null ? void 0 : _a.removeAllRanges(); + } + }); + return true; +}; +var clearContent = (emitUpdate = true) => ({ commands }) => { + return commands.setContent("", { emitUpdate }); +}; +var clearNodes = () => ({ state, tr: tr2, dispatch }) => { + const { selection } = tr2; + const { ranges } = selection; + if (!dispatch) { + return true; + } + ranges.forEach(({ $from, $to }) => { + state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => { + if (node.type.isText) { + return; + } + const { doc: doc4, mapping } = tr2; + const $mappedFrom = doc4.resolve(mapping.map(pos)); + const $mappedTo = doc4.resolve(mapping.map(pos + node.nodeSize)); + const nodeRange = $mappedFrom.blockRange($mappedTo); + if (!nodeRange) { + return; + } + const targetLiftDepth = liftTarget(nodeRange); + if (node.type.isTextblock) { + const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index()); + tr2.setNodeMarkup(nodeRange.start, defaultType); + } + if (targetLiftDepth || targetLiftDepth === 0) { + tr2.lift(nodeRange, targetLiftDepth); + } + }); + }); + return true; +}; +var command = (fn) => (props) => { + return fn(props); +}; +var createParagraphNear2 = () => ({ state, dispatch }) => { + return createParagraphNear(state, dispatch); +}; +var cut = (originRange, targetPos) => ({ editor, tr: tr2 }) => { + const { state } = editor; + const contentSlice = state.doc.slice(originRange.from, originRange.to); + tr2.deleteRange(originRange.from, originRange.to); + const newPos = tr2.mapping.map(targetPos); + tr2.insert(newPos, contentSlice.content); + tr2.setSelection(new TextSelection(tr2.doc.resolve(Math.max(newPos - 1, 0)))); + return true; +}; +var deleteCurrentNode = () => ({ tr: tr2, dispatch }) => { + const { selection } = tr2; + const currentNode = selection.$anchor.node(); + if (currentNode.content.size > 0) { + return false; + } + const $pos = tr2.selection.$anchor; + for (let depth = $pos.depth; depth > 0; depth -= 1) { + const node = $pos.node(depth); + if (node.type === currentNode.type) { + if (dispatch) { + const from3 = $pos.before(depth); + const to = $pos.after(depth); + tr2.delete(from3, to).scrollIntoView(); + } + return true; + } + } + return false; +}; +function getNodeType(nameOrType, schema) { + if (typeof nameOrType === "string") { + if (!schema.nodes[nameOrType]) { + throw Error( + `There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?` + ); + } + return schema.nodes[nameOrType]; + } + return nameOrType; +} +var deleteNode = (typeOrName) => ({ tr: tr2, state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + const $pos = tr2.selection.$anchor; + for (let depth = $pos.depth; depth > 0; depth -= 1) { + const node = $pos.node(depth); + if (node.type === type) { + if (dispatch) { + const from3 = $pos.before(depth); + const to = $pos.after(depth); + tr2.delete(from3, to).scrollIntoView(); + } + return true; + } + } + return false; +}; +var deleteRange2 = (range) => ({ tr: tr2, dispatch }) => { + const { from: from3, to } = range; + if (dispatch) { + tr2.delete(from3, to); + } + return true; +}; +var hasTextContent = (nodeSpec) => { + if (!nodeSpec.content) { + return false; + } + const textRegex = /^text(\*|\+)/; + return textRegex.test(nodeSpec.content); +}; +var expandSelectionForSide = ($pos, schema, side) => { + if (!$pos.parent.isInline) { + return $pos.pos; + } + if (side === "left" && $pos.pos > $pos.start() || side === "right" && $pos.pos < $pos.end()) { + return $pos.pos; + } + const parentContent = schema.nodes[$pos.parent.type.name].spec; + if (!hasTextContent(parentContent)) { + return $pos.pos; + } + return side === "left" ? $pos.start() - 1 : $pos.end() + 1; +}; +var expandSelectionForInlineText = ($from, $to, schema) => { + const from3 = expandSelectionForSide($from, schema, "left"); + const to = expandSelectionForSide($to, schema, "right"); + return { from: from3, to }; +}; +var deleteSelection2 = () => ({ state, dispatch }) => { + const { $from, $to } = state.selection; + if (state.selection.empty) { + return false; + } + const { from: from3, to } = expandSelectionForInlineText($from, $to, state.schema); + if (dispatch) { + state.tr.deleteRange(from3, to).scrollIntoView(); + dispatch(state.tr); + } + return true; +}; +var enter = () => ({ commands }) => { + return commands.keyboardShortcut("Enter"); +}; +var exitCode2 = () => ({ state, dispatch }) => { + return exitCode(state, dispatch); +}; +function isRegExp(value) { + return Object.prototype.toString.call(value) === "[object RegExp]"; +} +function objectIncludes(object1, object2, options = { strict: true }) { + const keys3 = Object.keys(object2); + if (!keys3.length) { + return true; + } + return keys3.every((key) => { + if (options.strict) { + return object2[key] === object1[key]; + } + if (isRegExp(object2[key])) { + return object2[key].test(object1[key]); + } + return object2[key] === object1[key]; + }); +} +function findMarkInSet(marks, type, attributes = {}) { + return marks.find((item) => { + return item.type === type && objectIncludes( + // Only check equality for the attributes that are provided + Object.fromEntries(Object.keys(attributes).map((k) => [k, item.attrs[k]])), + attributes + ); + }); +} +function isMarkInSet(marks, type, attributes = {}) { + return !!findMarkInSet(marks, type, attributes); +} +function getMarkRange($pos, type, attributes) { + if (!$pos || !type) { + return; + } + let start = $pos.parent.childAfter($pos.parentOffset); + if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) { + start = $pos.parent.childBefore($pos.parentOffset); + } + if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) { + return; + } + if (!attributes) { + const firstMark = start.node.marks.find((mark2) => mark2.type === type); + if (firstMark) { + attributes = firstMark.attrs; + } + } + const mark = findMarkInSet([...start.node.marks], type, attributes); + if (!mark) { + return; + } + let startIndex = start.index; + let startPos = $pos.start() + start.offset; + let endIndex = startIndex + 1; + let endPos = startPos + start.node.nodeSize; + while (startIndex > 0 && isMarkInSet([...$pos.parent.child(startIndex - 1).marks], type, attributes)) { + startIndex -= 1; + startPos -= $pos.parent.child(startIndex).nodeSize; + } + while (endIndex < $pos.parent.childCount && isMarkInSet([...$pos.parent.child(endIndex).marks], type, attributes)) { + endPos += $pos.parent.child(endIndex).nodeSize; + endIndex += 1; + } + return { + from: startPos, + to: endPos + }; +} +function getMarkType(nameOrType, schema) { + if (typeof nameOrType === "string") { + if (!schema.marks[nameOrType]) { + throw Error( + `There is no mark type named '${nameOrType}'. Maybe you forgot to add the extension?` + ); + } + return schema.marks[nameOrType]; + } + return nameOrType; +} +var extendMarkRange = (typeOrName, attributes) => ({ tr: tr2, state, dispatch }) => { + const type = getMarkType(typeOrName, state.schema); + const { doc: doc4, selection } = tr2; + const { $from, from: from3, to } = selection; + if (dispatch) { + const range = getMarkRange($from, type, attributes); + if (range && range.from <= from3 && range.to >= to) { + const newSelection = TextSelection.create(doc4, range.from, range.to); + tr2.setSelection(newSelection); + } + } + return true; +}; +var first = (commands) => (props) => { + const items = typeof commands === "function" ? commands(props) : commands; + for (let i = 0; i < items.length; i += 1) { + if (items[i](props)) { + return true; + } + } + return false; +}; +function isTextSelection(value) { + return value instanceof TextSelection; +} +function minMax(value = 0, min2 = 0, max2 = 0) { + return Math.min(Math.max(value, min2), max2); +} +function resolveFocusPosition(doc4, position = null) { + if (!position) { + return null; + } + const selectionAtStart = Selection.atStart(doc4); + const selectionAtEnd = Selection.atEnd(doc4); + if (position === "start" || position === true) { + return selectionAtStart; + } + if (position === "end") { + return selectionAtEnd; + } + const minPos = selectionAtStart.from; + const maxPos = selectionAtEnd.to; + if (position === "all") { + return TextSelection.create( + doc4, + minMax(0, minPos, maxPos), + minMax(doc4.content.size, minPos, maxPos) + ); + } + return TextSelection.create( + doc4, + minMax(position, minPos, maxPos), + minMax(position, minPos, maxPos) + ); +} +function isAndroid() { + return navigator.platform === "Android" || /android/i.test(navigator.userAgent); +} +function isiOS() { + return ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"].includes( + navigator.platform + ) || // iPad on iOS 13 detection + navigator.userAgent.includes("Mac") && "ontouchend" in document; +} +function isSafari() { + return typeof navigator !== "undefined" ? /^((?!chrome|android).)*safari/i.test(navigator.userAgent) : false; +} +var focus = (position = null, options = {}) => ({ editor, view, tr: tr2, dispatch }) => { + options = { + scrollIntoView: true, + ...options + }; + const delayedFocus = () => { + if (isiOS() || isAndroid()) { + ; + view.dom.focus(); + } + if (isSafari() && !isiOS() && !isAndroid()) { + ; + view.dom.focus({ preventScroll: true }); + } + requestAnimationFrame(() => { + if (!editor.isDestroyed) { + view.focus(); + if (options == null ? void 0 : options.scrollIntoView) { + editor.commands.scrollIntoView(); + } + } + }); + }; + try { + if (view.hasFocus() && position === null || position === false) { + return true; + } + } catch { + return false; + } + if (dispatch && position === null && !isTextSelection(editor.state.selection)) { + delayedFocus(); + return true; + } + const selection = resolveFocusPosition(tr2.doc, position) || editor.state.selection; + const isSameSelection = editor.state.selection.eq(selection); + if (dispatch) { + if (!isSameSelection) { + tr2.setSelection(selection); + } + if (isSameSelection && tr2.storedMarks) { + tr2.setStoredMarks(tr2.storedMarks); + } + delayedFocus(); + } + return true; +}; +var forEach = (items, fn) => (props) => { + return items.every((item, index) => fn(item, { ...props, index })); +}; +var insertContent = (value, options) => ({ tr: tr2, commands }) => { + return commands.insertContentAt( + { from: tr2.selection.from, to: tr2.selection.to }, + value, + options + ); +}; +var removeWhitespaces = (node) => { + const children = node.childNodes; + for (let i = children.length - 1; i >= 0; i -= 1) { + const child = children[i]; + if (child.nodeType === 3 && child.nodeValue && /^(\n\s\s|\n)$/.test(child.nodeValue)) { + node.removeChild(child); + } else if (child.nodeType === 1) { + removeWhitespaces(child); + } + } + return node; +}; +function elementFromString(value) { + if (typeof window === "undefined") { + throw new Error( + "[tiptap error]: there is no window object available, so this function cannot be used" + ); + } + const wrappedValue = `${value}`; + const html = new window.DOMParser().parseFromString(wrappedValue, "text/html").body; + return removeWhitespaces(html); +} +function createNodeFromContent(content, schema, options) { + if (content instanceof Node || content instanceof Fragment) { + return content; + } + options = { + slice: true, + parseOptions: {}, + ...options + }; + const isJSONContent = typeof content === "object" && content !== null; + const isTextContent = typeof content === "string"; + if (isJSONContent) { + try { + const isArrayContent = Array.isArray(content) && content.length > 0; + if (isArrayContent) { + return Fragment.fromArray(content.map((item) => schema.nodeFromJSON(item))); + } + const node = schema.nodeFromJSON(content); + if (options.errorOnInvalidContent) { + node.check(); + } + return node; + } catch (error) { + if (options.errorOnInvalidContent) { + throw new Error("[tiptap error]: Invalid JSON content", { cause: error }); + } + console.warn("[tiptap warn]: Invalid content.", "Passed value:", content, "Error:", error); + return createNodeFromContent("", schema, options); + } + } + if (isTextContent) { + if (options.errorOnInvalidContent) { + let hasInvalidContent = false; + let invalidContent = ""; + const contentCheckSchema = new Schema({ + topNode: schema.spec.topNode, + marks: schema.spec.marks, + // Prosemirror's schemas are executed such that: the last to execute, matches last + // This means that we can add a catch-all node at the end of the schema to catch any content that we don't know how to handle + nodes: schema.spec.nodes.append({ + __tiptap__private__unknown__catch__all__node: { + content: "inline*", + group: "block", + parseDOM: [ + { + tag: "*", + getAttrs: (e) => { + hasInvalidContent = true; + invalidContent = typeof e === "string" ? e : e.outerHTML; + return null; + } + } + ] + } + }) + }); + if (options.slice) { + DOMParser2.fromSchema(contentCheckSchema).parseSlice( + elementFromString(content), + options.parseOptions + ); + } else { + DOMParser2.fromSchema(contentCheckSchema).parse( + elementFromString(content), + options.parseOptions + ); + } + if (options.errorOnInvalidContent && hasInvalidContent) { + throw new Error("[tiptap error]: Invalid HTML content", { + cause: new Error(`Invalid element found: ${invalidContent}`) + }); + } + } + const parser = DOMParser2.fromSchema(schema); + if (options.slice) { + return parser.parseSlice(elementFromString(content), options.parseOptions).content; + } + return parser.parse(elementFromString(content), options.parseOptions); + } + return createNodeFromContent("", schema, options); +} +function selectionToInsertionEnd2(tr2, startLen, bias) { + const last2 = tr2.steps.length - 1; + if (last2 < startLen) { + return; + } + const step = tr2.steps[last2]; + if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) { + return; + } + const map4 = tr2.mapping.maps[last2]; + let end = 0; + map4.forEach((_from, _to, _newFrom, newTo) => { + if (end === 0) { + end = newTo; + } + }); + tr2.setSelection(Selection.near(tr2.doc.resolve(end), bias)); +} +var isFragment = (nodeOrFragment) => { + return !("type" in nodeOrFragment); +}; +var insertContentAt = (position, value, options) => ({ tr: tr2, dispatch, editor }) => { + var _a; + if (dispatch) { + options = { + parseOptions: editor.options.parseOptions, + updateSelection: true, + applyInputRules: false, + applyPasteRules: false, + ...options + }; + let content; + const emitContentError = (error) => { + editor.emit("contentError", { + editor, + error, + disableCollaboration: () => { + if ("collaboration" in editor.storage && typeof editor.storage.collaboration === "object" && editor.storage.collaboration) { + ; + editor.storage.collaboration.isDisabled = true; + } + } + }); + }; + const parseOptions = { + preserveWhitespace: "full", + ...options.parseOptions + }; + if (!options.errorOnInvalidContent && !editor.options.enableContentCheck && editor.options.emitContentError) { + try { + createNodeFromContent(value, editor.schema, { + parseOptions, + errorOnInvalidContent: true + }); + } catch (e) { + emitContentError(e); + } + } + try { + content = createNodeFromContent(value, editor.schema, { + parseOptions, + errorOnInvalidContent: (_a = options.errorOnInvalidContent) != null ? _a : editor.options.enableContentCheck + }); + } catch (e) { + emitContentError(e); + return false; + } + let { from: from3, to } = typeof position === "number" ? { from: position, to: position } : { from: position.from, to: position.to }; + let isOnlyTextContent = true; + let isOnlyBlockContent = true; + const nodes = isFragment(content) ? content : [content]; + nodes.forEach((node) => { + node.check(); + isOnlyTextContent = isOnlyTextContent ? node.isText && node.marks.length === 0 : false; + isOnlyBlockContent = isOnlyBlockContent ? node.isBlock : false; + }); + if (from3 === to && isOnlyBlockContent) { + const { parent } = tr2.doc.resolve(from3); + const isEmptyTextBlock = parent.isTextblock && !parent.type.spec.code && !parent.childCount; + if (isEmptyTextBlock) { + from3 -= 1; + to += 1; + } + } + let newContent; + if (isOnlyTextContent) { + if (Array.isArray(value)) { + newContent = value.map((v2) => v2.text || "").join(""); + } else if (value instanceof Fragment) { + let text2 = ""; + value.forEach((node) => { + if (node.text) { + text2 += node.text; + } + }); + newContent = text2; + } else if (typeof value === "object" && !!value && !!value.text) { + newContent = value.text; + } else { + newContent = value; + } + tr2.insertText(newContent, from3, to); + } else { + newContent = content; + const $from = tr2.doc.resolve(from3); + const $fromNode = $from.node(); + const fromSelectionAtStart = $from.parentOffset === 0; + const isTextSelection2 = $fromNode.isText || $fromNode.isTextblock; + const hasContent2 = $fromNode.content.size > 0; + if (fromSelectionAtStart && isTextSelection2 && hasContent2 && isOnlyBlockContent) { + from3 = Math.max(0, from3 - 1); + } + tr2.replaceWith(from3, to, newContent); + } + if (options.updateSelection) { + selectionToInsertionEnd2(tr2, tr2.steps.length - 1, -1); + } + if (options.applyInputRules) { + tr2.setMeta("applyInputRules", { from: from3, text: newContent }); + } + if (options.applyPasteRules) { + tr2.setMeta("applyPasteRules", { from: from3, text: newContent }); + } + } + return true; +}; +var joinUp2 = () => ({ state, dispatch }) => { + return joinUp(state, dispatch); +}; +var joinDown2 = () => ({ state, dispatch }) => { + return joinDown(state, dispatch); +}; +var joinBackward2 = () => ({ state, dispatch }) => { + return joinBackward(state, dispatch); +}; +var joinForward2 = () => ({ state, dispatch }) => { + return joinForward(state, dispatch); +}; +var joinItemBackward = () => ({ state, dispatch, tr: tr2 }) => { + try { + const point = joinPoint(state.doc, state.selection.$from.pos, -1); + if (point === null || point === void 0) { + return false; + } + tr2.join(point, 2); + if (dispatch) { + dispatch(tr2); + } + return true; + } catch { + return false; + } +}; +var joinItemForward = () => ({ state, dispatch, tr: tr2 }) => { + try { + const point = joinPoint(state.doc, state.selection.$from.pos, 1); + if (point === null || point === void 0) { + return false; + } + tr2.join(point, 2); + if (dispatch) { + dispatch(tr2); + } + return true; + } catch { + return false; + } +}; +var joinTextblockBackward2 = () => ({ state, dispatch }) => { + return joinTextblockBackward(state, dispatch); +}; +var joinTextblockForward2 = () => ({ state, dispatch }) => { + return joinTextblockForward(state, dispatch); +}; +function isMacOS() { + return typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; +} +function normalizeKeyName2(name) { + const parts = name.split(/-(?!$)/); + let result = parts[parts.length - 1]; + if (result === "Space") { + result = " "; + } + let alt; + let ctrl; + let shift2; + let meta; + for (let i = 0; i < parts.length - 1; i += 1) { + const mod = parts[i]; + if (/^(cmd|meta|m)$/i.test(mod)) { + meta = true; + } else if (/^a(lt)?$/i.test(mod)) { + alt = true; + } else if (/^(c|ctrl|control)$/i.test(mod)) { + ctrl = true; + } else if (/^s(hift)?$/i.test(mod)) { + shift2 = true; + } else if (/^mod$/i.test(mod)) { + if (isiOS() || isMacOS()) { + meta = true; + } else { + ctrl = true; + } + } else { + throw new Error(`Unrecognized modifier name: ${mod}`); + } + } + if (alt) { + result = `Alt-${result}`; + } + if (ctrl) { + result = `Ctrl-${result}`; + } + if (meta) { + result = `Meta-${result}`; + } + if (shift2) { + result = `Shift-${result}`; + } + return result; +} +var keyboardShortcut = (name) => ({ editor, view, tr: tr2, dispatch }) => { + const keys3 = normalizeKeyName2(name).split(/-(?!$)/); + const key = keys3.find((item) => !["Alt", "Ctrl", "Meta", "Shift"].includes(item)); + const event = new KeyboardEvent("keydown", { + key: key === "Space" ? " " : key, + altKey: keys3.includes("Alt"), + ctrlKey: keys3.includes("Ctrl"), + metaKey: keys3.includes("Meta"), + shiftKey: keys3.includes("Shift"), + bubbles: true, + cancelable: true + }); + const capturedTransaction = editor.captureTransaction(() => { + view.someProp("handleKeyDown", (f) => f(view, event)); + }); + capturedTransaction == null ? void 0 : capturedTransaction.steps.forEach((step) => { + const newStep = step.map(tr2.mapping); + if (newStep && dispatch) { + tr2.maybeStep(newStep); + } + }); + return true; +}; +function isNodeActive(state, typeOrName, attributes = {}) { + const { from: from3, to, empty: empty2 } = state.selection; + const type = typeOrName ? getNodeType(typeOrName, state.schema) : null; + const nodeRanges = []; + state.doc.nodesBetween(from3, to, (node, pos) => { + if (node.isText) { + return; + } + const relativeFrom = Math.max(from3, pos); + const relativeTo = Math.min(to, pos + node.nodeSize); + nodeRanges.push({ + node, + from: relativeFrom, + to: relativeTo + }); + }); + const selectionRange = to - from3; + const matchedNodeRanges = nodeRanges.filter((nodeRange) => { + if (!type) { + return true; + } + return type.name === nodeRange.node.type.name; + }).filter((nodeRange) => objectIncludes(nodeRange.node.attrs, attributes, { strict: false })); + if (empty2) { + return !!matchedNodeRanges.length; + } + const range = matchedNodeRanges.reduce((sum, nodeRange) => sum + nodeRange.to - nodeRange.from, 0); + return range >= selectionRange; +} +var lift3 = (typeOrName, attributes = {}) => ({ state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + const isActive2 = isNodeActive(state, type, attributes); + if (!isActive2) { + return false; + } + return lift2(state, dispatch); +}; +var liftEmptyBlock2 = () => ({ state, dispatch }) => { + return liftEmptyBlock(state, dispatch); +}; +var liftListItem2 = (typeOrName) => ({ state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + return liftListItem(type)(state, dispatch); +}; +var newlineInCode2 = () => ({ state, dispatch }) => { + return newlineInCode(state, dispatch); +}; +function getSchemaTypeNameByName(name, schema) { + if (schema.nodes[name]) { + return "node"; + } + if (schema.marks[name]) { + return "mark"; + } + return null; +} +function deleteProps(obj, propOrProps) { + const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps; + return Object.keys(obj).reduce((newObj, prop) => { + if (!props.includes(prop)) { + newObj[prop] = obj[prop]; + } + return newObj; + }, {}); +} +var resetAttributes = (typeOrName, attributes) => ({ tr: tr2, state, dispatch }) => { + let nodeType = null; + let markType = null; + const schemaType = getSchemaTypeNameByName( + typeof typeOrName === "string" ? typeOrName : typeOrName.name, + state.schema + ); + if (!schemaType) { + return false; + } + if (schemaType === "node") { + nodeType = getNodeType(typeOrName, state.schema); + } + if (schemaType === "mark") { + markType = getMarkType(typeOrName, state.schema); + } + let canReset = false; + tr2.selection.ranges.forEach((range) => { + state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => { + if (nodeType && nodeType === node.type) { + canReset = true; + if (dispatch) { + tr2.setNodeMarkup(pos, void 0, deleteProps(node.attrs, attributes)); + } + } + if (markType && node.marks.length) { + node.marks.forEach((mark) => { + if (markType === mark.type) { + canReset = true; + if (dispatch) { + tr2.addMark( + pos, + pos + node.nodeSize, + markType.create(deleteProps(mark.attrs, attributes)) + ); + } + } + }); + } + }); + }); + return canReset; +}; +var scrollIntoView = () => ({ tr: tr2, dispatch }) => { + if (dispatch) { + tr2.scrollIntoView(); + } + return true; +}; +var selectAll2 = () => ({ tr: tr2, dispatch }) => { + if (dispatch) { + const selection = new AllSelection(tr2.doc); + tr2.setSelection(selection); + } + return true; +}; +var selectNodeBackward2 = () => ({ state, dispatch }) => { + return selectNodeBackward(state, dispatch); +}; +var selectNodeForward2 = () => ({ state, dispatch }) => { + return selectNodeForward(state, dispatch); +}; +var selectParentNode2 = () => ({ state, dispatch }) => { + return selectParentNode(state, dispatch); +}; +var selectTextblockEnd2 = () => ({ state, dispatch }) => { + return selectTextblockEnd(state, dispatch); +}; +var selectTextblockStart2 = () => ({ state, dispatch }) => { + return selectTextblockStart(state, dispatch); +}; +function createDocument(content, schema, parseOptions = {}, options = {}) { + return createNodeFromContent(content, schema, { + slice: false, + parseOptions, + errorOnInvalidContent: options.errorOnInvalidContent + }); +} +var setContent = (content, { errorOnInvalidContent, emitUpdate = true, parseOptions = {} } = {}) => ({ editor, tr: tr2, dispatch, commands }) => { + const { doc: doc4 } = tr2; + if (parseOptions.preserveWhitespace !== "full") { + const document2 = createDocument(content, editor.schema, parseOptions, { + errorOnInvalidContent: errorOnInvalidContent != null ? errorOnInvalidContent : editor.options.enableContentCheck + }); + if (dispatch) { + tr2.replaceWith(0, doc4.content.size, document2).setMeta("preventUpdate", !emitUpdate); + } + return true; + } + if (dispatch) { + tr2.setMeta("preventUpdate", !emitUpdate); + } + return commands.insertContentAt({ from: 0, to: doc4.content.size }, content, { + parseOptions, + errorOnInvalidContent: errorOnInvalidContent != null ? errorOnInvalidContent : editor.options.enableContentCheck + }); +}; +function getMarkAttributes(state, typeOrName) { + const type = getMarkType(typeOrName, state.schema); + const { from: from3, to, empty: empty2 } = state.selection; + const marks = []; + if (empty2) { + if (state.storedMarks) { + marks.push(...state.storedMarks); + } + marks.push(...state.selection.$head.marks()); + } else { + state.doc.nodesBetween(from3, to, (node) => { + marks.push(...node.marks); + }); + } + const mark = marks.find((markItem) => markItem.type.name === type.name); + if (!mark) { + return {}; + } + return { ...mark.attrs }; +} +function combineTransactionSteps(oldDoc, transactions) { + const transform = new Transform(oldDoc); + transactions.forEach((transaction) => { + transaction.steps.forEach((step) => { + transform.step(step); + }); + }); + return transform; +} +function defaultBlockAt2(match2) { + for (let i = 0; i < match2.edgeCount; i += 1) { + const { type } = match2.edge(i); + if (type.isTextblock && !type.hasRequiredAttrs()) { + return type; + } + } + return null; +} +function findChildrenInRange(node, range, predicate) { + const nodesWithPos = []; + node.nodesBetween(range.from, range.to, (child, pos) => { + if (predicate(child)) { + nodesWithPos.push({ + node: child, + pos + }); + } + }); + return nodesWithPos; +} +function findParentNodeClosestToPos($pos, predicate) { + for (let i = $pos.depth; i > 0; i -= 1) { + const node = $pos.node(i); + if (predicate(node)) { + return { + pos: i > 0 ? $pos.before(i) : 0, + start: $pos.start(i), + depth: i, + node + }; + } + } +} +function findParentNode(predicate) { + return (selection) => findParentNodeClosestToPos(selection.$from, predicate); +} +function getExtensionField(extension, field, context) { + if (extension.config[field] === void 0 && extension.parent) { + return getExtensionField(extension.parent, field, context); + } + if (typeof extension.config[field] === "function") { + const value = extension.config[field].bind({ + ...context, + parent: extension.parent ? getExtensionField(extension.parent, field, context) : null + }); + return value; + } + return extension.config[field]; +} +function flattenExtensions(extensions) { + return extensions.map((extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage + }; + const addExtensions = getExtensionField( + extension, + "addExtensions", + context + ); + if (addExtensions) { + return [extension, ...flattenExtensions(addExtensions())]; + } + return extension; + }).flat(10); +} +function getHTMLFromFragment(fragment, schema) { + const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment); + const temporaryDocument = document.implementation.createHTMLDocument(); + const container = temporaryDocument.createElement("div"); + container.appendChild(documentFragment); + return container.innerHTML; +} +function isFunction(value) { + return typeof value === "function"; +} +function callOrReturn(value, context = void 0, ...props) { + if (isFunction(value)) { + if (context) { + return value.bind(context)(...props); + } + return value(...props); + } + return value; +} +function isEmptyObject(value = {}) { + return Object.keys(value).length === 0 && value.constructor === Object; +} +function splitExtensions(extensions) { + const baseExtensions = extensions.filter( + (extension) => extension.type === "extension" + ); + const nodeExtensions = extensions.filter((extension) => extension.type === "node"); + const markExtensions = extensions.filter((extension) => extension.type === "mark"); + return { + baseExtensions, + nodeExtensions, + markExtensions + }; +} +function getAttributesFromExtensions(extensions) { + const extensionAttributes = []; + const { nodeExtensions, markExtensions } = splitExtensions(extensions); + const nodeAndMarkExtensions = [...nodeExtensions, ...markExtensions]; + const defaultAttribute = { + default: null, + validate: void 0, + rendered: true, + renderHTML: null, + parseHTML: null, + keepOnSplit: true, + isRequired: false + }; + const nodeExtensionTypes = nodeExtensions.filter((ext) => ext.name !== "text").map((ext) => ext.name); + const markExtensionTypes = markExtensions.map((ext) => ext.name); + const allExtensionTypes = [...nodeExtensionTypes, ...markExtensionTypes]; + extensions.forEach((extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage, + extensions: nodeAndMarkExtensions + }; + const addGlobalAttributes = getExtensionField( + extension, + "addGlobalAttributes", + context + ); + if (!addGlobalAttributes) { + return; + } + const globalAttributes = addGlobalAttributes(); + globalAttributes.forEach((globalAttribute) => { + let resolvedTypes; + if (Array.isArray(globalAttribute.types)) { + resolvedTypes = globalAttribute.types; + } else if (globalAttribute.types === "*") { + resolvedTypes = allExtensionTypes; + } else if (globalAttribute.types === "nodes") { + resolvedTypes = nodeExtensionTypes; + } else if (globalAttribute.types === "marks") { + resolvedTypes = markExtensionTypes; + } else { + resolvedTypes = []; + } + resolvedTypes.forEach((type) => { + Object.entries(globalAttribute.attributes).forEach(([name, attribute]) => { + extensionAttributes.push({ + type, + name, + attribute: { + ...defaultAttribute, + ...attribute + } + }); + }); + }); + }); + }); + nodeAndMarkExtensions.forEach((extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage + }; + const addAttributes = getExtensionField(extension, "addAttributes", context); + if (!addAttributes) { + return; + } + const attributes = addAttributes(); + Object.entries(attributes).forEach(([name, attribute]) => { + const mergedAttr = { + ...defaultAttribute, + ...attribute + }; + if (typeof (mergedAttr == null ? void 0 : mergedAttr.default) === "function") { + mergedAttr.default = mergedAttr.default(); + } + if ((mergedAttr == null ? void 0 : mergedAttr.isRequired) && (mergedAttr == null ? void 0 : mergedAttr.default) === void 0) { + delete mergedAttr.default; + } + extensionAttributes.push({ + type: extension.name, + name, + attribute: mergedAttr + }); + }); + }); + return extensionAttributes; +} +function splitStyleDeclarations(styles) { + const result = []; + let current = ""; + let inSingleQuote = false; + let inDoubleQuote = false; + let parenDepth = 0; + const length2 = styles.length; + for (let i = 0; i < length2; i += 1) { + const char = styles[i]; + if (char === "'" && !inDoubleQuote) { + inSingleQuote = !inSingleQuote; + current += char; + continue; + } + if (char === '"' && !inSingleQuote) { + inDoubleQuote = !inDoubleQuote; + current += char; + continue; + } + if (!inSingleQuote && !inDoubleQuote) { + if (char === "(") { + parenDepth += 1; + current += char; + continue; + } + if (char === ")" && parenDepth > 0) { + parenDepth -= 1; + current += char; + continue; + } + if (char === ";" && parenDepth === 0) { + result.push(current); + current = ""; + continue; + } + } + current += char; + } + if (current) { + result.push(current); + } + return result; +} +function parseStyleEntries(styles) { + const pairs = []; + const declarations = splitStyleDeclarations(styles || ""); + const numDeclarations = declarations.length; + for (let i = 0; i < numDeclarations; i += 1) { + const declaration = declarations[i]; + const firstColonIndex = declaration.indexOf(":"); + if (firstColonIndex === -1) { + continue; + } + const property = declaration.slice(0, firstColonIndex).trim(); + const value = declaration.slice(firstColonIndex + 1).trim(); + if (property && value) { + pairs.push([property, value]); + } + } + return pairs; +} +function mergeAttributes(...objects) { + return objects.filter((item) => !!item).reduce((items, item) => { + const mergedAttributes = { ...items }; + Object.entries(item).forEach(([key, value]) => { + const exists = mergedAttributes[key]; + if (!exists) { + mergedAttributes[key] = value; + return; + } + if (key === "class") { + const valueClasses = value ? String(value).split(" ") : []; + const existingClasses = mergedAttributes[key] ? mergedAttributes[key].split(" ") : []; + const insertClasses = valueClasses.filter( + (valueClass) => !existingClasses.includes(valueClass) + ); + mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" "); + } else if (key === "style") { + const styleMap = new Map([ + ...parseStyleEntries(mergedAttributes[key]), + ...parseStyleEntries(value) + ]); + mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join("; "); + } else { + mergedAttributes[key] = value; + } + }); + return mergedAttributes; + }, {}); +} +function getRenderedAttributes(nodeOrMark, extensionAttributes) { + return extensionAttributes.filter((attribute) => attribute.type === nodeOrMark.type.name).filter((item) => item.attribute.rendered).map((item) => { + if (!item.attribute.renderHTML) { + return { + [item.name]: nodeOrMark.attrs[item.name] + }; + } + return item.attribute.renderHTML(nodeOrMark.attrs) || {}; + }).reduce((attributes, attribute) => mergeAttributes(attributes, attribute), {}); +} +function fromString(value) { + if (typeof value !== "string") { + return value; + } + if (value.match(/^[+-]?(?:\d*\.)?\d+$/)) { + return Number(value); + } + if (value === "true") { + return true; + } + if (value === "false") { + return false; + } + return value; +} +function injectExtensionAttributesToParseRule(parseRule, extensionAttributes) { + if ("style" in parseRule) { + return parseRule; + } + return { + ...parseRule, + getAttrs: (node) => { + const oldAttributes = parseRule.getAttrs ? parseRule.getAttrs(node) : parseRule.attrs; + if (oldAttributes === false) { + return false; + } + const newAttributes = extensionAttributes.reduce((items, item) => { + const value = item.attribute.parseHTML ? item.attribute.parseHTML(node) : fromString(node.getAttribute(item.name)); + if (value === null || value === void 0) { + return items; + } + return { + ...items, + [item.name]: value + }; + }, {}); + return { ...oldAttributes, ...newAttributes }; + } + }; +} +function cleanUpSchemaItem(data) { + return Object.fromEntries( + // @ts-ignore + Object.entries(data).filter(([key, value]) => { + if (key === "attrs" && isEmptyObject(value)) { + return false; + } + return value !== null && value !== void 0; + }) + ); +} +function buildAttributeSpec(extensionAttribute) { + var _a, _b; + const spec = {}; + if (!((_a = extensionAttribute == null ? void 0 : extensionAttribute.attribute) == null ? void 0 : _a.isRequired) && "default" in ((extensionAttribute == null ? void 0 : extensionAttribute.attribute) || {})) { + spec.default = extensionAttribute.attribute.default; + } + if (((_b = extensionAttribute == null ? void 0 : extensionAttribute.attribute) == null ? void 0 : _b.validate) !== void 0) { + spec.validate = extensionAttribute.attribute.validate; + } + return [extensionAttribute.name, spec]; +} +function getSchemaByResolvedExtensions(extensions, editor) { + var _a; + const allAttributes = getAttributesFromExtensions(extensions); + const { nodeExtensions, markExtensions } = splitExtensions(extensions); + const topNode = (_a = nodeExtensions.find((extension) => getExtensionField(extension, "topNode"))) == null ? void 0 : _a.name; + const nodes = Object.fromEntries( + nodeExtensions.map((extension) => { + const extensionAttributes = allAttributes.filter( + (attribute) => attribute.type === extension.name + ); + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage, + editor + }; + const extraNodeFields = extensions.reduce((fields, e) => { + const extendNodeSchema = getExtensionField( + e, + "extendNodeSchema", + context + ); + return { + ...fields, + ...extendNodeSchema ? extendNodeSchema(extension) : {} + }; + }, {}); + const schema = cleanUpSchemaItem({ + ...extraNodeFields, + content: callOrReturn( + getExtensionField(extension, "content", context) + ), + marks: callOrReturn(getExtensionField(extension, "marks", context)), + group: callOrReturn(getExtensionField(extension, "group", context)), + inline: callOrReturn(getExtensionField(extension, "inline", context)), + atom: callOrReturn(getExtensionField(extension, "atom", context)), + selectable: callOrReturn( + getExtensionField(extension, "selectable", context) + ), + draggable: callOrReturn( + getExtensionField(extension, "draggable", context) + ), + code: callOrReturn(getExtensionField(extension, "code", context)), + whitespace: callOrReturn( + getExtensionField(extension, "whitespace", context) + ), + linebreakReplacement: callOrReturn( + getExtensionField( + extension, + "linebreakReplacement", + context + ) + ), + defining: callOrReturn( + getExtensionField(extension, "defining", context) + ), + isolating: callOrReturn( + getExtensionField(extension, "isolating", context) + ), + attrs: Object.fromEntries(extensionAttributes.map(buildAttributeSpec)) + }); + const parseHTML = callOrReturn( + getExtensionField(extension, "parseHTML", context) + ); + if (parseHTML) { + schema.parseDOM = parseHTML.map( + (parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes) + ); + } + const renderHTML = getExtensionField( + extension, + "renderHTML", + context + ); + if (renderHTML) { + schema.toDOM = (node) => renderHTML({ + node, + HTMLAttributes: getRenderedAttributes(node, extensionAttributes) + }); + } + const renderText = getExtensionField( + extension, + "renderText", + context + ); + if (renderText) { + schema.toText = renderText; + } + return [extension.name, schema]; + }) + ); + const marks = Object.fromEntries( + markExtensions.map((extension) => { + const extensionAttributes = allAttributes.filter( + (attribute) => attribute.type === extension.name + ); + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage, + editor + }; + const extraMarkFields = extensions.reduce((fields, e) => { + const extendMarkSchema = getExtensionField( + e, + "extendMarkSchema", + context + ); + return { + ...fields, + ...extendMarkSchema ? extendMarkSchema(extension) : {} + }; + }, {}); + const schema = cleanUpSchemaItem({ + ...extraMarkFields, + inclusive: callOrReturn( + getExtensionField(extension, "inclusive", context) + ), + excludes: callOrReturn( + getExtensionField(extension, "excludes", context) + ), + group: callOrReturn(getExtensionField(extension, "group", context)), + spanning: callOrReturn( + getExtensionField(extension, "spanning", context) + ), + code: callOrReturn(getExtensionField(extension, "code", context)), + attrs: Object.fromEntries(extensionAttributes.map(buildAttributeSpec)) + }); + const parseHTML = callOrReturn( + getExtensionField(extension, "parseHTML", context) + ); + if (parseHTML) { + schema.parseDOM = parseHTML.map( + (parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes) + ); + } + const renderHTML = getExtensionField( + extension, + "renderHTML", + context + ); + if (renderHTML) { + schema.toDOM = (mark) => renderHTML({ + mark, + HTMLAttributes: getRenderedAttributes(mark, extensionAttributes) + }); + } + return [extension.name, schema]; + }) + ); + return new Schema({ + topNode, + nodes, + marks + }); +} +function findDuplicates(items) { + const filtered = items.filter((el, index) => items.indexOf(el) !== index); + return Array.from(new Set(filtered)); +} +function sortExtensions(extensions) { + const defaultPriority = 100; + return extensions.sort((a, b2) => { + const priorityA = getExtensionField(a, "priority") || defaultPriority; + const priorityB = getExtensionField(b2, "priority") || defaultPriority; + if (priorityA > priorityB) { + return -1; + } + if (priorityA < priorityB) { + return 1; + } + return 0; + }); +} +function resolveExtensions(extensions) { + const resolvedExtensions = sortExtensions(flattenExtensions(extensions)); + const duplicatedNames = findDuplicates(resolvedExtensions.map((extension) => extension.name)); + if (duplicatedNames.length) { + console.warn( + `[tiptap warn]: Duplicate extension names found: [${duplicatedNames.map((item) => `'${item}'`).join(", ")}]. This can lead to issues.` + ); + } + return resolvedExtensions; +} +function getTextBetween(startNode, range, options) { + const { from: from3, to } = range; + const { blockSeparator = "\n\n", textSerializers = {} } = options || {}; + let text2 = ""; + startNode.nodesBetween(from3, to, (node, pos, parent, index) => { + var _a; + if (node.isBlock && pos > from3) { + text2 += blockSeparator; + } + const textSerializer = textSerializers == null ? void 0 : textSerializers[node.type.name]; + if (textSerializer) { + if (parent) { + text2 += textSerializer({ + node, + pos, + parent, + index, + range + }); + } + return false; + } + if (node.isText) { + text2 += (_a = node == null ? void 0 : node.text) == null ? void 0 : _a.slice(Math.max(from3, pos) - pos, to - pos); + } + }); + return text2; +} +function getText2(node, options) { + const range = { + from: 0, + to: node.content.size + }; + return getTextBetween(node, range, options); +} +function getTextSerializersFromSchema(schema) { + return Object.fromEntries( + Object.entries(schema.nodes).filter(([, node]) => node.spec.toText).map(([name, node]) => [name, node.spec.toText]) + ); +} +function getNodeAttributes(state, typeOrName) { + const type = getNodeType(typeOrName, state.schema); + const { from: from3, to } = state.selection; + const nodes = []; + state.doc.nodesBetween(from3, to, (node2) => { + nodes.push(node2); + }); + const node = nodes.reverse().find((nodeItem) => nodeItem.type.name === type.name); + if (!node) { + return {}; + } + return { ...node.attrs }; +} +function getAttributes(state, typeOrName) { + const schemaType = getSchemaTypeNameByName( + typeof typeOrName === "string" ? typeOrName : typeOrName.name, + state.schema + ); + if (schemaType === "node") { + return getNodeAttributes(state, typeOrName); + } + if (schemaType === "mark") { + return getMarkAttributes(state, typeOrName); + } + return {}; +} +function removeDuplicates(array, by = JSON.stringify) { + const seen = {}; + return array.filter((item) => { + const key = by(item); + return Object.prototype.hasOwnProperty.call(seen, key) ? false : seen[key] = true; + }); +} +function simplifyChangedRanges(changes) { + const uniqueChanges = removeDuplicates(changes); + return uniqueChanges.length === 1 ? uniqueChanges : uniqueChanges.filter((change, index) => { + const rest = uniqueChanges.filter((_2, i) => i !== index); + return !rest.some((otherChange) => { + return change.oldRange.from >= otherChange.oldRange.from && change.oldRange.to <= otherChange.oldRange.to && change.newRange.from >= otherChange.newRange.from && change.newRange.to <= otherChange.newRange.to; + }); + }); +} +function getChangedRanges(transform) { + const { mapping, steps } = transform; + const changes = []; + mapping.maps.forEach((stepMap, index) => { + const ranges = []; + if (!stepMap.ranges.length) { + const { from: from3, to } = steps[index]; + if (from3 === void 0 || to === void 0) { + return; + } + ranges.push({ from: from3, to }); + } else { + stepMap.forEach((from3, to) => { + ranges.push({ from: from3, to }); + }); + } + ranges.forEach(({ from: from3, to }) => { + const newStart = mapping.slice(index).map(from3, -1); + const newEnd = mapping.slice(index).map(to); + const oldStart = mapping.invert().map(newStart, -1); + const oldEnd = mapping.invert().map(newEnd); + changes.push({ + oldRange: { + from: oldStart, + to: oldEnd + }, + newRange: { + from: newStart, + to: newEnd + } + }); + }); + }); + return simplifyChangedRanges(changes); +} +function getMarksBetween(from3, to, doc4) { + const marks = []; + if (from3 === to) { + doc4.resolve(from3).marks().forEach((mark) => { + const $pos = doc4.resolve(from3); + const range = getMarkRange($pos, mark.type); + if (!range) { + return; + } + marks.push({ + mark, + ...range + }); + }); + } else { + doc4.nodesBetween(from3, to, (node, pos) => { + if (!node || (node == null ? void 0 : node.nodeSize) === void 0) { + return; + } + marks.push( + ...node.marks.map((mark) => ({ + from: pos, + to: pos + node.nodeSize, + mark + })) + ); + }); + } + return marks; +} +var getNodeAtPosition = (state, typeOrName, pos, maxDepth = 20) => { + const $pos = state.doc.resolve(pos); + let currentDepth = maxDepth; + let node = null; + while (currentDepth > 0 && node === null) { + const currentNode = $pos.node(currentDepth); + if ((currentNode == null ? void 0 : currentNode.type.name) === typeOrName) { + node = currentNode; + } else { + currentDepth -= 1; + } + } + return [node, currentDepth]; +}; +function getSchemaTypeByName(name, schema) { + return schema.nodes[name] || schema.marks[name] || null; +} +function getSplittedAttributes(extensionAttributes, typeName, attributes) { + return Object.fromEntries( + Object.entries(attributes).filter(([name]) => { + const extensionAttribute = extensionAttributes.find((item) => { + return item.type === typeName && item.name === name; + }); + if (!extensionAttribute) { + return false; + } + return extensionAttribute.attribute.keepOnSplit; + }) + ); +} +var getTextContentFromNodes = ($from, maxMatch = 500) => { + let textBefore = ""; + const sliceEndPos = $from.parentOffset; + $from.parent.nodesBetween( + Math.max(0, sliceEndPos - maxMatch), + sliceEndPos, + (node, pos, parent, index) => { + var _a, _b; + const chunk = ((_b = (_a = node.type.spec).toText) == null ? void 0 : _b.call(_a, { + node, + pos, + parent, + index + })) || node.textContent || "%leaf%"; + textBefore += node.isAtom && !node.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos)); + } + ); + return textBefore; +}; +function isMarkActive(state, typeOrName, attributes = {}) { + const { empty: empty2, ranges } = state.selection; + const type = typeOrName ? getMarkType(typeOrName, state.schema) : null; + if (empty2) { + return !!(state.storedMarks || state.selection.$from.marks()).filter((mark) => { + if (!type) { + return true; + } + return type.name === mark.type.name; + }).find((mark) => objectIncludes(mark.attrs, attributes, { strict: false })); + } + let selectionRange = 0; + const markRanges = []; + ranges.forEach(({ $from, $to }) => { + const from3 = $from.pos; + const to = $to.pos; + state.doc.nodesBetween(from3, to, (node, pos) => { + if (type && node.inlineContent && !node.type.allowsMarkType(type)) { + return false; + } + if (!node.isText && !node.marks.length) { + return; + } + const relativeFrom = Math.max(from3, pos); + const relativeTo = Math.min(to, pos + node.nodeSize); + const range2 = relativeTo - relativeFrom; + selectionRange += range2; + markRanges.push( + ...node.marks.map((mark) => ({ + mark, + from: relativeFrom, + to: relativeTo + })) + ); + }); + }); + if (selectionRange === 0) { + return false; + } + const matchedRange = markRanges.filter((markRange) => { + if (!type) { + return true; + } + return type.name === markRange.mark.type.name; + }).filter((markRange) => objectIncludes(markRange.mark.attrs, attributes, { strict: false })).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0); + const excludedRange = markRanges.filter((markRange) => { + if (!type) { + return true; + } + return markRange.mark.type !== type && markRange.mark.type.excludes(type); + }).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0); + const range = matchedRange > 0 ? matchedRange + excludedRange : matchedRange; + return range >= selectionRange; +} +function isActive(state, name, attributes = {}) { + if (!name) { + return isNodeActive(state, null, attributes) || isMarkActive(state, null, attributes); + } + const schemaType = getSchemaTypeNameByName(name, state.schema); + if (schemaType === "node") { + return isNodeActive(state, name, attributes); + } + if (schemaType === "mark") { + return isMarkActive(state, name, attributes); + } + return false; +} +var isAtEndOfNode = (state, nodeType) => { + const { $from, $to, $anchor } = state.selection; + if (nodeType) { + const parentNode2 = findParentNode((node) => node.type.name === nodeType)(state.selection); + if (!parentNode2) { + return false; + } + const $parentPos = state.doc.resolve(parentNode2.pos + 1); + if ($anchor.pos + 1 === $parentPos.end()) { + return true; + } + return false; + } + if ($to.parentOffset < $to.parent.nodeSize - 2 || $from.pos !== $to.pos) { + return false; + } + return true; +}; +var isAtStartOfNode = (state) => { + const { $from, $to } = state.selection; + if ($from.parentOffset > 0 || $from.pos !== $to.pos) { + return false; + } + return true; +}; +function isExtensionRulesEnabled(extension, enabled) { + if (Array.isArray(enabled)) { + return enabled.some((enabledExtension) => { + const name = typeof enabledExtension === "string" ? enabledExtension : enabledExtension.name; + return name === extension.name; + }); + } + return enabled; +} +function isList(name, extensions) { + const { nodeExtensions } = splitExtensions(extensions); + const extension = nodeExtensions.find((item) => item.name === name); + if (!extension) { + return false; + } + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage + }; + const group = callOrReturn(getExtensionField(extension, "group", context)); + if (typeof group !== "string") { + return false; + } + return group.split(" ").includes("list"); +} +function isNodeEmpty(node, { + checkChildren = true, + ignoreWhitespace = false +} = {}) { + var _a; + if (ignoreWhitespace) { + if (node.type.name === "hardBreak") { + return true; + } + if (node.isText) { + return !/\S/.test((_a = node.text) != null ? _a : ""); + } + } + if (node.isText) { + return !node.text; + } + if (node.isAtom || node.isLeaf) { + return false; + } + if (node.content.childCount === 0) { + return true; + } + if (checkChildren) { + let isContentEmpty = true; + node.content.forEach((childNode) => { + if (isContentEmpty === false) { + return; + } + if (!isNodeEmpty(childNode, { ignoreWhitespace, checkChildren })) { + isContentEmpty = false; + } + }); + return isContentEmpty; + } + return false; +} +function isNodeSelection(value) { + return value instanceof NodeSelection; +} +var MappablePosition = class _MappablePosition { + constructor(position) { + this.position = position; + } + /** + * Creates a MappablePosition from a JSON object. + */ + static fromJSON(json) { + return new _MappablePosition(json.position); + } + /** + * Converts the MappablePosition to a JSON object. + */ + toJSON() { + return { + position: this.position + }; + } +}; +function getUpdatedPosition(position, transaction) { + const mapResult = transaction.mapping.mapResult(position.position); + return { + position: new MappablePosition(mapResult.pos), + mapResult + }; +} +function createMappablePosition(position) { + return new MappablePosition(position); +} +function canSetMark(state, tr2, newMarkType) { + var _a; + const { selection } = tr2; + let cursor = null; + if (isTextSelection(selection)) { + cursor = selection.$cursor; + } + if (cursor) { + const currentMarks = (_a = state.storedMarks) != null ? _a : cursor.marks(); + const parentAllowsMarkType = cursor.parent.type.allowsMarkType(newMarkType); + return parentAllowsMarkType && (!!newMarkType.isInSet(currentMarks) || !currentMarks.some((mark) => mark.type.excludes(newMarkType))); + } + const { ranges } = selection; + return ranges.some(({ $from, $to }) => { + let someNodeSupportsMark = $from.depth === 0 ? state.doc.inlineContent && state.doc.type.allowsMarkType(newMarkType) : false; + state.doc.nodesBetween($from.pos, $to.pos, (node, _pos, parent) => { + if (someNodeSupportsMark) { + return false; + } + if (node.isInline) { + const parentAllowsMarkType = !parent || parent.type.allowsMarkType(newMarkType); + const currentMarksAllowMarkType = !!newMarkType.isInSet(node.marks) || !node.marks.some((otherMark) => otherMark.type.excludes(newMarkType)); + someNodeSupportsMark = parentAllowsMarkType && currentMarksAllowMarkType; + } + return !someNodeSupportsMark; + }); + return someNodeSupportsMark; + }); +} +var setMark = (typeOrName, attributes = {}) => ({ tr: tr2, state, dispatch }) => { + const { selection } = tr2; + const { empty: empty2, ranges } = selection; + const type = getMarkType(typeOrName, state.schema); + if (dispatch) { + if (empty2) { + const oldAttributes = getMarkAttributes(state, type); + tr2.addStoredMark( + type.create({ + ...oldAttributes, + ...attributes + }) + ); + } else { + ranges.forEach((range) => { + const from3 = range.$from.pos; + const to = range.$to.pos; + state.doc.nodesBetween(from3, to, (node, pos) => { + const trimmedFrom = Math.max(pos, from3); + const trimmedTo = Math.min(pos + node.nodeSize, to); + const someHasMark = node.marks.find((mark) => mark.type === type); + if (someHasMark) { + node.marks.forEach((mark) => { + if (type === mark.type) { + tr2.addMark( + trimmedFrom, + trimmedTo, + type.create({ + ...mark.attrs, + ...attributes + }) + ); + } + }); + } else { + tr2.addMark(trimmedFrom, trimmedTo, type.create(attributes)); + } + }); + }); + } + } + return canSetMark(state, tr2, type); +}; +var setMeta = (key, value) => ({ tr: tr2 }) => { + tr2.setMeta(key, value); + return true; +}; +var setNode = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => { + const type = getNodeType(typeOrName, state.schema); + let attributesToCopy; + if (state.selection.$anchor.sameParent(state.selection.$head)) { + attributesToCopy = state.selection.$anchor.parent.attrs; + } + if (!type.isTextblock) { + console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.'); + return false; + } + return chain().command(({ commands }) => { + const canSetBlock = setBlockType2(type, { ...attributesToCopy, ...attributes })(state); + if (canSetBlock) { + return true; + } + return commands.clearNodes(); + }).command(({ state: updatedState }) => { + return setBlockType2(type, { ...attributesToCopy, ...attributes })(updatedState, dispatch); + }).run(); +}; +var setNodeSelection = (position) => ({ tr: tr2, dispatch }) => { + if (dispatch) { + const { doc: doc4 } = tr2; + const from3 = minMax(position, 0, doc4.content.size); + const selection = NodeSelection.create(doc4, from3); + tr2.setSelection(selection); + } + return true; +}; +var setTextDirection = (direction, position) => ({ tr: tr2, state, dispatch }) => { + const { selection } = state; + let from3; + let to; + if (typeof position === "number") { + from3 = position; + to = position; + } else if (position && "from" in position && "to" in position) { + from3 = position.from; + to = position.to; + } else { + from3 = selection.from; + to = selection.to; + } + if (dispatch) { + tr2.doc.nodesBetween(from3, to, (node, pos) => { + if (node.isText) { + return; + } + tr2.setNodeMarkup(pos, void 0, { + ...node.attrs, + dir: direction + }); + }); + } + return true; +}; +var setTextSelection = (position) => ({ tr: tr2, dispatch }) => { + if (dispatch) { + const { doc: doc4 } = tr2; + const { from: from3, to } = typeof position === "number" ? { from: position, to: position } : position; + const minPos = TextSelection.atStart(doc4).from; + const maxPos = TextSelection.atEnd(doc4).to; + const resolvedFrom = minMax(from3, minPos, maxPos); + const resolvedEnd = minMax(to, minPos, maxPos); + const selection = TextSelection.create(doc4, resolvedFrom, resolvedEnd); + tr2.setSelection(selection); + } + return true; +}; +var sinkListItem2 = (typeOrName) => ({ state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + return sinkListItem(type)(state, dispatch); +}; +function ensureMarks(state, splittableMarks) { + const marks = state.storedMarks || state.selection.$to.parentOffset && state.selection.$from.marks(); + if (marks) { + const filteredMarks = marks.filter((mark) => splittableMarks == null ? void 0 : splittableMarks.includes(mark.type.name)); + state.tr.ensureMarks(filteredMarks); + } +} +var splitBlock2 = ({ keepMarks = true } = {}) => ({ tr: tr2, state, dispatch, editor }) => { + const { selection, doc: doc4 } = tr2; + const { $from, $to } = selection; + const extensionAttributes = editor.extensionManager.attributes; + const newAttributes = getSplittedAttributes( + extensionAttributes, + $from.node().type.name, + $from.node().attrs + ); + if (selection instanceof NodeSelection && selection.node.isBlock) { + if (!$from.parentOffset || !canSplit(doc4, $from.pos)) { + return false; + } + if (dispatch) { + if (keepMarks) { + ensureMarks(state, editor.extensionManager.splittableMarks); + } + tr2.split($from.pos).scrollIntoView(); + } + return true; + } + if (!$from.parent.isBlock) { + return false; + } + const atEnd = $to.parentOffset === $to.parent.content.size; + const deflt = $from.depth === 0 ? void 0 : defaultBlockAt2($from.node(-1).contentMatchAt($from.indexAfter(-1))); + let types = atEnd && deflt ? [ + { + type: deflt, + attrs: newAttributes + } + ] : void 0; + let can = canSplit(tr2.doc, tr2.mapping.map($from.pos), 1, types); + if (!types && !can && canSplit(tr2.doc, tr2.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : void 0)) { + can = true; + types = deflt ? [ + { + type: deflt, + attrs: newAttributes + } + ] : void 0; + } + if (dispatch) { + if (can) { + if (selection instanceof TextSelection) { + tr2.deleteSelection(); + } + tr2.split(tr2.mapping.map($from.pos), 1, types); + if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) { + const first2 = tr2.mapping.map($from.before()); + const $first = tr2.doc.resolve(first2); + if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) { + tr2.setNodeMarkup(tr2.mapping.map($from.before()), deflt); + } + } + } + if (keepMarks) { + ensureMarks(state, editor.extensionManager.splittableMarks); + } + tr2.scrollIntoView(); + } + return can; +}; +var splitListItem = (typeOrName, overrideAttrs = {}) => ({ tr: tr2, state, dispatch, editor }) => { + var _a; + const type = getNodeType(typeOrName, state.schema); + const { $from, $to } = state.selection; + const node = state.selection.node; + if (node && node.isBlock || $from.depth < 2 || !$from.sameParent($to)) { + return false; + } + const grandParent = $from.node(-1); + if (grandParent.type !== type) { + return false; + } + const extensionAttributes = editor.extensionManager.attributes; + if ($from.parent.content.size === 0 && $from.node(-1).childCount === $from.indexAfter(-1)) { + if ($from.depth === 2 || $from.node(-3).type !== type || $from.index(-2) !== $from.node(-2).childCount - 1) { + return false; + } + if (dispatch) { + let wrap2 = Fragment.empty; + const depthBefore = $from.index(-1) ? 1 : $from.index(-2) ? 2 : 3; + for (let d2 = $from.depth - depthBefore; d2 >= $from.depth - 3; d2 -= 1) { + wrap2 = Fragment.from($from.node(d2).copy(wrap2)); + } + const depthAfter = ( + // oxlint-disable-next-line no-nested-ternary + $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3 + ); + const newNextTypeAttributes2 = { + ...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs), + ...overrideAttrs + }; + const nextType2 = ((_a = type.contentMatch.defaultType) == null ? void 0 : _a.createAndFill(newNextTypeAttributes2)) || void 0; + wrap2 = wrap2.append(Fragment.from(type.createAndFill(null, nextType2) || void 0)); + const start = $from.before($from.depth - (depthBefore - 1)); + tr2.replace(start, $from.after(-depthAfter), new Slice(wrap2, 4 - depthBefore, 0)); + let sel = -1; + tr2.doc.nodesBetween(start, tr2.doc.content.size, (n, pos) => { + if (sel > -1) { + return false; + } + if (n.isTextblock && n.content.size === 0) { + sel = pos + 1; + } + }); + if (sel > -1) { + tr2.setSelection(TextSelection.near(tr2.doc.resolve(sel))); + } + tr2.scrollIntoView(); + } + return true; + } + const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null; + const newTypeAttributes = { + ...getSplittedAttributes(extensionAttributes, grandParent.type.name, grandParent.attrs), + ...overrideAttrs + }; + const newNextTypeAttributes = { + ...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs), + ...overrideAttrs + }; + tr2.delete($from.pos, $to.pos); + const types = nextType ? [ + { type, attrs: newTypeAttributes }, + { type: nextType, attrs: newNextTypeAttributes } + ] : [{ type, attrs: newTypeAttributes }]; + if (!canSplit(tr2.doc, $from.pos, 2)) { + return false; + } + if (dispatch) { + const { selection, storedMarks } = state; + const { splittableMarks } = editor.extensionManager; + const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks(); + tr2.split($from.pos, 2, types).scrollIntoView(); + if (!marks || !dispatch) { + return true; + } + const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name)); + tr2.ensureMarks(filteredMarks); + } + return true; +}; +var joinListBackwards = (tr2, listType) => { + const list = findParentNode((node) => node.type === listType)(tr2.selection); + if (!list) { + return true; + } + const before = tr2.doc.resolve(Math.max(0, list.pos - 1)).before(list.depth); + if (before === void 0) { + return true; + } + const nodeBefore = tr2.doc.nodeAt(before); + const canJoinBackwards = list.node.type === (nodeBefore == null ? void 0 : nodeBefore.type) && canJoin(tr2.doc, list.pos); + if (!canJoinBackwards) { + return true; + } + tr2.join(list.pos); + return true; +}; +var joinListForwards = (tr2, listType) => { + const list = findParentNode((node) => node.type === listType)(tr2.selection); + if (!list) { + return true; + } + const after = tr2.doc.resolve(list.start).after(list.depth); + if (after === void 0) { + return true; + } + const nodeAfter = tr2.doc.nodeAt(after); + const canJoinForwards = list.node.type === (nodeAfter == null ? void 0 : nodeAfter.type) && canJoin(tr2.doc, after); + if (!canJoinForwards) { + return true; + } + tr2.join(after); + return true; +}; +function createInnerSelectionForWholeDocList(tr2) { + const doc4 = tr2.doc; + const list = doc4.firstChild; + if (!list) { + return null; + } + const $start = doc4.resolve(1); + const $end = doc4.resolve(list.nodeSize - 1); + return TextSelection.between($start, $end); +} +var toggleList = (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) => ({ editor, tr: tr2, state, dispatch, chain, commands, can }) => { + const { extensions, splittableMarks } = editor.extensionManager; + const listType = getNodeType(listTypeOrName, state.schema); + const itemType = getNodeType(itemTypeOrName, state.schema); + const { selection, storedMarks } = state; + const { $from, $to } = selection; + const range = $from.blockRange($to); + const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks(); + if (!range) { + return false; + } + const parentList = findParentNode((node) => isList(node.type.name, extensions))(selection); + const isAllSelection = selection.from === 0 && selection.to === state.doc.content.size; + const topLevelNodes = state.doc.content.content; + const soleTopLevelNode = topLevelNodes.length === 1 ? topLevelNodes[0] : null; + const allSelectionList = isAllSelection && soleTopLevelNode && isList(soleTopLevelNode.type.name, extensions) ? { + node: soleTopLevelNode, + pos: 0, + depth: 0 + } : null; + const currentList = parentList != null ? parentList : allSelectionList; + const isInsideExistingList = !!parentList && range.depth >= 1 && range.depth - parentList.depth <= 1; + const hasWholeDocSelectedList = !!allSelectionList; + if ((isInsideExistingList || hasWholeDocSelectedList) && currentList) { + if (currentList.node.type === listType) { + if (isAllSelection && hasWholeDocSelectedList) { + return chain().command(({ tr: trx, dispatch: disp }) => { + const nextSelection = createInnerSelectionForWholeDocList(trx); + if (!nextSelection) { + return false; + } + trx.setSelection(nextSelection); + if (disp) { + disp(trx); + } + return true; + }).liftListItem(itemType).run(); + } + return commands.liftListItem(itemType); + } + if (isList(currentList.node.type.name, extensions) && listType.validContent(currentList.node.content)) { + return chain().command(() => { + tr2.setNodeMarkup(currentList.pos, listType); + return true; + }).command(() => joinListBackwards(tr2, listType)).command(() => joinListForwards(tr2, listType)).run(); + } + } + if (!keepMarks || !marks || !dispatch) { + return chain().command(() => { + const canWrapInList = can().wrapInList(listType, attributes); + if (canWrapInList) { + return true; + } + return commands.clearNodes(); + }).wrapInList(listType, attributes).command(() => joinListBackwards(tr2, listType)).command(() => joinListForwards(tr2, listType)).run(); + } + return chain().command(() => { + const canWrapInList = can().wrapInList(listType, attributes); + const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name)); + tr2.ensureMarks(filteredMarks); + if (canWrapInList) { + return true; + } + return commands.clearNodes(); + }).wrapInList(listType, attributes).command(() => joinListBackwards(tr2, listType)).command(() => joinListForwards(tr2, listType)).run(); +}; +var toggleMark = (typeOrName, attributes = {}, options = {}) => ({ state, commands }) => { + const { extendEmptyMarkRange = false } = options; + const type = getMarkType(typeOrName, state.schema); + const isActive2 = isMarkActive(state, type, attributes); + if (isActive2) { + return commands.unsetMark(type, { extendEmptyMarkRange }); + } + return commands.setMark(type, attributes); +}; +var toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state, commands }) => { + const type = getNodeType(typeOrName, state.schema); + const toggleType = getNodeType(toggleTypeOrName, state.schema); + const isActive2 = isNodeActive(state, type, attributes); + let attributesToCopy; + if (state.selection.$anchor.sameParent(state.selection.$head)) { + attributesToCopy = state.selection.$anchor.parent.attrs; + } + if (isActive2) { + return commands.setNode(toggleType, attributesToCopy); + } + return commands.setNode(type, { ...attributesToCopy, ...attributes }); +}; +var toggleWrap = (typeOrName, attributes = {}) => ({ state, commands }) => { + const type = getNodeType(typeOrName, state.schema); + const isActive2 = isNodeActive(state, type, attributes); + if (isActive2) { + return commands.lift(type); + } + return commands.wrapIn(type, attributes); +}; +var undoInputRule = () => ({ state, dispatch }) => { + const plugins = state.plugins; + for (let i = 0; i < plugins.length; i += 1) { + const plugin = plugins[i]; + let undoable; + if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) { + if (dispatch) { + const tr2 = state.tr; + const toUndo = undoable.transform; + for (let j2 = toUndo.steps.length - 1; j2 >= 0; j2 -= 1) { + tr2.step(toUndo.steps[j2].invert(toUndo.docs[j2])); + } + if (undoable.text) { + const marks = tr2.doc.resolve(undoable.from).marks(); + tr2.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks)); + } else { + tr2.delete(undoable.from, undoable.to); + } + } + return true; + } + } + return false; +}; +var unsetAllMarks = (options = {}) => ({ tr: tr2, dispatch, editor }) => { + const { ignoreClearable = false } = options; + const { selection } = tr2; + const { empty: empty2, ranges } = selection; + if (empty2) { + return true; + } + const { nonClearableMarks } = editor.extensionManager; + if (dispatch) { + const clearableMarkTypes = Object.values(editor.schema.marks).filter( + (markType) => ignoreClearable || !nonClearableMarks.includes(markType.name) + ); + ranges.forEach((range) => { + for (const markType of clearableMarkTypes) { + tr2.removeMark(range.$from.pos, range.$to.pos, markType); + } + }); + } + return true; +}; +var unsetMark = (typeOrName, options = {}) => ({ tr: tr2, state, dispatch }) => { + var _a; + const { extendEmptyMarkRange = false } = options; + const { selection } = tr2; + const type = getMarkType(typeOrName, state.schema); + const { $from, empty: empty2, ranges } = selection; + if (!dispatch) { + return true; + } + if (empty2 && extendEmptyMarkRange) { + let { from: from3, to } = selection; + const attrs = (_a = $from.marks().find((mark) => mark.type === type)) == null ? void 0 : _a.attrs; + const range = getMarkRange($from, type, attrs); + if (range) { + from3 = range.from; + to = range.to; + } + tr2.removeMark(from3, to, type); + } else { + ranges.forEach((range) => { + tr2.removeMark(range.$from.pos, range.$to.pos, type); + }); + } + tr2.removeStoredMark(type); + return true; +}; +var unsetTextDirection = (position) => ({ tr: tr2, state, dispatch }) => { + const { selection } = state; + let from3; + let to; + if (typeof position === "number") { + from3 = position; + to = position; + } else if (position && "from" in position && "to" in position) { + from3 = position.from; + to = position.to; + } else { + from3 = selection.from; + to = selection.to; + } + if (dispatch) { + tr2.doc.nodesBetween(from3, to, (node, pos) => { + if (node.isText) { + return; + } + const newAttrs = { ...node.attrs }; + delete newAttrs.dir; + tr2.setNodeMarkup(pos, void 0, newAttrs); + }); + } + return true; +}; +var updateAttributes = (typeOrName, attributes = {}) => ({ tr: tr2, state, dispatch }) => { + let nodeType = null; + let markType = null; + const schemaType = getSchemaTypeNameByName( + typeof typeOrName === "string" ? typeOrName : typeOrName.name, + state.schema + ); + if (!schemaType) { + return false; + } + if (schemaType === "node") { + nodeType = getNodeType(typeOrName, state.schema); + } + if (schemaType === "mark") { + markType = getMarkType(typeOrName, state.schema); + } + let canUpdate = false; + tr2.selection.ranges.forEach((range) => { + const from3 = range.$from.pos; + const to = range.$to.pos; + let lastPos; + let lastNode; + let trimmedFrom; + let trimmedTo; + if (tr2.selection.empty) { + state.doc.nodesBetween(from3, to, (node, pos) => { + if (nodeType && nodeType === node.type) { + canUpdate = true; + trimmedFrom = Math.max(pos, from3); + trimmedTo = Math.min(pos + node.nodeSize, to); + lastPos = pos; + lastNode = node; + } + }); + } else { + state.doc.nodesBetween(from3, to, (node, pos) => { + if (pos < from3 && nodeType && nodeType === node.type) { + canUpdate = true; + trimmedFrom = Math.max(pos, from3); + trimmedTo = Math.min(pos + node.nodeSize, to); + lastPos = pos; + lastNode = node; + } + if (pos >= from3 && pos <= to) { + if (nodeType && nodeType === node.type) { + canUpdate = true; + if (dispatch) { + tr2.setNodeMarkup(pos, void 0, { + ...node.attrs, + ...attributes + }); + } + } + if (markType && node.marks.length) { + node.marks.forEach((mark) => { + if (markType === mark.type) { + canUpdate = true; + if (dispatch) { + const trimmedFrom2 = Math.max(pos, from3); + const trimmedTo2 = Math.min(pos + node.nodeSize, to); + tr2.addMark( + trimmedFrom2, + trimmedTo2, + markType.create({ + ...mark.attrs, + ...attributes + }) + ); + } + } + }); + } + } + }); + } + if (lastNode) { + if (lastPos !== void 0 && dispatch) { + tr2.setNodeMarkup(lastPos, void 0, { + ...lastNode.attrs, + ...attributes + }); + } + if (markType && lastNode.marks.length) { + lastNode.marks.forEach((mark) => { + if (markType === mark.type && dispatch) { + tr2.addMark( + trimmedFrom, + trimmedTo, + markType.create({ + ...mark.attrs, + ...attributes + }) + ); + } + }); + } + } + }); + return canUpdate; +}; +var wrapIn2 = (typeOrName, attributes = {}) => ({ state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + return wrapIn(type, attributes)(state, dispatch); +}; +var wrapInList2 = (typeOrName, attributes = {}) => ({ state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + return wrapInList(type, attributes)(state, dispatch); +}; +var EventEmitter = class { + constructor() { + this.callbacks = {}; + } + on(event, fn) { + if (!this.callbacks[event]) { + this.callbacks[event] = []; + } + this.callbacks[event].push(fn); + return this; + } + emit(event, ...args2) { + const callbacks = this.callbacks[event]; + if (callbacks) { + callbacks.forEach((callback) => callback.apply(this, args2)); + } + return this; + } + off(event, fn) { + const callbacks = this.callbacks[event]; + if (callbacks) { + if (fn) { + this.callbacks[event] = callbacks.filter((callback) => callback !== fn); + } else { + delete this.callbacks[event]; + } + } + return this; + } + once(event, fn) { + const onceFn = (...args2) => { + this.off(event, onceFn); + fn.apply(this, args2); + }; + return this.on(event, onceFn); + } + removeAllListeners() { + this.callbacks = {}; + } +}; +var InputRule = class { + constructor(config) { + var _a; + this.find = config.find; + this.handler = config.handler; + this.undoable = (_a = config.undoable) != null ? _a : true; + } +}; +var inputRuleMatcherHandler = (text2, find3) => { + if (isRegExp(find3)) { + return find3.exec(text2); + } + const inputRuleMatch = find3(text2); + if (!inputRuleMatch) { + return null; + } + const result = [inputRuleMatch.text]; + result.index = inputRuleMatch.index; + result.input = text2; + result.data = inputRuleMatch.data; + if (inputRuleMatch.replaceWith) { + if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) { + console.warn( + '[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".' + ); + } + result.push(inputRuleMatch.replaceWith); + } + return result; +}; +function run(config) { + var _a; + const { editor, from: from3, to, text: text2, rules: rules3, plugin } = config; + const { view } = editor; + if (view.composing) { + return false; + } + const $from = view.state.doc.resolve(from3); + if ( + // check for code node + $from.parent.type.spec.code || // check for code mark + !!((_a = $from.nodeBefore || $from.nodeAfter) == null ? void 0 : _a.marks.find((mark) => mark.type.spec.code)) + ) { + return false; + } + let matched = false; + const textBefore = getTextContentFromNodes($from) + text2; + rules3.forEach((rule) => { + if (matched) { + return; + } + const match2 = inputRuleMatcherHandler(textBefore, rule.find); + if (!match2) { + return; + } + const tr2 = view.state.tr; + const state = createChainableState({ + state: view.state, + transaction: tr2 + }); + const range = { + from: from3 - (match2[0].length - text2.length), + to + }; + const { commands, chain, can } = new CommandManager({ + editor, + state + }); + const handler = rule.handler({ + state, + range, + match: match2, + commands, + chain, + can + }); + if (handler === null || !tr2.steps.length) { + return; + } + if (rule.undoable) { + tr2.setMeta(plugin, { + transform: tr2, + from: from3, + to, + text: text2 + }); + } + view.dispatch(tr2); + matched = true; + }); + return matched; +} +function inputRulesPlugin(props) { + const { editor, rules: rules3 } = props; + const plugin = new Plugin({ + state: { + init() { + return null; + }, + apply(tr2, prev, state) { + const stored = tr2.getMeta(plugin); + if (stored) { + return stored; + } + const simulatedInputMeta = tr2.getMeta("applyInputRules"); + const isSimulatedInput = !!simulatedInputMeta; + if (isSimulatedInput) { + setTimeout(() => { + let { text: text2 } = simulatedInputMeta; + if (typeof text2 === "string") { + text2 = text2; + } else { + text2 = getHTMLFromFragment(Fragment.from(text2), state.schema); + } + const { from: from3 } = simulatedInputMeta; + const to = from3 + text2.length; + run({ + editor, + from: from3, + to, + text: text2, + rules: rules3, + plugin + }); + }); + } + return tr2.selectionSet || tr2.docChanged ? null : prev; + } + }, + props: { + handleTextInput(view, from3, to, text2) { + return run({ + editor, + from: from3, + to, + text: text2, + rules: rules3, + plugin + }); + }, + handleDOMEvents: { + compositionend: (view) => { + setTimeout(() => { + const { $cursor } = view.state.selection; + if ($cursor) { + run({ + editor, + from: $cursor.pos, + to: $cursor.pos, + text: "", + rules: rules3, + plugin + }); + } + }); + return false; + } + }, + // add support for input rules to trigger on enter + // this is useful for example for code blocks + handleKeyDown(view, event) { + if (event.key !== "Enter") { + return false; + } + const { $cursor } = view.state.selection; + if ($cursor) { + return run({ + editor, + from: $cursor.pos, + to: $cursor.pos, + text: "\n", + rules: rules3, + plugin + }); + } + return false; + } + }, + // @ts-ignore + isInputRules: true + }); + return plugin; +} +function getType(value) { + return Object.prototype.toString.call(value).slice(8, -1); +} +function isPlainObject(value) { + if (getType(value) !== "Object") { + return false; + } + return value.constructor === Object && Object.getPrototypeOf(value) === Object.prototype; +} +function mergeDeep(target, source) { + const output = { ...target }; + if (isPlainObject(target) && isPlainObject(source)) { + Object.keys(source).forEach((key) => { + if (isPlainObject(source[key]) && isPlainObject(target[key])) { + output[key] = mergeDeep(target[key], source[key]); + } else { + output[key] = source[key]; + } + }); + } + return output; +} +var Extendable = class { + constructor(config = {}) { + this.type = "extendable"; + this.parent = null; + this.child = null; + this.name = ""; + this.config = { + name: this.name + }; + this.config = { + ...this.config, + ...config + }; + this.name = this.config.name; + } + get options() { + return { + ...callOrReturn( + getExtensionField(this, "addOptions", { + name: this.name + }) + ) + }; + } + get storage() { + return { + ...callOrReturn( + getExtensionField(this, "addStorage", { + name: this.name, + options: this.options + }) + ) + }; + } + configure(options = {}) { + const extension = this.extend({ + ...this.config, + addOptions: () => { + return mergeDeep(this.options, options); + } + }); + extension.name = this.name; + extension.parent = this.parent; + this.child = null; + return extension; + } + extend(extendedConfig = {}) { + const extension = new this.constructor({ ...this.config, ...extendedConfig }); + extension.parent = this; + this.child = extension; + extension.name = "name" in extendedConfig ? extendedConfig.name : extension.parent.name; + return extension; + } +}; +var Mark2 = class _Mark extends Extendable { + constructor() { + super(...arguments); + this.type = "mark"; + } + /** + * Create a new Mark instance + * @param config - Mark configuration object or a function that returns a configuration object + */ + static create(config = {}) { + const resolvedConfig = typeof config === "function" ? config() : config; + return new _Mark(resolvedConfig); + } + static handleExit({ editor, mark }) { + const { tr: tr2 } = editor.state; + const currentPos = editor.state.selection.$from; + const isAtEnd = currentPos.pos === currentPos.end(); + if (isAtEnd) { + const currentMarks = currentPos.marks(); + const isInMark = !!currentMarks.find((m2) => (m2 == null ? void 0 : m2.type.name) === mark.name); + if (!isInMark) { + return false; + } + const removeMark2 = currentMarks.find((m2) => (m2 == null ? void 0 : m2.type.name) === mark.name); + if (removeMark2) { + tr2.removeStoredMark(removeMark2); + } + tr2.insertText(" ", currentPos.pos); + editor.view.dispatch(tr2); + return true; + } + return false; + } + configure(options) { + return super.configure(options); + } + extend(extendedConfig) { + const resolvedConfig = typeof extendedConfig === "function" ? extendedConfig() : extendedConfig; + return super.extend(resolvedConfig); + } +}; +function isNumber(value) { + return typeof value === "number"; +} +var PasteRule = class { + constructor(config) { + this.find = config.find; + this.handler = config.handler; + } +}; +var pasteRuleMatcherHandler = (text2, find3, event) => { + if (isRegExp(find3)) { + return [...text2.matchAll(find3)]; + } + const matches2 = find3(text2, event); + if (!matches2) { + return []; + } + return matches2.map((pasteRuleMatch) => { + const result = [pasteRuleMatch.text]; + result.index = pasteRuleMatch.index; + result.input = text2; + result.data = pasteRuleMatch.data; + if (pasteRuleMatch.replaceWith) { + if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) { + console.warn( + '[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".' + ); + } + result.push(pasteRuleMatch.replaceWith); + } + return result; + }); +}; +function run2(config) { + const { editor, state, from: from3, to, rule, pasteEvent, dropEvent } = config; + const { commands, chain, can } = new CommandManager({ + editor, + state + }); + const handlers2 = []; + state.doc.nodesBetween(from3, to, (node, pos) => { + var _a, _b, _c, _d, _e2; + if (((_b = (_a = node.type) == null ? void 0 : _a.spec) == null ? void 0 : _b.code) || !(node.isText || node.isTextblock || node.isInline)) { + return; + } + const contentSize = (_e2 = (_d = (_c = node.content) == null ? void 0 : _c.size) != null ? _d : node.nodeSize) != null ? _e2 : 0; + const resolvedFrom = Math.max(from3, pos); + const resolvedTo = Math.min(to, pos + contentSize); + if (resolvedFrom >= resolvedTo) { + return; + } + const textToMatch = node.isText ? node.text || "" : node.textBetween(resolvedFrom - pos, resolvedTo - pos, void 0, "\uFFFC"); + const matches2 = pasteRuleMatcherHandler(textToMatch, rule.find, pasteEvent); + matches2.forEach((match2) => { + if (match2.index === void 0) { + return; + } + const start = resolvedFrom + match2.index + 1; + const end = start + match2[0].length; + const range = { + from: state.tr.mapping.map(start), + to: state.tr.mapping.map(end) + }; + const handler = rule.handler({ + state, + range, + match: match2, + commands, + chain, + can, + pasteEvent, + dropEvent + }); + handlers2.push(handler); + }); + }); + const success = handlers2.every((handler) => handler !== null); + return success; +} +var tiptapDragFromOtherEditor = null; +var createClipboardPasteEvent = (text2) => { + var _a; + const event = new ClipboardEvent("paste", { + clipboardData: new DataTransfer() + }); + (_a = event.clipboardData) == null ? void 0 : _a.setData("text/html", text2); + return event; +}; +function pasteRulesPlugin(props) { + const { editor, rules: rules3 } = props; + let dragSourceElement = null; + let isPastedFromProseMirror = false; + let isDroppedFromProseMirror = false; + let pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null; + let dropEvent; + try { + dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null; + } catch { + dropEvent = null; + } + const processEvent = ({ + state, + from: from3, + to, + rule, + pasteEvt + }) => { + const tr2 = state.tr; + const chainableState = createChainableState({ + state, + transaction: tr2 + }); + const handler = run2({ + editor, + state: chainableState, + from: Math.max(from3 - 1, 0), + to: to.b - 1, + rule, + pasteEvent: pasteEvt, + dropEvent + }); + if (!handler || !tr2.steps.length) { + return; + } + try { + dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null; + } catch { + dropEvent = null; + } + pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null; + return tr2; + }; + const plugins = rules3.map((rule) => { + return new Plugin({ + // we register a global drag handler to track the current drag source element + view(view) { + const handleDragstart = (event) => { + var _a; + dragSourceElement = ((_a = view.dom.parentElement) == null ? void 0 : _a.contains(event.target)) ? view.dom.parentElement : null; + if (dragSourceElement) { + tiptapDragFromOtherEditor = editor; + } + }; + const handleDragend = () => { + if (tiptapDragFromOtherEditor) { + tiptapDragFromOtherEditor = null; + } + }; + window.addEventListener("dragstart", handleDragstart); + window.addEventListener("dragend", handleDragend); + return { + destroy() { + window.removeEventListener("dragstart", handleDragstart); + window.removeEventListener("dragend", handleDragend); + } + }; + }, + props: { + handleDOMEvents: { + drop: (view, event) => { + isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement; + dropEvent = event; + if (!isDroppedFromProseMirror) { + const dragFromOtherEditor = tiptapDragFromOtherEditor; + if (dragFromOtherEditor == null ? void 0 : dragFromOtherEditor.isEditable) { + setTimeout(() => { + const selection = dragFromOtherEditor.state.selection; + if (selection) { + dragFromOtherEditor.commands.deleteRange({ + from: selection.from, + to: selection.to + }); + } + }, 10); + } + } + return false; + }, + paste: (_view, event) => { + var _a; + const html = (_a = event.clipboardData) == null ? void 0 : _a.getData("text/html"); + pasteEvent = event; + isPastedFromProseMirror = !!(html == null ? void 0 : html.includes("data-pm-slice")); + return false; + } + } + }, + appendTransaction: (transactions, oldState, state) => { + const transaction = transactions[0]; + const isPaste = transaction.getMeta("uiEvent") === "paste" && !isPastedFromProseMirror; + const isDrop = transaction.getMeta("uiEvent") === "drop" && !isDroppedFromProseMirror; + const simulatedPasteMeta = transaction.getMeta("applyPasteRules"); + const isSimulatedPaste = !!simulatedPasteMeta; + if (!isPaste && !isDrop && !isSimulatedPaste) { + return; + } + if (isSimulatedPaste) { + let { text: text2 } = simulatedPasteMeta; + if (typeof text2 === "string") { + text2 = text2; + } else { + text2 = getHTMLFromFragment(Fragment.from(text2), state.schema); + } + const { from: from22 } = simulatedPasteMeta; + const to2 = from22 + text2.length; + const pasteEvt = createClipboardPasteEvent(text2); + return processEvent({ + rule, + state, + from: from22, + to: { b: to2 }, + pasteEvt + }); + } + const from3 = oldState.doc.content.findDiffStart(state.doc.content); + const to = oldState.doc.content.findDiffEnd(state.doc.content); + if (!isNumber(from3) || !to || from3 === to.b) { + return; + } + return processEvent({ + rule, + state, + from: from3, + to, + pasteEvt: pasteEvent + }); + } + }); + }); + return plugins; +} +var ExtensionManager = class { + constructor(extensions, editor) { + this.splittableMarks = []; + this.nonClearableMarks = []; + this.editor = editor; + this.baseExtensions = extensions; + this.extensions = resolveExtensions(extensions); + this.schema = getSchemaByResolvedExtensions(this.extensions, editor); + this.setupExtensions(); + } + /** + * Get all commands from the extensions. + * @returns An object with all commands where the key is the command name and the value is the command function + */ + get commands() { + return this.extensions.reduce((commands, extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: this.editor.extensionStorage[extension.name], + editor: this.editor, + type: getSchemaTypeByName(extension.name, this.schema) + }; + const addCommands = getExtensionField( + extension, + "addCommands", + context + ); + if (!addCommands) { + return commands; + } + return { + ...commands, + ...addCommands() + }; + }, {}); + } + /** + * Get all registered Prosemirror plugins from the extensions. + * @returns An array of Prosemirror plugins + */ + get plugins() { + const { editor } = this; + const extensions = sortExtensions([...this.extensions].reverse()); + const allPlugins = extensions.flatMap((extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: this.editor.extensionStorage[extension.name], + editor, + type: getSchemaTypeByName(extension.name, this.schema) + }; + const plugins = []; + const addKeyboardShortcuts = getExtensionField( + extension, + "addKeyboardShortcuts", + context + ); + let defaultBindings = {}; + if (extension.type === "mark" && getExtensionField(extension, "exitable", context)) { + defaultBindings.ArrowRight = () => Mark2.handleExit({ editor, mark: extension }); + } + if (addKeyboardShortcuts) { + const bindings = Object.fromEntries( + Object.entries(addKeyboardShortcuts()).map(([shortcut, method]) => { + return [shortcut, () => method({ editor })]; + }) + ); + defaultBindings = { ...defaultBindings, ...bindings }; + } + const keyMapPlugin = keymap(defaultBindings); + plugins.push(keyMapPlugin); + const addInputRules = getExtensionField( + extension, + "addInputRules", + context + ); + if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) { + const rules3 = addInputRules(); + if (rules3 && rules3.length) { + const inputResult = inputRulesPlugin({ + editor, + rules: rules3 + }); + const inputPlugins = Array.isArray(inputResult) ? inputResult : [inputResult]; + plugins.push(...inputPlugins); + } + } + const addPasteRules = getExtensionField( + extension, + "addPasteRules", + context + ); + if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) { + const rules3 = addPasteRules(); + if (rules3 && rules3.length) { + const pasteRules = pasteRulesPlugin({ editor, rules: rules3 }); + plugins.push(...pasteRules); + } + } + const addProseMirrorPlugins = getExtensionField( + extension, + "addProseMirrorPlugins", + context + ); + if (addProseMirrorPlugins) { + const proseMirrorPlugins = addProseMirrorPlugins(); + plugins.push(...proseMirrorPlugins); + } + return plugins; + }); + return allPlugins; + } + /** + * Get all attributes from the extensions. + * @returns An array of attributes + */ + get attributes() { + return getAttributesFromExtensions(this.extensions); + } + /** + * Get all node views from the extensions. + * @returns An object with all node views where the key is the node name and the value is the node view function + */ + get nodeViews() { + const { editor } = this; + const { nodeExtensions } = splitExtensions(this.extensions); + return Object.fromEntries( + nodeExtensions.filter((extension) => !!getExtensionField(extension, "addNodeView")).map((extension) => { + const extensionAttributes = this.attributes.filter( + (attribute) => attribute.type === extension.name + ); + const context = { + name: extension.name, + options: extension.options, + storage: this.editor.extensionStorage[extension.name], + editor, + type: getNodeType(extension.name, this.schema) + }; + const addNodeView = getExtensionField( + extension, + "addNodeView", + context + ); + if (!addNodeView) { + return []; + } + const nodeViewResult = addNodeView(); + if (!nodeViewResult) { + return []; + } + const nodeview = (node, view, getPos, decorations, innerDecorations) => { + const HTMLAttributes = getRenderedAttributes(node, extensionAttributes); + return nodeViewResult({ + // pass-through + node, + view, + getPos, + decorations, + innerDecorations, + // tiptap-specific + editor, + extension, + HTMLAttributes + }); + }; + return [extension.name, nodeview]; + }) + ); + } + /** + * Get the composed dispatchTransaction function from all extensions. + * @param baseDispatch The base dispatch function (e.g. from the editor or user props) + * @returns A composed dispatch function + */ + dispatchTransaction(baseDispatch) { + const { editor } = this; + const extensions = sortExtensions([...this.extensions].reverse()); + return extensions.reduceRight((next2, extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: this.editor.extensionStorage[extension.name], + editor, + type: getSchemaTypeByName(extension.name, this.schema) + }; + const dispatchTransaction = getExtensionField( + extension, + "dispatchTransaction", + context + ); + if (!dispatchTransaction) { + return next2; + } + return (transaction) => { + dispatchTransaction.call(context, { transaction, next: next2 }); + }; + }, baseDispatch); + } + /** + * Get the composed transformPastedHTML function from all extensions. + * @param baseTransform The base transform function (e.g. from the editor props) + * @returns A composed transform function that chains all extension transforms + */ + transformPastedHTML(baseTransform) { + const { editor } = this; + const extensions = sortExtensions([...this.extensions]); + return extensions.reduce( + (transform, extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: this.editor.extensionStorage[extension.name], + editor, + type: getSchemaTypeByName(extension.name, this.schema) + }; + const extensionTransform = getExtensionField( + extension, + "transformPastedHTML", + context + ); + if (!extensionTransform) { + return transform; + } + return (html, view) => { + const transformedHtml = transform(html, view); + return extensionTransform.call(context, transformedHtml); + }; + }, + baseTransform || ((html) => html) + ); + } + get markViews() { + const { editor } = this; + const { markExtensions } = splitExtensions(this.extensions); + return Object.fromEntries( + markExtensions.filter((extension) => !!getExtensionField(extension, "addMarkView")).map((extension) => { + const extensionAttributes = this.attributes.filter( + (attribute) => attribute.type === extension.name + ); + const context = { + name: extension.name, + options: extension.options, + storage: this.editor.extensionStorage[extension.name], + editor, + type: getMarkType(extension.name, this.schema) + }; + const addMarkView = getExtensionField( + extension, + "addMarkView", + context + ); + if (!addMarkView) { + return []; + } + const markView = (mark, view, inline) => { + const HTMLAttributes = getRenderedAttributes(mark, extensionAttributes); + return addMarkView()({ + // pass-through + mark, + view, + inline, + // tiptap-specific + editor, + extension, + HTMLAttributes, + updateAttributes: (attrs) => { + updateMarkViewAttributes(mark, editor, attrs); + } + }); + }; + return [extension.name, markView]; + }) + ); + } + /** + * Destroy the extension manager and clean up all extension references + * to prevent memory leaks through parent/child extension chains. + * + * Walks each extension's full parent chain and nulls every forward + * `parent.child → current` link where the parent still points to the + * current node. This breaks the retention path from module-scope + * singleton roots through deep extend() chains. + * + * Only ancestor `.child` links matching the current chain are cleared. + * The `.parent` pointer on ancestors is never touched — extensions + * may be shared across live editors, so their own backward references + * and non-matching forward links must remain intact. + */ + destroy() { + this.extensions.forEach((extension) => { + let current = extension; + while (current.parent) { + const parent = current.parent; + if (parent.child === current) { + parent.child = null; + } + current = parent; + } + }); + this.extensions = []; + this.baseExtensions = []; + this.schema = null; + this.editor = null; + } + /** + * Go through all extensions, create extension storages & setup marks + * & bind editor event listener. + */ + setupExtensions() { + const extensions = this.extensions; + this.editor.extensionStorage = Object.fromEntries( + extensions.map((extension) => [extension.name, extension.storage]) + ); + extensions.forEach((extension) => { + var _a, _b; + const context = { + name: extension.name, + options: extension.options, + storage: this.editor.extensionStorage[extension.name], + editor: this.editor, + type: getSchemaTypeByName(extension.name, this.schema) + }; + if (extension.type === "mark") { + const keepOnSplit = (_a = callOrReturn(getExtensionField(extension, "keepOnSplit", context))) != null ? _a : true; + if (keepOnSplit) { + this.splittableMarks.push(extension.name); + } + const clearable = (_b = callOrReturn( + getExtensionField(extension, "clearable", context) + )) != null ? _b : true; + if (!clearable) { + this.nonClearableMarks.push(extension.name); + } + } + const onBeforeCreate = getExtensionField( + extension, + "onBeforeCreate", + context + ); + const onCreate = getExtensionField(extension, "onCreate", context); + const onUpdate = getExtensionField(extension, "onUpdate", context); + const onSelectionUpdate = getExtensionField( + extension, + "onSelectionUpdate", + context + ); + const onTransaction = getExtensionField( + extension, + "onTransaction", + context + ); + const onFocus = getExtensionField(extension, "onFocus", context); + const onBlur = getExtensionField(extension, "onBlur", context); + const onDestroy = getExtensionField(extension, "onDestroy", context); + if (onBeforeCreate) { + this.editor.on("beforeCreate", onBeforeCreate); + } + if (onCreate) { + this.editor.on("create", onCreate); + } + if (onUpdate) { + this.editor.on("update", onUpdate); + } + if (onSelectionUpdate) { + this.editor.on("selectionUpdate", onSelectionUpdate); + } + if (onTransaction) { + this.editor.on("transaction", onTransaction); + } + if (onFocus) { + this.editor.on("focus", onFocus); + } + if (onBlur) { + this.editor.on("blur", onBlur); + } + if (onDestroy) { + this.editor.on("destroy", onDestroy); + } + }); + } +}; +ExtensionManager.resolve = resolveExtensions; +ExtensionManager.sort = sortExtensions; +ExtensionManager.flatten = flattenExtensions; +var extensions_exports = {}; +__export2(extensions_exports, { + ClipboardTextSerializer: () => ClipboardTextSerializer, + Commands: () => Commands, + Delete: () => Delete, + Drop: () => Drop, + Editable: () => Editable, + FocusEvents: () => FocusEvents, + Keymap: () => Keymap, + Paste: () => Paste, + Tabindex: () => Tabindex, + TextDirection: () => TextDirection, + focusEventsPluginKey: () => focusEventsPluginKey +}); +var Extension = class _Extension extends Extendable { + constructor() { + super(...arguments); + this.type = "extension"; + } + /** + * Create a new Extension instance + * @param config - Extension configuration object or a function that returns a configuration object + */ + static create(config = {}) { + const resolvedConfig = typeof config === "function" ? config() : config; + return new _Extension(resolvedConfig); + } + configure(options) { + return super.configure(options); + } + extend(extendedConfig) { + const resolvedConfig = typeof extendedConfig === "function" ? extendedConfig() : extendedConfig; + return super.extend(resolvedConfig); + } +}; +var ClipboardTextSerializer = Extension.create({ + name: "clipboardTextSerializer", + addOptions() { + return { + blockSeparator: void 0 + }; + }, + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("clipboardTextSerializer"), + props: { + clipboardTextSerializer: () => { + const { editor } = this; + const { state, schema } = editor; + const { doc: doc4, selection } = state; + const textSerializers = getTextSerializersFromSchema(schema); + const { blockSeparator } = this.options; + const options = { + ...blockSeparator !== void 0 ? { blockSeparator } : {}, + textSerializers + }; + const sortedRanges = [...selection.ranges].sort((a, b2) => a.$from.pos - b2.$from.pos); + return sortedRanges.map( + ({ $from, $to }) => getTextBetween(doc4, { from: $from.pos, to: $to.pos }, options) + ).join(blockSeparator != null ? blockSeparator : "\n\n"); + } + } + }) + ]; + } +}); +var Commands = Extension.create({ + name: "commands", + addCommands() { + return { + ...commands_exports + }; + } +}); +var Delete = Extension.create({ + name: "delete", + onUpdate({ transaction, appendedTransactions }) { + var _a, _b, _c; + const callback = () => { + var _a2, _b2, _c2, _d; + if ((_d = (_c2 = (_b2 = (_a2 = this.editor.options.coreExtensionOptions) == null ? void 0 : _a2.delete) == null ? void 0 : _b2.filterTransaction) == null ? void 0 : _c2.call(_b2, transaction)) != null ? _d : transaction.getMeta("y-sync$")) { + return; + } + const nextTransaction = combineTransactionSteps(transaction.before, [ + transaction, + ...appendedTransactions + ]); + const changes = getChangedRanges(nextTransaction); + changes.forEach((change) => { + if (nextTransaction.mapping.mapResult(change.oldRange.from).deletedAfter && nextTransaction.mapping.mapResult(change.oldRange.to).deletedBefore) { + nextTransaction.before.nodesBetween( + change.oldRange.from, + change.oldRange.to, + (node, from3) => { + const to = from3 + node.nodeSize - 2; + const isFullyWithinRange = change.oldRange.from <= from3 && to <= change.oldRange.to; + this.editor.emit("delete", { + type: "node", + node, + from: from3, + to, + newFrom: nextTransaction.mapping.map(from3), + newTo: nextTransaction.mapping.map(to), + deletedRange: change.oldRange, + newRange: change.newRange, + partial: !isFullyWithinRange, + editor: this.editor, + transaction, + combinedTransform: nextTransaction + }); + } + ); + } + }); + const mapping = nextTransaction.mapping; + nextTransaction.steps.forEach((step, index) => { + var _a3, _b3; + if (step instanceof RemoveMarkStep) { + const newStart = mapping.slice(index).map(step.from, -1); + const newEnd = mapping.slice(index).map(step.to); + const oldStart = mapping.invert().map(newStart, -1); + const oldEnd = mapping.invert().map(newEnd); + const foundBeforeMark = newStart > 0 ? (_a3 = nextTransaction.doc.nodeAt(newStart - 1)) == null ? void 0 : _a3.marks.some((mark) => mark.eq(step.mark)) : false; + const foundAfterMark = (_b3 = nextTransaction.doc.nodeAt(newEnd)) == null ? void 0 : _b3.marks.some((mark) => mark.eq(step.mark)); + this.editor.emit("delete", { + type: "mark", + mark: step.mark, + from: step.from, + to: step.to, + deletedRange: { + from: oldStart, + to: oldEnd + }, + newRange: { + from: newStart, + to: newEnd + }, + partial: Boolean(foundAfterMark || foundBeforeMark), + editor: this.editor, + transaction, + combinedTransform: nextTransaction + }); + } + }); + }; + if ((_c = (_b = (_a = this.editor.options.coreExtensionOptions) == null ? void 0 : _a.delete) == null ? void 0 : _b.async) != null ? _c : true) { + setTimeout(callback, 0); + } else { + callback(); + } + } +}); +var Drop = Extension.create({ + name: "drop", + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("tiptapDrop"), + props: { + handleDrop: (_2, e, slice2, moved) => { + this.editor.emit("drop", { + editor: this.editor, + event: e, + slice: slice2, + moved + }); + } + } + }) + ]; + } +}); +var Editable = Extension.create({ + name: "editable", + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("editable"), + props: { + editable: () => this.editor.options.editable + } + }) + ]; + } +}); +var focusEventsPluginKey = new PluginKey("focusEvents"); +var FocusEvents = Extension.create({ + name: "focusEvents", + addProseMirrorPlugins() { + const { editor } = this; + return [ + new Plugin({ + key: focusEventsPluginKey, + props: { + handleDOMEvents: { + focus: (view, event) => { + editor.isFocused = true; + const transaction = editor.state.tr.setMeta("focus", { event }).setMeta("addToHistory", false); + view.dispatch(transaction); + return false; + }, + blur: (view, event) => { + editor.isFocused = false; + const transaction = editor.state.tr.setMeta("blur", { event }).setMeta("addToHistory", false); + view.dispatch(transaction); + return false; + } + } + } + }) + ]; + } +}); +var Keymap = Extension.create({ + name: "keymap", + addKeyboardShortcuts() { + const handleBackspace3 = () => this.editor.commands.first(({ commands }) => [ + () => commands.undoInputRule(), + // maybe convert first text block node to default node + () => commands.command(({ tr: tr2 }) => { + const { selection, doc: doc4 } = tr2; + const { empty: empty2, $anchor } = selection; + const { pos, parent } = $anchor; + const $parentPos = $anchor.parent.isTextblock && pos > 0 ? tr2.doc.resolve(pos - 1) : $anchor; + const parentIsIsolating = $parentPos.parent.type.spec.isolating; + const parentPos = $anchor.pos - $anchor.parentOffset; + const isAtStart = parentIsIsolating && $parentPos.parent.childCount === 1 ? parentPos === $anchor.pos : Selection.atStart(doc4).from === pos; + if (!empty2 || !parent.type.isTextblock || parent.textContent.length || !isAtStart || isAtStart && $anchor.parent.type.name === "paragraph") { + return false; + } + return commands.clearNodes(); + }), + () => commands.deleteSelection(), + () => commands.joinBackward(), + () => commands.selectNodeBackward() + ]); + const handleDelete2 = () => this.editor.commands.first(({ commands }) => [ + () => commands.deleteSelection(), + () => commands.deleteCurrentNode(), + () => commands.joinForward(), + () => commands.selectNodeForward() + ]); + const handleEnter = () => this.editor.commands.first(({ commands }) => [ + () => commands.newlineInCode(), + () => commands.createParagraphNear(), + () => commands.liftEmptyBlock(), + () => commands.splitBlock() + ]); + const baseKeymap = { + Enter: handleEnter, + "Mod-Enter": () => this.editor.commands.exitCode(), + Backspace: handleBackspace3, + "Mod-Backspace": handleBackspace3, + "Shift-Backspace": handleBackspace3, + Delete: handleDelete2, + "Mod-Delete": handleDelete2, + "Mod-a": () => this.editor.commands.selectAll() + }; + const pcKeymap = { + ...baseKeymap + }; + const macKeymap = { + ...baseKeymap, + "Ctrl-h": handleBackspace3, + "Alt-Backspace": handleBackspace3, + "Ctrl-d": handleDelete2, + "Ctrl-Alt-Backspace": handleDelete2, + "Alt-Delete": handleDelete2, + "Alt-d": handleDelete2, + "Ctrl-a": () => this.editor.commands.selectTextblockStart(), + "Ctrl-e": () => this.editor.commands.selectTextblockEnd() + }; + if (isiOS() || isMacOS()) { + return macKeymap; + } + return pcKeymap; + }, + addProseMirrorPlugins() { + return [ + // With this plugin we check if the whole document was selected and deleted. + // In this case we will additionally call `clearNodes()` to convert e.g. a heading + // to a paragraph if necessary. + // This is an alternative to ProseMirror's `AllSelection`, which doesn’t work well + // with many other commands. + new Plugin({ + key: new PluginKey("clearDocument"), + appendTransaction: (transactions, oldState, newState) => { + if (transactions.some((tr22) => tr22.getMeta("composition"))) { + return; + } + const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc); + const ignoreTr = transactions.some( + (transaction) => transaction.getMeta("preventClearDocument") + ); + if (!docChanges || ignoreTr) { + return; + } + const { empty: empty2, from: from3, to } = oldState.selection; + const allFrom = Selection.atStart(oldState.doc).from; + const allEnd = Selection.atEnd(oldState.doc).to; + const allWasSelected = from3 === allFrom && to === allEnd; + if (empty2 || !allWasSelected) { + return; + } + const isEmpty3 = isNodeEmpty(newState.doc); + if (!isEmpty3) { + return; + } + const tr2 = newState.tr; + const state = createChainableState({ + state: newState, + transaction: tr2 + }); + const { commands } = new CommandManager({ + editor: this.editor, + state + }); + commands.clearNodes(); + if (!tr2.steps.length) { + return; + } + return tr2; + } + }) + ]; + } +}); +var Paste = Extension.create({ + name: "paste", + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("tiptapPaste"), + props: { + handlePaste: (_view, e, slice2) => { + this.editor.emit("paste", { + editor: this.editor, + event: e, + slice: slice2 + }); + } + } + }) + ]; + } +}); +var Tabindex = Extension.create({ + name: "tabindex", + addOptions() { + return { + value: void 0 + }; + }, + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("tabindex"), + props: { + attributes: () => { + var _a; + if (!this.editor.isEditable && this.options.value === void 0) { + return {}; + } + return { tabindex: (_a = this.options.value) != null ? _a : "0" }; + } + } + }) + ]; + } +}); +var TextDirection = Extension.create({ + name: "textDirection", + addOptions() { + return { + direction: void 0 + }; + }, + addGlobalAttributes() { + if (!this.options.direction) { + return []; + } + const { nodeExtensions } = splitExtensions(this.extensions); + return [ + { + types: nodeExtensions.filter((extension) => extension.name !== "text").map((extension) => extension.name), + attributes: { + dir: { + default: this.options.direction, + parseHTML: (element2) => { + const dir = element2.getAttribute("dir"); + if (dir && (dir === "ltr" || dir === "rtl" || dir === "auto")) { + return dir; + } + return this.options.direction; + }, + renderHTML: (attributes) => { + if (!attributes.dir) { + return {}; + } + return { + dir: attributes.dir + }; + } + } + } + } + ]; + }, + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("textDirection"), + props: { + attributes: () => { + const direction = this.options.direction; + if (!direction) { + return {}; + } + return { + dir: direction + }; + } + } + }) + ]; + } +}); +var NodePos = class _NodePos { + constructor(pos, editor, isBlock2 = false, node = null) { + this.currentNode = null; + this.actualDepth = null; + this.isBlock = isBlock2; + this.resolvedPos = pos; + this.editor = editor; + this.currentNode = node; + } + get name() { + return this.node.type.name; + } + get node() { + return this.currentNode || this.resolvedPos.node(); + } + get element() { + return this.editor.view.domAtPos(this.pos).node; + } + get depth() { + var _a; + return (_a = this.actualDepth) != null ? _a : this.resolvedPos.depth; + } + get pos() { + return this.resolvedPos.pos; + } + get content() { + return this.node.content; + } + set content(content) { + let from3 = this.from; + let to = this.to; + if (this.isBlock) { + if (this.content.size === 0) { + console.error( + `You can\u2019t set content on a block node. Tried to set content on ${this.name} at ${this.pos}` + ); + return; + } + from3 = this.from + 1; + to = this.to - 1; + } + this.editor.commands.insertContentAt({ from: from3, to }, content); + } + get attributes() { + return this.node.attrs; + } + get textContent() { + return this.node.textContent; + } + get size() { + return this.node.nodeSize; + } + get from() { + if (this.isBlock) { + return this.pos; + } + return this.resolvedPos.start(this.resolvedPos.depth); + } + get range() { + return { + from: this.from, + to: this.to + }; + } + get to() { + if (this.isBlock) { + return this.pos + this.size; + } + return this.resolvedPos.end(this.resolvedPos.depth) + (this.node.isText ? 0 : 1); + } + get parent() { + if (this.depth === 0) { + return null; + } + const parentPos = this.resolvedPos.start(this.resolvedPos.depth - 1); + const $pos = this.resolvedPos.doc.resolve(parentPos); + return new _NodePos($pos, this.editor); + } + get before() { + let $pos = this.resolvedPos.doc.resolve(this.from - (this.isBlock ? 1 : 2)); + if ($pos.depth !== this.depth) { + $pos = this.resolvedPos.doc.resolve(this.from - 3); + } + return new _NodePos($pos, this.editor); + } + get after() { + let $pos = this.resolvedPos.doc.resolve(this.to + (this.isBlock ? 2 : 1)); + if ($pos.depth !== this.depth) { + $pos = this.resolvedPos.doc.resolve(this.to + 3); + } + return new _NodePos($pos, this.editor); + } + get children() { + const children = []; + this.node.content.forEach((node, offset) => { + const isBlock2 = node.isBlock && !node.isTextblock; + const isNonTextAtom = node.isAtom && !node.isText; + const isInline2 = node.isInline; + const targetPos = this.pos + offset + (isNonTextAtom ? 0 : 1); + if (targetPos < 0 || targetPos > this.resolvedPos.doc.nodeSize - 2) { + return; + } + const $pos = this.resolvedPos.doc.resolve(targetPos); + if (!isBlock2 && !isInline2 && $pos.depth <= this.depth) { + return; + } + const childNodePos = new _NodePos( + $pos, + this.editor, + isBlock2, + isBlock2 || isInline2 ? node : null + ); + if (isBlock2) { + childNodePos.actualDepth = this.depth + 1; + } + children.push(childNodePos); + }); + return children; + } + get firstChild() { + return this.children[0] || null; + } + get lastChild() { + const children = this.children; + return children[children.length - 1] || null; + } + closest(selector, attributes = {}) { + let node = null; + let currentNode = this.parent; + while (currentNode && !node) { + if (currentNode.node.type.name === selector) { + if (Object.keys(attributes).length > 0) { + const nodeAttributes = currentNode.node.attrs; + const attrKeys = Object.keys(attributes); + for (let index = 0; index < attrKeys.length; index += 1) { + const key = attrKeys[index]; + if (nodeAttributes[key] !== attributes[key]) { + break; + } + } + } else { + node = currentNode; + } + } + currentNode = currentNode.parent; + } + return node; + } + querySelector(selector, attributes = {}) { + return this.querySelectorAll(selector, attributes, true)[0] || null; + } + querySelectorAll(selector, attributes = {}, firstItemOnly = false) { + let nodes = []; + if (!this.children || this.children.length === 0) { + return nodes; + } + const attrKeys = Object.keys(attributes); + this.children.forEach((childPos) => { + if (firstItemOnly && nodes.length > 0) { + return; + } + if (childPos.node.type.name === selector) { + const doesAllAttributesMatch = attrKeys.every( + (key) => attributes[key] === childPos.node.attrs[key] + ); + if (doesAllAttributesMatch) { + nodes.push(childPos); + } + } + if (firstItemOnly && nodes.length > 0) { + return; + } + nodes = nodes.concat(childPos.querySelectorAll(selector, attributes, firstItemOnly)); + }); + return nodes; + } + setAttribute(attributes) { + const { tr: tr2 } = this.editor.state; + tr2.setNodeMarkup(this.from, void 0, { + ...this.node.attrs, + ...attributes + }); + this.editor.view.dispatch(tr2); + } +}; +var style = `.ProseMirror { + position: relative; +} + +.ProseMirror { + word-wrap: break-word; + white-space: pre-wrap; + white-space: break-spaces; + -webkit-font-variant-ligatures: none; + font-variant-ligatures: none; + font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */ +} + +.ProseMirror [contenteditable="false"] { + white-space: normal; +} + +.ProseMirror [contenteditable="false"] [contenteditable="true"] { + white-space: pre-wrap; +} + +.ProseMirror pre { + white-space: pre-wrap; +} + +img.ProseMirror-separator { + display: inline !important; + border: none !important; + margin: 0 !important; + width: 0 !important; + height: 0 !important; +} + +.ProseMirror-gapcursor { + display: none; + pointer-events: none; + position: absolute; + margin: 0; +} + +.ProseMirror-gapcursor:after { + content: ""; + display: block; + position: absolute; + top: -2px; + width: 20px; + border-top: 1px solid black; + animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite; +} + +@keyframes ProseMirror-cursor-blink { + to { + visibility: hidden; + } +} + +.ProseMirror-hideselection *::selection { + background: transparent; +} + +.ProseMirror-hideselection *::-moz-selection { + background: transparent; +} + +.ProseMirror-hideselection * { + caret-color: transparent; +} + +.ProseMirror-focused .ProseMirror-gapcursor { + display: block; +}`; +function createStyleTag(style2, nonce, suffix) { + const tiptapStyleTag = document.querySelector(`style[data-tiptap-style${suffix ? `-${suffix}` : ""}]`); + if (tiptapStyleTag !== null) { + return tiptapStyleTag; + } + const styleNode = document.createElement("style"); + if (nonce) { + styleNode.setAttribute("nonce", nonce); + } + styleNode.setAttribute(`data-tiptap-style${suffix ? `-${suffix}` : ""}`, ""); + styleNode.innerHTML = style2; + document.getElementsByTagName("head")[0].appendChild(styleNode); + return styleNode; +} +var Editor = class extends EventEmitter { + constructor(options = {}) { + super(); + this.css = null; + this.className = "tiptap"; + this.editorView = null; + this.isFocused = false; + this.destroyed = false; + this.isInitialized = false; + this.extensionStorage = {}; + this.instanceId = Math.random().toString(36).slice(2, 9); + this.options = { + element: typeof document !== "undefined" ? document.createElement("div") : null, + content: "", + injectCSS: true, + injectNonce: void 0, + extensions: [], + autofocus: false, + editable: true, + textDirection: void 0, + editorProps: {}, + parseOptions: {}, + coreExtensionOptions: {}, + enableInputRules: true, + enablePasteRules: true, + enableCoreExtensions: true, + enableContentCheck: false, + emitContentError: false, + onBeforeCreate: () => null, + onCreate: () => null, + onMount: () => null, + onUnmount: () => null, + onUpdate: () => null, + onSelectionUpdate: () => null, + onTransaction: () => null, + onFocus: () => null, + onBlur: () => null, + onDestroy: () => null, + onContentError: ({ error }) => { + throw error; + }, + onPaste: () => null, + onDrop: () => null, + onDelete: () => null, + enableExtensionDispatchTransaction: true + }; + this.isCapturingTransaction = false; + this.capturedTransaction = null; + this.utils = { + getUpdatedPosition, + createMappablePosition + }; + this.setOptions(options); + this.createExtensionManager(); + this.createCommandManager(); + this.createSchema(); + this.on("beforeCreate", this.options.onBeforeCreate); + this.emit("beforeCreate", { editor: this }); + this.on("mount", this.options.onMount); + this.on("unmount", this.options.onUnmount); + this.on("contentError", this.options.onContentError); + this.on("create", this.options.onCreate); + this.on("update", this.options.onUpdate); + this.on("selectionUpdate", this.options.onSelectionUpdate); + this.on("transaction", this.options.onTransaction); + this.on("focus", this.options.onFocus); + this.on("blur", this.options.onBlur); + this.on("destroy", this.options.onDestroy); + this.on("drop", ({ event, slice: slice2, moved }) => this.options.onDrop(event, slice2, moved)); + this.on("paste", ({ event, slice: slice2 }) => this.options.onPaste(event, slice2)); + this.on("delete", this.options.onDelete); + const initialDoc = this.createDoc(); + const selection = resolveFocusPosition(initialDoc, this.options.autofocus); + this.editorState = EditorState.create({ + doc: initialDoc, + schema: this.schema, + selection: selection || void 0 + }); + if (this.options.element) { + this.mount(this.options.element); + } + } + /** + * Attach the editor to the DOM, creating a new editor view. + */ + mount(el) { + if (typeof document === "undefined") { + throw new Error( + `[tiptap error]: The editor cannot be mounted because there is no 'document' defined in this environment.` + ); + } + this.createView(el); + this.emit("mount", { editor: this }); + if (this.css && !document.head.contains(this.css)) { + document.head.appendChild(this.css); + } + window.setTimeout(() => { + if (this.isDestroyed) { + return; + } + if (this.options.autofocus !== false && this.options.autofocus !== null) { + this.commands.focus(this.options.autofocus); + } + this.emit("create", { editor: this }); + this.isInitialized = true; + }, 0); + } + /** + * Remove the editor from the DOM, but still allow remounting at a different point in time + */ + unmount() { + if (this.editorView) { + const dom = this.editorView.dom; + if (dom == null ? void 0 : dom.editor) { + delete dom.editor; + } + this.editorView.destroy(); + } + this.editorView = null; + this.isInitialized = false; + if (this.css && !document.querySelectorAll(`.${this.className}`).length) { + try { + if (typeof this.css.remove === "function") { + this.css.remove(); + } else if (this.css.parentNode) { + this.css.parentNode.removeChild(this.css); + } + } catch (error) { + console.warn("Failed to remove CSS element:", error); + } + } + this.css = null; + this.emit("unmount", { editor: this }); + } + /** + * Returns the editor storage. + */ + get storage() { + return this.extensionStorage; + } + /** + * An object of all registered commands. + */ + get commands() { + return this.commandManager.commands; + } + /** + * Create a command chain to call multiple commands at once. + */ + chain() { + return this.commandManager.chain(); + } + /** + * Check if a command or a command chain can be executed. Without executing it. + */ + can() { + return this.commandManager.can(); + } + /** + * Inject CSS styles. + */ + injectCSS() { + if (this.options.injectCSS && typeof document !== "undefined") { + this.css = createStyleTag(style, this.options.injectNonce); + } + } + /** + * Update editor options. + * + * @param options A list of options + */ + setOptions(options = {}) { + this.options = { + ...this.options, + ...options + }; + if (!this.editorView || !this.state || this.isDestroyed) { + return; + } + if (this.options.editorProps) { + this.view.setProps(this.options.editorProps); + } + this.view.updateState(this.state); + } + /** + * Update editable state of the editor. + */ + setEditable(editable, emitUpdate = true) { + this.setOptions({ editable }); + if (emitUpdate) { + this.emit("update", { editor: this, transaction: this.state.tr, appendedTransactions: [] }); + } + } + /** + * Returns whether the editor is editable. + */ + get isEditable() { + return this.options.editable && this.view && this.view.editable; + } + /** + * Returns the editor view. + */ + get view() { + if (this.editorView) { + return this.editorView; + } + return new Proxy( + { + state: this.editorState, + updateState: (state) => { + this.editorState = state; + }, + dispatch: (tr2) => { + this.dispatchTransaction(tr2); + }, + // Stub some commonly accessed properties to prevent errors + composing: false, + dragging: null, + editable: true, + isDestroyed: false + }, + { + get: (obj, key) => { + if (this.editorView) { + return this.editorView[key]; + } + if (key === "state") { + return this.editorState; + } + if (key in obj) { + return Reflect.get(obj, key); + } + throw new Error( + `[tiptap error]: The editor view is not available. Cannot access view['${key}']. The editor may not be mounted yet.` + ); + } + } + ); + } + /** + * Returns the editor state. + */ + get state() { + if (this.editorView) { + this.editorState = this.view.state; + } + return this.editorState; + } + /** + * Register a ProseMirror plugin. + * + * @param plugin A ProseMirror plugin + * @param handlePlugins Control how to merge the plugin into the existing plugins. + * @returns The new editor state + */ + registerPlugin(plugin, handlePlugins) { + const plugins = isFunction(handlePlugins) ? handlePlugins(plugin, [...this.state.plugins]) : [...this.state.plugins, plugin]; + const state = this.state.reconfigure({ plugins }); + this.view.updateState(state); + return state; + } + /** + * Unregister a ProseMirror plugin. + * + * @param nameOrPluginKeyToRemove The plugins name + * @returns The new editor state or undefined if the editor is destroyed + */ + unregisterPlugin(nameOrPluginKeyToRemove) { + if (this.isDestroyed) { + return void 0; + } + const prevPlugins = this.state.plugins; + let plugins = prevPlugins; + [].concat(nameOrPluginKeyToRemove).forEach((nameOrPluginKey) => { + const name = typeof nameOrPluginKey === "string" ? `${nameOrPluginKey}$` : nameOrPluginKey.key; + plugins = plugins.filter((plugin) => !plugin.key.startsWith(name)); + }); + if (prevPlugins.length === plugins.length) { + return void 0; + } + const state = this.state.reconfigure({ + plugins + }); + this.view.updateState(state); + return state; + } + /** + * Creates an extension manager. + */ + createExtensionManager() { + var _a, _b, _c, _d; + const coreExtensions = this.options.enableCoreExtensions ? [ + Editable, + ClipboardTextSerializer.configure({ + blockSeparator: (_b = (_a = this.options.coreExtensionOptions) == null ? void 0 : _a.clipboardTextSerializer) == null ? void 0 : _b.blockSeparator + }), + Commands, + FocusEvents, + Keymap, + Tabindex.configure({ + value: (_d = (_c = this.options.coreExtensionOptions) == null ? void 0 : _c.tabindex) == null ? void 0 : _d.value + }), + Drop, + Paste, + Delete, + TextDirection.configure({ + direction: this.options.textDirection + }) + ].filter((ext) => { + if (typeof this.options.enableCoreExtensions === "object") { + return this.options.enableCoreExtensions[ext.name] !== false; + } + return true; + }) : []; + const allExtensions = [...coreExtensions, ...this.options.extensions].filter((extension) => { + return ["extension", "node", "mark"].includes(extension == null ? void 0 : extension.type); + }); + this.extensionManager = new ExtensionManager(allExtensions, this); + } + /** + * Creates an command manager. + */ + createCommandManager() { + this.commandManager = new CommandManager({ + editor: this + }); + } + /** + * Creates a ProseMirror schema. + */ + createSchema() { + this.schema = this.extensionManager.schema; + } + /** + * Creates the initial document. + */ + createDoc() { + let doc4; + try { + doc4 = createDocument(this.options.content, this.schema, this.options.parseOptions, { + errorOnInvalidContent: this.options.enableContentCheck + }); + } catch (e) { + if (!(e instanceof Error) || !["[tiptap error]: Invalid JSON content", "[tiptap error]: Invalid HTML content"].includes( + e.message + )) { + throw e; + } + this.emit("contentError", { + editor: this, + error: e, + disableCollaboration: () => { + if ("collaboration" in this.storage && typeof this.storage.collaboration === "object" && this.storage.collaboration) { + ; + this.storage.collaboration.isDisabled = true; + } + this.options.extensions = this.options.extensions.filter( + (extension) => extension.name !== "collaboration" + ); + this.createExtensionManager(); + } + }); + doc4 = createDocument(this.options.content, this.schema, this.options.parseOptions, { + errorOnInvalidContent: false + }); + } + return doc4; + } + /** + * Creates a ProseMirror view. + */ + createView(element2) { + const { editorProps, enableExtensionDispatchTransaction } = this.options; + const baseDispatch = editorProps.dispatchTransaction || this.dispatchTransaction.bind(this); + const dispatch = enableExtensionDispatchTransaction ? this.extensionManager.dispatchTransaction(baseDispatch) : baseDispatch; + const baseTransformPastedHTML = editorProps.transformPastedHTML; + const transformPastedHTML = this.extensionManager.transformPastedHTML(baseTransformPastedHTML); + this.editorView = new EditorView(element2, { + ...editorProps, + attributes: { + // add `role="textbox"` to the editor element + role: "textbox", + ...editorProps == null ? void 0 : editorProps.attributes + }, + dispatchTransaction: dispatch, + transformPastedHTML, + state: this.editorState, + markViews: this.extensionManager.markViews, + nodeViews: this.extensionManager.nodeViews + }); + const newState = this.state.reconfigure({ + plugins: this.extensionManager.plugins + }); + this.view.updateState(newState); + this.prependClass(); + this.injectCSS(); + const dom = this.view.dom; + dom.editor = this; + } + /** + * Creates all node and mark views. + */ + createNodeViews() { + if (this.view.isDestroyed) { + return; + } + this.view.setProps({ + markViews: this.extensionManager.markViews, + nodeViews: this.extensionManager.nodeViews + }); + } + /** + * Prepend class name to element. + */ + prependClass() { + this.view.dom.className = `${this.className} ${this.view.dom.className}`; + } + captureTransaction(fn) { + this.isCapturingTransaction = true; + fn(); + this.isCapturingTransaction = false; + const tr2 = this.capturedTransaction; + this.capturedTransaction = null; + return tr2; + } + /** + * The callback over which to send transactions (state updates) produced by the view. + * + * @param transaction An editor state transaction + */ + dispatchTransaction(transaction) { + if (this.view.isDestroyed) { + return; + } + if (this.isCapturingTransaction) { + if (!this.capturedTransaction) { + this.capturedTransaction = transaction; + return; + } + transaction.steps.forEach((step) => { + var _a; + return (_a = this.capturedTransaction) == null ? void 0 : _a.step(step); + }); + return; + } + const { state, transactions } = this.state.applyTransaction(transaction); + const selectionHasChanged = !this.state.selection.eq(state.selection); + const rootTrWasApplied = transactions.includes(transaction); + const prevState = this.state; + this.emit("beforeTransaction", { + editor: this, + transaction, + nextState: state + }); + if (!rootTrWasApplied) { + return; + } + this.view.updateState(state); + this.emit("transaction", { + editor: this, + transaction, + appendedTransactions: transactions.slice(1) + }); + if (selectionHasChanged) { + this.emit("selectionUpdate", { + editor: this, + transaction + }); + } + const mostRecentFocusTr = transactions.findLast((tr2) => tr2.getMeta("focus") || tr2.getMeta("blur")); + const focus2 = mostRecentFocusTr == null ? void 0 : mostRecentFocusTr.getMeta("focus"); + const blur2 = mostRecentFocusTr == null ? void 0 : mostRecentFocusTr.getMeta("blur"); + if (focus2) { + this.emit("focus", { + editor: this, + event: focus2.event, + // oxlint-disable-next-lineno-non-null-assertion + transaction: mostRecentFocusTr + }); + } + if (blur2) { + this.emit("blur", { + editor: this, + event: blur2.event, + // oxlint-disable-next-lineno-non-null-assertion + transaction: mostRecentFocusTr + }); + } + if (transaction.getMeta("preventUpdate") || !transactions.some((tr2) => tr2.docChanged) || prevState.doc.eq(state.doc)) { + return; + } + this.emit("update", { + editor: this, + transaction, + appendedTransactions: transactions.slice(1) + }); + } + /** + * Get attributes of the currently selected node or mark. + */ + getAttributes(nameOrType) { + return getAttributes(this.state, nameOrType); + } + isActive(nameOrAttributes, attributesOrUndefined) { + const name = typeof nameOrAttributes === "string" ? nameOrAttributes : null; + const attributes = typeof nameOrAttributes === "string" ? attributesOrUndefined : nameOrAttributes; + return isActive(this.state, name, attributes); + } + /** + * Get the document as JSON. + */ + getJSON() { + return this.state.doc.toJSON(); + } + /** + * Get the document as HTML. + */ + getHTML() { + return getHTMLFromFragment(this.state.doc.content, this.schema); + } + /** + * Get the document as text. + */ + getText(options) { + const { blockSeparator = "\n\n", textSerializers = {} } = options || {}; + return getText2(this.state.doc, { + blockSeparator, + textSerializers: { + ...getTextSerializersFromSchema(this.schema), + ...textSerializers + } + }); + } + /** + * Check if there is no content. + */ + get isEmpty() { + return isNodeEmpty(this.state.doc); + } + /** + * Destroy the editor. + */ + destroy() { + if (this.destroyed) { + return; + } + this.destroyed = true; + this.emit("destroy"); + this.unmount(); + this.removeAllListeners(); + this.extensionManager.destroy(); + this.extensionManager = null; + this.schema = null; + this.commandManager = null; + this.extensionStorage = {}; + } + /** + * Check if the editor is already destroyed. + */ + get isDestroyed() { + var _a, _b; + return (_b = (_a = this.editorView) == null ? void 0 : _a.isDestroyed) != null ? _b : true; + } + $node(selector, attributes) { + var _a; + return ((_a = this.$doc) == null ? void 0 : _a.querySelector(selector, attributes)) || null; + } + $nodes(selector, attributes) { + var _a; + return ((_a = this.$doc) == null ? void 0 : _a.querySelectorAll(selector, attributes)) || null; + } + $pos(pos) { + const $pos = this.state.doc.resolve(pos); + const node = pos > 0 && $pos.nodeAfter && !$pos.nodeAfter.isText ? $pos.nodeAfter : null; + return new NodePos($pos, this, false, node); + } + get $doc() { + return this.$pos(0); + } +}; +function markInputRule(config) { + return new InputRule({ + find: config.find, + handler: ({ state, range, match: match2 }) => { + const attributes = callOrReturn(config.getAttributes, void 0, match2); + if (attributes === false || attributes === null) { + return null; + } + const { tr: tr2 } = state; + const captureGroup = match2[match2.length - 1]; + const fullMatch = match2[0]; + if (captureGroup) { + const startSpaces = fullMatch.search(/\S/); + const textStart = range.from + fullMatch.indexOf(captureGroup); + const textEnd = textStart + captureGroup.length; + const excludedMarks = getMarksBetween(range.from, range.to, state.doc).filter((item) => { + const excluded = item.mark.type.excluded; + return excluded.find((type) => type === config.type && type !== item.mark.type); + }).filter((item) => item.to > textStart); + if (excludedMarks.length) { + return null; + } + if (textEnd < range.to) { + tr2.delete(textEnd, range.to); + } + if (textStart > range.from) { + tr2.delete(range.from + startSpaces, textStart); + } + const markEnd = range.from + startSpaces + captureGroup.length; + tr2.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {})); + tr2.removeStoredMark(config.type); + } + }, + undoable: config.undoable + }); +} +function nodeInputRule(config) { + return new InputRule({ + find: config.find, + handler: ({ state, range, match: match2 }) => { + const attributes = callOrReturn(config.getAttributes, void 0, match2) || {}; + const { tr: tr2 } = state; + const start = range.from; + let end = range.to; + const newNode = config.type.create(attributes); + if (match2[1]) { + const offset = match2[0].lastIndexOf(match2[1]); + let matchStart = start + offset; + if (matchStart > end) { + matchStart = end; + } else { + end = matchStart + match2[1].length; + } + const lastChar = match2[0][match2[0].length - 1]; + tr2.insertText(lastChar, start + match2[0].length - 1); + tr2.replaceWith(matchStart, end, newNode); + } else if (match2[0]) { + const insertionStart = config.type.isInline ? start : start - 1; + tr2.insert(insertionStart, config.type.create(attributes)).delete( + tr2.mapping.map(start), + tr2.mapping.map(end) + ); + } + tr2.scrollIntoView(); + }, + undoable: config.undoable + }); +} +function textblockTypeInputRule(config) { + return new InputRule({ + find: config.find, + handler: ({ state, range, match: match2 }) => { + const $start = state.doc.resolve(range.from); + const attributes = callOrReturn(config.getAttributes, void 0, match2) || {}; + if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), config.type)) { + return null; + } + state.tr.delete(range.from, range.to).setBlockType(range.from, range.from, config.type, attributes); + }, + undoable: config.undoable + }); +} +function wrappingInputRule(config) { + return new InputRule({ + find: config.find, + handler: ({ state, range, match: match2, chain }) => { + const attributes = callOrReturn(config.getAttributes, void 0, match2) || {}; + const tr2 = state.tr.delete(range.from, range.to); + const $start = tr2.doc.resolve(range.from); + const blockRange = $start.blockRange(); + const wrapping = blockRange && findWrapping(blockRange, config.type, attributes); + if (!wrapping) { + return null; + } + tr2.wrap(blockRange, wrapping); + if (config.keepMarks && config.editor) { + const { selection, storedMarks } = state; + const { splittableMarks } = config.editor.extensionManager; + const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks(); + if (marks) { + const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name)); + tr2.ensureMarks(filteredMarks); + } + } + if (config.keepAttributes) { + const nodeType = config.type.name === "bulletList" || config.type.name === "orderedList" ? "listItem" : "taskList"; + chain().updateAttributes(nodeType, attributes).run(); + } + const before = tr2.doc.resolve(range.from - 1).nodeBefore; + if (before && before.type === config.type && canJoin(tr2.doc, range.from - 1) && (!config.joinPredicate || config.joinPredicate(match2, before))) { + tr2.join(range.from - 1); + } + }, + undoable: config.undoable + }); +} +function canInsertNode(state, nodeType) { + const { selection } = state; + const { $from } = selection; + if (selection instanceof NodeSelection) { + const index = $from.index(); + const parent = $from.parent; + return parent.canReplaceWith(index, index + 1, nodeType); + } + let depth = $from.depth; + while (depth >= 0) { + const index = $from.index(depth); + const parent = $from.node(depth); + const match2 = parent.contentMatchAt(index); + if (match2.matchType(nodeType)) { + return true; + } + depth -= 1; + } + return false; +} +var markdown_exports = {}; +__export2(markdown_exports, { + createAtomBlockMarkdownSpec: () => createAtomBlockMarkdownSpec, + createBlockMarkdownSpec: () => createBlockMarkdownSpec, + createInlineMarkdownSpec: () => createInlineMarkdownSpec, + parseAttributes: () => parseAttributes, + parseIndentedBlocks: () => parseIndentedBlocks, + renderNestedMarkdownContent: () => renderNestedMarkdownContent, + serializeAttributes: () => serializeAttributes +}); +function parseAttributes(attrString) { + if (!(attrString == null ? void 0 : attrString.trim())) { + return {}; + } + const attributes = {}; + const quotedStrings = []; + const tempString = attrString.replace(/["']([^"']*)["']/g, (match2) => { + quotedStrings.push(match2); + return `__QUOTED_${quotedStrings.length - 1}__`; + }); + const classMatches = tempString.match(/(?:^|\s)\.([a-zA-Z][\w-]*)/g); + if (classMatches) { + const classes = classMatches.map((match2) => match2.trim().slice(1)); + attributes.class = classes.join(" "); + } + const idMatch = tempString.match(/(?:^|\s)#([a-zA-Z][\w-]*)/); + if (idMatch) { + attributes.id = idMatch[1]; + } + const kvRegex = /([a-zA-Z][\w-]*)\s*=\s*(__QUOTED_\d+__)/g; + const kvMatches = Array.from(tempString.matchAll(kvRegex)); + kvMatches.forEach(([, key, quotedRef]) => { + var _a; + const quotedIndex = parseInt(((_a = quotedRef.match(/__QUOTED_(\d+)__/)) == null ? void 0 : _a[1]) || "0", 10); + const quotedValue = quotedStrings[quotedIndex]; + if (quotedValue) { + attributes[key] = quotedValue.slice(1, -1); + } + }); + const cleanString = tempString.replace(/(?:^|\s)\.([a-zA-Z][\w-]*)/g, "").replace(/(?:^|\s)#([a-zA-Z][\w-]*)/g, "").replace(/([a-zA-Z][\w-]*)\s*=\s*__QUOTED_\d+__/g, "").trim(); + if (cleanString) { + const booleanAttrs = cleanString.split(/\s+/).filter(Boolean); + booleanAttrs.forEach((attr) => { + if (attr.match(/^[a-zA-Z][\w-]*$/)) { + attributes[attr] = true; + } + }); + } + return attributes; +} +function serializeAttributes(attributes) { + if (!attributes || Object.keys(attributes).length === 0) { + return ""; + } + const parts = []; + if (attributes.class) { + const classes = String(attributes.class).split(/\s+/).filter(Boolean); + classes.forEach((cls) => parts.push(`.${cls}`)); + } + if (attributes.id) { + parts.push(`#${attributes.id}`); + } + Object.entries(attributes).forEach(([key, value]) => { + if (key === "class" || key === "id") { + return; + } + if (value === true) { + parts.push(key); + } else if (value !== false && value != null) { + parts.push(`${key}="${String(value)}"`); + } + }); + return parts.join(" "); +} +function createAtomBlockMarkdownSpec(options) { + const { + nodeName, + name: markdownName, + parseAttributes: parseAttributes2 = parseAttributes, + serializeAttributes: serializeAttributes2 = serializeAttributes, + defaultAttributes = {}, + requiredAttributes = [], + allowedAttributes + } = options; + const blockName = markdownName || nodeName; + const filterAttributes = (attrs) => { + if (!allowedAttributes) { + return attrs; + } + const filtered = {}; + allowedAttributes.forEach((key) => { + if (key in attrs) { + filtered[key] = attrs[key]; + } + }); + return filtered; + }; + return { + parseMarkdown: (token, h2) => { + const attrs = { ...defaultAttributes, ...token.attributes }; + return h2.createNode(nodeName, attrs, []); + }, + markdownTokenizer: { + name: nodeName, + level: "block", + start(src) { + var _a; + const regex = new RegExp(`^:::${blockName}(?:\\s|$)`, "m"); + const index = (_a = src.match(regex)) == null ? void 0 : _a.index; + return index !== void 0 ? index : -1; + }, + tokenize(src, _tokens, _lexer) { + const regex = new RegExp(`^:::${blockName}(?:\\s+\\{([^}]*)\\})?\\s*:::(?:\\n|$)`); + const match2 = src.match(regex); + if (!match2) { + return void 0; + } + const attrString = match2[1] || ""; + const attributes = parseAttributes2(attrString); + const missingRequired = requiredAttributes.find((required) => !(required in attributes)); + if (missingRequired) { + return void 0; + } + return { + type: nodeName, + raw: match2[0], + attributes + }; + } + }, + renderMarkdown: (node) => { + const filteredAttrs = filterAttributes(node.attrs || {}); + const attrs = serializeAttributes2(filteredAttrs); + const attrString = attrs ? ` {${attrs}}` : ""; + return `:::${blockName}${attrString} :::`; + } + }; +} +function createBlockMarkdownSpec(options) { + const { + nodeName, + name: markdownName, + getContent, + parseAttributes: parseAttributes2 = parseAttributes, + serializeAttributes: serializeAttributes2 = serializeAttributes, + defaultAttributes = {}, + content = "block", + allowedAttributes + } = options; + const blockName = markdownName || nodeName; + const filterAttributes = (attrs) => { + if (!allowedAttributes) { + return attrs; + } + const filtered = {}; + allowedAttributes.forEach((key) => { + if (key in attrs) { + filtered[key] = attrs[key]; + } + }); + return filtered; + }; + return { + parseMarkdown: (token, h2) => { + let nodeContent; + if (getContent) { + const contentResult = getContent(token); + nodeContent = typeof contentResult === "string" ? [{ type: "text", text: contentResult }] : contentResult; + } else if (content === "block") { + nodeContent = h2.parseChildren(token.tokens || []); + } else { + nodeContent = h2.parseInline(token.tokens || []); + } + const attrs = { ...defaultAttributes, ...token.attributes }; + return h2.createNode(nodeName, attrs, nodeContent); + }, + markdownTokenizer: { + name: nodeName, + level: "block", + start(src) { + var _a; + const regex = new RegExp(`^:::${blockName}`, "m"); + const index = (_a = src.match(regex)) == null ? void 0 : _a.index; + return index !== void 0 ? index : -1; + }, + tokenize(src, _tokens, lexer) { + var _a; + const openingRegex = new RegExp(`^:::${blockName}(?:\\s+\\{([^}]*)\\})?\\s*\\n`); + const openingMatch = src.match(openingRegex); + if (!openingMatch) { + return void 0; + } + const [openingTag, attrString = ""] = openingMatch; + const attributes = parseAttributes2(attrString); + let level = 1; + const position = openingTag.length; + let matchedContent = ""; + const blockPattern = /^:::([\w-]*)(\s.*)?/gm; + const remaining = src.slice(position); + blockPattern.lastIndex = 0; + for (; ; ) { + const match2 = blockPattern.exec(remaining); + if (match2 === null) { + break; + } + const matchPos = match2.index; + const blockType = match2[1]; + if ((_a = match2[2]) == null ? void 0 : _a.endsWith(":::")) { + continue; + } + if (blockType) { + level += 1; + } else { + level -= 1; + if (level === 0) { + const rawContent = remaining.slice(0, matchPos); + matchedContent = rawContent.trim(); + const fullMatch = src.slice(0, position + matchPos + match2[0].length); + let contentTokens = []; + if (matchedContent) { + if (content === "block") { + contentTokens = lexer.blockTokens(rawContent); + contentTokens.forEach((token) => { + if (token.text && (!token.tokens || token.tokens.length === 0)) { + token.tokens = lexer.inlineTokens(token.text); + } + }); + while (contentTokens.length > 0) { + const lastToken = contentTokens[contentTokens.length - 1]; + if (lastToken.type === "paragraph" && (!lastToken.text || lastToken.text.trim() === "")) { + contentTokens.pop(); + } else { + break; + } + } + } else { + contentTokens = lexer.inlineTokens(matchedContent); + } + } + return { + type: nodeName, + raw: fullMatch, + attributes, + content: matchedContent, + tokens: contentTokens + }; + } + } + } + return void 0; + } + }, + renderMarkdown: (node, h2) => { + const filteredAttrs = filterAttributes(node.attrs || {}); + const attrs = serializeAttributes2(filteredAttrs); + const attrString = attrs ? ` {${attrs}}` : ""; + const renderedContent = h2.renderChildren(node.content || [], "\n\n"); + return `:::${blockName}${attrString} + +${renderedContent} + +:::`; + } + }; +} +function parseShortcodeAttributes(attrString) { + if (!attrString.trim()) { + return {}; + } + const attributes = {}; + const regex = /(\w+)=(?:"([^"]*)"|'([^']*)')/g; + let match2 = regex.exec(attrString); + while (match2 !== null) { + const [, key, doubleQuoted, singleQuoted] = match2; + attributes[key] = doubleQuoted || singleQuoted; + match2 = regex.exec(attrString); + } + return attributes; +} +function serializeShortcodeAttributes(attrs) { + return Object.entries(attrs).filter(([, value]) => value !== void 0 && value !== null).map(([key, value]) => `${key}="${value}"`).join(" "); +} +function createInlineMarkdownSpec(options) { + const { + nodeName, + name: shortcodeName, + getContent, + parseAttributes: parseAttributes2 = parseShortcodeAttributes, + serializeAttributes: serializeAttributes2 = serializeShortcodeAttributes, + defaultAttributes = {}, + selfClosing = false, + allowedAttributes + } = options; + const shortcode = shortcodeName || nodeName; + const filterAttributes = (attrs) => { + if (!allowedAttributes) { + return attrs; + } + const filtered = {}; + allowedAttributes.forEach((attr) => { + const attrName = typeof attr === "string" ? attr : attr.name; + const skipIfDefault = typeof attr === "string" ? void 0 : attr.skipIfDefault; + if (attrName in attrs) { + const value = attrs[attrName]; + if (skipIfDefault !== void 0 && value === skipIfDefault) { + return; + } + filtered[attrName] = value; + } + }); + return filtered; + }; + const escapedShortcode = shortcode.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + return { + parseMarkdown: (token, h2) => { + const attrs = { ...defaultAttributes, ...token.attributes }; + if (selfClosing) { + return h2.createNode(nodeName, attrs); + } + const content = getContent ? getContent(token) : token.content || ""; + if (content) { + return h2.createNode(nodeName, attrs, [h2.createTextNode(content)]); + } + return h2.createNode(nodeName, attrs, []); + }, + markdownTokenizer: { + name: nodeName, + level: "inline", + start(src) { + const startPattern = selfClosing ? new RegExp(`\\[${escapedShortcode}\\s*[^\\]]*\\]`) : new RegExp(`\\[${escapedShortcode}\\s*[^\\]]*\\][\\s\\S]*?\\[\\/${escapedShortcode}\\]`); + const match2 = src.match(startPattern); + const index = match2 == null ? void 0 : match2.index; + return index !== void 0 ? index : -1; + }, + tokenize(src, _tokens, _lexer) { + const tokenPattern = selfClosing ? new RegExp(`^\\[${escapedShortcode}\\s*([^\\]]*)\\]`) : new RegExp( + `^\\[${escapedShortcode}\\s*([^\\]]*)\\]([\\s\\S]*?)\\[\\/${escapedShortcode}\\]` + ); + const match2 = src.match(tokenPattern); + if (!match2) { + return void 0; + } + let content = ""; + let attrString = ""; + if (selfClosing) { + const [, attrs] = match2; + attrString = attrs; + } else { + const [, attrs, contentMatch] = match2; + attrString = attrs; + content = contentMatch || ""; + } + const attributes = parseAttributes2(attrString.trim()); + return { + type: nodeName, + raw: match2[0], + content: content.trim(), + attributes + }; + } + }, + renderMarkdown: (node) => { + let content = ""; + if (getContent) { + content = getContent(node); + } else if (node.content && node.content.length > 0) { + content = node.content.filter((child) => child.type === "text").map((child) => child.text).join(""); + } + const filteredAttrs = filterAttributes(node.attrs || {}); + const attrs = serializeAttributes2(filteredAttrs); + const attrString = attrs ? ` ${attrs}` : ""; + if (selfClosing) { + return `[${shortcode}${attrString}]`; + } + return `[${shortcode}${attrString}]${content}[/${shortcode}]`; + } + }; +} +function parseIndentedBlocks(src, config, lexer) { + var _a, _b, _c, _d; + const lines = src.split("\n"); + const items = []; + let totalRaw = ""; + let i = 0; + const baseIndentSize = config.baseIndentSize || 2; + while (i < lines.length) { + const currentLine = lines[i]; + const itemMatch = currentLine.match(config.itemPattern); + if (!itemMatch) { + if (items.length > 0) { + break; + } else if (currentLine.trim() === "") { + i += 1; + totalRaw = `${totalRaw}${currentLine} +`; + continue; + } else { + return void 0; + } + } + const itemData = config.extractItemData(itemMatch); + const { indentLevel, mainContent } = itemData; + totalRaw = `${totalRaw}${currentLine} +`; + const itemContent = [mainContent]; + i += 1; + while (i < lines.length) { + const nextLine = lines[i]; + if (nextLine.trim() === "") { + const nextNonEmptyIndex = lines.slice(i + 1).findIndex((l3) => l3.trim() !== ""); + if (nextNonEmptyIndex === -1) { + break; + } + const nextNonEmpty = lines[i + 1 + nextNonEmptyIndex]; + const nextIndent2 = ((_b = (_a = nextNonEmpty.match(/^(\s*)/)) == null ? void 0 : _a[1]) == null ? void 0 : _b.length) || 0; + if (nextIndent2 > indentLevel) { + itemContent.push(nextLine); + totalRaw = `${totalRaw}${nextLine} +`; + i += 1; + continue; + } else { + break; + } + } + const nextIndent = ((_d = (_c = nextLine.match(/^(\s*)/)) == null ? void 0 : _c[1]) == null ? void 0 : _d.length) || 0; + if (nextIndent > indentLevel) { + itemContent.push(nextLine); + totalRaw = `${totalRaw}${nextLine} +`; + i += 1; + } else { + break; + } + } + let nestedTokens; + const nestedContent = itemContent.slice(1); + if (nestedContent.length > 0) { + const dedentedNested = nestedContent.map((nestedLine) => nestedLine.slice(indentLevel + baseIndentSize)).join("\n"); + if (dedentedNested.trim()) { + if (config.customNestedParser) { + nestedTokens = config.customNestedParser(dedentedNested); + } else { + nestedTokens = lexer.blockTokens(dedentedNested); + } + } + } + const token = config.createToken(itemData, nestedTokens); + items.push(token); + } + if (items.length === 0) { + return void 0; + } + return { + items, + raw: totalRaw + }; +} +function renderNestedMarkdownContent(node, h2, prefixOrGenerator, ctx) { + if (!node || !Array.isArray(node.content)) { + return ""; + } + const prefix = typeof prefixOrGenerator === "function" ? prefixOrGenerator(ctx) : prefixOrGenerator; + const [content, ...children] = node.content; + const mainContent = h2.renderChildren([content]); + let output = `${prefix}${mainContent}`; + if (children && children.length > 0) { + children.forEach((child, index) => { + var _a, _b; + const childContent = (_b = (_a = h2.renderChild) == null ? void 0 : _a.call(h2, child, index + 1)) != null ? _b : h2.renderChildren([child]); + if (childContent !== void 0 && childContent !== null) { + const indentedChild = childContent.split("\n").map((line) => line ? h2.indent(line) : h2.indent("")).join("\n"); + output += child.type === "paragraph" ? ` + +${indentedChild}` : ` +${indentedChild}`; + } + }); + } + return output; +} +function updateMarkViewAttributes(checkMark, editor, attrs = {}) { + const { state } = editor; + const { doc: doc4, tr: tr2 } = state; + const thisMark = checkMark; + doc4.descendants((node, pos) => { + const from3 = tr2.mapping.map(pos); + const to = tr2.mapping.map(pos) + node.nodeSize; + let foundMark = null; + node.marks.forEach((mark) => { + if (mark !== thisMark) { + return false; + } + foundMark = mark; + }); + if (!foundMark) { + return; + } + let needsUpdate = false; + Object.keys(attrs).forEach((k) => { + if (attrs[k] !== foundMark.attrs[k]) { + needsUpdate = true; + } + }); + if (needsUpdate) { + const updatedMark = checkMark.type.create({ + ...checkMark.attrs, + ...attrs + }); + tr2.removeMark(from3, to, checkMark.type); + tr2.addMark(from3, to, updatedMark); + } + }); + if (tr2.docChanged) { + editor.view.dispatch(tr2); + } +} +var Node3 = class _Node extends Extendable { + constructor() { + super(...arguments); + this.type = "node"; + } + /** + * Create a new Node instance + * @param config - Node configuration object or a function that returns a configuration object + */ + static create(config = {}) { + const resolvedConfig = typeof config === "function" ? config() : config; + return new _Node(resolvedConfig); + } + configure(options) { + return super.configure(options); + } + extend(extendedConfig) { + const resolvedConfig = typeof extendedConfig === "function" ? extendedConfig() : extendedConfig; + return super.extend(resolvedConfig); + } +}; +function markPasteRule(config) { + return new PasteRule({ + find: config.find, + handler: ({ state, range, match: match2, pasteEvent }) => { + const attributes = callOrReturn(config.getAttributes, void 0, match2, pasteEvent); + if (attributes === false || attributes === null) { + return null; + } + const { tr: tr2 } = state; + const captureGroup = match2[match2.length - 1]; + const fullMatch = match2[0]; + let markEnd = range.to; + if (captureGroup) { + const startSpaces = fullMatch.search(/\S/); + const textStart = range.from + fullMatch.indexOf(captureGroup); + const textEnd = textStart + captureGroup.length; + const excludedMarks = getMarksBetween(range.from, range.to, state.doc).filter((item) => { + const excluded = item.mark.type.excluded; + return excluded.find((type) => type === config.type && type !== item.mark.type); + }).filter((item) => item.to > textStart); + if (excludedMarks.length) { + return null; + } + if (textEnd < range.to) { + tr2.delete(textEnd, range.to); + } + if (textStart > range.from) { + tr2.delete(range.from + startSpaces, textStart); + } + markEnd = range.from + startSpaces + captureGroup.length; + tr2.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {})); + const isMatchAtEndOfText = match2.index !== void 0 && match2.input !== void 0 && match2.index + match2[0].length >= match2.input.length; + if (!isMatchAtEndOfText) { + tr2.removeStoredMark(config.type); + } + } + } + }); +} + +// ../../node_modules/.pnpm/@tiptap+core@3.26.0_@tiptap+pm@3.26.0/node_modules/@tiptap/core/dist/jsx-runtime/jsx-runtime.js +var h = (tag, attributes) => { + if (tag === "slot") { + return 0; + } + if (tag instanceof Function) { + return tag(attributes); + } + const { children, ...rest } = attributes != null ? attributes : {}; + if (tag === "svg") { + throw new Error( + "SVG elements are not supported in the JSX syntax, use the array syntax instead" + ); + } + return [tag, rest, children]; +}; + +// ../../node_modules/.pnpm/@tiptap+extension-blockquote@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-blockquote/dist/index.js +function findDiffStart2(a, b2, pos) { + for (let i = 0; ; i++) { + if (i == a.childCount || i == b2.childCount) + return a.childCount == b2.childCount ? null : pos; + let childA = a.child(i), childB = b2.child(i); + if (childA == childB) { + pos += childA.nodeSize; + continue; + } + if (!childA.sameMarkup(childB)) + return pos; + if (childA.isText && childA.text != childB.text) { + for (let j2 = 0; childA.text[j2] == childB.text[j2]; j2++) + pos++; + return pos; + } + if (childA.content.size || childB.content.size) { + let inner = findDiffStart2(childA.content, childB.content, pos + 1); + if (inner != null) + return inner; + } + pos += childA.nodeSize; + } +} +function findDiffEnd2(a, b2, posA, posB) { + for (let iA = a.childCount, iB = b2.childCount; ; ) { + if (iA == 0 || iB == 0) + return iA == iB ? null : { a: posA, b: posB }; + let childA = a.child(--iA), childB = b2.child(--iB), size2 = childA.nodeSize; + if (childA == childB) { + posA -= size2; + posB -= size2; + continue; + } + if (!childA.sameMarkup(childB)) + return { a: posA, b: posB }; + if (childA.isText && childA.text != childB.text) { + let same = 0, minSize = Math.min(childA.text.length, childB.text.length); + while (same < minSize && childA.text[childA.text.length - same - 1] == childB.text[childB.text.length - same - 1]) { + same++; + posA--; + posB--; + } + return { a: posA, b: posB }; + } + if (childA.content.size || childB.content.size) { + let inner = findDiffEnd2(childA.content, childB.content, posA - 1, posB - 1); + if (inner) + return inner; + } + posA -= size2; + posB -= size2; + } +} +var Fragment2 = class _Fragment { + /** + @internal + */ + constructor(content, size2) { + this.content = content; + this.size = size2 || 0; + if (size2 == null) + for (let i = 0; i < content.length; i++) + this.size += content[i].nodeSize; + } + /** + Invoke a callback for all descendant nodes between the given two + positions (relative to start of this fragment). Doesn't descend + into a node when the callback returns `false`. + */ + nodesBetween(from3, to, f, nodeStart = 0, parent) { + for (let i = 0, pos = 0; pos < to; i++) { + let child = this.content[i], end = pos + child.nodeSize; + if (end > from3 && f(child, nodeStart + pos, parent || null, i) !== false && child.content.size) { + let start = pos + 1; + child.nodesBetween(Math.max(0, from3 - start), Math.min(child.content.size, to - start), f, nodeStart + start); + } + pos = end; + } + } + /** + Call the given callback for every descendant node. `pos` will be + relative to the start of the fragment. The callback may return + `false` to prevent traversal of a given node's children. + */ + descendants(f) { + this.nodesBetween(0, this.size, f); + } + /** + Extract the text between `from` and `to`. See the same method on + [`Node`](https://prosemirror.net/docs/ref/#model.Node.textBetween). + */ + textBetween(from3, to, blockSeparator, leafText) { + let text2 = "", first2 = true; + this.nodesBetween(from3, to, (node, pos) => { + let nodeText = node.isText ? node.text.slice(Math.max(from3, pos) - pos, to - pos) : !node.isLeaf ? "" : leafText ? typeof leafText === "function" ? leafText(node) : leafText : node.type.spec.leafText ? node.type.spec.leafText(node) : ""; + if (node.isBlock && (node.isLeaf && nodeText || node.isTextblock) && blockSeparator) { + if (first2) + first2 = false; + else + text2 += blockSeparator; + } + text2 += nodeText; + }, 0); + return text2; + } + /** + Create a new fragment containing the combined content of this + fragment and the other. + */ + append(other) { + if (!other.size) + return this; + if (!this.size) + return other; + let last2 = this.lastChild, first2 = other.firstChild, content = this.content.slice(), i = 0; + if (last2.isText && last2.sameMarkup(first2)) { + content[content.length - 1] = last2.withText(last2.text + first2.text); + i = 1; + } + for (; i < other.content.length; i++) + content.push(other.content[i]); + return new _Fragment(content, this.size + other.size); + } + /** + Cut out the sub-fragment between the two given positions. + */ + cut(from3, to = this.size) { + if (from3 == 0 && to == this.size) + return this; + let result = [], size2 = 0; + if (to > from3) + for (let i = 0, pos = 0; pos < to; i++) { + let child = this.content[i], end = pos + child.nodeSize; + if (end > from3) { + if (pos < from3 || end > to) { + if (child.isText) + child = child.cut(Math.max(0, from3 - pos), Math.min(child.text.length, to - pos)); + else + child = child.cut(Math.max(0, from3 - pos - 1), Math.min(child.content.size, to - pos - 1)); + } + result.push(child); + size2 += child.nodeSize; + } + pos = end; + } + return new _Fragment(result, size2); + } + /** + @internal + */ + cutByIndex(from3, to) { + if (from3 == to) + return _Fragment.empty; + if (from3 == 0 && to == this.content.length) + return this; + return new _Fragment(this.content.slice(from3, to)); + } + /** + Create a new fragment in which the node at the given index is + replaced by the given node. + */ + replaceChild(index, node) { + let current = this.content[index]; + if (current == node) + return this; + let copy3 = this.content.slice(); + let size2 = this.size + node.nodeSize - current.nodeSize; + copy3[index] = node; + return new _Fragment(copy3, size2); + } + /** + Create a new fragment by prepending the given node to this + fragment. + */ + addToStart(node) { + return new _Fragment([node].concat(this.content), this.size + node.nodeSize); + } + /** + Create a new fragment by appending the given node to this + fragment. + */ + addToEnd(node) { + return new _Fragment(this.content.concat(node), this.size + node.nodeSize); + } + /** + Compare this fragment to another one. + */ + eq(other) { + if (this.content.length != other.content.length) + return false; + for (let i = 0; i < this.content.length; i++) + if (!this.content[i].eq(other.content[i])) + return false; + return true; + } + /** + The first child of the fragment, or `null` if it is empty. + */ + get firstChild() { + return this.content.length ? this.content[0] : null; + } + /** + The last child of the fragment, or `null` if it is empty. + */ + get lastChild() { + return this.content.length ? this.content[this.content.length - 1] : null; + } + /** + The number of child nodes in this fragment. + */ + get childCount() { + return this.content.length; + } + /** + Get the child node at the given index. Raise an error when the + index is out of range. + */ + child(index) { + let found22 = this.content[index]; + if (!found22) + throw new RangeError("Index " + index + " out of range for " + this); + return found22; + } + /** + Get the child node at the given index, if it exists. + */ + maybeChild(index) { + return this.content[index] || null; + } + /** + Call `f` for every child node, passing the node, its offset + into this parent node, and its index. + */ + forEach(f) { + for (let i = 0, p = 0; i < this.content.length; i++) { + let child = this.content[i]; + f(child, p, i); + p += child.nodeSize; + } + } + /** + Find the first position at which this fragment and another + fragment differ, or `null` if they are the same. + */ + findDiffStart(other, pos = 0) { + return findDiffStart2(this, other, pos); + } + /** + Find the first position, searching from the end, at which this + fragment and the given fragment differ, or `null` if they are + the same. Since this position will not be the same in both + nodes, an object with two separate positions is returned. + */ + findDiffEnd(other, pos = this.size, otherPos = other.size) { + return findDiffEnd2(this, other, pos, otherPos); + } + /** + Find the index and inner offset corresponding to a given relative + position in this fragment. The result object will be reused + (overwritten) the next time the function is called. @internal + */ + findIndex(pos) { + if (pos == 0) + return retIndex2(0, pos); + if (pos == this.size) + return retIndex2(this.content.length, pos); + if (pos > this.size || pos < 0) + throw new RangeError(`Position ${pos} outside of fragment (${this})`); + for (let i = 0, curPos = 0; ; i++) { + let cur = this.child(i), end = curPos + cur.nodeSize; + if (end >= pos) { + if (end == pos) + return retIndex2(i + 1, end); + return retIndex2(i, curPos); + } + curPos = end; + } + } + /** + Return a debugging string that describes this fragment. + */ + toString() { + return "<" + this.toStringInner() + ">"; + } + /** + @internal + */ + toStringInner() { + return this.content.join(", "); + } + /** + Create a JSON-serializeable representation of this fragment. + */ + toJSON() { + return this.content.length ? this.content.map((n) => n.toJSON()) : null; + } + /** + Deserialize a fragment from its JSON representation. + */ + static fromJSON(schema, value) { + if (!value) + return _Fragment.empty; + if (!Array.isArray(value)) + throw new RangeError("Invalid input for Fragment.fromJSON"); + return _Fragment.fromArray(value.map(schema.nodeFromJSON)); + } + /** + Build a fragment from an array of nodes. Ensures that adjacent + text nodes with the same marks are joined together. + */ + static fromArray(array) { + if (!array.length) + return _Fragment.empty; + let joined, size2 = 0; + for (let i = 0; i < array.length; i++) { + let node = array[i]; + size2 += node.nodeSize; + if (i && node.isText && array[i - 1].sameMarkup(node)) { + if (!joined) + joined = array.slice(0, i); + joined[joined.length - 1] = node.withText(joined[joined.length - 1].text + node.text); + } else if (joined) { + joined.push(node); + } + } + return new _Fragment(joined || array, size2); + } + /** + Create a fragment from something that can be interpreted as a + set of nodes. For `null`, it returns the empty fragment. For a + fragment, the fragment itself. For a node or array of nodes, a + fragment containing those nodes. + */ + static from(nodes) { + if (!nodes) + return _Fragment.empty; + if (nodes instanceof _Fragment) + return nodes; + if (Array.isArray(nodes)) + return this.fromArray(nodes); + if (nodes.attrs) + return new _Fragment([nodes], nodes.nodeSize); + throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : "")); + } +}; +Fragment2.empty = new Fragment2([], 0); +var found2 = { index: 0, offset: 0 }; +function retIndex2(index, offset) { + found2.index = index; + found2.offset = offset; + return found2; +} +function compareDeep2(a, b2) { + if (a === b2) + return true; + if (!(a && typeof a == "object") || !(b2 && typeof b2 == "object")) + return false; + let array = Array.isArray(a); + if (Array.isArray(b2) != array) + return false; + if (array) { + if (a.length != b2.length) + return false; + for (let i = 0; i < a.length; i++) + if (!compareDeep2(a[i], b2[i])) + return false; + } else { + for (let p in a) + if (!(p in b2) || !compareDeep2(a[p], b2[p])) + return false; + for (let p in b2) + if (!(p in a)) + return false; + } + return true; +} +var Mark3 = class _Mark2 { + /** + @internal + */ + constructor(type, attrs) { + this.type = type; + this.attrs = attrs; + } + /** + Given a set of marks, create a new set which contains this one as + well, in the right position. If this mark is already in the set, + the set itself is returned. If any marks that are set to be + [exclusive](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) with this mark are present, + those are replaced by this one. + */ + addToSet(set) { + let copy3, placed = false; + for (let i = 0; i < set.length; i++) { + let other = set[i]; + if (this.eq(other)) + return set; + if (this.type.excludes(other.type)) { + if (!copy3) + copy3 = set.slice(0, i); + } else if (other.type.excludes(this.type)) { + return set; + } else { + if (!placed && other.type.rank > this.type.rank) { + if (!copy3) + copy3 = set.slice(0, i); + copy3.push(this); + placed = true; + } + if (copy3) + copy3.push(other); + } + } + if (!copy3) + copy3 = set.slice(); + if (!placed) + copy3.push(this); + return copy3; + } + /** + Remove this mark from the given set, returning a new set. If this + mark is not in the set, the set itself is returned. + */ + removeFromSet(set) { + for (let i = 0; i < set.length; i++) + if (this.eq(set[i])) + return set.slice(0, i).concat(set.slice(i + 1)); + return set; + } + /** + Test whether this mark is in the given set of marks. + */ + isInSet(set) { + for (let i = 0; i < set.length; i++) + if (this.eq(set[i])) + return true; + return false; + } + /** + Test whether this mark has the same type and attributes as + another mark. + */ + eq(other) { + return this == other || this.type == other.type && compareDeep2(this.attrs, other.attrs); + } + /** + Convert this mark to a JSON-serializeable representation. + */ + toJSON() { + let obj = { type: this.type.name }; + for (let _2 in this.attrs) { + obj.attrs = this.attrs; + break; + } + return obj; + } + /** + Deserialize a mark from JSON. + */ + static fromJSON(schema, json) { + if (!json) + throw new RangeError("Invalid input for Mark.fromJSON"); + let type = schema.marks[json.type]; + if (!type) + throw new RangeError(`There is no mark type ${json.type} in this schema`); + let mark = type.create(json.attrs); + type.checkAttrs(mark.attrs); + return mark; + } + /** + Test whether two sets of marks are identical. + */ + static sameSet(a, b2) { + if (a == b2) + return true; + if (a.length != b2.length) + return false; + for (let i = 0; i < a.length; i++) + if (!a[i].eq(b2[i])) + return false; + return true; + } + /** + Create a properly sorted mark set from null, a single mark, or an + unsorted array of marks. + */ + static setFrom(marks) { + if (!marks || Array.isArray(marks) && marks.length == 0) + return _Mark2.none; + if (marks instanceof _Mark2) + return [marks]; + let copy3 = marks.slice(); + copy3.sort((a, b2) => a.type.rank - b2.type.rank); + return copy3; + } +}; +Mark3.none = []; +var ReplaceError2 = class extends Error { +}; +var Slice2 = class _Slice { + /** + Create a slice. When specifying a non-zero open depth, you must + make sure that there are nodes of at least that depth at the + appropriate side of the fragment—i.e. if the fragment is an + empty paragraph node, `openStart` and `openEnd` can't be greater + than 1. + + It is not necessary for the content of open nodes to conform to + the schema's content constraints, though it should be a valid + start/end/middle for such a node, depending on which sides are + open. + */ + constructor(content, openStart, openEnd) { + this.content = content; + this.openStart = openStart; + this.openEnd = openEnd; + } + /** + The size this slice would add when inserted into a document. + */ + get size() { + return this.content.size - this.openStart - this.openEnd; + } + /** + @internal + */ + insertAt(pos, fragment) { + let content = insertInto2(this.content, pos + this.openStart, fragment, this.openStart + 1, this.openEnd + 1); + return content && new _Slice(content, this.openStart, this.openEnd); + } + /** + @internal + */ + removeBetween(from3, to) { + return new _Slice(removeRange2(this.content, from3 + this.openStart, to + this.openStart), this.openStart, this.openEnd); + } + /** + Tests whether this slice is equal to another slice. + */ + eq(other) { + return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd; + } + /** + @internal + */ + toString() { + return this.content + "(" + this.openStart + "," + this.openEnd + ")"; + } + /** + Convert a slice to a JSON-serializable representation. + */ + toJSON() { + if (!this.content.size) + return null; + let json = { content: this.content.toJSON() }; + if (this.openStart > 0) + json.openStart = this.openStart; + if (this.openEnd > 0) + json.openEnd = this.openEnd; + return json; + } + /** + Deserialize a slice from its JSON representation. + */ + static fromJSON(schema, json) { + if (!json) + return _Slice.empty; + let openStart = json.openStart || 0, openEnd = json.openEnd || 0; + if (typeof openStart != "number" || typeof openEnd != "number") + throw new RangeError("Invalid input for Slice.fromJSON"); + return new _Slice(Fragment2.fromJSON(schema, json.content), openStart, openEnd); + } + /** + Create a slice from a fragment by taking the maximum possible + open value on both side of the fragment. + */ + static maxOpen(fragment, openIsolating = true) { + let openStart = 0, openEnd = 0; + for (let n = fragment.firstChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.firstChild) + openStart++; + for (let n = fragment.lastChild; n && !n.isLeaf && (openIsolating || !n.type.spec.isolating); n = n.lastChild) + openEnd++; + return new _Slice(fragment, openStart, openEnd); + } +}; +Slice2.empty = new Slice2(Fragment2.empty, 0, 0); +function removeRange2(content, from3, to) { + let { index, offset } = content.findIndex(from3), child = content.maybeChild(index); + let { index: indexTo, offset: offsetTo } = content.findIndex(to); + if (offset == from3 || child.isText) { + if (offsetTo != to && !content.child(indexTo).isText) + throw new RangeError("Removing non-flat range"); + return content.cut(0, from3).append(content.cut(to)); + } + if (index != indexTo) + throw new RangeError("Removing non-flat range"); + return content.replaceChild(index, child.copy(removeRange2(child.content, from3 - offset - 1, to - offset - 1))); +} +function insertInto2(content, dist, insert, openStart, openEnd, parent) { + let { index, offset } = content.findIndex(dist), child = content.maybeChild(index); + if (offset == dist || child.isText) { + if (parent && openStart <= 0 && openEnd <= 0 && !parent.canReplace(index, index, insert)) + return null; + return content.cut(0, dist).append(insert).append(content.cut(dist)); + } + let inner = insertInto2(child.content, dist - offset - 1, insert, index == 0 ? openStart - 1 : 0, index == content.childCount - 1 ? openEnd - 1 : 0, child); + return inner && content.replaceChild(index, child.copy(inner)); +} +function replace2($from, $to, slice2) { + if (slice2.openStart > $from.depth) + throw new ReplaceError2("Inserted content deeper than insertion position"); + if ($from.depth - slice2.openStart != $to.depth - slice2.openEnd) + throw new ReplaceError2("Inconsistent open depths"); + return replaceOuter2($from, $to, slice2, 0); +} +function replaceOuter2($from, $to, slice2, depth) { + let index = $from.index(depth), node = $from.node(depth); + if (index == $to.index(depth) && depth < $from.depth - slice2.openStart) { + let inner = replaceOuter2($from, $to, slice2, depth + 1); + return node.copy(node.content.replaceChild(index, inner)); + } else if (!slice2.content.size) { + return close2(node, replaceTwoWay2($from, $to, depth)); + } else if (!slice2.openStart && !slice2.openEnd && $from.depth == depth && $to.depth == depth) { + let parent = $from.parent, content = parent.content; + return close2(parent, content.cut(0, $from.parentOffset).append(slice2.content).append(content.cut($to.parentOffset))); + } else { + let { start, end } = prepareSliceForReplace2(slice2, $from); + return close2(node, replaceThreeWay2($from, start, end, $to, depth)); + } +} +function checkJoin2(main, sub) { + if (!sub.type.compatibleContent(main.type)) + throw new ReplaceError2("Cannot join " + sub.type.name + " onto " + main.type.name); +} +function joinable3($before, $after, depth) { + let node = $before.node(depth); + checkJoin2(node, $after.node(depth)); + return node; +} +function addNode2(child, target) { + let last2 = target.length - 1; + if (last2 >= 0 && child.isText && child.sameMarkup(target[last2])) + target[last2] = child.withText(target[last2].text + child.text); + else + target.push(child); +} +function addRange2($start, $end, depth, target) { + let node = ($end || $start).node(depth); + let startIndex = 0, endIndex = $end ? $end.index(depth) : node.childCount; + if ($start) { + startIndex = $start.index(depth); + if ($start.depth > depth) { + startIndex++; + } else if ($start.textOffset) { + addNode2($start.nodeAfter, target); + startIndex++; + } + } + for (let i = startIndex; i < endIndex; i++) + addNode2(node.child(i), target); + if ($end && $end.depth == depth && $end.textOffset) + addNode2($end.nodeBefore, target); +} +function close2(node, content) { + node.type.checkContent(content); + return node.copy(content); +} +function replaceThreeWay2($from, $start, $end, $to, depth) { + let openStart = $from.depth > depth && joinable3($from, $start, depth + 1); + let openEnd = $to.depth > depth && joinable3($end, $to, depth + 1); + let content = []; + addRange2(null, $from, depth, content); + if (openStart && openEnd && $start.index(depth) == $end.index(depth)) { + checkJoin2(openStart, openEnd); + addNode2(close2(openStart, replaceThreeWay2($from, $start, $end, $to, depth + 1)), content); + } else { + if (openStart) + addNode2(close2(openStart, replaceTwoWay2($from, $start, depth + 1)), content); + addRange2($start, $end, depth, content); + if (openEnd) + addNode2(close2(openEnd, replaceTwoWay2($end, $to, depth + 1)), content); + } + addRange2($to, null, depth, content); + return new Fragment2(content); +} +function replaceTwoWay2($from, $to, depth) { + let content = []; + addRange2(null, $from, depth, content); + if ($from.depth > depth) { + let type = joinable3($from, $to, depth + 1); + addNode2(close2(type, replaceTwoWay2($from, $to, depth + 1)), content); + } + addRange2($to, null, depth, content); + return new Fragment2(content); +} +function prepareSliceForReplace2(slice2, $along) { + let extra = $along.depth - slice2.openStart, parent = $along.node(extra); + let node = parent.copy(slice2.content); + for (let i = extra - 1; i >= 0; i--) + node = $along.node(i).copy(Fragment2.from(node)); + return { + start: node.resolveNoCache(slice2.openStart + extra), + end: node.resolveNoCache(node.content.size - slice2.openEnd - extra) + }; +} +var ResolvedPos2 = class _ResolvedPos { + /** + @internal + */ + constructor(pos, path, parentOffset) { + this.pos = pos; + this.path = path; + this.parentOffset = parentOffset; + this.depth = path.length / 3 - 1; + } + /** + @internal + */ + resolveDepth(val) { + if (val == null) + return this.depth; + if (val < 0) + return this.depth + val; + return val; + } + /** + The parent node that the position points into. Note that even if + a position points into a text node, that node is not considered + the parent—text nodes are ‘flat’ in this model, and have no content. + */ + get parent() { + return this.node(this.depth); + } + /** + The root node in which the position was resolved. + */ + get doc() { + return this.node(0); + } + /** + The ancestor node at the given level. `p.node(p.depth)` is the + same as `p.parent`. + */ + node(depth) { + return this.path[this.resolveDepth(depth) * 3]; + } + /** + The index into the ancestor at the given level. If this points + at the 3rd node in the 2nd paragraph on the top level, for + example, `p.index(0)` is 1 and `p.index(1)` is 2. + */ + index(depth) { + return this.path[this.resolveDepth(depth) * 3 + 1]; + } + /** + The index pointing after this position into the ancestor at the + given level. + */ + indexAfter(depth) { + depth = this.resolveDepth(depth); + return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1); + } + /** + The (absolute) position at the start of the node at the given + level. + */ + start(depth) { + depth = this.resolveDepth(depth); + return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1; + } + /** + The (absolute) position at the end of the node at the given + level. + */ + end(depth) { + depth = this.resolveDepth(depth); + return this.start(depth) + this.node(depth).content.size; + } + /** + The (absolute) position directly before the wrapping node at the + given level, or, when `depth` is `this.depth + 1`, the original + position. + */ + before(depth) { + depth = this.resolveDepth(depth); + if (!depth) + throw new RangeError("There is no position before the top-level node"); + return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1]; + } + /** + The (absolute) position directly after the wrapping node at the + given level, or the original position when `depth` is `this.depth + 1`. + */ + after(depth) { + depth = this.resolveDepth(depth); + if (!depth) + throw new RangeError("There is no position after the top-level node"); + return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize; + } + /** + When this position points into a text node, this returns the + distance between the position and the start of the text node. + Will be zero for positions that point between nodes. + */ + get textOffset() { + return this.pos - this.path[this.path.length - 1]; + } + /** + Get the node directly after the position, if any. If the position + points into a text node, only the part of that node after the + position is returned. + */ + get nodeAfter() { + let parent = this.parent, index = this.index(this.depth); + if (index == parent.childCount) + return null; + let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index); + return dOff ? parent.child(index).cut(dOff) : child; + } + /** + Get the node directly before the position, if any. If the + position points into a text node, only the part of that node + before the position is returned. + */ + get nodeBefore() { + let index = this.index(this.depth); + let dOff = this.pos - this.path[this.path.length - 1]; + if (dOff) + return this.parent.child(index).cut(0, dOff); + return index == 0 ? null : this.parent.child(index - 1); + } + /** + Get the position at the given index in the parent node at the + given depth (which defaults to `this.depth`). + */ + posAtIndex(index, depth) { + depth = this.resolveDepth(depth); + let node = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1; + for (let i = 0; i < index; i++) + pos += node.child(i).nodeSize; + return pos; + } + /** + Get the marks at this position, factoring in the surrounding + marks' [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) property. If the + position is at the start of a non-empty node, the marks of the + node after it (if any) are returned. + */ + marks() { + let parent = this.parent, index = this.index(); + if (parent.content.size == 0) + return Mark3.none; + if (this.textOffset) + return parent.child(index).marks; + let main = parent.maybeChild(index - 1), other = parent.maybeChild(index); + if (!main) { + let tmp = main; + main = other; + other = tmp; + } + let marks = main.marks; + for (var i = 0; i < marks.length; i++) + if (marks[i].type.spec.inclusive === false && (!other || !marks[i].isInSet(other.marks))) + marks = marks[i--].removeFromSet(marks); + return marks; + } + /** + Get the marks after the current position, if any, except those + that are non-inclusive and not present at position `$end`. This + is mostly useful for getting the set of marks to preserve after a + deletion. Will return `null` if this position is at the end of + its parent node or its parent node isn't a textblock (in which + case no marks should be preserved). + */ + marksAcross($end) { + let after = this.parent.maybeChild(this.index()); + if (!after || !after.isInline) + return null; + let marks = after.marks, next2 = $end.parent.maybeChild($end.index()); + for (var i = 0; i < marks.length; i++) + if (marks[i].type.spec.inclusive === false && (!next2 || !marks[i].isInSet(next2.marks))) + marks = marks[i--].removeFromSet(marks); + return marks; + } + /** + The depth up to which this position and the given (non-resolved) + position share the same parent nodes. + */ + sharedDepth(pos) { + for (let depth = this.depth; depth > 0; depth--) + if (this.start(depth) <= pos && this.end(depth) >= pos) + return depth; + return 0; + } + /** + Returns a range based on the place where this position and the + given position diverge around block content. If both point into + the same textblock, for example, a range around that textblock + will be returned. If they point into different blocks, the range + around those blocks in their shared ancestor is returned. You can + pass in an optional predicate that will be called with a parent + node to see if a range into that parent is acceptable. + */ + blockRange(other = this, pred) { + if (other.pos < this.pos) + return other.blockRange(this); + for (let d2 = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d2 >= 0; d2--) + if (other.pos <= this.end(d2) && (!pred || pred(this.node(d2)))) + return new NodeRange2(this, other, d2); + return null; + } + /** + Query whether the given position shares the same parent node. + */ + sameParent(other) { + return this.pos - this.parentOffset == other.pos - other.parentOffset; + } + /** + Return the greater of this and the given position. + */ + max(other) { + return other.pos > this.pos ? other : this; + } + /** + Return the smaller of this and the given position. + */ + min(other) { + return other.pos < this.pos ? other : this; + } + /** + @internal + */ + toString() { + let str = ""; + for (let i = 1; i <= this.depth; i++) + str += (str ? "/" : "") + this.node(i).type.name + "_" + this.index(i - 1); + return str + ":" + this.parentOffset; + } + /** + @internal + */ + static resolve(doc4, pos) { + if (!(pos >= 0 && pos <= doc4.content.size)) + throw new RangeError("Position " + pos + " out of range"); + let path = []; + let start = 0, parentOffset = pos; + for (let node = doc4; ; ) { + let { index, offset } = node.content.findIndex(parentOffset); + let rem = parentOffset - offset; + path.push(node, index, start + offset); + if (!rem) + break; + node = node.child(index); + if (node.isText) + break; + parentOffset = rem - 1; + start += offset + 1; + } + return new _ResolvedPos(pos, path, parentOffset); + } + /** + @internal + */ + static resolveCached(doc4, pos) { + let cache = resolveCache2.get(doc4); + if (cache) { + for (let i = 0; i < cache.elts.length; i++) { + let elt = cache.elts[i]; + if (elt.pos == pos) + return elt; + } + } else { + resolveCache2.set(doc4, cache = new ResolveCache2()); + } + let result = cache.elts[cache.i] = _ResolvedPos.resolve(doc4, pos); + cache.i = (cache.i + 1) % resolveCacheSize2; + return result; + } +}; +var ResolveCache2 = class { + constructor() { + this.elts = []; + this.i = 0; + } +}; +var resolveCacheSize2 = 12; +var resolveCache2 = /* @__PURE__ */ new WeakMap(); +var NodeRange2 = class { + /** + Construct a node range. `$from` and `$to` should point into the + same node until at least the given `depth`, since a node range + denotes an adjacent set of nodes in a single parent node. + */ + constructor($from, $to, depth) { + this.$from = $from; + this.$to = $to; + this.depth = depth; + } + /** + The position at the start of the range. + */ + get start() { + return this.$from.before(this.depth + 1); + } + /** + The position at the end of the range. + */ + get end() { + return this.$to.after(this.depth + 1); + } + /** + The parent node that the range points into. + */ + get parent() { + return this.$from.node(this.depth); + } + /** + The start index of the range in the parent node. + */ + get startIndex() { + return this.$from.index(this.depth); + } + /** + The end index of the range in the parent node. + */ + get endIndex() { + return this.$to.indexAfter(this.depth); + } +}; +var emptyAttrs2 = /* @__PURE__ */ Object.create(null); +var Node2 = class _Node2 { + /** + @internal + */ + constructor(type, attrs, content, marks = Mark3.none) { + this.type = type; + this.attrs = attrs; + this.marks = marks; + this.content = content || Fragment2.empty; + } + /** + The array of this node's child nodes. + */ + get children() { + return this.content.content; + } + /** + The size of this node, as defined by the integer-based [indexing + scheme](https://prosemirror.net/docs/guide/#doc.indexing). For text nodes, this is the + amount of characters. For other leaf nodes, it is one. For + non-leaf nodes, it is the size of the content plus two (the + start and end token). + */ + get nodeSize() { + return this.isLeaf ? 1 : 2 + this.content.size; + } + /** + The number of children that the node has. + */ + get childCount() { + return this.content.childCount; + } + /** + Get the child node at the given index. Raises an error when the + index is out of range. + */ + child(index) { + return this.content.child(index); + } + /** + Get the child node at the given index, if it exists. + */ + maybeChild(index) { + return this.content.maybeChild(index); + } + /** + Call `f` for every child node, passing the node, its offset + into this parent node, and its index. + */ + forEach(f) { + this.content.forEach(f); + } + /** + Invoke a callback for all descendant nodes recursively overlapping + the given two positions that are relative to start of this + node's content. This includes all ancestors of the nodes + containing the two positions. The callback is invoked with the + node, its position relative to the original node (method receiver), + its parent node, and its child index. When the callback returns + false for a given node, that node's children will not be + recursed over. The last parameter can be used to specify a + starting position to count from. + */ + nodesBetween(from3, to, f, startPos = 0) { + this.content.nodesBetween(from3, to, f, startPos, this); + } + /** + Call the given callback for every descendant node. Doesn't + descend into a node when the callback returns `false`. + */ + descendants(f) { + this.nodesBetween(0, this.content.size, f); + } + /** + Concatenates all the text nodes found in this fragment and its + children. + */ + get textContent() { + return this.isLeaf && this.type.spec.leafText ? this.type.spec.leafText(this) : this.textBetween(0, this.content.size, ""); + } + /** + Get all text between positions `from` and `to`. When + `blockSeparator` is given, it will be inserted to separate text + from different block nodes. If `leafText` is given, it'll be + inserted for every non-text leaf node encountered, otherwise + [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used. + */ + textBetween(from3, to, blockSeparator, leafText) { + return this.content.textBetween(from3, to, blockSeparator, leafText); + } + /** + Returns this node's first child, or `null` if there are no + children. + */ + get firstChild() { + return this.content.firstChild; + } + /** + Returns this node's last child, or `null` if there are no + children. + */ + get lastChild() { + return this.content.lastChild; + } + /** + Test whether two nodes represent the same piece of document. + */ + eq(other) { + return this == other || this.sameMarkup(other) && this.content.eq(other.content); + } + /** + Compare the markup (type, attributes, and marks) of this node to + those of another. Returns `true` if both have the same markup. + */ + sameMarkup(other) { + return this.hasMarkup(other.type, other.attrs, other.marks); + } + /** + Check whether this node's markup correspond to the given type, + attributes, and marks. + */ + hasMarkup(type, attrs, marks) { + return this.type == type && compareDeep2(this.attrs, attrs || type.defaultAttrs || emptyAttrs2) && Mark3.sameSet(this.marks, marks || Mark3.none); + } + /** + Create a new node with the same markup as this node, containing + the given content (or empty, if no content is given). + */ + copy(content = null) { + if (content == this.content) + return this; + return new _Node2(this.type, this.attrs, content, this.marks); + } + /** + Create a copy of this node, with the given set of marks instead + of the node's own marks. + */ + mark(marks) { + return marks == this.marks ? this : new _Node2(this.type, this.attrs, this.content, marks); + } + /** + Create a copy of this node with only the content between the + given positions. If `to` is not given, it defaults to the end of + the node. + */ + cut(from3, to = this.content.size) { + if (from3 == 0 && to == this.content.size) + return this; + return this.copy(this.content.cut(from3, to)); + } + /** + Cut out the part of the document between the given positions, and + return it as a `Slice` object. + */ + slice(from3, to = this.content.size, includeParents = false) { + if (from3 == to) + return Slice2.empty; + let $from = this.resolve(from3), $to = this.resolve(to); + let depth = includeParents ? 0 : $from.sharedDepth(to); + let start = $from.start(depth), node = $from.node(depth); + let content = node.content.cut($from.pos - start, $to.pos - start); + return new Slice2(content, $from.depth - depth, $to.depth - depth); + } + /** + Replace the part of the document between the given positions with + the given slice. The slice must 'fit', meaning its open sides + must be able to connect to the surrounding content, and its + content nodes must be valid children for the node they are placed + into. If any of this is violated, an error of type + [`ReplaceError`](https://prosemirror.net/docs/ref/#model.ReplaceError) is thrown. + */ + replace(from3, to, slice2) { + return replace2(this.resolve(from3), this.resolve(to), slice2); + } + /** + Find the node directly after the given position. + */ + nodeAt(pos) { + for (let node = this; ; ) { + let { index, offset } = node.content.findIndex(pos); + node = node.maybeChild(index); + if (!node) + return null; + if (offset == pos || node.isText) + return node; + pos -= offset + 1; + } + } + /** + Find the (direct) child node after the given offset, if any, + and return it along with its index and offset relative to this + node. + */ + childAfter(pos) { + let { index, offset } = this.content.findIndex(pos); + return { node: this.content.maybeChild(index), index, offset }; + } + /** + Find the (direct) child node before the given offset, if any, + and return it along with its index and offset relative to this + node. + */ + childBefore(pos) { + if (pos == 0) + return { node: null, index: 0, offset: 0 }; + let { index, offset } = this.content.findIndex(pos); + if (offset < pos) + return { node: this.content.child(index), index, offset }; + let node = this.content.child(index - 1); + return { node, index: index - 1, offset: offset - node.nodeSize }; + } + /** + Resolve the given position in the document, returning an + [object](https://prosemirror.net/docs/ref/#model.ResolvedPos) with information about its context. + */ + resolve(pos) { + return ResolvedPos2.resolveCached(this, pos); + } + /** + @internal + */ + resolveNoCache(pos) { + return ResolvedPos2.resolve(this, pos); + } + /** + Test whether a given mark or mark type occurs in this document + between the two given positions. + */ + rangeHasMark(from3, to, type) { + let found22 = false; + if (to > from3) + this.nodesBetween(from3, to, (node) => { + if (type.isInSet(node.marks)) + found22 = true; + return !found22; + }); + return found22; + } + /** + True when this is a block (non-inline node) + */ + get isBlock() { + return this.type.isBlock; + } + /** + True when this is a textblock node, a block node with inline + content. + */ + get isTextblock() { + return this.type.isTextblock; + } + /** + True when this node allows inline content. + */ + get inlineContent() { + return this.type.inlineContent; + } + /** + True when this is an inline node (a text node or a node that can + appear among text). + */ + get isInline() { + return this.type.isInline; + } + /** + True when this is a text node. + */ + get isText() { + return this.type.isText; + } + /** + True when this is a leaf node. + */ + get isLeaf() { + return this.type.isLeaf; + } + /** + True when this is an atom, i.e. when it does not have directly + editable content. This is usually the same as `isLeaf`, but can + be configured with the [`atom` property](https://prosemirror.net/docs/ref/#model.NodeSpec.atom) + on a node's spec (typically used when the node is displayed as + an uneditable [node view](https://prosemirror.net/docs/ref/#view.NodeView)). + */ + get isAtom() { + return this.type.isAtom; + } + /** + Return a string representation of this node for debugging + purposes. + */ + toString() { + if (this.type.spec.toDebugString) + return this.type.spec.toDebugString(this); + let name = this.type.name; + if (this.content.size) + name += "(" + this.content.toStringInner() + ")"; + return wrapMarks2(this.marks, name); + } + /** + Get the content match in this node at the given index. + */ + contentMatchAt(index) { + let match2 = this.type.contentMatch.matchFragment(this.content, 0, index); + if (!match2) + throw new Error("Called contentMatchAt on a node with invalid content"); + return match2; + } + /** + Test whether replacing the range between `from` and `to` (by + child index) with the given replacement fragment (which defaults + to the empty fragment) would leave the node's content valid. You + can optionally pass `start` and `end` indices into the + replacement fragment. + */ + canReplace(from3, to, replacement = Fragment2.empty, start = 0, end = replacement.childCount) { + let one = this.contentMatchAt(from3).matchFragment(replacement, start, end); + let two = one && one.matchFragment(this.content, to); + if (!two || !two.validEnd) + return false; + for (let i = start; i < end; i++) + if (!this.type.allowsMarks(replacement.child(i).marks)) + return false; + return true; + } + /** + Test whether replacing the range `from` to `to` (by index) with + a node of the given type would leave the node's content valid. + */ + canReplaceWith(from3, to, type, marks) { + if (marks && !this.type.allowsMarks(marks)) + return false; + let start = this.contentMatchAt(from3).matchType(type); + let end = start && start.matchFragment(this.content, to); + return end ? end.validEnd : false; + } + /** + Test whether the given node's content could be appended to this + node. If that node is empty, this will only return true if there + is at least one node type that can appear in both nodes (to avoid + merging completely incompatible nodes). + */ + canAppend(other) { + if (other.content.size) + return this.canReplace(this.childCount, this.childCount, other.content); + else + return this.type.compatibleContent(other.type); + } + /** + Check whether this node and its descendants conform to the + schema, and raise an exception when they do not. + */ + check() { + this.type.checkContent(this.content); + this.type.checkAttrs(this.attrs); + let copy3 = Mark3.none; + for (let i = 0; i < this.marks.length; i++) { + let mark = this.marks[i]; + mark.type.checkAttrs(mark.attrs); + copy3 = mark.addToSet(copy3); + } + if (!Mark3.sameSet(copy3, this.marks)) + throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map((m2) => m2.type.name)}`); + this.content.forEach((node) => node.check()); + } + /** + Return a JSON-serializeable representation of this node. + */ + toJSON() { + let obj = { type: this.type.name }; + for (let _2 in this.attrs) { + obj.attrs = this.attrs; + break; + } + if (this.content.size) + obj.content = this.content.toJSON(); + if (this.marks.length) + obj.marks = this.marks.map((n) => n.toJSON()); + return obj; + } + /** + Deserialize a node from its JSON representation. + */ + static fromJSON(schema, json) { + if (!json) + throw new RangeError("Invalid input for Node.fromJSON"); + let marks = void 0; + if (json.marks) { + if (!Array.isArray(json.marks)) + throw new RangeError("Invalid mark data for Node.fromJSON"); + marks = json.marks.map(schema.markFromJSON); + } + if (json.type == "text") { + if (typeof json.text != "string") + throw new RangeError("Invalid text node in JSON"); + return schema.text(json.text, marks); + } + let content = Fragment2.fromJSON(schema, json.content); + let node = schema.nodeType(json.type).create(json.attrs, content, marks); + node.type.checkAttrs(node.attrs); + return node; + } +}; +Node2.prototype.text = void 0; +function wrapMarks2(marks, str) { + for (let i = marks.length - 1; i >= 0; i--) + str = marks[i].type.name + "(" + str + ")"; + return str; +} +var ContentMatch2 = class _ContentMatch { + /** + @internal + */ + constructor(validEnd) { + this.validEnd = validEnd; + this.next = []; + this.wrapCache = []; + } + /** + @internal + */ + static parse(string, nodeTypes) { + let stream = new TokenStream2(string, nodeTypes); + if (stream.next == null) + return _ContentMatch.empty; + let expr = parseExpr2(stream); + if (stream.next) + stream.err("Unexpected trailing text"); + let match2 = dfa2(nfa2(expr)); + checkForDeadEnds2(match2, stream); + return match2; + } + /** + Match a node type, returning a match after that node if + successful. + */ + matchType(type) { + for (let i = 0; i < this.next.length; i++) + if (this.next[i].type == type) + return this.next[i].next; + return null; + } + /** + Try to match a fragment. Returns the resulting match when + successful. + */ + matchFragment(frag, start = 0, end = frag.childCount) { + let cur = this; + for (let i = start; cur && i < end; i++) + cur = cur.matchType(frag.child(i).type); + return cur; + } + /** + @internal + */ + get inlineContent() { + return this.next.length != 0 && this.next[0].type.isInline; + } + /** + Get the first matching node type at this match position that can + be generated. + */ + get defaultType() { + for (let i = 0; i < this.next.length; i++) { + let { type } = this.next[i]; + if (!(type.isText || type.hasRequiredAttrs())) + return type; + } + return null; + } + /** + @internal + */ + compatible(other) { + for (let i = 0; i < this.next.length; i++) + for (let j2 = 0; j2 < other.next.length; j2++) + if (this.next[i].type == other.next[j2].type) + return true; + return false; + } + /** + Try to match the given fragment, and if that fails, see if it can + be made to match by inserting nodes in front of it. When + successful, return a fragment of inserted nodes (which may be + empty if nothing had to be inserted). When `toEnd` is true, only + return a fragment if the resulting match goes to the end of the + content expression. + */ + fillBefore(after, toEnd = false, startIndex = 0) { + let seen = [this]; + function search(match2, types) { + let finished = match2.matchFragment(after, startIndex); + if (finished && (!toEnd || finished.validEnd)) + return Fragment2.from(types.map((tp) => tp.createAndFill())); + for (let i = 0; i < match2.next.length; i++) { + let { type, next: next2 } = match2.next[i]; + if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next2) == -1) { + seen.push(next2); + let found22 = search(next2, types.concat(type)); + if (found22) + return found22; + } + } + return null; + } + return search(this, []); + } + /** + Find a set of wrapping node types that would allow a node of the + given type to appear at this position. The result may be empty + (when it fits directly) and will be null when no such wrapping + exists. + */ + findWrapping(target) { + for (let i = 0; i < this.wrapCache.length; i += 2) + if (this.wrapCache[i] == target) + return this.wrapCache[i + 1]; + let computed = this.computeWrapping(target); + this.wrapCache.push(target, computed); + return computed; + } + /** + @internal + */ + computeWrapping(target) { + let seen = /* @__PURE__ */ Object.create(null), active = [{ match: this, type: null, via: null }]; + while (active.length) { + let current = active.shift(), match2 = current.match; + if (match2.matchType(target)) { + let result = []; + for (let obj = current; obj.type; obj = obj.via) + result.push(obj.type); + return result.reverse(); + } + for (let i = 0; i < match2.next.length; i++) { + let { type, next: next2 } = match2.next[i]; + if (!type.isLeaf && !type.hasRequiredAttrs() && !(type.name in seen) && (!current.type || next2.validEnd)) { + active.push({ match: type.contentMatch, type, via: current }); + seen[type.name] = true; + } + } + } + return null; + } + /** + The number of outgoing edges this node has in the finite + automaton that describes the content expression. + */ + get edgeCount() { + return this.next.length; + } + /** + Get the _n_​th outgoing edge from this node in the finite + automaton that describes the content expression. + */ + edge(n) { + if (n >= this.next.length) + throw new RangeError(`There's no ${n}th edge in this content match`); + return this.next[n]; + } + /** + @internal + */ + toString() { + let seen = []; + function scan(m2) { + seen.push(m2); + for (let i = 0; i < m2.next.length; i++) + if (seen.indexOf(m2.next[i].next) == -1) + scan(m2.next[i].next); + } + scan(this); + return seen.map((m2, i) => { + let out = i + (m2.validEnd ? "*" : " ") + " "; + for (let i2 = 0; i2 < m2.next.length; i2++) + out += (i2 ? ", " : "") + m2.next[i2].type.name + "->" + seen.indexOf(m2.next[i2].next); + return out; + }).join("\n"); + } +}; +ContentMatch2.empty = new ContentMatch2(true); +var TokenStream2 = class { + constructor(string, nodeTypes) { + this.string = string; + this.nodeTypes = nodeTypes; + this.inline = null; + this.pos = 0; + this.tokens = string.split(/\s*(?=\b|\W|$)/); + if (this.tokens[this.tokens.length - 1] == "") + this.tokens.pop(); + if (this.tokens[0] == "") + this.tokens.shift(); + } + get next() { + return this.tokens[this.pos]; + } + eat(tok) { + return this.next == tok && (this.pos++ || true); + } + err(str) { + throw new SyntaxError(str + " (in content expression '" + this.string + "')"); + } +}; +function parseExpr2(stream) { + let exprs = []; + do { + exprs.push(parseExprSeq2(stream)); + } while (stream.eat("|")); + return exprs.length == 1 ? exprs[0] : { type: "choice", exprs }; +} +function parseExprSeq2(stream) { + let exprs = []; + do { + exprs.push(parseExprSubscript2(stream)); + } while (stream.next && stream.next != ")" && stream.next != "|"); + return exprs.length == 1 ? exprs[0] : { type: "seq", exprs }; +} +function parseExprSubscript2(stream) { + let expr = parseExprAtom2(stream); + for (; ; ) { + if (stream.eat("+")) + expr = { type: "plus", expr }; + else if (stream.eat("*")) + expr = { type: "star", expr }; + else if (stream.eat("?")) + expr = { type: "opt", expr }; + else if (stream.eat("{")) + expr = parseExprRange2(stream, expr); + else + break; + } + return expr; +} +function parseNum2(stream) { + if (/\D/.test(stream.next)) + stream.err("Expected number, got '" + stream.next + "'"); + let result = Number(stream.next); + stream.pos++; + return result; +} +function parseExprRange2(stream, expr) { + let min2 = parseNum2(stream), max2 = min2; + if (stream.eat(",")) { + if (stream.next != "}") + max2 = parseNum2(stream); + else + max2 = -1; + } + if (!stream.eat("}")) + stream.err("Unclosed braced range"); + return { type: "range", min: min2, max: max2, expr }; +} +function resolveName2(stream, name) { + let types = stream.nodeTypes, type = types[name]; + if (type) + return [type]; + let result = []; + for (let typeName in types) { + let type2 = types[typeName]; + if (type2.isInGroup(name)) + result.push(type2); + } + if (result.length == 0) + stream.err("No node type or group '" + name + "' found"); + return result; +} +function parseExprAtom2(stream) { + if (stream.eat("(")) { + let expr = parseExpr2(stream); + if (!stream.eat(")")) + stream.err("Missing closing paren"); + return expr; + } else if (!/\W/.test(stream.next)) { + let exprs = resolveName2(stream, stream.next).map((type) => { + if (stream.inline == null) + stream.inline = type.isInline; + else if (stream.inline != type.isInline) + stream.err("Mixing inline and block content"); + return { type: "name", value: type }; + }); + stream.pos++; + return exprs.length == 1 ? exprs[0] : { type: "choice", exprs }; + } else { + stream.err("Unexpected token '" + stream.next + "'"); + } +} +function nfa2(expr) { + let nfa22 = [[]]; + connect(compile(expr, 0), node()); + return nfa22; + function node() { + return nfa22.push([]) - 1; + } + function edge(from3, to, term) { + let edge2 = { term, to }; + nfa22[from3].push(edge2); + return edge2; + } + function connect(edges, to) { + edges.forEach((edge2) => edge2.to = to); + } + function compile(expr2, from3) { + if (expr2.type == "choice") { + return expr2.exprs.reduce((out, expr3) => out.concat(compile(expr3, from3)), []); + } else if (expr2.type == "seq") { + for (let i = 0; ; i++) { + let next2 = compile(expr2.exprs[i], from3); + if (i == expr2.exprs.length - 1) + return next2; + connect(next2, from3 = node()); + } + } else if (expr2.type == "star") { + let loop = node(); + edge(from3, loop); + connect(compile(expr2.expr, loop), loop); + return [edge(loop)]; + } else if (expr2.type == "plus") { + let loop = node(); + connect(compile(expr2.expr, from3), loop); + connect(compile(expr2.expr, loop), loop); + return [edge(loop)]; + } else if (expr2.type == "opt") { + return [edge(from3)].concat(compile(expr2.expr, from3)); + } else if (expr2.type == "range") { + let cur = from3; + for (let i = 0; i < expr2.min; i++) { + let next2 = node(); + connect(compile(expr2.expr, cur), next2); + cur = next2; + } + if (expr2.max == -1) { + connect(compile(expr2.expr, cur), cur); + } else { + for (let i = expr2.min; i < expr2.max; i++) { + let next2 = node(); + edge(cur, next2); + connect(compile(expr2.expr, cur), next2); + cur = next2; + } + } + return [edge(cur)]; + } else if (expr2.type == "name") { + return [edge(from3, void 0, expr2.value)]; + } else { + throw new Error("Unknown expr type"); + } + } +} +function cmp2(a, b2) { + return b2 - a; +} +function nullFrom2(nfa22, node) { + let result = []; + scan(node); + return result.sort(cmp2); + function scan(node2) { + let edges = nfa22[node2]; + if (edges.length == 1 && !edges[0].term) + return scan(edges[0].to); + result.push(node2); + for (let i = 0; i < edges.length; i++) { + let { term, to } = edges[i]; + if (!term && result.indexOf(to) == -1) + scan(to); + } + } +} +function dfa2(nfa22) { + let labeled = /* @__PURE__ */ Object.create(null); + return explore(nullFrom2(nfa22, 0)); + function explore(states) { + let out = []; + states.forEach((node) => { + nfa22[node].forEach(({ term, to }) => { + if (!term) + return; + let set; + for (let i = 0; i < out.length; i++) + if (out[i][0] == term) + set = out[i][1]; + nullFrom2(nfa22, to).forEach((node2) => { + if (!set) + out.push([term, set = []]); + if (set.indexOf(node2) == -1) + set.push(node2); + }); + }); + }); + let state = labeled[states.join(",")] = new ContentMatch2(states.indexOf(nfa22.length - 1) > -1); + for (let i = 0; i < out.length; i++) { + let states2 = out[i][1].sort(cmp2); + state.next.push({ type: out[i][0], next: labeled[states2.join(",")] || explore(states2) }); + } + return state; + } +} +function checkForDeadEnds2(match2, stream) { + for (let i = 0, work = [match2]; i < work.length; i++) { + let state = work[i], dead = !state.validEnd, nodes = []; + for (let j2 = 0; j2 < state.next.length; j2++) { + let { type, next: next2 } = state.next[j2]; + nodes.push(type.name); + if (dead && !(type.isText || type.hasRequiredAttrs())) + dead = false; + if (work.indexOf(next2) == -1) + work.push(next2); + } + if (dead) + stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)"); + } +} +var lower162 = 65535; +var factor162 = Math.pow(2, 16); +function makeRecover2(index, offset) { + return index + offset * factor162; +} +function recoverIndex2(value) { + return value & lower162; +} +function recoverOffset2(value) { + return (value - (value & lower162)) / factor162; +} +var DEL_BEFORE2 = 1; +var DEL_AFTER2 = 2; +var DEL_ACROSS2 = 4; +var DEL_SIDE2 = 8; +var MapResult2 = class { + /** + @internal + */ + constructor(pos, delInfo, recover) { + this.pos = pos; + this.delInfo = delInfo; + this.recover = recover; + } + /** + Tells you whether the position was deleted, that is, whether the + step removed the token on the side queried (via the `assoc`) + argument from the document. + */ + get deleted() { + return (this.delInfo & DEL_SIDE2) > 0; + } + /** + Tells you whether the token before the mapped position was deleted. + */ + get deletedBefore() { + return (this.delInfo & (DEL_BEFORE2 | DEL_ACROSS2)) > 0; + } + /** + True when the token after the mapped position was deleted. + */ + get deletedAfter() { + return (this.delInfo & (DEL_AFTER2 | DEL_ACROSS2)) > 0; + } + /** + Tells whether any of the steps mapped through deletes across the + position (including both the token before and after the + position). + */ + get deletedAcross() { + return (this.delInfo & DEL_ACROSS2) > 0; + } +}; +var StepMap2 = class _StepMap { + /** + Create a position map. The modifications to the document are + represented as an array of numbers, in which each group of three + represents a modified chunk as `[start, oldSize, newSize]`. + */ + constructor(ranges, inverted = false) { + this.ranges = ranges; + this.inverted = inverted; + if (!ranges.length && _StepMap.empty) + return _StepMap.empty; + } + /** + @internal + */ + recover(value) { + let diff = 0, index = recoverIndex2(value); + if (!this.inverted) + for (let i = 0; i < index; i++) + diff += this.ranges[i * 3 + 2] - this.ranges[i * 3 + 1]; + return this.ranges[index * 3] + diff + recoverOffset2(value); + } + mapResult(pos, assoc = 1) { + return this._map(pos, assoc, false); + } + map(pos, assoc = 1) { + return this._map(pos, assoc, true); + } + /** + @internal + */ + _map(pos, assoc, simple) { + let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (let i = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) + break; + let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex], end = start + oldSize; + if (pos <= end) { + let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc; + let result = start + diff + (side < 0 ? 0 : newSize); + if (simple) + return result; + let recover = pos == (assoc < 0 ? start : end) ? null : makeRecover2(i / 3, pos - start); + let del2 = pos == start ? DEL_AFTER2 : pos == end ? DEL_BEFORE2 : DEL_ACROSS2; + if (assoc < 0 ? pos != start : pos != end) + del2 |= DEL_SIDE2; + return new MapResult2(result, del2, recover); + } + diff += newSize - oldSize; + } + return simple ? pos + diff : new MapResult2(pos + diff, 0, null); + } + /** + @internal + */ + touches(pos, recover) { + let diff = 0, index = recoverIndex2(recover); + let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (let i = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i] - (this.inverted ? diff : 0); + if (start > pos) + break; + let oldSize = this.ranges[i + oldIndex], end = start + oldSize; + if (pos <= end && i == index * 3) + return true; + diff += this.ranges[i + newIndex] - oldSize; + } + return false; + } + /** + Calls the given function on each of the changed ranges included in + this map. + */ + forEach(f) { + let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (let i = 0, diff = 0; i < this.ranges.length; i += 3) { + let start = this.ranges[i], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff); + let oldSize = this.ranges[i + oldIndex], newSize = this.ranges[i + newIndex]; + f(oldStart, oldStart + oldSize, newStart, newStart + newSize); + diff += newSize - oldSize; + } + } + /** + Create an inverted version of this map. The result can be used to + map positions in the post-step document to the pre-step document. + */ + invert() { + return new _StepMap(this.ranges, !this.inverted); + } + /** + @internal + */ + toString() { + return (this.inverted ? "-" : "") + JSON.stringify(this.ranges); + } + /** + Create a map that moves all positions by offset `n` (which may be + negative). This can be useful when applying steps meant for a + sub-document to a larger document, or vice-versa. + */ + static offset(n) { + return n == 0 ? _StepMap.empty : new _StepMap(n < 0 ? [0, -n, 0] : [0, 0, n]); + } +}; +StepMap2.empty = new StepMap2([]); +var stepsByID2 = /* @__PURE__ */ Object.create(null); +var Step2 = class { + /** + Get the step map that represents the changes made by this step, + and which can be used to transform between positions in the old + and the new document. + */ + getMap() { + return StepMap2.empty; + } + /** + Try to merge this step with another one, to be applied directly + after it. Returns the merged step when possible, null if the + steps can't be merged. + */ + merge(other) { + return null; + } + /** + Deserialize a step from its JSON representation. Will call + through to the step class' own implementation of this method. + */ + static fromJSON(schema, json) { + if (!json || !json.stepType) + throw new RangeError("Invalid input for Step.fromJSON"); + let type = stepsByID2[json.stepType]; + if (!type) + throw new RangeError(`No step type ${json.stepType} defined`); + return type.fromJSON(schema, json); + } + /** + To be able to serialize steps to JSON, each step needs a string + ID to attach to its JSON representation. Use this method to + register an ID for your step classes. Try to pick something + that's unlikely to clash with steps from other modules. + */ + static jsonID(id2, stepClass) { + if (id2 in stepsByID2) + throw new RangeError("Duplicate use of step JSON ID " + id2); + stepsByID2[id2] = stepClass; + stepClass.prototype.jsonID = id2; + return stepClass; + } +}; +var StepResult2 = class _StepResult { + /** + @internal + */ + constructor(doc4, failed) { + this.doc = doc4; + this.failed = failed; + } + /** + Create a successful step result. + */ + static ok(doc4) { + return new _StepResult(doc4, null); + } + /** + Create a failed step result. + */ + static fail(message) { + return new _StepResult(null, message); + } + /** + Call [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) with the given + arguments. Create a successful result if it succeeds, and a + failed one if it throws a `ReplaceError`. + */ + static fromReplace(doc4, from3, to, slice2) { + try { + return _StepResult.ok(doc4.replace(from3, to, slice2)); + } catch (e) { + if (e instanceof ReplaceError2) + return _StepResult.fail(e.message); + throw e; + } + } +}; +function mapFragment2(fragment, f, parent) { + let mapped = []; + for (let i = 0; i < fragment.childCount; i++) { + let child = fragment.child(i); + if (child.content.size) + child = child.copy(mapFragment2(child.content, f, child)); + if (child.isInline) + child = f(child, parent, i); + mapped.push(child); + } + return Fragment2.fromArray(mapped); +} +var AddMarkStep2 = class _AddMarkStep extends Step2 { + /** + Create a mark step. + */ + constructor(from3, to, mark) { + super(); + this.from = from3; + this.to = to; + this.mark = mark; + } + apply(doc4) { + let oldSlice = doc4.slice(this.from, this.to), $from = doc4.resolve(this.from); + let parent = $from.node($from.sharedDepth(this.to)); + let slice2 = new Slice2(mapFragment2(oldSlice.content, (node, parent2) => { + if (!node.isAtom || !parent2.type.allowsMarkType(this.mark.type)) + return node; + return node.mark(this.mark.addToSet(node.marks)); + }, parent), oldSlice.openStart, oldSlice.openEnd); + return StepResult2.fromReplace(doc4, this.from, this.to, slice2); + } + invert() { + return new RemoveMarkStep2(this.from, this.to, this.mark); + } + map(mapping) { + let from3 = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from3.deleted && to.deleted || from3.pos >= to.pos) + return null; + return new _AddMarkStep(from3.pos, to.pos, this.mark); + } + merge(other) { + if (other instanceof _AddMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) + return new _AddMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark); + return null; + } + toJSON() { + return { + stepType: "addMark", + mark: this.mark.toJSON(), + from: this.from, + to: this.to + }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for AddMarkStep.fromJSON"); + return new _AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark)); + } +}; +Step2.jsonID("addMark", AddMarkStep2); +var RemoveMarkStep2 = class _RemoveMarkStep extends Step2 { + /** + Create a mark-removing step. + */ + constructor(from3, to, mark) { + super(); + this.from = from3; + this.to = to; + this.mark = mark; + } + apply(doc4) { + let oldSlice = doc4.slice(this.from, this.to); + let slice2 = new Slice2(mapFragment2(oldSlice.content, (node) => { + return node.mark(this.mark.removeFromSet(node.marks)); + }, doc4), oldSlice.openStart, oldSlice.openEnd); + return StepResult2.fromReplace(doc4, this.from, this.to, slice2); + } + invert() { + return new AddMarkStep2(this.from, this.to, this.mark); + } + map(mapping) { + let from3 = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from3.deleted && to.deleted || from3.pos >= to.pos) + return null; + return new _RemoveMarkStep(from3.pos, to.pos, this.mark); + } + merge(other) { + if (other instanceof _RemoveMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) + return new _RemoveMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark); + return null; + } + toJSON() { + return { + stepType: "removeMark", + mark: this.mark.toJSON(), + from: this.from, + to: this.to + }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for RemoveMarkStep.fromJSON"); + return new _RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark)); + } +}; +Step2.jsonID("removeMark", RemoveMarkStep2); +var AddNodeMarkStep2 = class _AddNodeMarkStep extends Step2 { + /** + Create a node mark step. + */ + constructor(pos, mark) { + super(); + this.pos = pos; + this.mark = mark; + } + apply(doc4) { + let node = doc4.nodeAt(this.pos); + if (!node) + return StepResult2.fail("No node at mark step's position"); + let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks)); + return StepResult2.fromReplace(doc4, this.pos, this.pos + 1, new Slice2(Fragment2.from(updated), 0, node.isLeaf ? 0 : 1)); + } + invert(doc4) { + let node = doc4.nodeAt(this.pos); + if (node) { + let newSet = this.mark.addToSet(node.marks); + if (newSet.length == node.marks.length) { + for (let i = 0; i < node.marks.length; i++) + if (!node.marks[i].isInSet(newSet)) + return new _AddNodeMarkStep(this.pos, node.marks[i]); + return new _AddNodeMarkStep(this.pos, this.mark); + } + } + return new RemoveNodeMarkStep2(this.pos, this.mark); + } + map(mapping) { + let pos = mapping.mapResult(this.pos, 1); + return pos.deletedAfter ? null : new _AddNodeMarkStep(pos.pos, this.mark); + } + toJSON() { + return { stepType: "addNodeMark", pos: this.pos, mark: this.mark.toJSON() }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.pos != "number") + throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON"); + return new _AddNodeMarkStep(json.pos, schema.markFromJSON(json.mark)); + } +}; +Step2.jsonID("addNodeMark", AddNodeMarkStep2); +var RemoveNodeMarkStep2 = class _RemoveNodeMarkStep extends Step2 { + /** + Create a mark-removing step. + */ + constructor(pos, mark) { + super(); + this.pos = pos; + this.mark = mark; + } + apply(doc4) { + let node = doc4.nodeAt(this.pos); + if (!node) + return StepResult2.fail("No node at mark step's position"); + let updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks)); + return StepResult2.fromReplace(doc4, this.pos, this.pos + 1, new Slice2(Fragment2.from(updated), 0, node.isLeaf ? 0 : 1)); + } + invert(doc4) { + let node = doc4.nodeAt(this.pos); + if (!node || !this.mark.isInSet(node.marks)) + return this; + return new AddNodeMarkStep2(this.pos, this.mark); + } + map(mapping) { + let pos = mapping.mapResult(this.pos, 1); + return pos.deletedAfter ? null : new _RemoveNodeMarkStep(pos.pos, this.mark); + } + toJSON() { + return { stepType: "removeNodeMark", pos: this.pos, mark: this.mark.toJSON() }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.pos != "number") + throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON"); + return new _RemoveNodeMarkStep(json.pos, schema.markFromJSON(json.mark)); + } +}; +Step2.jsonID("removeNodeMark", RemoveNodeMarkStep2); +var ReplaceStep2 = class _ReplaceStep extends Step2 { + /** + The given `slice` should fit the 'gap' between `from` and + `to`—the depths must line up, and the surrounding nodes must be + able to be joined with the open sides of the slice. When + `structure` is true, the step will fail if the content between + from and to is not just a sequence of closing and then opening + tokens (this is to guard against rebased replace steps + overwriting something they weren't supposed to). + */ + constructor(from3, to, slice2, structure = false) { + super(); + this.from = from3; + this.to = to; + this.slice = slice2; + this.structure = structure; + } + apply(doc4) { + if (this.structure && contentBetween2(doc4, this.from, this.to)) + return StepResult2.fail("Structure replace would overwrite content"); + return StepResult2.fromReplace(doc4, this.from, this.to, this.slice); + } + getMap() { + return new StepMap2([this.from, this.to - this.from, this.slice.size]); + } + invert(doc4) { + return new _ReplaceStep(this.from, this.from + this.slice.size, doc4.slice(this.from, this.to)); + } + map(mapping) { + let to = mapping.mapResult(this.to, -1); + let from3 = this.from == this.to && _ReplaceStep.MAP_BIAS < 0 ? to : mapping.mapResult(this.from, 1); + if (from3.deletedAcross && to.deletedAcross) + return null; + return new _ReplaceStep(from3.pos, Math.max(from3.pos, to.pos), this.slice, this.structure); + } + merge(other) { + if (!(other instanceof _ReplaceStep) || other.structure || this.structure) + return null; + if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { + let slice2 = this.slice.size + other.slice.size == 0 ? Slice2.empty : new Slice2(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd); + return new _ReplaceStep(this.from, this.to + (other.to - other.from), slice2, this.structure); + } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { + let slice2 = this.slice.size + other.slice.size == 0 ? Slice2.empty : new Slice2(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd); + return new _ReplaceStep(other.from, this.to, slice2, this.structure); + } else { + return null; + } + } + toJSON() { + let json = { stepType: "replace", from: this.from, to: this.to }; + if (this.slice.size) + json.slice = this.slice.toJSON(); + if (this.structure) + json.structure = true; + return json; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for ReplaceStep.fromJSON"); + return new _ReplaceStep(json.from, json.to, Slice2.fromJSON(schema, json.slice), !!json.structure); + } +}; +ReplaceStep2.MAP_BIAS = 1; +Step2.jsonID("replace", ReplaceStep2); +var ReplaceAroundStep2 = class _ReplaceAroundStep extends Step2 { + /** + Create a replace-around step with the given range and gap. + `insert` should be the point in the slice into which the content + of the gap should be moved. `structure` has the same meaning as + it has in the [`ReplaceStep`](https://prosemirror.net/docs/ref/#transform.ReplaceStep) class. + */ + constructor(from3, to, gapFrom, gapTo, slice2, insert, structure = false) { + super(); + this.from = from3; + this.to = to; + this.gapFrom = gapFrom; + this.gapTo = gapTo; + this.slice = slice2; + this.insert = insert; + this.structure = structure; + } + apply(doc4) { + if (this.structure && (contentBetween2(doc4, this.from, this.gapFrom) || contentBetween2(doc4, this.gapTo, this.to))) + return StepResult2.fail("Structure gap-replace would overwrite content"); + let gap = doc4.slice(this.gapFrom, this.gapTo); + if (gap.openStart || gap.openEnd) + return StepResult2.fail("Gap is not a flat range"); + let inserted = this.slice.insertAt(this.insert, gap.content); + if (!inserted) + return StepResult2.fail("Content does not fit in gap"); + return StepResult2.fromReplace(doc4, this.from, this.to, inserted); + } + getMap() { + return new StepMap2([ + this.from, + this.gapFrom - this.from, + this.insert, + this.gapTo, + this.to - this.gapTo, + this.slice.size - this.insert + ]); + } + invert(doc4) { + let gap = this.gapTo - this.gapFrom; + return new _ReplaceAroundStep(this.from, this.from + this.slice.size + gap, this.from + this.insert, this.from + this.insert + gap, doc4.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), this.gapFrom - this.from, this.structure); + } + map(mapping) { + let from3 = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + let gapFrom = this.from == this.gapFrom ? from3.pos : mapping.map(this.gapFrom, -1); + let gapTo = this.to == this.gapTo ? to.pos : mapping.map(this.gapTo, 1); + if (from3.deletedAcross && to.deletedAcross || gapFrom < from3.pos || gapTo > to.pos) + return null; + return new _ReplaceAroundStep(from3.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure); + } + toJSON() { + let json = { + stepType: "replaceAround", + from: this.from, + to: this.to, + gapFrom: this.gapFrom, + gapTo: this.gapTo, + insert: this.insert + }; + if (this.slice.size) + json.slice = this.slice.toJSON(); + if (this.structure) + json.structure = true; + return json; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number" || typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") + throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON"); + return new _ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, Slice2.fromJSON(schema, json.slice), json.insert, !!json.structure); + } +}; +Step2.jsonID("replaceAround", ReplaceAroundStep2); +function contentBetween2(doc4, from3, to) { + let $from = doc4.resolve(from3), dist = to - from3, depth = $from.depth; + while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { + depth--; + dist--; + } + if (dist > 0) { + let next2 = $from.node(depth).maybeChild($from.indexAfter(depth)); + while (dist > 0) { + if (!next2 || next2.isLeaf) + return true; + next2 = next2.firstChild; + dist--; + } + } + return false; +} +var AttrStep2 = class _AttrStep extends Step2 { + /** + Construct an attribute step. + */ + constructor(pos, attr, value) { + super(); + this.pos = pos; + this.attr = attr; + this.value = value; + } + apply(doc4) { + let node = doc4.nodeAt(this.pos); + if (!node) + return StepResult2.fail("No node at attribute step's position"); + let attrs = /* @__PURE__ */ Object.create(null); + for (let name in node.attrs) + attrs[name] = node.attrs[name]; + attrs[this.attr] = this.value; + let updated = node.type.create(attrs, null, node.marks); + return StepResult2.fromReplace(doc4, this.pos, this.pos + 1, new Slice2(Fragment2.from(updated), 0, node.isLeaf ? 0 : 1)); + } + getMap() { + return StepMap2.empty; + } + invert(doc4) { + return new _AttrStep(this.pos, this.attr, doc4.nodeAt(this.pos).attrs[this.attr]); + } + map(mapping) { + let pos = mapping.mapResult(this.pos, 1); + return pos.deletedAfter ? null : new _AttrStep(pos.pos, this.attr, this.value); + } + toJSON() { + return { stepType: "attr", pos: this.pos, attr: this.attr, value: this.value }; + } + static fromJSON(schema, json) { + if (typeof json.pos != "number" || typeof json.attr != "string") + throw new RangeError("Invalid input for AttrStep.fromJSON"); + return new _AttrStep(json.pos, json.attr, json.value); + } +}; +Step2.jsonID("attr", AttrStep2); +var DocAttrStep2 = class _DocAttrStep extends Step2 { + /** + Construct an attribute step. + */ + constructor(attr, value) { + super(); + this.attr = attr; + this.value = value; + } + apply(doc4) { + let attrs = /* @__PURE__ */ Object.create(null); + for (let name in doc4.attrs) + attrs[name] = doc4.attrs[name]; + attrs[this.attr] = this.value; + let updated = doc4.type.create(attrs, doc4.content, doc4.marks); + return StepResult2.ok(updated); + } + getMap() { + return StepMap2.empty; + } + invert(doc4) { + return new _DocAttrStep(this.attr, doc4.attrs[this.attr]); + } + map(mapping) { + return this; + } + toJSON() { + return { stepType: "docAttr", attr: this.attr, value: this.value }; + } + static fromJSON(schema, json) { + if (typeof json.attr != "string") + throw new RangeError("Invalid input for DocAttrStep.fromJSON"); + return new _DocAttrStep(json.attr, json.value); + } +}; +Step2.jsonID("docAttr", DocAttrStep2); +var TransformError3 = class extends Error { +}; +TransformError3 = function TransformError22(message) { + let err = Error.call(this, message); + err.__proto__ = TransformError22.prototype; + return err; +}; +TransformError3.prototype = Object.create(Error.prototype); +TransformError3.prototype.constructor = TransformError3; +TransformError3.prototype.name = "TransformError"; +var classesById2 = /* @__PURE__ */ Object.create(null); +var Selection2 = class { + /** + Initialize a selection with the head and anchor and ranges. If no + ranges are given, constructs a single range across `$anchor` and + `$head`. + */ + constructor($anchor, $head, ranges) { + this.$anchor = $anchor; + this.$head = $head; + this.ranges = ranges || [new SelectionRange2($anchor.min($head), $anchor.max($head))]; + } + /** + The selection's anchor, as an unresolved position. + */ + get anchor() { + return this.$anchor.pos; + } + /** + The selection's head. + */ + get head() { + return this.$head.pos; + } + /** + The lower bound of the selection's main range. + */ + get from() { + return this.$from.pos; + } + /** + The upper bound of the selection's main range. + */ + get to() { + return this.$to.pos; + } + /** + The resolved lower bound of the selection's main range. + */ + get $from() { + return this.ranges[0].$from; + } + /** + The resolved upper bound of the selection's main range. + */ + get $to() { + return this.ranges[0].$to; + } + /** + Indicates whether the selection contains any content. + */ + get empty() { + let ranges = this.ranges; + for (let i = 0; i < ranges.length; i++) + if (ranges[i].$from.pos != ranges[i].$to.pos) + return false; + return true; + } + /** + Get the content of this selection as a slice. + */ + content() { + return this.$from.doc.slice(this.from, this.to, true); + } + /** + Replace the selection with a slice or, if no slice is given, + delete the selection. Will append to the given transaction. + */ + replace(tr2, content = Slice2.empty) { + let lastNode = content.content.lastChild, lastParent = null; + for (let i = 0; i < content.openEnd; i++) { + lastParent = lastNode; + lastNode = lastNode.lastChild; + } + let mapFrom = tr2.steps.length, ranges = this.ranges; + for (let i = 0; i < ranges.length; i++) { + let { $from, $to } = ranges[i], mapping = tr2.mapping.slice(mapFrom); + tr2.replaceRange(mapping.map($from.pos), mapping.map($to.pos), i ? Slice2.empty : content); + if (i == 0) + selectionToInsertionEnd3(tr2, mapFrom, (lastNode ? lastNode.isInline : lastParent && lastParent.isTextblock) ? -1 : 1); + } + } + /** + Replace the selection with the given node, appending the changes + to the given transaction. + */ + replaceWith(tr2, node) { + let mapFrom = tr2.steps.length, ranges = this.ranges; + for (let i = 0; i < ranges.length; i++) { + let { $from, $to } = ranges[i], mapping = tr2.mapping.slice(mapFrom); + let from3 = mapping.map($from.pos), to = mapping.map($to.pos); + if (i) { + tr2.deleteRange(from3, to); + } else { + tr2.replaceRangeWith(from3, to, node); + selectionToInsertionEnd3(tr2, mapFrom, node.isInline ? -1 : 1); + } + } + } + /** + Find a valid cursor or leaf node selection starting at the given + position and searching back if `dir` is negative, and forward if + positive. When `textOnly` is true, only consider cursor + selections. Will return null when no valid selection position is + found. + */ + static findFrom($pos, dir, textOnly = false) { + let inner = $pos.parent.inlineContent ? new TextSelection2($pos) : findSelectionIn2($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly); + if (inner) + return inner; + for (let depth = $pos.depth - 1; depth >= 0; depth--) { + let found22 = dir < 0 ? findSelectionIn2($pos.node(0), $pos.node(depth), $pos.before(depth + 1), $pos.index(depth), dir, textOnly) : findSelectionIn2($pos.node(0), $pos.node(depth), $pos.after(depth + 1), $pos.index(depth) + 1, dir, textOnly); + if (found22) + return found22; + } + return null; + } + /** + Find a valid cursor or leaf node selection near the given + position. Searches forward first by default, but if `bias` is + negative, it will search backwards first. + */ + static near($pos, bias = 1) { + return this.findFrom($pos, bias) || this.findFrom($pos, -bias) || new AllSelection2($pos.node(0)); + } + /** + Find the cursor or leaf node selection closest to the start of + the given document. Will return an + [`AllSelection`](https://prosemirror.net/docs/ref/#state.AllSelection) if no valid position + exists. + */ + static atStart(doc4) { + return findSelectionIn2(doc4, doc4, 0, 0, 1) || new AllSelection2(doc4); + } + /** + Find the cursor or leaf node selection closest to the end of the + given document. + */ + static atEnd(doc4) { + return findSelectionIn2(doc4, doc4, doc4.content.size, doc4.childCount, -1) || new AllSelection2(doc4); + } + /** + Deserialize the JSON representation of a selection. Must be + implemented for custom classes (as a static class method). + */ + static fromJSON(doc4, json) { + if (!json || !json.type) + throw new RangeError("Invalid input for Selection.fromJSON"); + let cls = classesById2[json.type]; + if (!cls) + throw new RangeError(`No selection type ${json.type} defined`); + return cls.fromJSON(doc4, json); + } + /** + To be able to deserialize selections from JSON, custom selection + classes must register themselves with an ID string, so that they + can be disambiguated. Try to pick something that's unlikely to + clash with classes from other modules. + */ + static jsonID(id2, selectionClass) { + if (id2 in classesById2) + throw new RangeError("Duplicate use of selection JSON ID " + id2); + classesById2[id2] = selectionClass; + selectionClass.prototype.jsonID = id2; + return selectionClass; + } + /** + Get a [bookmark](https://prosemirror.net/docs/ref/#state.SelectionBookmark) for this selection, + which is a value that can be mapped without having access to a + current document, and later resolved to a real selection for a + given document again. (This is used mostly by the history to + track and restore old selections.) The default implementation of + this method just converts the selection to a text selection and + returns the bookmark for that. + */ + getBookmark() { + return TextSelection2.between(this.$anchor, this.$head).getBookmark(); + } +}; +Selection2.prototype.visible = true; +var SelectionRange2 = class { + /** + Create a range. + */ + constructor($from, $to) { + this.$from = $from; + this.$to = $to; + } +}; +var warnedAboutTextSelection2 = false; +function checkTextSelection2($pos) { + if (!warnedAboutTextSelection2 && !$pos.parent.inlineContent) { + warnedAboutTextSelection2 = true; + console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")"); + } +} +var TextSelection2 = class _TextSelection extends Selection2 { + /** + Construct a text selection between the given points. + */ + constructor($anchor, $head = $anchor) { + checkTextSelection2($anchor); + checkTextSelection2($head); + super($anchor, $head); + } + /** + Returns a resolved position if this is a cursor selection (an + empty text selection), and null otherwise. + */ + get $cursor() { + return this.$anchor.pos == this.$head.pos ? this.$head : null; + } + map(doc4, mapping) { + let $head = doc4.resolve(mapping.map(this.head)); + if (!$head.parent.inlineContent) + return Selection2.near($head); + let $anchor = doc4.resolve(mapping.map(this.anchor)); + return new _TextSelection($anchor.parent.inlineContent ? $anchor : $head, $head); + } + replace(tr2, content = Slice2.empty) { + super.replace(tr2, content); + if (content == Slice2.empty) { + let marks = this.$from.marksAcross(this.$to); + if (marks) + tr2.ensureMarks(marks); + } + } + eq(other) { + return other instanceof _TextSelection && other.anchor == this.anchor && other.head == this.head; + } + getBookmark() { + return new TextBookmark2(this.anchor, this.head); + } + toJSON() { + return { type: "text", anchor: this.anchor, head: this.head }; + } + /** + @internal + */ + static fromJSON(doc4, json) { + if (typeof json.anchor != "number" || typeof json.head != "number") + throw new RangeError("Invalid input for TextSelection.fromJSON"); + return new _TextSelection(doc4.resolve(json.anchor), doc4.resolve(json.head)); + } + /** + Create a text selection from non-resolved positions. + */ + static create(doc4, anchor, head = anchor) { + let $anchor = doc4.resolve(anchor); + return new this($anchor, head == anchor ? $anchor : doc4.resolve(head)); + } + /** + Return a text selection that spans the given positions or, if + they aren't text positions, find a text selection near them. + `bias` determines whether the method searches forward (default) + or backwards (negative number) first. Will fall back to calling + [`Selection.near`](https://prosemirror.net/docs/ref/#state.Selection^near) when the document + doesn't contain a valid text position. + */ + static between($anchor, $head, bias) { + let dPos = $anchor.pos - $head.pos; + if (!bias || dPos) + bias = dPos >= 0 ? 1 : -1; + if (!$head.parent.inlineContent) { + let found22 = Selection2.findFrom($head, bias, true) || Selection2.findFrom($head, -bias, true); + if (found22) + $head = found22.$head; + else + return Selection2.near($head, bias); + } + if (!$anchor.parent.inlineContent) { + if (dPos == 0) { + $anchor = $head; + } else { + $anchor = (Selection2.findFrom($anchor, -bias, true) || Selection2.findFrom($anchor, bias, true)).$anchor; + if ($anchor.pos < $head.pos != dPos < 0) + $anchor = $head; + } + } + return new _TextSelection($anchor, $head); + } +}; +Selection2.jsonID("text", TextSelection2); +var TextBookmark2 = class _TextBookmark { + constructor(anchor, head) { + this.anchor = anchor; + this.head = head; + } + map(mapping) { + return new _TextBookmark(mapping.map(this.anchor), mapping.map(this.head)); + } + resolve(doc4) { + return TextSelection2.between(doc4.resolve(this.anchor), doc4.resolve(this.head)); + } +}; +var NodeSelection2 = class _NodeSelection extends Selection2 { + /** + Create a node selection. Does not verify the validity of its + argument. + */ + constructor($pos) { + let node = $pos.nodeAfter; + let $end = $pos.node(0).resolve($pos.pos + node.nodeSize); + super($pos, $end); + this.node = node; + } + map(doc4, mapping) { + let { deleted, pos } = mapping.mapResult(this.anchor); + let $pos = doc4.resolve(pos); + if (deleted) + return Selection2.near($pos); + return new _NodeSelection($pos); + } + content() { + return new Slice2(Fragment2.from(this.node), 0, 0); + } + eq(other) { + return other instanceof _NodeSelection && other.anchor == this.anchor; + } + toJSON() { + return { type: "node", anchor: this.anchor }; + } + getBookmark() { + return new NodeBookmark2(this.anchor); + } + /** + @internal + */ + static fromJSON(doc4, json) { + if (typeof json.anchor != "number") + throw new RangeError("Invalid input for NodeSelection.fromJSON"); + return new _NodeSelection(doc4.resolve(json.anchor)); + } + /** + Create a node selection from non-resolved positions. + */ + static create(doc4, from3) { + return new _NodeSelection(doc4.resolve(from3)); + } + /** + Determines whether the given node may be selected as a node + selection. + */ + static isSelectable(node) { + return !node.isText && node.type.spec.selectable !== false; + } +}; +NodeSelection2.prototype.visible = false; +Selection2.jsonID("node", NodeSelection2); +var NodeBookmark2 = class _NodeBookmark { + constructor(anchor) { + this.anchor = anchor; + } + map(mapping) { + let { deleted, pos } = mapping.mapResult(this.anchor); + return deleted ? new TextBookmark2(pos, pos) : new _NodeBookmark(pos); + } + resolve(doc4) { + let $pos = doc4.resolve(this.anchor), node = $pos.nodeAfter; + if (node && NodeSelection2.isSelectable(node)) + return new NodeSelection2($pos); + return Selection2.near($pos); + } +}; +var AllSelection2 = class _AllSelection extends Selection2 { + /** + Create an all-selection over the given document. + */ + constructor(doc4) { + super(doc4.resolve(0), doc4.resolve(doc4.content.size)); + } + replace(tr2, content = Slice2.empty) { + if (content == Slice2.empty) { + tr2.delete(0, tr2.doc.content.size); + let sel = Selection2.atStart(tr2.doc); + if (!sel.eq(tr2.selection)) + tr2.setSelection(sel); + } else { + super.replace(tr2, content); + } + } + toJSON() { + return { type: "all" }; + } + /** + @internal + */ + static fromJSON(doc4) { + return new _AllSelection(doc4); + } + map(doc4) { + return new _AllSelection(doc4); + } + eq(other) { + return other instanceof _AllSelection; + } + getBookmark() { + return AllBookmark2; + } +}; +Selection2.jsonID("all", AllSelection2); +var AllBookmark2 = { + map() { + return this; + }, + resolve(doc4) { + return new AllSelection2(doc4); + } +}; +function findSelectionIn2(doc4, node, pos, index, dir, text2 = false) { + if (node.inlineContent) + return TextSelection2.create(doc4, pos); + for (let i = index - (dir > 0 ? 0 : 1); dir > 0 ? i < node.childCount : i >= 0; i += dir) { + let child = node.child(i); + if (!child.isAtom) { + let inner = findSelectionIn2(doc4, child, pos + dir, dir < 0 ? child.childCount : 0, dir, text2); + if (inner) + return inner; + } else if (!text2 && NodeSelection2.isSelectable(child)) { + return NodeSelection2.create(doc4, pos - (dir < 0 ? child.nodeSize : 0)); + } + pos += child.nodeSize * dir; + } + return null; +} +function selectionToInsertionEnd3(tr2, startLen, bias) { + let last2 = tr2.steps.length - 1; + if (last2 < startLen) + return; + let step = tr2.steps[last2]; + if (!(step instanceof ReplaceStep2 || step instanceof ReplaceAroundStep2)) + return; + let map4 = tr2.mapping.maps[last2], end; + map4.forEach((_from, _to, _newFrom, newTo) => { + if (end == null) + end = newTo; + }); + tr2.setSelection(Selection2.near(tr2.doc.resolve(end), bias)); +} +function bind2(f, self) { + return !self || !f ? f : f.bind(self); +} +var FieldDesc2 = class { + constructor(name, desc, self) { + this.name = name; + this.init = bind2(desc.init, self); + this.apply = bind2(desc.apply, self); + } +}; +var baseFields2 = [ + new FieldDesc2("doc", { + init(config) { + return config.doc || config.schema.topNodeType.createAndFill(); + }, + apply(tr2) { + return tr2.doc; + } + }), + new FieldDesc2("selection", { + init(config, instance) { + return config.selection || Selection2.atStart(instance.doc); + }, + apply(tr2) { + return tr2.selection; + } + }), + new FieldDesc2("storedMarks", { + init(config) { + return config.storedMarks || null; + }, + apply(tr2, _marks, _old, state) { + return state.selection.$cursor ? tr2.storedMarks : null; + } + }), + new FieldDesc2("scrollToSelection", { + init() { + return 0; + }, + apply(tr2, prev) { + return tr2.scrolledIntoView ? prev + 1 : prev; + } + }) +]; +var handleBackspace = (editor, type) => { + var _a; + const { state, view } = editor; + const { selection } = state; + if (!selection.empty) return false; + const { $from } = selection; + if ($from.parentOffset !== 0) return false; + const parentDepth = $from.depth - 1; + const parent = $from.node(parentDepth); + const index = $from.index(parentDepth); + if (index === 0) return false; + if (parent.type === type) { + return editor.commands.lift(type.name); + } + const previous = parent.child(index - 1); + if (previous.type !== type || !((_a = previous.lastChild) == null ? void 0 : _a.isTextblock)) { + return false; + } + const blockStart = $from.before(); + const insideBlockquoteEnd = blockStart - 1; + const targetPos = insideBlockquoteEnd - 1; + const { tr: tr2 } = state; + tr2.delete(blockStart, $from.after()).insert(targetPos, $from.parent.content); + tr2.setSelection(TextSelection2.create(tr2.doc, targetPos)); + view.dispatch(tr2.scrollIntoView()); + return true; +}; +var inputRegex = /^\s*>\s$/; +var Blockquote = Node3.create({ + name: "blockquote", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + content: "block+", + group: "block", + defining: true, + parseHTML() { + return [{ tag: "blockquote" }]; + }, + renderHTML({ HTMLAttributes }) { + return /* @__PURE__ */ h("blockquote", { ...mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), children: /* @__PURE__ */ h("slot", {}) }); + }, + parseMarkdown: (token, helpers) => { + var _a; + const parseBlockChildren = (_a = helpers.parseBlockChildren) != null ? _a : helpers.parseChildren; + return helpers.createNode("blockquote", void 0, parseBlockChildren(token.tokens || [])); + }, + renderMarkdown: (node, h2) => { + if (!node.content) { + return ""; + } + const prefix = ">"; + const result = []; + node.content.forEach((child, index) => { + var _a, _b; + const childContent = (_b = (_a = h2.renderChild) == null ? void 0 : _a.call(h2, child, index)) != null ? _b : h2.renderChildren([child]); + const lines = childContent.split("\n"); + const linesWithPrefix = lines.map((line) => { + if (line.trim() === "") { + return prefix; + } + return `${prefix} ${line}`; + }); + result.push(linesWithPrefix.join("\n")); + }); + return result.join(` +${prefix} +`); + }, + addCommands() { + return { + setBlockquote: () => ({ commands }) => { + return commands.wrapIn(this.name); + }, + toggleBlockquote: () => ({ commands }) => { + return commands.toggleWrap(this.name); + }, + unsetBlockquote: () => ({ commands }) => { + return commands.lift(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Shift-b": () => this.editor.commands.toggleBlockquote(), + Backspace: () => handleBackspace(this.editor, this.type) + }; + }, + addInputRules() { + return [ + wrappingInputRule({ + find: inputRegex, + type: this.type + }) + ]; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-bold@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-bold/dist/index.js +var starInputRegex = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))$/; +var starPasteRegex = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))/g; +var underscoreInputRegex = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))$/; +var underscorePasteRegex = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))/g; +var Bold = Mark2.create({ + name: "bold", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + parseHTML() { + return [ + { + tag: "strong" + }, + { + tag: "b", + getAttrs: (node) => node.style.fontWeight !== "normal" && null + }, + { + style: "font-weight=400", + clearMark: (mark) => mark.type.name === this.name + }, + { + style: "font-weight", + getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null + } + ]; + }, + renderHTML({ HTMLAttributes }) { + return /* @__PURE__ */ h("strong", { ...mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), children: /* @__PURE__ */ h("slot", {}) }); + }, + markdownTokenName: "strong", + parseMarkdown: (token, helpers) => { + return helpers.applyMark("bold", helpers.parseInline(token.tokens || [])); + }, + markdownOptions: { + htmlReopen: { + open: "", + close: "" + } + }, + renderMarkdown: (node, h2) => { + return `**${h2.renderChildren(node)}**`; + }, + addCommands() { + return { + setBold: () => ({ commands }) => { + return commands.setMark(this.name); + }, + toggleBold: () => ({ commands }) => { + return commands.toggleMark(this.name); + }, + unsetBold: () => ({ commands }) => { + return commands.unsetMark(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-b": () => this.editor.commands.toggleBold(), + "Mod-B": () => this.editor.commands.toggleBold() + }; + }, + addInputRules() { + return [ + markInputRule({ + find: starInputRegex, + type: this.type + }), + markInputRule({ + find: underscoreInputRegex, + type: this.type + }) + ]; + }, + addPasteRules() { + return [ + markPasteRule({ + find: starPasteRegex, + type: this.type + }), + markPasteRule({ + find: underscorePasteRegex, + type: this.type + }) + ]; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-code@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-code/dist/index.js +var inputRegexMatch = (text2) => { + const match2 = /`([^`]+)`(?!`)$/.exec(text2); + if (!match2) { + return null; + } + if (match2.index > 0 && text2[match2.index - 1] === "`") { + return null; + } + return { + index: match2.index, + text: match2[0], + replaceWith: match2[1] + }; +}; +var pasteRegexMatch = (text2) => { + const regex = /`([^`]+)`(?!`)/g; + const matches2 = []; + let match2; + while ((match2 = regex.exec(text2)) !== null) { + if (match2.index > 0 && text2[match2.index - 1] === "`") { + continue; + } + matches2.push({ + index: match2.index, + text: match2[0], + replaceWith: match2[1] + }); + } + return matches2; +}; +var Code = Mark2.create({ + name: "code", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + excludes: "_", + code: true, + exitable: true, + parseHTML() { + return [{ tag: "code" }]; + }, + renderHTML({ HTMLAttributes }) { + return ["code", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + markdownTokenName: "codespan", + parseMarkdown: (token, helpers) => { + return helpers.applyMark("code", [{ type: "text", text: token.text || "" }]); + }, + renderMarkdown: (node, h2) => { + if (!node.content) { + return ""; + } + return `\`${h2.renderChildren(node.content)}\``; + }, + addCommands() { + return { + setCode: () => ({ commands }) => { + return commands.setMark(this.name); + }, + toggleCode: () => ({ commands }) => { + return commands.toggleMark(this.name); + }, + unsetCode: () => ({ commands }) => { + return commands.unsetMark(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-e": () => this.editor.commands.toggleCode() + }; + }, + addInputRules() { + return [ + markInputRule({ + find: inputRegexMatch, + type: this.type + }) + ]; + }, + addPasteRules() { + return [ + markPasteRule({ + find: pasteRegexMatch, + type: this.type + }) + ]; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-code-block@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0__@tiptap+pm@3.26.0/node_modules/@tiptap/extension-code-block/dist/index.js +var DEFAULT_TAB_SIZE = 4; +var backtickInputRegex = /^```([a-z]+)?[\s\n]$/; +var tildeInputRegex = /^~~~([a-z]+)?[\s\n]$/; +var CodeBlock = Node3.create({ + name: "codeBlock", + addOptions() { + return { + languageClassPrefix: "language-", + exitOnTripleEnter: true, + exitOnArrowDown: true, + defaultLanguage: null, + enableTabIndentation: false, + tabSize: DEFAULT_TAB_SIZE, + HTMLAttributes: {} + }; + }, + content: "text*", + marks: "", + group: "block", + code: true, + defining: true, + addAttributes() { + return { + language: { + default: this.options.defaultLanguage, + parseHTML: (element2) => { + var _a; + const { languageClassPrefix } = this.options; + if (!languageClassPrefix) { + return null; + } + const classNames = [...((_a = element2.firstElementChild) == null ? void 0 : _a.classList) || []]; + const languages = classNames.filter((className) => className.startsWith(languageClassPrefix)).map((className) => className.replace(languageClassPrefix, "")); + const language = languages[0]; + if (!language) { + return null; + } + return language; + }, + rendered: false + } + }; + }, + parseHTML() { + return [ + { + tag: "pre", + preserveWhitespace: "full" + } + ]; + }, + renderHTML({ node, HTMLAttributes }) { + return [ + "pre", + mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), + [ + "code", + { + class: node.attrs.language ? this.options.languageClassPrefix + node.attrs.language : null + }, + 0 + ] + ]; + }, + markdownTokenName: "code", + parseMarkdown: (token, helpers) => { + var _a, _b; + if (((_a = token.raw) == null ? void 0 : _a.startsWith("```")) === false && ((_b = token.raw) == null ? void 0 : _b.startsWith("~~~")) === false && token.codeBlockStyle !== "indented") { + return []; + } + return helpers.createNode( + "codeBlock", + { language: token.lang || null }, + token.text ? [helpers.createTextNode(token.text)] : [] + ); + }, + renderMarkdown: (node, h2) => { + var _a; + let output = ""; + const language = ((_a = node.attrs) == null ? void 0 : _a.language) || ""; + if (!node.content) { + output = `\`\`\`${language} + +\`\`\``; + } else { + const lines = [`\`\`\`${language}`, h2.renderChildren(node.content), "```"]; + output = lines.join("\n"); + } + return output; + }, + addCommands() { + return { + setCodeBlock: (attributes) => ({ commands }) => { + return commands.setNode(this.name, attributes); + }, + toggleCodeBlock: (attributes) => ({ commands }) => { + return commands.toggleNode(this.name, "paragraph", attributes); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Alt-c": () => this.editor.commands.toggleCodeBlock(), + // remove code block when at start of document or code block is empty + Backspace: () => { + const { empty: empty2, $anchor } = this.editor.state.selection; + const isAtStart = $anchor.pos === 1; + if (!empty2 || $anchor.parent.type.name !== this.name) { + return false; + } + if (isAtStart || !$anchor.parent.textContent.length) { + return this.editor.commands.clearNodes(); + } + return false; + }, + // handle tab indentation + Tab: ({ editor }) => { + var _a; + if (!this.options.enableTabIndentation) { + return false; + } + const tabSize = (_a = this.options.tabSize) != null ? _a : DEFAULT_TAB_SIZE; + const { state } = editor; + const { selection } = state; + const { $from, empty: empty2 } = selection; + if ($from.parent.type !== this.type) { + return false; + } + const indent = " ".repeat(tabSize); + if (empty2) { + return editor.commands.insertContent(indent); + } + return editor.commands.command(({ tr: tr2 }) => { + const { from: from3, to } = selection; + const text2 = state.doc.textBetween(from3, to, "\n", "\n"); + const lines = text2.split("\n"); + const indentedText = lines.map((line) => indent + line).join("\n"); + tr2.replaceWith(from3, to, state.schema.text(indentedText)); + return true; + }); + }, + // handle shift+tab reverse indentation + "Shift-Tab": ({ editor }) => { + var _a; + if (!this.options.enableTabIndentation) { + return false; + } + const tabSize = (_a = this.options.tabSize) != null ? _a : DEFAULT_TAB_SIZE; + const { state } = editor; + const { selection } = state; + const { $from, empty: empty2 } = selection; + if ($from.parent.type !== this.type) { + return false; + } + if (empty2) { + return editor.commands.command(({ tr: tr2 }) => { + var _a2; + const { pos } = $from; + const codeBlockStart = $from.start(); + const codeBlockEnd = $from.end(); + const allText = state.doc.textBetween(codeBlockStart, codeBlockEnd, "\n", "\n"); + const lines = allText.split("\n"); + let currentLineIndex = 0; + let charCount = 0; + const relativeCursorPos = pos - codeBlockStart; + for (let i = 0; i < lines.length; i += 1) { + if (charCount + lines[i].length >= relativeCursorPos) { + currentLineIndex = i; + break; + } + charCount += lines[i].length + 1; + } + const currentLine = lines[currentLineIndex]; + const leadingSpaces = ((_a2 = currentLine.match(/^ */)) == null ? void 0 : _a2[0]) || ""; + const spacesToRemove = Math.min(leadingSpaces.length, tabSize); + if (spacesToRemove === 0) { + return true; + } + let lineStartPos = codeBlockStart; + for (let i = 0; i < currentLineIndex; i += 1) { + lineStartPos += lines[i].length + 1; + } + tr2.delete(lineStartPos, lineStartPos + spacesToRemove); + const cursorPosInLine = pos - lineStartPos; + if (cursorPosInLine <= spacesToRemove) { + tr2.setSelection(TextSelection.create(tr2.doc, lineStartPos)); + } + return true; + }); + } + return editor.commands.command(({ tr: tr2 }) => { + const { from: from3, to } = selection; + const text2 = state.doc.textBetween(from3, to, "\n", "\n"); + const lines = text2.split("\n"); + const reverseIndentText = lines.map((line) => { + var _a2; + const leadingSpaces = ((_a2 = line.match(/^ */)) == null ? void 0 : _a2[0]) || ""; + const spacesToRemove = Math.min(leadingSpaces.length, tabSize); + return line.slice(spacesToRemove); + }).join("\n"); + tr2.replaceWith(from3, to, state.schema.text(reverseIndentText)); + return true; + }); + }, + // exit node on triple enter + Enter: ({ editor }) => { + if (!this.options.exitOnTripleEnter) { + return false; + } + const { state } = editor; + const { selection } = state; + const { $from, empty: empty2 } = selection; + if (!empty2 || $from.parent.type !== this.type) { + return false; + } + const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2; + const endsWithDoubleNewline = $from.parent.textContent.endsWith("\n\n"); + if (!isAtEnd || !endsWithDoubleNewline) { + return false; + } + return editor.chain().command(({ tr: tr2 }) => { + tr2.delete($from.pos - 2, $from.pos); + return true; + }).exitCode().run(); + }, + // exit node on arrow down + ArrowDown: ({ editor }) => { + if (!this.options.exitOnArrowDown) { + return false; + } + const { state } = editor; + const { selection, doc: doc4 } = state; + const { $from, empty: empty2 } = selection; + if (!empty2 || $from.parent.type !== this.type) { + return false; + } + const isAtEnd = $from.parentOffset === $from.parent.nodeSize - 2; + if (!isAtEnd) { + return false; + } + const after = $from.after(); + if (after === void 0) { + return false; + } + const nodeAfter = doc4.nodeAt(after); + if (nodeAfter) { + return editor.commands.command(({ tr: tr2 }) => { + tr2.setSelection(Selection.near(doc4.resolve(after))); + return true; + }); + } + return editor.commands.exitCode(); + } + }; + }, + addInputRules() { + return [ + textblockTypeInputRule({ + find: backtickInputRegex, + type: this.type, + getAttributes: (match2) => ({ + language: match2[1] + }) + }), + textblockTypeInputRule({ + find: tildeInputRegex, + type: this.type, + getAttributes: (match2) => ({ + language: match2[1] + }) + }) + ]; + }, + addProseMirrorPlugins() { + return [ + // this plugin creates a code block for pasted content from VS Code + // we can also detect the copied code language + new Plugin({ + key: new PluginKey("codeBlockVSCodeHandler"), + props: { + handlePaste: (view, event) => { + if (!event.clipboardData) { + return false; + } + if (this.editor.isActive(this.type.name)) { + return false; + } + const text2 = event.clipboardData.getData("text/plain"); + const vscode = event.clipboardData.getData("vscode-editor-data"); + const vscodeData = vscode ? JSON.parse(vscode) : void 0; + const language = vscodeData == null ? void 0 : vscodeData.mode; + if (!text2 || !language) { + return false; + } + const { tr: tr2, schema } = view.state; + const textNode = schema.text(text2.replace(/\r\n?/g, "\n")); + tr2.replaceSelectionWith(this.type.create({ language }, textNode)); + if (tr2.selection.$from.parent.type !== this.type) { + tr2.setSelection( + TextSelection.near(tr2.doc.resolve(Math.max(0, tr2.selection.from - 2))) + ); + } + tr2.setMeta("paste", true); + view.dispatch(tr2); + return true; + } + } + }) + ]; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-document@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-document/dist/index.js +var Document = Node3.create({ + name: "doc", + topNode: true, + content: "block+", + renderMarkdown: (node, h2) => { + if (!node.content) { + return ""; + } + return h2.renderChildren(node.content, "\n\n"); + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-hard-break@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-hard-break/dist/index.js +var HardBreak = Node3.create({ + name: "hardBreak", + markdownTokenName: "br", + addOptions() { + return { + keepMarks: true, + HTMLAttributes: {} + }; + }, + inline: true, + group: "inline", + selectable: false, + linebreakReplacement: true, + parseHTML() { + return [{ tag: "br" }]; + }, + renderHTML({ HTMLAttributes }) { + return ["br", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)]; + }, + renderText() { + return "\n"; + }, + renderMarkdown: () => ` +`, + parseMarkdown: () => { + return { + type: "hardBreak" + }; + }, + addCommands() { + return { + setHardBreak: () => ({ commands, chain, state, editor }) => { + return commands.first([ + () => commands.exitCode(), + () => commands.command(() => { + const { selection, storedMarks } = state; + if (selection.$from.parent.type.spec.isolating) { + return false; + } + const { keepMarks } = this.options; + const { splittableMarks } = editor.extensionManager; + const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks(); + return chain().insertContent({ type: this.name }).command(({ tr: tr2, dispatch }) => { + if (dispatch && marks && keepMarks) { + const filteredMarks = marks.filter( + (mark) => splittableMarks.includes(mark.type.name) + ); + tr2.ensureMarks(filteredMarks); + } + return true; + }).run(); + }) + ]); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Enter": () => this.editor.commands.setHardBreak(), + "Shift-Enter": () => this.editor.commands.setHardBreak() + }; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-heading@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-heading/dist/index.js +var Heading = Node3.create({ + name: "heading", + addOptions() { + return { + levels: [1, 2, 3, 4, 5, 6], + HTMLAttributes: {} + }; + }, + content: "inline*", + group: "block", + defining: true, + addAttributes() { + return { + level: { + default: 1, + rendered: false + } + }; + }, + parseHTML() { + return this.options.levels.map((level) => ({ + tag: `h${level}`, + attrs: { level } + })); + }, + renderHTML({ node, HTMLAttributes }) { + const hasLevel = this.options.levels.includes(node.attrs.level); + const level = hasLevel ? node.attrs.level : this.options.levels[0]; + return [`h${level}`, mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + parseMarkdown: (token, helpers) => { + return helpers.createNode( + "heading", + { level: token.depth || 1 }, + helpers.parseInline(token.tokens || []) + ); + }, + renderMarkdown: (node, h2) => { + var _a; + const level = ((_a = node.attrs) == null ? void 0 : _a.level) ? parseInt(node.attrs.level, 10) : 1; + const headingChars = "#".repeat(level); + if (!node.content) { + return ""; + } + return `${headingChars} ${h2.renderChildren(node.content)}`; + }, + addCommands() { + return { + setHeading: (attributes) => ({ commands }) => { + if (!this.options.levels.includes(attributes.level)) { + return false; + } + return commands.setNode(this.name, attributes); + }, + toggleHeading: (attributes) => ({ commands }) => { + if (!this.options.levels.includes(attributes.level)) { + return false; + } + return commands.toggleNode(this.name, "paragraph", attributes); + } + }; + }, + addKeyboardShortcuts() { + return this.options.levels.reduce( + (items, level) => ({ + ...items, + [`Mod-Alt-${level}`]: () => this.editor.commands.toggleHeading({ level }) + }), + {} + ); + }, + addInputRules() { + return this.options.levels.map((level) => { + return textblockTypeInputRule({ + find: new RegExp(`^(#{${Math.min(...this.options.levels)},${level}})\\s$`), + type: this.type, + getAttributes: { + level + } + }); + }); + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-horizontal-rule@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0__@tiptap+pm@3.26.0/node_modules/@tiptap/extension-horizontal-rule/dist/index.js +var HorizontalRule = Node3.create({ + name: "horizontalRule", + addOptions() { + return { + HTMLAttributes: {}, + nextNodeType: "paragraph" + }; + }, + group: "block", + parseHTML() { + return [{ tag: "hr" }]; + }, + renderHTML({ HTMLAttributes }) { + return ["hr", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)]; + }, + markdownTokenName: "hr", + parseMarkdown: (token, helpers) => { + return helpers.createNode("horizontalRule"); + }, + renderMarkdown: () => { + return "---"; + }, + addCommands() { + return { + setHorizontalRule: () => ({ chain, state }) => { + if (!canInsertNode(state, state.schema.nodes[this.name])) { + return false; + } + const { selection } = state; + const { $to: $originTo } = selection; + const currentChain = chain(); + if (isNodeSelection(selection)) { + currentChain.insertContentAt($originTo.pos, { + type: this.name + }); + } else { + currentChain.insertContent({ type: this.name }); + } + return currentChain.command(({ state: chainState, tr: tr2, dispatch }) => { + if (dispatch) { + const { $to } = tr2.selection; + const posAfter = $to.end(); + if ($to.nodeAfter) { + if ($to.nodeAfter.isTextblock) { + tr2.setSelection(TextSelection.create(tr2.doc, $to.pos + 1)); + } else if ($to.nodeAfter.isBlock) { + tr2.setSelection(NodeSelection.create(tr2.doc, $to.pos)); + } else { + tr2.setSelection(TextSelection.create(tr2.doc, $to.pos)); + } + } else { + const nodeType = chainState.schema.nodes[this.options.nextNodeType] || $to.parent.type.contentMatch.defaultType; + const node = nodeType == null ? void 0 : nodeType.create(); + if (node) { + tr2.insert(posAfter, node); + tr2.setSelection(TextSelection.create(tr2.doc, posAfter + 1)); + } + } + tr2.scrollIntoView(); + } + return true; + }).run(); + } + }; + }, + addInputRules() { + return [ + nodeInputRule({ + find: /^(?:---|—-|___\s|\*\*\*\s)$/, + type: this.type + }) + ]; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-italic@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-italic/dist/index.js +var starInputRegex2 = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))$/; +var starPasteRegex2 = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))/g; +var underscoreInputRegex2 = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))$/; +var underscorePasteRegex2 = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))/g; +var Italic = Mark2.create({ + name: "italic", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + parseHTML() { + return [ + { + tag: "em" + }, + { + tag: "i", + getAttrs: (node) => node.style.fontStyle !== "normal" && null + }, + { + style: "font-style=normal", + clearMark: (mark) => mark.type.name === this.name + }, + { + style: "font-style=italic" + } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["em", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + addCommands() { + return { + setItalic: () => ({ commands }) => { + return commands.setMark(this.name); + }, + toggleItalic: () => ({ commands }) => { + return commands.toggleMark(this.name); + }, + unsetItalic: () => ({ commands }) => { + return commands.unsetMark(this.name); + } + }; + }, + markdownTokenName: "em", + parseMarkdown: (token, helpers) => { + return helpers.applyMark("italic", helpers.parseInline(token.tokens || [])); + }, + markdownOptions: { + htmlReopen: { + open: "", + close: "" + } + }, + renderMarkdown: (node, h2) => { + return `*${h2.renderChildren(node)}*`; + }, + addKeyboardShortcuts() { + return { + "Mod-i": () => this.editor.commands.toggleItalic(), + "Mod-I": () => this.editor.commands.toggleItalic() + }; + }, + addInputRules() { + return [ + markInputRule({ + find: starInputRegex2, + type: this.type + }), + markInputRule({ + find: underscoreInputRegex2, + type: this.type + }) + ]; + }, + addPasteRules() { + return [ + markPasteRule({ + find: starPasteRegex2, + type: this.type + }), + markPasteRule({ + find: underscorePasteRegex2, + type: this.type + }) + ]; + } +}); + +// ../../node_modules/.pnpm/linkifyjs@4.3.3/node_modules/linkifyjs/dist/linkify.mjs +var encodedTlds = "aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2odyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rck0msd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5m\xF6gensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2oodside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2"; +var encodedUtlds = "\u03B5\u03BB1\u03C52\u0431\u04331\u0435\u043B3\u0434\u0435\u0442\u04384\u0435\u044E2\u043A\u0430\u0442\u043E\u043B\u0438\u043A6\u043E\u043C3\u043C\u043A\u04342\u043E\u043D1\u0441\u043A\u0432\u04306\u043E\u043D\u043B\u0430\u0439\u043D5\u0440\u04333\u0440\u0443\u04412\u04442\u0441\u0430\u0439\u04423\u0440\u04313\u0443\u043A\u04403\u049B\u0430\u04373\u0570\u0561\u05753\u05D9\u05E9\u05E8\u05D0\u05DC5\u05E7\u05D5\u05DD3\u0627\u0628\u0648\u0638\u0628\u064A5\u0631\u0627\u0645\u0643\u06485\u0644\u0627\u0631\u062F\u06464\u0628\u062D\u0631\u064A\u06465\u062C\u0632\u0627\u0626\u06315\u0633\u0639\u0648\u062F\u064A\u06296\u0639\u0644\u064A\u0627\u06465\u0645\u063A\u0631\u06285\u0645\u0627\u0631\u0627\u062A5\u06CC\u0631\u0627\u06465\u0628\u0627\u0631\u062A2\u0632\u0627\u06314\u064A\u062A\u06433\u06BE\u0627\u0631\u062A5\u062A\u0648\u0646\u06334\u0633\u0648\u062F\u0627\u06463\u0631\u064A\u06295\u0634\u0628\u0643\u06294\u0639\u0631\u0627\u06422\u06282\u0645\u0627\u06464\u0641\u0644\u0633\u0637\u064A\u06466\u0642\u0637\u06313\u0643\u0627\u062B\u0648\u0644\u064A\u06436\u0648\u06453\u0645\u0635\u06312\u0644\u064A\u0633\u064A\u06275\u0648\u0631\u064A\u062A\u0627\u0646\u064A\u06277\u0642\u06394\u0647\u0645\u0631\u0627\u06475\u067E\u0627\u06A9\u0633\u062A\u0627\u06467\u0680\u0627\u0631\u062A4\u0915\u0949\u092E3\u0928\u0947\u091F3\u092D\u093E\u0930\u09240\u092E\u094D3\u094B\u09245\u0938\u0902\u0917\u0920\u09285\u09AC\u09BE\u0982\u09B2\u09BE5\u09AD\u09BE\u09B0\u09A42\u09F0\u09A44\u0A2D\u0A3E\u0A30\u0A244\u0AAD\u0ABE\u0AB0\u0AA44\u0B2D\u0B3E\u0B30\u0B244\u0B87\u0BA8\u0BCD\u0BA4\u0BBF\u0BAF\u0BBE6\u0BB2\u0B99\u0BCD\u0B95\u0BC86\u0B9A\u0BBF\u0B99\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0BC2\u0BB0\u0BCD11\u0C2D\u0C3E\u0C30\u0C24\u0C4D5\u0CAD\u0CBE\u0CB0\u0CA44\u0D2D\u0D3E\u0D30\u0D24\u0D025\u0DBD\u0D82\u0D9A\u0DCF4\u0E04\u0E2D\u0E213\u0E44\u0E17\u0E223\u0EA5\u0EB2\u0EA73\u10D2\u10D42\u307F\u3093\u306A3\u30A2\u30DE\u30BE\u30F34\u30AF\u30E9\u30A6\u30C94\u30B0\u30FC\u30B0\u30EB4\u30B3\u30E02\u30B9\u30C8\u30A23\u30BB\u30FC\u30EB3\u30D5\u30A1\u30C3\u30B7\u30E7\u30F36\u30DD\u30A4\u30F3\u30C84\u4E16\u754C2\u4E2D\u4FE11\u56FD1\u570B1\u6587\u7F513\u4E9A\u9A6C\u900A3\u4F01\u4E1A2\u4F5B\u5C712\u4FE1\u606F2\u5065\u5EB72\u516B\u53662\u516C\u53F81\u76CA2\u53F0\u6E7E1\u70632\u5546\u57CE1\u5E971\u68072\u5609\u91CC0\u5927\u9152\u5E975\u5728\u7EBF2\u5927\u62FF2\u5929\u4E3B\u65593\u5A31\u4E502\u5BB6\u96FB2\u5E7F\u4E1C2\u5FAE\u535A2\u6148\u55842\u6211\u7231\u4F603\u624B\u673A2\u62DB\u80582\u653F\u52A11\u5E9C2\u65B0\u52A0\u57612\u95FB2\u65F6\u5C1A2\u66F8\u7C4D2\u673A\u67842\u6DE1\u9A6C\u95213\u6E38\u620F2\u6FB3\u95802\u70B9\u770B2\u79FB\u52A82\u7EC4\u7EC7\u673A\u67844\u7F51\u57401\u5E971\u7AD91\u7EDC2\u8054\u901A2\u8C37\u6B4C2\u8D2D\u72692\u901A\u8CA92\u96C6\u56E22\u96FB\u8A0A\u76C8\u79D14\u98DE\u5229\u6D663\u98DF\u54C12\u9910\u53852\u9999\u683C\u91CC\u62C93\u6E2F2\uB2F7\uB1371\uCEF42\uC0BC\uC1312\uD55C\uAD6D2"; +var numeric = "numeric"; +var ascii = "ascii"; +var alpha = "alpha"; +var asciinumeric = "asciinumeric"; +var alphanumeric = "alphanumeric"; +var domain = "domain"; +var emoji = "emoji"; +var scheme = "scheme"; +var slashscheme = "slashscheme"; +var whitespace = "whitespace"; +function registerGroup(name, groups) { + if (!(name in groups)) { + groups[name] = []; + } + return groups[name]; +} +function addToGroups(t, flags, groups) { + if (flags[numeric]) { + flags[asciinumeric] = true; + flags[alphanumeric] = true; + } + if (flags[ascii]) { + flags[asciinumeric] = true; + flags[alpha] = true; + } + if (flags[asciinumeric]) { + flags[alphanumeric] = true; + } + if (flags[alpha]) { + flags[alphanumeric] = true; + } + if (flags[alphanumeric]) { + flags[domain] = true; + } + if (flags[emoji]) { + flags[domain] = true; + } + for (const k in flags) { + const group = registerGroup(k, groups); + if (group.indexOf(t) < 0) { + group.push(t); + } + } +} +function flagsForToken(t, groups) { + const result = {}; + for (const c in groups) { + if (groups[c].indexOf(t) >= 0) { + result[c] = true; + } + } + return result; +} +function State(token = null) { + this.j = {}; + this.jr = []; + this.jd = null; + this.t = token; +} +State.groups = {}; +State.prototype = { + accepts() { + return !!this.t; + }, + /** + * Follow an existing transition from the given input to the next state. + * Does not mutate. + * @param {string} input character or token type to transition on + * @returns {?State} the next state, if any + */ + go(input) { + const state = this; + const nextState = state.j[input]; + if (nextState) { + return nextState; + } + for (let i = 0; i < state.jr.length; i++) { + const regex = state.jr[i][0]; + const nextState2 = state.jr[i][1]; + if (nextState2 && regex.test(input)) { + return nextState2; + } + } + return state.jd; + }, + /** + * Whether the state has a transition for the given input. Set the second + * argument to true to only look for an exact match (and not a default or + * regular-expression-based transition) + * @param {string} input + * @param {boolean} exactOnly + */ + has(input, exactOnly = false) { + return exactOnly ? input in this.j : !!this.go(input); + }, + /** + * Short for "transition all"; create a transition from the array of items + * in the given list to the same final resulting state. + * @param {string | string[]} inputs Group of inputs to transition on + * @param {Transition | State} [next] Transition options + * @param {Flags} [flags] Collections flags to add token to + * @param {Collections} [groups] Master list of token groups + */ + ta(inputs, next2, flags, groups) { + for (let i = 0; i < inputs.length; i++) { + this.tt(inputs[i], next2, flags, groups); + } + }, + /** + * Short for "take regexp transition"; defines a transition for this state + * when it encounters a token which matches the given regular expression + * @param {RegExp} regexp Regular expression transition (populate first) + * @param {T | State} [next] Transition options + * @param {Flags} [flags] Collections flags to add token to + * @param {Collections} [groups] Master list of token groups + * @returns {State} taken after the given input + */ + tr(regexp, next2, flags, groups) { + groups = groups || State.groups; + let nextState; + if (next2 && next2.j) { + nextState = next2; + } else { + nextState = new State(next2); + if (flags && groups) { + addToGroups(next2, flags, groups); + } + } + this.jr.push([regexp, nextState]); + return nextState; + }, + /** + * Short for "take transitions", will take as many sequential transitions as + * the length of the given input and returns the + * resulting final state. + * @param {string | string[]} input + * @param {T | State} [next] Transition options + * @param {Flags} [flags] Collections flags to add token to + * @param {Collections} [groups] Master list of token groups + * @returns {State} taken after the given input + */ + ts(input, next2, flags, groups) { + let state = this; + const len = input.length; + if (!len) { + return state; + } + for (let i = 0; i < len - 1; i++) { + state = state.tt(input[i]); + } + return state.tt(input[len - 1], next2, flags, groups); + }, + /** + * Short for "take transition", this is a method for building/working with + * state machines. + * + * If a state already exists for the given input, returns it. + * + * If a token is specified, that state will emit that token when reached by + * the linkify engine. + * + * If no state exists, it will be initialized with some default transitions + * that resemble existing default transitions. + * + * If a state is given for the second argument, that state will be + * transitioned to on the given input regardless of what that input + * previously did. + * + * Specify a token group flags to define groups that this token belongs to. + * The token will be added to corresponding entires in the given groups + * object. + * + * @param {string} input character, token type to transition on + * @param {T | State} [next] Transition options + * @param {Flags} [flags] Collections flags to add token to + * @param {Collections} [groups] Master list of groups + * @returns {State} taken after the given input + */ + tt(input, next2, flags, groups) { + groups = groups || State.groups; + const state = this; + if (next2 && next2.j) { + state.j[input] = next2; + return next2; + } + const t = next2; + let nextState, templateState = state.go(input); + if (templateState) { + nextState = new State(); + Object.assign(nextState.j, templateState.j); + nextState.jr.push.apply(nextState.jr, templateState.jr); + nextState.jd = templateState.jd; + nextState.t = templateState.t; + } else { + nextState = new State(); + } + if (t) { + if (groups) { + if (nextState.t && typeof nextState.t === "string") { + const allFlags = Object.assign(flagsForToken(nextState.t, groups), flags); + addToGroups(t, allFlags, groups); + } else if (flags) { + addToGroups(t, flags, groups); + } + } + nextState.t = t; + } + state.j[input] = nextState; + return nextState; + } +}; +var ta = (state, input, next2, flags, groups) => state.ta(input, next2, flags, groups); +var tr = (state, regexp, next2, flags, groups) => state.tr(regexp, next2, flags, groups); +var ts = (state, input, next2, flags, groups) => state.ts(input, next2, flags, groups); +var tt = (state, input, next2, flags, groups) => state.tt(input, next2, flags, groups); +var WORD = "WORD"; +var UWORD = "UWORD"; +var ASCIINUMERICAL = "ASCIINUMERICAL"; +var ALPHANUMERICAL = "ALPHANUMERICAL"; +var LOCALHOST = "LOCALHOST"; +var TLD = "TLD"; +var UTLD = "UTLD"; +var SCHEME = "SCHEME"; +var SLASH_SCHEME = "SLASH_SCHEME"; +var NUM = "NUM"; +var WS = "WS"; +var NL = "NL"; +var OPENBRACE = "OPENBRACE"; +var CLOSEBRACE = "CLOSEBRACE"; +var OPENBRACKET = "OPENBRACKET"; +var CLOSEBRACKET = "CLOSEBRACKET"; +var OPENPAREN = "OPENPAREN"; +var CLOSEPAREN = "CLOSEPAREN"; +var OPENANGLEBRACKET = "OPENANGLEBRACKET"; +var CLOSEANGLEBRACKET = "CLOSEANGLEBRACKET"; +var FULLWIDTHLEFTPAREN = "FULLWIDTHLEFTPAREN"; +var FULLWIDTHRIGHTPAREN = "FULLWIDTHRIGHTPAREN"; +var LEFTCORNERBRACKET = "LEFTCORNERBRACKET"; +var RIGHTCORNERBRACKET = "RIGHTCORNERBRACKET"; +var LEFTWHITECORNERBRACKET = "LEFTWHITECORNERBRACKET"; +var RIGHTWHITECORNERBRACKET = "RIGHTWHITECORNERBRACKET"; +var FULLWIDTHLESSTHAN = "FULLWIDTHLESSTHAN"; +var FULLWIDTHGREATERTHAN = "FULLWIDTHGREATERTHAN"; +var AMPERSAND = "AMPERSAND"; +var APOSTROPHE = "APOSTROPHE"; +var ASTERISK = "ASTERISK"; +var AT = "AT"; +var BACKSLASH = "BACKSLASH"; +var BACKTICK = "BACKTICK"; +var CARET = "CARET"; +var COLON = "COLON"; +var COMMA = "COMMA"; +var DOLLAR = "DOLLAR"; +var DOT = "DOT"; +var EQUALS = "EQUALS"; +var EXCLAMATION = "EXCLAMATION"; +var HYPHEN = "HYPHEN"; +var PERCENT = "PERCENT"; +var PIPE = "PIPE"; +var PLUS = "PLUS"; +var POUND = "POUND"; +var QUERY = "QUERY"; +var QUOTE = "QUOTE"; +var FULLWIDTHMIDDLEDOT = "FULLWIDTHMIDDLEDOT"; +var SEMI = "SEMI"; +var SLASH = "SLASH"; +var TILDE = "TILDE"; +var UNDERSCORE = "UNDERSCORE"; +var EMOJI$1 = "EMOJI"; +var SYM = "SYM"; +var tk = /* @__PURE__ */ Object.freeze({ + __proto__: null, + ALPHANUMERICAL, + AMPERSAND, + APOSTROPHE, + ASCIINUMERICAL, + ASTERISK, + AT, + BACKSLASH, + BACKTICK, + CARET, + CLOSEANGLEBRACKET, + CLOSEBRACE, + CLOSEBRACKET, + CLOSEPAREN, + COLON, + COMMA, + DOLLAR, + DOT, + EMOJI: EMOJI$1, + EQUALS, + EXCLAMATION, + FULLWIDTHGREATERTHAN, + FULLWIDTHLEFTPAREN, + FULLWIDTHLESSTHAN, + FULLWIDTHMIDDLEDOT, + FULLWIDTHRIGHTPAREN, + HYPHEN, + LEFTCORNERBRACKET, + LEFTWHITECORNERBRACKET, + LOCALHOST, + NL, + NUM, + OPENANGLEBRACKET, + OPENBRACE, + OPENBRACKET, + OPENPAREN, + PERCENT, + PIPE, + PLUS, + POUND, + QUERY, + QUOTE, + RIGHTCORNERBRACKET, + RIGHTWHITECORNERBRACKET, + SCHEME, + SEMI, + SLASH, + SLASH_SCHEME, + SYM, + TILDE, + TLD, + UNDERSCORE, + UTLD, + UWORD, + WORD, + WS +}); +var ASCII_LETTER = /[a-z]/; +var LETTER = /\p{L}/u; +var EMOJI = /\p{Emoji}/u; +var DIGIT = /\d/; +var SPACE = /\s/; +var CR = "\r"; +var LF = "\n"; +var EMOJI_VARIATION = "\uFE0F"; +var EMOJI_JOINER = "\u200D"; +var OBJECT_REPLACEMENT = "\uFFFC"; +var tlds = null; +var utlds = null; +function init$2(customSchemes = []) { + const groups = {}; + State.groups = groups; + const Start = new State(); + if (tlds == null) { + tlds = decodeTlds(encodedTlds); + } + if (utlds == null) { + utlds = decodeTlds(encodedUtlds); + } + tt(Start, "'", APOSTROPHE); + tt(Start, "{", OPENBRACE); + tt(Start, "}", CLOSEBRACE); + tt(Start, "[", OPENBRACKET); + tt(Start, "]", CLOSEBRACKET); + tt(Start, "(", OPENPAREN); + tt(Start, ")", CLOSEPAREN); + tt(Start, "<", OPENANGLEBRACKET); + tt(Start, ">", CLOSEANGLEBRACKET); + tt(Start, "\uFF08", FULLWIDTHLEFTPAREN); + tt(Start, "\uFF09", FULLWIDTHRIGHTPAREN); + tt(Start, "\u300C", LEFTCORNERBRACKET); + tt(Start, "\u300D", RIGHTCORNERBRACKET); + tt(Start, "\u300E", LEFTWHITECORNERBRACKET); + tt(Start, "\u300F", RIGHTWHITECORNERBRACKET); + tt(Start, "\uFF1C", FULLWIDTHLESSTHAN); + tt(Start, "\uFF1E", FULLWIDTHGREATERTHAN); + tt(Start, "&", AMPERSAND); + tt(Start, "*", ASTERISK); + tt(Start, "@", AT); + tt(Start, "`", BACKTICK); + tt(Start, "^", CARET); + tt(Start, ":", COLON); + tt(Start, ",", COMMA); + tt(Start, "$", DOLLAR); + tt(Start, ".", DOT); + tt(Start, "=", EQUALS); + tt(Start, "!", EXCLAMATION); + tt(Start, "-", HYPHEN); + tt(Start, "%", PERCENT); + tt(Start, "|", PIPE); + tt(Start, "+", PLUS); + tt(Start, "#", POUND); + tt(Start, "?", QUERY); + tt(Start, '"', QUOTE); + tt(Start, "/", SLASH); + tt(Start, ";", SEMI); + tt(Start, "~", TILDE); + tt(Start, "_", UNDERSCORE); + tt(Start, "\\", BACKSLASH); + tt(Start, "\u30FB", FULLWIDTHMIDDLEDOT); + const Num = tr(Start, DIGIT, NUM, { + [numeric]: true + }); + tr(Num, DIGIT, Num); + const Asciinumeric = tr(Num, ASCII_LETTER, ASCIINUMERICAL, { + [asciinumeric]: true + }); + const Alphanumeric = tr(Num, LETTER, ALPHANUMERICAL, { + [alphanumeric]: true + }); + const Word = tr(Start, ASCII_LETTER, WORD, { + [ascii]: true + }); + tr(Word, DIGIT, Asciinumeric); + tr(Word, ASCII_LETTER, Word); + tr(Asciinumeric, DIGIT, Asciinumeric); + tr(Asciinumeric, ASCII_LETTER, Asciinumeric); + const UWord = tr(Start, LETTER, UWORD, { + [alpha]: true + }); + tr(UWord, ASCII_LETTER); + tr(UWord, DIGIT, Alphanumeric); + tr(UWord, LETTER, UWord); + tr(Alphanumeric, DIGIT, Alphanumeric); + tr(Alphanumeric, ASCII_LETTER); + tr(Alphanumeric, LETTER, Alphanumeric); + const Nl2 = tt(Start, LF, NL, { + [whitespace]: true + }); + const Cr = tt(Start, CR, WS, { + [whitespace]: true + }); + const Ws = tr(Start, SPACE, WS, { + [whitespace]: true + }); + tt(Start, OBJECT_REPLACEMENT, Ws); + tt(Cr, LF, Nl2); + tt(Cr, OBJECT_REPLACEMENT, Ws); + tr(Cr, SPACE, Ws); + tt(Ws, CR); + tt(Ws, LF); + tr(Ws, SPACE, Ws); + tt(Ws, OBJECT_REPLACEMENT, Ws); + const Emoji = tr(Start, EMOJI, EMOJI$1, { + [emoji]: true + }); + tt(Emoji, "#"); + tr(Emoji, EMOJI, Emoji); + tt(Emoji, EMOJI_VARIATION, Emoji); + const EmojiJoiner = tt(Emoji, EMOJI_JOINER); + tt(EmojiJoiner, "#"); + tr(EmojiJoiner, EMOJI, Emoji); + const wordjr = [[ASCII_LETTER, Word], [DIGIT, Asciinumeric]]; + const uwordjr = [[ASCII_LETTER, null], [LETTER, UWord], [DIGIT, Alphanumeric]]; + for (let i = 0; i < tlds.length; i++) { + fastts(Start, tlds[i], TLD, WORD, wordjr); + } + for (let i = 0; i < utlds.length; i++) { + fastts(Start, utlds[i], UTLD, UWORD, uwordjr); + } + addToGroups(TLD, { + tld: true, + ascii: true + }, groups); + addToGroups(UTLD, { + utld: true, + alpha: true + }, groups); + fastts(Start, "file", SCHEME, WORD, wordjr); + fastts(Start, "mailto", SCHEME, WORD, wordjr); + fastts(Start, "http", SLASH_SCHEME, WORD, wordjr); + fastts(Start, "https", SLASH_SCHEME, WORD, wordjr); + fastts(Start, "ftp", SLASH_SCHEME, WORD, wordjr); + fastts(Start, "ftps", SLASH_SCHEME, WORD, wordjr); + addToGroups(SCHEME, { + scheme: true, + ascii: true + }, groups); + addToGroups(SLASH_SCHEME, { + slashscheme: true, + ascii: true + }, groups); + customSchemes = customSchemes.sort((a, b2) => a[0] > b2[0] ? 1 : -1); + for (let i = 0; i < customSchemes.length; i++) { + const sch = customSchemes[i][0]; + const optionalSlashSlash = customSchemes[i][1]; + const flags = optionalSlashSlash ? { + [scheme]: true + } : { + [slashscheme]: true + }; + if (sch.indexOf("-") >= 0) { + flags[domain] = true; + } else if (!ASCII_LETTER.test(sch)) { + flags[numeric] = true; + } else if (DIGIT.test(sch)) { + flags[asciinumeric] = true; + } else { + flags[ascii] = true; + } + ts(Start, sch, sch, flags); + } + ts(Start, "localhost", LOCALHOST, { + ascii: true + }); + Start.jd = new State(SYM); + return { + start: Start, + tokens: Object.assign({ + groups + }, tk) + }; +} +function run$1(start, str) { + const iterable = stringToArray(str.replace(/[A-Z]/g, (c) => c.toLowerCase())); + const charCount = iterable.length; + const tokens = []; + let cursor = 0; + let charCursor = 0; + while (charCursor < charCount) { + let state = start; + let nextState = null; + let tokenLength = 0; + let latestAccepting = null; + let sinceAccepts = -1; + let charsSinceAccepts = -1; + while (charCursor < charCount && (nextState = state.go(iterable[charCursor]))) { + state = nextState; + if (state.accepts()) { + sinceAccepts = 0; + charsSinceAccepts = 0; + latestAccepting = state; + } else if (sinceAccepts >= 0) { + sinceAccepts += iterable[charCursor].length; + charsSinceAccepts++; + } + tokenLength += iterable[charCursor].length; + cursor += iterable[charCursor].length; + charCursor++; + } + cursor -= sinceAccepts; + charCursor -= charsSinceAccepts; + tokenLength -= sinceAccepts; + tokens.push({ + t: latestAccepting.t, + // token type/name + v: str.slice(cursor - tokenLength, cursor), + // string value + s: cursor - tokenLength, + // start index + e: cursor + // end index (excluding) + }); + } + return tokens; +} +function stringToArray(str) { + const result = []; + const len = str.length; + let index = 0; + while (index < len) { + let first2 = str.charCodeAt(index); + let second; + let char = first2 < 55296 || first2 > 56319 || index + 1 === len || (second = str.charCodeAt(index + 1)) < 56320 || second > 57343 ? str[index] : str.slice(index, index + 2); + result.push(char); + index += char.length; + } + return result; +} +function fastts(state, input, t, defaultt, jr) { + let next2; + const len = input.length; + for (let i = 0; i < len - 1; i++) { + const char = input[i]; + if (state.j[char]) { + next2 = state.j[char]; + } else { + next2 = new State(defaultt); + next2.jr = jr.slice(); + state.j[char] = next2; + } + state = next2; + } + next2 = new State(t); + next2.jr = jr.slice(); + state.j[input[len - 1]] = next2; + return next2; +} +function decodeTlds(encoded) { + const words = []; + const stack = []; + let i = 0; + let digits = "0123456789"; + while (i < encoded.length) { + let popDigitCount = 0; + while (digits.indexOf(encoded[i + popDigitCount]) >= 0) { + popDigitCount++; + } + if (popDigitCount > 0) { + words.push(stack.join("")); + for (let popCount = parseInt(encoded.substring(i, i + popDigitCount), 10); popCount > 0; popCount--) { + stack.pop(); + } + i += popDigitCount; + } else { + stack.push(encoded[i]); + i++; + } + } + return words; +} +var defaults = { + defaultProtocol: "http", + events: null, + format: noop, + formatHref: noop, + nl2br: false, + tagName: "a", + target: null, + rel: null, + validate: true, + truncate: Infinity, + className: null, + attributes: null, + ignoreTags: [], + render: null +}; +function Options(opts, defaultRender = null) { + let o = Object.assign({}, defaults); + if (opts) { + o = Object.assign(o, opts instanceof Options ? opts.o : opts); + } + const ignoredTags = o.ignoreTags; + const uppercaseIgnoredTags = []; + for (let i = 0; i < ignoredTags.length; i++) { + uppercaseIgnoredTags.push(ignoredTags[i].toUpperCase()); + } + this.o = o; + if (defaultRender) { + this.defaultRender = defaultRender; + } + this.ignoreTags = uppercaseIgnoredTags; +} +Options.prototype = { + o: defaults, + /** + * @type string[] + */ + ignoreTags: [], + /** + * @param {IntermediateRepresentation} ir + * @returns {any} + */ + defaultRender(ir) { + return ir; + }, + /** + * Returns true or false based on whether a token should be displayed as a + * link based on the user options. + * @param {MultiToken} token + * @returns {boolean} + */ + check(token) { + return this.get("validate", token.toString(), token); + }, + // Private methods + /** + * Resolve an option's value based on the value of the option and the given + * params. If operator and token are specified and the target option is + * callable, automatically calls the function with the given argument. + * @template {keyof Opts} K + * @param {K} key Name of option to use + * @param {string} [operator] will be passed to the target option if it's a + * function. If not specified, RAW function value gets returned + * @param {MultiToken} [token] The token from linkify.tokenize + * @returns {Opts[K] | any} + */ + get(key, operator, token) { + const isCallable = operator != null; + let option = this.o[key]; + if (!option) { + return option; + } + if (typeof option === "object") { + option = token.t in option ? option[token.t] : defaults[key]; + if (typeof option === "function" && isCallable) { + option = option(operator, token); + } + } else if (typeof option === "function" && isCallable) { + option = option(operator, token.t, token); + } + return option; + }, + /** + * @template {keyof Opts} L + * @param {L} key Name of options object to use + * @param {string} [operator] + * @param {MultiToken} [token] + * @returns {Opts[L] | any} + */ + getObj(key, operator, token) { + let obj = this.o[key]; + if (typeof obj === "function" && operator != null) { + obj = obj(operator, token.t, token); + } + return obj; + }, + /** + * Convert the given token to a rendered element that may be added to the + * calling-interface's DOM + * @param {MultiToken} token Token to render to an HTML element + * @returns {any} Render result; e.g., HTML string, DOM element, React + * Component, etc. + */ + render(token) { + const ir = token.render(this); + const renderFn = this.get("render", null, token) || this.defaultRender; + return renderFn(ir, token.t, token); + } +}; +function noop(val) { + return val; +} +function MultiToken(value, tokens) { + this.t = "token"; + this.v = value; + this.tk = tokens; +} +MultiToken.prototype = { + isLink: false, + /** + * Return the string this token represents. + * @return {string} + */ + toString() { + return this.v; + }, + /** + * What should the value for this token be in the `href` HTML attribute? + * Returns the `.toString` value by default. + * @param {string} [scheme] + * @return {string} + */ + toHref(scheme2) { + return this.toString(); + }, + /** + * @param {Options} options Formatting options + * @returns {string} + */ + toFormattedString(options) { + const val = this.toString(); + const truncate = options.get("truncate", val, this); + const formatted = options.get("format", val, this); + return truncate && formatted.length > truncate ? formatted.substring(0, truncate) + "\u2026" : formatted; + }, + /** + * + * @param {Options} options + * @returns {string} + */ + toFormattedHref(options) { + return options.get("formatHref", this.toHref(options.get("defaultProtocol")), this); + }, + /** + * The start index of this token in the original input string + * @returns {number} + */ + startIndex() { + return this.tk[0].s; + }, + /** + * The end index of this token in the original input string (up to this + * index but not including it) + * @returns {number} + */ + endIndex() { + return this.tk[this.tk.length - 1].e; + }, + /** + Returns an object of relevant values for this token, which includes keys + * type - Kind of token ('url', 'email', etc.) + * value - Original text + * href - The value that should be added to the anchor tag's href + attribute + @method toObject + @param {string} [protocol] `'http'` by default + */ + toObject(protocol = defaults.defaultProtocol) { + return { + type: this.t, + value: this.toString(), + isLink: this.isLink, + href: this.toHref(protocol), + start: this.startIndex(), + end: this.endIndex() + }; + }, + /** + * + * @param {Options} options Formatting option + */ + toFormattedObject(options) { + return { + type: this.t, + value: this.toFormattedString(options), + isLink: this.isLink, + href: this.toFormattedHref(options), + start: this.startIndex(), + end: this.endIndex() + }; + }, + /** + * Whether this token should be rendered as a link according to the given options + * @param {Options} options + * @returns {boolean} + */ + validate(options) { + return options.get("validate", this.toString(), this); + }, + /** + * Return an object that represents how this link should be rendered. + * @param {Options} options Formattinng options + */ + render(options) { + const token = this; + const href = this.toHref(options.get("defaultProtocol")); + const formattedHref = options.get("formatHref", href, this); + const tagName = options.get("tagName", href, token); + const content = this.toFormattedString(options); + const attributes = {}; + const className = options.get("className", href, token); + const target = options.get("target", href, token); + const rel = options.get("rel", href, token); + const attrs = options.getObj("attributes", href, token); + const eventListeners = options.getObj("events", href, token); + attributes.href = formattedHref; + if (className) { + attributes.class = className; + } + if (target) { + attributes.target = target; + } + if (rel) { + attributes.rel = rel; + } + if (attrs) { + Object.assign(attributes, attrs); + } + return { + tagName, + attributes, + content, + eventListeners + }; + } +}; +function createTokenClass(type, props) { + class Token extends MultiToken { + constructor(value, tokens) { + super(value, tokens); + this.t = type; + } + } + for (const p in props) { + Token.prototype[p] = props[p]; + } + Token.t = type; + return Token; +} +var Email = createTokenClass("email", { + isLink: true, + toHref() { + return "mailto:" + this.toString(); + } +}); +var Text = createTokenClass("text"); +var Nl = createTokenClass("nl"); +var Url = createTokenClass("url", { + isLink: true, + /** + Lowercases relevant parts of the domain and adds the protocol if + required. Note that this will not escape unsafe HTML characters in the + URL. + @param {string} [scheme] default scheme (e.g., 'https') + @return {string} the full href + */ + toHref(scheme2 = defaults.defaultProtocol) { + return this.hasProtocol() ? this.v : `${scheme2}://${this.v}`; + }, + /** + * Check whether this URL token has a protocol + * @return {boolean} + */ + hasProtocol() { + const tokens = this.tk; + return tokens.length >= 2 && tokens[0].t !== LOCALHOST && tokens[1].t === COLON; + } +}); +var makeState = (arg) => new State(arg); +function init$1({ + groups +}) { + const qsAccepting = groups.domain.concat([AMPERSAND, ASTERISK, AT, BACKSLASH, BACKTICK, CARET, DOLLAR, EQUALS, HYPHEN, NUM, PERCENT, PIPE, PLUS, POUND, SLASH, SYM, TILDE, UNDERSCORE]); + const qsNonAccepting = [APOSTROPHE, COLON, COMMA, DOT, EXCLAMATION, PERCENT, QUERY, QUOTE, SEMI, OPENANGLEBRACKET, CLOSEANGLEBRACKET, OPENBRACE, CLOSEBRACE, CLOSEBRACKET, OPENBRACKET, OPENPAREN, CLOSEPAREN, FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN, LEFTCORNERBRACKET, RIGHTCORNERBRACKET, LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET, FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN]; + const localpartAccepting = [AMPERSAND, APOSTROPHE, ASTERISK, BACKSLASH, BACKTICK, CARET, DOLLAR, EQUALS, HYPHEN, OPENBRACE, CLOSEBRACE, PERCENT, PIPE, PLUS, POUND, QUERY, SLASH, SYM, TILDE, UNDERSCORE]; + const Start = makeState(); + const Localpart = tt(Start, TILDE); + ta(Localpart, localpartAccepting, Localpart); + ta(Localpart, groups.domain, Localpart); + const Domain = makeState(), Scheme = makeState(), SlashScheme = makeState(); + ta(Start, groups.domain, Domain); + ta(Start, groups.scheme, Scheme); + ta(Start, groups.slashscheme, SlashScheme); + ta(Domain, localpartAccepting, Localpart); + ta(Domain, groups.domain, Domain); + const LocalpartAt = tt(Domain, AT); + tt(Localpart, AT, LocalpartAt); + tt(Scheme, AT, LocalpartAt); + tt(SlashScheme, AT, LocalpartAt); + const LocalpartDot = tt(Localpart, DOT); + ta(LocalpartDot, localpartAccepting, Localpart); + ta(LocalpartDot, groups.domain, Localpart); + const EmailDomain = makeState(); + ta(LocalpartAt, groups.domain, EmailDomain); + ta(EmailDomain, groups.domain, EmailDomain); + const EmailDomainDot = tt(EmailDomain, DOT); + ta(EmailDomainDot, groups.domain, EmailDomain); + const Email$1 = makeState(Email); + ta(EmailDomainDot, groups.tld, Email$1); + ta(EmailDomainDot, groups.utld, Email$1); + tt(LocalpartAt, LOCALHOST, Email$1); + const EmailDomainHyphen = tt(EmailDomain, HYPHEN); + tt(EmailDomainHyphen, HYPHEN, EmailDomainHyphen); + ta(EmailDomainHyphen, groups.domain, EmailDomain); + ta(Email$1, groups.domain, EmailDomain); + tt(Email$1, DOT, EmailDomainDot); + tt(Email$1, HYPHEN, EmailDomainHyphen); + const DomainHyphen = tt(Domain, HYPHEN); + const DomainDot = tt(Domain, DOT); + tt(DomainHyphen, HYPHEN, DomainHyphen); + ta(DomainHyphen, groups.domain, Domain); + ta(DomainDot, localpartAccepting, Localpart); + ta(DomainDot, groups.domain, Domain); + const DomainDotTld = makeState(Url); + ta(DomainDot, groups.tld, DomainDotTld); + ta(DomainDot, groups.utld, DomainDotTld); + ta(DomainDotTld, groups.domain, Domain); + ta(DomainDotTld, localpartAccepting, Localpart); + tt(DomainDotTld, DOT, DomainDot); + tt(DomainDotTld, HYPHEN, DomainHyphen); + tt(DomainDotTld, AT, LocalpartAt); + const DomainDotTldColon = tt(DomainDotTld, COLON); + const DomainDotTldColonPort = makeState(Url); + ta(DomainDotTldColon, groups.numeric, DomainDotTldColonPort); + const Url$1 = makeState(Url); + const UrlNonaccept = makeState(); + ta(Url$1, qsAccepting, Url$1); + ta(Url$1, qsNonAccepting, UrlNonaccept); + ta(UrlNonaccept, qsAccepting, Url$1); + ta(UrlNonaccept, qsNonAccepting, UrlNonaccept); + tt(DomainDotTld, SLASH, Url$1); + tt(DomainDotTldColonPort, SLASH, Url$1); + const SchemeColon = tt(Scheme, COLON); + const SlashSchemeColon = tt(SlashScheme, COLON); + const SlashSchemeColonSlash = tt(SlashSchemeColon, SLASH); + const UriPrefix = tt(SlashSchemeColonSlash, SLASH); + ta(Scheme, groups.domain, Domain); + tt(Scheme, DOT, DomainDot); + tt(Scheme, HYPHEN, DomainHyphen); + ta(SlashScheme, groups.domain, Domain); + tt(SlashScheme, DOT, DomainDot); + tt(SlashScheme, HYPHEN, DomainHyphen); + ta(SchemeColon, groups.domain, Url$1); + tt(SchemeColon, SLASH, Url$1); + tt(SchemeColon, QUERY, Url$1); + ta(UriPrefix, groups.domain, Url$1); + ta(UriPrefix, qsAccepting, Url$1); + tt(UriPrefix, SLASH, Url$1); + const bracketPairs = [ + [OPENBRACE, CLOSEBRACE], + // {} + [OPENBRACKET, CLOSEBRACKET], + // [] + [OPENPAREN, CLOSEPAREN], + // () + [OPENANGLEBRACKET, CLOSEANGLEBRACKET], + // <> + [FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN], + // () + [LEFTCORNERBRACKET, RIGHTCORNERBRACKET], + // 「」 + [LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET], + // 『』 + [FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN] + // <> + ]; + for (let i = 0; i < bracketPairs.length; i++) { + const [OPEN, CLOSE] = bracketPairs[i]; + const UrlOpen = tt(Url$1, OPEN); + tt(UrlNonaccept, OPEN, UrlOpen); + const UrlOpenQ = makeState(Url); + ta(UrlOpen, qsAccepting, UrlOpenQ); + const UrlOpenSyms = makeState(); + ta(UrlOpen, qsNonAccepting, UrlOpenSyms); + tt(UrlOpen, CLOSE, Url$1); + ta(UrlOpenQ, qsAccepting, UrlOpenQ); + ta(UrlOpenQ, qsNonAccepting, UrlOpenSyms); + ta(UrlOpenSyms, qsAccepting, UrlOpenQ); + ta(UrlOpenSyms, qsNonAccepting, UrlOpenSyms); + tt(UrlOpenQ, CLOSE, Url$1); + tt(UrlOpenSyms, CLOSE, Url$1); + } + tt(Start, LOCALHOST, DomainDotTld); + tt(Start, NL, Nl); + return { + start: Start, + tokens: tk + }; +} +function run3(start, input, tokens) { + let len = tokens.length; + let cursor = 0; + let multis = []; + let textTokens = []; + while (cursor < len) { + let state = start; + let secondState = null; + let nextState = null; + let multiLength = 0; + let latestAccepting = null; + let sinceAccepts = -1; + while (cursor < len && !(secondState = state.go(tokens[cursor].t))) { + textTokens.push(tokens[cursor++]); + } + while (cursor < len && (nextState = secondState || state.go(tokens[cursor].t))) { + secondState = null; + state = nextState; + if (state.accepts()) { + sinceAccepts = 0; + latestAccepting = state; + } else if (sinceAccepts >= 0) { + sinceAccepts++; + } + cursor++; + multiLength++; + } + if (sinceAccepts < 0) { + cursor -= multiLength; + if (cursor < len) { + textTokens.push(tokens[cursor]); + cursor++; + } + } else { + if (textTokens.length > 0) { + multis.push(initMultiToken(Text, input, textTokens)); + textTokens = []; + } + cursor -= sinceAccepts; + multiLength -= sinceAccepts; + const Multi = latestAccepting.t; + const subtokens = tokens.slice(cursor - multiLength, cursor); + multis.push(initMultiToken(Multi, input, subtokens)); + } + } + if (textTokens.length > 0) { + multis.push(initMultiToken(Text, input, textTokens)); + } + return multis; +} +function initMultiToken(Multi, input, tokens) { + const startIdx = tokens[0].s; + const endIdx = tokens[tokens.length - 1].e; + const value = input.slice(startIdx, endIdx); + return new Multi(value, tokens); +} +var warn = typeof console !== "undefined" && console && console.warn || (() => { +}); +var warnAdvice = "until manual call of linkify.init(). Register all schemes and plugins before invoking linkify the first time."; +var INIT = { + scanner: null, + parser: null, + tokenQueue: [], + pluginQueue: [], + customSchemes: [], + initialized: false +}; +function reset() { + State.groups = {}; + INIT.scanner = null; + INIT.parser = null; + INIT.tokenQueue = []; + INIT.pluginQueue = []; + INIT.customSchemes = []; + INIT.initialized = false; + return INIT; +} +function registerCustomProtocol(scheme2, optionalSlashSlash = false) { + if (INIT.initialized) { + warn(`linkifyjs: already initialized - will not register custom scheme "${scheme2}" ${warnAdvice}`); + } + if (!/^[0-9a-z]+(-[0-9a-z]+)*$/.test(scheme2)) { + throw new Error(`linkifyjs: incorrect scheme format. +1. Must only contain digits, lowercase ASCII letters or "-" +2. Cannot start or end with "-" +3. "-" cannot repeat`); + } + INIT.customSchemes.push([scheme2, optionalSlashSlash]); +} +function init() { + INIT.scanner = init$2(INIT.customSchemes); + for (let i = 0; i < INIT.tokenQueue.length; i++) { + INIT.tokenQueue[i][1]({ + scanner: INIT.scanner + }); + } + INIT.parser = init$1(INIT.scanner.tokens); + for (let i = 0; i < INIT.pluginQueue.length; i++) { + INIT.pluginQueue[i][1]({ + scanner: INIT.scanner, + parser: INIT.parser + }); + } + INIT.initialized = true; + return INIT; +} +function tokenize(str) { + if (!INIT.initialized) { + init(); + } + return run3(INIT.parser.start, str, run$1(INIT.scanner.start, str)); +} +tokenize.scan = run$1; +function find(str, type = null, opts = null) { + if (type && typeof type === "object") { + if (opts) { + throw Error(`linkifyjs: Invalid link type ${type}; must be a string`); + } + opts = type; + type = null; + } + const options = new Options(opts); + const tokens = tokenize(str); + const filtered = []; + for (let i = 0; i < tokens.length; i++) { + const token = tokens[i]; + if (token.isLink && (!type || token.t === type) && options.check(token)) { + filtered.push(token.toFormattedObject(options)); + } + } + return filtered; +} + +// ../../node_modules/.pnpm/@tiptap+extension-link@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0__@tiptap+pm@3.26.0/node_modules/@tiptap/extension-link/dist/index.js +var UNICODE_WHITESPACE_PATTERN = "[\0- \xA0\u1680\u180E\u2000-\u2029\u205F\u3000]"; +var UNICODE_WHITESPACE_REGEX = new RegExp(UNICODE_WHITESPACE_PATTERN); +var UNICODE_WHITESPACE_REGEX_END = new RegExp(`${UNICODE_WHITESPACE_PATTERN}$`); +var UNICODE_WHITESPACE_REGEX_GLOBAL = new RegExp(UNICODE_WHITESPACE_PATTERN, "g"); +function isValidLinkStructure(tokens) { + if (tokens.length === 1) { + return tokens[0].isLink; + } + if (tokens.length === 3 && tokens[1].isLink) { + return ["()", "[]"].includes(tokens[0].value + tokens[2].value); + } + return false; +} +function autolink(options) { + return new Plugin({ + key: new PluginKey("autolink"), + appendTransaction: (transactions, oldState, newState) => { + const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc); + const preventAutolink = transactions.some( + (transaction) => transaction.getMeta("preventAutolink") + ); + if (!docChanges || preventAutolink) { + return; + } + const { tr: tr2 } = newState; + const transform = combineTransactionSteps(oldState.doc, [...transactions]); + const changes = getChangedRanges(transform); + changes.forEach(({ newRange }) => { + const nodesInChangedRanges = findChildrenInRange( + newState.doc, + newRange, + (node) => node.isTextblock + ); + let textBlock; + let textBeforeWhitespace; + if (nodesInChangedRanges.length > 1) { + textBlock = nodesInChangedRanges[0]; + textBeforeWhitespace = newState.doc.textBetween( + textBlock.pos, + textBlock.pos + textBlock.node.nodeSize, + void 0, + " " + ); + } else if (nodesInChangedRanges.length) { + const endText = newState.doc.textBetween(newRange.from, newRange.to, " ", " "); + if (!UNICODE_WHITESPACE_REGEX_END.test(endText)) { + return; + } + textBlock = nodesInChangedRanges[0]; + textBeforeWhitespace = newState.doc.textBetween( + textBlock.pos, + newRange.to, + void 0, + " " + ); + } + if (textBlock && textBeforeWhitespace) { + const wordsBeforeWhitespace = textBeforeWhitespace.split(UNICODE_WHITESPACE_REGEX).filter(Boolean); + if (wordsBeforeWhitespace.length <= 0) { + return false; + } + const lastWordBeforeSpace = wordsBeforeWhitespace[wordsBeforeWhitespace.length - 1]; + const lastWordAndBlockOffset = textBlock.pos + textBeforeWhitespace.lastIndexOf(lastWordBeforeSpace); + if (!lastWordBeforeSpace) { + return false; + } + const linksBeforeSpace = tokenize(lastWordBeforeSpace).map( + (t) => t.toObject(options.defaultProtocol) + ); + if (!isValidLinkStructure(linksBeforeSpace)) { + return false; + } + linksBeforeSpace.filter((link) => link.isLink).map((link) => ({ + ...link, + from: lastWordAndBlockOffset + link.start + 1, + to: lastWordAndBlockOffset + link.end + 1 + })).filter((link) => { + if (!newState.schema.marks.code) { + return true; + } + return !newState.doc.rangeHasMark(link.from, link.to, newState.schema.marks.code); + }).filter((link) => options.validate(link.value)).filter((link) => options.shouldAutoLink(link.value)).forEach((link) => { + if (getMarksBetween(link.from, link.to, newState.doc).some( + (item) => item.mark.type === options.type + )) { + return; + } + tr2.addMark( + link.from, + link.to, + options.type.create({ + href: link.href + }) + ); + }); + } + }); + if (!tr2.steps.length) { + return; + } + return tr2; + } + }); +} +function clickHandler(options) { + return new Plugin({ + key: new PluginKey("handleClickLink"), + props: { + handleClick: (view, pos, event) => { + var _a, _b; + if (event.button !== 0) { + return false; + } + if (!view.editable) { + return false; + } + let link = null; + if (event.target instanceof HTMLAnchorElement) { + link = event.target; + } else { + const target = event.target; + if (!target) { + return false; + } + const root2 = options.editor.view.dom; + link = target.closest("a"); + if (link && !root2.contains(link)) { + link = null; + } + } + if (!link) { + return false; + } + let handled = false; + if (options.enableClickSelection) { + const commandResult = options.editor.commands.extendMarkRange(options.type.name); + handled = commandResult; + } + if (options.openOnClick) { + const attrs = getAttributes(view.state, options.type.name); + const href = (_a = link.href) != null ? _a : attrs.href; + const target = (_b = link.target) != null ? _b : attrs.target; + if (href) { + window.open(href, target); + handled = true; + } + } + return handled; + } + } + }); +} +function pasteHandler(options) { + return new Plugin({ + key: new PluginKey("handlePasteLink"), + props: { + handlePaste: (view, _event, slice2) => { + const { shouldAutoLink } = options; + const { state } = view; + const { selection } = state; + const { empty: empty2 } = selection; + if (empty2) { + return false; + } + let textContent = ""; + slice2.content.forEach((node) => { + textContent += node.textContent; + }); + const link = find(textContent, { defaultProtocol: options.defaultProtocol }).find( + (item) => item.isLink && item.value === textContent + ); + if (!textContent || !link || shouldAutoLink !== void 0 && !shouldAutoLink(link.value)) { + return false; + } + return options.editor.commands.setMark(options.type, { + href: link.href + }); + } + } + }); +} +function isAllowedUri(uri, protocols) { + const allowedProtocols = [ + "http", + "https", + "ftp", + "ftps", + "mailto", + "tel", + "callto", + "sms", + "cid", + "xmpp" + ]; + if (protocols) { + protocols.forEach((protocol) => { + const nextProtocol = typeof protocol === "string" ? protocol : protocol.scheme; + if (nextProtocol) { + allowedProtocols.push(nextProtocol); + } + }); + } + return !uri || uri.replace(UNICODE_WHITESPACE_REGEX_GLOBAL, "").match( + new RegExp( + // oxlint-disable-next-line no-useless-escape + `^(?:(?:${allowedProtocols.join("|")}):|[^a-z]|[a-z0-9+.-]+(?:[^a-z+.-:]|$))`, + "i" + ) + ); +} +var Link = Mark2.create({ + name: "link", + priority: 1e3, + keepOnSplit: false, + exitable: true, + onCreate() { + if (this.options.validate && !this.options.shouldAutoLink) { + this.options.shouldAutoLink = this.options.validate; + console.warn( + "The `validate` option is deprecated. Rename to the `shouldAutoLink` option instead." + ); + } + this.options.protocols.forEach((protocol) => { + if (typeof protocol === "string") { + registerCustomProtocol(protocol); + return; + } + registerCustomProtocol(protocol.scheme, protocol.optionalSlashes); + }); + }, + onDestroy() { + reset(); + }, + inclusive() { + return this.options.autolink; + }, + addOptions() { + return { + openOnClick: true, + enableClickSelection: false, + linkOnPaste: true, + autolink: true, + protocols: [], + defaultProtocol: "http", + HTMLAttributes: { + target: "_blank", + rel: "noopener noreferrer nofollow", + class: null + }, + isAllowedUri: (url, ctx) => !!isAllowedUri(url, ctx.protocols), + validate: (url) => !!url, + shouldAutoLink: (url) => { + const hasProtocol = /^[a-z][a-z0-9+.-]*:\/\//i.test(url); + const hasMaybeProtocol = /^[a-z][a-z0-9+.-]*:/i.test(url); + if (hasProtocol || hasMaybeProtocol && !url.includes("@")) { + return true; + } + const urlWithoutUserinfo = url.includes("@") ? url.split("@").pop() : url; + const hostname = urlWithoutUserinfo.split(/[/?#:]/)[0]; + if (/^\d{1,3}(\.\d{1,3}){3}$/.test(hostname)) { + return false; + } + if (!/\./.test(hostname)) { + return false; + } + return true; + } + }; + }, + addAttributes() { + return { + href: { + default: null, + parseHTML(element2) { + return element2.getAttribute("href"); + } + }, + target: { + default: this.options.HTMLAttributes.target + }, + rel: { + default: this.options.HTMLAttributes.rel + }, + class: { + default: this.options.HTMLAttributes.class + }, + title: { + default: null + } + }; + }, + parseHTML() { + return [ + { + tag: "a[href]", + getAttrs: (dom) => { + const href = dom.getAttribute("href"); + if (!href || !this.options.isAllowedUri(href, { + defaultValidate: (url) => !!isAllowedUri(url, this.options.protocols), + protocols: this.options.protocols, + defaultProtocol: this.options.defaultProtocol + })) { + return false; + } + return null; + } + } + ]; + }, + renderHTML({ HTMLAttributes }) { + if (!this.options.isAllowedUri(HTMLAttributes.href, { + defaultValidate: (href) => !!isAllowedUri(href, this.options.protocols), + protocols: this.options.protocols, + defaultProtocol: this.options.defaultProtocol + })) { + return ["a", mergeAttributes(this.options.HTMLAttributes, { ...HTMLAttributes, href: "" }), 0]; + } + return ["a", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + markdownTokenName: "link", + parseMarkdown: (token, helpers) => { + return helpers.applyMark("link", helpers.parseInline(token.tokens || []), { + href: token.href, + title: token.title || null + }); + }, + renderMarkdown: (node, h2) => { + var _a, _b, _c, _d; + const href = (_b = (_a = node.attrs) == null ? void 0 : _a.href) != null ? _b : ""; + const title = (_d = (_c = node.attrs) == null ? void 0 : _c.title) != null ? _d : ""; + const text2 = h2.renderChildren(node); + return title ? `[${text2}](${href} "${title}")` : `[${text2}](${href})`; + }, + addCommands() { + return { + setLink: (attributes) => ({ chain }) => { + const { href } = attributes; + if (!this.options.isAllowedUri(href, { + defaultValidate: (url) => !!isAllowedUri(url, this.options.protocols), + protocols: this.options.protocols, + defaultProtocol: this.options.defaultProtocol + })) { + return false; + } + return chain().setMark(this.name, attributes).setMeta("preventAutolink", true).run(); + }, + toggleLink: (attributes) => ({ chain }) => { + const { href } = attributes || {}; + if (href && !this.options.isAllowedUri(href, { + defaultValidate: (url) => !!isAllowedUri(url, this.options.protocols), + protocols: this.options.protocols, + defaultProtocol: this.options.defaultProtocol + })) { + return false; + } + return chain().toggleMark(this.name, attributes, { extendEmptyMarkRange: true }).setMeta("preventAutolink", true).run(); + }, + unsetLink: () => ({ chain }) => { + return chain().unsetMark(this.name, { extendEmptyMarkRange: true }).setMeta("preventAutolink", true).run(); + } + }; + }, + addPasteRules() { + return [ + markPasteRule({ + find: (text2) => { + const foundLinks = []; + if (text2) { + const { protocols, defaultProtocol } = this.options; + const links = find(text2).filter( + (item) => item.isLink && this.options.isAllowedUri(item.value, { + defaultValidate: (href) => !!isAllowedUri(href, protocols), + protocols, + defaultProtocol + }) + ); + if (links.length) { + links.forEach((link) => { + if (!this.options.shouldAutoLink(link.value)) { + return; + } + foundLinks.push({ + text: link.value, + data: { + href: link.href + }, + index: link.start + }); + }); + } + } + return foundLinks; + }, + type: this.type, + getAttributes: (match2) => { + var _a; + return { + href: (_a = match2.data) == null ? void 0 : _a.href + }; + } + }) + ]; + }, + addProseMirrorPlugins() { + const plugins = []; + const { protocols, defaultProtocol } = this.options; + if (this.options.autolink) { + plugins.push( + autolink({ + type: this.type, + defaultProtocol: this.options.defaultProtocol, + validate: (url) => this.options.isAllowedUri(url, { + defaultValidate: (href) => !!isAllowedUri(href, protocols), + protocols, + defaultProtocol + }), + shouldAutoLink: this.options.shouldAutoLink + }) + ); + } + plugins.push( + clickHandler({ + type: this.type, + editor: this.editor, + openOnClick: this.options.openOnClick === "whenNotEditable" ? true : this.options.openOnClick, + enableClickSelection: this.options.enableClickSelection + }) + ); + if (this.options.linkOnPaste) { + plugins.push( + pasteHandler({ + editor: this.editor, + defaultProtocol: this.options.defaultProtocol, + type: this.type, + shouldAutoLink: this.options.shouldAutoLink + }) + ); + } + return plugins; + } +}); +var index_default = Link; + +// ../../node_modules/.pnpm/@tiptap+extension-list@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0__@tiptap+pm@3.26.0/node_modules/@tiptap/extension-list/dist/index.js +var __defProp3 = Object.defineProperty; +var __export3 = (target, all2) => { + for (var name in all2) + __defProp3(target, name, { get: all2[name], enumerable: true }); +}; +var ListItemName = "listItem"; +var TextStyleName = "textStyle"; +var bulletListInputRegex = /^\s*([-+*])\s$/; +var BulletList = Node3.create({ + name: "bulletList", + addOptions() { + return { + itemTypeName: "listItem", + HTMLAttributes: {}, + keepMarks: false, + keepAttributes: false + }; + }, + group: "block list", + content() { + return `${this.options.itemTypeName}+`; + }, + parseHTML() { + return [{ tag: "ul" }]; + }, + renderHTML({ HTMLAttributes }) { + return ["ul", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + markdownTokenName: "list", + parseMarkdown: (token, helpers) => { + if (token.type !== "list" || token.ordered) { + return []; + } + return { + type: "bulletList", + content: token.items ? helpers.parseChildren(token.items) : [] + }; + }, + renderMarkdown: (node, h2) => { + if (!node.content) { + return ""; + } + return h2.renderChildren(node.content, "\n"); + }, + markdownOptions: { + indentsContent: true + }, + addCommands() { + return { + toggleBulletList: () => ({ commands, chain }) => { + if (this.options.keepAttributes) { + return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName)).run(); + } + return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Shift-8": () => this.editor.commands.toggleBulletList() + }; + }, + addInputRules() { + let inputRule = wrappingInputRule({ + find: bulletListInputRegex, + type: this.type + }); + if (this.options.keepMarks || this.options.keepAttributes) { + inputRule = wrappingInputRule({ + find: bulletListInputRegex, + type: this.type, + keepMarks: this.options.keepMarks, + keepAttributes: this.options.keepAttributes, + getAttributes: () => { + return this.editor.getAttributes(TextStyleName); + }, + editor: this.editor + }); + } + return [inputRule]; + } +}); +var getBranchingNestedListAtCursor = (state, itemName, wrapperNames) => { + const { selection } = state; + if (!selection.empty) { + return null; + } + const { $from } = selection; + if (!$from.parent.isTextblock) { + return null; + } + if ($from.parentOffset !== $from.parent.content.size) { + return null; + } + let listItemDepth = -1; + for (let depth = $from.depth; depth > 0; depth -= 1) { + if ($from.node(depth).type.name === itemName) { + listItemDepth = depth; + break; + } + } + if (listItemDepth < 0) { + return null; + } + const listItem = $from.node(listItemDepth); + const indexInListItem = $from.index(listItemDepth); + if (indexInListItem + 1 >= listItem.childCount) { + return null; + } + const nextChild = listItem.child(indexInListItem + 1); + if (!wrapperNames.includes(nextChild.type.name)) { + return null; + } + const itemType = state.schema.nodes[itemName]; + let hasBranching = false; + nextChild.forEach((child) => { + if (child.type === itemType && child.childCount > 1) { + hasBranching = true; + } + }); + if (!hasBranching) { + return null; + } + const nodeAfter = state.doc.resolve($from.after()).nodeAfter; + if (!nodeAfter || !wrapperNames.includes(nodeAfter.type.name)) { + return null; + } + const items = []; + nodeAfter.forEach((child) => { + items.push(child); + }); + if (items.length === 0) { + return null; + } + return { + listItemDepth, + nestedList: nodeAfter, + nestedListPos: $from.after(), + insertPos: $from.after(listItemDepth), + items + }; +}; +var hoistBranchingNestedList = (state, dispatch, itemName, wrapperNames) => { + const context = getBranchingNestedListAtCursor(state, itemName, wrapperNames); + if (!context) { + return false; + } + const { selection } = state; + const { nestedList, nestedListPos, insertPos, items } = context; + const tr2 = state.tr; + tr2.delete(nestedListPos, nestedListPos + nestedList.nodeSize); + const mappedInsertPos = tr2.mapping.map(insertPos); + tr2.insert(mappedInsertPos, Fragment.from(items)); + tr2.setSelection(selection.map(tr2.doc, tr2.mapping)); + if (dispatch) { + dispatch(tr2); + } + return true; +}; +var handleDeleteBranchingNestedList = (editor, itemName, wrapperNames) => { + return hoistBranchingNestedList(editor.state, editor.view.dispatch, itemName, wrapperNames); +}; +var createBranchingListDeleteKeymap = (itemName, wrapperNames) => { + return Extension.create({ + name: `${itemName}BranchingDeleteKeymap`, + priority: 101, + addKeyboardShortcuts() { + const handleDelete2 = () => handleDeleteBranchingNestedList(this.editor, itemName, wrapperNames); + return { + Delete: handleDelete2, + "Mod-Delete": handleDelete2 + }; + } + }); +}; +function isSameLineOrderedListToken(token) { + var _a, _b; + const nestedToken = (_a = token.tokens) == null ? void 0 : _a[0]; + return Boolean( + token.text && ((_b = token.tokens) == null ? void 0 : _b.length) === 1 && (nestedToken == null ? void 0 : nestedToken.type) === "list" && nestedToken.ordered && nestedToken.raw === token.text + ); +} +function parseSameLineOrderedListText(text2, helpers) { + if (helpers.tokenizeInline) { + return helpers.parseInline(helpers.tokenizeInline(text2)); + } + return helpers.parseInline([ + { + type: "text", + raw: text2, + text: text2 + } + ]); +} +var ListItem = Node3.create({ + name: "listItem", + addOptions() { + return { + HTMLAttributes: {}, + bulletListTypeName: "bulletList", + orderedListTypeName: "orderedList" + }; + }, + content: "paragraph block*", + defining: true, + parseHTML() { + return [ + { + tag: "li" + } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["li", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + markdownTokenName: "list_item", + parseMarkdown: (token, helpers) => { + var _a; + if (token.type !== "list_item") { + return []; + } + const parseBlockChildren = (_a = helpers.parseBlockChildren) != null ? _a : helpers.parseChildren; + let content = []; + if (token.tokens && token.tokens.length > 0) { + if (isSameLineOrderedListToken(token)) { + return { + type: "listItem", + content: [ + { + type: "paragraph", + content: parseSameLineOrderedListText(token.text || "", helpers) + } + ] + }; + } + const hasParagraphTokens = token.tokens.some((t) => t.type === "paragraph"); + if (hasParagraphTokens) { + content = parseBlockChildren(token.tokens); + } else { + const firstToken = token.tokens[0]; + if (firstToken && firstToken.type === "text" && firstToken.tokens && firstToken.tokens.length > 0) { + const inlineContent = helpers.parseInline(firstToken.tokens); + content = [ + { + type: "paragraph", + content: inlineContent + } + ]; + if (token.tokens.length > 1) { + const remainingTokens = token.tokens.slice(1); + const additionalContent = parseBlockChildren(remainingTokens); + content.push(...additionalContent); + } + } else { + content = parseBlockChildren(token.tokens); + } + } + } + if (content.length === 0) { + content = [ + { + type: "paragraph", + content: [] + } + ]; + } + return { + type: "listItem", + content + }; + }, + renderMarkdown: (node, h2, ctx) => { + return renderNestedMarkdownContent( + node, + h2, + (context) => { + var _a, _b; + if (context.parentType === "bulletList") { + return "- "; + } + if (context.parentType === "orderedList") { + const start = ((_b = (_a = context.meta) == null ? void 0 : _a.parentAttrs) == null ? void 0 : _b.start) || 1; + return `${start + context.index}. `; + } + return "- "; + }, + ctx + ); + }, + addExtensions() { + return [ + createBranchingListDeleteKeymap(this.name, [ + this.options.bulletListTypeName, + this.options.orderedListTypeName + ]) + ]; + }, + addKeyboardShortcuts() { + return { + Enter: () => this.editor.commands.splitListItem(this.name), + Tab: () => this.editor.commands.sinkListItem(this.name), + "Shift-Tab": () => this.editor.commands.liftListItem(this.name) + }; + } +}); +var listHelpers_exports = {}; +__export3(listHelpers_exports, { + findListItemPos: () => findListItemPos, + getNextListDepth: () => getNextListDepth, + handleBackspace: () => handleBackspace2, + handleDelete: () => handleDelete, + hasListBefore: () => hasListBefore, + hasListItemAfter: () => hasListItemAfter, + hasListItemBefore: () => hasListItemBefore, + listItemHasSubList: () => listItemHasSubList, + nextListIsDeeper: () => nextListIsDeeper, + nextListIsHigher: () => nextListIsHigher +}); +var findListItemPos = (typeOrName, state) => { + const { $from } = state.selection; + const nodeType = getNodeType(typeOrName, state.schema); + let currentNode = null; + let currentDepth = $from.depth; + let currentPos = $from.pos; + let targetDepth = null; + while (currentDepth > 0 && targetDepth === null) { + currentNode = $from.node(currentDepth); + if (currentNode.type === nodeType) { + targetDepth = currentDepth; + } else { + currentDepth -= 1; + currentPos -= 1; + } + } + if (targetDepth === null) { + return null; + } + return { $pos: state.doc.resolve(currentPos), depth: targetDepth }; +}; +var getNextListDepth = (typeOrName, state) => { + const listItemPos = findListItemPos(typeOrName, state); + if (!listItemPos) { + return false; + } + const [, depth] = getNodeAtPosition(state, typeOrName, listItemPos.$pos.pos + 4); + return depth; +}; +var hasListBefore = (editorState, name, parentListTypes) => { + const { $anchor } = editorState.selection; + const previousNodePos = Math.max(0, $anchor.pos - 2); + const previousNode = editorState.doc.resolve(previousNodePos).node(); + if (!previousNode || !parentListTypes.includes(previousNode.type.name)) { + return false; + } + return true; +}; +var handleBackspace2 = (editor, name, parentListTypes) => { + if (editor.commands.undoInputRule()) { + return true; + } + if (editor.state.selection.from !== editor.state.selection.to) { + return false; + } + if (!isNodeActive(editor.state, name) && hasListBefore(editor.state, name, parentListTypes)) { + const { $anchor } = editor.state.selection; + const $listPos = editor.state.doc.resolve($anchor.before() - 1); + const listDescendants = []; + $listPos.node().descendants((node, pos) => { + if (node.type.name === name) { + listDescendants.push({ node, pos }); + } + }); + const lastItem = listDescendants.at(-1); + if (!lastItem) { + return false; + } + const $lastItemPos = editor.state.doc.resolve($listPos.start() + lastItem.pos + 1); + return editor.chain().cut({ from: $anchor.start() - 1, to: $anchor.end() + 1 }, $lastItemPos.end()).joinForward().run(); + } + if (!isNodeActive(editor.state, name)) { + return false; + } + if (!isAtStartOfNode(editor.state)) { + return false; + } + return editor.chain().liftListItem(name).run(); +}; +var nextListIsDeeper = (typeOrName, state) => { + const listDepth = getNextListDepth(typeOrName, state); + const listItemPos = findListItemPos(typeOrName, state); + if (!listItemPos || !listDepth) { + return false; + } + if (listDepth > listItemPos.depth) { + return true; + } + return false; +}; +var nextListIsHigher = (typeOrName, state) => { + const listDepth = getNextListDepth(typeOrName, state); + const listItemPos = findListItemPos(typeOrName, state); + if (!listItemPos || !listDepth) { + return false; + } + if (listDepth < listItemPos.depth) { + return true; + } + return false; +}; +var handleDelete = (editor, name) => { + if (!isNodeActive(editor.state, name)) { + return false; + } + if (!isAtEndOfNode(editor.state, name)) { + return false; + } + const { selection } = editor.state; + const { $from, $to } = selection; + if (!selection.empty && $from.sameParent($to)) { + return false; + } + if (nextListIsDeeper(name, editor.state)) { + return editor.chain().focus(editor.state.selection.from + 4).lift(name).joinBackward().run(); + } + if (nextListIsHigher(name, editor.state)) { + return editor.chain().joinForward().joinBackward().run(); + } + return editor.commands.joinItemForward(); +}; +var hasListItemAfter = (typeOrName, state) => { + var _a; + const { $anchor } = state.selection; + const $targetPos = state.doc.resolve($anchor.pos - $anchor.parentOffset - 2); + if ($targetPos.index() === $targetPos.parent.childCount - 1) { + return false; + } + if (((_a = $targetPos.nodeAfter) == null ? void 0 : _a.type.name) !== typeOrName) { + return false; + } + return true; +}; +var hasListItemBefore = (typeOrName, state) => { + var _a; + const { $anchor } = state.selection; + const $targetPos = state.doc.resolve($anchor.pos - 2); + if ($targetPos.index() === 0) { + return false; + } + if (((_a = $targetPos.nodeBefore) == null ? void 0 : _a.type.name) !== typeOrName) { + return false; + } + return true; +}; +var listItemHasSubList = (typeOrName, state, node) => { + if (!node) { + return false; + } + const nodeType = getNodeType(typeOrName, state.schema); + let hasSubList = false; + node.descendants((child) => { + if (child.type === nodeType) { + hasSubList = true; + } + }); + return hasSubList; +}; +var ListKeymap = Extension.create({ + name: "listKeymap", + addOptions() { + return { + listTypes: [ + { + itemName: "listItem", + wrapperNames: ["bulletList", "orderedList"] + }, + { + itemName: "taskItem", + wrapperNames: ["taskList"] + } + ] + }; + }, + addKeyboardShortcuts() { + return { + Delete: ({ editor }) => { + let handled = false; + this.options.listTypes.forEach(({ itemName }) => { + if (editor.state.schema.nodes[itemName] === void 0) { + return; + } + if (handleDelete(editor, itemName)) { + handled = true; + } + }); + return handled; + }, + "Mod-Delete": ({ editor }) => { + let handled = false; + this.options.listTypes.forEach(({ itemName }) => { + if (editor.state.schema.nodes[itemName] === void 0) { + return; + } + if (handleDelete(editor, itemName)) { + handled = true; + } + }); + return handled; + }, + Backspace: ({ editor }) => { + let handled = false; + this.options.listTypes.forEach(({ itemName, wrapperNames }) => { + if (editor.state.schema.nodes[itemName] === void 0) { + return; + } + if (handleBackspace2(editor, itemName, wrapperNames)) { + handled = true; + } + }); + return handled; + }, + "Mod-Backspace": ({ editor }) => { + let handled = false; + this.options.listTypes.forEach(({ itemName, wrapperNames }) => { + if (editor.state.schema.nodes[itemName] === void 0) { + return; + } + if (handleBackspace2(editor, itemName, wrapperNames)) { + handled = true; + } + }); + return handled; + } + }; + } +}); +var ORDERED_LIST_ITEM_REGEX = /^(\s*)(\d+)\.\s+(.*)$/; +var INDENTED_LINE_REGEX = /^\s/; +function isBlockContentLine(line) { + const trimmedLine = line.trimStart(); + return ( + // oxlint-disable-next-line prefer-string-starts-ends-with + /^[-+*]\s+/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with + /^\d+\.\s+/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with + /^>\s?/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with + /^```/.test(trimmedLine) || // oxlint-disable-next-line prefer-string-starts-ends-with + /^~~~/.test(trimmedLine) + ); +} +function splitItemContent(contentLines) { + const paragraphLines = []; + const blockLines = []; + let reachedBlockBoundary = false; + contentLines.forEach((line) => { + if (reachedBlockBoundary) { + blockLines.push(line); + return; + } + if (line.trim() === "") { + reachedBlockBoundary = true; + blockLines.push(line); + return; + } + if (paragraphLines.length > 0 && isBlockContentLine(line)) { + reachedBlockBoundary = true; + blockLines.push(line); + return; + } + paragraphLines.push(line); + }); + return { + paragraphLines, + blockLines + }; +} +function collectOrderedListItems(lines) { + const listItems = []; + let currentLineIndex = 0; + let consumed = 0; + while (currentLineIndex < lines.length) { + const line = lines[currentLineIndex]; + const match2 = line.match(ORDERED_LIST_ITEM_REGEX); + if (!match2) { + break; + } + const [, indent, number, content] = match2; + const indentLevel = indent.length; + const itemContentLines = [content]; + let nextLineIndex = currentLineIndex + 1; + const itemLines = [line]; + let sawBlankLine = false; + while (nextLineIndex < lines.length) { + const nextLine = lines[nextLineIndex]; + const nextMatch = nextLine.match(ORDERED_LIST_ITEM_REGEX); + if (nextMatch) { + break; + } + if (nextLine.trim() === "") { + itemLines.push(nextLine); + itemContentLines.push(""); + sawBlankLine = true; + nextLineIndex += 1; + } else if (nextLine.match(INDENTED_LINE_REGEX)) { + itemLines.push(nextLine); + itemContentLines.push(nextLine.slice(indentLevel + 2)); + nextLineIndex += 1; + } else { + if (sawBlankLine) { + break; + } + itemLines.push(nextLine); + itemContentLines.push(nextLine); + nextLineIndex += 1; + } + } + listItems.push({ + indent: indentLevel, + number: parseInt(number, 10), + content: itemContentLines.join("\n").trim(), + contentLines: itemContentLines, + raw: itemLines.join("\n") + }); + consumed = nextLineIndex; + currentLineIndex = nextLineIndex; + } + return [listItems, consumed]; +} +function buildNestedStructure(items, baseIndent, lexer) { + const result = []; + let currentIndex = 0; + while (currentIndex < items.length) { + const item = items[currentIndex]; + if (item.indent === baseIndent) { + const { paragraphLines, blockLines } = splitItemContent(item.contentLines); + const mainText = paragraphLines.join("\n").trim(); + const tokens = []; + if (mainText) { + tokens.push({ + type: "paragraph", + raw: mainText, + tokens: lexer.inlineTokens(mainText) + }); + } + const additionalContent = blockLines.join("\n").trim(); + if (additionalContent) { + const blockTokens = lexer.blockTokens(additionalContent); + tokens.push(...blockTokens); + } + let lookAheadIndex = currentIndex + 1; + const nestedItems = []; + while (lookAheadIndex < items.length && items[lookAheadIndex].indent > baseIndent) { + nestedItems.push(items[lookAheadIndex]); + lookAheadIndex += 1; + } + if (nestedItems.length > 0) { + const nextIndent = Math.min(...nestedItems.map((nestedItem) => nestedItem.indent)); + const nestedListItems = buildNestedStructure(nestedItems, nextIndent, lexer); + tokens.push({ + type: "list", + ordered: true, + start: nestedItems[0].number, + items: nestedListItems, + raw: nestedItems.map((nestedItem) => nestedItem.raw).join("\n") + }); + } + result.push({ + type: "list_item", + raw: item.raw, + tokens + }); + currentIndex = lookAheadIndex; + } else { + currentIndex += 1; + } + } + return result; +} +function parseListItems(items, helpers) { + return items.map((item) => { + if (item.type !== "list_item") { + return helpers.parseChildren([item])[0]; + } + const content = []; + if (item.tokens && item.tokens.length > 0) { + item.tokens.forEach((itemToken) => { + if (itemToken.type === "paragraph" || itemToken.type === "list" || itemToken.type === "blockquote" || itemToken.type === "code") { + content.push(...helpers.parseChildren([itemToken])); + } else if (itemToken.type === "text" && itemToken.tokens) { + const inlineContent = helpers.parseChildren([itemToken]); + content.push({ + type: "paragraph", + content: inlineContent + }); + } else { + const parsed = helpers.parseChildren([itemToken]); + if (parsed.length > 0) { + content.push(...parsed); + } + } + }); + } + return { + type: "listItem", + content + }; + }); +} +var ListItemName2 = "listItem"; +var TextStyleName2 = "textStyle"; +var orderedListInputRegex = /^(\d+)\.\s$/; +var OrderedList = Node3.create({ + name: "orderedList", + addOptions() { + return { + itemTypeName: "listItem", + HTMLAttributes: {}, + keepMarks: false, + keepAttributes: false + }; + }, + group: "block list", + content() { + return `${this.options.itemTypeName}+`; + }, + addAttributes() { + return { + start: { + default: 1, + parseHTML: (element2) => { + return element2.hasAttribute("start") ? parseInt(element2.getAttribute("start") || "", 10) : 1; + } + }, + type: { + default: null, + parseHTML: (element2) => element2.getAttribute("type") + } + }; + }, + parseHTML() { + return [ + { + tag: "ol" + } + ]; + }, + renderHTML({ HTMLAttributes }) { + const { start, ...attributesWithoutStart } = HTMLAttributes; + return start === 1 ? ["ol", mergeAttributes(this.options.HTMLAttributes, attributesWithoutStart), 0] : ["ol", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + markdownTokenName: "list", + parseMarkdown: (token, helpers) => { + if (token.type !== "list" || !token.ordered) { + return []; + } + const startValue = token.start || 1; + const content = token.items ? parseListItems(token.items, helpers) : []; + if (startValue !== 1) { + return { + type: "orderedList", + attrs: { start: startValue }, + content + }; + } + return { + type: "orderedList", + content + }; + }, + renderMarkdown: (node, h2) => { + if (!node.content) { + return ""; + } + return h2.renderChildren(node.content, "\n"); + }, + markdownTokenizer: { + name: "orderedList", + level: "block", + start: (src) => { + const match2 = src.match(/^(\s*)(\d+)\.\s+/); + const index = match2 == null ? void 0 : match2.index; + return index !== void 0 ? index : -1; + }, + tokenize: (src, _tokens, lexer) => { + var _a; + const lines = src.split("\n"); + const [listItems, consumed] = collectOrderedListItems(lines); + if (listItems.length === 0) { + return void 0; + } + const items = buildNestedStructure(listItems, 0, lexer); + if (items.length === 0) { + return void 0; + } + const startValue = ((_a = listItems[0]) == null ? void 0 : _a.number) || 1; + return { + type: "list", + ordered: true, + start: startValue, + items, + raw: lines.slice(0, consumed).join("\n") + }; + } + }, + markdownOptions: { + indentsContent: true + }, + addCommands() { + return { + toggleOrderedList: () => ({ commands, chain }) => { + if (this.options.keepAttributes) { + return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName2, this.editor.getAttributes(TextStyleName2)).run(); + } + return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Shift-7": () => this.editor.commands.toggleOrderedList() + }; + }, + addInputRules() { + let inputRule = wrappingInputRule({ + find: orderedListInputRegex, + type: this.type, + getAttributes: (match2) => ({ start: +match2[1] }), + joinPredicate: (match2, node) => node.childCount + node.attrs.start === +match2[1] + }); + if (this.options.keepMarks || this.options.keepAttributes) { + inputRule = wrappingInputRule({ + find: orderedListInputRegex, + type: this.type, + keepMarks: this.options.keepMarks, + keepAttributes: this.options.keepAttributes, + getAttributes: (match2) => ({ start: +match2[1], ...this.editor.getAttributes(TextStyleName2) }), + joinPredicate: (match2, node) => node.childCount + node.attrs.start === +match2[1], + editor: this.editor + }); + } + return [inputRule]; + } +}); +var inputRegex2 = /^\s*(\[([( |x])?\])\s$/; +var TaskItem = Node3.create({ + name: "taskItem", + addOptions() { + return { + nested: false, + HTMLAttributes: {}, + taskListTypeName: "taskList", + a11y: void 0 + }; + }, + content() { + return this.options.nested ? "paragraph block*" : "paragraph+"; + }, + defining: true, + addAttributes() { + return { + checked: { + default: false, + keepOnSplit: false, + parseHTML: (element2) => { + const dataChecked = element2.getAttribute("data-checked"); + return dataChecked === "" || dataChecked === "true"; + }, + renderHTML: (attributes) => ({ + "data-checked": attributes.checked + }) + } + }; + }, + parseHTML() { + return [ + { + tag: `li[data-type="${this.name}"]`, + priority: 51 + } + ]; + }, + renderHTML({ node, HTMLAttributes }) { + return [ + "li", + mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { + "data-type": this.name + }), + [ + "label", + [ + "input", + { + type: "checkbox", + checked: node.attrs.checked ? "checked" : null + } + ], + ["span"] + ], + ["div", 0] + ]; + }, + parseMarkdown: (token, h2) => { + const content = []; + if (token.tokens && token.tokens.length > 0) { + content.push(h2.createNode("paragraph", {}, h2.parseInline(token.tokens))); + } else if (token.text) { + content.push(h2.createNode("paragraph", {}, [h2.createNode("text", { text: token.text })])); + } else { + content.push(h2.createNode("paragraph", {}, [])); + } + if (token.nestedTokens && token.nestedTokens.length > 0) { + const nestedContent = h2.parseChildren(token.nestedTokens); + content.push(...nestedContent); + } + return h2.createNode("taskItem", { checked: token.checked || false }, content); + }, + renderMarkdown: (node, h2) => { + var _a; + const checkedChar = ((_a = node.attrs) == null ? void 0 : _a.checked) ? "x" : " "; + const prefix = `- [${checkedChar}] `; + return renderNestedMarkdownContent(node, h2, prefix); + }, + addExtensions() { + if (!this.options.nested) { + return []; + } + return [createBranchingListDeleteKeymap(this.name, [this.options.taskListTypeName])]; + }, + addKeyboardShortcuts() { + const shortcuts = { + Enter: () => this.editor.commands.splitListItem(this.name), + "Shift-Tab": () => this.editor.commands.liftListItem(this.name) + }; + if (!this.options.nested) { + return shortcuts; + } + return { + ...shortcuts, + Tab: () => this.editor.commands.sinkListItem(this.name) + }; + }, + addNodeView() { + return ({ node, HTMLAttributes, getPos, editor }) => { + const listItem = document.createElement("li"); + const checkboxWrapper = document.createElement("label"); + const checkboxStyler = document.createElement("span"); + const checkbox = document.createElement("input"); + const content = document.createElement("div"); + const updateA11Y = (currentNode) => { + var _a, _b; + checkbox.ariaLabel = ((_b = (_a = this.options.a11y) == null ? void 0 : _a.checkboxLabel) == null ? void 0 : _b.call(_a, currentNode, checkbox.checked)) || `Task item checkbox for ${currentNode.textContent || "empty task item"}`; + }; + updateA11Y(node); + checkboxWrapper.contentEditable = "false"; + checkbox.type = "checkbox"; + checkbox.addEventListener("mousedown", (event) => event.preventDefault()); + checkbox.addEventListener("change", (event) => { + if (!editor.isEditable && !this.options.onReadOnlyChecked) { + checkbox.checked = !checkbox.checked; + return; + } + const { checked } = event.target; + if (editor.isEditable && typeof getPos === "function") { + editor.chain().focus(void 0, { scrollIntoView: false }).command(({ tr: tr2 }) => { + const position = getPos(); + if (typeof position !== "number") { + return false; + } + const currentNode = tr2.doc.nodeAt(position); + tr2.setNodeMarkup(position, void 0, { + ...currentNode == null ? void 0 : currentNode.attrs, + checked + }); + return true; + }).run(); + } + if (!editor.isEditable && this.options.onReadOnlyChecked) { + if (!this.options.onReadOnlyChecked(node, checked)) { + checkbox.checked = !checkbox.checked; + } + } + }); + Object.entries(this.options.HTMLAttributes).forEach(([key, value]) => { + listItem.setAttribute(key, value); + }); + listItem.dataset.checked = node.attrs.checked; + checkbox.checked = node.attrs.checked; + checkboxWrapper.append(checkbox, checkboxStyler); + listItem.append(checkboxWrapper, content); + Object.entries(HTMLAttributes).forEach(([key, value]) => { + listItem.setAttribute(key, value); + }); + let prevRenderedAttributeKeys = new Set(Object.keys(HTMLAttributes)); + return { + dom: listItem, + contentDOM: content, + update: (updatedNode) => { + if (updatedNode.type !== this.type) { + return false; + } + listItem.dataset.checked = updatedNode.attrs.checked; + checkbox.checked = updatedNode.attrs.checked; + updateA11Y(updatedNode); + const extensionAttributes = editor.extensionManager.attributes; + const newHTMLAttributes = getRenderedAttributes(updatedNode, extensionAttributes); + const newKeys = new Set(Object.keys(newHTMLAttributes)); + const staticAttrs = this.options.HTMLAttributes; + prevRenderedAttributeKeys.forEach((key) => { + if (!newKeys.has(key)) { + if (key in staticAttrs) { + listItem.setAttribute(key, staticAttrs[key]); + } else { + listItem.removeAttribute(key); + } + } + }); + Object.entries(newHTMLAttributes).forEach(([key, value]) => { + if (value === null || value === void 0) { + if (key in staticAttrs) { + listItem.setAttribute(key, staticAttrs[key]); + } else { + listItem.removeAttribute(key); + } + } else { + listItem.setAttribute(key, value); + } + }); + prevRenderedAttributeKeys = newKeys; + return true; + } + }; + }; + }, + addInputRules() { + return [ + wrappingInputRule({ + find: inputRegex2, + type: this.type, + getAttributes: (match2) => ({ + checked: match2[match2.length - 1] === "x" + }) + }) + ]; + } +}); +var TaskList = Node3.create({ + name: "taskList", + addOptions() { + return { + itemTypeName: "taskItem", + HTMLAttributes: {} + }; + }, + group: "block list", + content() { + return `${this.options.itemTypeName}+`; + }, + parseHTML() { + return [ + { + tag: `ul[data-type="${this.name}"]`, + priority: 51 + } + ]; + }, + renderHTML({ HTMLAttributes }) { + return [ + "ul", + mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { "data-type": this.name }), + 0 + ]; + }, + parseMarkdown: (token, h2) => { + return h2.createNode("taskList", {}, h2.parseChildren(token.items || [])); + }, + renderMarkdown: (node, h2) => { + if (!node.content) { + return ""; + } + return h2.renderChildren(node.content, "\n"); + }, + markdownTokenizer: { + name: "taskList", + level: "block", + start(src) { + var _a; + const index = (_a = src.match(/^\s*[-+*]\s+\[([ xX])\]\s+/)) == null ? void 0 : _a.index; + return index !== void 0 ? index : -1; + }, + tokenize(src, tokens, lexer) { + const parseTaskListContent = (content) => { + const nestedResult = parseIndentedBlocks( + content, + { + itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/, + extractItemData: (match2) => ({ + indentLevel: match2[1].length, + mainContent: match2[4], + checked: match2[3].toLowerCase() === "x" + }), + createToken: (data, nestedTokens) => ({ + type: "taskItem", + raw: "", + mainContent: data.mainContent, + indentLevel: data.indentLevel, + checked: data.checked, + text: data.mainContent, + tokens: lexer.inlineTokens(data.mainContent), + nestedTokens + }), + // Allow recursive nesting + customNestedParser: parseTaskListContent + }, + lexer + ); + if (nestedResult) { + return [ + { + type: "taskList", + raw: nestedResult.raw, + items: nestedResult.items + } + ]; + } + return lexer.blockTokens(content); + }; + const result = parseIndentedBlocks( + src, + { + itemPattern: /^(\s*)([-+*])\s+\[([ xX])\]\s+(.*)$/, + extractItemData: (match2) => ({ + indentLevel: match2[1].length, + mainContent: match2[4], + checked: match2[3].toLowerCase() === "x" + }), + createToken: (data, nestedTokens) => ({ + type: "taskItem", + raw: "", + mainContent: data.mainContent, + indentLevel: data.indentLevel, + checked: data.checked, + text: data.mainContent, + tokens: lexer.inlineTokens(data.mainContent), + nestedTokens + }), + // Use the recursive parser for nested content + customNestedParser: parseTaskListContent + }, + lexer + ); + if (!result) { + return void 0; + } + return { + type: "taskList", + raw: result.raw, + items: result.items + }; + } + }, + markdownOptions: { + indentsContent: true + }, + addCommands() { + return { + toggleTaskList: () => ({ commands }) => { + return commands.toggleList(this.name, this.options.itemTypeName); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Shift-9": () => this.editor.commands.toggleTaskList() + }; + } +}); +var ListKit = Extension.create({ + name: "listKit", + addExtensions() { + const extensions = []; + if (this.options.bulletList !== false) { + extensions.push(BulletList.configure(this.options.bulletList)); + } + if (this.options.listItem !== false) { + extensions.push(ListItem.configure(this.options.listItem)); + } + if (this.options.listKeymap !== false) { + extensions.push(ListKeymap.configure(this.options.listKeymap)); + } + if (this.options.orderedList !== false) { + extensions.push(OrderedList.configure(this.options.orderedList)); + } + if (this.options.taskItem !== false) { + extensions.push(TaskItem.configure(this.options.taskItem)); + } + if (this.options.taskList !== false) { + extensions.push(TaskList.configure(this.options.taskList)); + } + return extensions; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-paragraph@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-paragraph/dist/index.js +var EMPTY_PARAGRAPH_MARKDOWN = " "; +var NBSP_CHAR = "\xA0"; +var Paragraph = Node3.create({ + name: "paragraph", + priority: 1e3, + addOptions() { + return { + HTMLAttributes: {} + }; + }, + group: "block", + content: "inline*", + parseHTML() { + return [{ tag: "p" }]; + }, + renderHTML({ HTMLAttributes }) { + return ["p", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + parseMarkdown: (token, helpers) => { + const tokens = token.tokens || []; + if (tokens.length === 1 && tokens[0].type === "image") { + return helpers.parseChildren([tokens[0]]); + } + const content = helpers.parseInline(tokens); + const hasExplicitEmptyParagraphMarker = tokens.length === 1 && tokens[0].type === "text" && (tokens[0].raw === EMPTY_PARAGRAPH_MARKDOWN || tokens[0].text === EMPTY_PARAGRAPH_MARKDOWN || tokens[0].raw === NBSP_CHAR || tokens[0].text === NBSP_CHAR); + if (hasExplicitEmptyParagraphMarker && content.length === 1 && content[0].type === "text" && (content[0].text === EMPTY_PARAGRAPH_MARKDOWN || content[0].text === NBSP_CHAR)) { + return helpers.createNode("paragraph", void 0, []); + } + return helpers.createNode("paragraph", void 0, content); + }, + renderMarkdown: (node, h2, ctx) => { + var _a, _b; + if (!node) { + return ""; + } + const content = Array.isArray(node.content) ? node.content : []; + if (content.length === 0) { + const previousContent = Array.isArray((_a = ctx == null ? void 0 : ctx.previousNode) == null ? void 0 : _a.content) ? ctx.previousNode.content : []; + const previousNodeIsEmptyParagraph = ((_b = ctx == null ? void 0 : ctx.previousNode) == null ? void 0 : _b.type) === "paragraph" && previousContent.length === 0; + return previousNodeIsEmptyParagraph ? EMPTY_PARAGRAPH_MARKDOWN : ""; + } + return h2.renderChildren(content); + }, + addCommands() { + return { + setParagraph: () => ({ commands }) => { + return commands.setNode(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Alt-0": () => this.editor.commands.setParagraph() + }; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-strike@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-strike/dist/index.js +var inputRegex3 = /(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))$/; +var pasteRegex = /(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))/g; +var Strike = Mark2.create({ + name: "strike", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + parseHTML() { + return [ + { + tag: "s" + }, + { + tag: "del" + }, + { + tag: "strike" + }, + { + style: "text-decoration", + consuming: false, + getAttrs: (style2) => style2.includes("line-through") ? {} : false + } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["s", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + markdownTokenName: "del", + parseMarkdown: (token, helpers) => { + return helpers.applyMark("strike", helpers.parseInline(token.tokens || [])); + }, + renderMarkdown: (node, h2) => { + return `~~${h2.renderChildren(node)}~~`; + }, + addCommands() { + return { + setStrike: () => ({ commands }) => { + return commands.setMark(this.name); + }, + toggleStrike: () => ({ commands }) => { + return commands.toggleMark(this.name); + }, + unsetStrike: () => ({ commands }) => { + return commands.unsetMark(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Shift-s": () => this.editor.commands.toggleStrike() + }; + }, + addInputRules() { + return [ + markInputRule({ + find: inputRegex3, + type: this.type + }) + ]; + }, + addPasteRules() { + return [ + markPasteRule({ + find: pasteRegex, + type: this.type + }) + ]; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-text@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-text/dist/index.js +var Text2 = Node3.create({ + name: "text", + group: "inline", + parseMarkdown: (token) => { + return { + type: "text", + text: token.text || "" + }; + }, + renderMarkdown: (node) => node.text || "" +}); + +// ../../node_modules/.pnpm/@tiptap+extension-underline@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-underline/dist/index.js +var Underline = Mark2.create({ + name: "underline", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + parseHTML() { + return [ + { + tag: "u" + }, + { + style: "text-decoration", + consuming: false, + getAttrs: (style2) => style2.includes("underline") ? {} : false + } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["u", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + parseMarkdown(token, helpers) { + return helpers.applyMark(this.name || "underline", helpers.parseInline(token.tokens || [])); + }, + renderMarkdown(node, helpers) { + return `++${helpers.renderChildren(node)}++`; + }, + markdownTokenizer: { + name: "underline", + level: "inline", + start(src) { + return src.indexOf("++"); + }, + tokenize(src, _tokens, lexer) { + const rule = /^(\+\+)([\s\S]+?)(\+\+)/; + const match2 = rule.exec(src); + if (!match2) { + return void 0; + } + const innerContent = match2[2].trim(); + return { + type: "underline", + raw: match2[0], + text: innerContent, + tokens: lexer.inlineTokens(innerContent) + }; + } + }, + addCommands() { + return { + setUnderline: () => ({ commands }) => { + return commands.setMark(this.name); + }, + toggleUnderline: () => ({ commands }) => { + return commands.toggleMark(this.name); + }, + unsetUnderline: () => ({ commands }) => { + return commands.unsetMark(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-u": () => this.editor.commands.toggleUnderline(), + "Mod-U": () => this.editor.commands.toggleUnderline() + }; + } +}); + +// ../../node_modules/.pnpm/prosemirror-dropcursor@1.8.2/node_modules/prosemirror-dropcursor/dist/index.js +function dropCursor(options = {}) { + return new Plugin({ + view(editorView) { + return new DropCursorView(editorView, options); + } + }); +} +var DropCursorView = class { + constructor(editorView, options) { + var _a; + this.editorView = editorView; + this.cursorPos = null; + this.element = null; + this.timeout = -1; + this.width = (_a = options.width) !== null && _a !== void 0 ? _a : 1; + this.color = options.color === false ? void 0 : options.color || "black"; + this.class = options.class; + this.handlers = ["dragover", "dragend", "drop", "dragleave"].map((name) => { + let handler = (e) => { + this[name](e); + }; + editorView.dom.addEventListener(name, handler); + return { name, handler }; + }); + } + destroy() { + this.handlers.forEach(({ name, handler }) => this.editorView.dom.removeEventListener(name, handler)); + } + update(editorView, prevState) { + if (this.cursorPos != null && prevState.doc != editorView.state.doc) { + if (this.cursorPos > editorView.state.doc.content.size) + this.setCursor(null); + else + this.updateOverlay(); + } + } + setCursor(pos) { + if (pos == this.cursorPos) + return; + this.cursorPos = pos; + if (pos == null) { + this.element.parentNode.removeChild(this.element); + this.element = null; + } else { + this.updateOverlay(); + } + } + updateOverlay() { + let $pos = this.editorView.state.doc.resolve(this.cursorPos); + let isBlock2 = !$pos.parent.inlineContent, rect; + let editorDOM = this.editorView.dom, editorRect = editorDOM.getBoundingClientRect(); + let scaleX = editorRect.width / editorDOM.offsetWidth, scaleY = editorRect.height / editorDOM.offsetHeight; + if (isBlock2) { + let before = $pos.nodeBefore, after = $pos.nodeAfter; + if (before || after) { + let node = this.editorView.nodeDOM(this.cursorPos - (before ? before.nodeSize : 0)); + if (node) { + let nodeRect = node.getBoundingClientRect(); + let top = before ? nodeRect.bottom : nodeRect.top; + if (before && after) + top = (top + this.editorView.nodeDOM(this.cursorPos).getBoundingClientRect().top) / 2; + let halfWidth = this.width / 2 * scaleY; + rect = { left: nodeRect.left, right: nodeRect.right, top: top - halfWidth, bottom: top + halfWidth }; + } + } + } + if (!rect) { + let coords = this.editorView.coordsAtPos(this.cursorPos); + let halfWidth = this.width / 2 * scaleX; + rect = { left: coords.left - halfWidth, right: coords.left + halfWidth, top: coords.top, bottom: coords.bottom }; + } + let parent = this.editorView.dom.offsetParent; + if (!this.element) { + this.element = parent.appendChild(document.createElement("div")); + if (this.class) + this.element.className = this.class; + this.element.style.cssText = "position: absolute; z-index: 50; pointer-events: none;"; + if (this.color) { + this.element.style.backgroundColor = this.color; + } + } + this.element.classList.toggle("prosemirror-dropcursor-block", isBlock2); + this.element.classList.toggle("prosemirror-dropcursor-inline", !isBlock2); + let parentLeft, parentTop; + if (!parent || parent == document.body && getComputedStyle(parent).position == "static") { + parentLeft = -pageXOffset; + parentTop = -pageYOffset; + } else { + let rect2 = parent.getBoundingClientRect(); + let parentScaleX = rect2.width / parent.offsetWidth, parentScaleY = rect2.height / parent.offsetHeight; + parentLeft = rect2.left - parent.scrollLeft * parentScaleX; + parentTop = rect2.top - parent.scrollTop * parentScaleY; + } + this.element.style.left = (rect.left - parentLeft) / scaleX + "px"; + this.element.style.top = (rect.top - parentTop) / scaleY + "px"; + this.element.style.width = (rect.right - rect.left) / scaleX + "px"; + this.element.style.height = (rect.bottom - rect.top) / scaleY + "px"; + } + scheduleRemoval(timeout2) { + clearTimeout(this.timeout); + this.timeout = setTimeout(() => this.setCursor(null), timeout2); + } + dragover(event) { + if (!this.editorView.editable) + return; + let pos = this.editorView.posAtCoords({ left: event.clientX, top: event.clientY }); + let node = pos && pos.inside >= 0 && this.editorView.state.doc.nodeAt(pos.inside); + let disableDropCursor = node && node.type.spec.disableDropCursor; + let disabled = typeof disableDropCursor == "function" ? disableDropCursor(this.editorView, pos, event) : disableDropCursor; + if (pos && !disabled) { + let target = pos.pos; + if (this.editorView.dragging && this.editorView.dragging.slice) { + let point = dropPoint(this.editorView.state.doc, target, this.editorView.dragging.slice); + if (point != null) + target = point; + } + this.setCursor(target); + this.scheduleRemoval(5e3); + } + } + dragend() { + this.scheduleRemoval(20); + } + drop() { + this.scheduleRemoval(20); + } + dragleave(event) { + if (!this.editorView.dom.contains(event.relatedTarget)) + this.setCursor(null); + } +}; + +// ../../node_modules/.pnpm/prosemirror-gapcursor@1.4.1/node_modules/prosemirror-gapcursor/dist/index.js +var GapCursor = class _GapCursor extends Selection { + /** + Create a gap cursor. + */ + constructor($pos) { + super($pos, $pos); + } + map(doc4, mapping) { + let $pos = doc4.resolve(mapping.map(this.head)); + return _GapCursor.valid($pos) ? new _GapCursor($pos) : Selection.near($pos); + } + content() { + return Slice.empty; + } + eq(other) { + return other instanceof _GapCursor && other.head == this.head; + } + toJSON() { + return { type: "gapcursor", pos: this.head }; + } + /** + @internal + */ + static fromJSON(doc4, json) { + if (typeof json.pos != "number") + throw new RangeError("Invalid input for GapCursor.fromJSON"); + return new _GapCursor(doc4.resolve(json.pos)); + } + /** + @internal + */ + getBookmark() { + return new GapBookmark(this.anchor); + } + /** + @internal + */ + static valid($pos) { + let parent = $pos.parent; + if (parent.inlineContent || !closedBefore($pos) || !closedAfter($pos)) + return false; + let override = parent.type.spec.allowGapCursor; + if (override != null) + return override; + let deflt = parent.contentMatchAt($pos.index()).defaultType; + return deflt && deflt.isTextblock; + } + /** + @internal + */ + static findGapCursorFrom($pos, dir, mustMove = false) { + search: for (; ; ) { + if (!mustMove && _GapCursor.valid($pos)) + return $pos; + let pos = $pos.pos, next2 = null; + for (let d2 = $pos.depth; ; d2--) { + let parent = $pos.node(d2); + if (dir > 0 ? $pos.indexAfter(d2) < parent.childCount : $pos.index(d2) > 0) { + next2 = parent.child(dir > 0 ? $pos.indexAfter(d2) : $pos.index(d2) - 1); + break; + } else if (d2 == 0) { + return null; + } + pos += dir; + let $cur = $pos.doc.resolve(pos); + if (_GapCursor.valid($cur)) + return $cur; + } + for (; ; ) { + let inside = dir > 0 ? next2.firstChild : next2.lastChild; + if (!inside) { + if (next2.isAtom && !next2.isText && !NodeSelection.isSelectable(next2)) { + $pos = $pos.doc.resolve(pos + next2.nodeSize * dir); + mustMove = false; + continue search; + } + break; + } + next2 = inside; + pos += dir; + let $cur = $pos.doc.resolve(pos); + if (_GapCursor.valid($cur)) + return $cur; + } + return null; + } + } +}; +GapCursor.prototype.visible = false; +GapCursor.findFrom = GapCursor.findGapCursorFrom; +Selection.jsonID("gapcursor", GapCursor); +var GapBookmark = class _GapBookmark { + constructor(pos) { + this.pos = pos; + } + map(mapping) { + return new _GapBookmark(mapping.map(this.pos)); + } + resolve(doc4) { + let $pos = doc4.resolve(this.pos); + return GapCursor.valid($pos) ? new GapCursor($pos) : Selection.near($pos); + } +}; +function needsGap(type) { + return type.isAtom || type.spec.isolating || type.spec.createGapCursor; +} +function closedBefore($pos) { + for (let d2 = $pos.depth; d2 >= 0; d2--) { + let index = $pos.index(d2), parent = $pos.node(d2); + if (index == 0) { + if (parent.type.spec.isolating) + return true; + continue; + } + for (let before = parent.child(index - 1); ; before = before.lastChild) { + if (before.childCount == 0 && !before.inlineContent || needsGap(before.type)) + return true; + if (before.inlineContent) + return false; + } + } + return true; +} +function closedAfter($pos) { + for (let d2 = $pos.depth; d2 >= 0; d2--) { + let index = $pos.indexAfter(d2), parent = $pos.node(d2); + if (index == parent.childCount) { + if (parent.type.spec.isolating) + return true; + continue; + } + for (let after = parent.child(index); ; after = after.firstChild) { + if (after.childCount == 0 && !after.inlineContent || needsGap(after.type)) + return true; + if (after.inlineContent) + return false; + } + } + return true; +} +function gapCursor() { + return new Plugin({ + props: { + decorations: drawGapCursor, + createSelectionBetween(_view, $anchor, $head) { + return $anchor.pos == $head.pos && GapCursor.valid($head) ? new GapCursor($head) : null; + }, + handleClick, + handleKeyDown, + handleDOMEvents: { beforeinput } + } + }); +} +var handleKeyDown = keydownHandler({ + "ArrowLeft": arrow("horiz", -1), + "ArrowRight": arrow("horiz", 1), + "ArrowUp": arrow("vert", -1), + "ArrowDown": arrow("vert", 1) +}); +function arrow(axis, dir) { + const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left"; + return function(state, dispatch, view) { + let sel = state.selection; + let $start = dir > 0 ? sel.$to : sel.$from, mustMove = sel.empty; + if (sel instanceof TextSelection) { + if (!view.endOfTextblock(dirStr) || $start.depth == 0) + return false; + mustMove = false; + $start = state.doc.resolve(dir > 0 ? $start.after() : $start.before()); + } + let $found = GapCursor.findGapCursorFrom($start, dir, mustMove); + if (!$found) + return false; + if (dispatch) + dispatch(state.tr.setSelection(new GapCursor($found))); + return true; + }; +} +function handleClick(view, pos, event) { + if (!view || !view.editable) + return false; + let $pos = view.state.doc.resolve(pos); + if (!GapCursor.valid($pos)) + return false; + let clickPos = view.posAtCoords({ left: event.clientX, top: event.clientY }); + if (clickPos && clickPos.inside > -1 && NodeSelection.isSelectable(view.state.doc.nodeAt(clickPos.inside))) + return false; + view.dispatch(view.state.tr.setSelection(new GapCursor($pos))); + return true; +} +function beforeinput(view, event) { + if (event.inputType != "insertCompositionText" || !(view.state.selection instanceof GapCursor)) + return false; + let { $from } = view.state.selection; + let insert = $from.parent.contentMatchAt($from.index()).findWrapping(view.state.schema.nodes.text); + if (!insert) + return false; + let frag = Fragment.empty; + for (let i = insert.length - 1; i >= 0; i--) + frag = Fragment.from(insert[i].createAndFill(null, frag)); + let tr2 = view.state.tr.replace($from.pos, $from.pos, new Slice(frag, 0, 0)); + tr2.setSelection(TextSelection.near(tr2.doc.resolve($from.pos + 1))); + view.dispatch(tr2); + return false; +} +function drawGapCursor(state) { + if (!(state.selection instanceof GapCursor)) + return null; + let node = document.createElement("div"); + node.className = "ProseMirror-gapcursor"; + return DecorationSet.create(state.doc, [Decoration.widget(state.selection.head, node, { key: "gapcursor" })]); +} + +// ../../node_modules/.pnpm/rope-sequence@1.3.4/node_modules/rope-sequence/dist/index.js +var GOOD_LEAF_SIZE = 200; +var RopeSequence = function RopeSequence2() { +}; +RopeSequence.prototype.append = function append(other) { + if (!other.length) { + return this; + } + other = RopeSequence.from(other); + return !this.length && other || other.length < GOOD_LEAF_SIZE && this.leafAppend(other) || this.length < GOOD_LEAF_SIZE && other.leafPrepend(this) || this.appendInner(other); +}; +RopeSequence.prototype.prepend = function prepend(other) { + if (!other.length) { + return this; + } + return RopeSequence.from(other).append(this); +}; +RopeSequence.prototype.appendInner = function appendInner(other) { + return new Append(this, other); +}; +RopeSequence.prototype.slice = function slice(from3, to) { + if (from3 === void 0) from3 = 0; + if (to === void 0) to = this.length; + if (from3 >= to) { + return RopeSequence.empty; + } + return this.sliceInner(Math.max(0, from3), Math.min(this.length, to)); +}; +RopeSequence.prototype.get = function get(i) { + if (i < 0 || i >= this.length) { + return void 0; + } + return this.getInner(i); +}; +RopeSequence.prototype.forEach = function forEach2(f, from3, to) { + if (from3 === void 0) from3 = 0; + if (to === void 0) to = this.length; + if (from3 <= to) { + this.forEachInner(f, from3, to, 0); + } else { + this.forEachInvertedInner(f, from3, to, 0); + } +}; +RopeSequence.prototype.map = function map(f, from3, to) { + if (from3 === void 0) from3 = 0; + if (to === void 0) to = this.length; + var result = []; + this.forEach(function(elt, i) { + return result.push(f(elt, i)); + }, from3, to); + return result; +}; +RopeSequence.from = function from(values) { + if (values instanceof RopeSequence) { + return values; + } + return values && values.length ? new Leaf(values) : RopeSequence.empty; +}; +var Leaf = /* @__PURE__ */ (function(RopeSequence3) { + function Leaf2(values) { + RopeSequence3.call(this); + this.values = values; + } + if (RopeSequence3) Leaf2.__proto__ = RopeSequence3; + Leaf2.prototype = Object.create(RopeSequence3 && RopeSequence3.prototype); + Leaf2.prototype.constructor = Leaf2; + var prototypeAccessors = { length: { configurable: true }, depth: { configurable: true } }; + Leaf2.prototype.flatten = function flatten() { + return this.values; + }; + Leaf2.prototype.sliceInner = function sliceInner(from3, to) { + if (from3 == 0 && to == this.length) { + return this; + } + return new Leaf2(this.values.slice(from3, to)); + }; + Leaf2.prototype.getInner = function getInner(i) { + return this.values[i]; + }; + Leaf2.prototype.forEachInner = function forEachInner(f, from3, to, start) { + for (var i = from3; i < to; i++) { + if (f(this.values[i], start + i) === false) { + return false; + } + } + }; + Leaf2.prototype.forEachInvertedInner = function forEachInvertedInner(f, from3, to, start) { + for (var i = from3 - 1; i >= to; i--) { + if (f(this.values[i], start + i) === false) { + return false; + } + } + }; + Leaf2.prototype.leafAppend = function leafAppend(other) { + if (this.length + other.length <= GOOD_LEAF_SIZE) { + return new Leaf2(this.values.concat(other.flatten())); + } + }; + Leaf2.prototype.leafPrepend = function leafPrepend(other) { + if (this.length + other.length <= GOOD_LEAF_SIZE) { + return new Leaf2(other.flatten().concat(this.values)); + } + }; + prototypeAccessors.length.get = function() { + return this.values.length; + }; + prototypeAccessors.depth.get = function() { + return 0; + }; + Object.defineProperties(Leaf2.prototype, prototypeAccessors); + return Leaf2; +})(RopeSequence); +RopeSequence.empty = new Leaf([]); +var Append = /* @__PURE__ */ (function(RopeSequence3) { + function Append2(left, right) { + RopeSequence3.call(this); + this.left = left; + this.right = right; + this.length = left.length + right.length; + this.depth = Math.max(left.depth, right.depth) + 1; + } + if (RopeSequence3) Append2.__proto__ = RopeSequence3; + Append2.prototype = Object.create(RopeSequence3 && RopeSequence3.prototype); + Append2.prototype.constructor = Append2; + Append2.prototype.flatten = function flatten() { + return this.left.flatten().concat(this.right.flatten()); + }; + Append2.prototype.getInner = function getInner(i) { + return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length); + }; + Append2.prototype.forEachInner = function forEachInner(f, from3, to, start) { + var leftLen = this.left.length; + if (from3 < leftLen && this.left.forEachInner(f, from3, Math.min(to, leftLen), start) === false) { + return false; + } + if (to > leftLen && this.right.forEachInner(f, Math.max(from3 - leftLen, 0), Math.min(this.length, to) - leftLen, start + leftLen) === false) { + return false; + } + }; + Append2.prototype.forEachInvertedInner = function forEachInvertedInner(f, from3, to, start) { + var leftLen = this.left.length; + if (from3 > leftLen && this.right.forEachInvertedInner(f, from3 - leftLen, Math.max(to, leftLen) - leftLen, start + leftLen) === false) { + return false; + } + if (to < leftLen && this.left.forEachInvertedInner(f, Math.min(from3, leftLen), to, start) === false) { + return false; + } + }; + Append2.prototype.sliceInner = function sliceInner(from3, to) { + if (from3 == 0 && to == this.length) { + return this; + } + var leftLen = this.left.length; + if (to <= leftLen) { + return this.left.slice(from3, to); + } + if (from3 >= leftLen) { + return this.right.slice(from3 - leftLen, to - leftLen); + } + return this.left.slice(from3, leftLen).append(this.right.slice(0, to - leftLen)); + }; + Append2.prototype.leafAppend = function leafAppend(other) { + var inner = this.right.leafAppend(other); + if (inner) { + return new Append2(this.left, inner); + } + }; + Append2.prototype.leafPrepend = function leafPrepend(other) { + var inner = this.left.leafPrepend(other); + if (inner) { + return new Append2(inner, this.right); + } + }; + Append2.prototype.appendInner = function appendInner2(other) { + if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1) { + return new Append2(this.left, new Append2(this.right, other)); + } + return new Append2(this, other); + }; + return Append2; +})(RopeSequence); +var dist_default2 = RopeSequence; + +// ../../node_modules/.pnpm/prosemirror-history@1.5.0/node_modules/prosemirror-history/dist/index.js +var max_empty_items = 500; +var Branch = class _Branch { + constructor(items, eventCount) { + this.items = items; + this.eventCount = eventCount; + } + // Pop the latest event off the branch's history and apply it + // to a document transform. + popEvent(state, preserveItems) { + if (this.eventCount == 0) + return null; + let end = this.items.length; + for (; ; end--) { + let next2 = this.items.get(end - 1); + if (next2.selection) { + --end; + break; + } + } + let remap, mapFrom; + if (preserveItems) { + remap = this.remapping(end, this.items.length); + mapFrom = remap.maps.length; + } + let transform = state.tr; + let selection, remaining; + let addAfter = [], addBefore = []; + this.items.forEach((item, i) => { + if (!item.step) { + if (!remap) { + remap = this.remapping(end, i + 1); + mapFrom = remap.maps.length; + } + mapFrom--; + addBefore.push(item); + return; + } + if (remap) { + addBefore.push(new Item(item.map)); + let step = item.step.map(remap.slice(mapFrom)), map4; + if (step && transform.maybeStep(step).doc) { + map4 = transform.mapping.maps[transform.mapping.maps.length - 1]; + addAfter.push(new Item(map4, void 0, void 0, addAfter.length + addBefore.length)); + } + mapFrom--; + if (map4) + remap.appendMap(map4, mapFrom); + } else { + transform.maybeStep(item.step); + } + if (item.selection) { + selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection; + remaining = new _Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1); + return false; + } + }, this.items.length, 0); + return { remaining, transform, selection }; + } + // Create a new branch with the given transform added. + addTransform(transform, selection, histOptions, preserveItems) { + let newItems = [], eventCount = this.eventCount; + let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null; + for (let i = 0; i < transform.steps.length; i++) { + let step = transform.steps[i].invert(transform.docs[i]); + let item = new Item(transform.mapping.maps[i], step, selection), merged; + if (merged = lastItem && lastItem.merge(item)) { + item = merged; + if (i) + newItems.pop(); + else + oldItems = oldItems.slice(0, oldItems.length - 1); + } + newItems.push(item); + if (selection) { + eventCount++; + selection = void 0; + } + if (!preserveItems) + lastItem = item; + } + let overflow = eventCount - histOptions.depth; + if (overflow > DEPTH_OVERFLOW) { + oldItems = cutOffEvents(oldItems, overflow); + eventCount -= overflow; + } + return new _Branch(oldItems.append(newItems), eventCount); + } + remapping(from3, to) { + let maps = new Mapping(); + this.items.forEach((item, i) => { + let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from3 ? maps.maps.length - item.mirrorOffset : void 0; + maps.appendMap(item.map, mirrorPos); + }, from3, to); + return maps; + } + addMaps(array) { + if (this.eventCount == 0) + return this; + return new _Branch(this.items.append(array.map((map4) => new Item(map4))), this.eventCount); + } + // When the collab module receives remote changes, the history has + // to know about those, so that it can adjust the steps that were + // rebased on top of the remote changes, and include the position + // maps for the remote changes in its array of items. + rebased(rebasedTransform, rebasedCount) { + if (!this.eventCount) + return this; + let rebasedItems = [], start = Math.max(0, this.items.length - rebasedCount); + let mapping = rebasedTransform.mapping; + let newUntil = rebasedTransform.steps.length; + let eventCount = this.eventCount; + this.items.forEach((item) => { + if (item.selection) + eventCount--; + }, start); + let iRebased = rebasedCount; + this.items.forEach((item) => { + let pos = mapping.getMirror(--iRebased); + if (pos == null) + return; + newUntil = Math.min(newUntil, pos); + let map4 = mapping.maps[pos]; + if (item.step) { + let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]); + let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos)); + if (selection) + eventCount++; + rebasedItems.push(new Item(map4, step, selection)); + } else { + rebasedItems.push(new Item(map4)); + } + }, start); + let newMaps = []; + for (let i = rebasedCount; i < newUntil; i++) + newMaps.push(new Item(mapping.maps[i])); + let items = this.items.slice(0, start).append(newMaps).append(rebasedItems); + let branch = new _Branch(items, eventCount); + if (branch.emptyItemCount() > max_empty_items) + branch = branch.compress(this.items.length - rebasedItems.length); + return branch; + } + emptyItemCount() { + let count = 0; + this.items.forEach((item) => { + if (!item.step) + count++; + }); + return count; + } + // Compressing a branch means rewriting it to push the air (map-only + // items) out. During collaboration, these naturally accumulate + // because each remote change adds one. The `upto` argument is used + // to ensure that only the items below a given level are compressed, + // because `rebased` relies on a clean, untouched set of items in + // order to associate old items with rebased steps. + compress(upto = this.items.length) { + let remap = this.remapping(0, upto), mapFrom = remap.maps.length; + let items = [], events = 0; + this.items.forEach((item, i) => { + if (i >= upto) { + items.push(item); + if (item.selection) + events++; + } else if (item.step) { + let step = item.step.map(remap.slice(mapFrom)), map4 = step && step.getMap(); + mapFrom--; + if (map4) + remap.appendMap(map4, mapFrom); + if (step) { + let selection = item.selection && item.selection.map(remap.slice(mapFrom)); + if (selection) + events++; + let newItem = new Item(map4.invert(), step, selection), merged, last2 = items.length - 1; + if (merged = items.length && items[last2].merge(newItem)) + items[last2] = merged; + else + items.push(newItem); + } + } else if (item.map) { + mapFrom--; + } + }, this.items.length, 0); + return new _Branch(dist_default2.from(items.reverse()), events); + } +}; +Branch.empty = new Branch(dist_default2.empty, 0); +function cutOffEvents(items, n) { + let cutPoint; + items.forEach((item, i) => { + if (item.selection && n-- == 0) { + cutPoint = i; + return false; + } + }); + return items.slice(cutPoint); +} +var Item = class _Item { + constructor(map4, step, selection, mirrorOffset) { + this.map = map4; + this.step = step; + this.selection = selection; + this.mirrorOffset = mirrorOffset; + } + merge(other) { + if (this.step && other.step && !other.selection) { + let step = other.step.merge(this.step); + if (step) + return new _Item(step.getMap().invert(), step, this.selection); + } + } +}; +var HistoryState = class { + constructor(done, undone, prevRanges, prevTime, prevComposition) { + this.done = done; + this.undone = undone; + this.prevRanges = prevRanges; + this.prevTime = prevTime; + this.prevComposition = prevComposition; + } +}; +var DEPTH_OVERFLOW = 20; +function applyTransaction(history2, state, tr2, options) { + let historyTr = tr2.getMeta(historyKey), rebased; + if (historyTr) + return historyTr.historyState; + if (tr2.getMeta(closeHistoryKey)) + history2 = new HistoryState(history2.done, history2.undone, null, 0, -1); + let appended = tr2.getMeta("appendedTransaction"); + if (tr2.steps.length == 0) { + return history2; + } else if (appended && appended.getMeta(historyKey)) { + if (appended.getMeta(historyKey).redo) + return new HistoryState(history2.done.addTransform(tr2, void 0, options, mustPreserveItems(state)), history2.undone, rangesFor(tr2.mapping.maps), history2.prevTime, history2.prevComposition); + else + return new HistoryState(history2.done, history2.undone.addTransform(tr2, void 0, options, mustPreserveItems(state)), null, history2.prevTime, history2.prevComposition); + } else if (tr2.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) { + let composition = tr2.getMeta("composition"); + let newGroup = history2.prevTime == 0 || !appended && history2.prevComposition != composition && (history2.prevTime < (tr2.time || 0) - options.newGroupDelay || !isAdjacentTo(tr2, history2.prevRanges)); + let prevRanges = appended ? mapRanges(history2.prevRanges, tr2.mapping) : rangesFor(tr2.mapping.maps); + return new HistoryState(history2.done.addTransform(tr2, newGroup ? state.selection.getBookmark() : void 0, options, mustPreserveItems(state)), Branch.empty, prevRanges, tr2.time, composition == null ? history2.prevComposition : composition); + } else if (rebased = tr2.getMeta("rebased")) { + return new HistoryState(history2.done.rebased(tr2, rebased), history2.undone.rebased(tr2, rebased), mapRanges(history2.prevRanges, tr2.mapping), history2.prevTime, history2.prevComposition); + } else { + return new HistoryState(history2.done.addMaps(tr2.mapping.maps), history2.undone.addMaps(tr2.mapping.maps), mapRanges(history2.prevRanges, tr2.mapping), history2.prevTime, history2.prevComposition); + } +} +function isAdjacentTo(transform, prevRanges) { + if (!prevRanges) + return false; + if (!transform.docChanged) + return true; + let adjacent = false; + transform.mapping.maps[0].forEach((start, end) => { + for (let i = 0; i < prevRanges.length; i += 2) + if (start <= prevRanges[i + 1] && end >= prevRanges[i]) + adjacent = true; + }); + return adjacent; +} +function rangesFor(maps) { + let result = []; + for (let i = maps.length - 1; i >= 0 && result.length == 0; i--) + maps[i].forEach((_from, _to, from3, to) => result.push(from3, to)); + return result; +} +function mapRanges(ranges, mapping) { + if (!ranges) + return null; + let result = []; + for (let i = 0; i < ranges.length; i += 2) { + let from3 = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1); + if (from3 <= to) + result.push(from3, to); + } + return result; +} +function histTransaction(history2, state, redo3) { + let preserveItems = mustPreserveItems(state); + let histOptions = historyKey.get(state).spec.config; + let pop = (redo3 ? history2.undone : history2.done).popEvent(state, preserveItems); + if (!pop) + return null; + let selection = pop.selection.resolve(pop.transform.doc); + let added = (redo3 ? history2.done : history2.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems); + let newHist = new HistoryState(redo3 ? added : pop.remaining, redo3 ? pop.remaining : added, null, 0, -1); + return pop.transform.setSelection(selection).setMeta(historyKey, { redo: redo3, historyState: newHist }); +} +var cachedPreserveItems = false; +var cachedPreserveItemsPlugins = null; +function mustPreserveItems(state) { + let plugins = state.plugins; + if (cachedPreserveItemsPlugins != plugins) { + cachedPreserveItems = false; + cachedPreserveItemsPlugins = plugins; + for (let i = 0; i < plugins.length; i++) + if (plugins[i].spec.historyPreserveItems) { + cachedPreserveItems = true; + break; + } + } + return cachedPreserveItems; +} +var historyKey = new PluginKey("history"); +var closeHistoryKey = new PluginKey("closeHistory"); +function history(config = {}) { + config = { + depth: config.depth || 100, + newGroupDelay: config.newGroupDelay || 500 + }; + return new Plugin({ + key: historyKey, + state: { + init() { + return new HistoryState(Branch.empty, Branch.empty, null, 0, -1); + }, + apply(tr2, hist, state) { + return applyTransaction(hist, state, tr2, config); + } + }, + config, + props: { + handleDOMEvents: { + beforeinput(view, e) { + let inputType = e.inputType; + let command2 = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null; + if (!command2 || !view.editable) + return false; + e.preventDefault(); + return command2(view.state, view.dispatch); + } + } + } + }); +} +function buildCommand(redo3, scroll) { + return (state, dispatch) => { + let hist = historyKey.getState(state); + if (!hist || (redo3 ? hist.undone : hist.done).eventCount == 0) + return false; + if (dispatch) { + let tr2 = histTransaction(hist, state, redo3); + if (tr2) + dispatch(scroll ? tr2.scrollIntoView() : tr2); + } + return true; + }; +} +var undo = buildCommand(false, true); +var redo = buildCommand(true, true); +var undoNoScroll = buildCommand(false, false); +var redoNoScroll = buildCommand(true, false); + +// ../../node_modules/.pnpm/@tiptap+extensions@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0__@tiptap+pm@3.26.0/node_modules/@tiptap/extensions/dist/index.js +var CharacterCount = Extension.create({ + name: "characterCount", + addOptions() { + return { + limit: null, + autoTrim: true, + mode: "textSize", + textCounter: (text2) => text2.length, + wordCounter: (text2) => text2.split(" ").filter((word2) => word2 !== "").length + }; + }, + addStorage() { + return { + characters: () => 0, + words: () => 0 + }; + }, + onBeforeCreate() { + this.storage.characters = (options) => { + const node = (options == null ? void 0 : options.node) || this.editor.state.doc; + const mode = (options == null ? void 0 : options.mode) || this.options.mode; + if (mode === "textSize") { + const text2 = node.textBetween(0, node.content.size, void 0, " "); + return this.options.textCounter(text2); + } + return node.nodeSize; + }; + this.storage.words = (options) => { + const node = (options == null ? void 0 : options.node) || this.editor.state.doc; + const text2 = node.textBetween(0, node.content.size, " ", " "); + return this.options.wordCounter(text2); + }; + }, + addProseMirrorPlugins() { + let initialEvaluationDone = false; + return [ + new Plugin({ + key: new PluginKey("characterCount"), + appendTransaction: (transactions, oldState, newState) => { + if (initialEvaluationDone) { + return; + } + const limit = this.options.limit; + const autoTrim = this.options.autoTrim; + if (limit === null || limit === void 0 || limit === 0 || autoTrim === false) { + initialEvaluationDone = true; + return; + } + const initialContentSize = this.storage.characters({ node: newState.doc }); + if (initialContentSize > limit) { + const over = initialContentSize - limit; + const from3 = 0; + const to = over; + console.warn( + `[CharacterCount] Initial content exceeded limit of ${limit} characters. Content was automatically trimmed.` + ); + const tr2 = newState.tr.deleteRange(from3, to); + initialEvaluationDone = true; + return tr2; + } + initialEvaluationDone = true; + }, + filterTransaction: (transaction, state) => { + const limit = this.options.limit; + if (!transaction.docChanged || limit === 0 || limit === null || limit === void 0) { + return true; + } + const oldSize = this.storage.characters({ node: state.doc }); + const newSize = this.storage.characters({ node: transaction.doc }); + if (newSize <= limit) { + return true; + } + if (oldSize > limit && newSize > limit && newSize <= oldSize) { + return true; + } + if (oldSize > limit && newSize > limit && newSize > oldSize) { + return false; + } + const isPaste = transaction.getMeta("paste"); + if (!isPaste) { + return false; + } + const pos = transaction.selection.$head.pos; + const over = newSize - limit; + const from3 = pos - over; + const to = pos; + transaction.deleteRange(from3, to); + const updatedSize = this.storage.characters({ node: transaction.doc }); + if (updatedSize > limit) { + return false; + } + return true; + } + }) + ]; + } +}); +var Dropcursor = Extension.create({ + name: "dropCursor", + addOptions() { + return { + color: "currentColor", + width: 1, + class: void 0 + }; + }, + addProseMirrorPlugins() { + return [dropCursor(this.options)]; + } +}); +var Focus = Extension.create({ + name: "focus", + addOptions() { + return { + className: "has-focus", + mode: "all" + }; + }, + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("focus"), + props: { + decorations: ({ doc: doc4, selection }) => { + const { isEditable, isFocused } = this.editor; + const { anchor } = selection; + const decorations = []; + if (!isEditable || !isFocused) { + return DecorationSet.create(doc4, []); + } + let maxLevels = 0; + if (this.options.mode === "deepest") { + doc4.descendants((node, pos) => { + if (node.isText) { + return; + } + const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1; + if (!isCurrent) { + return false; + } + maxLevels += 1; + }); + } + let currentLevel = 0; + doc4.descendants((node, pos) => { + if (node.isText) { + return false; + } + const isCurrent = anchor >= pos && anchor <= pos + node.nodeSize - 1; + if (!isCurrent) { + return false; + } + currentLevel += 1; + const outOfScope = this.options.mode === "deepest" && maxLevels - currentLevel > 0 || this.options.mode === "shallowest" && currentLevel > 1; + if (outOfScope) { + return this.options.mode === "deepest"; + } + decorations.push( + Decoration.node(pos, pos + node.nodeSize, { + class: this.options.className + }) + ); + }); + return DecorationSet.create(doc4, decorations); + } + } + }) + ]; + } +}); +var Gapcursor = Extension.create({ + name: "gapCursor", + addProseMirrorPlugins() { + return [gapCursor()]; + }, + extendNodeSchema(extension) { + var _a; + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage + }; + return { + allowGapCursor: (_a = callOrReturn(getExtensionField(extension, "allowGapCursor", context))) != null ? _a : null + }; + } +}); +var DEFAULT_DATA_ATTRIBUTE = "placeholder"; +var PLUGIN_KEY = new PluginKey("tiptap__placeholder"); +var VIEWPORT_OVERSCAN_PX = 200; +function createPlaceholderDecoration(options) { + const { + editor, + placeholder, + dataAttribute, + pos, + node, + isEmptyDoc, + hasAnchor, + classes: { emptyNode, emptyEditor } + } = options; + const classes = [emptyNode]; + if (isEmptyDoc) { + classes.push(emptyEditor); + } + return Decoration.node(pos, pos + node.nodeSize, { + class: classes.join(" "), + [dataAttribute]: typeof placeholder === "function" ? placeholder({ + editor, + node, + pos, + hasAnchor + }) : placeholder + }); +} +function resolveEmptyNodeClass(emptyNodeClass, props) { + return typeof emptyNodeClass === "function" ? emptyNodeClass(props) : emptyNodeClass; +} +function buildPlaceholderDecorations({ + editor, + options, + dataAttribute, + doc: doc4, + selection +}) { + var _a, _b; + const active = editor.isEditable || !options.showOnlyWhenEditable; + if (!active) { + return null; + } + const { anchor } = selection; + const decorations = []; + const isEmptyDoc = editor.isEmpty; + const useResolvedPath = options.showOnlyCurrent && !options.includeChildren; + if (useResolvedPath) { + const resolved = doc4.resolve(anchor); + const node = resolved.depth > 0 ? resolved.node(1) : resolved.nodeAfter; + const nodeStart = resolved.depth > 0 ? resolved.before(1) : anchor; + if (node && node.type.isTextblock && isNodeEmpty(node)) { + const hasAnchor = anchor >= nodeStart && anchor <= nodeStart + node.nodeSize; + decorations.push( + createPlaceholderDecoration({ + editor, + isEmptyDoc, + dataAttribute, + hasAnchor, + placeholder: options.placeholder, + classes: { + emptyEditor: options.emptyEditorClass, + emptyNode: resolveEmptyNodeClass(options.emptyNodeClass, { + editor, + node, + pos: nodeStart, + hasAnchor + }) + }, + node, + pos: nodeStart + }) + ); + } + } else { + const pluginState = PLUGIN_KEY.getState(editor.state); + const from3 = (_a = pluginState == null ? void 0 : pluginState.topPos) != null ? _a : 0; + const to = (_b = pluginState == null ? void 0 : pluginState.bottomPos) != null ? _b : doc4.content.size; + doc4.nodesBetween(from3, to, (node, pos) => { + const hasAnchor = anchor >= pos && anchor <= pos + node.nodeSize; + const isEmpty3 = !node.isLeaf && isNodeEmpty(node); + if (!node.type.isTextblock) { + return options.includeChildren; + } + if ((hasAnchor || !options.showOnlyCurrent) && isEmpty3) { + decorations.push( + createPlaceholderDecoration({ + editor, + isEmptyDoc, + dataAttribute, + hasAnchor, + placeholder: options.placeholder, + classes: { + emptyEditor: options.emptyEditorClass, + emptyNode: resolveEmptyNodeClass(options.emptyNodeClass, { + editor, + node, + pos, + hasAnchor + }) + }, + node, + pos + }) + ); + } + return options.includeChildren; + }); + } + return DecorationSet.create(doc4, decorations); +} +function preparePlaceholderAttribute(attr) { + return attr.replace(/\s+/g, "-").replace(/[^a-zA-Z0-9-]/g, "").replace(/^[0-9-]+/, "").replace(/^-+/, "").toLowerCase(); +} +function isScrollable(el) { + const style2 = getComputedStyle(el); + const overflow = `${style2.overflow} ${style2.overflowY} ${style2.overflowX}`; + return /auto|scroll|overlay/.test(overflow); +} +function findScrollParent(element2) { + let el = element2; + while (el) { + if (isScrollable(el)) { + return el; + } + const parent = el.parentElement; + if (!parent) { + const root2 = el.getRootNode(); + if (root2 instanceof ShadowRoot) { + el = root2.host; + continue; + } + return window; + } + el = parent; + } + return window; +} +function getContainerRect(container) { + if (container === window) { + return { top: 0, bottom: window.innerHeight }; + } + return container.getBoundingClientRect(); +} +function getViewportBoundaryPositions({ + doc: doc4, + view, + scrollContainer +}) { + const editorRect = view.dom.getBoundingClientRect(); + const containerRect = scrollContainer ? getContainerRect(scrollContainer) : { top: 0, bottom: window.innerHeight }; + const visibleTop = Math.max(editorRect.top, containerRect.top) - VIEWPORT_OVERSCAN_PX; + const visibleBottom = Math.min(editorRect.bottom, containerRect.bottom) + VIEWPORT_OVERSCAN_PX; + if (visibleTop >= visibleBottom) { + return { top: 0, bottom: doc4.content.size }; + } + const isRTL = getComputedStyle(view.dom).direction === "rtl"; + const x2 = isRTL ? Math.max(editorRect.right - 2, editorRect.left + 2) : editorRect.left + 2; + const topPos = view.posAtCoords({ left: x2, top: visibleTop + 2 }); + const bottomPos = view.posAtCoords({ left: x2, top: visibleBottom - 2 }); + return { + top: topPos ? topPos.pos : 0, + bottom: bottomPos ? bottomPos.pos : doc4.content.size + }; +} +var viewportPluginState = { + /** + * Initialises the viewport state with no known positions. + * @returns The initial viewport state. + */ + init() { + return { topPos: null, bottomPos: null }; + }, + /** + * Updates the viewport state from incoming transactions. + * @param tr - The transaction being applied. + * @param prev - The previous viewport state. + * @returns The next viewport state. + */ + apply(tr2, prev) { + const meta = tr2.getMeta(PLUGIN_KEY); + if (meta == null ? void 0 : meta.positions) { + return { topPos: meta.positions.top, bottomPos: meta.positions.bottom }; + } + if (!tr2.docChanged) { + return prev; + } + return { + topPos: prev.topPos !== null ? tr2.mapping.map(prev.topPos) : null, + bottomPos: prev.bottomPos !== null ? tr2.mapping.map(prev.bottomPos) : null + }; + } +}; +function createViewportPluginView(view) { + const scrollContainer = findScrollParent(view.dom); + const computeAndDispatch = () => { + const positions = getViewportBoundaryPositions({ + view, + doc: view.state.doc, + scrollContainer + }); + const prev = PLUGIN_KEY.getState(view.state); + if ((prev == null ? void 0 : prev.topPos) === positions.top && (prev == null ? void 0 : prev.bottomPos) === positions.bottom) { + return; + } + const tr2 = view.state.tr.setMeta(PLUGIN_KEY, { positions }); + view.dispatch(tr2); + }; + let frame = null; + let lastCompute = 0; + const MIN_SCROLL_INTERVAL = 150; + const scheduleFrame = () => { + if (frame !== null) return; + frame = requestAnimationFrame(() => { + frame = null; + const now = performance.now(); + if (now - lastCompute >= MIN_SCROLL_INTERVAL) { + lastCompute = now; + computeAndDispatch(); + } else { + scheduleFrame(); + } + }); + }; + scrollContainer.addEventListener("scroll", scheduleFrame, { passive: true }); + computeAndDispatch(); + return { + update(_view, prevState) { + if (view.state.doc.content.size !== prevState.doc.content.size) { + scheduleFrame(); + } + }, + destroy: () => { + if (frame !== null) { + cancelAnimationFrame(frame); + } + scrollContainer.removeEventListener("scroll", scheduleFrame); + } + }; +} +function createPlaceholderPlugin({ editor, options }) { + const dataAttribute = options.dataAttribute ? `data-${preparePlaceholderAttribute(options.dataAttribute)}` : `data-${DEFAULT_DATA_ATTRIBUTE}`; + return new Plugin({ + key: PLUGIN_KEY, + state: viewportPluginState, + view: createViewportPluginView, + props: { + decorations: ({ doc: doc4, selection }) => buildPlaceholderDecorations({ editor, options, dataAttribute, doc: doc4, selection }) + } + }); +} +var Placeholder = Extension.create({ + name: "placeholder", + addOptions() { + return { + emptyEditorClass: "is-editor-empty", + emptyNodeClass: "is-empty", + dataAttribute: DEFAULT_DATA_ATTRIBUTE, + placeholder: "Write something \u2026", + showOnlyWhenEditable: true, + showOnlyCurrent: true, + includeChildren: false + }; + }, + addProseMirrorPlugins() { + return [createPlaceholderPlugin({ editor: this.editor, options: this.options })]; + } +}); +var selectionStyle = `.ProseMirror:not(.ProseMirror-focused) *::selection { + background: transparent; +} + +.ProseMirror:not(.ProseMirror-focused) *::-moz-selection { + background: transparent; +}`; +var Selection3 = Extension.create({ + name: "selection", + addOptions() { + return { + className: "selection" + }; + }, + addProseMirrorPlugins() { + const { editor, options } = this; + if (editor.options.injectCSS && typeof document !== "undefined") { + createStyleTag(selectionStyle, editor.options.injectNonce, "selection"); + } + return [ + new Plugin({ + key: new PluginKey("selection"), + props: { + decorations(state) { + if (state.selection.empty || editor.isFocused || !editor.isEditable || isNodeSelection(state.selection) || editor.view.dragging) { + return null; + } + return DecorationSet.create(state.doc, [ + Decoration.inline(state.selection.from, state.selection.to, { + class: options.className + }) + ]); + } + } + }) + ]; + } +}); +var skipTrailingNodeMeta = "skipTrailingNode"; +function nodeEqualsType({ + types, + node +}) { + return node && Array.isArray(types) && types.includes(node.type) || (node == null ? void 0 : node.type) === types; +} +var TrailingNode = Extension.create({ + name: "trailingNode", + addOptions() { + return { + node: void 0, + notAfter: [] + }; + }, + addProseMirrorPlugins() { + var _a; + const plugin = new PluginKey(this.name); + const defaultNode = this.options.node || ((_a = this.editor.schema.topNodeType.contentMatch.defaultType) == null ? void 0 : _a.name) || "paragraph"; + const disabledNodes = Object.entries(this.editor.schema.nodes).map(([, value]) => value).filter((node) => (this.options.notAfter || []).concat(defaultNode).includes(node.name)); + return [ + new Plugin({ + key: plugin, + appendTransaction: (transactions, __, state) => { + const { doc: doc4, tr: tr2, schema } = state; + const shouldInsertNodeAtEnd = plugin.getState(state); + const endPosition = doc4.content.size; + const type = schema.nodes[defaultNode]; + if (transactions.some((transaction) => transaction.getMeta(skipTrailingNodeMeta))) { + return; + } + if (!shouldInsertNodeAtEnd) { + return; + } + return tr2.insert(endPosition, type.create()); + }, + state: { + init: (_2, state) => { + const lastNode = state.tr.doc.lastChild; + return !nodeEqualsType({ node: lastNode, types: disabledNodes }); + }, + apply: (tr2, value) => { + if (!tr2.docChanged) { + return value; + } + if (tr2.getMeta("__uniqueIDTransaction")) { + return value; + } + const lastNode = tr2.doc.lastChild; + return !nodeEqualsType({ node: lastNode, types: disabledNodes }); + } + } + }) + ]; + } +}); +var UndoRedo = Extension.create({ + name: "undoRedo", + addOptions() { + return { + depth: 100, + newGroupDelay: 500 + }; + }, + addCommands() { + return { + undo: () => ({ state, dispatch }) => { + return undo(state, dispatch); + }, + redo: () => ({ state, dispatch }) => { + return redo(state, dispatch); + } + }; + }, + addProseMirrorPlugins() { + return [history(this.options)]; + }, + addKeyboardShortcuts() { + return { + "Mod-z": () => this.editor.commands.undo(), + "Shift-Mod-z": () => this.editor.commands.redo(), + "Mod-y": () => this.editor.commands.redo(), + // Russian keyboard layouts + "Mod-\u044F": () => this.editor.commands.undo(), + "Shift-Mod-\u044F": () => this.editor.commands.redo() + }; + } +}); + +// ../../node_modules/.pnpm/@tiptap+starter-kit@3.26.0/node_modules/@tiptap/starter-kit/dist/index.js +var StarterKit = Extension.create({ + name: "starterKit", + addExtensions() { + var _a, _b, _c, _d; + const extensions = []; + if (this.options.bold !== false) { + extensions.push(Bold.configure(this.options.bold)); + } + if (this.options.blockquote !== false) { + extensions.push(Blockquote.configure(this.options.blockquote)); + } + if (this.options.bulletList !== false) { + extensions.push(BulletList.configure(this.options.bulletList)); + } + if (this.options.code !== false) { + extensions.push(Code.configure(this.options.code)); + } + if (this.options.codeBlock !== false) { + extensions.push(CodeBlock.configure(this.options.codeBlock)); + } + if (this.options.document !== false) { + extensions.push(Document.configure(this.options.document)); + } + if (this.options.dropcursor !== false) { + extensions.push(Dropcursor.configure(this.options.dropcursor)); + } + if (this.options.gapcursor !== false) { + extensions.push(Gapcursor.configure(this.options.gapcursor)); + } + if (this.options.hardBreak !== false) { + extensions.push(HardBreak.configure(this.options.hardBreak)); + } + if (this.options.heading !== false) { + extensions.push(Heading.configure(this.options.heading)); + } + if (this.options.undoRedo !== false) { + extensions.push(UndoRedo.configure(this.options.undoRedo)); + } + if (this.options.horizontalRule !== false) { + extensions.push(HorizontalRule.configure(this.options.horizontalRule)); + } + if (this.options.italic !== false) { + extensions.push(Italic.configure(this.options.italic)); + } + if (this.options.listItem !== false) { + extensions.push(ListItem.configure(this.options.listItem)); + } + if (this.options.listKeymap !== false) { + extensions.push(ListKeymap.configure((_a = this.options) == null ? void 0 : _a.listKeymap)); + } + if (this.options.link !== false) { + extensions.push(Link.configure((_b = this.options) == null ? void 0 : _b.link)); + } + if (this.options.orderedList !== false) { + extensions.push(OrderedList.configure(this.options.orderedList)); + } + if (this.options.paragraph !== false) { + extensions.push(Paragraph.configure(this.options.paragraph)); + } + if (this.options.strike !== false) { + extensions.push(Strike.configure(this.options.strike)); + } + if (this.options.text !== false) { + extensions.push(Text2.configure(this.options.text)); + } + if (this.options.underline !== false) { + extensions.push(Underline.configure((_c = this.options) == null ? void 0 : _c.underline)); + } + if (this.options.trailingNode !== false) { + extensions.push(TrailingNode.configure((_d = this.options) == null ? void 0 : _d.trailingNode)); + } + return extensions; + } +}); +var index_default2 = StarterKit; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/map.js +var create = () => /* @__PURE__ */ new Map(); +var copy2 = (m2) => { + const r = create(); + m2.forEach((v2, k) => { + r.set(k, v2); + }); + return r; +}; +var setIfUndefined = (map4, key, createT) => { + let set = map4.get(key); + if (set === void 0) { + map4.set(key, set = createT()); + } + return set; +}; +var map2 = (m2, f) => { + const res = []; + for (const [key, value] of m2) { + res.push(f(value, key)); + } + return res; +}; +var any = (m2, f) => { + for (const [key, value] of m2) { + if (f(value, key)) { + return true; + } + } + return false; +}; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/set.js +var create2 = () => /* @__PURE__ */ new Set(); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/array.js +var last = (arr) => arr[arr.length - 1]; +var appendTo = (dest, src) => { + for (let i = 0; i < src.length; i++) { + dest.push(src[i]); + } +}; +var from2 = Array.from; +var every = (arr, f) => { + for (let i = 0; i < arr.length; i++) { + if (!f(arr[i], i, arr)) { + return false; + } + } + return true; +}; +var some = (arr, f) => { + for (let i = 0; i < arr.length; i++) { + if (f(arr[i], i, arr)) { + return true; + } + } + return false; +}; +var unfold = (len, f) => { + const array = new Array(len); + for (let i = 0; i < len; i++) { + array[i] = f(i, array); + } + return array; +}; +var isArray = Array.isArray; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/observable.js +var ObservableV2 = class { + constructor() { + this._observers = create(); + } + /** + * @template {keyof EVENTS & string} NAME + * @param {NAME} name + * @param {EVENTS[NAME]} f + */ + on(name, f) { + setIfUndefined( + this._observers, + /** @type {string} */ + name, + create2 + ).add(f); + return f; + } + /** + * @template {keyof EVENTS & string} NAME + * @param {NAME} name + * @param {EVENTS[NAME]} f + */ + once(name, f) { + const _f = (...args2) => { + this.off( + name, + /** @type {any} */ + _f + ); + f(...args2); + }; + this.on( + name, + /** @type {any} */ + _f + ); + } + /** + * @template {keyof EVENTS & string} NAME + * @param {NAME} name + * @param {EVENTS[NAME]} f + */ + off(name, f) { + const observers = this._observers.get(name); + if (observers !== void 0) { + observers.delete(f); + if (observers.size === 0) { + this._observers.delete(name); + } + } + } + /** + * Emit a named event. All registered event listeners that listen to the + * specified name will receive the event. + * + * @todo This should catch exceptions + * + * @template {keyof EVENTS & string} NAME + * @param {NAME} name The event name. + * @param {Parameters} args The arguments that are applied to the event listener. + */ + emit(name, args2) { + return from2((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); + } + destroy() { + this._observers = create(); + } +}; +var Observable = class { + constructor() { + this._observers = create(); + } + /** + * @param {N} name + * @param {function} f + */ + on(name, f) { + setIfUndefined(this._observers, name, create2).add(f); + } + /** + * @param {N} name + * @param {function} f + */ + once(name, f) { + const _f = (...args2) => { + this.off(name, _f); + f(...args2); + }; + this.on(name, _f); + } + /** + * @param {N} name + * @param {function} f + */ + off(name, f) { + const observers = this._observers.get(name); + if (observers !== void 0) { + observers.delete(f); + if (observers.size === 0) { + this._observers.delete(name); + } + } + } + /** + * Emit a named event. All registered event listeners that listen to the + * specified name will receive the event. + * + * @todo This should catch exceptions + * + * @param {N} name The event name. + * @param {Array} args The arguments that are applied to the event listener. + */ + emit(name, args2) { + return from2((this._observers.get(name) || create()).values()).forEach((f) => f(...args2)); + } + destroy() { + this._observers = create(); + } +}; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/math.js +var floor = Math.floor; +var abs = Math.abs; +var min = (a, b2) => a < b2 ? a : b2; +var max = (a, b2) => a > b2 ? a : b2; +var isNaN = Number.isNaN; +var pow = Math.pow; +var isNegativeZero = (n) => n !== 0 ? n < 0 : 1 / n < 0; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/binary.js +var BIT1 = 1; +var BIT2 = 2; +var BIT3 = 4; +var BIT4 = 8; +var BIT6 = 32; +var BIT7 = 64; +var BIT8 = 128; +var BIT18 = 1 << 17; +var BIT19 = 1 << 18; +var BIT20 = 1 << 19; +var BIT21 = 1 << 20; +var BIT22 = 1 << 21; +var BIT23 = 1 << 22; +var BIT24 = 1 << 23; +var BIT25 = 1 << 24; +var BIT26 = 1 << 25; +var BIT27 = 1 << 26; +var BIT28 = 1 << 27; +var BIT29 = 1 << 28; +var BIT30 = 1 << 29; +var BIT31 = 1 << 30; +var BIT32 = 1 << 31; +var BITS5 = 31; +var BITS6 = 63; +var BITS7 = 127; +var BITS17 = BIT18 - 1; +var BITS18 = BIT19 - 1; +var BITS19 = BIT20 - 1; +var BITS20 = BIT21 - 1; +var BITS21 = BIT22 - 1; +var BITS22 = BIT23 - 1; +var BITS23 = BIT24 - 1; +var BITS24 = BIT25 - 1; +var BITS25 = BIT26 - 1; +var BITS26 = BIT27 - 1; +var BITS27 = BIT28 - 1; +var BITS28 = BIT29 - 1; +var BITS29 = BIT30 - 1; +var BITS30 = BIT31 - 1; +var BITS31 = 2147483647; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/number.js +var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER; +var MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER; +var LOWEST_INT32 = 1 << 31; +var isInteger = Number.isInteger || ((num) => typeof num === "number" && isFinite(num) && floor(num) === num); +var isNaN2 = Number.isNaN; +var parseInt2 = Number.parseInt; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/string.js +var fromCharCode = String.fromCharCode; +var fromCodePoint = String.fromCodePoint; +var MAX_UTF16_CHARACTER = fromCharCode(65535); +var toLowerCase = (s) => s.toLowerCase(); +var trimLeftRegex = /^\s*/g; +var trimLeft = (s) => s.replace(trimLeftRegex, ""); +var fromCamelCaseRegex = /([A-Z])/g; +var fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, (match2) => `${separator}${toLowerCase(match2)}`)); +var _encodeUtf8Polyfill = (str) => { + const encodedString = unescape(encodeURIComponent(str)); + const len = encodedString.length; + const buf = new Uint8Array(len); + for (let i = 0; i < len; i++) { + buf[i] = /** @type {number} */ + encodedString.codePointAt(i); + } + return buf; +}; +var utf8TextEncoder = ( + /** @type {TextEncoder} */ + typeof TextEncoder !== "undefined" ? new TextEncoder() : null +); +var _encodeUtf8Native = (str) => utf8TextEncoder.encode(str); +var encodeUtf8 = utf8TextEncoder ? _encodeUtf8Native : _encodeUtf8Polyfill; +var utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }); +if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) { + utf8TextDecoder = null; +} +var repeat = (source, n) => unfold(n, () => source).join(""); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/encoding.js +var Encoder = class { + constructor() { + this.cpos = 0; + this.cbuf = new Uint8Array(100); + this.bufs = []; + } +}; +var createEncoder = () => new Encoder(); +var encode = (f) => { + const encoder = createEncoder(); + f(encoder); + return toUint8Array(encoder); +}; +var length = (encoder) => { + let len = encoder.cpos; + for (let i = 0; i < encoder.bufs.length; i++) { + len += encoder.bufs[i].length; + } + return len; +}; +var toUint8Array = (encoder) => { + const uint8arr = new Uint8Array(length(encoder)); + let curPos = 0; + for (let i = 0; i < encoder.bufs.length; i++) { + const d2 = encoder.bufs[i]; + uint8arr.set(d2, curPos); + curPos += d2.length; + } + uint8arr.set(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos), curPos); + return uint8arr; +}; +var verifyLen = (encoder, len) => { + const bufferLen = encoder.cbuf.length; + if (bufferLen - encoder.cpos < len) { + encoder.bufs.push(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos)); + encoder.cbuf = new Uint8Array(max(bufferLen, len) * 2); + encoder.cpos = 0; + } +}; +var write = (encoder, num) => { + const bufferLen = encoder.cbuf.length; + if (encoder.cpos === bufferLen) { + encoder.bufs.push(encoder.cbuf); + encoder.cbuf = new Uint8Array(bufferLen * 2); + encoder.cpos = 0; + } + encoder.cbuf[encoder.cpos++] = num; +}; +var writeUint8 = write; +var writeVarUint = (encoder, num) => { + while (num > BITS7) { + write(encoder, BIT8 | BITS7 & num); + num = floor(num / 128); + } + write(encoder, BITS7 & num); +}; +var writeVarInt = (encoder, num) => { + const isNegative = isNegativeZero(num); + if (isNegative) { + num = -num; + } + write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | BITS6 & num); + num = floor(num / 64); + while (num > 0) { + write(encoder, (num > BITS7 ? BIT8 : 0) | BITS7 & num); + num = floor(num / 128); + } +}; +var _strBuffer = new Uint8Array(3e4); +var _maxStrBSize = _strBuffer.length / 3; +var _writeVarStringNative = (encoder, str) => { + if (str.length < _maxStrBSize) { + const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0; + writeVarUint(encoder, written); + for (let i = 0; i < written; i++) { + write(encoder, _strBuffer[i]); + } + } else { + writeVarUint8Array(encoder, encodeUtf8(str)); + } +}; +var _writeVarStringPolyfill = (encoder, str) => { + const encodedString = unescape(encodeURIComponent(str)); + const len = encodedString.length; + writeVarUint(encoder, len); + for (let i = 0; i < len; i++) { + write( + encoder, + /** @type {number} */ + encodedString.codePointAt(i) + ); + } +}; +var writeVarString = utf8TextEncoder && /** @type {any} */ +utf8TextEncoder.encodeInto ? _writeVarStringNative : _writeVarStringPolyfill; +var writeUint8Array = (encoder, uint8Array) => { + const bufferLen = encoder.cbuf.length; + const cpos = encoder.cpos; + const leftCopyLen = min(bufferLen - cpos, uint8Array.length); + const rightCopyLen = uint8Array.length - leftCopyLen; + encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos); + encoder.cpos += leftCopyLen; + if (rightCopyLen > 0) { + encoder.bufs.push(encoder.cbuf); + encoder.cbuf = new Uint8Array(max(bufferLen * 2, rightCopyLen)); + encoder.cbuf.set(uint8Array.subarray(leftCopyLen)); + encoder.cpos = rightCopyLen; + } +}; +var writeVarUint8Array = (encoder, uint8Array) => { + writeVarUint(encoder, uint8Array.byteLength); + writeUint8Array(encoder, uint8Array); +}; +var writeOnDataView = (encoder, len) => { + verifyLen(encoder, len); + const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len); + encoder.cpos += len; + return dview; +}; +var writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false); +var writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false); +var writeBigInt64 = (encoder, num) => ( + /** @type {any} */ + writeOnDataView(encoder, 8).setBigInt64(0, num, false) +); +var floatTestBed = new DataView(new ArrayBuffer(4)); +var isFloat32 = (num) => { + floatTestBed.setFloat32(0, num); + return floatTestBed.getFloat32(0) === num; +}; +var writeAny = (encoder, data) => { + switch (typeof data) { + case "string": + write(encoder, 119); + writeVarString(encoder, data); + break; + case "number": + if (isInteger(data) && abs(data) <= BITS31) { + write(encoder, 125); + writeVarInt(encoder, data); + } else if (isFloat32(data)) { + write(encoder, 124); + writeFloat32(encoder, data); + } else { + write(encoder, 123); + writeFloat64(encoder, data); + } + break; + case "bigint": + write(encoder, 122); + writeBigInt64(encoder, data); + break; + case "object": + if (data === null) { + write(encoder, 126); + } else if (isArray(data)) { + write(encoder, 117); + writeVarUint(encoder, data.length); + for (let i = 0; i < data.length; i++) { + writeAny(encoder, data[i]); + } + } else if (data instanceof Uint8Array) { + write(encoder, 116); + writeVarUint8Array(encoder, data); + } else { + write(encoder, 118); + const keys3 = Object.keys(data); + writeVarUint(encoder, keys3.length); + for (let i = 0; i < keys3.length; i++) { + const key = keys3[i]; + writeVarString(encoder, key); + writeAny(encoder, data[key]); + } + } + break; + case "boolean": + write(encoder, data ? 120 : 121); + break; + default: + write(encoder, 127); + } +}; +var RleEncoder = class extends Encoder { + /** + * @param {function(Encoder, T):void} writer + */ + constructor(writer) { + super(); + this.w = writer; + this.s = null; + this.count = 0; + } + /** + * @param {T} v + */ + write(v2) { + if (this.s === v2) { + this.count++; + } else { + if (this.count > 0) { + writeVarUint(this, this.count - 1); + } + this.count = 1; + this.w(this, v2); + this.s = v2; + } + } +}; +var flushUintOptRleEncoder = (encoder) => { + if (encoder.count > 0) { + writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s); + if (encoder.count > 1) { + writeVarUint(encoder.encoder, encoder.count - 2); + } + } +}; +var UintOptRleEncoder = class { + constructor() { + this.encoder = new Encoder(); + this.s = 0; + this.count = 0; + } + /** + * @param {number} v + */ + write(v2) { + if (this.s === v2) { + this.count++; + } else { + flushUintOptRleEncoder(this); + this.count = 1; + this.s = v2; + } + } + /** + * Flush the encoded state and transform this to a Uint8Array. + * + * Note that this should only be called once. + */ + toUint8Array() { + flushUintOptRleEncoder(this); + return toUint8Array(this.encoder); + } +}; +var flushIntDiffOptRleEncoder = (encoder) => { + if (encoder.count > 0) { + const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1); + writeVarInt(encoder.encoder, encodedDiff); + if (encoder.count > 1) { + writeVarUint(encoder.encoder, encoder.count - 2); + } + } +}; +var IntDiffOptRleEncoder = class { + constructor() { + this.encoder = new Encoder(); + this.s = 0; + this.count = 0; + this.diff = 0; + } + /** + * @param {number} v + */ + write(v2) { + if (this.diff === v2 - this.s) { + this.s = v2; + this.count++; + } else { + flushIntDiffOptRleEncoder(this); + this.count = 1; + this.diff = v2 - this.s; + this.s = v2; + } + } + /** + * Flush the encoded state and transform this to a Uint8Array. + * + * Note that this should only be called once. + */ + toUint8Array() { + flushIntDiffOptRleEncoder(this); + return toUint8Array(this.encoder); + } +}; +var StringEncoder = class { + constructor() { + this.sarr = []; + this.s = ""; + this.lensE = new UintOptRleEncoder(); + } + /** + * @param {string} string + */ + write(string) { + this.s += string; + if (this.s.length > 19) { + this.sarr.push(this.s); + this.s = ""; + } + this.lensE.write(string.length); + } + toUint8Array() { + const encoder = new Encoder(); + this.sarr.push(this.s); + this.s = ""; + writeVarString(encoder, this.sarr.join("")); + writeUint8Array(encoder, this.lensE.toUint8Array()); + return toUint8Array(encoder); + } +}; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/error.js +var create3 = (s) => new Error(s); +var methodUnimplemented = () => { + throw create3("Method unimplemented"); +}; +var unexpectedCase = () => { + throw create3("Unexpected case"); +}; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/decoding.js +var errorUnexpectedEndOfArray = create3("Unexpected end of array"); +var errorIntegerOutOfRange = create3("Integer out of Range"); +var Decoder = class { + /** + * @param {Uint8Array} uint8Array Binary data to decode + */ + constructor(uint8Array) { + this.arr = uint8Array; + this.pos = 0; + } +}; +var createDecoder = (uint8Array) => new Decoder(uint8Array); +var hasContent = (decoder) => decoder.pos !== decoder.arr.length; +var readUint8Array = (decoder, len) => { + const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len); + decoder.pos += len; + return view; +}; +var readVarUint8Array = (decoder) => readUint8Array(decoder, readVarUint(decoder)); +var readUint8 = (decoder) => decoder.arr[decoder.pos++]; +var readVarUint = (decoder) => { + let num = 0; + let mult = 1; + const len = decoder.arr.length; + while (decoder.pos < len) { + const r = decoder.arr[decoder.pos++]; + num = num + (r & BITS7) * mult; + mult *= 128; + if (r < BIT8) { + return num; + } + if (num > MAX_SAFE_INTEGER) { + throw errorIntegerOutOfRange; + } + } + throw errorUnexpectedEndOfArray; +}; +var readVarInt = (decoder) => { + let r = decoder.arr[decoder.pos++]; + let num = r & BITS6; + let mult = 64; + const sign = (r & BIT7) > 0 ? -1 : 1; + if ((r & BIT8) === 0) { + return sign * num; + } + const len = decoder.arr.length; + while (decoder.pos < len) { + r = decoder.arr[decoder.pos++]; + num = num + (r & BITS7) * mult; + mult *= 128; + if (r < BIT8) { + return sign * num; + } + if (num > MAX_SAFE_INTEGER) { + throw errorIntegerOutOfRange; + } + } + throw errorUnexpectedEndOfArray; +}; +var _readVarStringPolyfill = (decoder) => { + let remainingLen = readVarUint(decoder); + if (remainingLen === 0) { + return ""; + } else { + let encodedString = String.fromCodePoint(readUint8(decoder)); + if (--remainingLen < 100) { + while (remainingLen--) { + encodedString += String.fromCodePoint(readUint8(decoder)); + } + } else { + while (remainingLen > 0) { + const nextLen = remainingLen < 1e4 ? remainingLen : 1e4; + const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen); + decoder.pos += nextLen; + encodedString += String.fromCodePoint.apply( + null, + /** @type {any} */ + bytes + ); + remainingLen -= nextLen; + } + } + return decodeURIComponent(escape(encodedString)); + } +}; +var _readVarStringNative = (decoder) => ( + /** @type any */ + utf8TextDecoder.decode(readVarUint8Array(decoder)) +); +var readVarString = utf8TextDecoder ? _readVarStringNative : _readVarStringPolyfill; +var readFromDataView = (decoder, len) => { + const dv = new DataView(decoder.arr.buffer, decoder.arr.byteOffset + decoder.pos, len); + decoder.pos += len; + return dv; +}; +var readFloat32 = (decoder) => readFromDataView(decoder, 4).getFloat32(0, false); +var readFloat64 = (decoder) => readFromDataView(decoder, 8).getFloat64(0, false); +var readBigInt64 = (decoder) => ( + /** @type {any} */ + readFromDataView(decoder, 8).getBigInt64(0, false) +); +var readAnyLookupTable = [ + (decoder) => void 0, + // CASE 127: undefined + (decoder) => null, + // CASE 126: null + readVarInt, + // CASE 125: integer + readFloat32, + // CASE 124: float32 + readFloat64, + // CASE 123: float64 + readBigInt64, + // CASE 122: bigint + (decoder) => false, + // CASE 121: boolean (false) + (decoder) => true, + // CASE 120: boolean (true) + readVarString, + // CASE 119: string + (decoder) => { + const len = readVarUint(decoder); + const obj = {}; + for (let i = 0; i < len; i++) { + const key = readVarString(decoder); + obj[key] = readAny(decoder); + } + return obj; + }, + (decoder) => { + const len = readVarUint(decoder); + const arr = []; + for (let i = 0; i < len; i++) { + arr.push(readAny(decoder)); + } + return arr; + }, + readVarUint8Array + // CASE 116: Uint8Array +]; +var readAny = (decoder) => readAnyLookupTable[127 - readUint8(decoder)](decoder); +var RleDecoder = class extends Decoder { + /** + * @param {Uint8Array} uint8Array + * @param {function(Decoder):T} reader + */ + constructor(uint8Array, reader) { + super(uint8Array); + this.reader = reader; + this.s = null; + this.count = 0; + } + read() { + if (this.count === 0) { + this.s = this.reader(this); + if (hasContent(this)) { + this.count = readVarUint(this) + 1; + } else { + this.count = -1; + } + } + this.count--; + return ( + /** @type {T} */ + this.s + ); + } +}; +var UintOptRleDecoder = class extends Decoder { + /** + * @param {Uint8Array} uint8Array + */ + constructor(uint8Array) { + super(uint8Array); + this.s = 0; + this.count = 0; + } + read() { + if (this.count === 0) { + this.s = readVarInt(this); + const isNegative = isNegativeZero(this.s); + this.count = 1; + if (isNegative) { + this.s = -this.s; + this.count = readVarUint(this) + 2; + } + } + this.count--; + return ( + /** @type {number} */ + this.s + ); + } +}; +var IntDiffOptRleDecoder = class extends Decoder { + /** + * @param {Uint8Array} uint8Array + */ + constructor(uint8Array) { + super(uint8Array); + this.s = 0; + this.count = 0; + this.diff = 0; + } + /** + * @return {number} + */ + read() { + if (this.count === 0) { + const diff = readVarInt(this); + const hasCount = diff & 1; + this.diff = floor(diff / 2); + this.count = 1; + if (hasCount) { + this.count = readVarUint(this) + 2; + } + } + this.s += this.diff; + this.count--; + return this.s; + } +}; +var StringDecoder = class { + /** + * @param {Uint8Array} uint8Array + */ + constructor(uint8Array) { + this.decoder = new UintOptRleDecoder(uint8Array); + this.str = readVarString(this.decoder); + this.spos = 0; + } + /** + * @return {string} + */ + read() { + const end = this.spos + this.decoder.read(); + const res = this.str.slice(this.spos, end); + this.spos = end; + return res; + } +}; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/webcrypto.js +var subtle = crypto.subtle; +var getRandomValues = crypto.getRandomValues.bind(crypto); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/random.js +var rand = Math.random; +var uint32 = () => getRandomValues(new Uint32Array(1))[0]; +var oneOf = (arr) => arr[floor(rand() * arr.length)]; +var uuidv4Template = "10000000-1000-4000-8000" + -1e11; +var uuidv4 = () => uuidv4Template.replace( + /[018]/g, + /** @param {number} c */ + (c) => (c ^ uint32() & 15 >> c / 4).toString(16) +); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/time.js +var getUnixTime = Date.now; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/promise.js +var create4 = (f) => ( + /** @type {Promise} */ + new Promise(f) +); +var all = Promise.all.bind(Promise); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/conditions.js +var undefinedToNull = (v2) => v2 === void 0 ? null : v2; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/storage.js +var VarStoragePolyfill = class { + constructor() { + this.map = /* @__PURE__ */ new Map(); + } + /** + * @param {string} key + * @param {any} newValue + */ + setItem(key, newValue) { + this.map.set(key, newValue); + } + /** + * @param {string} key + */ + getItem(key) { + return this.map.get(key); + } +}; +var _localStorage = new VarStoragePolyfill(); +var usePolyfill = true; +try { + if (typeof localStorage !== "undefined" && localStorage) { + _localStorage = localStorage; + usePolyfill = false; + } +} catch (e) { +} +var varStorage = _localStorage; +var onChange = (eventHandler) => usePolyfill || addEventListener( + "storage", + /** @type {any} */ + eventHandler +); +var offChange = (eventHandler) => usePolyfill || removeEventListener( + "storage", + /** @type {any} */ + eventHandler +); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/trait/equality.js +var EqualityTraitSymbol = /* @__PURE__ */ Symbol("Equality"); +var equals = (a, b2) => a === b2 || !!a?.[EqualityTraitSymbol]?.(b2) || false; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/object.js +var isObject = (o) => typeof o === "object"; +var assign = Object.assign; +var keys2 = Object.keys; +var forEach3 = (obj, f) => { + for (const key in obj) { + f(obj[key], key); + } +}; +var map3 = (obj, f) => { + const results = []; + for (const key in obj) { + results.push(f(obj[key], key)); + } + return results; +}; +var size = (obj) => keys2(obj).length; +var isEmpty = (obj) => { + for (const _k in obj) { + return false; + } + return true; +}; +var every2 = (obj, f) => { + for (const key in obj) { + if (!f(obj[key], key)) { + return false; + } + } + return true; +}; +var hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key); +var equalFlat = (a, b2) => a === b2 || size(a) === size(b2) && every2(a, (val, key) => (val !== void 0 || hasProperty(b2, key)) && equals(b2[key], val)); +var freeze = Object.freeze; +var deepFreeze = (o) => { + for (const key in o) { + const c = o[key]; + if (typeof c === "object" || typeof c === "function") { + deepFreeze(o[key]); + } + } + return freeze(o); +}; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/function.js +var callAll = (fs, args2, i = 0) => { + try { + for (; i < fs.length; i++) { + fs[i](...args2); + } + } finally { + if (i < fs.length) { + callAll(fs, args2, i + 1); + } + } +}; +var id = (a) => a; +var equalityDeep = (a, b2) => { + if (a === b2) { + return true; + } + if (a == null || b2 == null || a.constructor !== b2.constructor && (a.constructor || Object) !== (b2.constructor || Object)) { + return false; + } + if (a[EqualityTraitSymbol] != null) { + return a[EqualityTraitSymbol](b2); + } + switch (a.constructor) { + case ArrayBuffer: + a = new Uint8Array(a); + b2 = new Uint8Array(b2); + // eslint-disable-next-line no-fallthrough + case Uint8Array: { + if (a.byteLength !== b2.byteLength) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (a[i] !== b2[i]) { + return false; + } + } + break; + } + case Set: { + if (a.size !== b2.size) { + return false; + } + for (const value of a) { + if (!b2.has(value)) { + return false; + } + } + break; + } + case Map: { + if (a.size !== b2.size) { + return false; + } + for (const key of a.keys()) { + if (!b2.has(key) || !equalityDeep(a.get(key), b2.get(key))) { + return false; + } + } + break; + } + case void 0: + case Object: + if (size(a) !== size(b2)) { + return false; + } + for (const key in a) { + if (!hasProperty(a, key) || !equalityDeep(a[key], b2[key])) { + return false; + } + } + break; + case Array: + if (a.length !== b2.length) { + return false; + } + for (let i = 0; i < a.length; i++) { + if (!equalityDeep(a[i], b2[i])) { + return false; + } + } + break; + default: + return false; + } + return true; +}; +var isOneOf = (value, options) => options.includes(value); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/environment.js +var isNode = typeof process !== "undefined" && process.release && /node|io\.js/.test(process.release.name) && Object.prototype.toString.call(typeof process !== "undefined" ? process : 0) === "[object process]"; +var isBrowser = typeof window !== "undefined" && typeof document !== "undefined" && !isNode; +var isMac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; +var params; +var args = []; +var computeParams = () => { + if (params === void 0) { + if (isNode) { + params = create(); + const pargs = process.argv; + let currParamName = null; + for (let i = 0; i < pargs.length; i++) { + const parg = pargs[i]; + if (parg[0] === "-") { + if (currParamName !== null) { + params.set(currParamName, ""); + } + currParamName = parg; + } else { + if (currParamName !== null) { + params.set(currParamName, parg); + currParamName = null; + } else { + args.push(parg); + } + } + } + if (currParamName !== null) { + params.set(currParamName, ""); + } + } else if (typeof location === "object") { + params = create(); + (location.search || "?").slice(1).split("&").forEach((kv) => { + if (kv.length !== 0) { + const [key, value] = kv.split("="); + params.set(`--${fromCamelCase(key, "-")}`, value); + params.set(`-${fromCamelCase(key, "-")}`, value); + } + }); + } else { + params = create(); + } + } + return params; +}; +var hasParam = (name) => computeParams().has(name); +var getVariable = (name) => isNode ? undefinedToNull(process.env[name.toUpperCase().replaceAll("-", "_")]) : undefinedToNull(varStorage.getItem(name)); +var hasConf = (name) => hasParam("--" + name) || getVariable(name) !== null; +var production = hasConf("production"); +var forceColor = isNode && isOneOf(process.env.FORCE_COLOR, ["true", "1", "2"]); +var supportsColor = forceColor || !hasParam("--no-colors") && // @todo deprecate --no-colors +!hasConf("no-color") && (!isNode || process.stdout.isTTY) && (!isNode || hasParam("--color") || getVariable("COLORTERM") !== null || (getVariable("TERM") || "").includes("color")); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/buffer.js +var createUint8ArrayFromLen = (len) => new Uint8Array(len); +var createUint8ArrayViewFromArrayBuffer = (buffer, byteOffset, length2) => new Uint8Array(buffer, byteOffset, length2); +var createUint8ArrayFromArrayBuffer = (buffer) => new Uint8Array(buffer); +var toBase64Browser = (bytes) => { + let s = ""; + for (let i = 0; i < bytes.byteLength; i++) { + s += fromCharCode(bytes[i]); + } + return btoa(s); +}; +var toBase64Node = (bytes) => Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64"); +var fromBase64Browser = (s) => { + const a = atob(s); + const bytes = createUint8ArrayFromLen(a.length); + for (let i = 0; i < a.length; i++) { + bytes[i] = a.charCodeAt(i); + } + return bytes; +}; +var fromBase64Node = (s) => { + const buf = Buffer.from(s, "base64"); + return createUint8ArrayViewFromArrayBuffer(buf.buffer, buf.byteOffset, buf.byteLength); +}; +var toBase64 = isBrowser ? toBase64Browser : toBase64Node; +var fromBase64 = isBrowser ? fromBase64Browser : fromBase64Node; +var copyUint8Array = (uint8Array) => { + const newBuf = createUint8ArrayFromLen(uint8Array.byteLength); + newBuf.set(uint8Array); + return newBuf; +}; +var encodeAny = (data) => encode((encoder) => writeAny(encoder, data)); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/pair.js +var Pair = class { + /** + * @param {L} left + * @param {R} right + */ + constructor(left, right) { + this.left = left; + this.right = right; + } +}; +var create5 = (left, right) => new Pair(left, right); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/prng.js +var bool = (gen) => gen.next() >= 0.5; +var int53 = (gen, min2, max2) => floor(gen.next() * (max2 + 1 - min2) + min2); +var int32 = (gen, min2, max2) => floor(gen.next() * (max2 + 1 - min2) + min2); +var int31 = (gen, min2, max2) => int32(gen, min2, max2); +var letter = (gen) => fromCharCode(int31(gen, 97, 122)); +var word = (gen, minLen = 0, maxLen = 20) => { + const len = int31(gen, minLen, maxLen); + let str = ""; + for (let i = 0; i < len; i++) { + str += letter(gen); + } + return str; +}; +var oneOf2 = (gen, array) => array[int31(gen, 0, array.length - 1)]; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/schema.js +var schemaSymbol = /* @__PURE__ */ Symbol("0schema"); +var ValidationError = class { + constructor() { + this._rerrs = []; + } + /** + * @param {string?} path + * @param {string} expected + * @param {string} has + * @param {string?} message + */ + extend(path, expected, has2, message = null) { + this._rerrs.push({ path, expected, has: has2, message }); + } + toString() { + const s = []; + for (let i = this._rerrs.length - 1; i > 0; i--) { + const r = this._rerrs[i]; + s.push(repeat(" ", (this._rerrs.length - i) * 2) + `${r.path != null ? `[${r.path}] ` : ""}${r.has} doesn't match ${r.expected}. ${r.message}`); + } + return s.join("\n"); + } +}; +var shapeExtends = (a, b2) => { + if (a === b2) return true; + if (a == null || b2 == null || a.constructor !== b2.constructor) return false; + if (a[EqualityTraitSymbol]) return equals(a, b2); + if (isArray(a)) { + return every( + a, + (aitem) => some(b2, (bitem) => shapeExtends(aitem, bitem)) + ); + } else if (isObject(a)) { + return every2( + a, + (aitem, akey) => shapeExtends(aitem, b2[akey]) + ); + } + return false; +}; +var Schema2 = class { + // this.shape must not be defined on Schema. Otherwise typecheck on metatypes (e.g. $$object) won't work as expected anymore + /** + * If true, the more things are added to the shape the more objects this schema will accept (e.g. + * union). By default, the more objects are added, the the fewer objects this schema will accept. + * @protected + */ + static _dilutes = false; + /** + * @param {Schema} other + */ + extends(other) { + let [a, b2] = [ + /** @type {any} */ + this.shape, + /** @type {any} */ + other.shape + ]; + if ( + /** @type {typeof Schema} */ + this.constructor._dilutes + ) [b2, a] = [a, b2]; + return shapeExtends(a, b2); + } + /** + * Overwrite this when necessary. By default, we only check the `shape` property which every shape + * should have. + * @param {Schema} other + */ + equals(other) { + return this.constructor === other.constructor && equalityDeep(this.shape, other.shape); + } + [schemaSymbol]() { + return true; + } + /** + * @param {object} other + */ + [EqualityTraitSymbol](other) { + return this.equals( + /** @type {any} */ + other + ); + } + /** + * Use `schema.validate(obj)` with a typed parameter that is already of typed to be an instance of + * Schema. Validate will check the structure of the parameter and return true iff the instance + * really is an instance of Schema. + * + * @param {T} o + * @return {boolean} + */ + validate(o) { + return this.check(o); + } + /* c8 ignore start */ + /** + * Similar to validate, but this method accepts untyped parameters. + * + * @param {any} _o + * @param {ValidationError} [_err] + * @return {_o is T} + */ + check(_o, _err) { + methodUnimplemented(); + } + /* c8 ignore stop */ + /** + * @type {Schema} + */ + get nullable() { + return $union(this, $null); + } + /** + * @type {$Optional>} + */ + get optional() { + return new $Optional( + /** @type {Schema} */ + this + ); + } + /** + * Cast a variable to a specific type. Returns the casted value, or throws an exception otherwise. + * Use this if you know that the type is of a specific type and you just want to convince the type + * system. + * + * **Do not rely on these error messages!** + * Performs an assertion check only if not in a production environment. + * + * @template OO + * @param {OO} o + * @return {Extract extends never ? T : (OO extends Array ? T : Extract)} + */ + cast(o) { + assert(o, this); + return ( + /** @type {any} */ + o + ); + } + /** + * EXPECTO PATRONUM!! 🪄 + * This function protects against type errors. Though it may not work in the real world. + * + * "After all this time?" + * "Always." - Snape, talking about type safety + * + * Ensures that a variable is a a specific type. Returns the value, or throws an exception if the assertion check failed. + * Use this if you know that the type is of a specific type and you just want to convince the type + * system. + * + * Can be useful when defining lambdas: `s.lambda(s.$number, s.$void).expect((n) => n + 1)` + * + * **Do not rely on these error messages!** + * Performs an assertion check if not in a production environment. + * + * @param {T} o + * @return {o extends T ? T : never} + */ + expect(o) { + assert(o, this); + return o; + } +}; +var $ConstructedBy = class extends Schema2 { + /** + * @param {C} c + * @param {((o:Instance)=>boolean)|null} check + */ + constructor(c, check) { + super(); + this.shape = c; + this._c = check; + } + /** + * @param {any} o + * @param {ValidationError} [err] + * @return {o is C extends ((...args:any[]) => infer T) ? T : (C extends (new (...args:any[]) => any) ? InstanceType : never)} o + */ + check(o, err = void 0) { + const c = o?.constructor === this.shape && (this._c == null || this._c(o)); + !c && err?.extend(null, this.shape.name, o?.constructor.name, o?.constructor !== this.shape ? "Constructor match failed" : "Check failed"); + return c; + } +}; +var $constructedBy = (c, check = null) => new $ConstructedBy(c, check); +var $$constructedBy = $constructedBy($ConstructedBy); +var $Custom = class extends Schema2 { + /** + * @param {(o:any) => boolean} check + */ + constructor(check) { + super(); + this.shape = check; + } + /** + * @param {any} o + * @param {ValidationError} err + * @return {o is any} + */ + check(o, err) { + const c = this.shape(o); + !c && err?.extend(null, "custom prop", o?.constructor.name, "failed to check custom prop"); + return c; + } +}; +var $custom = (check) => new $Custom(check); +var $$custom = $constructedBy($Custom); +var $Literal = class extends Schema2 { + /** + * @param {Array} literals + */ + constructor(literals) { + super(); + this.shape = literals; + } + /** + * + * @param {any} o + * @param {ValidationError} [err] + * @return {o is T} + */ + check(o, err) { + const c = this.shape.some((a) => a === o); + !c && err?.extend(null, this.shape.join(" | "), o.toString()); + return c; + } +}; +var $literal = (...literals) => new $Literal(literals); +var $$literal = $constructedBy($Literal); +var _regexEscape = ( + /** @type {any} */ + RegExp.escape || /** @type {(str:string) => string} */ + ((str) => str.replace(/[().|&,$^[\]]/g, (s) => "\\" + s)) +); +var _schemaStringTemplateToRegex = (s) => { + if ($string.check(s)) { + return [_regexEscape(s)]; + } + if ($$literal.check(s)) { + return ( + /** @type {Array} */ + s.shape.map((v2) => v2 + "") + ); + } + if ($$number.check(s)) { + return ["[+-]?\\d+.?\\d*"]; + } + if ($$string.check(s)) { + return [".*"]; + } + if ($$union.check(s)) { + return s.shape.map(_schemaStringTemplateToRegex).flat(1); + } + unexpectedCase(); +}; +var $StringTemplate = class extends Schema2 { + /** + * @param {T} shape + */ + constructor(shape) { + super(); + this.shape = shape; + this._r = new RegExp("^" + shape.map(_schemaStringTemplateToRegex).map((opts) => `(${opts.join("|")})`).join("") + "$"); + } + /** + * @param {any} o + * @param {ValidationError} [err] + * @return {o is CastStringTemplateArgsToTemplate} + */ + check(o, err) { + const c = this._r.exec(o) != null; + !c && err?.extend(null, this._r.toString(), o.toString(), "String doesn't match string template."); + return c; + } +}; +var $$stringTemplate = $constructedBy($StringTemplate); +var isOptionalSymbol = /* @__PURE__ */ Symbol("optional"); +var $Optional = class extends Schema2 { + /** + * @param {S} shape + */ + constructor(shape) { + super(); + this.shape = shape; + } + /** + * @param {any} o + * @param {ValidationError} [err] + * @return {o is (Unwrap|undefined)} + */ + check(o, err) { + const c = o === void 0 || this.shape.check(o); + !c && err?.extend(null, "undefined (optional)", "()"); + return c; + } + get [isOptionalSymbol]() { + return true; + } +}; +var $$optional = $constructedBy($Optional); +var $Never = class extends Schema2 { + /** + * @param {any} _o + * @param {ValidationError} [err] + * @return {_o is never} + */ + check(_o, err) { + err?.extend(null, "never", typeof _o); + return false; + } +}; +var $never = new $Never(); +var $$never = $constructedBy($Never); +var $Object = class _$Object extends Schema2 { + /** + * @param {S} shape + * @param {boolean} partial + */ + constructor(shape, partial = false) { + super(); + this.shape = shape; + this._isPartial = partial; + } + static _dilutes = true; + /** + * @type {Schema>>} + */ + get partial() { + return new _$Object(this.shape, true); + } + /** + * @param {any} o + * @param {ValidationError} err + * @return {o is $ObjectToType} + */ + check(o, err) { + if (o == null) { + err?.extend(null, "object", "null"); + return false; + } + return every2(this.shape, (vv, vk) => { + const c = this._isPartial && !hasProperty(o, vk) || vv.check(o[vk], err); + !c && err?.extend(vk.toString(), vv.toString(), typeof o[vk], "Object property does not match"); + return c; + }); + } +}; +var $object = (def) => ( + /** @type {any} */ + new $Object(def) +); +var $$object = $constructedBy($Object); +var $objectAny = $custom((o) => o != null && (o.constructor === Object || o.constructor == null)); +var $Record = class extends Schema2 { + /** + * @param {Keys} keys + * @param {Values} values + */ + constructor(keys3, values) { + super(); + this.shape = { + keys: keys3, + values + }; + } + /** + * @param {any} o + * @param {ValidationError} err + * @return {o is { [key in Unwrap]: Unwrap }} + */ + check(o, err) { + return o != null && every2(o, (vv, vk) => { + const ck = this.shape.keys.check(vk, err); + !ck && err?.extend(vk + "", "Record", typeof o, ck ? "Key doesn't match schema" : "Value doesn't match value"); + return ck && this.shape.values.check(vv, err); + }); + } +}; +var $record = (keys3, values) => new $Record(keys3, values); +var $$record = $constructedBy($Record); +var $Tuple = class extends Schema2 { + /** + * @param {S} shape + */ + constructor(shape) { + super(); + this.shape = shape; + } + /** + * @param {any} o + * @param {ValidationError} err + * @return {o is { [K in keyof S]: S[K] extends Schema ? Type : never }} + */ + check(o, err) { + return o != null && every2(this.shape, (vv, vk) => { + const c = ( + /** @type {Schema} */ + vv.check(o[vk], err) + ); + !c && err?.extend(vk.toString(), "Tuple", typeof vv); + return c; + }); + } +}; +var $tuple = (...def) => new $Tuple(def); +var $$tuple = $constructedBy($Tuple); +var $Array = class extends Schema2 { + /** + * @param {Array} v + */ + constructor(v2) { + super(); + this.shape = v2.length === 1 ? v2[0] : new $Union(v2); + } + /** + * @param {any} o + * @param {ValidationError} [err] + * @return {o is Array ? T : never>} o + */ + check(o, err) { + const c = isArray(o) && every(o, (oi) => this.shape.check(oi)); + !c && err?.extend(null, "Array", ""); + return c; + } +}; +var $array = (...def) => new $Array(def); +var $$array = $constructedBy($Array); +var $arrayAny = $custom((o) => isArray(o)); +var $InstanceOf = class extends Schema2 { + /** + * @param {new (...args:any) => T} constructor + * @param {((o:T) => boolean)|null} check + */ + constructor(constructor, check) { + super(); + this.shape = constructor; + this._c = check; + } + /** + * @param {any} o + * @param {ValidationError} err + * @return {o is T} + */ + check(o, err) { + const c = o instanceof this.shape && (this._c == null || this._c(o)); + !c && err?.extend(null, this.shape.name, o?.constructor.name); + return c; + } +}; +var $instanceOf = (c, check = null) => new $InstanceOf(c, check); +var $$instanceOf = $constructedBy($InstanceOf); +var $$schema = $instanceOf(Schema2); +var $Lambda = class extends Schema2 { + /** + * @param {Args} args + */ + constructor(args2) { + super(); + this.len = args2.length - 1; + this.args = $tuple(...args2.slice(-1)); + this.res = args2[this.len]; + } + /** + * @param {any} f + * @param {ValidationError} err + * @return {f is _LArgsToLambdaDef} + */ + check(f, err) { + const c = f.constructor === Function && f.length <= this.len; + !c && err?.extend(null, "function", typeof f); + return c; + } +}; +var $$lambda = $constructedBy($Lambda); +var $function = $custom((o) => typeof o === "function"); +var $Intersection = class extends Schema2 { + /** + * @param {T} v + */ + constructor(v2) { + super(); + this.shape = v2; + } + /** + * @param {any} o + * @param {ValidationError} [err] + * @return {o is Intersect>} + */ + check(o, err) { + const c = every(this.shape, (check) => check.check(o, err)); + !c && err?.extend(null, "Intersectinon", typeof o); + return c; + } +}; +var $$intersect = $constructedBy($Intersection, (o) => o.shape.length > 0); +var $Union = class extends Schema2 { + static _dilutes = true; + /** + * @param {Array>} v + */ + constructor(v2) { + super(); + this.shape = v2; + } + /** + * @param {any} o + * @param {ValidationError} [err] + * @return {o is S} + */ + check(o, err) { + const c = some(this.shape, (vv) => vv.check(o, err)); + err?.extend(null, "Union", typeof o); + return c; + } +}; +var $union = (...schemas) => schemas.findIndex(($s) => $$union.check($s)) >= 0 ? $union(...schemas.map(($s) => $($s)).map(($s) => $$union.check($s) ? $s.shape : [$s]).flat(1)) : schemas.length === 1 ? schemas[0] : new $Union(schemas); +var $$union = ( + /** @type {Schema<$Union>} */ + $constructedBy($Union) +); +var _t = () => true; +var $any = $custom(_t); +var $$any = ( + /** @type {Schema>} */ + $constructedBy($Custom, (o) => o.shape === _t) +); +var $bigint = $custom((o) => typeof o === "bigint"); +var $$bigint = ( + /** @type {Schema>} */ + $custom((o) => o === $bigint) +); +var $symbol = $custom((o) => typeof o === "symbol"); +var $$symbol = ( + /** @type {Schema>} */ + $custom((o) => o === $symbol) +); +var $number = $custom((o) => typeof o === "number"); +var $$number = ( + /** @type {Schema>} */ + $custom((o) => o === $number) +); +var $string = $custom((o) => typeof o === "string"); +var $$string = ( + /** @type {Schema>} */ + $custom((o) => o === $string) +); +var $boolean = $custom((o) => typeof o === "boolean"); +var $$boolean = ( + /** @type {Schema>} */ + $custom((o) => o === $boolean) +); +var $undefined = $literal(void 0); +var $$undefined = ( + /** @type {Schema>} */ + $constructedBy($Literal, (o) => o.shape.length === 1 && o.shape[0] === void 0) +); +var $void = $literal(void 0); +var $null = $literal(null); +var $$null = ( + /** @type {Schema>} */ + $constructedBy($Literal, (o) => o.shape.length === 1 && o.shape[0] === null) +); +var $uint8Array = $constructedBy(Uint8Array); +var $$uint8Array = ( + /** @type {Schema>} */ + $constructedBy($ConstructedBy, (o) => o.shape === Uint8Array) +); +var $primitive = $union($number, $string, $null, $undefined, $bigint, $boolean, $symbol); +var $json = (() => { + const $jsonArr = ( + /** @type {$Array<$any>} */ + $array($any) + ); + const $jsonRecord = ( + /** @type {$Record<$string,$any>} */ + $record($string, $any) + ); + const $json2 = $union($number, $string, $null, $boolean, $jsonArr, $jsonRecord); + $jsonArr.shape = $json2; + $jsonRecord.shape.values = $json2; + return $json2; +})(); +var $ = (o) => { + if ($$schema.check(o)) { + return ( + /** @type {any} */ + o + ); + } else if ($objectAny.check(o)) { + const o2 = {}; + for (const k in o) { + o2[k] = $(o[k]); + } + return ( + /** @type {any} */ + $object(o2) + ); + } else if ($arrayAny.check(o)) { + return ( + /** @type {any} */ + $union(...o.map($)) + ); + } else if ($primitive.check(o)) { + return ( + /** @type {any} */ + $literal(o) + ); + } else if ($function.check(o)) { + return ( + /** @type {any} */ + $constructedBy( + /** @type {any} */ + o + ) + ); + } + unexpectedCase(); +}; +var assert = production ? () => { +} : (o, schema) => { + const err = new ValidationError(); + if (!schema.check(o, err)) { + throw create3(`Expected value to be of type ${schema.constructor.name}. +${err.toString()}`); + } +}; +var PatternMatcher = class { + /** + * @param {Schema} [$state] + */ + constructor($state) { + this.patterns = []; + this.$state = $state; + } + /** + * @template P + * @template R + * @param {P} pattern + * @param {(o:NoInfer>>,s:State)=>R} handler + * @return {PatternMatcher>,R>>} + */ + if(pattern, handler) { + this.patterns.push({ if: $(pattern), h: handler }); + return this; + } + /** + * @template R + * @param {(o:any,s:State)=>R} h + */ + else(h2) { + return this.if($any, h2); + } + /** + * @return {State extends undefined + * ? >(o:In,state?:undefined)=>PatternMatchResult + * : >(o:In,state:State)=>PatternMatchResult} + */ + done() { + return ( + /** @type {any} */ + (o, s) => { + for (let i = 0; i < this.patterns.length; i++) { + const p = this.patterns[i]; + if (p.if.check(o)) { + return p.h(o, s); + } + } + throw create3("Unhandled pattern"); + } + ); + } +}; +var match = (state) => new PatternMatcher( + /** @type {any} */ + state +); +var _random = ( + /** @type {any} */ + match( + /** @type {Schema} */ + $any + ).if($$number, (_o, gen) => int53(gen, MIN_SAFE_INTEGER, MAX_SAFE_INTEGER)).if($$string, (_o, gen) => word(gen)).if($$boolean, (_o, gen) => bool(gen)).if($$bigint, (_o, gen) => BigInt(int53(gen, MIN_SAFE_INTEGER, MAX_SAFE_INTEGER))).if($$union, (o, gen) => random(gen, oneOf2(gen, o.shape))).if($$object, (o, gen) => { + const res = {}; + for (const k in o.shape) { + let prop = o.shape[k]; + if ($$optional.check(prop)) { + if (bool(gen)) { + continue; + } + prop = prop.shape; + } + res[k] = _random(prop, gen); + } + return res; + }).if($$array, (o, gen) => { + const arr = []; + const n = int32(gen, 0, 42); + for (let i = 0; i < n; i++) { + arr.push(random(gen, o.shape)); + } + return arr; + }).if($$literal, (o, gen) => { + return oneOf2(gen, o.shape); + }).if($$null, (o, gen) => { + return null; + }).if($$lambda, (o, gen) => { + const res = random(gen, o.res); + return () => res; + }).if($$any, (o, gen) => random(gen, oneOf2(gen, [ + $number, + $string, + $null, + $undefined, + $bigint, + $boolean, + $array($number), + $record($union("a", "b", "c"), $number) + ]))).if($$record, (o, gen) => { + const res = {}; + const keysN = int53(gen, 0, 3); + for (let i = 0; i < keysN; i++) { + const key = random(gen, o.shape.keys); + const val = random(gen, o.shape.values); + res[key] = val; + } + return res; + }).done() +); +var random = (gen, schema) => ( + /** @type {any} */ + _random($(schema), gen) +); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/dom.js +var doc3 = ( + /** @type {Document} */ + typeof document !== "undefined" ? document : {} +); +var $fragment = $custom((el) => el.nodeType === DOCUMENT_FRAGMENT_NODE); +var domParser = ( + /** @type {DOMParser} */ + typeof DOMParser !== "undefined" ? new DOMParser() : null +); +var $element = $custom((el) => el.nodeType === ELEMENT_NODE); +var $text = $custom((el) => el.nodeType === TEXT_NODE); +var mapToStyleString = (m2) => map2(m2, (value, key) => `${key}:${value};`).join(""); +var ELEMENT_NODE = doc3.ELEMENT_NODE; +var TEXT_NODE = doc3.TEXT_NODE; +var CDATA_SECTION_NODE = doc3.CDATA_SECTION_NODE; +var COMMENT_NODE = doc3.COMMENT_NODE; +var DOCUMENT_NODE = doc3.DOCUMENT_NODE; +var DOCUMENT_TYPE_NODE = doc3.DOCUMENT_TYPE_NODE; +var DOCUMENT_FRAGMENT_NODE = doc3.DOCUMENT_FRAGMENT_NODE; +var $node = $custom((el) => el.nodeType === DOCUMENT_NODE); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/eventloop.js +var createTimeoutClass = (clearFunction) => class TT { + /** + * @param {number} timeoutId + */ + constructor(timeoutId) { + this._ = timeoutId; + } + destroy() { + clearFunction(this._); + } +}; +var Timeout = createTimeoutClass(clearTimeout); +var timeout = (timeout2, callback) => new Timeout(setTimeout(callback, timeout2)); +var Interval = createTimeoutClass(clearInterval); +var Animation = createTimeoutClass((arg) => typeof requestAnimationFrame !== "undefined" && cancelAnimationFrame(arg)); +var Idle = createTimeoutClass((arg) => typeof cancelIdleCallback !== "undefined" && cancelIdleCallback(arg)); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/symbol.js +var create6 = Symbol; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/logging.common.js +var BOLD = create6(); +var UNBOLD = create6(); +var BLUE = create6(); +var GREY = create6(); +var GREEN = create6(); +var RED = create6(); +var PURPLE = create6(); +var ORANGE = create6(); +var UNCOLOR = create6(); +var computeNoColorLoggingArgs = (args2) => { + if (args2.length === 1 && args2[0]?.constructor === Function) { + args2 = /** @type {Array} */ + /** @type {[function]} */ + args2[0](); + } + const strBuilder = []; + const logArgs = []; + let i = 0; + for (; i < args2.length; i++) { + const arg = args2[i]; + if (arg === void 0) { + break; + } else if (arg.constructor === String || arg.constructor === Number) { + strBuilder.push(arg); + } else if (arg.constructor === Object) { + break; + } + } + if (i > 0) { + logArgs.push(strBuilder.join("")); + } + for (; i < args2.length; i++) { + const arg = args2[i]; + if (!(arg instanceof Symbol)) { + logArgs.push(arg); + } + } + return logArgs; +}; +var lastLoggingTime = getUnixTime(); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/logging.js +var _browserStyleMap = { + [BOLD]: create5("font-weight", "bold"), + [UNBOLD]: create5("font-weight", "normal"), + [BLUE]: create5("color", "blue"), + [GREEN]: create5("color", "green"), + [GREY]: create5("color", "grey"), + [RED]: create5("color", "red"), + [PURPLE]: create5("color", "purple"), + [ORANGE]: create5("color", "orange"), + // not well supported in chrome when debugging node with inspector - TODO: deprecate + [UNCOLOR]: create5("color", "black") +}; +var computeBrowserLoggingArgs = (args2) => { + if (args2.length === 1 && args2[0]?.constructor === Function) { + args2 = /** @type {Array} */ + /** @type {[function]} */ + args2[0](); + } + const strBuilder = []; + const styles = []; + const currentStyle = create(); + let logArgs = []; + let i = 0; + for (; i < args2.length; i++) { + const arg = args2[i]; + const style2 = _browserStyleMap[arg]; + if (style2 !== void 0) { + currentStyle.set(style2.left, style2.right); + } else { + if (arg === void 0) { + break; + } + if (arg.constructor === String || arg.constructor === Number) { + const style3 = mapToStyleString(currentStyle); + if (i > 0 || style3.length > 0) { + strBuilder.push("%c" + arg); + styles.push(style3); + } else { + strBuilder.push(arg); + } + } else { + break; + } + } + } + if (i > 0) { + logArgs = styles; + logArgs.unshift(strBuilder.join("")); + } + for (; i < args2.length; i++) { + const arg = args2[i]; + if (!(arg instanceof Symbol)) { + logArgs.push(arg); + } + } + return logArgs; +}; +var computeLoggingArgs = supportsColor ? computeBrowserLoggingArgs : computeNoColorLoggingArgs; +var print = (...args2) => { + console.log(...computeLoggingArgs(args2)); + vconsoles.forEach((vc) => vc.print(args2)); +}; +var warn2 = (...args2) => { + console.warn(...computeLoggingArgs(args2)); + args2.unshift(ORANGE); + vconsoles.forEach((vc) => vc.print(args2)); +}; +var vconsoles = create2(); + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/iterator.js +var createIterator = (next2) => ({ + /** + * @return {IterableIterator} + */ + [Symbol.iterator]() { + return this; + }, + // @ts-ignore + next: next2 +}); +var iteratorFilter = (iterator, filter) => createIterator(() => { + let res; + do { + res = iterator.next(); + } while (!res.done && !filter(res.value)); + return res; +}); +var iteratorMap = (iterator, fmap) => createIterator(() => { + const { done, value } = iterator.next(); + return { done, value: done ? void 0 : fmap(value) }; +}); + +// ../../node_modules/.pnpm/yjs@13.6.31/node_modules/yjs/dist/yjs.mjs +var DeleteItem = class { + /** + * @param {number} clock + * @param {number} len + */ + constructor(clock, len) { + this.clock = clock; + this.len = len; + } +}; +var DeleteSet = class { + constructor() { + this.clients = /* @__PURE__ */ new Map(); + } +}; +var iterateDeletedStructs = (transaction, ds, f) => ds.clients.forEach((deletes, clientid) => { + const structs = ( + /** @type {Array} */ + transaction.doc.store.clients.get(clientid) + ); + if (structs != null) { + const lastStruct = structs[structs.length - 1]; + const clockState = lastStruct.id.clock + lastStruct.length; + for (let i = 0, del2 = deletes[i]; i < deletes.length && del2.clock < clockState; del2 = deletes[++i]) { + iterateStructs(transaction, structs, del2.clock, del2.len, f); + } + } +}); +var findIndexDS = (dis, clock) => { + let left = 0; + let right = dis.length - 1; + while (left <= right) { + const midindex = floor((left + right) / 2); + const mid = dis[midindex]; + const midclock = mid.clock; + if (midclock <= clock) { + if (clock < midclock + mid.len) { + return midindex; + } + left = midindex + 1; + } else { + right = midindex - 1; + } + } + return null; +}; +var isDeleted = (ds, id2) => { + const dis = ds.clients.get(id2.client); + return dis !== void 0 && findIndexDS(dis, id2.clock) !== null; +}; +var sortAndMergeDeleteSet = (ds) => { + ds.clients.forEach((dels) => { + dels.sort((a, b2) => a.clock - b2.clock); + let i, j2; + for (i = 1, j2 = 1; i < dels.length; i++) { + const left = dels[j2 - 1]; + const right = dels[i]; + if (left.clock + left.len >= right.clock) { + dels[j2 - 1] = new DeleteItem(left.clock, max(left.len, right.clock + right.len - left.clock)); + } else { + if (j2 < i) { + dels[j2] = right; + } + j2++; + } + } + dels.length = j2; + }); +}; +var mergeDeleteSets = (dss) => { + const merged = new DeleteSet(); + for (let dssI = 0; dssI < dss.length; dssI++) { + dss[dssI].clients.forEach((delsLeft, client) => { + if (!merged.clients.has(client)) { + const dels = delsLeft.slice(); + for (let i = dssI + 1; i < dss.length; i++) { + appendTo(dels, dss[i].clients.get(client) || []); + } + merged.clients.set(client, dels); + } + }); + } + sortAndMergeDeleteSet(merged); + return merged; +}; +var addToDeleteSet = (ds, client, clock, length2) => { + setIfUndefined(ds.clients, client, () => ( + /** @type {Array} */ + [] + )).push(new DeleteItem(clock, length2)); +}; +var createDeleteSet = () => new DeleteSet(); +var createDeleteSetFromStructStore = (ss) => { + const ds = createDeleteSet(); + ss.clients.forEach((structs, client) => { + const dsitems = []; + for (let i = 0; i < structs.length; i++) { + const struct = structs[i]; + if (struct.deleted) { + const clock = struct.id.clock; + let len = struct.length; + if (i + 1 < structs.length) { + for (let next2 = structs[i + 1]; i + 1 < structs.length && next2.deleted; next2 = structs[++i + 1]) { + len += next2.length; + } + } + dsitems.push(new DeleteItem(clock, len)); + } + } + if (dsitems.length > 0) { + ds.clients.set(client, dsitems); + } + }); + return ds; +}; +var writeDeleteSet = (encoder, ds) => { + writeVarUint(encoder.restEncoder, ds.clients.size); + from2(ds.clients.entries()).sort((a, b2) => b2[0] - a[0]).forEach(([client, dsitems]) => { + encoder.resetDsCurVal(); + writeVarUint(encoder.restEncoder, client); + const len = dsitems.length; + writeVarUint(encoder.restEncoder, len); + for (let i = 0; i < len; i++) { + const item = dsitems[i]; + encoder.writeDsClock(item.clock); + encoder.writeDsLen(item.len); + } + }); +}; +var readDeleteSet = (decoder) => { + const ds = new DeleteSet(); + const numClients = readVarUint(decoder.restDecoder); + for (let i = 0; i < numClients; i++) { + decoder.resetDsCurVal(); + const client = readVarUint(decoder.restDecoder); + const numberOfDeletes = readVarUint(decoder.restDecoder); + if (numberOfDeletes > 0) { + const dsField = setIfUndefined(ds.clients, client, () => ( + /** @type {Array} */ + [] + )); + for (let i2 = 0; i2 < numberOfDeletes; i2++) { + dsField.push(new DeleteItem(decoder.readDsClock(), decoder.readDsLen())); + } + } + } + return ds; +}; +var readAndApplyDeleteSet = (decoder, transaction, store) => { + const unappliedDS = new DeleteSet(); + const numClients = readVarUint(decoder.restDecoder); + for (let i = 0; i < numClients; i++) { + decoder.resetDsCurVal(); + const client = readVarUint(decoder.restDecoder); + const numberOfDeletes = readVarUint(decoder.restDecoder); + const structs = store.clients.get(client) || []; + const state = getState(store, client); + for (let i2 = 0; i2 < numberOfDeletes; i2++) { + const clock = decoder.readDsClock(); + const clockEnd = clock + decoder.readDsLen(); + if (clock < state) { + if (state < clockEnd) { + addToDeleteSet(unappliedDS, client, state, clockEnd - state); + } + let index = findIndexSS(structs, clock); + let struct = structs[index]; + if (!struct.deleted && struct.id.clock < clock) { + structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); + index++; + } + while (index < structs.length) { + struct = structs[index++]; + if (struct.id.clock < clockEnd) { + if (!struct.deleted) { + if (clockEnd < struct.id.clock + struct.length) { + structs.splice(index, 0, splitItem(transaction, struct, clockEnd - struct.id.clock)); + } + struct.delete(transaction); + } + } else { + break; + } + } + } else { + addToDeleteSet(unappliedDS, client, clock, clockEnd - clock); + } + } + } + if (unappliedDS.clients.size > 0) { + const ds = new UpdateEncoderV2(); + writeVarUint(ds.restEncoder, 0); + writeDeleteSet(ds, unappliedDS); + return ds.toUint8Array(); + } + return null; +}; +var generateNewClientId = uint32; +var Doc = class _Doc extends ObservableV2 { + /** + * @param {DocOpts} opts configuration + */ + constructor({ guid = uuidv4(), collectionid = null, gc = true, gcFilter = () => true, meta = null, autoLoad = false, shouldLoad = true } = {}) { + super(); + this.gc = gc; + this.gcFilter = gcFilter; + this.clientID = generateNewClientId(); + this.guid = guid; + this.collectionid = collectionid; + this.share = /* @__PURE__ */ new Map(); + this.store = new StructStore(); + this._transaction = null; + this._transactionCleanups = []; + this.subdocs = /* @__PURE__ */ new Set(); + this._item = null; + this.shouldLoad = shouldLoad; + this.autoLoad = autoLoad; + this.meta = meta; + this.isLoaded = false; + this.isSynced = false; + this.isDestroyed = false; + this.whenLoaded = create4((resolve) => { + this.on("load", () => { + this.isLoaded = true; + resolve(this); + }); + }); + const provideSyncedPromise = () => create4((resolve) => { + const eventHandler = (isSynced) => { + if (isSynced === void 0 || isSynced === true) { + this.off("sync", eventHandler); + resolve(); + } + }; + this.on("sync", eventHandler); + }); + this.on("sync", (isSynced) => { + if (isSynced === false && this.isSynced) { + this.whenSynced = provideSyncedPromise(); + } + this.isSynced = isSynced === void 0 || isSynced === true; + if (this.isSynced && !this.isLoaded) { + this.emit("load", [this]); + } + }); + this.whenSynced = provideSyncedPromise(); + } + /** + * Notify the parent document that you request to load data into this subdocument (if it is a subdocument). + * + * `load()` might be used in the future to request any provider to load the most current data. + * + * It is safe to call `load()` multiple times. + */ + load() { + const item = this._item; + if (item !== null && !this.shouldLoad) { + transact( + /** @type {any} */ + item.parent.doc, + (transaction) => { + transaction.subdocsLoaded.add(this); + }, + null, + true + ); + } + this.shouldLoad = true; + } + getSubdocs() { + return this.subdocs; + } + getSubdocGuids() { + return new Set(from2(this.subdocs).map((doc4) => doc4.guid)); + } + /** + * Changes that happen inside of a transaction are bundled. This means that + * the observer fires _after_ the transaction is finished and that all changes + * that happened inside of the transaction are sent as one message to the + * other peers. + * + * @template T + * @param {function(Transaction):T} f The function that should be executed as a transaction + * @param {any} [origin] Origin of who started the transaction. Will be stored on transaction.origin + * @return T + * + * @public + */ + transact(f, origin = null) { + return transact(this, f, origin); + } + /** + * Define a shared data type. + * + * Multiple calls of `ydoc.get(name, TypeConstructor)` yield the same result + * and do not overwrite each other. I.e. + * `ydoc.get(name, Y.Array) === ydoc.get(name, Y.Array)` + * + * After this method is called, the type is also available on `ydoc.share.get(name)`. + * + * *Best Practices:* + * Define all types right after the Y.Doc instance is created and store them in a separate object. + * Also use the typed methods `getText(name)`, `getArray(name)`, .. + * + * @template {typeof AbstractType} Type + * @example + * const ydoc = new Y.Doc(..) + * const appState = { + * document: ydoc.getText('document') + * comments: ydoc.getArray('comments') + * } + * + * @param {string} name + * @param {Type} TypeConstructor The constructor of the type definition. E.g. Y.Text, Y.Array, Y.Map, ... + * @return {InstanceType} The created type. Constructed with TypeConstructor + * + * @public + */ + get(name, TypeConstructor = ( + /** @type {any} */ + AbstractType + )) { + const type = setIfUndefined(this.share, name, () => { + const t = new TypeConstructor(); + t._integrate(this, null); + return t; + }); + const Constr = type.constructor; + if (TypeConstructor !== AbstractType && Constr !== TypeConstructor) { + if (Constr === AbstractType) { + const t = new TypeConstructor(); + t._map = type._map; + type._map.forEach( + /** @param {Item?} n */ + (n) => { + for (; n !== null; n = n.left) { + n.parent = t; + } + } + ); + t._start = type._start; + for (let n = t._start; n !== null; n = n.right) { + n.parent = t; + } + t._length = type._length; + this.share.set(name, t); + t._integrate(this, null); + return ( + /** @type {InstanceType} */ + t + ); + } else { + throw new Error(`Type with the name ${name} has already been defined with a different constructor`); + } + } + return ( + /** @type {InstanceType} */ + type + ); + } + /** + * @template T + * @param {string} [name] + * @return {YArray} + * + * @public + */ + getArray(name = "") { + return ( + /** @type {YArray} */ + this.get(name, YArray) + ); + } + /** + * @param {string} [name] + * @return {YText} + * + * @public + */ + getText(name = "") { + return this.get(name, YText); + } + /** + * @template T + * @param {string} [name] + * @return {YMap} + * + * @public + */ + getMap(name = "") { + return ( + /** @type {YMap} */ + this.get(name, YMap) + ); + } + /** + * @param {string} [name] + * @return {YXmlElement} + * + * @public + */ + getXmlElement(name = "") { + return ( + /** @type {YXmlElement<{[key:string]:string}>} */ + this.get(name, YXmlElement) + ); + } + /** + * @param {string} [name] + * @return {YXmlFragment} + * + * @public + */ + getXmlFragment(name = "") { + return this.get(name, YXmlFragment); + } + /** + * Converts the entire document into a js object, recursively traversing each yjs type + * Doesn't log types that have not been defined (using ydoc.getType(..)). + * + * @deprecated Do not use this method and rather call toJSON directly on the shared types. + * + * @return {Object} + */ + toJSON() { + const doc4 = {}; + this.share.forEach((value, key) => { + doc4[key] = value.toJSON(); + }); + return doc4; + } + /** + * Emit `destroy` event and unregister all event handlers. + */ + destroy() { + this.isDestroyed = true; + from2(this.subdocs).forEach((subdoc) => subdoc.destroy()); + const item = this._item; + if (item !== null) { + this._item = null; + const content = ( + /** @type {ContentDoc} */ + item.content + ); + content.doc = new _Doc({ guid: this.guid, ...content.opts, shouldLoad: false }); + content.doc._item = item; + transact( + /** @type {any} */ + item.parent.doc, + (transaction) => { + const doc4 = content.doc; + if (!item.deleted) { + transaction.subdocsAdded.add(doc4); + } + transaction.subdocsRemoved.add(this); + }, + null, + true + ); + } + this.emit("destroyed", [true]); + this.emit("destroy", [this]); + super.destroy(); + } +}; +var DSDecoderV1 = class { + /** + * @param {decoding.Decoder} decoder + */ + constructor(decoder) { + this.restDecoder = decoder; + } + resetDsCurVal() { + } + /** + * @return {number} + */ + readDsClock() { + return readVarUint(this.restDecoder); + } + /** + * @return {number} + */ + readDsLen() { + return readVarUint(this.restDecoder); + } +}; +var UpdateDecoderV1 = class extends DSDecoderV1 { + /** + * @return {ID} + */ + readLeftID() { + return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); + } + /** + * @return {ID} + */ + readRightID() { + return createID(readVarUint(this.restDecoder), readVarUint(this.restDecoder)); + } + /** + * Read the next client id. + * Use this in favor of readID whenever possible to reduce the number of objects created. + */ + readClient() { + return readVarUint(this.restDecoder); + } + /** + * @return {number} info An unsigned 8-bit integer + */ + readInfo() { + return readUint8(this.restDecoder); + } + /** + * @return {string} + */ + readString() { + return readVarString(this.restDecoder); + } + /** + * @return {boolean} isKey + */ + readParentInfo() { + return readVarUint(this.restDecoder) === 1; + } + /** + * @return {number} info An unsigned 8-bit integer + */ + readTypeRef() { + return readVarUint(this.restDecoder); + } + /** + * Write len of a struct - well suited for Opt RLE encoder. + * + * @return {number} len + */ + readLen() { + return readVarUint(this.restDecoder); + } + /** + * @return {any} + */ + readAny() { + return readAny(this.restDecoder); + } + /** + * @return {Uint8Array} + */ + readBuf() { + return copyUint8Array(readVarUint8Array(this.restDecoder)); + } + /** + * Legacy implementation uses JSON parse. We use any-decoding in v2. + * + * @return {any} + */ + readJSON() { + return JSON.parse(readVarString(this.restDecoder)); + } + /** + * @return {string} + */ + readKey() { + return readVarString(this.restDecoder); + } +}; +var DSDecoderV2 = class { + /** + * @param {decoding.Decoder} decoder + */ + constructor(decoder) { + this.dsCurrVal = 0; + this.restDecoder = decoder; + } + resetDsCurVal() { + this.dsCurrVal = 0; + } + /** + * @return {number} + */ + readDsClock() { + this.dsCurrVal += readVarUint(this.restDecoder); + return this.dsCurrVal; + } + /** + * @return {number} + */ + readDsLen() { + const diff = readVarUint(this.restDecoder) + 1; + this.dsCurrVal += diff; + return diff; + } +}; +var UpdateDecoderV2 = class extends DSDecoderV2 { + /** + * @param {decoding.Decoder} decoder + */ + constructor(decoder) { + super(decoder); + this.keys = []; + readVarUint(decoder); + this.keyClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); + this.clientDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); + this.leftClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); + this.rightClockDecoder = new IntDiffOptRleDecoder(readVarUint8Array(decoder)); + this.infoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); + this.stringDecoder = new StringDecoder(readVarUint8Array(decoder)); + this.parentInfoDecoder = new RleDecoder(readVarUint8Array(decoder), readUint8); + this.typeRefDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); + this.lenDecoder = new UintOptRleDecoder(readVarUint8Array(decoder)); + } + /** + * @return {ID} + */ + readLeftID() { + return new ID(this.clientDecoder.read(), this.leftClockDecoder.read()); + } + /** + * @return {ID} + */ + readRightID() { + return new ID(this.clientDecoder.read(), this.rightClockDecoder.read()); + } + /** + * Read the next client id. + * Use this in favor of readID whenever possible to reduce the number of objects created. + */ + readClient() { + return this.clientDecoder.read(); + } + /** + * @return {number} info An unsigned 8-bit integer + */ + readInfo() { + return ( + /** @type {number} */ + this.infoDecoder.read() + ); + } + /** + * @return {string} + */ + readString() { + return this.stringDecoder.read(); + } + /** + * @return {boolean} + */ + readParentInfo() { + return this.parentInfoDecoder.read() === 1; + } + /** + * @return {number} An unsigned 8-bit integer + */ + readTypeRef() { + return this.typeRefDecoder.read(); + } + /** + * Write len of a struct - well suited for Opt RLE encoder. + * + * @return {number} + */ + readLen() { + return this.lenDecoder.read(); + } + /** + * @return {any} + */ + readAny() { + return readAny(this.restDecoder); + } + /** + * @return {Uint8Array} + */ + readBuf() { + return readVarUint8Array(this.restDecoder); + } + /** + * This is mainly here for legacy purposes. + * + * Initial we incoded objects using JSON. Now we use the much faster lib0/any-encoder. This method mainly exists for legacy purposes for the v1 encoder. + * + * @return {any} + */ + readJSON() { + return readAny(this.restDecoder); + } + /** + * @return {string} + */ + readKey() { + const keyClock = this.keyClockDecoder.read(); + if (keyClock < this.keys.length) { + return this.keys[keyClock]; + } else { + const key = this.stringDecoder.read(); + this.keys.push(key); + return key; + } + } +}; +var DSEncoderV1 = class { + constructor() { + this.restEncoder = createEncoder(); + } + toUint8Array() { + return toUint8Array(this.restEncoder); + } + resetDsCurVal() { + } + /** + * @param {number} clock + */ + writeDsClock(clock) { + writeVarUint(this.restEncoder, clock); + } + /** + * @param {number} len + */ + writeDsLen(len) { + writeVarUint(this.restEncoder, len); + } +}; +var UpdateEncoderV1 = class extends DSEncoderV1 { + /** + * @param {ID} id + */ + writeLeftID(id2) { + writeVarUint(this.restEncoder, id2.client); + writeVarUint(this.restEncoder, id2.clock); + } + /** + * @param {ID} id + */ + writeRightID(id2) { + writeVarUint(this.restEncoder, id2.client); + writeVarUint(this.restEncoder, id2.clock); + } + /** + * Use writeClient and writeClock instead of writeID if possible. + * @param {number} client + */ + writeClient(client) { + writeVarUint(this.restEncoder, client); + } + /** + * @param {number} info An unsigned 8-bit integer + */ + writeInfo(info) { + writeUint8(this.restEncoder, info); + } + /** + * @param {string} s + */ + writeString(s) { + writeVarString(this.restEncoder, s); + } + /** + * @param {boolean} isYKey + */ + writeParentInfo(isYKey) { + writeVarUint(this.restEncoder, isYKey ? 1 : 0); + } + /** + * @param {number} info An unsigned 8-bit integer + */ + writeTypeRef(info) { + writeVarUint(this.restEncoder, info); + } + /** + * Write len of a struct - well suited for Opt RLE encoder. + * + * @param {number} len + */ + writeLen(len) { + writeVarUint(this.restEncoder, len); + } + /** + * @param {any} any + */ + writeAny(any2) { + writeAny(this.restEncoder, any2); + } + /** + * @param {Uint8Array} buf + */ + writeBuf(buf) { + writeVarUint8Array(this.restEncoder, buf); + } + /** + * @param {any} embed + */ + writeJSON(embed) { + writeVarString(this.restEncoder, JSON.stringify(embed)); + } + /** + * @param {string} key + */ + writeKey(key) { + writeVarString(this.restEncoder, key); + } +}; +var DSEncoderV2 = class { + constructor() { + this.restEncoder = createEncoder(); + this.dsCurrVal = 0; + } + toUint8Array() { + return toUint8Array(this.restEncoder); + } + resetDsCurVal() { + this.dsCurrVal = 0; + } + /** + * @param {number} clock + */ + writeDsClock(clock) { + const diff = clock - this.dsCurrVal; + this.dsCurrVal = clock; + writeVarUint(this.restEncoder, diff); + } + /** + * @param {number} len + */ + writeDsLen(len) { + if (len === 0) { + unexpectedCase(); + } + writeVarUint(this.restEncoder, len - 1); + this.dsCurrVal += len; + } +}; +var UpdateEncoderV2 = class extends DSEncoderV2 { + constructor() { + super(); + this.keyMap = /* @__PURE__ */ new Map(); + this.keyClock = 0; + this.keyClockEncoder = new IntDiffOptRleEncoder(); + this.clientEncoder = new UintOptRleEncoder(); + this.leftClockEncoder = new IntDiffOptRleEncoder(); + this.rightClockEncoder = new IntDiffOptRleEncoder(); + this.infoEncoder = new RleEncoder(writeUint8); + this.stringEncoder = new StringEncoder(); + this.parentInfoEncoder = new RleEncoder(writeUint8); + this.typeRefEncoder = new UintOptRleEncoder(); + this.lenEncoder = new UintOptRleEncoder(); + } + toUint8Array() { + const encoder = createEncoder(); + writeVarUint(encoder, 0); + writeVarUint8Array(encoder, this.keyClockEncoder.toUint8Array()); + writeVarUint8Array(encoder, this.clientEncoder.toUint8Array()); + writeVarUint8Array(encoder, this.leftClockEncoder.toUint8Array()); + writeVarUint8Array(encoder, this.rightClockEncoder.toUint8Array()); + writeVarUint8Array(encoder, toUint8Array(this.infoEncoder)); + writeVarUint8Array(encoder, this.stringEncoder.toUint8Array()); + writeVarUint8Array(encoder, toUint8Array(this.parentInfoEncoder)); + writeVarUint8Array(encoder, this.typeRefEncoder.toUint8Array()); + writeVarUint8Array(encoder, this.lenEncoder.toUint8Array()); + writeUint8Array(encoder, toUint8Array(this.restEncoder)); + return toUint8Array(encoder); + } + /** + * @param {ID} id + */ + writeLeftID(id2) { + this.clientEncoder.write(id2.client); + this.leftClockEncoder.write(id2.clock); + } + /** + * @param {ID} id + */ + writeRightID(id2) { + this.clientEncoder.write(id2.client); + this.rightClockEncoder.write(id2.clock); + } + /** + * @param {number} client + */ + writeClient(client) { + this.clientEncoder.write(client); + } + /** + * @param {number} info An unsigned 8-bit integer + */ + writeInfo(info) { + this.infoEncoder.write(info); + } + /** + * @param {string} s + */ + writeString(s) { + this.stringEncoder.write(s); + } + /** + * @param {boolean} isYKey + */ + writeParentInfo(isYKey) { + this.parentInfoEncoder.write(isYKey ? 1 : 0); + } + /** + * @param {number} info An unsigned 8-bit integer + */ + writeTypeRef(info) { + this.typeRefEncoder.write(info); + } + /** + * Write len of a struct - well suited for Opt RLE encoder. + * + * @param {number} len + */ + writeLen(len) { + this.lenEncoder.write(len); + } + /** + * @param {any} any + */ + writeAny(any2) { + writeAny(this.restEncoder, any2); + } + /** + * @param {Uint8Array} buf + */ + writeBuf(buf) { + writeVarUint8Array(this.restEncoder, buf); + } + /** + * This is mainly here for legacy purposes. + * + * Initial we incoded objects using JSON. Now we use the much faster lib0/any-encoder. This method mainly exists for legacy purposes for the v1 encoder. + * + * @param {any} embed + */ + writeJSON(embed) { + writeAny(this.restEncoder, embed); + } + /** + * Property keys are often reused. For example, in y-prosemirror the key `bold` might + * occur very often. For a 3d application, the key `position` might occur very often. + * + * We cache these keys in a Map and refer to them via a unique number. + * + * @param {string} key + */ + writeKey(key) { + const clock = this.keyMap.get(key); + if (clock === void 0) { + this.keyClockEncoder.write(this.keyClock++); + this.stringEncoder.write(key); + } else { + this.keyClockEncoder.write(clock); + } + } +}; +var writeStructs = (encoder, structs, client, clock) => { + clock = max(clock, structs[0].id.clock); + const startNewStructs = findIndexSS(structs, clock); + writeVarUint(encoder.restEncoder, structs.length - startNewStructs); + encoder.writeClient(client); + writeVarUint(encoder.restEncoder, clock); + const firstStruct = structs[startNewStructs]; + firstStruct.write(encoder, clock - firstStruct.id.clock); + for (let i = startNewStructs + 1; i < structs.length; i++) { + structs[i].write(encoder, 0); + } +}; +var writeClientsStructs = (encoder, store, _sm) => { + const sm = /* @__PURE__ */ new Map(); + _sm.forEach((clock, client) => { + if (getState(store, client) > clock) { + sm.set(client, clock); + } + }); + getStateVector(store).forEach((_clock, client) => { + if (!_sm.has(client)) { + sm.set(client, 0); + } + }); + writeVarUint(encoder.restEncoder, sm.size); + from2(sm.entries()).sort((a, b2) => b2[0] - a[0]).forEach(([client, clock]) => { + writeStructs( + encoder, + /** @type {Array} */ + store.clients.get(client), + client, + clock + ); + }); +}; +var readClientsStructRefs = (decoder, doc4) => { + const clientRefs = create(); + const numOfStateUpdates = readVarUint(decoder.restDecoder); + for (let i = 0; i < numOfStateUpdates; i++) { + const numberOfStructs = readVarUint(decoder.restDecoder); + const refs = new Array(numberOfStructs); + const client = decoder.readClient(); + let clock = readVarUint(decoder.restDecoder); + clientRefs.set(client, { i: 0, refs }); + for (let i2 = 0; i2 < numberOfStructs; i2++) { + const info = decoder.readInfo(); + switch (BITS5 & info) { + case 0: { + const len = decoder.readLen(); + refs[i2] = new GC(createID(client, clock), len); + clock += len; + break; + } + case 10: { + const len = readVarUint(decoder.restDecoder); + refs[i2] = new Skip(createID(client, clock), len); + clock += len; + break; + } + default: { + const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; + const struct = new Item2( + createID(client, clock), + null, + // left + (info & BIT8) === BIT8 ? decoder.readLeftID() : null, + // origin + null, + // right + (info & BIT7) === BIT7 ? decoder.readRightID() : null, + // right origin + cantCopyParentInfo ? decoder.readParentInfo() ? doc4.get(decoder.readString()) : decoder.readLeftID() : null, + // parent + cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, + // parentSub + readItemContent(decoder, info) + // item content + ); + refs[i2] = struct; + clock += struct.length; + } + } + } + } + return clientRefs; +}; +var integrateStructs = (transaction, store, clientsStructRefs) => { + const stack = []; + let clientsStructRefsIds = from2(clientsStructRefs.keys()).sort((a, b2) => a - b2); + if (clientsStructRefsIds.length === 0) { + return null; + } + const getNextStructTarget = () => { + if (clientsStructRefsIds.length === 0) { + return null; + } + let nextStructsTarget = ( + /** @type {{i:number,refs:Array}} */ + clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]) + ); + while (nextStructsTarget.refs.length === nextStructsTarget.i) { + clientsStructRefsIds.pop(); + if (clientsStructRefsIds.length > 0) { + nextStructsTarget = /** @type {{i:number,refs:Array}} */ + clientsStructRefs.get(clientsStructRefsIds[clientsStructRefsIds.length - 1]); + } else { + return null; + } + } + return nextStructsTarget; + }; + let curStructsTarget = getNextStructTarget(); + if (curStructsTarget === null) { + return null; + } + const restStructs = new StructStore(); + const missingSV = /* @__PURE__ */ new Map(); + const updateMissingSv = (client, clock) => { + const mclock = missingSV.get(client); + if (mclock == null || mclock > clock) { + missingSV.set(client, clock); + } + }; + let stackHead = ( + /** @type {any} */ + curStructsTarget.refs[ + /** @type {any} */ + curStructsTarget.i++ + ] + ); + const state = /* @__PURE__ */ new Map(); + const addStackToRestSS = () => { + for (const item of stack) { + const client = item.id.client; + const inapplicableItems = clientsStructRefs.get(client); + if (inapplicableItems) { + inapplicableItems.i--; + restStructs.clients.set(client, inapplicableItems.refs.slice(inapplicableItems.i)); + clientsStructRefs.delete(client); + inapplicableItems.i = 0; + inapplicableItems.refs = []; + } else { + restStructs.clients.set(client, [item]); + } + clientsStructRefsIds = clientsStructRefsIds.filter((c) => c !== client); + } + stack.length = 0; + }; + while (true) { + if (stackHead.constructor !== Skip) { + const localClock = setIfUndefined(state, stackHead.id.client, () => getState(store, stackHead.id.client)); + const offset = localClock - stackHead.id.clock; + if (offset < 0) { + stack.push(stackHead); + updateMissingSv(stackHead.id.client, stackHead.id.clock - 1); + addStackToRestSS(); + } else { + const missing = stackHead.getMissing(transaction, store); + if (missing !== null) { + stack.push(stackHead); + const structRefs = clientsStructRefs.get( + /** @type {number} */ + missing + ) || { refs: [], i: 0 }; + if (structRefs.refs.length === structRefs.i) { + updateMissingSv( + /** @type {number} */ + missing, + getState(store, missing) + ); + addStackToRestSS(); + } else { + stackHead = structRefs.refs[structRefs.i++]; + continue; + } + } else if (offset === 0 || offset < stackHead.length) { + stackHead.integrate(transaction, offset); + state.set(stackHead.id.client, stackHead.id.clock + stackHead.length); + } + } + } + if (stack.length > 0) { + stackHead = /** @type {GC|Item} */ + stack.pop(); + } else if (curStructsTarget !== null && curStructsTarget.i < curStructsTarget.refs.length) { + stackHead = /** @type {GC|Item} */ + curStructsTarget.refs[curStructsTarget.i++]; + } else { + curStructsTarget = getNextStructTarget(); + if (curStructsTarget === null) { + break; + } else { + stackHead = /** @type {GC|Item} */ + curStructsTarget.refs[curStructsTarget.i++]; + } + } + } + if (restStructs.clients.size > 0) { + const encoder = new UpdateEncoderV2(); + writeClientsStructs(encoder, restStructs, /* @__PURE__ */ new Map()); + writeVarUint(encoder.restEncoder, 0); + return { missing: missingSV, update: encoder.toUint8Array() }; + } + return null; +}; +var writeStructsFromTransaction = (encoder, transaction) => writeClientsStructs(encoder, transaction.doc.store, transaction.beforeState); +var readUpdateV2 = (decoder, ydoc, transactionOrigin, structDecoder = new UpdateDecoderV2(decoder)) => transact(ydoc, (transaction) => { + transaction.local = false; + let retry = false; + const doc4 = transaction.doc; + const store = doc4.store; + const ss = readClientsStructRefs(structDecoder, doc4); + const restStructs = integrateStructs(transaction, store, ss); + const pending = store.pendingStructs; + if (pending) { + for (const [client, clock] of pending.missing) { + if (clock < getState(store, client)) { + retry = true; + break; + } + } + if (restStructs) { + for (const [client, clock] of restStructs.missing) { + const mclock = pending.missing.get(client); + if (mclock == null || mclock > clock) { + pending.missing.set(client, clock); + } + } + pending.update = mergeUpdatesV2([pending.update, restStructs.update]); + } + } else { + store.pendingStructs = restStructs; + } + const dsRest = readAndApplyDeleteSet(structDecoder, transaction, store); + if (store.pendingDs) { + const pendingDSUpdate = new UpdateDecoderV2(createDecoder(store.pendingDs)); + readVarUint(pendingDSUpdate.restDecoder); + const dsRest2 = readAndApplyDeleteSet(pendingDSUpdate, transaction, store); + if (dsRest && dsRest2) { + store.pendingDs = mergeUpdatesV2([dsRest, dsRest2]); + } else { + store.pendingDs = dsRest || dsRest2; + } + } else { + store.pendingDs = dsRest; + } + if (retry) { + const update = ( + /** @type {{update: Uint8Array}} */ + store.pendingStructs.update + ); + store.pendingStructs = null; + applyUpdateV2(transaction.doc, update); + } +}, transactionOrigin, false); +var applyUpdateV2 = (ydoc, update, transactionOrigin, YDecoder = UpdateDecoderV2) => { + const decoder = createDecoder(update); + readUpdateV2(decoder, ydoc, transactionOrigin, new YDecoder(decoder)); +}; +var applyUpdate = (ydoc, update, transactionOrigin) => applyUpdateV2(ydoc, update, transactionOrigin, UpdateDecoderV1); +var writeStateAsUpdate = (encoder, doc4, targetStateVector = /* @__PURE__ */ new Map()) => { + writeClientsStructs(encoder, doc4.store, targetStateVector); + writeDeleteSet(encoder, createDeleteSetFromStructStore(doc4.store)); +}; +var encodeStateAsUpdateV2 = (doc4, encodedTargetStateVector = new Uint8Array([0]), encoder = new UpdateEncoderV2()) => { + const targetStateVector = decodeStateVector(encodedTargetStateVector); + writeStateAsUpdate(encoder, doc4, targetStateVector); + const updates = [encoder.toUint8Array()]; + if (doc4.store.pendingDs) { + updates.push(doc4.store.pendingDs); + } + if (doc4.store.pendingStructs) { + updates.push(diffUpdateV2(doc4.store.pendingStructs.update, encodedTargetStateVector)); + } + if (updates.length > 1) { + if (encoder.constructor === UpdateEncoderV1) { + return mergeUpdates(updates.map((update, i) => i === 0 ? update : convertUpdateFormatV2ToV1(update))); + } else if (encoder.constructor === UpdateEncoderV2) { + return mergeUpdatesV2(updates); + } + } + return updates[0]; +}; +var encodeStateAsUpdate = (doc4, encodedTargetStateVector) => encodeStateAsUpdateV2(doc4, encodedTargetStateVector, new UpdateEncoderV1()); +var readStateVector = (decoder) => { + const ss = /* @__PURE__ */ new Map(); + const ssLength = readVarUint(decoder.restDecoder); + for (let i = 0; i < ssLength; i++) { + const client = readVarUint(decoder.restDecoder); + const clock = readVarUint(decoder.restDecoder); + ss.set(client, clock); + } + return ss; +}; +var decodeStateVector = (decodedState) => readStateVector(new DSDecoderV1(createDecoder(decodedState))); +var writeStateVector = (encoder, sv) => { + writeVarUint(encoder.restEncoder, sv.size); + from2(sv.entries()).sort((a, b2) => b2[0] - a[0]).forEach(([client, clock]) => { + writeVarUint(encoder.restEncoder, client); + writeVarUint(encoder.restEncoder, clock); + }); + return encoder; +}; +var writeDocumentStateVector = (encoder, doc4) => writeStateVector(encoder, getStateVector(doc4.store)); +var encodeStateVectorV2 = (doc4, encoder = new DSEncoderV2()) => { + if (doc4 instanceof Map) { + writeStateVector(encoder, doc4); + } else { + writeDocumentStateVector(encoder, doc4); + } + return encoder.toUint8Array(); +}; +var encodeStateVector = (doc4) => encodeStateVectorV2(doc4, new DSEncoderV1()); +var EventHandler = class { + constructor() { + this.l = []; + } +}; +var createEventHandler = () => new EventHandler(); +var addEventHandlerListener = (eventHandler, f) => eventHandler.l.push(f); +var removeEventHandlerListener = (eventHandler, f) => { + const l3 = eventHandler.l; + const len = l3.length; + eventHandler.l = l3.filter((g2) => f !== g2); + if (len === eventHandler.l.length) { + console.error("[yjs] Tried to remove event handler that doesn't exist."); + } +}; +var callEventHandlerListeners = (eventHandler, arg0, arg1) => callAll(eventHandler.l, [arg0, arg1]); +var ID = class { + /** + * @param {number} client client id + * @param {number} clock unique per client id, continuous number + */ + constructor(client, clock) { + this.client = client; + this.clock = clock; + } +}; +var compareIDs = (a, b2) => a === b2 || a !== null && b2 !== null && a.client === b2.client && a.clock === b2.clock; +var createID = (client, clock) => new ID(client, clock); +var findRootTypeKey = (type) => { + for (const [key, value] of type.doc.share.entries()) { + if (value === type) { + return key; + } + } + throw unexpectedCase(); +}; +var isParentOf = (parent, child) => { + while (child !== null) { + if (child.parent === parent) { + return true; + } + child = /** @type {AbstractType} */ + child.parent._item; + } + return false; +}; +var RelativePosition = class { + /** + * @param {ID|null} type + * @param {string|null} tname + * @param {ID|null} item + * @param {number} assoc + */ + constructor(type, tname, item, assoc = 0) { + this.type = type; + this.tname = tname; + this.item = item; + this.assoc = assoc; + } +}; +var AbsolutePosition = class { + /** + * @param {AbstractType} type + * @param {number} index + * @param {number} [assoc] + */ + constructor(type, index, assoc = 0) { + this.type = type; + this.index = index; + this.assoc = assoc; + } +}; +var createAbsolutePosition = (type, index, assoc = 0) => new AbsolutePosition(type, index, assoc); +var createRelativePosition = (type, item, assoc) => { + let typeid = null; + let tname = null; + if (type._item === null) { + tname = findRootTypeKey(type); + } else { + typeid = createID(type._item.id.client, type._item.id.clock); + } + return new RelativePosition(typeid, tname, item, assoc); +}; +var createRelativePositionFromTypeIndex = (type, index, assoc = 0) => { + let t = type._start; + if (assoc < 0) { + if (index === 0) { + return createRelativePosition(type, null, assoc); + } + index--; + } + while (t !== null) { + if (!t.deleted && t.countable) { + if (t.length > index) { + return createRelativePosition(type, createID(t.id.client, t.id.clock + index), assoc); + } + index -= t.length; + } + if (t.right === null && assoc < 0) { + return createRelativePosition(type, t.lastId, assoc); + } + t = t.right; + } + return createRelativePosition(type, null, assoc); +}; +var getItemWithOffset = (store, id2) => { + const item = getItem(store, id2); + const diff = id2.clock - item.id.clock; + return { + item, + diff + }; +}; +var createAbsolutePositionFromRelativePosition = (rpos, doc4, followUndoneDeletions = true) => { + const store = doc4.store; + const rightID = rpos.item; + const typeID = rpos.type; + const tname = rpos.tname; + const assoc = rpos.assoc; + let type = null; + let index = 0; + if (rightID !== null) { + if (getState(store, rightID.client) <= rightID.clock) { + return null; + } + const res = followUndoneDeletions ? followRedone(store, rightID) : getItemWithOffset(store, rightID); + const right = res.item; + if (!(right instanceof Item2)) { + return null; + } + type = /** @type {AbstractType} */ + right.parent; + if (type._item === null || !type._item.deleted) { + index = right.deleted || !right.countable ? 0 : res.diff + (assoc >= 0 ? 0 : 1); + let n = right.left; + while (n !== null) { + if (!n.deleted && n.countable) { + index += n.length; + } + n = n.left; + } + } + } else { + if (tname !== null) { + type = doc4.get(tname); + } else if (typeID !== null) { + if (getState(store, typeID.client) <= typeID.clock) { + return null; + } + const { item } = followUndoneDeletions ? followRedone(store, typeID) : { item: getItem(store, typeID) }; + if (item instanceof Item2 && item.content instanceof ContentType) { + type = item.content.type; + } else { + return null; + } + } else { + throw unexpectedCase(); + } + if (assoc >= 0) { + index = type._length; + } else { + index = 0; + } + } + return createAbsolutePosition(type, index, rpos.assoc); +}; +var Snapshot = class { + /** + * @param {DeleteSet} ds + * @param {Map} sv state map + */ + constructor(ds, sv) { + this.ds = ds; + this.sv = sv; + } +}; +var createSnapshot = (ds, sm) => new Snapshot(ds, sm); +var emptySnapshot = createSnapshot(createDeleteSet(), /* @__PURE__ */ new Map()); +var snapshot = (doc4) => createSnapshot(createDeleteSetFromStructStore(doc4.store), getStateVector(doc4.store)); +var isVisible = (item, snapshot2) => snapshot2 === void 0 ? !item.deleted : snapshot2.sv.has(item.id.client) && (snapshot2.sv.get(item.id.client) || 0) > item.id.clock && !isDeleted(snapshot2.ds, item.id); +var splitSnapshotAffectedStructs = (transaction, snapshot2) => { + const meta = setIfUndefined(transaction.meta, splitSnapshotAffectedStructs, create2); + const store = transaction.doc.store; + if (!meta.has(snapshot2)) { + snapshot2.sv.forEach((clock, client) => { + if (clock < getState(store, client)) { + getItemCleanStart(transaction, createID(client, clock)); + } + }); + iterateDeletedStructs(transaction, snapshot2.ds, (_item) => { + }); + meta.add(snapshot2); + } +}; +var StructStore = class { + constructor() { + this.clients = /* @__PURE__ */ new Map(); + this.pendingStructs = null; + this.pendingDs = null; + } +}; +var getStateVector = (store) => { + const sm = /* @__PURE__ */ new Map(); + store.clients.forEach((structs, client) => { + const struct = structs[structs.length - 1]; + sm.set(client, struct.id.clock + struct.length); + }); + return sm; +}; +var getState = (store, client) => { + const structs = store.clients.get(client); + if (structs === void 0) { + return 0; + } + const lastStruct = structs[structs.length - 1]; + return lastStruct.id.clock + lastStruct.length; +}; +var addStruct = (store, struct) => { + let structs = store.clients.get(struct.id.client); + if (structs === void 0) { + structs = []; + store.clients.set(struct.id.client, structs); + } else { + const lastStruct = structs[structs.length - 1]; + if (lastStruct.id.clock + lastStruct.length !== struct.id.clock) { + throw unexpectedCase(); + } + } + structs.push(struct); +}; +var findIndexSS = (structs, clock) => { + let left = 0; + let right = structs.length - 1; + let mid = structs[right]; + let midclock = mid.id.clock; + if (midclock === clock) { + return right; + } + let midindex = floor(clock / (midclock + mid.length - 1) * right); + while (left <= right) { + mid = structs[midindex]; + midclock = mid.id.clock; + if (midclock <= clock) { + if (clock < midclock + mid.length) { + return midindex; + } + left = midindex + 1; + } else { + right = midindex - 1; + } + midindex = floor((left + right) / 2); + } + throw unexpectedCase(); +}; +var find2 = (store, id2) => { + const structs = store.clients.get(id2.client); + return structs[findIndexSS(structs, id2.clock)]; +}; +var getItem = ( + /** @type {function(StructStore,ID):Item} */ + find2 +); +var findIndexCleanStart = (transaction, structs, clock) => { + const index = findIndexSS(structs, clock); + const struct = structs[index]; + if (struct.id.clock < clock && struct instanceof Item2) { + structs.splice(index + 1, 0, splitItem(transaction, struct, clock - struct.id.clock)); + return index + 1; + } + return index; +}; +var getItemCleanStart = (transaction, id2) => { + const structs = ( + /** @type {Array} */ + transaction.doc.store.clients.get(id2.client) + ); + return structs[findIndexCleanStart(transaction, structs, id2.clock)]; +}; +var getItemCleanEnd = (transaction, store, id2) => { + const structs = store.clients.get(id2.client); + const index = findIndexSS(structs, id2.clock); + const struct = structs[index]; + if (id2.clock !== struct.id.clock + struct.length - 1 && struct.constructor !== GC) { + structs.splice(index + 1, 0, splitItem(transaction, struct, id2.clock - struct.id.clock + 1)); + } + return struct; +}; +var replaceStruct = (store, struct, newStruct) => { + const structs = ( + /** @type {Array} */ + store.clients.get(struct.id.client) + ); + structs[findIndexSS(structs, struct.id.clock)] = newStruct; +}; +var iterateStructs = (transaction, structs, clockStart, len, f) => { + if (len === 0) { + return; + } + const clockEnd = clockStart + len; + let index = findIndexCleanStart(transaction, structs, clockStart); + let struct; + do { + struct = structs[index++]; + if (clockEnd < struct.id.clock + struct.length) { + findIndexCleanStart(transaction, structs, clockEnd); + } + f(struct); + } while (index < structs.length && structs[index].id.clock < clockEnd); +}; +var Transaction2 = class { + /** + * @param {Doc} doc + * @param {any} origin + * @param {boolean} local + */ + constructor(doc4, origin, local) { + this.doc = doc4; + this.deleteSet = new DeleteSet(); + this.beforeState = getStateVector(doc4.store); + this.afterState = /* @__PURE__ */ new Map(); + this.changed = /* @__PURE__ */ new Map(); + this.changedParentTypes = /* @__PURE__ */ new Map(); + this._mergeStructs = []; + this.origin = origin; + this.meta = /* @__PURE__ */ new Map(); + this.local = local; + this.subdocsAdded = /* @__PURE__ */ new Set(); + this.subdocsRemoved = /* @__PURE__ */ new Set(); + this.subdocsLoaded = /* @__PURE__ */ new Set(); + this._needFormattingCleanup = false; + } +}; +var writeUpdateMessageFromTransaction = (encoder, transaction) => { + if (transaction.deleteSet.clients.size === 0 && !any(transaction.afterState, (clock, client) => transaction.beforeState.get(client) !== clock)) { + return false; + } + sortAndMergeDeleteSet(transaction.deleteSet); + writeStructsFromTransaction(encoder, transaction); + writeDeleteSet(encoder, transaction.deleteSet); + return true; +}; +var addChangedTypeToTransaction = (transaction, type, parentSub) => { + const item = type._item; + if (item === null || item.id.clock < (transaction.beforeState.get(item.id.client) || 0) && !item.deleted) { + setIfUndefined(transaction.changed, type, create2).add(parentSub); + } +}; +var tryToMergeWithLefts = (structs, pos) => { + let right = structs[pos]; + let left = structs[pos - 1]; + let i = pos; + for (; i > 0; right = left, left = structs[--i - 1]) { + if (left.deleted === right.deleted && left.constructor === right.constructor) { + if (left.mergeWith(right)) { + if (right instanceof Item2 && right.parentSub !== null && /** @type {AbstractType} */ + right.parent._map.get(right.parentSub) === right) { + right.parent._map.set( + right.parentSub, + /** @type {Item} */ + left + ); + } + continue; + } + } + break; + } + const merged = pos - i; + if (merged) { + structs.splice(pos + 1 - merged, merged); + } + return merged; +}; +var tryGcDeleteSet = (ds, store, gcFilter) => { + for (const [client, deleteItems] of ds.clients.entries()) { + const structs = ( + /** @type {Array} */ + store.clients.get(client) + ); + for (let di = deleteItems.length - 1; di >= 0; di--) { + const deleteItem = deleteItems[di]; + const endDeleteItemClock = deleteItem.clock + deleteItem.len; + for (let si = findIndexSS(structs, deleteItem.clock), struct = structs[si]; si < structs.length && struct.id.clock < endDeleteItemClock; struct = structs[++si]) { + const struct2 = structs[si]; + if (deleteItem.clock + deleteItem.len <= struct2.id.clock) { + break; + } + if (struct2 instanceof Item2 && struct2.deleted && !struct2.keep && gcFilter(struct2)) { + struct2.gc(store, false); + } + } + } + } +}; +var tryMergeDeleteSet = (ds, store) => { + ds.clients.forEach((deleteItems, client) => { + const structs = ( + /** @type {Array} */ + store.clients.get(client) + ); + for (let di = deleteItems.length - 1; di >= 0; di--) { + const deleteItem = deleteItems[di]; + const mostRightIndexToCheck = min(structs.length - 1, 1 + findIndexSS(structs, deleteItem.clock + deleteItem.len - 1)); + for (let si = mostRightIndexToCheck, struct = structs[si]; si > 0 && struct.id.clock >= deleteItem.clock; struct = structs[si]) { + si -= 1 + tryToMergeWithLefts(structs, si); + } + } + }); +}; +var cleanupTransactions = (transactionCleanups, i) => { + if (i < transactionCleanups.length) { + const transaction = transactionCleanups[i]; + const doc4 = transaction.doc; + const store = doc4.store; + const ds = transaction.deleteSet; + const mergeStructs = transaction._mergeStructs; + try { + sortAndMergeDeleteSet(ds); + transaction.afterState = getStateVector(transaction.doc.store); + doc4.emit("beforeObserverCalls", [transaction, doc4]); + const fs = []; + transaction.changed.forEach( + (subs, itemtype) => fs.push(() => { + if (itemtype._item === null || !itemtype._item.deleted) { + itemtype._callObserver(transaction, subs); + } + }) + ); + fs.push(() => { + transaction.changedParentTypes.forEach((events, type) => { + if (type._dEH.l.length > 0 && (type._item === null || !type._item.deleted)) { + events = events.filter( + (event) => event.target._item === null || !event.target._item.deleted + ); + events.forEach((event) => { + event.currentTarget = type; + event._path = null; + }); + events.sort((event1, event2) => event1.path.length - event2.path.length); + fs.push(() => { + callEventHandlerListeners(type._dEH, events, transaction); + }); + } + }); + fs.push(() => doc4.emit("afterTransaction", [transaction, doc4])); + fs.push(() => { + if (transaction._needFormattingCleanup) { + cleanupYTextAfterTransaction(transaction); + } + }); + }); + callAll(fs, []); + } finally { + if (doc4.gc) { + tryGcDeleteSet(ds, store, doc4.gcFilter); + } + tryMergeDeleteSet(ds, store); + transaction.afterState.forEach((clock, client) => { + const beforeClock = transaction.beforeState.get(client) || 0; + if (beforeClock !== clock) { + const structs = ( + /** @type {Array} */ + store.clients.get(client) + ); + const firstChangePos = max(findIndexSS(structs, beforeClock), 1); + for (let i2 = structs.length - 1; i2 >= firstChangePos; ) { + i2 -= 1 + tryToMergeWithLefts(structs, i2); + } + } + }); + for (let i2 = mergeStructs.length - 1; i2 >= 0; i2--) { + const { client, clock } = mergeStructs[i2].id; + const structs = ( + /** @type {Array} */ + store.clients.get(client) + ); + const replacedStructPos = findIndexSS(structs, clock); + if (replacedStructPos + 1 < structs.length) { + if (tryToMergeWithLefts(structs, replacedStructPos + 1) > 1) { + continue; + } + } + if (replacedStructPos > 0) { + tryToMergeWithLefts(structs, replacedStructPos); + } + } + if (!transaction.local && transaction.afterState.get(doc4.clientID) !== transaction.beforeState.get(doc4.clientID)) { + print(ORANGE, BOLD, "[yjs] ", UNBOLD, RED, "Changed the client-id because another client seems to be using it."); + doc4.clientID = generateNewClientId(); + } + doc4.emit("afterTransactionCleanup", [transaction, doc4]); + if (doc4._observers.has("update")) { + const encoder = new UpdateEncoderV1(); + const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); + if (hasContent2) { + doc4.emit("update", [encoder.toUint8Array(), transaction.origin, doc4, transaction]); + } + } + if (doc4._observers.has("updateV2")) { + const encoder = new UpdateEncoderV2(); + const hasContent2 = writeUpdateMessageFromTransaction(encoder, transaction); + if (hasContent2) { + doc4.emit("updateV2", [encoder.toUint8Array(), transaction.origin, doc4, transaction]); + } + } + const { subdocsAdded, subdocsLoaded, subdocsRemoved } = transaction; + if (subdocsAdded.size > 0 || subdocsRemoved.size > 0 || subdocsLoaded.size > 0) { + subdocsAdded.forEach((subdoc) => { + subdoc.clientID = doc4.clientID; + if (subdoc.collectionid == null) { + subdoc.collectionid = doc4.collectionid; + } + doc4.subdocs.add(subdoc); + }); + subdocsRemoved.forEach((subdoc) => doc4.subdocs.delete(subdoc)); + doc4.emit("subdocs", [{ loaded: subdocsLoaded, added: subdocsAdded, removed: subdocsRemoved }, doc4, transaction]); + subdocsRemoved.forEach((subdoc) => subdoc.destroy()); + } + if (transactionCleanups.length <= i + 1) { + doc4._transactionCleanups = []; + doc4.emit("afterAllTransactions", [doc4, transactionCleanups]); + } else { + cleanupTransactions(transactionCleanups, i + 1); + } + } + } +}; +var transact = (doc4, f, origin = null, local = true) => { + const transactionCleanups = doc4._transactionCleanups; + let initialCall = false; + let result = null; + if (doc4._transaction === null) { + initialCall = true; + doc4._transaction = new Transaction2(doc4, origin, local); + transactionCleanups.push(doc4._transaction); + if (transactionCleanups.length === 1) { + doc4.emit("beforeAllTransactions", [doc4]); + } + doc4.emit("beforeTransaction", [doc4._transaction, doc4]); + } + try { + result = f(doc4._transaction); + } finally { + if (initialCall) { + const finishCleanup = doc4._transaction === transactionCleanups[0]; + doc4._transaction = null; + if (finishCleanup) { + cleanupTransactions(transactionCleanups, 0); + } + } + } + return result; +}; +var StackItem = class { + /** + * @param {DeleteSet} deletions + * @param {DeleteSet} insertions + */ + constructor(deletions, insertions) { + this.insertions = insertions; + this.deletions = deletions; + this.meta = /* @__PURE__ */ new Map(); + } +}; +var clearUndoManagerStackItem = (tr2, um, stackItem) => { + iterateDeletedStructs(tr2, stackItem.deletions, (item) => { + if (item instanceof Item2 && um.scope.some((type) => type === tr2.doc || isParentOf( + /** @type {AbstractType} */ + type, + item + ))) { + keepItem(item, false); + } + }); +}; +var popStackItem = (undoManager, stack, eventType) => { + let _tr = null; + const doc4 = undoManager.doc; + const scope = undoManager.scope; + transact(doc4, (transaction) => { + while (stack.length > 0 && undoManager.currStackItem === null) { + const store = doc4.store; + const stackItem = ( + /** @type {StackItem} */ + stack.pop() + ); + const itemsToRedo = /* @__PURE__ */ new Set(); + const itemsToDelete = []; + let performedChange = false; + iterateDeletedStructs(transaction, stackItem.insertions, (struct) => { + if (struct instanceof Item2) { + if (struct.redone !== null) { + let { item, diff } = followRedone(store, struct.id); + if (diff > 0) { + item = getItemCleanStart(transaction, createID(item.id.client, item.id.clock + diff)); + } + struct = item; + } + if (!struct.deleted && scope.some((type) => type === transaction.doc || isParentOf( + /** @type {AbstractType} */ + type, + /** @type {Item} */ + struct + ))) { + itemsToDelete.push(struct); + } + } + }); + iterateDeletedStructs(transaction, stackItem.deletions, (struct) => { + if (struct instanceof Item2 && scope.some((type) => type === transaction.doc || isParentOf( + /** @type {AbstractType} */ + type, + struct + )) && // Never redo structs in stackItem.insertions because they were created and deleted in the same capture interval. + !isDeleted(stackItem.insertions, struct.id)) { + itemsToRedo.add(struct); + } + }); + itemsToRedo.forEach((struct) => { + performedChange = redoItem(transaction, struct, itemsToRedo, stackItem.insertions, undoManager.ignoreRemoteMapChanges, undoManager) !== null || performedChange; + }); + for (let i = itemsToDelete.length - 1; i >= 0; i--) { + const item = itemsToDelete[i]; + if (undoManager.deleteFilter(item)) { + item.delete(transaction); + performedChange = true; + } + } + undoManager.currStackItem = performedChange ? stackItem : null; + } + transaction.changed.forEach((subProps, type) => { + if (subProps.has(null) && type._searchMarker) { + type._searchMarker.length = 0; + } + }); + _tr = transaction; + }, undoManager); + const res = undoManager.currStackItem; + if (res != null) { + const changedParentTypes = _tr.changedParentTypes; + undoManager.emit("stack-item-popped", [{ stackItem: res, type: eventType, changedParentTypes, origin: undoManager }, undoManager]); + undoManager.currStackItem = null; + } + return res; +}; +var UndoManager = class extends ObservableV2 { + /** + * @param {Doc|AbstractType|Array>} typeScope Limits the scope of the UndoManager. If this is set to a ydoc instance, all changes on that ydoc will be undone. If set to a specific type, only changes on that type or its children will be undone. Also accepts an array of types. + * @param {UndoManagerOptions} options + */ + constructor(typeScope, { + captureTimeout = 500, + captureTransaction = (_tr) => true, + deleteFilter = () => true, + trackedOrigins = /* @__PURE__ */ new Set([null]), + ignoreRemoteMapChanges = false, + doc: doc4 = ( + /** @type {Doc} */ + isArray(typeScope) ? typeScope[0].doc : typeScope instanceof Doc ? typeScope : typeScope.doc + ) + } = {}) { + super(); + this.scope = []; + this.doc = doc4; + this.addToScope(typeScope); + this.deleteFilter = deleteFilter; + trackedOrigins.add(this); + this.trackedOrigins = trackedOrigins; + this.captureTransaction = captureTransaction; + this.undoStack = []; + this.redoStack = []; + this.undoing = false; + this.redoing = false; + this.currStackItem = null; + this.lastChange = 0; + this.ignoreRemoteMapChanges = ignoreRemoteMapChanges; + this.captureTimeout = captureTimeout; + this.afterTransactionHandler = (transaction) => { + if (!this.captureTransaction(transaction) || !this.scope.some((type) => transaction.changedParentTypes.has( + /** @type {AbstractType} */ + type + ) || type === this.doc) || !this.trackedOrigins.has(transaction.origin) && (!transaction.origin || !this.trackedOrigins.has(transaction.origin.constructor))) { + return; + } + const undoing = this.undoing; + const redoing = this.redoing; + const stack = undoing ? this.redoStack : this.undoStack; + if (undoing) { + this.stopCapturing(); + } else if (!redoing) { + this.clear(false, true); + } + const insertions = new DeleteSet(); + transaction.afterState.forEach((endClock, client) => { + const startClock = transaction.beforeState.get(client) || 0; + const len = endClock - startClock; + if (len > 0) { + addToDeleteSet(insertions, client, startClock, len); + } + }); + const now = getUnixTime(); + let didAdd = false; + if (this.lastChange > 0 && now - this.lastChange < this.captureTimeout && stack.length > 0 && !undoing && !redoing) { + const lastOp = stack[stack.length - 1]; + lastOp.deletions = mergeDeleteSets([lastOp.deletions, transaction.deleteSet]); + lastOp.insertions = mergeDeleteSets([lastOp.insertions, insertions]); + } else { + stack.push(new StackItem(transaction.deleteSet, insertions)); + didAdd = true; + } + if (!undoing && !redoing) { + this.lastChange = now; + } + iterateDeletedStructs( + transaction, + transaction.deleteSet, + /** @param {Item|GC} item */ + (item) => { + if (item instanceof Item2 && this.scope.some((type) => type === transaction.doc || isParentOf( + /** @type {AbstractType} */ + type, + item + ))) { + keepItem(item, true); + } + } + ); + const changeEvent = [{ stackItem: stack[stack.length - 1], origin: transaction.origin, type: undoing ? "redo" : "undo", changedParentTypes: transaction.changedParentTypes }, this]; + if (didAdd) { + this.emit("stack-item-added", changeEvent); + } else { + this.emit("stack-item-updated", changeEvent); + } + }; + this.doc.on("afterTransaction", this.afterTransactionHandler); + this.doc.on("destroy", () => { + this.destroy(); + }); + } + /** + * Extend the scope. + * + * @param {Array | Doc> | AbstractType | Doc} ytypes + */ + addToScope(ytypes) { + const tmpSet = new Set(this.scope); + ytypes = isArray(ytypes) ? ytypes : [ytypes]; + ytypes.forEach((ytype) => { + if (!tmpSet.has(ytype)) { + tmpSet.add(ytype); + if (ytype instanceof AbstractType ? ytype.doc !== this.doc : ytype !== this.doc) warn2("[yjs#509] Not same Y.Doc"); + this.scope.push(ytype); + } + }); + } + /** + * @param {any} origin + */ + addTrackedOrigin(origin) { + this.trackedOrigins.add(origin); + } + /** + * @param {any} origin + */ + removeTrackedOrigin(origin) { + this.trackedOrigins.delete(origin); + } + clear(clearUndoStack = true, clearRedoStack = true) { + if (clearUndoStack && this.canUndo() || clearRedoStack && this.canRedo()) { + this.doc.transact((tr2) => { + if (clearUndoStack) { + this.undoStack.forEach((item) => clearUndoManagerStackItem(tr2, this, item)); + this.undoStack = []; + } + if (clearRedoStack) { + this.redoStack.forEach((item) => clearUndoManagerStackItem(tr2, this, item)); + this.redoStack = []; + } + this.emit("stack-cleared", [{ undoStackCleared: clearUndoStack, redoStackCleared: clearRedoStack }]); + }); + } + } + /** + * UndoManager merges Undo-StackItem if they are created within time-gap + * smaller than `options.captureTimeout`. Call `um.stopCapturing()` so that the next + * StackItem won't be merged. + * + * + * @example + * // without stopCapturing + * ytext.insert(0, 'a') + * ytext.insert(1, 'b') + * um.undo() + * ytext.toString() // => '' (note that 'ab' was removed) + * // with stopCapturing + * ytext.insert(0, 'a') + * um.stopCapturing() + * ytext.insert(0, 'b') + * um.undo() + * ytext.toString() // => 'a' (note that only 'b' was removed) + * + */ + stopCapturing() { + this.lastChange = 0; + } + /** + * Undo last changes on type. + * + * @return {StackItem?} Returns StackItem if a change was applied + */ + undo() { + this.undoing = true; + let res; + try { + res = popStackItem(this, this.undoStack, "undo"); + } finally { + this.undoing = false; + } + return res; + } + /** + * Redo last undo operation. + * + * @return {StackItem?} Returns StackItem if a change was applied + */ + redo() { + this.redoing = true; + let res; + try { + res = popStackItem(this, this.redoStack, "redo"); + } finally { + this.redoing = false; + } + return res; + } + /** + * Are undo steps available? + * + * @return {boolean} `true` if undo is possible + */ + canUndo() { + return this.undoStack.length > 0; + } + /** + * Are redo steps available? + * + * @return {boolean} `true` if redo is possible + */ + canRedo() { + return this.redoStack.length > 0; + } + destroy() { + this.trackedOrigins.delete(this); + this.doc.off("afterTransaction", this.afterTransactionHandler); + super.destroy(); + } +}; +function* lazyStructReaderGenerator(decoder) { + const numOfStateUpdates = readVarUint(decoder.restDecoder); + for (let i = 0; i < numOfStateUpdates; i++) { + const numberOfStructs = readVarUint(decoder.restDecoder); + const client = decoder.readClient(); + let clock = readVarUint(decoder.restDecoder); + for (let i2 = 0; i2 < numberOfStructs; i2++) { + const info = decoder.readInfo(); + if (info === 10) { + const len = readVarUint(decoder.restDecoder); + yield new Skip(createID(client, clock), len); + clock += len; + } else if ((BITS5 & info) !== 0) { + const cantCopyParentInfo = (info & (BIT7 | BIT8)) === 0; + const struct = new Item2( + createID(client, clock), + null, + // left + (info & BIT8) === BIT8 ? decoder.readLeftID() : null, + // origin + null, + // right + (info & BIT7) === BIT7 ? decoder.readRightID() : null, + // right origin + // @ts-ignore Force writing a string here. + cantCopyParentInfo ? decoder.readParentInfo() ? decoder.readString() : decoder.readLeftID() : null, + // parent + cantCopyParentInfo && (info & BIT6) === BIT6 ? decoder.readString() : null, + // parentSub + readItemContent(decoder, info) + // item content + ); + yield struct; + clock += struct.length; + } else { + const len = decoder.readLen(); + yield new GC(createID(client, clock), len); + clock += len; + } + } + } +} +var LazyStructReader = class { + /** + * @param {UpdateDecoderV1 | UpdateDecoderV2} decoder + * @param {boolean} filterSkips + */ + constructor(decoder, filterSkips) { + this.gen = lazyStructReaderGenerator(decoder); + this.curr = null; + this.done = false; + this.filterSkips = filterSkips; + this.next(); + } + /** + * @return {Item | GC | Skip |null} + */ + next() { + do { + this.curr = this.gen.next().value || null; + } while (this.filterSkips && this.curr !== null && this.curr.constructor === Skip); + return this.curr; + } +}; +var LazyStructWriter = class { + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + */ + constructor(encoder) { + this.currClient = 0; + this.startClock = 0; + this.written = 0; + this.encoder = encoder; + this.clientStructs = []; + } +}; +var mergeUpdates = (updates) => mergeUpdatesV2(updates, UpdateDecoderV1, UpdateEncoderV1); +var sliceStruct = (left, diff) => { + if (left.constructor === GC) { + const { client, clock } = left.id; + return new GC(createID(client, clock + diff), left.length - diff); + } else if (left.constructor === Skip) { + const { client, clock } = left.id; + return new Skip(createID(client, clock + diff), left.length - diff); + } else { + const leftItem = ( + /** @type {Item} */ + left + ); + const { client, clock } = leftItem.id; + return new Item2( + createID(client, clock + diff), + null, + createID(client, clock + diff - 1), + null, + leftItem.rightOrigin, + leftItem.parent, + leftItem.parentSub, + leftItem.content.splice(diff) + ); + } +}; +var mergeUpdatesV2 = (updates, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { + if (updates.length === 1) { + return updates[0]; + } + const updateDecoders = updates.map((update) => new YDecoder(createDecoder(update))); + let lazyStructDecoders = updateDecoders.map((decoder) => new LazyStructReader(decoder, true)); + let currWrite = null; + const updateEncoder = new YEncoder(); + const lazyStructEncoder = new LazyStructWriter(updateEncoder); + while (true) { + lazyStructDecoders = lazyStructDecoders.filter((dec) => dec.curr !== null); + lazyStructDecoders.sort( + /** @type {function(any,any):number} */ + (dec1, dec2) => { + if (dec1.curr.id.client === dec2.curr.id.client) { + const clockDiff = dec1.curr.id.clock - dec2.curr.id.clock; + if (clockDiff === 0) { + return dec1.curr.constructor === dec2.curr.constructor ? 0 : dec1.curr.constructor === Skip ? 1 : -1; + } else { + return clockDiff; + } + } else { + return dec2.curr.id.client - dec1.curr.id.client; + } + } + ); + if (lazyStructDecoders.length === 0) { + break; + } + const currDecoder = lazyStructDecoders[0]; + const firstClient = ( + /** @type {Item | GC} */ + currDecoder.curr.id.client + ); + if (currWrite !== null) { + let curr = ( + /** @type {Item | GC | null} */ + currDecoder.curr + ); + let iterated = false; + while (curr !== null && curr.id.clock + curr.length <= currWrite.struct.id.clock + currWrite.struct.length && curr.id.client >= currWrite.struct.id.client) { + curr = currDecoder.next(); + iterated = true; + } + if (curr === null || // current decoder is empty + curr.id.client !== firstClient || // check whether there is another decoder that has has updates from `firstClient` + iterated && curr.id.clock > currWrite.struct.id.clock + currWrite.struct.length) { + continue; + } + if (firstClient !== currWrite.struct.id.client) { + writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); + currWrite = { struct: curr, offset: 0 }; + currDecoder.next(); + } else { + if (currWrite.struct.id.clock + currWrite.struct.length < curr.id.clock) { + if (currWrite.struct.constructor === Skip) { + currWrite.struct.length = curr.id.clock + curr.length - currWrite.struct.id.clock; + } else { + writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); + const diff = curr.id.clock - currWrite.struct.id.clock - currWrite.struct.length; + const struct = new Skip(createID(firstClient, currWrite.struct.id.clock + currWrite.struct.length), diff); + currWrite = { struct, offset: 0 }; + } + } else { + const diff = currWrite.struct.id.clock + currWrite.struct.length - curr.id.clock; + if (diff > 0) { + if (currWrite.struct.constructor === Skip) { + currWrite.struct.length -= diff; + } else { + curr = sliceStruct(curr, diff); + } + } + if (!currWrite.struct.mergeWith( + /** @type {any} */ + curr + )) { + writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); + currWrite = { struct: curr, offset: 0 }; + currDecoder.next(); + } + } + } + } else { + currWrite = { struct: ( + /** @type {Item | GC} */ + currDecoder.curr + ), offset: 0 }; + currDecoder.next(); + } + for (let next2 = currDecoder.curr; next2 !== null && next2.id.client === firstClient && next2.id.clock === currWrite.struct.id.clock + currWrite.struct.length && next2.constructor !== Skip; next2 = currDecoder.next()) { + writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); + currWrite = { struct: next2, offset: 0 }; + } + } + if (currWrite !== null) { + writeStructToLazyStructWriter(lazyStructEncoder, currWrite.struct, currWrite.offset); + currWrite = null; + } + finishLazyStructWriting(lazyStructEncoder); + const dss = updateDecoders.map((decoder) => readDeleteSet(decoder)); + const ds = mergeDeleteSets(dss); + writeDeleteSet(updateEncoder, ds); + return updateEncoder.toUint8Array(); +}; +var diffUpdateV2 = (update, sv, YDecoder = UpdateDecoderV2, YEncoder = UpdateEncoderV2) => { + const state = decodeStateVector(sv); + const encoder = new YEncoder(); + const lazyStructWriter = new LazyStructWriter(encoder); + const decoder = new YDecoder(createDecoder(update)); + const reader = new LazyStructReader(decoder, false); + while (reader.curr) { + const curr = reader.curr; + const currClient = curr.id.client; + const svClock = state.get(currClient) || 0; + if (reader.curr.constructor === Skip) { + reader.next(); + continue; + } + if (curr.id.clock + curr.length > svClock) { + writeStructToLazyStructWriter(lazyStructWriter, curr, max(svClock - curr.id.clock, 0)); + reader.next(); + while (reader.curr && reader.curr.id.client === currClient) { + writeStructToLazyStructWriter(lazyStructWriter, reader.curr, 0); + reader.next(); + } + } else { + while (reader.curr && reader.curr.id.client === currClient && reader.curr.id.clock + reader.curr.length <= svClock) { + reader.next(); + } + } + } + finishLazyStructWriting(lazyStructWriter); + const ds = readDeleteSet(decoder); + writeDeleteSet(encoder, ds); + return encoder.toUint8Array(); +}; +var flushLazyStructWriter = (lazyWriter) => { + if (lazyWriter.written > 0) { + lazyWriter.clientStructs.push({ written: lazyWriter.written, restEncoder: toUint8Array(lazyWriter.encoder.restEncoder) }); + lazyWriter.encoder.restEncoder = createEncoder(); + lazyWriter.written = 0; + } +}; +var writeStructToLazyStructWriter = (lazyWriter, struct, offset) => { + if (lazyWriter.written > 0 && lazyWriter.currClient !== struct.id.client) { + flushLazyStructWriter(lazyWriter); + } + if (lazyWriter.written === 0) { + lazyWriter.currClient = struct.id.client; + lazyWriter.encoder.writeClient(struct.id.client); + writeVarUint(lazyWriter.encoder.restEncoder, struct.id.clock + offset); + } + struct.write(lazyWriter.encoder, offset); + lazyWriter.written++; +}; +var finishLazyStructWriting = (lazyWriter) => { + flushLazyStructWriter(lazyWriter); + const restEncoder = lazyWriter.encoder.restEncoder; + writeVarUint(restEncoder, lazyWriter.clientStructs.length); + for (let i = 0; i < lazyWriter.clientStructs.length; i++) { + const partStructs = lazyWriter.clientStructs[i]; + writeVarUint(restEncoder, partStructs.written); + writeUint8Array(restEncoder, partStructs.restEncoder); + } +}; +var convertUpdateFormat = (update, blockTransformer, YDecoder, YEncoder) => { + const updateDecoder = new YDecoder(createDecoder(update)); + const lazyDecoder = new LazyStructReader(updateDecoder, false); + const updateEncoder = new YEncoder(); + const lazyWriter = new LazyStructWriter(updateEncoder); + for (let curr = lazyDecoder.curr; curr !== null; curr = lazyDecoder.next()) { + writeStructToLazyStructWriter(lazyWriter, blockTransformer(curr), 0); + } + finishLazyStructWriting(lazyWriter); + const ds = readDeleteSet(updateDecoder); + writeDeleteSet(updateEncoder, ds); + return updateEncoder.toUint8Array(); +}; +var convertUpdateFormatV2ToV1 = (update) => convertUpdateFormat(update, id, UpdateDecoderV2, UpdateEncoderV1); +var errorComputeChanges = "You must not compute changes after the event-handler fired."; +var YEvent = class { + /** + * @param {T} target The changed type. + * @param {Transaction} transaction + */ + constructor(target, transaction) { + this.target = target; + this.currentTarget = target; + this.transaction = transaction; + this._changes = null; + this._keys = null; + this._delta = null; + this._path = null; + } + /** + * Computes the path from `y` to the changed type. + * + * @todo v14 should standardize on path: Array<{parent, index}> because that is easier to work with. + * + * The following property holds: + * @example + * let type = y + * event.path.forEach(dir => { + * type = type.get(dir) + * }) + * type === event.target // => true + */ + get path() { + return this._path || (this._path = getPathTo(this.currentTarget, this.target)); + } + /** + * Check if a struct is deleted by this event. + * + * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. + * + * @param {AbstractStruct} struct + * @return {boolean} + */ + deletes(struct) { + return isDeleted(this.transaction.deleteSet, struct.id); + } + /** + * @type {Map} + */ + get keys() { + if (this._keys === null) { + if (this.transaction.doc._transactionCleanups.length === 0) { + throw create3(errorComputeChanges); + } + const keys3 = /* @__PURE__ */ new Map(); + const target = this.target; + const changed = ( + /** @type Set */ + this.transaction.changed.get(target) + ); + changed.forEach((key) => { + if (key !== null) { + const item = ( + /** @type {Item} */ + target._map.get(key) + ); + let action; + let oldValue; + if (this.adds(item)) { + let prev = item.left; + while (prev !== null && this.adds(prev)) { + prev = prev.left; + } + if (this.deletes(item)) { + if (prev !== null && this.deletes(prev)) { + action = "delete"; + oldValue = last(prev.content.getContent()); + } else { + return; + } + } else { + if (prev !== null && this.deletes(prev)) { + action = "update"; + oldValue = last(prev.content.getContent()); + } else { + action = "add"; + oldValue = void 0; + } + } + } else { + if (this.deletes(item)) { + action = "delete"; + oldValue = last( + /** @type {Item} */ + item.content.getContent() + ); + } else { + return; + } + } + keys3.set(key, { action, oldValue }); + } + }); + this._keys = keys3; + } + return this._keys; + } + /** + * This is a computed property. Note that this can only be safely computed during the + * event call. Computing this property after other changes happened might result in + * unexpected behavior (incorrect computation of deltas). A safe way to collect changes + * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. + * + * @type {Array<{insert?: string | Array | object | AbstractType, retain?: number, delete?: number, attributes?: Object}>} + */ + get delta() { + return this.changes.delta; + } + /** + * Check if a struct is added by this event. + * + * In contrast to change.deleted, this method also returns true if the struct was added and then deleted. + * + * @param {AbstractStruct} struct + * @return {boolean} + */ + adds(struct) { + return struct.id.clock >= (this.transaction.beforeState.get(struct.id.client) || 0); + } + /** + * This is a computed property. Note that this can only be safely computed during the + * event call. Computing this property after other changes happened might result in + * unexpected behavior (incorrect computation of deltas). A safe way to collect changes + * is to store the `changes` or the `delta` object. Avoid storing the `transaction` object. + * + * @type {{added:Set,deleted:Set,keys:Map,delta:Array<{insert?:Array|string, delete?:number, retain?:number}>}} + */ + get changes() { + let changes = this._changes; + if (changes === null) { + if (this.transaction.doc._transactionCleanups.length === 0) { + throw create3(errorComputeChanges); + } + const target = this.target; + const added = create2(); + const deleted = create2(); + const delta = []; + changes = { + added, + deleted, + delta, + keys: this.keys + }; + const changed = ( + /** @type Set */ + this.transaction.changed.get(target) + ); + if (changed.has(null)) { + let lastOp = null; + const packOp = () => { + if (lastOp) { + delta.push(lastOp); + } + }; + for (let item = target._start; item !== null; item = item.right) { + if (item.deleted) { + if (this.deletes(item) && !this.adds(item)) { + if (lastOp === null || lastOp.delete === void 0) { + packOp(); + lastOp = { delete: 0 }; + } + lastOp.delete += item.length; + deleted.add(item); + } + } else { + if (this.adds(item)) { + if (lastOp === null || lastOp.insert === void 0) { + packOp(); + lastOp = { insert: [] }; + } + lastOp.insert = lastOp.insert.concat(item.content.getContent()); + added.add(item); + } else { + if (lastOp === null || lastOp.retain === void 0) { + packOp(); + lastOp = { retain: 0 }; + } + lastOp.retain += item.length; + } + } + } + if (lastOp !== null && lastOp.retain === void 0) { + packOp(); + } + } + this._changes = changes; + } + return ( + /** @type {any} */ + changes + ); + } +}; +var getPathTo = (parent, child) => { + const path = []; + while (child._item !== null && child !== parent) { + if (child._item.parentSub !== null) { + path.unshift(child._item.parentSub); + } else { + let i = 0; + let c = ( + /** @type {AbstractType} */ + child._item.parent._start + ); + while (c !== child._item && c !== null) { + if (!c.deleted && c.countable) { + i += c.length; + } + c = c.right; + } + path.unshift(i); + } + child = /** @type {AbstractType} */ + child._item.parent; + } + return path; +}; +var warnPrematureAccess = () => { + warn2("Invalid access: Add Yjs type to a document before reading data."); +}; +var maxSearchMarker = 80; +var globalSearchMarkerTimestamp = 0; +var ArraySearchMarker = class { + /** + * @param {Item} p + * @param {number} index + */ + constructor(p, index) { + p.marker = true; + this.p = p; + this.index = index; + this.timestamp = globalSearchMarkerTimestamp++; + } +}; +var refreshMarkerTimestamp = (marker) => { + marker.timestamp = globalSearchMarkerTimestamp++; +}; +var overwriteMarker = (marker, p, index) => { + marker.p.marker = false; + marker.p = p; + p.marker = true; + marker.index = index; + marker.timestamp = globalSearchMarkerTimestamp++; +}; +var markPosition = (searchMarker, p, index) => { + if (searchMarker.length >= maxSearchMarker) { + const marker = searchMarker.reduce((a, b2) => a.timestamp < b2.timestamp ? a : b2); + overwriteMarker(marker, p, index); + return marker; + } else { + const pm = new ArraySearchMarker(p, index); + searchMarker.push(pm); + return pm; + } +}; +var findMarker = (yarray, index) => { + if (yarray._start === null || index === 0 || yarray._searchMarker === null) { + return null; + } + const marker = yarray._searchMarker.length === 0 ? null : yarray._searchMarker.reduce((a, b2) => abs(index - a.index) < abs(index - b2.index) ? a : b2); + let p = yarray._start; + let pindex = 0; + if (marker !== null) { + p = marker.p; + pindex = marker.index; + refreshMarkerTimestamp(marker); + } + while (p.right !== null && pindex < index) { + if (!p.deleted && p.countable) { + if (index < pindex + p.length) { + break; + } + pindex += p.length; + } + p = p.right; + } + while (p.left !== null && pindex > index) { + p = p.left; + if (!p.deleted && p.countable) { + pindex -= p.length; + } + } + while (p.left !== null && p.left.id.client === p.id.client && p.left.id.clock + p.left.length === p.id.clock) { + p = p.left; + if (!p.deleted && p.countable) { + pindex -= p.length; + } + } + if (marker !== null && abs(marker.index - pindex) < /** @type {YText|YArray} */ + p.parent.length / maxSearchMarker) { + overwriteMarker(marker, p, pindex); + return marker; + } else { + return markPosition(yarray._searchMarker, p, pindex); + } +}; +var updateMarkerChanges = (searchMarker, index, len) => { + for (let i = searchMarker.length - 1; i >= 0; i--) { + const m2 = searchMarker[i]; + if (len > 0) { + let p = m2.p; + p.marker = false; + while (p && (p.deleted || !p.countable)) { + p = p.left; + if (p && !p.deleted && p.countable) { + m2.index -= p.length; + } + } + if (p === null || p.marker === true) { + searchMarker.splice(i, 1); + continue; + } + m2.p = p; + p.marker = true; + } + if (index < m2.index || len > 0 && index === m2.index) { + m2.index = max(index, m2.index + len); + } + } +}; +var callTypeObservers = (type, transaction, event) => { + const changedType = type; + const changedParentTypes = transaction.changedParentTypes; + while (true) { + setIfUndefined(changedParentTypes, type, () => []).push(event); + if (type._item === null) { + break; + } + type = /** @type {AbstractType} */ + type._item.parent; + } + callEventHandlerListeners(changedType._eH, event, transaction); +}; +var AbstractType = class { + constructor() { + this._item = null; + this._map = /* @__PURE__ */ new Map(); + this._start = null; + this.doc = null; + this._length = 0; + this._eH = createEventHandler(); + this._dEH = createEventHandler(); + this._searchMarker = null; + } + /** + * @return {AbstractType|null} + */ + get parent() { + return this._item ? ( + /** @type {AbstractType} */ + this._item.parent + ) : null; + } + /** + * Integrate this type into the Yjs instance. + * + * * Save this struct in the os + * * This type is sent to other client + * * Observer functions are fired + * + * @param {Doc} y The Yjs instance + * @param {Item|null} item + */ + _integrate(y2, item) { + this.doc = y2; + this._item = item; + } + /** + * @return {AbstractType} + */ + _copy() { + throw methodUnimplemented(); + } + /** + * Makes a copy of this data type that can be included somewhere else. + * + * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. + * + * @return {AbstractType} + */ + clone() { + throw methodUnimplemented(); + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} _encoder + */ + _write(_encoder) { + } + /** + * The first non-deleted item + */ + get _first() { + let n = this._start; + while (n !== null && n.deleted) { + n = n.right; + } + return n; + } + /** + * Creates YEvent and calls all type observers. + * Must be implemented by each type. + * + * @param {Transaction} transaction + * @param {Set} _parentSubs Keys changed on this type. `null` if list was modified. + */ + _callObserver(transaction, _parentSubs) { + if (!transaction.local && this._searchMarker) { + this._searchMarker.length = 0; + } + } + /** + * Observe all events that are created on this type. + * + * @param {function(EventType, Transaction):void} f Observer function + */ + observe(f) { + addEventHandlerListener(this._eH, f); + } + /** + * Observe all events that are created by this type and its children. + * + * @param {function(Array>,Transaction):void} f Observer function + */ + observeDeep(f) { + addEventHandlerListener(this._dEH, f); + } + /** + * Unregister an observer function. + * + * @param {function(EventType,Transaction):void} f Observer function + */ + unobserve(f) { + removeEventHandlerListener(this._eH, f); + } + /** + * Unregister an observer function. + * + * @param {function(Array>,Transaction):void} f Observer function + */ + unobserveDeep(f) { + removeEventHandlerListener(this._dEH, f); + } + /** + * @abstract + * @return {any} + */ + toJSON() { + } +}; +var typeListSlice = (type, start, end) => { + type.doc ?? warnPrematureAccess(); + if (start < 0) { + start = type._length + start; + } + if (end < 0) { + end = type._length + end; + } + let len = end - start; + const cs = []; + let n = type._start; + while (n !== null && len > 0) { + if (n.countable && !n.deleted) { + const c = n.content.getContent(); + if (c.length <= start) { + start -= c.length; + } else { + for (let i = start; i < c.length && len > 0; i++) { + cs.push(c[i]); + len--; + } + start = 0; + } + } + n = n.right; + } + return cs; +}; +var typeListToArray = (type) => { + type.doc ?? warnPrematureAccess(); + const cs = []; + let n = type._start; + while (n !== null) { + if (n.countable && !n.deleted) { + const c = n.content.getContent(); + for (let i = 0; i < c.length; i++) { + cs.push(c[i]); + } + } + n = n.right; + } + return cs; +}; +var typeListToArraySnapshot = (type, snapshot2) => { + const cs = []; + let n = type._start; + while (n !== null) { + if (n.countable && isVisible(n, snapshot2)) { + const c = n.content.getContent(); + for (let i = 0; i < c.length; i++) { + cs.push(c[i]); + } + } + n = n.right; + } + return cs; +}; +var typeListForEach = (type, f) => { + let index = 0; + let n = type._start; + type.doc ?? warnPrematureAccess(); + while (n !== null) { + if (n.countable && !n.deleted) { + const c = n.content.getContent(); + for (let i = 0; i < c.length; i++) { + f(c[i], index++, type); + } + } + n = n.right; + } +}; +var typeListMap = (type, f) => { + const result = []; + typeListForEach(type, (c, i) => { + result.push(f(c, i, type)); + }); + return result; +}; +var typeListCreateIterator = (type) => { + let n = type._start; + let currentContent = null; + let currentContentIndex = 0; + return { + [Symbol.iterator]() { + return this; + }, + next: () => { + if (currentContent === null) { + while (n !== null && n.deleted) { + n = n.right; + } + if (n === null) { + return { + done: true, + value: void 0 + }; + } + currentContent = n.content.getContent(); + currentContentIndex = 0; + n = n.right; + } + const value = currentContent[currentContentIndex++]; + if (currentContent.length <= currentContentIndex) { + currentContent = null; + } + return { + done: false, + value + }; + } + }; +}; +var typeListGet = (type, index) => { + type.doc ?? warnPrematureAccess(); + const marker = findMarker(type, index); + let n = type._start; + if (marker !== null) { + n = marker.p; + index -= marker.index; + } + for (; n !== null; n = n.right) { + if (!n.deleted && n.countable) { + if (index < n.length) { + return n.content.getContent()[index]; + } + index -= n.length; + } + } +}; +var typeListInsertGenericsAfter = (transaction, parent, referenceItem, content) => { + let left = referenceItem; + const doc4 = transaction.doc; + const ownClientId = doc4.clientID; + const store = doc4.store; + const right = referenceItem === null ? parent._start : referenceItem.right; + let jsonContent = []; + const packJsonContent = () => { + if (jsonContent.length > 0) { + left = new Item2(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentAny(jsonContent)); + left.integrate(transaction, 0); + jsonContent = []; + } + }; + content.forEach((c) => { + if (c === null) { + jsonContent.push(c); + } else { + switch (c.constructor) { + case Number: + case Object: + case Boolean: + case Array: + case String: + jsonContent.push(c); + break; + default: + packJsonContent(); + switch (c.constructor) { + case Uint8Array: + case ArrayBuffer: + left = new Item2(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentBinary(new Uint8Array( + /** @type {Uint8Array} */ + c + ))); + left.integrate(transaction, 0); + break; + case Doc: + left = new Item2(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentDoc( + /** @type {Doc} */ + c + )); + left.integrate(transaction, 0); + break; + default: + if (c instanceof AbstractType) { + left = new Item2(createID(ownClientId, getState(store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentType(c)); + left.integrate(transaction, 0); + } else { + throw new Error("Unexpected content type in insert operation"); + } + } + } + } + }); + packJsonContent(); +}; +var lengthExceeded = () => create3("Length exceeded!"); +var typeListInsertGenerics = (transaction, parent, index, content) => { + if (index > parent._length) { + throw lengthExceeded(); + } + if (index === 0) { + if (parent._searchMarker) { + updateMarkerChanges(parent._searchMarker, index, content.length); + } + return typeListInsertGenericsAfter(transaction, parent, null, content); + } + const startIndex = index; + const marker = findMarker(parent, index); + let n = parent._start; + if (marker !== null) { + n = marker.p; + index -= marker.index; + if (index === 0) { + n = n.prev; + index += n && n.countable && !n.deleted ? n.length : 0; + } + } + for (; n !== null; n = n.right) { + if (!n.deleted && n.countable) { + if (index <= n.length) { + if (index < n.length) { + getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); + } + break; + } + index -= n.length; + } + } + if (parent._searchMarker) { + updateMarkerChanges(parent._searchMarker, startIndex, content.length); + } + return typeListInsertGenericsAfter(transaction, parent, n, content); +}; +var typeListPushGenerics = (transaction, parent, content) => { + const marker = (parent._searchMarker || []).reduce((maxMarker, currMarker) => currMarker.index > maxMarker.index ? currMarker : maxMarker, { index: 0, p: parent._start }); + let n = marker.p; + if (n) { + while (n.right) { + n = n.right; + } + } + return typeListInsertGenericsAfter(transaction, parent, n, content); +}; +var typeListDelete = (transaction, parent, index, length2) => { + if (length2 === 0) { + return; + } + const startIndex = index; + const startLength = length2; + const marker = findMarker(parent, index); + let n = parent._start; + if (marker !== null) { + n = marker.p; + index -= marker.index; + } + for (; n !== null && index > 0; n = n.right) { + if (!n.deleted && n.countable) { + if (index < n.length) { + getItemCleanStart(transaction, createID(n.id.client, n.id.clock + index)); + } + index -= n.length; + } + } + while (length2 > 0 && n !== null) { + if (!n.deleted) { + if (length2 < n.length) { + getItemCleanStart(transaction, createID(n.id.client, n.id.clock + length2)); + } + n.delete(transaction); + length2 -= n.length; + } + n = n.right; + } + if (length2 > 0) { + throw lengthExceeded(); + } + if (parent._searchMarker) { + updateMarkerChanges( + parent._searchMarker, + startIndex, + -startLength + length2 + /* in case we remove the above exception */ + ); + } +}; +var typeMapDelete = (transaction, parent, key) => { + const c = parent._map.get(key); + if (c !== void 0) { + c.delete(transaction); + } +}; +var typeMapSet = (transaction, parent, key, value) => { + const left = parent._map.get(key) || null; + const doc4 = transaction.doc; + const ownClientId = doc4.clientID; + let content; + if (value == null) { + content = new ContentAny([value]); + } else { + switch (value.constructor) { + case Number: + case Object: + case Boolean: + case Array: + case String: + case Date: + case BigInt: + content = new ContentAny([value]); + break; + case Uint8Array: + content = new ContentBinary( + /** @type {Uint8Array} */ + value + ); + break; + case Doc: + content = new ContentDoc( + /** @type {Doc} */ + value + ); + break; + default: + if (value instanceof AbstractType) { + content = new ContentType(value); + } else { + throw new Error("Unexpected content type"); + } + } + } + new Item2(createID(ownClientId, getState(doc4.store, ownClientId)), left, left && left.lastId, null, null, parent, key, content).integrate(transaction, 0); +}; +var typeMapGet = (parent, key) => { + parent.doc ?? warnPrematureAccess(); + const val = parent._map.get(key); + return val !== void 0 && !val.deleted ? val.content.getContent()[val.length - 1] : void 0; +}; +var typeMapGetAll = (parent) => { + const res = {}; + parent.doc ?? warnPrematureAccess(); + parent._map.forEach((value, key) => { + if (!value.deleted) { + res[key] = value.content.getContent()[value.length - 1]; + } + }); + return res; +}; +var typeMapHas = (parent, key) => { + parent.doc ?? warnPrematureAccess(); + const val = parent._map.get(key); + return val !== void 0 && !val.deleted; +}; +var typeMapGetAllSnapshot = (parent, snapshot2) => { + const res = {}; + parent._map.forEach((value, key) => { + let v2 = value; + while (v2 !== null && (!snapshot2.sv.has(v2.id.client) || v2.id.clock >= (snapshot2.sv.get(v2.id.client) || 0))) { + v2 = v2.left; + } + if (v2 !== null && isVisible(v2, snapshot2)) { + res[key] = v2.content.getContent()[v2.length - 1]; + } + }); + return res; +}; +var createMapIterator = (type) => { + type.doc ?? warnPrematureAccess(); + return iteratorFilter( + type._map.entries(), + /** @param {any} entry */ + (entry) => !entry[1].deleted + ); +}; +var YArrayEvent = class extends YEvent { +}; +var YArray = class _YArray extends AbstractType { + constructor() { + super(); + this._prelimContent = []; + this._searchMarker = []; + } + /** + * Construct a new YArray containing the specified items. + * @template {Object|Array|number|null|string|Uint8Array} T + * @param {Array} items + * @return {YArray} + */ + static from(items) { + const a = new _YArray(); + a.push(items); + return a; + } + /** + * Integrate this type into the Yjs instance. + * + * * Save this struct in the os + * * This type is sent to other client + * * Observer functions are fired + * + * @param {Doc} y The Yjs instance + * @param {Item} item + */ + _integrate(y2, item) { + super._integrate(y2, item); + this.insert( + 0, + /** @type {Array} */ + this._prelimContent + ); + this._prelimContent = null; + } + /** + * @return {YArray} + */ + _copy() { + return new _YArray(); + } + /** + * Makes a copy of this data type that can be included somewhere else. + * + * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. + * + * @return {YArray} + */ + clone() { + const arr = new _YArray(); + arr.insert(0, this.toArray().map( + (el) => el instanceof AbstractType ? ( + /** @type {typeof el} */ + el.clone() + ) : el + )); + return arr; + } + get length() { + this.doc ?? warnPrematureAccess(); + return this._length; + } + /** + * Creates YArrayEvent and calls observers. + * + * @param {Transaction} transaction + * @param {Set} parentSubs Keys changed on this type. `null` if list was modified. + */ + _callObserver(transaction, parentSubs) { + super._callObserver(transaction, parentSubs); + callTypeObservers(this, transaction, new YArrayEvent(this, transaction)); + } + /** + * Inserts new content at an index. + * + * Important: This function expects an array of content. Not just a content + * object. The reason for this "weirdness" is that inserting several elements + * is very efficient when it is done as a single operation. + * + * @example + * // Insert character 'a' at position 0 + * yarray.insert(0, ['a']) + * // Insert numbers 1, 2 at position 1 + * yarray.insert(1, [1, 2]) + * + * @param {number} index The index to insert content at. + * @param {Array} content The array of content + */ + insert(index, content) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeListInsertGenerics( + transaction, + this, + index, + /** @type {any} */ + content + ); + }); + } else { + this._prelimContent.splice(index, 0, ...content); + } + } + /** + * Appends content to this YArray. + * + * @param {Array} content Array of content to append. + * + * @todo Use the following implementation in all types. + */ + push(content) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeListPushGenerics( + transaction, + this, + /** @type {any} */ + content + ); + }); + } else { + this._prelimContent.push(...content); + } + } + /** + * Prepends content to this YArray. + * + * @param {Array} content Array of content to prepend. + */ + unshift(content) { + this.insert(0, content); + } + /** + * Deletes elements starting from an index. + * + * @param {number} index Index at which to start deleting elements + * @param {number} length The number of elements to remove. Defaults to 1. + */ + delete(index, length2 = 1) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeListDelete(transaction, this, index, length2); + }); + } else { + this._prelimContent.splice(index, length2); + } + } + /** + * Returns the i-th element from a YArray. + * + * @param {number} index The index of the element to return from the YArray + * @return {T} + */ + get(index) { + return typeListGet(this, index); + } + /** + * Transforms this YArray to a JavaScript Array. + * + * @return {Array} + */ + toArray() { + return typeListToArray(this); + } + /** + * Returns a portion of this YArray into a JavaScript Array selected + * from start to end (end not included). + * + * @param {number} [start] + * @param {number} [end] + * @return {Array} + */ + slice(start = 0, end = this.length) { + return typeListSlice(this, start, end); + } + /** + * Transforms this Shared Type to a JSON object. + * + * @return {Array} + */ + toJSON() { + return this.map((c) => c instanceof AbstractType ? c.toJSON() : c); + } + /** + * Returns an Array with the result of calling a provided function on every + * element of this YArray. + * + * @template M + * @param {function(T,number,YArray):M} f Function that produces an element of the new Array + * @return {Array} A new array with each element being the result of the + * callback function + */ + map(f) { + return typeListMap( + this, + /** @type {any} */ + f + ); + } + /** + * Executes a provided function once on every element of this YArray. + * + * @param {function(T,number,YArray):void} f A function to execute on every element of this YArray. + */ + forEach(f) { + typeListForEach(this, f); + } + /** + * @return {IterableIterator} + */ + [Symbol.iterator]() { + return typeListCreateIterator(this); + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + */ + _write(encoder) { + encoder.writeTypeRef(YArrayRefID); + } +}; +var readYArray = (_decoder) => new YArray(); +var YMapEvent = class extends YEvent { + /** + * @param {YMap} ymap The YArray that changed. + * @param {Transaction} transaction + * @param {Set} subs The keys that changed. + */ + constructor(ymap, transaction, subs) { + super(ymap, transaction); + this.keysChanged = subs; + } +}; +var YMap = class _YMap extends AbstractType { + /** + * + * @param {Iterable=} entries - an optional iterable to initialize the YMap + */ + constructor(entries) { + super(); + this._prelimContent = null; + if (entries === void 0) { + this._prelimContent = /* @__PURE__ */ new Map(); + } else { + this._prelimContent = new Map(entries); + } + } + /** + * Integrate this type into the Yjs instance. + * + * * Save this struct in the os + * * This type is sent to other client + * * Observer functions are fired + * + * @param {Doc} y The Yjs instance + * @param {Item} item + */ + _integrate(y2, item) { + super._integrate(y2, item); + this._prelimContent.forEach((value, key) => { + this.set(key, value); + }); + this._prelimContent = null; + } + /** + * @return {YMap} + */ + _copy() { + return new _YMap(); + } + /** + * Makes a copy of this data type that can be included somewhere else. + * + * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. + * + * @return {YMap} + */ + clone() { + const map4 = new _YMap(); + this.forEach((value, key) => { + map4.set(key, value instanceof AbstractType ? ( + /** @type {typeof value} */ + value.clone() + ) : value); + }); + return map4; + } + /** + * Creates YMapEvent and calls observers. + * + * @param {Transaction} transaction + * @param {Set} parentSubs Keys changed on this type. `null` if list was modified. + */ + _callObserver(transaction, parentSubs) { + callTypeObservers(this, transaction, new YMapEvent(this, transaction, parentSubs)); + } + /** + * Transforms this Shared Type to a JSON object. + * + * @return {Object} + */ + toJSON() { + this.doc ?? warnPrematureAccess(); + const map4 = {}; + this._map.forEach((item, key) => { + if (!item.deleted) { + const v2 = item.content.getContent()[item.length - 1]; + map4[key] = v2 instanceof AbstractType ? v2.toJSON() : v2; + } + }); + return map4; + } + /** + * Returns the size of the YMap (count of key/value pairs) + * + * @return {number} + */ + get size() { + return [...createMapIterator(this)].length; + } + /** + * Returns the keys for each element in the YMap Type. + * + * @return {IterableIterator} + */ + keys() { + return iteratorMap( + createMapIterator(this), + /** @param {any} v */ + (v2) => v2[0] + ); + } + /** + * Returns the values for each element in the YMap Type. + * + * @return {IterableIterator} + */ + values() { + return iteratorMap( + createMapIterator(this), + /** @param {any} v */ + (v2) => v2[1].content.getContent()[v2[1].length - 1] + ); + } + /** + * Returns an Iterator of [key, value] pairs + * + * @return {IterableIterator<[string, MapType]>} + */ + entries() { + return iteratorMap( + createMapIterator(this), + /** @param {any} v */ + (v2) => ( + /** @type {any} */ + [v2[0], v2[1].content.getContent()[v2[1].length - 1]] + ) + ); + } + /** + * Executes a provided function on once on every key-value pair. + * + * @param {function(MapType,string,YMap):void} f A function to execute on every element of this YArray. + */ + forEach(f) { + this.doc ?? warnPrematureAccess(); + this._map.forEach((item, key) => { + if (!item.deleted) { + f(item.content.getContent()[item.length - 1], key, this); + } + }); + } + /** + * Returns an Iterator of [key, value] pairs + * + * @return {IterableIterator<[string, MapType]>} + */ + [Symbol.iterator]() { + return this.entries(); + } + /** + * Remove a specified element from this YMap. + * + * @param {string} key The key of the element to remove. + */ + delete(key) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeMapDelete(transaction, this, key); + }); + } else { + this._prelimContent.delete(key); + } + } + /** + * Adds or updates an element with a specified key and value. + * @template {MapType} VAL + * + * @param {string} key The key of the element to add to this YMap + * @param {VAL} value The value of the element to add + * @return {VAL} + */ + set(key, value) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeMapSet( + transaction, + this, + key, + /** @type {any} */ + value + ); + }); + } else { + this._prelimContent.set(key, value); + } + return value; + } + /** + * Returns a specified element from this YMap. + * + * @param {string} key + * @return {MapType|undefined} + */ + get(key) { + return ( + /** @type {any} */ + typeMapGet(this, key) + ); + } + /** + * Returns a boolean indicating whether the specified key exists or not. + * + * @param {string} key The key to test. + * @return {boolean} + */ + has(key) { + return typeMapHas(this, key); + } + /** + * Removes all elements from this YMap. + */ + clear() { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + this.forEach(function(_value, key, map4) { + typeMapDelete(transaction, map4, key); + }); + }); + } else { + this._prelimContent.clear(); + } + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + */ + _write(encoder) { + encoder.writeTypeRef(YMapRefID); + } +}; +var readYMap = (_decoder) => new YMap(); +var equalAttrs = (a, b2) => a === b2 || typeof a === "object" && typeof b2 === "object" && a && b2 && equalFlat(a, b2); +var ItemTextListPosition = class { + /** + * @param {Item|null} left + * @param {Item|null} right + * @param {number} index + * @param {Map} currentAttributes + */ + constructor(left, right, index, currentAttributes) { + this.left = left; + this.right = right; + this.index = index; + this.currentAttributes = currentAttributes; + } + /** + * Only call this if you know that this.right is defined + */ + forward() { + if (this.right === null) { + unexpectedCase(); + } + switch (this.right.content.constructor) { + case ContentFormat: + if (!this.right.deleted) { + updateCurrentAttributes( + this.currentAttributes, + /** @type {ContentFormat} */ + this.right.content + ); + } + break; + default: + if (!this.right.deleted) { + this.index += this.right.length; + } + break; + } + this.left = this.right; + this.right = this.right.right; + } +}; +var findNextPosition = (transaction, pos, count) => { + while (pos.right !== null && count > 0) { + switch (pos.right.content.constructor) { + case ContentFormat: + if (!pos.right.deleted) { + updateCurrentAttributes( + pos.currentAttributes, + /** @type {ContentFormat} */ + pos.right.content + ); + } + break; + default: + if (!pos.right.deleted) { + if (count < pos.right.length) { + getItemCleanStart(transaction, createID(pos.right.id.client, pos.right.id.clock + count)); + } + pos.index += pos.right.length; + count -= pos.right.length; + } + break; + } + pos.left = pos.right; + pos.right = pos.right.right; + } + return pos; +}; +var findPosition = (transaction, parent, index, useSearchMarker) => { + const currentAttributes = /* @__PURE__ */ new Map(); + const marker = useSearchMarker ? findMarker(parent, index) : null; + if (marker) { + const pos = new ItemTextListPosition(marker.p.left, marker.p, marker.index, currentAttributes); + return findNextPosition(transaction, pos, index - marker.index); + } else { + const pos = new ItemTextListPosition(null, parent._start, 0, currentAttributes); + return findNextPosition(transaction, pos, index); + } +}; +var insertNegatedAttributes = (transaction, parent, currPos, negatedAttributes) => { + while (currPos.right !== null && (currPos.right.deleted === true || currPos.right.content.constructor === ContentFormat && equalAttrs( + negatedAttributes.get( + /** @type {ContentFormat} */ + currPos.right.content.key + ), + /** @type {ContentFormat} */ + currPos.right.content.value + ))) { + if (!currPos.right.deleted) { + negatedAttributes.delete( + /** @type {ContentFormat} */ + currPos.right.content.key + ); + } + currPos.forward(); + } + const doc4 = transaction.doc; + const ownClientId = doc4.clientID; + negatedAttributes.forEach((val, key) => { + const left = currPos.left; + const right = currPos.right; + const nextFormat = new Item2(createID(ownClientId, getState(doc4.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); + nextFormat.integrate(transaction, 0); + currPos.right = nextFormat; + currPos.forward(); + }); +}; +var updateCurrentAttributes = (currentAttributes, format) => { + const { key, value } = format; + if (value === null) { + currentAttributes.delete(key); + } else { + currentAttributes.set(key, value); + } +}; +var minimizeAttributeChanges = (currPos, attributes) => { + while (true) { + if (currPos.right === null) { + break; + } else if (currPos.right.deleted || currPos.right.content.constructor === ContentFormat && equalAttrs( + attributes[ + /** @type {ContentFormat} */ + currPos.right.content.key + ] ?? null, + /** @type {ContentFormat} */ + currPos.right.content.value + )) ; + else { + break; + } + currPos.forward(); + } +}; +var insertAttributes = (transaction, parent, currPos, attributes) => { + const doc4 = transaction.doc; + const ownClientId = doc4.clientID; + const negatedAttributes = /* @__PURE__ */ new Map(); + for (const key in attributes) { + const val = attributes[key]; + const currentVal = currPos.currentAttributes.get(key) ?? null; + if (!equalAttrs(currentVal, val)) { + negatedAttributes.set(key, currentVal); + const { left, right } = currPos; + currPos.right = new Item2(createID(ownClientId, getState(doc4.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, new ContentFormat(key, val)); + currPos.right.integrate(transaction, 0); + currPos.forward(); + } + } + return negatedAttributes; +}; +var insertText = (transaction, parent, currPos, text2, attributes) => { + currPos.currentAttributes.forEach((_val, key) => { + if (attributes[key] === void 0) { + attributes[key] = null; + } + }); + const doc4 = transaction.doc; + const ownClientId = doc4.clientID; + minimizeAttributeChanges(currPos, attributes); + const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); + const content = text2.constructor === String ? new ContentString( + /** @type {string} */ + text2 + ) : text2 instanceof AbstractType ? new ContentType(text2) : new ContentEmbed(text2); + let { left, right, index } = currPos; + if (parent._searchMarker) { + updateMarkerChanges(parent._searchMarker, currPos.index, content.getLength()); + } + right = new Item2(createID(ownClientId, getState(doc4.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, content); + right.integrate(transaction, 0); + currPos.right = right; + currPos.index = index; + currPos.forward(); + insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); +}; +var formatText = (transaction, parent, currPos, length2, attributes) => { + const doc4 = transaction.doc; + const ownClientId = doc4.clientID; + minimizeAttributeChanges(currPos, attributes); + const negatedAttributes = insertAttributes(transaction, parent, currPos, attributes); + iterationLoop: while (currPos.right !== null && (length2 > 0 || negatedAttributes.size > 0 && (currPos.right.deleted || currPos.right.content.constructor === ContentFormat))) { + if (!currPos.right.deleted) { + switch (currPos.right.content.constructor) { + case ContentFormat: { + const { key, value } = ( + /** @type {ContentFormat} */ + currPos.right.content + ); + const attr = attributes[key]; + if (attr !== void 0) { + if (equalAttrs(attr, value)) { + negatedAttributes.delete(key); + } else { + if (length2 === 0) { + break iterationLoop; + } + negatedAttributes.set(key, value); + } + currPos.right.delete(transaction); + } else { + currPos.currentAttributes.set(key, value); + } + break; + } + default: + if (length2 < currPos.right.length) { + getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length2)); + } + length2 -= currPos.right.length; + break; + } + } + currPos.forward(); + } + if (length2 > 0) { + let newlines = ""; + for (; length2 > 0; length2--) { + newlines += "\n"; + } + currPos.right = new Item2(createID(ownClientId, getState(doc4.store, ownClientId)), currPos.left, currPos.left && currPos.left.lastId, currPos.right, currPos.right && currPos.right.id, parent, null, new ContentString(newlines)); + currPos.right.integrate(transaction, 0); + currPos.forward(); + } + insertNegatedAttributes(transaction, parent, currPos, negatedAttributes); +}; +var cleanupFormattingGap = (transaction, start, curr, startAttributes, currAttributes) => { + let end = start; + const endFormats = create(); + while (end && (!end.countable || end.deleted)) { + if (!end.deleted && end.content.constructor === ContentFormat) { + const cf = ( + /** @type {ContentFormat} */ + end.content + ); + endFormats.set(cf.key, cf); + } + end = end.right; + } + let cleanups = 0; + let reachedCurr = false; + while (start !== end) { + if (curr === start) { + reachedCurr = true; + } + if (!start.deleted) { + const content = start.content; + switch (content.constructor) { + case ContentFormat: { + const { key, value } = ( + /** @type {ContentFormat} */ + content + ); + const startAttrValue = startAttributes.get(key) ?? null; + if (endFormats.get(key) !== content || startAttrValue === value) { + start.delete(transaction); + cleanups++; + if (!reachedCurr && (currAttributes.get(key) ?? null) === value && startAttrValue !== value) { + if (startAttrValue === null) { + currAttributes.delete(key); + } else { + currAttributes.set(key, startAttrValue); + } + } + } + if (!reachedCurr && !start.deleted) { + updateCurrentAttributes( + currAttributes, + /** @type {ContentFormat} */ + content + ); + } + break; + } + } + } + start = /** @type {Item} */ + start.right; + } + return cleanups; +}; +var cleanupContextlessFormattingGap = (transaction, item) => { + while (item && item.right && (item.right.deleted || !item.right.countable)) { + item = item.right; + } + const attrs = /* @__PURE__ */ new Set(); + while (item && (item.deleted || !item.countable)) { + if (!item.deleted && item.content.constructor === ContentFormat) { + const key = ( + /** @type {ContentFormat} */ + item.content.key + ); + if (attrs.has(key)) { + item.delete(transaction); + } else { + attrs.add(key); + } + } + item = item.left; + } +}; +var cleanupYTextFormatting = (type) => { + let res = 0; + transact( + /** @type {Doc} */ + type.doc, + (transaction) => { + let start = ( + /** @type {Item} */ + type._start + ); + let end = type._start; + let startAttributes = create(); + const currentAttributes = copy2(startAttributes); + while (end) { + if (end.deleted === false) { + switch (end.content.constructor) { + case ContentFormat: + updateCurrentAttributes( + currentAttributes, + /** @type {ContentFormat} */ + end.content + ); + break; + default: + res += cleanupFormattingGap(transaction, start, end, startAttributes, currentAttributes); + startAttributes = copy2(currentAttributes); + start = end; + break; + } + } + end = end.right; + } + } + ); + return res; +}; +var cleanupYTextAfterTransaction = (transaction) => { + const needFullCleanup = /* @__PURE__ */ new Set(); + const doc4 = transaction.doc; + for (const [client, afterClock] of transaction.afterState.entries()) { + const clock = transaction.beforeState.get(client) || 0; + if (afterClock === clock) { + continue; + } + iterateStructs( + transaction, + /** @type {Array} */ + doc4.store.clients.get(client), + clock, + afterClock, + (item) => { + if (!item.deleted && /** @type {Item} */ + item.content.constructor === ContentFormat && item.constructor !== GC) { + needFullCleanup.add( + /** @type {any} */ + item.parent + ); + } + } + ); + } + transact(doc4, (t) => { + iterateDeletedStructs(transaction, transaction.deleteSet, (item) => { + if (item instanceof GC || !/** @type {YText} */ + item.parent._hasFormatting || needFullCleanup.has( + /** @type {YText} */ + item.parent + )) { + return; + } + const parent = ( + /** @type {YText} */ + item.parent + ); + if (item.content.constructor === ContentFormat) { + needFullCleanup.add(parent); + } else { + cleanupContextlessFormattingGap(t, item); + } + }); + for (const yText of needFullCleanup) { + cleanupYTextFormatting(yText); + } + }); +}; +var deleteText = (transaction, currPos, length2) => { + const startLength = length2; + const startAttrs = copy2(currPos.currentAttributes); + const start = currPos.right; + while (length2 > 0 && currPos.right !== null) { + if (currPos.right.deleted === false) { + switch (currPos.right.content.constructor) { + case ContentType: + case ContentEmbed: + case ContentString: + if (length2 < currPos.right.length) { + getItemCleanStart(transaction, createID(currPos.right.id.client, currPos.right.id.clock + length2)); + } + length2 -= currPos.right.length; + currPos.right.delete(transaction); + break; + } + } + currPos.forward(); + } + if (start) { + cleanupFormattingGap(transaction, start, currPos.right, startAttrs, currPos.currentAttributes); + } + const parent = ( + /** @type {AbstractType} */ + /** @type {Item} */ + (currPos.left || currPos.right).parent + ); + if (parent._searchMarker) { + updateMarkerChanges(parent._searchMarker, currPos.index, -startLength + length2); + } + return currPos; +}; +var YTextEvent = class extends YEvent { + /** + * @param {YText} ytext + * @param {Transaction} transaction + * @param {Set} subs The keys that changed + */ + constructor(ytext, transaction, subs) { + super(ytext, transaction); + this.childListChanged = false; + this.keysChanged = /* @__PURE__ */ new Set(); + subs.forEach((sub) => { + if (sub === null) { + this.childListChanged = true; + } else { + this.keysChanged.add(sub); + } + }); + } + /** + * @type {{added:Set,deleted:Set,keys:Map,delta:Array<{insert?:Array|string, delete?:number, retain?:number}>}} + */ + get changes() { + if (this._changes === null) { + const changes = { + keys: this.keys, + delta: this.delta, + added: /* @__PURE__ */ new Set(), + deleted: /* @__PURE__ */ new Set() + }; + this._changes = changes; + } + return ( + /** @type {any} */ + this._changes + ); + } + /** + * Compute the changes in the delta format. + * A {@link https://quilljs.com/docs/delta/|Quill Delta}) that represents the changes on the document. + * + * @type {Array<{insert?:string|object|AbstractType, delete?:number, retain?:number, attributes?: Object}>} + * + * @public + */ + get delta() { + if (this._delta === null) { + const y2 = ( + /** @type {Doc} */ + this.target.doc + ); + const delta = []; + transact(y2, (transaction) => { + const currentAttributes = /* @__PURE__ */ new Map(); + const oldAttributes = /* @__PURE__ */ new Map(); + let item = this.target._start; + let action = null; + const attributes = {}; + let insert = ""; + let retain = 0; + let deleteLen = 0; + const addOp = () => { + if (action !== null) { + let op = null; + switch (action) { + case "delete": + if (deleteLen > 0) { + op = { delete: deleteLen }; + } + deleteLen = 0; + break; + case "insert": + if (typeof insert === "object" || insert.length > 0) { + op = { insert }; + if (currentAttributes.size > 0) { + op.attributes = {}; + currentAttributes.forEach((value, key) => { + if (value !== null) { + op.attributes[key] = value; + } + }); + } + } + insert = ""; + break; + case "retain": + if (retain > 0) { + op = { retain }; + if (!isEmpty(attributes)) { + op.attributes = assign({}, attributes); + } + } + retain = 0; + break; + } + if (op) delta.push(op); + action = null; + } + }; + while (item !== null) { + switch (item.content.constructor) { + case ContentType: + case ContentEmbed: + if (this.adds(item)) { + if (!this.deletes(item)) { + addOp(); + action = "insert"; + insert = item.content.getContent()[0]; + addOp(); + } + } else if (this.deletes(item)) { + if (action !== "delete") { + addOp(); + action = "delete"; + } + deleteLen += 1; + } else if (!item.deleted) { + if (action !== "retain") { + addOp(); + action = "retain"; + } + retain += 1; + } + break; + case ContentString: + if (this.adds(item)) { + if (!this.deletes(item)) { + if (action !== "insert") { + addOp(); + action = "insert"; + } + insert += /** @type {ContentString} */ + item.content.str; + } + } else if (this.deletes(item)) { + if (action !== "delete") { + addOp(); + action = "delete"; + } + deleteLen += item.length; + } else if (!item.deleted) { + if (action !== "retain") { + addOp(); + action = "retain"; + } + retain += item.length; + } + break; + case ContentFormat: { + const { key, value } = ( + /** @type {ContentFormat} */ + item.content + ); + if (this.adds(item)) { + if (!this.deletes(item)) { + const curVal = currentAttributes.get(key) ?? null; + if (!equalAttrs(curVal, value)) { + if (action === "retain") { + addOp(); + } + if (equalAttrs(value, oldAttributes.get(key) ?? null)) { + delete attributes[key]; + } else { + attributes[key] = value; + } + } else if (value !== null) { + item.delete(transaction); + } + } + } else if (this.deletes(item)) { + oldAttributes.set(key, value); + const curVal = currentAttributes.get(key) ?? null; + if (!equalAttrs(curVal, value)) { + if (action === "retain") { + addOp(); + } + attributes[key] = curVal; + } + } else if (!item.deleted) { + oldAttributes.set(key, value); + const attr = attributes[key]; + if (attr !== void 0) { + if (!equalAttrs(attr, value)) { + if (action === "retain") { + addOp(); + } + if (value === null) { + delete attributes[key]; + } else { + attributes[key] = value; + } + } else if (attr !== null) { + item.delete(transaction); + } + } + } + if (!item.deleted) { + if (action === "insert") { + addOp(); + } + updateCurrentAttributes( + currentAttributes, + /** @type {ContentFormat} */ + item.content + ); + } + break; + } + } + item = item.right; + } + addOp(); + while (delta.length > 0) { + const lastOp = delta[delta.length - 1]; + if (lastOp.retain !== void 0 && lastOp.attributes === void 0) { + delta.pop(); + } else { + break; + } + } + }); + this._delta = delta; + } + return ( + /** @type {any} */ + this._delta + ); + } +}; +var YText = class _YText extends AbstractType { + /** + * @param {String} [string] The initial value of the YText. + */ + constructor(string) { + super(); + this._pending = string !== void 0 ? [() => this.insert(0, string)] : []; + this._searchMarker = []; + this._hasFormatting = false; + } + /** + * Number of characters of this text type. + * + * @type {number} + */ + get length() { + this.doc ?? warnPrematureAccess(); + return this._length; + } + /** + * @param {Doc} y + * @param {Item} item + */ + _integrate(y2, item) { + super._integrate(y2, item); + try { + this._pending.forEach((f) => f()); + } catch (e) { + console.error(e); + } + this._pending = null; + } + _copy() { + return new _YText(); + } + /** + * Makes a copy of this data type that can be included somewhere else. + * + * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. + * + * @return {YText} + */ + clone() { + const text2 = new _YText(); + text2.applyDelta(this.toDelta()); + return text2; + } + /** + * Creates YTextEvent and calls observers. + * + * @param {Transaction} transaction + * @param {Set} parentSubs Keys changed on this type. `null` if list was modified. + */ + _callObserver(transaction, parentSubs) { + super._callObserver(transaction, parentSubs); + const event = new YTextEvent(this, transaction, parentSubs); + callTypeObservers(this, transaction, event); + if (!transaction.local && this._hasFormatting) { + transaction._needFormattingCleanup = true; + } + } + /** + * Returns the unformatted string representation of this YText type. + * + * @public + */ + toString() { + this.doc ?? warnPrematureAccess(); + let str = ""; + let n = this._start; + while (n !== null) { + if (!n.deleted && n.countable && n.content.constructor === ContentString) { + str += /** @type {ContentString} */ + n.content.str; + } + n = n.right; + } + return str; + } + /** + * Returns the unformatted string representation of this YText type. + * + * @return {string} + * @public + */ + toJSON() { + return this.toString(); + } + /** + * Apply a {@link Delta} on this shared YText type. + * + * @param {Array} delta The changes to apply on this element. + * @param {object} opts + * @param {boolean} [opts.sanitize] Sanitize input delta. Removes ending newlines if set to true. + * + * + * @public + */ + applyDelta(delta, { sanitize = true } = {}) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + const currPos = new ItemTextListPosition(null, this._start, 0, /* @__PURE__ */ new Map()); + for (let i = 0; i < delta.length; i++) { + const op = delta[i]; + if (op.insert !== void 0) { + const ins = !sanitize && typeof op.insert === "string" && i === delta.length - 1 && currPos.right === null && op.insert.slice(-1) === "\n" ? op.insert.slice(0, -1) : op.insert; + if (typeof ins !== "string" || ins.length > 0) { + insertText(transaction, this, currPos, ins, op.attributes || {}); + } + } else if (op.retain !== void 0) { + formatText(transaction, this, currPos, op.retain, op.attributes || {}); + } else if (op.delete !== void 0) { + deleteText(transaction, currPos, op.delete); + } + } + }); + } else { + this._pending.push(() => this.applyDelta(delta)); + } + } + /** + * Returns the Delta representation of this YText type. + * + * @param {Snapshot} [snapshot] + * @param {Snapshot} [prevSnapshot] + * @param {function('removed' | 'added', ID):any} [computeYChange] + * @return {any} The Delta representation of this type. + * + * @public + */ + toDelta(snapshot2, prevSnapshot, computeYChange) { + this.doc ?? warnPrematureAccess(); + const ops = []; + const currentAttributes = /* @__PURE__ */ new Map(); + const doc4 = ( + /** @type {Doc} */ + this.doc + ); + let str = ""; + let n = this._start; + function packStr() { + if (str.length > 0) { + const attributes = {}; + let addAttributes = false; + currentAttributes.forEach((value, key) => { + addAttributes = true; + attributes[key] = value; + }); + const op = { insert: str }; + if (addAttributes) { + op.attributes = attributes; + } + ops.push(op); + str = ""; + } + } + const computeDelta = () => { + while (n !== null) { + if (isVisible(n, snapshot2) || prevSnapshot !== void 0 && isVisible(n, prevSnapshot)) { + switch (n.content.constructor) { + case ContentString: { + const cur = currentAttributes.get("ychange"); + if (snapshot2 !== void 0 && !isVisible(n, snapshot2)) { + if (cur === void 0 || cur.user !== n.id.client || cur.type !== "removed") { + packStr(); + currentAttributes.set("ychange", computeYChange ? computeYChange("removed", n.id) : { type: "removed" }); + } + } else if (prevSnapshot !== void 0 && !isVisible(n, prevSnapshot)) { + if (cur === void 0 || cur.user !== n.id.client || cur.type !== "added") { + packStr(); + currentAttributes.set("ychange", computeYChange ? computeYChange("added", n.id) : { type: "added" }); + } + } else if (cur !== void 0) { + packStr(); + currentAttributes.delete("ychange"); + } + str += /** @type {ContentString} */ + n.content.str; + break; + } + case ContentType: + case ContentEmbed: { + packStr(); + const op = { + insert: n.content.getContent()[0] + }; + if (currentAttributes.size > 0) { + const attrs = ( + /** @type {Object} */ + {} + ); + op.attributes = attrs; + currentAttributes.forEach((value, key) => { + attrs[key] = value; + }); + } + ops.push(op); + break; + } + case ContentFormat: + if (isVisible(n, snapshot2)) { + packStr(); + updateCurrentAttributes( + currentAttributes, + /** @type {ContentFormat} */ + n.content + ); + } + break; + } + } + n = n.right; + } + packStr(); + }; + if (snapshot2 || prevSnapshot) { + transact(doc4, (transaction) => { + if (snapshot2) { + splitSnapshotAffectedStructs(transaction, snapshot2); + } + if (prevSnapshot) { + splitSnapshotAffectedStructs(transaction, prevSnapshot); + } + computeDelta(); + }, "cleanup"); + } else { + computeDelta(); + } + return ops; + } + /** + * Insert text at a given index. + * + * @param {number} index The index at which to start inserting. + * @param {String} text The text to insert at the specified position. + * @param {TextAttributes} [attributes] Optionally define some formatting + * information to apply on the inserted + * Text. + * @public + */ + insert(index, text2, attributes) { + if (text2.length <= 0) { + return; + } + const y2 = this.doc; + if (y2 !== null) { + transact(y2, (transaction) => { + const pos = findPosition(transaction, this, index, !attributes); + if (!attributes) { + attributes = {}; + pos.currentAttributes.forEach((v2, k) => { + attributes[k] = v2; + }); + } + insertText(transaction, this, pos, text2, attributes); + }); + } else { + this._pending.push(() => this.insert(index, text2, attributes)); + } + } + /** + * Inserts an embed at a index. + * + * @param {number} index The index to insert the embed at. + * @param {Object | AbstractType} embed The Object that represents the embed. + * @param {TextAttributes} [attributes] Attribute information to apply on the + * embed + * + * @public + */ + insertEmbed(index, embed, attributes) { + const y2 = this.doc; + if (y2 !== null) { + transact(y2, (transaction) => { + const pos = findPosition(transaction, this, index, !attributes); + insertText(transaction, this, pos, embed, attributes || {}); + }); + } else { + this._pending.push(() => this.insertEmbed(index, embed, attributes || {})); + } + } + /** + * Deletes text starting from an index. + * + * @param {number} index Index at which to start deleting. + * @param {number} length The number of characters to remove. Defaults to 1. + * + * @public + */ + delete(index, length2) { + if (length2 === 0) { + return; + } + const y2 = this.doc; + if (y2 !== null) { + transact(y2, (transaction) => { + deleteText(transaction, findPosition(transaction, this, index, true), length2); + }); + } else { + this._pending.push(() => this.delete(index, length2)); + } + } + /** + * Assigns properties to a range of text. + * + * @param {number} index The position where to start formatting. + * @param {number} length The amount of characters to assign properties to. + * @param {TextAttributes} attributes Attribute information to apply on the + * text. + * + * @public + */ + format(index, length2, attributes) { + if (length2 === 0) { + return; + } + const y2 = this.doc; + if (y2 !== null) { + transact(y2, (transaction) => { + const pos = findPosition(transaction, this, index, false); + if (pos.right === null) { + return; + } + formatText(transaction, this, pos, length2, attributes); + }); + } else { + this._pending.push(() => this.format(index, length2, attributes)); + } + } + /** + * Removes an attribute. + * + * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. + * + * @param {String} attributeName The attribute name that is to be removed. + * + * @public + */ + removeAttribute(attributeName) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeMapDelete(transaction, this, attributeName); + }); + } else { + this._pending.push(() => this.removeAttribute(attributeName)); + } + } + /** + * Sets or updates an attribute. + * + * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. + * + * @param {String} attributeName The attribute name that is to be set. + * @param {any} attributeValue The attribute value that is to be set. + * + * @public + */ + setAttribute(attributeName, attributeValue) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeMapSet(transaction, this, attributeName, attributeValue); + }); + } else { + this._pending.push(() => this.setAttribute(attributeName, attributeValue)); + } + } + /** + * Returns an attribute value that belongs to the attribute name. + * + * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. + * + * @param {String} attributeName The attribute name that identifies the + * queried value. + * @return {any} The queried attribute value. + * + * @public + */ + getAttribute(attributeName) { + return ( + /** @type {any} */ + typeMapGet(this, attributeName) + ); + } + /** + * Returns all attribute name/value pairs in a JSON Object. + * + * @note Xml-Text nodes don't have attributes. You can use this feature to assign properties to complete text-blocks. + * + * @return {Object} A JSON Object that describes the attributes. + * + * @public + */ + getAttributes() { + return typeMapGetAll(this); + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + */ + _write(encoder) { + encoder.writeTypeRef(YTextRefID); + } +}; +var readYText = (_decoder) => new YText(); +var YXmlTreeWalker = class { + /** + * @param {YXmlFragment | YXmlElement} root + * @param {function(AbstractType):boolean} [f] + */ + constructor(root2, f = () => true) { + this._filter = f; + this._root = root2; + this._currentNode = /** @type {Item} */ + root2._start; + this._firstCall = true; + root2.doc ?? warnPrematureAccess(); + } + [Symbol.iterator]() { + return this; + } + /** + * Get the next node. + * + * @return {IteratorResult} The next node. + * + * @public + */ + next() { + let n = this._currentNode; + let type = n && n.content && /** @type {any} */ + n.content.type; + if (n !== null && (!this._firstCall || n.deleted || !this._filter(type))) { + do { + type = /** @type {any} */ + n.content.type; + if (!n.deleted && (type.constructor === YXmlElement || type.constructor === YXmlFragment) && type._start !== null) { + n = type._start; + } else { + while (n !== null) { + const nxt = n.next; + if (nxt !== null) { + n = nxt; + break; + } else if (n.parent === this._root) { + n = null; + } else { + n = /** @type {AbstractType} */ + n.parent._item; + } + } + } + } while (n !== null && (n.deleted || !this._filter( + /** @type {ContentType} */ + n.content.type + ))); + } + this._firstCall = false; + if (n === null) { + return { value: void 0, done: true }; + } + this._currentNode = n; + return { value: ( + /** @type {any} */ + n.content.type + ), done: false }; + } +}; +var YXmlFragment = class _YXmlFragment extends AbstractType { + constructor() { + super(); + this._prelimContent = []; + } + /** + * @type {YXmlElement|YXmlText|null} + */ + get firstChild() { + const first2 = this._first; + return first2 ? first2.content.getContent()[0] : null; + } + /** + * Integrate this type into the Yjs instance. + * + * * Save this struct in the os + * * This type is sent to other client + * * Observer functions are fired + * + * @param {Doc} y The Yjs instance + * @param {Item} item + */ + _integrate(y2, item) { + super._integrate(y2, item); + this.insert( + 0, + /** @type {Array} */ + this._prelimContent + ); + this._prelimContent = null; + } + _copy() { + return new _YXmlFragment(); + } + /** + * Makes a copy of this data type that can be included somewhere else. + * + * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. + * + * @return {YXmlFragment} + */ + clone() { + const el = new _YXmlFragment(); + el.insert(0, this.toArray().map((item) => item instanceof AbstractType ? item.clone() : item)); + return el; + } + get length() { + this.doc ?? warnPrematureAccess(); + return this._prelimContent === null ? this._length : this._prelimContent.length; + } + /** + * Create a subtree of childNodes. + * + * @example + * const walker = elem.createTreeWalker(dom => dom.nodeName === 'div') + * for (let node in walker) { + * // `node` is a div node + * nop(node) + * } + * + * @param {function(AbstractType):boolean} filter Function that is called on each child element and + * returns a Boolean indicating whether the child + * is to be included in the subtree. + * @return {YXmlTreeWalker} A subtree and a position within it. + * + * @public + */ + createTreeWalker(filter) { + return new YXmlTreeWalker(this, filter); + } + /** + * Returns the first YXmlElement that matches the query. + * Similar to DOM's {@link querySelector}. + * + * Query support: + * - tagname + * TODO: + * - id + * - attribute + * + * @param {CSS_Selector} query The query on the children. + * @return {YXmlElement|YXmlText|YXmlHook|null} The first element that matches the query or null. + * + * @public + */ + querySelector(query) { + query = query.toUpperCase(); + const iterator = new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query); + const next2 = iterator.next(); + if (next2.done) { + return null; + } else { + return next2.value; + } + } + /** + * Returns all YXmlElements that match the query. + * Similar to Dom's {@link querySelectorAll}. + * + * @todo Does not yet support all queries. Currently only query by tagName. + * + * @param {CSS_Selector} query The query on the children + * @return {Array} The elements that match this query. + * + * @public + */ + querySelectorAll(query) { + query = query.toUpperCase(); + return from2(new YXmlTreeWalker(this, (element2) => element2.nodeName && element2.nodeName.toUpperCase() === query)); + } + /** + * Creates YXmlEvent and calls observers. + * + * @param {Transaction} transaction + * @param {Set} parentSubs Keys changed on this type. `null` if list was modified. + */ + _callObserver(transaction, parentSubs) { + callTypeObservers(this, transaction, new YXmlEvent(this, parentSubs, transaction)); + } + /** + * Get the string representation of all the children of this YXmlFragment. + * + * @return {string} The string representation of all children. + */ + toString() { + return typeListMap(this, (xml) => xml.toString()).join(""); + } + /** + * @return {string} + */ + toJSON() { + return this.toString(); + } + /** + * Creates a Dom Element that mirrors this YXmlElement. + * + * @param {Document} [_document=document] The document object (you must define + * this when calling this method in + * nodejs) + * @param {Object} [hooks={}] Optional property to customize how hooks + * are presented in the DOM + * @param {any} [binding] You should not set this property. This is + * used if DomBinding wants to create a + * association to the created DOM type. + * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} + * + * @public + */ + toDOM(_document = document, hooks = {}, binding) { + const fragment = _document.createDocumentFragment(); + if (binding !== void 0) { + binding._createAssociation(fragment, this); + } + typeListForEach(this, (xmlType) => { + fragment.insertBefore(xmlType.toDOM(_document, hooks, binding), null); + }); + return fragment; + } + /** + * Inserts new content at an index. + * + * @example + * // Insert character 'a' at position 0 + * xml.insert(0, [new Y.XmlText('text')]) + * + * @param {number} index The index to insert content at + * @param {Array} content The array of content + */ + insert(index, content) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeListInsertGenerics(transaction, this, index, content); + }); + } else { + this._prelimContent.splice(index, 0, ...content); + } + } + /** + * Inserts new content at an index. + * + * @example + * // Insert character 'a' at position 0 + * xml.insert(0, [new Y.XmlText('text')]) + * + * @param {null|Item|YXmlElement|YXmlText} ref The index to insert content at + * @param {Array} content The array of content + */ + insertAfter(ref, content) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + const refItem = ref && ref instanceof AbstractType ? ref._item : ref; + typeListInsertGenericsAfter(transaction, this, refItem, content); + }); + } else { + const pc = ( + /** @type {Array} */ + this._prelimContent + ); + const index = ref === null ? 0 : pc.findIndex((el) => el === ref) + 1; + if (index === 0 && ref !== null) { + throw create3("Reference item not found"); + } + pc.splice(index, 0, ...content); + } + } + /** + * Deletes elements starting from an index. + * + * @param {number} index Index at which to start deleting elements + * @param {number} [length=1] The number of elements to remove. Defaults to 1. + */ + delete(index, length2 = 1) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeListDelete(transaction, this, index, length2); + }); + } else { + this._prelimContent.splice(index, length2); + } + } + /** + * Transforms this YArray to a JavaScript Array. + * + * @return {Array} + */ + toArray() { + return typeListToArray(this); + } + /** + * Appends content to this YArray. + * + * @param {Array} content Array of content to append. + */ + push(content) { + this.insert(this.length, content); + } + /** + * Prepends content to this YArray. + * + * @param {Array} content Array of content to prepend. + */ + unshift(content) { + this.insert(0, content); + } + /** + * Returns the i-th element from a YArray. + * + * @param {number} index The index of the element to return from the YArray + * @return {YXmlElement|YXmlText} + */ + get(index) { + return typeListGet(this, index); + } + /** + * Returns a portion of this YXmlFragment into a JavaScript Array selected + * from start to end (end not included). + * + * @param {number} [start] + * @param {number} [end] + * @return {Array} + */ + slice(start = 0, end = this.length) { + return typeListSlice(this, start, end); + } + /** + * Executes a provided function on once on every child element. + * + * @param {function(YXmlElement|YXmlText,number, typeof self):void} f A function to execute on every element of this YArray. + */ + forEach(f) { + typeListForEach(this, f); + } + /** + * Transform the properties of this type to binary and write it to an + * BinaryEncoder. + * + * This is called when this Item is sent to a remote peer. + * + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. + */ + _write(encoder) { + encoder.writeTypeRef(YXmlFragmentRefID); + } +}; +var readYXmlFragment = (_decoder) => new YXmlFragment(); +var YXmlElement = class _YXmlElement extends YXmlFragment { + constructor(nodeName = "UNDEFINED") { + super(); + this.nodeName = nodeName; + this._prelimAttrs = /* @__PURE__ */ new Map(); + } + /** + * @type {YXmlElement|YXmlText|null} + */ + get nextSibling() { + const n = this._item ? this._item.next : null; + return n ? ( + /** @type {YXmlElement|YXmlText} */ + /** @type {ContentType} */ + n.content.type + ) : null; + } + /** + * @type {YXmlElement|YXmlText|null} + */ + get prevSibling() { + const n = this._item ? this._item.prev : null; + return n ? ( + /** @type {YXmlElement|YXmlText} */ + /** @type {ContentType} */ + n.content.type + ) : null; + } + /** + * Integrate this type into the Yjs instance. + * + * * Save this struct in the os + * * This type is sent to other client + * * Observer functions are fired + * + * @param {Doc} y The Yjs instance + * @param {Item} item + */ + _integrate(y2, item) { + super._integrate(y2, item); + /** @type {Map} */ + this._prelimAttrs.forEach((value, key) => { + this.setAttribute(key, value); + }); + this._prelimAttrs = null; + } + /** + * Creates an Item with the same effect as this Item (without position effect) + * + * @return {YXmlElement} + */ + _copy() { + return new _YXmlElement(this.nodeName); + } + /** + * Makes a copy of this data type that can be included somewhere else. + * + * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. + * + * @return {YXmlElement} + */ + clone() { + const el = new _YXmlElement(this.nodeName); + const attrs = this.getAttributes(); + forEach3(attrs, (value, key) => { + el.setAttribute( + key, + /** @type {any} */ + value + ); + }); + el.insert(0, this.toArray().map((v2) => v2 instanceof AbstractType ? v2.clone() : v2)); + return el; + } + /** + * Returns the XML serialization of this YXmlElement. + * The attributes are ordered by attribute-name, so you can easily use this + * method to compare YXmlElements + * + * @return {string} The string representation of this type. + * + * @public + */ + toString() { + const attrs = this.getAttributes(); + const stringBuilder = []; + const keys3 = []; + for (const key in attrs) { + keys3.push(key); + } + keys3.sort(); + const keysLen = keys3.length; + for (let i = 0; i < keysLen; i++) { + const key = keys3[i]; + stringBuilder.push(key + '="' + attrs[key] + '"'); + } + const nodeName = this.nodeName.toLocaleLowerCase(); + const attrsString = stringBuilder.length > 0 ? " " + stringBuilder.join(" ") : ""; + return `<${nodeName}${attrsString}>${super.toString()}`; + } + /** + * Removes an attribute from this YXmlElement. + * + * @param {string} attributeName The attribute name that is to be removed. + * + * @public + */ + removeAttribute(attributeName) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeMapDelete(transaction, this, attributeName); + }); + } else { + this._prelimAttrs.delete(attributeName); + } + } + /** + * Sets or updates an attribute. + * + * @template {keyof KV & string} KEY + * + * @param {KEY} attributeName The attribute name that is to be set. + * @param {KV[KEY]} attributeValue The attribute value that is to be set. + * + * @public + */ + setAttribute(attributeName, attributeValue) { + if (this.doc !== null) { + transact(this.doc, (transaction) => { + typeMapSet(transaction, this, attributeName, attributeValue); + }); + } else { + this._prelimAttrs.set(attributeName, attributeValue); + } + } + /** + * Returns an attribute value that belongs to the attribute name. + * + * @template {keyof KV & string} KEY + * + * @param {KEY} attributeName The attribute name that identifies the + * queried value. + * @return {KV[KEY]|undefined} The queried attribute value. + * + * @public + */ + getAttribute(attributeName) { + return ( + /** @type {any} */ + typeMapGet(this, attributeName) + ); + } + /** + * Returns whether an attribute exists + * + * @param {string} attributeName The attribute name to check for existence. + * @return {boolean} whether the attribute exists. + * + * @public + */ + hasAttribute(attributeName) { + return ( + /** @type {any} */ + typeMapHas(this, attributeName) + ); + } + /** + * Returns all attribute name/value pairs in a JSON Object. + * + * @param {Snapshot} [snapshot] + * @return {{ [Key in Extract]?: KV[Key]}} A JSON Object that describes the attributes. + * + * @public + */ + getAttributes(snapshot2) { + return ( + /** @type {any} */ + snapshot2 ? typeMapGetAllSnapshot(this, snapshot2) : typeMapGetAll(this) + ); + } + /** + * Creates a Dom Element that mirrors this YXmlElement. + * + * @param {Document} [_document=document] The document object (you must define + * this when calling this method in + * nodejs) + * @param {Object} [hooks={}] Optional property to customize how hooks + * are presented in the DOM + * @param {any} [binding] You should not set this property. This is + * used if DomBinding wants to create a + * association to the created DOM type. + * @return {Node} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} + * + * @public + */ + toDOM(_document = document, hooks = {}, binding) { + const dom = _document.createElement(this.nodeName); + const attrs = this.getAttributes(); + for (const key in attrs) { + const value = attrs[key]; + if (typeof value === "string") { + dom.setAttribute(key, value); + } + } + typeListForEach(this, (yxml) => { + dom.appendChild(yxml.toDOM(_document, hooks, binding)); + }); + if (binding !== void 0) { + binding._createAssociation(dom, this); + } + return dom; + } + /** + * Transform the properties of this type to binary and write it to an + * BinaryEncoder. + * + * This is called when this Item is sent to a remote peer. + * + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. + */ + _write(encoder) { + encoder.writeTypeRef(YXmlElementRefID); + encoder.writeKey(this.nodeName); + } +}; +var readYXmlElement = (decoder) => new YXmlElement(decoder.readKey()); +var YXmlEvent = class extends YEvent { + /** + * @param {YXmlElement|YXmlText|YXmlFragment} target The target on which the event is created. + * @param {Set} subs The set of changed attributes. `null` is included if the + * child list changed. + * @param {Transaction} transaction The transaction instance with which the + * change was created. + */ + constructor(target, subs, transaction) { + super(target, transaction); + this.childListChanged = false; + this.attributesChanged = /* @__PURE__ */ new Set(); + subs.forEach((sub) => { + if (sub === null) { + this.childListChanged = true; + } else { + this.attributesChanged.add(sub); + } + }); + } +}; +var YXmlHook = class _YXmlHook extends YMap { + /** + * @param {string} hookName nodeName of the Dom Node. + */ + constructor(hookName) { + super(); + this.hookName = hookName; + } + /** + * Creates an Item with the same effect as this Item (without position effect) + */ + _copy() { + return new _YXmlHook(this.hookName); + } + /** + * Makes a copy of this data type that can be included somewhere else. + * + * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. + * + * @return {YXmlHook} + */ + clone() { + const el = new _YXmlHook(this.hookName); + this.forEach((value, key) => { + el.set(key, value); + }); + return el; + } + /** + * Creates a Dom Element that mirrors this YXmlElement. + * + * @param {Document} [_document=document] The document object (you must define + * this when calling this method in + * nodejs) + * @param {Object.} [hooks] Optional property to customize how hooks + * are presented in the DOM + * @param {any} [binding] You should not set this property. This is + * used if DomBinding wants to create a + * association to the created DOM type + * @return {Element} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} + * + * @public + */ + toDOM(_document = document, hooks = {}, binding) { + const hook = hooks[this.hookName]; + let dom; + if (hook !== void 0) { + dom = hook.createDom(this); + } else { + dom = document.createElement(this.hookName); + } + dom.setAttribute("data-yjs-hook", this.hookName); + if (binding !== void 0) { + binding._createAssociation(dom, this); + } + return dom; + } + /** + * Transform the properties of this type to binary and write it to an + * BinaryEncoder. + * + * This is called when this Item is sent to a remote peer. + * + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. + */ + _write(encoder) { + encoder.writeTypeRef(YXmlHookRefID); + encoder.writeKey(this.hookName); + } +}; +var readYXmlHook = (decoder) => new YXmlHook(decoder.readKey()); +var YXmlText = class _YXmlText extends YText { + /** + * @type {YXmlElement|YXmlText|null} + */ + get nextSibling() { + const n = this._item ? this._item.next : null; + return n ? ( + /** @type {YXmlElement|YXmlText} */ + /** @type {ContentType} */ + n.content.type + ) : null; + } + /** + * @type {YXmlElement|YXmlText|null} + */ + get prevSibling() { + const n = this._item ? this._item.prev : null; + return n ? ( + /** @type {YXmlElement|YXmlText} */ + /** @type {ContentType} */ + n.content.type + ) : null; + } + _copy() { + return new _YXmlText(); + } + /** + * Makes a copy of this data type that can be included somewhere else. + * + * Note that the content is only readable _after_ it has been included somewhere in the Ydoc. + * + * @return {YXmlText} + */ + clone() { + const text2 = new _YXmlText(); + text2.applyDelta(this.toDelta()); + return text2; + } + /** + * Creates a Dom Element that mirrors this YXmlText. + * + * @param {Document} [_document=document] The document object (you must define + * this when calling this method in + * nodejs) + * @param {Object} [hooks] Optional property to customize how hooks + * are presented in the DOM + * @param {any} [binding] You should not set this property. This is + * used if DomBinding wants to create a + * association to the created DOM type. + * @return {Text} The {@link https://developer.mozilla.org/en-US/docs/Web/API/Element|Dom Element} + * + * @public + */ + toDOM(_document = document, hooks, binding) { + const dom = _document.createTextNode(this.toString()); + if (binding !== void 0) { + binding._createAssociation(dom, this); + } + return dom; + } + toString() { + return this.toDelta().map((delta) => { + const nestedNodes = []; + for (const nodeName in delta.attributes) { + const attrs = []; + for (const key in delta.attributes[nodeName]) { + attrs.push({ key, value: delta.attributes[nodeName][key] }); + } + attrs.sort((a, b2) => a.key < b2.key ? -1 : 1); + nestedNodes.push({ nodeName, attrs }); + } + nestedNodes.sort((a, b2) => a.nodeName < b2.nodeName ? -1 : 1); + let str = ""; + for (let i = 0; i < nestedNodes.length; i++) { + const node = nestedNodes[i]; + str += `<${node.nodeName}`; + for (let j2 = 0; j2 < node.attrs.length; j2++) { + const attr = node.attrs[j2]; + str += ` ${attr.key}="${attr.value}"`; + } + str += ">"; + } + str += delta.insert; + for (let i = nestedNodes.length - 1; i >= 0; i--) { + str += ``; + } + return str; + }).join(""); + } + /** + * @return {string} + */ + toJSON() { + return this.toString(); + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + */ + _write(encoder) { + encoder.writeTypeRef(YXmlTextRefID); + } +}; +var readYXmlText = (decoder) => new YXmlText(); +var AbstractStruct = class { + /** + * @param {ID} id + * @param {number} length + */ + constructor(id2, length2) { + this.id = id2; + this.length = length2; + } + /** + * @type {boolean} + */ + get deleted() { + throw methodUnimplemented(); + } + /** + * Merge this struct with the item to the right. + * This method is already assuming that `this.id.clock + this.length === this.id.clock`. + * Also this method does *not* remove right from StructStore! + * @param {AbstractStruct} right + * @return {boolean} whether this merged with right + */ + mergeWith(right) { + return false; + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. + * @param {number} offset + * @param {number} encodingRef + */ + write(encoder, offset, encodingRef) { + throw methodUnimplemented(); + } + /** + * @param {Transaction} transaction + * @param {number} offset + */ + integrate(transaction, offset) { + throw methodUnimplemented(); + } +}; +var structGCRefNumber = 0; +var GC = class extends AbstractStruct { + get deleted() { + return true; + } + delete() { + } + /** + * @param {GC} right + * @return {boolean} + */ + mergeWith(right) { + if (this.constructor !== right.constructor) { + return false; + } + this.length += right.length; + return true; + } + /** + * @param {Transaction} transaction + * @param {number} offset + */ + integrate(transaction, offset) { + if (offset > 0) { + this.id.clock += offset; + this.length -= offset; + } + addStruct(transaction.doc.store, this); + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + encoder.writeInfo(structGCRefNumber); + encoder.writeLen(this.length - offset); + } + /** + * @param {Transaction} transaction + * @param {StructStore} store + * @return {null | number} + */ + getMissing(transaction, store) { + return null; + } +}; +var ContentBinary = class _ContentBinary { + /** + * @param {Uint8Array} content + */ + constructor(content) { + this.content = content; + } + /** + * @return {number} + */ + getLength() { + return 1; + } + /** + * @return {Array} + */ + getContent() { + return [this.content]; + } + /** + * @return {boolean} + */ + isCountable() { + return true; + } + /** + * @return {ContentBinary} + */ + copy() { + return new _ContentBinary(this.content); + } + /** + * @param {number} offset + * @return {ContentBinary} + */ + splice(offset) { + throw methodUnimplemented(); + } + /** + * @param {ContentBinary} right + * @return {boolean} + */ + mergeWith(right) { + return false; + } + /** + * @param {Transaction} transaction + * @param {Item} item + */ + integrate(transaction, item) { + } + /** + * @param {Transaction} transaction + */ + delete(transaction) { + } + /** + * @param {StructStore} store + */ + gc(store) { + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + encoder.writeBuf(this.content); + } + /** + * @return {number} + */ + getRef() { + return 3; + } +}; +var readContentBinary = (decoder) => new ContentBinary(decoder.readBuf()); +var ContentDeleted = class _ContentDeleted { + /** + * @param {number} len + */ + constructor(len) { + this.len = len; + } + /** + * @return {number} + */ + getLength() { + return this.len; + } + /** + * @return {Array} + */ + getContent() { + return []; + } + /** + * @return {boolean} + */ + isCountable() { + return false; + } + /** + * @return {ContentDeleted} + */ + copy() { + return new _ContentDeleted(this.len); + } + /** + * @param {number} offset + * @return {ContentDeleted} + */ + splice(offset) { + const right = new _ContentDeleted(this.len - offset); + this.len = offset; + return right; + } + /** + * @param {ContentDeleted} right + * @return {boolean} + */ + mergeWith(right) { + this.len += right.len; + return true; + } + /** + * @param {Transaction} transaction + * @param {Item} item + */ + integrate(transaction, item) { + addToDeleteSet(transaction.deleteSet, item.id.client, item.id.clock, this.len); + item.markDeleted(); + } + /** + * @param {Transaction} transaction + */ + delete(transaction) { + } + /** + * @param {StructStore} store + */ + gc(store) { + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + encoder.writeLen(this.len - offset); + } + /** + * @return {number} + */ + getRef() { + return 1; + } +}; +var readContentDeleted = (decoder) => new ContentDeleted(decoder.readLen()); +var createDocFromOpts = (guid, opts) => new Doc({ guid, ...opts, shouldLoad: opts.shouldLoad || opts.autoLoad || false }); +var ContentDoc = class _ContentDoc { + /** + * @param {Doc} doc + */ + constructor(doc4) { + if (doc4._item) { + console.error("This document was already integrated as a sub-document. You should create a second instance instead with the same guid."); + } + this.doc = doc4; + const opts = {}; + this.opts = opts; + if (!doc4.gc) { + opts.gc = false; + } + if (doc4.autoLoad) { + opts.autoLoad = true; + } + if (doc4.meta !== null) { + opts.meta = doc4.meta; + } + } + /** + * @return {number} + */ + getLength() { + return 1; + } + /** + * @return {Array} + */ + getContent() { + return [this.doc]; + } + /** + * @return {boolean} + */ + isCountable() { + return true; + } + /** + * @return {ContentDoc} + */ + copy() { + return new _ContentDoc(createDocFromOpts(this.doc.guid, this.opts)); + } + /** + * @param {number} offset + * @return {ContentDoc} + */ + splice(offset) { + throw methodUnimplemented(); + } + /** + * @param {ContentDoc} right + * @return {boolean} + */ + mergeWith(right) { + return false; + } + /** + * @param {Transaction} transaction + * @param {Item} item + */ + integrate(transaction, item) { + this.doc._item = item; + transaction.subdocsAdded.add(this.doc); + if (this.doc.shouldLoad) { + transaction.subdocsLoaded.add(this.doc); + } + } + /** + * @param {Transaction} transaction + */ + delete(transaction) { + if (transaction.subdocsAdded.has(this.doc)) { + transaction.subdocsAdded.delete(this.doc); + } else { + transaction.subdocsRemoved.add(this.doc); + } + } + /** + * @param {StructStore} store + */ + gc(store) { + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + encoder.writeString(this.doc.guid); + encoder.writeAny(this.opts); + } + /** + * @return {number} + */ + getRef() { + return 9; + } +}; +var readContentDoc = (decoder) => new ContentDoc(createDocFromOpts(decoder.readString(), decoder.readAny())); +var ContentEmbed = class _ContentEmbed { + /** + * @param {Object} embed + */ + constructor(embed) { + this.embed = embed; + } + /** + * @return {number} + */ + getLength() { + return 1; + } + /** + * @return {Array} + */ + getContent() { + return [this.embed]; + } + /** + * @return {boolean} + */ + isCountable() { + return true; + } + /** + * @return {ContentEmbed} + */ + copy() { + return new _ContentEmbed(this.embed); + } + /** + * @param {number} offset + * @return {ContentEmbed} + */ + splice(offset) { + throw methodUnimplemented(); + } + /** + * @param {ContentEmbed} right + * @return {boolean} + */ + mergeWith(right) { + return false; + } + /** + * @param {Transaction} transaction + * @param {Item} item + */ + integrate(transaction, item) { + } + /** + * @param {Transaction} transaction + */ + delete(transaction) { + } + /** + * @param {StructStore} store + */ + gc(store) { + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + encoder.writeJSON(this.embed); + } + /** + * @return {number} + */ + getRef() { + return 5; + } +}; +var readContentEmbed = (decoder) => new ContentEmbed(decoder.readJSON()); +var ContentFormat = class _ContentFormat { + /** + * @param {string} key + * @param {Object} value + */ + constructor(key, value) { + this.key = key; + this.value = value; + } + /** + * @return {number} + */ + getLength() { + return 1; + } + /** + * @return {Array} + */ + getContent() { + return []; + } + /** + * @return {boolean} + */ + isCountable() { + return false; + } + /** + * @return {ContentFormat} + */ + copy() { + return new _ContentFormat(this.key, this.value); + } + /** + * @param {number} _offset + * @return {ContentFormat} + */ + splice(_offset) { + throw methodUnimplemented(); + } + /** + * @param {ContentFormat} _right + * @return {boolean} + */ + mergeWith(_right) { + return false; + } + /** + * @param {Transaction} _transaction + * @param {Item} item + */ + integrate(_transaction, item) { + const p = ( + /** @type {YText} */ + item.parent + ); + p._searchMarker = null; + p._hasFormatting = true; + } + /** + * @param {Transaction} transaction + */ + delete(transaction) { + } + /** + * @param {StructStore} store + */ + gc(store) { + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + encoder.writeKey(this.key); + encoder.writeJSON(this.value); + } + /** + * @return {number} + */ + getRef() { + return 6; + } +}; +var readContentFormat = (decoder) => new ContentFormat(decoder.readKey(), decoder.readJSON()); +var ContentJSON = class _ContentJSON { + /** + * @param {Array} arr + */ + constructor(arr) { + this.arr = arr; + } + /** + * @return {number} + */ + getLength() { + return this.arr.length; + } + /** + * @return {Array} + */ + getContent() { + return this.arr; + } + /** + * @return {boolean} + */ + isCountable() { + return true; + } + /** + * @return {ContentJSON} + */ + copy() { + return new _ContentJSON(this.arr); + } + /** + * @param {number} offset + * @return {ContentJSON} + */ + splice(offset) { + const right = new _ContentJSON(this.arr.slice(offset)); + this.arr = this.arr.slice(0, offset); + return right; + } + /** + * @param {ContentJSON} right + * @return {boolean} + */ + mergeWith(right) { + this.arr = this.arr.concat(right.arr); + return true; + } + /** + * @param {Transaction} transaction + * @param {Item} item + */ + integrate(transaction, item) { + } + /** + * @param {Transaction} transaction + */ + delete(transaction) { + } + /** + * @param {StructStore} store + */ + gc(store) { + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + const len = this.arr.length; + encoder.writeLen(len - offset); + for (let i = offset; i < len; i++) { + const c = this.arr[i]; + encoder.writeString(c === void 0 ? "undefined" : JSON.stringify(c)); + } + } + /** + * @return {number} + */ + getRef() { + return 2; + } +}; +var readContentJSON = (decoder) => { + const len = decoder.readLen(); + const cs = []; + for (let i = 0; i < len; i++) { + const c = decoder.readString(); + if (c === "undefined") { + cs.push(void 0); + } else { + cs.push(JSON.parse(c)); + } + } + return new ContentJSON(cs); +}; +var isDevMode = getVariable("node_env") === "development"; +var ContentAny = class _ContentAny { + /** + * @param {Array} arr + */ + constructor(arr) { + this.arr = arr; + isDevMode && deepFreeze(arr); + } + /** + * @return {number} + */ + getLength() { + return this.arr.length; + } + /** + * @return {Array} + */ + getContent() { + return this.arr; + } + /** + * @return {boolean} + */ + isCountable() { + return true; + } + /** + * @return {ContentAny} + */ + copy() { + return new _ContentAny(this.arr); + } + /** + * @param {number} offset + * @return {ContentAny} + */ + splice(offset) { + const right = new _ContentAny(this.arr.slice(offset)); + this.arr = this.arr.slice(0, offset); + return right; + } + /** + * @param {ContentAny} right + * @return {boolean} + */ + mergeWith(right) { + this.arr = this.arr.concat(right.arr); + return true; + } + /** + * @param {Transaction} transaction + * @param {Item} item + */ + integrate(transaction, item) { + } + /** + * @param {Transaction} transaction + */ + delete(transaction) { + } + /** + * @param {StructStore} store + */ + gc(store) { + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + const len = this.arr.length; + encoder.writeLen(len - offset); + for (let i = offset; i < len; i++) { + const c = this.arr[i]; + encoder.writeAny(c); + } + } + /** + * @return {number} + */ + getRef() { + return 8; + } +}; +var readContentAny = (decoder) => { + const len = decoder.readLen(); + const cs = []; + for (let i = 0; i < len; i++) { + cs.push(decoder.readAny()); + } + return new ContentAny(cs); +}; +var ContentString = class _ContentString { + /** + * @param {string} str + */ + constructor(str) { + this.str = str; + } + /** + * @return {number} + */ + getLength() { + return this.str.length; + } + /** + * @return {Array} + */ + getContent() { + return this.str.split(""); + } + /** + * @return {boolean} + */ + isCountable() { + return true; + } + /** + * @return {ContentString} + */ + copy() { + return new _ContentString(this.str); + } + /** + * @param {number} offset + * @return {ContentString} + */ + splice(offset) { + const right = new _ContentString(this.str.slice(offset)); + this.str = this.str.slice(0, offset); + const firstCharCode = this.str.charCodeAt(offset - 1); + if (firstCharCode >= 55296 && firstCharCode <= 56319) { + this.str = this.str.slice(0, offset - 1) + "\uFFFD"; + right.str = "\uFFFD" + right.str.slice(1); + } + return right; + } + /** + * @param {ContentString} right + * @return {boolean} + */ + mergeWith(right) { + this.str += right.str; + return true; + } + /** + * @param {Transaction} transaction + * @param {Item} item + */ + integrate(transaction, item) { + } + /** + * @param {Transaction} transaction + */ + delete(transaction) { + } + /** + * @param {StructStore} store + */ + gc(store) { + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + encoder.writeString(offset === 0 ? this.str : this.str.slice(offset)); + } + /** + * @return {number} + */ + getRef() { + return 4; + } +}; +var readContentString = (decoder) => new ContentString(decoder.readString()); +var typeRefs = [ + readYArray, + readYMap, + readYText, + readYXmlElement, + readYXmlFragment, + readYXmlHook, + readYXmlText +]; +var YArrayRefID = 0; +var YMapRefID = 1; +var YTextRefID = 2; +var YXmlElementRefID = 3; +var YXmlFragmentRefID = 4; +var YXmlHookRefID = 5; +var YXmlTextRefID = 6; +var ContentType = class _ContentType { + /** + * @param {AbstractType} type + */ + constructor(type) { + this.type = type; + } + /** + * @return {number} + */ + getLength() { + return 1; + } + /** + * @return {Array} + */ + getContent() { + return [this.type]; + } + /** + * @return {boolean} + */ + isCountable() { + return true; + } + /** + * @return {ContentType} + */ + copy() { + return new _ContentType(this.type._copy()); + } + /** + * @param {number} offset + * @return {ContentType} + */ + splice(offset) { + throw methodUnimplemented(); + } + /** + * @param {ContentType} right + * @return {boolean} + */ + mergeWith(right) { + return false; + } + /** + * @param {Transaction} transaction + * @param {Item} item + */ + integrate(transaction, item) { + this.type._integrate(transaction.doc, item); + } + /** + * @param {Transaction} transaction + */ + delete(transaction) { + let item = this.type._start; + while (item !== null) { + if (!item.deleted) { + item.delete(transaction); + } else if (item.id.clock < (transaction.beforeState.get(item.id.client) || 0)) { + transaction._mergeStructs.push(item); + } + item = item.right; + } + this.type._map.forEach((item2) => { + if (!item2.deleted) { + item2.delete(transaction); + } else if (item2.id.clock < (transaction.beforeState.get(item2.id.client) || 0)) { + transaction._mergeStructs.push(item2); + } + }); + transaction.changed.delete(this.type); + } + /** + * @param {StructStore} store + */ + gc(store) { + let item = this.type._start; + while (item !== null) { + item.gc(store, true); + item = item.right; + } + this.type._start = null; + this.type._map.forEach( + /** @param {Item | null} item */ + (item2) => { + while (item2 !== null) { + item2.gc(store, true); + item2 = item2.left; + } + } + ); + this.type._map = /* @__PURE__ */ new Map(); + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + this.type._write(encoder); + } + /** + * @return {number} + */ + getRef() { + return 7; + } +}; +var readContentType = (decoder) => new ContentType(typeRefs[decoder.readTypeRef()](decoder)); +var followRedone = (store, id2) => { + let nextID = id2; + let diff = 0; + let item; + do { + if (diff > 0) { + nextID = createID(nextID.client, nextID.clock + diff); + } + item = getItem(store, nextID); + diff = nextID.clock - item.id.clock; + nextID = item.redone; + } while (nextID !== null && item instanceof Item2); + return { + item, + diff + }; +}; +var keepItem = (item, keep) => { + while (item !== null && item.keep !== keep) { + item.keep = keep; + item = /** @type {AbstractType} */ + item.parent._item; + } +}; +var splitItem = (transaction, leftItem, diff) => { + const { client, clock } = leftItem.id; + const rightItem = new Item2( + createID(client, clock + diff), + leftItem, + createID(client, clock + diff - 1), + leftItem.right, + leftItem.rightOrigin, + leftItem.parent, + leftItem.parentSub, + leftItem.content.splice(diff) + ); + if (leftItem.deleted) { + rightItem.markDeleted(); + } + if (leftItem.keep) { + rightItem.keep = true; + } + if (leftItem.redone !== null) { + rightItem.redone = createID(leftItem.redone.client, leftItem.redone.clock + diff); + } + leftItem.right = rightItem; + if (rightItem.right !== null) { + rightItem.right.left = rightItem; + } + transaction._mergeStructs.push(rightItem); + if (rightItem.parentSub !== null && rightItem.right === null) { + rightItem.parent._map.set(rightItem.parentSub, rightItem); + } + leftItem.length = diff; + return rightItem; +}; +var isDeletedByUndoStack = (stack, id2) => some( + stack, + /** @param {StackItem} s */ + (s) => isDeleted(s.deletions, id2) +); +var redoItem = (transaction, item, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) => { + const doc4 = transaction.doc; + const store = doc4.store; + const ownClientID = doc4.clientID; + const redone = item.redone; + if (redone !== null) { + return getItemCleanStart(transaction, redone); + } + let parentItem = ( + /** @type {AbstractType} */ + item.parent._item + ); + let left = null; + let right; + if (parentItem !== null && parentItem.deleted === true) { + if (parentItem.redone === null && (!redoitems.has(parentItem) || redoItem(transaction, parentItem, redoitems, itemsToDelete, ignoreRemoteMapChanges, um) === null)) { + return null; + } + while (parentItem.redone !== null) { + parentItem = getItemCleanStart(transaction, parentItem.redone); + } + } + const parentType = parentItem === null ? ( + /** @type {AbstractType} */ + item.parent + ) : ( + /** @type {ContentType} */ + parentItem.content.type + ); + if (item.parentSub === null) { + left = item.left; + right = item; + while (left !== null) { + let leftTrace = left; + while (leftTrace !== null && /** @type {AbstractType} */ + leftTrace.parent._item !== parentItem) { + leftTrace = leftTrace.redone === null ? null : getItemCleanStart(transaction, leftTrace.redone); + } + if (leftTrace !== null && /** @type {AbstractType} */ + leftTrace.parent._item === parentItem) { + left = leftTrace; + break; + } + left = left.left; + } + while (right !== null) { + let rightTrace = right; + while (rightTrace !== null && /** @type {AbstractType} */ + rightTrace.parent._item !== parentItem) { + rightTrace = rightTrace.redone === null ? null : getItemCleanStart(transaction, rightTrace.redone); + } + if (rightTrace !== null && /** @type {AbstractType} */ + rightTrace.parent._item === parentItem) { + right = rightTrace; + break; + } + right = right.right; + } + } else { + right = null; + if (item.right && !ignoreRemoteMapChanges) { + left = item; + while (left !== null && left.right !== null && (left.right.redone || isDeleted(itemsToDelete, left.right.id) || isDeletedByUndoStack(um.undoStack, left.right.id) || isDeletedByUndoStack(um.redoStack, left.right.id))) { + left = left.right; + while (left.redone) left = getItemCleanStart(transaction, left.redone); + } + if (left && left.right !== null) { + return null; + } + } else { + left = parentType._map.get(item.parentSub) || null; + } + if (left !== null && /** @type {AbstractType} */ + left.parent._item !== parentItem) { + left = parentType._map.get(item.parentSub) || null; + } + } + const nextClock = getState(store, ownClientID); + const nextId = createID(ownClientID, nextClock); + const redoneItem = new Item2( + nextId, + left, + left && left.lastId, + right, + right && right.id, + parentType, + item.parentSub, + item.content.copy() + ); + item.redone = nextId; + keepItem(redoneItem, true); + redoneItem.integrate(transaction, 0); + return redoneItem; +}; +var Item2 = class _Item extends AbstractStruct { + /** + * @param {ID} id + * @param {Item | null} left + * @param {ID | null} origin + * @param {Item | null} right + * @param {ID | null} rightOrigin + * @param {AbstractType|ID|null} parent Is a type if integrated, is null if it is possible to copy parent from left or right, is ID before integration to search for it. + * @param {string | null} parentSub + * @param {AbstractContent} content + */ + constructor(id2, left, origin, right, rightOrigin, parent, parentSub, content) { + super(id2, content.getLength()); + this.origin = origin; + this.left = left; + this.right = right; + this.rightOrigin = rightOrigin; + this.parent = parent; + this.parentSub = parentSub; + this.redone = null; + this.content = content; + this.info = this.content.isCountable() ? BIT2 : 0; + } + /** + * This is used to mark the item as an indexed fast-search marker + * + * @type {boolean} + */ + set marker(isMarked) { + if ((this.info & BIT4) > 0 !== isMarked) { + this.info ^= BIT4; + } + } + get marker() { + return (this.info & BIT4) > 0; + } + /** + * If true, do not garbage collect this Item. + */ + get keep() { + return (this.info & BIT1) > 0; + } + set keep(doKeep) { + if (this.keep !== doKeep) { + this.info ^= BIT1; + } + } + get countable() { + return (this.info & BIT2) > 0; + } + /** + * Whether this item was deleted or not. + * @type {Boolean} + */ + get deleted() { + return (this.info & BIT3) > 0; + } + set deleted(doDelete) { + if (this.deleted !== doDelete) { + this.info ^= BIT3; + } + } + markDeleted() { + this.info |= BIT3; + } + /** + * Return the creator clientID of the missing op or define missing items and return null. + * + * @param {Transaction} transaction + * @param {StructStore} store + * @return {null | number} + */ + getMissing(transaction, store) { + if (this.origin && this.origin.client !== this.id.client && this.origin.clock >= getState(store, this.origin.client)) { + return this.origin.client; + } + if (this.rightOrigin && this.rightOrigin.client !== this.id.client && this.rightOrigin.clock >= getState(store, this.rightOrigin.client)) { + return this.rightOrigin.client; + } + if (this.parent && this.parent.constructor === ID && this.id.client !== this.parent.client && this.parent.clock >= getState(store, this.parent.client)) { + return this.parent.client; + } + if (this.origin) { + this.left = getItemCleanEnd(transaction, store, this.origin); + this.origin = this.left.lastId; + } + if (this.rightOrigin) { + this.right = getItemCleanStart(transaction, this.rightOrigin); + this.rightOrigin = this.right.id; + } + if (this.left && this.left.constructor === GC || this.right && this.right.constructor === GC) { + this.parent = null; + } else if (!this.parent) { + if (this.left && this.left.constructor === _Item) { + this.parent = this.left.parent; + this.parentSub = this.left.parentSub; + } else if (this.right && this.right.constructor === _Item) { + this.parent = this.right.parent; + this.parentSub = this.right.parentSub; + } + } else if (this.parent.constructor === ID) { + const parentItem = getItem(store, this.parent); + if (parentItem.constructor === GC) { + this.parent = null; + } else { + this.parent = /** @type {ContentType} */ + parentItem.content.type; + } + } + return null; + } + /** + * @param {Transaction} transaction + * @param {number} offset + */ + integrate(transaction, offset) { + if (offset > 0) { + this.id.clock += offset; + this.left = getItemCleanEnd(transaction, transaction.doc.store, createID(this.id.client, this.id.clock - 1)); + this.origin = this.left.lastId; + this.content = this.content.splice(offset); + this.length -= offset; + } + if (this.parent) { + if (!this.left && (!this.right || this.right.left !== null) || this.left && this.left.right !== this.right) { + let left = this.left; + let o; + if (left !== null) { + o = left.right; + } else if (this.parentSub !== null) { + o = /** @type {AbstractType} */ + this.parent._map.get(this.parentSub) || null; + while (o !== null && o.left !== null) { + o = o.left; + } + } else { + o = /** @type {AbstractType} */ + this.parent._start; + } + const conflictingItems = /* @__PURE__ */ new Set(); + const itemsBeforeOrigin = /* @__PURE__ */ new Set(); + while (o !== null && o !== this.right) { + itemsBeforeOrigin.add(o); + conflictingItems.add(o); + if (compareIDs(this.origin, o.origin)) { + if (o.id.client < this.id.client) { + left = o; + conflictingItems.clear(); + } else if (compareIDs(this.rightOrigin, o.rightOrigin)) { + break; + } + } else if (o.origin !== null && itemsBeforeOrigin.has(getItem(transaction.doc.store, o.origin))) { + if (!conflictingItems.has(getItem(transaction.doc.store, o.origin))) { + left = o; + conflictingItems.clear(); + } + } else { + break; + } + o = o.right; + } + this.left = left; + } + if (this.left !== null) { + const right = this.left.right; + this.right = right; + this.left.right = this; + } else { + let r; + if (this.parentSub !== null) { + r = /** @type {AbstractType} */ + this.parent._map.get(this.parentSub) || null; + while (r !== null && r.left !== null) { + r = r.left; + } + } else { + r = /** @type {AbstractType} */ + this.parent._start; + this.parent._start = this; + } + this.right = r; + } + if (this.right !== null) { + this.right.left = this; + } else if (this.parentSub !== null) { + this.parent._map.set(this.parentSub, this); + if (this.left !== null) { + this.left.delete(transaction); + } + } + if (this.parentSub === null && this.countable && !this.deleted) { + this.parent._length += this.length; + } + addStruct(transaction.doc.store, this); + this.content.integrate(transaction, this); + addChangedTypeToTransaction( + transaction, + /** @type {AbstractType} */ + this.parent, + this.parentSub + ); + if ( + /** @type {AbstractType} */ + this.parent._item !== null && /** @type {AbstractType} */ + this.parent._item.deleted || this.parentSub !== null && this.right !== null + ) { + this.delete(transaction); + } + } else { + new GC(this.id, this.length).integrate(transaction, 0); + } + } + /** + * Returns the next non-deleted item + */ + get next() { + let n = this.right; + while (n !== null && n.deleted) { + n = n.right; + } + return n; + } + /** + * Returns the previous non-deleted item + */ + get prev() { + let n = this.left; + while (n !== null && n.deleted) { + n = n.left; + } + return n; + } + /** + * Computes the last content address of this Item. + */ + get lastId() { + return this.length === 1 ? this.id : createID(this.id.client, this.id.clock + this.length - 1); + } + /** + * Try to merge two items + * + * @param {Item} right + * @return {boolean} + */ + mergeWith(right) { + if (this.constructor === right.constructor && compareIDs(right.origin, this.lastId) && this.right === right && compareIDs(this.rightOrigin, right.rightOrigin) && this.id.client === right.id.client && this.id.clock + this.length === right.id.clock && this.deleted === right.deleted && this.redone === null && right.redone === null && this.content.constructor === right.content.constructor && this.content.mergeWith(right.content)) { + const searchMarker = ( + /** @type {AbstractType} */ + this.parent._searchMarker + ); + if (searchMarker) { + searchMarker.forEach((marker) => { + if (marker.p === right) { + marker.p = this; + if (!this.deleted && this.countable) { + marker.index -= this.length; + } + } + }); + } + if (right.keep) { + this.keep = true; + } + this.right = right.right; + if (this.right !== null) { + this.right.left = this; + } + this.length += right.length; + return true; + } + return false; + } + /** + * Mark this Item as deleted. + * + * @param {Transaction} transaction + */ + delete(transaction) { + if (!this.deleted) { + const parent = ( + /** @type {AbstractType} */ + this.parent + ); + if (this.countable && this.parentSub === null) { + parent._length -= this.length; + } + this.markDeleted(); + addToDeleteSet(transaction.deleteSet, this.id.client, this.id.clock, this.length); + addChangedTypeToTransaction(transaction, parent, this.parentSub); + this.content.delete(transaction); + } + } + /** + * @param {StructStore} store + * @param {boolean} parentGCd + */ + gc(store, parentGCd) { + if (!this.deleted) { + throw unexpectedCase(); + } + this.content.gc(store); + if (parentGCd) { + replaceStruct(store, this, new GC(this.id, this.length)); + } else { + this.content = new ContentDeleted(this.length); + } + } + /** + * Transform the properties of this type to binary and write it to an + * BinaryEncoder. + * + * This is called when this Item is sent to a remote peer. + * + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder The encoder to write data to. + * @param {number} offset + */ + write(encoder, offset) { + const origin = offset > 0 ? createID(this.id.client, this.id.clock + offset - 1) : this.origin; + const rightOrigin = this.rightOrigin; + const parentSub = this.parentSub; + const info = this.content.getRef() & BITS5 | (origin === null ? 0 : BIT8) | // origin is defined + (rightOrigin === null ? 0 : BIT7) | // right origin is defined + (parentSub === null ? 0 : BIT6); + encoder.writeInfo(info); + if (origin !== null) { + encoder.writeLeftID(origin); + } + if (rightOrigin !== null) { + encoder.writeRightID(rightOrigin); + } + if (origin === null && rightOrigin === null) { + const parent = ( + /** @type {AbstractType} */ + this.parent + ); + if (parent._item !== void 0) { + const parentItem = parent._item; + if (parentItem === null) { + const ykey = findRootTypeKey(parent); + encoder.writeParentInfo(true); + encoder.writeString(ykey); + } else { + encoder.writeParentInfo(false); + encoder.writeLeftID(parentItem.id); + } + } else if (parent.constructor === String) { + encoder.writeParentInfo(true); + encoder.writeString(parent); + } else if (parent.constructor === ID) { + encoder.writeParentInfo(false); + encoder.writeLeftID(parent); + } else { + unexpectedCase(); + } + if (parentSub !== null) { + encoder.writeString(parentSub); + } + } + this.content.write(encoder, offset); + } +}; +var readItemContent = (decoder, info) => contentRefs[info & BITS5](decoder); +var contentRefs = [ + () => { + unexpectedCase(); + }, + // GC is not ItemContent + readContentDeleted, + // 1 + readContentJSON, + // 2 + readContentBinary, + // 3 + readContentString, + // 4 + readContentEmbed, + // 5 + readContentFormat, + // 6 + readContentType, + // 7 + readContentAny, + // 8 + readContentDoc, + // 9 + () => { + unexpectedCase(); + } + // 10 - Skip is not ItemContent +]; +var structSkipRefNumber = 10; +var Skip = class extends AbstractStruct { + get deleted() { + return true; + } + delete() { + } + /** + * @param {Skip} right + * @return {boolean} + */ + mergeWith(right) { + if (this.constructor !== right.constructor) { + return false; + } + this.length += right.length; + return true; + } + /** + * @param {Transaction} transaction + * @param {number} offset + */ + integrate(transaction, offset) { + unexpectedCase(); + } + /** + * @param {UpdateEncoderV1 | UpdateEncoderV2} encoder + * @param {number} offset + */ + write(encoder, offset) { + encoder.writeInfo(structSkipRefNumber); + writeVarUint(encoder.restEncoder, this.length - offset); + } + /** + * @param {Transaction} transaction + * @param {StructStore} store + * @return {null | number} + */ + getMissing(transaction, store) { + return null; + } +}; +var glo = ( + /** @type {any} */ + typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {} +); +var importIdentifier = "__ $YJS$ __"; +if (glo[importIdentifier] === true) { + console.error("Yjs was already imported. This breaks constructor checks and will lead to issues! - https://github.com/yjs/yjs/issues/438"); +} +glo[importIdentifier] = true; + +// ../../node_modules/.pnpm/y-protocols@1.0.7_yjs@13.6.31/node_modules/y-protocols/awareness.js +var outdatedTimeout = 3e4; +var Awareness = class extends Observable { + /** + * @param {Y.Doc} doc + */ + constructor(doc4) { + super(); + this.doc = doc4; + this.clientID = doc4.clientID; + this.states = /* @__PURE__ */ new Map(); + this.meta = /* @__PURE__ */ new Map(); + this._checkInterval = /** @type {any} */ + setInterval(() => { + const now = getUnixTime(); + if (this.getLocalState() !== null && outdatedTimeout / 2 <= now - /** @type {{lastUpdated:number}} */ + this.meta.get(this.clientID).lastUpdated) { + this.setLocalState(this.getLocalState()); + } + const remove2 = []; + this.meta.forEach((meta, clientid) => { + if (clientid !== this.clientID && outdatedTimeout <= now - meta.lastUpdated && this.states.has(clientid)) { + remove2.push(clientid); + } + }); + if (remove2.length > 0) { + removeAwarenessStates(this, remove2, "timeout"); + } + }, floor(outdatedTimeout / 10)); + doc4.on("destroy", () => { + this.destroy(); + }); + this.setLocalState({}); + } + destroy() { + this.emit("destroy", [this]); + this.setLocalState(null); + super.destroy(); + clearInterval(this._checkInterval); + } + /** + * @return {Object|null} + */ + getLocalState() { + return this.states.get(this.clientID) || null; + } + /** + * @param {Object|null} state + */ + setLocalState(state) { + const clientID = this.clientID; + const currLocalMeta = this.meta.get(clientID); + const clock = currLocalMeta === void 0 ? 0 : currLocalMeta.clock + 1; + const prevState = this.states.get(clientID); + if (state === null) { + this.states.delete(clientID); + } else { + this.states.set(clientID, state); + } + this.meta.set(clientID, { + clock, + lastUpdated: getUnixTime() + }); + const added = []; + const updated = []; + const filteredUpdated = []; + const removed = []; + if (state === null) { + removed.push(clientID); + } else if (prevState == null) { + if (state != null) { + added.push(clientID); + } + } else { + updated.push(clientID); + if (!equalityDeep(prevState, state)) { + filteredUpdated.push(clientID); + } + } + if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) { + this.emit("change", [{ added, updated: filteredUpdated, removed }, "local"]); + } + this.emit("update", [{ added, updated, removed }, "local"]); + } + /** + * @param {string} field + * @param {any} value + */ + setLocalStateField(field, value) { + const state = this.getLocalState(); + if (state !== null) { + this.setLocalState({ + ...state, + [field]: value + }); + } + } + /** + * @return {Map>} + */ + getStates() { + return this.states; + } +}; +var removeAwarenessStates = (awareness, clients, origin) => { + const removed = []; + for (let i = 0; i < clients.length; i++) { + const clientID = clients[i]; + if (awareness.states.has(clientID)) { + awareness.states.delete(clientID); + if (clientID === awareness.clientID) { + const curMeta = ( + /** @type {MetaClientState} */ + awareness.meta.get(clientID) + ); + awareness.meta.set(clientID, { + clock: curMeta.clock + 1, + lastUpdated: getUnixTime() + }); + } + removed.push(clientID); + } + } + if (removed.length > 0) { + awareness.emit("change", [{ added: [], updated: [], removed }, origin]); + awareness.emit("update", [{ added: [], updated: [], removed }, origin]); + } +}; +var encodeAwarenessUpdate = (awareness, clients, states = awareness.states) => { + const len = clients.length; + const encoder = createEncoder(); + writeVarUint(encoder, len); + for (let i = 0; i < len; i++) { + const clientID = clients[i]; + const state = states.get(clientID) || null; + const clock = ( + /** @type {MetaClientState} */ + awareness.meta.get(clientID).clock + ); + writeVarUint(encoder, clientID); + writeVarUint(encoder, clock); + writeVarString(encoder, JSON.stringify(state)); + } + return toUint8Array(encoder); +}; +var applyAwarenessUpdate = (awareness, update, origin) => { + const decoder = createDecoder(update); + const timestamp = getUnixTime(); + const added = []; + const updated = []; + const filteredUpdated = []; + const removed = []; + const len = readVarUint(decoder); + for (let i = 0; i < len; i++) { + const clientID = readVarUint(decoder); + let clock = readVarUint(decoder); + const state = JSON.parse(readVarString(decoder)); + const clientMeta = awareness.meta.get(clientID); + const prevState = awareness.states.get(clientID); + const currClock = clientMeta === void 0 ? 0 : clientMeta.clock; + if (currClock < clock || currClock === clock && state === null && awareness.states.has(clientID)) { + if (state === null) { + if (clientID === awareness.clientID && awareness.getLocalState() != null) { + clock++; + } else { + awareness.states.delete(clientID); + } + } else { + awareness.states.set(clientID, state); + } + awareness.meta.set(clientID, { + clock, + lastUpdated: timestamp + }); + if (clientMeta === void 0 && state !== null) { + added.push(clientID); + } else if (clientMeta !== void 0 && state === null) { + removed.push(clientID); + } else if (state !== null) { + if (!equalityDeep(state, prevState)) { + filteredUpdated.push(clientID); + } + updated.push(clientID); + } + } + } + if (added.length > 0 || filteredUpdated.length > 0 || removed.length > 0) { + awareness.emit("change", [{ + added, + updated: filteredUpdated, + removed + }, origin]); + } + if (added.length > 0 || updated.length > 0 || removed.length > 0) { + awareness.emit("update", [{ + added, + updated, + removed + }, origin]); + } +}; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/mutex.js +var createMutex = () => { + let token = true; + return (f, g2) => { + if (token) { + token = false; + try { + f(); + } finally { + token = true; + } + } else if (g2 !== void 0) { + g2(); + } + }; +}; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/diff.js +var highSurrogateRegex = /[\uD800-\uDBFF]/; +var lowSurrogateRegex = /[\uDC00-\uDFFF]/; +var simpleDiffString = (a, b2) => { + let left = 0; + let right = 0; + while (left < a.length && left < b2.length && a[left] === b2[left]) { + left++; + } + if (left > 0 && highSurrogateRegex.test(a[left - 1])) left--; + while (right + left < a.length && right + left < b2.length && a[a.length - right - 1] === b2[b2.length - right - 1]) { + right++; + } + if (right > 0 && lowSurrogateRegex.test(a[a.length - right])) right--; + return { + index: left, + remove: a.length - left - right, + insert: b2.slice(left, b2.length - right) + }; +}; +var simpleDiff = simpleDiffString; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/hash/sha256.js +var rotr = (w2, shift2) => w2 >>> shift2 | w2 << 32 - shift2; +var sum0to256 = (x2) => rotr(x2, 2) ^ rotr(x2, 13) ^ rotr(x2, 22); +var sum1to256 = (x2) => rotr(x2, 6) ^ rotr(x2, 11) ^ rotr(x2, 25); +var sigma0to256 = (x2) => rotr(x2, 7) ^ rotr(x2, 18) ^ x2 >>> 3; +var sigma1to256 = (x2) => rotr(x2, 17) ^ rotr(x2, 19) ^ x2 >>> 10; +var K = new Uint32Array([ + 1116352408, + 1899447441, + 3049323471, + 3921009573, + 961987163, + 1508970993, + 2453635748, + 2870763221, + 3624381080, + 310598401, + 607225278, + 1426881987, + 1925078388, + 2162078206, + 2614888103, + 3248222580, + 3835390401, + 4022224774, + 264347078, + 604807628, + 770255983, + 1249150122, + 1555081692, + 1996064986, + 2554220882, + 2821834349, + 2952996808, + 3210313671, + 3336571891, + 3584528711, + 113926993, + 338241895, + 666307205, + 773529912, + 1294757372, + 1396182291, + 1695183700, + 1986661051, + 2177026350, + 2456956037, + 2730485921, + 2820302411, + 3259730800, + 3345764771, + 3516065817, + 3600352804, + 4094571909, + 275423344, + 430227734, + 506948616, + 659060556, + 883997877, + 958139571, + 1322822218, + 1537002063, + 1747873779, + 1955562222, + 2024104815, + 2227730452, + 2361852424, + 2428436474, + 2756734187, + 3204031479, + 3329325298 +]); +var HINIT = new Uint32Array([ + 1779033703, + 3144134277, + 1013904242, + 2773480762, + 1359893119, + 2600822924, + 528734635, + 1541459225 +]); +var Hasher = class { + constructor() { + const buf = new ArrayBuffer(64 + 64 * 4); + this._H = new Uint32Array(buf, 0, 8); + this._H.set(HINIT); + this._W = new Uint32Array(buf, 64, 64); + } + _updateHash() { + const H2 = this._H; + const W2 = this._W; + for (let t = 16; t < 64; t++) { + W2[t] = sigma1to256(W2[t - 2]) + W2[t - 7] + sigma0to256(W2[t - 15]) + W2[t - 16]; + } + let a = H2[0]; + let b2 = H2[1]; + let c = H2[2]; + let d2 = H2[3]; + let e = H2[4]; + let f = H2[5]; + let g2 = H2[6]; + let h2 = H2[7]; + for (let tt3 = 0, T1, T2; tt3 < 64; tt3++) { + T1 = h2 + sum1to256(e) + (e & f ^ ~e & g2) + K[tt3] + W2[tt3] >>> 0; + T2 = sum0to256(a) + (a & b2 ^ a & c ^ b2 & c) >>> 0; + h2 = g2; + g2 = f; + f = e; + e = d2 + T1 >>> 0; + d2 = c; + c = b2; + b2 = a; + a = T1 + T2 >>> 0; + } + H2[0] += a; + H2[1] += b2; + H2[2] += c; + H2[3] += d2; + H2[4] += e; + H2[5] += f; + H2[6] += g2; + H2[7] += h2; + } + /** + * Returns a 32-byte hash. + * + * @param {Uint8Array} data + */ + digest(data) { + let i = 0; + for (; i + 56 <= data.length; ) { + let j3 = 0; + for (; j3 < 16 && i + 3 < data.length; j3++) { + this._W[j3] = data[i++] << 24 | data[i++] << 16 | data[i++] << 8 | data[i++]; + } + if (i % 64 !== 0) { + this._W.fill(0, j3, 16); + while (i < data.length) { + this._W[j3] |= data[i] << (3 - i % 4) * 8; + i++; + } + this._W[j3] |= BIT8 << (3 - i % 4) * 8; + } + this._updateHash(); + } + const isPaddedWith1 = i % 64 !== 0; + this._W.fill(0, 0, 16); + let j2 = 0; + for (; i < data.length; j2++) { + for (let ci = 3; ci >= 0 && i < data.length; ci--) { + this._W[j2] |= data[i++] << ci * 8; + } + } + if (!isPaddedWith1) { + this._W[j2 - (i % 4 === 0 ? 0 : 1)] |= BIT8 << (3 - i % 4) * 8; + } + this._W[14] = data.byteLength / BIT30; + this._W[15] = data.byteLength * 8; + this._updateHash(); + const dv = new Uint8Array(32); + for (let i2 = 0; i2 < this._H.length; i2++) { + for (let ci = 0; ci < 4; ci++) { + dv[i2 * 4 + ci] = this._H[i2] >>> (3 - ci) * 8; + } + } + return dv; + } +}; +var digest = (data) => new Hasher().digest(data); + +// ../../node_modules/.pnpm/@tiptap+y-tiptap@3.0.4_prosemirror-model@1.25.7_prosemirror-state@1.4.4_prosemirror-view@1.41_wvoac4aukupuym4gujml7mo5iq/node_modules/@tiptap/y-tiptap/dist/y-tiptap.js +var ySyncPluginKey = new PluginKey("y-sync"); +var yUndoPluginKey = new PluginKey("y-undo"); +var yCursorPluginKey = new PluginKey("yjs-cursor"); +var _convolute = (digest2) => { + const N2 = 6; + for (let i = N2; i < digest2.length; i++) { + digest2[i % N2] = digest2[i % N2] ^ digest2[i]; + } + return digest2.slice(0, N2); +}; +var hashOfJSON = (json) => toBase64(_convolute(digest(encodeAny(json)))); +var isVisible2 = (item, snapshot2) => snapshot2 === void 0 ? !item.deleted : snapshot2.sv.has(item.id.client) && /** @type {number} */ +snapshot2.sv.get(item.id.client) > item.id.clock && !isDeleted(snapshot2.ds, item.id); +var defaultColors = [{ light: "#ecd44433", dark: "#ecd444" }]; +var getUserColor = (colorMapping, colors, user) => { + if (!colorMapping.has(user)) { + if (colorMapping.size < colors.length) { + const usedColors = create2(); + colorMapping.forEach((color) => usedColors.add(color)); + colors = colors.filter((color) => !usedColors.has(color)); + } + colorMapping.set(user, oneOf(colors)); + } + return ( + /** @type {ColorDef} */ + colorMapping.get(user) + ); +}; +var ySyncPlugin = (yXmlFragment, { + colors = defaultColors, + colorMapping = /* @__PURE__ */ new Map(), + permanentUserData = null, + onFirstRender = () => { + }, + mapping +} = {}) => { + let initialContentChanged = false; + const binding = new ProsemirrorBinding(yXmlFragment, mapping); + const plugin = new Plugin({ + props: { + editable: (state) => { + const syncState = ySyncPluginKey.getState(state); + return syncState.snapshot == null && syncState.prevSnapshot == null; + } + }, + key: ySyncPluginKey, + state: { + /** + * @returns {any} + */ + init: (_initargs, _state) => { + return { + type: yXmlFragment, + doc: yXmlFragment.doc, + binding, + snapshot: null, + prevSnapshot: null, + isChangeOrigin: false, + isUndoRedoOperation: false, + addToHistory: true, + colors, + colorMapping, + permanentUserData + }; + }, + apply: (tr2, pluginState) => { + const change = tr2.getMeta(ySyncPluginKey); + if (change !== void 0) { + pluginState = Object.assign({}, pluginState); + for (const key in change) { + pluginState[key] = change[key]; + } + } + pluginState.addToHistory = tr2.getMeta("addToHistory") !== false; + pluginState.isChangeOrigin = change !== void 0 && !!change.isChangeOrigin; + pluginState.isUndoRedoOperation = change !== void 0 && !!change.isChangeOrigin && !!change.isUndoRedoOperation; + if (binding.prosemirrorView !== null) { + if (change !== void 0 && (change.snapshot != null || change.prevSnapshot != null)) { + timeout(0, () => { + if (binding.prosemirrorView == null) { + return; + } + if (change.restore == null) { + binding._renderSnapshot( + change.snapshot, + change.prevSnapshot, + pluginState + ); + } else { + binding._renderSnapshot( + change.snapshot, + change.snapshot, + pluginState + ); + delete pluginState.restore; + delete pluginState.snapshot; + delete pluginState.prevSnapshot; + binding.mux(() => { + binding._prosemirrorChanged( + binding.prosemirrorView.state.doc + ); + }); + } + }); + } + } + return pluginState; + } + }, + view: (view) => { + binding.initView(view); + if (mapping == null) { + binding._forceRerender(); + } + onFirstRender(); + return { + update: () => { + const pluginState = plugin.getState(view.state); + if (pluginState.snapshot == null && pluginState.prevSnapshot == null) { + if ( + // If the content doesn't change initially, we don't render anything to Yjs + // If the content was cleared by a user action, we want to catch the change and + // represent it in Yjs + initialContentChanged || view.state.doc.content.findDiffStart( + view.state.doc.type.createAndFill().content + ) !== null + ) { + initialContentChanged = true; + if (pluginState.addToHistory === false && !pluginState.isChangeOrigin) { + const yUndoPluginState = yUndoPluginKey.getState(view.state); + const um = yUndoPluginState && yUndoPluginState.undoManager; + if (um) { + um.stopCapturing(); + } + } + binding.mux(() => { + pluginState.doc.transact((tr2) => { + tr2.meta.set("addToHistory", pluginState.addToHistory); + binding._prosemirrorChanged(view.state.doc); + }, ySyncPluginKey); + }); + } + } + }, + destroy: () => { + binding.destroy(); + } + }; + } + }); + return plugin; +}; +var restoreRelativeSelection = (tr2, relSel, binding) => { + if (relSel !== null && relSel.anchor !== null && relSel.head !== null) { + if (relSel.type === "all") { + tr2.setSelection(new AllSelection(tr2.doc)); + } else if (relSel.type === "node") { + const anchor = relativePositionToAbsolutePosition( + binding.doc, + binding.type, + relSel.anchor, + binding.mapping + ); + tr2.setSelection(createSafeNodeSelection(tr2, anchor)); + } else { + const anchor = relativePositionToAbsolutePosition( + binding.doc, + binding.type, + relSel.anchor, + binding.mapping + ); + const head = relativePositionToAbsolutePosition( + binding.doc, + binding.type, + relSel.head, + binding.mapping + ); + if (anchor !== null && head !== null) { + tr2.setSelection(TextSelection.between(tr2.doc.resolve(anchor), tr2.doc.resolve(head))); + } + } + } +}; +var createSafeNodeSelection = (tr2, pos) => { + const $pos = tr2.doc.resolve(pos); + if ($pos.nodeAfter) { + return NodeSelection.create(tr2.doc, pos); + } else { + return TextSelection.near($pos); + } +}; +var getRelativeSelection = (pmbinding, state) => ({ + type: ( + /** @type {any} */ + state.selection.jsonID + ), + anchor: absolutePositionToRelativePosition( + state.selection.anchor, + pmbinding.type, + pmbinding.mapping + ), + head: absolutePositionToRelativePosition( + state.selection.head, + pmbinding.type, + pmbinding.mapping + ) +}); +var ProsemirrorBinding = class { + /** + * @param {Y.XmlFragment} yXmlFragment The bind source + * @param {ProsemirrorMapping} mapping + */ + constructor(yXmlFragment, mapping = /* @__PURE__ */ new Map()) { + this.type = yXmlFragment; + this.prosemirrorView = null; + this.mux = createMutex(); + this.mapping = mapping; + this.isOMark = /* @__PURE__ */ new Map(); + this._observeFunction = this._typeChanged.bind(this); + this.doc = yXmlFragment.doc; + this.beforeTransactionSelection = null; + this.beforeAllTransactions = () => { + if (this.beforeTransactionSelection === null && this.prosemirrorView != null) { + this.beforeTransactionSelection = getRelativeSelection( + this, + this.prosemirrorView.state + ); + } + }; + this.afterAllTransactions = () => { + this.beforeTransactionSelection = null; + }; + this._domSelectionInView = null; + } + /** + * Create a transaction for changing the prosemirror state. + * + * @returns + */ + get _tr() { + return this.prosemirrorView.state.tr.setMeta("addToHistory", false); + } + _isLocalCursorInView() { + if (!this.prosemirrorView.hasFocus()) return false; + if (isBrowser && this._domSelectionInView === null) { + timeout(0, () => { + this._domSelectionInView = null; + }); + this._domSelectionInView = this._isDomSelectionInView(); + } + return this._domSelectionInView; + } + _isDomSelectionInView() { + const selection = this.prosemirrorView._root.getSelection(); + if (selection == null || selection.anchorNode == null) return false; + const range = this.prosemirrorView._root.createRange(); + range.setStart(selection.anchorNode, selection.anchorOffset); + range.setEnd(selection.focusNode, selection.focusOffset); + const rects = range.getClientRects(); + if (rects.length === 0) { + if (range.startContainer && range.collapsed) { + range.selectNodeContents(range.startContainer); + } + } + const bounding = range.getBoundingClientRect(); + const documentElement = doc3.documentElement; + return bounding.bottom >= 0 && bounding.right >= 0 && bounding.left <= (window.innerWidth || documentElement.clientWidth || 0) && bounding.top <= (window.innerHeight || documentElement.clientHeight || 0); + } + /** + * @param {Y.Snapshot} snapshot + * @param {Y.Snapshot} prevSnapshot + */ + renderSnapshot(snapshot2, prevSnapshot) { + if (!prevSnapshot) { + prevSnapshot = createSnapshot(createDeleteSet(), /* @__PURE__ */ new Map()); + } + this.prosemirrorView.dispatch( + this._tr.setMeta(ySyncPluginKey, { snapshot: snapshot2, prevSnapshot }) + ); + } + unrenderSnapshot() { + this.mapping.clear(); + this.mux(() => { + const fragmentContent = this.type.toArray().map( + (t) => createNodeFromYElement( + /** @type {Y.XmlElement} */ + t, + this.prosemirrorView.state.schema, + this + ) + ).filter((n) => n !== null); + const tr2 = this._tr.replace( + 0, + this.prosemirrorView.state.doc.content.size, + new Slice(Fragment.from(fragmentContent), 0, 0) + ); + tr2.setMeta(ySyncPluginKey, { snapshot: null, prevSnapshot: null }); + this.prosemirrorView.dispatch(tr2); + }); + } + _forceRerender() { + this.mapping.clear(); + this.mux(() => { + const sel = this.beforeTransactionSelection !== null ? null : this.prosemirrorView.state.selection; + const fragmentContent = this.type.toArray().map( + (t) => createNodeFromYElement( + /** @type {Y.XmlElement} */ + t, + this.prosemirrorView.state.schema, + this + ) + ).filter((n) => n !== null); + const tr2 = this._tr.replace( + 0, + this.prosemirrorView.state.doc.content.size, + new Slice(Fragment.from(fragmentContent), 0, 0) + ); + if (sel) { + const clampedAnchor = min(max(sel.anchor, 0), tr2.doc.content.size); + const clampedHead = min(max(sel.head, 0), tr2.doc.content.size); + tr2.setSelection(TextSelection.create(tr2.doc, clampedAnchor, clampedHead)); + } + this.prosemirrorView.dispatch( + tr2.setMeta(ySyncPluginKey, { isChangeOrigin: true, binding: this }) + ); + }); + } + /** + * @param {Y.Snapshot|Uint8Array} snapshot + * @param {Y.Snapshot|Uint8Array} prevSnapshot + * @param {Object} pluginState + */ + _renderSnapshot(snapshot2, prevSnapshot, pluginState) { + let historyDoc = this.doc; + let historyType = this.type; + if (!snapshot2) { + snapshot2 = snapshot(this.doc); + } + if (snapshot2 instanceof Uint8Array || prevSnapshot instanceof Uint8Array) { + if (!(snapshot2 instanceof Uint8Array) || !(prevSnapshot instanceof Uint8Array)) { + unexpectedCase(); + } + historyDoc = new Doc({ gc: false }); + applyUpdateV2(historyDoc, prevSnapshot); + prevSnapshot = snapshot(historyDoc); + applyUpdateV2(historyDoc, snapshot2); + snapshot2 = snapshot(historyDoc); + if (historyType._item === null) { + const rootKey = Array.from(this.doc.share.keys()).find( + (key) => this.doc.share.get(key) === this.type + ); + historyType = historyDoc.getXmlFragment(rootKey); + } else { + const historyStructs = historyDoc.store.clients.get(historyType._item.id.client) ?? []; + const itemIndex = findIndexSS( + historyStructs, + historyType._item.id.clock + ); + const item = ( + /** @type {Y.Item} */ + historyStructs[itemIndex] + ); + const content = ( + /** @type {Y.ContentType} */ + item.content + ); + historyType = /** @type {Y.XmlFragment} */ + content.type; + } + } + this.mapping.clear(); + this.mux(() => { + historyDoc.transact((transaction) => { + const pud = pluginState.permanentUserData; + if (pud) { + pud.dss.forEach((ds) => { + iterateDeletedStructs(transaction, ds, (_item) => { + }); + }); + } + const computeYChange = (type, id2) => { + const user = type === "added" ? pud.getUserByClientId(id2.client) : pud.getUserByDeletedId(id2); + return { + user, + type, + color: getUserColor( + pluginState.colorMapping, + pluginState.colors, + user + ) + }; + }; + const fragmentContent = typeListToArraySnapshot( + historyType, + new Snapshot(prevSnapshot.ds, snapshot2.sv) + ).map((t) => { + if (!t._item.deleted || isVisible2(t._item, snapshot2) || isVisible2(t._item, prevSnapshot)) { + return createNodeFromYElement( + t, + this.prosemirrorView.state.schema, + { mapping: /* @__PURE__ */ new Map(), isOMark: /* @__PURE__ */ new Map() }, + snapshot2, + prevSnapshot, + computeYChange + ); + } else { + return null; + } + }).filter((n) => n !== null); + const tr2 = this._tr.replace( + 0, + this.prosemirrorView.state.doc.content.size, + new Slice(Fragment.from(fragmentContent), 0, 0) + ); + this.prosemirrorView.dispatch( + tr2.setMeta(ySyncPluginKey, { isChangeOrigin: true }) + ); + }, ySyncPluginKey); + }); + } + /** + * @param {Array>} events + * @param {Y.Transaction} transaction + */ + _typeChanged(events, transaction) { + if (this.prosemirrorView == null) return; + const syncState = ySyncPluginKey.getState(this.prosemirrorView.state); + if (events.length === 0 || syncState.snapshot != null || syncState.prevSnapshot != null) { + this.renderSnapshot(syncState.snapshot, syncState.prevSnapshot); + return; + } + this.mux(() => { + const delType = (_2, type) => this.mapping.delete(type); + iterateDeletedStructs( + transaction, + transaction.deleteSet, + (struct) => { + if (struct.constructor === Item2) { + const type = ( + /** @type {Y.ContentType} */ + /** @type {Y.Item} */ + struct.content.type + ); + type && this.mapping.delete(type); + } + } + ); + transaction.changed.forEach(delType); + transaction.changedParentTypes.forEach(delType); + const fragmentContent = this.type.toArray().map( + (t) => createNodeIfNotExists( + /** @type {Y.XmlElement | Y.XmlHook} */ + t, + this.prosemirrorView.state.schema, + this + ) + ).filter((n) => n !== null); + let tr2 = this._tr.replace( + 0, + this.prosemirrorView.state.doc.content.size, + new Slice(Fragment.from(fragmentContent), 0, 0) + ); + restoreRelativeSelection(tr2, this.beforeTransactionSelection, this); + tr2 = tr2.setMeta(ySyncPluginKey, { isChangeOrigin: true, isUndoRedoOperation: transaction.origin instanceof UndoManager }); + if (this.beforeTransactionSelection !== null && this._isLocalCursorInView()) { + tr2.scrollIntoView(); + } + this.prosemirrorView.dispatch(tr2); + }); + } + /** + * @param {import('prosemirror-model').Node} doc + */ + _prosemirrorChanged(doc4) { + this.doc.transact(() => { + updateYFragment(this.doc, this.type, doc4, this); + this.beforeTransactionSelection = getRelativeSelection( + this, + this.prosemirrorView.state + ); + }, ySyncPluginKey); + } + /** + * View is ready to listen to changes. Register observers. + * @param {any} prosemirrorView + */ + initView(prosemirrorView) { + if (this.prosemirrorView != null) this.destroy(); + this.prosemirrorView = prosemirrorView; + this.doc.on("beforeAllTransactions", this.beforeAllTransactions); + this.doc.on("afterAllTransactions", this.afterAllTransactions); + this.type.observeDeep(this._observeFunction); + } + destroy() { + if (this.prosemirrorView == null) return; + this.prosemirrorView = null; + this.type.unobserveDeep(this._observeFunction); + this.doc.off("beforeAllTransactions", this.beforeAllTransactions); + this.doc.off("afterAllTransactions", this.afterAllTransactions); + } +}; +var createNodeIfNotExists = (el, schema, meta, snapshot2, prevSnapshot, computeYChange) => { + const node = ( + /** @type {PModel.Node} */ + meta.mapping.get(el) + ); + if (node === void 0) { + if (el instanceof YXmlElement) { + return createNodeFromYElement( + el, + schema, + meta, + snapshot2, + prevSnapshot, + computeYChange + ); + } else { + throw methodUnimplemented(); + } + } + return node; +}; +var createNodeFromYElement = (el, schema, meta, snapshot2, prevSnapshot, computeYChange) => { + const children = []; + const createChildren = (type) => { + if (type instanceof YXmlElement) { + const n = createNodeIfNotExists( + type, + schema, + meta, + snapshot2, + prevSnapshot, + computeYChange + ); + if (n !== null) { + children.push(n); + } + } else { + const nextytext = ( + /** @type {Y.ContentType} */ + type._item.right?.content?.type + ); + if (nextytext instanceof YText && !nextytext._item.deleted && nextytext._item.id.client === nextytext.doc.clientID) { + type.applyDelta([ + { retain: type.length }, + ...nextytext.toDelta() + ]); + nextytext.doc.transact((tr2) => { + nextytext._item.delete(tr2); + }); + } + const ns = createTextNodesFromYText( + type, + schema, + meta, + snapshot2, + prevSnapshot, + computeYChange + ); + if (ns !== null) { + ns.forEach((textchild) => { + if (textchild !== null) { + children.push(textchild); + } + }); + } + } + }; + if (snapshot2 === void 0 || prevSnapshot === void 0) { + el.toArray().forEach(createChildren); + } else { + typeListToArraySnapshot(el, new Snapshot(prevSnapshot.ds, snapshot2.sv)).forEach(createChildren); + } + try { + const attrs = el.getAttributes(snapshot2); + if (snapshot2 !== void 0) { + if (!isVisible2( + /** @type {Y.Item} */ + el._item, + snapshot2 + )) { + attrs.ychange = computeYChange ? computeYChange( + "removed", + /** @type {Y.Item} */ + el._item.id + ) : { type: "removed" }; + } else if (!isVisible2( + /** @type {Y.Item} */ + el._item, + prevSnapshot + )) { + attrs.ychange = computeYChange ? computeYChange( + "added", + /** @type {Y.Item} */ + el._item.id + ) : { type: "added" }; + } + } + const node = schema.node(el.nodeName, attrs, children); + meta.mapping.set(el, node); + return node; + } catch (e) { + el.doc.transact((transaction) => { + el._item.delete(transaction); + }, ySyncPluginKey); + meta.mapping.delete(el); + return null; + } +}; +var createTextNodesFromYText = (text2, schema, _meta, snapshot2, prevSnapshot, computeYChange) => { + const nodes = []; + const deltas = text2.toDelta(snapshot2, prevSnapshot, computeYChange); + try { + for (let i = 0; i < deltas.length; i++) { + const delta = deltas[i]; + nodes.push(schema.text(delta.insert, attributesToMarks(delta.attributes, schema))); + } + } catch (e) { + text2.doc.transact((transaction) => { + text2._item.delete(transaction); + }, ySyncPluginKey); + return null; + } + return nodes; +}; +var createTypeFromTextNodes = (nodes, meta) => { + const type = new YXmlText(); + const delta = nodes.map((node) => ({ + // @ts-ignore + insert: node.text, + attributes: marksToAttributes(node.marks, meta) + })); + type.applyDelta(delta); + meta.mapping.set(type, nodes); + return type; +}; +var createTypeFromElementNode = (node, meta) => { + const type = new YXmlElement(node.type.name); + for (const key in node.attrs) { + const val = node.attrs[key]; + if (val !== null && key !== "ychange") { + type.setAttribute(key, val); + } + } + type.insert( + 0, + normalizePNodeContent(node).map( + (n) => createTypeFromTextOrElementNode(n, meta) + ) + ); + meta.mapping.set(type, node); + return type; +}; +var createTypeFromTextOrElementNode = (node, meta) => node instanceof Array ? createTypeFromTextNodes(node, meta) : createTypeFromElementNode(node, meta); +var isObject2 = (val) => typeof val === "object" && val !== null; +var equalAttrs2 = (pattrs, yattrs) => { + const keys3 = Object.keys(pattrs).filter((key) => pattrs[key] !== null); + let eq = keys3.length === Object.keys(yattrs).filter((key) => yattrs[key] !== null).length; + for (let i = 0; i < keys3.length && eq; i++) { + const key = keys3[i]; + const l3 = pattrs[key]; + const r = yattrs[key]; + eq = key === "ychange" || l3 === r || isObject2(l3) && isObject2(r) && equalAttrs2(l3, r); + } + return eq; +}; +var normalizePNodeContent = (pnode) => { + const c = pnode.content.content; + const res = []; + for (let i = 0; i < c.length; i++) { + const n = c[i]; + if (n.isText) { + const textNodes = []; + for (let tnode = c[i]; i < c.length && tnode.isText; tnode = c[++i]) { + textNodes.push(tnode); + } + i--; + res.push(textNodes); + } else { + res.push(n); + } + } + return res; +}; +var equalYTextPText = (ytext, ptexts) => { + const delta = ytext.toDelta(); + return delta.length === ptexts.length && delta.every( + /** @type {(d:any,i:number) => boolean} */ + (d2, i) => d2.insert === /** @type {any} */ + ptexts[i].text && keys2(d2.attributes || {}).length === ptexts[i].marks.length && every2(d2.attributes, (attr, yattrname) => { + const markname = yattr2markname(yattrname); + const pmarks = ptexts[i].marks; + const pmark = pmarks.find( + /** @param {any} mark */ + (mark) => mark.type.name === markname + ); + if (!pmark) { + return false; + } + return equalAttrs2(attr, pmarks.find( + /** @param {any} mark */ + (mark) => mark.type.name === markname + )?.attrs); + }) + ); +}; +var equalYTypePNode = (ytype, pnode) => { + if (ytype instanceof YXmlElement && !(pnode instanceof Array) && matchNodeName(ytype, pnode)) { + const normalizedContent = normalizePNodeContent(pnode); + return ytype._length === normalizedContent.length && equalAttrs2(ytype.getAttributes(), pnode.attrs) && ytype.toArray().every( + (ychild, i) => equalYTypePNode(ychild, normalizedContent[i]) + ); + } + return ytype instanceof YXmlText && pnode instanceof Array && equalYTextPText(ytype, pnode); +}; +var mappedIdentity = (mapped, pcontent) => mapped === pcontent || mapped instanceof Array && pcontent instanceof Array && mapped.length === pcontent.length && mapped.every( + (a, i) => pcontent[i] === a +); +var computeChildEqualityFactor = (ytype, pnode, meta) => { + const yChildren = ytype.toArray(); + const pChildren = normalizePNodeContent(pnode); + const pChildCnt = pChildren.length; + const yChildCnt = yChildren.length; + const minCnt = min(yChildCnt, pChildCnt); + let left = 0; + let right = 0; + let foundMappedChild = false; + for (; left < minCnt; left++) { + const leftY = yChildren[left]; + const leftP = pChildren[left]; + if (mappedIdentity(meta.mapping.get(leftY), leftP)) { + foundMappedChild = true; + } else if (!equalYTypePNode(leftY, leftP)) { + break; + } + } + for (; left + right < minCnt; right++) { + const rightY = yChildren[yChildCnt - right - 1]; + const rightP = pChildren[pChildCnt - right - 1]; + if (mappedIdentity(meta.mapping.get(rightY), rightP)) { + foundMappedChild = true; + } else if (!equalYTypePNode(rightY, rightP)) { + break; + } + } + return { + equalityFactor: left + right, + foundMappedChild + }; +}; +var ytextTrans = (ytext) => { + let str = ""; + let n = ytext._start; + const nAttrs = {}; + while (n !== null) { + if (!n.deleted) { + if (n.countable && n.content instanceof ContentString) { + str += n.content.str; + } else if (n.content instanceof ContentFormat) { + nAttrs[n.content.key] = null; + } + } + n = n.right; + } + return { + str, + nAttrs + }; +}; +var updateYText = (ytext, ptexts, meta) => { + meta.mapping.set(ytext, ptexts); + const { nAttrs, str } = ytextTrans(ytext); + const content = ptexts.map((p) => ({ + insert: ( + /** @type {any} */ + p.text + ), + attributes: Object.assign({}, nAttrs, marksToAttributes(p.marks, meta)) + })); + const { insert, remove: remove2, index } = simpleDiff( + str, + content.map((c) => c.insert).join("") + ); + ytext.delete(index, remove2); + ytext.insert(index, insert); + ytext.applyDelta( + content.map((c) => ({ retain: c.insert.length, attributes: c.attributes })) + ); +}; +var hashedMarkNameRegex = /(.*)(--[a-zA-Z0-9+/=]{8})$/; +var yattr2markname = (attrName) => hashedMarkNameRegex.exec(attrName)?.[1] ?? attrName; +var attributesToMarks = (attrs, schema) => { + const marks = []; + for (const markName in attrs) { + marks.push(schema.mark(yattr2markname(markName), attrs[markName])); + } + return marks; +}; +var marksToAttributes = (marks, meta) => { + const pattrs = {}; + marks.forEach((mark) => { + if (mark.type.name !== "ychange") { + const isOverlapping = setIfUndefined(meta.isOMark, mark.type, () => !mark.type.excludes(mark.type)); + pattrs[isOverlapping ? `${mark.type.name}--${hashOfJSON(mark.toJSON())}` : mark.type.name] = mark.attrs; + } + }); + return pattrs; +}; +var updateYFragment = (y2, yDomFragment, pNode, meta) => { + if (yDomFragment instanceof YXmlElement && yDomFragment.nodeName !== pNode.type.name) { + throw new Error("node name mismatch!"); + } + meta.mapping.set(yDomFragment, pNode); + if (yDomFragment instanceof YXmlElement) { + const yDomAttrs = yDomFragment.getAttributes(); + const pAttrs = pNode.attrs; + for (const key in pAttrs) { + if (pAttrs[key] !== null) { + if (yDomAttrs[key] !== pAttrs[key] && key !== "ychange") { + yDomFragment.setAttribute(key, pAttrs[key]); + } + } else { + yDomFragment.removeAttribute(key); + } + } + for (const key in yDomAttrs) { + if (pAttrs[key] === void 0) { + yDomFragment.removeAttribute(key); + } + } + } + const pChildren = normalizePNodeContent(pNode); + const pChildCnt = pChildren.length; + const yChildren = yDomFragment.toArray(); + const yChildCnt = yChildren.length; + const minCnt = min(pChildCnt, yChildCnt); + let left = 0; + let right = 0; + for (; left < minCnt; left++) { + const leftY = yChildren[left]; + const leftP = pChildren[left]; + if (!mappedIdentity(meta.mapping.get(leftY), leftP)) { + if (equalYTypePNode(leftY, leftP)) { + meta.mapping.set(leftY, leftP); + } else { + break; + } + } + } + for (; right + left + 1 < minCnt; right++) { + const rightY = yChildren[yChildCnt - right - 1]; + const rightP = pChildren[pChildCnt - right - 1]; + if (!mappedIdentity(meta.mapping.get(rightY), rightP)) { + if (equalYTypePNode(rightY, rightP)) { + meta.mapping.set(rightY, rightP); + } else { + break; + } + } + } + y2.transact(() => { + while (yChildCnt - left - right > 0 && pChildCnt - left - right > 0) { + const leftY = yChildren[left]; + const leftP = pChildren[left]; + const rightY = yChildren[yChildCnt - right - 1]; + const rightP = pChildren[pChildCnt - right - 1]; + if (leftY instanceof YXmlText && leftP instanceof Array) { + if (!equalYTextPText(leftY, leftP)) { + updateYText(leftY, leftP, meta); + } + left += 1; + } else { + let updateLeft = leftY instanceof YXmlElement && matchNodeName(leftY, leftP); + let updateRight = rightY instanceof YXmlElement && matchNodeName(rightY, rightP); + if (updateLeft && updateRight) { + const equalityLeft = computeChildEqualityFactor( + /** @type {Y.XmlElement} */ + leftY, + /** @type {PModel.Node} */ + leftP, + meta + ); + const equalityRight = computeChildEqualityFactor( + /** @type {Y.XmlElement} */ + rightY, + /** @type {PModel.Node} */ + rightP, + meta + ); + if (equalityLeft.foundMappedChild && !equalityRight.foundMappedChild) { + updateRight = false; + } else if (!equalityLeft.foundMappedChild && equalityRight.foundMappedChild) { + updateLeft = false; + } else if (equalityLeft.equalityFactor < equalityRight.equalityFactor) { + updateLeft = false; + } else { + updateRight = false; + } + } + if (updateLeft) { + updateYFragment( + y2, + /** @type {Y.XmlFragment} */ + leftY, + /** @type {PModel.Node} */ + leftP, + meta + ); + left += 1; + } else if (updateRight) { + updateYFragment( + y2, + /** @type {Y.XmlFragment} */ + rightY, + /** @type {PModel.Node} */ + rightP, + meta + ); + right += 1; + } else { + meta.mapping.delete(yDomFragment.get(left)); + yDomFragment.delete(left, 1); + yDomFragment.insert(left, [ + createTypeFromTextOrElementNode(leftP, meta) + ]); + left += 1; + } + } + } + const yDelLen = yChildCnt - left - right; + if (yChildCnt === 1 && pChildCnt === 0 && yChildren[0] instanceof YXmlText) { + meta.mapping.delete(yChildren[0]); + yChildren[0].delete(0, yChildren[0].length); + } else if (yDelLen > 0) { + yDomFragment.slice(left, left + yDelLen).forEach((type) => meta.mapping.delete(type)); + yDomFragment.delete(left, yDelLen); + } + if (left + right < pChildCnt) { + const ins = []; + for (let i = left; i < pChildCnt - right; i++) { + ins.push(createTypeFromTextOrElementNode(pChildren[i], meta)); + } + yDomFragment.insert(left, ins); + } + }, ySyncPluginKey); +}; +var matchNodeName = (yElement, pNode) => !(pNode instanceof Array) && yElement.nodeName === pNode.type.name; +var absolutePositionToRelativePosition = (pos, type, mapping) => { + if (pos === 0) { + return createRelativePositionFromTypeIndex(type, 0, -1); + } + let n = type._first === null ? null : ( + /** @type {Y.ContentType} */ + type._first.content.type + ); + while (n !== null && type !== n) { + if (n instanceof YXmlText) { + if (n._length >= pos) { + return createRelativePositionFromTypeIndex(n, pos, -1); + } else { + pos -= n._length; + } + if (n._item !== null && n._item.next !== null) { + n = /** @type {Y.ContentType} */ + n._item.next.content.type; + } else { + do { + n = n._item === null ? null : n._item.parent; + pos--; + } while (n !== type && n !== null && n._item !== null && n._item.next === null); + if (n !== null && n !== type) { + n = n._item === null ? null : ( + /** @type {Y.ContentType} */ + /** @type Y.Item */ + n._item.next.content.type + ); + } + } + } else { + const pNodeSize = ( + /** @type {any} */ + (mapping.get(n) || { nodeSize: 0 }).nodeSize + ); + if (n._first !== null && pos < pNodeSize) { + n = /** @type {Y.ContentType} */ + n._first.content.type; + pos--; + } else { + if (pos === 1 && n._length === 0 && pNodeSize > 1) { + return new RelativePosition(n._item === null ? null : n._item.id, n._item === null ? findRootTypeKey(n) : null, null); + } + pos -= pNodeSize; + if (n._item !== null && n._item.next !== null) { + n = /** @type {Y.ContentType} */ + n._item.next.content.type; + } else { + if (pos === 0) { + n = n._item === null ? n : n._item.parent; + return new RelativePosition(n._item === null ? null : n._item.id, n._item === null ? findRootTypeKey(n) : null, null); + } + do { + n = /** @type {Y.Item} */ + n._item.parent; + pos--; + } while (n !== type && /** @type {Y.Item} */ + n._item.next === null); + if (n !== type) { + n = /** @type {Y.ContentType} */ + /** @type {Y.Item} */ + /** @type {Y.Item} */ + n._item.next.content.type; + } + } + } + } + if (n === null) { + throw unexpectedCase(); + } + if (pos === 0 && n.constructor !== YXmlText && n !== type) { + return createRelativePosition2(n._item.parent, n._item); + } + } + return createRelativePositionFromTypeIndex(type, type._length, -1); +}; +var createRelativePosition2 = (type, item) => { + let typeid = null; + let tname = null; + if (type._item === null) { + tname = findRootTypeKey(type); + } else { + typeid = createID(type._item.id.client, type._item.id.clock); + } + return new RelativePosition(typeid, tname, item.id); +}; +var relativePositionToAbsolutePosition = (y2, documentType, relPos, mapping) => { + const decodedPos = createAbsolutePositionFromRelativePosition(relPos, y2); + if (decodedPos === null || decodedPos.type !== documentType && !isParentOf(documentType, decodedPos.type._item)) { + return null; + } + let type = decodedPos.type; + let pos = 0; + if (type.constructor === YXmlText) { + pos = decodedPos.index; + } else if (type._item === null || !type._item.deleted) { + let n = type._first; + let i = 0; + while (i < type._length && i < decodedPos.index && n !== null) { + if (!n.deleted) { + const t = ( + /** @type {Y.ContentType} */ + n.content.type + ); + i++; + if (t instanceof YXmlText) { + pos += t._length; + } else { + pos += /** @type {any} */ + mapping.get(t).nodeSize; + } + } + n = /** @type {Y.Item} */ + n.right; + } + pos += 1; + } + while (type !== documentType && type._item !== null) { + const parent = type._item.parent; + if (parent._item === null || !parent._item.deleted) { + pos += 1; + let n = ( + /** @type {Y.AbstractType} */ + parent._first + ); + while (n !== null) { + const contentType = ( + /** @type {Y.ContentType} */ + n.content.type + ); + if (contentType === type) { + break; + } + if (!n.deleted) { + if (contentType instanceof YXmlText) { + pos += contentType._length; + } else { + pos += /** @type {any} */ + mapping.get(contentType).nodeSize; + } + } + n = n.right; + } + } + type = /** @type {Y.AbstractType} */ + parent; + } + return pos - 1; +}; +var undo2 = (state) => { + const undoManager = yUndoPluginKey.getState(state).undoManager; + if (undoManager != null) { + undoManager.undo(); + return true; + } +}; +var redo2 = (state) => { + const undoManager = yUndoPluginKey.getState(state).undoManager; + if (undoManager != null) { + undoManager.redo(); + return true; + } +}; +var defaultProtectedNodes = /* @__PURE__ */ new Set(["paragraph"]); +var defaultDeleteFilter = (item, protectedNodes) => !(item instanceof Item2) || !(item.content instanceof ContentType) || !(item.content.type instanceof YText || item.content.type instanceof YXmlElement && protectedNodes.has(item.content.type.nodeName)) || item.content.type._length === 0; +var yUndoPlugin = ({ protectedNodes = defaultProtectedNodes, trackedOrigins = [], undoManager = null } = {}) => new Plugin({ + key: yUndoPluginKey, + state: { + init: (initargs, state) => { + const ystate = ySyncPluginKey.getState(state); + let _undoManager = undoManager; + if (!_undoManager) { + const doc4 = ystate.doc; + const destroyListenersBefore = new Set(doc4 ? doc4._observers.get("destroy") : []); + _undoManager = new UndoManager(ystate.type, { + trackedOrigins: new Set([ySyncPluginKey].concat(trackedOrigins)), + deleteFilter: (item) => defaultDeleteFilter(item, protectedNodes), + captureTransaction: (tr2) => tr2.meta.get("addToHistory") !== false + }); + const destroyListenersAfter = doc4 ? doc4._observers.get("destroy") : /* @__PURE__ */ new Set(); + _undoManager._yTiptapDocDestroyListeners = Array.from(destroyListenersAfter || []).filter((listener) => !destroyListenersBefore.has(listener)); + } + return { + undoManager: _undoManager, + prevSel: null, + hasUndoOps: _undoManager.undoStack.length > 0, + hasRedoOps: _undoManager.redoStack.length > 0 + }; + }, + /** + * @returns {any} + */ + apply: (tr2, val, oldState, state) => { + const binding = ySyncPluginKey.getState(state).binding; + const undoManager2 = val.undoManager; + const hasUndoOps = undoManager2.undoStack.length > 0; + const hasRedoOps = undoManager2.redoStack.length > 0; + if (binding) { + return { + undoManager: undoManager2, + prevSel: getRelativeSelection(binding, oldState), + hasUndoOps, + hasRedoOps + }; + } else { + if (hasUndoOps !== val.hasUndoOps || hasRedoOps !== val.hasRedoOps) { + return Object.assign({}, val, { + hasUndoOps: undoManager2.undoStack.length > 0, + hasRedoOps: undoManager2.redoStack.length > 0 + }); + } else { + return val; + } + } + } + }, + view: (view) => { + const ystate = ySyncPluginKey.getState(view.state); + const undoManager2 = yUndoPluginKey.getState(view.state).undoManager; + undoManager2.on("stack-item-added", ({ stackItem }) => { + const binding = ystate.binding; + if (binding) { + stackItem.meta.set(binding, yUndoPluginKey.getState(view.state).prevSel); + } + }); + undoManager2.on("stack-item-popped", ({ stackItem }) => { + const binding = ystate.binding; + if (binding) { + binding.beforeTransactionSelection = stackItem.meta.get(binding) || binding.beforeTransactionSelection; + } + }); + return { + destroy: () => { + undoManager2.destroy(); + const leakedDestroyListeners = undoManager2._yTiptapDocDestroyListeners; + if (leakedDestroyListeners && undoManager2.doc) { + leakedDestroyListeners.forEach((listener) => undoManager2.doc.off("destroy", listener)); + undoManager2._yTiptapDocDestroyListeners = null; + } + } + }; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-collaboration@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0__@tiptap+pm@3.26_2l5xq5ovwtsor54wf2zetibzfu/node_modules/@tiptap/extension-collaboration/dist/index.js +function isChangeOrigin(transaction) { + return !!transaction.getMeta(ySyncPluginKey); +} +function getYAbsolutePosition(state, relativePos) { + const ystate = ySyncPluginKey.getState(state); + return relativePositionToAbsolutePosition( + ystate.doc, + ystate.type, + relativePos, + ystate.binding.mapping + ) || 0; +} +function getYRelativePosition(state, absolutePos) { + const ystate = ySyncPluginKey.getState(state); + return absolutePositionToRelativePosition(absolutePos, ystate.type, ystate.binding.mapping); +} +var CollaborationMappablePosition = class _CollaborationMappablePosition extends MappablePosition { + constructor(position, yRelativePosition) { + super(position); + this.yRelativePosition = yRelativePosition; + } + /** + * Creates a CollaborationMappablePosition from a JSON object. + */ + static fromJSON(json) { + return new _CollaborationMappablePosition(json.position, json.yRelativePosition); + } + /** + * Converts the CollaborationMappablePosition to a JSON object. + */ + toJSON() { + return { + position: this.position, + yRelativePosition: this.yRelativePosition + }; + } +}; +function createMappablePosition2(position, state) { + const yRelativePosition = getYRelativePosition(state, position); + return new CollaborationMappablePosition(position, yRelativePosition); +} +function getUpdatedPosition2(position, transaction, state) { + const yRelativePosition = position instanceof CollaborationMappablePosition ? position.yRelativePosition : null; + if (isChangeOrigin(transaction) && yRelativePosition) { + const absolutePosition2 = getYAbsolutePosition(state, yRelativePosition); + return { + position: new CollaborationMappablePosition(absolutePosition2, yRelativePosition), + mapResult: null + }; + } + const result = getUpdatedPosition(position, transaction); + const absolutePosition = result.position.position; + return { + position: new CollaborationMappablePosition( + absolutePosition, + yRelativePosition != null ? yRelativePosition : getYRelativePosition(state, absolutePosition) + ), + mapResult: result.mapResult + }; +} +var Collaboration = Extension.create({ + name: "collaboration", + priority: 1e3, + addOptions() { + return { + document: null, + field: "default", + fragment: null, + provider: null + }; + }, + addStorage() { + return { + isDisabled: false + }; + }, + onCreate() { + if (this.editor.extensionManager.extensions.find((extension) => extension.name === "undoRedo")) { + console.warn( + '[tiptap warn]: "@tiptap/extension-collaboration" comes with its own history support and is not compatible with "@tiptap/extension-undo-redo".' + ); + } + }, + onBeforeCreate() { + this.editor.utils.getUpdatedPosition = (position, transaction) => getUpdatedPosition2(position, transaction, this.editor.state); + this.editor.utils.createMappablePosition = (position) => createMappablePosition2(position, this.editor.state); + }, + addCommands() { + return { + undo: () => ({ tr: tr2, state, dispatch }) => { + tr2.setMeta("preventDispatch", true); + const undoManager = yUndoPluginKey.getState(state).undoManager; + if (undoManager.undoStack.length === 0) { + return false; + } + if (!dispatch) { + return true; + } + return undo2(state); + }, + redo: () => ({ tr: tr2, state, dispatch }) => { + tr2.setMeta("preventDispatch", true); + const undoManager = yUndoPluginKey.getState(state).undoManager; + if (undoManager.redoStack.length === 0) { + return false; + } + if (!dispatch) { + return true; + } + return redo2(state); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-z": () => this.editor.commands.undo(), + "Mod-y": () => this.editor.commands.redo(), + "Shift-Mod-z": () => this.editor.commands.redo() + }; + }, + addProseMirrorPlugins() { + const fragment = this.options.fragment ? this.options.fragment : this.options.document.getXmlFragment(this.options.field); + const yUndoPluginInstance = yUndoPlugin(this.options.yUndoOptions); + const originalUndoPluginView = yUndoPluginInstance.spec.view; + yUndoPluginInstance.spec.view = (view) => { + const { undoManager } = yUndoPluginKey.getState(view.state); + if (undoManager.restore) { + undoManager.restore(); + undoManager.restore = () => { + }; + } + const viewRet = originalUndoPluginView ? originalUndoPluginView(view) : void 0; + return { + destroy: () => { + const hasUndoManSelf = undoManager.trackedOrigins.has(undoManager); + const observers = undoManager._observers; + undoManager.restore = () => { + if (hasUndoManSelf) { + undoManager.trackedOrigins.add(undoManager); + } + undoManager.doc.on("afterTransaction", undoManager.afterTransactionHandler); + undoManager._observers = observers; + }; + if (viewRet == null ? void 0 : viewRet.destroy) { + viewRet.destroy(); + } + } + }; + }; + const ySyncPluginOptions = { + ...this.options.ySyncOptions, + onFirstRender: this.options.onFirstRender + }; + const ySyncPluginInstance = ySyncPlugin(fragment, ySyncPluginOptions); + return [ + ySyncPluginInstance, + yUndoPluginInstance, + // Only add the filterInvalidContent plugin if content checking is enabled + this.editor.options.enableContentCheck && new Plugin({ + key: new PluginKey("filterInvalidContent"), + filterTransaction: (transaction) => { + if (!isChangeOrigin(transaction)) { + return true; + } + if (this.storage.isDisabled) { + return false; + } + if (!transaction.docChanged) { + return true; + } + try { + transaction.doc.check(); + return true; + } catch (error) { + this.storage.isDisabled = true; + this.editor.emit("contentError", { + error, + editor: this.editor, + disableCollaboration: () => { + var _a; + (_a = fragment.doc) == null ? void 0 : _a.destroy(); + } + }); + return true; + } + } + }) + ].filter(Boolean); + } +}); +var index_default3 = Collaboration; + +// ../../node_modules/.pnpm/@tiptap+extension-placeholder@3.26.0_@tiptap+extensions@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0__@tiptap+pm@3.26.0_/node_modules/@tiptap/extension-placeholder/dist/index.js +var index_default4 = Placeholder; + +// ../../node_modules/.pnpm/@tiptap+extension-task-list@3.26.0_@tiptap+extension-list@3.26.0_@tiptap+core@3.26.0_@tiptap+_swbnsazyfblvczk6h3sxqywlia/node_modules/@tiptap/extension-task-list/dist/index.js +var index_default5 = TaskList; + +// ../../node_modules/.pnpm/@tiptap+extension-task-item@3.26.0_@tiptap+extension-list@3.26.0_@tiptap+core@3.26.0_@tiptap+_dh6y4ij5lgeuihg7efjr5p57qi/node_modules/@tiptap/extension-task-item/dist/index.js +var index_default6 = TaskItem; + +// ../../node_modules/.pnpm/prosemirror-tables@1.8.5/node_modules/prosemirror-tables/dist/index.js +var readFromCache; +var addToCache; +if (typeof WeakMap != "undefined") { + let cache = /* @__PURE__ */ new WeakMap(); + readFromCache = (key) => cache.get(key); + addToCache = (key, value) => { + cache.set(key, value); + return value; + }; +} else { + const cache = []; + const cacheSize = 10; + let cachePos = 0; + readFromCache = (key) => { + for (let i = 0; i < cache.length; i += 2) if (cache[i] == key) return cache[i + 1]; + }; + addToCache = (key, value) => { + if (cachePos == cacheSize) cachePos = 0; + cache[cachePos++] = key; + return cache[cachePos++] = value; + }; +} +var TableMap = class { + constructor(width, height, map4, problems) { + this.width = width; + this.height = height; + this.map = map4; + this.problems = problems; + } + findCell(pos) { + for (let i = 0; i < this.map.length; i++) { + const curPos = this.map[i]; + if (curPos != pos) continue; + const left = i % this.width; + const top = i / this.width | 0; + let right = left + 1; + let bottom = top + 1; + for (let j2 = 1; right < this.width && this.map[i + j2] == curPos; j2++) right++; + for (let j2 = 1; bottom < this.height && this.map[i + this.width * j2] == curPos; j2++) bottom++; + return { + left, + top, + right, + bottom + }; + } + throw new RangeError(`No cell with offset ${pos} found`); + } + colCount(pos) { + for (let i = 0; i < this.map.length; i++) if (this.map[i] == pos) return i % this.width; + throw new RangeError(`No cell with offset ${pos} found`); + } + nextCell(pos, axis, dir) { + const { left, right, top, bottom } = this.findCell(pos); + if (axis == "horiz") { + if (dir < 0 ? left == 0 : right == this.width) return null; + return this.map[top * this.width + (dir < 0 ? left - 1 : right)]; + } else { + if (dir < 0 ? top == 0 : bottom == this.height) return null; + return this.map[left + this.width * (dir < 0 ? top - 1 : bottom)]; + } + } + rectBetween(a, b2) { + const { left: leftA, right: rightA, top: topA, bottom: bottomA } = this.findCell(a); + const { left: leftB, right: rightB, top: topB, bottom: bottomB } = this.findCell(b2); + return { + left: Math.min(leftA, leftB), + top: Math.min(topA, topB), + right: Math.max(rightA, rightB), + bottom: Math.max(bottomA, bottomB) + }; + } + cellsInRect(rect) { + const result = []; + const seen = {}; + for (let row = rect.top; row < rect.bottom; row++) for (let col = rect.left; col < rect.right; col++) { + const index = row * this.width + col; + const pos = this.map[index]; + if (seen[pos]) continue; + seen[pos] = true; + if (col == rect.left && col && this.map[index - 1] == pos || row == rect.top && row && this.map[index - this.width] == pos) continue; + result.push(pos); + } + return result; + } + positionAt(row, col, table) { + for (let i = 0, rowStart = 0; ; i++) { + const rowEnd = rowStart + table.child(i).nodeSize; + if (i == row) { + let index = col + row * this.width; + const rowEndIndex = (row + 1) * this.width; + while (index < rowEndIndex && this.map[index] < rowStart) index++; + return index == rowEndIndex ? rowEnd - 1 : this.map[index]; + } + rowStart = rowEnd; + } + } + static get(table) { + return readFromCache(table) || addToCache(table, computeMap(table)); + } +}; +function computeMap(table) { + if (table.type.spec.tableRole != "table") throw new RangeError("Not a table node: " + table.type.name); + const width = findWidth(table), height = table.childCount; + const map4 = []; + let mapPos = 0; + let problems = null; + const colWidths = []; + for (let i = 0, e = width * height; i < e; i++) map4[i] = 0; + for (let row = 0, pos = 0; row < height; row++) { + const rowNode = table.child(row); + pos++; + for (let i = 0; ; i++) { + while (mapPos < map4.length && map4[mapPos] != 0) mapPos++; + if (i == rowNode.childCount) break; + const cellNode = rowNode.child(i); + const { colspan, rowspan, colwidth } = cellNode.attrs; + for (let h2 = 0; h2 < rowspan; h2++) { + if (h2 + row >= height) { + (problems || (problems = [])).push({ + type: "overlong_rowspan", + pos, + n: rowspan - h2 + }); + break; + } + const start = mapPos + h2 * width; + for (let w2 = 0; w2 < colspan; w2++) { + if (map4[start + w2] == 0) map4[start + w2] = pos; + else (problems || (problems = [])).push({ + type: "collision", + row, + pos, + n: colspan - w2 + }); + const colW = colwidth && colwidth[w2]; + if (colW) { + const widthIndex = (start + w2) % width * 2, prev = colWidths[widthIndex]; + if (prev == null || prev != colW && colWidths[widthIndex + 1] == 1) { + colWidths[widthIndex] = colW; + colWidths[widthIndex + 1] = 1; + } else if (prev == colW) colWidths[widthIndex + 1]++; + } + } + } + mapPos += colspan; + pos += cellNode.nodeSize; + } + const expectedPos = (row + 1) * width; + let missing = 0; + while (mapPos < expectedPos) if (map4[mapPos++] == 0) missing++; + if (missing) (problems || (problems = [])).push({ + type: "missing", + row, + n: missing + }); + pos++; + } + if (width === 0 || height === 0) (problems || (problems = [])).push({ type: "zero_sized" }); + const tableMap = new TableMap(width, height, map4, problems); + let badWidths = false; + for (let i = 0; !badWidths && i < colWidths.length; i += 2) if (colWidths[i] != null && colWidths[i + 1] < height) badWidths = true; + if (badWidths) findBadColWidths(tableMap, colWidths, table); + return tableMap; +} +function findWidth(table) { + let width = -1; + let hasRowSpan = false; + for (let row = 0; row < table.childCount; row++) { + const rowNode = table.child(row); + let rowWidth = 0; + if (hasRowSpan) for (let j2 = 0; j2 < row; j2++) { + const prevRow = table.child(j2); + for (let i = 0; i < prevRow.childCount; i++) { + const cell2 = prevRow.child(i); + if (j2 + cell2.attrs.rowspan > row) rowWidth += cell2.attrs.colspan; + } + } + for (let i = 0; i < rowNode.childCount; i++) { + const cell2 = rowNode.child(i); + rowWidth += cell2.attrs.colspan; + if (cell2.attrs.rowspan > 1) hasRowSpan = true; + } + if (width == -1) width = rowWidth; + else if (width != rowWidth) width = Math.max(width, rowWidth); + } + return width; +} +function findBadColWidths(map4, colWidths, table) { + if (!map4.problems) map4.problems = []; + const seen = {}; + for (let i = 0; i < map4.map.length; i++) { + const pos = map4.map[i]; + if (seen[pos]) continue; + seen[pos] = true; + const node = table.nodeAt(pos); + if (!node) throw new RangeError(`No cell with offset ${pos} found`); + let updated = null; + const attrs = node.attrs; + for (let j2 = 0; j2 < attrs.colspan; j2++) { + const colWidth = colWidths[(i + j2) % map4.width * 2]; + if (colWidth != null && (!attrs.colwidth || attrs.colwidth[j2] != colWidth)) (updated || (updated = freshColWidth(attrs)))[j2] = colWidth; + } + if (updated) map4.problems.unshift({ + type: "colwidth mismatch", + pos, + colwidth: updated + }); + } +} +function freshColWidth(attrs) { + if (attrs.colwidth) return attrs.colwidth.slice(); + const result = []; + for (let i = 0; i < attrs.colspan; i++) result.push(0); + return result; +} +function tableNodeTypes(schema) { + let result = schema.cached.tableNodeTypes; + if (!result) { + result = schema.cached.tableNodeTypes = {}; + for (const name in schema.nodes) { + const type = schema.nodes[name], role = type.spec.tableRole; + if (role) result[role] = type; + } + } + return result; +} +var tableEditingKey = new PluginKey("selectingCells"); +function cellAround($pos) { + for (let d2 = $pos.depth - 1; d2 > 0; d2--) if ($pos.node(d2).type.spec.tableRole == "row") return $pos.node(0).resolve($pos.before(d2 + 1)); + return null; +} +function cellWrapping($pos) { + for (let d2 = $pos.depth; d2 > 0; d2--) { + const role = $pos.node(d2).type.spec.tableRole; + if (role === "cell" || role === "header_cell") return $pos.node(d2); + } + return null; +} +function isInTable(state) { + const $head = state.selection.$head; + for (let d2 = $head.depth; d2 > 0; d2--) if ($head.node(d2).type.spec.tableRole == "row") return true; + return false; +} +function selectionCell(state) { + const sel = state.selection; + if ("$anchorCell" in sel && sel.$anchorCell) return sel.$anchorCell.pos > sel.$headCell.pos ? sel.$anchorCell : sel.$headCell; + else if ("node" in sel && sel.node && sel.node.type.spec.tableRole == "cell") return sel.$anchor; + const $cell = cellAround(sel.$head) || cellNear(sel.$head); + if ($cell) return $cell; + throw new RangeError(`No cell found around position ${sel.head}`); +} +function cellNear($pos) { + for (let after = $pos.nodeAfter, pos = $pos.pos; after; after = after.firstChild, pos++) { + const role = after.type.spec.tableRole; + if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos); + } + for (let before = $pos.nodeBefore, pos = $pos.pos; before; before = before.lastChild, pos--) { + const role = before.type.spec.tableRole; + if (role == "cell" || role == "header_cell") return $pos.doc.resolve(pos - before.nodeSize); + } +} +function pointsAtCell($pos) { + return $pos.parent.type.spec.tableRole == "row" && !!$pos.nodeAfter; +} +function moveCellForward($pos) { + return $pos.node(0).resolve($pos.pos + $pos.nodeAfter.nodeSize); +} +function inSameTable($cellA, $cellB) { + return $cellA.depth == $cellB.depth && $cellA.pos >= $cellB.start(-1) && $cellA.pos <= $cellB.end(-1); +} +function nextCell($pos, axis, dir) { + const table = $pos.node(-1); + const map4 = TableMap.get(table); + const tableStart = $pos.start(-1); + const moved = map4.nextCell($pos.pos - tableStart, axis, dir); + return moved == null ? null : $pos.node(0).resolve(tableStart + moved); +} +function removeColSpan(attrs, pos, n = 1) { + const result = { + ...attrs, + colspan: attrs.colspan - n + }; + if (result.colwidth) { + result.colwidth = result.colwidth.slice(); + result.colwidth.splice(pos, n); + if (!result.colwidth.some((w2) => w2 > 0)) result.colwidth = null; + } + return result; +} +function addColSpan(attrs, pos, n = 1) { + const result = { + ...attrs, + colspan: attrs.colspan + n + }; + if (result.colwidth) { + result.colwidth = result.colwidth.slice(); + for (let i = 0; i < n; i++) result.colwidth.splice(pos, 0, 0); + } + return result; +} +function columnIsHeader(map4, table, col) { + const headerCell = tableNodeTypes(table.type.schema).header_cell; + for (let row = 0; row < map4.height; row++) if (table.nodeAt(map4.map[col + row * map4.width]).type != headerCell) return false; + return true; +} +var CellSelection = class CellSelection2 extends Selection { + constructor($anchorCell, $headCell = $anchorCell) { + const table = $anchorCell.node(-1); + const map4 = TableMap.get(table); + const tableStart = $anchorCell.start(-1); + const rect = map4.rectBetween($anchorCell.pos - tableStart, $headCell.pos - tableStart); + const doc4 = $anchorCell.node(0); + const cells = map4.cellsInRect(rect).filter((p) => p != $headCell.pos - tableStart); + cells.unshift($headCell.pos - tableStart); + const ranges = cells.map((pos) => { + const cell2 = table.nodeAt(pos); + if (!cell2) throw new RangeError(`No cell with offset ${pos} found`); + const from3 = tableStart + pos + 1; + return new SelectionRange(doc4.resolve(from3), doc4.resolve(from3 + cell2.content.size)); + }); + super(ranges[0].$from, ranges[0].$to, ranges); + this.$anchorCell = $anchorCell; + this.$headCell = $headCell; + } + map(doc4, mapping) { + const $anchorCell = doc4.resolve(mapping.map(this.$anchorCell.pos)); + const $headCell = doc4.resolve(mapping.map(this.$headCell.pos)); + if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) { + const tableChanged = this.$anchorCell.node(-1) != $anchorCell.node(-1); + if (tableChanged && this.isRowSelection()) return CellSelection2.rowSelection($anchorCell, $headCell); + else if (tableChanged && this.isColSelection()) return CellSelection2.colSelection($anchorCell, $headCell); + else return new CellSelection2($anchorCell, $headCell); + } + return TextSelection.between($anchorCell, $headCell); + } + content() { + const table = this.$anchorCell.node(-1); + const map4 = TableMap.get(table); + const tableStart = this.$anchorCell.start(-1); + const rect = map4.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart); + const seen = {}; + const rows = []; + for (let row = rect.top; row < rect.bottom; row++) { + const rowContent = []; + for (let index = row * map4.width + rect.left, col = rect.left; col < rect.right; col++, index++) { + const pos = map4.map[index]; + if (seen[pos]) continue; + seen[pos] = true; + const cellRect = map4.findCell(pos); + let cell2 = table.nodeAt(pos); + if (!cell2) throw new RangeError(`No cell with offset ${pos} found`); + const extraLeft = rect.left - cellRect.left; + const extraRight = cellRect.right - rect.right; + if (extraLeft > 0 || extraRight > 0) { + let attrs = cell2.attrs; + if (extraLeft > 0) attrs = removeColSpan(attrs, 0, extraLeft); + if (extraRight > 0) attrs = removeColSpan(attrs, attrs.colspan - extraRight, extraRight); + if (cellRect.left < rect.left) { + cell2 = cell2.type.createAndFill(attrs); + if (!cell2) throw new RangeError(`Could not create cell with attrs ${JSON.stringify(attrs)}`); + } else cell2 = cell2.type.create(attrs, cell2.content); + } + if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) { + const attrs = { + ...cell2.attrs, + rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top) + }; + if (cellRect.top < rect.top) cell2 = cell2.type.createAndFill(attrs); + else cell2 = cell2.type.create(attrs, cell2.content); + } + rowContent.push(cell2); + } + rows.push(table.child(row).copy(Fragment.from(rowContent))); + } + const fragment = this.isColSelection() && this.isRowSelection() ? table : rows; + return new Slice(Fragment.from(fragment), 1, 1); + } + replace(tr2, content = Slice.empty) { + const mapFrom = tr2.steps.length, ranges = this.ranges; + for (let i = 0; i < ranges.length; i++) { + const { $from, $to } = ranges[i], mapping = tr2.mapping.slice(mapFrom); + tr2.replace(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content); + } + const sel = Selection.findFrom(tr2.doc.resolve(tr2.mapping.slice(mapFrom).map(this.to)), -1); + if (sel) tr2.setSelection(sel); + } + replaceWith(tr2, node) { + this.replace(tr2, new Slice(Fragment.from(node), 0, 0)); + } + forEachCell(f) { + const table = this.$anchorCell.node(-1); + const map4 = TableMap.get(table); + const tableStart = this.$anchorCell.start(-1); + const cells = map4.cellsInRect(map4.rectBetween(this.$anchorCell.pos - tableStart, this.$headCell.pos - tableStart)); + for (let i = 0; i < cells.length; i++) f(table.nodeAt(cells[i]), tableStart + cells[i]); + } + isColSelection() { + const anchorTop = this.$anchorCell.index(-1); + const headTop = this.$headCell.index(-1); + if (Math.min(anchorTop, headTop) > 0) return false; + const anchorBottom = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan; + const headBottom = headTop + this.$headCell.nodeAfter.attrs.rowspan; + return Math.max(anchorBottom, headBottom) == this.$headCell.node(-1).childCount; + } + static colSelection($anchorCell, $headCell = $anchorCell) { + const table = $anchorCell.node(-1); + const map4 = TableMap.get(table); + const tableStart = $anchorCell.start(-1); + const anchorRect = map4.findCell($anchorCell.pos - tableStart); + const headRect = map4.findCell($headCell.pos - tableStart); + const doc4 = $anchorCell.node(0); + if (anchorRect.top <= headRect.top) { + if (anchorRect.top > 0) $anchorCell = doc4.resolve(tableStart + map4.map[anchorRect.left]); + if (headRect.bottom < map4.height) $headCell = doc4.resolve(tableStart + map4.map[map4.width * (map4.height - 1) + headRect.right - 1]); + } else { + if (headRect.top > 0) $headCell = doc4.resolve(tableStart + map4.map[headRect.left]); + if (anchorRect.bottom < map4.height) $anchorCell = doc4.resolve(tableStart + map4.map[map4.width * (map4.height - 1) + anchorRect.right - 1]); + } + return new CellSelection2($anchorCell, $headCell); + } + isRowSelection() { + const table = this.$anchorCell.node(-1); + const map4 = TableMap.get(table); + const tableStart = this.$anchorCell.start(-1); + const anchorLeft = map4.colCount(this.$anchorCell.pos - tableStart); + const headLeft = map4.colCount(this.$headCell.pos - tableStart); + if (Math.min(anchorLeft, headLeft) > 0) return false; + const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan; + const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan; + return Math.max(anchorRight, headRight) == map4.width; + } + eq(other) { + return other instanceof CellSelection2 && other.$anchorCell.pos == this.$anchorCell.pos && other.$headCell.pos == this.$headCell.pos; + } + static rowSelection($anchorCell, $headCell = $anchorCell) { + const table = $anchorCell.node(-1); + const map4 = TableMap.get(table); + const tableStart = $anchorCell.start(-1); + const anchorRect = map4.findCell($anchorCell.pos - tableStart); + const headRect = map4.findCell($headCell.pos - tableStart); + const doc4 = $anchorCell.node(0); + if (anchorRect.left <= headRect.left) { + if (anchorRect.left > 0) $anchorCell = doc4.resolve(tableStart + map4.map[anchorRect.top * map4.width]); + if (headRect.right < map4.width) $headCell = doc4.resolve(tableStart + map4.map[map4.width * (headRect.top + 1) - 1]); + } else { + if (headRect.left > 0) $headCell = doc4.resolve(tableStart + map4.map[headRect.top * map4.width]); + if (anchorRect.right < map4.width) $anchorCell = doc4.resolve(tableStart + map4.map[map4.width * (anchorRect.top + 1) - 1]); + } + return new CellSelection2($anchorCell, $headCell); + } + toJSON() { + return { + type: "cell", + anchor: this.$anchorCell.pos, + head: this.$headCell.pos + }; + } + static fromJSON(doc4, json) { + return new CellSelection2(doc4.resolve(json.anchor), doc4.resolve(json.head)); + } + static create(doc4, anchorCell, headCell = anchorCell) { + return new CellSelection2(doc4.resolve(anchorCell), doc4.resolve(headCell)); + } + getBookmark() { + return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos); + } +}; +CellSelection.prototype.visible = false; +Selection.jsonID("cell", CellSelection); +var CellBookmark = class CellBookmark2 { + constructor(anchor, head) { + this.anchor = anchor; + this.head = head; + } + map(mapping) { + return new CellBookmark2(mapping.map(this.anchor), mapping.map(this.head)); + } + resolve(doc4) { + const $anchorCell = doc4.resolve(this.anchor), $headCell = doc4.resolve(this.head); + if ($anchorCell.parent.type.spec.tableRole == "row" && $headCell.parent.type.spec.tableRole == "row" && $anchorCell.index() < $anchorCell.parent.childCount && $headCell.index() < $headCell.parent.childCount && inSameTable($anchorCell, $headCell)) return new CellSelection($anchorCell, $headCell); + else return Selection.near($headCell, 1); + } +}; +function drawCellSelection(state) { + if (!(state.selection instanceof CellSelection)) return null; + const cells = []; + state.selection.forEachCell((node, pos) => { + cells.push(Decoration.node(pos, pos + node.nodeSize, { class: "selectedCell" })); + }); + return DecorationSet.create(state.doc, cells); +} +function isCellBoundarySelection({ $from, $to }) { + if ($from.pos == $to.pos || $from.pos < $to.pos - 6) return false; + let afterFrom = $from.pos; + let beforeTo = $to.pos; + let depth = $from.depth; + for (; depth >= 0; depth--, afterFrom++) if ($from.after(depth + 1) < $from.end(depth)) break; + for (let d2 = $to.depth; d2 >= 0; d2--, beforeTo--) if ($to.before(d2 + 1) > $to.start(d2)) break; + return afterFrom == beforeTo && /row|table/.test($from.node(depth).type.spec.tableRole); +} +function isTextSelectionAcrossCells({ $from, $to }) { + let fromCellBoundaryNode; + let toCellBoundaryNode; + for (let i = $from.depth; i > 0; i--) { + const node = $from.node(i); + if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") { + fromCellBoundaryNode = node; + break; + } + } + for (let i = $to.depth; i > 0; i--) { + const node = $to.node(i); + if (node.type.spec.tableRole === "cell" || node.type.spec.tableRole === "header_cell") { + toCellBoundaryNode = node; + break; + } + } + return fromCellBoundaryNode !== toCellBoundaryNode && $to.parentOffset === 0; +} +function normalizeSelection(state, tr2, allowTableNodeSelection) { + const sel = (tr2 || state).selection; + const doc4 = (tr2 || state).doc; + let normalize2; + let role; + if (sel instanceof NodeSelection && (role = sel.node.type.spec.tableRole)) { + if (role == "cell" || role == "header_cell") normalize2 = CellSelection.create(doc4, sel.from); + else if (role == "row") { + const $cell = doc4.resolve(sel.from + 1); + normalize2 = CellSelection.rowSelection($cell, $cell); + } else if (!allowTableNodeSelection) { + const map4 = TableMap.get(sel.node); + const start = sel.from + 1; + const lastCell = start + map4.map[map4.width * map4.height - 1]; + normalize2 = CellSelection.create(doc4, start + 1, lastCell); + } + } else if (sel instanceof TextSelection && isCellBoundarySelection(sel)) normalize2 = TextSelection.create(doc4, sel.from); + else if (sel instanceof TextSelection && isTextSelectionAcrossCells(sel)) normalize2 = TextSelection.create(doc4, sel.$from.start(), sel.$from.end()); + if (normalize2) (tr2 || (tr2 = state.tr)).setSelection(normalize2); + return tr2; +} +var fixTablesKey = new PluginKey("fix-tables"); +function changedDescendants(old, cur, offset, f) { + const oldSize = old.childCount, curSize = cur.childCount; + outer: for (let i = 0, j2 = 0; i < curSize; i++) { + const child = cur.child(i); + for (let scan = j2, e = Math.min(oldSize, i + 3); scan < e; scan++) if (old.child(scan) == child) { + j2 = scan + 1; + offset += child.nodeSize; + continue outer; + } + f(child, offset); + if (j2 < oldSize && old.child(j2).sameMarkup(child)) changedDescendants(old.child(j2), child, offset + 1, f); + else child.nodesBetween(0, child.content.size, f, offset + 1); + offset += child.nodeSize; + } +} +function fixTables(state, oldState) { + let tr2; + const check = (node, pos) => { + if (node.type.spec.tableRole == "table") tr2 = fixTable(state, node, pos, tr2); + }; + if (!oldState) state.doc.descendants(check); + else if (oldState.doc != state.doc) changedDescendants(oldState.doc, state.doc, 0, check); + return tr2; +} +function fixTable(state, table, tablePos, tr2) { + const map4 = TableMap.get(table); + if (!map4.problems) return tr2; + if (!tr2) tr2 = state.tr; + const mustAdd = []; + for (let i = 0; i < map4.height; i++) mustAdd.push(0); + for (let i = 0; i < map4.problems.length; i++) { + const prob = map4.problems[i]; + if (prob.type == "collision") { + const cell2 = table.nodeAt(prob.pos); + if (!cell2) continue; + const attrs = cell2.attrs; + for (let j2 = 0; j2 < attrs.rowspan; j2++) mustAdd[prob.row + j2] += prob.n; + tr2.setNodeMarkup(tr2.mapping.map(tablePos + 1 + prob.pos), null, removeColSpan(attrs, attrs.colspan - prob.n, prob.n)); + } else if (prob.type == "missing") mustAdd[prob.row] += prob.n; + else if (prob.type == "overlong_rowspan") { + const cell2 = table.nodeAt(prob.pos); + if (!cell2) continue; + tr2.setNodeMarkup(tr2.mapping.map(tablePos + 1 + prob.pos), null, { + ...cell2.attrs, + rowspan: cell2.attrs.rowspan - prob.n + }); + } else if (prob.type == "colwidth mismatch") { + const cell2 = table.nodeAt(prob.pos); + if (!cell2) continue; + tr2.setNodeMarkup(tr2.mapping.map(tablePos + 1 + prob.pos), null, { + ...cell2.attrs, + colwidth: prob.colwidth + }); + } else if (prob.type == "zero_sized") { + const pos = tr2.mapping.map(tablePos); + tr2.delete(pos, pos + table.nodeSize); + } + } + let first2, last2; + for (let i = 0; i < mustAdd.length; i++) if (mustAdd[i]) { + if (first2 == null) first2 = i; + last2 = i; + } + for (let i = 0, pos = tablePos + 1; i < map4.height; i++) { + const row = table.child(i); + const end = pos + row.nodeSize; + const add = mustAdd[i]; + if (add > 0) { + let role = "cell"; + if (row.firstChild) role = row.firstChild.type.spec.tableRole; + const nodes = []; + for (let j2 = 0; j2 < add; j2++) { + const node = tableNodeTypes(state.schema)[role].createAndFill(); + if (node) nodes.push(node); + } + const side = (i == 0 || first2 == i - 1) && last2 == i ? pos + 1 : end - 1; + tr2.insert(tr2.mapping.map(side), nodes); + } + pos = end; + } + return tr2.setMeta(fixTablesKey, { fixTables: true }); +} +function selectedRect(state) { + const sel = state.selection; + const $pos = selectionCell(state); + const table = $pos.node(-1); + const tableStart = $pos.start(-1); + const map4 = TableMap.get(table); + return { + ...sel instanceof CellSelection ? map4.rectBetween(sel.$anchorCell.pos - tableStart, sel.$headCell.pos - tableStart) : map4.findCell($pos.pos - tableStart), + tableStart, + map: map4, + table + }; +} +function addColumn(tr2, { map: map4, tableStart, table }, col) { + let refColumn = col > 0 ? -1 : 0; + if (columnIsHeader(map4, table, col + refColumn)) refColumn = col == 0 || col == map4.width ? null : 0; + for (let row = 0; row < map4.height; row++) { + const index = row * map4.width + col; + if (col > 0 && col < map4.width && map4.map[index - 1] == map4.map[index]) { + const pos = map4.map[index]; + const cell2 = table.nodeAt(pos); + tr2.setNodeMarkup(tr2.mapping.map(tableStart + pos), null, addColSpan(cell2.attrs, col - map4.colCount(pos))); + row += cell2.attrs.rowspan - 1; + } else { + const type = refColumn == null ? tableNodeTypes(table.type.schema).cell : table.nodeAt(map4.map[index + refColumn]).type; + const pos = map4.positionAt(row, col, table); + tr2.insert(tr2.mapping.map(tableStart + pos), type.createAndFill()); + } + } + return tr2; +} +function addColumnBefore(state, dispatch) { + if (!isInTable(state)) return false; + if (dispatch) { + const rect = selectedRect(state); + dispatch(addColumn(state.tr, rect, rect.left)); + } + return true; +} +function addColumnAfter(state, dispatch) { + if (!isInTable(state)) return false; + if (dispatch) { + const rect = selectedRect(state); + dispatch(addColumn(state.tr, rect, rect.right)); + } + return true; +} +function removeColumn(tr2, { map: map4, table, tableStart }, col) { + const mapStart = tr2.mapping.maps.length; + for (let row = 0; row < map4.height; ) { + const index = row * map4.width + col; + const pos = map4.map[index]; + const cell2 = table.nodeAt(pos); + const attrs = cell2.attrs; + if (col > 0 && map4.map[index - 1] == pos || col < map4.width - 1 && map4.map[index + 1] == pos) tr2.setNodeMarkup(tr2.mapping.slice(mapStart).map(tableStart + pos), null, removeColSpan(attrs, col - map4.colCount(pos))); + else { + const start = tr2.mapping.slice(mapStart).map(tableStart + pos); + tr2.delete(start, start + cell2.nodeSize); + } + row += attrs.rowspan; + } +} +function deleteColumn(state, dispatch) { + if (!isInTable(state)) return false; + if (dispatch) { + const rect = selectedRect(state); + const tr2 = state.tr; + if (rect.left == 0 && rect.right == rect.map.width) return false; + for (let i = rect.right - 1; ; i--) { + removeColumn(tr2, rect, i); + if (i == rect.left) break; + const table = rect.tableStart ? tr2.doc.nodeAt(rect.tableStart - 1) : tr2.doc; + if (!table) throw new RangeError("No table found"); + rect.table = table; + rect.map = TableMap.get(table); + } + dispatch(tr2); + } + return true; +} +function rowIsHeader(map4, table, row) { + var _table$nodeAt; + const headerCell = tableNodeTypes(table.type.schema).header_cell; + for (let col = 0; col < map4.width; col++) if (((_table$nodeAt = table.nodeAt(map4.map[col + row * map4.width])) === null || _table$nodeAt === void 0 ? void 0 : _table$nodeAt.type) != headerCell) return false; + return true; +} +function addRow(tr2, { map: map4, tableStart, table }, row) { + let rowPos = tableStart; + for (let i = 0; i < row; i++) rowPos += table.child(i).nodeSize; + const cells = []; + let refRow = row > 0 ? -1 : 0; + if (rowIsHeader(map4, table, row + refRow)) refRow = row == 0 || row == map4.height ? null : 0; + for (let col = 0, index = map4.width * row; col < map4.width; col++, index++) if (row > 0 && row < map4.height && map4.map[index] == map4.map[index - map4.width]) { + const pos = map4.map[index]; + const attrs = table.nodeAt(pos).attrs; + tr2.setNodeMarkup(tableStart + pos, null, { + ...attrs, + rowspan: attrs.rowspan + 1 + }); + col += attrs.colspan - 1; + } else { + var _table$nodeAt2; + const type = refRow == null ? tableNodeTypes(table.type.schema).cell : (_table$nodeAt2 = table.nodeAt(map4.map[index + refRow * map4.width])) === null || _table$nodeAt2 === void 0 ? void 0 : _table$nodeAt2.type; + const node = type === null || type === void 0 ? void 0 : type.createAndFill(); + if (node) cells.push(node); + } + tr2.insert(rowPos, tableNodeTypes(table.type.schema).row.create(null, cells)); + return tr2; +} +function addRowBefore(state, dispatch) { + if (!isInTable(state)) return false; + if (dispatch) { + const rect = selectedRect(state); + dispatch(addRow(state.tr, rect, rect.top)); + } + return true; +} +function addRowAfter(state, dispatch) { + if (!isInTable(state)) return false; + if (dispatch) { + const rect = selectedRect(state); + dispatch(addRow(state.tr, rect, rect.bottom)); + } + return true; +} +function removeRow(tr2, { map: map4, table, tableStart }, row) { + let rowPos = 0; + for (let i = 0; i < row; i++) rowPos += table.child(i).nodeSize; + const nextRow = rowPos + table.child(row).nodeSize; + const mapFrom = tr2.mapping.maps.length; + tr2.delete(rowPos + tableStart, nextRow + tableStart); + const seen = /* @__PURE__ */ new Set(); + for (let col = 0, index = row * map4.width; col < map4.width; col++, index++) { + const pos = map4.map[index]; + if (seen.has(pos)) continue; + seen.add(pos); + if (row > 0 && pos == map4.map[index - map4.width]) { + const attrs = table.nodeAt(pos).attrs; + tr2.setNodeMarkup(tr2.mapping.slice(mapFrom).map(pos + tableStart), null, { + ...attrs, + rowspan: attrs.rowspan - 1 + }); + col += attrs.colspan - 1; + } else if (row < map4.height && pos == map4.map[index + map4.width]) { + const cell2 = table.nodeAt(pos); + const attrs = cell2.attrs; + const copy3 = cell2.type.create({ + ...attrs, + rowspan: cell2.attrs.rowspan - 1 + }, cell2.content); + const newPos = map4.positionAt(row + 1, col, table); + tr2.insert(tr2.mapping.slice(mapFrom).map(tableStart + newPos), copy3); + col += attrs.colspan - 1; + } + } +} +function deleteRow(state, dispatch) { + if (!isInTable(state)) return false; + if (dispatch) { + const rect = selectedRect(state), tr2 = state.tr; + if (rect.top == 0 && rect.bottom == rect.map.height) return false; + for (let i = rect.bottom - 1; ; i--) { + removeRow(tr2, rect, i); + if (i == rect.top) break; + const table = rect.tableStart ? tr2.doc.nodeAt(rect.tableStart - 1) : tr2.doc; + if (!table) throw new RangeError("No table found"); + rect.table = table; + rect.map = TableMap.get(rect.table); + } + dispatch(tr2); + } + return true; +} +function isEmpty2(cell2) { + const c = cell2.content; + return c.childCount == 1 && c.child(0).isTextblock && c.child(0).childCount == 0; +} +function cellsOverlapRectangle({ width, height, map: map4 }, rect) { + let indexTop = rect.top * width + rect.left, indexLeft = indexTop; + let indexBottom = (rect.bottom - 1) * width + rect.left, indexRight = indexTop + (rect.right - rect.left - 1); + for (let i = rect.top; i < rect.bottom; i++) { + if (rect.left > 0 && map4[indexLeft] == map4[indexLeft - 1] || rect.right < width && map4[indexRight] == map4[indexRight + 1]) return true; + indexLeft += width; + indexRight += width; + } + for (let i = rect.left; i < rect.right; i++) { + if (rect.top > 0 && map4[indexTop] == map4[indexTop - width] || rect.bottom < height && map4[indexBottom] == map4[indexBottom + width]) return true; + indexTop++; + indexBottom++; + } + return false; +} +function mergeCells(state, dispatch) { + const sel = state.selection; + if (!(sel instanceof CellSelection) || sel.$anchorCell.pos == sel.$headCell.pos) return false; + const rect = selectedRect(state), { map: map4 } = rect; + if (cellsOverlapRectangle(map4, rect)) return false; + if (dispatch) { + const tr2 = state.tr; + const seen = {}; + let content = Fragment.empty; + let mergedPos; + let mergedCell; + for (let row = rect.top; row < rect.bottom; row++) for (let col = rect.left; col < rect.right; col++) { + const cellPos = map4.map[row * map4.width + col]; + const cell2 = rect.table.nodeAt(cellPos); + if (seen[cellPos] || !cell2) continue; + seen[cellPos] = true; + if (mergedPos == null) { + mergedPos = cellPos; + mergedCell = cell2; + } else { + if (!isEmpty2(cell2)) content = content.append(cell2.content); + const mapped = tr2.mapping.map(cellPos + rect.tableStart); + tr2.delete(mapped, mapped + cell2.nodeSize); + } + } + if (mergedPos == null || mergedCell == null) return true; + tr2.setNodeMarkup(mergedPos + rect.tableStart, null, { + ...addColSpan(mergedCell.attrs, mergedCell.attrs.colspan, rect.right - rect.left - mergedCell.attrs.colspan), + rowspan: rect.bottom - rect.top + }); + if (content.size > 0) { + const end = mergedPos + 1 + mergedCell.content.size; + const start = isEmpty2(mergedCell) ? mergedPos + 1 : end; + tr2.replaceWith(start + rect.tableStart, end + rect.tableStart, content); + } + tr2.setSelection(new CellSelection(tr2.doc.resolve(mergedPos + rect.tableStart))); + dispatch(tr2); + } + return true; +} +function splitCell(state, dispatch) { + const nodeTypes = tableNodeTypes(state.schema); + return splitCellWithType(({ node }) => { + return nodeTypes[node.type.spec.tableRole]; + })(state, dispatch); +} +function splitCellWithType(getCellType) { + return (state, dispatch) => { + const sel = state.selection; + let cellNode; + let cellPos; + if (!(sel instanceof CellSelection)) { + var _cellAround; + cellNode = cellWrapping(sel.$from); + if (!cellNode) return false; + cellPos = (_cellAround = cellAround(sel.$from)) === null || _cellAround === void 0 ? void 0 : _cellAround.pos; + } else { + if (sel.$anchorCell.pos != sel.$headCell.pos) return false; + cellNode = sel.$anchorCell.nodeAfter; + cellPos = sel.$anchorCell.pos; + } + if (cellNode == null || cellPos == null) return false; + if (cellNode.attrs.colspan == 1 && cellNode.attrs.rowspan == 1) return false; + if (dispatch) { + let baseAttrs = cellNode.attrs; + const attrs = []; + const colwidth = baseAttrs.colwidth; + if (baseAttrs.rowspan > 1) baseAttrs = { + ...baseAttrs, + rowspan: 1 + }; + if (baseAttrs.colspan > 1) baseAttrs = { + ...baseAttrs, + colspan: 1 + }; + const rect = selectedRect(state), tr2 = state.tr; + for (let i = 0; i < rect.right - rect.left; i++) attrs.push(colwidth ? { + ...baseAttrs, + colwidth: colwidth && colwidth[i] ? [colwidth[i]] : null + } : baseAttrs); + let lastCell; + for (let row = rect.top; row < rect.bottom; row++) { + let pos = rect.map.positionAt(row, rect.left, rect.table); + if (row == rect.top) pos += cellNode.nodeSize; + for (let col = rect.left, i = 0; col < rect.right; col++, i++) { + if (col == rect.left && row == rect.top) continue; + tr2.insert(lastCell = tr2.mapping.map(pos + rect.tableStart, 1), getCellType({ + node: cellNode, + row, + col + }).createAndFill(attrs[i])); + } + } + tr2.setNodeMarkup(cellPos, getCellType({ + node: cellNode, + row: rect.top, + col: rect.left + }), attrs[0]); + if (sel instanceof CellSelection) tr2.setSelection(new CellSelection(tr2.doc.resolve(sel.$anchorCell.pos), lastCell ? tr2.doc.resolve(lastCell) : void 0)); + dispatch(tr2); + } + return true; + }; +} +function setCellAttr(name, value) { + return function(state, dispatch) { + if (!isInTable(state)) return false; + const $cell = selectionCell(state); + if ($cell.nodeAfter.attrs[name] === value) return false; + if (dispatch) { + const tr2 = state.tr; + if (state.selection instanceof CellSelection) state.selection.forEachCell((node, pos) => { + if (node.attrs[name] !== value) tr2.setNodeMarkup(pos, null, { + ...node.attrs, + [name]: value + }); + }); + else tr2.setNodeMarkup($cell.pos, null, { + ...$cell.nodeAfter.attrs, + [name]: value + }); + dispatch(tr2); + } + return true; + }; +} +function deprecated_toggleHeader(type) { + return function(state, dispatch) { + if (!isInTable(state)) return false; + if (dispatch) { + const types = tableNodeTypes(state.schema); + const rect = selectedRect(state), tr2 = state.tr; + const cells = rect.map.cellsInRect(type == "column" ? { + left: rect.left, + top: 0, + right: rect.right, + bottom: rect.map.height + } : type == "row" ? { + left: 0, + top: rect.top, + right: rect.map.width, + bottom: rect.bottom + } : rect); + const nodes = cells.map((pos) => rect.table.nodeAt(pos)); + for (let i = 0; i < cells.length; i++) if (nodes[i].type == types.header_cell) tr2.setNodeMarkup(rect.tableStart + cells[i], types.cell, nodes[i].attrs); + if (tr2.steps.length === 0) for (let i = 0; i < cells.length; i++) tr2.setNodeMarkup(rect.tableStart + cells[i], types.header_cell, nodes[i].attrs); + dispatch(tr2); + } + return true; + }; +} +function isHeaderEnabledByType(type, rect, types) { + const cellPositions = rect.map.cellsInRect({ + left: 0, + top: 0, + right: type == "row" ? rect.map.width : 1, + bottom: type == "column" ? rect.map.height : 1 + }); + for (let i = 0; i < cellPositions.length; i++) { + const cell2 = rect.table.nodeAt(cellPositions[i]); + if (cell2 && cell2.type !== types.header_cell) return false; + } + return true; +} +function toggleHeader(type, options) { + options = options || { useDeprecatedLogic: false }; + if (options.useDeprecatedLogic) return deprecated_toggleHeader(type); + return function(state, dispatch) { + if (!isInTable(state)) return false; + if (dispatch) { + const types = tableNodeTypes(state.schema); + const rect = selectedRect(state), tr2 = state.tr; + const isHeaderRowEnabled = isHeaderEnabledByType("row", rect, types); + const isHeaderColumnEnabled = isHeaderEnabledByType("column", rect, types); + const selectionStartsAt = (type === "column" ? isHeaderRowEnabled : type === "row" ? isHeaderColumnEnabled : false) ? 1 : 0; + const cellsRect = type == "column" ? { + left: 0, + top: selectionStartsAt, + right: 1, + bottom: rect.map.height + } : type == "row" ? { + left: selectionStartsAt, + top: 0, + right: rect.map.width, + bottom: 1 + } : rect; + const newType = type == "column" ? isHeaderColumnEnabled ? types.cell : types.header_cell : type == "row" ? isHeaderRowEnabled ? types.cell : types.header_cell : types.cell; + rect.map.cellsInRect(cellsRect).forEach((relativeCellPos) => { + const cellPos = relativeCellPos + rect.tableStart; + const cell2 = tr2.doc.nodeAt(cellPos); + if (cell2) tr2.setNodeMarkup(cellPos, newType, cell2.attrs); + }); + dispatch(tr2); + } + return true; + }; +} +var toggleHeaderRow = toggleHeader("row", { useDeprecatedLogic: true }); +var toggleHeaderColumn = toggleHeader("column", { useDeprecatedLogic: true }); +var toggleHeaderCell = toggleHeader("cell", { useDeprecatedLogic: true }); +function findNextCell($cell, dir) { + if (dir < 0) { + const before = $cell.nodeBefore; + if (before) return $cell.pos - before.nodeSize; + for (let row = $cell.index(-1) - 1, rowEnd = $cell.before(); row >= 0; row--) { + const rowNode = $cell.node(-1).child(row); + const lastChild = rowNode.lastChild; + if (lastChild) return rowEnd - 1 - lastChild.nodeSize; + rowEnd -= rowNode.nodeSize; + } + } else { + if ($cell.index() < $cell.parent.childCount - 1) return $cell.pos + $cell.nodeAfter.nodeSize; + const table = $cell.node(-1); + for (let row = $cell.indexAfter(-1), rowStart = $cell.after(); row < table.childCount; row++) { + const rowNode = table.child(row); + if (rowNode.childCount) return rowStart + 1; + rowStart += rowNode.nodeSize; + } + } + return null; +} +function goToNextCell(direction) { + return function(state, dispatch) { + if (!isInTable(state)) return false; + const cell2 = findNextCell(selectionCell(state), direction); + if (cell2 == null) return false; + if (dispatch) { + const $cell = state.doc.resolve(cell2); + dispatch(state.tr.setSelection(TextSelection.between($cell, moveCellForward($cell))).scrollIntoView()); + } + return true; + }; +} +function deleteTable(state, dispatch) { + const $pos = state.selection.$anchor; + for (let d2 = $pos.depth; d2 > 0; d2--) if ($pos.node(d2).type.spec.tableRole == "table") { + if (dispatch) dispatch(state.tr.delete($pos.before(d2), $pos.after(d2)).scrollIntoView()); + return true; + } + return false; +} +function deleteCellSelection(state, dispatch) { + const sel = state.selection; + if (!(sel instanceof CellSelection)) return false; + if (dispatch) { + const tr2 = state.tr; + const baseContent = tableNodeTypes(state.schema).cell.createAndFill().content; + sel.forEachCell((cell2, pos) => { + if (!cell2.content.eq(baseContent)) tr2.replace(tr2.mapping.map(pos + 1), tr2.mapping.map(pos + cell2.nodeSize - 1), new Slice(baseContent, 0, 0)); + }); + if (tr2.docChanged) dispatch(tr2); + } + return true; +} +function pastedCells(slice2) { + if (slice2.size === 0) return null; + let { content, openStart, openEnd } = slice2; + while (content.childCount == 1 && (openStart > 0 && openEnd > 0 || content.child(0).type.spec.tableRole == "table")) { + openStart--; + openEnd--; + content = content.child(0).content; + } + const first2 = content.child(0); + const role = first2.type.spec.tableRole; + const schema = first2.type.schema, rows = []; + if (role == "row") for (let i = 0; i < content.childCount; i++) { + let cells = content.child(i).content; + const left = i ? 0 : Math.max(0, openStart - 1); + const right = i < content.childCount - 1 ? 0 : Math.max(0, openEnd - 1); + if (left || right) cells = fitSlice(tableNodeTypes(schema).row, new Slice(cells, left, right)).content; + rows.push(cells); + } + else if (role == "cell" || role == "header_cell") rows.push(openStart || openEnd ? fitSlice(tableNodeTypes(schema).row, new Slice(content, openStart, openEnd)).content : content); + else return null; + return ensureRectangular(schema, rows); +} +function ensureRectangular(schema, rows) { + const widths = []; + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + for (let j2 = row.childCount - 1; j2 >= 0; j2--) { + const { rowspan, colspan } = row.child(j2).attrs; + for (let r = i; r < i + rowspan; r++) widths[r] = (widths[r] || 0) + colspan; + } + } + let width = 0; + for (let r = 0; r < widths.length; r++) width = Math.max(width, widths[r]); + for (let r = 0; r < widths.length; r++) { + if (r >= rows.length) rows.push(Fragment.empty); + if (widths[r] < width) { + const empty2 = tableNodeTypes(schema).cell.createAndFill(); + const cells = []; + for (let i = widths[r]; i < width; i++) cells.push(empty2); + rows[r] = rows[r].append(Fragment.from(cells)); + } + } + return { + height: rows.length, + width, + rows + }; +} +function fitSlice(nodeType, slice2) { + const node = nodeType.createAndFill(); + return new Transform(node).replace(0, node.content.size, slice2).doc; +} +function clipCells({ width, height, rows }, newWidth, newHeight) { + if (width != newWidth) { + const added = []; + const newRows = []; + for (let row = 0; row < rows.length; row++) { + const frag = rows[row], cells = []; + for (let col = added[row] || 0, i = 0; col < newWidth; i++) { + let cell2 = frag.child(i % frag.childCount); + if (col + cell2.attrs.colspan > newWidth) cell2 = cell2.type.createChecked(removeColSpan(cell2.attrs, cell2.attrs.colspan, col + cell2.attrs.colspan - newWidth), cell2.content); + cells.push(cell2); + col += cell2.attrs.colspan; + for (let j2 = 1; j2 < cell2.attrs.rowspan; j2++) added[row + j2] = (added[row + j2] || 0) + cell2.attrs.colspan; + } + newRows.push(Fragment.from(cells)); + } + rows = newRows; + width = newWidth; + } + if (height != newHeight) { + const newRows = []; + for (let row = 0, i = 0; row < newHeight; row++, i++) { + const cells = [], source = rows[i % height]; + for (let j2 = 0; j2 < source.childCount; j2++) { + let cell2 = source.child(j2); + if (row + cell2.attrs.rowspan > newHeight) cell2 = cell2.type.create({ + ...cell2.attrs, + rowspan: Math.max(1, newHeight - cell2.attrs.rowspan) + }, cell2.content); + cells.push(cell2); + } + newRows.push(Fragment.from(cells)); + } + rows = newRows; + height = newHeight; + } + return { + width, + height, + rows + }; +} +function growTable(tr2, map4, table, start, width, height, mapFrom) { + const schema = tr2.doc.type.schema; + const types = tableNodeTypes(schema); + let empty2; + let emptyHead; + if (width > map4.width) for (let row = 0, rowEnd = 0; row < map4.height; row++) { + const rowNode = table.child(row); + rowEnd += rowNode.nodeSize; + const cells = []; + let add; + if (rowNode.lastChild == null || rowNode.lastChild.type == types.cell) add = empty2 || (empty2 = types.cell.createAndFill()); + else add = emptyHead || (emptyHead = types.header_cell.createAndFill()); + for (let i = map4.width; i < width; i++) cells.push(add); + tr2.insert(tr2.mapping.slice(mapFrom).map(rowEnd - 1 + start), cells); + } + if (height > map4.height) { + const cells = []; + for (let i = 0, start$1 = (map4.height - 1) * map4.width; i < Math.max(map4.width, width); i++) { + const header = i >= map4.width ? false : table.nodeAt(map4.map[start$1 + i]).type == types.header_cell; + cells.push(header ? emptyHead || (emptyHead = types.header_cell.createAndFill()) : empty2 || (empty2 = types.cell.createAndFill())); + } + const emptyRow = types.row.create(null, Fragment.from(cells)), rows = []; + for (let i = map4.height; i < height; i++) rows.push(emptyRow); + tr2.insert(tr2.mapping.slice(mapFrom).map(start + table.nodeSize - 2), rows); + } + return !!(empty2 || emptyHead); +} +function isolateHorizontal(tr2, map4, table, start, left, right, top, mapFrom) { + if (top == 0 || top == map4.height) return false; + let found3 = false; + for (let col = left; col < right; col++) { + const index = top * map4.width + col, pos = map4.map[index]; + if (map4.map[index - map4.width] == pos) { + found3 = true; + const cell2 = table.nodeAt(pos); + const { top: cellTop, left: cellLeft } = map4.findCell(pos); + tr2.setNodeMarkup(tr2.mapping.slice(mapFrom).map(pos + start), null, { + ...cell2.attrs, + rowspan: top - cellTop + }); + tr2.insert(tr2.mapping.slice(mapFrom).map(map4.positionAt(top, cellLeft, table)), cell2.type.createAndFill({ + ...cell2.attrs, + rowspan: cellTop + cell2.attrs.rowspan - top + })); + col += cell2.attrs.colspan - 1; + } + } + return found3; +} +function isolateVertical(tr2, map4, table, start, top, bottom, left, mapFrom) { + if (left == 0 || left == map4.width) return false; + let found3 = false; + for (let row = top; row < bottom; row++) { + const index = row * map4.width + left, pos = map4.map[index]; + if (map4.map[index - 1] == pos) { + found3 = true; + const cell2 = table.nodeAt(pos); + const cellLeft = map4.colCount(pos); + const updatePos = tr2.mapping.slice(mapFrom).map(pos + start); + tr2.setNodeMarkup(updatePos, null, removeColSpan(cell2.attrs, left - cellLeft, cell2.attrs.colspan - (left - cellLeft))); + tr2.insert(updatePos + cell2.nodeSize, cell2.type.createAndFill(removeColSpan(cell2.attrs, 0, left - cellLeft))); + row += cell2.attrs.rowspan - 1; + } + } + return found3; +} +function insertCells(state, dispatch, tableStart, rect, cells) { + let table = tableStart ? state.doc.nodeAt(tableStart - 1) : state.doc; + if (!table) throw new Error("No table found"); + let map4 = TableMap.get(table); + const { top, left } = rect; + const right = left + cells.width, bottom = top + cells.height; + const tr2 = state.tr; + let mapFrom = 0; + function recomp() { + table = tableStart ? tr2.doc.nodeAt(tableStart - 1) : tr2.doc; + if (!table) throw new Error("No table found"); + map4 = TableMap.get(table); + mapFrom = tr2.mapping.maps.length; + } + if (growTable(tr2, map4, table, tableStart, right, bottom, mapFrom)) recomp(); + if (isolateHorizontal(tr2, map4, table, tableStart, left, right, top, mapFrom)) recomp(); + if (isolateHorizontal(tr2, map4, table, tableStart, left, right, bottom, mapFrom)) recomp(); + if (isolateVertical(tr2, map4, table, tableStart, top, bottom, left, mapFrom)) recomp(); + if (isolateVertical(tr2, map4, table, tableStart, top, bottom, right, mapFrom)) recomp(); + for (let row = top; row < bottom; row++) { + const from3 = map4.positionAt(row, left, table), to = map4.positionAt(row, right, table); + tr2.replace(tr2.mapping.slice(mapFrom).map(from3 + tableStart), tr2.mapping.slice(mapFrom).map(to + tableStart), new Slice(cells.rows[row - top], 0, 0)); + } + recomp(); + tr2.setSelection(new CellSelection(tr2.doc.resolve(tableStart + map4.positionAt(top, left, table)), tr2.doc.resolve(tableStart + map4.positionAt(bottom - 1, right - 1, table)))); + dispatch(tr2); +} +var handleKeyDown2 = keydownHandler({ + ArrowLeft: arrow2("horiz", -1), + ArrowRight: arrow2("horiz", 1), + ArrowUp: arrow2("vert", -1), + ArrowDown: arrow2("vert", 1), + "Shift-ArrowLeft": shiftArrow("horiz", -1), + "Shift-ArrowRight": shiftArrow("horiz", 1), + "Shift-ArrowUp": shiftArrow("vert", -1), + "Shift-ArrowDown": shiftArrow("vert", 1), + Backspace: deleteCellSelection, + "Mod-Backspace": deleteCellSelection, + Delete: deleteCellSelection, + "Mod-Delete": deleteCellSelection +}); +function maybeSetSelection(state, dispatch, selection) { + if (selection.eq(state.selection)) return false; + if (dispatch) dispatch(state.tr.setSelection(selection).scrollIntoView()); + return true; +} +function arrow2(axis, dir) { + return (state, dispatch, view) => { + if (!view) return false; + const sel = state.selection; + if (sel instanceof CellSelection) return maybeSetSelection(state, dispatch, Selection.near(sel.$headCell, dir)); + if (axis != "horiz" && !sel.empty) return false; + const end = atEndOfCell(view, axis, dir); + if (end == null) return false; + if (axis == "horiz") return maybeSetSelection(state, dispatch, Selection.near(state.doc.resolve(sel.head + dir), dir)); + else { + const $cell = state.doc.resolve(end); + const $next = nextCell($cell, axis, dir); + let newSel; + if ($next) newSel = Selection.near($next, 1); + else if (dir < 0) newSel = Selection.near(state.doc.resolve($cell.before(-1)), -1); + else newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1); + return maybeSetSelection(state, dispatch, newSel); + } + }; +} +function shiftArrow(axis, dir) { + return (state, dispatch, view) => { + if (!view) return false; + const sel = state.selection; + let cellSel; + if (sel instanceof CellSelection) cellSel = sel; + else { + const end = atEndOfCell(view, axis, dir); + if (end == null) return false; + cellSel = new CellSelection(state.doc.resolve(end)); + } + const $head = nextCell(cellSel.$headCell, axis, dir); + if (!$head) return false; + return maybeSetSelection(state, dispatch, new CellSelection(cellSel.$anchorCell, $head)); + }; +} +function handleTripleClick2(view, pos) { + const doc4 = view.state.doc, $cell = cellAround(doc4.resolve(pos)); + if (!$cell) return false; + view.dispatch(view.state.tr.setSelection(new CellSelection($cell))); + return true; +} +function handlePaste(view, _2, slice2) { + if (!isInTable(view.state)) return false; + let cells = pastedCells(slice2); + const sel = view.state.selection; + if (sel instanceof CellSelection) { + if (!cells) cells = { + width: 1, + height: 1, + rows: [Fragment.from(fitSlice(tableNodeTypes(view.state.schema).cell, slice2))] + }; + const table = sel.$anchorCell.node(-1); + const start = sel.$anchorCell.start(-1); + const rect = TableMap.get(table).rectBetween(sel.$anchorCell.pos - start, sel.$headCell.pos - start); + cells = clipCells(cells, rect.right - rect.left, rect.bottom - rect.top); + insertCells(view.state, view.dispatch, start, rect, cells); + return true; + } else if (cells) { + const $cell = selectionCell(view.state); + const start = $cell.start(-1); + insertCells(view.state, view.dispatch, start, TableMap.get($cell.node(-1)).findCell($cell.pos - start), cells); + return true; + } else return false; +} +function handleMouseDown$1(view, startEvent) { + var _cellUnderMouse; + if (startEvent.button != 0) return; + if (startEvent.ctrlKey || startEvent.metaKey) return; + const startDOMCell = domInCell(view, startEvent.target); + let $anchor; + if (startEvent.shiftKey && view.state.selection instanceof CellSelection) { + setCellSelection(view.state.selection.$anchorCell, startEvent); + startEvent.preventDefault(); + } else if (startEvent.shiftKey && startDOMCell && ($anchor = cellAround(view.state.selection.$anchor)) != null && ((_cellUnderMouse = cellUnderMouse(view, startEvent)) === null || _cellUnderMouse === void 0 ? void 0 : _cellUnderMouse.pos) != $anchor.pos) { + setCellSelection($anchor, startEvent); + startEvent.preventDefault(); + } else if (!startDOMCell) return; + function setCellSelection($anchor$1, event) { + let $head = cellUnderMouse(view, event); + const starting = tableEditingKey.getState(view.state) == null; + if (!$head || !inSameTable($anchor$1, $head)) if (starting) $head = $anchor$1; + else return; + const selection = new CellSelection($anchor$1, $head); + if (starting || !view.state.selection.eq(selection)) { + const tr2 = view.state.tr.setSelection(selection); + if (starting) tr2.setMeta(tableEditingKey, $anchor$1.pos); + view.dispatch(tr2); + } + } + function stop() { + view.root.removeEventListener("mouseup", stop); + view.root.removeEventListener("dragstart", stop); + view.root.removeEventListener("mousemove", move); + if (tableEditingKey.getState(view.state) != null) view.dispatch(view.state.tr.setMeta(tableEditingKey, -1)); + } + function move(_event) { + const event = _event; + const anchor = tableEditingKey.getState(view.state); + let $anchor$1; + if (anchor != null) $anchor$1 = view.state.doc.resolve(anchor); + else if (domInCell(view, event.target) != startDOMCell) { + $anchor$1 = cellUnderMouse(view, startEvent); + if (!$anchor$1) return stop(); + } + if ($anchor$1) setCellSelection($anchor$1, event); + } + view.root.addEventListener("mouseup", stop); + view.root.addEventListener("dragstart", stop); + view.root.addEventListener("mousemove", move); +} +function atEndOfCell(view, axis, dir) { + if (!(view.state.selection instanceof TextSelection)) return null; + const { $head } = view.state.selection; + for (let d2 = $head.depth - 1; d2 >= 0; d2--) { + const parent = $head.node(d2); + if ((dir < 0 ? $head.index(d2) : $head.indexAfter(d2)) != (dir < 0 ? 0 : parent.childCount)) return null; + if (parent.type.spec.tableRole == "cell" || parent.type.spec.tableRole == "header_cell") { + const cellPos = $head.before(d2); + const dirStr = axis == "vert" ? dir > 0 ? "down" : "up" : dir > 0 ? "right" : "left"; + return view.endOfTextblock(dirStr) ? cellPos : null; + } + } + return null; +} +function domInCell(view, dom) { + for (; dom && dom != view.dom; dom = dom.parentNode) if (dom.nodeName == "TD" || dom.nodeName == "TH") return dom; + return null; +} +function cellUnderMouse(view, event) { + const mousePos = view.posAtCoords({ + left: event.clientX, + top: event.clientY + }); + if (!mousePos) return null; + let { inside, pos } = mousePos; + return inside >= 0 && cellAround(view.state.doc.resolve(inside)) || cellAround(view.state.doc.resolve(pos)); +} +var TableView = class { + constructor(node, defaultCellMinWidth) { + this.node = node; + this.defaultCellMinWidth = defaultCellMinWidth; + this.dom = document.createElement("div"); + this.dom.className = "tableWrapper"; + this.table = this.dom.appendChild(document.createElement("table")); + this.table.style.setProperty("--default-cell-min-width", `${defaultCellMinWidth}px`); + this.colgroup = this.table.appendChild(document.createElement("colgroup")); + updateColumnsOnResize(node, this.colgroup, this.table, defaultCellMinWidth); + this.contentDOM = this.table.appendChild(document.createElement("tbody")); + } + update(node) { + if (node.type != this.node.type) return false; + this.node = node; + updateColumnsOnResize(node, this.colgroup, this.table, this.defaultCellMinWidth); + return true; + } + ignoreMutation(record) { + return record.type == "attributes" && (record.target == this.table || this.colgroup.contains(record.target)); + } +}; +function updateColumnsOnResize(node, colgroup, table, defaultCellMinWidth, overrideCol, overrideValue) { + let totalWidth = 0; + let fixedWidth = true; + let nextDOM = colgroup.firstChild; + const row = node.firstChild; + if (!row) return; + for (let i = 0, col = 0; i < row.childCount; i++) { + const { colspan, colwidth } = row.child(i).attrs; + for (let j2 = 0; j2 < colspan; j2++, col++) { + const hasWidth = overrideCol == col ? overrideValue : colwidth && colwidth[j2]; + const cssWidth = hasWidth ? hasWidth + "px" : ""; + totalWidth += hasWidth || defaultCellMinWidth; + if (!hasWidth) fixedWidth = false; + if (!nextDOM) { + const col$1 = document.createElement("col"); + col$1.style.width = cssWidth; + colgroup.appendChild(col$1); + } else { + if (nextDOM.style.width != cssWidth) nextDOM.style.width = cssWidth; + nextDOM = nextDOM.nextSibling; + } + } + } + while (nextDOM) { + var _nextDOM$parentNode; + const after = nextDOM.nextSibling; + (_nextDOM$parentNode = nextDOM.parentNode) === null || _nextDOM$parentNode === void 0 || _nextDOM$parentNode.removeChild(nextDOM); + nextDOM = after; + } + if (fixedWidth) { + table.style.width = totalWidth + "px"; + table.style.minWidth = ""; + } else { + table.style.width = ""; + table.style.minWidth = totalWidth + "px"; + } +} +var columnResizingPluginKey = new PluginKey("tableColumnResizing"); +function columnResizing({ handleWidth = 5, cellMinWidth = 25, defaultCellMinWidth = 100, View = TableView, lastColumnResizable = true } = {}) { + const plugin = new Plugin({ + key: columnResizingPluginKey, + state: { + init(_2, state) { + var _plugin$spec; + const nodeViews = (_plugin$spec = plugin.spec) === null || _plugin$spec === void 0 || (_plugin$spec = _plugin$spec.props) === null || _plugin$spec === void 0 ? void 0 : _plugin$spec.nodeViews; + const tableName = tableNodeTypes(state.schema).table.name; + if (View && nodeViews) nodeViews[tableName] = (node, view) => { + return new View(node, defaultCellMinWidth, view); + }; + return new ResizeState(-1, false); + }, + apply(tr2, prev) { + return prev.apply(tr2); + } + }, + props: { + attributes: (state) => { + const pluginState = columnResizingPluginKey.getState(state); + return pluginState && pluginState.activeHandle > -1 ? { class: "resize-cursor" } : {}; + }, + handleDOMEvents: { + mousemove: (view, event) => { + handleMouseMove(view, event, handleWidth, lastColumnResizable); + }, + mouseleave: (view) => { + handleMouseLeave(view); + }, + mousedown: (view, event) => { + handleMouseDown(view, event, cellMinWidth, defaultCellMinWidth); + } + }, + decorations: (state) => { + const pluginState = columnResizingPluginKey.getState(state); + if (pluginState && pluginState.activeHandle > -1) return handleDecorations(state, pluginState.activeHandle); + }, + nodeViews: {} + } + }); + return plugin; +} +var ResizeState = class ResizeState2 { + constructor(activeHandle, dragging) { + this.activeHandle = activeHandle; + this.dragging = dragging; + } + apply(tr2) { + const state = this; + const action = tr2.getMeta(columnResizingPluginKey); + if (action && action.setHandle != null) return new ResizeState2(action.setHandle, false); + if (action && action.setDragging !== void 0) return new ResizeState2(state.activeHandle, action.setDragging); + if (state.activeHandle > -1 && tr2.docChanged) { + let handle = tr2.mapping.map(state.activeHandle, -1); + if (!pointsAtCell(tr2.doc.resolve(handle))) handle = -1; + return new ResizeState2(handle, state.dragging); + } + return state; + } +}; +function handleMouseMove(view, event, handleWidth, lastColumnResizable) { + if (!view.editable) return; + const pluginState = columnResizingPluginKey.getState(view.state); + if (!pluginState) return; + if (!pluginState.dragging) { + const target = domCellAround(event.target); + let cell2 = -1; + if (target) { + const { left, right } = target.getBoundingClientRect(); + if (event.clientX - left <= handleWidth) cell2 = edgeCell(view, event, "left", handleWidth); + else if (right - event.clientX <= handleWidth) cell2 = edgeCell(view, event, "right", handleWidth); + } + if (cell2 != pluginState.activeHandle) { + if (!lastColumnResizable && cell2 !== -1) { + const $cell = view.state.doc.resolve(cell2); + const table = $cell.node(-1); + const map4 = TableMap.get(table); + const tableStart = $cell.start(-1); + if (map4.colCount($cell.pos - tableStart) + $cell.nodeAfter.attrs.colspan - 1 == map4.width - 1) return; + } + updateHandle(view, cell2); + } + } +} +function handleMouseLeave(view) { + if (!view.editable) return; + const pluginState = columnResizingPluginKey.getState(view.state); + if (pluginState && pluginState.activeHandle > -1 && !pluginState.dragging) updateHandle(view, -1); +} +function handleMouseDown(view, event, cellMinWidth, defaultCellMinWidth) { + var _view$dom$ownerDocume; + if (!view.editable) return false; + const win = (_view$dom$ownerDocume = view.dom.ownerDocument.defaultView) !== null && _view$dom$ownerDocume !== void 0 ? _view$dom$ownerDocume : window; + const pluginState = columnResizingPluginKey.getState(view.state); + if (!pluginState || pluginState.activeHandle == -1 || pluginState.dragging) return false; + const cell2 = view.state.doc.nodeAt(pluginState.activeHandle); + const width = currentColWidth(view, pluginState.activeHandle, cell2.attrs); + view.dispatch(view.state.tr.setMeta(columnResizingPluginKey, { setDragging: { + startX: event.clientX, + startWidth: width + } })); + function finish(event$1) { + win.removeEventListener("mouseup", finish); + win.removeEventListener("mousemove", move); + const pluginState$1 = columnResizingPluginKey.getState(view.state); + if (pluginState$1 === null || pluginState$1 === void 0 ? void 0 : pluginState$1.dragging) { + updateColumnWidth(view, pluginState$1.activeHandle, draggedWidth(pluginState$1.dragging, event$1, cellMinWidth)); + view.dispatch(view.state.tr.setMeta(columnResizingPluginKey, { setDragging: null })); + } + } + function move(event$1) { + if (!event$1.which) return finish(event$1); + const pluginState$1 = columnResizingPluginKey.getState(view.state); + if (!pluginState$1) return; + if (pluginState$1.dragging) { + const dragged = draggedWidth(pluginState$1.dragging, event$1, cellMinWidth); + displayColumnWidth(view, pluginState$1.activeHandle, dragged, defaultCellMinWidth); + } + } + displayColumnWidth(view, pluginState.activeHandle, width, defaultCellMinWidth); + win.addEventListener("mouseup", finish); + win.addEventListener("mousemove", move); + event.preventDefault(); + return true; +} +function currentColWidth(view, cellPos, { colspan, colwidth }) { + const width = colwidth && colwidth[colwidth.length - 1]; + if (width) return width; + const dom = view.domAtPos(cellPos); + let domWidth = dom.node.childNodes[dom.offset].offsetWidth, parts = colspan; + if (colwidth) { + for (let i = 0; i < colspan; i++) if (colwidth[i]) { + domWidth -= colwidth[i]; + parts--; + } + } + return domWidth / parts; +} +function domCellAround(target) { + while (target && target.nodeName != "TD" && target.nodeName != "TH") target = target.classList && target.classList.contains("ProseMirror") ? null : target.parentNode; + return target; +} +function edgeCell(view, event, side, handleWidth) { + const offset = side == "right" ? -handleWidth : handleWidth; + const found3 = view.posAtCoords({ + left: event.clientX + offset, + top: event.clientY + }); + if (!found3) return -1; + const { pos } = found3; + const $cell = cellAround(view.state.doc.resolve(pos)); + if (!$cell) return -1; + if (side == "right") return $cell.pos; + const map4 = TableMap.get($cell.node(-1)), start = $cell.start(-1); + const index = map4.map.indexOf($cell.pos - start); + return index % map4.width == 0 ? -1 : start + map4.map[index - 1]; +} +function draggedWidth(dragging, event, resizeMinWidth) { + const offset = event.clientX - dragging.startX; + return Math.max(resizeMinWidth, dragging.startWidth + offset); +} +function updateHandle(view, value) { + view.dispatch(view.state.tr.setMeta(columnResizingPluginKey, { setHandle: value })); +} +function updateColumnWidth(view, cell2, width) { + const $cell = view.state.doc.resolve(cell2); + const table = $cell.node(-1), map4 = TableMap.get(table), start = $cell.start(-1); + const col = map4.colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1; + const tr2 = view.state.tr; + for (let row = 0; row < map4.height; row++) { + const mapIndex = row * map4.width + col; + if (row && map4.map[mapIndex] == map4.map[mapIndex - map4.width]) continue; + const pos = map4.map[mapIndex]; + const attrs = table.nodeAt(pos).attrs; + const index = attrs.colspan == 1 ? 0 : col - map4.colCount(pos); + if (attrs.colwidth && attrs.colwidth[index] == width) continue; + const colwidth = attrs.colwidth ? attrs.colwidth.slice() : zeroes(attrs.colspan); + colwidth[index] = width; + tr2.setNodeMarkup(start + pos, null, { + ...attrs, + colwidth + }); + } + if (tr2.docChanged) view.dispatch(tr2); +} +function displayColumnWidth(view, cell2, width, defaultCellMinWidth) { + const $cell = view.state.doc.resolve(cell2); + const table = $cell.node(-1), start = $cell.start(-1); + const col = TableMap.get(table).colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1; + let dom = view.domAtPos($cell.start(-1)).node; + while (dom && dom.nodeName != "TABLE") dom = dom.parentNode; + if (!dom) return; + updateColumnsOnResize(table, dom.firstChild, dom, defaultCellMinWidth, col, width); +} +function zeroes(n) { + return Array(n).fill(0); +} +function handleDecorations(state, cell2) { + const decorations = []; + const $cell = state.doc.resolve(cell2); + const table = $cell.node(-1); + if (!table) return DecorationSet.empty; + const map4 = TableMap.get(table); + const start = $cell.start(-1); + const col = map4.colCount($cell.pos - start) + $cell.nodeAfter.attrs.colspan - 1; + for (let row = 0; row < map4.height; row++) { + const index = col + row * map4.width; + if ((col == map4.width - 1 || map4.map[index] != map4.map[index + 1]) && (row == 0 || map4.map[index] != map4.map[index - map4.width])) { + var _columnResizingPlugin; + const cellPos = map4.map[index]; + const pos = start + cellPos + table.nodeAt(cellPos).nodeSize - 1; + const dom = document.createElement("div"); + dom.className = "column-resize-handle"; + if ((_columnResizingPlugin = columnResizingPluginKey.getState(state)) === null || _columnResizingPlugin === void 0 ? void 0 : _columnResizingPlugin.dragging) decorations.push(Decoration.node(start + cellPos, start + cellPos + table.nodeAt(cellPos).nodeSize, { class: "column-resize-dragging" })); + decorations.push(Decoration.widget(pos, dom)); + } + } + return DecorationSet.create(state.doc, decorations); +} +function tableEditing({ allowTableNodeSelection = false } = {}) { + return new Plugin({ + key: tableEditingKey, + state: { + init() { + return null; + }, + apply(tr2, cur) { + const set = tr2.getMeta(tableEditingKey); + if (set != null) return set == -1 ? null : set; + if (cur == null || !tr2.docChanged) return cur; + const { deleted, pos } = tr2.mapping.mapResult(cur); + return deleted ? null : pos; + } + }, + props: { + decorations: drawCellSelection, + handleDOMEvents: { mousedown: handleMouseDown$1 }, + createSelectionBetween(view) { + return tableEditingKey.getState(view.state) != null ? view.state.selection : null; + }, + handleTripleClick: handleTripleClick2, + handleKeyDown: handleKeyDown2, + handlePaste + }, + appendTransaction(_2, oldState, state) { + return normalizeSelection(state, fixTables(state, oldState), allowTableNodeSelection); + } + }); +} + +// ../../node_modules/.pnpm/@tiptap+extension-table@3.26.0_@tiptap+core@3.26.0_@tiptap+pm@3.26.0__@tiptap+pm@3.26.0/node_modules/@tiptap/extension-table/dist/index.js +function normalizeTableCellAlign(value) { + if (value === "left" || value === "right" || value === "center") { + return value; + } + return null; +} +function parseAlign(element2) { + const styleAlign = (element2.style.textAlign || "").trim().toLowerCase(); + const attrAlign = (element2.getAttribute("align") || "").trim().toLowerCase(); + const align = styleAlign || attrAlign; + return normalizeTableCellAlign(align); +} +function normalizeTableCellAlignFromAttributes(attributes) { + return normalizeTableCellAlign(attributes == null ? void 0 : attributes.align); +} +function createAlignAttribute() { + return { + default: null, + parseHTML: (element2) => parseAlign(element2), + renderHTML: (attributes) => { + if (!attributes.align) { + return {}; + } + return { + style: `text-align: ${attributes.align}` + }; + } + }; +} +var TableCell = Node3.create({ + name: "tableCell", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + content: "block+", + addAttributes() { + return { + colspan: { + default: 1 + }, + rowspan: { + default: 1 + }, + colwidth: { + default: null, + parseHTML: (element2) => { + var _a, _b; + const colwidth = element2.getAttribute("colwidth"); + const value = colwidth ? colwidth.split(",").map((width) => parseInt(width, 10)) : null; + if (!value) { + const cols = (_a = element2.closest("table")) == null ? void 0 : _a.querySelectorAll("colgroup > col"); + const cellIndex = Array.from(((_b = element2.parentElement) == null ? void 0 : _b.children) || []).indexOf(element2); + if (cellIndex && cellIndex > -1 && cols && cols[cellIndex]) { + const colWidth = cols[cellIndex].getAttribute("width"); + return colWidth ? [parseInt(colWidth, 10)] : null; + } + } + return value; + } + }, + align: createAlignAttribute() + }; + }, + tableRole: "cell", + isolating: true, + parseHTML() { + return [{ tag: "td" }]; + }, + renderHTML({ HTMLAttributes }) { + return ["td", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + } +}); +var TableHeader = Node3.create({ + name: "tableHeader", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + content: "block+", + addAttributes() { + return { + colspan: { + default: 1 + }, + rowspan: { + default: 1 + }, + colwidth: { + default: null, + parseHTML: (element2) => { + const colwidth = element2.getAttribute("colwidth"); + const value = colwidth ? colwidth.split(",").map((width) => parseInt(width, 10)) : null; + return value; + } + }, + align: createAlignAttribute() + }; + }, + tableRole: "header_cell", + isolating: true, + parseHTML() { + return [{ tag: "th" }]; + }, + renderHTML({ HTMLAttributes }) { + return ["th", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + } +}); +var TableRow = Node3.create({ + name: "tableRow", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + content: "(tableCell | tableHeader)*", + tableRole: "row", + parseHTML() { + return [{ tag: "tr" }]; + }, + renderHTML({ HTMLAttributes }) { + return ["tr", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + } +}); +function getColStyleDeclaration(minWidth, width) { + if (width) { + return ["width", `${Math.max(width, minWidth)}px`]; + } + return ["min-width", `${minWidth}px`]; +} +function updateColumns(node, colgroup, table, cellMinWidth, overrideCol, overrideValue) { + var _a; + let totalWidth = 0; + let fixedWidth = true; + let nextDOM = colgroup.firstChild; + const row = node.firstChild; + if (row !== null) { + for (let i = 0, col = 0; i < row.childCount; i += 1) { + const { colspan, colwidth } = row.child(i).attrs; + for (let j2 = 0; j2 < colspan; j2 += 1, col += 1) { + const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j2]; + const cssWidth = hasWidth ? `${hasWidth}px` : ""; + totalWidth += hasWidth || cellMinWidth; + if (!hasWidth) { + fixedWidth = false; + } + if (!nextDOM) { + const colElement = document.createElement("col"); + const [propertyKey, propertyValue] = getColStyleDeclaration(cellMinWidth, hasWidth); + colElement.style.setProperty(propertyKey, propertyValue); + colgroup.appendChild(colElement); + } else { + if (nextDOM.style.width !== cssWidth) { + const [propertyKey, propertyValue] = getColStyleDeclaration(cellMinWidth, hasWidth); + nextDOM.style.setProperty(propertyKey, propertyValue); + } + nextDOM = nextDOM.nextSibling; + } + } + } + } + while (nextDOM) { + const after = nextDOM.nextSibling; + (_a = nextDOM.parentNode) == null ? void 0 : _a.removeChild(nextDOM); + nextDOM = after; + } + const hasUserWidth = node.attrs.style && typeof node.attrs.style === "string" && /\bwidth\s*:/i.test(node.attrs.style); + if (fixedWidth && !hasUserWidth) { + table.style.width = `${totalWidth}px`; + table.style.minWidth = ""; + } else { + table.style.width = ""; + table.style.minWidth = `${totalWidth}px`; + } +} +var TableView2 = class { + constructor(node, cellMinWidth, _view, HTMLAttributes = {}) { + this.node = node; + this.cellMinWidth = cellMinWidth; + this.dom = document.createElement("div"); + this.dom.className = "tableWrapper"; + this.table = this.dom.appendChild(document.createElement("table")); + for (const [key, value] of Object.entries(HTMLAttributes)) { + if (value !== void 0 && value !== null) { + if (key === "style") { + this.table.style.cssText = String(value); + } else { + this.table.setAttribute(key, String(value)); + } + } + } + if (node.attrs.style) { + this.table.style.cssText = node.attrs.style; + } + this.colgroup = this.table.appendChild(document.createElement("colgroup")); + updateColumns(node, this.colgroup, this.table, cellMinWidth); + this.contentDOM = this.table.appendChild(document.createElement("tbody")); + } + update(node) { + if (node.type !== this.node.type) { + return false; + } + this.node = node; + updateColumns(node, this.colgroup, this.table, this.cellMinWidth); + return true; + } + ignoreMutation(mutation) { + const target = mutation.target; + const isInsideWrapper = this.dom.contains(target); + const isInsideContent = this.contentDOM.contains(target); + if (isInsideWrapper && !isInsideContent) { + if (mutation.type === "attributes" || mutation.type === "childList" || mutation.type === "characterData") { + return true; + } + } + return false; + } +}; +function createColGroup(node, cellMinWidth, overrideCol, overrideValue) { + let totalWidth = 0; + let fixedWidth = true; + const cols = []; + const row = node.firstChild; + if (!row) { + return {}; + } + for (let i = 0, col = 0; i < row.childCount; i += 1) { + const { colspan, colwidth } = row.child(i).attrs; + for (let j2 = 0; j2 < colspan; j2 += 1, col += 1) { + const hasWidth = overrideCol === col ? overrideValue : colwidth && colwidth[j2]; + totalWidth += hasWidth || cellMinWidth; + if (!hasWidth) { + fixedWidth = false; + } + const [property, value] = getColStyleDeclaration(cellMinWidth, hasWidth); + cols.push(["col", { style: `${property}: ${value}` }]); + } + } + const tableWidth = fixedWidth ? `${totalWidth}px` : ""; + const tableMinWidth = fixedWidth ? "" : `${totalWidth}px`; + const colgroup = ["colgroup", {}, ...cols]; + return { colgroup, tableWidth, tableMinWidth }; +} +function createCell(cellType, cellContent) { + if (cellContent) { + return cellType.createChecked(null, cellContent); + } + return cellType.createAndFill(); +} +function getTableNodeTypes(schema) { + if (schema.cached.tableNodeTypes) { + return schema.cached.tableNodeTypes; + } + const roles = {}; + Object.keys(schema.nodes).forEach((type) => { + const nodeType = schema.nodes[type]; + if (nodeType.spec.tableRole) { + roles[nodeType.spec.tableRole] = nodeType; + } + }); + schema.cached.tableNodeTypes = roles; + return roles; +} +function createTable(schema, rowsCount, colsCount, withHeaderRow, cellContent) { + const types = getTableNodeTypes(schema); + const headerCells = []; + const cells = []; + for (let index = 0; index < colsCount; index += 1) { + const cell2 = createCell(types.cell, cellContent); + if (cell2) { + cells.push(cell2); + } + if (withHeaderRow) { + const headerCell = createCell(types.header_cell, cellContent); + if (headerCell) { + headerCells.push(headerCell); + } + } + } + const rows = []; + for (let index = 0; index < rowsCount; index += 1) { + rows.push(types.row.createChecked(null, withHeaderRow && index === 0 ? headerCells : cells)); + } + return types.table.createChecked(null, rows); +} +function isCellSelection(value) { + return value instanceof CellSelection; +} +var deleteTableWhenAllCellsSelected = ({ editor }) => { + const { selection } = editor.state; + if (!isCellSelection(selection)) { + return false; + } + let cellCount = 0; + const table = findParentNodeClosestToPos(selection.ranges[0].$from, (node) => { + return node.type.name === "table"; + }); + table == null ? void 0 : table.node.descendants((node) => { + if (node.type.name === "table") { + return false; + } + if (["tableCell", "tableHeader"].includes(node.type.name)) { + cellCount += 1; + } + }); + const allCellsSelected = cellCount === selection.ranges.length; + if (!allCellsSelected) { + return false; + } + editor.commands.deleteTable(); + return true; +}; +var DEFAULT_CELL_LINE_SEPARATOR = ""; +function collapseWhitespace(s) { + return (s || "").replace(/\s+/g, " ").trim(); +} +function renderTableToMarkdown(node, h2, options = {}) { + var _a; + const cellSep = (_a = options.cellLineSeparator) != null ? _a : DEFAULT_CELL_LINE_SEPARATOR; + if (!node || !node.content || node.content.length === 0) { + return ""; + } + const rows = []; + node.content.forEach((rowNode) => { + const cells = []; + if (rowNode.content) { + rowNode.content.forEach((cellNode) => { + let raw = ""; + if (cellNode.content && Array.isArray(cellNode.content) && cellNode.content.length > 1) { + const parts = cellNode.content.map( + (child) => h2.renderChildren(child) + ); + raw = parts.join(cellSep); + } else { + raw = cellNode.content ? h2.renderChildren(cellNode.content) : ""; + } + const text2 = collapseWhitespace(raw); + const isHeader = cellNode.type === "tableHeader"; + const align = normalizeTableCellAlignFromAttributes(cellNode.attrs); + cells.push({ text: text2, isHeader, align }); + }); + } + rows.push(cells); + }); + const columnCount = rows.reduce((max2, r) => Math.max(max2, r.length), 0); + if (columnCount === 0) { + return ""; + } + const colWidths = Array.from({ length: columnCount }).fill(0); + rows.forEach((r) => { + var _a2; + for (let i = 0; i < columnCount; i += 1) { + const cell2 = ((_a2 = r[i]) == null ? void 0 : _a2.text) || ""; + const len = cell2.length; + if (len > colWidths[i]) { + colWidths[i] = len; + } + if (colWidths[i] < 3) { + colWidths[i] = 3; + } + } + }); + const pad = (s, width) => s + " ".repeat(Math.max(0, width - s.length)); + const headerRow = rows[0]; + const hasHeader = headerRow.some((c) => c.isHeader); + const colAlignments = Array.from({ + length: columnCount + }).fill(null); + rows.forEach((r) => { + var _a2; + for (let i = 0; i < columnCount; i += 1) { + if (!colAlignments[i] && ((_a2 = r[i]) == null ? void 0 : _a2.align)) { + colAlignments[i] = r[i].align; + } + } + }); + let out = "\n"; + const headerTexts = Array.from({ length: columnCount }).map( + (_2, i) => hasHeader ? headerRow[i] && headerRow[i].text || "" : "" + ); + out += `| ${headerTexts.map((t, i) => pad(t, colWidths[i])).join(" | ")} | +`; + out += `| ${colWidths.map((w2, index) => { + const dashCount = Math.max(3, w2); + const alignment = colAlignments[index]; + if (alignment === "left") { + return `:${"-".repeat(dashCount)}`; + } + if (alignment === "right") { + return `${"-".repeat(dashCount)}:`; + } + if (alignment === "center") { + return `:${"-".repeat(dashCount)}:`; + } + return "-".repeat(dashCount); + }).join(" | ")} | +`; + const body = hasHeader ? rows.slice(1) : rows; + body.forEach((r) => { + out += `| ${Array.from({ length: columnCount }).fill(0).map((_2, i) => pad(r[i] && r[i].text || "", colWidths[i])).join(" | ")} | +`; + }); + return out; +} +var markdown_default = renderTableToMarkdown; +var Table = Node3.create({ + name: "table", + // @ts-ignore + addOptions() { + return { + HTMLAttributes: {}, + resizable: false, + renderWrapper: false, + handleWidth: 5, + cellMinWidth: 25, + // TODO: fix + View: TableView2, + lastColumnResizable: true, + allowTableNodeSelection: false + }; + }, + content: "tableRow+", + tableRole: "table", + isolating: true, + group: "block", + parseHTML() { + return [{ tag: "table" }]; + }, + renderHTML({ node, HTMLAttributes }) { + const { colgroup, tableWidth, tableMinWidth } = createColGroup(node, this.options.cellMinWidth); + const userStyles = HTMLAttributes.style; + function getTableStyle() { + if (userStyles) { + return userStyles; + } + return tableWidth ? `width: ${tableWidth}` : `min-width: ${tableMinWidth}`; + } + const table = [ + "table", + mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { + style: getTableStyle() + }), + colgroup, + ["tbody", 0] + ]; + return this.options.renderWrapper ? ["div", { class: "tableWrapper" }, table] : table; + }, + parseMarkdown: (token, h2) => { + const rows = []; + const alignments = Array.isArray(token.align) ? token.align : []; + if (token.header) { + const headerCells = []; + token.header.forEach((cell2, index) => { + var _a; + const align = normalizeTableCellAlign((_a = alignments[index]) != null ? _a : cell2.align); + const attrs = align ? { align } : {}; + headerCells.push( + h2.createNode("tableHeader", attrs, [ + { type: "paragraph", content: h2.parseInline(cell2.tokens) } + ]) + ); + }); + rows.push(h2.createNode("tableRow", {}, headerCells)); + } + if (token.rows) { + token.rows.forEach((row) => { + const bodyCells = []; + row.forEach((cell2, index) => { + var _a; + const align = normalizeTableCellAlign((_a = alignments[index]) != null ? _a : cell2.align); + const attrs = align ? { align } : {}; + bodyCells.push( + h2.createNode("tableCell", attrs, [ + { type: "paragraph", content: h2.parseInline(cell2.tokens) } + ]) + ); + }); + rows.push(h2.createNode("tableRow", {}, bodyCells)); + }); + } + return h2.createNode("table", void 0, rows); + }, + renderMarkdown: (node, h2) => { + return markdown_default(node, h2); + }, + addCommands() { + return { + insertTable: ({ rows = 3, cols = 3, withHeaderRow = true } = {}) => ({ tr: tr2, dispatch, editor }) => { + const node = createTable(editor.schema, rows, cols, withHeaderRow); + if (dispatch) { + const offset = tr2.selection.from + 1; + tr2.replaceSelectionWith(node).scrollIntoView().setSelection(TextSelection.near(tr2.doc.resolve(offset))); + } + return true; + }, + addColumnBefore: () => ({ state, dispatch }) => { + return addColumnBefore(state, dispatch); + }, + addColumnAfter: () => ({ state, dispatch }) => { + return addColumnAfter(state, dispatch); + }, + deleteColumn: () => ({ state, dispatch }) => { + return deleteColumn(state, dispatch); + }, + addRowBefore: () => ({ state, dispatch }) => { + return addRowBefore(state, dispatch); + }, + addRowAfter: () => ({ state, dispatch }) => { + return addRowAfter(state, dispatch); + }, + deleteRow: () => ({ state, dispatch }) => { + return deleteRow(state, dispatch); + }, + deleteTable: () => ({ state, dispatch }) => { + return deleteTable(state, dispatch); + }, + mergeCells: () => ({ state, dispatch }) => { + return mergeCells(state, dispatch); + }, + splitCell: () => ({ state, dispatch }) => { + return splitCell(state, dispatch); + }, + toggleHeaderColumn: () => ({ state, dispatch }) => { + return toggleHeader("column")(state, dispatch); + }, + toggleHeaderRow: () => ({ state, dispatch }) => { + return toggleHeader("row")(state, dispatch); + }, + toggleHeaderCell: () => ({ state, dispatch }) => { + return toggleHeaderCell(state, dispatch); + }, + mergeOrSplit: () => ({ state, dispatch }) => { + if (mergeCells(state, dispatch)) { + return true; + } + return splitCell(state, dispatch); + }, + setCellAttribute: (name, value) => ({ state, dispatch }) => { + return setCellAttr(name, value)(state, dispatch); + }, + goToNextCell: () => ({ state, dispatch }) => { + return goToNextCell(1)(state, dispatch); + }, + goToPreviousCell: () => ({ state, dispatch }) => { + return goToNextCell(-1)(state, dispatch); + }, + fixTables: () => ({ state, dispatch }) => { + if (dispatch) { + fixTables(state); + } + return true; + }, + setCellSelection: (position) => ({ tr: tr2, dispatch }) => { + if (dispatch) { + const selection = CellSelection.create(tr2.doc, position.anchorCell, position.headCell); + tr2.setSelection(selection); + } + return true; + } + }; + }, + addKeyboardShortcuts() { + return { + Tab: () => { + if (this.editor.commands.goToNextCell()) { + return true; + } + if (!this.editor.can().addRowAfter()) { + return false; + } + return this.editor.chain().addRowAfter().goToNextCell().run(); + }, + "Shift-Tab": () => this.editor.commands.goToPreviousCell(), + Backspace: deleteTableWhenAllCellsSelected, + "Mod-Backspace": deleteTableWhenAllCellsSelected, + Delete: deleteTableWhenAllCellsSelected, + "Mod-Delete": deleteTableWhenAllCellsSelected + }; + }, + addProseMirrorPlugins() { + const isResizable = this.options.resizable && this.editor.isEditable; + return [ + ...isResizable ? [ + columnResizing({ + handleWidth: this.options.handleWidth, + cellMinWidth: this.options.cellMinWidth, + defaultCellMinWidth: this.options.cellMinWidth, + View: this.options.View, + lastColumnResizable: this.options.lastColumnResizable + }) + ] : [], + tableEditing({ + allowTableNodeSelection: this.options.allowTableNodeSelection + }) + ]; + }, + addNodeView() { + const isResizable = this.options.resizable && this.editor.isEditable; + const View = this.options.View; + if (isResizable || !View) { + return null; + } + return ({ node, view, HTMLAttributes }) => { + const mergedAttributes = mergeAttributes(this.options.HTMLAttributes, HTMLAttributes); + return new View(node, this.options.cellMinWidth, view, mergedAttributes); + }; + }, + extendNodeSchema(extension) { + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage + }; + return { + tableRole: callOrReturn(getExtensionField(extension, "tableRole", context)) + }; + } +}); +var TableKit = Extension.create({ + name: "tableKit", + addExtensions() { + const extensions = []; + if (this.options.table !== false) { + extensions.push(Table.configure(this.options.table)); + } + if (this.options.tableCell !== false) { + extensions.push(TableCell.configure(this.options.tableCell)); + } + if (this.options.tableHeader !== false) { + extensions.push(TableHeader.configure(this.options.tableHeader)); + } + if (this.options.tableRow !== false) { + extensions.push(TableRow.configure(this.options.tableRow)); + } + return extensions; + } +}); + +// ../../node_modules/.pnpm/@tiptap+extension-table-row@3.26.0_@tiptap+extension-table@3.26.0_@tiptap+core@3.26.0_@tiptap_yeiuvgb4oft5wntle66urljnqu/node_modules/@tiptap/extension-table-row/dist/index.js +var index_default7 = TableRow; + +// ../../node_modules/.pnpm/@tiptap+extension-table-header@3.26.0_@tiptap+extension-table@3.26.0_@tiptap+core@3.26.0_@tip_e5k67lnie6guh4g7o24n2jsola/node_modules/@tiptap/extension-table-header/dist/index.js +var index_default8 = TableHeader; + +// ../../node_modules/.pnpm/@tiptap+extension-table-cell@3.26.0_@tiptap+extension-table@3.26.0_@tiptap+core@3.26.0_@tipta_z5d77clamm766wykk6vrjtnivm/node_modules/@tiptap/extension-table-cell/dist/index.js +var index_default9 = TableCell; + +// ../../node_modules/.pnpm/marked@18.0.5/node_modules/marked/lib/marked.esm.js +function M() { + return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null }; +} +var T = M(); +function N(l3) { + T = l3; +} +var _ = { exec: () => null }; +function E(l3) { + let e = []; + return (t) => { + let n = Math.max(0, Math.min(3, t - 1)), s = e[n]; + return s || (s = l3(n), e[n] = s), s; + }; +} +function d(l3, e = "") { + let t = typeof l3 == "string" ? l3 : l3.source, n = { replace: (s, r) => { + let i = typeof r == "string" ? r : r.source; + return i = i.replace(m.caret, "$1"), t = t.replace(s, i), n; + }, getRegex: () => new RegExp(t, e) }; + return n; +} +var Te = ((l3 = "") => { + try { + return !!new RegExp("(?<=1)(?/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (l3) => new RegExp(`^( {0,3}${l3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: E((l3) => new RegExp(`^ {0,${l3}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)), hrRegex: E((l3) => new RegExp(`^ {0,${l3}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)), fencesBeginRegex: E((l3) => new RegExp(`^ {0,${l3}}(?:\`\`\`|~~~)`)), headingBeginRegex: E((l3) => new RegExp(`^ {0,${l3}}#`)), htmlBeginRegex: E((l3) => new RegExp(`^ {0,${l3}}<(?:[a-z].*>|!--)`, "i")), blockquoteBeginRegex: E((l3) => new RegExp(`^ {0,${l3}}>`)) }; +var Oe = /^(?:[ \t]*(?:\n|$))+/; +var we = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/; +var ye = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/; +var B = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/; +var Pe = /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/; +var j = / {0,3}(?:[*+-]|\d{1,9}[.)])/; +var oe = /^(?!bull |blockCode|fences|blockquote|heading|html|table)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html|table))+?)\n {0,3}(=+|-+) *(?:\n+|$)/; +var ae = d(oe).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/\|table/g, "").getRegex(); +var Se = d(oe).replace(/bull/g, j).replace(/blockCode/g, /(?: {4}| {0,3}\t)/).replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g, / {0,3}>/).replace(/heading/g, / {0,3}#{1,6}/).replace(/html/g, / {0,3}<[^\n>]+>\n/).replace(/table/g, / {0,3}\|?(?:[:\- ]*\|)+[\:\- ]*\n/).getRegex(); +var F = /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/; +var $e = /^[^\n]+/; +var U = /(?!\s*\])(?:\\[\s\S]|[^\[\]\\])+/; +var Le = d(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[ \t]*)?| *\n[ \t]*)(title))? *(?:\n+|$)/).replace("label", U).replace("title", /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(); +var _e = d(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g, j).getRegex(); +var H = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul"; +var K2 = /|$))/; +var ze = d("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|\\n*|$)|\\n*|$)|)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", K2).replace("tag", H).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(); +var le = d(F).replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex(); +var Me = d(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", le).getRegex(); +var W = { blockquote: Me, code: we, def: Le, fences: ye, heading: Pe, hr: B, html: ze, lheading: ae, list: _e, newline: Oe, paragraph: le, table: _, text: $e }; +var se = d("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex(); +var Ee = { ...W, lheading: Se, table: se, paragraph: d(F).replace("hr", B).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html", ")|<(?:script|pre|style|textarea|!--)").replace("tag", H).getRegex() }; +var Ie = { ...W, html: d(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", K2).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: _, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: d(F).replace("hr", B).replace("heading", ` *#{1,6} *[^ +]`).replace("lheading", ae).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() }; +var Ae = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/; +var Ce = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/; +var ue = /^( {2,}|\\)\n(?!\s*$)/; +var Be = /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\`+)[^`]+\k(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", Te ? "(?`+)[^`]+\k(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex(); +var ce = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/; +var Ze = d(ce, "u").replace(/punct/g, I).getRegex(); +var Ge = d(ce, "u").replace(/punct/g, pe).getRegex(); +var he = "^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)punct(\\*+)(?=[\\s]|$)|notPunctSpace(\\*+)(?!\\*)(?=punctSpace|$)|(?!\\*)punctSpace(\\*+)(?=notPunctSpace)|[\\s](\\*+)(?!\\*)(?=punct)|(?!\\*)punct(\\*+)(?!\\*)(?=punct)|notPunctSpace(\\*+)(?=notPunctSpace)"; +var Ne = d(he, "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, I).getRegex(); +var Qe = d(he, "gu").replace(/notPunctSpace/g, ve).replace(/punctSpace/g, qe).replace(/punct/g, pe).getRegex(); +var je = d("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)punct(_+)(?=[\\s]|$)|notPunctSpace(_+)(?!_)(?=punctSpace|$)|(?!_)punctSpace(_+)(?=notPunctSpace)|[\\s](_+)(?!_)(?=punct)|(?!_)punct(_+)(?!_)(?=punct)", "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, I).getRegex(); +var Fe = d(/^~~?(?:((?!~)punct)|[^\s~])/, "u").replace(/punct/g, I).getRegex(); +var Ue = "^[^~]+(?=[^~])|(?!~)punct(~~?)(?=[\\s]|$)|notPunctSpace(~~?)(?!~)(?=punctSpace|$)|(?!~)punctSpace(~~?)(?=notPunctSpace)|[\\s](~~?)(?!~)(?=punct)|(?!~)punct(~~?)(?!~)(?=punct)|notPunctSpace(~~?)(?=notPunctSpace)"; +var Ke = d(Ue, "gu").replace(/notPunctSpace/g, X).replace(/punctSpace/g, Z).replace(/punct/g, I).getRegex(); +var We = d(/\\(punct)/, "gu").replace(/punct/g, I).getRegex(); +var Xe = d(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(); +var Je = d(K2).replace("(?:-->|$)", "-->").getRegex(); +var Ve = d("^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^").replace("comment", Je).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(); +var v = /(?:\[(?:\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/; +var Ye = d(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", v).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]*/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(); +var ke = d(/^!?\[(label)\]\[(ref)\]/).replace("label", v).replace("ref", U).getRegex(); +var de = d(/^!?\[(ref)\](?:\[\])?/).replace("ref", U).getRegex(); +var et = d("reflink|nolink(?!\\()", "g").replace("reflink", ke).replace("nolink", de).getRegex(); +var ie3 = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/; +var J = { _backpedal: _, anyPunctuation: We, autolink: Xe, blockSkip: He, br: ue, code: Ce, del: _, delLDelim: _, delRDelim: _, emStrongLDelim: Ze, emStrongRDelimAst: Ne, emStrongRDelimUnd: je, escape: Ae, link: Ye, nolink: de, punctuation: De, reflink: ke, reflinkSearch: et, tag: Ve, text: Be, url: _ }; +var tt2 = { ...J, link: d(/^!?\[(label)\]\((.*?)\)/).replace("label", v).getRegex(), reflink: d(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", v).getRegex() }; +var Q = { ...J, emStrongRDelimAst: Qe, emStrongLDelim: Ge, delLDelim: Fe, delRDelim: Ke, url: d(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ie3).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: d(/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\": ">", '"': """, "'": "'" }; +var ge = (l3) => rt[l3]; +function O(l3, e) { + if (e) { + if (m.escapeTest.test(l3)) return l3.replace(m.escapeReplace, ge); + } else if (m.escapeTestNoEncode.test(l3)) return l3.replace(m.escapeReplaceNoEncode, ge); + return l3; +} +function V(l3) { + try { + l3 = encodeURI(l3).replace(m.percentDecode, "%"); + } catch { + return null; + } + return l3; +} +function Y(l3, e) { + let t = l3.replace(m.findPipe, (r, i, o) => { + let u = false, a = i; + for (; --a >= 0 && o[a] === "\\"; ) u = !u; + return u ? "|" : " |"; + }), n = t.split(m.splitPipe), s = 0; + if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e); + else for (; n.length < e; ) n.push(""); + for (; s < n.length; s++) n[s] = n[s].trim().replace(m.slashPipe, "|"); + return n; +} +function $2(l3, e, t) { + let n = l3.length; + if (n === 0) return ""; + let s = 0; + for (; s < n; ) { + let r = l3.charAt(n - s - 1); + if (r === e && !t) s++; + else if (r !== e && t) s++; + else break; + } + return l3.slice(0, n - s); +} +function ee(l3) { + let e = l3.split(` +`), t = e.length - 1; + for (; t >= 0 && m.blankLine.test(e[t]); ) t--; + return e.length - t <= 2 ? l3 : e.slice(0, t + 1).join(` +`); +} +function fe(l3, e) { + if (l3.indexOf(e[1]) === -1) return -1; + let t = 0; + for (let n = 0; n < l3.length; n++) if (l3[n] === "\\") n++; + else if (l3[n] === e[0]) t++; + else if (l3[n] === e[1] && (t--, t < 0)) return n; + return t > 0 ? -2 : -1; +} +function me(l3, e = 0) { + let t = e, n = ""; + for (let s of l3) if (s === " ") { + let r = 4 - t % 4; + n += " ".repeat(r), t += r; + } else n += s, t++; + return n; +} +function xe(l3, e, t, n, s) { + let r = e.href, i = e.title || null, o = l3[1].replace(s.other.outputLinkReplace, "$1"); + n.state.inLink = true; + let u = { type: l3[0].charAt(0) === "!" ? "image" : "link", raw: t, href: r, title: i, text: o, tokens: n.inlineTokens(o) }; + return n.state.inLink = false, u; +} +function st(l3, e, t) { + let n = l3.match(t.other.indentCodeCompensation); + if (n === null) return e; + let s = n[1]; + return e.split(` +`).map((r) => { + let i = r.match(t.other.beginningSpace); + if (i === null) return r; + let [o] = i; + return o.length >= s.length ? r.slice(s.length) : r; + }).join(` +`); +} +var w = class { + options; + rules; + lexer; + constructor(e) { + this.options = e || T; + } + space(e) { + let t = this.rules.block.newline.exec(e); + if (t && t[0].length > 0) return { type: "space", raw: t[0] }; + } + code(e) { + let t = this.rules.block.code.exec(e); + if (t) { + let n = this.options.pedantic ? t[0] : ee(t[0]), s = n.replace(this.rules.other.codeRemoveIndent, ""); + return { type: "code", raw: n, codeBlockStyle: "indented", text: s }; + } + } + fences(e) { + let t = this.rules.block.fences.exec(e); + if (t) { + let n = t[0], s = st(n, t[3] || "", this.rules); + return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: s }; + } + } + heading(e) { + let t = this.rules.block.heading.exec(e); + if (t) { + let n = t[2].trim(); + if (this.rules.other.endingHash.test(n)) { + let s = $2(n, "#"); + (this.options.pedantic || !s || this.rules.other.endingSpaceChar.test(s)) && (n = s.trim()); + } + return { type: "heading", raw: $2(t[0], ` +`), depth: t[1].length, text: n, tokens: this.lexer.inline(n) }; + } + } + hr(e) { + let t = this.rules.block.hr.exec(e); + if (t) return { type: "hr", raw: $2(t[0], ` +`) }; + } + blockquote(e) { + let t = this.rules.block.blockquote.exec(e); + if (t) { + let n = $2(t[0], ` +`).split(` +`), s = "", r = "", i = []; + for (; n.length > 0; ) { + let o = false, u = [], a; + for (a = 0; a < n.length; a++) if (this.rules.other.blockquoteStart.test(n[a])) u.push(n[a]), o = true; + else if (!o) u.push(n[a]); + else break; + n = n.slice(a); + let c = u.join(` +`), p = c.replace(this.rules.other.blockquoteSetextReplace, ` + $1`).replace(this.rules.other.blockquoteSetextReplace2, ""); + s = s ? `${s} +${c}` : c, r = r ? `${r} +${p}` : p; + let k = this.lexer.state.top; + if (this.lexer.state.top = true, this.lexer.blockTokens(p, i, true), this.lexer.state.top = k, n.length === 0) break; + let h2 = i.at(-1); + if (h2?.type === "code") break; + if (h2?.type === "blockquote") { + let R = h2, f = R.raw + ` +` + n.join(` +`), S = this.blockquote(f); + i[i.length - 1] = S, s = s.substring(0, s.length - R.raw.length) + S.raw, r = r.substring(0, r.length - R.text.length) + S.text; + break; + } else if (h2?.type === "list") { + let R = h2, f = R.raw + ` +` + n.join(` +`), S = this.list(f); + i[i.length - 1] = S, s = s.substring(0, s.length - h2.raw.length) + S.raw, r = r.substring(0, r.length - R.raw.length) + S.raw, n = f.substring(i.at(-1).raw.length).split(` +`); + continue; + } + } + return { type: "blockquote", raw: s, tokens: i, text: r }; + } + } + list(e) { + let t = this.rules.block.list.exec(e); + if (t) { + let n = t[1].trim(), s = n.length > 1, r = { type: "list", raw: "", ordered: s, start: s ? +n.slice(0, -1) : "", loose: false, items: [] }; + n = s ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = s ? n : "[*+-]"); + let i = this.rules.other.listItemRegex(n), o = false; + for (; e; ) { + let a = false, c = "", p = ""; + if (!(t = i.exec(e)) || this.rules.block.hr.test(e)) break; + c = t[0], e = e.substring(c.length); + let k = me(t[2].split(` +`, 1)[0], t[1].length), h2 = e.split(` +`, 1)[0], R = !k.trim(), f = 0; + if (this.options.pedantic ? (f = 2, p = k.trimStart()) : R ? f = t[1].length + 1 : (f = k.search(this.rules.other.nonSpaceChar), f = f > 4 ? 1 : f, p = k.slice(f), f += t[1].length), R && this.rules.other.blankLine.test(h2) && (c += h2 + ` +`, e = e.substring(h2.length + 1), a = true), !a) { + let S = this.rules.other.nextBulletRegex(f), te = this.rules.other.hrRegex(f), ne = this.rules.other.fencesBeginRegex(f), re = this.rules.other.headingBeginRegex(f), be = this.rules.other.htmlBeginRegex(f), Re = this.rules.other.blockquoteBeginRegex(f); + for (; e; ) { + let G = e.split(` +`, 1)[0], C; + if (h2 = G, this.options.pedantic ? (h2 = h2.replace(this.rules.other.listReplaceNesting, " "), C = h2) : C = h2.replace(this.rules.other.tabCharGlobal, " "), ne.test(h2) || re.test(h2) || be.test(h2) || Re.test(h2) || S.test(h2) || te.test(h2)) break; + if (C.search(this.rules.other.nonSpaceChar) >= f || !h2.trim()) p += ` +` + C.slice(f); + else { + if (R || k.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(k) || re.test(k) || te.test(k)) break; + p += ` +` + h2; + } + R = !h2.trim(), c += G + ` +`, e = e.substring(G.length + 1), k = C.slice(f); + } + } + r.loose || (o ? r.loose = true : this.rules.other.doubleBlankLine.test(c) && (o = true)), r.items.push({ type: "list_item", raw: c, task: !!this.options.gfm && this.rules.other.listIsTask.test(p), loose: false, text: p, tokens: [] }), r.raw += c; + } + let u = r.items.at(-1); + if (u) u.raw = u.raw.trimEnd(), u.text = u.text.trimEnd(); + else return; + r.raw = r.raw.trimEnd(); + for (let a of r.items) { + this.lexer.state.top = false, a.tokens = this.lexer.blockTokens(a.text, []); + let c = a.tokens[0]; + if (a.task && (c?.type === "text" || c?.type === "paragraph")) { + a.text = a.text.replace(this.rules.other.listReplaceTask, ""), c.raw = c.raw.replace(this.rules.other.listReplaceTask, ""), c.text = c.text.replace(this.rules.other.listReplaceTask, ""); + for (let k = this.lexer.inlineQueue.length - 1; k >= 0; k--) if (this.rules.other.listIsTask.test(this.lexer.inlineQueue[k].src)) { + this.lexer.inlineQueue[k].src = this.lexer.inlineQueue[k].src.replace(this.rules.other.listReplaceTask, ""); + break; + } + let p = this.rules.other.listTaskCheckbox.exec(a.raw); + if (p) { + let k = { type: "checkbox", raw: p[0] + " ", checked: p[0] !== "[ ]" }; + a.checked = k.checked, r.loose ? a.tokens[0] && ["paragraph", "text"].includes(a.tokens[0].type) && "tokens" in a.tokens[0] && a.tokens[0].tokens ? (a.tokens[0].raw = k.raw + a.tokens[0].raw, a.tokens[0].text = k.raw + a.tokens[0].text, a.tokens[0].tokens.unshift(k)) : a.tokens.unshift({ type: "paragraph", raw: k.raw, text: k.raw, tokens: [k] }) : a.tokens.unshift(k); + } + } else a.task && (a.task = false); + if (!r.loose) { + let p = a.tokens.filter((h2) => h2.type === "space"), k = p.length > 0 && p.some((h2) => this.rules.other.anyLine.test(h2.raw)); + r.loose = k; + } + } + if (r.loose) for (let a of r.items) { + a.loose = true; + for (let c of a.tokens) c.type === "text" && (c.type = "paragraph"); + } + return r; + } + } + html(e) { + let t = this.rules.block.html.exec(e); + if (t) { + let n = ee(t[0]); + return { type: "html", block: true, raw: n, pre: t[1] === "pre" || t[1] === "script" || t[1] === "style", text: n }; + } + } + def(e) { + let t = this.rules.block.def.exec(e); + if (t) { + let n = t[1].toLowerCase().replace(this.rules.other.multipleSpaceGlobal, " "), s = t[2] ? t[2].replace(this.rules.other.hrefBrackets, "$1").replace(this.rules.inline.anyPunctuation, "$1") : "", r = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline.anyPunctuation, "$1") : t[3]; + return { type: "def", tag: n, raw: $2(t[0], ` +`), href: s, title: r }; + } + } + table(e) { + let t = this.rules.block.table.exec(e); + if (!t || !this.rules.other.tableDelimiter.test(t[2])) return; + let n = Y(t[1]), s = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), r = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(` +`) : [], i = { type: "table", raw: $2(t[0], ` +`), header: [], align: [], rows: [] }; + if (n.length === s.length) { + for (let o of s) this.rules.other.tableAlignRight.test(o) ? i.align.push("right") : this.rules.other.tableAlignCenter.test(o) ? i.align.push("center") : this.rules.other.tableAlignLeft.test(o) ? i.align.push("left") : i.align.push(null); + for (let o = 0; o < n.length; o++) i.header.push({ text: n[o], tokens: this.lexer.inline(n[o]), header: true, align: i.align[o] }); + for (let o of r) i.rows.push(Y(o, i.header.length).map((u, a) => ({ text: u, tokens: this.lexer.inline(u), header: false, align: i.align[a] }))); + return i; + } + } + lheading(e) { + let t = this.rules.block.lheading.exec(e); + if (t) { + let n = t[1].trim(); + return { type: "heading", raw: $2(t[0], ` +`), depth: t[2].charAt(0) === "=" ? 1 : 2, text: n, tokens: this.lexer.inline(n) }; + } + } + paragraph(e) { + let t = this.rules.block.paragraph.exec(e); + if (t) { + let n = t[1].charAt(t[1].length - 1) === ` +` ? t[1].slice(0, -1) : t[1]; + return { type: "paragraph", raw: t[0], text: n, tokens: this.lexer.inline(n) }; + } + } + text(e) { + let t = this.rules.block.text.exec(e); + if (t) return { type: "text", raw: t[0], text: t[0], tokens: this.lexer.inline(t[0]) }; + } + escape(e) { + let t = this.rules.inline.escape.exec(e); + if (t) return { type: "escape", raw: t[0], text: t[1] }; + } + tag(e) { + let t = this.rules.inline.tag.exec(e); + if (t) return !this.lexer.state.inLink && this.rules.other.startATag.test(t[0]) ? this.lexer.state.inLink = true : this.lexer.state.inLink && this.rules.other.endATag.test(t[0]) && (this.lexer.state.inLink = false), !this.lexer.state.inRawBlock && this.rules.other.startPreScriptTag.test(t[0]) ? this.lexer.state.inRawBlock = true : this.lexer.state.inRawBlock && this.rules.other.endPreScriptTag.test(t[0]) && (this.lexer.state.inRawBlock = false), { type: "html", raw: t[0], inLink: this.lexer.state.inLink, inRawBlock: this.lexer.state.inRawBlock, block: false, text: t[0] }; + } + link(e) { + let t = this.rules.inline.link.exec(e); + if (t) { + let n = t[2].trim(); + if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) { + if (!this.rules.other.endAngleBracket.test(n)) return; + let i = $2(n.slice(0, -1), "\\"); + if ((n.length - i.length) % 2 === 0) return; + } else { + let i = fe(t[2], "()"); + if (i === -2) return; + if (i > -1) { + let u = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + i; + t[2] = t[2].substring(0, i), t[0] = t[0].substring(0, u).trim(), t[3] = ""; + } + } + let s = t[2], r = ""; + if (this.options.pedantic) { + let i = this.rules.other.pedanticHrefTitle.exec(s); + i && (s = i[1], r = i[3]); + } else r = t[3] ? t[3].slice(1, -1) : ""; + return s = s.trim(), this.rules.other.startAngleBracket.test(s) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? s = s.slice(1) : s = s.slice(1, -1)), xe(t, { href: s && s.replace(this.rules.inline.anyPunctuation, "$1"), title: r && r.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules); + } + } + reflink(e, t) { + let n; + if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) { + let s = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), r = t[s.toLowerCase()]; + if (!r) { + let i = n[0].charAt(0); + return { type: "text", raw: i, text: i }; + } + return xe(n, r, n[0], this.lexer, this.rules); + } + } + emStrong(e, t, n = "") { + let s = this.rules.inline.emStrongLDelim.exec(e); + if (!s || !s[1] && !s[2] && !s[3] && !s[4] || s[4] && n.match(this.rules.other.unicodeAlphaNumeric)) return; + if (!(s[1] || s[3] || "") || !n || this.rules.inline.punctuation.exec(n)) { + let i = [...s[0]].length - 1, o, u, a = i, c = 0, p = s[0][0] === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd; + for (p.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = p.exec(t)) !== null; ) { + if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o) continue; + if (u = [...o].length, s[3] || s[4]) { + a += u; + continue; + } else if ((s[5] || s[6]) && i % 3 && !((i + u) % 3)) { + c += u; + continue; + } + if (a -= u, a > 0) continue; + u = Math.min(u, u + a + c); + let k = [...s[0]][0].length, h2 = e.slice(0, i + s.index + k + u); + if (Math.min(i, u) % 2) { + let f = h2.slice(1, -1); + return { type: "em", raw: h2, text: f, tokens: this.lexer.inlineTokens(f) }; + } + let R = h2.slice(2, -2); + return { type: "strong", raw: h2, text: R, tokens: this.lexer.inlineTokens(R) }; + } + } + } + codespan(e) { + let t = this.rules.inline.code.exec(e); + if (t) { + let n = t[2].replace(this.rules.other.newLineCharGlobal, " "), s = this.rules.other.nonSpaceChar.test(n), r = this.rules.other.startingSpaceChar.test(n) && this.rules.other.endingSpaceChar.test(n); + return s && r && (n = n.substring(1, n.length - 1)), { type: "codespan", raw: t[0], text: n }; + } + } + br(e) { + let t = this.rules.inline.br.exec(e); + if (t) return { type: "br", raw: t[0] }; + } + del(e, t, n = "") { + let s = this.rules.inline.delLDelim.exec(e); + if (!s) return; + if (!(s[1] || "") || !n || this.rules.inline.punctuation.exec(n)) { + let i = [...s[0]].length - 1, o, u, a = i, c = this.rules.inline.delRDelim; + for (c.lastIndex = 0, t = t.slice(-1 * e.length + i); (s = c.exec(t)) !== null; ) { + if (o = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !o || (u = [...o].length, u !== i)) continue; + if (s[3] || s[4]) { + a += u; + continue; + } + if (a -= u, a > 0) continue; + u = Math.min(u, u + a); + let p = [...s[0]][0].length, k = e.slice(0, i + s.index + p + u), h2 = k.slice(i, -i); + return { type: "del", raw: k, text: h2, tokens: this.lexer.inlineTokens(h2) }; + } + } + } + autolink(e) { + let t = this.rules.inline.autolink.exec(e); + if (t) { + let n, s; + return t[2] === "@" ? (n = t[1], s = "mailto:" + n) : (n = t[1], s = n), { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] }; + } + } + url(e) { + let t; + if (t = this.rules.inline.url.exec(e)) { + let n, s; + if (t[2] === "@") n = t[0], s = "mailto:" + n; + else { + let r; + do + r = t[0], t[0] = this.rules.inline._backpedal.exec(t[0])?.[0] ?? ""; + while (r !== t[0]); + n = t[0], t[1] === "www." ? s = "http://" + t[0] : s = t[0]; + } + return { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] }; + } + } + inlineText(e) { + let t = this.rules.inline.text.exec(e); + if (t) { + let n = this.lexer.state.inRawBlock; + return { type: "text", raw: t[0], text: t[0], escaped: n }; + } + } +}; +var x = class l { + tokens; + options; + state; + inlineQueue; + tokenizer; + constructor(e) { + this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || T, this.options.tokenizer = this.options.tokenizer || new w(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, top: true }; + let t = { other: m, block: D.normal, inline: A.normal }; + this.options.pedantic ? (t.block = D.pedantic, t.inline = A.pedantic) : this.options.gfm && (t.block = D.gfm, this.options.breaks ? t.inline = A.breaks : t.inline = A.gfm), this.tokenizer.rules = t; + } + static get rules() { + return { block: D, inline: A }; + } + static lex(e, t) { + return new l(t).lex(e); + } + static lexInline(e, t) { + return new l(t).inlineTokens(e); + } + lex(e) { + e = e.replace(m.carriageReturn, ` +`), this.blockTokens(e, this.tokens); + for (let t = 0; t < this.inlineQueue.length; t++) { + let n = this.inlineQueue[t]; + this.inlineTokens(n.src, n.tokens); + } + return this.inlineQueue = [], this.tokens; + } + blockTokens(e, t = [], n = false) { + this.tokenizer.lexer = this, this.options.pedantic && (e = e.replace(m.tabCharGlobal, " ").replace(m.spaceLine, "")); + let s = 1 / 0; + for (; e; ) { + if (e.length < s) s = e.length; + else { + this.infiniteLoopError(e.charCodeAt(0)); + break; + } + let r; + if (this.options.extensions?.block?.some((o) => (r = o.call({ lexer: this }, e, t)) ? (e = e.substring(r.raw.length), t.push(r), true) : false)) continue; + if (r = this.tokenizer.space(e)) { + e = e.substring(r.raw.length); + let o = t.at(-1); + r.raw.length === 1 && o !== void 0 ? o.raw += ` +` : t.push(r); + continue; + } + if (r = this.tokenizer.code(e)) { + e = e.substring(r.raw.length); + let o = t.at(-1); + o?.type === "paragraph" || o?.type === "text" ? (o.raw += (o.raw.endsWith(` +`) ? "" : ` +`) + r.raw, o.text += ` +` + r.text, this.inlineQueue.at(-1).src = o.text) : t.push(r); + continue; + } + if (r = this.tokenizer.fences(e)) { + e = e.substring(r.raw.length), t.push(r); + continue; + } + if (r = this.tokenizer.heading(e)) { + e = e.substring(r.raw.length), t.push(r); + continue; + } + if (r = this.tokenizer.hr(e)) { + e = e.substring(r.raw.length), t.push(r); + continue; + } + if (r = this.tokenizer.blockquote(e)) { + e = e.substring(r.raw.length), t.push(r); + continue; + } + if (r = this.tokenizer.list(e)) { + e = e.substring(r.raw.length), t.push(r); + continue; + } + if (r = this.tokenizer.html(e)) { + e = e.substring(r.raw.length), t.push(r); + continue; + } + if (r = this.tokenizer.def(e)) { + e = e.substring(r.raw.length); + let o = t.at(-1); + o?.type === "paragraph" || o?.type === "text" ? (o.raw += (o.raw.endsWith(` +`) ? "" : ` +`) + r.raw, o.text += ` +` + r.raw, this.inlineQueue.at(-1).src = o.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t.push(r)); + continue; + } + if (r = this.tokenizer.table(e)) { + e = e.substring(r.raw.length), t.push(r); + continue; + } + if (r = this.tokenizer.lheading(e)) { + e = e.substring(r.raw.length), t.push(r); + continue; + } + let i = e; + if (this.options.extensions?.startBlock) { + let o = 1 / 0, u = e.slice(1), a; + this.options.extensions.startBlock.forEach((c) => { + a = c.call({ lexer: this }, u), typeof a == "number" && a >= 0 && (o = Math.min(o, a)); + }), o < 1 / 0 && o >= 0 && (i = e.substring(0, o + 1)); + } + if (this.state.top && (r = this.tokenizer.paragraph(i))) { + let o = t.at(-1); + n && o?.type === "paragraph" ? (o.raw += (o.raw.endsWith(` +`) ? "" : ` +`) + r.raw, o.text += ` +` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = o.text) : t.push(r), n = i.length !== e.length, e = e.substring(r.raw.length); + continue; + } + if (r = this.tokenizer.text(e)) { + e = e.substring(r.raw.length); + let o = t.at(-1); + o?.type === "text" ? (o.raw += (o.raw.endsWith(` +`) ? "" : ` +`) + r.raw, o.text += ` +` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = o.text) : t.push(r); + continue; + } + if (e) { + this.infiniteLoopError(e.charCodeAt(0)); + break; + } + } + return this.state.top = true, t; + } + inline(e, t = []) { + return this.inlineQueue.push({ src: e, tokens: t }), t; + } + inlineTokens(e, t = []) { + this.tokenizer.lexer = this; + let n = e, s = null; + if (this.tokens.links) { + let a = Object.keys(this.tokens.links); + if (a.length > 0) for (; (s = this.tokenizer.rules.inline.reflinkSearch.exec(n)) !== null; ) a.includes(s[0].slice(s[0].lastIndexOf("[") + 1, -1)) && (n = n.slice(0, s.index) + "[" + "a".repeat(s[0].length - 2) + "]" + n.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex)); + } + for (; (s = this.tokenizer.rules.inline.anyPunctuation.exec(n)) !== null; ) n = n.slice(0, s.index) + "++" + n.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex); + let r; + for (; (s = this.tokenizer.rules.inline.blockSkip.exec(n)) !== null; ) r = s[2] ? s[2].length : 0, n = n.slice(0, s.index + r) + "[" + "a".repeat(s[0].length - r - 2) + "]" + n.slice(this.tokenizer.rules.inline.blockSkip.lastIndex); + n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n; + let i = false, o = "", u = 1 / 0; + for (; e; ) { + if (e.length < u) u = e.length; + else { + this.infiniteLoopError(e.charCodeAt(0)); + break; + } + i || (o = ""), i = false; + let a; + if (this.options.extensions?.inline?.some((p) => (a = p.call({ lexer: this }, e, t)) ? (e = e.substring(a.raw.length), t.push(a), true) : false)) continue; + if (a = this.tokenizer.escape(e)) { + e = e.substring(a.raw.length), t.push(a); + continue; + } + if (a = this.tokenizer.tag(e)) { + e = e.substring(a.raw.length), t.push(a); + continue; + } + if (a = this.tokenizer.link(e)) { + e = e.substring(a.raw.length), t.push(a); + continue; + } + if (a = this.tokenizer.reflink(e, this.tokens.links)) { + e = e.substring(a.raw.length); + let p = t.at(-1); + a.type === "text" && p?.type === "text" ? (p.raw += a.raw, p.text += a.text) : t.push(a); + continue; + } + if (a = this.tokenizer.emStrong(e, n, o)) { + e = e.substring(a.raw.length), t.push(a); + continue; + } + if (a = this.tokenizer.codespan(e)) { + e = e.substring(a.raw.length), t.push(a); + continue; + } + if (a = this.tokenizer.br(e)) { + e = e.substring(a.raw.length), t.push(a); + continue; + } + if (a = this.tokenizer.del(e, n, o)) { + e = e.substring(a.raw.length), t.push(a); + continue; + } + if (a = this.tokenizer.autolink(e)) { + e = e.substring(a.raw.length), t.push(a); + continue; + } + if (!this.state.inLink && (a = this.tokenizer.url(e))) { + e = e.substring(a.raw.length), t.push(a); + continue; + } + let c = e; + if (this.options.extensions?.startInline) { + let p = 1 / 0, k = e.slice(1), h2; + this.options.extensions.startInline.forEach((R) => { + h2 = R.call({ lexer: this }, k), typeof h2 == "number" && h2 >= 0 && (p = Math.min(p, h2)); + }), p < 1 / 0 && p >= 0 && (c = e.substring(0, p + 1)); + } + if (a = this.tokenizer.inlineText(c)) { + e = e.substring(a.raw.length), a.raw.slice(-1) !== "_" && (o = a.raw.slice(-1)), i = true; + let p = t.at(-1); + p?.type === "text" ? (p.raw += a.raw, p.text += a.text) : t.push(a); + continue; + } + if (e) { + this.infiniteLoopError(e.charCodeAt(0)); + break; + } + } + return t; + } + infiniteLoopError(e) { + let t = "Infinite loop on byte: " + e; + if (this.options.silent) console.error(t); + else throw new Error(t); + } +}; +var y = class { + options; + parser; + constructor(e) { + this.options = e || T; + } + space(e) { + return ""; + } + code({ text: e, lang: t, escaped: n }) { + let s = (t || "").match(m.notSpaceStart)?.[0], r = e.replace(m.endingNewline, "") + ` +`; + return s ? '
' + (n ? r : O(r, true)) + `
+` : "
" + (n ? r : O(r, true)) + `
+`; + } + blockquote({ tokens: e }) { + return `
+${this.parser.parse(e)}
+`; + } + html({ text: e }) { + return e; + } + def(e) { + return ""; + } + heading({ tokens: e, depth: t }) { + return `${this.parser.parseInline(e)} +`; + } + hr(e) { + return `
+`; + } + list(e) { + let t = e.ordered, n = e.start, s = ""; + for (let o = 0; o < e.items.length; o++) { + let u = e.items[o]; + s += this.listitem(u); + } + let r = t ? "ol" : "ul", i = t && n !== 1 ? ' start="' + n + '"' : ""; + return "<" + r + i + `> +` + s + " +`; + } + listitem(e) { + return `
  • ${this.parser.parse(e.tokens)}
  • +`; + } + checkbox({ checked: e }) { + return " '; + } + paragraph({ tokens: e }) { + return `

    ${this.parser.parseInline(e)}

    +`; + } + table(e) { + let t = "", n = ""; + for (let r = 0; r < e.header.length; r++) n += this.tablecell(e.header[r]); + t += this.tablerow({ text: n }); + let s = ""; + for (let r = 0; r < e.rows.length; r++) { + let i = e.rows[r]; + n = ""; + for (let o = 0; o < i.length; o++) n += this.tablecell(i[o]); + s += this.tablerow({ text: n }); + } + return s && (s = `${s}`), ` + +` + t + ` +` + s + `
    +`; + } + tablerow({ text: e }) { + return ` +${e} +`; + } + tablecell(e) { + let t = this.parser.parseInline(e.tokens), n = e.header ? "th" : "td"; + return (e.align ? `<${n} align="${e.align}">` : `<${n}>`) + t + ` +`; + } + strong({ tokens: e }) { + return `${this.parser.parseInline(e)}`; + } + em({ tokens: e }) { + return `${this.parser.parseInline(e)}`; + } + codespan({ text: e }) { + return `${O(e, true)}`; + } + br(e) { + return "
    "; + } + del({ tokens: e }) { + return `${this.parser.parseInline(e)}`; + } + link({ href: e, title: t, tokens: n }) { + let s = this.parser.parseInline(n), r = V(e); + if (r === null) return s; + e = r; + let i = '
    ", i; + } + image({ href: e, title: t, text: n, tokens: s }) { + s && (n = this.parser.parseInline(s, this.parser.textRenderer)); + let r = V(e); + if (r === null) return O(n); + e = r; + let i = `${O(n)} { + let o = r[i].flat(1 / 0); + n = n.concat(this.walkTokens(o, t)); + }) : r.tokens && (n = n.concat(this.walkTokens(r.tokens, t))); + } + } + return n; + } + use(...e) { + let t = this.defaults.extensions || { renderers: {}, childTokens: {} }; + return e.forEach((n) => { + let s = { ...n }; + if (s.async = this.defaults.async || s.async || false, n.extensions && (n.extensions.forEach((r) => { + if (!r.name) throw new Error("extension name required"); + if ("renderer" in r) { + let i = t.renderers[r.name]; + i ? t.renderers[r.name] = function(...o) { + let u = r.renderer.apply(this, o); + return u === false && (u = i.apply(this, o)), u; + } : t.renderers[r.name] = r.renderer; + } + if ("tokenizer" in r) { + if (!r.level || r.level !== "block" && r.level !== "inline") throw new Error("extension level must be 'block' or 'inline'"); + let i = t[r.level]; + i ? i.unshift(r.tokenizer) : t[r.level] = [r.tokenizer], r.start && (r.level === "block" ? t.startBlock ? t.startBlock.push(r.start) : t.startBlock = [r.start] : r.level === "inline" && (t.startInline ? t.startInline.push(r.start) : t.startInline = [r.start])); + } + "childTokens" in r && r.childTokens && (t.childTokens[r.name] = r.childTokens); + }), s.extensions = t), n.renderer) { + let r = this.defaults.renderer || new y(this.defaults); + for (let i in n.renderer) { + if (!(i in r)) throw new Error(`renderer '${i}' does not exist`); + if (["options", "parser"].includes(i)) continue; + let o = i, u = n.renderer[o], a = r[o]; + r[o] = (...c) => { + let p = u.apply(r, c); + return p === false && (p = a.apply(r, c)), p || ""; + }; + } + s.renderer = r; + } + if (n.tokenizer) { + let r = this.defaults.tokenizer || new w(this.defaults); + for (let i in n.tokenizer) { + if (!(i in r)) throw new Error(`tokenizer '${i}' does not exist`); + if (["options", "rules", "lexer"].includes(i)) continue; + let o = i, u = n.tokenizer[o], a = r[o]; + r[o] = (...c) => { + let p = u.apply(r, c); + return p === false && (p = a.apply(r, c)), p; + }; + } + s.tokenizer = r; + } + if (n.hooks) { + let r = this.defaults.hooks || new P(); + for (let i in n.hooks) { + if (!(i in r)) throw new Error(`hook '${i}' does not exist`); + if (["options", "block"].includes(i)) continue; + let o = i, u = n.hooks[o], a = r[o]; + P.passThroughHooks.has(i) ? r[o] = (c) => { + if (this.defaults.async && P.passThroughHooksRespectAsync.has(i)) return (async () => { + let k = await u.call(r, c); + return a.call(r, k); + })(); + let p = u.call(r, c); + return a.call(r, p); + } : r[o] = (...c) => { + if (this.defaults.async) return (async () => { + let k = await u.apply(r, c); + return k === false && (k = await a.apply(r, c)), k; + })(); + let p = u.apply(r, c); + return p === false && (p = a.apply(r, c)), p; + }; + } + s.hooks = r; + } + if (n.walkTokens) { + let r = this.defaults.walkTokens, i = n.walkTokens; + s.walkTokens = function(o) { + let u = []; + return u.push(i.call(this, o)), r && (u = u.concat(r.call(this, o))), u; + }; + } + this.defaults = { ...this.defaults, ...s }; + }), this; + } + setOptions(e) { + return this.defaults = { ...this.defaults, ...e }, this; + } + lexer(e, t) { + return x.lex(e, t ?? this.defaults); + } + parser(e, t) { + return b.parse(e, t ?? this.defaults); + } + parseMarkdown(e) { + return (n, s) => { + let r = { ...s }, i = { ...this.defaults, ...r }, o = this.onError(!!i.silent, !!i.async); + if (this.defaults.async === true && r.async === false) return o(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.")); + if (typeof n > "u" || n === null) return o(new Error("marked(): input parameter is undefined or null")); + if (typeof n != "string") return o(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected")); + if (i.hooks && (i.hooks.options = i, i.hooks.block = e), i.async) return (async () => { + let u = i.hooks ? await i.hooks.preprocess(n) : n, c = await (i.hooks ? await i.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(u, i), p = i.hooks ? await i.hooks.processAllTokens(c) : c; + i.walkTokens && await Promise.all(this.walkTokens(p, i.walkTokens)); + let h2 = await (i.hooks ? await i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(p, i); + return i.hooks ? await i.hooks.postprocess(h2) : h2; + })().catch(o); + try { + i.hooks && (n = i.hooks.preprocess(n)); + let a = (i.hooks ? i.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(n, i); + i.hooks && (a = i.hooks.processAllTokens(a)), i.walkTokens && this.walkTokens(a, i.walkTokens); + let p = (i.hooks ? i.hooks.provideParser(e) : e ? b.parse : b.parseInline)(a, i); + return i.hooks && (p = i.hooks.postprocess(p)), p; + } catch (u) { + return o(u); + } + }; + } + onError(e, t) { + return (n) => { + if (n.message += ` +Please report this to https://github.com/markedjs/marked.`, e) { + let s = "

    An error occurred:

    " + O(n.message + "", true) + "
    "; + return t ? Promise.resolve(s) : s; + } + if (t) return Promise.reject(n); + throw n; + }; + } +}; +var z = new q(); +function g(l3, e) { + return z.parse(l3, e); +} +g.options = g.setOptions = function(l3) { + return z.setOptions(l3), g.defaults = z.defaults, N(g.defaults), g; +}; +g.getDefaults = M; +g.defaults = T; +g.use = function(...l3) { + return z.use(...l3), g.defaults = z.defaults, N(g.defaults), g; +}; +g.walkTokens = function(l3, e) { + return z.walkTokens(l3, e); +}; +g.parseInline = z.parseInline; +g.Parser = b; +g.parser = b.parse; +g.Renderer = y; +g.TextRenderer = L; +g.Lexer = x; +g.lexer = x.lex; +g.Tokenizer = w; +g.Hooks = P; +g.parse = g; +var Ft = g.options; +var Ut = g.setOptions; +var Kt = g.use; +var Wt = g.walkTokens; +var Xt = g.parseInline; +var Vt = b.parse; +var Yt = x.lex; + +// ../../node_modules/.pnpm/turndown@7.2.4/node_modules/turndown/lib/turndown.browser.es.js +function extend(destination) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) destination[key] = source[key]; + } + } + return destination; +} +function repeat2(character, count) { + return Array(count + 1).join(character); +} +function trimLeadingNewlines(string) { + return string.replace(/^\n*/, ""); +} +function trimTrailingNewlines(string) { + var indexEnd = string.length; + while (indexEnd > 0 && string[indexEnd - 1] === "\n") indexEnd--; + return string.substring(0, indexEnd); +} +function trimNewlines(string) { + return trimTrailingNewlines(trimLeadingNewlines(string)); +} +var blockElements = ["ADDRESS", "ARTICLE", "ASIDE", "AUDIO", "BLOCKQUOTE", "BODY", "CANVAS", "CENTER", "DD", "DIR", "DIV", "DL", "DT", "FIELDSET", "FIGCAPTION", "FIGURE", "FOOTER", "FORM", "FRAMESET", "H1", "H2", "H3", "H4", "H5", "H6", "HEADER", "HGROUP", "HR", "HTML", "ISINDEX", "LI", "MAIN", "MENU", "NAV", "NOFRAMES", "NOSCRIPT", "OL", "OUTPUT", "P", "PRE", "SECTION", "TABLE", "TBODY", "TD", "TFOOT", "TH", "THEAD", "TR", "UL"]; +function isBlock(node) { + return is(node, blockElements); +} +var voidElements = ["AREA", "BASE", "BR", "COL", "COMMAND", "EMBED", "HR", "IMG", "INPUT", "KEYGEN", "LINK", "META", "PARAM", "SOURCE", "TRACK", "WBR"]; +function isVoid(node) { + return is(node, voidElements); +} +function hasVoid(node) { + return has(node, voidElements); +} +var meaningfulWhenBlankElements = ["A", "TABLE", "THEAD", "TBODY", "TFOOT", "TH", "TD", "IFRAME", "SCRIPT", "AUDIO", "VIDEO"]; +function isMeaningfulWhenBlank(node) { + return is(node, meaningfulWhenBlankElements); +} +function hasMeaningfulWhenBlank(node) { + return has(node, meaningfulWhenBlankElements); +} +function is(node, tagNames) { + return tagNames.indexOf(node.nodeName) >= 0; +} +function has(node, tagNames) { + return node.getElementsByTagName && tagNames.some(function(tagName) { + return node.getElementsByTagName(tagName).length; + }); +} +var markdownEscapes = [[/\\/g, "\\\\"], [/\*/g, "\\*"], [/^-/g, "\\-"], [/^\+ /g, "\\+ "], [/^(=+)/g, "\\$1"], [/^(#{1,6}) /g, "\\$1 "], [/`/g, "\\`"], [/^~~~/g, "\\~~~"], [/\[/g, "\\["], [/\]/g, "\\]"], [/^>/g, "\\>"], [/_/g, "\\_"], [/^(\d+)\. /g, "$1\\. "]]; +function escapeMarkdown(string) { + return markdownEscapes.reduce(function(accumulator, escape2) { + return accumulator.replace(escape2[0], escape2[1]); + }, string); +} +var rules = {}; +rules.paragraph = { + filter: "p", + replacement: function(content) { + return "\n\n" + content + "\n\n"; + } +}; +rules.lineBreak = { + filter: "br", + replacement: function(content, node, options) { + return options.br + "\n"; + } +}; +rules.heading = { + filter: ["h1", "h2", "h3", "h4", "h5", "h6"], + replacement: function(content, node, options) { + var hLevel = Number(node.nodeName.charAt(1)); + if (options.headingStyle === "setext" && hLevel < 3) { + var underline = repeat2(hLevel === 1 ? "=" : "-", content.length); + return "\n\n" + content + "\n" + underline + "\n\n"; + } else { + return "\n\n" + repeat2("#", hLevel) + " " + content + "\n\n"; + } + } +}; +rules.blockquote = { + filter: "blockquote", + replacement: function(content) { + content = trimNewlines(content).replace(/^/gm, "> "); + return "\n\n" + content + "\n\n"; + } +}; +rules.list = { + filter: ["ul", "ol"], + replacement: function(content, node) { + var parent = node.parentNode; + if (parent.nodeName === "LI" && parent.lastElementChild === node) { + return "\n" + content; + } else { + return "\n\n" + content + "\n\n"; + } + } +}; +rules.listItem = { + filter: "li", + replacement: function(content, node, options) { + var prefix = options.bulletListMarker + " "; + var parent = node.parentNode; + if (parent.nodeName === "OL") { + var start = parent.getAttribute("start"); + var index = Array.prototype.indexOf.call(parent.children, node); + prefix = (start ? Number(start) + index : index + 1) + ". "; + } + var isParagraph = /\n$/.test(content); + content = trimNewlines(content) + (isParagraph ? "\n" : ""); + content = content.replace(/\n/gm, "\n" + " ".repeat(prefix.length)); + return prefix + content + (node.nextSibling ? "\n" : ""); + } +}; +rules.indentedCodeBlock = { + filter: function(node, options) { + return options.codeBlockStyle === "indented" && node.nodeName === "PRE" && node.firstChild && node.firstChild.nodeName === "CODE"; + }, + replacement: function(content, node, options) { + return "\n\n " + node.firstChild.textContent.replace(/\n/g, "\n ") + "\n\n"; + } +}; +rules.fencedCodeBlock = { + filter: function(node, options) { + return options.codeBlockStyle === "fenced" && node.nodeName === "PRE" && node.firstChild && node.firstChild.nodeName === "CODE"; + }, + replacement: function(content, node, options) { + var className = node.firstChild.getAttribute("class") || ""; + var language = (className.match(/language-(\S+)/) || [null, ""])[1]; + var code = node.firstChild.textContent; + var fenceChar = options.fence.charAt(0); + var fenceSize = 3; + var fenceInCodeRegex = new RegExp("^" + fenceChar + "{3,}", "gm"); + var match2; + while (match2 = fenceInCodeRegex.exec(code)) { + if (match2[0].length >= fenceSize) { + fenceSize = match2[0].length + 1; + } + } + var fence = repeat2(fenceChar, fenceSize); + return "\n\n" + fence + language + "\n" + code.replace(/\n$/, "") + "\n" + fence + "\n\n"; + } +}; +rules.horizontalRule = { + filter: "hr", + replacement: function(content, node, options) { + return "\n\n" + options.hr + "\n\n"; + } +}; +rules.inlineLink = { + filter: function(node, options) { + return options.linkStyle === "inlined" && node.nodeName === "A" && node.getAttribute("href"); + }, + replacement: function(content, node) { + var href = escapeLinkDestination(node.getAttribute("href")); + var title = escapeLinkTitle(cleanAttribute(node.getAttribute("title"))); + var titlePart = title ? ' "' + title + '"' : ""; + return "[" + content + "](" + href + titlePart + ")"; + } +}; +rules.referenceLink = { + filter: function(node, options) { + return options.linkStyle === "referenced" && node.nodeName === "A" && node.getAttribute("href"); + }, + replacement: function(content, node, options) { + var href = escapeLinkDestination(node.getAttribute("href")); + var title = cleanAttribute(node.getAttribute("title")); + if (title) title = ' "' + escapeLinkTitle(title) + '"'; + var replacement; + var reference; + switch (options.linkReferenceStyle) { + case "collapsed": + replacement = "[" + content + "][]"; + reference = "[" + content + "]: " + href + title; + break; + case "shortcut": + replacement = "[" + content + "]"; + reference = "[" + content + "]: " + href + title; + break; + default: + var id2 = this.references.length + 1; + replacement = "[" + content + "][" + id2 + "]"; + reference = "[" + id2 + "]: " + href + title; + } + this.references.push(reference); + return replacement; + }, + references: [], + append: function(options) { + var references = ""; + if (this.references.length) { + references = "\n\n" + this.references.join("\n") + "\n\n"; + this.references = []; + } + return references; + } +}; +rules.emphasis = { + filter: ["em", "i"], + replacement: function(content, node, options) { + if (!content.trim()) return ""; + return options.emDelimiter + content + options.emDelimiter; + } +}; +rules.strong = { + filter: ["strong", "b"], + replacement: function(content, node, options) { + if (!content.trim()) return ""; + return options.strongDelimiter + content + options.strongDelimiter; + } +}; +rules.code = { + filter: function(node) { + var hasSiblings = node.previousSibling || node.nextSibling; + var isCodeBlock = node.parentNode.nodeName === "PRE" && !hasSiblings; + return node.nodeName === "CODE" && !isCodeBlock; + }, + replacement: function(content) { + if (!content) return ""; + content = content.replace(/\r?\n|\r/g, " "); + var extraSpace = /^`|^ .*?[^ ].* $|`$/.test(content) ? " " : ""; + var delimiter = "`"; + var matches2 = content.match(/`+/gm) || []; + while (matches2.indexOf(delimiter) !== -1) delimiter = delimiter + "`"; + return delimiter + extraSpace + content + extraSpace + delimiter; + } +}; +rules.image = { + filter: "img", + replacement: function(content, node) { + var alt = escapeMarkdown(cleanAttribute(node.getAttribute("alt"))); + var src = escapeLinkDestination(node.getAttribute("src") || ""); + var title = cleanAttribute(node.getAttribute("title")); + var titlePart = title ? ' "' + escapeLinkTitle(title) + '"' : ""; + return src ? "![" + alt + "](" + src + titlePart + ")" : ""; + } +}; +function cleanAttribute(attribute) { + return attribute ? attribute.replace(/(\n+\s*)+/g, "\n") : ""; +} +function escapeLinkDestination(destination) { + var escaped = destination.replace(/([<>()])/g, "\\$1"); + return escaped.indexOf(" ") >= 0 ? "<" + escaped + ">" : escaped; +} +function escapeLinkTitle(title) { + return title.replace(/"/g, '\\"'); +} +function Rules(options) { + this.options = options; + this._keep = []; + this._remove = []; + this.blankRule = { + replacement: options.blankReplacement + }; + this.keepReplacement = options.keepReplacement; + this.defaultRule = { + replacement: options.defaultReplacement + }; + this.array = []; + for (var key in options.rules) this.array.push(options.rules[key]); +} +Rules.prototype = { + add: function(key, rule) { + this.array.unshift(rule); + }, + keep: function(filter) { + this._keep.unshift({ + filter, + replacement: this.keepReplacement + }); + }, + remove: function(filter) { + this._remove.unshift({ + filter, + replacement: function() { + return ""; + } + }); + }, + forNode: function(node) { + if (node.isBlank) return this.blankRule; + var rule; + if (rule = findRule(this.array, node, this.options)) return rule; + if (rule = findRule(this._keep, node, this.options)) return rule; + if (rule = findRule(this._remove, node, this.options)) return rule; + return this.defaultRule; + }, + forEach: function(fn) { + for (var i = 0; i < this.array.length; i++) fn(this.array[i], i); + } +}; +function findRule(rules3, node, options) { + for (var i = 0; i < rules3.length; i++) { + var rule = rules3[i]; + if (filterValue(rule, node, options)) return rule; + } + return void 0; +} +function filterValue(rule, node, options) { + var filter = rule.filter; + if (typeof filter === "string") { + if (filter === node.nodeName.toLowerCase()) return true; + } else if (Array.isArray(filter)) { + if (filter.indexOf(node.nodeName.toLowerCase()) > -1) return true; + } else if (typeof filter === "function") { + if (filter.call(rule, node, options)) return true; + } else { + throw new TypeError("`filter` needs to be a string, array, or function"); + } +} +function collapseWhitespace2(options) { + var element2 = options.element; + var isBlock2 = options.isBlock; + var isVoid2 = options.isVoid; + var isPre = options.isPre || function(node2) { + return node2.nodeName === "PRE"; + }; + if (!element2.firstChild || isPre(element2)) return; + var prevText = null; + var keepLeadingWs = false; + var prev = null; + var node = next(prev, element2, isPre); + while (node !== element2) { + if (node.nodeType === 3 || node.nodeType === 4) { + var text2 = node.data.replace(/[ \r\n\t]+/g, " "); + if ((!prevText || / $/.test(prevText.data)) && !keepLeadingWs && text2[0] === " ") { + text2 = text2.substr(1); + } + if (!text2) { + node = remove(node); + continue; + } + node.data = text2; + prevText = node; + } else if (node.nodeType === 1) { + if (isBlock2(node) || node.nodeName === "BR") { + if (prevText) { + prevText.data = prevText.data.replace(/ $/, ""); + } + prevText = null; + keepLeadingWs = false; + } else if (isVoid2(node) || isPre(node)) { + prevText = null; + keepLeadingWs = true; + } else if (prevText) { + keepLeadingWs = false; + } + } else { + node = remove(node); + continue; + } + var nextNode = next(prev, node, isPre); + prev = node; + node = nextNode; + } + if (prevText) { + prevText.data = prevText.data.replace(/ $/, ""); + if (!prevText.data) { + remove(prevText); + } + } +} +function remove(node) { + var next2 = node.nextSibling || node.parentNode; + node.parentNode.removeChild(node); + return next2; +} +function next(prev, current, isPre) { + if (prev && prev.parentNode === current || isPre(current)) { + return current.nextSibling || current.parentNode; + } + return current.firstChild || current.nextSibling || current.parentNode; +} +var root = typeof window !== "undefined" ? window : {}; +function canParseHTMLNatively() { + var Parser = root.DOMParser; + var canParse = false; + try { + if (new Parser().parseFromString("", "text/html")) { + canParse = true; + } + } catch (e) { + } + return canParse; +} +function createHTMLParser() { + var Parser = function() { + }; + { + if (shouldUseActiveX()) { + Parser.prototype.parseFromString = function(string) { + var doc4 = new window.ActiveXObject("htmlfile"); + doc4.designMode = "on"; + doc4.open(); + doc4.write(string); + doc4.close(); + return doc4; + }; + } else { + Parser.prototype.parseFromString = function(string) { + var doc4 = document.implementation.createHTMLDocument(""); + doc4.open(); + doc4.write(string); + doc4.close(); + return doc4; + }; + } + } + return Parser; +} +function shouldUseActiveX() { + var useActiveX = false; + try { + document.implementation.createHTMLDocument("").open(); + } catch (e) { + if (root.ActiveXObject) useActiveX = true; + } + return useActiveX; +} +var HTMLParser = canParseHTMLNatively() ? root.DOMParser : createHTMLParser(); +function RootNode(input, options) { + var root2; + if (typeof input === "string") { + var doc4 = htmlParser().parseFromString( + // DOM parsers arrange elements in the and . + // Wrapping in a custom element ensures elements are reliably arranged in + // a single element. + '' + input + "", + "text/html" + ); + root2 = doc4.getElementById("turndown-root"); + } else { + root2 = input.cloneNode(true); + } + collapseWhitespace2({ + element: root2, + isBlock, + isVoid, + isPre: options.preformattedCode ? isPreOrCode : null + }); + return root2; +} +var _htmlParser; +function htmlParser() { + _htmlParser = _htmlParser || new HTMLParser(); + return _htmlParser; +} +function isPreOrCode(node) { + return node.nodeName === "PRE" || node.nodeName === "CODE"; +} +function Node4(node, options) { + node.isBlock = isBlock(node); + node.isCode = node.nodeName === "CODE" || node.parentNode.isCode; + node.isBlank = isBlank(node); + node.flankingWhitespace = flankingWhitespace(node, options); + return node; +} +function isBlank(node) { + return !isVoid(node) && !isMeaningfulWhenBlank(node) && /^\s*$/i.test(node.textContent) && !hasVoid(node) && !hasMeaningfulWhenBlank(node); +} +function flankingWhitespace(node, options) { + if (node.isBlock || options.preformattedCode && node.isCode) { + return { + leading: "", + trailing: "" + }; + } + var edges = edgeWhitespace(node.textContent); + if (edges.leadingAscii && isFlankedByWhitespace("left", node, options)) { + edges.leading = edges.leadingNonAscii; + } + if (edges.trailingAscii && isFlankedByWhitespace("right", node, options)) { + edges.trailing = edges.trailingNonAscii; + } + return { + leading: edges.leading, + trailing: edges.trailing + }; +} +function edgeWhitespace(string) { + var m2 = string.match(/^(([ \t\r\n]*)(\s*))(?:(?=\S)[\s\S]*\S)?((\s*?)([ \t\r\n]*))$/); + return { + leading: m2[1], + // whole string for whitespace-only strings + leadingAscii: m2[2], + leadingNonAscii: m2[3], + trailing: m2[4], + // empty for whitespace-only strings + trailingNonAscii: m2[5], + trailingAscii: m2[6] + }; +} +function isFlankedByWhitespace(side, node, options) { + var sibling; + var regExp; + var isFlanked; + if (side === "left") { + sibling = node.previousSibling; + regExp = / $/; + } else { + sibling = node.nextSibling; + regExp = /^ /; + } + if (sibling) { + if (sibling.nodeType === 3) { + isFlanked = regExp.test(sibling.nodeValue); + } else if (options.preformattedCode && sibling.nodeName === "CODE") { + isFlanked = false; + } else if (sibling.nodeType === 1 && !isBlock(sibling)) { + isFlanked = regExp.test(sibling.textContent); + } + } + return isFlanked; +} +var reduce = Array.prototype.reduce; +function TurndownService(options) { + if (!(this instanceof TurndownService)) return new TurndownService(options); + var defaults2 = { + rules, + headingStyle: "setext", + hr: "* * *", + bulletListMarker: "*", + codeBlockStyle: "indented", + fence: "```", + emDelimiter: "_", + strongDelimiter: "**", + linkStyle: "inlined", + linkReferenceStyle: "full", + br: " ", + preformattedCode: false, + blankReplacement: function(content, node) { + return node.isBlock ? "\n\n" : ""; + }, + keepReplacement: function(content, node) { + return node.isBlock ? "\n\n" + node.outerHTML + "\n\n" : node.outerHTML; + }, + defaultReplacement: function(content, node) { + return node.isBlock ? "\n\n" + content + "\n\n" : content; + } + }; + this.options = extend({}, defaults2, options); + this.rules = new Rules(this.options); +} +TurndownService.prototype = { + /** + * The entry point for converting a string or DOM node to Markdown + * @public + * @param {String|HTMLElement} input The string or DOM node to convert + * @returns A Markdown representation of the input + * @type String + */ + turndown: function(input) { + if (!canConvert(input)) { + throw new TypeError(input + " is not a string, or an element/document/fragment node."); + } + if (input === "") return ""; + var output = process2.call(this, new RootNode(input, this.options)); + return postProcess.call(this, output); + }, + /** + * Add one or more plugins + * @public + * @param {Function|Array} plugin The plugin or array of plugins to add + * @returns The Turndown instance for chaining + * @type Object + */ + use: function(plugin) { + if (Array.isArray(plugin)) { + for (var i = 0; i < plugin.length; i++) this.use(plugin[i]); + } else if (typeof plugin === "function") { + plugin(this); + } else { + throw new TypeError("plugin must be a Function or an Array of Functions"); + } + return this; + }, + /** + * Adds a rule + * @public + * @param {String} key The unique key of the rule + * @param {Object} rule The rule + * @returns The Turndown instance for chaining + * @type Object + */ + addRule: function(key, rule) { + this.rules.add(key, rule); + return this; + }, + /** + * Keep a node (as HTML) that matches the filter + * @public + * @param {String|Array|Function} filter The unique key of the rule + * @returns The Turndown instance for chaining + * @type Object + */ + keep: function(filter) { + this.rules.keep(filter); + return this; + }, + /** + * Remove a node that matches the filter + * @public + * @param {String|Array|Function} filter The unique key of the rule + * @returns The Turndown instance for chaining + * @type Object + */ + remove: function(filter) { + this.rules.remove(filter); + return this; + }, + /** + * Escapes Markdown syntax + * @public + * @param {String} string The string to escape + * @returns A string with Markdown syntax escaped + * @type String + */ + escape: function(string) { + return escapeMarkdown(string); + } +}; +function process2(parentNode2) { + var self = this; + return reduce.call(parentNode2.childNodes, function(output, node) { + node = new Node4(node, self.options); + var replacement = ""; + if (node.nodeType === 3) { + replacement = node.isCode ? node.nodeValue : self.escape(node.nodeValue); + } else if (node.nodeType === 1) { + replacement = replacementForNode.call(self, node); + } + return join2(output, replacement); + }, ""); +} +function postProcess(output) { + var self = this; + this.rules.forEach(function(rule) { + if (typeof rule.append === "function") { + output = join2(output, rule.append(self.options)); + } + }); + return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, ""); +} +function replacementForNode(node) { + var rule = this.rules.forNode(node); + var content = process2.call(this, node); + var whitespace2 = node.flankingWhitespace; + if (whitespace2.leading || whitespace2.trailing) content = content.trim(); + return whitespace2.leading + rule.replacement(content, node, this.options) + whitespace2.trailing; +} +function join2(output, replacement) { + var s1 = trimTrailingNewlines(output); + var s2 = trimLeadingNewlines(replacement); + var nls = Math.max(output.length - s1.length, replacement.length - s2.length); + var separator = "\n\n".substring(0, nls); + return s1 + separator + s2; +} +function canConvert(input) { + return input != null && (typeof input === "string" || input.nodeType && (input.nodeType === 1 || input.nodeType === 9 || input.nodeType === 11)); +} + +// ../../node_modules/.pnpm/turndown-plugin-gfm@1.0.2/node_modules/turndown-plugin-gfm/lib/turndown-plugin-gfm.es.js +var highlightRegExp = /highlight-(?:text|source)-([a-z0-9]+)/; +function highlightedCodeBlock(turndownService) { + turndownService.addRule("highlightedCodeBlock", { + filter: function(node) { + var firstChild = node.firstChild; + return node.nodeName === "DIV" && highlightRegExp.test(node.className) && firstChild && firstChild.nodeName === "PRE"; + }, + replacement: function(content, node, options) { + var className = node.className || ""; + var language = (className.match(highlightRegExp) || [null, ""])[1]; + return "\n\n" + options.fence + language + "\n" + node.firstChild.textContent + "\n" + options.fence + "\n\n"; + } + }); +} +function strikethrough(turndownService) { + turndownService.addRule("strikethrough", { + filter: ["del", "s", "strike"], + replacement: function(content) { + return "~" + content + "~"; + } + }); +} +var indexOf = Array.prototype.indexOf; +var every3 = Array.prototype.every; +var rules2 = {}; +rules2.tableCell = { + filter: ["th", "td"], + replacement: function(content, node) { + return cell(content, node); + } +}; +rules2.tableRow = { + filter: "tr", + replacement: function(content, node) { + var borderCells = ""; + var alignMap = { left: ":--", right: "--:", center: ":-:" }; + if (isHeadingRow(node)) { + for (var i = 0; i < node.childNodes.length; i++) { + var border = "---"; + var align = (node.childNodes[i].getAttribute("align") || "").toLowerCase(); + if (align) border = alignMap[align] || border; + borderCells += cell(border, node.childNodes[i]); + } + } + return "\n" + content + (borderCells ? "\n" + borderCells : ""); + } +}; +rules2.table = { + // Only convert tables with a heading row. + // Tables with no heading row are kept using `keep` (see below). + filter: function(node) { + return node.nodeName === "TABLE" && isHeadingRow(node.rows[0]); + }, + replacement: function(content) { + content = content.replace("\n\n", "\n"); + return "\n\n" + content + "\n\n"; + } +}; +rules2.tableSection = { + filter: ["thead", "tbody", "tfoot"], + replacement: function(content) { + return content; + } +}; +function isHeadingRow(tr2) { + var parentNode2 = tr2.parentNode; + return parentNode2.nodeName === "THEAD" || parentNode2.firstChild === tr2 && (parentNode2.nodeName === "TABLE" || isFirstTbody(parentNode2)) && every3.call(tr2.childNodes, function(n) { + return n.nodeName === "TH"; + }); +} +function isFirstTbody(element2) { + var previousSibling = element2.previousSibling; + return element2.nodeName === "TBODY" && (!previousSibling || previousSibling.nodeName === "THEAD" && /^\s*$/i.test(previousSibling.textContent)); +} +function cell(content, node) { + var index = indexOf.call(node.parentNode.childNodes, node); + var prefix = " "; + if (index === 0) prefix = "| "; + return prefix + content + " |"; +} +function tables(turndownService) { + turndownService.keep(function(node) { + return node.nodeName === "TABLE" && !isHeadingRow(node.rows[0]); + }); + for (var key in rules2) turndownService.addRule(key, rules2[key]); +} +function taskListItems(turndownService) { + turndownService.addRule("taskListItems", { + filter: function(node) { + return node.type === "checkbox" && node.parentNode.nodeName === "LI"; + }, + replacement: function(content, node) { + return (node.checked ? "[x]" : "[ ]") + " "; + } + }); +} +function gfm(turndownService) { + turndownService.use([ + highlightedCodeBlock, + strikethrough, + tables, + taskListItems + ]); +} + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/broadcastchannel.js +var channels = /* @__PURE__ */ new Map(); +var LocalStoragePolyfill = class { + /** + * @param {string} room + */ + constructor(room) { + this.room = room; + this.onmessage = null; + this._onChange = (e) => e.key === room && this.onmessage !== null && this.onmessage({ data: fromBase64(e.newValue || "") }); + onChange(this._onChange); + } + /** + * @param {ArrayBuffer} buf + */ + postMessage(buf) { + varStorage.setItem(this.room, toBase64(createUint8ArrayFromArrayBuffer(buf))); + } + close() { + offChange(this._onChange); + } +}; +var BC = typeof BroadcastChannel === "undefined" ? LocalStoragePolyfill : BroadcastChannel; +var getChannel = (room) => setIfUndefined(channels, room, () => { + const subs = create2(); + const bc = new BC(room); + bc.onmessage = (e) => subs.forEach((sub) => sub(e.data, "broadcastchannel")); + return { + bc, + subs + }; +}); +var subscribe = (room, f) => { + getChannel(room).subs.add(f); + return f; +}; +var unsubscribe = (room, f) => { + const channel = getChannel(room); + const unsubscribed = channel.subs.delete(f); + if (unsubscribed && channel.subs.size === 0) { + channel.bc.close(); + channels.delete(room); + } + return unsubscribed; +}; +var publish = (room, data, origin = null) => { + const c = getChannel(room); + c.bc.postMessage(data); + c.subs.forEach((sub) => sub(data, origin)); +}; + +// ../../node_modules/.pnpm/y-protocols@1.0.7_yjs@13.6.31/node_modules/y-protocols/sync.js +var messageYjsSyncStep1 = 0; +var messageYjsSyncStep2 = 1; +var messageYjsUpdate = 2; +var writeSyncStep1 = (encoder, doc4) => { + writeVarUint(encoder, messageYjsSyncStep1); + const sv = encodeStateVector(doc4); + writeVarUint8Array(encoder, sv); +}; +var writeSyncStep2 = (encoder, doc4, encodedStateVector) => { + writeVarUint(encoder, messageYjsSyncStep2); + writeVarUint8Array(encoder, encodeStateAsUpdate(doc4, encodedStateVector)); +}; +var readSyncStep1 = (decoder, encoder, doc4) => writeSyncStep2(encoder, doc4, readVarUint8Array(decoder)); +var readSyncStep2 = (decoder, doc4, transactionOrigin, errorHandler) => { + try { + applyUpdate(doc4, readVarUint8Array(decoder), transactionOrigin); + } catch (error) { + if (errorHandler != null) errorHandler( + /** @type {Error} */ + error + ); + console.error("Caught error while handling a Yjs update", error); + } +}; +var writeUpdate = (encoder, update) => { + writeVarUint(encoder, messageYjsUpdate); + writeVarUint8Array(encoder, update); +}; +var readUpdate = readSyncStep2; +var readSyncMessage = (decoder, encoder, doc4, transactionOrigin, errorHandler) => { + const messageType = readVarUint(decoder); + switch (messageType) { + case messageYjsSyncStep1: + readSyncStep1(decoder, encoder, doc4); + break; + case messageYjsSyncStep2: + readSyncStep2(decoder, doc4, transactionOrigin, errorHandler); + break; + case messageYjsUpdate: + readUpdate(decoder, doc4, transactionOrigin, errorHandler); + break; + default: + throw new Error("Unknown message type"); + } + return messageType; +}; + +// ../../node_modules/.pnpm/y-protocols@1.0.7_yjs@13.6.31/node_modules/y-protocols/auth.js +var messagePermissionDenied = 0; +var readAuthMessage = (decoder, y2, permissionDeniedHandler2) => { + switch (readVarUint(decoder)) { + case messagePermissionDenied: + permissionDeniedHandler2(y2, readVarString(decoder)); + } +}; + +// ../../node_modules/.pnpm/lib0@0.2.117/node_modules/lib0/url.js +var encodeQueryParams = (params2) => map3(params2, (val, key) => `${encodeURIComponent(key)}=${encodeURIComponent(val)}`).join("&"); + +// ../../node_modules/.pnpm/y-websocket@3.0.0_yjs@13.6.31/node_modules/y-websocket/src/y-websocket.js +var messageSync = 0; +var messageQueryAwareness = 3; +var messageAwareness = 1; +var messageAuth = 2; +var messageHandlers = []; +messageHandlers[messageSync] = (encoder, decoder, provider, emitSynced, _messageType) => { + writeVarUint(encoder, messageSync); + const syncMessageType = readSyncMessage( + decoder, + encoder, + provider.doc, + provider + ); + if (emitSynced && syncMessageType === messageYjsSyncStep2 && !provider.synced) { + provider.synced = true; + } +}; +messageHandlers[messageQueryAwareness] = (encoder, _decoder, provider, _emitSynced, _messageType) => { + writeVarUint(encoder, messageAwareness); + writeVarUint8Array( + encoder, + encodeAwarenessUpdate( + provider.awareness, + Array.from(provider.awareness.getStates().keys()) + ) + ); +}; +messageHandlers[messageAwareness] = (_encoder, decoder, provider, _emitSynced, _messageType) => { + applyAwarenessUpdate( + provider.awareness, + readVarUint8Array(decoder), + provider + ); +}; +messageHandlers[messageAuth] = (_encoder, decoder, provider, _emitSynced, _messageType) => { + readAuthMessage( + decoder, + provider.doc, + (_ydoc, reason) => permissionDeniedHandler(provider, reason) + ); +}; +var messageReconnectTimeout = 3e4; +var permissionDeniedHandler = (provider, reason) => console.warn(`Permission denied to access ${provider.url}. +${reason}`); +var readMessage = (provider, buf, emitSynced) => { + const decoder = createDecoder(buf); + const encoder = createEncoder(); + const messageType = readVarUint(decoder); + const messageHandler = provider.messageHandlers[messageType]; + if ( + /** @type {any} */ + messageHandler + ) { + messageHandler(encoder, decoder, provider, emitSynced, messageType); + } else { + console.error("Unable to compute message"); + } + return encoder; +}; +var closeWebsocketConnection = (provider, ws, event) => { + if (ws === provider.ws) { + provider.emit("connection-close", [event, provider]); + provider.ws = null; + ws.close(); + provider.wsconnecting = false; + if (provider.wsconnected) { + provider.wsconnected = false; + provider.synced = false; + removeAwarenessStates( + provider.awareness, + Array.from(provider.awareness.getStates().keys()).filter( + (client) => client !== provider.doc.clientID + ), + provider + ); + provider.emit("status", [{ + status: "disconnected" + }]); + } else { + provider.wsUnsuccessfulReconnects++; + } + setTimeout( + setupWS, + min( + pow(2, provider.wsUnsuccessfulReconnects) * 100, + provider.maxBackoffTime + ), + provider + ); + } +}; +var setupWS = (provider) => { + if (provider.shouldConnect && provider.ws === null) { + const websocket = new provider._WS(provider.url, provider.protocols); + websocket.binaryType = "arraybuffer"; + provider.ws = websocket; + provider.wsconnecting = true; + provider.wsconnected = false; + provider.synced = false; + websocket.onmessage = (event) => { + provider.wsLastMessageReceived = getUnixTime(); + const encoder = readMessage(provider, new Uint8Array(event.data), true); + if (length(encoder) > 1) { + websocket.send(toUint8Array(encoder)); + } + }; + websocket.onerror = (event) => { + provider.emit("connection-error", [event, provider]); + }; + websocket.onclose = (event) => { + closeWebsocketConnection(provider, websocket, event); + }; + websocket.onopen = () => { + provider.wsLastMessageReceived = getUnixTime(); + provider.wsconnecting = false; + provider.wsconnected = true; + provider.wsUnsuccessfulReconnects = 0; + provider.emit("status", [{ + status: "connected" + }]); + const encoder = createEncoder(); + writeVarUint(encoder, messageSync); + writeSyncStep1(encoder, provider.doc); + websocket.send(toUint8Array(encoder)); + if (provider.awareness.getLocalState() !== null) { + const encoderAwarenessState = createEncoder(); + writeVarUint(encoderAwarenessState, messageAwareness); + writeVarUint8Array( + encoderAwarenessState, + encodeAwarenessUpdate(provider.awareness, [ + provider.doc.clientID + ]) + ); + websocket.send(toUint8Array(encoderAwarenessState)); + } + }; + provider.emit("status", [{ + status: "connecting" + }]); + } +}; +var broadcastMessage = (provider, buf) => { + const ws = provider.ws; + if (provider.wsconnected && ws && ws.readyState === ws.OPEN) { + ws.send(buf); + } + if (provider.bcconnected) { + publish(provider.bcChannel, buf, provider); + } +}; +var WebsocketProvider = class extends ObservableV2 { + /** + * @param {string} serverUrl + * @param {string} roomname + * @param {Y.Doc} doc + * @param {object} opts + * @param {boolean} [opts.connect] + * @param {awarenessProtocol.Awareness} [opts.awareness] + * @param {Object} [opts.params] specify url parameters + * @param {Array} [opts.protocols] specify websocket protocols + * @param {typeof WebSocket} [opts.WebSocketPolyfill] Optionall provide a WebSocket polyfill + * @param {number} [opts.resyncInterval] Request server state every `resyncInterval` milliseconds + * @param {number} [opts.maxBackoffTime] Maximum amount of time to wait before trying to reconnect (we try to reconnect using exponential backoff) + * @param {boolean} [opts.disableBc] Disable cross-tab BroadcastChannel communication + */ + constructor(serverUrl, roomname, doc4, { + connect = true, + awareness = new Awareness(doc4), + params: params2 = {}, + protocols = [], + WebSocketPolyfill = WebSocket, + resyncInterval = -1, + maxBackoffTime = 2500, + disableBc = false + } = {}) { + super(); + while (serverUrl[serverUrl.length - 1] === "/") { + serverUrl = serverUrl.slice(0, serverUrl.length - 1); + } + this.serverUrl = serverUrl; + this.bcChannel = serverUrl + "/" + roomname; + this.maxBackoffTime = maxBackoffTime; + this.params = params2; + this.protocols = protocols; + this.roomname = roomname; + this.doc = doc4; + this._WS = WebSocketPolyfill; + this.awareness = awareness; + this.wsconnected = false; + this.wsconnecting = false; + this.bcconnected = false; + this.disableBc = disableBc; + this.wsUnsuccessfulReconnects = 0; + this.messageHandlers = messageHandlers.slice(); + this._synced = false; + this.ws = null; + this.wsLastMessageReceived = 0; + this.shouldConnect = connect; + this._resyncInterval = 0; + if (resyncInterval > 0) { + this._resyncInterval = /** @type {any} */ + setInterval(() => { + if (this.ws && this.ws.readyState === WebSocket.OPEN) { + const encoder = createEncoder(); + writeVarUint(encoder, messageSync); + writeSyncStep1(encoder, doc4); + this.ws.send(toUint8Array(encoder)); + } + }, resyncInterval); + } + this._bcSubscriber = (data, origin) => { + if (origin !== this) { + const encoder = readMessage(this, new Uint8Array(data), false); + if (length(encoder) > 1) { + publish(this.bcChannel, toUint8Array(encoder), this); + } + } + }; + this._updateHandler = (update, origin) => { + if (origin !== this) { + const encoder = createEncoder(); + writeVarUint(encoder, messageSync); + writeUpdate(encoder, update); + broadcastMessage(this, toUint8Array(encoder)); + } + }; + this.doc.on("update", this._updateHandler); + this._awarenessUpdateHandler = ({ added, updated, removed }, _origin) => { + const changedClients = added.concat(updated).concat(removed); + const encoder = createEncoder(); + writeVarUint(encoder, messageAwareness); + writeVarUint8Array( + encoder, + encodeAwarenessUpdate(awareness, changedClients) + ); + broadcastMessage(this, toUint8Array(encoder)); + }; + this._exitHandler = () => { + removeAwarenessStates( + this.awareness, + [doc4.clientID], + "app closed" + ); + }; + if (isNode && typeof process !== "undefined") { + process.on("exit", this._exitHandler); + } + awareness.on("update", this._awarenessUpdateHandler); + this._checkInterval = /** @type {any} */ + setInterval(() => { + if (this.wsconnected && messageReconnectTimeout < getUnixTime() - this.wsLastMessageReceived) { + closeWebsocketConnection( + this, + /** @type {WebSocket} */ + this.ws, + null + ); + } + }, messageReconnectTimeout / 10); + if (connect) { + this.connect(); + } + } + get url() { + const encodedParams = encodeQueryParams(this.params); + return this.serverUrl + "/" + this.roomname + (encodedParams.length === 0 ? "" : "?" + encodedParams); + } + /** + * @type {boolean} + */ + get synced() { + return this._synced; + } + set synced(state) { + if (this._synced !== state) { + this._synced = state; + this.emit("synced", [state]); + this.emit("sync", [state]); + } + } + destroy() { + if (this._resyncInterval !== 0) { + clearInterval(this._resyncInterval); + } + clearInterval(this._checkInterval); + this.disconnect(); + if (isNode && typeof process !== "undefined") { + process.off("exit", this._exitHandler); + } + this.awareness.off("update", this._awarenessUpdateHandler); + this.doc.off("update", this._updateHandler); + super.destroy(); + } + connectBc() { + if (this.disableBc) { + return; + } + if (!this.bcconnected) { + subscribe(this.bcChannel, this._bcSubscriber); + this.bcconnected = true; + } + const encoderSync = createEncoder(); + writeVarUint(encoderSync, messageSync); + writeSyncStep1(encoderSync, this.doc); + publish(this.bcChannel, toUint8Array(encoderSync), this); + const encoderState = createEncoder(); + writeVarUint(encoderState, messageSync); + writeSyncStep2(encoderState, this.doc); + publish(this.bcChannel, toUint8Array(encoderState), this); + const encoderAwarenessQuery = createEncoder(); + writeVarUint(encoderAwarenessQuery, messageQueryAwareness); + publish( + this.bcChannel, + toUint8Array(encoderAwarenessQuery), + this + ); + const encoderAwarenessState = createEncoder(); + writeVarUint(encoderAwarenessState, messageAwareness); + writeVarUint8Array( + encoderAwarenessState, + encodeAwarenessUpdate(this.awareness, [ + this.doc.clientID + ]) + ); + publish( + this.bcChannel, + toUint8Array(encoderAwarenessState), + this + ); + } + disconnectBc() { + const encoder = createEncoder(); + writeVarUint(encoder, messageAwareness); + writeVarUint8Array( + encoder, + encodeAwarenessUpdate(this.awareness, [ + this.doc.clientID + ], /* @__PURE__ */ new Map()) + ); + broadcastMessage(this, toUint8Array(encoder)); + if (this.bcconnected) { + unsubscribe(this.bcChannel, this._bcSubscriber); + this.bcconnected = false; + } + } + disconnect() { + this.shouldConnect = false; + this.disconnectBc(); + if (this.ws !== null) { + closeWebsocketConnection(this, this.ws, null); + } + } + connect() { + this.shouldConnect = true; + if (!this.wsconnected && this.ws === null) { + setupWS(this); + this.connectBc(); + } + } +}; + +// src/api-client.ts +var import_obsidian = require("obsidian"); +var PagedenApiError = class extends Error { + constructor(status, body) { + super(`Pageden API error ${status}`); + this.status = status; + this.body = body; + this.name = "PagedenApiError"; + } + status; + body; + get code() { + if (this.body && typeof this.body === "object" && "error" in this.body) { + return String(this.body.error); + } + return void 0; + } + get currentVersion() { + if (this.body && typeof this.body === "object" && "currentVersion" in this.body) { + const value = this.body.currentVersion; + return typeof value === "string" ? value : null; + } + return null; + } +}; +var ObsidianRequestTransport = class { + async request(options) { + const response = await (0, import_obsidian.requestUrl)(options); + return { status: response.status, text: response.text, arrayBuffer: response.arrayBuffer }; + } +}; +var PagedenApiClient = class { + constructor(serverUrl, token, transport = new ObsidianRequestTransport()) { + this.serverUrl = serverUrl; + this.token = token; + this.transport = transport; + } + serverUrl; + token; + transport; + me() { + return this.request("GET", "/me"); + } + async validate() { + await this.me(); + } + tree(workspaceId) { + return this.request("GET", `/documents/tree?workspaceId=${encodeURIComponent(workspaceId)}`); + } + document(id2) { + return this.request("GET", `/documents/${encodeURIComponent(id2)}`); + } + createFolder(body) { + return this.request("POST", "/folders", body); + } + createDocument(body) { + return this.request("POST", "/documents", body); + } + push(documentId, body) { + return this.request("POST", `/documents/${encodeURIComponent(documentId)}/push`, body); + } + search(workspaceId, q2, limit = 20) { + const params2 = new URLSearchParams({ workspaceId, q: q2, limit: String(limit) }); + return this.request("GET", `/search?${params2.toString()}`); + } + deviceStart() { + return this.request("POST", "/auth/device/start", void 0, { auth: false }); + } + devicePoll(deviceCode) { + return this.request("POST", "/auth/device/poll", { deviceCode }, { auth: false }); + } + attachments(documentId) { + return this.request("GET", `/documents/${encodeURIComponent(documentId)}/attachments`); + } + uploadAttachment(documentId, filename, data, contentType = "application/octet-stream") { + return this.request("POST", `/documents/${encodeURIComponent(documentId)}/attachments?filename=${encodeURIComponent(filename)}`, data, { + contentType, + raw: true + }); + } + async downloadAttachment(attachmentId) { + const response = await this.rawRequest("GET", `/attachments/${encodeURIComponent(attachmentId)}`); + if (response.arrayBuffer) return response.arrayBuffer; + return new TextEncoder().encode(response.text).buffer; + } + async deleteAttachment(attachmentId) { + await this.request("DELETE", `/attachments/${encodeURIComponent(attachmentId)}`); + } + async request(method, path, body, options = {}) { + const response = await this.rawRequest(method, path, body, options); + const json = safeJson(response.text); + if (response.status < 200 || response.status >= 300) { + throw new PagedenApiError(response.status, json); + } + return json; + } + async rawRequest(method, path, body, options = {}) { + const headers = { + ...options.auth === false || !this.token ? {} : { authorization: `Bearer ${this.token}` }, + ...body === void 0 ? {} : { "content-type": options.contentType ?? "application/json" } + }; + const response = await this.transport.request({ + method, + url: `${this.serverUrl.replace(/\/+$/, "")}/api${path}`, + headers, + body: body === void 0 ? void 0 : options.raw ? body : JSON.stringify(body) + }); + if (response.status < 200 || response.status >= 300) { + throw new PagedenApiError(response.status, safeJson(response.text)); + } + return response; + } +}; +function safeJson(text2) { + if (!text2) return null; + try { + return JSON.parse(text2); + } catch { + return text2; + } +} + +// src/metadata.ts +var ServerMetaStore = class { + constructor(adapter, pluginDir) { + this.adapter = adapter; + this.path = `${pluginDir.replace(/\/+$/, "")}/.server-meta.json`; + } + adapter; + path; + get filePath() { + return this.path; + } + async read() { + if (!await this.adapter.exists(this.path)) return { documents: {}, attachments: {} }; + const raw = await this.adapter.read(this.path); + const parsed = JSON.parse(raw); + return { documents: parsed.documents ?? {}, attachments: parsed.attachments ?? {} }; + } + async write(meta) { + await this.adapter.write(this.path, JSON.stringify(meta, null, 2)); + } + async list() { + const meta = await this.read(); + return Object.values(meta.documents); + } + async getByLocalPath(localPath) { + const meta = await this.read(); + return Object.values(meta.documents).find((entry) => entry.localPath === localPath) ?? null; + } + async upsert(entry) { + const meta = await this.read(); + meta.documents[entry.documentId] = entry; + await this.write(meta); + } + async listAttachments() { + const meta = await this.read(); + return Object.values(meta.attachments ?? {}); + } + async listAttachmentsForDocument(documentId) { + const meta = await this.read(); + return Object.values(meta.attachments ?? {}).filter((entry) => entry.documentId === documentId); + } + async upsertAttachment(entry) { + const meta = await this.read(); + meta.attachments ??= {}; + meta.attachments[entry.attachmentId] = entry; + await this.write(meta); + } + async removeAttachment(attachmentId) { + const meta = await this.read(); + if (!meta.attachments) return; + delete meta.attachments[attachmentId]; + await this.write(meta); + } +}; + +// src/sync.ts +var import_obsidian2 = require("obsidian"); + +// src/checksum.ts +function canonicalize(content) { + return content.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\n*$/, "") + "\n"; +} +async function checksum(content) { + if (!globalThis.crypto?.subtle) { + throw new Error("Web Crypto is required to compute Pageden checksums."); + } + const bytes = new TextEncoder().encode(canonicalize(content)); + const digest2 = await globalThis.crypto.subtle.digest("SHA-256", bytes); + const hex = [...new Uint8Array(digest2)].map((byte) => byte.toString(16).padStart(2, "0")).join(""); + return `sha256:${hex}`; +} + +// src/sync.ts +function localPathForRemote(remoteDocsFolder, remotePath) { + const withoutLeadingSlash = remotePath.replace(/^\/+/, ""); + const withExtension = withoutLeadingSlash.endsWith(".md") ? withoutLeadingSlash : `${withoutLeadingSlash}.md`; + return (0, import_obsidian2.normalizePath)(`${remoteDocsFolder}/${withExtension}`); +} +async function ensureFolder(vault, folderPath) { + const parts = (0, import_obsidian2.normalizePath)(folderPath).split("/").filter(Boolean); + let current = ""; + for (const part of parts) { + current = current ? `${current}/${part}` : part; + if (!await vault.exists(current)) await vault.mkdir(current); + } +} +async function downloadDocument(deps, doc4) { + const remote = await deps.api.document(doc4.id); + const localPath = localPathForRemote(deps.remoteDocsFolder, remote.path); + const parent = localPath.split("/").slice(0, -1).join("/"); + if (parent) await ensureFolder(deps.vault, parent); + const content = canonicalize(remote.content); + await deps.vault.write(localPath, content); + const meta = metaFromRemote(remote, localPath); + await deps.meta.upsert(meta); + const attachments = hasAttachmentSupport(deps) ? await syncDocumentAttachments(deps, meta, content) : emptyAttachmentSummary(); + return { localPath, meta, attachments }; +} +async function pushLocalDocument(deps, localPath) { + const meta = await deps.meta.getByLocalPath(localPath); + if (!meta) throw new Error("This file is not linked to a Pageden document."); + if (meta.permission === "viewer") return { status: "blocked_viewer" }; + const content = canonicalize(await deps.vault.read(localPath)); + try { + const result = await deps.api.push(meta.documentId, { + baseVersion: meta.baseVersion, + checksum: await checksum(content), + content + }); + const nextMeta = { ...meta, baseVersion: result.version, checksum: result.checksum, updatedAt: result.updatedAt }; + await deps.meta.upsert(nextMeta); + if (hasAttachmentSupport(deps)) await syncDocumentAttachments(deps, nextMeta, content); + return { status: "pushed", result }; + } catch (error) { + if (error instanceof PagedenApiError && error.status === 409) { + const server = await deps.api.document(meta.documentId); + const conflictPath = await writeConflictFile(deps.vault, localPath, server); + await deps.meta.upsert({ ...meta, baseVersion: server.version ?? meta.baseVersion, checksum: server.checksum ?? meta.checksum, permission: server.permission, updatedAt: server.updatedAt }); + return { status: "conflict", conflictPath, serverPath: server.path }; + } + throw error; + } +} +async function pushOrCreateLocalDocument(deps, localPath) { + const meta = await deps.meta.getByLocalPath(localPath); + if (meta) return pushLocalDocument(deps, localPath); + return createRemoteDocumentFromLocal(deps, localPath); +} +async function createRemoteDocumentFromLocal(deps, localPath) { + const content = canonicalize(await deps.vault.read(localPath)); + const tree = await deps.api.tree(deps.workspaceId); + const target = targetPathForLocal(deps.remoteDocsFolder, localPath); + const existingPath = target.documentPath; + if (tree.documents.some((doc4) => trimSlashes(doc4.path) === existingPath)) { + throw new Error(`A Pageden document already exists at "${existingPath}". Download it first to link this local note safely.`); + } + const folder = await ensureRemoteFolderPath(deps.api, deps.workspaceId, tree, target.folderSegments); + const created = await deps.api.createDocument({ + workspaceId: deps.workspaceId, + folderId: folder.id, + title: frontmatterTitle(content) ?? target.title, + slug: target.documentSlug, + content + }); + const remote = await deps.api.document(created.id); + const meta = metaFromRemote(remote, localPath); + await deps.meta.upsert(meta); + if (hasAttachmentSupport(deps)) await syncDocumentAttachments(deps, meta, content); + return { + status: "created", + result: { id: remote.id, version: meta.baseVersion, checksum: meta.checksum, updatedAt: meta.updatedAt }, + meta + }; +} +async function writeConflictFile(vault, localPath, server) { + const stem = localPath.replace(/\.md$/i, ""); + const conflictPath = (0, import_obsidian2.normalizePath)(`${stem}.conflict.md`); + await vault.write(conflictPath, canonicalize(server.content)); + return conflictPath; +} +function metaFromRemote(remote, localPath) { + if (!remote.version || !remote.checksum) { + throw new Error("Remote document is missing version metadata."); + } + return { + documentId: remote.id, + localPath, + remotePath: remote.path, + title: remote.title, + baseVersion: remote.version, + checksum: remote.checksum, + permission: remote.permission, + updatedAt: remote.updatedAt + }; +} +async function ensureRemoteFolderPath(api, workspaceId, tree, folderSegments) { + const folderByPath = new Map(tree.folders.map((folder) => [trimSlashes(folder.path), folder])); + let parent = null; + let currentPath = ""; + for (const segment of folderSegments) { + const slug = slugify(segment); + currentPath = currentPath ? `${currentPath}/${slug}` : slug; + const existing = folderByPath.get(currentPath); + if (existing) { + parent = existing; + continue; + } + const created = await api.createFolder({ + workspaceId, + parentFolderId: parent?.id ?? null, + name: segment, + slug + }); + parent = { + id: created.id, + parentFolderId: parent?.id ?? null, + name: segment, + slug, + path: trimSlashes(created.path), + permission: "manager" + }; + folderByPath.set(currentPath, parent); + } + if (!parent) { + throw new Error("Create the note inside a folder so Pageden knows where to place it."); + } + return parent; +} +function targetPathForLocal(remoteDocsFolder, localPath) { + const normalizedLocal = (0, import_obsidian2.normalizePath)(localPath); + const normalizedRoot = (0, import_obsidian2.normalizePath)(remoteDocsFolder).replace(/\/+$/, ""); + const relativePath = normalizedLocal === normalizedRoot ? "" : normalizedLocal.startsWith(`${normalizedRoot}/`) ? normalizedLocal.slice(normalizedRoot.length + 1) : normalizedLocal; + const parts = relativePath.split("/").filter(Boolean); + const filename = parts.pop() ?? "untitled.md"; + const folderSegments = parts.map((part) => part.replace(/\.md$/i, "")); + const title = filename.replace(/\.md$/i, "") || "Untitled"; + const documentSlug = slugify(filename); + const documentPath = [...folderSegments.map(slugify), `${documentSlug}.md`].filter(Boolean).join("/"); + return { folderSegments, title, documentSlug, documentPath }; +} +function frontmatterTitle(content) { + if (!content.startsWith("---\n")) return null; + const end = content.indexOf("\n---", 4); + if (end === -1) return null; + const raw = content.slice(4, end); + for (const line of raw.split("\n")) { + const match2 = line.match(/^title:\s*(.+)$/i); + if (!match2?.[1]) continue; + return match2[1].trim().replace(/^['"]|['"]$/g, "") || null; + } + return null; +} +function slugify(value) { + const slug = value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/\.md$/i, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""); + return slug || "untitled"; +} +function trimSlashes(path) { + return path.replace(/^\/+|\/+$/g, ""); +} +function conflictSiblingPath(localPath) { + return `${localPath.replace(/\.md$/i, "")}.conflict.md`; +} +async function syncLinkedDocument(deps, entry) { + const base2 = { documentId: entry.documentId, localPath: entry.localPath }; + let remote; + try { + remote = await deps.api.document(entry.documentId); + } catch (error) { + if (error instanceof PagedenApiError && error.status === 404) return { ...base2, status: "gone" }; + throw error; + } + const serverMoved = (remote.version ?? "") !== entry.baseVersion; + const localExists = await deps.vault.exists(entry.localPath); + if (await deps.vault.exists(conflictSiblingPath(entry.localPath))) { + return { ...base2, status: "conflict_pending", conflictPath: conflictSiblingPath(entry.localPath) }; + } + let localCanonical = ""; + if (localExists) { + localCanonical = canonicalize(await deps.vault.read(entry.localPath)); + const localDiverged = await checksum(localCanonical) !== entry.checksum; + if (localDiverged) { + if (remote.permission === "viewer") { + if (serverMoved) { + const conflictPath = await writeConflictFile(deps.vault, entry.localPath, remote); + await deps.meta.upsert(metaFromRemote(remote, entry.localPath)); + return { ...base2, status: "conflict", conflictPath }; + } + await deps.meta.upsert({ ...entry, permission: "viewer" }); + return { ...base2, status: "blocked_viewer" }; + } + const pushed = await pushLocalDocument(deps, entry.localPath); + if (pushed.status === "pushed") return { ...base2, status: "pushed" }; + if (pushed.status === "conflict") return { ...base2, status: "conflict", conflictPath: pushed.conflictPath }; + return { ...base2, status: "blocked_viewer" }; + } + } + if (!localExists) { + return { ...base2, status: "missing_local" }; + } + if (serverMoved) { + const fresh = canonicalize(await deps.vault.read(entry.localPath)); + if (await checksum(fresh) !== entry.checksum) { + const conflictPath = await writeConflictFile(deps.vault, entry.localPath, remote); + await deps.meta.upsert(metaFromRemote(remote, entry.localPath)); + return { ...base2, status: "conflict", conflictPath }; + } + await applyRemotePull(deps, entry.localPath, remote); + return { ...base2, status: "pulled" }; + } + if (remote.permission !== entry.permission) { + await deps.meta.upsert({ ...entry, permission: remote.permission }); + } + if (hasAttachmentSupport(deps)) { + await syncDocumentAttachments(deps, { ...entry, permission: remote.permission }, localCanonical); + } + return { ...base2, status: "unchanged" }; +} +async function applyRemotePull(deps, localPath, remote) { + const parent = localPath.split("/").slice(0, -1).join("/"); + if (parent) await ensureFolder(deps.vault, parent); + const content = canonicalize(remote.content); + await deps.vault.write(localPath, content); + const meta = metaFromRemote(remote, localPath); + await deps.meta.upsert(meta); + if (hasAttachmentSupport(deps)) await syncDocumentAttachments(deps, meta, content); +} +async function runBackgroundSyncPass(deps, onResult) { + const summary = { + unchanged: 0, + created: 0, + pulled: 0, + pushed: 0, + conflicts: 0, + conflictsPending: 0, + blockedViewer: 0, + missingLocal: 0, + gone: 0, + attachmentsDownloaded: 0, + attachmentsUploaded: 0, + attachmentsDeleted: 0, + errors: 0 + }; + const entries = await deps.meta.list(); + const linkedLocalPaths = new Set(entries.map((entry) => (0, import_obsidian2.normalizePath)(entry.localPath))); + for (const entry of entries) { + try { + const result = await syncLinkedDocument(deps, entry); + onResult?.(result); + switch (result.status) { + case "unchanged": + summary.unchanged += 1; + break; + case "created": + summary.created += 1; + break; + case "pulled": + summary.pulled += 1; + break; + case "pushed": + summary.pushed += 1; + break; + case "conflict": + summary.conflicts += 1; + break; + case "conflict_pending": + summary.conflictsPending += 1; + break; + case "blocked_viewer": + summary.blockedViewer += 1; + break; + case "missing_local": + summary.missingLocal += 1; + break; + case "gone": + summary.gone += 1; + break; + } + } catch { + summary.errors += 1; + } + } + if (canCreateUnlinkedLocalDocuments(deps)) { + for (const localPath of await deps.localMarkdownPaths()) { + const normalizedPath = (0, import_obsidian2.normalizePath)(localPath); + if (linkedLocalPaths.has(normalizedPath) || normalizedPath.endsWith(".conflict.md")) continue; + try { + const result = await createRemoteDocumentFromLocal(deps, normalizedPath); + if (result.meta) linkedLocalPaths.add((0, import_obsidian2.normalizePath)(result.meta.localPath)); + summary.created += 1; + onResult?.({ documentId: result.meta?.documentId ?? "", localPath: normalizedPath, status: "created" }); + } catch { + summary.errors += 1; + } + } + } + return summary; +} +function canCreateUnlinkedLocalDocuments(deps) { + return Boolean(deps.workspaceId && deps.localMarkdownPaths && deps.api.tree && deps.api.createFolder && deps.api.createDocument); +} +async function syncDocumentAttachments(deps, entry, markdown) { + const api = requireAttachmentApi(deps); + const meta = requireAttachmentMeta(deps); + const vault = requireBinaryVault(deps); + const summary = emptyAttachmentSummary(); + const remote = await api.attachments(entry.documentId); + const tracked = await meta.listAttachmentsForDocument(entry.documentId); + const trackedById = new Map(tracked.map((item) => [item.attachmentId, item])); + const remoteById = new Map(remote.attachments.map((item) => [item.id, item])); + const content = markdown ?? (await deps.vault.exists(entry.localPath) ? await deps.vault.read(entry.localPath) : ""); + const referenced = entry.permission === "viewer" ? /* @__PURE__ */ new Set() : extractAttachmentPaths(content, entry.localPath); + for (const old of tracked) { + if (!remoteById.has(old.attachmentId)) await meta.removeAttachment(old.attachmentId); + } + if (entry.permission !== "viewer") { + for (const old of tracked) { + if (!remoteById.has(old.attachmentId) || referenced.has(old.localPath) || await deps.vault.exists(old.localPath)) continue; + await api.deleteAttachment(old.attachmentId); + await meta.removeAttachment(old.attachmentId); + remoteById.delete(old.attachmentId); + summary.deleted += 1; + } + } + for (const attachment of remote.attachments) { + if (!remoteById.has(attachment.id)) continue; + const localPath = trackedById.get(attachment.id)?.localPath ?? attachmentLocalPath(entry.localPath, attachment.filename); + if (!await deps.vault.exists(localPath) || trackedById.get(attachment.id)?.sha256 !== attachment.sha256) { + await ensureParent(deps.vault, localPath); + await vault.writeBinary(localPath, await api.downloadAttachment(attachment.id)); + summary.downloaded += 1; + } + await meta.upsertAttachment(metaFromAttachment(entry.documentId, localPath, attachment)); + } + if (entry.permission === "viewer") return summary; + const trackedByPath = new Map((await meta.listAttachmentsForDocument(entry.documentId)).map((item) => [item.localPath, item])); + for (const localPath of referenced) { + if (!await deps.vault.exists(localPath)) { + summary.skipped += 1; + continue; + } + const bytes = await vault.readBinary(localPath); + const sha256 = await sha256Hex(bytes); + const existing = trackedByPath.get(localPath); + if (existing?.sha256 === sha256) { + summary.skipped += 1; + continue; + } + const uploaded = await api.uploadAttachment(entry.documentId, localPath.split("/").pop() ?? "attachment", bytes, contentTypeForPath(localPath)); + if (existing) { + await api.deleteAttachment(existing.attachmentId); + await meta.removeAttachment(existing.attachmentId); + summary.deleted += 1; + } + await meta.upsertAttachment(metaFromAttachment(entry.documentId, localPath, uploaded)); + summary.uploaded += 1; + } + return summary; +} +function emptyAttachmentSummary() { + return { downloaded: 0, uploaded: 0, deleted: 0, skipped: 0 }; +} +function hasAttachmentSupport(deps) { + return Boolean( + deps.api.attachments && deps.api.uploadAttachment && deps.api.downloadAttachment && deps.api.deleteAttachment && deps.vault.readBinary && deps.vault.writeBinary && deps.meta.listAttachmentsForDocument && deps.meta.upsertAttachment && deps.meta.removeAttachment + ); +} +function requireAttachmentApi(deps) { + if (!deps.api.attachments || !deps.api.uploadAttachment || !deps.api.downloadAttachment || !deps.api.deleteAttachment) { + throw new Error("Attachment sync requires attachment API methods."); + } + return deps.api; +} +function requireAttachmentMeta(deps) { + if (!deps.meta.listAttachmentsForDocument || !deps.meta.upsertAttachment || !deps.meta.removeAttachment) { + throw new Error("Attachment sync requires attachment metadata methods."); + } + return deps.meta; +} +function requireBinaryVault(deps) { + if (!deps.vault.readBinary || !deps.vault.writeBinary) { + throw new Error("Attachment sync requires binary vault methods."); + } + return deps.vault; +} +function metaFromAttachment(documentId, localPath, attachment) { + return { + attachmentId: attachment.id, + documentId, + localPath, + filename: attachment.filename, + sha256: attachment.sha256, + size: attachment.size, + contentType: attachment.contentType, + createdAt: attachment.createdAt + }; +} +function attachmentLocalPath(documentPath, filename) { + const parent = documentPath.split("/").slice(0, -1).join("/"); + return (0, import_obsidian2.normalizePath)(`${parent}/${filename}`); +} +async function ensureParent(vault, path) { + const parent = path.split("/").slice(0, -1).join("/"); + if (parent) await ensureFolder(vault, parent); +} +function extractAttachmentPaths(markdown, documentPath) { + const parent = documentPath.split("/").slice(0, -1).join("/"); + const out = /* @__PURE__ */ new Set(); + const push = (raw) => { + const target = raw.trim(); + if (!target || target.startsWith("#") || /^[a-z][a-z0-9+.-]*:/i.test(target) || target.endsWith(".md")) return; + const clean = target.split(/[?#]/)[0] ?? ""; + if (!clean) return; + out.add((0, import_obsidian2.normalizePath)(clean.startsWith("/") ? clean.slice(1) : `${parent}/${clean}`)); + }; + for (const match2 of markdown.matchAll(/!\[[^\]]*]\(([^)]+)\)|\[[^\]]+]\(([^)]+)\)/g)) { + push(match2[1] ?? match2[2] ?? ""); + } + for (const match2 of markdown.matchAll(/!\[\[([^\]|#]+)(?:#[^\]|]+)?(?:\|[^\]]+)?]]/g)) { + push(match2[1] ?? ""); + } + return out; +} +async function sha256Hex(bytes) { + const hash = await crypto.subtle.digest("SHA-256", bytes); + return [...new Uint8Array(hash)].map((b2) => b2.toString(16).padStart(2, "0")).join(""); +} +function contentTypeForPath(path) { + const ext = path.split(".").pop()?.toLowerCase(); + if (ext === "png") return "image/png"; + if (ext === "jpg" || ext === "jpeg") return "image/jpeg"; + if (ext === "gif") return "image/gif"; + if (ext === "webp") return "image/webp"; + if (ext === "svg") return "image/svg+xml"; + if (ext === "pdf") return "application/pdf"; + return "application/octet-stream"; +} + +// src/runner.ts +function createSyncRunner(pass) { + let inFlight = false; + let pending = false; + async function run4() { + if (inFlight) { + pending = true; + return; + } + inFlight = true; + try { + do { + pending = false; + await pass(); + } while (pending); + } finally { + inFlight = false; + } + } + return { run: run4, isRunning: () => inFlight }; +} +function createDebouncer(ms) { + const timers = /* @__PURE__ */ new Map(); + function cancel(key) { + const existing = timers.get(key); + if (existing !== void 0) { + clearTimeout(existing); + timers.delete(key); + } + } + return { + schedule(key, fn) { + cancel(key); + timers.set( + key, + setTimeout(() => { + timers.delete(key); + fn(); + }, ms) + ); + }, + cancel, + cancelAll() { + for (const timer of timers.values()) clearTimeout(timer); + timers.clear(); + } + }; +} + +// src/import-vault.ts +var import_obsidian3 = require("obsidian"); +var DEFAULT_ROOT_NAME = "Imported from Obsidian"; +function buildVaultImportPreview(files, remoteTree, targetRootName = DEFAULT_ROOT_NAME) { + const importable = splitImportableFiles(files); + const targetRootSlug = slugify2(targetRootName); + const remoteDocumentPaths = new Set(remoteTree.documents.map((doc4) => trimSlashes2(doc4.path))); + const conflicts = importable.notes.map((file) => remotePathForNote(file.path, targetRootSlug)).filter((path) => remoteDocumentPaths.has(path)).sort(); + const warnings = conflicts.length ? [`${conflicts.length} note${conflicts.length === 1 ? "" : "s"} already exist in Pageden and will be skipped.`] : []; + return { + targetRootName, + targetRootSlug, + notes: importable.notes.length, + attachments: importable.attachments.length, + skipped: importable.skipped, + conflicts, + warnings + }; +} +async function importVaultToPageden(deps) { + const remoteTree = deps.remoteTree ?? await deps.api.tree(deps.workspaceId); + const preview = buildVaultImportPreview(deps.files, remoteTree, deps.targetRootName); + const importable = splitImportableFiles(deps.files); + const attachmentIndex = buildAttachmentIndex(importable.attachments); + const folderByPath = new Map(remoteTree.folders.map((folder) => [trimSlashes2(folder.path), folder])); + const documentPaths = new Set(remoteTree.documents.map((doc4) => trimSlashes2(doc4.path))); + const targetRootSlug = preview.targetRootSlug; + let foldersCreated = 0; + let documentsCreated = 0; + let documentsSkipped = 0; + let attachmentsUploaded = 0; + const attachmentWarnings = []; + const rows = []; + async function ensureRemoteFolder(localDir) { + const segments = localDir.split("/").filter(Boolean); + let parent = null; + let currentPath = ""; + const rootPath = targetRootSlug; + parent = folderByPath.get(rootPath) ?? null; + if (!parent) { + const created = await deps.api.createFolder({ + workspaceId: deps.workspaceId, + parentFolderId: null, + name: deps.targetRootName, + slug: targetRootSlug + }); + parent = folderFromCreate(created.id, null, deps.targetRootName, targetRootSlug, created.path); + folderByPath.set(rootPath, parent); + foldersCreated += 1; + } + currentPath = rootPath; + for (const segment of segments) { + const slug = slugify2(segment); + currentPath = `${currentPath}/${slug}`; + const existing = folderByPath.get(currentPath); + if (existing) { + parent = existing; + continue; + } + const created = await deps.api.createFolder({ + workspaceId: deps.workspaceId, + parentFolderId: parent.id, + name: segment, + slug + }); + parent = folderFromCreate(created.id, parent.id, segment, slug, created.path); + folderByPath.set(currentPath, parent); + foldersCreated += 1; + } + return parent; + } + let noteIndex = 0; + for (const note of importable.notes) { + noteIndex++; + deps.onProgress?.(noteIndex, importable.notes.length); + const remotePath = remotePathForNote(note.path, targetRootSlug); + if (documentPaths.has(remotePath)) { + documentsSkipped += 1; + rows.push({ path: note.path, status: "skipped", message: "A document with this path already exists." }); + continue; + } + const localDir = dirname(note.path); + const folder = await ensureRemoteFolder(localDir); + const content = canonicalize(await deps.vault.read(note.path)); + const title = frontmatterTitle2(content) ?? (basename(note.path).replace(/\.md$/i, "") || "Untitled"); + const created = await deps.api.createDocument({ + workspaceId: deps.workspaceId, + folderId: folder.id, + title, + slug: slugify2(basename(note.path).replace(/\.md$/i, "")), + content + }); + documentPaths.add(trimSlashes2(created.path)); + const remote = await deps.api.document(created.id); + await deps.meta.upsert(metaFromImportedRemote(remote, note.path)); + documentsCreated += 1; + rows.push({ path: note.path, status: "created", message: `Created ${created.path}` }); + const refs = extractAttachmentRefs(content); + const uploadedForDoc = /* @__PURE__ */ new Set(); + for (const ref of refs) { + const attachment = resolveAttachmentRef(ref, note.path, attachmentIndex); + if (!attachment || uploadedForDoc.has(attachment.path)) continue; + uploadedForDoc.add(attachment.path); + if (!deps.vault.readBinary) { + const message = `Cannot upload ${attachment.path}: this vault adapter does not support binary reads.`; + attachmentWarnings.push(message); + rows.push({ path: attachment.path, status: "warning", message }); + continue; + } + try { + const bytes = await deps.vault.readBinary(attachment.path); + await uploadAttachmentWithRetry(deps.api, remote.id, basename(attachment.path), bytes, mimeTypeForPath(attachment.path)); + attachmentsUploaded += 1; + } catch (error) { + const message = `Could not upload ${attachment.path}: ${error instanceof Error ? error.message : "unknown error"}`; + attachmentWarnings.push(message); + rows.push({ path: attachment.path, status: "warning", message }); + } + } + } + return { + ...preview, + foldersCreated, + documentsCreated, + documentsSkipped, + attachmentsUploaded, + attachmentWarnings, + rows + }; +} +function extractAttachmentRefs(markdown) { + const refs = /* @__PURE__ */ new Set(); + const obsidianEmbed = /!\[\[([^\]#|]+)(?:[#|][^\]]*)?\]\]/g; + const markdownImage = /!\[[^\]]*]\((?![a-z][a-z0-9+.-]*:)([^)\s]+)(?:\s+"[^"]*")?\)/gi; + for (const match2 of markdown.matchAll(obsidianEmbed)) { + if (match2[1]) refs.add(match2[1]); + } + for (const match2 of markdown.matchAll(markdownImage)) { + if (match2[1]) refs.add(decodeURIComponent(match2[1])); + } + return [...refs]; +} +function slugify2(value) { + const slug = value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/\.md$/i, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, ""); + return slug || "untitled"; +} +function splitImportableFiles(files) { + let skipped = 0; + const notes = []; + const attachments = []; + for (const file of files) { + const path = (0, import_obsidian3.normalizePath)(file.path); + if (isIgnoredPath(path)) { + skipped += 1; + continue; + } + if (file.extension.toLowerCase() === "md") { + if (path.endsWith(".conflict.md")) skipped += 1; + else notes.push({ ...file, path }); + } else { + attachments.push({ ...file, path }); + } + } + notes.sort((a, b2) => a.path.localeCompare(b2.path)); + attachments.sort((a, b2) => a.path.localeCompare(b2.path)); + return { notes, attachments, skipped }; +} +function isIgnoredPath(path) { + return path.startsWith(".obsidian/") || path.startsWith(".trash/") || path.startsWith(".git/"); +} +function buildAttachmentIndex(files) { + const byPath = /* @__PURE__ */ new Map(); + const byName = /* @__PURE__ */ new Map(); + for (const file of files) { + byPath.set(file.path, file); + const list = byName.get(file.name) ?? []; + list.push(file); + byName.set(file.name, list); + } + return { byPath, byName }; +} +function resolveAttachmentRef(ref, notePath, index) { + const cleanRef = (0, import_obsidian3.normalizePath)(ref.replace(/^<|>$/g, "")); + const noteDir = dirname(notePath); + const candidates = [ + (0, import_obsidian3.normalizePath)(`${noteDir}/${cleanRef}`), + cleanRef + ]; + for (const candidate of candidates) { + const found3 = index.byPath.get(candidate); + if (found3) return found3; + } + const byName = index.byName.get(basename(cleanRef)); + if (byName?.length) return byName[0] ?? null; + return null; +} +function remotePathForNote(path, targetRootSlug) { + const localDir = dirname(path).split("/").filter(Boolean).map(slugify2).join("/"); + const docSlug = slugify2(basename(path)); + return [targetRootSlug, localDir, `${docSlug}.md`].filter(Boolean).join("/"); +} +function frontmatterTitle2(content) { + if (!content.startsWith("---\n")) return null; + const end = content.indexOf("\n---", 4); + if (end === -1) return null; + const raw = content.slice(4, end); + for (const line of raw.split("\n")) { + const match2 = line.match(/^title:\s*(.+)$/i); + if (!match2?.[1]) continue; + return match2[1].trim().replace(/^['"]|['"]$/g, "") || null; + } + return null; +} +async function uploadAttachmentWithRetry(api, documentId, name, bytes, mimeType) { + try { + await api.uploadAttachment(documentId, name, bytes, mimeType); + } catch (firstError) { + try { + await api.uploadAttachment(documentId, name, bytes, mimeType); + } catch { + throw firstError; + } + } +} +function folderFromCreate(id2, parentFolderId, name, slug, path) { + return { + id: id2, + parentFolderId, + name, + slug, + path: trimSlashes2(path), + permission: "manager" + }; +} +function metaFromImportedRemote(remote, localPath) { + if (!remote.version || !remote.checksum) throw new Error("Imported document is missing version metadata."); + return { + documentId: remote.id, + localPath, + remotePath: remote.path, + title: remote.title, + baseVersion: remote.version, + checksum: remote.checksum, + permission: remote.permission, + updatedAt: remote.updatedAt + }; +} +function mimeTypeForPath(path) { + const ext = path.split(".").pop()?.toLowerCase(); + if (ext === "png") return "image/png"; + if (ext === "jpg" || ext === "jpeg") return "image/jpeg"; + if (ext === "gif") return "image/gif"; + if (ext === "webp") return "image/webp"; + if (ext === "mp4") return "video/mp4"; + if (ext === "webm") return "video/webm"; + if (ext === "mov") return "video/quicktime"; + if (ext === "pdf") return "application/pdf"; + return "application/octet-stream"; +} +function dirname(path) { + const normalized = (0, import_obsidian3.normalizePath)(path); + const index = normalized.lastIndexOf("/"); + return index === -1 ? "" : normalized.slice(0, index); +} +function basename(path) { + return (0, import_obsidian3.normalizePath)(path).split("/").filter(Boolean).pop() ?? ""; +} +function trimSlashes2(path) { + return path.replace(/^\/+|\/+$/g, ""); +} + +// src/main.ts +var PUSH_DEBOUNCE_MS = 2e3; +var REMOTE_WRITE_GUARD_MS = 1500; +var LIVE_VIEW_TYPE = "pageden-live-document"; +var turndown = new TurndownService({ + bulletListMarker: "-", + codeBlockStyle: "fenced", + headingStyle: "atx" +}); +turndown.use(gfm); +var DEFAULT_SETTINGS = { + serverUrl: "https://go.pageden.app", + token: "", + workspaceId: "", + remoteDocsFolder: "Remote Docs", + autoSyncEnabled: false, + autoSyncIntervalMinutes: 5, + userName: "", + workspaceName: "" +}; +var PagedenPlugin = class extends import_obsidian4.Plugin { + settings = DEFAULT_SETTINGS; + metaStore; + statusBarEl; + syncRunner; + pushDebouncer; + applyingRemoteWrites = /* @__PURE__ */ new Set(); + syncIntervalId; + lastSummary; + async onload() { + await this.loadSettings(); + this.metaStore = new ServerMetaStore(this.app.vault.adapter, this.pluginDir()); + this.addSettingTab(new PagedenSettingTab(this.app, this)); + this.registerView(LIVE_VIEW_TYPE, (leaf) => new LiveDocumentView(leaf, this)); + this.addCommand({ + id: "validate-connection", + name: "Validate connection", + callback: () => void this.validateConnection() + }); + this.addCommand({ + id: "browse-remote-documents", + name: "Browse remote documents", + callback: () => void this.openRemoteBrowser() + }); + this.addCommand({ + id: "search-remote-documents", + name: "Search remote documents", + callback: () => void this.openRemoteSearch() + }); + this.addCommand({ + id: "import-vault", + name: "Import this vault to Pageden", + callback: () => void this.openVaultImport() + }); + this.addCommand({ + id: "open-live-document", + name: "Open live document", + callback: () => void this.openLiveDocumentPicker() + }); + this.addCommand({ + id: "device-code-login", + name: "Log in with device code", + callback: () => void this.startDeviceLogin() + }); + this.addCommand({ + id: "push-active-document", + name: "Push active document", + checkCallback: (checking) => { + const file = this.app.workspace.getActiveFile(); + const canPush = file instanceof import_obsidian4.TFile && file.extension === "md"; + if (checking) return canPush; + if (file) void this.pushFile(file); + return true; + } + }); + this.addCommand({ + id: "download-folder", + name: "Download a Pageden folder", + callback: () => void this.openFolderDownload() + }); + this.addCommand({ + id: "download-all-documents", + name: "Download all Pageden documents", + callback: () => void this.downloadAllDocuments() + }); + this.addCommand({ + id: "resolve-conflict", + name: "Resolve conflict for this note", + checkCallback: (checking) => { + const file = this.app.workspace.getActiveFile(); + const canResolve = file instanceof import_obsidian4.TFile && file.extension === "md" && !file.path.endsWith(".conflict.md"); + if (checking) return canResolve; + if (file) void this.resolveConflict(file); + return true; + } + }); + this.statusBarEl = this.addStatusBarItem(); + this.syncRunner = createSyncRunner(() => this.runSyncPass()); + this.pushDebouncer = createDebouncer(PUSH_DEBOUNCE_MS); + this.addCommand({ + id: "sync-now", + name: "Sync now", + callback: () => void this.syncRunner.run() + }); + this.registerEvent(this.app.vault.on("modify", (file) => this.onVaultFileChanged(file))); + this.registerEvent(this.app.vault.on("create", (file) => this.onVaultFileChanged(file))); + this.app.workspace.onLayoutReady(() => this.startAutoSync()); + } + onunload() { + this.stopAutoSync(); + } + // Start (or restart) the auto-sync interval. Safe to call repeatedly — e.g. when settings change. + startAutoSync() { + this.stopAutoSync(); + if (!this.settings.autoSyncEnabled) { + this.setStatusIdle(); + return; + } + const minutes = Math.max(1, Math.floor(Number(this.settings.autoSyncIntervalMinutes)) || DEFAULT_SETTINGS.autoSyncIntervalMinutes); + this.syncIntervalId = window.setInterval(() => void this.syncRunner.run(), minutes * 6e4); + this.registerInterval(this.syncIntervalId); + if (this.isConfigured()) void this.syncRunner.run(); + else this.setStatus("Pageden: not connected"); + } + stopAutoSync() { + if (this.syncIntervalId !== void 0) { + window.clearInterval(this.syncIntervalId); + this.syncIntervalId = void 0; + } + this.pushDebouncer?.cancelAll(); + } + isConfigured() { + return Boolean(this.settings.serverUrl.trim() && this.settings.token.trim() && this.settings.workspaceId.trim()); + } + // One full pull/push reconciliation pass. Serialised by syncRunner; never throws into Obsidian. + async runSyncPass() { + if (!this.settings.autoSyncEnabled || !this.isConfigured()) return; + this.setStatus("Pageden: syncing\u2026"); + try { + const summary = await runBackgroundSyncPass(this.backgroundSyncDeps()); + this.lastSummary = summary; + this.renderSummary(summary); + } catch { + this.setStatus("Pageden: offline"); + } + } + onVaultFileChanged(file) { + if (!this.settings.autoSyncEnabled || !this.isConfigured()) return; + if (!(file instanceof import_obsidian4.TFile) || file.extension !== "md") return; + const path = file.path; + if (path.endsWith(".conflict.md")) return; + if (this.applyingRemoteWrites.has(path)) return; + this.pushDebouncer.schedule(path, () => void this.debouncedPush(path)); + } + async debouncedPush(path) { + if (this.syncRunner.isRunning()) { + this.pushDebouncer.schedule(path, () => void this.debouncedPush(path)); + return; + } + try { + const meta = await this.metaStore.getByLocalPath(path); + if (meta?.permission === "viewer") return; + if (!meta && !isUnderRemoteDocsFolder(this.settings.remoteDocsFolder, path)) return; + if (await this.app.vault.adapter.exists(conflictSiblingPath(path))) return; + const localCanonical = canonicalize(await this.app.vault.adapter.read(path)); + if (meta && await checksum(localCanonical) === meta.checksum) return; + const result = await pushOrCreateLocalDocument(this.createSyncDeps(), path); + if (result.status === "conflict") this.setStatus("Pageden: conflict"); + else if (result.status === "pushed" || result.status === "created") this.setStatusIdle(); + } catch { + this.setStatus("Pageden: error"); + } + } + backgroundSyncDeps() { + const base2 = this.syncDeps(); + return { + ...base2, + vault: this.guardedVault(base2.vault), + workspaceId: this.settings.workspaceId, + localMarkdownPaths: async () => this.app.vault.getFiles().filter((file) => file.extension === "md" && isUnderRemoteDocsFolder(this.settings.remoteDocsFolder, file.path)).map((file) => file.path) + }; + } + // Wrap vault writes so a background pull marks the path as remote-applied; the modify handler + // skips it (belt to the checksum gate's suspenders). + guardedVault(base2) { + return { + ...base2, + write: async (path, content) => { + this.applyingRemoteWrites.add(path); + try { + await base2.write(path, content); + } finally { + window.setTimeout(() => this.applyingRemoteWrites.delete(path), REMOTE_WRITE_GUARD_MS); + } + }, + writeBinary: base2.writeBinary ? async (path, content) => { + this.applyingRemoteWrites.add(path); + try { + await base2.writeBinary?.(path, content); + } finally { + window.setTimeout(() => this.applyingRemoteWrites.delete(path), REMOTE_WRITE_GUARD_MS); + } + } : void 0 + }; + } + setStatus(text2) { + this.statusBarEl?.setText(text2); + } + setStatusIdle() { + const s = this.lastSummary; + if (s && s.conflicts) { + this.setStatus(`Pageden: ${s.conflicts} conflict${s.conflicts === 1 ? "" : "s"} \u2014 run "Resolve conflict" to fix`); + } else if (s && (s.created || s.pulled || s.pushed)) { + this.setStatus(`Pageden: synced (${s.created} created, ${s.pushed} sent, ${s.pulled} received)`); + } else { + this.setStatus("Pageden: up to date"); + } + } + renderSummary(s) { + if (s.errors) this.setStatus("Pageden: sync error \u2014 will retry"); + else if (s.conflicts) this.setStatus(`Pageden: ${s.conflicts} conflict${s.conflicts === 1 ? "" : "s"} \u2014 run "Resolve conflict" to fix`); + else this.setStatus(`Pageden: synced (${s.created} created, ${s.pushed} sent, ${s.pulled} received)`); + } + async loadSettings() { + this.settings = { ...DEFAULT_SETTINGS, ...await this.loadData() }; + } + async saveSettings() { + await this.saveData(this.settings); + } + api() { + return new PagedenApiClient(this.settings.serverUrl, this.settings.token); + } + liveBaseUrl() { + return `${this.settings.serverUrl.replace(/\/+$/, "")}/api/live`; + } + publicApi() { + return new PagedenApiClient(this.settings.serverUrl, ""); + } + async validateConnection() { + try { + this.requireConfigured(); + await this.api().validate(); + new import_obsidian4.Notice("Pageden connection is valid."); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async openRemoteBrowser() { + try { + this.requireConfigured(); + const tree = await this.api().tree(this.settings.workspaceId); + new RemoteDocumentModal(this.app, tree, (doc4) => void this.download(doc4)).open(); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async openRemoteSearch() { + try { + this.requireConfigured(); + new RemoteSearchModal(this.app, this).open(); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async openVaultImport() { + try { + this.requireConfigured(); + const files = this.vaultImportFiles(); + const tree = await this.api().tree(this.settings.workspaceId); + new VaultImportModal(this.app, this, files, tree).open(); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async openLiveDocumentPicker() { + try { + this.requireConfigured(); + const tree = await this.api().tree(this.settings.workspaceId); + new RemoteDocumentModal(this.app, tree, (doc4) => void this.openLiveDocument(doc4), "Open live").open(); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async searchRemote(query) { + const response = await this.api().search(this.settings.workspaceId, query); + return response.results; + } + async downloadSearchResult(result) { + await this.download({ + id: result.id, + folderId: "", + title: result.title, + path: result.path, + permission: result.permission, + version: null, + checksum: null + }); + } + async startDeviceLogin() { + try { + if (!this.settings.serverUrl.trim()) throw new Error("Set a Pageden server URL first."); + const request = await this.publicApi().deviceStart(); + new DeviceLoginModal(this.app, this, request).open(); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async pollDeviceLogin(deviceCode) { + const result = await this.publicApi().devicePoll(deviceCode); + if (result.status === "pending") return "pending"; + if (result.status === "approved") { + this.settings.token = result.token; + try { + const me2 = await new PagedenApiClient(this.settings.serverUrl, result.token).me(); + this.settings.userName = me2.user.name; + if (me2.workspaces.length === 1) { + const ws = me2.workspaces[0]; + this.settings.workspaceId = ws.id; + this.settings.workspaceName = ws.name; + await this.saveSettings(); + this.startAutoSync(); + new import_obsidian4.Notice(`Connected! Signed in as ${me2.user.name}, workspace "${ws.name}".`); + } else if (me2.workspaces.length > 1) { + await this.saveSettings(); + new WorkspacePickerModal(this.app, this, me2.workspaces).open(); + } else { + await this.saveSettings(); + this.startAutoSync(); + new import_obsidian4.Notice(`Connected as ${me2.user.name}. No workspaces found \u2014 create one in Pageden first.`); + } + } catch { + await this.saveSettings(); + this.startAutoSync(); + new import_obsidian4.Notice("Login approved. Open Settings \u2192 Pageden to select a workspace."); + } + return "done"; + } + if (result.status === "denied") new import_obsidian4.Notice("Login was cancelled."); + else if (result.status === "expired") new import_obsidian4.Notice("Login code expired. Please try again."); + else new import_obsidian4.Notice(`Login ${result.status}.`); + return "done"; + } + async download(doc4) { + try { + const result = await downloadDocument(this.syncDeps(), doc4); + new import_obsidian4.Notice(`Downloaded ${result.localPath}`); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async openLiveDocument(doc4) { + try { + this.requireConfigured(); + if (doc4.permission === "viewer") { + new import_obsidian4.Notice("Live editing requires editor or manager permission."); + return; + } + const leaf = this.app.workspace.getLeaf("tab"); + await leaf.setViewState({ type: LIVE_VIEW_TYPE, active: true }); + if (leaf.view instanceof LiveDocumentView) await leaf.view.openDocument(doc4.id); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async pushFile(file) { + try { + this.requireConfigured(); + const result = await pushOrCreateLocalDocument(this.createSyncDeps(), file.path); + if (result.status === "blocked_viewer") { + new import_obsidian4.Notice("This remote document is viewer-only, so it cannot be pushed."); + } else if (result.status === "conflict") { + new import_obsidian4.Notice( + `Your changes conflict with a newer server version. +The server version was saved as "${result.conflictPath}". +Use the "Resolve conflict for this note" command to dismiss it.`, + 8e3 + ); + } else { + new import_obsidian4.Notice(result.status === "created" ? "Created in Pageden." : "Pushed to Pageden."); + } + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async importVault(files, targetRootName, onProgress) { + this.requireConfigured(); + return importVaultToPageden({ + api: this.api(), + vault: this.vaultAdapter(), + meta: this.metaStore, + workspaceId: this.settings.workspaceId, + files, + targetRootName, + onProgress + }); + } + async openFolderDownload() { + try { + this.requireConfigured(); + const tree = await this.api().tree(this.settings.workspaceId); + new FolderDownloadModal(this.app, this, tree).open(); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async downloadFolderDocuments(folderId, folderName, tree) { + try { + const docs = tree.documents.filter((d2) => d2.folderId === folderId); + if (docs.length === 0) { + new import_obsidian4.Notice(`No documents found in "${folderName}".`); + return; + } + new import_obsidian4.Notice(`Downloading ${docs.length} note${docs.length === 1 ? "" : "s"} from "${folderName}"\u2026`, 3e3); + let downloaded = 0; + let failed = 0; + for (const doc4 of docs) { + try { + await downloadDocument(this.syncDeps(), doc4); + downloaded++; + } catch { + failed++; + } + } + new import_obsidian4.Notice( + failed > 0 ? `Downloaded ${downloaded} of ${docs.length} notes from "${folderName}". ${failed} failed.` : `Downloaded ${downloaded} note${downloaded === 1 ? "" : "s"} from "${folderName}".` + ); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async downloadAllDocuments() { + try { + this.requireConfigured(); + const tree = await this.api().tree(this.settings.workspaceId); + if (tree.documents.length === 0) { + new import_obsidian4.Notice("No documents found in your Pageden workspace."); + return; + } + new import_obsidian4.Notice(`Downloading ${tree.documents.length} note${tree.documents.length === 1 ? "" : "s"}\u2026`, 3e3); + let downloaded = 0; + let failed = 0; + for (const doc4 of tree.documents) { + try { + await downloadDocument(this.syncDeps(), doc4); + downloaded++; + } catch { + failed++; + } + } + new import_obsidian4.Notice( + failed > 0 ? `Downloaded ${downloaded} of ${tree.documents.length} notes. ${failed} failed.` : `Downloaded all ${downloaded} note${downloaded === 1 ? "" : "s"}.` + ); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } + async resolveConflict(file) { + const conflictPath = conflictSiblingPath(file.path); + if (!await this.app.vault.adapter.exists(conflictPath)) { + new import_obsidian4.Notice("No conflict file found for this note."); + return; + } + await this.app.vault.adapter.remove(conflictPath); + new import_obsidian4.Notice("Conflict resolved \u2014 the server copy has been removed."); + } + syncDeps() { + return { + api: this.api(), + vault: this.vaultAdapter(), + meta: this.metaStore, + remoteDocsFolder: this.settings.remoteDocsFolder + }; + } + createSyncDeps() { + return { + ...this.syncDeps(), + workspaceId: this.settings.workspaceId + }; + } + vaultAdapter() { + const adapter = this.app.vault.adapter; + return { + read: (path) => adapter.read(path), + write: (path, content) => adapter.write(path, content), + readBinary: (path) => adapter.readBinary(path), + writeBinary: (path, content) => adapter.writeBinary(path, content), + exists: (path) => adapter.exists(path), + mkdir: (path) => adapter.mkdir(path) + }; + } + vaultImportFiles() { + return this.app.vault.getFiles().map((file) => ({ + path: file.path, + name: file.name, + extension: file.extension + })); + } + pluginDir() { + return this.manifest.dir ?? `.obsidian/plugins/${this.manifest.id}`; + } + requireConfigured() { + if (!this.settings.serverUrl.trim()) throw new Error("Please set your Pageden server URL in settings."); + if (!this.settings.token.trim()) throw new Error('Please connect to Pageden first. Open Settings \u2192 Pageden and click "Connect to Pageden".'); + if (!this.settings.workspaceId.trim()) throw new Error('Please select a workspace. Open Settings \u2192 Pageden and click "Connect to Pageden".'); + } +}; +var LiveDocumentView = class extends import_obsidian4.ItemView { + constructor(leaf, plugin) { + super(leaf); + this.plugin = plugin; + } + plugin; + editor; + provider; + ydoc; + documentId; + baseVersion = ""; + lastSavedMarkdown = ""; + statusEl; + titleEl; + pathEl; + saveTimer; + saving = false; + saveAgain = false; + getViewType() { + return LIVE_VIEW_TYPE; + } + getDisplayText() { + return this.titleEl?.getText() || "Pageden live document"; + } + async openDocument(documentId) { + this.destroyLiveSession(); + this.documentId = documentId; + this.contentEl.empty(); + this.contentEl.addClass("pageden-live-view"); + const header = this.contentEl.createDiv({ cls: "pageden-live-header" }); + const titleWrap = header.createDiv(); + this.titleEl = titleWrap.createEl("h2", { text: "Loading..." }); + this.pathEl = titleWrap.createEl("p", { text: "Connecting to Pageden" }); + this.statusEl = header.createEl("span", { text: "Connecting", cls: "pageden-live-status" }); + const toolbar = this.contentEl.createDiv({ cls: "pageden-live-toolbar" }); + const editorEl = this.contentEl.createDiv({ cls: "pageden-live-editor" }); + const remote = await this.plugin.api().document(documentId); + if (remote.permission === "viewer") throw new Error("Live editing requires editor or manager permission."); + this.baseVersion = remote.version ?? ""; + this.lastSavedMarkdown = remote.content; + this.titleEl.setText(remote.title); + this.pathEl.setText(remote.path); + this.ydoc = new Doc(); + this.provider = new WebsocketProvider(this.plugin.liveBaseUrl(), documentId, this.ydoc, { + params: { token: this.plugin.settings.token }, + connect: true, + disableBc: true + }); + this.editor = new Editor({ + element: editorEl, + extensions: [ + index_default2.configure({ link: false, undoRedo: false }), + index_default3.configure({ document: this.ydoc }), + index_default.configure({ autolink: true, openOnClick: false, protocols: ["http", "https", "mailto"] }), + index_default4.configure({ placeholder: "Start writing..." }), + index_default5, + index_default6.configure({ nested: true }), + Table.configure({ resizable: true }), + index_default7, + index_default8, + index_default9 + ], + editorProps: { + attributes: { class: "pageden-live-prosemirror" } + }, + onUpdate: ({ editor }) => { + const markdown = htmlToMarkdown(editor.getHTML()); + if (markdown !== this.lastSavedMarkdown) this.scheduleSave(); + } + }); + this.renderToolbar(toolbar); + this.provider.on("status", (event) => this.setStatus(event.status === "connected" ? "Live" : "Reconnecting")); + this.provider.on("sync", (synced) => { + if (synced) this.seedInitialContent(remote.content); + }); + if (this.provider.synced) this.seedInitialContent(remote.content); + } + async onClose() { + this.destroyLiveSession(); + } + renderToolbar(toolbar) { + const buttons = [ + ["B", () => this.editor?.chain().focus().toggleBold().run()], + ["I", () => this.editor?.chain().focus().toggleItalic().run()], + ["H1", () => this.editor?.chain().focus().toggleHeading({ level: 1 }).run()], + ["H2", () => this.editor?.chain().focus().toggleHeading({ level: 2 }).run()], + ["List", () => this.editor?.chain().focus().toggleBulletList().run()], + ["Task", () => this.editor?.chain().focus().toggleTaskList().run()], + ["Save", () => void this.persist()] + ]; + for (const [label, action] of buttons) { + const button = toolbar.createEl("button", { text: label, cls: "pageden-live-button" }); + button.addEventListener("click", action); + } + } + seedInitialContent(markdown) { + if (!this.editor || this.editor.getText().trim()) return; + this.editor.commands.setContent(markdownToHtml(markdown), { emitUpdate: true }); + } + scheduleSave() { + if (this.saving) { + this.saveAgain = true; + return; + } + if (this.saveTimer !== void 0) window.clearTimeout(this.saveTimer); + this.saveTimer = window.setTimeout(() => void this.persist(), 1500); + } + async persist() { + if (!this.editor || !this.documentId) return; + if (this.saving) { + this.saveAgain = true; + return; + } + if (this.saveTimer !== void 0) { + window.clearTimeout(this.saveTimer); + this.saveTimer = void 0; + } + const content = htmlToMarkdown(this.editor.getHTML()); + if (content === this.lastSavedMarkdown) return; + this.saving = true; + this.setStatus("Saving"); + try { + const result = await this.plugin.api().push(this.documentId, { + baseVersion: this.baseVersion, + checksum: await checksum(content), + content + }); + this.baseVersion = result.version; + this.lastSavedMarkdown = content; + this.setStatus("Saved"); + } catch (error) { + if (error instanceof PagedenApiError && error.status === 409 && error.currentVersion) { + this.baseVersion = error.currentVersion; + this.saving = false; + await this.persist(); + return; + } + this.setStatus("Save failed"); + throw error; + } finally { + this.saving = false; + if (this.saveAgain) { + this.saveAgain = false; + this.scheduleSave(); + } + } + } + setStatus(status) { + this.statusEl?.setText(status); + } + destroyLiveSession() { + if (this.saveTimer !== void 0) { + window.clearTimeout(this.saveTimer); + this.saveTimer = void 0; + } + this.editor?.destroy(); + this.provider?.destroy(); + this.ydoc?.destroy(); + this.editor = void 0; + this.provider = void 0; + this.ydoc = void 0; + this.saveAgain = false; + } +}; +var PagedenSettingTab = class extends import_obsidian4.PluginSettingTab { + constructor(app, plugin) { + super(app, plugin); + this.plugin = plugin; + } + plugin; + display() { + const { containerEl } = this; + containerEl.empty(); + containerEl.createEl("h2", { text: "Pageden" }); + const isConnected = this.plugin.isConfigured(); + if (!isConnected) { + containerEl.createEl("p", { + text: "Connect your Obsidian vault to Pageden to sync notes and collaborate with your team.", + cls: "setting-item-description" + }); + new import_obsidian4.Setting(containerEl).setName("Connect your vault").setDesc("Click the button below. A login page will open in your browser \u2014 approve it there and you're done.").addButton( + (btn) => btn.setButtonText("Connect to Pageden").setCta().onClick(() => void this.plugin.startDeviceLogin()) + ); + containerEl.createEl("h3", { text: "Server" }); + new import_obsidian4.Setting(containerEl).setName("Server URL").setDesc("The address of your Pageden server.").addText( + (text2) => text2.setPlaceholder("https://app.example.com").setValue(this.plugin.settings.serverUrl).onChange(async (value) => { + this.plugin.settings.serverUrl = value.trim(); + await this.plugin.saveSettings(); + }) + ); + } else { + const displayName = this.plugin.settings.userName || "your account"; + const displayWs = this.plugin.settings.workspaceName || this.plugin.settings.workspaceId; + new import_obsidian4.Setting(containerEl).setName(`Signed in as ${displayName}`).setDesc(`Workspace: ${displayWs}`).addButton( + (btn) => btn.setButtonText("Change workspace").onClick(() => void this.changeWorkspace()) + ).addButton( + (btn) => btn.setButtonText("Disconnect").onClick(async () => { + this.plugin.settings.token = ""; + this.plugin.settings.workspaceId = ""; + this.plugin.settings.userName = ""; + this.plugin.settings.workspaceName = ""; + await this.plugin.saveSettings(); + this.plugin.startAutoSync(); + this.display(); + }) + ); + containerEl.createEl("h3", { text: "Sync" }); + new import_obsidian4.Setting(containerEl).setName("Background sync").setDesc("Automatically pull remote updates and push local edits.").addToggle( + (toggle) => toggle.setValue(this.plugin.settings.autoSyncEnabled).onChange(async (value) => { + this.plugin.settings.autoSyncEnabled = value; + await this.plugin.saveSettings(); + this.plugin.startAutoSync(); + }) + ); + new import_obsidian4.Setting(containerEl).setName("Sync interval (minutes)").setDesc("How often background sync runs. Minimum 1 minute.").addText( + (text2) => text2.setPlaceholder("5").setValue(String(this.plugin.settings.autoSyncIntervalMinutes)).onChange(async (value) => { + const minutes = Math.max(1, Math.floor(Number(value)) || DEFAULT_SETTINGS.autoSyncIntervalMinutes); + this.plugin.settings.autoSyncIntervalMinutes = minutes; + await this.plugin.saveSettings(); + this.plugin.startAutoSync(); + }) + ); + new import_obsidian4.Setting(containerEl).setName("Local folder").setDesc("Folder in your vault where downloaded documents are stored.").addText( + (text2) => text2.setPlaceholder("Remote Docs").setValue(this.plugin.settings.remoteDocsFolder).onChange(async (value) => { + this.plugin.settings.remoteDocsFolder = (0, import_obsidian4.normalizePath)(value.trim() || DEFAULT_SETTINGS.remoteDocsFolder); + await this.plugin.saveSettings(); + }) + ); + const details = containerEl.createEl("details"); + details.createEl("summary", { text: "Advanced" }); + const adv = details.createDiv(); + new import_obsidian4.Setting(adv).setName("Server URL").addText( + (text2) => text2.setPlaceholder("https://app.example.com").setValue(this.plugin.settings.serverUrl).onChange(async (value) => { + this.plugin.settings.serverUrl = value.trim(); + await this.plugin.saveSettings(); + this.plugin.startAutoSync(); + }) + ); + new import_obsidian4.Setting(adv).setName("Connection").addButton( + (btn) => btn.setButtonText("Test connection").onClick(() => void this.plugin.validateConnection()) + ).addButton( + (btn) => btn.setButtonText("Sign in again").onClick(() => void this.plugin.startDeviceLogin()) + ); + } + } + async changeWorkspace() { + try { + const me2 = await this.plugin.api().me(); + if (me2.workspaces.length === 0) { + new import_obsidian4.Notice("No workspaces found on this account."); + return; + } + new WorkspacePickerModal(this.app, this.plugin, me2.workspaces, () => this.display()).open(); + } catch (error) { + new import_obsidian4.Notice(errorMessage(error)); + } + } +}; +var RemoteDocumentModal = class extends import_obsidian4.Modal { + constructor(app, tree, onPick, buttonText = "Download") { + super(app); + this.tree = tree; + this.onPick = onPick; + this.buttonText = buttonText; + } + tree; + onPick; + buttonText; + onOpen() { + const { contentEl } = this; + contentEl.empty(); + contentEl.createEl("h2", { text: "Pageden documents" }); + const visibleDocs = this.tree.documents.filter((doc4) => doc4.permission !== "viewer" || doc4.version); + if (visibleDocs.length === 0) { + contentEl.createEl("p", { text: "No remote documents are available." }); + return; + } + for (const doc4 of visibleDocs) { + new import_obsidian4.Setting(contentEl).setName(doc4.title).setDesc(doc4.permission === "viewer" ? `${doc4.path} \xB7 read only` : doc4.path).addButton( + (button) => button.setButtonText(this.buttonText).onClick(() => { + this.close(); + this.onPick(doc4); + }) + ); + } + } +}; +var RemoteSearchModal = class extends import_obsidian4.Modal { + constructor(app, plugin) { + super(app); + this.plugin = plugin; + } + plugin; + query = ""; + resultsEl; + onOpen() { + const { contentEl } = this; + contentEl.empty(); + contentEl.createEl("h2", { text: "Search Pageden" }); + new import_obsidian4.Setting(contentEl).setName("Query").addText( + (text2) => text2.setPlaceholder("Search remote documents").onChange((value) => { + this.query = value; + }) + ).addButton( + (button) => button.setButtonText("Search").onClick(() => void this.runSearch()) + ); + this.resultsEl = contentEl.createDiv(); + } + async runSearch() { + if (!this.resultsEl) return; + this.resultsEl.empty(); + const q2 = this.query.trim(); + if (!q2) { + this.resultsEl.createEl("p", { text: "Enter a search query." }); + return; + } + try { + const results = await this.plugin.searchRemote(q2); + if (results.length === 0) { + this.resultsEl.createEl("p", { text: "No results." }); + return; + } + for (const result of results) { + new import_obsidian4.Setting(this.resultsEl).setName(result.title).setDesc(result.permission === "viewer" ? `${result.path} \xB7 read only` : result.path).addButton( + (button) => button.setButtonText("Download").onClick(() => { + this.close(); + void this.plugin.downloadSearchResult(result); + }) + ); + } + } catch (error) { + this.resultsEl.createEl("p", { text: errorMessage(error) }); + } + } +}; +var VaultImportModal = class extends import_obsidian4.Modal { + constructor(app, plugin, files, remoteTree) { + super(app); + this.plugin = plugin; + this.files = files; + this.remoteTree = remoteTree; + } + plugin; + files; + remoteTree; + targetRootName = "Imported from Obsidian"; + previewEl; + statusEl; + onOpen() { + const { contentEl } = this; + contentEl.empty(); + contentEl.createEl("h2", { text: "Import Obsidian vault" }); + contentEl.createEl("p", { + text: "Upload this vault's notes into Pageden. Existing remote documents are skipped, never overwritten." + }); + new import_obsidian4.Setting(contentEl).setName("Pageden folder").setDesc("Imported folders and notes will be created under this top-level folder.").addText( + (text2) => text2.setPlaceholder("Imported from Obsidian").setValue(this.targetRootName).onChange((value) => { + this.targetRootName = value.trim() || "Imported from Obsidian"; + this.renderPreview(); + }) + ); + this.previewEl = contentEl.createDiv(); + this.statusEl = contentEl.createEl("p"); + this.renderPreview(); + new import_obsidian4.Setting(contentEl).addButton( + (button) => button.setButtonText("Import vault").setCta().onClick(async () => { + button.setDisabled(true).setButtonText("Importing..."); + await this.runImport(); + button.setDisabled(false).setButtonText("Import vault"); + }) + ).addButton((button) => button.setButtonText("Cancel").onClick(() => this.close())); + } + renderPreview() { + if (!this.previewEl) return; + this.previewEl.empty(); + const preview = buildVaultImportPreview(this.files, this.remoteTree, this.targetRootName); + this.previewEl.createEl("h3", { text: "Preview" }); + const list = this.previewEl.createEl("ul"); + list.createEl("li", { text: `${preview.notes} Markdown note${preview.notes === 1 ? "" : "s"} ready to import.` }); + list.createEl("li", { text: `${preview.attachments} attachment${preview.attachments === 1 ? "" : "s"} detected.` }); + list.createEl("li", { text: `${preview.skipped} internal or unsupported file${preview.skipped === 1 ? "" : "s"} skipped.` }); + if (preview.conflicts.length) { + list.createEl("li", { text: `${preview.conflicts.length} remote document${preview.conflicts.length === 1 ? "" : "s"} already exist and will be skipped.` }); + } + this.statusEl?.setText(""); + } + async runImport() { + try { + this.statusEl?.setText("Starting import\u2026"); + const report = await this.plugin.importVault(this.files, this.targetRootName, (current, total) => { + this.statusEl?.setText(`Importing note ${current} of ${total}\u2026`); + }); + const warnings = report.attachmentWarnings.length ? ` ${report.attachmentWarnings.length} attachment warning${report.attachmentWarnings.length === 1 ? "" : "s"}.` : ""; + this.statusEl?.setText( + `Done! Created ${report.foldersCreated} folder${report.foldersCreated === 1 ? "" : "s"}, imported ${report.documentsCreated} note${report.documentsCreated === 1 ? "" : "s"}, uploaded ${report.attachmentsUploaded} attachment${report.attachmentsUploaded === 1 ? "" : "s"}.${warnings}` + ); + new import_obsidian4.Notice("Vault import complete."); + } catch (error) { + const message = errorMessage(error); + this.statusEl?.setText(message); + new import_obsidian4.Notice(message); + } + } +}; +var DeviceLoginModal = class extends import_obsidian4.Modal { + constructor(app, plugin, request) { + super(app); + this.plugin = plugin; + this.request = request; + } + plugin; + request; + intervalId; + statusEl; + onOpen() { + const { contentEl } = this; + contentEl.empty(); + contentEl.createEl("h2", { text: "Connect to Pageden" }); + contentEl.createEl("p", { + text: "A login page should have opened in your browser. Enter this code there to approve the connection:" + }); + contentEl.createEl("h3", { text: this.request.userCode, cls: "pageden-device-code" }); + contentEl.createEl("p", { + text: "If the browser did not open automatically, use the button below.", + cls: "setting-item-description" + }); + new import_obsidian4.Setting(contentEl).addButton( + (button) => button.setButtonText("Open browser").onClick(() => window.open(this.request.verificationUri)) + ).addButton( + (button) => button.setButtonText("Copy code").onClick(() => void navigator.clipboard?.writeText(this.request.userCode)) + ).addButton( + (button) => button.setButtonText("Check now").onClick(() => void this.poll()) + ); + this.statusEl = contentEl.createEl("p", { text: "Waiting for you to approve in the browser\u2026" }); + const intervalMs = Math.max(1, this.request.interval) * 1e3; + this.intervalId = window.setInterval(() => void this.poll(), intervalMs); + window.open(this.request.verificationUri); + } + onClose() { + if (this.intervalId !== void 0) { + window.clearInterval(this.intervalId); + this.intervalId = void 0; + } + } + async poll() { + try { + const status = await this.plugin.pollDeviceLogin(this.request.deviceCode); + if (status === "pending") { + this.statusEl?.setText("Waiting for approval..."); + } else { + this.close(); + } + } catch (error) { + this.statusEl?.setText(errorMessage(error)); + } + } +}; +var WorkspacePickerModal = class extends import_obsidian4.Modal { + constructor(app, plugin, workspaces, onSelect) { + super(app); + this.plugin = plugin; + this.workspaces = workspaces; + this.onSelect = onSelect; + } + plugin; + workspaces; + onSelect; + onOpen() { + const { contentEl } = this; + contentEl.empty(); + contentEl.createEl("h2", { text: "Choose a workspace" }); + contentEl.createEl("p", { + text: "Select which Pageden workspace to sync with this vault.", + cls: "setting-item-description" + }); + for (const ws of this.workspaces) { + new import_obsidian4.Setting(contentEl).setName(ws.name).setDesc(ws.role === "admin" ? "You are an admin" : "Member").addButton( + (btn) => btn.setButtonText("Select").setCta().onClick(async () => { + this.plugin.settings.workspaceId = ws.id; + this.plugin.settings.workspaceName = ws.name; + await this.plugin.saveSettings(); + this.plugin.startAutoSync(); + this.close(); + new import_obsidian4.Notice(`Workspace set to "${ws.name}".`); + this.onSelect?.(); + }) + ); + } + } +}; +var FolderDownloadModal = class extends import_obsidian4.Modal { + constructor(app, plugin, tree) { + super(app); + this.plugin = plugin; + this.tree = tree; + } + plugin; + tree; + onOpen() { + const { contentEl } = this; + contentEl.empty(); + contentEl.createEl("h2", { text: "Download a folder" }); + contentEl.createEl("p", { + text: "Choose a folder to download all its notes to your vault.", + cls: "setting-item-description" + }); + const foldersWithDocs = this.tree.folders.map((folder) => ({ folder, count: this.tree.documents.filter((d2) => d2.folderId === folder.id).length })).filter(({ count }) => count > 0).sort((a, b2) => a.folder.path.localeCompare(b2.folder.path)); + if (foldersWithDocs.length === 0) { + contentEl.createEl("p", { text: "No folders with documents found in your workspace." }); + return; + } + for (const { folder, count } of foldersWithDocs) { + new import_obsidian4.Setting(contentEl).setName(folder.name).setDesc(`${folder.path} \xB7 ${count} note${count === 1 ? "" : "s"}`).addButton( + (btn) => btn.setButtonText("Download all").onClick(() => { + this.close(); + void this.plugin.downloadFolderDocuments(folder.id, folder.name, this.tree); + }) + ); + } + } +}; +function errorMessage(error) { + if (error instanceof Error) return error.message; + return "Pageden request failed."; +} +function isUnderRemoteDocsFolder(remoteDocsFolder, path) { + const root2 = (0, import_obsidian4.normalizePath)(remoteDocsFolder).replace(/\/+$/, ""); + const localPath = (0, import_obsidian4.normalizePath)(path); + return localPath === root2 || localPath.startsWith(`${root2}/`); +} +function markdownToHtml(markdown) { + return g.parse(markdown, { async: false }); +} +function htmlToMarkdown(html) { + const markdown = turndown.turndown(html).trimEnd(); + return markdown ? `${markdown} +` : ""; +} +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21haW4udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL29yZGVyZWRtYXBAMi4xLjEvbm9kZV9tb2R1bGVzL29yZGVyZWRtYXAvZGlzdC9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHJvc2VtaXJyb3ItbW9kZWxAMS4yNS43L25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci1tb2RlbC9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci10cmFuc2Zvcm1AMS4xMi4wL25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci10cmFuc2Zvcm0vZGlzdC9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHJvc2VtaXJyb3Itc3RhdGVAMS40LjQvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXN0YXRlL2Rpc3QvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3Byb3NlbWlycm9yLWNvbW1hbmRzQDEuNy4xL25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci1jb21tYW5kcy9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci1zY2hlbWEtbGlzdEAxLjUuMS9ub2RlX21vZHVsZXMvcHJvc2VtaXJyb3Itc2NoZW1hLWxpc3QvZGlzdC9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHJvc2VtaXJyb3Itdmlld0AxLjQxLjgvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXZpZXcvZGlzdC9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vdzNjLWtleW5hbWVAMi4yLjgvbm9kZV9tb2R1bGVzL3czYy1rZXluYW1lL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci1rZXltYXBAMS4yLjMvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLWtleW1hcC9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvY3JlYXRlQ2hhaW5hYmxlU3RhdGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvQ29tbWFuZE1hbmFnZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvYmx1ci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9jbGVhckNvbnRlbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvY2xlYXJOb2Rlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9jb21tYW5kLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2NyZWF0ZVBhcmFncmFwaE5lYXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvY3V0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2RlbGV0ZUN1cnJlbnROb2RlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0Tm9kZVR5cGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvZGVsZXRlTm9kZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9kZWxldGVSYW5nZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9kZWxldGVTZWxlY3Rpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvZW50ZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvZXhpdENvZGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvZXh0ZW5kTWFya1JhbmdlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9pc1JlZ0V4cC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvb2JqZWN0SW5jbHVkZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRNYXJrUmFuZ2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRNYXJrVHlwZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9maXJzdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2lzVGV4dFNlbGVjdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL3Jlc29sdmVGb2N1c1Bvc2l0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9taW5NYXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2lzQW5kcm9pZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvaXNpT1MudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2lzU2FmYXJpLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2ZvY3VzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2ZvckVhY2gudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvaW5zZXJ0Q29udGVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9pbnNlcnRDb250ZW50QXQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9jcmVhdGVOb2RlRnJvbUNvbnRlbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2VsZW1lbnRGcm9tU3RyaW5nLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvc2VsZWN0aW9uVG9JbnNlcnRpb25FbmQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvam9pbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9qb2luSXRlbUJhY2t3YXJkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2pvaW5JdGVtRm9yd2FyZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9qb2luVGV4dGJsb2NrQmFja3dhcmQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvam9pblRleHRibG9ja0ZvcndhcmQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2lzTWFjT1MudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMva2V5Ym9hcmRTaG9ydGN1dC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9saWZ0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvaXNOb2RlQWN0aXZlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2xpZnRFbXB0eUJsb2NrLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2xpZnRMaXN0SXRlbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9uZXdsaW5lSW5Db2RlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2RlbGV0ZVByb3BzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3Jlc2V0QXR0cmlidXRlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zY3JvbGxJbnRvVmlldy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zZWxlY3RBbGwudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc2VsZWN0Tm9kZUJhY2t3YXJkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3NlbGVjdE5vZGVGb3J3YXJkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3NlbGVjdFBhcmVudE5vZGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc2VsZWN0VGV4dGJsb2NrRW5kLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3NlbGVjdFRleHRibG9ja1N0YXJ0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvY3JlYXRlRG9jdW1lbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc2V0Q29udGVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldE1hcmtBdHRyaWJ1dGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvY29tYmluZVRyYW5zYWN0aW9uU3RlcHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9kZWZhdWx0QmxvY2tBdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2ZpbmRDaGlsZHJlbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2ZpbmRDaGlsZHJlbkluUmFuZ2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9maW5kUGFyZW50Tm9kZUNsb3Nlc3RUb1Bvcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2ZpbmRQYXJlbnROb2RlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0RXh0ZW5zaW9uRmllbGQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9mbGF0dGVuRXh0ZW5zaW9ucy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dlbmVyYXRlSFRNTC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldEhUTUxGcm9tRnJhZ21lbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRTY2hlbWFCeVJlc29sdmVkRXh0ZW5zaW9ucy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvaXNGdW5jdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvY2FsbE9yUmV0dXJuLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9pc0VtcHR5T2JqZWN0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvc3BsaXRFeHRlbnNpb25zLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0QXR0cmlidXRlc0Zyb21FeHRlbnNpb25zLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9tZXJnZUF0dHJpYnV0ZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRSZW5kZXJlZEF0dHJpYnV0ZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2Zyb21TdHJpbmcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9pbmplY3RFeHRlbnNpb25BdHRyaWJ1dGVzVG9QYXJzZVJ1bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2ZpbmREdXBsaWNhdGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvc29ydEV4dGVuc2lvbnMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9yZXNvbHZlRXh0ZW5zaW9ucy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldFNjaGVtYS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dlbmVyYXRlSlNPTi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dlbmVyYXRlVGV4dC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldFRleHRCZXR3ZWVuLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0VGV4dC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldFRleHRTZXJpYWxpemVyc0Zyb21TY2hlbWEudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXROb2RlQXR0cmlidXRlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldEF0dHJpYnV0ZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL3JlbW92ZUR1cGxpY2F0ZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRDaGFuZ2VkUmFuZ2VzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0RGVidWdKU09OLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0TWFya3NCZXR3ZWVuLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0Tm9kZUF0UG9zaXRpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRTY2hlbWFUeXBlQnlOYW1lLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0U3BsaXR0ZWRBdHRyaWJ1dGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0VGV4dENvbnRlbnRGcm9tTm9kZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9pc01hcmtBY3RpdmUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9pc0FjdGl2ZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2lzQXRFbmRPZk5vZGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9pc0F0U3RhcnRPZk5vZGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9pc0V4dGVuc2lvblJ1bGVzRW5hYmxlZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2lzTGlzdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2lzTm9kZUVtcHR5LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvaXNOb2RlU2VsZWN0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvaXNOb2RlVmlld1NlbGVjdGVkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvTWFwcGFibGVQb3NpdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL3Bvc1RvRE9NUmVjdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL3Jld3JpdGVVbmtub3duQ29udGVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zZXRNYXJrLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3NldE1ldGEudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc2V0Tm9kZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zZXROb2RlU2VsZWN0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3NldFRleHREaXJlY3Rpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc2V0VGV4dFNlbGVjdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zaW5rTGlzdEl0ZW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc3BsaXRCbG9jay50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zcGxpdExpc3RJdGVtLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3RvZ2dsZUxpc3QudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvdG9nZ2xlTWFyay50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy90b2dnbGVOb2RlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3RvZ2dsZVdyYXAudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvdW5kb0lucHV0UnVsZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy91bnNldEFsbE1hcmtzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3Vuc2V0TWFyay50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy91bnNldFRleHREaXJlY3Rpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvdXBkYXRlQXR0cmlidXRlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy93cmFwSW4udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvd3JhcEluTGlzdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9FZGl0b3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvRXZlbnRFbWl0dGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL0V4dGVuc2lvbk1hbmFnZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvSW5wdXRSdWxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9pc1BsYWluT2JqZWN0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9tZXJnZURlZXAudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvRXh0ZW5kYWJsZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9NYXJrLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL1Bhc3RlUnVsZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvaXNOdW1iZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvZXh0ZW5zaW9ucy9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9leHRlbnNpb25zL2NsaXBib2FyZFRleHRTZXJpYWxpemVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL0V4dGVuc2lvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9leHRlbnNpb25zL2NvbW1hbmRzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2V4dGVuc2lvbnMvZGVsZXRlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2V4dGVuc2lvbnMvZHJvcC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9leHRlbnNpb25zL2VkaXRhYmxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2V4dGVuc2lvbnMvZm9jdXNFdmVudHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvZXh0ZW5zaW9ucy9rZXltYXAudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvZXh0ZW5zaW9ucy9wYXN0ZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9leHRlbnNpb25zL3RhYmluZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2V4dGVuc2lvbnMvdGV4dERpcmVjdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9Ob2RlUG9zLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3N0eWxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9jcmVhdGVTdHlsZVRhZy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9pbnB1dFJ1bGVzL21hcmtJbnB1dFJ1bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaW5wdXRSdWxlcy9ub2RlSW5wdXRSdWxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2lucHV0UnVsZXMvdGV4dGJsb2NrVHlwZUlucHV0UnVsZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9pbnB1dFJ1bGVzL3RleHRJbnB1dFJ1bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaW5wdXRSdWxlcy93cmFwcGluZ0lucHV0UnVsZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9qc3gtcnVudGltZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9saWIvUmVzaXphYmxlTm9kZVZpZXcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2F0dHJzRXF1YWwudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2Nhbkluc2VydE5vZGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2VzY2FwZUZvclJlZ0V4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9nZXRTdHlsZVByb3BlcnR5LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9odG1sRW50aXRpZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2lzRmlyZWZveC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvaXNTdHJpbmcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL21hcmtkb3duL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9tYXJrZG93bi9hdHRyaWJ1dGVVdGlscy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvbWFya2Rvd24vY3JlYXRlQXRvbUJsb2NrTWFya2Rvd25TcGVjLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9tYXJrZG93bi9jcmVhdGVCbG9ja01hcmtkb3duU3BlYy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvbWFya2Rvd24vY3JlYXRlSW5saW5lTWFya2Rvd25TcGVjLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9tYXJrZG93bi9wYXJzZUluZGVudGVkQmxvY2tzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9tYXJrZG93bi9yZW5kZXJOZXN0ZWRNYXJrZG93bkNvbnRlbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL21hcmtzRXF1YWwudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvTWFya1ZpZXcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvTm9kZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9Ob2RlVmlldy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9wYXN0ZVJ1bGVzL21hcmtQYXN0ZVJ1bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvcGFzdGVSdWxlcy9ub2RlUGFzdGVSdWxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3Bhc3RlUnVsZXMvdGV4dFBhc3RlUnVsZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9UcmFja2VyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2pzeC1ydW50aW1lLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1ibG9ja3F1b3RlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tYmxvY2txdW90ZS9zcmMvYmxvY2txdW90ZS50c3giLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWJsb2NrcXVvdGVAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfL25vZGVfbW9kdWxlcy9ub2RlX21vZHVsZXMvLnBucG0vcHJvc2VtaXJyb3ItbW9kZWxAMS4yNS43L25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci1tb2RlbC9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1ibG9ja3F1b3RlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvbm9kZV9tb2R1bGVzLy5wbnBtL3Byb3NlbWlycm9yLXRyYW5zZm9ybUAxLjEyLjAvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXRyYW5zZm9ybS9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1ibG9ja3F1b3RlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvbm9kZV9tb2R1bGVzLy5wbnBtL3Byb3NlbWlycm9yLXN0YXRlQDEuNC40L25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci1zdGF0ZS9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1ibG9ja3F1b3RlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tYmxvY2txdW90ZS9zcmMvaGFuZGxlQmFja3NwYWNlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1ibG9ja3F1b3RlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tYmxvY2txdW90ZS9zcmMvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWJvbGRAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1ib2xkL3NyYy9ib2xkLnRzeCIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tYm9sZEAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF8vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWJvbGQvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1jb2RlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tY29kZS9zcmMvY29kZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tY29kZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF8vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWNvZGUvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1jb2RlLWJsb2NrQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tY29kZS1ibG9jay9zcmMvY29kZS1ibG9jay50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tY29kZS1ibG9ja0AzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWNvZGUtYmxvY2svc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1kb2N1bWVudEAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF8vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWRvY3VtZW50L3NyYy9kb2N1bWVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tZG9jdW1lbnRAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1kb2N1bWVudC9zcmMvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWhhcmQtYnJlYWtAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1oYXJkLWJyZWFrL3NyYy9oYXJkLWJyZWFrLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1oYXJkLWJyZWFrQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24taGFyZC1icmVhay9zcmMvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWhlYWRpbmdAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1oZWFkaW5nL3NyYy9oZWFkaW5nLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1oZWFkaW5nQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24taGVhZGluZy9zcmMvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWhvcml6b250YWwtcnVsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWhvcml6b250YWwtcnVsZS9zcmMvaG9yaXpvbnRhbC1ydWxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1ob3Jpem9udGFsLXJ1bGVAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1ob3Jpem9udGFsLXJ1bGUvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1pdGFsaWNAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1pdGFsaWMvc3JjL2l0YWxpYy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24taXRhbGljQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24taXRhbGljL3NyYy9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbGlua2lmeWpzQDQuMy4zL25vZGVfbW9kdWxlcy9saW5raWZ5anMvZGlzdC9saW5raWZ5Lm1qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tbGlua0AzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWxpbmsvc3JjL2xpbmsudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpbmtAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saW5rL3NyYy9oZWxwZXJzL2F1dG9saW5rLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1saW5rQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tbGluay9zcmMvaGVscGVycy93aGl0ZXNwYWNlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1saW5rQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tbGluay9zcmMvaGVscGVycy9jbGlja0hhbmRsZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpbmtAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saW5rL3NyYy9oZWxwZXJzL3Bhc3RlSGFuZGxlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tbGlua0AzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWxpbmsvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1saXN0QDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tbGlzdC9zcmMvYnVsbGV0LWxpc3QvYnVsbGV0LWxpc3QudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saXN0L3NyYy9pdGVtL2xpc3QtaXRlbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tbGlzdEAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWxpc3Qvc3JjL2hlbHBlcnMvY3JlYXRlQnJhbmNoaW5nTGlzdERlbGV0ZUtleW1hcC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tbGlzdEAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWxpc3Qvc3JjL2hlbHBlcnMvaG9pc3RCcmFuY2hpbmdOZXN0ZWRMaXN0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1saXN0QDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tbGlzdC9zcmMvaGVscGVycy9nZXRCcmFuY2hpbmdOZXN0ZWRMaXN0QXRDdXJzb3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saXN0L3NyYy9oZWxwZXJzL2hhbmRsZURlbGV0ZUJyYW5jaGluZ05lc3RlZExpc3QudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saXN0L3NyYy9rZXltYXAvbGlzdC1rZXltYXAudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saXN0L3NyYy9rZXltYXAvbGlzdEhlbHBlcnMvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saXN0L3NyYy9rZXltYXAvbGlzdEhlbHBlcnMvZmluZExpc3RJdGVtUG9zLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1saXN0QDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tbGlzdC9zcmMva2V5bWFwL2xpc3RIZWxwZXJzL2dldE5leHRMaXN0RGVwdGgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saXN0L3NyYy9rZXltYXAvbGlzdEhlbHBlcnMvaGFuZGxlQmFja3NwYWNlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1saXN0QDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tbGlzdC9zcmMva2V5bWFwL2xpc3RIZWxwZXJzL2hhc0xpc3RCZWZvcmUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saXN0L3NyYy9rZXltYXAvbGlzdEhlbHBlcnMvaGFuZGxlRGVsZXRlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1saXN0QDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tbGlzdC9zcmMva2V5bWFwL2xpc3RIZWxwZXJzL25leHRMaXN0SXNEZWVwZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saXN0L3NyYy9rZXltYXAvbGlzdEhlbHBlcnMvbmV4dExpc3RJc0hpZ2hlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tbGlzdEAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWxpc3Qvc3JjL2tleW1hcC9saXN0SGVscGVycy9oYXNMaXN0SXRlbUFmdGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1saXN0QDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tbGlzdC9zcmMva2V5bWFwL2xpc3RIZWxwZXJzL2hhc0xpc3RJdGVtQmVmb3JlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1saXN0QDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tbGlzdC9zcmMva2V5bWFwL2xpc3RIZWxwZXJzL2xpc3RJdGVtSGFzU3ViTGlzdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tbGlzdEAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWxpc3Qvc3JjL2tpdC9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tbGlzdEAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWxpc3Qvc3JjL29yZGVyZWQtbGlzdC9vcmRlcmVkLWxpc3QudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saXN0L3NyYy9vcmRlcmVkLWxpc3QvdXRpbHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1saXN0L3NyYy90YXNrLWl0ZW0vdGFzay1pdGVtLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1saXN0QDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tbGlzdC9zcmMvdGFzay1saXN0L3Rhc2stbGlzdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tcGFyYWdyYXBoQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tcGFyYWdyYXBoL3NyYy9wYXJhZ3JhcGgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLXBhcmFncmFwaEAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF8vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXBhcmFncmFwaC9zcmMvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLXN0cmlrZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF8vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXN0cmlrZS9zcmMvc3RyaWtlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1zdHJpa2VAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1zdHJpa2Uvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10ZXh0QDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tdGV4dC9zcmMvdGV4dC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tdGV4dEAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF8vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRleHQvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi11bmRlcmxpbmVAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi11bmRlcmxpbmUvc3JjL3VuZGVybGluZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tdW5kZXJsaW5lQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tdW5kZXJsaW5lL3NyYy9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHJvc2VtaXJyb3ItZHJvcGN1cnNvckAxLjguMi9ub2RlX21vZHVsZXMvcHJvc2VtaXJyb3ItZHJvcGN1cnNvci9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci1nYXBjdXJzb3JAMS40LjEvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLWdhcGN1cnNvci9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9yb3BlLXNlcXVlbmNlQDEuMy40L25vZGVfbW9kdWxlcy9yb3BlLXNlcXVlbmNlL2Rpc3QvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3Byb3NlbWlycm9yLWhpc3RvcnlAMS41LjAvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLWhpc3RvcnkvZGlzdC9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb25zQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb25zL3NyYy9jaGFyYWN0ZXItY291bnQvY2hhcmFjdGVyLWNvdW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbnNAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbnMvc3JjL2Ryb3AtY3Vyc29yL2Ryb3AtY3Vyc29yLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbnNAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbnMvc3JjL2ZvY3VzL2ZvY3VzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbnNAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbnMvc3JjL2dhcC1jdXJzb3IvZ2FwLWN1cnNvci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb25zQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb25zL3NyYy9wbGFjZWhvbGRlci9jb25zdGFudHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uc0AzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9ucy9zcmMvcGxhY2Vob2xkZXIvcGxhY2Vob2xkZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uc0AzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9ucy9zcmMvcGxhY2Vob2xkZXIvcGx1Z2lucy9QbGFjZWhvbGRlclBsdWdpbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb25zQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb25zL3NyYy9wbGFjZWhvbGRlci91dGlscy9idWlsZFBsYWNlaG9sZGVyRGVjb3JhdGlvbnMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uc0AzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9ucy9zcmMvcGxhY2Vob2xkZXIvdXRpbHMvY3JlYXRlUGxhY2Vob2xkZXJEZWNvcmF0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbnNAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbnMvc3JjL3BsYWNlaG9sZGVyL3V0aWxzL3ByZXBhcmVQbGFjZWhvbGRlckF0dHJpYnV0ZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb25zQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb25zL3NyYy9wbGFjZWhvbGRlci91dGlscy9maW5kU2Nyb2xsUGFyZW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbnNAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbnMvc3JjL3BsYWNlaG9sZGVyL3V0aWxzL2dldFZpZXdwb3J0Qm91bmRhcnlQb3NpdGlvbnMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uc0AzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9ucy9zcmMvcGxhY2Vob2xkZXIvdXRpbHMvdmlld3BvcnRUcmFja2luZy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb25zQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb25zL3NyYy9zZWxlY3Rpb24vc2VsZWN0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbnNAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbnMvc3JjL3RyYWlsaW5nLW5vZGUvdHJhaWxpbmctbm9kZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb25zQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb25zL3NyYy91bmRvLXJlZG8vdW5kby1yZWRvLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK3N0YXJ0ZXIta2l0QDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9zdGFydGVyLWtpdC9zcmMvc3RhcnRlci1raXQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArc3RhcnRlci1raXRAMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL3N0YXJ0ZXIta2l0L3NyYy9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbGliMEAwLjIuMTE3L25vZGVfbW9kdWxlcy9saWIwL21hcC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbGliMEAwLjIuMTE3L25vZGVfbW9kdWxlcy9saWIwL3NldC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbGliMEAwLjIuMTE3L25vZGVfbW9kdWxlcy9saWIwL2FycmF5LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9saWIwQDAuMi4xMTcvbm9kZV9tb2R1bGVzL2xpYjAvb2JzZXJ2YWJsZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbGliMEAwLjIuMTE3L25vZGVfbW9kdWxlcy9saWIwL21hdGguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9iaW5hcnkuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9udW1iZXIuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9zdHJpbmcuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9lbmNvZGluZy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbGliMEAwLjIuMTE3L25vZGVfbW9kdWxlcy9saWIwL2Vycm9yLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9saWIwQDAuMi4xMTcvbm9kZV9tb2R1bGVzL2xpYjAvZGVjb2RpbmcuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC93ZWJjcnlwdG8uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9yYW5kb20uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC90aW1lLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9saWIwQDAuMi4xMTcvbm9kZV9tb2R1bGVzL2xpYjAvcHJvbWlzZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbGliMEAwLjIuMTE3L25vZGVfbW9kdWxlcy9saWIwL2NvbmRpdGlvbnMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9zdG9yYWdlLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9saWIwQDAuMi4xMTcvbm9kZV9tb2R1bGVzL2xpYjAvdHJhaXQvZXF1YWxpdHkuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9vYmplY3QuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9mdW5jdGlvbi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbGliMEAwLjIuMTE3L25vZGVfbW9kdWxlcy9saWIwL2Vudmlyb25tZW50LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9saWIwQDAuMi4xMTcvbm9kZV9tb2R1bGVzL2xpYjAvYnVmZmVyLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9saWIwQDAuMi4xMTcvbm9kZV9tb2R1bGVzL2xpYjAvcGFpci5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbGliMEAwLjIuMTE3L25vZGVfbW9kdWxlcy9saWIwL3BybmcuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9zY2hlbWEuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9kb20uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9ldmVudGxvb3AuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9zeW1ib2wuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9sb2dnaW5nLmNvbW1vbi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbGliMEAwLjIuMTE3L25vZGVfbW9kdWxlcy9saWIwL2xvZ2dpbmcuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9pdGVyYXRvci5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdXRpbHMvQWJzdHJhY3RDb25uZWN0b3IuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95anMvc3JjL3V0aWxzL0RlbGV0ZVNldC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdXRpbHMvRG9jLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy91dGlscy9VcGRhdGVEZWNvZGVyLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy91dGlscy9VcGRhdGVFbmNvZGVyLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy91dGlscy9lbmNvZGluZy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdXRpbHMvRXZlbnRIYW5kbGVyLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy91dGlscy9JRC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdXRpbHMvaXNQYXJlbnRPZi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdXRpbHMvbG9nZ2luZy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdXRpbHMvUGVybWFuZW50VXNlckRhdGEuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95anMvc3JjL3V0aWxzL1JlbGF0aXZlUG9zaXRpb24uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95anMvc3JjL3V0aWxzL1NuYXBzaG90LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy91dGlscy9TdHJ1Y3RTdG9yZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdXRpbHMvVHJhbnNhY3Rpb24uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95anMvc3JjL3V0aWxzL1VuZG9NYW5hZ2VyLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy91dGlscy91cGRhdGVzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy91dGlscy9ZRXZlbnQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95anMvc3JjL3R5cGVzL0Fic3RyYWN0VHlwZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdHlwZXMvWUFycmF5LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy90eXBlcy9ZTWFwLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy90eXBlcy9ZVGV4dC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdHlwZXMvWVhtbEZyYWdtZW50LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy90eXBlcy9ZWG1sRWxlbWVudC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdHlwZXMvWVhtbEV2ZW50LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy90eXBlcy9ZWG1sSG9vay5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvdHlwZXMvWVhtbFRleHQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95anMvc3JjL3N0cnVjdHMvQWJzdHJhY3RTdHJ1Y3QuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95anMvc3JjL3N0cnVjdHMvR0MuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95anMvc3JjL3N0cnVjdHMvQ29udGVudEJpbmFyeS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvc3RydWN0cy9Db250ZW50RGVsZXRlZC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvc3RydWN0cy9Db250ZW50RG9jLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy9zdHJ1Y3RzL0NvbnRlbnRFbWJlZC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvc3RydWN0cy9Db250ZW50Rm9ybWF0LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy9zdHJ1Y3RzL0NvbnRlbnRKU09OLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy9zdHJ1Y3RzL0NvbnRlbnRBbnkuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95anMvc3JjL3N0cnVjdHMvQ29udGVudFN0cmluZy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvc3RydWN0cy9Db250ZW50VHlwZS5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3lqcy9zcmMvc3RydWN0cy9JdGVtLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveWpzL3NyYy9zdHJ1Y3RzL1NraXAuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95anMvc3JjL2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95LXByb3RvY29sc0AxLjAuN195anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveS1wcm90b2NvbHMvYXdhcmVuZXNzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9saWIwQDAuMi4xMTcvbm9kZV9tb2R1bGVzL2xpYjAvbXV0ZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9kaWZmLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9saWIwQDAuMi4xMTcvbm9kZV9tb2R1bGVzL2xpYjAvaGFzaC9zaGEyNTYuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXAreS10aXB0YXBAMy4wLjRfcHJvc2VtaXJyb3ItbW9kZWxAMS4yNS43X3Byb3NlbWlycm9yLXN0YXRlQDEuNC40X3Byb3NlbWlycm9yLXZpZXdAMS40MV93dm9hYzRhdWt1cHV5bTRndWptbDdtbzVpcS9ub2RlX21vZHVsZXMvQHRpcHRhcC95LXRpcHRhcC9zcmMvcGx1Z2lucy9rZXlzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK3ktdGlwdGFwQDMuMC40X3Byb3NlbWlycm9yLW1vZGVsQDEuMjUuN19wcm9zZW1pcnJvci1zdGF0ZUAxLjQuNF9wcm9zZW1pcnJvci12aWV3QDEuNDFfd3ZvYWM0YXVrdXB1eW00Z3VqbWw3bW81aXEvbm9kZV9tb2R1bGVzL0B0aXB0YXAveS10aXB0YXAvc3JjL3V0aWxzLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK3ktdGlwdGFwQDMuMC40X3Byb3NlbWlycm9yLW1vZGVsQDEuMjUuN19wcm9zZW1pcnJvci1zdGF0ZUAxLjQuNF9wcm9zZW1pcnJvci12aWV3QDEuNDFfd3ZvYWM0YXVrdXB1eW00Z3VqbWw3bW81aXEvbm9kZV9tb2R1bGVzL0B0aXB0YXAveS10aXB0YXAvc3JjL3BsdWdpbnMvc3luYy1wbHVnaW4uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXAreS10aXB0YXBAMy4wLjRfcHJvc2VtaXJyb3ItbW9kZWxAMS4yNS43X3Byb3NlbWlycm9yLXN0YXRlQDEuNC40X3Byb3NlbWlycm9yLXZpZXdAMS40MV93dm9hYzRhdWt1cHV5bTRndWptbDdtbzVpcS9ub2RlX21vZHVsZXMvQHRpcHRhcC95LXRpcHRhcC9zcmMvbGliLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK3ktdGlwdGFwQDMuMC40X3Byb3NlbWlycm9yLW1vZGVsQDEuMjUuN19wcm9zZW1pcnJvci1zdGF0ZUAxLjQuNF9wcm9zZW1pcnJvci12aWV3QDEuNDFfd3ZvYWM0YXVrdXB1eW00Z3VqbWw3bW81aXEvbm9kZV9tb2R1bGVzL0B0aXB0YXAveS10aXB0YXAvc3JjL3BsdWdpbnMvY3Vyc29yLXBsdWdpbi5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCt5LXRpcHRhcEAzLjAuNF9wcm9zZW1pcnJvci1tb2RlbEAxLjI1LjdfcHJvc2VtaXJyb3Itc3RhdGVAMS40LjRfcHJvc2VtaXJyb3Itdmlld0AxLjQxX3d2b2FjNGF1a3VwdXltNGd1am1sN21vNWlxL25vZGVfbW9kdWxlcy9AdGlwdGFwL3ktdGlwdGFwL3NyYy9wbHVnaW5zL3VuZG8tcGx1Z2luLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1jb2xsYWJvcmF0aW9uQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjZfMmw1eHE1b3Z3dHNvcjU0d2YyemV0aWJ6ZnUvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWNvbGxhYm9yYXRpb24vc3JjL2NvbGxhYm9yYXRpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWNvbGxhYm9yYXRpb25AMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNl8ybDV4cTVvdnd0c29yNTR3ZjJ6ZXRpYnpmdS9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tY29sbGFib3JhdGlvbi9zcmMvaGVscGVycy9Db2xsYWJvcmF0aW9uTWFwcGFibGVQb3NpdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tY29sbGFib3JhdGlvbkAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2XzJsNXhxNW92d3Rzb3I1NHdmMnpldGliemZ1L25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi1jb2xsYWJvcmF0aW9uL3NyYy9oZWxwZXJzL2lzQ2hhbmdlT3JpZ2luLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi1jb2xsYWJvcmF0aW9uQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjZfMmw1eHE1b3Z3dHNvcjU0d2YyemV0aWJ6ZnUvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWNvbGxhYm9yYXRpb24vc3JjL2hlbHBlcnMveVJlbGF0aXZlUG9zaXRpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLWNvbGxhYm9yYXRpb25AMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNl8ybDV4cTVvdnd0c29yNTR3ZjJ6ZXRpYnpmdS9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tY29sbGFib3JhdGlvbi9zcmMvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLXBsYWNlaG9sZGVyQDMuMjYuMF9AdGlwdGFwK2V4dGVuc2lvbnNAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wXy9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tcGxhY2Vob2xkZXIvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10YXNrLWxpc3RAMy4yNi4wX0B0aXB0YXArZXh0ZW5zaW9uLWxpc3RAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtfc3dibnNhenlmYmx2Y3prNmgzc3hxeXdsaWEvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRhc2stbGlzdC9zcmMvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLXRhc2staXRlbUAzLjI2LjBfQHRpcHRhcCtleHRlbnNpb24tbGlzdEAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK19kaDZ5NGlqNWxnZXVpaGc3ZWZqcjVwNTdxaS9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tdGFzay1pdGVtL3NyYy9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHJvc2VtaXJyb3ItdGFibGVzQDEuOC41L25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci10YWJsZXMvc3JjL3RhYmxlbWFwLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci10YWJsZXNAMS44LjUvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXRhYmxlcy9zcmMvc2NoZW1hLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci10YWJsZXNAMS44LjUvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXRhYmxlcy9zcmMvdXRpbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHJvc2VtaXJyb3ItdGFibGVzQDEuOC41L25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci10YWJsZXMvc3JjL2NlbGxzZWxlY3Rpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3Byb3NlbWlycm9yLXRhYmxlc0AxLjguNS9ub2RlX21vZHVsZXMvcHJvc2VtaXJyb3ItdGFibGVzL3NyYy9maXh0YWJsZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3Byb3NlbWlycm9yLXRhYmxlc0AxLjguNS9ub2RlX21vZHVsZXMvcHJvc2VtaXJyb3ItdGFibGVzL3NyYy91dGlscy9jb252ZXJ0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci10YWJsZXNAMS44LjUvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXRhYmxlcy9zcmMvdXRpbHMvbW92ZS1yb3ctaW4tYXJyYXktb2Ytcm93cy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHJvc2VtaXJyb3ItdGFibGVzQDEuOC41L25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci10YWJsZXMvc3JjL3V0aWxzL3F1ZXJ5LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci10YWJsZXNAMS44LjUvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXRhYmxlcy9zcmMvdXRpbHMvZ2V0LWNlbGxzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci10YWJsZXNAMS44LjUvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXRhYmxlcy9zcmMvdXRpbHMvc2VsZWN0aW9uLXJhbmdlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci10YWJsZXNAMS44LjUvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXRhYmxlcy9zcmMvdXRpbHMvdHJhbnNwb3NlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci10YWJsZXNAMS44LjUvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXRhYmxlcy9zcmMvdXRpbHMvbW92ZS1jb2x1bW4udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3Byb3NlbWlycm9yLXRhYmxlc0AxLjguNS9ub2RlX21vZHVsZXMvcHJvc2VtaXJyb3ItdGFibGVzL3NyYy91dGlscy9tb3ZlLXJvdy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHJvc2VtaXJyb3ItdGFibGVzQDEuOC41L25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci10YWJsZXMvc3JjL2NvbW1hbmRzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci10YWJsZXNAMS44LjUvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXRhYmxlcy9zcmMvY29weXBhc3RlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wcm9zZW1pcnJvci10YWJsZXNAMS44LjUvbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXRhYmxlcy9zcmMvaW5wdXQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3Byb3NlbWlycm9yLXRhYmxlc0AxLjguNS9ub2RlX21vZHVsZXMvcHJvc2VtaXJyb3ItdGFibGVzL3NyYy90YWJsZXZpZXcudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3Byb3NlbWlycm9yLXRhYmxlc0AxLjguNS9ub2RlX21vZHVsZXMvcHJvc2VtaXJyb3ItdGFibGVzL3NyYy9jb2x1bW5yZXNpemluZy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHJvc2VtaXJyb3ItdGFibGVzQDEuOC41L25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci10YWJsZXMvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlL3NyYy9jZWxsL3RhYmxlLWNlbGwudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLXRhYmxlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tdGFibGUvc3JjL3V0aWxpdGllcy9wYXJzZUFsaWduLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlL3NyYy9oZWFkZXIvdGFibGUtaGVhZGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlL3NyYy9raXQvaW5kZXgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLXRhYmxlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tdGFibGUvc3JjL3Jvdy90YWJsZS1yb3cudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLXRhYmxlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tdGFibGUvc3JjL3RhYmxlL3RhYmxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlL3NyYy90YWJsZS91dGlsaXRpZXMvY29sU3R5bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLXRhYmxlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tdGFibGUvc3JjL3RhYmxlL1RhYmxlVmlldy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tdGFibGVAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi10YWJsZS9zcmMvdGFibGUvdXRpbGl0aWVzL2NyZWF0ZUNvbEdyb3VwLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlL3NyYy90YWJsZS91dGlsaXRpZXMvY3JlYXRlQ2VsbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tdGFibGVAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcCtwbUAzLjI2LjBfX0B0aXB0YXArcG1AMy4yNi4wL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi10YWJsZS9zcmMvdGFibGUvdXRpbGl0aWVzL2dldFRhYmxlTm9kZVR5cGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlL3NyYy90YWJsZS91dGlsaXRpZXMvY3JlYXRlVGFibGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLXRhYmxlQDMuMjYuMF9AdGlwdGFwK2NvcmVAMy4yNi4wX0B0aXB0YXArcG1AMy4yNi4wX19AdGlwdGFwK3BtQDMuMjYuMC9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tdGFibGUvc3JjL3RhYmxlL3V0aWxpdGllcy9kZWxldGVUYWJsZVdoZW5BbGxDZWxsc1NlbGVjdGVkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlL3NyYy90YWJsZS91dGlsaXRpZXMvaXNDZWxsU2VsZWN0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFwK3BtQDMuMjYuMF9fQHRpcHRhcCtwbUAzLjI2LjAvbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlL3NyYy90YWJsZS91dGlsaXRpZXMvbWFya2Rvd24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL0B0aXB0YXArZXh0ZW5zaW9uLXRhYmxlLXJvd0AzLjI2LjBfQHRpcHRhcCtleHRlbnNpb24tdGFibGVAMy4yNi4wX0B0aXB0YXArY29yZUAzLjI2LjBfQHRpcHRhcF95ZWl1dmdiNG9mdDV3bnRsZTY2dXJsam5xdS9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tdGFibGUtcm93L3NyYy9pbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vQHRpcHRhcCtleHRlbnNpb24tdGFibGUtaGVhZGVyQDMuMjYuMF9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwX2U1azY3bG5pZTZndWg0ZzdvMjRuMmpzb2xhL25vZGVfbW9kdWxlcy9AdGlwdGFwL2V4dGVuc2lvbi10YWJsZS1oZWFkZXIvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZS1jZWxsQDMuMjYuMF9AdGlwdGFwK2V4dGVuc2lvbi10YWJsZUAzLjI2LjBfQHRpcHRhcCtjb3JlQDMuMjYuMF9AdGlwdGFfejVkNzdjbGFtbTc2Nnd5a2s2dnJqdG5pdm0vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlLWNlbGwvc3JjL2luZGV4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9tYXJrZWRAMTguMC41L25vZGVfbW9kdWxlcy9tYXJrZWQvc3JjL2RlZmF1bHRzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9tYXJrZWRAMTguMC41L25vZGVfbW9kdWxlcy9tYXJrZWQvc3JjL3J1bGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9tYXJrZWRAMTguMC41L25vZGVfbW9kdWxlcy9tYXJrZWQvc3JjL2hlbHBlcnMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL21hcmtlZEAxOC4wLjUvbm9kZV9tb2R1bGVzL21hcmtlZC9zcmMvVG9rZW5pemVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9tYXJrZWRAMTguMC41L25vZGVfbW9kdWxlcy9tYXJrZWQvc3JjL0xleGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9tYXJrZWRAMTguMC41L25vZGVfbW9kdWxlcy9tYXJrZWQvc3JjL1JlbmRlcmVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9tYXJrZWRAMTguMC41L25vZGVfbW9kdWxlcy9tYXJrZWQvc3JjL1RleHRSZW5kZXJlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vbWFya2VkQDE4LjAuNS9ub2RlX21vZHVsZXMvbWFya2VkL3NyYy9QYXJzZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL21hcmtlZEAxOC4wLjUvbm9kZV9tb2R1bGVzL21hcmtlZC9zcmMvSG9va3MudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL21hcmtlZEAxOC4wLjUvbm9kZV9tb2R1bGVzL21hcmtlZC9zcmMvSW5zdGFuY2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL21hcmtlZEAxOC4wLjUvbm9kZV9tb2R1bGVzL21hcmtlZC9zcmMvbWFya2VkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS90dXJuZG93bkA3LjIuNC9ub2RlX21vZHVsZXMvdHVybmRvd24vbGliL3R1cm5kb3duLmJyb3dzZXIuZXMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3R1cm5kb3duLXBsdWdpbi1nZm1AMS4wLjIvbm9kZV9tb2R1bGVzL3R1cm5kb3duLXBsdWdpbi1nZm0vbGliL3R1cm5kb3duLXBsdWdpbi1nZm0uZXMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC9icm9hZGNhc3RjaGFubmVsLmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS95LXByb3RvY29sc0AxLjAuN195anNAMTMuNi4zMS9ub2RlX21vZHVsZXMveS1wcm90b2NvbHMvc3luYy5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0veS1wcm90b2NvbHNAMS4wLjdfeWpzQDEzLjYuMzEvbm9kZV9tb2R1bGVzL3ktcHJvdG9jb2xzL2F1dGguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL2xpYjBAMC4yLjExNy9ub2RlX21vZHVsZXMvbGliMC91cmwuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3ktd2Vic29ja2V0QDMuMC4wX3lqc0AxMy42LjMxL25vZGVfbW9kdWxlcy95LXdlYnNvY2tldC9zcmMveS13ZWJzb2NrZXQuanMiLCAic3JjL2FwaS1jbGllbnQudHMiLCAic3JjL21ldGFkYXRhLnRzIiwgInNyYy9zeW5jLnRzIiwgInNyYy9jaGVja3N1bS50cyIsICJzcmMvcnVubmVyLnRzIiwgInNyYy9pbXBvcnQtdmF1bHQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7XG4gIEFwcCxcbiAgSXRlbVZpZXcsXG4gIE1vZGFsLFxuICBOb3RpY2UsXG4gIFBsdWdpbixcbiAgUGx1Z2luU2V0dGluZ1RhYixcbiAgU2V0dGluZyxcbiAgVEZpbGUsXG4gIFdvcmtzcGFjZUxlYWYsXG4gIG5vcm1hbGl6ZVBhdGgsXG59IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHsgRWRpdG9yIH0gZnJvbSBcIkB0aXB0YXAvY29yZVwiO1xuaW1wb3J0IFN0YXJ0ZXJLaXQgZnJvbSBcIkB0aXB0YXAvc3RhcnRlci1raXRcIjtcbmltcG9ydCBDb2xsYWJvcmF0aW9uIGZyb20gXCJAdGlwdGFwL2V4dGVuc2lvbi1jb2xsYWJvcmF0aW9uXCI7XG5pbXBvcnQgTGluayBmcm9tIFwiQHRpcHRhcC9leHRlbnNpb24tbGlua1wiO1xuaW1wb3J0IFBsYWNlaG9sZGVyIGZyb20gXCJAdGlwdGFwL2V4dGVuc2lvbi1wbGFjZWhvbGRlclwiO1xuaW1wb3J0IFRhc2tMaXN0IGZyb20gXCJAdGlwdGFwL2V4dGVuc2lvbi10YXNrLWxpc3RcIjtcbmltcG9ydCBUYXNrSXRlbSBmcm9tIFwiQHRpcHRhcC9leHRlbnNpb24tdGFzay1pdGVtXCI7XG5pbXBvcnQgeyBUYWJsZSB9IGZyb20gXCJAdGlwdGFwL2V4dGVuc2lvbi10YWJsZVwiO1xuaW1wb3J0IFRhYmxlUm93IGZyb20gXCJAdGlwdGFwL2V4dGVuc2lvbi10YWJsZS1yb3dcIjtcbmltcG9ydCBUYWJsZUhlYWRlciBmcm9tIFwiQHRpcHRhcC9leHRlbnNpb24tdGFibGUtaGVhZGVyXCI7XG5pbXBvcnQgVGFibGVDZWxsIGZyb20gXCJAdGlwdGFwL2V4dGVuc2lvbi10YWJsZS1jZWxsXCI7XG5pbXBvcnQgeyBtYXJrZWQgfSBmcm9tIFwibWFya2VkXCI7XG5pbXBvcnQgVHVybmRvd25TZXJ2aWNlIGZyb20gXCJ0dXJuZG93blwiO1xuaW1wb3J0IHsgZ2ZtIH0gZnJvbSBcInR1cm5kb3duLXBsdWdpbi1nZm1cIjtcbmltcG9ydCAqIGFzIFkgZnJvbSBcInlqc1wiO1xuaW1wb3J0IHsgV2Vic29ja2V0UHJvdmlkZXIgfSBmcm9tIFwieS13ZWJzb2NrZXRcIjtcbmltcG9ydCB7IFBhZ2VkZW5BcGlDbGllbnQsIFBhZ2VkZW5BcGlFcnJvciB9IGZyb20gXCIuL2FwaS1jbGllbnRcIjtcbmltcG9ydCB7IFNlcnZlck1ldGFTdG9yZSB9IGZyb20gXCIuL21ldGFkYXRhXCI7XG5pbXBvcnQge1xuICBjb25mbGljdFNpYmxpbmdQYXRoLFxuICBkb3dubG9hZERvY3VtZW50LFxuICBwdXNoT3JDcmVhdGVMb2NhbERvY3VtZW50LFxuICBydW5CYWNrZ3JvdW5kU3luY1Bhc3MsXG4gIHR5cGUgU3luY1Bhc3NTdW1tYXJ5LFxuICB0eXBlIFZhdWx0TGlrZSxcbn0gZnJvbSBcIi4vc3luY1wiO1xuaW1wb3J0IHsgY3JlYXRlRGVib3VuY2VyLCBjcmVhdGVTeW5jUnVubmVyIH0gZnJvbSBcIi4vcnVubmVyXCI7XG5pbXBvcnQgeyBjYW5vbmljYWxpemUsIGNoZWNrc3VtIH0gZnJvbSBcIi4vY2hlY2tzdW1cIjtcbmltcG9ydCB7IGJ1aWxkVmF1bHRJbXBvcnRQcmV2aWV3LCBpbXBvcnRWYXVsdFRvUGFnZWRlbiwgdHlwZSBWYXVsdEltcG9ydEZpbGUsIHR5cGUgVmF1bHRJbXBvcnRSZXBvcnQgfSBmcm9tIFwiLi9pbXBvcnQtdmF1bHRcIjtcbmltcG9ydCB0eXBlIHsgRGV2aWNlU3RhcnRSZXNwb25zZSwgTWVSZXNwb25zZSwgUGFnZWRlblNldHRpbmdzLCBSZW1vdGVEb2N1bWVudCwgUmVtb3RlVHJlZSwgU2VhcmNoUmVzdWx0IH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuY29uc3QgUFVTSF9ERUJPVU5DRV9NUyA9IDIwMDA7XG5jb25zdCBSRU1PVEVfV1JJVEVfR1VBUkRfTVMgPSAxNTAwO1xuY29uc3QgTElWRV9WSUVXX1RZUEUgPSBcInBhZ2VkZW4tbGl2ZS1kb2N1bWVudFwiO1xuXG5jb25zdCB0dXJuZG93biA9IG5ldyBUdXJuZG93blNlcnZpY2Uoe1xuICBidWxsZXRMaXN0TWFya2VyOiBcIi1cIixcbiAgY29kZUJsb2NrU3R5bGU6IFwiZmVuY2VkXCIsXG4gIGhlYWRpbmdTdHlsZTogXCJhdHhcIixcbn0pO1xudHVybmRvd24udXNlKGdmbSk7XG5cbmNvbnN0IERFRkFVTFRfU0VUVElOR1M6IFBhZ2VkZW5TZXR0aW5ncyA9IHtcbiAgc2VydmVyVXJsOiBcImh0dHBzOi8vZ28ucGFnZWRlbi5hcHBcIixcbiAgdG9rZW46IFwiXCIsXG4gIHdvcmtzcGFjZUlkOiBcIlwiLFxuICByZW1vdGVEb2NzRm9sZGVyOiBcIlJlbW90ZSBEb2NzXCIsXG4gIGF1dG9TeW5jRW5hYmxlZDogZmFsc2UsXG4gIGF1dG9TeW5jSW50ZXJ2YWxNaW51dGVzOiA1LFxuICB1c2VyTmFtZTogXCJcIixcbiAgd29ya3NwYWNlTmFtZTogXCJcIixcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhZ2VkZW5QbHVnaW4gZXh0ZW5kcyBQbHVnaW4ge1xuICBzZXR0aW5nczogUGFnZWRlblNldHRpbmdzID0gREVGQVVMVF9TRVRUSU5HUztcbiAgcHJpdmF0ZSBtZXRhU3RvcmUhOiBTZXJ2ZXJNZXRhU3RvcmU7XG4gIHByaXZhdGUgc3RhdHVzQmFyRWw/OiBIVE1MRWxlbWVudDtcbiAgcHJpdmF0ZSBzeW5jUnVubmVyITogUmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlU3luY1J1bm5lcj47XG4gIHByaXZhdGUgcHVzaERlYm91bmNlciE6IFJldHVyblR5cGU8dHlwZW9mIGNyZWF0ZURlYm91bmNlcj47XG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwbHlpbmdSZW1vdGVXcml0ZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgcHJpdmF0ZSBzeW5jSW50ZXJ2YWxJZD86IG51bWJlcjtcbiAgcHJpdmF0ZSBsYXN0U3VtbWFyeT86IFN5bmNQYXNzU3VtbWFyeTtcblxuICBhc3luYyBvbmxvYWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5sb2FkU2V0dGluZ3MoKTtcbiAgICB0aGlzLm1ldGFTdG9yZSA9IG5ldyBTZXJ2ZXJNZXRhU3RvcmUodGhpcy5hcHAudmF1bHQuYWRhcHRlciwgdGhpcy5wbHVnaW5EaXIoKSk7XG5cbiAgICB0aGlzLmFkZFNldHRpbmdUYWIobmV3IFBhZ2VkZW5TZXR0aW5nVGFiKHRoaXMuYXBwLCB0aGlzKSk7XG4gICAgdGhpcy5yZWdpc3RlclZpZXcoTElWRV9WSUVXX1RZUEUsIChsZWFmKSA9PiBuZXcgTGl2ZURvY3VtZW50VmlldyhsZWFmLCB0aGlzKSk7XG5cbiAgICB0aGlzLmFkZENvbW1hbmQoe1xuICAgICAgaWQ6IFwidmFsaWRhdGUtY29ubmVjdGlvblwiLFxuICAgICAgbmFtZTogXCJWYWxpZGF0ZSBjb25uZWN0aW9uXCIsXG4gICAgICBjYWxsYmFjazogKCkgPT4gdm9pZCB0aGlzLnZhbGlkYXRlQ29ubmVjdGlvbigpLFxuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRDb21tYW5kKHtcbiAgICAgIGlkOiBcImJyb3dzZS1yZW1vdGUtZG9jdW1lbnRzXCIsXG4gICAgICBuYW1lOiBcIkJyb3dzZSByZW1vdGUgZG9jdW1lbnRzXCIsXG4gICAgICBjYWxsYmFjazogKCkgPT4gdm9pZCB0aGlzLm9wZW5SZW1vdGVCcm93c2VyKCksXG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZENvbW1hbmQoe1xuICAgICAgaWQ6IFwic2VhcmNoLXJlbW90ZS1kb2N1bWVudHNcIixcbiAgICAgIG5hbWU6IFwiU2VhcmNoIHJlbW90ZSBkb2N1bWVudHNcIixcbiAgICAgIGNhbGxiYWNrOiAoKSA9PiB2b2lkIHRoaXMub3BlblJlbW90ZVNlYXJjaCgpLFxuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRDb21tYW5kKHtcbiAgICAgIGlkOiBcImltcG9ydC12YXVsdFwiLFxuICAgICAgbmFtZTogXCJJbXBvcnQgdGhpcyB2YXVsdCB0byBQYWdlZGVuXCIsXG4gICAgICBjYWxsYmFjazogKCkgPT4gdm9pZCB0aGlzLm9wZW5WYXVsdEltcG9ydCgpLFxuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRDb21tYW5kKHtcbiAgICAgIGlkOiBcIm9wZW4tbGl2ZS1kb2N1bWVudFwiLFxuICAgICAgbmFtZTogXCJPcGVuIGxpdmUgZG9jdW1lbnRcIixcbiAgICAgIGNhbGxiYWNrOiAoKSA9PiB2b2lkIHRoaXMub3BlbkxpdmVEb2N1bWVudFBpY2tlcigpLFxuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRDb21tYW5kKHtcbiAgICAgIGlkOiBcImRldmljZS1jb2RlLWxvZ2luXCIsXG4gICAgICBuYW1lOiBcIkxvZyBpbiB3aXRoIGRldmljZSBjb2RlXCIsXG4gICAgICBjYWxsYmFjazogKCkgPT4gdm9pZCB0aGlzLnN0YXJ0RGV2aWNlTG9naW4oKSxcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XG4gICAgICBpZDogXCJwdXNoLWFjdGl2ZS1kb2N1bWVudFwiLFxuICAgICAgbmFtZTogXCJQdXNoIGFjdGl2ZSBkb2N1bWVudFwiLFxuICAgICAgY2hlY2tDYWxsYmFjazogKGNoZWNraW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlRmlsZSgpO1xuICAgICAgICBjb25zdCBjYW5QdXNoID0gZmlsZSBpbnN0YW5jZW9mIFRGaWxlICYmIGZpbGUuZXh0ZW5zaW9uID09PSBcIm1kXCI7XG4gICAgICAgIGlmIChjaGVja2luZykgcmV0dXJuIGNhblB1c2g7XG4gICAgICAgIGlmIChmaWxlKSB2b2lkIHRoaXMucHVzaEZpbGUoZmlsZSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XG4gICAgICBpZDogXCJkb3dubG9hZC1mb2xkZXJcIixcbiAgICAgIG5hbWU6IFwiRG93bmxvYWQgYSBQYWdlZGVuIGZvbGRlclwiLFxuICAgICAgY2FsbGJhY2s6ICgpID0+IHZvaWQgdGhpcy5vcGVuRm9sZGVyRG93bmxvYWQoKSxcbiAgICB9KTtcblxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XG4gICAgICBpZDogXCJkb3dubG9hZC1hbGwtZG9jdW1lbnRzXCIsXG4gICAgICBuYW1lOiBcIkRvd25sb2FkIGFsbCBQYWdlZGVuIGRvY3VtZW50c1wiLFxuICAgICAgY2FsbGJhY2s6ICgpID0+IHZvaWQgdGhpcy5kb3dubG9hZEFsbERvY3VtZW50cygpLFxuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRDb21tYW5kKHtcbiAgICAgIGlkOiBcInJlc29sdmUtY29uZmxpY3RcIixcbiAgICAgIG5hbWU6IFwiUmVzb2x2ZSBjb25mbGljdCBmb3IgdGhpcyBub3RlXCIsXG4gICAgICBjaGVja0NhbGxiYWNrOiAoY2hlY2tpbmcpID0+IHtcbiAgICAgICAgY29uc3QgZmlsZSA9IHRoaXMuYXBwLndvcmtzcGFjZS5nZXRBY3RpdmVGaWxlKCk7XG4gICAgICAgIGNvbnN0IGNhblJlc29sdmUgPSBmaWxlIGluc3RhbmNlb2YgVEZpbGUgJiYgZmlsZS5leHRlbnNpb24gPT09IFwibWRcIiAmJiAhZmlsZS5wYXRoLmVuZHNXaXRoKFwiLmNvbmZsaWN0Lm1kXCIpO1xuICAgICAgICBpZiAoY2hlY2tpbmcpIHJldHVybiBjYW5SZXNvbHZlO1xuICAgICAgICBpZiAoZmlsZSkgdm9pZCB0aGlzLnJlc29sdmVDb25mbGljdChmaWxlKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gQmFja2dyb3VuZCBzeW5jIHdpcmluZy5cbiAgICB0aGlzLnN0YXR1c0JhckVsID0gdGhpcy5hZGRTdGF0dXNCYXJJdGVtKCk7XG4gICAgdGhpcy5zeW5jUnVubmVyID0gY3JlYXRlU3luY1J1bm5lcigoKSA9PiB0aGlzLnJ1blN5bmNQYXNzKCkpO1xuICAgIHRoaXMucHVzaERlYm91bmNlciA9IGNyZWF0ZURlYm91bmNlcihQVVNIX0RFQk9VTkNFX01TKTtcblxuICAgIHRoaXMuYWRkQ29tbWFuZCh7XG4gICAgICBpZDogXCJzeW5jLW5vd1wiLFxuICAgICAgbmFtZTogXCJTeW5jIG5vd1wiLFxuICAgICAgY2FsbGJhY2s6ICgpID0+IHZvaWQgdGhpcy5zeW5jUnVubmVyLnJ1bigpLFxuICAgIH0pO1xuXG4gICAgdGhpcy5yZWdpc3RlckV2ZW50KHRoaXMuYXBwLnZhdWx0Lm9uKFwibW9kaWZ5XCIsIChmaWxlKSA9PiB0aGlzLm9uVmF1bHRGaWxlQ2hhbmdlZChmaWxlKSkpO1xuICAgIHRoaXMucmVnaXN0ZXJFdmVudCh0aGlzLmFwcC52YXVsdC5vbihcImNyZWF0ZVwiLCAoZmlsZSkgPT4gdGhpcy5vblZhdWx0RmlsZUNoYW5nZWQoZmlsZSkpKTtcbiAgICB0aGlzLmFwcC53b3Jrc3BhY2Uub25MYXlvdXRSZWFkeSgoKSA9PiB0aGlzLnN0YXJ0QXV0b1N5bmMoKSk7XG4gIH1cblxuICBvbnVubG9hZCgpOiB2b2lkIHtcbiAgICB0aGlzLnN0b3BBdXRvU3luYygpO1xuICB9XG5cbiAgLy8gU3RhcnQgKG9yIHJlc3RhcnQpIHRoZSBhdXRvLXN5bmMgaW50ZXJ2YWwuIFNhZmUgdG8gY2FsbCByZXBlYXRlZGx5IFx1MjAxNCBlLmcuIHdoZW4gc2V0dGluZ3MgY2hhbmdlLlxuICBzdGFydEF1dG9TeW5jKCk6IHZvaWQge1xuICAgIHRoaXMuc3RvcEF1dG9TeW5jKCk7XG4gICAgaWYgKCF0aGlzLnNldHRpbmdzLmF1dG9TeW5jRW5hYmxlZCkge1xuICAgICAgdGhpcy5zZXRTdGF0dXNJZGxlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG1pbnV0ZXMgPSBNYXRoLm1heCgxLCBNYXRoLmZsb29yKE51bWJlcih0aGlzLnNldHRpbmdzLmF1dG9TeW5jSW50ZXJ2YWxNaW51dGVzKSkgfHwgREVGQVVMVF9TRVRUSU5HUy5hdXRvU3luY0ludGVydmFsTWludXRlcyk7XG4gICAgdGhpcy5zeW5jSW50ZXJ2YWxJZCA9IHdpbmRvdy5zZXRJbnRlcnZhbCgoKSA9PiB2b2lkIHRoaXMuc3luY1J1bm5lci5ydW4oKSwgbWludXRlcyAqIDYwXzAwMCk7XG4gICAgdGhpcy5yZWdpc3RlckludGVydmFsKHRoaXMuc3luY0ludGVydmFsSWQpO1xuICAgIGlmICh0aGlzLmlzQ29uZmlndXJlZCgpKSB2b2lkIHRoaXMuc3luY1J1bm5lci5ydW4oKTtcbiAgICBlbHNlIHRoaXMuc2V0U3RhdHVzKFwiUGFnZWRlbjogbm90IGNvbm5lY3RlZFwiKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RvcEF1dG9TeW5jKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnN5bmNJbnRlcnZhbElkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMuc3luY0ludGVydmFsSWQpO1xuICAgICAgdGhpcy5zeW5jSW50ZXJ2YWxJZCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdGhpcy5wdXNoRGVib3VuY2VyPy5jYW5jZWxBbGwoKTtcbiAgfVxuXG4gIGlzQ29uZmlndXJlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gQm9vbGVhbih0aGlzLnNldHRpbmdzLnNlcnZlclVybC50cmltKCkgJiYgdGhpcy5zZXR0aW5ncy50b2tlbi50cmltKCkgJiYgdGhpcy5zZXR0aW5ncy53b3Jrc3BhY2VJZC50cmltKCkpO1xuICB9XG5cbiAgLy8gT25lIGZ1bGwgcHVsbC9wdXNoIHJlY29uY2lsaWF0aW9uIHBhc3MuIFNlcmlhbGlzZWQgYnkgc3luY1J1bm5lcjsgbmV2ZXIgdGhyb3dzIGludG8gT2JzaWRpYW4uXG4gIHByaXZhdGUgYXN5bmMgcnVuU3luY1Bhc3MoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLnNldHRpbmdzLmF1dG9TeW5jRW5hYmxlZCB8fCAhdGhpcy5pc0NvbmZpZ3VyZWQoKSkgcmV0dXJuO1xuICAgIHRoaXMuc2V0U3RhdHVzKFwiUGFnZWRlbjogc3luY2luZ1xcdTIwMjZcIik7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN1bW1hcnkgPSBhd2FpdCBydW5CYWNrZ3JvdW5kU3luY1Bhc3ModGhpcy5iYWNrZ3JvdW5kU3luY0RlcHMoKSk7XG4gICAgICB0aGlzLmxhc3RTdW1tYXJ5ID0gc3VtbWFyeTtcbiAgICAgIHRoaXMucmVuZGVyU3VtbWFyeShzdW1tYXJ5KTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIE5ldHdvcmsvdG9wLWxldmVsIGZhaWx1cmU6IHBhdXNlIHF1aWV0bHksIHJldHJ5IG5leHQgdGljay4gTm8gbm9pc3kgcG9wdXBzLlxuICAgICAgdGhpcy5zZXRTdGF0dXMoXCJQYWdlZGVuOiBvZmZsaW5lXCIpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25WYXVsdEZpbGVDaGFuZ2VkKGZpbGU6IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2V0dGluZ3MuYXV0b1N5bmNFbmFibGVkIHx8ICF0aGlzLmlzQ29uZmlndXJlZCgpKSByZXR1cm47XG4gICAgaWYgKCEoZmlsZSBpbnN0YW5jZW9mIFRGaWxlKSB8fCBmaWxlLmV4dGVuc2lvbiAhPT0gXCJtZFwiKSByZXR1cm47XG4gICAgY29uc3QgcGF0aCA9IGZpbGUucGF0aDtcbiAgICBpZiAocGF0aC5lbmRzV2l0aChcIi5jb25mbGljdC5tZFwiKSkgcmV0dXJuO1xuICAgIGlmICh0aGlzLmFwcGx5aW5nUmVtb3RlV3JpdGVzLmhhcyhwYXRoKSkgcmV0dXJuOyAvLyBvdXIgb3duIHB1bGwgd3JpdGUgXHUyMDE0IGRvbid0IGVjaG8gaXQgYmFja1xuICAgIHRoaXMucHVzaERlYm91bmNlci5zY2hlZHVsZShwYXRoLCAoKSA9PiB2b2lkIHRoaXMuZGVib3VuY2VkUHVzaChwYXRoKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRlYm91bmNlZFB1c2gocGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gRG9uJ3QgcHVzaCBkdXJpbmcgYSBmdWxsIHBhc3M7IHJlc2NoZWR1bGUgc28gdGhlIGVkaXQgaXMgbm90IGRyb3BwZWQuXG4gICAgaWYgKHRoaXMuc3luY1J1bm5lci5pc1J1bm5pbmcoKSkge1xuICAgICAgdGhpcy5wdXNoRGVib3VuY2VyLnNjaGVkdWxlKHBhdGgsICgpID0+IHZvaWQgdGhpcy5kZWJvdW5jZWRQdXNoKHBhdGgpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG1ldGEgPSBhd2FpdCB0aGlzLm1ldGFTdG9yZS5nZXRCeUxvY2FsUGF0aChwYXRoKTtcbiAgICAgIGlmIChtZXRhPy5wZXJtaXNzaW9uID09PSBcInZpZXdlclwiKSByZXR1cm47XG4gICAgICBpZiAoIW1ldGEgJiYgIWlzVW5kZXJSZW1vdGVEb2NzRm9sZGVyKHRoaXMuc2V0dGluZ3MucmVtb3RlRG9jc0ZvbGRlciwgcGF0aCkpIHJldHVybjtcbiAgICAgIC8vIERvbid0IGF1dG8tcHVzaCB3aGlsZSBhbiB1bnJlc29sdmVkIGNvbmZsaWN0IGNvcHkgZXhpc3RzIFx1MjAxNCB3YWl0IGZvciB0aGUgdXNlciB0byByZXNvbHZlIGl0LlxuICAgICAgaWYgKGF3YWl0IHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIuZXhpc3RzKGNvbmZsaWN0U2libGluZ1BhdGgocGF0aCkpKSByZXR1cm47XG4gICAgICBjb25zdCBsb2NhbENhbm9uaWNhbCA9IGNhbm9uaWNhbGl6ZShhd2FpdCB0aGlzLmFwcC52YXVsdC5hZGFwdGVyLnJlYWQocGF0aCkpO1xuICAgICAgLy8gQ2hlY2tzdW0gZ2F0ZTogaWRlbnRpY2FsIHRvIHRoZSBsYXN0LXN5bmNlZCBjb250ZW50IG1lYW5zIGEgcmVtb3RlIHdyaXRlIG9yIGEgbm8tb3Agc2F2ZSxcbiAgICAgIC8vIG5vdCBhIHJlYWwgZWRpdCBcdTIwMTQgc2tpcCB0byBhdm9pZCBwdWxsL3B1c2ggcGluZy1wb25nIChjb3ZlcnMgZGVsYXllZCBtb2RpZnkgZXZlbnRzIHRvbykuXG4gICAgICBpZiAobWV0YSAmJiAoYXdhaXQgY2hlY2tzdW0obG9jYWxDYW5vbmljYWwpKSA9PT0gbWV0YS5jaGVja3N1bSkgcmV0dXJuO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHVzaE9yQ3JlYXRlTG9jYWxEb2N1bWVudCh0aGlzLmNyZWF0ZVN5bmNEZXBzKCksIHBhdGgpO1xuICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiY29uZmxpY3RcIikgdGhpcy5zZXRTdGF0dXMoXCJQYWdlZGVuOiBjb25mbGljdFwiKTtcbiAgICAgIGVsc2UgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwicHVzaGVkXCIgfHwgcmVzdWx0LnN0YXR1cyA9PT0gXCJjcmVhdGVkXCIpIHRoaXMuc2V0U3RhdHVzSWRsZSgpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdGhpcy5zZXRTdGF0dXMoXCJQYWdlZGVuOiBlcnJvclwiKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGJhY2tncm91bmRTeW5jRGVwcygpIHtcbiAgICBjb25zdCBiYXNlID0gdGhpcy5zeW5jRGVwcygpO1xuICAgIHJldHVybiB7XG4gICAgICAuLi5iYXNlLFxuICAgICAgdmF1bHQ6IHRoaXMuZ3VhcmRlZFZhdWx0KGJhc2UudmF1bHQpLFxuICAgICAgd29ya3NwYWNlSWQ6IHRoaXMuc2V0dGluZ3Mud29ya3NwYWNlSWQsXG4gICAgICBsb2NhbE1hcmtkb3duUGF0aHM6IGFzeW5jICgpID0+XG4gICAgICAgIHRoaXMuYXBwLnZhdWx0XG4gICAgICAgICAgLmdldEZpbGVzKClcbiAgICAgICAgICAuZmlsdGVyKChmaWxlKSA9PiBmaWxlLmV4dGVuc2lvbiA9PT0gXCJtZFwiICYmIGlzVW5kZXJSZW1vdGVEb2NzRm9sZGVyKHRoaXMuc2V0dGluZ3MucmVtb3RlRG9jc0ZvbGRlciwgZmlsZS5wYXRoKSlcbiAgICAgICAgICAubWFwKChmaWxlKSA9PiBmaWxlLnBhdGgpLFxuICAgIH07XG4gIH1cblxuICAvLyBXcmFwIHZhdWx0IHdyaXRlcyBzbyBhIGJhY2tncm91bmQgcHVsbCBtYXJrcyB0aGUgcGF0aCBhcyByZW1vdGUtYXBwbGllZDsgdGhlIG1vZGlmeSBoYW5kbGVyXG4gIC8vIHNraXBzIGl0IChiZWx0IHRvIHRoZSBjaGVja3N1bSBnYXRlJ3Mgc3VzcGVuZGVycykuXG4gIHByaXZhdGUgZ3VhcmRlZFZhdWx0KGJhc2U6IFZhdWx0TGlrZSk6IFZhdWx0TGlrZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmJhc2UsXG4gICAgICB3cml0ZTogYXN5bmMgKHBhdGg6IHN0cmluZywgY29udGVudDogc3RyaW5nKSA9PiB7XG4gICAgICAgIHRoaXMuYXBwbHlpbmdSZW1vdGVXcml0ZXMuYWRkKHBhdGgpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGJhc2Uud3JpdGUocGF0aCwgY29udGVudCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoKCkgPT4gdGhpcy5hcHBseWluZ1JlbW90ZVdyaXRlcy5kZWxldGUocGF0aCksIFJFTU9URV9XUklURV9HVUFSRF9NUyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB3cml0ZUJpbmFyeTogYmFzZS53cml0ZUJpbmFyeVxuICAgICAgICA/IGFzeW5jIChwYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IEFycmF5QnVmZmVyKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFwcGx5aW5nUmVtb3RlV3JpdGVzLmFkZChwYXRoKTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGF3YWl0IGJhc2Uud3JpdGVCaW5hcnk/LihwYXRoLCBjb250ZW50KTtcbiAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHRoaXMuYXBwbHlpbmdSZW1vdGVXcml0ZXMuZGVsZXRlKHBhdGgpLCBSRU1PVEVfV1JJVEVfR1VBUkRfTVMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0U3RhdHVzKHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc3RhdHVzQmFyRWw/LnNldFRleHQodGV4dCk7XG4gIH1cblxuICBwcml2YXRlIHNldFN0YXR1c0lkbGUoKTogdm9pZCB7XG4gICAgY29uc3QgcyA9IHRoaXMubGFzdFN1bW1hcnk7XG4gICAgaWYgKHMgJiYgcy5jb25mbGljdHMpIHtcbiAgICAgIHRoaXMuc2V0U3RhdHVzKGBQYWdlZGVuOiAke3MuY29uZmxpY3RzfSBjb25mbGljdCR7cy5jb25mbGljdHMgPT09IDEgPyBcIlwiIDogXCJzXCJ9IFxcdTIwMTQgcnVuIFwiUmVzb2x2ZSBjb25mbGljdFwiIHRvIGZpeGApO1xuICAgIH0gZWxzZSBpZiAocyAmJiAocy5jcmVhdGVkIHx8IHMucHVsbGVkIHx8IHMucHVzaGVkKSkge1xuICAgICAgdGhpcy5zZXRTdGF0dXMoYFBhZ2VkZW46IHN5bmNlZCAoJHtzLmNyZWF0ZWR9IGNyZWF0ZWQsICR7cy5wdXNoZWR9IHNlbnQsICR7cy5wdWxsZWR9IHJlY2VpdmVkKWApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXR1cyhcIlBhZ2VkZW46IHVwIHRvIGRhdGVcIik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJTdW1tYXJ5KHM6IFN5bmNQYXNzU3VtbWFyeSk6IHZvaWQge1xuICAgIGlmIChzLmVycm9ycykgdGhpcy5zZXRTdGF0dXMoXCJQYWdlZGVuOiBzeW5jIGVycm9yIFxcdTIwMTQgd2lsbCByZXRyeVwiKTtcbiAgICBlbHNlIGlmIChzLmNvbmZsaWN0cykgdGhpcy5zZXRTdGF0dXMoYFBhZ2VkZW46ICR7cy5jb25mbGljdHN9IGNvbmZsaWN0JHtzLmNvbmZsaWN0cyA9PT0gMSA/IFwiXCIgOiBcInNcIn0gXFx1MjAxNCBydW4gXCJSZXNvbHZlIGNvbmZsaWN0XCIgdG8gZml4YCk7XG4gICAgZWxzZSB0aGlzLnNldFN0YXR1cyhgUGFnZWRlbjogc3luY2VkICgke3MuY3JlYXRlZH0gY3JlYXRlZCwgJHtzLnB1c2hlZH0gc2VudCwgJHtzLnB1bGxlZH0gcmVjZWl2ZWQpYCk7XG4gIH1cblxuICBhc3luYyBsb2FkU2V0dGluZ3MoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zZXR0aW5ncyA9IHsgLi4uREVGQVVMVF9TRVRUSU5HUywgLi4uKChhd2FpdCB0aGlzLmxvYWREYXRhKCkpIGFzIFBhcnRpYWw8UGFnZWRlblNldHRpbmdzPiB8IG51bGwpIH07XG4gIH1cblxuICBhc3luYyBzYXZlU2V0dGluZ3MoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcbiAgfVxuXG4gIGFwaSgpOiBQYWdlZGVuQXBpQ2xpZW50IHtcbiAgICByZXR1cm4gbmV3IFBhZ2VkZW5BcGlDbGllbnQodGhpcy5zZXR0aW5ncy5zZXJ2ZXJVcmwsIHRoaXMuc2V0dGluZ3MudG9rZW4pO1xuICB9XG5cbiAgbGl2ZUJhc2VVcmwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7dGhpcy5zZXR0aW5ncy5zZXJ2ZXJVcmwucmVwbGFjZSgvXFwvKyQvLCBcIlwiKX0vYXBpL2xpdmVgO1xuICB9XG5cbiAgcHVibGljQXBpKCk6IFBhZ2VkZW5BcGlDbGllbnQge1xuICAgIHJldHVybiBuZXcgUGFnZWRlbkFwaUNsaWVudCh0aGlzLnNldHRpbmdzLnNlcnZlclVybCwgXCJcIik7XG4gIH1cblxuICBhc3luYyB2YWxpZGF0ZUNvbm5lY3Rpb24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMucmVxdWlyZUNvbmZpZ3VyZWQoKTtcbiAgICAgIGF3YWl0IHRoaXMuYXBpKCkudmFsaWRhdGUoKTtcbiAgICAgIG5ldyBOb3RpY2UoXCJQYWdlZGVuIGNvbm5lY3Rpb24gaXMgdmFsaWQuXCIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBuZXcgTm90aWNlKGVycm9yTWVzc2FnZShlcnJvcikpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIG9wZW5SZW1vdGVCcm93c2VyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnJlcXVpcmVDb25maWd1cmVkKCk7XG4gICAgICBjb25zdCB0cmVlID0gYXdhaXQgdGhpcy5hcGkoKS50cmVlKHRoaXMuc2V0dGluZ3Mud29ya3NwYWNlSWQpO1xuICAgICAgbmV3IFJlbW90ZURvY3VtZW50TW9kYWwodGhpcy5hcHAsIHRyZWUsIChkb2MpID0+IHZvaWQgdGhpcy5kb3dubG9hZChkb2MpKS5vcGVuKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIG5ldyBOb3RpY2UoZXJyb3JNZXNzYWdlKGVycm9yKSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgb3BlblJlbW90ZVNlYXJjaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5yZXF1aXJlQ29uZmlndXJlZCgpO1xuICAgICAgbmV3IFJlbW90ZVNlYXJjaE1vZGFsKHRoaXMuYXBwLCB0aGlzKS5vcGVuKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIG5ldyBOb3RpY2UoZXJyb3JNZXNzYWdlKGVycm9yKSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgb3BlblZhdWx0SW1wb3J0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnJlcXVpcmVDb25maWd1cmVkKCk7XG4gICAgICBjb25zdCBmaWxlcyA9IHRoaXMudmF1bHRJbXBvcnRGaWxlcygpO1xuICAgICAgY29uc3QgdHJlZSA9IGF3YWl0IHRoaXMuYXBpKCkudHJlZSh0aGlzLnNldHRpbmdzLndvcmtzcGFjZUlkKTtcbiAgICAgIG5ldyBWYXVsdEltcG9ydE1vZGFsKHRoaXMuYXBwLCB0aGlzLCBmaWxlcywgdHJlZSkub3BlbigpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBuZXcgTm90aWNlKGVycm9yTWVzc2FnZShlcnJvcikpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIG9wZW5MaXZlRG9jdW1lbnRQaWNrZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMucmVxdWlyZUNvbmZpZ3VyZWQoKTtcbiAgICAgIGNvbnN0IHRyZWUgPSBhd2FpdCB0aGlzLmFwaSgpLnRyZWUodGhpcy5zZXR0aW5ncy53b3Jrc3BhY2VJZCk7XG4gICAgICBuZXcgUmVtb3RlRG9jdW1lbnRNb2RhbCh0aGlzLmFwcCwgdHJlZSwgKGRvYykgPT4gdm9pZCB0aGlzLm9wZW5MaXZlRG9jdW1lbnQoZG9jKSwgXCJPcGVuIGxpdmVcIikub3BlbigpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBuZXcgTm90aWNlKGVycm9yTWVzc2FnZShlcnJvcikpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNlYXJjaFJlbW90ZShxdWVyeTogc3RyaW5nKTogUHJvbWlzZTxTZWFyY2hSZXN1bHRbXT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5hcGkoKS5zZWFyY2godGhpcy5zZXR0aW5ncy53b3Jrc3BhY2VJZCwgcXVlcnkpO1xuICAgIHJldHVybiByZXNwb25zZS5yZXN1bHRzO1xuICB9XG5cbiAgYXN5bmMgZG93bmxvYWRTZWFyY2hSZXN1bHQocmVzdWx0OiBTZWFyY2hSZXN1bHQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmRvd25sb2FkKHtcbiAgICAgIGlkOiByZXN1bHQuaWQsXG4gICAgICBmb2xkZXJJZDogXCJcIixcbiAgICAgIHRpdGxlOiByZXN1bHQudGl0bGUsXG4gICAgICBwYXRoOiByZXN1bHQucGF0aCxcbiAgICAgIHBlcm1pc3Npb246IHJlc3VsdC5wZXJtaXNzaW9uLFxuICAgICAgdmVyc2lvbjogbnVsbCxcbiAgICAgIGNoZWNrc3VtOiBudWxsLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgc3RhcnREZXZpY2VMb2dpbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgaWYgKCF0aGlzLnNldHRpbmdzLnNlcnZlclVybC50cmltKCkpIHRocm93IG5ldyBFcnJvcihcIlNldCBhIFBhZ2VkZW4gc2VydmVyIFVSTCBmaXJzdC5cIik7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gYXdhaXQgdGhpcy5wdWJsaWNBcGkoKS5kZXZpY2VTdGFydCgpO1xuICAgICAgbmV3IERldmljZUxvZ2luTW9kYWwodGhpcy5hcHAsIHRoaXMsIHJlcXVlc3QpLm9wZW4oKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbmV3IE5vdGljZShlcnJvck1lc3NhZ2UoZXJyb3IpKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBwb2xsRGV2aWNlTG9naW4oZGV2aWNlQ29kZTogc3RyaW5nKTogUHJvbWlzZTxcInBlbmRpbmdcIiB8IFwiZG9uZVwiPiB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5wdWJsaWNBcGkoKS5kZXZpY2VQb2xsKGRldmljZUNvZGUpO1xuICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSBcInBlbmRpbmdcIikgcmV0dXJuIFwicGVuZGluZ1wiO1xuICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSBcImFwcHJvdmVkXCIpIHtcbiAgICAgIHRoaXMuc2V0dGluZ3MudG9rZW4gPSByZXN1bHQudG9rZW47XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBtZSA9IGF3YWl0IG5ldyBQYWdlZGVuQXBpQ2xpZW50KHRoaXMuc2V0dGluZ3Muc2VydmVyVXJsLCByZXN1bHQudG9rZW4pLm1lKCk7XG4gICAgICAgIHRoaXMuc2V0dGluZ3MudXNlck5hbWUgPSBtZS51c2VyLm5hbWU7XG4gICAgICAgIGlmIChtZS53b3Jrc3BhY2VzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgIGNvbnN0IHdzID0gbWUud29ya3NwYWNlc1swXSE7XG4gICAgICAgICAgdGhpcy5zZXR0aW5ncy53b3Jrc3BhY2VJZCA9IHdzLmlkO1xuICAgICAgICAgIHRoaXMuc2V0dGluZ3Mud29ya3NwYWNlTmFtZSA9IHdzLm5hbWU7XG4gICAgICAgICAgYXdhaXQgdGhpcy5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICB0aGlzLnN0YXJ0QXV0b1N5bmMoKTtcbiAgICAgICAgICBuZXcgTm90aWNlKGBDb25uZWN0ZWQhIFNpZ25lZCBpbiBhcyAke21lLnVzZXIubmFtZX0sIHdvcmtzcGFjZSBcIiR7d3MubmFtZX1cIi5gKTtcbiAgICAgICAgfSBlbHNlIGlmIChtZS53b3Jrc3BhY2VzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgIG5ldyBXb3Jrc3BhY2VQaWNrZXJNb2RhbCh0aGlzLmFwcCwgdGhpcywgbWUud29ya3NwYWNlcykub3BlbigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IHRoaXMuc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgdGhpcy5zdGFydEF1dG9TeW5jKCk7XG4gICAgICAgICAgbmV3IE5vdGljZShgQ29ubmVjdGVkIGFzICR7bWUudXNlci5uYW1lfS4gTm8gd29ya3NwYWNlcyBmb3VuZCBcdTIwMTQgY3JlYXRlIG9uZSBpbiBQYWdlZGVuIGZpcnN0LmApO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgYXdhaXQgdGhpcy5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgdGhpcy5zdGFydEF1dG9TeW5jKCk7XG4gICAgICAgIG5ldyBOb3RpY2UoXCJMb2dpbiBhcHByb3ZlZC4gT3BlbiBTZXR0aW5ncyBcdTIxOTIgUGFnZWRlbiB0byBzZWxlY3QgYSB3b3Jrc3BhY2UuXCIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFwiZG9uZVwiO1xuICAgIH1cbiAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJkZW5pZWRcIikgbmV3IE5vdGljZShcIkxvZ2luIHdhcyBjYW5jZWxsZWQuXCIpO1xuICAgIGVsc2UgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiZXhwaXJlZFwiKSBuZXcgTm90aWNlKFwiTG9naW4gY29kZSBleHBpcmVkLiBQbGVhc2UgdHJ5IGFnYWluLlwiKTtcbiAgICBlbHNlIG5ldyBOb3RpY2UoYExvZ2luICR7cmVzdWx0LnN0YXR1c30uYCk7XG4gICAgcmV0dXJuIFwiZG9uZVwiO1xuICB9XG5cbiAgYXN5bmMgZG93bmxvYWQoZG9jOiBSZW1vdGVEb2N1bWVudCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkb3dubG9hZERvY3VtZW50KHRoaXMuc3luY0RlcHMoKSwgZG9jKTtcbiAgICAgIG5ldyBOb3RpY2UoYERvd25sb2FkZWQgJHtyZXN1bHQubG9jYWxQYXRofWApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBuZXcgTm90aWNlKGVycm9yTWVzc2FnZShlcnJvcikpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIG9wZW5MaXZlRG9jdW1lbnQoZG9jOiBQaWNrPFJlbW90ZURvY3VtZW50LCBcImlkXCIgfCBcInBlcm1pc3Npb25cIj4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5yZXF1aXJlQ29uZmlndXJlZCgpO1xuICAgICAgaWYgKGRvYy5wZXJtaXNzaW9uID09PSBcInZpZXdlclwiKSB7XG4gICAgICAgIG5ldyBOb3RpY2UoXCJMaXZlIGVkaXRpbmcgcmVxdWlyZXMgZWRpdG9yIG9yIG1hbmFnZXIgcGVybWlzc2lvbi5cIik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxlYWYgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhZihcInRhYlwiKTtcbiAgICAgIGF3YWl0IGxlYWYuc2V0Vmlld1N0YXRlKHsgdHlwZTogTElWRV9WSUVXX1RZUEUsIGFjdGl2ZTogdHJ1ZSB9KTtcbiAgICAgIGlmIChsZWFmLnZpZXcgaW5zdGFuY2VvZiBMaXZlRG9jdW1lbnRWaWV3KSBhd2FpdCBsZWFmLnZpZXcub3BlbkRvY3VtZW50KGRvYy5pZCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIG5ldyBOb3RpY2UoZXJyb3JNZXNzYWdlKGVycm9yKSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgcHVzaEZpbGUoZmlsZTogVEZpbGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5yZXF1aXJlQ29uZmlndXJlZCgpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHVzaE9yQ3JlYXRlTG9jYWxEb2N1bWVudCh0aGlzLmNyZWF0ZVN5bmNEZXBzKCksIGZpbGUucGF0aCk7XG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJibG9ja2VkX3ZpZXdlclwiKSB7XG4gICAgICAgIG5ldyBOb3RpY2UoXCJUaGlzIHJlbW90ZSBkb2N1bWVudCBpcyB2aWV3ZXItb25seSwgc28gaXQgY2Fubm90IGJlIHB1c2hlZC5cIik7XG4gICAgICB9IGVsc2UgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwiY29uZmxpY3RcIikge1xuICAgICAgICBuZXcgTm90aWNlKFxuICAgICAgICAgIGBZb3VyIGNoYW5nZXMgY29uZmxpY3Qgd2l0aCBhIG5ld2VyIHNlcnZlciB2ZXJzaW9uLlxcblRoZSBzZXJ2ZXIgdmVyc2lvbiB3YXMgc2F2ZWQgYXMgXCIke3Jlc3VsdC5jb25mbGljdFBhdGh9XCIuXFxuVXNlIHRoZSBcIlJlc29sdmUgY29uZmxpY3QgZm9yIHRoaXMgbm90ZVwiIGNvbW1hbmQgdG8gZGlzbWlzcyBpdC5gLFxuICAgICAgICAgIDgwMDAsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXcgTm90aWNlKHJlc3VsdC5zdGF0dXMgPT09IFwiY3JlYXRlZFwiID8gXCJDcmVhdGVkIGluIFBhZ2VkZW4uXCIgOiBcIlB1c2hlZCB0byBQYWdlZGVuLlwiKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbmV3IE5vdGljZShlcnJvck1lc3NhZ2UoZXJyb3IpKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBpbXBvcnRWYXVsdChmaWxlczogVmF1bHRJbXBvcnRGaWxlW10sIHRhcmdldFJvb3ROYW1lOiBzdHJpbmcsIG9uUHJvZ3Jlc3M/OiAoY3VycmVudDogbnVtYmVyLCB0b3RhbDogbnVtYmVyKSA9PiB2b2lkKTogUHJvbWlzZTxWYXVsdEltcG9ydFJlcG9ydD4ge1xuICAgIHRoaXMucmVxdWlyZUNvbmZpZ3VyZWQoKTtcbiAgICByZXR1cm4gaW1wb3J0VmF1bHRUb1BhZ2VkZW4oe1xuICAgICAgYXBpOiB0aGlzLmFwaSgpLFxuICAgICAgdmF1bHQ6IHRoaXMudmF1bHRBZGFwdGVyKCksXG4gICAgICBtZXRhOiB0aGlzLm1ldGFTdG9yZSxcbiAgICAgIHdvcmtzcGFjZUlkOiB0aGlzLnNldHRpbmdzLndvcmtzcGFjZUlkLFxuICAgICAgZmlsZXMsXG4gICAgICB0YXJnZXRSb290TmFtZSxcbiAgICAgIG9uUHJvZ3Jlc3MsXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBvcGVuRm9sZGVyRG93bmxvYWQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMucmVxdWlyZUNvbmZpZ3VyZWQoKTtcbiAgICAgIGNvbnN0IHRyZWUgPSBhd2FpdCB0aGlzLmFwaSgpLnRyZWUodGhpcy5zZXR0aW5ncy53b3Jrc3BhY2VJZCk7XG4gICAgICBuZXcgRm9sZGVyRG93bmxvYWRNb2RhbCh0aGlzLmFwcCwgdGhpcywgdHJlZSkub3BlbigpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBuZXcgTm90aWNlKGVycm9yTWVzc2FnZShlcnJvcikpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGRvd25sb2FkRm9sZGVyRG9jdW1lbnRzKGZvbGRlcklkOiBzdHJpbmcsIGZvbGRlck5hbWU6IHN0cmluZywgdHJlZTogUmVtb3RlVHJlZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkb2NzID0gdHJlZS5kb2N1bWVudHMuZmlsdGVyKChkKSA9PiBkLmZvbGRlcklkID09PSBmb2xkZXJJZCk7XG4gICAgICBpZiAoZG9jcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbmV3IE5vdGljZShgTm8gZG9jdW1lbnRzIGZvdW5kIGluIFwiJHtmb2xkZXJOYW1lfVwiLmApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBuZXcgTm90aWNlKGBEb3dubG9hZGluZyAke2RvY3MubGVuZ3RofSBub3RlJHtkb2NzLmxlbmd0aCA9PT0gMSA/IFwiXCIgOiBcInNcIn0gZnJvbSBcIiR7Zm9sZGVyTmFtZX1cIlx1MjAyNmAsIDMwMDApO1xuICAgICAgbGV0IGRvd25sb2FkZWQgPSAwO1xuICAgICAgbGV0IGZhaWxlZCA9IDA7XG4gICAgICBmb3IgKGNvbnN0IGRvYyBvZiBkb2NzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZG93bmxvYWREb2N1bWVudCh0aGlzLnN5bmNEZXBzKCksIGRvYyk7XG4gICAgICAgICAgZG93bmxvYWRlZCsrO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICBmYWlsZWQrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbmV3IE5vdGljZShcbiAgICAgICAgZmFpbGVkID4gMFxuICAgICAgICAgID8gYERvd25sb2FkZWQgJHtkb3dubG9hZGVkfSBvZiAke2RvY3MubGVuZ3RofSBub3RlcyBmcm9tIFwiJHtmb2xkZXJOYW1lfVwiLiAke2ZhaWxlZH0gZmFpbGVkLmBcbiAgICAgICAgICA6IGBEb3dubG9hZGVkICR7ZG93bmxvYWRlZH0gbm90ZSR7ZG93bmxvYWRlZCA9PT0gMSA/IFwiXCIgOiBcInNcIn0gZnJvbSBcIiR7Zm9sZGVyTmFtZX1cIi5gLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbmV3IE5vdGljZShlcnJvck1lc3NhZ2UoZXJyb3IpKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBkb3dubG9hZEFsbERvY3VtZW50cygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5yZXF1aXJlQ29uZmlndXJlZCgpO1xuICAgICAgY29uc3QgdHJlZSA9IGF3YWl0IHRoaXMuYXBpKCkudHJlZSh0aGlzLnNldHRpbmdzLndvcmtzcGFjZUlkKTtcbiAgICAgIGlmICh0cmVlLmRvY3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbmV3IE5vdGljZShcIk5vIGRvY3VtZW50cyBmb3VuZCBpbiB5b3VyIFBhZ2VkZW4gd29ya3NwYWNlLlwiKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgbmV3IE5vdGljZShgRG93bmxvYWRpbmcgJHt0cmVlLmRvY3VtZW50cy5sZW5ndGh9IG5vdGUke3RyZWUuZG9jdW1lbnRzLmxlbmd0aCA9PT0gMSA/IFwiXCIgOiBcInNcIn1cdTIwMjZgLCAzMDAwKTtcbiAgICAgIGxldCBkb3dubG9hZGVkID0gMDtcbiAgICAgIGxldCBmYWlsZWQgPSAwO1xuICAgICAgZm9yIChjb25zdCBkb2Mgb2YgdHJlZS5kb2N1bWVudHMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBkb3dubG9hZERvY3VtZW50KHRoaXMuc3luY0RlcHMoKSwgZG9jKTtcbiAgICAgICAgICBkb3dubG9hZGVkKys7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIGZhaWxlZCsrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBuZXcgTm90aWNlKFxuICAgICAgICBmYWlsZWQgPiAwXG4gICAgICAgICAgPyBgRG93bmxvYWRlZCAke2Rvd25sb2FkZWR9IG9mICR7dHJlZS5kb2N1bWVudHMubGVuZ3RofSBub3Rlcy4gJHtmYWlsZWR9IGZhaWxlZC5gXG4gICAgICAgICAgOiBgRG93bmxvYWRlZCBhbGwgJHtkb3dubG9hZGVkfSBub3RlJHtkb3dubG9hZGVkID09PSAxID8gXCJcIiA6IFwic1wifS5gLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbmV3IE5vdGljZShlcnJvck1lc3NhZ2UoZXJyb3IpKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyByZXNvbHZlQ29uZmxpY3QoZmlsZTogVEZpbGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjb25mbGljdFBhdGggPSBjb25mbGljdFNpYmxpbmdQYXRoKGZpbGUucGF0aCk7XG4gICAgaWYgKCEoYXdhaXQgdGhpcy5hcHAudmF1bHQuYWRhcHRlci5leGlzdHMoY29uZmxpY3RQYXRoKSkpIHtcbiAgICAgIG5ldyBOb3RpY2UoXCJObyBjb25mbGljdCBmaWxlIGZvdW5kIGZvciB0aGlzIG5vdGUuXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLmFwcC52YXVsdC5hZGFwdGVyLnJlbW92ZShjb25mbGljdFBhdGgpO1xuICAgIG5ldyBOb3RpY2UoXCJDb25mbGljdCByZXNvbHZlZCBcdTIwMTQgdGhlIHNlcnZlciBjb3B5IGhhcyBiZWVuIHJlbW92ZWQuXCIpO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW5jRGVwcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgYXBpOiB0aGlzLmFwaSgpLFxuICAgICAgdmF1bHQ6IHRoaXMudmF1bHRBZGFwdGVyKCksXG4gICAgICBtZXRhOiB0aGlzLm1ldGFTdG9yZSxcbiAgICAgIHJlbW90ZURvY3NGb2xkZXI6IHRoaXMuc2V0dGluZ3MucmVtb3RlRG9jc0ZvbGRlcixcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVTeW5jRGVwcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5zeW5jRGVwcygpLFxuICAgICAgd29ya3NwYWNlSWQ6IHRoaXMuc2V0dGluZ3Mud29ya3NwYWNlSWQsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgdmF1bHRBZGFwdGVyKCk6IFZhdWx0TGlrZSB7XG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXI7XG4gICAgcmV0dXJuIHtcbiAgICAgIHJlYWQ6IChwYXRoKSA9PiBhZGFwdGVyLnJlYWQocGF0aCksXG4gICAgICB3cml0ZTogKHBhdGgsIGNvbnRlbnQpID0+IGFkYXB0ZXIud3JpdGUocGF0aCwgY29udGVudCksXG4gICAgICByZWFkQmluYXJ5OiAocGF0aCkgPT4gYWRhcHRlci5yZWFkQmluYXJ5KHBhdGgpLFxuICAgICAgd3JpdGVCaW5hcnk6IChwYXRoLCBjb250ZW50KSA9PiBhZGFwdGVyLndyaXRlQmluYXJ5KHBhdGgsIGNvbnRlbnQpLFxuICAgICAgZXhpc3RzOiAocGF0aCkgPT4gYWRhcHRlci5leGlzdHMocGF0aCksXG4gICAgICBta2RpcjogKHBhdGgpID0+IGFkYXB0ZXIubWtkaXIocGF0aCksXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgdmF1bHRJbXBvcnRGaWxlcygpOiBWYXVsdEltcG9ydEZpbGVbXSB7XG4gICAgcmV0dXJuIHRoaXMuYXBwLnZhdWx0LmdldEZpbGVzKCkubWFwKChmaWxlKSA9PiAoe1xuICAgICAgcGF0aDogZmlsZS5wYXRoLFxuICAgICAgbmFtZTogZmlsZS5uYW1lLFxuICAgICAgZXh0ZW5zaW9uOiBmaWxlLmV4dGVuc2lvbixcbiAgICB9KSk7XG4gIH1cblxuICBwcml2YXRlIHBsdWdpbkRpcigpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm1hbmlmZXN0LmRpciA/PyBgLm9ic2lkaWFuL3BsdWdpbnMvJHt0aGlzLm1hbmlmZXN0LmlkfWA7XG4gIH1cblxuICBwcml2YXRlIHJlcXVpcmVDb25maWd1cmVkKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zZXR0aW5ncy5zZXJ2ZXJVcmwudHJpbSgpKSB0aHJvdyBuZXcgRXJyb3IoXCJQbGVhc2Ugc2V0IHlvdXIgUGFnZWRlbiBzZXJ2ZXIgVVJMIGluIHNldHRpbmdzLlwiKTtcbiAgICBpZiAoIXRoaXMuc2V0dGluZ3MudG9rZW4udHJpbSgpKSB0aHJvdyBuZXcgRXJyb3IoXCJQbGVhc2UgY29ubmVjdCB0byBQYWdlZGVuIGZpcnN0LiBPcGVuIFNldHRpbmdzIFx1MjE5MiBQYWdlZGVuIGFuZCBjbGljayBcXFwiQ29ubmVjdCB0byBQYWdlZGVuXFxcIi5cIik7XG4gICAgaWYgKCF0aGlzLnNldHRpbmdzLndvcmtzcGFjZUlkLnRyaW0oKSkgdGhyb3cgbmV3IEVycm9yKFwiUGxlYXNlIHNlbGVjdCBhIHdvcmtzcGFjZS4gT3BlbiBTZXR0aW5ncyBcdTIxOTIgUGFnZWRlbiBhbmQgY2xpY2sgXFxcIkNvbm5lY3QgdG8gUGFnZWRlblxcXCIuXCIpO1xuICB9XG59XG5cbmNsYXNzIExpdmVEb2N1bWVudFZpZXcgZXh0ZW5kcyBJdGVtVmlldyB7XG4gIHByaXZhdGUgZWRpdG9yPzogRWRpdG9yO1xuICBwcml2YXRlIHByb3ZpZGVyPzogV2Vic29ja2V0UHJvdmlkZXI7XG4gIHByaXZhdGUgeWRvYz86IFkuRG9jO1xuICBwcml2YXRlIGRvY3VtZW50SWQ/OiBzdHJpbmc7XG4gIHByaXZhdGUgYmFzZVZlcnNpb24gPSBcIlwiO1xuICBwcml2YXRlIGxhc3RTYXZlZE1hcmtkb3duID0gXCJcIjtcbiAgcHJpdmF0ZSBzdGF0dXNFbD86IEhUTUxFbGVtZW50O1xuICBwcml2YXRlIHRpdGxlRWw/OiBIVE1MRWxlbWVudDtcbiAgcHJpdmF0ZSBwYXRoRWw/OiBIVE1MRWxlbWVudDtcbiAgcHJpdmF0ZSBzYXZlVGltZXI/OiBudW1iZXI7XG4gIHByaXZhdGUgc2F2aW5nID0gZmFsc2U7XG4gIHByaXZhdGUgc2F2ZUFnYWluID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgbGVhZjogV29ya3NwYWNlTGVhZixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBsdWdpbjogUGFnZWRlblBsdWdpbixcbiAgKSB7XG4gICAgc3VwZXIobGVhZik7XG4gIH1cblxuICBnZXRWaWV3VHlwZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBMSVZFX1ZJRVdfVFlQRTtcbiAgfVxuXG4gIGdldERpc3BsYXlUZXh0KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudGl0bGVFbD8uZ2V0VGV4dCgpIHx8IFwiUGFnZWRlbiBsaXZlIGRvY3VtZW50XCI7XG4gIH1cblxuICBhc3luYyBvcGVuRG9jdW1lbnQoZG9jdW1lbnRJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5kZXN0cm95TGl2ZVNlc3Npb24oKTtcbiAgICB0aGlzLmRvY3VtZW50SWQgPSBkb2N1bWVudElkO1xuICAgIHRoaXMuY29udGVudEVsLmVtcHR5KCk7XG4gICAgdGhpcy5jb250ZW50RWwuYWRkQ2xhc3MoXCJwYWdlZGVuLWxpdmUtdmlld1wiKTtcblxuICAgIGNvbnN0IGhlYWRlciA9IHRoaXMuY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogXCJwYWdlZGVuLWxpdmUtaGVhZGVyXCIgfSk7XG4gICAgY29uc3QgdGl0bGVXcmFwID0gaGVhZGVyLmNyZWF0ZURpdigpO1xuICAgIHRoaXMudGl0bGVFbCA9IHRpdGxlV3JhcC5jcmVhdGVFbChcImgyXCIsIHsgdGV4dDogXCJMb2FkaW5nLi4uXCIgfSk7XG4gICAgdGhpcy5wYXRoRWwgPSB0aXRsZVdyYXAuY3JlYXRlRWwoXCJwXCIsIHsgdGV4dDogXCJDb25uZWN0aW5nIHRvIFBhZ2VkZW5cIiB9KTtcbiAgICB0aGlzLnN0YXR1c0VsID0gaGVhZGVyLmNyZWF0ZUVsKFwic3BhblwiLCB7IHRleHQ6IFwiQ29ubmVjdGluZ1wiLCBjbHM6IFwicGFnZWRlbi1saXZlLXN0YXR1c1wiIH0pO1xuXG4gICAgY29uc3QgdG9vbGJhciA9IHRoaXMuY29udGVudEVsLmNyZWF0ZURpdih7IGNsczogXCJwYWdlZGVuLWxpdmUtdG9vbGJhclwiIH0pO1xuICAgIGNvbnN0IGVkaXRvckVsID0gdGhpcy5jb250ZW50RWwuY3JlYXRlRGl2KHsgY2xzOiBcInBhZ2VkZW4tbGl2ZS1lZGl0b3JcIiB9KTtcblxuICAgIGNvbnN0IHJlbW90ZSA9IGF3YWl0IHRoaXMucGx1Z2luLmFwaSgpLmRvY3VtZW50KGRvY3VtZW50SWQpO1xuICAgIGlmIChyZW1vdGUucGVybWlzc2lvbiA9PT0gXCJ2aWV3ZXJcIikgdGhyb3cgbmV3IEVycm9yKFwiTGl2ZSBlZGl0aW5nIHJlcXVpcmVzIGVkaXRvciBvciBtYW5hZ2VyIHBlcm1pc3Npb24uXCIpO1xuICAgIHRoaXMuYmFzZVZlcnNpb24gPSByZW1vdGUudmVyc2lvbiA/PyBcIlwiO1xuICAgIHRoaXMubGFzdFNhdmVkTWFya2Rvd24gPSByZW1vdGUuY29udGVudDtcbiAgICB0aGlzLnRpdGxlRWwuc2V0VGV4dChyZW1vdGUudGl0bGUpO1xuICAgIHRoaXMucGF0aEVsLnNldFRleHQocmVtb3RlLnBhdGgpO1xuXG4gICAgdGhpcy55ZG9jID0gbmV3IFkuRG9jKCk7XG4gICAgdGhpcy5wcm92aWRlciA9IG5ldyBXZWJzb2NrZXRQcm92aWRlcih0aGlzLnBsdWdpbi5saXZlQmFzZVVybCgpLCBkb2N1bWVudElkLCB0aGlzLnlkb2MsIHtcbiAgICAgIHBhcmFtczogeyB0b2tlbjogdGhpcy5wbHVnaW4uc2V0dGluZ3MudG9rZW4gfSxcbiAgICAgIGNvbm5lY3Q6IHRydWUsXG4gICAgICBkaXNhYmxlQmM6IHRydWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLmVkaXRvciA9IG5ldyBFZGl0b3Ioe1xuICAgICAgZWxlbWVudDogZWRpdG9yRWwsXG4gICAgICBleHRlbnNpb25zOiBbXG4gICAgICAgIFN0YXJ0ZXJLaXQuY29uZmlndXJlKHsgbGluazogZmFsc2UsIHVuZG9SZWRvOiBmYWxzZSB9KSxcbiAgICAgICAgQ29sbGFib3JhdGlvbi5jb25maWd1cmUoeyBkb2N1bWVudDogdGhpcy55ZG9jIH0pLFxuICAgICAgICBMaW5rLmNvbmZpZ3VyZSh7IGF1dG9saW5rOiB0cnVlLCBvcGVuT25DbGljazogZmFsc2UsIHByb3RvY29sczogW1wiaHR0cFwiLCBcImh0dHBzXCIsIFwibWFpbHRvXCJdIH0pLFxuICAgICAgICBQbGFjZWhvbGRlci5jb25maWd1cmUoeyBwbGFjZWhvbGRlcjogXCJTdGFydCB3cml0aW5nLi4uXCIgfSksXG4gICAgICAgIFRhc2tMaXN0LFxuICAgICAgICBUYXNrSXRlbS5jb25maWd1cmUoeyBuZXN0ZWQ6IHRydWUgfSksXG4gICAgICAgIFRhYmxlLmNvbmZpZ3VyZSh7IHJlc2l6YWJsZTogdHJ1ZSB9KSxcbiAgICAgICAgVGFibGVSb3csXG4gICAgICAgIFRhYmxlSGVhZGVyLFxuICAgICAgICBUYWJsZUNlbGwsXG4gICAgICBdLFxuICAgICAgZWRpdG9yUHJvcHM6IHtcbiAgICAgICAgYXR0cmlidXRlczogeyBjbGFzczogXCJwYWdlZGVuLWxpdmUtcHJvc2VtaXJyb3JcIiB9LFxuICAgICAgfSxcbiAgICAgIG9uVXBkYXRlOiAoeyBlZGl0b3IgfSkgPT4ge1xuICAgICAgICBjb25zdCBtYXJrZG93biA9IGh0bWxUb01hcmtkb3duKGVkaXRvci5nZXRIVE1MKCkpO1xuICAgICAgICBpZiAobWFya2Rvd24gIT09IHRoaXMubGFzdFNhdmVkTWFya2Rvd24pIHRoaXMuc2NoZWR1bGVTYXZlKCk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5yZW5kZXJUb29sYmFyKHRvb2xiYXIpO1xuICAgIHRoaXMucHJvdmlkZXIub24oXCJzdGF0dXNcIiwgKGV2ZW50OiB7IHN0YXR1czogc3RyaW5nIH0pID0+IHRoaXMuc2V0U3RhdHVzKGV2ZW50LnN0YXR1cyA9PT0gXCJjb25uZWN0ZWRcIiA/IFwiTGl2ZVwiIDogXCJSZWNvbm5lY3RpbmdcIikpO1xuICAgIHRoaXMucHJvdmlkZXIub24oXCJzeW5jXCIsIChzeW5jZWQ6IGJvb2xlYW4pID0+IHtcbiAgICAgIGlmIChzeW5jZWQpIHRoaXMuc2VlZEluaXRpYWxDb250ZW50KHJlbW90ZS5jb250ZW50KTtcbiAgICB9KTtcbiAgICBpZiAodGhpcy5wcm92aWRlci5zeW5jZWQpIHRoaXMuc2VlZEluaXRpYWxDb250ZW50KHJlbW90ZS5jb250ZW50KTtcbiAgfVxuXG4gIGFzeW5jIG9uQ2xvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5kZXN0cm95TGl2ZVNlc3Npb24oKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyVG9vbGJhcih0b29sYmFyOiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIGNvbnN0IGJ1dHRvbnM6IEFycmF5PFtzdHJpbmcsICgpID0+IHZvaWRdPiA9IFtcbiAgICAgIFtcIkJcIiwgKCkgPT4gdGhpcy5lZGl0b3I/LmNoYWluKCkuZm9jdXMoKS50b2dnbGVCb2xkKCkucnVuKCldLFxuICAgICAgW1wiSVwiLCAoKSA9PiB0aGlzLmVkaXRvcj8uY2hhaW4oKS5mb2N1cygpLnRvZ2dsZUl0YWxpYygpLnJ1bigpXSxcbiAgICAgIFtcIkgxXCIsICgpID0+IHRoaXMuZWRpdG9yPy5jaGFpbigpLmZvY3VzKCkudG9nZ2xlSGVhZGluZyh7IGxldmVsOiAxIH0pLnJ1bigpXSxcbiAgICAgIFtcIkgyXCIsICgpID0+IHRoaXMuZWRpdG9yPy5jaGFpbigpLmZvY3VzKCkudG9nZ2xlSGVhZGluZyh7IGxldmVsOiAyIH0pLnJ1bigpXSxcbiAgICAgIFtcIkxpc3RcIiwgKCkgPT4gdGhpcy5lZGl0b3I/LmNoYWluKCkuZm9jdXMoKS50b2dnbGVCdWxsZXRMaXN0KCkucnVuKCldLFxuICAgICAgW1wiVGFza1wiLCAoKSA9PiB0aGlzLmVkaXRvcj8uY2hhaW4oKS5mb2N1cygpLnRvZ2dsZVRhc2tMaXN0KCkucnVuKCldLFxuICAgICAgW1wiU2F2ZVwiLCAoKSA9PiB2b2lkIHRoaXMucGVyc2lzdCgpXSxcbiAgICBdO1xuICAgIGZvciAoY29uc3QgW2xhYmVsLCBhY3Rpb25dIG9mIGJ1dHRvbnMpIHtcbiAgICAgIGNvbnN0IGJ1dHRvbiA9IHRvb2xiYXIuY3JlYXRlRWwoXCJidXR0b25cIiwgeyB0ZXh0OiBsYWJlbCwgY2xzOiBcInBhZ2VkZW4tbGl2ZS1idXR0b25cIiB9KTtcbiAgICAgIGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgYWN0aW9uKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNlZWRJbml0aWFsQ29udGVudChtYXJrZG93bjogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmVkaXRvciB8fCB0aGlzLmVkaXRvci5nZXRUZXh0KCkudHJpbSgpKSByZXR1cm47XG4gICAgdGhpcy5lZGl0b3IuY29tbWFuZHMuc2V0Q29udGVudChtYXJrZG93blRvSHRtbChtYXJrZG93biksIHsgZW1pdFVwZGF0ZTogdHJ1ZSB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2NoZWR1bGVTYXZlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNhdmluZykge1xuICAgICAgdGhpcy5zYXZlQWdhaW4gPSB0cnVlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5zYXZlVGltZXIgIT09IHVuZGVmaW5lZCkgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLnNhdmVUaW1lcik7XG4gICAgdGhpcy5zYXZlVGltZXIgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB2b2lkIHRoaXMucGVyc2lzdCgpLCAxNTAwKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcGVyc2lzdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuZWRpdG9yIHx8ICF0aGlzLmRvY3VtZW50SWQpIHJldHVybjtcbiAgICBpZiAodGhpcy5zYXZpbmcpIHtcbiAgICAgIHRoaXMuc2F2ZUFnYWluID0gdHJ1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuc2F2ZVRpbWVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5zYXZlVGltZXIpO1xuICAgICAgdGhpcy5zYXZlVGltZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IGNvbnRlbnQgPSBodG1sVG9NYXJrZG93bih0aGlzLmVkaXRvci5nZXRIVE1MKCkpO1xuICAgIGlmIChjb250ZW50ID09PSB0aGlzLmxhc3RTYXZlZE1hcmtkb3duKSByZXR1cm47XG4gICAgdGhpcy5zYXZpbmcgPSB0cnVlO1xuICAgIHRoaXMuc2V0U3RhdHVzKFwiU2F2aW5nXCIpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnBsdWdpbi5hcGkoKS5wdXNoKHRoaXMuZG9jdW1lbnRJZCwge1xuICAgICAgICBiYXNlVmVyc2lvbjogdGhpcy5iYXNlVmVyc2lvbixcbiAgICAgICAgY2hlY2tzdW06IGF3YWl0IGNoZWNrc3VtKGNvbnRlbnQpLFxuICAgICAgICBjb250ZW50LFxuICAgICAgfSk7XG4gICAgICB0aGlzLmJhc2VWZXJzaW9uID0gcmVzdWx0LnZlcnNpb247XG4gICAgICB0aGlzLmxhc3RTYXZlZE1hcmtkb3duID0gY29udGVudDtcbiAgICAgIHRoaXMuc2V0U3RhdHVzKFwiU2F2ZWRcIik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFBhZ2VkZW5BcGlFcnJvciAmJiBlcnJvci5zdGF0dXMgPT09IDQwOSAmJiBlcnJvci5jdXJyZW50VmVyc2lvbikge1xuICAgICAgICB0aGlzLmJhc2VWZXJzaW9uID0gZXJyb3IuY3VycmVudFZlcnNpb247XG4gICAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICAgIGF3YWl0IHRoaXMucGVyc2lzdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnNldFN0YXR1cyhcIlNhdmUgZmFpbGVkXCIpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuc2F2aW5nID0gZmFsc2U7XG4gICAgICBpZiAodGhpcy5zYXZlQWdhaW4pIHtcbiAgICAgICAgdGhpcy5zYXZlQWdhaW4gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zY2hlZHVsZVNhdmUoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldFN0YXR1cyhzdGF0dXM6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc3RhdHVzRWw/LnNldFRleHQoc3RhdHVzKTtcbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveUxpdmVTZXNzaW9uKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNhdmVUaW1lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuc2F2ZVRpbWVyKTtcbiAgICAgIHRoaXMuc2F2ZVRpbWVyID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLmVkaXRvcj8uZGVzdHJveSgpO1xuICAgIHRoaXMucHJvdmlkZXI/LmRlc3Ryb3koKTtcbiAgICB0aGlzLnlkb2M/LmRlc3Ryb3koKTtcbiAgICB0aGlzLmVkaXRvciA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnByb3ZpZGVyID0gdW5kZWZpbmVkO1xuICAgIHRoaXMueWRvYyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnNhdmVBZ2FpbiA9IGZhbHNlO1xuICB9XG59XG5cbmNsYXNzIFBhZ2VkZW5TZXR0aW5nVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XG4gIGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwcml2YXRlIHJlYWRvbmx5IHBsdWdpbjogUGFnZWRlblBsdWdpbikge1xuICAgIHN1cGVyKGFwcCwgcGx1Z2luKTtcbiAgfVxuXG4gIGRpc3BsYXkoKTogdm9pZCB7XG4gICAgY29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcbiAgICBjb250YWluZXJFbC5lbXB0eSgpO1xuICAgIGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDJcIiwgeyB0ZXh0OiBcIlBhZ2VkZW5cIiB9KTtcblxuICAgIGNvbnN0IGlzQ29ubmVjdGVkID0gdGhpcy5wbHVnaW4uaXNDb25maWd1cmVkKCk7XG5cbiAgICBpZiAoIWlzQ29ubmVjdGVkKSB7XG4gICAgICBjb250YWluZXJFbC5jcmVhdGVFbChcInBcIiwge1xuICAgICAgICB0ZXh0OiBcIkNvbm5lY3QgeW91ciBPYnNpZGlhbiB2YXVsdCB0byBQYWdlZGVuIHRvIHN5bmMgbm90ZXMgYW5kIGNvbGxhYm9yYXRlIHdpdGggeW91ciB0ZWFtLlwiLFxuICAgICAgICBjbHM6IFwic2V0dGluZy1pdGVtLWRlc2NyaXB0aW9uXCIsXG4gICAgICB9KTtcblxuICAgICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAgIC5zZXROYW1lKFwiQ29ubmVjdCB5b3VyIHZhdWx0XCIpXG4gICAgICAgIC5zZXREZXNjKFwiQ2xpY2sgdGhlIGJ1dHRvbiBiZWxvdy4gQSBsb2dpbiBwYWdlIHdpbGwgb3BlbiBpbiB5b3VyIGJyb3dzZXIgXHUyMDE0IGFwcHJvdmUgaXQgdGhlcmUgYW5kIHlvdSdyZSBkb25lLlwiKVxuICAgICAgICAuYWRkQnV0dG9uKChidG4pID0+XG4gICAgICAgICAgYnRuXG4gICAgICAgICAgICAuc2V0QnV0dG9uVGV4dChcIkNvbm5lY3QgdG8gUGFnZWRlblwiKVxuICAgICAgICAgICAgLnNldEN0YSgpXG4gICAgICAgICAgICAub25DbGljaygoKSA9PiB2b2lkIHRoaXMucGx1Z2luLnN0YXJ0RGV2aWNlTG9naW4oKSksXG4gICAgICAgICk7XG5cbiAgICAgIGNvbnRhaW5lckVsLmNyZWF0ZUVsKFwiaDNcIiwgeyB0ZXh0OiBcIlNlcnZlclwiIH0pO1xuXG4gICAgICBuZXcgU2V0dGluZyhjb250YWluZXJFbClcbiAgICAgICAgLnNldE5hbWUoXCJTZXJ2ZXIgVVJMXCIpXG4gICAgICAgIC5zZXREZXNjKFwiVGhlIGFkZHJlc3Mgb2YgeW91ciBQYWdlZGVuIHNlcnZlci5cIilcbiAgICAgICAgLmFkZFRleHQoKHRleHQpID0+XG4gICAgICAgICAgdGV4dFxuICAgICAgICAgICAgLnNldFBsYWNlaG9sZGVyKFwiaHR0cHM6Ly9hcHAuZXhhbXBsZS5jb21cIilcbiAgICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zZXJ2ZXJVcmwpXG4gICAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLnNlcnZlclVybCA9IHZhbHVlLnRyaW0oKTtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZGlzcGxheU5hbWUgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy51c2VyTmFtZSB8fCBcInlvdXIgYWNjb3VudFwiO1xuICAgICAgY29uc3QgZGlzcGxheVdzID0gdGhpcy5wbHVnaW4uc2V0dGluZ3Mud29ya3NwYWNlTmFtZSB8fCB0aGlzLnBsdWdpbi5zZXR0aW5ncy53b3Jrc3BhY2VJZDtcblxuICAgICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAgIC5zZXROYW1lKGBTaWduZWQgaW4gYXMgJHtkaXNwbGF5TmFtZX1gKVxuICAgICAgICAuc2V0RGVzYyhgV29ya3NwYWNlOiAke2Rpc3BsYXlXc31gKVxuICAgICAgICAuYWRkQnV0dG9uKChidG4pID0+XG4gICAgICAgICAgYnRuLnNldEJ1dHRvblRleHQoXCJDaGFuZ2Ugd29ya3NwYWNlXCIpLm9uQ2xpY2soKCkgPT4gdm9pZCB0aGlzLmNoYW5nZVdvcmtzcGFjZSgpKSxcbiAgICAgICAgKVxuICAgICAgICAuYWRkQnV0dG9uKChidG4pID0+XG4gICAgICAgICAgYnRuLnNldEJ1dHRvblRleHQoXCJEaXNjb25uZWN0XCIpLm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudG9rZW4gPSBcIlwiO1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3Mud29ya3NwYWNlSWQgPSBcIlwiO1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MudXNlck5hbWUgPSBcIlwiO1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3Mud29ya3NwYWNlTmFtZSA9IFwiXCI7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgIHRoaXMucGx1Z2luLnN0YXJ0QXV0b1N5bmMoKTtcbiAgICAgICAgICAgIHRoaXMuZGlzcGxheSgpO1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICBjb250YWluZXJFbC5jcmVhdGVFbChcImgzXCIsIHsgdGV4dDogXCJTeW5jXCIgfSk7XG5cbiAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgICAuc2V0TmFtZShcIkJhY2tncm91bmQgc3luY1wiKVxuICAgICAgICAuc2V0RGVzYyhcIkF1dG9tYXRpY2FsbHkgcHVsbCByZW1vdGUgdXBkYXRlcyBhbmQgcHVzaCBsb2NhbCBlZGl0cy5cIilcbiAgICAgICAgLmFkZFRvZ2dsZSgodG9nZ2xlKSA9PlxuICAgICAgICAgIHRvZ2dsZS5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5hdXRvU3luY0VuYWJsZWQpLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MuYXV0b1N5bmNFbmFibGVkID0gdmFsdWU7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgIHRoaXMucGx1Z2luLnN0YXJ0QXV0b1N5bmMoKTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAgIC5zZXROYW1lKFwiU3luYyBpbnRlcnZhbCAobWludXRlcylcIilcbiAgICAgICAgLnNldERlc2MoXCJIb3cgb2Z0ZW4gYmFja2dyb3VuZCBzeW5jIHJ1bnMuIE1pbmltdW0gMSBtaW51dGUuXCIpXG4gICAgICAgIC5hZGRUZXh0KCh0ZXh0KSA9PlxuICAgICAgICAgIHRleHRcbiAgICAgICAgICAgIC5zZXRQbGFjZWhvbGRlcihcIjVcIilcbiAgICAgICAgICAgIC5zZXRWYWx1ZShTdHJpbmcodGhpcy5wbHVnaW4uc2V0dGluZ3MuYXV0b1N5bmNJbnRlcnZhbE1pbnV0ZXMpKVxuICAgICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBtaW51dGVzID0gTWF0aC5tYXgoMSwgTWF0aC5mbG9vcihOdW1iZXIodmFsdWUpKSB8fCBERUZBVUxUX1NFVFRJTkdTLmF1dG9TeW5jSW50ZXJ2YWxNaW51dGVzKTtcbiAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MuYXV0b1N5bmNJbnRlcnZhbE1pbnV0ZXMgPSBtaW51dGVzO1xuICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcbiAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc3RhcnRBdXRvU3luYygpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgICAuc2V0TmFtZShcIkxvY2FsIGZvbGRlclwiKVxuICAgICAgICAuc2V0RGVzYyhcIkZvbGRlciBpbiB5b3VyIHZhdWx0IHdoZXJlIGRvd25sb2FkZWQgZG9jdW1lbnRzIGFyZSBzdG9yZWQuXCIpXG4gICAgICAgIC5hZGRUZXh0KCh0ZXh0KSA9PlxuICAgICAgICAgIHRleHRcbiAgICAgICAgICAgIC5zZXRQbGFjZWhvbGRlcihcIlJlbW90ZSBEb2NzXCIpXG4gICAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MucmVtb3RlRG9jc0ZvbGRlcilcbiAgICAgICAgICAgIC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3MucmVtb3RlRG9jc0ZvbGRlciA9IG5vcm1hbGl6ZVBhdGgodmFsdWUudHJpbSgpIHx8IERFRkFVTFRfU0VUVElOR1MucmVtb3RlRG9jc0ZvbGRlcik7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgIGNvbnN0IGRldGFpbHMgPSBjb250YWluZXJFbC5jcmVhdGVFbChcImRldGFpbHNcIik7XG4gICAgICBkZXRhaWxzLmNyZWF0ZUVsKFwic3VtbWFyeVwiLCB7IHRleHQ6IFwiQWR2YW5jZWRcIiB9KTtcbiAgICAgIGNvbnN0IGFkdiA9IGRldGFpbHMuY3JlYXRlRGl2KCk7XG5cbiAgICAgIG5ldyBTZXR0aW5nKGFkdilcbiAgICAgICAgLnNldE5hbWUoXCJTZXJ2ZXIgVVJMXCIpXG4gICAgICAgIC5hZGRUZXh0KCh0ZXh0KSA9PlxuICAgICAgICAgIHRleHRcbiAgICAgICAgICAgIC5zZXRQbGFjZWhvbGRlcihcImh0dHBzOi8vYXBwLmV4YW1wbGUuY29tXCIpXG4gICAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3Muc2VydmVyVXJsKVxuICAgICAgICAgICAgLm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zZXJ2ZXJVcmwgPSB2YWx1ZS50cmltKCk7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zdGFydEF1dG9TeW5jKCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgbmV3IFNldHRpbmcoYWR2KVxuICAgICAgICAuc2V0TmFtZShcIkNvbm5lY3Rpb25cIilcbiAgICAgICAgLmFkZEJ1dHRvbigoYnRuKSA9PlxuICAgICAgICAgIGJ0bi5zZXRCdXR0b25UZXh0KFwiVGVzdCBjb25uZWN0aW9uXCIpLm9uQ2xpY2soKCkgPT4gdm9pZCB0aGlzLnBsdWdpbi52YWxpZGF0ZUNvbm5lY3Rpb24oKSksXG4gICAgICAgIClcbiAgICAgICAgLmFkZEJ1dHRvbigoYnRuKSA9PlxuICAgICAgICAgIGJ0bi5zZXRCdXR0b25UZXh0KFwiU2lnbiBpbiBhZ2FpblwiKS5vbkNsaWNrKCgpID0+IHZvaWQgdGhpcy5wbHVnaW4uc3RhcnREZXZpY2VMb2dpbigpKSxcbiAgICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNoYW5nZVdvcmtzcGFjZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbWUgPSBhd2FpdCB0aGlzLnBsdWdpbi5hcGkoKS5tZSgpO1xuICAgICAgaWYgKG1lLndvcmtzcGFjZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIG5ldyBOb3RpY2UoXCJObyB3b3Jrc3BhY2VzIGZvdW5kIG9uIHRoaXMgYWNjb3VudC5cIik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIG5ldyBXb3Jrc3BhY2VQaWNrZXJNb2RhbCh0aGlzLmFwcCwgdGhpcy5wbHVnaW4sIG1lLndvcmtzcGFjZXMsICgpID0+IHRoaXMuZGlzcGxheSgpKS5vcGVuKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIG5ldyBOb3RpY2UoZXJyb3JNZXNzYWdlKGVycm9yKSk7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIFJlbW90ZURvY3VtZW50TW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIGFwcDogQXBwLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdHJlZTogUmVtb3RlVHJlZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9uUGljazogKGRvYzogUmVtb3RlRG9jdW1lbnQpID0+IHZvaWQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBidXR0b25UZXh0ID0gXCJEb3dubG9hZFwiLFxuICApIHtcbiAgICBzdXBlcihhcHApO1xuICB9XG5cbiAgb25PcGVuKCk6IHZvaWQge1xuICAgIGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuICAgIGNvbnRlbnRFbC5lbXB0eSgpO1xuICAgIGNvbnRlbnRFbC5jcmVhdGVFbChcImgyXCIsIHsgdGV4dDogXCJQYWdlZGVuIGRvY3VtZW50c1wiIH0pO1xuICAgIGNvbnN0IHZpc2libGVEb2NzID0gdGhpcy50cmVlLmRvY3VtZW50cy5maWx0ZXIoKGRvYykgPT4gZG9jLnBlcm1pc3Npb24gIT09IFwidmlld2VyXCIgfHwgZG9jLnZlcnNpb24pO1xuICAgIGlmICh2aXNpYmxlRG9jcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwgeyB0ZXh0OiBcIk5vIHJlbW90ZSBkb2N1bWVudHMgYXJlIGF2YWlsYWJsZS5cIiB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCBkb2Mgb2YgdmlzaWJsZURvY3MpIHtcbiAgICAgIG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcbiAgICAgICAgLnNldE5hbWUoZG9jLnRpdGxlKVxuICAgICAgICAuc2V0RGVzYyhkb2MucGVybWlzc2lvbiA9PT0gXCJ2aWV3ZXJcIiA/IGAke2RvYy5wYXRofSBcdTAwQjcgcmVhZCBvbmx5YCA6IGRvYy5wYXRoKVxuICAgICAgICAuYWRkQnV0dG9uKChidXR0b24pID0+XG4gICAgICAgICAgYnV0dG9uLnNldEJ1dHRvblRleHQodGhpcy5idXR0b25UZXh0KS5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgIHRoaXMub25QaWNrKGRvYyk7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIFJlbW90ZVNlYXJjaE1vZGFsIGV4dGVuZHMgTW9kYWwge1xuICBwcml2YXRlIHF1ZXJ5ID0gXCJcIjtcbiAgcHJpdmF0ZSByZXN1bHRzRWw/OiBIVE1MRWxlbWVudDtcblxuICBjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcHJpdmF0ZSByZWFkb25seSBwbHVnaW46IFBhZ2VkZW5QbHVnaW4pIHtcbiAgICBzdXBlcihhcHApO1xuICB9XG5cbiAgb25PcGVuKCk6IHZvaWQge1xuICAgIGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuICAgIGNvbnRlbnRFbC5lbXB0eSgpO1xuICAgIGNvbnRlbnRFbC5jcmVhdGVFbChcImgyXCIsIHsgdGV4dDogXCJTZWFyY2ggUGFnZWRlblwiIH0pO1xuICAgIG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcbiAgICAgIC5zZXROYW1lKFwiUXVlcnlcIilcbiAgICAgIC5hZGRUZXh0KCh0ZXh0KSA9PlxuICAgICAgICB0ZXh0XG4gICAgICAgICAgLnNldFBsYWNlaG9sZGVyKFwiU2VhcmNoIHJlbW90ZSBkb2N1bWVudHNcIilcbiAgICAgICAgICAub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnF1ZXJ5ID0gdmFsdWU7XG4gICAgICAgICAgfSksXG4gICAgICApXG4gICAgICAuYWRkQnV0dG9uKChidXR0b24pID0+XG4gICAgICAgIGJ1dHRvbi5zZXRCdXR0b25UZXh0KFwiU2VhcmNoXCIpLm9uQ2xpY2soKCkgPT4gdm9pZCB0aGlzLnJ1blNlYXJjaCgpKSxcbiAgICAgICk7XG4gICAgdGhpcy5yZXN1bHRzRWwgPSBjb250ZW50RWwuY3JlYXRlRGl2KCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJ1blNlYXJjaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMucmVzdWx0c0VsKSByZXR1cm47XG4gICAgdGhpcy5yZXN1bHRzRWwuZW1wdHkoKTtcbiAgICBjb25zdCBxID0gdGhpcy5xdWVyeS50cmltKCk7XG4gICAgaWYgKCFxKSB7XG4gICAgICB0aGlzLnJlc3VsdHNFbC5jcmVhdGVFbChcInBcIiwgeyB0ZXh0OiBcIkVudGVyIGEgc2VhcmNoIHF1ZXJ5LlwiIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMucGx1Z2luLnNlYXJjaFJlbW90ZShxKTtcbiAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLnJlc3VsdHNFbC5jcmVhdGVFbChcInBcIiwgeyB0ZXh0OiBcIk5vIHJlc3VsdHMuXCIgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICAgICAgbmV3IFNldHRpbmcodGhpcy5yZXN1bHRzRWwpXG4gICAgICAgICAgLnNldE5hbWUocmVzdWx0LnRpdGxlKVxuICAgICAgICAgIC5zZXREZXNjKHJlc3VsdC5wZXJtaXNzaW9uID09PSBcInZpZXdlclwiID8gYCR7cmVzdWx0LnBhdGh9IFx1MDBCNyByZWFkIG9ubHlgIDogcmVzdWx0LnBhdGgpXG4gICAgICAgICAgLmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuICAgICAgICAgICAgYnV0dG9uLnNldEJ1dHRvblRleHQoXCJEb3dubG9hZFwiKS5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICAgICAgICB2b2lkIHRoaXMucGx1Z2luLmRvd25sb2FkU2VhcmNoUmVzdWx0KHJlc3VsdCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLnJlc3VsdHNFbC5jcmVhdGVFbChcInBcIiwgeyB0ZXh0OiBlcnJvck1lc3NhZ2UoZXJyb3IpIH0pO1xuICAgIH1cbiAgfVxufVxuXG5jbGFzcyBWYXVsdEltcG9ydE1vZGFsIGV4dGVuZHMgTW9kYWwge1xuICBwcml2YXRlIHRhcmdldFJvb3ROYW1lID0gXCJJbXBvcnRlZCBmcm9tIE9ic2lkaWFuXCI7XG4gIHByaXZhdGUgcHJldmlld0VsPzogSFRNTEVsZW1lbnQ7XG4gIHByaXZhdGUgc3RhdHVzRWw/OiBIVE1MRWxlbWVudDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBhcHA6IEFwcCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBsdWdpbjogUGFnZWRlblBsdWdpbixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGZpbGVzOiBWYXVsdEltcG9ydEZpbGVbXSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlbW90ZVRyZWU6IFJlbW90ZVRyZWUsXG4gICkge1xuICAgIHN1cGVyKGFwcCk7XG4gIH1cblxuICBvbk9wZW4oKTogdm9pZCB7XG4gICAgY29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XG4gICAgY29udGVudEVsLmVtcHR5KCk7XG4gICAgY29udGVudEVsLmNyZWF0ZUVsKFwiaDJcIiwgeyB0ZXh0OiBcIkltcG9ydCBPYnNpZGlhbiB2YXVsdFwiIH0pO1xuICAgIGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuICAgICAgdGV4dDogXCJVcGxvYWQgdGhpcyB2YXVsdCdzIG5vdGVzIGludG8gUGFnZWRlbi4gRXhpc3RpbmcgcmVtb3RlIGRvY3VtZW50cyBhcmUgc2tpcHBlZCwgbmV2ZXIgb3ZlcndyaXR0ZW4uXCIsXG4gICAgfSk7XG5cbiAgICBuZXcgU2V0dGluZyhjb250ZW50RWwpXG4gICAgICAuc2V0TmFtZShcIlBhZ2VkZW4gZm9sZGVyXCIpXG4gICAgICAuc2V0RGVzYyhcIkltcG9ydGVkIGZvbGRlcnMgYW5kIG5vdGVzIHdpbGwgYmUgY3JlYXRlZCB1bmRlciB0aGlzIHRvcC1sZXZlbCBmb2xkZXIuXCIpXG4gICAgICAuYWRkVGV4dCgodGV4dCkgPT5cbiAgICAgICAgdGV4dFxuICAgICAgICAgIC5zZXRQbGFjZWhvbGRlcihcIkltcG9ydGVkIGZyb20gT2JzaWRpYW5cIilcbiAgICAgICAgICAuc2V0VmFsdWUodGhpcy50YXJnZXRSb290TmFtZSlcbiAgICAgICAgICAub25DaGFuZ2UoKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnRhcmdldFJvb3ROYW1lID0gdmFsdWUudHJpbSgpIHx8IFwiSW1wb3J0ZWQgZnJvbSBPYnNpZGlhblwiO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXJQcmV2aWV3KCk7XG4gICAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgdGhpcy5wcmV2aWV3RWwgPSBjb250ZW50RWwuY3JlYXRlRGl2KCk7XG4gICAgdGhpcy5zdGF0dXNFbCA9IGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIik7XG4gICAgdGhpcy5yZW5kZXJQcmV2aWV3KCk7XG5cbiAgICBuZXcgU2V0dGluZyhjb250ZW50RWwpXG4gICAgICAuYWRkQnV0dG9uKChidXR0b24pID0+XG4gICAgICAgIGJ1dHRvblxuICAgICAgICAgIC5zZXRCdXR0b25UZXh0KFwiSW1wb3J0IHZhdWx0XCIpXG4gICAgICAgICAgLnNldEN0YSgpXG4gICAgICAgICAgLm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYnV0dG9uLnNldERpc2FibGVkKHRydWUpLnNldEJ1dHRvblRleHQoXCJJbXBvcnRpbmcuLi5cIik7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJ1bkltcG9ydCgpO1xuICAgICAgICAgICAgYnV0dG9uLnNldERpc2FibGVkKGZhbHNlKS5zZXRCdXR0b25UZXh0KFwiSW1wb3J0IHZhdWx0XCIpO1xuICAgICAgICAgIH0pLFxuICAgICAgKVxuICAgICAgLmFkZEJ1dHRvbigoYnV0dG9uKSA9PiBidXR0b24uc2V0QnV0dG9uVGV4dChcIkNhbmNlbFwiKS5vbkNsaWNrKCgpID0+IHRoaXMuY2xvc2UoKSkpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJQcmV2aWV3KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wcmV2aWV3RWwpIHJldHVybjtcbiAgICB0aGlzLnByZXZpZXdFbC5lbXB0eSgpO1xuICAgIGNvbnN0IHByZXZpZXcgPSBidWlsZFZhdWx0SW1wb3J0UHJldmlldyh0aGlzLmZpbGVzLCB0aGlzLnJlbW90ZVRyZWUsIHRoaXMudGFyZ2V0Um9vdE5hbWUpO1xuICAgIHRoaXMucHJldmlld0VsLmNyZWF0ZUVsKFwiaDNcIiwgeyB0ZXh0OiBcIlByZXZpZXdcIiB9KTtcbiAgICBjb25zdCBsaXN0ID0gdGhpcy5wcmV2aWV3RWwuY3JlYXRlRWwoXCJ1bFwiKTtcbiAgICBsaXN0LmNyZWF0ZUVsKFwibGlcIiwgeyB0ZXh0OiBgJHtwcmV2aWV3Lm5vdGVzfSBNYXJrZG93biBub3RlJHtwcmV2aWV3Lm5vdGVzID09PSAxID8gXCJcIiA6IFwic1wifSByZWFkeSB0byBpbXBvcnQuYCB9KTtcbiAgICBsaXN0LmNyZWF0ZUVsKFwibGlcIiwgeyB0ZXh0OiBgJHtwcmV2aWV3LmF0dGFjaG1lbnRzfSBhdHRhY2htZW50JHtwcmV2aWV3LmF0dGFjaG1lbnRzID09PSAxID8gXCJcIiA6IFwic1wifSBkZXRlY3RlZC5gIH0pO1xuICAgIGxpc3QuY3JlYXRlRWwoXCJsaVwiLCB7IHRleHQ6IGAke3ByZXZpZXcuc2tpcHBlZH0gaW50ZXJuYWwgb3IgdW5zdXBwb3J0ZWQgZmlsZSR7cHJldmlldy5za2lwcGVkID09PSAxID8gXCJcIiA6IFwic1wifSBza2lwcGVkLmAgfSk7XG4gICAgaWYgKHByZXZpZXcuY29uZmxpY3RzLmxlbmd0aCkge1xuICAgICAgbGlzdC5jcmVhdGVFbChcImxpXCIsIHsgdGV4dDogYCR7cHJldmlldy5jb25mbGljdHMubGVuZ3RofSByZW1vdGUgZG9jdW1lbnQke3ByZXZpZXcuY29uZmxpY3RzLmxlbmd0aCA9PT0gMSA/IFwiXCIgOiBcInNcIn0gYWxyZWFkeSBleGlzdCBhbmQgd2lsbCBiZSBza2lwcGVkLmAgfSk7XG4gICAgfVxuICAgIHRoaXMuc3RhdHVzRWw/LnNldFRleHQoXCJcIik7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJ1bkltcG9ydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5zdGF0dXNFbD8uc2V0VGV4dChcIlN0YXJ0aW5nIGltcG9ydFx1MjAyNlwiKTtcbiAgICAgIGNvbnN0IHJlcG9ydCA9IGF3YWl0IHRoaXMucGx1Z2luLmltcG9ydFZhdWx0KHRoaXMuZmlsZXMsIHRoaXMudGFyZ2V0Um9vdE5hbWUsIChjdXJyZW50LCB0b3RhbCkgPT4ge1xuICAgICAgICB0aGlzLnN0YXR1c0VsPy5zZXRUZXh0KGBJbXBvcnRpbmcgbm90ZSAke2N1cnJlbnR9IG9mICR7dG90YWx9XHUyMDI2YCk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHdhcm5pbmdzID0gcmVwb3J0LmF0dGFjaG1lbnRXYXJuaW5ncy5sZW5ndGggPyBgICR7cmVwb3J0LmF0dGFjaG1lbnRXYXJuaW5ncy5sZW5ndGh9IGF0dGFjaG1lbnQgd2FybmluZyR7cmVwb3J0LmF0dGFjaG1lbnRXYXJuaW5ncy5sZW5ndGggPT09IDEgPyBcIlwiIDogXCJzXCJ9LmAgOiBcIlwiO1xuICAgICAgdGhpcy5zdGF0dXNFbD8uc2V0VGV4dChcbiAgICAgICAgYERvbmUhIENyZWF0ZWQgJHtyZXBvcnQuZm9sZGVyc0NyZWF0ZWR9IGZvbGRlciR7cmVwb3J0LmZvbGRlcnNDcmVhdGVkID09PSAxID8gXCJcIiA6IFwic1wifSwgaW1wb3J0ZWQgJHtyZXBvcnQuZG9jdW1lbnRzQ3JlYXRlZH0gbm90ZSR7cmVwb3J0LmRvY3VtZW50c0NyZWF0ZWQgPT09IDEgPyBcIlwiIDogXCJzXCJ9LCB1cGxvYWRlZCAke3JlcG9ydC5hdHRhY2htZW50c1VwbG9hZGVkfSBhdHRhY2htZW50JHtyZXBvcnQuYXR0YWNobWVudHNVcGxvYWRlZCA9PT0gMSA/IFwiXCIgOiBcInNcIn0uJHt3YXJuaW5nc31gLFxuICAgICAgKTtcbiAgICAgIG5ldyBOb3RpY2UoXCJWYXVsdCBpbXBvcnQgY29tcGxldGUuXCIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gZXJyb3JNZXNzYWdlKGVycm9yKTtcbiAgICAgIHRoaXMuc3RhdHVzRWw/LnNldFRleHQobWVzc2FnZSk7XG4gICAgICBuZXcgTm90aWNlKG1lc3NhZ2UpO1xuICAgIH1cbiAgfVxufVxuXG5jbGFzcyBEZXZpY2VMb2dpbk1vZGFsIGV4dGVuZHMgTW9kYWwge1xuICBwcml2YXRlIGludGVydmFsSWQ/OiBudW1iZXI7XG4gIHByaXZhdGUgc3RhdHVzRWw/OiBIVE1MRWxlbWVudDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBhcHA6IEFwcCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHBsdWdpbjogUGFnZWRlblBsdWdpbixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlcXVlc3Q6IERldmljZVN0YXJ0UmVzcG9uc2UsXG4gICkge1xuICAgIHN1cGVyKGFwcCk7XG4gIH1cblxuICBvbk9wZW4oKTogdm9pZCB7XG4gICAgY29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XG4gICAgY29udGVudEVsLmVtcHR5KCk7XG4gICAgY29udGVudEVsLmNyZWF0ZUVsKFwiaDJcIiwgeyB0ZXh0OiBcIkNvbm5lY3QgdG8gUGFnZWRlblwiIH0pO1xuICAgIGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuICAgICAgdGV4dDogXCJBIGxvZ2luIHBhZ2Ugc2hvdWxkIGhhdmUgb3BlbmVkIGluIHlvdXIgYnJvd3Nlci4gRW50ZXIgdGhpcyBjb2RlIHRoZXJlIHRvIGFwcHJvdmUgdGhlIGNvbm5lY3Rpb246XCIsXG4gICAgfSk7XG4gICAgY29udGVudEVsLmNyZWF0ZUVsKFwiaDNcIiwgeyB0ZXh0OiB0aGlzLnJlcXVlc3QudXNlckNvZGUsIGNsczogXCJwYWdlZGVuLWRldmljZS1jb2RlXCIgfSk7XG4gICAgY29udGVudEVsLmNyZWF0ZUVsKFwicFwiLCB7XG4gICAgICB0ZXh0OiBcIklmIHRoZSBicm93c2VyIGRpZCBub3Qgb3BlbiBhdXRvbWF0aWNhbGx5LCB1c2UgdGhlIGJ1dHRvbiBiZWxvdy5cIixcbiAgICAgIGNsczogXCJzZXR0aW5nLWl0ZW0tZGVzY3JpcHRpb25cIixcbiAgICB9KTtcbiAgICBuZXcgU2V0dGluZyhjb250ZW50RWwpXG4gICAgICAuYWRkQnV0dG9uKChidXR0b24pID0+XG4gICAgICAgIGJ1dHRvbi5zZXRCdXR0b25UZXh0KFwiT3BlbiBicm93c2VyXCIpLm9uQ2xpY2soKCkgPT4gd2luZG93Lm9wZW4odGhpcy5yZXF1ZXN0LnZlcmlmaWNhdGlvblVyaSkpLFxuICAgICAgKVxuICAgICAgLmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuICAgICAgICBidXR0b24uc2V0QnV0dG9uVGV4dChcIkNvcHkgY29kZVwiKS5vbkNsaWNrKCgpID0+IHZvaWQgbmF2aWdhdG9yLmNsaXBib2FyZD8ud3JpdGVUZXh0KHRoaXMucmVxdWVzdC51c2VyQ29kZSkpLFxuICAgICAgKVxuICAgICAgLmFkZEJ1dHRvbigoYnV0dG9uKSA9PlxuICAgICAgICBidXR0b24uc2V0QnV0dG9uVGV4dChcIkNoZWNrIG5vd1wiKS5vbkNsaWNrKCgpID0+IHZvaWQgdGhpcy5wb2xsKCkpLFxuICAgICAgKTtcbiAgICB0aGlzLnN0YXR1c0VsID0gY29udGVudEVsLmNyZWF0ZUVsKFwicFwiLCB7IHRleHQ6IFwiV2FpdGluZyBmb3IgeW91IHRvIGFwcHJvdmUgaW4gdGhlIGJyb3dzZXJcdTIwMjZcIiB9KTtcbiAgICBjb25zdCBpbnRlcnZhbE1zID0gTWF0aC5tYXgoMSwgdGhpcy5yZXF1ZXN0LmludGVydmFsKSAqIDEwMDA7XG4gICAgdGhpcy5pbnRlcnZhbElkID0gd2luZG93LnNldEludGVydmFsKCgpID0+IHZvaWQgdGhpcy5wb2xsKCksIGludGVydmFsTXMpO1xuICAgIHdpbmRvdy5vcGVuKHRoaXMucmVxdWVzdC52ZXJpZmljYXRpb25VcmkpO1xuICB9XG5cbiAgb25DbG9zZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pbnRlcnZhbElkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMuaW50ZXJ2YWxJZCk7XG4gICAgICB0aGlzLmludGVydmFsSWQgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwb2xsKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCB0aGlzLnBsdWdpbi5wb2xsRGV2aWNlTG9naW4odGhpcy5yZXF1ZXN0LmRldmljZUNvZGUpO1xuICAgICAgaWYgKHN0YXR1cyA9PT0gXCJwZW5kaW5nXCIpIHtcbiAgICAgICAgdGhpcy5zdGF0dXNFbD8uc2V0VGV4dChcIldhaXRpbmcgZm9yIGFwcHJvdmFsLi4uXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLnN0YXR1c0VsPy5zZXRUZXh0KGVycm9yTWVzc2FnZShlcnJvcikpO1xuICAgIH1cbiAgfVxufVxuXG5jbGFzcyBXb3Jrc3BhY2VQaWNrZXJNb2RhbCBleHRlbmRzIE1vZGFsIHtcbiAgY29uc3RydWN0b3IoXG4gICAgYXBwOiBBcHAsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwbHVnaW46IFBhZ2VkZW5QbHVnaW4sXG4gICAgcHJpdmF0ZSByZWFkb25seSB3b3Jrc3BhY2VzOiBNZVJlc3BvbnNlW1wid29ya3NwYWNlc1wiXSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9uU2VsZWN0PzogKCkgPT4gdm9pZCxcbiAgKSB7XG4gICAgc3VwZXIoYXBwKTtcbiAgfVxuXG4gIG9uT3BlbigpOiB2b2lkIHtcbiAgICBjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcbiAgICBjb250ZW50RWwuZW1wdHkoKTtcbiAgICBjb250ZW50RWwuY3JlYXRlRWwoXCJoMlwiLCB7IHRleHQ6IFwiQ2hvb3NlIGEgd29ya3NwYWNlXCIgfSk7XG4gICAgY29udGVudEVsLmNyZWF0ZUVsKFwicFwiLCB7XG4gICAgICB0ZXh0OiBcIlNlbGVjdCB3aGljaCBQYWdlZGVuIHdvcmtzcGFjZSB0byBzeW5jIHdpdGggdGhpcyB2YXVsdC5cIixcbiAgICAgIGNsczogXCJzZXR0aW5nLWl0ZW0tZGVzY3JpcHRpb25cIixcbiAgICB9KTtcbiAgICBmb3IgKGNvbnN0IHdzIG9mIHRoaXMud29ya3NwYWNlcykge1xuICAgICAgbmV3IFNldHRpbmcoY29udGVudEVsKVxuICAgICAgICAuc2V0TmFtZSh3cy5uYW1lKVxuICAgICAgICAuc2V0RGVzYyh3cy5yb2xlID09PSBcImFkbWluXCIgPyBcIllvdSBhcmUgYW4gYWRtaW5cIiA6IFwiTWVtYmVyXCIpXG4gICAgICAgIC5hZGRCdXR0b24oKGJ0bikgPT5cbiAgICAgICAgICBidG5cbiAgICAgICAgICAgIC5zZXRCdXR0b25UZXh0KFwiU2VsZWN0XCIpXG4gICAgICAgICAgICAuc2V0Q3RhKClcbiAgICAgICAgICAgIC5vbkNsaWNrKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3Mud29ya3NwYWNlSWQgPSB3cy5pZDtcbiAgICAgICAgICAgICAgdGhpcy5wbHVnaW4uc2V0dGluZ3Mud29ya3NwYWNlTmFtZSA9IHdzLm5hbWU7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zdGFydEF1dG9TeW5jKCk7XG4gICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgICAgbmV3IE5vdGljZShgV29ya3NwYWNlIHNldCB0byBcIiR7d3MubmFtZX1cIi5gKTtcbiAgICAgICAgICAgICAgdGhpcy5vblNlbGVjdD8uKCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuY2xhc3MgRm9sZGVyRG93bmxvYWRNb2RhbCBleHRlbmRzIE1vZGFsIHtcbiAgY29uc3RydWN0b3IoXG4gICAgYXBwOiBBcHAsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwbHVnaW46IFBhZ2VkZW5QbHVnaW4sXG4gICAgcHJpdmF0ZSByZWFkb25seSB0cmVlOiBSZW1vdGVUcmVlLFxuICApIHtcbiAgICBzdXBlcihhcHApO1xuICB9XG5cbiAgb25PcGVuKCk6IHZvaWQge1xuICAgIGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuICAgIGNvbnRlbnRFbC5lbXB0eSgpO1xuICAgIGNvbnRlbnRFbC5jcmVhdGVFbChcImgyXCIsIHsgdGV4dDogXCJEb3dubG9hZCBhIGZvbGRlclwiIH0pO1xuICAgIGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuICAgICAgdGV4dDogXCJDaG9vc2UgYSBmb2xkZXIgdG8gZG93bmxvYWQgYWxsIGl0cyBub3RlcyB0byB5b3VyIHZhdWx0LlwiLFxuICAgICAgY2xzOiBcInNldHRpbmctaXRlbS1kZXNjcmlwdGlvblwiLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZm9sZGVyc1dpdGhEb2NzID0gdGhpcy50cmVlLmZvbGRlcnNcbiAgICAgIC5tYXAoKGZvbGRlcikgPT4gKHsgZm9sZGVyLCBjb3VudDogdGhpcy50cmVlLmRvY3VtZW50cy5maWx0ZXIoKGQpID0+IGQuZm9sZGVySWQgPT09IGZvbGRlci5pZCkubGVuZ3RoIH0pKVxuICAgICAgLmZpbHRlcigoeyBjb3VudCB9KSA9PiBjb3VudCA+IDApXG4gICAgICAuc29ydCgoYSwgYikgPT4gYS5mb2xkZXIucGF0aC5sb2NhbGVDb21wYXJlKGIuZm9sZGVyLnBhdGgpKTtcblxuICAgIGlmIChmb2xkZXJzV2l0aERvY3MubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHsgdGV4dDogXCJObyBmb2xkZXJzIHdpdGggZG9jdW1lbnRzIGZvdW5kIGluIHlvdXIgd29ya3NwYWNlLlwiIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgeyBmb2xkZXIsIGNvdW50IH0gb2YgZm9sZGVyc1dpdGhEb2NzKSB7XG4gICAgICBuZXcgU2V0dGluZyhjb250ZW50RWwpXG4gICAgICAgIC5zZXROYW1lKGZvbGRlci5uYW1lKVxuICAgICAgICAuc2V0RGVzYyhgJHtmb2xkZXIucGF0aH0gXHUwMEI3ICR7Y291bnR9IG5vdGUke2NvdW50ID09PSAxID8gXCJcIiA6IFwic1wifWApXG4gICAgICAgIC5hZGRCdXR0b24oKGJ0bikgPT5cbiAgICAgICAgICBidG4uc2V0QnV0dG9uVGV4dChcIkRvd25sb2FkIGFsbFwiKS5vbkNsaWNrKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgIHZvaWQgdGhpcy5wbHVnaW4uZG93bmxvYWRGb2xkZXJEb2N1bWVudHMoZm9sZGVyLmlkLCBmb2xkZXIubmFtZSwgdGhpcy50cmVlKTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZXJyb3JNZXNzYWdlKGVycm9yOiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHJldHVybiBlcnJvci5tZXNzYWdlO1xuICByZXR1cm4gXCJQYWdlZGVuIHJlcXVlc3QgZmFpbGVkLlwiO1xufVxuXG5mdW5jdGlvbiBpc1VuZGVyUmVtb3RlRG9jc0ZvbGRlcihyZW1vdGVEb2NzRm9sZGVyOiBzdHJpbmcsIHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCByb290ID0gbm9ybWFsaXplUGF0aChyZW1vdGVEb2NzRm9sZGVyKS5yZXBsYWNlKC9cXC8rJC8sIFwiXCIpO1xuICBjb25zdCBsb2NhbFBhdGggPSBub3JtYWxpemVQYXRoKHBhdGgpO1xuICByZXR1cm4gbG9jYWxQYXRoID09PSByb290IHx8IGxvY2FsUGF0aC5zdGFydHNXaXRoKGAke3Jvb3R9L2ApO1xufVxuXG5mdW5jdGlvbiBtYXJrZG93blRvSHRtbChtYXJrZG93bjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIG1hcmtlZC5wYXJzZShtYXJrZG93biwgeyBhc3luYzogZmFsc2UgfSkgYXMgc3RyaW5nO1xufVxuXG5mdW5jdGlvbiBodG1sVG9NYXJrZG93bihodG1sOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBtYXJrZG93biA9IHR1cm5kb3duLnR1cm5kb3duKGh0bWwpLnRyaW1FbmQoKTtcbiAgcmV0dXJuIG1hcmtkb3duID8gYCR7bWFya2Rvd259XFxuYCA6IFwiXCI7XG59XG4iLCAiLy8gOjotIFBlcnNpc3RlbnQgZGF0YSBzdHJ1Y3R1cmUgcmVwcmVzZW50aW5nIGFuIG9yZGVyZWQgbWFwcGluZyBmcm9tXG4vLyBzdHJpbmdzIHRvIHZhbHVlcywgd2l0aCBzb21lIGNvbnZlbmllbnQgdXBkYXRlIG1ldGhvZHMuXG5mdW5jdGlvbiBPcmRlcmVkTWFwKGNvbnRlbnQpIHtcbiAgdGhpcy5jb250ZW50ID0gY29udGVudDtcbn1cblxuT3JkZXJlZE1hcC5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBPcmRlcmVkTWFwLFxuXG4gIGZpbmQ6IGZ1bmN0aW9uKGtleSkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jb250ZW50Lmxlbmd0aDsgaSArPSAyKVxuICAgICAgaWYgKHRoaXMuY29udGVudFtpXSA9PT0ga2V5KSByZXR1cm4gaVxuICAgIHJldHVybiAtMVxuICB9LFxuXG4gIC8vIDo6IChzdHJpbmcpIFx1MjE5MiA/YW55XG4gIC8vIFJldHJpZXZlIHRoZSB2YWx1ZSBzdG9yZWQgdW5kZXIgYGtleWAsIG9yIHJldHVybiB1bmRlZmluZWQgd2hlblxuICAvLyBubyBzdWNoIGtleSBleGlzdHMuXG4gIGdldDogZnVuY3Rpb24oa2V5KSB7XG4gICAgdmFyIGZvdW5kID0gdGhpcy5maW5kKGtleSk7XG4gICAgcmV0dXJuIGZvdW5kID09IC0xID8gdW5kZWZpbmVkIDogdGhpcy5jb250ZW50W2ZvdW5kICsgMV1cbiAgfSxcblxuICAvLyA6OiAoc3RyaW5nLCBhbnksID9zdHJpbmcpIFx1MjE5MiBPcmRlcmVkTWFwXG4gIC8vIENyZWF0ZSBhIG5ldyBtYXAgYnkgcmVwbGFjaW5nIHRoZSB2YWx1ZSBvZiBga2V5YCB3aXRoIGEgbmV3XG4gIC8vIHZhbHVlLCBvciBhZGRpbmcgYSBiaW5kaW5nIHRvIHRoZSBlbmQgb2YgdGhlIG1hcC4gSWYgYG5ld0tleWAgaXNcbiAgLy8gZ2l2ZW4sIHRoZSBrZXkgb2YgdGhlIGJpbmRpbmcgd2lsbCBiZSByZXBsYWNlZCB3aXRoIHRoYXQga2V5LlxuICB1cGRhdGU6IGZ1bmN0aW9uKGtleSwgdmFsdWUsIG5ld0tleSkge1xuICAgIHZhciBzZWxmID0gbmV3S2V5ICYmIG5ld0tleSAhPSBrZXkgPyB0aGlzLnJlbW92ZShuZXdLZXkpIDogdGhpcztcbiAgICB2YXIgZm91bmQgPSBzZWxmLmZpbmQoa2V5KSwgY29udGVudCA9IHNlbGYuY29udGVudC5zbGljZSgpO1xuICAgIGlmIChmb3VuZCA9PSAtMSkge1xuICAgICAgY29udGVudC5wdXNoKG5ld0tleSB8fCBrZXksIHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29udGVudFtmb3VuZCArIDFdID0gdmFsdWU7XG4gICAgICBpZiAobmV3S2V5KSBjb250ZW50W2ZvdW5kXSA9IG5ld0tleTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBPcmRlcmVkTWFwKGNvbnRlbnQpXG4gIH0sXG5cbiAgLy8gOjogKHN0cmluZykgXHUyMTkyIE9yZGVyZWRNYXBcbiAgLy8gUmV0dXJuIGEgbWFwIHdpdGggdGhlIGdpdmVuIGtleSByZW1vdmVkLCBpZiBpdCBleGlzdGVkLlxuICByZW1vdmU6IGZ1bmN0aW9uKGtleSkge1xuICAgIHZhciBmb3VuZCA9IHRoaXMuZmluZChrZXkpO1xuICAgIGlmIChmb3VuZCA9PSAtMSkgcmV0dXJuIHRoaXNcbiAgICB2YXIgY29udGVudCA9IHRoaXMuY29udGVudC5zbGljZSgpO1xuICAgIGNvbnRlbnQuc3BsaWNlKGZvdW5kLCAyKTtcbiAgICByZXR1cm4gbmV3IE9yZGVyZWRNYXAoY29udGVudClcbiAgfSxcblxuICAvLyA6OiAoc3RyaW5nLCBhbnkpIFx1MjE5MiBPcmRlcmVkTWFwXG4gIC8vIEFkZCBhIG5ldyBrZXkgdG8gdGhlIHN0YXJ0IG9mIHRoZSBtYXAuXG4gIGFkZFRvU3RhcnQ6IGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IE9yZGVyZWRNYXAoW2tleSwgdmFsdWVdLmNvbmNhdCh0aGlzLnJlbW92ZShrZXkpLmNvbnRlbnQpKVxuICB9LFxuXG4gIC8vIDo6IChzdHJpbmcsIGFueSkgXHUyMTkyIE9yZGVyZWRNYXBcbiAgLy8gQWRkIGEgbmV3IGtleSB0byB0aGUgZW5kIG9mIHRoZSBtYXAuXG4gIGFkZFRvRW5kOiBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgdmFyIGNvbnRlbnQgPSB0aGlzLnJlbW92ZShrZXkpLmNvbnRlbnQuc2xpY2UoKTtcbiAgICBjb250ZW50LnB1c2goa2V5LCB2YWx1ZSk7XG4gICAgcmV0dXJuIG5ldyBPcmRlcmVkTWFwKGNvbnRlbnQpXG4gIH0sXG5cbiAgLy8gOjogKHN0cmluZywgc3RyaW5nLCBhbnkpIFx1MjE5MiBPcmRlcmVkTWFwXG4gIC8vIEFkZCBhIGtleSBhZnRlciB0aGUgZ2l2ZW4ga2V5LiBJZiBgcGxhY2VgIGlzIG5vdCBmb3VuZCwgdGhlIG5ld1xuICAvLyBrZXkgaXMgYWRkZWQgdG8gdGhlIGVuZC5cbiAgYWRkQmVmb3JlOiBmdW5jdGlvbihwbGFjZSwga2V5LCB2YWx1ZSkge1xuICAgIHZhciB3aXRob3V0ID0gdGhpcy5yZW1vdmUoa2V5KSwgY29udGVudCA9IHdpdGhvdXQuY29udGVudC5zbGljZSgpO1xuICAgIHZhciBmb3VuZCA9IHdpdGhvdXQuZmluZChwbGFjZSk7XG4gICAgY29udGVudC5zcGxpY2UoZm91bmQgPT0gLTEgPyBjb250ZW50Lmxlbmd0aCA6IGZvdW5kLCAwLCBrZXksIHZhbHVlKTtcbiAgICByZXR1cm4gbmV3IE9yZGVyZWRNYXAoY29udGVudClcbiAgfSxcblxuICAvLyA6OiAoKGtleTogc3RyaW5nLCB2YWx1ZTogYW55KSlcbiAgLy8gQ2FsbCB0aGUgZ2l2ZW4gZnVuY3Rpb24gZm9yIGVhY2gga2V5L3ZhbHVlIHBhaXIgaW4gdGhlIG1hcCwgaW5cbiAgLy8gb3JkZXIuXG4gIGZvckVhY2g6IGZ1bmN0aW9uKGYpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY29udGVudC5sZW5ndGg7IGkgKz0gMilcbiAgICAgIGYodGhpcy5jb250ZW50W2ldLCB0aGlzLmNvbnRlbnRbaSArIDFdKTtcbiAgfSxcblxuICAvLyA6OiAodW5pb248T2JqZWN0LCBPcmRlcmVkTWFwPikgXHUyMTkyIE9yZGVyZWRNYXBcbiAgLy8gQ3JlYXRlIGEgbmV3IG1hcCBieSBwcmVwZW5kaW5nIHRoZSBrZXlzIGluIHRoaXMgbWFwIHRoYXQgZG9uJ3RcbiAgLy8gYXBwZWFyIGluIGBtYXBgIGJlZm9yZSB0aGUga2V5cyBpbiBgbWFwYC5cbiAgcHJlcGVuZDogZnVuY3Rpb24obWFwKSB7XG4gICAgbWFwID0gT3JkZXJlZE1hcC5mcm9tKG1hcCk7XG4gICAgaWYgKCFtYXAuc2l6ZSkgcmV0dXJuIHRoaXNcbiAgICByZXR1cm4gbmV3IE9yZGVyZWRNYXAobWFwLmNvbnRlbnQuY29uY2F0KHRoaXMuc3VidHJhY3QobWFwKS5jb250ZW50KSlcbiAgfSxcblxuICAvLyA6OiAodW5pb248T2JqZWN0LCBPcmRlcmVkTWFwPikgXHUyMTkyIE9yZGVyZWRNYXBcbiAgLy8gQ3JlYXRlIGEgbmV3IG1hcCBieSBhcHBlbmRpbmcgdGhlIGtleXMgaW4gdGhpcyBtYXAgdGhhdCBkb24ndFxuICAvLyBhcHBlYXIgaW4gYG1hcGAgYWZ0ZXIgdGhlIGtleXMgaW4gYG1hcGAuXG4gIGFwcGVuZDogZnVuY3Rpb24obWFwKSB7XG4gICAgbWFwID0gT3JkZXJlZE1hcC5mcm9tKG1hcCk7XG4gICAgaWYgKCFtYXAuc2l6ZSkgcmV0dXJuIHRoaXNcbiAgICByZXR1cm4gbmV3IE9yZGVyZWRNYXAodGhpcy5zdWJ0cmFjdChtYXApLmNvbnRlbnQuY29uY2F0KG1hcC5jb250ZW50KSlcbiAgfSxcblxuICAvLyA6OiAodW5pb248T2JqZWN0LCBPcmRlcmVkTWFwPikgXHUyMTkyIE9yZGVyZWRNYXBcbiAgLy8gQ3JlYXRlIGEgbWFwIGNvbnRhaW5pbmcgYWxsIHRoZSBrZXlzIGluIHRoaXMgbWFwIHRoYXQgZG9uJ3RcbiAgLy8gYXBwZWFyIGluIGBtYXBgLlxuICBzdWJ0cmFjdDogZnVuY3Rpb24obWFwKSB7XG4gICAgdmFyIHJlc3VsdCA9IHRoaXM7XG4gICAgbWFwID0gT3JkZXJlZE1hcC5mcm9tKG1hcCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXAuY29udGVudC5sZW5ndGg7IGkgKz0gMilcbiAgICAgIHJlc3VsdCA9IHJlc3VsdC5yZW1vdmUobWFwLmNvbnRlbnRbaV0pO1xuICAgIHJldHVybiByZXN1bHRcbiAgfSxcblxuICAvLyA6OiAoKSBcdTIxOTIgT2JqZWN0XG4gIC8vIFR1cm4gb3JkZXJlZCBtYXAgaW50byBhIHBsYWluIG9iamVjdC5cbiAgdG9PYmplY3Q6IGZ1bmN0aW9uKCkge1xuICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24oa2V5LCB2YWx1ZSkgeyByZXN1bHRba2V5XSA9IHZhbHVlOyB9KTtcbiAgICByZXR1cm4gcmVzdWx0XG4gIH0sXG5cbiAgLy8gOjogbnVtYmVyXG4gIC8vIFRoZSBhbW91bnQgb2Yga2V5cyBpbiB0aGlzIG1hcC5cbiAgZ2V0IHNpemUoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29udGVudC5sZW5ndGggPj4gMVxuICB9XG59O1xuXG4vLyA6OiAoP3VuaW9uPE9iamVjdCwgT3JkZXJlZE1hcD4pIFx1MjE5MiBPcmRlcmVkTWFwXG4vLyBSZXR1cm4gYSBtYXAgd2l0aCB0aGUgZ2l2ZW4gY29udGVudC4gSWYgbnVsbCwgY3JlYXRlIGFuIGVtcHR5XG4vLyBtYXAuIElmIGdpdmVuIGFuIG9yZGVyZWQgbWFwLCByZXR1cm4gdGhhdCBtYXAgaXRzZWxmLiBJZiBnaXZlbiBhblxuLy8gb2JqZWN0LCBjcmVhdGUgYSBtYXAgZnJvbSB0aGUgb2JqZWN0J3MgcHJvcGVydGllcy5cbk9yZGVyZWRNYXAuZnJvbSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE9yZGVyZWRNYXApIHJldHVybiB2YWx1ZVxuICB2YXIgY29udGVudCA9IFtdO1xuICBpZiAodmFsdWUpIGZvciAodmFyIHByb3AgaW4gdmFsdWUpIGNvbnRlbnQucHVzaChwcm9wLCB2YWx1ZVtwcm9wXSk7XG4gIHJldHVybiBuZXcgT3JkZXJlZE1hcChjb250ZW50KVxufTtcblxuZXhwb3J0IGRlZmF1bHQgT3JkZXJlZE1hcDtcbiIsICJpbXBvcnQgT3JkZXJlZE1hcCBmcm9tICdvcmRlcmVkbWFwJztcblxuZnVuY3Rpb24gZmluZERpZmZTdGFydChhLCBiLCBwb3MpIHtcbiAgICBmb3IgKGxldCBpID0gMDs7IGkrKykge1xuICAgICAgICBpZiAoaSA9PSBhLmNoaWxkQ291bnQgfHwgaSA9PSBiLmNoaWxkQ291bnQpXG4gICAgICAgICAgICByZXR1cm4gYS5jaGlsZENvdW50ID09IGIuY2hpbGRDb3VudCA/IG51bGwgOiBwb3M7XG4gICAgICAgIGxldCBjaGlsZEEgPSBhLmNoaWxkKGkpLCBjaGlsZEIgPSBiLmNoaWxkKGkpO1xuICAgICAgICBpZiAoY2hpbGRBID09IGNoaWxkQikge1xuICAgICAgICAgICAgcG9zICs9IGNoaWxkQS5ub2RlU2l6ZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY2hpbGRBLnNhbWVNYXJrdXAoY2hpbGRCKSlcbiAgICAgICAgICAgIHJldHVybiBwb3M7XG4gICAgICAgIGlmIChjaGlsZEEuaXNUZXh0ICYmIGNoaWxkQS50ZXh0ICE9IGNoaWxkQi50ZXh0KSB7XG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgY2hpbGRBLnRleHRbal0gPT0gY2hpbGRCLnRleHRbal07IGorKylcbiAgICAgICAgICAgICAgICBwb3MrKztcbiAgICAgICAgICAgIHJldHVybiBwb3M7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoaWxkQS5jb250ZW50LnNpemUgfHwgY2hpbGRCLmNvbnRlbnQuc2l6ZSkge1xuICAgICAgICAgICAgbGV0IGlubmVyID0gZmluZERpZmZTdGFydChjaGlsZEEuY29udGVudCwgY2hpbGRCLmNvbnRlbnQsIHBvcyArIDEpO1xuICAgICAgICAgICAgaWYgKGlubmVyICE9IG51bGwpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGlubmVyO1xuICAgICAgICB9XG4gICAgICAgIHBvcyArPSBjaGlsZEEubm9kZVNpemU7XG4gICAgfVxufVxuZnVuY3Rpb24gZmluZERpZmZFbmQoYSwgYiwgcG9zQSwgcG9zQikge1xuICAgIGZvciAobGV0IGlBID0gYS5jaGlsZENvdW50LCBpQiA9IGIuY2hpbGRDb3VudDs7KSB7XG4gICAgICAgIGlmIChpQSA9PSAwIHx8IGlCID09IDApXG4gICAgICAgICAgICByZXR1cm4gaUEgPT0gaUIgPyBudWxsIDogeyBhOiBwb3NBLCBiOiBwb3NCIH07XG4gICAgICAgIGxldCBjaGlsZEEgPSBhLmNoaWxkKC0taUEpLCBjaGlsZEIgPSBiLmNoaWxkKC0taUIpLCBzaXplID0gY2hpbGRBLm5vZGVTaXplO1xuICAgICAgICBpZiAoY2hpbGRBID09IGNoaWxkQikge1xuICAgICAgICAgICAgcG9zQSAtPSBzaXplO1xuICAgICAgICAgICAgcG9zQiAtPSBzaXplO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjaGlsZEEuc2FtZU1hcmt1cChjaGlsZEIpKVxuICAgICAgICAgICAgcmV0dXJuIHsgYTogcG9zQSwgYjogcG9zQiB9O1xuICAgICAgICBpZiAoY2hpbGRBLmlzVGV4dCAmJiBjaGlsZEEudGV4dCAhPSBjaGlsZEIudGV4dCkge1xuICAgICAgICAgICAgbGV0IHNhbWUgPSAwLCBtaW5TaXplID0gTWF0aC5taW4oY2hpbGRBLnRleHQubGVuZ3RoLCBjaGlsZEIudGV4dC5sZW5ndGgpO1xuICAgICAgICAgICAgd2hpbGUgKHNhbWUgPCBtaW5TaXplICYmIGNoaWxkQS50ZXh0W2NoaWxkQS50ZXh0Lmxlbmd0aCAtIHNhbWUgLSAxXSA9PSBjaGlsZEIudGV4dFtjaGlsZEIudGV4dC5sZW5ndGggLSBzYW1lIC0gMV0pIHtcbiAgICAgICAgICAgICAgICBzYW1lKys7XG4gICAgICAgICAgICAgICAgcG9zQS0tO1xuICAgICAgICAgICAgICAgIHBvc0ItLTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7IGE6IHBvc0EsIGI6IHBvc0IgfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hpbGRBLmNvbnRlbnQuc2l6ZSB8fCBjaGlsZEIuY29udGVudC5zaXplKSB7XG4gICAgICAgICAgICBsZXQgaW5uZXIgPSBmaW5kRGlmZkVuZChjaGlsZEEuY29udGVudCwgY2hpbGRCLmNvbnRlbnQsIHBvc0EgLSAxLCBwb3NCIC0gMSk7XG4gICAgICAgICAgICBpZiAoaW5uZXIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGlubmVyO1xuICAgICAgICB9XG4gICAgICAgIHBvc0EgLT0gc2l6ZTtcbiAgICAgICAgcG9zQiAtPSBzaXplO1xuICAgIH1cbn1cblxuLyoqXG5BIGZyYWdtZW50IHJlcHJlc2VudHMgYSBub2RlJ3MgY29sbGVjdGlvbiBvZiBjaGlsZCBub2Rlcy5cblxuTGlrZSBub2RlcywgZnJhZ21lbnRzIGFyZSBwZXJzaXN0ZW50IGRhdGEgc3RydWN0dXJlcywgYW5kIHlvdVxuc2hvdWxkIG5vdCBtdXRhdGUgdGhlbSBvciB0aGVpciBjb250ZW50LiBSYXRoZXIsIHlvdSBjcmVhdGUgbmV3XG5pbnN0YW5jZXMgd2hlbmV2ZXIgbmVlZGVkLiBUaGUgQVBJIHRyaWVzIHRvIG1ha2UgdGhpcyBlYXN5LlxuKi9cbmNsYXNzIEZyYWdtZW50IHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBjaGlsZCBub2RlcyBpbiB0aGlzIGZyYWdtZW50LlxuICAgICovXG4gICAgY29udGVudCwgc2l6ZSkge1xuICAgICAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuICAgICAgICB0aGlzLnNpemUgPSBzaXplIHx8IDA7XG4gICAgICAgIGlmIChzaXplID09IG51bGwpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnRlbnQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgdGhpcy5zaXplICs9IGNvbnRlbnRbaV0ubm9kZVNpemU7XG4gICAgfVxuICAgIC8qKlxuICAgIEludm9rZSBhIGNhbGxiYWNrIGZvciBhbGwgZGVzY2VuZGFudCBub2RlcyBiZXR3ZWVuIHRoZSBnaXZlbiB0d29cbiAgICBwb3NpdGlvbnMgKHJlbGF0aXZlIHRvIHN0YXJ0IG9mIHRoaXMgZnJhZ21lbnQpLiBEb2Vzbid0IGRlc2NlbmRcbiAgICBpbnRvIGEgbm9kZSB3aGVuIHRoZSBjYWxsYmFjayByZXR1cm5zIGBmYWxzZWAuXG4gICAgKi9cbiAgICBub2Rlc0JldHdlZW4oZnJvbSwgdG8sIGYsIG5vZGVTdGFydCA9IDAsIHBhcmVudCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgcG9zID0gMDsgcG9zIDwgdG87IGkrKykge1xuICAgICAgICAgICAgbGV0IGNoaWxkID0gdGhpcy5jb250ZW50W2ldLCBlbmQgPSBwb3MgKyBjaGlsZC5ub2RlU2l6ZTtcbiAgICAgICAgICAgIGlmIChlbmQgPiBmcm9tICYmIGYoY2hpbGQsIG5vZGVTdGFydCArIHBvcywgcGFyZW50IHx8IG51bGwsIGkpICE9PSBmYWxzZSAmJiBjaGlsZC5jb250ZW50LnNpemUpIHtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSBwb3MgKyAxO1xuICAgICAgICAgICAgICAgIGNoaWxkLm5vZGVzQmV0d2VlbihNYXRoLm1heCgwLCBmcm9tIC0gc3RhcnQpLCBNYXRoLm1pbihjaGlsZC5jb250ZW50LnNpemUsIHRvIC0gc3RhcnQpLCBmLCBub2RlU3RhcnQgKyBzdGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwb3MgPSBlbmQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgQ2FsbCB0aGUgZ2l2ZW4gY2FsbGJhY2sgZm9yIGV2ZXJ5IGRlc2NlbmRhbnQgbm9kZS4gYHBvc2Agd2lsbCBiZVxuICAgIHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgZnJhZ21lbnQuIFRoZSBjYWxsYmFjayBtYXkgcmV0dXJuXG4gICAgYGZhbHNlYCB0byBwcmV2ZW50IHRyYXZlcnNhbCBvZiBhIGdpdmVuIG5vZGUncyBjaGlsZHJlbi5cbiAgICAqL1xuICAgIGRlc2NlbmRhbnRzKGYpIHtcbiAgICAgICAgdGhpcy5ub2Rlc0JldHdlZW4oMCwgdGhpcy5zaXplLCBmKTtcbiAgICB9XG4gICAgLyoqXG4gICAgRXh0cmFjdCB0aGUgdGV4dCBiZXR3ZWVuIGBmcm9tYCBhbmQgYHRvYC4gU2VlIHRoZSBzYW1lIG1ldGhvZCBvblxuICAgIFtgTm9kZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlLnRleHRCZXR3ZWVuKS5cbiAgICAqL1xuICAgIHRleHRCZXR3ZWVuKGZyb20sIHRvLCBibG9ja1NlcGFyYXRvciwgbGVhZlRleHQpIHtcbiAgICAgICAgbGV0IHRleHQgPSBcIlwiLCBmaXJzdCA9IHRydWU7XG4gICAgICAgIHRoaXMubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgICAgICBsZXQgbm9kZVRleHQgPSBub2RlLmlzVGV4dCA/IG5vZGUudGV4dC5zbGljZShNYXRoLm1heChmcm9tLCBwb3MpIC0gcG9zLCB0byAtIHBvcylcbiAgICAgICAgICAgICAgICA6ICFub2RlLmlzTGVhZiA/IFwiXCJcbiAgICAgICAgICAgICAgICAgICAgOiBsZWFmVGV4dCA/ICh0eXBlb2YgbGVhZlRleHQgPT09IFwiZnVuY3Rpb25cIiA/IGxlYWZUZXh0KG5vZGUpIDogbGVhZlRleHQpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IG5vZGUudHlwZS5zcGVjLmxlYWZUZXh0ID8gbm9kZS50eXBlLnNwZWMubGVhZlRleHQobm9kZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IFwiXCI7XG4gICAgICAgICAgICBpZiAobm9kZS5pc0Jsb2NrICYmIChub2RlLmlzTGVhZiAmJiBub2RlVGV4dCB8fCBub2RlLmlzVGV4dGJsb2NrKSAmJiBibG9ja1NlcGFyYXRvcikge1xuICAgICAgICAgICAgICAgIGlmIChmaXJzdClcbiAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIHRleHQgKz0gYmxvY2tTZXBhcmF0b3I7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0ZXh0ICs9IG5vZGVUZXh0O1xuICAgICAgICB9LCAwKTtcbiAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5ldyBmcmFnbWVudCBjb250YWluaW5nIHRoZSBjb21iaW5lZCBjb250ZW50IG9mIHRoaXNcbiAgICBmcmFnbWVudCBhbmQgdGhlIG90aGVyLlxuICAgICovXG4gICAgYXBwZW5kKG90aGVyKSB7XG4gICAgICAgIGlmICghb3RoZXIuc2l6ZSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICBpZiAoIXRoaXMuc2l6ZSlcbiAgICAgICAgICAgIHJldHVybiBvdGhlcjtcbiAgICAgICAgbGV0IGxhc3QgPSB0aGlzLmxhc3RDaGlsZCwgZmlyc3QgPSBvdGhlci5maXJzdENoaWxkLCBjb250ZW50ID0gdGhpcy5jb250ZW50LnNsaWNlKCksIGkgPSAwO1xuICAgICAgICBpZiAobGFzdC5pc1RleHQgJiYgbGFzdC5zYW1lTWFya3VwKGZpcnN0KSkge1xuICAgICAgICAgICAgY29udGVudFtjb250ZW50Lmxlbmd0aCAtIDFdID0gbGFzdC53aXRoVGV4dChsYXN0LnRleHQgKyBmaXJzdC50ZXh0KTtcbiAgICAgICAgICAgIGkgPSAxO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoOyBpIDwgb3RoZXIuY29udGVudC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGNvbnRlbnQucHVzaChvdGhlci5jb250ZW50W2ldKTtcbiAgICAgICAgcmV0dXJuIG5ldyBGcmFnbWVudChjb250ZW50LCB0aGlzLnNpemUgKyBvdGhlci5zaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3V0IG91dCB0aGUgc3ViLWZyYWdtZW50IGJldHdlZW4gdGhlIHR3byBnaXZlbiBwb3NpdGlvbnMuXG4gICAgKi9cbiAgICBjdXQoZnJvbSwgdG8gPSB0aGlzLnNpemUpIHtcbiAgICAgICAgaWYgKGZyb20gPT0gMCAmJiB0byA9PSB0aGlzLnNpemUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgbGV0IHJlc3VsdCA9IFtdLCBzaXplID0gMDtcbiAgICAgICAgaWYgKHRvID4gZnJvbSlcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwLCBwb3MgPSAwOyBwb3MgPCB0bzsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNoaWxkID0gdGhpcy5jb250ZW50W2ldLCBlbmQgPSBwb3MgKyBjaGlsZC5ub2RlU2l6ZTtcbiAgICAgICAgICAgICAgICBpZiAoZW5kID4gZnJvbSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAocG9zIDwgZnJvbSB8fCBlbmQgPiB0bykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLmlzVGV4dClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmN1dChNYXRoLm1heCgwLCBmcm9tIC0gcG9zKSwgTWF0aC5taW4oY2hpbGQudGV4dC5sZW5ndGgsIHRvIC0gcG9zKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5jdXQoTWF0aC5tYXgoMCwgZnJvbSAtIHBvcyAtIDEpLCBNYXRoLm1pbihjaGlsZC5jb250ZW50LnNpemUsIHRvIC0gcG9zIC0gMSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGNoaWxkKTtcbiAgICAgICAgICAgICAgICAgICAgc2l6ZSArPSBjaGlsZC5ub2RlU2l6ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcG9zID0gZW5kO1xuICAgICAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IEZyYWdtZW50KHJlc3VsdCwgc2l6ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY3V0QnlJbmRleChmcm9tLCB0bykge1xuICAgICAgICBpZiAoZnJvbSA9PSB0bylcbiAgICAgICAgICAgIHJldHVybiBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgaWYgKGZyb20gPT0gMCAmJiB0byA9PSB0aGlzLmNvbnRlbnQubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIHJldHVybiBuZXcgRnJhZ21lbnQodGhpcy5jb250ZW50LnNsaWNlKGZyb20sIHRvKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5ldyBmcmFnbWVudCBpbiB3aGljaCB0aGUgbm9kZSBhdCB0aGUgZ2l2ZW4gaW5kZXggaXNcbiAgICByZXBsYWNlZCBieSB0aGUgZ2l2ZW4gbm9kZS5cbiAgICAqL1xuICAgIHJlcGxhY2VDaGlsZChpbmRleCwgbm9kZSkge1xuICAgICAgICBsZXQgY3VycmVudCA9IHRoaXMuY29udGVudFtpbmRleF07XG4gICAgICAgIGlmIChjdXJyZW50ID09IG5vZGUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgbGV0IGNvcHkgPSB0aGlzLmNvbnRlbnQuc2xpY2UoKTtcbiAgICAgICAgbGV0IHNpemUgPSB0aGlzLnNpemUgKyBub2RlLm5vZGVTaXplIC0gY3VycmVudC5ub2RlU2l6ZTtcbiAgICAgICAgY29weVtpbmRleF0gPSBub2RlO1xuICAgICAgICByZXR1cm4gbmV3IEZyYWdtZW50KGNvcHksIHNpemUpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBuZXcgZnJhZ21lbnQgYnkgcHJlcGVuZGluZyB0aGUgZ2l2ZW4gbm9kZSB0byB0aGlzXG4gICAgZnJhZ21lbnQuXG4gICAgKi9cbiAgICBhZGRUb1N0YXJ0KG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGcmFnbWVudChbbm9kZV0uY29uY2F0KHRoaXMuY29udGVudCksIHRoaXMuc2l6ZSArIG5vZGUubm9kZVNpemUpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBuZXcgZnJhZ21lbnQgYnkgYXBwZW5kaW5nIHRoZSBnaXZlbiBub2RlIHRvIHRoaXNcbiAgICBmcmFnbWVudC5cbiAgICAqL1xuICAgIGFkZFRvRW5kKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGcmFnbWVudCh0aGlzLmNvbnRlbnQuY29uY2F0KG5vZGUpLCB0aGlzLnNpemUgKyBub2RlLm5vZGVTaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ29tcGFyZSB0aGlzIGZyYWdtZW50IHRvIGFub3RoZXIgb25lLlxuICAgICovXG4gICAgZXEob3RoZXIpIHtcbiAgICAgICAgaWYgKHRoaXMuY29udGVudC5sZW5ndGggIT0gb3RoZXIuY29udGVudC5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jb250ZW50Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKCF0aGlzLmNvbnRlbnRbaV0uZXEob3RoZXIuY29udGVudFtpXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIGZpcnN0IGNoaWxkIG9mIHRoZSBmcmFnbWVudCwgb3IgYG51bGxgIGlmIGl0IGlzIGVtcHR5LlxuICAgICovXG4gICAgZ2V0IGZpcnN0Q2hpbGQoKSB7IHJldHVybiB0aGlzLmNvbnRlbnQubGVuZ3RoID8gdGhpcy5jb250ZW50WzBdIDogbnVsbDsgfVxuICAgIC8qKlxuICAgIFRoZSBsYXN0IGNoaWxkIG9mIHRoZSBmcmFnbWVudCwgb3IgYG51bGxgIGlmIGl0IGlzIGVtcHR5LlxuICAgICovXG4gICAgZ2V0IGxhc3RDaGlsZCgpIHsgcmV0dXJuIHRoaXMuY29udGVudC5sZW5ndGggPyB0aGlzLmNvbnRlbnRbdGhpcy5jb250ZW50Lmxlbmd0aCAtIDFdIDogbnVsbDsgfVxuICAgIC8qKlxuICAgIFRoZSBudW1iZXIgb2YgY2hpbGQgbm9kZXMgaW4gdGhpcyBmcmFnbWVudC5cbiAgICAqL1xuICAgIGdldCBjaGlsZENvdW50KCkgeyByZXR1cm4gdGhpcy5jb250ZW50Lmxlbmd0aDsgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgY2hpbGQgbm9kZSBhdCB0aGUgZ2l2ZW4gaW5kZXguIFJhaXNlIGFuIGVycm9yIHdoZW4gdGhlXG4gICAgaW5kZXggaXMgb3V0IG9mIHJhbmdlLlxuICAgICovXG4gICAgY2hpbGQoaW5kZXgpIHtcbiAgICAgICAgbGV0IGZvdW5kID0gdGhpcy5jb250ZW50W2luZGV4XTtcbiAgICAgICAgaWYgKCFmb3VuZClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW5kZXggXCIgKyBpbmRleCArIFwiIG91dCBvZiByYW5nZSBmb3IgXCIgKyB0aGlzKTtcbiAgICAgICAgcmV0dXJuIGZvdW5kO1xuICAgIH1cbiAgICAvKipcbiAgICBHZXQgdGhlIGNoaWxkIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4LCBpZiBpdCBleGlzdHMuXG4gICAgKi9cbiAgICBtYXliZUNoaWxkKGluZGV4KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRlbnRbaW5kZXhdIHx8IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIENhbGwgYGZgIGZvciBldmVyeSBjaGlsZCBub2RlLCBwYXNzaW5nIHRoZSBub2RlLCBpdHMgb2Zmc2V0XG4gICAgaW50byB0aGlzIHBhcmVudCBub2RlLCBhbmQgaXRzIGluZGV4LlxuICAgICovXG4gICAgZm9yRWFjaChmKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBwID0gMDsgaSA8IHRoaXMuY29udGVudC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGNoaWxkID0gdGhpcy5jb250ZW50W2ldO1xuICAgICAgICAgICAgZihjaGlsZCwgcCwgaSk7XG4gICAgICAgICAgICBwICs9IGNoaWxkLm5vZGVTaXplO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgdGhlIGZpcnN0IHBvc2l0aW9uIGF0IHdoaWNoIHRoaXMgZnJhZ21lbnQgYW5kIGFub3RoZXJcbiAgICBmcmFnbWVudCBkaWZmZXIsIG9yIGBudWxsYCBpZiB0aGV5IGFyZSB0aGUgc2FtZS5cbiAgICAqL1xuICAgIGZpbmREaWZmU3RhcnQob3RoZXIsIHBvcyA9IDApIHtcbiAgICAgICAgcmV0dXJuIGZpbmREaWZmU3RhcnQodGhpcywgb3RoZXIsIHBvcyk7XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgdGhlIGZpcnN0IHBvc2l0aW9uLCBzZWFyY2hpbmcgZnJvbSB0aGUgZW5kLCBhdCB3aGljaCB0aGlzXG4gICAgZnJhZ21lbnQgYW5kIHRoZSBnaXZlbiBmcmFnbWVudCBkaWZmZXIsIG9yIGBudWxsYCBpZiB0aGV5IGFyZVxuICAgIHRoZSBzYW1lLiBTaW5jZSB0aGlzIHBvc2l0aW9uIHdpbGwgbm90IGJlIHRoZSBzYW1lIGluIGJvdGhcbiAgICBub2RlcywgYW4gb2JqZWN0IHdpdGggdHdvIHNlcGFyYXRlIHBvc2l0aW9ucyBpcyByZXR1cm5lZC5cbiAgICAqL1xuICAgIGZpbmREaWZmRW5kKG90aGVyLCBwb3MgPSB0aGlzLnNpemUsIG90aGVyUG9zID0gb3RoZXIuc2l6ZSkge1xuICAgICAgICByZXR1cm4gZmluZERpZmZFbmQodGhpcywgb3RoZXIsIHBvcywgb3RoZXJQb3MpO1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSBpbmRleCBhbmQgaW5uZXIgb2Zmc2V0IGNvcnJlc3BvbmRpbmcgdG8gYSBnaXZlbiByZWxhdGl2ZVxuICAgIHBvc2l0aW9uIGluIHRoaXMgZnJhZ21lbnQuIFRoZSByZXN1bHQgb2JqZWN0IHdpbGwgYmUgcmV1c2VkXG4gICAgKG92ZXJ3cml0dGVuKSB0aGUgbmV4dCB0aW1lIHRoZSBmdW5jdGlvbiBpcyBjYWxsZWQuIEBpbnRlcm5hbFxuICAgICovXG4gICAgZmluZEluZGV4KHBvcykge1xuICAgICAgICBpZiAocG9zID09IDApXG4gICAgICAgICAgICByZXR1cm4gcmV0SW5kZXgoMCwgcG9zKTtcbiAgICAgICAgaWYgKHBvcyA9PSB0aGlzLnNpemUpXG4gICAgICAgICAgICByZXR1cm4gcmV0SW5kZXgodGhpcy5jb250ZW50Lmxlbmd0aCwgcG9zKTtcbiAgICAgICAgaWYgKHBvcyA+IHRoaXMuc2l6ZSB8fCBwb3MgPCAwKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYFBvc2l0aW9uICR7cG9zfSBvdXRzaWRlIG9mIGZyYWdtZW50ICgke3RoaXN9KWApO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgY3VyUG9zID0gMDs7IGkrKykge1xuICAgICAgICAgICAgbGV0IGN1ciA9IHRoaXMuY2hpbGQoaSksIGVuZCA9IGN1clBvcyArIGN1ci5ub2RlU2l6ZTtcbiAgICAgICAgICAgIGlmIChlbmQgPj0gcG9zKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVuZCA9PSBwb3MpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXRJbmRleChpICsgMSwgZW5kKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0SW5kZXgoaSwgY3VyUG9zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN1clBvcyA9IGVuZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm4gYSBkZWJ1Z2dpbmcgc3RyaW5nIHRoYXQgZGVzY3JpYmVzIHRoaXMgZnJhZ21lbnQuXG4gICAgKi9cbiAgICB0b1N0cmluZygpIHsgcmV0dXJuIFwiPFwiICsgdGhpcy50b1N0cmluZ0lubmVyKCkgKyBcIj5cIjsgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgdG9TdHJpbmdJbm5lcigpIHsgcmV0dXJuIHRoaXMuY29udGVudC5qb2luKFwiLCBcIik7IH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBKU09OLXNlcmlhbGl6ZWFibGUgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBmcmFnbWVudC5cbiAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudC5sZW5ndGggPyB0aGlzLmNvbnRlbnQubWFwKG4gPT4gbi50b0pTT04oKSkgOiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBEZXNlcmlhbGl6ZSBhIGZyYWdtZW50IGZyb20gaXRzIEpTT04gcmVwcmVzZW50YXRpb24uXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCB2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKVxuICAgICAgICAgICAgcmV0dXJuIEZyYWdtZW50LmVtcHR5O1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBGcmFnbWVudC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIEZyYWdtZW50LmZyb21BcnJheSh2YWx1ZS5tYXAoc2NoZW1hLm5vZGVGcm9tSlNPTikpO1xuICAgIH1cbiAgICAvKipcbiAgICBCdWlsZCBhIGZyYWdtZW50IGZyb20gYW4gYXJyYXkgb2Ygbm9kZXMuIEVuc3VyZXMgdGhhdCBhZGphY2VudFxuICAgIHRleHQgbm9kZXMgd2l0aCB0aGUgc2FtZSBtYXJrcyBhcmUgam9pbmVkIHRvZ2V0aGVyLlxuICAgICovXG4gICAgc3RhdGljIGZyb21BcnJheShhcnJheSkge1xuICAgICAgICBpZiAoIWFycmF5Lmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgbGV0IGpvaW5lZCwgc2l6ZSA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBub2RlID0gYXJyYXlbaV07XG4gICAgICAgICAgICBzaXplICs9IG5vZGUubm9kZVNpemU7XG4gICAgICAgICAgICBpZiAoaSAmJiBub2RlLmlzVGV4dCAmJiBhcnJheVtpIC0gMV0uc2FtZU1hcmt1cChub2RlKSkge1xuICAgICAgICAgICAgICAgIGlmICgham9pbmVkKVxuICAgICAgICAgICAgICAgICAgICBqb2luZWQgPSBhcnJheS5zbGljZSgwLCBpKTtcbiAgICAgICAgICAgICAgICBqb2luZWRbam9pbmVkLmxlbmd0aCAtIDFdID0gbm9kZVxuICAgICAgICAgICAgICAgICAgICAud2l0aFRleHQoam9pbmVkW2pvaW5lZC5sZW5ndGggLSAxXS50ZXh0ICsgbm9kZS50ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGpvaW5lZCkge1xuICAgICAgICAgICAgICAgIGpvaW5lZC5wdXNoKG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgRnJhZ21lbnQoam9pbmVkIHx8IGFycmF5LCBzaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgZnJhZ21lbnQgZnJvbSBzb21ldGhpbmcgdGhhdCBjYW4gYmUgaW50ZXJwcmV0ZWQgYXMgYVxuICAgIHNldCBvZiBub2Rlcy4gRm9yIGBudWxsYCwgaXQgcmV0dXJucyB0aGUgZW1wdHkgZnJhZ21lbnQuIEZvciBhXG4gICAgZnJhZ21lbnQsIHRoZSBmcmFnbWVudCBpdHNlbGYuIEZvciBhIG5vZGUgb3IgYXJyYXkgb2Ygbm9kZXMsIGFcbiAgICBmcmFnbWVudCBjb250YWluaW5nIHRob3NlIG5vZGVzLlxuICAgICovXG4gICAgc3RhdGljIGZyb20obm9kZXMpIHtcbiAgICAgICAgaWYgKCFub2RlcylcbiAgICAgICAgICAgIHJldHVybiBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgaWYgKG5vZGVzIGluc3RhbmNlb2YgRnJhZ21lbnQpXG4gICAgICAgICAgICByZXR1cm4gbm9kZXM7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG5vZGVzKSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZyb21BcnJheShub2Rlcyk7XG4gICAgICAgIGlmIChub2Rlcy5hdHRycylcbiAgICAgICAgICAgIHJldHVybiBuZXcgRnJhZ21lbnQoW25vZGVzXSwgbm9kZXMubm9kZVNpemUpO1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkNhbiBub3QgY29udmVydCBcIiArIG5vZGVzICsgXCIgdG8gYSBGcmFnbWVudFwiICtcbiAgICAgICAgICAgIChub2Rlcy5ub2Rlc0JldHdlZW4gPyBcIiAobG9va3MgbGlrZSBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBwcm9zZW1pcnJvci1tb2RlbCB3ZXJlIGxvYWRlZClcIiA6IFwiXCIpKTtcbiAgICB9XG59XG4vKipcbkFuIGVtcHR5IGZyYWdtZW50LiBJbnRlbmRlZCB0byBiZSByZXVzZWQgd2hlbmV2ZXIgYSBub2RlIGRvZXNuJ3RcbmNvbnRhaW4gYW55dGhpbmcgKHJhdGhlciB0aGFuIGFsbG9jYXRpbmcgYSBuZXcgZW1wdHkgZnJhZ21lbnQgZm9yXG5lYWNoIGxlYWYgbm9kZSkuXG4qL1xuRnJhZ21lbnQuZW1wdHkgPSBuZXcgRnJhZ21lbnQoW10sIDApO1xuY29uc3QgZm91bmQgPSB7IGluZGV4OiAwLCBvZmZzZXQ6IDAgfTtcbmZ1bmN0aW9uIHJldEluZGV4KGluZGV4LCBvZmZzZXQpIHtcbiAgICBmb3VuZC5pbmRleCA9IGluZGV4O1xuICAgIGZvdW5kLm9mZnNldCA9IG9mZnNldDtcbiAgICByZXR1cm4gZm91bmQ7XG59XG5cbmZ1bmN0aW9uIGNvbXBhcmVEZWVwKGEsIGIpIHtcbiAgICBpZiAoYSA9PT0gYilcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgaWYgKCEoYSAmJiB0eXBlb2YgYSA9PSBcIm9iamVjdFwiKSB8fFxuICAgICAgICAhKGIgJiYgdHlwZW9mIGIgPT0gXCJvYmplY3RcIikpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgYXJyYXkgPSBBcnJheS5pc0FycmF5KGEpO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGIpICE9IGFycmF5KVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGFycmF5KSB7XG4gICAgICAgIGlmIChhLmxlbmd0aCAhPSBiLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKCFjb21wYXJlRGVlcChhW2ldLCBiW2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBmb3IgKGxldCBwIGluIGEpXG4gICAgICAgICAgICBpZiAoIShwIGluIGIpIHx8ICFjb21wYXJlRGVlcChhW3BdLCBiW3BdKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IHAgaW4gYilcbiAgICAgICAgICAgIGlmICghKHAgaW4gYSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG5BIG1hcmsgaXMgYSBwaWVjZSBvZiBpbmZvcm1hdGlvbiB0aGF0IGNhbiBiZSBhdHRhY2hlZCB0byBhIG5vZGUsXG5zdWNoIGFzIGl0IGJlaW5nIGVtcGhhc2l6ZWQsIGluIGNvZGUgZm9udCwgb3IgYSBsaW5rLiBJdCBoYXMgYVxudHlwZSBhbmQgb3B0aW9uYWxseSBhIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgcHJvdmlkZSBmdXJ0aGVyXG5pbmZvcm1hdGlvbiAoc3VjaCBhcyB0aGUgdGFyZ2V0IG9mIHRoZSBsaW5rKS4gTWFya3MgYXJlIGNyZWF0ZWRcbnRocm91Z2ggYSBgU2NoZW1hYCwgd2hpY2ggY29udHJvbHMgd2hpY2ggdHlwZXMgZXhpc3QgYW5kIHdoaWNoXG5hdHRyaWJ1dGVzIHRoZXkgaGF2ZS5cbiovXG5jbGFzcyBNYXJrIHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSB0eXBlIG9mIHRoaXMgbWFyay5cbiAgICAqL1xuICAgIHR5cGUsIFxuICAgIC8qKlxuICAgIFRoZSBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1hcmsuXG4gICAgKi9cbiAgICBhdHRycykge1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLmF0dHJzID0gYXR0cnM7XG4gICAgfVxuICAgIC8qKlxuICAgIEdpdmVuIGEgc2V0IG9mIG1hcmtzLCBjcmVhdGUgYSBuZXcgc2V0IHdoaWNoIGNvbnRhaW5zIHRoaXMgb25lIGFzXG4gICAgd2VsbCwgaW4gdGhlIHJpZ2h0IHBvc2l0aW9uLiBJZiB0aGlzIG1hcmsgaXMgYWxyZWFkeSBpbiB0aGUgc2V0LFxuICAgIHRoZSBzZXQgaXRzZWxmIGlzIHJldHVybmVkLiBJZiBhbnkgbWFya3MgdGhhdCBhcmUgc2V0IHRvIGJlXG4gICAgW2V4Y2x1c2l2ZV0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk1hcmtTcGVjLmV4Y2x1ZGVzKSB3aXRoIHRoaXMgbWFyayBhcmUgcHJlc2VudCxcbiAgICB0aG9zZSBhcmUgcmVwbGFjZWQgYnkgdGhpcyBvbmUuXG4gICAgKi9cbiAgICBhZGRUb1NldChzZXQpIHtcbiAgICAgICAgbGV0IGNvcHksIHBsYWNlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG90aGVyID0gc2V0W2ldO1xuICAgICAgICAgICAgaWYgKHRoaXMuZXEob3RoZXIpKVxuICAgICAgICAgICAgICAgIHJldHVybiBzZXQ7XG4gICAgICAgICAgICBpZiAodGhpcy50eXBlLmV4Y2x1ZGVzKG90aGVyLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjb3B5KVxuICAgICAgICAgICAgICAgICAgICBjb3B5ID0gc2V0LnNsaWNlKDAsIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAob3RoZXIudHlwZS5leGNsdWRlcyh0aGlzLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNldDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghcGxhY2VkICYmIG90aGVyLnR5cGUucmFuayA+IHRoaXMudHlwZS5yYW5rKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY29weSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvcHkgPSBzZXQuc2xpY2UoMCwgaSk7XG4gICAgICAgICAgICAgICAgICAgIGNvcHkucHVzaCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgcGxhY2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNvcHkpXG4gICAgICAgICAgICAgICAgICAgIGNvcHkucHVzaChvdGhlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjb3B5KVxuICAgICAgICAgICAgY29weSA9IHNldC5zbGljZSgpO1xuICAgICAgICBpZiAoIXBsYWNlZClcbiAgICAgICAgICAgIGNvcHkucHVzaCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIGNvcHk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlbW92ZSB0aGlzIG1hcmsgZnJvbSB0aGUgZ2l2ZW4gc2V0LCByZXR1cm5pbmcgYSBuZXcgc2V0LiBJZiB0aGlzXG4gICAgbWFyayBpcyBub3QgaW4gdGhlIHNldCwgdGhlIHNldCBpdHNlbGYgaXMgcmV0dXJuZWQuXG4gICAgKi9cbiAgICByZW1vdmVGcm9tU2V0KHNldCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmICh0aGlzLmVxKHNldFtpXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNldC5zbGljZSgwLCBpKS5jb25jYXQoc2V0LnNsaWNlKGkgKyAxKSk7XG4gICAgICAgIHJldHVybiBzZXQ7XG4gICAgfVxuICAgIC8qKlxuICAgIFRlc3Qgd2hldGhlciB0aGlzIG1hcmsgaXMgaW4gdGhlIGdpdmVuIHNldCBvZiBtYXJrcy5cbiAgICAqL1xuICAgIGlzSW5TZXQoc2V0KSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2V0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKHRoaXMuZXEoc2V0W2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgdGhpcyBtYXJrIGhhcyB0aGUgc2FtZSB0eXBlIGFuZCBhdHRyaWJ1dGVzIGFzXG4gICAgYW5vdGhlciBtYXJrLlxuICAgICovXG4gICAgZXEob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXIgfHxcbiAgICAgICAgICAgICh0aGlzLnR5cGUgPT0gb3RoZXIudHlwZSAmJiBjb21wYXJlRGVlcCh0aGlzLmF0dHJzLCBvdGhlci5hdHRycykpO1xuICAgIH1cbiAgICAvKipcbiAgICBDb252ZXJ0IHRoaXMgbWFyayB0byBhIEpTT04tc2VyaWFsaXplYWJsZSByZXByZXNlbnRhdGlvbi5cbiAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgbGV0IG9iaiA9IHsgdHlwZTogdGhpcy50eXBlLm5hbWUgfTtcbiAgICAgICAgZm9yIChsZXQgXyBpbiB0aGlzLmF0dHJzKSB7XG4gICAgICAgICAgICBvYmouYXR0cnMgPSB0aGlzLmF0dHJzO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG4gICAgLyoqXG4gICAgRGVzZXJpYWxpemUgYSBtYXJrIGZyb20gSlNPTi5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBNYXJrLmZyb21KU09OXCIpO1xuICAgICAgICBsZXQgdHlwZSA9IHNjaGVtYS5tYXJrc1tqc29uLnR5cGVdO1xuICAgICAgICBpZiAoIXR5cGUpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgVGhlcmUgaXMgbm8gbWFyayB0eXBlICR7anNvbi50eXBlfSBpbiB0aGlzIHNjaGVtYWApO1xuICAgICAgICBsZXQgbWFyayA9IHR5cGUuY3JlYXRlKGpzb24uYXR0cnMpO1xuICAgICAgICB0eXBlLmNoZWNrQXR0cnMobWFyay5hdHRycyk7XG4gICAgICAgIHJldHVybiBtYXJrO1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgdHdvIHNldHMgb2YgbWFya3MgYXJlIGlkZW50aWNhbC5cbiAgICAqL1xuICAgIHN0YXRpYyBzYW1lU2V0KGEsIGIpIHtcbiAgICAgICAgaWYgKGEgPT0gYilcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAoYS5sZW5ndGggIT0gYi5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmICghYVtpXS5lcShiW2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBwcm9wZXJseSBzb3J0ZWQgbWFyayBzZXQgZnJvbSBudWxsLCBhIHNpbmdsZSBtYXJrLCBvciBhblxuICAgIHVuc29ydGVkIGFycmF5IG9mIG1hcmtzLlxuICAgICovXG4gICAgc3RhdGljIHNldEZyb20obWFya3MpIHtcbiAgICAgICAgaWYgKCFtYXJrcyB8fCBBcnJheS5pc0FycmF5KG1hcmtzKSAmJiBtYXJrcy5sZW5ndGggPT0gMClcbiAgICAgICAgICAgIHJldHVybiBNYXJrLm5vbmU7XG4gICAgICAgIGlmIChtYXJrcyBpbnN0YW5jZW9mIE1hcmspXG4gICAgICAgICAgICByZXR1cm4gW21hcmtzXTtcbiAgICAgICAgbGV0IGNvcHkgPSBtYXJrcy5zbGljZSgpO1xuICAgICAgICBjb3B5LnNvcnQoKGEsIGIpID0+IGEudHlwZS5yYW5rIC0gYi50eXBlLnJhbmspO1xuICAgICAgICByZXR1cm4gY29weTtcbiAgICB9XG59XG4vKipcblRoZSBlbXB0eSBzZXQgb2YgbWFya3MuXG4qL1xuTWFyay5ub25lID0gW107XG5cbi8qKlxuRXJyb3IgdHlwZSByYWlzZWQgYnkgW2BOb2RlLnJlcGxhY2VgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZS5yZXBsYWNlKSB3aGVuXG5naXZlbiBhbiBpbnZhbGlkIHJlcGxhY2VtZW50LlxuKi9cbmNsYXNzIFJlcGxhY2VFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbi8qKlxuQSBzbGljZSByZXByZXNlbnRzIGEgcGllY2UgY3V0IG91dCBvZiBhIGxhcmdlciBkb2N1bWVudC4gSXRcbnN0b3JlcyBub3Qgb25seSBhIGZyYWdtZW50LCBidXQgYWxzbyB0aGUgZGVwdGggdXAgdG8gd2hpY2ggbm9kZXMgb25cbmJvdGggc2lkZSBhcmUgXHUyMDE4b3Blblx1MjAxOSAoY3V0IHRocm91Z2gpLlxuKi9cbmNsYXNzIFNsaWNlIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBzbGljZS4gV2hlbiBzcGVjaWZ5aW5nIGEgbm9uLXplcm8gb3BlbiBkZXB0aCwgeW91IG11c3RcbiAgICBtYWtlIHN1cmUgdGhhdCB0aGVyZSBhcmUgbm9kZXMgb2YgYXQgbGVhc3QgdGhhdCBkZXB0aCBhdCB0aGVcbiAgICBhcHByb3ByaWF0ZSBzaWRlIG9mIHRoZSBmcmFnbWVudFx1MjAxNGkuZS4gaWYgdGhlIGZyYWdtZW50IGlzIGFuXG4gICAgZW1wdHkgcGFyYWdyYXBoIG5vZGUsIGBvcGVuU3RhcnRgIGFuZCBgb3BlbkVuZGAgY2FuJ3QgYmUgZ3JlYXRlclxuICAgIHRoYW4gMS5cbiAgICBcbiAgICBJdCBpcyBub3QgbmVjZXNzYXJ5IGZvciB0aGUgY29udGVudCBvZiBvcGVuIG5vZGVzIHRvIGNvbmZvcm0gdG9cbiAgICB0aGUgc2NoZW1hJ3MgY29udGVudCBjb25zdHJhaW50cywgdGhvdWdoIGl0IHNob3VsZCBiZSBhIHZhbGlkXG4gICAgc3RhcnQvZW5kL21pZGRsZSBmb3Igc3VjaCBhIG5vZGUsIGRlcGVuZGluZyBvbiB3aGljaCBzaWRlcyBhcmVcbiAgICBvcGVuLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHNsaWNlJ3MgY29udGVudC5cbiAgICAqL1xuICAgIGNvbnRlbnQsIFxuICAgIC8qKlxuICAgIFRoZSBvcGVuIGRlcHRoIGF0IHRoZSBzdGFydCBvZiB0aGUgZnJhZ21lbnQuXG4gICAgKi9cbiAgICBvcGVuU3RhcnQsIFxuICAgIC8qKlxuICAgIFRoZSBvcGVuIGRlcHRoIGF0IHRoZSBlbmQuXG4gICAgKi9cbiAgICBvcGVuRW5kKSB7XG4gICAgICAgIHRoaXMuY29udGVudCA9IGNvbnRlbnQ7XG4gICAgICAgIHRoaXMub3BlblN0YXJ0ID0gb3BlblN0YXJ0O1xuICAgICAgICB0aGlzLm9wZW5FbmQgPSBvcGVuRW5kO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgc2l6ZSB0aGlzIHNsaWNlIHdvdWxkIGFkZCB3aGVuIGluc2VydGVkIGludG8gYSBkb2N1bWVudC5cbiAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZW50LnNpemUgLSB0aGlzLm9wZW5TdGFydCAtIHRoaXMub3BlbkVuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBpbnNlcnRBdChwb3MsIGZyYWdtZW50KSB7XG4gICAgICAgIGxldCBjb250ZW50ID0gaW5zZXJ0SW50byh0aGlzLmNvbnRlbnQsIHBvcyArIHRoaXMub3BlblN0YXJ0LCBmcmFnbWVudCwgdGhpcy5vcGVuU3RhcnQgKyAxLCB0aGlzLm9wZW5FbmQgKyAxKTtcbiAgICAgICAgcmV0dXJuIGNvbnRlbnQgJiYgbmV3IFNsaWNlKGNvbnRlbnQsIHRoaXMub3BlblN0YXJ0LCB0aGlzLm9wZW5FbmQpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHJlbW92ZUJldHdlZW4oZnJvbSwgdG8pIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTbGljZShyZW1vdmVSYW5nZSh0aGlzLmNvbnRlbnQsIGZyb20gKyB0aGlzLm9wZW5TdGFydCwgdG8gKyB0aGlzLm9wZW5TdGFydCksIHRoaXMub3BlblN0YXJ0LCB0aGlzLm9wZW5FbmQpO1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0cyB3aGV0aGVyIHRoaXMgc2xpY2UgaXMgZXF1YWwgdG8gYW5vdGhlciBzbGljZS5cbiAgICAqL1xuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRlbnQuZXEob3RoZXIuY29udGVudCkgJiYgdGhpcy5vcGVuU3RhcnQgPT0gb3RoZXIub3BlblN0YXJ0ICYmIHRoaXMub3BlbkVuZCA9PSBvdGhlci5vcGVuRW5kO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZW50ICsgXCIoXCIgKyB0aGlzLm9wZW5TdGFydCArIFwiLFwiICsgdGhpcy5vcGVuRW5kICsgXCIpXCI7XG4gICAgfVxuICAgIC8qKlxuICAgIENvbnZlcnQgYSBzbGljZSB0byBhIEpTT04tc2VyaWFsaXphYmxlIHJlcHJlc2VudGF0aW9uLlxuICAgICovXG4gICAgdG9KU09OKCkge1xuICAgICAgICBpZiAoIXRoaXMuY29udGVudC5zaXplKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGxldCBqc29uID0geyBjb250ZW50OiB0aGlzLmNvbnRlbnQudG9KU09OKCkgfTtcbiAgICAgICAgaWYgKHRoaXMub3BlblN0YXJ0ID4gMClcbiAgICAgICAgICAgIGpzb24ub3BlblN0YXJ0ID0gdGhpcy5vcGVuU3RhcnQ7XG4gICAgICAgIGlmICh0aGlzLm9wZW5FbmQgPiAwKVxuICAgICAgICAgICAganNvbi5vcGVuRW5kID0gdGhpcy5vcGVuRW5kO1xuICAgICAgICByZXR1cm4ganNvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgRGVzZXJpYWxpemUgYSBzbGljZSBmcm9tIGl0cyBKU09OIHJlcHJlc2VudGF0aW9uLlxuICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKHNjaGVtYSwganNvbikge1xuICAgICAgICBpZiAoIWpzb24pXG4gICAgICAgICAgICByZXR1cm4gU2xpY2UuZW1wdHk7XG4gICAgICAgIGxldCBvcGVuU3RhcnQgPSBqc29uLm9wZW5TdGFydCB8fCAwLCBvcGVuRW5kID0ganNvbi5vcGVuRW5kIHx8IDA7XG4gICAgICAgIGlmICh0eXBlb2Ygb3BlblN0YXJ0ICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIG9wZW5FbmQgIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgU2xpY2UuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbUpTT04oc2NoZW1hLCBqc29uLmNvbnRlbnQpLCBvcGVuU3RhcnQsIG9wZW5FbmQpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBzbGljZSBmcm9tIGEgZnJhZ21lbnQgYnkgdGFraW5nIHRoZSBtYXhpbXVtIHBvc3NpYmxlXG4gICAgb3BlbiB2YWx1ZSBvbiBib3RoIHNpZGUgb2YgdGhlIGZyYWdtZW50LlxuICAgICovXG4gICAgc3RhdGljIG1heE9wZW4oZnJhZ21lbnQsIG9wZW5Jc29sYXRpbmcgPSB0cnVlKSB7XG4gICAgICAgIGxldCBvcGVuU3RhcnQgPSAwLCBvcGVuRW5kID0gMDtcbiAgICAgICAgZm9yIChsZXQgbiA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7IG4gJiYgIW4uaXNMZWFmICYmIChvcGVuSXNvbGF0aW5nIHx8ICFuLnR5cGUuc3BlYy5pc29sYXRpbmcpOyBuID0gbi5maXJzdENoaWxkKVxuICAgICAgICAgICAgb3BlblN0YXJ0Kys7XG4gICAgICAgIGZvciAobGV0IG4gPSBmcmFnbWVudC5sYXN0Q2hpbGQ7IG4gJiYgIW4uaXNMZWFmICYmIChvcGVuSXNvbGF0aW5nIHx8ICFuLnR5cGUuc3BlYy5pc29sYXRpbmcpOyBuID0gbi5sYXN0Q2hpbGQpXG4gICAgICAgICAgICBvcGVuRW5kKys7XG4gICAgICAgIHJldHVybiBuZXcgU2xpY2UoZnJhZ21lbnQsIG9wZW5TdGFydCwgb3BlbkVuZCk7XG4gICAgfVxufVxuLyoqXG5UaGUgZW1wdHkgc2xpY2UuXG4qL1xuU2xpY2UuZW1wdHkgPSBuZXcgU2xpY2UoRnJhZ21lbnQuZW1wdHksIDAsIDApO1xuZnVuY3Rpb24gcmVtb3ZlUmFuZ2UoY29udGVudCwgZnJvbSwgdG8pIHtcbiAgICBsZXQgeyBpbmRleCwgb2Zmc2V0IH0gPSBjb250ZW50LmZpbmRJbmRleChmcm9tKSwgY2hpbGQgPSBjb250ZW50Lm1heWJlQ2hpbGQoaW5kZXgpO1xuICAgIGxldCB7IGluZGV4OiBpbmRleFRvLCBvZmZzZXQ6IG9mZnNldFRvIH0gPSBjb250ZW50LmZpbmRJbmRleCh0byk7XG4gICAgaWYgKG9mZnNldCA9PSBmcm9tIHx8IGNoaWxkLmlzVGV4dCkge1xuICAgICAgICBpZiAob2Zmc2V0VG8gIT0gdG8gJiYgIWNvbnRlbnQuY2hpbGQoaW5kZXhUbykuaXNUZXh0KVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJSZW1vdmluZyBub24tZmxhdCByYW5nZVwiKTtcbiAgICAgICAgcmV0dXJuIGNvbnRlbnQuY3V0KDAsIGZyb20pLmFwcGVuZChjb250ZW50LmN1dCh0bykpO1xuICAgIH1cbiAgICBpZiAoaW5kZXggIT0gaW5kZXhUbylcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJSZW1vdmluZyBub24tZmxhdCByYW5nZVwiKTtcbiAgICByZXR1cm4gY29udGVudC5yZXBsYWNlQ2hpbGQoaW5kZXgsIGNoaWxkLmNvcHkocmVtb3ZlUmFuZ2UoY2hpbGQuY29udGVudCwgZnJvbSAtIG9mZnNldCAtIDEsIHRvIC0gb2Zmc2V0IC0gMSkpKTtcbn1cbmZ1bmN0aW9uIGluc2VydEludG8oY29udGVudCwgZGlzdCwgaW5zZXJ0LCBvcGVuU3RhcnQsIG9wZW5FbmQsIHBhcmVudCkge1xuICAgIGxldCB7IGluZGV4LCBvZmZzZXQgfSA9IGNvbnRlbnQuZmluZEluZGV4KGRpc3QpLCBjaGlsZCA9IGNvbnRlbnQubWF5YmVDaGlsZChpbmRleCk7XG4gICAgaWYgKG9mZnNldCA9PSBkaXN0IHx8IGNoaWxkLmlzVGV4dCkge1xuICAgICAgICBpZiAocGFyZW50ICYmIG9wZW5TdGFydCA8PSAwICYmIG9wZW5FbmQgPD0gMCAmJiAhcGFyZW50LmNhblJlcGxhY2UoaW5kZXgsIGluZGV4LCBpbnNlcnQpKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBjb250ZW50LmN1dCgwLCBkaXN0KS5hcHBlbmQoaW5zZXJ0KS5hcHBlbmQoY29udGVudC5jdXQoZGlzdCkpO1xuICAgIH1cbiAgICBsZXQgaW5uZXIgPSBpbnNlcnRJbnRvKGNoaWxkLmNvbnRlbnQsIGRpc3QgLSBvZmZzZXQgLSAxLCBpbnNlcnQsIGluZGV4ID09IDAgPyBvcGVuU3RhcnQgLSAxIDogMCwgaW5kZXggPT0gY29udGVudC5jaGlsZENvdW50IC0gMSA/IG9wZW5FbmQgLSAxIDogMCwgY2hpbGQpO1xuICAgIHJldHVybiBpbm5lciAmJiBjb250ZW50LnJlcGxhY2VDaGlsZChpbmRleCwgY2hpbGQuY29weShpbm5lcikpO1xufVxuZnVuY3Rpb24gcmVwbGFjZSgkZnJvbSwgJHRvLCBzbGljZSkge1xuICAgIGlmIChzbGljZS5vcGVuU3RhcnQgPiAkZnJvbS5kZXB0aClcbiAgICAgICAgdGhyb3cgbmV3IFJlcGxhY2VFcnJvcihcIkluc2VydGVkIGNvbnRlbnQgZGVlcGVyIHRoYW4gaW5zZXJ0aW9uIHBvc2l0aW9uXCIpO1xuICAgIGlmICgkZnJvbS5kZXB0aCAtIHNsaWNlLm9wZW5TdGFydCAhPSAkdG8uZGVwdGggLSBzbGljZS5vcGVuRW5kKVxuICAgICAgICB0aHJvdyBuZXcgUmVwbGFjZUVycm9yKFwiSW5jb25zaXN0ZW50IG9wZW4gZGVwdGhzXCIpO1xuICAgIHJldHVybiByZXBsYWNlT3V0ZXIoJGZyb20sICR0bywgc2xpY2UsIDApO1xufVxuZnVuY3Rpb24gcmVwbGFjZU91dGVyKCRmcm9tLCAkdG8sIHNsaWNlLCBkZXB0aCkge1xuICAgIGxldCBpbmRleCA9ICRmcm9tLmluZGV4KGRlcHRoKSwgbm9kZSA9ICRmcm9tLm5vZGUoZGVwdGgpO1xuICAgIGlmIChpbmRleCA9PSAkdG8uaW5kZXgoZGVwdGgpICYmIGRlcHRoIDwgJGZyb20uZGVwdGggLSBzbGljZS5vcGVuU3RhcnQpIHtcbiAgICAgICAgbGV0IGlubmVyID0gcmVwbGFjZU91dGVyKCRmcm9tLCAkdG8sIHNsaWNlLCBkZXB0aCArIDEpO1xuICAgICAgICByZXR1cm4gbm9kZS5jb3B5KG5vZGUuY29udGVudC5yZXBsYWNlQ2hpbGQoaW5kZXgsIGlubmVyKSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKCFzbGljZS5jb250ZW50LnNpemUpIHtcbiAgICAgICAgcmV0dXJuIGNsb3NlKG5vZGUsIHJlcGxhY2VUd29XYXkoJGZyb20sICR0bywgZGVwdGgpKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoIXNsaWNlLm9wZW5TdGFydCAmJiAhc2xpY2Uub3BlbkVuZCAmJiAkZnJvbS5kZXB0aCA9PSBkZXB0aCAmJiAkdG8uZGVwdGggPT0gZGVwdGgpIHsgLy8gU2ltcGxlLCBmbGF0IGNhc2VcbiAgICAgICAgbGV0IHBhcmVudCA9ICRmcm9tLnBhcmVudCwgY29udGVudCA9IHBhcmVudC5jb250ZW50O1xuICAgICAgICByZXR1cm4gY2xvc2UocGFyZW50LCBjb250ZW50LmN1dCgwLCAkZnJvbS5wYXJlbnRPZmZzZXQpLmFwcGVuZChzbGljZS5jb250ZW50KS5hcHBlbmQoY29udGVudC5jdXQoJHRvLnBhcmVudE9mZnNldCkpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGxldCB7IHN0YXJ0LCBlbmQgfSA9IHByZXBhcmVTbGljZUZvclJlcGxhY2Uoc2xpY2UsICRmcm9tKTtcbiAgICAgICAgcmV0dXJuIGNsb3NlKG5vZGUsIHJlcGxhY2VUaHJlZVdheSgkZnJvbSwgc3RhcnQsIGVuZCwgJHRvLCBkZXB0aCkpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNoZWNrSm9pbihtYWluLCBzdWIpIHtcbiAgICBpZiAoIXN1Yi50eXBlLmNvbXBhdGlibGVDb250ZW50KG1haW4udHlwZSkpXG4gICAgICAgIHRocm93IG5ldyBSZXBsYWNlRXJyb3IoXCJDYW5ub3Qgam9pbiBcIiArIHN1Yi50eXBlLm5hbWUgKyBcIiBvbnRvIFwiICsgbWFpbi50eXBlLm5hbWUpO1xufVxuZnVuY3Rpb24gam9pbmFibGUoJGJlZm9yZSwgJGFmdGVyLCBkZXB0aCkge1xuICAgIGxldCBub2RlID0gJGJlZm9yZS5ub2RlKGRlcHRoKTtcbiAgICBjaGVja0pvaW4obm9kZSwgJGFmdGVyLm5vZGUoZGVwdGgpKTtcbiAgICByZXR1cm4gbm9kZTtcbn1cbmZ1bmN0aW9uIGFkZE5vZGUoY2hpbGQsIHRhcmdldCkge1xuICAgIGxldCBsYXN0ID0gdGFyZ2V0Lmxlbmd0aCAtIDE7XG4gICAgaWYgKGxhc3QgPj0gMCAmJiBjaGlsZC5pc1RleHQgJiYgY2hpbGQuc2FtZU1hcmt1cCh0YXJnZXRbbGFzdF0pKVxuICAgICAgICB0YXJnZXRbbGFzdF0gPSBjaGlsZC53aXRoVGV4dCh0YXJnZXRbbGFzdF0udGV4dCArIGNoaWxkLnRleHQpO1xuICAgIGVsc2VcbiAgICAgICAgdGFyZ2V0LnB1c2goY2hpbGQpO1xufVxuZnVuY3Rpb24gYWRkUmFuZ2UoJHN0YXJ0LCAkZW5kLCBkZXB0aCwgdGFyZ2V0KSB7XG4gICAgbGV0IG5vZGUgPSAoJGVuZCB8fCAkc3RhcnQpLm5vZGUoZGVwdGgpO1xuICAgIGxldCBzdGFydEluZGV4ID0gMCwgZW5kSW5kZXggPSAkZW5kID8gJGVuZC5pbmRleChkZXB0aCkgOiBub2RlLmNoaWxkQ291bnQ7XG4gICAgaWYgKCRzdGFydCkge1xuICAgICAgICBzdGFydEluZGV4ID0gJHN0YXJ0LmluZGV4KGRlcHRoKTtcbiAgICAgICAgaWYgKCRzdGFydC5kZXB0aCA+IGRlcHRoKSB7XG4gICAgICAgICAgICBzdGFydEluZGV4Kys7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoJHN0YXJ0LnRleHRPZmZzZXQpIHtcbiAgICAgICAgICAgIGFkZE5vZGUoJHN0YXJ0Lm5vZGVBZnRlciwgdGFyZ2V0KTtcbiAgICAgICAgICAgIHN0YXJ0SW5kZXgrKztcbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGxldCBpID0gc3RhcnRJbmRleDsgaSA8IGVuZEluZGV4OyBpKyspXG4gICAgICAgIGFkZE5vZGUobm9kZS5jaGlsZChpKSwgdGFyZ2V0KTtcbiAgICBpZiAoJGVuZCAmJiAkZW5kLmRlcHRoID09IGRlcHRoICYmICRlbmQudGV4dE9mZnNldClcbiAgICAgICAgYWRkTm9kZSgkZW5kLm5vZGVCZWZvcmUsIHRhcmdldCk7XG59XG5mdW5jdGlvbiBjbG9zZShub2RlLCBjb250ZW50KSB7XG4gICAgbm9kZS50eXBlLmNoZWNrQ29udGVudChjb250ZW50KTtcbiAgICByZXR1cm4gbm9kZS5jb3B5KGNvbnRlbnQpO1xufVxuZnVuY3Rpb24gcmVwbGFjZVRocmVlV2F5KCRmcm9tLCAkc3RhcnQsICRlbmQsICR0bywgZGVwdGgpIHtcbiAgICBsZXQgb3BlblN0YXJ0ID0gJGZyb20uZGVwdGggPiBkZXB0aCAmJiBqb2luYWJsZSgkZnJvbSwgJHN0YXJ0LCBkZXB0aCArIDEpO1xuICAgIGxldCBvcGVuRW5kID0gJHRvLmRlcHRoID4gZGVwdGggJiYgam9pbmFibGUoJGVuZCwgJHRvLCBkZXB0aCArIDEpO1xuICAgIGxldCBjb250ZW50ID0gW107XG4gICAgYWRkUmFuZ2UobnVsbCwgJGZyb20sIGRlcHRoLCBjb250ZW50KTtcbiAgICBpZiAob3BlblN0YXJ0ICYmIG9wZW5FbmQgJiYgJHN0YXJ0LmluZGV4KGRlcHRoKSA9PSAkZW5kLmluZGV4KGRlcHRoKSkge1xuICAgICAgICBjaGVja0pvaW4ob3BlblN0YXJ0LCBvcGVuRW5kKTtcbiAgICAgICAgYWRkTm9kZShjbG9zZShvcGVuU3RhcnQsIHJlcGxhY2VUaHJlZVdheSgkZnJvbSwgJHN0YXJ0LCAkZW5kLCAkdG8sIGRlcHRoICsgMSkpLCBjb250ZW50KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmIChvcGVuU3RhcnQpXG4gICAgICAgICAgICBhZGROb2RlKGNsb3NlKG9wZW5TdGFydCwgcmVwbGFjZVR3b1dheSgkZnJvbSwgJHN0YXJ0LCBkZXB0aCArIDEpKSwgY29udGVudCk7XG4gICAgICAgIGFkZFJhbmdlKCRzdGFydCwgJGVuZCwgZGVwdGgsIGNvbnRlbnQpO1xuICAgICAgICBpZiAob3BlbkVuZClcbiAgICAgICAgICAgIGFkZE5vZGUoY2xvc2Uob3BlbkVuZCwgcmVwbGFjZVR3b1dheSgkZW5kLCAkdG8sIGRlcHRoICsgMSkpLCBjb250ZW50KTtcbiAgICB9XG4gICAgYWRkUmFuZ2UoJHRvLCBudWxsLCBkZXB0aCwgY29udGVudCk7XG4gICAgcmV0dXJuIG5ldyBGcmFnbWVudChjb250ZW50KTtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VUd29XYXkoJGZyb20sICR0bywgZGVwdGgpIHtcbiAgICBsZXQgY29udGVudCA9IFtdO1xuICAgIGFkZFJhbmdlKG51bGwsICRmcm9tLCBkZXB0aCwgY29udGVudCk7XG4gICAgaWYgKCRmcm9tLmRlcHRoID4gZGVwdGgpIHtcbiAgICAgICAgbGV0IHR5cGUgPSBqb2luYWJsZSgkZnJvbSwgJHRvLCBkZXB0aCArIDEpO1xuICAgICAgICBhZGROb2RlKGNsb3NlKHR5cGUsIHJlcGxhY2VUd29XYXkoJGZyb20sICR0bywgZGVwdGggKyAxKSksIGNvbnRlbnQpO1xuICAgIH1cbiAgICBhZGRSYW5nZSgkdG8sIG51bGwsIGRlcHRoLCBjb250ZW50KTtcbiAgICByZXR1cm4gbmV3IEZyYWdtZW50KGNvbnRlbnQpO1xufVxuZnVuY3Rpb24gcHJlcGFyZVNsaWNlRm9yUmVwbGFjZShzbGljZSwgJGFsb25nKSB7XG4gICAgbGV0IGV4dHJhID0gJGFsb25nLmRlcHRoIC0gc2xpY2Uub3BlblN0YXJ0LCBwYXJlbnQgPSAkYWxvbmcubm9kZShleHRyYSk7XG4gICAgbGV0IG5vZGUgPSBwYXJlbnQuY29weShzbGljZS5jb250ZW50KTtcbiAgICBmb3IgKGxldCBpID0gZXh0cmEgLSAxOyBpID49IDA7IGktLSlcbiAgICAgICAgbm9kZSA9ICRhbG9uZy5ub2RlKGkpLmNvcHkoRnJhZ21lbnQuZnJvbShub2RlKSk7XG4gICAgcmV0dXJuIHsgc3RhcnQ6IG5vZGUucmVzb2x2ZU5vQ2FjaGUoc2xpY2Uub3BlblN0YXJ0ICsgZXh0cmEpLFxuICAgICAgICBlbmQ6IG5vZGUucmVzb2x2ZU5vQ2FjaGUobm9kZS5jb250ZW50LnNpemUgLSBzbGljZS5vcGVuRW5kIC0gZXh0cmEpIH07XG59XG5cbi8qKlxuWW91IGNhbiBbX3Jlc29sdmVfXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZS5yZXNvbHZlKSBhIHBvc2l0aW9uIHRvIGdldCBtb3JlXG5pbmZvcm1hdGlvbiBhYm91dCBpdC4gT2JqZWN0cyBvZiB0aGlzIGNsYXNzIHJlcHJlc2VudCBzdWNoIGFcbnJlc29sdmVkIHBvc2l0aW9uLCBwcm92aWRpbmcgdmFyaW91cyBwaWVjZXMgb2YgY29udGV4dFxuaW5mb3JtYXRpb24sIGFuZCBzb21lIGhlbHBlciBtZXRob2RzLlxuXG5UaHJvdWdob3V0IHRoaXMgaW50ZXJmYWNlLCBtZXRob2RzIHRoYXQgdGFrZSBhbiBvcHRpb25hbCBgZGVwdGhgXG5wYXJhbWV0ZXIgd2lsbCBpbnRlcnByZXQgdW5kZWZpbmVkIGFzIGB0aGlzLmRlcHRoYCBhbmQgbmVnYXRpdmVcbm51bWJlcnMgYXMgYHRoaXMuZGVwdGggKyB2YWx1ZWAuXG4qL1xuY2xhc3MgUmVzb2x2ZWRQb3Mge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHBvc2l0aW9uIHRoYXQgd2FzIHJlc29sdmVkLlxuICAgICovXG4gICAgcG9zLCBcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHBhdGgsIFxuICAgIC8qKlxuICAgIFRoZSBvZmZzZXQgdGhpcyBwb3NpdGlvbiBoYXMgaW50byBpdHMgcGFyZW50IG5vZGUuXG4gICAgKi9cbiAgICBwYXJlbnRPZmZzZXQpIHtcbiAgICAgICAgdGhpcy5wb3MgPSBwb3M7XG4gICAgICAgIHRoaXMucGF0aCA9IHBhdGg7XG4gICAgICAgIHRoaXMucGFyZW50T2Zmc2V0ID0gcGFyZW50T2Zmc2V0O1xuICAgICAgICB0aGlzLmRlcHRoID0gcGF0aC5sZW5ndGggLyAzIC0gMTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICByZXNvbHZlRGVwdGgodmFsKSB7XG4gICAgICAgIGlmICh2YWwgPT0gbnVsbClcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlcHRoO1xuICAgICAgICBpZiAodmFsIDwgMClcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlcHRoICsgdmFsO1xuICAgICAgICByZXR1cm4gdmFsO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgcGFyZW50IG5vZGUgdGhhdCB0aGUgcG9zaXRpb24gcG9pbnRzIGludG8uIE5vdGUgdGhhdCBldmVuIGlmXG4gICAgYSBwb3NpdGlvbiBwb2ludHMgaW50byBhIHRleHQgbm9kZSwgdGhhdCBub2RlIGlzIG5vdCBjb25zaWRlcmVkXG4gICAgdGhlIHBhcmVudFx1MjAxNHRleHQgbm9kZXMgYXJlIFx1MjAxOGZsYXRcdTIwMTkgaW4gdGhpcyBtb2RlbCwgYW5kIGhhdmUgbm8gY29udGVudC5cbiAgICAqL1xuICAgIGdldCBwYXJlbnQoKSB7IHJldHVybiB0aGlzLm5vZGUodGhpcy5kZXB0aCk7IH1cbiAgICAvKipcbiAgICBUaGUgcm9vdCBub2RlIGluIHdoaWNoIHRoZSBwb3NpdGlvbiB3YXMgcmVzb2x2ZWQuXG4gICAgKi9cbiAgICBnZXQgZG9jKCkgeyByZXR1cm4gdGhpcy5ub2RlKDApOyB9XG4gICAgLyoqXG4gICAgVGhlIGFuY2VzdG9yIG5vZGUgYXQgdGhlIGdpdmVuIGxldmVsLiBgcC5ub2RlKHAuZGVwdGgpYCBpcyB0aGVcbiAgICBzYW1lIGFzIGBwLnBhcmVudGAuXG4gICAgKi9cbiAgICBub2RlKGRlcHRoKSB7IHJldHVybiB0aGlzLnBhdGhbdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpICogM107IH1cbiAgICAvKipcbiAgICBUaGUgaW5kZXggaW50byB0aGUgYW5jZXN0b3IgYXQgdGhlIGdpdmVuIGxldmVsLiBJZiB0aGlzIHBvaW50c1xuICAgIGF0IHRoZSAzcmQgbm9kZSBpbiB0aGUgMm5kIHBhcmFncmFwaCBvbiB0aGUgdG9wIGxldmVsLCBmb3JcbiAgICBleGFtcGxlLCBgcC5pbmRleCgwKWAgaXMgMSBhbmQgYHAuaW5kZXgoMSlgIGlzIDIuXG4gICAgKi9cbiAgICBpbmRleChkZXB0aCkgeyByZXR1cm4gdGhpcy5wYXRoW3RoaXMucmVzb2x2ZURlcHRoKGRlcHRoKSAqIDMgKyAxXTsgfVxuICAgIC8qKlxuICAgIFRoZSBpbmRleCBwb2ludGluZyBhZnRlciB0aGlzIHBvc2l0aW9uIGludG8gdGhlIGFuY2VzdG9yIGF0IHRoZVxuICAgIGdpdmVuIGxldmVsLlxuICAgICovXG4gICAgaW5kZXhBZnRlcihkZXB0aCkge1xuICAgICAgICBkZXB0aCA9IHRoaXMucmVzb2x2ZURlcHRoKGRlcHRoKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5kZXgoZGVwdGgpICsgKGRlcHRoID09IHRoaXMuZGVwdGggJiYgIXRoaXMudGV4dE9mZnNldCA/IDAgOiAxKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIChhYnNvbHV0ZSkgcG9zaXRpb24gYXQgdGhlIHN0YXJ0IG9mIHRoZSBub2RlIGF0IHRoZSBnaXZlblxuICAgIGxldmVsLlxuICAgICovXG4gICAgc3RhcnQoZGVwdGgpIHtcbiAgICAgICAgZGVwdGggPSB0aGlzLnJlc29sdmVEZXB0aChkZXB0aCk7XG4gICAgICAgIHJldHVybiBkZXB0aCA9PSAwID8gMCA6IHRoaXMucGF0aFtkZXB0aCAqIDMgLSAxXSArIDE7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSAoYWJzb2x1dGUpIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIG5vZGUgYXQgdGhlIGdpdmVuXG4gICAgbGV2ZWwuXG4gICAgKi9cbiAgICBlbmQoZGVwdGgpIHtcbiAgICAgICAgZGVwdGggPSB0aGlzLnJlc29sdmVEZXB0aChkZXB0aCk7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXJ0KGRlcHRoKSArIHRoaXMubm9kZShkZXB0aCkuY29udGVudC5zaXplO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgKGFic29sdXRlKSBwb3NpdGlvbiBkaXJlY3RseSBiZWZvcmUgdGhlIHdyYXBwaW5nIG5vZGUgYXQgdGhlXG4gICAgZ2l2ZW4gbGV2ZWwsIG9yLCB3aGVuIGBkZXB0aGAgaXMgYHRoaXMuZGVwdGggKyAxYCwgdGhlIG9yaWdpbmFsXG4gICAgcG9zaXRpb24uXG4gICAgKi9cbiAgICBiZWZvcmUoZGVwdGgpIHtcbiAgICAgICAgZGVwdGggPSB0aGlzLnJlc29sdmVEZXB0aChkZXB0aCk7XG4gICAgICAgIGlmICghZGVwdGgpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlRoZXJlIGlzIG5vIHBvc2l0aW9uIGJlZm9yZSB0aGUgdG9wLWxldmVsIG5vZGVcIik7XG4gICAgICAgIHJldHVybiBkZXB0aCA9PSB0aGlzLmRlcHRoICsgMSA/IHRoaXMucG9zIDogdGhpcy5wYXRoW2RlcHRoICogMyAtIDFdO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgKGFic29sdXRlKSBwb3NpdGlvbiBkaXJlY3RseSBhZnRlciB0aGUgd3JhcHBpbmcgbm9kZSBhdCB0aGVcbiAgICBnaXZlbiBsZXZlbCwgb3IgdGhlIG9yaWdpbmFsIHBvc2l0aW9uIHdoZW4gYGRlcHRoYCBpcyBgdGhpcy5kZXB0aCArIDFgLlxuICAgICovXG4gICAgYWZ0ZXIoZGVwdGgpIHtcbiAgICAgICAgZGVwdGggPSB0aGlzLnJlc29sdmVEZXB0aChkZXB0aCk7XG4gICAgICAgIGlmICghZGVwdGgpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlRoZXJlIGlzIG5vIHBvc2l0aW9uIGFmdGVyIHRoZSB0b3AtbGV2ZWwgbm9kZVwiKTtcbiAgICAgICAgcmV0dXJuIGRlcHRoID09IHRoaXMuZGVwdGggKyAxID8gdGhpcy5wb3MgOiB0aGlzLnBhdGhbZGVwdGggKiAzIC0gMV0gKyB0aGlzLnBhdGhbZGVwdGggKiAzXS5ub2RlU2l6ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgV2hlbiB0aGlzIHBvc2l0aW9uIHBvaW50cyBpbnRvIGEgdGV4dCBub2RlLCB0aGlzIHJldHVybnMgdGhlXG4gICAgZGlzdGFuY2UgYmV0d2VlbiB0aGUgcG9zaXRpb24gYW5kIHRoZSBzdGFydCBvZiB0aGUgdGV4dCBub2RlLlxuICAgIFdpbGwgYmUgemVybyBmb3IgcG9zaXRpb25zIHRoYXQgcG9pbnQgYmV0d2VlbiBub2Rlcy5cbiAgICAqL1xuICAgIGdldCB0ZXh0T2Zmc2V0KCkgeyByZXR1cm4gdGhpcy5wb3MgLSB0aGlzLnBhdGhbdGhpcy5wYXRoLmxlbmd0aCAtIDFdOyB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBub2RlIGRpcmVjdGx5IGFmdGVyIHRoZSBwb3NpdGlvbiwgaWYgYW55LiBJZiB0aGUgcG9zaXRpb25cbiAgICBwb2ludHMgaW50byBhIHRleHQgbm9kZSwgb25seSB0aGUgcGFydCBvZiB0aGF0IG5vZGUgYWZ0ZXIgdGhlXG4gICAgcG9zaXRpb24gaXMgcmV0dXJuZWQuXG4gICAgKi9cbiAgICBnZXQgbm9kZUFmdGVyKCkge1xuICAgICAgICBsZXQgcGFyZW50ID0gdGhpcy5wYXJlbnQsIGluZGV4ID0gdGhpcy5pbmRleCh0aGlzLmRlcHRoKTtcbiAgICAgICAgaWYgKGluZGV4ID09IHBhcmVudC5jaGlsZENvdW50KVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGxldCBkT2ZmID0gdGhpcy5wb3MgLSB0aGlzLnBhdGhbdGhpcy5wYXRoLmxlbmd0aCAtIDFdLCBjaGlsZCA9IHBhcmVudC5jaGlsZChpbmRleCk7XG4gICAgICAgIHJldHVybiBkT2ZmID8gcGFyZW50LmNoaWxkKGluZGV4KS5jdXQoZE9mZikgOiBjaGlsZDtcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBub2RlIGRpcmVjdGx5IGJlZm9yZSB0aGUgcG9zaXRpb24sIGlmIGFueS4gSWYgdGhlXG4gICAgcG9zaXRpb24gcG9pbnRzIGludG8gYSB0ZXh0IG5vZGUsIG9ubHkgdGhlIHBhcnQgb2YgdGhhdCBub2RlXG4gICAgYmVmb3JlIHRoZSBwb3NpdGlvbiBpcyByZXR1cm5lZC5cbiAgICAqL1xuICAgIGdldCBub2RlQmVmb3JlKCkge1xuICAgICAgICBsZXQgaW5kZXggPSB0aGlzLmluZGV4KHRoaXMuZGVwdGgpO1xuICAgICAgICBsZXQgZE9mZiA9IHRoaXMucG9zIC0gdGhpcy5wYXRoW3RoaXMucGF0aC5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKGRPZmYpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQuY2hpbGQoaW5kZXgpLmN1dCgwLCBkT2ZmKTtcbiAgICAgICAgcmV0dXJuIGluZGV4ID09IDAgPyBudWxsIDogdGhpcy5wYXJlbnQuY2hpbGQoaW5kZXggLSAxKTtcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBwb3NpdGlvbiBhdCB0aGUgZ2l2ZW4gaW5kZXggaW4gdGhlIHBhcmVudCBub2RlIGF0IHRoZVxuICAgIGdpdmVuIGRlcHRoICh3aGljaCBkZWZhdWx0cyB0byBgdGhpcy5kZXB0aGApLlxuICAgICovXG4gICAgcG9zQXRJbmRleChpbmRleCwgZGVwdGgpIHtcbiAgICAgICAgZGVwdGggPSB0aGlzLnJlc29sdmVEZXB0aChkZXB0aCk7XG4gICAgICAgIGxldCBub2RlID0gdGhpcy5wYXRoW2RlcHRoICogM10sIHBvcyA9IGRlcHRoID09IDAgPyAwIDogdGhpcy5wYXRoW2RlcHRoICogMyAtIDFdICsgMTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRleDsgaSsrKVxuICAgICAgICAgICAgcG9zICs9IG5vZGUuY2hpbGQoaSkubm9kZVNpemU7XG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgbWFya3MgYXQgdGhpcyBwb3NpdGlvbiwgZmFjdG9yaW5nIGluIHRoZSBzdXJyb3VuZGluZ1xuICAgIG1hcmtzJyBbYGluY2x1c2l2ZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5NYXJrU3BlYy5pbmNsdXNpdmUpIHByb3BlcnR5LiBJZiB0aGVcbiAgICBwb3NpdGlvbiBpcyBhdCB0aGUgc3RhcnQgb2YgYSBub24tZW1wdHkgbm9kZSwgdGhlIG1hcmtzIG9mIHRoZVxuICAgIG5vZGUgYWZ0ZXIgaXQgKGlmIGFueSkgYXJlIHJldHVybmVkLlxuICAgICovXG4gICAgbWFya3MoKSB7XG4gICAgICAgIGxldCBwYXJlbnQgPSB0aGlzLnBhcmVudCwgaW5kZXggPSB0aGlzLmluZGV4KCk7XG4gICAgICAgIC8vIEluIGFuIGVtcHR5IHBhcmVudCwgcmV0dXJuIHRoZSBlbXB0eSBhcnJheVxuICAgICAgICBpZiAocGFyZW50LmNvbnRlbnQuc2l6ZSA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIE1hcmsubm9uZTtcbiAgICAgICAgLy8gV2hlbiBpbnNpZGUgYSB0ZXh0IG5vZGUsIGp1c3QgcmV0dXJuIHRoZSB0ZXh0IG5vZGUncyBtYXJrc1xuICAgICAgICBpZiAodGhpcy50ZXh0T2Zmc2V0KVxuICAgICAgICAgICAgcmV0dXJuIHBhcmVudC5jaGlsZChpbmRleCkubWFya3M7XG4gICAgICAgIGxldCBtYWluID0gcGFyZW50Lm1heWJlQ2hpbGQoaW5kZXggLSAxKSwgb3RoZXIgPSBwYXJlbnQubWF5YmVDaGlsZChpbmRleCk7XG4gICAgICAgIC8vIElmIHRoZSBgYWZ0ZXJgIGZsYWcgaXMgdHJ1ZSBvZiB0aGVyZSBpcyBubyBub2RlIGJlZm9yZSwgbWFrZVxuICAgICAgICAvLyB0aGUgbm9kZSBhZnRlciB0aGlzIHBvc2l0aW9uIHRoZSBtYWluIHJlZmVyZW5jZS5cbiAgICAgICAgaWYgKCFtYWluKSB7XG4gICAgICAgICAgICBsZXQgdG1wID0gbWFpbjtcbiAgICAgICAgICAgIG1haW4gPSBvdGhlcjtcbiAgICAgICAgICAgIG90aGVyID0gdG1wO1xuICAgICAgICB9XG4gICAgICAgIC8vIFVzZSBhbGwgbWFya3MgaW4gdGhlIG1haW4gbm9kZSwgZXhjZXB0IHRob3NlIHRoYXQgaGF2ZVxuICAgICAgICAvLyBgaW5jbHVzaXZlYCBzZXQgdG8gZmFsc2UgYW5kIGFyZSBub3QgcHJlc2VudCBpbiB0aGUgb3RoZXIgbm9kZS5cbiAgICAgICAgbGV0IG1hcmtzID0gbWFpbi5tYXJrcztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmIChtYXJrc1tpXS50eXBlLnNwZWMuaW5jbHVzaXZlID09PSBmYWxzZSAmJiAoIW90aGVyIHx8ICFtYXJrc1tpXS5pc0luU2V0KG90aGVyLm1hcmtzKSkpXG4gICAgICAgICAgICAgICAgbWFya3MgPSBtYXJrc1tpLS1dLnJlbW92ZUZyb21TZXQobWFya3MpO1xuICAgICAgICByZXR1cm4gbWFya3M7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgbWFya3MgYWZ0ZXIgdGhlIGN1cnJlbnQgcG9zaXRpb24sIGlmIGFueSwgZXhjZXB0IHRob3NlXG4gICAgdGhhdCBhcmUgbm9uLWluY2x1c2l2ZSBhbmQgbm90IHByZXNlbnQgYXQgcG9zaXRpb24gYCRlbmRgLiBUaGlzXG4gICAgaXMgbW9zdGx5IHVzZWZ1bCBmb3IgZ2V0dGluZyB0aGUgc2V0IG9mIG1hcmtzIHRvIHByZXNlcnZlIGFmdGVyIGFcbiAgICBkZWxldGlvbi4gV2lsbCByZXR1cm4gYG51bGxgIGlmIHRoaXMgcG9zaXRpb24gaXMgYXQgdGhlIGVuZCBvZlxuICAgIGl0cyBwYXJlbnQgbm9kZSBvciBpdHMgcGFyZW50IG5vZGUgaXNuJ3QgYSB0ZXh0YmxvY2sgKGluIHdoaWNoXG4gICAgY2FzZSBubyBtYXJrcyBzaG91bGQgYmUgcHJlc2VydmVkKS5cbiAgICAqL1xuICAgIG1hcmtzQWNyb3NzKCRlbmQpIHtcbiAgICAgICAgbGV0IGFmdGVyID0gdGhpcy5wYXJlbnQubWF5YmVDaGlsZCh0aGlzLmluZGV4KCkpO1xuICAgICAgICBpZiAoIWFmdGVyIHx8ICFhZnRlci5pc0lubGluZSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBsZXQgbWFya3MgPSBhZnRlci5tYXJrcywgbmV4dCA9ICRlbmQucGFyZW50Lm1heWJlQ2hpbGQoJGVuZC5pbmRleCgpKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmIChtYXJrc1tpXS50eXBlLnNwZWMuaW5jbHVzaXZlID09PSBmYWxzZSAmJiAoIW5leHQgfHwgIW1hcmtzW2ldLmlzSW5TZXQobmV4dC5tYXJrcykpKVxuICAgICAgICAgICAgICAgIG1hcmtzID0gbWFya3NbaS0tXS5yZW1vdmVGcm9tU2V0KG1hcmtzKTtcbiAgICAgICAgcmV0dXJuIG1hcmtzO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgZGVwdGggdXAgdG8gd2hpY2ggdGhpcyBwb3NpdGlvbiBhbmQgdGhlIGdpdmVuIChub24tcmVzb2x2ZWQpXG4gICAgcG9zaXRpb24gc2hhcmUgdGhlIHNhbWUgcGFyZW50IG5vZGVzLlxuICAgICovXG4gICAgc2hhcmVkRGVwdGgocG9zKSB7XG4gICAgICAgIGZvciAobGV0IGRlcHRoID0gdGhpcy5kZXB0aDsgZGVwdGggPiAwOyBkZXB0aC0tKVxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhcnQoZGVwdGgpIDw9IHBvcyAmJiB0aGlzLmVuZChkZXB0aCkgPj0gcG9zKVxuICAgICAgICAgICAgICAgIHJldHVybiBkZXB0aDtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHVybnMgYSByYW5nZSBiYXNlZCBvbiB0aGUgcGxhY2Ugd2hlcmUgdGhpcyBwb3NpdGlvbiBhbmQgdGhlXG4gICAgZ2l2ZW4gcG9zaXRpb24gZGl2ZXJnZSBhcm91bmQgYmxvY2sgY29udGVudC4gSWYgYm90aCBwb2ludCBpbnRvXG4gICAgdGhlIHNhbWUgdGV4dGJsb2NrLCBmb3IgZXhhbXBsZSwgYSByYW5nZSBhcm91bmQgdGhhdCB0ZXh0YmxvY2tcbiAgICB3aWxsIGJlIHJldHVybmVkLiBJZiB0aGV5IHBvaW50IGludG8gZGlmZmVyZW50IGJsb2NrcywgdGhlIHJhbmdlXG4gICAgYXJvdW5kIHRob3NlIGJsb2NrcyBpbiB0aGVpciBzaGFyZWQgYW5jZXN0b3IgaXMgcmV0dXJuZWQuIFlvdSBjYW5cbiAgICBwYXNzIGluIGFuIG9wdGlvbmFsIHByZWRpY2F0ZSB0aGF0IHdpbGwgYmUgY2FsbGVkIHdpdGggYSBwYXJlbnRcbiAgICBub2RlIHRvIHNlZSBpZiBhIHJhbmdlIGludG8gdGhhdCBwYXJlbnQgaXMgYWNjZXB0YWJsZS5cbiAgICAqL1xuICAgIGJsb2NrUmFuZ2Uob3RoZXIgPSB0aGlzLCBwcmVkKSB7XG4gICAgICAgIGlmIChvdGhlci5wb3MgPCB0aGlzLnBvcylcbiAgICAgICAgICAgIHJldHVybiBvdGhlci5ibG9ja1JhbmdlKHRoaXMpO1xuICAgICAgICBmb3IgKGxldCBkID0gdGhpcy5kZXB0aCAtICh0aGlzLnBhcmVudC5pbmxpbmVDb250ZW50IHx8IHRoaXMucG9zID09IG90aGVyLnBvcyA/IDEgOiAwKTsgZCA+PSAwOyBkLS0pXG4gICAgICAgICAgICBpZiAob3RoZXIucG9zIDw9IHRoaXMuZW5kKGQpICYmICghcHJlZCB8fCBwcmVkKHRoaXMubm9kZShkKSkpKVxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTm9kZVJhbmdlKHRoaXMsIG90aGVyLCBkKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIFF1ZXJ5IHdoZXRoZXIgdGhlIGdpdmVuIHBvc2l0aW9uIHNoYXJlcyB0aGUgc2FtZSBwYXJlbnQgbm9kZS5cbiAgICAqL1xuICAgIHNhbWVQYXJlbnQob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zIC0gdGhpcy5wYXJlbnRPZmZzZXQgPT0gb3RoZXIucG9zIC0gb3RoZXIucGFyZW50T2Zmc2V0O1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm4gdGhlIGdyZWF0ZXIgb2YgdGhpcyBhbmQgdGhlIGdpdmVuIHBvc2l0aW9uLlxuICAgICovXG4gICAgbWF4KG90aGVyKSB7XG4gICAgICAgIHJldHVybiBvdGhlci5wb3MgPiB0aGlzLnBvcyA/IG90aGVyIDogdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJuIHRoZSBzbWFsbGVyIG9mIHRoaXMgYW5kIHRoZSBnaXZlbiBwb3NpdGlvbi5cbiAgICAqL1xuICAgIG1pbihvdGhlcikge1xuICAgICAgICByZXR1cm4gb3RoZXIucG9zIDwgdGhpcy5wb3MgPyBvdGhlciA6IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIGxldCBzdHIgPSBcIlwiO1xuICAgICAgICBmb3IgKGxldCBpID0gMTsgaSA8PSB0aGlzLmRlcHRoOyBpKyspXG4gICAgICAgICAgICBzdHIgKz0gKHN0ciA/IFwiL1wiIDogXCJcIikgKyB0aGlzLm5vZGUoaSkudHlwZS5uYW1lICsgXCJfXCIgKyB0aGlzLmluZGV4KGkgLSAxKTtcbiAgICAgICAgcmV0dXJuIHN0ciArIFwiOlwiICsgdGhpcy5wYXJlbnRPZmZzZXQ7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIHJlc29sdmUoZG9jLCBwb3MpIHtcbiAgICAgICAgaWYgKCEocG9zID49IDAgJiYgcG9zIDw9IGRvYy5jb250ZW50LnNpemUpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJQb3NpdGlvbiBcIiArIHBvcyArIFwiIG91dCBvZiByYW5nZVwiKTtcbiAgICAgICAgbGV0IHBhdGggPSBbXTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gMCwgcGFyZW50T2Zmc2V0ID0gcG9zO1xuICAgICAgICBmb3IgKGxldCBub2RlID0gZG9jOzspIHtcbiAgICAgICAgICAgIGxldCB7IGluZGV4LCBvZmZzZXQgfSA9IG5vZGUuY29udGVudC5maW5kSW5kZXgocGFyZW50T2Zmc2V0KTtcbiAgICAgICAgICAgIGxldCByZW0gPSBwYXJlbnRPZmZzZXQgLSBvZmZzZXQ7XG4gICAgICAgICAgICBwYXRoLnB1c2gobm9kZSwgaW5kZXgsIHN0YXJ0ICsgb2Zmc2V0KTtcbiAgICAgICAgICAgIGlmICghcmVtKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgbm9kZSA9IG5vZGUuY2hpbGQoaW5kZXgpO1xuICAgICAgICAgICAgaWYgKG5vZGUuaXNUZXh0KVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgcGFyZW50T2Zmc2V0ID0gcmVtIC0gMTtcbiAgICAgICAgICAgIHN0YXJ0ICs9IG9mZnNldCArIDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBSZXNvbHZlZFBvcyhwb3MsIHBhdGgsIHBhcmVudE9mZnNldCk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIHJlc29sdmVDYWNoZWQoZG9jLCBwb3MpIHtcbiAgICAgICAgbGV0IGNhY2hlID0gcmVzb2x2ZUNhY2hlLmdldChkb2MpO1xuICAgICAgICBpZiAoY2FjaGUpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2FjaGUuZWx0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBlbHQgPSBjYWNoZS5lbHRzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChlbHQucG9zID09IHBvcylcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmVDYWNoZS5zZXQoZG9jLCBjYWNoZSA9IG5ldyBSZXNvbHZlQ2FjaGUpO1xuICAgICAgICB9XG4gICAgICAgIGxldCByZXN1bHQgPSBjYWNoZS5lbHRzW2NhY2hlLmldID0gUmVzb2x2ZWRQb3MucmVzb2x2ZShkb2MsIHBvcyk7XG4gICAgICAgIGNhY2hlLmkgPSAoY2FjaGUuaSArIDEpICUgcmVzb2x2ZUNhY2hlU2l6ZTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG59XG5jbGFzcyBSZXNvbHZlQ2FjaGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmVsdHMgPSBbXTtcbiAgICAgICAgdGhpcy5pID0gMDtcbiAgICB9XG59XG5jb25zdCByZXNvbHZlQ2FjaGVTaXplID0gMTIsIHJlc29sdmVDYWNoZSA9IG5ldyBXZWFrTWFwKCk7XG4vKipcblJlcHJlc2VudHMgYSBmbGF0IHJhbmdlIG9mIGNvbnRlbnQsIGkuZS4gb25lIHRoYXQgc3RhcnRzIGFuZFxuZW5kcyBpbiB0aGUgc2FtZSBub2RlLlxuKi9cbmNsYXNzIE5vZGVSYW5nZSB7XG4gICAgLyoqXG4gICAgQ29uc3RydWN0IGEgbm9kZSByYW5nZS4gYCRmcm9tYCBhbmQgYCR0b2Agc2hvdWxkIHBvaW50IGludG8gdGhlXG4gICAgc2FtZSBub2RlIHVudGlsIGF0IGxlYXN0IHRoZSBnaXZlbiBgZGVwdGhgLCBzaW5jZSBhIG5vZGUgcmFuZ2VcbiAgICBkZW5vdGVzIGFuIGFkamFjZW50IHNldCBvZiBub2RlcyBpbiBhIHNpbmdsZSBwYXJlbnQgbm9kZS5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIEEgcmVzb2x2ZWQgcG9zaXRpb24gYWxvbmcgdGhlIHN0YXJ0IG9mIHRoZSBjb250ZW50LiBNYXkgaGF2ZSBhXG4gICAgYGRlcHRoYCBncmVhdGVyIHRoYW4gdGhpcyBvYmplY3QncyBgZGVwdGhgIHByb3BlcnR5LCBzaW5jZVxuICAgIHRoZXNlIGFyZSB0aGUgcG9zaXRpb25zIHRoYXQgd2VyZSB1c2VkIHRvIGNvbXB1dGUgdGhlIHJhbmdlLFxuICAgIG5vdCByZS1yZXNvbHZlZCBwb3NpdGlvbnMgZGlyZWN0bHkgYXQgaXRzIGJvdW5kYXJpZXMuXG4gICAgKi9cbiAgICAkZnJvbSwgXG4gICAgLyoqXG4gICAgQSBwb3NpdGlvbiBhbG9uZyB0aGUgZW5kIG9mIHRoZSBjb250ZW50LiBTZWVcbiAgICBjYXZlYXQgZm9yIFtgJGZyb21gXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVJhbmdlLiRmcm9tKS5cbiAgICAqL1xuICAgICR0bywgXG4gICAgLyoqXG4gICAgVGhlIGRlcHRoIG9mIHRoZSBub2RlIHRoYXQgdGhpcyByYW5nZSBwb2ludHMgaW50by5cbiAgICAqL1xuICAgIGRlcHRoKSB7XG4gICAgICAgIHRoaXMuJGZyb20gPSAkZnJvbTtcbiAgICAgICAgdGhpcy4kdG8gPSAkdG87XG4gICAgICAgIHRoaXMuZGVwdGggPSBkZXB0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHBvc2l0aW9uIGF0IHRoZSBzdGFydCBvZiB0aGUgcmFuZ2UuXG4gICAgKi9cbiAgICBnZXQgc3RhcnQoKSB7IHJldHVybiB0aGlzLiRmcm9tLmJlZm9yZSh0aGlzLmRlcHRoICsgMSk7IH1cbiAgICAvKipcbiAgICBUaGUgcG9zaXRpb24gYXQgdGhlIGVuZCBvZiB0aGUgcmFuZ2UuXG4gICAgKi9cbiAgICBnZXQgZW5kKCkgeyByZXR1cm4gdGhpcy4kdG8uYWZ0ZXIodGhpcy5kZXB0aCArIDEpOyB9XG4gICAgLyoqXG4gICAgVGhlIHBhcmVudCBub2RlIHRoYXQgdGhlIHJhbmdlIHBvaW50cyBpbnRvLlxuICAgICovXG4gICAgZ2V0IHBhcmVudCgpIHsgcmV0dXJuIHRoaXMuJGZyb20ubm9kZSh0aGlzLmRlcHRoKTsgfVxuICAgIC8qKlxuICAgIFRoZSBzdGFydCBpbmRleCBvZiB0aGUgcmFuZ2UgaW4gdGhlIHBhcmVudCBub2RlLlxuICAgICovXG4gICAgZ2V0IHN0YXJ0SW5kZXgoKSB7IHJldHVybiB0aGlzLiRmcm9tLmluZGV4KHRoaXMuZGVwdGgpOyB9XG4gICAgLyoqXG4gICAgVGhlIGVuZCBpbmRleCBvZiB0aGUgcmFuZ2UgaW4gdGhlIHBhcmVudCBub2RlLlxuICAgICovXG4gICAgZ2V0IGVuZEluZGV4KCkgeyByZXR1cm4gdGhpcy4kdG8uaW5kZXhBZnRlcih0aGlzLmRlcHRoKTsgfVxufVxuXG5jb25zdCBlbXB0eUF0dHJzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbi8qKlxuVGhpcyBjbGFzcyByZXByZXNlbnRzIGEgbm9kZSBpbiB0aGUgdHJlZSB0aGF0IG1ha2VzIHVwIGFcblByb3NlTWlycm9yIGRvY3VtZW50LiBTbyBhIGRvY3VtZW50IGlzIGFuIGluc3RhbmNlIG9mIGBOb2RlYCwgd2l0aFxuY2hpbGRyZW4gdGhhdCBhcmUgYWxzbyBpbnN0YW5jZXMgb2YgYE5vZGVgLlxuXG5Ob2RlcyBhcmUgcGVyc2lzdGVudCBkYXRhIHN0cnVjdHVyZXMuIEluc3RlYWQgb2YgY2hhbmdpbmcgdGhlbSwgeW91XG5jcmVhdGUgbmV3IG9uZXMgd2l0aCB0aGUgY29udGVudCB5b3Ugd2FudC4gT2xkIG9uZXMga2VlcCBwb2ludGluZ1xuYXQgdGhlIG9sZCBkb2N1bWVudCBzaGFwZS4gVGhpcyBpcyBtYWRlIGNoZWFwZXIgYnkgc2hhcmluZ1xuc3RydWN0dXJlIGJldHdlZW4gdGhlIG9sZCBhbmQgbmV3IGRhdGEgYXMgbXVjaCBhcyBwb3NzaWJsZSwgd2hpY2ggYVxudHJlZSBzaGFwZSBsaWtlIHRoaXMgKHdpdGhvdXQgYmFjayBwb2ludGVycykgbWFrZXMgZWFzeS5cblxuKipEbyBub3QqKiBkaXJlY3RseSBtdXRhdGUgdGhlIHByb3BlcnRpZXMgb2YgYSBgTm9kZWAgb2JqZWN0LiBTZWVcblt0aGUgZ3VpZGVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvZ3VpZGUvI2RvYykgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4qL1xuY2xhc3MgTm9kZSB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgdHlwZSBvZiBub2RlIHRoYXQgdGhpcyBpcy5cbiAgICAqL1xuICAgIHR5cGUsIFxuICAgIC8qKlxuICAgIEFuIG9iamVjdCBtYXBwaW5nIGF0dHJpYnV0ZSBuYW1lcyB0byB2YWx1ZXMuIFRoZSBraW5kIG9mXG4gICAgYXR0cmlidXRlcyBhbGxvd2VkIGFuZCByZXF1aXJlZCBhcmVcbiAgICBbZGV0ZXJtaW5lZF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmF0dHJzKSBieSB0aGUgbm9kZSB0eXBlLlxuICAgICovXG4gICAgYXR0cnMsIFxuICAgIC8vIEEgZnJhZ21lbnQgaG9sZGluZyB0aGUgbm9kZSdzIGNoaWxkcmVuLlxuICAgIGNvbnRlbnQsIFxuICAgIC8qKlxuICAgIFRoZSBtYXJrcyAodGhpbmdzIGxpa2Ugd2hldGhlciBpdCBpcyBlbXBoYXNpemVkIG9yIHBhcnQgb2YgYVxuICAgIGxpbmspIGFwcGxpZWQgdG8gdGhpcyBub2RlLlxuICAgICovXG4gICAgbWFya3MgPSBNYXJrLm5vbmUpIHtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5hdHRycyA9IGF0dHJzO1xuICAgICAgICB0aGlzLm1hcmtzID0gbWFya3M7XG4gICAgICAgIHRoaXMuY29udGVudCA9IGNvbnRlbnQgfHwgRnJhZ21lbnQuZW1wdHk7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSBhcnJheSBvZiB0aGlzIG5vZGUncyBjaGlsZCBub2Rlcy5cbiAgICAqL1xuICAgIGdldCBjaGlsZHJlbigpIHsgcmV0dXJuIHRoaXMuY29udGVudC5jb250ZW50OyB9XG4gICAgLyoqXG4gICAgVGhlIHNpemUgb2YgdGhpcyBub2RlLCBhcyBkZWZpbmVkIGJ5IHRoZSBpbnRlZ2VyLWJhc2VkIFtpbmRleGluZ1xuICAgIHNjaGVtZV0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9ndWlkZS8jZG9jLmluZGV4aW5nKS4gRm9yIHRleHQgbm9kZXMsIHRoaXMgaXMgdGhlXG4gICAgYW1vdW50IG9mIGNoYXJhY3RlcnMuIEZvciBvdGhlciBsZWFmIG5vZGVzLCBpdCBpcyBvbmUuIEZvclxuICAgIG5vbi1sZWFmIG5vZGVzLCBpdCBpcyB0aGUgc2l6ZSBvZiB0aGUgY29udGVudCBwbHVzIHR3byAodGhlXG4gICAgc3RhcnQgYW5kIGVuZCB0b2tlbikuXG4gICAgKi9cbiAgICBnZXQgbm9kZVNpemUoKSB7IHJldHVybiB0aGlzLmlzTGVhZiA/IDEgOiAyICsgdGhpcy5jb250ZW50LnNpemU7IH1cbiAgICAvKipcbiAgICBUaGUgbnVtYmVyIG9mIGNoaWxkcmVuIHRoYXQgdGhlIG5vZGUgaGFzLlxuICAgICovXG4gICAgZ2V0IGNoaWxkQ291bnQoKSB7IHJldHVybiB0aGlzLmNvbnRlbnQuY2hpbGRDb3VudDsgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgY2hpbGQgbm9kZSBhdCB0aGUgZ2l2ZW4gaW5kZXguIFJhaXNlcyBhbiBlcnJvciB3aGVuIHRoZVxuICAgIGluZGV4IGlzIG91dCBvZiByYW5nZS5cbiAgICAqL1xuICAgIGNoaWxkKGluZGV4KSB7IHJldHVybiB0aGlzLmNvbnRlbnQuY2hpbGQoaW5kZXgpOyB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBjaGlsZCBub2RlIGF0IHRoZSBnaXZlbiBpbmRleCwgaWYgaXQgZXhpc3RzLlxuICAgICovXG4gICAgbWF5YmVDaGlsZChpbmRleCkgeyByZXR1cm4gdGhpcy5jb250ZW50Lm1heWJlQ2hpbGQoaW5kZXgpOyB9XG4gICAgLyoqXG4gICAgQ2FsbCBgZmAgZm9yIGV2ZXJ5IGNoaWxkIG5vZGUsIHBhc3NpbmcgdGhlIG5vZGUsIGl0cyBvZmZzZXRcbiAgICBpbnRvIHRoaXMgcGFyZW50IG5vZGUsIGFuZCBpdHMgaW5kZXguXG4gICAgKi9cbiAgICBmb3JFYWNoKGYpIHsgdGhpcy5jb250ZW50LmZvckVhY2goZik7IH1cbiAgICAvKipcbiAgICBJbnZva2UgYSBjYWxsYmFjayBmb3IgYWxsIGRlc2NlbmRhbnQgbm9kZXMgcmVjdXJzaXZlbHkgb3ZlcmxhcHBpbmdcbiAgICB0aGUgZ2l2ZW4gdHdvIHBvc2l0aW9ucyB0aGF0IGFyZSByZWxhdGl2ZSB0byBzdGFydCBvZiB0aGlzXG4gICAgbm9kZSdzIGNvbnRlbnQuIFRoaXMgaW5jbHVkZXMgYWxsIGFuY2VzdG9ycyBvZiB0aGUgbm9kZXNcbiAgICBjb250YWluaW5nIHRoZSB0d28gcG9zaXRpb25zLiBUaGUgY2FsbGJhY2sgaXMgaW52b2tlZCB3aXRoIHRoZVxuICAgIG5vZGUsIGl0cyBwb3NpdGlvbiByZWxhdGl2ZSB0byB0aGUgb3JpZ2luYWwgbm9kZSAobWV0aG9kIHJlY2VpdmVyKSxcbiAgICBpdHMgcGFyZW50IG5vZGUsIGFuZCBpdHMgY2hpbGQgaW5kZXguIFdoZW4gdGhlIGNhbGxiYWNrIHJldHVybnNcbiAgICBmYWxzZSBmb3IgYSBnaXZlbiBub2RlLCB0aGF0IG5vZGUncyBjaGlsZHJlbiB3aWxsIG5vdCBiZVxuICAgIHJlY3Vyc2VkIG92ZXIuIFRoZSBsYXN0IHBhcmFtZXRlciBjYW4gYmUgdXNlZCB0byBzcGVjaWZ5IGFcbiAgICBzdGFydGluZyBwb3NpdGlvbiB0byBjb3VudCBmcm9tLlxuICAgICovXG4gICAgbm9kZXNCZXR3ZWVuKGZyb20sIHRvLCBmLCBzdGFydFBvcyA9IDApIHtcbiAgICAgICAgdGhpcy5jb250ZW50Lm5vZGVzQmV0d2Vlbihmcm9tLCB0bywgZiwgc3RhcnRQb3MsIHRoaXMpO1xuICAgIH1cbiAgICAvKipcbiAgICBDYWxsIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgZXZlcnkgZGVzY2VuZGFudCBub2RlLiBEb2Vzbid0XG4gICAgZGVzY2VuZCBpbnRvIGEgbm9kZSB3aGVuIHRoZSBjYWxsYmFjayByZXR1cm5zIGBmYWxzZWAuXG4gICAgKi9cbiAgICBkZXNjZW5kYW50cyhmKSB7XG4gICAgICAgIHRoaXMubm9kZXNCZXR3ZWVuKDAsIHRoaXMuY29udGVudC5zaXplLCBmKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ29uY2F0ZW5hdGVzIGFsbCB0aGUgdGV4dCBub2RlcyBmb3VuZCBpbiB0aGlzIGZyYWdtZW50IGFuZCBpdHNcbiAgICBjaGlsZHJlbi5cbiAgICAqL1xuICAgIGdldCB0ZXh0Q29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLmlzTGVhZiAmJiB0aGlzLnR5cGUuc3BlYy5sZWFmVGV4dClcbiAgICAgICAgICAgID8gdGhpcy50eXBlLnNwZWMubGVhZlRleHQodGhpcylcbiAgICAgICAgICAgIDogdGhpcy50ZXh0QmV0d2VlbigwLCB0aGlzLmNvbnRlbnQuc2l6ZSwgXCJcIik7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCBhbGwgdGV4dCBiZXR3ZWVuIHBvc2l0aW9ucyBgZnJvbWAgYW5kIGB0b2AuIFdoZW5cbiAgICBgYmxvY2tTZXBhcmF0b3JgIGlzIGdpdmVuLCBpdCB3aWxsIGJlIGluc2VydGVkIHRvIHNlcGFyYXRlIHRleHRcbiAgICBmcm9tIGRpZmZlcmVudCBibG9jayBub2Rlcy4gSWYgYGxlYWZUZXh0YCBpcyBnaXZlbiwgaXQnbGwgYmVcbiAgICBpbnNlcnRlZCBmb3IgZXZlcnkgbm9uLXRleHQgbGVhZiBub2RlIGVuY291bnRlcmVkLCBvdGhlcndpc2VcbiAgICBbYGxlYWZUZXh0YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmxlYWZUZXh0KSB3aWxsIGJlIHVzZWQuXG4gICAgKi9cbiAgICB0ZXh0QmV0d2Vlbihmcm9tLCB0bywgYmxvY2tTZXBhcmF0b3IsIGxlYWZUZXh0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRlbnQudGV4dEJldHdlZW4oZnJvbSwgdG8sIGJsb2NrU2VwYXJhdG9yLCBsZWFmVGV4dCk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHVybnMgdGhpcyBub2RlJ3MgZmlyc3QgY2hpbGQsIG9yIGBudWxsYCBpZiB0aGVyZSBhcmUgbm9cbiAgICBjaGlsZHJlbi5cbiAgICAqL1xuICAgIGdldCBmaXJzdENoaWxkKCkgeyByZXR1cm4gdGhpcy5jb250ZW50LmZpcnN0Q2hpbGQ7IH1cbiAgICAvKipcbiAgICBSZXR1cm5zIHRoaXMgbm9kZSdzIGxhc3QgY2hpbGQsIG9yIGBudWxsYCBpZiB0aGVyZSBhcmUgbm9cbiAgICBjaGlsZHJlbi5cbiAgICAqL1xuICAgIGdldCBsYXN0Q2hpbGQoKSB7IHJldHVybiB0aGlzLmNvbnRlbnQubGFzdENoaWxkOyB9XG4gICAgLyoqXG4gICAgVGVzdCB3aGV0aGVyIHR3byBub2RlcyByZXByZXNlbnQgdGhlIHNhbWUgcGllY2Ugb2YgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBlcShvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcyA9PSBvdGhlciB8fCAodGhpcy5zYW1lTWFya3VwKG90aGVyKSAmJiB0aGlzLmNvbnRlbnQuZXEob3RoZXIuY29udGVudCkpO1xuICAgIH1cbiAgICAvKipcbiAgICBDb21wYXJlIHRoZSBtYXJrdXAgKHR5cGUsIGF0dHJpYnV0ZXMsIGFuZCBtYXJrcykgb2YgdGhpcyBub2RlIHRvXG4gICAgdGhvc2Ugb2YgYW5vdGhlci4gUmV0dXJucyBgdHJ1ZWAgaWYgYm90aCBoYXZlIHRoZSBzYW1lIG1hcmt1cC5cbiAgICAqL1xuICAgIHNhbWVNYXJrdXAob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFzTWFya3VwKG90aGVyLnR5cGUsIG90aGVyLmF0dHJzLCBvdGhlci5tYXJrcyk7XG4gICAgfVxuICAgIC8qKlxuICAgIENoZWNrIHdoZXRoZXIgdGhpcyBub2RlJ3MgbWFya3VwIGNvcnJlc3BvbmQgdG8gdGhlIGdpdmVuIHR5cGUsXG4gICAgYXR0cmlidXRlcywgYW5kIG1hcmtzLlxuICAgICovXG4gICAgaGFzTWFya3VwKHR5cGUsIGF0dHJzLCBtYXJrcykge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09IHR5cGUgJiZcbiAgICAgICAgICAgIGNvbXBhcmVEZWVwKHRoaXMuYXR0cnMsIGF0dHJzIHx8IHR5cGUuZGVmYXVsdEF0dHJzIHx8IGVtcHR5QXR0cnMpICYmXG4gICAgICAgICAgICBNYXJrLnNhbWVTZXQodGhpcy5tYXJrcywgbWFya3MgfHwgTWFyay5ub25lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbmV3IG5vZGUgd2l0aCB0aGUgc2FtZSBtYXJrdXAgYXMgdGhpcyBub2RlLCBjb250YWluaW5nXG4gICAgdGhlIGdpdmVuIGNvbnRlbnQgKG9yIGVtcHR5LCBpZiBubyBjb250ZW50IGlzIGdpdmVuKS5cbiAgICAqL1xuICAgIGNvcHkoY29udGVudCA9IG51bGwpIHtcbiAgICAgICAgaWYgKGNvbnRlbnQgPT0gdGhpcy5jb250ZW50KVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZSh0aGlzLnR5cGUsIHRoaXMuYXR0cnMsIGNvbnRlbnQsIHRoaXMubWFya3MpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBjb3B5IG9mIHRoaXMgbm9kZSwgd2l0aCB0aGUgZ2l2ZW4gc2V0IG9mIG1hcmtzIGluc3RlYWRcbiAgICBvZiB0aGUgbm9kZSdzIG93biBtYXJrcy5cbiAgICAqL1xuICAgIG1hcmsobWFya3MpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtzID09IHRoaXMubWFya3MgPyB0aGlzIDogbmV3IE5vZGUodGhpcy50eXBlLCB0aGlzLmF0dHJzLCB0aGlzLmNvbnRlbnQsIG1hcmtzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgY29weSBvZiB0aGlzIG5vZGUgd2l0aCBvbmx5IHRoZSBjb250ZW50IGJldHdlZW4gdGhlXG4gICAgZ2l2ZW4gcG9zaXRpb25zLiBJZiBgdG9gIGlzIG5vdCBnaXZlbiwgaXQgZGVmYXVsdHMgdG8gdGhlIGVuZCBvZlxuICAgIHRoZSBub2RlLlxuICAgICovXG4gICAgY3V0KGZyb20sIHRvID0gdGhpcy5jb250ZW50LnNpemUpIHtcbiAgICAgICAgaWYgKGZyb20gPT0gMCAmJiB0byA9PSB0aGlzLmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gdGhpcy5jb3B5KHRoaXMuY29udGVudC5jdXQoZnJvbSwgdG8pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3V0IG91dCB0aGUgcGFydCBvZiB0aGUgZG9jdW1lbnQgYmV0d2VlbiB0aGUgZ2l2ZW4gcG9zaXRpb25zLCBhbmRcbiAgICByZXR1cm4gaXQgYXMgYSBgU2xpY2VgIG9iamVjdC5cbiAgICAqL1xuICAgIHNsaWNlKGZyb20sIHRvID0gdGhpcy5jb250ZW50LnNpemUsIGluY2x1ZGVQYXJlbnRzID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKGZyb20gPT0gdG8pXG4gICAgICAgICAgICByZXR1cm4gU2xpY2UuZW1wdHk7XG4gICAgICAgIGxldCAkZnJvbSA9IHRoaXMucmVzb2x2ZShmcm9tKSwgJHRvID0gdGhpcy5yZXNvbHZlKHRvKTtcbiAgICAgICAgbGV0IGRlcHRoID0gaW5jbHVkZVBhcmVudHMgPyAwIDogJGZyb20uc2hhcmVkRGVwdGgodG8pO1xuICAgICAgICBsZXQgc3RhcnQgPSAkZnJvbS5zdGFydChkZXB0aCksIG5vZGUgPSAkZnJvbS5ub2RlKGRlcHRoKTtcbiAgICAgICAgbGV0IGNvbnRlbnQgPSBub2RlLmNvbnRlbnQuY3V0KCRmcm9tLnBvcyAtIHN0YXJ0LCAkdG8ucG9zIC0gc3RhcnQpO1xuICAgICAgICByZXR1cm4gbmV3IFNsaWNlKGNvbnRlbnQsICRmcm9tLmRlcHRoIC0gZGVwdGgsICR0by5kZXB0aCAtIGRlcHRoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmVwbGFjZSB0aGUgcGFydCBvZiB0aGUgZG9jdW1lbnQgYmV0d2VlbiB0aGUgZ2l2ZW4gcG9zaXRpb25zIHdpdGhcbiAgICB0aGUgZ2l2ZW4gc2xpY2UuIFRoZSBzbGljZSBtdXN0ICdmaXQnLCBtZWFuaW5nIGl0cyBvcGVuIHNpZGVzXG4gICAgbXVzdCBiZSBhYmxlIHRvIGNvbm5lY3QgdG8gdGhlIHN1cnJvdW5kaW5nIGNvbnRlbnQsIGFuZCBpdHNcbiAgICBjb250ZW50IG5vZGVzIG11c3QgYmUgdmFsaWQgY2hpbGRyZW4gZm9yIHRoZSBub2RlIHRoZXkgYXJlIHBsYWNlZFxuICAgIGludG8uIElmIGFueSBvZiB0aGlzIGlzIHZpb2xhdGVkLCBhbiBlcnJvciBvZiB0eXBlXG4gICAgW2BSZXBsYWNlRXJyb3JgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuUmVwbGFjZUVycm9yKSBpcyB0aHJvd24uXG4gICAgKi9cbiAgICByZXBsYWNlKGZyb20sIHRvLCBzbGljZSkge1xuICAgICAgICByZXR1cm4gcmVwbGFjZSh0aGlzLnJlc29sdmUoZnJvbSksIHRoaXMucmVzb2x2ZSh0byksIHNsaWNlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCB0aGUgbm9kZSBkaXJlY3RseSBhZnRlciB0aGUgZ2l2ZW4gcG9zaXRpb24uXG4gICAgKi9cbiAgICBub2RlQXQocG9zKSB7XG4gICAgICAgIGZvciAobGV0IG5vZGUgPSB0aGlzOzspIHtcbiAgICAgICAgICAgIGxldCB7IGluZGV4LCBvZmZzZXQgfSA9IG5vZGUuY29udGVudC5maW5kSW5kZXgocG9zKTtcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLm1heWJlQ2hpbGQoaW5kZXgpO1xuICAgICAgICAgICAgaWYgKCFub2RlKVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA9PSBwb3MgfHwgbm9kZS5pc1RleHQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICAgICAgICBwb3MgLT0gb2Zmc2V0ICsgMTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSAoZGlyZWN0KSBjaGlsZCBub2RlIGFmdGVyIHRoZSBnaXZlbiBvZmZzZXQsIGlmIGFueSxcbiAgICBhbmQgcmV0dXJuIGl0IGFsb25nIHdpdGggaXRzIGluZGV4IGFuZCBvZmZzZXQgcmVsYXRpdmUgdG8gdGhpc1xuICAgIG5vZGUuXG4gICAgKi9cbiAgICBjaGlsZEFmdGVyKHBvcykge1xuICAgICAgICBsZXQgeyBpbmRleCwgb2Zmc2V0IH0gPSB0aGlzLmNvbnRlbnQuZmluZEluZGV4KHBvcyk7XG4gICAgICAgIHJldHVybiB7IG5vZGU6IHRoaXMuY29udGVudC5tYXliZUNoaWxkKGluZGV4KSwgaW5kZXgsIG9mZnNldCB9O1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSAoZGlyZWN0KSBjaGlsZCBub2RlIGJlZm9yZSB0aGUgZ2l2ZW4gb2Zmc2V0LCBpZiBhbnksXG4gICAgYW5kIHJldHVybiBpdCBhbG9uZyB3aXRoIGl0cyBpbmRleCBhbmQgb2Zmc2V0IHJlbGF0aXZlIHRvIHRoaXNcbiAgICBub2RlLlxuICAgICovXG4gICAgY2hpbGRCZWZvcmUocG9zKSB7XG4gICAgICAgIGlmIChwb3MgPT0gMClcbiAgICAgICAgICAgIHJldHVybiB7IG5vZGU6IG51bGwsIGluZGV4OiAwLCBvZmZzZXQ6IDAgfTtcbiAgICAgICAgbGV0IHsgaW5kZXgsIG9mZnNldCB9ID0gdGhpcy5jb250ZW50LmZpbmRJbmRleChwb3MpO1xuICAgICAgICBpZiAob2Zmc2V0IDwgcG9zKVxuICAgICAgICAgICAgcmV0dXJuIHsgbm9kZTogdGhpcy5jb250ZW50LmNoaWxkKGluZGV4KSwgaW5kZXgsIG9mZnNldCB9O1xuICAgICAgICBsZXQgbm9kZSA9IHRoaXMuY29udGVudC5jaGlsZChpbmRleCAtIDEpO1xuICAgICAgICByZXR1cm4geyBub2RlLCBpbmRleDogaW5kZXggLSAxLCBvZmZzZXQ6IG9mZnNldCAtIG5vZGUubm9kZVNpemUgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmVzb2x2ZSB0aGUgZ2l2ZW4gcG9zaXRpb24gaW4gdGhlIGRvY3VtZW50LCByZXR1cm5pbmcgYW5cbiAgICBbb2JqZWN0XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuUmVzb2x2ZWRQb3MpIHdpdGggaW5mb3JtYXRpb24gYWJvdXQgaXRzIGNvbnRleHQuXG4gICAgKi9cbiAgICByZXNvbHZlKHBvcykgeyByZXR1cm4gUmVzb2x2ZWRQb3MucmVzb2x2ZUNhY2hlZCh0aGlzLCBwb3MpOyB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICByZXNvbHZlTm9DYWNoZShwb3MpIHsgcmV0dXJuIFJlc29sdmVkUG9zLnJlc29sdmUodGhpcywgcG9zKTsgfVxuICAgIC8qKlxuICAgIFRlc3Qgd2hldGhlciBhIGdpdmVuIG1hcmsgb3IgbWFyayB0eXBlIG9jY3VycyBpbiB0aGlzIGRvY3VtZW50XG4gICAgYmV0d2VlbiB0aGUgdHdvIGdpdmVuIHBvc2l0aW9ucy5cbiAgICAqL1xuICAgIHJhbmdlSGFzTWFyayhmcm9tLCB0bywgdHlwZSkge1xuICAgICAgICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRvID4gZnJvbSlcbiAgICAgICAgICAgIHRoaXMubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCBub2RlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZS5pc0luU2V0KG5vZGUubWFya3MpKVxuICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuICFmb3VuZDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZm91bmQ7XG4gICAgfVxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGlzIGlzIGEgYmxvY2sgKG5vbi1pbmxpbmUgbm9kZSlcbiAgICAqL1xuICAgIGdldCBpc0Jsb2NrKCkgeyByZXR1cm4gdGhpcy50eXBlLmlzQmxvY2s7IH1cbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhpcyBpcyBhIHRleHRibG9jayBub2RlLCBhIGJsb2NrIG5vZGUgd2l0aCBpbmxpbmVcbiAgICBjb250ZW50LlxuICAgICovXG4gICAgZ2V0IGlzVGV4dGJsb2NrKCkgeyByZXR1cm4gdGhpcy50eXBlLmlzVGV4dGJsb2NrOyB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoaXMgbm9kZSBhbGxvd3MgaW5saW5lIGNvbnRlbnQuXG4gICAgKi9cbiAgICBnZXQgaW5saW5lQ29udGVudCgpIHsgcmV0dXJuIHRoaXMudHlwZS5pbmxpbmVDb250ZW50OyB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoaXMgaXMgYW4gaW5saW5lIG5vZGUgKGEgdGV4dCBub2RlIG9yIGEgbm9kZSB0aGF0IGNhblxuICAgIGFwcGVhciBhbW9uZyB0ZXh0KS5cbiAgICAqL1xuICAgIGdldCBpc0lubGluZSgpIHsgcmV0dXJuIHRoaXMudHlwZS5pc0lubGluZTsgfVxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGlzIGlzIGEgdGV4dCBub2RlLlxuICAgICovXG4gICAgZ2V0IGlzVGV4dCgpIHsgcmV0dXJuIHRoaXMudHlwZS5pc1RleHQ7IH1cbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhpcyBpcyBhIGxlYWYgbm9kZS5cbiAgICAqL1xuICAgIGdldCBpc0xlYWYoKSB7IHJldHVybiB0aGlzLnR5cGUuaXNMZWFmOyB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoaXMgaXMgYW4gYXRvbSwgaS5lLiB3aGVuIGl0IGRvZXMgbm90IGhhdmUgZGlyZWN0bHlcbiAgICBlZGl0YWJsZSBjb250ZW50LiBUaGlzIGlzIHVzdWFsbHkgdGhlIHNhbWUgYXMgYGlzTGVhZmAsIGJ1dCBjYW5cbiAgICBiZSBjb25maWd1cmVkIHdpdGggdGhlIFtgYXRvbWAgcHJvcGVydHldKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5hdG9tKVxuICAgIG9uIGEgbm9kZSdzIHNwZWMgKHR5cGljYWxseSB1c2VkIHdoZW4gdGhlIG5vZGUgaXMgZGlzcGxheWVkIGFzXG4gICAgYW4gdW5lZGl0YWJsZSBbbm9kZSB2aWV3XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdmlldy5Ob2RlVmlldykpLlxuICAgICovXG4gICAgZ2V0IGlzQXRvbSgpIHsgcmV0dXJuIHRoaXMudHlwZS5pc0F0b207IH1cbiAgICAvKipcbiAgICBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBub2RlIGZvciBkZWJ1Z2dpbmdcbiAgICBwdXJwb3Nlcy5cbiAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICBpZiAodGhpcy50eXBlLnNwZWMudG9EZWJ1Z1N0cmluZylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnR5cGUuc3BlYy50b0RlYnVnU3RyaW5nKHRoaXMpO1xuICAgICAgICBsZXQgbmFtZSA9IHRoaXMudHlwZS5uYW1lO1xuICAgICAgICBpZiAodGhpcy5jb250ZW50LnNpemUpXG4gICAgICAgICAgICBuYW1lICs9IFwiKFwiICsgdGhpcy5jb250ZW50LnRvU3RyaW5nSW5uZXIoKSArIFwiKVwiO1xuICAgICAgICByZXR1cm4gd3JhcE1hcmtzKHRoaXMubWFya3MsIG5hbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICBHZXQgdGhlIGNvbnRlbnQgbWF0Y2ggaW4gdGhpcyBub2RlIGF0IHRoZSBnaXZlbiBpbmRleC5cbiAgICAqL1xuICAgIGNvbnRlbnRNYXRjaEF0KGluZGV4KSB7XG4gICAgICAgIGxldCBtYXRjaCA9IHRoaXMudHlwZS5jb250ZW50TWF0Y2gubWF0Y2hGcmFnbWVudCh0aGlzLmNvbnRlbnQsIDAsIGluZGV4KTtcbiAgICAgICAgaWYgKCFtYXRjaClcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbGxlZCBjb250ZW50TWF0Y2hBdCBvbiBhIG5vZGUgd2l0aCBpbnZhbGlkIGNvbnRlbnRcIik7XG4gICAgICAgIHJldHVybiBtYXRjaDtcbiAgICB9XG4gICAgLyoqXG4gICAgVGVzdCB3aGV0aGVyIHJlcGxhY2luZyB0aGUgcmFuZ2UgYmV0d2VlbiBgZnJvbWAgYW5kIGB0b2AgKGJ5XG4gICAgY2hpbGQgaW5kZXgpIHdpdGggdGhlIGdpdmVuIHJlcGxhY2VtZW50IGZyYWdtZW50ICh3aGljaCBkZWZhdWx0c1xuICAgIHRvIHRoZSBlbXB0eSBmcmFnbWVudCkgd291bGQgbGVhdmUgdGhlIG5vZGUncyBjb250ZW50IHZhbGlkLiBZb3VcbiAgICBjYW4gb3B0aW9uYWxseSBwYXNzIGBzdGFydGAgYW5kIGBlbmRgIGluZGljZXMgaW50byB0aGVcbiAgICByZXBsYWNlbWVudCBmcmFnbWVudC5cbiAgICAqL1xuICAgIGNhblJlcGxhY2UoZnJvbSwgdG8sIHJlcGxhY2VtZW50ID0gRnJhZ21lbnQuZW1wdHksIHN0YXJ0ID0gMCwgZW5kID0gcmVwbGFjZW1lbnQuY2hpbGRDb3VudCkge1xuICAgICAgICBsZXQgb25lID0gdGhpcy5jb250ZW50TWF0Y2hBdChmcm9tKS5tYXRjaEZyYWdtZW50KHJlcGxhY2VtZW50LCBzdGFydCwgZW5kKTtcbiAgICAgICAgbGV0IHR3byA9IG9uZSAmJiBvbmUubWF0Y2hGcmFnbWVudCh0aGlzLmNvbnRlbnQsIHRvKTtcbiAgICAgICAgaWYgKCF0d28gfHwgIXR3by52YWxpZEVuZClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspXG4gICAgICAgICAgICBpZiAoIXRoaXMudHlwZS5hbGxvd3NNYXJrcyhyZXBsYWNlbWVudC5jaGlsZChpKS5tYXJrcykpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGVzdCB3aGV0aGVyIHJlcGxhY2luZyB0aGUgcmFuZ2UgYGZyb21gIHRvIGB0b2AgKGJ5IGluZGV4KSB3aXRoXG4gICAgYSBub2RlIG9mIHRoZSBnaXZlbiB0eXBlIHdvdWxkIGxlYXZlIHRoZSBub2RlJ3MgY29udGVudCB2YWxpZC5cbiAgICAqL1xuICAgIGNhblJlcGxhY2VXaXRoKGZyb20sIHRvLCB0eXBlLCBtYXJrcykge1xuICAgICAgICBpZiAobWFya3MgJiYgIXRoaXMudHlwZS5hbGxvd3NNYXJrcyhtYXJrcykpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGxldCBzdGFydCA9IHRoaXMuY29udGVudE1hdGNoQXQoZnJvbSkubWF0Y2hUeXBlKHR5cGUpO1xuICAgICAgICBsZXQgZW5kID0gc3RhcnQgJiYgc3RhcnQubWF0Y2hGcmFnbWVudCh0aGlzLmNvbnRlbnQsIHRvKTtcbiAgICAgICAgcmV0dXJuIGVuZCA/IGVuZC52YWxpZEVuZCA6IGZhbHNlO1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgdGhlIGdpdmVuIG5vZGUncyBjb250ZW50IGNvdWxkIGJlIGFwcGVuZGVkIHRvIHRoaXNcbiAgICBub2RlLiBJZiB0aGF0IG5vZGUgaXMgZW1wdHksIHRoaXMgd2lsbCBvbmx5IHJldHVybiB0cnVlIGlmIHRoZXJlXG4gICAgaXMgYXQgbGVhc3Qgb25lIG5vZGUgdHlwZSB0aGF0IGNhbiBhcHBlYXIgaW4gYm90aCBub2RlcyAodG8gYXZvaWRcbiAgICBtZXJnaW5nIGNvbXBsZXRlbHkgaW5jb21wYXRpYmxlIG5vZGVzKS5cbiAgICAqL1xuICAgIGNhbkFwcGVuZChvdGhlcikge1xuICAgICAgICBpZiAob3RoZXIuY29udGVudC5zaXplKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2FuUmVwbGFjZSh0aGlzLmNoaWxkQ291bnQsIHRoaXMuY2hpbGRDb3VudCwgb3RoZXIuY29udGVudCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnR5cGUuY29tcGF0aWJsZUNvbnRlbnQob3RoZXIudHlwZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENoZWNrIHdoZXRoZXIgdGhpcyBub2RlIGFuZCBpdHMgZGVzY2VuZGFudHMgY29uZm9ybSB0byB0aGVcbiAgICBzY2hlbWEsIGFuZCByYWlzZSBhbiBleGNlcHRpb24gd2hlbiB0aGV5IGRvIG5vdC5cbiAgICAqL1xuICAgIGNoZWNrKCkge1xuICAgICAgICB0aGlzLnR5cGUuY2hlY2tDb250ZW50KHRoaXMuY29udGVudCk7XG4gICAgICAgIHRoaXMudHlwZS5jaGVja0F0dHJzKHRoaXMuYXR0cnMpO1xuICAgICAgICBsZXQgY29weSA9IE1hcmsubm9uZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm1hcmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbWFyayA9IHRoaXMubWFya3NbaV07XG4gICAgICAgICAgICBtYXJrLnR5cGUuY2hlY2tBdHRycyhtYXJrLmF0dHJzKTtcbiAgICAgICAgICAgIGNvcHkgPSBtYXJrLmFkZFRvU2V0KGNvcHkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghTWFyay5zYW1lU2V0KGNvcHksIHRoaXMubWFya3MpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYEludmFsaWQgY29sbGVjdGlvbiBvZiBtYXJrcyBmb3Igbm9kZSAke3RoaXMudHlwZS5uYW1lfTogJHt0aGlzLm1hcmtzLm1hcChtID0+IG0udHlwZS5uYW1lKX1gKTtcbiAgICAgICAgdGhpcy5jb250ZW50LmZvckVhY2gobm9kZSA9PiBub2RlLmNoZWNrKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm4gYSBKU09OLXNlcmlhbGl6ZWFibGUgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBub2RlLlxuICAgICovXG4gICAgdG9KU09OKCkge1xuICAgICAgICBsZXQgb2JqID0geyB0eXBlOiB0aGlzLnR5cGUubmFtZSB9O1xuICAgICAgICBmb3IgKGxldCBfIGluIHRoaXMuYXR0cnMpIHtcbiAgICAgICAgICAgIG9iai5hdHRycyA9IHRoaXMuYXR0cnM7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5jb250ZW50LnNpemUpXG4gICAgICAgICAgICBvYmouY29udGVudCA9IHRoaXMuY29udGVudC50b0pTT04oKTtcbiAgICAgICAgaWYgKHRoaXMubWFya3MubGVuZ3RoKVxuICAgICAgICAgICAgb2JqLm1hcmtzID0gdGhpcy5tYXJrcy5tYXAobiA9PiBuLnRvSlNPTigpKTtcbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG4gICAgLyoqXG4gICAgRGVzZXJpYWxpemUgYSBub2RlIGZyb20gaXRzIEpTT04gcmVwcmVzZW50YXRpb24uXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICghanNvbilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgTm9kZS5mcm9tSlNPTlwiKTtcbiAgICAgICAgbGV0IG1hcmtzID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoanNvbi5tYXJrcykge1xuICAgICAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGpzb24ubWFya3MpKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBtYXJrIGRhdGEgZm9yIE5vZGUuZnJvbUpTT05cIik7XG4gICAgICAgICAgICBtYXJrcyA9IGpzb24ubWFya3MubWFwKHNjaGVtYS5tYXJrRnJvbUpTT04pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChqc29uLnR5cGUgPT0gXCJ0ZXh0XCIpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YganNvbi50ZXh0ICE9IFwic3RyaW5nXCIpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIHRleHQgbm9kZSBpbiBKU09OXCIpO1xuICAgICAgICAgICAgcmV0dXJuIHNjaGVtYS50ZXh0KGpzb24udGV4dCwgbWFya3MpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBjb250ZW50ID0gRnJhZ21lbnQuZnJvbUpTT04oc2NoZW1hLCBqc29uLmNvbnRlbnQpO1xuICAgICAgICBsZXQgbm9kZSA9IHNjaGVtYS5ub2RlVHlwZShqc29uLnR5cGUpLmNyZWF0ZShqc29uLmF0dHJzLCBjb250ZW50LCBtYXJrcyk7XG4gICAgICAgIG5vZGUudHlwZS5jaGVja0F0dHJzKG5vZGUuYXR0cnMpO1xuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICB9XG59XG5Ob2RlLnByb3RvdHlwZS50ZXh0ID0gdW5kZWZpbmVkO1xuY2xhc3MgVGV4dE5vZGUgZXh0ZW5kcyBOb2RlIHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHR5cGUsIGF0dHJzLCBjb250ZW50LCBtYXJrcykge1xuICAgICAgICBzdXBlcih0eXBlLCBhdHRycywgbnVsbCwgbWFya3MpO1xuICAgICAgICBpZiAoIWNvbnRlbnQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkVtcHR5IHRleHQgbm9kZXMgYXJlIG5vdCBhbGxvd2VkXCIpO1xuICAgICAgICB0aGlzLnRleHQgPSBjb250ZW50O1xuICAgIH1cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZS5zcGVjLnRvRGVidWdTdHJpbmcpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50eXBlLnNwZWMudG9EZWJ1Z1N0cmluZyh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHdyYXBNYXJrcyh0aGlzLm1hcmtzLCBKU09OLnN0cmluZ2lmeSh0aGlzLnRleHQpKTtcbiAgICB9XG4gICAgZ2V0IHRleHRDb250ZW50KCkgeyByZXR1cm4gdGhpcy50ZXh0OyB9XG4gICAgdGV4dEJldHdlZW4oZnJvbSwgdG8pIHsgcmV0dXJuIHRoaXMudGV4dC5zbGljZShmcm9tLCB0byk7IH1cbiAgICBnZXQgbm9kZVNpemUoKSB7IHJldHVybiB0aGlzLnRleHQubGVuZ3RoOyB9XG4gICAgbWFyayhtYXJrcykge1xuICAgICAgICByZXR1cm4gbWFya3MgPT0gdGhpcy5tYXJrcyA/IHRoaXMgOiBuZXcgVGV4dE5vZGUodGhpcy50eXBlLCB0aGlzLmF0dHJzLCB0aGlzLnRleHQsIG1hcmtzKTtcbiAgICB9XG4gICAgd2l0aFRleHQodGV4dCkge1xuICAgICAgICBpZiAodGV4dCA9PSB0aGlzLnRleHQpXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0Tm9kZSh0aGlzLnR5cGUsIHRoaXMuYXR0cnMsIHRleHQsIHRoaXMubWFya3MpO1xuICAgIH1cbiAgICBjdXQoZnJvbSA9IDAsIHRvID0gdGhpcy50ZXh0Lmxlbmd0aCkge1xuICAgICAgICBpZiAoZnJvbSA9PSAwICYmIHRvID09IHRoaXMudGV4dC5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgcmV0dXJuIHRoaXMud2l0aFRleHQodGhpcy50ZXh0LnNsaWNlKGZyb20sIHRvKSk7XG4gICAgfVxuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNhbWVNYXJrdXAob3RoZXIpICYmIHRoaXMudGV4dCA9PSBvdGhlci50ZXh0O1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGxldCBiYXNlID0gc3VwZXIudG9KU09OKCk7XG4gICAgICAgIGJhc2UudGV4dCA9IHRoaXMudGV4dDtcbiAgICAgICAgcmV0dXJuIGJhc2U7XG4gICAgfVxufVxuZnVuY3Rpb24gd3JhcE1hcmtzKG1hcmtzLCBzdHIpIHtcbiAgICBmb3IgKGxldCBpID0gbWFya3MubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgIHN0ciA9IG1hcmtzW2ldLnR5cGUubmFtZSArIFwiKFwiICsgc3RyICsgXCIpXCI7XG4gICAgcmV0dXJuIHN0cjtcbn1cblxuLyoqXG5JbnN0YW5jZXMgb2YgdGhpcyBjbGFzcyByZXByZXNlbnQgYSBtYXRjaCBzdGF0ZSBvZiBhIG5vZGUgdHlwZSdzXG5bY29udGVudCBleHByZXNzaW9uXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuY29udGVudCksIGFuZCBjYW4gYmUgdXNlZCB0b1xuZmluZCBvdXQgd2hldGhlciBmdXJ0aGVyIGNvbnRlbnQgbWF0Y2hlcyBoZXJlLCBhbmQgd2hldGhlciBhIGdpdmVuXG5wb3NpdGlvbiBpcyBhIHZhbGlkIGVuZCBvZiB0aGUgbm9kZS5cbiovXG5jbGFzcyBDb250ZW50TWF0Y2gge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoaXMgbWF0Y2ggc3RhdGUgcmVwcmVzZW50cyBhIHZhbGlkIGVuZCBvZiB0aGUgbm9kZS5cbiAgICAqL1xuICAgIHZhbGlkRW5kKSB7XG4gICAgICAgIHRoaXMudmFsaWRFbmQgPSB2YWxpZEVuZDtcbiAgICAgICAgLyoqXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLm5leHQgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLndyYXBDYWNoZSA9IFtdO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBwYXJzZShzdHJpbmcsIG5vZGVUeXBlcykge1xuICAgICAgICBsZXQgc3RyZWFtID0gbmV3IFRva2VuU3RyZWFtKHN0cmluZywgbm9kZVR5cGVzKTtcbiAgICAgICAgaWYgKHN0cmVhbS5uZXh0ID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gQ29udGVudE1hdGNoLmVtcHR5O1xuICAgICAgICBsZXQgZXhwciA9IHBhcnNlRXhwcihzdHJlYW0pO1xuICAgICAgICBpZiAoc3RyZWFtLm5leHQpXG4gICAgICAgICAgICBzdHJlYW0uZXJyKFwiVW5leHBlY3RlZCB0cmFpbGluZyB0ZXh0XCIpO1xuICAgICAgICBsZXQgbWF0Y2ggPSBkZmEobmZhKGV4cHIpKTtcbiAgICAgICAgY2hlY2tGb3JEZWFkRW5kcyhtYXRjaCwgc3RyZWFtKTtcbiAgICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH1cbiAgICAvKipcbiAgICBNYXRjaCBhIG5vZGUgdHlwZSwgcmV0dXJuaW5nIGEgbWF0Y2ggYWZ0ZXIgdGhhdCBub2RlIGlmXG4gICAgc3VjY2Vzc2Z1bC5cbiAgICAqL1xuICAgIG1hdGNoVHlwZSh0eXBlKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uZXh0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKHRoaXMubmV4dFtpXS50eXBlID09IHR5cGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmV4dFtpXS5uZXh0O1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgVHJ5IHRvIG1hdGNoIGEgZnJhZ21lbnQuIFJldHVybnMgdGhlIHJlc3VsdGluZyBtYXRjaCB3aGVuXG4gICAgc3VjY2Vzc2Z1bC5cbiAgICAqL1xuICAgIG1hdGNoRnJhZ21lbnQoZnJhZywgc3RhcnQgPSAwLCBlbmQgPSBmcmFnLmNoaWxkQ291bnQpIHtcbiAgICAgICAgbGV0IGN1ciA9IHRoaXM7XG4gICAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgY3VyICYmIGkgPCBlbmQ7IGkrKylcbiAgICAgICAgICAgIGN1ciA9IGN1ci5tYXRjaFR5cGUoZnJhZy5jaGlsZChpKS50eXBlKTtcbiAgICAgICAgcmV0dXJuIGN1cjtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBnZXQgaW5saW5lQ29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmV4dC5sZW5ndGggIT0gMCAmJiB0aGlzLm5leHRbMF0udHlwZS5pc0lubGluZTtcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBmaXJzdCBtYXRjaGluZyBub2RlIHR5cGUgYXQgdGhpcyBtYXRjaCBwb3NpdGlvbiB0aGF0IGNhblxuICAgIGJlIGdlbmVyYXRlZC5cbiAgICAqL1xuICAgIGdldCBkZWZhdWx0VHlwZSgpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5leHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB7IHR5cGUgfSA9IHRoaXMubmV4dFtpXTtcbiAgICAgICAgICAgIGlmICghKHR5cGUuaXNUZXh0IHx8IHR5cGUuaGFzUmVxdWlyZWRBdHRycygpKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gdHlwZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb21wYXRpYmxlKG90aGVyKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uZXh0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBvdGhlci5uZXh0Lmxlbmd0aDsgaisrKVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm5leHRbaV0udHlwZSA9PSBvdGhlci5uZXh0W2pdLnR5cGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8qKlxuICAgIFRyeSB0byBtYXRjaCB0aGUgZ2l2ZW4gZnJhZ21lbnQsIGFuZCBpZiB0aGF0IGZhaWxzLCBzZWUgaWYgaXQgY2FuXG4gICAgYmUgbWFkZSB0byBtYXRjaCBieSBpbnNlcnRpbmcgbm9kZXMgaW4gZnJvbnQgb2YgaXQuIFdoZW5cbiAgICBzdWNjZXNzZnVsLCByZXR1cm4gYSBmcmFnbWVudCBvZiBpbnNlcnRlZCBub2RlcyAod2hpY2ggbWF5IGJlXG4gICAgZW1wdHkgaWYgbm90aGluZyBoYWQgdG8gYmUgaW5zZXJ0ZWQpLiBXaGVuIGB0b0VuZGAgaXMgdHJ1ZSwgb25seVxuICAgIHJldHVybiBhIGZyYWdtZW50IGlmIHRoZSByZXN1bHRpbmcgbWF0Y2ggZ29lcyB0byB0aGUgZW5kIG9mIHRoZVxuICAgIGNvbnRlbnQgZXhwcmVzc2lvbi5cbiAgICAqL1xuICAgIGZpbGxCZWZvcmUoYWZ0ZXIsIHRvRW5kID0gZmFsc2UsIHN0YXJ0SW5kZXggPSAwKSB7XG4gICAgICAgIGxldCBzZWVuID0gW3RoaXNdO1xuICAgICAgICBmdW5jdGlvbiBzZWFyY2gobWF0Y2gsIHR5cGVzKSB7XG4gICAgICAgICAgICBsZXQgZmluaXNoZWQgPSBtYXRjaC5tYXRjaEZyYWdtZW50KGFmdGVyLCBzdGFydEluZGV4KTtcbiAgICAgICAgICAgIGlmIChmaW5pc2hlZCAmJiAoIXRvRW5kIHx8IGZpbmlzaGVkLnZhbGlkRW5kKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gRnJhZ21lbnQuZnJvbSh0eXBlcy5tYXAodHAgPT4gdHAuY3JlYXRlQW5kRmlsbCgpKSk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hdGNoLm5leHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgeyB0eXBlLCBuZXh0IH0gPSBtYXRjaC5uZXh0W2ldO1xuICAgICAgICAgICAgICAgIGlmICghKHR5cGUuaXNUZXh0IHx8IHR5cGUuaGFzUmVxdWlyZWRBdHRycygpKSAmJiBzZWVuLmluZGV4T2YobmV4dCkgPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgc2Vlbi5wdXNoKG5leHQpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgZm91bmQgPSBzZWFyY2gobmV4dCwgdHlwZXMuY29uY2F0KHR5cGUpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZvdW5kKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZvdW5kO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzZWFyY2godGhpcywgW10pO1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIGEgc2V0IG9mIHdyYXBwaW5nIG5vZGUgdHlwZXMgdGhhdCB3b3VsZCBhbGxvdyBhIG5vZGUgb2YgdGhlXG4gICAgZ2l2ZW4gdHlwZSB0byBhcHBlYXIgYXQgdGhpcyBwb3NpdGlvbi4gVGhlIHJlc3VsdCBtYXkgYmUgZW1wdHlcbiAgICAod2hlbiBpdCBmaXRzIGRpcmVjdGx5KSBhbmQgd2lsbCBiZSBudWxsIHdoZW4gbm8gc3VjaCB3cmFwcGluZ1xuICAgIGV4aXN0cy5cbiAgICAqL1xuICAgIGZpbmRXcmFwcGluZyh0YXJnZXQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLndyYXBDYWNoZS5sZW5ndGg7IGkgKz0gMilcbiAgICAgICAgICAgIGlmICh0aGlzLndyYXBDYWNoZVtpXSA9PSB0YXJnZXQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMud3JhcENhY2hlW2kgKyAxXTtcbiAgICAgICAgbGV0IGNvbXB1dGVkID0gdGhpcy5jb21wdXRlV3JhcHBpbmcodGFyZ2V0KTtcbiAgICAgICAgdGhpcy53cmFwQ2FjaGUucHVzaCh0YXJnZXQsIGNvbXB1dGVkKTtcbiAgICAgICAgcmV0dXJuIGNvbXB1dGVkO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbXB1dGVXcmFwcGluZyh0YXJnZXQpIHtcbiAgICAgICAgbGV0IHNlZW4gPSBPYmplY3QuY3JlYXRlKG51bGwpLCBhY3RpdmUgPSBbeyBtYXRjaDogdGhpcywgdHlwZTogbnVsbCwgdmlhOiBudWxsIH1dO1xuICAgICAgICB3aGlsZSAoYWN0aXZlLmxlbmd0aCkge1xuICAgICAgICAgICAgbGV0IGN1cnJlbnQgPSBhY3RpdmUuc2hpZnQoKSwgbWF0Y2ggPSBjdXJyZW50Lm1hdGNoO1xuICAgICAgICAgICAgaWYgKG1hdGNoLm1hdGNoVHlwZSh0YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IG9iaiA9IGN1cnJlbnQ7IG9iai50eXBlOyBvYmogPSBvYmoudmlhKVxuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChvYmoudHlwZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5yZXZlcnNlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hdGNoLm5leHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgeyB0eXBlLCBuZXh0IH0gPSBtYXRjaC5uZXh0W2ldO1xuICAgICAgICAgICAgICAgIGlmICghdHlwZS5pc0xlYWYgJiYgIXR5cGUuaGFzUmVxdWlyZWRBdHRycygpICYmICEodHlwZS5uYW1lIGluIHNlZW4pICYmICghY3VycmVudC50eXBlIHx8IG5leHQudmFsaWRFbmQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZS5wdXNoKHsgbWF0Y2g6IHR5cGUuY29udGVudE1hdGNoLCB0eXBlLCB2aWE6IGN1cnJlbnQgfSk7XG4gICAgICAgICAgICAgICAgICAgIHNlZW5bdHlwZS5uYW1lXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgbnVtYmVyIG9mIG91dGdvaW5nIGVkZ2VzIHRoaXMgbm9kZSBoYXMgaW4gdGhlIGZpbml0ZVxuICAgIGF1dG9tYXRvbiB0aGF0IGRlc2NyaWJlcyB0aGUgY29udGVudCBleHByZXNzaW9uLlxuICAgICovXG4gICAgZ2V0IGVkZ2VDb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubmV4dC5sZW5ndGg7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgX25fXHUyMDBCdGggb3V0Z29pbmcgZWRnZSBmcm9tIHRoaXMgbm9kZSBpbiB0aGUgZmluaXRlXG4gICAgYXV0b21hdG9uIHRoYXQgZGVzY3JpYmVzIHRoZSBjb250ZW50IGV4cHJlc3Npb24uXG4gICAgKi9cbiAgICBlZGdlKG4pIHtcbiAgICAgICAgaWYgKG4gPj0gdGhpcy5uZXh0Lmxlbmd0aClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBUaGVyZSdzIG5vICR7bn10aCBlZGdlIGluIHRoaXMgY29udGVudCBtYXRjaGApO1xuICAgICAgICByZXR1cm4gdGhpcy5uZXh0W25dO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICBsZXQgc2VlbiA9IFtdO1xuICAgICAgICBmdW5jdGlvbiBzY2FuKG0pIHtcbiAgICAgICAgICAgIHNlZW4ucHVzaChtKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbS5uZXh0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIGlmIChzZWVuLmluZGV4T2YobS5uZXh0W2ldLm5leHQpID09IC0xKVxuICAgICAgICAgICAgICAgICAgICBzY2FuKG0ubmV4dFtpXS5uZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBzY2FuKHRoaXMpO1xuICAgICAgICByZXR1cm4gc2Vlbi5tYXAoKG0sIGkpID0+IHtcbiAgICAgICAgICAgIGxldCBvdXQgPSBpICsgKG0udmFsaWRFbmQgPyBcIipcIiA6IFwiIFwiKSArIFwiIFwiO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtLm5leHQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgb3V0ICs9IChpID8gXCIsIFwiIDogXCJcIikgKyBtLm5leHRbaV0udHlwZS5uYW1lICsgXCItPlwiICsgc2Vlbi5pbmRleE9mKG0ubmV4dFtpXS5uZXh0KTtcbiAgICAgICAgICAgIHJldHVybiBvdXQ7XG4gICAgICAgIH0pLmpvaW4oXCJcXG5cIik7XG4gICAgfVxufVxuLyoqXG5AaW50ZXJuYWxcbiovXG5Db250ZW50TWF0Y2guZW1wdHkgPSBuZXcgQ29udGVudE1hdGNoKHRydWUpO1xuY2xhc3MgVG9rZW5TdHJlYW0ge1xuICAgIGNvbnN0cnVjdG9yKHN0cmluZywgbm9kZVR5cGVzKSB7XG4gICAgICAgIHRoaXMuc3RyaW5nID0gc3RyaW5nO1xuICAgICAgICB0aGlzLm5vZGVUeXBlcyA9IG5vZGVUeXBlcztcbiAgICAgICAgdGhpcy5pbmxpbmUgPSBudWxsO1xuICAgICAgICB0aGlzLnBvcyA9IDA7XG4gICAgICAgIHRoaXMudG9rZW5zID0gc3RyaW5nLnNwbGl0KC9cXHMqKD89XFxifFxcV3wkKS8pO1xuICAgICAgICBpZiAodGhpcy50b2tlbnNbdGhpcy50b2tlbnMubGVuZ3RoIC0gMV0gPT0gXCJcIilcbiAgICAgICAgICAgIHRoaXMudG9rZW5zLnBvcCgpO1xuICAgICAgICBpZiAodGhpcy50b2tlbnNbMF0gPT0gXCJcIilcbiAgICAgICAgICAgIHRoaXMudG9rZW5zLnNoaWZ0KCk7XG4gICAgfVxuICAgIGdldCBuZXh0KCkgeyByZXR1cm4gdGhpcy50b2tlbnNbdGhpcy5wb3NdOyB9XG4gICAgZWF0KHRvaykgeyByZXR1cm4gdGhpcy5uZXh0ID09IHRvayAmJiAodGhpcy5wb3MrKyB8fCB0cnVlKTsgfVxuICAgIGVycihzdHIpIHsgdGhyb3cgbmV3IFN5bnRheEVycm9yKHN0ciArIFwiIChpbiBjb250ZW50IGV4cHJlc3Npb24gJ1wiICsgdGhpcy5zdHJpbmcgKyBcIicpXCIpOyB9XG59XG5mdW5jdGlvbiBwYXJzZUV4cHIoc3RyZWFtKSB7XG4gICAgbGV0IGV4cHJzID0gW107XG4gICAgZG8ge1xuICAgICAgICBleHBycy5wdXNoKHBhcnNlRXhwclNlcShzdHJlYW0pKTtcbiAgICB9IHdoaWxlIChzdHJlYW0uZWF0KFwifFwiKSk7XG4gICAgcmV0dXJuIGV4cHJzLmxlbmd0aCA9PSAxID8gZXhwcnNbMF0gOiB7IHR5cGU6IFwiY2hvaWNlXCIsIGV4cHJzIH07XG59XG5mdW5jdGlvbiBwYXJzZUV4cHJTZXEoc3RyZWFtKSB7XG4gICAgbGV0IGV4cHJzID0gW107XG4gICAgZG8ge1xuICAgICAgICBleHBycy5wdXNoKHBhcnNlRXhwclN1YnNjcmlwdChzdHJlYW0pKTtcbiAgICB9IHdoaWxlIChzdHJlYW0ubmV4dCAmJiBzdHJlYW0ubmV4dCAhPSBcIilcIiAmJiBzdHJlYW0ubmV4dCAhPSBcInxcIik7XG4gICAgcmV0dXJuIGV4cHJzLmxlbmd0aCA9PSAxID8gZXhwcnNbMF0gOiB7IHR5cGU6IFwic2VxXCIsIGV4cHJzIH07XG59XG5mdW5jdGlvbiBwYXJzZUV4cHJTdWJzY3JpcHQoc3RyZWFtKSB7XG4gICAgbGV0IGV4cHIgPSBwYXJzZUV4cHJBdG9tKHN0cmVhbSk7XG4gICAgZm9yICg7Oykge1xuICAgICAgICBpZiAoc3RyZWFtLmVhdChcIitcIikpXG4gICAgICAgICAgICBleHByID0geyB0eXBlOiBcInBsdXNcIiwgZXhwciB9O1xuICAgICAgICBlbHNlIGlmIChzdHJlYW0uZWF0KFwiKlwiKSlcbiAgICAgICAgICAgIGV4cHIgPSB7IHR5cGU6IFwic3RhclwiLCBleHByIH07XG4gICAgICAgIGVsc2UgaWYgKHN0cmVhbS5lYXQoXCI/XCIpKVxuICAgICAgICAgICAgZXhwciA9IHsgdHlwZTogXCJvcHRcIiwgZXhwciB9O1xuICAgICAgICBlbHNlIGlmIChzdHJlYW0uZWF0KFwie1wiKSlcbiAgICAgICAgICAgIGV4cHIgPSBwYXJzZUV4cHJSYW5nZShzdHJlYW0sIGV4cHIpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGV4cHI7XG59XG5mdW5jdGlvbiBwYXJzZU51bShzdHJlYW0pIHtcbiAgICBpZiAoL1xcRC8udGVzdChzdHJlYW0ubmV4dCkpXG4gICAgICAgIHN0cmVhbS5lcnIoXCJFeHBlY3RlZCBudW1iZXIsIGdvdCAnXCIgKyBzdHJlYW0ubmV4dCArIFwiJ1wiKTtcbiAgICBsZXQgcmVzdWx0ID0gTnVtYmVyKHN0cmVhbS5uZXh0KTtcbiAgICBzdHJlYW0ucG9zKys7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIHBhcnNlRXhwclJhbmdlKHN0cmVhbSwgZXhwcikge1xuICAgIGxldCBtaW4gPSBwYXJzZU51bShzdHJlYW0pLCBtYXggPSBtaW47XG4gICAgaWYgKHN0cmVhbS5lYXQoXCIsXCIpKSB7XG4gICAgICAgIGlmIChzdHJlYW0ubmV4dCAhPSBcIn1cIilcbiAgICAgICAgICAgIG1heCA9IHBhcnNlTnVtKHN0cmVhbSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIG1heCA9IC0xO1xuICAgIH1cbiAgICBpZiAoIXN0cmVhbS5lYXQoXCJ9XCIpKVxuICAgICAgICBzdHJlYW0uZXJyKFwiVW5jbG9zZWQgYnJhY2VkIHJhbmdlXCIpO1xuICAgIHJldHVybiB7IHR5cGU6IFwicmFuZ2VcIiwgbWluLCBtYXgsIGV4cHIgfTtcbn1cbmZ1bmN0aW9uIHJlc29sdmVOYW1lKHN0cmVhbSwgbmFtZSkge1xuICAgIGxldCB0eXBlcyA9IHN0cmVhbS5ub2RlVHlwZXMsIHR5cGUgPSB0eXBlc1tuYW1lXTtcbiAgICBpZiAodHlwZSlcbiAgICAgICAgcmV0dXJuIFt0eXBlXTtcbiAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgZm9yIChsZXQgdHlwZU5hbWUgaW4gdHlwZXMpIHtcbiAgICAgICAgbGV0IHR5cGUgPSB0eXBlc1t0eXBlTmFtZV07XG4gICAgICAgIGlmICh0eXBlLmlzSW5Hcm91cChuYW1lKSlcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHR5cGUpO1xuICAgIH1cbiAgICBpZiAocmVzdWx0Lmxlbmd0aCA9PSAwKVxuICAgICAgICBzdHJlYW0uZXJyKFwiTm8gbm9kZSB0eXBlIG9yIGdyb3VwICdcIiArIG5hbWUgKyBcIicgZm91bmRcIik7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIHBhcnNlRXhwckF0b20oc3RyZWFtKSB7XG4gICAgaWYgKHN0cmVhbS5lYXQoXCIoXCIpKSB7XG4gICAgICAgIGxldCBleHByID0gcGFyc2VFeHByKHN0cmVhbSk7XG4gICAgICAgIGlmICghc3RyZWFtLmVhdChcIilcIikpXG4gICAgICAgICAgICBzdHJlYW0uZXJyKFwiTWlzc2luZyBjbG9zaW5nIHBhcmVuXCIpO1xuICAgICAgICByZXR1cm4gZXhwcjtcbiAgICB9XG4gICAgZWxzZSBpZiAoIS9cXFcvLnRlc3Qoc3RyZWFtLm5leHQpKSB7XG4gICAgICAgIGxldCBleHBycyA9IHJlc29sdmVOYW1lKHN0cmVhbSwgc3RyZWFtLm5leHQpLm1hcCh0eXBlID0+IHtcbiAgICAgICAgICAgIGlmIChzdHJlYW0uaW5saW5lID09IG51bGwpXG4gICAgICAgICAgICAgICAgc3RyZWFtLmlubGluZSA9IHR5cGUuaXNJbmxpbmU7XG4gICAgICAgICAgICBlbHNlIGlmIChzdHJlYW0uaW5saW5lICE9IHR5cGUuaXNJbmxpbmUpXG4gICAgICAgICAgICAgICAgc3RyZWFtLmVycihcIk1peGluZyBpbmxpbmUgYW5kIGJsb2NrIGNvbnRlbnRcIik7XG4gICAgICAgICAgICByZXR1cm4geyB0eXBlOiBcIm5hbWVcIiwgdmFsdWU6IHR5cGUgfTtcbiAgICAgICAgfSk7XG4gICAgICAgIHN0cmVhbS5wb3MrKztcbiAgICAgICAgcmV0dXJuIGV4cHJzLmxlbmd0aCA9PSAxID8gZXhwcnNbMF0gOiB7IHR5cGU6IFwiY2hvaWNlXCIsIGV4cHJzIH07XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzdHJlYW0uZXJyKFwiVW5leHBlY3RlZCB0b2tlbiAnXCIgKyBzdHJlYW0ubmV4dCArIFwiJ1wiKTtcbiAgICB9XG59XG4vLyBDb25zdHJ1Y3QgYW4gTkZBIGZyb20gYW4gZXhwcmVzc2lvbiBhcyByZXR1cm5lZCBieSB0aGUgcGFyc2VyLiBUaGVcbi8vIE5GQSBpcyByZXByZXNlbnRlZCBhcyBhbiBhcnJheSBvZiBzdGF0ZXMsIHdoaWNoIGFyZSB0aGVtc2VsdmVzXG4vLyBhcnJheXMgb2YgZWRnZXMsIHdoaWNoIGFyZSBge3Rlcm0sIHRvfWAgb2JqZWN0cy4gVGhlIGZpcnN0IHN0YXRlIGlzXG4vLyB0aGUgZW50cnkgc3RhdGUgYW5kIHRoZSBsYXN0IG5vZGUgaXMgdGhlIHN1Y2Nlc3Mgc3RhdGUuXG4vL1xuLy8gTm90ZSB0aGF0IHVubGlrZSB0eXBpY2FsIE5GQXMsIHRoZSBlZGdlIG9yZGVyaW5nIGluIHRoaXMgb25lIGlzXG4vLyBzaWduaWZpY2FudCwgaW4gdGhhdCBpdCBpcyB1c2VkIHRvIGNvbnRydWN0IGZpbGxlciBjb250ZW50IHdoZW5cbi8vIG5lY2Vzc2FyeS5cbmZ1bmN0aW9uIG5mYShleHByKSB7XG4gICAgbGV0IG5mYSA9IFtbXV07XG4gICAgY29ubmVjdChjb21waWxlKGV4cHIsIDApLCBub2RlKCkpO1xuICAgIHJldHVybiBuZmE7XG4gICAgZnVuY3Rpb24gbm9kZSgpIHsgcmV0dXJuIG5mYS5wdXNoKFtdKSAtIDE7IH1cbiAgICBmdW5jdGlvbiBlZGdlKGZyb20sIHRvLCB0ZXJtKSB7XG4gICAgICAgIGxldCBlZGdlID0geyB0ZXJtLCB0byB9O1xuICAgICAgICBuZmFbZnJvbV0ucHVzaChlZGdlKTtcbiAgICAgICAgcmV0dXJuIGVkZ2U7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNvbm5lY3QoZWRnZXMsIHRvKSB7XG4gICAgICAgIGVkZ2VzLmZvckVhY2goZWRnZSA9PiBlZGdlLnRvID0gdG8pO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjb21waWxlKGV4cHIsIGZyb20pIHtcbiAgICAgICAgaWYgKGV4cHIudHlwZSA9PSBcImNob2ljZVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gZXhwci5leHBycy5yZWR1Y2UoKG91dCwgZXhwcikgPT4gb3V0LmNvbmNhdChjb21waWxlKGV4cHIsIGZyb20pKSwgW10pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV4cHIudHlwZSA9PSBcInNlcVwiKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDs7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gY29tcGlsZShleHByLmV4cHJzW2ldLCBmcm9tKTtcbiAgICAgICAgICAgICAgICBpZiAoaSA9PSBleHByLmV4cHJzLmxlbmd0aCAtIDEpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICAgICAgICAgIGNvbm5lY3QobmV4dCwgZnJvbSA9IG5vZGUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXhwci50eXBlID09IFwic3RhclwiKSB7XG4gICAgICAgICAgICBsZXQgbG9vcCA9IG5vZGUoKTtcbiAgICAgICAgICAgIGVkZ2UoZnJvbSwgbG9vcCk7XG4gICAgICAgICAgICBjb25uZWN0KGNvbXBpbGUoZXhwci5leHByLCBsb29wKSwgbG9vcCk7XG4gICAgICAgICAgICByZXR1cm4gW2VkZ2UobG9vcCldO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV4cHIudHlwZSA9PSBcInBsdXNcIikge1xuICAgICAgICAgICAgbGV0IGxvb3AgPSBub2RlKCk7XG4gICAgICAgICAgICBjb25uZWN0KGNvbXBpbGUoZXhwci5leHByLCBmcm9tKSwgbG9vcCk7XG4gICAgICAgICAgICBjb25uZWN0KGNvbXBpbGUoZXhwci5leHByLCBsb29wKSwgbG9vcCk7XG4gICAgICAgICAgICByZXR1cm4gW2VkZ2UobG9vcCldO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV4cHIudHlwZSA9PSBcIm9wdFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gW2VkZ2UoZnJvbSldLmNvbmNhdChjb21waWxlKGV4cHIuZXhwciwgZnJvbSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV4cHIudHlwZSA9PSBcInJhbmdlXCIpIHtcbiAgICAgICAgICAgIGxldCBjdXIgPSBmcm9tO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBleHByLm1pbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5leHQgPSBub2RlKCk7XG4gICAgICAgICAgICAgICAgY29ubmVjdChjb21waWxlKGV4cHIuZXhwciwgY3VyKSwgbmV4dCk7XG4gICAgICAgICAgICAgICAgY3VyID0gbmV4dDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChleHByLm1heCA9PSAtMSkge1xuICAgICAgICAgICAgICAgIGNvbm5lY3QoY29tcGlsZShleHByLmV4cHIsIGN1ciksIGN1cik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gZXhwci5taW47IGkgPCBleHByLm1heDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gbm9kZSgpO1xuICAgICAgICAgICAgICAgICAgICBlZGdlKGN1ciwgbmV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3QoY29tcGlsZShleHByLmV4cHIsIGN1ciksIG5leHQpO1xuICAgICAgICAgICAgICAgICAgICBjdXIgPSBuZXh0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBbZWRnZShjdXIpXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChleHByLnR5cGUgPT0gXCJuYW1lXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBbZWRnZShmcm9tLCB1bmRlZmluZWQsIGV4cHIudmFsdWUpXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVua25vd24gZXhwciB0eXBlXCIpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gY21wKGEsIGIpIHsgcmV0dXJuIGIgLSBhOyB9XG4vLyBHZXQgdGhlIHNldCBvZiBub2RlcyByZWFjaGFibGUgYnkgbnVsbCBlZGdlcyBmcm9tIGBub2RlYC4gT21pdFxuLy8gbm9kZXMgd2l0aCBvbmx5IGEgc2luZ2xlIG51bGwtb3V0LWVkZ2UsIHNpbmNlIHRoZXkgbWF5IGxlYWQgdG9cbi8vIG5lZWRsZXNzIGR1cGxpY2F0ZWQgbm9kZXMuXG5mdW5jdGlvbiBudWxsRnJvbShuZmEsIG5vZGUpIHtcbiAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgc2Nhbihub2RlKTtcbiAgICByZXR1cm4gcmVzdWx0LnNvcnQoY21wKTtcbiAgICBmdW5jdGlvbiBzY2FuKG5vZGUpIHtcbiAgICAgICAgbGV0IGVkZ2VzID0gbmZhW25vZGVdO1xuICAgICAgICBpZiAoZWRnZXMubGVuZ3RoID09IDEgJiYgIWVkZ2VzWzBdLnRlcm0pXG4gICAgICAgICAgICByZXR1cm4gc2NhbihlZGdlc1swXS50byk7XG4gICAgICAgIHJlc3VsdC5wdXNoKG5vZGUpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVkZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgeyB0ZXJtLCB0byB9ID0gZWRnZXNbaV07XG4gICAgICAgICAgICBpZiAoIXRlcm0gJiYgcmVzdWx0LmluZGV4T2YodG8pID09IC0xKVxuICAgICAgICAgICAgICAgIHNjYW4odG8pO1xuICAgICAgICB9XG4gICAgfVxufVxuLy8gQ29tcGlsZXMgYW4gTkZBIGFzIHByb2R1Y2VkIGJ5IGBuZmFgIGludG8gYSBERkEsIG1vZGVsZWQgYXMgYSBzZXRcbi8vIG9mIHN0YXRlIG9iamVjdHMgKGBDb250ZW50TWF0Y2hgIGluc3RhbmNlcykgd2l0aCB0cmFuc2l0aW9uc1xuLy8gYmV0d2VlbiB0aGVtLlxuZnVuY3Rpb24gZGZhKG5mYSkge1xuICAgIGxldCBsYWJlbGVkID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICByZXR1cm4gZXhwbG9yZShudWxsRnJvbShuZmEsIDApKTtcbiAgICBmdW5jdGlvbiBleHBsb3JlKHN0YXRlcykge1xuICAgICAgICBsZXQgb3V0ID0gW107XG4gICAgICAgIHN0YXRlcy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgbmZhW25vZGVdLmZvckVhY2goKHsgdGVybSwgdG8gfSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghdGVybSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGxldCBzZXQ7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgICAgIGlmIChvdXRbaV1bMF0gPT0gdGVybSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldCA9IG91dFtpXVsxXTtcbiAgICAgICAgICAgICAgICBudWxsRnJvbShuZmEsIHRvKS5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXNldClcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dC5wdXNoKFt0ZXJtLCBzZXQgPSBbXV0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2V0LmluZGV4T2Yobm9kZSkgPT0gLTEpXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQucHVzaChub2RlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgbGV0IHN0YXRlID0gbGFiZWxlZFtzdGF0ZXMuam9pbihcIixcIildID0gbmV3IENvbnRlbnRNYXRjaChzdGF0ZXMuaW5kZXhPZihuZmEubGVuZ3RoIC0gMSkgPiAtMSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgc3RhdGVzID0gb3V0W2ldWzFdLnNvcnQoY21wKTtcbiAgICAgICAgICAgIHN0YXRlLm5leHQucHVzaCh7IHR5cGU6IG91dFtpXVswXSwgbmV4dDogbGFiZWxlZFtzdGF0ZXMuam9pbihcIixcIildIHx8IGV4cGxvcmUoc3RhdGVzKSB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgfVxufVxuZnVuY3Rpb24gY2hlY2tGb3JEZWFkRW5kcyhtYXRjaCwgc3RyZWFtKSB7XG4gICAgZm9yIChsZXQgaSA9IDAsIHdvcmsgPSBbbWF0Y2hdOyBpIDwgd29yay5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgc3RhdGUgPSB3b3JrW2ldLCBkZWFkID0gIXN0YXRlLnZhbGlkRW5kLCBub2RlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHN0YXRlLm5leHQubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICAgIGxldCB7IHR5cGUsIG5leHQgfSA9IHN0YXRlLm5leHRbal07XG4gICAgICAgICAgICBub2Rlcy5wdXNoKHR5cGUubmFtZSk7XG4gICAgICAgICAgICBpZiAoZGVhZCAmJiAhKHR5cGUuaXNUZXh0IHx8IHR5cGUuaGFzUmVxdWlyZWRBdHRycygpKSlcbiAgICAgICAgICAgICAgICBkZWFkID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAod29yay5pbmRleE9mKG5leHQpID09IC0xKVxuICAgICAgICAgICAgICAgIHdvcmsucHVzaChuZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVhZClcbiAgICAgICAgICAgIHN0cmVhbS5lcnIoXCJPbmx5IG5vbi1nZW5lcmF0YWJsZSBub2RlcyAoXCIgKyBub2Rlcy5qb2luKFwiLCBcIikgKyBcIikgaW4gYSByZXF1aXJlZCBwb3NpdGlvbiAoc2VlIGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvZ3VpZGUvI2dlbmVyYXRhYmxlKVwiKTtcbiAgICB9XG59XG5cbi8vIEZvciBub2RlIHR5cGVzIHdoZXJlIGFsbCBhdHRycyBoYXZlIGEgZGVmYXVsdCB2YWx1ZSAob3Igd2hpY2ggZG9uJ3Rcbi8vIGhhdmUgYW55IGF0dHJpYnV0ZXMpLCBidWlsZCB1cCBhIHNpbmdsZSByZXVzYWJsZSBkZWZhdWx0IGF0dHJpYnV0ZVxuLy8gb2JqZWN0LCBhbmQgdXNlIGl0IGZvciBhbGwgbm9kZXMgdGhhdCBkb24ndCBzcGVjaWZ5IHNwZWNpZmljXG4vLyBhdHRyaWJ1dGVzLlxuZnVuY3Rpb24gZGVmYXVsdEF0dHJzKGF0dHJzKSB7XG4gICAgbGV0IGRlZmF1bHRzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICBmb3IgKGxldCBhdHRyTmFtZSBpbiBhdHRycykge1xuICAgICAgICBsZXQgYXR0ciA9IGF0dHJzW2F0dHJOYW1lXTtcbiAgICAgICAgaWYgKCFhdHRyLmhhc0RlZmF1bHQpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgZGVmYXVsdHNbYXR0ck5hbWVdID0gYXR0ci5kZWZhdWx0O1xuICAgIH1cbiAgICByZXR1cm4gZGVmYXVsdHM7XG59XG5mdW5jdGlvbiBjb21wdXRlQXR0cnMoYXR0cnMsIHZhbHVlKSB7XG4gICAgbGV0IGJ1aWx0ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICBmb3IgKGxldCBuYW1lIGluIGF0dHJzKSB7XG4gICAgICAgIGxldCBnaXZlbiA9IHZhbHVlICYmIHZhbHVlW25hbWVdO1xuICAgICAgICBpZiAoZ2l2ZW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbGV0IGF0dHIgPSBhdHRyc1tuYW1lXTtcbiAgICAgICAgICAgIGlmIChhdHRyLmhhc0RlZmF1bHQpXG4gICAgICAgICAgICAgICAgZ2l2ZW4gPSBhdHRyLmRlZmF1bHQ7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJObyB2YWx1ZSBzdXBwbGllZCBmb3IgYXR0cmlidXRlIFwiICsgbmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgYnVpbHRbbmFtZV0gPSBnaXZlbjtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWx0O1xufVxuZnVuY3Rpb24gY2hlY2tBdHRycyhhdHRycywgdmFsdWVzLCB0eXBlLCBuYW1lKSB7XG4gICAgZm9yIChsZXQgbmFtZSBpbiB2YWx1ZXMpXG4gICAgICAgIGlmICghKG5hbWUgaW4gYXR0cnMpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYFVuc3VwcG9ydGVkIGF0dHJpYnV0ZSAke25hbWV9IGZvciAke3R5cGV9IG9mIHR5cGUgJHtuYW1lfWApO1xuICAgIGZvciAobGV0IG5hbWUgaW4gYXR0cnMpIHtcbiAgICAgICAgbGV0IGF0dHIgPSBhdHRyc1tuYW1lXTtcbiAgICAgICAgaWYgKGF0dHIudmFsaWRhdGUpXG4gICAgICAgICAgICBhdHRyLnZhbGlkYXRlKHZhbHVlc1tuYW1lXSk7XG4gICAgfVxufVxuZnVuY3Rpb24gaW5pdEF0dHJzKHR5cGVOYW1lLCBhdHRycykge1xuICAgIGxldCByZXN1bHQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIGlmIChhdHRycylcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBhdHRycylcbiAgICAgICAgICAgIHJlc3VsdFtuYW1lXSA9IG5ldyBBdHRyaWJ1dGUodHlwZU5hbWUsIG5hbWUsIGF0dHJzW25hbWVdKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLyoqXG5Ob2RlIHR5cGVzIGFyZSBvYmplY3RzIGFsbG9jYXRlZCBvbmNlIHBlciBgU2NoZW1hYCBhbmQgdXNlZCB0b1xuW3RhZ10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGUudHlwZSkgYE5vZGVgIGluc3RhbmNlcy4gVGhleSBjb250YWluIGluZm9ybWF0aW9uXG5hYm91dCB0aGUgbm9kZSB0eXBlLCBzdWNoIGFzIGl0cyBuYW1lIGFuZCB3aGF0IGtpbmQgb2Ygbm9kZSBpdFxucmVwcmVzZW50cy5cbiovXG5jbGFzcyBOb2RlVHlwZSB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgbmFtZSB0aGUgbm9kZSB0eXBlIGhhcyBpbiB0aGlzIHNjaGVtYS5cbiAgICAqL1xuICAgIG5hbWUsIFxuICAgIC8qKlxuICAgIEEgbGluayBiYWNrIHRvIHRoZSBgU2NoZW1hYCB0aGUgbm9kZSB0eXBlIGJlbG9uZ3MgdG8uXG4gICAgKi9cbiAgICBzY2hlbWEsIFxuICAgIC8qKlxuICAgIFRoZSBzcGVjIHRoYXQgdGhpcyB0eXBlIGlzIGJhc2VkIG9uXG4gICAgKi9cbiAgICBzcGVjKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMuc2NoZW1hID0gc2NoZW1hO1xuICAgICAgICB0aGlzLnNwZWMgPSBzcGVjO1xuICAgICAgICAvKipcbiAgICAgICAgVGhlIHNldCBvZiBtYXJrcyBhbGxvd2VkIGluIHRoaXMgbm9kZS4gYG51bGxgIG1lYW5zIGFsbCBtYXJrc1xuICAgICAgICBhcmUgYWxsb3dlZC5cbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5tYXJrU2V0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5ncm91cHMgPSBzcGVjLmdyb3VwID8gc3BlYy5ncm91cC5zcGxpdChcIiBcIikgOiBbXTtcbiAgICAgICAgdGhpcy5hdHRycyA9IGluaXRBdHRycyhuYW1lLCBzcGVjLmF0dHJzKTtcbiAgICAgICAgdGhpcy5kZWZhdWx0QXR0cnMgPSBkZWZhdWx0QXR0cnModGhpcy5hdHRycyk7XG4gICAgICAgIHRoaXMuY29udGVudE1hdGNoID0gbnVsbDtcbiAgICAgICAgdGhpcy5pbmxpbmVDb250ZW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy5pc0Jsb2NrID0gIShzcGVjLmlubGluZSB8fCBuYW1lID09IFwidGV4dFwiKTtcbiAgICAgICAgdGhpcy5pc1RleHQgPSBuYW1lID09IFwidGV4dFwiO1xuICAgIH1cbiAgICAvKipcbiAgICBUcnVlIGlmIHRoaXMgaXMgYW4gaW5saW5lIHR5cGUuXG4gICAgKi9cbiAgICBnZXQgaXNJbmxpbmUoKSB7IHJldHVybiAhdGhpcy5pc0Jsb2NrOyB9XG4gICAgLyoqXG4gICAgVHJ1ZSBpZiB0aGlzIGlzIGEgdGV4dGJsb2NrIHR5cGUsIGEgYmxvY2sgdGhhdCBjb250YWlucyBpbmxpbmVcbiAgICBjb250ZW50LlxuICAgICovXG4gICAgZ2V0IGlzVGV4dGJsb2NrKCkgeyByZXR1cm4gdGhpcy5pc0Jsb2NrICYmIHRoaXMuaW5saW5lQ29udGVudDsgfVxuICAgIC8qKlxuICAgIFRydWUgZm9yIG5vZGUgdHlwZXMgdGhhdCBhbGxvdyBubyBjb250ZW50LlxuICAgICovXG4gICAgZ2V0IGlzTGVhZigpIHsgcmV0dXJuIHRoaXMuY29udGVudE1hdGNoID09IENvbnRlbnRNYXRjaC5lbXB0eTsgfVxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGlzIG5vZGUgaXMgYW4gYXRvbSwgaS5lLiB3aGVuIGl0IGRvZXMgbm90IGhhdmVcbiAgICBkaXJlY3RseSBlZGl0YWJsZSBjb250ZW50LlxuICAgICovXG4gICAgZ2V0IGlzQXRvbSgpIHsgcmV0dXJuIHRoaXMuaXNMZWFmIHx8ICEhdGhpcy5zcGVjLmF0b207IH1cbiAgICAvKipcbiAgICBSZXR1cm4gdHJ1ZSB3aGVuIHRoaXMgbm9kZSB0eXBlIGlzIHBhcnQgb2YgdGhlIGdpdmVuXG4gICAgW2dyb3VwXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuZ3JvdXApLlxuICAgICovXG4gICAgaXNJbkdyb3VwKGdyb3VwKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdyb3Vwcy5pbmRleE9mKGdyb3VwKSA+IC0xO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgbm9kZSB0eXBlJ3MgW3doaXRlc3BhY2VdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy53aGl0ZXNwYWNlKSBvcHRpb24uXG4gICAgKi9cbiAgICBnZXQgd2hpdGVzcGFjZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3BlYy53aGl0ZXNwYWNlIHx8ICh0aGlzLnNwZWMuY29kZSA/IFwicHJlXCIgOiBcIm5vcm1hbFwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGVsbHMgeW91IHdoZXRoZXIgdGhpcyBub2RlIHR5cGUgaGFzIGFueSByZXF1aXJlZCBhdHRyaWJ1dGVzLlxuICAgICovXG4gICAgaGFzUmVxdWlyZWRBdHRycygpIHtcbiAgICAgICAgZm9yIChsZXQgbiBpbiB0aGlzLmF0dHJzKVxuICAgICAgICAgICAgaWYgKHRoaXMuYXR0cnNbbl0uaXNSZXF1aXJlZClcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvKipcbiAgICBJbmRpY2F0ZXMgd2hldGhlciB0aGlzIG5vZGUgYWxsb3dzIHNvbWUgb2YgdGhlIHNhbWUgY29udGVudCBhc1xuICAgIHRoZSBnaXZlbiBub2RlIHR5cGUuXG4gICAgKi9cbiAgICBjb21wYXRpYmxlQ29udGVudChvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcyA9PSBvdGhlciB8fCB0aGlzLmNvbnRlbnRNYXRjaC5jb21wYXRpYmxlKG90aGVyLmNvbnRlbnRNYXRjaCk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29tcHV0ZUF0dHJzKGF0dHJzKSB7XG4gICAgICAgIGlmICghYXR0cnMgJiYgdGhpcy5kZWZhdWx0QXR0cnMpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZWZhdWx0QXR0cnM7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJldHVybiBjb21wdXRlQXR0cnModGhpcy5hdHRycywgYXR0cnMpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBgTm9kZWAgb2YgdGhpcyB0eXBlLiBUaGUgZ2l2ZW4gYXR0cmlidXRlcyBhcmVcbiAgICBjaGVja2VkIGFuZCBkZWZhdWx0ZWQgKHlvdSBjYW4gcGFzcyBgbnVsbGAgdG8gdXNlIHRoZSB0eXBlJ3NcbiAgICBkZWZhdWx0cyBlbnRpcmVseSwgaWYgbm8gcmVxdWlyZWQgYXR0cmlidXRlcyBleGlzdCkuIGBjb250ZW50YFxuICAgIG1heSBiZSBhIGBGcmFnbWVudGAsIGEgbm9kZSwgYW4gYXJyYXkgb2Ygbm9kZXMsIG9yXG4gICAgYG51bGxgLiBTaW1pbGFybHkgYG1hcmtzYCBtYXkgYmUgYG51bGxgIHRvIGRlZmF1bHQgdG8gdGhlIGVtcHR5XG4gICAgc2V0IG9mIG1hcmtzLlxuICAgICovXG4gICAgY3JlYXRlKGF0dHJzID0gbnVsbCwgY29udGVudCwgbWFya3MpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNUZXh0KVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm9kZVR5cGUuY3JlYXRlIGNhbid0IGNvbnN0cnVjdCB0ZXh0IG5vZGVzXCIpO1xuICAgICAgICByZXR1cm4gbmV3IE5vZGUodGhpcywgdGhpcy5jb21wdXRlQXR0cnMoYXR0cnMpLCBGcmFnbWVudC5mcm9tKGNvbnRlbnQpLCBNYXJrLnNldEZyb20obWFya3MpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgTGlrZSBbYGNyZWF0ZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlVHlwZS5jcmVhdGUpLCBidXQgY2hlY2sgdGhlIGdpdmVuIGNvbnRlbnRcbiAgICBhZ2FpbnN0IHRoZSBub2RlIHR5cGUncyBjb250ZW50IHJlc3RyaWN0aW9ucywgYW5kIHRocm93IGFuIGVycm9yXG4gICAgaWYgaXQgZG9lc24ndCBtYXRjaC5cbiAgICAqL1xuICAgIGNyZWF0ZUNoZWNrZWQoYXR0cnMgPSBudWxsLCBjb250ZW50LCBtYXJrcykge1xuICAgICAgICBjb250ZW50ID0gRnJhZ21lbnQuZnJvbShjb250ZW50KTtcbiAgICAgICAgdGhpcy5jaGVja0NvbnRlbnQoY29udGVudCk7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZSh0aGlzLCB0aGlzLmNvbXB1dGVBdHRycyhhdHRycyksIGNvbnRlbnQsIE1hcmsuc2V0RnJvbShtYXJrcykpO1xuICAgIH1cbiAgICAvKipcbiAgICBMaWtlIFtgY3JlYXRlYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVUeXBlLmNyZWF0ZSksIGJ1dCBzZWUgaWYgaXQgaXNcbiAgICBuZWNlc3NhcnkgdG8gYWRkIG5vZGVzIHRvIHRoZSBzdGFydCBvciBlbmQgb2YgdGhlIGdpdmVuIGZyYWdtZW50XG4gICAgdG8gbWFrZSBpdCBmaXQgdGhlIG5vZGUuIElmIG5vIGZpdHRpbmcgd3JhcHBpbmcgY2FuIGJlIGZvdW5kLFxuICAgIHJldHVybiBudWxsLiBOb3RlIHRoYXQsIGR1ZSB0byB0aGUgZmFjdCB0aGF0IHJlcXVpcmVkIG5vZGVzIGNhblxuICAgIGFsd2F5cyBiZSBjcmVhdGVkLCB0aGlzIHdpbGwgYWx3YXlzIHN1Y2NlZWQgaWYgeW91IHBhc3MgbnVsbCBvclxuICAgIGBGcmFnbWVudC5lbXB0eWAgYXMgY29udGVudC5cbiAgICAqL1xuICAgIGNyZWF0ZUFuZEZpbGwoYXR0cnMgPSBudWxsLCBjb250ZW50LCBtYXJrcykge1xuICAgICAgICBhdHRycyA9IHRoaXMuY29tcHV0ZUF0dHJzKGF0dHJzKTtcbiAgICAgICAgY29udGVudCA9IEZyYWdtZW50LmZyb20oY29udGVudCk7XG4gICAgICAgIGlmIChjb250ZW50LnNpemUpIHtcbiAgICAgICAgICAgIGxldCBiZWZvcmUgPSB0aGlzLmNvbnRlbnRNYXRjaC5maWxsQmVmb3JlKGNvbnRlbnQpO1xuICAgICAgICAgICAgaWYgKCFiZWZvcmUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICBjb250ZW50ID0gYmVmb3JlLmFwcGVuZChjb250ZW50KTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbWF0Y2hlZCA9IHRoaXMuY29udGVudE1hdGNoLm1hdGNoRnJhZ21lbnQoY29udGVudCk7XG4gICAgICAgIGxldCBhZnRlciA9IG1hdGNoZWQgJiYgbWF0Y2hlZC5maWxsQmVmb3JlKEZyYWdtZW50LmVtcHR5LCB0cnVlKTtcbiAgICAgICAgaWYgKCFhZnRlcilcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gbmV3IE5vZGUodGhpcywgYXR0cnMsIGNvbnRlbnQuYXBwZW5kKGFmdGVyKSwgTWFyay5zZXRGcm9tKG1hcmtzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gZnJhZ21lbnQgaXMgdmFsaWQgY29udGVudCBmb3IgdGhpcyBub2RlXG4gICAgdHlwZS5cbiAgICAqL1xuICAgIHZhbGlkQ29udGVudChjb250ZW50KSB7XG4gICAgICAgIGxldCByZXN1bHQgPSB0aGlzLmNvbnRlbnRNYXRjaC5tYXRjaEZyYWdtZW50KGNvbnRlbnQpO1xuICAgICAgICBpZiAoIXJlc3VsdCB8fCAhcmVzdWx0LnZhbGlkRW5kKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnRlbnQuY2hpbGRDb3VudDsgaSsrKVxuICAgICAgICAgICAgaWYgKCF0aGlzLmFsbG93c01hcmtzKGNvbnRlbnQuY2hpbGQoaSkubWFya3MpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgIFRocm93cyBhIFJhbmdlRXJyb3IgaWYgdGhlIGdpdmVuIGZyYWdtZW50IGlzIG5vdCB2YWxpZCBjb250ZW50IGZvciB0aGlzXG4gICAgbm9kZSB0eXBlLlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY2hlY2tDb250ZW50KGNvbnRlbnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLnZhbGlkQ29udGVudChjb250ZW50KSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBJbnZhbGlkIGNvbnRlbnQgZm9yIG5vZGUgJHt0aGlzLm5hbWV9OiAke2NvbnRlbnQudG9TdHJpbmcoKS5zbGljZSgwLCA1MCl9YCk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY2hlY2tBdHRycyhhdHRycykge1xuICAgICAgICBjaGVja0F0dHJzKHRoaXMuYXR0cnMsIGF0dHJzLCBcIm5vZGVcIiwgdGhpcy5uYW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ2hlY2sgd2hldGhlciB0aGUgZ2l2ZW4gbWFyayB0eXBlIGlzIGFsbG93ZWQgaW4gdGhpcyBub2RlLlxuICAgICovXG4gICAgYWxsb3dzTWFya1R5cGUobWFya1R5cGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFya1NldCA9PSBudWxsIHx8IHRoaXMubWFya1NldC5pbmRleE9mKG1hcmtUeXBlKSA+IC0xO1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgdGhlIGdpdmVuIHNldCBvZiBtYXJrcyBhcmUgYWxsb3dlZCBpbiB0aGlzIG5vZGUuXG4gICAgKi9cbiAgICBhbGxvd3NNYXJrcyhtYXJrcykge1xuICAgICAgICBpZiAodGhpcy5tYXJrU2V0ID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmICghdGhpcy5hbGxvd3NNYXJrVHlwZShtYXJrc1tpXS50eXBlKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICBSZW1vdmVzIHRoZSBtYXJrcyB0aGF0IGFyZSBub3QgYWxsb3dlZCBpbiB0aGlzIG5vZGUgZnJvbSB0aGUgZ2l2ZW4gc2V0LlxuICAgICovXG4gICAgYWxsb3dlZE1hcmtzKG1hcmtzKSB7XG4gICAgICAgIGlmICh0aGlzLm1hcmtTZXQgPT0gbnVsbClcbiAgICAgICAgICAgIHJldHVybiBtYXJrcztcbiAgICAgICAgbGV0IGNvcHk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWFya3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5hbGxvd3NNYXJrVHlwZShtYXJrc1tpXS50eXBlKSkge1xuICAgICAgICAgICAgICAgIGlmICghY29weSlcbiAgICAgICAgICAgICAgICAgICAgY29weSA9IG1hcmtzLnNsaWNlKDAsIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY29weSkge1xuICAgICAgICAgICAgICAgIGNvcHkucHVzaChtYXJrc1tpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICFjb3B5ID8gbWFya3MgOiBjb3B5Lmxlbmd0aCA/IGNvcHkgOiBNYXJrLm5vbmU7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIGNvbXBpbGUobm9kZXMsIHNjaGVtYSkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgbm9kZXMuZm9yRWFjaCgobmFtZSwgc3BlYykgPT4gcmVzdWx0W25hbWVdID0gbmV3IE5vZGVUeXBlKG5hbWUsIHNjaGVtYSwgc3BlYykpO1xuICAgICAgICBsZXQgdG9wVHlwZSA9IHNjaGVtYS5zcGVjLnRvcE5vZGUgfHwgXCJkb2NcIjtcbiAgICAgICAgaWYgKCFyZXN1bHRbdG9wVHlwZV0pXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlNjaGVtYSBpcyBtaXNzaW5nIGl0cyB0b3Agbm9kZSB0eXBlICgnXCIgKyB0b3BUeXBlICsgXCInKVwiKTtcbiAgICAgICAgaWYgKCFyZXN1bHQudGV4dClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiRXZlcnkgc2NoZW1hIG5lZWRzIGEgJ3RleHQnIHR5cGVcIik7XG4gICAgICAgIGZvciAobGV0IF8gaW4gcmVzdWx0LnRleHQuYXR0cnMpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlRoZSB0ZXh0IG5vZGUgdHlwZSBzaG91bGQgbm90IGhhdmUgYXR0cmlidXRlc1wiKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG59XG5mdW5jdGlvbiB2YWxpZGF0ZVR5cGUodHlwZU5hbWUsIGF0dHJOYW1lLCB0eXBlKSB7XG4gICAgbGV0IHR5cGVzID0gdHlwZS5zcGxpdChcInxcIik7XG4gICAgcmV0dXJuICh2YWx1ZSkgPT4ge1xuICAgICAgICBsZXQgbmFtZSA9IHZhbHVlID09PSBudWxsID8gXCJudWxsXCIgOiB0eXBlb2YgdmFsdWU7XG4gICAgICAgIGlmICh0eXBlcy5pbmRleE9mKG5hbWUpIDwgMClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBFeHBlY3RlZCB2YWx1ZSBvZiB0eXBlICR7dHlwZXN9IGZvciBhdHRyaWJ1dGUgJHthdHRyTmFtZX0gb24gdHlwZSAke3R5cGVOYW1lfSwgZ290ICR7bmFtZX1gKTtcbiAgICB9O1xufVxuLy8gQXR0cmlidXRlIGRlc2NyaXB0b3JzXG5jbGFzcyBBdHRyaWJ1dGUge1xuICAgIGNvbnN0cnVjdG9yKHR5cGVOYW1lLCBhdHRyTmFtZSwgb3B0aW9ucykge1xuICAgICAgICB0aGlzLmhhc0RlZmF1bHQgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywgXCJkZWZhdWx0XCIpO1xuICAgICAgICB0aGlzLmRlZmF1bHQgPSBvcHRpb25zLmRlZmF1bHQ7XG4gICAgICAgIHRoaXMudmFsaWRhdGUgPSB0eXBlb2Ygb3B0aW9ucy52YWxpZGF0ZSA9PSBcInN0cmluZ1wiID8gdmFsaWRhdGVUeXBlKHR5cGVOYW1lLCBhdHRyTmFtZSwgb3B0aW9ucy52YWxpZGF0ZSkgOiBvcHRpb25zLnZhbGlkYXRlO1xuICAgIH1cbiAgICBnZXQgaXNSZXF1aXJlZCgpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLmhhc0RlZmF1bHQ7XG4gICAgfVxufVxuLy8gTWFya3Ncbi8qKlxuTGlrZSBub2RlcywgbWFya3MgKHdoaWNoIGFyZSBhc3NvY2lhdGVkIHdpdGggbm9kZXMgdG8gc2lnbmlmeVxudGhpbmdzIGxpa2UgZW1waGFzaXMgb3IgYmVpbmcgcGFydCBvZiBhIGxpbmspIGFyZVxuW3RhZ2dlZF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk1hcmsudHlwZSkgd2l0aCB0eXBlIG9iamVjdHMsIHdoaWNoIGFyZVxuaW5zdGFudGlhdGVkIG9uY2UgcGVyIGBTY2hlbWFgLlxuKi9cbmNsYXNzIE1hcmtUeXBlIHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBuYW1lIG9mIHRoZSBtYXJrIHR5cGUuXG4gICAgKi9cbiAgICBuYW1lLCBcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHJhbmssIFxuICAgIC8qKlxuICAgIFRoZSBzY2hlbWEgdGhhdCB0aGlzIG1hcmsgdHlwZSBpbnN0YW5jZSBpcyBwYXJ0IG9mLlxuICAgICovXG4gICAgc2NoZW1hLCBcbiAgICAvKipcbiAgICBUaGUgc3BlYyBvbiB3aGljaCB0aGUgdHlwZSBpcyBiYXNlZC5cbiAgICAqL1xuICAgIHNwZWMpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5yYW5rID0gcmFuaztcbiAgICAgICAgdGhpcy5zY2hlbWEgPSBzY2hlbWE7XG4gICAgICAgIHRoaXMuc3BlYyA9IHNwZWM7XG4gICAgICAgIHRoaXMuYXR0cnMgPSBpbml0QXR0cnMobmFtZSwgc3BlYy5hdHRycyk7XG4gICAgICAgIHRoaXMuZXhjbHVkZWQgPSBudWxsO1xuICAgICAgICBsZXQgZGVmYXVsdHMgPSBkZWZhdWx0QXR0cnModGhpcy5hdHRycyk7XG4gICAgICAgIHRoaXMuaW5zdGFuY2UgPSBkZWZhdWx0cyA/IG5ldyBNYXJrKHRoaXMsIGRlZmF1bHRzKSA6IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG1hcmsgb2YgdGhpcyB0eXBlLiBgYXR0cnNgIG1heSBiZSBgbnVsbGAgb3IgYW4gb2JqZWN0XG4gICAgY29udGFpbmluZyBvbmx5IHNvbWUgb2YgdGhlIG1hcmsncyBhdHRyaWJ1dGVzLiBUaGUgb3RoZXJzLCBpZlxuICAgIHRoZXkgaGF2ZSBkZWZhdWx0cywgd2lsbCBiZSBhZGRlZC5cbiAgICAqL1xuICAgIGNyZWF0ZShhdHRycyA9IG51bGwpIHtcbiAgICAgICAgaWYgKCFhdHRycyAmJiB0aGlzLmluc3RhbmNlKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2U7XG4gICAgICAgIHJldHVybiBuZXcgTWFyayh0aGlzLCBjb21wdXRlQXR0cnModGhpcy5hdHRycywgYXR0cnMpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgY29tcGlsZShtYXJrcywgc2NoZW1hKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBPYmplY3QuY3JlYXRlKG51bGwpLCByYW5rID0gMDtcbiAgICAgICAgbWFya3MuZm9yRWFjaCgobmFtZSwgc3BlYykgPT4gcmVzdWx0W25hbWVdID0gbmV3IE1hcmtUeXBlKG5hbWUsIHJhbmsrKywgc2NoZW1hLCBzcGVjKSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKlxuICAgIFdoZW4gdGhlcmUgaXMgYSBtYXJrIG9mIHRoaXMgdHlwZSBpbiB0aGUgZ2l2ZW4gc2V0LCBhIG5ldyBzZXRcbiAgICB3aXRob3V0IGl0IGlzIHJldHVybmVkLiBPdGhlcndpc2UsIHRoZSBpbnB1dCBzZXQgaXMgcmV0dXJuZWQuXG4gICAgKi9cbiAgICByZW1vdmVGcm9tU2V0KHNldCkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmIChzZXRbaV0udHlwZSA9PSB0aGlzKSB7XG4gICAgICAgICAgICAgICAgc2V0ID0gc2V0LnNsaWNlKDAsIGkpLmNvbmNhdChzZXQuc2xpY2UoaSArIDEpKTtcbiAgICAgICAgICAgICAgICBpLS07XG4gICAgICAgICAgICB9XG4gICAgICAgIHJldHVybiBzZXQ7XG4gICAgfVxuICAgIC8qKlxuICAgIFRlc3RzIHdoZXRoZXIgdGhlcmUgaXMgYSBtYXJrIG9mIHRoaXMgdHlwZSBpbiB0aGUgZ2l2ZW4gc2V0LlxuICAgICovXG4gICAgaXNJblNldChzZXQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAoc2V0W2ldLnR5cGUgPT0gdGhpcylcbiAgICAgICAgICAgICAgICByZXR1cm4gc2V0W2ldO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNoZWNrQXR0cnMoYXR0cnMpIHtcbiAgICAgICAgY2hlY2tBdHRycyh0aGlzLmF0dHJzLCBhdHRycywgXCJtYXJrXCIsIHRoaXMubmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIFF1ZXJpZXMgd2hldGhlciBhIGdpdmVuIG1hcmsgdHlwZSBpc1xuICAgIFtleGNsdWRlZF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk1hcmtTcGVjLmV4Y2x1ZGVzKSBieSB0aGlzIG9uZS5cbiAgICAqL1xuICAgIGV4Y2x1ZGVzKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmV4Y2x1ZGVkLmluZGV4T2Yob3RoZXIpID4gLTE7XG4gICAgfVxufVxuLyoqXG5BIGRvY3VtZW50IHNjaGVtYS4gSG9sZHMgW25vZGVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlVHlwZSkgYW5kIFttYXJrXG50eXBlXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTWFya1R5cGUpIG9iamVjdHMgZm9yIHRoZSBub2RlcyBhbmQgbWFya3MgdGhhdCBtYXlcbm9jY3VyIGluIGNvbmZvcm1pbmcgZG9jdW1lbnRzLCBhbmQgcHJvdmlkZXMgZnVuY3Rpb25hbGl0eSBmb3JcbmNyZWF0aW5nIGFuZCBkZXNlcmlhbGl6aW5nIHN1Y2ggZG9jdW1lbnRzLlxuXG5XaGVuIGdpdmVuLCB0aGUgdHlwZSBwYXJhbWV0ZXJzIHByb3ZpZGUgdGhlIG5hbWVzIG9mIHRoZSBub2RlcyBhbmRcbm1hcmtzIGluIHRoaXMgc2NoZW1hLlxuKi9cbmNsYXNzIFNjaGVtYSB7XG4gICAgLyoqXG4gICAgQ29uc3RydWN0IGEgc2NoZW1hIGZyb20gYSBzY2hlbWEgW3NwZWNpZmljYXRpb25dKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5TY2hlbWFTcGVjKS5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHNwZWMpIHtcbiAgICAgICAgLyoqXG4gICAgICAgIFRoZSBbbGluZWJyZWFrXG4gICAgICAgIHJlcGxhY2VtZW50XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMubGluZWJyZWFrUmVwbGFjZW1lbnQpIG5vZGUgZGVmaW5lZFxuICAgICAgICBpbiB0aGlzIHNjaGVtYSwgaWYgYW55LlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLmxpbmVicmVha1JlcGxhY2VtZW50ID0gbnVsbDtcbiAgICAgICAgLyoqXG4gICAgICAgIEFuIG9iamVjdCBmb3Igc3RvcmluZyB3aGF0ZXZlciB2YWx1ZXMgbW9kdWxlcyBtYXkgd2FudCB0b1xuICAgICAgICBjb21wdXRlIGFuZCBjYWNoZSBwZXIgc2NoZW1hLiAoSWYgeW91IHdhbnQgdG8gc3RvcmUgc29tZXRoaW5nXG4gICAgICAgIGluIGl0LCB0cnkgdG8gdXNlIHByb3BlcnR5IG5hbWVzIHVubGlrZWx5IHRvIGNsYXNoLilcbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jYWNoZWQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBsZXQgaW5zdGFuY2VTcGVjID0gdGhpcy5zcGVjID0ge307XG4gICAgICAgIGZvciAobGV0IHByb3AgaW4gc3BlYylcbiAgICAgICAgICAgIGluc3RhbmNlU3BlY1twcm9wXSA9IHNwZWNbcHJvcF07XG4gICAgICAgIGluc3RhbmNlU3BlYy5ub2RlcyA9IE9yZGVyZWRNYXAuZnJvbShzcGVjLm5vZGVzKSxcbiAgICAgICAgICAgIGluc3RhbmNlU3BlYy5tYXJrcyA9IE9yZGVyZWRNYXAuZnJvbShzcGVjLm1hcmtzIHx8IHt9KSxcbiAgICAgICAgICAgIHRoaXMubm9kZXMgPSBOb2RlVHlwZS5jb21waWxlKHRoaXMuc3BlYy5ub2RlcywgdGhpcyk7XG4gICAgICAgIHRoaXMubWFya3MgPSBNYXJrVHlwZS5jb21waWxlKHRoaXMuc3BlYy5tYXJrcywgdGhpcyk7XG4gICAgICAgIGxldCBjb250ZW50RXhwckNhY2hlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgZm9yIChsZXQgcHJvcCBpbiB0aGlzLm5vZGVzKSB7XG4gICAgICAgICAgICBpZiAocHJvcCBpbiB0aGlzLm1hcmtzKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKHByb3AgKyBcIiBjYW4gbm90IGJlIGJvdGggYSBub2RlIGFuZCBhIG1hcmtcIik7XG4gICAgICAgICAgICBsZXQgdHlwZSA9IHRoaXMubm9kZXNbcHJvcF0sIGNvbnRlbnRFeHByID0gdHlwZS5zcGVjLmNvbnRlbnQgfHwgXCJcIiwgbWFya0V4cHIgPSB0eXBlLnNwZWMubWFya3M7XG4gICAgICAgICAgICB0eXBlLmNvbnRlbnRNYXRjaCA9IGNvbnRlbnRFeHByQ2FjaGVbY29udGVudEV4cHJdIHx8XG4gICAgICAgICAgICAgICAgKGNvbnRlbnRFeHByQ2FjaGVbY29udGVudEV4cHJdID0gQ29udGVudE1hdGNoLnBhcnNlKGNvbnRlbnRFeHByLCB0aGlzLm5vZGVzKSk7XG4gICAgICAgICAgICB0eXBlLmlubGluZUNvbnRlbnQgPSB0eXBlLmNvbnRlbnRNYXRjaC5pbmxpbmVDb250ZW50O1xuICAgICAgICAgICAgaWYgKHR5cGUuc3BlYy5saW5lYnJlYWtSZXBsYWNlbWVudCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpbmVicmVha1JlcGxhY2VtZW50KVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIk11bHRpcGxlIGxpbmVicmVhayBub2RlcyBkZWZpbmVkXCIpO1xuICAgICAgICAgICAgICAgIGlmICghdHlwZS5pc0lubGluZSB8fCAhdHlwZS5pc0xlYWYpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTGluZWJyZWFrIHJlcGxhY2VtZW50IG5vZGVzIG11c3QgYmUgaW5saW5lIGxlYWYgbm9kZXNcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5saW5lYnJlYWtSZXBsYWNlbWVudCA9IHR5cGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0eXBlLm1hcmtTZXQgPSBtYXJrRXhwciA9PSBcIl9cIiA/IG51bGwgOlxuICAgICAgICAgICAgICAgIG1hcmtFeHByID8gZ2F0aGVyTWFya3ModGhpcywgbWFya0V4cHIuc3BsaXQoXCIgXCIpKSA6XG4gICAgICAgICAgICAgICAgICAgIG1hcmtFeHByID09IFwiXCIgfHwgIXR5cGUuaW5saW5lQ29udGVudCA/IFtdIDogbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBwcm9wIGluIHRoaXMubWFya3MpIHtcbiAgICAgICAgICAgIGxldCB0eXBlID0gdGhpcy5tYXJrc1twcm9wXSwgZXhjbCA9IHR5cGUuc3BlYy5leGNsdWRlcztcbiAgICAgICAgICAgIHR5cGUuZXhjbHVkZWQgPSBleGNsID09IG51bGwgPyBbdHlwZV0gOiBleGNsID09IFwiXCIgPyBbXSA6IGdhdGhlck1hcmtzKHRoaXMsIGV4Y2wuc3BsaXQoXCIgXCIpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm5vZGVGcm9tSlNPTiA9IGpzb24gPT4gTm9kZS5mcm9tSlNPTih0aGlzLCBqc29uKTtcbiAgICAgICAgdGhpcy5tYXJrRnJvbUpTT04gPSBqc29uID0+IE1hcmsuZnJvbUpTT04odGhpcywganNvbik7XG4gICAgICAgIHRoaXMudG9wTm9kZVR5cGUgPSB0aGlzLm5vZGVzW3RoaXMuc3BlYy50b3BOb2RlIHx8IFwiZG9jXCJdO1xuICAgICAgICB0aGlzLmNhY2hlZC53cmFwcGluZ3MgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBub2RlIGluIHRoaXMgc2NoZW1hLiBUaGUgYHR5cGVgIG1heSBiZSBhIHN0cmluZyBvciBhXG4gICAgYE5vZGVUeXBlYCBpbnN0YW5jZS4gQXR0cmlidXRlcyB3aWxsIGJlIGV4dGVuZGVkIHdpdGggZGVmYXVsdHMsXG4gICAgYGNvbnRlbnRgIG1heSBiZSBhIGBGcmFnbWVudGAsIGBudWxsYCwgYSBgTm9kZWAsIG9yIGFuIGFycmF5IG9mXG4gICAgbm9kZXMuXG4gICAgKi9cbiAgICBub2RlKHR5cGUsIGF0dHJzID0gbnVsbCwgY29udGVudCwgbWFya3MpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0eXBlID09IFwic3RyaW5nXCIpXG4gICAgICAgICAgICB0eXBlID0gdGhpcy5ub2RlVHlwZSh0eXBlKTtcbiAgICAgICAgZWxzZSBpZiAoISh0eXBlIGluc3RhbmNlb2YgTm9kZVR5cGUpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIG5vZGUgdHlwZTogXCIgKyB0eXBlKTtcbiAgICAgICAgZWxzZSBpZiAodHlwZS5zY2hlbWEgIT0gdGhpcylcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTm9kZSB0eXBlIGZyb20gZGlmZmVyZW50IHNjaGVtYSB1c2VkIChcIiArIHR5cGUubmFtZSArIFwiKVwiKTtcbiAgICAgICAgcmV0dXJuIHR5cGUuY3JlYXRlQ2hlY2tlZChhdHRycywgY29udGVudCwgbWFya3MpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSB0ZXh0IG5vZGUgaW4gdGhlIHNjaGVtYS4gRW1wdHkgdGV4dCBub2RlcyBhcmUgbm90XG4gICAgYWxsb3dlZC5cbiAgICAqL1xuICAgIHRleHQodGV4dCwgbWFya3MpIHtcbiAgICAgICAgbGV0IHR5cGUgPSB0aGlzLm5vZGVzLnRleHQ7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dE5vZGUodHlwZSwgdHlwZS5kZWZhdWx0QXR0cnMsIHRleHQsIE1hcmsuc2V0RnJvbShtYXJrcykpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBtYXJrIHdpdGggdGhlIGdpdmVuIHR5cGUgYW5kIGF0dHJpYnV0ZXMuXG4gICAgKi9cbiAgICBtYXJrKHR5cGUsIGF0dHJzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdHlwZSA9PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgdHlwZSA9IHRoaXMubWFya3NbdHlwZV07XG4gICAgICAgIHJldHVybiB0eXBlLmNyZWF0ZShhdHRycyk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgbm9kZVR5cGUobmFtZSkge1xuICAgICAgICBsZXQgZm91bmQgPSB0aGlzLm5vZGVzW25hbWVdO1xuICAgICAgICBpZiAoIWZvdW5kKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJVbmtub3duIG5vZGUgdHlwZTogXCIgKyBuYW1lKTtcbiAgICAgICAgcmV0dXJuIGZvdW5kO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdhdGhlck1hcmtzKHNjaGVtYSwgbWFya3MpIHtcbiAgICBsZXQgZm91bmQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hcmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBuYW1lID0gbWFya3NbaV0sIG1hcmsgPSBzY2hlbWEubWFya3NbbmFtZV0sIG9rID0gbWFyaztcbiAgICAgICAgaWYgKG1hcmspIHtcbiAgICAgICAgICAgIGZvdW5kLnB1c2gobWFyayk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGxldCBwcm9wIGluIHNjaGVtYS5tYXJrcykge1xuICAgICAgICAgICAgICAgIGxldCBtYXJrID0gc2NoZW1hLm1hcmtzW3Byb3BdO1xuICAgICAgICAgICAgICAgIGlmIChuYW1lID09IFwiX1wiIHx8IChtYXJrLnNwZWMuZ3JvdXAgJiYgbWFyay5zcGVjLmdyb3VwLnNwbGl0KFwiIFwiKS5pbmRleE9mKG5hbWUpID4gLTEpKVxuICAgICAgICAgICAgICAgICAgICBmb3VuZC5wdXNoKG9rID0gbWFyayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFvaylcbiAgICAgICAgICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIlVua25vd24gbWFyayB0eXBlOiAnXCIgKyBtYXJrc1tpXSArIFwiJ1wiKTtcbiAgICB9XG4gICAgcmV0dXJuIGZvdW5kO1xufVxuXG5mdW5jdGlvbiBpc1RhZ1J1bGUocnVsZSkgeyByZXR1cm4gcnVsZS50YWcgIT0gbnVsbDsgfVxuZnVuY3Rpb24gaXNTdHlsZVJ1bGUocnVsZSkgeyByZXR1cm4gcnVsZS5zdHlsZSAhPSBudWxsOyB9XG4vKipcbkEgRE9NIHBhcnNlciByZXByZXNlbnRzIGEgc3RyYXRlZ3kgZm9yIHBhcnNpbmcgRE9NIGNvbnRlbnQgaW50byBhXG5Qcm9zZU1pcnJvciBkb2N1bWVudCBjb25mb3JtaW5nIHRvIGEgZ2l2ZW4gc2NoZW1hLiBJdHMgYmVoYXZpb3IgaXNcbmRlZmluZWQgYnkgYW4gYXJyYXkgb2YgW3J1bGVzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuUGFyc2VSdWxlKS5cbiovXG5jbGFzcyBET01QYXJzZXIge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIHBhcnNlciB0aGF0IHRhcmdldHMgdGhlIGdpdmVuIHNjaGVtYSwgdXNpbmcgdGhlIGdpdmVuXG4gICAgcGFyc2luZyBydWxlcy5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBzY2hlbWEgaW50byB3aGljaCB0aGUgcGFyc2VyIHBhcnNlcy5cbiAgICAqL1xuICAgIHNjaGVtYSwgXG4gICAgLyoqXG4gICAgVGhlIHNldCBvZiBbcGFyc2UgcnVsZXNdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5QYXJzZVJ1bGUpIHRoYXQgdGhlIHBhcnNlclxuICAgIHVzZXMsIGluIG9yZGVyIG9mIHByZWNlZGVuY2UuXG4gICAgKi9cbiAgICBydWxlcykge1xuICAgICAgICB0aGlzLnNjaGVtYSA9IHNjaGVtYTtcbiAgICAgICAgdGhpcy5ydWxlcyA9IHJ1bGVzO1xuICAgICAgICAvKipcbiAgICAgICAgQGludGVybmFsXG4gICAgICAgICovXG4gICAgICAgIHRoaXMudGFncyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgQGludGVybmFsXG4gICAgICAgICovXG4gICAgICAgIHRoaXMuc3R5bGVzID0gW107XG4gICAgICAgIGxldCBtYXRjaGVkU3R5bGVzID0gdGhpcy5tYXRjaGVkU3R5bGVzID0gW107XG4gICAgICAgIHJ1bGVzLmZvckVhY2gocnVsZSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNUYWdSdWxlKHJ1bGUpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50YWdzLnB1c2gocnVsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc1N0eWxlUnVsZShydWxlKSkge1xuICAgICAgICAgICAgICAgIGxldCBwcm9wID0gL1tePV0qLy5leGVjKHJ1bGUuc3R5bGUpWzBdO1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaGVkU3R5bGVzLmluZGV4T2YocHJvcCkgPCAwKVxuICAgICAgICAgICAgICAgICAgICBtYXRjaGVkU3R5bGVzLnB1c2gocHJvcCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zdHlsZXMucHVzaChydWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIC8vIE9ubHkgbm9ybWFsaXplIGxpc3QgZWxlbWVudHMgd2hlbiBsaXN0cyBpbiB0aGUgc2NoZW1hIGNhbid0IGRpcmVjdGx5IGNvbnRhaW4gdGhlbXNlbHZlc1xuICAgICAgICB0aGlzLm5vcm1hbGl6ZUxpc3RzID0gIXRoaXMudGFncy5zb21lKHIgPT4ge1xuICAgICAgICAgICAgaWYgKCEvXih1bHxvbClcXGIvLnRlc3Qoci50YWcpIHx8ICFyLm5vZGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgbGV0IG5vZGUgPSBzY2hlbWEubm9kZXNbci5ub2RlXTtcbiAgICAgICAgICAgIHJldHVybiBub2RlLmNvbnRlbnRNYXRjaC5tYXRjaFR5cGUobm9kZSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICAvKipcbiAgICBQYXJzZSBhIGRvY3VtZW50IGZyb20gdGhlIGNvbnRlbnQgb2YgYSBET00gbm9kZS5cbiAgICAqL1xuICAgIHBhcnNlKGRvbSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGxldCBjb250ZXh0ID0gbmV3IFBhcnNlQ29udGV4dCh0aGlzLCBvcHRpb25zLCBmYWxzZSk7XG4gICAgICAgIGNvbnRleHQuYWRkQWxsKGRvbSwgTWFyay5ub25lLCBvcHRpb25zLmZyb20sIG9wdGlvbnMudG8pO1xuICAgICAgICByZXR1cm4gY29udGV4dC5maW5pc2goKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUGFyc2VzIHRoZSBjb250ZW50IG9mIHRoZSBnaXZlbiBET00gbm9kZSwgbGlrZVxuICAgIFtgcGFyc2VgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuRE9NUGFyc2VyLnBhcnNlKSwgYW5kIHRha2VzIHRoZSBzYW1lIHNldCBvZlxuICAgIG9wdGlvbnMuIEJ1dCB1bmxpa2UgdGhhdCBtZXRob2QsIHdoaWNoIHByb2R1Y2VzIGEgd2hvbGUgbm9kZSxcbiAgICB0aGlzIG9uZSByZXR1cm5zIGEgc2xpY2UgdGhhdCBpcyBvcGVuIGF0IHRoZSBzaWRlcywgbWVhbmluZyB0aGF0XG4gICAgdGhlIHNjaGVtYSBjb25zdHJhaW50cyBhcmVuJ3QgYXBwbGllZCB0byB0aGUgc3RhcnQgb2Ygbm9kZXMgdG9cbiAgICB0aGUgbGVmdCBvZiB0aGUgaW5wdXQgYW5kIHRoZSBlbmQgb2Ygbm9kZXMgYXQgdGhlIGVuZC5cbiAgICAqL1xuICAgIHBhcnNlU2xpY2UoZG9tLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgbGV0IGNvbnRleHQgPSBuZXcgUGFyc2VDb250ZXh0KHRoaXMsIG9wdGlvbnMsIHRydWUpO1xuICAgICAgICBjb250ZXh0LmFkZEFsbChkb20sIE1hcmsubm9uZSwgb3B0aW9ucy5mcm9tLCBvcHRpb25zLnRvKTtcbiAgICAgICAgcmV0dXJuIFNsaWNlLm1heE9wZW4oY29udGV4dC5maW5pc2goKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgbWF0Y2hUYWcoZG9tLCBjb250ZXh0LCBhZnRlcikge1xuICAgICAgICBmb3IgKGxldCBpID0gYWZ0ZXIgPyB0aGlzLnRhZ3MuaW5kZXhPZihhZnRlcikgKyAxIDogMDsgaSA8IHRoaXMudGFncy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHJ1bGUgPSB0aGlzLnRhZ3NbaV07XG4gICAgICAgICAgICBpZiAobWF0Y2hlcyhkb20sIHJ1bGUudGFnKSAmJlxuICAgICAgICAgICAgICAgIChydWxlLm5hbWVzcGFjZSA9PT0gdW5kZWZpbmVkIHx8IGRvbS5uYW1lc3BhY2VVUkkgPT0gcnVsZS5uYW1lc3BhY2UpICYmXG4gICAgICAgICAgICAgICAgKCFydWxlLmNvbnRleHQgfHwgY29udGV4dC5tYXRjaGVzQ29udGV4dChydWxlLmNvbnRleHQpKSkge1xuICAgICAgICAgICAgICAgIGlmIChydWxlLmdldEF0dHJzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZXN1bHQgPSBydWxlLmdldEF0dHJzKGRvbSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIHJ1bGUuYXR0cnMgPSByZXN1bHQgfHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcnVsZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIG1hdGNoU3R5bGUocHJvcCwgdmFsdWUsIGNvbnRleHQsIGFmdGVyKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSBhZnRlciA/IHRoaXMuc3R5bGVzLmluZGV4T2YoYWZ0ZXIpICsgMSA6IDA7IGkgPCB0aGlzLnN0eWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHJ1bGUgPSB0aGlzLnN0eWxlc1tpXSwgc3R5bGUgPSBydWxlLnN0eWxlO1xuICAgICAgICAgICAgaWYgKHN0eWxlLmluZGV4T2YocHJvcCkgIT0gMCB8fFxuICAgICAgICAgICAgICAgIHJ1bGUuY29udGV4dCAmJiAhY29udGV4dC5tYXRjaGVzQ29udGV4dChydWxlLmNvbnRleHQpIHx8XG4gICAgICAgICAgICAgICAgLy8gVGVzdCB0aGF0IHRoZSBzdHlsZSBzdHJpbmcgZWl0aGVyIHByZWNpc2VseSBtYXRjaGVzIHRoZSBwcm9wLFxuICAgICAgICAgICAgICAgIC8vIG9yIGhhcyBhbiAnPScgc2lnbiBhZnRlciB0aGUgcHJvcCwgZm9sbG93ZWQgYnkgdGhlIGdpdmVuXG4gICAgICAgICAgICAgICAgLy8gdmFsdWUuXG4gICAgICAgICAgICAgICAgc3R5bGUubGVuZ3RoID4gcHJvcC5sZW5ndGggJiZcbiAgICAgICAgICAgICAgICAgICAgKHN0eWxlLmNoYXJDb2RlQXQocHJvcC5sZW5ndGgpICE9IDYxIHx8IHN0eWxlLnNsaWNlKHByb3AubGVuZ3RoICsgMSkgIT0gdmFsdWUpKVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHJ1bGUuZ2V0QXR0cnMpIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gcnVsZS5nZXRBdHRycyh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIHJ1bGUuYXR0cnMgPSByZXN1bHQgfHwgdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJ1bGU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgc2NoZW1hUnVsZXMoc2NoZW1hKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICAgICAgZnVuY3Rpb24gaW5zZXJ0KHJ1bGUpIHtcbiAgICAgICAgICAgIGxldCBwcmlvcml0eSA9IHJ1bGUucHJpb3JpdHkgPT0gbnVsbCA/IDUwIDogcnVsZS5wcmlvcml0eSwgaSA9IDA7XG4gICAgICAgICAgICBmb3IgKDsgaSA8IHJlc3VsdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gcmVzdWx0W2ldLCBuZXh0UHJpb3JpdHkgPSBuZXh0LnByaW9yaXR5ID09IG51bGwgPyA1MCA6IG5leHQucHJpb3JpdHk7XG4gICAgICAgICAgICAgICAgaWYgKG5leHRQcmlvcml0eSA8IHByaW9yaXR5KVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdC5zcGxpY2UoaSwgMCwgcnVsZSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBzY2hlbWEubWFya3MpIHtcbiAgICAgICAgICAgIGxldCBydWxlcyA9IHNjaGVtYS5tYXJrc1tuYW1lXS5zcGVjLnBhcnNlRE9NO1xuICAgICAgICAgICAgaWYgKHJ1bGVzKVxuICAgICAgICAgICAgICAgIHJ1bGVzLmZvckVhY2gocnVsZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGluc2VydChydWxlID0gY29weShydWxlKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghKHJ1bGUubWFyayB8fCBydWxlLmlnbm9yZSB8fCBydWxlLmNsZWFyTWFyaykpXG4gICAgICAgICAgICAgICAgICAgICAgICBydWxlLm1hcmsgPSBuYW1lO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IG5hbWUgaW4gc2NoZW1hLm5vZGVzKSB7XG4gICAgICAgICAgICBsZXQgcnVsZXMgPSBzY2hlbWEubm9kZXNbbmFtZV0uc3BlYy5wYXJzZURPTTtcbiAgICAgICAgICAgIGlmIChydWxlcylcbiAgICAgICAgICAgICAgICBydWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpbnNlcnQocnVsZSA9IGNvcHkocnVsZSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShydWxlLm5vZGUgfHwgcnVsZS5pZ25vcmUgfHwgcnVsZS5tYXJrKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bGUubm9kZSA9IG5hbWU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgLyoqXG4gICAgQ29uc3RydWN0IGEgRE9NIHBhcnNlciB1c2luZyB0aGUgcGFyc2luZyBydWxlcyBsaXN0ZWQgaW4gYVxuICAgIHNjaGVtYSdzIFtub2RlIHNwZWNzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMucGFyc2VET00pLCByZW9yZGVyZWQgYnlcbiAgICBbcHJpb3JpdHldKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5HZW5lcmljUGFyc2VSdWxlLnByaW9yaXR5KS5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tU2NoZW1hKHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gc2NoZW1hLmNhY2hlZC5kb21QYXJzZXIgfHxcbiAgICAgICAgICAgIChzY2hlbWEuY2FjaGVkLmRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoc2NoZW1hLCBET01QYXJzZXIuc2NoZW1hUnVsZXMoc2NoZW1hKSkpO1xuICAgIH1cbn1cbmNvbnN0IGJsb2NrVGFncyA9IHtcbiAgICBhZGRyZXNzOiB0cnVlLCBhcnRpY2xlOiB0cnVlLCBhc2lkZTogdHJ1ZSwgYmxvY2txdW90ZTogdHJ1ZSwgY2FudmFzOiB0cnVlLFxuICAgIGRkOiB0cnVlLCBkaXY6IHRydWUsIGRsOiB0cnVlLCBmaWVsZHNldDogdHJ1ZSwgZmlnY2FwdGlvbjogdHJ1ZSwgZmlndXJlOiB0cnVlLFxuICAgIGZvb3RlcjogdHJ1ZSwgZm9ybTogdHJ1ZSwgaDE6IHRydWUsIGgyOiB0cnVlLCBoMzogdHJ1ZSwgaDQ6IHRydWUsIGg1OiB0cnVlLFxuICAgIGg2OiB0cnVlLCBoZWFkZXI6IHRydWUsIGhncm91cDogdHJ1ZSwgaHI6IHRydWUsIGxpOiB0cnVlLCBub3NjcmlwdDogdHJ1ZSwgb2w6IHRydWUsXG4gICAgb3V0cHV0OiB0cnVlLCBwOiB0cnVlLCBwcmU6IHRydWUsIHNlY3Rpb246IHRydWUsIHRhYmxlOiB0cnVlLCB0Zm9vdDogdHJ1ZSwgdWw6IHRydWVcbn07XG5jb25zdCBpZ25vcmVUYWdzID0ge1xuICAgIGhlYWQ6IHRydWUsIG5vc2NyaXB0OiB0cnVlLCBvYmplY3Q6IHRydWUsIHNjcmlwdDogdHJ1ZSwgc3R5bGU6IHRydWUsIHRpdGxlOiB0cnVlXG59O1xuY29uc3QgbGlzdFRhZ3MgPSB7IG9sOiB0cnVlLCB1bDogdHJ1ZSB9O1xuLy8gVXNpbmcgYSBiaXRmaWVsZCBmb3Igbm9kZSBjb250ZXh0IG9wdGlvbnNcbmNvbnN0IE9QVF9QUkVTRVJWRV9XUyA9IDEsIE9QVF9QUkVTRVJWRV9XU19GVUxMID0gMiwgT1BUX09QRU5fTEVGVCA9IDQ7XG5mdW5jdGlvbiB3c09wdGlvbnNGb3IodHlwZSwgcHJlc2VydmVXaGl0ZXNwYWNlLCBiYXNlKSB7XG4gICAgaWYgKHByZXNlcnZlV2hpdGVzcGFjZSAhPSBudWxsKVxuICAgICAgICByZXR1cm4gKHByZXNlcnZlV2hpdGVzcGFjZSA/IE9QVF9QUkVTRVJWRV9XUyA6IDApIHxcbiAgICAgICAgICAgIChwcmVzZXJ2ZVdoaXRlc3BhY2UgPT09IFwiZnVsbFwiID8gT1BUX1BSRVNFUlZFX1dTX0ZVTEwgOiAwKTtcbiAgICByZXR1cm4gdHlwZSAmJiB0eXBlLndoaXRlc3BhY2UgPT0gXCJwcmVcIiA/IE9QVF9QUkVTRVJWRV9XUyB8IE9QVF9QUkVTRVJWRV9XU19GVUxMIDogYmFzZSAmIH5PUFRfT1BFTl9MRUZUO1xufVxuY2xhc3MgTm9kZUNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKHR5cGUsIGF0dHJzLCBtYXJrcywgc29saWQsIG1hdGNoLCBvcHRpb25zKSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuYXR0cnMgPSBhdHRycztcbiAgICAgICAgdGhpcy5tYXJrcyA9IG1hcmtzO1xuICAgICAgICB0aGlzLnNvbGlkID0gc29saWQ7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIHRoaXMuY29udGVudCA9IFtdO1xuICAgICAgICAvLyBNYXJrcyBhcHBsaWVkIHRvIHRoZSBub2RlJ3MgY2hpbGRyZW5cbiAgICAgICAgdGhpcy5hY3RpdmVNYXJrcyA9IE1hcmsubm9uZTtcbiAgICAgICAgdGhpcy5tYXRjaCA9IG1hdGNoIHx8IChvcHRpb25zICYgT1BUX09QRU5fTEVGVCA/IG51bGwgOiB0eXBlLmNvbnRlbnRNYXRjaCk7XG4gICAgfVxuICAgIGZpbmRXcmFwcGluZyhub2RlKSB7XG4gICAgICAgIGlmICghdGhpcy5tYXRjaCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnR5cGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgbGV0IGZpbGwgPSB0aGlzLnR5cGUuY29udGVudE1hdGNoLmZpbGxCZWZvcmUoRnJhZ21lbnQuZnJvbShub2RlKSk7XG4gICAgICAgICAgICBpZiAoZmlsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMubWF0Y2ggPSB0aGlzLnR5cGUuY29udGVudE1hdGNoLm1hdGNoRnJhZ21lbnQoZmlsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLnR5cGUuY29udGVudE1hdGNoLCB3cmFwO1xuICAgICAgICAgICAgICAgIGlmICh3cmFwID0gc3RhcnQuZmluZFdyYXBwaW5nKG5vZGUudHlwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXRjaCA9IHN0YXJ0O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gd3JhcDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaC5maW5kV3JhcHBpbmcobm9kZS50eXBlKTtcbiAgICB9XG4gICAgZmluaXNoKG9wZW5FbmQpIHtcbiAgICAgICAgaWYgKCEodGhpcy5vcHRpb25zICYgT1BUX1BSRVNFUlZFX1dTKSkgeyAvLyBTdHJpcCB0cmFpbGluZyB3aGl0ZXNwYWNlXG4gICAgICAgICAgICBsZXQgbGFzdCA9IHRoaXMuY29udGVudFt0aGlzLmNvbnRlbnQubGVuZ3RoIC0gMV0sIG07XG4gICAgICAgICAgICBpZiAobGFzdCAmJiBsYXN0LmlzVGV4dCAmJiAobSA9IC9bIFxcdFxcclxcblxcdTAwMGNdKyQvLmV4ZWMobGFzdC50ZXh0KSkpIHtcbiAgICAgICAgICAgICAgICBsZXQgdGV4dCA9IGxhc3Q7XG4gICAgICAgICAgICAgICAgaWYgKGxhc3QudGV4dC5sZW5ndGggPT0gbVswXS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudC5wb3AoKTtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudFt0aGlzLmNvbnRlbnQubGVuZ3RoIC0gMV0gPSB0ZXh0LndpdGhUZXh0KHRleHQudGV4dC5zbGljZSgwLCB0ZXh0LnRleHQubGVuZ3RoIC0gbVswXS5sZW5ndGgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgY29udGVudCA9IEZyYWdtZW50LmZyb20odGhpcy5jb250ZW50KTtcbiAgICAgICAgaWYgKCFvcGVuRW5kICYmIHRoaXMubWF0Y2gpXG4gICAgICAgICAgICBjb250ZW50ID0gY29udGVudC5hcHBlbmQodGhpcy5tYXRjaC5maWxsQmVmb3JlKEZyYWdtZW50LmVtcHR5LCB0cnVlKSk7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPyB0aGlzLnR5cGUuY3JlYXRlKHRoaXMuYXR0cnMsIGNvbnRlbnQsIHRoaXMubWFya3MpIDogY29udGVudDtcbiAgICB9XG4gICAgaW5saW5lQ29udGV4dChub2RlKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50eXBlLmlubGluZUNvbnRlbnQ7XG4gICAgICAgIGlmICh0aGlzLmNvbnRlbnQubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudFswXS5pc0lubGluZTtcbiAgICAgICAgcmV0dXJuIG5vZGUucGFyZW50Tm9kZSAmJiAhYmxvY2tUYWdzLmhhc093blByb3BlcnR5KG5vZGUucGFyZW50Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgICB9XG59XG5jbGFzcyBQYXJzZUNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8vIFRoZSBwYXJzZXIgd2UgYXJlIHVzaW5nLlxuICAgIHBhcnNlciwgXG4gICAgLy8gVGhlIG9wdGlvbnMgcGFzc2VkIHRvIHRoaXMgcGFyc2UuXG4gICAgb3B0aW9ucywgaXNPcGVuKSB7XG4gICAgICAgIHRoaXMucGFyc2VyID0gcGFyc2VyO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICB0aGlzLmlzT3BlbiA9IGlzT3BlbjtcbiAgICAgICAgdGhpcy5vcGVuID0gMDtcbiAgICAgICAgdGhpcy5sb2NhbFByZXNlcnZlV1MgPSBmYWxzZTtcbiAgICAgICAgbGV0IHRvcE5vZGUgPSBvcHRpb25zLnRvcE5vZGUsIHRvcENvbnRleHQ7XG4gICAgICAgIGxldCB0b3BPcHRpb25zID0gd3NPcHRpb25zRm9yKG51bGwsIG9wdGlvbnMucHJlc2VydmVXaGl0ZXNwYWNlLCAwKSB8IChpc09wZW4gPyBPUFRfT1BFTl9MRUZUIDogMCk7XG4gICAgICAgIGlmICh0b3BOb2RlKVxuICAgICAgICAgICAgdG9wQ29udGV4dCA9IG5ldyBOb2RlQ29udGV4dCh0b3BOb2RlLnR5cGUsIHRvcE5vZGUuYXR0cnMsIE1hcmsubm9uZSwgdHJ1ZSwgb3B0aW9ucy50b3BNYXRjaCB8fCB0b3BOb2RlLnR5cGUuY29udGVudE1hdGNoLCB0b3BPcHRpb25zKTtcbiAgICAgICAgZWxzZSBpZiAoaXNPcGVuKVxuICAgICAgICAgICAgdG9wQ29udGV4dCA9IG5ldyBOb2RlQ29udGV4dChudWxsLCBudWxsLCBNYXJrLm5vbmUsIHRydWUsIG51bGwsIHRvcE9wdGlvbnMpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0b3BDb250ZXh0ID0gbmV3IE5vZGVDb250ZXh0KHBhcnNlci5zY2hlbWEudG9wTm9kZVR5cGUsIG51bGwsIE1hcmsubm9uZSwgdHJ1ZSwgbnVsbCwgdG9wT3B0aW9ucyk7XG4gICAgICAgIHRoaXMubm9kZXMgPSBbdG9wQ29udGV4dF07XG4gICAgICAgIHRoaXMuZmluZCA9IG9wdGlvbnMuZmluZFBvc2l0aW9ucztcbiAgICAgICAgdGhpcy5uZWVkc0Jsb2NrID0gZmFsc2U7XG4gICAgfVxuICAgIGdldCB0b3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5vZGVzW3RoaXMub3Blbl07XG4gICAgfVxuICAgIC8vIEFkZCBhIERPTSBub2RlIHRvIHRoZSBjb250ZW50LiBUZXh0IGlzIGluc2VydGVkIGFzIHRleHQgbm9kZSxcbiAgICAvLyBvdGhlcndpc2UsIHRoZSBub2RlIGlzIHBhc3NlZCB0byBgYWRkRWxlbWVudGAgb3IsIGlmIGl0IGhhcyBhXG4gICAgLy8gYHN0eWxlYCBhdHRyaWJ1dGUsIGBhZGRFbGVtZW50V2l0aFN0eWxlc2AuXG4gICAgYWRkRE9NKGRvbSwgbWFya3MpIHtcbiAgICAgICAgaWYgKGRvbS5ub2RlVHlwZSA9PSAzKVxuICAgICAgICAgICAgdGhpcy5hZGRUZXh0Tm9kZShkb20sIG1hcmtzKTtcbiAgICAgICAgZWxzZSBpZiAoZG9tLm5vZGVUeXBlID09IDEpXG4gICAgICAgICAgICB0aGlzLmFkZEVsZW1lbnQoZG9tLCBtYXJrcyk7XG4gICAgfVxuICAgIGFkZFRleHROb2RlKGRvbSwgbWFya3MpIHtcbiAgICAgICAgbGV0IHZhbHVlID0gZG9tLm5vZGVWYWx1ZTtcbiAgICAgICAgbGV0IHRvcCA9IHRoaXMudG9wLCBwcmVzZXJ2ZVdTID0gKHRvcC5vcHRpb25zICYgT1BUX1BSRVNFUlZFX1dTX0ZVTEwpID8gXCJmdWxsXCJcbiAgICAgICAgICAgIDogdGhpcy5sb2NhbFByZXNlcnZlV1MgfHwgKHRvcC5vcHRpb25zICYgT1BUX1BSRVNFUlZFX1dTKSA+IDA7XG4gICAgICAgIGxldCB7IHNjaGVtYSB9ID0gdGhpcy5wYXJzZXI7XG4gICAgICAgIGlmIChwcmVzZXJ2ZVdTID09PSBcImZ1bGxcIiB8fFxuICAgICAgICAgICAgdG9wLmlubGluZUNvbnRleHQoZG9tKSB8fFxuICAgICAgICAgICAgL1teIFxcdFxcclxcblxcdTAwMGNdLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgaWYgKCFwcmVzZXJ2ZVdTKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9bIFxcdFxcclxcblxcdTAwMGNdKy9nLCBcIiBcIik7XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBzdGFydHMgd2l0aCB3aGl0ZXNwYWNlLCBhbmQgdGhlcmUgaXMgbm8gbm9kZSBiZWZvcmUgaXQsIG9yXG4gICAgICAgICAgICAgICAgLy8gYSBoYXJkIGJyZWFrLCBvciBhIHRleHQgbm9kZSB0aGF0IGVuZHMgd2l0aCB3aGl0ZXNwYWNlLCBzdHJpcCB0aGVcbiAgICAgICAgICAgICAgICAvLyBsZWFkaW5nIHNwYWNlLlxuICAgICAgICAgICAgICAgIGlmICgvXlsgXFx0XFxyXFxuXFx1MDAwY10vLnRlc3QodmFsdWUpICYmIHRoaXMub3BlbiA9PSB0aGlzLm5vZGVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG5vZGVCZWZvcmUgPSB0b3AuY29udGVudFt0b3AuY29udGVudC5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGRvbU5vZGVCZWZvcmUgPSBkb20ucHJldmlvdXNTaWJsaW5nO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vZGVCZWZvcmUgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIChkb21Ob2RlQmVmb3JlICYmIGRvbU5vZGVCZWZvcmUubm9kZU5hbWUgPT0gJ0JSJykgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIChub2RlQmVmb3JlLmlzVGV4dCAmJiAvWyBcXHRcXHJcXG5cXHUwMDBjXSQvLnRlc3Qobm9kZUJlZm9yZS50ZXh0KSkpXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnNsaWNlKDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHByZXNlcnZlV1MgPT09IFwiZnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXHJcXG4/L2csIFwiXFxuXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoc2NoZW1hLmxpbmVicmVha1JlcGxhY2VtZW50ICYmIC9bXFxyXFxuXS8udGVzdCh2YWx1ZSkgJiYgdGhpcy50b3AuZmluZFdyYXBwaW5nKHNjaGVtYS5saW5lYnJlYWtSZXBsYWNlbWVudC5jcmVhdGUoKSkpIHtcbiAgICAgICAgICAgICAgICBsZXQgbGluZXMgPSB2YWx1ZS5zcGxpdCgvXFxyP1xcbnxcXHIvKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnNlcnROb2RlKHNjaGVtYS5saW5lYnJlYWtSZXBsYWNlbWVudC5jcmVhdGUoKSwgbWFya3MsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobGluZXNbaV0pXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluc2VydE5vZGUoc2NoZW1hLnRleHQobGluZXNbaV0pLCBtYXJrcywgIS9cXFMvLnRlc3QobGluZXNbaV0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXHI/XFxufFxcci9nLCBcIiBcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUpXG4gICAgICAgICAgICAgICAgdGhpcy5pbnNlcnROb2RlKHNjaGVtYS50ZXh0KHZhbHVlKSwgbWFya3MsICEvXFxTLy50ZXN0KHZhbHVlKSk7XG4gICAgICAgICAgICB0aGlzLmZpbmRJblRleHQoZG9tKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZmluZEluc2lkZShkb20pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIFRyeSB0byBmaW5kIGEgaGFuZGxlciBmb3IgdGhlIGdpdmVuIHRhZyBhbmQgdXNlIHRoYXQgdG8gcGFyc2UuIElmXG4gICAgLy8gbm9uZSBpcyBmb3VuZCwgdGhlIGVsZW1lbnQncyBjb250ZW50IG5vZGVzIGFyZSBhZGRlZCBkaXJlY3RseS5cbiAgICBhZGRFbGVtZW50KGRvbSwgbWFya3MsIG1hdGNoQWZ0ZXIpIHtcbiAgICAgICAgbGV0IG91dGVyV1MgPSB0aGlzLmxvY2FsUHJlc2VydmVXUywgdG9wID0gdGhpcy50b3A7XG4gICAgICAgIGlmIChkb20udGFnTmFtZSA9PSBcIlBSRVwiIHx8IC9wcmUvLnRlc3QoZG9tLnN0eWxlICYmIGRvbS5zdHlsZS53aGl0ZVNwYWNlKSlcbiAgICAgICAgICAgIHRoaXMubG9jYWxQcmVzZXJ2ZVdTID0gdHJ1ZTtcbiAgICAgICAgbGV0IG5hbWUgPSBkb20ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSwgcnVsZUlEO1xuICAgICAgICBpZiAobGlzdFRhZ3MuaGFzT3duUHJvcGVydHkobmFtZSkgJiYgdGhpcy5wYXJzZXIubm9ybWFsaXplTGlzdHMpXG4gICAgICAgICAgICBub3JtYWxpemVMaXN0KGRvbSk7XG4gICAgICAgIGxldCBydWxlID0gKHRoaXMub3B0aW9ucy5ydWxlRnJvbU5vZGUgJiYgdGhpcy5vcHRpb25zLnJ1bGVGcm9tTm9kZShkb20pKSB8fFxuICAgICAgICAgICAgKHJ1bGVJRCA9IHRoaXMucGFyc2VyLm1hdGNoVGFnKGRvbSwgdGhpcywgbWF0Y2hBZnRlcikpO1xuICAgICAgICBvdXQ6IGlmIChydWxlID8gcnVsZS5pZ25vcmUgOiBpZ25vcmVUYWdzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgICB0aGlzLmZpbmRJbnNpZGUoZG9tKTtcbiAgICAgICAgICAgIHRoaXMuaWdub3JlRmFsbGJhY2soZG9tLCBtYXJrcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXJ1bGUgfHwgcnVsZS5za2lwIHx8IHJ1bGUuY2xvc2VQYXJlbnQpIHtcbiAgICAgICAgICAgIGlmIChydWxlICYmIHJ1bGUuY2xvc2VQYXJlbnQpXG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuID0gTWF0aC5tYXgoMCwgdGhpcy5vcGVuIC0gMSk7XG4gICAgICAgICAgICBlbHNlIGlmIChydWxlICYmIHJ1bGUuc2tpcC5ub2RlVHlwZSlcbiAgICAgICAgICAgICAgICBkb20gPSBydWxlLnNraXA7XG4gICAgICAgICAgICBsZXQgc3luYywgb2xkTmVlZHNCbG9jayA9IHRoaXMubmVlZHNCbG9jaztcbiAgICAgICAgICAgIGlmIChibG9ja1RhZ3MuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAodG9wLmNvbnRlbnQubGVuZ3RoICYmIHRvcC5jb250ZW50WzBdLmlzSW5saW5lICYmIHRoaXMub3Blbikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW4tLTtcbiAgICAgICAgICAgICAgICAgICAgdG9wID0gdGhpcy50b3A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN5bmMgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmICghdG9wLnR5cGUpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubmVlZHNCbG9jayA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghZG9tLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxlYWZGYWxsYmFjayhkb20sIG1hcmtzKTtcbiAgICAgICAgICAgICAgICBicmVhayBvdXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgaW5uZXJNYXJrcyA9IHJ1bGUgJiYgcnVsZS5za2lwID8gbWFya3MgOiB0aGlzLnJlYWRTdHlsZXMoZG9tLCBtYXJrcyk7XG4gICAgICAgICAgICBpZiAoaW5uZXJNYXJrcylcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEFsbChkb20sIGlubmVyTWFya3MpO1xuICAgICAgICAgICAgaWYgKHN5bmMpXG4gICAgICAgICAgICAgICAgdGhpcy5zeW5jKHRvcCk7XG4gICAgICAgICAgICB0aGlzLm5lZWRzQmxvY2sgPSBvbGROZWVkc0Jsb2NrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IGlubmVyTWFya3MgPSB0aGlzLnJlYWRTdHlsZXMoZG9tLCBtYXJrcyk7XG4gICAgICAgICAgICBpZiAoaW5uZXJNYXJrcylcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEVsZW1lbnRCeVJ1bGUoZG9tLCBydWxlLCBpbm5lck1hcmtzLCBydWxlLmNvbnN1bWluZyA9PT0gZmFsc2UgPyBydWxlSUQgOiB1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubG9jYWxQcmVzZXJ2ZVdTID0gb3V0ZXJXUztcbiAgICB9XG4gICAgLy8gQ2FsbGVkIGZvciBsZWFmIERPTSBub2RlcyB0aGF0IHdvdWxkIG90aGVyd2lzZSBiZSBpZ25vcmVkXG4gICAgbGVhZkZhbGxiYWNrKGRvbSwgbWFya3MpIHtcbiAgICAgICAgaWYgKGRvbS5ub2RlTmFtZSA9PSBcIkJSXCIgJiYgdGhpcy50b3AudHlwZSAmJiB0aGlzLnRvcC50eXBlLmlubGluZUNvbnRlbnQpXG4gICAgICAgICAgICB0aGlzLmFkZFRleHROb2RlKGRvbS5vd25lckRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFwiXFxuXCIpLCBtYXJrcyk7XG4gICAgfVxuICAgIC8vIENhbGxlZCBmb3IgaWdub3JlZCBub2Rlc1xuICAgIGlnbm9yZUZhbGxiYWNrKGRvbSwgbWFya3MpIHtcbiAgICAgICAgLy8gSWdub3JlZCBCUiBub2RlcyBzaG91bGQgYXQgbGVhc3QgY3JlYXRlIGFuIGlubGluZSBjb250ZXh0XG4gICAgICAgIGlmIChkb20ubm9kZU5hbWUgPT0gXCJCUlwiICYmICghdGhpcy50b3AudHlwZSB8fCAhdGhpcy50b3AudHlwZS5pbmxpbmVDb250ZW50KSlcbiAgICAgICAgICAgIHRoaXMuZmluZFBsYWNlKHRoaXMucGFyc2VyLnNjaGVtYS50ZXh0KFwiLVwiKSwgbWFya3MsIHRydWUpO1xuICAgIH1cbiAgICAvLyBSdW4gYW55IHN0eWxlIHBhcnNlciBhc3NvY2lhdGVkIHdpdGggdGhlIG5vZGUncyBzdHlsZXMuIEVpdGhlclxuICAgIC8vIHJldHVybiBhbiB1cGRhdGVkIGFycmF5IG9mIG1hcmtzLCBvciBudWxsIHRvIGluZGljYXRlIHNvbWUgb2YgdGhlXG4gICAgLy8gc3R5bGVzIGhhZCBhIHJ1bGUgd2l0aCBgaWdub3JlYCBzZXQuXG4gICAgcmVhZFN0eWxlcyhkb20sIG1hcmtzKSB7XG4gICAgICAgIGxldCBzdHlsZXMgPSBkb20uc3R5bGU7XG4gICAgICAgIC8vIEJlY2F1c2UgbWFueSBwcm9wZXJ0aWVzIHdpbGwgb25seSBzaG93IHVwIGluICdub3JtYWxpemVkJyBmb3JtXG4gICAgICAgIC8vIGluIGBzdHlsZS5pdGVtYCAoaS5lLiB0ZXh0LWRlY29yYXRpb24gYmVjb21lc1xuICAgICAgICAvLyB0ZXh0LWRlY29yYXRpb24tbGluZSwgdGV4dC1kZWNvcmF0aW9uLWNvbG9yLCBldGMpLCB3ZSBkaXJlY3RseVxuICAgICAgICAvLyBxdWVyeSB0aGUgc3R5bGVzIG1lbnRpb25lZCBpbiBvdXIgcnVsZXMgaW5zdGVhZCBvZiBpdGVyYXRpbmdcbiAgICAgICAgLy8gb3ZlciB0aGUgaXRlbXMuXG4gICAgICAgIGlmIChzdHlsZXMgJiYgc3R5bGVzLmxlbmd0aClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5wYXJzZXIubWF0Y2hlZFN0eWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBuYW1lID0gdGhpcy5wYXJzZXIubWF0Y2hlZFN0eWxlc1tpXSwgdmFsdWUgPSBzdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKTtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGFmdGVyID0gdW5kZWZpbmVkOzspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBydWxlID0gdGhpcy5wYXJzZXIubWF0Y2hTdHlsZShuYW1lLCB2YWx1ZSwgdGhpcywgYWZ0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFydWxlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJ1bGUuaWdub3JlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJ1bGUuY2xlYXJNYXJrKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmtzID0gbWFya3MuZmlsdGVyKG0gPT4gIXJ1bGUuY2xlYXJNYXJrKG0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJrcyA9IG1hcmtzLmNvbmNhdCh0aGlzLnBhcnNlci5zY2hlbWEubWFya3NbcnVsZS5tYXJrXS5jcmVhdGUocnVsZS5hdHRycykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJ1bGUuY29uc3VtaW5nID09PSBmYWxzZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZnRlciA9IHJ1bGU7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hcmtzO1xuICAgIH1cbiAgICAvLyBMb29rIHVwIGEgaGFuZGxlciBmb3IgdGhlIGdpdmVuIG5vZGUuIElmIG5vbmUgYXJlIGZvdW5kLCByZXR1cm5cbiAgICAvLyBmYWxzZS4gT3RoZXJ3aXNlLCBhcHBseSBpdCwgdXNlIGl0cyByZXR1cm4gdmFsdWUgdG8gZHJpdmUgdGhlIHdheVxuICAgIC8vIHRoZSBub2RlJ3MgY29udGVudCBpcyB3cmFwcGVkLCBhbmQgcmV0dXJuIHRydWUuXG4gICAgYWRkRWxlbWVudEJ5UnVsZShkb20sIHJ1bGUsIG1hcmtzLCBjb250aW51ZUFmdGVyKSB7XG4gICAgICAgIGxldCBzeW5jLCBub2RlVHlwZTtcbiAgICAgICAgaWYgKHJ1bGUubm9kZSkge1xuICAgICAgICAgICAgbm9kZVR5cGUgPSB0aGlzLnBhcnNlci5zY2hlbWEubm9kZXNbcnVsZS5ub2RlXTtcbiAgICAgICAgICAgIGlmICghbm9kZVR5cGUuaXNMZWFmKSB7XG4gICAgICAgICAgICAgICAgbGV0IGlubmVyID0gdGhpcy5lbnRlcihub2RlVHlwZSwgcnVsZS5hdHRycyB8fCBudWxsLCBtYXJrcywgcnVsZS5wcmVzZXJ2ZVdoaXRlc3BhY2UpO1xuICAgICAgICAgICAgICAgIGlmIChpbm5lcikge1xuICAgICAgICAgICAgICAgICAgICBzeW5jID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgbWFya3MgPSBpbm5lcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghdGhpcy5pbnNlcnROb2RlKG5vZGVUeXBlLmNyZWF0ZShydWxlLmF0dHJzKSwgbWFya3MsIGRvbS5ub2RlTmFtZSA9PSBcIkJSXCIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWFmRmFsbGJhY2soZG9tLCBtYXJrcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgbWFya1R5cGUgPSB0aGlzLnBhcnNlci5zY2hlbWEubWFya3NbcnVsZS5tYXJrXTtcbiAgICAgICAgICAgIG1hcmtzID0gbWFya3MuY29uY2F0KG1hcmtUeXBlLmNyZWF0ZShydWxlLmF0dHJzKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHN0YXJ0SW4gPSB0aGlzLnRvcDtcbiAgICAgICAgaWYgKG5vZGVUeXBlICYmIG5vZGVUeXBlLmlzTGVhZikge1xuICAgICAgICAgICAgdGhpcy5maW5kSW5zaWRlKGRvbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY29udGludWVBZnRlcikge1xuICAgICAgICAgICAgdGhpcy5hZGRFbGVtZW50KGRvbSwgbWFya3MsIGNvbnRpbnVlQWZ0ZXIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHJ1bGUuZ2V0Q29udGVudCkge1xuICAgICAgICAgICAgdGhpcy5maW5kSW5zaWRlKGRvbSk7XG4gICAgICAgICAgICBydWxlLmdldENvbnRlbnQoZG9tLCB0aGlzLnBhcnNlci5zY2hlbWEpLmZvckVhY2gobm9kZSA9PiB0aGlzLmluc2VydE5vZGUobm9kZSwgbWFya3MsIGZhbHNlKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgY29udGVudERPTSA9IGRvbTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcnVsZS5jb250ZW50RWxlbWVudCA9PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgIGNvbnRlbnRET00gPSBkb20ucXVlcnlTZWxlY3RvcihydWxlLmNvbnRlbnRFbGVtZW50KTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBydWxlLmNvbnRlbnRFbGVtZW50ID09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgICAgICAgICBjb250ZW50RE9NID0gcnVsZS5jb250ZW50RWxlbWVudChkb20pO1xuICAgICAgICAgICAgZWxzZSBpZiAocnVsZS5jb250ZW50RWxlbWVudClcbiAgICAgICAgICAgICAgICBjb250ZW50RE9NID0gcnVsZS5jb250ZW50RWxlbWVudDtcbiAgICAgICAgICAgIHRoaXMuZmluZEFyb3VuZChkb20sIGNvbnRlbnRET00sIHRydWUpO1xuICAgICAgICAgICAgdGhpcy5hZGRBbGwoY29udGVudERPTSwgbWFya3MpO1xuICAgICAgICAgICAgdGhpcy5maW5kQXJvdW5kKGRvbSwgY29udGVudERPTSwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzeW5jICYmIHRoaXMuc3luYyhzdGFydEluKSlcbiAgICAgICAgICAgIHRoaXMub3Blbi0tO1xuICAgIH1cbiAgICAvLyBBZGQgYWxsIGNoaWxkIG5vZGVzIGJldHdlZW4gYHN0YXJ0SW5kZXhgIGFuZCBgZW5kSW5kZXhgIChvciB0aGVcbiAgICAvLyB3aG9sZSBub2RlLCBpZiBub3QgZ2l2ZW4pLiBJZiBgc3luY2AgaXMgcGFzc2VkLCB1c2UgaXQgdG9cbiAgICAvLyBzeW5jaHJvbml6ZSBhZnRlciBldmVyeSBibG9jayBlbGVtZW50LlxuICAgIGFkZEFsbChwYXJlbnQsIG1hcmtzLCBzdGFydEluZGV4LCBlbmRJbmRleCkge1xuICAgICAgICBsZXQgaW5kZXggPSBzdGFydEluZGV4IHx8IDA7XG4gICAgICAgIGZvciAobGV0IGRvbSA9IHN0YXJ0SW5kZXggPyBwYXJlbnQuY2hpbGROb2Rlc1tzdGFydEluZGV4XSA6IHBhcmVudC5maXJzdENoaWxkLCBlbmQgPSBlbmRJbmRleCA9PSBudWxsID8gbnVsbCA6IHBhcmVudC5jaGlsZE5vZGVzW2VuZEluZGV4XTsgZG9tICE9IGVuZDsgZG9tID0gZG9tLm5leHRTaWJsaW5nLCArK2luZGV4KSB7XG4gICAgICAgICAgICB0aGlzLmZpbmRBdFBvaW50KHBhcmVudCwgaW5kZXgpO1xuICAgICAgICAgICAgdGhpcy5hZGRET00oZG9tLCBtYXJrcyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5maW5kQXRQb2ludChwYXJlbnQsIGluZGV4KTtcbiAgICB9XG4gICAgLy8gVHJ5IHRvIGZpbmQgYSB3YXkgdG8gZml0IHRoZSBnaXZlbiBub2RlIHR5cGUgaW50byB0aGUgY3VycmVudFxuICAgIC8vIGNvbnRleHQuIE1heSBhZGQgaW50ZXJtZWRpYXRlIHdyYXBwZXJzIGFuZC9vciBsZWF2ZSBub24tc29saWRcbiAgICAvLyBub2RlcyB0aGF0IHdlJ3JlIGluLlxuICAgIGZpbmRQbGFjZShub2RlLCBtYXJrcywgY2F1dGlvdXMpIHtcbiAgICAgICAgbGV0IHJvdXRlLCBzeW5jO1xuICAgICAgICBmb3IgKGxldCBkZXB0aCA9IHRoaXMub3BlbiwgcGVuYWx0eSA9IDA7IGRlcHRoID49IDA7IGRlcHRoLS0pIHtcbiAgICAgICAgICAgIGxldCBjeCA9IHRoaXMubm9kZXNbZGVwdGhdO1xuICAgICAgICAgICAgbGV0IGZvdW5kID0gY3guZmluZFdyYXBwaW5nKG5vZGUpO1xuICAgICAgICAgICAgaWYgKGZvdW5kICYmICghcm91dGUgfHwgcm91dGUubGVuZ3RoID4gZm91bmQubGVuZ3RoICsgcGVuYWx0eSkpIHtcbiAgICAgICAgICAgICAgICByb3V0ZSA9IGZvdW5kO1xuICAgICAgICAgICAgICAgIHN5bmMgPSBjeDtcbiAgICAgICAgICAgICAgICBpZiAoIWZvdW5kLmxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3guc29saWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2F1dGlvdXMpXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIHBlbmFsdHkgKz0gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIXJvdXRlKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHRoaXMuc3luYyhzeW5jKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3V0ZS5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIG1hcmtzID0gdGhpcy5lbnRlcklubmVyKHJvdXRlW2ldLCBudWxsLCBtYXJrcywgZmFsc2UpO1xuICAgICAgICByZXR1cm4gbWFya3M7XG4gICAgfVxuICAgIC8vIFRyeSB0byBpbnNlcnQgdGhlIGdpdmVuIG5vZGUsIGFkanVzdGluZyB0aGUgY29udGV4dCB3aGVuIG5lZWRlZC5cbiAgICBpbnNlcnROb2RlKG5vZGUsIG1hcmtzLCBjYXV0aW91cykge1xuICAgICAgICBpZiAobm9kZS5pc0lubGluZSAmJiB0aGlzLm5lZWRzQmxvY2sgJiYgIXRoaXMudG9wLnR5cGUpIHtcbiAgICAgICAgICAgIGxldCBibG9jayA9IHRoaXMudGV4dGJsb2NrRnJvbUNvbnRleHQoKTtcbiAgICAgICAgICAgIGlmIChibG9jaylcbiAgICAgICAgICAgICAgICBtYXJrcyA9IHRoaXMuZW50ZXJJbm5lcihibG9jaywgbnVsbCwgbWFya3MpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBpbm5lck1hcmtzID0gdGhpcy5maW5kUGxhY2Uobm9kZSwgbWFya3MsIGNhdXRpb3VzKTtcbiAgICAgICAgaWYgKGlubmVyTWFya3MpIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2VFeHRyYSgpO1xuICAgICAgICAgICAgbGV0IHRvcCA9IHRoaXMudG9wO1xuICAgICAgICAgICAgaWYgKHRvcC5tYXRjaClcbiAgICAgICAgICAgICAgICB0b3AubWF0Y2ggPSB0b3AubWF0Y2gubWF0Y2hUeXBlKG5vZGUudHlwZSk7XG4gICAgICAgICAgICBsZXQgbm9kZU1hcmtzID0gTWFyay5ub25lO1xuICAgICAgICAgICAgZm9yIChsZXQgbSBvZiBpbm5lck1hcmtzLmNvbmNhdChub2RlLm1hcmtzKSlcbiAgICAgICAgICAgICAgICBpZiAodG9wLnR5cGUgPyB0b3AudHlwZS5hbGxvd3NNYXJrVHlwZShtLnR5cGUpIDogbWFya01heUFwcGx5KG0udHlwZSwgbm9kZS50eXBlKSlcbiAgICAgICAgICAgICAgICAgICAgbm9kZU1hcmtzID0gbS5hZGRUb1NldChub2RlTWFya3MpO1xuICAgICAgICAgICAgdG9wLmNvbnRlbnQucHVzaChub2RlLm1hcmsobm9kZU1hcmtzKSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFRyeSB0byBzdGFydCBhIG5vZGUgb2YgdGhlIGdpdmVuIHR5cGUsIGFkanVzdGluZyB0aGUgY29udGV4dCB3aGVuXG4gICAgLy8gbmVjZXNzYXJ5LlxuICAgIGVudGVyKHR5cGUsIGF0dHJzLCBtYXJrcywgcHJlc2VydmVXUykge1xuICAgICAgICBsZXQgaW5uZXJNYXJrcyA9IHRoaXMuZmluZFBsYWNlKHR5cGUuY3JlYXRlKGF0dHJzKSwgbWFya3MsIGZhbHNlKTtcbiAgICAgICAgaWYgKGlubmVyTWFya3MpXG4gICAgICAgICAgICBpbm5lck1hcmtzID0gdGhpcy5lbnRlcklubmVyKHR5cGUsIGF0dHJzLCBtYXJrcywgdHJ1ZSwgcHJlc2VydmVXUyk7XG4gICAgICAgIHJldHVybiBpbm5lck1hcmtzO1xuICAgIH1cbiAgICAvLyBPcGVuIGEgbm9kZSBvZiB0aGUgZ2l2ZW4gdHlwZVxuICAgIGVudGVySW5uZXIodHlwZSwgYXR0cnMsIG1hcmtzLCBzb2xpZCA9IGZhbHNlLCBwcmVzZXJ2ZVdTKSB7XG4gICAgICAgIHRoaXMuY2xvc2VFeHRyYSgpO1xuICAgICAgICBsZXQgdG9wID0gdGhpcy50b3A7XG4gICAgICAgIHRvcC5tYXRjaCA9IHRvcC5tYXRjaCAmJiB0b3AubWF0Y2gubWF0Y2hUeXBlKHR5cGUpO1xuICAgICAgICBsZXQgb3B0aW9ucyA9IHdzT3B0aW9uc0Zvcih0eXBlLCBwcmVzZXJ2ZVdTLCB0b3Aub3B0aW9ucyk7XG4gICAgICAgIGlmICgodG9wLm9wdGlvbnMgJiBPUFRfT1BFTl9MRUZUKSAmJiB0b3AuY29udGVudC5sZW5ndGggPT0gMClcbiAgICAgICAgICAgIG9wdGlvbnMgfD0gT1BUX09QRU5fTEVGVDtcbiAgICAgICAgbGV0IGFwcGx5TWFya3MgPSBNYXJrLm5vbmU7XG4gICAgICAgIG1hcmtzID0gbWFya3MuZmlsdGVyKG0gPT4ge1xuICAgICAgICAgICAgaWYgKHRvcC50eXBlID8gdG9wLnR5cGUuYWxsb3dzTWFya1R5cGUobS50eXBlKSA6IG1hcmtNYXlBcHBseShtLnR5cGUsIHR5cGUpKSB7XG4gICAgICAgICAgICAgICAgYXBwbHlNYXJrcyA9IG0uYWRkVG9TZXQoYXBwbHlNYXJrcyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm5vZGVzLnB1c2gobmV3IE5vZGVDb250ZXh0KHR5cGUsIGF0dHJzLCBhcHBseU1hcmtzLCBzb2xpZCwgbnVsbCwgb3B0aW9ucykpO1xuICAgICAgICB0aGlzLm9wZW4rKztcbiAgICAgICAgcmV0dXJuIG1hcmtzO1xuICAgIH1cbiAgICAvLyBNYWtlIHN1cmUgYWxsIG5vZGVzIGFib3ZlIHRoaXMub3BlbiBhcmUgZmluaXNoZWQgYW5kIGFkZGVkIHRvXG4gICAgLy8gdGhlaXIgcGFyZW50c1xuICAgIGNsb3NlRXh0cmEob3BlbkVuZCA9IGZhbHNlKSB7XG4gICAgICAgIGxldCBpID0gdGhpcy5ub2Rlcy5sZW5ndGggLSAxO1xuICAgICAgICBpZiAoaSA+IHRoaXMub3Blbikge1xuICAgICAgICAgICAgZm9yICg7IGkgPiB0aGlzLm9wZW47IGktLSlcbiAgICAgICAgICAgICAgICB0aGlzLm5vZGVzW2kgLSAxXS5jb250ZW50LnB1c2godGhpcy5ub2Rlc1tpXS5maW5pc2gob3BlbkVuZCkpO1xuICAgICAgICAgICAgdGhpcy5ub2Rlcy5sZW5ndGggPSB0aGlzLm9wZW4gKyAxO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZpbmlzaCgpIHtcbiAgICAgICAgdGhpcy5vcGVuID0gMDtcbiAgICAgICAgdGhpcy5jbG9zZUV4dHJhKHRoaXMuaXNPcGVuKTtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9kZXNbMF0uZmluaXNoKCEhKHRoaXMuaXNPcGVuIHx8IHRoaXMub3B0aW9ucy50b3BPcGVuKSk7XG4gICAgfVxuICAgIHN5bmModG8pIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMub3BlbjsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm5vZGVzW2ldID09IHRvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuID0gaTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMubG9jYWxQcmVzZXJ2ZVdTKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub2Rlc1tpXS5vcHRpb25zIHw9IE9QVF9QUkVTRVJWRV9XUztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGdldCBjdXJyZW50UG9zKCkge1xuICAgICAgICB0aGlzLmNsb3NlRXh0cmEoKTtcbiAgICAgICAgbGV0IHBvcyA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLm9wZW47IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgY29udGVudCA9IHRoaXMubm9kZXNbaV0uY29udGVudDtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSBjb250ZW50Lmxlbmd0aCAtIDE7IGogPj0gMDsgai0tKVxuICAgICAgICAgICAgICAgIHBvcyArPSBjb250ZW50W2pdLm5vZGVTaXplO1xuICAgICAgICAgICAgaWYgKGkpXG4gICAgICAgICAgICAgICAgcG9zKys7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBvcztcbiAgICB9XG4gICAgZmluZEF0UG9pbnQocGFyZW50LCBvZmZzZXQpIHtcbiAgICAgICAgaWYgKHRoaXMuZmluZClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5maW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZmluZFtpXS5ub2RlID09IHBhcmVudCAmJiB0aGlzLmZpbmRbaV0ub2Zmc2V0ID09IG9mZnNldClcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maW5kW2ldLnBvcyA9IHRoaXMuY3VycmVudFBvcztcbiAgICAgICAgICAgIH1cbiAgICB9XG4gICAgZmluZEluc2lkZShwYXJlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuZmluZClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5maW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZmluZFtpXS5wb3MgPT0gbnVsbCAmJiBwYXJlbnQubm9kZVR5cGUgPT0gMSAmJiBwYXJlbnQuY29udGFpbnModGhpcy5maW5kW2ldLm5vZGUpKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRbaV0ucG9zID0gdGhpcy5jdXJyZW50UG9zO1xuICAgICAgICAgICAgfVxuICAgIH1cbiAgICBmaW5kQXJvdW5kKHBhcmVudCwgY29udGVudCwgYmVmb3JlKSB7XG4gICAgICAgIGlmIChwYXJlbnQgIT0gY29udGVudCAmJiB0aGlzLmZpbmQpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZmluZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmZpbmRbaV0ucG9zID09IG51bGwgJiYgcGFyZW50Lm5vZGVUeXBlID09IDEgJiYgcGFyZW50LmNvbnRhaW5zKHRoaXMuZmluZFtpXS5ub2RlKSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcG9zID0gY29udGVudC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbih0aGlzLmZpbmRbaV0ubm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb3MgJiAoYmVmb3JlID8gMiA6IDQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maW5kW2ldLnBvcyA9IHRoaXMuY3VycmVudFBvcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIGZpbmRJblRleHQodGV4dE5vZGUpIHtcbiAgICAgICAgaWYgKHRoaXMuZmluZClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5maW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZmluZFtpXS5ub2RlID09IHRleHROb2RlKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRbaV0ucG9zID0gdGhpcy5jdXJyZW50UG9zIC0gKHRleHROb2RlLm5vZGVWYWx1ZS5sZW5ndGggLSB0aGlzLmZpbmRbaV0ub2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICB9XG4gICAgLy8gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBnaXZlbiBjb250ZXh0IHN0cmluZyBtYXRjaGVzIHRoaXMgY29udGV4dC5cbiAgICBtYXRjaGVzQ29udGV4dChjb250ZXh0KSB7XG4gICAgICAgIGlmIChjb250ZXh0LmluZGV4T2YoXCJ8XCIpID4gLTEpXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5zcGxpdCgvXFxzKlxcfFxccyovKS5zb21lKHRoaXMubWF0Y2hlc0NvbnRleHQsIHRoaXMpO1xuICAgICAgICBsZXQgcGFydHMgPSBjb250ZXh0LnNwbGl0KFwiL1wiKTtcbiAgICAgICAgbGV0IG9wdGlvbiA9IHRoaXMub3B0aW9ucy5jb250ZXh0O1xuICAgICAgICBsZXQgdXNlUm9vdCA9ICF0aGlzLmlzT3BlbiAmJiAoIW9wdGlvbiB8fCBvcHRpb24ucGFyZW50LnR5cGUgPT0gdGhpcy5ub2Rlc1swXS50eXBlKTtcbiAgICAgICAgbGV0IG1pbkRlcHRoID0gLShvcHRpb24gPyBvcHRpb24uZGVwdGggKyAxIDogMCkgKyAodXNlUm9vdCA/IDAgOiAxKTtcbiAgICAgICAgbGV0IG1hdGNoID0gKGksIGRlcHRoKSA9PiB7XG4gICAgICAgICAgICBmb3IgKDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICBsZXQgcGFydCA9IHBhcnRzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0ID09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gcGFydHMubGVuZ3RoIC0gMSB8fCBpID09IDApXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGRlcHRoID49IG1pbkRlcHRoOyBkZXB0aC0tKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoKGkgLSAxLCBkZXB0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gZGVwdGggPiAwIHx8IChkZXB0aCA9PSAwICYmIHVzZVJvb3QpID8gdGhpcy5ub2Rlc1tkZXB0aF0udHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBvcHRpb24gJiYgZGVwdGggPj0gbWluRGVwdGggPyBvcHRpb24ubm9kZShkZXB0aCAtIG1pbkRlcHRoKS50eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW5leHQgfHwgKG5leHQubmFtZSAhPSBwYXJ0ICYmICFuZXh0LmlzSW5Hcm91cChwYXJ0KSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGRlcHRoLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtYXRjaChwYXJ0cy5sZW5ndGggLSAxLCB0aGlzLm9wZW4pO1xuICAgIH1cbiAgICB0ZXh0YmxvY2tGcm9tQ29udGV4dCgpIHtcbiAgICAgICAgbGV0ICRjb250ZXh0ID0gdGhpcy5vcHRpb25zLmNvbnRleHQ7XG4gICAgICAgIGlmICgkY29udGV4dClcbiAgICAgICAgICAgIGZvciAobGV0IGQgPSAkY29udGV4dC5kZXB0aDsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgICAgICAgICBsZXQgZGVmbHQgPSAkY29udGV4dC5ub2RlKGQpLmNvbnRlbnRNYXRjaEF0KCRjb250ZXh0LmluZGV4QWZ0ZXIoZCkpLmRlZmF1bHRUeXBlO1xuICAgICAgICAgICAgICAgIGlmIChkZWZsdCAmJiBkZWZsdC5pc1RleHRibG9jayAmJiBkZWZsdC5kZWZhdWx0QXR0cnMpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiB0aGlzLnBhcnNlci5zY2hlbWEubm9kZXMpIHtcbiAgICAgICAgICAgIGxldCB0eXBlID0gdGhpcy5wYXJzZXIuc2NoZW1hLm5vZGVzW25hbWVdO1xuICAgICAgICAgICAgaWYgKHR5cGUuaXNUZXh0YmxvY2sgJiYgdHlwZS5kZWZhdWx0QXR0cnMpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGU7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyBLbHVkZ2UgdG8gd29yayBhcm91bmQgZGlyZWN0bHkgbmVzdGVkIGxpc3Qgbm9kZXMgcHJvZHVjZWQgYnkgc29tZVxuLy8gdG9vbHMgYW5kIGFsbG93ZWQgYnkgYnJvd3NlcnMgdG8gbWVhbiB0aGF0IHRoZSBuZXN0ZWQgbGlzdCBpc1xuLy8gYWN0dWFsbHkgcGFydCBvZiB0aGUgbGlzdCBpdGVtIGFib3ZlIGl0LlxuZnVuY3Rpb24gbm9ybWFsaXplTGlzdChkb20pIHtcbiAgICBmb3IgKGxldCBjaGlsZCA9IGRvbS5maXJzdENoaWxkLCBwcmV2SXRlbSA9IG51bGw7IGNoaWxkOyBjaGlsZCA9IGNoaWxkLm5leHRTaWJsaW5nKSB7XG4gICAgICAgIGxldCBuYW1lID0gY2hpbGQubm9kZVR5cGUgPT0gMSA/IGNoaWxkLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgOiBudWxsO1xuICAgICAgICBpZiAobmFtZSAmJiBsaXN0VGFncy5oYXNPd25Qcm9wZXJ0eShuYW1lKSAmJiBwcmV2SXRlbSkge1xuICAgICAgICAgICAgcHJldkl0ZW0uYXBwZW5kQ2hpbGQoY2hpbGQpO1xuICAgICAgICAgICAgY2hpbGQgPSBwcmV2SXRlbTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lID09IFwibGlcIikge1xuICAgICAgICAgICAgcHJldkl0ZW0gPSBjaGlsZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lKSB7XG4gICAgICAgICAgICBwcmV2SXRlbSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyBBcHBseSBhIENTUyBzZWxlY3Rvci5cbmZ1bmN0aW9uIG1hdGNoZXMoZG9tLCBzZWxlY3Rvcikge1xuICAgIHJldHVybiAoZG9tLm1hdGNoZXMgfHwgZG9tLm1zTWF0Y2hlc1NlbGVjdG9yIHx8IGRvbS53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHwgZG9tLm1vek1hdGNoZXNTZWxlY3RvcikuY2FsbChkb20sIHNlbGVjdG9yKTtcbn1cbmZ1bmN0aW9uIGNvcHkob2JqKSB7XG4gICAgbGV0IGNvcHkgPSB7fTtcbiAgICBmb3IgKGxldCBwcm9wIGluIG9iailcbiAgICAgICAgY29weVtwcm9wXSA9IG9ialtwcm9wXTtcbiAgICByZXR1cm4gY29weTtcbn1cbi8vIFVzZWQgd2hlbiBmaW5kaW5nIGEgbWFyayBhdCB0aGUgdG9wIGxldmVsIG9mIGEgZnJhZ21lbnQgcGFyc2UuXG4vLyBDaGVja3Mgd2hldGhlciBpdCB3b3VsZCBiZSByZWFzb25hYmxlIHRvIGFwcGx5IGEgZ2l2ZW4gbWFyayB0eXBlIHRvXG4vLyBhIGdpdmVuIG5vZGUsIGJ5IGxvb2tpbmcgYXQgdGhlIHdheSB0aGUgbWFyayBvY2N1cnMgaW4gdGhlIHNjaGVtYS5cbmZ1bmN0aW9uIG1hcmtNYXlBcHBseShtYXJrVHlwZSwgbm9kZVR5cGUpIHtcbiAgICBsZXQgbm9kZXMgPSBub2RlVHlwZS5zY2hlbWEubm9kZXM7XG4gICAgZm9yIChsZXQgbmFtZSBpbiBub2Rlcykge1xuICAgICAgICBsZXQgcGFyZW50ID0gbm9kZXNbbmFtZV07XG4gICAgICAgIGlmICghcGFyZW50LmFsbG93c01hcmtUeXBlKG1hcmtUeXBlKSlcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBsZXQgc2VlbiA9IFtdLCBzY2FuID0gKG1hdGNoKSA9PiB7XG4gICAgICAgICAgICBzZWVuLnB1c2gobWF0Y2gpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXRjaC5lZGdlQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCB7IHR5cGUsIG5leHQgfSA9IG1hdGNoLmVkZ2UoaSk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gbm9kZVR5cGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIGlmIChzZWVuLmluZGV4T2YobmV4dCkgPCAwICYmIHNjYW4obmV4dCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoc2NhbihwYXJlbnQuY29udGVudE1hdGNoKSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cblxuLyoqXG5BIERPTSBzZXJpYWxpemVyIGtub3dzIGhvdyB0byBjb252ZXJ0IFByb3NlTWlycm9yIG5vZGVzIGFuZFxubWFya3Mgb2YgdmFyaW91cyB0eXBlcyB0byBET00gbm9kZXMuXG4qL1xuY2xhc3MgRE9NU2VyaWFsaXplciB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgc2VyaWFsaXplci4gYG5vZGVzYCBzaG91bGQgbWFwIG5vZGUgbmFtZXMgdG8gZnVuY3Rpb25zXG4gICAgdGhhdCB0YWtlIGEgbm9kZSBhbmQgcmV0dXJuIGEgZGVzY3JpcHRpb24gb2YgdGhlIGNvcnJlc3BvbmRpbmdcbiAgICBET00uIGBtYXJrc2AgZG9lcyB0aGUgc2FtZSBmb3IgbWFyayBuYW1lcywgYnV0IGFsc28gZ2V0cyBhblxuICAgIGFyZ3VtZW50IHRoYXQgdGVsbHMgaXQgd2hldGhlciB0aGUgbWFyaydzIGNvbnRlbnQgaXMgYmxvY2sgb3JcbiAgICBpbmxpbmUgY29udGVudCAoZm9yIHR5cGljYWwgdXNlLCBpdCdsbCBhbHdheXMgYmUgaW5saW5lKS4gQSBtYXJrXG4gICAgc2VyaWFsaXplciBtYXkgYmUgYG51bGxgIHRvIGluZGljYXRlIHRoYXQgbWFya3Mgb2YgdGhhdCB0eXBlXG4gICAgc2hvdWxkIG5vdCBiZSBzZXJpYWxpemVkLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIG5vZGUgc2VyaWFsaXphdGlvbiBmdW5jdGlvbnMuXG4gICAgKi9cbiAgICBub2RlcywgXG4gICAgLyoqXG4gICAgVGhlIG1hcmsgc2VyaWFsaXphdGlvbiBmdW5jdGlvbnMuXG4gICAgKi9cbiAgICBtYXJrcykge1xuICAgICAgICB0aGlzLm5vZGVzID0gbm9kZXM7XG4gICAgICAgIHRoaXMubWFya3MgPSBtYXJrcztcbiAgICB9XG4gICAgLyoqXG4gICAgU2VyaWFsaXplIHRoZSBjb250ZW50IG9mIHRoaXMgZnJhZ21lbnQgdG8gYSBET00gZnJhZ21lbnQuIFdoZW5cbiAgICBub3QgaW4gdGhlIGJyb3dzZXIsIHRoZSBgZG9jdW1lbnRgIG9wdGlvbiwgY29udGFpbmluZyBhIERPTVxuICAgIGRvY3VtZW50LCBzaG91bGQgYmUgcGFzc2VkIHNvIHRoYXQgdGhlIHNlcmlhbGl6ZXIgY2FuIGNyZWF0ZVxuICAgIG5vZGVzLlxuICAgICovXG4gICAgc2VyaWFsaXplRnJhZ21lbnQoZnJhZ21lbnQsIG9wdGlvbnMgPSB7fSwgdGFyZ2V0KSB7XG4gICAgICAgIGlmICghdGFyZ2V0KVxuICAgICAgICAgICAgdGFyZ2V0ID0gZG9jKG9wdGlvbnMpLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgbGV0IHRvcCA9IHRhcmdldCwgYWN0aXZlID0gW107XG4gICAgICAgIGZyYWdtZW50LmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICBpZiAoYWN0aXZlLmxlbmd0aCB8fCBub2RlLm1hcmtzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGxldCBrZWVwID0gMCwgcmVuZGVyZWQgPSAwO1xuICAgICAgICAgICAgICAgIHdoaWxlIChrZWVwIDwgYWN0aXZlLmxlbmd0aCAmJiByZW5kZXJlZCA8IG5vZGUubWFya3MubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gbm9kZS5tYXJrc1tyZW5kZXJlZF07XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5tYXJrc1tuZXh0LnR5cGUubmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcmVkKys7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5leHQuZXEoYWN0aXZlW2tlZXBdWzBdKSB8fCBuZXh0LnR5cGUuc3BlYy5zcGFubmluZyA9PT0gZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAga2VlcCsrO1xuICAgICAgICAgICAgICAgICAgICByZW5kZXJlZCsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB3aGlsZSAoa2VlcCA8IGFjdGl2ZS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRvcCA9IGFjdGl2ZS5wb3AoKVsxXTtcbiAgICAgICAgICAgICAgICB3aGlsZSAocmVuZGVyZWQgPCBub2RlLm1hcmtzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgYWRkID0gbm9kZS5tYXJrc1tyZW5kZXJlZCsrXTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG1hcmtET00gPSB0aGlzLnNlcmlhbGl6ZU1hcmsoYWRkLCBub2RlLmlzSW5saW5lLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1hcmtET00pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZS5wdXNoKFthZGQsIHRvcF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdG9wLmFwcGVuZENoaWxkKG1hcmtET00uZG9tKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcCA9IG1hcmtET00uY29udGVudERPTSB8fCBtYXJrRE9NLmRvbTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRvcC5hcHBlbmRDaGlsZCh0aGlzLnNlcmlhbGl6ZU5vZGVJbm5lcihub2RlLCBvcHRpb25zKSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHNlcmlhbGl6ZU5vZGVJbm5lcihub2RlLCBvcHRpb25zKSB7XG4gICAgICAgIGlmIChub2RlLmlzVGV4dClcbiAgICAgICAgICAgIHJldHVybiBkb2Mob3B0aW9ucykuY3JlYXRlVGV4dE5vZGUobm9kZS50ZXh0KTtcbiAgICAgICAgbGV0IHsgZG9tLCBjb250ZW50RE9NIH0gPSByZW5kZXJTcGVjKGRvYyhvcHRpb25zKSwgdGhpcy5ub2Rlc1tub2RlLnR5cGUubmFtZV0obm9kZSksIG51bGwsIG5vZGUuYXR0cnMpO1xuICAgICAgICBpZiAoY29udGVudERPTSkge1xuICAgICAgICAgICAgaWYgKG5vZGUuaXNMZWFmKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiQ29udGVudCBob2xlIG5vdCBhbGxvd2VkIGluIGEgbGVhZiBub2RlIHNwZWNcIik7XG4gICAgICAgICAgICB0aGlzLnNlcmlhbGl6ZUZyYWdtZW50KG5vZGUuY29udGVudCwgb3B0aW9ucywgY29udGVudERPTSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRvbTtcbiAgICB9XG4gICAgLyoqXG4gICAgU2VyaWFsaXplIHRoaXMgbm9kZSB0byBhIERPTSBub2RlLiBUaGlzIGNhbiBiZSB1c2VmdWwgd2hlbiB5b3VcbiAgICBuZWVkIHRvIHNlcmlhbGl6ZSBhIHBhcnQgb2YgYSBkb2N1bWVudCwgYXMgb3Bwb3NlZCB0byB0aGUgd2hvbGVcbiAgICBkb2N1bWVudC4gVG8gc2VyaWFsaXplIGEgd2hvbGUgZG9jdW1lbnQsIHVzZVxuICAgIFtgc2VyaWFsaXplRnJhZ21lbnRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuRE9NU2VyaWFsaXplci5zZXJpYWxpemVGcmFnbWVudCkgb25cbiAgICBpdHMgW2NvbnRlbnRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlLmNvbnRlbnQpLlxuICAgICovXG4gICAgc2VyaWFsaXplTm9kZShub2RlLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgbGV0IGRvbSA9IHRoaXMuc2VyaWFsaXplTm9kZUlubmVyKG5vZGUsIG9wdGlvbnMpO1xuICAgICAgICBmb3IgKGxldCBpID0gbm9kZS5tYXJrcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgbGV0IHdyYXAgPSB0aGlzLnNlcmlhbGl6ZU1hcmsobm9kZS5tYXJrc1tpXSwgbm9kZS5pc0lubGluZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAod3JhcCkge1xuICAgICAgICAgICAgICAgICh3cmFwLmNvbnRlbnRET00gfHwgd3JhcC5kb20pLmFwcGVuZENoaWxkKGRvbSk7XG4gICAgICAgICAgICAgICAgZG9tID0gd3JhcC5kb207XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRvbTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzZXJpYWxpemVNYXJrKG1hcmssIGlubGluZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGxldCB0b0RPTSA9IHRoaXMubWFya3NbbWFyay50eXBlLm5hbWVdO1xuICAgICAgICByZXR1cm4gdG9ET00gJiYgcmVuZGVyU3BlYyhkb2Mob3B0aW9ucyksIHRvRE9NKG1hcmssIGlubGluZSksIG51bGwsIG1hcmsuYXR0cnMpO1xuICAgIH1cbiAgICBzdGF0aWMgcmVuZGVyU3BlYyhkb2MsIHN0cnVjdHVyZSwgeG1sTlMgPSBudWxsLCBibG9ja0FycmF5c0luKSB7XG4gICAgICAgIC8vIEtsdWRnZSBmb3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCBhY2NpZGVudGFsIG9yaWdpbmFsIGJlaGF2aW91c1xuICAgICAgICBpZiAodHlwZW9mIHN0cnVjdHVyZSA9PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgcmV0dXJuIHsgZG9tOiBkb2MuY3JlYXRlVGV4dE5vZGUoc3RydWN0dXJlKSB9O1xuICAgICAgICByZXR1cm4gcmVuZGVyU3BlYyhkb2MsIHN0cnVjdHVyZSwgeG1sTlMsIGJsb2NrQXJyYXlzSW4pO1xuICAgIH1cbiAgICAvKipcbiAgICBCdWlsZCBhIHNlcmlhbGl6ZXIgdXNpbmcgdGhlIFtgdG9ET01gXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMudG9ET00pXG4gICAgcHJvcGVydGllcyBpbiBhIHNjaGVtYSdzIG5vZGUgYW5kIG1hcmsgc3BlY3MuXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbVNjaGVtYShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYS5jYWNoZWQuZG9tU2VyaWFsaXplciB8fFxuICAgICAgICAgICAgKHNjaGVtYS5jYWNoZWQuZG9tU2VyaWFsaXplciA9IG5ldyBET01TZXJpYWxpemVyKHRoaXMubm9kZXNGcm9tU2NoZW1hKHNjaGVtYSksIHRoaXMubWFya3NGcm9tU2NoZW1hKHNjaGVtYSkpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgR2F0aGVyIHRoZSBzZXJpYWxpemVycyBpbiBhIHNjaGVtYSdzIG5vZGUgc3BlY3MgaW50byBhbiBvYmplY3QuXG4gICAgVGhpcyBjYW4gYmUgdXNlZnVsIGFzIGEgYmFzZSB0byBidWlsZCBhIGN1c3RvbSBzZXJpYWxpemVyIGZyb20uXG4gICAgKi9cbiAgICBzdGF0aWMgbm9kZXNGcm9tU2NoZW1hKHNjaGVtYSkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gZ2F0aGVyVG9ET00oc2NoZW1hLm5vZGVzKTtcbiAgICAgICAgaWYgKCFyZXN1bHQudGV4dClcbiAgICAgICAgICAgIHJlc3VsdC50ZXh0ID0gbm9kZSA9PiBub2RlLnRleHQ7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKlxuICAgIEdhdGhlciB0aGUgc2VyaWFsaXplcnMgaW4gYSBzY2hlbWEncyBtYXJrIHNwZWNzIGludG8gYW4gb2JqZWN0LlxuICAgICovXG4gICAgc3RhdGljIG1hcmtzRnJvbVNjaGVtYShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIGdhdGhlclRvRE9NKHNjaGVtYS5tYXJrcyk7XG4gICAgfVxufVxuZnVuY3Rpb24gZ2F0aGVyVG9ET00ob2JqKSB7XG4gICAgbGV0IHJlc3VsdCA9IHt9O1xuICAgIGZvciAobGV0IG5hbWUgaW4gb2JqKSB7XG4gICAgICAgIGxldCB0b0RPTSA9IG9ialtuYW1lXS5zcGVjLnRvRE9NO1xuICAgICAgICBpZiAodG9ET00pXG4gICAgICAgICAgICByZXN1bHRbbmFtZV0gPSB0b0RPTTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGRvYyhvcHRpb25zKSB7XG4gICAgcmV0dXJuIG9wdGlvbnMuZG9jdW1lbnQgfHwgd2luZG93LmRvY3VtZW50O1xufVxuY29uc3Qgc3VzcGljaW91c0F0dHJpYnV0ZUNhY2hlID0gbmV3IFdlYWtNYXAoKTtcbmZ1bmN0aW9uIHN1c3BpY2lvdXNBdHRyaWJ1dGVzKGF0dHJzKSB7XG4gICAgbGV0IHZhbHVlID0gc3VzcGljaW91c0F0dHJpYnV0ZUNhY2hlLmdldChhdHRycyk7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpXG4gICAgICAgIHN1c3BpY2lvdXNBdHRyaWJ1dGVDYWNoZS5zZXQoYXR0cnMsIHZhbHVlID0gc3VzcGljaW91c0F0dHJpYnV0ZXNJbm5lcihhdHRycykpO1xuICAgIHJldHVybiB2YWx1ZTtcbn1cbmZ1bmN0aW9uIHN1c3BpY2lvdXNBdHRyaWJ1dGVzSW5uZXIoYXR0cnMpIHtcbiAgICBsZXQgcmVzdWx0ID0gbnVsbDtcbiAgICBmdW5jdGlvbiBzY2FuKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZVswXSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcmVzdWx0KVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gW107XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgICAgICAgICBzY2FuKHZhbHVlW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBwcm9wIGluIHZhbHVlKVxuICAgICAgICAgICAgICAgICAgICBzY2FuKHZhbHVlW3Byb3BdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBzY2FuKGF0dHJzKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gcmVuZGVyU3BlYyhkb2MsIHN0cnVjdHVyZSwgeG1sTlMsIGJsb2NrQXJyYXlzSW4pIHtcbiAgICBpZiAoc3RydWN0dXJlLm5vZGVUeXBlID09IDEpXG4gICAgICAgIHJldHVybiB7IGRvbTogc3RydWN0dXJlIH07XG4gICAgaWYgKHN0cnVjdHVyZS5kb20gJiYgc3RydWN0dXJlLmRvbS5ub2RlVHlwZSA9PSAxKVxuICAgICAgICByZXR1cm4gc3RydWN0dXJlO1xuICAgIGxldCB0YWdOYW1lID0gc3RydWN0dXJlWzBdLCBzdXNwaWNpb3VzO1xuICAgIGlmICh0eXBlb2YgdGFnTmFtZSAhPSBcInN0cmluZ1wiKVxuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgYXJyYXkgcGFzc2VkIHRvIHJlbmRlclNwZWNcIik7XG4gICAgaWYgKGJsb2NrQXJyYXlzSW4gJiYgKHN1c3BpY2lvdXMgPSBzdXNwaWNpb3VzQXR0cmlidXRlcyhibG9ja0FycmF5c0luKSkgJiZcbiAgICAgICAgc3VzcGljaW91cy5pbmRleE9mKHN0cnVjdHVyZSkgPiAtMSlcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJVc2luZyBhbiBhcnJheSBmcm9tIGFuIGF0dHJpYnV0ZSBvYmplY3QgYXMgYSBET00gc3BlYy4gVGhpcyBtYXkgYmUgYW4gYXR0ZW1wdGVkIGNyb3NzIHNpdGUgc2NyaXB0aW5nIGF0dGFjay5cIik7XG4gICAgbGV0IHNwYWNlID0gdGFnTmFtZS5pbmRleE9mKFwiIFwiKTtcbiAgICBpZiAoc3BhY2UgPiAwKSB7XG4gICAgICAgIHhtbE5TID0gdGFnTmFtZS5zbGljZSgwLCBzcGFjZSk7XG4gICAgICAgIHRhZ05hbWUgPSB0YWdOYW1lLnNsaWNlKHNwYWNlICsgMSk7XG4gICAgfVxuICAgIGxldCBjb250ZW50RE9NO1xuICAgIGxldCBkb20gPSAoeG1sTlMgPyBkb2MuY3JlYXRlRWxlbWVudE5TKHhtbE5TLCB0YWdOYW1lKSA6IGRvYy5jcmVhdGVFbGVtZW50KHRhZ05hbWUpKTtcbiAgICBsZXQgYXR0cnMgPSBzdHJ1Y3R1cmVbMV0sIHN0YXJ0ID0gMTtcbiAgICBpZiAoYXR0cnMgJiYgdHlwZW9mIGF0dHJzID09IFwib2JqZWN0XCIgJiYgYXR0cnMubm9kZVR5cGUgPT0gbnVsbCAmJiAhQXJyYXkuaXNBcnJheShhdHRycykpIHtcbiAgICAgICAgc3RhcnQgPSAyO1xuICAgICAgICBmb3IgKGxldCBuYW1lIGluIGF0dHJzKVxuICAgICAgICAgICAgaWYgKGF0dHJzW25hbWVdICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBsZXQgc3BhY2UgPSBuYW1lLmluZGV4T2YoXCIgXCIpO1xuICAgICAgICAgICAgICAgIGlmIChzcGFjZSA+IDApXG4gICAgICAgICAgICAgICAgICAgIGRvbS5zZXRBdHRyaWJ1dGVOUyhuYW1lLnNsaWNlKDAsIHNwYWNlKSwgbmFtZS5zbGljZShzcGFjZSArIDEpLCBhdHRyc1tuYW1lXSk7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAobmFtZSA9PSBcInN0eWxlXCIgJiYgZG9tLnN0eWxlKVxuICAgICAgICAgICAgICAgICAgICBkb20uc3R5bGUuY3NzVGV4dCA9IGF0dHJzW25hbWVdO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgZG9tLnNldEF0dHJpYnV0ZShuYW1lLCBhdHRyc1tuYW1lXSk7XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IHN0cnVjdHVyZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgY2hpbGQgPSBzdHJ1Y3R1cmVbaV07XG4gICAgICAgIGlmIChjaGlsZCA9PT0gMCkge1xuICAgICAgICAgICAgaWYgKGkgPCBzdHJ1Y3R1cmUubGVuZ3RoIC0gMSB8fCBpID4gc3RhcnQpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJDb250ZW50IGhvbGUgbXVzdCBiZSB0aGUgb25seSBjaGlsZCBvZiBpdHMgcGFyZW50IG5vZGVcIik7XG4gICAgICAgICAgICByZXR1cm4geyBkb20sIGNvbnRlbnRET006IGRvbSB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBjaGlsZCA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBkb20uYXBwZW5kQ2hpbGQoZG9jLmNyZWF0ZVRleHROb2RlKGNoaWxkKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgeyBkb206IGlubmVyLCBjb250ZW50RE9NOiBpbm5lckNvbnRlbnQgfSA9IHJlbmRlclNwZWMoZG9jLCBjaGlsZCwgeG1sTlMsIGJsb2NrQXJyYXlzSW4pO1xuICAgICAgICAgICAgZG9tLmFwcGVuZENoaWxkKGlubmVyKTtcbiAgICAgICAgICAgIGlmIChpbm5lckNvbnRlbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29udGVudERPTSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJNdWx0aXBsZSBjb250ZW50IGhvbGVzXCIpO1xuICAgICAgICAgICAgICAgIGNvbnRlbnRET00gPSBpbm5lckNvbnRlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgZG9tLCBjb250ZW50RE9NIH07XG59XG5cbmV4cG9ydCB7IENvbnRlbnRNYXRjaCwgRE9NUGFyc2VyLCBET01TZXJpYWxpemVyLCBGcmFnbWVudCwgTWFyaywgTWFya1R5cGUsIE5vZGUsIE5vZGVSYW5nZSwgTm9kZVR5cGUsIFJlcGxhY2VFcnJvciwgUmVzb2x2ZWRQb3MsIFNjaGVtYSwgU2xpY2UgfTtcbiIsICJpbXBvcnQgeyBSZXBsYWNlRXJyb3IsIFNsaWNlLCBGcmFnbWVudCwgTWFya1R5cGUsIE1hcmsgfSBmcm9tICdwcm9zZW1pcnJvci1tb2RlbCc7XG5cbi8vIFJlY292ZXJ5IHZhbHVlcyBlbmNvZGUgYSByYW5nZSBpbmRleCBhbmQgYW4gb2Zmc2V0LiBUaGV5IGFyZVxuLy8gcmVwcmVzZW50ZWQgYXMgbnVtYmVycywgYmVjYXVzZSB0b25zIG9mIHRoZW0gd2lsbCBiZSBjcmVhdGVkIHdoZW5cbi8vIG1hcHBpbmcsIGZvciBleGFtcGxlLCBhIGxhcmdlIG51bWJlciBvZiBkZWNvcmF0aW9ucy4gVGhlIG51bWJlcidzXG4vLyBsb3dlciAxNiBiaXRzIHByb3ZpZGUgdGhlIGluZGV4LCB0aGUgcmVtYWluaW5nIGJpdHMgdGhlIG9mZnNldC5cbi8vXG4vLyBOb3RlOiBXZSBpbnRlbnRpb25hbGx5IGRvbid0IHVzZSBiaXQgc2hpZnQgb3BlcmF0b3JzIHRvIGVuLSBhbmRcbi8vIGRlY29kZSB0aGVzZSwgc2luY2UgdGhvc2UgY2xpcCB0byAzMiBiaXRzLCB3aGljaCB3ZSBtaWdodCBpbiByYXJlXG4vLyBjYXNlcyB3YW50IHRvIG92ZXJmbG93LiBBIDY0LWJpdCBmbG9hdCBjYW4gcmVwcmVzZW50IDQ4LWJpdFxuLy8gaW50ZWdlcnMgcHJlY2lzZWx5LlxuY29uc3QgbG93ZXIxNiA9IDB4ZmZmZjtcbmNvbnN0IGZhY3RvcjE2ID0gTWF0aC5wb3coMiwgMTYpO1xuZnVuY3Rpb24gbWFrZVJlY292ZXIoaW5kZXgsIG9mZnNldCkgeyByZXR1cm4gaW5kZXggKyBvZmZzZXQgKiBmYWN0b3IxNjsgfVxuZnVuY3Rpb24gcmVjb3ZlckluZGV4KHZhbHVlKSB7IHJldHVybiB2YWx1ZSAmIGxvd2VyMTY7IH1cbmZ1bmN0aW9uIHJlY292ZXJPZmZzZXQodmFsdWUpIHsgcmV0dXJuICh2YWx1ZSAtICh2YWx1ZSAmIGxvd2VyMTYpKSAvIGZhY3RvcjE2OyB9XG5jb25zdCBERUxfQkVGT1JFID0gMSwgREVMX0FGVEVSID0gMiwgREVMX0FDUk9TUyA9IDQsIERFTF9TSURFID0gODtcbi8qKlxuQW4gb2JqZWN0IHJlcHJlc2VudGluZyBhIG1hcHBlZCBwb3NpdGlvbiB3aXRoIGV4dHJhXG5pbmZvcm1hdGlvbi5cbiovXG5jbGFzcyBNYXBSZXN1bHQge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIG1hcHBlZCB2ZXJzaW9uIG9mIHRoZSBwb3NpdGlvbi5cbiAgICAqL1xuICAgIHBvcywgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBkZWxJbmZvLCBcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHJlY292ZXIpIHtcbiAgICAgICAgdGhpcy5wb3MgPSBwb3M7XG4gICAgICAgIHRoaXMuZGVsSW5mbyA9IGRlbEluZm87XG4gICAgICAgIHRoaXMucmVjb3ZlciA9IHJlY292ZXI7XG4gICAgfVxuICAgIC8qKlxuICAgIFRlbGxzIHlvdSB3aGV0aGVyIHRoZSBwb3NpdGlvbiB3YXMgZGVsZXRlZCwgdGhhdCBpcywgd2hldGhlciB0aGVcbiAgICBzdGVwIHJlbW92ZWQgdGhlIHRva2VuIG9uIHRoZSBzaWRlIHF1ZXJpZWQgKHZpYSB0aGUgYGFzc29jYClcbiAgICBhcmd1bWVudCBmcm9tIHRoZSBkb2N1bWVudC5cbiAgICAqL1xuICAgIGdldCBkZWxldGVkKCkgeyByZXR1cm4gKHRoaXMuZGVsSW5mbyAmIERFTF9TSURFKSA+IDA7IH1cbiAgICAvKipcbiAgICBUZWxscyB5b3Ugd2hldGhlciB0aGUgdG9rZW4gYmVmb3JlIHRoZSBtYXBwZWQgcG9zaXRpb24gd2FzIGRlbGV0ZWQuXG4gICAgKi9cbiAgICBnZXQgZGVsZXRlZEJlZm9yZSgpIHsgcmV0dXJuICh0aGlzLmRlbEluZm8gJiAoREVMX0JFRk9SRSB8IERFTF9BQ1JPU1MpKSA+IDA7IH1cbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhlIHRva2VuIGFmdGVyIHRoZSBtYXBwZWQgcG9zaXRpb24gd2FzIGRlbGV0ZWQuXG4gICAgKi9cbiAgICBnZXQgZGVsZXRlZEFmdGVyKCkgeyByZXR1cm4gKHRoaXMuZGVsSW5mbyAmIChERUxfQUZURVIgfCBERUxfQUNST1NTKSkgPiAwOyB9XG4gICAgLyoqXG4gICAgVGVsbHMgd2hldGhlciBhbnkgb2YgdGhlIHN0ZXBzIG1hcHBlZCB0aHJvdWdoIGRlbGV0ZXMgYWNyb3NzIHRoZVxuICAgIHBvc2l0aW9uIChpbmNsdWRpbmcgYm90aCB0aGUgdG9rZW4gYmVmb3JlIGFuZCBhZnRlciB0aGVcbiAgICBwb3NpdGlvbikuXG4gICAgKi9cbiAgICBnZXQgZGVsZXRlZEFjcm9zcygpIHsgcmV0dXJuICh0aGlzLmRlbEluZm8gJiBERUxfQUNST1NTKSA+IDA7IH1cbn1cbi8qKlxuQSBtYXAgZGVzY3JpYmluZyB0aGUgZGVsZXRpb25zIGFuZCBpbnNlcnRpb25zIG1hZGUgYnkgYSBzdGVwLCB3aGljaFxuY2FuIGJlIHVzZWQgdG8gZmluZCB0aGUgY29ycmVzcG9uZGVuY2UgYmV0d2VlbiBwb3NpdGlvbnMgaW4gdGhlXG5wcmUtc3RlcCB2ZXJzaW9uIG9mIGEgZG9jdW1lbnQgYW5kIHRoZSBzYW1lIHBvc2l0aW9uIGluIHRoZVxucG9zdC1zdGVwIHZlcnNpb24uXG4qL1xuY2xhc3MgU3RlcE1hcCB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgcG9zaXRpb24gbWFwLiBUaGUgbW9kaWZpY2F0aW9ucyB0byB0aGUgZG9jdW1lbnQgYXJlXG4gICAgcmVwcmVzZW50ZWQgYXMgYW4gYXJyYXkgb2YgbnVtYmVycywgaW4gd2hpY2ggZWFjaCBncm91cCBvZiB0aHJlZVxuICAgIHJlcHJlc2VudHMgYSBtb2RpZmllZCBjaHVuayBhcyBgW3N0YXJ0LCBvbGRTaXplLCBuZXdTaXplXWAuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHJhbmdlcywgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBpbnZlcnRlZCA9IGZhbHNlKSB7XG4gICAgICAgIHRoaXMucmFuZ2VzID0gcmFuZ2VzO1xuICAgICAgICB0aGlzLmludmVydGVkID0gaW52ZXJ0ZWQ7XG4gICAgICAgIGlmICghcmFuZ2VzLmxlbmd0aCAmJiBTdGVwTWFwLmVtcHR5KVxuICAgICAgICAgICAgcmV0dXJuIFN0ZXBNYXAuZW1wdHk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgcmVjb3Zlcih2YWx1ZSkge1xuICAgICAgICBsZXQgZGlmZiA9IDAsIGluZGV4ID0gcmVjb3ZlckluZGV4KHZhbHVlKTtcbiAgICAgICAgaWYgKCF0aGlzLmludmVydGVkKVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRleDsgaSsrKVxuICAgICAgICAgICAgICAgIGRpZmYgKz0gdGhpcy5yYW5nZXNbaSAqIDMgKyAyXSAtIHRoaXMucmFuZ2VzW2kgKiAzICsgMV07XG4gICAgICAgIHJldHVybiB0aGlzLnJhbmdlc1tpbmRleCAqIDNdICsgZGlmZiArIHJlY292ZXJPZmZzZXQodmFsdWUpO1xuICAgIH1cbiAgICBtYXBSZXN1bHQocG9zLCBhc3NvYyA9IDEpIHsgcmV0dXJuIHRoaXMuX21hcChwb3MsIGFzc29jLCBmYWxzZSk7IH1cbiAgICBtYXAocG9zLCBhc3NvYyA9IDEpIHsgcmV0dXJuIHRoaXMuX21hcChwb3MsIGFzc29jLCB0cnVlKTsgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgX21hcChwb3MsIGFzc29jLCBzaW1wbGUpIHtcbiAgICAgICAgbGV0IGRpZmYgPSAwLCBvbGRJbmRleCA9IHRoaXMuaW52ZXJ0ZWQgPyAyIDogMSwgbmV3SW5kZXggPSB0aGlzLmludmVydGVkID8gMSA6IDI7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5yYW5nZXMubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgIGxldCBzdGFydCA9IHRoaXMucmFuZ2VzW2ldIC0gKHRoaXMuaW52ZXJ0ZWQgPyBkaWZmIDogMCk7XG4gICAgICAgICAgICBpZiAoc3RhcnQgPiBwb3MpXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBsZXQgb2xkU2l6ZSA9IHRoaXMucmFuZ2VzW2kgKyBvbGRJbmRleF0sIG5ld1NpemUgPSB0aGlzLnJhbmdlc1tpICsgbmV3SW5kZXhdLCBlbmQgPSBzdGFydCArIG9sZFNpemU7XG4gICAgICAgICAgICBpZiAocG9zIDw9IGVuZCkge1xuICAgICAgICAgICAgICAgIGxldCBzaWRlID0gIW9sZFNpemUgPyBhc3NvYyA6IHBvcyA9PSBzdGFydCA/IC0xIDogcG9zID09IGVuZCA/IDEgOiBhc3NvYztcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gc3RhcnQgKyBkaWZmICsgKHNpZGUgPCAwID8gMCA6IG5ld1NpemUpO1xuICAgICAgICAgICAgICAgIGlmIChzaW1wbGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgbGV0IHJlY292ZXIgPSBwb3MgPT0gKGFzc29jIDwgMCA/IHN0YXJ0IDogZW5kKSA/IG51bGwgOiBtYWtlUmVjb3ZlcihpIC8gMywgcG9zIC0gc3RhcnQpO1xuICAgICAgICAgICAgICAgIGxldCBkZWwgPSBwb3MgPT0gc3RhcnQgPyBERUxfQUZURVIgOiBwb3MgPT0gZW5kID8gREVMX0JFRk9SRSA6IERFTF9BQ1JPU1M7XG4gICAgICAgICAgICAgICAgaWYgKGFzc29jIDwgMCA/IHBvcyAhPSBzdGFydCA6IHBvcyAhPSBlbmQpXG4gICAgICAgICAgICAgICAgICAgIGRlbCB8PSBERUxfU0lERTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE1hcFJlc3VsdChyZXN1bHQsIGRlbCwgcmVjb3Zlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkaWZmICs9IG5ld1NpemUgLSBvbGRTaXplO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzaW1wbGUgPyBwb3MgKyBkaWZmIDogbmV3IE1hcFJlc3VsdChwb3MgKyBkaWZmLCAwLCBudWxsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICB0b3VjaGVzKHBvcywgcmVjb3Zlcikge1xuICAgICAgICBsZXQgZGlmZiA9IDAsIGluZGV4ID0gcmVjb3ZlckluZGV4KHJlY292ZXIpO1xuICAgICAgICBsZXQgb2xkSW5kZXggPSB0aGlzLmludmVydGVkID8gMiA6IDEsIG5ld0luZGV4ID0gdGhpcy5pbnZlcnRlZCA/IDEgOiAyO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucmFuZ2VzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLnJhbmdlc1tpXSAtICh0aGlzLmludmVydGVkID8gZGlmZiA6IDApO1xuICAgICAgICAgICAgaWYgKHN0YXJ0ID4gcG9zKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgbGV0IG9sZFNpemUgPSB0aGlzLnJhbmdlc1tpICsgb2xkSW5kZXhdLCBlbmQgPSBzdGFydCArIG9sZFNpemU7XG4gICAgICAgICAgICBpZiAocG9zIDw9IGVuZCAmJiBpID09IGluZGV4ICogMylcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIGRpZmYgKz0gdGhpcy5yYW5nZXNbaSArIG5ld0luZGV4XSAtIG9sZFNpemU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvKipcbiAgICBDYWxscyB0aGUgZ2l2ZW4gZnVuY3Rpb24gb24gZWFjaCBvZiB0aGUgY2hhbmdlZCByYW5nZXMgaW5jbHVkZWQgaW5cbiAgICB0aGlzIG1hcC5cbiAgICAqL1xuICAgIGZvckVhY2goZikge1xuICAgICAgICBsZXQgb2xkSW5kZXggPSB0aGlzLmludmVydGVkID8gMiA6IDEsIG5ld0luZGV4ID0gdGhpcy5pbnZlcnRlZCA/IDEgOiAyO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgZGlmZiA9IDA7IGkgPCB0aGlzLnJhbmdlcy5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgICAgICAgbGV0IHN0YXJ0ID0gdGhpcy5yYW5nZXNbaV0sIG9sZFN0YXJ0ID0gc3RhcnQgLSAodGhpcy5pbnZlcnRlZCA/IGRpZmYgOiAwKSwgbmV3U3RhcnQgPSBzdGFydCArICh0aGlzLmludmVydGVkID8gMCA6IGRpZmYpO1xuICAgICAgICAgICAgbGV0IG9sZFNpemUgPSB0aGlzLnJhbmdlc1tpICsgb2xkSW5kZXhdLCBuZXdTaXplID0gdGhpcy5yYW5nZXNbaSArIG5ld0luZGV4XTtcbiAgICAgICAgICAgIGYob2xkU3RhcnQsIG9sZFN0YXJ0ICsgb2xkU2l6ZSwgbmV3U3RhcnQsIG5ld1N0YXJ0ICsgbmV3U2l6ZSk7XG4gICAgICAgICAgICBkaWZmICs9IG5ld1NpemUgLSBvbGRTaXplO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhbiBpbnZlcnRlZCB2ZXJzaW9uIG9mIHRoaXMgbWFwLiBUaGUgcmVzdWx0IGNhbiBiZSB1c2VkIHRvXG4gICAgbWFwIHBvc2l0aW9ucyBpbiB0aGUgcG9zdC1zdGVwIGRvY3VtZW50IHRvIHRoZSBwcmUtc3RlcCBkb2N1bWVudC5cbiAgICAqL1xuICAgIGludmVydCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdGVwTWFwKHRoaXMucmFuZ2VzLCAhdGhpcy5pbnZlcnRlZCk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy5pbnZlcnRlZCA/IFwiLVwiIDogXCJcIikgKyBKU09OLnN0cmluZ2lmeSh0aGlzLnJhbmdlcyk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG1hcCB0aGF0IG1vdmVzIGFsbCBwb3NpdGlvbnMgYnkgb2Zmc2V0IGBuYCAod2hpY2ggbWF5IGJlXG4gICAgbmVnYXRpdmUpLiBUaGlzIGNhbiBiZSB1c2VmdWwgd2hlbiBhcHBseWluZyBzdGVwcyBtZWFudCBmb3IgYVxuICAgIHN1Yi1kb2N1bWVudCB0byBhIGxhcmdlciBkb2N1bWVudCwgb3IgdmljZS12ZXJzYS5cbiAgICAqL1xuICAgIHN0YXRpYyBvZmZzZXQobikge1xuICAgICAgICByZXR1cm4gbiA9PSAwID8gU3RlcE1hcC5lbXB0eSA6IG5ldyBTdGVwTWFwKG4gPCAwID8gWzAsIC1uLCAwXSA6IFswLCAwLCBuXSk7XG4gICAgfVxufVxuLyoqXG5BIFN0ZXBNYXAgdGhhdCBjb250YWlucyBubyBjaGFuZ2VkIHJhbmdlcy5cbiovXG5TdGVwTWFwLmVtcHR5ID0gbmV3IFN0ZXBNYXAoW10pO1xuLyoqXG5BIG1hcHBpbmcgcmVwcmVzZW50cyBhIHBpcGVsaW5lIG9mIHplcm8gb3IgbW9yZSBbc3RlcFxubWFwc10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5TdGVwTWFwKS4gSXQgaGFzIHNwZWNpYWwgcHJvdmlzaW9ucyBmb3IgbG9zc2xlc3NseVxuaGFuZGxpbmcgbWFwcGluZyBwb3NpdGlvbnMgdGhyb3VnaCBhIHNlcmllcyBvZiBzdGVwcyBpbiB3aGljaCBzb21lXG5zdGVwcyBhcmUgaW52ZXJ0ZWQgdmVyc2lvbnMgb2YgZWFybGllciBzdGVwcy4gKFRoaXMgY29tZXMgdXAgd2hlblxuXHUyMDE4W3JlYmFzaW5nXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL2d1aWRlLyN0cmFuc2Zvcm0ucmViYXNpbmcpXHUyMDE5IHN0ZXBzIGZvclxuY29sbGFib3JhdGlvbiBvciBoaXN0b3J5IG1hbmFnZW1lbnQuKVxuKi9cbmNsYXNzIE1hcHBpbmcge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5ldyBtYXBwaW5nIHdpdGggdGhlIGdpdmVuIHBvc2l0aW9uIG1hcHMuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihtYXBzLCBcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIG1pcnJvciwgXG4gICAgLyoqXG4gICAgVGhlIHN0YXJ0aW5nIHBvc2l0aW9uIGluIHRoZSBgbWFwc2AgYXJyYXksIHVzZWQgd2hlbiBgbWFwYCBvclxuICAgIGBtYXBSZXN1bHRgIGlzIGNhbGxlZC5cbiAgICAqL1xuICAgIGZyb20gPSAwLCBcbiAgICAvKipcbiAgICBUaGUgZW5kIHBvc2l0aW9uIGluIHRoZSBgbWFwc2AgYXJyYXkuXG4gICAgKi9cbiAgICB0byA9IG1hcHMgPyBtYXBzLmxlbmd0aCA6IDApIHtcbiAgICAgICAgdGhpcy5taXJyb3IgPSBtaXJyb3I7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgICAgIHRoaXMudG8gPSB0bztcbiAgICAgICAgdGhpcy5fbWFwcyA9IG1hcHMgfHwgW107XG4gICAgICAgIHRoaXMub3duRGF0YSA9ICEobWFwcyB8fCBtaXJyb3IpO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgc3RlcCBtYXBzIGluIHRoaXMgbWFwcGluZy5cbiAgICAqL1xuICAgIGdldCBtYXBzKCkgeyByZXR1cm4gdGhpcy5fbWFwczsgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG1hcHBpbmcgdGhhdCBtYXBzIG9ubHkgdGhyb3VnaCBhIHBhcnQgb2YgdGhpcyBvbmUuXG4gICAgKi9cbiAgICBzbGljZShmcm9tID0gMCwgdG8gPSB0aGlzLm1hcHMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWFwcGluZyh0aGlzLl9tYXBzLCB0aGlzLm1pcnJvciwgZnJvbSwgdG8pO1xuICAgIH1cbiAgICAvKipcbiAgICBBZGQgYSBzdGVwIG1hcCB0byB0aGUgZW5kIG9mIHRoaXMgbWFwcGluZy4gSWYgYG1pcnJvcnNgIGlzXG4gICAgZ2l2ZW4sIGl0IHNob3VsZCBiZSB0aGUgaW5kZXggb2YgdGhlIHN0ZXAgbWFwIHRoYXQgaXMgdGhlIG1pcnJvclxuICAgIGltYWdlIG9mIHRoaXMgb25lLlxuICAgICovXG4gICAgYXBwZW5kTWFwKG1hcCwgbWlycm9ycykge1xuICAgICAgICBpZiAoIXRoaXMub3duRGF0YSkge1xuICAgICAgICAgICAgdGhpcy5fbWFwcyA9IHRoaXMuX21hcHMuc2xpY2UoKTtcbiAgICAgICAgICAgIHRoaXMubWlycm9yID0gdGhpcy5taXJyb3IgJiYgdGhpcy5taXJyb3Iuc2xpY2UoKTtcbiAgICAgICAgICAgIHRoaXMub3duRGF0YSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50byA9IHRoaXMuX21hcHMucHVzaChtYXApO1xuICAgICAgICBpZiAobWlycm9ycyAhPSBudWxsKVxuICAgICAgICAgICAgdGhpcy5zZXRNaXJyb3IodGhpcy5fbWFwcy5sZW5ndGggLSAxLCBtaXJyb3JzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQWRkIGFsbCB0aGUgc3RlcCBtYXBzIGluIGEgZ2l2ZW4gbWFwcGluZyB0byB0aGlzIG9uZSAocHJlc2VydmluZ1xuICAgIG1pcnJvcmluZyBpbmZvcm1hdGlvbikuXG4gICAgKi9cbiAgICBhcHBlbmRNYXBwaW5nKG1hcHBpbmcpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIHN0YXJ0U2l6ZSA9IHRoaXMuX21hcHMubGVuZ3RoOyBpIDwgbWFwcGluZy5fbWFwcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG1pcnIgPSBtYXBwaW5nLmdldE1pcnJvcihpKTtcbiAgICAgICAgICAgIHRoaXMuYXBwZW5kTWFwKG1hcHBpbmcuX21hcHNbaV0sIG1pcnIgIT0gbnVsbCAmJiBtaXJyIDwgaSA/IHN0YXJ0U2l6ZSArIG1pcnIgOiB1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmRzIHRoZSBvZmZzZXQgb2YgdGhlIHN0ZXAgbWFwIHRoYXQgbWlycm9ycyB0aGUgbWFwIGF0IHRoZVxuICAgIGdpdmVuIG9mZnNldCwgaW4gdGhpcyBtYXBwaW5nIChhcyBwZXIgdGhlIHNlY29uZCBhcmd1bWVudCB0b1xuICAgIGBhcHBlbmRNYXBgKS5cbiAgICAqL1xuICAgIGdldE1pcnJvcihuKSB7XG4gICAgICAgIGlmICh0aGlzLm1pcnJvcilcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5taXJyb3IubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubWlycm9yW2ldID09IG4pXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm1pcnJvcltpICsgKGkgJSAyID8gLTEgOiAxKV07XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc2V0TWlycm9yKG4sIG0pIHtcbiAgICAgICAgaWYgKCF0aGlzLm1pcnJvcilcbiAgICAgICAgICAgIHRoaXMubWlycm9yID0gW107XG4gICAgICAgIHRoaXMubWlycm9yLnB1c2gobiwgbSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEFwcGVuZCB0aGUgaW52ZXJzZSBvZiB0aGUgZ2l2ZW4gbWFwcGluZyB0byB0aGlzIG9uZS5cbiAgICAqL1xuICAgIGFwcGVuZE1hcHBpbmdJbnZlcnRlZChtYXBwaW5nKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSBtYXBwaW5nLm1hcHMubGVuZ3RoIC0gMSwgdG90YWxTaXplID0gdGhpcy5fbWFwcy5sZW5ndGggKyBtYXBwaW5nLl9tYXBzLmxlbmd0aDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGxldCBtaXJyID0gbWFwcGluZy5nZXRNaXJyb3IoaSk7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZE1hcChtYXBwaW5nLl9tYXBzW2ldLmludmVydCgpLCBtaXJyICE9IG51bGwgJiYgbWlyciA+IGkgPyB0b3RhbFNpemUgLSBtaXJyIC0gMSA6IHVuZGVmaW5lZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGFuIGludmVydGVkIHZlcnNpb24gb2YgdGhpcyBtYXBwaW5nLlxuICAgICovXG4gICAgaW52ZXJ0KCkge1xuICAgICAgICBsZXQgaW52ZXJzZSA9IG5ldyBNYXBwaW5nO1xuICAgICAgICBpbnZlcnNlLmFwcGVuZE1hcHBpbmdJbnZlcnRlZCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIGludmVyc2U7XG4gICAgfVxuICAgIC8qKlxuICAgIE1hcCBhIHBvc2l0aW9uIHRocm91Z2ggdGhpcyBtYXBwaW5nLlxuICAgICovXG4gICAgbWFwKHBvcywgYXNzb2MgPSAxKSB7XG4gICAgICAgIGlmICh0aGlzLm1pcnJvcilcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9tYXAocG9zLCBhc3NvYywgdHJ1ZSk7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLmZyb207IGkgPCB0aGlzLnRvOyBpKyspXG4gICAgICAgICAgICBwb3MgPSB0aGlzLl9tYXBzW2ldLm1hcChwb3MsIGFzc29jKTtcbiAgICAgICAgcmV0dXJuIHBvcztcbiAgICB9XG4gICAgLyoqXG4gICAgTWFwIGEgcG9zaXRpb24gdGhyb3VnaCB0aGlzIG1hcHBpbmcsIHJldHVybmluZyBhIG1hcHBpbmdcbiAgICByZXN1bHQuXG4gICAgKi9cbiAgICBtYXBSZXN1bHQocG9zLCBhc3NvYyA9IDEpIHsgcmV0dXJuIHRoaXMuX21hcChwb3MsIGFzc29jLCBmYWxzZSk7IH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIF9tYXAocG9zLCBhc3NvYywgc2ltcGxlKSB7XG4gICAgICAgIGxldCBkZWxJbmZvID0gMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuZnJvbTsgaSA8IHRoaXMudG87IGkrKykge1xuICAgICAgICAgICAgbGV0IG1hcCA9IHRoaXMuX21hcHNbaV0sIHJlc3VsdCA9IG1hcC5tYXBSZXN1bHQocG9zLCBhc3NvYyk7XG4gICAgICAgICAgICBpZiAocmVzdWx0LnJlY292ZXIgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGxldCBjb3JyID0gdGhpcy5nZXRNaXJyb3IoaSk7XG4gICAgICAgICAgICAgICAgaWYgKGNvcnIgIT0gbnVsbCAmJiBjb3JyID4gaSAmJiBjb3JyIDwgdGhpcy50bykge1xuICAgICAgICAgICAgICAgICAgICBpID0gY29ycjtcbiAgICAgICAgICAgICAgICAgICAgcG9zID0gdGhpcy5fbWFwc1tjb3JyXS5yZWNvdmVyKHJlc3VsdC5yZWNvdmVyKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsSW5mbyB8PSByZXN1bHQuZGVsSW5mbztcbiAgICAgICAgICAgIHBvcyA9IHJlc3VsdC5wb3M7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNpbXBsZSA/IHBvcyA6IG5ldyBNYXBSZXN1bHQocG9zLCBkZWxJbmZvLCBudWxsKTtcbiAgICB9XG59XG5cbmNvbnN0IHN0ZXBzQnlJRCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4vKipcbkEgc3RlcCBvYmplY3QgcmVwcmVzZW50cyBhbiBhdG9taWMgY2hhbmdlLiBJdCBnZW5lcmFsbHkgYXBwbGllc1xub25seSB0byB0aGUgZG9jdW1lbnQgaXQgd2FzIGNyZWF0ZWQgZm9yLCBzaW5jZSB0aGUgcG9zaXRpb25zXG5zdG9yZWQgaW4gaXQgd2lsbCBvbmx5IG1ha2Ugc2Vuc2UgZm9yIHRoYXQgZG9jdW1lbnQuXG5cbk5ldyBzdGVwcyBhcmUgZGVmaW5lZCBieSBjcmVhdGluZyBjbGFzc2VzIHRoYXQgZXh0ZW5kIGBTdGVwYCxcbm92ZXJyaWRpbmcgdGhlIGBhcHBseWAsIGBpbnZlcnRgLCBgbWFwYCwgYGdldE1hcGAgYW5kIGBmcm9tSlNPTmBcbm1ldGhvZHMsIGFuZCByZWdpc3RlcmluZyB5b3VyIGNsYXNzIHdpdGggYSB1bmlxdWVcbkpTT04tc2VyaWFsaXphdGlvbiBpZGVudGlmaWVyIHVzaW5nXG5bYFN0ZXAuanNvbklEYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5TdGVwXmpzb25JRCkuXG4qL1xuY2xhc3MgU3RlcCB7XG4gICAgLyoqXG4gICAgR2V0IHRoZSBzdGVwIG1hcCB0aGF0IHJlcHJlc2VudHMgdGhlIGNoYW5nZXMgbWFkZSBieSB0aGlzIHN0ZXAsXG4gICAgYW5kIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHRyYW5zZm9ybSBiZXR3ZWVuIHBvc2l0aW9ucyBpbiB0aGUgb2xkXG4gICAgYW5kIHRoZSBuZXcgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBnZXRNYXAoKSB7IHJldHVybiBTdGVwTWFwLmVtcHR5OyB9XG4gICAgLyoqXG4gICAgVHJ5IHRvIG1lcmdlIHRoaXMgc3RlcCB3aXRoIGFub3RoZXIgb25lLCB0byBiZSBhcHBsaWVkIGRpcmVjdGx5XG4gICAgYWZ0ZXIgaXQuIFJldHVybnMgdGhlIG1lcmdlZCBzdGVwIHdoZW4gcG9zc2libGUsIG51bGwgaWYgdGhlXG4gICAgc3RlcHMgY2FuJ3QgYmUgbWVyZ2VkLlxuICAgICovXG4gICAgbWVyZ2Uob3RoZXIpIHsgcmV0dXJuIG51bGw7IH1cbiAgICAvKipcbiAgICBEZXNlcmlhbGl6ZSBhIHN0ZXAgZnJvbSBpdHMgSlNPTiByZXByZXNlbnRhdGlvbi4gV2lsbCBjYWxsXG4gICAgdGhyb3VnaCB0byB0aGUgc3RlcCBjbGFzcycgb3duIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgbWV0aG9kLlxuICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKHNjaGVtYSwganNvbikge1xuICAgICAgICBpZiAoIWpzb24gfHwgIWpzb24uc3RlcFR5cGUpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIFN0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIGxldCB0eXBlID0gc3RlcHNCeUlEW2pzb24uc3RlcFR5cGVdO1xuICAgICAgICBpZiAoIXR5cGUpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgTm8gc3RlcCB0eXBlICR7anNvbi5zdGVwVHlwZX0gZGVmaW5lZGApO1xuICAgICAgICByZXR1cm4gdHlwZS5mcm9tSlNPTihzY2hlbWEsIGpzb24pO1xuICAgIH1cbiAgICAvKipcbiAgICBUbyBiZSBhYmxlIHRvIHNlcmlhbGl6ZSBzdGVwcyB0byBKU09OLCBlYWNoIHN0ZXAgbmVlZHMgYSBzdHJpbmdcbiAgICBJRCB0byBhdHRhY2ggdG8gaXRzIEpTT04gcmVwcmVzZW50YXRpb24uIFVzZSB0aGlzIG1ldGhvZCB0b1xuICAgIHJlZ2lzdGVyIGFuIElEIGZvciB5b3VyIHN0ZXAgY2xhc3Nlcy4gVHJ5IHRvIHBpY2sgc29tZXRoaW5nXG4gICAgdGhhdCdzIHVubGlrZWx5IHRvIGNsYXNoIHdpdGggc3RlcHMgZnJvbSBvdGhlciBtb2R1bGVzLlxuICAgICovXG4gICAgc3RhdGljIGpzb25JRChpZCwgc3RlcENsYXNzKSB7XG4gICAgICAgIGlmIChpZCBpbiBzdGVwc0J5SUQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkR1cGxpY2F0ZSB1c2Ugb2Ygc3RlcCBKU09OIElEIFwiICsgaWQpO1xuICAgICAgICBzdGVwc0J5SURbaWRdID0gc3RlcENsYXNzO1xuICAgICAgICBzdGVwQ2xhc3MucHJvdG90eXBlLmpzb25JRCA9IGlkO1xuICAgICAgICByZXR1cm4gc3RlcENsYXNzO1xuICAgIH1cbn1cbi8qKlxuVGhlIHJlc3VsdCBvZiBbYXBwbHlpbmddKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0uU3RlcC5hcHBseSkgYSBzdGVwLiBDb250YWlucyBlaXRoZXIgYVxubmV3IGRvY3VtZW50IG9yIGEgZmFpbHVyZSB2YWx1ZS5cbiovXG5jbGFzcyBTdGVwUmVzdWx0IHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSB0cmFuc2Zvcm1lZCBkb2N1bWVudCwgaWYgc3VjY2Vzc2Z1bC5cbiAgICAqL1xuICAgIGRvYywgXG4gICAgLyoqXG4gICAgVGhlIGZhaWx1cmUgbWVzc2FnZSwgaWYgdW5zdWNjZXNzZnVsLlxuICAgICovXG4gICAgZmFpbGVkKSB7XG4gICAgICAgIHRoaXMuZG9jID0gZG9jO1xuICAgICAgICB0aGlzLmZhaWxlZCA9IGZhaWxlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgc3VjY2Vzc2Z1bCBzdGVwIHJlc3VsdC5cbiAgICAqL1xuICAgIHN0YXRpYyBvayhkb2MpIHsgcmV0dXJuIG5ldyBTdGVwUmVzdWx0KGRvYywgbnVsbCk7IH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBmYWlsZWQgc3RlcCByZXN1bHQuXG4gICAgKi9cbiAgICBzdGF0aWMgZmFpbChtZXNzYWdlKSB7IHJldHVybiBuZXcgU3RlcFJlc3VsdChudWxsLCBtZXNzYWdlKTsgfVxuICAgIC8qKlxuICAgIENhbGwgW2BOb2RlLnJlcGxhY2VgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZS5yZXBsYWNlKSB3aXRoIHRoZSBnaXZlblxuICAgIGFyZ3VtZW50cy4gQ3JlYXRlIGEgc3VjY2Vzc2Z1bCByZXN1bHQgaWYgaXQgc3VjY2VlZHMsIGFuZCBhXG4gICAgZmFpbGVkIG9uZSBpZiBpdCB0aHJvd3MgYSBgUmVwbGFjZUVycm9yYC5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tUmVwbGFjZShkb2MsIGZyb20sIHRvLCBzbGljZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQub2soZG9jLnJlcGxhY2UoZnJvbSwgdG8sIHNsaWNlKSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgUmVwbGFjZUVycm9yKVxuICAgICAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZhaWwoZS5tZXNzYWdlKTtcbiAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIG1hcEZyYWdtZW50KGZyYWdtZW50LCBmLCBwYXJlbnQpIHtcbiAgICBsZXQgbWFwcGVkID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmcmFnbWVudC5jaGlsZENvdW50OyBpKyspIHtcbiAgICAgICAgbGV0IGNoaWxkID0gZnJhZ21lbnQuY2hpbGQoaSk7XG4gICAgICAgIGlmIChjaGlsZC5jb250ZW50LnNpemUpXG4gICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmNvcHkobWFwRnJhZ21lbnQoY2hpbGQuY29udGVudCwgZiwgY2hpbGQpKTtcbiAgICAgICAgaWYgKGNoaWxkLmlzSW5saW5lKVxuICAgICAgICAgICAgY2hpbGQgPSBmKGNoaWxkLCBwYXJlbnQsIGkpO1xuICAgICAgICBtYXBwZWQucHVzaChjaGlsZCk7XG4gICAgfVxuICAgIHJldHVybiBGcmFnbWVudC5mcm9tQXJyYXkobWFwcGVkKTtcbn1cbi8qKlxuQWRkIGEgbWFyayB0byBhbGwgaW5saW5lIGNvbnRlbnQgYmV0d2VlbiB0d28gcG9zaXRpb25zLlxuKi9cbmNsYXNzIEFkZE1hcmtTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbWFyayBzdGVwLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHN0YXJ0IG9mIHRoZSBtYXJrZWQgcmFuZ2UuXG4gICAgKi9cbiAgICBmcm9tLCBcbiAgICAvKipcbiAgICBUaGUgZW5kIG9mIHRoZSBtYXJrZWQgcmFuZ2UuXG4gICAgKi9cbiAgICB0bywgXG4gICAgLyoqXG4gICAgVGhlIG1hcmsgdG8gYWRkLlxuICAgICovXG4gICAgbWFyaykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmZyb20gPSBmcm9tO1xuICAgICAgICB0aGlzLnRvID0gdG87XG4gICAgICAgIHRoaXMubWFyayA9IG1hcms7XG4gICAgfVxuICAgIGFwcGx5KGRvYykge1xuICAgICAgICBsZXQgb2xkU2xpY2UgPSBkb2Muc2xpY2UodGhpcy5mcm9tLCB0aGlzLnRvKSwgJGZyb20gPSBkb2MucmVzb2x2ZSh0aGlzLmZyb20pO1xuICAgICAgICBsZXQgcGFyZW50ID0gJGZyb20ubm9kZSgkZnJvbS5zaGFyZWREZXB0aCh0aGlzLnRvKSk7XG4gICAgICAgIGxldCBzbGljZSA9IG5ldyBTbGljZShtYXBGcmFnbWVudChvbGRTbGljZS5jb250ZW50LCAobm9kZSwgcGFyZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoIW5vZGUuaXNBdG9tIHx8ICFwYXJlbnQudHlwZS5hbGxvd3NNYXJrVHlwZSh0aGlzLm1hcmsudHlwZSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5tYXJrKHRoaXMubWFyay5hZGRUb1NldChub2RlLm1hcmtzKSk7XG4gICAgICAgIH0sIHBhcmVudCksIG9sZFNsaWNlLm9wZW5TdGFydCwgb2xkU2xpY2Uub3BlbkVuZCk7XG4gICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZyb21SZXBsYWNlKGRvYywgdGhpcy5mcm9tLCB0aGlzLnRvLCBzbGljZSk7XG4gICAgfVxuICAgIGludmVydCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZW1vdmVNYXJrU3RlcCh0aGlzLmZyb20sIHRoaXMudG8sIHRoaXMubWFyayk7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nKSB7XG4gICAgICAgIGxldCBmcm9tID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy5mcm9tLCAxKSwgdG8gPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLnRvLCAtMSk7XG4gICAgICAgIGlmIChmcm9tLmRlbGV0ZWQgJiYgdG8uZGVsZXRlZCB8fCBmcm9tLnBvcyA+PSB0by5wb3MpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgcmV0dXJuIG5ldyBBZGRNYXJrU3RlcChmcm9tLnBvcywgdG8ucG9zLCB0aGlzLm1hcmspO1xuICAgIH1cbiAgICBtZXJnZShvdGhlcikge1xuICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBBZGRNYXJrU3RlcCAmJlxuICAgICAgICAgICAgb3RoZXIubWFyay5lcSh0aGlzLm1hcmspICYmXG4gICAgICAgICAgICB0aGlzLmZyb20gPD0gb3RoZXIudG8gJiYgdGhpcy50byA+PSBvdGhlci5mcm9tKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBBZGRNYXJrU3RlcChNYXRoLm1pbih0aGlzLmZyb20sIG90aGVyLmZyb20pLCBNYXRoLm1heCh0aGlzLnRvLCBvdGhlci50byksIHRoaXMubWFyayk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB7IHN0ZXBUeXBlOiBcImFkZE1hcmtcIiwgbWFyazogdGhpcy5tYXJrLnRvSlNPTigpLFxuICAgICAgICAgICAgZnJvbTogdGhpcy5mcm9tLCB0bzogdGhpcy50byB9O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBqc29uLmZyb20gIT0gXCJudW1iZXJcIiB8fCB0eXBlb2YganNvbi50byAhPSBcIm51bWJlclwiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBBZGRNYXJrU3RlcC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBBZGRNYXJrU3RlcChqc29uLmZyb20sIGpzb24udG8sIHNjaGVtYS5tYXJrRnJvbUpTT04oanNvbi5tYXJrKSk7XG4gICAgfVxufVxuU3RlcC5qc29uSUQoXCJhZGRNYXJrXCIsIEFkZE1hcmtTdGVwKTtcbi8qKlxuUmVtb3ZlIGEgbWFyayBmcm9tIGFsbCBpbmxpbmUgY29udGVudCBiZXR3ZWVuIHR3byBwb3NpdGlvbnMuXG4qL1xuY2xhc3MgUmVtb3ZlTWFya1N0ZXAgZXh0ZW5kcyBTdGVwIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBtYXJrLXJlbW92aW5nIHN0ZXAuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgc3RhcnQgb2YgdGhlIHVubWFya2VkIHJhbmdlLlxuICAgICovXG4gICAgZnJvbSwgXG4gICAgLyoqXG4gICAgVGhlIGVuZCBvZiB0aGUgdW5tYXJrZWQgcmFuZ2UuXG4gICAgKi9cbiAgICB0bywgXG4gICAgLyoqXG4gICAgVGhlIG1hcmsgdG8gcmVtb3ZlLlxuICAgICovXG4gICAgbWFyaykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmZyb20gPSBmcm9tO1xuICAgICAgICB0aGlzLnRvID0gdG87XG4gICAgICAgIHRoaXMubWFyayA9IG1hcms7XG4gICAgfVxuICAgIGFwcGx5KGRvYykge1xuICAgICAgICBsZXQgb2xkU2xpY2UgPSBkb2Muc2xpY2UodGhpcy5mcm9tLCB0aGlzLnRvKTtcbiAgICAgICAgbGV0IHNsaWNlID0gbmV3IFNsaWNlKG1hcEZyYWdtZW50KG9sZFNsaWNlLmNvbnRlbnQsIG5vZGUgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIG5vZGUubWFyayh0aGlzLm1hcmsucmVtb3ZlRnJvbVNldChub2RlLm1hcmtzKSk7XG4gICAgICAgIH0sIGRvYyksIG9sZFNsaWNlLm9wZW5TdGFydCwgb2xkU2xpY2Uub3BlbkVuZCk7XG4gICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZyb21SZXBsYWNlKGRvYywgdGhpcy5mcm9tLCB0aGlzLnRvLCBzbGljZSk7XG4gICAgfVxuICAgIGludmVydCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBZGRNYXJrU3RlcCh0aGlzLmZyb20sIHRoaXMudG8sIHRoaXMubWFyayk7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nKSB7XG4gICAgICAgIGxldCBmcm9tID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy5mcm9tLCAxKSwgdG8gPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLnRvLCAtMSk7XG4gICAgICAgIGlmIChmcm9tLmRlbGV0ZWQgJiYgdG8uZGVsZXRlZCB8fCBmcm9tLnBvcyA+PSB0by5wb3MpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgcmV0dXJuIG5ldyBSZW1vdmVNYXJrU3RlcChmcm9tLnBvcywgdG8ucG9zLCB0aGlzLm1hcmspO1xuICAgIH1cbiAgICBtZXJnZShvdGhlcikge1xuICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBSZW1vdmVNYXJrU3RlcCAmJlxuICAgICAgICAgICAgb3RoZXIubWFyay5lcSh0aGlzLm1hcmspICYmXG4gICAgICAgICAgICB0aGlzLmZyb20gPD0gb3RoZXIudG8gJiYgdGhpcy50byA+PSBvdGhlci5mcm9tKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZW1vdmVNYXJrU3RlcChNYXRoLm1pbih0aGlzLmZyb20sIG90aGVyLmZyb20pLCBNYXRoLm1heCh0aGlzLnRvLCBvdGhlci50byksIHRoaXMubWFyayk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB7IHN0ZXBUeXBlOiBcInJlbW92ZU1hcmtcIiwgbWFyazogdGhpcy5tYXJrLnRvSlNPTigpLFxuICAgICAgICAgICAgZnJvbTogdGhpcy5mcm9tLCB0bzogdGhpcy50byB9O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBqc29uLmZyb20gIT0gXCJudW1iZXJcIiB8fCB0eXBlb2YganNvbi50byAhPSBcIm51bWJlclwiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBSZW1vdmVNYXJrU3RlcC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBSZW1vdmVNYXJrU3RlcChqc29uLmZyb20sIGpzb24udG8sIHNjaGVtYS5tYXJrRnJvbUpTT04oanNvbi5tYXJrKSk7XG4gICAgfVxufVxuU3RlcC5qc29uSUQoXCJyZW1vdmVNYXJrXCIsIFJlbW92ZU1hcmtTdGVwKTtcbi8qKlxuQWRkIGEgbWFyayB0byBhIHNwZWNpZmljIG5vZGUuXG4qL1xuY2xhc3MgQWRkTm9kZU1hcmtTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbm9kZSBtYXJrIHN0ZXAuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgcG9zaXRpb24gb2YgdGhlIHRhcmdldCBub2RlLlxuICAgICovXG4gICAgcG9zLCBcbiAgICAvKipcbiAgICBUaGUgbWFyayB0byBhZGQuXG4gICAgKi9cbiAgICBtYXJrKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMucG9zID0gcG9zO1xuICAgICAgICB0aGlzLm1hcmsgPSBtYXJrO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgbGV0IG5vZGUgPSBkb2Mubm9kZUF0KHRoaXMucG9zKTtcbiAgICAgICAgaWYgKCFub2RlKVxuICAgICAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZmFpbChcIk5vIG5vZGUgYXQgbWFyayBzdGVwJ3MgcG9zaXRpb25cIik7XG4gICAgICAgIGxldCB1cGRhdGVkID0gbm9kZS50eXBlLmNyZWF0ZShub2RlLmF0dHJzLCBudWxsLCB0aGlzLm1hcmsuYWRkVG9TZXQobm9kZS5tYXJrcykpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMucG9zLCB0aGlzLnBvcyArIDEsIG5ldyBTbGljZShGcmFnbWVudC5mcm9tKHVwZGF0ZWQpLCAwLCBub2RlLmlzTGVhZiA/IDAgOiAxKSk7XG4gICAgfVxuICAgIGludmVydChkb2MpIHtcbiAgICAgICAgbGV0IG5vZGUgPSBkb2Mubm9kZUF0KHRoaXMucG9zKTtcbiAgICAgICAgaWYgKG5vZGUpIHtcbiAgICAgICAgICAgIGxldCBuZXdTZXQgPSB0aGlzLm1hcmsuYWRkVG9TZXQobm9kZS5tYXJrcyk7XG4gICAgICAgICAgICBpZiAobmV3U2V0Lmxlbmd0aCA9PSBub2RlLm1hcmtzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZS5tYXJrcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub2RlLm1hcmtzW2ldLmlzSW5TZXQobmV3U2V0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQWRkTm9kZU1hcmtTdGVwKHRoaXMucG9zLCBub2RlLm1hcmtzW2ldKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFkZE5vZGVNYXJrU3RlcCh0aGlzLnBvcywgdGhpcy5tYXJrKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFJlbW92ZU5vZGVNYXJrU3RlcCh0aGlzLnBvcywgdGhpcy5tYXJrKTtcbiAgICB9XG4gICAgbWFwKG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IHBvcyA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMucG9zLCAxKTtcbiAgICAgICAgcmV0dXJuIHBvcy5kZWxldGVkQWZ0ZXIgPyBudWxsIDogbmV3IEFkZE5vZGVNYXJrU3RlcChwb3MucG9zLCB0aGlzLm1hcmspO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB7IHN0ZXBUeXBlOiBcImFkZE5vZGVNYXJrXCIsIHBvczogdGhpcy5wb3MsIG1hcms6IHRoaXMubWFyay50b0pTT04oKSB9O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBqc29uLnBvcyAhPSBcIm51bWJlclwiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBBZGROb2RlTWFya1N0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgQWRkTm9kZU1hcmtTdGVwKGpzb24ucG9zLCBzY2hlbWEubWFya0Zyb21KU09OKGpzb24ubWFyaykpO1xuICAgIH1cbn1cblN0ZXAuanNvbklEKFwiYWRkTm9kZU1hcmtcIiwgQWRkTm9kZU1hcmtTdGVwKTtcbi8qKlxuUmVtb3ZlIGEgbWFyayBmcm9tIGEgc3BlY2lmaWMgbm9kZS5cbiovXG5jbGFzcyBSZW1vdmVOb2RlTWFya1N0ZXAgZXh0ZW5kcyBTdGVwIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBtYXJrLXJlbW92aW5nIHN0ZXAuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgcG9zaXRpb24gb2YgdGhlIHRhcmdldCBub2RlLlxuICAgICovXG4gICAgcG9zLCBcbiAgICAvKipcbiAgICBUaGUgbWFyayB0byByZW1vdmUuXG4gICAgKi9cbiAgICBtYXJrKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMucG9zID0gcG9zO1xuICAgICAgICB0aGlzLm1hcmsgPSBtYXJrO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgbGV0IG5vZGUgPSBkb2Mubm9kZUF0KHRoaXMucG9zKTtcbiAgICAgICAgaWYgKCFub2RlKVxuICAgICAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZmFpbChcIk5vIG5vZGUgYXQgbWFyayBzdGVwJ3MgcG9zaXRpb25cIik7XG4gICAgICAgIGxldCB1cGRhdGVkID0gbm9kZS50eXBlLmNyZWF0ZShub2RlLmF0dHJzLCBudWxsLCB0aGlzLm1hcmsucmVtb3ZlRnJvbVNldChub2RlLm1hcmtzKSk7XG4gICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZyb21SZXBsYWNlKGRvYywgdGhpcy5wb3MsIHRoaXMucG9zICsgMSwgbmV3IFNsaWNlKEZyYWdtZW50LmZyb20odXBkYXRlZCksIDAsIG5vZGUuaXNMZWFmID8gMCA6IDEpKTtcbiAgICB9XG4gICAgaW52ZXJ0KGRvYykge1xuICAgICAgICBsZXQgbm9kZSA9IGRvYy5ub2RlQXQodGhpcy5wb3MpO1xuICAgICAgICBpZiAoIW5vZGUgfHwgIXRoaXMubWFyay5pc0luU2V0KG5vZGUubWFya3MpKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIHJldHVybiBuZXcgQWRkTm9kZU1hcmtTdGVwKHRoaXMucG9zLCB0aGlzLm1hcmspO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICBsZXQgcG9zID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy5wb3MsIDEpO1xuICAgICAgICByZXR1cm4gcG9zLmRlbGV0ZWRBZnRlciA/IG51bGwgOiBuZXcgUmVtb3ZlTm9kZU1hcmtTdGVwKHBvcy5wb3MsIHRoaXMubWFyayk7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RlcFR5cGU6IFwicmVtb3ZlTm9kZU1hcmtcIiwgcG9zOiB0aGlzLnBvcywgbWFyazogdGhpcy5tYXJrLnRvSlNPTigpIH07XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKHNjaGVtYSwganNvbikge1xuICAgICAgICBpZiAodHlwZW9mIGpzb24ucG9zICE9IFwibnVtYmVyXCIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIFJlbW92ZU5vZGVNYXJrU3RlcC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBSZW1vdmVOb2RlTWFya1N0ZXAoanNvbi5wb3MsIHNjaGVtYS5tYXJrRnJvbUpTT04oanNvbi5tYXJrKSk7XG4gICAgfVxufVxuU3RlcC5qc29uSUQoXCJyZW1vdmVOb2RlTWFya1wiLCBSZW1vdmVOb2RlTWFya1N0ZXApO1xuXG4vKipcblJlcGxhY2UgYSBwYXJ0IG9mIHRoZSBkb2N1bWVudCB3aXRoIGEgc2xpY2Ugb2YgbmV3IGNvbnRlbnQuXG4qL1xuY2xhc3MgUmVwbGFjZVN0ZXAgZXh0ZW5kcyBTdGVwIHtcbiAgICAvKipcbiAgICBUaGUgZ2l2ZW4gYHNsaWNlYCBzaG91bGQgZml0IHRoZSAnZ2FwJyBiZXR3ZWVuIGBmcm9tYCBhbmRcbiAgICBgdG9gXHUyMDE0dGhlIGRlcHRocyBtdXN0IGxpbmUgdXAsIGFuZCB0aGUgc3Vycm91bmRpbmcgbm9kZXMgbXVzdCBiZVxuICAgIGFibGUgdG8gYmUgam9pbmVkIHdpdGggdGhlIG9wZW4gc2lkZXMgb2YgdGhlIHNsaWNlLiBXaGVuXG4gICAgYHN0cnVjdHVyZWAgaXMgdHJ1ZSwgdGhlIHN0ZXAgd2lsbCBmYWlsIGlmIHRoZSBjb250ZW50IGJldHdlZW5cbiAgICBmcm9tIGFuZCB0byBpcyBub3QganVzdCBhIHNlcXVlbmNlIG9mIGNsb3NpbmcgYW5kIHRoZW4gb3BlbmluZ1xuICAgIHRva2VucyAodGhpcyBpcyB0byBndWFyZCBhZ2FpbnN0IHJlYmFzZWQgcmVwbGFjZSBzdGVwc1xuICAgIG92ZXJ3cml0aW5nIHNvbWV0aGluZyB0aGV5IHdlcmVuJ3Qgc3VwcG9zZWQgdG8pLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSByZXBsYWNlZCByYW5nZS5cbiAgICAqL1xuICAgIGZyb20sIFxuICAgIC8qKlxuICAgIFRoZSBlbmQgcG9zaXRpb24gb2YgdGhlIHJlcGxhY2VkIHJhbmdlLlxuICAgICovXG4gICAgdG8sIFxuICAgIC8qKlxuICAgIFRoZSBzbGljZSB0byBpbnNlcnQuXG4gICAgKi9cbiAgICBzbGljZSwgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdHJ1Y3R1cmUgPSBmYWxzZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmZyb20gPSBmcm9tO1xuICAgICAgICB0aGlzLnRvID0gdG87XG4gICAgICAgIHRoaXMuc2xpY2UgPSBzbGljZTtcbiAgICAgICAgdGhpcy5zdHJ1Y3R1cmUgPSBzdHJ1Y3R1cmU7XG4gICAgfVxuICAgIGFwcGx5KGRvYykge1xuICAgICAgICBpZiAodGhpcy5zdHJ1Y3R1cmUgJiYgY29udGVudEJldHdlZW4oZG9jLCB0aGlzLmZyb20sIHRoaXMudG8pKVxuICAgICAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZmFpbChcIlN0cnVjdHVyZSByZXBsYWNlIHdvdWxkIG92ZXJ3cml0ZSBjb250ZW50XCIpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMuZnJvbSwgdGhpcy50bywgdGhpcy5zbGljZSk7XG4gICAgfVxuICAgIGdldE1hcCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdGVwTWFwKFt0aGlzLmZyb20sIHRoaXMudG8gLSB0aGlzLmZyb20sIHRoaXMuc2xpY2Uuc2l6ZV0pO1xuICAgIH1cbiAgICBpbnZlcnQoZG9jKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVwbGFjZVN0ZXAodGhpcy5mcm9tLCB0aGlzLmZyb20gKyB0aGlzLnNsaWNlLnNpemUsIGRvYy5zbGljZSh0aGlzLmZyb20sIHRoaXMudG8pKTtcbiAgICB9XG4gICAgbWFwKG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IHRvID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy50bywgLTEpO1xuICAgICAgICBsZXQgZnJvbSA9IHRoaXMuZnJvbSA9PSB0aGlzLnRvICYmIFJlcGxhY2VTdGVwLk1BUF9CSUFTIDwgMCA/IHRvIDogbWFwcGluZy5tYXBSZXN1bHQodGhpcy5mcm9tLCAxKTtcbiAgICAgICAgaWYgKGZyb20uZGVsZXRlZEFjcm9zcyAmJiB0by5kZWxldGVkQWNyb3NzKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBuZXcgUmVwbGFjZVN0ZXAoZnJvbS5wb3MsIE1hdGgubWF4KGZyb20ucG9zLCB0by5wb3MpLCB0aGlzLnNsaWNlLCB0aGlzLnN0cnVjdHVyZSk7XG4gICAgfVxuICAgIG1lcmdlKG90aGVyKSB7XG4gICAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgUmVwbGFjZVN0ZXApIHx8IG90aGVyLnN0cnVjdHVyZSB8fCB0aGlzLnN0cnVjdHVyZSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBpZiAodGhpcy5mcm9tICsgdGhpcy5zbGljZS5zaXplID09IG90aGVyLmZyb20gJiYgIXRoaXMuc2xpY2Uub3BlbkVuZCAmJiAhb3RoZXIuc2xpY2Uub3BlblN0YXJ0KSB7XG4gICAgICAgICAgICBsZXQgc2xpY2UgPSB0aGlzLnNsaWNlLnNpemUgKyBvdGhlci5zbGljZS5zaXplID09IDAgPyBTbGljZS5lbXB0eVxuICAgICAgICAgICAgICAgIDogbmV3IFNsaWNlKHRoaXMuc2xpY2UuY29udGVudC5hcHBlbmQob3RoZXIuc2xpY2UuY29udGVudCksIHRoaXMuc2xpY2Uub3BlblN0YXJ0LCBvdGhlci5zbGljZS5vcGVuRW5kKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVwbGFjZVN0ZXAodGhpcy5mcm9tLCB0aGlzLnRvICsgKG90aGVyLnRvIC0gb3RoZXIuZnJvbSksIHNsaWNlLCB0aGlzLnN0cnVjdHVyZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAob3RoZXIudG8gPT0gdGhpcy5mcm9tICYmICF0aGlzLnNsaWNlLm9wZW5TdGFydCAmJiAhb3RoZXIuc2xpY2Uub3BlbkVuZCkge1xuICAgICAgICAgICAgbGV0IHNsaWNlID0gdGhpcy5zbGljZS5zaXplICsgb3RoZXIuc2xpY2Uuc2l6ZSA9PSAwID8gU2xpY2UuZW1wdHlcbiAgICAgICAgICAgICAgICA6IG5ldyBTbGljZShvdGhlci5zbGljZS5jb250ZW50LmFwcGVuZCh0aGlzLnNsaWNlLmNvbnRlbnQpLCBvdGhlci5zbGljZS5vcGVuU3RhcnQsIHRoaXMuc2xpY2Uub3BlbkVuZCk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VTdGVwKG90aGVyLmZyb20sIHRoaXMudG8sIHNsaWNlLCB0aGlzLnN0cnVjdHVyZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGxldCBqc29uID0geyBzdGVwVHlwZTogXCJyZXBsYWNlXCIsIGZyb206IHRoaXMuZnJvbSwgdG86IHRoaXMudG8gfTtcbiAgICAgICAgaWYgKHRoaXMuc2xpY2Uuc2l6ZSlcbiAgICAgICAgICAgIGpzb24uc2xpY2UgPSB0aGlzLnNsaWNlLnRvSlNPTigpO1xuICAgICAgICBpZiAodGhpcy5zdHJ1Y3R1cmUpXG4gICAgICAgICAgICBqc29uLnN0cnVjdHVyZSA9IHRydWU7XG4gICAgICAgIHJldHVybiBqc29uO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBqc29uLmZyb20gIT0gXCJudW1iZXJcIiB8fCB0eXBlb2YganNvbi50byAhPSBcIm51bWJlclwiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBSZXBsYWNlU3RlcC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBsYWNlU3RlcChqc29uLmZyb20sIGpzb24udG8sIFNsaWNlLmZyb21KU09OKHNjaGVtYSwganNvbi5zbGljZSksICEhanNvbi5zdHJ1Y3R1cmUpO1xuICAgIH1cbn1cbi8qKlxuQnkgZGVmYXVsdCwgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCBhbiBpbnNlcnRpbmcgc3RlcFxubWFwcGVkIG92ZXIgYW4gaW5zZXJ0aW9uIGF0IHRoYXQgc2FtZSBwb3NpdGlvbiBmaWxsIG1vdmUgYWZ0ZXJcbnRoZSBpbnNlcnRlZCBjb250ZW50LiBJbiBhIGNvbGxhYm9yYXRpdmUgZWRpdGluZyBzaXR1YXRpb24sIHRoYXRcbmNhbiBtYWtlIHJlZG9uZSBpbnNlcnRpb25zIGFwcGVhciBpbiB1bmV4cGVjdGVkIHBsYWNlcy4gWW91IGNhblxuc2V0IHRoaXMgdG8gLTEgdG8gbWFrZSBzdWNoIG1hcHBpbmcga2VlcCB0aGUgc3RlcCBiZWZvcmUgdGhlXG5pbnNlcnRpb24gaW5zdGVhZC5cbiovXG5SZXBsYWNlU3RlcC5NQVBfQklBUyA9IDE7XG5TdGVwLmpzb25JRChcInJlcGxhY2VcIiwgUmVwbGFjZVN0ZXApO1xuLyoqXG5SZXBsYWNlIGEgcGFydCBvZiB0aGUgZG9jdW1lbnQgd2l0aCBhIHNsaWNlIG9mIGNvbnRlbnQsIGJ1dFxucHJlc2VydmUgYSByYW5nZSBvZiB0aGUgcmVwbGFjZWQgY29udGVudCBieSBtb3ZpbmcgaXQgaW50byB0aGVcbnNsaWNlLlxuKi9cbmNsYXNzIFJlcGxhY2VBcm91bmRTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgcmVwbGFjZS1hcm91bmQgc3RlcCB3aXRoIHRoZSBnaXZlbiByYW5nZSBhbmQgZ2FwLlxuICAgIGBpbnNlcnRgIHNob3VsZCBiZSB0aGUgcG9pbnQgaW4gdGhlIHNsaWNlIGludG8gd2hpY2ggdGhlIGNvbnRlbnRcbiAgICBvZiB0aGUgZ2FwIHNob3VsZCBiZSBtb3ZlZC4gYHN0cnVjdHVyZWAgaGFzIHRoZSBzYW1lIG1lYW5pbmcgYXNcbiAgICBpdCBoYXMgaW4gdGhlIFtgUmVwbGFjZVN0ZXBgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdHJhbnNmb3JtLlJlcGxhY2VTdGVwKSBjbGFzcy5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVwbGFjZWQgcmFuZ2UuXG4gICAgKi9cbiAgICBmcm9tLCBcbiAgICAvKipcbiAgICBUaGUgZW5kIHBvc2l0aW9uIG9mIHRoZSByZXBsYWNlZCByYW5nZS5cbiAgICAqL1xuICAgIHRvLCBcbiAgICAvKipcbiAgICBUaGUgc3RhcnQgb2YgcHJlc2VydmVkIHJhbmdlLlxuICAgICovXG4gICAgZ2FwRnJvbSwgXG4gICAgLyoqXG4gICAgVGhlIGVuZCBvZiBwcmVzZXJ2ZWQgcmFuZ2UuXG4gICAgKi9cbiAgICBnYXBUbywgXG4gICAgLyoqXG4gICAgVGhlIHNsaWNlIHRvIGluc2VydC5cbiAgICAqL1xuICAgIHNsaWNlLCBcbiAgICAvKipcbiAgICBUaGUgcG9zaXRpb24gaW4gdGhlIHNsaWNlIHdoZXJlIHRoZSBwcmVzZXJ2ZWQgcmFuZ2Ugc2hvdWxkIGJlXG4gICAgaW5zZXJ0ZWQuXG4gICAgKi9cbiAgICBpbnNlcnQsIFxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RydWN0dXJlID0gZmFsc2UpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICAgICAgdGhpcy50byA9IHRvO1xuICAgICAgICB0aGlzLmdhcEZyb20gPSBnYXBGcm9tO1xuICAgICAgICB0aGlzLmdhcFRvID0gZ2FwVG87XG4gICAgICAgIHRoaXMuc2xpY2UgPSBzbGljZTtcbiAgICAgICAgdGhpcy5pbnNlcnQgPSBpbnNlcnQ7XG4gICAgICAgIHRoaXMuc3RydWN0dXJlID0gc3RydWN0dXJlO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RydWN0dXJlICYmIChjb250ZW50QmV0d2Vlbihkb2MsIHRoaXMuZnJvbSwgdGhpcy5nYXBGcm9tKSB8fFxuICAgICAgICAgICAgY29udGVudEJldHdlZW4oZG9jLCB0aGlzLmdhcFRvLCB0aGlzLnRvKSkpXG4gICAgICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mYWlsKFwiU3RydWN0dXJlIGdhcC1yZXBsYWNlIHdvdWxkIG92ZXJ3cml0ZSBjb250ZW50XCIpO1xuICAgICAgICBsZXQgZ2FwID0gZG9jLnNsaWNlKHRoaXMuZ2FwRnJvbSwgdGhpcy5nYXBUbyk7XG4gICAgICAgIGlmIChnYXAub3BlblN0YXJ0IHx8IGdhcC5vcGVuRW5kKVxuICAgICAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZmFpbChcIkdhcCBpcyBub3QgYSBmbGF0IHJhbmdlXCIpO1xuICAgICAgICBsZXQgaW5zZXJ0ZWQgPSB0aGlzLnNsaWNlLmluc2VydEF0KHRoaXMuaW5zZXJ0LCBnYXAuY29udGVudCk7XG4gICAgICAgIGlmICghaW5zZXJ0ZWQpXG4gICAgICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mYWlsKFwiQ29udGVudCBkb2VzIG5vdCBmaXQgaW4gZ2FwXCIpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMuZnJvbSwgdGhpcy50bywgaW5zZXJ0ZWQpO1xuICAgIH1cbiAgICBnZXRNYXAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RlcE1hcChbdGhpcy5mcm9tLCB0aGlzLmdhcEZyb20gLSB0aGlzLmZyb20sIHRoaXMuaW5zZXJ0LFxuICAgICAgICAgICAgdGhpcy5nYXBUbywgdGhpcy50byAtIHRoaXMuZ2FwVG8sIHRoaXMuc2xpY2Uuc2l6ZSAtIHRoaXMuaW5zZXJ0XSk7XG4gICAgfVxuICAgIGludmVydChkb2MpIHtcbiAgICAgICAgbGV0IGdhcCA9IHRoaXMuZ2FwVG8gLSB0aGlzLmdhcEZyb207XG4gICAgICAgIHJldHVybiBuZXcgUmVwbGFjZUFyb3VuZFN0ZXAodGhpcy5mcm9tLCB0aGlzLmZyb20gKyB0aGlzLnNsaWNlLnNpemUgKyBnYXAsIHRoaXMuZnJvbSArIHRoaXMuaW5zZXJ0LCB0aGlzLmZyb20gKyB0aGlzLmluc2VydCArIGdhcCwgZG9jLnNsaWNlKHRoaXMuZnJvbSwgdGhpcy50bykucmVtb3ZlQmV0d2Vlbih0aGlzLmdhcEZyb20gLSB0aGlzLmZyb20sIHRoaXMuZ2FwVG8gLSB0aGlzLmZyb20pLCB0aGlzLmdhcEZyb20gLSB0aGlzLmZyb20sIHRoaXMuc3RydWN0dXJlKTtcbiAgICB9XG4gICAgbWFwKG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IGZyb20gPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLmZyb20sIDEpLCB0byA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMudG8sIC0xKTtcbiAgICAgICAgbGV0IGdhcEZyb20gPSB0aGlzLmZyb20gPT0gdGhpcy5nYXBGcm9tID8gZnJvbS5wb3MgOiBtYXBwaW5nLm1hcCh0aGlzLmdhcEZyb20sIC0xKTtcbiAgICAgICAgbGV0IGdhcFRvID0gdGhpcy50byA9PSB0aGlzLmdhcFRvID8gdG8ucG9zIDogbWFwcGluZy5tYXAodGhpcy5nYXBUbywgMSk7XG4gICAgICAgIGlmICgoZnJvbS5kZWxldGVkQWNyb3NzICYmIHRvLmRlbGV0ZWRBY3Jvc3MpIHx8IGdhcEZyb20gPCBmcm9tLnBvcyB8fCBnYXBUbyA+IHRvLnBvcylcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VBcm91bmRTdGVwKGZyb20ucG9zLCB0by5wb3MsIGdhcEZyb20sIGdhcFRvLCB0aGlzLnNsaWNlLCB0aGlzLmluc2VydCwgdGhpcy5zdHJ1Y3R1cmUpO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGxldCBqc29uID0geyBzdGVwVHlwZTogXCJyZXBsYWNlQXJvdW5kXCIsIGZyb206IHRoaXMuZnJvbSwgdG86IHRoaXMudG8sXG4gICAgICAgICAgICBnYXBGcm9tOiB0aGlzLmdhcEZyb20sIGdhcFRvOiB0aGlzLmdhcFRvLCBpbnNlcnQ6IHRoaXMuaW5zZXJ0IH07XG4gICAgICAgIGlmICh0aGlzLnNsaWNlLnNpemUpXG4gICAgICAgICAgICBqc29uLnNsaWNlID0gdGhpcy5zbGljZS50b0pTT04oKTtcbiAgICAgICAgaWYgKHRoaXMuc3RydWN0dXJlKVxuICAgICAgICAgICAganNvbi5zdHJ1Y3R1cmUgPSB0cnVlO1xuICAgICAgICByZXR1cm4ganNvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5mcm9tICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24udG8gIT0gXCJudW1iZXJcIiB8fFxuICAgICAgICAgICAgdHlwZW9mIGpzb24uZ2FwRnJvbSAhPSBcIm51bWJlclwiIHx8IHR5cGVvZiBqc29uLmdhcFRvICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24uaW5zZXJ0ICE9IFwibnVtYmVyXCIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIFJlcGxhY2VBcm91bmRTdGVwLmZyb21KU09OXCIpO1xuICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VBcm91bmRTdGVwKGpzb24uZnJvbSwganNvbi50bywganNvbi5nYXBGcm9tLCBqc29uLmdhcFRvLCBTbGljZS5mcm9tSlNPTihzY2hlbWEsIGpzb24uc2xpY2UpLCBqc29uLmluc2VydCwgISFqc29uLnN0cnVjdHVyZSk7XG4gICAgfVxufVxuU3RlcC5qc29uSUQoXCJyZXBsYWNlQXJvdW5kXCIsIFJlcGxhY2VBcm91bmRTdGVwKTtcbmZ1bmN0aW9uIGNvbnRlbnRCZXR3ZWVuKGRvYywgZnJvbSwgdG8pIHtcbiAgICBsZXQgJGZyb20gPSBkb2MucmVzb2x2ZShmcm9tKSwgZGlzdCA9IHRvIC0gZnJvbSwgZGVwdGggPSAkZnJvbS5kZXB0aDtcbiAgICB3aGlsZSAoZGlzdCA+IDAgJiYgZGVwdGggPiAwICYmICRmcm9tLmluZGV4QWZ0ZXIoZGVwdGgpID09ICRmcm9tLm5vZGUoZGVwdGgpLmNoaWxkQ291bnQpIHtcbiAgICAgICAgZGVwdGgtLTtcbiAgICAgICAgZGlzdC0tO1xuICAgIH1cbiAgICBpZiAoZGlzdCA+IDApIHtcbiAgICAgICAgbGV0IG5leHQgPSAkZnJvbS5ub2RlKGRlcHRoKS5tYXliZUNoaWxkKCRmcm9tLmluZGV4QWZ0ZXIoZGVwdGgpKTtcbiAgICAgICAgd2hpbGUgKGRpc3QgPiAwKSB7XG4gICAgICAgICAgICBpZiAoIW5leHQgfHwgbmV4dC5pc0xlYWYpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICBuZXh0ID0gbmV4dC5maXJzdENoaWxkO1xuICAgICAgICAgICAgZGlzdC0tO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gYWRkTWFyayh0ciwgZnJvbSwgdG8sIG1hcmspIHtcbiAgICBsZXQgcmVtb3ZlZCA9IFtdLCBhZGRlZCA9IFtdO1xuICAgIGxldCByZW1vdmluZywgYWRkaW5nO1xuICAgIHRyLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MsIHBhcmVudCkgPT4ge1xuICAgICAgICBpZiAoIW5vZGUuaXNJbmxpbmUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGxldCBtYXJrcyA9IG5vZGUubWFya3M7XG4gICAgICAgIGlmICghbWFyay5pc0luU2V0KG1hcmtzKSAmJiBwYXJlbnQudHlwZS5hbGxvd3NNYXJrVHlwZShtYXJrLnR5cGUpKSB7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSBNYXRoLm1heChwb3MsIGZyb20pLCBlbmQgPSBNYXRoLm1pbihwb3MgKyBub2RlLm5vZGVTaXplLCB0byk7XG4gICAgICAgICAgICBsZXQgbmV3U2V0ID0gbWFyay5hZGRUb1NldChtYXJrcyk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hcmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFtYXJrc1tpXS5pc0luU2V0KG5ld1NldCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92aW5nICYmIHJlbW92aW5nLnRvID09IHN0YXJ0ICYmIHJlbW92aW5nLm1hcmsuZXEobWFya3NbaV0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZpbmcudG8gPSBlbmQ7XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZWQucHVzaChyZW1vdmluZyA9IG5ldyBSZW1vdmVNYXJrU3RlcChzdGFydCwgZW5kLCBtYXJrc1tpXSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhZGRpbmcgJiYgYWRkaW5nLnRvID09IHN0YXJ0KVxuICAgICAgICAgICAgICAgIGFkZGluZy50byA9IGVuZDtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBhZGRlZC5wdXNoKGFkZGluZyA9IG5ldyBBZGRNYXJrU3RlcChzdGFydCwgZW5kLCBtYXJrKSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZW1vdmVkLmZvckVhY2gocyA9PiB0ci5zdGVwKHMpKTtcbiAgICBhZGRlZC5mb3JFYWNoKHMgPT4gdHIuc3RlcChzKSk7XG59XG5mdW5jdGlvbiByZW1vdmVNYXJrKHRyLCBmcm9tLCB0bywgbWFyaykge1xuICAgIGxldCBtYXRjaGVkID0gW10sIHN0ZXAgPSAwO1xuICAgIHRyLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MpID0+IHtcbiAgICAgICAgaWYgKCFub2RlLmlzSW5saW5lKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBzdGVwKys7XG4gICAgICAgIGxldCB0b1JlbW92ZSA9IG51bGw7XG4gICAgICAgIGlmIChtYXJrIGluc3RhbmNlb2YgTWFya1R5cGUpIHtcbiAgICAgICAgICAgIGxldCBzZXQgPSBub2RlLm1hcmtzLCBmb3VuZDtcbiAgICAgICAgICAgIHdoaWxlIChmb3VuZCA9IG1hcmsuaXNJblNldChzZXQpKSB7XG4gICAgICAgICAgICAgICAgKHRvUmVtb3ZlIHx8ICh0b1JlbW92ZSA9IFtdKSkucHVzaChmb3VuZCk7XG4gICAgICAgICAgICAgICAgc2V0ID0gZm91bmQucmVtb3ZlRnJvbVNldChzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG1hcmspIHtcbiAgICAgICAgICAgIGlmIChtYXJrLmlzSW5TZXQobm9kZS5tYXJrcykpXG4gICAgICAgICAgICAgICAgdG9SZW1vdmUgPSBbbWFya107XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0b1JlbW92ZSA9IG5vZGUubWFya3M7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRvUmVtb3ZlICYmIHRvUmVtb3ZlLmxlbmd0aCkge1xuICAgICAgICAgICAgbGV0IGVuZCA9IE1hdGgubWluKHBvcyArIG5vZGUubm9kZVNpemUsIHRvKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdG9SZW1vdmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgc3R5bGUgPSB0b1JlbW92ZVtpXSwgZm91bmQ7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBtYXRjaGVkLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBtID0gbWF0Y2hlZFtqXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG0uc3RlcCA9PSBzdGVwIC0gMSAmJiBzdHlsZS5lcShtYXRjaGVkW2pdLnN0eWxlKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kID0gbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvdW5kLnRvID0gZW5kO1xuICAgICAgICAgICAgICAgICAgICBmb3VuZC5zdGVwID0gc3RlcDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG1hdGNoZWQucHVzaCh7IHN0eWxlLCBmcm9tOiBNYXRoLm1heChwb3MsIGZyb20pLCB0bzogZW5kLCBzdGVwIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuICAgIG1hdGNoZWQuZm9yRWFjaChtID0+IHRyLnN0ZXAobmV3IFJlbW92ZU1hcmtTdGVwKG0uZnJvbSwgbS50bywgbS5zdHlsZSkpKTtcbn1cbmZ1bmN0aW9uIGNsZWFySW5jb21wYXRpYmxlKHRyLCBwb3MsIHBhcmVudFR5cGUsIG1hdGNoID0gcGFyZW50VHlwZS5jb250ZW50TWF0Y2gsIGNsZWFyTmV3bGluZXMgPSB0cnVlKSB7XG4gICAgbGV0IG5vZGUgPSB0ci5kb2Mubm9kZUF0KHBvcyk7XG4gICAgbGV0IHJlcGxTdGVwcyA9IFtdLCBjdXIgPSBwb3MgKyAxO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZS5jaGlsZENvdW50OyBpKyspIHtcbiAgICAgICAgbGV0IGNoaWxkID0gbm9kZS5jaGlsZChpKSwgZW5kID0gY3VyICsgY2hpbGQubm9kZVNpemU7XG4gICAgICAgIGxldCBhbGxvd2VkID0gbWF0Y2gubWF0Y2hUeXBlKGNoaWxkLnR5cGUpO1xuICAgICAgICBpZiAoIWFsbG93ZWQpIHtcbiAgICAgICAgICAgIHJlcGxTdGVwcy5wdXNoKG5ldyBSZXBsYWNlU3RlcChjdXIsIGVuZCwgU2xpY2UuZW1wdHkpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG1hdGNoID0gYWxsb3dlZDtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY2hpbGQubWFya3MubGVuZ3RoOyBqKyspXG4gICAgICAgICAgICAgICAgaWYgKCFwYXJlbnRUeXBlLmFsbG93c01hcmtUeXBlKGNoaWxkLm1hcmtzW2pdLnR5cGUpKVxuICAgICAgICAgICAgICAgICAgICB0ci5zdGVwKG5ldyBSZW1vdmVNYXJrU3RlcChjdXIsIGVuZCwgY2hpbGQubWFya3Nbal0pKTtcbiAgICAgICAgICAgIGlmIChjbGVhck5ld2xpbmVzICYmIGNoaWxkLmlzVGV4dCAmJiBwYXJlbnRUeXBlLndoaXRlc3BhY2UgIT0gXCJwcmVcIikge1xuICAgICAgICAgICAgICAgIGxldCBtLCBuZXdsaW5lID0gL1xccj9cXG58XFxyL2csIHNsaWNlO1xuICAgICAgICAgICAgICAgIHdoaWxlIChtID0gbmV3bGluZS5leGVjKGNoaWxkLnRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2xpY2UpXG4gICAgICAgICAgICAgICAgICAgICAgICBzbGljZSA9IG5ldyBTbGljZShGcmFnbWVudC5mcm9tKHBhcmVudFR5cGUuc2NoZW1hLnRleHQoXCIgXCIsIHBhcmVudFR5cGUuYWxsb3dlZE1hcmtzKGNoaWxkLm1hcmtzKSkpLCAwLCAwKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwbFN0ZXBzLnB1c2gobmV3IFJlcGxhY2VTdGVwKGN1ciArIG0uaW5kZXgsIGN1ciArIG0uaW5kZXggKyBtWzBdLmxlbmd0aCwgc2xpY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY3VyID0gZW5kO1xuICAgIH1cbiAgICBpZiAoIW1hdGNoLnZhbGlkRW5kKSB7XG4gICAgICAgIGxldCBmaWxsID0gbWF0Y2guZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSk7XG4gICAgICAgIHRyLnJlcGxhY2UoY3VyLCBjdXIsIG5ldyBTbGljZShmaWxsLCAwLCAwKSk7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSByZXBsU3RlcHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgIHRyLnN0ZXAocmVwbFN0ZXBzW2ldKTtcbn1cblxuZnVuY3Rpb24gY2FuQ3V0KG5vZGUsIHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gKHN0YXJ0ID09IDAgfHwgbm9kZS5jYW5SZXBsYWNlKHN0YXJ0LCBub2RlLmNoaWxkQ291bnQpKSAmJlxuICAgICAgICAoZW5kID09IG5vZGUuY2hpbGRDb3VudCB8fCBub2RlLmNhblJlcGxhY2UoMCwgZW5kKSk7XG59XG4vKipcblRyeSB0byBmaW5kIGEgdGFyZ2V0IGRlcHRoIHRvIHdoaWNoIHRoZSBjb250ZW50IGluIHRoZSBnaXZlbiByYW5nZVxuY2FuIGJlIGxpZnRlZC4gV2lsbCBub3QgZ28gYWNyb3NzXG5baXNvbGF0aW5nXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuaXNvbGF0aW5nKSBwYXJlbnQgbm9kZXMuXG4qL1xuZnVuY3Rpb24gbGlmdFRhcmdldChyYW5nZSkge1xuICAgIGxldCBwYXJlbnQgPSByYW5nZS5wYXJlbnQ7XG4gICAgbGV0IGNvbnRlbnQgPSBwYXJlbnQuY29udGVudC5jdXRCeUluZGV4KHJhbmdlLnN0YXJ0SW5kZXgsIHJhbmdlLmVuZEluZGV4KTtcbiAgICBmb3IgKGxldCBkZXB0aCA9IHJhbmdlLmRlcHRoLCBjb250ZW50QmVmb3JlID0gMCwgY29udGVudEFmdGVyID0gMDs7IC0tZGVwdGgpIHtcbiAgICAgICAgbGV0IG5vZGUgPSByYW5nZS4kZnJvbS5ub2RlKGRlcHRoKTtcbiAgICAgICAgbGV0IGluZGV4ID0gcmFuZ2UuJGZyb20uaW5kZXgoZGVwdGgpICsgY29udGVudEJlZm9yZSwgZW5kSW5kZXggPSByYW5nZS4kdG8uaW5kZXhBZnRlcihkZXB0aCkgLSBjb250ZW50QWZ0ZXI7XG4gICAgICAgIGlmIChkZXB0aCA8IHJhbmdlLmRlcHRoICYmIG5vZGUuY2FuUmVwbGFjZShpbmRleCwgZW5kSW5kZXgsIGNvbnRlbnQpKVxuICAgICAgICAgICAgcmV0dXJuIGRlcHRoO1xuICAgICAgICBpZiAoZGVwdGggPT0gMCB8fCBub2RlLnR5cGUuc3BlYy5pc29sYXRpbmcgfHwgIWNhbkN1dChub2RlLCBpbmRleCwgZW5kSW5kZXgpKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGlmIChpbmRleClcbiAgICAgICAgICAgIGNvbnRlbnRCZWZvcmUgPSAxO1xuICAgICAgICBpZiAoZW5kSW5kZXggPCBub2RlLmNoaWxkQ291bnQpXG4gICAgICAgICAgICBjb250ZW50QWZ0ZXIgPSAxO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIGxpZnQodHIsIHJhbmdlLCB0YXJnZXQpIHtcbiAgICBsZXQgeyAkZnJvbSwgJHRvLCBkZXB0aCB9ID0gcmFuZ2U7XG4gICAgbGV0IGdhcFN0YXJ0ID0gJGZyb20uYmVmb3JlKGRlcHRoICsgMSksIGdhcEVuZCA9ICR0by5hZnRlcihkZXB0aCArIDEpO1xuICAgIGxldCBzdGFydCA9IGdhcFN0YXJ0LCBlbmQgPSBnYXBFbmQ7XG4gICAgbGV0IGJlZm9yZSA9IEZyYWdtZW50LmVtcHR5LCBvcGVuU3RhcnQgPSAwO1xuICAgIGZvciAobGV0IGQgPSBkZXB0aCwgc3BsaXR0aW5nID0gZmFsc2U7IGQgPiB0YXJnZXQ7IGQtLSlcbiAgICAgICAgaWYgKHNwbGl0dGluZyB8fCAkZnJvbS5pbmRleChkKSA+IDApIHtcbiAgICAgICAgICAgIHNwbGl0dGluZyA9IHRydWU7XG4gICAgICAgICAgICBiZWZvcmUgPSBGcmFnbWVudC5mcm9tKCRmcm9tLm5vZGUoZCkuY29weShiZWZvcmUpKTtcbiAgICAgICAgICAgIG9wZW5TdGFydCsrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc3RhcnQtLTtcbiAgICAgICAgfVxuICAgIGxldCBhZnRlciA9IEZyYWdtZW50LmVtcHR5LCBvcGVuRW5kID0gMDtcbiAgICBmb3IgKGxldCBkID0gZGVwdGgsIHNwbGl0dGluZyA9IGZhbHNlOyBkID4gdGFyZ2V0OyBkLS0pXG4gICAgICAgIGlmIChzcGxpdHRpbmcgfHwgJHRvLmFmdGVyKGQgKyAxKSA8ICR0by5lbmQoZCkpIHtcbiAgICAgICAgICAgIHNwbGl0dGluZyA9IHRydWU7XG4gICAgICAgICAgICBhZnRlciA9IEZyYWdtZW50LmZyb20oJHRvLm5vZGUoZCkuY29weShhZnRlcikpO1xuICAgICAgICAgICAgb3BlbkVuZCsrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZW5kKys7XG4gICAgICAgIH1cbiAgICB0ci5zdGVwKG5ldyBSZXBsYWNlQXJvdW5kU3RlcChzdGFydCwgZW5kLCBnYXBTdGFydCwgZ2FwRW5kLCBuZXcgU2xpY2UoYmVmb3JlLmFwcGVuZChhZnRlciksIG9wZW5TdGFydCwgb3BlbkVuZCksIGJlZm9yZS5zaXplIC0gb3BlblN0YXJ0LCB0cnVlKSk7XG59XG4vKipcblRyeSB0byBmaW5kIGEgdmFsaWQgd2F5IHRvIHdyYXAgdGhlIGNvbnRlbnQgaW4gdGhlIGdpdmVuIHJhbmdlIGluIGFcbm5vZGUgb2YgdGhlIGdpdmVuIHR5cGUuIE1heSBpbnRyb2R1Y2UgZXh0cmEgbm9kZXMgYXJvdW5kIGFuZCBpbnNpZGVcbnRoZSB3cmFwcGVyIG5vZGUsIGlmIG5lY2Vzc2FyeS4gUmV0dXJucyBudWxsIGlmIG5vIHZhbGlkIHdyYXBwaW5nXG5jb3VsZCBiZSBmb3VuZC4gV2hlbiBgaW5uZXJSYW5nZWAgaXMgZ2l2ZW4sIHRoYXQgcmFuZ2UncyBjb250ZW50IGlzXG51c2VkIGFzIHRoZSBjb250ZW50IHRvIGZpdCBpbnRvIHRoZSB3cmFwcGluZywgaW5zdGVhZCBvZiB0aGVcbmNvbnRlbnQgb2YgYHJhbmdlYC5cbiovXG5mdW5jdGlvbiBmaW5kV3JhcHBpbmcocmFuZ2UsIG5vZGVUeXBlLCBhdHRycyA9IG51bGwsIGlubmVyUmFuZ2UgPSByYW5nZSkge1xuICAgIGxldCBhcm91bmQgPSBmaW5kV3JhcHBpbmdPdXRzaWRlKHJhbmdlLCBub2RlVHlwZSk7XG4gICAgbGV0IGlubmVyID0gYXJvdW5kICYmIGZpbmRXcmFwcGluZ0luc2lkZShpbm5lclJhbmdlLCBub2RlVHlwZSk7XG4gICAgaWYgKCFpbm5lcilcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIGFyb3VuZC5tYXAod2l0aEF0dHJzKVxuICAgICAgICAuY29uY2F0KHsgdHlwZTogbm9kZVR5cGUsIGF0dHJzIH0pLmNvbmNhdChpbm5lci5tYXAod2l0aEF0dHJzKSk7XG59XG5mdW5jdGlvbiB3aXRoQXR0cnModHlwZSkgeyByZXR1cm4geyB0eXBlLCBhdHRyczogbnVsbCB9OyB9XG5mdW5jdGlvbiBmaW5kV3JhcHBpbmdPdXRzaWRlKHJhbmdlLCB0eXBlKSB7XG4gICAgbGV0IHsgcGFyZW50LCBzdGFydEluZGV4LCBlbmRJbmRleCB9ID0gcmFuZ2U7XG4gICAgbGV0IGFyb3VuZCA9IHBhcmVudC5jb250ZW50TWF0Y2hBdChzdGFydEluZGV4KS5maW5kV3JhcHBpbmcodHlwZSk7XG4gICAgaWYgKCFhcm91bmQpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGxldCBvdXRlciA9IGFyb3VuZC5sZW5ndGggPyBhcm91bmRbMF0gOiB0eXBlO1xuICAgIHJldHVybiBwYXJlbnQuY2FuUmVwbGFjZVdpdGgoc3RhcnRJbmRleCwgZW5kSW5kZXgsIG91dGVyKSA/IGFyb3VuZCA6IG51bGw7XG59XG5mdW5jdGlvbiBmaW5kV3JhcHBpbmdJbnNpZGUocmFuZ2UsIHR5cGUpIHtcbiAgICBsZXQgeyBwYXJlbnQsIHN0YXJ0SW5kZXgsIGVuZEluZGV4IH0gPSByYW5nZTtcbiAgICBsZXQgaW5uZXIgPSBwYXJlbnQuY2hpbGQoc3RhcnRJbmRleCk7XG4gICAgbGV0IGluc2lkZSA9IHR5cGUuY29udGVudE1hdGNoLmZpbmRXcmFwcGluZyhpbm5lci50eXBlKTtcbiAgICBpZiAoIWluc2lkZSlcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgbGV0IGxhc3RUeXBlID0gaW5zaWRlLmxlbmd0aCA/IGluc2lkZVtpbnNpZGUubGVuZ3RoIC0gMV0gOiB0eXBlO1xuICAgIGxldCBpbm5lck1hdGNoID0gbGFzdFR5cGUuY29udGVudE1hdGNoO1xuICAgIGZvciAobGV0IGkgPSBzdGFydEluZGV4OyBpbm5lck1hdGNoICYmIGkgPCBlbmRJbmRleDsgaSsrKVxuICAgICAgICBpbm5lck1hdGNoID0gaW5uZXJNYXRjaC5tYXRjaFR5cGUocGFyZW50LmNoaWxkKGkpLnR5cGUpO1xuICAgIGlmICghaW5uZXJNYXRjaCB8fCAhaW5uZXJNYXRjaC52YWxpZEVuZClcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIGluc2lkZTtcbn1cbmZ1bmN0aW9uIHdyYXAodHIsIHJhbmdlLCB3cmFwcGVycykge1xuICAgIGxldCBjb250ZW50ID0gRnJhZ21lbnQuZW1wdHk7XG4gICAgZm9yIChsZXQgaSA9IHdyYXBwZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGlmIChjb250ZW50LnNpemUpIHtcbiAgICAgICAgICAgIGxldCBtYXRjaCA9IHdyYXBwZXJzW2ldLnR5cGUuY29udGVudE1hdGNoLm1hdGNoRnJhZ21lbnQoY29udGVudCk7XG4gICAgICAgICAgICBpZiAoIW1hdGNoIHx8ICFtYXRjaC52YWxpZEVuZClcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIldyYXBwZXIgdHlwZSBnaXZlbiB0byBUcmFuc2Zvcm0ud3JhcCBkb2VzIG5vdCBmb3JtIHZhbGlkIGNvbnRlbnQgb2YgaXRzIHBhcmVudCB3cmFwcGVyXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRlbnQgPSBGcmFnbWVudC5mcm9tKHdyYXBwZXJzW2ldLnR5cGUuY3JlYXRlKHdyYXBwZXJzW2ldLmF0dHJzLCBjb250ZW50KSk7XG4gICAgfVxuICAgIGxldCBzdGFydCA9IHJhbmdlLnN0YXJ0LCBlbmQgPSByYW5nZS5lbmQ7XG4gICAgdHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAoc3RhcnQsIGVuZCwgc3RhcnQsIGVuZCwgbmV3IFNsaWNlKGNvbnRlbnQsIDAsIDApLCB3cmFwcGVycy5sZW5ndGgsIHRydWUpKTtcbn1cbmZ1bmN0aW9uIHNldEJsb2NrVHlwZSh0ciwgZnJvbSwgdG8sIHR5cGUsIGF0dHJzKSB7XG4gICAgaWYgKCF0eXBlLmlzVGV4dGJsb2NrKVxuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlR5cGUgZ2l2ZW4gdG8gc2V0QmxvY2tUeXBlIHNob3VsZCBiZSBhIHRleHRibG9ja1wiKTtcbiAgICBsZXQgbWFwRnJvbSA9IHRyLnN0ZXBzLmxlbmd0aDtcbiAgICB0ci5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgIGxldCBhdHRyc0hlcmUgPSB0eXBlb2YgYXR0cnMgPT0gXCJmdW5jdGlvblwiID8gYXR0cnMobm9kZSkgOiBhdHRycztcbiAgICAgICAgaWYgKG5vZGUuaXNUZXh0YmxvY2sgJiYgIW5vZGUuaGFzTWFya3VwKHR5cGUsIGF0dHJzSGVyZSkgJiZcbiAgICAgICAgICAgIGNhbkNoYW5nZVR5cGUodHIuZG9jLCB0ci5tYXBwaW5nLnNsaWNlKG1hcEZyb20pLm1hcChwb3MpLCB0eXBlKSkge1xuICAgICAgICAgICAgbGV0IGNvbnZlcnROZXdsaW5lcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAodHlwZS5zY2hlbWEubGluZWJyZWFrUmVwbGFjZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBsZXQgcHJlID0gdHlwZS53aGl0ZXNwYWNlID09IFwicHJlXCIsIHN1cHBvcnRMaW5lYnJlYWsgPSAhIXR5cGUuY29udGVudE1hdGNoLm1hdGNoVHlwZSh0eXBlLnNjaGVtYS5saW5lYnJlYWtSZXBsYWNlbWVudCk7XG4gICAgICAgICAgICAgICAgaWYgKHByZSAmJiAhc3VwcG9ydExpbmVicmVhaylcbiAgICAgICAgICAgICAgICAgICAgY29udmVydE5ld2xpbmVzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoIXByZSAmJiBzdXBwb3J0TGluZWJyZWFrKVxuICAgICAgICAgICAgICAgICAgICBjb252ZXJ0TmV3bGluZXMgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRW5zdXJlIGFsbCBtYXJrdXAgdGhhdCBpc24ndCBhbGxvd2VkIGluIHRoZSBuZXcgbm9kZSB0eXBlIGlzIGNsZWFyZWRcbiAgICAgICAgICAgIGlmIChjb252ZXJ0TmV3bGluZXMgPT09IGZhbHNlKVxuICAgICAgICAgICAgICAgIHJlcGxhY2VMaW5lYnJlYWtzKHRyLCBub2RlLCBwb3MsIG1hcEZyb20pO1xuICAgICAgICAgICAgY2xlYXJJbmNvbXBhdGlibGUodHIsIHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSkubWFwKHBvcywgMSksIHR5cGUsIHVuZGVmaW5lZCwgY29udmVydE5ld2xpbmVzID09PSBudWxsKTtcbiAgICAgICAgICAgIGxldCBtYXBwaW5nID0gdHIubWFwcGluZy5zbGljZShtYXBGcm9tKTtcbiAgICAgICAgICAgIGxldCBzdGFydE0gPSBtYXBwaW5nLm1hcChwb3MsIDEpLCBlbmRNID0gbWFwcGluZy5tYXAocG9zICsgbm9kZS5ub2RlU2l6ZSwgMSk7XG4gICAgICAgICAgICB0ci5zdGVwKG5ldyBSZXBsYWNlQXJvdW5kU3RlcChzdGFydE0sIGVuZE0sIHN0YXJ0TSArIDEsIGVuZE0gLSAxLCBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbSh0eXBlLmNyZWF0ZShhdHRyc0hlcmUsIG51bGwsIG5vZGUubWFya3MpKSwgMCwgMCksIDEsIHRydWUpKTtcbiAgICAgICAgICAgIGlmIChjb252ZXJ0TmV3bGluZXMgPT09IHRydWUpXG4gICAgICAgICAgICAgICAgcmVwbGFjZU5ld2xpbmVzKHRyLCBub2RlLCBwb3MsIG1hcEZyb20pO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5mdW5jdGlvbiByZXBsYWNlTmV3bGluZXModHIsIG5vZGUsIHBvcywgbWFwRnJvbSkge1xuICAgIG5vZGUuZm9yRWFjaCgoY2hpbGQsIG9mZnNldCkgPT4ge1xuICAgICAgICBpZiAoY2hpbGQuaXNUZXh0KSB7XG4gICAgICAgICAgICBsZXQgbSwgbmV3bGluZSA9IC9cXHI/XFxufFxcci9nO1xuICAgICAgICAgICAgd2hpbGUgKG0gPSBuZXdsaW5lLmV4ZWMoY2hpbGQudGV4dCkpIHtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSB0ci5tYXBwaW5nLnNsaWNlKG1hcEZyb20pLm1hcChwb3MgKyAxICsgb2Zmc2V0ICsgbS5pbmRleCk7XG4gICAgICAgICAgICAgICAgdHIucmVwbGFjZVdpdGgoc3RhcnQsIHN0YXJ0ICsgMSwgbm9kZS50eXBlLnNjaGVtYS5saW5lYnJlYWtSZXBsYWNlbWVudC5jcmVhdGUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VMaW5lYnJlYWtzKHRyLCBub2RlLCBwb3MsIG1hcEZyb20pIHtcbiAgICBub2RlLmZvckVhY2goKGNoaWxkLCBvZmZzZXQpID0+IHtcbiAgICAgICAgaWYgKGNoaWxkLnR5cGUgPT0gY2hpbGQudHlwZS5zY2hlbWEubGluZWJyZWFrUmVwbGFjZW1lbnQpIHtcbiAgICAgICAgICAgIGxldCBzdGFydCA9IHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSkubWFwKHBvcyArIDEgKyBvZmZzZXQpO1xuICAgICAgICAgICAgdHIucmVwbGFjZVdpdGgoc3RhcnQsIHN0YXJ0ICsgMSwgbm9kZS50eXBlLnNjaGVtYS50ZXh0KFwiXFxuXCIpKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gY2FuQ2hhbmdlVHlwZShkb2MsIHBvcywgdHlwZSkge1xuICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUocG9zKSwgaW5kZXggPSAkcG9zLmluZGV4KCk7XG4gICAgcmV0dXJuICRwb3MucGFyZW50LmNhblJlcGxhY2VXaXRoKGluZGV4LCBpbmRleCArIDEsIHR5cGUpO1xufVxuLyoqXG5DaGFuZ2UgdGhlIHR5cGUsIGF0dHJpYnV0ZXMsIGFuZC9vciBtYXJrcyBvZiB0aGUgbm9kZSBhdCBgcG9zYC5cbldoZW4gYHR5cGVgIGlzbid0IGdpdmVuLCB0aGUgZXhpc3Rpbmcgbm9kZSB0eXBlIGlzIHByZXNlcnZlZCxcbiovXG5mdW5jdGlvbiBzZXROb2RlTWFya3VwKHRyLCBwb3MsIHR5cGUsIGF0dHJzLCBtYXJrcykge1xuICAgIGxldCBub2RlID0gdHIuZG9jLm5vZGVBdChwb3MpO1xuICAgIGlmICghbm9kZSlcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJObyBub2RlIGF0IGdpdmVuIHBvc2l0aW9uXCIpO1xuICAgIGlmICghdHlwZSlcbiAgICAgICAgdHlwZSA9IG5vZGUudHlwZTtcbiAgICBsZXQgbmV3Tm9kZSA9IHR5cGUuY3JlYXRlKGF0dHJzLCBudWxsLCBtYXJrcyB8fCBub2RlLm1hcmtzKTtcbiAgICBpZiAobm9kZS5pc0xlYWYpXG4gICAgICAgIHJldHVybiB0ci5yZXBsYWNlV2l0aChwb3MsIHBvcyArIG5vZGUubm9kZVNpemUsIG5ld05vZGUpO1xuICAgIGlmICghdHlwZS52YWxpZENvbnRlbnQobm9kZS5jb250ZW50KSlcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGNvbnRlbnQgZm9yIG5vZGUgdHlwZSBcIiArIHR5cGUubmFtZSk7XG4gICAgdHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAocG9zLCBwb3MgKyBub2RlLm5vZGVTaXplLCBwb3MgKyAxLCBwb3MgKyBub2RlLm5vZGVTaXplIC0gMSwgbmV3IFNsaWNlKEZyYWdtZW50LmZyb20obmV3Tm9kZSksIDAsIDApLCAxLCB0cnVlKSk7XG59XG4vKipcbkNoZWNrIHdoZXRoZXIgc3BsaXR0aW5nIGF0IHRoZSBnaXZlbiBwb3NpdGlvbiBpcyBhbGxvd2VkLlxuKi9cbmZ1bmN0aW9uIGNhblNwbGl0KGRvYywgcG9zLCBkZXB0aCA9IDEsIHR5cGVzQWZ0ZXIpIHtcbiAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHBvcyksIGJhc2UgPSAkcG9zLmRlcHRoIC0gZGVwdGg7XG4gICAgbGV0IGlubmVyVHlwZSA9ICh0eXBlc0FmdGVyICYmIHR5cGVzQWZ0ZXJbdHlwZXNBZnRlci5sZW5ndGggLSAxXSkgfHwgJHBvcy5wYXJlbnQ7XG4gICAgaWYgKGJhc2UgPCAwIHx8ICRwb3MucGFyZW50LnR5cGUuc3BlYy5pc29sYXRpbmcgfHxcbiAgICAgICAgISRwb3MucGFyZW50LmNhblJlcGxhY2UoJHBvcy5pbmRleCgpLCAkcG9zLnBhcmVudC5jaGlsZENvdW50KSB8fFxuICAgICAgICAhaW5uZXJUeXBlLnR5cGUudmFsaWRDb250ZW50KCRwb3MucGFyZW50LmNvbnRlbnQuY3V0QnlJbmRleCgkcG9zLmluZGV4KCksICRwb3MucGFyZW50LmNoaWxkQ291bnQpKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGZvciAobGV0IGQgPSAkcG9zLmRlcHRoIC0gMSwgaSA9IGRlcHRoIC0gMjsgZCA+IGJhc2U7IGQtLSwgaS0tKSB7XG4gICAgICAgIGxldCBub2RlID0gJHBvcy5ub2RlKGQpLCBpbmRleCA9ICRwb3MuaW5kZXgoZCk7XG4gICAgICAgIGlmIChub2RlLnR5cGUuc3BlYy5pc29sYXRpbmcpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGxldCByZXN0ID0gbm9kZS5jb250ZW50LmN1dEJ5SW5kZXgoaW5kZXgsIG5vZGUuY2hpbGRDb3VudCk7XG4gICAgICAgIGxldCBvdmVycmlkZUNoaWxkID0gdHlwZXNBZnRlciAmJiB0eXBlc0FmdGVyW2kgKyAxXTtcbiAgICAgICAgaWYgKG92ZXJyaWRlQ2hpbGQpXG4gICAgICAgICAgICByZXN0ID0gcmVzdC5yZXBsYWNlQ2hpbGQoMCwgb3ZlcnJpZGVDaGlsZC50eXBlLmNyZWF0ZShvdmVycmlkZUNoaWxkLmF0dHJzKSk7XG4gICAgICAgIGxldCBhZnRlciA9ICh0eXBlc0FmdGVyICYmIHR5cGVzQWZ0ZXJbaV0pIHx8IG5vZGU7XG4gICAgICAgIGlmICghbm9kZS5jYW5SZXBsYWNlKGluZGV4ICsgMSwgbm9kZS5jaGlsZENvdW50KSB8fCAhYWZ0ZXIudHlwZS52YWxpZENvbnRlbnQocmVzdCkpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCBpbmRleCA9ICRwb3MuaW5kZXhBZnRlcihiYXNlKTtcbiAgICBsZXQgYmFzZVR5cGUgPSB0eXBlc0FmdGVyICYmIHR5cGVzQWZ0ZXJbMF07XG4gICAgcmV0dXJuICRwb3Mubm9kZShiYXNlKS5jYW5SZXBsYWNlV2l0aChpbmRleCwgaW5kZXgsIGJhc2VUeXBlID8gYmFzZVR5cGUudHlwZSA6ICRwb3Mubm9kZShiYXNlICsgMSkudHlwZSk7XG59XG5mdW5jdGlvbiBzcGxpdCh0ciwgcG9zLCBkZXB0aCA9IDEsIHR5cGVzQWZ0ZXIpIHtcbiAgICBsZXQgJHBvcyA9IHRyLmRvYy5yZXNvbHZlKHBvcyksIGJlZm9yZSA9IEZyYWdtZW50LmVtcHR5LCBhZnRlciA9IEZyYWdtZW50LmVtcHR5O1xuICAgIGZvciAobGV0IGQgPSAkcG9zLmRlcHRoLCBlID0gJHBvcy5kZXB0aCAtIGRlcHRoLCBpID0gZGVwdGggLSAxOyBkID4gZTsgZC0tLCBpLS0pIHtcbiAgICAgICAgYmVmb3JlID0gRnJhZ21lbnQuZnJvbSgkcG9zLm5vZGUoZCkuY29weShiZWZvcmUpKTtcbiAgICAgICAgbGV0IHR5cGVBZnRlciA9IHR5cGVzQWZ0ZXIgJiYgdHlwZXNBZnRlcltpXTtcbiAgICAgICAgYWZ0ZXIgPSBGcmFnbWVudC5mcm9tKHR5cGVBZnRlciA/IHR5cGVBZnRlci50eXBlLmNyZWF0ZSh0eXBlQWZ0ZXIuYXR0cnMsIGFmdGVyKSA6ICRwb3Mubm9kZShkKS5jb3B5KGFmdGVyKSk7XG4gICAgfVxuICAgIHRyLnN0ZXAobmV3IFJlcGxhY2VTdGVwKHBvcywgcG9zLCBuZXcgU2xpY2UoYmVmb3JlLmFwcGVuZChhZnRlciksIGRlcHRoLCBkZXB0aCksIHRydWUpKTtcbn1cbi8qKlxuVGVzdCB3aGV0aGVyIHRoZSBibG9ja3MgYmVmb3JlIGFuZCBhZnRlciBhIGdpdmVuIHBvc2l0aW9uIGNhbiBiZVxuam9pbmVkLlxuKi9cbmZ1bmN0aW9uIGNhbkpvaW4oZG9jLCBwb3MpIHtcbiAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHBvcyksIGluZGV4ID0gJHBvcy5pbmRleCgpO1xuICAgIHJldHVybiBqb2luYWJsZSgkcG9zLm5vZGVCZWZvcmUsICRwb3Mubm9kZUFmdGVyKSAmJlxuICAgICAgICAkcG9zLnBhcmVudC5jYW5SZXBsYWNlKGluZGV4LCBpbmRleCArIDEpO1xufVxuZnVuY3Rpb24gY2FuQXBwZW5kV2l0aFN1YnN0aXR1dGVkTGluZWJyZWFrcyhhLCBiKSB7XG4gICAgaWYgKCFiLmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgYS50eXBlLmNvbXBhdGlibGVDb250ZW50KGIudHlwZSk7XG4gICAgbGV0IG1hdGNoID0gYS5jb250ZW50TWF0Y2hBdChhLmNoaWxkQ291bnQpO1xuICAgIGxldCB7IGxpbmVicmVha1JlcGxhY2VtZW50IH0gPSBhLnR5cGUuc2NoZW1hO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYi5jaGlsZENvdW50OyBpKyspIHtcbiAgICAgICAgbGV0IGNoaWxkID0gYi5jaGlsZChpKTtcbiAgICAgICAgbGV0IHR5cGUgPSBjaGlsZC50eXBlID09IGxpbmVicmVha1JlcGxhY2VtZW50ID8gYS50eXBlLnNjaGVtYS5ub2Rlcy50ZXh0IDogY2hpbGQudHlwZTtcbiAgICAgICAgbWF0Y2ggPSBtYXRjaC5tYXRjaFR5cGUodHlwZSk7XG4gICAgICAgIGlmICghbWF0Y2gpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmICghYS50eXBlLmFsbG93c01hcmtzKGNoaWxkLm1hcmtzKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoLnZhbGlkRW5kO1xufVxuZnVuY3Rpb24gam9pbmFibGUoYSwgYikge1xuICAgIHJldHVybiAhIShhICYmIGIgJiYgIWEuaXNMZWFmICYmIGNhbkFwcGVuZFdpdGhTdWJzdGl0dXRlZExpbmVicmVha3MoYSwgYikpO1xufVxuLyoqXG5GaW5kIGFuIGFuY2VzdG9yIG9mIHRoZSBnaXZlbiBwb3NpdGlvbiB0aGF0IGNhbiBiZSBqb2luZWQgdG8gdGhlXG5ibG9jayBiZWZvcmUgKG9yIGFmdGVyIGlmIGBkaXJgIGlzIHBvc2l0aXZlKS4gUmV0dXJucyB0aGUgam9pbmFibGVcbnBvaW50LCBpZiBhbnkuXG4qL1xuZnVuY3Rpb24gam9pblBvaW50KGRvYywgcG9zLCBkaXIgPSAtMSkge1xuICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUocG9zKTtcbiAgICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aDs7IGQtLSkge1xuICAgICAgICBsZXQgYmVmb3JlLCBhZnRlciwgaW5kZXggPSAkcG9zLmluZGV4KGQpO1xuICAgICAgICBpZiAoZCA9PSAkcG9zLmRlcHRoKSB7XG4gICAgICAgICAgICBiZWZvcmUgPSAkcG9zLm5vZGVCZWZvcmU7XG4gICAgICAgICAgICBhZnRlciA9ICRwb3Mubm9kZUFmdGVyO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRpciA+IDApIHtcbiAgICAgICAgICAgIGJlZm9yZSA9ICRwb3Mubm9kZShkICsgMSk7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgYWZ0ZXIgPSAkcG9zLm5vZGUoZCkubWF5YmVDaGlsZChpbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBiZWZvcmUgPSAkcG9zLm5vZGUoZCkubWF5YmVDaGlsZChpbmRleCAtIDEpO1xuICAgICAgICAgICAgYWZ0ZXIgPSAkcG9zLm5vZGUoZCArIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChiZWZvcmUgJiYgIWJlZm9yZS5pc1RleHRibG9jayAmJiBqb2luYWJsZShiZWZvcmUsIGFmdGVyKSAmJlxuICAgICAgICAgICAgJHBvcy5ub2RlKGQpLmNhblJlcGxhY2UoaW5kZXgsIGluZGV4ICsgMSkpXG4gICAgICAgICAgICByZXR1cm4gcG9zO1xuICAgICAgICBpZiAoZCA9PSAwKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIHBvcyA9IGRpciA8IDAgPyAkcG9zLmJlZm9yZShkKSA6ICRwb3MuYWZ0ZXIoZCk7XG4gICAgfVxufVxuZnVuY3Rpb24gam9pbih0ciwgcG9zLCBkZXB0aCkge1xuICAgIGxldCBjb252ZXJ0TmV3bGluZXMgPSBudWxsO1xuICAgIGxldCB7IGxpbmVicmVha1JlcGxhY2VtZW50IH0gPSB0ci5kb2MudHlwZS5zY2hlbWE7XG4gICAgbGV0ICRiZWZvcmUgPSB0ci5kb2MucmVzb2x2ZShwb3MgLSBkZXB0aCksIGJlZm9yZVR5cGUgPSAkYmVmb3JlLm5vZGUoKS50eXBlO1xuICAgIGlmIChsaW5lYnJlYWtSZXBsYWNlbWVudCAmJiBiZWZvcmVUeXBlLmlubGluZUNvbnRlbnQpIHtcbiAgICAgICAgbGV0IHByZSA9IGJlZm9yZVR5cGUud2hpdGVzcGFjZSA9PSBcInByZVwiO1xuICAgICAgICBsZXQgc3VwcG9ydExpbmVicmVhayA9ICEhYmVmb3JlVHlwZS5jb250ZW50TWF0Y2gubWF0Y2hUeXBlKGxpbmVicmVha1JlcGxhY2VtZW50KTtcbiAgICAgICAgaWYgKHByZSAmJiAhc3VwcG9ydExpbmVicmVhaylcbiAgICAgICAgICAgIGNvbnZlcnROZXdsaW5lcyA9IGZhbHNlO1xuICAgICAgICBlbHNlIGlmICghcHJlICYmIHN1cHBvcnRMaW5lYnJlYWspXG4gICAgICAgICAgICBjb252ZXJ0TmV3bGluZXMgPSB0cnVlO1xuICAgIH1cbiAgICBsZXQgbWFwRnJvbSA9IHRyLnN0ZXBzLmxlbmd0aDtcbiAgICBpZiAoY29udmVydE5ld2xpbmVzID09PSBmYWxzZSkge1xuICAgICAgICBsZXQgJGFmdGVyID0gdHIuZG9jLnJlc29sdmUocG9zICsgZGVwdGgpO1xuICAgICAgICByZXBsYWNlTGluZWJyZWFrcyh0ciwgJGFmdGVyLm5vZGUoKSwgJGFmdGVyLmJlZm9yZSgpLCBtYXBGcm9tKTtcbiAgICB9XG4gICAgaWYgKGJlZm9yZVR5cGUuaW5saW5lQ29udGVudClcbiAgICAgICAgY2xlYXJJbmNvbXBhdGlibGUodHIsIHBvcyArIGRlcHRoIC0gMSwgYmVmb3JlVHlwZSwgJGJlZm9yZS5ub2RlKCkuY29udGVudE1hdGNoQXQoJGJlZm9yZS5pbmRleCgpKSwgY29udmVydE5ld2xpbmVzID09IG51bGwpO1xuICAgIGxldCBtYXBwaW5nID0gdHIubWFwcGluZy5zbGljZShtYXBGcm9tKSwgc3RhcnQgPSBtYXBwaW5nLm1hcChwb3MgLSBkZXB0aCk7XG4gICAgdHIuc3RlcChuZXcgUmVwbGFjZVN0ZXAoc3RhcnQsIG1hcHBpbmcubWFwKHBvcyArIGRlcHRoLCAtMSksIFNsaWNlLmVtcHR5LCB0cnVlKSk7XG4gICAgaWYgKGNvbnZlcnROZXdsaW5lcyA9PT0gdHJ1ZSkge1xuICAgICAgICBsZXQgJGZ1bGwgPSB0ci5kb2MucmVzb2x2ZShzdGFydCk7XG4gICAgICAgIHJlcGxhY2VOZXdsaW5lcyh0ciwgJGZ1bGwubm9kZSgpLCAkZnVsbC5iZWZvcmUoKSwgdHIuc3RlcHMubGVuZ3RoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRyO1xufVxuLyoqXG5UcnkgdG8gZmluZCBhIHBvaW50IHdoZXJlIGEgbm9kZSBvZiB0aGUgZ2l2ZW4gdHlwZSBjYW4gYmUgaW5zZXJ0ZWRcbm5lYXIgYHBvc2AsIGJ5IHNlYXJjaGluZyB1cCB0aGUgbm9kZSBoaWVyYXJjaHkgd2hlbiBgcG9zYCBpdHNlbGZcbmlzbid0IGEgdmFsaWQgcGxhY2UgYnV0IGlzIGF0IHRoZSBzdGFydCBvciBlbmQgb2YgYSBub2RlLiBSZXR1cm5cbm51bGwgaWYgbm8gcG9zaXRpb24gd2FzIGZvdW5kLlxuKi9cbmZ1bmN0aW9uIGluc2VydFBvaW50KGRvYywgcG9zLCBub2RlVHlwZSkge1xuICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUocG9zKTtcbiAgICBpZiAoJHBvcy5wYXJlbnQuY2FuUmVwbGFjZVdpdGgoJHBvcy5pbmRleCgpLCAkcG9zLmluZGV4KCksIG5vZGVUeXBlKSlcbiAgICAgICAgcmV0dXJuIHBvcztcbiAgICBpZiAoJHBvcy5wYXJlbnRPZmZzZXQgPT0gMClcbiAgICAgICAgZm9yIChsZXQgZCA9ICRwb3MuZGVwdGggLSAxOyBkID49IDA7IGQtLSkge1xuICAgICAgICAgICAgbGV0IGluZGV4ID0gJHBvcy5pbmRleChkKTtcbiAgICAgICAgICAgIGlmICgkcG9zLm5vZGUoZCkuY2FuUmVwbGFjZVdpdGgoaW5kZXgsIGluZGV4LCBub2RlVHlwZSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuICRwb3MuYmVmb3JlKGQgKyAxKTtcbiAgICAgICAgICAgIGlmIChpbmRleCA+IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICBpZiAoJHBvcy5wYXJlbnRPZmZzZXQgPT0gJHBvcy5wYXJlbnQuY29udGVudC5zaXplKVxuICAgICAgICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aCAtIDE7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAkcG9zLmluZGV4QWZ0ZXIoZCk7XG4gICAgICAgICAgICBpZiAoJHBvcy5ub2RlKGQpLmNhblJlcGxhY2VXaXRoKGluZGV4LCBpbmRleCwgbm9kZVR5cGUpKVxuICAgICAgICAgICAgICAgIHJldHVybiAkcG9zLmFmdGVyKGQgKyAxKTtcbiAgICAgICAgICAgIGlmIChpbmRleCA8ICRwb3Mubm9kZShkKS5jaGlsZENvdW50KVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG4vKipcbkZpbmRzIGEgcG9zaXRpb24gYXQgb3IgYXJvdW5kIHRoZSBnaXZlbiBwb3NpdGlvbiB3aGVyZSB0aGUgZ2l2ZW5cbnNsaWNlIGNhbiBiZSBpbnNlcnRlZC4gV2lsbCBsb29rIGF0IHBhcmVudCBub2RlcycgbmVhcmVzdCBib3VuZGFyeVxuYW5kIHRyeSB0aGVyZSwgZXZlbiBpZiB0aGUgb3JpZ2luYWwgcG9zaXRpb24gd2Fzbid0IGRpcmVjdGx5IGF0IHRoZVxuc3RhcnQgb3IgZW5kIG9mIHRoYXQgbm9kZS4gUmV0dXJucyBudWxsIHdoZW4gbm8gcG9zaXRpb24gd2FzIGZvdW5kLlxuKi9cbmZ1bmN0aW9uIGRyb3BQb2ludChkb2MsIHBvcywgc2xpY2UpIHtcbiAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHBvcyk7XG4gICAgaWYgKCFzbGljZS5jb250ZW50LnNpemUpXG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgbGV0IGNvbnRlbnQgPSBzbGljZS5jb250ZW50O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpY2Uub3BlblN0YXJ0OyBpKyspXG4gICAgICAgIGNvbnRlbnQgPSBjb250ZW50LmZpcnN0Q2hpbGQuY29udGVudDtcbiAgICBmb3IgKGxldCBwYXNzID0gMTsgcGFzcyA8PSAoc2xpY2Uub3BlblN0YXJ0ID09IDAgJiYgc2xpY2Uuc2l6ZSA/IDIgOiAxKTsgcGFzcysrKSB7XG4gICAgICAgIGZvciAobGV0IGQgPSAkcG9zLmRlcHRoOyBkID49IDA7IGQtLSkge1xuICAgICAgICAgICAgbGV0IGJpYXMgPSBkID09ICRwb3MuZGVwdGggPyAwIDogJHBvcy5wb3MgPD0gKCRwb3Muc3RhcnQoZCArIDEpICsgJHBvcy5lbmQoZCArIDEpKSAvIDIgPyAtMSA6IDE7XG4gICAgICAgICAgICBsZXQgaW5zZXJ0UG9zID0gJHBvcy5pbmRleChkKSArIChiaWFzID4gMCA/IDEgOiAwKTtcbiAgICAgICAgICAgIGxldCBwYXJlbnQgPSAkcG9zLm5vZGUoZCksIGZpdHMgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChwYXNzID09IDEpIHtcbiAgICAgICAgICAgICAgICBmaXRzID0gcGFyZW50LmNhblJlcGxhY2UoaW5zZXJ0UG9zLCBpbnNlcnRQb3MsIGNvbnRlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IHdyYXBwaW5nID0gcGFyZW50LmNvbnRlbnRNYXRjaEF0KGluc2VydFBvcykuZmluZFdyYXBwaW5nKGNvbnRlbnQuZmlyc3RDaGlsZC50eXBlKTtcbiAgICAgICAgICAgICAgICBmaXRzID0gd3JhcHBpbmcgJiYgcGFyZW50LmNhblJlcGxhY2VXaXRoKGluc2VydFBvcywgaW5zZXJ0UG9zLCB3cmFwcGluZ1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZml0cylcbiAgICAgICAgICAgICAgICByZXR1cm4gYmlhcyA9PSAwID8gJHBvcy5wb3MgOiBiaWFzIDwgMCA/ICRwb3MuYmVmb3JlKGQgKyAxKSA6ICRwb3MuYWZ0ZXIoZCArIDEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG4vKipcblx1MjAxOEZpdFx1MjAxOSBhIHNsaWNlIGludG8gYSBnaXZlbiBwb3NpdGlvbiBpbiB0aGUgZG9jdW1lbnQsIHByb2R1Y2luZyBhXG5bc3RlcF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5TdGVwKSB0aGF0IGluc2VydHMgaXQuIFdpbGwgcmV0dXJuIG51bGwgaWZcbnRoZXJlJ3Mgbm8gbWVhbmluZ2Z1bCB3YXkgdG8gaW5zZXJ0IHRoZSBzbGljZSBoZXJlLCBvciBpbnNlcnRpbmcgaXRcbndvdWxkIGJlIGEgbm8tb3AgKGFuIGVtcHR5IHNsaWNlIG92ZXIgYW4gZW1wdHkgcmFuZ2UpLlxuKi9cbmZ1bmN0aW9uIHJlcGxhY2VTdGVwKGRvYywgZnJvbSwgdG8gPSBmcm9tLCBzbGljZSA9IFNsaWNlLmVtcHR5KSB7XG4gICAgaWYgKGZyb20gPT0gdG8gJiYgIXNsaWNlLnNpemUpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGxldCAkZnJvbSA9IGRvYy5yZXNvbHZlKGZyb20pLCAkdG8gPSBkb2MucmVzb2x2ZSh0byk7XG4gICAgLy8gT3B0aW1pemF0aW9uIC0tIGF2b2lkIHdvcmsgaWYgaXQncyBvYnZpb3VzIHRoYXQgaXQncyBub3QgbmVlZGVkLlxuICAgIGlmIChmaXRzVHJpdmlhbGx5KCRmcm9tLCAkdG8sIHNsaWNlKSlcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBsYWNlU3RlcChmcm9tLCB0bywgc2xpY2UpO1xuICAgIHJldHVybiBuZXcgRml0dGVyKCRmcm9tLCAkdG8sIHNsaWNlKS5maXQoKTtcbn1cbmZ1bmN0aW9uIGZpdHNUcml2aWFsbHkoJGZyb20sICR0bywgc2xpY2UpIHtcbiAgICByZXR1cm4gIXNsaWNlLm9wZW5TdGFydCAmJiAhc2xpY2Uub3BlbkVuZCAmJiAkZnJvbS5zdGFydCgpID09ICR0by5zdGFydCgpICYmXG4gICAgICAgICRmcm9tLnBhcmVudC5jYW5SZXBsYWNlKCRmcm9tLmluZGV4KCksICR0by5pbmRleCgpLCBzbGljZS5jb250ZW50KTtcbn1cbi8vIEFsZ29yaXRobSBmb3IgJ3BsYWNpbmcnIHRoZSBlbGVtZW50cyBvZiBhIHNsaWNlIGludG8gYSBnYXA6XG4vL1xuLy8gV2UgY29uc2lkZXIgdGhlIGNvbnRlbnQgb2YgZWFjaCBub2RlIHRoYXQgaXMgb3BlbiB0byB0aGUgbGVmdCB0byBiZVxuLy8gaW5kZXBlbmRlbnRseSBwbGFjZWFibGUuIEkuZS4gaW4gPHAoXCJmb29cIiksIHAoXCJiYXJcIik+LCB3aGVuIHRoZVxuLy8gcGFyYWdyYXBoIG9uIHRoZSBsZWZ0IGlzIG9wZW4sIFwiZm9vXCIgY2FuIGJlIHBsYWNlZCAoc29tZXdoZXJlIG9uXG4vLyB0aGUgbGVmdCBzaWRlIG9mIHRoZSByZXBsYWNlbWVudCBnYXApIGluZGVwZW5kZW50bHkgZnJvbSBwKFwiYmFyXCIpLlxuLy9cbi8vIFRoaXMgY2xhc3MgdHJhY2tzIHRoZSBzdGF0ZSBvZiB0aGUgcGxhY2VtZW50IHByb2dyZXNzIGluIHRoZVxuLy8gZm9sbG93aW5nIHByb3BlcnRpZXM6XG4vL1xuLy8gIC0gYGZyb250aWVyYCBob2xkcyBhIHN0YWNrIG9mIGB7dHlwZSwgbWF0Y2h9YCBvYmplY3RzIHRoYXRcbi8vICAgIHJlcHJlc2VudCB0aGUgb3BlbiBzaWRlIG9mIHRoZSByZXBsYWNlbWVudC4gSXQgc3RhcnRzIGF0XG4vLyAgICBgJGZyb21gLCB0aGVuIG1vdmVzIGZvcndhcmQgYXMgY29udGVudCBpcyBwbGFjZWQsIGFuZCBpcyBmaW5hbGx5XG4vLyAgICByZWNvbmNpbGVkIHdpdGggYCR0b2AuXG4vL1xuLy8gIC0gYHVucGxhY2VkYCBpcyBhIHNsaWNlIHRoYXQgcmVwcmVzZW50cyB0aGUgY29udGVudCB0aGF0IGhhc24ndFxuLy8gICAgYmVlbiBwbGFjZWQgeWV0LlxuLy9cbi8vICAtIGBwbGFjZWRgIGlzIGEgZnJhZ21lbnQgb2YgcGxhY2VkIGNvbnRlbnQuIEl0cyBvcGVuLXN0YXJ0IHZhbHVlXG4vLyAgICBpcyBpbXBsaWNpdCBpbiBgJGZyb21gLCBhbmQgaXRzIG9wZW4tZW5kIHZhbHVlIGluIGBmcm9udGllcmAuXG5jbGFzcyBGaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yKCRmcm9tLCAkdG8sIHVucGxhY2VkKSB7XG4gICAgICAgIHRoaXMuJGZyb20gPSAkZnJvbTtcbiAgICAgICAgdGhpcy4kdG8gPSAkdG87XG4gICAgICAgIHRoaXMudW5wbGFjZWQgPSB1bnBsYWNlZDtcbiAgICAgICAgdGhpcy5mcm9udGllciA9IFtdO1xuICAgICAgICB0aGlzLnBsYWNlZCA9IEZyYWdtZW50LmVtcHR5O1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSAkZnJvbS5kZXB0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbm9kZSA9ICRmcm9tLm5vZGUoaSk7XG4gICAgICAgICAgICB0aGlzLmZyb250aWVyLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6IG5vZGUudHlwZSxcbiAgICAgICAgICAgICAgICBtYXRjaDogbm9kZS5jb250ZW50TWF0Y2hBdCgkZnJvbS5pbmRleEFmdGVyKGkpKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9ICRmcm9tLmRlcHRoOyBpID4gMDsgaS0tKVxuICAgICAgICAgICAgdGhpcy5wbGFjZWQgPSBGcmFnbWVudC5mcm9tKCRmcm9tLm5vZGUoaSkuY29weSh0aGlzLnBsYWNlZCkpO1xuICAgIH1cbiAgICBnZXQgZGVwdGgoKSB7IHJldHVybiB0aGlzLmZyb250aWVyLmxlbmd0aCAtIDE7IH1cbiAgICBmaXQoKSB7XG4gICAgICAgIC8vIEFzIGxvbmcgYXMgdGhlcmUncyB1bnBsYWNlZCBjb250ZW50LCB0cnkgdG8gcGxhY2Ugc29tZSBvZiBpdC5cbiAgICAgICAgLy8gSWYgdGhhdCBmYWlscywgZWl0aGVyIGluY3JlYXNlIHRoZSBvcGVuIHNjb3JlIG9mIHRoZSB1bnBsYWNlZFxuICAgICAgICAvLyBzbGljZSwgb3IgZHJvcCBub2RlcyBmcm9tIGl0LCBhbmQgdGhlbiB0cnkgYWdhaW4uXG4gICAgICAgIHdoaWxlICh0aGlzLnVucGxhY2VkLnNpemUpIHtcbiAgICAgICAgICAgIGxldCBmaXQgPSB0aGlzLmZpbmRGaXR0YWJsZSgpO1xuICAgICAgICAgICAgaWYgKGZpdClcbiAgICAgICAgICAgICAgICB0aGlzLnBsYWNlTm9kZXMoZml0KTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW5Nb3JlKCkgfHwgdGhpcy5kcm9wTm9kZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdoZW4gdGhlcmUncyBpbmxpbmUgY29udGVudCBkaXJlY3RseSBhZnRlciB0aGUgZnJvbnRpZXIgX2FuZF9cbiAgICAgICAgLy8gZGlyZWN0bHkgYWZ0ZXIgYHRoaXMuJHRvYCwgd2UgbXVzdCBnZW5lcmF0ZSBhIGBSZXBsYWNlQXJvdW5kYFxuICAgICAgICAvLyBzdGVwIHRoYXQgcHVsbHMgdGhhdCBjb250ZW50IGludG8gdGhlIG5vZGUgYWZ0ZXIgdGhlIGZyb250aWVyLlxuICAgICAgICAvLyBUaGF0IG1lYW5zIHRoZSBmaXR0aW5nIG11c3QgYmUgZG9uZSB0byB0aGUgZW5kIG9mIHRoZSB0ZXh0YmxvY2tcbiAgICAgICAgLy8gbm9kZSBhZnRlciBgdGhpcy4kdG9gLCBub3QgYHRoaXMuJHRvYCBpdHNlbGYuXG4gICAgICAgIGxldCBtb3ZlSW5saW5lID0gdGhpcy5tdXN0TW92ZUlubGluZSgpLCBwbGFjZWRTaXplID0gdGhpcy5wbGFjZWQuc2l6ZSAtIHRoaXMuZGVwdGggLSB0aGlzLiRmcm9tLmRlcHRoO1xuICAgICAgICBsZXQgJGZyb20gPSB0aGlzLiRmcm9tLCAkdG8gPSB0aGlzLmNsb3NlKG1vdmVJbmxpbmUgPCAwID8gdGhpcy4kdG8gOiAkZnJvbS5kb2MucmVzb2x2ZShtb3ZlSW5saW5lKSk7XG4gICAgICAgIGlmICghJHRvKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIC8vIElmIGNsb3NpbmcgdG8gYCR0b2Agc3VjY2VlZGVkLCBjcmVhdGUgYSBzdGVwXG4gICAgICAgIGxldCBjb250ZW50ID0gdGhpcy5wbGFjZWQsIG9wZW5TdGFydCA9ICRmcm9tLmRlcHRoLCBvcGVuRW5kID0gJHRvLmRlcHRoO1xuICAgICAgICB3aGlsZSAob3BlblN0YXJ0ICYmIG9wZW5FbmQgJiYgY29udGVudC5jaGlsZENvdW50ID09IDEpIHsgLy8gTm9ybWFsaXplIGJ5IGRyb3BwaW5nIG9wZW4gcGFyZW50IG5vZGVzXG4gICAgICAgICAgICBjb250ZW50ID0gY29udGVudC5maXJzdENoaWxkLmNvbnRlbnQ7XG4gICAgICAgICAgICBvcGVuU3RhcnQtLTtcbiAgICAgICAgICAgIG9wZW5FbmQtLTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc2xpY2UgPSBuZXcgU2xpY2UoY29udGVudCwgb3BlblN0YXJ0LCBvcGVuRW5kKTtcbiAgICAgICAgaWYgKG1vdmVJbmxpbmUgPiAtMSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVwbGFjZUFyb3VuZFN0ZXAoJGZyb20ucG9zLCBtb3ZlSW5saW5lLCB0aGlzLiR0by5wb3MsIHRoaXMuJHRvLmVuZCgpLCBzbGljZSwgcGxhY2VkU2l6ZSk7XG4gICAgICAgIGlmIChzbGljZS5zaXplIHx8ICRmcm9tLnBvcyAhPSB0aGlzLiR0by5wb3MpIC8vIERvbid0IGdlbmVyYXRlIG5vLW9wIHN0ZXBzXG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VTdGVwKCRmcm9tLnBvcywgJHRvLnBvcywgc2xpY2UpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gRmluZCBhIHBvc2l0aW9uIG9uIHRoZSBzdGFydCBzcGluZSBvZiBgdGhpcy51bnBsYWNlZGAgdGhhdCBoYXNcbiAgICAvLyBjb250ZW50IHRoYXQgY2FuIGJlIG1vdmVkIHNvbWV3aGVyZSBvbiB0aGUgZnJvbnRpZXIuIFJldHVybnMgdHdvXG4gICAgLy8gZGVwdGhzLCBvbmUgZm9yIHRoZSBzbGljZSBhbmQgb25lIGZvciB0aGUgZnJvbnRpZXIuXG4gICAgZmluZEZpdHRhYmxlKCkge1xuICAgICAgICBsZXQgc3RhcnREZXB0aCA9IHRoaXMudW5wbGFjZWQub3BlblN0YXJ0O1xuICAgICAgICBmb3IgKGxldCBjdXIgPSB0aGlzLnVucGxhY2VkLmNvbnRlbnQsIGQgPSAwLCBvcGVuRW5kID0gdGhpcy51bnBsYWNlZC5vcGVuRW5kOyBkIDwgc3RhcnREZXB0aDsgZCsrKSB7XG4gICAgICAgICAgICBsZXQgbm9kZSA9IGN1ci5maXJzdENoaWxkO1xuICAgICAgICAgICAgaWYgKGN1ci5jaGlsZENvdW50ID4gMSlcbiAgICAgICAgICAgICAgICBvcGVuRW5kID0gMDtcbiAgICAgICAgICAgIGlmIChub2RlLnR5cGUuc3BlYy5pc29sYXRpbmcgJiYgb3BlbkVuZCA8PSBkKSB7XG4gICAgICAgICAgICAgICAgc3RhcnREZXB0aCA9IGQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXIgPSBub2RlLmNvbnRlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT25seSB0cnkgd3JhcHBpbmcgbm9kZXMgKHBhc3MgMikgYWZ0ZXIgZmluZGluZyBhIHBsYWNlIHdpdGhvdXRcbiAgICAgICAgLy8gd3JhcHBpbmcgZmFpbGVkLlxuICAgICAgICBmb3IgKGxldCBwYXNzID0gMTsgcGFzcyA8PSAyOyBwYXNzKyspIHtcbiAgICAgICAgICAgIGZvciAobGV0IHNsaWNlRGVwdGggPSBwYXNzID09IDEgPyBzdGFydERlcHRoIDogdGhpcy51bnBsYWNlZC5vcGVuU3RhcnQ7IHNsaWNlRGVwdGggPj0gMDsgc2xpY2VEZXB0aC0tKSB7XG4gICAgICAgICAgICAgICAgbGV0IGZyYWdtZW50LCBwYXJlbnQgPSBudWxsO1xuICAgICAgICAgICAgICAgIGlmIChzbGljZURlcHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IGNvbnRlbnRBdCh0aGlzLnVucGxhY2VkLmNvbnRlbnQsIHNsaWNlRGVwdGggLSAxKS5maXJzdENoaWxkO1xuICAgICAgICAgICAgICAgICAgICBmcmFnbWVudCA9IHBhcmVudC5jb250ZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZnJhZ21lbnQgPSB0aGlzLnVucGxhY2VkLmNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBmaXJzdCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZnJvbnRpZXJEZXB0aCA9IHRoaXMuZGVwdGg7IGZyb250aWVyRGVwdGggPj0gMDsgZnJvbnRpZXJEZXB0aC0tKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB7IHR5cGUsIG1hdGNoIH0gPSB0aGlzLmZyb250aWVyW2Zyb250aWVyRGVwdGhdLCB3cmFwLCBpbmplY3QgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAvLyBJbiBwYXNzIDEsIGlmIHRoZSBuZXh0IG5vZGUgbWF0Y2hlcywgb3IgdGhlcmUgaXMgbm8gbmV4dFxuICAgICAgICAgICAgICAgICAgICAvLyBub2RlIGJ1dCB0aGUgcGFyZW50cyBsb29rIGNvbXBhdGlibGUsIHdlJ3ZlIGZvdW5kIGFcbiAgICAgICAgICAgICAgICAgICAgLy8gcGxhY2UuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXNzID09IDEgJiYgKGZpcnN0ID8gbWF0Y2gubWF0Y2hUeXBlKGZpcnN0LnR5cGUpIHx8IChpbmplY3QgPSBtYXRjaC5maWxsQmVmb3JlKEZyYWdtZW50LmZyb20oZmlyc3QpLCBmYWxzZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHBhcmVudCAmJiB0eXBlLmNvbXBhdGlibGVDb250ZW50KHBhcmVudC50eXBlKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBzbGljZURlcHRoLCBmcm9udGllckRlcHRoLCBwYXJlbnQsIGluamVjdCB9O1xuICAgICAgICAgICAgICAgICAgICAvLyBJbiBwYXNzIDIsIGxvb2sgZm9yIGEgc2V0IG9mIHdyYXBwaW5nIG5vZGVzIHRoYXQgbWFrZVxuICAgICAgICAgICAgICAgICAgICAvLyBgZmlyc3RgIGZpdCBoZXJlLlxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwYXNzID09IDIgJiYgZmlyc3QgJiYgKHdyYXAgPSBtYXRjaC5maW5kV3JhcHBpbmcoZmlyc3QudHlwZSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgc2xpY2VEZXB0aCwgZnJvbnRpZXJEZXB0aCwgcGFyZW50LCB3cmFwIH07XG4gICAgICAgICAgICAgICAgICAgIC8vIERvbid0IGNvbnRpbnVlIGxvb2tpbmcgZnVydGhlciB1cCBpZiB0aGUgcGFyZW50IG5vZGVcbiAgICAgICAgICAgICAgICAgICAgLy8gd291bGQgZml0IGhlcmUuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgJiYgbWF0Y2gubWF0Y2hUeXBlKHBhcmVudC50eXBlKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBvcGVuTW9yZSgpIHtcbiAgICAgICAgbGV0IHsgY29udGVudCwgb3BlblN0YXJ0LCBvcGVuRW5kIH0gPSB0aGlzLnVucGxhY2VkO1xuICAgICAgICBsZXQgaW5uZXIgPSBjb250ZW50QXQoY29udGVudCwgb3BlblN0YXJ0KTtcbiAgICAgICAgaWYgKCFpbm5lci5jaGlsZENvdW50IHx8IGlubmVyLmZpcnN0Q2hpbGQuaXNMZWFmKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB0aGlzLnVucGxhY2VkID0gbmV3IFNsaWNlKGNvbnRlbnQsIG9wZW5TdGFydCArIDEsIE1hdGgubWF4KG9wZW5FbmQsIGlubmVyLnNpemUgKyBvcGVuU3RhcnQgPj0gY29udGVudC5zaXplIC0gb3BlbkVuZCA/IG9wZW5TdGFydCArIDEgOiAwKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBkcm9wTm9kZSgpIHtcbiAgICAgICAgbGV0IHsgY29udGVudCwgb3BlblN0YXJ0LCBvcGVuRW5kIH0gPSB0aGlzLnVucGxhY2VkO1xuICAgICAgICBsZXQgaW5uZXIgPSBjb250ZW50QXQoY29udGVudCwgb3BlblN0YXJ0KTtcbiAgICAgICAgaWYgKGlubmVyLmNoaWxkQ291bnQgPD0gMSAmJiBvcGVuU3RhcnQgPiAwKSB7XG4gICAgICAgICAgICBsZXQgb3BlbkF0RW5kID0gY29udGVudC5zaXplIC0gb3BlblN0YXJ0IDw9IG9wZW5TdGFydCArIGlubmVyLnNpemU7XG4gICAgICAgICAgICB0aGlzLnVucGxhY2VkID0gbmV3IFNsaWNlKGRyb3BGcm9tRnJhZ21lbnQoY29udGVudCwgb3BlblN0YXJ0IC0gMSwgMSksIG9wZW5TdGFydCAtIDEsIG9wZW5BdEVuZCA/IG9wZW5TdGFydCAtIDEgOiBvcGVuRW5kKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudW5wbGFjZWQgPSBuZXcgU2xpY2UoZHJvcEZyb21GcmFnbWVudChjb250ZW50LCBvcGVuU3RhcnQsIDEpLCBvcGVuU3RhcnQsIG9wZW5FbmQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIE1vdmUgY29udGVudCBmcm9tIHRoZSB1bnBsYWNlZCBzbGljZSBhdCBgc2xpY2VEZXB0aGAgdG8gdGhlXG4gICAgLy8gZnJvbnRpZXIgbm9kZSBhdCBgZnJvbnRpZXJEZXB0aGAuIENsb3NlIHRoYXQgZnJvbnRpZXIgbm9kZSB3aGVuXG4gICAgLy8gYXBwbGljYWJsZS5cbiAgICBwbGFjZU5vZGVzKHsgc2xpY2VEZXB0aCwgZnJvbnRpZXJEZXB0aCwgcGFyZW50LCBpbmplY3QsIHdyYXAgfSkge1xuICAgICAgICB3aGlsZSAodGhpcy5kZXB0aCA+IGZyb250aWVyRGVwdGgpXG4gICAgICAgICAgICB0aGlzLmNsb3NlRnJvbnRpZXJOb2RlKCk7XG4gICAgICAgIGlmICh3cmFwKVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB3cmFwLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIHRoaXMub3BlbkZyb250aWVyTm9kZSh3cmFwW2ldKTtcbiAgICAgICAgbGV0IHNsaWNlID0gdGhpcy51bnBsYWNlZCwgZnJhZ21lbnQgPSBwYXJlbnQgPyBwYXJlbnQuY29udGVudCA6IHNsaWNlLmNvbnRlbnQ7XG4gICAgICAgIGxldCBvcGVuU3RhcnQgPSBzbGljZS5vcGVuU3RhcnQgLSBzbGljZURlcHRoO1xuICAgICAgICBsZXQgdGFrZW4gPSAwLCBhZGQgPSBbXTtcbiAgICAgICAgbGV0IHsgbWF0Y2gsIHR5cGUgfSA9IHRoaXMuZnJvbnRpZXJbZnJvbnRpZXJEZXB0aF07XG4gICAgICAgIGlmIChpbmplY3QpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5qZWN0LmNoaWxkQ291bnQ7IGkrKylcbiAgICAgICAgICAgICAgICBhZGQucHVzaChpbmplY3QuY2hpbGQoaSkpO1xuICAgICAgICAgICAgbWF0Y2ggPSBtYXRjaC5tYXRjaEZyYWdtZW50KGluamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ29tcHV0ZXMgdGhlIGFtb3VudCBvZiAoZW5kKSBvcGVuIG5vZGVzIGF0IHRoZSBlbmQgb2YgdGhlXG4gICAgICAgIC8vIGZyYWdtZW50LiBXaGVuIDAsIHRoZSBwYXJlbnQgaXMgb3BlbiwgYnV0IG5vIG1vcmUuIFdoZW5cbiAgICAgICAgLy8gbmVnYXRpdmUsIG5vdGhpbmcgaXMgb3Blbi5cbiAgICAgICAgbGV0IG9wZW5FbmRDb3VudCA9IChmcmFnbWVudC5zaXplICsgc2xpY2VEZXB0aCkgLSAoc2xpY2UuY29udGVudC5zaXplIC0gc2xpY2Uub3BlbkVuZCk7XG4gICAgICAgIC8vIFNjYW4gb3ZlciB0aGUgZnJhZ21lbnQsIGZpdHRpbmcgYXMgbWFueSBjaGlsZCBub2RlcyBhc1xuICAgICAgICAvLyBwb3NzaWJsZS5cbiAgICAgICAgd2hpbGUgKHRha2VuIDwgZnJhZ21lbnQuY2hpbGRDb3VudCkge1xuICAgICAgICAgICAgbGV0IG5leHQgPSBmcmFnbWVudC5jaGlsZCh0YWtlbiksIG1hdGNoZXMgPSBtYXRjaC5tYXRjaFR5cGUobmV4dC50eXBlKTtcbiAgICAgICAgICAgIGlmICghbWF0Y2hlcylcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIHRha2VuKys7XG4gICAgICAgICAgICBpZiAodGFrZW4gPiAxIHx8IG9wZW5TdGFydCA9PSAwIHx8IG5leHQuY29udGVudC5zaXplKSB7IC8vIERyb3AgZW1wdHkgb3BlbiBub2Rlc1xuICAgICAgICAgICAgICAgIG1hdGNoID0gbWF0Y2hlcztcbiAgICAgICAgICAgICAgICBhZGQucHVzaChjbG9zZU5vZGVTdGFydChuZXh0Lm1hcmsodHlwZS5hbGxvd2VkTWFya3MobmV4dC5tYXJrcykpLCB0YWtlbiA9PSAxID8gb3BlblN0YXJ0IDogMCwgdGFrZW4gPT0gZnJhZ21lbnQuY2hpbGRDb3VudCA/IG9wZW5FbmRDb3VudCA6IC0xKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHRvRW5kID0gdGFrZW4gPT0gZnJhZ21lbnQuY2hpbGRDb3VudDtcbiAgICAgICAgaWYgKCF0b0VuZClcbiAgICAgICAgICAgIG9wZW5FbmRDb3VudCA9IC0xO1xuICAgICAgICB0aGlzLnBsYWNlZCA9IGFkZFRvRnJhZ21lbnQodGhpcy5wbGFjZWQsIGZyb250aWVyRGVwdGgsIEZyYWdtZW50LmZyb20oYWRkKSk7XG4gICAgICAgIHRoaXMuZnJvbnRpZXJbZnJvbnRpZXJEZXB0aF0ubWF0Y2ggPSBtYXRjaDtcbiAgICAgICAgLy8gSWYgdGhlIHBhcmVudCB0eXBlcyBtYXRjaCwgYW5kIHRoZSBlbnRpcmUgbm9kZSB3YXMgbW92ZWQsIGFuZFxuICAgICAgICAvLyBpdCdzIG5vdCBvcGVuLCBjbG9zZSB0aGlzIGZyb250aWVyIG5vZGUgcmlnaHQgYXdheS5cbiAgICAgICAgaWYgKHRvRW5kICYmIG9wZW5FbmRDb3VudCA8IDAgJiYgcGFyZW50ICYmIHBhcmVudC50eXBlID09IHRoaXMuZnJvbnRpZXJbdGhpcy5kZXB0aF0udHlwZSAmJiB0aGlzLmZyb250aWVyLmxlbmd0aCA+IDEpXG4gICAgICAgICAgICB0aGlzLmNsb3NlRnJvbnRpZXJOb2RlKCk7XG4gICAgICAgIC8vIEFkZCBuZXcgZnJvbnRpZXIgbm9kZXMgZm9yIGFueSBvcGVuIG5vZGVzIGF0IHRoZSBlbmQuXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBjdXIgPSBmcmFnbWVudDsgaSA8IG9wZW5FbmRDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbm9kZSA9IGN1ci5sYXN0Q2hpbGQ7XG4gICAgICAgICAgICB0aGlzLmZyb250aWVyLnB1c2goeyB0eXBlOiBub2RlLnR5cGUsIG1hdGNoOiBub2RlLmNvbnRlbnRNYXRjaEF0KG5vZGUuY2hpbGRDb3VudCkgfSk7XG4gICAgICAgICAgICBjdXIgPSBub2RlLmNvbnRlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVXBkYXRlIGB0aGlzLnVucGxhY2VkYC4gRHJvcCB0aGUgZW50aXJlIG5vZGUgZnJvbSB3aGljaCB3ZVxuICAgICAgICAvLyBwbGFjZWQgaXQgd2UgZ290IHRvIGl0cyBlbmQsIG90aGVyd2lzZSBqdXN0IGRyb3AgdGhlIHBsYWNlZFxuICAgICAgICAvLyBub2Rlcy5cbiAgICAgICAgdGhpcy51bnBsYWNlZCA9ICF0b0VuZCA/IG5ldyBTbGljZShkcm9wRnJvbUZyYWdtZW50KHNsaWNlLmNvbnRlbnQsIHNsaWNlRGVwdGgsIHRha2VuKSwgc2xpY2Uub3BlblN0YXJ0LCBzbGljZS5vcGVuRW5kKVxuICAgICAgICAgICAgOiBzbGljZURlcHRoID09IDAgPyBTbGljZS5lbXB0eVxuICAgICAgICAgICAgICAgIDogbmV3IFNsaWNlKGRyb3BGcm9tRnJhZ21lbnQoc2xpY2UuY29udGVudCwgc2xpY2VEZXB0aCAtIDEsIDEpLCBzbGljZURlcHRoIC0gMSwgb3BlbkVuZENvdW50IDwgMCA/IHNsaWNlLm9wZW5FbmQgOiBzbGljZURlcHRoIC0gMSk7XG4gICAgfVxuICAgIG11c3RNb3ZlSW5saW5lKCkge1xuICAgICAgICBpZiAoIXRoaXMuJHRvLnBhcmVudC5pc1RleHRibG9jaylcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgbGV0IHRvcCA9IHRoaXMuZnJvbnRpZXJbdGhpcy5kZXB0aF0sIGxldmVsO1xuICAgICAgICBpZiAoIXRvcC50eXBlLmlzVGV4dGJsb2NrIHx8ICFjb250ZW50QWZ0ZXJGaXRzKHRoaXMuJHRvLCB0aGlzLiR0by5kZXB0aCwgdG9wLnR5cGUsIHRvcC5tYXRjaCwgZmFsc2UpIHx8XG4gICAgICAgICAgICAodGhpcy4kdG8uZGVwdGggPT0gdGhpcy5kZXB0aCAmJiAobGV2ZWwgPSB0aGlzLmZpbmRDbG9zZUxldmVsKHRoaXMuJHRvKSkgJiYgbGV2ZWwuZGVwdGggPT0gdGhpcy5kZXB0aCkpXG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIGxldCB7IGRlcHRoIH0gPSB0aGlzLiR0bywgYWZ0ZXIgPSB0aGlzLiR0by5hZnRlcihkZXB0aCk7XG4gICAgICAgIHdoaWxlIChkZXB0aCA+IDEgJiYgYWZ0ZXIgPT0gdGhpcy4kdG8uZW5kKC0tZGVwdGgpKVxuICAgICAgICAgICAgKythZnRlcjtcbiAgICAgICAgcmV0dXJuIGFmdGVyO1xuICAgIH1cbiAgICBmaW5kQ2xvc2VMZXZlbCgkdG8pIHtcbiAgICAgICAgc2NhbjogZm9yIChsZXQgaSA9IE1hdGgubWluKHRoaXMuZGVwdGgsICR0by5kZXB0aCk7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgeyBtYXRjaCwgdHlwZSB9ID0gdGhpcy5mcm9udGllcltpXTtcbiAgICAgICAgICAgIGxldCBkcm9wSW5uZXIgPSBpIDwgJHRvLmRlcHRoICYmICR0by5lbmQoaSArIDEpID09ICR0by5wb3MgKyAoJHRvLmRlcHRoIC0gKGkgKyAxKSk7XG4gICAgICAgICAgICBsZXQgZml0ID0gY29udGVudEFmdGVyRml0cygkdG8sIGksIHR5cGUsIG1hdGNoLCBkcm9wSW5uZXIpO1xuICAgICAgICAgICAgaWYgKCFmaXQpXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICBmb3IgKGxldCBkID0gaSAtIDE7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgICAgICAgICAgbGV0IHsgbWF0Y2gsIHR5cGUgfSA9IHRoaXMuZnJvbnRpZXJbZF07XG4gICAgICAgICAgICAgICAgbGV0IG1hdGNoZXMgPSBjb250ZW50QWZ0ZXJGaXRzKCR0bywgZCwgdHlwZSwgbWF0Y2gsIHRydWUpO1xuICAgICAgICAgICAgICAgIGlmICghbWF0Y2hlcyB8fCBtYXRjaGVzLmNoaWxkQ291bnQpXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHNjYW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4geyBkZXB0aDogaSwgZml0LCBtb3ZlOiBkcm9wSW5uZXIgPyAkdG8uZG9jLnJlc29sdmUoJHRvLmFmdGVyKGkgKyAxKSkgOiAkdG8gfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjbG9zZSgkdG8pIHtcbiAgICAgICAgbGV0IGNsb3NlID0gdGhpcy5maW5kQ2xvc2VMZXZlbCgkdG8pO1xuICAgICAgICBpZiAoIWNsb3NlKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHdoaWxlICh0aGlzLmRlcHRoID4gY2xvc2UuZGVwdGgpXG4gICAgICAgICAgICB0aGlzLmNsb3NlRnJvbnRpZXJOb2RlKCk7XG4gICAgICAgIGlmIChjbG9zZS5maXQuY2hpbGRDb3VudClcbiAgICAgICAgICAgIHRoaXMucGxhY2VkID0gYWRkVG9GcmFnbWVudCh0aGlzLnBsYWNlZCwgY2xvc2UuZGVwdGgsIGNsb3NlLmZpdCk7XG4gICAgICAgICR0byA9IGNsb3NlLm1vdmU7XG4gICAgICAgIGZvciAobGV0IGQgPSBjbG9zZS5kZXB0aCArIDE7IGQgPD0gJHRvLmRlcHRoOyBkKyspIHtcbiAgICAgICAgICAgIGxldCBub2RlID0gJHRvLm5vZGUoZCksIGFkZCA9IG5vZGUudHlwZS5jb250ZW50TWF0Y2guZmlsbEJlZm9yZShub2RlLmNvbnRlbnQsIHRydWUsICR0by5pbmRleChkKSk7XG4gICAgICAgICAgICB0aGlzLm9wZW5Gcm9udGllck5vZGUobm9kZS50eXBlLCBub2RlLmF0dHJzLCBhZGQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAkdG87XG4gICAgfVxuICAgIG9wZW5Gcm9udGllck5vZGUodHlwZSwgYXR0cnMgPSBudWxsLCBjb250ZW50KSB7XG4gICAgICAgIGxldCB0b3AgPSB0aGlzLmZyb250aWVyW3RoaXMuZGVwdGhdO1xuICAgICAgICB0b3AubWF0Y2ggPSB0b3AubWF0Y2gubWF0Y2hUeXBlKHR5cGUpO1xuICAgICAgICB0aGlzLnBsYWNlZCA9IGFkZFRvRnJhZ21lbnQodGhpcy5wbGFjZWQsIHRoaXMuZGVwdGgsIEZyYWdtZW50LmZyb20odHlwZS5jcmVhdGUoYXR0cnMsIGNvbnRlbnQpKSk7XG4gICAgICAgIHRoaXMuZnJvbnRpZXIucHVzaCh7IHR5cGUsIG1hdGNoOiB0eXBlLmNvbnRlbnRNYXRjaCB9KTtcbiAgICB9XG4gICAgY2xvc2VGcm9udGllck5vZGUoKSB7XG4gICAgICAgIGxldCBvcGVuID0gdGhpcy5mcm9udGllci5wb3AoKTtcbiAgICAgICAgbGV0IGFkZCA9IG9wZW4ubWF0Y2guZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSk7XG4gICAgICAgIGlmIChhZGQuY2hpbGRDb3VudClcbiAgICAgICAgICAgIHRoaXMucGxhY2VkID0gYWRkVG9GcmFnbWVudCh0aGlzLnBsYWNlZCwgdGhpcy5mcm9udGllci5sZW5ndGgsIGFkZCk7XG4gICAgfVxufVxuZnVuY3Rpb24gZHJvcEZyb21GcmFnbWVudChmcmFnbWVudCwgZGVwdGgsIGNvdW50KSB7XG4gICAgaWYgKGRlcHRoID09IDApXG4gICAgICAgIHJldHVybiBmcmFnbWVudC5jdXRCeUluZGV4KGNvdW50LCBmcmFnbWVudC5jaGlsZENvdW50KTtcbiAgICByZXR1cm4gZnJhZ21lbnQucmVwbGFjZUNoaWxkKDAsIGZyYWdtZW50LmZpcnN0Q2hpbGQuY29weShkcm9wRnJvbUZyYWdtZW50KGZyYWdtZW50LmZpcnN0Q2hpbGQuY29udGVudCwgZGVwdGggLSAxLCBjb3VudCkpKTtcbn1cbmZ1bmN0aW9uIGFkZFRvRnJhZ21lbnQoZnJhZ21lbnQsIGRlcHRoLCBjb250ZW50KSB7XG4gICAgaWYgKGRlcHRoID09IDApXG4gICAgICAgIHJldHVybiBmcmFnbWVudC5hcHBlbmQoY29udGVudCk7XG4gICAgcmV0dXJuIGZyYWdtZW50LnJlcGxhY2VDaGlsZChmcmFnbWVudC5jaGlsZENvdW50IC0gMSwgZnJhZ21lbnQubGFzdENoaWxkLmNvcHkoYWRkVG9GcmFnbWVudChmcmFnbWVudC5sYXN0Q2hpbGQuY29udGVudCwgZGVwdGggLSAxLCBjb250ZW50KSkpO1xufVxuZnVuY3Rpb24gY29udGVudEF0KGZyYWdtZW50LCBkZXB0aCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVwdGg7IGkrKylcbiAgICAgICAgZnJhZ21lbnQgPSBmcmFnbWVudC5maXJzdENoaWxkLmNvbnRlbnQ7XG4gICAgcmV0dXJuIGZyYWdtZW50O1xufVxuZnVuY3Rpb24gY2xvc2VOb2RlU3RhcnQobm9kZSwgb3BlblN0YXJ0LCBvcGVuRW5kKSB7XG4gICAgaWYgKG9wZW5TdGFydCA8PSAwKVxuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICBsZXQgZnJhZyA9IG5vZGUuY29udGVudDtcbiAgICBpZiAob3BlblN0YXJ0ID4gMSlcbiAgICAgICAgZnJhZyA9IGZyYWcucmVwbGFjZUNoaWxkKDAsIGNsb3NlTm9kZVN0YXJ0KGZyYWcuZmlyc3RDaGlsZCwgb3BlblN0YXJ0IC0gMSwgZnJhZy5jaGlsZENvdW50ID09IDEgPyBvcGVuRW5kIC0gMSA6IDApKTtcbiAgICBpZiAob3BlblN0YXJ0ID4gMCkge1xuICAgICAgICBmcmFnID0gbm9kZS50eXBlLmNvbnRlbnRNYXRjaC5maWxsQmVmb3JlKGZyYWcpLmFwcGVuZChmcmFnKTtcbiAgICAgICAgaWYgKG9wZW5FbmQgPD0gMClcbiAgICAgICAgICAgIGZyYWcgPSBmcmFnLmFwcGVuZChub2RlLnR5cGUuY29udGVudE1hdGNoLm1hdGNoRnJhZ21lbnQoZnJhZykuZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZS5jb3B5KGZyYWcpO1xufVxuZnVuY3Rpb24gY29udGVudEFmdGVyRml0cygkdG8sIGRlcHRoLCB0eXBlLCBtYXRjaCwgb3Blbikge1xuICAgIGxldCBub2RlID0gJHRvLm5vZGUoZGVwdGgpLCBpbmRleCA9IG9wZW4gPyAkdG8uaW5kZXhBZnRlcihkZXB0aCkgOiAkdG8uaW5kZXgoZGVwdGgpO1xuICAgIGlmIChpbmRleCA9PSBub2RlLmNoaWxkQ291bnQgJiYgIXR5cGUuY29tcGF0aWJsZUNvbnRlbnQobm9kZS50eXBlKSlcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgbGV0IGZpdCA9IG1hdGNoLmZpbGxCZWZvcmUobm9kZS5jb250ZW50LCB0cnVlLCBpbmRleCk7XG4gICAgcmV0dXJuIGZpdCAmJiAhaW52YWxpZE1hcmtzKHR5cGUsIG5vZGUuY29udGVudCwgaW5kZXgpID8gZml0IDogbnVsbDtcbn1cbmZ1bmN0aW9uIGludmFsaWRNYXJrcyh0eXBlLCBmcmFnbWVudCwgc3RhcnQpIHtcbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBmcmFnbWVudC5jaGlsZENvdW50OyBpKyspXG4gICAgICAgIGlmICghdHlwZS5hbGxvd3NNYXJrcyhmcmFnbWVudC5jaGlsZChpKS5tYXJrcykpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBkZWZpbmVzQ29udGVudCh0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUuc3BlYy5kZWZpbmluZyB8fCB0eXBlLnNwZWMuZGVmaW5pbmdGb3JDb250ZW50O1xufVxuZnVuY3Rpb24gcmVwbGFjZVJhbmdlKHRyLCBmcm9tLCB0bywgc2xpY2UpIHtcbiAgICBpZiAoIXNsaWNlLnNpemUpXG4gICAgICAgIHJldHVybiB0ci5kZWxldGVSYW5nZShmcm9tLCB0byk7XG4gICAgbGV0ICRmcm9tID0gdHIuZG9jLnJlc29sdmUoZnJvbSksICR0byA9IHRyLmRvYy5yZXNvbHZlKHRvKTtcbiAgICBpZiAoZml0c1RyaXZpYWxseSgkZnJvbSwgJHRvLCBzbGljZSkpXG4gICAgICAgIHJldHVybiB0ci5zdGVwKG5ldyBSZXBsYWNlU3RlcChmcm9tLCB0bywgc2xpY2UpKTtcbiAgICBsZXQgdGFyZ2V0RGVwdGhzID0gY292ZXJlZERlcHRocygkZnJvbSwgJHRvKTtcbiAgICAvLyBDYW4ndCByZXBsYWNlIHRoZSB3aG9sZSBkb2N1bWVudCwgc28gcmVtb3ZlIDAgaWYgaXQncyBwcmVzZW50XG4gICAgaWYgKHRhcmdldERlcHRoc1t0YXJnZXREZXB0aHMubGVuZ3RoIC0gMV0gPT0gMClcbiAgICAgICAgdGFyZ2V0RGVwdGhzLnBvcCgpO1xuICAgIC8vIE5lZ2F0aXZlIG51bWJlcnMgcmVwcmVzZW50IG5vdCBleHBhbnNpb24gb3ZlciB0aGUgd2hvbGUgbm9kZSBhdFxuICAgIC8vIHRoYXQgZGVwdGgsIGJ1dCByZXBsYWNpbmcgZnJvbSAkZnJvbS5iZWZvcmUoLUQpIHRvICR0by5wb3MuXG4gICAgbGV0IHByZWZlcnJlZFRhcmdldCA9IC0oJGZyb20uZGVwdGggKyAxKTtcbiAgICB0YXJnZXREZXB0aHMudW5zaGlmdChwcmVmZXJyZWRUYXJnZXQpO1xuICAgIC8vIFRoaXMgbG9vcCBwaWNrcyBhIHByZWZlcnJlZCB0YXJnZXQgZGVwdGgsIGlmIG9uZSBvZiB0aGUgY292ZXJpbmdcbiAgICAvLyBkZXB0aHMgaXMgbm90IG91dHNpZGUgb2YgYSBkZWZpbmluZyBub2RlLCBhbmQgYWRkcyBuZWdhdGl2ZVxuICAgIC8vIGRlcHRocyBmb3IgYW55IGRlcHRoIHRoYXQgaGFzICRmcm9tIGF0IGl0cyBzdGFydCBhbmQgZG9lcyBub3RcbiAgICAvLyBjcm9zcyBhIGRlZmluaW5nIG5vZGUuXG4gICAgZm9yIChsZXQgZCA9ICRmcm9tLmRlcHRoLCBwb3MgPSAkZnJvbS5wb3MgLSAxOyBkID4gMDsgZC0tLCBwb3MtLSkge1xuICAgICAgICBsZXQgc3BlYyA9ICRmcm9tLm5vZGUoZCkudHlwZS5zcGVjO1xuICAgICAgICBpZiAoc3BlYy5kZWZpbmluZyB8fCBzcGVjLmRlZmluaW5nQXNDb250ZXh0IHx8IHNwZWMuaXNvbGF0aW5nKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGlmICh0YXJnZXREZXB0aHMuaW5kZXhPZihkKSA+IC0xKVxuICAgICAgICAgICAgcHJlZmVycmVkVGFyZ2V0ID0gZDtcbiAgICAgICAgZWxzZSBpZiAoJGZyb20uYmVmb3JlKGQpID09IHBvcylcbiAgICAgICAgICAgIHRhcmdldERlcHRocy5zcGxpY2UoMSwgMCwgLWQpO1xuICAgIH1cbiAgICAvLyBUcnkgdG8gZml0IGVhY2ggcG9zc2libGUgZGVwdGggb2YgdGhlIHNsaWNlIGludG8gZWFjaCBwb3NzaWJsZVxuICAgIC8vIHRhcmdldCBkZXB0aCwgc3RhcnRpbmcgd2l0aCB0aGUgcHJlZmVycmVkIGRlcHRocy5cbiAgICBsZXQgcHJlZmVycmVkVGFyZ2V0SW5kZXggPSB0YXJnZXREZXB0aHMuaW5kZXhPZihwcmVmZXJyZWRUYXJnZXQpO1xuICAgIGxldCBsZWZ0Tm9kZXMgPSBbXSwgcHJlZmVycmVkRGVwdGggPSBzbGljZS5vcGVuU3RhcnQ7XG4gICAgZm9yIChsZXQgY29udGVudCA9IHNsaWNlLmNvbnRlbnQsIGkgPSAwOzsgaSsrKSB7XG4gICAgICAgIGxldCBub2RlID0gY29udGVudC5maXJzdENoaWxkO1xuICAgICAgICBsZWZ0Tm9kZXMucHVzaChub2RlKTtcbiAgICAgICAgaWYgKGkgPT0gc2xpY2Uub3BlblN0YXJ0KVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNvbnRlbnQgPSBub2RlLmNvbnRlbnQ7XG4gICAgfVxuICAgIC8vIEJhY2sgdXAgcHJlZmVycmVkRGVwdGggdG8gY292ZXIgZGVmaW5pbmcgdGV4dGJsb2NrcyBkaXJlY3RseVxuICAgIC8vIGFib3ZlIGl0LCBwb3NzaWJseSBza2lwcGluZyBhIG5vbi1kZWZpbmluZyB0ZXh0YmxvY2suXG4gICAgZm9yIChsZXQgZCA9IHByZWZlcnJlZERlcHRoIC0gMTsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgbGV0IGxlZnROb2RlID0gbGVmdE5vZGVzW2RdLCBkZWYgPSBkZWZpbmVzQ29udGVudChsZWZ0Tm9kZS50eXBlKTtcbiAgICAgICAgaWYgKGRlZiAmJiAhbGVmdE5vZGUuc2FtZU1hcmt1cCgkZnJvbS5ub2RlKE1hdGguYWJzKHByZWZlcnJlZFRhcmdldCkgLSAxKSkpXG4gICAgICAgICAgICBwcmVmZXJyZWREZXB0aCA9IGQ7XG4gICAgICAgIGVsc2UgaWYgKGRlZiB8fCAhbGVmdE5vZGUudHlwZS5pc1RleHRibG9jaylcbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBmb3IgKGxldCBqID0gc2xpY2Uub3BlblN0YXJ0OyBqID49IDA7IGotLSkge1xuICAgICAgICBsZXQgb3BlbkRlcHRoID0gKGogKyBwcmVmZXJyZWREZXB0aCArIDEpICUgKHNsaWNlLm9wZW5TdGFydCArIDEpO1xuICAgICAgICBsZXQgaW5zZXJ0ID0gbGVmdE5vZGVzW29wZW5EZXB0aF07XG4gICAgICAgIGlmICghaW5zZXJ0KVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGFyZ2V0RGVwdGhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAvLyBMb29wIG92ZXIgcG9zc2libGUgZXhwYW5zaW9uIGxldmVscywgc3RhcnRpbmcgd2l0aCB0aGVcbiAgICAgICAgICAgIC8vIHByZWZlcnJlZCBvbmVcbiAgICAgICAgICAgIGxldCB0YXJnZXREZXB0aCA9IHRhcmdldERlcHRoc1soaSArIHByZWZlcnJlZFRhcmdldEluZGV4KSAlIHRhcmdldERlcHRocy5sZW5ndGhdLCBleHBhbmQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHRhcmdldERlcHRoIDwgMCkge1xuICAgICAgICAgICAgICAgIGV4cGFuZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRhcmdldERlcHRoID0gLXRhcmdldERlcHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHBhcmVudCA9ICRmcm9tLm5vZGUodGFyZ2V0RGVwdGggLSAxKSwgaW5kZXggPSAkZnJvbS5pbmRleCh0YXJnZXREZXB0aCAtIDEpO1xuICAgICAgICAgICAgaWYgKHBhcmVudC5jYW5SZXBsYWNlV2l0aChpbmRleCwgaW5kZXgsIGluc2VydC50eXBlLCBpbnNlcnQubWFya3MpKVxuICAgICAgICAgICAgICAgIHJldHVybiB0ci5yZXBsYWNlKCRmcm9tLmJlZm9yZSh0YXJnZXREZXB0aCksIGV4cGFuZCA/ICR0by5hZnRlcih0YXJnZXREZXB0aCkgOiB0bywgbmV3IFNsaWNlKGNsb3NlRnJhZ21lbnQoc2xpY2UuY29udGVudCwgMCwgc2xpY2Uub3BlblN0YXJ0LCBvcGVuRGVwdGgpLCBvcGVuRGVwdGgsIHNsaWNlLm9wZW5FbmQpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsZXQgc3RhcnRTdGVwcyA9IHRyLnN0ZXBzLmxlbmd0aDtcbiAgICBmb3IgKGxldCBpID0gdGFyZ2V0RGVwdGhzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHRyLnJlcGxhY2UoZnJvbSwgdG8sIHNsaWNlKTtcbiAgICAgICAgaWYgKHRyLnN0ZXBzLmxlbmd0aCA+IHN0YXJ0U3RlcHMpXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgbGV0IGRlcHRoID0gdGFyZ2V0RGVwdGhzW2ldO1xuICAgICAgICBpZiAoZGVwdGggPCAwKVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGZyb20gPSAkZnJvbS5iZWZvcmUoZGVwdGgpO1xuICAgICAgICB0byA9ICR0by5hZnRlcihkZXB0aCk7XG4gICAgfVxufVxuZnVuY3Rpb24gY2xvc2VGcmFnbWVudChmcmFnbWVudCwgZGVwdGgsIG9sZE9wZW4sIG5ld09wZW4sIHBhcmVudCkge1xuICAgIGlmIChkZXB0aCA8IG9sZE9wZW4pIHtcbiAgICAgICAgbGV0IGZpcnN0ID0gZnJhZ21lbnQuZmlyc3RDaGlsZDtcbiAgICAgICAgZnJhZ21lbnQgPSBmcmFnbWVudC5yZXBsYWNlQ2hpbGQoMCwgZmlyc3QuY29weShjbG9zZUZyYWdtZW50KGZpcnN0LmNvbnRlbnQsIGRlcHRoICsgMSwgb2xkT3BlbiwgbmV3T3BlbiwgZmlyc3QpKSk7XG4gICAgfVxuICAgIGlmIChkZXB0aCA+IG5ld09wZW4pIHtcbiAgICAgICAgbGV0IG1hdGNoID0gcGFyZW50LmNvbnRlbnRNYXRjaEF0KDApO1xuICAgICAgICBsZXQgc3RhcnQgPSBtYXRjaC5maWxsQmVmb3JlKGZyYWdtZW50KS5hcHBlbmQoZnJhZ21lbnQpO1xuICAgICAgICBmcmFnbWVudCA9IHN0YXJ0LmFwcGVuZChtYXRjaC5tYXRjaEZyYWdtZW50KHN0YXJ0KS5maWxsQmVmb3JlKEZyYWdtZW50LmVtcHR5LCB0cnVlKSk7XG4gICAgfVxuICAgIHJldHVybiBmcmFnbWVudDtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VSYW5nZVdpdGgodHIsIGZyb20sIHRvLCBub2RlKSB7XG4gICAgaWYgKCFub2RlLmlzSW5saW5lICYmIGZyb20gPT0gdG8gJiYgdHIuZG9jLnJlc29sdmUoZnJvbSkucGFyZW50LmNvbnRlbnQuc2l6ZSkge1xuICAgICAgICBsZXQgcG9pbnQgPSBpbnNlcnRQb2ludCh0ci5kb2MsIGZyb20sIG5vZGUudHlwZSk7XG4gICAgICAgIGlmIChwb2ludCAhPSBudWxsKVxuICAgICAgICAgICAgZnJvbSA9IHRvID0gcG9pbnQ7XG4gICAgfVxuICAgIHRyLnJlcGxhY2VSYW5nZShmcm9tLCB0bywgbmV3IFNsaWNlKEZyYWdtZW50LmZyb20obm9kZSksIDAsIDApKTtcbn1cbmZ1bmN0aW9uIGRlbGV0ZVJhbmdlKHRyLCBmcm9tLCB0bykge1xuICAgIGxldCAkZnJvbSA9IHRyLmRvYy5yZXNvbHZlKGZyb20pLCAkdG8gPSB0ci5kb2MucmVzb2x2ZSh0byk7XG4gICAgLy8gV2hlbiB0aGUgZGVsZXRlZCByYW5nZSBzcGFucyBmcm9tIHRoZSBzdGFydCBvZiBvbmUgdGV4dGJsb2NrIHRvXG4gICAgLy8gdGhlIHN0YXJ0IG9mIGFub3RoZXIgb25lLCBtb3ZlIG91dCBvZiB0aGUgc3RhcnQgb2YgYm90aCBibG9ja3MuXG4gICAgaWYgKCRmcm9tLnBhcmVudC5pc1RleHRibG9jayAmJiAkdG8ucGFyZW50LmlzVGV4dGJsb2NrICYmICRmcm9tLnN0YXJ0KCkgIT0gJHRvLnN0YXJ0KCkgJiZcbiAgICAgICAgJGZyb20ucGFyZW50T2Zmc2V0ID09IDAgJiYgJHRvLnBhcmVudE9mZnNldCA9PSAwKSB7XG4gICAgICAgIGxldCBzaGFyZWQgPSAkZnJvbS5zaGFyZWREZXB0aCh0byksIGlzb2xhdGVkID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGQgPSAkZnJvbS5kZXB0aDsgZCA+IHNoYXJlZDsgZC0tKVxuICAgICAgICAgICAgaWYgKCRmcm9tLm5vZGUoZCkudHlwZS5zcGVjLmlzb2xhdGluZylcbiAgICAgICAgICAgICAgICBpc29sYXRlZCA9IHRydWU7XG4gICAgICAgIGZvciAobGV0IGQgPSAkdG8uZGVwdGg7IGQgPiBzaGFyZWQ7IGQtLSlcbiAgICAgICAgICAgIGlmICgkdG8ubm9kZShkKS50eXBlLnNwZWMuaXNvbGF0aW5nKVxuICAgICAgICAgICAgICAgIGlzb2xhdGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKCFpc29sYXRlZCkge1xuICAgICAgICAgICAgZm9yIChsZXQgZCA9ICRmcm9tLmRlcHRoOyBkID4gMCAmJiBmcm9tID09ICRmcm9tLnN0YXJ0KGQpOyBkLS0pXG4gICAgICAgICAgICAgICAgZnJvbSA9ICRmcm9tLmJlZm9yZShkKTtcbiAgICAgICAgICAgIGZvciAobGV0IGQgPSAkdG8uZGVwdGg7IGQgPiAwICYmIHRvID09ICR0by5zdGFydChkKTsgZC0tKVxuICAgICAgICAgICAgICAgIHRvID0gJHRvLmJlZm9yZShkKTtcbiAgICAgICAgICAgICRmcm9tID0gdHIuZG9jLnJlc29sdmUoZnJvbSk7XG4gICAgICAgICAgICAkdG8gPSB0ci5kb2MucmVzb2x2ZSh0byk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGV0IGNvdmVyZWQgPSBjb3ZlcmVkRGVwdGhzKCRmcm9tLCAkdG8pO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY292ZXJlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgZGVwdGggPSBjb3ZlcmVkW2ldLCBsYXN0ID0gaSA9PSBjb3ZlcmVkLmxlbmd0aCAtIDE7XG4gICAgICAgIGlmICgobGFzdCAmJiBkZXB0aCA9PSAwKSB8fCAkZnJvbS5ub2RlKGRlcHRoKS50eXBlLmNvbnRlbnRNYXRjaC52YWxpZEVuZClcbiAgICAgICAgICAgIHJldHVybiB0ci5kZWxldGUoJGZyb20uc3RhcnQoZGVwdGgpLCAkdG8uZW5kKGRlcHRoKSk7XG4gICAgICAgIGlmIChkZXB0aCA+IDAgJiYgKGxhc3QgfHwgJGZyb20ubm9kZShkZXB0aCAtIDEpLmNhblJlcGxhY2UoJGZyb20uaW5kZXgoZGVwdGggLSAxKSwgJHRvLmluZGV4QWZ0ZXIoZGVwdGggLSAxKSkpKVxuICAgICAgICAgICAgcmV0dXJuIHRyLmRlbGV0ZSgkZnJvbS5iZWZvcmUoZGVwdGgpLCAkdG8uYWZ0ZXIoZGVwdGgpKTtcbiAgICB9XG4gICAgZm9yIChsZXQgZCA9IDE7IGQgPD0gJGZyb20uZGVwdGggJiYgZCA8PSAkdG8uZGVwdGg7IGQrKykge1xuICAgICAgICBpZiAoZnJvbSAtICRmcm9tLnN0YXJ0KGQpID09ICRmcm9tLmRlcHRoIC0gZCAmJiB0byA+ICRmcm9tLmVuZChkKSAmJiAkdG8uZW5kKGQpIC0gdG8gIT0gJHRvLmRlcHRoIC0gZCAmJlxuICAgICAgICAgICAgJGZyb20uc3RhcnQoZCAtIDEpID09ICR0by5zdGFydChkIC0gMSkgJiYgJGZyb20ubm9kZShkIC0gMSkuY2FuUmVwbGFjZSgkZnJvbS5pbmRleChkIC0gMSksICR0by5pbmRleChkIC0gMSkpKVxuICAgICAgICAgICAgcmV0dXJuIHRyLmRlbGV0ZSgkZnJvbS5iZWZvcmUoZCksIHRvKTtcbiAgICB9XG4gICAgdHIuZGVsZXRlKGZyb20sIHRvKTtcbn1cbi8vIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIGRlcHRocyBmb3Igd2hpY2ggJGZyb20gLSAkdG8gc3BhbnMgdGhlXG4vLyB3aG9sZSBjb250ZW50IG9mIHRoZSBub2RlcyBhdCB0aGF0IGRlcHRoLlxuZnVuY3Rpb24gY292ZXJlZERlcHRocygkZnJvbSwgJHRvKSB7XG4gICAgbGV0IHJlc3VsdCA9IFtdLCBtaW5EZXB0aCA9IE1hdGgubWluKCRmcm9tLmRlcHRoLCAkdG8uZGVwdGgpO1xuICAgIGZvciAobGV0IGQgPSBtaW5EZXB0aDsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgbGV0IHN0YXJ0ID0gJGZyb20uc3RhcnQoZCk7XG4gICAgICAgIGlmIChzdGFydCA8ICRmcm9tLnBvcyAtICgkZnJvbS5kZXB0aCAtIGQpIHx8XG4gICAgICAgICAgICAkdG8uZW5kKGQpID4gJHRvLnBvcyArICgkdG8uZGVwdGggLSBkKSB8fFxuICAgICAgICAgICAgJGZyb20ubm9kZShkKS50eXBlLnNwZWMuaXNvbGF0aW5nIHx8XG4gICAgICAgICAgICAkdG8ubm9kZShkKS50eXBlLnNwZWMuaXNvbGF0aW5nKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGlmIChzdGFydCA9PSAkdG8uc3RhcnQoZCkgfHxcbiAgICAgICAgICAgIChkID09ICRmcm9tLmRlcHRoICYmIGQgPT0gJHRvLmRlcHRoICYmICRmcm9tLnBhcmVudC5pbmxpbmVDb250ZW50ICYmICR0by5wYXJlbnQuaW5saW5lQ29udGVudCAmJlxuICAgICAgICAgICAgICAgIGQgJiYgJHRvLnN0YXJ0KGQgLSAxKSA9PSBzdGFydCAtIDEpKVxuICAgICAgICAgICAgcmVzdWx0LnB1c2goZCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuVXBkYXRlIGFuIGF0dHJpYnV0ZSBpbiBhIHNwZWNpZmljIG5vZGUuXG4qL1xuY2xhc3MgQXR0clN0ZXAgZXh0ZW5kcyBTdGVwIHtcbiAgICAvKipcbiAgICBDb25zdHJ1Y3QgYW4gYXR0cmlidXRlIHN0ZXAuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgcG9zaXRpb24gb2YgdGhlIHRhcmdldCBub2RlLlxuICAgICovXG4gICAgcG9zLCBcbiAgICAvKipcbiAgICBUaGUgYXR0cmlidXRlIHRvIHNldC5cbiAgICAqL1xuICAgIGF0dHIsIFxuICAgIC8vIFRoZSBhdHRyaWJ1dGUncyBuZXcgdmFsdWUuXG4gICAgdmFsdWUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5wb3MgPSBwb3M7XG4gICAgICAgIHRoaXMuYXR0ciA9IGF0dHI7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gICAgYXBwbHkoZG9jKSB7XG4gICAgICAgIGxldCBub2RlID0gZG9jLm5vZGVBdCh0aGlzLnBvcyk7XG4gICAgICAgIGlmICghbm9kZSlcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZhaWwoXCJObyBub2RlIGF0IGF0dHJpYnV0ZSBzdGVwJ3MgcG9zaXRpb25cIik7XG4gICAgICAgIGxldCBhdHRycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIGZvciAobGV0IG5hbWUgaW4gbm9kZS5hdHRycylcbiAgICAgICAgICAgIGF0dHJzW25hbWVdID0gbm9kZS5hdHRyc1tuYW1lXTtcbiAgICAgICAgYXR0cnNbdGhpcy5hdHRyXSA9IHRoaXMudmFsdWU7XG4gICAgICAgIGxldCB1cGRhdGVkID0gbm9kZS50eXBlLmNyZWF0ZShhdHRycywgbnVsbCwgbm9kZS5tYXJrcyk7XG4gICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZyb21SZXBsYWNlKGRvYywgdGhpcy5wb3MsIHRoaXMucG9zICsgMSwgbmV3IFNsaWNlKEZyYWdtZW50LmZyb20odXBkYXRlZCksIDAsIG5vZGUuaXNMZWFmID8gMCA6IDEpKTtcbiAgICB9XG4gICAgZ2V0TWFwKCkge1xuICAgICAgICByZXR1cm4gU3RlcE1hcC5lbXB0eTtcbiAgICB9XG4gICAgaW52ZXJ0KGRvYykge1xuICAgICAgICByZXR1cm4gbmV3IEF0dHJTdGVwKHRoaXMucG9zLCB0aGlzLmF0dHIsIGRvYy5ub2RlQXQodGhpcy5wb3MpLmF0dHJzW3RoaXMuYXR0cl0pO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICBsZXQgcG9zID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy5wb3MsIDEpO1xuICAgICAgICByZXR1cm4gcG9zLmRlbGV0ZWRBZnRlciA/IG51bGwgOiBuZXcgQXR0clN0ZXAocG9zLnBvcywgdGhpcy5hdHRyLCB0aGlzLnZhbHVlKTtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyBzdGVwVHlwZTogXCJhdHRyXCIsIHBvczogdGhpcy5wb3MsIGF0dHI6IHRoaXMuYXR0ciwgdmFsdWU6IHRoaXMudmFsdWUgfTtcbiAgICB9XG4gICAgc3RhdGljIGZyb21KU09OKHNjaGVtYSwganNvbikge1xuICAgICAgICBpZiAodHlwZW9mIGpzb24ucG9zICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24uYXR0ciAhPSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBBdHRyU3RlcC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBBdHRyU3RlcChqc29uLnBvcywganNvbi5hdHRyLCBqc29uLnZhbHVlKTtcbiAgICB9XG59XG5TdGVwLmpzb25JRChcImF0dHJcIiwgQXR0clN0ZXApO1xuLyoqXG5VcGRhdGUgYW4gYXR0cmlidXRlIGluIHRoZSBkb2Mgbm9kZS5cbiovXG5jbGFzcyBEb2NBdHRyU3RlcCBleHRlbmRzIFN0ZXAge1xuICAgIC8qKlxuICAgIENvbnN0cnVjdCBhbiBhdHRyaWJ1dGUgc3RlcC5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBhdHRyaWJ1dGUgdG8gc2V0LlxuICAgICovXG4gICAgYXR0ciwgXG4gICAgLy8gVGhlIGF0dHJpYnV0ZSdzIG5ldyB2YWx1ZS5cbiAgICB2YWx1ZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmF0dHIgPSBhdHRyO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIGFwcGx5KGRvYykge1xuICAgICAgICBsZXQgYXR0cnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBmb3IgKGxldCBuYW1lIGluIGRvYy5hdHRycylcbiAgICAgICAgICAgIGF0dHJzW25hbWVdID0gZG9jLmF0dHJzW25hbWVdO1xuICAgICAgICBhdHRyc1t0aGlzLmF0dHJdID0gdGhpcy52YWx1ZTtcbiAgICAgICAgbGV0IHVwZGF0ZWQgPSBkb2MudHlwZS5jcmVhdGUoYXR0cnMsIGRvYy5jb250ZW50LCBkb2MubWFya3MpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5vayh1cGRhdGVkKTtcbiAgICB9XG4gICAgZ2V0TWFwKCkge1xuICAgICAgICByZXR1cm4gU3RlcE1hcC5lbXB0eTtcbiAgICB9XG4gICAgaW52ZXJ0KGRvYykge1xuICAgICAgICByZXR1cm4gbmV3IERvY0F0dHJTdGVwKHRoaXMuYXR0ciwgZG9jLmF0dHJzW3RoaXMuYXR0cl0pO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyBzdGVwVHlwZTogXCJkb2NBdHRyXCIsIGF0dHI6IHRoaXMuYXR0ciwgdmFsdWU6IHRoaXMudmFsdWUgfTtcbiAgICB9XG4gICAgc3RhdGljIGZyb21KU09OKHNjaGVtYSwganNvbikge1xuICAgICAgICBpZiAodHlwZW9mIGpzb24uYXR0ciAhPSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBEb2NBdHRyU3RlcC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBEb2NBdHRyU3RlcChqc29uLmF0dHIsIGpzb24udmFsdWUpO1xuICAgIH1cbn1cblN0ZXAuanNvbklEKFwiZG9jQXR0clwiLCBEb2NBdHRyU3RlcCk7XG5cbi8qKlxuQGludGVybmFsXG4qL1xubGV0IFRyYW5zZm9ybUVycm9yID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7XG59O1xuVHJhbnNmb3JtRXJyb3IgPSBmdW5jdGlvbiBUcmFuc2Zvcm1FcnJvcihtZXNzYWdlKSB7XG4gICAgbGV0IGVyciA9IEVycm9yLmNhbGwodGhpcywgbWVzc2FnZSk7XG4gICAgZXJyLl9fcHJvdG9fXyA9IFRyYW5zZm9ybUVycm9yLnByb3RvdHlwZTtcbiAgICByZXR1cm4gZXJyO1xufTtcblRyYW5zZm9ybUVycm9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTtcblRyYW5zZm9ybUVycm9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFRyYW5zZm9ybUVycm9yO1xuVHJhbnNmb3JtRXJyb3IucHJvdG90eXBlLm5hbWUgPSBcIlRyYW5zZm9ybUVycm9yXCI7XG4vKipcbkFic3RyYWN0aW9uIHRvIGJ1aWxkIHVwIGFuZCB0cmFjayBhbiBhcnJheSBvZlxuW3N0ZXBzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdHJhbnNmb3JtLlN0ZXApIHJlcHJlc2VudGluZyBhIGRvY3VtZW50IHRyYW5zZm9ybWF0aW9uLlxuXG5Nb3N0IHRyYW5zZm9ybWluZyBtZXRob2RzIHJldHVybiB0aGUgYFRyYW5zZm9ybWAgb2JqZWN0IGl0c2VsZiwgc29cbnRoYXQgdGhleSBjYW4gYmUgY2hhaW5lZC5cbiovXG5jbGFzcyBUcmFuc2Zvcm0ge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIHRyYW5zZm9ybSB0aGF0IHN0YXJ0cyB3aXRoIHRoZSBnaXZlbiBkb2N1bWVudC5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBjdXJyZW50IGRvY3VtZW50ICh0aGUgcmVzdWx0IG9mIGFwcGx5aW5nIHRoZSBzdGVwcyBpbiB0aGVcbiAgICB0cmFuc2Zvcm0pLlxuICAgICovXG4gICAgZG9jKSB7XG4gICAgICAgIHRoaXMuZG9jID0gZG9jO1xuICAgICAgICAvKipcbiAgICAgICAgVGhlIHN0ZXBzIGluIHRoaXMgdHJhbnNmb3JtLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLnN0ZXBzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICBUaGUgZG9jdW1lbnRzIGJlZm9yZSBlYWNoIG9mIHRoZSBzdGVwcy5cbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5kb2NzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICBBIG1hcHBpbmcgd2l0aCB0aGUgbWFwcyBmb3IgZWFjaCBvZiB0aGUgc3RlcHMgaW4gdGhpcyB0cmFuc2Zvcm0uXG4gICAgICAgICovXG4gICAgICAgIHRoaXMubWFwcGluZyA9IG5ldyBNYXBwaW5nO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgc3RhcnRpbmcgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBnZXQgYmVmb3JlKCkgeyByZXR1cm4gdGhpcy5kb2NzLmxlbmd0aCA/IHRoaXMuZG9jc1swXSA6IHRoaXMuZG9jOyB9XG4gICAgLyoqXG4gICAgQXBwbHkgYSBuZXcgc3RlcCBpbiB0aGlzIHRyYW5zZm9ybSwgc2F2aW5nIHRoZSByZXN1bHQuIFRocm93cyBhblxuICAgIGVycm9yIHdoZW4gdGhlIHN0ZXAgZmFpbHMuXG4gICAgKi9cbiAgICBzdGVwKHN0ZXApIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IHRoaXMubWF5YmVTdGVwKHN0ZXApO1xuICAgICAgICBpZiAocmVzdWx0LmZhaWxlZClcbiAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1FcnJvcihyZXN1bHQuZmFpbGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFRyeSB0byBhcHBseSBhIHN0ZXAgaW4gdGhpcyB0cmFuc2Zvcm1hdGlvbiwgaWdub3JpbmcgaXQgaWYgaXRcbiAgICBmYWlscy4gUmV0dXJucyB0aGUgc3RlcCByZXN1bHQuXG4gICAgKi9cbiAgICBtYXliZVN0ZXAoc3RlcCkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gc3RlcC5hcHBseSh0aGlzLmRvYyk7XG4gICAgICAgIGlmICghcmVzdWx0LmZhaWxlZClcbiAgICAgICAgICAgIHRoaXMuYWRkU3RlcChzdGVwLCByZXN1bHQuZG9jKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoZSBkb2N1bWVudCBoYXMgYmVlbiBjaGFuZ2VkICh3aGVuIHRoZXJlIGFyZSBhbnlcbiAgICBzdGVwcykuXG4gICAgKi9cbiAgICBnZXQgZG9jQ2hhbmdlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RlcHMubGVuZ3RoID4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJuIGEgc2luZ2xlIHJhbmdlLCBpbiBwb3N0LXRyYW5zZm9ybSBkb2N1bWVudCBwb3NpdGlvbnMsXG4gICAgdGhhdCBjb3ZlcnMgYWxsIGNvbnRlbnQgY2hhbmdlZCBieSB0aGlzIHRyYW5zZm9ybS4gUmV0dXJucyBudWxsXG4gICAgaWYgbm8gcmVwbGFjZW1lbnRzIGFyZSBtYWRlLiBOb3RlIHRoYXQgdGhpcyB3aWxsIGlnbm9yZSBjaGFuZ2VzXG4gICAgdGhhdCBhZGQvcmVtb3ZlIG1hcmtzIHdpdGhvdXQgcmVwbGFjaW5nIHRoZSB1bmRlcmx5aW5nIGNvbnRlbnQuXG4gICAgKi9cbiAgICBjaGFuZ2VkUmFuZ2UoKSB7XG4gICAgICAgIGxldCBmcm9tID0gMWU5LCB0byA9IC0xZTk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5tYXBwaW5nLm1hcHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBtYXAgPSB0aGlzLm1hcHBpbmcubWFwc1tpXTtcbiAgICAgICAgICAgIGlmIChpKSB7XG4gICAgICAgICAgICAgICAgZnJvbSA9IG1hcC5tYXAoZnJvbSwgMSk7XG4gICAgICAgICAgICAgICAgdG8gPSBtYXAubWFwKHRvLCAtMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtYXAuZm9yRWFjaCgoX2YsIF90LCBmcm9tQiwgdG9CKSA9PiB7XG4gICAgICAgICAgICAgICAgZnJvbSA9IE1hdGgubWluKGZyb20sIGZyb21CKTtcbiAgICAgICAgICAgICAgICB0byA9IE1hdGgubWF4KHRvLCB0b0IpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZyb20gPT0gMWU5ID8gbnVsbCA6IHsgZnJvbSwgdG8gfTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBhZGRTdGVwKHN0ZXAsIGRvYykge1xuICAgICAgICB0aGlzLmRvY3MucHVzaCh0aGlzLmRvYyk7XG4gICAgICAgIHRoaXMuc3RlcHMucHVzaChzdGVwKTtcbiAgICAgICAgdGhpcy5tYXBwaW5nLmFwcGVuZE1hcChzdGVwLmdldE1hcCgpKTtcbiAgICAgICAgdGhpcy5kb2MgPSBkb2M7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIHBhcnQgb2YgdGhlIGRvY3VtZW50IGJldHdlZW4gYGZyb21gIGFuZCBgdG9gIHdpdGggdGhlXG4gICAgZ2l2ZW4gYHNsaWNlYC5cbiAgICAqL1xuICAgIHJlcGxhY2UoZnJvbSwgdG8gPSBmcm9tLCBzbGljZSA9IFNsaWNlLmVtcHR5KSB7XG4gICAgICAgIGxldCBzdGVwID0gcmVwbGFjZVN0ZXAodGhpcy5kb2MsIGZyb20sIHRvLCBzbGljZSk7XG4gICAgICAgIGlmIChzdGVwKVxuICAgICAgICAgICAgdGhpcy5zdGVwKHN0ZXApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgUmVwbGFjZSB0aGUgZ2l2ZW4gcmFuZ2Ugd2l0aCB0aGUgZ2l2ZW4gY29udGVudCwgd2hpY2ggbWF5IGJlIGFcbiAgICBmcmFnbWVudCwgbm9kZSwgb3IgYXJyYXkgb2Ygbm9kZXMuXG4gICAgKi9cbiAgICByZXBsYWNlV2l0aChmcm9tLCB0bywgY29udGVudCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXBsYWNlKGZyb20sIHRvLCBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbShjb250ZW50KSwgMCwgMCkpO1xuICAgIH1cbiAgICAvKipcbiAgICBEZWxldGUgdGhlIGNvbnRlbnQgYmV0d2VlbiB0aGUgZ2l2ZW4gcG9zaXRpb25zLlxuICAgICovXG4gICAgZGVsZXRlKGZyb20sIHRvKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlcGxhY2UoZnJvbSwgdG8sIFNsaWNlLmVtcHR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgSW5zZXJ0IHRoZSBnaXZlbiBjb250ZW50IGF0IHRoZSBnaXZlbiBwb3NpdGlvbi5cbiAgICAqL1xuICAgIGluc2VydChwb3MsIGNvbnRlbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZVdpdGgocG9zLCBwb3MsIGNvbnRlbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXBsYWNlIGEgcmFuZ2Ugb2YgdGhlIGRvY3VtZW50IHdpdGggYSBnaXZlbiBzbGljZSwgdXNpbmdcbiAgICBgZnJvbWAsIGB0b2AsIGFuZCB0aGUgc2xpY2Unc1xuICAgIFtgb3BlblN0YXJ0YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLlNsaWNlLm9wZW5TdGFydCkgcHJvcGVydHkgYXMgaGludHMsIHJhdGhlclxuICAgIHRoYW4gZml4ZWQgc3RhcnQgYW5kIGVuZCBwb2ludHMuIFRoaXMgbWV0aG9kIG1heSBncm93IHRoZVxuICAgIHJlcGxhY2VkIGFyZWEgb3IgY2xvc2Ugb3BlbiBub2RlcyBpbiB0aGUgc2xpY2UgaW4gb3JkZXIgdG8gZ2V0IGFcbiAgICBmaXQgdGhhdCBpcyBtb3JlIGluIGxpbmUgd2l0aCBXWVNJV1lHIGV4cGVjdGF0aW9ucywgYnkgZHJvcHBpbmdcbiAgICBmdWxseSBjb3ZlcmVkIHBhcmVudCBub2RlcyBvZiB0aGUgcmVwbGFjZWQgcmVnaW9uIHdoZW4gdGhleSBhcmVcbiAgICBtYXJrZWQgW25vbi1kZWZpbmluZyBhc1xuICAgIGNvbnRleHRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5kZWZpbmluZ0FzQ29udGV4dCksIG9yIGluY2x1ZGluZyBhblxuICAgIG9wZW4gcGFyZW50IG5vZGUgZnJvbSB0aGUgc2xpY2UgdGhhdCBfaXNfIG1hcmtlZCBhcyBbZGVmaW5pbmdcbiAgICBpdHMgY29udGVudF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmRlZmluaW5nRm9yQ29udGVudCkuXG4gICAgXG4gICAgVGhpcyBpcyB0aGUgbWV0aG9kLCBmb3IgZXhhbXBsZSwgdG8gaGFuZGxlIHBhc3RlLiBUaGUgc2ltaWxhclxuICAgIFtgcmVwbGFjZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0uVHJhbnNmb3JtLnJlcGxhY2UpIG1ldGhvZCBpcyBhIG1vcmVcbiAgICBwcmltaXRpdmUgdG9vbCB3aGljaCB3aWxsIF9ub3RfIG1vdmUgdGhlIHN0YXJ0IGFuZCBlbmQgb2YgaXRzIGdpdmVuXG4gICAgcmFuZ2UsIGFuZCBpcyB1c2VmdWwgaW4gc2l0dWF0aW9ucyB3aGVyZSB5b3UgbmVlZCBtb3JlIHByZWNpc2VcbiAgICBjb250cm9sIG92ZXIgd2hhdCBoYXBwZW5zLlxuICAgICovXG4gICAgcmVwbGFjZVJhbmdlKGZyb20sIHRvLCBzbGljZSkge1xuICAgICAgICByZXBsYWNlUmFuZ2UodGhpcywgZnJvbSwgdG8sIHNsaWNlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIGdpdmVuIHJhbmdlIHdpdGggYSBub2RlLCBidXQgdXNlIGBmcm9tYCBhbmQgYHRvYCBhc1xuICAgIGhpbnRzLCByYXRoZXIgdGhhbiBwcmVjaXNlIHBvc2l0aW9ucy4gV2hlbiBmcm9tIGFuZCB0byBhcmUgdGhlIHNhbWVcbiAgICBhbmQgYXJlIGF0IHRoZSBzdGFydCBvciBlbmQgb2YgYSBwYXJlbnQgbm9kZSBpbiB3aGljaCB0aGUgZ2l2ZW5cbiAgICBub2RlIGRvZXNuJ3QgZml0LCB0aGlzIG1ldGhvZCBtYXkgX21vdmVfIHRoZW0gb3V0IHRvd2FyZHMgYSBwYXJlbnRcbiAgICB0aGF0IGRvZXMgYWxsb3cgdGhlIGdpdmVuIG5vZGUgdG8gYmUgcGxhY2VkLiBXaGVuIHRoZSBnaXZlbiByYW5nZVxuICAgIGNvbXBsZXRlbHkgY292ZXJzIGEgcGFyZW50IG5vZGUsIHRoaXMgbWV0aG9kIG1heSBjb21wbGV0ZWx5IHJlcGxhY2VcbiAgICB0aGF0IHBhcmVudCBub2RlLlxuICAgICovXG4gICAgcmVwbGFjZVJhbmdlV2l0aChmcm9tLCB0bywgbm9kZSkge1xuICAgICAgICByZXBsYWNlUmFuZ2VXaXRoKHRoaXMsIGZyb20sIHRvLCBub2RlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIERlbGV0ZSB0aGUgZ2l2ZW4gcmFuZ2UsIGV4cGFuZGluZyBpdCB0byBjb3ZlciBmdWxseSBjb3ZlcmVkXG4gICAgcGFyZW50IG5vZGVzIHVudGlsIGEgdmFsaWQgcmVwbGFjZSBpcyBmb3VuZC5cbiAgICAqL1xuICAgIGRlbGV0ZVJhbmdlKGZyb20sIHRvKSB7XG4gICAgICAgIGRlbGV0ZVJhbmdlKHRoaXMsIGZyb20sIHRvKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFNwbGl0IHRoZSBjb250ZW50IGluIHRoZSBnaXZlbiByYW5nZSBvZmYgZnJvbSBpdHMgcGFyZW50LCBpZiB0aGVyZVxuICAgIGlzIHNpYmxpbmcgY29udGVudCBiZWZvcmUgb3IgYWZ0ZXIgaXQsIGFuZCBtb3ZlIGl0IHVwIHRoZSB0cmVlIHRvXG4gICAgdGhlIGRlcHRoIHNwZWNpZmllZCBieSBgdGFyZ2V0YC4gWW91J2xsIHByb2JhYmx5IHdhbnQgdG8gdXNlXG4gICAgW2BsaWZ0VGFyZ2V0YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5saWZ0VGFyZ2V0KSB0byBjb21wdXRlIGB0YXJnZXRgLCB0byBtYWtlXG4gICAgc3VyZSB0aGUgbGlmdCBpcyB2YWxpZC5cbiAgICAqL1xuICAgIGxpZnQocmFuZ2UsIHRhcmdldCkge1xuICAgICAgICBsaWZ0KHRoaXMsIHJhbmdlLCB0YXJnZXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgSm9pbiB0aGUgYmxvY2tzIGFyb3VuZCB0aGUgZ2l2ZW4gcG9zaXRpb24uIElmIGRlcHRoIGlzIDIsIHRoZWlyXG4gICAgbGFzdCBhbmQgZmlyc3Qgc2libGluZ3MgYXJlIGFsc28gam9pbmVkLCBhbmQgc28gb24uXG4gICAgKi9cbiAgICBqb2luKHBvcywgZGVwdGggPSAxKSB7XG4gICAgICAgIGpvaW4odGhpcywgcG9zLCBkZXB0aCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBXcmFwIHRoZSBnaXZlbiBbcmFuZ2VdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlUmFuZ2UpIGluIHRoZSBnaXZlbiBzZXQgb2Ygd3JhcHBlcnMuXG4gICAgVGhlIHdyYXBwZXJzIGFyZSBhc3N1bWVkIHRvIGJlIHZhbGlkIGluIHRoaXMgcG9zaXRpb24sIGFuZCBzaG91bGRcbiAgICBwcm9iYWJseSBiZSBjb21wdXRlZCB3aXRoIFtgZmluZFdyYXBwaW5nYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5maW5kV3JhcHBpbmcpLlxuICAgICovXG4gICAgd3JhcChyYW5nZSwgd3JhcHBlcnMpIHtcbiAgICAgICAgd3JhcCh0aGlzLCByYW5nZSwgd3JhcHBlcnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgU2V0IHRoZSB0eXBlIG9mIGFsbCB0ZXh0YmxvY2tzIChwYXJ0bHkpIGJldHdlZW4gYGZyb21gIGFuZCBgdG9gIHRvXG4gICAgdGhlIGdpdmVuIG5vZGUgdHlwZSB3aXRoIHRoZSBnaXZlbiBhdHRyaWJ1dGVzLlxuICAgICovXG4gICAgc2V0QmxvY2tUeXBlKGZyb20sIHRvID0gZnJvbSwgdHlwZSwgYXR0cnMgPSBudWxsKSB7XG4gICAgICAgIHNldEJsb2NrVHlwZSh0aGlzLCBmcm9tLCB0bywgdHlwZSwgYXR0cnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgQ2hhbmdlIHRoZSB0eXBlLCBhdHRyaWJ1dGVzLCBhbmQvb3IgbWFya3Mgb2YgdGhlIG5vZGUgYXQgYHBvc2AuXG4gICAgV2hlbiBgdHlwZWAgaXNuJ3QgZ2l2ZW4sIHRoZSBleGlzdGluZyBub2RlIHR5cGUgaXMgcHJlc2VydmVkLFxuICAgICovXG4gICAgc2V0Tm9kZU1hcmt1cChwb3MsIHR5cGUsIGF0dHJzID0gbnVsbCwgbWFya3MpIHtcbiAgICAgICAgc2V0Tm9kZU1hcmt1cCh0aGlzLCBwb3MsIHR5cGUsIGF0dHJzLCBtYXJrcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBTZXQgYSBzaW5nbGUgYXR0cmlidXRlIG9uIGEgZ2l2ZW4gbm9kZSB0byBhIG5ldyB2YWx1ZS5cbiAgICBUaGUgYHBvc2AgYWRkcmVzc2VzIHRoZSBkb2N1bWVudCBjb250ZW50LiBVc2UgYHNldERvY0F0dHJpYnV0ZWBcbiAgICB0byBzZXQgYXR0cmlidXRlcyBvbiB0aGUgZG9jdW1lbnQgaXRzZWxmLlxuICAgICovXG4gICAgc2V0Tm9kZUF0dHJpYnV0ZShwb3MsIGF0dHIsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuc3RlcChuZXcgQXR0clN0ZXAocG9zLCBhdHRyLCB2YWx1ZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgU2V0IGEgc2luZ2xlIGF0dHJpYnV0ZSBvbiB0aGUgZG9jdW1lbnQgdG8gYSBuZXcgdmFsdWUuXG4gICAgKi9cbiAgICBzZXREb2NBdHRyaWJ1dGUoYXR0ciwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5zdGVwKG5ldyBEb2NBdHRyU3RlcChhdHRyLCB2YWx1ZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgQWRkIGEgbWFyayB0byB0aGUgbm9kZSBhdCBwb3NpdGlvbiBgcG9zYC5cbiAgICAqL1xuICAgIGFkZE5vZGVNYXJrKHBvcywgbWFyaykge1xuICAgICAgICB0aGlzLnN0ZXAobmV3IEFkZE5vZGVNYXJrU3RlcChwb3MsIG1hcmspKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlbW92ZSBhIG1hcmsgKG9yIGFsbCBtYXJrcyBvZiB0aGUgZ2l2ZW4gdHlwZSkgZnJvbSB0aGUgbm9kZSBhdFxuICAgIHBvc2l0aW9uIGBwb3NgLlxuICAgICovXG4gICAgcmVtb3ZlTm9kZU1hcmsocG9zLCBtYXJrKSB7XG4gICAgICAgIGxldCBub2RlID0gdGhpcy5kb2Mubm9kZUF0KHBvcyk7XG4gICAgICAgIGlmICghbm9kZSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTm8gbm9kZSBhdCBwb3NpdGlvbiBcIiArIHBvcyk7XG4gICAgICAgIGlmIChtYXJrIGluc3RhbmNlb2YgTWFyaykge1xuICAgICAgICAgICAgaWYgKG1hcmsuaXNJblNldChub2RlLm1hcmtzKSlcbiAgICAgICAgICAgICAgICB0aGlzLnN0ZXAobmV3IFJlbW92ZU5vZGVNYXJrU3RlcChwb3MsIG1hcmspKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBzZXQgPSBub2RlLm1hcmtzLCBmb3VuZCwgc3RlcHMgPSBbXTtcbiAgICAgICAgICAgIHdoaWxlIChmb3VuZCA9IG1hcmsuaXNJblNldChzZXQpKSB7XG4gICAgICAgICAgICAgICAgc3RlcHMucHVzaChuZXcgUmVtb3ZlTm9kZU1hcmtTdGVwKHBvcywgZm91bmQpKTtcbiAgICAgICAgICAgICAgICBzZXQgPSBmb3VuZC5yZW1vdmVGcm9tU2V0KHNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gc3RlcHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgICAgICAgICAgdGhpcy5zdGVwKHN0ZXBzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgU3BsaXQgdGhlIG5vZGUgYXQgdGhlIGdpdmVuIHBvc2l0aW9uLCBhbmQgb3B0aW9uYWxseSwgaWYgYGRlcHRoYCBpc1xuICAgIGdyZWF0ZXIgdGhhbiBvbmUsIGFueSBudW1iZXIgb2Ygbm9kZXMgYWJvdmUgdGhhdC4gQnkgZGVmYXVsdCwgdGhlXG4gICAgcGFydHMgc3BsaXQgb2ZmIHdpbGwgaW5oZXJpdCB0aGUgbm9kZSB0eXBlIG9mIHRoZSBvcmlnaW5hbCBub2RlLlxuICAgIFRoaXMgY2FuIGJlIGNoYW5nZWQgYnkgcGFzc2luZyBhbiBhcnJheSBvZiB0eXBlcyBhbmQgYXR0cmlidXRlcyB0b1xuICAgIHVzZSBhZnRlciB0aGUgc3BsaXQgKHdpdGggdGhlIG91dGVybW9zdCBub2RlcyBjb21pbmcgZmlyc3QpLlxuICAgICovXG4gICAgc3BsaXQocG9zLCBkZXB0aCA9IDEsIHR5cGVzQWZ0ZXIpIHtcbiAgICAgICAgc3BsaXQodGhpcywgcG9zLCBkZXB0aCwgdHlwZXNBZnRlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBBZGQgdGhlIGdpdmVuIG1hcmsgdG8gdGhlIGlubGluZSBjb250ZW50IGJldHdlZW4gYGZyb21gIGFuZCBgdG9gLlxuICAgICovXG4gICAgYWRkTWFyayhmcm9tLCB0bywgbWFyaykge1xuICAgICAgICBhZGRNYXJrKHRoaXMsIGZyb20sIHRvLCBtYXJrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlbW92ZSBtYXJrcyBmcm9tIGlubGluZSBub2RlcyBiZXR3ZWVuIGBmcm9tYCBhbmQgYHRvYC4gV2hlblxuICAgIGBtYXJrYCBpcyBhIHNpbmdsZSBtYXJrLCByZW1vdmUgcHJlY2lzZWx5IHRoYXQgbWFyay4gV2hlbiBpdCBpc1xuICAgIGEgbWFyayB0eXBlLCByZW1vdmUgYWxsIG1hcmtzIG9mIHRoYXQgdHlwZS4gV2hlbiBpdCBpcyBudWxsLFxuICAgIHJlbW92ZSBhbGwgbWFya3Mgb2YgYW55IHR5cGUuXG4gICAgKi9cbiAgICByZW1vdmVNYXJrKGZyb20sIHRvLCBtYXJrKSB7XG4gICAgICAgIHJlbW92ZU1hcmsodGhpcywgZnJvbSwgdG8sIG1hcmspO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgUmVtb3ZlcyBhbGwgbWFya3MgYW5kIG5vZGVzIGZyb20gdGhlIGNvbnRlbnQgb2YgdGhlIG5vZGUgYXRcbiAgICBgcG9zYCB0aGF0IGRvbid0IG1hdGNoIHRoZSBnaXZlbiBuZXcgcGFyZW50IG5vZGUgdHlwZS4gQWNjZXB0c1xuICAgIGFuIG9wdGlvbmFsIHN0YXJ0aW5nIFtjb250ZW50IG1hdGNoXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuQ29udGVudE1hdGNoKSBhc1xuICAgIHRoaXJkIGFyZ3VtZW50LlxuICAgICovXG4gICAgY2xlYXJJbmNvbXBhdGlibGUocG9zLCBwYXJlbnRUeXBlLCBtYXRjaCkge1xuICAgICAgICBjbGVhckluY29tcGF0aWJsZSh0aGlzLCBwb3MsIHBhcmVudFR5cGUsIG1hdGNoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuXG5leHBvcnQgeyBBZGRNYXJrU3RlcCwgQWRkTm9kZU1hcmtTdGVwLCBBdHRyU3RlcCwgRG9jQXR0clN0ZXAsIE1hcFJlc3VsdCwgTWFwcGluZywgUmVtb3ZlTWFya1N0ZXAsIFJlbW92ZU5vZGVNYXJrU3RlcCwgUmVwbGFjZUFyb3VuZFN0ZXAsIFJlcGxhY2VTdGVwLCBTdGVwLCBTdGVwTWFwLCBTdGVwUmVzdWx0LCBUcmFuc2Zvcm0sIFRyYW5zZm9ybUVycm9yLCBjYW5Kb2luLCBjYW5TcGxpdCwgZHJvcFBvaW50LCBmaW5kV3JhcHBpbmcsIGluc2VydFBvaW50LCBqb2luUG9pbnQsIGxpZnRUYXJnZXQsIHJlcGxhY2VTdGVwIH07XG4iLCAiaW1wb3J0IHsgU2xpY2UsIEZyYWdtZW50LCBNYXJrLCBOb2RlIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuaW1wb3J0IHsgUmVwbGFjZVN0ZXAsIFJlcGxhY2VBcm91bmRTdGVwLCBUcmFuc2Zvcm0gfSBmcm9tICdwcm9zZW1pcnJvci10cmFuc2Zvcm0nO1xuXG5jb25zdCBjbGFzc2VzQnlJZCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4vKipcblN1cGVyY2xhc3MgZm9yIGVkaXRvciBzZWxlY3Rpb25zLiBFdmVyeSBzZWxlY3Rpb24gdHlwZSBzaG91bGRcbmV4dGVuZCB0aGlzLiBTaG91bGQgbm90IGJlIGluc3RhbnRpYXRlZCBkaXJlY3RseS5cbiovXG5jbGFzcyBTZWxlY3Rpb24ge1xuICAgIC8qKlxuICAgIEluaXRpYWxpemUgYSBzZWxlY3Rpb24gd2l0aCB0aGUgaGVhZCBhbmQgYW5jaG9yIGFuZCByYW5nZXMuIElmIG5vXG4gICAgcmFuZ2VzIGFyZSBnaXZlbiwgY29uc3RydWN0cyBhIHNpbmdsZSByYW5nZSBhY3Jvc3MgYCRhbmNob3JgIGFuZFxuICAgIGAkaGVhZGAuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgcmVzb2x2ZWQgYW5jaG9yIG9mIHRoZSBzZWxlY3Rpb24gKHRoZSBzaWRlIHRoYXQgc3RheXMgaW5cbiAgICBwbGFjZSB3aGVuIHRoZSBzZWxlY3Rpb24gaXMgbW9kaWZpZWQpLlxuICAgICovXG4gICAgJGFuY2hvciwgXG4gICAgLyoqXG4gICAgVGhlIHJlc29sdmVkIGhlYWQgb2YgdGhlIHNlbGVjdGlvbiAodGhlIHNpZGUgdGhhdCBtb3ZlcyB3aGVuXG4gICAgdGhlIHNlbGVjdGlvbiBpcyBtb2RpZmllZCkuXG4gICAgKi9cbiAgICAkaGVhZCwgcmFuZ2VzKSB7XG4gICAgICAgIHRoaXMuJGFuY2hvciA9ICRhbmNob3I7XG4gICAgICAgIHRoaXMuJGhlYWQgPSAkaGVhZDtcbiAgICAgICAgdGhpcy5yYW5nZXMgPSByYW5nZXMgfHwgW25ldyBTZWxlY3Rpb25SYW5nZSgkYW5jaG9yLm1pbigkaGVhZCksICRhbmNob3IubWF4KCRoZWFkKSldO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgc2VsZWN0aW9uJ3MgYW5jaG9yLCBhcyBhbiB1bnJlc29sdmVkIHBvc2l0aW9uLlxuICAgICovXG4gICAgZ2V0IGFuY2hvcigpIHsgcmV0dXJuIHRoaXMuJGFuY2hvci5wb3M7IH1cbiAgICAvKipcbiAgICBUaGUgc2VsZWN0aW9uJ3MgaGVhZC5cbiAgICAqL1xuICAgIGdldCBoZWFkKCkgeyByZXR1cm4gdGhpcy4kaGVhZC5wb3M7IH1cbiAgICAvKipcbiAgICBUaGUgbG93ZXIgYm91bmQgb2YgdGhlIHNlbGVjdGlvbidzIG1haW4gcmFuZ2UuXG4gICAgKi9cbiAgICBnZXQgZnJvbSgpIHsgcmV0dXJuIHRoaXMuJGZyb20ucG9zOyB9XG4gICAgLyoqXG4gICAgVGhlIHVwcGVyIGJvdW5kIG9mIHRoZSBzZWxlY3Rpb24ncyBtYWluIHJhbmdlLlxuICAgICovXG4gICAgZ2V0IHRvKCkgeyByZXR1cm4gdGhpcy4kdG8ucG9zOyB9XG4gICAgLyoqXG4gICAgVGhlIHJlc29sdmVkIGxvd2VyICBib3VuZCBvZiB0aGUgc2VsZWN0aW9uJ3MgbWFpbiByYW5nZS5cbiAgICAqL1xuICAgIGdldCAkZnJvbSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmFuZ2VzWzBdLiRmcm9tO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgcmVzb2x2ZWQgdXBwZXIgYm91bmQgb2YgdGhlIHNlbGVjdGlvbidzIG1haW4gcmFuZ2UuXG4gICAgKi9cbiAgICBnZXQgJHRvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yYW5nZXNbMF0uJHRvO1xuICAgIH1cbiAgICAvKipcbiAgICBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc2VsZWN0aW9uIGNvbnRhaW5zIGFueSBjb250ZW50LlxuICAgICovXG4gICAgZ2V0IGVtcHR5KCkge1xuICAgICAgICBsZXQgcmFuZ2VzID0gdGhpcy5yYW5nZXM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKHJhbmdlc1tpXS4kZnJvbS5wb3MgIT0gcmFuZ2VzW2ldLiR0by5wb3MpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBjb250ZW50IG9mIHRoaXMgc2VsZWN0aW9uIGFzIGEgc2xpY2UuXG4gICAgKi9cbiAgICBjb250ZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy4kZnJvbS5kb2Muc2xpY2UodGhpcy5mcm9tLCB0aGlzLnRvLCB0cnVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmVwbGFjZSB0aGUgc2VsZWN0aW9uIHdpdGggYSBzbGljZSBvciwgaWYgbm8gc2xpY2UgaXMgZ2l2ZW4sXG4gICAgZGVsZXRlIHRoZSBzZWxlY3Rpb24uIFdpbGwgYXBwZW5kIHRvIHRoZSBnaXZlbiB0cmFuc2FjdGlvbi5cbiAgICAqL1xuICAgIHJlcGxhY2UodHIsIGNvbnRlbnQgPSBTbGljZS5lbXB0eSkge1xuICAgICAgICAvLyBQdXQgdGhlIG5ldyBzZWxlY3Rpb24gYXQgdGhlIHBvc2l0aW9uIGFmdGVyIHRoZSBpbnNlcnRlZFxuICAgICAgICAvLyBjb250ZW50LiBXaGVuIHRoYXQgZW5kZWQgaW4gYW4gaW5saW5lIG5vZGUsIHNlYXJjaCBiYWNrd2FyZHMsXG4gICAgICAgIC8vIHRvIGdldCB0aGUgcG9zaXRpb24gYWZ0ZXIgdGhhdCBub2RlLiBJZiBub3QsIHNlYXJjaCBmb3J3YXJkLlxuICAgICAgICBsZXQgbGFzdE5vZGUgPSBjb250ZW50LmNvbnRlbnQubGFzdENoaWxkLCBsYXN0UGFyZW50ID0gbnVsbDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb250ZW50Lm9wZW5FbmQ7IGkrKykge1xuICAgICAgICAgICAgbGFzdFBhcmVudCA9IGxhc3ROb2RlO1xuICAgICAgICAgICAgbGFzdE5vZGUgPSBsYXN0Tm9kZS5sYXN0Q2hpbGQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG1hcEZyb20gPSB0ci5zdGVwcy5sZW5ndGgsIHJhbmdlcyA9IHRoaXMucmFuZ2VzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHsgJGZyb20sICR0byB9ID0gcmFuZ2VzW2ldLCBtYXBwaW5nID0gdHIubWFwcGluZy5zbGljZShtYXBGcm9tKTtcbiAgICAgICAgICAgIHRyLnJlcGxhY2VSYW5nZShtYXBwaW5nLm1hcCgkZnJvbS5wb3MpLCBtYXBwaW5nLm1hcCgkdG8ucG9zKSwgaSA/IFNsaWNlLmVtcHR5IDogY29udGVudCk7XG4gICAgICAgICAgICBpZiAoaSA9PSAwKVxuICAgICAgICAgICAgICAgIHNlbGVjdGlvblRvSW5zZXJ0aW9uRW5kKHRyLCBtYXBGcm9tLCAobGFzdE5vZGUgPyBsYXN0Tm9kZS5pc0lubGluZSA6IGxhc3RQYXJlbnQgJiYgbGFzdFBhcmVudC5pc1RleHRibG9jaykgPyAtMSA6IDEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIHNlbGVjdGlvbiB3aXRoIHRoZSBnaXZlbiBub2RlLCBhcHBlbmRpbmcgdGhlIGNoYW5nZXNcbiAgICB0byB0aGUgZ2l2ZW4gdHJhbnNhY3Rpb24uXG4gICAgKi9cbiAgICByZXBsYWNlV2l0aCh0ciwgbm9kZSkge1xuICAgICAgICBsZXQgbWFwRnJvbSA9IHRyLnN0ZXBzLmxlbmd0aCwgcmFuZ2VzID0gdGhpcy5yYW5nZXM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgeyAkZnJvbSwgJHRvIH0gPSByYW5nZXNbaV0sIG1hcHBpbmcgPSB0ci5tYXBwaW5nLnNsaWNlKG1hcEZyb20pO1xuICAgICAgICAgICAgbGV0IGZyb20gPSBtYXBwaW5nLm1hcCgkZnJvbS5wb3MpLCB0byA9IG1hcHBpbmcubWFwKCR0by5wb3MpO1xuICAgICAgICAgICAgaWYgKGkpIHtcbiAgICAgICAgICAgICAgICB0ci5kZWxldGVSYW5nZShmcm9tLCB0byk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0ci5yZXBsYWNlUmFuZ2VXaXRoKGZyb20sIHRvLCBub2RlKTtcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25Ub0luc2VydGlvbkVuZCh0ciwgbWFwRnJvbSwgbm9kZS5pc0lubGluZSA/IC0xIDogMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCBhIHZhbGlkIGN1cnNvciBvciBsZWFmIG5vZGUgc2VsZWN0aW9uIHN0YXJ0aW5nIGF0IHRoZSBnaXZlblxuICAgIHBvc2l0aW9uIGFuZCBzZWFyY2hpbmcgYmFjayBpZiBgZGlyYCBpcyBuZWdhdGl2ZSwgYW5kIGZvcndhcmQgaWZcbiAgICBwb3NpdGl2ZS4gV2hlbiBgdGV4dE9ubHlgIGlzIHRydWUsIG9ubHkgY29uc2lkZXIgY3Vyc29yXG4gICAgc2VsZWN0aW9ucy4gV2lsbCByZXR1cm4gbnVsbCB3aGVuIG5vIHZhbGlkIHNlbGVjdGlvbiBwb3NpdGlvbiBpc1xuICAgIGZvdW5kLlxuICAgICovXG4gICAgc3RhdGljIGZpbmRGcm9tKCRwb3MsIGRpciwgdGV4dE9ubHkgPSBmYWxzZSkge1xuICAgICAgICBsZXQgaW5uZXIgPSAkcG9zLnBhcmVudC5pbmxpbmVDb250ZW50ID8gbmV3IFRleHRTZWxlY3Rpb24oJHBvcylcbiAgICAgICAgICAgIDogZmluZFNlbGVjdGlvbkluKCRwb3Mubm9kZSgwKSwgJHBvcy5wYXJlbnQsICRwb3MucG9zLCAkcG9zLmluZGV4KCksIGRpciwgdGV4dE9ubHkpO1xuICAgICAgICBpZiAoaW5uZXIpXG4gICAgICAgICAgICByZXR1cm4gaW5uZXI7XG4gICAgICAgIGZvciAobGV0IGRlcHRoID0gJHBvcy5kZXB0aCAtIDE7IGRlcHRoID49IDA7IGRlcHRoLS0pIHtcbiAgICAgICAgICAgIGxldCBmb3VuZCA9IGRpciA8IDBcbiAgICAgICAgICAgICAgICA/IGZpbmRTZWxlY3Rpb25JbigkcG9zLm5vZGUoMCksICRwb3Mubm9kZShkZXB0aCksICRwb3MuYmVmb3JlKGRlcHRoICsgMSksICRwb3MuaW5kZXgoZGVwdGgpLCBkaXIsIHRleHRPbmx5KVxuICAgICAgICAgICAgICAgIDogZmluZFNlbGVjdGlvbkluKCRwb3Mubm9kZSgwKSwgJHBvcy5ub2RlKGRlcHRoKSwgJHBvcy5hZnRlcihkZXB0aCArIDEpLCAkcG9zLmluZGV4KGRlcHRoKSArIDEsIGRpciwgdGV4dE9ubHkpO1xuICAgICAgICAgICAgaWYgKGZvdW5kKVxuICAgICAgICAgICAgICAgIHJldHVybiBmb3VuZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCBhIHZhbGlkIGN1cnNvciBvciBsZWFmIG5vZGUgc2VsZWN0aW9uIG5lYXIgdGhlIGdpdmVuXG4gICAgcG9zaXRpb24uIFNlYXJjaGVzIGZvcndhcmQgZmlyc3QgYnkgZGVmYXVsdCwgYnV0IGlmIGBiaWFzYCBpc1xuICAgIG5lZ2F0aXZlLCBpdCB3aWxsIHNlYXJjaCBiYWNrd2FyZHMgZmlyc3QuXG4gICAgKi9cbiAgICBzdGF0aWMgbmVhcigkcG9zLCBiaWFzID0gMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5maW5kRnJvbSgkcG9zLCBiaWFzKSB8fCB0aGlzLmZpbmRGcm9tKCRwb3MsIC1iaWFzKSB8fCBuZXcgQWxsU2VsZWN0aW9uKCRwb3Mubm9kZSgwKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgdGhlIGN1cnNvciBvciBsZWFmIG5vZGUgc2VsZWN0aW9uIGNsb3Nlc3QgdG8gdGhlIHN0YXJ0IG9mXG4gICAgdGhlIGdpdmVuIGRvY3VtZW50LiBXaWxsIHJldHVybiBhblxuICAgIFtgQWxsU2VsZWN0aW9uYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLkFsbFNlbGVjdGlvbikgaWYgbm8gdmFsaWQgcG9zaXRpb25cbiAgICBleGlzdHMuXG4gICAgKi9cbiAgICBzdGF0aWMgYXRTdGFydChkb2MpIHtcbiAgICAgICAgcmV0dXJuIGZpbmRTZWxlY3Rpb25Jbihkb2MsIGRvYywgMCwgMCwgMSkgfHwgbmV3IEFsbFNlbGVjdGlvbihkb2MpO1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSBjdXJzb3Igb3IgbGVhZiBub2RlIHNlbGVjdGlvbiBjbG9zZXN0IHRvIHRoZSBlbmQgb2YgdGhlXG4gICAgZ2l2ZW4gZG9jdW1lbnQuXG4gICAgKi9cbiAgICBzdGF0aWMgYXRFbmQoZG9jKSB7XG4gICAgICAgIHJldHVybiBmaW5kU2VsZWN0aW9uSW4oZG9jLCBkb2MsIGRvYy5jb250ZW50LnNpemUsIGRvYy5jaGlsZENvdW50LCAtMSkgfHwgbmV3IEFsbFNlbGVjdGlvbihkb2MpO1xuICAgIH1cbiAgICAvKipcbiAgICBEZXNlcmlhbGl6ZSB0aGUgSlNPTiByZXByZXNlbnRhdGlvbiBvZiBhIHNlbGVjdGlvbi4gTXVzdCBiZVxuICAgIGltcGxlbWVudGVkIGZvciBjdXN0b20gY2xhc3NlcyAoYXMgYSBzdGF0aWMgY2xhc3MgbWV0aG9kKS5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihkb2MsIGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uIHx8ICFqc29uLnR5cGUpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIFNlbGVjdGlvbi5mcm9tSlNPTlwiKTtcbiAgICAgICAgbGV0IGNscyA9IGNsYXNzZXNCeUlkW2pzb24udHlwZV07XG4gICAgICAgIGlmICghY2xzKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYE5vIHNlbGVjdGlvbiB0eXBlICR7anNvbi50eXBlfSBkZWZpbmVkYCk7XG4gICAgICAgIHJldHVybiBjbHMuZnJvbUpTT04oZG9jLCBqc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVG8gYmUgYWJsZSB0byBkZXNlcmlhbGl6ZSBzZWxlY3Rpb25zIGZyb20gSlNPTiwgY3VzdG9tIHNlbGVjdGlvblxuICAgIGNsYXNzZXMgbXVzdCByZWdpc3RlciB0aGVtc2VsdmVzIHdpdGggYW4gSUQgc3RyaW5nLCBzbyB0aGF0IHRoZXlcbiAgICBjYW4gYmUgZGlzYW1iaWd1YXRlZC4gVHJ5IHRvIHBpY2sgc29tZXRoaW5nIHRoYXQncyB1bmxpa2VseSB0b1xuICAgIGNsYXNoIHdpdGggY2xhc3NlcyBmcm9tIG90aGVyIG1vZHVsZXMuXG4gICAgKi9cbiAgICBzdGF0aWMganNvbklEKGlkLCBzZWxlY3Rpb25DbGFzcykge1xuICAgICAgICBpZiAoaWQgaW4gY2xhc3Nlc0J5SWQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkR1cGxpY2F0ZSB1c2Ugb2Ygc2VsZWN0aW9uIEpTT04gSUQgXCIgKyBpZCk7XG4gICAgICAgIGNsYXNzZXNCeUlkW2lkXSA9IHNlbGVjdGlvbkNsYXNzO1xuICAgICAgICBzZWxlY3Rpb25DbGFzcy5wcm90b3R5cGUuanNvbklEID0gaWQ7XG4gICAgICAgIHJldHVybiBzZWxlY3Rpb25DbGFzcztcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IGEgW2Jvb2ttYXJrXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuU2VsZWN0aW9uQm9va21hcmspIGZvciB0aGlzIHNlbGVjdGlvbixcbiAgICB3aGljaCBpcyBhIHZhbHVlIHRoYXQgY2FuIGJlIG1hcHBlZCB3aXRob3V0IGhhdmluZyBhY2Nlc3MgdG8gYVxuICAgIGN1cnJlbnQgZG9jdW1lbnQsIGFuZCBsYXRlciByZXNvbHZlZCB0byBhIHJlYWwgc2VsZWN0aW9uIGZvciBhXG4gICAgZ2l2ZW4gZG9jdW1lbnQgYWdhaW4uIChUaGlzIGlzIHVzZWQgbW9zdGx5IGJ5IHRoZSBoaXN0b3J5IHRvXG4gICAgdHJhY2sgYW5kIHJlc3RvcmUgb2xkIHNlbGVjdGlvbnMuKSBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZlxuICAgIHRoaXMgbWV0aG9kIGp1c3QgY29udmVydHMgdGhlIHNlbGVjdGlvbiB0byBhIHRleHQgc2VsZWN0aW9uIGFuZFxuICAgIHJldHVybnMgdGhlIGJvb2ttYXJrIGZvciB0aGF0LlxuICAgICovXG4gICAgZ2V0Qm9va21hcmsoKSB7XG4gICAgICAgIHJldHVybiBUZXh0U2VsZWN0aW9uLmJldHdlZW4odGhpcy4kYW5jaG9yLCB0aGlzLiRoZWFkKS5nZXRCb29rbWFyaygpO1xuICAgIH1cbn1cblNlbGVjdGlvbi5wcm90b3R5cGUudmlzaWJsZSA9IHRydWU7XG4vKipcblJlcHJlc2VudHMgYSBzZWxlY3RlZCByYW5nZSBpbiBhIGRvY3VtZW50LlxuKi9cbmNsYXNzIFNlbGVjdGlvblJhbmdlIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSByYW5nZS5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBsb3dlciBib3VuZCBvZiB0aGUgcmFuZ2UuXG4gICAgKi9cbiAgICAkZnJvbSwgXG4gICAgLyoqXG4gICAgVGhlIHVwcGVyIGJvdW5kIG9mIHRoZSByYW5nZS5cbiAgICAqL1xuICAgICR0bykge1xuICAgICAgICB0aGlzLiRmcm9tID0gJGZyb207XG4gICAgICAgIHRoaXMuJHRvID0gJHRvO1xuICAgIH1cbn1cbmxldCB3YXJuZWRBYm91dFRleHRTZWxlY3Rpb24gPSBmYWxzZTtcbmZ1bmN0aW9uIGNoZWNrVGV4dFNlbGVjdGlvbigkcG9zKSB7XG4gICAgaWYgKCF3YXJuZWRBYm91dFRleHRTZWxlY3Rpb24gJiYgISRwb3MucGFyZW50LmlubGluZUNvbnRlbnQpIHtcbiAgICAgICAgd2FybmVkQWJvdXRUZXh0U2VsZWN0aW9uID0gdHJ1ZTtcbiAgICAgICAgY29uc29sZVtcIndhcm5cIl0oXCJUZXh0U2VsZWN0aW9uIGVuZHBvaW50IG5vdCBwb2ludGluZyBpbnRvIGEgbm9kZSB3aXRoIGlubGluZSBjb250ZW50IChcIiArICRwb3MucGFyZW50LnR5cGUubmFtZSArIFwiKVwiKTtcbiAgICB9XG59XG4vKipcbkEgdGV4dCBzZWxlY3Rpb24gcmVwcmVzZW50cyBhIGNsYXNzaWNhbCBlZGl0b3Igc2VsZWN0aW9uLCB3aXRoIGFcbmhlYWQgKHRoZSBtb3Zpbmcgc2lkZSkgYW5kIGFuY2hvciAoaW1tb2JpbGUgc2lkZSksIGJvdGggb2Ygd2hpY2hcbnBvaW50IGludG8gdGV4dGJsb2NrIG5vZGVzLiBJdCBjYW4gYmUgZW1wdHkgKGEgcmVndWxhciBjdXJzb3JcbnBvc2l0aW9uKS5cbiovXG5jbGFzcyBUZXh0U2VsZWN0aW9uIGV4dGVuZHMgU2VsZWN0aW9uIHtcbiAgICAvKipcbiAgICBDb25zdHJ1Y3QgYSB0ZXh0IHNlbGVjdGlvbiBiZXR3ZWVuIHRoZSBnaXZlbiBwb2ludHMuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcigkYW5jaG9yLCAkaGVhZCA9ICRhbmNob3IpIHtcbiAgICAgICAgY2hlY2tUZXh0U2VsZWN0aW9uKCRhbmNob3IpO1xuICAgICAgICBjaGVja1RleHRTZWxlY3Rpb24oJGhlYWQpO1xuICAgICAgICBzdXBlcigkYW5jaG9yLCAkaGVhZCk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHVybnMgYSByZXNvbHZlZCBwb3NpdGlvbiBpZiB0aGlzIGlzIGEgY3Vyc29yIHNlbGVjdGlvbiAoYW5cbiAgICBlbXB0eSB0ZXh0IHNlbGVjdGlvbiksIGFuZCBudWxsIG90aGVyd2lzZS5cbiAgICAqL1xuICAgIGdldCAkY3Vyc29yKCkgeyByZXR1cm4gdGhpcy4kYW5jaG9yLnBvcyA9PSB0aGlzLiRoZWFkLnBvcyA/IHRoaXMuJGhlYWQgOiBudWxsOyB9XG4gICAgbWFwKGRvYywgbWFwcGluZykge1xuICAgICAgICBsZXQgJGhlYWQgPSBkb2MucmVzb2x2ZShtYXBwaW5nLm1hcCh0aGlzLmhlYWQpKTtcbiAgICAgICAgaWYgKCEkaGVhZC5wYXJlbnQuaW5saW5lQ29udGVudClcbiAgICAgICAgICAgIHJldHVybiBTZWxlY3Rpb24ubmVhcigkaGVhZCk7XG4gICAgICAgIGxldCAkYW5jaG9yID0gZG9jLnJlc29sdmUobWFwcGluZy5tYXAodGhpcy5hbmNob3IpKTtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0U2VsZWN0aW9uKCRhbmNob3IucGFyZW50LmlubGluZUNvbnRlbnQgPyAkYW5jaG9yIDogJGhlYWQsICRoZWFkKTtcbiAgICB9XG4gICAgcmVwbGFjZSh0ciwgY29udGVudCA9IFNsaWNlLmVtcHR5KSB7XG4gICAgICAgIHN1cGVyLnJlcGxhY2UodHIsIGNvbnRlbnQpO1xuICAgICAgICBpZiAoY29udGVudCA9PSBTbGljZS5lbXB0eSkge1xuICAgICAgICAgICAgbGV0IG1hcmtzID0gdGhpcy4kZnJvbS5tYXJrc0Fjcm9zcyh0aGlzLiR0byk7XG4gICAgICAgICAgICBpZiAobWFya3MpXG4gICAgICAgICAgICAgICAgdHIuZW5zdXJlTWFya3MobWFya3MpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIHJldHVybiBvdGhlciBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24gJiYgb3RoZXIuYW5jaG9yID09IHRoaXMuYW5jaG9yICYmIG90aGVyLmhlYWQgPT0gdGhpcy5oZWFkO1xuICAgIH1cbiAgICBnZXRCb29rbWFyaygpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0Qm9va21hcmsodGhpcy5hbmNob3IsIHRoaXMuaGVhZCk7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHsgdHlwZTogXCJ0ZXh0XCIsIGFuY2hvcjogdGhpcy5hbmNob3IsIGhlYWQ6IHRoaXMuaGVhZCB9O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihkb2MsIGpzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBqc29uLmFuY2hvciAhPSBcIm51bWJlclwiIHx8IHR5cGVvZiBqc29uLmhlYWQgIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgVGV4dFNlbGVjdGlvbi5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0U2VsZWN0aW9uKGRvYy5yZXNvbHZlKGpzb24uYW5jaG9yKSwgZG9jLnJlc29sdmUoanNvbi5oZWFkKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIHRleHQgc2VsZWN0aW9uIGZyb20gbm9uLXJlc29sdmVkIHBvc2l0aW9ucy5cbiAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGUoZG9jLCBhbmNob3IsIGhlYWQgPSBhbmNob3IpIHtcbiAgICAgICAgbGV0ICRhbmNob3IgPSBkb2MucmVzb2x2ZShhbmNob3IpO1xuICAgICAgICByZXR1cm4gbmV3IHRoaXMoJGFuY2hvciwgaGVhZCA9PSBhbmNob3IgPyAkYW5jaG9yIDogZG9jLnJlc29sdmUoaGVhZCkpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm4gYSB0ZXh0IHNlbGVjdGlvbiB0aGF0IHNwYW5zIHRoZSBnaXZlbiBwb3NpdGlvbnMgb3IsIGlmXG4gICAgdGhleSBhcmVuJ3QgdGV4dCBwb3NpdGlvbnMsIGZpbmQgYSB0ZXh0IHNlbGVjdGlvbiBuZWFyIHRoZW0uXG4gICAgYGJpYXNgIGRldGVybWluZXMgd2hldGhlciB0aGUgbWV0aG9kIHNlYXJjaGVzIGZvcndhcmQgKGRlZmF1bHQpXG4gICAgb3IgYmFja3dhcmRzIChuZWdhdGl2ZSBudW1iZXIpIGZpcnN0LiBXaWxsIGZhbGwgYmFjayB0byBjYWxsaW5nXG4gICAgW2BTZWxlY3Rpb24ubmVhcmBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5TZWxlY3Rpb25ebmVhcikgd2hlbiB0aGUgZG9jdW1lbnRcbiAgICBkb2Vzbid0IGNvbnRhaW4gYSB2YWxpZCB0ZXh0IHBvc2l0aW9uLlxuICAgICovXG4gICAgc3RhdGljIGJldHdlZW4oJGFuY2hvciwgJGhlYWQsIGJpYXMpIHtcbiAgICAgICAgbGV0IGRQb3MgPSAkYW5jaG9yLnBvcyAtICRoZWFkLnBvcztcbiAgICAgICAgaWYgKCFiaWFzIHx8IGRQb3MpXG4gICAgICAgICAgICBiaWFzID0gZFBvcyA+PSAwID8gMSA6IC0xO1xuICAgICAgICBpZiAoISRoZWFkLnBhcmVudC5pbmxpbmVDb250ZW50KSB7XG4gICAgICAgICAgICBsZXQgZm91bmQgPSBTZWxlY3Rpb24uZmluZEZyb20oJGhlYWQsIGJpYXMsIHRydWUpIHx8IFNlbGVjdGlvbi5maW5kRnJvbSgkaGVhZCwgLWJpYXMsIHRydWUpO1xuICAgICAgICAgICAgaWYgKGZvdW5kKVxuICAgICAgICAgICAgICAgICRoZWFkID0gZm91bmQuJGhlYWQ7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgcmV0dXJuIFNlbGVjdGlvbi5uZWFyKCRoZWFkLCBiaWFzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISRhbmNob3IucGFyZW50LmlubGluZUNvbnRlbnQpIHtcbiAgICAgICAgICAgIGlmIChkUG9zID09IDApIHtcbiAgICAgICAgICAgICAgICAkYW5jaG9yID0gJGhlYWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAkYW5jaG9yID0gKFNlbGVjdGlvbi5maW5kRnJvbSgkYW5jaG9yLCAtYmlhcywgdHJ1ZSkgfHwgU2VsZWN0aW9uLmZpbmRGcm9tKCRhbmNob3IsIGJpYXMsIHRydWUpKS4kYW5jaG9yO1xuICAgICAgICAgICAgICAgIGlmICgoJGFuY2hvci5wb3MgPCAkaGVhZC5wb3MpICE9IChkUG9zIDwgMCkpXG4gICAgICAgICAgICAgICAgICAgICRhbmNob3IgPSAkaGVhZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFRleHRTZWxlY3Rpb24oJGFuY2hvciwgJGhlYWQpO1xuICAgIH1cbn1cblNlbGVjdGlvbi5qc29uSUQoXCJ0ZXh0XCIsIFRleHRTZWxlY3Rpb24pO1xuY2xhc3MgVGV4dEJvb2ttYXJrIHtcbiAgICBjb25zdHJ1Y3RvcihhbmNob3IsIGhlYWQpIHtcbiAgICAgICAgdGhpcy5hbmNob3IgPSBhbmNob3I7XG4gICAgICAgIHRoaXMuaGVhZCA9IGhlYWQ7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dEJvb2ttYXJrKG1hcHBpbmcubWFwKHRoaXMuYW5jaG9yKSwgbWFwcGluZy5tYXAodGhpcy5oZWFkKSk7XG4gICAgfVxuICAgIHJlc29sdmUoZG9jKSB7XG4gICAgICAgIHJldHVybiBUZXh0U2VsZWN0aW9uLmJldHdlZW4oZG9jLnJlc29sdmUodGhpcy5hbmNob3IpLCBkb2MucmVzb2x2ZSh0aGlzLmhlYWQpKTtcbiAgICB9XG59XG4vKipcbkEgbm9kZSBzZWxlY3Rpb24gaXMgYSBzZWxlY3Rpb24gdGhhdCBwb2ludHMgYXQgYSBzaW5nbGUgbm9kZS4gQWxsXG5ub2RlcyBtYXJrZWQgW3NlbGVjdGFibGVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5zZWxlY3RhYmxlKSBjYW4gYmUgdGhlXG50YXJnZXQgb2YgYSBub2RlIHNlbGVjdGlvbi4gSW4gc3VjaCBhIHNlbGVjdGlvbiwgYGZyb21gIGFuZCBgdG9gXG5wb2ludCBkaXJlY3RseSBiZWZvcmUgYW5kIGFmdGVyIHRoZSBzZWxlY3RlZCBub2RlLCBgYW5jaG9yYCBlcXVhbHNcbmBmcm9tYCwgYW5kIGBoZWFkYCBlcXVhbHMgYHRvYC4uXG4qL1xuY2xhc3MgTm9kZVNlbGVjdGlvbiBleHRlbmRzIFNlbGVjdGlvbiB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbm9kZSBzZWxlY3Rpb24uIERvZXMgbm90IHZlcmlmeSB0aGUgdmFsaWRpdHkgb2YgaXRzXG4gICAgYXJndW1lbnQuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcigkcG9zKSB7XG4gICAgICAgIGxldCBub2RlID0gJHBvcy5ub2RlQWZ0ZXI7XG4gICAgICAgIGxldCAkZW5kID0gJHBvcy5ub2RlKDApLnJlc29sdmUoJHBvcy5wb3MgKyBub2RlLm5vZGVTaXplKTtcbiAgICAgICAgc3VwZXIoJHBvcywgJGVuZCk7XG4gICAgICAgIHRoaXMubm9kZSA9IG5vZGU7XG4gICAgfVxuICAgIG1hcChkb2MsIG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IHsgZGVsZXRlZCwgcG9zIH0gPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLmFuY2hvcik7XG4gICAgICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUocG9zKTtcbiAgICAgICAgaWYgKGRlbGV0ZWQpXG4gICAgICAgICAgICByZXR1cm4gU2VsZWN0aW9uLm5lYXIoJHBvcyk7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZVNlbGVjdGlvbigkcG9zKTtcbiAgICB9XG4gICAgY29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTbGljZShGcmFnbWVudC5mcm9tKHRoaXMubm9kZSksIDAsIDApO1xuICAgIH1cbiAgICBlcShvdGhlcikge1xuICAgICAgICByZXR1cm4gb3RoZXIgaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uICYmIG90aGVyLmFuY2hvciA9PSB0aGlzLmFuY2hvcjtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyB0eXBlOiBcIm5vZGVcIiwgYW5jaG9yOiB0aGlzLmFuY2hvciB9O1xuICAgIH1cbiAgICBnZXRCb29rbWFyaygpIHsgcmV0dXJuIG5ldyBOb2RlQm9va21hcmsodGhpcy5hbmNob3IpOyB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oZG9jLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5hbmNob3IgIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgTm9kZVNlbGVjdGlvbi5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBOb2RlU2VsZWN0aW9uKGRvYy5yZXNvbHZlKGpzb24uYW5jaG9yKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5vZGUgc2VsZWN0aW9uIGZyb20gbm9uLXJlc29sdmVkIHBvc2l0aW9ucy5cbiAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGUoZG9jLCBmcm9tKSB7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZVNlbGVjdGlvbihkb2MucmVzb2x2ZShmcm9tKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIERldGVybWluZXMgd2hldGhlciB0aGUgZ2l2ZW4gbm9kZSBtYXkgYmUgc2VsZWN0ZWQgYXMgYSBub2RlXG4gICAgc2VsZWN0aW9uLlxuICAgICovXG4gICAgc3RhdGljIGlzU2VsZWN0YWJsZShub2RlKSB7XG4gICAgICAgIHJldHVybiAhbm9kZS5pc1RleHQgJiYgbm9kZS50eXBlLnNwZWMuc2VsZWN0YWJsZSAhPT0gZmFsc2U7XG4gICAgfVxufVxuTm9kZVNlbGVjdGlvbi5wcm90b3R5cGUudmlzaWJsZSA9IGZhbHNlO1xuU2VsZWN0aW9uLmpzb25JRChcIm5vZGVcIiwgTm9kZVNlbGVjdGlvbik7XG5jbGFzcyBOb2RlQm9va21hcmsge1xuICAgIGNvbnN0cnVjdG9yKGFuY2hvcikge1xuICAgICAgICB0aGlzLmFuY2hvciA9IGFuY2hvcjtcbiAgICB9XG4gICAgbWFwKG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IHsgZGVsZXRlZCwgcG9zIH0gPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLmFuY2hvcik7XG4gICAgICAgIHJldHVybiBkZWxldGVkID8gbmV3IFRleHRCb29rbWFyayhwb3MsIHBvcykgOiBuZXcgTm9kZUJvb2ttYXJrKHBvcyk7XG4gICAgfVxuICAgIHJlc29sdmUoZG9jKSB7XG4gICAgICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUodGhpcy5hbmNob3IpLCBub2RlID0gJHBvcy5ub2RlQWZ0ZXI7XG4gICAgICAgIGlmIChub2RlICYmIE5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKG5vZGUpKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBOb2RlU2VsZWN0aW9uKCRwb3MpO1xuICAgICAgICByZXR1cm4gU2VsZWN0aW9uLm5lYXIoJHBvcyk7XG4gICAgfVxufVxuLyoqXG5BIHNlbGVjdGlvbiB0eXBlIHRoYXQgcmVwcmVzZW50cyBzZWxlY3RpbmcgdGhlIHdob2xlIGRvY3VtZW50XG4od2hpY2ggY2FuIG5vdCBuZWNlc3NhcmlseSBiZSBleHByZXNzZWQgd2l0aCBhIHRleHQgc2VsZWN0aW9uLCB3aGVuXG50aGVyZSBhcmUgZm9yIGV4YW1wbGUgbGVhZiBibG9jayBub2RlcyBhdCB0aGUgc3RhcnQgb3IgZW5kIG9mIHRoZVxuZG9jdW1lbnQpLlxuKi9cbmNsYXNzIEFsbFNlbGVjdGlvbiBleHRlbmRzIFNlbGVjdGlvbiB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGFuIGFsbC1zZWxlY3Rpb24gb3ZlciB0aGUgZ2l2ZW4gZG9jdW1lbnQuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihkb2MpIHtcbiAgICAgICAgc3VwZXIoZG9jLnJlc29sdmUoMCksIGRvYy5yZXNvbHZlKGRvYy5jb250ZW50LnNpemUpKTtcbiAgICB9XG4gICAgcmVwbGFjZSh0ciwgY29udGVudCA9IFNsaWNlLmVtcHR5KSB7XG4gICAgICAgIGlmIChjb250ZW50ID09IFNsaWNlLmVtcHR5KSB7XG4gICAgICAgICAgICB0ci5kZWxldGUoMCwgdHIuZG9jLmNvbnRlbnQuc2l6ZSk7XG4gICAgICAgICAgICBsZXQgc2VsID0gU2VsZWN0aW9uLmF0U3RhcnQodHIuZG9jKTtcbiAgICAgICAgICAgIGlmICghc2VsLmVxKHRyLnNlbGVjdGlvbikpXG4gICAgICAgICAgICAgICAgdHIuc2V0U2VsZWN0aW9uKHNlbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdXBlci5yZXBsYWNlKHRyLCBjb250ZW50KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB0b0pTT04oKSB7IHJldHVybiB7IHR5cGU6IFwiYWxsXCIgfTsgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKGRvYykgeyByZXR1cm4gbmV3IEFsbFNlbGVjdGlvbihkb2MpOyB9XG4gICAgbWFwKGRvYykgeyByZXR1cm4gbmV3IEFsbFNlbGVjdGlvbihkb2MpOyB9XG4gICAgZXEob3RoZXIpIHsgcmV0dXJuIG90aGVyIGluc3RhbmNlb2YgQWxsU2VsZWN0aW9uOyB9XG4gICAgZ2V0Qm9va21hcmsoKSB7IHJldHVybiBBbGxCb29rbWFyazsgfVxufVxuU2VsZWN0aW9uLmpzb25JRChcImFsbFwiLCBBbGxTZWxlY3Rpb24pO1xuY29uc3QgQWxsQm9va21hcmsgPSB7XG4gICAgbWFwKCkgeyByZXR1cm4gdGhpczsgfSxcbiAgICByZXNvbHZlKGRvYykgeyByZXR1cm4gbmV3IEFsbFNlbGVjdGlvbihkb2MpOyB9XG59O1xuLy8gRklYTUUgd2UnbGwgbmVlZCBzb21lIGF3YXJlbmVzcyBvZiB0ZXh0IGRpcmVjdGlvbiB3aGVuIHNjYW5uaW5nIGZvciBzZWxlY3Rpb25zXG4vLyBUcnkgdG8gZmluZCBhIHNlbGVjdGlvbiBpbnNpZGUgdGhlIGdpdmVuIG5vZGUuIGBwb3NgIHBvaW50cyBhdCB0aGVcbi8vIHBvc2l0aW9uIHdoZXJlIHRoZSBzZWFyY2ggc3RhcnRzLiBXaGVuIGB0ZXh0YCBpcyB0cnVlLCBvbmx5IHJldHVyblxuLy8gdGV4dCBzZWxlY3Rpb25zLlxuZnVuY3Rpb24gZmluZFNlbGVjdGlvbkluKGRvYywgbm9kZSwgcG9zLCBpbmRleCwgZGlyLCB0ZXh0ID0gZmFsc2UpIHtcbiAgICBpZiAobm9kZS5pbmxpbmVDb250ZW50KVxuICAgICAgICByZXR1cm4gVGV4dFNlbGVjdGlvbi5jcmVhdGUoZG9jLCBwb3MpO1xuICAgIGZvciAobGV0IGkgPSBpbmRleCAtIChkaXIgPiAwID8gMCA6IDEpOyBkaXIgPiAwID8gaSA8IG5vZGUuY2hpbGRDb3VudCA6IGkgPj0gMDsgaSArPSBkaXIpIHtcbiAgICAgICAgbGV0IGNoaWxkID0gbm9kZS5jaGlsZChpKTtcbiAgICAgICAgaWYgKCFjaGlsZC5pc0F0b20pIHtcbiAgICAgICAgICAgIGxldCBpbm5lciA9IGZpbmRTZWxlY3Rpb25Jbihkb2MsIGNoaWxkLCBwb3MgKyBkaXIsIGRpciA8IDAgPyBjaGlsZC5jaGlsZENvdW50IDogMCwgZGlyLCB0ZXh0KTtcbiAgICAgICAgICAgIGlmIChpbm5lcilcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5uZXI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXRleHQgJiYgTm9kZVNlbGVjdGlvbi5pc1NlbGVjdGFibGUoY2hpbGQpKSB7XG4gICAgICAgICAgICByZXR1cm4gTm9kZVNlbGVjdGlvbi5jcmVhdGUoZG9jLCBwb3MgLSAoZGlyIDwgMCA/IGNoaWxkLm5vZGVTaXplIDogMCkpO1xuICAgICAgICB9XG4gICAgICAgIHBvcyArPSBjaGlsZC5ub2RlU2l6ZSAqIGRpcjtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBzZWxlY3Rpb25Ub0luc2VydGlvbkVuZCh0ciwgc3RhcnRMZW4sIGJpYXMpIHtcbiAgICBsZXQgbGFzdCA9IHRyLnN0ZXBzLmxlbmd0aCAtIDE7XG4gICAgaWYgKGxhc3QgPCBzdGFydExlbilcbiAgICAgICAgcmV0dXJuO1xuICAgIGxldCBzdGVwID0gdHIuc3RlcHNbbGFzdF07XG4gICAgaWYgKCEoc3RlcCBpbnN0YW5jZW9mIFJlcGxhY2VTdGVwIHx8IHN0ZXAgaW5zdGFuY2VvZiBSZXBsYWNlQXJvdW5kU3RlcCkpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgbWFwID0gdHIubWFwcGluZy5tYXBzW2xhc3RdLCBlbmQ7XG4gICAgbWFwLmZvckVhY2goKF9mcm9tLCBfdG8sIF9uZXdGcm9tLCBuZXdUbykgPT4geyBpZiAoZW5kID09IG51bGwpXG4gICAgICAgIGVuZCA9IG5ld1RvOyB9KTtcbiAgICB0ci5zZXRTZWxlY3Rpb24oU2VsZWN0aW9uLm5lYXIodHIuZG9jLnJlc29sdmUoZW5kKSwgYmlhcykpO1xufVxuXG5jb25zdCBVUERBVEVEX1NFTCA9IDEsIFVQREFURURfTUFSS1MgPSAyLCBVUERBVEVEX1NDUk9MTCA9IDQ7XG4vKipcbkFuIGVkaXRvciBzdGF0ZSB0cmFuc2FjdGlvbiwgd2hpY2ggY2FuIGJlIGFwcGxpZWQgdG8gYSBzdGF0ZSB0b1xuY3JlYXRlIGFuIHVwZGF0ZWQgc3RhdGUuIFVzZVxuW2BFZGl0b3JTdGF0ZS50cmBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5FZGl0b3JTdGF0ZS50cikgdG8gY3JlYXRlIGFuIGluc3RhbmNlLlxuXG5UcmFuc2FjdGlvbnMgdHJhY2sgY2hhbmdlcyB0byB0aGUgZG9jdW1lbnQgKHRoZXkgYXJlIGEgc3ViY2xhc3Mgb2ZcbltgVHJhbnNmb3JtYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5UcmFuc2Zvcm0pKSwgYnV0IGFsc28gb3RoZXIgc3RhdGUgY2hhbmdlcyxcbmxpa2Ugc2VsZWN0aW9uIHVwZGF0ZXMgYW5kIGFkanVzdG1lbnRzIG9mIHRoZSBzZXQgb2YgW3N0b3JlZFxubWFya3NdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5FZGl0b3JTdGF0ZS5zdG9yZWRNYXJrcykuIEluIGFkZGl0aW9uLCB5b3UgY2FuIHN0b3JlXG5tZXRhZGF0YSBwcm9wZXJ0aWVzIGluIGEgdHJhbnNhY3Rpb24sIHdoaWNoIGFyZSBleHRyYSBwaWVjZXMgb2ZcbmluZm9ybWF0aW9uIHRoYXQgY2xpZW50IGNvZGUgb3IgcGx1Z2lucyBjYW4gdXNlIHRvIGRlc2NyaWJlIHdoYXQgYVxudHJhbnNhY3Rpb24gcmVwcmVzZW50cywgc28gdGhhdCB0aGV5IGNhbiB1cGRhdGUgdGhlaXIgW293blxuc3RhdGVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5TdGF0ZUZpZWxkKSBhY2NvcmRpbmdseS5cblxuVGhlIFtlZGl0b3Igdmlld10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuRWRpdG9yVmlldykgdXNlcyBhIGZldyBtZXRhZGF0YVxucHJvcGVydGllczogaXQgd2lsbCBhdHRhY2ggYSBwcm9wZXJ0eSBgXCJwb2ludGVyXCJgIHdpdGggdGhlIHZhbHVlXG5gdHJ1ZWAgdG8gc2VsZWN0aW9uIHRyYW5zYWN0aW9ucyBkaXJlY3RseSBjYXVzZWQgYnkgbW91c2Ugb3IgdG91Y2hcbmlucHV0LCBhIGBcImNvbXBvc2l0aW9uXCJgIHByb3BlcnR5IGhvbGRpbmcgYW4gSUQgaWRlbnRpZnlpbmcgdGhlXG5jb21wb3NpdGlvbiB0aGF0IGNhdXNlZCBpdCB0byB0cmFuc2FjdGlvbnMgY2F1c2VkIGJ5IGNvbXBvc2VkIERPTVxuaW5wdXQsIGFuZCBhIGBcInVpRXZlbnRcImAgcHJvcGVydHkgb2YgdGhhdCBtYXkgYmUgYFwicGFzdGVcImAsXG5gXCJjdXRcImAsIG9yIGBcImRyb3BcImAuXG4qL1xuY2xhc3MgVHJhbnNhY3Rpb24gZXh0ZW5kcyBUcmFuc2Zvcm0ge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RhdGUpIHtcbiAgICAgICAgc3VwZXIoc3RhdGUuZG9jKTtcbiAgICAgICAgLy8gVGhlIHN0ZXAgY291bnQgZm9yIHdoaWNoIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpcyB2YWxpZC5cbiAgICAgICAgdGhpcy5jdXJTZWxlY3Rpb25Gb3IgPSAwO1xuICAgICAgICAvLyBCaXRmaWVsZCB0byB0cmFjayB3aGljaCBhc3BlY3RzIG9mIHRoZSBzdGF0ZSB3ZXJlIHVwZGF0ZWQgYnlcbiAgICAgICAgLy8gdGhpcyB0cmFuc2FjdGlvbi5cbiAgICAgICAgdGhpcy51cGRhdGVkID0gMDtcbiAgICAgICAgLy8gT2JqZWN0IHVzZWQgdG8gc3RvcmUgbWV0YWRhdGEgcHJvcGVydGllcyBmb3IgdGhlIHRyYW5zYWN0aW9uLlxuICAgICAgICB0aGlzLm1ldGEgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLnRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICB0aGlzLmN1clNlbGVjdGlvbiA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgdGhpcy5zdG9yZWRNYXJrcyA9IHN0YXRlLnN0b3JlZE1hcmtzO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgdHJhbnNhY3Rpb24ncyBjdXJyZW50IHNlbGVjdGlvbi4gVGhpcyBkZWZhdWx0cyB0byB0aGUgZWRpdG9yXG4gICAgc2VsZWN0aW9uIFttYXBwZWRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5TZWxlY3Rpb24ubWFwKSB0aHJvdWdoIHRoZSBzdGVwcyBpbiB0aGVcbiAgICB0cmFuc2FjdGlvbiwgYnV0IGNhbiBiZSBvdmVyd3JpdHRlbiB3aXRoXG4gICAgW2BzZXRTZWxlY3Rpb25gXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuVHJhbnNhY3Rpb24uc2V0U2VsZWN0aW9uKS5cbiAgICAqL1xuICAgIGdldCBzZWxlY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLmN1clNlbGVjdGlvbkZvciA8IHRoaXMuc3RlcHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmN1clNlbGVjdGlvbiA9IHRoaXMuY3VyU2VsZWN0aW9uLm1hcCh0aGlzLmRvYywgdGhpcy5tYXBwaW5nLnNsaWNlKHRoaXMuY3VyU2VsZWN0aW9uRm9yKSk7XG4gICAgICAgICAgICB0aGlzLmN1clNlbGVjdGlvbkZvciA9IHRoaXMuc3RlcHMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmN1clNlbGVjdGlvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgVXBkYXRlIHRoZSB0cmFuc2FjdGlvbidzIGN1cnJlbnQgc2VsZWN0aW9uLiBXaWxsIGRldGVybWluZSB0aGVcbiAgICBzZWxlY3Rpb24gdGhhdCB0aGUgZWRpdG9yIGdldHMgd2hlbiB0aGUgdHJhbnNhY3Rpb24gaXMgYXBwbGllZC5cbiAgICAqL1xuICAgIHNldFNlbGVjdGlvbihzZWxlY3Rpb24pIHtcbiAgICAgICAgaWYgKHNlbGVjdGlvbi4kZnJvbS5kb2MgIT0gdGhpcy5kb2MpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlNlbGVjdGlvbiBwYXNzZWQgdG8gc2V0U2VsZWN0aW9uIG11c3QgcG9pbnQgYXQgdGhlIGN1cnJlbnQgZG9jdW1lbnRcIik7XG4gICAgICAgIHRoaXMuY3VyU2VsZWN0aW9uID0gc2VsZWN0aW9uO1xuICAgICAgICB0aGlzLmN1clNlbGVjdGlvbkZvciA9IHRoaXMuc3RlcHMubGVuZ3RoO1xuICAgICAgICB0aGlzLnVwZGF0ZWQgPSAodGhpcy51cGRhdGVkIHwgVVBEQVRFRF9TRUwpICYgflVQREFURURfTUFSS1M7XG4gICAgICAgIHRoaXMuc3RvcmVkTWFya3MgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgV2hldGhlciB0aGUgc2VsZWN0aW9uIHdhcyBleHBsaWNpdGx5IHVwZGF0ZWQgYnkgdGhpcyB0cmFuc2FjdGlvbi5cbiAgICAqL1xuICAgIGdldCBzZWxlY3Rpb25TZXQoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy51cGRhdGVkICYgVVBEQVRFRF9TRUwpID4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgU2V0IHRoZSBjdXJyZW50IHN0b3JlZCBtYXJrcy5cbiAgICAqL1xuICAgIHNldFN0b3JlZE1hcmtzKG1hcmtzKSB7XG4gICAgICAgIHRoaXMuc3RvcmVkTWFya3MgPSBtYXJrcztcbiAgICAgICAgdGhpcy51cGRhdGVkIHw9IFVQREFURURfTUFSS1M7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBNYWtlIHN1cmUgdGhlIGN1cnJlbnQgc3RvcmVkIG1hcmtzIG9yLCBpZiB0aGF0IGlzIG51bGwsIHRoZSBtYXJrc1xuICAgIGF0IHRoZSBzZWxlY3Rpb24sIG1hdGNoIHRoZSBnaXZlbiBzZXQgb2YgbWFya3MuIERvZXMgbm90aGluZyBpZlxuICAgIHRoaXMgaXMgYWxyZWFkeSB0aGUgY2FzZS5cbiAgICAqL1xuICAgIGVuc3VyZU1hcmtzKG1hcmtzKSB7XG4gICAgICAgIGlmICghTWFyay5zYW1lU2V0KHRoaXMuc3RvcmVkTWFya3MgfHwgdGhpcy5zZWxlY3Rpb24uJGZyb20ubWFya3MoKSwgbWFya3MpKVxuICAgICAgICAgICAgdGhpcy5zZXRTdG9yZWRNYXJrcyhtYXJrcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBBZGQgYSBtYXJrIHRvIHRoZSBzZXQgb2Ygc3RvcmVkIG1hcmtzLlxuICAgICovXG4gICAgYWRkU3RvcmVkTWFyayhtYXJrKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuc3VyZU1hcmtzKG1hcmsuYWRkVG9TZXQodGhpcy5zdG9yZWRNYXJrcyB8fCB0aGlzLnNlbGVjdGlvbi4kaGVhZC5tYXJrcygpKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlbW92ZSBhIG1hcmsgb3IgbWFyayB0eXBlIGZyb20gdGhlIHNldCBvZiBzdG9yZWQgbWFya3MuXG4gICAgKi9cbiAgICByZW1vdmVTdG9yZWRNYXJrKG1hcmspIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5zdXJlTWFya3MobWFyay5yZW1vdmVGcm9tU2V0KHRoaXMuc3RvcmVkTWFya3MgfHwgdGhpcy5zZWxlY3Rpb24uJGhlYWQubWFya3MoKSkpO1xuICAgIH1cbiAgICAvKipcbiAgICBXaGV0aGVyIHRoZSBzdG9yZWQgbWFya3Mgd2VyZSBleHBsaWNpdGx5IHNldCBmb3IgdGhpcyB0cmFuc2FjdGlvbi5cbiAgICAqL1xuICAgIGdldCBzdG9yZWRNYXJrc1NldCgpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnVwZGF0ZWQgJiBVUERBVEVEX01BUktTKSA+IDA7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgYWRkU3RlcChzdGVwLCBkb2MpIHtcbiAgICAgICAgc3VwZXIuYWRkU3RlcChzdGVwLCBkb2MpO1xuICAgICAgICB0aGlzLnVwZGF0ZWQgPSB0aGlzLnVwZGF0ZWQgJiB+VVBEQVRFRF9NQVJLUztcbiAgICAgICAgdGhpcy5zdG9yZWRNYXJrcyA9IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIFVwZGF0ZSB0aGUgdGltZXN0YW1wIGZvciB0aGUgdHJhbnNhY3Rpb24uXG4gICAgKi9cbiAgICBzZXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGhpcy50aW1lID0gdGltZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIHdpdGggdGhlIGdpdmVuIHNsaWNlLlxuICAgICovXG4gICAgcmVwbGFjZVNlbGVjdGlvbihzbGljZSkge1xuICAgICAgICB0aGlzLnNlbGVjdGlvbi5yZXBsYWNlKHRoaXMsIHNsaWNlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIHNlbGVjdGlvbiB3aXRoIHRoZSBnaXZlbiBub2RlLiBXaGVuIGBpbmhlcml0TWFya3NgIGlzXG4gICAgdHJ1ZSBhbmQgdGhlIGNvbnRlbnQgaXMgaW5saW5lLCBpdCBpbmhlcml0cyB0aGUgbWFya3MgZnJvbSB0aGVcbiAgICBwbGFjZSB3aGVyZSBpdCBpcyBpbnNlcnRlZC5cbiAgICAqL1xuICAgIHJlcGxhY2VTZWxlY3Rpb25XaXRoKG5vZGUsIGluaGVyaXRNYXJrcyA9IHRydWUpIHtcbiAgICAgICAgbGV0IHNlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uO1xuICAgICAgICBpZiAoaW5oZXJpdE1hcmtzKVxuICAgICAgICAgICAgbm9kZSA9IG5vZGUubWFyayh0aGlzLnN0b3JlZE1hcmtzIHx8IChzZWxlY3Rpb24uZW1wdHkgPyBzZWxlY3Rpb24uJGZyb20ubWFya3MoKSA6IChzZWxlY3Rpb24uJGZyb20ubWFya3NBY3Jvc3Moc2VsZWN0aW9uLiR0bykgfHwgTWFyay5ub25lKSkpO1xuICAgICAgICBzZWxlY3Rpb24ucmVwbGFjZVdpdGgodGhpcywgbm9kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBEZWxldGUgdGhlIHNlbGVjdGlvbi5cbiAgICAqL1xuICAgIGRlbGV0ZVNlbGVjdGlvbigpIHtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb24ucmVwbGFjZSh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIGdpdmVuIHJhbmdlLCBvciB0aGUgc2VsZWN0aW9uIGlmIG5vIHJhbmdlIGlzIGdpdmVuLFxuICAgIHdpdGggYSB0ZXh0IG5vZGUgY29udGFpbmluZyB0aGUgZ2l2ZW4gc3RyaW5nLlxuICAgICovXG4gICAgaW5zZXJ0VGV4dCh0ZXh0LCBmcm9tLCB0bykge1xuICAgICAgICBsZXQgc2NoZW1hID0gdGhpcy5kb2MudHlwZS5zY2hlbWE7XG4gICAgICAgIGlmIChmcm9tID09IG51bGwpIHtcbiAgICAgICAgICAgIGlmICghdGV4dClcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWxldGVTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VTZWxlY3Rpb25XaXRoKHNjaGVtYS50ZXh0KHRleHQpLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0byA9PSBudWxsKVxuICAgICAgICAgICAgICAgIHRvID0gZnJvbTtcbiAgICAgICAgICAgIGlmICghdGV4dClcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWxldGVSYW5nZShmcm9tLCB0byk7XG4gICAgICAgICAgICBsZXQgbWFya3MgPSB0aGlzLnN0b3JlZE1hcmtzO1xuICAgICAgICAgICAgaWYgKCFtYXJrcykge1xuICAgICAgICAgICAgICAgIGxldCAkZnJvbSA9IHRoaXMuZG9jLnJlc29sdmUoZnJvbSk7XG4gICAgICAgICAgICAgICAgbWFya3MgPSB0byA9PSBmcm9tID8gJGZyb20ubWFya3MoKSA6ICRmcm9tLm1hcmtzQWNyb3NzKHRoaXMuZG9jLnJlc29sdmUodG8pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucmVwbGFjZVJhbmdlV2l0aChmcm9tLCB0bywgc2NoZW1hLnRleHQodGV4dCwgbWFya3MpKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZWxlY3Rpb24uZW1wdHkgJiYgdGhpcy5zZWxlY3Rpb24udG8gPT0gZnJvbSArIHRleHQubGVuZ3RoKVxuICAgICAgICAgICAgICAgIHRoaXMuc2V0U2VsZWN0aW9uKFNlbGVjdGlvbi5uZWFyKHRoaXMuc2VsZWN0aW9uLiR0bykpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgU3RvcmUgYSBtZXRhZGF0YSBwcm9wZXJ0eSBpbiB0aGlzIHRyYW5zYWN0aW9uLCBrZXllZCBlaXRoZXIgYnlcbiAgICBuYW1lIG9yIGJ5IHBsdWdpbi5cbiAgICAqL1xuICAgIHNldE1ldGEoa2V5LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLm1ldGFbdHlwZW9mIGtleSA9PSBcInN0cmluZ1wiID8ga2V5IDoga2V5LmtleV0gPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHJpZXZlIGEgbWV0YWRhdGEgcHJvcGVydHkgZm9yIGEgZ2l2ZW4gbmFtZSBvciBwbHVnaW4uXG4gICAgKi9cbiAgICBnZXRNZXRhKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tZXRhW3R5cGVvZiBrZXkgPT0gXCJzdHJpbmdcIiA/IGtleSA6IGtleS5rZXldO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm5zIHRydWUgaWYgdGhpcyB0cmFuc2FjdGlvbiBkb2Vzbid0IGNvbnRhaW4gYW55IG1ldGFkYXRhLFxuICAgIGFuZCBjYW4gdGh1cyBzYWZlbHkgYmUgZXh0ZW5kZWQuXG4gICAgKi9cbiAgICBnZXQgaXNHZW5lcmljKCkge1xuICAgICAgICBmb3IgKGxldCBfIGluIHRoaXMubWV0YSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgIEluZGljYXRlIHRoYXQgdGhlIGVkaXRvciBzaG91bGQgc2Nyb2xsIHRoZSBzZWxlY3Rpb24gaW50byB2aWV3XG4gICAgd2hlbiB1cGRhdGVkIHRvIHRoZSBzdGF0ZSBwcm9kdWNlZCBieSB0aGlzIHRyYW5zYWN0aW9uLlxuICAgICovXG4gICAgc2Nyb2xsSW50b1ZpZXcoKSB7XG4gICAgICAgIHRoaXMudXBkYXRlZCB8PSBVUERBVEVEX1NDUk9MTDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGlzIHRyYW5zYWN0aW9uIGhhcyBoYWQgYHNjcm9sbEludG9WaWV3YCBjYWxsZWQgb24gaXQuXG4gICAgKi9cbiAgICBnZXQgc2Nyb2xsZWRJbnRvVmlldygpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnVwZGF0ZWQgJiBVUERBVEVEX1NDUk9MTCkgPiAwO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gYmluZChmLCBzZWxmKSB7XG4gICAgcmV0dXJuICFzZWxmIHx8ICFmID8gZiA6IGYuYmluZChzZWxmKTtcbn1cbmNsYXNzIEZpZWxkRGVzYyB7XG4gICAgY29uc3RydWN0b3IobmFtZSwgZGVzYywgc2VsZikge1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLmluaXQgPSBiaW5kKGRlc2MuaW5pdCwgc2VsZik7XG4gICAgICAgIHRoaXMuYXBwbHkgPSBiaW5kKGRlc2MuYXBwbHksIHNlbGYpO1xuICAgIH1cbn1cbmNvbnN0IGJhc2VGaWVsZHMgPSBbXG4gICAgbmV3IEZpZWxkRGVzYyhcImRvY1wiLCB7XG4gICAgICAgIGluaXQoY29uZmlnKSB7IHJldHVybiBjb25maWcuZG9jIHx8IGNvbmZpZy5zY2hlbWEudG9wTm9kZVR5cGUuY3JlYXRlQW5kRmlsbCgpOyB9LFxuICAgICAgICBhcHBseSh0cikgeyByZXR1cm4gdHIuZG9jOyB9XG4gICAgfSksXG4gICAgbmV3IEZpZWxkRGVzYyhcInNlbGVjdGlvblwiLCB7XG4gICAgICAgIGluaXQoY29uZmlnLCBpbnN0YW5jZSkgeyByZXR1cm4gY29uZmlnLnNlbGVjdGlvbiB8fCBTZWxlY3Rpb24uYXRTdGFydChpbnN0YW5jZS5kb2MpOyB9LFxuICAgICAgICBhcHBseSh0cikgeyByZXR1cm4gdHIuc2VsZWN0aW9uOyB9XG4gICAgfSksXG4gICAgbmV3IEZpZWxkRGVzYyhcInN0b3JlZE1hcmtzXCIsIHtcbiAgICAgICAgaW5pdChjb25maWcpIHsgcmV0dXJuIGNvbmZpZy5zdG9yZWRNYXJrcyB8fCBudWxsOyB9LFxuICAgICAgICBhcHBseSh0ciwgX21hcmtzLCBfb2xkLCBzdGF0ZSkgeyByZXR1cm4gc3RhdGUuc2VsZWN0aW9uLiRjdXJzb3IgPyB0ci5zdG9yZWRNYXJrcyA6IG51bGw7IH1cbiAgICB9KSxcbiAgICBuZXcgRmllbGREZXNjKFwic2Nyb2xsVG9TZWxlY3Rpb25cIiwge1xuICAgICAgICBpbml0KCkgeyByZXR1cm4gMDsgfSxcbiAgICAgICAgYXBwbHkodHIsIHByZXYpIHsgcmV0dXJuIHRyLnNjcm9sbGVkSW50b1ZpZXcgPyBwcmV2ICsgMSA6IHByZXY7IH1cbiAgICB9KVxuXTtcbi8vIE9iamVjdCB3cmFwcGluZyB0aGUgcGFydCBvZiBhIHN0YXRlIG9iamVjdCB0aGF0IHN0YXlzIHRoZSBzYW1lXG4vLyBhY3Jvc3MgdHJhbnNhY3Rpb25zLiBTdG9yZWQgaW4gdGhlIHN0YXRlJ3MgYGNvbmZpZ2AgcHJvcGVydHkuXG5jbGFzcyBDb25maWd1cmF0aW9uIHtcbiAgICBjb25zdHJ1Y3RvcihzY2hlbWEsIHBsdWdpbnMpIHtcbiAgICAgICAgdGhpcy5zY2hlbWEgPSBzY2hlbWE7XG4gICAgICAgIHRoaXMucGx1Z2lucyA9IFtdO1xuICAgICAgICB0aGlzLnBsdWdpbnNCeUtleSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIHRoaXMuZmllbGRzID0gYmFzZUZpZWxkcy5zbGljZSgpO1xuICAgICAgICBpZiAocGx1Z2lucylcbiAgICAgICAgICAgIHBsdWdpbnMuZm9yRWFjaChwbHVnaW4gPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBsdWdpbnNCeUtleVtwbHVnaW4ua2V5XSlcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJBZGRpbmcgZGlmZmVyZW50IGluc3RhbmNlcyBvZiBhIGtleWVkIHBsdWdpbiAoXCIgKyBwbHVnaW4ua2V5ICsgXCIpXCIpO1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2lucy5wdXNoKHBsdWdpbik7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zQnlLZXlbcGx1Z2luLmtleV0gPSBwbHVnaW47XG4gICAgICAgICAgICAgICAgaWYgKHBsdWdpbi5zcGVjLnN0YXRlKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpZWxkcy5wdXNoKG5ldyBGaWVsZERlc2MocGx1Z2luLmtleSwgcGx1Z2luLnNwZWMuc3RhdGUsIHBsdWdpbikpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxufVxuLyoqXG5UaGUgc3RhdGUgb2YgYSBQcm9zZU1pcnJvciBlZGl0b3IgaXMgcmVwcmVzZW50ZWQgYnkgYW4gb2JqZWN0IG9mXG50aGlzIHR5cGUuIEEgc3RhdGUgaXMgYSBwZXJzaXN0ZW50IGRhdGEgc3RydWN0dXJlXHUyMDE0aXQgaXNuJ3RcbnVwZGF0ZWQsIGJ1dCByYXRoZXIgYSBuZXcgc3RhdGUgdmFsdWUgaXMgY29tcHV0ZWQgZnJvbSBhbiBvbGQgb25lXG51c2luZyB0aGUgW2BhcHBseWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5FZGl0b3JTdGF0ZS5hcHBseSkgbWV0aG9kLlxuXG5BIHN0YXRlIGhvbGRzIGEgbnVtYmVyIG9mIGJ1aWx0LWluIGZpZWxkcywgYW5kIHBsdWdpbnMgY2FuXG5bZGVmaW5lXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuUGx1Z2luU3BlYy5zdGF0ZSkgYWRkaXRpb25hbCBmaWVsZHMuXG4qL1xuY2xhc3MgRWRpdG9yU3RhdGUge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25maWcpIHtcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSBzY2hlbWEgb2YgdGhlIHN0YXRlJ3MgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBnZXQgc2NoZW1hKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuc2NoZW1hO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgcGx1Z2lucyB0aGF0IGFyZSBhY3RpdmUgaW4gdGhpcyBzdGF0ZS5cbiAgICAqL1xuICAgIGdldCBwbHVnaW5zKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcucGx1Z2lucztcbiAgICB9XG4gICAgLyoqXG4gICAgQXBwbHkgdGhlIGdpdmVuIHRyYW5zYWN0aW9uIHRvIHByb2R1Y2UgYSBuZXcgc3RhdGUuXG4gICAgKi9cbiAgICBhcHBseSh0cikge1xuICAgICAgICByZXR1cm4gdGhpcy5hcHBseVRyYW5zYWN0aW9uKHRyKS5zdGF0ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBmaWx0ZXJUcmFuc2FjdGlvbih0ciwgaWdub3JlID0gLTEpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNvbmZpZy5wbHVnaW5zLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKGkgIT0gaWdub3JlKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBsdWdpbiA9IHRoaXMuY29uZmlnLnBsdWdpbnNbaV07XG4gICAgICAgICAgICAgICAgaWYgKHBsdWdpbi5zcGVjLmZpbHRlclRyYW5zYWN0aW9uICYmICFwbHVnaW4uc3BlYy5maWx0ZXJUcmFuc2FjdGlvbi5jYWxsKHBsdWdpbiwgdHIsIHRoaXMpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICBWZXJib3NlIHZhcmlhbnQgb2YgW2BhcHBseWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5FZGl0b3JTdGF0ZS5hcHBseSkgdGhhdFxuICAgIHJldHVybnMgdGhlIHByZWNpc2UgdHJhbnNhY3Rpb25zIHRoYXQgd2VyZSBhcHBsaWVkICh3aGljaCBtaWdodFxuICAgIGJlIGluZmx1ZW5jZWQgYnkgdGhlIFt0cmFuc2FjdGlvblxuICAgIGhvb2tzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuUGx1Z2luU3BlYy5maWx0ZXJUcmFuc2FjdGlvbikgb2ZcbiAgICBwbHVnaW5zKSBhbG9uZyB3aXRoIHRoZSBuZXcgc3RhdGUuXG4gICAgKi9cbiAgICBhcHBseVRyYW5zYWN0aW9uKHJvb3RUcikge1xuICAgICAgICBpZiAoIXRoaXMuZmlsdGVyVHJhbnNhY3Rpb24ocm9vdFRyKSlcbiAgICAgICAgICAgIHJldHVybiB7IHN0YXRlOiB0aGlzLCB0cmFuc2FjdGlvbnM6IFtdIH07XG4gICAgICAgIGxldCB0cnMgPSBbcm9vdFRyXSwgbmV3U3RhdGUgPSB0aGlzLmFwcGx5SW5uZXIocm9vdFRyKSwgc2VlbiA9IG51bGw7XG4gICAgICAgIC8vIFRoaXMgbG9vcCByZXBlYXRlZGx5IGdpdmVzIHBsdWdpbnMgYSBjaGFuY2UgdG8gcmVzcG9uZCB0b1xuICAgICAgICAvLyB0cmFuc2FjdGlvbnMgYXMgbmV3IHRyYW5zYWN0aW9ucyBhcmUgYWRkZWQsIG1ha2luZyBzdXJlIHRvIG9ubHlcbiAgICAgICAgLy8gcGFzcyB0aGUgdHJhbnNhY3Rpb25zIHRoZSBwbHVnaW4gZGlkIG5vdCBzZWUgYmVmb3JlLlxuICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgICBsZXQgaGF2ZU5ldyA9IGZhbHNlO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNvbmZpZy5wbHVnaW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBsdWdpbiA9IHRoaXMuY29uZmlnLnBsdWdpbnNbaV07XG4gICAgICAgICAgICAgICAgaWYgKHBsdWdpbi5zcGVjLmFwcGVuZFRyYW5zYWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBuID0gc2VlbiA/IHNlZW5baV0ubiA6IDAsIG9sZFN0YXRlID0gc2VlbiA/IHNlZW5baV0uc3RhdGUgOiB0aGlzO1xuICAgICAgICAgICAgICAgICAgICBsZXQgdHIgPSBuIDwgdHJzLmxlbmd0aCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luLnNwZWMuYXBwZW5kVHJhbnNhY3Rpb24uY2FsbChwbHVnaW4sIG4gPyB0cnMuc2xpY2UobikgOiB0cnMsIG9sZFN0YXRlLCBuZXdTdGF0ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0ciAmJiBuZXdTdGF0ZS5maWx0ZXJUcmFuc2FjdGlvbih0ciwgaSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyLnNldE1ldGEoXCJhcHBlbmRlZFRyYW5zYWN0aW9uXCIsIHJvb3RUcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNlZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVuID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLmNvbmZpZy5wbHVnaW5zLmxlbmd0aDsgaisrKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVuLnB1c2goaiA8IGkgPyB7IHN0YXRlOiBuZXdTdGF0ZSwgbjogdHJzLmxlbmd0aCB9IDogeyBzdGF0ZTogdGhpcywgbjogMCB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHRycy5wdXNoKHRyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1N0YXRlID0gbmV3U3RhdGUuYXBwbHlJbm5lcih0cik7XG4gICAgICAgICAgICAgICAgICAgICAgICBoYXZlTmV3ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VlbilcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlZW5baV0gPSB7IHN0YXRlOiBuZXdTdGF0ZSwgbjogdHJzLmxlbmd0aCB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaGF2ZU5ldylcbiAgICAgICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogbmV3U3RhdGUsIHRyYW5zYWN0aW9uczogdHJzIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBhcHBseUlubmVyKHRyKSB7XG4gICAgICAgIGlmICghdHIuYmVmb3JlLmVxKHRoaXMuZG9jKSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiQXBwbHlpbmcgYSBtaXNtYXRjaGVkIHRyYW5zYWN0aW9uXCIpO1xuICAgICAgICBsZXQgbmV3SW5zdGFuY2UgPSBuZXcgRWRpdG9yU3RhdGUodGhpcy5jb25maWcpLCBmaWVsZHMgPSB0aGlzLmNvbmZpZy5maWVsZHM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgZmllbGQgPSBmaWVsZHNbaV07XG4gICAgICAgICAgICBuZXdJbnN0YW5jZVtmaWVsZC5uYW1lXSA9IGZpZWxkLmFwcGx5KHRyLCB0aGlzW2ZpZWxkLm5hbWVdLCB0aGlzLCBuZXdJbnN0YW5jZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ld0luc3RhbmNlO1xuICAgIH1cbiAgICAvKipcbiAgICBBY2Nlc3NvciB0aGF0IGNvbnN0cnVjdHMgYW5kIHJldHVybnMgYSBuZXcgW3RyYW5zYWN0aW9uXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuVHJhbnNhY3Rpb24pIGZyb20gdGhpcyBzdGF0ZS5cbiAgICAqL1xuICAgIGdldCB0cigpIHsgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbih0aGlzKTsgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5ldyBzdGF0ZS5cbiAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGUoY29uZmlnKSB7XG4gICAgICAgIGxldCAkY29uZmlnID0gbmV3IENvbmZpZ3VyYXRpb24oY29uZmlnLmRvYyA/IGNvbmZpZy5kb2MudHlwZS5zY2hlbWEgOiBjb25maWcuc2NoZW1hLCBjb25maWcucGx1Z2lucyk7XG4gICAgICAgIGxldCBpbnN0YW5jZSA9IG5ldyBFZGl0b3JTdGF0ZSgkY29uZmlnKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAkY29uZmlnLmZpZWxkcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGluc3RhbmNlWyRjb25maWcuZmllbGRzW2ldLm5hbWVdID0gJGNvbmZpZy5maWVsZHNbaV0uaW5pdChjb25maWcsIGluc3RhbmNlKTtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBuZXcgc3RhdGUgYmFzZWQgb24gdGhpcyBvbmUsIGJ1dCB3aXRoIGFuIGFkanVzdGVkIHNldFxuICAgIG9mIGFjdGl2ZSBwbHVnaW5zLiBTdGF0ZSBmaWVsZHMgdGhhdCBleGlzdCBpbiBib3RoIHNldHMgb2ZcbiAgICBwbHVnaW5zIGFyZSBrZXB0IHVuY2hhbmdlZC4gVGhvc2UgdGhhdCBubyBsb25nZXIgZXhpc3QgYXJlXG4gICAgZHJvcHBlZCwgYW5kIHRob3NlIHRoYXQgYXJlIG5ldyBhcmUgaW5pdGlhbGl6ZWQgdXNpbmcgdGhlaXJcbiAgICBbYGluaXRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuU3RhdGVGaWVsZC5pbml0KSBtZXRob2QsIHBhc3NpbmcgaW4gdGhlIG5ld1xuICAgIGNvbmZpZ3VyYXRpb24gb2JqZWN0Li5cbiAgICAqL1xuICAgIHJlY29uZmlndXJlKGNvbmZpZykge1xuICAgICAgICBsZXQgJGNvbmZpZyA9IG5ldyBDb25maWd1cmF0aW9uKHRoaXMuc2NoZW1hLCBjb25maWcucGx1Z2lucyk7XG4gICAgICAgIGxldCBmaWVsZHMgPSAkY29uZmlnLmZpZWxkcywgaW5zdGFuY2UgPSBuZXcgRWRpdG9yU3RhdGUoJGNvbmZpZyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbmFtZSA9IGZpZWxkc1tpXS5uYW1lO1xuICAgICAgICAgICAgaW5zdGFuY2VbbmFtZV0gPSB0aGlzLmhhc093blByb3BlcnR5KG5hbWUpID8gdGhpc1tuYW1lXSA6IGZpZWxkc1tpXS5pbml0KGNvbmZpZywgaW5zdGFuY2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9XG4gICAgLyoqXG4gICAgU2VyaWFsaXplIHRoaXMgc3RhdGUgdG8gSlNPTi4gSWYgeW91IHdhbnQgdG8gc2VyaWFsaXplIHRoZSBzdGF0ZVxuICAgIG9mIHBsdWdpbnMsIHBhc3MgYW4gb2JqZWN0IG1hcHBpbmcgcHJvcGVydHkgbmFtZXMgdG8gdXNlIGluIHRoZVxuICAgIHJlc3VsdGluZyBKU09OIG9iamVjdCB0byBwbHVnaW4gb2JqZWN0cy4gVGhlIGFyZ3VtZW50IG1heSBhbHNvIGJlXG4gICAgYSBzdHJpbmcgb3IgbnVtYmVyLCBpbiB3aGljaCBjYXNlIGl0IGlzIGlnbm9yZWQsIHRvIHN1cHBvcnQgdGhlXG4gICAgd2F5IGBKU09OLnN0cmluZ2lmeWAgY2FsbHMgYHRvU3RyaW5nYCBtZXRob2RzLlxuICAgICovXG4gICAgdG9KU09OKHBsdWdpbkZpZWxkcykge1xuICAgICAgICBsZXQgcmVzdWx0ID0geyBkb2M6IHRoaXMuZG9jLnRvSlNPTigpLCBzZWxlY3Rpb246IHRoaXMuc2VsZWN0aW9uLnRvSlNPTigpIH07XG4gICAgICAgIGlmICh0aGlzLnN0b3JlZE1hcmtzKVxuICAgICAgICAgICAgcmVzdWx0LnN0b3JlZE1hcmtzID0gdGhpcy5zdG9yZWRNYXJrcy5tYXAobSA9PiBtLnRvSlNPTigpKTtcbiAgICAgICAgaWYgKHBsdWdpbkZpZWxkcyAmJiB0eXBlb2YgcGx1Z2luRmllbGRzID09ICdvYmplY3QnKVxuICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBwbHVnaW5GaWVsZHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCA9PSBcImRvY1wiIHx8IHByb3AgPT0gXCJzZWxlY3Rpb25cIilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgSlNPTiBmaWVsZHMgYGRvY2AgYW5kIGBzZWxlY3Rpb25gIGFyZSByZXNlcnZlZFwiKTtcbiAgICAgICAgICAgICAgICBsZXQgcGx1Z2luID0gcGx1Z2luRmllbGRzW3Byb3BdLCBzdGF0ZSA9IHBsdWdpbi5zcGVjLnN0YXRlO1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZSAmJiBzdGF0ZS50b0pTT04pXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFtwcm9wXSA9IHN0YXRlLnRvSlNPTi5jYWxsKHBsdWdpbiwgdGhpc1twbHVnaW4ua2V5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKlxuICAgIERlc2VyaWFsaXplIGEgSlNPTiByZXByZXNlbnRhdGlvbiBvZiBhIHN0YXRlLiBgY29uZmlnYCBzaG91bGRcbiAgICBoYXZlIGF0IGxlYXN0IGEgYHNjaGVtYWAgZmllbGQsIGFuZCBzaG91bGQgY29udGFpbiBhcnJheSBvZlxuICAgIHBsdWdpbnMgdG8gaW5pdGlhbGl6ZSB0aGUgc3RhdGUgd2l0aC4gYHBsdWdpbkZpZWxkc2AgY2FuIGJlIHVzZWRcbiAgICB0byBkZXNlcmlhbGl6ZSB0aGUgc3RhdGUgb2YgcGx1Z2lucywgYnkgYXNzb2NpYXRpbmcgcGx1Z2luXG4gICAgaW5zdGFuY2VzIHdpdGggdGhlIHByb3BlcnR5IG5hbWVzIHRoZXkgdXNlIGluIHRoZSBKU09OIG9iamVjdC5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihjb25maWcsIGpzb24sIHBsdWdpbkZpZWxkcykge1xuICAgICAgICBpZiAoIWpzb24pXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIEVkaXRvclN0YXRlLmZyb21KU09OXCIpO1xuICAgICAgICBpZiAoIWNvbmZpZy5zY2hlbWEpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlJlcXVpcmVkIGNvbmZpZyBmaWVsZCAnc2NoZW1hJyBtaXNzaW5nXCIpO1xuICAgICAgICBsZXQgJGNvbmZpZyA9IG5ldyBDb25maWd1cmF0aW9uKGNvbmZpZy5zY2hlbWEsIGNvbmZpZy5wbHVnaW5zKTtcbiAgICAgICAgbGV0IGluc3RhbmNlID0gbmV3IEVkaXRvclN0YXRlKCRjb25maWcpO1xuICAgICAgICAkY29uZmlnLmZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgICAgICAgIGlmIChmaWVsZC5uYW1lID09IFwiZG9jXCIpIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5kb2MgPSBOb2RlLmZyb21KU09OKGNvbmZpZy5zY2hlbWEsIGpzb24uZG9jKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGZpZWxkLm5hbWUgPT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGluc3RhbmNlLnNlbGVjdGlvbiA9IFNlbGVjdGlvbi5mcm9tSlNPTihpbnN0YW5jZS5kb2MsIGpzb24uc2VsZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGZpZWxkLm5hbWUgPT0gXCJzdG9yZWRNYXJrc1wiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGpzb24uc3RvcmVkTWFya3MpXG4gICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnN0b3JlZE1hcmtzID0ganNvbi5zdG9yZWRNYXJrcy5tYXAoY29uZmlnLnNjaGVtYS5tYXJrRnJvbUpTT04pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHBsdWdpbkZpZWxkcylcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBwbHVnaW5GaWVsZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwbHVnaW4gPSBwbHVnaW5GaWVsZHNbcHJvcF0sIHN0YXRlID0gcGx1Z2luLnNwZWMuc3RhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGx1Z2luLmtleSA9PSBmaWVsZC5uYW1lICYmIHN0YXRlICYmIHN0YXRlLmZyb21KU09OICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGpzb24sIHByb3ApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VbZmllbGQubmFtZV0gPSBzdGF0ZS5mcm9tSlNPTi5jYWxsKHBsdWdpbiwgY29uZmlnLCBqc29uW3Byb3BdLCBpbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaW5zdGFuY2VbZmllbGQubmFtZV0gPSBmaWVsZC5pbml0KGNvbmZpZywgaW5zdGFuY2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gYmluZFByb3BzKG9iaiwgc2VsZiwgdGFyZ2V0KSB7XG4gICAgZm9yIChsZXQgcHJvcCBpbiBvYmopIHtcbiAgICAgICAgbGV0IHZhbCA9IG9ialtwcm9wXTtcbiAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAgICAgICAgdmFsID0gdmFsLmJpbmQoc2VsZik7XG4gICAgICAgIGVsc2UgaWYgKHByb3AgPT0gXCJoYW5kbGVET01FdmVudHNcIilcbiAgICAgICAgICAgIHZhbCA9IGJpbmRQcm9wcyh2YWwsIHNlbGYsIHt9KTtcbiAgICAgICAgdGFyZ2V0W3Byb3BdID0gdmFsO1xuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0O1xufVxuLyoqXG5QbHVnaW5zIGJ1bmRsZSBmdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlIGFkZGVkIHRvIGFuIGVkaXRvci5cblRoZXkgYXJlIHBhcnQgb2YgdGhlIFtlZGl0b3Igc3RhdGVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5FZGl0b3JTdGF0ZSkgYW5kXG5tYXkgaW5mbHVlbmNlIHRoYXQgc3RhdGUgYW5kIHRoZSB2aWV3IHRoYXQgY29udGFpbnMgaXQuXG4qL1xuY2xhc3MgUGx1Z2luIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBwbHVnaW4uXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgcGx1Z2luJ3MgW3NwZWMgb2JqZWN0XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuUGx1Z2luU3BlYykuXG4gICAgKi9cbiAgICBzcGVjKSB7XG4gICAgICAgIHRoaXMuc3BlYyA9IHNwZWM7XG4gICAgICAgIC8qKlxuICAgICAgICBUaGUgW3Byb3BzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdmlldy5FZGl0b3JQcm9wcykgZXhwb3J0ZWQgYnkgdGhpcyBwbHVnaW4uXG4gICAgICAgICovXG4gICAgICAgIHRoaXMucHJvcHMgPSB7fTtcbiAgICAgICAgaWYgKHNwZWMucHJvcHMpXG4gICAgICAgICAgICBiaW5kUHJvcHMoc3BlYy5wcm9wcywgdGhpcywgdGhpcy5wcm9wcyk7XG4gICAgICAgIHRoaXMua2V5ID0gc3BlYy5rZXkgPyBzcGVjLmtleS5rZXkgOiBjcmVhdGVLZXkoXCJwbHVnaW5cIik7XG4gICAgfVxuICAgIC8qKlxuICAgIEV4dHJhY3QgdGhlIHBsdWdpbidzIHN0YXRlIGZpZWxkIGZyb20gYW4gZWRpdG9yIHN0YXRlLlxuICAgICovXG4gICAgZ2V0U3RhdGUoc3RhdGUpIHsgcmV0dXJuIHN0YXRlW3RoaXMua2V5XTsgfVxufVxuY29uc3Qga2V5cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5mdW5jdGlvbiBjcmVhdGVLZXkobmFtZSkge1xuICAgIGlmIChuYW1lIGluIGtleXMpXG4gICAgICAgIHJldHVybiBuYW1lICsgXCIkXCIgKyArK2tleXNbbmFtZV07XG4gICAga2V5c1tuYW1lXSA9IDA7XG4gICAgcmV0dXJuIG5hbWUgKyBcIiRcIjtcbn1cbi8qKlxuQSBrZXkgaXMgdXNlZCB0byBbdGFnXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuUGx1Z2luU3BlYy5rZXkpIHBsdWdpbnMgaW4gYSB3YXlcbnRoYXQgbWFrZXMgaXQgcG9zc2libGUgdG8gZmluZCB0aGVtLCBnaXZlbiBhbiBlZGl0b3Igc3RhdGUuXG5Bc3NpZ25pbmcgYSBrZXkgZG9lcyBtZWFuIG9ubHkgb25lIHBsdWdpbiBvZiB0aGF0IHR5cGUgY2FuIGJlXG5hY3RpdmUgaW4gYSBzdGF0ZS5cbiovXG5jbGFzcyBQbHVnaW5LZXkge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIHBsdWdpbiBrZXkuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihuYW1lID0gXCJrZXlcIikgeyB0aGlzLmtleSA9IGNyZWF0ZUtleShuYW1lKTsgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgYWN0aXZlIHBsdWdpbiB3aXRoIHRoaXMga2V5LCBpZiBhbnksIGZyb20gYW4gZWRpdG9yXG4gICAgc3RhdGUuXG4gICAgKi9cbiAgICBnZXQoc3RhdGUpIHsgcmV0dXJuIHN0YXRlLmNvbmZpZy5wbHVnaW5zQnlLZXlbdGhpcy5rZXldOyB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBwbHVnaW4ncyBzdGF0ZSBmcm9tIGFuIGVkaXRvciBzdGF0ZS5cbiAgICAqL1xuICAgIGdldFN0YXRlKHN0YXRlKSB7IHJldHVybiBzdGF0ZVt0aGlzLmtleV07IH1cbn1cblxuZXhwb3J0IHsgQWxsU2VsZWN0aW9uLCBFZGl0b3JTdGF0ZSwgTm9kZVNlbGVjdGlvbiwgUGx1Z2luLCBQbHVnaW5LZXksIFNlbGVjdGlvbiwgU2VsZWN0aW9uUmFuZ2UsIFRleHRTZWxlY3Rpb24sIFRyYW5zYWN0aW9uIH07XG4iLCAiaW1wb3J0IHsgbGlmdFRhcmdldCwgcmVwbGFjZVN0ZXAsIFJlcGxhY2VTdGVwLCBjYW5Kb2luLCBqb2luUG9pbnQsIGNhblNwbGl0LCBSZXBsYWNlQXJvdW5kU3RlcCwgZmluZFdyYXBwaW5nIH0gZnJvbSAncHJvc2VtaXJyb3ItdHJhbnNmb3JtJztcbmltcG9ydCB7IFNsaWNlLCBGcmFnbWVudCB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB7IE5vZGVTZWxlY3Rpb24sIFNlbGVjdGlvbiwgVGV4dFNlbGVjdGlvbiwgQWxsU2VsZWN0aW9uLCBTZWxlY3Rpb25SYW5nZSB9IGZyb20gJ3Byb3NlbWlycm9yLXN0YXRlJztcblxuLyoqXG5EZWxldGUgdGhlIHNlbGVjdGlvbiwgaWYgdGhlcmUgaXMgb25lLlxuKi9cbmNvbnN0IGRlbGV0ZVNlbGVjdGlvbiA9IChzdGF0ZSwgZGlzcGF0Y2gpID0+IHtcbiAgICBpZiAoc3RhdGUuc2VsZWN0aW9uLmVtcHR5KVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5kZWxldGVTZWxlY3Rpb24oKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5mdW5jdGlvbiBhdEJsb2NrU3RhcnQoc3RhdGUsIHZpZXcpIHtcbiAgICBsZXQgeyAkY3Vyc29yIH0gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgaWYgKCEkY3Vyc29yIHx8ICh2aWV3ID8gIXZpZXcuZW5kT2ZUZXh0YmxvY2soXCJiYWNrd2FyZFwiLCBzdGF0ZSlcbiAgICAgICAgOiAkY3Vyc29yLnBhcmVudE9mZnNldCA+IDApKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gJGN1cnNvcjtcbn1cbi8qKlxuSWYgdGhlIHNlbGVjdGlvbiBpcyBlbXB0eSBhbmQgYXQgdGhlIHN0YXJ0IG9mIGEgdGV4dGJsb2NrLCB0cnkgdG9cbnJlZHVjZSB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGF0IGJsb2NrIGFuZCB0aGUgb25lIGJlZm9yZSBpdFx1MjAxNGlmXG50aGVyZSdzIGEgYmxvY2sgZGlyZWN0bHkgYmVmb3JlIGl0IHRoYXQgY2FuIGJlIGpvaW5lZCwgam9pbiB0aGVtLlxuSWYgbm90LCB0cnkgdG8gbW92ZSB0aGUgc2VsZWN0ZWQgYmxvY2sgY2xvc2VyIHRvIHRoZSBuZXh0IG9uZSBpblxudGhlIGRvY3VtZW50IHN0cnVjdHVyZSBieSBsaWZ0aW5nIGl0IG91dCBvZiBpdHMgcGFyZW50IG9yIG1vdmluZyBpdFxuaW50byBhIHBhcmVudCBvZiB0aGUgcHJldmlvdXMgYmxvY2suIFdpbGwgdXNlIHRoZSB2aWV3IGZvciBhY2N1cmF0ZVxuKGJpZGktYXdhcmUpIHN0YXJ0LW9mLXRleHRibG9jayBkZXRlY3Rpb24gaWYgZ2l2ZW4uXG4qL1xuY29uc3Qgam9pbkJhY2t3YXJkID0gKHN0YXRlLCBkaXNwYXRjaCwgdmlldykgPT4ge1xuICAgIGxldCAkY3Vyc29yID0gYXRCbG9ja1N0YXJ0KHN0YXRlLCB2aWV3KTtcbiAgICBpZiAoISRjdXJzb3IpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgJGN1dCA9IGZpbmRDdXRCZWZvcmUoJGN1cnNvcik7XG4gICAgLy8gSWYgdGhlcmUgaXMgbm8gbm9kZSBiZWZvcmUgdGhpcywgdHJ5IHRvIGxpZnRcbiAgICBpZiAoISRjdXQpIHtcbiAgICAgICAgbGV0IHJhbmdlID0gJGN1cnNvci5ibG9ja1JhbmdlKCksIHRhcmdldCA9IHJhbmdlICYmIGxpZnRUYXJnZXQocmFuZ2UpO1xuICAgICAgICBpZiAodGFyZ2V0ID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLmxpZnQocmFuZ2UsIHRhcmdldCkuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBsZXQgYmVmb3JlID0gJGN1dC5ub2RlQmVmb3JlO1xuICAgIC8vIEFwcGx5IHRoZSBqb2luaW5nIGFsZ29yaXRobVxuICAgIGlmIChkZWxldGVCYXJyaWVyKHN0YXRlLCAkY3V0LCBkaXNwYXRjaCwgLTEpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAvLyBJZiB0aGUgbm9kZSBiZWxvdyBoYXMgbm8gY29udGVudCBhbmQgdGhlIG5vZGUgYWJvdmUgaXNcbiAgICAvLyBzZWxlY3RhYmxlLCBkZWxldGUgdGhlIG5vZGUgYmVsb3cgYW5kIHNlbGVjdCB0aGUgb25lIGFib3ZlLlxuICAgIGlmICgkY3Vyc29yLnBhcmVudC5jb250ZW50LnNpemUgPT0gMCAmJlxuICAgICAgICAodGV4dGJsb2NrQXQoYmVmb3JlLCBcImVuZFwiKSB8fCBOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZShiZWZvcmUpKSkge1xuICAgICAgICBmb3IgKGxldCBkZXB0aCA9ICRjdXJzb3IuZGVwdGg7OyBkZXB0aC0tKSB7XG4gICAgICAgICAgICBsZXQgZGVsU3RlcCA9IHJlcGxhY2VTdGVwKHN0YXRlLmRvYywgJGN1cnNvci5iZWZvcmUoZGVwdGgpLCAkY3Vyc29yLmFmdGVyKGRlcHRoKSwgU2xpY2UuZW1wdHkpO1xuICAgICAgICAgICAgaWYgKGRlbFN0ZXAgJiYgZGVsU3RlcC5zbGljZS5zaXplIDwgZGVsU3RlcC50byAtIGRlbFN0ZXAuZnJvbSkge1xuICAgICAgICAgICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdHIgPSBzdGF0ZS50ci5zdGVwKGRlbFN0ZXApO1xuICAgICAgICAgICAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24odGV4dGJsb2NrQXQoYmVmb3JlLCBcImVuZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBTZWxlY3Rpb24uZmluZEZyb20odHIuZG9jLnJlc29sdmUodHIubWFwcGluZy5tYXAoJGN1dC5wb3MsIC0xKSksIC0xKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBOb2RlU2VsZWN0aW9uLmNyZWF0ZSh0ci5kb2MsICRjdXQucG9zIC0gYmVmb3JlLm5vZGVTaXplKSk7XG4gICAgICAgICAgICAgICAgICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkZXB0aCA9PSAxIHx8ICRjdXJzb3Iubm9kZShkZXB0aCAtIDEpLmNoaWxkQ291bnQgPiAxKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIElmIHRoZSBub2RlIGJlZm9yZSBpcyBhbiBhdG9tLCBkZWxldGUgaXRcbiAgICBpZiAoYmVmb3JlLmlzQXRvbSAmJiAkY3V0LmRlcHRoID09ICRjdXJzb3IuZGVwdGggLSAxKSB7XG4gICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLmRlbGV0ZSgkY3V0LnBvcyAtIGJlZm9yZS5ub2RlU2l6ZSwgJGN1dC5wb3MpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbi8qKlxuQSBtb3JlIGxpbWl0ZWQgZm9ybSBvZiBbYGpvaW5CYWNrd2FyZGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNjb21tYW5kcy5qb2luQmFja3dhcmQpXG50aGF0IG9ubHkgdHJpZXMgdG8gam9pbiB0aGUgY3VycmVudCB0ZXh0YmxvY2sgdG8gdGhlIG9uZSBiZWZvcmVcbml0LCBpZiB0aGUgY3Vyc29yIGlzIGF0IHRoZSBzdGFydCBvZiBhIHRleHRibG9jay5cbiovXG5jb25zdCBqb2luVGV4dGJsb2NrQmFja3dhcmQgPSAoc3RhdGUsIGRpc3BhdGNoLCB2aWV3KSA9PiB7XG4gICAgbGV0ICRjdXJzb3IgPSBhdEJsb2NrU3RhcnQoc3RhdGUsIHZpZXcpO1xuICAgIGlmICghJGN1cnNvcilcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCAkY3V0ID0gZmluZEN1dEJlZm9yZSgkY3Vyc29yKTtcbiAgICByZXR1cm4gJGN1dCA/IGpvaW5UZXh0YmxvY2tzQXJvdW5kKHN0YXRlLCAkY3V0LCBkaXNwYXRjaCkgOiBmYWxzZTtcbn07XG4vKipcbkEgbW9yZSBsaW1pdGVkIGZvcm0gb2YgW2Bqb2luRm9yd2FyZGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNjb21tYW5kcy5qb2luRm9yd2FyZClcbnRoYXQgb25seSB0cmllcyB0byBqb2luIHRoZSBjdXJyZW50IHRleHRibG9jayB0byB0aGUgb25lIGFmdGVyXG5pdCwgaWYgdGhlIGN1cnNvciBpcyBhdCB0aGUgZW5kIG9mIGEgdGV4dGJsb2NrLlxuKi9cbmNvbnN0IGpvaW5UZXh0YmxvY2tGb3J3YXJkID0gKHN0YXRlLCBkaXNwYXRjaCwgdmlldykgPT4ge1xuICAgIGxldCAkY3Vyc29yID0gYXRCbG9ja0VuZChzdGF0ZSwgdmlldyk7XG4gICAgaWYgKCEkY3Vyc29yKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0ICRjdXQgPSBmaW5kQ3V0QWZ0ZXIoJGN1cnNvcik7XG4gICAgcmV0dXJuICRjdXQgPyBqb2luVGV4dGJsb2Nrc0Fyb3VuZChzdGF0ZSwgJGN1dCwgZGlzcGF0Y2gpIDogZmFsc2U7XG59O1xuZnVuY3Rpb24gam9pblRleHRibG9ja3NBcm91bmQoc3RhdGUsICRjdXQsIGRpc3BhdGNoKSB7XG4gICAgbGV0IGJlZm9yZSA9ICRjdXQubm9kZUJlZm9yZSwgYmVmb3JlVGV4dCA9IGJlZm9yZSwgYmVmb3JlUG9zID0gJGN1dC5wb3MgLSAxO1xuICAgIGZvciAoOyAhYmVmb3JlVGV4dC5pc1RleHRibG9jazsgYmVmb3JlUG9zLS0pIHtcbiAgICAgICAgaWYgKGJlZm9yZVRleHQudHlwZS5zcGVjLmlzb2xhdGluZylcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgbGV0IGNoaWxkID0gYmVmb3JlVGV4dC5sYXN0Q2hpbGQ7XG4gICAgICAgIGlmICghY2hpbGQpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGJlZm9yZVRleHQgPSBjaGlsZDtcbiAgICB9XG4gICAgbGV0IGFmdGVyID0gJGN1dC5ub2RlQWZ0ZXIsIGFmdGVyVGV4dCA9IGFmdGVyLCBhZnRlclBvcyA9ICRjdXQucG9zICsgMTtcbiAgICBmb3IgKDsgIWFmdGVyVGV4dC5pc1RleHRibG9jazsgYWZ0ZXJQb3MrKykge1xuICAgICAgICBpZiAoYWZ0ZXJUZXh0LnR5cGUuc3BlYy5pc29sYXRpbmcpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGxldCBjaGlsZCA9IGFmdGVyVGV4dC5maXJzdENoaWxkO1xuICAgICAgICBpZiAoIWNoaWxkKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBhZnRlclRleHQgPSBjaGlsZDtcbiAgICB9XG4gICAgbGV0IHN0ZXAgPSByZXBsYWNlU3RlcChzdGF0ZS5kb2MsIGJlZm9yZVBvcywgYWZ0ZXJQb3MsIFNsaWNlLmVtcHR5KTtcbiAgICBpZiAoIXN0ZXAgfHwgc3RlcC5mcm9tICE9IGJlZm9yZVBvcyB8fFxuICAgICAgICBzdGVwIGluc3RhbmNlb2YgUmVwbGFjZVN0ZXAgJiYgc3RlcC5zbGljZS5zaXplID49IGFmdGVyUG9zIC0gYmVmb3JlUG9zKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgIGxldCB0ciA9IHN0YXRlLnRyLnN0ZXAoc3RlcCk7XG4gICAgICAgIHRyLnNldFNlbGVjdGlvbihUZXh0U2VsZWN0aW9uLmNyZWF0ZSh0ci5kb2MsIGJlZm9yZVBvcykpO1xuICAgICAgICBkaXNwYXRjaCh0ci5zY3JvbGxJbnRvVmlldygpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiB0ZXh0YmxvY2tBdChub2RlLCBzaWRlLCBvbmx5ID0gZmFsc2UpIHtcbiAgICBmb3IgKGxldCBzY2FuID0gbm9kZTsgc2Nhbjsgc2NhbiA9IChzaWRlID09IFwic3RhcnRcIiA/IHNjYW4uZmlyc3RDaGlsZCA6IHNjYW4ubGFzdENoaWxkKSkge1xuICAgICAgICBpZiAoc2Nhbi5pc1RleHRibG9jaylcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAob25seSAmJiBzY2FuLmNoaWxkQ291bnQgIT0gMSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuLyoqXG5XaGVuIHRoZSBzZWxlY3Rpb24gaXMgZW1wdHkgYW5kIGF0IHRoZSBzdGFydCBvZiBhIHRleHRibG9jaywgc2VsZWN0XG50aGUgbm9kZSBiZWZvcmUgdGhhdCB0ZXh0YmxvY2ssIGlmIHBvc3NpYmxlLiBUaGlzIGlzIGludGVuZGVkIHRvIGJlXG5ib3VuZCB0byBrZXlzIGxpa2UgYmFja3NwYWNlLCBhZnRlclxuW2Bqb2luQmFja3dhcmRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jY29tbWFuZHMuam9pbkJhY2t3YXJkKSBvciBvdGhlciBkZWxldGluZ1xuY29tbWFuZHMsIGFzIGEgZmFsbC1iYWNrIGJlaGF2aW9yIHdoZW4gdGhlIHNjaGVtYSBkb2Vzbid0IGFsbG93XG5kZWxldGlvbiBhdCB0aGUgc2VsZWN0ZWQgcG9pbnQuXG4qL1xuY29uc3Qgc2VsZWN0Tm9kZUJhY2t3YXJkID0gKHN0YXRlLCBkaXNwYXRjaCwgdmlldykgPT4ge1xuICAgIGxldCB7ICRoZWFkLCBlbXB0eSB9ID0gc3RhdGUuc2VsZWN0aW9uLCAkY3V0ID0gJGhlYWQ7XG4gICAgaWYgKCFlbXB0eSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmICgkaGVhZC5wYXJlbnQuaXNUZXh0YmxvY2spIHtcbiAgICAgICAgaWYgKHZpZXcgPyAhdmlldy5lbmRPZlRleHRibG9jayhcImJhY2t3YXJkXCIsIHN0YXRlKSA6ICRoZWFkLnBhcmVudE9mZnNldCA+IDApXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICRjdXQgPSBmaW5kQ3V0QmVmb3JlKCRoZWFkKTtcbiAgICB9XG4gICAgbGV0IG5vZGUgPSAkY3V0ICYmICRjdXQubm9kZUJlZm9yZTtcbiAgICBpZiAoIW5vZGUgfHwgIU5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKG5vZGUpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5zZXRTZWxlY3Rpb24oTm9kZVNlbGVjdGlvbi5jcmVhdGUoc3RhdGUuZG9jLCAkY3V0LnBvcyAtIG5vZGUubm9kZVNpemUpKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5mdW5jdGlvbiBmaW5kQ3V0QmVmb3JlKCRwb3MpIHtcbiAgICBpZiAoISRwb3MucGFyZW50LnR5cGUuc3BlYy5pc29sYXRpbmcpXG4gICAgICAgIGZvciAobGV0IGkgPSAkcG9zLmRlcHRoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGlmICgkcG9zLmluZGV4KGkpID4gMClcbiAgICAgICAgICAgICAgICByZXR1cm4gJHBvcy5kb2MucmVzb2x2ZSgkcG9zLmJlZm9yZShpICsgMSkpO1xuICAgICAgICAgICAgaWYgKCRwb3Mubm9kZShpKS50eXBlLnNwZWMuaXNvbGF0aW5nKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBhdEJsb2NrRW5kKHN0YXRlLCB2aWV3KSB7XG4gICAgbGV0IHsgJGN1cnNvciB9ID0gc3RhdGUuc2VsZWN0aW9uO1xuICAgIGlmICghJGN1cnNvciB8fCAodmlldyA/ICF2aWV3LmVuZE9mVGV4dGJsb2NrKFwiZm9yd2FyZFwiLCBzdGF0ZSlcbiAgICAgICAgOiAkY3Vyc29yLnBhcmVudE9mZnNldCA8ICRjdXJzb3IucGFyZW50LmNvbnRlbnQuc2l6ZSkpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIHJldHVybiAkY3Vyc29yO1xufVxuLyoqXG5JZiB0aGUgc2VsZWN0aW9uIGlzIGVtcHR5IGFuZCB0aGUgY3Vyc29yIGlzIGF0IHRoZSBlbmQgb2YgYVxudGV4dGJsb2NrLCB0cnkgdG8gcmVkdWNlIG9yIHJlbW92ZSB0aGUgYm91bmRhcnkgYmV0d2VlbiB0aGF0IGJsb2NrXG5hbmQgdGhlIG9uZSBhZnRlciBpdCwgZWl0aGVyIGJ5IGpvaW5pbmcgdGhlbSBvciBieSBtb3ZpbmcgdGhlIG90aGVyXG5ibG9jayBjbG9zZXIgdG8gdGhpcyBvbmUgaW4gdGhlIHRyZWUgc3RydWN0dXJlLiBXaWxsIHVzZSB0aGUgdmlld1xuZm9yIGFjY3VyYXRlIHN0YXJ0LW9mLXRleHRibG9jayBkZXRlY3Rpb24gaWYgZ2l2ZW4uXG4qL1xuY29uc3Qgam9pbkZvcndhcmQgPSAoc3RhdGUsIGRpc3BhdGNoLCB2aWV3KSA9PiB7XG4gICAgbGV0ICRjdXJzb3IgPSBhdEJsb2NrRW5kKHN0YXRlLCB2aWV3KTtcbiAgICBpZiAoISRjdXJzb3IpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgJGN1dCA9IGZpbmRDdXRBZnRlcigkY3Vyc29yKTtcbiAgICAvLyBJZiB0aGVyZSBpcyBubyBub2RlIGFmdGVyIHRoaXMsIHRoZXJlJ3Mgbm90aGluZyB0byBkb1xuICAgIGlmICghJGN1dClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCBhZnRlciA9ICRjdXQubm9kZUFmdGVyO1xuICAgIC8vIFRyeSB0aGUgam9pbmluZyBhbGdvcml0aG1cbiAgICBpZiAoZGVsZXRlQmFycmllcihzdGF0ZSwgJGN1dCwgZGlzcGF0Y2gsIDEpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAvLyBJZiB0aGUgbm9kZSBhYm92ZSBoYXMgbm8gY29udGVudCBhbmQgdGhlIG5vZGUgYmVsb3cgaXNcbiAgICAvLyBzZWxlY3RhYmxlLCBkZWxldGUgdGhlIG5vZGUgYWJvdmUgYW5kIHNlbGVjdCB0aGUgb25lIGJlbG93LlxuICAgIGlmICgkY3Vyc29yLnBhcmVudC5jb250ZW50LnNpemUgPT0gMCAmJlxuICAgICAgICAodGV4dGJsb2NrQXQoYWZ0ZXIsIFwic3RhcnRcIikgfHwgTm9kZVNlbGVjdGlvbi5pc1NlbGVjdGFibGUoYWZ0ZXIpKSkge1xuICAgICAgICBsZXQgZGVsU3RlcCA9IHJlcGxhY2VTdGVwKHN0YXRlLmRvYywgJGN1cnNvci5iZWZvcmUoKSwgJGN1cnNvci5hZnRlcigpLCBTbGljZS5lbXB0eSk7XG4gICAgICAgIGlmIChkZWxTdGVwICYmIGRlbFN0ZXAuc2xpY2Uuc2l6ZSA8IGRlbFN0ZXAudG8gLSBkZWxTdGVwLmZyb20pIHtcbiAgICAgICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgICAgICAgIGxldCB0ciA9IHN0YXRlLnRyLnN0ZXAoZGVsU3RlcCk7XG4gICAgICAgICAgICAgICAgdHIuc2V0U2VsZWN0aW9uKHRleHRibG9ja0F0KGFmdGVyLCBcInN0YXJ0XCIpID8gU2VsZWN0aW9uLmZpbmRGcm9tKHRyLmRvYy5yZXNvbHZlKHRyLm1hcHBpbmcubWFwKCRjdXQucG9zKSksIDEpXG4gICAgICAgICAgICAgICAgICAgIDogTm9kZVNlbGVjdGlvbi5jcmVhdGUodHIuZG9jLCB0ci5tYXBwaW5nLm1hcCgkY3V0LnBvcykpKTtcbiAgICAgICAgICAgICAgICBkaXNwYXRjaCh0ci5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIElmIHRoZSBuZXh0IG5vZGUgaXMgYW4gYXRvbSwgZGVsZXRlIGl0XG4gICAgaWYgKGFmdGVyLmlzQXRvbSAmJiAkY3V0LmRlcHRoID09ICRjdXJzb3IuZGVwdGggLSAxKSB7XG4gICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLmRlbGV0ZSgkY3V0LnBvcywgJGN1dC5wb3MgKyBhZnRlci5ub2RlU2l6ZSkuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59O1xuLyoqXG5XaGVuIHRoZSBzZWxlY3Rpb24gaXMgZW1wdHkgYW5kIGF0IHRoZSBlbmQgb2YgYSB0ZXh0YmxvY2ssIHNlbGVjdFxudGhlIG5vZGUgY29taW5nIGFmdGVyIHRoYXQgdGV4dGJsb2NrLCBpZiBwb3NzaWJsZS4gVGhpcyBpcyBpbnRlbmRlZFxudG8gYmUgYm91bmQgdG8ga2V5cyBsaWtlIGRlbGV0ZSwgYWZ0ZXJcbltgam9pbkZvcndhcmRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jY29tbWFuZHMuam9pbkZvcndhcmQpIGFuZCBzaW1pbGFyIGRlbGV0aW5nXG5jb21tYW5kcywgdG8gcHJvdmlkZSBhIGZhbGwtYmFjayBiZWhhdmlvciB3aGVuIHRoZSBzY2hlbWEgZG9lc24ndFxuYWxsb3cgZGVsZXRpb24gYXQgdGhlIHNlbGVjdGVkIHBvaW50LlxuKi9cbmNvbnN0IHNlbGVjdE5vZGVGb3J3YXJkID0gKHN0YXRlLCBkaXNwYXRjaCwgdmlldykgPT4ge1xuICAgIGxldCB7ICRoZWFkLCBlbXB0eSB9ID0gc3RhdGUuc2VsZWN0aW9uLCAkY3V0ID0gJGhlYWQ7XG4gICAgaWYgKCFlbXB0eSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmICgkaGVhZC5wYXJlbnQuaXNUZXh0YmxvY2spIHtcbiAgICAgICAgaWYgKHZpZXcgPyAhdmlldy5lbmRPZlRleHRibG9jayhcImZvcndhcmRcIiwgc3RhdGUpIDogJGhlYWQucGFyZW50T2Zmc2V0IDwgJGhlYWQucGFyZW50LmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgJGN1dCA9IGZpbmRDdXRBZnRlcigkaGVhZCk7XG4gICAgfVxuICAgIGxldCBub2RlID0gJGN1dCAmJiAkY3V0Lm5vZGVBZnRlcjtcbiAgICBpZiAoIW5vZGUgfHwgIU5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKG5vZGUpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5zZXRTZWxlY3Rpb24oTm9kZVNlbGVjdGlvbi5jcmVhdGUoc3RhdGUuZG9jLCAkY3V0LnBvcykpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgIHJldHVybiB0cnVlO1xufTtcbmZ1bmN0aW9uIGZpbmRDdXRBZnRlcigkcG9zKSB7XG4gICAgaWYgKCEkcG9zLnBhcmVudC50eXBlLnNwZWMuaXNvbGF0aW5nKVxuICAgICAgICBmb3IgKGxldCBpID0gJHBvcy5kZXB0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgcGFyZW50ID0gJHBvcy5ub2RlKGkpO1xuICAgICAgICAgICAgaWYgKCRwb3MuaW5kZXgoaSkgKyAxIDwgcGFyZW50LmNoaWxkQ291bnQpXG4gICAgICAgICAgICAgICAgcmV0dXJuICRwb3MuZG9jLnJlc29sdmUoJHBvcy5hZnRlcihpICsgMSkpO1xuICAgICAgICAgICAgaWYgKHBhcmVudC50eXBlLnNwZWMuaXNvbGF0aW5nKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG4vKipcbkpvaW4gdGhlIHNlbGVjdGVkIGJsb2NrIG9yLCBpZiB0aGVyZSBpcyBhIHRleHQgc2VsZWN0aW9uLCB0aGVcbmNsb3Nlc3QgYW5jZXN0b3IgYmxvY2sgb2YgdGhlIHNlbGVjdGlvbiB0aGF0IGNhbiBiZSBqb2luZWQsIHdpdGhcbnRoZSBzaWJsaW5nIGFib3ZlIGl0LlxuKi9cbmNvbnN0IGpvaW5VcCA9IChzdGF0ZSwgZGlzcGF0Y2gpID0+IHtcbiAgICBsZXQgc2VsID0gc3RhdGUuc2VsZWN0aW9uLCBub2RlU2VsID0gc2VsIGluc3RhbmNlb2YgTm9kZVNlbGVjdGlvbiwgcG9pbnQ7XG4gICAgaWYgKG5vZGVTZWwpIHtcbiAgICAgICAgaWYgKHNlbC5ub2RlLmlzVGV4dGJsb2NrIHx8ICFjYW5Kb2luKHN0YXRlLmRvYywgc2VsLmZyb20pKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBwb2ludCA9IHNlbC5mcm9tO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcG9pbnQgPSBqb2luUG9pbnQoc3RhdGUuZG9jLCBzZWwuZnJvbSwgLTEpO1xuICAgICAgICBpZiAocG9pbnQgPT0gbnVsbClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgIGxldCB0ciA9IHN0YXRlLnRyLmpvaW4ocG9pbnQpO1xuICAgICAgICBpZiAobm9kZVNlbClcbiAgICAgICAgICAgIHRyLnNldFNlbGVjdGlvbihOb2RlU2VsZWN0aW9uLmNyZWF0ZSh0ci5kb2MsIHBvaW50IC0gc3RhdGUuZG9jLnJlc29sdmUocG9pbnQpLm5vZGVCZWZvcmUubm9kZVNpemUpKTtcbiAgICAgICAgZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcbi8qKlxuSm9pbiB0aGUgc2VsZWN0ZWQgYmxvY2ssIG9yIHRoZSBjbG9zZXN0IGFuY2VzdG9yIG9mIHRoZSBzZWxlY3Rpb25cbnRoYXQgY2FuIGJlIGpvaW5lZCwgd2l0aCB0aGUgc2libGluZyBhZnRlciBpdC5cbiovXG5jb25zdCBqb2luRG93biA9IChzdGF0ZSwgZGlzcGF0Y2gpID0+IHtcbiAgICBsZXQgc2VsID0gc3RhdGUuc2VsZWN0aW9uLCBwb2ludDtcbiAgICBpZiAoc2VsIGluc3RhbmNlb2YgTm9kZVNlbGVjdGlvbikge1xuICAgICAgICBpZiAoc2VsLm5vZGUuaXNUZXh0YmxvY2sgfHwgIWNhbkpvaW4oc3RhdGUuZG9jLCBzZWwudG8pKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBwb2ludCA9IHNlbC50bztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHBvaW50ID0gam9pblBvaW50KHN0YXRlLmRvYywgc2VsLnRvLCAxKTtcbiAgICAgICAgaWYgKHBvaW50ID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuam9pbihwb2ludCkuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLyoqXG5MaWZ0IHRoZSBzZWxlY3RlZCBibG9jaywgb3IgdGhlIGNsb3Nlc3QgYW5jZXN0b3IgYmxvY2sgb2YgdGhlXG5zZWxlY3Rpb24gdGhhdCBjYW4gYmUgbGlmdGVkLCBvdXQgb2YgaXRzIHBhcmVudCBub2RlLlxuKi9cbmNvbnN0IGxpZnQgPSAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgbGV0IHsgJGZyb20sICR0byB9ID0gc3RhdGUuc2VsZWN0aW9uO1xuICAgIGxldCByYW5nZSA9ICRmcm9tLmJsb2NrUmFuZ2UoJHRvKSwgdGFyZ2V0ID0gcmFuZ2UgJiYgbGlmdFRhcmdldChyYW5nZSk7XG4gICAgaWYgKHRhcmdldCA9PSBudWxsKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5saWZ0KHJhbmdlLCB0YXJnZXQpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgIHJldHVybiB0cnVlO1xufTtcbi8qKlxuSWYgdGhlIHNlbGVjdGlvbiBpcyBpbiBhIG5vZGUgd2hvc2UgdHlwZSBoYXMgYSB0cnV0aHlcbltgY29kZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5jb2RlKSBwcm9wZXJ0eSBpbiBpdHMgc3BlYywgcmVwbGFjZSB0aGVcbnNlbGVjdGlvbiB3aXRoIGEgbmV3bGluZSBjaGFyYWN0ZXIuXG4qL1xuY29uc3QgbmV3bGluZUluQ29kZSA9IChzdGF0ZSwgZGlzcGF0Y2gpID0+IHtcbiAgICBsZXQgeyAkaGVhZCwgJGFuY2hvciB9ID0gc3RhdGUuc2VsZWN0aW9uO1xuICAgIGlmICghJGhlYWQucGFyZW50LnR5cGUuc3BlYy5jb2RlIHx8ICEkaGVhZC5zYW1lUGFyZW50KCRhbmNob3IpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5pbnNlcnRUZXh0KFwiXFxuXCIpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgIHJldHVybiB0cnVlO1xufTtcbmZ1bmN0aW9uIGRlZmF1bHRCbG9ja0F0KG1hdGNoKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXRjaC5lZGdlQ291bnQ7IGkrKykge1xuICAgICAgICBsZXQgeyB0eXBlIH0gPSBtYXRjaC5lZGdlKGkpO1xuICAgICAgICBpZiAodHlwZS5pc1RleHRibG9jayAmJiAhdHlwZS5oYXNSZXF1aXJlZEF0dHJzKCkpXG4gICAgICAgICAgICByZXR1cm4gdHlwZTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG4vKipcbldoZW4gdGhlIHNlbGVjdGlvbiBpcyBpbiBhIG5vZGUgd2l0aCBhIHRydXRoeVxuW2Bjb2RlYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmNvZGUpIHByb3BlcnR5IGluIGl0cyBzcGVjLCBjcmVhdGUgYVxuZGVmYXVsdCBibG9jayBhZnRlciB0aGUgY29kZSBibG9jaywgYW5kIG1vdmUgdGhlIGN1cnNvciB0aGVyZS5cbiovXG5jb25zdCBleGl0Q29kZSA9IChzdGF0ZSwgZGlzcGF0Y2gpID0+IHtcbiAgICBsZXQgeyAkaGVhZCwgJGFuY2hvciB9ID0gc3RhdGUuc2VsZWN0aW9uO1xuICAgIGlmICghJGhlYWQucGFyZW50LnR5cGUuc3BlYy5jb2RlIHx8ICEkaGVhZC5zYW1lUGFyZW50KCRhbmNob3IpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IGFib3ZlID0gJGhlYWQubm9kZSgtMSksIGFmdGVyID0gJGhlYWQuaW5kZXhBZnRlcigtMSksIHR5cGUgPSBkZWZhdWx0QmxvY2tBdChhYm92ZS5jb250ZW50TWF0Y2hBdChhZnRlcikpO1xuICAgIGlmICghdHlwZSB8fCAhYWJvdmUuY2FuUmVwbGFjZVdpdGgoYWZ0ZXIsIGFmdGVyLCB0eXBlKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICBsZXQgcG9zID0gJGhlYWQuYWZ0ZXIoKSwgdHIgPSBzdGF0ZS50ci5yZXBsYWNlV2l0aChwb3MsIHBvcywgdHlwZS5jcmVhdGVBbmRGaWxsKCkpO1xuICAgICAgICB0ci5zZXRTZWxlY3Rpb24oU2VsZWN0aW9uLm5lYXIodHIuZG9jLnJlc29sdmUocG9zKSwgMSkpO1xuICAgICAgICBkaXNwYXRjaCh0ci5zY3JvbGxJbnRvVmlldygpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLyoqXG5JZiBhIGJsb2NrIG5vZGUgaXMgc2VsZWN0ZWQsIGNyZWF0ZSBhbiBlbXB0eSBwYXJhZ3JhcGggYmVmb3JlIChpZlxuaXQgaXMgaXRzIHBhcmVudCdzIGZpcnN0IGNoaWxkKSBvciBhZnRlciBpdC5cbiovXG5jb25zdCBjcmVhdGVQYXJhZ3JhcGhOZWFyID0gKHN0YXRlLCBkaXNwYXRjaCkgPT4ge1xuICAgIGxldCBzZWwgPSBzdGF0ZS5zZWxlY3Rpb24sIHsgJGZyb20sICR0byB9ID0gc2VsO1xuICAgIGlmIChzZWwgaW5zdGFuY2VvZiBBbGxTZWxlY3Rpb24gfHwgJGZyb20ucGFyZW50LmlubGluZUNvbnRlbnQgfHwgJHRvLnBhcmVudC5pbmxpbmVDb250ZW50KVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IHR5cGUgPSBkZWZhdWx0QmxvY2tBdCgkdG8ucGFyZW50LmNvbnRlbnRNYXRjaEF0KCR0by5pbmRleEFmdGVyKCkpKTtcbiAgICBpZiAoIXR5cGUgfHwgIXR5cGUuaXNUZXh0YmxvY2spXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgbGV0IHNpZGUgPSAoISRmcm9tLnBhcmVudE9mZnNldCAmJiAkdG8uaW5kZXgoKSA8ICR0by5wYXJlbnQuY2hpbGRDb3VudCA/ICRmcm9tIDogJHRvKS5wb3M7XG4gICAgICAgIGxldCB0ciA9IHN0YXRlLnRyLmluc2VydChzaWRlLCB0eXBlLmNyZWF0ZUFuZEZpbGwoKSk7XG4gICAgICAgIHRyLnNldFNlbGVjdGlvbihUZXh0U2VsZWN0aW9uLmNyZWF0ZSh0ci5kb2MsIHNpZGUgKyAxKSk7XG4gICAgICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vKipcbklmIHRoZSBjdXJzb3IgaXMgaW4gYW4gZW1wdHkgdGV4dGJsb2NrIHRoYXQgY2FuIGJlIGxpZnRlZCwgbGlmdCB0aGVcbmJsb2NrLlxuKi9cbmNvbnN0IGxpZnRFbXB0eUJsb2NrID0gKHN0YXRlLCBkaXNwYXRjaCkgPT4ge1xuICAgIGxldCB7ICRjdXJzb3IgfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICBpZiAoISRjdXJzb3IgfHwgJGN1cnNvci5wYXJlbnQuY29udGVudC5zaXplKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCRjdXJzb3IuZGVwdGggPiAxICYmICRjdXJzb3IuYWZ0ZXIoKSAhPSAkY3Vyc29yLmVuZCgtMSkpIHtcbiAgICAgICAgbGV0IGJlZm9yZSA9ICRjdXJzb3IuYmVmb3JlKCk7XG4gICAgICAgIGlmIChjYW5TcGxpdChzdGF0ZS5kb2MsIGJlZm9yZSkpIHtcbiAgICAgICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5zcGxpdChiZWZvcmUpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGV0IHJhbmdlID0gJGN1cnNvci5ibG9ja1JhbmdlKCksIHRhcmdldCA9IHJhbmdlICYmIGxpZnRUYXJnZXQocmFuZ2UpO1xuICAgIGlmICh0YXJnZXQgPT0gbnVsbClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIubGlmdChyYW5nZSwgdGFyZ2V0KS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vKipcbkNyZWF0ZSBhIHZhcmlhbnQgb2YgW2BzcGxpdEJsb2NrYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI2NvbW1hbmRzLnNwbGl0QmxvY2spIHRoYXQgdXNlc1xuYSBjdXN0b20gZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIHRoZSB0eXBlIG9mIHRoZSBuZXdseSBzcGxpdCBvZmYgYmxvY2suXG4qL1xuZnVuY3Rpb24gc3BsaXRCbG9ja0FzKHNwbGl0Tm9kZSkge1xuICAgIHJldHVybiAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgICAgIGxldCB7ICRmcm9tLCAkdG8gfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgaWYgKHN0YXRlLnNlbGVjdGlvbiBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24gJiYgc3RhdGUuc2VsZWN0aW9uLm5vZGUuaXNCbG9jaykge1xuICAgICAgICAgICAgaWYgKCEkZnJvbS5wYXJlbnRPZmZzZXQgfHwgIWNhblNwbGl0KHN0YXRlLmRvYywgJGZyb20ucG9zKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgICAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuc3BsaXQoJGZyb20ucG9zKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghJGZyb20uZGVwdGgpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGxldCB0eXBlcyA9IFtdO1xuICAgICAgICBsZXQgc3BsaXREZXB0aCwgZGVmbHQsIGF0RW5kID0gZmFsc2UsIGF0U3RhcnQgPSBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgZCA9ICRmcm9tLmRlcHRoOzsgZC0tKSB7XG4gICAgICAgICAgICBsZXQgbm9kZSA9ICRmcm9tLm5vZGUoZCk7XG4gICAgICAgICAgICBpZiAobm9kZS5pc0Jsb2NrKSB7XG4gICAgICAgICAgICAgICAgYXRFbmQgPSAkZnJvbS5lbmQoZCkgPT0gJGZyb20ucG9zICsgKCRmcm9tLmRlcHRoIC0gZCk7XG4gICAgICAgICAgICAgICAgYXRTdGFydCA9ICRmcm9tLnN0YXJ0KGQpID09ICRmcm9tLnBvcyAtICgkZnJvbS5kZXB0aCAtIGQpO1xuICAgICAgICAgICAgICAgIGRlZmx0ID0gZGVmYXVsdEJsb2NrQXQoJGZyb20ubm9kZShkIC0gMSkuY29udGVudE1hdGNoQXQoJGZyb20uaW5kZXhBZnRlcihkIC0gMSkpKTtcbiAgICAgICAgICAgICAgICBsZXQgc3BsaXRUeXBlID0gc3BsaXROb2RlICYmIHNwbGl0Tm9kZSgkdG8ucGFyZW50LCBhdEVuZCwgJGZyb20pO1xuICAgICAgICAgICAgICAgIHR5cGVzLnVuc2hpZnQoc3BsaXRUeXBlIHx8IChhdEVuZCAmJiBkZWZsdCA/IHsgdHlwZTogZGVmbHQgfSA6IG51bGwpKTtcbiAgICAgICAgICAgICAgICBzcGxpdERlcHRoID0gZDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChkID09IDEpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB0eXBlcy51bnNoaWZ0KG51bGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCB0ciA9IHN0YXRlLnRyO1xuICAgICAgICBpZiAoc3RhdGUuc2VsZWN0aW9uIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvbiB8fCBzdGF0ZS5zZWxlY3Rpb24gaW5zdGFuY2VvZiBBbGxTZWxlY3Rpb24pXG4gICAgICAgICAgICB0ci5kZWxldGVTZWxlY3Rpb24oKTtcbiAgICAgICAgbGV0IHNwbGl0UG9zID0gdHIubWFwcGluZy5tYXAoJGZyb20ucG9zKTtcbiAgICAgICAgbGV0IGNhbiA9IGNhblNwbGl0KHRyLmRvYywgc3BsaXRQb3MsIHR5cGVzLmxlbmd0aCwgdHlwZXMpO1xuICAgICAgICBpZiAoIWNhbikge1xuICAgICAgICAgICAgdHlwZXNbMF0gPSBkZWZsdCA/IHsgdHlwZTogZGVmbHQgfSA6IG51bGw7XG4gICAgICAgICAgICBjYW4gPSBjYW5TcGxpdCh0ci5kb2MsIHNwbGl0UG9zLCB0eXBlcy5sZW5ndGgsIHR5cGVzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNhbilcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgdHIuc3BsaXQoc3BsaXRQb3MsIHR5cGVzLmxlbmd0aCwgdHlwZXMpO1xuICAgICAgICBpZiAoIWF0RW5kICYmIGF0U3RhcnQgJiYgJGZyb20ubm9kZShzcGxpdERlcHRoKS50eXBlICE9IGRlZmx0KSB7XG4gICAgICAgICAgICBsZXQgZmlyc3QgPSB0ci5tYXBwaW5nLm1hcCgkZnJvbS5iZWZvcmUoc3BsaXREZXB0aCkpLCAkZmlyc3QgPSB0ci5kb2MucmVzb2x2ZShmaXJzdCk7XG4gICAgICAgICAgICBpZiAoZGVmbHQgJiYgJGZyb20ubm9kZShzcGxpdERlcHRoIC0gMSkuY2FuUmVwbGFjZVdpdGgoJGZpcnN0LmluZGV4KCksICRmaXJzdC5pbmRleCgpICsgMSwgZGVmbHQpKVxuICAgICAgICAgICAgICAgIHRyLnNldE5vZGVNYXJrdXAodHIubWFwcGluZy5tYXAoJGZyb20uYmVmb3JlKHNwbGl0RGVwdGgpKSwgZGVmbHQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xufVxuLyoqXG5TcGxpdCB0aGUgcGFyZW50IGJsb2NrIG9mIHRoZSBzZWxlY3Rpb24uIElmIHRoZSBzZWxlY3Rpb24gaXMgYSB0ZXh0XG5zZWxlY3Rpb24sIGFsc28gZGVsZXRlIGl0cyBjb250ZW50LlxuKi9cbmNvbnN0IHNwbGl0QmxvY2sgPSBzcGxpdEJsb2NrQXMoKTtcbi8qKlxuQWN0cyBsaWtlIFtgc3BsaXRCbG9ja2BdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNjb21tYW5kcy5zcGxpdEJsb2NrKSwgYnV0IHdpdGhvdXRcbnJlc2V0dGluZyB0aGUgc2V0IG9mIGFjdGl2ZSBtYXJrcyBhdCB0aGUgY3Vyc29yLlxuKi9cbmNvbnN0IHNwbGl0QmxvY2tLZWVwTWFya3MgPSAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgcmV0dXJuIHNwbGl0QmxvY2soc3RhdGUsIGRpc3BhdGNoICYmICh0ciA9PiB7XG4gICAgICAgIGxldCBtYXJrcyA9IHN0YXRlLnN0b3JlZE1hcmtzIHx8IChzdGF0ZS5zZWxlY3Rpb24uJHRvLnBhcmVudE9mZnNldCAmJiBzdGF0ZS5zZWxlY3Rpb24uJGZyb20ubWFya3MoKSk7XG4gICAgICAgIGlmIChtYXJrcylcbiAgICAgICAgICAgIHRyLmVuc3VyZU1hcmtzKG1hcmtzKTtcbiAgICAgICAgZGlzcGF0Y2godHIpO1xuICAgIH0pKTtcbn07XG4vKipcbk1vdmUgdGhlIHNlbGVjdGlvbiB0byB0aGUgbm9kZSB3cmFwcGluZyB0aGUgY3VycmVudCBzZWxlY3Rpb24sIGlmXG5hbnkuIChXaWxsIG5vdCBzZWxlY3QgdGhlIGRvY3VtZW50IG5vZGUuKVxuKi9cbmNvbnN0IHNlbGVjdFBhcmVudE5vZGUgPSAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgbGV0IHsgJGZyb20sIHRvIH0gPSBzdGF0ZS5zZWxlY3Rpb24sIHBvcztcbiAgICBsZXQgc2FtZSA9ICRmcm9tLnNoYXJlZERlcHRoKHRvKTtcbiAgICBpZiAoc2FtZSA9PSAwKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgcG9zID0gJGZyb20uYmVmb3JlKHNhbWUpO1xuICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuc2V0U2VsZWN0aW9uKE5vZGVTZWxlY3Rpb24uY3JlYXRlKHN0YXRlLmRvYywgcG9zKSkpO1xuICAgIHJldHVybiB0cnVlO1xufTtcbi8qKlxuU2VsZWN0IHRoZSB3aG9sZSBkb2N1bWVudC5cbiovXG5jb25zdCBzZWxlY3RBbGwgPSAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5zZXRTZWxlY3Rpb24obmV3IEFsbFNlbGVjdGlvbihzdGF0ZS5kb2MpKSk7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuZnVuY3Rpb24gam9pbk1heWJlQ2xlYXIoc3RhdGUsICRwb3MsIGRpc3BhdGNoKSB7XG4gICAgbGV0IGJlZm9yZSA9ICRwb3Mubm9kZUJlZm9yZSwgYWZ0ZXIgPSAkcG9zLm5vZGVBZnRlciwgaW5kZXggPSAkcG9zLmluZGV4KCk7XG4gICAgaWYgKCFiZWZvcmUgfHwgIWFmdGVyIHx8ICFiZWZvcmUudHlwZS5jb21wYXRpYmxlQ29udGVudChhZnRlci50eXBlKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghYmVmb3JlLmNvbnRlbnQuc2l6ZSAmJiAkcG9zLnBhcmVudC5jYW5SZXBsYWNlKGluZGV4IC0gMSwgaW5kZXgpKSB7XG4gICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLmRlbGV0ZSgkcG9zLnBvcyAtIGJlZm9yZS5ub2RlU2l6ZSwgJHBvcy5wb3MpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKCEkcG9zLnBhcmVudC5jYW5SZXBsYWNlKGluZGV4LCBpbmRleCArIDEpIHx8ICEoYWZ0ZXIuaXNUZXh0YmxvY2sgfHwgY2FuSm9pbihzdGF0ZS5kb2MsICRwb3MucG9zKSkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLmpvaW4oJHBvcy5wb3MpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gZGVsZXRlQmFycmllcihzdGF0ZSwgJGN1dCwgZGlzcGF0Y2gsIGRpcikge1xuICAgIGxldCBiZWZvcmUgPSAkY3V0Lm5vZGVCZWZvcmUsIGFmdGVyID0gJGN1dC5ub2RlQWZ0ZXIsIGNvbm4sIG1hdGNoO1xuICAgIGxldCBpc29sYXRlZCA9IGJlZm9yZS50eXBlLnNwZWMuaXNvbGF0aW5nIHx8IGFmdGVyLnR5cGUuc3BlYy5pc29sYXRpbmc7XG4gICAgaWYgKCFpc29sYXRlZCAmJiBqb2luTWF5YmVDbGVhcihzdGF0ZSwgJGN1dCwgZGlzcGF0Y2gpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICBsZXQgY2FuRGVsQWZ0ZXIgPSAhaXNvbGF0ZWQgJiYgJGN1dC5wYXJlbnQuY2FuUmVwbGFjZSgkY3V0LmluZGV4KCksICRjdXQuaW5kZXgoKSArIDEpO1xuICAgIGlmIChjYW5EZWxBZnRlciAmJlxuICAgICAgICAoY29ubiA9IChtYXRjaCA9IGJlZm9yZS5jb250ZW50TWF0Y2hBdChiZWZvcmUuY2hpbGRDb3VudCkpLmZpbmRXcmFwcGluZyhhZnRlci50eXBlKSkgJiZcbiAgICAgICAgbWF0Y2gubWF0Y2hUeXBlKGNvbm5bMF0gfHwgYWZ0ZXIudHlwZSkudmFsaWRFbmQpIHtcbiAgICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgICAgICBsZXQgZW5kID0gJGN1dC5wb3MgKyBhZnRlci5ub2RlU2l6ZSwgd3JhcCA9IEZyYWdtZW50LmVtcHR5O1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IGNvbm4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgICAgICAgICAgd3JhcCA9IEZyYWdtZW50LmZyb20oY29ubltpXS5jcmVhdGUobnVsbCwgd3JhcCkpO1xuICAgICAgICAgICAgd3JhcCA9IEZyYWdtZW50LmZyb20oYmVmb3JlLmNvcHkod3JhcCkpO1xuICAgICAgICAgICAgbGV0IHRyID0gc3RhdGUudHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAoJGN1dC5wb3MgLSAxLCBlbmQsICRjdXQucG9zLCBlbmQsIG5ldyBTbGljZSh3cmFwLCAxLCAwKSwgY29ubi5sZW5ndGgsIHRydWUpKTtcbiAgICAgICAgICAgIGxldCAkam9pbkF0ID0gdHIuZG9jLnJlc29sdmUoZW5kICsgMiAqIGNvbm4ubGVuZ3RoKTtcbiAgICAgICAgICAgIGlmICgkam9pbkF0Lm5vZGVBZnRlciAmJiAkam9pbkF0Lm5vZGVBZnRlci50eXBlID09IGJlZm9yZS50eXBlICYmXG4gICAgICAgICAgICAgICAgY2FuSm9pbih0ci5kb2MsICRqb2luQXQucG9zKSlcbiAgICAgICAgICAgICAgICB0ci5qb2luKCRqb2luQXQucG9zKTtcbiAgICAgICAgICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBsZXQgc2VsQWZ0ZXIgPSBhZnRlci50eXBlLnNwZWMuaXNvbGF0aW5nIHx8IChkaXIgPiAwICYmIGlzb2xhdGVkKSA/IG51bGwgOiBTZWxlY3Rpb24uZmluZEZyb20oJGN1dCwgMSk7XG4gICAgbGV0IHJhbmdlID0gc2VsQWZ0ZXIgJiYgc2VsQWZ0ZXIuJGZyb20uYmxvY2tSYW5nZShzZWxBZnRlci4kdG8pLCB0YXJnZXQgPSByYW5nZSAmJiBsaWZ0VGFyZ2V0KHJhbmdlKTtcbiAgICBpZiAodGFyZ2V0ICE9IG51bGwgJiYgdGFyZ2V0ID49ICRjdXQuZGVwdGgpIHtcbiAgICAgICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIubGlmdChyYW5nZSwgdGFyZ2V0KS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChjYW5EZWxBZnRlciAmJiB0ZXh0YmxvY2tBdChhZnRlciwgXCJzdGFydFwiLCB0cnVlKSAmJiB0ZXh0YmxvY2tBdChiZWZvcmUsIFwiZW5kXCIpKSB7XG4gICAgICAgIGxldCBhdCA9IGJlZm9yZSwgd3JhcCA9IFtdO1xuICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgICB3cmFwLnB1c2goYXQpO1xuICAgICAgICAgICAgaWYgKGF0LmlzVGV4dGJsb2NrKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgYXQgPSBhdC5sYXN0Q2hpbGQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGFmdGVyVGV4dCA9IGFmdGVyLCBhZnRlckRlcHRoID0gMTtcbiAgICAgICAgZm9yICg7ICFhZnRlclRleHQuaXNUZXh0YmxvY2s7IGFmdGVyVGV4dCA9IGFmdGVyVGV4dC5maXJzdENoaWxkKVxuICAgICAgICAgICAgYWZ0ZXJEZXB0aCsrO1xuICAgICAgICBpZiAoYXQuY2FuUmVwbGFjZShhdC5jaGlsZENvdW50LCBhdC5jaGlsZENvdW50LCBhZnRlclRleHQuY29udGVudCkpIHtcbiAgICAgICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgICAgICAgIGxldCBlbmQgPSBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gd3JhcC5sZW5ndGggLSAxOyBpID49IDA7IGktLSlcbiAgICAgICAgICAgICAgICAgICAgZW5kID0gRnJhZ21lbnQuZnJvbSh3cmFwW2ldLmNvcHkoZW5kKSk7XG4gICAgICAgICAgICAgICAgbGV0IHRyID0gc3RhdGUudHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAoJGN1dC5wb3MgLSB3cmFwLmxlbmd0aCwgJGN1dC5wb3MgKyBhZnRlci5ub2RlU2l6ZSwgJGN1dC5wb3MgKyBhZnRlckRlcHRoLCAkY3V0LnBvcyArIGFmdGVyLm5vZGVTaXplIC0gYWZ0ZXJEZXB0aCwgbmV3IFNsaWNlKGVuZCwgd3JhcC5sZW5ndGgsIDApLCAwLCB0cnVlKSk7XG4gICAgICAgICAgICAgICAgZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBzZWxlY3RUZXh0YmxvY2tTaWRlKHNpZGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHN0YXRlLCBkaXNwYXRjaCkge1xuICAgICAgICBsZXQgc2VsID0gc3RhdGUuc2VsZWN0aW9uLCAkcG9zID0gc2lkZSA8IDAgPyBzZWwuJGZyb20gOiBzZWwuJHRvO1xuICAgICAgICBsZXQgZGVwdGggPSAkcG9zLmRlcHRoO1xuICAgICAgICB3aGlsZSAoJHBvcy5ub2RlKGRlcHRoKS5pc0lubGluZSkge1xuICAgICAgICAgICAgaWYgKCFkZXB0aClcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBkZXB0aC0tO1xuICAgICAgICB9XG4gICAgICAgIGlmICghJHBvcy5ub2RlKGRlcHRoKS5pc1RleHRibG9jaylcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuc2V0U2VsZWN0aW9uKFRleHRTZWxlY3Rpb24uY3JlYXRlKHN0YXRlLmRvYywgc2lkZSA8IDAgPyAkcG9zLnN0YXJ0KGRlcHRoKSA6ICRwb3MuZW5kKGRlcHRoKSkpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbn1cbi8qKlxuTW92ZXMgdGhlIGN1cnNvciB0byB0aGUgc3RhcnQgb2YgY3VycmVudCB0ZXh0IGJsb2NrLlxuKi9cbmNvbnN0IHNlbGVjdFRleHRibG9ja1N0YXJ0ID0gc2VsZWN0VGV4dGJsb2NrU2lkZSgtMSk7XG4vKipcbk1vdmVzIHRoZSBjdXJzb3IgdG8gdGhlIGVuZCBvZiBjdXJyZW50IHRleHQgYmxvY2suXG4qL1xuY29uc3Qgc2VsZWN0VGV4dGJsb2NrRW5kID0gc2VsZWN0VGV4dGJsb2NrU2lkZSgxKTtcbi8vIFBhcmFtZXRlcml6ZWQgY29tbWFuZHNcbi8qKlxuV3JhcCB0aGUgc2VsZWN0aW9uIGluIGEgbm9kZSBvZiB0aGUgZ2l2ZW4gdHlwZSB3aXRoIHRoZSBnaXZlblxuYXR0cmlidXRlcy5cbiovXG5mdW5jdGlvbiB3cmFwSW4obm9kZVR5cGUsIGF0dHJzID0gbnVsbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoc3RhdGUsIGRpc3BhdGNoKSB7XG4gICAgICAgIGxldCB7ICRmcm9tLCAkdG8gfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgbGV0IHJhbmdlID0gJGZyb20uYmxvY2tSYW5nZSgkdG8pLCB3cmFwcGluZyA9IHJhbmdlICYmIGZpbmRXcmFwcGluZyhyYW5nZSwgbm9kZVR5cGUsIGF0dHJzKTtcbiAgICAgICAgaWYgKCF3cmFwcGluZylcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIud3JhcChyYW5nZSwgd3JhcHBpbmcpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xufVxuLyoqXG5SZXR1cm5zIGEgY29tbWFuZCB0aGF0IHRyaWVzIHRvIHNldCB0aGUgc2VsZWN0ZWQgdGV4dGJsb2NrcyB0byB0aGVcbmdpdmVuIG5vZGUgdHlwZSB3aXRoIHRoZSBnaXZlbiBhdHRyaWJ1dGVzLlxuKi9cbmZ1bmN0aW9uIHNldEJsb2NrVHlwZShub2RlVHlwZSwgYXR0cnMgPSBudWxsKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzdGF0ZSwgZGlzcGF0Y2gpIHtcbiAgICAgICAgbGV0IGFwcGxpY2FibGUgPSBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdGF0ZS5zZWxlY3Rpb24ucmFuZ2VzLmxlbmd0aCAmJiAhYXBwbGljYWJsZTsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgeyAkZnJvbTogeyBwb3M6IGZyb20gfSwgJHRvOiB7IHBvczogdG8gfSB9ID0gc3RhdGUuc2VsZWN0aW9uLnJhbmdlc1tpXTtcbiAgICAgICAgICAgIHN0YXRlLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoYXBwbGljYWJsZSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIGlmICghbm9kZS5pc1RleHRibG9jayB8fCBub2RlLmhhc01hcmt1cChub2RlVHlwZSwgYXR0cnMpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUudHlwZSA9PSBub2RlVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBhcHBsaWNhYmxlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCAkcG9zID0gc3RhdGUuZG9jLnJlc29sdmUocG9zKSwgaW5kZXggPSAkcG9zLmluZGV4KCk7XG4gICAgICAgICAgICAgICAgICAgIGFwcGxpY2FibGUgPSAkcG9zLnBhcmVudC5jYW5SZXBsYWNlV2l0aChpbmRleCwgaW5kZXggKyAxLCBub2RlVHlwZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFhcHBsaWNhYmxlKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgICAgIGxldCB0ciA9IHN0YXRlLnRyO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdGF0ZS5zZWxlY3Rpb24ucmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHsgJGZyb206IHsgcG9zOiBmcm9tIH0sICR0bzogeyBwb3M6IHRvIH0gfSA9IHN0YXRlLnNlbGVjdGlvbi5yYW5nZXNbaV07XG4gICAgICAgICAgICAgICAgdHIuc2V0QmxvY2tUeXBlKGZyb20sIHRvLCBub2RlVHlwZSwgYXR0cnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbn1cbmZ1bmN0aW9uIG1hcmtBcHBsaWVzKGRvYywgcmFuZ2VzLCB0eXBlLCBlbnRlckF0b21zKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IHsgJGZyb20sICR0byB9ID0gcmFuZ2VzW2ldO1xuICAgICAgICBsZXQgY2FuID0gJGZyb20uZGVwdGggPT0gMCA/IGRvYy5pbmxpbmVDb250ZW50ICYmIGRvYy50eXBlLmFsbG93c01hcmtUeXBlKHR5cGUpIDogZmFsc2U7XG4gICAgICAgIGRvYy5ub2Rlc0JldHdlZW4oJGZyb20ucG9zLCAkdG8ucG9zLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgICAgICBpZiAoY2FuIHx8ICFlbnRlckF0b21zICYmIG5vZGUuaXNBdG9tICYmIG5vZGUuaXNJbmxpbmUgJiYgcG9zID49ICRmcm9tLnBvcyAmJiBwb3MgKyBub2RlLm5vZGVTaXplIDw9ICR0by5wb3MpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgY2FuID0gbm9kZS5pbmxpbmVDb250ZW50ICYmIG5vZGUudHlwZS5hbGxvd3NNYXJrVHlwZSh0eXBlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChjYW4pXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gcmVtb3ZlSW5saW5lQXRvbXMocmFuZ2VzKSB7XG4gICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCB7ICRmcm9tLCAkdG8gfSA9IHJhbmdlc1tpXTtcbiAgICAgICAgJGZyb20uZG9jLm5vZGVzQmV0d2VlbigkZnJvbS5wb3MsICR0by5wb3MsIChub2RlLCBwb3MpID0+IHtcbiAgICAgICAgICAgIGlmIChub2RlLmlzQXRvbSAmJiBub2RlLmNvbnRlbnQuc2l6ZSAmJiBub2RlLmlzSW5saW5lICYmIHBvcyA+PSAkZnJvbS5wb3MgJiYgcG9zICsgbm9kZS5ub2RlU2l6ZSA8PSAkdG8ucG9zKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBvcyArIDEgPiAkZnJvbS5wb3MpXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKG5ldyBTZWxlY3Rpb25SYW5nZSgkZnJvbSwgJGZyb20uZG9jLnJlc29sdmUocG9zICsgMSkpKTtcbiAgICAgICAgICAgICAgICAkZnJvbSA9ICRmcm9tLmRvYy5yZXNvbHZlKHBvcyArIDEgKyBub2RlLmNvbnRlbnQuc2l6ZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCRmcm9tLnBvcyA8ICR0by5wb3MpXG4gICAgICAgICAgICByZXN1bHQucHVzaChuZXcgU2VsZWN0aW9uUmFuZ2UoJGZyb20sICR0bykpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLyoqXG5DcmVhdGUgYSBjb21tYW5kIGZ1bmN0aW9uIHRoYXQgdG9nZ2xlcyB0aGUgZ2l2ZW4gbWFyayB3aXRoIHRoZVxuZ2l2ZW4gYXR0cmlidXRlcy4gV2lsbCByZXR1cm4gYGZhbHNlYCB3aGVuIHRoZSBjdXJyZW50IHNlbGVjdGlvblxuZG9lc24ndCBzdXBwb3J0IHRoYXQgbWFyay4gVGhpcyB3aWxsIHJlbW92ZSB0aGUgbWFyayBpZiBhbnkgbWFya3Ncbm9mIHRoYXQgdHlwZSBleGlzdCBpbiB0aGUgc2VsZWN0aW9uLCBvciBhZGQgaXQgb3RoZXJ3aXNlLiBJZiB0aGVcbnNlbGVjdGlvbiBpcyBlbXB0eSwgdGhpcyBhcHBsaWVzIHRvIHRoZSBbc3RvcmVkXG5tYXJrc10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLkVkaXRvclN0YXRlLnN0b3JlZE1hcmtzKSBpbnN0ZWFkIG9mIGEgcmFuZ2Ugb2YgdGhlXG5kb2N1bWVudC5cbiovXG5mdW5jdGlvbiB0b2dnbGVNYXJrKG1hcmtUeXBlLCBhdHRycyA9IG51bGwsIG9wdGlvbnMpIHtcbiAgICBsZXQgcmVtb3ZlV2hlblByZXNlbnQgPSAob3B0aW9ucyAmJiBvcHRpb25zLnJlbW92ZVdoZW5QcmVzZW50KSAhPT0gZmFsc2U7XG4gICAgbGV0IGVudGVyQXRvbXMgPSAob3B0aW9ucyAmJiBvcHRpb25zLmVudGVySW5saW5lQXRvbXMpICE9PSBmYWxzZTtcbiAgICBsZXQgZHJvcFNwYWNlID0gIShvcHRpb25zICYmIG9wdGlvbnMuaW5jbHVkZVdoaXRlc3BhY2UpO1xuICAgIHJldHVybiBmdW5jdGlvbiAoc3RhdGUsIGRpc3BhdGNoKSB7XG4gICAgICAgIGxldCB7IGVtcHR5LCAkY3Vyc29yLCByYW5nZXMgfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgaWYgKChlbXB0eSAmJiAhJGN1cnNvcikgfHwgIW1hcmtBcHBsaWVzKHN0YXRlLmRvYywgcmFuZ2VzLCBtYXJrVHlwZSwgZW50ZXJBdG9tcykpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgICAgaWYgKCRjdXJzb3IpIHtcbiAgICAgICAgICAgICAgICBpZiAobWFya1R5cGUuaXNJblNldChzdGF0ZS5zdG9yZWRNYXJrcyB8fCAkY3Vyc29yLm1hcmtzKCkpKVxuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5yZW1vdmVTdG9yZWRNYXJrKG1hcmtUeXBlKSk7XG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5hZGRTdG9yZWRNYXJrKG1hcmtUeXBlLmNyZWF0ZShhdHRycykpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBhZGQsIHRyID0gc3RhdGUudHI7XG4gICAgICAgICAgICAgICAgaWYgKCFlbnRlckF0b21zKVxuICAgICAgICAgICAgICAgICAgICByYW5nZXMgPSByZW1vdmVJbmxpbmVBdG9tcyhyYW5nZXMpO1xuICAgICAgICAgICAgICAgIGlmIChyZW1vdmVXaGVuUHJlc2VudCkge1xuICAgICAgICAgICAgICAgICAgICBhZGQgPSAhcmFuZ2VzLnNvbWUociA9PiBzdGF0ZS5kb2MucmFuZ2VIYXNNYXJrKHIuJGZyb20ucG9zLCByLiR0by5wb3MsIG1hcmtUeXBlKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBhZGQgPSAhcmFuZ2VzLmV2ZXJ5KHIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG1pc3NpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyLmRvYy5ub2Rlc0JldHdlZW4oci4kZnJvbS5wb3MsIHIuJHRvLnBvcywgKG5vZGUsIHBvcywgcGFyZW50KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1pc3NpbmcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaXNzaW5nID0gIW1hcmtUeXBlLmlzSW5TZXQobm9kZS5tYXJrcykgJiYgISFwYXJlbnQgJiYgcGFyZW50LnR5cGUuYWxsb3dzTWFya1R5cGUobWFya1R5cGUpICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICEobm9kZS5pc1RleHQgJiYgL15cXHMqJC8udGVzdChub2RlLnRleHRCZXR3ZWVuKE1hdGgubWF4KDAsIHIuJGZyb20ucG9zIC0gcG9zKSwgTWF0aC5taW4obm9kZS5ub2RlU2l6ZSwgci4kdG8ucG9zIC0gcG9zKSkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICFtaXNzaW5nO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHsgJGZyb20sICR0byB9ID0gcmFuZ2VzW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWFkZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHIucmVtb3ZlTWFyaygkZnJvbS5wb3MsICR0by5wb3MsIG1hcmtUeXBlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBmcm9tID0gJGZyb20ucG9zLCB0byA9ICR0by5wb3MsIHN0YXJ0ID0gJGZyb20ubm9kZUFmdGVyLCBlbmQgPSAkdG8ubm9kZUJlZm9yZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzcGFjZVN0YXJ0ID0gZHJvcFNwYWNlICYmIHN0YXJ0ICYmIHN0YXJ0LmlzVGV4dCA/IC9eXFxzKi8uZXhlYyhzdGFydC50ZXh0KVswXS5sZW5ndGggOiAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHNwYWNlRW5kID0gZHJvcFNwYWNlICYmIGVuZCAmJiBlbmQuaXNUZXh0ID8gL1xccyokLy5leGVjKGVuZC50ZXh0KVswXS5sZW5ndGggOiAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZyb20gKyBzcGFjZVN0YXJ0IDwgdG8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tICs9IHNwYWNlU3RhcnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gLT0gc3BhY2VFbmQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0ci5hZGRNYXJrKGZyb20sIHRvLCBtYXJrVHlwZS5jcmVhdGUoYXR0cnMpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkaXNwYXRjaCh0ci5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xufVxuZnVuY3Rpb24gd3JhcERpc3BhdGNoRm9ySm9pbihkaXNwYXRjaCwgaXNKb2luYWJsZSkge1xuICAgIHJldHVybiAodHIpID0+IHtcbiAgICAgICAgaWYgKCF0ci5pc0dlbmVyaWMpXG4gICAgICAgICAgICByZXR1cm4gZGlzcGF0Y2godHIpO1xuICAgICAgICBsZXQgcmFuZ2VzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdHIubWFwcGluZy5tYXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbWFwID0gdHIubWFwcGluZy5tYXBzW2ldO1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCByYW5nZXMubGVuZ3RoOyBqKyspXG4gICAgICAgICAgICAgICAgcmFuZ2VzW2pdID0gbWFwLm1hcChyYW5nZXNbal0pO1xuICAgICAgICAgICAgbWFwLmZvckVhY2goKF9zLCBfZSwgZnJvbSwgdG8pID0+IHJhbmdlcy5wdXNoKGZyb20sIHRvKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmlndXJlIG91dCB3aGljaCBqb2luYWJsZSBwb2ludHMgZXhpc3QgaW5zaWRlIHRob3NlIHJhbmdlcyxcbiAgICAgICAgLy8gYnkgY2hlY2tpbmcgYWxsIG5vZGUgYm91bmRhcmllcyBpbiB0aGVpciBwYXJlbnQgbm9kZXMuXG4gICAgICAgIGxldCBqb2luYWJsZSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgICAgICAgICAgbGV0IGZyb20gPSByYW5nZXNbaV0sIHRvID0gcmFuZ2VzW2kgKyAxXTtcbiAgICAgICAgICAgIGxldCAkZnJvbSA9IHRyLmRvYy5yZXNvbHZlKGZyb20pLCBkZXB0aCA9ICRmcm9tLnNoYXJlZERlcHRoKHRvKSwgcGFyZW50ID0gJGZyb20ubm9kZShkZXB0aCk7XG4gICAgICAgICAgICBmb3IgKGxldCBpbmRleCA9ICRmcm9tLmluZGV4QWZ0ZXIoZGVwdGgpLCBwb3MgPSAkZnJvbS5hZnRlcihkZXB0aCArIDEpOyBwb3MgPD0gdG87ICsraW5kZXgpIHtcbiAgICAgICAgICAgICAgICBsZXQgYWZ0ZXIgPSBwYXJlbnQubWF5YmVDaGlsZChpbmRleCk7XG4gICAgICAgICAgICAgICAgaWYgKCFhZnRlcilcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ICYmIGpvaW5hYmxlLmluZGV4T2YocG9zKSA9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgYmVmb3JlID0gcGFyZW50LmNoaWxkKGluZGV4IC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChiZWZvcmUudHlwZSA9PSBhZnRlci50eXBlICYmIGlzSm9pbmFibGUoYmVmb3JlLCBhZnRlcikpXG4gICAgICAgICAgICAgICAgICAgICAgICBqb2luYWJsZS5wdXNoKHBvcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBvcyArPSBhZnRlci5ub2RlU2l6ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBKb2luIHRoZSBqb2luYWJsZSBwb2ludHNcbiAgICAgICAgam9pbmFibGUuc29ydCgoYSwgYikgPT4gYSAtIGIpO1xuICAgICAgICBmb3IgKGxldCBpID0gam9pbmFibGUubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGlmIChjYW5Kb2luKHRyLmRvYywgam9pbmFibGVbaV0pKVxuICAgICAgICAgICAgICAgIHRyLmpvaW4oam9pbmFibGVbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGRpc3BhdGNoKHRyKTtcbiAgICB9O1xufVxuLyoqXG5XcmFwIGEgY29tbWFuZCBzbyB0aGF0LCB3aGVuIGl0IHByb2R1Y2VzIGEgdHJhbnNmb3JtIHRoYXQgY2F1c2VzXG50d28gam9pbmFibGUgbm9kZXMgdG8gZW5kIHVwIG5leHQgdG8gZWFjaCBvdGhlciwgdGhvc2UgYXJlIGpvaW5lZC5cbk5vZGVzIGFyZSBjb25zaWRlcmVkIGpvaW5hYmxlIHdoZW4gdGhleSBhcmUgb2YgdGhlIHNhbWUgdHlwZSBhbmRcbndoZW4gdGhlIGBpc0pvaW5hYmxlYCBwcmVkaWNhdGUgcmV0dXJucyB0cnVlIGZvciB0aGVtIG9yLCBpZiBhblxuYXJyYXkgb2Ygc3RyaW5ncyB3YXMgcGFzc2VkLCBpZiB0aGVpciBub2RlIHR5cGUgbmFtZSBpcyBpbiB0aGF0XG5hcnJheS5cbiovXG5mdW5jdGlvbiBhdXRvSm9pbihjb21tYW5kLCBpc0pvaW5hYmxlKSB7XG4gICAgbGV0IGNhbkpvaW4gPSBBcnJheS5pc0FycmF5KGlzSm9pbmFibGUpID8gKG5vZGUpID0+IGlzSm9pbmFibGUuaW5kZXhPZihub2RlLnR5cGUubmFtZSkgPiAtMVxuICAgICAgICA6IGlzSm9pbmFibGU7XG4gICAgcmV0dXJuIChzdGF0ZSwgZGlzcGF0Y2gsIHZpZXcpID0+IGNvbW1hbmQoc3RhdGUsIGRpc3BhdGNoICYmIHdyYXBEaXNwYXRjaEZvckpvaW4oZGlzcGF0Y2gsIGNhbkpvaW4pLCB2aWV3KTtcbn1cbi8qKlxuQ29tYmluZSBhIG51bWJlciBvZiBjb21tYW5kIGZ1bmN0aW9ucyBpbnRvIGEgc2luZ2xlIGZ1bmN0aW9uICh3aGljaFxuY2FsbHMgdGhlbSBvbmUgYnkgb25lIHVudGlsIG9uZSByZXR1cm5zIHRydWUpLlxuKi9cbmZ1bmN0aW9uIGNoYWluQ29tbWFuZHMoLi4uY29tbWFuZHMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHN0YXRlLCBkaXNwYXRjaCwgdmlldykge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbW1hbmRzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKGNvbW1hbmRzW2ldKHN0YXRlLCBkaXNwYXRjaCwgdmlldykpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xufVxubGV0IGJhY2tzcGFjZSA9IGNoYWluQ29tbWFuZHMoZGVsZXRlU2VsZWN0aW9uLCBqb2luQmFja3dhcmQsIHNlbGVjdE5vZGVCYWNrd2FyZCk7XG5sZXQgZGVsID0gY2hhaW5Db21tYW5kcyhkZWxldGVTZWxlY3Rpb24sIGpvaW5Gb3J3YXJkLCBzZWxlY3ROb2RlRm9yd2FyZCk7XG4vKipcbkEgYmFzaWMga2V5bWFwIGNvbnRhaW5pbmcgYmluZGluZ3Mgbm90IHNwZWNpZmljIHRvIGFueSBzY2hlbWEuXG5CaW5kcyB0aGUgZm9sbG93aW5nIGtleXMgKHdoZW4gbXVsdGlwbGUgY29tbWFuZHMgYXJlIGxpc3RlZCwgdGhleVxuYXJlIGNoYWluZWQgd2l0aCBbYGNoYWluQ29tbWFuZHNgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jY29tbWFuZHMuY2hhaW5Db21tYW5kcykpOlxuXG4qICoqRW50ZXIqKiB0byBgbmV3bGluZUluQ29kZWAsIGBjcmVhdGVQYXJhZ3JhcGhOZWFyYCwgYGxpZnRFbXB0eUJsb2NrYCwgYHNwbGl0QmxvY2tgXG4qICoqTW9kLUVudGVyKiogdG8gYGV4aXRDb2RlYFxuKiAqKkJhY2tzcGFjZSoqIGFuZCAqKk1vZC1CYWNrc3BhY2UqKiB0byBgZGVsZXRlU2VsZWN0aW9uYCwgYGpvaW5CYWNrd2FyZGAsIGBzZWxlY3ROb2RlQmFja3dhcmRgXG4qICoqRGVsZXRlKiogYW5kICoqTW9kLURlbGV0ZSoqIHRvIGBkZWxldGVTZWxlY3Rpb25gLCBgam9pbkZvcndhcmRgLCBgc2VsZWN0Tm9kZUZvcndhcmRgXG4qICoqTW9kLURlbGV0ZSoqIHRvIGBkZWxldGVTZWxlY3Rpb25gLCBgam9pbkZvcndhcmRgLCBgc2VsZWN0Tm9kZUZvcndhcmRgXG4qICoqTW9kLWEqKiB0byBgc2VsZWN0QWxsYFxuKi9cbmNvbnN0IHBjQmFzZUtleW1hcCA9IHtcbiAgICBcIkVudGVyXCI6IGNoYWluQ29tbWFuZHMobmV3bGluZUluQ29kZSwgY3JlYXRlUGFyYWdyYXBoTmVhciwgbGlmdEVtcHR5QmxvY2ssIHNwbGl0QmxvY2spLFxuICAgIFwiTW9kLUVudGVyXCI6IGV4aXRDb2RlLFxuICAgIFwiQmFja3NwYWNlXCI6IGJhY2tzcGFjZSxcbiAgICBcIk1vZC1CYWNrc3BhY2VcIjogYmFja3NwYWNlLFxuICAgIFwiU2hpZnQtQmFja3NwYWNlXCI6IGJhY2tzcGFjZSxcbiAgICBcIkRlbGV0ZVwiOiBkZWwsXG4gICAgXCJNb2QtRGVsZXRlXCI6IGRlbCxcbiAgICBcIk1vZC1hXCI6IHNlbGVjdEFsbFxufTtcbi8qKlxuQSBjb3B5IG9mIGBwY0Jhc2VLZXltYXBgIHRoYXQgYWxzbyBiaW5kcyAqKkN0cmwtaCoqIGxpa2UgQmFja3NwYWNlLFxuKipDdHJsLWQqKiBsaWtlIERlbGV0ZSwgKipBbHQtQmFja3NwYWNlKiogbGlrZSBDdHJsLUJhY2tzcGFjZSwgYW5kXG4qKkN0cmwtQWx0LUJhY2tzcGFjZSoqLCAqKkFsdC1EZWxldGUqKiwgYW5kICoqQWx0LWQqKiBsaWtlXG5DdHJsLURlbGV0ZS5cbiovXG5jb25zdCBtYWNCYXNlS2V5bWFwID0ge1xuICAgIFwiQ3RybC1oXCI6IHBjQmFzZUtleW1hcFtcIkJhY2tzcGFjZVwiXSxcbiAgICBcIkFsdC1CYWNrc3BhY2VcIjogcGNCYXNlS2V5bWFwW1wiTW9kLUJhY2tzcGFjZVwiXSxcbiAgICBcIkN0cmwtZFwiOiBwY0Jhc2VLZXltYXBbXCJEZWxldGVcIl0sXG4gICAgXCJDdHJsLUFsdC1CYWNrc3BhY2VcIjogcGNCYXNlS2V5bWFwW1wiTW9kLURlbGV0ZVwiXSxcbiAgICBcIkFsdC1EZWxldGVcIjogcGNCYXNlS2V5bWFwW1wiTW9kLURlbGV0ZVwiXSxcbiAgICBcIkFsdC1kXCI6IHBjQmFzZUtleW1hcFtcIk1vZC1EZWxldGVcIl0sXG4gICAgXCJDdHJsLWFcIjogc2VsZWN0VGV4dGJsb2NrU3RhcnQsXG4gICAgXCJDdHJsLWVcIjogc2VsZWN0VGV4dGJsb2NrRW5kXG59O1xuZm9yIChsZXQga2V5IGluIHBjQmFzZUtleW1hcClcbiAgICBtYWNCYXNlS2V5bWFwW2tleV0gPSBwY0Jhc2VLZXltYXBba2V5XTtcbmNvbnN0IG1hYyA9IHR5cGVvZiBuYXZpZ2F0b3IgIT0gXCJ1bmRlZmluZWRcIiA/IC9NYWN8aVAoaG9uZXxbb2FdZCkvLnRlc3QobmF2aWdhdG9yLnBsYXRmb3JtKVxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICA6IHR5cGVvZiBvcyAhPSBcInVuZGVmaW5lZFwiICYmIG9zLnBsYXRmb3JtID8gb3MucGxhdGZvcm0oKSA9PSBcImRhcndpblwiIDogZmFsc2U7XG4vKipcbkRlcGVuZGluZyBvbiB0aGUgZGV0ZWN0ZWQgcGxhdGZvcm0sIHRoaXMgd2lsbCBob2xkXG5bYHBjQmFzZWtleW1hcGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNjb21tYW5kcy5wY0Jhc2VLZXltYXApIG9yXG5bYG1hY0Jhc2VLZXltYXBgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jY29tbWFuZHMubWFjQmFzZUtleW1hcCkuXG4qL1xuY29uc3QgYmFzZUtleW1hcCA9IG1hYyA/IG1hY0Jhc2VLZXltYXAgOiBwY0Jhc2VLZXltYXA7XG5cbmV4cG9ydCB7IGF1dG9Kb2luLCBiYXNlS2V5bWFwLCBjaGFpbkNvbW1hbmRzLCBjcmVhdGVQYXJhZ3JhcGhOZWFyLCBkZWxldGVTZWxlY3Rpb24sIGV4aXRDb2RlLCBqb2luQmFja3dhcmQsIGpvaW5Eb3duLCBqb2luRm9yd2FyZCwgam9pblRleHRibG9ja0JhY2t3YXJkLCBqb2luVGV4dGJsb2NrRm9yd2FyZCwgam9pblVwLCBsaWZ0LCBsaWZ0RW1wdHlCbG9jaywgbWFjQmFzZUtleW1hcCwgbmV3bGluZUluQ29kZSwgcGNCYXNlS2V5bWFwLCBzZWxlY3RBbGwsIHNlbGVjdE5vZGVCYWNrd2FyZCwgc2VsZWN0Tm9kZUZvcndhcmQsIHNlbGVjdFBhcmVudE5vZGUsIHNlbGVjdFRleHRibG9ja0VuZCwgc2VsZWN0VGV4dGJsb2NrU3RhcnQsIHNldEJsb2NrVHlwZSwgc3BsaXRCbG9jaywgc3BsaXRCbG9ja0FzLCBzcGxpdEJsb2NrS2VlcE1hcmtzLCB0b2dnbGVNYXJrLCB3cmFwSW4gfTtcbiIsICJpbXBvcnQgeyBmaW5kV3JhcHBpbmcsIFJlcGxhY2VBcm91bmRTdGVwLCBjYW5TcGxpdCwgbGlmdFRhcmdldCwgY2FuSm9pbiB9IGZyb20gJ3Byb3NlbWlycm9yLXRyYW5zZm9ybSc7XG5pbXBvcnQgeyBOb2RlUmFuZ2UsIEZyYWdtZW50LCBTbGljZSB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB7IFNlbGVjdGlvbiB9IGZyb20gJ3Byb3NlbWlycm9yLXN0YXRlJztcblxuY29uc3Qgb2xET00gPSBbXCJvbFwiLCAwXSwgdWxET00gPSBbXCJ1bFwiLCAwXSwgbGlET00gPSBbXCJsaVwiLCAwXTtcbi8qKlxuQW4gb3JkZXJlZCBsaXN0IFtub2RlIHNwZWNdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYykuIEhhcyBhIHNpbmdsZVxuYXR0cmlidXRlLCBgb3JkZXJgLCB3aGljaCBkZXRlcm1pbmVzIHRoZSBudW1iZXIgYXQgd2hpY2ggdGhlIGxpc3RcbnN0YXJ0cyBjb3VudGluZywgYW5kIGRlZmF1bHRzIHRvIDEuIFJlcHJlc2VudGVkIGFzIGFuIGA8b2w+YFxuZWxlbWVudC5cbiovXG5jb25zdCBvcmRlcmVkTGlzdCA9IHtcbiAgICBhdHRyczogeyBvcmRlcjogeyBkZWZhdWx0OiAxLCB2YWxpZGF0ZTogXCJudW1iZXJcIiB9IH0sXG4gICAgcGFyc2VET006IFt7IHRhZzogXCJvbFwiLCBnZXRBdHRycyhkb20pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBvcmRlcjogZG9tLmhhc0F0dHJpYnV0ZShcInN0YXJ0XCIpID8gK2RvbS5nZXRBdHRyaWJ1dGUoXCJzdGFydFwiKSA6IDEgfTtcbiAgICAgICAgICAgIH0gfV0sXG4gICAgdG9ET00obm9kZSkge1xuICAgICAgICByZXR1cm4gbm9kZS5hdHRycy5vcmRlciA9PSAxID8gb2xET00gOiBbXCJvbFwiLCB7IHN0YXJ0OiBub2RlLmF0dHJzLm9yZGVyIH0sIDBdO1xuICAgIH1cbn07XG4vKipcbkEgYnVsbGV0IGxpc3Qgbm9kZSBzcGVjLCByZXByZXNlbnRlZCBpbiB0aGUgRE9NIGFzIGA8dWw+YC5cbiovXG5jb25zdCBidWxsZXRMaXN0ID0ge1xuICAgIHBhcnNlRE9NOiBbeyB0YWc6IFwidWxcIiB9XSxcbiAgICB0b0RPTSgpIHsgcmV0dXJuIHVsRE9NOyB9XG59O1xuLyoqXG5BIGxpc3QgaXRlbSAoYDxsaT5gKSBzcGVjLlxuKi9cbmNvbnN0IGxpc3RJdGVtID0ge1xuICAgIHBhcnNlRE9NOiBbeyB0YWc6IFwibGlcIiB9XSxcbiAgICB0b0RPTSgpIHsgcmV0dXJuIGxpRE9NOyB9LFxuICAgIGRlZmluaW5nOiB0cnVlXG59O1xuZnVuY3Rpb24gYWRkKG9iaiwgcHJvcHMpIHtcbiAgICBsZXQgY29weSA9IHt9O1xuICAgIGZvciAobGV0IHByb3AgaW4gb2JqKVxuICAgICAgICBjb3B5W3Byb3BdID0gb2JqW3Byb3BdO1xuICAgIGZvciAobGV0IHByb3AgaW4gcHJvcHMpXG4gICAgICAgIGNvcHlbcHJvcF0gPSBwcm9wc1twcm9wXTtcbiAgICByZXR1cm4gY29weTtcbn1cbi8qKlxuQ29udmVuaWVuY2UgZnVuY3Rpb24gZm9yIGFkZGluZyBsaXN0LXJlbGF0ZWQgbm9kZSB0eXBlcyB0byBhIG1hcFxuc3BlY2lmeWluZyB0aGUgbm9kZXMgZm9yIGEgc2NoZW1hLiBBZGRzXG5bYG9yZGVyZWRMaXN0YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3NjaGVtYS1saXN0Lm9yZGVyZWRMaXN0KSBhcyBgXCJvcmRlcmVkX2xpc3RcImAsXG5bYGJ1bGxldExpc3RgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc2NoZW1hLWxpc3QuYnVsbGV0TGlzdCkgYXMgYFwiYnVsbGV0X2xpc3RcImAsIGFuZFxuW2BsaXN0SXRlbWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzY2hlbWEtbGlzdC5saXN0SXRlbSkgYXMgYFwibGlzdF9pdGVtXCJgLlxuXG5gaXRlbUNvbnRlbnRgIGRldGVybWluZXMgdGhlIGNvbnRlbnQgZXhwcmVzc2lvbiBmb3IgdGhlIGxpc3QgaXRlbXMuXG5JZiB5b3Ugd2FudCB0aGUgY29tbWFuZHMgZGVmaW5lZCBpbiB0aGlzIG1vZHVsZSB0byBhcHBseSB0byB5b3VyXG5saXN0IHN0cnVjdHVyZSwgaXQgc2hvdWxkIGhhdmUgYSBzaGFwZSBsaWtlIGBcInBhcmFncmFwaCBibG9jaypcImAgb3JcbmBcInBhcmFncmFwaCAob3JkZXJlZF9saXN0IHwgYnVsbGV0X2xpc3QpKlwiYC4gYGxpc3RHcm91cGAgY2FuIGJlXG5naXZlbiB0byBhc3NpZ24gYSBncm91cCBuYW1lIHRvIHRoZSBsaXN0IG5vZGUgdHlwZXMsIGZvciBleGFtcGxlXG5gXCJibG9ja1wiYC5cbiovXG5mdW5jdGlvbiBhZGRMaXN0Tm9kZXMobm9kZXMsIGl0ZW1Db250ZW50LCBsaXN0R3JvdXApIHtcbiAgICByZXR1cm4gbm9kZXMuYXBwZW5kKHtcbiAgICAgICAgb3JkZXJlZF9saXN0OiBhZGQob3JkZXJlZExpc3QsIHsgY29udGVudDogXCJsaXN0X2l0ZW0rXCIsIGdyb3VwOiBsaXN0R3JvdXAgfSksXG4gICAgICAgIGJ1bGxldF9saXN0OiBhZGQoYnVsbGV0TGlzdCwgeyBjb250ZW50OiBcImxpc3RfaXRlbStcIiwgZ3JvdXA6IGxpc3RHcm91cCB9KSxcbiAgICAgICAgbGlzdF9pdGVtOiBhZGQobGlzdEl0ZW0sIHsgY29udGVudDogaXRlbUNvbnRlbnQgfSlcbiAgICB9KTtcbn1cbi8qKlxuUmV0dXJucyBhIGNvbW1hbmQgZnVuY3Rpb24gdGhhdCB3cmFwcyB0aGUgc2VsZWN0aW9uIGluIGEgbGlzdCB3aXRoXG50aGUgZ2l2ZW4gdHlwZSBhbiBhdHRyaWJ1dGVzLiBJZiBgZGlzcGF0Y2hgIGlzIG51bGwsIG9ubHkgcmV0dXJuIGFcbnZhbHVlIHRvIGluZGljYXRlIHdoZXRoZXIgdGhpcyBpcyBwb3NzaWJsZSwgYnV0IGRvbid0IGFjdHVhbGx5XG5wZXJmb3JtIHRoZSBjaGFuZ2UuXG4qL1xuZnVuY3Rpb24gd3JhcEluTGlzdChsaXN0VHlwZSwgYXR0cnMgPSBudWxsKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzdGF0ZSwgZGlzcGF0Y2gpIHtcbiAgICAgICAgbGV0IHsgJGZyb20sICR0byB9ID0gc3RhdGUuc2VsZWN0aW9uO1xuICAgICAgICBsZXQgcmFuZ2UgPSAkZnJvbS5ibG9ja1JhbmdlKCR0byk7XG4gICAgICAgIGlmICghcmFuZ2UpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGxldCB0ciA9IGRpc3BhdGNoID8gc3RhdGUudHIgOiBudWxsO1xuICAgICAgICBpZiAoIXdyYXBSYW5nZUluTGlzdCh0ciwgcmFuZ2UsIGxpc3RUeXBlLCBhdHRycykpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xufVxuLyoqXG5UcnkgdG8gd3JhcCB0aGUgZ2l2ZW4gbm9kZSByYW5nZSBpbiBhIGxpc3Qgb2YgdGhlIGdpdmVuIHR5cGUuXG5SZXR1cm4gYHRydWVgIHdoZW4gdGhpcyBpcyBwb3NzaWJsZSwgYGZhbHNlYCBvdGhlcndpc2UuIFdoZW4gYHRyYFxuaXMgbm9uLW51bGwsIHRoZSB3cmFwcGluZyBpcyBhZGRlZCB0byB0aGF0IHRyYW5zYWN0aW9uLiBXaGVuIGl0IGlzXG5gbnVsbGAsIHRoZSBmdW5jdGlvbiBvbmx5IHF1ZXJpZXMgd2hldGhlciB0aGUgd3JhcHBpbmcgaXNcbnBvc3NpYmxlLlxuKi9cbmZ1bmN0aW9uIHdyYXBSYW5nZUluTGlzdCh0ciwgcmFuZ2UsIGxpc3RUeXBlLCBhdHRycyA9IG51bGwpIHtcbiAgICBsZXQgZG9Kb2luID0gZmFsc2UsIG91dGVyUmFuZ2UgPSByYW5nZSwgZG9jID0gcmFuZ2UuJGZyb20uZG9jO1xuICAgIC8vIFRoaXMgaXMgYXQgdGhlIHRvcCBvZiBhbiBleGlzdGluZyBsaXN0IGl0ZW1cbiAgICBpZiAocmFuZ2UuZGVwdGggPj0gMiAmJiByYW5nZS4kZnJvbS5ub2RlKHJhbmdlLmRlcHRoIC0gMSkudHlwZS5jb21wYXRpYmxlQ29udGVudChsaXN0VHlwZSkgJiYgcmFuZ2Uuc3RhcnRJbmRleCA9PSAwKSB7XG4gICAgICAgIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIHRoaXMgaXMgdGhlIHRvcCBvZiB0aGUgbGlzdFxuICAgICAgICBpZiAocmFuZ2UuJGZyb20uaW5kZXgocmFuZ2UuZGVwdGggLSAxKSA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgJGluc2VydCA9IGRvYy5yZXNvbHZlKHJhbmdlLnN0YXJ0IC0gMik7XG4gICAgICAgIG91dGVyUmFuZ2UgPSBuZXcgTm9kZVJhbmdlKCRpbnNlcnQsICRpbnNlcnQsIHJhbmdlLmRlcHRoKTtcbiAgICAgICAgaWYgKHJhbmdlLmVuZEluZGV4IDwgcmFuZ2UucGFyZW50LmNoaWxkQ291bnQpXG4gICAgICAgICAgICByYW5nZSA9IG5ldyBOb2RlUmFuZ2UocmFuZ2UuJGZyb20sIGRvYy5yZXNvbHZlKHJhbmdlLiR0by5lbmQocmFuZ2UuZGVwdGgpKSwgcmFuZ2UuZGVwdGgpO1xuICAgICAgICBkb0pvaW4gPSB0cnVlO1xuICAgIH1cbiAgICBsZXQgd3JhcCA9IGZpbmRXcmFwcGluZyhvdXRlclJhbmdlLCBsaXN0VHlwZSwgYXR0cnMsIHJhbmdlKTtcbiAgICBpZiAoIXdyYXApXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBpZiAodHIpXG4gICAgICAgIGRvV3JhcEluTGlzdCh0ciwgcmFuZ2UsIHdyYXAsIGRvSm9pbiwgbGlzdFR5cGUpO1xuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gZG9XcmFwSW5MaXN0KHRyLCByYW5nZSwgd3JhcHBlcnMsIGpvaW5CZWZvcmUsIGxpc3RUeXBlKSB7XG4gICAgbGV0IGNvbnRlbnQgPSBGcmFnbWVudC5lbXB0eTtcbiAgICBmb3IgKGxldCBpID0gd3JhcHBlcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgIGNvbnRlbnQgPSBGcmFnbWVudC5mcm9tKHdyYXBwZXJzW2ldLnR5cGUuY3JlYXRlKHdyYXBwZXJzW2ldLmF0dHJzLCBjb250ZW50KSk7XG4gICAgdHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAocmFuZ2Uuc3RhcnQgLSAoam9pbkJlZm9yZSA/IDIgOiAwKSwgcmFuZ2UuZW5kLCByYW5nZS5zdGFydCwgcmFuZ2UuZW5kLCBuZXcgU2xpY2UoY29udGVudCwgMCwgMCksIHdyYXBwZXJzLmxlbmd0aCwgdHJ1ZSkpO1xuICAgIGxldCBmb3VuZCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB3cmFwcGVycy5sZW5ndGg7IGkrKylcbiAgICAgICAgaWYgKHdyYXBwZXJzW2ldLnR5cGUgPT0gbGlzdFR5cGUpXG4gICAgICAgICAgICBmb3VuZCA9IGkgKyAxO1xuICAgIGxldCBzcGxpdERlcHRoID0gd3JhcHBlcnMubGVuZ3RoIC0gZm91bmQ7XG4gICAgbGV0IHNwbGl0UG9zID0gcmFuZ2Uuc3RhcnQgKyB3cmFwcGVycy5sZW5ndGggLSAoam9pbkJlZm9yZSA/IDIgOiAwKSwgcGFyZW50ID0gcmFuZ2UucGFyZW50O1xuICAgIGZvciAobGV0IGkgPSByYW5nZS5zdGFydEluZGV4LCBlID0gcmFuZ2UuZW5kSW5kZXgsIGZpcnN0ID0gdHJ1ZTsgaSA8IGU7IGkrKywgZmlyc3QgPSBmYWxzZSkge1xuICAgICAgICBpZiAoIWZpcnN0ICYmIGNhblNwbGl0KHRyLmRvYywgc3BsaXRQb3MsIHNwbGl0RGVwdGgpKSB7XG4gICAgICAgICAgICB0ci5zcGxpdChzcGxpdFBvcywgc3BsaXREZXB0aCk7XG4gICAgICAgICAgICBzcGxpdFBvcyArPSAyICogc3BsaXREZXB0aDtcbiAgICAgICAgfVxuICAgICAgICBzcGxpdFBvcyArPSBwYXJlbnQuY2hpbGQoaSkubm9kZVNpemU7XG4gICAgfVxuICAgIHJldHVybiB0cjtcbn1cbi8qKlxuQnVpbGQgYSBjb21tYW5kIHRoYXQgc3BsaXRzIGEgbm9uLWVtcHR5IHRleHRibG9jayBhdCB0aGUgdG9wIGxldmVsXG5vZiBhIGxpc3QgaXRlbSBieSBhbHNvIHNwbGl0dGluZyB0aGF0IGxpc3QgaXRlbS5cbiovXG5mdW5jdGlvbiBzcGxpdExpc3RJdGVtKGl0ZW1UeXBlLCBpdGVtQXR0cnMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHN0YXRlLCBkaXNwYXRjaCkge1xuICAgICAgICBsZXQgeyAkZnJvbSwgJHRvLCBub2RlIH0gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgICAgIGlmICgobm9kZSAmJiBub2RlLmlzQmxvY2spIHx8ICRmcm9tLmRlcHRoIDwgMiB8fCAhJGZyb20uc2FtZVBhcmVudCgkdG8pKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgZ3JhbmRQYXJlbnQgPSAkZnJvbS5ub2RlKC0xKTtcbiAgICAgICAgaWYgKGdyYW5kUGFyZW50LnR5cGUgIT0gaXRlbVR5cGUpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmICgkZnJvbS5wYXJlbnQuY29udGVudC5zaXplID09IDAgJiYgJGZyb20ubm9kZSgtMSkuY2hpbGRDb3VudCA9PSAkZnJvbS5pbmRleEFmdGVyKC0xKSkge1xuICAgICAgICAgICAgLy8gSW4gYW4gZW1wdHkgYmxvY2suIElmIHRoaXMgaXMgYSBuZXN0ZWQgbGlzdCwgdGhlIHdyYXBwaW5nXG4gICAgICAgICAgICAvLyBsaXN0IGl0ZW0gc2hvdWxkIGJlIHNwbGl0LiBPdGhlcndpc2UsIGJhaWwgb3V0IGFuZCBsZXQgbmV4dFxuICAgICAgICAgICAgLy8gY29tbWFuZCBoYW5kbGUgbGlmdGluZy5cbiAgICAgICAgICAgIGlmICgkZnJvbS5kZXB0aCA9PSAzIHx8ICRmcm9tLm5vZGUoLTMpLnR5cGUgIT0gaXRlbVR5cGUgfHxcbiAgICAgICAgICAgICAgICAkZnJvbS5pbmRleCgtMikgIT0gJGZyb20ubm9kZSgtMikuY2hpbGRDb3VudCAtIDEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHdyYXAgPSBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgICAgICAgICBsZXQgZGVwdGhCZWZvcmUgPSAkZnJvbS5pbmRleCgtMSkgPyAxIDogJGZyb20uaW5kZXgoLTIpID8gMiA6IDM7XG4gICAgICAgICAgICAgICAgLy8gQnVpbGQgYSBmcmFnbWVudCBjb250YWluaW5nIGVtcHR5IHZlcnNpb25zIG9mIHRoZSBzdHJ1Y3R1cmVcbiAgICAgICAgICAgICAgICAvLyBmcm9tIHRoZSBvdXRlciBsaXN0IGl0ZW0gdG8gdGhlIHBhcmVudCBub2RlIG9mIHRoZSBjdXJzb3JcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBkID0gJGZyb20uZGVwdGggLSBkZXB0aEJlZm9yZTsgZCA+PSAkZnJvbS5kZXB0aCAtIDM7IGQtLSlcbiAgICAgICAgICAgICAgICAgICAgd3JhcCA9IEZyYWdtZW50LmZyb20oJGZyb20ubm9kZShkKS5jb3B5KHdyYXApKTtcbiAgICAgICAgICAgICAgICBsZXQgZGVwdGhBZnRlciA9ICRmcm9tLmluZGV4QWZ0ZXIoLTEpIDwgJGZyb20ubm9kZSgtMikuY2hpbGRDb3VudCA/IDFcbiAgICAgICAgICAgICAgICAgICAgOiAkZnJvbS5pbmRleEFmdGVyKC0yKSA8ICRmcm9tLm5vZGUoLTMpLmNoaWxkQ291bnQgPyAyIDogMztcbiAgICAgICAgICAgICAgICAvLyBBZGQgYSBzZWNvbmQgbGlzdCBpdGVtIHdpdGggYW4gZW1wdHkgZGVmYXVsdCBzdGFydCBub2RlXG4gICAgICAgICAgICAgICAgd3JhcCA9IHdyYXAuYXBwZW5kKEZyYWdtZW50LmZyb20oaXRlbVR5cGUuY3JlYXRlQW5kRmlsbCgpKSk7XG4gICAgICAgICAgICAgICAgbGV0IHN0YXJ0ID0gJGZyb20uYmVmb3JlKCRmcm9tLmRlcHRoIC0gKGRlcHRoQmVmb3JlIC0gMSkpO1xuICAgICAgICAgICAgICAgIGxldCB0ciA9IHN0YXRlLnRyLnJlcGxhY2Uoc3RhcnQsICRmcm9tLmFmdGVyKC1kZXB0aEFmdGVyKSwgbmV3IFNsaWNlKHdyYXAsIDQgLSBkZXB0aEJlZm9yZSwgMCkpO1xuICAgICAgICAgICAgICAgIGxldCBzZWwgPSAtMTtcbiAgICAgICAgICAgICAgICB0ci5kb2Mubm9kZXNCZXR3ZWVuKHN0YXJ0LCB0ci5kb2MuY29udGVudC5zaXplLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWwgPiAtMSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUuaXNUZXh0YmxvY2sgJiYgbm9kZS5jb250ZW50LnNpemUgPT0gMClcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbCA9IHBvcyArIDE7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKHNlbCA+IC0xKVxuICAgICAgICAgICAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24oU2VsZWN0aW9uLm5lYXIodHIuZG9jLnJlc29sdmUoc2VsKSkpO1xuICAgICAgICAgICAgICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG5leHRUeXBlID0gJHRvLnBvcyA9PSAkZnJvbS5lbmQoKSA/IGdyYW5kUGFyZW50LmNvbnRlbnRNYXRjaEF0KDApLmRlZmF1bHRUeXBlIDogbnVsbDtcbiAgICAgICAgbGV0IHRyID0gc3RhdGUudHIuZGVsZXRlKCRmcm9tLnBvcywgJHRvLnBvcyk7XG4gICAgICAgIGxldCB0eXBlcyA9IG5leHRUeXBlID8gW2l0ZW1BdHRycyA/IHsgdHlwZTogaXRlbVR5cGUsIGF0dHJzOiBpdGVtQXR0cnMgfSA6IG51bGwsIHsgdHlwZTogbmV4dFR5cGUgfV0gOiB1bmRlZmluZWQ7XG4gICAgICAgIGlmICghY2FuU3BsaXQodHIuZG9jLCAkZnJvbS5wb3MsIDIsIHR5cGVzKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICAgICAgZGlzcGF0Y2godHIuc3BsaXQoJGZyb20ucG9zLCAyLCB0eXBlcykuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG59XG4vKipcbkFjdHMgbGlrZSBbYHNwbGl0TGlzdEl0ZW1gXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc2NoZW1hLWxpc3Quc3BsaXRMaXN0SXRlbSksIGJ1dFxud2l0aG91dCByZXNldHRpbmcgdGhlIHNldCBvZiBhY3RpdmUgbWFya3MgYXQgdGhlIGN1cnNvci5cbiovXG5mdW5jdGlvbiBzcGxpdExpc3RJdGVtS2VlcE1hcmtzKGl0ZW1UeXBlLCBpdGVtQXR0cnMpIHtcbiAgICBsZXQgc3BsaXQgPSBzcGxpdExpc3RJdGVtKGl0ZW1UeXBlLCBpdGVtQXR0cnMpO1xuICAgIHJldHVybiAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgICAgIHJldHVybiBzcGxpdChzdGF0ZSwgZGlzcGF0Y2ggJiYgKHRyID0+IHtcbiAgICAgICAgICAgIGxldCBtYXJrcyA9IHN0YXRlLnN0b3JlZE1hcmtzIHx8IChzdGF0ZS5zZWxlY3Rpb24uJHRvLnBhcmVudE9mZnNldCAmJiBzdGF0ZS5zZWxlY3Rpb24uJGZyb20ubWFya3MoKSk7XG4gICAgICAgICAgICBpZiAobWFya3MpXG4gICAgICAgICAgICAgICAgdHIuZW5zdXJlTWFya3MobWFya3MpO1xuICAgICAgICAgICAgZGlzcGF0Y2godHIpO1xuICAgICAgICB9KSk7XG4gICAgfTtcbn1cbi8qKlxuQ3JlYXRlIGEgY29tbWFuZCB0byBsaWZ0IHRoZSBsaXN0IGl0ZW0gYXJvdW5kIHRoZSBzZWxlY3Rpb24gdXAgaW50b1xuYSB3cmFwcGluZyBsaXN0LlxuKi9cbmZ1bmN0aW9uIGxpZnRMaXN0SXRlbShpdGVtVHlwZSkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoc3RhdGUsIGRpc3BhdGNoKSB7XG4gICAgICAgIGxldCB7ICRmcm9tLCAkdG8gfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgbGV0IHJhbmdlID0gJGZyb20uYmxvY2tSYW5nZSgkdG8sIG5vZGUgPT4gbm9kZS5jaGlsZENvdW50ID4gMCAmJiBub2RlLmZpcnN0Q2hpbGQudHlwZSA9PSBpdGVtVHlwZSk7XG4gICAgICAgIGlmICghcmFuZ2UpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmICghZGlzcGF0Y2gpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgaWYgKCRmcm9tLm5vZGUocmFuZ2UuZGVwdGggLSAxKS50eXBlID09IGl0ZW1UeXBlKSAvLyBJbnNpZGUgYSBwYXJlbnQgbGlzdFxuICAgICAgICAgICAgcmV0dXJuIGxpZnRUb091dGVyTGlzdChzdGF0ZSwgZGlzcGF0Y2gsIGl0ZW1UeXBlLCByYW5nZSk7XG4gICAgICAgIGVsc2UgLy8gT3V0ZXIgbGlzdCBub2RlXG4gICAgICAgICAgICByZXR1cm4gbGlmdE91dE9mTGlzdChzdGF0ZSwgZGlzcGF0Y2gsIHJhbmdlKTtcbiAgICB9O1xufVxuZnVuY3Rpb24gbGlmdFRvT3V0ZXJMaXN0KHN0YXRlLCBkaXNwYXRjaCwgaXRlbVR5cGUsIHJhbmdlKSB7XG4gICAgbGV0IHRyID0gc3RhdGUudHIsIGVuZCA9IHJhbmdlLmVuZCwgZW5kT2ZMaXN0ID0gcmFuZ2UuJHRvLmVuZChyYW5nZS5kZXB0aCk7XG4gICAgaWYgKGVuZCA8IGVuZE9mTGlzdCkge1xuICAgICAgICAvLyBUaGVyZSBhcmUgc2libGluZ3MgYWZ0ZXIgdGhlIGxpZnRlZCBpdGVtcywgd2hpY2ggbXVzdCBiZWNvbWVcbiAgICAgICAgLy8gY2hpbGRyZW4gb2YgdGhlIGxhc3QgaXRlbVxuICAgICAgICB0ci5zdGVwKG5ldyBSZXBsYWNlQXJvdW5kU3RlcChlbmQgLSAxLCBlbmRPZkxpc3QsIGVuZCwgZW5kT2ZMaXN0LCBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbShpdGVtVHlwZS5jcmVhdGUobnVsbCwgcmFuZ2UucGFyZW50LmNvcHkoKSkpLCAxLCAwKSwgMSwgdHJ1ZSkpO1xuICAgICAgICByYW5nZSA9IG5ldyBOb2RlUmFuZ2UodHIuZG9jLnJlc29sdmUocmFuZ2UuJGZyb20ucG9zKSwgdHIuZG9jLnJlc29sdmUoZW5kT2ZMaXN0KSwgcmFuZ2UuZGVwdGgpO1xuICAgIH1cbiAgICBjb25zdCB0YXJnZXQgPSBsaWZ0VGFyZ2V0KHJhbmdlKTtcbiAgICBpZiAodGFyZ2V0ID09IG51bGwpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB0ci5saWZ0KHJhbmdlLCB0YXJnZXQpO1xuICAgIGxldCAkYWZ0ZXIgPSB0ci5kb2MucmVzb2x2ZSh0ci5tYXBwaW5nLm1hcChlbmQsIC0xKSAtIDEpO1xuICAgIGlmIChjYW5Kb2luKHRyLmRvYywgJGFmdGVyLnBvcykgJiYgJGFmdGVyLm5vZGVCZWZvcmUudHlwZSA9PSAkYWZ0ZXIubm9kZUFmdGVyLnR5cGUpXG4gICAgICAgIHRyLmpvaW4oJGFmdGVyLnBvcyk7XG4gICAgZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBsaWZ0T3V0T2ZMaXN0KHN0YXRlLCBkaXNwYXRjaCwgcmFuZ2UpIHtcbiAgICBsZXQgdHIgPSBzdGF0ZS50ciwgbGlzdCA9IHJhbmdlLnBhcmVudDtcbiAgICAvLyBNZXJnZSB0aGUgbGlzdCBpdGVtcyBpbnRvIGEgc2luZ2xlIGJpZyBpdGVtXG4gICAgZm9yIChsZXQgcG9zID0gcmFuZ2UuZW5kLCBpID0gcmFuZ2UuZW5kSW5kZXggLSAxLCBlID0gcmFuZ2Uuc3RhcnRJbmRleDsgaSA+IGU7IGktLSkge1xuICAgICAgICBwb3MgLT0gbGlzdC5jaGlsZChpKS5ub2RlU2l6ZTtcbiAgICAgICAgdHIuZGVsZXRlKHBvcyAtIDEsIHBvcyArIDEpO1xuICAgIH1cbiAgICBsZXQgJHN0YXJ0ID0gdHIuZG9jLnJlc29sdmUocmFuZ2Uuc3RhcnQpLCBpdGVtID0gJHN0YXJ0Lm5vZGVBZnRlcjtcbiAgICBpZiAodHIubWFwcGluZy5tYXAocmFuZ2UuZW5kKSAhPSByYW5nZS5zdGFydCArICRzdGFydC5ub2RlQWZ0ZXIubm9kZVNpemUpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgYXRTdGFydCA9IHJhbmdlLnN0YXJ0SW5kZXggPT0gMCwgYXRFbmQgPSByYW5nZS5lbmRJbmRleCA9PSBsaXN0LmNoaWxkQ291bnQ7XG4gICAgbGV0IHBhcmVudCA9ICRzdGFydC5ub2RlKC0xKSwgaW5kZXhCZWZvcmUgPSAkc3RhcnQuaW5kZXgoLTEpO1xuICAgIGlmICghcGFyZW50LmNhblJlcGxhY2UoaW5kZXhCZWZvcmUgKyAoYXRTdGFydCA/IDAgOiAxKSwgaW5kZXhCZWZvcmUgKyAxLCBpdGVtLmNvbnRlbnQuYXBwZW5kKGF0RW5kID8gRnJhZ21lbnQuZW1wdHkgOiBGcmFnbWVudC5mcm9tKGxpc3QpKSkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgc3RhcnQgPSAkc3RhcnQucG9zLCBlbmQgPSBzdGFydCArIGl0ZW0ubm9kZVNpemU7XG4gICAgLy8gU3RyaXAgb2ZmIHRoZSBzdXJyb3VuZGluZyBsaXN0LiBBdCB0aGUgc2lkZXMgd2hlcmUgd2UncmUgbm90IGF0XG4gICAgLy8gdGhlIGVuZCBvZiB0aGUgbGlzdCwgdGhlIGV4aXN0aW5nIGxpc3QgaXMgY2xvc2VkLiBBdCBzaWRlcyB3aGVyZVxuICAgIC8vIHRoaXMgaXMgdGhlIGVuZCwgaXQgaXMgb3ZlcndyaXR0ZW4gdG8gaXRzIGVuZC5cbiAgICB0ci5zdGVwKG5ldyBSZXBsYWNlQXJvdW5kU3RlcChzdGFydCAtIChhdFN0YXJ0ID8gMSA6IDApLCBlbmQgKyAoYXRFbmQgPyAxIDogMCksIHN0YXJ0ICsgMSwgZW5kIC0gMSwgbmV3IFNsaWNlKChhdFN0YXJ0ID8gRnJhZ21lbnQuZW1wdHkgOiBGcmFnbWVudC5mcm9tKGxpc3QuY29weShGcmFnbWVudC5lbXB0eSkpKVxuICAgICAgICAuYXBwZW5kKGF0RW5kID8gRnJhZ21lbnQuZW1wdHkgOiBGcmFnbWVudC5mcm9tKGxpc3QuY29weShGcmFnbWVudC5lbXB0eSkpKSwgYXRTdGFydCA/IDAgOiAxLCBhdEVuZCA/IDAgOiAxKSwgYXRTdGFydCA/IDAgOiAxKSk7XG4gICAgZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgcmV0dXJuIHRydWU7XG59XG4vKipcbkNyZWF0ZSBhIGNvbW1hbmQgdG8gc2luayB0aGUgbGlzdCBpdGVtIGFyb3VuZCB0aGUgc2VsZWN0aW9uIGRvd25cbmludG8gYW4gaW5uZXIgbGlzdC5cbiovXG5mdW5jdGlvbiBzaW5rTGlzdEl0ZW0oaXRlbVR5cGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHN0YXRlLCBkaXNwYXRjaCkge1xuICAgICAgICBsZXQgeyAkZnJvbSwgJHRvIH0gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgICAgIGxldCByYW5nZSA9ICRmcm9tLmJsb2NrUmFuZ2UoJHRvLCBub2RlID0+IG5vZGUuY2hpbGRDb3VudCA+IDAgJiYgbm9kZS5maXJzdENoaWxkLnR5cGUgPT0gaXRlbVR5cGUpO1xuICAgICAgICBpZiAoIXJhbmdlKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgc3RhcnRJbmRleCA9IHJhbmdlLnN0YXJ0SW5kZXg7XG4gICAgICAgIGlmIChzdGFydEluZGV4ID09IDApXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGxldCBwYXJlbnQgPSByYW5nZS5wYXJlbnQsIG5vZGVCZWZvcmUgPSBwYXJlbnQuY2hpbGQoc3RhcnRJbmRleCAtIDEpO1xuICAgICAgICBpZiAobm9kZUJlZm9yZS50eXBlICE9IGl0ZW1UeXBlKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgICAgIGxldCBuZXN0ZWRCZWZvcmUgPSBub2RlQmVmb3JlLmxhc3RDaGlsZCAmJiBub2RlQmVmb3JlLmxhc3RDaGlsZC50eXBlID09IHBhcmVudC50eXBlO1xuICAgICAgICAgICAgbGV0IGlubmVyID0gRnJhZ21lbnQuZnJvbShuZXN0ZWRCZWZvcmUgPyBpdGVtVHlwZS5jcmVhdGUoKSA6IG51bGwpO1xuICAgICAgICAgICAgbGV0IHNsaWNlID0gbmV3IFNsaWNlKEZyYWdtZW50LmZyb20oaXRlbVR5cGUuY3JlYXRlKG51bGwsIEZyYWdtZW50LmZyb20ocGFyZW50LnR5cGUuY3JlYXRlKG51bGwsIGlubmVyKSkpKSwgbmVzdGVkQmVmb3JlID8gMyA6IDEsIDApO1xuICAgICAgICAgICAgbGV0IGJlZm9yZSA9IHJhbmdlLnN0YXJ0LCBhZnRlciA9IHJhbmdlLmVuZDtcbiAgICAgICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLnN0ZXAobmV3IFJlcGxhY2VBcm91bmRTdGVwKGJlZm9yZSAtIChuZXN0ZWRCZWZvcmUgPyAzIDogMSksIGFmdGVyLCBiZWZvcmUsIGFmdGVyLCBzbGljZSwgMSwgdHJ1ZSkpXG4gICAgICAgICAgICAgICAgLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG59XG5cbmV4cG9ydCB7IGFkZExpc3ROb2RlcywgYnVsbGV0TGlzdCwgbGlmdExpc3RJdGVtLCBsaXN0SXRlbSwgb3JkZXJlZExpc3QsIHNpbmtMaXN0SXRlbSwgc3BsaXRMaXN0SXRlbSwgc3BsaXRMaXN0SXRlbUtlZXBNYXJrcywgd3JhcEluTGlzdCwgd3JhcFJhbmdlSW5MaXN0IH07XG4iLCAiaW1wb3J0IHsgVGV4dFNlbGVjdGlvbiwgTm9kZVNlbGVjdGlvbiwgQWxsU2VsZWN0aW9uLCBTZWxlY3Rpb24gfSBmcm9tICdwcm9zZW1pcnJvci1zdGF0ZSc7XG5pbXBvcnQgeyBET01TZXJpYWxpemVyLCBGcmFnbWVudCwgTWFyaywgU2xpY2UsIERPTVBhcnNlciB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB7IGRyb3BQb2ludCB9IGZyb20gJ3Byb3NlbWlycm9yLXRyYW5zZm9ybSc7XG5cbmNvbnN0IGRvbUluZGV4ID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICBmb3IgKHZhciBpbmRleCA9IDA7OyBpbmRleCsrKSB7XG4gICAgICAgIG5vZGUgPSBub2RlLnByZXZpb3VzU2libGluZztcbiAgICAgICAgaWYgKCFub2RlKVxuICAgICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbn07XG5jb25zdCBwYXJlbnROb2RlID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICBsZXQgcGFyZW50ID0gbm9kZS5hc3NpZ25lZFNsb3QgfHwgbm9kZS5wYXJlbnROb2RlO1xuICAgIHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlID09IDExID8gcGFyZW50Lmhvc3QgOiBwYXJlbnQ7XG59O1xubGV0IHJldXNlZFJhbmdlID0gbnVsbDtcbi8vIE5vdGUgdGhhdCB0aGlzIHdpbGwgYWx3YXlzIHJldHVybiB0aGUgc2FtZSByYW5nZSwgYmVjYXVzZSBET00gcmFuZ2Vcbi8vIG9iamVjdHMgYXJlIGV2ZXJ5IGV4cGVuc2l2ZSwgYW5kIGtlZXAgc2xvd2luZyBkb3duIHN1YnNlcXVlbnQgRE9NXG4vLyB1cGRhdGVzLCBmb3Igc29tZSByZWFzb24uXG5jb25zdCB0ZXh0UmFuZ2UgPSBmdW5jdGlvbiAobm9kZSwgZnJvbSwgdG8pIHtcbiAgICBsZXQgcmFuZ2UgPSByZXVzZWRSYW5nZSB8fCAocmV1c2VkUmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpKTtcbiAgICByYW5nZS5zZXRFbmQobm9kZSwgdG8gPT0gbnVsbCA/IG5vZGUubm9kZVZhbHVlLmxlbmd0aCA6IHRvKTtcbiAgICByYW5nZS5zZXRTdGFydChub2RlLCBmcm9tIHx8IDApO1xuICAgIHJldHVybiByYW5nZTtcbn07XG5jb25zdCBjbGVhclJldXNlZFJhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldXNlZFJhbmdlID0gbnVsbDtcbn07XG4vLyBTY2FucyBmb3J3YXJkIGFuZCBiYWNrd2FyZCB0aHJvdWdoIERPTSBwb3NpdGlvbnMgZXF1aXZhbGVudCB0byB0aGVcbi8vIGdpdmVuIG9uZSB0byBzZWUgaWYgdGhlIHR3byBhcmUgaW4gdGhlIHNhbWUgcGxhY2UgKGkuZS4gYWZ0ZXIgYVxuLy8gdGV4dCBub2RlIHZzIGF0IHRoZSBlbmQgb2YgdGhhdCB0ZXh0IG5vZGUpXG5jb25zdCBpc0VxdWl2YWxlbnRQb3NpdGlvbiA9IGZ1bmN0aW9uIChub2RlLCBvZmYsIHRhcmdldE5vZGUsIHRhcmdldE9mZikge1xuICAgIHJldHVybiB0YXJnZXROb2RlICYmIChzY2FuRm9yKG5vZGUsIG9mZiwgdGFyZ2V0Tm9kZSwgdGFyZ2V0T2ZmLCAtMSkgfHxcbiAgICAgICAgc2NhbkZvcihub2RlLCBvZmYsIHRhcmdldE5vZGUsIHRhcmdldE9mZiwgMSkpO1xufTtcbmNvbnN0IGF0b21FbGVtZW50cyA9IC9eKGltZ3xicnxpbnB1dHx0ZXh0YXJlYXxocikkL2k7XG5mdW5jdGlvbiBzY2FuRm9yKG5vZGUsIG9mZiwgdGFyZ2V0Tm9kZSwgdGFyZ2V0T2ZmLCBkaXIpIHtcbiAgICB2YXIgX2E7XG4gICAgZm9yICg7Oykge1xuICAgICAgICBpZiAobm9kZSA9PSB0YXJnZXROb2RlICYmIG9mZiA9PSB0YXJnZXRPZmYpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgaWYgKG9mZiA9PSAoZGlyIDwgMCA/IDAgOiBub2RlU2l6ZShub2RlKSkpIHtcbiAgICAgICAgICAgIGxldCBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgICAgICAgICBpZiAoIXBhcmVudCB8fCBwYXJlbnQubm9kZVR5cGUgIT0gMSB8fCBoYXNCbG9ja0Rlc2Mobm9kZSkgfHwgYXRvbUVsZW1lbnRzLnRlc3Qobm9kZS5ub2RlTmFtZSkgfHxcbiAgICAgICAgICAgICAgICBub2RlLmNvbnRlbnRFZGl0YWJsZSA9PSBcImZhbHNlXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgb2ZmID0gZG9tSW5kZXgobm9kZSkgKyAoZGlyIDwgMCA/IDAgOiAxKTtcbiAgICAgICAgICAgIG5vZGUgPSBwYXJlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobm9kZS5ub2RlVHlwZSA9PSAxKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGQgPSBub2RlLmNoaWxkTm9kZXNbb2ZmICsgKGRpciA8IDAgPyAtMSA6IDApXTtcbiAgICAgICAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PSAxICYmIGNoaWxkLmNvbnRlbnRFZGl0YWJsZSA9PSBcImZhbHNlXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoKF9hID0gY2hpbGQucG1WaWV3RGVzYykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLmlnbm9yZUZvclNlbGVjdGlvbilcbiAgICAgICAgICAgICAgICAgICAgb2ZmICs9IGRpcjtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBjaGlsZDtcbiAgICAgICAgICAgICAgICBvZmYgPSBkaXIgPCAwID8gbm9kZVNpemUobm9kZSkgOiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gbm9kZVNpemUobm9kZSkge1xuICAgIHJldHVybiBub2RlLm5vZGVUeXBlID09IDMgPyBub2RlLm5vZGVWYWx1ZS5sZW5ndGggOiBub2RlLmNoaWxkTm9kZXMubGVuZ3RoO1xufVxuZnVuY3Rpb24gdGV4dE5vZGVCZWZvcmUkMShub2RlLCBvZmZzZXQpIHtcbiAgICBmb3IgKDs7KSB7XG4gICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDMgJiYgb2Zmc2V0KVxuICAgICAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDEgJiYgb2Zmc2V0ID4gMCkge1xuICAgICAgICAgICAgaWYgKG5vZGUuY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0IC0gMV07XG4gICAgICAgICAgICBvZmZzZXQgPSBub2RlU2l6ZShub2RlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChub2RlLnBhcmVudE5vZGUgJiYgIWhhc0Jsb2NrRGVzYyhub2RlKSkge1xuICAgICAgICAgICAgb2Zmc2V0ID0gZG9tSW5kZXgobm9kZSk7XG4gICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiB0ZXh0Tm9kZUFmdGVyJDEobm9kZSwgb2Zmc2V0KSB7XG4gICAgZm9yICg7Oykge1xuICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSAzICYmIG9mZnNldCA8IG5vZGUubm9kZVZhbHVlLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSAxICYmIG9mZnNldCA8IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChub2RlLmNvbnRlbnRFZGl0YWJsZSA9PSBcImZhbHNlXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICBub2RlID0gbm9kZS5jaGlsZE5vZGVzW29mZnNldF07XG4gICAgICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG5vZGUucGFyZW50Tm9kZSAmJiAhaGFzQmxvY2tEZXNjKG5vZGUpKSB7XG4gICAgICAgICAgICBvZmZzZXQgPSBkb21JbmRleChub2RlKSArIDE7XG4gICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBpc09uRWRnZShub2RlLCBvZmZzZXQsIHBhcmVudCkge1xuICAgIGZvciAobGV0IGF0U3RhcnQgPSBvZmZzZXQgPT0gMCwgYXRFbmQgPSBvZmZzZXQgPT0gbm9kZVNpemUobm9kZSk7IGF0U3RhcnQgfHwgYXRFbmQ7KSB7XG4gICAgICAgIGlmIChub2RlID09IHBhcmVudClcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBsZXQgaW5kZXggPSBkb21JbmRleChub2RlKTtcbiAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgaWYgKCFub2RlKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBhdFN0YXJ0ID0gYXRTdGFydCAmJiBpbmRleCA9PSAwO1xuICAgICAgICBhdEVuZCA9IGF0RW5kICYmIGluZGV4ID09IG5vZGVTaXplKG5vZGUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGhhc0Jsb2NrRGVzYyhkb20pIHtcbiAgICBsZXQgZGVzYztcbiAgICBmb3IgKGxldCBjdXIgPSBkb207IGN1cjsgY3VyID0gY3VyLnBhcmVudE5vZGUpXG4gICAgICAgIGlmIChkZXNjID0gY3VyLnBtVmlld0Rlc2MpXG4gICAgICAgICAgICBicmVhaztcbiAgICByZXR1cm4gZGVzYyAmJiBkZXNjLm5vZGUgJiYgZGVzYy5ub2RlLmlzQmxvY2sgJiYgKGRlc2MuZG9tID09IGRvbSB8fCBkZXNjLmNvbnRlbnRET00gPT0gZG9tKTtcbn1cbi8vIFdvcmsgYXJvdW5kIENocm9tZSBpc3N1ZSBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NDc1MjNcbi8vIChpc0NvbGxhcHNlZCBpbmFwcHJvcHJpYXRlbHkgcmV0dXJucyB0cnVlIGluIHNoYWRvdyBkb20pXG5jb25zdCBzZWxlY3Rpb25Db2xsYXBzZWQgPSBmdW5jdGlvbiAoZG9tU2VsKSB7XG4gICAgcmV0dXJuIGRvbVNlbC5mb2N1c05vZGUgJiYgaXNFcXVpdmFsZW50UG9zaXRpb24oZG9tU2VsLmZvY3VzTm9kZSwgZG9tU2VsLmZvY3VzT2Zmc2V0LCBkb21TZWwuYW5jaG9yTm9kZSwgZG9tU2VsLmFuY2hvck9mZnNldCk7XG59O1xuZnVuY3Rpb24ga2V5RXZlbnQoa2V5Q29kZSwga2V5KSB7XG4gICAgbGV0IGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJFdmVudFwiKTtcbiAgICBldmVudC5pbml0RXZlbnQoXCJrZXlkb3duXCIsIHRydWUsIHRydWUpO1xuICAgIGV2ZW50LmtleUNvZGUgPSBrZXlDb2RlO1xuICAgIGV2ZW50LmtleSA9IGV2ZW50LmNvZGUgPSBrZXk7XG4gICAgcmV0dXJuIGV2ZW50O1xufVxuZnVuY3Rpb24gZGVlcEFjdGl2ZUVsZW1lbnQoZG9jKSB7XG4gICAgbGV0IGVsdCA9IGRvYy5hY3RpdmVFbGVtZW50O1xuICAgIHdoaWxlIChlbHQgJiYgZWx0LnNoYWRvd1Jvb3QpXG4gICAgICAgIGVsdCA9IGVsdC5zaGFkb3dSb290LmFjdGl2ZUVsZW1lbnQ7XG4gICAgcmV0dXJuIGVsdDtcbn1cbmZ1bmN0aW9uIGNhcmV0RnJvbVBvaW50KGRvYywgeCwgeSkge1xuICAgIGlmIChkb2MuY2FyZXRQb3NpdGlvbkZyb21Qb2ludCkge1xuICAgICAgICB0cnkgeyAvLyBGaXJlZm94IHRocm93cyBmb3IgdGhpcyBjYWxsIGluIGhhcmQtdG8tcHJlZGljdCBjaXJjdW1zdGFuY2VzICgjOTk0KVxuICAgICAgICAgICAgbGV0IHBvcyA9IGRvYy5jYXJldFBvc2l0aW9uRnJvbVBvaW50KHgsIHkpO1xuICAgICAgICAgICAgLy8gQ2xpcCB0aGUgb2Zmc2V0LCBiZWNhdXNlIENocm9tZSB3aWxsIHJldHVybiBhIHRleHQgb2Zmc2V0XG4gICAgICAgICAgICAvLyBpbnRvIDxpbnB1dD4gbm9kZXMsIHdoaWNoIGNhbid0IGJlIHRyZWF0ZWQgYXMgYSByZWd1bGFyIERPTVxuICAgICAgICAgICAgLy8gb2Zmc2V0XG4gICAgICAgICAgICBpZiAocG9zKVxuICAgICAgICAgICAgICAgIHJldHVybiB7IG5vZGU6IHBvcy5vZmZzZXROb2RlLCBvZmZzZXQ6IE1hdGgubWluKG5vZGVTaXplKHBvcy5vZmZzZXROb2RlKSwgcG9zLm9mZnNldCkgfTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoXykgeyB9XG4gICAgfVxuICAgIGlmIChkb2MuY2FyZXRSYW5nZUZyb21Qb2ludCkge1xuICAgICAgICBsZXQgcmFuZ2UgPSBkb2MuY2FyZXRSYW5nZUZyb21Qb2ludCh4LCB5KTtcbiAgICAgICAgaWYgKHJhbmdlKVxuICAgICAgICAgICAgcmV0dXJuIHsgbm9kZTogcmFuZ2Uuc3RhcnRDb250YWluZXIsIG9mZnNldDogTWF0aC5taW4obm9kZVNpemUocmFuZ2Uuc3RhcnRDb250YWluZXIpLCByYW5nZS5zdGFydE9mZnNldCkgfTtcbiAgICB9XG59XG5cbmNvbnN0IG5hdiA9IHR5cGVvZiBuYXZpZ2F0b3IgIT0gXCJ1bmRlZmluZWRcIiA/IG5hdmlnYXRvciA6IG51bGw7XG5jb25zdCBkb2MgPSB0eXBlb2YgZG9jdW1lbnQgIT0gXCJ1bmRlZmluZWRcIiA/IGRvY3VtZW50IDogbnVsbDtcbmNvbnN0IGFnZW50ID0gKG5hdiAmJiBuYXYudXNlckFnZW50KSB8fCBcIlwiO1xuY29uc3QgaWVfZWRnZSA9IC9FZGdlXFwvKFxcZCspLy5leGVjKGFnZW50KTtcbmNvbnN0IGllX3VwdG8xMCA9IC9NU0lFIFxcZC8uZXhlYyhhZ2VudCk7XG5jb25zdCBpZV8xMXVwID0gL1RyaWRlbnRcXC8oPzpbNy05XXxcXGR7Mix9KVxcLi4qcnY6KFxcZCspLy5leGVjKGFnZW50KTtcbmNvbnN0IGllID0gISEoaWVfdXB0bzEwIHx8IGllXzExdXAgfHwgaWVfZWRnZSk7XG5jb25zdCBpZV92ZXJzaW9uID0gaWVfdXB0bzEwID8gZG9jdW1lbnQuZG9jdW1lbnRNb2RlIDogaWVfMTF1cCA/ICtpZV8xMXVwWzFdIDogaWVfZWRnZSA/ICtpZV9lZGdlWzFdIDogMDtcbmNvbnN0IGdlY2tvID0gIWllICYmIC9nZWNrb1xcLyhcXGQrKS9pLnRlc3QoYWdlbnQpO1xuZ2Vja28gJiYgKygvRmlyZWZveFxcLyhcXGQrKS8uZXhlYyhhZ2VudCkgfHwgWzAsIDBdKVsxXTtcbmNvbnN0IF9jaHJvbWUgPSAhaWUgJiYgL0Nocm9tZVxcLyhcXGQrKS8uZXhlYyhhZ2VudCk7XG5jb25zdCBjaHJvbWUgPSAhIV9jaHJvbWU7XG5jb25zdCBjaHJvbWVfdmVyc2lvbiA9IF9jaHJvbWUgPyArX2Nocm9tZVsxXSA6IDA7XG5jb25zdCBzYWZhcmkgPSAhaWUgJiYgISFuYXYgJiYgL0FwcGxlIENvbXB1dGVyLy50ZXN0KG5hdi52ZW5kb3IpO1xuLy8gSXMgdHJ1ZSBmb3IgYm90aCBpT1MgYW5kIGlQYWRPUyBmb3IgY29udmVuaWVuY2VcbmNvbnN0IGlvcyA9IHNhZmFyaSAmJiAoL01vYmlsZVxcL1xcdysvLnRlc3QoYWdlbnQpIHx8ICEhbmF2ICYmIG5hdi5tYXhUb3VjaFBvaW50cyA+IDIpO1xuY29uc3QgbWFjID0gaW9zIHx8IChuYXYgPyAvTWFjLy50ZXN0KG5hdi5wbGF0Zm9ybSkgOiBmYWxzZSk7XG5jb25zdCB3aW5kb3dzID0gbmF2ID8gL1dpbi8udGVzdChuYXYucGxhdGZvcm0pIDogZmFsc2U7XG5jb25zdCBhbmRyb2lkID0gL0FuZHJvaWQgXFxkLy50ZXN0KGFnZW50KTtcbmNvbnN0IHdlYmtpdCA9ICEhZG9jICYmIFwid2Via2l0Rm9udFNtb290aGluZ1wiIGluIGRvYy5kb2N1bWVudEVsZW1lbnQuc3R5bGU7XG5jb25zdCB3ZWJraXRfdmVyc2lvbiA9IHdlYmtpdCA/ICsoL1xcYkFwcGxlV2ViS2l0XFwvKFxcZCspLy5leGVjKG5hdmlnYXRvci51c2VyQWdlbnQpIHx8IFswLCAwXSlbMV0gOiAwO1xuXG5mdW5jdGlvbiB3aW5kb3dSZWN0KGRvYykge1xuICAgIGxldCB2cCA9IGRvYy5kZWZhdWx0VmlldyAmJiBkb2MuZGVmYXVsdFZpZXcudmlzdWFsVmlld3BvcnQ7XG4gICAgaWYgKHZwKVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGVmdDogMCwgcmlnaHQ6IHZwLndpZHRoLFxuICAgICAgICAgICAgdG9wOiAwLCBib3R0b206IHZwLmhlaWdodFxuICAgICAgICB9O1xuICAgIHJldHVybiB7IGxlZnQ6IDAsIHJpZ2h0OiBkb2MuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoLFxuICAgICAgICB0b3A6IDAsIGJvdHRvbTogZG9jLmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQgfTtcbn1cbmZ1bmN0aW9uIGdldFNpZGUodmFsdWUsIHNpZGUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09IFwibnVtYmVyXCIgPyB2YWx1ZSA6IHZhbHVlW3NpZGVdO1xufVxuZnVuY3Rpb24gY2xpZW50UmVjdChub2RlKSB7XG4gICAgbGV0IHJlY3QgPSBub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIC8vIEFkanVzdCBmb3IgZWxlbWVudHMgd2l0aCBzdHlsZSBcInRyYW5zZm9ybTogc2NhbGUoKVwiXG4gICAgbGV0IHNjYWxlWCA9IChyZWN0LndpZHRoIC8gbm9kZS5vZmZzZXRXaWR0aCkgfHwgMTtcbiAgICBsZXQgc2NhbGVZID0gKHJlY3QuaGVpZ2h0IC8gbm9kZS5vZmZzZXRIZWlnaHQpIHx8IDE7XG4gICAgLy8gTWFrZSBzdXJlIHNjcm9sbGJhciB3aWR0aCBpc24ndCBpbmNsdWRlZCBpbiB0aGUgcmVjdGFuZ2xlXG4gICAgcmV0dXJuIHsgbGVmdDogcmVjdC5sZWZ0LCByaWdodDogcmVjdC5sZWZ0ICsgbm9kZS5jbGllbnRXaWR0aCAqIHNjYWxlWCxcbiAgICAgICAgdG9wOiByZWN0LnRvcCwgYm90dG9tOiByZWN0LnRvcCArIG5vZGUuY2xpZW50SGVpZ2h0ICogc2NhbGVZIH07XG59XG5mdW5jdGlvbiBzY3JvbGxSZWN0SW50b1ZpZXcodmlldywgcmVjdCwgc3RhcnRET00pIHtcbiAgICBsZXQgc2Nyb2xsVGhyZXNob2xkID0gdmlldy5zb21lUHJvcChcInNjcm9sbFRocmVzaG9sZFwiKSB8fCAwLCBzY3JvbGxNYXJnaW4gPSB2aWV3LnNvbWVQcm9wKFwic2Nyb2xsTWFyZ2luXCIpIHx8IDU7XG4gICAgbGV0IGRvYyA9IHZpZXcuZG9tLm93bmVyRG9jdW1lbnQ7XG4gICAgZm9yIChsZXQgcGFyZW50ID0gc3RhcnRET00gfHwgdmlldy5kb207Oykge1xuICAgICAgICBpZiAoIXBhcmVudClcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBpZiAocGFyZW50Lm5vZGVUeXBlICE9IDEpIHtcbiAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudE5vZGUocGFyZW50KTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGxldCBlbHQgPSBwYXJlbnQ7XG4gICAgICAgIGxldCBhdFRvcCA9IGVsdCA9PSBkb2MuYm9keTtcbiAgICAgICAgbGV0IGJvdW5kaW5nID0gYXRUb3AgPyB3aW5kb3dSZWN0KGRvYykgOiBjbGllbnRSZWN0KGVsdCk7XG4gICAgICAgIGxldCBtb3ZlWCA9IDAsIG1vdmVZID0gMDtcbiAgICAgICAgaWYgKHJlY3QudG9wIDwgYm91bmRpbmcudG9wICsgZ2V0U2lkZShzY3JvbGxUaHJlc2hvbGQsIFwidG9wXCIpKVxuICAgICAgICAgICAgbW92ZVkgPSAtKGJvdW5kaW5nLnRvcCAtIHJlY3QudG9wICsgZ2V0U2lkZShzY3JvbGxNYXJnaW4sIFwidG9wXCIpKTtcbiAgICAgICAgZWxzZSBpZiAocmVjdC5ib3R0b20gPiBib3VuZGluZy5ib3R0b20gLSBnZXRTaWRlKHNjcm9sbFRocmVzaG9sZCwgXCJib3R0b21cIikpXG4gICAgICAgICAgICBtb3ZlWSA9IHJlY3QuYm90dG9tIC0gcmVjdC50b3AgPiBib3VuZGluZy5ib3R0b20gLSBib3VuZGluZy50b3BcbiAgICAgICAgICAgICAgICA/IHJlY3QudG9wICsgZ2V0U2lkZShzY3JvbGxNYXJnaW4sIFwidG9wXCIpIC0gYm91bmRpbmcudG9wXG4gICAgICAgICAgICAgICAgOiByZWN0LmJvdHRvbSAtIGJvdW5kaW5nLmJvdHRvbSArIGdldFNpZGUoc2Nyb2xsTWFyZ2luLCBcImJvdHRvbVwiKTtcbiAgICAgICAgaWYgKHJlY3QubGVmdCA8IGJvdW5kaW5nLmxlZnQgKyBnZXRTaWRlKHNjcm9sbFRocmVzaG9sZCwgXCJsZWZ0XCIpKVxuICAgICAgICAgICAgbW92ZVggPSAtKGJvdW5kaW5nLmxlZnQgLSByZWN0LmxlZnQgKyBnZXRTaWRlKHNjcm9sbE1hcmdpbiwgXCJsZWZ0XCIpKTtcbiAgICAgICAgZWxzZSBpZiAocmVjdC5yaWdodCA+IGJvdW5kaW5nLnJpZ2h0IC0gZ2V0U2lkZShzY3JvbGxUaHJlc2hvbGQsIFwicmlnaHRcIikpXG4gICAgICAgICAgICBtb3ZlWCA9IHJlY3QucmlnaHQgLSBib3VuZGluZy5yaWdodCArIGdldFNpZGUoc2Nyb2xsTWFyZ2luLCBcInJpZ2h0XCIpO1xuICAgICAgICBpZiAobW92ZVggfHwgbW92ZVkpIHtcbiAgICAgICAgICAgIGlmIChhdFRvcCkge1xuICAgICAgICAgICAgICAgIGRvYy5kZWZhdWx0Vmlldy5zY3JvbGxCeShtb3ZlWCwgbW92ZVkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0YXJ0WCA9IGVsdC5zY3JvbGxMZWZ0LCBzdGFydFkgPSBlbHQuc2Nyb2xsVG9wO1xuICAgICAgICAgICAgICAgIGlmIChtb3ZlWSlcbiAgICAgICAgICAgICAgICAgICAgZWx0LnNjcm9sbFRvcCArPSBtb3ZlWTtcbiAgICAgICAgICAgICAgICBpZiAobW92ZVgpXG4gICAgICAgICAgICAgICAgICAgIGVsdC5zY3JvbGxMZWZ0ICs9IG1vdmVYO1xuICAgICAgICAgICAgICAgIGxldCBkWCA9IGVsdC5zY3JvbGxMZWZ0IC0gc3RhcnRYLCBkWSA9IGVsdC5zY3JvbGxUb3AgLSBzdGFydFk7XG4gICAgICAgICAgICAgICAgcmVjdCA9IHsgbGVmdDogcmVjdC5sZWZ0IC0gZFgsIHRvcDogcmVjdC50b3AgLSBkWSwgcmlnaHQ6IHJlY3QucmlnaHQgLSBkWCwgYm90dG9tOiByZWN0LmJvdHRvbSAtIGRZIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHBvcyA9IGF0VG9wID8gXCJmaXhlZFwiIDogZ2V0Q29tcHV0ZWRTdHlsZShwYXJlbnQpLnBvc2l0aW9uO1xuICAgICAgICBpZiAoL14oZml4ZWR8c3RpY2t5KSQvLnRlc3QocG9zKSlcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBwYXJlbnQgPSBwb3MgPT0gXCJhYnNvbHV0ZVwiID8gcGFyZW50Lm9mZnNldFBhcmVudCA6IHBhcmVudE5vZGUocGFyZW50KTtcbiAgICB9XG59XG4vLyBTdG9yZSB0aGUgc2Nyb2xsIHBvc2l0aW9uIG9mIHRoZSBlZGl0b3IncyBwYXJlbnQgbm9kZXMsIGFsb25nIHdpdGhcbi8vIHRoZSB0b3AgcG9zaXRpb24gb2YgYW4gZWxlbWVudCBuZWFyIHRoZSB0b3Agb2YgdGhlIGVkaXRvciwgd2hpY2hcbi8vIHdpbGwgYmUgdXNlZCB0byBtYWtlIHN1cmUgdGhlIHZpc2libGUgdmlld3BvcnQgcmVtYWlucyBzdGFibGUgZXZlblxuLy8gd2hlbiB0aGUgc2l6ZSBvZiB0aGUgY29udGVudCBhYm92ZSBjaGFuZ2VzLlxuZnVuY3Rpb24gc3RvcmVTY3JvbGxQb3Modmlldykge1xuICAgIGxldCByZWN0ID0gdmlldy5kb20uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIHN0YXJ0WSA9IE1hdGgubWF4KDAsIHJlY3QudG9wKTtcbiAgICBsZXQgcmVmRE9NLCByZWZUb3A7XG4gICAgZm9yIChsZXQgeCA9IChyZWN0LmxlZnQgKyByZWN0LnJpZ2h0KSAvIDIsIHkgPSBzdGFydFkgKyAxOyB5IDwgTWF0aC5taW4oaW5uZXJIZWlnaHQsIHJlY3QuYm90dG9tKTsgeSArPSA1KSB7XG4gICAgICAgIGxldCBkb20gPSB2aWV3LnJvb3QuZWxlbWVudEZyb21Qb2ludCh4LCB5KTtcbiAgICAgICAgaWYgKCFkb20gfHwgZG9tID09IHZpZXcuZG9tIHx8ICF2aWV3LmRvbS5jb250YWlucyhkb20pKVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGxldCBsb2NhbFJlY3QgPSBkb20uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGlmIChsb2NhbFJlY3QudG9wID49IHN0YXJ0WSAtIDIwKSB7XG4gICAgICAgICAgICByZWZET00gPSBkb207XG4gICAgICAgICAgICByZWZUb3AgPSBsb2NhbFJlY3QudG9wO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgcmVmRE9NOiByZWZET00sIHJlZlRvcDogcmVmVG9wLCBzdGFjazogc2Nyb2xsU3RhY2sodmlldy5kb20pIH07XG59XG5mdW5jdGlvbiBzY3JvbGxTdGFjayhkb20pIHtcbiAgICBsZXQgc3RhY2sgPSBbXSwgZG9jID0gZG9tLm93bmVyRG9jdW1lbnQ7XG4gICAgZm9yIChsZXQgY3VyID0gZG9tOyBjdXI7IGN1ciA9IHBhcmVudE5vZGUoY3VyKSkge1xuICAgICAgICBzdGFjay5wdXNoKHsgZG9tOiBjdXIsIHRvcDogY3VyLnNjcm9sbFRvcCwgbGVmdDogY3VyLnNjcm9sbExlZnQgfSk7XG4gICAgICAgIGlmIChkb20gPT0gZG9jKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBzdGFjaztcbn1cbi8vIFJlc2V0IHRoZSBzY3JvbGwgcG9zaXRpb24gb2YgdGhlIGVkaXRvcidzIHBhcmVudCBub2RlcyB0byB0aGF0IHdoYXRcbi8vIGl0IHdhcyBiZWZvcmUsIHdoZW4gc3RvcmVTY3JvbGxQb3Mgd2FzIGNhbGxlZC5cbmZ1bmN0aW9uIHJlc2V0U2Nyb2xsUG9zKHsgcmVmRE9NLCByZWZUb3AsIHN0YWNrIH0pIHtcbiAgICBsZXQgbmV3UmVmVG9wID0gcmVmRE9NID8gcmVmRE9NLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCA6IDA7XG4gICAgcmVzdG9yZVNjcm9sbFN0YWNrKHN0YWNrLCBuZXdSZWZUb3AgPT0gMCA/IDAgOiBuZXdSZWZUb3AgLSByZWZUb3ApO1xufVxuZnVuY3Rpb24gcmVzdG9yZVNjcm9sbFN0YWNrKHN0YWNrLCBkVG9wKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdGFjay5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgeyBkb20sIHRvcCwgbGVmdCB9ID0gc3RhY2tbaV07XG4gICAgICAgIGlmIChkb20uc2Nyb2xsVG9wICE9IHRvcCArIGRUb3ApXG4gICAgICAgICAgICBkb20uc2Nyb2xsVG9wID0gdG9wICsgZFRvcDtcbiAgICAgICAgaWYgKGRvbS5zY3JvbGxMZWZ0ICE9IGxlZnQpXG4gICAgICAgICAgICBkb20uc2Nyb2xsTGVmdCA9IGxlZnQ7XG4gICAgfVxufVxubGV0IHByZXZlbnRTY3JvbGxTdXBwb3J0ZWQgPSBudWxsO1xuLy8gRmVhdHVyZS1kZXRlY3RzIHN1cHBvcnQgZm9yIC5mb2N1cyh7cHJldmVudFNjcm9sbDogdHJ1ZX0pLCBhbmQgdXNlc1xuLy8gYSBmYWxsYmFjayBrbHVkZ2Ugd2hlbiBub3Qgc3VwcG9ydGVkLlxuZnVuY3Rpb24gZm9jdXNQcmV2ZW50U2Nyb2xsKGRvbSkge1xuICAgIGlmIChkb20uc2V0QWN0aXZlKVxuICAgICAgICByZXR1cm4gZG9tLnNldEFjdGl2ZSgpOyAvLyBpbiBJRVxuICAgIGlmIChwcmV2ZW50U2Nyb2xsU3VwcG9ydGVkKVxuICAgICAgICByZXR1cm4gZG9tLmZvY3VzKHByZXZlbnRTY3JvbGxTdXBwb3J0ZWQpO1xuICAgIGxldCBzdG9yZWQgPSBzY3JvbGxTdGFjayhkb20pO1xuICAgIGRvbS5mb2N1cyhwcmV2ZW50U2Nyb2xsU3VwcG9ydGVkID09IG51bGwgPyB7XG4gICAgICAgIGdldCBwcmV2ZW50U2Nyb2xsKCkge1xuICAgICAgICAgICAgcHJldmVudFNjcm9sbFN1cHBvcnRlZCA9IHsgcHJldmVudFNjcm9sbDogdHJ1ZSB9O1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9IDogdW5kZWZpbmVkKTtcbiAgICBpZiAoIXByZXZlbnRTY3JvbGxTdXBwb3J0ZWQpIHtcbiAgICAgICAgcHJldmVudFNjcm9sbFN1cHBvcnRlZCA9IGZhbHNlO1xuICAgICAgICByZXN0b3JlU2Nyb2xsU3RhY2soc3RvcmVkLCAwKTtcbiAgICB9XG59XG5mdW5jdGlvbiBmaW5kT2Zmc2V0SW5Ob2RlKG5vZGUsIGNvb3Jkcykge1xuICAgIGxldCBjbG9zZXN0LCBkeENsb3Nlc3QgPSAyZTgsIGNvb3Jkc0Nsb3Nlc3QsIG9mZnNldCA9IDA7XG4gICAgbGV0IHJvd0JvdCA9IGNvb3Jkcy50b3AsIHJvd1RvcCA9IGNvb3Jkcy50b3A7XG4gICAgbGV0IGZpcnN0QmVsb3csIGNvb3Jkc0JlbG93O1xuICAgIGZvciAobGV0IGNoaWxkID0gbm9kZS5maXJzdENoaWxkLCBjaGlsZEluZGV4ID0gMDsgY2hpbGQ7IGNoaWxkID0gY2hpbGQubmV4dFNpYmxpbmcsIGNoaWxkSW5kZXgrKykge1xuICAgICAgICBsZXQgcmVjdHM7XG4gICAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PSAxKVxuICAgICAgICAgICAgcmVjdHMgPSBjaGlsZC5nZXRDbGllbnRSZWN0cygpO1xuICAgICAgICBlbHNlIGlmIChjaGlsZC5ub2RlVHlwZSA9PSAzKVxuICAgICAgICAgICAgcmVjdHMgPSB0ZXh0UmFuZ2UoY2hpbGQpLmdldENsaWVudFJlY3RzKCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgcmVjdCA9IHJlY3RzW2ldO1xuICAgICAgICAgICAgaWYgKHJlY3QudG9wIDw9IHJvd0JvdCAmJiByZWN0LmJvdHRvbSA+PSByb3dUb3ApIHtcbiAgICAgICAgICAgICAgICByb3dCb3QgPSBNYXRoLm1heChyZWN0LmJvdHRvbSwgcm93Qm90KTtcbiAgICAgICAgICAgICAgICByb3dUb3AgPSBNYXRoLm1pbihyZWN0LnRvcCwgcm93VG9wKTtcbiAgICAgICAgICAgICAgICBsZXQgZHggPSByZWN0LmxlZnQgPiBjb29yZHMubGVmdCA/IHJlY3QubGVmdCAtIGNvb3Jkcy5sZWZ0XG4gICAgICAgICAgICAgICAgICAgIDogcmVjdC5yaWdodCA8IGNvb3Jkcy5sZWZ0ID8gY29vcmRzLmxlZnQgLSByZWN0LnJpZ2h0IDogMDtcbiAgICAgICAgICAgICAgICBpZiAoZHggPCBkeENsb3Nlc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgY2xvc2VzdCA9IGNoaWxkO1xuICAgICAgICAgICAgICAgICAgICBkeENsb3Nlc3QgPSBkeDtcbiAgICAgICAgICAgICAgICAgICAgY29vcmRzQ2xvc2VzdCA9IGR4ICYmIGNsb3Nlc3Qubm9kZVR5cGUgPT0gMyA/IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQ6IHJlY3QucmlnaHQgPCBjb29yZHMubGVmdCA/IHJlY3QucmlnaHQgOiByZWN0LmxlZnQsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IGNvb3Jkcy50b3BcbiAgICAgICAgICAgICAgICAgICAgfSA6IGNvb3JkcztcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09IDEgJiYgZHgpXG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSBjaGlsZEluZGV4ICsgKGNvb3Jkcy5sZWZ0ID49IChyZWN0LmxlZnQgKyByZWN0LnJpZ2h0KSAvIDIgPyAxIDogMCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHJlY3QudG9wID4gY29vcmRzLnRvcCAmJiAhZmlyc3RCZWxvdyAmJiByZWN0LmxlZnQgPD0gY29vcmRzLmxlZnQgJiYgcmVjdC5yaWdodCA+PSBjb29yZHMubGVmdCkge1xuICAgICAgICAgICAgICAgIGZpcnN0QmVsb3cgPSBjaGlsZDtcbiAgICAgICAgICAgICAgICBjb29yZHNCZWxvdyA9IHsgbGVmdDogTWF0aC5tYXgocmVjdC5sZWZ0LCBNYXRoLm1pbihyZWN0LnJpZ2h0LCBjb29yZHMubGVmdCkpLCB0b3A6IHJlY3QudG9wIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWNsb3Nlc3QgJiYgKGNvb3Jkcy5sZWZ0ID49IHJlY3QucmlnaHQgJiYgY29vcmRzLnRvcCA+PSByZWN0LnRvcCB8fFxuICAgICAgICAgICAgICAgIGNvb3Jkcy5sZWZ0ID49IHJlY3QubGVmdCAmJiBjb29yZHMudG9wID49IHJlY3QuYm90dG9tKSlcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSBjaGlsZEluZGV4ICsgMTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWNsb3Nlc3QgJiYgZmlyc3RCZWxvdykge1xuICAgICAgICBjbG9zZXN0ID0gZmlyc3RCZWxvdztcbiAgICAgICAgY29vcmRzQ2xvc2VzdCA9IGNvb3Jkc0JlbG93O1xuICAgICAgICBkeENsb3Nlc3QgPSAwO1xuICAgIH1cbiAgICBpZiAoY2xvc2VzdCAmJiBjbG9zZXN0Lm5vZGVUeXBlID09IDMpXG4gICAgICAgIHJldHVybiBmaW5kT2Zmc2V0SW5UZXh0KGNsb3Nlc3QsIGNvb3Jkc0Nsb3Nlc3QpO1xuICAgIGlmICghY2xvc2VzdCB8fCAoZHhDbG9zZXN0ICYmIGNsb3Nlc3Qubm9kZVR5cGUgPT0gMSkpXG4gICAgICAgIHJldHVybiB7IG5vZGUsIG9mZnNldCB9O1xuICAgIHJldHVybiBmaW5kT2Zmc2V0SW5Ob2RlKGNsb3Nlc3QsIGNvb3Jkc0Nsb3Nlc3QpO1xufVxuZnVuY3Rpb24gZmluZE9mZnNldEluVGV4dChub2RlLCBjb29yZHMpIHtcbiAgICBsZXQgbGVuID0gbm9kZS5ub2RlVmFsdWUubGVuZ3RoO1xuICAgIGxldCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCksIHJlc3VsdDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIHJhbmdlLnNldEVuZChub2RlLCBpICsgMSk7XG4gICAgICAgIHJhbmdlLnNldFN0YXJ0KG5vZGUsIGkpO1xuICAgICAgICBsZXQgcmVjdCA9IHNpbmdsZVJlY3QocmFuZ2UsIDEpO1xuICAgICAgICBpZiAocmVjdC50b3AgPT0gcmVjdC5ib3R0b20pXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgaWYgKGluUmVjdChjb29yZHMsIHJlY3QpKSB7XG4gICAgICAgICAgICByZXN1bHQgPSB7IG5vZGUsIG9mZnNldDogaSArIChjb29yZHMubGVmdCA+PSAocmVjdC5sZWZ0ICsgcmVjdC5yaWdodCkgLyAyID8gMSA6IDApIH07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICByYW5nZS5kZXRhY2goKTtcbiAgICByZXR1cm4gcmVzdWx0IHx8IHsgbm9kZSwgb2Zmc2V0OiAwIH07XG59XG5mdW5jdGlvbiBpblJlY3QoY29vcmRzLCByZWN0KSB7XG4gICAgcmV0dXJuIGNvb3Jkcy5sZWZ0ID49IHJlY3QubGVmdCAtIDEgJiYgY29vcmRzLmxlZnQgPD0gcmVjdC5yaWdodCArIDEgJiZcbiAgICAgICAgY29vcmRzLnRvcCA+PSByZWN0LnRvcCAtIDEgJiYgY29vcmRzLnRvcCA8PSByZWN0LmJvdHRvbSArIDE7XG59XG5mdW5jdGlvbiB0YXJnZXRLbHVkZ2UoZG9tLCBjb29yZHMpIHtcbiAgICBsZXQgcGFyZW50ID0gZG9tLnBhcmVudE5vZGU7XG4gICAgaWYgKHBhcmVudCAmJiAvXmxpJC9pLnRlc3QocGFyZW50Lm5vZGVOYW1lKSAmJiBjb29yZHMubGVmdCA8IGRvbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0KVxuICAgICAgICByZXR1cm4gcGFyZW50O1xuICAgIHJldHVybiBkb207XG59XG5mdW5jdGlvbiBwb3NGcm9tRWxlbWVudCh2aWV3LCBlbHQsIGNvb3Jkcykge1xuICAgIGxldCB7IG5vZGUsIG9mZnNldCB9ID0gZmluZE9mZnNldEluTm9kZShlbHQsIGNvb3JkcyksIGJpYXMgPSAtMTtcbiAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSAxICYmICFub2RlLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgbGV0IHJlY3QgPSBub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBiaWFzID0gcmVjdC5sZWZ0ICE9IHJlY3QucmlnaHQgJiYgY29vcmRzLmxlZnQgPiAocmVjdC5sZWZ0ICsgcmVjdC5yaWdodCkgLyAyID8gMSA6IC0xO1xuICAgIH1cbiAgICByZXR1cm4gdmlldy5kb2NWaWV3LnBvc0Zyb21ET00obm9kZSwgb2Zmc2V0LCBiaWFzKTtcbn1cbmZ1bmN0aW9uIHBvc0Zyb21DYXJldCh2aWV3LCBub2RlLCBvZmZzZXQsIGNvb3Jkcykge1xuICAgIC8vIEJyb3dzZXIgKGluIGNhcmV0UG9zaXRpb24vUmFuZ2VGcm9tUG9pbnQpIHdpbGwgYWdyZXNzaXZlbHlcbiAgICAvLyBub3JtYWxpemUgdG93YXJkcyBuZWFyYnkgaW5saW5lIG5vZGVzLiBTaW5jZSB3ZSBhcmUgaW50ZXJlc3RlZCBpblxuICAgIC8vIHBvc2l0aW9ucyBiZXR3ZWVuIGJsb2NrIG5vZGVzIHRvbywgd2UgZmlyc3Qgd2FsayB1cCB0aGUgaGllcmFyY2h5XG4gICAgLy8gb2Ygbm9kZXMgdG8gc2VlIGlmIHRoZXJlIGFyZSBibG9jayBub2RlcyB0aGF0IHRoZSBjb29yZGluYXRlc1xuICAgIC8vIGZhbGwgb3V0c2lkZSBvZi4gSWYgc28sIHdlIHRha2UgdGhlIHBvc2l0aW9uIGJlZm9yZS9hZnRlciB0aGF0XG4gICAgLy8gYmxvY2suIElmIG5vdCwgd2UgY2FsbCBgcG9zRnJvbURPTWAgb24gdGhlIHJhdyBub2RlL29mZnNldC5cbiAgICBsZXQgb3V0c2lkZUJsb2NrID0gLTE7XG4gICAgZm9yIChsZXQgY3VyID0gbm9kZSwgc2F3QmxvY2sgPSBmYWxzZTs7KSB7XG4gICAgICAgIGlmIChjdXIgPT0gdmlldy5kb20pXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgbGV0IGRlc2MgPSB2aWV3LmRvY1ZpZXcubmVhcmVzdERlc2MoY3VyLCB0cnVlKSwgcmVjdDtcbiAgICAgICAgaWYgKCFkZXNjKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGlmIChkZXNjLmRvbS5ub2RlVHlwZSA9PSAxICYmIChkZXNjLm5vZGUuaXNCbG9jayAmJiBkZXNjLnBhcmVudCB8fCAhZGVzYy5jb250ZW50RE9NKSAmJlxuICAgICAgICAgICAgLy8gSWdub3JlIGVsZW1lbnRzIHdpdGggemVyby1zaXplIGJvdW5kaW5nIHJlY3RhbmdsZXNcbiAgICAgICAgICAgICgocmVjdCA9IGRlc2MuZG9tLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKS53aWR0aCB8fCByZWN0LmhlaWdodCkpIHtcbiAgICAgICAgICAgIGlmIChkZXNjLm5vZGUuaXNCbG9jayAmJiBkZXNjLnBhcmVudCAmJiAhL15UKFJ8Qk9EWXxIRUFEfEZPT1QpJC8udGVzdChkZXNjLmRvbS5ub2RlTmFtZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBPbmx5IGFwcGx5IHRoZSBob3Jpem9udGFsIHRlc3QgdG8gdGhlIGlubmVybW9zdCBibG9jay4gVmVydGljYWwgZm9yIGFueSBwYXJlbnQuXG4gICAgICAgICAgICAgICAgaWYgKCFzYXdCbG9jayAmJiByZWN0LmxlZnQgPiBjb29yZHMubGVmdCB8fCByZWN0LnRvcCA+IGNvb3Jkcy50b3ApXG4gICAgICAgICAgICAgICAgICAgIG91dHNpZGVCbG9jayA9IGRlc2MucG9zQmVmb3JlO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzYXdCbG9jayAmJiByZWN0LnJpZ2h0IDwgY29vcmRzLmxlZnQgfHwgcmVjdC5ib3R0b20gPCBjb29yZHMudG9wKVxuICAgICAgICAgICAgICAgICAgICBvdXRzaWRlQmxvY2sgPSBkZXNjLnBvc0FmdGVyO1xuICAgICAgICAgICAgICAgIHNhd0Jsb2NrID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghZGVzYy5jb250ZW50RE9NICYmIG91dHNpZGVCbG9jayA8IDAgJiYgIWRlc2Mubm9kZS5pc1RleHQpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB3ZSBhcmUgaW5zaWRlIGEgbGVhZiwgcmV0dXJuIHRoZSBzaWRlIG9mIHRoZSBsZWFmIGNsb3NlciB0byB0aGUgY29vcmRzXG4gICAgICAgICAgICAgICAgbGV0IGJlZm9yZSA9IGRlc2Mubm9kZS5pc0Jsb2NrID8gY29vcmRzLnRvcCA8IChyZWN0LnRvcCArIHJlY3QuYm90dG9tKSAvIDJcbiAgICAgICAgICAgICAgICAgICAgOiBjb29yZHMubGVmdCA8IChyZWN0LmxlZnQgKyByZWN0LnJpZ2h0KSAvIDI7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJlZm9yZSA/IGRlc2MucG9zQmVmb3JlIDogZGVzYy5wb3NBZnRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjdXIgPSBkZXNjLmRvbS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gb3V0c2lkZUJsb2NrID4gLTEgPyBvdXRzaWRlQmxvY2sgOiB2aWV3LmRvY1ZpZXcucG9zRnJvbURPTShub2RlLCBvZmZzZXQsIC0xKTtcbn1cbmZ1bmN0aW9uIGVsZW1lbnRGcm9tUG9pbnQoZWxlbWVudCwgY29vcmRzLCBib3gpIHtcbiAgICBsZXQgbGVuID0gZWxlbWVudC5jaGlsZE5vZGVzLmxlbmd0aDtcbiAgICBpZiAobGVuICYmIGJveC50b3AgPCBib3guYm90dG9tKSB7XG4gICAgICAgIGZvciAobGV0IHN0YXJ0SSA9IE1hdGgubWF4KDAsIE1hdGgubWluKGxlbiAtIDEsIE1hdGguZmxvb3IobGVuICogKGNvb3Jkcy50b3AgLSBib3gudG9wKSAvIChib3guYm90dG9tIC0gYm94LnRvcCkpIC0gMikpLCBpID0gc3RhcnRJOzspIHtcbiAgICAgICAgICAgIGxldCBjaGlsZCA9IGVsZW1lbnQuY2hpbGROb2Rlc1tpXTtcbiAgICAgICAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PSAxKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlY3RzID0gY2hpbGQuZ2V0Q2xpZW50UmVjdHMoKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZWN0ID0gcmVjdHNbal07XG4gICAgICAgICAgICAgICAgICAgIGlmIChpblJlY3QoY29vcmRzLCByZWN0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBlbGVtZW50RnJvbVBvaW50KGNoaWxkLCBjb29yZHMsIHJlY3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICgoaSA9IChpICsgMSkgJSBsZW4pID09IHN0YXJ0SSlcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZWxlbWVudDtcbn1cbi8vIEdpdmVuIGFuIHgseSBwb3NpdGlvbiBvbiB0aGUgZWRpdG9yLCBnZXQgdGhlIHBvc2l0aW9uIGluIHRoZSBkb2N1bWVudC5cbmZ1bmN0aW9uIHBvc0F0Q29vcmRzKHZpZXcsIGNvb3Jkcykge1xuICAgIGxldCBkb2MgPSB2aWV3LmRvbS5vd25lckRvY3VtZW50LCBub2RlLCBvZmZzZXQgPSAwO1xuICAgIGxldCBjYXJldCA9IGNhcmV0RnJvbVBvaW50KGRvYywgY29vcmRzLmxlZnQsIGNvb3Jkcy50b3ApO1xuICAgIGlmIChjYXJldClcbiAgICAgICAgKHsgbm9kZSwgb2Zmc2V0IH0gPSBjYXJldCk7XG4gICAgbGV0IGVsdCA9ICh2aWV3LnJvb3QuZWxlbWVudEZyb21Qb2ludCA/IHZpZXcucm9vdCA6IGRvYylcbiAgICAgICAgLmVsZW1lbnRGcm9tUG9pbnQoY29vcmRzLmxlZnQsIGNvb3Jkcy50b3ApO1xuICAgIGxldCBwb3M7XG4gICAgaWYgKCFlbHQgfHwgIXZpZXcuZG9tLmNvbnRhaW5zKGVsdC5ub2RlVHlwZSAhPSAxID8gZWx0LnBhcmVudE5vZGUgOiBlbHQpKSB7XG4gICAgICAgIGxldCBib3ggPSB2aWV3LmRvbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgaWYgKCFpblJlY3QoY29vcmRzLCBib3gpKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGVsdCA9IGVsZW1lbnRGcm9tUG9pbnQodmlldy5kb20sIGNvb3JkcywgYm94KTtcbiAgICAgICAgaWYgKCFlbHQpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gU2FmYXJpJ3MgY2FyZXRSYW5nZUZyb21Qb2ludCByZXR1cm5zIG5vbnNlbnNlIHdoZW4gb24gYSBkcmFnZ2FibGUgZWxlbWVudFxuICAgIGlmIChzYWZhcmkpIHtcbiAgICAgICAgZm9yIChsZXQgcCA9IGVsdDsgbm9kZSAmJiBwOyBwID0gcGFyZW50Tm9kZShwKSlcbiAgICAgICAgICAgIGlmIChwLmRyYWdnYWJsZSlcbiAgICAgICAgICAgICAgICBub2RlID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBlbHQgPSB0YXJnZXRLbHVkZ2UoZWx0LCBjb29yZHMpO1xuICAgIGlmIChub2RlKSB7XG4gICAgICAgIGlmIChnZWNrbyAmJiBub2RlLm5vZGVUeXBlID09IDEpIHtcbiAgICAgICAgICAgIC8vIEZpcmVmb3ggd2lsbCBzb21ldGltZXMgcmV0dXJuIG9mZnNldHMgaW50byA8aW5wdXQ+IG5vZGVzLCB3aGljaFxuICAgICAgICAgICAgLy8gaGF2ZSBubyBhY3R1YWwgY2hpbGRyZW4sIGZyb20gY2FyZXRQb3NpdGlvbkZyb21Qb2ludCAoIzk1MylcbiAgICAgICAgICAgIG9mZnNldCA9IE1hdGgubWluKG9mZnNldCwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aCk7XG4gICAgICAgICAgICAvLyBJdCdsbCBhbHNvIG1vdmUgdGhlIHJldHVybmVkIHBvc2l0aW9uIGJlZm9yZSBpbWFnZSBub2RlcyxcbiAgICAgICAgICAgIC8vIGV2ZW4gaWYgdGhvc2UgYXJlIGJlaGluZCBpdC5cbiAgICAgICAgICAgIGlmIChvZmZzZXQgPCBub2RlLmNoaWxkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5leHQgPSBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0XSwgYm94O1xuICAgICAgICAgICAgICAgIGlmIChuZXh0Lm5vZGVOYW1lID09IFwiSU1HXCIgJiYgKGJveCA9IG5leHQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpLnJpZ2h0IDw9IGNvb3Jkcy5sZWZ0ICYmXG4gICAgICAgICAgICAgICAgICAgIGJveC5ib3R0b20gPiBjb29yZHMudG9wKVxuICAgICAgICAgICAgICAgICAgICBvZmZzZXQrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgcHJldjtcbiAgICAgICAgLy8gV2hlbiBjbGlja2luZyBhYm92ZSB0aGUgcmlnaHQgc2lkZSBvZiBhbiB1bmVkaXRhYmxlIG5vZGUsIENocm9tZSB3aWxsIHJlcG9ydCBhIGN1cnNvciBwb3NpdGlvbiBhZnRlciB0aGF0IG5vZGUuXG4gICAgICAgIGlmICh3ZWJraXQgJiYgb2Zmc2V0ICYmIG5vZGUubm9kZVR5cGUgPT0gMSAmJiAocHJldiA9IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXQgLSAxXSkubm9kZVR5cGUgPT0gMSAmJlxuICAgICAgICAgICAgcHJldi5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiICYmIHByZXYuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wID49IGNvb3Jkcy50b3ApXG4gICAgICAgICAgICBvZmZzZXQtLTtcbiAgICAgICAgLy8gU3VzcGljaW91c2x5IHNwZWNpZmljIGtsdWRnZSB0byB3b3JrIGFyb3VuZCBjYXJldCpGcm9tUG9pbnRcbiAgICAgICAgLy8gbmV2ZXIgcmV0dXJuaW5nIGEgcG9zaXRpb24gYXQgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnRcbiAgICAgICAgaWYgKG5vZGUgPT0gdmlldy5kb20gJiYgb2Zmc2V0ID09IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGggLSAxICYmIG5vZGUubGFzdENoaWxkLm5vZGVUeXBlID09IDEgJiZcbiAgICAgICAgICAgIGNvb3Jkcy50b3AgPiBub2RlLmxhc3RDaGlsZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5ib3R0b20pXG4gICAgICAgICAgICBwb3MgPSB2aWV3LnN0YXRlLmRvYy5jb250ZW50LnNpemU7XG4gICAgICAgIC8vIElnbm9yZSBwb3NpdGlvbnMgZGlyZWN0bHkgYWZ0ZXIgYSBCUiwgc2luY2UgY2FyZXQqRnJvbVBvaW50XG4gICAgICAgIC8vICdyb3VuZCB1cCcgcG9zaXRpb25zIHRoYXQgd291bGQgYmUgbW9yZSBhY2N1cmF0ZWx5IHBsYWNlZFxuICAgICAgICAvLyBiZWZvcmUgdGhlIEJSIG5vZGUuXG4gICAgICAgIGVsc2UgaWYgKG9mZnNldCA9PSAwIHx8IG5vZGUubm9kZVR5cGUgIT0gMSB8fCBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0IC0gMV0ubm9kZU5hbWUgIT0gXCJCUlwiKVxuICAgICAgICAgICAgcG9zID0gcG9zRnJvbUNhcmV0KHZpZXcsIG5vZGUsIG9mZnNldCwgY29vcmRzKTtcbiAgICB9XG4gICAgaWYgKHBvcyA9PSBudWxsKVxuICAgICAgICBwb3MgPSBwb3NGcm9tRWxlbWVudCh2aWV3LCBlbHQsIGNvb3Jkcyk7XG4gICAgbGV0IGRlc2MgPSB2aWV3LmRvY1ZpZXcubmVhcmVzdERlc2MoZWx0LCB0cnVlKTtcbiAgICByZXR1cm4geyBwb3MsIGluc2lkZTogZGVzYyA/IGRlc2MucG9zQXRTdGFydCAtIGRlc2MuYm9yZGVyIDogLTEgfTtcbn1cbmZ1bmN0aW9uIG5vblplcm8ocmVjdCkge1xuICAgIHJldHVybiByZWN0LnRvcCA8IHJlY3QuYm90dG9tIHx8IHJlY3QubGVmdCA8IHJlY3QucmlnaHQ7XG59XG5mdW5jdGlvbiBzaW5nbGVSZWN0KHRhcmdldCwgYmlhcykge1xuICAgIGxldCByZWN0cyA9IHRhcmdldC5nZXRDbGllbnRSZWN0cygpO1xuICAgIGlmIChyZWN0cy5sZW5ndGgpIHtcbiAgICAgICAgbGV0IGZpcnN0ID0gcmVjdHNbYmlhcyA8IDAgPyAwIDogcmVjdHMubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmIChub25aZXJvKGZpcnN0KSlcbiAgICAgICAgICAgIHJldHVybiBmaXJzdDtcbiAgICB9XG4gICAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5maW5kLmNhbGwocmVjdHMsIG5vblplcm8pIHx8IHRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbn1cbmNvbnN0IEJJREkgPSAvW1xcdTA1OTAtXFx1MDVmNFxcdTA2MDAtXFx1MDZmZlxcdTA3MDAtXFx1MDhhY10vO1xuLy8gR2l2ZW4gYSBwb3NpdGlvbiBpbiB0aGUgZG9jdW1lbnQgbW9kZWwsIGdldCBhIGJvdW5kaW5nIGJveCBvZiB0aGVcbi8vIGNoYXJhY3RlciBhdCB0aGF0IHBvc2l0aW9uLCByZWxhdGl2ZSB0byB0aGUgd2luZG93LlxuZnVuY3Rpb24gY29vcmRzQXRQb3ModmlldywgcG9zLCBzaWRlKSB7XG4gICAgbGV0IHsgbm9kZSwgb2Zmc2V0LCBhdG9tIH0gPSB2aWV3LmRvY1ZpZXcuZG9tRnJvbVBvcyhwb3MsIHNpZGUgPCAwID8gLTEgOiAxKTtcbiAgICBsZXQgc3VwcG9ydEVtcHR5UmFuZ2UgPSB3ZWJraXQgfHwgZ2Vja287XG4gICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMykge1xuICAgICAgICAvLyBUaGVzZSBicm93c2VycyBzdXBwb3J0IHF1ZXJ5aW5nIGVtcHR5IHRleHQgcmFuZ2VzLiBQcmVmZXIgdGhhdCBpblxuICAgICAgICAvLyBiaWRpIGNvbnRleHQgb3Igd2hlbiBhdCB0aGUgZW5kIG9mIGEgbm9kZS5cbiAgICAgICAgaWYgKHN1cHBvcnRFbXB0eVJhbmdlICYmIChCSURJLnRlc3Qobm9kZS5ub2RlVmFsdWUpIHx8IChzaWRlIDwgMCA/ICFvZmZzZXQgOiBvZmZzZXQgPT0gbm9kZS5ub2RlVmFsdWUubGVuZ3RoKSkpIHtcbiAgICAgICAgICAgIGxldCByZWN0ID0gc2luZ2xlUmVjdCh0ZXh0UmFuZ2Uobm9kZSwgb2Zmc2V0LCBvZmZzZXQpLCBzaWRlKTtcbiAgICAgICAgICAgIC8vIEZpcmVmb3ggcmV0dXJucyBiYWQgcmVzdWx0cyAodGhlIHBvc2l0aW9uIGJlZm9yZSB0aGUgc3BhY2UpXG4gICAgICAgICAgICAvLyB3aGVuIHF1ZXJ5aW5nIGEgcG9zaXRpb24gZGlyZWN0bHkgYWZ0ZXIgbGluZS1icm9rZW5cbiAgICAgICAgICAgIC8vIHdoaXRlc3BhY2UuIERldGVjdCB0aGlzIHNpdHVhdGlvbiBhbmQgYW5kIGtsdWRnZSBhcm91bmQgaXRcbiAgICAgICAgICAgIGlmIChnZWNrbyAmJiBvZmZzZXQgJiYgL1xccy8udGVzdChub2RlLm5vZGVWYWx1ZVtvZmZzZXQgLSAxXSkgJiYgb2Zmc2V0IDwgbm9kZS5ub2RlVmFsdWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlY3RCZWZvcmUgPSBzaW5nbGVSZWN0KHRleHRSYW5nZShub2RlLCBvZmZzZXQgLSAxLCBvZmZzZXQgLSAxKSwgLTEpO1xuICAgICAgICAgICAgICAgIGlmIChyZWN0QmVmb3JlLnRvcCA9PSByZWN0LnRvcCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVjdEFmdGVyID0gc2luZ2xlUmVjdCh0ZXh0UmFuZ2Uobm9kZSwgb2Zmc2V0LCBvZmZzZXQgKyAxKSwgLTEpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVjdEFmdGVyLnRvcCAhPSByZWN0LnRvcClcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmbGF0dGVuVihyZWN0QWZ0ZXIsIHJlY3RBZnRlci5sZWZ0IDwgcmVjdEJlZm9yZS5sZWZ0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVjdDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBmcm9tID0gb2Zmc2V0LCB0byA9IG9mZnNldCwgdGFrZVNpZGUgPSBzaWRlIDwgMCA/IDEgOiAtMTtcbiAgICAgICAgICAgIGlmIChzaWRlIDwgMCAmJiAhb2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgdG8rKztcbiAgICAgICAgICAgICAgICB0YWtlU2lkZSA9IC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoc2lkZSA+PSAwICYmIG9mZnNldCA9PSBub2RlLm5vZGVWYWx1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBmcm9tLS07XG4gICAgICAgICAgICAgICAgdGFrZVNpZGUgPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoc2lkZSA8IDApIHtcbiAgICAgICAgICAgICAgICBmcm9tLS07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0bysrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZsYXR0ZW5WKHNpbmdsZVJlY3QodGV4dFJhbmdlKG5vZGUsIGZyb20sIHRvKSwgdGFrZVNpZGUpLCB0YWtlU2lkZSA8IDApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCAkZG9tID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShwb3MgLSAoYXRvbSB8fCAwKSk7XG4gICAgLy8gUmV0dXJuIGEgaG9yaXpvbnRhbCBsaW5lIGluIGJsb2NrIGNvbnRleHRcbiAgICBpZiAoISRkb20ucGFyZW50LmlubGluZUNvbnRlbnQpIHtcbiAgICAgICAgaWYgKGF0b20gPT0gbnVsbCAmJiBvZmZzZXQgJiYgKHNpZGUgPCAwIHx8IG9mZnNldCA9PSBub2RlU2l6ZShub2RlKSkpIHtcbiAgICAgICAgICAgIGxldCBiZWZvcmUgPSBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0IC0gMV07XG4gICAgICAgICAgICBpZiAoYmVmb3JlLm5vZGVUeXBlID09IDEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZsYXR0ZW5IKGJlZm9yZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhdG9tID09IG51bGwgJiYgb2Zmc2V0IDwgbm9kZVNpemUobm9kZSkpIHtcbiAgICAgICAgICAgIGxldCBhZnRlciA9IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXRdO1xuICAgICAgICAgICAgaWYgKGFmdGVyLm5vZGVUeXBlID09IDEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZsYXR0ZW5IKGFmdGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmxhdHRlbkgobm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgc2lkZSA+PSAwKTtcbiAgICB9XG4gICAgLy8gSW5saW5lLCBub3QgaW4gdGV4dCBub2RlICh0aGlzIGlzIG5vdCBCaWRpLXNhZmUpXG4gICAgaWYgKGF0b20gPT0gbnVsbCAmJiBvZmZzZXQgJiYgKHNpZGUgPCAwIHx8IG9mZnNldCA9PSBub2RlU2l6ZShub2RlKSkpIHtcbiAgICAgICAgbGV0IGJlZm9yZSA9IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXQgLSAxXTtcbiAgICAgICAgbGV0IHRhcmdldCA9IGJlZm9yZS5ub2RlVHlwZSA9PSAzID8gdGV4dFJhbmdlKGJlZm9yZSwgbm9kZVNpemUoYmVmb3JlKSAtIChzdXBwb3J0RW1wdHlSYW5nZSA/IDAgOiAxKSlcbiAgICAgICAgICAgIC8vIEJSIG5vZGVzIHRlbmQgdG8gb25seSByZXR1cm4gdGhlIHJlY3RhbmdsZSBiZWZvcmUgdGhlbS5cbiAgICAgICAgICAgIC8vIE9ubHkgdXNlIHRoZW0gaWYgdGhleSBhcmUgdGhlIGxhc3QgZWxlbWVudCBpbiB0aGVpciBwYXJlbnRcbiAgICAgICAgICAgIDogYmVmb3JlLm5vZGVUeXBlID09IDEgJiYgKGJlZm9yZS5ub2RlTmFtZSAhPSBcIkJSXCIgfHwgIWJlZm9yZS5uZXh0U2libGluZykgPyBiZWZvcmUgOiBudWxsO1xuICAgICAgICBpZiAodGFyZ2V0KVxuICAgICAgICAgICAgcmV0dXJuIGZsYXR0ZW5WKHNpbmdsZVJlY3QodGFyZ2V0LCAxKSwgZmFsc2UpO1xuICAgIH1cbiAgICBpZiAoYXRvbSA9PSBudWxsICYmIG9mZnNldCA8IG5vZGVTaXplKG5vZGUpKSB7XG4gICAgICAgIGxldCBhZnRlciA9IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXRdO1xuICAgICAgICB3aGlsZSAoYWZ0ZXIucG1WaWV3RGVzYyAmJiBhZnRlci5wbVZpZXdEZXNjLmlnbm9yZUZvckNvb3JkcylcbiAgICAgICAgICAgIGFmdGVyID0gYWZ0ZXIubmV4dFNpYmxpbmc7XG4gICAgICAgIGxldCB0YXJnZXQgPSAhYWZ0ZXIgPyBudWxsIDogYWZ0ZXIubm9kZVR5cGUgPT0gMyA/IHRleHRSYW5nZShhZnRlciwgMCwgKHN1cHBvcnRFbXB0eVJhbmdlID8gMCA6IDEpKVxuICAgICAgICAgICAgOiBhZnRlci5ub2RlVHlwZSA9PSAxID8gYWZ0ZXIgOiBudWxsO1xuICAgICAgICBpZiAodGFyZ2V0KVxuICAgICAgICAgICAgcmV0dXJuIGZsYXR0ZW5WKHNpbmdsZVJlY3QodGFyZ2V0LCAtMSksIHRydWUpO1xuICAgIH1cbiAgICAvLyBBbGwgZWxzZSBmYWlsZWQsIGp1c3QgdHJ5IHRvIGdldCBhIHJlY3RhbmdsZSBmb3IgdGhlIHRhcmdldCBub2RlXG4gICAgcmV0dXJuIGZsYXR0ZW5WKHNpbmdsZVJlY3Qobm9kZS5ub2RlVHlwZSA9PSAzID8gdGV4dFJhbmdlKG5vZGUpIDogbm9kZSwgLXNpZGUpLCBzaWRlID49IDApO1xufVxuZnVuY3Rpb24gZmxhdHRlblYocmVjdCwgbGVmdCkge1xuICAgIGlmIChyZWN0LndpZHRoID09IDApXG4gICAgICAgIHJldHVybiByZWN0O1xuICAgIGxldCB4ID0gbGVmdCA/IHJlY3QubGVmdCA6IHJlY3QucmlnaHQ7XG4gICAgcmV0dXJuIHsgdG9wOiByZWN0LnRvcCwgYm90dG9tOiByZWN0LmJvdHRvbSwgbGVmdDogeCwgcmlnaHQ6IHggfTtcbn1cbmZ1bmN0aW9uIGZsYXR0ZW5IKHJlY3QsIHRvcCkge1xuICAgIGlmIChyZWN0LmhlaWdodCA9PSAwKVxuICAgICAgICByZXR1cm4gcmVjdDtcbiAgICBsZXQgeSA9IHRvcCA/IHJlY3QudG9wIDogcmVjdC5ib3R0b207XG4gICAgcmV0dXJuIHsgdG9wOiB5LCBib3R0b206IHksIGxlZnQ6IHJlY3QubGVmdCwgcmlnaHQ6IHJlY3QucmlnaHQgfTtcbn1cbmZ1bmN0aW9uIHdpdGhGbHVzaGVkU3RhdGUodmlldywgc3RhdGUsIGYpIHtcbiAgICBsZXQgdmlld1N0YXRlID0gdmlldy5zdGF0ZSwgYWN0aXZlID0gdmlldy5yb290LmFjdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKHZpZXdTdGF0ZSAhPSBzdGF0ZSlcbiAgICAgICAgdmlldy51cGRhdGVTdGF0ZShzdGF0ZSk7XG4gICAgaWYgKGFjdGl2ZSAhPSB2aWV3LmRvbSlcbiAgICAgICAgdmlldy5mb2N1cygpO1xuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBmKCk7XG4gICAgfVxuICAgIGZpbmFsbHkge1xuICAgICAgICBpZiAodmlld1N0YXRlICE9IHN0YXRlKVxuICAgICAgICAgICAgdmlldy51cGRhdGVTdGF0ZSh2aWV3U3RhdGUpO1xuICAgICAgICBpZiAoYWN0aXZlICE9IHZpZXcuZG9tICYmIGFjdGl2ZSlcbiAgICAgICAgICAgIGFjdGl2ZS5mb2N1cygpO1xuICAgIH1cbn1cbi8vIFdoZXRoZXIgdmVydGljYWwgcG9zaXRpb24gbW90aW9uIGluIGEgZ2l2ZW4gZGlyZWN0aW9uXG4vLyBmcm9tIGEgcG9zaXRpb24gd291bGQgbGVhdmUgYSB0ZXh0IGJsb2NrLlxuZnVuY3Rpb24gZW5kT2ZUZXh0YmxvY2tWZXJ0aWNhbCh2aWV3LCBzdGF0ZSwgZGlyKSB7XG4gICAgbGV0IHNlbCA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICBsZXQgJHBvcyA9IGRpciA9PSBcInVwXCIgPyBzZWwuJGZyb20gOiBzZWwuJHRvO1xuICAgIHJldHVybiB3aXRoRmx1c2hlZFN0YXRlKHZpZXcsIHN0YXRlLCAoKSA9PiB7XG4gICAgICAgIGxldCB7IG5vZGU6IGRvbSB9ID0gdmlldy5kb2NWaWV3LmRvbUZyb21Qb3MoJHBvcy5wb3MsIGRpciA9PSBcInVwXCIgPyAtMSA6IDEpO1xuICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgICBsZXQgbmVhcmVzdCA9IHZpZXcuZG9jVmlldy5uZWFyZXN0RGVzYyhkb20sIHRydWUpO1xuICAgICAgICAgICAgaWYgKCFuZWFyZXN0KVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgaWYgKG5lYXJlc3Qubm9kZS5pc0Jsb2NrKSB7XG4gICAgICAgICAgICAgICAgZG9tID0gbmVhcmVzdC5jb250ZW50RE9NIHx8IG5lYXJlc3QuZG9tO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZG9tID0gbmVhcmVzdC5kb20ucGFyZW50Tm9kZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY29vcmRzID0gY29vcmRzQXRQb3ModmlldywgJHBvcy5wb3MsIDEpO1xuICAgICAgICBmb3IgKGxldCBjaGlsZCA9IGRvbS5maXJzdENoaWxkOyBjaGlsZDsgY2hpbGQgPSBjaGlsZC5uZXh0U2libGluZykge1xuICAgICAgICAgICAgbGV0IGJveGVzO1xuICAgICAgICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlID09IDEpXG4gICAgICAgICAgICAgICAgYm94ZXMgPSBjaGlsZC5nZXRDbGllbnRSZWN0cygpO1xuICAgICAgICAgICAgZWxzZSBpZiAoY2hpbGQubm9kZVR5cGUgPT0gMylcbiAgICAgICAgICAgICAgICBib3hlcyA9IHRleHRSYW5nZShjaGlsZCwgMCwgY2hpbGQubm9kZVZhbHVlLmxlbmd0aCkuZ2V0Q2xpZW50UmVjdHMoKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYm94ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgYm94ID0gYm94ZXNbaV07XG4gICAgICAgICAgICAgICAgaWYgKGJveC5ib3R0b20gPiBib3gudG9wICsgMSAmJlxuICAgICAgICAgICAgICAgICAgICAoZGlyID09IFwidXBcIiA/IGNvb3Jkcy50b3AgLSBib3gudG9wID4gKGJveC5ib3R0b20gLSBjb29yZHMudG9wKSAqIDJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogYm94LmJvdHRvbSAtIGNvb3Jkcy5ib3R0b20gPiAoY29vcmRzLmJvdHRvbSAtIGJveC50b3ApICogMikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcbn1cbmNvbnN0IG1heWJlUlRMID0gL1tcXHUwNTkwLVxcdTA4YWNdLztcbmZ1bmN0aW9uIGVuZE9mVGV4dGJsb2NrSG9yaXpvbnRhbCh2aWV3LCBzdGF0ZSwgZGlyKSB7XG4gICAgbGV0IHsgJGhlYWQgfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICBpZiAoISRoZWFkLnBhcmVudC5pc1RleHRibG9jaylcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCBvZmZzZXQgPSAkaGVhZC5wYXJlbnRPZmZzZXQsIGF0U3RhcnQgPSAhb2Zmc2V0LCBhdEVuZCA9IG9mZnNldCA9PSAkaGVhZC5wYXJlbnQuY29udGVudC5zaXplO1xuICAgIGxldCBzZWwgPSB2aWV3LmRvbVNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsKVxuICAgICAgICByZXR1cm4gJGhlYWQucG9zID09ICRoZWFkLnN0YXJ0KCkgfHwgJGhlYWQucG9zID09ICRoZWFkLmVuZCgpO1xuICAgIC8vIElmIHRoZSB0ZXh0YmxvY2sgaXMgYWxsIExUUiwgb3IgdGhlIGJyb3dzZXIgZG9lc24ndCBzdXBwb3J0XG4gICAgLy8gU2VsZWN0aW9uLm1vZGlmeSAoRWRnZSksIGZhbGwgYmFjayB0byBhIHByaW1pdGl2ZSBhcHByb2FjaFxuICAgIGlmICghbWF5YmVSVEwudGVzdCgkaGVhZC5wYXJlbnQudGV4dENvbnRlbnQpIHx8ICFzZWwubW9kaWZ5KVxuICAgICAgICByZXR1cm4gZGlyID09IFwibGVmdFwiIHx8IGRpciA9PSBcImJhY2t3YXJkXCIgPyBhdFN0YXJ0IDogYXRFbmQ7XG4gICAgcmV0dXJuIHdpdGhGbHVzaGVkU3RhdGUodmlldywgc3RhdGUsICgpID0+IHtcbiAgICAgICAgLy8gVGhpcyBpcyBhIGh1Z2UgaGFjaywgYnV0IGFwcGVhcnMgdG8gYmUgdGhlIGJlc3Qgd2UgY2FuXG4gICAgICAgIC8vIGN1cnJlbnRseSBkbzogdXNlIGBTZWxlY3Rpb24ubW9kaWZ5YCB0byBtb3ZlIHRoZSBzZWxlY3Rpb24gYnlcbiAgICAgICAgLy8gb25lIGNoYXJhY3RlciwgYW5kIHNlZSBpZiB0aGF0IG1vdmVzIHRoZSBjdXJzb3Igb3V0IG9mIHRoZVxuICAgICAgICAvLyB0ZXh0YmxvY2sgKG9yIGRvZXNuJ3QgbW92ZSBpdCBhdCBhbGwsIHdoZW4gYXQgdGhlIHN0YXJ0L2VuZCBvZlxuICAgICAgICAvLyB0aGUgZG9jdW1lbnQpLlxuICAgICAgICBsZXQgeyBmb2N1c05vZGU6IG9sZE5vZGUsIGZvY3VzT2Zmc2V0OiBvbGRPZmYsIGFuY2hvck5vZGUsIGFuY2hvck9mZnNldCB9ID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgICAgICBsZXQgb2xkQmlkaUxldmVsID0gc2VsLmNhcmV0QmlkaUxldmVsIC8vIE9ubHkgZm9yIEZpcmVmb3hcbiAgICAgICAgO1xuICAgICAgICBzZWwubW9kaWZ5KFwibW92ZVwiLCBkaXIsIFwiY2hhcmFjdGVyXCIpO1xuICAgICAgICBsZXQgcGFyZW50RE9NID0gJGhlYWQuZGVwdGggPyB2aWV3LmRvY1ZpZXcuZG9tQWZ0ZXJQb3MoJGhlYWQuYmVmb3JlKCkpIDogdmlldy5kb207XG4gICAgICAgIGxldCB7IGZvY3VzTm9kZTogbmV3Tm9kZSwgZm9jdXNPZmZzZXQ6IG5ld09mZiB9ID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgICAgICBsZXQgcmVzdWx0ID0gbmV3Tm9kZSAmJiAhcGFyZW50RE9NLmNvbnRhaW5zKG5ld05vZGUubm9kZVR5cGUgPT0gMSA/IG5ld05vZGUgOiBuZXdOb2RlLnBhcmVudE5vZGUpIHx8XG4gICAgICAgICAgICAob2xkTm9kZSA9PSBuZXdOb2RlICYmIG9sZE9mZiA9PSBuZXdPZmYpO1xuICAgICAgICAvLyBSZXN0b3JlIHRoZSBwcmV2aW91cyBzZWxlY3Rpb25cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHNlbC5jb2xsYXBzZShhbmNob3JOb2RlLCBhbmNob3JPZmZzZXQpO1xuICAgICAgICAgICAgaWYgKG9sZE5vZGUgJiYgKG9sZE5vZGUgIT0gYW5jaG9yTm9kZSB8fCBvbGRPZmYgIT0gYW5jaG9yT2Zmc2V0KSAmJiBzZWwuZXh0ZW5kKVxuICAgICAgICAgICAgICAgIHNlbC5leHRlbmQob2xkTm9kZSwgb2xkT2ZmKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoXykgeyB9XG4gICAgICAgIGlmIChvbGRCaWRpTGV2ZWwgIT0gbnVsbClcbiAgICAgICAgICAgIHNlbC5jYXJldEJpZGlMZXZlbCA9IG9sZEJpZGlMZXZlbDtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcbn1cbmxldCBjYWNoZWRTdGF0ZSA9IG51bGw7XG5sZXQgY2FjaGVkRGlyID0gbnVsbDtcbmxldCBjYWNoZWRSZXN1bHQgPSBmYWxzZTtcbmZ1bmN0aW9uIGVuZE9mVGV4dGJsb2NrKHZpZXcsIHN0YXRlLCBkaXIpIHtcbiAgICBpZiAoY2FjaGVkU3RhdGUgPT0gc3RhdGUgJiYgY2FjaGVkRGlyID09IGRpcilcbiAgICAgICAgcmV0dXJuIGNhY2hlZFJlc3VsdDtcbiAgICBjYWNoZWRTdGF0ZSA9IHN0YXRlO1xuICAgIGNhY2hlZERpciA9IGRpcjtcbiAgICByZXR1cm4gY2FjaGVkUmVzdWx0ID0gZGlyID09IFwidXBcIiB8fCBkaXIgPT0gXCJkb3duXCJcbiAgICAgICAgPyBlbmRPZlRleHRibG9ja1ZlcnRpY2FsKHZpZXcsIHN0YXRlLCBkaXIpXG4gICAgICAgIDogZW5kT2ZUZXh0YmxvY2tIb3Jpem9udGFsKHZpZXcsIHN0YXRlLCBkaXIpO1xufVxuXG4vLyBWaWV3IGRlc2NyaXB0aW9ucyBhcmUgZGF0YSBzdHJ1Y3R1cmVzIHRoYXQgZGVzY3JpYmUgdGhlIERPTSB0aGF0IGlzXG4vLyB1c2VkIHRvIHJlcHJlc2VudCB0aGUgZWRpdG9yJ3MgY29udGVudC4gVGhleSBhcmUgdXNlZCBmb3I6XG4vL1xuLy8gLSBJbmNyZW1lbnRhbCByZWRyYXdpbmcgd2hlbiB0aGUgZG9jdW1lbnQgY2hhbmdlc1xuLy9cbi8vIC0gRmlndXJpbmcgb3V0IHdoYXQgcGFydCBvZiB0aGUgZG9jdW1lbnQgYSBnaXZlbiBET00gcG9zaXRpb25cbi8vICAgY29ycmVzcG9uZHMgdG9cbi8vXG4vLyAtIFdpcmluZyBpbiBjdXN0b20gaW1wbGVtZW50YXRpb25zIG9mIHRoZSBlZGl0aW5nIGludGVyZmFjZSBmb3IgYVxuLy8gICBnaXZlbiBub2RlXG4vL1xuLy8gVGhleSBmb3JtIGEgZG91Ymx5LWxpbmtlZCBtdXRhYmxlIHRyZWUsIHN0YXJ0aW5nIGF0IGB2aWV3LmRvY1ZpZXdgLlxuY29uc3QgTk9UX0RJUlRZID0gMCwgQ0hJTERfRElSVFkgPSAxLCBDT05URU5UX0RJUlRZID0gMiwgTk9ERV9ESVJUWSA9IDM7XG4vLyBTdXBlcmNsYXNzIGZvciB0aGUgdmFyaW91cyBraW5kcyBvZiBkZXNjcmlwdGlvbnMuIERlZmluZXMgdGhlaXJcbi8vIGJhc2ljIHN0cnVjdHVyZSBhbmQgc2hhcmVkIG1ldGhvZHMuXG5jbGFzcyBWaWV3RGVzYyB7XG4gICAgY29uc3RydWN0b3IocGFyZW50LCBjaGlsZHJlbiwgZG9tLCBcbiAgICAvLyBUaGlzIGlzIHRoZSBub2RlIHRoYXQgaG9sZHMgdGhlIGNoaWxkIHZpZXdzLiBJdCBtYXkgYmUgbnVsbCBmb3JcbiAgICAvLyBkZXNjcyB0aGF0IGRvbid0IGhhdmUgY2hpbGRyZW4uXG4gICAgY29udGVudERPTSkge1xuICAgICAgICB0aGlzLnBhcmVudCA9IHBhcmVudDtcbiAgICAgICAgdGhpcy5jaGlsZHJlbiA9IGNoaWxkcmVuO1xuICAgICAgICB0aGlzLmRvbSA9IGRvbTtcbiAgICAgICAgdGhpcy5jb250ZW50RE9NID0gY29udGVudERPTTtcbiAgICAgICAgdGhpcy5kaXJ0eSA9IE5PVF9ESVJUWTtcbiAgICAgICAgLy8gQW4gZXhwYW5kbyBwcm9wZXJ0eSBvbiB0aGUgRE9NIG5vZGUgcHJvdmlkZXMgYSBsaW5rIGJhY2sgdG8gaXRzXG4gICAgICAgIC8vIGRlc2NyaXB0aW9uLlxuICAgICAgICBkb20ucG1WaWV3RGVzYyA9IHRoaXM7XG4gICAgfVxuICAgIC8vIFVzZWQgdG8gY2hlY2sgd2hldGhlciBhIGdpdmVuIGRlc2NyaXB0aW9uIGNvcnJlc3BvbmRzIHRvIGFcbiAgICAvLyB3aWRnZXQvbWFyay9ub2RlLlxuICAgIG1hdGNoZXNXaWRnZXQod2lkZ2V0KSB7IHJldHVybiBmYWxzZTsgfVxuICAgIG1hdGNoZXNNYXJrKG1hcmspIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgbWF0Y2hlc05vZGUobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28pIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgbWF0Y2hlc0hhY2sobm9kZU5hbWUpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgLy8gV2hlbiBwYXJzaW5nIGluLWVkaXRvciBjb250ZW50IChpbiBkb21jaGFuZ2UuanMpLCB3ZSBhbGxvd1xuICAgIC8vIGRlc2NyaXB0aW9ucyB0byBkZXRlcm1pbmUgdGhlIHBhcnNlIHJ1bGVzIHRoYXQgc2hvdWxkIGJlIHVzZWQgdG9cbiAgICAvLyBwYXJzZSB0aGVtLlxuICAgIHBhcnNlUnVsZSgpIHsgcmV0dXJuIG51bGw7IH1cbiAgICAvLyBVc2VkIGJ5IHRoZSBlZGl0b3IncyBldmVudCBoYW5kbGVyIHRvIGlnbm9yZSBldmVudHMgdGhhdCBjb21lXG4gICAgLy8gZnJvbSBjZXJ0YWluIGRlc2NzLlxuICAgIHN0b3BFdmVudChldmVudCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICAvLyBUaGUgc2l6ZSBvZiB0aGUgY29udGVudCByZXByZXNlbnRlZCBieSB0aGlzIGRlc2MuXG4gICAgZ2V0IHNpemUoKSB7XG4gICAgICAgIGxldCBzaXplID0gMDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgc2l6ZSArPSB0aGlzLmNoaWxkcmVuW2ldLnNpemU7XG4gICAgICAgIHJldHVybiBzaXplO1xuICAgIH1cbiAgICAvLyBGb3IgYmxvY2sgbm9kZXMsIHRoaXMgcmVwcmVzZW50cyB0aGUgc3BhY2UgdGFrZW4gdXAgYnkgdGhlaXJcbiAgICAvLyBzdGFydC9lbmQgdG9rZW5zLlxuICAgIGdldCBib3JkZXIoKSB7IHJldHVybiAwOyB9XG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLmRvbS5wbVZpZXdEZXNjID09IHRoaXMpXG4gICAgICAgICAgICB0aGlzLmRvbS5wbVZpZXdEZXNjID0gdW5kZWZpbmVkO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICB0aGlzLmNoaWxkcmVuW2ldLmRlc3Ryb3koKTtcbiAgICB9XG4gICAgcG9zQmVmb3JlQ2hpbGQoY2hpbGQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIHBvcyA9IHRoaXMucG9zQXRTdGFydDs7IGkrKykge1xuICAgICAgICAgICAgbGV0IGN1ciA9IHRoaXMuY2hpbGRyZW5baV07XG4gICAgICAgICAgICBpZiAoY3VyID09IGNoaWxkKVxuICAgICAgICAgICAgICAgIHJldHVybiBwb3M7XG4gICAgICAgICAgICBwb3MgKz0gY3VyLnNpemU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IHBvc0JlZm9yZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LnBvc0JlZm9yZUNoaWxkKHRoaXMpO1xuICAgIH1cbiAgICBnZXQgcG9zQXRTdGFydCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50ID8gdGhpcy5wYXJlbnQucG9zQmVmb3JlQ2hpbGQodGhpcykgKyB0aGlzLmJvcmRlciA6IDA7XG4gICAgfVxuICAgIGdldCBwb3NBZnRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zQmVmb3JlICsgdGhpcy5zaXplO1xuICAgIH1cbiAgICBnZXQgcG9zQXRFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBvc0F0U3RhcnQgKyB0aGlzLnNpemUgLSAyICogdGhpcy5ib3JkZXI7XG4gICAgfVxuICAgIGxvY2FsUG9zRnJvbURPTShkb20sIG9mZnNldCwgYmlhcykge1xuICAgICAgICAvLyBJZiB0aGUgRE9NIHBvc2l0aW9uIGlzIGluIHRoZSBjb250ZW50LCB1c2UgdGhlIGNoaWxkIGRlc2MgYWZ0ZXJcbiAgICAgICAgLy8gaXQgdG8gZmlndXJlIG91dCBhIHBvc2l0aW9uLlxuICAgICAgICBpZiAodGhpcy5jb250ZW50RE9NICYmIHRoaXMuY29udGVudERPTS5jb250YWlucyhkb20ubm9kZVR5cGUgPT0gMSA/IGRvbSA6IGRvbS5wYXJlbnROb2RlKSkge1xuICAgICAgICAgICAgaWYgKGJpYXMgPCAwKSB7XG4gICAgICAgICAgICAgICAgbGV0IGRvbUJlZm9yZSwgZGVzYztcbiAgICAgICAgICAgICAgICBpZiAoZG9tID09IHRoaXMuY29udGVudERPTSkge1xuICAgICAgICAgICAgICAgICAgICBkb21CZWZvcmUgPSBkb20uY2hpbGROb2Rlc1tvZmZzZXQgLSAxXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChkb20ucGFyZW50Tm9kZSAhPSB0aGlzLmNvbnRlbnRET00pXG4gICAgICAgICAgICAgICAgICAgICAgICBkb20gPSBkb20ucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICAgICAgZG9tQmVmb3JlID0gZG9tLnByZXZpb3VzU2libGluZztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd2hpbGUgKGRvbUJlZm9yZSAmJiAhKChkZXNjID0gZG9tQmVmb3JlLnBtVmlld0Rlc2MpICYmIGRlc2MucGFyZW50ID09IHRoaXMpKVxuICAgICAgICAgICAgICAgICAgICBkb21CZWZvcmUgPSBkb21CZWZvcmUucHJldmlvdXNTaWJsaW5nO1xuICAgICAgICAgICAgICAgIHJldHVybiBkb21CZWZvcmUgPyB0aGlzLnBvc0JlZm9yZUNoaWxkKGRlc2MpICsgZGVzYy5zaXplIDogdGhpcy5wb3NBdFN0YXJ0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IGRvbUFmdGVyLCBkZXNjO1xuICAgICAgICAgICAgICAgIGlmIChkb20gPT0gdGhpcy5jb250ZW50RE9NKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbUFmdGVyID0gZG9tLmNoaWxkTm9kZXNbb2Zmc2V0XTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChkb20ucGFyZW50Tm9kZSAhPSB0aGlzLmNvbnRlbnRET00pXG4gICAgICAgICAgICAgICAgICAgICAgICBkb20gPSBkb20ucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICAgICAgZG9tQWZ0ZXIgPSBkb20ubmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdoaWxlIChkb21BZnRlciAmJiAhKChkZXNjID0gZG9tQWZ0ZXIucG1WaWV3RGVzYykgJiYgZGVzYy5wYXJlbnQgPT0gdGhpcykpXG4gICAgICAgICAgICAgICAgICAgIGRvbUFmdGVyID0gZG9tQWZ0ZXIubmV4dFNpYmxpbmc7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRvbUFmdGVyID8gdGhpcy5wb3NCZWZvcmVDaGlsZChkZXNjKSA6IHRoaXMucG9zQXRFbmQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCB1c2UgdmFyaW91cyBoZXVyaXN0aWNzLCBmYWxsaW5nIGJhY2sgb24gdGhlIGJpYXNcbiAgICAgICAgLy8gcGFyYW1ldGVyLCB0byBkZXRlcm1pbmUgd2hldGhlciB0byByZXR1cm4gdGhlIHBvc2l0aW9uIGF0IHRoZVxuICAgICAgICAvLyBzdGFydCBvciBhdCB0aGUgZW5kIG9mIHRoaXMgdmlldyBkZXNjLlxuICAgICAgICBsZXQgYXRFbmQ7XG4gICAgICAgIGlmIChkb20gPT0gdGhpcy5kb20gJiYgdGhpcy5jb250ZW50RE9NKSB7XG4gICAgICAgICAgICBhdEVuZCA9IG9mZnNldCA+IGRvbUluZGV4KHRoaXMuY29udGVudERPTSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5jb250ZW50RE9NICYmIHRoaXMuY29udGVudERPTSAhPSB0aGlzLmRvbSAmJiB0aGlzLmRvbS5jb250YWlucyh0aGlzLmNvbnRlbnRET00pKSB7XG4gICAgICAgICAgICBhdEVuZCA9IGRvbS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbih0aGlzLmNvbnRlbnRET00pICYgMjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aGlzLmRvbS5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICBpZiAob2Zmc2V0ID09IDApXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgc2VhcmNoID0gZG9tOzsgc2VhcmNoID0gc2VhcmNoLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlYXJjaCA9PSB0aGlzLmRvbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXRFbmQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWFyY2gucHJldmlvdXNTaWJsaW5nKVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGF0RW5kID09IG51bGwgJiYgb2Zmc2V0ID09IGRvbS5jaGlsZE5vZGVzLmxlbmd0aClcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBzZWFyY2ggPSBkb207OyBzZWFyY2ggPSBzZWFyY2gucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2VhcmNoID09IHRoaXMuZG9tKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhdEVuZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VhcmNoLm5leHRTaWJsaW5nKVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoYXRFbmQgPT0gbnVsbCA/IGJpYXMgPiAwIDogYXRFbmQpID8gdGhpcy5wb3NBdEVuZCA6IHRoaXMucG9zQXRTdGFydDtcbiAgICB9XG4gICAgbmVhcmVzdERlc2MoZG9tLCBvbmx5Tm9kZXMgPSBmYWxzZSkge1xuICAgICAgICBmb3IgKGxldCBmaXJzdCA9IHRydWUsIGN1ciA9IGRvbTsgY3VyOyBjdXIgPSBjdXIucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgbGV0IGRlc2MgPSB0aGlzLmdldERlc2MoY3VyKSwgbm9kZURPTTtcbiAgICAgICAgICAgIGlmIChkZXNjICYmICghb25seU5vZGVzIHx8IGRlc2Mubm9kZSkpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiBkb20gaXMgb3V0c2lkZSBvZiB0aGlzIGRlc2MncyBub2RlRE9NLCBkb24ndCBjb3VudCBpdC5cbiAgICAgICAgICAgICAgICBpZiAoZmlyc3QgJiYgKG5vZGVET00gPSBkZXNjLm5vZGVET00pICYmXG4gICAgICAgICAgICAgICAgICAgICEobm9kZURPTS5ub2RlVHlwZSA9PSAxID8gbm9kZURPTS5jb250YWlucyhkb20ubm9kZVR5cGUgPT0gMSA/IGRvbSA6IGRvbS5wYXJlbnROb2RlKSA6IG5vZGVET00gPT0gZG9tKSlcbiAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZXNjO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGdldERlc2MoZG9tKSB7XG4gICAgICAgIGxldCBkZXNjID0gZG9tLnBtVmlld0Rlc2M7XG4gICAgICAgIGZvciAobGV0IGN1ciA9IGRlc2M7IGN1cjsgY3VyID0gY3VyLnBhcmVudClcbiAgICAgICAgICAgIGlmIChjdXIgPT0gdGhpcylcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVzYztcbiAgICB9XG4gICAgcG9zRnJvbURPTShkb20sIG9mZnNldCwgYmlhcykge1xuICAgICAgICBmb3IgKGxldCBzY2FuID0gZG9tOyBzY2FuOyBzY2FuID0gc2Nhbi5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICBsZXQgZGVzYyA9IHRoaXMuZ2V0RGVzYyhzY2FuKTtcbiAgICAgICAgICAgIGlmIChkZXNjKVxuICAgICAgICAgICAgICAgIHJldHVybiBkZXNjLmxvY2FsUG9zRnJvbURPTShkb20sIG9mZnNldCwgYmlhcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICAvLyBGaW5kIHRoZSBkZXNjIGZvciB0aGUgbm9kZSBhZnRlciB0aGUgZ2l2ZW4gcG9zLCBpZiBhbnkuIChXaGVuIGFcbiAgICAvLyBwYXJlbnQgbm9kZSBvdmVycm9kZSByZW5kZXJpbmcsIHRoZXJlIG1pZ2h0IG5vdCBiZSBvbmUuKVxuICAgIGRlc2NBdChwb3MpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIG9mZnNldCA9IDA7IGkgPCB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW2ldLCBlbmQgPSBvZmZzZXQgKyBjaGlsZC5zaXplO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA9PSBwb3MgJiYgZW5kICE9IG9mZnNldCkge1xuICAgICAgICAgICAgICAgIHdoaWxlICghY2hpbGQuYm9yZGVyICYmIGNoaWxkLmNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgaW5uZXIgPSBjaGlsZC5jaGlsZHJlbltpXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbm5lci5zaXplKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBpbm5lcjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocG9zIDwgZW5kKVxuICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZC5kZXNjQXQocG9zIC0gb2Zmc2V0IC0gY2hpbGQuYm9yZGVyKTtcbiAgICAgICAgICAgIG9mZnNldCA9IGVuZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkb21Gcm9tUG9zKHBvcywgc2lkZSkge1xuICAgICAgICBpZiAoIXRoaXMuY29udGVudERPTSlcbiAgICAgICAgICAgIHJldHVybiB7IG5vZGU6IHRoaXMuZG9tLCBvZmZzZXQ6IDAsIGF0b206IHBvcyArIDEgfTtcbiAgICAgICAgLy8gRmlyc3QgZmluZCB0aGUgcG9zaXRpb24gaW4gdGhlIGNoaWxkIGFycmF5XG4gICAgICAgIGxldCBpID0gMCwgb2Zmc2V0ID0gMDtcbiAgICAgICAgZm9yIChsZXQgY3VyUG9zID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMuY2hpbGRyZW5baV0sIGVuZCA9IGN1clBvcyArIGNoaWxkLnNpemU7XG4gICAgICAgICAgICBpZiAoZW5kID4gcG9zIHx8IGNoaWxkIGluc3RhbmNlb2YgVHJhaWxpbmdIYWNrVmlld0Rlc2MpIHtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSBwb3MgLSBjdXJQb3M7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJQb3MgPSBlbmQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgdGhpcyBwb2ludHMgaW50byB0aGUgbWlkZGxlIG9mIGEgY2hpbGQsIGNhbGwgdGhyb3VnaFxuICAgICAgICBpZiAob2Zmc2V0KVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5baV0uZG9tRnJvbVBvcyhvZmZzZXQgLSB0aGlzLmNoaWxkcmVuW2ldLmJvcmRlciwgc2lkZSk7XG4gICAgICAgIC8vIEdvIGJhY2sgaWYgdGhlcmUgd2VyZSBhbnkgemVyby1sZW5ndGggd2lkZ2V0cyB3aXRoIHNpZGUgPj0gMCBiZWZvcmUgdGhpcyBwb2ludFxuICAgICAgICBmb3IgKGxldCBwcmV2OyBpICYmICEocHJldiA9IHRoaXMuY2hpbGRyZW5baSAtIDFdKS5zaXplICYmIHByZXYgaW5zdGFuY2VvZiBXaWRnZXRWaWV3RGVzYyAmJiBwcmV2LnNpZGUgPj0gMDsgaS0tKSB7IH1cbiAgICAgICAgLy8gU2NhbiB0b3dhcmRzIHRoZSBmaXJzdCB1c2VhYmxlIG5vZGVcbiAgICAgICAgaWYgKHNpZGUgPD0gMCkge1xuICAgICAgICAgICAgbGV0IHByZXYsIGVudGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIGZvciAoOzsgaS0tLCBlbnRlciA9IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgcHJldiA9IGkgPyB0aGlzLmNoaWxkcmVuW2kgLSAxXSA6IG51bGw7XG4gICAgICAgICAgICAgICAgaWYgKCFwcmV2IHx8IHByZXYuZG9tLnBhcmVudE5vZGUgPT0gdGhpcy5jb250ZW50RE9NKVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwcmV2ICYmIHNpZGUgJiYgZW50ZXIgJiYgIXByZXYuYm9yZGVyICYmICFwcmV2LmRvbUF0b20pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHByZXYuZG9tRnJvbVBvcyhwcmV2LnNpemUsIHNpZGUpO1xuICAgICAgICAgICAgcmV0dXJuIHsgbm9kZTogdGhpcy5jb250ZW50RE9NLCBvZmZzZXQ6IHByZXYgPyBkb21JbmRleChwcmV2LmRvbSkgKyAxIDogMCB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IG5leHQsIGVudGVyID0gdHJ1ZTtcbiAgICAgICAgICAgIGZvciAoOzsgaSsrLCBlbnRlciA9IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgbmV4dCA9IGkgPCB0aGlzLmNoaWxkcmVuLmxlbmd0aCA/IHRoaXMuY2hpbGRyZW5baV0gOiBudWxsO1xuICAgICAgICAgICAgICAgIGlmICghbmV4dCB8fCBuZXh0LmRvbS5wYXJlbnROb2RlID09IHRoaXMuY29udGVudERPTSlcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobmV4dCAmJiBlbnRlciAmJiAhbmV4dC5ib3JkZXIgJiYgIW5leHQuZG9tQXRvbSlcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV4dC5kb21Gcm9tUG9zKDAsIHNpZGUpO1xuICAgICAgICAgICAgcmV0dXJuIHsgbm9kZTogdGhpcy5jb250ZW50RE9NLCBvZmZzZXQ6IG5leHQgPyBkb21JbmRleChuZXh0LmRvbSkgOiB0aGlzLmNvbnRlbnRET00uY2hpbGROb2Rlcy5sZW5ndGggfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBVc2VkIHRvIGZpbmQgYSBET00gcmFuZ2UgaW4gYSBzaW5nbGUgcGFyZW50IGZvciBhIGdpdmVuIGNoYW5nZWRcbiAgICAvLyByYW5nZS5cbiAgICBwYXJzZVJhbmdlKGZyb20sIHRvLCBiYXNlID0gMCkge1xuICAgICAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggPT0gMClcbiAgICAgICAgICAgIHJldHVybiB7IG5vZGU6IHRoaXMuY29udGVudERPTSwgZnJvbSwgdG8sIGZyb21PZmZzZXQ6IDAsIHRvT2Zmc2V0OiB0aGlzLmNvbnRlbnRET00uY2hpbGROb2Rlcy5sZW5ndGggfTtcbiAgICAgICAgbGV0IGZyb21PZmZzZXQgPSAtMSwgdG9PZmZzZXQgPSAtMTtcbiAgICAgICAgZm9yIChsZXQgb2Zmc2V0ID0gYmFzZSwgaSA9IDA7OyBpKyspIHtcbiAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMuY2hpbGRyZW5baV0sIGVuZCA9IG9mZnNldCArIGNoaWxkLnNpemU7XG4gICAgICAgICAgICBpZiAoZnJvbU9mZnNldCA9PSAtMSAmJiBmcm9tIDw9IGVuZCkge1xuICAgICAgICAgICAgICAgIGxldCBjaGlsZEJhc2UgPSBvZmZzZXQgKyBjaGlsZC5ib3JkZXI7XG4gICAgICAgICAgICAgICAgLy8gRklYTUUgbWF5YmUgZGVzY2VuZCBtYXJrIHZpZXdzIHRvIHBhcnNlIGEgbmFycm93ZXIgcmFuZ2U/XG4gICAgICAgICAgICAgICAgaWYgKGZyb20gPj0gY2hpbGRCYXNlICYmIHRvIDw9IGVuZCAtIGNoaWxkLmJvcmRlciAmJiBjaGlsZC5ub2RlICYmXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkLmNvbnRlbnRET00gJiYgdGhpcy5jb250ZW50RE9NLmNvbnRhaW5zKGNoaWxkLmNvbnRlbnRET00pKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGQucGFyc2VSYW5nZShmcm9tLCB0bywgY2hpbGRCYXNlKTtcbiAgICAgICAgICAgICAgICBmcm9tID0gb2Zmc2V0O1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSBpOyBqID4gMDsgai0tKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBwcmV2ID0gdGhpcy5jaGlsZHJlbltqIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIGlmIChwcmV2LnNpemUgJiYgcHJldi5kb20ucGFyZW50Tm9kZSA9PSB0aGlzLmNvbnRlbnRET00gJiYgIXByZXYuZW1wdHlDaGlsZEF0KDEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmcm9tT2Zmc2V0ID0gZG9tSW5kZXgocHJldi5kb20pICsgMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGZyb20gLT0gcHJldi5zaXplO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoZnJvbU9mZnNldCA9PSAtMSlcbiAgICAgICAgICAgICAgICAgICAgZnJvbU9mZnNldCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZnJvbU9mZnNldCA+IC0xICYmIChlbmQgPiB0byB8fCBpID09IHRoaXMuY2hpbGRyZW4ubGVuZ3RoIC0gMSkpIHtcbiAgICAgICAgICAgICAgICB0byA9IGVuZDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gdGhpcy5jaGlsZHJlbltqXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQuc2l6ZSAmJiBuZXh0LmRvbS5wYXJlbnROb2RlID09IHRoaXMuY29udGVudERPTSAmJiAhbmV4dC5lbXB0eUNoaWxkQXQoLTEpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b09mZnNldCA9IGRvbUluZGV4KG5leHQuZG9tKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRvICs9IG5leHQuc2l6ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRvT2Zmc2V0ID09IC0xKVxuICAgICAgICAgICAgICAgICAgICB0b09mZnNldCA9IHRoaXMuY29udGVudERPTS5jaGlsZE5vZGVzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9mZnNldCA9IGVuZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBub2RlOiB0aGlzLmNvbnRlbnRET00sIGZyb20sIHRvLCBmcm9tT2Zmc2V0LCB0b09mZnNldCB9O1xuICAgIH1cbiAgICBlbXB0eUNoaWxkQXQoc2lkZSkge1xuICAgICAgICBpZiAodGhpcy5ib3JkZXIgfHwgIXRoaXMuY29udGVudERPTSB8fCAhdGhpcy5jaGlsZHJlbi5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGxldCBjaGlsZCA9IHRoaXMuY2hpbGRyZW5bc2lkZSA8IDAgPyAwIDogdGhpcy5jaGlsZHJlbi5sZW5ndGggLSAxXTtcbiAgICAgICAgcmV0dXJuIGNoaWxkLnNpemUgPT0gMCB8fCBjaGlsZC5lbXB0eUNoaWxkQXQoc2lkZSk7XG4gICAgfVxuICAgIGRvbUFmdGVyUG9zKHBvcykge1xuICAgICAgICBsZXQgeyBub2RlLCBvZmZzZXQgfSA9IHRoaXMuZG9tRnJvbVBvcyhwb3MsIDApO1xuICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSAhPSAxIHx8IG9mZnNldCA9PSBub2RlLmNoaWxkTm9kZXMubGVuZ3RoKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJObyBub2RlIGFmdGVyIHBvcyBcIiArIHBvcyk7XG4gICAgICAgIHJldHVybiBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0XTtcbiAgICB9XG4gICAgLy8gVmlldyBkZXNjcyBhcmUgcmVzcG9uc2libGUgZm9yIHNldHRpbmcgYW55IHNlbGVjdGlvbiB0aGF0IGZhbGxzXG4gICAgLy8gZW50aXJlbHkgaW5zaWRlIG9mIHRoZW0sIHNvIHRoYXQgY3VzdG9tIGltcGxlbWVudGF0aW9ucyBjYW4gZG9cbiAgICAvLyBjdXN0b20gdGhpbmdzIHdpdGggdGhlIHNlbGVjdGlvbi4gTm90ZSB0aGF0IHRoaXMgZmFsbHMgYXBhcnQgd2hlblxuICAgIC8vIGEgc2VsZWN0aW9uIHN0YXJ0cyBpbiBzdWNoIGEgbm9kZSBhbmQgZW5kcyBpbiBhbm90aGVyLCBpbiB3aGljaFxuICAgIC8vIGNhc2Ugd2UganVzdCB1c2Ugd2hhdGV2ZXIgZG9tRnJvbVBvcyBwcm9kdWNlcyBhcyBhIGJlc3QgZWZmb3J0LlxuICAgIHNldFNlbGVjdGlvbihhbmNob3IsIGhlYWQsIHZpZXcsIGZvcmNlID0gZmFsc2UpIHtcbiAgICAgICAgLy8gSWYgdGhlIHNlbGVjdGlvbiBmYWxscyBlbnRpcmVseSBpbiBhIGNoaWxkLCBnaXZlIGl0IHRvIHRoYXQgY2hpbGRcbiAgICAgICAgbGV0IGZyb20gPSBNYXRoLm1pbihhbmNob3IsIGhlYWQpLCB0byA9IE1hdGgubWF4KGFuY2hvciwgaGVhZCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBvZmZzZXQgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGNoaWxkID0gdGhpcy5jaGlsZHJlbltpXSwgZW5kID0gb2Zmc2V0ICsgY2hpbGQuc2l6ZTtcbiAgICAgICAgICAgIGlmIChmcm9tID4gb2Zmc2V0ICYmIHRvIDwgZW5kKVxuICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZC5zZXRTZWxlY3Rpb24oYW5jaG9yIC0gb2Zmc2V0IC0gY2hpbGQuYm9yZGVyLCBoZWFkIC0gb2Zmc2V0IC0gY2hpbGQuYm9yZGVyLCB2aWV3LCBmb3JjZSk7XG4gICAgICAgICAgICBvZmZzZXQgPSBlbmQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGFuY2hvckRPTSA9IHRoaXMuZG9tRnJvbVBvcyhhbmNob3IsIGFuY2hvciA/IC0xIDogMSk7XG4gICAgICAgIGxldCBoZWFkRE9NID0gaGVhZCA9PSBhbmNob3IgPyBhbmNob3JET00gOiB0aGlzLmRvbUZyb21Qb3MoaGVhZCwgaGVhZCA/IC0xIDogMSk7XG4gICAgICAgIGxldCBkb21TZWwgPSB2aWV3LnJvb3QuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICAgIGxldCBzZWxSYW5nZSA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKTtcbiAgICAgICAgbGV0IGJyS2x1ZGdlID0gZmFsc2U7XG4gICAgICAgIC8vIE9uIEZpcmVmb3gsIHVzaW5nIFNlbGVjdGlvbi5jb2xsYXBzZSB0byBwdXQgdGhlIGN1cnNvciBhZnRlciBhXG4gICAgICAgIC8vIEJSIG5vZGUgZm9yIHNvbWUgcmVhc29uIGRvZXNuJ3QgYWx3YXlzIHdvcmsgKCMxMDczKS4gT24gU2FmYXJpLFxuICAgICAgICAvLyB0aGUgY3Vyc29yIHNvbWV0aW1lcyBpbmV4cGxpY2FibGUgdmlzdWFsbHkgbGFncyBiZWhpbmQgaXRzXG4gICAgICAgIC8vIHJlcG9ydGVkIHBvc2l0aW9uIGluIHN1Y2ggc2l0dWF0aW9ucyAoIzEwOTIpLlxuICAgICAgICBpZiAoKGdlY2tvIHx8IHNhZmFyaSkgJiYgYW5jaG9yID09IGhlYWQpIHtcbiAgICAgICAgICAgIGxldCB7IG5vZGUsIG9mZnNldCB9ID0gYW5jaG9yRE9NO1xuICAgICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMykge1xuICAgICAgICAgICAgICAgIGJyS2x1ZGdlID0gISEob2Zmc2V0ICYmIG5vZGUubm9kZVZhbHVlW29mZnNldCAtIDFdID09IFwiXFxuXCIpO1xuICAgICAgICAgICAgICAgIC8vIElzc3VlICMxMTI4XG4gICAgICAgICAgICAgICAgaWYgKGJyS2x1ZGdlICYmIG9mZnNldCA9PSBub2RlLm5vZGVWYWx1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgc2NhbiA9IG5vZGUsIGFmdGVyOyBzY2FuOyBzY2FuID0gc2Nhbi5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWZ0ZXIgPSBzY2FuLm5leHRTaWJsaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFmdGVyLm5vZGVOYW1lID09IFwiQlJcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yRE9NID0gaGVhZERPTSA9IHsgbm9kZTogYWZ0ZXIucGFyZW50Tm9kZSwgb2Zmc2V0OiBkb21JbmRleChhZnRlcikgKyAxIH07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZGVzYyA9IHNjYW4ucG1WaWV3RGVzYztcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkZXNjICYmIGRlc2Mubm9kZSAmJiBkZXNjLm5vZGUuaXNCbG9jaylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBwcmV2ID0gbm9kZS5jaGlsZE5vZGVzW29mZnNldCAtIDFdO1xuICAgICAgICAgICAgICAgIGJyS2x1ZGdlID0gcHJldiAmJiAocHJldi5ub2RlTmFtZSA9PSBcIkJSXCIgfHwgcHJldi5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBGaXJlZm94IGNhbiBhY3Qgc3RyYW5nZWx5IHdoZW4gdGhlIHNlbGVjdGlvbiBpcyBpbiBmcm9udCBvZiBhblxuICAgICAgICAvLyB1bmVkaXRhYmxlIG5vZGUuIFNlZSAjMTE2MyBhbmQgaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTcwOTUzNlxuICAgICAgICBpZiAoZ2Vja28gJiYgc2VsUmFuZ2UuZm9jdXNOb2RlICYmIHNlbFJhbmdlLmZvY3VzTm9kZSAhPSBoZWFkRE9NLm5vZGUgJiYgc2VsUmFuZ2UuZm9jdXNOb2RlLm5vZGVUeXBlID09IDEpIHtcbiAgICAgICAgICAgIGxldCBhZnRlciA9IHNlbFJhbmdlLmZvY3VzTm9kZS5jaGlsZE5vZGVzW3NlbFJhbmdlLmZvY3VzT2Zmc2V0XTtcbiAgICAgICAgICAgIGlmIChhZnRlciAmJiBhZnRlci5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKVxuICAgICAgICAgICAgICAgIGZvcmNlID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIShmb3JjZSB8fCBicktsdWRnZSAmJiBzYWZhcmkpICYmXG4gICAgICAgICAgICBpc0VxdWl2YWxlbnRQb3NpdGlvbihhbmNob3JET00ubm9kZSwgYW5jaG9yRE9NLm9mZnNldCwgc2VsUmFuZ2UuYW5jaG9yTm9kZSwgc2VsUmFuZ2UuYW5jaG9yT2Zmc2V0KSAmJlxuICAgICAgICAgICAgaXNFcXVpdmFsZW50UG9zaXRpb24oaGVhZERPTS5ub2RlLCBoZWFkRE9NLm9mZnNldCwgc2VsUmFuZ2UuZm9jdXNOb2RlLCBzZWxSYW5nZS5mb2N1c09mZnNldCkpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIFNlbGVjdGlvbi5leHRlbmQgY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGFuICdpbnZlcnRlZCcgc2VsZWN0aW9uXG4gICAgICAgIC8vIChvbmUgd2hlcmUgdGhlIGZvY3VzIGlzIGJlZm9yZSB0aGUgYW5jaG9yKSwgYnV0IG5vdCBhbGxcbiAgICAgICAgLy8gYnJvd3NlcnMgc3VwcG9ydCBpdCB5ZXQuXG4gICAgICAgIGxldCBkb21TZWxFeHRlbmRlZCA9IGZhbHNlO1xuICAgICAgICBpZiAoKGRvbVNlbC5leHRlbmQgfHwgYW5jaG9yID09IGhlYWQpICYmICEoYnJLbHVkZ2UgJiYgZ2Vja28pKSB7XG4gICAgICAgICAgICBkb21TZWwuY29sbGFwc2UoYW5jaG9yRE9NLm5vZGUsIGFuY2hvckRPTS5vZmZzZXQpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoYW5jaG9yICE9IGhlYWQpXG4gICAgICAgICAgICAgICAgICAgIGRvbVNlbC5leHRlbmQoaGVhZERPTS5ub2RlLCBoZWFkRE9NLm9mZnNldCk7XG4gICAgICAgICAgICAgICAgZG9tU2VsRXh0ZW5kZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKF8pIHtcbiAgICAgICAgICAgICAgICAvLyBJbiBzb21lIGNhc2VzIHdpdGggQ2hyb21lIHRoZSBzZWxlY3Rpb24gaXMgZW1wdHkgYWZ0ZXIgY2FsbGluZ1xuICAgICAgICAgICAgICAgIC8vIGNvbGxhcHNlLCBldmVuIHdoZW4gaXQgc2hvdWxkIGJlIHZhbGlkLiBUaGlzIGFwcGVhcnMgdG8gYmUgYSBidWcsIGJ1dFxuICAgICAgICAgICAgICAgIC8vIGl0IGlzIGRpZmZpY3VsdCB0byBpc29sYXRlLiBJZiB0aGlzIGhhcHBlbnMgZmFsbGJhY2sgdG8gdGhlIG9sZCBwYXRoXG4gICAgICAgICAgICAgICAgLy8gd2l0aG91dCB1c2luZyBleHRlbmQuXG4gICAgICAgICAgICAgICAgLy8gU2ltaWxhcmx5LCB0aGlzIGNvdWxkIGNyYXNoIG9uIFNhZmFyaSBpZiB0aGUgZWRpdG9yIGlzIGhpZGRlbiwgYW5kXG4gICAgICAgICAgICAgICAgLy8gdGhlcmUgd2FzIG5vIHNlbGVjdGlvbi5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWRvbVNlbEV4dGVuZGVkKSB7XG4gICAgICAgICAgICBpZiAoYW5jaG9yID4gaGVhZCkge1xuICAgICAgICAgICAgICAgIGxldCB0bXAgPSBhbmNob3JET007XG4gICAgICAgICAgICAgICAgYW5jaG9yRE9NID0gaGVhZERPTTtcbiAgICAgICAgICAgICAgICBoZWFkRE9NID0gdG1wO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgICAgICAgIHJhbmdlLnNldEVuZChoZWFkRE9NLm5vZGUsIGhlYWRET00ub2Zmc2V0KTtcbiAgICAgICAgICAgIHJhbmdlLnNldFN0YXJ0KGFuY2hvckRPTS5ub2RlLCBhbmNob3JET00ub2Zmc2V0KTtcbiAgICAgICAgICAgIGRvbVNlbC5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgICAgICAgIGRvbVNlbC5hZGRSYW5nZShyYW5nZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWdub3JlTXV0YXRpb24obXV0YXRpb24pIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLmNvbnRlbnRET00gJiYgbXV0YXRpb24udHlwZSAhPSBcInNlbGVjdGlvblwiO1xuICAgIH1cbiAgICBnZXQgY29udGVudExvc3QoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRlbnRET00gJiYgdGhpcy5jb250ZW50RE9NICE9IHRoaXMuZG9tICYmICF0aGlzLmRvbS5jb250YWlucyh0aGlzLmNvbnRlbnRET00pO1xuICAgIH1cbiAgICAvLyBSZW1vdmUgYSBzdWJ0cmVlIG9mIHRoZSBlbGVtZW50IHRyZWUgdGhhdCBoYXMgYmVlbiB0b3VjaGVkXG4gICAgLy8gYnkgYSBET00gY2hhbmdlLCBzbyB0aGF0IHRoZSBuZXh0IHVwZGF0ZSB3aWxsIHJlZHJhdyBpdC5cbiAgICBtYXJrRGlydHkoZnJvbSwgdG8pIHtcbiAgICAgICAgZm9yIChsZXQgb2Zmc2V0ID0gMCwgaSA9IDA7IGkgPCB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW2ldLCBlbmQgPSBvZmZzZXQgKyBjaGlsZC5zaXplO1xuICAgICAgICAgICAgaWYgKG9mZnNldCA9PSBlbmQgPyBmcm9tIDw9IGVuZCAmJiB0byA+PSBvZmZzZXQgOiBmcm9tIDwgZW5kICYmIHRvID4gb2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0YXJ0SW5zaWRlID0gb2Zmc2V0ICsgY2hpbGQuYm9yZGVyLCBlbmRJbnNpZGUgPSBlbmQgLSBjaGlsZC5ib3JkZXI7XG4gICAgICAgICAgICAgICAgaWYgKGZyb20gPj0gc3RhcnRJbnNpZGUgJiYgdG8gPD0gZW5kSW5zaWRlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGlydHkgPSBmcm9tID09IG9mZnNldCB8fCB0byA9PSBlbmQgPyBDT05URU5UX0RJUlRZIDogQ0hJTERfRElSVFk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChmcm9tID09IHN0YXJ0SW5zaWRlICYmIHRvID09IGVuZEluc2lkZSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNoaWxkLmNvbnRlbnRMb3N0IHx8IGNoaWxkLmRvbS5wYXJlbnROb2RlICE9IHRoaXMuY29udGVudERPTSkpXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGlsZC5kaXJ0eSA9IE5PREVfRElSVFk7XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLm1hcmtEaXJ0eShmcm9tIC0gc3RhcnRJbnNpZGUsIHRvIC0gc3RhcnRJbnNpZGUpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjaGlsZC5kaXJ0eSA9IGNoaWxkLmRvbSA9PSBjaGlsZC5jb250ZW50RE9NICYmIGNoaWxkLmRvbS5wYXJlbnROb2RlID09IHRoaXMuY29udGVudERPTSAmJiAhY2hpbGQuY2hpbGRyZW4ubGVuZ3RoXG4gICAgICAgICAgICAgICAgICAgICAgICA/IENPTlRFTlRfRElSVFkgOiBOT0RFX0RJUlRZO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9mZnNldCA9IGVuZDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRpcnR5ID0gQ09OVEVOVF9ESVJUWTtcbiAgICB9XG4gICAgbWFya1BhcmVudHNEaXJ0eSgpIHtcbiAgICAgICAgbGV0IGxldmVsID0gMTtcbiAgICAgICAgZm9yIChsZXQgbm9kZSA9IHRoaXMucGFyZW50OyBub2RlOyBub2RlID0gbm9kZS5wYXJlbnQsIGxldmVsKyspIHtcbiAgICAgICAgICAgIGxldCBkaXJ0eSA9IGxldmVsID09IDEgPyBDT05URU5UX0RJUlRZIDogQ0hJTERfRElSVFk7XG4gICAgICAgICAgICBpZiAobm9kZS5kaXJ0eSA8IGRpcnR5KVxuICAgICAgICAgICAgICAgIG5vZGUuZGlydHkgPSBkaXJ0eTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQgZG9tQXRvbSgpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgZ2V0IGlnbm9yZUZvckNvb3JkcygpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgZ2V0IGlnbm9yZUZvclNlbGVjdGlvbigpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgaXNUZXh0KHRleHQpIHsgcmV0dXJuIGZhbHNlOyB9XG59XG4vLyBBIHdpZGdldCBkZXNjIHJlcHJlc2VudHMgYSB3aWRnZXQgZGVjb3JhdGlvbiwgd2hpY2ggaXMgYSBET00gbm9kZVxuLy8gZHJhd24gYmV0d2VlbiB0aGUgZG9jdW1lbnQgbm9kZXMuXG5jbGFzcyBXaWRnZXRWaWV3RGVzYyBleHRlbmRzIFZpZXdEZXNjIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJlbnQsIHdpZGdldCwgdmlldywgcG9zKSB7XG4gICAgICAgIGxldCBzZWxmLCBkb20gPSB3aWRnZXQudHlwZS50b0RPTTtcbiAgICAgICAgaWYgKHR5cGVvZiBkb20gPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICAgICAgZG9tID0gZG9tKHZpZXcsICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXNlbGYpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBwb3M7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGYucGFyZW50KVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gc2VsZi5wYXJlbnQucG9zQmVmb3JlQ2hpbGQoc2VsZik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgaWYgKCF3aWRnZXQudHlwZS5zcGVjLnJhdykge1xuICAgICAgICAgICAgaWYgKGRvbS5ub2RlVHlwZSAhPSAxKSB7XG4gICAgICAgICAgICAgICAgbGV0IHdyYXAgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgICAgICAgICAgICAgICB3cmFwLmFwcGVuZENoaWxkKGRvbSk7XG4gICAgICAgICAgICAgICAgZG9tID0gd3JhcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbS5jb250ZW50RWRpdGFibGUgPSBcImZhbHNlXCI7XG4gICAgICAgICAgICBkb20uY2xhc3NMaXN0LmFkZChcIlByb3NlTWlycm9yLXdpZGdldFwiKTtcbiAgICAgICAgfVxuICAgICAgICBzdXBlcihwYXJlbnQsIFtdLCBkb20sIG51bGwpO1xuICAgICAgICB0aGlzLndpZGdldCA9IHdpZGdldDtcbiAgICAgICAgdGhpcy53aWRnZXQgPSB3aWRnZXQ7XG4gICAgICAgIHNlbGYgPSB0aGlzO1xuICAgIH1cbiAgICBtYXRjaGVzV2lkZ2V0KHdpZGdldCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kaXJ0eSA9PSBOT1RfRElSVFkgJiYgd2lkZ2V0LnR5cGUuZXEodGhpcy53aWRnZXQudHlwZSk7XG4gICAgfVxuICAgIHBhcnNlUnVsZSgpIHsgcmV0dXJuIHsgaWdub3JlOiB0cnVlIH07IH1cbiAgICBzdG9wRXZlbnQoZXZlbnQpIHtcbiAgICAgICAgbGV0IHN0b3AgPSB0aGlzLndpZGdldC5zcGVjLnN0b3BFdmVudDtcbiAgICAgICAgcmV0dXJuIHN0b3AgPyBzdG9wKGV2ZW50KSA6IGZhbHNlO1xuICAgIH1cbiAgICBpZ25vcmVNdXRhdGlvbihtdXRhdGlvbikge1xuICAgICAgICByZXR1cm4gbXV0YXRpb24udHlwZSAhPSBcInNlbGVjdGlvblwiIHx8IHRoaXMud2lkZ2V0LnNwZWMuaWdub3JlU2VsZWN0aW9uO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLndpZGdldC50eXBlLmRlc3Ryb3kodGhpcy5kb20pO1xuICAgICAgICBzdXBlci5kZXN0cm95KCk7XG4gICAgfVxuICAgIGdldCBkb21BdG9tKCkgeyByZXR1cm4gdHJ1ZTsgfVxuICAgIGdldCBpZ25vcmVGb3JTZWxlY3Rpb24oKSB7IHJldHVybiAhIXRoaXMud2lkZ2V0LnR5cGUuc3BlYy5yZWxheGVkU2lkZTsgfVxuICAgIGdldCBzaWRlKCkgeyByZXR1cm4gdGhpcy53aWRnZXQudHlwZS5zaWRlOyB9XG59XG5jbGFzcyBDb21wb3NpdGlvblZpZXdEZXNjIGV4dGVuZHMgVmlld0Rlc2Mge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgZG9tLCB0ZXh0RE9NLCB0ZXh0KSB7XG4gICAgICAgIHN1cGVyKHBhcmVudCwgW10sIGRvbSwgbnVsbCk7XG4gICAgICAgIHRoaXMudGV4dERPTSA9IHRleHRET007XG4gICAgICAgIHRoaXMudGV4dCA9IHRleHQ7XG4gICAgfVxuICAgIGdldCBzaXplKCkgeyByZXR1cm4gdGhpcy50ZXh0Lmxlbmd0aDsgfVxuICAgIGxvY2FsUG9zRnJvbURPTShkb20sIG9mZnNldCkge1xuICAgICAgICBpZiAoZG9tICE9IHRoaXMudGV4dERPTSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnBvc0F0U3RhcnQgKyAob2Zmc2V0ID8gdGhpcy5zaXplIDogMCk7XG4gICAgICAgIHJldHVybiB0aGlzLnBvc0F0U3RhcnQgKyBvZmZzZXQ7XG4gICAgfVxuICAgIGRvbUZyb21Qb3MocG9zKSB7XG4gICAgICAgIHJldHVybiB7IG5vZGU6IHRoaXMudGV4dERPTSwgb2Zmc2V0OiBwb3MgfTtcbiAgICB9XG4gICAgaWdub3JlTXV0YXRpb24obXV0KSB7XG4gICAgICAgIHJldHVybiBtdXQudHlwZSA9PT0gJ2NoYXJhY3RlckRhdGEnICYmIG11dC50YXJnZXQubm9kZVZhbHVlID09IG11dC5vbGRWYWx1ZTtcbiAgICB9XG59XG4vLyBBIG1hcmsgZGVzYyByZXByZXNlbnRzIGEgbWFyay4gTWF5IGhhdmUgbXVsdGlwbGUgY2hpbGRyZW4sXG4vLyBkZXBlbmRpbmcgb24gaG93IHRoZSBtYXJrIGlzIHNwbGl0LiBOb3RlIHRoYXQgbWFya3MgYXJlIGRyYXduIHVzaW5nXG4vLyBhIGZpeGVkIG5lc3Rpbmcgb3JkZXIsIGZvciBzaW1wbGljaXR5IGFuZCBwcmVkaWN0YWJpbGl0eSwgc28gaW5cbi8vIHNvbWUgY2FzZXMgdGhleSB3aWxsIGJlIHNwbGl0IG1vcmUgb2Z0ZW4gdGhhbiB3b3VsZCBhcHBlYXJcbi8vIG5lY2Vzc2FyeS5cbmNsYXNzIE1hcmtWaWV3RGVzYyBleHRlbmRzIFZpZXdEZXNjIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJlbnQsIG1hcmssIGRvbSwgY29udGVudERPTSwgc3BlYykge1xuICAgICAgICBzdXBlcihwYXJlbnQsIFtdLCBkb20sIGNvbnRlbnRET00pO1xuICAgICAgICB0aGlzLm1hcmsgPSBtYXJrO1xuICAgICAgICB0aGlzLnNwZWMgPSBzcGVjO1xuICAgIH1cbiAgICBzdGF0aWMgY3JlYXRlKHBhcmVudCwgbWFyaywgaW5saW5lLCB2aWV3KSB7XG4gICAgICAgIGxldCBjdXN0b20gPSB2aWV3Lm5vZGVWaWV3c1ttYXJrLnR5cGUubmFtZV07XG4gICAgICAgIGxldCBzcGVjID0gY3VzdG9tICYmIGN1c3RvbShtYXJrLCB2aWV3LCBpbmxpbmUpO1xuICAgICAgICBpZiAoIXNwZWMgfHwgIXNwZWMuZG9tKVxuICAgICAgICAgICAgc3BlYyA9IERPTVNlcmlhbGl6ZXIucmVuZGVyU3BlYyhkb2N1bWVudCwgbWFyay50eXBlLnNwZWMudG9ET00obWFyaywgaW5saW5lKSwgbnVsbCwgbWFyay5hdHRycyk7XG4gICAgICAgIHJldHVybiBuZXcgTWFya1ZpZXdEZXNjKHBhcmVudCwgbWFyaywgc3BlYy5kb20sIHNwZWMuY29udGVudERPTSB8fCBzcGVjLmRvbSwgc3BlYyk7XG4gICAgfVxuICAgIHBhcnNlUnVsZSgpIHtcbiAgICAgICAgaWYgKCh0aGlzLmRpcnR5ICYgTk9ERV9ESVJUWSkgfHwgdGhpcy5tYXJrLnR5cGUuc3BlYy5yZXBhcnNlSW5WaWV3KVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiB7IG1hcms6IHRoaXMubWFyay50eXBlLm5hbWUsIGF0dHJzOiB0aGlzLm1hcmsuYXR0cnMsIGNvbnRlbnRFbGVtZW50OiB0aGlzLmNvbnRlbnRET00gfTtcbiAgICB9XG4gICAgbWF0Y2hlc01hcmsobWFyaykgeyByZXR1cm4gdGhpcy5kaXJ0eSAhPSBOT0RFX0RJUlRZICYmIHRoaXMubWFyay5lcShtYXJrKTsgfVxuICAgIG1hcmtEaXJ0eShmcm9tLCB0bykge1xuICAgICAgICBzdXBlci5tYXJrRGlydHkoZnJvbSwgdG8pO1xuICAgICAgICAvLyBNb3ZlIGRpcnR5IGluZm8gdG8gbmVhcmVzdCBub2RlIHZpZXdcbiAgICAgICAgaWYgKHRoaXMuZGlydHkgIT0gTk9UX0RJUlRZKSB7XG4gICAgICAgICAgICBsZXQgcGFyZW50ID0gdGhpcy5wYXJlbnQ7XG4gICAgICAgICAgICB3aGlsZSAoIXBhcmVudC5ub2RlKVxuICAgICAgICAgICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7XG4gICAgICAgICAgICBpZiAocGFyZW50LmRpcnR5IDwgdGhpcy5kaXJ0eSlcbiAgICAgICAgICAgICAgICBwYXJlbnQuZGlydHkgPSB0aGlzLmRpcnR5O1xuICAgICAgICAgICAgdGhpcy5kaXJ0eSA9IE5PVF9ESVJUWTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzbGljZShmcm9tLCB0bywgdmlldykge1xuICAgICAgICBsZXQgY29weSA9IE1hcmtWaWV3RGVzYy5jcmVhdGUodGhpcy5wYXJlbnQsIHRoaXMubWFyaywgdHJ1ZSwgdmlldyk7XG4gICAgICAgIGxldCBub2RlcyA9IHRoaXMuY2hpbGRyZW4sIHNpemUgPSB0aGlzLnNpemU7XG4gICAgICAgIGlmICh0byA8IHNpemUpXG4gICAgICAgICAgICBub2RlcyA9IHJlcGxhY2VOb2Rlcyhub2RlcywgdG8sIHNpemUsIHZpZXcpO1xuICAgICAgICBpZiAoZnJvbSA+IDApXG4gICAgICAgICAgICBub2RlcyA9IHJlcGxhY2VOb2Rlcyhub2RlcywgMCwgZnJvbSwgdmlldyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBub2Rlc1tpXS5wYXJlbnQgPSBjb3B5O1xuICAgICAgICBjb3B5LmNoaWxkcmVuID0gbm9kZXM7XG4gICAgICAgIHJldHVybiBjb3B5O1xuICAgIH1cbiAgICBpZ25vcmVNdXRhdGlvbihtdXRhdGlvbikge1xuICAgICAgICByZXR1cm4gdGhpcy5zcGVjLmlnbm9yZU11dGF0aW9uID8gdGhpcy5zcGVjLmlnbm9yZU11dGF0aW9uKG11dGF0aW9uKSA6IHN1cGVyLmlnbm9yZU11dGF0aW9uKG11dGF0aW9uKTtcbiAgICB9XG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgaWYgKHRoaXMuc3BlYy5kZXN0cm95KVxuICAgICAgICAgICAgdGhpcy5zcGVjLmRlc3Ryb3koKTtcbiAgICAgICAgc3VwZXIuZGVzdHJveSgpO1xuICAgIH1cbn1cbi8vIE5vZGUgdmlldyBkZXNjcyBhcmUgdGhlIG1haW4sIG1vc3QgY29tbW9uIHR5cGUgb2YgdmlldyBkZXNjLCBhbmRcbi8vIGNvcnJlc3BvbmQgdG8gYW4gYWN0dWFsIG5vZGUgaW4gdGhlIGRvY3VtZW50LiBVbmxpa2UgbWFyayBkZXNjcyxcbi8vIHRoZXkgcG9wdWxhdGUgdGhlaXIgY2hpbGQgYXJyYXkgdGhlbXNlbHZlcy5cbmNsYXNzIE5vZGVWaWV3RGVzYyBleHRlbmRzIFZpZXdEZXNjIHtcbiAgICBjb25zdHJ1Y3RvcihwYXJlbnQsIG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCBkb20sIGNvbnRlbnRET00sIG5vZGVET00sIHZpZXcsIHBvcykge1xuICAgICAgICBzdXBlcihwYXJlbnQsIFtdLCBkb20sIGNvbnRlbnRET00pO1xuICAgICAgICB0aGlzLm5vZGUgPSBub2RlO1xuICAgICAgICB0aGlzLm91dGVyRGVjbyA9IG91dGVyRGVjbztcbiAgICAgICAgdGhpcy5pbm5lckRlY28gPSBpbm5lckRlY287XG4gICAgICAgIHRoaXMubm9kZURPTSA9IG5vZGVET007XG4gICAgfVxuICAgIC8vIEJ5IGRlZmF1bHQsIGEgbm9kZSBpcyByZW5kZXJlZCB1c2luZyB0aGUgYHRvRE9NYCBtZXRob2QgZnJvbSB0aGVcbiAgICAvLyBub2RlIHR5cGUgc3BlYy4gQnV0IGNsaWVudCBjb2RlIGNhbiB1c2UgdGhlIGBub2RlVmlld3NgIHNwZWMgdG9cbiAgICAvLyBzdXBwbHkgYSBjdXN0b20gbm9kZSB2aWV3LCB3aGljaCBjYW4gaW5mbHVlbmNlIHZhcmlvdXMgYXNwZWN0cyBvZlxuICAgIC8vIHRoZSB3YXkgdGhlIG5vZGUgd29ya3MuXG4gICAgLy9cbiAgICAvLyAoVXNpbmcgc3ViY2xhc3NpbmcgZm9yIHRoaXMgd2FzIGludGVudGlvbmFsbHkgZGVjaWRlZCBhZ2FpbnN0LFxuICAgIC8vIHNpbmNlIGl0J2QgcmVxdWlyZSBleHBvc2luZyBhIHdob2xlIHNsZXcgb2YgZmluaWNreVxuICAgIC8vIGltcGxlbWVudGF0aW9uIGRldGFpbHMgdG8gdGhlIHVzZXIgY29kZSB0aGF0IHRoZXkgcHJvYmFibHkgd2lsbFxuICAgIC8vIG5ldmVyIG5lZWQuKVxuICAgIHN0YXRpYyBjcmVhdGUocGFyZW50LCBub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgdmlldywgcG9zKSB7XG4gICAgICAgIGxldCBjdXN0b20gPSB2aWV3Lm5vZGVWaWV3c1tub2RlLnR5cGUubmFtZV0sIGRlc2NPYmo7XG4gICAgICAgIGxldCBzcGVjID0gY3VzdG9tICYmIGN1c3RvbShub2RlLCB2aWV3LCAoKSA9PiB7XG4gICAgICAgICAgICAvLyAoVGhpcyBpcyBhIGZ1bmN0aW9uIHRoYXQgYWxsb3dzIHRoZSBjdXN0b20gdmlldyB0byBmaW5kIGl0c1xuICAgICAgICAgICAgLy8gb3duIHBvc2l0aW9uKVxuICAgICAgICAgICAgaWYgKCFkZXNjT2JqKVxuICAgICAgICAgICAgICAgIHJldHVybiBwb3M7XG4gICAgICAgICAgICBpZiAoZGVzY09iai5wYXJlbnQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlc2NPYmoucGFyZW50LnBvc0JlZm9yZUNoaWxkKGRlc2NPYmopO1xuICAgICAgICB9LCBvdXRlckRlY28sIGlubmVyRGVjbyk7XG4gICAgICAgIGxldCBkb20gPSBzcGVjICYmIHNwZWMuZG9tLCBjb250ZW50RE9NID0gc3BlYyAmJiBzcGVjLmNvbnRlbnRET007XG4gICAgICAgIGlmIChub2RlLmlzVGV4dCkge1xuICAgICAgICAgICAgaWYgKCFkb20pXG4gICAgICAgICAgICAgICAgZG9tID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobm9kZS50ZXh0KTtcbiAgICAgICAgICAgIGVsc2UgaWYgKGRvbS5ub2RlVHlwZSAhPSAzKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVGV4dCBtdXN0IGJlIHJlbmRlcmVkIGFzIGEgRE9NIHRleHQgbm9kZVwiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghZG9tKSB7XG4gICAgICAgICAgICBsZXQgc3BlYyA9IERPTVNlcmlhbGl6ZXIucmVuZGVyU3BlYyhkb2N1bWVudCwgbm9kZS50eXBlLnNwZWMudG9ET00obm9kZSksIG51bGwsIG5vZGUuYXR0cnMpO1xuICAgICAgICAgICAgKHsgZG9tLCBjb250ZW50RE9NIH0gPSBzcGVjKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNvbnRlbnRET00gJiYgIW5vZGUuaXNUZXh0ICYmIGRvbS5ub2RlTmFtZSAhPSBcIkJSXCIpIHsgLy8gQ2hyb21lIGdldHMgY29uZnVzZWQgYnkgPGJyIGNvbnRlbnRlZGl0YWJsZT1mYWxzZT5cbiAgICAgICAgICAgIGlmICghZG9tLmhhc0F0dHJpYnV0ZShcImNvbnRlbnRlZGl0YWJsZVwiKSlcbiAgICAgICAgICAgICAgICBkb20uY29udGVudEVkaXRhYmxlID0gXCJmYWxzZVwiO1xuICAgICAgICAgICAgaWYgKG5vZGUudHlwZS5zcGVjLmRyYWdnYWJsZSlcbiAgICAgICAgICAgICAgICBkb20uZHJhZ2dhYmxlID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbm9kZURPTSA9IGRvbTtcbiAgICAgICAgZG9tID0gYXBwbHlPdXRlckRlY28oZG9tLCBvdXRlckRlY28sIG5vZGUpO1xuICAgICAgICBpZiAoc3BlYylcbiAgICAgICAgICAgIHJldHVybiBkZXNjT2JqID0gbmV3IEN1c3RvbU5vZGVWaWV3RGVzYyhwYXJlbnQsIG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCBkb20sIGNvbnRlbnRET00gfHwgbnVsbCwgbm9kZURPTSwgc3BlYywgdmlldywgcG9zICsgMSk7XG4gICAgICAgIGVsc2UgaWYgKG5vZGUuaXNUZXh0KVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBUZXh0Vmlld0Rlc2MocGFyZW50LCBub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgZG9tLCBub2RlRE9NLCB2aWV3KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBOb2RlVmlld0Rlc2MocGFyZW50LCBub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgZG9tLCBjb250ZW50RE9NIHx8IG51bGwsIG5vZGVET00sIHZpZXcsIHBvcyArIDEpO1xuICAgIH1cbiAgICBwYXJzZVJ1bGUoKSB7XG4gICAgICAgIC8vIEV4cGVyaW1lbnRhbCBrbHVkZ2UgdG8gYWxsb3cgb3B0LWluIHJlLXBhcnNpbmcgb2Ygbm9kZXNcbiAgICAgICAgaWYgKHRoaXMubm9kZS50eXBlLnNwZWMucmVwYXJzZUluVmlldylcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAvLyBGSVhNRSB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoaXMgY2FuIGFsd2F5cyByZXR1cm4gdGhlIGN1cnJlbnRcbiAgICAgICAgLy8gYXR0cnMgbWVhbnMgdGhhdCBpZiB0aGUgdXNlciBzb21laG93IG1hbmFnZXMgdG8gY2hhbmdlIHRoZVxuICAgICAgICAvLyBhdHRycyBpbiB0aGUgZG9tLCB0aGF0IHdvbid0IGJlIHBpY2tlZCB1cC4gTm90IGVudGlyZWx5IHN1cmVcbiAgICAgICAgLy8gd2hldGhlciB0aGlzIGlzIGEgcHJvYmxlbVxuICAgICAgICBsZXQgcnVsZSA9IHsgbm9kZTogdGhpcy5ub2RlLnR5cGUubmFtZSwgYXR0cnM6IHRoaXMubm9kZS5hdHRycyB9O1xuICAgICAgICBpZiAodGhpcy5ub2RlLnR5cGUud2hpdGVzcGFjZSA9PSBcInByZVwiKVxuICAgICAgICAgICAgcnVsZS5wcmVzZXJ2ZVdoaXRlc3BhY2UgPSBcImZ1bGxcIjtcbiAgICAgICAgaWYgKCF0aGlzLmNvbnRlbnRET00pIHtcbiAgICAgICAgICAgIHJ1bGUuZ2V0Q29udGVudCA9ICgpID0+IHRoaXMubm9kZS5jb250ZW50O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCF0aGlzLmNvbnRlbnRMb3N0KSB7XG4gICAgICAgICAgICBydWxlLmNvbnRlbnRFbGVtZW50ID0gdGhpcy5jb250ZW50RE9NO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gQ2hyb21lIGxpa2VzIHRvIHJhbmRvbWx5IHJlY3JlYXRlIHBhcmVudCBub2RlcyB3aGVuXG4gICAgICAgICAgICAvLyBiYWNrc3BhY2luZyB0aGluZ3MuIFdoZW4gdGhhdCBoYXBwZW5zLCB0aGlzIHRyaWVzIHRvIGZpbmQgdGhlXG4gICAgICAgICAgICAvLyBuZXcgcGFyZW50LlxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmRvbS5jb250YWlucyhjaGlsZC5kb20ucGFyZW50Tm9kZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcnVsZS5jb250ZW50RWxlbWVudCA9IGNoaWxkLmRvbS5wYXJlbnROb2RlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXJ1bGUuY29udGVudEVsZW1lbnQpXG4gICAgICAgICAgICAgICAgcnVsZS5nZXRDb250ZW50ID0gKCkgPT4gRnJhZ21lbnQuZW1wdHk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJ1bGU7XG4gICAgfVxuICAgIG1hdGNoZXNOb2RlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpcnR5ID09IE5PVF9ESVJUWSAmJiBub2RlLmVxKHRoaXMubm9kZSkgJiZcbiAgICAgICAgICAgIHNhbWVPdXRlckRlY28ob3V0ZXJEZWNvLCB0aGlzLm91dGVyRGVjbykgJiYgaW5uZXJEZWNvLmVxKHRoaXMuaW5uZXJEZWNvKTtcbiAgICB9XG4gICAgZ2V0IHNpemUoKSB7IHJldHVybiB0aGlzLm5vZGUubm9kZVNpemU7IH1cbiAgICBnZXQgYm9yZGVyKCkgeyByZXR1cm4gdGhpcy5ub2RlLmlzTGVhZiA/IDAgOiAxOyB9XG4gICAgLy8gU3luY3MgYHRoaXMuY2hpbGRyZW5gIHRvIG1hdGNoIGB0aGlzLm5vZGUuY29udGVudGAgYW5kIHRoZSBsb2NhbFxuICAgIC8vIGRlY29yYXRpb25zLCBwb3NzaWJseSBpbnRyb2R1Y2luZyBuZXN0aW5nIGZvciBtYXJrcy4gVGhlbiwgaW4gYVxuICAgIC8vIHNlcGFyYXRlIHN0ZXAsIHN5bmNzIHRoZSBET00gaW5zaWRlIGB0aGlzLmNvbnRlbnRET01gIHRvXG4gICAgLy8gYHRoaXMuY2hpbGRyZW5gLlxuICAgIHVwZGF0ZUNoaWxkcmVuKHZpZXcsIHBvcykge1xuICAgICAgICBsZXQgaW5saW5lID0gdGhpcy5ub2RlLmlubGluZUNvbnRlbnQsIG9mZiA9IHBvcztcbiAgICAgICAgbGV0IGNvbXBvc2l0aW9uID0gdmlldy5jb21wb3NpbmcgPyB0aGlzLmxvY2FsQ29tcG9zaXRpb25JbmZvKHZpZXcsIHBvcykgOiBudWxsO1xuICAgICAgICBsZXQgbG9jYWxDb21wb3NpdGlvbiA9IGNvbXBvc2l0aW9uICYmIGNvbXBvc2l0aW9uLnBvcyA+IC0xID8gY29tcG9zaXRpb24gOiBudWxsO1xuICAgICAgICBsZXQgY29tcG9zaXRpb25JbkNoaWxkID0gY29tcG9zaXRpb24gJiYgY29tcG9zaXRpb24ucG9zIDwgMDtcbiAgICAgICAgbGV0IHVwZGF0ZXIgPSBuZXcgVmlld1RyZWVVcGRhdGVyKHRoaXMsIGxvY2FsQ29tcG9zaXRpb24gJiYgbG9jYWxDb21wb3NpdGlvbi5ub2RlLCB2aWV3KTtcbiAgICAgICAgaXRlckRlY28odGhpcy5ub2RlLCB0aGlzLmlubmVyRGVjbywgKHdpZGdldCwgaSwgaW5zaWRlTm9kZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHdpZGdldC5zcGVjLm1hcmtzKVxuICAgICAgICAgICAgICAgIHVwZGF0ZXIuc3luY1RvTWFya3Mod2lkZ2V0LnNwZWMubWFya3MsIGlubGluZSwgdmlldywgaSk7XG4gICAgICAgICAgICBlbHNlIGlmICh3aWRnZXQudHlwZS5zaWRlID49IDAgJiYgIWluc2lkZU5vZGUpXG4gICAgICAgICAgICAgICAgdXBkYXRlci5zeW5jVG9NYXJrcyhpID09IHRoaXMubm9kZS5jaGlsZENvdW50ID8gTWFyay5ub25lIDogdGhpcy5ub2RlLmNoaWxkKGkpLm1hcmtzLCBpbmxpbmUsIHZpZXcsIGkpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIG5leHQgbm9kZSBpcyBhIGRlc2MgbWF0Y2hpbmcgdGhpcyB3aWRnZXQsIHJldXNlIGl0LFxuICAgICAgICAgICAgLy8gb3RoZXJ3aXNlIGluc2VydCB0aGUgd2lkZ2V0IGFzIGEgbmV3IHZpZXcgZGVzYy5cbiAgICAgICAgICAgIHVwZGF0ZXIucGxhY2VXaWRnZXQod2lkZ2V0LCB2aWV3LCBvZmYpO1xuICAgICAgICB9LCAoY2hpbGQsIG91dGVyRGVjbywgaW5uZXJEZWNvLCBpKSA9PiB7XG4gICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIHdyYXBwaW5nIG1hcmsgZGVzY3MgbWF0Y2ggdGhlIG5vZGUncyBtYXJrcy5cbiAgICAgICAgICAgIHVwZGF0ZXIuc3luY1RvTWFya3MoY2hpbGQubWFya3MsIGlubGluZSwgdmlldywgaSk7XG4gICAgICAgICAgICAvLyBUcnkgc2V2ZXJhbCBzdHJhdGVnaWVzIGZvciBkcmF3aW5nIHRoaXMgbm9kZVxuICAgICAgICAgICAgbGV0IGNvbXBJbmRleDtcbiAgICAgICAgICAgIGlmICh1cGRhdGVyLmZpbmROb2RlTWF0Y2goY2hpbGQsIG91dGVyRGVjbywgaW5uZXJEZWNvLCBpKSkgO1xuICAgICAgICAgICAgZWxzZSBpZiAoY29tcG9zaXRpb25JbkNoaWxkICYmIHZpZXcuc3RhdGUuc2VsZWN0aW9uLmZyb20gPiBvZmYgJiZcbiAgICAgICAgICAgICAgICB2aWV3LnN0YXRlLnNlbGVjdGlvbi50byA8IG9mZiArIGNoaWxkLm5vZGVTaXplICYmXG4gICAgICAgICAgICAgICAgKGNvbXBJbmRleCA9IHVwZGF0ZXIuZmluZEluZGV4V2l0aENoaWxkKGNvbXBvc2l0aW9uLm5vZGUpKSA+IC0xICYmXG4gICAgICAgICAgICAgICAgdXBkYXRlci51cGRhdGVOb2RlQXQoY2hpbGQsIG91dGVyRGVjbywgaW5uZXJEZWNvLCBjb21wSW5kZXgsIHZpZXcpKSA7XG4gICAgICAgICAgICBlbHNlIGlmICh1cGRhdGVyLnVwZGF0ZU5leHROb2RlKGNoaWxkLCBvdXRlckRlY28sIGlubmVyRGVjbywgdmlldywgaSwgb2ZmKSkgO1xuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQWRkIGl0IGFzIGEgbmV3IHZpZXdcbiAgICAgICAgICAgICAgICB1cGRhdGVyLmFkZE5vZGUoY2hpbGQsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3LCBvZmYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb2ZmICs9IGNoaWxkLm5vZGVTaXplO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gRHJvcCBhbGwgcmVtYWluaW5nIGRlc2NzIGFmdGVyIHRoZSBjdXJyZW50IHBvc2l0aW9uLlxuICAgICAgICB1cGRhdGVyLnN5bmNUb01hcmtzKFtdLCBpbmxpbmUsIHZpZXcsIDApO1xuICAgICAgICBpZiAodGhpcy5ub2RlLmlzVGV4dGJsb2NrKVxuICAgICAgICAgICAgdXBkYXRlci5hZGRUZXh0YmxvY2tIYWNrcygpO1xuICAgICAgICB1cGRhdGVyLmRlc3Ryb3lSZXN0KCk7XG4gICAgICAgIC8vIFN5bmMgdGhlIERPTSBpZiBhbnl0aGluZyBjaGFuZ2VkXG4gICAgICAgIGlmICh1cGRhdGVyLmNoYW5nZWQgfHwgdGhpcy5kaXJ0eSA9PSBDT05URU5UX0RJUlRZKSB7XG4gICAgICAgICAgICAvLyBNYXkgaGF2ZSB0byBwcm90ZWN0IGZvY3VzZWQgRE9NIGZyb20gYmVpbmcgY2hhbmdlZCBpZiBhIGNvbXBvc2l0aW9uIGlzIGFjdGl2ZVxuICAgICAgICAgICAgaWYgKGxvY2FsQ29tcG9zaXRpb24pXG4gICAgICAgICAgICAgICAgdGhpcy5wcm90ZWN0TG9jYWxDb21wb3NpdGlvbih2aWV3LCBsb2NhbENvbXBvc2l0aW9uKTtcbiAgICAgICAgICAgIHJlbmRlckRlc2NzKHRoaXMuY29udGVudERPTSwgdGhpcy5jaGlsZHJlbiwgdmlldyk7XG4gICAgICAgICAgICBpZiAoaW9zKVxuICAgICAgICAgICAgICAgIGlvc0hhY2tzKHRoaXMuZG9tKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsb2NhbENvbXBvc2l0aW9uSW5mbyh2aWV3LCBwb3MpIHtcbiAgICAgICAgLy8gT25seSBkbyBzb21ldGhpbmcgaWYgYm90aCB0aGUgc2VsZWN0aW9uIGFuZCBhIGZvY3VzZWQgdGV4dCBub2RlXG4gICAgICAgIC8vIGFyZSBpbnNpZGUgb2YgdGhpcyBub2RlXG4gICAgICAgIGxldCB7IGZyb20sIHRvIH0gPSB2aWV3LnN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgaWYgKCEodmlldy5zdGF0ZS5zZWxlY3Rpb24gaW5zdGFuY2VvZiBUZXh0U2VsZWN0aW9uKSB8fCBmcm9tIDwgcG9zIHx8IHRvID4gcG9zICsgdGhpcy5ub2RlLmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBsZXQgdGV4dE5vZGUgPSB2aWV3LmlucHV0LmNvbXBvc2l0aW9uTm9kZTtcbiAgICAgICAgaWYgKCF0ZXh0Tm9kZSB8fCAhdGhpcy5kb20uY29udGFpbnModGV4dE5vZGUucGFyZW50Tm9kZSkpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgaWYgKHRoaXMubm9kZS5pbmxpbmVDb250ZW50KSB7XG4gICAgICAgICAgICAvLyBGaW5kIHRoZSB0ZXh0IGluIHRoZSBmb2N1c2VkIG5vZGUgaW4gdGhlIG5vZGUsIHN0b3AgaWYgaXQncyBub3RcbiAgICAgICAgICAgIC8vIHRoZXJlIChtYXkgaGF2ZSBiZWVuIG1vZGlmaWVkIHRocm91Z2ggb3RoZXIgbWVhbnMsIGluIHdoaWNoXG4gICAgICAgICAgICAvLyBjYXNlIGl0IHNob3VsZCBvdmVyd3JpdHRlbilcbiAgICAgICAgICAgIGxldCB0ZXh0ID0gdGV4dE5vZGUubm9kZVZhbHVlO1xuICAgICAgICAgICAgbGV0IHRleHRQb3MgPSBmaW5kVGV4dEluRnJhZ21lbnQodGhpcy5ub2RlLmNvbnRlbnQsIHRleHQsIGZyb20gLSBwb3MsIHRvIC0gcG9zKTtcbiAgICAgICAgICAgIHJldHVybiB0ZXh0UG9zIDwgMCA/IG51bGwgOiB7IG5vZGU6IHRleHROb2RlLCBwb3M6IHRleHRQb3MsIHRleHQgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB7IG5vZGU6IHRleHROb2RlLCBwb3M6IC0xLCB0ZXh0OiBcIlwiIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcHJvdGVjdExvY2FsQ29tcG9zaXRpb24odmlldywgeyBub2RlLCBwb3MsIHRleHQgfSkge1xuICAgICAgICAvLyBUaGUgbm9kZSBpcyBhbHJlYWR5IHBhcnQgb2YgYSBsb2NhbCB2aWV3IGRlc2MsIGxlYXZlIGl0IHRoZXJlXG4gICAgICAgIGlmICh0aGlzLmdldERlc2Mobm9kZSkpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIC8vIENyZWF0ZSBhIGNvbXBvc2l0aW9uIHZpZXcgZm9yIHRoZSBvcnBoYW5lZCBub2Rlc1xuICAgICAgICBsZXQgdG9wTm9kZSA9IG5vZGU7XG4gICAgICAgIGZvciAoOzsgdG9wTm9kZSA9IHRvcE5vZGUucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgaWYgKHRvcE5vZGUucGFyZW50Tm9kZSA9PSB0aGlzLmNvbnRlbnRET00pXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB3aGlsZSAodG9wTm9kZS5wcmV2aW91c1NpYmxpbmcpXG4gICAgICAgICAgICAgICAgdG9wTm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRvcE5vZGUucHJldmlvdXNTaWJsaW5nKTtcbiAgICAgICAgICAgIHdoaWxlICh0b3BOb2RlLm5leHRTaWJsaW5nKVxuICAgICAgICAgICAgICAgIHRvcE5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0b3BOb2RlLm5leHRTaWJsaW5nKTtcbiAgICAgICAgICAgIGlmICh0b3BOb2RlLnBtVmlld0Rlc2MpXG4gICAgICAgICAgICAgICAgdG9wTm9kZS5wbVZpZXdEZXNjID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGxldCBkZXNjID0gbmV3IENvbXBvc2l0aW9uVmlld0Rlc2ModGhpcywgdG9wTm9kZSwgbm9kZSwgdGV4dCk7XG4gICAgICAgIHZpZXcuaW5wdXQuY29tcG9zaXRpb25Ob2Rlcy5wdXNoKGRlc2MpO1xuICAgICAgICAvLyBQYXRjaCB1cCB0aGlzLmNoaWxkcmVuIHRvIGNvbnRhaW4gdGhlIGNvbXBvc2l0aW9uIHZpZXdcbiAgICAgICAgdGhpcy5jaGlsZHJlbiA9IHJlcGxhY2VOb2Rlcyh0aGlzLmNoaWxkcmVuLCBwb3MsIHBvcyArIHRleHQubGVuZ3RoLCB2aWV3LCBkZXNjKTtcbiAgICB9XG4gICAgLy8gSWYgdGhpcyBkZXNjIG11c3QgYmUgdXBkYXRlZCB0byBtYXRjaCB0aGUgZ2l2ZW4gbm9kZSBkZWNvcmF0aW9uLFxuICAgIC8vIGRvIHNvIGFuZCByZXR1cm4gdHJ1ZS5cbiAgICB1cGRhdGUobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcpIHtcbiAgICAgICAgaWYgKHRoaXMuZGlydHkgPT0gTk9ERV9ESVJUWSB8fFxuICAgICAgICAgICAgIW5vZGUuc2FtZU1hcmt1cCh0aGlzLm5vZGUpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB0aGlzLnVwZGF0ZUlubmVyKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHVwZGF0ZUlubmVyKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3KSB7XG4gICAgICAgIHRoaXMudXBkYXRlT3V0ZXJEZWNvKG91dGVyRGVjbyk7XG4gICAgICAgIHRoaXMubm9kZSA9IG5vZGU7XG4gICAgICAgIHRoaXMuaW5uZXJEZWNvID0gaW5uZXJEZWNvO1xuICAgICAgICBpZiAodGhpcy5jb250ZW50RE9NKVxuICAgICAgICAgICAgdGhpcy51cGRhdGVDaGlsZHJlbih2aWV3LCB0aGlzLnBvc0F0U3RhcnQpO1xuICAgICAgICB0aGlzLmRpcnR5ID0gTk9UX0RJUlRZO1xuICAgIH1cbiAgICB1cGRhdGVPdXRlckRlY28ob3V0ZXJEZWNvKSB7XG4gICAgICAgIGlmIChzYW1lT3V0ZXJEZWNvKG91dGVyRGVjbywgdGhpcy5vdXRlckRlY28pKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBsZXQgbmVlZHNXcmFwID0gdGhpcy5ub2RlRE9NLm5vZGVUeXBlICE9IDE7XG4gICAgICAgIGxldCBvbGRET00gPSB0aGlzLmRvbTtcbiAgICAgICAgdGhpcy5kb20gPSBwYXRjaE91dGVyRGVjbyh0aGlzLmRvbSwgdGhpcy5ub2RlRE9NLCBjb21wdXRlT3V0ZXJEZWNvKHRoaXMub3V0ZXJEZWNvLCB0aGlzLm5vZGUsIG5lZWRzV3JhcCksIGNvbXB1dGVPdXRlckRlY28ob3V0ZXJEZWNvLCB0aGlzLm5vZGUsIG5lZWRzV3JhcCkpO1xuICAgICAgICBpZiAodGhpcy5kb20gIT0gb2xkRE9NKSB7XG4gICAgICAgICAgICBvbGRET00ucG1WaWV3RGVzYyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHRoaXMuZG9tLnBtVmlld0Rlc2MgPSB0aGlzO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3V0ZXJEZWNvID0gb3V0ZXJEZWNvO1xuICAgIH1cbiAgICAvLyBNYXJrIHRoaXMgbm9kZSBhcyBiZWluZyB0aGUgc2VsZWN0ZWQgbm9kZS5cbiAgICBzZWxlY3ROb2RlKCkge1xuICAgICAgICBpZiAodGhpcy5ub2RlRE9NLm5vZGVUeXBlID09IDEpIHtcbiAgICAgICAgICAgIHRoaXMubm9kZURPTS5jbGFzc0xpc3QuYWRkKFwiUHJvc2VNaXJyb3Itc2VsZWN0ZWRub2RlXCIpO1xuICAgICAgICAgICAgaWYgKHRoaXMuY29udGVudERPTSB8fCAhdGhpcy5ub2RlLnR5cGUuc3BlYy5kcmFnZ2FibGUpXG4gICAgICAgICAgICAgICAgdGhpcy5ub2RlRE9NLmRyYWdnYWJsZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gUmVtb3ZlIHNlbGVjdGVkIG5vZGUgbWFya2luZyBmcm9tIHRoaXMgbm9kZS5cbiAgICBkZXNlbGVjdE5vZGUoKSB7XG4gICAgICAgIGlmICh0aGlzLm5vZGVET00ubm9kZVR5cGUgPT0gMSkge1xuICAgICAgICAgICAgdGhpcy5ub2RlRE9NLmNsYXNzTGlzdC5yZW1vdmUoXCJQcm9zZU1pcnJvci1zZWxlY3RlZG5vZGVcIik7XG4gICAgICAgICAgICBpZiAodGhpcy5jb250ZW50RE9NIHx8ICF0aGlzLm5vZGUudHlwZS5zcGVjLmRyYWdnYWJsZSlcbiAgICAgICAgICAgICAgICB0aGlzLm5vZGVET00ucmVtb3ZlQXR0cmlidXRlKFwiZHJhZ2dhYmxlXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBkb21BdG9tKCkgeyByZXR1cm4gdGhpcy5ub2RlLmlzQXRvbTsgfVxufVxuLy8gQ3JlYXRlIGEgdmlldyBkZXNjIGZvciB0aGUgdG9wLWxldmVsIGRvY3VtZW50IG5vZGUsIHRvIGJlIGV4cG9ydGVkXG4vLyBhbmQgdXNlZCBieSB0aGUgdmlldyBjbGFzcy5cbmZ1bmN0aW9uIGRvY1ZpZXdEZXNjKGRvYywgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgdmlldykge1xuICAgIGFwcGx5T3V0ZXJEZWNvKGRvbSwgb3V0ZXJEZWNvLCBkb2MpO1xuICAgIGxldCBkb2NWaWV3ID0gbmV3IE5vZGVWaWV3RGVzYyh1bmRlZmluZWQsIGRvYywgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgZG9tLCBkb20sIHZpZXcsIDApO1xuICAgIGlmIChkb2NWaWV3LmNvbnRlbnRET00pXG4gICAgICAgIGRvY1ZpZXcudXBkYXRlQ2hpbGRyZW4odmlldywgMCk7XG4gICAgcmV0dXJuIGRvY1ZpZXc7XG59XG5jbGFzcyBUZXh0Vmlld0Rlc2MgZXh0ZW5kcyBOb2RlVmlld0Rlc2Mge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgbm9kZURPTSwgdmlldykge1xuICAgICAgICBzdXBlcihwYXJlbnQsIG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCBkb20sIG51bGwsIG5vZGVET00sIHZpZXcsIDApO1xuICAgIH1cbiAgICBwYXJzZVJ1bGUoKSB7XG4gICAgICAgIGxldCBza2lwID0gdGhpcy5ub2RlRE9NLnBhcmVudE5vZGU7XG4gICAgICAgIHdoaWxlIChza2lwICYmIHNraXAgIT0gdGhpcy5kb20gJiYgIXNraXAucG1Jc0RlY28pXG4gICAgICAgICAgICBza2lwID0gc2tpcC5wYXJlbnROb2RlO1xuICAgICAgICByZXR1cm4geyBza2lwOiAoc2tpcCB8fCB0cnVlKSB9O1xuICAgIH1cbiAgICB1cGRhdGUobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcpIHtcbiAgICAgICAgaWYgKHRoaXMuZGlydHkgPT0gTk9ERV9ESVJUWSB8fCAodGhpcy5kaXJ0eSAhPSBOT1RfRElSVFkgJiYgIXRoaXMuaW5QYXJlbnQoKSkgfHxcbiAgICAgICAgICAgICFub2RlLnNhbWVNYXJrdXAodGhpcy5ub2RlKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgdGhpcy51cGRhdGVPdXRlckRlY28ob3V0ZXJEZWNvKTtcbiAgICAgICAgaWYgKCh0aGlzLmRpcnR5ICE9IE5PVF9ESVJUWSB8fCBub2RlLnRleHQgIT0gdGhpcy5ub2RlLnRleHQpICYmIG5vZGUudGV4dCAhPSB0aGlzLm5vZGVET00ubm9kZVZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLm5vZGVET00ubm9kZVZhbHVlID0gbm9kZS50ZXh0O1xuICAgICAgICAgICAgaWYgKHZpZXcudHJhY2tXcml0ZXMgPT0gdGhpcy5ub2RlRE9NKVxuICAgICAgICAgICAgICAgIHZpZXcudHJhY2tXcml0ZXMgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm9kZSA9IG5vZGU7XG4gICAgICAgIHRoaXMuZGlydHkgPSBOT1RfRElSVFk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpblBhcmVudCgpIHtcbiAgICAgICAgbGV0IHBhcmVudERPTSA9IHRoaXMucGFyZW50LmNvbnRlbnRET007XG4gICAgICAgIGZvciAobGV0IG4gPSB0aGlzLm5vZGVET007IG47IG4gPSBuLnBhcmVudE5vZGUpXG4gICAgICAgICAgICBpZiAobiA9PSBwYXJlbnRET00pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZG9tRnJvbVBvcyhwb3MpIHtcbiAgICAgICAgcmV0dXJuIHsgbm9kZTogdGhpcy5ub2RlRE9NLCBvZmZzZXQ6IHBvcyB9O1xuICAgIH1cbiAgICBsb2NhbFBvc0Zyb21ET00oZG9tLCBvZmZzZXQsIGJpYXMpIHtcbiAgICAgICAgaWYgKGRvbSA9PSB0aGlzLm5vZGVET00pXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wb3NBdFN0YXJ0ICsgTWF0aC5taW4ob2Zmc2V0LCB0aGlzLm5vZGUudGV4dC5sZW5ndGgpO1xuICAgICAgICByZXR1cm4gc3VwZXIubG9jYWxQb3NGcm9tRE9NKGRvbSwgb2Zmc2V0LCBiaWFzKTtcbiAgICB9XG4gICAgaWdub3JlTXV0YXRpb24obXV0YXRpb24pIHtcbiAgICAgICAgcmV0dXJuIG11dGF0aW9uLnR5cGUgIT0gXCJjaGFyYWN0ZXJEYXRhXCIgJiYgbXV0YXRpb24udHlwZSAhPSBcInNlbGVjdGlvblwiO1xuICAgIH1cbiAgICBzbGljZShmcm9tLCB0bywgdmlldykge1xuICAgICAgICBsZXQgbm9kZSA9IHRoaXMubm9kZS5jdXQoZnJvbSwgdG8pLCBkb20gPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShub2RlLnRleHQpO1xuICAgICAgICByZXR1cm4gbmV3IFRleHRWaWV3RGVzYyh0aGlzLnBhcmVudCwgbm9kZSwgdGhpcy5vdXRlckRlY28sIHRoaXMuaW5uZXJEZWNvLCBkb20sIGRvbSwgdmlldyk7XG4gICAgfVxuICAgIG1hcmtEaXJ0eShmcm9tLCB0bykge1xuICAgICAgICBzdXBlci5tYXJrRGlydHkoZnJvbSwgdG8pO1xuICAgICAgICBpZiAodGhpcy5kb20gIT0gdGhpcy5ub2RlRE9NICYmIChmcm9tID09IDAgfHwgdG8gPT0gdGhpcy5ub2RlRE9NLm5vZGVWYWx1ZS5sZW5ndGgpKVxuICAgICAgICAgICAgdGhpcy5kaXJ0eSA9IE5PREVfRElSVFk7XG4gICAgfVxuICAgIGdldCBkb21BdG9tKCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICBpc1RleHQodGV4dCkgeyByZXR1cm4gdGhpcy5ub2RlLnRleHQgPT0gdGV4dDsgfVxufVxuLy8gQSBkdW1teSBkZXNjIHVzZWQgdG8gdGFnIHRyYWlsaW5nIEJSIG9yIElNRyBub2RlcyBjcmVhdGVkIHRvIHdvcmtcbi8vIGFyb3VuZCBjb250ZW50RWRpdGFibGUgdGVycmlibGVuZXNzLlxuY2xhc3MgVHJhaWxpbmdIYWNrVmlld0Rlc2MgZXh0ZW5kcyBWaWV3RGVzYyB7XG4gICAgcGFyc2VSdWxlKCkgeyByZXR1cm4geyBpZ25vcmU6IHRydWUgfTsgfVxuICAgIG1hdGNoZXNIYWNrKG5vZGVOYW1lKSB7IHJldHVybiB0aGlzLmRpcnR5ID09IE5PVF9ESVJUWSAmJiB0aGlzLmRvbS5ub2RlTmFtZSA9PSBub2RlTmFtZTsgfVxuICAgIGdldCBkb21BdG9tKCkgeyByZXR1cm4gdHJ1ZTsgfVxuICAgIGdldCBpZ25vcmVGb3JDb29yZHMoKSB7IHJldHVybiB0aGlzLmRvbS5ub2RlTmFtZSA9PSBcIklNR1wiOyB9XG59XG4vLyBBIHNlcGFyYXRlIHN1YmNsYXNzIGlzIHVzZWQgZm9yIGN1c3RvbWl6ZWQgbm9kZSB2aWV3cywgc28gdGhhdCB0aGVcbi8vIGV4dHJhIGNoZWNrcyBvbmx5IGhhdmUgdG8gYmUgbWFkZSBmb3Igbm9kZXMgdGhhdCBhcmUgYWN0dWFsbHlcbi8vIGN1c3RvbWl6ZWQuXG5jbGFzcyBDdXN0b21Ob2RlVmlld0Rlc2MgZXh0ZW5kcyBOb2RlVmlld0Rlc2Mge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgY29udGVudERPTSwgbm9kZURPTSwgc3BlYywgdmlldywgcG9zKSB7XG4gICAgICAgIHN1cGVyKHBhcmVudCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgY29udGVudERPTSwgbm9kZURPTSwgdmlldywgcG9zKTtcbiAgICAgICAgdGhpcy5zcGVjID0gc3BlYztcbiAgICB9XG4gICAgLy8gQSBjdXN0b20gYHVwZGF0ZWAgbWV0aG9kIGdldHMgdG8gZGVjaWRlIHdoZXRoZXIgdGhlIHVwZGF0ZSBnb2VzXG4gICAgLy8gdGhyb3VnaC4gSWYgaXQgZG9lcywgYW5kIHRoZXJlJ3MgYSBgY29udGVudERPTWAgbm9kZSwgb3VyIGxvZ2ljXG4gICAgLy8gdXBkYXRlcyB0aGUgY2hpbGRyZW4uXG4gICAgdXBkYXRlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3KSB7XG4gICAgICAgIGlmICh0aGlzLmRpcnR5ID09IE5PREVfRElSVFkpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLnNwZWMudXBkYXRlICYmICh0aGlzLm5vZGUudHlwZSA9PSBub2RlLnR5cGUgfHwgdGhpcy5zcGVjLm11bHRpVHlwZSkpIHtcbiAgICAgICAgICAgIGxldCByZXN1bHQgPSB0aGlzLnNwZWMudXBkYXRlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQpXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVJbm5lcihub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgdmlldyk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCF0aGlzLmNvbnRlbnRET00gJiYgIW5vZGUuaXNMZWFmKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIudXBkYXRlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZWxlY3ROb2RlKCkge1xuICAgICAgICB0aGlzLnNwZWMuc2VsZWN0Tm9kZSA/IHRoaXMuc3BlYy5zZWxlY3ROb2RlKCkgOiBzdXBlci5zZWxlY3ROb2RlKCk7XG4gICAgfVxuICAgIGRlc2VsZWN0Tm9kZSgpIHtcbiAgICAgICAgdGhpcy5zcGVjLmRlc2VsZWN0Tm9kZSA/IHRoaXMuc3BlYy5kZXNlbGVjdE5vZGUoKSA6IHN1cGVyLmRlc2VsZWN0Tm9kZSgpO1xuICAgIH1cbiAgICBzZXRTZWxlY3Rpb24oYW5jaG9yLCBoZWFkLCB2aWV3LCBmb3JjZSkge1xuICAgICAgICB0aGlzLnNwZWMuc2V0U2VsZWN0aW9uID8gdGhpcy5zcGVjLnNldFNlbGVjdGlvbihhbmNob3IsIGhlYWQsIHZpZXcucm9vdClcbiAgICAgICAgICAgIDogc3VwZXIuc2V0U2VsZWN0aW9uKGFuY2hvciwgaGVhZCwgdmlldywgZm9yY2UpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5zcGVjLmRlc3Ryb3kpXG4gICAgICAgICAgICB0aGlzLnNwZWMuZGVzdHJveSgpO1xuICAgICAgICBzdXBlci5kZXN0cm95KCk7XG4gICAgfVxuICAgIHN0b3BFdmVudChldmVudCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zcGVjLnN0b3BFdmVudCA/IHRoaXMuc3BlYy5zdG9wRXZlbnQoZXZlbnQpIDogZmFsc2U7XG4gICAgfVxuICAgIGlnbm9yZU11dGF0aW9uKG11dGF0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNwZWMuaWdub3JlTXV0YXRpb24gPyB0aGlzLnNwZWMuaWdub3JlTXV0YXRpb24obXV0YXRpb24pIDogc3VwZXIuaWdub3JlTXV0YXRpb24obXV0YXRpb24pO1xuICAgIH1cbn1cbi8vIFN5bmMgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIERPTSBub2RlIHdpdGggdGhlIG5vZGVzIGFzc29jaWF0ZWRcbi8vIHdpdGggdGhlIGdpdmVuIGFycmF5IG9mIHZpZXcgZGVzY3MsIHJlY3Vyc2luZyBpbnRvIG1hcmsgZGVzY3Ncbi8vIGJlY2F1c2UgdGhpcyBzaG91bGQgc3luYyB0aGUgc3VidHJlZSBmb3IgYSB3aG9sZSBub2RlIGF0IGEgdGltZS5cbmZ1bmN0aW9uIHJlbmRlckRlc2NzKHBhcmVudERPTSwgZGVzY3MsIHZpZXcpIHtcbiAgICBsZXQgZG9tID0gcGFyZW50RE9NLmZpcnN0Q2hpbGQsIHdyaXR0ZW4gPSBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlc2NzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBkZXNjID0gZGVzY3NbaV0sIGNoaWxkRE9NID0gZGVzYy5kb207XG4gICAgICAgIGlmIChjaGlsZERPTS5wYXJlbnROb2RlID09IHBhcmVudERPTSkge1xuICAgICAgICAgICAgd2hpbGUgKGNoaWxkRE9NICE9IGRvbSkge1xuICAgICAgICAgICAgICAgIGRvbSA9IHJtKGRvbSk7XG4gICAgICAgICAgICAgICAgd3JpdHRlbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb20gPSBkb20ubmV4dFNpYmxpbmc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB3cml0dGVuID0gdHJ1ZTtcbiAgICAgICAgICAgIHBhcmVudERPTS5pbnNlcnRCZWZvcmUoY2hpbGRET00sIGRvbSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlc2MgaW5zdGFuY2VvZiBNYXJrVmlld0Rlc2MpIHtcbiAgICAgICAgICAgIGxldCBwb3MgPSBkb20gPyBkb20ucHJldmlvdXNTaWJsaW5nIDogcGFyZW50RE9NLmxhc3RDaGlsZDtcbiAgICAgICAgICAgIHJlbmRlckRlc2NzKGRlc2MuY29udGVudERPTSwgZGVzYy5jaGlsZHJlbiwgdmlldyk7XG4gICAgICAgICAgICBkb20gPSBwb3MgPyBwb3MubmV4dFNpYmxpbmcgOiBwYXJlbnRET00uZmlyc3RDaGlsZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICB3aGlsZSAoZG9tKSB7XG4gICAgICAgIGRvbSA9IHJtKGRvbSk7XG4gICAgICAgIHdyaXR0ZW4gPSB0cnVlO1xuICAgIH1cbiAgICBpZiAod3JpdHRlbiAmJiB2aWV3LnRyYWNrV3JpdGVzID09IHBhcmVudERPTSlcbiAgICAgICAgdmlldy50cmFja1dyaXRlcyA9IG51bGw7XG59XG5jb25zdCBPdXRlckRlY29MZXZlbCA9IGZ1bmN0aW9uIChub2RlTmFtZSkge1xuICAgIGlmIChub2RlTmFtZSlcbiAgICAgICAgdGhpcy5ub2RlTmFtZSA9IG5vZGVOYW1lO1xufTtcbk91dGVyRGVjb0xldmVsLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5jb25zdCBub0RlY28gPSBbbmV3IE91dGVyRGVjb0xldmVsXTtcbmZ1bmN0aW9uIGNvbXB1dGVPdXRlckRlY28ob3V0ZXJEZWNvLCBub2RlLCBuZWVkc1dyYXApIHtcbiAgICBpZiAob3V0ZXJEZWNvLmxlbmd0aCA9PSAwKVxuICAgICAgICByZXR1cm4gbm9EZWNvO1xuICAgIGxldCB0b3AgPSBuZWVkc1dyYXAgPyBub0RlY29bMF0gOiBuZXcgT3V0ZXJEZWNvTGV2ZWwsIHJlc3VsdCA9IFt0b3BdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0ZXJEZWNvLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBhdHRycyA9IG91dGVyRGVjb1tpXS50eXBlLmF0dHJzO1xuICAgICAgICBpZiAoIWF0dHJzKVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGlmIChhdHRycy5ub2RlTmFtZSlcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHRvcCA9IG5ldyBPdXRlckRlY29MZXZlbChhdHRycy5ub2RlTmFtZSkpO1xuICAgICAgICBmb3IgKGxldCBuYW1lIGluIGF0dHJzKSB7XG4gICAgICAgICAgICBsZXQgdmFsID0gYXR0cnNbbmFtZV07XG4gICAgICAgICAgICBpZiAodmFsID09IG51bGwpXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICBpZiAobmVlZHNXcmFwICYmIHJlc3VsdC5sZW5ndGggPT0gMSlcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaCh0b3AgPSBuZXcgT3V0ZXJEZWNvTGV2ZWwobm9kZS5pc0lubGluZSA/IFwic3BhblwiIDogXCJkaXZcIikpO1xuICAgICAgICAgICAgaWYgKG5hbWUgPT0gXCJjbGFzc1wiKVxuICAgICAgICAgICAgICAgIHRvcC5jbGFzcyA9ICh0b3AuY2xhc3MgPyB0b3AuY2xhc3MgKyBcIiBcIiA6IFwiXCIpICsgdmFsO1xuICAgICAgICAgICAgZWxzZSBpZiAobmFtZSA9PSBcInN0eWxlXCIpXG4gICAgICAgICAgICAgICAgdG9wLnN0eWxlID0gKHRvcC5zdHlsZSA/IHRvcC5zdHlsZSArIFwiO1wiIDogXCJcIikgKyB2YWw7XG4gICAgICAgICAgICBlbHNlIGlmIChuYW1lICE9IFwibm9kZU5hbWVcIilcbiAgICAgICAgICAgICAgICB0b3BbbmFtZV0gPSB2YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIHBhdGNoT3V0ZXJEZWNvKG91dGVyRE9NLCBub2RlRE9NLCBwcmV2Q29tcHV0ZWQsIGN1ckNvbXB1dGVkKSB7XG4gICAgLy8gU2hvcnRjdXQgZm9yIHRyaXZpYWwgY2FzZVxuICAgIGlmIChwcmV2Q29tcHV0ZWQgPT0gbm9EZWNvICYmIGN1ckNvbXB1dGVkID09IG5vRGVjbylcbiAgICAgICAgcmV0dXJuIG5vZGVET007XG4gICAgbGV0IGN1ckRPTSA9IG5vZGVET007XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjdXJDb21wdXRlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgZGVjbyA9IGN1ckNvbXB1dGVkW2ldLCBwcmV2ID0gcHJldkNvbXB1dGVkW2ldO1xuICAgICAgICBpZiAoaSkge1xuICAgICAgICAgICAgbGV0IHBhcmVudDtcbiAgICAgICAgICAgIGlmIChwcmV2ICYmIHByZXYubm9kZU5hbWUgPT0gZGVjby5ub2RlTmFtZSAmJiBjdXJET00gIT0gb3V0ZXJET00gJiZcbiAgICAgICAgICAgICAgICAocGFyZW50ID0gY3VyRE9NLnBhcmVudE5vZGUpICYmIHBhcmVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09IGRlY28ubm9kZU5hbWUpIHtcbiAgICAgICAgICAgICAgICBjdXJET00gPSBwYXJlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGRlY28ubm9kZU5hbWUpO1xuICAgICAgICAgICAgICAgIHBhcmVudC5wbUlzRGVjbyA9IHRydWU7XG4gICAgICAgICAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKGN1ckRPTSk7XG4gICAgICAgICAgICAgICAgcHJldiA9IG5vRGVjb1swXTtcbiAgICAgICAgICAgICAgICBjdXJET00gPSBwYXJlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcGF0Y2hBdHRyaWJ1dGVzKGN1ckRPTSwgcHJldiB8fCBub0RlY29bMF0sIGRlY28pO1xuICAgIH1cbiAgICByZXR1cm4gY3VyRE9NO1xufVxuZnVuY3Rpb24gcGF0Y2hBdHRyaWJ1dGVzKGRvbSwgcHJldiwgY3VyKSB7XG4gICAgZm9yIChsZXQgbmFtZSBpbiBwcmV2KVxuICAgICAgICBpZiAobmFtZSAhPSBcImNsYXNzXCIgJiYgbmFtZSAhPSBcInN0eWxlXCIgJiYgbmFtZSAhPSBcIm5vZGVOYW1lXCIgJiYgIShuYW1lIGluIGN1cikpXG4gICAgICAgICAgICBkb20ucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgIGZvciAobGV0IG5hbWUgaW4gY3VyKVxuICAgICAgICBpZiAobmFtZSAhPSBcImNsYXNzXCIgJiYgbmFtZSAhPSBcInN0eWxlXCIgJiYgbmFtZSAhPSBcIm5vZGVOYW1lXCIgJiYgY3VyW25hbWVdICE9IHByZXZbbmFtZV0pXG4gICAgICAgICAgICBkb20uc2V0QXR0cmlidXRlKG5hbWUsIGN1cltuYW1lXSk7XG4gICAgaWYgKHByZXYuY2xhc3MgIT0gY3VyLmNsYXNzKSB7XG4gICAgICAgIGxldCBwcmV2TGlzdCA9IHByZXYuY2xhc3MgPyBwcmV2LmNsYXNzLnNwbGl0KFwiIFwiKS5maWx0ZXIoQm9vbGVhbikgOiBbXTtcbiAgICAgICAgbGV0IGN1ckxpc3QgPSBjdXIuY2xhc3MgPyBjdXIuY2xhc3Muc3BsaXQoXCIgXCIpLmZpbHRlcihCb29sZWFuKSA6IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXZMaXN0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKGN1ckxpc3QuaW5kZXhPZihwcmV2TGlzdFtpXSkgPT0gLTEpXG4gICAgICAgICAgICAgICAgZG9tLmNsYXNzTGlzdC5yZW1vdmUocHJldkxpc3RbaV0pO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGN1ckxpc3QubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAocHJldkxpc3QuaW5kZXhPZihjdXJMaXN0W2ldKSA9PSAtMSlcbiAgICAgICAgICAgICAgICBkb20uY2xhc3NMaXN0LmFkZChjdXJMaXN0W2ldKTtcbiAgICAgICAgaWYgKGRvbS5jbGFzc0xpc3QubGVuZ3RoID09IDApXG4gICAgICAgICAgICBkb20ucmVtb3ZlQXR0cmlidXRlKFwiY2xhc3NcIik7XG4gICAgfVxuICAgIGlmIChwcmV2LnN0eWxlICE9IGN1ci5zdHlsZSkge1xuICAgICAgICBpZiAocHJldi5zdHlsZSkge1xuICAgICAgICAgICAgbGV0IHByb3AgPSAvXFxzKihbXFx3XFwtXFx4YTEtXFx1ZmZmZl0rKVxccyo6KD86XCIoPzpcXFxcLnxbXlwiXSkqXCJ8Jyg/OlxcXFwufFteJ10pKid8XFwoLio/XFwpfFteO10pKi9nLCBtO1xuICAgICAgICAgICAgd2hpbGUgKG0gPSBwcm9wLmV4ZWMocHJldi5zdHlsZSkpXG4gICAgICAgICAgICAgICAgZG9tLnN0eWxlLnJlbW92ZVByb3BlcnR5KG1bMV0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjdXIuc3R5bGUpXG4gICAgICAgICAgICBkb20uc3R5bGUuY3NzVGV4dCArPSBjdXIuc3R5bGU7XG4gICAgfVxufVxuZnVuY3Rpb24gYXBwbHlPdXRlckRlY28oZG9tLCBkZWNvLCBub2RlKSB7XG4gICAgcmV0dXJuIHBhdGNoT3V0ZXJEZWNvKGRvbSwgZG9tLCBub0RlY28sIGNvbXB1dGVPdXRlckRlY28oZGVjbywgbm9kZSwgZG9tLm5vZGVUeXBlICE9IDEpKTtcbn1cbmZ1bmN0aW9uIHNhbWVPdXRlckRlY28oYSwgYikge1xuICAgIGlmIChhLmxlbmd0aCAhPSBiLmxlbmd0aClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKylcbiAgICAgICAgaWYgKCFhW2ldLnR5cGUuZXEoYltpXS50eXBlKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdHJ1ZTtcbn1cbi8vIFJlbW92ZSBhIERPTSBub2RlIGFuZCByZXR1cm4gaXRzIG5leHQgc2libGluZy5cbmZ1bmN0aW9uIHJtKGRvbSkge1xuICAgIGxldCBuZXh0ID0gZG9tLm5leHRTaWJsaW5nO1xuICAgIGRvbS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGRvbSk7XG4gICAgcmV0dXJuIG5leHQ7XG59XG4vLyBIZWxwZXIgY2xhc3MgZm9yIGluY3JlbWVudGFsbHkgdXBkYXRpbmcgYSB0cmVlIG9mIG1hcmsgZGVzY3MgYW5kXG4vLyB0aGUgd2lkZ2V0IGFuZCBub2RlIGRlc2NzIGluc2lkZSBvZiB0aGVtLlxuY2xhc3MgVmlld1RyZWVVcGRhdGVyIHtcbiAgICBjb25zdHJ1Y3Rvcih0b3AsIGxvY2ssIHZpZXcpIHtcbiAgICAgICAgdGhpcy5sb2NrID0gbG9jaztcbiAgICAgICAgdGhpcy52aWV3ID0gdmlldztcbiAgICAgICAgLy8gSW5kZXggaW50byBgdGhpcy50b3BgJ3MgY2hpbGQgYXJyYXksIHJlcHJlc2VudHMgdGhlIGN1cnJlbnRcbiAgICAgICAgLy8gdXBkYXRlIHBvc2l0aW9uLlxuICAgICAgICB0aGlzLmluZGV4ID0gMDtcbiAgICAgICAgLy8gV2hlbiBlbnRlcmluZyBhIG1hcmssIHRoZSBjdXJyZW50IHRvcCBhbmQgaW5kZXggYXJlIHB1c2hlZFxuICAgICAgICAvLyBvbnRvIHRoaXMuXG4gICAgICAgIHRoaXMuc3RhY2sgPSBbXTtcbiAgICAgICAgLy8gVHJhY2tzIHdoZXRoZXIgYW55dGhpbmcgd2FzIGNoYW5nZWRcbiAgICAgICAgdGhpcy5jaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMudG9wID0gdG9wO1xuICAgICAgICB0aGlzLnByZU1hdGNoID0gcHJlTWF0Y2godG9wLm5vZGUuY29udGVudCwgdG9wKTtcbiAgICB9XG4gICAgLy8gRGVzdHJveSBhbmQgcmVtb3ZlIHRoZSBjaGlsZHJlbiBiZXR3ZWVuIHRoZSBnaXZlbiBpbmRpY2VzIGluXG4gICAgLy8gYHRoaXMudG9wYC5cbiAgICBkZXN0cm95QmV0d2VlbihzdGFydCwgZW5kKSB7XG4gICAgICAgIGlmIChzdGFydCA9PSBlbmQpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKVxuICAgICAgICAgICAgdGhpcy50b3AuY2hpbGRyZW5baV0uZGVzdHJveSgpO1xuICAgICAgICB0aGlzLnRvcC5jaGlsZHJlbi5zcGxpY2Uoc3RhcnQsIGVuZCAtIHN0YXJ0KTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG4gICAgLy8gRGVzdHJveSBhbGwgcmVtYWluaW5nIGNoaWxkcmVuIGluIGB0aGlzLnRvcGAuXG4gICAgZGVzdHJveVJlc3QoKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveUJldHdlZW4odGhpcy5pbmRleCwgdGhpcy50b3AuY2hpbGRyZW4ubGVuZ3RoKTtcbiAgICB9XG4gICAgLy8gU3luYyB0aGUgY3VycmVudCBzdGFjayBvZiBtYXJrIGRlc2NzIHdpdGggdGhlIGdpdmVuIGFycmF5IG9mXG4gICAgLy8gbWFya3MsIHJldXNpbmcgZXhpc3RpbmcgbWFyayBkZXNjcyB3aGVuIHBvc3NpYmxlLlxuICAgIHN5bmNUb01hcmtzKG1hcmtzLCBpbmxpbmUsIHZpZXcsIHBhcmVudEluZGV4KSB7XG4gICAgICAgIGxldCBrZWVwID0gMCwgZGVwdGggPSB0aGlzLnN0YWNrLmxlbmd0aCA+PiAxO1xuICAgICAgICBsZXQgbWF4S2VlcCA9IE1hdGgubWluKGRlcHRoLCBtYXJrcy5sZW5ndGgpO1xuICAgICAgICB3aGlsZSAoa2VlcCA8IG1heEtlZXAgJiZcbiAgICAgICAgICAgIChrZWVwID09IGRlcHRoIC0gMSA/IHRoaXMudG9wIDogdGhpcy5zdGFja1soa2VlcCArIDEpIDw8IDFdKVxuICAgICAgICAgICAgICAgIC5tYXRjaGVzTWFyayhtYXJrc1trZWVwXSkgJiYgbWFya3Nba2VlcF0udHlwZS5zcGVjLnNwYW5uaW5nICE9PSBmYWxzZSlcbiAgICAgICAgICAgIGtlZXArKztcbiAgICAgICAgd2hpbGUgKGtlZXAgPCBkZXB0aCkge1xuICAgICAgICAgICAgdGhpcy5kZXN0cm95UmVzdCgpO1xuICAgICAgICAgICAgdGhpcy50b3AuZGlydHkgPSBOT1RfRElSVFk7XG4gICAgICAgICAgICB0aGlzLmluZGV4ID0gdGhpcy5zdGFjay5wb3AoKTtcbiAgICAgICAgICAgIHRoaXMudG9wID0gdGhpcy5zdGFjay5wb3AoKTtcbiAgICAgICAgICAgIGRlcHRoLS07XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGRlcHRoIDwgbWFya3MubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLnN0YWNrLnB1c2godGhpcy50b3AsIHRoaXMuaW5kZXggKyAxKTtcbiAgICAgICAgICAgIGxldCBmb3VuZCA9IC0xLCBzY2FuVG8gPSB0aGlzLnRvcC5jaGlsZHJlbi5sZW5ndGg7XG4gICAgICAgICAgICBpZiAocGFyZW50SW5kZXggPCB0aGlzLnByZU1hdGNoLmluZGV4KVxuICAgICAgICAgICAgICAgIHNjYW5UbyA9IE1hdGgubWluKHRoaXMuaW5kZXggKyAzLCBzY2FuVG8pO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuaW5kZXg7IGkgPCBzY2FuVG87IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gdGhpcy50b3AuY2hpbGRyZW5baV07XG4gICAgICAgICAgICAgICAgaWYgKG5leHQubWF0Y2hlc01hcmsobWFya3NbZGVwdGhdKSAmJiAhdGhpcy5pc0xvY2tlZChuZXh0LmRvbSkpIHtcbiAgICAgICAgICAgICAgICAgICAgZm91bmQgPSBpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZm91bmQgPiAtMSkge1xuICAgICAgICAgICAgICAgIGlmIChmb3VuZCA+IHRoaXMuaW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXN0cm95QmV0d2Vlbih0aGlzLmluZGV4LCBmb3VuZCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudG9wID0gdGhpcy50b3AuY2hpbGRyZW5bdGhpcy5pbmRleF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgbWFya0Rlc2MgPSBNYXJrVmlld0Rlc2MuY3JlYXRlKHRoaXMudG9wLCBtYXJrc1tkZXB0aF0sIGlubGluZSwgdmlldyk7XG4gICAgICAgICAgICAgICAgdGhpcy50b3AuY2hpbGRyZW4uc3BsaWNlKHRoaXMuaW5kZXgsIDAsIG1hcmtEZXNjKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRvcCA9IG1hcmtEZXNjO1xuICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmluZGV4ID0gMDtcbiAgICAgICAgICAgIGRlcHRoKys7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gVHJ5IHRvIGZpbmQgYSBub2RlIGRlc2MgbWF0Y2hpbmcgdGhlIGdpdmVuIGRhdGEuIFNraXAgb3ZlciBpdCBhbmRcbiAgICAvLyByZXR1cm4gdHJ1ZSB3aGVuIHN1Y2Nlc3NmdWwuXG4gICAgZmluZE5vZGVNYXRjaChub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgaW5kZXgpIHtcbiAgICAgICAgbGV0IGZvdW5kID0gLTEsIHRhcmdldERlc2M7XG4gICAgICAgIGlmIChpbmRleCA+PSB0aGlzLnByZU1hdGNoLmluZGV4ICYmXG4gICAgICAgICAgICAodGFyZ2V0RGVzYyA9IHRoaXMucHJlTWF0Y2gubWF0Y2hlc1tpbmRleCAtIHRoaXMucHJlTWF0Y2guaW5kZXhdKS5wYXJlbnQgPT0gdGhpcy50b3AgJiZcbiAgICAgICAgICAgIHRhcmdldERlc2MubWF0Y2hlc05vZGUobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28pKSB7XG4gICAgICAgICAgICBmb3VuZCA9IHRoaXMudG9wLmNoaWxkcmVuLmluZGV4T2YodGFyZ2V0RGVzYywgdGhpcy5pbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5pbmRleCwgZSA9IE1hdGgubWluKHRoaXMudG9wLmNoaWxkcmVuLmxlbmd0aCwgaSArIDUpOyBpIDwgZTsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IGNoaWxkID0gdGhpcy50b3AuY2hpbGRyZW5baV07XG4gICAgICAgICAgICAgICAgaWYgKGNoaWxkLm1hdGNoZXNOb2RlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvKSAmJiAhdGhpcy5wcmVNYXRjaC5tYXRjaGVkLmhhcyhjaGlsZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZm91bmQgPSBpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZvdW5kIDwgMClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgdGhpcy5kZXN0cm95QmV0d2Vlbih0aGlzLmluZGV4LCBmb3VuZCk7XG4gICAgICAgIHRoaXMuaW5kZXgrKztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHVwZGF0ZU5vZGVBdChub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgaW5kZXgsIHZpZXcpIHtcbiAgICAgICAgbGV0IGNoaWxkID0gdGhpcy50b3AuY2hpbGRyZW5baW5kZXhdO1xuICAgICAgICBpZiAoY2hpbGQuZGlydHkgPT0gTk9ERV9ESVJUWSAmJiBjaGlsZC5kb20gPT0gY2hpbGQuY29udGVudERPTSlcbiAgICAgICAgICAgIGNoaWxkLmRpcnR5ID0gQ09OVEVOVF9ESVJUWTtcbiAgICAgICAgaWYgKCFjaGlsZC51cGRhdGUobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB0aGlzLmRlc3Ryb3lCZXR3ZWVuKHRoaXMuaW5kZXgsIGluZGV4KTtcbiAgICAgICAgdGhpcy5pbmRleCsrO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgZmluZEluZGV4V2l0aENoaWxkKGRvbU5vZGUpIHtcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgICAgbGV0IHBhcmVudCA9IGRvbU5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgICAgIGlmICghcGFyZW50KVxuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgICAgIGlmIChwYXJlbnQgPT0gdGhpcy50b3AuY29udGVudERPTSkge1xuICAgICAgICAgICAgICAgIGxldCBkZXNjID0gZG9tTm9kZS5wbVZpZXdEZXNjO1xuICAgICAgICAgICAgICAgIGlmIChkZXNjKVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5pbmRleDsgaSA8IHRoaXMudG9wLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy50b3AuY2hpbGRyZW5baV0gPT0gZGVzYylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbU5vZGUgPSBwYXJlbnQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gVHJ5IHRvIHVwZGF0ZSB0aGUgbmV4dCBub2RlLCBpZiBhbnksIHRvIHRoZSBnaXZlbiBkYXRhLiBDaGVja3NcbiAgICAvLyBwcmUtbWF0Y2hlcyB0byBhdm9pZCBvdmVyd3JpdGluZyBub2RlcyB0aGF0IGNvdWxkIHN0aWxsIGJlIHVzZWQuXG4gICAgdXBkYXRlTmV4dE5vZGUobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcsIGluZGV4LCBwb3MpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuaW5kZXg7IGkgPCB0aGlzLnRvcC5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG5leHQgPSB0aGlzLnRvcC5jaGlsZHJlbltpXTtcbiAgICAgICAgICAgIGlmIChuZXh0IGluc3RhbmNlb2YgTm9kZVZpZXdEZXNjKSB7XG4gICAgICAgICAgICAgICAgbGV0IHByZU1hdGNoID0gdGhpcy5wcmVNYXRjaC5tYXRjaGVkLmdldChuZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAocHJlTWF0Y2ggIT0gbnVsbCAmJiBwcmVNYXRjaCAhPSBpbmRleClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIGxldCBuZXh0RE9NID0gbmV4dC5kb20sIHVwZGF0ZWQ7XG4gICAgICAgICAgICAgICAgLy8gQ2FuJ3QgdXBkYXRlIGlmIG5leHRET00gaXMgb3IgY29udGFpbnMgdGhpcy5sb2NrLCBleGNlcHQgaWZcbiAgICAgICAgICAgICAgICAvLyBpdCdzIGEgdGV4dCBub2RlIHdob3NlIGNvbnRlbnQgYWxyZWFkeSBtYXRjaGVzIHRoZSBuZXcgdGV4dFxuICAgICAgICAgICAgICAgIC8vIGFuZCB3aG9zZSBkZWNvcmF0aW9ucyBtYXRjaCB0aGUgbmV3IG9uZXMuXG4gICAgICAgICAgICAgICAgbGV0IGxvY2tlZCA9IHRoaXMuaXNMb2NrZWQobmV4dERPTSkgJiZcbiAgICAgICAgICAgICAgICAgICAgIShub2RlLmlzVGV4dCAmJiBuZXh0Lm5vZGUgJiYgbmV4dC5ub2RlLmlzVGV4dCAmJiBuZXh0Lm5vZGVET00ubm9kZVZhbHVlID09IG5vZGUudGV4dCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dC5kaXJ0eSAhPSBOT0RFX0RJUlRZICYmIHNhbWVPdXRlckRlY28ob3V0ZXJEZWNvLCBuZXh0Lm91dGVyRGVjbykpO1xuICAgICAgICAgICAgICAgIGlmICghbG9ja2VkICYmIG5leHQudXBkYXRlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3KSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRlc3Ryb3lCZXR3ZWVuKHRoaXMuaW5kZXgsIGkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dC5kb20gIT0gbmV4dERPTSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFsb2NrZWQgJiYgKHVwZGF0ZWQgPSB0aGlzLnJlY3JlYXRlV3JhcHBlcihuZXh0LCBub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgdmlldywgcG9zKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXN0cm95QmV0d2Vlbih0aGlzLmluZGV4LCBpKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b3AuY2hpbGRyZW5bdGhpcy5pbmRleF0gPSB1cGRhdGVkO1xuICAgICAgICAgICAgICAgICAgICBpZiAodXBkYXRlZC5jb250ZW50RE9NKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkLmRpcnR5ID0gQ09OVEVOVF9ESVJUWTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZWQudXBkYXRlQ2hpbGRyZW4odmlldywgcG9zICsgMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkLmRpcnR5ID0gTk9UX0RJUlRZO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gV2hlbiBhIG5vZGUgd2l0aCBjb250ZW50IGlzIHJlcGxhY2VkIGJ5IGEgZGlmZmVyZW50IG5vZGUgd2l0aFxuICAgIC8vIGlkZW50aWNhbCBjb250ZW50LCBtb3ZlIG92ZXIgaXRzIGNoaWxkcmVuLlxuICAgIHJlY3JlYXRlV3JhcHBlcihuZXh0LCBub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgdmlldywgcG9zKSB7XG4gICAgICAgIGlmIChuZXh0LmRpcnR5IHx8IG5vZGUuaXNBdG9tIHx8ICFuZXh0LmNoaWxkcmVuLmxlbmd0aCB8fFxuICAgICAgICAgICAgIW5leHQubm9kZS5jb250ZW50LmVxKG5vZGUuY29udGVudCkgfHxcbiAgICAgICAgICAgICFzYW1lT3V0ZXJEZWNvKG91dGVyRGVjbywgbmV4dC5vdXRlckRlY28pIHx8ICFpbm5lckRlY28uZXEobmV4dC5pbm5lckRlY28pKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGxldCB3cmFwcGVyID0gTm9kZVZpZXdEZXNjLmNyZWF0ZSh0aGlzLnRvcCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcsIHBvcyk7XG4gICAgICAgIGlmICh3cmFwcGVyLmNvbnRlbnRET00pIHtcbiAgICAgICAgICAgIHdyYXBwZXIuY2hpbGRyZW4gPSBuZXh0LmNoaWxkcmVuO1xuICAgICAgICAgICAgbmV4dC5jaGlsZHJlbiA9IFtdO1xuICAgICAgICAgICAgZm9yIChsZXQgY2ggb2Ygd3JhcHBlci5jaGlsZHJlbilcbiAgICAgICAgICAgICAgICBjaC5wYXJlbnQgPSB3cmFwcGVyO1xuICAgICAgICB9XG4gICAgICAgIG5leHQuZGVzdHJveSgpO1xuICAgICAgICByZXR1cm4gd3JhcHBlcjtcbiAgICB9XG4gICAgLy8gSW5zZXJ0IHRoZSBub2RlIGFzIGEgbmV3bHkgY3JlYXRlZCBub2RlIGRlc2MuXG4gICAgYWRkTm9kZShub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgdmlldywgcG9zKSB7XG4gICAgICAgIGxldCBkZXNjID0gTm9kZVZpZXdEZXNjLmNyZWF0ZSh0aGlzLnRvcCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcsIHBvcyk7XG4gICAgICAgIGlmIChkZXNjLmNvbnRlbnRET00pXG4gICAgICAgICAgICBkZXNjLnVwZGF0ZUNoaWxkcmVuKHZpZXcsIHBvcyArIDEpO1xuICAgICAgICB0aGlzLnRvcC5jaGlsZHJlbi5zcGxpY2UodGhpcy5pbmRleCsrLCAwLCBkZXNjKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG4gICAgcGxhY2VXaWRnZXQod2lkZ2V0LCB2aWV3LCBwb3MpIHtcbiAgICAgICAgbGV0IG5leHQgPSB0aGlzLmluZGV4IDwgdGhpcy50b3AuY2hpbGRyZW4ubGVuZ3RoID8gdGhpcy50b3AuY2hpbGRyZW5bdGhpcy5pbmRleF0gOiBudWxsO1xuICAgICAgICBpZiAobmV4dCAmJiBuZXh0Lm1hdGNoZXNXaWRnZXQod2lkZ2V0KSAmJlxuICAgICAgICAgICAgKHdpZGdldCA9PSBuZXh0LndpZGdldCB8fCAhbmV4dC53aWRnZXQudHlwZS50b0RPTS5wYXJlbnROb2RlKSkge1xuICAgICAgICAgICAgdGhpcy5pbmRleCsrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IGRlc2MgPSBuZXcgV2lkZ2V0Vmlld0Rlc2ModGhpcy50b3AsIHdpZGdldCwgdmlldywgcG9zKTtcbiAgICAgICAgICAgIHRoaXMudG9wLmNoaWxkcmVuLnNwbGljZSh0aGlzLmluZGV4KyssIDAsIGRlc2MpO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBNYWtlIHN1cmUgYSB0ZXh0YmxvY2sgbG9va3MgYW5kIGJlaGF2ZXMgY29ycmVjdGx5IGluXG4gICAgLy8gY29udGVudEVkaXRhYmxlLlxuICAgIGFkZFRleHRibG9ja0hhY2tzKCkge1xuICAgICAgICBsZXQgbGFzdENoaWxkID0gdGhpcy50b3AuY2hpbGRyZW5bdGhpcy5pbmRleCAtIDFdLCBwYXJlbnQgPSB0aGlzLnRvcDtcbiAgICAgICAgd2hpbGUgKGxhc3RDaGlsZCBpbnN0YW5jZW9mIE1hcmtWaWV3RGVzYykge1xuICAgICAgICAgICAgcGFyZW50ID0gbGFzdENoaWxkO1xuICAgICAgICAgICAgbGFzdENoaWxkID0gcGFyZW50LmNoaWxkcmVuW3BhcmVudC5jaGlsZHJlbi5sZW5ndGggLSAxXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWxhc3RDaGlsZCB8fCAvLyBFbXB0eSB0ZXh0YmxvY2tcbiAgICAgICAgICAgICEobGFzdENoaWxkIGluc3RhbmNlb2YgVGV4dFZpZXdEZXNjKSB8fFxuICAgICAgICAgICAgL1xcbiQvLnRlc3QobGFzdENoaWxkLm5vZGUudGV4dCkgfHxcbiAgICAgICAgICAgICh0aGlzLnZpZXcucmVxdWlyZXNHZWNrb0hhY2tOb2RlICYmIC9cXHMkLy50ZXN0KGxhc3RDaGlsZC5ub2RlLnRleHQpKSkge1xuICAgICAgICAgICAgLy8gQXZvaWQgYnVncyBpbiBTYWZhcmkncyBjdXJzb3IgZHJhd2luZyAoIzExNjUpIGFuZCBDaHJvbWUncyBtb3VzZSBzZWxlY3Rpb24gKCMxMTUyKVxuICAgICAgICAgICAgaWYgKChzYWZhcmkgfHwgY2hyb21lKSAmJiBsYXN0Q2hpbGQgJiYgbGFzdENoaWxkLmRvbS5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKVxuICAgICAgICAgICAgICAgIHRoaXMuYWRkSGFja05vZGUoXCJJTUdcIiwgcGFyZW50KTtcbiAgICAgICAgICAgIHRoaXMuYWRkSGFja05vZGUoXCJCUlwiLCB0aGlzLnRvcCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgYWRkSGFja05vZGUobm9kZU5hbWUsIHBhcmVudCkge1xuICAgICAgICBpZiAocGFyZW50ID09IHRoaXMudG9wICYmIHRoaXMuaW5kZXggPCBwYXJlbnQuY2hpbGRyZW4ubGVuZ3RoICYmIHBhcmVudC5jaGlsZHJlblt0aGlzLmluZGV4XS5tYXRjaGVzSGFjayhub2RlTmFtZSkpIHtcbiAgICAgICAgICAgIHRoaXMuaW5kZXgrKztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBkb20gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KG5vZGVOYW1lKTtcbiAgICAgICAgICAgIGlmIChub2RlTmFtZSA9PSBcIklNR1wiKSB7XG4gICAgICAgICAgICAgICAgZG9tLmNsYXNzTmFtZSA9IFwiUHJvc2VNaXJyb3Itc2VwYXJhdG9yXCI7XG4gICAgICAgICAgICAgICAgZG9tLmFsdCA9IFwiXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobm9kZU5hbWUgPT0gXCJCUlwiKVxuICAgICAgICAgICAgICAgIGRvbS5jbGFzc05hbWUgPSBcIlByb3NlTWlycm9yLXRyYWlsaW5nQnJlYWtcIjtcbiAgICAgICAgICAgIGxldCBoYWNrID0gbmV3IFRyYWlsaW5nSGFja1ZpZXdEZXNjKHRoaXMudG9wLCBbXSwgZG9tLCBudWxsKTtcbiAgICAgICAgICAgIGlmIChwYXJlbnQgIT0gdGhpcy50b3ApXG4gICAgICAgICAgICAgICAgcGFyZW50LmNoaWxkcmVuLnB1c2goaGFjayk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgcGFyZW50LmNoaWxkcmVuLnNwbGljZSh0aGlzLmluZGV4KyssIDAsIGhhY2spO1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpc0xvY2tlZChub2RlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxvY2sgJiYgKG5vZGUgPT0gdGhpcy5sb2NrIHx8IG5vZGUubm9kZVR5cGUgPT0gMSAmJiBub2RlLmNvbnRhaW5zKHRoaXMubG9jay5wYXJlbnROb2RlKSk7XG4gICAgfVxufVxuLy8gSXRlcmF0ZSBmcm9tIHRoZSBlbmQgb2YgdGhlIGZyYWdtZW50IGFuZCBhcnJheSBvZiBkZXNjcyB0byBmaW5kXG4vLyBkaXJlY3RseSBtYXRjaGluZyBvbmVzLCBpbiBvcmRlciB0byBhdm9pZCBvdmVyZWFnZXJseSByZXVzaW5nIHRob3NlXG4vLyBmb3Igb3RoZXIgbm9kZXMuXG5mdW5jdGlvbiBwcmVNYXRjaChmcmFnLCBwYXJlbnREZXNjKSB7XG4gICAgbGV0IGN1ckRlc2MgPSBwYXJlbnREZXNjLCBkZXNjSSA9IGN1ckRlc2MuY2hpbGRyZW4ubGVuZ3RoO1xuICAgIGxldCBmSSA9IGZyYWcuY2hpbGRDb3VudCwgbWF0Y2hlZCA9IG5ldyBNYXAsIG1hdGNoZXMgPSBbXTtcbiAgICBvdXRlcjogd2hpbGUgKGZJID4gMCkge1xuICAgICAgICBsZXQgZGVzYztcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgICAgaWYgKGRlc2NJKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5leHQgPSBjdXJEZXNjLmNoaWxkcmVuW2Rlc2NJIC0gMV07XG4gICAgICAgICAgICAgICAgaWYgKG5leHQgaW5zdGFuY2VvZiBNYXJrVmlld0Rlc2MpIHtcbiAgICAgICAgICAgICAgICAgICAgY3VyRGVzYyA9IG5leHQ7XG4gICAgICAgICAgICAgICAgICAgIGRlc2NJID0gbmV4dC5jaGlsZHJlbi5sZW5ndGg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkZXNjID0gbmV4dDtcbiAgICAgICAgICAgICAgICAgICAgZGVzY0ktLTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY3VyRGVzYyA9PSBwYXJlbnREZXNjKSB7XG4gICAgICAgICAgICAgICAgYnJlYWsgb3V0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZXNjSSA9IGN1ckRlc2MucGFyZW50LmNoaWxkcmVuLmluZGV4T2YoY3VyRGVzYyk7XG4gICAgICAgICAgICAgICAgY3VyRGVzYyA9IGN1ckRlc2MucGFyZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBub2RlID0gZGVzYy5ub2RlO1xuICAgICAgICBpZiAoIW5vZGUpXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgaWYgKG5vZGUgIT0gZnJhZy5jaGlsZChmSSAtIDEpKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIC0tZkk7XG4gICAgICAgIG1hdGNoZWQuc2V0KGRlc2MsIGZJKTtcbiAgICAgICAgbWF0Y2hlcy5wdXNoKGRlc2MpO1xuICAgIH1cbiAgICByZXR1cm4geyBpbmRleDogZkksIG1hdGNoZWQsIG1hdGNoZXM6IG1hdGNoZXMucmV2ZXJzZSgpIH07XG59XG5mdW5jdGlvbiBjb21wYXJlU2lkZShhLCBiKSB7XG4gICAgcmV0dXJuIGEudHlwZS5zaWRlIC0gYi50eXBlLnNpZGU7XG59XG4vLyBUaGlzIGZ1bmN0aW9uIGFic3RyYWN0cyBpdGVyYXRpbmcgb3ZlciB0aGUgbm9kZXMgYW5kIGRlY29yYXRpb25zIGluXG4vLyBhIGZyYWdtZW50LiBDYWxscyBgb25Ob2RlYCBmb3IgZWFjaCBub2RlLCB3aXRoIGl0cyBsb2NhbCBhbmQgY2hpbGRcbi8vIGRlY29yYXRpb25zLiBTcGxpdHMgdGV4dCBub2RlcyB3aGVuIHRoZXJlIGlzIGEgZGVjb3JhdGlvbiBzdGFydGluZ1xuLy8gb3IgZW5kaW5nIGluc2lkZSBvZiB0aGVtLiBDYWxscyBgb25XaWRnZXRgIGZvciBlYWNoIHdpZGdldC5cbmZ1bmN0aW9uIGl0ZXJEZWNvKHBhcmVudCwgZGVjbywgb25XaWRnZXQsIG9uTm9kZSkge1xuICAgIGxldCBsb2NhbHMgPSBkZWNvLmxvY2FscyhwYXJlbnQpLCBvZmZzZXQgPSAwO1xuICAgIC8vIFNpbXBsZSwgY2hlYXAgdmFyaWFudCBmb3Igd2hlbiB0aGVyZSBhcmUgbm8gbG9jYWwgZGVjb3JhdGlvbnNcbiAgICBpZiAobG9jYWxzLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyZW50LmNoaWxkQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgbGV0IGNoaWxkID0gcGFyZW50LmNoaWxkKGkpO1xuICAgICAgICAgICAgb25Ob2RlKGNoaWxkLCBsb2NhbHMsIGRlY28uZm9yQ2hpbGQob2Zmc2V0LCBjaGlsZCksIGkpO1xuICAgICAgICAgICAgb2Zmc2V0ICs9IGNoaWxkLm5vZGVTaXplO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IGRlY29JbmRleCA9IDAsIGFjdGl2ZSA9IFtdLCByZXN0Tm9kZSA9IG51bGw7XG4gICAgZm9yIChsZXQgcGFyZW50SW5kZXggPSAwOzspIHtcbiAgICAgICAgbGV0IHdpZGdldCwgd2lkZ2V0cztcbiAgICAgICAgd2hpbGUgKGRlY29JbmRleCA8IGxvY2Fscy5sZW5ndGggJiYgbG9jYWxzW2RlY29JbmRleF0udG8gPT0gb2Zmc2V0KSB7XG4gICAgICAgICAgICBsZXQgbmV4dCA9IGxvY2Fsc1tkZWNvSW5kZXgrK107XG4gICAgICAgICAgICBpZiAobmV4dC53aWRnZXQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXdpZGdldClcbiAgICAgICAgICAgICAgICAgICAgd2lkZ2V0ID0gbmV4dDtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICh3aWRnZXRzIHx8ICh3aWRnZXRzID0gW3dpZGdldF0pKS5wdXNoKG5leHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh3aWRnZXQpIHtcbiAgICAgICAgICAgIGlmICh3aWRnZXRzKSB7XG4gICAgICAgICAgICAgICAgd2lkZ2V0cy5zb3J0KGNvbXBhcmVTaWRlKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHdpZGdldHMubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgICAgIG9uV2lkZ2V0KHdpZGdldHNbaV0sIHBhcmVudEluZGV4LCAhIXJlc3ROb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG9uV2lkZ2V0KHdpZGdldCwgcGFyZW50SW5kZXgsICEhcmVzdE5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBjaGlsZCwgaW5kZXg7XG4gICAgICAgIGlmIChyZXN0Tm9kZSkge1xuICAgICAgICAgICAgaW5kZXggPSAtMTtcbiAgICAgICAgICAgIGNoaWxkID0gcmVzdE5vZGU7XG4gICAgICAgICAgICByZXN0Tm9kZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAocGFyZW50SW5kZXggPCBwYXJlbnQuY2hpbGRDb3VudCkge1xuICAgICAgICAgICAgaW5kZXggPSBwYXJlbnRJbmRleDtcbiAgICAgICAgICAgIGNoaWxkID0gcGFyZW50LmNoaWxkKHBhcmVudEluZGV4KyspO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhY3RpdmUubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAoYWN0aXZlW2ldLnRvIDw9IG9mZnNldClcbiAgICAgICAgICAgICAgICBhY3RpdmUuc3BsaWNlKGktLSwgMSk7XG4gICAgICAgIHdoaWxlIChkZWNvSW5kZXggPCBsb2NhbHMubGVuZ3RoICYmIGxvY2Fsc1tkZWNvSW5kZXhdLmZyb20gPD0gb2Zmc2V0ICYmIGxvY2Fsc1tkZWNvSW5kZXhdLnRvID4gb2Zmc2V0KVxuICAgICAgICAgICAgYWN0aXZlLnB1c2gobG9jYWxzW2RlY29JbmRleCsrXSk7XG4gICAgICAgIGxldCBlbmQgPSBvZmZzZXQgKyBjaGlsZC5ub2RlU2l6ZTtcbiAgICAgICAgaWYgKGNoaWxkLmlzVGV4dCkge1xuICAgICAgICAgICAgbGV0IGN1dEF0ID0gZW5kO1xuICAgICAgICAgICAgaWYgKGRlY29JbmRleCA8IGxvY2Fscy5sZW5ndGggJiYgbG9jYWxzW2RlY29JbmRleF0uZnJvbSA8IGN1dEF0KVxuICAgICAgICAgICAgICAgIGN1dEF0ID0gbG9jYWxzW2RlY29JbmRleF0uZnJvbTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWN0aXZlLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIGlmIChhY3RpdmVbaV0udG8gPCBjdXRBdClcbiAgICAgICAgICAgICAgICAgICAgY3V0QXQgPSBhY3RpdmVbaV0udG87XG4gICAgICAgICAgICBpZiAoY3V0QXQgPCBlbmQpIHtcbiAgICAgICAgICAgICAgICByZXN0Tm9kZSA9IGNoaWxkLmN1dChjdXRBdCAtIG9mZnNldCk7XG4gICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5jdXQoMCwgY3V0QXQgLSBvZmZzZXQpO1xuICAgICAgICAgICAgICAgIGVuZCA9IGN1dEF0O1xuICAgICAgICAgICAgICAgIGluZGV4ID0gLTE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB3aGlsZSAoZGVjb0luZGV4IDwgbG9jYWxzLmxlbmd0aCAmJiBsb2NhbHNbZGVjb0luZGV4XS50byA8IGVuZClcbiAgICAgICAgICAgICAgICBkZWNvSW5kZXgrKztcbiAgICAgICAgfVxuICAgICAgICBsZXQgb3V0ZXJEZWNvID0gY2hpbGQuaXNJbmxpbmUgJiYgIWNoaWxkLmlzTGVhZiA/IGFjdGl2ZS5maWx0ZXIoZCA9PiAhZC5pbmxpbmUpIDogYWN0aXZlLnNsaWNlKCk7XG4gICAgICAgIG9uTm9kZShjaGlsZCwgb3V0ZXJEZWNvLCBkZWNvLmZvckNoaWxkKG9mZnNldCwgY2hpbGQpLCBpbmRleCk7XG4gICAgICAgIG9mZnNldCA9IGVuZDtcbiAgICB9XG59XG4vLyBMaXN0IG1hcmtlcnMgaW4gTW9iaWxlIFNhZmFyaSB3aWxsIG15c3RlcmlvdXNseSBkaXNhcHBlYXJcbi8vIHNvbWV0aW1lcy4gVGhpcyB3b3JrcyBhcm91bmQgdGhhdC5cbmZ1bmN0aW9uIGlvc0hhY2tzKGRvbSkge1xuICAgIGlmIChkb20ubm9kZU5hbWUgPT0gXCJVTFwiIHx8IGRvbS5ub2RlTmFtZSA9PSBcIk9MXCIpIHtcbiAgICAgICAgbGV0IG9sZENTUyA9IGRvbS5zdHlsZS5jc3NUZXh0O1xuICAgICAgICBkb20uc3R5bGUuY3NzVGV4dCA9IG9sZENTUyArIFwiOyBsaXN0LXN0eWxlOiBzcXVhcmUgIWltcG9ydGFudFwiO1xuICAgICAgICB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkb20pLmxpc3RTdHlsZTtcbiAgICAgICAgZG9tLnN0eWxlLmNzc1RleHQgPSBvbGRDU1M7XG4gICAgfVxufVxuLy8gRmluZCBhIHBpZWNlIG9mIHRleHQgaW4gYW4gaW5saW5lIGZyYWdtZW50LCBvdmVybGFwcGluZyBmcm9tLXRvXG5mdW5jdGlvbiBmaW5kVGV4dEluRnJhZ21lbnQoZnJhZywgdGV4dCwgZnJvbSwgdG8pIHtcbiAgICBmb3IgKGxldCBpID0gMCwgcG9zID0gMDsgaSA8IGZyYWcuY2hpbGRDb3VudCAmJiBwb3MgPD0gdG87KSB7XG4gICAgICAgIGxldCBjaGlsZCA9IGZyYWcuY2hpbGQoaSsrKSwgY2hpbGRTdGFydCA9IHBvcztcbiAgICAgICAgcG9zICs9IGNoaWxkLm5vZGVTaXplO1xuICAgICAgICBpZiAoIWNoaWxkLmlzVGV4dClcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBsZXQgc3RyID0gY2hpbGQudGV4dDtcbiAgICAgICAgd2hpbGUgKGkgPCBmcmFnLmNoaWxkQ291bnQpIHtcbiAgICAgICAgICAgIGxldCBuZXh0ID0gZnJhZy5jaGlsZChpKyspO1xuICAgICAgICAgICAgcG9zICs9IG5leHQubm9kZVNpemU7XG4gICAgICAgICAgICBpZiAoIW5leHQuaXNUZXh0KVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgc3RyICs9IG5leHQudGV4dDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zID49IGZyb20pIHtcbiAgICAgICAgICAgIGlmIChwb3MgPj0gdG8gJiYgc3RyLnNsaWNlKHRvIC0gdGV4dC5sZW5ndGggLSBjaGlsZFN0YXJ0LCB0byAtIGNoaWxkU3RhcnQpID09IHRleHQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRvIC0gdGV4dC5sZW5ndGg7XG4gICAgICAgICAgICBsZXQgZm91bmQgPSBjaGlsZFN0YXJ0IDwgdG8gPyBzdHIubGFzdEluZGV4T2YodGV4dCwgdG8gLSBjaGlsZFN0YXJ0IC0gMSkgOiAtMTtcbiAgICAgICAgICAgIGlmIChmb3VuZCA+PSAwICYmIGZvdW5kICsgdGV4dC5sZW5ndGggKyBjaGlsZFN0YXJ0ID49IGZyb20pXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkU3RhcnQgKyBmb3VuZDtcbiAgICAgICAgICAgIGlmIChmcm9tID09IHRvICYmIHN0ci5sZW5ndGggPj0gKHRvICsgdGV4dC5sZW5ndGgpIC0gY2hpbGRTdGFydCAmJlxuICAgICAgICAgICAgICAgIHN0ci5zbGljZSh0byAtIGNoaWxkU3RhcnQsIHRvIC0gY2hpbGRTdGFydCArIHRleHQubGVuZ3RoKSA9PSB0ZXh0KVxuICAgICAgICAgICAgICAgIHJldHVybiB0bztcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG59XG4vLyBSZXBsYWNlIHJhbmdlIGZyb20tdG8gaW4gYW4gYXJyYXkgb2YgdmlldyBkZXNjcyB3aXRoIHJlcGxhY2VtZW50XG4vLyAobWF5IGJlIG51bGwgdG8ganVzdCBkZWxldGUpLiBUaGlzIGdvZXMgdmVyeSBtdWNoIGFnYWluc3QgdGhlIGdyYWluXG4vLyBvZiB0aGUgcmVzdCBvZiB0aGlzIGNvZGUsIHdoaWNoIHRlbmRzIHRvIGNyZWF0ZSBub2RlcyB3aXRoIHRoZVxuLy8gcmlnaHQgc2hhcGUgaW4gb25lIGdvLCByYXRoZXIgdGhhbiBtZXNzaW5nIHdpdGggdGhlbSBhZnRlclxuLy8gY3JlYXRpb24sIGJ1dCBpcyBuZWNlc3NhcnkgaW4gdGhlIGNvbXBvc2l0aW9uIGhhY2suXG5mdW5jdGlvbiByZXBsYWNlTm9kZXMobm9kZXMsIGZyb20sIHRvLCB2aWV3LCByZXBsYWNlbWVudCkge1xuICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMCwgb2ZmID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBjaGlsZCA9IG5vZGVzW2ldLCBzdGFydCA9IG9mZiwgZW5kID0gb2ZmICs9IGNoaWxkLnNpemU7XG4gICAgICAgIGlmIChzdGFydCA+PSB0byB8fCBlbmQgPD0gZnJvbSkge1xuICAgICAgICAgICAgcmVzdWx0LnB1c2goY2hpbGQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKHN0YXJ0IDwgZnJvbSlcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChjaGlsZC5zbGljZSgwLCBmcm9tIC0gc3RhcnQsIHZpZXcpKTtcbiAgICAgICAgICAgIGlmIChyZXBsYWNlbWVudCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHJlcGxhY2VtZW50KTtcbiAgICAgICAgICAgICAgICByZXBsYWNlbWVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlbmQgPiB0bylcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChjaGlsZC5zbGljZSh0byAtIHN0YXJ0LCBjaGlsZC5zaXplLCB2aWV3KSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uRnJvbURPTSh2aWV3LCBvcmlnaW4gPSBudWxsKSB7XG4gICAgbGV0IGRvbVNlbCA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKSwgZG9jID0gdmlldy5zdGF0ZS5kb2M7XG4gICAgaWYgKCFkb21TZWwuZm9jdXNOb2RlKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBsZXQgbmVhcmVzdERlc2MgPSB2aWV3LmRvY1ZpZXcubmVhcmVzdERlc2MoZG9tU2VsLmZvY3VzTm9kZSksIGluV2lkZ2V0ID0gbmVhcmVzdERlc2MgJiYgbmVhcmVzdERlc2Muc2l6ZSA9PSAwO1xuICAgIGxldCBoZWFkID0gdmlldy5kb2NWaWV3LnBvc0Zyb21ET00oZG9tU2VsLmZvY3VzTm9kZSwgZG9tU2VsLmZvY3VzT2Zmc2V0LCAxKTtcbiAgICBpZiAoaGVhZCA8IDApXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGxldCAkaGVhZCA9IGRvYy5yZXNvbHZlKGhlYWQpLCBhbmNob3IsIHNlbGVjdGlvbjtcbiAgICBpZiAoc2VsZWN0aW9uQ29sbGFwc2VkKGRvbVNlbCkpIHtcbiAgICAgICAgYW5jaG9yID0gaGVhZDtcbiAgICAgICAgd2hpbGUgKG5lYXJlc3REZXNjICYmICFuZWFyZXN0RGVzYy5ub2RlKVxuICAgICAgICAgICAgbmVhcmVzdERlc2MgPSBuZWFyZXN0RGVzYy5wYXJlbnQ7XG4gICAgICAgIGxldCBuZWFyZXN0RGVzY05vZGUgPSBuZWFyZXN0RGVzYy5ub2RlO1xuICAgICAgICBpZiAobmVhcmVzdERlc2MgJiYgbmVhcmVzdERlc2NOb2RlLmlzQXRvbSAmJiBOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZShuZWFyZXN0RGVzY05vZGUpICYmIG5lYXJlc3REZXNjLnBhcmVudFxuICAgICAgICAgICAgJiYgIShuZWFyZXN0RGVzY05vZGUuaXNJbmxpbmUgJiYgaXNPbkVkZ2UoZG9tU2VsLmZvY3VzTm9kZSwgZG9tU2VsLmZvY3VzT2Zmc2V0LCBuZWFyZXN0RGVzYy5kb20pKSkge1xuICAgICAgICAgICAgbGV0IHBvcyA9IG5lYXJlc3REZXNjLnBvc0JlZm9yZTtcbiAgICAgICAgICAgIHNlbGVjdGlvbiA9IG5ldyBOb2RlU2VsZWN0aW9uKGhlYWQgPT0gcG9zID8gJGhlYWQgOiBkb2MucmVzb2x2ZShwb3MpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWYgKGRvbVNlbCBpbnN0YW5jZW9mIHZpZXcuZG9tLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcuU2VsZWN0aW9uICYmIGRvbVNlbC5yYW5nZUNvdW50ID4gMSkge1xuICAgICAgICAgICAgbGV0IG1pbiA9IGhlYWQsIG1heCA9IGhlYWQ7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRvbVNlbC5yYW5nZUNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgcmFuZ2UgPSBkb21TZWwuZ2V0UmFuZ2VBdChpKTtcbiAgICAgICAgICAgICAgICBtaW4gPSBNYXRoLm1pbihtaW4sIHZpZXcuZG9jVmlldy5wb3NGcm9tRE9NKHJhbmdlLnN0YXJ0Q29udGFpbmVyLCByYW5nZS5zdGFydE9mZnNldCwgMSkpO1xuICAgICAgICAgICAgICAgIG1heCA9IE1hdGgubWF4KG1heCwgdmlldy5kb2NWaWV3LnBvc0Zyb21ET00ocmFuZ2UuZW5kQ29udGFpbmVyLCByYW5nZS5lbmRPZmZzZXQsIC0xKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWluIDwgMClcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIFthbmNob3IsIGhlYWRdID0gbWF4ID09IHZpZXcuc3RhdGUuc2VsZWN0aW9uLmFuY2hvciA/IFttYXgsIG1pbl0gOiBbbWluLCBtYXhdO1xuICAgICAgICAgICAgJGhlYWQgPSBkb2MucmVzb2x2ZShoZWFkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGFuY2hvciA9IHZpZXcuZG9jVmlldy5wb3NGcm9tRE9NKGRvbVNlbC5hbmNob3JOb2RlLCBkb21TZWwuYW5jaG9yT2Zmc2V0LCAxKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYW5jaG9yIDwgMClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBsZXQgJGFuY2hvciA9IGRvYy5yZXNvbHZlKGFuY2hvcik7XG4gICAgaWYgKCFzZWxlY3Rpb24pIHtcbiAgICAgICAgbGV0IGJpYXMgPSBvcmlnaW4gPT0gXCJwb2ludGVyXCIgfHwgKHZpZXcuc3RhdGUuc2VsZWN0aW9uLmhlYWQgPCAkaGVhZC5wb3MgJiYgIWluV2lkZ2V0KSA/IDEgOiAtMTtcbiAgICAgICAgc2VsZWN0aW9uID0gc2VsZWN0aW9uQmV0d2Vlbih2aWV3LCAkYW5jaG9yLCAkaGVhZCwgYmlhcyk7XG4gICAgfVxuICAgIHJldHVybiBzZWxlY3Rpb247XG59XG5mdW5jdGlvbiBlZGl0b3JPd25zU2VsZWN0aW9uKHZpZXcpIHtcbiAgICByZXR1cm4gdmlldy5lZGl0YWJsZSA/IHZpZXcuaGFzRm9jdXMoKSA6XG4gICAgICAgIGhhc1NlbGVjdGlvbih2aWV3KSAmJiBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQuY29udGFpbnModmlldy5kb20pO1xufVxuZnVuY3Rpb24gc2VsZWN0aW9uVG9ET00odmlldywgZm9yY2UgPSBmYWxzZSkge1xuICAgIGxldCBzZWwgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbjtcbiAgICBzeW5jTm9kZVNlbGVjdGlvbih2aWV3LCBzZWwpO1xuICAgIGlmICghZWRpdG9yT3duc1NlbGVjdGlvbih2aWV3KSlcbiAgICAgICAgcmV0dXJuO1xuICAgIC8vIFRoZSBkZWxheWVkIGRyYWcgc2VsZWN0aW9uIGNhdXNlcyBpc3N1ZXMgd2l0aCBDZWxsIFNlbGVjdGlvbnNcbiAgICAvLyBpbiBTYWZhcmkuIEFuZCB0aGUgZHJhZyBzZWxlY3Rpb24gZGVsYXkgaXMgdG8gd29ya2Fyb25kIGlzc3Vlc1xuICAgIC8vIHdoaWNoIG9ubHkgcHJlc2VudCBpbiBDaHJvbWUuXG4gICAgaWYgKCFmb3JjZSAmJiB2aWV3LmlucHV0Lm1vdXNlRG93biAmJiB2aWV3LmlucHV0Lm1vdXNlRG93bi5hbGxvd0RlZmF1bHQgJiYgY2hyb21lKSB7XG4gICAgICAgIGxldCBkb21TZWwgPSB2aWV3LmRvbVNlbGVjdGlvblJhbmdlKCksIGN1clNlbCA9IHZpZXcuZG9tT2JzZXJ2ZXIuY3VycmVudFNlbGVjdGlvbjtcbiAgICAgICAgaWYgKGRvbVNlbC5hbmNob3JOb2RlICYmIGN1clNlbC5hbmNob3JOb2RlICYmXG4gICAgICAgICAgICBpc0VxdWl2YWxlbnRQb3NpdGlvbihkb21TZWwuYW5jaG9yTm9kZSwgZG9tU2VsLmFuY2hvck9mZnNldCwgY3VyU2VsLmFuY2hvck5vZGUsIGN1clNlbC5hbmNob3JPZmZzZXQpKSB7XG4gICAgICAgICAgICB2aWV3LmlucHV0Lm1vdXNlRG93bi5kZWxheWVkU2VsZWN0aW9uU3luYyA9IHRydWU7XG4gICAgICAgICAgICB2aWV3LmRvbU9ic2VydmVyLnNldEN1clNlbGVjdGlvbigpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZpZXcuZG9tT2JzZXJ2ZXIuZGlzY29ubmVjdFNlbGVjdGlvbigpO1xuICAgIGlmICh2aWV3LmN1cnNvcldyYXBwZXIpIHtcbiAgICAgICAgc2VsZWN0Q3Vyc29yV3JhcHBlcih2aWV3KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGxldCB7IGFuY2hvciwgaGVhZCB9ID0gc2VsLCByZXNldEVkaXRhYmxlRnJvbSwgcmVzZXRFZGl0YWJsZVRvO1xuICAgICAgICBpZiAoYnJva2VuU2VsZWN0QmV0d2VlblVuZWRpdGFibGUgJiYgIShzZWwgaW5zdGFuY2VvZiBUZXh0U2VsZWN0aW9uKSkge1xuICAgICAgICAgICAgaWYgKCFzZWwuJGZyb20ucGFyZW50LmlubGluZUNvbnRlbnQpXG4gICAgICAgICAgICAgICAgcmVzZXRFZGl0YWJsZUZyb20gPSB0ZW1wb3JhcmlseUVkaXRhYmxlTmVhcih2aWV3LCBzZWwuZnJvbSk7XG4gICAgICAgICAgICBpZiAoIXNlbC5lbXB0eSAmJiAhc2VsLiRmcm9tLnBhcmVudC5pbmxpbmVDb250ZW50KVxuICAgICAgICAgICAgICAgIHJlc2V0RWRpdGFibGVUbyA9IHRlbXBvcmFyaWx5RWRpdGFibGVOZWFyKHZpZXcsIHNlbC50byk7XG4gICAgICAgIH1cbiAgICAgICAgdmlldy5kb2NWaWV3LnNldFNlbGVjdGlvbihhbmNob3IsIGhlYWQsIHZpZXcsIGZvcmNlKTtcbiAgICAgICAgaWYgKGJyb2tlblNlbGVjdEJldHdlZW5VbmVkaXRhYmxlKSB7XG4gICAgICAgICAgICBpZiAocmVzZXRFZGl0YWJsZUZyb20pXG4gICAgICAgICAgICAgICAgcmVzZXRFZGl0YWJsZShyZXNldEVkaXRhYmxlRnJvbSk7XG4gICAgICAgICAgICBpZiAocmVzZXRFZGl0YWJsZVRvKVxuICAgICAgICAgICAgICAgIHJlc2V0RWRpdGFibGUocmVzZXRFZGl0YWJsZVRvKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VsLnZpc2libGUpIHtcbiAgICAgICAgICAgIHZpZXcuZG9tLmNsYXNzTGlzdC5yZW1vdmUoXCJQcm9zZU1pcnJvci1oaWRlc2VsZWN0aW9uXCIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmlldy5kb20uY2xhc3NMaXN0LmFkZChcIlByb3NlTWlycm9yLWhpZGVzZWxlY3Rpb25cIik7XG4gICAgICAgICAgICBpZiAoXCJvbnNlbGVjdGlvbmNoYW5nZVwiIGluIGRvY3VtZW50KVxuICAgICAgICAgICAgICAgIHJlbW92ZUNsYXNzT25TZWxlY3Rpb25DaGFuZ2Uodmlldyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdmlldy5kb21PYnNlcnZlci5zZXRDdXJTZWxlY3Rpb24oKTtcbiAgICB2aWV3LmRvbU9ic2VydmVyLmNvbm5lY3RTZWxlY3Rpb24oKTtcbn1cbi8vIEtsdWRnZSB0byB3b3JrIGFyb3VuZCBXZWJraXQgbm90IGFsbG93aW5nIGEgc2VsZWN0aW9uIHRvIHN0YXJ0L2VuZFxuLy8gYmV0d2VlbiBub24tZWRpdGFibGUgYmxvY2sgbm9kZXMuIFdlIGJyaWVmbHkgbWFrZSBzb21ldGhpbmdcbi8vIGVkaXRhYmxlLCBzZXQgdGhlIHNlbGVjdGlvbiwgdGhlbiBzZXQgaXQgdW5lZGl0YWJsZSBhZ2Fpbi5cbmNvbnN0IGJyb2tlblNlbGVjdEJldHdlZW5VbmVkaXRhYmxlID0gc2FmYXJpIHx8IGNocm9tZSAmJiBjaHJvbWVfdmVyc2lvbiA8IDYzO1xuZnVuY3Rpb24gdGVtcG9yYXJpbHlFZGl0YWJsZU5lYXIodmlldywgcG9zKSB7XG4gICAgbGV0IHsgbm9kZSwgb2Zmc2V0IH0gPSB2aWV3LmRvY1ZpZXcuZG9tRnJvbVBvcyhwb3MsIDApO1xuICAgIGxldCBhZnRlciA9IG9mZnNldCA8IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGggPyBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0XSA6IG51bGw7XG4gICAgbGV0IGJlZm9yZSA9IG9mZnNldCA/IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXQgLSAxXSA6IG51bGw7XG4gICAgaWYgKHNhZmFyaSAmJiBhZnRlciAmJiBhZnRlci5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKVxuICAgICAgICByZXR1cm4gc2V0RWRpdGFibGUoYWZ0ZXIpO1xuICAgIGlmICgoIWFmdGVyIHx8IGFmdGVyLmNvbnRlbnRFZGl0YWJsZSA9PSBcImZhbHNlXCIpICYmXG4gICAgICAgICghYmVmb3JlIHx8IGJlZm9yZS5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKSkge1xuICAgICAgICBpZiAoYWZ0ZXIpXG4gICAgICAgICAgICByZXR1cm4gc2V0RWRpdGFibGUoYWZ0ZXIpO1xuICAgICAgICBlbHNlIGlmIChiZWZvcmUpXG4gICAgICAgICAgICByZXR1cm4gc2V0RWRpdGFibGUoYmVmb3JlKTtcbiAgICB9XG59XG5mdW5jdGlvbiBzZXRFZGl0YWJsZShlbGVtZW50KSB7XG4gICAgZWxlbWVudC5jb250ZW50RWRpdGFibGUgPSBcInRydWVcIjtcbiAgICBpZiAoc2FmYXJpICYmIGVsZW1lbnQuZHJhZ2dhYmxlKSB7XG4gICAgICAgIGVsZW1lbnQuZHJhZ2dhYmxlID0gZmFsc2U7XG4gICAgICAgIGVsZW1lbnQud2FzRHJhZ2dhYmxlID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG59XG5mdW5jdGlvbiByZXNldEVkaXRhYmxlKGVsZW1lbnQpIHtcbiAgICBlbGVtZW50LmNvbnRlbnRFZGl0YWJsZSA9IFwiZmFsc2VcIjtcbiAgICBpZiAoZWxlbWVudC53YXNEcmFnZ2FibGUpIHtcbiAgICAgICAgZWxlbWVudC5kcmFnZ2FibGUgPSB0cnVlO1xuICAgICAgICBlbGVtZW50Lndhc0RyYWdnYWJsZSA9IG51bGw7XG4gICAgfVxufVxuZnVuY3Rpb24gcmVtb3ZlQ2xhc3NPblNlbGVjdGlvbkNoYW5nZSh2aWV3KSB7XG4gICAgbGV0IGRvYyA9IHZpZXcuZG9tLm93bmVyRG9jdW1lbnQ7XG4gICAgZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzZWxlY3Rpb25jaGFuZ2VcIiwgdmlldy5pbnB1dC5oaWRlU2VsZWN0aW9uR3VhcmQpO1xuICAgIGxldCBkb21TZWwgPSB2aWV3LmRvbVNlbGVjdGlvblJhbmdlKCk7XG4gICAgbGV0IG5vZGUgPSBkb21TZWwuYW5jaG9yTm9kZSwgb2Zmc2V0ID0gZG9tU2VsLmFuY2hvck9mZnNldDtcbiAgICBkb2MuYWRkRXZlbnRMaXN0ZW5lcihcInNlbGVjdGlvbmNoYW5nZVwiLCB2aWV3LmlucHV0LmhpZGVTZWxlY3Rpb25HdWFyZCA9ICgpID0+IHtcbiAgICAgICAgaWYgKGRvbVNlbC5hbmNob3JOb2RlICE9IG5vZGUgfHwgZG9tU2VsLmFuY2hvck9mZnNldCAhPSBvZmZzZXQpIHtcbiAgICAgICAgICAgIGRvYy5yZW1vdmVFdmVudExpc3RlbmVyKFwic2VsZWN0aW9uY2hhbmdlXCIsIHZpZXcuaW5wdXQuaGlkZVNlbGVjdGlvbkd1YXJkKTtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghZWRpdG9yT3duc1NlbGVjdGlvbih2aWV3KSB8fCB2aWV3LnN0YXRlLnNlbGVjdGlvbi52aXNpYmxlKVxuICAgICAgICAgICAgICAgICAgICB2aWV3LmRvbS5jbGFzc0xpc3QucmVtb3ZlKFwiUHJvc2VNaXJyb3ItaGlkZXNlbGVjdGlvblwiKTtcbiAgICAgICAgICAgIH0sIDIwKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gc2VsZWN0Q3Vyc29yV3JhcHBlcih2aWV3KSB7XG4gICAgbGV0IGRvbVNlbCA9IHZpZXcuZG9tU2VsZWN0aW9uKCk7XG4gICAgaWYgKCFkb21TZWwpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgbm9kZSA9IHZpZXcuY3Vyc29yV3JhcHBlci5kb20sIGltZyA9IG5vZGUubm9kZU5hbWUgPT0gXCJJTUdcIjtcbiAgICBpZiAoaW1nKVxuICAgICAgICBkb21TZWwuY29sbGFwc2Uobm9kZS5wYXJlbnROb2RlLCBkb21JbmRleChub2RlKSArIDEpO1xuICAgIGVsc2VcbiAgICAgICAgZG9tU2VsLmNvbGxhcHNlKG5vZGUsIDApO1xuICAgIC8vIEtsdWRnZSB0byBraWxsICdjb250cm9sIHNlbGVjdGlvbicgaW4gSUUxMSB3aGVuIHNlbGVjdGluZyBhblxuICAgIC8vIGludmlzaWJsZSBjdXJzb3Igd3JhcHBlciwgc2luY2UgdGhhdCB3b3VsZCByZXN1bHQgaW4gdGhvc2Ugd2VpcmRcbiAgICAvLyByZXNpemUgaGFuZGxlcyBhbmQgYSBzZWxlY3Rpb24gdGhhdCBjb25zaWRlcnMgdGhlIGFic29sdXRlbHlcbiAgICAvLyBwb3NpdGlvbmVkIHdyYXBwZXIsIHJhdGhlciB0aGFuIHRoZSByb290IGVkaXRhYmxlIG5vZGUsIHRoZVxuICAgIC8vIGZvY3VzZWQgZWxlbWVudC5cbiAgICBpZiAoIWltZyAmJiAhdmlldy5zdGF0ZS5zZWxlY3Rpb24udmlzaWJsZSAmJiBpZSAmJiBpZV92ZXJzaW9uIDw9IDExKSB7XG4gICAgICAgIG5vZGUuZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgICBub2RlLmRpc2FibGVkID0gZmFsc2U7XG4gICAgfVxufVxuZnVuY3Rpb24gc3luY05vZGVTZWxlY3Rpb24odmlldywgc2VsKSB7XG4gICAgaWYgKHNlbCBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24pIHtcbiAgICAgICAgbGV0IGRlc2MgPSB2aWV3LmRvY1ZpZXcuZGVzY0F0KHNlbC5mcm9tKTtcbiAgICAgICAgaWYgKGRlc2MgIT0gdmlldy5sYXN0U2VsZWN0ZWRWaWV3RGVzYykge1xuICAgICAgICAgICAgY2xlYXJOb2RlU2VsZWN0aW9uKHZpZXcpO1xuICAgICAgICAgICAgaWYgKGRlc2MpXG4gICAgICAgICAgICAgICAgZGVzYy5zZWxlY3ROb2RlKCk7XG4gICAgICAgICAgICB2aWV3Lmxhc3RTZWxlY3RlZFZpZXdEZXNjID0gZGVzYztcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgY2xlYXJOb2RlU2VsZWN0aW9uKHZpZXcpO1xuICAgIH1cbn1cbi8vIENsZWFyIGFsbCBET00gc3RhdGVmdWxuZXNzIG9mIHRoZSBsYXN0IG5vZGUgc2VsZWN0aW9uLlxuZnVuY3Rpb24gY2xlYXJOb2RlU2VsZWN0aW9uKHZpZXcpIHtcbiAgICBpZiAodmlldy5sYXN0U2VsZWN0ZWRWaWV3RGVzYykge1xuICAgICAgICBpZiAodmlldy5sYXN0U2VsZWN0ZWRWaWV3RGVzYy5wYXJlbnQpXG4gICAgICAgICAgICB2aWV3Lmxhc3RTZWxlY3RlZFZpZXdEZXNjLmRlc2VsZWN0Tm9kZSgpO1xuICAgICAgICB2aWV3Lmxhc3RTZWxlY3RlZFZpZXdEZXNjID0gdW5kZWZpbmVkO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHNlbGVjdGlvbkJldHdlZW4odmlldywgJGFuY2hvciwgJGhlYWQsIGJpYXMpIHtcbiAgICByZXR1cm4gdmlldy5zb21lUHJvcChcImNyZWF0ZVNlbGVjdGlvbkJldHdlZW5cIiwgZiA9PiBmKHZpZXcsICRhbmNob3IsICRoZWFkKSlcbiAgICAgICAgfHwgVGV4dFNlbGVjdGlvbi5iZXR3ZWVuKCRhbmNob3IsICRoZWFkLCBiaWFzKTtcbn1cbmZ1bmN0aW9uIGhhc0ZvY3VzQW5kU2VsZWN0aW9uKHZpZXcpIHtcbiAgICBpZiAodmlldy5lZGl0YWJsZSAmJiAhdmlldy5oYXNGb2N1cygpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIGhhc1NlbGVjdGlvbih2aWV3KTtcbn1cbmZ1bmN0aW9uIGhhc1NlbGVjdGlvbih2aWV3KSB7XG4gICAgbGV0IHNlbCA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKTtcbiAgICBpZiAoIXNlbC5hbmNob3JOb2RlKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gRmlyZWZveCB3aWxsIHJhaXNlICdwZXJtaXNzaW9uIGRlbmllZCcgZXJyb3JzIHdoZW4gYWNjZXNzaW5nXG4gICAgICAgIC8vIHByb3BlcnRpZXMgb2YgYHNlbC5hbmNob3JOb2RlYCB3aGVuIGl0J3MgaW4gYSBnZW5lcmF0ZWQgQ1NTXG4gICAgICAgIC8vIGVsZW1lbnQuXG4gICAgICAgIHJldHVybiB2aWV3LmRvbS5jb250YWlucyhzZWwuYW5jaG9yTm9kZS5ub2RlVHlwZSA9PSAzID8gc2VsLmFuY2hvck5vZGUucGFyZW50Tm9kZSA6IHNlbC5hbmNob3JOb2RlKSAmJlxuICAgICAgICAgICAgKHZpZXcuZWRpdGFibGUgfHwgdmlldy5kb20uY29udGFpbnMoc2VsLmZvY3VzTm9kZS5ub2RlVHlwZSA9PSAzID8gc2VsLmZvY3VzTm9kZS5wYXJlbnROb2RlIDogc2VsLmZvY3VzTm9kZSkpO1xuICAgIH1cbiAgICBjYXRjaCAoXykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuZnVuY3Rpb24gYW5jaG9ySW5SaWdodFBsYWNlKHZpZXcpIHtcbiAgICBsZXQgYW5jaG9yRE9NID0gdmlldy5kb2NWaWV3LmRvbUZyb21Qb3Modmlldy5zdGF0ZS5zZWxlY3Rpb24uYW5jaG9yLCAwKTtcbiAgICBsZXQgZG9tU2VsID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgIHJldHVybiBpc0VxdWl2YWxlbnRQb3NpdGlvbihhbmNob3JET00ubm9kZSwgYW5jaG9yRE9NLm9mZnNldCwgZG9tU2VsLmFuY2hvck5vZGUsIGRvbVNlbC5hbmNob3JPZmZzZXQpO1xufVxuXG5mdW5jdGlvbiBtb3ZlU2VsZWN0aW9uQmxvY2soc3RhdGUsIGRpcikge1xuICAgIGxldCB7ICRhbmNob3IsICRoZWFkIH0gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgbGV0ICRzaWRlID0gZGlyID4gMCA/ICRhbmNob3IubWF4KCRoZWFkKSA6ICRhbmNob3IubWluKCRoZWFkKTtcbiAgICBsZXQgJHN0YXJ0ID0gISRzaWRlLnBhcmVudC5pbmxpbmVDb250ZW50ID8gJHNpZGUgOiAkc2lkZS5kZXB0aCA/IHN0YXRlLmRvYy5yZXNvbHZlKGRpciA+IDAgPyAkc2lkZS5hZnRlcigpIDogJHNpZGUuYmVmb3JlKCkpIDogbnVsbDtcbiAgICByZXR1cm4gJHN0YXJ0ICYmIFNlbGVjdGlvbi5maW5kRnJvbSgkc3RhcnQsIGRpcik7XG59XG5mdW5jdGlvbiBhcHBseSh2aWV3LCBzZWwpIHtcbiAgICB2aWV3LmRpc3BhdGNoKHZpZXcuc3RhdGUudHIuc2V0U2VsZWN0aW9uKHNlbCkuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBzZWxlY3RIb3Jpem9udGFsbHkodmlldywgZGlyLCBtb2RzKSB7XG4gICAgbGV0IHNlbCA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uO1xuICAgIGlmIChzZWwgaW5zdGFuY2VvZiBUZXh0U2VsZWN0aW9uKSB7XG4gICAgICAgIGlmIChtb2RzLmluZGV4T2YoXCJzXCIpID4gLTEpIHtcbiAgICAgICAgICAgIGxldCB7ICRoZWFkIH0gPSBzZWwsIG5vZGUgPSAkaGVhZC50ZXh0T2Zmc2V0ID8gbnVsbCA6IGRpciA8IDAgPyAkaGVhZC5ub2RlQmVmb3JlIDogJGhlYWQubm9kZUFmdGVyO1xuICAgICAgICAgICAgaWYgKCFub2RlIHx8IG5vZGUuaXNUZXh0IHx8ICFub2RlLmlzTGVhZilcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBsZXQgJG5ld0hlYWQgPSB2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKCRoZWFkLnBvcyArIG5vZGUubm9kZVNpemUgKiAoZGlyIDwgMCA/IC0xIDogMSkpO1xuICAgICAgICAgICAgcmV0dXJuIGFwcGx5KHZpZXcsIG5ldyBUZXh0U2VsZWN0aW9uKHNlbC4kYW5jaG9yLCAkbmV3SGVhZCkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFzZWwuZW1wdHkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh2aWV3LmVuZE9mVGV4dGJsb2NrKGRpciA+IDAgPyBcImZvcndhcmRcIiA6IFwiYmFja3dhcmRcIikpIHtcbiAgICAgICAgICAgIGxldCBuZXh0ID0gbW92ZVNlbGVjdGlvbkJsb2NrKHZpZXcuc3RhdGUsIGRpcik7XG4gICAgICAgICAgICBpZiAobmV4dCAmJiAobmV4dCBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24pKVxuICAgICAgICAgICAgICAgIHJldHVybiBhcHBseSh2aWV3LCBuZXh0KTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghKG1hYyAmJiBtb2RzLmluZGV4T2YoXCJtXCIpID4gLTEpKSB7XG4gICAgICAgICAgICBsZXQgJGhlYWQgPSBzZWwuJGhlYWQsIG5vZGUgPSAkaGVhZC50ZXh0T2Zmc2V0ID8gbnVsbCA6IGRpciA8IDAgPyAkaGVhZC5ub2RlQmVmb3JlIDogJGhlYWQubm9kZUFmdGVyLCBkZXNjO1xuICAgICAgICAgICAgaWYgKCFub2RlIHx8IG5vZGUuaXNUZXh0KVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGxldCBub2RlUG9zID0gZGlyIDwgMCA/ICRoZWFkLnBvcyAtIG5vZGUubm9kZVNpemUgOiAkaGVhZC5wb3M7XG4gICAgICAgICAgICBpZiAoIShub2RlLmlzQXRvbSB8fCAoZGVzYyA9IHZpZXcuZG9jVmlldy5kZXNjQXQobm9kZVBvcykpICYmICFkZXNjLmNvbnRlbnRET00pKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGlmIChOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZShub2RlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhcHBseSh2aWV3LCBuZXcgTm9kZVNlbGVjdGlvbihkaXIgPCAwID8gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZSgkaGVhZC5wb3MgLSBub2RlLm5vZGVTaXplKSA6ICRoZWFkKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh3ZWJraXQpIHtcbiAgICAgICAgICAgICAgICAvLyBDaHJvbWUgYW5kIFNhZmFyaSB3aWxsIGludHJvZHVjZSBleHRyYSBwb2ludGxlc3MgY3Vyc29yXG4gICAgICAgICAgICAgICAgLy8gcG9zaXRpb25zIGFyb3VuZCBpbmxpbmUgdW5lZGl0YWJsZSBub2Rlcywgc28gd2UgaGF2ZSB0b1xuICAgICAgICAgICAgICAgIC8vIHRha2Ugb3ZlciBhbmQgbW92ZSB0aGUgY3Vyc29yIHBhc3QgdGhlbSAoIzkzNylcbiAgICAgICAgICAgICAgICByZXR1cm4gYXBwbHkodmlldywgbmV3IFRleHRTZWxlY3Rpb24odmlldy5zdGF0ZS5kb2MucmVzb2x2ZShkaXIgPCAwID8gbm9kZVBvcyA6IG5vZGVQb3MgKyBub2RlLm5vZGVTaXplKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKHNlbCBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24gJiYgc2VsLm5vZGUuaXNJbmxpbmUpIHtcbiAgICAgICAgcmV0dXJuIGFwcGx5KHZpZXcsIG5ldyBUZXh0U2VsZWN0aW9uKGRpciA+IDAgPyBzZWwuJHRvIDogc2VsLiRmcm9tKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBsZXQgbmV4dCA9IG1vdmVTZWxlY3Rpb25CbG9jayh2aWV3LnN0YXRlLCBkaXIpO1xuICAgICAgICBpZiAobmV4dClcbiAgICAgICAgICAgIHJldHVybiBhcHBseSh2aWV3LCBuZXh0KTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG5vZGVMZW4obm9kZSkge1xuICAgIHJldHVybiBub2RlLm5vZGVUeXBlID09IDMgPyBub2RlLm5vZGVWYWx1ZS5sZW5ndGggOiBub2RlLmNoaWxkTm9kZXMubGVuZ3RoO1xufVxuZnVuY3Rpb24gaXNJZ25vcmFibGUoZG9tLCBkaXIpIHtcbiAgICBsZXQgZGVzYyA9IGRvbS5wbVZpZXdEZXNjO1xuICAgIHJldHVybiBkZXNjICYmIGRlc2Muc2l6ZSA9PSAwICYmIChkaXIgPCAwIHx8IGRvbS5uZXh0U2libGluZyB8fCBkb20ubm9kZU5hbWUgIT0gXCJCUlwiKTtcbn1cbmZ1bmN0aW9uIHNraXBJZ25vcmVkTm9kZXModmlldywgZGlyKSB7XG4gICAgcmV0dXJuIGRpciA8IDAgPyBza2lwSWdub3JlZE5vZGVzQmVmb3JlKHZpZXcpIDogc2tpcElnbm9yZWROb2Rlc0FmdGVyKHZpZXcpO1xufVxuLy8gTWFrZSBzdXJlIHRoZSBjdXJzb3IgaXNuJ3QgZGlyZWN0bHkgYWZ0ZXIgb25lIG9yIG1vcmUgaWdub3JlZFxuLy8gbm9kZXMsIHdoaWNoIHdpbGwgY29uZnVzZSB0aGUgYnJvd3NlcidzIGN1cnNvciBtb3Rpb24gbG9naWMuXG5mdW5jdGlvbiBza2lwSWdub3JlZE5vZGVzQmVmb3JlKHZpZXcpIHtcbiAgICBsZXQgc2VsID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgIGxldCBub2RlID0gc2VsLmZvY3VzTm9kZSwgb2Zmc2V0ID0gc2VsLmZvY3VzT2Zmc2V0O1xuICAgIGlmICghbm9kZSlcbiAgICAgICAgcmV0dXJuO1xuICAgIGxldCBtb3ZlTm9kZSwgbW92ZU9mZnNldCwgZm9yY2UgPSBmYWxzZTtcbiAgICAvLyBHZWNrbyB3aWxsIGRvIG9kZCB0aGluZ3Mgd2hlbiB0aGUgc2VsZWN0aW9uIGlzIGRpcmVjdGx5IGluIGZyb250XG4gICAgLy8gb2YgYSBub24tZWRpdGFibGUgbm9kZSwgc28gaW4gdGhhdCBjYXNlLCBtb3ZlIGl0IGludG8gdGhlIG5leHRcbiAgICAvLyBub2RlIGlmIHBvc3NpYmxlLiBJc3N1ZSBwcm9zZW1pcnJvci9wcm9zZW1pcnJvciM4MzIuXG4gICAgaWYgKGdlY2tvICYmIG5vZGUubm9kZVR5cGUgPT0gMSAmJiBvZmZzZXQgPCBub2RlTGVuKG5vZGUpICYmIGlzSWdub3JhYmxlKG5vZGUuY2hpbGROb2Rlc1tvZmZzZXRdLCAtMSkpXG4gICAgICAgIGZvcmNlID0gdHJ1ZTtcbiAgICBmb3IgKDs7KSB7XG4gICAgICAgIGlmIChvZmZzZXQgPiAwKSB7XG4gICAgICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSAhPSAxKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgYmVmb3JlID0gbm9kZS5jaGlsZE5vZGVzW29mZnNldCAtIDFdO1xuICAgICAgICAgICAgICAgIGlmIChpc0lnbm9yYWJsZShiZWZvcmUsIC0xKSkge1xuICAgICAgICAgICAgICAgICAgICBtb3ZlTm9kZSA9IG5vZGU7XG4gICAgICAgICAgICAgICAgICAgIG1vdmVPZmZzZXQgPSAtLW9mZnNldDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoYmVmb3JlLm5vZGVUeXBlID09IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZSA9IGJlZm9yZTtcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gbm9kZS5ub2RlVmFsdWUubGVuZ3RoO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzQmxvY2tOb2RlKG5vZGUpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBwcmV2ID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7XG4gICAgICAgICAgICB3aGlsZSAocHJldiAmJiBpc0lnbm9yYWJsZShwcmV2LCAtMSkpIHtcbiAgICAgICAgICAgICAgICBtb3ZlTm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICBtb3ZlT2Zmc2V0ID0gZG9tSW5kZXgocHJldik7XG4gICAgICAgICAgICAgICAgcHJldiA9IHByZXYucHJldmlvdXNTaWJsaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFwcmV2KSB7XG4gICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICBpZiAobm9kZSA9PSB2aWV3LmRvbSlcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBwcmV2O1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IG5vZGVMZW4obm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGZvcmNlKVxuICAgICAgICBzZXRTZWxGb2N1cyh2aWV3LCBub2RlLCBvZmZzZXQpO1xuICAgIGVsc2UgaWYgKG1vdmVOb2RlKVxuICAgICAgICBzZXRTZWxGb2N1cyh2aWV3LCBtb3ZlTm9kZSwgbW92ZU9mZnNldCk7XG59XG4vLyBNYWtlIHN1cmUgdGhlIGN1cnNvciBpc24ndCBkaXJlY3RseSBiZWZvcmUgb25lIG9yIG1vcmUgaWdub3JlZFxuLy8gbm9kZXMuXG5mdW5jdGlvbiBza2lwSWdub3JlZE5vZGVzQWZ0ZXIodmlldykge1xuICAgIGxldCBzZWwgPSB2aWV3LmRvbVNlbGVjdGlvblJhbmdlKCk7XG4gICAgbGV0IG5vZGUgPSBzZWwuZm9jdXNOb2RlLCBvZmZzZXQgPSBzZWwuZm9jdXNPZmZzZXQ7XG4gICAgaWYgKCFub2RlKVxuICAgICAgICByZXR1cm47XG4gICAgbGV0IGxlbiA9IG5vZGVMZW4obm9kZSk7XG4gICAgbGV0IG1vdmVOb2RlLCBtb3ZlT2Zmc2V0O1xuICAgIGZvciAoOzspIHtcbiAgICAgICAgaWYgKG9mZnNldCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgIT0gMSlcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGxldCBhZnRlciA9IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXRdO1xuICAgICAgICAgICAgaWYgKGlzSWdub3JhYmxlKGFmdGVyLCAxKSkge1xuICAgICAgICAgICAgICAgIG1vdmVOb2RlID0gbm9kZTtcbiAgICAgICAgICAgICAgICBtb3ZlT2Zmc2V0ID0gKytvZmZzZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXNCbG9ja05vZGUobm9kZSkpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IG5leHQgPSBub2RlLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgd2hpbGUgKG5leHQgJiYgaXNJZ25vcmFibGUobmV4dCwgMSkpIHtcbiAgICAgICAgICAgICAgICBtb3ZlTm9kZSA9IG5leHQucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICBtb3ZlT2Zmc2V0ID0gZG9tSW5kZXgobmV4dCkgKyAxO1xuICAgICAgICAgICAgICAgIG5leHQgPSBuZXh0Lm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFuZXh0KSB7XG4gICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICBpZiAobm9kZSA9PSB2aWV3LmRvbSlcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gbGVuID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBuZXh0O1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7XG4gICAgICAgICAgICAgICAgbGVuID0gbm9kZUxlbihub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAobW92ZU5vZGUpXG4gICAgICAgIHNldFNlbEZvY3VzKHZpZXcsIG1vdmVOb2RlLCBtb3ZlT2Zmc2V0KTtcbn1cbmZ1bmN0aW9uIGlzQmxvY2tOb2RlKGRvbSkge1xuICAgIGxldCBkZXNjID0gZG9tLnBtVmlld0Rlc2M7XG4gICAgcmV0dXJuIGRlc2MgJiYgZGVzYy5ub2RlICYmIGRlc2Mubm9kZS5pc0Jsb2NrO1xufVxuZnVuY3Rpb24gdGV4dE5vZGVBZnRlcihub2RlLCBvZmZzZXQpIHtcbiAgICB3aGlsZSAobm9kZSAmJiBvZmZzZXQgPT0gbm9kZS5jaGlsZE5vZGVzLmxlbmd0aCAmJiAhaGFzQmxvY2tEZXNjKG5vZGUpKSB7XG4gICAgICAgIG9mZnNldCA9IGRvbUluZGV4KG5vZGUpICsgMTtcbiAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICB9XG4gICAgd2hpbGUgKG5vZGUgJiYgb2Zmc2V0IDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aCkge1xuICAgICAgICBsZXQgbmV4dCA9IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXRdO1xuICAgICAgICBpZiAobmV4dC5ub2RlVHlwZSA9PSAzKVxuICAgICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIGlmIChuZXh0Lm5vZGVUeXBlID09IDEgJiYgbmV4dC5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIG5vZGUgPSBuZXh0O1xuICAgICAgICBvZmZzZXQgPSAwO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHRleHROb2RlQmVmb3JlKG5vZGUsIG9mZnNldCkge1xuICAgIHdoaWxlIChub2RlICYmICFvZmZzZXQgJiYgIWhhc0Jsb2NrRGVzYyhub2RlKSkge1xuICAgICAgICBvZmZzZXQgPSBkb21JbmRleChub2RlKTtcbiAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICB9XG4gICAgd2hpbGUgKG5vZGUgJiYgb2Zmc2V0KSB7XG4gICAgICAgIGxldCBuZXh0ID0gbm9kZS5jaGlsZE5vZGVzW29mZnNldCAtIDFdO1xuICAgICAgICBpZiAobmV4dC5ub2RlVHlwZSA9PSAzKVxuICAgICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIGlmIChuZXh0Lm5vZGVUeXBlID09IDEgJiYgbmV4dC5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIG5vZGUgPSBuZXh0O1xuICAgICAgICBvZmZzZXQgPSBub2RlLmNoaWxkTm9kZXMubGVuZ3RoO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHNldFNlbEZvY3VzKHZpZXcsIG5vZGUsIG9mZnNldCkge1xuICAgIGlmIChub2RlLm5vZGVUeXBlICE9IDMpIHtcbiAgICAgICAgbGV0IGJlZm9yZSwgYWZ0ZXI7XG4gICAgICAgIGlmIChhZnRlciA9IHRleHROb2RlQWZ0ZXIobm9kZSwgb2Zmc2V0KSkge1xuICAgICAgICAgICAgbm9kZSA9IGFmdGVyO1xuICAgICAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChiZWZvcmUgPSB0ZXh0Tm9kZUJlZm9yZShub2RlLCBvZmZzZXQpKSB7XG4gICAgICAgICAgICBub2RlID0gYmVmb3JlO1xuICAgICAgICAgICAgb2Zmc2V0ID0gYmVmb3JlLm5vZGVWYWx1ZS5sZW5ndGg7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGV0IHNlbCA9IHZpZXcuZG9tU2VsZWN0aW9uKCk7XG4gICAgaWYgKCFzZWwpXG4gICAgICAgIHJldHVybjtcbiAgICBpZiAoc2VsZWN0aW9uQ29sbGFwc2VkKHNlbCkpIHtcbiAgICAgICAgbGV0IHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgICAgICAgcmFuZ2Uuc2V0RW5kKG5vZGUsIG9mZnNldCk7XG4gICAgICAgIHJhbmdlLnNldFN0YXJ0KG5vZGUsIG9mZnNldCk7XG4gICAgICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICAgICAgc2VsLmFkZFJhbmdlKHJhbmdlKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoc2VsLmV4dGVuZCkge1xuICAgICAgICBzZWwuZXh0ZW5kKG5vZGUsIG9mZnNldCk7XG4gICAgfVxuICAgIHZpZXcuZG9tT2JzZXJ2ZXIuc2V0Q3VyU2VsZWN0aW9uKCk7XG4gICAgbGV0IHsgc3RhdGUgfSA9IHZpZXc7XG4gICAgLy8gSWYgbm8gc3RhdGUgdXBkYXRlIGVuZHMgdXAgaGFwcGVuaW5nLCByZXNldCB0aGUgc2VsZWN0aW9uLlxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZiAodmlldy5zdGF0ZSA9PSBzdGF0ZSlcbiAgICAgICAgICAgIHNlbGVjdGlvblRvRE9NKHZpZXcpO1xuICAgIH0sIDUwKTtcbn1cbmZ1bmN0aW9uIGZpbmREaXJlY3Rpb24odmlldywgcG9zKSB7XG4gICAgbGV0ICRwb3MgPSB2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKHBvcyk7XG4gICAgaWYgKCEoY2hyb21lIHx8IHdpbmRvd3MpICYmICRwb3MucGFyZW50LmlubGluZUNvbnRlbnQpIHtcbiAgICAgICAgbGV0IGNvb3JkcyA9IHZpZXcuY29vcmRzQXRQb3MocG9zKTtcbiAgICAgICAgaWYgKHBvcyA+ICRwb3Muc3RhcnQoKSkge1xuICAgICAgICAgICAgbGV0IGJlZm9yZSA9IHZpZXcuY29vcmRzQXRQb3MocG9zIC0gMSk7XG4gICAgICAgICAgICBsZXQgbWlkID0gKGJlZm9yZS50b3AgKyBiZWZvcmUuYm90dG9tKSAvIDI7XG4gICAgICAgICAgICBpZiAobWlkID4gY29vcmRzLnRvcCAmJiBtaWQgPCBjb29yZHMuYm90dG9tICYmIE1hdGguYWJzKGJlZm9yZS5sZWZ0IC0gY29vcmRzLmxlZnQpID4gMSlcbiAgICAgICAgICAgICAgICByZXR1cm4gYmVmb3JlLmxlZnQgPCBjb29yZHMubGVmdCA/IFwibHRyXCIgOiBcInJ0bFwiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3MgPCAkcG9zLmVuZCgpKSB7XG4gICAgICAgICAgICBsZXQgYWZ0ZXIgPSB2aWV3LmNvb3Jkc0F0UG9zKHBvcyArIDEpO1xuICAgICAgICAgICAgbGV0IG1pZCA9IChhZnRlci50b3AgKyBhZnRlci5ib3R0b20pIC8gMjtcbiAgICAgICAgICAgIGlmIChtaWQgPiBjb29yZHMudG9wICYmIG1pZCA8IGNvb3Jkcy5ib3R0b20gJiYgTWF0aC5hYnMoYWZ0ZXIubGVmdCAtIGNvb3Jkcy5sZWZ0KSA+IDEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGFmdGVyLmxlZnQgPiBjb29yZHMubGVmdCA/IFwibHRyXCIgOiBcInJ0bFwiO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBjb21wdXRlZCA9IGdldENvbXB1dGVkU3R5bGUodmlldy5kb20pLmRpcmVjdGlvbjtcbiAgICByZXR1cm4gY29tcHV0ZWQgPT0gXCJydGxcIiA/IFwicnRsXCIgOiBcImx0clwiO1xufVxuLy8gQ2hlY2sgd2hldGhlciB2ZXJ0aWNhbCBzZWxlY3Rpb24gbW90aW9uIHdvdWxkIGludm9sdmUgbm9kZVxuLy8gc2VsZWN0aW9ucy4gSWYgc28sIGFwcGx5IGl0IChpZiBub3QsIHRoZSByZXN1bHQgaXMgbGVmdCB0byB0aGVcbi8vIGJyb3dzZXIpXG5mdW5jdGlvbiBzZWxlY3RWZXJ0aWNhbGx5KHZpZXcsIGRpciwgbW9kcykge1xuICAgIGxldCBzZWwgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbjtcbiAgICBpZiAoc2VsIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvbiAmJiAhc2VsLmVtcHR5IHx8IG1vZHMuaW5kZXhPZihcInNcIikgPiAtMSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChtYWMgJiYgbW9kcy5pbmRleE9mKFwibVwiKSA+IC0xKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IHsgJGZyb20sICR0byB9ID0gc2VsO1xuICAgIGlmICghJGZyb20ucGFyZW50LmlubGluZUNvbnRlbnQgfHwgdmlldy5lbmRPZlRleHRibG9jayhkaXIgPCAwID8gXCJ1cFwiIDogXCJkb3duXCIpKSB7XG4gICAgICAgIGxldCBuZXh0ID0gbW92ZVNlbGVjdGlvbkJsb2NrKHZpZXcuc3RhdGUsIGRpcik7XG4gICAgICAgIGlmIChuZXh0ICYmIChuZXh0IGluc3RhbmNlb2YgTm9kZVNlbGVjdGlvbikpXG4gICAgICAgICAgICByZXR1cm4gYXBwbHkodmlldywgbmV4dCk7XG4gICAgfVxuICAgIGlmICghJGZyb20ucGFyZW50LmlubGluZUNvbnRlbnQpIHtcbiAgICAgICAgbGV0IHNpZGUgPSBkaXIgPCAwID8gJGZyb20gOiAkdG87XG4gICAgICAgIGxldCBiZXlvbmQgPSBzZWwgaW5zdGFuY2VvZiBBbGxTZWxlY3Rpb24gPyBTZWxlY3Rpb24ubmVhcihzaWRlLCBkaXIpIDogU2VsZWN0aW9uLmZpbmRGcm9tKHNpZGUsIGRpcik7XG4gICAgICAgIHJldHVybiBiZXlvbmQgPyBhcHBseSh2aWV3LCBiZXlvbmQpIDogZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIHN0b3BOYXRpdmVIb3Jpem9udGFsRGVsZXRlKHZpZXcsIGRpcikge1xuICAgIGlmICghKHZpZXcuc3RhdGUuc2VsZWN0aW9uIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvbikpXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIGxldCB7ICRoZWFkLCAkYW5jaG9yLCBlbXB0eSB9ID0gdmlldy5zdGF0ZS5zZWxlY3Rpb247XG4gICAgaWYgKCEkaGVhZC5zYW1lUGFyZW50KCRhbmNob3IpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoIWVtcHR5KVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHZpZXcuZW5kT2ZUZXh0YmxvY2soZGlyID4gMCA/IFwiZm9yd2FyZFwiIDogXCJiYWNrd2FyZFwiKSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgbGV0IG5leHROb2RlID0gISRoZWFkLnRleHRPZmZzZXQgJiYgKGRpciA8IDAgPyAkaGVhZC5ub2RlQmVmb3JlIDogJGhlYWQubm9kZUFmdGVyKTtcbiAgICBpZiAobmV4dE5vZGUgJiYgIW5leHROb2RlLmlzVGV4dCkge1xuICAgICAgICBsZXQgdHIgPSB2aWV3LnN0YXRlLnRyO1xuICAgICAgICBpZiAoZGlyIDwgMClcbiAgICAgICAgICAgIHRyLmRlbGV0ZSgkaGVhZC5wb3MgLSBuZXh0Tm9kZS5ub2RlU2l6ZSwgJGhlYWQucG9zKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdHIuZGVsZXRlKCRoZWFkLnBvcywgJGhlYWQucG9zICsgbmV4dE5vZGUubm9kZVNpemUpO1xuICAgICAgICB2aWV3LmRpc3BhdGNoKHRyKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIHN3aXRjaEVkaXRhYmxlKHZpZXcsIG5vZGUsIHN0YXRlKSB7XG4gICAgdmlldy5kb21PYnNlcnZlci5zdG9wKCk7XG4gICAgbm9kZS5jb250ZW50RWRpdGFibGUgPSBzdGF0ZTtcbiAgICB2aWV3LmRvbU9ic2VydmVyLnN0YXJ0KCk7XG59XG4vLyBJc3N1ZSAjODY3IC8gIzEwOTAgLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD05MDM4MjFcbi8vIEluIHdoaWNoIFNhZmFyaSAoYW5kIGF0IHNvbWUgcG9pbnQgaW4gdGhlIHBhc3QsIENocm9tZSkgZG9lcyByZWFsbHlcbi8vIHdyb25nIHRoaW5ncyB3aGVuIHRoZSBkb3duIGFycm93IGlzIHByZXNzZWQgd2hlbiB0aGUgY3Vyc29yIGlzXG4vLyBkaXJlY3RseSBhdCB0aGUgc3RhcnQgb2YgYSB0ZXh0YmxvY2sgYW5kIGhhcyBhbiB1bmVkaXRhYmxlIG5vZGVcbi8vIGFmdGVyIGl0XG5mdW5jdGlvbiBzYWZhcmlEb3duQXJyb3dCdWcodmlldykge1xuICAgIGlmICghc2FmYXJpIHx8IHZpZXcuc3RhdGUuc2VsZWN0aW9uLiRoZWFkLnBhcmVudE9mZnNldCA+IDApXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgeyBmb2N1c05vZGUsIGZvY3VzT2Zmc2V0IH0gPSB2aWV3LmRvbVNlbGVjdGlvblJhbmdlKCk7XG4gICAgaWYgKGZvY3VzTm9kZSAmJiBmb2N1c05vZGUubm9kZVR5cGUgPT0gMSAmJiBmb2N1c09mZnNldCA9PSAwICYmXG4gICAgICAgIGZvY3VzTm9kZS5maXJzdENoaWxkICYmIGZvY3VzTm9kZS5maXJzdENoaWxkLmNvbnRlbnRFZGl0YWJsZSA9PSBcImZhbHNlXCIpIHtcbiAgICAgICAgbGV0IGNoaWxkID0gZm9jdXNOb2RlLmZpcnN0Q2hpbGQ7XG4gICAgICAgIHN3aXRjaEVkaXRhYmxlKHZpZXcsIGNoaWxkLCBcInRydWVcIik7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gc3dpdGNoRWRpdGFibGUodmlldywgY2hpbGQsIFwiZmFsc2VcIiksIDIwKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuLy8gQSBiYWNrZHJvcCBrZXkgbWFwcGluZyB1c2VkIHRvIG1ha2Ugc3VyZSB3ZSBhbHdheXMgc3VwcHJlc3Mga2V5c1xuLy8gdGhhdCBoYXZlIGEgZGFuZ2Vyb3VzIGRlZmF1bHQgZWZmZWN0LCBldmVuIGlmIHRoZSBjb21tYW5kcyB0aGV5IGFyZVxuLy8gYm91bmQgdG8gcmV0dXJuIGZhbHNlLCBhbmQgdG8gbWFrZSBzdXJlIHRoYXQgY3Vyc29yLW1vdGlvbiBrZXlzXG4vLyBmaW5kIGEgY3Vyc29yIChhcyBvcHBvc2VkIHRvIGEgbm9kZSBzZWxlY3Rpb24pIHdoZW4gcHJlc3NlZC4gRm9yXG4vLyBjdXJzb3ItbW90aW9uIGtleXMsIHRoZSBjb2RlIGluIHRoZSBoYW5kbGVycyBhbHNvIHRha2VzIGNhcmUgb2Zcbi8vIGJsb2NrIHNlbGVjdGlvbnMuXG5mdW5jdGlvbiBnZXRNb2RzKGV2ZW50KSB7XG4gICAgbGV0IHJlc3VsdCA9IFwiXCI7XG4gICAgaWYgKGV2ZW50LmN0cmxLZXkpXG4gICAgICAgIHJlc3VsdCArPSBcImNcIjtcbiAgICBpZiAoZXZlbnQubWV0YUtleSlcbiAgICAgICAgcmVzdWx0ICs9IFwibVwiO1xuICAgIGlmIChldmVudC5hbHRLZXkpXG4gICAgICAgIHJlc3VsdCArPSBcImFcIjtcbiAgICBpZiAoZXZlbnQuc2hpZnRLZXkpXG4gICAgICAgIHJlc3VsdCArPSBcInNcIjtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gY2FwdHVyZUtleURvd24odmlldywgZXZlbnQpIHtcbiAgICBsZXQgY29kZSA9IGV2ZW50LmtleUNvZGUsIG1vZHMgPSBnZXRNb2RzKGV2ZW50KTtcbiAgICBpZiAoY29kZSA9PSA4IHx8IChtYWMgJiYgY29kZSA9PSA3MiAmJiBtb2RzID09IFwiY1wiKSkgeyAvLyBCYWNrc3BhY2UsIEN0cmwtaCBvbiBNYWNcbiAgICAgICAgcmV0dXJuIHN0b3BOYXRpdmVIb3Jpem9udGFsRGVsZXRlKHZpZXcsIC0xKSB8fCBza2lwSWdub3JlZE5vZGVzKHZpZXcsIC0xKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoKGNvZGUgPT0gNDYgJiYgIWV2ZW50LnNoaWZ0S2V5KSB8fCAobWFjICYmIGNvZGUgPT0gNjggJiYgbW9kcyA9PSBcImNcIikpIHsgLy8gRGVsZXRlLCBDdHJsLWQgb24gTWFjXG4gICAgICAgIHJldHVybiBzdG9wTmF0aXZlSG9yaXpvbnRhbERlbGV0ZSh2aWV3LCAxKSB8fCBza2lwSWdub3JlZE5vZGVzKHZpZXcsIDEpO1xuICAgIH1cbiAgICBlbHNlIGlmIChjb2RlID09IDEzIHx8IGNvZGUgPT0gMjcpIHsgLy8gRW50ZXIsIEVzY1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgZWxzZSBpZiAoY29kZSA9PSAzNyB8fCAobWFjICYmIGNvZGUgPT0gNjYgJiYgbW9kcyA9PSBcImNcIikpIHsgLy8gTGVmdCBhcnJvdywgQ3RybC1iIG9uIE1hY1xuICAgICAgICBsZXQgZGlyID0gY29kZSA9PSAzNyA/IChmaW5kRGlyZWN0aW9uKHZpZXcsIHZpZXcuc3RhdGUuc2VsZWN0aW9uLmZyb20pID09IFwibHRyXCIgPyAtMSA6IDEpIDogLTE7XG4gICAgICAgIHJldHVybiBzZWxlY3RIb3Jpem9udGFsbHkodmlldywgZGlyLCBtb2RzKSB8fCBza2lwSWdub3JlZE5vZGVzKHZpZXcsIGRpcik7XG4gICAgfVxuICAgIGVsc2UgaWYgKGNvZGUgPT0gMzkgfHwgKG1hYyAmJiBjb2RlID09IDcwICYmIG1vZHMgPT0gXCJjXCIpKSB7IC8vIFJpZ2h0IGFycm93LCBDdHJsLWYgb24gTWFjXG4gICAgICAgIGxldCBkaXIgPSBjb2RlID09IDM5ID8gKGZpbmREaXJlY3Rpb24odmlldywgdmlldy5zdGF0ZS5zZWxlY3Rpb24uZnJvbSkgPT0gXCJsdHJcIiA/IDEgOiAtMSkgOiAxO1xuICAgICAgICByZXR1cm4gc2VsZWN0SG9yaXpvbnRhbGx5KHZpZXcsIGRpciwgbW9kcykgfHwgc2tpcElnbm9yZWROb2Rlcyh2aWV3LCBkaXIpO1xuICAgIH1cbiAgICBlbHNlIGlmIChjb2RlID09IDM4IHx8IChtYWMgJiYgY29kZSA9PSA4MCAmJiBtb2RzID09IFwiY1wiKSkgeyAvLyBVcCBhcnJvdywgQ3RybC1wIG9uIE1hY1xuICAgICAgICByZXR1cm4gc2VsZWN0VmVydGljYWxseSh2aWV3LCAtMSwgbW9kcykgfHwgc2tpcElnbm9yZWROb2Rlcyh2aWV3LCAtMSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGNvZGUgPT0gNDAgfHwgKG1hYyAmJiBjb2RlID09IDc4ICYmIG1vZHMgPT0gXCJjXCIpKSB7IC8vIERvd24gYXJyb3csIEN0cmwtbiBvbiBNYWNcbiAgICAgICAgcmV0dXJuIHNhZmFyaURvd25BcnJvd0J1Zyh2aWV3KSB8fCBzZWxlY3RWZXJ0aWNhbGx5KHZpZXcsIDEsIG1vZHMpIHx8IHNraXBJZ25vcmVkTm9kZXModmlldywgMSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKG1vZHMgPT0gKG1hYyA/IFwibVwiIDogXCJjXCIpICYmXG4gICAgICAgIChjb2RlID09IDY2IHx8IGNvZGUgPT0gNzMgfHwgY29kZSA9PSA4OSB8fCBjb2RlID09IDkwKSkgeyAvLyBNb2QtW2JpeXpdXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZUZvckNsaXBib2FyZCh2aWV3LCBzbGljZSkge1xuICAgIHZpZXcuc29tZVByb3AoXCJ0cmFuc2Zvcm1Db3BpZWRcIiwgZiA9PiB7IHNsaWNlID0gZihzbGljZSwgdmlldyk7IH0pO1xuICAgIGxldCBjb250ZXh0ID0gW10sIHsgY29udGVudCwgb3BlblN0YXJ0LCBvcGVuRW5kIH0gPSBzbGljZTtcbiAgICB3aGlsZSAob3BlblN0YXJ0ID4gMSAmJiBvcGVuRW5kID4gMSAmJiBjb250ZW50LmNoaWxkQ291bnQgPT0gMSAmJiBjb250ZW50LmZpcnN0Q2hpbGQuY2hpbGRDb3VudCA9PSAxKSB7XG4gICAgICAgIG9wZW5TdGFydC0tO1xuICAgICAgICBvcGVuRW5kLS07XG4gICAgICAgIGxldCBub2RlID0gY29udGVudC5maXJzdENoaWxkO1xuICAgICAgICBjb250ZXh0LnB1c2gobm9kZS50eXBlLm5hbWUsIG5vZGUuYXR0cnMgIT0gbm9kZS50eXBlLmRlZmF1bHRBdHRycyA/IG5vZGUuYXR0cnMgOiBudWxsKTtcbiAgICAgICAgY29udGVudCA9IG5vZGUuY29udGVudDtcbiAgICB9XG4gICAgbGV0IHNlcmlhbGl6ZXIgPSB2aWV3LnNvbWVQcm9wKFwiY2xpcGJvYXJkU2VyaWFsaXplclwiKSB8fCBET01TZXJpYWxpemVyLmZyb21TY2hlbWEodmlldy5zdGF0ZS5zY2hlbWEpO1xuICAgIGxldCBkb2MgPSBkZXRhY2hlZERvYygpLCB3cmFwID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgd3JhcC5hcHBlbmRDaGlsZChzZXJpYWxpemVyLnNlcmlhbGl6ZUZyYWdtZW50KGNvbnRlbnQsIHsgZG9jdW1lbnQ6IGRvYyB9KSk7XG4gICAgbGV0IGZpcnN0Q2hpbGQgPSB3cmFwLmZpcnN0Q2hpbGQsIG5lZWRzV3JhcCwgd3JhcHBlcnMgPSAwO1xuICAgIHdoaWxlIChmaXJzdENoaWxkICYmIGZpcnN0Q2hpbGQubm9kZVR5cGUgPT0gMSAmJiAobmVlZHNXcmFwID0gd3JhcE1hcFtmaXJzdENoaWxkLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCldKSkge1xuICAgICAgICBmb3IgKGxldCBpID0gbmVlZHNXcmFwLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgd3JhcHBlciA9IGRvYy5jcmVhdGVFbGVtZW50KG5lZWRzV3JhcFtpXSk7XG4gICAgICAgICAgICB3aGlsZSAod3JhcC5maXJzdENoaWxkKVxuICAgICAgICAgICAgICAgIHdyYXBwZXIuYXBwZW5kQ2hpbGQod3JhcC5maXJzdENoaWxkKTtcbiAgICAgICAgICAgIHdyYXAuYXBwZW5kQ2hpbGQod3JhcHBlcik7XG4gICAgICAgICAgICB3cmFwcGVycysrO1xuICAgICAgICB9XG4gICAgICAgIGZpcnN0Q2hpbGQgPSB3cmFwLmZpcnN0Q2hpbGQ7XG4gICAgfVxuICAgIGlmIChmaXJzdENoaWxkICYmIGZpcnN0Q2hpbGQubm9kZVR5cGUgPT0gMSlcbiAgICAgICAgZmlyc3RDaGlsZC5zZXRBdHRyaWJ1dGUoXCJkYXRhLXBtLXNsaWNlXCIsIGAke29wZW5TdGFydH0gJHtvcGVuRW5kfSR7d3JhcHBlcnMgPyBgIC0ke3dyYXBwZXJzfWAgOiBcIlwifSAke0pTT04uc3RyaW5naWZ5KGNvbnRleHQpfWApO1xuICAgIGxldCB0ZXh0ID0gdmlldy5zb21lUHJvcChcImNsaXBib2FyZFRleHRTZXJpYWxpemVyXCIsIGYgPT4gZihzbGljZSwgdmlldykpIHx8XG4gICAgICAgIHNsaWNlLmNvbnRlbnQudGV4dEJldHdlZW4oMCwgc2xpY2UuY29udGVudC5zaXplLCBcIlxcblxcblwiKTtcbiAgICByZXR1cm4geyBkb206IHdyYXAsIHRleHQsIHNsaWNlIH07XG59XG4vLyBSZWFkIGEgc2xpY2Ugb2YgY29udGVudCBmcm9tIHRoZSBjbGlwYm9hcmQgKG9yIGRyb3AgZGF0YSkuXG5mdW5jdGlvbiBwYXJzZUZyb21DbGlwYm9hcmQodmlldywgdGV4dCwgaHRtbCwgcGxhaW5UZXh0LCAkY29udGV4dCkge1xuICAgIGxldCBpbkNvZGUgPSAkY29udGV4dC5wYXJlbnQudHlwZS5zcGVjLmNvZGU7XG4gICAgbGV0IGRvbSwgc2xpY2U7XG4gICAgaWYgKCFodG1sICYmICF0ZXh0KVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBsZXQgYXNUZXh0ID0gISF0ZXh0ICYmIChwbGFpblRleHQgfHwgaW5Db2RlIHx8ICFodG1sKTtcbiAgICBpZiAoYXNUZXh0KSB7XG4gICAgICAgIHZpZXcuc29tZVByb3AoXCJ0cmFuc2Zvcm1QYXN0ZWRUZXh0XCIsIGYgPT4geyB0ZXh0ID0gZih0ZXh0LCBpbkNvZGUgfHwgcGxhaW5UZXh0LCB2aWV3KTsgfSk7XG4gICAgICAgIGlmIChpbkNvZGUpIHtcbiAgICAgICAgICAgIHNsaWNlID0gbmV3IFNsaWNlKEZyYWdtZW50LmZyb20odmlldy5zdGF0ZS5zY2hlbWEudGV4dCh0ZXh0LnJlcGxhY2UoL1xcclxcbj8vZywgXCJcXG5cIikpKSwgMCwgMCk7XG4gICAgICAgICAgICB2aWV3LnNvbWVQcm9wKFwidHJhbnNmb3JtUGFzdGVkXCIsIGYgPT4geyBzbGljZSA9IGYoc2xpY2UsIHZpZXcsIHRydWUpOyB9KTtcbiAgICAgICAgICAgIHJldHVybiBzbGljZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcGFyc2VkID0gdmlldy5zb21lUHJvcChcImNsaXBib2FyZFRleHRQYXJzZXJcIiwgZiA9PiBmKHRleHQsICRjb250ZXh0LCBwbGFpblRleHQsIHZpZXcpKTtcbiAgICAgICAgaWYgKHBhcnNlZCkge1xuICAgICAgICAgICAgc2xpY2UgPSBwYXJzZWQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgbWFya3MgPSAkY29udGV4dC5tYXJrcygpO1xuICAgICAgICAgICAgbGV0IHsgc2NoZW1hIH0gPSB2aWV3LnN0YXRlLCBzZXJpYWxpemVyID0gRE9NU2VyaWFsaXplci5mcm9tU2NoZW1hKHNjaGVtYSk7XG4gICAgICAgICAgICBkb20gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgICAgICAgICAgdGV4dC5zcGxpdCgvKD86XFxyXFxuP3xcXG4pKy8pLmZvckVhY2goYmxvY2sgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBwID0gZG9tLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJwXCIpKTtcbiAgICAgICAgICAgICAgICBpZiAoYmxvY2spXG4gICAgICAgICAgICAgICAgICAgIHAuYXBwZW5kQ2hpbGQoc2VyaWFsaXplci5zZXJpYWxpemVOb2RlKHNjaGVtYS50ZXh0KGJsb2NrLCBtYXJrcykpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICB2aWV3LnNvbWVQcm9wKFwidHJhbnNmb3JtUGFzdGVkSFRNTFwiLCBmID0+IHsgaHRtbCA9IGYoaHRtbCwgdmlldyk7IH0pO1xuICAgICAgICBkb20gPSByZWFkSFRNTChodG1sKTtcbiAgICAgICAgaWYgKHdlYmtpdClcbiAgICAgICAgICAgIHJlc3RvcmVSZXBsYWNlZFNwYWNlcyhkb20pO1xuICAgIH1cbiAgICBsZXQgY29udGV4dE5vZGUgPSBkb20gJiYgZG9tLnF1ZXJ5U2VsZWN0b3IoXCJbZGF0YS1wbS1zbGljZV1cIik7XG4gICAgbGV0IHNsaWNlRGF0YSA9IGNvbnRleHROb2RlICYmIC9eKFxcZCspIChcXGQrKSg/OiAtKFxcZCspKT8gKC4qKS8uZXhlYyhjb250ZXh0Tm9kZS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXBtLXNsaWNlXCIpIHx8IFwiXCIpO1xuICAgIGlmIChzbGljZURhdGEgJiYgc2xpY2VEYXRhWzNdKVxuICAgICAgICBmb3IgKGxldCBpID0gK3NsaWNlRGF0YVszXTsgaSA+IDA7IGktLSkge1xuICAgICAgICAgICAgbGV0IGNoaWxkID0gZG9tLmZpcnN0Q2hpbGQ7XG4gICAgICAgICAgICB3aGlsZSAoY2hpbGQgJiYgY2hpbGQubm9kZVR5cGUgIT0gMSlcbiAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgaWYgKCFjaGlsZClcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRvbSA9IGNoaWxkO1xuICAgICAgICB9XG4gICAgaWYgKCFzbGljZSkge1xuICAgICAgICBsZXQgcGFyc2VyID0gdmlldy5zb21lUHJvcChcImNsaXBib2FyZFBhcnNlclwiKSB8fCB2aWV3LnNvbWVQcm9wKFwiZG9tUGFyc2VyXCIpIHx8IERPTVBhcnNlci5mcm9tU2NoZW1hKHZpZXcuc3RhdGUuc2NoZW1hKTtcbiAgICAgICAgc2xpY2UgPSBwYXJzZXIucGFyc2VTbGljZShkb20sIHtcbiAgICAgICAgICAgIHByZXNlcnZlV2hpdGVzcGFjZTogISEoYXNUZXh0IHx8IHNsaWNlRGF0YSksXG4gICAgICAgICAgICBjb250ZXh0OiAkY29udGV4dCxcbiAgICAgICAgICAgIHJ1bGVGcm9tTm9kZShkb20pIHtcbiAgICAgICAgICAgICAgICBpZiAoZG9tLm5vZGVOYW1lID09IFwiQlJcIiAmJiAhZG9tLm5leHRTaWJsaW5nICYmXG4gICAgICAgICAgICAgICAgICAgIGRvbS5wYXJlbnROb2RlICYmICFpbmxpbmVQYXJlbnRzLnRlc3QoZG9tLnBhcmVudE5vZGUubm9kZU5hbWUpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBpZ25vcmU6IHRydWUgfTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChzbGljZURhdGEpIHtcbiAgICAgICAgc2xpY2UgPSBhZGRDb250ZXh0KGNsb3NlU2xpY2Uoc2xpY2UsICtzbGljZURhdGFbMV0sICtzbGljZURhdGFbMl0pLCBzbGljZURhdGFbNF0pO1xuICAgIH1cbiAgICBlbHNlIHsgLy8gSFRNTCB3YXNuJ3QgY3JlYXRlZCBieSBQcm9zZU1pcnJvci4gTWFrZSBzdXJlIHRvcC1sZXZlbCBzaWJsaW5ncyBhcmUgY29oZXJlbnRcbiAgICAgICAgc2xpY2UgPSBTbGljZS5tYXhPcGVuKG5vcm1hbGl6ZVNpYmxpbmdzKHNsaWNlLmNvbnRlbnQsICRjb250ZXh0KSwgdHJ1ZSk7XG4gICAgICAgIGlmIChzbGljZS5vcGVuU3RhcnQgfHwgc2xpY2Uub3BlbkVuZCkge1xuICAgICAgICAgICAgbGV0IG9wZW5TdGFydCA9IDAsIG9wZW5FbmQgPSAwO1xuICAgICAgICAgICAgZm9yIChsZXQgbm9kZSA9IHNsaWNlLmNvbnRlbnQuZmlyc3RDaGlsZDsgb3BlblN0YXJ0IDwgc2xpY2Uub3BlblN0YXJ0ICYmICFub2RlLnR5cGUuc3BlYy5pc29sYXRpbmc7IG9wZW5TdGFydCsrLCBub2RlID0gbm9kZS5maXJzdENoaWxkKSB7IH1cbiAgICAgICAgICAgIGZvciAobGV0IG5vZGUgPSBzbGljZS5jb250ZW50Lmxhc3RDaGlsZDsgb3BlbkVuZCA8IHNsaWNlLm9wZW5FbmQgJiYgIW5vZGUudHlwZS5zcGVjLmlzb2xhdGluZzsgb3BlbkVuZCsrLCBub2RlID0gbm9kZS5sYXN0Q2hpbGQpIHsgfVxuICAgICAgICAgICAgc2xpY2UgPSBjbG9zZVNsaWNlKHNsaWNlLCBvcGVuU3RhcnQsIG9wZW5FbmQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZpZXcuc29tZVByb3AoXCJ0cmFuc2Zvcm1QYXN0ZWRcIiwgZiA9PiB7IHNsaWNlID0gZihzbGljZSwgdmlldywgYXNUZXh0KTsgfSk7XG4gICAgcmV0dXJuIHNsaWNlO1xufVxuY29uc3QgaW5saW5lUGFyZW50cyA9IC9eKGF8YWJicnxhY3JvbnltfGJ8Y2l0ZXxjb2RlfGRlbHxlbXxpfGluc3xrYmR8bGFiZWx8b3V0cHV0fHF8cnVieXxzfHNhbXB8c3BhbnxzdHJvbmd8c3VifHN1cHx0aW1lfHV8dHR8dmFyKSQvaTtcbi8vIFRha2VzIGEgc2xpY2UgcGFyc2VkIHdpdGggcGFyc2VTbGljZSwgd2hpY2ggbWVhbnMgdGhlcmUgaGFzbid0IGJlZW5cbi8vIGFueSBjb250ZW50LWV4cHJlc3Npb24gY2hlY2tpbmcgZG9uZSBvbiB0aGUgdG9wIG5vZGVzLCB0cmllcyB0b1xuLy8gZmluZCBhIHBhcmVudCBub2RlIGluIHRoZSBjdXJyZW50IGNvbnRleHQgdGhhdCBtaWdodCBmaXQgdGhlIG5vZGVzLFxuLy8gYW5kIGlmIHN1Y2Nlc3NmdWwsIHJlYnVpbGRzIHRoZSBzbGljZSBzbyB0aGF0IGl0IGZpdHMgaW50byB0aGF0IHBhcmVudC5cbi8vXG4vLyBUaGlzIGFkZHJlc3NlcyB0aGUgcHJvYmxlbSB0aGF0IFRyYW5zZm9ybS5yZXBsYWNlIGV4cGVjdHMgYVxuLy8gY29oZXJlbnQgc2xpY2UsIGFuZCB3aWxsIGZhaWwgdG8gcGxhY2UgYSBzZXQgb2Ygc2libGluZ3MgdGhhdCBkb24ndFxuLy8gZml0IGFueXdoZXJlIGluIHRoZSBzY2hlbWEuXG5mdW5jdGlvbiBub3JtYWxpemVTaWJsaW5ncyhmcmFnbWVudCwgJGNvbnRleHQpIHtcbiAgICBpZiAoZnJhZ21lbnQuY2hpbGRDb3VudCA8IDIpXG4gICAgICAgIHJldHVybiBmcmFnbWVudDtcbiAgICBmb3IgKGxldCBkID0gJGNvbnRleHQuZGVwdGg7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgIGxldCBwYXJlbnQgPSAkY29udGV4dC5ub2RlKGQpO1xuICAgICAgICBsZXQgbWF0Y2ggPSBwYXJlbnQuY29udGVudE1hdGNoQXQoJGNvbnRleHQuaW5kZXgoZCkpO1xuICAgICAgICBsZXQgbGFzdFdyYXAsIHJlc3VsdCA9IFtdO1xuICAgICAgICBmcmFnbWVudC5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgaWYgKCFyZXN1bHQpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgbGV0IHdyYXAgPSBtYXRjaC5maW5kV3JhcHBpbmcobm9kZS50eXBlKSwgaW5MYXN0O1xuICAgICAgICAgICAgaWYgKCF3cmFwKVxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgPSBudWxsO1xuICAgICAgICAgICAgaWYgKGluTGFzdCA9IHJlc3VsdC5sZW5ndGggJiYgbGFzdFdyYXAubGVuZ3RoICYmIGFkZFRvU2libGluZyh3cmFwLCBsYXN0V3JhcCwgbm9kZSwgcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXSwgMCkpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRbcmVzdWx0Lmxlbmd0aCAtIDFdID0gaW5MYXN0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV0gPSBjbG9zZVJpZ2h0KHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV0sIGxhc3RXcmFwLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgbGV0IHdyYXBwZWQgPSB3aXRoV3JhcHBlcnMobm9kZSwgd3JhcCk7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2god3JhcHBlZCk7XG4gICAgICAgICAgICAgICAgbWF0Y2ggPSBtYXRjaC5tYXRjaFR5cGUod3JhcHBlZC50eXBlKTtcbiAgICAgICAgICAgICAgICBsYXN0V3JhcCA9IHdyYXA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0KVxuICAgICAgICAgICAgcmV0dXJuIEZyYWdtZW50LmZyb20ocmVzdWx0KTtcbiAgICB9XG4gICAgcmV0dXJuIGZyYWdtZW50O1xufVxuZnVuY3Rpb24gd2l0aFdyYXBwZXJzKG5vZGUsIHdyYXAsIGZyb20gPSAwKSB7XG4gICAgZm9yIChsZXQgaSA9IHdyYXAubGVuZ3RoIC0gMTsgaSA+PSBmcm9tOyBpLS0pXG4gICAgICAgIG5vZGUgPSB3cmFwW2ldLmNyZWF0ZShudWxsLCBGcmFnbWVudC5mcm9tKG5vZGUpKTtcbiAgICByZXR1cm4gbm9kZTtcbn1cbi8vIFVzZWQgdG8gZ3JvdXAgYWRqYWNlbnQgbm9kZXMgd3JhcHBlZCBpbiBzaW1pbGFyIHBhcmVudHMgYnlcbi8vIG5vcm1hbGl6ZVNpYmxpbmdzIGludG8gdGhlIHNhbWUgcGFyZW50IG5vZGVcbmZ1bmN0aW9uIGFkZFRvU2libGluZyh3cmFwLCBsYXN0V3JhcCwgbm9kZSwgc2libGluZywgZGVwdGgpIHtcbiAgICBpZiAoZGVwdGggPCB3cmFwLmxlbmd0aCAmJiBkZXB0aCA8IGxhc3RXcmFwLmxlbmd0aCAmJiB3cmFwW2RlcHRoXSA9PSBsYXN0V3JhcFtkZXB0aF0pIHtcbiAgICAgICAgbGV0IGlubmVyID0gYWRkVG9TaWJsaW5nKHdyYXAsIGxhc3RXcmFwLCBub2RlLCBzaWJsaW5nLmxhc3RDaGlsZCwgZGVwdGggKyAxKTtcbiAgICAgICAgaWYgKGlubmVyKVxuICAgICAgICAgICAgcmV0dXJuIHNpYmxpbmcuY29weShzaWJsaW5nLmNvbnRlbnQucmVwbGFjZUNoaWxkKHNpYmxpbmcuY2hpbGRDb3VudCAtIDEsIGlubmVyKSk7XG4gICAgICAgIGxldCBtYXRjaCA9IHNpYmxpbmcuY29udGVudE1hdGNoQXQoc2libGluZy5jaGlsZENvdW50KTtcbiAgICAgICAgaWYgKG1hdGNoLm1hdGNoVHlwZShkZXB0aCA9PSB3cmFwLmxlbmd0aCAtIDEgPyBub2RlLnR5cGUgOiB3cmFwW2RlcHRoICsgMV0pKVxuICAgICAgICAgICAgcmV0dXJuIHNpYmxpbmcuY29weShzaWJsaW5nLmNvbnRlbnQuYXBwZW5kKEZyYWdtZW50LmZyb20od2l0aFdyYXBwZXJzKG5vZGUsIHdyYXAsIGRlcHRoICsgMSkpKSk7XG4gICAgfVxufVxuZnVuY3Rpb24gY2xvc2VSaWdodChub2RlLCBkZXB0aCkge1xuICAgIGlmIChkZXB0aCA9PSAwKVxuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICBsZXQgZnJhZ21lbnQgPSBub2RlLmNvbnRlbnQucmVwbGFjZUNoaWxkKG5vZGUuY2hpbGRDb3VudCAtIDEsIGNsb3NlUmlnaHQobm9kZS5sYXN0Q2hpbGQsIGRlcHRoIC0gMSkpO1xuICAgIGxldCBmaWxsID0gbm9kZS5jb250ZW50TWF0Y2hBdChub2RlLmNoaWxkQ291bnQpLmZpbGxCZWZvcmUoRnJhZ21lbnQuZW1wdHksIHRydWUpO1xuICAgIHJldHVybiBub2RlLmNvcHkoZnJhZ21lbnQuYXBwZW5kKGZpbGwpKTtcbn1cbmZ1bmN0aW9uIGNsb3NlUmFuZ2UoZnJhZ21lbnQsIHNpZGUsIGZyb20sIHRvLCBkZXB0aCwgb3BlbkVuZCkge1xuICAgIGxldCBub2RlID0gc2lkZSA8IDAgPyBmcmFnbWVudC5maXJzdENoaWxkIDogZnJhZ21lbnQubGFzdENoaWxkLCBpbm5lciA9IG5vZGUuY29udGVudDtcbiAgICBpZiAoZnJhZ21lbnQuY2hpbGRDb3VudCA+IDEpXG4gICAgICAgIG9wZW5FbmQgPSAwO1xuICAgIGlmIChkZXB0aCA8IHRvIC0gMSlcbiAgICAgICAgaW5uZXIgPSBjbG9zZVJhbmdlKGlubmVyLCBzaWRlLCBmcm9tLCB0bywgZGVwdGggKyAxLCBvcGVuRW5kKTtcbiAgICBpZiAoZGVwdGggPj0gZnJvbSlcbiAgICAgICAgaW5uZXIgPSBzaWRlIDwgMCA/IG5vZGUuY29udGVudE1hdGNoQXQoMCkuZmlsbEJlZm9yZShpbm5lciwgb3BlbkVuZCA8PSBkZXB0aCkuYXBwZW5kKGlubmVyKVxuICAgICAgICAgICAgOiBpbm5lci5hcHBlbmQobm9kZS5jb250ZW50TWF0Y2hBdChub2RlLmNoaWxkQ291bnQpLmZpbGxCZWZvcmUoRnJhZ21lbnQuZW1wdHksIHRydWUpKTtcbiAgICByZXR1cm4gZnJhZ21lbnQucmVwbGFjZUNoaWxkKHNpZGUgPCAwID8gMCA6IGZyYWdtZW50LmNoaWxkQ291bnQgLSAxLCBub2RlLmNvcHkoaW5uZXIpKTtcbn1cbmZ1bmN0aW9uIGNsb3NlU2xpY2Uoc2xpY2UsIG9wZW5TdGFydCwgb3BlbkVuZCkge1xuICAgIGlmIChvcGVuU3RhcnQgPCBzbGljZS5vcGVuU3RhcnQpXG4gICAgICAgIHNsaWNlID0gbmV3IFNsaWNlKGNsb3NlUmFuZ2Uoc2xpY2UuY29udGVudCwgLTEsIG9wZW5TdGFydCwgc2xpY2Uub3BlblN0YXJ0LCAwLCBzbGljZS5vcGVuRW5kKSwgb3BlblN0YXJ0LCBzbGljZS5vcGVuRW5kKTtcbiAgICBpZiAob3BlbkVuZCA8IHNsaWNlLm9wZW5FbmQpXG4gICAgICAgIHNsaWNlID0gbmV3IFNsaWNlKGNsb3NlUmFuZ2Uoc2xpY2UuY29udGVudCwgMSwgb3BlbkVuZCwgc2xpY2Uub3BlbkVuZCwgMCwgMCksIHNsaWNlLm9wZW5TdGFydCwgb3BlbkVuZCk7XG4gICAgcmV0dXJuIHNsaWNlO1xufVxuLy8gVHJpY2sgZnJvbSBqUXVlcnkgLS0gc29tZSBlbGVtZW50cyBtdXN0IGJlIHdyYXBwZWQgaW4gb3RoZXJcbi8vIGVsZW1lbnRzIGZvciBpbm5lckhUTUwgdG8gd29yay4gSS5lLiBpZiB5b3UgZG8gYGRpdi5pbm5lckhUTUwgPVxuLy8gXCI8dGQ+Li48L3RkPlwiYCB0aGUgdGFibGUgY2VsbHMgYXJlIGlnbm9yZWQuXG5jb25zdCB3cmFwTWFwID0ge1xuICAgIHRoZWFkOiBbXCJ0YWJsZVwiXSxcbiAgICB0Ym9keTogW1widGFibGVcIl0sXG4gICAgdGZvb3Q6IFtcInRhYmxlXCJdLFxuICAgIGNhcHRpb246IFtcInRhYmxlXCJdLFxuICAgIGNvbGdyb3VwOiBbXCJ0YWJsZVwiXSxcbiAgICBjb2w6IFtcInRhYmxlXCIsIFwiY29sZ3JvdXBcIl0sXG4gICAgdHI6IFtcInRhYmxlXCIsIFwidGJvZHlcIl0sXG4gICAgdGQ6IFtcInRhYmxlXCIsIFwidGJvZHlcIiwgXCJ0clwiXSxcbiAgICB0aDogW1widGFibGVcIiwgXCJ0Ym9keVwiLCBcInRyXCJdXG59O1xubGV0IF9kZXRhY2hlZERvYyA9IG51bGw7XG5mdW5jdGlvbiBkZXRhY2hlZERvYygpIHtcbiAgICByZXR1cm4gX2RldGFjaGVkRG9jIHx8IChfZGV0YWNoZWREb2MgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoXCJ0aXRsZVwiKSk7XG59XG5sZXQgX3BvbGljeSA9IG51bGw7XG5mdW5jdGlvbiBtYXliZVdyYXBUcnVzdGVkKGh0bWwpIHtcbiAgICBsZXQgdHJ1c3RlZFR5cGVzID0gd2luZG93LnRydXN0ZWRUeXBlcztcbiAgICBpZiAoIXRydXN0ZWRUeXBlcylcbiAgICAgICAgcmV0dXJuIGh0bWw7XG4gICAgLy8gV2l0aCB0aGUgcmVxdWlyZS10cnVzdGVkLXR5cGVzLWZvciBDU1AsIENocm9tZSB3aWxsIGJsb2NrXG4gICAgLy8gaW5uZXJIVE1MLCBldmVuIG9uIGEgZGV0YWNoZWQgZG9jdW1lbnQuIFRoaXMgd3JhcHMgdGhlIHN0cmluZyBpblxuICAgIC8vIGEgd2F5IHRoYXQgbWFrZXMgdGhlIGJyb3dzZXIgYWxsb3cgdXMgdG8gdXNlIGl0cyBwYXJzZXIgYWdhaW4uXG4gICAgaWYgKCFfcG9saWN5KVxuICAgICAgICBfcG9saWN5ID0gdHJ1c3RlZFR5cGVzLmRlZmF1bHRQb2xpY3kgfHwgdHJ1c3RlZFR5cGVzLmNyZWF0ZVBvbGljeShcIlByb3NlTWlycm9yQ2xpcGJvYXJkXCIsIHsgY3JlYXRlSFRNTDogKHMpID0+IHMgfSk7XG4gICAgcmV0dXJuIF9wb2xpY3kuY3JlYXRlSFRNTChodG1sKTtcbn1cbmZ1bmN0aW9uIHJlYWRIVE1MKGh0bWwpIHtcbiAgICBsZXQgbWV0YXMgPSAvXihcXHMqPG1ldGEgW14+XSo+KSovLmV4ZWMoaHRtbCk7XG4gICAgaWYgKG1ldGFzKVxuICAgICAgICBodG1sID0gaHRtbC5zbGljZShtZXRhc1swXS5sZW5ndGgpO1xuICAgIGxldCBlbHQgPSBkZXRhY2hlZERvYygpLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgbGV0IGZpcnN0VGFnID0gLzwoW2Etel1bXj5cXHNdKykvaS5leGVjKGh0bWwpLCB3cmFwO1xuICAgIGlmICh3cmFwID0gZmlyc3RUYWcgJiYgd3JhcE1hcFtmaXJzdFRhZ1sxXS50b0xvd2VyQ2FzZSgpXSlcbiAgICAgICAgaHRtbCA9IHdyYXAubWFwKG4gPT4gXCI8XCIgKyBuICsgXCI+XCIpLmpvaW4oXCJcIikgKyBodG1sICsgd3JhcC5tYXAobiA9PiBcIjwvXCIgKyBuICsgXCI+XCIpLnJldmVyc2UoKS5qb2luKFwiXCIpO1xuICAgIGVsdC5pbm5lckhUTUwgPSBtYXliZVdyYXBUcnVzdGVkKGh0bWwpO1xuICAgIGlmICh3cmFwKVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHdyYXAubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBlbHQgPSBlbHQucXVlcnlTZWxlY3Rvcih3cmFwW2ldKSB8fCBlbHQ7XG4gICAgcmV0dXJuIGVsdDtcbn1cbi8vIFdlYmtpdCBicm93c2VycyBkbyBzb21lIGhhcmQtdG8tcHJlZGljdCByZXBsYWNlbWVudCBvZiByZWd1bGFyXG4vLyBzcGFjZXMgd2l0aCBub24tYnJlYWtpbmcgc3BhY2VzIHdoZW4gcHV0dGluZyBjb250ZW50IG9uIHRoZVxuLy8gY2xpcGJvYXJkLiBUaGlzIHRyaWVzIHRvIGNvbnZlcnQgc3VjaCBub24tYnJlYWtpbmcgc3BhY2VzICh3aGljaFxuLy8gd2lsbCBiZSB3cmFwcGVkIGluIGEgcGxhaW4gc3BhbiBvbiBDaHJvbWUsIGEgc3BhbiB3aXRoIGNsYXNzXG4vLyBBcHBsZS1jb252ZXJ0ZWQtc3BhY2Ugb24gU2FmYXJpKSBiYWNrIHRvIHJlZ3VsYXIgc3BhY2VzLlxuZnVuY3Rpb24gcmVzdG9yZVJlcGxhY2VkU3BhY2VzKGRvbSkge1xuICAgIGxldCBub2RlcyA9IGRvbS5xdWVyeVNlbGVjdG9yQWxsKGNocm9tZSA/IFwic3Bhbjpub3QoW2NsYXNzXSk6bm90KFtzdHlsZV0pXCIgOiBcInNwYW4uQXBwbGUtY29udmVydGVkLXNwYWNlXCIpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgaWYgKG5vZGUuY2hpbGROb2Rlcy5sZW5ndGggPT0gMSAmJiBub2RlLnRleHRDb250ZW50ID09IFwiXFx1MDBhMFwiICYmIG5vZGUucGFyZW50Tm9kZSlcbiAgICAgICAgICAgIG5vZGUucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoZG9tLm93bmVyRG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoXCIgXCIpLCBub2RlKTtcbiAgICB9XG59XG5mdW5jdGlvbiBhZGRDb250ZXh0KHNsaWNlLCBjb250ZXh0KSB7XG4gICAgaWYgKCFzbGljZS5zaXplKVxuICAgICAgICByZXR1cm4gc2xpY2U7XG4gICAgbGV0IHNjaGVtYSA9IHNsaWNlLmNvbnRlbnQuZmlyc3RDaGlsZC50eXBlLnNjaGVtYSwgYXJyYXk7XG4gICAgdHJ5IHtcbiAgICAgICAgYXJyYXkgPSBKU09OLnBhcnNlKGNvbnRleHQpO1xuICAgIH1cbiAgICBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gc2xpY2U7XG4gICAgfVxuICAgIGxldCB7IGNvbnRlbnQsIG9wZW5TdGFydCwgb3BlbkVuZCB9ID0gc2xpY2U7XG4gICAgZm9yIChsZXQgaSA9IGFycmF5Lmxlbmd0aCAtIDI7IGkgPj0gMDsgaSAtPSAyKSB7XG4gICAgICAgIGxldCB0eXBlID0gc2NoZW1hLm5vZGVzW2FycmF5W2ldXTtcbiAgICAgICAgaWYgKCF0eXBlIHx8IHR5cGUuaGFzUmVxdWlyZWRBdHRycygpKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNvbnRlbnQgPSBGcmFnbWVudC5mcm9tKHR5cGUuY3JlYXRlKGFycmF5W2kgKyAxXSwgY29udGVudCkpO1xuICAgICAgICBvcGVuU3RhcnQrKztcbiAgICAgICAgb3BlbkVuZCsrO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFNsaWNlKGNvbnRlbnQsIG9wZW5TdGFydCwgb3BlbkVuZCk7XG59XG5cbi8vIEEgY29sbGVjdGlvbiBvZiBET00gZXZlbnRzIHRoYXQgb2NjdXIgd2l0aGluIHRoZSBlZGl0b3IsIGFuZCBjYWxsYmFjayBmdW5jdGlvbnNcbi8vIHRvIGludm9rZSB3aGVuIHRoZSBldmVudCBmaXJlcy5cbmNvbnN0IGhhbmRsZXJzID0ge307XG5jb25zdCBlZGl0SGFuZGxlcnMgPSB7fTtcbmNvbnN0IHBhc3NpdmVIYW5kbGVycyA9IHsgdG91Y2hzdGFydDogdHJ1ZSwgdG91Y2htb3ZlOiB0cnVlIH07XG5jbGFzcyBJbnB1dFN0YXRlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5zaGlmdEtleSA9IGZhbHNlO1xuICAgICAgICB0aGlzLm1vdXNlRG93biA9IG51bGw7XG4gICAgICAgIHRoaXMubGFzdEtleUNvZGUgPSBudWxsO1xuICAgICAgICB0aGlzLmxhc3RLZXlDb2RlVGltZSA9IDA7XG4gICAgICAgIHRoaXMubGFzdENsaWNrID0geyB0aW1lOiAwLCB4OiAwLCB5OiAwLCB0eXBlOiBcIlwiLCBidXR0b246IDAgfTtcbiAgICAgICAgdGhpcy5sYXN0U2VsZWN0aW9uT3JpZ2luID0gbnVsbDtcbiAgICAgICAgdGhpcy5sYXN0U2VsZWN0aW9uVGltZSA9IDA7XG4gICAgICAgIHRoaXMubGFzdElPU0VudGVyID0gMDtcbiAgICAgICAgdGhpcy5sYXN0SU9TRW50ZXJGYWxsYmFja1RpbWVvdXQgPSAtMTtcbiAgICAgICAgdGhpcy5sYXN0Rm9jdXMgPSAwO1xuICAgICAgICB0aGlzLmxhc3RUb3VjaCA9IDA7XG4gICAgICAgIHRoaXMubGFzdENocm9tZURlbGV0ZSA9IDA7XG4gICAgICAgIHRoaXMuY29tcG9zaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY29tcG9zaXRpb25Ob2RlID0gbnVsbDtcbiAgICAgICAgdGhpcy5jb21wb3NpbmdUaW1lb3V0ID0gLTE7XG4gICAgICAgIHRoaXMuY29tcG9zaXRpb25Ob2RlcyA9IFtdO1xuICAgICAgICB0aGlzLmNvbXBvc2l0aW9uRW5kZWRBdCA9IC0yZTg7XG4gICAgICAgIHRoaXMuY29tcG9zaXRpb25JRCA9IDE7XG4gICAgICAgIHRoaXMuYmFkU2FmYXJpQ29tcG9zaXRpb24gPSBmYWxzZTtcbiAgICAgICAgLy8gU2V0IHRvIGEgY29tcG9zaXRpb24gSUQgd2hlbiB0aGVyZSBhcmUgcGVuZGluZyBjaGFuZ2VzIGF0IGNvbXBvc2l0aW9uZW5kXG4gICAgICAgIHRoaXMuY29tcG9zaXRpb25QZW5kaW5nQ2hhbmdlcyA9IDA7XG4gICAgICAgIHRoaXMuZG9tQ2hhbmdlQ291bnQgPSAwO1xuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLmhpZGVTZWxlY3Rpb25HdWFyZCA9IG51bGw7XG4gICAgfVxufVxuZnVuY3Rpb24gaW5pdElucHV0KHZpZXcpIHtcbiAgICBmb3IgKGxldCBldmVudCBpbiBoYW5kbGVycykge1xuICAgICAgICBsZXQgaGFuZGxlciA9IGhhbmRsZXJzW2V2ZW50XTtcbiAgICAgICAgdmlldy5kb20uYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgdmlldy5pbnB1dC5ldmVudEhhbmRsZXJzW2V2ZW50XSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50QmVsb25nc1RvVmlldyh2aWV3LCBldmVudCkgJiYgIXJ1bkN1c3RvbUhhbmRsZXIodmlldywgZXZlbnQpICYmXG4gICAgICAgICAgICAgICAgKHZpZXcuZWRpdGFibGUgfHwgIShldmVudC50eXBlIGluIGVkaXRIYW5kbGVycykpKVxuICAgICAgICAgICAgICAgIGhhbmRsZXIodmlldywgZXZlbnQpO1xuICAgICAgICB9LCBwYXNzaXZlSGFuZGxlcnNbZXZlbnRdID8geyBwYXNzaXZlOiB0cnVlIH0gOiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvLyBPbiBTYWZhcmksIGZvciByZWFzb25zIGJleW9uZCBteSB1bmRlcnN0YW5kaW5nLCBhZGRpbmcgYW4gaW5wdXRcbiAgICAvLyBldmVudCBoYW5kbGVyIG1ha2VzIGFuIGlzc3VlIHdoZXJlIHRoZSBjb21wb3NpdGlvbiB2YW5pc2hlcyB3aGVuXG4gICAgLy8geW91IHByZXNzIGVudGVyIGdvIGF3YXkuXG4gICAgaWYgKHNhZmFyaSlcbiAgICAgICAgdmlldy5kb20uYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsICgpID0+IG51bGwpO1xuICAgIGVuc3VyZUxpc3RlbmVycyh2aWV3KTtcbn1cbmZ1bmN0aW9uIHNldFNlbGVjdGlvbk9yaWdpbih2aWV3LCBvcmlnaW4pIHtcbiAgICB2aWV3LmlucHV0Lmxhc3RTZWxlY3Rpb25PcmlnaW4gPSBvcmlnaW47XG4gICAgdmlldy5pbnB1dC5sYXN0U2VsZWN0aW9uVGltZSA9IERhdGUubm93KCk7XG59XG5mdW5jdGlvbiBkZXN0cm95SW5wdXQodmlldykge1xuICAgIHZpZXcuZG9tT2JzZXJ2ZXIuc3RvcCgpO1xuICAgIGZvciAobGV0IHR5cGUgaW4gdmlldy5pbnB1dC5ldmVudEhhbmRsZXJzKVxuICAgICAgICB2aWV3LmRvbS5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIHZpZXcuaW5wdXQuZXZlbnRIYW5kbGVyc1t0eXBlXSk7XG4gICAgY2xlYXJUaW1lb3V0KHZpZXcuaW5wdXQuY29tcG9zaW5nVGltZW91dCk7XG4gICAgY2xlYXJUaW1lb3V0KHZpZXcuaW5wdXQubGFzdElPU0VudGVyRmFsbGJhY2tUaW1lb3V0KTtcbn1cbmZ1bmN0aW9uIGVuc3VyZUxpc3RlbmVycyh2aWV3KSB7XG4gICAgdmlldy5zb21lUHJvcChcImhhbmRsZURPTUV2ZW50c1wiLCBjdXJyZW50SGFuZGxlcnMgPT4ge1xuICAgICAgICBmb3IgKGxldCB0eXBlIGluIGN1cnJlbnRIYW5kbGVycylcbiAgICAgICAgICAgIGlmICghdmlldy5pbnB1dC5ldmVudEhhbmRsZXJzW3R5cGVdKVxuICAgICAgICAgICAgICAgIHZpZXcuZG9tLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgdmlldy5pbnB1dC5ldmVudEhhbmRsZXJzW3R5cGVdID0gZXZlbnQgPT4gcnVuQ3VzdG9tSGFuZGxlcih2aWV3LCBldmVudCkpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gcnVuQ3VzdG9tSGFuZGxlcih2aWV3LCBldmVudCkge1xuICAgIHJldHVybiB2aWV3LnNvbWVQcm9wKFwiaGFuZGxlRE9NRXZlbnRzXCIsIGhhbmRsZXJzID0+IHtcbiAgICAgICAgbGV0IGhhbmRsZXIgPSBoYW5kbGVyc1tldmVudC50eXBlXTtcbiAgICAgICAgcmV0dXJuIGhhbmRsZXIgPyBoYW5kbGVyKHZpZXcsIGV2ZW50KSB8fCBldmVudC5kZWZhdWx0UHJldmVudGVkIDogZmFsc2U7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBldmVudEJlbG9uZ3NUb1ZpZXcodmlldywgZXZlbnQpIHtcbiAgICBpZiAoIWV2ZW50LmJ1YmJsZXMpXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIGlmIChldmVudC5kZWZhdWx0UHJldmVudGVkKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgZm9yIChsZXQgbm9kZSA9IGV2ZW50LnRhcmdldDsgbm9kZSAhPSB2aWV3LmRvbTsgbm9kZSA9IG5vZGUucGFyZW50Tm9kZSlcbiAgICAgICAgaWYgKCFub2RlIHx8IG5vZGUubm9kZVR5cGUgPT0gMTEgfHxcbiAgICAgICAgICAgIChub2RlLnBtVmlld0Rlc2MgJiYgbm9kZS5wbVZpZXdEZXNjLnN0b3BFdmVudChldmVudCkpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudCh2aWV3LCBldmVudCkge1xuICAgIGlmICghcnVuQ3VzdG9tSGFuZGxlcih2aWV3LCBldmVudCkgJiYgaGFuZGxlcnNbZXZlbnQudHlwZV0gJiZcbiAgICAgICAgKHZpZXcuZWRpdGFibGUgfHwgIShldmVudC50eXBlIGluIGVkaXRIYW5kbGVycykpKVxuICAgICAgICBoYW5kbGVyc1tldmVudC50eXBlXSh2aWV3LCBldmVudCk7XG59XG5lZGl0SGFuZGxlcnMua2V5ZG93biA9ICh2aWV3LCBfZXZlbnQpID0+IHtcbiAgICBsZXQgZXZlbnQgPSBfZXZlbnQ7XG4gICAgdmlldy5pbnB1dC5zaGlmdEtleSA9IGV2ZW50LmtleUNvZGUgPT0gMTYgfHwgZXZlbnQuc2hpZnRLZXk7XG4gICAgaWYgKGluT3JOZWFyQ29tcG9zaXRpb24odmlldywgZXZlbnQpKVxuICAgICAgICByZXR1cm47XG4gICAgdmlldy5pbnB1dC5sYXN0S2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7XG4gICAgdmlldy5pbnB1dC5sYXN0S2V5Q29kZVRpbWUgPSBEYXRlLm5vdygpO1xuICAgIC8vIFN1cHByZXNzIGVudGVyIGtleSBldmVudHMgb24gQ2hyb21lIEFuZHJvaWQsIGJlY2F1c2UgdGhvc2UgdGVuZFxuICAgIC8vIHRvIGJlIHBhcnQgb2YgYSBjb25mdXNlZCBzZXF1ZW5jZSBvZiBjb21wb3NpdGlvbiBldmVudHMgZmlyZWQsXG4gICAgLy8gYW5kIGhhbmRsaW5nIHRoZW0gZWFnZXJseSB0ZW5kcyB0byBjb3JydXB0IHRoZSBpbnB1dC5cbiAgICBpZiAoYW5kcm9pZCAmJiBjaHJvbWUgJiYgZXZlbnQua2V5Q29kZSA9PSAxMylcbiAgICAgICAgcmV0dXJuO1xuICAgIGlmIChldmVudC5rZXlDb2RlICE9IDIyOSlcbiAgICAgICAgdmlldy5kb21PYnNlcnZlci5mb3JjZUZsdXNoKCk7XG4gICAgLy8gT24gaU9TLCBpZiB3ZSBwcmV2ZW50RGVmYXVsdCBlbnRlciBrZXkgcHJlc3NlcywgdGhlIHZpcnR1YWxcbiAgICAvLyBrZXlib2FyZCBnZXRzIGNvbmZ1c2VkLiBTbyB0aGUgaGFjayBoZXJlIGlzIHRvIHNldCBhIGZsYWcgdGhhdFxuICAgIC8vIG1ha2VzIHRoZSBET00gY2hhbmdlIGNvZGUgcmVjb2duaXplIHRoYXQgd2hhdCBqdXN0IGhhcHBlbnMgc2hvdWxkXG4gICAgLy8gYmUgcmVwbGFjZWQgYnkgd2hhdGV2ZXIgdGhlIEVudGVyIGtleSBoYW5kbGVycyBkby5cbiAgICBpZiAoaW9zICYmIGV2ZW50LmtleUNvZGUgPT0gMTMgJiYgIWV2ZW50LmN0cmxLZXkgJiYgIWV2ZW50LmFsdEtleSAmJiAhZXZlbnQubWV0YUtleSkge1xuICAgICAgICBsZXQgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdmlldy5pbnB1dC5sYXN0SU9TRW50ZXIgPSBub3c7XG4gICAgICAgIHZpZXcuaW5wdXQubGFzdElPU0VudGVyRmFsbGJhY2tUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodmlldy5pbnB1dC5sYXN0SU9TRW50ZXIgPT0gbm93KSB7XG4gICAgICAgICAgICAgICAgdmlldy5zb21lUHJvcChcImhhbmRsZUtleURvd25cIiwgZiA9PiBmKHZpZXcsIGtleUV2ZW50KDEzLCBcIkVudGVyXCIpKSk7XG4gICAgICAgICAgICAgICAgdmlldy5pbnB1dC5sYXN0SU9TRW50ZXIgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCAyMDApO1xuICAgIH1cbiAgICBlbHNlIGlmICh2aWV3LnNvbWVQcm9wKFwiaGFuZGxlS2V5RG93blwiLCBmID0+IGYodmlldywgZXZlbnQpKSB8fCBjYXB0dXJlS2V5RG93bih2aWV3LCBldmVudCkpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNldFNlbGVjdGlvbk9yaWdpbih2aWV3LCBcImtleVwiKTtcbiAgICB9XG59O1xuZWRpdEhhbmRsZXJzLmtleXVwID0gKHZpZXcsIGV2ZW50KSA9PiB7XG4gICAgaWYgKGV2ZW50LmtleUNvZGUgPT0gMTYpXG4gICAgICAgIHZpZXcuaW5wdXQuc2hpZnRLZXkgPSBmYWxzZTtcbn07XG5lZGl0SGFuZGxlcnMua2V5cHJlc3MgPSAodmlldywgX2V2ZW50KSA9PiB7XG4gICAgbGV0IGV2ZW50ID0gX2V2ZW50O1xuICAgIGlmIChpbk9yTmVhckNvbXBvc2l0aW9uKHZpZXcsIGV2ZW50KSB8fCAhZXZlbnQuY2hhckNvZGUgfHxcbiAgICAgICAgZXZlbnQuY3RybEtleSAmJiAhZXZlbnQuYWx0S2V5IHx8IG1hYyAmJiBldmVudC5tZXRhS2V5KVxuICAgICAgICByZXR1cm47XG4gICAgaWYgKHZpZXcuc29tZVByb3AoXCJoYW5kbGVLZXlQcmVzc1wiLCBmID0+IGYodmlldywgZXZlbnQpKSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBzZWwgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbjtcbiAgICBpZiAoIShzZWwgaW5zdGFuY2VvZiBUZXh0U2VsZWN0aW9uKSB8fCAhc2VsLiRmcm9tLnNhbWVQYXJlbnQoc2VsLiR0bykpIHtcbiAgICAgICAgbGV0IHRleHQgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGV2ZW50LmNoYXJDb2RlKTtcbiAgICAgICAgbGV0IGRlZmx0ID0gKCkgPT4gdmlldy5zdGF0ZS50ci5pbnNlcnRUZXh0KHRleHQpLnNjcm9sbEludG9WaWV3KCk7XG4gICAgICAgIGlmICghL1tcXHJcXG5dLy50ZXN0KHRleHQpICYmICF2aWV3LnNvbWVQcm9wKFwiaGFuZGxlVGV4dElucHV0XCIsIGYgPT4gZih2aWV3LCBzZWwuJGZyb20ucG9zLCBzZWwuJHRvLnBvcywgdGV4dCwgZGVmbHQpKSlcbiAgICAgICAgICAgIHZpZXcuZGlzcGF0Y2goZGVmbHQoKSk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxufTtcbmZ1bmN0aW9uIGV2ZW50Q29vcmRzKGV2ZW50KSB7IHJldHVybiB7IGxlZnQ6IGV2ZW50LmNsaWVudFgsIHRvcDogZXZlbnQuY2xpZW50WSB9OyB9XG5mdW5jdGlvbiBpc05lYXIoZXZlbnQsIGNsaWNrKSB7XG4gICAgbGV0IGR4ID0gY2xpY2sueCAtIGV2ZW50LmNsaWVudFgsIGR5ID0gY2xpY2sueSAtIGV2ZW50LmNsaWVudFk7XG4gICAgcmV0dXJuIGR4ICogZHggKyBkeSAqIGR5IDwgMTAwO1xufVxuZnVuY3Rpb24gcnVuSGFuZGxlck9uQ29udGV4dCh2aWV3LCBwcm9wTmFtZSwgcG9zLCBpbnNpZGUsIGV2ZW50KSB7XG4gICAgaWYgKGluc2lkZSA9PSAtMSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCAkcG9zID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShpbnNpZGUpO1xuICAgIGZvciAobGV0IGkgPSAkcG9zLmRlcHRoICsgMTsgaSA+IDA7IGktLSkge1xuICAgICAgICBpZiAodmlldy5zb21lUHJvcChwcm9wTmFtZSwgZiA9PiBpID4gJHBvcy5kZXB0aCA/IGYodmlldywgcG9zLCAkcG9zLm5vZGVBZnRlciwgJHBvcy5iZWZvcmUoaSksIGV2ZW50LCB0cnVlKVxuICAgICAgICAgICAgOiBmKHZpZXcsIHBvcywgJHBvcy5ub2RlKGkpLCAkcG9zLmJlZm9yZShpKSwgZXZlbnQsIGZhbHNlKSkpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gdXBkYXRlU2VsZWN0aW9uKHZpZXcsIHNlbGVjdGlvbiwgb3JpZ2luKSB7XG4gICAgaWYgKCF2aWV3LmZvY3VzZWQpXG4gICAgICAgIHZpZXcuZm9jdXMoKTtcbiAgICBpZiAodmlldy5zdGF0ZS5zZWxlY3Rpb24uZXEoc2VsZWN0aW9uKSlcbiAgICAgICAgcmV0dXJuO1xuICAgIGxldCB0ciA9IHZpZXcuc3RhdGUudHIuc2V0U2VsZWN0aW9uKHNlbGVjdGlvbik7XG4gICAgaWYgKG9yaWdpbiA9PSBcInBvaW50ZXJcIilcbiAgICAgICAgdHIuc2V0TWV0YShcInBvaW50ZXJcIiwgdHJ1ZSk7XG4gICAgdmlldy5kaXNwYXRjaCh0cik7XG59XG5mdW5jdGlvbiBzZWxlY3RDbGlja2VkTGVhZih2aWV3LCBpbnNpZGUpIHtcbiAgICBpZiAoaW5zaWRlID09IC0xKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0ICRwb3MgPSB2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKGluc2lkZSksIG5vZGUgPSAkcG9zLm5vZGVBZnRlcjtcbiAgICBpZiAobm9kZSAmJiBub2RlLmlzQXRvbSAmJiBOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZShub2RlKSkge1xuICAgICAgICB1cGRhdGVTZWxlY3Rpb24odmlldywgbmV3IE5vZGVTZWxlY3Rpb24oJHBvcyksIFwicG9pbnRlclwiKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIHNlbGVjdENsaWNrZWROb2RlKHZpZXcsIGluc2lkZSkge1xuICAgIGlmIChpbnNpZGUgPT0gLTEpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgc2VsID0gdmlldy5zdGF0ZS5zZWxlY3Rpb24sIHNlbGVjdGVkTm9kZSwgc2VsZWN0QXQ7XG4gICAgaWYgKHNlbCBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24pXG4gICAgICAgIHNlbGVjdGVkTm9kZSA9IHNlbC5ub2RlO1xuICAgIGxldCAkcG9zID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShpbnNpZGUpO1xuICAgIGZvciAobGV0IGkgPSAkcG9zLmRlcHRoICsgMTsgaSA+IDA7IGktLSkge1xuICAgICAgICBsZXQgbm9kZSA9IGkgPiAkcG9zLmRlcHRoID8gJHBvcy5ub2RlQWZ0ZXIgOiAkcG9zLm5vZGUoaSk7XG4gICAgICAgIGlmIChOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZShub2RlKSkge1xuICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZSAmJiBzZWwuJGZyb20uZGVwdGggPiAwICYmXG4gICAgICAgICAgICAgICAgaSA+PSBzZWwuJGZyb20uZGVwdGggJiYgJHBvcy5iZWZvcmUoc2VsLiRmcm9tLmRlcHRoICsgMSkgPT0gc2VsLiRmcm9tLnBvcylcbiAgICAgICAgICAgICAgICBzZWxlY3RBdCA9ICRwb3MuYmVmb3JlKHNlbC4kZnJvbS5kZXB0aCk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgc2VsZWN0QXQgPSAkcG9zLmJlZm9yZShpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChzZWxlY3RBdCAhPSBudWxsKSB7XG4gICAgICAgIHVwZGF0ZVNlbGVjdGlvbih2aWV3LCBOb2RlU2VsZWN0aW9uLmNyZWF0ZSh2aWV3LnN0YXRlLmRvYywgc2VsZWN0QXQpLCBcInBvaW50ZXJcIik7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGhhbmRsZVNpbmdsZUNsaWNrKHZpZXcsIHBvcywgaW5zaWRlLCBldmVudCwgc2VsZWN0Tm9kZSkge1xuICAgIHJldHVybiBydW5IYW5kbGVyT25Db250ZXh0KHZpZXcsIFwiaGFuZGxlQ2xpY2tPblwiLCBwb3MsIGluc2lkZSwgZXZlbnQpIHx8XG4gICAgICAgIHZpZXcuc29tZVByb3AoXCJoYW5kbGVDbGlja1wiLCBmID0+IGYodmlldywgcG9zLCBldmVudCkpIHx8XG4gICAgICAgIChzZWxlY3ROb2RlID8gc2VsZWN0Q2xpY2tlZE5vZGUodmlldywgaW5zaWRlKSA6IHNlbGVjdENsaWNrZWRMZWFmKHZpZXcsIGluc2lkZSkpO1xufVxuZnVuY3Rpb24gaGFuZGxlRG91YmxlQ2xpY2sodmlldywgcG9zLCBpbnNpZGUsIGV2ZW50KSB7XG4gICAgcmV0dXJuIHJ1bkhhbmRsZXJPbkNvbnRleHQodmlldywgXCJoYW5kbGVEb3VibGVDbGlja09uXCIsIHBvcywgaW5zaWRlLCBldmVudCkgfHxcbiAgICAgICAgdmlldy5zb21lUHJvcChcImhhbmRsZURvdWJsZUNsaWNrXCIsIGYgPT4gZih2aWV3LCBwb3MsIGV2ZW50KSk7XG59XG5mdW5jdGlvbiBoYW5kbGVUcmlwbGVDbGljayh2aWV3LCBwb3MsIGluc2lkZSwgZXZlbnQpIHtcbiAgICByZXR1cm4gcnVuSGFuZGxlck9uQ29udGV4dCh2aWV3LCBcImhhbmRsZVRyaXBsZUNsaWNrT25cIiwgcG9zLCBpbnNpZGUsIGV2ZW50KSB8fFxuICAgICAgICB2aWV3LnNvbWVQcm9wKFwiaGFuZGxlVHJpcGxlQ2xpY2tcIiwgZiA9PiBmKHZpZXcsIHBvcywgZXZlbnQpKSB8fFxuICAgICAgICBkZWZhdWx0VHJpcGxlQ2xpY2sodmlldywgaW5zaWRlLCBldmVudCk7XG59XG5mdW5jdGlvbiBkZWZhdWx0VHJpcGxlQ2xpY2sodmlldywgaW5zaWRlLCBldmVudCkge1xuICAgIGlmIChldmVudC5idXR0b24gIT0gMClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCBkb2MgPSB2aWV3LnN0YXRlLmRvYztcbiAgICBpZiAoaW5zaWRlID09IC0xKSB7XG4gICAgICAgIGlmIChkb2MuaW5saW5lQ29udGVudCkge1xuICAgICAgICAgICAgdXBkYXRlU2VsZWN0aW9uKHZpZXcsIFRleHRTZWxlY3Rpb24uY3JlYXRlKGRvYywgMCwgZG9jLmNvbnRlbnQuc2l6ZSksIFwicG9pbnRlclwiKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgbGV0ICRwb3MgPSBkb2MucmVzb2x2ZShpbnNpZGUpO1xuICAgIGZvciAobGV0IGkgPSAkcG9zLmRlcHRoICsgMTsgaSA+IDA7IGktLSkge1xuICAgICAgICBsZXQgbm9kZSA9IGkgPiAkcG9zLmRlcHRoID8gJHBvcy5ub2RlQWZ0ZXIgOiAkcG9zLm5vZGUoaSk7XG4gICAgICAgIGxldCBub2RlUG9zID0gJHBvcy5iZWZvcmUoaSk7XG4gICAgICAgIGlmIChub2RlLmlubGluZUNvbnRlbnQpXG4gICAgICAgICAgICB1cGRhdGVTZWxlY3Rpb24odmlldywgVGV4dFNlbGVjdGlvbi5jcmVhdGUoZG9jLCBub2RlUG9zICsgMSwgbm9kZVBvcyArIDEgKyBub2RlLmNvbnRlbnQuc2l6ZSksIFwicG9pbnRlclwiKTtcbiAgICAgICAgZWxzZSBpZiAoTm9kZVNlbGVjdGlvbi5pc1NlbGVjdGFibGUobm9kZSkpXG4gICAgICAgICAgICB1cGRhdGVTZWxlY3Rpb24odmlldywgTm9kZVNlbGVjdGlvbi5jcmVhdGUoZG9jLCBub2RlUG9zKSwgXCJwb2ludGVyXCIpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxufVxuZnVuY3Rpb24gZm9yY2VET01GbHVzaCh2aWV3KSB7XG4gICAgcmV0dXJuIGVuZENvbXBvc2l0aW9uKHZpZXcpO1xufVxuY29uc3Qgc2VsZWN0Tm9kZU1vZGlmaWVyID0gbWFjID8gXCJtZXRhS2V5XCIgOiBcImN0cmxLZXlcIjtcbmhhbmRsZXJzLm1vdXNlZG93biA9ICh2aWV3LCBfZXZlbnQpID0+IHtcbiAgICBsZXQgZXZlbnQgPSBfZXZlbnQ7XG4gICAgdmlldy5pbnB1dC5zaGlmdEtleSA9IGV2ZW50LnNoaWZ0S2V5O1xuICAgIGxldCBmbHVzaGVkID0gZm9yY2VET01GbHVzaCh2aWV3KTtcbiAgICBsZXQgbm93ID0gRGF0ZS5ub3coKSwgdHlwZSA9IFwic2luZ2xlQ2xpY2tcIjtcbiAgICBpZiAobm93IC0gdmlldy5pbnB1dC5sYXN0Q2xpY2sudGltZSA8IDUwMCAmJiBpc05lYXIoZXZlbnQsIHZpZXcuaW5wdXQubGFzdENsaWNrKSAmJiAhZXZlbnRbc2VsZWN0Tm9kZU1vZGlmaWVyXSAmJlxuICAgICAgICB2aWV3LmlucHV0Lmxhc3RDbGljay5idXR0b24gPT0gZXZlbnQuYnV0dG9uKSB7XG4gICAgICAgIGlmICh2aWV3LmlucHV0Lmxhc3RDbGljay50eXBlID09IFwic2luZ2xlQ2xpY2tcIilcbiAgICAgICAgICAgIHR5cGUgPSBcImRvdWJsZUNsaWNrXCI7XG4gICAgICAgIGVsc2UgaWYgKHZpZXcuaW5wdXQubGFzdENsaWNrLnR5cGUgPT0gXCJkb3VibGVDbGlja1wiKVxuICAgICAgICAgICAgdHlwZSA9IFwidHJpcGxlQ2xpY2tcIjtcbiAgICB9XG4gICAgdmlldy5pbnB1dC5sYXN0Q2xpY2sgPSB7IHRpbWU6IG5vdywgeDogZXZlbnQuY2xpZW50WCwgeTogZXZlbnQuY2xpZW50WSwgdHlwZSwgYnV0dG9uOiBldmVudC5idXR0b24gfTtcbiAgICBsZXQgcG9zID0gdmlldy5wb3NBdENvb3JkcyhldmVudENvb3JkcyhldmVudCkpO1xuICAgIGlmICghcG9zKVxuICAgICAgICByZXR1cm47XG4gICAgaWYgKHR5cGUgPT0gXCJzaW5nbGVDbGlja1wiKSB7XG4gICAgICAgIGlmICh2aWV3LmlucHV0Lm1vdXNlRG93bilcbiAgICAgICAgICAgIHZpZXcuaW5wdXQubW91c2VEb3duLmRvbmUoKTtcbiAgICAgICAgdmlldy5pbnB1dC5tb3VzZURvd24gPSBuZXcgTW91c2VEb3duKHZpZXcsIHBvcywgZXZlbnQsICEhZmx1c2hlZCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKCh0eXBlID09IFwiZG91YmxlQ2xpY2tcIiA/IGhhbmRsZURvdWJsZUNsaWNrIDogaGFuZGxlVHJpcGxlQ2xpY2spKHZpZXcsIHBvcy5wb3MsIHBvcy5pbnNpZGUsIGV2ZW50KSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc2V0U2VsZWN0aW9uT3JpZ2luKHZpZXcsIFwicG9pbnRlclwiKTtcbiAgICB9XG59O1xuY2xhc3MgTW91c2VEb3duIHtcbiAgICBjb25zdHJ1Y3Rvcih2aWV3LCBwb3MsIGV2ZW50LCBmbHVzaGVkKSB7XG4gICAgICAgIHRoaXMudmlldyA9IHZpZXc7XG4gICAgICAgIHRoaXMucG9zID0gcG9zO1xuICAgICAgICB0aGlzLmV2ZW50ID0gZXZlbnQ7XG4gICAgICAgIHRoaXMuZmx1c2hlZCA9IGZsdXNoZWQ7XG4gICAgICAgIHRoaXMuZGVsYXllZFNlbGVjdGlvblN5bmMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5taWdodERyYWcgPSBudWxsO1xuICAgICAgICB0aGlzLnN0YXJ0RG9jID0gdmlldy5zdGF0ZS5kb2M7XG4gICAgICAgIHRoaXMuc2VsZWN0Tm9kZSA9ICEhZXZlbnRbc2VsZWN0Tm9kZU1vZGlmaWVyXTtcbiAgICAgICAgdGhpcy5hbGxvd0RlZmF1bHQgPSBldmVudC5zaGlmdEtleTtcbiAgICAgICAgbGV0IHRhcmdldE5vZGUsIHRhcmdldFBvcztcbiAgICAgICAgaWYgKHBvcy5pbnNpZGUgPiAtMSkge1xuICAgICAgICAgICAgdGFyZ2V0Tm9kZSA9IHZpZXcuc3RhdGUuZG9jLm5vZGVBdChwb3MuaW5zaWRlKTtcbiAgICAgICAgICAgIHRhcmdldFBvcyA9IHBvcy5pbnNpZGU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgJHBvcyA9IHZpZXcuc3RhdGUuZG9jLnJlc29sdmUocG9zLnBvcyk7XG4gICAgICAgICAgICB0YXJnZXROb2RlID0gJHBvcy5wYXJlbnQ7XG4gICAgICAgICAgICB0YXJnZXRQb3MgPSAkcG9zLmRlcHRoID8gJHBvcy5iZWZvcmUoKSA6IDA7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gZmx1c2hlZCA/IG51bGwgOiBldmVudC50YXJnZXQ7XG4gICAgICAgIGNvbnN0IHRhcmdldERlc2MgPSB0YXJnZXQgPyB2aWV3LmRvY1ZpZXcubmVhcmVzdERlc2ModGFyZ2V0LCB0cnVlKSA6IG51bGw7XG4gICAgICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0RGVzYyAmJiB0YXJnZXREZXNjLm5vZGVET00ubm9kZVR5cGUgPT0gMSA/IHRhcmdldERlc2Mubm9kZURPTSA6IG51bGw7XG4gICAgICAgIGxldCB7IHNlbGVjdGlvbiB9ID0gdmlldy5zdGF0ZTtcbiAgICAgICAgaWYgKGV2ZW50LmJ1dHRvbiA9PSAwICYmXG4gICAgICAgICAgICAodGFyZ2V0Tm9kZS50eXBlLnNwZWMuZHJhZ2dhYmxlICYmIHRhcmdldE5vZGUudHlwZS5zcGVjLnNlbGVjdGFibGUgIT09IGZhbHNlIHx8XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uIGluc3RhbmNlb2YgTm9kZVNlbGVjdGlvbiAmJiBzZWxlY3Rpb24uZnJvbSA8PSB0YXJnZXRQb3MgJiYgc2VsZWN0aW9uLnRvID4gdGFyZ2V0UG9zKSlcbiAgICAgICAgICAgIHRoaXMubWlnaHREcmFnID0ge1xuICAgICAgICAgICAgICAgIG5vZGU6IHRhcmdldE5vZGUsXG4gICAgICAgICAgICAgICAgcG9zOiB0YXJnZXRQb3MsXG4gICAgICAgICAgICAgICAgYWRkQXR0cjogISEodGhpcy50YXJnZXQgJiYgIXRoaXMudGFyZ2V0LmRyYWdnYWJsZSksXG4gICAgICAgICAgICAgICAgc2V0VW5lZGl0YWJsZTogISEodGhpcy50YXJnZXQgJiYgZ2Vja28gJiYgIXRoaXMudGFyZ2V0Lmhhc0F0dHJpYnV0ZShcImNvbnRlbnRFZGl0YWJsZVwiKSlcbiAgICAgICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLnRhcmdldCAmJiB0aGlzLm1pZ2h0RHJhZyAmJiAodGhpcy5taWdodERyYWcuYWRkQXR0ciB8fCB0aGlzLm1pZ2h0RHJhZy5zZXRVbmVkaXRhYmxlKSkge1xuICAgICAgICAgICAgdGhpcy52aWV3LmRvbU9ic2VydmVyLnN0b3AoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLm1pZ2h0RHJhZy5hZGRBdHRyKVxuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0LmRyYWdnYWJsZSA9IHRydWU7XG4gICAgICAgICAgICBpZiAodGhpcy5taWdodERyYWcuc2V0VW5lZGl0YWJsZSlcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudmlldy5pbnB1dC5tb3VzZURvd24gPT0gdGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0LnNldEF0dHJpYnV0ZShcImNvbnRlbnRFZGl0YWJsZVwiLCBcImZhbHNlXCIpO1xuICAgICAgICAgICAgICAgIH0sIDIwKTtcbiAgICAgICAgICAgIHRoaXMudmlldy5kb21PYnNlcnZlci5zdGFydCgpO1xuICAgICAgICB9XG4gICAgICAgIHZpZXcucm9vdC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLnVwID0gdGhpcy51cC5iaW5kKHRoaXMpKTtcbiAgICAgICAgdmlldy5yb290LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgdGhpcy5tb3ZlID0gdGhpcy5tb3ZlLmJpbmQodGhpcykpO1xuICAgICAgICBzZXRTZWxlY3Rpb25PcmlnaW4odmlldywgXCJwb2ludGVyXCIpO1xuICAgIH1cbiAgICBkb25lKCkge1xuICAgICAgICB0aGlzLnZpZXcucm9vdC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLnVwKTtcbiAgICAgICAgdGhpcy52aWV3LnJvb3QucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCB0aGlzLm1vdmUpO1xuICAgICAgICBpZiAodGhpcy5taWdodERyYWcgJiYgdGhpcy50YXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMudmlldy5kb21PYnNlcnZlci5zdG9wKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5taWdodERyYWcuYWRkQXR0cilcbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC5yZW1vdmVBdHRyaWJ1dGUoXCJkcmFnZ2FibGVcIik7XG4gICAgICAgICAgICBpZiAodGhpcy5taWdodERyYWcuc2V0VW5lZGl0YWJsZSlcbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC5yZW1vdmVBdHRyaWJ1dGUoXCJjb250ZW50RWRpdGFibGVcIik7XG4gICAgICAgICAgICB0aGlzLnZpZXcuZG9tT2JzZXJ2ZXIuc3RhcnQoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5kZWxheWVkU2VsZWN0aW9uU3luYylcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gc2VsZWN0aW9uVG9ET00odGhpcy52aWV3KSk7XG4gICAgICAgIHRoaXMudmlldy5pbnB1dC5tb3VzZURvd24gPSBudWxsO1xuICAgIH1cbiAgICB1cChldmVudCkge1xuICAgICAgICB0aGlzLmRvbmUoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZpZXcuZG9tLmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGxldCBwb3MgPSB0aGlzLnBvcztcbiAgICAgICAgaWYgKHRoaXMudmlldy5zdGF0ZS5kb2MgIT0gdGhpcy5zdGFydERvYylcbiAgICAgICAgICAgIHBvcyA9IHRoaXMudmlldy5wb3NBdENvb3JkcyhldmVudENvb3JkcyhldmVudCkpO1xuICAgICAgICB0aGlzLnVwZGF0ZUFsbG93RGVmYXVsdChldmVudCk7XG4gICAgICAgIGlmICh0aGlzLmFsbG93RGVmYXVsdCB8fCAhcG9zKSB7XG4gICAgICAgICAgICBzZXRTZWxlY3Rpb25PcmlnaW4odGhpcy52aWV3LCBcInBvaW50ZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaGFuZGxlU2luZ2xlQ2xpY2sodGhpcy52aWV3LCBwb3MucG9zLCBwb3MuaW5zaWRlLCBldmVudCwgdGhpcy5zZWxlY3ROb2RlKSkge1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldmVudC5idXR0b24gPT0gMCAmJlxuICAgICAgICAgICAgKHRoaXMuZmx1c2hlZCB8fFxuICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBpZ25vcmVzIGNsaWNrcyBvbiBkcmFnZ2FibGUgZWxlbWVudHNcbiAgICAgICAgICAgICAgICAoc2FmYXJpICYmIHRoaXMubWlnaHREcmFnICYmICF0aGlzLm1pZ2h0RHJhZy5ub2RlLmlzQXRvbSkgfHxcbiAgICAgICAgICAgICAgICAvLyBDaHJvbWUgd2lsbCBzb21ldGltZXMgdHJlYXQgYSBub2RlIHNlbGVjdGlvbiBhcyBhXG4gICAgICAgICAgICAgICAgLy8gY3Vyc29yLCBidXQgc3RpbGwgcmVwb3J0IHRoYXQgdGhlIG5vZGUgaXMgc2VsZWN0ZWRcbiAgICAgICAgICAgICAgICAvLyB3aGVuIGFza2VkIHRocm91Z2ggZ2V0U2VsZWN0aW9uLiBZb3UnbGwgdGhlbiBnZXQgYVxuICAgICAgICAgICAgICAgIC8vIHNpdHVhdGlvbiB3aGVyZSBjbGlja2luZyBhdCB0aGUgcG9pbnQgd2hlcmUgdGhhdFxuICAgICAgICAgICAgICAgIC8vIChoaWRkZW4pIGN1cnNvciBpcyBkb2Vzbid0IGNoYW5nZSB0aGUgc2VsZWN0aW9uLCBhbmRcbiAgICAgICAgICAgICAgICAvLyB0aHVzIGRvZXNuJ3QgZ2V0IGEgcmVhY3Rpb24gZnJvbSBQcm9zZU1pcnJvci4gVGhpc1xuICAgICAgICAgICAgICAgIC8vIHdvcmtzIGFyb3VuZCB0aGF0LlxuICAgICAgICAgICAgICAgIChjaHJvbWUgJiYgIXRoaXMudmlldy5zdGF0ZS5zZWxlY3Rpb24udmlzaWJsZSAmJlxuICAgICAgICAgICAgICAgICAgICBNYXRoLm1pbihNYXRoLmFicyhwb3MucG9zIC0gdGhpcy52aWV3LnN0YXRlLnNlbGVjdGlvbi5mcm9tKSwgTWF0aC5hYnMocG9zLnBvcyAtIHRoaXMudmlldy5zdGF0ZS5zZWxlY3Rpb24udG8pKSA8PSAyKSkpIHtcbiAgICAgICAgICAgIHVwZGF0ZVNlbGVjdGlvbih0aGlzLnZpZXcsIFNlbGVjdGlvbi5uZWFyKHRoaXMudmlldy5zdGF0ZS5kb2MucmVzb2x2ZShwb3MucG9zKSksIFwicG9pbnRlclwiKTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzZXRTZWxlY3Rpb25PcmlnaW4odGhpcy52aWV3LCBcInBvaW50ZXJcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbW92ZShldmVudCkge1xuICAgICAgICB0aGlzLnVwZGF0ZUFsbG93RGVmYXVsdChldmVudCk7XG4gICAgICAgIHNldFNlbGVjdGlvbk9yaWdpbih0aGlzLnZpZXcsIFwicG9pbnRlclwiKTtcbiAgICAgICAgaWYgKGV2ZW50LmJ1dHRvbnMgPT0gMClcbiAgICAgICAgICAgIHRoaXMuZG9uZSgpO1xuICAgIH1cbiAgICB1cGRhdGVBbGxvd0RlZmF1bHQoZXZlbnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmFsbG93RGVmYXVsdCAmJiAoTWF0aC5hYnModGhpcy5ldmVudC54IC0gZXZlbnQuY2xpZW50WCkgPiA0IHx8XG4gICAgICAgICAgICBNYXRoLmFicyh0aGlzLmV2ZW50LnkgLSBldmVudC5jbGllbnRZKSA+IDQpKVxuICAgICAgICAgICAgdGhpcy5hbGxvd0RlZmF1bHQgPSB0cnVlO1xuICAgIH1cbn1cbmhhbmRsZXJzLnRvdWNoc3RhcnQgPSB2aWV3ID0+IHtcbiAgICB2aWV3LmlucHV0Lmxhc3RUb3VjaCA9IERhdGUubm93KCk7XG4gICAgZm9yY2VET01GbHVzaCh2aWV3KTtcbiAgICBzZXRTZWxlY3Rpb25PcmlnaW4odmlldywgXCJwb2ludGVyXCIpO1xufTtcbmhhbmRsZXJzLnRvdWNobW92ZSA9IHZpZXcgPT4ge1xuICAgIHZpZXcuaW5wdXQubGFzdFRvdWNoID0gRGF0ZS5ub3coKTtcbiAgICBzZXRTZWxlY3Rpb25PcmlnaW4odmlldywgXCJwb2ludGVyXCIpO1xufTtcbmhhbmRsZXJzLmNvbnRleHRtZW51ID0gdmlldyA9PiBmb3JjZURPTUZsdXNoKHZpZXcpO1xuZnVuY3Rpb24gaW5Pck5lYXJDb21wb3NpdGlvbih2aWV3LCBldmVudCkge1xuICAgIGlmICh2aWV3LmNvbXBvc2luZylcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgLy8gU2VlIGh0dHBzOi8vd3d3LnN0dW0uZGUvMjAxNi8wNi8yNC9oYW5kbGluZy1pbWUtZXZlbnRzLWluLWphdmFzY3JpcHQvLlxuICAgIC8vIE9uIEphcGFuZXNlIGlucHV0IG1ldGhvZCBlZGl0b3JzIChJTUVzKSwgdGhlIEVudGVyIGtleSBpcyB1c2VkIHRvIGNvbmZpcm0gY2hhcmFjdGVyXG4gICAgLy8gc2VsZWN0aW9uLiBPbiBTYWZhcmksIHdoZW4gRW50ZXIgaXMgcHJlc3NlZCwgY29tcG9zaXRpb25lbmQgYW5kIGtleWRvd24gZXZlbnRzIGFyZVxuICAgIC8vIGVtaXR0ZWQuIFRoZSBrZXlkb3duIGV2ZW50IHRyaWdnZXJzIG5ld2xpbmUgaW5zZXJ0aW9uLCB3aGljaCB3ZSBkb24ndCB3YW50LlxuICAgIC8vIFRoaXMgbWV0aG9kIHJldHVybnMgdHJ1ZSBpZiB0aGUga2V5ZG93biBldmVudCBzaG91bGQgYmUgaWdub3JlZC5cbiAgICAvLyBXZSBvbmx5IGlnbm9yZSBpdCBvbmNlLCBhcyBwcmVzc2luZyBFbnRlciBhIHNlY29uZCB0aW1lICpzaG91bGQqIGluc2VydCBhIG5ld2xpbmUuXG4gICAgLy8gRnVydGhlcm1vcmUsIHRoZSBrZXlkb3duIGV2ZW50IHRpbWVzdGFtcCBtdXN0IGJlIGNsb3NlIHRvIHRoZSBjb21wb3NpdGlvbkVuZGVkQXQgdGltZXN0YW1wLlxuICAgIC8vIFRoaXMgZ3VhcmRzIGFnYWluc3QgdGhlIGNhc2Ugd2hlcmUgY29tcG9zaXRpb25lbmQgaXMgdHJpZ2dlcmVkIHdpdGhvdXQgdGhlIGtleWJvYXJkXG4gICAgLy8gKGUuZy4gY2hhcmFjdGVyIGNvbmZpcm1hdGlvbiBtYXkgYmUgZG9uZSB3aXRoIHRoZSBtb3VzZSksIGFuZCBrZXlkb3duIGlzIHRyaWdnZXJlZFxuICAgIC8vIGFmdGVyd2FyZHMtIHdlIHdvdWxkbid0IHdhbnQgdG8gaWdub3JlIHRoZSBrZXlkb3duIGV2ZW50IGluIHRoaXMgY2FzZS5cbiAgICBpZiAoc2FmYXJpICYmIE1hdGguYWJzKGV2ZW50LnRpbWVTdGFtcCAtIHZpZXcuaW5wdXQuY29tcG9zaXRpb25FbmRlZEF0KSA8IDUwMCkge1xuICAgICAgICB2aWV3LmlucHV0LmNvbXBvc2l0aW9uRW5kZWRBdCA9IC0yZTg7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG4vLyBEcm9wIGFjdGl2ZSBjb21wb3NpdGlvbiBhZnRlciA1IHNlY29uZHMgb2YgaW5hY3Rpdml0eSBvbiBBbmRyb2lkXG5jb25zdCB0aW1lb3V0Q29tcG9zaXRpb24gPSBhbmRyb2lkID8gNTAwMCA6IC0xO1xuZWRpdEhhbmRsZXJzLmNvbXBvc2l0aW9uc3RhcnQgPSBlZGl0SGFuZGxlcnMuY29tcG9zaXRpb251cGRhdGUgPSB2aWV3ID0+IHtcbiAgICBpZiAoIXZpZXcuY29tcG9zaW5nKSB7XG4gICAgICAgIHZpZXcuZG9tT2JzZXJ2ZXIuZmx1c2goKTtcbiAgICAgICAgbGV0IHsgc3RhdGUgfSA9IHZpZXcsICRwb3MgPSBzdGF0ZS5zZWxlY3Rpb24uJHRvO1xuICAgICAgICBpZiAoc3RhdGUuc2VsZWN0aW9uIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvbiAmJlxuICAgICAgICAgICAgKHN0YXRlLnN0b3JlZE1hcmtzIHx8XG4gICAgICAgICAgICAgICAgKCEkcG9zLnRleHRPZmZzZXQgJiYgJHBvcy5wYXJlbnRPZmZzZXQgJiYgJHBvcy5ub2RlQmVmb3JlLm1hcmtzLnNvbWUobSA9PiBtLnR5cGUuc3BlYy5pbmNsdXNpdmUgPT09IGZhbHNlKSkgfHxcbiAgICAgICAgICAgICAgICBjaHJvbWUgJiYgd2luZG93cyAmJiBzZWxlY3Rpb25CZWZvcmVVbmVkaXRhYmxlKHZpZXcpKSkgeyAvLyBJc3N1ZSAjMTUwMFxuICAgICAgICAgICAgLy8gTmVlZCB0byB3cmFwIHRoZSBjdXJzb3IgaW4gbWFyayBub2RlcyBkaWZmZXJlbnQgZnJvbSB0aGUgb25lcyBpbiB0aGUgRE9NIGNvbnRleHRcbiAgICAgICAgICAgIHZpZXcubWFya0N1cnNvciA9IHZpZXcuc3RhdGUuc3RvcmVkTWFya3MgfHwgJHBvcy5tYXJrcygpO1xuICAgICAgICAgICAgZW5kQ29tcG9zaXRpb24odmlldywgdHJ1ZSk7XG4gICAgICAgICAgICB2aWV3Lm1hcmtDdXJzb3IgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZW5kQ29tcG9zaXRpb24odmlldywgIXN0YXRlLnNlbGVjdGlvbi5lbXB0eSk7XG4gICAgICAgICAgICAvLyBJbiBmaXJlZm94LCBpZiB0aGUgY3Vyc29yIGlzIGFmdGVyIGJ1dCBvdXRzaWRlIGEgbWFya2VkIG5vZGUsXG4gICAgICAgICAgICAvLyB0aGUgaW5zZXJ0ZWQgdGV4dCB3b24ndCBpbmhlcml0IHRoZSBtYXJrcy4gU28gdGhpcyBtb3ZlcyBpdFxuICAgICAgICAgICAgLy8gaW5zaWRlIGlmIG5lY2Vzc2FyeS5cbiAgICAgICAgICAgIGlmIChnZWNrbyAmJiBzdGF0ZS5zZWxlY3Rpb24uZW1wdHkgJiYgJHBvcy5wYXJlbnRPZmZzZXQgJiYgISRwb3MudGV4dE9mZnNldCAmJiAkcG9zLm5vZGVCZWZvcmUubWFya3MubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHNlbCA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBub2RlID0gc2VsLmZvY3VzTm9kZSwgb2Zmc2V0ID0gc2VsLmZvY3VzT2Zmc2V0OyBub2RlICYmIG5vZGUubm9kZVR5cGUgPT0gMSAmJiBvZmZzZXQgIT0gMDspIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGJlZm9yZSA9IG9mZnNldCA8IDAgPyBub2RlLmxhc3RDaGlsZCA6IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXQgLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFiZWZvcmUpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJlZm9yZS5ub2RlVHlwZSA9PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgc2VsID0gdmlldy5kb21TZWxlY3Rpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzZWwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsLmNvbGxhcHNlKGJlZm9yZSwgYmVmb3JlLm5vZGVWYWx1ZS5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlID0gYmVmb3JlO1xuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gLTE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpbmcgPSB0cnVlO1xuICAgIH1cbiAgICBzY2hlZHVsZUNvbXBvc2VFbmQodmlldywgdGltZW91dENvbXBvc2l0aW9uKTtcbn07XG5mdW5jdGlvbiBzZWxlY3Rpb25CZWZvcmVVbmVkaXRhYmxlKHZpZXcpIHtcbiAgICBsZXQgeyBmb2N1c05vZGUsIGZvY3VzT2Zmc2V0IH0gPSB2aWV3LmRvbVNlbGVjdGlvblJhbmdlKCk7XG4gICAgaWYgKCFmb2N1c05vZGUgfHwgZm9jdXNOb2RlLm5vZGVUeXBlICE9IDEgfHwgZm9jdXNPZmZzZXQgPj0gZm9jdXNOb2RlLmNoaWxkTm9kZXMubGVuZ3RoKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IG5leHQgPSBmb2N1c05vZGUuY2hpbGROb2Rlc1tmb2N1c09mZnNldF07XG4gICAgcmV0dXJuIG5leHQubm9kZVR5cGUgPT0gMSAmJiBuZXh0LmNvbnRlbnRFZGl0YWJsZSA9PSBcImZhbHNlXCI7XG59XG5lZGl0SGFuZGxlcnMuY29tcG9zaXRpb25lbmQgPSAodmlldywgZXZlbnQpID0+IHtcbiAgICBpZiAodmlldy5jb21wb3NpbmcpIHtcbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpbmcgPSBmYWxzZTtcbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpdGlvbkVuZGVkQXQgPSBldmVudC50aW1lU3RhbXA7XG4gICAgICAgIHZpZXcuaW5wdXQuY29tcG9zaXRpb25QZW5kaW5nQ2hhbmdlcyA9IHZpZXcuZG9tT2JzZXJ2ZXIucGVuZGluZ1JlY29yZHMoKS5sZW5ndGggPyB2aWV3LmlucHV0LmNvbXBvc2l0aW9uSUQgOiAwO1xuICAgICAgICB2aWV3LmlucHV0LmNvbXBvc2l0aW9uTm9kZSA9IG51bGw7XG4gICAgICAgIGlmICh2aWV3LmlucHV0LmJhZFNhZmFyaUNvbXBvc2l0aW9uKVxuICAgICAgICAgICAgdmlldy5kb21PYnNlcnZlci5mb3JjZUZsdXNoKCk7XG4gICAgICAgIGVsc2UgaWYgKHZpZXcuaW5wdXQuY29tcG9zaXRpb25QZW5kaW5nQ2hhbmdlcylcbiAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4gdmlldy5kb21PYnNlcnZlci5mbHVzaCgpKTtcbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpdGlvbklEKys7XG4gICAgICAgIHNjaGVkdWxlQ29tcG9zZUVuZCh2aWV3LCAyMCk7XG4gICAgfVxufTtcbmZ1bmN0aW9uIHNjaGVkdWxlQ29tcG9zZUVuZCh2aWV3LCBkZWxheSkge1xuICAgIGNsZWFyVGltZW91dCh2aWV3LmlucHV0LmNvbXBvc2luZ1RpbWVvdXQpO1xuICAgIGlmIChkZWxheSA+IC0xKVxuICAgICAgICB2aWV3LmlucHV0LmNvbXBvc2luZ1RpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IGVuZENvbXBvc2l0aW9uKHZpZXcpLCBkZWxheSk7XG59XG5mdW5jdGlvbiBjbGVhckNvbXBvc2l0aW9uKHZpZXcpIHtcbiAgICBpZiAodmlldy5jb21wb3NpbmcpIHtcbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpbmcgPSBmYWxzZTtcbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpdGlvbkVuZGVkQXQgPSB0aW1lc3RhbXBGcm9tQ3VzdG9tRXZlbnQoKTtcbiAgICB9XG4gICAgd2hpbGUgKHZpZXcuaW5wdXQuY29tcG9zaXRpb25Ob2Rlcy5sZW5ndGggPiAwKVxuICAgICAgICB2aWV3LmlucHV0LmNvbXBvc2l0aW9uTm9kZXMucG9wKCkubWFya1BhcmVudHNEaXJ0eSgpO1xufVxuZnVuY3Rpb24gZmluZENvbXBvc2l0aW9uTm9kZSh2aWV3KSB7XG4gICAgbGV0IHNlbCA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKTtcbiAgICBpZiAoIXNlbC5mb2N1c05vZGUpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGxldCB0ZXh0QmVmb3JlID0gdGV4dE5vZGVCZWZvcmUkMShzZWwuZm9jdXNOb2RlLCBzZWwuZm9jdXNPZmZzZXQpO1xuICAgIGxldCB0ZXh0QWZ0ZXIgPSB0ZXh0Tm9kZUFmdGVyJDEoc2VsLmZvY3VzTm9kZSwgc2VsLmZvY3VzT2Zmc2V0KTtcbiAgICBpZiAodGV4dEJlZm9yZSAmJiB0ZXh0QWZ0ZXIgJiYgdGV4dEJlZm9yZSAhPSB0ZXh0QWZ0ZXIpIHtcbiAgICAgICAgbGV0IGRlc2NBZnRlciA9IHRleHRBZnRlci5wbVZpZXdEZXNjLCBsYXN0Q2hhbmdlZCA9IHZpZXcuZG9tT2JzZXJ2ZXIubGFzdENoYW5nZWRUZXh0Tm9kZTtcbiAgICAgICAgaWYgKHRleHRCZWZvcmUgPT0gbGFzdENoYW5nZWQgfHwgdGV4dEFmdGVyID09IGxhc3RDaGFuZ2VkKVxuICAgICAgICAgICAgcmV0dXJuIGxhc3RDaGFuZ2VkO1xuICAgICAgICBpZiAoIWRlc2NBZnRlciB8fCAhZGVzY0FmdGVyLmlzVGV4dCh0ZXh0QWZ0ZXIubm9kZVZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRleHRBZnRlcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh2aWV3LmlucHV0LmNvbXBvc2l0aW9uTm9kZSA9PSB0ZXh0QWZ0ZXIpIHtcbiAgICAgICAgICAgIGxldCBkZXNjQmVmb3JlID0gdGV4dEJlZm9yZS5wbVZpZXdEZXNjO1xuICAgICAgICAgICAgaWYgKCEoIWRlc2NCZWZvcmUgfHwgIWRlc2NCZWZvcmUuaXNUZXh0KHRleHRCZWZvcmUubm9kZVZhbHVlKSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRleHRBZnRlcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGV4dEJlZm9yZSB8fCB0ZXh0QWZ0ZXI7XG59XG5mdW5jdGlvbiB0aW1lc3RhbXBGcm9tQ3VzdG9tRXZlbnQoKSB7XG4gICAgbGV0IGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJFdmVudFwiKTtcbiAgICBldmVudC5pbml0RXZlbnQoXCJldmVudFwiLCB0cnVlLCB0cnVlKTtcbiAgICByZXR1cm4gZXZlbnQudGltZVN0YW1wO1xufVxuLyoqXG5AaW50ZXJuYWxcbiovXG5mdW5jdGlvbiBlbmRDb21wb3NpdGlvbih2aWV3LCByZXN0YXJ0aW5nID0gZmFsc2UpIHtcbiAgICBpZiAoYW5kcm9pZCAmJiB2aWV3LmRvbU9ic2VydmVyLmZsdXNoaW5nU29vbiA+PSAwKVxuICAgICAgICByZXR1cm47XG4gICAgdmlldy5kb21PYnNlcnZlci5mb3JjZUZsdXNoKCk7XG4gICAgY2xlYXJDb21wb3NpdGlvbih2aWV3KTtcbiAgICBpZiAocmVzdGFydGluZyB8fCB2aWV3LmRvY1ZpZXcgJiYgdmlldy5kb2NWaWV3LmRpcnR5KSB7XG4gICAgICAgIGxldCBzZWwgPSBzZWxlY3Rpb25Gcm9tRE9NKHZpZXcpLCBjdXIgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgaWYgKHNlbCAmJiAhc2VsLmVxKGN1cikpXG4gICAgICAgICAgICB2aWV3LmRpc3BhdGNoKHZpZXcuc3RhdGUudHIuc2V0U2VsZWN0aW9uKHNlbCkpO1xuICAgICAgICBlbHNlIGlmICgodmlldy5tYXJrQ3Vyc29yIHx8IHJlc3RhcnRpbmcpICYmICFjdXIuJGZyb20ubm9kZShjdXIuJGZyb20uc2hhcmVkRGVwdGgoY3VyLnRvKSkuaW5saW5lQ29udGVudClcbiAgICAgICAgICAgIHZpZXcuZGlzcGF0Y2godmlldy5zdGF0ZS50ci5kZWxldGVTZWxlY3Rpb24oKSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHZpZXcudXBkYXRlU3RhdGUodmlldy5zdGF0ZSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBjYXB0dXJlQ29weSh2aWV3LCBkb20pIHtcbiAgICAvLyBUaGUgZXh0cmEgd3JhcHBlciBpcyBzb21laG93IG5lY2Vzc2FyeSBvbiBJRS9FZGdlIHRvIHByZXZlbnQgdGhlXG4gICAgLy8gY29udGVudCBmcm9tIGJlaW5nIG1hbmdsZWQgd2hlbiBpdCBpcyBwdXQgb250byB0aGUgY2xpcGJvYXJkXG4gICAgaWYgKCF2aWV3LmRvbS5wYXJlbnROb2RlKVxuICAgICAgICByZXR1cm47XG4gICAgbGV0IHdyYXAgPSB2aWV3LmRvbS5wYXJlbnROb2RlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikpO1xuICAgIHdyYXAuYXBwZW5kQ2hpbGQoZG9tKTtcbiAgICB3cmFwLnN0eWxlLmNzc1RleHQgPSBcInBvc2l0aW9uOiBmaXhlZDsgbGVmdDogLTEwMDAwcHg7IHRvcDogMTBweFwiO1xuICAgIGxldCBzZWwgPSBnZXRTZWxlY3Rpb24oKSwgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIHJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhkb20pO1xuICAgIC8vIERvbmUgYmVjYXVzZSBJRSB3aWxsIGZpcmUgYSBzZWxlY3Rpb25jaGFuZ2UgbW92aW5nIHRoZSBzZWxlY3Rpb25cbiAgICAvLyB0byBpdHMgc3RhcnQgd2hlbiByZW1vdmVBbGxSYW5nZXMgaXMgY2FsbGVkIGFuZCB0aGUgZWRpdG9yIHN0aWxsXG4gICAgLy8gaGFzIGZvY3VzICh3aGljaCB3aWxsIG1lc3MgdXAgdGhlIGVkaXRvcidzIHNlbGVjdGlvbiBzdGF0ZSkuXG4gICAgdmlldy5kb20uYmx1cigpO1xuICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWwuYWRkUmFuZ2UocmFuZ2UpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZiAod3JhcC5wYXJlbnROb2RlKVxuICAgICAgICAgICAgd3JhcC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHdyYXApO1xuICAgICAgICB2aWV3LmZvY3VzKCk7XG4gICAgfSwgNTApO1xufVxuLy8gVGhpcyBpcyB2ZXJ5IGNydWRlLCBidXQgdW5mb3J0dW5hdGVseSBib3RoIHRoZXNlIGJyb3dzZXJzIF9wcmV0ZW5kX1xuLy8gdGhhdCB0aGV5IGhhdmUgYSBjbGlwYm9hcmQgQVBJXHUyMDE0YWxsIHRoZSBvYmplY3RzIGFuZCBtZXRob2RzIGFyZVxuLy8gdGhlcmUsIHRoZXkganVzdCBkb24ndCB3b3JrLCBhbmQgdGhleSBhcmUgaGFyZCB0byB0ZXN0LlxuY29uc3QgYnJva2VuQ2xpcGJvYXJkQVBJID0gKGllICYmIGllX3ZlcnNpb24gPCAxNSkgfHxcbiAgICAoaW9zICYmIHdlYmtpdF92ZXJzaW9uIDwgNjA0KTtcbmhhbmRsZXJzLmNvcHkgPSBlZGl0SGFuZGxlcnMuY3V0ID0gKHZpZXcsIF9ldmVudCkgPT4ge1xuICAgIGxldCBldmVudCA9IF9ldmVudDtcbiAgICBsZXQgc2VsID0gdmlldy5zdGF0ZS5zZWxlY3Rpb24sIGN1dCA9IGV2ZW50LnR5cGUgPT0gXCJjdXRcIjtcbiAgICBpZiAoc2VsLmVtcHR5KVxuICAgICAgICByZXR1cm47XG4gICAgLy8gSUUgYW5kIEVkZ2UncyBjbGlwYm9hcmQgaW50ZXJmYWNlIGlzIGNvbXBsZXRlbHkgYnJva2VuXG4gICAgbGV0IGRhdGEgPSBicm9rZW5DbGlwYm9hcmRBUEkgPyBudWxsIDogZXZlbnQuY2xpcGJvYXJkRGF0YTtcbiAgICBsZXQgc2xpY2UgPSBzZWwuY29udGVudCgpLCB7IGRvbSwgdGV4dCB9ID0gc2VyaWFsaXplRm9yQ2xpcGJvYXJkKHZpZXcsIHNsaWNlKTtcbiAgICBpZiAoZGF0YSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBkYXRhLmNsZWFyRGF0YSgpO1xuICAgICAgICBkYXRhLnNldERhdGEoXCJ0ZXh0L2h0bWxcIiwgZG9tLmlubmVySFRNTCk7XG4gICAgICAgIGRhdGEuc2V0RGF0YShcInRleHQvcGxhaW5cIiwgdGV4dCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBjYXB0dXJlQ29weSh2aWV3LCBkb20pO1xuICAgIH1cbiAgICBpZiAoY3V0KVxuICAgICAgICB2aWV3LmRpc3BhdGNoKHZpZXcuc3RhdGUudHIuZGVsZXRlU2VsZWN0aW9uKCkuc2Nyb2xsSW50b1ZpZXcoKS5zZXRNZXRhKFwidWlFdmVudFwiLCBcImN1dFwiKSk7XG59O1xuZnVuY3Rpb24gc2xpY2VTaW5nbGVOb2RlKHNsaWNlKSB7XG4gICAgcmV0dXJuIHNsaWNlLm9wZW5TdGFydCA9PSAwICYmIHNsaWNlLm9wZW5FbmQgPT0gMCAmJiBzbGljZS5jb250ZW50LmNoaWxkQ291bnQgPT0gMSA/IHNsaWNlLmNvbnRlbnQuZmlyc3RDaGlsZCA6IG51bGw7XG59XG5mdW5jdGlvbiBjYXB0dXJlUGFzdGUodmlldywgZXZlbnQpIHtcbiAgICBpZiAoIXZpZXcuZG9tLnBhcmVudE5vZGUpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgcGxhaW5UZXh0ID0gdmlldy5pbnB1dC5zaGlmdEtleSB8fCB2aWV3LnN0YXRlLnNlbGVjdGlvbi4kZnJvbS5wYXJlbnQudHlwZS5zcGVjLmNvZGU7XG4gICAgbGV0IHRhcmdldCA9IHZpZXcuZG9tLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChwbGFpblRleHQgPyBcInRleHRhcmVhXCIgOiBcImRpdlwiKSk7XG4gICAgaWYgKCFwbGFpblRleHQpXG4gICAgICAgIHRhcmdldC5jb250ZW50RWRpdGFibGUgPSBcInRydWVcIjtcbiAgICB0YXJnZXQuc3R5bGUuY3NzVGV4dCA9IFwicG9zaXRpb246IGZpeGVkOyBsZWZ0OiAtMTAwMDBweDsgdG9wOiAxMHB4XCI7XG4gICAgdGFyZ2V0LmZvY3VzKCk7XG4gICAgbGV0IHBsYWluID0gdmlldy5pbnB1dC5zaGlmdEtleSAmJiB2aWV3LmlucHV0Lmxhc3RLZXlDb2RlICE9IDQ1O1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB2aWV3LmZvY3VzKCk7XG4gICAgICAgIGlmICh0YXJnZXQucGFyZW50Tm9kZSlcbiAgICAgICAgICAgIHRhcmdldC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRhcmdldCk7XG4gICAgICAgIGlmIChwbGFpblRleHQpXG4gICAgICAgICAgICBkb1Bhc3RlKHZpZXcsIHRhcmdldC52YWx1ZSwgbnVsbCwgcGxhaW4sIGV2ZW50KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgZG9QYXN0ZSh2aWV3LCB0YXJnZXQudGV4dENvbnRlbnQsIHRhcmdldC5pbm5lckhUTUwsIHBsYWluLCBldmVudCk7XG4gICAgfSwgNTApO1xufVxuZnVuY3Rpb24gZG9QYXN0ZSh2aWV3LCB0ZXh0LCBodG1sLCBwcmVmZXJQbGFpbiwgZXZlbnQpIHtcbiAgICBsZXQgc2xpY2UgPSBwYXJzZUZyb21DbGlwYm9hcmQodmlldywgdGV4dCwgaHRtbCwgcHJlZmVyUGxhaW4sIHZpZXcuc3RhdGUuc2VsZWN0aW9uLiRmcm9tKTtcbiAgICBpZiAodmlldy5zb21lUHJvcChcImhhbmRsZVBhc3RlXCIsIGYgPT4gZih2aWV3LCBldmVudCwgc2xpY2UgfHwgU2xpY2UuZW1wdHkpKSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgaWYgKCFzbGljZSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCBzaW5nbGVOb2RlID0gc2xpY2VTaW5nbGVOb2RlKHNsaWNlKTtcbiAgICBsZXQgdHIgPSBzaW5nbGVOb2RlXG4gICAgICAgID8gdmlldy5zdGF0ZS50ci5yZXBsYWNlU2VsZWN0aW9uV2l0aChzaW5nbGVOb2RlLCBwcmVmZXJQbGFpbilcbiAgICAgICAgOiB2aWV3LnN0YXRlLnRyLnJlcGxhY2VTZWxlY3Rpb24oc2xpY2UpO1xuICAgIHZpZXcuZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKS5zZXRNZXRhKFwicGFzdGVcIiwgdHJ1ZSkuc2V0TWV0YShcInVpRXZlbnRcIiwgXCJwYXN0ZVwiKSk7XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBnZXRUZXh0KGNsaXBib2FyZERhdGEpIHtcbiAgICBsZXQgdGV4dCA9IGNsaXBib2FyZERhdGEuZ2V0RGF0YShcInRleHQvcGxhaW5cIikgfHwgY2xpcGJvYXJkRGF0YS5nZXREYXRhKFwiVGV4dFwiKTtcbiAgICBpZiAodGV4dClcbiAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgbGV0IHVyaXMgPSBjbGlwYm9hcmREYXRhLmdldERhdGEoXCJ0ZXh0L3VyaS1saXN0XCIpO1xuICAgIHJldHVybiB1cmlzID8gdXJpcy5yZXBsYWNlKC9cXHI/XFxuL2csIFwiIFwiKSA6IFwiXCI7XG59XG5lZGl0SGFuZGxlcnMucGFzdGUgPSAodmlldywgX2V2ZW50KSA9PiB7XG4gICAgbGV0IGV2ZW50ID0gX2V2ZW50O1xuICAgIC8vIEhhbmRsaW5nIHBhc3RlIGZyb20gSmF2YVNjcmlwdCBkdXJpbmcgY29tcG9zaXRpb24gaXMgdmVyeSBwb29ybHlcbiAgICAvLyBoYW5kbGVkIGJ5IGJyb3dzZXJzLCBzbyBhcyBhIGRvZGd5IGJ1dCBwcmVmZXJhYmxlIGtsdWRnZSwgd2UganVzdFxuICAgIC8vIGxldCB0aGUgYnJvd3NlciBkbyBpdHMgbmF0aXZlIHRoaW5nIHRoZXJlLCBleGNlcHQgb24gQW5kcm9pZCxcbiAgICAvLyB3aGVyZSB0aGUgZWRpdG9yIGlzIGFsbW9zdCBhbHdheXMgY29tcG9zaW5nLlxuICAgIGlmICh2aWV3LmNvbXBvc2luZyAmJiAhYW5kcm9pZClcbiAgICAgICAgcmV0dXJuO1xuICAgIGxldCBkYXRhID0gYnJva2VuQ2xpcGJvYXJkQVBJID8gbnVsbCA6IGV2ZW50LmNsaXBib2FyZERhdGE7XG4gICAgbGV0IHBsYWluID0gdmlldy5pbnB1dC5zaGlmdEtleSAmJiB2aWV3LmlucHV0Lmxhc3RLZXlDb2RlICE9IDQ1O1xuICAgIGlmIChkYXRhICYmIGRvUGFzdGUodmlldywgZ2V0VGV4dChkYXRhKSwgZGF0YS5nZXREYXRhKFwidGV4dC9odG1sXCIpLCBwbGFpbiwgZXZlbnQpKVxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGVsc2VcbiAgICAgICAgY2FwdHVyZVBhc3RlKHZpZXcsIGV2ZW50KTtcbn07XG5jbGFzcyBEcmFnZ2luZyB7XG4gICAgY29uc3RydWN0b3Ioc2xpY2UsIG1vdmUsIG5vZGUpIHtcbiAgICAgICAgdGhpcy5zbGljZSA9IHNsaWNlO1xuICAgICAgICB0aGlzLm1vdmUgPSBtb3ZlO1xuICAgICAgICB0aGlzLm5vZGUgPSBub2RlO1xuICAgIH1cbn1cbmNvbnN0IGRyYWdDb3B5TW9kaWZpZXIgPSBtYWMgPyBcImFsdEtleVwiIDogXCJjdHJsS2V5XCI7XG5mdW5jdGlvbiBkcmFnTW92ZXModmlldywgZXZlbnQpIHtcbiAgICBsZXQgY29weTtcbiAgICB2aWV3LnNvbWVQcm9wKFwiZHJhZ0NvcGllc1wiLCB0ZXN0ID0+IHsgY29weSA9IGNvcHkgfHwgdGVzdChldmVudCk7IH0pO1xuICAgIHJldHVybiBjb3B5ICE9IG51bGwgPyAhY29weSA6ICFldmVudFtkcmFnQ29weU1vZGlmaWVyXTtcbn1cbmhhbmRsZXJzLmRyYWdzdGFydCA9ICh2aWV3LCBfZXZlbnQpID0+IHtcbiAgICBsZXQgZXZlbnQgPSBfZXZlbnQ7XG4gICAgbGV0IG1vdXNlRG93biA9IHZpZXcuaW5wdXQubW91c2VEb3duO1xuICAgIGlmIChtb3VzZURvd24pXG4gICAgICAgIG1vdXNlRG93bi5kb25lKCk7XG4gICAgaWYgKCFldmVudC5kYXRhVHJhbnNmZXIpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgc2VsID0gdmlldy5zdGF0ZS5zZWxlY3Rpb247XG4gICAgbGV0IHBvcyA9IHNlbC5lbXB0eSA/IG51bGwgOiB2aWV3LnBvc0F0Q29vcmRzKGV2ZW50Q29vcmRzKGV2ZW50KSk7XG4gICAgbGV0IG5vZGU7XG4gICAgaWYgKHBvcyAmJiBwb3MucG9zID49IHNlbC5mcm9tICYmIHBvcy5wb3MgPD0gKHNlbCBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24gPyBzZWwudG8gLSAxIDogc2VsLnRvKSkgO1xuICAgIGVsc2UgaWYgKG1vdXNlRG93biAmJiBtb3VzZURvd24ubWlnaHREcmFnKSB7XG4gICAgICAgIG5vZGUgPSBOb2RlU2VsZWN0aW9uLmNyZWF0ZSh2aWV3LnN0YXRlLmRvYywgbW91c2VEb3duLm1pZ2h0RHJhZy5wb3MpO1xuICAgIH1cbiAgICBlbHNlIGlmIChldmVudC50YXJnZXQgJiYgZXZlbnQudGFyZ2V0Lm5vZGVUeXBlID09IDEpIHtcbiAgICAgICAgbGV0IGRlc2MgPSB2aWV3LmRvY1ZpZXcubmVhcmVzdERlc2MoZXZlbnQudGFyZ2V0LCB0cnVlKTtcbiAgICAgICAgaWYgKGRlc2MgJiYgZGVzYy5ub2RlLnR5cGUuc3BlYy5kcmFnZ2FibGUgJiYgZGVzYyAhPSB2aWV3LmRvY1ZpZXcpXG4gICAgICAgICAgICBub2RlID0gTm9kZVNlbGVjdGlvbi5jcmVhdGUodmlldy5zdGF0ZS5kb2MsIGRlc2MucG9zQmVmb3JlKTtcbiAgICB9XG4gICAgbGV0IGRyYWdnZWRTbGljZSA9IChub2RlIHx8IHZpZXcuc3RhdGUuc2VsZWN0aW9uKS5jb250ZW50KCk7XG4gICAgbGV0IHsgZG9tLCB0ZXh0LCBzbGljZSB9ID0gc2VyaWFsaXplRm9yQ2xpcGJvYXJkKHZpZXcsIGRyYWdnZWRTbGljZSk7XG4gICAgLy8gUHJlLTEyMCBDaHJvbWUgdmVyc2lvbnMgY2xlYXIgZmlsZXMgd2hlbiBjYWxsaW5nIGBjbGVhckRhdGFgICgjMTQ3MilcbiAgICBpZiAoIWV2ZW50LmRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggfHwgIWNocm9tZSB8fCBjaHJvbWVfdmVyc2lvbiA+IDEyMClcbiAgICAgICAgZXZlbnQuZGF0YVRyYW5zZmVyLmNsZWFyRGF0YSgpO1xuICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5zZXREYXRhKGJyb2tlbkNsaXBib2FyZEFQSSA/IFwiVGV4dFwiIDogXCJ0ZXh0L2h0bWxcIiwgZG9tLmlubmVySFRNTCk7XG4gICAgLy8gU2VlIGh0dHBzOi8vY29kZS5oYXZlcmJla2UuYmVybGluL3Byb3NlbWlycm9yL3Byb3NlbWlycm9yL2lzc3Vlcy8xMTU2XG4gICAgZXZlbnQuZGF0YVRyYW5zZmVyLmVmZmVjdEFsbG93ZWQgPSBcImNvcHlNb3ZlXCI7XG4gICAgaWYgKCFicm9rZW5DbGlwYm9hcmRBUEkpXG4gICAgICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5zZXREYXRhKFwidGV4dC9wbGFpblwiLCB0ZXh0KTtcbiAgICB2aWV3LmRyYWdnaW5nID0gbmV3IERyYWdnaW5nKHNsaWNlLCBkcmFnTW92ZXModmlldywgZXZlbnQpLCBub2RlKTtcbn07XG5oYW5kbGVycy5kcmFnZW5kID0gdmlldyA9PiB7XG4gICAgbGV0IGRyYWdnaW5nID0gdmlldy5kcmFnZ2luZztcbiAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGlmICh2aWV3LmRyYWdnaW5nID09IGRyYWdnaW5nKVxuICAgICAgICAgICAgdmlldy5kcmFnZ2luZyA9IG51bGw7XG4gICAgfSwgNTApO1xufTtcbmVkaXRIYW5kbGVycy5kcmFnb3ZlciA9IGVkaXRIYW5kbGVycy5kcmFnZW50ZXIgPSAoXywgZSkgPT4gZS5wcmV2ZW50RGVmYXVsdCgpO1xuZWRpdEhhbmRsZXJzLmRyb3AgPSAodmlldywgZXZlbnQpID0+IHtcbiAgICB0cnkge1xuICAgICAgICBoYW5kbGVEcm9wKHZpZXcsIGV2ZW50LCB2aWV3LmRyYWdnaW5nKTtcbiAgICB9XG4gICAgZmluYWxseSB7XG4gICAgICAgIHZpZXcuZHJhZ2dpbmcgPSBudWxsO1xuICAgIH1cbn07XG5mdW5jdGlvbiBoYW5kbGVEcm9wKHZpZXcsIGV2ZW50LCBkcmFnZ2luZykge1xuICAgIGlmICghZXZlbnQuZGF0YVRyYW5zZmVyKVxuICAgICAgICByZXR1cm47XG4gICAgbGV0IGV2ZW50UG9zID0gdmlldy5wb3NBdENvb3JkcyhldmVudENvb3JkcyhldmVudCkpO1xuICAgIGlmICghZXZlbnRQb3MpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgJG1vdXNlID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShldmVudFBvcy5wb3MpO1xuICAgIGxldCBzbGljZSA9IGRyYWdnaW5nICYmIGRyYWdnaW5nLnNsaWNlO1xuICAgIGlmIChzbGljZSkge1xuICAgICAgICB2aWV3LnNvbWVQcm9wKFwidHJhbnNmb3JtUGFzdGVkXCIsIGYgPT4geyBzbGljZSA9IGYoc2xpY2UsIHZpZXcsIGZhbHNlKTsgfSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzbGljZSA9IHBhcnNlRnJvbUNsaXBib2FyZCh2aWV3LCBnZXRUZXh0KGV2ZW50LmRhdGFUcmFuc2ZlciksIGJyb2tlbkNsaXBib2FyZEFQSSA/IG51bGwgOiBldmVudC5kYXRhVHJhbnNmZXIuZ2V0RGF0YShcInRleHQvaHRtbFwiKSwgZmFsc2UsICRtb3VzZSk7XG4gICAgfVxuICAgIGxldCBtb3ZlID0gISEoZHJhZ2dpbmcgJiYgZHJhZ01vdmVzKHZpZXcsIGV2ZW50KSk7XG4gICAgaWYgKHZpZXcuc29tZVByb3AoXCJoYW5kbGVEcm9wXCIsIGYgPT4gZih2aWV3LCBldmVudCwgc2xpY2UgfHwgU2xpY2UuZW1wdHksIG1vdmUpKSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghc2xpY2UpXG4gICAgICAgIHJldHVybjtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGxldCBpbnNlcnRQb3MgPSBzbGljZSA/IGRyb3BQb2ludCh2aWV3LnN0YXRlLmRvYywgJG1vdXNlLnBvcywgc2xpY2UpIDogJG1vdXNlLnBvcztcbiAgICBpZiAoaW5zZXJ0UG9zID09IG51bGwpXG4gICAgICAgIGluc2VydFBvcyA9ICRtb3VzZS5wb3M7XG4gICAgbGV0IHRyID0gdmlldy5zdGF0ZS50cjtcbiAgICBpZiAobW92ZSkge1xuICAgICAgICBsZXQgeyBub2RlIH0gPSBkcmFnZ2luZztcbiAgICAgICAgaWYgKG5vZGUpXG4gICAgICAgICAgICBub2RlLnJlcGxhY2UodHIpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0ci5kZWxldGVTZWxlY3Rpb24oKTtcbiAgICB9XG4gICAgbGV0IHBvcyA9IHRyLm1hcHBpbmcubWFwKGluc2VydFBvcyk7XG4gICAgbGV0IGlzTm9kZSA9IHNsaWNlLm9wZW5TdGFydCA9PSAwICYmIHNsaWNlLm9wZW5FbmQgPT0gMCAmJiBzbGljZS5jb250ZW50LmNoaWxkQ291bnQgPT0gMTtcbiAgICBsZXQgYmVmb3JlSW5zZXJ0ID0gdHIuZG9jO1xuICAgIGlmIChpc05vZGUpXG4gICAgICAgIHRyLnJlcGxhY2VSYW5nZVdpdGgocG9zLCBwb3MsIHNsaWNlLmNvbnRlbnQuZmlyc3RDaGlsZCk7XG4gICAgZWxzZVxuICAgICAgICB0ci5yZXBsYWNlUmFuZ2UocG9zLCBwb3MsIHNsaWNlKTtcbiAgICBpZiAodHIuZG9jLmVxKGJlZm9yZUluc2VydCkpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgJHBvcyA9IHRyLmRvYy5yZXNvbHZlKHBvcyk7XG4gICAgaWYgKGlzTm9kZSAmJiBOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZShzbGljZS5jb250ZW50LmZpcnN0Q2hpbGQpICYmXG4gICAgICAgICRwb3Mubm9kZUFmdGVyICYmICRwb3Mubm9kZUFmdGVyLnNhbWVNYXJrdXAoc2xpY2UuY29udGVudC5maXJzdENoaWxkKSkge1xuICAgICAgICB0ci5zZXRTZWxlY3Rpb24obmV3IE5vZGVTZWxlY3Rpb24oJHBvcykpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbGV0IGVuZCA9IHRyLm1hcHBpbmcubWFwKGluc2VydFBvcyk7XG4gICAgICAgIHRyLm1hcHBpbmcubWFwc1t0ci5tYXBwaW5nLm1hcHMubGVuZ3RoIC0gMV0uZm9yRWFjaCgoX2Zyb20sIF90bywgX25ld0Zyb20sIG5ld1RvKSA9PiBlbmQgPSBuZXdUbyk7XG4gICAgICAgIHRyLnNldFNlbGVjdGlvbihzZWxlY3Rpb25CZXR3ZWVuKHZpZXcsICRwb3MsIHRyLmRvYy5yZXNvbHZlKGVuZCkpKTtcbiAgICB9XG4gICAgdmlldy5mb2N1cygpO1xuICAgIHZpZXcuZGlzcGF0Y2godHIuc2V0TWV0YShcInVpRXZlbnRcIiwgXCJkcm9wXCIpKTtcbn1cbmhhbmRsZXJzLmZvY3VzID0gdmlldyA9PiB7XG4gICAgdmlldy5pbnB1dC5sYXN0Rm9jdXMgPSBEYXRlLm5vdygpO1xuICAgIGlmICghdmlldy5mb2N1c2VkKSB7XG4gICAgICAgIHZpZXcuZG9tT2JzZXJ2ZXIuc3RvcCgpO1xuICAgICAgICB2aWV3LmRvbS5jbGFzc0xpc3QuYWRkKFwiUHJvc2VNaXJyb3ItZm9jdXNlZFwiKTtcbiAgICAgICAgdmlldy5kb21PYnNlcnZlci5zdGFydCgpO1xuICAgICAgICB2aWV3LmZvY3VzZWQgPSB0cnVlO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmICh2aWV3LmRvY1ZpZXcgJiYgdmlldy5oYXNGb2N1cygpICYmICF2aWV3LmRvbU9ic2VydmVyLmN1cnJlbnRTZWxlY3Rpb24uZXEodmlldy5kb21TZWxlY3Rpb25SYW5nZSgpKSlcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25Ub0RPTSh2aWV3KTtcbiAgICAgICAgfSwgMjApO1xuICAgIH1cbn07XG5oYW5kbGVycy5ibHVyID0gKHZpZXcsIF9ldmVudCkgPT4ge1xuICAgIGxldCBldmVudCA9IF9ldmVudDtcbiAgICBpZiAodmlldy5mb2N1c2VkKSB7XG4gICAgICAgIHZpZXcuZG9tT2JzZXJ2ZXIuc3RvcCgpO1xuICAgICAgICB2aWV3LmRvbS5jbGFzc0xpc3QucmVtb3ZlKFwiUHJvc2VNaXJyb3ItZm9jdXNlZFwiKTtcbiAgICAgICAgdmlldy5kb21PYnNlcnZlci5zdGFydCgpO1xuICAgICAgICBpZiAoZXZlbnQucmVsYXRlZFRhcmdldCAmJiB2aWV3LmRvbS5jb250YWlucyhldmVudC5yZWxhdGVkVGFyZ2V0KSlcbiAgICAgICAgICAgIHZpZXcuZG9tT2JzZXJ2ZXIuY3VycmVudFNlbGVjdGlvbi5jbGVhcigpO1xuICAgICAgICB2aWV3LmZvY3VzZWQgPSBmYWxzZTtcbiAgICB9XG59O1xuaGFuZGxlcnMuYmVmb3JlaW5wdXQgPSAodmlldywgX2V2ZW50KSA9PiB7XG4gICAgbGV0IGV2ZW50ID0gX2V2ZW50O1xuICAgIC8vIFdlIHNob3VsZCBwcm9iYWJseSBkbyBtb3JlIHdpdGggYmVmb3JlaW5wdXQgZXZlbnRzLCBidXQgc3VwcG9ydFxuICAgIC8vIGlzIHNvIHNwb3R0eSB0aGF0IEknbSBzdGlsbCB3YWl0aW5nIHRvIHNlZSB3aGVyZSB0aGV5IGFyZSBnb2luZy5cbiAgICAvLyBWZXJ5IHNwZWNpZmljIGhhY2sgdG8gZGVhbCB3aXRoIGJhY2tzcGFjZSBzb21ldGltZXMgZmFpbGluZyBvblxuICAgIC8vIENocm9tZSBBbmRyb2lkIHdoZW4gYWZ0ZXIgYW4gdW5lZGl0YWJsZSBub2RlLlxuICAgIGlmIChjaHJvbWUgJiYgYW5kcm9pZCAmJiBldmVudC5pbnB1dFR5cGUgPT0gXCJkZWxldGVDb250ZW50QmFja3dhcmRcIikge1xuICAgICAgICB2aWV3LmRvbU9ic2VydmVyLmZsdXNoU29vbigpO1xuICAgICAgICBsZXQgeyBkb21DaGFuZ2VDb3VudCB9ID0gdmlldy5pbnB1dDtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodmlldy5pbnB1dC5kb21DaGFuZ2VDb3VudCAhPSBkb21DaGFuZ2VDb3VudClcbiAgICAgICAgICAgICAgICByZXR1cm47IC8vIEV2ZW50IGFscmVhZHkgaGFkIHNvbWUgZWZmZWN0XG4gICAgICAgICAgICAvLyBUaGlzIGJ1ZyB0ZW5kcyB0byBjbG9zZSB0aGUgdmlydHVhbCBrZXlib2FyZCwgc28gd2UgcmVmb2N1c1xuICAgICAgICAgICAgdmlldy5kb20uYmx1cigpO1xuICAgICAgICAgICAgdmlldy5mb2N1cygpO1xuICAgICAgICAgICAgaWYgKHZpZXcuc29tZVByb3AoXCJoYW5kbGVLZXlEb3duXCIsIGYgPT4gZih2aWV3LCBrZXlFdmVudCg4LCBcIkJhY2tzcGFjZVwiKSkpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGxldCB7ICRjdXJzb3IgfSA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uO1xuICAgICAgICAgICAgLy8gQ3J1ZGUgYXBwcm94aW1hdGlvbiBvZiBiYWNrc3BhY2UgYmVoYXZpb3Igd2hlbiBubyBjb21tYW5kIGhhbmRsZWQgaXRcbiAgICAgICAgICAgIGlmICgkY3Vyc29yICYmICRjdXJzb3IucG9zID4gMClcbiAgICAgICAgICAgICAgICB2aWV3LmRpc3BhdGNoKHZpZXcuc3RhdGUudHIuZGVsZXRlKCRjdXJzb3IucG9zIC0gMSwgJGN1cnNvci5wb3MpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICB9LCA1MCk7XG4gICAgfVxufTtcbi8vIE1ha2Ugc3VyZSBhbGwgaGFuZGxlcnMgZ2V0IHJlZ2lzdGVyZWRcbmZvciAobGV0IHByb3AgaW4gZWRpdEhhbmRsZXJzKVxuICAgIGhhbmRsZXJzW3Byb3BdID0gZWRpdEhhbmRsZXJzW3Byb3BdO1xuXG5mdW5jdGlvbiBjb21wYXJlT2JqcyhhLCBiKSB7XG4gICAgaWYgKGEgPT0gYilcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgZm9yIChsZXQgcCBpbiBhKVxuICAgICAgICBpZiAoYVtwXSAhPT0gYltwXSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGxldCBwIGluIGIpXG4gICAgICAgIGlmICghKHAgaW4gYSkpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHRydWU7XG59XG5jbGFzcyBXaWRnZXRUeXBlIHtcbiAgICBjb25zdHJ1Y3Rvcih0b0RPTSwgc3BlYykge1xuICAgICAgICB0aGlzLnRvRE9NID0gdG9ET007XG4gICAgICAgIHRoaXMuc3BlYyA9IHNwZWMgfHwgbm9TcGVjO1xuICAgICAgICB0aGlzLnNpZGUgPSB0aGlzLnNwZWMuc2lkZSB8fCAwO1xuICAgIH1cbiAgICBtYXAobWFwcGluZywgc3Bhbiwgb2Zmc2V0LCBvbGRPZmZzZXQpIHtcbiAgICAgICAgbGV0IHsgcG9zLCBkZWxldGVkIH0gPSBtYXBwaW5nLm1hcFJlc3VsdChzcGFuLmZyb20gKyBvbGRPZmZzZXQsIHRoaXMuc2lkZSA8IDAgPyAtMSA6IDEpO1xuICAgICAgICByZXR1cm4gZGVsZXRlZCA/IG51bGwgOiBuZXcgRGVjb3JhdGlvbihwb3MgLSBvZmZzZXQsIHBvcyAtIG9mZnNldCwgdGhpcyk7XG4gICAgfVxuICAgIHZhbGlkKCkgeyByZXR1cm4gdHJ1ZTsgfVxuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzID09IG90aGVyIHx8XG4gICAgICAgICAgICAob3RoZXIgaW5zdGFuY2VvZiBXaWRnZXRUeXBlICYmXG4gICAgICAgICAgICAgICAgKHRoaXMuc3BlYy5rZXkgJiYgdGhpcy5zcGVjLmtleSA9PSBvdGhlci5zcGVjLmtleSB8fFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvRE9NID09IG90aGVyLnRvRE9NICYmIGNvbXBhcmVPYmpzKHRoaXMuc3BlYywgb3RoZXIuc3BlYykpKTtcbiAgICB9XG4gICAgZGVzdHJveShub2RlKSB7XG4gICAgICAgIGlmICh0aGlzLnNwZWMuZGVzdHJveSlcbiAgICAgICAgICAgIHRoaXMuc3BlYy5kZXN0cm95KG5vZGUpO1xuICAgIH1cbn1cbmNsYXNzIElubGluZVR5cGUge1xuICAgIGNvbnN0cnVjdG9yKGF0dHJzLCBzcGVjKSB7XG4gICAgICAgIHRoaXMuYXR0cnMgPSBhdHRycztcbiAgICAgICAgdGhpcy5zcGVjID0gc3BlYyB8fCBub1NwZWM7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nLCBzcGFuLCBvZmZzZXQsIG9sZE9mZnNldCkge1xuICAgICAgICBsZXQgZnJvbSA9IG1hcHBpbmcubWFwKHNwYW4uZnJvbSArIG9sZE9mZnNldCwgdGhpcy5zcGVjLmluY2x1c2l2ZVN0YXJ0ID8gLTEgOiAxKSAtIG9mZnNldDtcbiAgICAgICAgbGV0IHRvID0gbWFwcGluZy5tYXAoc3Bhbi50byArIG9sZE9mZnNldCwgdGhpcy5zcGVjLmluY2x1c2l2ZUVuZCA/IDEgOiAtMSkgLSBvZmZzZXQ7XG4gICAgICAgIHJldHVybiBmcm9tID49IHRvID8gbnVsbCA6IG5ldyBEZWNvcmF0aW9uKGZyb20sIHRvLCB0aGlzKTtcbiAgICB9XG4gICAgdmFsaWQoXywgc3BhbikgeyByZXR1cm4gc3Bhbi5mcm9tIDwgc3Bhbi50bzsgfVxuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzID09IG90aGVyIHx8XG4gICAgICAgICAgICAob3RoZXIgaW5zdGFuY2VvZiBJbmxpbmVUeXBlICYmIGNvbXBhcmVPYmpzKHRoaXMuYXR0cnMsIG90aGVyLmF0dHJzKSAmJlxuICAgICAgICAgICAgICAgIGNvbXBhcmVPYmpzKHRoaXMuc3BlYywgb3RoZXIuc3BlYykpO1xuICAgIH1cbiAgICBzdGF0aWMgaXMoc3BhbikgeyByZXR1cm4gc3Bhbi50eXBlIGluc3RhbmNlb2YgSW5saW5lVHlwZTsgfVxuICAgIGRlc3Ryb3koKSB7IH1cbn1cbmNsYXNzIE5vZGVUeXBlIHtcbiAgICBjb25zdHJ1Y3RvcihhdHRycywgc3BlYykge1xuICAgICAgICB0aGlzLmF0dHJzID0gYXR0cnM7XG4gICAgICAgIHRoaXMuc3BlYyA9IHNwZWMgfHwgbm9TcGVjO1xuICAgIH1cbiAgICBtYXAobWFwcGluZywgc3Bhbiwgb2Zmc2V0LCBvbGRPZmZzZXQpIHtcbiAgICAgICAgbGV0IGZyb20gPSBtYXBwaW5nLm1hcFJlc3VsdChzcGFuLmZyb20gKyBvbGRPZmZzZXQsIDEpO1xuICAgICAgICBpZiAoZnJvbS5kZWxldGVkKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGxldCB0byA9IG1hcHBpbmcubWFwUmVzdWx0KHNwYW4udG8gKyBvbGRPZmZzZXQsIC0xKTtcbiAgICAgICAgaWYgKHRvLmRlbGV0ZWQgfHwgdG8ucG9zIDw9IGZyb20ucG9zKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbihmcm9tLnBvcyAtIG9mZnNldCwgdG8ucG9zIC0gb2Zmc2V0LCB0aGlzKTtcbiAgICB9XG4gICAgdmFsaWQobm9kZSwgc3Bhbikge1xuICAgICAgICBsZXQgeyBpbmRleCwgb2Zmc2V0IH0gPSBub2RlLmNvbnRlbnQuZmluZEluZGV4KHNwYW4uZnJvbSksIGNoaWxkO1xuICAgICAgICByZXR1cm4gb2Zmc2V0ID09IHNwYW4uZnJvbSAmJiAhKGNoaWxkID0gbm9kZS5jaGlsZChpbmRleCkpLmlzVGV4dCAmJiBvZmZzZXQgKyBjaGlsZC5ub2RlU2l6ZSA9PSBzcGFuLnRvO1xuICAgIH1cbiAgICBlcShvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcyA9PSBvdGhlciB8fFxuICAgICAgICAgICAgKG90aGVyIGluc3RhbmNlb2YgTm9kZVR5cGUgJiYgY29tcGFyZU9ianModGhpcy5hdHRycywgb3RoZXIuYXR0cnMpICYmXG4gICAgICAgICAgICAgICAgY29tcGFyZU9ianModGhpcy5zcGVjLCBvdGhlci5zcGVjKSk7XG4gICAgfVxuICAgIGRlc3Ryb3koKSB7IH1cbn1cbi8qKlxuRGVjb3JhdGlvbiBvYmplY3RzIGNhbiBiZSBwcm92aWRlZCB0byB0aGUgdmlldyB0aHJvdWdoIHRoZVxuW2BkZWNvcmF0aW9uc2AgcHJvcF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuRWRpdG9yUHJvcHMuZGVjb3JhdGlvbnMpLiBUaGV5IGNvbWUgaW5cbnNldmVyYWwgdmFyaWFudHNcdTIwMTRzZWUgdGhlIHN0YXRpYyBtZW1iZXJzIG9mIHRoaXMgY2xhc3MgZm9yIGRldGFpbHMuXG4qL1xuY2xhc3MgRGVjb3JhdGlvbiB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIGRlY29yYXRpb24uXG4gICAgKi9cbiAgICBmcm9tLCBcbiAgICAvKipcbiAgICBUaGUgZW5kIHBvc2l0aW9uLiBXaWxsIGJlIHRoZSBzYW1lIGFzIGBmcm9tYCBmb3IgW3dpZGdldFxuICAgIGRlY29yYXRpb25zXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdmlldy5EZWNvcmF0aW9uXndpZGdldCkuXG4gICAgKi9cbiAgICB0bywgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICB0eXBlKSB7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgICAgIHRoaXMudG8gPSB0bztcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb3B5KGZyb20sIHRvKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbihmcm9tLCB0bywgdGhpcy50eXBlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBlcShvdGhlciwgb2Zmc2V0ID0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlLmVxKG90aGVyLnR5cGUpICYmIHRoaXMuZnJvbSArIG9mZnNldCA9PSBvdGhlci5mcm9tICYmIHRoaXMudG8gKyBvZmZzZXQgPT0gb3RoZXIudG87XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgbWFwKG1hcHBpbmcsIG9mZnNldCwgb2xkT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUubWFwKG1hcHBpbmcsIHRoaXMsIG9mZnNldCwgb2xkT2Zmc2V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlcyBhIHdpZGdldCBkZWNvcmF0aW9uLCB3aGljaCBpcyBhIERPTSBub2RlIHRoYXQncyBzaG93biBpblxuICAgIHRoZSBkb2N1bWVudCBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uIEl0IGlzIHJlY29tbWVuZGVkIHRoYXQgeW91XG4gICAgZGVsYXkgcmVuZGVyaW5nIHRoZSB3aWRnZXQgYnkgcGFzc2luZyBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZVxuICAgIGNhbGxlZCB3aGVuIHRoZSB3aWRnZXQgaXMgYWN0dWFsbHkgZHJhd24gaW4gYSB2aWV3LCBidXQgeW91IGNhblxuICAgIGFsc28gZGlyZWN0bHkgcGFzcyBhIERPTSBub2RlLiBgZ2V0UG9zYCBjYW4gYmUgdXNlZCB0byBmaW5kIHRoZVxuICAgIHdpZGdldCdzIGN1cnJlbnQgZG9jdW1lbnQgcG9zaXRpb24uXG4gICAgKi9cbiAgICBzdGF0aWMgd2lkZ2V0KHBvcywgdG9ET00sIHNwZWMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEZWNvcmF0aW9uKHBvcywgcG9zLCBuZXcgV2lkZ2V0VHlwZSh0b0RPTSwgc3BlYykpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGVzIGFuIGlubGluZSBkZWNvcmF0aW9uLCB3aGljaCBhZGRzIHRoZSBnaXZlbiBhdHRyaWJ1dGVzIHRvXG4gICAgZWFjaCBpbmxpbmUgbm9kZSBiZXR3ZWVuIGBmcm9tYCBhbmQgYHRvYC5cbiAgICAqL1xuICAgIHN0YXRpYyBpbmxpbmUoZnJvbSwgdG8sIGF0dHJzLCBzcGVjKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbihmcm9tLCB0bywgbmV3IElubGluZVR5cGUoYXR0cnMsIHNwZWMpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlcyBhIG5vZGUgZGVjb3JhdGlvbi4gYGZyb21gIGFuZCBgdG9gIHNob3VsZCBwb2ludCBwcmVjaXNlbHlcbiAgICBiZWZvcmUgYW5kIGFmdGVyIGEgbm9kZSBpbiB0aGUgZG9jdW1lbnQuIFRoYXQgbm9kZSwgYW5kIG9ubHkgdGhhdFxuICAgIG5vZGUsIHdpbGwgcmVjZWl2ZSB0aGUgZ2l2ZW4gYXR0cmlidXRlcy5cbiAgICAqL1xuICAgIHN0YXRpYyBub2RlKGZyb20sIHRvLCBhdHRycywgc3BlYykge1xuICAgICAgICByZXR1cm4gbmV3IERlY29yYXRpb24oZnJvbSwgdG8sIG5ldyBOb2RlVHlwZShhdHRycywgc3BlYykpO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgc3BlYyBwcm92aWRlZCB3aGVuIGNyZWF0aW5nIHRoaXMgZGVjb3JhdGlvbi4gQ2FuIGJlIHVzZWZ1bFxuICAgIGlmIHlvdSd2ZSBzdG9yZWQgZXh0cmEgaW5mb3JtYXRpb24gaW4gdGhhdCBvYmplY3QuXG4gICAgKi9cbiAgICBnZXQgc3BlYygpIHsgcmV0dXJuIHRoaXMudHlwZS5zcGVjOyB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBnZXQgaW5saW5lKCkgeyByZXR1cm4gdGhpcy50eXBlIGluc3RhbmNlb2YgSW5saW5lVHlwZTsgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgZ2V0IHdpZGdldCgpIHsgcmV0dXJuIHRoaXMudHlwZSBpbnN0YW5jZW9mIFdpZGdldFR5cGU7IH1cbn1cbmNvbnN0IG5vbmUgPSBbXSwgbm9TcGVjID0ge307XG4vKipcbkEgY29sbGVjdGlvbiBvZiBbZGVjb3JhdGlvbnNdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3LkRlY29yYXRpb24pLCBvcmdhbml6ZWQgaW4gc3VjaFxuYSB3YXkgdGhhdCB0aGUgZHJhd2luZyBhbGdvcml0aG0gY2FuIGVmZmljaWVudGx5IHVzZSBhbmQgY29tcGFyZVxudGhlbS4gVGhpcyBpcyBhIHBlcnNpc3RlbnQgZGF0YSBzdHJ1Y3R1cmVcdTIwMTRpdCBpcyBub3QgbW9kaWZpZWQsXG51cGRhdGVzIGNyZWF0ZSBhIG5ldyB2YWx1ZS5cbiovXG5jbGFzcyBEZWNvcmF0aW9uU2V0IHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGxvY2FsLCBjaGlsZHJlbikge1xuICAgICAgICB0aGlzLmxvY2FsID0gbG9jYWwubGVuZ3RoID8gbG9jYWwgOiBub25lO1xuICAgICAgICB0aGlzLmNoaWxkcmVuID0gY2hpbGRyZW4ubGVuZ3RoID8gY2hpbGRyZW4gOiBub25lO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBzZXQgb2YgZGVjb3JhdGlvbnMsIHVzaW5nIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGdpdmVuXG4gICAgZG9jdW1lbnQuIFRoaXMgd2lsbCBjb25zdW1lIChtb2RpZnkpIHRoZSBgZGVjb3JhdGlvbnNgIGFycmF5LCBzb1xuICAgIHlvdSBtdXN0IG1ha2UgYSBjb3B5IGlmIHlvdSB3YW50IG5lZWQgdG8gcHJlc2VydmUgdGhhdC5cbiAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGUoZG9jLCBkZWNvcmF0aW9ucykge1xuICAgICAgICByZXR1cm4gZGVjb3JhdGlvbnMubGVuZ3RoID8gYnVpbGRUcmVlKGRlY29yYXRpb25zLCBkb2MsIDAsIG5vU3BlYykgOiBlbXB0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCBhbGwgZGVjb3JhdGlvbnMgaW4gdGhpcyBzZXQgd2hpY2ggdG91Y2ggdGhlIGdpdmVuIHJhbmdlXG4gICAgKGluY2x1ZGluZyBkZWNvcmF0aW9ucyB0aGF0IHN0YXJ0IG9yIGVuZCBkaXJlY3RseSBhdCB0aGVcbiAgICBib3VuZGFyaWVzKSBhbmQgbWF0Y2ggdGhlIGdpdmVuIHByZWRpY2F0ZSBvbiB0aGVpciBzcGVjLiBXaGVuXG4gICAgYHN0YXJ0YCBhbmQgYGVuZGAgYXJlIG9taXR0ZWQsIGFsbCBkZWNvcmF0aW9ucyBpbiB0aGUgc2V0IGFyZVxuICAgIGNvbnNpZGVyZWQuIFdoZW4gYHByZWRpY2F0ZWAgaXNuJ3QgZ2l2ZW4sIGFsbCBkZWNvcmF0aW9ucyBhcmVcbiAgICBhc3N1bWVkIHRvIG1hdGNoLlxuICAgICovXG4gICAgZmluZChzdGFydCwgZW5kLCBwcmVkaWNhdGUpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgICAgICB0aGlzLmZpbmRJbm5lcihzdGFydCA9PSBudWxsID8gMCA6IHN0YXJ0LCBlbmQgPT0gbnVsbCA/IDFlOSA6IGVuZCwgcmVzdWx0LCAwLCBwcmVkaWNhdGUpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBmaW5kSW5uZXIoc3RhcnQsIGVuZCwgcmVzdWx0LCBvZmZzZXQsIHByZWRpY2F0ZSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubG9jYWwubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBzcGFuID0gdGhpcy5sb2NhbFtpXTtcbiAgICAgICAgICAgIGlmIChzcGFuLmZyb20gPD0gZW5kICYmIHNwYW4udG8gPj0gc3RhcnQgJiYgKCFwcmVkaWNhdGUgfHwgcHJlZGljYXRlKHNwYW4uc3BlYykpKVxuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHNwYW4uY29weShzcGFuLmZyb20gKyBvZmZzZXQsIHNwYW4udG8gKyBvZmZzZXQpKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNoaWxkcmVuW2ldIDwgZW5kICYmIHRoaXMuY2hpbGRyZW5baSArIDFdID4gc3RhcnQpIHtcbiAgICAgICAgICAgICAgICBsZXQgY2hpbGRPZmYgPSB0aGlzLmNoaWxkcmVuW2ldICsgMTtcbiAgICAgICAgICAgICAgICB0aGlzLmNoaWxkcmVuW2kgKyAyXS5maW5kSW5uZXIoc3RhcnQgLSBjaGlsZE9mZiwgZW5kIC0gY2hpbGRPZmYsIHJlc3VsdCwgb2Zmc2V0ICsgY2hpbGRPZmYsIHByZWRpY2F0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgTWFwIHRoZSBzZXQgb2YgZGVjb3JhdGlvbnMgaW4gcmVzcG9uc2UgdG8gYSBjaGFuZ2UgaW4gdGhlXG4gICAgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBtYXAobWFwcGluZywgZG9jLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICh0aGlzID09IGVtcHR5IHx8IG1hcHBpbmcubWFwcy5sZW5ndGggPT0gMClcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gdGhpcy5tYXBJbm5lcihtYXBwaW5nLCBkb2MsIDAsIDAsIG9wdGlvbnMgfHwgbm9TcGVjKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBtYXBJbm5lcihtYXBwaW5nLCBub2RlLCBvZmZzZXQsIG9sZE9mZnNldCwgb3B0aW9ucykge1xuICAgICAgICBsZXQgbmV3TG9jYWw7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sb2NhbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG1hcHBlZCA9IHRoaXMubG9jYWxbaV0ubWFwKG1hcHBpbmcsIG9mZnNldCwgb2xkT2Zmc2V0KTtcbiAgICAgICAgICAgIGlmIChtYXBwZWQgJiYgbWFwcGVkLnR5cGUudmFsaWQobm9kZSwgbWFwcGVkKSlcbiAgICAgICAgICAgICAgICAobmV3TG9jYWwgfHwgKG5ld0xvY2FsID0gW10pKS5wdXNoKG1hcHBlZCk7XG4gICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zLm9uUmVtb3ZlKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMub25SZW1vdmUodGhpcy5sb2NhbFtpXS5zcGVjKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gbWFwQ2hpbGRyZW4odGhpcy5jaGlsZHJlbiwgbmV3TG9jYWwgfHwgW10sIG1hcHBpbmcsIG5vZGUsIG9mZnNldCwgb2xkT2Zmc2V0LCBvcHRpb25zKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIG5ld0xvY2FsID8gbmV3IERlY29yYXRpb25TZXQobmV3TG9jYWwuc29ydChieVBvcyksIG5vbmUpIDogZW1wdHk7XG4gICAgfVxuICAgIC8qKlxuICAgIEFkZCB0aGUgZ2l2ZW4gYXJyYXkgb2YgZGVjb3JhdGlvbnMgdG8gdGhlIG9uZXMgaW4gdGhlIHNldCxcbiAgICBwcm9kdWNpbmcgYSBuZXcgc2V0LiBDb25zdW1lcyB0aGUgYGRlY29yYXRpb25zYCBhcnJheS4gTmVlZHNcbiAgICBhY2Nlc3MgdG8gdGhlIGN1cnJlbnQgZG9jdW1lbnQgdG8gY3JlYXRlIHRoZSBhcHByb3ByaWF0ZSB0cmVlXG4gICAgc3RydWN0dXJlLlxuICAgICovXG4gICAgYWRkKGRvYywgZGVjb3JhdGlvbnMpIHtcbiAgICAgICAgaWYgKCFkZWNvcmF0aW9ucy5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgaWYgKHRoaXMgPT0gZW1wdHkpXG4gICAgICAgICAgICByZXR1cm4gRGVjb3JhdGlvblNldC5jcmVhdGUoZG9jLCBkZWNvcmF0aW9ucyk7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZElubmVyKGRvYywgZGVjb3JhdGlvbnMsIDApO1xuICAgIH1cbiAgICBhZGRJbm5lcihkb2MsIGRlY29yYXRpb25zLCBvZmZzZXQpIHtcbiAgICAgICAgbGV0IGNoaWxkcmVuLCBjaGlsZEluZGV4ID0gMDtcbiAgICAgICAgZG9jLmZvckVhY2goKGNoaWxkTm9kZSwgY2hpbGRPZmZzZXQpID0+IHtcbiAgICAgICAgICAgIGxldCBiYXNlT2Zmc2V0ID0gY2hpbGRPZmZzZXQgKyBvZmZzZXQsIGZvdW5kO1xuICAgICAgICAgICAgaWYgKCEoZm91bmQgPSB0YWtlU3BhbnNGb3JOb2RlKGRlY29yYXRpb25zLCBjaGlsZE5vZGUsIGJhc2VPZmZzZXQpKSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBpZiAoIWNoaWxkcmVuKVxuICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbi5zbGljZSgpO1xuICAgICAgICAgICAgd2hpbGUgKGNoaWxkSW5kZXggPCBjaGlsZHJlbi5sZW5ndGggJiYgY2hpbGRyZW5bY2hpbGRJbmRleF0gPCBjaGlsZE9mZnNldClcbiAgICAgICAgICAgICAgICBjaGlsZEluZGV4ICs9IDM7XG4gICAgICAgICAgICBpZiAoY2hpbGRyZW5bY2hpbGRJbmRleF0gPT0gY2hpbGRPZmZzZXQpXG4gICAgICAgICAgICAgICAgY2hpbGRyZW5bY2hpbGRJbmRleCArIDJdID0gY2hpbGRyZW5bY2hpbGRJbmRleCArIDJdLmFkZElubmVyKGNoaWxkTm9kZSwgZm91bmQsIGJhc2VPZmZzZXQgKyAxKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjaGlsZHJlbi5zcGxpY2UoY2hpbGRJbmRleCwgMCwgY2hpbGRPZmZzZXQsIGNoaWxkT2Zmc2V0ICsgY2hpbGROb2RlLm5vZGVTaXplLCBidWlsZFRyZWUoZm91bmQsIGNoaWxkTm9kZSwgYmFzZU9mZnNldCArIDEsIG5vU3BlYykpO1xuICAgICAgICAgICAgY2hpbGRJbmRleCArPSAzO1xuICAgICAgICB9KTtcbiAgICAgICAgbGV0IGxvY2FsID0gbW92ZVNwYW5zKGNoaWxkSW5kZXggPyB3aXRob3V0TnVsbHMoZGVjb3JhdGlvbnMpIDogZGVjb3JhdGlvbnMsIC1vZmZzZXQpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxvY2FsLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKCFsb2NhbFtpXS50eXBlLnZhbGlkKGRvYywgbG9jYWxbaV0pKVxuICAgICAgICAgICAgICAgIGxvY2FsLnNwbGljZShpLS0sIDEpO1xuICAgICAgICByZXR1cm4gbmV3IERlY29yYXRpb25TZXQobG9jYWwubGVuZ3RoID8gdGhpcy5sb2NhbC5jb25jYXQobG9jYWwpLnNvcnQoYnlQb3MpIDogdGhpcy5sb2NhbCwgY2hpbGRyZW4gfHwgdGhpcy5jaGlsZHJlbik7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5ldyBzZXQgdGhhdCBjb250YWlucyB0aGUgZGVjb3JhdGlvbnMgaW4gdGhpcyBzZXQsIG1pbnVzXG4gICAgdGhlIG9uZXMgaW4gdGhlIGdpdmVuIGFycmF5LlxuICAgICovXG4gICAgcmVtb3ZlKGRlY29yYXRpb25zKSB7XG4gICAgICAgIGlmIChkZWNvcmF0aW9ucy5sZW5ndGggPT0gMCB8fCB0aGlzID09IGVtcHR5KVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIHJldHVybiB0aGlzLnJlbW92ZUlubmVyKGRlY29yYXRpb25zLCAwKTtcbiAgICB9XG4gICAgcmVtb3ZlSW5uZXIoZGVjb3JhdGlvbnMsIG9mZnNldCkge1xuICAgICAgICBsZXQgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuLCBsb2NhbCA9IHRoaXMubG9jYWw7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgIGxldCBmb3VuZDtcbiAgICAgICAgICAgIGxldCBmcm9tID0gY2hpbGRyZW5baV0gKyBvZmZzZXQsIHRvID0gY2hpbGRyZW5baSArIDFdICsgb2Zmc2V0O1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDAsIHNwYW47IGogPCBkZWNvcmF0aW9ucy5sZW5ndGg7IGorKylcbiAgICAgICAgICAgICAgICBpZiAoc3BhbiA9IGRlY29yYXRpb25zW2pdKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzcGFuLmZyb20gPiBmcm9tICYmIHNwYW4udG8gPCB0bykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVjb3JhdGlvbnNbal0gPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgKGZvdW5kIHx8IChmb3VuZCA9IFtdKSkucHVzaChzcGFuKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghZm91bmQpXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICBpZiAoY2hpbGRyZW4gPT0gdGhpcy5jaGlsZHJlbilcbiAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW4uc2xpY2UoKTtcbiAgICAgICAgICAgIGxldCByZW1vdmVkID0gY2hpbGRyZW5baSArIDJdLnJlbW92ZUlubmVyKGZvdW5kLCBmcm9tICsgMSk7XG4gICAgICAgICAgICBpZiAocmVtb3ZlZCAhPSBlbXB0eSkge1xuICAgICAgICAgICAgICAgIGNoaWxkcmVuW2kgKyAyXSA9IHJlbW92ZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjaGlsZHJlbi5zcGxpY2UoaSwgMyk7XG4gICAgICAgICAgICAgICAgaSAtPSAzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChsb2NhbC5sZW5ndGgpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgc3BhbjsgaSA8IGRlY29yYXRpb25zLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIGlmIChzcGFuID0gZGVjb3JhdGlvbnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBsb2NhbC5sZW5ndGg7IGorKylcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbFtqXS5lcShzcGFuLCBvZmZzZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvY2FsID09IHRoaXMubG9jYWwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsID0gdGhpcy5sb2NhbC5zbGljZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsLnNwbGljZShqLS0sIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgaWYgKGNoaWxkcmVuID09IHRoaXMuY2hpbGRyZW4gJiYgbG9jYWwgPT0gdGhpcy5sb2NhbClcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gbG9jYWwubGVuZ3RoIHx8IGNoaWxkcmVuLmxlbmd0aCA/IG5ldyBEZWNvcmF0aW9uU2V0KGxvY2FsLCBjaGlsZHJlbikgOiBlbXB0eTtcbiAgICB9XG4gICAgZm9yQ2hpbGQob2Zmc2V0LCBub2RlKSB7XG4gICAgICAgIGlmICh0aGlzID09IGVtcHR5KVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIGlmIChub2RlLmlzTGVhZilcbiAgICAgICAgICAgIHJldHVybiBEZWNvcmF0aW9uU2V0LmVtcHR5O1xuICAgICAgICBsZXQgY2hpbGQsIGxvY2FsO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDMpXG4gICAgICAgICAgICBpZiAodGhpcy5jaGlsZHJlbltpXSA+PSBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jaGlsZHJlbltpXSA9PSBvZmZzZXQpXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkID0gdGhpcy5jaGlsZHJlbltpICsgMl07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIGxldCBzdGFydCA9IG9mZnNldCArIDEsIGVuZCA9IHN0YXJ0ICsgbm9kZS5jb250ZW50LnNpemU7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sb2NhbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGRlYyA9IHRoaXMubG9jYWxbaV07XG4gICAgICAgICAgICBpZiAoZGVjLmZyb20gPCBlbmQgJiYgZGVjLnRvID4gc3RhcnQgJiYgKGRlYy50eXBlIGluc3RhbmNlb2YgSW5saW5lVHlwZSkpIHtcbiAgICAgICAgICAgICAgICBsZXQgZnJvbSA9IE1hdGgubWF4KHN0YXJ0LCBkZWMuZnJvbSkgLSBzdGFydCwgdG8gPSBNYXRoLm1pbihlbmQsIGRlYy50bykgLSBzdGFydDtcbiAgICAgICAgICAgICAgICBpZiAoZnJvbSA8IHRvKVxuICAgICAgICAgICAgICAgICAgICAobG9jYWwgfHwgKGxvY2FsID0gW10pKS5wdXNoKGRlYy5jb3B5KGZyb20sIHRvKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxvY2FsKSB7XG4gICAgICAgICAgICBsZXQgbG9jYWxTZXQgPSBuZXcgRGVjb3JhdGlvblNldChsb2NhbC5zb3J0KGJ5UG9zKSwgbm9uZSk7XG4gICAgICAgICAgICByZXR1cm4gY2hpbGQgPyBuZXcgRGVjb3JhdGlvbkdyb3VwKFtsb2NhbFNldCwgY2hpbGRdKSA6IGxvY2FsU2V0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGlsZCB8fCBlbXB0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBlcShvdGhlcikge1xuICAgICAgICBpZiAodGhpcyA9PSBvdGhlcilcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIERlY29yYXRpb25TZXQpIHx8XG4gICAgICAgICAgICB0aGlzLmxvY2FsLmxlbmd0aCAhPSBvdGhlci5sb2NhbC5sZW5ndGggfHxcbiAgICAgICAgICAgIHRoaXMuY2hpbGRyZW4ubGVuZ3RoICE9IG90aGVyLmNoaWxkcmVuLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxvY2FsLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKCF0aGlzLmxvY2FsW2ldLmVxKG90aGVyLmxvY2FsW2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkgKz0gMylcbiAgICAgICAgICAgIGlmICh0aGlzLmNoaWxkcmVuW2ldICE9IG90aGVyLmNoaWxkcmVuW2ldIHx8XG4gICAgICAgICAgICAgICAgdGhpcy5jaGlsZHJlbltpICsgMV0gIT0gb3RoZXIuY2hpbGRyZW5baSArIDFdIHx8XG4gICAgICAgICAgICAgICAgIXRoaXMuY2hpbGRyZW5baSArIDJdLmVxKG90aGVyLmNoaWxkcmVuW2kgKyAyXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBsb2NhbHMobm9kZSkge1xuICAgICAgICByZXR1cm4gcmVtb3ZlT3ZlcmxhcCh0aGlzLmxvY2Fsc0lubmVyKG5vZGUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBsb2NhbHNJbm5lcihub2RlKSB7XG4gICAgICAgIGlmICh0aGlzID09IGVtcHR5KVxuICAgICAgICAgICAgcmV0dXJuIG5vbmU7XG4gICAgICAgIGlmIChub2RlLmlubGluZUNvbnRlbnQgfHwgIXRoaXMubG9jYWwuc29tZShJbmxpbmVUeXBlLmlzKSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsO1xuICAgICAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sb2NhbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCEodGhpcy5sb2NhbFtpXS50eXBlIGluc3RhbmNlb2YgSW5saW5lVHlwZSkpXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2godGhpcy5sb2NhbFtpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgZm9yRWFjaFNldChmKSB7IGYodGhpcyk7IH1cbn1cbi8qKlxuVGhlIGVtcHR5IHNldCBvZiBkZWNvcmF0aW9ucy5cbiovXG5EZWNvcmF0aW9uU2V0LmVtcHR5ID0gbmV3IERlY29yYXRpb25TZXQoW10sIFtdKTtcbi8qKlxuQGludGVybmFsXG4qL1xuRGVjb3JhdGlvblNldC5yZW1vdmVPdmVybGFwID0gcmVtb3ZlT3ZlcmxhcDtcbmNvbnN0IGVtcHR5ID0gRGVjb3JhdGlvblNldC5lbXB0eTtcbi8vIEFuIGFic3RyYWN0aW9uIHRoYXQgYWxsb3dzIHRoZSBjb2RlIGRlYWxpbmcgd2l0aCBkZWNvcmF0aW9ucyB0b1xuLy8gdHJlYXQgbXVsdGlwbGUgRGVjb3JhdGlvblNldCBvYmplY3RzIGFzIGlmIGl0IHdlcmUgYSBzaW5nbGUgb2JqZWN0XG4vLyB3aXRoIChhIHN1YnNldCBvZikgdGhlIHNhbWUgaW50ZXJmYWNlLlxuY2xhc3MgRGVjb3JhdGlvbkdyb3VwIHtcbiAgICBjb25zdHJ1Y3RvcihtZW1iZXJzKSB7XG4gICAgICAgIHRoaXMubWVtYmVycyA9IG1lbWJlcnM7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nLCBkb2MpIHtcbiAgICAgICAgY29uc3QgbWFwcGVkRGVjb3MgPSB0aGlzLm1lbWJlcnMubWFwKG1lbWJlciA9PiBtZW1iZXIubWFwKG1hcHBpbmcsIGRvYywgbm9TcGVjKSk7XG4gICAgICAgIHJldHVybiBEZWNvcmF0aW9uR3JvdXAuZnJvbShtYXBwZWREZWNvcyk7XG4gICAgfVxuICAgIGZvckNoaWxkKG9mZnNldCwgY2hpbGQpIHtcbiAgICAgICAgaWYgKGNoaWxkLmlzTGVhZilcbiAgICAgICAgICAgIHJldHVybiBEZWNvcmF0aW9uU2V0LmVtcHR5O1xuICAgICAgICBsZXQgZm91bmQgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm1lbWJlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCByZXN1bHQgPSB0aGlzLm1lbWJlcnNbaV0uZm9yQ2hpbGQob2Zmc2V0LCBjaGlsZCk7XG4gICAgICAgICAgICBpZiAocmVzdWx0ID09IGVtcHR5KVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIERlY29yYXRpb25Hcm91cClcbiAgICAgICAgICAgICAgICBmb3VuZCA9IGZvdW5kLmNvbmNhdChyZXN1bHQubWVtYmVycyk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgZm91bmQucHVzaChyZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBEZWNvcmF0aW9uR3JvdXAuZnJvbShmb3VuZCk7XG4gICAgfVxuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgRGVjb3JhdGlvbkdyb3VwKSB8fFxuICAgICAgICAgICAgb3RoZXIubWVtYmVycy5sZW5ndGggIT0gdGhpcy5tZW1iZXJzLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm1lbWJlcnMubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAoIXRoaXMubWVtYmVyc1tpXS5lcShvdGhlci5tZW1iZXJzW2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBsb2NhbHMobm9kZSkge1xuICAgICAgICBsZXQgcmVzdWx0LCBzb3J0ZWQgPSB0cnVlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubWVtYmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGxvY2FscyA9IHRoaXMubWVtYmVyc1tpXS5sb2NhbHNJbm5lcihub2RlKTtcbiAgICAgICAgICAgIGlmICghbG9jYWxzLmxlbmd0aClcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gbG9jYWxzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHNvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgc29ydGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbG9jYWxzLmxlbmd0aDsgaisrKVxuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChsb2NhbHNbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQgPyByZW1vdmVPdmVybGFwKHNvcnRlZCA/IHJlc3VsdCA6IHJlc3VsdC5zb3J0KGJ5UG9zKSkgOiBub25lO1xuICAgIH1cbiAgICAvLyBDcmVhdGUgYSBncm91cCBmb3IgdGhlIGdpdmVuIGFycmF5IG9mIGRlY29yYXRpb24gc2V0cywgb3IgcmV0dXJuXG4gICAgLy8gYSBzaW5nbGUgc2V0IHdoZW4gcG9zc2libGUuXG4gICAgc3RhdGljIGZyb20obWVtYmVycykge1xuICAgICAgICBzd2l0Y2ggKG1lbWJlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6IHJldHVybiBlbXB0eTtcbiAgICAgICAgICAgIGNhc2UgMTogcmV0dXJuIG1lbWJlcnNbMF07XG4gICAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbmV3IERlY29yYXRpb25Hcm91cChtZW1iZXJzLmV2ZXJ5KG0gPT4gbSBpbnN0YW5jZW9mIERlY29yYXRpb25TZXQpID8gbWVtYmVycyA6XG4gICAgICAgICAgICAgICAgbWVtYmVycy5yZWR1Y2UoKHIsIG0pID0+IHIuY29uY2F0KG0gaW5zdGFuY2VvZiBEZWNvcmF0aW9uU2V0ID8gbSA6IG0ubWVtYmVycyksIFtdKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yRWFjaFNldChmKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5tZW1iZXJzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgdGhpcy5tZW1iZXJzW2ldLmZvckVhY2hTZXQoZik7XG4gICAgfVxufVxuZnVuY3Rpb24gbWFwQ2hpbGRyZW4ob2xkQ2hpbGRyZW4sIG5ld0xvY2FsLCBtYXBwaW5nLCBub2RlLCBvZmZzZXQsIG9sZE9mZnNldCwgb3B0aW9ucykge1xuICAgIGxldCBjaGlsZHJlbiA9IG9sZENoaWxkcmVuLnNsaWNlKCk7XG4gICAgLy8gTWFyayB0aGUgY2hpbGRyZW4gdGhhdCBhcmUgZGlyZWN0bHkgdG91Y2hlZCBieSBjaGFuZ2VzLCBhbmRcbiAgICAvLyBtb3ZlIHRob3NlIHRoYXQgYXJlIGFmdGVyIHRoZSBjaGFuZ2VzLlxuICAgIGZvciAobGV0IGkgPSAwLCBiYXNlT2Zmc2V0ID0gb2xkT2Zmc2V0OyBpIDwgbWFwcGluZy5tYXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBtb3ZlZCA9IDA7XG4gICAgICAgIG1hcHBpbmcubWFwc1tpXS5mb3JFYWNoKChvbGRTdGFydCwgb2xkRW5kLCBuZXdTdGFydCwgbmV3RW5kKSA9PiB7XG4gICAgICAgICAgICBsZXQgZFNpemUgPSAobmV3RW5kIC0gbmV3U3RhcnQpIC0gKG9sZEVuZCAtIG9sZFN0YXJ0KTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgICAgICBsZXQgZW5kID0gY2hpbGRyZW5baSArIDFdO1xuICAgICAgICAgICAgICAgIGlmIChlbmQgPCAwIHx8IG9sZFN0YXJ0ID4gZW5kICsgYmFzZU9mZnNldCAtIG1vdmVkKVxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSBjaGlsZHJlbltpXSArIGJhc2VPZmZzZXQgLSBtb3ZlZDtcbiAgICAgICAgICAgICAgICBpZiAob2xkRW5kID49IHN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuW2kgKyAxXSA9IG9sZFN0YXJ0IDw9IHN0YXJ0ID8gLTIgOiAtMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAob2xkU3RhcnQgPj0gYmFzZU9mZnNldCAmJiBkU2l6ZSkge1xuICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbltpXSArPSBkU2l6ZTtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baSArIDFdICs9IGRTaXplO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1vdmVkICs9IGRTaXplO1xuICAgICAgICB9KTtcbiAgICAgICAgYmFzZU9mZnNldCA9IG1hcHBpbmcubWFwc1tpXS5tYXAoYmFzZU9mZnNldCwgLTEpO1xuICAgIH1cbiAgICAvLyBGaW5kIHRoZSBjaGlsZCBub2RlcyB0aGF0IHN0aWxsIGNvcnJlc3BvbmQgdG8gYSBzaW5nbGUgbm9kZSxcbiAgICAvLyByZWN1cnNpdmVseSBjYWxsIG1hcElubmVyIG9uIHRoZW0gYW5kIHVwZGF0ZSB0aGVpciBwb3NpdGlvbnMuXG4gICAgbGV0IG11c3RSZWJ1aWxkID0gZmFsc2U7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkgKz0gMylcbiAgICAgICAgaWYgKGNoaWxkcmVuW2kgKyAxXSA8IDApIHsgLy8gVG91Y2hlZCBub2Rlc1xuICAgICAgICAgICAgaWYgKGNoaWxkcmVuW2kgKyAxXSA9PSAtMikge1xuICAgICAgICAgICAgICAgIG11c3RSZWJ1aWxkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjaGlsZHJlbltpICsgMV0gPSAtMTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBmcm9tID0gbWFwcGluZy5tYXAob2xkQ2hpbGRyZW5baV0gKyBvbGRPZmZzZXQpLCBmcm9tTG9jYWwgPSBmcm9tIC0gb2Zmc2V0O1xuICAgICAgICAgICAgaWYgKGZyb21Mb2NhbCA8IDAgfHwgZnJvbUxvY2FsID49IG5vZGUuY29udGVudC5zaXplKSB7XG4gICAgICAgICAgICAgICAgbXVzdFJlYnVpbGQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTXVzdCByZWFkIG9sZENoaWxkcmVuIGJlY2F1c2UgY2hpbGRyZW4gd2FzIHRhZ2dlZCB3aXRoIC0xXG4gICAgICAgICAgICBsZXQgdG8gPSBtYXBwaW5nLm1hcChvbGRDaGlsZHJlbltpICsgMV0gKyBvbGRPZmZzZXQsIC0xKSwgdG9Mb2NhbCA9IHRvIC0gb2Zmc2V0O1xuICAgICAgICAgICAgbGV0IHsgaW5kZXgsIG9mZnNldDogY2hpbGRPZmZzZXQgfSA9IG5vZGUuY29udGVudC5maW5kSW5kZXgoZnJvbUxvY2FsKTtcbiAgICAgICAgICAgIGxldCBjaGlsZE5vZGUgPSBub2RlLm1heWJlQ2hpbGQoaW5kZXgpO1xuICAgICAgICAgICAgaWYgKGNoaWxkTm9kZSAmJiBjaGlsZE9mZnNldCA9PSBmcm9tTG9jYWwgJiYgY2hpbGRPZmZzZXQgKyBjaGlsZE5vZGUubm9kZVNpemUgPT0gdG9Mb2NhbCkge1xuICAgICAgICAgICAgICAgIGxldCBtYXBwZWQgPSBjaGlsZHJlbltpICsgMl1cbiAgICAgICAgICAgICAgICAgICAgLm1hcElubmVyKG1hcHBpbmcsIGNoaWxkTm9kZSwgZnJvbSArIDEsIG9sZENoaWxkcmVuW2ldICsgb2xkT2Zmc2V0ICsgMSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgaWYgKG1hcHBlZCAhPSBlbXB0eSkge1xuICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbltpXSA9IGZyb21Mb2NhbDtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baSArIDFdID0gdG9Mb2NhbDtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baSArIDJdID0gbWFwcGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baSArIDFdID0gLTI7XG4gICAgICAgICAgICAgICAgICAgIG11c3RSZWJ1aWxkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBtdXN0UmVidWlsZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAvLyBSZW1haW5pbmcgY2hpbGRyZW4gbXVzdCBiZSBjb2xsZWN0ZWQgYW5kIHJlYnVpbHQgaW50byB0aGUgYXBwcm9wcmlhdGUgc3RydWN0dXJlXG4gICAgaWYgKG11c3RSZWJ1aWxkKSB7XG4gICAgICAgIGxldCBkZWNvcmF0aW9ucyA9IG1hcEFuZEdhdGhlclJlbWFpbmluZ0RlY29yYXRpb25zKGNoaWxkcmVuLCBvbGRDaGlsZHJlbiwgbmV3TG9jYWwsIG1hcHBpbmcsIG9mZnNldCwgb2xkT2Zmc2V0LCBvcHRpb25zKTtcbiAgICAgICAgbGV0IGJ1aWx0ID0gYnVpbGRUcmVlKGRlY29yYXRpb25zLCBub2RlLCAwLCBvcHRpb25zKTtcbiAgICAgICAgbmV3TG9jYWwgPSBidWlsdC5sb2NhbDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkgKz0gMylcbiAgICAgICAgICAgIGlmIChjaGlsZHJlbltpICsgMV0gPCAwKSB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW4uc3BsaWNlKGksIDMpO1xuICAgICAgICAgICAgICAgIGkgLT0gMztcbiAgICAgICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSAwOyBpIDwgYnVpbHQuY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgIGxldCBmcm9tID0gYnVpbHQuY2hpbGRyZW5baV07XG4gICAgICAgICAgICB3aGlsZSAoaiA8IGNoaWxkcmVuLmxlbmd0aCAmJiBjaGlsZHJlbltqXSA8IGZyb20pXG4gICAgICAgICAgICAgICAgaiArPSAzO1xuICAgICAgICAgICAgY2hpbGRyZW4uc3BsaWNlKGosIDAsIGJ1aWx0LmNoaWxkcmVuW2ldLCBidWlsdC5jaGlsZHJlbltpICsgMV0sIGJ1aWx0LmNoaWxkcmVuW2kgKyAyXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBEZWNvcmF0aW9uU2V0KG5ld0xvY2FsLnNvcnQoYnlQb3MpLCBjaGlsZHJlbik7XG59XG5mdW5jdGlvbiBtb3ZlU3BhbnMoc3BhbnMsIG9mZnNldCkge1xuICAgIGlmICghb2Zmc2V0IHx8ICFzcGFucy5sZW5ndGgpXG4gICAgICAgIHJldHVybiBzcGFucztcbiAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGFucy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgc3BhbiA9IHNwYW5zW2ldO1xuICAgICAgICByZXN1bHQucHVzaChuZXcgRGVjb3JhdGlvbihzcGFuLmZyb20gKyBvZmZzZXQsIHNwYW4udG8gKyBvZmZzZXQsIHNwYW4udHlwZSkpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gbWFwQW5kR2F0aGVyUmVtYWluaW5nRGVjb3JhdGlvbnMoY2hpbGRyZW4sIG9sZENoaWxkcmVuLCBkZWNvcmF0aW9ucywgbWFwcGluZywgb2Zmc2V0LCBvbGRPZmZzZXQsIG9wdGlvbnMpIHtcbiAgICAvLyBHYXRoZXIgYWxsIGRlY29yYXRpb25zIGZyb20gdGhlIHJlbWFpbmluZyBtYXJrZWQgY2hpbGRyZW5cbiAgICBmdW5jdGlvbiBnYXRoZXIoc2V0LCBvbGRPZmZzZXQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZXQubG9jYWwubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBtYXBwZWQgPSBzZXQubG9jYWxbaV0ubWFwKG1hcHBpbmcsIG9mZnNldCwgb2xkT2Zmc2V0KTtcbiAgICAgICAgICAgIGlmIChtYXBwZWQpXG4gICAgICAgICAgICAgICAgZGVjb3JhdGlvbnMucHVzaChtYXBwZWQpO1xuICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5vblJlbW92ZSlcbiAgICAgICAgICAgICAgICBvcHRpb25zLm9uUmVtb3ZlKHNldC5sb2NhbFtpXS5zcGVjKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNldC5jaGlsZHJlbi5sZW5ndGg7IGkgKz0gMylcbiAgICAgICAgICAgIGdhdGhlcihzZXQuY2hpbGRyZW5baSArIDJdLCBzZXQuY2hpbGRyZW5baV0gKyBvbGRPZmZzZXQgKyAxKTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkgKz0gMylcbiAgICAgICAgaWYgKGNoaWxkcmVuW2kgKyAxXSA9PSAtMSlcbiAgICAgICAgICAgIGdhdGhlcihjaGlsZHJlbltpICsgMl0sIG9sZENoaWxkcmVuW2ldICsgb2xkT2Zmc2V0ICsgMSk7XG4gICAgcmV0dXJuIGRlY29yYXRpb25zO1xufVxuZnVuY3Rpb24gdGFrZVNwYW5zRm9yTm9kZShzcGFucywgbm9kZSwgb2Zmc2V0KSB7XG4gICAgaWYgKG5vZGUuaXNMZWFmKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBsZXQgZW5kID0gb2Zmc2V0ICsgbm9kZS5ub2RlU2l6ZSwgZm91bmQgPSBudWxsO1xuICAgIGZvciAobGV0IGkgPSAwLCBzcGFuOyBpIDwgc3BhbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKChzcGFuID0gc3BhbnNbaV0pICYmIHNwYW4uZnJvbSA+IG9mZnNldCAmJiBzcGFuLnRvIDwgZW5kKSB7XG4gICAgICAgICAgICAoZm91bmQgfHwgKGZvdW5kID0gW10pKS5wdXNoKHNwYW4pO1xuICAgICAgICAgICAgc3BhbnNbaV0gPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmb3VuZDtcbn1cbmZ1bmN0aW9uIHdpdGhvdXROdWxscyhhcnJheSkge1xuICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKVxuICAgICAgICBpZiAoYXJyYXlbaV0gIT0gbnVsbClcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGFycmF5W2ldKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLy8gQnVpbGQgdXAgYSB0cmVlIHRoYXQgY29ycmVzcG9uZHMgdG8gYSBzZXQgb2YgZGVjb3JhdGlvbnMuIGBvZmZzZXRgXG4vLyBpcyBhIGJhc2Ugb2Zmc2V0IHRoYXQgc2hvdWxkIGJlIHN1YnRyYWN0ZWQgZnJvbSB0aGUgYGZyb21gIGFuZCBgdG9gXG4vLyBwb3NpdGlvbnMgaW4gdGhlIHNwYW5zIChzbyB0aGF0IHdlIGRvbid0IGhhdmUgdG8gYWxsb2NhdGUgbmV3IHNwYW5zXG4vLyBmb3IgcmVjdXJzaXZlIGNhbGxzKS5cbmZ1bmN0aW9uIGJ1aWxkVHJlZShzcGFucywgbm9kZSwgb2Zmc2V0LCBvcHRpb25zKSB7XG4gICAgbGV0IGNoaWxkcmVuID0gW10sIGhhc051bGxzID0gZmFsc2U7XG4gICAgbm9kZS5mb3JFYWNoKChjaGlsZE5vZGUsIGxvY2FsU3RhcnQpID0+IHtcbiAgICAgICAgbGV0IGZvdW5kID0gdGFrZVNwYW5zRm9yTm9kZShzcGFucywgY2hpbGROb2RlLCBsb2NhbFN0YXJ0ICsgb2Zmc2V0KTtcbiAgICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgICAgICBoYXNOdWxscyA9IHRydWU7XG4gICAgICAgICAgICBsZXQgc3VidHJlZSA9IGJ1aWxkVHJlZShmb3VuZCwgY2hpbGROb2RlLCBvZmZzZXQgKyBsb2NhbFN0YXJ0ICsgMSwgb3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAoc3VidHJlZSAhPSBlbXB0eSlcbiAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGxvY2FsU3RhcnQsIGxvY2FsU3RhcnQgKyBjaGlsZE5vZGUubm9kZVNpemUsIHN1YnRyZWUpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgbGV0IGxvY2FscyA9IG1vdmVTcGFucyhoYXNOdWxscyA/IHdpdGhvdXROdWxscyhzcGFucykgOiBzcGFucywgLW9mZnNldCkuc29ydChieVBvcyk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsb2NhbHMubGVuZ3RoOyBpKyspXG4gICAgICAgIGlmICghbG9jYWxzW2ldLnR5cGUudmFsaWQobm9kZSwgbG9jYWxzW2ldKSkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMub25SZW1vdmUpXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5vblJlbW92ZShsb2NhbHNbaV0uc3BlYyk7XG4gICAgICAgICAgICBsb2NhbHMuc3BsaWNlKGktLSwgMSk7XG4gICAgICAgIH1cbiAgICByZXR1cm4gbG9jYWxzLmxlbmd0aCB8fCBjaGlsZHJlbi5sZW5ndGggPyBuZXcgRGVjb3JhdGlvblNldChsb2NhbHMsIGNoaWxkcmVuKSA6IGVtcHR5O1xufVxuLy8gVXNlZCB0byBzb3J0IGRlY29yYXRpb25zIHNvIHRoYXQgb25lcyB3aXRoIGEgbG93IHN0YXJ0IHBvc2l0aW9uXG4vLyBjb21lIGZpcnN0LCBhbmQgd2l0aGluIGEgc2V0IHdpdGggdGhlIHNhbWUgc3RhcnQgcG9zaXRpb24sIHRob3NlXG4vLyB3aXRoIGFuIHNtYWxsZXIgZW5kIHBvc2l0aW9uIGNvbWUgZmlyc3QuXG5mdW5jdGlvbiBieVBvcyhhLCBiKSB7XG4gICAgcmV0dXJuIGEuZnJvbSAtIGIuZnJvbSB8fCBhLnRvIC0gYi50bztcbn1cbi8vIFNjYW4gYSBzb3J0ZWQgYXJyYXkgb2YgZGVjb3JhdGlvbnMgZm9yIHBhcnRpYWxseSBvdmVybGFwcGluZyBzcGFucyxcbi8vIGFuZCBzcGxpdCB0aG9zZSBzbyB0aGF0IG9ubHkgZnVsbHkgb3ZlcmxhcHBpbmcgc3BhbnMgYXJlIGxlZnQgKHRvXG4vLyBtYWtlIHN1YnNlcXVlbnQgcmVuZGVyaW5nIGVhc2llcikuIFdpbGwgcmV0dXJuIHRoZSBpbnB1dCBhcnJheSBpZlxuLy8gbm8gcGFydGlhbGx5IG92ZXJsYXBwaW5nIHNwYW5zIGFyZSBmb3VuZCAodGhlIGNvbW1vbiBjYXNlKS5cbmZ1bmN0aW9uIHJlbW92ZU92ZXJsYXAoc3BhbnMpIHtcbiAgICBsZXQgd29ya2luZyA9IHNwYW5zO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgd29ya2luZy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgbGV0IHNwYW4gPSB3b3JraW5nW2ldO1xuICAgICAgICBpZiAoc3Bhbi5mcm9tICE9IHNwYW4udG8pXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCB3b3JraW5nLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5leHQgPSB3b3JraW5nW2pdO1xuICAgICAgICAgICAgICAgIGlmIChuZXh0LmZyb20gPT0gc3Bhbi5mcm9tKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0LnRvICE9IHNwYW4udG8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3b3JraW5nID09IHNwYW5zKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtpbmcgPSBzcGFucy5zbGljZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9sbG93ZWQgYnkgYSBwYXJ0aWFsbHkgb3ZlcmxhcHBpbmcgbGFyZ2VyIHNwYW4uIFNwbGl0IHRoYXRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNwYW4uXG4gICAgICAgICAgICAgICAgICAgICAgICB3b3JraW5nW2pdID0gbmV4dC5jb3B5KG5leHQuZnJvbSwgc3Bhbi50byk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRBaGVhZCh3b3JraW5nLCBqICsgMSwgbmV4dC5jb3B5KHNwYW4udG8sIG5leHQudG8pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0LmZyb20gPCBzcGFuLnRvKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAod29ya2luZyA9PSBzcGFucylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JraW5nID0gc3BhbnMuc2xpY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBlbmQgb2YgdGhpcyBvbmUgb3ZlcmxhcHMgd2l0aCBhIHN1YnNlcXVlbnQgc3Bhbi4gU3BsaXRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgb25lLlxuICAgICAgICAgICAgICAgICAgICAgICAgd29ya2luZ1tpXSA9IHNwYW4uY29weShzcGFuLmZyb20sIG5leHQuZnJvbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRBaGVhZCh3b3JraW5nLCBqLCBzcGFuLmNvcHkobmV4dC5mcm9tLCBzcGFuLnRvKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gd29ya2luZztcbn1cbmZ1bmN0aW9uIGluc2VydEFoZWFkKGFycmF5LCBpLCBkZWNvKSB7XG4gICAgd2hpbGUgKGkgPCBhcnJheS5sZW5ndGggJiYgYnlQb3MoZGVjbywgYXJyYXlbaV0pID4gMClcbiAgICAgICAgaSsrO1xuICAgIGFycmF5LnNwbGljZShpLCAwLCBkZWNvKTtcbn1cbi8vIEdldCB0aGUgZGVjb3JhdGlvbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IHByb3BzIG9mIGEgdmlldy5cbmZ1bmN0aW9uIHZpZXdEZWNvcmF0aW9ucyh2aWV3KSB7XG4gICAgbGV0IGZvdW5kID0gW107XG4gICAgdmlldy5zb21lUHJvcChcImRlY29yYXRpb25zXCIsIGYgPT4ge1xuICAgICAgICBsZXQgcmVzdWx0ID0gZih2aWV3LnN0YXRlKTtcbiAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQgIT0gZW1wdHkpXG4gICAgICAgICAgICBmb3VuZC5wdXNoKHJlc3VsdCk7XG4gICAgfSk7XG4gICAgaWYgKHZpZXcuY3Vyc29yV3JhcHBlcilcbiAgICAgICAgZm91bmQucHVzaChEZWNvcmF0aW9uU2V0LmNyZWF0ZSh2aWV3LnN0YXRlLmRvYywgW3ZpZXcuY3Vyc29yV3JhcHBlci5kZWNvXSkpO1xuICAgIHJldHVybiBEZWNvcmF0aW9uR3JvdXAuZnJvbShmb3VuZCk7XG59XG5cbmNvbnN0IG9ic2VydmVPcHRpb25zID0ge1xuICAgIGNoaWxkTGlzdDogdHJ1ZSxcbiAgICBjaGFyYWN0ZXJEYXRhOiB0cnVlLFxuICAgIGNoYXJhY3RlckRhdGFPbGRWYWx1ZTogdHJ1ZSxcbiAgICBhdHRyaWJ1dGVzOiB0cnVlLFxuICAgIGF0dHJpYnV0ZU9sZFZhbHVlOiB0cnVlLFxuICAgIHN1YnRyZWU6IHRydWVcbn07XG4vLyBJRTExIGhhcyB2ZXJ5IGJyb2tlbiBtdXRhdGlvbiBvYnNlcnZlcnMsIHNvIHdlIGFsc28gbGlzdGVuIHRvIERPTUNoYXJhY3RlckRhdGFNb2RpZmllZFxuY29uc3QgdXNlQ2hhckRhdGEgPSBpZSAmJiBpZV92ZXJzaW9uIDw9IDExO1xuY2xhc3MgU2VsZWN0aW9uU3RhdGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmFuY2hvck5vZGUgPSBudWxsO1xuICAgICAgICB0aGlzLmFuY2hvck9mZnNldCA9IDA7XG4gICAgICAgIHRoaXMuZm9jdXNOb2RlID0gbnVsbDtcbiAgICAgICAgdGhpcy5mb2N1c09mZnNldCA9IDA7XG4gICAgfVxuICAgIHNldChzZWwpIHtcbiAgICAgICAgdGhpcy5hbmNob3JOb2RlID0gc2VsLmFuY2hvck5vZGU7XG4gICAgICAgIHRoaXMuYW5jaG9yT2Zmc2V0ID0gc2VsLmFuY2hvck9mZnNldDtcbiAgICAgICAgdGhpcy5mb2N1c05vZGUgPSBzZWwuZm9jdXNOb2RlO1xuICAgICAgICB0aGlzLmZvY3VzT2Zmc2V0ID0gc2VsLmZvY3VzT2Zmc2V0O1xuICAgIH1cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5hbmNob3JOb2RlID0gdGhpcy5mb2N1c05vZGUgPSBudWxsO1xuICAgIH1cbiAgICBlcShzZWwpIHtcbiAgICAgICAgcmV0dXJuIHNlbC5hbmNob3JOb2RlID09IHRoaXMuYW5jaG9yTm9kZSAmJiBzZWwuYW5jaG9yT2Zmc2V0ID09IHRoaXMuYW5jaG9yT2Zmc2V0ICYmXG4gICAgICAgICAgICBzZWwuZm9jdXNOb2RlID09IHRoaXMuZm9jdXNOb2RlICYmIHNlbC5mb2N1c09mZnNldCA9PSB0aGlzLmZvY3VzT2Zmc2V0O1xuICAgIH1cbn1cbmNsYXNzIERPTU9ic2VydmVyIHtcbiAgICBjb25zdHJ1Y3Rvcih2aWV3LCBoYW5kbGVET01DaGFuZ2UpIHtcbiAgICAgICAgdGhpcy52aWV3ID0gdmlldztcbiAgICAgICAgdGhpcy5oYW5kbGVET01DaGFuZ2UgPSBoYW5kbGVET01DaGFuZ2U7XG4gICAgICAgIHRoaXMucXVldWUgPSBbXTtcbiAgICAgICAgdGhpcy5mbHVzaGluZ1Nvb24gPSAtMTtcbiAgICAgICAgdGhpcy5vYnNlcnZlciA9IG51bGw7XG4gICAgICAgIHRoaXMuY3VycmVudFNlbGVjdGlvbiA9IG5ldyBTZWxlY3Rpb25TdGF0ZTtcbiAgICAgICAgdGhpcy5vbkNoYXJEYXRhID0gbnVsbDtcbiAgICAgICAgdGhpcy5zdXBwcmVzc2luZ1NlbGVjdGlvblVwZGF0ZXMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5sYXN0Q2hhbmdlZFRleHROb2RlID0gbnVsbDtcbiAgICAgICAgdGhpcy5vYnNlcnZlciA9IHdpbmRvdy5NdXRhdGlvbk9ic2VydmVyICYmXG4gICAgICAgICAgICBuZXcgd2luZG93Lk11dGF0aW9uT2JzZXJ2ZXIobXV0YXRpb25zID0+IHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG11dGF0aW9ucy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5xdWV1ZS5wdXNoKG11dGF0aW9uc1tpXSk7XG4gICAgICAgICAgICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPD0gMTEgJiYgbXV0YXRpb25zLnNvbWUobSA9PiBtLnR5cGUgPT0gXCJjaGlsZExpc3RcIiAmJiBtLnJlbW92ZWROb2Rlcy5sZW5ndGggfHxcbiAgICAgICAgICAgICAgICAgICAgbS50eXBlID09IFwiY2hhcmFjdGVyRGF0YVwiICYmIG0ub2xkVmFsdWUubGVuZ3RoID4gbS50YXJnZXQubm9kZVZhbHVlLmxlbmd0aCkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSUUxMSB3aWxsIHNvbWV0aW1lcyAob24gYmFja3NwYWNpbmcgb3V0IGEgc2luZ2xlIGNoYXJhY3RlclxuICAgICAgICAgICAgICAgICAgICAvLyB0ZXh0IG5vZGUgYWZ0ZXIgYSBCUiBub2RlKSBjYWxsIHRoZSBvYnNlcnZlciBjYWxsYmFja1xuICAgICAgICAgICAgICAgICAgICAvLyBiZWZvcmUgYWN0dWFsbHkgdXBkYXRpbmcgdGhlIERPTSwgd2hpY2ggd2lsbCBjYXVzZVxuICAgICAgICAgICAgICAgICAgICAvLyBQcm9zZU1pcnJvciB0byBtaXNzIHRoZSBjaGFuZ2UgKHNlZSAjOTMwKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZsdXNoU29vbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmIChzYWZhcmkgJiYgdmlldy5jb21wb3NpbmcgJiYgbXV0YXRpb25zLnNvbWUobSA9PiBtLnR5cGUgPT0gXCJjaGlsZExpc3RcIiAmJiBtLnRhcmdldC5ub2RlTmFtZSA9PSBcIlRSXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBkb2VzIHdlaXJkIHN0dWZmIHdoZW4gZmluaXNoaW5nIGEgY29tcG9zaXRpb24gaW4gYVxuICAgICAgICAgICAgICAgICAgICAvLyB0YWJsZSBjZWxsLCB3aGljaCB0ZW5kcyB0byBpbnZvbHZlIGluc2VydGluZyBpbmFwcHJvcHJpYXRlXG4gICAgICAgICAgICAgICAgICAgIC8vIG5vZGVzIGluIHRoZSB0YWJsZSByb3cuXG4gICAgICAgICAgICAgICAgICAgIHZpZXcuaW5wdXQuYmFkU2FmYXJpQ29tcG9zaXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZsdXNoU29vbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mbHVzaCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICBpZiAodXNlQ2hhckRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMub25DaGFyRGF0YSA9IGUgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucXVldWUucHVzaCh7IHRhcmdldDogZS50YXJnZXQsIHR5cGU6IFwiY2hhcmFjdGVyRGF0YVwiLCBvbGRWYWx1ZTogZS5wcmV2VmFsdWUgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5mbHVzaFNvb24oKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vblNlbGVjdGlvbkNoYW5nZSA9IHRoaXMub25TZWxlY3Rpb25DaGFuZ2UuYmluZCh0aGlzKTtcbiAgICB9XG4gICAgZmx1c2hTb29uKCkge1xuICAgICAgICBpZiAodGhpcy5mbHVzaGluZ1Nvb24gPCAwKVxuICAgICAgICAgICAgdGhpcy5mbHVzaGluZ1Nvb24gPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7IHRoaXMuZmx1c2hpbmdTb29uID0gLTE7IHRoaXMuZmx1c2goKTsgfSwgMjApO1xuICAgIH1cbiAgICBmb3JjZUZsdXNoKCkge1xuICAgICAgICBpZiAodGhpcy5mbHVzaGluZ1Nvb24gPiAtMSkge1xuICAgICAgICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLmZsdXNoaW5nU29vbik7XG4gICAgICAgICAgICB0aGlzLmZsdXNoaW5nU29vbiA9IC0xO1xuICAgICAgICAgICAgdGhpcy5mbHVzaCgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN0YXJ0KCkge1xuICAgICAgICBpZiAodGhpcy5vYnNlcnZlcikge1xuICAgICAgICAgICAgdGhpcy5vYnNlcnZlci50YWtlUmVjb3JkcygpO1xuICAgICAgICAgICAgdGhpcy5vYnNlcnZlci5vYnNlcnZlKHRoaXMudmlldy5kb20sIG9ic2VydmVPcHRpb25zKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5vbkNoYXJEYXRhKVxuICAgICAgICAgICAgdGhpcy52aWV3LmRvbS5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ2hhcmFjdGVyRGF0YU1vZGlmaWVkXCIsIHRoaXMub25DaGFyRGF0YSk7XG4gICAgICAgIHRoaXMuY29ubmVjdFNlbGVjdGlvbigpO1xuICAgIH1cbiAgICBzdG9wKCkge1xuICAgICAgICBpZiAodGhpcy5vYnNlcnZlcikge1xuICAgICAgICAgICAgbGV0IHRha2UgPSB0aGlzLm9ic2VydmVyLnRha2VSZWNvcmRzKCk7XG4gICAgICAgICAgICBpZiAodGFrZS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRha2UubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucXVldWUucHVzaCh0YWtlW2ldKTtcbiAgICAgICAgICAgICAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB0aGlzLmZsdXNoKCksIDIwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm9uQ2hhckRhdGEpXG4gICAgICAgICAgICB0aGlzLnZpZXcuZG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJET01DaGFyYWN0ZXJEYXRhTW9kaWZpZWRcIiwgdGhpcy5vbkNoYXJEYXRhKTtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0U2VsZWN0aW9uKCk7XG4gICAgfVxuICAgIGNvbm5lY3RTZWxlY3Rpb24oKSB7XG4gICAgICAgIHRoaXMudmlldy5kb20ub3duZXJEb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwic2VsZWN0aW9uY2hhbmdlXCIsIHRoaXMub25TZWxlY3Rpb25DaGFuZ2UpO1xuICAgIH1cbiAgICBkaXNjb25uZWN0U2VsZWN0aW9uKCkge1xuICAgICAgICB0aGlzLnZpZXcuZG9tLm93bmVyRG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNlbGVjdGlvbmNoYW5nZVwiLCB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlKTtcbiAgICB9XG4gICAgc3VwcHJlc3NTZWxlY3Rpb25VcGRhdGVzKCkge1xuICAgICAgICB0aGlzLnN1cHByZXNzaW5nU2VsZWN0aW9uVXBkYXRlcyA9IHRydWU7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zdXBwcmVzc2luZ1NlbGVjdGlvblVwZGF0ZXMgPSBmYWxzZSwgNTApO1xuICAgIH1cbiAgICBvblNlbGVjdGlvbkNoYW5nZSgpIHtcbiAgICAgICAgaWYgKCFoYXNGb2N1c0FuZFNlbGVjdGlvbih0aGlzLnZpZXcpKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpZiAodGhpcy5zdXBwcmVzc2luZ1NlbGVjdGlvblVwZGF0ZXMpXG4gICAgICAgICAgICByZXR1cm4gc2VsZWN0aW9uVG9ET00odGhpcy52aWV3KTtcbiAgICAgICAgLy8gRGVsZXRpb25zIG9uIElFMTEgZmlyZSB0aGVpciBldmVudHMgaW4gdGhlIHdyb25nIG9yZGVyLCBnaXZpbmdcbiAgICAgICAgLy8gdXMgYSBzZWxlY3Rpb24gY2hhbmdlIGV2ZW50IGJlZm9yZSB0aGUgRE9NIGNoYW5nZXMgYXJlXG4gICAgICAgIC8vIHJlcG9ydGVkLlxuICAgICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8PSAxMSAmJiAhdGhpcy52aWV3LnN0YXRlLnNlbGVjdGlvbi5lbXB0eSkge1xuICAgICAgICAgICAgbGV0IHNlbCA9IHRoaXMudmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgICAgICAgICAgLy8gU2VsZWN0aW9uLmlzQ29sbGFwc2VkIGlzbid0IHJlbGlhYmxlIG9uIElFXG4gICAgICAgICAgICBpZiAoc2VsLmZvY3VzTm9kZSAmJiBpc0VxdWl2YWxlbnRQb3NpdGlvbihzZWwuZm9jdXNOb2RlLCBzZWwuZm9jdXNPZmZzZXQsIHNlbC5hbmNob3JOb2RlLCBzZWwuYW5jaG9yT2Zmc2V0KSlcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5mbHVzaFNvb24oKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZsdXNoKCk7XG4gICAgfVxuICAgIHNldEN1clNlbGVjdGlvbigpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50U2VsZWN0aW9uLnNldCh0aGlzLnZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKSk7XG4gICAgfVxuICAgIGlnbm9yZVNlbGVjdGlvbkNoYW5nZShzZWwpIHtcbiAgICAgICAgaWYgKCFzZWwuZm9jdXNOb2RlKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIGxldCBhbmNlc3RvcnMgPSBuZXcgU2V0LCBjb250YWluZXI7XG4gICAgICAgIGZvciAobGV0IHNjYW4gPSBzZWwuZm9jdXNOb2RlOyBzY2FuOyBzY2FuID0gcGFyZW50Tm9kZShzY2FuKSlcbiAgICAgICAgICAgIGFuY2VzdG9ycy5hZGQoc2Nhbik7XG4gICAgICAgIGZvciAobGV0IHNjYW4gPSBzZWwuYW5jaG9yTm9kZTsgc2Nhbjsgc2NhbiA9IHBhcmVudE5vZGUoc2NhbikpXG4gICAgICAgICAgICBpZiAoYW5jZXN0b3JzLmhhcyhzY2FuKSkge1xuICAgICAgICAgICAgICAgIGNvbnRhaW5lciA9IHNjYW47XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIGxldCBkZXNjID0gY29udGFpbmVyICYmIHRoaXMudmlldy5kb2NWaWV3Lm5lYXJlc3REZXNjKGNvbnRhaW5lcik7XG4gICAgICAgIGlmIChkZXNjICYmIGRlc2MuaWdub3JlTXV0YXRpb24oe1xuICAgICAgICAgICAgdHlwZTogXCJzZWxlY3Rpb25cIixcbiAgICAgICAgICAgIHRhcmdldDogY29udGFpbmVyLm5vZGVUeXBlID09IDMgPyBjb250YWluZXIucGFyZW50Tm9kZSA6IGNvbnRhaW5lclxuICAgICAgICB9KSkge1xuICAgICAgICAgICAgdGhpcy5zZXRDdXJTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHBlbmRpbmdSZWNvcmRzKCkge1xuICAgICAgICBpZiAodGhpcy5vYnNlcnZlcilcbiAgICAgICAgICAgIGZvciAobGV0IG11dCBvZiB0aGlzLm9ic2VydmVyLnRha2VSZWNvcmRzKCkpXG4gICAgICAgICAgICAgICAgdGhpcy5xdWV1ZS5wdXNoKG11dCk7XG4gICAgICAgIHJldHVybiB0aGlzLnF1ZXVlO1xuICAgIH1cbiAgICBmbHVzaCgpIHtcbiAgICAgICAgbGV0IHsgdmlldyB9ID0gdGhpcztcbiAgICAgICAgaWYgKCF2aWV3LmRvY1ZpZXcgfHwgdGhpcy5mbHVzaGluZ1Nvb24gPiAtMSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgbGV0IG11dGF0aW9ucyA9IHRoaXMucGVuZGluZ1JlY29yZHMoKTtcbiAgICAgICAgaWYgKG11dGF0aW9ucy5sZW5ndGgpXG4gICAgICAgICAgICB0aGlzLnF1ZXVlID0gW107XG4gICAgICAgIGxldCBzZWwgPSB2aWV3LmRvbVNlbGVjdGlvblJhbmdlKCk7XG4gICAgICAgIGxldCBuZXdTZWwgPSAhdGhpcy5zdXBwcmVzc2luZ1NlbGVjdGlvblVwZGF0ZXMgJiYgIXRoaXMuY3VycmVudFNlbGVjdGlvbi5lcShzZWwpICYmIGhhc0ZvY3VzQW5kU2VsZWN0aW9uKHZpZXcpICYmICF0aGlzLmlnbm9yZVNlbGVjdGlvbkNoYW5nZShzZWwpO1xuICAgICAgICBsZXQgZnJvbSA9IC0xLCB0byA9IC0xLCB0eXBlT3ZlciA9IGZhbHNlLCBhZGRlZCA9IFtdO1xuICAgICAgICBpZiAodmlldy5lZGl0YWJsZSkge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtdXRhdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gdGhpcy5yZWdpc3Rlck11dGF0aW9uKG11dGF0aW9uc1tpXSwgYWRkZWQpO1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgZnJvbSA9IGZyb20gPCAwID8gcmVzdWx0LmZyb20gOiBNYXRoLm1pbihyZXN1bHQuZnJvbSwgZnJvbSk7XG4gICAgICAgICAgICAgICAgICAgIHRvID0gdG8gPCAwID8gcmVzdWx0LnRvIDogTWF0aC5tYXgocmVzdWx0LnRvLCB0byk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQudHlwZU92ZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlT3ZlciA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChhZGRlZC5zb21lKG4gPT4gbi5ub2RlTmFtZSA9PSBcIkJSXCIpICYmICh2aWV3LmlucHV0Lmxhc3RLZXlDb2RlID09IDggfHwgdmlldy5pbnB1dC5sYXN0S2V5Q29kZSA9PSA0NikpIHtcbiAgICAgICAgICAgIC8vIEJyb3dzZXJzIHNvbWV0aW1lcyBpbnNlcnQgYSBib2d1cyBicmVhayBub2RlIGlmIHlvdVxuICAgICAgICAgICAgLy8gYmFja3NwYWNlIG91dCB0aGUgbGFzdCBiaXQgb2YgdGV4dCBiZWZvcmUgYW4gaW5saW5lLWZsZXggbm9kZSAoIzE1NTIpXG4gICAgICAgICAgICBmb3IgKGxldCBub2RlIG9mIGFkZGVkKVxuICAgICAgICAgICAgICAgIGlmIChub2RlLm5vZGVOYW1lID09IFwiQlJcIiAmJiBub2RlLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGFmdGVyID0gbm9kZS5uZXh0U2libGluZztcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKGFmdGVyICYmIGFmdGVyLm5vZGVUeXBlID09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhZnRlci5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXIgPSBhZnRlci5maXJzdENoaWxkO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGdlY2tvICYmIGFkZGVkLmxlbmd0aCkge1xuICAgICAgICAgICAgbGV0IGJycyA9IGFkZGVkLmZpbHRlcihuID0+IG4ubm9kZU5hbWUgPT0gXCJCUlwiKTtcbiAgICAgICAgICAgIGlmIChicnMubGVuZ3RoID09IDIpIHtcbiAgICAgICAgICAgICAgICBsZXQgW2EsIGJdID0gYnJzO1xuICAgICAgICAgICAgICAgIGlmIChhLnBhcmVudE5vZGUgJiYgYS5wYXJlbnROb2RlLnBhcmVudE5vZGUgPT0gYi5wYXJlbnROb2RlKVxuICAgICAgICAgICAgICAgICAgICBiLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgYS5yZW1vdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCB7IGZvY3VzTm9kZSB9ID0gdGhpcy5jdXJyZW50U2VsZWN0aW9uO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGJyIG9mIGJycykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcGFyZW50ID0gYnIucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudCAmJiBwYXJlbnQubm9kZU5hbWUgPT0gXCJMSVwiICYmICghZm9jdXNOb2RlIHx8IGJsb2NrUGFyZW50KHZpZXcsIGZvY3VzTm9kZSkgIT0gcGFyZW50KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVhZFNlbCA9IG51bGw7XG4gICAgICAgIC8vIElmIGl0IGxvb2tzIGxpa2UgdGhlIGJyb3dzZXIgaGFzIHJlc2V0IHRoZSBzZWxlY3Rpb24gdG8gdGhlXG4gICAgICAgIC8vIHN0YXJ0IG9mIHRoZSBkb2N1bWVudCBhZnRlciBmb2N1cywgcmVzdG9yZSB0aGUgc2VsZWN0aW9uIGZyb21cbiAgICAgICAgLy8gdGhlIHN0YXRlXG4gICAgICAgIGlmIChmcm9tIDwgMCAmJiBuZXdTZWwgJiYgdmlldy5pbnB1dC5sYXN0Rm9jdXMgPiBEYXRlLm5vdygpIC0gMjAwICYmXG4gICAgICAgICAgICBNYXRoLm1heCh2aWV3LmlucHV0Lmxhc3RUb3VjaCwgdmlldy5pbnB1dC5sYXN0Q2xpY2sudGltZSkgPCBEYXRlLm5vdygpIC0gMzAwICYmXG4gICAgICAgICAgICBzZWxlY3Rpb25Db2xsYXBzZWQoc2VsKSAmJiAocmVhZFNlbCA9IHNlbGVjdGlvbkZyb21ET00odmlldykpICYmXG4gICAgICAgICAgICByZWFkU2VsLmVxKFNlbGVjdGlvbi5uZWFyKHZpZXcuc3RhdGUuZG9jLnJlc29sdmUoMCksIDEpKSkge1xuICAgICAgICAgICAgdmlldy5pbnB1dC5sYXN0Rm9jdXMgPSAwO1xuICAgICAgICAgICAgc2VsZWN0aW9uVG9ET00odmlldyk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRTZWxlY3Rpb24uc2V0KHNlbCk7XG4gICAgICAgICAgICB2aWV3LnNjcm9sbFRvU2VsZWN0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZnJvbSA+IC0xIHx8IG5ld1NlbCkge1xuICAgICAgICAgICAgaWYgKGZyb20gPiAtMSkge1xuICAgICAgICAgICAgICAgIHZpZXcuZG9jVmlldy5tYXJrRGlydHkoZnJvbSwgdG8pO1xuICAgICAgICAgICAgICAgIGNoZWNrQ1NTKHZpZXcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZpZXcuaW5wdXQuYmFkU2FmYXJpQ29tcG9zaXRpb24pIHtcbiAgICAgICAgICAgICAgICB2aWV3LmlucHV0LmJhZFNhZmFyaUNvbXBvc2l0aW9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZml4VXBCYWRTYWZhcmlDb21wb3NpdGlvbih2aWV3LCBhZGRlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmhhbmRsZURPTUNoYW5nZShmcm9tLCB0bywgdHlwZU92ZXIsIGFkZGVkKTtcbiAgICAgICAgICAgIGlmICh2aWV3LmRvY1ZpZXcgJiYgdmlldy5kb2NWaWV3LmRpcnR5KVxuICAgICAgICAgICAgICAgIHZpZXcudXBkYXRlU3RhdGUodmlldy5zdGF0ZSk7XG4gICAgICAgICAgICBlbHNlIGlmICghdGhpcy5jdXJyZW50U2VsZWN0aW9uLmVxKHNlbCkpXG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uVG9ET00odmlldyk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRTZWxlY3Rpb24uc2V0KHNlbCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVnaXN0ZXJNdXRhdGlvbihtdXQsIGFkZGVkKSB7XG4gICAgICAgIC8vIElnbm9yZSBtdXRhdGlvbnMgaW5zaWRlIG5vZGVzIHRoYXQgd2VyZSBhbHJlYWR5IG5vdGVkIGFzIGluc2VydGVkXG4gICAgICAgIGlmIChhZGRlZC5pbmRleE9mKG11dC50YXJnZXQpID4gLTEpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgbGV0IGRlc2MgPSB0aGlzLnZpZXcuZG9jVmlldy5uZWFyZXN0RGVzYyhtdXQudGFyZ2V0KTtcbiAgICAgICAgaWYgKG11dC50eXBlID09IFwiYXR0cmlidXRlc1wiICYmXG4gICAgICAgICAgICAoZGVzYyA9PSB0aGlzLnZpZXcuZG9jVmlldyB8fCBtdXQuYXR0cmlidXRlTmFtZSA9PSBcImNvbnRlbnRlZGl0YWJsZVwiIHx8XG4gICAgICAgICAgICAgICAgLy8gRmlyZWZveCBzb21ldGltZXMgZmlyZXMgc3B1cmlvdXMgZXZlbnRzIGZvciBudWxsL2VtcHR5IHN0eWxlc1xuICAgICAgICAgICAgICAgIChtdXQuYXR0cmlidXRlTmFtZSA9PSBcInN0eWxlXCIgJiYgIW11dC5vbGRWYWx1ZSAmJiAhbXV0LnRhcmdldC5nZXRBdHRyaWJ1dGUoXCJzdHlsZVwiKSkpKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGlmICghZGVzYyB8fCBkZXNjLmlnbm9yZU11dGF0aW9uKG11dCkpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgaWYgKG11dC50eXBlID09IFwiY2hpbGRMaXN0XCIpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbXV0LmFkZGVkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgbm9kZSA9IG11dC5hZGRlZE5vZGVzW2ldO1xuICAgICAgICAgICAgICAgIGFkZGVkLnB1c2gobm9kZSk7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXN0Q2hhbmdlZFRleHROb2RlID0gbm9kZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkZXNjLmNvbnRlbnRET00gJiYgZGVzYy5jb250ZW50RE9NICE9IGRlc2MuZG9tICYmICFkZXNjLmNvbnRlbnRET00uY29udGFpbnMobXV0LnRhcmdldCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgZnJvbTogZGVzYy5wb3NCZWZvcmUsIHRvOiBkZXNjLnBvc0FmdGVyIH07XG4gICAgICAgICAgICBsZXQgcHJldiA9IG11dC5wcmV2aW91c1NpYmxpbmcsIG5leHQgPSBtdXQubmV4dFNpYmxpbmc7XG4gICAgICAgICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8PSAxMSAmJiBtdXQuYWRkZWROb2Rlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAvLyBJRTExIGdpdmVzIHVzIGluY29ycmVjdCBuZXh0L3ByZXYgc2libGluZ3MgZm9yIHNvbWVcbiAgICAgICAgICAgICAgICAvLyBpbnNlcnRpb25zLCBzbyBpZiB0aGVyZSBhcmUgYWRkZWQgbm9kZXMsIHJlY29tcHV0ZSB0aG9zZVxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbXV0LmFkZGVkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHsgcHJldmlvdXNTaWJsaW5nLCBuZXh0U2libGluZyB9ID0gbXV0LmFkZGVkTm9kZXNbaV07XG4gICAgICAgICAgICAgICAgICAgIGlmICghcHJldmlvdXNTaWJsaW5nIHx8IEFycmF5LnByb3RvdHlwZS5pbmRleE9mLmNhbGwobXV0LmFkZGVkTm9kZXMsIHByZXZpb3VzU2libGluZykgPCAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgcHJldiA9IHByZXZpb3VzU2libGluZztcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuZXh0U2libGluZyB8fCBBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKG11dC5hZGRlZE5vZGVzLCBuZXh0U2libGluZykgPCAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dCA9IG5leHRTaWJsaW5nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBmcm9tT2Zmc2V0ID0gcHJldiAmJiBwcmV2LnBhcmVudE5vZGUgPT0gbXV0LnRhcmdldFxuICAgICAgICAgICAgICAgID8gZG9tSW5kZXgocHJldikgKyAxIDogMDtcbiAgICAgICAgICAgIGxldCBmcm9tID0gZGVzYy5sb2NhbFBvc0Zyb21ET00obXV0LnRhcmdldCwgZnJvbU9mZnNldCwgLTEpO1xuICAgICAgICAgICAgbGV0IHRvT2Zmc2V0ID0gbmV4dCAmJiBuZXh0LnBhcmVudE5vZGUgPT0gbXV0LnRhcmdldFxuICAgICAgICAgICAgICAgID8gZG9tSW5kZXgobmV4dCkgOiBtdXQudGFyZ2V0LmNoaWxkTm9kZXMubGVuZ3RoO1xuICAgICAgICAgICAgbGV0IHRvID0gZGVzYy5sb2NhbFBvc0Zyb21ET00obXV0LnRhcmdldCwgdG9PZmZzZXQsIDEpO1xuICAgICAgICAgICAgcmV0dXJuIHsgZnJvbSwgdG8gfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChtdXQudHlwZSA9PSBcImF0dHJpYnV0ZXNcIikge1xuICAgICAgICAgICAgcmV0dXJuIHsgZnJvbTogZGVzYy5wb3NBdFN0YXJ0IC0gZGVzYy5ib3JkZXIsIHRvOiBkZXNjLnBvc0F0RW5kICsgZGVzYy5ib3JkZXIgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHsgLy8gXCJjaGFyYWN0ZXJEYXRhXCJcbiAgICAgICAgICAgIHRoaXMubGFzdENoYW5nZWRUZXh0Tm9kZSA9IG11dC50YXJnZXQ7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGZyb206IGRlc2MucG9zQXRTdGFydCxcbiAgICAgICAgICAgICAgICB0bzogZGVzYy5wb3NBdEVuZCxcbiAgICAgICAgICAgICAgICAvLyBBbiBldmVudCB3YXMgZ2VuZXJhdGVkIGZvciBhIHRleHQgY2hhbmdlIHRoYXQgZGlkbid0IGNoYW5nZVxuICAgICAgICAgICAgICAgIC8vIGFueSB0ZXh0LiBNYXJrIHRoZSBkb20gY2hhbmdlIHRvIGZhbGwgYmFjayB0byBhc3N1bWluZyB0aGVcbiAgICAgICAgICAgICAgICAvLyBzZWxlY3Rpb24gd2FzIHR5cGVkIG92ZXIgd2l0aCBhbiBpZGVudGljYWwgdmFsdWUgaWYgaXQgY2FuJ3RcbiAgICAgICAgICAgICAgICAvLyBmaW5kIGFub3RoZXIgY2hhbmdlLlxuICAgICAgICAgICAgICAgIHR5cGVPdmVyOiBtdXQudGFyZ2V0Lm5vZGVWYWx1ZSA9PSBtdXQub2xkVmFsdWVcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG59XG5sZXQgY3NzQ2hlY2tlZCA9IG5ldyBXZWFrTWFwKCk7XG5sZXQgY3NzQ2hlY2tXYXJuZWQgPSBmYWxzZTtcbmZ1bmN0aW9uIGNoZWNrQ1NTKHZpZXcpIHtcbiAgICBpZiAoY3NzQ2hlY2tlZC5oYXModmlldykpXG4gICAgICAgIHJldHVybjtcbiAgICBjc3NDaGVja2VkLnNldCh2aWV3LCBudWxsKTtcbiAgICBpZiAoWydub3JtYWwnLCAnbm93cmFwJywgJ3ByZS1saW5lJ10uaW5kZXhPZihnZXRDb21wdXRlZFN0eWxlKHZpZXcuZG9tKS53aGl0ZVNwYWNlKSAhPT0gLTEpIHtcbiAgICAgICAgdmlldy5yZXF1aXJlc0dlY2tvSGFja05vZGUgPSBnZWNrbztcbiAgICAgICAgaWYgKGNzc0NoZWNrV2FybmVkKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjb25zb2xlW1wid2FyblwiXShcIlByb3NlTWlycm9yIGV4cGVjdHMgdGhlIENTUyB3aGl0ZS1zcGFjZSBwcm9wZXJ0eSB0byBiZSBzZXQsIHByZWZlcmFibHkgdG8gJ3ByZS13cmFwJy4gSXQgaXMgcmVjb21tZW5kZWQgdG8gbG9hZCBzdHlsZS9wcm9zZW1pcnJvci5jc3MgZnJvbSB0aGUgcHJvc2VtaXJyb3ItdmlldyBwYWNrYWdlLlwiKTtcbiAgICAgICAgY3NzQ2hlY2tXYXJuZWQgPSB0cnVlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJhbmdlVG9TZWxlY3Rpb25SYW5nZSh2aWV3LCByYW5nZSkge1xuICAgIGxldCBhbmNob3JOb2RlID0gcmFuZ2Uuc3RhcnRDb250YWluZXIsIGFuY2hvck9mZnNldCA9IHJhbmdlLnN0YXJ0T2Zmc2V0O1xuICAgIGxldCBmb2N1c05vZGUgPSByYW5nZS5lbmRDb250YWluZXIsIGZvY3VzT2Zmc2V0ID0gcmFuZ2UuZW5kT2Zmc2V0O1xuICAgIGxldCBjdXJyZW50QW5jaG9yID0gdmlldy5kb21BdFBvcyh2aWV3LnN0YXRlLnNlbGVjdGlvbi5hbmNob3IpO1xuICAgIC8vIFNpbmNlIHN1Y2ggYSByYW5nZSBkb2Vzbid0IGRpc3Rpbmd1aXNoIGJldHdlZW4gYW5jaG9yIGFuZCBoZWFkLFxuICAgIC8vIHVzZSBhIGhldXJpc3RpYyB0aGF0IGZsaXBzIGl0IGFyb3VuZCBpZiBpdHMgZW5kIG1hdGNoZXMgdGhlXG4gICAgLy8gY3VycmVudCBhbmNob3IuXG4gICAgaWYgKGlzRXF1aXZhbGVudFBvc2l0aW9uKGN1cnJlbnRBbmNob3Iubm9kZSwgY3VycmVudEFuY2hvci5vZmZzZXQsIGZvY3VzTm9kZSwgZm9jdXNPZmZzZXQpKVxuICAgICAgICBbYW5jaG9yTm9kZSwgYW5jaG9yT2Zmc2V0LCBmb2N1c05vZGUsIGZvY3VzT2Zmc2V0XSA9IFtmb2N1c05vZGUsIGZvY3VzT2Zmc2V0LCBhbmNob3JOb2RlLCBhbmNob3JPZmZzZXRdO1xuICAgIHJldHVybiB7IGFuY2hvck5vZGUsIGFuY2hvck9mZnNldCwgZm9jdXNOb2RlLCBmb2N1c09mZnNldCB9O1xufVxuLy8gVXNlZCB0byB3b3JrIGFyb3VuZCBhIFNhZmFyaSBTZWxlY3Rpb24vc2hhZG93IERPTSBidWdcbi8vIEJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9jb2RlbWlycm9yL2Rldi9pc3N1ZXMvNDE0IGZpeFxuZnVuY3Rpb24gc2FmYXJpU2hhZG93U2VsZWN0aW9uUmFuZ2Uodmlldywgc2VsZWN0aW9uKSB7XG4gICAgaWYgKHNlbGVjdGlvbi5nZXRDb21wb3NlZFJhbmdlcykge1xuICAgICAgICBsZXQgcmFuZ2UgPSBzZWxlY3Rpb24uZ2V0Q29tcG9zZWRSYW5nZXModmlldy5yb290KVswXTtcbiAgICAgICAgaWYgKHJhbmdlKVxuICAgICAgICAgICAgcmV0dXJuIHJhbmdlVG9TZWxlY3Rpb25SYW5nZSh2aWV3LCByYW5nZSk7XG4gICAgfVxuICAgIGxldCBmb3VuZDtcbiAgICBmdW5jdGlvbiByZWFkKGV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgICBmb3VuZCA9IGV2ZW50LmdldFRhcmdldFJhbmdlcygpWzBdO1xuICAgIH1cbiAgICAvLyBCZWNhdXNlIFNhZmFyaSAoYXQgbGVhc3QgaW4gMjAxOC0yMDIyKSBkb2Vzbid0IHByb3ZpZGUgcmVndWxhclxuICAgIC8vIGFjY2VzcyB0byB0aGUgc2VsZWN0aW9uIGluc2lkZSBhIHNoYWRvd1Jvb3QsIHdlIGhhdmUgdG8gcGVyZm9ybSBhXG4gICAgLy8gcmlkaWN1bG91cyBoYWNrIHRvIGdldCBhdCBpdFx1MjAxNHVzaW5nIGBleGVjQ29tbWFuZGAgdG8gdHJpZ2dlciBhXG4gICAgLy8gYGJlZm9yZUlucHV0YCBldmVudCBzbyB0aGF0IHdlIGNhbiByZWFkIHRoZSB0YXJnZXQgcmFuZ2UgZnJvbSB0aGVcbiAgICAvLyBldmVudC5cbiAgICB2aWV3LmRvbS5hZGRFdmVudExpc3RlbmVyKFwiYmVmb3JlaW5wdXRcIiwgcmVhZCwgdHJ1ZSk7XG4gICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoXCJpbmRlbnRcIik7XG4gICAgdmlldy5kb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImJlZm9yZWlucHV0XCIsIHJlYWQsIHRydWUpO1xuICAgIHJldHVybiBmb3VuZCA/IHJhbmdlVG9TZWxlY3Rpb25SYW5nZSh2aWV3LCBmb3VuZCkgOiBudWxsO1xufVxuZnVuY3Rpb24gYmxvY2tQYXJlbnQodmlldywgbm9kZSkge1xuICAgIGZvciAobGV0IHAgPSBub2RlLnBhcmVudE5vZGU7IHAgJiYgcCAhPSB2aWV3LmRvbTsgcCA9IHAucGFyZW50Tm9kZSkge1xuICAgICAgICBsZXQgZGVzYyA9IHZpZXcuZG9jVmlldy5uZWFyZXN0RGVzYyhwLCB0cnVlKTtcbiAgICAgICAgaWYgKGRlc2MgJiYgZGVzYy5ub2RlLmlzQmxvY2spXG4gICAgICAgICAgICByZXR1cm4gcDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG4vLyBLbHVkZ2UgZm9yIGEgU2FmYXJpIGJ1ZyB3aGVyZSwgb24gZW5kaW5nIGEgY29tcG9zaXRpb24gaW4gYW5cbi8vIG90aGVyd2lzZSBlbXB0eSB0YWJsZSBjZWxsLCBpdCByYW5kb21seSBtb3ZlcyB0aGUgY29tcG9zZWQgdGV4dFxuLy8gaW50byB0aGUgdGFibGUgcm93IGFyb3VuZCB0aGF0IGNlbGwsIGdyZWF0bHkgY29uZnVzaW5nIGV2ZXJ5dGhpbmdcbi8vICgjMTg4KS5cbmZ1bmN0aW9uIGZpeFVwQmFkU2FmYXJpQ29tcG9zaXRpb24odmlldywgYWRkZWROb2Rlcykge1xuICAgIHZhciBfYTtcbiAgICBsZXQgeyBmb2N1c05vZGUsIGZvY3VzT2Zmc2V0IH0gPSB2aWV3LmRvbVNlbGVjdGlvblJhbmdlKCk7XG4gICAgZm9yIChsZXQgbm9kZSBvZiBhZGRlZE5vZGVzKSB7XG4gICAgICAgIGlmICgoKF9hID0gbm9kZS5wYXJlbnROb2RlKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Eubm9kZU5hbWUpID09IFwiVFJcIikge1xuICAgICAgICAgICAgbGV0IG5leHRDZWxsID0gbm9kZS5uZXh0U2libGluZztcbiAgICAgICAgICAgIHdoaWxlIChuZXh0Q2VsbCAmJiAobmV4dENlbGwubm9kZU5hbWUgIT0gXCJURFwiICYmIG5leHRDZWxsLm5vZGVOYW1lICE9IFwiVEhcIikpXG4gICAgICAgICAgICAgICAgbmV4dENlbGwgPSBuZXh0Q2VsbC5uZXh0U2libGluZztcbiAgICAgICAgICAgIGlmIChuZXh0Q2VsbCkge1xuICAgICAgICAgICAgICAgIGxldCBwYXJlbnQgPSBuZXh0Q2VsbDtcbiAgICAgICAgICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBmaXJzdCA9IHBhcmVudC5maXJzdENoaWxkO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWZpcnN0IHx8IGZpcnN0Lm5vZGVUeXBlICE9IDEgfHwgZmlyc3QuY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgL14oQlJ8SU1HKSQvLnRlc3QoZmlyc3Qubm9kZU5hbWUpKVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IGZpcnN0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwYXJlbnQuaW5zZXJ0QmVmb3JlKG5vZGUsIHBhcmVudC5maXJzdENoaWxkKTtcbiAgICAgICAgICAgICAgICBpZiAoZm9jdXNOb2RlID09IG5vZGUpXG4gICAgICAgICAgICAgICAgICAgIHZpZXcuZG9tU2VsZWN0aW9uKCkuY29sbGFwc2Uobm9kZSwgZm9jdXNPZmZzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vLyBOb3RlIHRoYXQgYWxsIHJlZmVyZW5jaW5nIGFuZCBwYXJzaW5nIGlzIGRvbmUgd2l0aCB0aGVcbi8vIHN0YXJ0LW9mLW9wZXJhdGlvbiBzZWxlY3Rpb24gYW5kIGRvY3VtZW50LCBzaW5jZSB0aGF0J3MgdGhlIG9uZVxuLy8gdGhhdCB0aGUgRE9NIHJlcHJlc2VudHMuIElmIGFueSBjaGFuZ2VzIGNhbWUgaW4gaW4gdGhlIG1lYW50aW1lLFxuLy8gdGhlIG1vZGlmaWNhdGlvbiBpcyBtYXBwZWQgb3ZlciB0aG9zZSBiZWZvcmUgaXQgaXMgYXBwbGllZCwgaW5cbi8vIHJlYWRET01DaGFuZ2UuXG5mdW5jdGlvbiBwYXJzZUJldHdlZW4odmlldywgZnJvbV8sIHRvXykge1xuICAgIGxldCB7IG5vZGU6IHBhcmVudCwgZnJvbU9mZnNldCwgdG9PZmZzZXQsIGZyb20sIHRvIH0gPSB2aWV3LmRvY1ZpZXcucGFyc2VSYW5nZShmcm9tXywgdG9fKTtcbiAgICBsZXQgZG9tU2VsID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgIGxldCBmaW5kO1xuICAgIGxldCBhbmNob3IgPSBkb21TZWwuYW5jaG9yTm9kZTtcbiAgICBpZiAoYW5jaG9yICYmIHZpZXcuZG9tLmNvbnRhaW5zKGFuY2hvci5ub2RlVHlwZSA9PSAxID8gYW5jaG9yIDogYW5jaG9yLnBhcmVudE5vZGUpKSB7XG4gICAgICAgIGZpbmQgPSBbeyBub2RlOiBhbmNob3IsIG9mZnNldDogZG9tU2VsLmFuY2hvck9mZnNldCB9XTtcbiAgICAgICAgaWYgKCFzZWxlY3Rpb25Db2xsYXBzZWQoZG9tU2VsKSlcbiAgICAgICAgICAgIGZpbmQucHVzaCh7IG5vZGU6IGRvbVNlbC5mb2N1c05vZGUsIG9mZnNldDogZG9tU2VsLmZvY3VzT2Zmc2V0IH0pO1xuICAgIH1cbiAgICAvLyBXb3JrIGFyb3VuZCBpc3N1ZSBpbiBDaHJvbWUgd2hlcmUgYmFja3NwYWNpbmcgc29tZXRpbWVzIHJlcGxhY2VzXG4gICAgLy8gdGhlIGRlbGV0ZWQgY29udGVudCB3aXRoIGEgcmFuZG9tIEJSIG5vZGUgKGlzc3VlcyAjNzk5LCAjODMxKVxuICAgIGlmIChjaHJvbWUgJiYgdmlldy5pbnB1dC5sYXN0S2V5Q29kZSA9PT0gOCkge1xuICAgICAgICBmb3IgKGxldCBvZmYgPSB0b09mZnNldDsgb2ZmID4gZnJvbU9mZnNldDsgb2ZmLS0pIHtcbiAgICAgICAgICAgIGxldCBub2RlID0gcGFyZW50LmNoaWxkTm9kZXNbb2ZmIC0gMV0sIGRlc2MgPSBub2RlLnBtVmlld0Rlc2M7XG4gICAgICAgICAgICBpZiAobm9kZS5ub2RlTmFtZSA9PSBcIkJSXCIgJiYgIWRlc2MpIHtcbiAgICAgICAgICAgICAgICB0b09mZnNldCA9IG9mZjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghZGVzYyB8fCBkZXNjLnNpemUpXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGV0IHN0YXJ0RG9jID0gdmlldy5zdGF0ZS5kb2M7XG4gICAgbGV0IHBhcnNlciA9IHZpZXcuc29tZVByb3AoXCJkb21QYXJzZXJcIikgfHwgRE9NUGFyc2VyLmZyb21TY2hlbWEodmlldy5zdGF0ZS5zY2hlbWEpO1xuICAgIGxldCAkZnJvbSA9IHN0YXJ0RG9jLnJlc29sdmUoZnJvbSk7XG4gICAgbGV0IHNlbCA9IG51bGwsIGRvYyA9IHBhcnNlci5wYXJzZShwYXJlbnQsIHtcbiAgICAgICAgdG9wTm9kZTogJGZyb20ucGFyZW50LFxuICAgICAgICB0b3BNYXRjaDogJGZyb20ucGFyZW50LmNvbnRlbnRNYXRjaEF0KCRmcm9tLmluZGV4KCkpLFxuICAgICAgICB0b3BPcGVuOiB0cnVlLFxuICAgICAgICBmcm9tOiBmcm9tT2Zmc2V0LFxuICAgICAgICB0bzogdG9PZmZzZXQsXG4gICAgICAgIHByZXNlcnZlV2hpdGVzcGFjZTogJGZyb20ucGFyZW50LnR5cGUud2hpdGVzcGFjZSA9PSBcInByZVwiID8gXCJmdWxsXCIgOiB0cnVlLFxuICAgICAgICBmaW5kUG9zaXRpb25zOiBmaW5kLFxuICAgICAgICBydWxlRnJvbU5vZGUsXG4gICAgICAgIGNvbnRleHQ6ICRmcm9tXG4gICAgfSk7XG4gICAgaWYgKGZpbmQgJiYgZmluZFswXS5wb3MgIT0gbnVsbCkge1xuICAgICAgICBsZXQgYW5jaG9yID0gZmluZFswXS5wb3MsIGhlYWQgPSBmaW5kWzFdICYmIGZpbmRbMV0ucG9zO1xuICAgICAgICBpZiAoaGVhZCA9PSBudWxsKVxuICAgICAgICAgICAgaGVhZCA9IGFuY2hvcjtcbiAgICAgICAgc2VsID0geyBhbmNob3I6IGFuY2hvciArIGZyb20sIGhlYWQ6IGhlYWQgKyBmcm9tIH07XG4gICAgfVxuICAgIHJldHVybiB7IGRvYywgc2VsLCBmcm9tLCB0byB9O1xufVxuZnVuY3Rpb24gcnVsZUZyb21Ob2RlKGRvbSkge1xuICAgIGxldCBkZXNjID0gZG9tLnBtVmlld0Rlc2M7XG4gICAgaWYgKGRlc2MpIHtcbiAgICAgICAgcmV0dXJuIGRlc2MucGFyc2VSdWxlKCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGRvbS5ub2RlTmFtZSA9PSBcIkJSXCIgJiYgZG9tLnBhcmVudE5vZGUpIHtcbiAgICAgICAgLy8gU2FmYXJpIHJlcGxhY2VzIHRoZSBsaXN0IGl0ZW0gb3IgdGFibGUgY2VsbCB3aXRoIGEgQlJcbiAgICAgICAgLy8gZGlyZWN0bHkgaW4gdGhlIGxpc3Qgbm9kZSAoPyEpIGlmIHlvdSBkZWxldGUgdGhlIGxhc3RcbiAgICAgICAgLy8gY2hhcmFjdGVyIGluIGEgbGlzdCBpdGVtIG9yIHRhYmxlIGNlbGwgKCM3MDgsICM4NjIpXG4gICAgICAgIGlmIChzYWZhcmkgJiYgL14odWx8b2wpJC9pLnRlc3QoZG9tLnBhcmVudE5vZGUubm9kZU5hbWUpKSB7XG4gICAgICAgICAgICBsZXQgc2tpcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgICAgICBza2lwLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJsaVwiKSk7XG4gICAgICAgICAgICByZXR1cm4geyBza2lwIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZG9tLnBhcmVudE5vZGUubGFzdENoaWxkID09IGRvbSB8fCBzYWZhcmkgJiYgL14odHJ8dGFibGUpJC9pLnRlc3QoZG9tLnBhcmVudE5vZGUubm9kZU5hbWUpKSB7XG4gICAgICAgICAgICByZXR1cm4geyBpZ25vcmU6IHRydWUgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmIChkb20ubm9kZU5hbWUgPT0gXCJJTUdcIiAmJiBkb20uZ2V0QXR0cmlidXRlKFwibWFyay1wbGFjZWhvbGRlclwiKSkge1xuICAgICAgICByZXR1cm4geyBpZ25vcmU6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5jb25zdCBpc0lubGluZSA9IC9eKGF8YWJicnxhY3JvbnltfGJ8YmRbaW9dfGJpZ3xicnxidXR0b258Y2l0ZXxjb2RlfGRhdGEobGlzdCk/fGRlbHxkZm58ZW18aXxpbWd8aW5zfGtiZHxsYWJlbHxtYXB8bWFya3xtZXRlcnxvdXRwdXR8cXxydWJ5fHN8c2FtcHxzbWFsbHxzcGFufHN0cm9uZ3xzdVticF18dGltZXx1fHR0fHZhcikkL2k7XG5mdW5jdGlvbiByZWFkRE9NQ2hhbmdlKHZpZXcsIGZyb20sIHRvLCB0eXBlT3ZlciwgYWRkZWROb2Rlcykge1xuICAgIGxldCBjb21wb3NpdGlvbklEID0gdmlldy5pbnB1dC5jb21wb3NpdGlvblBlbmRpbmdDaGFuZ2VzIHx8ICh2aWV3LmNvbXBvc2luZyA/IHZpZXcuaW5wdXQuY29tcG9zaXRpb25JRCA6IDApO1xuICAgIHZpZXcuaW5wdXQuY29tcG9zaXRpb25QZW5kaW5nQ2hhbmdlcyA9IDA7XG4gICAgaWYgKGZyb20gPCAwKSB7XG4gICAgICAgIGxldCBvcmlnaW4gPSB2aWV3LmlucHV0Lmxhc3RTZWxlY3Rpb25UaW1lID4gRGF0ZS5ub3coKSAtIDUwID8gdmlldy5pbnB1dC5sYXN0U2VsZWN0aW9uT3JpZ2luIDogbnVsbDtcbiAgICAgICAgbGV0IG5ld1NlbCA9IHNlbGVjdGlvbkZyb21ET00odmlldywgb3JpZ2luKTtcbiAgICAgICAgaWYgKG5ld1NlbCAmJiAhdmlldy5zdGF0ZS5zZWxlY3Rpb24uZXEobmV3U2VsKSkge1xuICAgICAgICAgICAgaWYgKGNocm9tZSAmJiBhbmRyb2lkICYmXG4gICAgICAgICAgICAgICAgdmlldy5pbnB1dC5sYXN0S2V5Q29kZSA9PT0gMTMgJiYgRGF0ZS5ub3coKSAtIDEwMCA8IHZpZXcuaW5wdXQubGFzdEtleUNvZGVUaW1lICYmXG4gICAgICAgICAgICAgICAgdmlldy5zb21lUHJvcChcImhhbmRsZUtleURvd25cIiwgZiA9PiBmKHZpZXcsIGtleUV2ZW50KDEzLCBcIkVudGVyXCIpKSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgbGV0IHRyID0gdmlldy5zdGF0ZS50ci5zZXRTZWxlY3Rpb24obmV3U2VsKTtcbiAgICAgICAgICAgIGlmIChvcmlnaW4gPT0gXCJwb2ludGVyXCIpXG4gICAgICAgICAgICAgICAgdHIuc2V0TWV0YShcInBvaW50ZXJcIiwgdHJ1ZSk7XG4gICAgICAgICAgICBlbHNlIGlmIChvcmlnaW4gPT0gXCJrZXlcIilcbiAgICAgICAgICAgICAgICB0ci5zY3JvbGxJbnRvVmlldygpO1xuICAgICAgICAgICAgaWYgKGNvbXBvc2l0aW9uSUQpXG4gICAgICAgICAgICAgICAgdHIuc2V0TWV0YShcImNvbXBvc2l0aW9uXCIsIGNvbXBvc2l0aW9uSUQpO1xuICAgICAgICAgICAgdmlldy5kaXNwYXRjaCh0cik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgJGJlZm9yZSA9IHZpZXcuc3RhdGUuZG9jLnJlc29sdmUoZnJvbSk7XG4gICAgbGV0IHNoYXJlZCA9ICRiZWZvcmUuc2hhcmVkRGVwdGgodG8pO1xuICAgIGZyb20gPSAkYmVmb3JlLmJlZm9yZShzaGFyZWQgKyAxKTtcbiAgICB0byA9IHZpZXcuc3RhdGUuZG9jLnJlc29sdmUodG8pLmFmdGVyKHNoYXJlZCArIDEpO1xuICAgIGxldCBzZWwgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbjtcbiAgICBsZXQgcGFyc2UgPSBwYXJzZUJldHdlZW4odmlldywgZnJvbSwgdG8pO1xuICAgIGxldCBkb2MgPSB2aWV3LnN0YXRlLmRvYywgY29tcGFyZSA9IGRvYy5zbGljZShwYXJzZS5mcm9tLCBwYXJzZS50byk7XG4gICAgbGV0IHByZWZlcnJlZFBvcywgcHJlZmVycmVkU2lkZTtcbiAgICAvLyBQcmVmZXIgYW5jaG9yaW5nIHRvIGVuZCB3aGVuIEJhY2tzcGFjZSBpcyBwcmVzc2VkXG4gICAgaWYgKHZpZXcuaW5wdXQubGFzdEtleUNvZGUgPT09IDggJiYgRGF0ZS5ub3coKSAtIDEwMCA8IHZpZXcuaW5wdXQubGFzdEtleUNvZGVUaW1lKSB7XG4gICAgICAgIHByZWZlcnJlZFBvcyA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uLnRvO1xuICAgICAgICBwcmVmZXJyZWRTaWRlID0gXCJlbmRcIjtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHByZWZlcnJlZFBvcyA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uLmZyb207XG4gICAgICAgIHByZWZlcnJlZFNpZGUgPSBcInN0YXJ0XCI7XG4gICAgfVxuICAgIHZpZXcuaW5wdXQubGFzdEtleUNvZGUgPSBudWxsO1xuICAgIGxldCBjaGFuZ2UgPSBmaW5kRGlmZihjb21wYXJlLmNvbnRlbnQsIHBhcnNlLmRvYy5jb250ZW50LCBwYXJzZS5mcm9tLCBwcmVmZXJyZWRQb3MsIHByZWZlcnJlZFNpZGUpO1xuICAgIGlmIChjaGFuZ2UpXG4gICAgICAgIHZpZXcuaW5wdXQuZG9tQ2hhbmdlQ291bnQrKztcbiAgICBpZiAoKGlvcyAmJiB2aWV3LmlucHV0Lmxhc3RJT1NFbnRlciA+IERhdGUubm93KCkgLSAyMjUgfHwgYW5kcm9pZCkgJiZcbiAgICAgICAgYWRkZWROb2Rlcy5zb21lKG4gPT4gbi5ub2RlVHlwZSA9PSAxICYmICFpc0lubGluZS50ZXN0KG4ubm9kZU5hbWUpKSAmJlxuICAgICAgICAoIWNoYW5nZSB8fCBjaGFuZ2UuZW5kQSA+PSBjaGFuZ2UuZW5kQikgJiZcbiAgICAgICAgdmlldy5zb21lUHJvcChcImhhbmRsZUtleURvd25cIiwgZiA9PiBmKHZpZXcsIGtleUV2ZW50KDEzLCBcIkVudGVyXCIpKSkpIHtcbiAgICAgICAgdmlldy5pbnB1dC5sYXN0SU9TRW50ZXIgPSAwO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghY2hhbmdlKSB7XG4gICAgICAgIGlmICh0eXBlT3ZlciAmJiBzZWwgaW5zdGFuY2VvZiBUZXh0U2VsZWN0aW9uICYmICFzZWwuZW1wdHkgJiYgc2VsLiRoZWFkLnNhbWVQYXJlbnQoc2VsLiRhbmNob3IpICYmXG4gICAgICAgICAgICAhdmlldy5jb21wb3NpbmcgJiYgIShwYXJzZS5zZWwgJiYgcGFyc2Uuc2VsLmFuY2hvciAhPSBwYXJzZS5zZWwuaGVhZCkpIHtcbiAgICAgICAgICAgIGNoYW5nZSA9IHsgc3RhcnQ6IHNlbC5mcm9tLCBlbmRBOiBzZWwudG8sIGVuZEI6IHNlbC50byB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaWYgKHBhcnNlLnNlbCkge1xuICAgICAgICAgICAgICAgIGxldCBzZWwgPSByZXNvbHZlU2VsZWN0aW9uKHZpZXcsIHZpZXcuc3RhdGUuZG9jLCBwYXJzZS5zZWwpO1xuICAgICAgICAgICAgICAgIGlmIChzZWwgJiYgIXNlbC5lcSh2aWV3LnN0YXRlLnNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRyID0gdmlldy5zdGF0ZS50ci5zZXRTZWxlY3Rpb24oc2VsKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbXBvc2l0aW9uSUQpXG4gICAgICAgICAgICAgICAgICAgICAgICB0ci5zZXRNZXRhKFwiY29tcG9zaXRpb25cIiwgY29tcG9zaXRpb25JRCk7XG4gICAgICAgICAgICAgICAgICAgIHZpZXcuZGlzcGF0Y2godHIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgb3ZlcndyaXRpbmcgYSBzZWxlY3Rpb24gYnkgdHlwaW5nIG1hdGNoZXNcbiAgICAvLyB0aGUgc3RhcnQgb3IgZW5kIG9mIHRoZSBzZWxlY3RlZCBjb250ZW50LCBjcmVhdGluZyBhIGNoYW5nZVxuICAgIC8vIHRoYXQncyBzbWFsbGVyIHRoYW4gd2hhdCB3YXMgYWN0dWFsbHkgb3ZlcndyaXR0ZW4uXG4gICAgaWYgKHZpZXcuc3RhdGUuc2VsZWN0aW9uLmZyb20gPCB2aWV3LnN0YXRlLnNlbGVjdGlvbi50byAmJlxuICAgICAgICBjaGFuZ2Uuc3RhcnQgPT0gY2hhbmdlLmVuZEIgJiZcbiAgICAgICAgdmlldy5zdGF0ZS5zZWxlY3Rpb24gaW5zdGFuY2VvZiBUZXh0U2VsZWN0aW9uKSB7XG4gICAgICAgIGlmIChjaGFuZ2Uuc3RhcnQgPiB2aWV3LnN0YXRlLnNlbGVjdGlvbi5mcm9tICYmIGNoYW5nZS5zdGFydCA8PSB2aWV3LnN0YXRlLnNlbGVjdGlvbi5mcm9tICsgMiAmJlxuICAgICAgICAgICAgdmlldy5zdGF0ZS5zZWxlY3Rpb24uZnJvbSA+PSBwYXJzZS5mcm9tKSB7XG4gICAgICAgICAgICBjaGFuZ2Uuc3RhcnQgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbi5mcm9tO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNoYW5nZS5lbmRBIDwgdmlldy5zdGF0ZS5zZWxlY3Rpb24udG8gJiYgY2hhbmdlLmVuZEEgPj0gdmlldy5zdGF0ZS5zZWxlY3Rpb24udG8gLSAyICYmXG4gICAgICAgICAgICB2aWV3LnN0YXRlLnNlbGVjdGlvbi50byA8PSBwYXJzZS50bykge1xuICAgICAgICAgICAgY2hhbmdlLmVuZEIgKz0gKHZpZXcuc3RhdGUuc2VsZWN0aW9uLnRvIC0gY2hhbmdlLmVuZEEpO1xuICAgICAgICAgICAgY2hhbmdlLmVuZEEgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbi50bztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBJRTExIHdpbGwgaW5zZXJ0IGEgbm9uLWJyZWFraW5nIHNwYWNlIF9haGVhZF8gb2YgdGhlIHNwYWNlIGFmdGVyXG4gICAgLy8gdGhlIGN1cnNvciBzcGFjZSB3aGVuIGFkZGluZyBhIHNwYWNlIGJlZm9yZSBhbm90aGVyIHNwYWNlLiBXaGVuXG4gICAgLy8gdGhhdCBoYXBwZW5lZCwgYWRqdXN0IHRoZSBjaGFuZ2UgdG8gY292ZXIgdGhlIHNwYWNlIGluc3RlYWQuXG4gICAgaWYgKGllICYmIGllX3ZlcnNpb24gPD0gMTEgJiYgY2hhbmdlLmVuZEIgPT0gY2hhbmdlLnN0YXJ0ICsgMSAmJlxuICAgICAgICBjaGFuZ2UuZW5kQSA9PSBjaGFuZ2Uuc3RhcnQgJiYgY2hhbmdlLnN0YXJ0ID4gcGFyc2UuZnJvbSAmJlxuICAgICAgICBwYXJzZS5kb2MudGV4dEJldHdlZW4oY2hhbmdlLnN0YXJ0IC0gcGFyc2UuZnJvbSAtIDEsIGNoYW5nZS5zdGFydCAtIHBhcnNlLmZyb20gKyAxKSA9PSBcIiBcXHUwMGEwXCIpIHtcbiAgICAgICAgY2hhbmdlLnN0YXJ0LS07XG4gICAgICAgIGNoYW5nZS5lbmRBLS07XG4gICAgICAgIGNoYW5nZS5lbmRCLS07XG4gICAgfVxuICAgIGxldCAkZnJvbSA9IHBhcnNlLmRvYy5yZXNvbHZlTm9DYWNoZShjaGFuZ2Uuc3RhcnQgLSBwYXJzZS5mcm9tKTtcbiAgICBsZXQgJHRvID0gcGFyc2UuZG9jLnJlc29sdmVOb0NhY2hlKGNoYW5nZS5lbmRCIC0gcGFyc2UuZnJvbSk7XG4gICAgbGV0ICRmcm9tQSA9IGRvYy5yZXNvbHZlKGNoYW5nZS5zdGFydCk7XG4gICAgbGV0IGlubGluZUNoYW5nZSA9ICRmcm9tLnNhbWVQYXJlbnQoJHRvKSAmJiAkZnJvbS5wYXJlbnQuaW5saW5lQ29udGVudCAmJiAkZnJvbUEuZW5kKCkgPj0gY2hhbmdlLmVuZEE7XG4gICAgLy8gSWYgdGhpcyBsb29rcyBsaWtlIHRoZSBlZmZlY3Qgb2YgcHJlc3NpbmcgRW50ZXIgKG9yIHdhcyByZWNvcmRlZFxuICAgIC8vIGFzIGJlaW5nIGFuIGlPUyBlbnRlciBwcmVzcyksIGp1c3QgZGlzcGF0Y2ggYW4gRW50ZXIga2V5IGluc3RlYWQuXG4gICAgaWYgKCgoaW9zICYmIHZpZXcuaW5wdXQubGFzdElPU0VudGVyID4gRGF0ZS5ub3coKSAtIDIyNSAmJlxuICAgICAgICAoIWlubGluZUNoYW5nZSB8fCBhZGRlZE5vZGVzLnNvbWUobiA9PiBuLm5vZGVOYW1lID09IFwiRElWXCIgfHwgbi5ub2RlTmFtZSA9PSBcIlBcIikpKSB8fFxuICAgICAgICAoIWlubGluZUNoYW5nZSAmJiAkZnJvbS5wb3MgPCBwYXJzZS5kb2MuY29udGVudC5zaXplICYmXG4gICAgICAgICAgICAoISRmcm9tLnNhbWVQYXJlbnQoJHRvKSB8fCAhJGZyb20ucGFyZW50LmlubGluZUNvbnRlbnQpICYmXG4gICAgICAgICAgICAkZnJvbS5wb3MgPCAkdG8ucG9zICYmICEvXFxTLy50ZXN0KHBhcnNlLmRvYy50ZXh0QmV0d2VlbigkZnJvbS5wb3MsICR0by5wb3MsIFwiXCIsIFwiXCIpKSkpICYmXG4gICAgICAgIHZpZXcuc29tZVByb3AoXCJoYW5kbGVLZXlEb3duXCIsIGYgPT4gZih2aWV3LCBrZXlFdmVudCgxMywgXCJFbnRlclwiKSkpKSB7XG4gICAgICAgIHZpZXcuaW5wdXQubGFzdElPU0VudGVyID0gMDtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBTYW1lIGZvciBiYWNrc3BhY2VcbiAgICBpZiAodmlldy5zdGF0ZS5zZWxlY3Rpb24uYW5jaG9yID4gY2hhbmdlLnN0YXJ0ICYmXG4gICAgICAgIGxvb2tzTGlrZUJhY2tzcGFjZShkb2MsIGNoYW5nZS5zdGFydCwgY2hhbmdlLmVuZEEsICRmcm9tLCAkdG8pICYmXG4gICAgICAgIHZpZXcuc29tZVByb3AoXCJoYW5kbGVLZXlEb3duXCIsIGYgPT4gZih2aWV3LCBrZXlFdmVudCg4LCBcIkJhY2tzcGFjZVwiKSkpKSB7XG4gICAgICAgIGlmIChhbmRyb2lkICYmIGNocm9tZSlcbiAgICAgICAgICAgIHZpZXcuZG9tT2JzZXJ2ZXIuc3VwcHJlc3NTZWxlY3Rpb25VcGRhdGVzKCk7IC8vICM4MjBcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBDaHJvbWUgd2lsbCBvY2Nhc2lvbmFsbHksIGR1cmluZyBjb21wb3NpdGlvbiwgZGVsZXRlIHRoZVxuICAgIC8vIGVudGlyZSBjb21wb3NpdGlvbiBhbmQgdGhlbiBpbW1lZGlhdGVseSBpbnNlcnQgaXQgYWdhaW4uIFRoaXMgaXNcbiAgICAvLyB1c2VkIHRvIGRldGVjdCB0aGF0IHNpdHVhdGlvbi5cbiAgICBpZiAoY2hyb21lICYmIGNoYW5nZS5lbmRCID09IGNoYW5nZS5zdGFydClcbiAgICAgICAgdmlldy5pbnB1dC5sYXN0Q2hyb21lRGVsZXRlID0gRGF0ZS5ub3coKTtcbiAgICAvLyBUaGlzIHRyaWVzIHRvIGRldGVjdCBBbmRyb2lkIHZpcnR1YWwga2V5Ym9hcmRcbiAgICAvLyBlbnRlci1hbmQtcGljay1zdWdnZXN0aW9uIGFjdGlvbi4gVGhhdCBzb21ldGltZXMgKHNlZSBpc3N1ZVxuICAgIC8vICMxMDU5KSBmaXJzdCBmaXJlcyBhIERPTSBtdXRhdGlvbiwgYmVmb3JlIG1vdmluZyB0aGUgc2VsZWN0aW9uIHRvXG4gICAgLy8gdGhlIG5ld2x5IGNyZWF0ZWQgYmxvY2suIEFuZCB0aGVuLCBiZWNhdXNlIFByb3NlTWlycm9yIGNsZWFucyB1cFxuICAgIC8vIHRoZSBET00gc2VsZWN0aW9uLCBpdCBnaXZlcyB1cCBtb3ZpbmcgdGhlIHNlbGVjdGlvbiBlbnRpcmVseSxcbiAgICAvLyBsZWF2aW5nIHRoZSBjdXJzb3IgaW4gdGhlIHdyb25nIHBsYWNlLiBXaGVuIHRoYXQgaGFwcGVucywgd2UgZHJvcFxuICAgIC8vIHRoZSBuZXcgcGFyYWdyYXBoIGZyb20gdGhlIGluaXRpYWwgY2hhbmdlLCBhbmQgZmlyZSBhIHNpbXVsYXRlZFxuICAgIC8vIGVudGVyIGtleSBhZnRlcndhcmRzLlxuICAgIGlmIChhbmRyb2lkICYmICFpbmxpbmVDaGFuZ2UgJiYgJGZyb20uc3RhcnQoKSAhPSAkdG8uc3RhcnQoKSAmJiAkdG8ucGFyZW50T2Zmc2V0ID09IDAgJiYgJGZyb20uZGVwdGggPT0gJHRvLmRlcHRoICYmXG4gICAgICAgIHBhcnNlLnNlbCAmJiBwYXJzZS5zZWwuYW5jaG9yID09IHBhcnNlLnNlbC5oZWFkICYmIHBhcnNlLnNlbC5oZWFkID09IGNoYW5nZS5lbmRBKSB7XG4gICAgICAgIGNoYW5nZS5lbmRCIC09IDI7XG4gICAgICAgICR0byA9IHBhcnNlLmRvYy5yZXNvbHZlTm9DYWNoZShjaGFuZ2UuZW5kQiAtIHBhcnNlLmZyb20pO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHZpZXcuc29tZVByb3AoXCJoYW5kbGVLZXlEb3duXCIsIGZ1bmN0aW9uIChmKSB7IHJldHVybiBmKHZpZXcsIGtleUV2ZW50KDEzLCBcIkVudGVyXCIpKTsgfSk7XG4gICAgICAgIH0sIDIwKTtcbiAgICB9XG4gICAgbGV0IGNoRnJvbSA9IGNoYW5nZS5zdGFydCwgY2hUbyA9IGNoYW5nZS5lbmRBO1xuICAgIGxldCBta1RyID0gKGJhc2UpID0+IHtcbiAgICAgICAgbGV0IHRyID0gYmFzZSB8fCB2aWV3LnN0YXRlLnRyLnJlcGxhY2UoY2hGcm9tLCBjaFRvLCBwYXJzZS5kb2Muc2xpY2UoY2hhbmdlLnN0YXJ0IC0gcGFyc2UuZnJvbSwgY2hhbmdlLmVuZEIgLSBwYXJzZS5mcm9tKSk7XG4gICAgICAgIGlmIChwYXJzZS5zZWwpIHtcbiAgICAgICAgICAgIGxldCBzZWwgPSByZXNvbHZlU2VsZWN0aW9uKHZpZXcsIHRyLmRvYywgcGFyc2Uuc2VsKTtcbiAgICAgICAgICAgIC8vIENocm9tZSB3aWxsIHNvbWV0aW1lcywgZHVyaW5nIGNvbXBvc2l0aW9uLCByZXBvcnQgdGhlXG4gICAgICAgICAgICAvLyBzZWxlY3Rpb24gaW4gdGhlIHdyb25nIHBsYWNlLiBJZiBpdCBsb29rcyBsaWtlIHRoYXQgaXNcbiAgICAgICAgICAgIC8vIGhhcHBlbmluZywgZG9uJ3QgdXBkYXRlIHRoZSBzZWxlY3Rpb24uXG4gICAgICAgICAgICAvLyBFZGdlIGp1c3QgZG9lc24ndCBtb3ZlIHRoZSBjdXJzb3IgZm9yd2FyZCB3aGVuIHlvdSBzdGFydCB0eXBpbmdcbiAgICAgICAgICAgIC8vIGluIGFuIGVtcHR5IGJsb2NrIG9yIGJldHdlZW4gYnIgbm9kZXMuXG4gICAgICAgICAgICBpZiAoc2VsICYmICEoY2hyb21lICYmIHZpZXcuY29tcG9zaW5nICYmIHNlbC5lbXB0eSAmJlxuICAgICAgICAgICAgICAgIChjaGFuZ2Uuc3RhcnQgIT0gY2hhbmdlLmVuZEIgfHwgdmlldy5pbnB1dC5sYXN0Q2hyb21lRGVsZXRlIDwgRGF0ZS5ub3coKSAtIDEwMCkgJiZcbiAgICAgICAgICAgICAgICAoc2VsLmhlYWQgPT0gY2hGcm9tIHx8IHNlbC5oZWFkID09IHRyLm1hcHBpbmcubWFwKGNoVG8pIC0gMSkgfHxcbiAgICAgICAgICAgICAgICBpZSAmJiBzZWwuZW1wdHkgJiYgc2VsLmhlYWQgPT0gY2hGcm9tKSlcbiAgICAgICAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24oc2VsKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29tcG9zaXRpb25JRClcbiAgICAgICAgICAgIHRyLnNldE1ldGEoXCJjb21wb3NpdGlvblwiLCBjb21wb3NpdGlvbklEKTtcbiAgICAgICAgcmV0dXJuIHRyLnNjcm9sbEludG9WaWV3KCk7XG4gICAgfTtcbiAgICBsZXQgbWFya0NoYW5nZTtcbiAgICBpZiAoaW5saW5lQ2hhbmdlKSB7XG4gICAgICAgIGlmICgkZnJvbS5wb3MgPT0gJHRvLnBvcykgeyAvLyBEZWxldGlvblxuICAgICAgICAgICAgLy8gSUUxMSBzb21ldGltZXMgd2VpcmRseSBtb3ZlcyB0aGUgRE9NIHNlbGVjdGlvbiBhcm91bmQgYWZ0ZXJcbiAgICAgICAgICAgIC8vIGJhY2tzcGFjaW5nIG91dCB0aGUgZmlyc3QgZWxlbWVudCBpbiBhIHRleHRibG9ja1xuICAgICAgICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPD0gMTEgJiYgJGZyb20ucGFyZW50T2Zmc2V0ID09IDApIHtcbiAgICAgICAgICAgICAgICB2aWV3LmRvbU9ic2VydmVyLnN1cHByZXNzU2VsZWN0aW9uVXBkYXRlcygpO1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gc2VsZWN0aW9uVG9ET00odmlldyksIDIwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCB0ciA9IG1rVHIodmlldy5zdGF0ZS50ci5kZWxldGUoY2hGcm9tLCBjaFRvKSk7XG4gICAgICAgICAgICBsZXQgbWFya3MgPSBkb2MucmVzb2x2ZShjaGFuZ2Uuc3RhcnQpLm1hcmtzQWNyb3NzKGRvYy5yZXNvbHZlKGNoYW5nZS5lbmRBKSk7XG4gICAgICAgICAgICBpZiAobWFya3MpXG4gICAgICAgICAgICAgICAgdHIuZW5zdXJlTWFya3MobWFya3MpO1xuICAgICAgICAgICAgdmlldy5kaXNwYXRjaCh0cik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIC8vIEFkZGluZyBvciByZW1vdmluZyBhIG1hcmtcbiAgICAgICAgY2hhbmdlLmVuZEEgPT0gY2hhbmdlLmVuZEIgJiZcbiAgICAgICAgICAgIChtYXJrQ2hhbmdlID0gaXNNYXJrQ2hhbmdlKCRmcm9tLnBhcmVudC5jb250ZW50LmN1dCgkZnJvbS5wYXJlbnRPZmZzZXQsICR0by5wYXJlbnRPZmZzZXQpLCAkZnJvbUEucGFyZW50LmNvbnRlbnQuY3V0KCRmcm9tQS5wYXJlbnRPZmZzZXQsIGNoYW5nZS5lbmRBIC0gJGZyb21BLnN0YXJ0KCkpKSkpIHtcbiAgICAgICAgICAgIGxldCB0ciA9IG1rVHIodmlldy5zdGF0ZS50cik7XG4gICAgICAgICAgICBpZiAobWFya0NoYW5nZS50eXBlID09IFwiYWRkXCIpXG4gICAgICAgICAgICAgICAgdHIuYWRkTWFyayhjaEZyb20sIGNoVG8sIG1hcmtDaGFuZ2UubWFyayk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdHIucmVtb3ZlTWFyayhjaEZyb20sIGNoVG8sIG1hcmtDaGFuZ2UubWFyayk7XG4gICAgICAgICAgICB2aWV3LmRpc3BhdGNoKHRyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICgkZnJvbS5wYXJlbnQuY2hpbGQoJGZyb20uaW5kZXgoKSkuaXNUZXh0ICYmICRmcm9tLmluZGV4KCkgPT0gJHRvLmluZGV4KCkgLSAoJHRvLnRleHRPZmZzZXQgPyAwIDogMSkpIHtcbiAgICAgICAgICAgIC8vIEJvdGggcG9zaXRpb25zIGluIHRoZSBzYW1lIHRleHQgbm9kZSAtLSBzaW1wbHkgaW5zZXJ0IHRleHRcbiAgICAgICAgICAgIGxldCB0ZXh0ID0gJGZyb20ucGFyZW50LnRleHRCZXR3ZWVuKCRmcm9tLnBhcmVudE9mZnNldCwgJHRvLnBhcmVudE9mZnNldCk7XG4gICAgICAgICAgICBsZXQgZGVmbHQgPSAoKSA9PiBta1RyKHZpZXcuc3RhdGUudHIuaW5zZXJ0VGV4dCh0ZXh0LCBjaEZyb20sIGNoVG8pKTtcbiAgICAgICAgICAgIGlmICghdmlldy5zb21lUHJvcChcImhhbmRsZVRleHRJbnB1dFwiLCBmID0+IGYodmlldywgY2hGcm9tLCBjaFRvLCB0ZXh0LCBkZWZsdCkpKVxuICAgICAgICAgICAgICAgIHZpZXcuZGlzcGF0Y2goZGVmbHQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2aWV3LmRpc3BhdGNoKG1rVHIoKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHZpZXcuZGlzcGF0Y2gobWtUcigpKTtcbiAgICB9XG59XG5mdW5jdGlvbiByZXNvbHZlU2VsZWN0aW9uKHZpZXcsIGRvYywgcGFyc2VkU2VsKSB7XG4gICAgaWYgKE1hdGgubWF4KHBhcnNlZFNlbC5hbmNob3IsIHBhcnNlZFNlbC5oZWFkKSA+IGRvYy5jb250ZW50LnNpemUpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIHJldHVybiBzZWxlY3Rpb25CZXR3ZWVuKHZpZXcsIGRvYy5yZXNvbHZlKHBhcnNlZFNlbC5hbmNob3IpLCBkb2MucmVzb2x2ZShwYXJzZWRTZWwuaGVhZCkpO1xufVxuLy8gR2l2ZW4gdHdvIHNhbWUtbGVuZ3RoLCBub24tZW1wdHkgZnJhZ21lbnRzIG9mIGlubGluZSBjb250ZW50LFxuLy8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGZpcnN0IGNvdWxkIGJlIGNyZWF0ZWQgZnJvbSB0aGUgc2Vjb25kIGJ5XG4vLyByZW1vdmluZyBvciBhZGRpbmcgYSBzaW5nbGUgbWFyayB0eXBlLlxuZnVuY3Rpb24gaXNNYXJrQ2hhbmdlKGN1ciwgcHJldikge1xuICAgIGxldCBjdXJNYXJrcyA9IGN1ci5maXJzdENoaWxkLm1hcmtzLCBwcmV2TWFya3MgPSBwcmV2LmZpcnN0Q2hpbGQubWFya3M7XG4gICAgbGV0IGFkZGVkID0gY3VyTWFya3MsIHJlbW92ZWQgPSBwcmV2TWFya3MsIHR5cGUsIG1hcmssIHVwZGF0ZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXZNYXJrcy5sZW5ndGg7IGkrKylcbiAgICAgICAgYWRkZWQgPSBwcmV2TWFya3NbaV0ucmVtb3ZlRnJvbVNldChhZGRlZCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjdXJNYXJrcy5sZW5ndGg7IGkrKylcbiAgICAgICAgcmVtb3ZlZCA9IGN1ck1hcmtzW2ldLnJlbW92ZUZyb21TZXQocmVtb3ZlZCk7XG4gICAgaWYgKGFkZGVkLmxlbmd0aCA9PSAxICYmIHJlbW92ZWQubGVuZ3RoID09IDApIHtcbiAgICAgICAgbWFyayA9IGFkZGVkWzBdO1xuICAgICAgICB0eXBlID0gXCJhZGRcIjtcbiAgICAgICAgdXBkYXRlID0gKG5vZGUpID0+IG5vZGUubWFyayhtYXJrLmFkZFRvU2V0KG5vZGUubWFya3MpKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoYWRkZWQubGVuZ3RoID09IDAgJiYgcmVtb3ZlZC5sZW5ndGggPT0gMSkge1xuICAgICAgICBtYXJrID0gcmVtb3ZlZFswXTtcbiAgICAgICAgdHlwZSA9IFwicmVtb3ZlXCI7XG4gICAgICAgIHVwZGF0ZSA9IChub2RlKSA9PiBub2RlLm1hcmsobWFyay5yZW1vdmVGcm9tU2V0KG5vZGUubWFya3MpKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBsZXQgdXBkYXRlZCA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHJldi5jaGlsZENvdW50OyBpKyspXG4gICAgICAgIHVwZGF0ZWQucHVzaCh1cGRhdGUocHJldi5jaGlsZChpKSkpO1xuICAgIGlmIChGcmFnbWVudC5mcm9tKHVwZGF0ZWQpLmVxKGN1cikpXG4gICAgICAgIHJldHVybiB7IG1hcmssIHR5cGUgfTtcbn1cbmZ1bmN0aW9uIGxvb2tzTGlrZUJhY2tzcGFjZShvbGQsIHN0YXJ0LCBlbmQsICRuZXdTdGFydCwgJG5ld0VuZCkge1xuICAgIGlmICggLy8gVGhlIGNvbnRlbnQgbXVzdCBoYXZlIHNocnVua1xuICAgIGVuZCAtIHN0YXJ0IDw9ICRuZXdFbmQucG9zIC0gJG5ld1N0YXJ0LnBvcyB8fFxuICAgICAgICAvLyBuZXdFbmQgbXVzdCBwb2ludCBkaXJlY3RseSBhdCBvciBhZnRlciB0aGUgZW5kIG9mIHRoZSBibG9jayB0aGF0IG5ld1N0YXJ0IHBvaW50cyBpbnRvXG4gICAgICAgIHNraXBDbG9zaW5nQW5kT3BlbmluZygkbmV3U3RhcnQsIHRydWUsIGZhbHNlKSA8ICRuZXdFbmQucG9zKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0ICRzdGFydCA9IG9sZC5yZXNvbHZlKHN0YXJ0KTtcbiAgICAvLyBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUsIHJhdGhlciB0aGFuIGpvaW5pbmcgYmxvY2tzLCB0aGUgY2hhbmdlIGp1c3QgcmVtb3ZlZCBhbiBlbnRpcmUgYmxvY2tcbiAgICBpZiAoISRuZXdTdGFydC5wYXJlbnQuaXNUZXh0YmxvY2spIHtcbiAgICAgICAgbGV0IGFmdGVyID0gJHN0YXJ0Lm5vZGVBZnRlcjtcbiAgICAgICAgcmV0dXJuIGFmdGVyICE9IG51bGwgJiYgZW5kID09IHN0YXJ0ICsgYWZ0ZXIubm9kZVNpemU7XG4gICAgfVxuICAgIC8vIFN0YXJ0IG11c3QgYmUgYXQgdGhlIGVuZCBvZiBhIGJsb2NrXG4gICAgaWYgKCRzdGFydC5wYXJlbnRPZmZzZXQgPCAkc3RhcnQucGFyZW50LmNvbnRlbnQuc2l6ZSB8fCAhJHN0YXJ0LnBhcmVudC5pc1RleHRibG9jaylcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCAkbmV4dCA9IG9sZC5yZXNvbHZlKHNraXBDbG9zaW5nQW5kT3BlbmluZygkc3RhcnQsIHRydWUsIHRydWUpKTtcbiAgICAvLyBUaGUgbmV4dCB0ZXh0YmxvY2sgbXVzdCBzdGFydCBiZWZvcmUgZW5kIGFuZCBlbmQgbmVhciBpdFxuICAgIGlmICghJG5leHQucGFyZW50LmlzVGV4dGJsb2NrIHx8ICRuZXh0LnBvcyA+IGVuZCB8fFxuICAgICAgICBza2lwQ2xvc2luZ0FuZE9wZW5pbmcoJG5leHQsIHRydWUsIGZhbHNlKSA8IGVuZClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIC8vIFRoZSBmcmFnbWVudHMgYWZ0ZXIgdGhlIGpvaW4gcG9pbnQgbXVzdCBtYXRjaFxuICAgIHJldHVybiAkbmV3U3RhcnQucGFyZW50LmNvbnRlbnQuY3V0KCRuZXdTdGFydC5wYXJlbnRPZmZzZXQpLmVxKCRuZXh0LnBhcmVudC5jb250ZW50KTtcbn1cbmZ1bmN0aW9uIHNraXBDbG9zaW5nQW5kT3BlbmluZygkcG9zLCBmcm9tRW5kLCBtYXlPcGVuKSB7XG4gICAgbGV0IGRlcHRoID0gJHBvcy5kZXB0aCwgZW5kID0gZnJvbUVuZCA/ICRwb3MuZW5kKCkgOiAkcG9zLnBvcztcbiAgICB3aGlsZSAoZGVwdGggPiAwICYmIChmcm9tRW5kIHx8ICRwb3MuaW5kZXhBZnRlcihkZXB0aCkgPT0gJHBvcy5ub2RlKGRlcHRoKS5jaGlsZENvdW50KSkge1xuICAgICAgICBkZXB0aC0tO1xuICAgICAgICBlbmQrKztcbiAgICAgICAgZnJvbUVuZCA9IGZhbHNlO1xuICAgIH1cbiAgICBpZiAobWF5T3Blbikge1xuICAgICAgICBsZXQgbmV4dCA9ICRwb3Mubm9kZShkZXB0aCkubWF5YmVDaGlsZCgkcG9zLmluZGV4QWZ0ZXIoZGVwdGgpKTtcbiAgICAgICAgd2hpbGUgKG5leHQgJiYgIW5leHQuaXNMZWFmKSB7XG4gICAgICAgICAgICBuZXh0ID0gbmV4dC5maXJzdENoaWxkO1xuICAgICAgICAgICAgZW5kKys7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGVuZDtcbn1cbmZ1bmN0aW9uIGZpbmREaWZmKGEsIGIsIHBvcywgcHJlZmVycmVkUG9zLCBwcmVmZXJyZWRTaWRlKSB7XG4gICAgbGV0IHN0YXJ0ID0gYS5maW5kRGlmZlN0YXJ0KGIsIHBvcyk7XG4gICAgaWYgKHN0YXJ0ID09IG51bGwpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGxldCB7IGE6IGVuZEEsIGI6IGVuZEIgfSA9IGEuZmluZERpZmZFbmQoYiwgcG9zICsgYS5zaXplLCBwb3MgKyBiLnNpemUpO1xuICAgIGlmIChwcmVmZXJyZWRTaWRlID09IFwiZW5kXCIpIHtcbiAgICAgICAgbGV0IGFkanVzdCA9IE1hdGgubWF4KDAsIHN0YXJ0IC0gTWF0aC5taW4oZW5kQSwgZW5kQikpO1xuICAgICAgICBwcmVmZXJyZWRQb3MgLT0gZW5kQSArIGFkanVzdCAtIHN0YXJ0O1xuICAgIH1cbiAgICBpZiAoZW5kQSA8IHN0YXJ0ICYmIGEuc2l6ZSA8IGIuc2l6ZSkge1xuICAgICAgICBsZXQgbW92ZSA9IHByZWZlcnJlZFBvcyA8PSBzdGFydCAmJiBwcmVmZXJyZWRQb3MgPj0gZW5kQSA/IHN0YXJ0IC0gcHJlZmVycmVkUG9zIDogMDtcbiAgICAgICAgc3RhcnQgLT0gbW92ZTtcbiAgICAgICAgaWYgKHN0YXJ0ICYmIHN0YXJ0IDwgYi5zaXplICYmIGlzU3Vycm9nYXRlUGFpcihiLnRleHRCZXR3ZWVuKHN0YXJ0IC0gMSwgc3RhcnQgKyAxKSkpXG4gICAgICAgICAgICBzdGFydCArPSBtb3ZlID8gMSA6IC0xO1xuICAgICAgICBlbmRCID0gc3RhcnQgKyAoZW5kQiAtIGVuZEEpO1xuICAgICAgICBlbmRBID0gc3RhcnQ7XG4gICAgfVxuICAgIGVsc2UgaWYgKGVuZEIgPCBzdGFydCkge1xuICAgICAgICBsZXQgbW92ZSA9IHByZWZlcnJlZFBvcyA8PSBzdGFydCAmJiBwcmVmZXJyZWRQb3MgPj0gZW5kQiA/IHN0YXJ0IC0gcHJlZmVycmVkUG9zIDogMDtcbiAgICAgICAgc3RhcnQgLT0gbW92ZTtcbiAgICAgICAgaWYgKHN0YXJ0ICYmIHN0YXJ0IDwgYS5zaXplICYmIGlzU3Vycm9nYXRlUGFpcihhLnRleHRCZXR3ZWVuKHN0YXJ0IC0gMSwgc3RhcnQgKyAxKSkpXG4gICAgICAgICAgICBzdGFydCArPSBtb3ZlID8gMSA6IC0xO1xuICAgICAgICBlbmRBID0gc3RhcnQgKyAoZW5kQSAtIGVuZEIpO1xuICAgICAgICBlbmRCID0gc3RhcnQ7XG4gICAgfVxuICAgIHJldHVybiB7IHN0YXJ0LCBlbmRBLCBlbmRCIH07XG59XG5mdW5jdGlvbiBpc1N1cnJvZ2F0ZVBhaXIoc3RyKSB7XG4gICAgaWYgKHN0ci5sZW5ndGggIT0gMilcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCBhID0gc3RyLmNoYXJDb2RlQXQoMCksIGIgPSBzdHIuY2hhckNvZGVBdCgxKTtcbiAgICByZXR1cm4gYSA+PSAweERDMDAgJiYgYSA8PSAweERGRkYgJiYgYiA+PSAweEQ4MDAgJiYgYiA8PSAweERCRkY7XG59XG5cbi8qKlxuQGludGVybmFsXG4qL1xuY29uc3QgX19wYXJzZUZyb21DbGlwYm9hcmQgPSBwYXJzZUZyb21DbGlwYm9hcmQ7XG4vKipcbkBpbnRlcm5hbFxuKi9cbmNvbnN0IF9fZW5kQ29tcG9zaXRpb24gPSBlbmRDb21wb3NpdGlvbjtcbi8qKlxuQW4gZWRpdG9yIHZpZXcgbWFuYWdlcyB0aGUgRE9NIHN0cnVjdHVyZSB0aGF0IHJlcHJlc2VudHMgYW5cbmVkaXRhYmxlIGRvY3VtZW50LiBJdHMgc3RhdGUgYW5kIGJlaGF2aW9yIGFyZSBkZXRlcm1pbmVkIGJ5IGl0c1xuW3Byb3BzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdmlldy5EaXJlY3RFZGl0b3JQcm9wcykuXG4qL1xuY2xhc3MgRWRpdG9yVmlldyB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgdmlldy4gYHBsYWNlYCBtYXkgYmUgYSBET00gbm9kZSB0aGF0IHRoZSBlZGl0b3Igc2hvdWxkXG4gICAgYmUgYXBwZW5kZWQgdG8sIGEgZnVuY3Rpb24gdGhhdCB3aWxsIHBsYWNlIGl0IGludG8gdGhlIGRvY3VtZW50LFxuICAgIG9yIGFuIG9iamVjdCB3aG9zZSBgbW91bnRgIHByb3BlcnR5IGhvbGRzIHRoZSBub2RlIHRvIHVzZSBhcyB0aGVcbiAgICBkb2N1bWVudCBjb250YWluZXIuIElmIGl0IGlzIGBudWxsYCwgdGhlIGVkaXRvciB3aWxsIG5vdCBiZVxuICAgIGFkZGVkIHRvIHRoZSBkb2N1bWVudC5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHBsYWNlLCBwcm9wcykge1xuICAgICAgICB0aGlzLl9yb290ID0gbnVsbDtcbiAgICAgICAgLyoqXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLmZvY3VzZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgIEtsdWRnZSB1c2VkIHRvIHdvcmsgYXJvdW5kIGEgQ2hyb21lIGJ1ZyBAaW50ZXJuYWxcbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy50cmFja1dyaXRlcyA9IG51bGw7XG4gICAgICAgIHRoaXMubW91bnRlZCA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgQGludGVybmFsXG4gICAgICAgICovXG4gICAgICAgIHRoaXMubWFya0N1cnNvciA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICBAaW50ZXJuYWxcbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5jdXJzb3JXcmFwcGVyID0gbnVsbDtcbiAgICAgICAgLyoqXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLmxhc3RTZWxlY3RlZFZpZXdEZXNjID0gdW5kZWZpbmVkO1xuICAgICAgICAvKipcbiAgICAgICAgQGludGVybmFsXG4gICAgICAgICovXG4gICAgICAgIHRoaXMuaW5wdXQgPSBuZXcgSW5wdXRTdGF0ZTtcbiAgICAgICAgdGhpcy5wcmV2RGlyZWN0UGx1Z2lucyA9IFtdO1xuICAgICAgICB0aGlzLnBsdWdpblZpZXdzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICBIb2xkcyBgdHJ1ZWAgd2hlbiBhIGhhY2sgbm9kZSBpcyBuZWVkZWQgaW4gRmlyZWZveCB0byBwcmV2ZW50IHRoZVxuICAgICAgICBbc3BhY2UgaXMgZWF0ZW4gaXNzdWVdKGh0dHBzOi8vY29kZS5oYXZlcmJla2UuYmVybGluL3Byb3NlbWlycm9yL3Byb3NlbWlycm9yL2lzc3Vlcy82NTEpXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLnJlcXVpcmVzR2Vja29IYWNrTm9kZSA9IGZhbHNlO1xuICAgICAgICAvKipcbiAgICAgICAgV2hlbiBlZGl0b3IgY29udGVudCBpcyBiZWluZyBkcmFnZ2VkLCB0aGlzIG9iamVjdCBjb250YWluc1xuICAgICAgICBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZHJhZ2dlZCBzbGljZSBhbmQgd2hldGhlciBpdCBpcyBiZWluZ1xuICAgICAgICBjb3BpZWQgb3IgbW92ZWQuIEF0IGFueSBvdGhlciB0aW1lLCBpdCBpcyBudWxsLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLmRyYWdnaW5nID0gbnVsbDtcbiAgICAgICAgdGhpcy5fcHJvcHMgPSBwcm9wcztcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHByb3BzLnN0YXRlO1xuICAgICAgICB0aGlzLmRpcmVjdFBsdWdpbnMgPSBwcm9wcy5wbHVnaW5zIHx8IFtdO1xuICAgICAgICB0aGlzLmRpcmVjdFBsdWdpbnMuZm9yRWFjaChjaGVja1N0YXRlQ29tcG9uZW50KTtcbiAgICAgICAgdGhpcy5kaXNwYXRjaCA9IHRoaXMuZGlzcGF0Y2guYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5kb20gPSAocGxhY2UgJiYgcGxhY2UubW91bnQpIHx8IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgIGlmIChwbGFjZSkge1xuICAgICAgICAgICAgaWYgKHBsYWNlLmFwcGVuZENoaWxkKVxuICAgICAgICAgICAgICAgIHBsYWNlLmFwcGVuZENoaWxkKHRoaXMuZG9tKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBwbGFjZSA9PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgICAgICAgICAgcGxhY2UodGhpcy5kb20pO1xuICAgICAgICAgICAgZWxzZSBpZiAocGxhY2UubW91bnQpXG4gICAgICAgICAgICAgICAgdGhpcy5tb3VudGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVkaXRhYmxlID0gZ2V0RWRpdGFibGUodGhpcyk7XG4gICAgICAgIHVwZGF0ZUN1cnNvcldyYXBwZXIodGhpcyk7XG4gICAgICAgIHRoaXMubm9kZVZpZXdzID0gYnVpbGROb2RlVmlld3ModGhpcyk7XG4gICAgICAgIHRoaXMuZG9jVmlldyA9IGRvY1ZpZXdEZXNjKHRoaXMuc3RhdGUuZG9jLCBjb21wdXRlRG9jRGVjbyh0aGlzKSwgdmlld0RlY29yYXRpb25zKHRoaXMpLCB0aGlzLmRvbSwgdGhpcyk7XG4gICAgICAgIHRoaXMuZG9tT2JzZXJ2ZXIgPSBuZXcgRE9NT2JzZXJ2ZXIodGhpcywgKGZyb20sIHRvLCB0eXBlT3ZlciwgYWRkZWQpID0+IHJlYWRET01DaGFuZ2UodGhpcywgZnJvbSwgdG8sIHR5cGVPdmVyLCBhZGRlZCkpO1xuICAgICAgICB0aGlzLmRvbU9ic2VydmVyLnN0YXJ0KCk7XG4gICAgICAgIGluaXRJbnB1dCh0aGlzKTtcbiAgICAgICAgdGhpcy51cGRhdGVQbHVnaW5WaWV3cygpO1xuICAgIH1cbiAgICAvKipcbiAgICBIb2xkcyBgdHJ1ZWAgd2hlbiBhXG4gICAgW2NvbXBvc2l0aW9uXShodHRwczovL3czYy5naXRodWIuaW8vdWlldmVudHMvI2V2ZW50cy1jb21wb3NpdGlvbmV2ZW50cylcbiAgICBpcyBhY3RpdmUuXG4gICAgKi9cbiAgICBnZXQgY29tcG9zaW5nKCkgeyByZXR1cm4gdGhpcy5pbnB1dC5jb21wb3Npbmc7IH1cbiAgICAvKipcbiAgICBUaGUgdmlldydzIGN1cnJlbnQgW3Byb3BzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdmlldy5FZGl0b3JQcm9wcykuXG4gICAgKi9cbiAgICBnZXQgcHJvcHMoKSB7XG4gICAgICAgIGlmICh0aGlzLl9wcm9wcy5zdGF0ZSAhPSB0aGlzLnN0YXRlKSB7XG4gICAgICAgICAgICBsZXQgcHJldiA9IHRoaXMuX3Byb3BzO1xuICAgICAgICAgICAgdGhpcy5fcHJvcHMgPSB7fTtcbiAgICAgICAgICAgIGZvciAobGV0IG5hbWUgaW4gcHJldilcbiAgICAgICAgICAgICAgICB0aGlzLl9wcm9wc1tuYW1lXSA9IHByZXZbbmFtZV07XG4gICAgICAgICAgICB0aGlzLl9wcm9wcy5zdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3Byb3BzO1xuICAgIH1cbiAgICAvKipcbiAgICBVcGRhdGUgdGhlIHZpZXcncyBwcm9wcy4gV2lsbCBpbW1lZGlhdGVseSBjYXVzZSBhbiB1cGRhdGUgdG9cbiAgICB0aGUgRE9NLlxuICAgICovXG4gICAgdXBkYXRlKHByb3BzKSB7XG4gICAgICAgIGlmIChwcm9wcy5oYW5kbGVET01FdmVudHMgIT0gdGhpcy5fcHJvcHMuaGFuZGxlRE9NRXZlbnRzKVxuICAgICAgICAgICAgZW5zdXJlTGlzdGVuZXJzKHRoaXMpO1xuICAgICAgICBsZXQgcHJldlByb3BzID0gdGhpcy5fcHJvcHM7XG4gICAgICAgIHRoaXMuX3Byb3BzID0gcHJvcHM7XG4gICAgICAgIGlmIChwcm9wcy5wbHVnaW5zKSB7XG4gICAgICAgICAgICBwcm9wcy5wbHVnaW5zLmZvckVhY2goY2hlY2tTdGF0ZUNvbXBvbmVudCk7XG4gICAgICAgICAgICB0aGlzLmRpcmVjdFBsdWdpbnMgPSBwcm9wcy5wbHVnaW5zO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlU3RhdGVJbm5lcihwcm9wcy5zdGF0ZSwgcHJldlByb3BzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVXBkYXRlIHRoZSB2aWV3IGJ5IHVwZGF0aW5nIGV4aXN0aW5nIHByb3BzIG9iamVjdCB3aXRoIHRoZSBvYmplY3RcbiAgICBnaXZlbiBhcyBhcmd1bWVudC4gRXF1aXZhbGVudCB0byBgdmlldy51cGRhdGUoT2JqZWN0LmFzc2lnbih7fSxcbiAgICB2aWV3LnByb3BzLCBwcm9wcykpYC5cbiAgICAqL1xuICAgIHNldFByb3BzKHByb3BzKSB7XG4gICAgICAgIGxldCB1cGRhdGVkID0ge307XG4gICAgICAgIGZvciAobGV0IG5hbWUgaW4gdGhpcy5fcHJvcHMpXG4gICAgICAgICAgICB1cGRhdGVkW25hbWVdID0gdGhpcy5fcHJvcHNbbmFtZV07XG4gICAgICAgIHVwZGF0ZWQuc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgICAgICBmb3IgKGxldCBuYW1lIGluIHByb3BzKVxuICAgICAgICAgICAgdXBkYXRlZFtuYW1lXSA9IHByb3BzW25hbWVdO1xuICAgICAgICB0aGlzLnVwZGF0ZSh1cGRhdGVkKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVXBkYXRlIHRoZSBlZGl0b3IncyBgc3RhdGVgIHByb3AsIHdpdGhvdXQgdG91Y2hpbmcgYW55IG9mIHRoZVxuICAgIG90aGVyIHByb3BzLlxuICAgICovXG4gICAgdXBkYXRlU3RhdGUoc3RhdGUpIHtcbiAgICAgICAgdGhpcy51cGRhdGVTdGF0ZUlubmVyKHN0YXRlLCB0aGlzLl9wcm9wcyk7XG4gICAgfVxuICAgIHVwZGF0ZVN0YXRlSW5uZXIoc3RhdGUsIHByZXZQcm9wcykge1xuICAgICAgICB2YXIgX2E7XG4gICAgICAgIGxldCBwcmV2ID0gdGhpcy5zdGF0ZSwgcmVkcmF3ID0gZmFsc2UsIHVwZGF0ZVNlbCA9IGZhbHNlO1xuICAgICAgICAvLyBXaGVuIHN0b3JlZCBtYXJrcyBhcmUgYWRkZWQsIHN0b3AgY29tcG9zaXRpb24sIHNvIHRoYXQgdGhleSBjYW5cbiAgICAgICAgLy8gYmUgZGlzcGxheWVkLlxuICAgICAgICBpZiAoc3RhdGUuc3RvcmVkTWFya3MgJiYgdGhpcy5jb21wb3NpbmcpIHtcbiAgICAgICAgICAgIGNsZWFyQ29tcG9zaXRpb24odGhpcyk7XG4gICAgICAgICAgICB1cGRhdGVTZWwgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhdGUgPSBzdGF0ZTtcbiAgICAgICAgbGV0IHBsdWdpbnNDaGFuZ2VkID0gcHJldi5wbHVnaW5zICE9IHN0YXRlLnBsdWdpbnMgfHwgdGhpcy5fcHJvcHMucGx1Z2lucyAhPSBwcmV2UHJvcHMucGx1Z2lucztcbiAgICAgICAgaWYgKHBsdWdpbnNDaGFuZ2VkIHx8IHRoaXMuX3Byb3BzLnBsdWdpbnMgIT0gcHJldlByb3BzLnBsdWdpbnMgfHwgdGhpcy5fcHJvcHMubm9kZVZpZXdzICE9IHByZXZQcm9wcy5ub2RlVmlld3MpIHtcbiAgICAgICAgICAgIGxldCBub2RlVmlld3MgPSBidWlsZE5vZGVWaWV3cyh0aGlzKTtcbiAgICAgICAgICAgIGlmIChjaGFuZ2VkTm9kZVZpZXdzKG5vZGVWaWV3cywgdGhpcy5ub2RlVmlld3MpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub2RlVmlld3MgPSBub2RlVmlld3M7XG4gICAgICAgICAgICAgICAgcmVkcmF3ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocGx1Z2luc0NoYW5nZWQgfHwgcHJldlByb3BzLmhhbmRsZURPTUV2ZW50cyAhPSB0aGlzLl9wcm9wcy5oYW5kbGVET01FdmVudHMpIHtcbiAgICAgICAgICAgIGVuc3VyZUxpc3RlbmVycyh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVkaXRhYmxlID0gZ2V0RWRpdGFibGUodGhpcyk7XG4gICAgICAgIHVwZGF0ZUN1cnNvcldyYXBwZXIodGhpcyk7XG4gICAgICAgIGxldCBpbm5lckRlY28gPSB2aWV3RGVjb3JhdGlvbnModGhpcyksIG91dGVyRGVjbyA9IGNvbXB1dGVEb2NEZWNvKHRoaXMpO1xuICAgICAgICBsZXQgc2Nyb2xsID0gcHJldi5wbHVnaW5zICE9IHN0YXRlLnBsdWdpbnMgJiYgIXByZXYuZG9jLmVxKHN0YXRlLmRvYykgPyBcInJlc2V0XCJcbiAgICAgICAgICAgIDogc3RhdGUuc2Nyb2xsVG9TZWxlY3Rpb24gPiBwcmV2LnNjcm9sbFRvU2VsZWN0aW9uID8gXCJ0byBzZWxlY3Rpb25cIiA6IFwicHJlc2VydmVcIjtcbiAgICAgICAgbGV0IHVwZGF0ZURvYyA9IHJlZHJhdyB8fCAhdGhpcy5kb2NWaWV3Lm1hdGNoZXNOb2RlKHN0YXRlLmRvYywgb3V0ZXJEZWNvLCBpbm5lckRlY28pO1xuICAgICAgICBpZiAodXBkYXRlRG9jIHx8ICFzdGF0ZS5zZWxlY3Rpb24uZXEocHJldi5zZWxlY3Rpb24pKVxuICAgICAgICAgICAgdXBkYXRlU2VsID0gdHJ1ZTtcbiAgICAgICAgbGV0IG9sZFNjcm9sbFBvcyA9IHNjcm9sbCA9PSBcInByZXNlcnZlXCIgJiYgdXBkYXRlU2VsICYmIHRoaXMuZG9tLnN0eWxlLm92ZXJmbG93QW5jaG9yID09IG51bGwgJiYgc3RvcmVTY3JvbGxQb3ModGhpcyk7XG4gICAgICAgIGlmICh1cGRhdGVTZWwpIHtcbiAgICAgICAgICAgIHRoaXMuZG9tT2JzZXJ2ZXIuc3RvcCgpO1xuICAgICAgICAgICAgLy8gV29yayBhcm91bmQgYW4gaXNzdWUgaW4gQ2hyb21lLCBJRSwgYW5kIEVkZ2Ugd2hlcmUgY2hhbmdpbmdcbiAgICAgICAgICAgIC8vIHRoZSBET00gYXJvdW5kIGFuIGFjdGl2ZSBzZWxlY3Rpb24gcHV0cyBpdCBpbnRvIGEgYnJva2VuXG4gICAgICAgICAgICAvLyBzdGF0ZSB3aGVyZSB0aGUgdGhpbmcgdGhlIHVzZXIgc2VlcyBkaWZmZXJzIGZyb20gdGhlXG4gICAgICAgICAgICAvLyBzZWxlY3Rpb24gcmVwb3J0ZWQgYnkgdGhlIFNlbGVjdGlvbiBvYmplY3QgKCM3MTAsICM5NzMsXG4gICAgICAgICAgICAvLyAjMTAxMSwgIzEwMTMsICMxMDM1KS5cbiAgICAgICAgICAgIGxldCBmb3JjZVNlbFVwZGF0ZSA9IHVwZGF0ZURvYyAmJiAoaWUgfHwgY2hyb21lKSAmJiAhdGhpcy5jb21wb3NpbmcgJiZcbiAgICAgICAgICAgICAgICAhcHJldi5zZWxlY3Rpb24uZW1wdHkgJiYgIXN0YXRlLnNlbGVjdGlvbi5lbXB0eSAmJiBzZWxlY3Rpb25Db250ZXh0Q2hhbmdlZChwcmV2LnNlbGVjdGlvbiwgc3RhdGUuc2VsZWN0aW9uKTtcbiAgICAgICAgICAgIGlmICh1cGRhdGVEb2MpIHtcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgbm9kZSB0aGF0IHRoZSBzZWxlY3Rpb24gcG9pbnRzIGludG8gaXMgd3JpdHRlbiB0byxcbiAgICAgICAgICAgICAgICAvLyBDaHJvbWUgc29tZXRpbWVzIHN0YXJ0cyBtaXNyZXBvcnRpbmcgdGhlIHNlbGVjdGlvbiwgc28gdGhpc1xuICAgICAgICAgICAgICAgIC8vIHRyYWNrcyB0aGF0IGFuZCBmb3JjZXMgYSBzZWxlY3Rpb24gcmVzZXQgd2hlbiBvdXIgdXBkYXRlXG4gICAgICAgICAgICAgICAgLy8gZGlkIHdyaXRlIHRvIHRoZSBub2RlLlxuICAgICAgICAgICAgICAgIGxldCBjaHJvbWVLbHVkZ2UgPSBjaHJvbWUgPyAodGhpcy50cmFja1dyaXRlcyA9IHRoaXMuZG9tU2VsZWN0aW9uUmFuZ2UoKS5mb2N1c05vZGUpIDogbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb21wb3NpbmcpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXQuY29tcG9zaXRpb25Ob2RlID0gZmluZENvbXBvc2l0aW9uTm9kZSh0aGlzKTtcbiAgICAgICAgICAgICAgICBpZiAocmVkcmF3IHx8ICF0aGlzLmRvY1ZpZXcudXBkYXRlKHN0YXRlLmRvYywgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHRoaXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZG9jVmlldy51cGRhdGVPdXRlckRlY28ob3V0ZXJEZWNvKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb2NWaWV3LmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb2NWaWV3ID0gZG9jVmlld0Rlc2Moc3RhdGUuZG9jLCBvdXRlckRlY28sIGlubmVyRGVjbywgdGhpcy5kb20sIHRoaXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoY2hyb21lS2x1ZGdlICYmICghdGhpcy50cmFja1dyaXRlcyB8fCAhdGhpcy5kb20uY29udGFpbnModGhpcy50cmFja1dyaXRlcykpKVxuICAgICAgICAgICAgICAgICAgICBmb3JjZVNlbFVwZGF0ZSA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBXb3JrIGFyb3VuZCBmb3IgYW4gaXNzdWUgd2hlcmUgYW4gdXBkYXRlIGFycml2aW5nIHJpZ2h0IGJldHdlZW5cbiAgICAgICAgICAgIC8vIGEgRE9NIHNlbGVjdGlvbiBjaGFuZ2UgYW5kIHRoZSBcInNlbGVjdGlvbmNoYW5nZVwiIGV2ZW50IGZvciBpdFxuICAgICAgICAgICAgLy8gY2FuIGNhdXNlIGEgc3B1cmlvdXMgRE9NIHNlbGVjdGlvbiB1cGRhdGUsIGRpc3J1cHRpbmcgbW91c2VcbiAgICAgICAgICAgIC8vIGRyYWcgc2VsZWN0aW9uLlxuICAgICAgICAgICAgaWYgKGZvcmNlU2VsVXBkYXRlIHx8XG4gICAgICAgICAgICAgICAgISh0aGlzLmlucHV0Lm1vdXNlRG93biAmJiB0aGlzLmRvbU9ic2VydmVyLmN1cnJlbnRTZWxlY3Rpb24uZXEodGhpcy5kb21TZWxlY3Rpb25SYW5nZSgpKSAmJlxuICAgICAgICAgICAgICAgICAgICBhbmNob3JJblJpZ2h0UGxhY2UodGhpcykpKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uVG9ET00odGhpcywgZm9yY2VTZWxVcGRhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3luY05vZGVTZWxlY3Rpb24odGhpcywgc3RhdGUuc2VsZWN0aW9uKTtcbiAgICAgICAgICAgICAgICB0aGlzLmRvbU9ic2VydmVyLnNldEN1clNlbGVjdGlvbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kb21PYnNlcnZlci5zdGFydCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlUGx1Z2luVmlld3MocHJldik7XG4gICAgICAgIGlmICgoKF9hID0gdGhpcy5kcmFnZ2luZykgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hLm5vZGUpICYmICFwcmV2LmRvYy5lcShzdGF0ZS5kb2MpKVxuICAgICAgICAgICAgdGhpcy51cGRhdGVEcmFnZ2VkTm9kZSh0aGlzLmRyYWdnaW5nLCBwcmV2KTtcbiAgICAgICAgaWYgKHNjcm9sbCA9PSBcInJlc2V0XCIpIHtcbiAgICAgICAgICAgIHRoaXMuZG9tLnNjcm9sbFRvcCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc2Nyb2xsID09IFwidG8gc2VsZWN0aW9uXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9TZWxlY3Rpb24oKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvbGRTY3JvbGxQb3MpIHtcbiAgICAgICAgICAgIHJlc2V0U2Nyb2xsUG9zKG9sZFNjcm9sbFBvcyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzY3JvbGxUb1NlbGVjdGlvbigpIHtcbiAgICAgICAgbGV0IHN0YXJ0RE9NID0gdGhpcy5kb21TZWxlY3Rpb25SYW5nZSgpLmZvY3VzTm9kZTtcbiAgICAgICAgaWYgKCFzdGFydERPTSB8fCAhdGhpcy5kb20uY29udGFpbnMoc3RhcnRET00ubm9kZVR5cGUgPT0gMSA/IHN0YXJ0RE9NIDogc3RhcnRET00ucGFyZW50Tm9kZSkpIDtcbiAgICAgICAgZWxzZSBpZiAodGhpcy5zb21lUHJvcChcImhhbmRsZVNjcm9sbFRvU2VsZWN0aW9uXCIsIGYgPT4gZih0aGlzKSkpIDtcbiAgICAgICAgZWxzZSBpZiAodGhpcy5zdGF0ZS5zZWxlY3Rpb24gaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uKSB7XG4gICAgICAgICAgICBsZXQgdGFyZ2V0ID0gdGhpcy5kb2NWaWV3LmRvbUFmdGVyUG9zKHRoaXMuc3RhdGUuc2VsZWN0aW9uLmZyb20pO1xuICAgICAgICAgICAgaWYgKHRhcmdldC5ub2RlVHlwZSA9PSAxKVxuICAgICAgICAgICAgICAgIHNjcm9sbFJlY3RJbnRvVmlldyh0aGlzLCB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIHN0YXJ0RE9NKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHNjcm9sbFJlY3RJbnRvVmlldyh0aGlzLCB0aGlzLmNvb3Jkc0F0UG9zKHRoaXMuc3RhdGUuc2VsZWN0aW9uLmhlYWQsIDEpLCBzdGFydERPTSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZGVzdHJveVBsdWdpblZpZXdzKCkge1xuICAgICAgICBsZXQgdmlldztcbiAgICAgICAgd2hpbGUgKHZpZXcgPSB0aGlzLnBsdWdpblZpZXdzLnBvcCgpKVxuICAgICAgICAgICAgaWYgKHZpZXcuZGVzdHJveSlcbiAgICAgICAgICAgICAgICB2aWV3LmRlc3Ryb3koKTtcbiAgICB9XG4gICAgdXBkYXRlUGx1Z2luVmlld3MocHJldlN0YXRlKSB7XG4gICAgICAgIGlmICghcHJldlN0YXRlIHx8IHByZXZTdGF0ZS5wbHVnaW5zICE9IHRoaXMuc3RhdGUucGx1Z2lucyB8fCB0aGlzLmRpcmVjdFBsdWdpbnMgIT0gdGhpcy5wcmV2RGlyZWN0UGx1Z2lucykge1xuICAgICAgICAgICAgdGhpcy5wcmV2RGlyZWN0UGx1Z2lucyA9IHRoaXMuZGlyZWN0UGx1Z2lucztcbiAgICAgICAgICAgIHRoaXMuZGVzdHJveVBsdWdpblZpZXdzKCk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGlyZWN0UGx1Z2lucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBwbHVnaW4gPSB0aGlzLmRpcmVjdFBsdWdpbnNbaV07XG4gICAgICAgICAgICAgICAgaWYgKHBsdWdpbi5zcGVjLnZpZXcpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luVmlld3MucHVzaChwbHVnaW4uc3BlYy52aWV3KHRoaXMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zdGF0ZS5wbHVnaW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBsdWdpbiA9IHRoaXMuc3RhdGUucGx1Z2luc1tpXTtcbiAgICAgICAgICAgICAgICBpZiAocGx1Z2luLnNwZWMudmlldylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5WaWV3cy5wdXNoKHBsdWdpbi5zcGVjLnZpZXcodGhpcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBsdWdpblZpZXdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBsdWdpblZpZXcgPSB0aGlzLnBsdWdpblZpZXdzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChwbHVnaW5WaWV3LnVwZGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgcGx1Z2luVmlldy51cGRhdGUodGhpcywgcHJldlN0YXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICB1cGRhdGVEcmFnZ2VkTm9kZShkcmFnZ2luZywgcHJldikge1xuICAgICAgICBsZXQgc2VsID0gZHJhZ2dpbmcubm9kZSwgZm91bmQgPSAtMTtcbiAgICAgICAgaWYgKHNlbC5mcm9tIDwgdGhpcy5zdGF0ZS5kb2MuY29udGVudC5zaXplICYmIHRoaXMuc3RhdGUuZG9jLm5vZGVBdChzZWwuZnJvbSkgPT0gc2VsLm5vZGUpIHtcbiAgICAgICAgICAgIGZvdW5kID0gc2VsLmZyb207XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgbW92ZWRQb3MgPSBzZWwuZnJvbSArICh0aGlzLnN0YXRlLmRvYy5jb250ZW50LnNpemUgLSBwcmV2LmRvYy5jb250ZW50LnNpemUpO1xuICAgICAgICAgICAgbGV0IG1vdmVkID0gbW92ZWRQb3MgPiAwICYmIG1vdmVkUG9zIDwgdGhpcy5zdGF0ZS5kb2MuY29udGVudC5zaXplICYmIHRoaXMuc3RhdGUuZG9jLm5vZGVBdChtb3ZlZFBvcyk7XG4gICAgICAgICAgICBpZiAobW92ZWQgPT0gc2VsLm5vZGUpXG4gICAgICAgICAgICAgICAgZm91bmQgPSBtb3ZlZFBvcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRyYWdnaW5nID0gbmV3IERyYWdnaW5nKGRyYWdnaW5nLnNsaWNlLCBkcmFnZ2luZy5tb3ZlLCBmb3VuZCA8IDAgPyB1bmRlZmluZWQgOiBOb2RlU2VsZWN0aW9uLmNyZWF0ZSh0aGlzLnN0YXRlLmRvYywgZm91bmQpKTtcbiAgICB9XG4gICAgc29tZVByb3AocHJvcE5hbWUsIGYpIHtcbiAgICAgICAgbGV0IHByb3AgPSB0aGlzLl9wcm9wcyAmJiB0aGlzLl9wcm9wc1twcm9wTmFtZV0sIHZhbHVlO1xuICAgICAgICBpZiAocHJvcCAhPSBudWxsICYmICh2YWx1ZSA9IGYgPyBmKHByb3ApIDogcHJvcCkpXG4gICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5kaXJlY3RQbHVnaW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgcHJvcCA9IHRoaXMuZGlyZWN0UGx1Z2luc1tpXS5wcm9wc1twcm9wTmFtZV07XG4gICAgICAgICAgICBpZiAocHJvcCAhPSBudWxsICYmICh2YWx1ZSA9IGYgPyBmKHByb3ApIDogcHJvcCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwbHVnaW5zID0gdGhpcy5zdGF0ZS5wbHVnaW5zO1xuICAgICAgICBpZiAocGx1Z2lucylcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGx1Z2lucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBwcm9wID0gcGx1Z2luc1tpXS5wcm9wc1twcm9wTmFtZV07XG4gICAgICAgICAgICAgICAgaWYgKHByb3AgIT0gbnVsbCAmJiAodmFsdWUgPSBmID8gZihwcm9wKSA6IHByb3ApKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIFF1ZXJ5IHdoZXRoZXIgdGhlIHZpZXcgaGFzIGZvY3VzLlxuICAgICovXG4gICAgaGFzRm9jdXMoKSB7XG4gICAgICAgIC8vIFdvcmsgYXJvdW5kIElFIG5vdCBoYW5kbGluZyBmb2N1cyBjb3JyZWN0bHkgaWYgcmVzaXplIGhhbmRsZXMgYXJlIHNob3duLlxuICAgICAgICAvLyBJZiB0aGUgY3Vyc29yIGlzIGluc2lkZSBhbiBlbGVtZW50IHdpdGggcmVzaXplIGhhbmRsZXMsIGFjdGl2ZUVsZW1lbnRcbiAgICAgICAgLy8gd2lsbCBiZSB0aGF0IGVsZW1lbnQgaW5zdGVhZCBvZiB0aGlzLmRvbS5cbiAgICAgICAgaWYgKGllKSB7XG4gICAgICAgICAgICAvLyBJZiBhY3RpdmVFbGVtZW50IGlzIHdpdGhpbiB0aGlzLmRvbSwgYW5kIHRoZXJlIGFyZSBubyBvdGhlciBlbGVtZW50c1xuICAgICAgICAgICAgLy8gc2V0dGluZyBgY29udGVudGVkaXRhYmxlYCB0byBmYWxzZSBpbiBiZXR3ZWVuLCB0cmVhdCBpdCBhcyBmb2N1c2VkLlxuICAgICAgICAgICAgbGV0IG5vZGUgPSB0aGlzLnJvb3QuYWN0aXZlRWxlbWVudDtcbiAgICAgICAgICAgIGlmIChub2RlID09IHRoaXMuZG9tKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgaWYgKCFub2RlIHx8ICF0aGlzLmRvbS5jb250YWlucyhub2RlKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB3aGlsZSAobm9kZSAmJiB0aGlzLmRvbSAhPSBub2RlICYmIHRoaXMuZG9tLmNvbnRhaW5zKG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuY29udGVudEVkaXRhYmxlID09ICdmYWxzZScpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICBub2RlID0gbm9kZS5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMucm9vdC5hY3RpdmVFbGVtZW50ID09IHRoaXMuZG9tO1xuICAgIH1cbiAgICAvKipcbiAgICBGb2N1cyB0aGUgZWRpdG9yLlxuICAgICovXG4gICAgZm9jdXMoKSB7XG4gICAgICAgIHRoaXMuZG9tT2JzZXJ2ZXIuc3RvcCgpO1xuICAgICAgICBpZiAodGhpcy5lZGl0YWJsZSlcbiAgICAgICAgICAgIGZvY3VzUHJldmVudFNjcm9sbCh0aGlzLmRvbSk7XG4gICAgICAgIHNlbGVjdGlvblRvRE9NKHRoaXMpO1xuICAgICAgICB0aGlzLmRvbU9ic2VydmVyLnN0YXJ0KCk7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgZG9jdW1lbnQgcm9vdCBpbiB3aGljaCB0aGUgZWRpdG9yIGV4aXN0cy4gVGhpcyB3aWxsXG4gICAgdXN1YWxseSBiZSB0aGUgdG9wLWxldmVsIGBkb2N1bWVudGAsIGJ1dCBtaWdodCBiZSBhIFtzaGFkb3dcbiAgICBET01dKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL1dlYl9Db21wb25lbnRzL1NoYWRvd19ET00pXG4gICAgcm9vdCBpZiB0aGUgZWRpdG9yIGlzIGluc2lkZSBvbmUuXG4gICAgKi9cbiAgICBnZXQgcm9vdCgpIHtcbiAgICAgICAgbGV0IGNhY2hlZCA9IHRoaXMuX3Jvb3Q7XG4gICAgICAgIGlmIChjYWNoZWQgPT0gbnVsbClcbiAgICAgICAgICAgIGZvciAobGV0IHNlYXJjaCA9IHRoaXMuZG9tLnBhcmVudE5vZGU7IHNlYXJjaDsgc2VhcmNoID0gc2VhcmNoLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoc2VhcmNoLm5vZGVUeXBlID09IDkgfHwgKHNlYXJjaC5ub2RlVHlwZSA9PSAxMSAmJiBzZWFyY2guaG9zdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWFyY2guZ2V0U2VsZWN0aW9uKVxuICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmdldFByb3RvdHlwZU9mKHNlYXJjaCkuZ2V0U2VsZWN0aW9uID0gKCkgPT4gc2VhcmNoLm93bmVyRG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9yb290ID0gc2VhcmNoO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNhY2hlZCB8fCBkb2N1bWVudDtcbiAgICB9XG4gICAgLyoqXG4gICAgV2hlbiBhbiBleGlzdGluZyBlZGl0b3IgdmlldyBpcyBtb3ZlZCB0byBhIG5ldyBkb2N1bWVudCBvclxuICAgIHNoYWRvdyB0cmVlLCBjYWxsIHRoaXMgdG8gbWFrZSBpdCByZWNvbXB1dGUgaXRzIHJvb3QuXG4gICAgKi9cbiAgICB1cGRhdGVSb290KCkge1xuICAgICAgICB0aGlzLl9yb290ID0gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgR2l2ZW4gYSBwYWlyIG9mIHZpZXdwb3J0IGNvb3JkaW5hdGVzLCByZXR1cm4gdGhlIGRvY3VtZW50XG4gICAgcG9zaXRpb24gdGhhdCBjb3JyZXNwb25kcyB0byB0aGVtLiBNYXkgcmV0dXJuIG51bGwgaWYgdGhlIGdpdmVuXG4gICAgY29vcmRpbmF0ZXMgYXJlbid0IGluc2lkZSBvZiB0aGUgZWRpdG9yLiBXaGVuIGFuIG9iamVjdCBpc1xuICAgIHJldHVybmVkLCBpdHMgYHBvc2AgcHJvcGVydHkgaXMgdGhlIHBvc2l0aW9uIG5lYXJlc3QgdG8gdGhlXG4gICAgY29vcmRpbmF0ZXMsIGFuZCBpdHMgYGluc2lkZWAgcHJvcGVydHkgaG9sZHMgdGhlIHBvc2l0aW9uIG9mIHRoZVxuICAgIGlubmVyIG5vZGUgdGhhdCB0aGUgcG9zaXRpb24gZmFsbHMgaW5zaWRlIG9mLCBvciAtMSBpZiBpdCBpcyBhdFxuICAgIHRoZSB0b3AgbGV2ZWwsIG5vdCBpbiBhbnkgbm9kZS5cbiAgICAqL1xuICAgIHBvc0F0Q29vcmRzKGNvb3Jkcykge1xuICAgICAgICByZXR1cm4gcG9zQXRDb29yZHModGhpcywgY29vcmRzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJucyB0aGUgdmlld3BvcnQgcmVjdGFuZ2xlIGF0IGEgZ2l2ZW4gZG9jdW1lbnQgcG9zaXRpb24uXG4gICAgYGxlZnRgIGFuZCBgcmlnaHRgIHdpbGwgYmUgdGhlIHNhbWUgbnVtYmVyLCBhcyB0aGlzIHJldHVybnMgYVxuICAgIGZsYXQgY3Vyc29yLWlzaCByZWN0YW5nbGUuIElmIHRoZSBwb3NpdGlvbiBpcyBiZXR3ZWVuIHR3byB0aGluZ3NcbiAgICB0aGF0IGFyZW4ndCBkaXJlY3RseSBhZGphY2VudCwgYHNpZGVgIGRldGVybWluZXMgd2hpY2ggZWxlbWVudFxuICAgIGlzIHVzZWQuIFdoZW4gPCAwLCB0aGUgZWxlbWVudCBiZWZvcmUgdGhlIHBvc2l0aW9uIGlzIHVzZWQsXG4gICAgb3RoZXJ3aXNlIHRoZSBlbGVtZW50IGFmdGVyLlxuICAgICovXG4gICAgY29vcmRzQXRQb3MocG9zLCBzaWRlID0gMSkge1xuICAgICAgICByZXR1cm4gY29vcmRzQXRQb3ModGhpcywgcG9zLCBzaWRlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCB0aGUgRE9NIHBvc2l0aW9uIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIGdpdmVuIGRvY3VtZW50XG4gICAgcG9zaXRpb24uIFdoZW4gYHNpZGVgIGlzIG5lZ2F0aXZlLCBmaW5kIHRoZSBwb3NpdGlvbiBhcyBjbG9zZSBhc1xuICAgIHBvc3NpYmxlIHRvIHRoZSBjb250ZW50IGJlZm9yZSB0aGUgcG9zaXRpb24uIFdoZW4gcG9zaXRpdmUsXG4gICAgcHJlZmVyIHBvc2l0aW9ucyBjbG9zZSB0byB0aGUgY29udGVudCBhZnRlciB0aGUgcG9zaXRpb24uIFdoZW5cbiAgICB6ZXJvLCBwcmVmZXIgYXMgc2hhbGxvdyBhIHBvc2l0aW9uIGFzIHBvc3NpYmxlLlxuICAgIFxuICAgIE5vdGUgdGhhdCB5b3Ugc2hvdWxkICoqbm90KiogbXV0YXRlIHRoZSBlZGl0b3IncyBpbnRlcm5hbCBET00sXG4gICAgb25seSBpbnNwZWN0IGl0IChhbmQgZXZlbiB0aGF0IGlzIHVzdWFsbHkgbm90IG5lY2Vzc2FyeSkuXG4gICAgKi9cbiAgICBkb21BdFBvcyhwb3MsIHNpZGUgPSAwKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRvY1ZpZXcuZG9tRnJvbVBvcyhwb3MsIHNpZGUpO1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSBET00gbm9kZSB0aGF0IHJlcHJlc2VudHMgdGhlIGRvY3VtZW50IG5vZGUgYWZ0ZXIgdGhlXG4gICAgZ2l2ZW4gcG9zaXRpb24uIE1heSByZXR1cm4gYG51bGxgIHdoZW4gdGhlIHBvc2l0aW9uIGRvZXNuJ3QgcG9pbnRcbiAgICBpbiBmcm9udCBvZiBhIG5vZGUgb3IgaWYgdGhlIG5vZGUgaXMgaW5zaWRlIGFuIG9wYXF1ZSBub2RlIHZpZXcuXG4gICAgXG4gICAgVGhpcyBpcyBpbnRlbmRlZCB0byBiZSBhYmxlIHRvIGNhbGwgdGhpbmdzIGxpa2VcbiAgICBgZ2V0Qm91bmRpbmdDbGllbnRSZWN0YCBvbiB0aGF0IERPTSBub2RlLiBEbyAqKm5vdCoqIG11dGF0ZSB0aGVcbiAgICBlZGl0b3IgRE9NIGRpcmVjdGx5LCBvciBhZGQgc3R5bGluZyB0aGlzIHdheSwgc2luY2UgdGhhdCB3aWxsIGJlXG4gICAgaW1tZWRpYXRlbHkgb3ZlcnJpZGVuIGJ5IHRoZSBlZGl0b3IgYXMgaXQgcmVkcmF3cyB0aGUgbm9kZS5cbiAgICAqL1xuICAgIG5vZGVET00ocG9zKSB7XG4gICAgICAgIGxldCBkZXNjID0gdGhpcy5kb2NWaWV3LmRlc2NBdChwb3MpO1xuICAgICAgICByZXR1cm4gZGVzYyA/IGRlc2Mubm9kZURPTSA6IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgdGhlIGRvY3VtZW50IHBvc2l0aW9uIHRoYXQgY29ycmVzcG9uZHMgdG8gYSBnaXZlbiBET01cbiAgICBwb3NpdGlvbi4gKFdoZW5ldmVyIHBvc3NpYmxlLCBpdCBpcyBwcmVmZXJhYmxlIHRvIGluc3BlY3QgdGhlXG4gICAgZG9jdW1lbnQgc3RydWN0dXJlIGRpcmVjdGx5LCByYXRoZXIgdGhhbiBwb2tpbmcgYXJvdW5kIGluIHRoZVxuICAgIERPTSwgYnV0IHNvbWV0aW1lc1x1MjAxNGZvciBleGFtcGxlIHdoZW4gaW50ZXJwcmV0aW5nIGFuIGV2ZW50XG4gICAgdGFyZ2V0XHUyMDE0eW91IGRvbid0IGhhdmUgYSBjaG9pY2UuKVxuICAgIFxuICAgIFRoZSBgYmlhc2AgcGFyYW1ldGVyIGNhbiBiZSB1c2VkIHRvIGluZmx1ZW5jZSB3aGljaCBzaWRlIG9mIGEgRE9NXG4gICAgbm9kZSB0byB1c2Ugd2hlbiB0aGUgcG9zaXRpb24gaXMgaW5zaWRlIGEgbGVhZiBub2RlLlxuICAgICovXG4gICAgcG9zQXRET00obm9kZSwgb2Zmc2V0LCBiaWFzID0gLTEpIHtcbiAgICAgICAgbGV0IHBvcyA9IHRoaXMuZG9jVmlldy5wb3NGcm9tRE9NKG5vZGUsIG9mZnNldCwgYmlhcyk7XG4gICAgICAgIGlmIChwb3MgPT0gbnVsbClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiRE9NIHBvc2l0aW9uIG5vdCBpbnNpZGUgdGhlIGVkaXRvclwiKTtcbiAgICAgICAgcmV0dXJuIHBvcztcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCBvdXQgd2hldGhlciB0aGUgc2VsZWN0aW9uIGlzIGF0IHRoZSBlbmQgb2YgYSB0ZXh0YmxvY2sgd2hlblxuICAgIG1vdmluZyBpbiBhIGdpdmVuIGRpcmVjdGlvbi4gV2hlbiwgZm9yIGV4YW1wbGUsIGdpdmVuIGBcImxlZnRcImAsXG4gICAgaXQgd2lsbCByZXR1cm4gdHJ1ZSBpZiBtb3ZpbmcgbGVmdCBmcm9tIHRoZSBjdXJyZW50IGN1cnNvclxuICAgIHBvc2l0aW9uIHdvdWxkIGxlYXZlIHRoYXQgcG9zaXRpb24ncyBwYXJlbnQgdGV4dGJsb2NrLiBXaWxsIGFwcGx5XG4gICAgdG8gdGhlIHZpZXcncyBjdXJyZW50IHN0YXRlIGJ5IGRlZmF1bHQsIGJ1dCBpdCBpcyBwb3NzaWJsZSB0b1xuICAgIHBhc3MgYSBkaWZmZXJlbnQgc3RhdGUuXG4gICAgKi9cbiAgICBlbmRPZlRleHRibG9jayhkaXIsIHN0YXRlKSB7XG4gICAgICAgIHJldHVybiBlbmRPZlRleHRibG9jayh0aGlzLCBzdGF0ZSB8fCB0aGlzLnN0YXRlLCBkaXIpO1xuICAgIH1cbiAgICAvKipcbiAgICBSdW4gdGhlIGVkaXRvcidzIHBhc3RlIGxvZ2ljIHdpdGggdGhlIGdpdmVuIEhUTUwgc3RyaW5nLiBUaGVcbiAgICBgZXZlbnRgLCBpZiBnaXZlbiwgd2lsbCBiZSBwYXNzZWQgdG8gdGhlXG4gICAgW2BoYW5kbGVQYXN0ZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3LkVkaXRvclByb3BzLmhhbmRsZVBhc3RlKSBob29rLlxuICAgICovXG4gICAgcGFzdGVIVE1MKGh0bWwsIGV2ZW50KSB7XG4gICAgICAgIHJldHVybiBkb1Bhc3RlKHRoaXMsIFwiXCIsIGh0bWwsIGZhbHNlLCBldmVudCB8fCBuZXcgQ2xpcGJvYXJkRXZlbnQoXCJwYXN0ZVwiKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJ1biB0aGUgZWRpdG9yJ3MgcGFzdGUgbG9naWMgd2l0aCB0aGUgZ2l2ZW4gcGxhaW4tdGV4dCBpbnB1dC5cbiAgICAqL1xuICAgIHBhc3RlVGV4dCh0ZXh0LCBldmVudCkge1xuICAgICAgICByZXR1cm4gZG9QYXN0ZSh0aGlzLCB0ZXh0LCBudWxsLCB0cnVlLCBldmVudCB8fCBuZXcgQ2xpcGJvYXJkRXZlbnQoXCJwYXN0ZVwiKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIFNlcmlhbGl6ZSB0aGUgZ2l2ZW4gc2xpY2UgYXMgaXQgd291bGQgYmUgaWYgaXQgd2FzIGNvcGllZCBmcm9tXG4gICAgdGhpcyBlZGl0b3IuIFJldHVybnMgYSBET00gZWxlbWVudCB0aGF0IGNvbnRhaW5zIGFcbiAgICByZXByZXNlbnRhdGlvbiBvZiB0aGUgc2xpY2UgYXMgaXRzIGNoaWxkcmVuLCBhIHRleHR1YWxcbiAgICByZXByZXNlbnRhdGlvbiwgYW5kIHRoZSB0cmFuc2Zvcm1lZCBzbGljZSAod2hpY2ggY2FuIGJlXG4gICAgZGlmZmVyZW50IGZyb20gdGhlIGdpdmVuIGlucHV0IGR1ZSB0byBob29rcyBsaWtlXG4gICAgW2B0cmFuc2Zvcm1Db3BpZWRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdmlldy5FZGl0b3JQcm9wcy50cmFuc2Zvcm1Db3BpZWQpKS5cbiAgICAqL1xuICAgIHNlcmlhbGl6ZUZvckNsaXBib2FyZChzbGljZSkge1xuICAgICAgICByZXR1cm4gc2VyaWFsaXplRm9yQ2xpcGJvYXJkKHRoaXMsIHNsaWNlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmVtb3ZlcyB0aGUgZWRpdG9yIGZyb20gdGhlIERPTSBhbmQgZGVzdHJveXMgYWxsIFtub2RlXG4gICAgdmlld3NdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3Lk5vZGVWaWV3KS5cbiAgICAqL1xuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIGlmICghdGhpcy5kb2NWaWV3KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBkZXN0cm95SW5wdXQodGhpcyk7XG4gICAgICAgIHRoaXMuZGVzdHJveVBsdWdpblZpZXdzKCk7XG4gICAgICAgIGlmICh0aGlzLm1vdW50ZWQpIHtcbiAgICAgICAgICAgIHRoaXMuZG9jVmlldy51cGRhdGUodGhpcy5zdGF0ZS5kb2MsIFtdLCB2aWV3RGVjb3JhdGlvbnModGhpcyksIHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5kb20udGV4dENvbnRlbnQgPSBcIlwiO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuZG9tLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuZG9tLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5kb20pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZG9jVmlldy5kZXN0cm95KCk7XG4gICAgICAgIHRoaXMuZG9jVmlldyA9IG51bGw7XG4gICAgICAgIGNsZWFyUmV1c2VkUmFuZ2UoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhpcyBpcyB0cnVlIHdoZW4gdGhlIHZpZXcgaGFzIGJlZW5cbiAgICBbZGVzdHJveWVkXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdmlldy5FZGl0b3JWaWV3LmRlc3Ryb3kpIChhbmQgdGh1cyBzaG91bGQgbm90IGJlXG4gICAgdXNlZCBhbnltb3JlKS5cbiAgICAqL1xuICAgIGdldCBpc0Rlc3Ryb3llZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZG9jVmlldyA9PSBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBVc2VkIGZvciB0ZXN0aW5nLlxuICAgICovXG4gICAgZGlzcGF0Y2hFdmVudChldmVudCkge1xuICAgICAgICByZXR1cm4gZGlzcGF0Y2hFdmVudCh0aGlzLCBldmVudCk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgZG9tU2VsZWN0aW9uUmFuZ2UoKSB7XG4gICAgICAgIGxldCBzZWwgPSB0aGlzLmRvbVNlbGVjdGlvbigpO1xuICAgICAgICBpZiAoIXNlbClcbiAgICAgICAgICAgIHJldHVybiB7IGZvY3VzTm9kZTogbnVsbCwgZm9jdXNPZmZzZXQ6IDAsIGFuY2hvck5vZGU6IG51bGwsIGFuY2hvck9mZnNldDogMCB9O1xuICAgICAgICByZXR1cm4gc2FmYXJpICYmIHRoaXMucm9vdC5ub2RlVHlwZSA9PT0gMTEgJiZcbiAgICAgICAgICAgIGRlZXBBY3RpdmVFbGVtZW50KHRoaXMuZG9tLm93bmVyRG9jdW1lbnQpID09IHRoaXMuZG9tICYmIHNhZmFyaVNoYWRvd1NlbGVjdGlvblJhbmdlKHRoaXMsIHNlbCkgfHwgc2VsO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGRvbVNlbGVjdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucm9vdC5nZXRTZWxlY3Rpb24oKTtcbiAgICB9XG59XG5FZGl0b3JWaWV3LnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uICh0cikge1xuICAgIGxldCBkaXNwYXRjaFRyYW5zYWN0aW9uID0gdGhpcy5fcHJvcHMuZGlzcGF0Y2hUcmFuc2FjdGlvbjtcbiAgICBpZiAoZGlzcGF0Y2hUcmFuc2FjdGlvbilcbiAgICAgICAgZGlzcGF0Y2hUcmFuc2FjdGlvbi5jYWxsKHRoaXMsIHRyKTtcbiAgICBlbHNlXG4gICAgICAgIHRoaXMudXBkYXRlU3RhdGUodGhpcy5zdGF0ZS5hcHBseSh0cikpO1xufTtcbmZ1bmN0aW9uIGNvbXB1dGVEb2NEZWNvKHZpZXcpIHtcbiAgICBsZXQgYXR0cnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIGF0dHJzLmNsYXNzID0gXCJQcm9zZU1pcnJvclwiO1xuICAgIGF0dHJzLmNvbnRlbnRlZGl0YWJsZSA9IFN0cmluZyh2aWV3LmVkaXRhYmxlKTtcbiAgICB2aWV3LnNvbWVQcm9wKFwiYXR0cmlidXRlc1wiLCB2YWx1ZSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZSh2aWV3LnN0YXRlKTtcbiAgICAgICAgaWYgKHZhbHVlKVxuICAgICAgICAgICAgZm9yIChsZXQgYXR0ciBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmIChhdHRyID09IFwiY2xhc3NcIilcbiAgICAgICAgICAgICAgICAgICAgYXR0cnMuY2xhc3MgKz0gXCIgXCIgKyB2YWx1ZVthdHRyXTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdHRyID09IFwic3R5bGVcIilcbiAgICAgICAgICAgICAgICAgICAgYXR0cnMuc3R5bGUgPSAoYXR0cnMuc3R5bGUgPyBhdHRycy5zdHlsZSArIFwiO1wiIDogXCJcIikgKyB2YWx1ZVthdHRyXTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghYXR0cnNbYXR0cl0gJiYgYXR0ciAhPSBcImNvbnRlbnRlZGl0YWJsZVwiICYmIGF0dHIgIT0gXCJub2RlTmFtZVwiKVxuICAgICAgICAgICAgICAgICAgICBhdHRyc1thdHRyXSA9IFN0cmluZyh2YWx1ZVthdHRyXSk7XG4gICAgICAgICAgICB9XG4gICAgfSk7XG4gICAgaWYgKCFhdHRycy50cmFuc2xhdGUpXG4gICAgICAgIGF0dHJzLnRyYW5zbGF0ZSA9IFwibm9cIjtcbiAgICByZXR1cm4gW0RlY29yYXRpb24ubm9kZSgwLCB2aWV3LnN0YXRlLmRvYy5jb250ZW50LnNpemUsIGF0dHJzKV07XG59XG5mdW5jdGlvbiB1cGRhdGVDdXJzb3JXcmFwcGVyKHZpZXcpIHtcbiAgICBpZiAodmlldy5tYXJrQ3Vyc29yKSB7XG4gICAgICAgIGxldCBkb20gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW1nXCIpO1xuICAgICAgICBkb20uY2xhc3NOYW1lID0gXCJQcm9zZU1pcnJvci1zZXBhcmF0b3JcIjtcbiAgICAgICAgZG9tLnNldEF0dHJpYnV0ZShcIm1hcmstcGxhY2Vob2xkZXJcIiwgXCJ0cnVlXCIpO1xuICAgICAgICBkb20uc2V0QXR0cmlidXRlKFwiYWx0XCIsIFwiXCIpO1xuICAgICAgICB2aWV3LmN1cnNvcldyYXBwZXIgPSB7IGRvbSwgZGVjbzogRGVjb3JhdGlvbi53aWRnZXQodmlldy5zdGF0ZS5zZWxlY3Rpb24uZnJvbSwgZG9tLCB7IHJhdzogdHJ1ZSwgbWFya3M6IHZpZXcubWFya0N1cnNvciB9KSB9O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmlldy5jdXJzb3JXcmFwcGVyID0gbnVsbDtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRFZGl0YWJsZSh2aWV3KSB7XG4gICAgcmV0dXJuICF2aWV3LnNvbWVQcm9wKFwiZWRpdGFibGVcIiwgdmFsdWUgPT4gdmFsdWUodmlldy5zdGF0ZSkgPT09IGZhbHNlKTtcbn1cbmZ1bmN0aW9uIHNlbGVjdGlvbkNvbnRleHRDaGFuZ2VkKHNlbDEsIHNlbDIpIHtcbiAgICBsZXQgZGVwdGggPSBNYXRoLm1pbihzZWwxLiRhbmNob3Iuc2hhcmVkRGVwdGgoc2VsMS5oZWFkKSwgc2VsMi4kYW5jaG9yLnNoYXJlZERlcHRoKHNlbDIuaGVhZCkpO1xuICAgIHJldHVybiBzZWwxLiRhbmNob3Iuc3RhcnQoZGVwdGgpICE9IHNlbDIuJGFuY2hvci5zdGFydChkZXB0aCk7XG59XG5mdW5jdGlvbiBidWlsZE5vZGVWaWV3cyh2aWV3KSB7XG4gICAgbGV0IHJlc3VsdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgZnVuY3Rpb24gYWRkKG9iaikge1xuICAgICAgICBmb3IgKGxldCBwcm9wIGluIG9iailcbiAgICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwgcHJvcCkpXG4gICAgICAgICAgICAgICAgcmVzdWx0W3Byb3BdID0gb2JqW3Byb3BdO1xuICAgIH1cbiAgICB2aWV3LnNvbWVQcm9wKFwibm9kZVZpZXdzXCIsIGFkZCk7XG4gICAgdmlldy5zb21lUHJvcChcIm1hcmtWaWV3c1wiLCBhZGQpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBjaGFuZ2VkTm9kZVZpZXdzKGEsIGIpIHtcbiAgICBsZXQgbkEgPSAwLCBuQiA9IDA7XG4gICAgZm9yIChsZXQgcHJvcCBpbiBhKSB7XG4gICAgICAgIGlmIChhW3Byb3BdICE9IGJbcHJvcF0pXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgbkErKztcbiAgICB9XG4gICAgZm9yIChsZXQgXyBpbiBiKVxuICAgICAgICBuQisrO1xuICAgIHJldHVybiBuQSAhPSBuQjtcbn1cbmZ1bmN0aW9uIGNoZWNrU3RhdGVDb21wb25lbnQocGx1Z2luKSB7XG4gICAgaWYgKHBsdWdpbi5zcGVjLnN0YXRlIHx8IHBsdWdpbi5zcGVjLmZpbHRlclRyYW5zYWN0aW9uIHx8IHBsdWdpbi5zcGVjLmFwcGVuZFRyYW5zYWN0aW9uKVxuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlBsdWdpbnMgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSB2aWV3IG11c3Qgbm90IGhhdmUgYSBzdGF0ZSBjb21wb25lbnRcIik7XG59XG5cbmV4cG9ydCB7IERlY29yYXRpb24sIERlY29yYXRpb25TZXQsIEVkaXRvclZpZXcsIF9fZW5kQ29tcG9zaXRpb24sIF9fcGFyc2VGcm9tQ2xpcGJvYXJkIH07XG4iLCAiZXhwb3J0IHZhciBiYXNlID0ge1xuICA4OiBcIkJhY2tzcGFjZVwiLFxuICA5OiBcIlRhYlwiLFxuICAxMDogXCJFbnRlclwiLFxuICAxMjogXCJOdW1Mb2NrXCIsXG4gIDEzOiBcIkVudGVyXCIsXG4gIDE2OiBcIlNoaWZ0XCIsXG4gIDE3OiBcIkNvbnRyb2xcIixcbiAgMTg6IFwiQWx0XCIsXG4gIDIwOiBcIkNhcHNMb2NrXCIsXG4gIDI3OiBcIkVzY2FwZVwiLFxuICAzMjogXCIgXCIsXG4gIDMzOiBcIlBhZ2VVcFwiLFxuICAzNDogXCJQYWdlRG93blwiLFxuICAzNTogXCJFbmRcIixcbiAgMzY6IFwiSG9tZVwiLFxuICAzNzogXCJBcnJvd0xlZnRcIixcbiAgMzg6IFwiQXJyb3dVcFwiLFxuICAzOTogXCJBcnJvd1JpZ2h0XCIsXG4gIDQwOiBcIkFycm93RG93blwiLFxuICA0NDogXCJQcmludFNjcmVlblwiLFxuICA0NTogXCJJbnNlcnRcIixcbiAgNDY6IFwiRGVsZXRlXCIsXG4gIDU5OiBcIjtcIixcbiAgNjE6IFwiPVwiLFxuICA5MTogXCJNZXRhXCIsXG4gIDkyOiBcIk1ldGFcIixcbiAgMTA2OiBcIipcIixcbiAgMTA3OiBcIitcIixcbiAgMTA4OiBcIixcIixcbiAgMTA5OiBcIi1cIixcbiAgMTEwOiBcIi5cIixcbiAgMTExOiBcIi9cIixcbiAgMTQ0OiBcIk51bUxvY2tcIixcbiAgMTQ1OiBcIlNjcm9sbExvY2tcIixcbiAgMTYwOiBcIlNoaWZ0XCIsXG4gIDE2MTogXCJTaGlmdFwiLFxuICAxNjI6IFwiQ29udHJvbFwiLFxuICAxNjM6IFwiQ29udHJvbFwiLFxuICAxNjQ6IFwiQWx0XCIsXG4gIDE2NTogXCJBbHRcIixcbiAgMTczOiBcIi1cIixcbiAgMTg2OiBcIjtcIixcbiAgMTg3OiBcIj1cIixcbiAgMTg4OiBcIixcIixcbiAgMTg5OiBcIi1cIixcbiAgMTkwOiBcIi5cIixcbiAgMTkxOiBcIi9cIixcbiAgMTkyOiBcImBcIixcbiAgMjE5OiBcIltcIixcbiAgMjIwOiBcIlxcXFxcIixcbiAgMjIxOiBcIl1cIixcbiAgMjIyOiBcIidcIlxufVxuXG5leHBvcnQgdmFyIHNoaWZ0ID0ge1xuICA0ODogXCIpXCIsXG4gIDQ5OiBcIiFcIixcbiAgNTA6IFwiQFwiLFxuICA1MTogXCIjXCIsXG4gIDUyOiBcIiRcIixcbiAgNTM6IFwiJVwiLFxuICA1NDogXCJeXCIsXG4gIDU1OiBcIiZcIixcbiAgNTY6IFwiKlwiLFxuICA1NzogXCIoXCIsXG4gIDU5OiBcIjpcIixcbiAgNjE6IFwiK1wiLFxuICAxNzM6IFwiX1wiLFxuICAxODY6IFwiOlwiLFxuICAxODc6IFwiK1wiLFxuICAxODg6IFwiPFwiLFxuICAxODk6IFwiX1wiLFxuICAxOTA6IFwiPlwiLFxuICAxOTE6IFwiP1wiLFxuICAxOTI6IFwiflwiLFxuICAyMTk6IFwie1wiLFxuICAyMjA6IFwifFwiLFxuICAyMjE6IFwifVwiLFxuICAyMjI6IFwiXFxcIlwiXG59XG5cbnZhciBtYWMgPSB0eXBlb2YgbmF2aWdhdG9yICE9IFwidW5kZWZpbmVkXCIgJiYgL01hYy8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pXG52YXIgaWUgPSB0eXBlb2YgbmF2aWdhdG9yICE9IFwidW5kZWZpbmVkXCIgJiYgL01TSUUgXFxkfFRyaWRlbnRcXC8oPzpbNy05XXxcXGR7Mix9KVxcLi4qcnY6KFxcZCspLy5leGVjKG5hdmlnYXRvci51c2VyQWdlbnQpXG5cbi8vIEZpbGwgaW4gdGhlIGRpZ2l0IGtleXNcbmZvciAodmFyIGkgPSAwOyBpIDwgMTA7IGkrKykgYmFzZVs0OCArIGldID0gYmFzZVs5NiArIGldID0gU3RyaW5nKGkpXG5cbi8vIFRoZSBmdW5jdGlvbiBrZXlzXG5mb3IgKHZhciBpID0gMTsgaSA8PSAyNDsgaSsrKSBiYXNlW2kgKyAxMTFdID0gXCJGXCIgKyBpXG5cbi8vIEFuZCB0aGUgYWxwaGFiZXRpYyBrZXlzXG5mb3IgKHZhciBpID0gNjU7IGkgPD0gOTA7IGkrKykge1xuICBiYXNlW2ldID0gU3RyaW5nLmZyb21DaGFyQ29kZShpICsgMzIpXG4gIHNoaWZ0W2ldID0gU3RyaW5nLmZyb21DaGFyQ29kZShpKVxufVxuXG4vLyBGb3IgZWFjaCBjb2RlIHRoYXQgZG9lc24ndCBoYXZlIGEgc2hpZnQtZXF1aXZhbGVudCwgY29weSB0aGUgYmFzZSBuYW1lXG5mb3IgKHZhciBjb2RlIGluIGJhc2UpIGlmICghc2hpZnQuaGFzT3duUHJvcGVydHkoY29kZSkpIHNoaWZ0W2NvZGVdID0gYmFzZVtjb2RlXVxuXG5leHBvcnQgZnVuY3Rpb24ga2V5TmFtZShldmVudCkge1xuICAvLyBPbiBtYWNPUywga2V5cyBoZWxkIHdpdGggU2hpZnQgYW5kIENtZCBkb24ndCByZWZsZWN0IHRoZSBlZmZlY3Qgb2YgU2hpZnQgaW4gYC5rZXlgLlxuICAvLyBPbiBJRSwgc2hpZnQgZWZmZWN0IGlzIG5ldmVyIGluY2x1ZGVkIGluIGAua2V5YC5cbiAgdmFyIGlnbm9yZUtleSA9IG1hYyAmJiBldmVudC5tZXRhS2V5ICYmIGV2ZW50LnNoaWZ0S2V5ICYmICFldmVudC5jdHJsS2V5ICYmICFldmVudC5hbHRLZXkgfHxcbiAgICAgIGllICYmIGV2ZW50LnNoaWZ0S2V5ICYmIGV2ZW50LmtleSAmJiBldmVudC5rZXkubGVuZ3RoID09IDEgfHxcbiAgICAgIGV2ZW50LmtleSA9PSBcIlVuaWRlbnRpZmllZFwiXG4gIHZhciBuYW1lID0gKCFpZ25vcmVLZXkgJiYgZXZlbnQua2V5KSB8fFxuICAgIChldmVudC5zaGlmdEtleSA/IHNoaWZ0IDogYmFzZSlbZXZlbnQua2V5Q29kZV0gfHxcbiAgICBldmVudC5rZXkgfHwgXCJVbmlkZW50aWZpZWRcIlxuICAvLyBFZGdlIHNvbWV0aW1lcyBwcm9kdWNlcyB3cm9uZyBuYW1lcyAoSXNzdWUgIzMpXG4gIGlmIChuYW1lID09IFwiRXNjXCIpIG5hbWUgPSBcIkVzY2FwZVwiXG4gIGlmIChuYW1lID09IFwiRGVsXCIpIG5hbWUgPSBcIkRlbGV0ZVwiXG4gIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1pY3Jvc29mdC5jb20vZW4tdXMvbWljcm9zb2Z0LWVkZ2UvcGxhdGZvcm0vaXNzdWVzLzg4NjA1NzEvXG4gIGlmIChuYW1lID09IFwiTGVmdFwiKSBuYW1lID0gXCJBcnJvd0xlZnRcIlxuICBpZiAobmFtZSA9PSBcIlVwXCIpIG5hbWUgPSBcIkFycm93VXBcIlxuICBpZiAobmFtZSA9PSBcIlJpZ2h0XCIpIG5hbWUgPSBcIkFycm93UmlnaHRcIlxuICBpZiAobmFtZSA9PSBcIkRvd25cIikgbmFtZSA9IFwiQXJyb3dEb3duXCJcbiAgcmV0dXJuIG5hbWVcbn1cbiIsICJpbXBvcnQgeyBrZXlOYW1lLCBiYXNlIH0gZnJvbSAndzNjLWtleW5hbWUnO1xuaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuXG5jb25zdCBtYWMgPSB0eXBlb2YgbmF2aWdhdG9yICE9IFwidW5kZWZpbmVkXCIgJiYgL01hY3xpUChob25lfFtvYV1kKS8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pO1xuY29uc3Qgd2luZG93cyA9IHR5cGVvZiBuYXZpZ2F0b3IgIT0gXCJ1bmRlZmluZWRcIiAmJiAvV2luLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7XG5mdW5jdGlvbiBub3JtYWxpemVLZXlOYW1lKG5hbWUpIHtcbiAgICBsZXQgcGFydHMgPSBuYW1lLnNwbGl0KC8tKD8hJCkvKSwgcmVzdWx0ID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV07XG4gICAgaWYgKHJlc3VsdCA9PSBcIlNwYWNlXCIpXG4gICAgICAgIHJlc3VsdCA9IFwiIFwiO1xuICAgIGxldCBhbHQsIGN0cmwsIHNoaWZ0LCBtZXRhO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGxldCBtb2QgPSBwYXJ0c1tpXTtcbiAgICAgICAgaWYgKC9eKGNtZHxtZXRhfG0pJC9pLnRlc3QobW9kKSlcbiAgICAgICAgICAgIG1ldGEgPSB0cnVlO1xuICAgICAgICBlbHNlIGlmICgvXmEobHQpPyQvaS50ZXN0KG1vZCkpXG4gICAgICAgICAgICBhbHQgPSB0cnVlO1xuICAgICAgICBlbHNlIGlmICgvXihjfGN0cmx8Y29udHJvbCkkL2kudGVzdChtb2QpKVxuICAgICAgICAgICAgY3RybCA9IHRydWU7XG4gICAgICAgIGVsc2UgaWYgKC9ecyhoaWZ0KT8kL2kudGVzdChtb2QpKVxuICAgICAgICAgICAgc2hpZnQgPSB0cnVlO1xuICAgICAgICBlbHNlIGlmICgvXm1vZCQvaS50ZXN0KG1vZCkpIHtcbiAgICAgICAgICAgIGlmIChtYWMpXG4gICAgICAgICAgICAgICAgbWV0YSA9IHRydWU7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgY3RybCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5yZWNvZ25pemVkIG1vZGlmaWVyIG5hbWU6IFwiICsgbW9kKTtcbiAgICB9XG4gICAgaWYgKGFsdClcbiAgICAgICAgcmVzdWx0ID0gXCJBbHQtXCIgKyByZXN1bHQ7XG4gICAgaWYgKGN0cmwpXG4gICAgICAgIHJlc3VsdCA9IFwiQ3RybC1cIiArIHJlc3VsdDtcbiAgICBpZiAobWV0YSlcbiAgICAgICAgcmVzdWx0ID0gXCJNZXRhLVwiICsgcmVzdWx0O1xuICAgIGlmIChzaGlmdClcbiAgICAgICAgcmVzdWx0ID0gXCJTaGlmdC1cIiArIHJlc3VsdDtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gbm9ybWFsaXplKG1hcCkge1xuICAgIGxldCBjb3B5ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICBmb3IgKGxldCBwcm9wIGluIG1hcClcbiAgICAgICAgY29weVtub3JtYWxpemVLZXlOYW1lKHByb3ApXSA9IG1hcFtwcm9wXTtcbiAgICByZXR1cm4gY29weTtcbn1cbmZ1bmN0aW9uIG1vZGlmaWVycyhuYW1lLCBldmVudCwgc2hpZnQgPSB0cnVlKSB7XG4gICAgaWYgKGV2ZW50LmFsdEtleSlcbiAgICAgICAgbmFtZSA9IFwiQWx0LVwiICsgbmFtZTtcbiAgICBpZiAoZXZlbnQuY3RybEtleSlcbiAgICAgICAgbmFtZSA9IFwiQ3RybC1cIiArIG5hbWU7XG4gICAgaWYgKGV2ZW50Lm1ldGFLZXkpXG4gICAgICAgIG5hbWUgPSBcIk1ldGEtXCIgKyBuYW1lO1xuICAgIGlmIChzaGlmdCAmJiBldmVudC5zaGlmdEtleSlcbiAgICAgICAgbmFtZSA9IFwiU2hpZnQtXCIgKyBuYW1lO1xuICAgIHJldHVybiBuYW1lO1xufVxuLyoqXG5DcmVhdGUgYSBrZXltYXAgcGx1Z2luIGZvciB0aGUgZ2l2ZW4gc2V0IG9mIGJpbmRpbmdzLlxuXG5CaW5kaW5ncyBzaG91bGQgbWFwIGtleSBuYW1lcyB0byBbY29tbWFuZF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI2NvbW1hbmRzKS1zdHlsZVxuZnVuY3Rpb25zLCB3aGljaCB3aWxsIGJlIGNhbGxlZCB3aXRoIGAoRWRpdG9yU3RhdGUsIGRpc3BhdGNoLFxuRWRpdG9yVmlldylgIGFyZ3VtZW50cywgYW5kIHNob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHRoZXkndmUgaGFuZGxlZFxudGhlIGtleS4gTm90ZSB0aGF0IHRoZSB2aWV3IGFyZ3VtZW50IGlzbid0IHBhcnQgb2YgdGhlIGNvbW1hbmRcbnByb3RvY29sLCBidXQgY2FuIGJlIHVzZWQgYXMgYW4gZXNjYXBlIGhhdGNoIGlmIGEgYmluZGluZyBuZWVkcyB0b1xuZGlyZWN0bHkgaW50ZXJhY3Qgd2l0aCB0aGUgVUkuXG5cbktleSBuYW1lcyBtYXkgYmUgc3RyaW5ncyBsaWtlIGBcIlNoaWZ0LUN0cmwtRW50ZXJcImBcdTIwMTRhIGtleVxuaWRlbnRpZmllciBwcmVmaXhlZCB3aXRoIHplcm8gb3IgbW9yZSBtb2RpZmllcnMuIEtleSBpZGVudGlmaWVyc1xuYXJlIGJhc2VkIG9uIHRoZSBzdHJpbmdzIHRoYXQgY2FuIGFwcGVhciBpblxuW2BLZXlFdmVudC5rZXlgXShodHRwczpkZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0tleWJvYXJkRXZlbnQva2V5KS5cblVzZSBsb3dlcmNhc2UgbGV0dGVycyB0byByZWZlciB0byBsZXR0ZXIga2V5cyAob3IgdXBwZXJjYXNlIGxldHRlcnNcbmlmIHlvdSB3YW50IHNoaWZ0IHRvIGJlIGhlbGQpLiBZb3UgbWF5IHVzZSBgXCJTcGFjZVwiYCBhcyBhbiBhbGlhc1xuZm9yIHRoZSBgXCIgXCJgIG5hbWUuXG5cbk1vZGlmaWVycyBjYW4gYmUgZ2l2ZW4gaW4gYW55IG9yZGVyLiBgU2hpZnQtYCAob3IgYHMtYCksIGBBbHQtYCAob3JcbmBhLWApLCBgQ3RybC1gIChvciBgYy1gIG9yIGBDb250cm9sLWApIGFuZCBgQ21kLWAgKG9yIGBtLWAgb3JcbmBNZXRhLWApIGFyZSByZWNvZ25pemVkLiBGb3IgY2hhcmFjdGVycyB0aGF0IGFyZSBjcmVhdGVkIGJ5IGhvbGRpbmdcbnNoaWZ0LCB0aGUgYFNoaWZ0LWAgcHJlZml4IGlzIGltcGxpZWQsIGFuZCBzaG91bGQgbm90IGJlIGFkZGVkXG5leHBsaWNpdGx5LlxuXG5Zb3UgY2FuIHVzZSBgTW9kLWAgYXMgYSBzaG9ydGhhbmQgZm9yIGBDbWQtYCBvbiBNYWMgYW5kIGBDdHJsLWAgb25cbm90aGVyIHBsYXRmb3Jtcy5cblxuWW91IGNhbiBhZGQgbXVsdGlwbGUga2V5bWFwIHBsdWdpbnMgdG8gYW4gZWRpdG9yLiBUaGUgb3JkZXIgaW5cbndoaWNoIHRoZXkgYXBwZWFyIGRldGVybWluZXMgdGhlaXIgcHJlY2VkZW5jZSAodGhlIG9uZXMgZWFybHkgaW5cbnRoZSBhcnJheSBnZXQgdG8gZGlzcGF0Y2ggZmlyc3QpLlxuKi9cbmZ1bmN0aW9uIGtleW1hcChiaW5kaW5ncykge1xuICAgIHJldHVybiBuZXcgUGx1Z2luKHsgcHJvcHM6IHsgaGFuZGxlS2V5RG93bjoga2V5ZG93bkhhbmRsZXIoYmluZGluZ3MpIH0gfSk7XG59XG4vKipcbkdpdmVuIGEgc2V0IG9mIGJpbmRpbmdzICh1c2luZyB0aGUgc2FtZSBmb3JtYXQgYXNcbltga2V5bWFwYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI2tleW1hcC5rZXltYXApKSwgcmV0dXJuIGEgW2tleWRvd25cbmhhbmRsZXJdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3LkVkaXRvclByb3BzLmhhbmRsZUtleURvd24pIHRoYXQgaGFuZGxlcyB0aGVtLlxuKi9cbmZ1bmN0aW9uIGtleWRvd25IYW5kbGVyKGJpbmRpbmdzKSB7XG4gICAgbGV0IG1hcCA9IG5vcm1hbGl6ZShiaW5kaW5ncyk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh2aWV3LCBldmVudCkge1xuICAgICAgICBsZXQgbmFtZSA9IGtleU5hbWUoZXZlbnQpLCBiYXNlTmFtZSwgZGlyZWN0ID0gbWFwW21vZGlmaWVycyhuYW1lLCBldmVudCldO1xuICAgICAgICBpZiAoZGlyZWN0ICYmIGRpcmVjdCh2aWV3LnN0YXRlLCB2aWV3LmRpc3BhdGNoLCB2aWV3KSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAvLyBBIGNoYXJhY3RlciBrZXlcbiAgICAgICAgaWYgKG5hbWUubGVuZ3RoID09IDEgJiYgbmFtZSAhPSBcIiBcIikge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICAgICAgLy8gSW4gY2FzZSB0aGUgbmFtZSB3YXMgYWxyZWFkeSBtb2RpZmllZCBieSBzaGlmdCwgdHJ5IGxvb2tpbmdcbiAgICAgICAgICAgICAgICAvLyBpdCB1cCB3aXRob3V0IGl0cyBzaGlmdCBtb2RpZmllclxuICAgICAgICAgICAgICAgIGxldCBub1NoaWZ0ID0gbWFwW21vZGlmaWVycyhuYW1lLCBldmVudCwgZmFsc2UpXTtcbiAgICAgICAgICAgICAgICBpZiAobm9TaGlmdCAmJiBub1NoaWZ0KHZpZXcuc3RhdGUsIHZpZXcuZGlzcGF0Y2gsIHZpZXcpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICgoZXZlbnQuYWx0S2V5IHx8IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuY3RybEtleSkgJiZcbiAgICAgICAgICAgICAgICAvLyBDdHJsLUFsdCBtYXkgYmUgdXNlZCBmb3IgQWx0R3Igb24gV2luZG93c1xuICAgICAgICAgICAgICAgICEod2luZG93cyAmJiBldmVudC5jdHJsS2V5ICYmIGV2ZW50LmFsdEtleSkgJiZcbiAgICAgICAgICAgICAgICAoYmFzZU5hbWUgPSBiYXNlW2V2ZW50LmtleUNvZGVdKSAmJiBiYXNlTmFtZSAhPSBuYW1lKSB7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IGZhbGxpbmcgYmFjayB0byB0aGUga2V5Q29kZSB3aGVuIHRoZXJlJ3MgYSBtb2RpZmllclxuICAgICAgICAgICAgICAgIC8vIGFjdGl2ZSBvciB0aGUgY2hhcmFjdGVyIHByb2R1Y2VkIGlzbid0IEFTQ0lJLCBhbmQgb3VyIHRhYmxlXG4gICAgICAgICAgICAgICAgLy8gcHJvZHVjZXMgYSBkaWZmZXJlbnQgbmFtZSBmcm9tIHRoZSB0aGUga2V5Q29kZS4gU2VlICM2NjgsXG4gICAgICAgICAgICAgICAgLy8gIzEwNjAsICMxNTI5LlxuICAgICAgICAgICAgICAgIGxldCBmcm9tQ29kZSA9IG1hcFttb2RpZmllcnMoYmFzZU5hbWUsIGV2ZW50KV07XG4gICAgICAgICAgICAgICAgaWYgKGZyb21Db2RlICYmIGZyb21Db2RlKHZpZXcuc3RhdGUsIHZpZXcuZGlzcGF0Y2gsIHZpZXcpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbn1cblxuZXhwb3J0IHsga2V5ZG93bkhhbmRsZXIsIGtleW1hcCB9O1xuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUsIFRyYW5zYWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuLyoqXG4gKiBUYWtlcyBhIFRyYW5zYWN0aW9uICYgRWRpdG9yIFN0YXRlIGFuZCB0dXJucyBpdCBpbnRvIGEgY2hhaW5hYmxlIHN0YXRlIG9iamVjdFxuICogQHBhcmFtIGNvbmZpZyBUaGUgdHJhbnNhY3Rpb24gYW5kIHN0YXRlIHRvIGNyZWF0ZSB0aGUgY2hhaW5hYmxlIHN0YXRlIGZyb21cbiAqIEByZXR1cm5zIEEgY2hhaW5hYmxlIEVkaXRvciBzdGF0ZSBvYmplY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNoYWluYWJsZVN0YXRlKGNvbmZpZzoge1xuICB0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb25cbiAgc3RhdGU6IEVkaXRvclN0YXRlXG59KTogRWRpdG9yU3RhdGUge1xuICBjb25zdCB7IHN0YXRlLCB0cmFuc2FjdGlvbiB9ID0gY29uZmlnXG4gIGxldCB7IHNlbGVjdGlvbiB9ID0gdHJhbnNhY3Rpb25cbiAgbGV0IHsgZG9jIH0gPSB0cmFuc2FjdGlvblxuICBsZXQgeyBzdG9yZWRNYXJrcyB9ID0gdHJhbnNhY3Rpb25cblxuICByZXR1cm4ge1xuICAgIC4uLnN0YXRlLFxuICAgIGFwcGx5OiBzdGF0ZS5hcHBseS5iaW5kKHN0YXRlKSxcbiAgICBhcHBseVRyYW5zYWN0aW9uOiBzdGF0ZS5hcHBseVRyYW5zYWN0aW9uLmJpbmQoc3RhdGUpLFxuICAgIHBsdWdpbnM6IHN0YXRlLnBsdWdpbnMsXG4gICAgc2NoZW1hOiBzdGF0ZS5zY2hlbWEsXG4gICAgcmVjb25maWd1cmU6IHN0YXRlLnJlY29uZmlndXJlLmJpbmQoc3RhdGUpLFxuICAgIHRvSlNPTjogc3RhdGUudG9KU09OLmJpbmQoc3RhdGUpLFxuICAgIGdldCBzdG9yZWRNYXJrcygpIHtcbiAgICAgIHJldHVybiBzdG9yZWRNYXJrc1xuICAgIH0sXG4gICAgZ2V0IHNlbGVjdGlvbigpIHtcbiAgICAgIHJldHVybiBzZWxlY3Rpb25cbiAgICB9LFxuICAgIGdldCBkb2MoKSB7XG4gICAgICByZXR1cm4gZG9jXG4gICAgfSxcbiAgICBnZXQgdHIoKSB7XG4gICAgICBzZWxlY3Rpb24gPSB0cmFuc2FjdGlvbi5zZWxlY3Rpb25cbiAgICAgIGRvYyA9IHRyYW5zYWN0aW9uLmRvY1xuICAgICAgc3RvcmVkTWFya3MgPSB0cmFuc2FjdGlvbi5zdG9yZWRNYXJrc1xuXG4gICAgICByZXR1cm4gdHJhbnNhY3Rpb25cbiAgICB9LFxuICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBFZGl0b3JTdGF0ZSwgVHJhbnNhY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgdHlwZSB7IEVkaXRvciB9IGZyb20gJy4vRWRpdG9yLmpzJ1xuaW1wb3J0IHsgY3JlYXRlQ2hhaW5hYmxlU3RhdGUgfSBmcm9tICcuL2hlbHBlcnMvY3JlYXRlQ2hhaW5hYmxlU3RhdGUuanMnXG5pbXBvcnQgdHlwZSB7XG4gIEFueUNvbW1hbmRzLFxuICBDYW5Db21tYW5kcyxcbiAgQ2hhaW5lZENvbW1hbmRzLFxuICBDb21tYW5kUHJvcHMsXG4gIFNpbmdsZUNvbW1hbmRzLFxufSBmcm9tICcuL3R5cGVzLmpzJ1xuXG5leHBvcnQgY2xhc3MgQ29tbWFuZE1hbmFnZXIge1xuICBlZGl0b3I6IEVkaXRvclxuXG4gIHJhd0NvbW1hbmRzOiBBbnlDb21tYW5kc1xuXG4gIGN1c3RvbVN0YXRlPzogRWRpdG9yU3RhdGVcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogeyBlZGl0b3I6IEVkaXRvcjsgc3RhdGU/OiBFZGl0b3JTdGF0ZSB9KSB7XG4gICAgdGhpcy5lZGl0b3IgPSBwcm9wcy5lZGl0b3JcbiAgICB0aGlzLnJhd0NvbW1hbmRzID0gdGhpcy5lZGl0b3IuZXh0ZW5zaW9uTWFuYWdlci5jb21tYW5kc1xuICAgIHRoaXMuY3VzdG9tU3RhdGUgPSBwcm9wcy5zdGF0ZVxuICB9XG5cbiAgZ2V0IGhhc0N1c3RvbVN0YXRlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuY3VzdG9tU3RhdGVcbiAgfVxuXG4gIGdldCBzdGF0ZSgpOiBFZGl0b3JTdGF0ZSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tU3RhdGUgfHwgdGhpcy5lZGl0b3Iuc3RhdGVcbiAgfVxuXG4gIGdldCBjb21tYW5kcygpOiBTaW5nbGVDb21tYW5kcyB7XG4gICAgY29uc3QgeyByYXdDb21tYW5kcywgZWRpdG9yLCBzdGF0ZSB9ID0gdGhpc1xuICAgIGNvbnN0IHsgdmlldyB9ID0gZWRpdG9yXG4gICAgY29uc3QgeyB0ciB9ID0gc3RhdGVcbiAgICBjb25zdCBwcm9wcyA9IHRoaXMuYnVpbGRQcm9wcyh0cilcblxuICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyhyYXdDb21tYW5kcykubWFwKChbbmFtZSwgY29tbWFuZF0pID0+IHtcbiAgICAgICAgY29uc3QgbWV0aG9kID0gKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBjb21tYW5kKC4uLmFyZ3MpKHByb3BzKVxuXG4gICAgICAgICAgaWYgKCF0ci5nZXRNZXRhKCdwcmV2ZW50RGlzcGF0Y2gnKSAmJiAhdGhpcy5oYXNDdXN0b21TdGF0ZSkge1xuICAgICAgICAgICAgdmlldy5kaXNwYXRjaCh0cilcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gY2FsbGJhY2tcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbbmFtZSwgbWV0aG9kXVxuICAgICAgfSksXG4gICAgKSBhcyB1bmtub3duIGFzIFNpbmdsZUNvbW1hbmRzXG4gIH1cblxuICBnZXQgY2hhaW4oKTogKCkgPT4gQ2hhaW5lZENvbW1hbmRzIHtcbiAgICByZXR1cm4gKCkgPT4gdGhpcy5jcmVhdGVDaGFpbigpXG4gIH1cblxuICBnZXQgY2FuKCk6ICgpID0+IENhbkNvbW1hbmRzIHtcbiAgICByZXR1cm4gKCkgPT4gdGhpcy5jcmVhdGVDYW4oKVxuICB9XG5cbiAgcHVibGljIGNyZWF0ZUNoYWluKHN0YXJ0VHI/OiBUcmFuc2FjdGlvbiwgc2hvdWxkRGlzcGF0Y2ggPSB0cnVlKTogQ2hhaW5lZENvbW1hbmRzIHtcbiAgICBjb25zdCB7IHJhd0NvbW1hbmRzLCBlZGl0b3IsIHN0YXRlIH0gPSB0aGlzXG4gICAgY29uc3QgeyB2aWV3IH0gPSBlZGl0b3JcbiAgICBjb25zdCBjYWxsYmFja3M6IGJvb2xlYW5bXSA9IFtdXG4gICAgY29uc3QgaGFzU3RhcnRUcmFuc2FjdGlvbiA9ICEhc3RhcnRUclxuICAgIGNvbnN0IHRyID0gc3RhcnRUciB8fCBzdGF0ZS50clxuXG4gICAgY29uc3QgcnVuID0gKCkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICAhaGFzU3RhcnRUcmFuc2FjdGlvbiAmJlxuICAgICAgICBzaG91bGREaXNwYXRjaCAmJlxuICAgICAgICAhdHIuZ2V0TWV0YSgncHJldmVudERpc3BhdGNoJykgJiZcbiAgICAgICAgIXRoaXMuaGFzQ3VzdG9tU3RhdGVcbiAgICAgICkge1xuICAgICAgICB2aWV3LmRpc3BhdGNoKHRyKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2FsbGJhY2tzLmV2ZXJ5KGNhbGxiYWNrID0+IGNhbGxiYWNrID09PSB0cnVlKVxuICAgIH1cblxuICAgIGNvbnN0IGNoYWluID0ge1xuICAgICAgLi4uT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBPYmplY3QuZW50cmllcyhyYXdDb21tYW5kcykubWFwKChbbmFtZSwgY29tbWFuZF0pID0+IHtcbiAgICAgICAgICBjb25zdCBjaGFpbmVkQ29tbWFuZCA9ICguLi5hcmdzOiBuZXZlcltdKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwcm9wcyA9IHRoaXMuYnVpbGRQcm9wcyh0ciwgc2hvdWxkRGlzcGF0Y2gpXG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IGNvbW1hbmQoLi4uYXJncykocHJvcHMpXG5cbiAgICAgICAgICAgIGNhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKVxuXG4gICAgICAgICAgICByZXR1cm4gY2hhaW5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gW25hbWUsIGNoYWluZWRDb21tYW5kXVxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgICBydW4sXG4gICAgfSBhcyB1bmtub3duIGFzIENoYWluZWRDb21tYW5kc1xuXG4gICAgcmV0dXJuIGNoYWluXG4gIH1cblxuICBwdWJsaWMgY3JlYXRlQ2FuKHN0YXJ0VHI/OiBUcmFuc2FjdGlvbik6IENhbkNvbW1hbmRzIHtcbiAgICBjb25zdCB7IHJhd0NvbW1hbmRzLCBzdGF0ZSB9ID0gdGhpc1xuICAgIGNvbnN0IGRpc3BhdGNoID0gZmFsc2VcbiAgICBjb25zdCB0ciA9IHN0YXJ0VHIgfHwgc3RhdGUudHJcbiAgICBjb25zdCBwcm9wcyA9IHRoaXMuYnVpbGRQcm9wcyh0ciwgZGlzcGF0Y2gpXG4gICAgY29uc3QgZm9ybWF0dGVkQ29tbWFuZHMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyhyYXdDb21tYW5kcykubWFwKChbbmFtZSwgY29tbWFuZF0pID0+IHtcbiAgICAgICAgcmV0dXJuIFtuYW1lLCAoLi4uYXJnczogbmV2ZXJbXSkgPT4gY29tbWFuZCguLi5hcmdzKSh7IC4uLnByb3BzLCBkaXNwYXRjaDogdW5kZWZpbmVkIH0pXVxuICAgICAgfSksXG4gICAgKSBhcyB1bmtub3duIGFzIFNpbmdsZUNvbW1hbmRzXG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uZm9ybWF0dGVkQ29tbWFuZHMsXG4gICAgICBjaGFpbjogKCkgPT4gdGhpcy5jcmVhdGVDaGFpbih0ciwgZGlzcGF0Y2gpLFxuICAgIH0gYXMgQ2FuQ29tbWFuZHNcbiAgfVxuXG4gIHB1YmxpYyBidWlsZFByb3BzKHRyOiBUcmFuc2FjdGlvbiwgc2hvdWxkRGlzcGF0Y2ggPSB0cnVlKTogQ29tbWFuZFByb3BzIHtcbiAgICBjb25zdCB7IHJhd0NvbW1hbmRzLCBlZGl0b3IsIHN0YXRlIH0gPSB0aGlzXG4gICAgY29uc3QgeyB2aWV3IH0gPSBlZGl0b3JcblxuICAgIGNvbnN0IHByb3BzOiBDb21tYW5kUHJvcHMgPSB7XG4gICAgICB0cixcbiAgICAgIGVkaXRvcixcbiAgICAgIHZpZXcsXG4gICAgICBzdGF0ZTogY3JlYXRlQ2hhaW5hYmxlU3RhdGUoe1xuICAgICAgICBzdGF0ZSxcbiAgICAgICAgdHJhbnNhY3Rpb246IHRyLFxuICAgICAgfSksXG4gICAgICBkaXNwYXRjaDogc2hvdWxkRGlzcGF0Y2ggPyAoKSA9PiB1bmRlZmluZWQgOiB1bmRlZmluZWQsXG4gICAgICBjaGFpbjogKCkgPT4gdGhpcy5jcmVhdGVDaGFpbih0ciwgc2hvdWxkRGlzcGF0Y2gpLFxuICAgICAgY2FuOiAoKSA9PiB0aGlzLmNyZWF0ZUNhbih0ciksXG4gICAgICBnZXQgY29tbWFuZHMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgT2JqZWN0LmVudHJpZXMocmF3Q29tbWFuZHMpLm1hcCgoW25hbWUsIGNvbW1hbmRdKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gW25hbWUsICguLi5hcmdzOiBuZXZlcltdKSA9PiBjb21tYW5kKC4uLmFyZ3MpKHByb3BzKV1cbiAgICAgICAgICB9KSxcbiAgICAgICAgKSBhcyB1bmtub3duIGFzIFNpbmdsZUNvbW1hbmRzXG4gICAgICB9LFxuICAgIH1cblxuICAgIHJldHVybiBwcm9wc1xuICB9XG59XG4iLCAiZXhwb3J0ICogZnJvbSAnLi9ibHVyLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9jbGVhckNvbnRlbnQuanMnXG5leHBvcnQgKiBmcm9tICcuL2NsZWFyTm9kZXMuanMnXG5leHBvcnQgKiBmcm9tICcuL2NvbW1hbmQuanMnXG5leHBvcnQgKiBmcm9tICcuL2NyZWF0ZVBhcmFncmFwaE5lYXIuanMnXG5leHBvcnQgKiBmcm9tICcuL2N1dC5qcydcbmV4cG9ydCAqIGZyb20gJy4vZGVsZXRlQ3VycmVudE5vZGUuanMnXG5leHBvcnQgKiBmcm9tICcuL2RlbGV0ZU5vZGUuanMnXG5leHBvcnQgKiBmcm9tICcuL2RlbGV0ZVJhbmdlLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9kZWxldGVTZWxlY3Rpb24uanMnXG5leHBvcnQgKiBmcm9tICcuL2VudGVyLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9leGl0Q29kZS5qcydcbmV4cG9ydCAqIGZyb20gJy4vZXh0ZW5kTWFya1JhbmdlLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9maXJzdC5qcydcbmV4cG9ydCAqIGZyb20gJy4vZm9jdXMuanMnXG5leHBvcnQgKiBmcm9tICcuL2ZvckVhY2guanMnXG5leHBvcnQgKiBmcm9tICcuL2luc2VydENvbnRlbnQuanMnXG5leHBvcnQgKiBmcm9tICcuL2luc2VydENvbnRlbnRBdC5qcydcbmV4cG9ydCAqIGZyb20gJy4vam9pbi5qcydcbmV4cG9ydCAqIGZyb20gJy4vam9pbkl0ZW1CYWNrd2FyZC5qcydcbmV4cG9ydCAqIGZyb20gJy4vam9pbkl0ZW1Gb3J3YXJkLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9qb2luVGV4dGJsb2NrQmFja3dhcmQuanMnXG5leHBvcnQgKiBmcm9tICcuL2pvaW5UZXh0YmxvY2tGb3J3YXJkLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9rZXlib2FyZFNob3J0Y3V0LmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9saWZ0LmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9saWZ0RW1wdHlCbG9jay5qcydcbmV4cG9ydCAqIGZyb20gJy4vbGlmdExpc3RJdGVtLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9uZXdsaW5lSW5Db2RlLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9yZXNldEF0dHJpYnV0ZXMuanMnXG5leHBvcnQgKiBmcm9tICcuL3Njcm9sbEludG9WaWV3LmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9zZWxlY3RBbGwuanMnXG5leHBvcnQgKiBmcm9tICcuL3NlbGVjdE5vZGVCYWNrd2FyZC5qcydcbmV4cG9ydCAqIGZyb20gJy4vc2VsZWN0Tm9kZUZvcndhcmQuanMnXG5leHBvcnQgKiBmcm9tICcuL3NlbGVjdFBhcmVudE5vZGUuanMnXG5leHBvcnQgKiBmcm9tICcuL3NlbGVjdFRleHRibG9ja0VuZC5qcydcbmV4cG9ydCAqIGZyb20gJy4vc2VsZWN0VGV4dGJsb2NrU3RhcnQuanMnXG5leHBvcnQgKiBmcm9tICcuL3NldENvbnRlbnQuanMnXG5leHBvcnQgKiBmcm9tICcuL3NldE1hcmsuanMnXG5leHBvcnQgKiBmcm9tICcuL3NldE1ldGEuanMnXG5leHBvcnQgKiBmcm9tICcuL3NldE5vZGUuanMnXG5leHBvcnQgKiBmcm9tICcuL3NldE5vZGVTZWxlY3Rpb24uanMnXG5leHBvcnQgKiBmcm9tICcuL3NldFRleHREaXJlY3Rpb24uanMnXG5leHBvcnQgKiBmcm9tICcuL3NldFRleHRTZWxlY3Rpb24uanMnXG5leHBvcnQgKiBmcm9tICcuL3NpbmtMaXN0SXRlbS5qcydcbmV4cG9ydCAqIGZyb20gJy4vc3BsaXRCbG9jay5qcydcbmV4cG9ydCAqIGZyb20gJy4vc3BsaXRMaXN0SXRlbS5qcydcbmV4cG9ydCAqIGZyb20gJy4vdG9nZ2xlTGlzdC5qcydcbmV4cG9ydCAqIGZyb20gJy4vdG9nZ2xlTWFyay5qcydcbmV4cG9ydCAqIGZyb20gJy4vdG9nZ2xlTm9kZS5qcydcbmV4cG9ydCAqIGZyb20gJy4vdG9nZ2xlV3JhcC5qcydcbmV4cG9ydCAqIGZyb20gJy4vdW5kb0lucHV0UnVsZS5qcydcbmV4cG9ydCAqIGZyb20gJy4vdW5zZXRBbGxNYXJrcy5qcydcbmV4cG9ydCAqIGZyb20gJy4vdW5zZXRNYXJrLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi91bnNldFRleHREaXJlY3Rpb24uanMnXG5leHBvcnQgKiBmcm9tICcuL3VwZGF0ZUF0dHJpYnV0ZXMuanMnXG5leHBvcnQgKiBmcm9tICcuL3dyYXBJbi5qcydcbmV4cG9ydCAqIGZyb20gJy4vd3JhcEluTGlzdC5qcydcbiIsICJpbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBibHVyOiB7XG4gICAgICAvKipcbiAgICAgICAqIFJlbW92ZXMgZm9jdXMgZnJvbSB0aGUgZWRpdG9yLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmJsdXIoKVxuICAgICAgICovXG4gICAgICBibHVyOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBibHVyOiBSYXdDb21tYW5kc1snYmx1ciddID1cbiAgKCkgPT5cbiAgKHsgZWRpdG9yLCB2aWV3IH0pID0+IHtcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgaWYgKCFlZGl0b3IuaXNEZXN0cm95ZWQpIHtcbiAgICAgICAgOyh2aWV3LmRvbSBhcyBIVE1MRWxlbWVudCkuYmx1cigpXG5cbiAgICAgICAgLy8gQnJvd3NlcnMgc2hvdWxkIHJlbW92ZSB0aGUgY2FyZXQgb24gYmx1ciBidXQgc2FmYXJpIGRvZXMgbm90LlxuICAgICAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS91ZWJlcmRvc2lzL3RpcHRhcC9pc3N1ZXMvMjQwNVxuICAgICAgICB3aW5kb3c/LmdldFNlbGVjdGlvbigpPy5yZW1vdmVBbGxSYW5nZXMoKVxuICAgICAgfVxuICAgIH0pXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG4iLCAiaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgY2xlYXJDb250ZW50OiB7XG4gICAgICAvKipcbiAgICAgICAqIENsZWFyIHRoZSB3aG9sZSBkb2N1bWVudC5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5jbGVhckNvbnRlbnQoKVxuICAgICAgICovXG4gICAgICBjbGVhckNvbnRlbnQ6IChcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgdG8gZW1pdCBhbiB1cGRhdGUgZXZlbnQuXG4gICAgICAgICAqIEBkZWZhdWx0IHRydWVcbiAgICAgICAgICovXG4gICAgICAgIGVtaXRVcGRhdGU/OiBib29sZWFuLFxuICAgICAgKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjbGVhckNvbnRlbnQ6IFJhd0NvbW1hbmRzWydjbGVhckNvbnRlbnQnXSA9XG4gIChlbWl0VXBkYXRlID0gdHJ1ZSkgPT5cbiAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgIHJldHVybiBjb21tYW5kcy5zZXRDb250ZW50KCcnLCB7IGVtaXRVcGRhdGUgfSlcbiAgfVxuIiwgImltcG9ydCB7IGxpZnRUYXJnZXQgfSBmcm9tICdAdGlwdGFwL3BtL3RyYW5zZm9ybSdcblxuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgY2xlYXJOb2Rlczoge1xuICAgICAgLyoqXG4gICAgICAgKiBOb3JtYWxpemUgbm9kZXMgdG8gYSBzaW1wbGUgcGFyYWdyYXBoLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmNsZWFyTm9kZXMoKVxuICAgICAgICovXG4gICAgICBjbGVhck5vZGVzOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjbGVhck5vZGVzOiBSYXdDb21tYW5kc1snY2xlYXJOb2RlcyddID1cbiAgKCkgPT5cbiAgKHsgc3RhdGUsIHRyLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IHRyXG4gICAgY29uc3QgeyByYW5nZXMgfSA9IHNlbGVjdGlvblxuXG4gICAgaWYgKCFkaXNwYXRjaCkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICByYW5nZXMuZm9yRWFjaCgoeyAkZnJvbSwgJHRvIH0pID0+IHtcbiAgICAgIHN0YXRlLmRvYy5ub2Rlc0JldHdlZW4oJGZyb20ucG9zLCAkdG8ucG9zLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgIGlmIChub2RlLnR5cGUuaXNUZXh0KSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IGRvYywgbWFwcGluZyB9ID0gdHJcbiAgICAgICAgY29uc3QgJG1hcHBlZEZyb20gPSBkb2MucmVzb2x2ZShtYXBwaW5nLm1hcChwb3MpKVxuICAgICAgICBjb25zdCAkbWFwcGVkVG8gPSBkb2MucmVzb2x2ZShtYXBwaW5nLm1hcChwb3MgKyBub2RlLm5vZGVTaXplKSlcbiAgICAgICAgY29uc3Qgbm9kZVJhbmdlID0gJG1hcHBlZEZyb20uYmxvY2tSYW5nZSgkbWFwcGVkVG8pXG5cbiAgICAgICAgaWYgKCFub2RlUmFuZ2UpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRhcmdldExpZnREZXB0aCA9IGxpZnRUYXJnZXQobm9kZVJhbmdlKVxuXG4gICAgICAgIGlmIChub2RlLnR5cGUuaXNUZXh0YmxvY2spIHtcbiAgICAgICAgICBjb25zdCB7IGRlZmF1bHRUeXBlIH0gPSAkbWFwcGVkRnJvbS5wYXJlbnQuY29udGVudE1hdGNoQXQoJG1hcHBlZEZyb20uaW5kZXgoKSlcblxuICAgICAgICAgIHRyLnNldE5vZGVNYXJrdXAobm9kZVJhbmdlLnN0YXJ0LCBkZWZhdWx0VHlwZSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0YXJnZXRMaWZ0RGVwdGggfHwgdGFyZ2V0TGlmdERlcHRoID09PSAwKSB7XG4gICAgICAgICAgdHIubGlmdChub2RlUmFuZ2UsIHRhcmdldExpZnREZXB0aClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9KVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgQ29tbWFuZCwgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGNvbW1hbmQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogRGVmaW5lIGEgY29tbWFuZCBpbmxpbmUuXG4gICAgICAgKiBAcGFyYW0gZm4gVGhlIGNvbW1hbmQgZnVuY3Rpb24uXG4gICAgICAgKiBAZXhhbXBsZVxuICAgICAgICogZWRpdG9yLmNvbW1hbmRzLmNvbW1hbmQoKHsgdHIsIHN0YXRlIH0pID0+IHtcbiAgICAgICAqICAgLi4uXG4gICAgICAgKiAgIHJldHVybiB0cnVlXG4gICAgICAgKiB9KVxuICAgICAgICovXG4gICAgICBjb21tYW5kOiAoZm46IChwcm9wczogUGFyYW1ldGVyczxDb21tYW5kPlswXSkgPT4gYm9vbGVhbikgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgY29tbWFuZDogUmF3Q29tbWFuZHNbJ2NvbW1hbmQnXSA9IGZuID0+IHByb3BzID0+IHtcbiAgcmV0dXJuIGZuKHByb3BzKVxufVxuIiwgImltcG9ydCB7IGNyZWF0ZVBhcmFncmFwaE5lYXIgYXMgb3JpZ2luYWxDcmVhdGVQYXJhZ3JhcGhOZWFyIH0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcblxuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgY3JlYXRlUGFyYWdyYXBoTmVhcjoge1xuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGUgYSBwYXJhZ3JhcGggbmVhcmJ5LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmNyZWF0ZVBhcmFncmFwaE5lYXIoKVxuICAgICAgICovXG4gICAgICBjcmVhdGVQYXJhZ3JhcGhOZWFyOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYXJhZ3JhcGhOZWFyOiBSYXdDb21tYW5kc1snY3JlYXRlUGFyYWdyYXBoTmVhciddID1cbiAgKCkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICByZXR1cm4gb3JpZ2luYWxDcmVhdGVQYXJhZ3JhcGhOZWFyKHN0YXRlLCBkaXNwYXRjaClcbiAgfVxuIiwgImltcG9ydCB7IFRleHRTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBjdXQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogQ3V0cyBjb250ZW50IGZyb20gYSByYW5nZSBhbmQgaW5zZXJ0cyBpdCBhdCBhIGdpdmVuIHBvc2l0aW9uLlxuICAgICAgICogQHBhcmFtIHJhbmdlIFRoZSByYW5nZSB0byBjdXQuXG4gICAgICAgKiBAcGFyYW0gcmFuZ2UuZnJvbSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHJhbmdlLlxuICAgICAgICogQHBhcmFtIHJhbmdlLnRvIFRoZSBlbmQgcG9zaXRpb24gb2YgdGhlIHJhbmdlLlxuICAgICAgICogQHBhcmFtIHRhcmdldFBvcyBUaGUgcG9zaXRpb24gdG8gaW5zZXJ0IHRoZSBjb250ZW50IGF0LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmN1dCh7IGZyb206IDEsIHRvOiAzIH0sIDUpXG4gICAgICAgKi9cbiAgICAgIGN1dDogKHsgZnJvbSwgdG8gfTogeyBmcm9tOiBudW1iZXI7IHRvOiBudW1iZXIgfSwgdGFyZ2V0UG9zOiBudW1iZXIpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGN1dDogUmF3Q29tbWFuZHNbJ2N1dCddID1cbiAgKG9yaWdpblJhbmdlLCB0YXJnZXRQb3MpID0+XG4gICh7IGVkaXRvciwgdHIgfSkgPT4ge1xuICAgIGNvbnN0IHsgc3RhdGUgfSA9IGVkaXRvclxuXG4gICAgY29uc3QgY29udGVudFNsaWNlID0gc3RhdGUuZG9jLnNsaWNlKG9yaWdpblJhbmdlLmZyb20sIG9yaWdpblJhbmdlLnRvKVxuXG4gICAgdHIuZGVsZXRlUmFuZ2Uob3JpZ2luUmFuZ2UuZnJvbSwgb3JpZ2luUmFuZ2UudG8pXG4gICAgY29uc3QgbmV3UG9zID0gdHIubWFwcGluZy5tYXAodGFyZ2V0UG9zKVxuXG4gICAgdHIuaW5zZXJ0KG5ld1BvcywgY29udGVudFNsaWNlLmNvbnRlbnQpXG5cbiAgICB0ci5zZXRTZWxlY3Rpb24obmV3IFRleHRTZWxlY3Rpb24odHIuZG9jLnJlc29sdmUoTWF0aC5tYXgobmV3UG9zIC0gMSwgMCkpKSlcblxuICAgIHJldHVybiB0cnVlXG4gIH1cbiIsICJpbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBkZWxldGVDdXJyZW50Tm9kZToge1xuICAgICAgLyoqXG4gICAgICAgKiBEZWxldGUgdGhlIG5vZGUgdGhhdCBjdXJyZW50bHkgaGFzIHRoZSBzZWxlY3Rpb24gYW5jaG9yLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmRlbGV0ZUN1cnJlbnROb2RlKClcbiAgICAgICAqL1xuICAgICAgZGVsZXRlQ3VycmVudE5vZGU6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGRlbGV0ZUN1cnJlbnROb2RlOiBSYXdDb21tYW5kc1snZGVsZXRlQ3VycmVudE5vZGUnXSA9XG4gICgpID0+XG4gICh7IHRyLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IHRyXG4gICAgY29uc3QgY3VycmVudE5vZGUgPSBzZWxlY3Rpb24uJGFuY2hvci5ub2RlKClcblxuICAgIC8vIGlmIHRoZXJlIGlzIGNvbnRlbnQgaW5zaWRlIHRoZSBjdXJyZW50IG5vZGUsIGJyZWFrIG91dCBvZiB0aGlzIGNvbW1hbmRcbiAgICBpZiAoY3VycmVudE5vZGUuY29udGVudC5zaXplID4gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgY29uc3QgJHBvcyA9IHRyLnNlbGVjdGlvbi4kYW5jaG9yXG5cbiAgICBmb3IgKGxldCBkZXB0aCA9ICRwb3MuZGVwdGg7IGRlcHRoID4gMDsgZGVwdGggLT0gMSkge1xuICAgICAgY29uc3Qgbm9kZSA9ICRwb3Mubm9kZShkZXB0aClcblxuICAgICAgaWYgKG5vZGUudHlwZSA9PT0gY3VycmVudE5vZGUudHlwZSkge1xuICAgICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgICBjb25zdCBmcm9tID0gJHBvcy5iZWZvcmUoZGVwdGgpXG4gICAgICAgICAgY29uc3QgdG8gPSAkcG9zLmFmdGVyKGRlcHRoKVxuXG4gICAgICAgICAgdHIuZGVsZXRlKGZyb20sIHRvKS5zY3JvbGxJbnRvVmlldygpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlVHlwZSwgU2NoZW1hIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5vZGVUeXBlKG5hbWVPclR5cGU6IHN0cmluZyB8IE5vZGVUeXBlLCBzY2hlbWE6IFNjaGVtYSk6IE5vZGVUeXBlIHtcbiAgaWYgKHR5cGVvZiBuYW1lT3JUeXBlID09PSAnc3RyaW5nJykge1xuICAgIGlmICghc2NoZW1hLm5vZGVzW25hbWVPclR5cGVdKSB7XG4gICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgYFRoZXJlIGlzIG5vIG5vZGUgdHlwZSBuYW1lZCAnJHtuYW1lT3JUeXBlfScuIE1heWJlIHlvdSBmb3Jnb3QgdG8gYWRkIHRoZSBleHRlbnNpb24/YCxcbiAgICAgIClcbiAgICB9XG5cbiAgICByZXR1cm4gc2NoZW1hLm5vZGVzW25hbWVPclR5cGVdXG4gIH1cblxuICByZXR1cm4gbmFtZU9yVHlwZVxufVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBkZWxldGVOb2RlOiB7XG4gICAgICAvKipcbiAgICAgICAqIERlbGV0ZSBhIG5vZGUgd2l0aCBhIGdpdmVuIHR5cGUgb3IgbmFtZS5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuZGVsZXRlTm9kZSgncGFyYWdyYXBoJylcbiAgICAgICAqL1xuICAgICAgZGVsZXRlTm9kZTogKHR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBkZWxldGVOb2RlOiBSYXdDb21tYW5kc1snZGVsZXRlTm9kZSddID1cbiAgdHlwZU9yTmFtZSA9PlxuICAoeyB0ciwgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICBjb25zdCB0eXBlID0gZ2V0Tm9kZVR5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuICAgIGNvbnN0ICRwb3MgPSB0ci5zZWxlY3Rpb24uJGFuY2hvclxuXG4gICAgZm9yIChsZXQgZGVwdGggPSAkcG9zLmRlcHRoOyBkZXB0aCA+IDA7IGRlcHRoIC09IDEpIHtcbiAgICAgIGNvbnN0IG5vZGUgPSAkcG9zLm5vZGUoZGVwdGgpXG5cbiAgICAgIGlmIChub2RlLnR5cGUgPT09IHR5cGUpIHtcbiAgICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgICAgY29uc3QgZnJvbSA9ICRwb3MuYmVmb3JlKGRlcHRoKVxuICAgICAgICAgIGNvbnN0IHRvID0gJHBvcy5hZnRlcihkZXB0aClcblxuICAgICAgICAgIHRyLmRlbGV0ZShmcm9tLCB0bykuc2Nyb2xsSW50b1ZpZXcoKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgUmFuZ2UsIFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBkZWxldGVSYW5nZToge1xuICAgICAgLyoqXG4gICAgICAgKiBEZWxldGUgYSBnaXZlbiByYW5nZS5cbiAgICAgICAqIEBwYXJhbSByYW5nZSBUaGUgcmFuZ2UgdG8gZGVsZXRlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmRlbGV0ZVJhbmdlKHsgZnJvbTogMSwgdG86IDMgfSlcbiAgICAgICAqL1xuICAgICAgZGVsZXRlUmFuZ2U6IChyYW5nZTogUmFuZ2UpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGRlbGV0ZVJhbmdlOiBSYXdDb21tYW5kc1snZGVsZXRlUmFuZ2UnXSA9XG4gIHJhbmdlID0+XG4gICh7IHRyLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgY29uc3QgeyBmcm9tLCB0byB9ID0gcmFuZ2VcblxuICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgdHIuZGVsZXRlKGZyb20sIHRvKVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH1cbiIsICJpbXBvcnQgdHlwZSB7IFJlc29sdmVkUG9zLCBTY2hlbWEgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbi8qKlxuICogQ2hlY2sgaWYgYSBub2RlIGhhcyB0ZXh0IGNvbnRlbnQgYmFzZWQgb24gaXRzIGNvbnRlbnQgc3BlY2lmaWNhdGlvbi5cbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgbm9kZSdzIGNvbnRlbnQgc3BlYyBtYXRjaGVzIHRleHQqIG9yIHRleHQrIHBhdHRlcm5zLlxuICovXG5jb25zdCBoYXNUZXh0Q29udGVudCA9IChub2RlU3BlYzogeyBjb250ZW50Pzogc3RyaW5nIH0pOiBib29sZWFuID0+IHtcbiAgaWYgKCFub2RlU3BlYy5jb250ZW50KSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgY29uc3QgdGV4dFJlZ2V4ID0gL150ZXh0KFxcKnxcXCspL1xuICByZXR1cm4gdGV4dFJlZ2V4LnRlc3Qobm9kZVNwZWMuY29udGVudClcbn1cblxuLyoqXG4gKiBFeHBhbmQgc2VsZWN0aW9uIHBvc2l0aW9uIGZvciBhIHNwZWNpZmljIHNpZGUgKGxlZnQgb3IgcmlnaHQpIHRvIGhhbmRsZSBpbmxpbmUgdGV4dCBub2Rlcy5cbiAqIFRoaXMgZnVuY3Rpb24gY2hlY2tzIGlmIHRoZSBwb3NpdGlvbiBpcyB3aXRoaW4gYW4gaW5saW5lIG5vZGUgd2l0aCB0ZXh0IGNvbnRlbnQgYW5kXG4gKiBleHBhbmRzIGl0IHRvIGluY2x1ZGUgdGhlIGVudGlyZSBub2RlIGJvdW5kYXJpZXMgZm9yIHByb3BlciBkZWxldGlvbi5cbiAqIEBwYXJhbSAkcG9zIC0gVGhlIHJlc29sdmVkIHBvc2l0aW9uIHRvIGV4cGFuZFxuICogQHBhcmFtIHNjaGVtYSAtIFRoZSBQcm9zZU1pcnJvciBzY2hlbWFcbiAqIEBwYXJhbSBzaWRlIC0gV2hpY2ggc2lkZSB0byBleHBhbmQgKCdsZWZ0JyBvciAncmlnaHQnKVxuICogQHJldHVybnMgVGhlIGV4cGFuZGVkIHBvc2l0aW9uIGZvciBkZWxldGlvblxuICovXG5jb25zdCBleHBhbmRTZWxlY3Rpb25Gb3JTaWRlID0gKFxuICAkcG9zOiBSZXNvbHZlZFBvcyxcbiAgc2NoZW1hOiBTY2hlbWEsXG4gIHNpZGU6ICdsZWZ0JyB8ICdyaWdodCcsXG4pOiBudW1iZXIgPT4ge1xuICBpZiAoISRwb3MucGFyZW50LmlzSW5saW5lKSB7XG4gICAgcmV0dXJuICRwb3MucG9zXG4gIH1cblxuICBpZiAoKHNpZGUgPT09ICdsZWZ0JyAmJiAkcG9zLnBvcyA+ICRwb3Muc3RhcnQoKSkgfHwgKHNpZGUgPT09ICdyaWdodCcgJiYgJHBvcy5wb3MgPCAkcG9zLmVuZCgpKSkge1xuICAgIHJldHVybiAkcG9zLnBvc1xuICB9XG5cbiAgY29uc3QgcGFyZW50Q29udGVudCA9IHNjaGVtYS5ub2Rlc1skcG9zLnBhcmVudC50eXBlLm5hbWVdLnNwZWNcbiAgaWYgKCFoYXNUZXh0Q29udGVudChwYXJlbnRDb250ZW50KSkge1xuICAgIHJldHVybiAkcG9zLnBvc1xuICB9XG5cbiAgcmV0dXJuIHNpZGUgPT09ICdsZWZ0JyA/ICRwb3Muc3RhcnQoKSAtIDEgOiAkcG9zLmVuZCgpICsgMVxufVxuXG4vKipcbiAqIEV4cGFuZCBzZWxlY3Rpb24gcmFuZ2UgdG8gcHJvcGVybHkgaGFuZGxlIGRlbGV0aW9uIG9mIGlubGluZSB0ZXh0IG5vZGVzLlxuICogSW5saW5lIHRleHQgbm9kZXMgZG9uJ3QgY29sbGFwc2UgY29ycmVjdGx5IHdoZW4gdGV4dCBpbnNpZGUgaXMgZGVsZXRlZCxcbiAqIHNvIHdlIG5lZWQgdG8gZXhwYW5kIHRoZSBzZWxlY3Rpb24gdG8gaW5jbHVkZSB0aGUgZW50aXJlIG5vZGUuXG4gKiBTZWU6IGh0dHBzOi8vY29kZS5oYXZlcmJla2UuYmVybGluL3Byb3NlbWlycm9yL3Byb3NlbWlycm9yL2lzc3Vlcy8xMzY1XG4gKi9cbmNvbnN0IGV4cGFuZFNlbGVjdGlvbkZvcklubGluZVRleHQgPSAoXG4gICRmcm9tOiBSZXNvbHZlZFBvcyxcbiAgJHRvOiBSZXNvbHZlZFBvcyxcbiAgc2NoZW1hOiBTY2hlbWEsXG4pOiB7IGZyb206IG51bWJlcjsgdG86IG51bWJlciB9ID0+IHtcbiAgY29uc3QgZnJvbSA9IGV4cGFuZFNlbGVjdGlvbkZvclNpZGUoJGZyb20sIHNjaGVtYSwgJ2xlZnQnKVxuICBjb25zdCB0byA9IGV4cGFuZFNlbGVjdGlvbkZvclNpZGUoJHRvLCBzY2hlbWEsICdyaWdodCcpXG5cbiAgcmV0dXJuIHsgZnJvbSwgdG8gfVxufVxuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgZGVsZXRlU2VsZWN0aW9uOiB7XG4gICAgICAvKipcbiAgICAgICAqIERlbGV0ZSB0aGUgc2VsZWN0aW9uLCBpZiB0aGVyZSBpcyBvbmUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuZGVsZXRlU2VsZWN0aW9uKClcbiAgICAgICAqL1xuICAgICAgZGVsZXRlU2VsZWN0aW9uOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBkZWxldGVTZWxlY3Rpb246IFJhd0NvbW1hbmRzWydkZWxldGVTZWxlY3Rpb24nXSA9XG4gICgpID0+XG4gICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgY29uc3QgeyAkZnJvbSwgJHRvIH0gPSBzdGF0ZS5zZWxlY3Rpb25cbiAgICBpZiAoc3RhdGUuc2VsZWN0aW9uLmVtcHR5KSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBjb25zdCB7IGZyb20sIHRvIH0gPSBleHBhbmRTZWxlY3Rpb25Gb3JJbmxpbmVUZXh0KCRmcm9tLCAkdG8sIHN0YXRlLnNjaGVtYSlcblxuICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgc3RhdGUudHIuZGVsZXRlUmFuZ2UoZnJvbSwgdG8pLnNjcm9sbEludG9WaWV3KClcbiAgICAgIGRpc3BhdGNoKHN0YXRlLnRyKVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH1cbiIsICJpbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBlbnRlcjoge1xuICAgICAgLyoqXG4gICAgICAgKiBUcmlnZ2VyIGVudGVyLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmVudGVyKClcbiAgICAgICAqL1xuICAgICAgZW50ZXI6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGVudGVyOiBSYXdDb21tYW5kc1snZW50ZXInXSA9XG4gICgpID0+XG4gICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICByZXR1cm4gY29tbWFuZHMua2V5Ym9hcmRTaG9ydGN1dCgnRW50ZXInKVxuICB9XG4iLCAiaW1wb3J0IHsgZXhpdENvZGUgYXMgb3JpZ2luYWxFeGl0Q29kZSB9IGZyb20gJ0B0aXB0YXAvcG0vY29tbWFuZHMnXG5cbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGV4aXRDb2RlOiB7XG4gICAgICAvKipcbiAgICAgICAqIEV4aXQgZnJvbSBhIGNvZGUgYmxvY2suXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuZXhpdENvZGUoKVxuICAgICAgICovXG4gICAgICBleGl0Q29kZTogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZXhpdENvZGU6IFJhd0NvbW1hbmRzWydleGl0Q29kZSddID1cbiAgKCkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICByZXR1cm4gb3JpZ2luYWxFeGl0Q29kZShzdGF0ZSwgZGlzcGF0Y2gpXG4gIH1cbiIsICJpbXBvcnQgdHlwZSB7IE1hcmtUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IFRleHRTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBnZXRNYXJrUmFuZ2UgfSBmcm9tICcuLi9oZWxwZXJzL2dldE1hcmtSYW5nZS5qcydcbmltcG9ydCB7IGdldE1hcmtUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXRNYXJrVHlwZS5qcydcbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGV4dGVuZE1hcmtSYW5nZToge1xuICAgICAgLyoqXG4gICAgICAgKiBFeHRlbmRzIHRoZSB0ZXh0IHNlbGVjdGlvbiB0byB0aGUgY3VycmVudCBtYXJrIGJ5IHR5cGUgb3IgbmFtZS5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG1hcmsuXG4gICAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyB0byBtYXRjaCBhZ2FpbnN0LlxuICAgICAgICogSWYgbm90IHByb3ZpZGVkLCBvbmx5IHRoZSBmaXJzdCBtYXJrIGF0IHRoZSBwb3NpdGlvbiB3aWxsIGJlIG1hdGNoZWQuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuZXh0ZW5kTWFya1JhbmdlKCdib2xkJylcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5leHRlbmRNYXJrUmFuZ2UoJ21lbnRpb24nLCB7IHVzZXJJZDogXCIxXCIgfSlcbiAgICAgICAqL1xuICAgICAgZXh0ZW5kTWFya1JhbmdlOiAoXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBtYXJrLlxuICAgICAgICAgKi9cbiAgICAgICAgdHlwZU9yTmFtZTogc3RyaW5nIHwgTWFya1R5cGUsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBtYXJrLlxuICAgICAgICAgKi9cbiAgICAgICAgYXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGV4dGVuZE1hcmtSYW5nZTogUmF3Q29tbWFuZHNbJ2V4dGVuZE1hcmtSYW5nZSddID1cbiAgKHR5cGVPck5hbWUsIGF0dHJpYnV0ZXMpID0+XG4gICh7IHRyLCBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgIGNvbnN0IHR5cGUgPSBnZXRNYXJrVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gICAgY29uc3QgeyBkb2MsIHNlbGVjdGlvbiB9ID0gdHJcbiAgICBjb25zdCB7ICRmcm9tLCBmcm9tLCB0byB9ID0gc2VsZWN0aW9uXG5cbiAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgIGNvbnN0IHJhbmdlID0gZ2V0TWFya1JhbmdlKCRmcm9tLCB0eXBlLCBhdHRyaWJ1dGVzKVxuXG4gICAgICBpZiAocmFuZ2UgJiYgcmFuZ2UuZnJvbSA8PSBmcm9tICYmIHJhbmdlLnRvID49IHRvKSB7XG4gICAgICAgIGNvbnN0IG5ld1NlbGVjdGlvbiA9IFRleHRTZWxlY3Rpb24uY3JlYXRlKGRvYywgcmFuZ2UuZnJvbSwgcmFuZ2UudG8pXG5cbiAgICAgICAgdHIuc2V0U2VsZWN0aW9uKG5ld1NlbGVjdGlvbilcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGlzUmVnRXhwKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBSZWdFeHAge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSdcbn1cbiIsICJpbXBvcnQgeyBpc1JlZ0V4cCB9IGZyb20gJy4vaXNSZWdFeHAuanMnXG5cbi8qKlxuICogQ2hlY2sgaWYgb2JqZWN0MSBpbmNsdWRlcyBvYmplY3QyXG4gKiBAcGFyYW0gb2JqZWN0MSBPYmplY3RcbiAqIEBwYXJhbSBvYmplY3QyIE9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gb2JqZWN0SW5jbHVkZXMoXG4gIG9iamVjdDE6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIG9iamVjdDI6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIG9wdGlvbnM6IHsgc3RyaWN0OiBib29sZWFuIH0gPSB7IHN0cmljdDogdHJ1ZSB9LFxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QyKVxuXG4gIGlmICgha2V5cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgcmV0dXJuIGtleXMuZXZlcnkoa2V5ID0+IHtcbiAgICBpZiAob3B0aW9ucy5zdHJpY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QyW2tleV0gPT09IG9iamVjdDFba2V5XVxuICAgIH1cblxuICAgIGlmIChpc1JlZ0V4cChvYmplY3QyW2tleV0pKSB7XG4gICAgICByZXR1cm4gb2JqZWN0MltrZXldLnRlc3Qob2JqZWN0MVtrZXldKVxuICAgIH1cblxuICAgIHJldHVybiBvYmplY3QyW2tleV0gPT09IG9iamVjdDFba2V5XVxuICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgTWFyayBhcyBQcm9zZU1pcnJvck1hcmssIE1hcmtUeXBlLCBSZXNvbHZlZFBvcyB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB0eXBlIHsgUmFuZ2UgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IG9iamVjdEluY2x1ZGVzIH0gZnJvbSAnLi4vdXRpbGl0aWVzL29iamVjdEluY2x1ZGVzLmpzJ1xuXG5mdW5jdGlvbiBmaW5kTWFya0luU2V0KFxuICBtYXJrczogUHJvc2VNaXJyb3JNYXJrW10sXG4gIHR5cGU6IE1hcmtUeXBlLFxuICBhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge30sXG4pOiBQcm9zZU1pcnJvck1hcmsgfCB1bmRlZmluZWQge1xuICByZXR1cm4gbWFya3MuZmluZChpdGVtID0+IHtcbiAgICByZXR1cm4gKFxuICAgICAgaXRlbS50eXBlID09PSB0eXBlICYmXG4gICAgICBvYmplY3RJbmNsdWRlcyhcbiAgICAgICAgLy8gT25seSBjaGVjayBlcXVhbGl0eSBmb3IgdGhlIGF0dHJpYnV0ZXMgdGhhdCBhcmUgcHJvdmlkZWRcbiAgICAgICAgT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpLm1hcChrID0+IFtrLCBpdGVtLmF0dHJzW2tdXSkpLFxuICAgICAgICBhdHRyaWJ1dGVzLFxuICAgICAgKVxuICAgIClcbiAgfSlcbn1cblxuZnVuY3Rpb24gaXNNYXJrSW5TZXQoXG4gIG1hcmtzOiBQcm9zZU1pcnJvck1hcmtbXSxcbiAgdHlwZTogTWFya1R5cGUsXG4gIGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fSxcbik6IGJvb2xlYW4ge1xuICByZXR1cm4gISFmaW5kTWFya0luU2V0KG1hcmtzLCB0eXBlLCBhdHRyaWJ1dGVzKVxufVxuXG4vKipcbiAqIEdldCB0aGUgcmFuZ2Ugb2YgYSBtYXJrIGF0IGEgcmVzb2x2ZWQgcG9zaXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXJrUmFuZ2UoXG4gIC8qKlxuICAgKiBUaGUgcG9zaXRpb24gdG8gZ2V0IHRoZSBtYXJrIHJhbmdlIGZvci5cbiAgICovXG4gICRwb3M6IFJlc29sdmVkUG9zLFxuICAvKipcbiAgICogVGhlIG1hcmsgdHlwZSB0byBnZXQgdGhlIHJhbmdlIGZvci5cbiAgICovXG4gIHR5cGU6IE1hcmtUeXBlLFxuICAvKipcbiAgICogVGhlIGF0dHJpYnV0ZXMgdG8gbWF0Y2ggYWdhaW5zdC5cbiAgICogSWYgbm90IHByb3ZpZGVkLCBvbmx5IHRoZSBmaXJzdCBtYXJrIGF0IHRoZSBwb3NpdGlvbiB3aWxsIGJlIG1hdGNoZWQuXG4gICAqL1xuICBhdHRyaWJ1dGVzPzogUmVjb3JkPHN0cmluZywgYW55Pixcbik6IFJhbmdlIHwgdm9pZCB7XG4gIGlmICghJHBvcyB8fCAhdHlwZSkge1xuICAgIHJldHVyblxuICB9XG4gIGxldCBzdGFydCA9ICRwb3MucGFyZW50LmNoaWxkQWZ0ZXIoJHBvcy5wYXJlbnRPZmZzZXQpXG5cbiAgLy8gSWYgdGhlIGN1cnNvciBpcyBhdCB0aGUgc3RhcnQgb2YgYSB0ZXh0IG5vZGUgdGhhdCBkb2VzIG5vdCBoYXZlIHRoZSBtYXJrLCBsb29rIGJhY2t3YXJkXG4gIGlmICghc3RhcnQubm9kZSB8fCAhc3RhcnQubm9kZS5tYXJrcy5zb21lKG1hcmsgPT4gbWFyay50eXBlID09PSB0eXBlKSkge1xuICAgIHN0YXJ0ID0gJHBvcy5wYXJlbnQuY2hpbGRCZWZvcmUoJHBvcy5wYXJlbnRPZmZzZXQpXG4gIH1cblxuICAvLyBJZiB0aGVyZSBpcyBubyB0ZXh0IG5vZGUgd2l0aCB0aGUgbWFyayBldmVuIGJhY2t3YXJkLCByZXR1cm4gdW5kZWZpbmVkXG4gIGlmICghc3RhcnQubm9kZSB8fCAhc3RhcnQubm9kZS5tYXJrcy5zb21lKG1hcmsgPT4gbWFyay50eXBlID09PSB0eXBlKSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgLy8gRGVmYXVsdCB0byBvbmx5IG1hdGNoaW5nIGFnYWluc3QgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIGZpcnN0IG1hcmsgd2l0aCB0aGUgZ2l2ZW4gdHlwZVxuICBpZiAoIWF0dHJpYnV0ZXMpIHtcbiAgICBjb25zdCBmaXJzdE1hcmsgPSBzdGFydC5ub2RlLm1hcmtzLmZpbmQobWFyayA9PiBtYXJrLnR5cGUgPT09IHR5cGUpXG4gICAgaWYgKGZpcnN0TWFyaykge1xuICAgICAgYXR0cmlidXRlcyA9IGZpcnN0TWFyay5hdHRyc1xuICAgIH1cbiAgfVxuXG4gIC8vIFdlIG5vdyBrbm93IHRoYXQgdGhlIGN1cnNvciBpcyBlaXRoZXIgYXQgdGhlIHN0YXJ0LCBtaWRkbGUgb3IgZW5kIG9mIGEgdGV4dCBub2RlIHdpdGggdGhlIHNwZWNpZmllZCBtYXJrXG4gIC8vIHNvIHdlIGNhbiBsb29rIGl0IHVwIG9uIHRoZSB0YXJnZXRlZCBtYXJrXG4gIGNvbnN0IG1hcmsgPSBmaW5kTWFya0luU2V0KFsuLi5zdGFydC5ub2RlLm1hcmtzXSwgdHlwZSwgYXR0cmlidXRlcylcblxuICBpZiAoIW1hcmspIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIGxldCBzdGFydEluZGV4ID0gc3RhcnQuaW5kZXhcbiAgbGV0IHN0YXJ0UG9zID0gJHBvcy5zdGFydCgpICsgc3RhcnQub2Zmc2V0XG4gIGxldCBlbmRJbmRleCA9IHN0YXJ0SW5kZXggKyAxXG4gIGxldCBlbmRQb3MgPSBzdGFydFBvcyArIHN0YXJ0Lm5vZGUubm9kZVNpemVcblxuICB3aGlsZSAoXG4gICAgc3RhcnRJbmRleCA+IDAgJiZcbiAgICBpc01hcmtJblNldChbLi4uJHBvcy5wYXJlbnQuY2hpbGQoc3RhcnRJbmRleCAtIDEpLm1hcmtzXSwgdHlwZSwgYXR0cmlidXRlcylcbiAgKSB7XG4gICAgc3RhcnRJbmRleCAtPSAxXG4gICAgc3RhcnRQb3MgLT0gJHBvcy5wYXJlbnQuY2hpbGQoc3RhcnRJbmRleCkubm9kZVNpemVcbiAgfVxuXG4gIHdoaWxlIChcbiAgICBlbmRJbmRleCA8ICRwb3MucGFyZW50LmNoaWxkQ291bnQgJiZcbiAgICBpc01hcmtJblNldChbLi4uJHBvcy5wYXJlbnQuY2hpbGQoZW5kSW5kZXgpLm1hcmtzXSwgdHlwZSwgYXR0cmlidXRlcylcbiAgKSB7XG4gICAgZW5kUG9zICs9ICRwb3MucGFyZW50LmNoaWxkKGVuZEluZGV4KS5ub2RlU2l6ZVxuICAgIGVuZEluZGV4ICs9IDFcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZnJvbTogc3RhcnRQb3MsXG4gICAgdG86IGVuZFBvcyxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgTWFya1R5cGUsIFNjaGVtYSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXJrVHlwZShuYW1lT3JUeXBlOiBzdHJpbmcgfCBNYXJrVHlwZSwgc2NoZW1hOiBTY2hlbWEpOiBNYXJrVHlwZSB7XG4gIGlmICh0eXBlb2YgbmFtZU9yVHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoIXNjaGVtYS5tYXJrc1tuYW1lT3JUeXBlXSkge1xuICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgIGBUaGVyZSBpcyBubyBtYXJrIHR5cGUgbmFtZWQgJyR7bmFtZU9yVHlwZX0nLiBNYXliZSB5b3UgZm9yZ290IHRvIGFkZCB0aGUgZXh0ZW5zaW9uP2AsXG4gICAgICApXG4gICAgfVxuXG4gICAgcmV0dXJuIHNjaGVtYS5tYXJrc1tuYW1lT3JUeXBlXVxuICB9XG5cbiAgcmV0dXJuIG5hbWVPclR5cGVcbn1cbiIsICJpbXBvcnQgdHlwZSB7IENvbW1hbmQsIENvbW1hbmRQcm9wcywgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGZpcnN0OiB7XG4gICAgICAvKipcbiAgICAgICAqIFJ1bnMgb25lIGNvbW1hbmQgYWZ0ZXIgdGhlIG90aGVyIGFuZCBzdG9wcyBhdCB0aGUgZmlyc3Qgd2hpY2ggcmV0dXJucyB0cnVlLlxuICAgICAgICogQHBhcmFtIGNvbW1hbmRzIFRoZSBjb21tYW5kcyB0byBydW4uXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuZmlyc3QoW2NvbW1hbmQxLCBjb21tYW5kMl0pXG4gICAgICAgKi9cbiAgICAgIGZpcnN0OiAoY29tbWFuZHM6IENvbW1hbmRbXSB8ICgocHJvcHM6IENvbW1hbmRQcm9wcykgPT4gQ29tbWFuZFtdKSkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZmlyc3Q6IFJhd0NvbW1hbmRzWydmaXJzdCddID0gY29tbWFuZHMgPT4gcHJvcHMgPT4ge1xuICBjb25zdCBpdGVtcyA9IHR5cGVvZiBjb21tYW5kcyA9PT0gJ2Z1bmN0aW9uJyA/IGNvbW1hbmRzKHByb3BzKSA6IGNvbW1hbmRzXG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGlmIChpdGVtc1tpXShwcm9wcykpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG4iLCAiaW1wb3J0IHsgVGV4dFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1RleHRTZWxlY3Rpb24odmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBUZXh0U2VsZWN0aW9uIHtcbiAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvblxufVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgU2VsZWN0aW9uLCBUZXh0U2VsZWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHR5cGUgeyBGb2N1c1Bvc2l0aW9uIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBtaW5NYXggfSBmcm9tICcuLi91dGlsaXRpZXMvbWluTWF4LmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUZvY3VzUG9zaXRpb24oXG4gIGRvYzogUHJvc2VNaXJyb3JOb2RlLFxuICBwb3NpdGlvbjogRm9jdXNQb3NpdGlvbiA9IG51bGwsXG4pOiBTZWxlY3Rpb24gfCBudWxsIHtcbiAgaWYgKCFwb3NpdGlvbikge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBjb25zdCBzZWxlY3Rpb25BdFN0YXJ0ID0gU2VsZWN0aW9uLmF0U3RhcnQoZG9jKVxuICBjb25zdCBzZWxlY3Rpb25BdEVuZCA9IFNlbGVjdGlvbi5hdEVuZChkb2MpXG5cbiAgaWYgKHBvc2l0aW9uID09PSAnc3RhcnQnIHx8IHBvc2l0aW9uID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIHNlbGVjdGlvbkF0U3RhcnRcbiAgfVxuXG4gIGlmIChwb3NpdGlvbiA9PT0gJ2VuZCcpIHtcbiAgICByZXR1cm4gc2VsZWN0aW9uQXRFbmRcbiAgfVxuXG4gIGNvbnN0IG1pblBvcyA9IHNlbGVjdGlvbkF0U3RhcnQuZnJvbVxuICBjb25zdCBtYXhQb3MgPSBzZWxlY3Rpb25BdEVuZC50b1xuXG4gIGlmIChwb3NpdGlvbiA9PT0gJ2FsbCcpIHtcbiAgICByZXR1cm4gVGV4dFNlbGVjdGlvbi5jcmVhdGUoXG4gICAgICBkb2MsXG4gICAgICBtaW5NYXgoMCwgbWluUG9zLCBtYXhQb3MpLFxuICAgICAgbWluTWF4KGRvYy5jb250ZW50LnNpemUsIG1pblBvcywgbWF4UG9zKSxcbiAgICApXG4gIH1cblxuICByZXR1cm4gVGV4dFNlbGVjdGlvbi5jcmVhdGUoXG4gICAgZG9jLFxuICAgIG1pbk1heChwb3NpdGlvbiwgbWluUG9zLCBtYXhQb3MpLFxuICAgIG1pbk1heChwb3NpdGlvbiwgbWluUG9zLCBtYXhQb3MpLFxuICApXG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIG1pbk1heCh2YWx1ZSA9IDAsIG1pbiA9IDAsIG1heCA9IDApOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgodmFsdWUsIG1pbiksIG1heClcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gaXNBbmRyb2lkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gbmF2aWdhdG9yLnBsYXRmb3JtID09PSAnQW5kcm9pZCcgfHwgL2FuZHJvaWQvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpXG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGlzaU9TKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIFsnaVBhZCBTaW11bGF0b3InLCAnaVBob25lIFNpbXVsYXRvcicsICdpUG9kIFNpbXVsYXRvcicsICdpUGFkJywgJ2lQaG9uZScsICdpUG9kJ10uaW5jbHVkZXMoXG4gICAgICBuYXZpZ2F0b3IucGxhdGZvcm0sXG4gICAgKSB8fFxuICAgIC8vIGlQYWQgb24gaU9TIDEzIGRldGVjdGlvblxuICAgIChuYXZpZ2F0b3IudXNlckFnZW50LmluY2x1ZGVzKCdNYWMnKSAmJiAnb250b3VjaGVuZCcgaW4gZG9jdW1lbnQpXG4gIClcbn1cbiIsICIvKipcbiAqIERldGVjdHMgaWYgdGhlIGN1cnJlbnQgYnJvd3NlciBpcyBTYWZhcmkgKGJ1dCBub3QgaU9TIFNhZmFyaSBvciBDaHJvbWUpLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSBicm93c2VyIGlzIFNhZmFyaSwgYGZhbHNlYCBvdGhlcndpc2UuXG4gKiBAZXhhbXBsZVxuICogaWYgKGlzU2FmYXJpKCkpIHtcbiAqICAgLy8gU2FmYXJpLXNwZWNpZmljIGhhbmRsaW5nXG4gKiB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NhZmFyaSgpOiBib29sZWFuIHtcbiAgcmV0dXJuIHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnXG4gICAgPyAvXigoPyFjaHJvbWV8YW5kcm9pZCkuKSpzYWZhcmkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpXG4gICAgOiBmYWxzZVxufVxuIiwgImltcG9ydCB7IGlzVGV4dFNlbGVjdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvaXNUZXh0U2VsZWN0aW9uLmpzJ1xuaW1wb3J0IHsgcmVzb2x2ZUZvY3VzUG9zaXRpb24gfSBmcm9tICcuLi9oZWxwZXJzL3Jlc29sdmVGb2N1c1Bvc2l0aW9uLmpzJ1xuaW1wb3J0IHR5cGUgeyBGb2N1c1Bvc2l0aW9uLCBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgaXNBbmRyb2lkIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2lzQW5kcm9pZC5qcydcbmltcG9ydCB7IGlzaU9TIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2lzaU9TLmpzJ1xuaW1wb3J0IHsgaXNTYWZhcmkgfSBmcm9tICcuLi91dGlsaXRpZXMvaXNTYWZhcmkuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBmb2N1czoge1xuICAgICAgLyoqXG4gICAgICAgKiBGb2N1cyB0aGUgZWRpdG9yIGF0IHRoZSBnaXZlbiBwb3NpdGlvbi5cbiAgICAgICAqIEBwYXJhbSBwb3NpdGlvbiBUaGUgcG9zaXRpb24gdG8gZm9jdXMgYXQuXG4gICAgICAgKiBAcGFyYW0gb3B0aW9ucy5zY3JvbGxJbnRvVmlldyBTY3JvbGwgdGhlIGZvY3VzZWQgcG9zaXRpb24gaW50byB2aWV3IGFmdGVyIGZvY3VzaW5nXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuZm9jdXMoKVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmZvY3VzKDMyLCB7IHNjcm9sbEludG9WaWV3OiBmYWxzZSB9KVxuICAgICAgICovXG4gICAgICBmb2N1czogKFxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBvc2l0aW9uIHRvIGZvY3VzIGF0LlxuICAgICAgICAgKi9cbiAgICAgICAgcG9zaXRpb24/OiBGb2N1c1Bvc2l0aW9uLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPcHRpb25hbCBvcHRpb25zXG4gICAgICAgICAqIEBkZWZhdWx0IHsgc2Nyb2xsSW50b1ZpZXc6IHRydWUgfVxuICAgICAgICAgKi9cbiAgICAgICAgb3B0aW9ucz86IHtcbiAgICAgICAgICBzY3JvbGxJbnRvVmlldz86IGJvb2xlYW5cbiAgICAgICAgfSxcbiAgICAgICkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZm9jdXM6IFJhd0NvbW1hbmRzWydmb2N1cyddID1cbiAgKHBvc2l0aW9uID0gbnVsbCwgb3B0aW9ucyA9IHt9KSA9PlxuICAoeyBlZGl0b3IsIHZpZXcsIHRyLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgb3B0aW9ucyA9IHtcbiAgICAgIHNjcm9sbEludG9WaWV3OiB0cnVlLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9XG5cbiAgICBjb25zdCBkZWxheWVkRm9jdXMgPSAoKSA9PiB7XG4gICAgICAvLyBmb2N1cyB3aXRoaW4gYHJlcXVlc3RBbmltYXRpb25GcmFtZWAgYnJlYWtzIGZvY3VzIG9uIGlPUyBhbmQgQW5kcm9pZFxuICAgICAgLy8gc28gd2UgaGF2ZSB0byBjYWxsIHRoaXNcbiAgICAgIGlmIChpc2lPUygpIHx8IGlzQW5kcm9pZCgpKSB7XG4gICAgICAgIDsodmlldy5kb20gYXMgSFRNTEVsZW1lbnQpLmZvY3VzKClcbiAgICAgIH1cblxuICAgICAgLy8gU2FmYXJpIHJlcXVpcmVzIHByZXZlbnRTY3JvbGwgdG8gYXZvaWQgdGhlIGJyb3dzZXIgc2Nyb2xsaW5nIHRvIHRoZVxuICAgICAgLy8gdG9wIG9mIHRoZSBlZGl0b3Igd2hlbiBmb2N1cyBpcyBjYWxsZWQgYmVmb3JlIHRoZSBzZWxlY3Rpb24gaXMgc2V0LlxuICAgICAgLy8gV2UgZXhjbHVkZSBpT1MgYW5kIEFuZHJvaWQgc2luY2UgdGhleSBhcmUgYWxyZWFkeSBoYW5kbGVkIGFib3ZlLlxuICAgICAgLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vdWViZXJkb3Npcy90aXB0YXAvaXNzdWVzLzczMThcbiAgICAgIGlmIChpc1NhZmFyaSgpICYmICFpc2lPUygpICYmICFpc0FuZHJvaWQoKSkge1xuICAgICAgICA7KHZpZXcuZG9tIGFzIEhUTUxFbGVtZW50KS5mb2N1cyh7IHByZXZlbnRTY3JvbGw6IHRydWUgfSlcbiAgICAgIH1cblxuICAgICAgLy8gRm9yIFJlYWN0IHdlIGhhdmUgdG8gZm9jdXMgYXN5bmNocm9ub3VzbHkuIE90aGVyd2lzZSB3aWxkIHRoaW5ncyBoYXBwZW4uXG4gICAgICAvLyBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS91ZWJlcmRvc2lzL3RpcHRhcC9pc3N1ZXMvMTUyMFxuICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgaWYgKCFlZGl0b3IuaXNEZXN0cm95ZWQpIHtcbiAgICAgICAgICB2aWV3LmZvY3VzKClcblxuICAgICAgICAgIGlmIChvcHRpb25zPy5zY3JvbGxJbnRvVmlldykge1xuICAgICAgICAgICAgZWRpdG9yLmNvbW1hbmRzLnNjcm9sbEludG9WaWV3KClcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGlmICgodmlldy5oYXNGb2N1cygpICYmIHBvc2l0aW9uID09PSBudWxsKSB8fCBwb3NpdGlvbiA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIGlmIHZpZXcuaGFzRm9jdXMgZmFpbHMgKHZpZXcgbm90IG1vdW50ZWQgeWV0KVxuICAgICAgLy8gd2Ugd2lsbCByZXR1cm4gZmFsc2UgYmVjYXVzZSB0aGVyZSdzIG5vdGhpbmcgdG8gZm9jdXNcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIHdlIGRvbuKAmXQgdHJ5IHRvIHJlc29sdmUgYSBOb2RlU2VsZWN0aW9uIG9yIENlbGxTZWxlY3Rpb25cbiAgICBpZiAoZGlzcGF0Y2ggJiYgcG9zaXRpb24gPT09IG51bGwgJiYgIWlzVGV4dFNlbGVjdGlvbihlZGl0b3Iuc3RhdGUuc2VsZWN0aW9uKSkge1xuICAgICAgZGVsYXllZEZvY3VzKClcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gcGFzcyB0aHJvdWdoIHRyLmRvYyBpbnN0ZWFkIG9mIGVkaXRvci5zdGF0ZS5kb2NcbiAgICAvLyBzaW5jZSB0cmFuc2FjdGlvbnMgY291bGQgY2hhbmdlIHRoZSBlZGl0b3JzIHN0YXRlIGJlZm9yZSB0aGlzIGNvbW1hbmQgaGFzIGJlZW4gcnVuXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gcmVzb2x2ZUZvY3VzUG9zaXRpb24odHIuZG9jLCBwb3NpdGlvbikgfHwgZWRpdG9yLnN0YXRlLnNlbGVjdGlvblxuICAgIGNvbnN0IGlzU2FtZVNlbGVjdGlvbiA9IGVkaXRvci5zdGF0ZS5zZWxlY3Rpb24uZXEoc2VsZWN0aW9uKVxuXG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICBpZiAoIWlzU2FtZVNlbGVjdGlvbikge1xuICAgICAgICB0ci5zZXRTZWxlY3Rpb24oc2VsZWN0aW9uKVxuICAgICAgfVxuXG4gICAgICAvLyBgdHIuc2V0U2VsZWN0aW9uYCByZXNldHMgdGhlIHN0b3JlZCBtYXJrc1xuICAgICAgLy8gc28gd2XigJlsbCByZXN0b3JlIHRoZW0gaWYgdGhlIHNlbGVjdGlvbiBpcyB0aGUgc2FtZSBhcyBiZWZvcmVcbiAgICAgIGlmIChpc1NhbWVTZWxlY3Rpb24gJiYgdHIuc3RvcmVkTWFya3MpIHtcbiAgICAgICAgdHIuc2V0U3RvcmVkTWFya3ModHIuc3RvcmVkTWFya3MpXG4gICAgICB9XG5cbiAgICAgIGRlbGF5ZWRGb2N1cygpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgQ29tbWFuZFByb3BzLCBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgZm9yRWFjaDoge1xuICAgICAgLyoqXG4gICAgICAgKiBMb29wIHRocm91Z2ggYW4gYXJyYXkgb2YgaXRlbXMuXG4gICAgICAgKi9cbiAgICAgIGZvckVhY2g6IDxUPihcbiAgICAgICAgaXRlbXM6IFRbXSxcbiAgICAgICAgZm46IChcbiAgICAgICAgICBpdGVtOiBULFxuICAgICAgICAgIHByb3BzOiBDb21tYW5kUHJvcHMgJiB7XG4gICAgICAgICAgICBpbmRleDogbnVtYmVyXG4gICAgICAgICAgfSxcbiAgICAgICAgKSA9PiBib29sZWFuLFxuICAgICAgKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBmb3JFYWNoOiBSYXdDb21tYW5kc1snZm9yRWFjaCddID0gKGl0ZW1zLCBmbikgPT4gcHJvcHMgPT4ge1xuICByZXR1cm4gaXRlbXMuZXZlcnkoKGl0ZW0sIGluZGV4KSA9PiBmbihpdGVtLCB7IC4uLnByb3BzLCBpbmRleCB9KSlcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEZyYWdtZW50LCBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSwgUGFyc2VPcHRpb25zIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBDb250ZW50LCBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIEluc2VydENvbnRlbnRPcHRpb25zIHtcbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIHBhcnNpbmcgdGhlIGNvbnRlbnQuXG4gICAqL1xuICBwYXJzZU9wdGlvbnM/OiBQYXJzZU9wdGlvbnNcblxuICAvKipcbiAgICogV2hldGhlciB0byB1cGRhdGUgdGhlIHNlbGVjdGlvbiBhZnRlciBpbnNlcnRpbmcgdGhlIGNvbnRlbnQuXG4gICAqL1xuICB1cGRhdGVTZWxlY3Rpb24/OiBib29sZWFuXG4gIGFwcGx5SW5wdXRSdWxlcz86IGJvb2xlYW5cbiAgYXBwbHlQYXN0ZVJ1bGVzPzogYm9vbGVhblxufVxuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgaW5zZXJ0Q29udGVudDoge1xuICAgICAgLyoqXG4gICAgICAgKiBJbnNlcnQgYSBub2RlIG9yIHN0cmluZyBvZiBIVE1MIGF0IHRoZSBjdXJyZW50IHBvc2l0aW9uLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmluc2VydENvbnRlbnQoJzxoMT5FeGFtcGxlPC9oMT4nKVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmluc2VydENvbnRlbnQoJzxoMT5FeGFtcGxlPC9oMT4nLCB7IHVwZGF0ZVNlbGVjdGlvbjogZmFsc2UgfSlcbiAgICAgICAqL1xuICAgICAgaW5zZXJ0Q29udGVudDogKFxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIFByb3NlTWlycm9yIGNvbnRlbnQgdG8gaW5zZXJ0LlxuICAgICAgICAgKi9cbiAgICAgICAgdmFsdWU6IENvbnRlbnQgfCBQcm9zZU1pcnJvck5vZGUgfCBGcmFnbWVudCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogT3B0aW9uYWwgb3B0aW9uc1xuICAgICAgICAgKi9cbiAgICAgICAgb3B0aW9ucz86IEluc2VydENvbnRlbnRPcHRpb25zLFxuICAgICAgKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBpbnNlcnRDb250ZW50OiBSYXdDb21tYW5kc1snaW5zZXJ0Q29udGVudCddID1cbiAgKHZhbHVlLCBvcHRpb25zKSA9PlxuICAoeyB0ciwgY29tbWFuZHMgfSkgPT4ge1xuICAgIHJldHVybiBjb21tYW5kcy5pbnNlcnRDb250ZW50QXQoXG4gICAgICB7IGZyb206IHRyLnNlbGVjdGlvbi5mcm9tLCB0bzogdHIuc2VsZWN0aW9uLnRvIH0sXG4gICAgICB2YWx1ZSxcbiAgICAgIG9wdGlvbnMsXG4gICAgKVxuICB9XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSwgUGFyc2VPcHRpb25zIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IEZyYWdtZW50IH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgY3JlYXRlTm9kZUZyb21Db250ZW50IH0gZnJvbSAnLi4vaGVscGVycy9jcmVhdGVOb2RlRnJvbUNvbnRlbnQuanMnXG5pbXBvcnQgeyBzZWxlY3Rpb25Ub0luc2VydGlvbkVuZCB9IGZyb20gJy4uL2hlbHBlcnMvc2VsZWN0aW9uVG9JbnNlcnRpb25FbmQuanMnXG5pbXBvcnQgdHlwZSB7IENvbnRlbnQsIFJhbmdlLCBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIEluc2VydENvbnRlbnRBdE9wdGlvbnMge1xuICAvKipcbiAgICogT3B0aW9ucyBmb3IgcGFyc2luZyB0aGUgY29udGVudC5cbiAgICovXG4gIHBhcnNlT3B0aW9ucz86IFBhcnNlT3B0aW9uc1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHVwZGF0ZSB0aGUgc2VsZWN0aW9uIGFmdGVyIGluc2VydGluZyB0aGUgY29udGVudC5cbiAgICovXG4gIHVwZGF0ZVNlbGVjdGlvbj86IGJvb2xlYW5cblxuICAvKipcbiAgICogV2hldGhlciB0byBhcHBseSBpbnB1dCBydWxlcyBhZnRlciBpbnNlcnRpbmcgdGhlIGNvbnRlbnQuXG4gICAqL1xuICBhcHBseUlucHV0UnVsZXM/OiBib29sZWFuXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gYXBwbHkgcGFzdGUgcnVsZXMgYWZ0ZXIgaW5zZXJ0aW5nIHRoZSBjb250ZW50LlxuICAgKi9cbiAgYXBwbHlQYXN0ZVJ1bGVzPzogYm9vbGVhblxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBjb250ZW50IGlzIGludmFsaWQuXG4gICAqL1xuICBlcnJvck9uSW52YWxpZENvbnRlbnQ/OiBib29sZWFuXG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBpbnNlcnRDb250ZW50QXQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogSW5zZXJ0IGEgbm9kZSBvciBzdHJpbmcgb2YgSFRNTCBhdCBhIHNwZWNpZmljIHBvc2l0aW9uLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmluc2VydENvbnRlbnRBdCgwLCAnPGgxPkV4YW1wbGU8L2gxPicpXG4gICAgICAgKi9cbiAgICAgIGluc2VydENvbnRlbnRBdDogKFxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIHBvc2l0aW9uIHRvIGluc2VydCB0aGUgY29udGVudCBhdC5cbiAgICAgICAgICovXG4gICAgICAgIHBvc2l0aW9uOiBudW1iZXIgfCBSYW5nZSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIFByb3NlTWlycm9yIGNvbnRlbnQgdG8gaW5zZXJ0LlxuICAgICAgICAgKi9cbiAgICAgICAgdmFsdWU6IENvbnRlbnQgfCBQcm9zZU1pcnJvck5vZGUgfCBGcmFnbWVudCxcblxuICAgICAgICAvKipcbiAgICAgICAgICogT3B0aW9uYWwgb3B0aW9uc1xuICAgICAgICAgKi9cbiAgICAgICAgb3B0aW9ucz86IEluc2VydENvbnRlbnRBdE9wdGlvbnMsXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgaXNGcmFnbWVudCA9IChub2RlT3JGcmFnbWVudDogUHJvc2VNaXJyb3JOb2RlIHwgRnJhZ21lbnQpOiBub2RlT3JGcmFnbWVudCBpcyBGcmFnbWVudCA9PiB7XG4gIHJldHVybiAhKCd0eXBlJyBpbiBub2RlT3JGcmFnbWVudClcbn1cblxuZXhwb3J0IGNvbnN0IGluc2VydENvbnRlbnRBdDogUmF3Q29tbWFuZHNbJ2luc2VydENvbnRlbnRBdCddID1cbiAgKHBvc2l0aW9uLCB2YWx1ZSwgb3B0aW9ucykgPT5cbiAgKHsgdHIsIGRpc3BhdGNoLCBlZGl0b3IgfSkgPT4ge1xuICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgb3B0aW9ucyA9IHtcbiAgICAgICAgcGFyc2VPcHRpb25zOiBlZGl0b3Iub3B0aW9ucy5wYXJzZU9wdGlvbnMsXG4gICAgICAgIHVwZGF0ZVNlbGVjdGlvbjogdHJ1ZSxcbiAgICAgICAgYXBwbHlJbnB1dFJ1bGVzOiBmYWxzZSxcbiAgICAgICAgYXBwbHlQYXN0ZVJ1bGVzOiBmYWxzZSxcbiAgICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIH1cblxuICAgICAgbGV0IGNvbnRlbnQ6IEZyYWdtZW50IHwgUHJvc2VNaXJyb3JOb2RlXG5cbiAgICAgIGNvbnN0IGVtaXRDb250ZW50RXJyb3IgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgIGVkaXRvci5lbWl0KCdjb250ZW50RXJyb3InLCB7XG4gICAgICAgICAgZWRpdG9yLFxuICAgICAgICAgIGVycm9yLFxuICAgICAgICAgIGRpc2FibGVDb2xsYWJvcmF0aW9uOiAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICdjb2xsYWJvcmF0aW9uJyBpbiBlZGl0b3Iuc3RvcmFnZSAmJlxuICAgICAgICAgICAgICB0eXBlb2YgZWRpdG9yLnN0b3JhZ2UuY29sbGFib3JhdGlvbiA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgICAgZWRpdG9yLnN0b3JhZ2UuY29sbGFib3JhdGlvblxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIDsoZWRpdG9yLnN0b3JhZ2UuY29sbGFib3JhdGlvbiBhcyBhbnkpLmlzRGlzYWJsZWQgPSB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFyc2VPcHRpb25zOiBQYXJzZU9wdGlvbnMgPSB7XG4gICAgICAgIHByZXNlcnZlV2hpdGVzcGFjZTogJ2Z1bGwnLFxuICAgICAgICAuLi5vcHRpb25zLnBhcnNlT3B0aW9ucyxcbiAgICAgIH1cblxuICAgICAgLy8gSWYgYGVtaXRDb250ZW50RXJyb3JgIGlzIGVuYWJsZWQsIHdlIHdhbnQgdG8gY2hlY2sgdGhlIGNvbnRlbnQgZm9yIGVycm9yc1xuICAgICAgLy8gYnV0IGlnbm9yZSB0aGVtIChkbyBub3QgcmVtb3ZlIHRoZSBpbnZhbGlkIGNvbnRlbnQgZnJvbSB0aGUgZG9jdW1lbnQpXG4gICAgICBpZiAoXG4gICAgICAgICFvcHRpb25zLmVycm9yT25JbnZhbGlkQ29udGVudCAmJlxuICAgICAgICAhZWRpdG9yLm9wdGlvbnMuZW5hYmxlQ29udGVudENoZWNrICYmXG4gICAgICAgIGVkaXRvci5vcHRpb25zLmVtaXRDb250ZW50RXJyb3JcbiAgICAgICkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNyZWF0ZU5vZGVGcm9tQ29udGVudCh2YWx1ZSwgZWRpdG9yLnNjaGVtYSwge1xuICAgICAgICAgICAgcGFyc2VPcHRpb25zLFxuICAgICAgICAgICAgZXJyb3JPbkludmFsaWRDb250ZW50OiB0cnVlLFxuICAgICAgICAgIH0pXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBlbWl0Q29udGVudEVycm9yKGUgYXMgRXJyb3IpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29udGVudCA9IGNyZWF0ZU5vZGVGcm9tQ29udGVudCh2YWx1ZSwgZWRpdG9yLnNjaGVtYSwge1xuICAgICAgICAgIHBhcnNlT3B0aW9ucyxcbiAgICAgICAgICBlcnJvck9uSW52YWxpZENvbnRlbnQ6IG9wdGlvbnMuZXJyb3JPbkludmFsaWRDb250ZW50ID8/IGVkaXRvci5vcHRpb25zLmVuYWJsZUNvbnRlbnRDaGVjayxcbiAgICAgICAgfSlcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgZW1pdENvbnRlbnRFcnJvcihlIGFzIEVycm9yKVxuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cblxuICAgICAgbGV0IHsgZnJvbSwgdG8gfSA9XG4gICAgICAgIHR5cGVvZiBwb3NpdGlvbiA9PT0gJ251bWJlcidcbiAgICAgICAgICA/IHsgZnJvbTogcG9zaXRpb24sIHRvOiBwb3NpdGlvbiB9XG4gICAgICAgICAgOiB7IGZyb206IHBvc2l0aW9uLmZyb20sIHRvOiBwb3NpdGlvbi50byB9XG5cbiAgICAgIGxldCBpc09ubHlUZXh0Q29udGVudCA9IHRydWVcbiAgICAgIGxldCBpc09ubHlCbG9ja0NvbnRlbnQgPSB0cnVlXG4gICAgICBjb25zdCBub2RlcyA9IGlzRnJhZ21lbnQoY29udGVudCkgPyBjb250ZW50IDogW2NvbnRlbnRdXG5cbiAgICAgIG5vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgIC8vIGNoZWNrIGlmIGFkZGVkIG5vZGUgaXMgdmFsaWRcbiAgICAgICAgbm9kZS5jaGVjaygpXG5cbiAgICAgICAgaXNPbmx5VGV4dENvbnRlbnQgPSBpc09ubHlUZXh0Q29udGVudCA/IG5vZGUuaXNUZXh0ICYmIG5vZGUubWFya3MubGVuZ3RoID09PSAwIDogZmFsc2VcblxuICAgICAgICBpc09ubHlCbG9ja0NvbnRlbnQgPSBpc09ubHlCbG9ja0NvbnRlbnQgPyBub2RlLmlzQmxvY2sgOiBmYWxzZVxuICAgICAgfSlcblxuICAgICAgLy8gY2hlY2sgaWYgd2UgY2FuIHJlcGxhY2UgdGhlIHdyYXBwaW5nIG5vZGUgYnlcbiAgICAgIC8vIHRoZSBuZXdseSBpbnNlcnRlZCBjb250ZW50XG4gICAgICAvLyBleGFtcGxlOlxuICAgICAgLy8gcmVwbGFjZSBhbiBlbXB0eSBwYXJhZ3JhcGggYnkgYW4gaW5zZXJ0ZWQgaW1hZ2VcbiAgICAgIC8vIGluc3RlYWQgb2YgaW5zZXJ0aW5nIHRoZSBpbWFnZSBiZWxvdyB0aGUgcGFyYWdyYXBoXG4gICAgICBpZiAoZnJvbSA9PT0gdG8gJiYgaXNPbmx5QmxvY2tDb250ZW50KSB7XG4gICAgICAgIGNvbnN0IHsgcGFyZW50IH0gPSB0ci5kb2MucmVzb2x2ZShmcm9tKVxuICAgICAgICBjb25zdCBpc0VtcHR5VGV4dEJsb2NrID0gcGFyZW50LmlzVGV4dGJsb2NrICYmICFwYXJlbnQudHlwZS5zcGVjLmNvZGUgJiYgIXBhcmVudC5jaGlsZENvdW50XG5cbiAgICAgICAgaWYgKGlzRW1wdHlUZXh0QmxvY2spIHtcbiAgICAgICAgICBmcm9tIC09IDFcbiAgICAgICAgICB0byArPSAxXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGV0IG5ld0NvbnRlbnRcblxuICAgICAgLy8gaWYgdGhlcmUgaXMgb25seSBwbGFpbiB0ZXh0IHdlIGhhdmUgdG8gdXNlIGBpbnNlcnRUZXh0YFxuICAgICAgLy8gYmVjYXVzZSB0aGlzIHdpbGwga2VlcCB0aGUgY3VycmVudCBtYXJrc1xuICAgICAgaWYgKGlzT25seVRleHRDb250ZW50KSB7XG4gICAgICAgIC8vIGlmIHZhbHVlIGlzIHN0cmluZywgd2UgY2FuIHVzZSBpdCBkaXJlY3RseVxuICAgICAgICAvLyBvdGhlcndpc2UgaWYgaXQgaXMgYW4gYXJyYXksIHdlIGhhdmUgdG8gam9pbiBpdFxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICBuZXdDb250ZW50ID0gdmFsdWUubWFwKHYgPT4gdi50ZXh0IHx8ICcnKS5qb2luKCcnKVxuICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRnJhZ21lbnQpIHtcbiAgICAgICAgICBsZXQgdGV4dCA9ICcnXG5cbiAgICAgICAgICB2YWx1ZS5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgaWYgKG5vZGUudGV4dCkge1xuICAgICAgICAgICAgICB0ZXh0ICs9IG5vZGUudGV4dFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICBuZXdDb250ZW50ID0gdGV4dFxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgISF2YWx1ZSAmJiAhIXZhbHVlLnRleHQpIHtcbiAgICAgICAgICBuZXdDb250ZW50ID0gdmFsdWUudGV4dFxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld0NvbnRlbnQgPSB2YWx1ZSBhcyBzdHJpbmdcbiAgICAgICAgfVxuXG4gICAgICAgIHRyLmluc2VydFRleHQobmV3Q29udGVudCwgZnJvbSwgdG8pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdDb250ZW50ID0gY29udGVudFxuXG4gICAgICAgIGNvbnN0ICRmcm9tID0gdHIuZG9jLnJlc29sdmUoZnJvbSlcbiAgICAgICAgY29uc3QgJGZyb21Ob2RlID0gJGZyb20ubm9kZSgpXG4gICAgICAgIGNvbnN0IGZyb21TZWxlY3Rpb25BdFN0YXJ0ID0gJGZyb20ucGFyZW50T2Zmc2V0ID09PSAwXG4gICAgICAgIGNvbnN0IGlzVGV4dFNlbGVjdGlvbiA9ICRmcm9tTm9kZS5pc1RleHQgfHwgJGZyb21Ob2RlLmlzVGV4dGJsb2NrXG4gICAgICAgIGNvbnN0IGhhc0NvbnRlbnQgPSAkZnJvbU5vZGUuY29udGVudC5zaXplID4gMFxuXG4gICAgICAgIGlmIChmcm9tU2VsZWN0aW9uQXRTdGFydCAmJiBpc1RleHRTZWxlY3Rpb24gJiYgaGFzQ29udGVudCAmJiBpc09ubHlCbG9ja0NvbnRlbnQpIHtcbiAgICAgICAgICBmcm9tID0gTWF0aC5tYXgoMCwgZnJvbSAtIDEpXG4gICAgICAgIH1cblxuICAgICAgICB0ci5yZXBsYWNlV2l0aChmcm9tLCB0bywgbmV3Q29udGVudClcbiAgICAgIH1cblxuICAgICAgLy8gc2V0IGN1cnNvciBhdCBlbmQgb2YgaW5zZXJ0ZWQgY29udGVudFxuICAgICAgaWYgKG9wdGlvbnMudXBkYXRlU2VsZWN0aW9uKSB7XG4gICAgICAgIHNlbGVjdGlvblRvSW5zZXJ0aW9uRW5kKHRyLCB0ci5zdGVwcy5sZW5ndGggLSAxLCAtMSlcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnMuYXBwbHlJbnB1dFJ1bGVzKSB7XG4gICAgICAgIHRyLnNldE1ldGEoJ2FwcGx5SW5wdXRSdWxlcycsIHsgZnJvbSwgdGV4dDogbmV3Q29udGVudCB9KVxuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5hcHBseVBhc3RlUnVsZXMpIHtcbiAgICAgICAgdHIuc2V0TWV0YSgnYXBwbHlQYXN0ZVJ1bGVzJywgeyBmcm9tLCB0ZXh0OiBuZXdDb250ZW50IH0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgUGFyc2VPcHRpb25zIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IERPTVBhcnNlciwgRnJhZ21lbnQsIE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlLCBTY2hlbWEgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgdHlwZSB7IENvbnRlbnQgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGVsZW1lbnRGcm9tU3RyaW5nIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2VsZW1lbnRGcm9tU3RyaW5nLmpzJ1xuXG5leHBvcnQgdHlwZSBDcmVhdGVOb2RlRnJvbUNvbnRlbnRPcHRpb25zID0ge1xuICBzbGljZT86IGJvb2xlYW5cbiAgcGFyc2VPcHRpb25zPzogUGFyc2VPcHRpb25zXG4gIGVycm9yT25JbnZhbGlkQ29udGVudD86IGJvb2xlYW5cbn1cblxuLyoqXG4gKiBUYWtlcyBhIEpTT04gb3IgSFRNTCBjb250ZW50IGFuZCBjcmVhdGVzIGEgUHJvc2VtaXJyb3Igbm9kZSBvciBmcmFnbWVudCBmcm9tIGl0LlxuICogQHBhcmFtIGNvbnRlbnQgVGhlIEpTT04gb3IgSFRNTCBjb250ZW50IHRvIGNyZWF0ZSB0aGUgbm9kZSBmcm9tXG4gKiBAcGFyYW0gc2NoZW1hIFRoZSBQcm9zZW1pcnJvciBzY2hlbWEgdG8gdXNlIGZvciB0aGUgbm9kZVxuICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgdGhlIHBhcnNlclxuICogQHJldHVybnMgVGhlIGNyZWF0ZWQgUHJvc2VtaXJyb3Igbm9kZSBvciBmcmFnbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTm9kZUZyb21Db250ZW50KFxuICBjb250ZW50OiBDb250ZW50IHwgUHJvc2VNaXJyb3JOb2RlIHwgRnJhZ21lbnQsXG4gIHNjaGVtYTogU2NoZW1hLFxuICBvcHRpb25zPzogQ3JlYXRlTm9kZUZyb21Db250ZW50T3B0aW9ucyxcbik6IFByb3NlTWlycm9yTm9kZSB8IEZyYWdtZW50IHtcbiAgaWYgKGNvbnRlbnQgaW5zdGFuY2VvZiBQcm9zZU1pcnJvck5vZGUgfHwgY29udGVudCBpbnN0YW5jZW9mIEZyYWdtZW50KSB7XG4gICAgcmV0dXJuIGNvbnRlbnRcbiAgfVxuICBvcHRpb25zID0ge1xuICAgIHNsaWNlOiB0cnVlLFxuICAgIHBhcnNlT3B0aW9uczoge30sXG4gICAgLi4ub3B0aW9ucyxcbiAgfVxuXG4gIGNvbnN0IGlzSlNPTkNvbnRlbnQgPSB0eXBlb2YgY29udGVudCA9PT0gJ29iamVjdCcgJiYgY29udGVudCAhPT0gbnVsbFxuICBjb25zdCBpc1RleHRDb250ZW50ID0gdHlwZW9mIGNvbnRlbnQgPT09ICdzdHJpbmcnXG5cbiAgaWYgKGlzSlNPTkNvbnRlbnQpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgaXNBcnJheUNvbnRlbnQgPSBBcnJheS5pc0FycmF5KGNvbnRlbnQpICYmIGNvbnRlbnQubGVuZ3RoID4gMFxuXG4gICAgICAvLyBpZiB0aGUgSlNPTiBDb250ZW50IGlzIGFuIGFycmF5IG9mIG5vZGVzLCBjcmVhdGUgYSBmcmFnbWVudCBmb3IgZWFjaCBub2RlXG4gICAgICBpZiAoaXNBcnJheUNvbnRlbnQpIHtcbiAgICAgICAgcmV0dXJuIEZyYWdtZW50LmZyb21BcnJheShjb250ZW50Lm1hcChpdGVtID0+IHNjaGVtYS5ub2RlRnJvbUpTT04oaXRlbSkpKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBub2RlID0gc2NoZW1hLm5vZGVGcm9tSlNPTihjb250ZW50KVxuXG4gICAgICBpZiAob3B0aW9ucy5lcnJvck9uSW52YWxpZENvbnRlbnQpIHtcbiAgICAgICAgbm9kZS5jaGVjaygpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBub2RlXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChvcHRpb25zLmVycm9yT25JbnZhbGlkQ29udGVudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1t0aXB0YXAgZXJyb3JdOiBJbnZhbGlkIEpTT04gY29udGVudCcsIHsgY2F1c2U6IGVycm9yIGFzIEVycm9yIH0pXG4gICAgICB9XG5cbiAgICAgIGNvbnNvbGUud2FybignW3RpcHRhcCB3YXJuXTogSW52YWxpZCBjb250ZW50LicsICdQYXNzZWQgdmFsdWU6JywgY29udGVudCwgJ0Vycm9yOicsIGVycm9yKVxuXG4gICAgICByZXR1cm4gY3JlYXRlTm9kZUZyb21Db250ZW50KCcnLCBzY2hlbWEsIG9wdGlvbnMpXG4gICAgfVxuICB9XG5cbiAgaWYgKGlzVGV4dENvbnRlbnQpIHtcbiAgICAvLyBDaGVjayBmb3IgaW52YWxpZCBjb250ZW50XG4gICAgaWYgKG9wdGlvbnMuZXJyb3JPbkludmFsaWRDb250ZW50KSB7XG4gICAgICBsZXQgaGFzSW52YWxpZENvbnRlbnQgPSBmYWxzZVxuICAgICAgbGV0IGludmFsaWRDb250ZW50ID0gJydcblxuICAgICAgLy8gQSBjb3B5IG9mIHRoZSBjdXJyZW50IHNjaGVtYSB3aXRoIGEgY2F0Y2gtYWxsIG5vZGUgYXQgdGhlIGVuZFxuICAgICAgY29uc3QgY29udGVudENoZWNrU2NoZW1hID0gbmV3IFNjaGVtYSh7XG4gICAgICAgIHRvcE5vZGU6IHNjaGVtYS5zcGVjLnRvcE5vZGUsXG4gICAgICAgIG1hcmtzOiBzY2hlbWEuc3BlYy5tYXJrcyxcbiAgICAgICAgLy8gUHJvc2VtaXJyb3IncyBzY2hlbWFzIGFyZSBleGVjdXRlZCBzdWNoIHRoYXQ6IHRoZSBsYXN0IHRvIGV4ZWN1dGUsIG1hdGNoZXMgbGFzdFxuICAgICAgICAvLyBUaGlzIG1lYW5zIHRoYXQgd2UgY2FuIGFkZCBhIGNhdGNoLWFsbCBub2RlIGF0IHRoZSBlbmQgb2YgdGhlIHNjaGVtYSB0byBjYXRjaCBhbnkgY29udGVudCB0aGF0IHdlIGRvbid0IGtub3cgaG93IHRvIGhhbmRsZVxuICAgICAgICBub2Rlczogc2NoZW1hLnNwZWMubm9kZXMuYXBwZW5kKHtcbiAgICAgICAgICBfX3RpcHRhcF9fcHJpdmF0ZV9fdW5rbm93bl9fY2F0Y2hfX2FsbF9fbm9kZToge1xuICAgICAgICAgICAgY29udGVudDogJ2lubGluZSonLFxuICAgICAgICAgICAgZ3JvdXA6ICdibG9jaycsXG4gICAgICAgICAgICBwYXJzZURPTTogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGFnOiAnKicsXG4gICAgICAgICAgICAgICAgZ2V0QXR0cnM6IGUgPT4ge1xuICAgICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBldmVyIGNhbGxlZCwgd2Uga25vdyB0aGF0IHRoZSBjb250ZW50IGhhcyBzb21ldGhpbmcgdGhhdCB3ZSBkb24ndCBrbm93IGhvdyB0byBoYW5kbGUgaW4gdGhlIHNjaGVtYVxuICAgICAgICAgICAgICAgICAgaGFzSW52YWxpZENvbnRlbnQgPSB0cnVlXG4gICAgICAgICAgICAgICAgICAvLyBUcnkgdG8gc3RyaW5naWZ5IHRoZSBlbGVtZW50IGZvciBhIG1vcmUgaGVscGZ1bCBlcnJvciBtZXNzYWdlXG4gICAgICAgICAgICAgICAgICBpbnZhbGlkQ29udGVudCA9IHR5cGVvZiBlID09PSAnc3RyaW5nJyA/IGUgOiBlLm91dGVySFRNTFxuICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0pXG5cbiAgICAgIGlmIChvcHRpb25zLnNsaWNlKSB7XG4gICAgICAgIERPTVBhcnNlci5mcm9tU2NoZW1hKGNvbnRlbnRDaGVja1NjaGVtYSkucGFyc2VTbGljZShcbiAgICAgICAgICBlbGVtZW50RnJvbVN0cmluZyhjb250ZW50KSxcbiAgICAgICAgICBvcHRpb25zLnBhcnNlT3B0aW9ucyxcbiAgICAgICAgKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgRE9NUGFyc2VyLmZyb21TY2hlbWEoY29udGVudENoZWNrU2NoZW1hKS5wYXJzZShcbiAgICAgICAgICBlbGVtZW50RnJvbVN0cmluZyhjb250ZW50KSxcbiAgICAgICAgICBvcHRpb25zLnBhcnNlT3B0aW9ucyxcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5lcnJvck9uSW52YWxpZENvbnRlbnQgJiYgaGFzSW52YWxpZENvbnRlbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdbdGlwdGFwIGVycm9yXTogSW52YWxpZCBIVE1MIGNvbnRlbnQnLCB7XG4gICAgICAgICAgY2F1c2U6IG5ldyBFcnJvcihgSW52YWxpZCBlbGVtZW50IGZvdW5kOiAke2ludmFsaWRDb250ZW50fWApLFxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHBhcnNlciA9IERPTVBhcnNlci5mcm9tU2NoZW1hKHNjaGVtYSlcblxuICAgIGlmIChvcHRpb25zLnNsaWNlKSB7XG4gICAgICByZXR1cm4gcGFyc2VyLnBhcnNlU2xpY2UoZWxlbWVudEZyb21TdHJpbmcoY29udGVudCksIG9wdGlvbnMucGFyc2VPcHRpb25zKS5jb250ZW50XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcnNlci5wYXJzZShlbGVtZW50RnJvbVN0cmluZyhjb250ZW50KSwgb3B0aW9ucy5wYXJzZU9wdGlvbnMpXG4gIH1cblxuICByZXR1cm4gY3JlYXRlTm9kZUZyb21Db250ZW50KCcnLCBzY2hlbWEsIG9wdGlvbnMpXG59XG4iLCAiY29uc3QgcmVtb3ZlV2hpdGVzcGFjZXMgPSAobm9kZTogSFRNTEVsZW1lbnQpID0+IHtcbiAgY29uc3QgY2hpbGRyZW4gPSBub2RlLmNoaWxkTm9kZXNcblxuICBmb3IgKGxldCBpID0gY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpIC09IDEpIHtcbiAgICBjb25zdCBjaGlsZCA9IGNoaWxkcmVuW2ldXG5cbiAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT09IDMgJiYgY2hpbGQubm9kZVZhbHVlICYmIC9eKFxcblxcc1xcc3xcXG4pJC8udGVzdChjaGlsZC5ub2RlVmFsdWUpKSB7XG4gICAgICBub2RlLnJlbW92ZUNoaWxkKGNoaWxkKVxuICAgIH0gZWxzZSBpZiAoY2hpbGQubm9kZVR5cGUgPT09IDEpIHtcbiAgICAgIHJlbW92ZVdoaXRlc3BhY2VzKGNoaWxkIGFzIEhUTUxFbGVtZW50KVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBub2RlXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbGVtZW50RnJvbVN0cmluZyh2YWx1ZTogc3RyaW5nKTogSFRNTEVsZW1lbnQge1xuICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnW3RpcHRhcCBlcnJvcl06IHRoZXJlIGlzIG5vIHdpbmRvdyBvYmplY3QgYXZhaWxhYmxlLCBzbyB0aGlzIGZ1bmN0aW9uIGNhbm5vdCBiZSB1c2VkJyxcbiAgICApXG4gIH1cbiAgLy8gYWRkIGEgd3JhcHBlciB0byBwcmVzZXJ2ZSBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlXG4gIGNvbnN0IHdyYXBwZWRWYWx1ZSA9IGA8Ym9keT4ke3ZhbHVlfTwvYm9keT5gXG5cbiAgY29uc3QgaHRtbCA9IG5ldyB3aW5kb3cuRE9NUGFyc2VyKCkucGFyc2VGcm9tU3RyaW5nKHdyYXBwZWRWYWx1ZSwgJ3RleHQvaHRtbCcpLmJvZHlcblxuICByZXR1cm4gcmVtb3ZlV2hpdGVzcGFjZXMoaHRtbClcbn1cbiIsICJpbXBvcnQgdHlwZSB7IFRyYW5zYWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcbmltcG9ydCB7IFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgeyBSZXBsYWNlQXJvdW5kU3RlcCwgUmVwbGFjZVN0ZXAgfSBmcm9tICdAdGlwdGFwL3BtL3RyYW5zZm9ybSdcblxuLy8gc291cmNlOiBodHRwczovL2dpdGh1Yi5jb20vUHJvc2VNaXJyb3IvcHJvc2VtaXJyb3Itc3RhdGUvYmxvYi9tYXN0ZXIvc3JjL3NlbGVjdGlvbi5qcyNMNDY2XG5leHBvcnQgZnVuY3Rpb24gc2VsZWN0aW9uVG9JbnNlcnRpb25FbmQodHI6IFRyYW5zYWN0aW9uLCBzdGFydExlbjogbnVtYmVyLCBiaWFzOiBudW1iZXIpIHtcbiAgY29uc3QgbGFzdCA9IHRyLnN0ZXBzLmxlbmd0aCAtIDFcblxuICBpZiAobGFzdCA8IHN0YXJ0TGVuKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBjb25zdCBzdGVwID0gdHIuc3RlcHNbbGFzdF1cblxuICBpZiAoIShzdGVwIGluc3RhbmNlb2YgUmVwbGFjZVN0ZXAgfHwgc3RlcCBpbnN0YW5jZW9mIFJlcGxhY2VBcm91bmRTdGVwKSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgY29uc3QgbWFwID0gdHIubWFwcGluZy5tYXBzW2xhc3RdXG4gIGxldCBlbmQgPSAwXG5cbiAgbWFwLmZvckVhY2goKF9mcm9tLCBfdG8sIF9uZXdGcm9tLCBuZXdUbykgPT4ge1xuICAgIGlmIChlbmQgPT09IDApIHtcbiAgICAgIGVuZCA9IG5ld1RvXG4gICAgfVxuICB9KVxuXG4gIHRyLnNldFNlbGVjdGlvbihTZWxlY3Rpb24ubmVhcih0ci5kb2MucmVzb2x2ZShlbmQpLCBiaWFzKSlcbn1cbiIsICJpbXBvcnQge1xuICBqb2luQmFja3dhcmQgYXMgb3JpZ2luYWxKb2luQmFja3dhcmQsXG4gIGpvaW5Eb3duIGFzIG9yaWdpbmFsSm9pbkRvd24sXG4gIGpvaW5Gb3J3YXJkIGFzIG9yaWdpbmFsSm9pbkZvcndhcmQsXG4gIGpvaW5VcCBhcyBvcmlnaW5hbEpvaW5VcCxcbn0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcblxuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgam9pblVwOiB7XG4gICAgICAvKipcbiAgICAgICAqIEpvaW4gdGhlIHNlbGVjdGVkIGJsb2NrIG9yLCBpZiB0aGVyZSBpcyBhIHRleHQgc2VsZWN0aW9uLCB0aGUgY2xvc2VzdCBhbmNlc3RvciBibG9jayBvZiB0aGUgc2VsZWN0aW9uIHRoYXQgY2FuIGJlIGpvaW5lZCwgd2l0aCB0aGUgc2libGluZyBhYm92ZSBpdC5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5qb2luVXAoKVxuICAgICAgICovXG4gICAgICBqb2luVXA6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gICAgam9pbkRvd246IHtcbiAgICAgIC8qKlxuICAgICAgICogSm9pbiB0aGUgc2VsZWN0ZWQgYmxvY2ssIG9yIHRoZSBjbG9zZXN0IGFuY2VzdG9yIG9mIHRoZSBzZWxlY3Rpb24gdGhhdCBjYW4gYmUgam9pbmVkLCB3aXRoIHRoZSBzaWJsaW5nIGFmdGVyIGl0LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmpvaW5Eb3duKClcbiAgICAgICAqL1xuICAgICAgam9pbkRvd246ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gICAgam9pbkJhY2t3YXJkOiB7XG4gICAgICAvKipcbiAgICAgICAqIElmIHRoZSBzZWxlY3Rpb24gaXMgZW1wdHkgYW5kIGF0IHRoZSBzdGFydCBvZiBhIHRleHRibG9jaywgdHJ5IHRvIHJlZHVjZSB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0aGF0IGJsb2NrIGFuZCB0aGUgb25lIGJlZm9yZSBpdOKAlGlmIHRoZXJlJ3MgYSBibG9jayBkaXJlY3RseSBiZWZvcmUgaXQgdGhhdCBjYW4gYmUgam9pbmVkLCBqb2luIHRoZW0uXG4gICAgICAgKiBJZiBub3QsIHRyeSB0byBtb3ZlIHRoZSBzZWxlY3RlZCBibG9jayBjbG9zZXIgdG8gdGhlIG5leHQgb25lIGluIHRoZSBkb2N1bWVudCBzdHJ1Y3R1cmUgYnkgbGlmdGluZyBpdCBvdXQgb2YgaXRzXG4gICAgICAgKiBwYXJlbnQgb3IgbW92aW5nIGl0IGludG8gYSBwYXJlbnQgb2YgdGhlIHByZXZpb3VzIGJsb2NrLiBXaWxsIHVzZSB0aGUgdmlldyBmb3IgYWNjdXJhdGUgKGJpZGktYXdhcmUpIHN0YXJ0LW9mLXRleHRibG9jayBkZXRlY3Rpb24gaWYgZ2l2ZW4uXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuam9pbkJhY2t3YXJkKClcbiAgICAgICAqL1xuICAgICAgam9pbkJhY2t3YXJkOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICAgIGpvaW5Gb3J3YXJkOiB7XG4gICAgICAvKipcbiAgICAgICAqIElmIHRoZSBzZWxlY3Rpb24gaXMgZW1wdHkgYW5kIHRoZSBjdXJzb3IgaXMgYXQgdGhlIGVuZCBvZiBhIHRleHRibG9jaywgdHJ5IHRvIHJlZHVjZSBvciByZW1vdmUgdGhlIGJvdW5kYXJ5IGJldHdlZW4gdGhhdCBibG9jayBhbmQgdGhlIG9uZSBhZnRlciBpdCxcbiAgICAgICAqIGVpdGhlciBieSBqb2luaW5nIHRoZW0gb3IgYnkgbW92aW5nIHRoZSBvdGhlciBibG9jayBjbG9zZXIgdG8gdGhpcyBvbmUgaW4gdGhlIHRyZWUgc3RydWN0dXJlLlxuICAgICAgICogV2lsbCB1c2UgdGhlIHZpZXcgZm9yIGFjY3VyYXRlIHN0YXJ0LW9mLXRleHRibG9jayBkZXRlY3Rpb24gaWYgZ2l2ZW4uXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuam9pbkZvcndhcmQoKVxuICAgICAgICovXG4gICAgICBqb2luRm9yd2FyZDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgam9pblVwOiBSYXdDb21tYW5kc1snam9pblVwJ10gPVxuICAoKSA9PlxuICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgIHJldHVybiBvcmlnaW5hbEpvaW5VcChzdGF0ZSwgZGlzcGF0Y2gpXG4gIH1cblxuZXhwb3J0IGNvbnN0IGpvaW5Eb3duOiBSYXdDb21tYW5kc1snam9pbkRvd24nXSA9XG4gICgpID0+XG4gICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgcmV0dXJuIG9yaWdpbmFsSm9pbkRvd24oc3RhdGUsIGRpc3BhdGNoKVxuICB9XG5cbmV4cG9ydCBjb25zdCBqb2luQmFja3dhcmQ6IFJhd0NvbW1hbmRzWydqb2luQmFja3dhcmQnXSA9XG4gICgpID0+XG4gICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgcmV0dXJuIG9yaWdpbmFsSm9pbkJhY2t3YXJkKHN0YXRlLCBkaXNwYXRjaClcbiAgfVxuXG5leHBvcnQgY29uc3Qgam9pbkZvcndhcmQ6IFJhd0NvbW1hbmRzWydqb2luRm9yd2FyZCddID1cbiAgKCkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICByZXR1cm4gb3JpZ2luYWxKb2luRm9yd2FyZChzdGF0ZSwgZGlzcGF0Y2gpXG4gIH1cbiIsICJpbXBvcnQgeyBqb2luUG9pbnQgfSBmcm9tICdAdGlwdGFwL3BtL3RyYW5zZm9ybSdcblxuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgam9pbkl0ZW1CYWNrd2FyZDoge1xuICAgICAgLyoqXG4gICAgICAgKiBKb2luIHR3byBpdGVtcyBiYWNrd2FyZC5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5qb2luSXRlbUJhY2t3YXJkKClcbiAgICAgICAqL1xuICAgICAgam9pbkl0ZW1CYWNrd2FyZDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgam9pbkl0ZW1CYWNrd2FyZDogUmF3Q29tbWFuZHNbJ2pvaW5JdGVtQmFja3dhcmQnXSA9XG4gICgpID0+XG4gICh7IHN0YXRlLCBkaXNwYXRjaCwgdHIgfSkgPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwb2ludCA9IGpvaW5Qb2ludChzdGF0ZS5kb2MsIHN0YXRlLnNlbGVjdGlvbi4kZnJvbS5wb3MsIC0xKVxuXG4gICAgICBpZiAocG9pbnQgPT09IG51bGwgfHwgcG9pbnQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cblxuICAgICAgdHIuam9pbihwb2ludCwgMilcblxuICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgIGRpc3BhdGNoKHRyKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG4iLCAiaW1wb3J0IHsgam9pblBvaW50IH0gZnJvbSAnQHRpcHRhcC9wbS90cmFuc2Zvcm0nXG5cbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGpvaW5JdGVtRm9yd2FyZDoge1xuICAgICAgLyoqXG4gICAgICAgKiBKb2luIHR3byBpdGVtcyBGb3J3YXJkcy5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5qb2luSXRlbUZvcndhcmQoKVxuICAgICAgICovXG4gICAgICBqb2luSXRlbUZvcndhcmQ6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGpvaW5JdGVtRm9yd2FyZDogUmF3Q29tbWFuZHNbJ2pvaW5JdGVtRm9yd2FyZCddID1cbiAgKCkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoLCB0ciB9KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBvaW50ID0gam9pblBvaW50KHN0YXRlLmRvYywgc3RhdGUuc2VsZWN0aW9uLiRmcm9tLnBvcywgKzEpXG5cbiAgICAgIGlmIChwb2ludCA9PT0gbnVsbCB8fCBwb2ludCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuXG4gICAgICB0ci5qb2luKHBvaW50LCAyKVxuXG4gICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgZGlzcGF0Y2godHIpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cbiIsICJpbXBvcnQgeyBqb2luVGV4dGJsb2NrQmFja3dhcmQgYXMgb3JpZ2luYWxDb21tYW5kIH0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcblxuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgam9pblRleHRibG9ja0JhY2t3YXJkOiB7XG4gICAgICAvKipcbiAgICAgICAqIEEgbW9yZSBsaW1pdGVkIGZvcm0gb2Ygam9pbkJhY2t3YXJkIHRoYXQgb25seSB0cmllcyB0byBqb2luIHRoZSBjdXJyZW50IHRleHRibG9jayB0byB0aGUgb25lIGJlZm9yZSBpdCwgaWYgdGhlIGN1cnNvciBpcyBhdCB0aGUgc3RhcnQgb2YgYSB0ZXh0YmxvY2suXG4gICAgICAgKi9cbiAgICAgIGpvaW5UZXh0YmxvY2tCYWNrd2FyZDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgam9pblRleHRibG9ja0JhY2t3YXJkOiBSYXdDb21tYW5kc1snam9pblRleHRibG9ja0JhY2t3YXJkJ10gPVxuICAoKSA9PlxuICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgIHJldHVybiBvcmlnaW5hbENvbW1hbmQoc3RhdGUsIGRpc3BhdGNoKVxuICB9XG4iLCAiaW1wb3J0IHsgam9pblRleHRibG9ja0ZvcndhcmQgYXMgb3JpZ2luYWxDb21tYW5kIH0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcblxuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgam9pblRleHRibG9ja0ZvcndhcmQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogQSBtb3JlIGxpbWl0ZWQgZm9ybSBvZiBqb2luRm9yd2FyZCB0aGF0IG9ubHkgdHJpZXMgdG8gam9pbiB0aGUgY3VycmVudCB0ZXh0YmxvY2sgdG8gdGhlIG9uZSBhZnRlciBpdCwgaWYgdGhlIGN1cnNvciBpcyBhdCB0aGUgZW5kIG9mIGEgdGV4dGJsb2NrLlxuICAgICAgICovXG4gICAgICBqb2luVGV4dGJsb2NrRm9yd2FyZDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgam9pblRleHRibG9ja0ZvcndhcmQ6IFJhd0NvbW1hbmRzWydqb2luVGV4dGJsb2NrRm9yd2FyZCddID1cbiAgKCkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICByZXR1cm4gb3JpZ2luYWxDb21tYW5kKHN0YXRlLCBkaXNwYXRjaClcbiAgfVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpc01hY09TKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgPyAvTWFjLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSkgOiBmYWxzZVxufVxuIiwgImltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGlzaU9TIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2lzaU9TLmpzJ1xuaW1wb3J0IHsgaXNNYWNPUyB9IGZyb20gJy4uL3V0aWxpdGllcy9pc01hY09TLmpzJ1xuXG5mdW5jdGlvbiBub3JtYWxpemVLZXlOYW1lKG5hbWU6IHN0cmluZykge1xuICBjb25zdCBwYXJ0cyA9IG5hbWUuc3BsaXQoLy0oPyEkKS8pXG4gIGxldCByZXN1bHQgPSBwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXVxuXG4gIGlmIChyZXN1bHQgPT09ICdTcGFjZScpIHtcbiAgICByZXN1bHQgPSAnICdcbiAgfVxuXG4gIGxldCBhbHRcbiAgbGV0IGN0cmxcbiAgbGV0IHNoaWZ0XG4gIGxldCBtZXRhXG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGggLSAxOyBpICs9IDEpIHtcbiAgICBjb25zdCBtb2QgPSBwYXJ0c1tpXVxuXG4gICAgaWYgKC9eKGNtZHxtZXRhfG0pJC9pLnRlc3QobW9kKSkge1xuICAgICAgbWV0YSA9IHRydWVcbiAgICB9IGVsc2UgaWYgKC9eYShsdCk/JC9pLnRlc3QobW9kKSkge1xuICAgICAgYWx0ID0gdHJ1ZVxuICAgIH0gZWxzZSBpZiAoL14oY3xjdHJsfGNvbnRyb2wpJC9pLnRlc3QobW9kKSkge1xuICAgICAgY3RybCA9IHRydWVcbiAgICB9IGVsc2UgaWYgKC9ecyhoaWZ0KT8kL2kudGVzdChtb2QpKSB7XG4gICAgICBzaGlmdCA9IHRydWVcbiAgICB9IGVsc2UgaWYgKC9ebW9kJC9pLnRlc3QobW9kKSkge1xuICAgICAgaWYgKGlzaU9TKCkgfHwgaXNNYWNPUygpKSB7XG4gICAgICAgIG1ldGEgPSB0cnVlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdHJsID0gdHJ1ZVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBtb2RpZmllciBuYW1lOiAke21vZH1gKVxuICAgIH1cbiAgfVxuXG4gIGlmIChhbHQpIHtcbiAgICByZXN1bHQgPSBgQWx0LSR7cmVzdWx0fWBcbiAgfVxuXG4gIGlmIChjdHJsKSB7XG4gICAgcmVzdWx0ID0gYEN0cmwtJHtyZXN1bHR9YFxuICB9XG5cbiAgaWYgKG1ldGEpIHtcbiAgICByZXN1bHQgPSBgTWV0YS0ke3Jlc3VsdH1gXG4gIH1cblxuICBpZiAoc2hpZnQpIHtcbiAgICByZXN1bHQgPSBgU2hpZnQtJHtyZXN1bHR9YFxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAga2V5Ym9hcmRTaG9ydGN1dDoge1xuICAgICAgLyoqXG4gICAgICAgKiBUcmlnZ2VyIGEga2V5Ym9hcmQgc2hvcnRjdXQuXG4gICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgbmFtZSBvZiB0aGUga2V5Ym9hcmQgc2hvcnRjdXQuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMua2V5Ym9hcmRTaG9ydGN1dCgnTW9kLWInKVxuICAgICAgICovXG4gICAgICBrZXlib2FyZFNob3J0Y3V0OiAobmFtZTogc3RyaW5nKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBrZXlib2FyZFNob3J0Y3V0OiBSYXdDb21tYW5kc1sna2V5Ym9hcmRTaG9ydGN1dCddID1cbiAgbmFtZSA9PlxuICAoeyBlZGl0b3IsIHZpZXcsIHRyLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgY29uc3Qga2V5cyA9IG5vcm1hbGl6ZUtleU5hbWUobmFtZSkuc3BsaXQoLy0oPyEkKS8pXG4gICAgY29uc3Qga2V5ID0ga2V5cy5maW5kKGl0ZW0gPT4gIVsnQWx0JywgJ0N0cmwnLCAnTWV0YScsICdTaGlmdCddLmluY2x1ZGVzKGl0ZW0pKVxuICAgIGNvbnN0IGV2ZW50ID0gbmV3IEtleWJvYXJkRXZlbnQoJ2tleWRvd24nLCB7XG4gICAgICBrZXk6IGtleSA9PT0gJ1NwYWNlJyA/ICcgJyA6IGtleSxcbiAgICAgIGFsdEtleToga2V5cy5pbmNsdWRlcygnQWx0JyksXG4gICAgICBjdHJsS2V5OiBrZXlzLmluY2x1ZGVzKCdDdHJsJyksXG4gICAgICBtZXRhS2V5OiBrZXlzLmluY2x1ZGVzKCdNZXRhJyksXG4gICAgICBzaGlmdEtleToga2V5cy5pbmNsdWRlcygnU2hpZnQnKSxcbiAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICBjYW5jZWxhYmxlOiB0cnVlLFxuICAgIH0pXG5cbiAgICBjb25zdCBjYXB0dXJlZFRyYW5zYWN0aW9uID0gZWRpdG9yLmNhcHR1cmVUcmFuc2FjdGlvbigoKSA9PiB7XG4gICAgICB2aWV3LnNvbWVQcm9wKCdoYW5kbGVLZXlEb3duJywgZiA9PiBmKHZpZXcsIGV2ZW50KSlcbiAgICB9KVxuXG4gICAgY2FwdHVyZWRUcmFuc2FjdGlvbj8uc3RlcHMuZm9yRWFjaChzdGVwID0+IHtcbiAgICAgIGNvbnN0IG5ld1N0ZXAgPSBzdGVwLm1hcCh0ci5tYXBwaW5nKVxuXG4gICAgICBpZiAobmV3U3RlcCAmJiBkaXNwYXRjaCkge1xuICAgICAgICB0ci5tYXliZVN0ZXAobmV3U3RlcClcbiAgICAgIH1cbiAgICB9KVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuIiwgImltcG9ydCB7IGxpZnQgYXMgb3JpZ2luYWxMaWZ0IH0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcbmltcG9ydCB0eXBlIHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBpc05vZGVBY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL2lzTm9kZUFjdGl2ZS5qcydcbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGxpZnQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogUmVtb3ZlcyBhbiBleGlzdGluZyB3cmFwIGlmIHBvc3NpYmxlIGxpZnRpbmcgdGhlIG5vZGUgb3V0IG9mIGl0XG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBub2RlLlxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMubGlmdCgncGFyYWdyYXBoJylcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5saWZ0KCdoZWFkaW5nJywgeyBsZXZlbDogMSB9KVxuICAgICAgICovXG4gICAgICBsaWZ0OiAodHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUsIGF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBsaWZ0OiBSYXdDb21tYW5kc1snbGlmdCddID1cbiAgKHR5cGVPck5hbWUsIGF0dHJpYnV0ZXMgPSB7fSkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICBjb25zdCB0eXBlID0gZ2V0Tm9kZVR5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuICAgIGNvbnN0IGlzQWN0aXZlID0gaXNOb2RlQWN0aXZlKHN0YXRlLCB0eXBlLCBhdHRyaWJ1dGVzKVxuXG4gICAgaWYgKCFpc0FjdGl2ZSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgcmV0dXJuIG9yaWdpbmFsTGlmdChzdGF0ZSwgZGlzcGF0Y2gpXG4gIH1cbiIsICJpbXBvcnQgdHlwZSB7IE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgdHlwZSB7IE5vZGVSYW5nZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgb2JqZWN0SW5jbHVkZXMgfSBmcm9tICcuLi91dGlsaXRpZXMvb2JqZWN0SW5jbHVkZXMuanMnXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4vZ2V0Tm9kZVR5cGUuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBpc05vZGVBY3RpdmUoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgdHlwZU9yTmFtZTogTm9kZVR5cGUgfCBzdHJpbmcgfCBudWxsLFxuICBhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge30sXG4pOiBib29sZWFuIHtcbiAgY29uc3QgeyBmcm9tLCB0bywgZW1wdHkgfSA9IHN0YXRlLnNlbGVjdGlvblxuICBjb25zdCB0eXBlID0gdHlwZU9yTmFtZSA/IGdldE5vZGVUeXBlKHR5cGVPck5hbWUsIHN0YXRlLnNjaGVtYSkgOiBudWxsXG5cbiAgY29uc3Qgbm9kZVJhbmdlczogTm9kZVJhbmdlW10gPSBbXVxuXG4gIHN0YXRlLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MpID0+IHtcbiAgICBpZiAobm9kZS5pc1RleHQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHJlbGF0aXZlRnJvbSA9IE1hdGgubWF4KGZyb20sIHBvcylcbiAgICBjb25zdCByZWxhdGl2ZVRvID0gTWF0aC5taW4odG8sIHBvcyArIG5vZGUubm9kZVNpemUpXG5cbiAgICBub2RlUmFuZ2VzLnB1c2goe1xuICAgICAgbm9kZSxcbiAgICAgIGZyb206IHJlbGF0aXZlRnJvbSxcbiAgICAgIHRvOiByZWxhdGl2ZVRvLFxuICAgIH0pXG4gIH0pXG5cbiAgY29uc3Qgc2VsZWN0aW9uUmFuZ2UgPSB0byAtIGZyb21cbiAgY29uc3QgbWF0Y2hlZE5vZGVSYW5nZXMgPSBub2RlUmFuZ2VzXG4gICAgLmZpbHRlcihub2RlUmFuZ2UgPT4ge1xuICAgICAgaWYgKCF0eXBlKSB7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0eXBlLm5hbWUgPT09IG5vZGVSYW5nZS5ub2RlLnR5cGUubmFtZVxuICAgIH0pXG4gICAgLmZpbHRlcihub2RlUmFuZ2UgPT4gb2JqZWN0SW5jbHVkZXMobm9kZVJhbmdlLm5vZGUuYXR0cnMsIGF0dHJpYnV0ZXMsIHsgc3RyaWN0OiBmYWxzZSB9KSlcblxuICBpZiAoZW1wdHkpIHtcbiAgICByZXR1cm4gISFtYXRjaGVkTm9kZVJhbmdlcy5sZW5ndGhcbiAgfVxuXG4gIGNvbnN0IHJhbmdlID0gbWF0Y2hlZE5vZGVSYW5nZXMucmVkdWNlKChzdW0sIG5vZGVSYW5nZSkgPT4gc3VtICsgbm9kZVJhbmdlLnRvIC0gbm9kZVJhbmdlLmZyb20sIDApXG5cbiAgcmV0dXJuIHJhbmdlID49IHNlbGVjdGlvblJhbmdlXG59XG4iLCAiaW1wb3J0IHsgbGlmdEVtcHR5QmxvY2sgYXMgb3JpZ2luYWxMaWZ0RW1wdHlCbG9jayB9IGZyb20gJ0B0aXB0YXAvcG0vY29tbWFuZHMnXG5cbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGxpZnRFbXB0eUJsb2NrOiB7XG4gICAgICAvKipcbiAgICAgICAqIElmIHRoZSBjdXJzb3IgaXMgaW4gYW4gZW1wdHkgdGV4dGJsb2NrIHRoYXQgY2FuIGJlIGxpZnRlZCwgbGlmdCB0aGUgYmxvY2suXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMubGlmdEVtcHR5QmxvY2soKVxuICAgICAgICovXG4gICAgICBsaWZ0RW1wdHlCbG9jazogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgbGlmdEVtcHR5QmxvY2s6IFJhd0NvbW1hbmRzWydsaWZ0RW1wdHlCbG9jayddID1cbiAgKCkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICByZXR1cm4gb3JpZ2luYWxMaWZ0RW1wdHlCbG9jayhzdGF0ZSwgZGlzcGF0Y2gpXG4gIH1cbiIsICJpbXBvcnQgdHlwZSB7IE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IGxpZnRMaXN0SXRlbSBhcyBvcmlnaW5hbExpZnRMaXN0SXRlbSB9IGZyb20gJ0B0aXB0YXAvcG0vc2NoZW1hLWxpc3QnXG5cbmltcG9ydCB7IGdldE5vZGVUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXROb2RlVHlwZS5qcydcbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGxpZnRMaXN0SXRlbToge1xuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGUgYSBjb21tYW5kIHRvIGxpZnQgdGhlIGxpc3QgaXRlbSBhcm91bmQgdGhlIHNlbGVjdGlvbiB1cCBpbnRvIGEgd3JhcHBpbmcgbGlzdC5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMubGlmdExpc3RJdGVtKCdsaXN0SXRlbScpXG4gICAgICAgKi9cbiAgICAgIGxpZnRMaXN0SXRlbTogKHR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBsaWZ0TGlzdEl0ZW06IFJhd0NvbW1hbmRzWydsaWZ0TGlzdEl0ZW0nXSA9XG4gIHR5cGVPck5hbWUgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICBjb25zdCB0eXBlID0gZ2V0Tm9kZVR5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuXG4gICAgcmV0dXJuIG9yaWdpbmFsTGlmdExpc3RJdGVtKHR5cGUpKHN0YXRlLCBkaXNwYXRjaClcbiAgfVxuIiwgImltcG9ydCB7IG5ld2xpbmVJbkNvZGUgYXMgb3JpZ2luYWxOZXdsaW5lSW5Db2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcblxuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgbmV3bGluZUluQ29kZToge1xuICAgICAgLyoqXG4gICAgICAgKiBBZGQgYSBuZXdsaW5lIGNoYXJhY3RlciBpbiBjb2RlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLm5ld2xpbmVJbkNvZGUoKVxuICAgICAgICovXG4gICAgICBuZXdsaW5lSW5Db2RlOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBuZXdsaW5lSW5Db2RlOiBSYXdDb21tYW5kc1snbmV3bGluZUluQ29kZSddID1cbiAgKCkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICByZXR1cm4gb3JpZ2luYWxOZXdsaW5lSW5Db2RlKHN0YXRlLCBkaXNwYXRjaClcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgU2NoZW1hIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuLyoqXG4gKiBHZXQgdGhlIHR5cGUgb2YgYSBzY2hlbWEgaXRlbSBieSBpdHMgbmFtZS5cbiAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBzY2hlbWEgaXRlbVxuICogQHBhcmFtIHNjaGVtYSBUaGUgUHJvc2VtaXJvciBzY2hlbWEgdG8gc2VhcmNoIGluXG4gKiBAcmV0dXJucyBUaGUgdHlwZSBvZiB0aGUgc2NoZW1hIGl0ZW0gKGBub2RlYCBvciBgbWFya2ApLCBvciBudWxsIGlmIGl0IGRvZXNuJ3QgZXhpc3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNjaGVtYVR5cGVOYW1lQnlOYW1lKG5hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWEpOiAnbm9kZScgfCAnbWFyaycgfCBudWxsIHtcbiAgaWYgKHNjaGVtYS5ub2Rlc1tuYW1lXSkge1xuICAgIHJldHVybiAnbm9kZSdcbiAgfVxuXG4gIGlmIChzY2hlbWEubWFya3NbbmFtZV0pIHtcbiAgICByZXR1cm4gJ21hcmsnXG4gIH1cblxuICByZXR1cm4gbnVsbFxufVxuIiwgIi8qKlxuICogUmVtb3ZlIGEgcHJvcGVydHkgb3IgYW4gYXJyYXkgb2YgcHJvcGVydGllcyBmcm9tIGFuIG9iamVjdFxuICogQHBhcmFtIG9iaiBPYmplY3RcbiAqIEBwYXJhbSBrZXkgS2V5IHRvIHJlbW92ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlUHJvcHMoXG4gIG9iajogUmVjb3JkPHN0cmluZywgYW55PixcbiAgcHJvcE9yUHJvcHM6IHN0cmluZyB8IHN0cmluZ1tdLFxuKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gIGNvbnN0IHByb3BzID0gdHlwZW9mIHByb3BPclByb3BzID09PSAnc3RyaW5nJyA/IFtwcm9wT3JQcm9wc10gOiBwcm9wT3JQcm9wc1xuXG4gIHJldHVybiBPYmplY3Qua2V5cyhvYmopLnJlZHVjZSgobmV3T2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBwcm9wKSA9PiB7XG4gICAgaWYgKCFwcm9wcy5pbmNsdWRlcyhwcm9wKSkge1xuICAgICAgbmV3T2JqW3Byb3BdID0gb2JqW3Byb3BdXG4gICAgfVxuXG4gICAgcmV0dXJuIG5ld09ialxuICB9LCB7fSlcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE1hcmtUeXBlLCBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IGdldE1hcmtUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXRNYXJrVHlwZS5qcydcbmltcG9ydCB7IGdldE5vZGVUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXROb2RlVHlwZS5qcydcbmltcG9ydCB7IGdldFNjaGVtYVR5cGVOYW1lQnlOYW1lIH0gZnJvbSAnLi4vaGVscGVycy9nZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZS5qcydcbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGRlbGV0ZVByb3BzIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2RlbGV0ZVByb3BzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgcmVzZXRBdHRyaWJ1dGVzOiB7XG4gICAgICAvKipcbiAgICAgICAqIFJlc2V0cyBzb21lIG5vZGUgYXR0cmlidXRlcyB0byB0aGUgZGVmYXVsdCB2YWx1ZS5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBvZiB0aGUgbm9kZSB0byByZXNldC5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5yZXNldEF0dHJpYnV0ZXMoJ2hlYWRpbmcnLCAnbGV2ZWwnKVxuICAgICAgICovXG4gICAgICByZXNldEF0dHJpYnV0ZXM6IChcbiAgICAgICAgdHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUgfCBNYXJrVHlwZSxcbiAgICAgICAgYXR0cmlidXRlczogc3RyaW5nIHwgc3RyaW5nW10sXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHJlc2V0QXR0cmlidXRlczogUmF3Q29tbWFuZHNbJ3Jlc2V0QXR0cmlidXRlcyddID1cbiAgKHR5cGVPck5hbWUsIGF0dHJpYnV0ZXMpID0+XG4gICh7IHRyLCBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgIGxldCBub2RlVHlwZTogTm9kZVR5cGUgfCBudWxsID0gbnVsbFxuICAgIGxldCBtYXJrVHlwZTogTWFya1R5cGUgfCBudWxsID0gbnVsbFxuXG4gICAgY29uc3Qgc2NoZW1hVHlwZSA9IGdldFNjaGVtYVR5cGVOYW1lQnlOYW1lKFxuICAgICAgdHlwZW9mIHR5cGVPck5hbWUgPT09ICdzdHJpbmcnID8gdHlwZU9yTmFtZSA6IHR5cGVPck5hbWUubmFtZSxcbiAgICAgIHN0YXRlLnNjaGVtYSxcbiAgICApXG5cbiAgICBpZiAoIXNjaGVtYVR5cGUpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGlmIChzY2hlbWFUeXBlID09PSAnbm9kZScpIHtcbiAgICAgIG5vZGVUeXBlID0gZ2V0Tm9kZVR5cGUodHlwZU9yTmFtZSBhcyBOb2RlVHlwZSwgc3RhdGUuc2NoZW1hKVxuICAgIH1cblxuICAgIGlmIChzY2hlbWFUeXBlID09PSAnbWFyaycpIHtcbiAgICAgIG1hcmtUeXBlID0gZ2V0TWFya1R5cGUodHlwZU9yTmFtZSBhcyBNYXJrVHlwZSwgc3RhdGUuc2NoZW1hKVxuICAgIH1cblxuICAgIGxldCBjYW5SZXNldCA9IGZhbHNlXG5cbiAgICB0ci5zZWxlY3Rpb24ucmFuZ2VzLmZvckVhY2gocmFuZ2UgPT4ge1xuICAgICAgc3RhdGUuZG9jLm5vZGVzQmV0d2VlbihyYW5nZS4kZnJvbS5wb3MsIHJhbmdlLiR0by5wb3MsIChub2RlLCBwb3MpID0+IHtcbiAgICAgICAgaWYgKG5vZGVUeXBlICYmIG5vZGVUeXBlID09PSBub2RlLnR5cGUpIHtcbiAgICAgICAgICBjYW5SZXNldCA9IHRydWVcblxuICAgICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgICAgdHIuc2V0Tm9kZU1hcmt1cChwb3MsIHVuZGVmaW5lZCwgZGVsZXRlUHJvcHMobm9kZS5hdHRycywgYXR0cmlidXRlcykpXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1hcmtUeXBlICYmIG5vZGUubWFya3MubGVuZ3RoKSB7XG4gICAgICAgICAgbm9kZS5tYXJrcy5mb3JFYWNoKG1hcmsgPT4ge1xuICAgICAgICAgICAgaWYgKG1hcmtUeXBlID09PSBtYXJrLnR5cGUpIHtcbiAgICAgICAgICAgICAgY2FuUmVzZXQgPSB0cnVlXG5cbiAgICAgICAgICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgICAgICAgICAgdHIuYWRkTWFyayhcbiAgICAgICAgICAgICAgICAgIHBvcyxcbiAgICAgICAgICAgICAgICAgIHBvcyArIG5vZGUubm9kZVNpemUsXG4gICAgICAgICAgICAgICAgICBtYXJrVHlwZS5jcmVhdGUoZGVsZXRlUHJvcHMobWFyay5hdHRycywgYXR0cmlidXRlcykpLFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfSlcblxuICAgIHJldHVybiBjYW5SZXNldFxuICB9XG4iLCAiaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2Nyb2xsSW50b1ZpZXc6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2Nyb2xsIHRoZSBzZWxlY3Rpb24gaW50byB2aWV3LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNjcm9sbEludG9WaWV3KClcbiAgICAgICAqL1xuICAgICAgc2Nyb2xsSW50b1ZpZXc6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNjcm9sbEludG9WaWV3OiBSYXdDb21tYW5kc1snc2Nyb2xsSW50b1ZpZXcnXSA9XG4gICgpID0+XG4gICh7IHRyLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICB0ci5zY3JvbGxJbnRvVmlldygpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuIiwgImltcG9ydCB7IEFsbFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHNlbGVjdEFsbDoge1xuICAgICAgLyoqXG4gICAgICAgKiBTZWxlY3QgdGhlIHdob2xlIGRvY3VtZW50LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNlbGVjdEFsbCgpXG4gICAgICAgKi9cbiAgICAgIHNlbGVjdEFsbDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgc2VsZWN0QWxsOiBSYXdDb21tYW5kc1snc2VsZWN0QWxsJ10gPVxuICAoKSA9PlxuICAoeyB0ciwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgY29uc3Qgc2VsZWN0aW9uID0gbmV3IEFsbFNlbGVjdGlvbih0ci5kb2MpXG5cbiAgICAgIHRyLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuIiwgImltcG9ydCB7IHNlbGVjdE5vZGVCYWNrd2FyZCBhcyBvcmlnaW5hbFNlbGVjdE5vZGVCYWNrd2FyZCB9IGZyb20gJ0B0aXB0YXAvcG0vY29tbWFuZHMnXG5cbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHNlbGVjdE5vZGVCYWNrd2FyZDoge1xuICAgICAgLyoqXG4gICAgICAgKiBTZWxlY3QgYSBub2RlIGJhY2t3YXJkLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNlbGVjdE5vZGVCYWNrd2FyZCgpXG4gICAgICAgKi9cbiAgICAgIHNlbGVjdE5vZGVCYWNrd2FyZDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgc2VsZWN0Tm9kZUJhY2t3YXJkOiBSYXdDb21tYW5kc1snc2VsZWN0Tm9kZUJhY2t3YXJkJ10gPVxuICAoKSA9PlxuICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgIHJldHVybiBvcmlnaW5hbFNlbGVjdE5vZGVCYWNrd2FyZChzdGF0ZSwgZGlzcGF0Y2gpXG4gIH1cbiIsICJpbXBvcnQgeyBzZWxlY3ROb2RlRm9yd2FyZCBhcyBvcmlnaW5hbFNlbGVjdE5vZGVGb3J3YXJkIH0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcblxuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2VsZWN0Tm9kZUZvcndhcmQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2VsZWN0IGEgbm9kZSBmb3J3YXJkLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNlbGVjdE5vZGVGb3J3YXJkKClcbiAgICAgICAqL1xuICAgICAgc2VsZWN0Tm9kZUZvcndhcmQ6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNlbGVjdE5vZGVGb3J3YXJkOiBSYXdDb21tYW5kc1snc2VsZWN0Tm9kZUZvcndhcmQnXSA9XG4gICgpID0+XG4gICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgcmV0dXJuIG9yaWdpbmFsU2VsZWN0Tm9kZUZvcndhcmQoc3RhdGUsIGRpc3BhdGNoKVxuICB9XG4iLCAiaW1wb3J0IHsgc2VsZWN0UGFyZW50Tm9kZSBhcyBvcmlnaW5hbFNlbGVjdFBhcmVudE5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuXG5pbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZWxlY3RQYXJlbnROb2RlOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNlbGVjdCB0aGUgcGFyZW50IG5vZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2VsZWN0UGFyZW50Tm9kZSgpXG4gICAgICAgKi9cbiAgICAgIHNlbGVjdFBhcmVudE5vZGU6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNlbGVjdFBhcmVudE5vZGU6IFJhd0NvbW1hbmRzWydzZWxlY3RQYXJlbnROb2RlJ10gPVxuICAoKSA9PlxuICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgIHJldHVybiBvcmlnaW5hbFNlbGVjdFBhcmVudE5vZGUoc3RhdGUsIGRpc3BhdGNoKVxuICB9XG4iLCAiLy8gQHRzLWlnbm9yZVxuLy8gVE9ETzogYWRkIHR5cGVzIHRvIEB0eXBlcy9wcm9zZW1pcnJvci1jb21tYW5kc1xuaW1wb3J0IHsgc2VsZWN0VGV4dGJsb2NrRW5kIGFzIG9yaWdpbmFsU2VsZWN0VGV4dGJsb2NrRW5kIH0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcblxuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2VsZWN0VGV4dGJsb2NrRW5kOiB7XG4gICAgICAvKipcbiAgICAgICAqIE1vdmVzIHRoZSBjdXJzb3IgdG8gdGhlIGVuZCBvZiBjdXJyZW50IHRleHQgYmxvY2suXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2VsZWN0VGV4dGJsb2NrRW5kKClcbiAgICAgICAqL1xuICAgICAgc2VsZWN0VGV4dGJsb2NrRW5kOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBzZWxlY3RUZXh0YmxvY2tFbmQ6IFJhd0NvbW1hbmRzWydzZWxlY3RUZXh0YmxvY2tFbmQnXSA9XG4gICgpID0+XG4gICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgcmV0dXJuIG9yaWdpbmFsU2VsZWN0VGV4dGJsb2NrRW5kKHN0YXRlLCBkaXNwYXRjaClcbiAgfVxuIiwgIi8vIEB0cy1pZ25vcmVcbi8vIFRPRE86IGFkZCB0eXBlcyB0byBAdHlwZXMvcHJvc2VtaXJyb3ItY29tbWFuZHNcbmltcG9ydCB7IHNlbGVjdFRleHRibG9ja1N0YXJ0IGFzIG9yaWdpbmFsU2VsZWN0VGV4dGJsb2NrU3RhcnQgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuXG5pbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZWxlY3RUZXh0YmxvY2tTdGFydDoge1xuICAgICAgLyoqXG4gICAgICAgKiBNb3ZlcyB0aGUgY3Vyc29yIHRvIHRoZSBzdGFydCBvZiBjdXJyZW50IHRleHQgYmxvY2suXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2VsZWN0VGV4dGJsb2NrU3RhcnQoKVxuICAgICAgICovXG4gICAgICBzZWxlY3RUZXh0YmxvY2tTdGFydDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgc2VsZWN0VGV4dGJsb2NrU3RhcnQ6IFJhd0NvbW1hbmRzWydzZWxlY3RUZXh0YmxvY2tTdGFydCddID1cbiAgKCkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICByZXR1cm4gb3JpZ2luYWxTZWxlY3RUZXh0YmxvY2tTdGFydChzdGF0ZSwgZGlzcGF0Y2gpXG4gIH1cbiIsICJpbXBvcnQgdHlwZSB7IEZyYWdtZW50LCBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSwgUGFyc2VPcHRpb25zLCBTY2hlbWEgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgdHlwZSB7IENvbnRlbnQgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGNyZWF0ZU5vZGVGcm9tQ29udGVudCB9IGZyb20gJy4vY3JlYXRlTm9kZUZyb21Db250ZW50LmpzJ1xuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBQcm9zZW1pcnJvciBkb2N1bWVudCBub2RlIGZyb20gY29udGVudC5cbiAqIEBwYXJhbSBjb250ZW50IFRoZSBKU09OIG9yIEhUTUwgY29udGVudCB0byBjcmVhdGUgdGhlIGRvY3VtZW50IGZyb21cbiAqIEBwYXJhbSBzY2hlbWEgVGhlIFByb3NlbWlycm9yIHNjaGVtYSB0byB1c2UgZm9yIHRoZSBkb2N1bWVudFxuICogQHBhcmFtIHBhcnNlT3B0aW9ucyBPcHRpb25zIGZvciB0aGUgcGFyc2VyXG4gKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBQcm9zZW1pcnJvciBkb2N1bWVudCBub2RlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEb2N1bWVudChcbiAgY29udGVudDogQ29udGVudCB8IFByb3NlTWlycm9yTm9kZSB8IEZyYWdtZW50LFxuICBzY2hlbWE6IFNjaGVtYSxcbiAgcGFyc2VPcHRpb25zOiBQYXJzZU9wdGlvbnMgPSB7fSxcbiAgb3B0aW9uczogeyBlcnJvck9uSW52YWxpZENvbnRlbnQ/OiBib29sZWFuIH0gPSB7fSxcbik6IFByb3NlTWlycm9yTm9kZSB7XG4gIHJldHVybiBjcmVhdGVOb2RlRnJvbUNvbnRlbnQoY29udGVudCwgc2NoZW1hLCB7XG4gICAgc2xpY2U6IGZhbHNlLFxuICAgIHBhcnNlT3B0aW9ucyxcbiAgICBlcnJvck9uSW52YWxpZENvbnRlbnQ6IG9wdGlvbnMuZXJyb3JPbkludmFsaWRDb250ZW50LFxuICB9KSBhcyBQcm9zZU1pcnJvck5vZGVcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEZyYWdtZW50LCBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSwgUGFyc2VPcHRpb25zIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgY3JlYXRlRG9jdW1lbnQgfSBmcm9tICcuLi9oZWxwZXJzL2NyZWF0ZURvY3VtZW50LmpzJ1xuaW1wb3J0IHR5cGUgeyBDb250ZW50LCBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFNldENvbnRlbnRPcHRpb25zIHtcbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIHBhcnNpbmcgdGhlIGNvbnRlbnQuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqL1xuICBwYXJzZU9wdGlvbnM/OiBQYXJzZU9wdGlvbnNcblxuICAvKipcbiAgICogV2hldGhlciB0byB0aHJvdyBhbiBlcnJvciBpZiB0aGUgY29udGVudCBpcyBpbnZhbGlkLlxuICAgKi9cbiAgZXJyb3JPbkludmFsaWRDb250ZW50PzogYm9vbGVhblxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGVtaXQgYW4gdXBkYXRlIGV2ZW50LlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICBlbWl0VXBkYXRlPzogYm9vbGVhblxufVxuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2V0Q29udGVudDoge1xuICAgICAgLyoqXG4gICAgICAgKiBSZXBsYWNlIHRoZSB3aG9sZSBkb2N1bWVudCB3aXRoIG5ldyBjb250ZW50LlxuICAgICAgICogQHBhcmFtIGNvbnRlbnQgVGhlIG5ldyBjb250ZW50LlxuICAgICAgICogQHBhcmFtIGVtaXRVcGRhdGUgV2hldGhlciB0byBlbWl0IGFuIHVwZGF0ZSBldmVudC5cbiAgICAgICAqIEBwYXJhbSBwYXJzZU9wdGlvbnMgT3B0aW9ucyBmb3IgcGFyc2luZyB0aGUgY29udGVudC5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5zZXRDb250ZW50KCc8cD5FeGFtcGxlIHRleHQ8L3A+JylcbiAgICAgICAqL1xuICAgICAgc2V0Q29udGVudDogKFxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG5ldyBjb250ZW50LlxuICAgICAgICAgKi9cbiAgICAgICAgY29udGVudDogQ29udGVudCB8IEZyYWdtZW50IHwgUHJvc2VNaXJyb3JOb2RlLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPcHRpb25zIGZvciBgc2V0Q29udGVudGAuXG4gICAgICAgICAqL1xuICAgICAgICBvcHRpb25zPzogU2V0Q29udGVudE9wdGlvbnMsXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNldENvbnRlbnQ6IFJhd0NvbW1hbmRzWydzZXRDb250ZW50J10gPVxuICAoY29udGVudCwgeyBlcnJvck9uSW52YWxpZENvbnRlbnQsIGVtaXRVcGRhdGUgPSB0cnVlLCBwYXJzZU9wdGlvbnMgPSB7fSB9ID0ge30pID0+XG4gICh7IGVkaXRvciwgdHIsIGRpc3BhdGNoLCBjb21tYW5kcyB9KSA9PiB7XG4gICAgY29uc3QgeyBkb2MgfSA9IHRyXG5cbiAgICAvLyBUaGlzIGlzIHRvIGtlZXAgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIHRoZSBwcmV2aW91cyBiZWhhdmlvclxuICAgIC8vIFRPRE8gcmVtb3ZlIHRoaXMgaW4gdGhlIG5leHQgbWFqb3IgdmVyc2lvblxuICAgIGlmIChwYXJzZU9wdGlvbnMucHJlc2VydmVXaGl0ZXNwYWNlICE9PSAnZnVsbCcpIHtcbiAgICAgIGNvbnN0IGRvY3VtZW50ID0gY3JlYXRlRG9jdW1lbnQoY29udGVudCwgZWRpdG9yLnNjaGVtYSwgcGFyc2VPcHRpb25zLCB7XG4gICAgICAgIGVycm9yT25JbnZhbGlkQ29udGVudDogZXJyb3JPbkludmFsaWRDb250ZW50ID8/IGVkaXRvci5vcHRpb25zLmVuYWJsZUNvbnRlbnRDaGVjayxcbiAgICAgIH0pXG5cbiAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICB0ci5yZXBsYWNlV2l0aCgwLCBkb2MuY29udGVudC5zaXplLCBkb2N1bWVudCkuc2V0TWV0YSgncHJldmVudFVwZGF0ZScsICFlbWl0VXBkYXRlKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgIHRyLnNldE1ldGEoJ3ByZXZlbnRVcGRhdGUnLCAhZW1pdFVwZGF0ZSlcbiAgICB9XG5cbiAgICByZXR1cm4gY29tbWFuZHMuaW5zZXJ0Q29udGVudEF0KHsgZnJvbTogMCwgdG86IGRvYy5jb250ZW50LnNpemUgfSwgY29udGVudCwge1xuICAgICAgcGFyc2VPcHRpb25zLFxuICAgICAgZXJyb3JPbkludmFsaWRDb250ZW50OiBlcnJvck9uSW52YWxpZENvbnRlbnQgPz8gZWRpdG9yLm9wdGlvbnMuZW5hYmxlQ29udGVudENoZWNrLFxuICAgIH0pXG4gIH1cbiIsICJpbXBvcnQgdHlwZSB7IE1hcmssIE1hcmtUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBnZXRNYXJrVHlwZSB9IGZyb20gJy4vZ2V0TWFya1R5cGUuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXJrQXR0cmlidXRlcyhcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuICB0eXBlT3JOYW1lOiBzdHJpbmcgfCBNYXJrVHlwZSxcbik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBjb25zdCB0eXBlID0gZ2V0TWFya1R5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuICBjb25zdCB7IGZyb20sIHRvLCBlbXB0eSB9ID0gc3RhdGUuc2VsZWN0aW9uXG4gIGNvbnN0IG1hcmtzOiBNYXJrW10gPSBbXVxuXG4gIGlmIChlbXB0eSkge1xuICAgIGlmIChzdGF0ZS5zdG9yZWRNYXJrcykge1xuICAgICAgbWFya3MucHVzaCguLi5zdGF0ZS5zdG9yZWRNYXJrcylcbiAgICB9XG5cbiAgICBtYXJrcy5wdXNoKC4uLnN0YXRlLnNlbGVjdGlvbi4kaGVhZC5tYXJrcygpKVxuICB9IGVsc2Uge1xuICAgIHN0YXRlLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIG5vZGUgPT4ge1xuICAgICAgbWFya3MucHVzaCguLi5ub2RlLm1hcmtzKVxuICAgIH0pXG4gIH1cblxuICBjb25zdCBtYXJrID0gbWFya3MuZmluZChtYXJrSXRlbSA9PiBtYXJrSXRlbS50eXBlLm5hbWUgPT09IHR5cGUubmFtZSlcblxuICBpZiAoIW1hcmspIHtcbiAgICByZXR1cm4ge31cbiAgfVxuXG4gIHJldHVybiB7IC4uLm1hcmsuYXR0cnMgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHR5cGUgeyBUcmFuc2FjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgeyBUcmFuc2Zvcm0gfSBmcm9tICdAdGlwdGFwL3BtL3RyYW5zZm9ybSdcblxuLyoqXG4gKiBSZXR1cm5zIGEgbmV3IGBUcmFuc2Zvcm1gIGJhc2VkIG9uIGFsbCBzdGVwcyBvZiB0aGUgcGFzc2VkIHRyYW5zYWN0aW9ucy5cbiAqIEBwYXJhbSBvbGREb2MgVGhlIFByb3NlbWlycm9yIG5vZGUgdG8gc3RhcnQgZnJvbVxuICogQHBhcmFtIHRyYW5zYWN0aW9ucyBUaGUgdHJhbnNhY3Rpb25zIHRvIGNvbWJpbmVcbiAqIEByZXR1cm5zIEEgbmV3IGBUcmFuc2Zvcm1gIHdpdGggYWxsIHN0ZXBzIG9mIHRoZSBwYXNzZWQgdHJhbnNhY3Rpb25zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21iaW5lVHJhbnNhY3Rpb25TdGVwcyhcbiAgb2xkRG9jOiBQcm9zZU1pcnJvck5vZGUsXG4gIHRyYW5zYWN0aW9uczogVHJhbnNhY3Rpb25bXSxcbik6IFRyYW5zZm9ybSB7XG4gIGNvbnN0IHRyYW5zZm9ybSA9IG5ldyBUcmFuc2Zvcm0ob2xkRG9jKVxuXG4gIHRyYW5zYWN0aW9ucy5mb3JFYWNoKHRyYW5zYWN0aW9uID0+IHtcbiAgICB0cmFuc2FjdGlvbi5zdGVwcy5mb3JFYWNoKHN0ZXAgPT4ge1xuICAgICAgdHJhbnNmb3JtLnN0ZXAoc3RlcClcbiAgICB9KVxuICB9KVxuXG4gIHJldHVybiB0cmFuc2Zvcm1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IENvbnRlbnRNYXRjaCwgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG4vKipcbiAqIEdldHMgdGhlIGRlZmF1bHQgYmxvY2sgdHlwZSBhdCBhIGdpdmVuIG1hdGNoXG4gKiBAcGFyYW0gbWF0Y2ggVGhlIGNvbnRlbnQgbWF0Y2ggdG8gZ2V0IHRoZSBkZWZhdWx0IGJsb2NrIHR5cGUgZnJvbVxuICogQHJldHVybnMgVGhlIGRlZmF1bHQgYmxvY2sgdHlwZSBvciBudWxsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0QmxvY2tBdChtYXRjaDogQ29udGVudE1hdGNoKTogTm9kZVR5cGUgfCBudWxsIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXRjaC5lZGdlQ291bnQ7IGkgKz0gMSkge1xuICAgIGNvbnN0IHsgdHlwZSB9ID0gbWF0Y2guZWRnZShpKVxuXG4gICAgaWYgKHR5cGUuaXNUZXh0YmxvY2sgJiYgIXR5cGUuaGFzUmVxdWlyZWRBdHRycygpKSB7XG4gICAgICByZXR1cm4gdHlwZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB0eXBlIHsgTm9kZVdpdGhQb3MsIFByZWRpY2F0ZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG4vKipcbiAqIEZpbmQgY2hpbGRyZW4gaW5zaWRlIGEgUHJvc2VtaXJyb3Igbm9kZSB0aGF0IG1hdGNoIGEgcHJlZGljYXRlLlxuICogQHBhcmFtIG5vZGUgVGhlIFByb3NlbWlycm9yIG5vZGUgdG8gc2VhcmNoIGluXG4gKiBAcGFyYW0gcHJlZGljYXRlIFRoZSBwcmVkaWNhdGUgdG8gbWF0Y2hcbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIG5vZGVzIHdpdGggdGhlaXIgcG9zaXRpb25zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kQ2hpbGRyZW4obm9kZTogUHJvc2VNaXJyb3JOb2RlLCBwcmVkaWNhdGU6IFByZWRpY2F0ZSk6IE5vZGVXaXRoUG9zW10ge1xuICBjb25zdCBub2Rlc1dpdGhQb3M6IE5vZGVXaXRoUG9zW10gPSBbXVxuXG4gIG5vZGUuZGVzY2VuZGFudHMoKGNoaWxkLCBwb3MpID0+IHtcbiAgICBpZiAocHJlZGljYXRlKGNoaWxkKSkge1xuICAgICAgbm9kZXNXaXRoUG9zLnB1c2goe1xuICAgICAgICBub2RlOiBjaGlsZCxcbiAgICAgICAgcG9zLFxuICAgICAgfSlcbiAgICB9XG4gIH0pXG5cbiAgcmV0dXJuIG5vZGVzV2l0aFBvc1xufVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgdHlwZSB7IE5vZGVXaXRoUG9zLCBQcmVkaWNhdGUsIFJhbmdlIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbi8qKlxuICogU2FtZSBhcyBgZmluZENoaWxkcmVuYCBidXQgc2VhcmNoZXMgb25seSB3aXRoaW4gYSBgcmFuZ2VgLlxuICogQHBhcmFtIG5vZGUgVGhlIFByb3NlbWlycm9yIG5vZGUgdG8gc2VhcmNoIGluXG4gKiBAcGFyYW0gcmFuZ2UgVGhlIHJhbmdlIHRvIHNlYXJjaCBpblxuICogQHBhcmFtIHByZWRpY2F0ZSBUaGUgcHJlZGljYXRlIHRvIG1hdGNoXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBub2RlcyB3aXRoIHRoZWlyIHBvc2l0aW9uc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZENoaWxkcmVuSW5SYW5nZShcbiAgbm9kZTogUHJvc2VNaXJyb3JOb2RlLFxuICByYW5nZTogUmFuZ2UsXG4gIHByZWRpY2F0ZTogUHJlZGljYXRlLFxuKTogTm9kZVdpdGhQb3NbXSB7XG4gIGNvbnN0IG5vZGVzV2l0aFBvczogTm9kZVdpdGhQb3NbXSA9IFtdXG5cbiAgLy8gaWYgKHJhbmdlLmZyb20gPT09IHJhbmdlLnRvKSB7XG4gIC8vICAgY29uc3Qgbm9kZUF0ID0gbm9kZS5ub2RlQXQocmFuZ2UuZnJvbSlcblxuICAvLyAgIGlmIChub2RlQXQpIHtcbiAgLy8gICAgIG5vZGVzV2l0aFBvcy5wdXNoKHtcbiAgLy8gICAgICAgbm9kZTogbm9kZUF0LFxuICAvLyAgICAgICBwb3M6IHJhbmdlLmZyb20sXG4gIC8vICAgICB9KVxuICAvLyAgIH1cbiAgLy8gfVxuXG4gIG5vZGUubm9kZXNCZXR3ZWVuKHJhbmdlLmZyb20sIHJhbmdlLnRvLCAoY2hpbGQsIHBvcykgPT4ge1xuICAgIGlmIChwcmVkaWNhdGUoY2hpbGQpKSB7XG4gICAgICBub2Rlc1dpdGhQb3MucHVzaCh7XG4gICAgICAgIG5vZGU6IGNoaWxkLFxuICAgICAgICBwb3MsXG4gICAgICB9KVxuICAgIH1cbiAgfSlcblxuICByZXR1cm4gbm9kZXNXaXRoUG9zXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSwgUmVzb2x2ZWRQb3MgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgdHlwZSB7IFByZWRpY2F0ZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG4vKipcbiAqIEZpbmRzIHRoZSBjbG9zZXN0IHBhcmVudCBub2RlIHRvIGEgcmVzb2x2ZWQgcG9zaXRpb24gdGhhdCBtYXRjaGVzIGEgcHJlZGljYXRlLlxuICogQHBhcmFtICRwb3MgVGhlIHJlc29sdmVkIHBvc2l0aW9uIHRvIHNlYXJjaCBmcm9tXG4gKiBAcGFyYW0gcHJlZGljYXRlIFRoZSBwcmVkaWNhdGUgdG8gbWF0Y2hcbiAqIEByZXR1cm5zIFRoZSBjbG9zZXN0IHBhcmVudCBub2RlIHRvIHRoZSByZXNvbHZlZCBwb3NpdGlvbiB0aGF0IG1hdGNoZXMgdGhlIHByZWRpY2F0ZVxuICogQGV4YW1wbGUgYGBganNcbiAqIGZpbmRQYXJlbnROb2RlQ2xvc2VzdFRvUG9zKCRmcm9tLCBub2RlID0+IG5vZGUudHlwZS5uYW1lID09PSAncGFyYWdyYXBoJylcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZFBhcmVudE5vZGVDbG9zZXN0VG9Qb3MoXG4gICRwb3M6IFJlc29sdmVkUG9zLFxuICBwcmVkaWNhdGU6IFByZWRpY2F0ZSxcbik6XG4gIHwge1xuICAgICAgcG9zOiBudW1iZXJcbiAgICAgIHN0YXJ0OiBudW1iZXJcbiAgICAgIGRlcHRoOiBudW1iZXJcbiAgICAgIG5vZGU6IFByb3NlTWlycm9yTm9kZVxuICAgIH1cbiAgfCB1bmRlZmluZWQge1xuICBmb3IgKGxldCBpID0gJHBvcy5kZXB0aDsgaSA+IDA7IGkgLT0gMSkge1xuICAgIGNvbnN0IG5vZGUgPSAkcG9zLm5vZGUoaSlcblxuICAgIGlmIChwcmVkaWNhdGUobm9kZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBvczogaSA+IDAgPyAkcG9zLmJlZm9yZShpKSA6IDAsXG4gICAgICAgIHN0YXJ0OiAkcG9zLnN0YXJ0KGkpLFxuICAgICAgICBkZXB0aDogaSxcbiAgICAgICAgbm9kZSxcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB0eXBlIHsgUHJlZGljYXRlIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBmaW5kUGFyZW50Tm9kZUNsb3Nlc3RUb1BvcyB9IGZyb20gJy4vZmluZFBhcmVudE5vZGVDbG9zZXN0VG9Qb3MuanMnXG5cbi8qKlxuICogRmluZHMgdGhlIGNsb3Nlc3QgcGFyZW50IG5vZGUgdG8gdGhlIGN1cnJlbnQgc2VsZWN0aW9uIHRoYXQgbWF0Y2hlcyBhIHByZWRpY2F0ZS5cbiAqIEBwYXJhbSBwcmVkaWNhdGUgVGhlIHByZWRpY2F0ZSB0byBtYXRjaFxuICogQHJldHVybnMgQSBjb21tYW5kIHRoYXQgZmluZHMgdGhlIGNsb3Nlc3QgcGFyZW50IG5vZGUgdG8gdGhlIGN1cnJlbnQgc2VsZWN0aW9uIHRoYXQgbWF0Y2hlcyB0aGUgcHJlZGljYXRlXG4gKiBAZXhhbXBsZSBgYGBqc1xuICogZmluZFBhcmVudE5vZGUobm9kZSA9PiBub2RlLnR5cGUubmFtZSA9PT0gJ3BhcmFncmFwaCcpXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRQYXJlbnROb2RlKFxuICBwcmVkaWNhdGU6IFByZWRpY2F0ZSxcbik6IChzZWxlY3Rpb246IFNlbGVjdGlvbikgPT4gUmV0dXJuVHlwZTx0eXBlb2YgZmluZFBhcmVudE5vZGVDbG9zZXN0VG9Qb3M+IHtcbiAgcmV0dXJuIChzZWxlY3Rpb246IFNlbGVjdGlvbikgPT4gZmluZFBhcmVudE5vZGVDbG9zZXN0VG9Qb3Moc2VsZWN0aW9uLiRmcm9tLCBwcmVkaWNhdGUpXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25Db25maWcgfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5pbXBvcnQgdHlwZSB7IE1hcmtDb25maWcgfSBmcm9tICcuLi9NYXJrLmpzJ1xuaW1wb3J0IHR5cGUgeyBOb2RlQ29uZmlnIH0gZnJvbSAnLi4vTm9kZS5qcydcbmltcG9ydCB0eXBlIHsgQW55RXh0ZW5zaW9uLCBNYXliZVRoaXNQYXJhbWV0ZXJUeXBlLCBSZW1vdmVUaGlzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbi8qKlxuICogUmV0dXJucyBhIGZpZWxkIGZyb20gYW4gZXh0ZW5zaW9uXG4gKiBAcGFyYW0gZXh0ZW5zaW9uIFRoZSBUaXB0YXAgZXh0ZW5zaW9uXG4gKiBAcGFyYW0gZmllbGQgVGhlIGZpZWxkLCBmb3IgZXhhbXBsZSBgcmVuZGVySFRNTGAgb3IgYHByaW9yaXR5YFxuICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgb2JqZWN0IHRoYXQgc2hvdWxkIGJlIHBhc3NlZCBhcyBgdGhpc2AgaW50byB0aGUgZnVuY3Rpb25cbiAqIEByZXR1cm5zIFRoZSBmaWVsZCB2YWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uRmllbGQ8VCA9IGFueSwgRSBleHRlbmRzIEFueUV4dGVuc2lvbiA9IGFueT4oXG4gIGV4dGVuc2lvbjogRSxcbiAgZmllbGQ6IGtleW9mIEV4dGVuc2lvbkNvbmZpZyB8IGtleW9mIE1hcmtDb25maWcgfCBrZXlvZiBOb2RlQ29uZmlnLFxuICBjb250ZXh0PzogT21pdDxNYXliZVRoaXNQYXJhbWV0ZXJUeXBlPFQ+LCAncGFyZW50Jz4sXG4pOiBSZW1vdmVUaGlzPFQ+IHtcbiAgaWYgKGV4dGVuc2lvbi5jb25maWdbZmllbGQgYXMga2V5b2YgdHlwZW9mIGV4dGVuc2lvbi5jb25maWddID09PSB1bmRlZmluZWQgJiYgZXh0ZW5zaW9uLnBhcmVudCkge1xuICAgIHJldHVybiBnZXRFeHRlbnNpb25GaWVsZChleHRlbnNpb24ucGFyZW50LCBmaWVsZCwgY29udGV4dClcbiAgfVxuXG4gIGlmICh0eXBlb2YgZXh0ZW5zaW9uLmNvbmZpZ1tmaWVsZCBhcyBrZXlvZiB0eXBlb2YgZXh0ZW5zaW9uLmNvbmZpZ10gPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCB2YWx1ZSA9IChleHRlbnNpb24uY29uZmlnW2ZpZWxkIGFzIGtleW9mIHR5cGVvZiBleHRlbnNpb24uY29uZmlnXSBhcyBhbnkpLmJpbmQoe1xuICAgICAgLi4uY29udGV4dCxcbiAgICAgIHBhcmVudDogZXh0ZW5zaW9uLnBhcmVudCA/IGdldEV4dGVuc2lvbkZpZWxkKGV4dGVuc2lvbi5wYXJlbnQsIGZpZWxkLCBjb250ZXh0KSA6IG51bGwsXG4gICAgfSlcblxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgcmV0dXJuIGV4dGVuc2lvbi5jb25maWdbZmllbGQgYXMga2V5b2YgdHlwZW9mIGV4dGVuc2lvbi5jb25maWddIGFzIFJlbW92ZVRoaXM8VD5cbn1cbiIsICJpbXBvcnQgdHlwZSB7IEFueUNvbmZpZywgRXh0ZW5zaW9ucyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgZ2V0RXh0ZW5zaW9uRmllbGQgfSBmcm9tICcuL2dldEV4dGVuc2lvbkZpZWxkLmpzJ1xuXG4vKipcbiAqIENyZWF0ZSBhIGZsYXR0ZW5lZCBhcnJheSBvZiBleHRlbnNpb25zIGJ5IHRyYXZlcnNpbmcgdGhlIGBhZGRFeHRlbnNpb25zYCBmaWVsZC5cbiAqIEBwYXJhbSBleHRlbnNpb25zIEFuIGFycmF5IG9mIFRpcHRhcCBleHRlbnNpb25zXG4gKiBAcmV0dXJucyBBIGZsYXR0ZW5lZCBhcnJheSBvZiBUaXB0YXAgZXh0ZW5zaW9uc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZmxhdHRlbkV4dGVuc2lvbnMoZXh0ZW5zaW9uczogRXh0ZW5zaW9ucyk6IEV4dGVuc2lvbnMge1xuICByZXR1cm4gKFxuICAgIGV4dGVuc2lvbnNcbiAgICAgIC5tYXAoZXh0ZW5zaW9uID0+IHtcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgICBuYW1lOiBleHRlbnNpb24ubmFtZSxcbiAgICAgICAgICBvcHRpb25zOiBleHRlbnNpb24ub3B0aW9ucyxcbiAgICAgICAgICBzdG9yYWdlOiBleHRlbnNpb24uc3RvcmFnZSxcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFkZEV4dGVuc2lvbnMgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZEV4dGVuc2lvbnMnXT4oXG4gICAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAgICdhZGRFeHRlbnNpb25zJyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICApXG5cbiAgICAgICAgaWYgKGFkZEV4dGVuc2lvbnMpIHtcbiAgICAgICAgICByZXR1cm4gW2V4dGVuc2lvbiwgLi4uZmxhdHRlbkV4dGVuc2lvbnMoYWRkRXh0ZW5zaW9ucygpKV1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBleHRlbnNpb25cbiAgICAgIH0pXG4gICAgICAvLyBgSW5maW5pdHlgIHdpbGwgYnJlYWsgVHlwZVNjcmlwdCBzbyB3ZSBzZXQgYSBudW1iZXIgdGhhdCBpcyBwcm9iYWJseSBoaWdoIGVub3VnaFxuICAgICAgLmZsYXQoMTApXG4gIClcbn1cbiIsICJpbXBvcnQgeyBOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25zLCBKU09OQ29udGVudCB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgZ2V0SFRNTEZyb21GcmFnbWVudCB9IGZyb20gJy4vZ2V0SFRNTEZyb21GcmFnbWVudC5qcydcbmltcG9ydCB7IGdldFNjaGVtYSB9IGZyb20gJy4vZ2V0U2NoZW1hLmpzJ1xuXG4vKipcbiAqIEdlbmVyYXRlIEhUTUwgZnJvbSBhIEpTT05Db250ZW50XG4gKiBAcGFyYW0gZG9jIFRoZSBKU09OQ29udGVudCB0byBnZW5lcmF0ZSBIVE1MIGZyb21cbiAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBleHRlbnNpb25zIHRvIHVzZSBmb3IgdGhlIHNjaGVtYVxuICogQHJldHVybnMgVGhlIGdlbmVyYXRlZCBIVE1MXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUhUTUwoZG9jOiBKU09OQ29udGVudCwgZXh0ZW5zaW9uczogRXh0ZW5zaW9ucyk6IHN0cmluZyB7XG4gIGNvbnN0IHNjaGVtYSA9IGdldFNjaGVtYShleHRlbnNpb25zKVxuICBjb25zdCBjb250ZW50Tm9kZSA9IE5vZGUuZnJvbUpTT04oc2NoZW1hLCBkb2MpXG5cbiAgcmV0dXJuIGdldEhUTUxGcm9tRnJhZ21lbnQoY29udGVudE5vZGUuY29udGVudCwgc2NoZW1hKVxufVxuIiwgImltcG9ydCB0eXBlIHsgRnJhZ21lbnQsIFNjaGVtYSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBET01TZXJpYWxpemVyIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhUTUxGcm9tRnJhZ21lbnQoZnJhZ21lbnQ6IEZyYWdtZW50LCBzY2hlbWE6IFNjaGVtYSk6IHN0cmluZyB7XG4gIGNvbnN0IGRvY3VtZW50RnJhZ21lbnQgPSBET01TZXJpYWxpemVyLmZyb21TY2hlbWEoc2NoZW1hKS5zZXJpYWxpemVGcmFnbWVudChmcmFnbWVudClcblxuICBjb25zdCB0ZW1wb3JhcnlEb2N1bWVudCA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCgpXG4gIGNvbnN0IGNvbnRhaW5lciA9IHRlbXBvcmFyeURvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG5cbiAgY29udGFpbmVyLmFwcGVuZENoaWxkKGRvY3VtZW50RnJhZ21lbnQpXG5cbiAgcmV0dXJuIGNvbnRhaW5lci5pbm5lckhUTUxcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE1hcmtTcGVjLCBOb2RlU3BlYywgVGFnUGFyc2VSdWxlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IFNjaGVtYSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB0eXBlIHsgRWRpdG9yLCBNYXJrQ29uZmlnLCBOb2RlQ29uZmlnIH0gZnJvbSAnLi4vaW5kZXguanMnXG5pbXBvcnQgdHlwZSB7IEFueUNvbmZpZywgRXh0ZW5zaW9ucyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgY2FsbE9yUmV0dXJuIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2NhbGxPclJldHVybi5qcydcbmltcG9ydCB7IGlzRW1wdHlPYmplY3QgfSBmcm9tICcuLi91dGlsaXRpZXMvaXNFbXB0eU9iamVjdC5qcydcbmltcG9ydCB7IGdldEF0dHJpYnV0ZXNGcm9tRXh0ZW5zaW9ucyB9IGZyb20gJy4vZ2V0QXR0cmlidXRlc0Zyb21FeHRlbnNpb25zLmpzJ1xuaW1wb3J0IHsgZ2V0RXh0ZW5zaW9uRmllbGQgfSBmcm9tICcuL2dldEV4dGVuc2lvbkZpZWxkLmpzJ1xuaW1wb3J0IHsgZ2V0UmVuZGVyZWRBdHRyaWJ1dGVzIH0gZnJvbSAnLi9nZXRSZW5kZXJlZEF0dHJpYnV0ZXMuanMnXG5pbXBvcnQgeyBpbmplY3RFeHRlbnNpb25BdHRyaWJ1dGVzVG9QYXJzZVJ1bGUgfSBmcm9tICcuL2luamVjdEV4dGVuc2lvbkF0dHJpYnV0ZXNUb1BhcnNlUnVsZS5qcydcbmltcG9ydCB7IHNwbGl0RXh0ZW5zaW9ucyB9IGZyb20gJy4vc3BsaXRFeHRlbnNpb25zLmpzJ1xuXG5mdW5jdGlvbiBjbGVhblVwU2NoZW1hSXRlbTxUPihkYXRhOiBUKSB7XG4gIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIE9iamVjdC5lbnRyaWVzKGRhdGEpLmZpbHRlcigoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAoa2V5ID09PSAnYXR0cnMnICYmIGlzRW1wdHlPYmplY3QodmFsdWUgYXMgb2JqZWN0IHwgdW5kZWZpbmVkKSkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWRcbiAgICB9KSxcbiAgKSBhcyBUXG59XG5cbi8qKlxuICogQnVpbGRzIGFuIGF0dHJpYnV0ZSBzcGVjIHR1cGxlIGZvciBQcm9zZU1pcnJvciBzY2hlbWEgZnJvbSBhbiBleHRlbnNpb24gYXR0cmlidXRlLlxuICogQHBhcmFtIGV4dGVuc2lvbkF0dHJpYnV0ZSBUaGUgZXh0ZW5zaW9uIGF0dHJpYnV0ZSB0byBidWlsZCB0aGUgc3BlYyBmb3JcbiAqIEByZXR1cm5zIEEgdHVwbGUgb2YgW2F0dHJpYnV0ZU5hbWUsIHNwZWNdXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkQXR0cmlidXRlU3BlYyhcbiAgZXh0ZW5zaW9uQXR0cmlidXRlOiBSZXR1cm5UeXBlPHR5cGVvZiBnZXRBdHRyaWJ1dGVzRnJvbUV4dGVuc2lvbnM+W251bWJlcl0sXG4pOiBbc3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBhbnk+XSB7XG4gIGNvbnN0IHNwZWM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fVxuXG4gIC8vIE9ubHkgaW5jbHVkZSAnZGVmYXVsdCcgaWYgdGhlIGF0dHJpYnV0ZSBpcyBub3QgcmVxdWlyZWQgYW5kIGRlZmF1bHQgaXMgc2V0IG9uIHRoZSBhdHRyaWJ1dGVcbiAgaWYgKFxuICAgICFleHRlbnNpb25BdHRyaWJ1dGU/LmF0dHJpYnV0ZT8uaXNSZXF1aXJlZCAmJlxuICAgICdkZWZhdWx0JyBpbiAoZXh0ZW5zaW9uQXR0cmlidXRlPy5hdHRyaWJ1dGUgfHwge30pXG4gICkge1xuICAgIHNwZWMuZGVmYXVsdCA9IGV4dGVuc2lvbkF0dHJpYnV0ZS5hdHRyaWJ1dGUuZGVmYXVsdFxuICB9XG5cbiAgLy8gT25seSBpbmNsdWRlICd2YWxpZGF0ZScgaWYgaXQncyBkZWZpbmVkXG4gIGlmIChleHRlbnNpb25BdHRyaWJ1dGU/LmF0dHJpYnV0ZT8udmFsaWRhdGUgIT09IHVuZGVmaW5lZCkge1xuICAgIHNwZWMudmFsaWRhdGUgPSBleHRlbnNpb25BdHRyaWJ1dGUuYXR0cmlidXRlLnZhbGlkYXRlXG4gIH1cblxuICByZXR1cm4gW2V4dGVuc2lvbkF0dHJpYnV0ZS5uYW1lLCBzcGVjXVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgUHJvc2VtaXJyb3Igc2NoZW1hIGJhc2VkIG9uIHRoZSBnaXZlbiBleHRlbnNpb25zLlxuICogQHBhcmFtIGV4dGVuc2lvbnMgQW4gYXJyYXkgb2YgVGlwdGFwIGV4dGVuc2lvbnNcbiAqIEBwYXJhbSBlZGl0b3IgVGhlIGVkaXRvciBpbnN0YW5jZVxuICogQHJldHVybnMgQSBQcm9zZW1pcnJvciBzY2hlbWFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNjaGVtYUJ5UmVzb2x2ZWRFeHRlbnNpb25zKGV4dGVuc2lvbnM6IEV4dGVuc2lvbnMsIGVkaXRvcj86IEVkaXRvcik6IFNjaGVtYSB7XG4gIGNvbnN0IGFsbEF0dHJpYnV0ZXMgPSBnZXRBdHRyaWJ1dGVzRnJvbUV4dGVuc2lvbnMoZXh0ZW5zaW9ucylcbiAgY29uc3QgeyBub2RlRXh0ZW5zaW9ucywgbWFya0V4dGVuc2lvbnMgfSA9IHNwbGl0RXh0ZW5zaW9ucyhleHRlbnNpb25zKVxuICBjb25zdCB0b3BOb2RlID0gbm9kZUV4dGVuc2lvbnMuZmluZChleHRlbnNpb24gPT4gZ2V0RXh0ZW5zaW9uRmllbGQoZXh0ZW5zaW9uLCAndG9wTm9kZScpKT8ubmFtZVxuXG4gIGNvbnN0IG5vZGVzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgIG5vZGVFeHRlbnNpb25zLm1hcChleHRlbnNpb24gPT4ge1xuICAgICAgY29uc3QgZXh0ZW5zaW9uQXR0cmlidXRlcyA9IGFsbEF0dHJpYnV0ZXMuZmlsdGVyKFxuICAgICAgICBhdHRyaWJ1dGUgPT4gYXR0cmlidXRlLnR5cGUgPT09IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgKVxuICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgIG9wdGlvbnM6IGV4dGVuc2lvbi5vcHRpb25zLFxuICAgICAgICBzdG9yYWdlOiBleHRlbnNpb24uc3RvcmFnZSxcbiAgICAgICAgZWRpdG9yLFxuICAgICAgfVxuXG4gICAgICBjb25zdCBleHRyYU5vZGVGaWVsZHMgPSBleHRlbnNpb25zLnJlZHVjZSgoZmllbGRzLCBlKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4dGVuZE5vZGVTY2hlbWEgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2V4dGVuZE5vZGVTY2hlbWEnXT4oXG4gICAgICAgICAgZSxcbiAgICAgICAgICAnZXh0ZW5kTm9kZVNjaGVtYScsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgKVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgIC4uLihleHRlbmROb2RlU2NoZW1hID8gZXh0ZW5kTm9kZVNjaGVtYShleHRlbnNpb24pIDoge30pLFxuICAgICAgICB9XG4gICAgICB9LCB7fSlcblxuICAgICAgY29uc3Qgc2NoZW1hOiBOb2RlU3BlYyA9IGNsZWFuVXBTY2hlbWFJdGVtKHtcbiAgICAgICAgLi4uZXh0cmFOb2RlRmllbGRzLFxuICAgICAgICBjb250ZW50OiBjYWxsT3JSZXR1cm4oXG4gICAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snY29udGVudCddPihleHRlbnNpb24sICdjb250ZW50JywgY29udGV4dCksXG4gICAgICAgICksXG4gICAgICAgIG1hcmtzOiBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snbWFya3MnXT4oZXh0ZW5zaW9uLCAnbWFya3MnLCBjb250ZXh0KSksXG4gICAgICAgIGdyb3VwOiBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snZ3JvdXAnXT4oZXh0ZW5zaW9uLCAnZ3JvdXAnLCBjb250ZXh0KSksXG4gICAgICAgIGlubGluZTogY2FsbE9yUmV0dXJuKGdldEV4dGVuc2lvbkZpZWxkPE5vZGVDb25maWdbJ2lubGluZSddPihleHRlbnNpb24sICdpbmxpbmUnLCBjb250ZXh0KSksXG4gICAgICAgIGF0b206IGNhbGxPclJldHVybihnZXRFeHRlbnNpb25GaWVsZDxOb2RlQ29uZmlnWydhdG9tJ10+KGV4dGVuc2lvbiwgJ2F0b20nLCBjb250ZXh0KSksXG4gICAgICAgIHNlbGVjdGFibGU6IGNhbGxPclJldHVybihcbiAgICAgICAgICBnZXRFeHRlbnNpb25GaWVsZDxOb2RlQ29uZmlnWydzZWxlY3RhYmxlJ10+KGV4dGVuc2lvbiwgJ3NlbGVjdGFibGUnLCBjb250ZXh0KSxcbiAgICAgICAgKSxcbiAgICAgICAgZHJhZ2dhYmxlOiBjYWxsT3JSZXR1cm4oXG4gICAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snZHJhZ2dhYmxlJ10+KGV4dGVuc2lvbiwgJ2RyYWdnYWJsZScsIGNvbnRleHQpLFxuICAgICAgICApLFxuICAgICAgICBjb2RlOiBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snY29kZSddPihleHRlbnNpb24sICdjb2RlJywgY29udGV4dCkpLFxuICAgICAgICB3aGl0ZXNwYWNlOiBjYWxsT3JSZXR1cm4oXG4gICAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snd2hpdGVzcGFjZSddPihleHRlbnNpb24sICd3aGl0ZXNwYWNlJywgY29udGV4dCksXG4gICAgICAgICksXG4gICAgICAgIGxpbmVicmVha1JlcGxhY2VtZW50OiBjYWxsT3JSZXR1cm4oXG4gICAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snbGluZWJyZWFrUmVwbGFjZW1lbnQnXT4oXG4gICAgICAgICAgICBleHRlbnNpb24sXG4gICAgICAgICAgICAnbGluZWJyZWFrUmVwbGFjZW1lbnQnLFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgICBkZWZpbmluZzogY2FsbE9yUmV0dXJuKFxuICAgICAgICAgIGdldEV4dGVuc2lvbkZpZWxkPE5vZGVDb25maWdbJ2RlZmluaW5nJ10+KGV4dGVuc2lvbiwgJ2RlZmluaW5nJywgY29udGV4dCksXG4gICAgICAgICksXG4gICAgICAgIGlzb2xhdGluZzogY2FsbE9yUmV0dXJuKFxuICAgICAgICAgIGdldEV4dGVuc2lvbkZpZWxkPE5vZGVDb25maWdbJ2lzb2xhdGluZyddPihleHRlbnNpb24sICdpc29sYXRpbmcnLCBjb250ZXh0KSxcbiAgICAgICAgKSxcbiAgICAgICAgYXR0cnM6IE9iamVjdC5mcm9tRW50cmllcyhleHRlbnNpb25BdHRyaWJ1dGVzLm1hcChidWlsZEF0dHJpYnV0ZVNwZWMpKSxcbiAgICAgIH0pXG5cbiAgICAgIGNvbnN0IHBhcnNlSFRNTCA9IGNhbGxPclJldHVybihcbiAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1sncGFyc2VIVE1MJ10+KGV4dGVuc2lvbiwgJ3BhcnNlSFRNTCcsIGNvbnRleHQpLFxuICAgICAgKVxuXG4gICAgICBpZiAocGFyc2VIVE1MKSB7XG4gICAgICAgIHNjaGVtYS5wYXJzZURPTSA9IHBhcnNlSFRNTC5tYXAocGFyc2VSdWxlID0+XG4gICAgICAgICAgaW5qZWN0RXh0ZW5zaW9uQXR0cmlidXRlc1RvUGFyc2VSdWxlKHBhcnNlUnVsZSwgZXh0ZW5zaW9uQXR0cmlidXRlcyksXG4gICAgICAgICkgYXMgVGFnUGFyc2VSdWxlW11cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVuZGVySFRNTCA9IGdldEV4dGVuc2lvbkZpZWxkPE5vZGVDb25maWdbJ3JlbmRlckhUTUwnXT4oXG4gICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgJ3JlbmRlckhUTUwnLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKVxuXG4gICAgICBpZiAocmVuZGVySFRNTCkge1xuICAgICAgICBzY2hlbWEudG9ET00gPSBub2RlID0+XG4gICAgICAgICAgcmVuZGVySFRNTCh7XG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgSFRNTEF0dHJpYnV0ZXM6IGdldFJlbmRlcmVkQXR0cmlidXRlcyhub2RlLCBleHRlbnNpb25BdHRyaWJ1dGVzKSxcbiAgICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZW5kZXJUZXh0ID0gZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1sncmVuZGVyVGV4dCddPihcbiAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAncmVuZGVyVGV4dCcsXG4gICAgICAgIGNvbnRleHQsXG4gICAgICApXG5cbiAgICAgIGlmIChyZW5kZXJUZXh0KSB7XG4gICAgICAgIHNjaGVtYS50b1RleHQgPSByZW5kZXJUZXh0XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBbZXh0ZW5zaW9uLm5hbWUsIHNjaGVtYV1cbiAgICB9KSxcbiAgKVxuXG4gIGNvbnN0IG1hcmtzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgIG1hcmtFeHRlbnNpb25zLm1hcChleHRlbnNpb24gPT4ge1xuICAgICAgY29uc3QgZXh0ZW5zaW9uQXR0cmlidXRlcyA9IGFsbEF0dHJpYnV0ZXMuZmlsdGVyKFxuICAgICAgICBhdHRyaWJ1dGUgPT4gYXR0cmlidXRlLnR5cGUgPT09IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgKVxuICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgIG9wdGlvbnM6IGV4dGVuc2lvbi5vcHRpb25zLFxuICAgICAgICBzdG9yYWdlOiBleHRlbnNpb24uc3RvcmFnZSxcbiAgICAgICAgZWRpdG9yLFxuICAgICAgfVxuXG4gICAgICBjb25zdCBleHRyYU1hcmtGaWVsZHMgPSBleHRlbnNpb25zLnJlZHVjZSgoZmllbGRzLCBlKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4dGVuZE1hcmtTY2hlbWEgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2V4dGVuZE1hcmtTY2hlbWEnXT4oXG4gICAgICAgICAgZSxcbiAgICAgICAgICAnZXh0ZW5kTWFya1NjaGVtYScsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgKVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgIC4uLihleHRlbmRNYXJrU2NoZW1hID8gZXh0ZW5kTWFya1NjaGVtYShleHRlbnNpb24gYXMgYW55KSA6IHt9KSxcbiAgICAgICAgfVxuICAgICAgfSwge30pXG5cbiAgICAgIGNvbnN0IHNjaGVtYTogTWFya1NwZWMgPSBjbGVhblVwU2NoZW1hSXRlbSh7XG4gICAgICAgIC4uLmV4dHJhTWFya0ZpZWxkcyxcbiAgICAgICAgaW5jbHVzaXZlOiBjYWxsT3JSZXR1cm4oXG4gICAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8TWFya0NvbmZpZ1snaW5jbHVzaXZlJ10+KGV4dGVuc2lvbiwgJ2luY2x1c2l2ZScsIGNvbnRleHQpLFxuICAgICAgICApLFxuICAgICAgICBleGNsdWRlczogY2FsbE9yUmV0dXJuKFxuICAgICAgICAgIGdldEV4dGVuc2lvbkZpZWxkPE1hcmtDb25maWdbJ2V4Y2x1ZGVzJ10+KGV4dGVuc2lvbiwgJ2V4Y2x1ZGVzJywgY29udGV4dCksXG4gICAgICAgICksXG4gICAgICAgIGdyb3VwOiBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQ8TWFya0NvbmZpZ1snZ3JvdXAnXT4oZXh0ZW5zaW9uLCAnZ3JvdXAnLCBjb250ZXh0KSksXG4gICAgICAgIHNwYW5uaW5nOiBjYWxsT3JSZXR1cm4oXG4gICAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8TWFya0NvbmZpZ1snc3Bhbm5pbmcnXT4oZXh0ZW5zaW9uLCAnc3Bhbm5pbmcnLCBjb250ZXh0KSxcbiAgICAgICAgKSxcbiAgICAgICAgY29kZTogY2FsbE9yUmV0dXJuKGdldEV4dGVuc2lvbkZpZWxkPE1hcmtDb25maWdbJ2NvZGUnXT4oZXh0ZW5zaW9uLCAnY29kZScsIGNvbnRleHQpKSxcbiAgICAgICAgYXR0cnM6IE9iamVjdC5mcm9tRW50cmllcyhleHRlbnNpb25BdHRyaWJ1dGVzLm1hcChidWlsZEF0dHJpYnV0ZVNwZWMpKSxcbiAgICAgIH0pXG5cbiAgICAgIGNvbnN0IHBhcnNlSFRNTCA9IGNhbGxPclJldHVybihcbiAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8TWFya0NvbmZpZ1sncGFyc2VIVE1MJ10+KGV4dGVuc2lvbiwgJ3BhcnNlSFRNTCcsIGNvbnRleHQpLFxuICAgICAgKVxuXG4gICAgICBpZiAocGFyc2VIVE1MKSB7XG4gICAgICAgIHNjaGVtYS5wYXJzZURPTSA9IHBhcnNlSFRNTC5tYXAocGFyc2VSdWxlID0+XG4gICAgICAgICAgaW5qZWN0RXh0ZW5zaW9uQXR0cmlidXRlc1RvUGFyc2VSdWxlKHBhcnNlUnVsZSwgZXh0ZW5zaW9uQXR0cmlidXRlcyksXG4gICAgICAgIClcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVuZGVySFRNTCA9IGdldEV4dGVuc2lvbkZpZWxkPE1hcmtDb25maWdbJ3JlbmRlckhUTUwnXT4oXG4gICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgJ3JlbmRlckhUTUwnLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKVxuXG4gICAgICBpZiAocmVuZGVySFRNTCkge1xuICAgICAgICBzY2hlbWEudG9ET00gPSBtYXJrID0+XG4gICAgICAgICAgcmVuZGVySFRNTCh7XG4gICAgICAgICAgICBtYXJrLFxuICAgICAgICAgICAgSFRNTEF0dHJpYnV0ZXM6IGdldFJlbmRlcmVkQXR0cmlidXRlcyhtYXJrLCBleHRlbnNpb25BdHRyaWJ1dGVzKSxcbiAgICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gW2V4dGVuc2lvbi5uYW1lLCBzY2hlbWFdXG4gICAgfSksXG4gIClcblxuICByZXR1cm4gbmV3IFNjaGVtYSh7XG4gICAgdG9wTm9kZSxcbiAgICBub2RlcyxcbiAgICBtYXJrcyxcbiAgfSlcbn1cbiIsICIvLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmVuby11bnNhZmUtZnVuY3Rpb24tdHlwZVxuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWU6IGFueSk6IHZhbHVlIGlzIEZ1bmN0aW9uIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJ1xufVxuIiwgImltcG9ydCB0eXBlIHsgTWF5YmVSZXR1cm5UeXBlIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSAnLi9pc0Z1bmN0aW9uLmpzJ1xuXG4vKipcbiAqIE9wdGlvbmFsbHkgY2FsbHMgYHZhbHVlYCBhcyBhIGZ1bmN0aW9uLlxuICogT3RoZXJ3aXNlIGl0IGlzIHJldHVybmVkIGRpcmVjdGx5LlxuICogQHBhcmFtIHZhbHVlIEZ1bmN0aW9uIG9yIGFueSB2YWx1ZS5cbiAqIEBwYXJhbSBjb250ZXh0IE9wdGlvbmFsIGNvbnRleHQgdG8gYmluZCB0byBmdW5jdGlvbi5cbiAqIEBwYXJhbSBwcm9wcyBPcHRpb25hbCBwcm9wcyB0byBwYXNzIHRvIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FsbE9yUmV0dXJuPFQ+KFxuICB2YWx1ZTogVCxcbiAgY29udGV4dDogYW55ID0gdW5kZWZpbmVkLFxuICAuLi5wcm9wczogYW55W11cbik6IE1heWJlUmV0dXJuVHlwZTxUPiB7XG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIGlmIChjb250ZXh0KSB7XG4gICAgICByZXR1cm4gdmFsdWUuYmluZChjb250ZXh0KSguLi5wcm9wcylcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWUoLi4ucHJvcHMpXG4gIH1cblxuICByZXR1cm4gdmFsdWUgYXMgTWF5YmVSZXR1cm5UeXBlPFQ+XG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGlzRW1wdHlPYmplY3QodmFsdWUgPSB7fSk6IGJvb2xlYW4ge1xuICByZXR1cm4gT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA9PT0gMCAmJiB2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5pbXBvcnQgdHlwZSB7IE1hcmsgfSBmcm9tICcuLi9NYXJrLmpzJ1xuaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSAnLi4vTm9kZS5qcydcbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9ucyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gc3BsaXRFeHRlbnNpb25zKGV4dGVuc2lvbnM6IEV4dGVuc2lvbnMpIHtcbiAgY29uc3QgYmFzZUV4dGVuc2lvbnMgPSBleHRlbnNpb25zLmZpbHRlcihcbiAgICBleHRlbnNpb24gPT4gZXh0ZW5zaW9uLnR5cGUgPT09ICdleHRlbnNpb24nLFxuICApIGFzIEV4dGVuc2lvbltdXG4gIGNvbnN0IG5vZGVFeHRlbnNpb25zID0gZXh0ZW5zaW9ucy5maWx0ZXIoZXh0ZW5zaW9uID0+IGV4dGVuc2lvbi50eXBlID09PSAnbm9kZScpIGFzIE5vZGVbXVxuICBjb25zdCBtYXJrRXh0ZW5zaW9ucyA9IGV4dGVuc2lvbnMuZmlsdGVyKGV4dGVuc2lvbiA9PiBleHRlbnNpb24udHlwZSA9PT0gJ21hcmsnKSBhcyBNYXJrW11cblxuICByZXR1cm4ge1xuICAgIGJhc2VFeHRlbnNpb25zLFxuICAgIG5vZGVFeHRlbnNpb25zLFxuICAgIG1hcmtFeHRlbnNpb25zLFxuICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBNYXJrQ29uZmlnLCBOb2RlQ29uZmlnIH0gZnJvbSAnLi4vaW5kZXguanMnXG5pbXBvcnQgdHlwZSB7IEFueUNvbmZpZywgQXR0cmlidXRlLCBBdHRyaWJ1dGVzLCBFeHRlbnNpb25BdHRyaWJ1dGUsIEV4dGVuc2lvbnMgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGdldEV4dGVuc2lvbkZpZWxkIH0gZnJvbSAnLi9nZXRFeHRlbnNpb25GaWVsZC5qcydcbmltcG9ydCB7IHNwbGl0RXh0ZW5zaW9ucyB9IGZyb20gJy4vc3BsaXRFeHRlbnNpb25zLmpzJ1xuXG4vKipcbiAqIEdldCBhIGxpc3Qgb2YgYWxsIGV4dGVuc2lvbiBhdHRyaWJ1dGVzIGRlZmluZWQgaW4gYGFkZEF0dHJpYnV0ZWAgYW5kIGBhZGRHbG9iYWxBdHRyaWJ1dGVgLlxuICogQHBhcmFtIGV4dGVuc2lvbnMgTGlzdCBvZiBleHRlbnNpb25zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBdHRyaWJ1dGVzRnJvbUV4dGVuc2lvbnMoZXh0ZW5zaW9uczogRXh0ZW5zaW9ucyk6IEV4dGVuc2lvbkF0dHJpYnV0ZVtdIHtcbiAgY29uc3QgZXh0ZW5zaW9uQXR0cmlidXRlczogRXh0ZW5zaW9uQXR0cmlidXRlW10gPSBbXVxuICBjb25zdCB7IG5vZGVFeHRlbnNpb25zLCBtYXJrRXh0ZW5zaW9ucyB9ID0gc3BsaXRFeHRlbnNpb25zKGV4dGVuc2lvbnMpXG4gIGNvbnN0IG5vZGVBbmRNYXJrRXh0ZW5zaW9ucyA9IFsuLi5ub2RlRXh0ZW5zaW9ucywgLi4ubWFya0V4dGVuc2lvbnNdXG4gIGNvbnN0IGRlZmF1bHRBdHRyaWJ1dGU6IFJlcXVpcmVkPE9taXQ8QXR0cmlidXRlLCAndmFsaWRhdGUnPj4gJiBQaWNrPEF0dHJpYnV0ZSwgJ3ZhbGlkYXRlJz4gPSB7XG4gICAgZGVmYXVsdDogbnVsbCxcbiAgICB2YWxpZGF0ZTogdW5kZWZpbmVkLFxuICAgIHJlbmRlcmVkOiB0cnVlLFxuICAgIHJlbmRlckhUTUw6IG51bGwsXG4gICAgcGFyc2VIVE1MOiBudWxsLFxuICAgIGtlZXBPblNwbGl0OiB0cnVlLFxuICAgIGlzUmVxdWlyZWQ6IGZhbHNlLFxuICB9XG5cbiAgLy8gUHJlY29tcHV0ZSBsaXN0cyBvZiBleHRlbnNpb24gdHlwZXMgZm9yIGdsb2JhbCBhdHRyaWJ1dGUgcmVzb2x1dGlvblxuICBjb25zdCBub2RlRXh0ZW5zaW9uVHlwZXMgPSBub2RlRXh0ZW5zaW9ucy5maWx0ZXIoZXh0ID0+IGV4dC5uYW1lICE9PSAndGV4dCcpLm1hcChleHQgPT4gZXh0Lm5hbWUpXG4gIGNvbnN0IG1hcmtFeHRlbnNpb25UeXBlcyA9IG1hcmtFeHRlbnNpb25zLm1hcChleHQgPT4gZXh0Lm5hbWUpXG4gIGNvbnN0IGFsbEV4dGVuc2lvblR5cGVzID0gWy4uLm5vZGVFeHRlbnNpb25UeXBlcywgLi4ubWFya0V4dGVuc2lvblR5cGVzXVxuXG4gIGV4dGVuc2lvbnMuZm9yRWFjaChleHRlbnNpb24gPT4ge1xuICAgIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgICBuYW1lOiBleHRlbnNpb24ubmFtZSxcbiAgICAgIG9wdGlvbnM6IGV4dGVuc2lvbi5vcHRpb25zLFxuICAgICAgc3RvcmFnZTogZXh0ZW5zaW9uLnN0b3JhZ2UsXG4gICAgICBleHRlbnNpb25zOiBub2RlQW5kTWFya0V4dGVuc2lvbnMsXG4gICAgfVxuXG4gICAgY29uc3QgYWRkR2xvYmFsQXR0cmlidXRlcyA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snYWRkR2xvYmFsQXR0cmlidXRlcyddPihcbiAgICAgIGV4dGVuc2lvbixcbiAgICAgICdhZGRHbG9iYWxBdHRyaWJ1dGVzJyxcbiAgICAgIGNvbnRleHQsXG4gICAgKVxuXG4gICAgaWYgKCFhZGRHbG9iYWxBdHRyaWJ1dGVzKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBnbG9iYWxBdHRyaWJ1dGVzID0gYWRkR2xvYmFsQXR0cmlidXRlcygpXG5cbiAgICBnbG9iYWxBdHRyaWJ1dGVzLmZvckVhY2goZ2xvYmFsQXR0cmlidXRlID0+IHtcbiAgICAgIC8vIFJlc29sdmUgdGhlIHR5cGVzIGJhc2VkIG9uIHRoZSBzdHJpbmcgc2hvcnRoYW5kIG9yIGV4cGxpY2l0IGFycmF5XG4gICAgICBsZXQgcmVzb2x2ZWRUeXBlczogc3RyaW5nW11cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGdsb2JhbEF0dHJpYnV0ZS50eXBlcykpIHtcbiAgICAgICAgcmVzb2x2ZWRUeXBlcyA9IGdsb2JhbEF0dHJpYnV0ZS50eXBlc1xuICAgICAgfSBlbHNlIGlmIChnbG9iYWxBdHRyaWJ1dGUudHlwZXMgPT09ICcqJykge1xuICAgICAgICByZXNvbHZlZFR5cGVzID0gYWxsRXh0ZW5zaW9uVHlwZXNcbiAgICAgIH0gZWxzZSBpZiAoZ2xvYmFsQXR0cmlidXRlLnR5cGVzID09PSAnbm9kZXMnKSB7XG4gICAgICAgIHJlc29sdmVkVHlwZXMgPSBub2RlRXh0ZW5zaW9uVHlwZXNcbiAgICAgIH0gZWxzZSBpZiAoZ2xvYmFsQXR0cmlidXRlLnR5cGVzID09PSAnbWFya3MnKSB7XG4gICAgICAgIHJlc29sdmVkVHlwZXMgPSBtYXJrRXh0ZW5zaW9uVHlwZXNcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmVkVHlwZXMgPSBbXVxuICAgICAgfVxuXG4gICAgICByZXNvbHZlZFR5cGVzLmZvckVhY2godHlwZSA9PiB7XG4gICAgICAgIE9iamVjdC5lbnRyaWVzKGdsb2JhbEF0dHJpYnV0ZS5hdHRyaWJ1dGVzKS5mb3JFYWNoKChbbmFtZSwgYXR0cmlidXRlXSkgPT4ge1xuICAgICAgICAgIGV4dGVuc2lvbkF0dHJpYnV0ZXMucHVzaCh7XG4gICAgICAgICAgICB0eXBlLFxuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGF0dHJpYnV0ZToge1xuICAgICAgICAgICAgICAuLi5kZWZhdWx0QXR0cmlidXRlLFxuICAgICAgICAgICAgICAuLi5hdHRyaWJ1dGUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIH0pXG4gIH0pXG5cbiAgbm9kZUFuZE1hcmtFeHRlbnNpb25zLmZvckVhY2goZXh0ZW5zaW9uID0+IHtcbiAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICBvcHRpb25zOiBleHRlbnNpb24ub3B0aW9ucyxcbiAgICAgIHN0b3JhZ2U6IGV4dGVuc2lvbi5zdG9yYWdlLFxuICAgIH1cblxuICAgIGNvbnN0IGFkZEF0dHJpYnV0ZXMgPSBnZXRFeHRlbnNpb25GaWVsZDxcbiAgICAgIE5vZGVDb25maWdbJ2FkZEF0dHJpYnV0ZXMnXSB8IE1hcmtDb25maWdbJ2FkZEF0dHJpYnV0ZXMnXVxuICAgID4oZXh0ZW5zaW9uLCAnYWRkQXR0cmlidXRlcycsIGNvbnRleHQpXG5cbiAgICBpZiAoIWFkZEF0dHJpYnV0ZXMpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIFRPRE86IHJlbW92ZSBgYXMgQXR0cmlidXRlc2BcbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gYWRkQXR0cmlidXRlcygpIGFzIEF0dHJpYnV0ZXNcblxuICAgIE9iamVjdC5lbnRyaWVzKGF0dHJpYnV0ZXMpLmZvckVhY2goKFtuYW1lLCBhdHRyaWJ1dGVdKSA9PiB7XG4gICAgICBjb25zdCBtZXJnZWRBdHRyID0ge1xuICAgICAgICAuLi5kZWZhdWx0QXR0cmlidXRlLFxuICAgICAgICAuLi5hdHRyaWJ1dGUsXG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgbWVyZ2VkQXR0cj8uZGVmYXVsdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBtZXJnZWRBdHRyLmRlZmF1bHQgPSBtZXJnZWRBdHRyLmRlZmF1bHQoKVxuICAgICAgfVxuXG4gICAgICBpZiAobWVyZ2VkQXR0cj8uaXNSZXF1aXJlZCAmJiBtZXJnZWRBdHRyPy5kZWZhdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZGVsZXRlIG1lcmdlZEF0dHIuZGVmYXVsdFxuICAgICAgfVxuXG4gICAgICBleHRlbnNpb25BdHRyaWJ1dGVzLnB1c2goe1xuICAgICAgICB0eXBlOiBleHRlbnNpb24ubmFtZSxcbiAgICAgICAgbmFtZSxcbiAgICAgICAgYXR0cmlidXRlOiBtZXJnZWRBdHRyLFxuICAgICAgfSlcbiAgICB9KVxuICB9KVxuXG4gIHJldHVybiBleHRlbnNpb25BdHRyaWJ1dGVzXG59XG4iLCAiLyoqIFNwbGl0cyBhIENTUyBzdHlsZSBzdHJpbmcgaW50byBkZWNsYXJhdGlvbnMsIGlnbm9yaW5nIHNlbWljb2xvbnMgaW5zaWRlIHF1b3Rlcy9wYXJlbnRoZXNlcy4gKi9cbmZ1bmN0aW9uIHNwbGl0U3R5bGVEZWNsYXJhdGlvbnMoc3R5bGVzOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbXVxuXG4gIGxldCBjdXJyZW50ID0gJydcbiAgbGV0IGluU2luZ2xlUXVvdGUgPSBmYWxzZVxuICBsZXQgaW5Eb3VibGVRdW90ZSA9IGZhbHNlXG4gIGxldCBwYXJlbkRlcHRoID0gMFxuXG4gIGNvbnN0IGxlbmd0aCA9IHN0eWxlcy5sZW5ndGhcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMSkge1xuICAgIGNvbnN0IGNoYXIgPSBzdHlsZXNbaV1cbiAgICBpZiAoY2hhciA9PT0gXCInXCIgJiYgIWluRG91YmxlUXVvdGUpIHtcbiAgICAgIGluU2luZ2xlUXVvdGUgPSAhaW5TaW5nbGVRdW90ZVxuICAgICAgY3VycmVudCArPSBjaGFyXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoY2hhciA9PT0gJ1wiJyAmJiAhaW5TaW5nbGVRdW90ZSkge1xuICAgICAgaW5Eb3VibGVRdW90ZSA9ICFpbkRvdWJsZVF1b3RlXG4gICAgICBjdXJyZW50ICs9IGNoYXJcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmICghaW5TaW5nbGVRdW90ZSAmJiAhaW5Eb3VibGVRdW90ZSkge1xuICAgICAgaWYgKGNoYXIgPT09ICcoJykge1xuICAgICAgICBwYXJlbkRlcHRoICs9IDFcbiAgICAgICAgY3VycmVudCArPSBjaGFyXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBpZiAoY2hhciA9PT0gJyknICYmIHBhcmVuRGVwdGggPiAwKSB7XG4gICAgICAgIHBhcmVuRGVwdGggLT0gMVxuICAgICAgICBjdXJyZW50ICs9IGNoYXJcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGlmIChjaGFyID09PSAnOycgJiYgcGFyZW5EZXB0aCA9PT0gMCkge1xuICAgICAgICByZXN1bHQucHVzaChjdXJyZW50KVxuICAgICAgICBjdXJyZW50ID0gJydcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICB9XG4gICAgY3VycmVudCArPSBjaGFyXG4gIH1cbiAgaWYgKGN1cnJlbnQpIHtcbiAgICByZXN1bHQucHVzaChjdXJyZW50KVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vKiogWWllbGRzIHByb3BlcnR5L3ZhbHVlIHBhaXJzIGZyb20gYSBzdHlsZSBzdHJpbmcuICovXG5mdW5jdGlvbiBwYXJzZVN0eWxlRW50cmllcyhzdHlsZXM6IHN0cmluZyB8IHVuZGVmaW5lZCk6IFtwcm9wZXJ0eTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nXVtdIHtcbiAgY29uc3QgcGFpcnM6IFtzdHJpbmcsIHN0cmluZ11bXSA9IFtdXG5cbiAgY29uc3QgZGVjbGFyYXRpb25zID0gc3BsaXRTdHlsZURlY2xhcmF0aW9ucyhzdHlsZXMgfHwgJycpXG4gIGNvbnN0IG51bURlY2xhcmF0aW9ucyA9IGRlY2xhcmF0aW9ucy5sZW5ndGhcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IG51bURlY2xhcmF0aW9uczsgaSArPSAxKSB7XG4gICAgY29uc3QgZGVjbGFyYXRpb24gPSBkZWNsYXJhdGlvbnNbaV1cblxuICAgIGNvbnN0IGZpcnN0Q29sb25JbmRleCA9IGRlY2xhcmF0aW9uLmluZGV4T2YoJzonKVxuICAgIGlmIChmaXJzdENvbG9uSW5kZXggPT09IC0xKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGNvbnN0IHByb3BlcnR5ID0gZGVjbGFyYXRpb24uc2xpY2UoMCwgZmlyc3RDb2xvbkluZGV4KS50cmltKClcbiAgICBjb25zdCB2YWx1ZSA9IGRlY2xhcmF0aW9uLnNsaWNlKGZpcnN0Q29sb25JbmRleCArIDEpLnRyaW0oKVxuICAgIGlmIChwcm9wZXJ0eSAmJiB2YWx1ZSkge1xuICAgICAgcGFpcnMucHVzaChbcHJvcGVydHksIHZhbHVlXSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcGFpcnNcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlQXR0cmlidXRlcyguLi5vYmplY3RzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10pOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgcmV0dXJuIG9iamVjdHNcbiAgICAuZmlsdGVyKGl0ZW0gPT4gISFpdGVtKVxuICAgIC5yZWR1Y2UoKGl0ZW1zLCBpdGVtKSA9PiB7XG4gICAgICBjb25zdCBtZXJnZWRBdHRyaWJ1dGVzID0geyAuLi5pdGVtcyB9XG5cbiAgICAgIE9iamVjdC5lbnRyaWVzKGl0ZW0pLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICBjb25zdCBleGlzdHMgPSBtZXJnZWRBdHRyaWJ1dGVzW2tleV1cblxuICAgICAgICBpZiAoIWV4aXN0cykge1xuICAgICAgICAgIG1lcmdlZEF0dHJpYnV0ZXNba2V5XSA9IHZhbHVlXG5cbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChrZXkgPT09ICdjbGFzcycpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZUNsYXNzZXM6IHN0cmluZ1tdID0gdmFsdWUgPyBTdHJpbmcodmFsdWUpLnNwbGl0KCcgJykgOiBbXVxuICAgICAgICAgIGNvbnN0IGV4aXN0aW5nQ2xhc3Nlczogc3RyaW5nW10gPSBtZXJnZWRBdHRyaWJ1dGVzW2tleV1cbiAgICAgICAgICAgID8gbWVyZ2VkQXR0cmlidXRlc1trZXldLnNwbGl0KCcgJylcbiAgICAgICAgICAgIDogW11cblxuICAgICAgICAgIGNvbnN0IGluc2VydENsYXNzZXMgPSB2YWx1ZUNsYXNzZXMuZmlsdGVyKFxuICAgICAgICAgICAgdmFsdWVDbGFzcyA9PiAhZXhpc3RpbmdDbGFzc2VzLmluY2x1ZGVzKHZhbHVlQ2xhc3MpLFxuICAgICAgICAgIClcblxuICAgICAgICAgIG1lcmdlZEF0dHJpYnV0ZXNba2V5XSA9IFsuLi5leGlzdGluZ0NsYXNzZXMsIC4uLmluc2VydENsYXNzZXNdLmpvaW4oJyAnKVxuICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ3N0eWxlJykge1xuICAgICAgICAgIGNvbnN0IHN0eWxlTWFwID0gbmV3IE1hcChbXG4gICAgICAgICAgICAuLi5wYXJzZVN0eWxlRW50cmllcyhtZXJnZWRBdHRyaWJ1dGVzW2tleV0pLFxuICAgICAgICAgICAgLi4ucGFyc2VTdHlsZUVudHJpZXModmFsdWUpLFxuICAgICAgICAgIF0pXG5cbiAgICAgICAgICBtZXJnZWRBdHRyaWJ1dGVzW2tleV0gPSBBcnJheS5mcm9tKHN0eWxlTWFwLmVudHJpZXMoKSlcbiAgICAgICAgICAgIC5tYXAoKFtwcm9wZXJ0eSwgdmFsXSkgPT4gYCR7cHJvcGVydHl9OiAke3ZhbH1gKVxuICAgICAgICAgICAgLmpvaW4oJzsgJylcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtZXJnZWRBdHRyaWJ1dGVzW2tleV0gPSB2YWx1ZVxuICAgICAgICB9XG4gICAgICB9KVxuXG4gICAgICByZXR1cm4gbWVyZ2VkQXR0cmlidXRlc1xuICAgIH0sIHt9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgTWFyaywgTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQXR0cmlidXRlIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBtZXJnZUF0dHJpYnV0ZXMgfSBmcm9tICcuLi91dGlsaXRpZXMvbWVyZ2VBdHRyaWJ1dGVzLmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVuZGVyZWRBdHRyaWJ1dGVzKFxuICBub2RlT3JNYXJrOiBOb2RlIHwgTWFyayxcbiAgZXh0ZW5zaW9uQXR0cmlidXRlczogRXh0ZW5zaW9uQXR0cmlidXRlW10sXG4pOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgcmV0dXJuIGV4dGVuc2lvbkF0dHJpYnV0ZXNcbiAgICAuZmlsdGVyKGF0dHJpYnV0ZSA9PiBhdHRyaWJ1dGUudHlwZSA9PT0gbm9kZU9yTWFyay50eXBlLm5hbWUpXG4gICAgLmZpbHRlcihpdGVtID0+IGl0ZW0uYXR0cmlidXRlLnJlbmRlcmVkKVxuICAgIC5tYXAoaXRlbSA9PiB7XG4gICAgICBpZiAoIWl0ZW0uYXR0cmlidXRlLnJlbmRlckhUTUwpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBbaXRlbS5uYW1lXTogbm9kZU9yTWFyay5hdHRyc1tpdGVtLm5hbWVdLFxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBpdGVtLmF0dHJpYnV0ZS5yZW5kZXJIVE1MKG5vZGVPck1hcmsuYXR0cnMpIHx8IHt9XG4gICAgfSlcbiAgICAucmVkdWNlKChhdHRyaWJ1dGVzLCBhdHRyaWJ1dGUpID0+IG1lcmdlQXR0cmlidXRlcyhhdHRyaWJ1dGVzLCBhdHRyaWJ1dGUpLCB7fSlcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gZnJvbVN0cmluZyh2YWx1ZTogYW55KTogYW55IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIGlmICh2YWx1ZS5tYXRjaCgvXlsrLV0/KD86XFxkKlxcLik/XFxkKyQvKSkge1xuICAgIHJldHVybiBOdW1iZXIodmFsdWUpXG4gIH1cblxuICBpZiAodmFsdWUgPT09ICd0cnVlJykge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBpZiAodmFsdWUgPT09ICdmYWxzZScpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiB2YWx1ZVxufVxuIiwgImltcG9ydCB0eXBlIHsgUGFyc2VSdWxlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BdHRyaWJ1dGUgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGZyb21TdHJpbmcgfSBmcm9tICcuLi91dGlsaXRpZXMvZnJvbVN0cmluZy5qcydcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIG1lcmdlcyBleHRlbnNpb24gYXR0cmlidXRlcyBpbnRvIHBhcnNlcnVsZSBhdHRyaWJ1dGVzIChgYXR0cnNgIG9yIGBnZXRBdHRyc2ApLlxuICogQ2FuY2VscyB3aGVuIGBnZXRBdHRyc2AgcmV0dXJuZWQgYGZhbHNlYC5cbiAqIEBwYXJhbSBwYXJzZVJ1bGUgUHJvc2VNaXJyb3IgUGFyc2VSdWxlXG4gKiBAcGFyYW0gZXh0ZW5zaW9uQXR0cmlidXRlcyBMaXN0IG9mIGF0dHJpYnV0ZXMgdG8gaW5qZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmplY3RFeHRlbnNpb25BdHRyaWJ1dGVzVG9QYXJzZVJ1bGUoXG4gIHBhcnNlUnVsZTogUGFyc2VSdWxlLFxuICBleHRlbnNpb25BdHRyaWJ1dGVzOiBFeHRlbnNpb25BdHRyaWJ1dGVbXSxcbik6IFBhcnNlUnVsZSB7XG4gIGlmICgnc3R5bGUnIGluIHBhcnNlUnVsZSkge1xuICAgIHJldHVybiBwYXJzZVJ1bGVcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgLi4ucGFyc2VSdWxlLFxuICAgIGdldEF0dHJzOiAobm9kZTogSFRNTEVsZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IG9sZEF0dHJpYnV0ZXMgPSBwYXJzZVJ1bGUuZ2V0QXR0cnMgPyBwYXJzZVJ1bGUuZ2V0QXR0cnMobm9kZSkgOiBwYXJzZVJ1bGUuYXR0cnNcblxuICAgICAgaWYgKG9sZEF0dHJpYnV0ZXMgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXdBdHRyaWJ1dGVzID0gZXh0ZW5zaW9uQXR0cmlidXRlcy5yZWR1Y2UoKGl0ZW1zLCBpdGVtKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gaXRlbS5hdHRyaWJ1dGUucGFyc2VIVE1MXG4gICAgICAgICAgPyBpdGVtLmF0dHJpYnV0ZS5wYXJzZUhUTUwobm9kZSlcbiAgICAgICAgICA6IGZyb21TdHJpbmcobm9kZS5nZXRBdHRyaWJ1dGUoaXRlbS5uYW1lKSlcblxuICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiBpdGVtc1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5pdGVtcyxcbiAgICAgICAgICBbaXRlbS5uYW1lXTogdmFsdWUsXG4gICAgICAgIH1cbiAgICAgIH0sIHt9KVxuXG4gICAgICByZXR1cm4geyAuLi5vbGRBdHRyaWJ1dGVzLCAuLi5uZXdBdHRyaWJ1dGVzIH1cbiAgICB9LFxuICB9XG59XG4iLCAiLyoqXG4gKiBGaW5kIGR1cGxpY2F0ZXMgaW4gYW4gYXJyYXkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kRHVwbGljYXRlczxUPihpdGVtczogVFtdKTogVFtdIHtcbiAgY29uc3QgZmlsdGVyZWQgPSBpdGVtcy5maWx0ZXIoKGVsLCBpbmRleCkgPT4gaXRlbXMuaW5kZXhPZihlbCkgIT09IGluZGV4KVxuXG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoZmlsdGVyZWQpKVxufVxuIiwgImltcG9ydCB0eXBlIHsgQW55Q29uZmlnLCBFeHRlbnNpb25zIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBnZXRFeHRlbnNpb25GaWVsZCB9IGZyb20gJy4vZ2V0RXh0ZW5zaW9uRmllbGQuanMnXG5cbi8qKlxuICogU29ydCBleHRlbnNpb25zIGJ5IHByaW9yaXR5LlxuICogQHBhcmFtIGV4dGVuc2lvbnMgQW4gYXJyYXkgb2YgVGlwdGFwIGV4dGVuc2lvbnNcbiAqIEByZXR1cm5zIEEgc29ydGVkIGFycmF5IG9mIFRpcHRhcCBleHRlbnNpb25zIGJ5IHByaW9yaXR5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzb3J0RXh0ZW5zaW9ucyhleHRlbnNpb25zOiBFeHRlbnNpb25zKTogRXh0ZW5zaW9ucyB7XG4gIGNvbnN0IGRlZmF1bHRQcmlvcml0eSA9IDEwMFxuXG4gIHJldHVybiBleHRlbnNpb25zLnNvcnQoKGEsIGIpID0+IHtcbiAgICBjb25zdCBwcmlvcml0eUEgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ3ByaW9yaXR5J10+KGEsICdwcmlvcml0eScpIHx8IGRlZmF1bHRQcmlvcml0eVxuICAgIGNvbnN0IHByaW9yaXR5QiA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1sncHJpb3JpdHknXT4oYiwgJ3ByaW9yaXR5JykgfHwgZGVmYXVsdFByaW9yaXR5XG5cbiAgICBpZiAocHJpb3JpdHlBID4gcHJpb3JpdHlCKSB7XG4gICAgICByZXR1cm4gLTFcbiAgICB9XG5cbiAgICBpZiAocHJpb3JpdHlBIDwgcHJpb3JpdHlCKSB7XG4gICAgICByZXR1cm4gMVxuICAgIH1cblxuICAgIHJldHVybiAwXG4gIH0pXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25zIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBmaW5kRHVwbGljYXRlcyB9IGZyb20gJy4uL3V0aWxpdGllcy9maW5kRHVwbGljYXRlcy5qcydcbmltcG9ydCB7IGZsYXR0ZW5FeHRlbnNpb25zIH0gZnJvbSAnLi9mbGF0dGVuRXh0ZW5zaW9ucy5qcydcbmltcG9ydCB7IHNvcnRFeHRlbnNpb25zIH0gZnJvbSAnLi9zb3J0RXh0ZW5zaW9ucy5qcydcblxuLyoqXG4gKiBSZXR1cm5zIGEgZmxhdHRlbmVkIGFuZCBzb3J0ZWQgZXh0ZW5zaW9uIGxpc3Qgd2hpbGVcbiAqIGFsc28gY2hlY2tpbmcgZm9yIGR1cGxpY2F0ZWQgZXh0ZW5zaW9ucyBhbmQgd2FybnMgdGhlIHVzZXIuXG4gKiBAcGFyYW0gZXh0ZW5zaW9ucyBBbiBhcnJheSBvZiBUaXB0YXAgZXh0ZW5zaW9uc1xuICogQHJldHVybnMgQW4gZmxhdHRlbmVkIGFuZCBzb3J0ZWQgYXJyYXkgb2YgVGlwdGFwIGV4dGVuc2lvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVFeHRlbnNpb25zKGV4dGVuc2lvbnM6IEV4dGVuc2lvbnMpOiBFeHRlbnNpb25zIHtcbiAgY29uc3QgcmVzb2x2ZWRFeHRlbnNpb25zID0gc29ydEV4dGVuc2lvbnMoZmxhdHRlbkV4dGVuc2lvbnMoZXh0ZW5zaW9ucykpXG4gIGNvbnN0IGR1cGxpY2F0ZWROYW1lcyA9IGZpbmREdXBsaWNhdGVzKHJlc29sdmVkRXh0ZW5zaW9ucy5tYXAoZXh0ZW5zaW9uID0+IGV4dGVuc2lvbi5uYW1lKSlcblxuICBpZiAoZHVwbGljYXRlZE5hbWVzLmxlbmd0aCkge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgIGBbdGlwdGFwIHdhcm5dOiBEdXBsaWNhdGUgZXh0ZW5zaW9uIG5hbWVzIGZvdW5kOiBbJHtkdXBsaWNhdGVkTmFtZXNcbiAgICAgICAgLm1hcChpdGVtID0+IGAnJHtpdGVtfSdgKVxuICAgICAgICAuam9pbignLCAnKX1dLiBUaGlzIGNhbiBsZWFkIHRvIGlzc3Vlcy5gLFxuICAgIClcbiAgfVxuXG4gIHJldHVybiByZXNvbHZlZEV4dGVuc2lvbnNcbn1cbiIsICJpbXBvcnQgdHlwZSB7IFNjaGVtYSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB0eXBlIHsgRWRpdG9yIH0gZnJvbSAnLi4vRWRpdG9yLmpzJ1xuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25zIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBnZXRTY2hlbWFCeVJlc29sdmVkRXh0ZW5zaW9ucyB9IGZyb20gJy4vZ2V0U2NoZW1hQnlSZXNvbHZlZEV4dGVuc2lvbnMuanMnXG5pbXBvcnQgeyByZXNvbHZlRXh0ZW5zaW9ucyB9IGZyb20gJy4vcmVzb2x2ZUV4dGVuc2lvbnMuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTY2hlbWEoZXh0ZW5zaW9uczogRXh0ZW5zaW9ucywgZWRpdG9yPzogRWRpdG9yKTogU2NoZW1hIHtcbiAgY29uc3QgcmVzb2x2ZWRFeHRlbnNpb25zID0gcmVzb2x2ZUV4dGVuc2lvbnMoZXh0ZW5zaW9ucylcblxuICByZXR1cm4gZ2V0U2NoZW1hQnlSZXNvbHZlZEV4dGVuc2lvbnMocmVzb2x2ZWRFeHRlbnNpb25zLCBlZGl0b3IpXG59XG4iLCAiaW1wb3J0IHsgRE9NUGFyc2VyIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25zIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBlbGVtZW50RnJvbVN0cmluZyB9IGZyb20gJy4uL3V0aWxpdGllcy9lbGVtZW50RnJvbVN0cmluZy5qcydcbmltcG9ydCB7IGdldFNjaGVtYSB9IGZyb20gJy4vZ2V0U2NoZW1hLmpzJ1xuXG4vKipcbiAqIEdlbmVyYXRlIEpTT05Db250ZW50IGZyb20gSFRNTFxuICogQHBhcmFtIGh0bWwgVGhlIEhUTUwgdG8gZ2VuZXJhdGUgSlNPTkNvbnRlbnQgZnJvbVxuICogQHBhcmFtIGV4dGVuc2lvbnMgVGhlIGV4dGVuc2lvbnMgdG8gdXNlIGZvciB0aGUgc2NoZW1hXG4gKiBAcmV0dXJucyBUaGUgZ2VuZXJhdGVkIEpTT05Db250ZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUpTT04oaHRtbDogc3RyaW5nLCBleHRlbnNpb25zOiBFeHRlbnNpb25zKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gIGNvbnN0IHNjaGVtYSA9IGdldFNjaGVtYShleHRlbnNpb25zKVxuICBjb25zdCBkb20gPSBlbGVtZW50RnJvbVN0cmluZyhodG1sKVxuXG4gIHJldHVybiBET01QYXJzZXIuZnJvbVNjaGVtYShzY2hlbWEpLnBhcnNlKGRvbSkudG9KU09OKClcbn1cbiIsICJpbXBvcnQgeyBOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25zLCBKU09OQ29udGVudCwgVGV4dFNlcmlhbGl6ZXIgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGdldFNjaGVtYSB9IGZyb20gJy4vZ2V0U2NoZW1hLmpzJ1xuaW1wb3J0IHsgZ2V0VGV4dCB9IGZyb20gJy4vZ2V0VGV4dC5qcydcbmltcG9ydCB7IGdldFRleHRTZXJpYWxpemVyc0Zyb21TY2hlbWEgfSBmcm9tICcuL2dldFRleHRTZXJpYWxpemVyc0Zyb21TY2hlbWEuanMnXG5cbi8qKlxuICogR2VuZXJhdGUgcmF3IHRleHQgZnJvbSBhIEpTT05Db250ZW50XG4gKiBAcGFyYW0gZG9jIFRoZSBKU09OQ29udGVudCB0byBnZW5lcmF0ZSB0ZXh0IGZyb21cbiAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBleHRlbnNpb25zIHRvIHVzZSBmb3IgdGhlIHNjaGVtYVxuICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgdGhlIHRleHQgZ2VuZXJhdGlvbiBmLmUuIGJsb2NrU2VwYXJhdG9yIG9yIHRleHRTZXJpYWxpemVyc1xuICogQHJldHVybnMgVGhlIGdlbmVyYXRlZCB0ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVRleHQoXG4gIGRvYzogSlNPTkNvbnRlbnQsXG4gIGV4dGVuc2lvbnM6IEV4dGVuc2lvbnMsXG4gIG9wdGlvbnM/OiB7XG4gICAgYmxvY2tTZXBhcmF0b3I/OiBzdHJpbmdcbiAgICB0ZXh0U2VyaWFsaXplcnM/OiBSZWNvcmQ8c3RyaW5nLCBUZXh0U2VyaWFsaXplcj5cbiAgfSxcbik6IHN0cmluZyB7XG4gIGNvbnN0IHsgYmxvY2tTZXBhcmF0b3IgPSAnXFxuXFxuJywgdGV4dFNlcmlhbGl6ZXJzID0ge30gfSA9IG9wdGlvbnMgfHwge31cbiAgY29uc3Qgc2NoZW1hID0gZ2V0U2NoZW1hKGV4dGVuc2lvbnMpXG4gIGNvbnN0IGNvbnRlbnROb2RlID0gTm9kZS5mcm9tSlNPTihzY2hlbWEsIGRvYylcblxuICByZXR1cm4gZ2V0VGV4dChjb250ZW50Tm9kZSwge1xuICAgIGJsb2NrU2VwYXJhdG9yLFxuICAgIHRleHRTZXJpYWxpemVyczoge1xuICAgICAgLi4uZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYShzY2hlbWEpLFxuICAgICAgLi4udGV4dFNlcmlhbGl6ZXJzLFxuICAgIH0sXG4gIH0pXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB0eXBlIHsgUmFuZ2UsIFRleHRTZXJpYWxpemVyIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbi8qKlxuICogR2V0cyB0aGUgdGV4dCBiZXR3ZWVuIHR3byBwb3NpdGlvbnMgaW4gYSBQcm9zZW1pcnJvciBub2RlXG4gKiBhbmQgc2VyaWFsaXplcyBpdCB1c2luZyB0aGUgZ2l2ZW4gdGV4dCBzZXJpYWxpemVycyBhbmQgYmxvY2sgc2VwYXJhdG9yIChzZWUgZ2V0VGV4dClcbiAqIEBwYXJhbSBzdGFydE5vZGUgVGhlIFByb3NlbWlycm9yIG5vZGUgdG8gc3RhcnQgZnJvbVxuICogQHBhcmFtIHJhbmdlIFRoZSByYW5nZSBvZiB0aGUgdGV4dCB0byBnZXRcbiAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIHRoZSB0ZXh0IHNlcmlhbGl6ZXIgJiBibG9jayBzZXBhcmF0b3JcbiAqIEByZXR1cm5zIFRoZSB0ZXh0IGJldHdlZW4gdGhlIHR3byBwb3NpdGlvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRleHRCZXR3ZWVuKFxuICBzdGFydE5vZGU6IFByb3NlTWlycm9yTm9kZSxcbiAgcmFuZ2U6IFJhbmdlLFxuICBvcHRpb25zPzoge1xuICAgIGJsb2NrU2VwYXJhdG9yPzogc3RyaW5nXG4gICAgdGV4dFNlcmlhbGl6ZXJzPzogUmVjb3JkPHN0cmluZywgVGV4dFNlcmlhbGl6ZXI+XG4gIH0sXG4pOiBzdHJpbmcge1xuICBjb25zdCB7IGZyb20sIHRvIH0gPSByYW5nZVxuICBjb25zdCB7IGJsb2NrU2VwYXJhdG9yID0gJ1xcblxcbicsIHRleHRTZXJpYWxpemVycyA9IHt9IH0gPSBvcHRpb25zIHx8IHt9XG4gIGxldCB0ZXh0ID0gJydcblxuICBzdGFydE5vZGUubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zLCBwYXJlbnQsIGluZGV4KSA9PiB7XG4gICAgaWYgKG5vZGUuaXNCbG9jayAmJiBwb3MgPiBmcm9tKSB7XG4gICAgICB0ZXh0ICs9IGJsb2NrU2VwYXJhdG9yXG4gICAgfVxuXG4gICAgY29uc3QgdGV4dFNlcmlhbGl6ZXIgPSB0ZXh0U2VyaWFsaXplcnM/Lltub2RlLnR5cGUubmFtZV1cblxuICAgIGlmICh0ZXh0U2VyaWFsaXplcikge1xuICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICB0ZXh0ICs9IHRleHRTZXJpYWxpemVyKHtcbiAgICAgICAgICBub2RlLFxuICAgICAgICAgIHBvcyxcbiAgICAgICAgICBwYXJlbnQsXG4gICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgcmFuZ2UsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgICAvLyBkbyBub3QgZGVzY2VuZCBpbnRvIGNoaWxkIG5vZGVzIHdoZW4gdGhlcmUgZXhpc3RzIGEgc2VyaWFsaXplclxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKG5vZGUuaXNUZXh0KSB7XG4gICAgICB0ZXh0ICs9IG5vZGU/LnRleHQ/LnNsaWNlKE1hdGgubWF4KGZyb20sIHBvcykgLSBwb3MsIHRvIC0gcG9zKSAvLyBveGxpbnQtZGlzYWJsZS1saW5lXG4gICAgfVxuICB9KVxuXG4gIHJldHVybiB0ZXh0XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB0eXBlIHsgVGV4dFNlcmlhbGl6ZXIgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGdldFRleHRCZXR3ZWVuIH0gZnJvbSAnLi9nZXRUZXh0QmV0d2Vlbi5qcydcblxuLyoqXG4gKiBHZXRzIHRoZSB0ZXh0IG9mIGEgUHJvc2VtaXJyb3Igbm9kZVxuICogQHBhcmFtIG5vZGUgVGhlIFByb3NlbWlycm9yIG5vZGVcbiAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIHRoZSB0ZXh0IHNlcmlhbGl6ZXIgJiBibG9jayBzZXBhcmF0b3JcbiAqIEByZXR1cm5zIFRoZSB0ZXh0IG9mIHRoZSBub2RlXG4gKiBAZXhhbXBsZSBgYGBqc1xuICogY29uc3QgdGV4dCA9IGdldFRleHQobm9kZSwgeyBibG9ja1NlcGFyYXRvcjogJ1xcbicgfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGV4dChcbiAgbm9kZTogUHJvc2VNaXJyb3JOb2RlLFxuICBvcHRpb25zPzoge1xuICAgIGJsb2NrU2VwYXJhdG9yPzogc3RyaW5nXG4gICAgdGV4dFNlcmlhbGl6ZXJzPzogUmVjb3JkPHN0cmluZywgVGV4dFNlcmlhbGl6ZXI+XG4gIH0sXG4pIHtcbiAgY29uc3QgcmFuZ2UgPSB7XG4gICAgZnJvbTogMCxcbiAgICB0bzogbm9kZS5jb250ZW50LnNpemUsXG4gIH1cblxuICByZXR1cm4gZ2V0VGV4dEJldHdlZW4obm9kZSwgcmFuZ2UsIG9wdGlvbnMpXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBTY2hlbWEgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgdHlwZSB7IFRleHRTZXJpYWxpemVyIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbi8qKlxuICogRmluZCB0ZXh0IHNlcmlhbGl6ZXJzIGB0b1RleHRgIGluIGEgUHJvc2VtaXJyb3Igc2NoZW1hXG4gKiBAcGFyYW0gc2NoZW1hIFRoZSBQcm9zZW1pcnJvciBzY2hlbWEgdG8gc2VhcmNoIGluXG4gKiBAcmV0dXJucyBBIHJlY29yZCBvZiB0ZXh0IHNlcmlhbGl6ZXJzIGJ5IG5vZGUgbmFtZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYShzY2hlbWE6IFNjaGVtYSk6IFJlY29yZDxzdHJpbmcsIFRleHRTZXJpYWxpemVyPiB7XG4gIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgT2JqZWN0LmVudHJpZXMoc2NoZW1hLm5vZGVzKVxuICAgICAgLmZpbHRlcigoWywgbm9kZV0pID0+IG5vZGUuc3BlYy50b1RleHQpXG4gICAgICAubWFwKChbbmFtZSwgbm9kZV0pID0+IFtuYW1lLCBub2RlLnNwZWMudG9UZXh0XSksXG4gIClcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE5vZGUsIE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4vZ2V0Tm9kZVR5cGUuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXROb2RlQXR0cmlidXRlcyhcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuICB0eXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSxcbik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBjb25zdCB0eXBlID0gZ2V0Tm9kZVR5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuICBjb25zdCB7IGZyb20sIHRvIH0gPSBzdGF0ZS5zZWxlY3Rpb25cbiAgY29uc3Qgbm9kZXM6IE5vZGVbXSA9IFtdXG5cbiAgc3RhdGUuZG9jLm5vZGVzQmV0d2Vlbihmcm9tLCB0bywgbm9kZSA9PiB7XG4gICAgbm9kZXMucHVzaChub2RlKVxuICB9KVxuXG4gIGNvbnN0IG5vZGUgPSBub2Rlcy5yZXZlcnNlKCkuZmluZChub2RlSXRlbSA9PiBub2RlSXRlbS50eXBlLm5hbWUgPT09IHR5cGUubmFtZSlcblxuICBpZiAoIW5vZGUpIHtcbiAgICByZXR1cm4ge31cbiAgfVxuXG4gIHJldHVybiB7IC4uLm5vZGUuYXR0cnMgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgTWFya1R5cGUsIE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBnZXRNYXJrQXR0cmlidXRlcyB9IGZyb20gJy4vZ2V0TWFya0F0dHJpYnV0ZXMuanMnXG5pbXBvcnQgeyBnZXROb2RlQXR0cmlidXRlcyB9IGZyb20gJy4vZ2V0Tm9kZUF0dHJpYnV0ZXMuanMnXG5pbXBvcnQgeyBnZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZSB9IGZyb20gJy4vZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUuanMnXG5cbi8qKlxuICogR2V0IG5vZGUgb3IgbWFyayBhdHRyaWJ1dGVzIGJ5IHR5cGUgb3IgbmFtZSBvbiB0aGUgY3VycmVudCBlZGl0b3Igc3RhdGVcbiAqIEBwYXJhbSBzdGF0ZSBUaGUgY3VycmVudCBlZGl0b3Igc3RhdGVcbiAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSBub2RlIG9yIG1hcmsgdHlwZSBvciBuYW1lXG4gKiBAcmV0dXJucyBUaGUgYXR0cmlidXRlcyBvZiB0aGUgbm9kZSBvciBtYXJrIG9yIGFuIGVtcHR5IG9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXR0cmlidXRlcyhcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuICB0eXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSB8IE1hcmtUeXBlLFxuKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gIGNvbnN0IHNjaGVtYVR5cGUgPSBnZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZShcbiAgICB0eXBlb2YgdHlwZU9yTmFtZSA9PT0gJ3N0cmluZycgPyB0eXBlT3JOYW1lIDogdHlwZU9yTmFtZS5uYW1lLFxuICAgIHN0YXRlLnNjaGVtYSxcbiAgKVxuXG4gIGlmIChzY2hlbWFUeXBlID09PSAnbm9kZScpIHtcbiAgICByZXR1cm4gZ2V0Tm9kZUF0dHJpYnV0ZXMoc3RhdGUsIHR5cGVPck5hbWUgYXMgTm9kZVR5cGUpXG4gIH1cblxuICBpZiAoc2NoZW1hVHlwZSA9PT0gJ21hcmsnKSB7XG4gICAgcmV0dXJuIGdldE1hcmtBdHRyaWJ1dGVzKHN0YXRlLCB0eXBlT3JOYW1lIGFzIE1hcmtUeXBlKVxuICB9XG5cbiAgcmV0dXJuIHt9XG59XG4iLCAiLyoqXG4gKiBSZW1vdmVzIGR1cGxpY2F0ZWQgdmFsdWVzIHdpdGhpbiBhbiBhcnJheS5cbiAqIFN1cHBvcnRzIG51bWJlcnMsIHN0cmluZ3MgYW5kIG9iamVjdHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVEdXBsaWNhdGVzPFQ+KGFycmF5OiBUW10sIGJ5ID0gSlNPTi5zdHJpbmdpZnkpOiBUW10ge1xuICBjb25zdCBzZWVuOiBSZWNvcmQ8YW55LCBhbnk+ID0ge31cblxuICByZXR1cm4gYXJyYXkuZmlsdGVyKGl0ZW0gPT4ge1xuICAgIGNvbnN0IGtleSA9IGJ5KGl0ZW0pXG5cbiAgICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNlZW4sIGtleSkgPyBmYWxzZSA6IChzZWVuW2tleV0gPSB0cnVlKVxuICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgU3RlcCwgVHJhbnNmb3JtIH0gZnJvbSAnQHRpcHRhcC9wbS90cmFuc2Zvcm0nXG5cbmltcG9ydCB0eXBlIHsgUmFuZ2UgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IHJlbW92ZUR1cGxpY2F0ZXMgfSBmcm9tICcuLi91dGlsaXRpZXMvcmVtb3ZlRHVwbGljYXRlcy5qcydcblxuZXhwb3J0IHR5cGUgQ2hhbmdlZFJhbmdlID0ge1xuICBvbGRSYW5nZTogUmFuZ2VcbiAgbmV3UmFuZ2U6IFJhbmdlXG59XG5cbi8qKlxuICogUmVtb3ZlcyBkdXBsaWNhdGVkIHJhbmdlcyBhbmQgcmFuZ2VzIHRoYXQgYXJlXG4gKiBmdWxseSBjYXB0dXJlZCBieSBvdGhlciByYW5nZXMuXG4gKi9cbmZ1bmN0aW9uIHNpbXBsaWZ5Q2hhbmdlZFJhbmdlcyhjaGFuZ2VzOiBDaGFuZ2VkUmFuZ2VbXSk6IENoYW5nZWRSYW5nZVtdIHtcbiAgY29uc3QgdW5pcXVlQ2hhbmdlcyA9IHJlbW92ZUR1cGxpY2F0ZXMoY2hhbmdlcylcblxuICByZXR1cm4gdW5pcXVlQ2hhbmdlcy5sZW5ndGggPT09IDFcbiAgICA/IHVuaXF1ZUNoYW5nZXNcbiAgICA6IHVuaXF1ZUNoYW5nZXMuZmlsdGVyKChjaGFuZ2UsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3QgPSB1bmlxdWVDaGFuZ2VzLmZpbHRlcigoXywgaSkgPT4gaSAhPT0gaW5kZXgpXG5cbiAgICAgICAgcmV0dXJuICFyZXN0LnNvbWUob3RoZXJDaGFuZ2UgPT4ge1xuICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBjaGFuZ2Uub2xkUmFuZ2UuZnJvbSA+PSBvdGhlckNoYW5nZS5vbGRSYW5nZS5mcm9tICYmXG4gICAgICAgICAgICBjaGFuZ2Uub2xkUmFuZ2UudG8gPD0gb3RoZXJDaGFuZ2Uub2xkUmFuZ2UudG8gJiZcbiAgICAgICAgICAgIGNoYW5nZS5uZXdSYW5nZS5mcm9tID49IG90aGVyQ2hhbmdlLm5ld1JhbmdlLmZyb20gJiZcbiAgICAgICAgICAgIGNoYW5nZS5uZXdSYW5nZS50byA8PSBvdGhlckNoYW5nZS5uZXdSYW5nZS50b1xuICAgICAgICAgIClcbiAgICAgICAgfSlcbiAgICAgIH0pXG59XG5cbi8qKlxuICogUmV0dXJucyBhIGxpc3Qgb2YgY2hhbmdlZCByYW5nZXNcbiAqIGJhc2VkIG9uIHRoZSBmaXJzdCBhbmQgbGFzdCBzdGF0ZSBvZiBhbGwgc3RlcHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGFuZ2VkUmFuZ2VzKHRyYW5zZm9ybTogVHJhbnNmb3JtKTogQ2hhbmdlZFJhbmdlW10ge1xuICBjb25zdCB7IG1hcHBpbmcsIHN0ZXBzIH0gPSB0cmFuc2Zvcm1cbiAgY29uc3QgY2hhbmdlczogQ2hhbmdlZFJhbmdlW10gPSBbXVxuXG4gIG1hcHBpbmcubWFwcy5mb3JFYWNoKChzdGVwTWFwLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IHJhbmdlczogUmFuZ2VbXSA9IFtdXG5cbiAgICAvLyBUaGlzIGFjY291bnRzIGZvciBzdGVwIGNoYW5nZXMgd2hlcmUgbm8gcmFuZ2Ugd2FzIGFjdHVhbGx5IGFsdGVyZWRcbiAgICAvLyBlLmcuIHdoZW4gc2V0dGluZyBhIG1hcmssIG5vZGUgYXR0cmlidXRlLCBldGMuXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGlmICghc3RlcE1hcC5yYW5nZXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCB7IGZyb20sIHRvIH0gPSBzdGVwc1tpbmRleF0gYXMgU3RlcCAmIHtcbiAgICAgICAgZnJvbT86IG51bWJlclxuICAgICAgICB0bz86IG51bWJlclxuICAgICAgfVxuXG4gICAgICBpZiAoZnJvbSA9PT0gdW5kZWZpbmVkIHx8IHRvID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIHJhbmdlcy5wdXNoKHsgZnJvbSwgdG8gfSlcbiAgICB9IGVsc2Uge1xuICAgICAgc3RlcE1hcC5mb3JFYWNoKChmcm9tLCB0bykgPT4ge1xuICAgICAgICByYW5nZXMucHVzaCh7IGZyb20sIHRvIH0pXG4gICAgICB9KVxuICAgIH1cblxuICAgIHJhbmdlcy5mb3JFYWNoKCh7IGZyb20sIHRvIH0pID0+IHtcbiAgICAgIGNvbnN0IG5ld1N0YXJ0ID0gbWFwcGluZy5zbGljZShpbmRleCkubWFwKGZyb20sIC0xKVxuICAgICAgY29uc3QgbmV3RW5kID0gbWFwcGluZy5zbGljZShpbmRleCkubWFwKHRvKVxuICAgICAgY29uc3Qgb2xkU3RhcnQgPSBtYXBwaW5nLmludmVydCgpLm1hcChuZXdTdGFydCwgLTEpXG4gICAgICBjb25zdCBvbGRFbmQgPSBtYXBwaW5nLmludmVydCgpLm1hcChuZXdFbmQpXG5cbiAgICAgIGNoYW5nZXMucHVzaCh7XG4gICAgICAgIG9sZFJhbmdlOiB7XG4gICAgICAgICAgZnJvbTogb2xkU3RhcnQsXG4gICAgICAgICAgdG86IG9sZEVuZCxcbiAgICAgICAgfSxcbiAgICAgICAgbmV3UmFuZ2U6IHtcbiAgICAgICAgICBmcm9tOiBuZXdTdGFydCxcbiAgICAgICAgICB0bzogbmV3RW5kLFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9KVxuICB9KVxuXG4gIHJldHVybiBzaW1wbGlmeUNoYW5nZWRSYW5nZXMoY2hhbmdlcylcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBKU09OQ29udGVudCB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5pbnRlcmZhY2UgRGVidWdKU09OQ29udGVudCBleHRlbmRzIEpTT05Db250ZW50IHtcbiAgZnJvbTogbnVtYmVyXG4gIHRvOiBudW1iZXJcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlYnVnSlNPTihub2RlOiBQcm9zZU1pcnJvck5vZGUsIHN0YXJ0T2Zmc2V0ID0gMCk6IERlYnVnSlNPTkNvbnRlbnQge1xuICBjb25zdCBpc1RvcE5vZGUgPSBub2RlLnR5cGUgPT09IG5vZGUudHlwZS5zY2hlbWEudG9wTm9kZVR5cGVcbiAgY29uc3QgaW5jcmVtZW50ID0gaXNUb3BOb2RlID8gMCA6IDFcbiAgY29uc3QgZnJvbSA9IHN0YXJ0T2Zmc2V0XG4gIGNvbnN0IHRvID0gZnJvbSArIG5vZGUubm9kZVNpemVcbiAgY29uc3QgbWFya3MgPSBub2RlLm1hcmtzLm1hcChtYXJrID0+IHtcbiAgICBjb25zdCBvdXRwdXQ6IHsgdHlwZTogc3RyaW5nOyBhdHRycz86IFJlY29yZDxzdHJpbmcsIGFueT4gfSA9IHtcbiAgICAgIHR5cGU6IG1hcmsudHlwZS5uYW1lLFxuICAgIH1cblxuICAgIGlmIChPYmplY3Qua2V5cyhtYXJrLmF0dHJzKS5sZW5ndGgpIHtcbiAgICAgIG91dHB1dC5hdHRycyA9IHsgLi4ubWFyay5hdHRycyB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dFxuICB9KVxuICBjb25zdCBhdHRycyA9IHsgLi4ubm9kZS5hdHRycyB9XG4gIGNvbnN0IG91dHB1dDogRGVidWdKU09OQ29udGVudCA9IHtcbiAgICB0eXBlOiBub2RlLnR5cGUubmFtZSxcbiAgICBmcm9tLFxuICAgIHRvLFxuICB9XG5cbiAgaWYgKE9iamVjdC5rZXlzKGF0dHJzKS5sZW5ndGgpIHtcbiAgICBvdXRwdXQuYXR0cnMgPSBhdHRyc1xuICB9XG5cbiAgaWYgKG1hcmtzLmxlbmd0aCkge1xuICAgIG91dHB1dC5tYXJrcyA9IG1hcmtzXG4gIH1cblxuICBpZiAobm9kZS5jb250ZW50LmNoaWxkQ291bnQpIHtcbiAgICBvdXRwdXQuY29udGVudCA9IFtdXG5cbiAgICBub2RlLmZvckVhY2goKGNoaWxkLCBvZmZzZXQpID0+IHtcbiAgICAgIG91dHB1dC5jb250ZW50Py5wdXNoKGdldERlYnVnSlNPTihjaGlsZCwgc3RhcnRPZmZzZXQgKyBvZmZzZXQgKyBpbmNyZW1lbnQpKVxuICAgIH0pXG4gIH1cblxuICBpZiAobm9kZS50ZXh0KSB7XG4gICAgb3V0cHV0LnRleHQgPSBub2RlLnRleHRcbiAgfVxuXG4gIHJldHVybiBvdXRwdXRcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBNYXJrUmFuZ2UgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGdldE1hcmtSYW5nZSB9IGZyb20gJy4vZ2V0TWFya1JhbmdlLmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWFya3NCZXR3ZWVuKGZyb206IG51bWJlciwgdG86IG51bWJlciwgZG9jOiBQcm9zZU1pcnJvck5vZGUpOiBNYXJrUmFuZ2VbXSB7XG4gIGNvbnN0IG1hcmtzOiBNYXJrUmFuZ2VbXSA9IFtdXG5cbiAgLy8gZ2V0IGFsbCBpbmNsdXNpdmUgbWFya3Mgb24gZW1wdHkgc2VsZWN0aW9uXG4gIGlmIChmcm9tID09PSB0bykge1xuICAgIGRvY1xuICAgICAgLnJlc29sdmUoZnJvbSlcbiAgICAgIC5tYXJrcygpXG4gICAgICAuZm9yRWFjaChtYXJrID0+IHtcbiAgICAgICAgY29uc3QgJHBvcyA9IGRvYy5yZXNvbHZlKGZyb20pXG4gICAgICAgIGNvbnN0IHJhbmdlID0gZ2V0TWFya1JhbmdlKCRwb3MsIG1hcmsudHlwZSlcblxuICAgICAgICBpZiAoIXJhbmdlKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICBtYXJrcy5wdXNoKHtcbiAgICAgICAgICBtYXJrLFxuICAgICAgICAgIC4uLnJhbmdlLFxuICAgICAgICB9KVxuICAgICAgfSlcbiAgfSBlbHNlIHtcbiAgICBkb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICBpZiAoIW5vZGUgfHwgbm9kZT8ubm9kZVNpemUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgbWFya3MucHVzaChcbiAgICAgICAgLi4ubm9kZS5tYXJrcy5tYXAobWFyayA9PiAoe1xuICAgICAgICAgIGZyb206IHBvcyxcbiAgICAgICAgICB0bzogcG9zICsgbm9kZS5ub2RlU2l6ZSxcbiAgICAgICAgICBtYXJrLFxuICAgICAgICB9KSksXG4gICAgICApXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBtYXJrc1xufVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZSwgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHR5cGUgeyBFZGl0b3JTdGF0ZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbi8qKlxuICogRmluZHMgdGhlIGZpcnN0IG5vZGUgb2YgYSBnaXZlbiB0eXBlIG9yIG5hbWUgaW4gdGhlIGN1cnJlbnQgc2VsZWN0aW9uLlxuICogQHBhcmFtIHN0YXRlIFRoZSBlZGl0b3Igc3RhdGUuXG4gKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgbm9kZSB0eXBlIG9yIG5hbWUuXG4gKiBAcGFyYW0gcG9zIFRoZSBwb3NpdGlvbiB0byBzdGFydCBzZWFyY2hpbmcgZnJvbS5cbiAqIEBwYXJhbSBtYXhEZXB0aCBUaGUgbWF4aW11bSBkZXB0aCB0byBzZWFyY2guXG4gKiBAcmV0dXJucyBUaGUgbm9kZSBhbmQgdGhlIGRlcHRoIGFzIGFuIGFycmF5LlxuICovXG5leHBvcnQgY29uc3QgZ2V0Tm9kZUF0UG9zaXRpb24gPSAoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgdHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUsXG4gIHBvczogbnVtYmVyLFxuICBtYXhEZXB0aCA9IDIwLFxuKSA9PiB7XG4gIGNvbnN0ICRwb3MgPSBzdGF0ZS5kb2MucmVzb2x2ZShwb3MpXG5cbiAgbGV0IGN1cnJlbnREZXB0aCA9IG1heERlcHRoXG4gIGxldCBub2RlOiBOb2RlIHwgbnVsbCA9IG51bGxcblxuICB3aGlsZSAoY3VycmVudERlcHRoID4gMCAmJiBub2RlID09PSBudWxsKSB7XG4gICAgY29uc3QgY3VycmVudE5vZGUgPSAkcG9zLm5vZGUoY3VycmVudERlcHRoKVxuXG4gICAgaWYgKGN1cnJlbnROb2RlPy50eXBlLm5hbWUgPT09IHR5cGVPck5hbWUpIHtcbiAgICAgIG5vZGUgPSBjdXJyZW50Tm9kZVxuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50RGVwdGggLT0gMVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBbbm9kZSwgY3VycmVudERlcHRoXSBhcyBbTm9kZSB8IG51bGwsIG51bWJlcl1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IE1hcmtUeXBlLCBOb2RlVHlwZSwgU2NoZW1hIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuLyoqXG4gKiBUcmllcyB0byBnZXQgYSBub2RlIG9yIG1hcmsgdHlwZSBieSBpdHMgbmFtZS5cbiAqIEBwYXJhbSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBub2RlIG9yIG1hcmsgdHlwZVxuICogQHBhcmFtIHNjaGVtYSBUaGUgUHJvc2VtaXJvciBzY2hlbWEgdG8gc2VhcmNoIGluXG4gKiBAcmV0dXJucyBUaGUgbm9kZSBvciBtYXJrIHR5cGUsIG9yIG51bGwgaWYgaXQgZG9lc24ndCBleGlzdFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2NoZW1hVHlwZUJ5TmFtZShuYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hKTogTm9kZVR5cGUgfCBNYXJrVHlwZSB8IG51bGwge1xuICByZXR1cm4gc2NoZW1hLm5vZGVzW25hbWVdIHx8IHNjaGVtYS5tYXJrc1tuYW1lXSB8fCBudWxsXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBFeHRlbnNpb25BdHRyaWJ1dGUgfSBmcm9tICcuLi90eXBlcy5qcydcblxuLyoqXG4gKiBSZXR1cm4gYXR0cmlidXRlcyBvZiBhbiBleHRlbnNpb24gdGhhdCBzaG91bGQgYmUgc3BsaXR0ZWQgYnkga2VlcE9uU3BsaXQgZmxhZ1xuICogQHBhcmFtIGV4dGVuc2lvbkF0dHJpYnV0ZXMgQXJyYXkgb2YgZXh0ZW5zaW9uIGF0dHJpYnV0ZXNcbiAqIEBwYXJhbSB0eXBlTmFtZSBUaGUgdHlwZSBvZiB0aGUgZXh0ZW5zaW9uXG4gKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBvZiB0aGUgZXh0ZW5zaW9uXG4gKiBAcmV0dXJucyBUaGUgc3BsaXR0ZWQgYXR0cmlidXRlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3BsaXR0ZWRBdHRyaWJ1dGVzKFxuICBleHRlbnNpb25BdHRyaWJ1dGVzOiBFeHRlbnNpb25BdHRyaWJ1dGVbXSxcbiAgdHlwZU5hbWU6IHN0cmluZyxcbiAgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55Pixcbik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgIE9iamVjdC5lbnRyaWVzKGF0dHJpYnV0ZXMpLmZpbHRlcigoW25hbWVdKSA9PiB7XG4gICAgICBjb25zdCBleHRlbnNpb25BdHRyaWJ1dGUgPSBleHRlbnNpb25BdHRyaWJ1dGVzLmZpbmQoaXRlbSA9PiB7XG4gICAgICAgIHJldHVybiBpdGVtLnR5cGUgPT09IHR5cGVOYW1lICYmIGl0ZW0ubmFtZSA9PT0gbmFtZVxuICAgICAgfSlcblxuICAgICAgaWYgKCFleHRlbnNpb25BdHRyaWJ1dGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBleHRlbnNpb25BdHRyaWJ1dGUuYXR0cmlidXRlLmtlZXBPblNwbGl0XG4gICAgfSksXG4gIClcbn1cbiIsICJpbXBvcnQgdHlwZSB7IFJlc29sdmVkUG9zIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSB0ZXh0IGNvbnRlbnQgb2YgYSByZXNvbHZlZCBwcm9zZW1pcnJvciBwb3NpdGlvblxuICogQHBhcmFtICRmcm9tIFRoZSByZXNvbHZlZCBwb3NpdGlvbiB0byBnZXQgdGhlIHRleHQgY29udGVudCBmcm9tXG4gKiBAcGFyYW0gbWF4TWF0Y2ggVGhlIG1heGltdW0gbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gbWF0Y2hcbiAqIEByZXR1cm5zIFRoZSB0ZXh0IGNvbnRlbnRcbiAqL1xuZXhwb3J0IGNvbnN0IGdldFRleHRDb250ZW50RnJvbU5vZGVzID0gKCRmcm9tOiBSZXNvbHZlZFBvcywgbWF4TWF0Y2ggPSA1MDApID0+IHtcbiAgbGV0IHRleHRCZWZvcmUgPSAnJ1xuXG4gIGNvbnN0IHNsaWNlRW5kUG9zID0gJGZyb20ucGFyZW50T2Zmc2V0XG5cbiAgJGZyb20ucGFyZW50Lm5vZGVzQmV0d2VlbihcbiAgICBNYXRoLm1heCgwLCBzbGljZUVuZFBvcyAtIG1heE1hdGNoKSxcbiAgICBzbGljZUVuZFBvcyxcbiAgICAobm9kZSwgcG9zLCBwYXJlbnQsIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBjaHVuayA9XG4gICAgICAgIG5vZGUudHlwZS5zcGVjLnRvVGV4dD8uKHtcbiAgICAgICAgICBub2RlLFxuICAgICAgICAgIHBvcyxcbiAgICAgICAgICBwYXJlbnQsXG4gICAgICAgICAgaW5kZXgsXG4gICAgICAgIH0pIHx8XG4gICAgICAgIG5vZGUudGV4dENvbnRlbnQgfHxcbiAgICAgICAgJyVsZWFmJSdcblxuICAgICAgdGV4dEJlZm9yZSArPVxuICAgICAgICBub2RlLmlzQXRvbSAmJiAhbm9kZS5pc1RleHQgPyBjaHVuayA6IGNodW5rLnNsaWNlKDAsIE1hdGgubWF4KDAsIHNsaWNlRW5kUG9zIC0gcG9zKSlcbiAgICB9LFxuICApXG5cbiAgcmV0dXJuIHRleHRCZWZvcmVcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE1hcmtUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgdHlwZSB7IE1hcmtSYW5nZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgb2JqZWN0SW5jbHVkZXMgfSBmcm9tICcuLi91dGlsaXRpZXMvb2JqZWN0SW5jbHVkZXMuanMnXG5pbXBvcnQgeyBnZXRNYXJrVHlwZSB9IGZyb20gJy4vZ2V0TWFya1R5cGUuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBpc01hcmtBY3RpdmUoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgdHlwZU9yTmFtZTogTWFya1R5cGUgfCBzdHJpbmcgfCBudWxsLFxuICBhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge30sXG4pOiBib29sZWFuIHtcbiAgY29uc3QgeyBlbXB0eSwgcmFuZ2VzIH0gPSBzdGF0ZS5zZWxlY3Rpb25cbiAgY29uc3QgdHlwZSA9IHR5cGVPck5hbWUgPyBnZXRNYXJrVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpIDogbnVsbFxuXG4gIGlmIChlbXB0eSkge1xuICAgIHJldHVybiAhIShzdGF0ZS5zdG9yZWRNYXJrcyB8fCBzdGF0ZS5zZWxlY3Rpb24uJGZyb20ubWFya3MoKSlcbiAgICAgIC5maWx0ZXIobWFyayA9PiB7XG4gICAgICAgIGlmICghdHlwZSkge1xuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHlwZS5uYW1lID09PSBtYXJrLnR5cGUubmFtZVxuICAgICAgfSlcbiAgICAgIC5maW5kKG1hcmsgPT4gb2JqZWN0SW5jbHVkZXMobWFyay5hdHRycywgYXR0cmlidXRlcywgeyBzdHJpY3Q6IGZhbHNlIH0pKVxuICB9XG5cbiAgbGV0IHNlbGVjdGlvblJhbmdlID0gMFxuICBjb25zdCBtYXJrUmFuZ2VzOiBNYXJrUmFuZ2VbXSA9IFtdXG5cbiAgcmFuZ2VzLmZvckVhY2goKHsgJGZyb20sICR0byB9KSA9PiB7XG4gICAgY29uc3QgZnJvbSA9ICRmcm9tLnBvc1xuICAgIGNvbnN0IHRvID0gJHRvLnBvc1xuXG4gICAgc3RhdGUuZG9jLm5vZGVzQmV0d2Vlbihmcm9tLCB0bywgKG5vZGUsIHBvcykgPT4ge1xuICAgICAgLy8gaWdub3JlIHNlbGVjdGVkIHRleHQgaW5zaWRlIG5vZGVzIHdob3NlIHNjaGVtYSBkaXNhbGxvd3MgdGhpcyBtYXJrIHR5cGVcbiAgICAgIGlmICh0eXBlICYmIG5vZGUuaW5saW5lQ29udGVudCAmJiAhbm9kZS50eXBlLmFsbG93c01hcmtUeXBlKHR5cGUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuXG4gICAgICBpZiAoIW5vZGUuaXNUZXh0ICYmICFub2RlLm1hcmtzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVsYXRpdmVGcm9tID0gTWF0aC5tYXgoZnJvbSwgcG9zKVxuICAgICAgY29uc3QgcmVsYXRpdmVUbyA9IE1hdGgubWluKHRvLCBwb3MgKyBub2RlLm5vZGVTaXplKVxuICAgICAgY29uc3QgcmFuZ2UgPSByZWxhdGl2ZVRvIC0gcmVsYXRpdmVGcm9tXG5cbiAgICAgIHNlbGVjdGlvblJhbmdlICs9IHJhbmdlXG5cbiAgICAgIG1hcmtSYW5nZXMucHVzaChcbiAgICAgICAgLi4ubm9kZS5tYXJrcy5tYXAobWFyayA9PiAoe1xuICAgICAgICAgIG1hcmssXG4gICAgICAgICAgZnJvbTogcmVsYXRpdmVGcm9tLFxuICAgICAgICAgIHRvOiByZWxhdGl2ZVRvLFxuICAgICAgICB9KSksXG4gICAgICApXG4gICAgfSlcbiAgfSlcblxuICBpZiAoc2VsZWN0aW9uUmFuZ2UgPT09IDApIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIGNhbGN1bGF0ZSByYW5nZSBvZiBtYXRjaGVkIG1hcmtcbiAgY29uc3QgbWF0Y2hlZFJhbmdlID0gbWFya1Jhbmdlc1xuICAgIC5maWx0ZXIobWFya1JhbmdlID0+IHtcbiAgICAgIGlmICghdHlwZSkge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHlwZS5uYW1lID09PSBtYXJrUmFuZ2UubWFyay50eXBlLm5hbWVcbiAgICB9KVxuICAgIC5maWx0ZXIobWFya1JhbmdlID0+IG9iamVjdEluY2x1ZGVzKG1hcmtSYW5nZS5tYXJrLmF0dHJzLCBhdHRyaWJ1dGVzLCB7IHN0cmljdDogZmFsc2UgfSkpXG4gICAgLnJlZHVjZSgoc3VtLCBtYXJrUmFuZ2UpID0+IHN1bSArIG1hcmtSYW5nZS50byAtIG1hcmtSYW5nZS5mcm9tLCAwKVxuXG4gIC8vIGNhbGN1bGF0ZSByYW5nZSBvZiBtYXJrcyB0aGF0IGV4Y2x1ZGVzIHRoZSBzZWFyY2hlZCBtYXJrXG4gIC8vIGZvciBleGFtcGxlIGBjb2RlYCBkb2VzbuKAmXQgYWxsb3cgYW55IG90aGVyIG1hcmtzXG4gIGNvbnN0IGV4Y2x1ZGVkUmFuZ2UgPSBtYXJrUmFuZ2VzXG4gICAgLmZpbHRlcihtYXJrUmFuZ2UgPT4ge1xuICAgICAgaWYgKCF0eXBlKSB7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBtYXJrUmFuZ2UubWFyay50eXBlICE9PSB0eXBlICYmIG1hcmtSYW5nZS5tYXJrLnR5cGUuZXhjbHVkZXModHlwZSlcbiAgICB9KVxuICAgIC5yZWR1Y2UoKHN1bSwgbWFya1JhbmdlKSA9PiBzdW0gKyBtYXJrUmFuZ2UudG8gLSBtYXJrUmFuZ2UuZnJvbSwgMClcblxuICAvLyB3ZSBvbmx5IGluY2x1ZGUgdGhlIHJlc3VsdCBvZiBgZXhjbHVkZWRSYW5nZWBcbiAgLy8gaWYgdGhlcmUgaXMgYSBtYXRjaCBhdCBhbGxcbiAgY29uc3QgcmFuZ2UgPSBtYXRjaGVkUmFuZ2UgPiAwID8gbWF0Y2hlZFJhbmdlICsgZXhjbHVkZWRSYW5nZSA6IG1hdGNoZWRSYW5nZVxuXG4gIHJldHVybiByYW5nZSA+PSBzZWxlY3Rpb25SYW5nZVxufVxuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBnZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZSB9IGZyb20gJy4vZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUuanMnXG5pbXBvcnQgeyBpc01hcmtBY3RpdmUgfSBmcm9tICcuL2lzTWFya0FjdGl2ZS5qcydcbmltcG9ydCB7IGlzTm9kZUFjdGl2ZSB9IGZyb20gJy4vaXNOb2RlQWN0aXZlLmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gaXNBY3RpdmUoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgbmFtZTogc3RyaW5nIHwgbnVsbCxcbiAgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9LFxuKTogYm9vbGVhbiB7XG4gIGlmICghbmFtZSkge1xuICAgIHJldHVybiBpc05vZGVBY3RpdmUoc3RhdGUsIG51bGwsIGF0dHJpYnV0ZXMpIHx8IGlzTWFya0FjdGl2ZShzdGF0ZSwgbnVsbCwgYXR0cmlidXRlcylcbiAgfVxuXG4gIGNvbnN0IHNjaGVtYVR5cGUgPSBnZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZShuYW1lLCBzdGF0ZS5zY2hlbWEpXG5cbiAgaWYgKHNjaGVtYVR5cGUgPT09ICdub2RlJykge1xuICAgIHJldHVybiBpc05vZGVBY3RpdmUoc3RhdGUsIG5hbWUsIGF0dHJpYnV0ZXMpXG4gIH1cblxuICBpZiAoc2NoZW1hVHlwZSA9PT0gJ21hcmsnKSB7XG4gICAgcmV0dXJuIGlzTWFya0FjdGl2ZShzdGF0ZSwgbmFtZSwgYXR0cmlidXRlcylcbiAgfVxuXG4gIHJldHVybiBmYWxzZVxufVxuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBmaW5kUGFyZW50Tm9kZSB9IGZyb20gJy4vZmluZFBhcmVudE5vZGUuanMnXG5cbmV4cG9ydCBjb25zdCBpc0F0RW5kT2ZOb2RlID0gKHN0YXRlOiBFZGl0b3JTdGF0ZSwgbm9kZVR5cGU/OiBzdHJpbmcpID0+IHtcbiAgY29uc3QgeyAkZnJvbSwgJHRvLCAkYW5jaG9yIH0gPSBzdGF0ZS5zZWxlY3Rpb25cblxuICBpZiAobm9kZVR5cGUpIHtcbiAgICBjb25zdCBwYXJlbnROb2RlID0gZmluZFBhcmVudE5vZGUobm9kZSA9PiBub2RlLnR5cGUubmFtZSA9PT0gbm9kZVR5cGUpKHN0YXRlLnNlbGVjdGlvbilcblxuICAgIGlmICghcGFyZW50Tm9kZSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgY29uc3QgJHBhcmVudFBvcyA9IHN0YXRlLmRvYy5yZXNvbHZlKHBhcmVudE5vZGUucG9zICsgMSlcblxuICAgIGlmICgkYW5jaG9yLnBvcyArIDEgPT09ICRwYXJlbnRQb3MuZW5kKCkpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAoJHRvLnBhcmVudE9mZnNldCA8ICR0by5wYXJlbnQubm9kZVNpemUgLSAyIHx8ICRmcm9tLnBvcyAhPT0gJHRvLnBvcykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEVkaXRvclN0YXRlIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuZXhwb3J0IGNvbnN0IGlzQXRTdGFydE9mTm9kZSA9IChzdGF0ZTogRWRpdG9yU3RhdGUpID0+IHtcbiAgY29uc3QgeyAkZnJvbSwgJHRvIH0gPSBzdGF0ZS5zZWxlY3Rpb25cblxuICBpZiAoJGZyb20ucGFyZW50T2Zmc2V0ID4gMCB8fCAkZnJvbS5wb3MgIT09ICR0by5wb3MpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBBbnlFeHRlbnNpb24sIEVuYWJsZVJ1bGVzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0V4dGVuc2lvblJ1bGVzRW5hYmxlZChleHRlbnNpb246IEFueUV4dGVuc2lvbiwgZW5hYmxlZDogRW5hYmxlUnVsZXMpOiBib29sZWFuIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoZW5hYmxlZCkpIHtcbiAgICByZXR1cm4gZW5hYmxlZC5zb21lKGVuYWJsZWRFeHRlbnNpb24gPT4ge1xuICAgICAgY29uc3QgbmFtZSA9IHR5cGVvZiBlbmFibGVkRXh0ZW5zaW9uID09PSAnc3RyaW5nJyA/IGVuYWJsZWRFeHRlbnNpb24gOiBlbmFibGVkRXh0ZW5zaW9uLm5hbWVcblxuICAgICAgcmV0dXJuIG5hbWUgPT09IGV4dGVuc2lvbi5uYW1lXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBlbmFibGVkXG59XG4iLCAiaW1wb3J0IHsgZ2V0RXh0ZW5zaW9uRmllbGQgfSBmcm9tICcuLi9oZWxwZXJzL2dldEV4dGVuc2lvbkZpZWxkLmpzJ1xuaW1wb3J0IHR5cGUgeyBOb2RlQ29uZmlnIH0gZnJvbSAnLi4vaW5kZXguanMnXG5pbXBvcnQgdHlwZSB7IEV4dGVuc2lvbnMgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGNhbGxPclJldHVybiB9IGZyb20gJy4uL3V0aWxpdGllcy9jYWxsT3JSZXR1cm4uanMnXG5pbXBvcnQgeyBzcGxpdEV4dGVuc2lvbnMgfSBmcm9tICcuL3NwbGl0RXh0ZW5zaW9ucy5qcydcblxuZXhwb3J0IGZ1bmN0aW9uIGlzTGlzdChuYW1lOiBzdHJpbmcsIGV4dGVuc2lvbnM6IEV4dGVuc2lvbnMpOiBib29sZWFuIHtcbiAgY29uc3QgeyBub2RlRXh0ZW5zaW9ucyB9ID0gc3BsaXRFeHRlbnNpb25zKGV4dGVuc2lvbnMpXG4gIGNvbnN0IGV4dGVuc2lvbiA9IG5vZGVFeHRlbnNpb25zLmZpbmQoaXRlbSA9PiBpdGVtLm5hbWUgPT09IG5hbWUpXG5cbiAgaWYgKCFleHRlbnNpb24pIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgb3B0aW9uczogZXh0ZW5zaW9uLm9wdGlvbnMsXG4gICAgc3RvcmFnZTogZXh0ZW5zaW9uLnN0b3JhZ2UsXG4gIH1cbiAgY29uc3QgZ3JvdXAgPSBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snZ3JvdXAnXT4oZXh0ZW5zaW9uLCAnZ3JvdXAnLCBjb250ZXh0KSlcblxuICBpZiAodHlwZW9mIGdyb3VwICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIGdyb3VwLnNwbGl0KCcgJykuaW5jbHVkZXMoJ2xpc3QnKVxufVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gcHJvc2VtaXJyb3Igbm9kZSBpcyBlbXB0eS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzTm9kZUVtcHR5KFxuICBub2RlOiBQcm9zZU1pcnJvck5vZGUsXG4gIHtcbiAgICBjaGVja0NoaWxkcmVuID0gdHJ1ZSxcbiAgICBpZ25vcmVXaGl0ZXNwYWNlID0gZmFsc2UsXG4gIH06IHtcbiAgICAvKipcbiAgICAgKiBXaGVuIHRydWUgKGRlZmF1bHQpLCBpdCB3aWxsIGFsc28gY2hlY2sgaWYgYWxsIGNoaWxkcmVuIGFyZSBlbXB0eS5cbiAgICAgKi9cbiAgICBjaGVja0NoaWxkcmVuPzogYm9vbGVhblxuICAgIC8qKlxuICAgICAqIFdoZW4gdHJ1ZSwgaXQgd2lsbCBpZ25vcmUgd2hpdGVzcGFjZSB3aGVuIGNoZWNraW5nIGZvciBlbXB0aW5lc3MuXG4gICAgICovXG4gICAgaWdub3JlV2hpdGVzcGFjZT86IGJvb2xlYW5cbiAgfSA9IHt9LFxuKTogYm9vbGVhbiB7XG4gIGlmIChpZ25vcmVXaGl0ZXNwYWNlKSB7XG4gICAgaWYgKG5vZGUudHlwZS5uYW1lID09PSAnaGFyZEJyZWFrJykge1xuICAgICAgLy8gSGFyZCBicmVha3MgYXJlIGNvbnNpZGVyZWQgZW1wdHlcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICAgIGlmIChub2RlLmlzVGV4dCkge1xuICAgICAgcmV0dXJuICEvXFxTLy50ZXN0KG5vZGUudGV4dCA/PyAnJylcbiAgICB9XG4gIH1cblxuICBpZiAobm9kZS5pc1RleHQpIHtcbiAgICByZXR1cm4gIW5vZGUudGV4dFxuICB9XG5cbiAgaWYgKG5vZGUuaXNBdG9tIHx8IG5vZGUuaXNMZWFmKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAobm9kZS5jb250ZW50LmNoaWxkQ291bnQgPT09IDApIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgaWYgKGNoZWNrQ2hpbGRyZW4pIHtcbiAgICBsZXQgaXNDb250ZW50RW1wdHkgPSB0cnVlXG5cbiAgICBub2RlLmNvbnRlbnQuZm9yRWFjaChjaGlsZE5vZGUgPT4ge1xuICAgICAgaWYgKGlzQ29udGVudEVtcHR5ID09PSBmYWxzZSkge1xuICAgICAgICAvLyBFeGl0IGVhcmx5IGZvciBwZXJmXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAoIWlzTm9kZUVtcHR5KGNoaWxkTm9kZSwgeyBpZ25vcmVXaGl0ZXNwYWNlLCBjaGVja0NoaWxkcmVuIH0pKSB7XG4gICAgICAgIGlzQ29udGVudEVtcHR5ID0gZmFsc2VcbiAgICAgIH1cbiAgICB9KVxuXG4gICAgcmV0dXJuIGlzQ29udGVudEVtcHR5XG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cbiIsICJpbXBvcnQgeyBOb2RlU2VsZWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuZXhwb3J0IGZ1bmN0aW9uIGlzTm9kZVNlbGVjdGlvbih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIE5vZGVTZWxlY3Rpb24ge1xuICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBpc1RleHRTZWxlY3Rpb24gfSBmcm9tICcuL2lzVGV4dFNlbGVjdGlvbi5qcydcblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSBub2RlIHZpZXcgc2hvdWxkIGJlIGNvbnNpZGVyZWQgc2VsZWN0ZWQgZm9yIHRoZSBnaXZlblxuICogZWRpdG9yIHNlbGVjdGlvbi5cbiAqXG4gKiBBIG5vZGUgaXMgY29uc2lkZXJlZCBzZWxlY3RlZCB3aGVuIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBmdWxseSBjb3ZlcnMgaXRcbiAqIChlLmcuIGEgYE5vZGVTZWxlY3Rpb25gKS4gV2hlbiBgc2VsZWN0ZWRPblRleHRTZWxlY3Rpb25gIGlzIGVuYWJsZWQsIHRoZVxuICogbm9kZSBpcyBhZGRpdGlvbmFsbHkgY29uc2lkZXJlZCBzZWxlY3RlZCBpZiBhIGBUZXh0U2VsZWN0aW9uYCBpcyBmdWxseVxuICogY29udGFpbmVkIHdpdGhpbiB0aGUgbm9kZSdzIHJhbmdlLlxuICpcbiAqIEBwYXJhbSBzZWxlY3Rpb24gVGhlIGN1cnJlbnQgZWRpdG9yIHNlbGVjdGlvbi5cbiAqIEBwYXJhbSBwb3MgVGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSBub2RlIGluIHRoZSBkb2N1bWVudC5cbiAqIEBwYXJhbSBub2RlU2l6ZSBUaGUgc2l6ZSBvZiB0aGUgbm9kZS5cbiAqIEBwYXJhbSBzZWxlY3RlZE9uVGV4dFNlbGVjdGlvbiBXaGVuIGB0cnVlYCwgYWxzbyB0cmVhdCBzZWxlY3Rpb25zIGluc2lkZSB0aGUgbm9kZSBhcyBzZWxlY3RlZC5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgbm9kZSB2aWV3IHNob3VsZCByZW5kZXIgYXMgc2VsZWN0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc05vZGVWaWV3U2VsZWN0ZWQoe1xuICBzZWxlY3Rpb24sXG4gIHBvcyxcbiAgbm9kZVNpemUsXG4gIHNlbGVjdGVkT25UZXh0U2VsZWN0aW9uID0gZmFsc2UsXG59OiB7XG4gIHNlbGVjdGlvbjogU2VsZWN0aW9uXG4gIHBvczogbnVtYmVyXG4gIG5vZGVTaXplOiBudW1iZXJcbiAgc2VsZWN0ZWRPblRleHRTZWxlY3Rpb24/OiBib29sZWFuXG59KTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgZnJvbSwgdG8gfSA9IHNlbGVjdGlvblxuXG4gIGlmIChmcm9tIDw9IHBvcyAmJiB0byA+PSBwb3MgKyBub2RlU2l6ZSkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBpZiAoc2VsZWN0ZWRPblRleHRTZWxlY3Rpb24gJiYgaXNUZXh0U2VsZWN0aW9uKHNlbGVjdGlvbikgJiYgZnJvbSA+IHBvcyAmJiB0byA8IHBvcyArIG5vZGVTaXplKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIHJldHVybiBmYWxzZVxufVxuIiwgImltcG9ydCB0eXBlIHsgVHJhbnNhY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHR5cGUgeyBNYXBSZXN1bHQgfSBmcm9tICdAdGlwdGFwL3BtL3RyYW5zZm9ybSdcblxuLyoqXG4gKiBBIGNsYXNzIHRoYXQgcmVwcmVzZW50cyBhIG1hcHBhYmxlIHBvc2l0aW9uIGluIHRoZSBlZGl0b3IuIEl0IGNhbiBiZSBleHRlbmRlZFxuICogYnkgb3RoZXIgZXh0ZW5zaW9ucyB0byBhZGQgYWRkaXRpb25hbCBwb3NpdGlvbiBtYXBwaW5nIGNhcGFiaWxpdGllcy5cbiAqL1xuZXhwb3J0IGNsYXNzIE1hcHBhYmxlUG9zaXRpb24ge1xuICAvKipcbiAgICogVGhlIGFic29sdXRlIHBvc2l0aW9uIGluIHRoZSBlZGl0b3IuXG4gICAqL1xuICBwdWJsaWMgcG9zaXRpb246IG51bWJlclxuXG4gIGNvbnN0cnVjdG9yKHBvc2l0aW9uOiBudW1iZXIpIHtcbiAgICB0aGlzLnBvc2l0aW9uID0gcG9zaXRpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgTWFwcGFibGVQb3NpdGlvbiBmcm9tIGEgSlNPTiBvYmplY3QuXG4gICAqL1xuICBzdGF0aWMgZnJvbUpTT04oanNvbjogYW55KTogTWFwcGFibGVQb3NpdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBNYXBwYWJsZVBvc2l0aW9uKGpzb24ucG9zaXRpb24pXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIE1hcHBhYmxlUG9zaXRpb24gdG8gYSBKU09OIG9iamVjdC5cbiAgICovXG4gIHRvSlNPTigpOiBhbnkge1xuICAgIHJldHVybiB7XG4gICAgICBwb3NpdGlvbjogdGhpcy5wb3NpdGlvbixcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBUaGUgcmVzdWx0IG9mIHRoZSBnZXRVcGRhdGVkUG9zaXRpb24gZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR2V0VXBkYXRlZFBvc2l0aW9uUmVzdWx0IHtcbiAgcG9zaXRpb246IE1hcHBhYmxlUG9zaXRpb25cbiAgbWFwUmVzdWx0OiBNYXBSZXN1bHQgfCBudWxsXG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgbmV3IHBvc2l0aW9uIGFmdGVyIGFwcGx5aW5nIGEgdHJhbnNhY3Rpb24uXG4gKlxuICogQHJldHVybnMgVGhlIG5ldyBtYXBwYWJsZSBwb3NpdGlvbiBhbmQgdGhlIG1hcCByZXN1bHQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRVcGRhdGVkUG9zaXRpb24oXG4gIHBvc2l0aW9uOiBNYXBwYWJsZVBvc2l0aW9uLFxuICB0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24sXG4pOiBHZXRVcGRhdGVkUG9zaXRpb25SZXN1bHQge1xuICBjb25zdCBtYXBSZXN1bHQgPSB0cmFuc2FjdGlvbi5tYXBwaW5nLm1hcFJlc3VsdChwb3NpdGlvbi5wb3NpdGlvbilcbiAgcmV0dXJuIHtcbiAgICBwb3NpdGlvbjogbmV3IE1hcHBhYmxlUG9zaXRpb24obWFwUmVzdWx0LnBvcyksXG4gICAgbWFwUmVzdWx0LFxuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIE1hcHBhYmxlUG9zaXRpb24gZnJvbSBhIHBvc2l0aW9uIG51bWJlci4gVGhpcyBpcyB0aGUgZGVmYXVsdFxuICogaW1wbGVtZW50YXRpb24gZm9yIFRpcHRhcCBjb3JlLiBJdCBjYW4gYmUgb3ZlcnJpZGRlbiBieSBvdGhlciBUaXB0YXBcbiAqIGV4dGVuc2lvbnMuXG4gKlxuICogQHBhcmFtIHBvc2l0aW9uIFRoZSBwb3NpdGlvbiAoYXMgYSBudW1iZXIpIHdoZXJlIHRoZSBNYXBwYWJsZVBvc2l0aW9uIHdpbGwgYmUgY3JlYXRlZC5cbiAqIEByZXR1cm5zIEEgbmV3IE1hcHBhYmxlUG9zaXRpb24gaW5zdGFuY2UgYXQgdGhlIGdpdmVuIHBvc2l0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWFwcGFibGVQb3NpdGlvbihwb3NpdGlvbjogbnVtYmVyKTogTWFwcGFibGVQb3NpdGlvbiB7XG4gIHJldHVybiBuZXcgTWFwcGFibGVQb3NpdGlvbihwb3NpdGlvbilcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEVkaXRvclZpZXcgfSBmcm9tICdAdGlwdGFwL3BtL3ZpZXcnXG5cbmltcG9ydCB7IG1pbk1heCB9IGZyb20gJy4uL3V0aWxpdGllcy9taW5NYXguanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBwb3NUb0RPTVJlY3QodmlldzogRWRpdG9yVmlldywgZnJvbTogbnVtYmVyLCB0bzogbnVtYmVyKTogRE9NUmVjdCB7XG4gIGNvbnN0IG1pblBvcyA9IDBcbiAgY29uc3QgbWF4UG9zID0gdmlldy5zdGF0ZS5kb2MuY29udGVudC5zaXplXG4gIGNvbnN0IHJlc29sdmVkRnJvbSA9IG1pbk1heChmcm9tLCBtaW5Qb3MsIG1heFBvcylcbiAgY29uc3QgcmVzb2x2ZWRFbmQgPSBtaW5NYXgodG8sIG1pblBvcywgbWF4UG9zKVxuICBjb25zdCBzdGFydCA9IHZpZXcuY29vcmRzQXRQb3MocmVzb2x2ZWRGcm9tKVxuICBjb25zdCBlbmQgPSB2aWV3LmNvb3Jkc0F0UG9zKHJlc29sdmVkRW5kLCAtMSlcbiAgY29uc3QgdG9wID0gTWF0aC5taW4oc3RhcnQudG9wLCBlbmQudG9wKVxuICBjb25zdCBib3R0b20gPSBNYXRoLm1heChzdGFydC5ib3R0b20sIGVuZC5ib3R0b20pXG4gIGNvbnN0IGxlZnQgPSBNYXRoLm1pbihzdGFydC5sZWZ0LCBlbmQubGVmdClcbiAgY29uc3QgcmlnaHQgPSBNYXRoLm1heChzdGFydC5yaWdodCwgZW5kLnJpZ2h0KVxuICBjb25zdCB3aWR0aCA9IHJpZ2h0IC0gbGVmdFxuICBjb25zdCBoZWlnaHQgPSBib3R0b20gLSB0b3BcbiAgY29uc3QgeCA9IGxlZnRcbiAgY29uc3QgeSA9IHRvcFxuICBjb25zdCBkYXRhID0ge1xuICAgIHRvcCxcbiAgICBib3R0b20sXG4gICAgbGVmdCxcbiAgICByaWdodCxcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gICAgeCxcbiAgICB5LFxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5kYXRhLFxuICAgIHRvSlNPTjogKCkgPT4gZGF0YSxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgU2NoZW1hIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBKU09OQ29udGVudCB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG50eXBlIFJld3JpdGVVbmtub3duQ29udGVudE9wdGlvbnMgPSB7XG4gIC8qKlxuICAgKiBJZiB0cnVlLCB1bmtub3duIG5vZGVzIHdpbGwgYmUgdHJlYXRlZCBhcyBwYXJhZ3JhcGhzXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIGZhbGxiYWNrVG9QYXJhZ3JhcGg/OiBib29sZWFuXG59XG5cbnR5cGUgUmV3cml0dGVuQ29udGVudCA9IHtcbiAgLyoqXG4gICAqIFRoZSBvcmlnaW5hbCBKU09OIGNvbnRlbnQgdGhhdCB3YXMgcmV3cml0dGVuXG4gICAqL1xuICBvcmlnaW5hbDogSlNPTkNvbnRlbnRcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBub2RlIG9yIG1hcmsgdGhhdCB3YXMgdW5zdXBwb3J0ZWRcbiAgICovXG4gIHVuc3VwcG9ydGVkOiBzdHJpbmdcbn1bXVxuXG4vKipcbiAqIFRoZSBhY3R1YWwgaW1wbGVtZW50YXRpb24gb2YgdGhlIHJld3JpdGVVbmtub3duQ29udGVudCBmdW5jdGlvblxuICovXG5mdW5jdGlvbiByZXdyaXRlVW5rbm93bkNvbnRlbnRJbm5lcih7XG4gIGpzb24sXG4gIHZhbGlkTWFya3MsXG4gIHZhbGlkTm9kZXMsXG4gIG9wdGlvbnMsXG4gIHJld3JpdHRlbkNvbnRlbnQgPSBbXSxcbn06IHtcbiAganNvbjogSlNPTkNvbnRlbnRcbiAgdmFsaWRNYXJrczogU2V0PHN0cmluZz5cbiAgdmFsaWROb2RlczogU2V0PHN0cmluZz5cbiAgb3B0aW9ucz86IFJld3JpdGVVbmtub3duQ29udGVudE9wdGlvbnNcbiAgcmV3cml0dGVuQ29udGVudD86IFJld3JpdHRlbkNvbnRlbnRcbn0pOiB7XG4gIC8qKlxuICAgKiBUaGUgY2xlYW5lZCBKU09OIGNvbnRlbnRcbiAgICovXG4gIGpzb246IEpTT05Db250ZW50IHwgbnVsbFxuICAvKipcbiAgICogVGhlIGFycmF5IG9mIG5vZGVzIGFuZCBtYXJrcyB0aGF0IHdlcmUgcmV3cml0dGVuXG4gICAqL1xuICByZXdyaXR0ZW5Db250ZW50OiBSZXdyaXR0ZW5Db250ZW50XG59IHtcbiAgaWYgKGpzb24ubWFya3MgJiYgQXJyYXkuaXNBcnJheShqc29uLm1hcmtzKSkge1xuICAgIGpzb24ubWFya3MgPSBqc29uLm1hcmtzLmZpbHRlcihtYXJrID0+IHtcbiAgICAgIGNvbnN0IG5hbWUgPSB0eXBlb2YgbWFyayA9PT0gJ3N0cmluZycgPyBtYXJrIDogbWFyay50eXBlXG5cbiAgICAgIGlmICh2YWxpZE1hcmtzLmhhcyhuYW1lKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuXG4gICAgICByZXdyaXR0ZW5Db250ZW50LnB1c2goe1xuICAgICAgICBvcmlnaW5hbDogSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShtYXJrKSksXG4gICAgICAgIHVuc3VwcG9ydGVkOiBuYW1lLFxuICAgICAgfSlcbiAgICAgIC8vIEp1c3QgaWdub3JlIGFueSB1bmtub3duIG1hcmtzXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9KVxuICB9XG5cbiAgaWYgKGpzb24uY29udGVudCAmJiBBcnJheS5pc0FycmF5KGpzb24uY29udGVudCkpIHtcbiAgICBqc29uLmNvbnRlbnQgPSBqc29uLmNvbnRlbnRcbiAgICAgIC5tYXAoXG4gICAgICAgIHZhbHVlID0+XG4gICAgICAgICAgcmV3cml0ZVVua25vd25Db250ZW50SW5uZXIoe1xuICAgICAgICAgICAganNvbjogdmFsdWUsXG4gICAgICAgICAgICB2YWxpZE1hcmtzLFxuICAgICAgICAgICAgdmFsaWROb2RlcyxcbiAgICAgICAgICAgIG9wdGlvbnMsXG4gICAgICAgICAgICByZXdyaXR0ZW5Db250ZW50LFxuICAgICAgICAgIH0pLmpzb24sXG4gICAgICApXG4gICAgICAuZmlsdGVyKGEgPT4gYSAhPT0gbnVsbCAmJiBhICE9PSB1bmRlZmluZWQpXG4gIH1cblxuICBpZiAoanNvbi50eXBlICYmICF2YWxpZE5vZGVzLmhhcyhqc29uLnR5cGUpKSB7XG4gICAgcmV3cml0dGVuQ29udGVudC5wdXNoKHtcbiAgICAgIG9yaWdpbmFsOiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGpzb24pKSxcbiAgICAgIHVuc3VwcG9ydGVkOiBqc29uLnR5cGUsXG4gICAgfSlcblxuICAgIGlmIChqc29uLmNvbnRlbnQgJiYgQXJyYXkuaXNBcnJheShqc29uLmNvbnRlbnQpICYmIG9wdGlvbnM/LmZhbGxiYWNrVG9QYXJhZ3JhcGggIT09IGZhbHNlKSB7XG4gICAgICAvLyBKdXN0IHRyZWF0IGl0IGxpa2UgYSBwYXJhZ3JhcGggYW5kIGhvcGUgZm9yIHRoZSBiZXN0XG4gICAgICBqc29uLnR5cGUgPSAncGFyYWdyYXBoJ1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBqc29uLFxuICAgICAgICByZXdyaXR0ZW5Db250ZW50LFxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIG9yIGp1c3Qgb21pdCBpdCBlbnRpcmVseVxuICAgIHJldHVybiB7XG4gICAgICBqc29uOiBudWxsLFxuICAgICAgcmV3cml0dGVuQ29udGVudCxcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBqc29uLCByZXdyaXR0ZW5Db250ZW50IH1cbn1cblxuLyoqXG4gKiBSZXdyaXRlIHVua25vd24gbm9kZXMgYW5kIG1hcmtzIHdpdGhpbiBKU09OIGNvbnRlbnRcbiAqIEFsbG93aW5nIGZvciB1c2VyIHdpdGhpbiB0aGUgZWRpdG9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXdyaXRlVW5rbm93bkNvbnRlbnQoXG4gIC8qKlxuICAgKiBUaGUgSlNPTiBjb250ZW50IHRvIGNsZWFuIG9mIHVua25vd24gbm9kZXMgYW5kIG1hcmtzXG4gICAqL1xuICBqc29uOiBKU09OQ29udGVudCxcbiAgLyoqXG4gICAqIFRoZSBzY2hlbWEgdG8gdXNlIGZvciB2YWxpZGF0aW9uXG4gICAqL1xuICBzY2hlbWE6IFNjaGVtYSxcbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIHRoZSBjbGVhbmluZyBwcm9jZXNzXG4gICAqL1xuICBvcHRpb25zPzogUmV3cml0ZVVua25vd25Db250ZW50T3B0aW9ucyxcbik6IHtcbiAgLyoqXG4gICAqIFRoZSBjbGVhbmVkIEpTT04gY29udGVudFxuICAgKi9cbiAganNvbjogSlNPTkNvbnRlbnQgfCBudWxsXG4gIC8qKlxuICAgKiBUaGUgYXJyYXkgb2Ygbm9kZXMgYW5kIG1hcmtzIHRoYXQgd2VyZSByZXdyaXR0ZW5cbiAgICovXG4gIHJld3JpdHRlbkNvbnRlbnQ6IHtcbiAgICAvKipcbiAgICAgKiBUaGUgb3JpZ2luYWwgSlNPTiBjb250ZW50IHRoYXQgd2FzIHJld3JpdHRlblxuICAgICAqL1xuICAgIG9yaWdpbmFsOiBKU09OQ29udGVudFxuICAgIC8qKlxuICAgICAqIFRoZSBuYW1lIG9mIHRoZSBub2RlIG9yIG1hcmsgdGhhdCB3YXMgdW5zdXBwb3J0ZWRcbiAgICAgKi9cbiAgICB1bnN1cHBvcnRlZDogc3RyaW5nXG4gIH1bXVxufSB7XG4gIHJldHVybiByZXdyaXRlVW5rbm93bkNvbnRlbnRJbm5lcih7XG4gICAganNvbixcbiAgICB2YWxpZE5vZGVzOiBuZXcgU2V0KE9iamVjdC5rZXlzKHNjaGVtYS5ub2RlcykpLFxuICAgIHZhbGlkTWFya3M6IG5ldyBTZXQoT2JqZWN0LmtleXMoc2NoZW1hLm1hcmtzKSksXG4gICAgb3B0aW9ucyxcbiAgfSlcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE1hcmtUeXBlLCBSZXNvbHZlZFBvcyB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgdHlwZSB7IEVkaXRvclN0YXRlLCBUcmFuc2FjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IGdldE1hcmtBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vaGVscGVycy9nZXRNYXJrQXR0cmlidXRlcy5qcydcbmltcG9ydCB7IGdldE1hcmtUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXRNYXJrVHlwZS5qcydcbmltcG9ydCB7IGlzVGV4dFNlbGVjdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnXG5pbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZXRNYXJrOiB7XG4gICAgICAvKipcbiAgICAgICAqIEFkZCBhIG1hcmsgd2l0aCBuZXcgYXR0cmlidXRlcy5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSBtYXJrIHR5cGUgb3IgbmFtZS5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5zZXRNYXJrKCdib2xkJywgeyBsZXZlbDogMSB9KVxuICAgICAgICovXG4gICAgICBzZXRNYXJrOiAodHlwZU9yTmFtZTogc3RyaW5nIHwgTWFya1R5cGUsIGF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNhblNldE1hcmsoc3RhdGU6IEVkaXRvclN0YXRlLCB0cjogVHJhbnNhY3Rpb24sIG5ld01hcmtUeXBlOiBNYXJrVHlwZSkge1xuICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gdHJcbiAgbGV0IGN1cnNvcjogUmVzb2x2ZWRQb3MgfCBudWxsID0gbnVsbFxuXG4gIGlmIChpc1RleHRTZWxlY3Rpb24oc2VsZWN0aW9uKSkge1xuICAgIGN1cnNvciA9IHNlbGVjdGlvbi4kY3Vyc29yXG4gIH1cblxuICBpZiAoY3Vyc29yKSB7XG4gICAgY29uc3QgY3VycmVudE1hcmtzID0gc3RhdGUuc3RvcmVkTWFya3MgPz8gY3Vyc29yLm1hcmtzKClcbiAgICBjb25zdCBwYXJlbnRBbGxvd3NNYXJrVHlwZSA9IGN1cnNvci5wYXJlbnQudHlwZS5hbGxvd3NNYXJrVHlwZShuZXdNYXJrVHlwZSlcblxuICAgIC8vIFRoZXJlIGNhbiBiZSBubyBjdXJyZW50IG1hcmtzIHRoYXQgZXhjbHVkZSB0aGUgbmV3IG1hcmssIGFuZCB0aGUgcGFyZW50IG11c3QgYWxsb3cgdGhpcyBtYXJrIHR5cGVcbiAgICByZXR1cm4gKFxuICAgICAgcGFyZW50QWxsb3dzTWFya1R5cGUgJiZcbiAgICAgICghIW5ld01hcmtUeXBlLmlzSW5TZXQoY3VycmVudE1hcmtzKSB8fFxuICAgICAgICAhY3VycmVudE1hcmtzLnNvbWUobWFyayA9PiBtYXJrLnR5cGUuZXhjbHVkZXMobmV3TWFya1R5cGUpKSlcbiAgICApXG4gIH1cblxuICBjb25zdCB7IHJhbmdlcyB9ID0gc2VsZWN0aW9uXG5cbiAgcmV0dXJuIHJhbmdlcy5zb21lKCh7ICRmcm9tLCAkdG8gfSkgPT4ge1xuICAgIGxldCBzb21lTm9kZVN1cHBvcnRzTWFyayA9XG4gICAgICAkZnJvbS5kZXB0aCA9PT0gMFxuICAgICAgICA/IHN0YXRlLmRvYy5pbmxpbmVDb250ZW50ICYmIHN0YXRlLmRvYy50eXBlLmFsbG93c01hcmtUeXBlKG5ld01hcmtUeXBlKVxuICAgICAgICA6IGZhbHNlXG5cbiAgICBzdGF0ZS5kb2Mubm9kZXNCZXR3ZWVuKCRmcm9tLnBvcywgJHRvLnBvcywgKG5vZGUsIF9wb3MsIHBhcmVudCkgPT4ge1xuICAgICAgLy8gSWYgd2UgYWxyZWFkeSBmb3VuZCBhIG1hcmsgdGhhdCB3ZSBjYW4gZW5hYmxlLCByZXR1cm4gZmFsc2UgdG8gYnlwYXNzIHRoZSByZW1haW5pbmcgc2VhcmNoXG4gICAgICBpZiAoc29tZU5vZGVTdXBwb3J0c01hcmspIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG5cbiAgICAgIGlmIChub2RlLmlzSW5saW5lKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudEFsbG93c01hcmtUeXBlID0gIXBhcmVudCB8fCBwYXJlbnQudHlwZS5hbGxvd3NNYXJrVHlwZShuZXdNYXJrVHlwZSlcbiAgICAgICAgY29uc3QgY3VycmVudE1hcmtzQWxsb3dNYXJrVHlwZSA9XG4gICAgICAgICAgISFuZXdNYXJrVHlwZS5pc0luU2V0KG5vZGUubWFya3MpIHx8XG4gICAgICAgICAgIW5vZGUubWFya3Muc29tZShvdGhlck1hcmsgPT4gb3RoZXJNYXJrLnR5cGUuZXhjbHVkZXMobmV3TWFya1R5cGUpKVxuXG4gICAgICAgIHNvbWVOb2RlU3VwcG9ydHNNYXJrID0gcGFyZW50QWxsb3dzTWFya1R5cGUgJiYgY3VycmVudE1hcmtzQWxsb3dNYXJrVHlwZVxuICAgICAgfVxuICAgICAgcmV0dXJuICFzb21lTm9kZVN1cHBvcnRzTWFya1xuICAgIH0pXG5cbiAgICByZXR1cm4gc29tZU5vZGVTdXBwb3J0c01hcmtcbiAgfSlcbn1cbmV4cG9ydCBjb25zdCBzZXRNYXJrOiBSYXdDb21tYW5kc1snc2V0TWFyayddID1cbiAgKHR5cGVPck5hbWUsIGF0dHJpYnV0ZXMgPSB7fSkgPT5cbiAgKHsgdHIsIHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IHRyXG4gICAgY29uc3QgeyBlbXB0eSwgcmFuZ2VzIH0gPSBzZWxlY3Rpb25cbiAgICBjb25zdCB0eXBlID0gZ2V0TWFya1R5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuXG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICBpZiAoZW1wdHkpIHtcbiAgICAgICAgY29uc3Qgb2xkQXR0cmlidXRlcyA9IGdldE1hcmtBdHRyaWJ1dGVzKHN0YXRlLCB0eXBlKVxuXG4gICAgICAgIHRyLmFkZFN0b3JlZE1hcmsoXG4gICAgICAgICAgdHlwZS5jcmVhdGUoe1xuICAgICAgICAgICAgLi4ub2xkQXR0cmlidXRlcyxcbiAgICAgICAgICAgIC4uLmF0dHJpYnV0ZXMsXG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJhbmdlcy5mb3JFYWNoKHJhbmdlID0+IHtcbiAgICAgICAgICBjb25zdCBmcm9tID0gcmFuZ2UuJGZyb20ucG9zXG4gICAgICAgICAgY29uc3QgdG8gPSByYW5nZS4kdG8ucG9zXG5cbiAgICAgICAgICBzdGF0ZS5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0cmltbWVkRnJvbSA9IE1hdGgubWF4KHBvcywgZnJvbSlcbiAgICAgICAgICAgIGNvbnN0IHRyaW1tZWRUbyA9IE1hdGgubWluKHBvcyArIG5vZGUubm9kZVNpemUsIHRvKVxuICAgICAgICAgICAgY29uc3Qgc29tZUhhc01hcmsgPSBub2RlLm1hcmtzLmZpbmQobWFyayA9PiBtYXJrLnR5cGUgPT09IHR5cGUpXG5cbiAgICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFscmVhZHkgYSBtYXJrIG9mIHRoaXMgdHlwZVxuICAgICAgICAgICAgLy8gd2Uga25vdyB0aGF0IHdlIGhhdmUgdG8gbWVyZ2UgaXRzIGF0dHJpYnV0ZXNcbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSB3ZSBhZGQgYSBmcmVzaCBuZXcgbWFya1xuICAgICAgICAgICAgaWYgKHNvbWVIYXNNYXJrKSB7XG4gICAgICAgICAgICAgIG5vZGUubWFya3MuZm9yRWFjaChtYXJrID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gbWFyay50eXBlKSB7XG4gICAgICAgICAgICAgICAgICB0ci5hZGRNYXJrKFxuICAgICAgICAgICAgICAgICAgICB0cmltbWVkRnJvbSxcbiAgICAgICAgICAgICAgICAgICAgdHJpbW1lZFRvLFxuICAgICAgICAgICAgICAgICAgICB0eXBlLmNyZWF0ZSh7XG4gICAgICAgICAgICAgICAgICAgICAgLi4ubWFyay5hdHRycyxcbiAgICAgICAgICAgICAgICAgICAgICAuLi5hdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0ci5hZGRNYXJrKHRyaW1tZWRGcm9tLCB0cmltbWVkVG8sIHR5cGUuY3JlYXRlKGF0dHJpYnV0ZXMpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNhblNldE1hcmsoc3RhdGUsIHRyLCB0eXBlKVxuICB9XG4iLCAiaW1wb3J0IHR5cGUgeyBQbHVnaW4sIFBsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHNldE1ldGE6IHtcbiAgICAgIC8qKlxuICAgICAgICogU3RvcmUgYSBtZXRhZGF0YSBwcm9wZXJ0eSBpbiB0aGUgY3VycmVudCB0cmFuc2FjdGlvbi5cbiAgICAgICAqIEBwYXJhbSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0YWRhdGEgcHJvcGVydHkuXG4gICAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIHN0b3JlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldE1ldGEoJ2ZvbycsICdiYXInKVxuICAgICAgICovXG4gICAgICBzZXRNZXRhOiAoa2V5OiBzdHJpbmcgfCBQbHVnaW4gfCBQbHVnaW5LZXksIHZhbHVlOiBhbnkpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNldE1ldGE6IFJhd0NvbW1hbmRzWydzZXRNZXRhJ10gPVxuICAoa2V5LCB2YWx1ZSkgPT5cbiAgKHsgdHIgfSkgPT4ge1xuICAgIHRyLnNldE1ldGEoa2V5LCB2YWx1ZSlcblxuICAgIHJldHVybiB0cnVlXG4gIH1cbiIsICJpbXBvcnQgeyBzZXRCbG9ja1R5cGUgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuaW1wb3J0IHR5cGUgeyBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IGdldE5vZGVUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXROb2RlVHlwZS5qcydcbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHNldE5vZGU6IHtcbiAgICAgIC8qKlxuICAgICAgICogUmVwbGFjZSBhIGdpdmVuIHJhbmdlIHdpdGggYSBub2RlLlxuICAgICAgICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIHR5cGUgb3IgbmFtZSBvZiB0aGUgbm9kZVxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG5vZGVcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5zZXROb2RlKCdwYXJhZ3JhcGgnKVxuICAgICAgICovXG4gICAgICBzZXROb2RlOiAodHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUsIGF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBzZXROb2RlOiBSYXdDb21tYW5kc1snc2V0Tm9kZSddID1cbiAgKHR5cGVPck5hbWUsIGF0dHJpYnV0ZXMgPSB7fSkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoLCBjaGFpbiB9KSA9PiB7XG4gICAgY29uc3QgdHlwZSA9IGdldE5vZGVUeXBlKHR5cGVPck5hbWUsIHN0YXRlLnNjaGVtYSlcblxuICAgIGxldCBhdHRyaWJ1dGVzVG9Db3B5OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgdW5kZWZpbmVkXG5cbiAgICBpZiAoc3RhdGUuc2VsZWN0aW9uLiRhbmNob3Iuc2FtZVBhcmVudChzdGF0ZS5zZWxlY3Rpb24uJGhlYWQpKSB7XG4gICAgICAvLyBvbmx5IGNvcHkgYXR0cmlidXRlcyBpZiB0aGUgc2VsZWN0aW9uIGlzIHBvaW50aW5nIHRvIGEgbm9kZSBvZiB0aGUgc2FtZSB0eXBlXG4gICAgICBhdHRyaWJ1dGVzVG9Db3B5ID0gc3RhdGUuc2VsZWN0aW9uLiRhbmNob3IucGFyZW50LmF0dHJzXG4gICAgfVxuXG4gICAgLy8gVE9ETzogdXNlIGEgZmFsbGJhY2sgbGlrZSBpbnNlcnRDb250ZW50P1xuICAgIGlmICghdHlwZS5pc1RleHRibG9jaykge1xuICAgICAgY29uc29sZS53YXJuKCdbdGlwdGFwIHdhcm5dOiBDdXJyZW50bHkgXCJzZXROb2RlKClcIiBvbmx5IHN1cHBvcnRzIHRleHQgYmxvY2sgbm9kZXMuJylcblxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIGNoYWluKClcbiAgICAgICAgLy8gdHJ5IHRvIGNvbnZlcnQgbm9kZSB0byBkZWZhdWx0IG5vZGUgaWYgbmVlZGVkXG4gICAgICAgIC5jb21tYW5kKCh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgICBjb25zdCBjYW5TZXRCbG9jayA9IHNldEJsb2NrVHlwZSh0eXBlLCB7IC4uLmF0dHJpYnV0ZXNUb0NvcHksIC4uLmF0dHJpYnV0ZXMgfSkoc3RhdGUpXG5cbiAgICAgICAgICBpZiAoY2FuU2V0QmxvY2spIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLmNsZWFyTm9kZXMoKVxuICAgICAgICB9KVxuICAgICAgICAuY29tbWFuZCgoeyBzdGF0ZTogdXBkYXRlZFN0YXRlIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gc2V0QmxvY2tUeXBlKHR5cGUsIHsgLi4uYXR0cmlidXRlc1RvQ29weSwgLi4uYXR0cmlidXRlcyB9KSh1cGRhdGVkU3RhdGUsIGRpc3BhdGNoKVxuICAgICAgICB9KVxuICAgICAgICAucnVuKClcbiAgICApXG4gIH1cbiIsICJpbXBvcnQgeyBOb2RlU2VsZWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgbWluTWF4IH0gZnJvbSAnLi4vdXRpbGl0aWVzL21pbk1heC5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHNldE5vZGVTZWxlY3Rpb246IHtcbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlcyBhIE5vZGVTZWxlY3Rpb24uXG4gICAgICAgKiBAcGFyYW0gcG9zaXRpb24gLSBQb3NpdGlvbiBvZiB0aGUgbm9kZS5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5zZXROb2RlU2VsZWN0aW9uKDEwKVxuICAgICAgICovXG4gICAgICBzZXROb2RlU2VsZWN0aW9uOiAocG9zaXRpb246IG51bWJlcikgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgc2V0Tm9kZVNlbGVjdGlvbjogUmF3Q29tbWFuZHNbJ3NldE5vZGVTZWxlY3Rpb24nXSA9XG4gIHBvc2l0aW9uID0+XG4gICh7IHRyLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICBjb25zdCB7IGRvYyB9ID0gdHJcbiAgICAgIGNvbnN0IGZyb20gPSBtaW5NYXgocG9zaXRpb24sIDAsIGRvYy5jb250ZW50LnNpemUpXG4gICAgICBjb25zdCBzZWxlY3Rpb24gPSBOb2RlU2VsZWN0aW9uLmNyZWF0ZShkb2MsIGZyb20pXG5cbiAgICAgIHRyLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgUmFuZ2UsIFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZXRUZXh0RGlyZWN0aW9uOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNldCB0aGUgdGV4dCBkaXJlY3Rpb24gZm9yIG5vZGVzLlxuICAgICAgICogSWYgbm8gcG9zaXRpb24gaXMgcHJvdmlkZWQsIGl0IHdpbGwgdXNlIHRoZSBjdXJyZW50IHNlbGVjdGlvbi5cbiAgICAgICAqIEBwYXJhbSBkaXJlY3Rpb24gVGhlIHRleHQgZGlyZWN0aW9uIHRvIHNldCAoJ2x0cicsICdydGwnLCBvciAnYXV0bycpXG4gICAgICAgKiBAcGFyYW0gcG9zaXRpb24gT3B0aW9uYWwgcG9zaXRpb24gb3IgcmFuZ2UgdG8gYXBwbHkgdGhlIGRpcmVjdGlvbiB0b1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldFRleHREaXJlY3Rpb24oJ3J0bCcpXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2V0VGV4dERpcmVjdGlvbignbHRyJywgeyBmcm9tOiAwLCB0bzogMTAgfSlcbiAgICAgICAqL1xuICAgICAgc2V0VGV4dERpcmVjdGlvbjogKGRpcmVjdGlvbjogJ2x0cicgfCAncnRsJyB8ICdhdXRvJywgcG9zaXRpb24/OiBudW1iZXIgfCBSYW5nZSkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgc2V0VGV4dERpcmVjdGlvbjogUmF3Q29tbWFuZHNbJ3NldFRleHREaXJlY3Rpb24nXSA9XG4gIChkaXJlY3Rpb24sIHBvc2l0aW9uKSA9PlxuICAoeyB0ciwgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gc3RhdGVcbiAgICBsZXQgZnJvbTogbnVtYmVyXG4gICAgbGV0IHRvOiBudW1iZXJcblxuICAgIGlmICh0eXBlb2YgcG9zaXRpb24gPT09ICdudW1iZXInKSB7XG4gICAgICBmcm9tID0gcG9zaXRpb25cbiAgICAgIHRvID0gcG9zaXRpb25cbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uICYmICdmcm9tJyBpbiBwb3NpdGlvbiAmJiAndG8nIGluIHBvc2l0aW9uKSB7XG4gICAgICBmcm9tID0gcG9zaXRpb24uZnJvbVxuICAgICAgdG8gPSBwb3NpdGlvbi50b1xuICAgIH0gZWxzZSB7XG4gICAgICBmcm9tID0gc2VsZWN0aW9uLmZyb21cbiAgICAgIHRvID0gc2VsZWN0aW9uLnRvXG4gICAgfVxuXG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICB0ci5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgIGlmIChub2RlLmlzVGV4dCkge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgdHIuc2V0Tm9kZU1hcmt1cChwb3MsIHVuZGVmaW5lZCwge1xuICAgICAgICAgIC4uLm5vZGUuYXR0cnMsXG4gICAgICAgICAgZGlyOiBkaXJlY3Rpb24sXG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH1cbiIsICJpbXBvcnQgeyBUZXh0U2VsZWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHR5cGUgeyBSYW5nZSwgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IG1pbk1heCB9IGZyb20gJy4uL3V0aWxpdGllcy9taW5NYXguanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZXRUZXh0U2VsZWN0aW9uOiB7XG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBUZXh0U2VsZWN0aW9uLlxuICAgICAgICogQHBhcmFtIHBvc2l0aW9uIFRoZSBwb3NpdGlvbiBvZiB0aGUgc2VsZWN0aW9uLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldFRleHRTZWxlY3Rpb24oMTApXG4gICAgICAgKi9cbiAgICAgIHNldFRleHRTZWxlY3Rpb246IChwb3NpdGlvbjogbnVtYmVyIHwgUmFuZ2UpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNldFRleHRTZWxlY3Rpb246IFJhd0NvbW1hbmRzWydzZXRUZXh0U2VsZWN0aW9uJ10gPVxuICBwb3NpdGlvbiA9PlxuICAoeyB0ciwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgY29uc3QgeyBkb2MgfSA9IHRyXG4gICAgICBjb25zdCB7IGZyb20sIHRvIH0gPVxuICAgICAgICB0eXBlb2YgcG9zaXRpb24gPT09ICdudW1iZXInID8geyBmcm9tOiBwb3NpdGlvbiwgdG86IHBvc2l0aW9uIH0gOiBwb3NpdGlvblxuICAgICAgY29uc3QgbWluUG9zID0gVGV4dFNlbGVjdGlvbi5hdFN0YXJ0KGRvYykuZnJvbVxuICAgICAgY29uc3QgbWF4UG9zID0gVGV4dFNlbGVjdGlvbi5hdEVuZChkb2MpLnRvXG4gICAgICBjb25zdCByZXNvbHZlZEZyb20gPSBtaW5NYXgoZnJvbSwgbWluUG9zLCBtYXhQb3MpXG4gICAgICBjb25zdCByZXNvbHZlZEVuZCA9IG1pbk1heCh0bywgbWluUG9zLCBtYXhQb3MpXG4gICAgICBjb25zdCBzZWxlY3Rpb24gPSBUZXh0U2VsZWN0aW9uLmNyZWF0ZShkb2MsIHJlc29sdmVkRnJvbSwgcmVzb2x2ZWRFbmQpXG5cbiAgICAgIHRyLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgc2lua0xpc3RJdGVtIGFzIG9yaWdpbmFsU2lua0xpc3RJdGVtIH0gZnJvbSAnQHRpcHRhcC9wbS9zY2hlbWEtbGlzdCdcblxuaW1wb3J0IHsgZ2V0Tm9kZVR5cGUgfSBmcm9tICcuLi9oZWxwZXJzL2dldE5vZGVUeXBlLmpzJ1xuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2lua0xpc3RJdGVtOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNpbmsgdGhlIGxpc3QgaXRlbSBkb3duIGludG8gYW4gaW5uZXIgbGlzdC5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2lua0xpc3RJdGVtKCdsaXN0SXRlbScpXG4gICAgICAgKi9cbiAgICAgIHNpbmtMaXN0SXRlbTogKHR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBzaW5rTGlzdEl0ZW06IFJhd0NvbW1hbmRzWydzaW5rTGlzdEl0ZW0nXSA9XG4gIHR5cGVPck5hbWUgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICBjb25zdCB0eXBlID0gZ2V0Tm9kZVR5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuXG4gICAgcmV0dXJuIG9yaWdpbmFsU2lua0xpc3RJdGVtKHR5cGUpKHN0YXRlLCBkaXNwYXRjaClcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHsgTm9kZVNlbGVjdGlvbiwgVGV4dFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgeyBjYW5TcGxpdCB9IGZyb20gJ0B0aXB0YXAvcG0vdHJhbnNmb3JtJ1xuXG5pbXBvcnQgeyBkZWZhdWx0QmxvY2tBdCB9IGZyb20gJy4uL2hlbHBlcnMvZGVmYXVsdEJsb2NrQXQuanMnXG5pbXBvcnQgeyBnZXRTcGxpdHRlZEF0dHJpYnV0ZXMgfSBmcm9tICcuLi9oZWxwZXJzL2dldFNwbGl0dGVkQXR0cmlidXRlcy5qcydcbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZnVuY3Rpb24gZW5zdXJlTWFya3Moc3RhdGU6IEVkaXRvclN0YXRlLCBzcGxpdHRhYmxlTWFya3M/OiBzdHJpbmdbXSkge1xuICBjb25zdCBtYXJrcyA9XG4gICAgc3RhdGUuc3RvcmVkTWFya3MgfHwgKHN0YXRlLnNlbGVjdGlvbi4kdG8ucGFyZW50T2Zmc2V0ICYmIHN0YXRlLnNlbGVjdGlvbi4kZnJvbS5tYXJrcygpKVxuXG4gIGlmIChtYXJrcykge1xuICAgIGNvbnN0IGZpbHRlcmVkTWFya3MgPSBtYXJrcy5maWx0ZXIobWFyayA9PiBzcGxpdHRhYmxlTWFya3M/LmluY2x1ZGVzKG1hcmsudHlwZS5uYW1lKSlcblxuICAgIHN0YXRlLnRyLmVuc3VyZU1hcmtzKGZpbHRlcmVkTWFya3MpXG4gIH1cbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHNwbGl0QmxvY2s6IHtcbiAgICAgIC8qKlxuICAgICAgICogRm9ya3MgYSBuZXcgbm9kZSBmcm9tIGFuIGV4aXN0aW5nIG5vZGUuXG4gICAgICAgKiBAcGFyYW0gb3B0aW9ucy5rZWVwTWFya3MgS2VlcCBtYXJrcyBmcm9tIHRoZSBwcmV2aW91cyBub2RlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNwbGl0QmxvY2soKVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNwbGl0QmxvY2soeyBrZWVwTWFya3M6IHRydWUgfSlcbiAgICAgICAqL1xuICAgICAgc3BsaXRCbG9jazogKG9wdGlvbnM/OiB7IGtlZXBNYXJrcz86IGJvb2xlYW4gfSkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgc3BsaXRCbG9jazogUmF3Q29tbWFuZHNbJ3NwbGl0QmxvY2snXSA9XG4gICh7IGtlZXBNYXJrcyA9IHRydWUgfSA9IHt9KSA9PlxuICAoeyB0ciwgc3RhdGUsIGRpc3BhdGNoLCBlZGl0b3IgfSkgPT4ge1xuICAgIGNvbnN0IHsgc2VsZWN0aW9uLCBkb2MgfSA9IHRyXG4gICAgY29uc3QgeyAkZnJvbSwgJHRvIH0gPSBzZWxlY3Rpb25cbiAgICBjb25zdCBleHRlbnNpb25BdHRyaWJ1dGVzID0gZWRpdG9yLmV4dGVuc2lvbk1hbmFnZXIuYXR0cmlidXRlc1xuICAgIGNvbnN0IG5ld0F0dHJpYnV0ZXMgPSBnZXRTcGxpdHRlZEF0dHJpYnV0ZXMoXG4gICAgICBleHRlbnNpb25BdHRyaWJ1dGVzLFxuICAgICAgJGZyb20ubm9kZSgpLnR5cGUubmFtZSxcbiAgICAgICRmcm9tLm5vZGUoKS5hdHRycyxcbiAgICApXG5cbiAgICBpZiAoc2VsZWN0aW9uIGluc3RhbmNlb2YgTm9kZVNlbGVjdGlvbiAmJiBzZWxlY3Rpb24ubm9kZS5pc0Jsb2NrKSB7XG4gICAgICBpZiAoISRmcm9tLnBhcmVudE9mZnNldCB8fCAhY2FuU3BsaXQoZG9jLCAkZnJvbS5wb3MpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuXG4gICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgaWYgKGtlZXBNYXJrcykge1xuICAgICAgICAgIGVuc3VyZU1hcmtzKHN0YXRlLCBlZGl0b3IuZXh0ZW5zaW9uTWFuYWdlci5zcGxpdHRhYmxlTWFya3MpXG4gICAgICAgIH1cblxuICAgICAgICB0ci5zcGxpdCgkZnJvbS5wb3MpLnNjcm9sbEludG9WaWV3KClcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBpZiAoISRmcm9tLnBhcmVudC5pc0Jsb2NrKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBjb25zdCBhdEVuZCA9ICR0by5wYXJlbnRPZmZzZXQgPT09ICR0by5wYXJlbnQuY29udGVudC5zaXplXG5cbiAgICBjb25zdCBkZWZsdCA9XG4gICAgICAkZnJvbS5kZXB0aCA9PT0gMFxuICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICA6IGRlZmF1bHRCbG9ja0F0KCRmcm9tLm5vZGUoLTEpLmNvbnRlbnRNYXRjaEF0KCRmcm9tLmluZGV4QWZ0ZXIoLTEpKSlcblxuICAgIGxldCB0eXBlcyA9XG4gICAgICBhdEVuZCAmJiBkZWZsdFxuICAgICAgICA/IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogZGVmbHQsXG4gICAgICAgICAgICAgIGF0dHJzOiBuZXdBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdXG4gICAgICAgIDogdW5kZWZpbmVkXG5cbiAgICBsZXQgY2FuID0gY2FuU3BsaXQodHIuZG9jLCB0ci5tYXBwaW5nLm1hcCgkZnJvbS5wb3MpLCAxLCB0eXBlcylcblxuICAgIGlmIChcbiAgICAgICF0eXBlcyAmJlxuICAgICAgIWNhbiAmJlxuICAgICAgY2FuU3BsaXQodHIuZG9jLCB0ci5tYXBwaW5nLm1hcCgkZnJvbS5wb3MpLCAxLCBkZWZsdCA/IFt7IHR5cGU6IGRlZmx0IH1dIDogdW5kZWZpbmVkKVxuICAgICkge1xuICAgICAgY2FuID0gdHJ1ZVxuICAgICAgdHlwZXMgPSBkZWZsdFxuICAgICAgICA/IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogZGVmbHQsXG4gICAgICAgICAgICAgIGF0dHJzOiBuZXdBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdXG4gICAgICAgIDogdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICBpZiAoY2FuKSB7XG4gICAgICAgIGlmIChzZWxlY3Rpb24gaW5zdGFuY2VvZiBUZXh0U2VsZWN0aW9uKSB7XG4gICAgICAgICAgdHIuZGVsZXRlU2VsZWN0aW9uKClcbiAgICAgICAgfVxuXG4gICAgICAgIHRyLnNwbGl0KHRyLm1hcHBpbmcubWFwKCRmcm9tLnBvcyksIDEsIHR5cGVzKVxuXG4gICAgICAgIGlmIChkZWZsdCAmJiAhYXRFbmQgJiYgISRmcm9tLnBhcmVudE9mZnNldCAmJiAkZnJvbS5wYXJlbnQudHlwZSAhPT0gZGVmbHQpIHtcbiAgICAgICAgICBjb25zdCBmaXJzdCA9IHRyLm1hcHBpbmcubWFwKCRmcm9tLmJlZm9yZSgpKVxuICAgICAgICAgIGNvbnN0ICRmaXJzdCA9IHRyLmRvYy5yZXNvbHZlKGZpcnN0KVxuXG4gICAgICAgICAgaWYgKCRmcm9tLm5vZGUoLTEpLmNhblJlcGxhY2VXaXRoKCRmaXJzdC5pbmRleCgpLCAkZmlyc3QuaW5kZXgoKSArIDEsIGRlZmx0KSkge1xuICAgICAgICAgICAgdHIuc2V0Tm9kZU1hcmt1cCh0ci5tYXBwaW5nLm1hcCgkZnJvbS5iZWZvcmUoKSksIGRlZmx0KVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoa2VlcE1hcmtzKSB7XG4gICAgICAgIGVuc3VyZU1hcmtzKHN0YXRlLCBlZGl0b3IuZXh0ZW5zaW9uTWFuYWdlci5zcGxpdHRhYmxlTWFya3MpXG4gICAgICB9XG5cbiAgICAgIHRyLnNjcm9sbEludG9WaWV3KClcbiAgICB9XG5cbiAgICByZXR1cm4gY2FuXG4gIH1cbiIsICJpbXBvcnQgdHlwZSB7IE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlLCBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBGcmFnbWVudCwgU2xpY2UgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgVGV4dFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgeyBjYW5TcGxpdCB9IGZyb20gJ0B0aXB0YXAvcG0vdHJhbnNmb3JtJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBnZXRTcGxpdHRlZEF0dHJpYnV0ZXMgfSBmcm9tICcuLi9oZWxwZXJzL2dldFNwbGl0dGVkQXR0cmlidXRlcy5qcydcbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHNwbGl0TGlzdEl0ZW06IHtcbiAgICAgIC8qKlxuICAgICAgICogU3BsaXRzIG9uZSBsaXN0IGl0ZW0gaW50byB0d28gbGlzdCBpdGVtcy5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAcGFyYW0gb3ZlcnJpZGVBdHRycyBUaGUgYXR0cmlidXRlcyB0byBlbnN1cmUgb24gdGhlIG5ldyBub2RlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNwbGl0TGlzdEl0ZW0oJ2xpc3RJdGVtJylcbiAgICAgICAqL1xuICAgICAgc3BsaXRMaXN0SXRlbTogKFxuICAgICAgICB0eXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSxcbiAgICAgICAgb3ZlcnJpZGVBdHRycz86IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNwbGl0TGlzdEl0ZW06IFJhd0NvbW1hbmRzWydzcGxpdExpc3RJdGVtJ10gPVxuICAodHlwZU9yTmFtZSwgb3ZlcnJpZGVBdHRycyA9IHt9KSA9PlxuICAoeyB0ciwgc3RhdGUsIGRpc3BhdGNoLCBlZGl0b3IgfSkgPT4ge1xuICAgIGNvbnN0IHR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gICAgY29uc3QgeyAkZnJvbSwgJHRvIH0gPSBzdGF0ZS5zZWxlY3Rpb25cblxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICAvLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICBjb25zdCBub2RlOiBQcm9zZU1pcnJvck5vZGUgPSBzdGF0ZS5zZWxlY3Rpb24ubm9kZVxuXG4gICAgaWYgKChub2RlICYmIG5vZGUuaXNCbG9jaykgfHwgJGZyb20uZGVwdGggPCAyIHx8ICEkZnJvbS5zYW1lUGFyZW50KCR0bykpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGNvbnN0IGdyYW5kUGFyZW50ID0gJGZyb20ubm9kZSgtMSlcblxuICAgIGlmIChncmFuZFBhcmVudC50eXBlICE9PSB0eXBlKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBjb25zdCBleHRlbnNpb25BdHRyaWJ1dGVzID0gZWRpdG9yLmV4dGVuc2lvbk1hbmFnZXIuYXR0cmlidXRlc1xuXG4gICAgaWYgKCRmcm9tLnBhcmVudC5jb250ZW50LnNpemUgPT09IDAgJiYgJGZyb20ubm9kZSgtMSkuY2hpbGRDb3VudCA9PT0gJGZyb20uaW5kZXhBZnRlcigtMSkpIHtcbiAgICAgIC8vIEluIGFuIGVtcHR5IGJsb2NrLiBJZiB0aGlzIGlzIGEgbmVzdGVkIGxpc3QsIHRoZSB3cmFwcGluZ1xuICAgICAgLy8gbGlzdCBpdGVtIHNob3VsZCBiZSBzcGxpdC4gT3RoZXJ3aXNlLCBiYWlsIG91dCBhbmQgbGV0IG5leHRcbiAgICAgIC8vIGNvbW1hbmQgaGFuZGxlIGxpZnRpbmcuXG4gICAgICBpZiAoXG4gICAgICAgICRmcm9tLmRlcHRoID09PSAyIHx8XG4gICAgICAgICRmcm9tLm5vZGUoLTMpLnR5cGUgIT09IHR5cGUgfHxcbiAgICAgICAgJGZyb20uaW5kZXgoLTIpICE9PSAkZnJvbS5ub2RlKC0yKS5jaGlsZENvdW50IC0gMVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuXG4gICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgbGV0IHdyYXAgPSBGcmFnbWVudC5lbXB0eVxuICAgICAgICAvLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgY29uc3QgZGVwdGhCZWZvcmUgPSAkZnJvbS5pbmRleCgtMSkgPyAxIDogJGZyb20uaW5kZXgoLTIpID8gMiA6IDNcblxuICAgICAgICAvLyBCdWlsZCBhIGZyYWdtZW50IGNvbnRhaW5pbmcgZW1wdHkgdmVyc2lvbnMgb2YgdGhlIHN0cnVjdHVyZVxuICAgICAgICAvLyBmcm9tIHRoZSBvdXRlciBsaXN0IGl0ZW0gdG8gdGhlIHBhcmVudCBub2RlIG9mIHRoZSBjdXJzb3JcbiAgICAgICAgZm9yIChsZXQgZCA9ICRmcm9tLmRlcHRoIC0gZGVwdGhCZWZvcmU7IGQgPj0gJGZyb20uZGVwdGggLSAzOyBkIC09IDEpIHtcbiAgICAgICAgICB3cmFwID0gRnJhZ21lbnQuZnJvbSgkZnJvbS5ub2RlKGQpLmNvcHkod3JhcCkpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZXB0aEFmdGVyID1cbiAgICAgICAgICAvLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmVzdGVkLXRlcm5hcnlcbiAgICAgICAgICAkZnJvbS5pbmRleEFmdGVyKC0xKSA8ICRmcm9tLm5vZGUoLTIpLmNoaWxkQ291bnRcbiAgICAgICAgICAgID8gMVxuICAgICAgICAgICAgOiAkZnJvbS5pbmRleEFmdGVyKC0yKSA8ICRmcm9tLm5vZGUoLTMpLmNoaWxkQ291bnRcbiAgICAgICAgICAgICAgPyAyXG4gICAgICAgICAgICAgIDogM1xuXG4gICAgICAgIC8vIEFkZCBhIHNlY29uZCBsaXN0IGl0ZW0gd2l0aCBhbiBlbXB0eSBkZWZhdWx0IHN0YXJ0IG5vZGVcbiAgICAgICAgY29uc3QgbmV3TmV4dFR5cGVBdHRyaWJ1dGVzID0ge1xuICAgICAgICAgIC4uLmdldFNwbGl0dGVkQXR0cmlidXRlcyhleHRlbnNpb25BdHRyaWJ1dGVzLCAkZnJvbS5ub2RlKCkudHlwZS5uYW1lLCAkZnJvbS5ub2RlKCkuYXR0cnMpLFxuICAgICAgICAgIC4uLm92ZXJyaWRlQXR0cnMsXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV4dFR5cGUgPVxuICAgICAgICAgIHR5cGUuY29udGVudE1hdGNoLmRlZmF1bHRUeXBlPy5jcmVhdGVBbmRGaWxsKG5ld05leHRUeXBlQXR0cmlidXRlcykgfHwgdW5kZWZpbmVkXG5cbiAgICAgICAgd3JhcCA9IHdyYXAuYXBwZW5kKEZyYWdtZW50LmZyb20odHlwZS5jcmVhdGVBbmRGaWxsKG51bGwsIG5leHRUeXBlKSB8fCB1bmRlZmluZWQpKVxuXG4gICAgICAgIGNvbnN0IHN0YXJ0ID0gJGZyb20uYmVmb3JlKCRmcm9tLmRlcHRoIC0gKGRlcHRoQmVmb3JlIC0gMSkpXG5cbiAgICAgICAgdHIucmVwbGFjZShzdGFydCwgJGZyb20uYWZ0ZXIoLWRlcHRoQWZ0ZXIpLCBuZXcgU2xpY2Uod3JhcCwgNCAtIGRlcHRoQmVmb3JlLCAwKSlcblxuICAgICAgICBsZXQgc2VsID0gLTFcblxuICAgICAgICB0ci5kb2Mubm9kZXNCZXR3ZWVuKHN0YXJ0LCB0ci5kb2MuY29udGVudC5zaXplLCAobiwgcG9zKSA9PiB7XG4gICAgICAgICAgaWYgKHNlbCA+IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAobi5pc1RleHRibG9jayAmJiBuLmNvbnRlbnQuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgICAgc2VsID0gcG9zICsgMVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICBpZiAoc2VsID4gLTEpIHtcbiAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24oVGV4dFNlbGVjdGlvbi5uZWFyKHRyLmRvYy5yZXNvbHZlKHNlbCkpKVxuICAgICAgICB9XG5cbiAgICAgICAgdHIuc2Nyb2xsSW50b1ZpZXcoKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGNvbnN0IG5leHRUeXBlID0gJHRvLnBvcyA9PT0gJGZyb20uZW5kKCkgPyBncmFuZFBhcmVudC5jb250ZW50TWF0Y2hBdCgwKS5kZWZhdWx0VHlwZSA6IG51bGxcblxuICAgIGNvbnN0IG5ld1R5cGVBdHRyaWJ1dGVzID0ge1xuICAgICAgLi4uZ2V0U3BsaXR0ZWRBdHRyaWJ1dGVzKGV4dGVuc2lvbkF0dHJpYnV0ZXMsIGdyYW5kUGFyZW50LnR5cGUubmFtZSwgZ3JhbmRQYXJlbnQuYXR0cnMpLFxuICAgICAgLi4ub3ZlcnJpZGVBdHRycyxcbiAgICB9XG4gICAgY29uc3QgbmV3TmV4dFR5cGVBdHRyaWJ1dGVzID0ge1xuICAgICAgLi4uZ2V0U3BsaXR0ZWRBdHRyaWJ1dGVzKGV4dGVuc2lvbkF0dHJpYnV0ZXMsICRmcm9tLm5vZGUoKS50eXBlLm5hbWUsICRmcm9tLm5vZGUoKS5hdHRycyksXG4gICAgICAuLi5vdmVycmlkZUF0dHJzLFxuICAgIH1cblxuICAgIHRyLmRlbGV0ZSgkZnJvbS5wb3MsICR0by5wb3MpXG5cbiAgICBjb25zdCB0eXBlcyA9IG5leHRUeXBlXG4gICAgICA/IFtcbiAgICAgICAgICB7IHR5cGUsIGF0dHJzOiBuZXdUeXBlQXR0cmlidXRlcyB9LFxuICAgICAgICAgIHsgdHlwZTogbmV4dFR5cGUsIGF0dHJzOiBuZXdOZXh0VHlwZUF0dHJpYnV0ZXMgfSxcbiAgICAgICAgXVxuICAgICAgOiBbeyB0eXBlLCBhdHRyczogbmV3VHlwZUF0dHJpYnV0ZXMgfV1cblxuICAgIGlmICghY2FuU3BsaXQodHIuZG9jLCAkZnJvbS5wb3MsIDIpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgIGNvbnN0IHsgc2VsZWN0aW9uLCBzdG9yZWRNYXJrcyB9ID0gc3RhdGVcbiAgICAgIGNvbnN0IHsgc3BsaXR0YWJsZU1hcmtzIH0gPSBlZGl0b3IuZXh0ZW5zaW9uTWFuYWdlclxuICAgICAgY29uc3QgbWFya3MgPSBzdG9yZWRNYXJrcyB8fCAoc2VsZWN0aW9uLiR0by5wYXJlbnRPZmZzZXQgJiYgc2VsZWN0aW9uLiRmcm9tLm1hcmtzKCkpXG5cbiAgICAgIHRyLnNwbGl0KCRmcm9tLnBvcywgMiwgdHlwZXMpLnNjcm9sbEludG9WaWV3KClcblxuICAgICAgaWYgKCFtYXJrcyB8fCAhZGlzcGF0Y2gpIHtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmlsdGVyZWRNYXJrcyA9IG1hcmtzLmZpbHRlcihtYXJrID0+IHNwbGl0dGFibGVNYXJrcy5pbmNsdWRlcyhtYXJrLnR5cGUubmFtZSkpXG5cbiAgICAgIHRyLmVuc3VyZU1hcmtzKGZpbHRlcmVkTWFya3MpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHR5cGUgeyBUcmFuc2FjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgeyBUZXh0U2VsZWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcbmltcG9ydCB7IGNhbkpvaW4gfSBmcm9tICdAdGlwdGFwL3BtL3RyYW5zZm9ybSdcblxuaW1wb3J0IHsgZmluZFBhcmVudE5vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2ZpbmRQYXJlbnROb2RlLmpzJ1xuaW1wb3J0IHsgZ2V0Tm9kZVR5cGUgfSBmcm9tICcuLi9oZWxwZXJzL2dldE5vZGVUeXBlLmpzJ1xuaW1wb3J0IHsgaXNMaXN0IH0gZnJvbSAnLi4vaGVscGVycy9pc0xpc3QuanMnXG5pbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmNvbnN0IGpvaW5MaXN0QmFja3dhcmRzID0gKHRyOiBUcmFuc2FjdGlvbiwgbGlzdFR5cGU6IE5vZGVUeXBlKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IGxpc3QgPSBmaW5kUGFyZW50Tm9kZShub2RlID0+IG5vZGUudHlwZSA9PT0gbGlzdFR5cGUpKHRyLnNlbGVjdGlvbilcblxuICBpZiAoIWxpc3QpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgY29uc3QgYmVmb3JlID0gdHIuZG9jLnJlc29sdmUoTWF0aC5tYXgoMCwgbGlzdC5wb3MgLSAxKSkuYmVmb3JlKGxpc3QuZGVwdGgpXG5cbiAgaWYgKGJlZm9yZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGNvbnN0IG5vZGVCZWZvcmUgPSB0ci5kb2Mubm9kZUF0KGJlZm9yZSlcbiAgY29uc3QgY2FuSm9pbkJhY2t3YXJkcyA9IGxpc3Qubm9kZS50eXBlID09PSBub2RlQmVmb3JlPy50eXBlICYmIGNhbkpvaW4odHIuZG9jLCBsaXN0LnBvcylcblxuICBpZiAoIWNhbkpvaW5CYWNrd2FyZHMpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgdHIuam9pbihsaXN0LnBvcylcblxuICByZXR1cm4gdHJ1ZVxufVxuXG5jb25zdCBqb2luTGlzdEZvcndhcmRzID0gKHRyOiBUcmFuc2FjdGlvbiwgbGlzdFR5cGU6IE5vZGVUeXBlKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IGxpc3QgPSBmaW5kUGFyZW50Tm9kZShub2RlID0+IG5vZGUudHlwZSA9PT0gbGlzdFR5cGUpKHRyLnNlbGVjdGlvbilcblxuICBpZiAoIWxpc3QpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgY29uc3QgYWZ0ZXIgPSB0ci5kb2MucmVzb2x2ZShsaXN0LnN0YXJ0KS5hZnRlcihsaXN0LmRlcHRoKVxuXG4gIGlmIChhZnRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGNvbnN0IG5vZGVBZnRlciA9IHRyLmRvYy5ub2RlQXQoYWZ0ZXIpXG4gIGNvbnN0IGNhbkpvaW5Gb3J3YXJkcyA9IGxpc3Qubm9kZS50eXBlID09PSBub2RlQWZ0ZXI/LnR5cGUgJiYgY2FuSm9pbih0ci5kb2MsIGFmdGVyKVxuXG4gIGlmICghY2FuSm9pbkZvcndhcmRzKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIHRyLmpvaW4oYWZ0ZXIpXG5cbiAgcmV0dXJuIHRydWVcbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHRvZ2dsZUxpc3Q6IHtcbiAgICAgIC8qKlxuICAgICAgICogVG9nZ2xlIGJldHdlZW4gZGlmZmVyZW50IGxpc3QgdHlwZXMuXG4gICAgICAgKiBAcGFyYW0gbGlzdFR5cGVPck5hbWUgVGhlIHR5cGUgb3IgbmFtZSBvZiB0aGUgbGlzdC5cbiAgICAgICAqIEBwYXJhbSBpdGVtVHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBsaXN0IGl0ZW0uXG4gICAgICAgKiBAcGFyYW0ga2VlcE1hcmtzIEtlZXAgbWFya3Mgd2hlbiB0b2dnbGluZy5cbiAgICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIEF0dHJpYnV0ZXMgZm9yIHRoZSBuZXcgbGlzdC5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVMaXN0KCdidWxsZXRMaXN0JywgJ2xpc3RJdGVtJylcbiAgICAgICAqL1xuICAgICAgdG9nZ2xlTGlzdDogKFxuICAgICAgICBsaXN0VHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUsXG4gICAgICAgIGl0ZW1UeXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSxcbiAgICAgICAga2VlcE1hcmtzPzogYm9vbGVhbixcbiAgICAgICAgYXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlSW5uZXJTZWxlY3Rpb25Gb3JXaG9sZURvY0xpc3QodHI6IFRyYW5zYWN0aW9uKSB7XG4gIGNvbnN0IGRvYyA9IHRyLmRvY1xuICBjb25zdCBsaXN0ID0gZG9jLmZpcnN0Q2hpbGRcblxuICBpZiAoIWxpc3QpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLy8gUGxhY2UgdGhlIHNlbGVjdGlvbiBpbnNpZGUgdGhlIGxpc3Qgbm9kZSBzbyB0aGF0IFByb3NlTWlycm9yJ3NcbiAgLy8gbGlmdExpc3RJdGVtIGNvbW1hbmQgY2FuIG9wZXJhdGUuIEFsbFNlbGVjdGlvbiBzaXRzIGF0IHRoZSBkb2Mgcm9vdC5cbiAgLy8gVXNlIFRleHRTZWxlY3Rpb24uYmV0d2VlbiB0byByZXNvbHZlIHBvc2l0aW9ucyBpbnRvIHZhbGlkIGlubGluZVxuICAvLyBjb250ZW50IHBvc2l0aW9ucywgc28gdGhlIHNlbGVjdGlvbiBzdXJ2aXZlcyBwb3NpdGlvbiBtYXBwaW5nIGFmdGVyXG4gIC8vIGxpZnRMaXN0SXRlbSByZW1vdmVzIGxpc3QvaXRlbSB3cmFwcGVycy5cbiAgY29uc3QgJHN0YXJ0ID0gZG9jLnJlc29sdmUoMSlcbiAgY29uc3QgJGVuZCA9IGRvYy5yZXNvbHZlKGxpc3Qubm9kZVNpemUgLSAxKVxuXG4gIHJldHVybiBUZXh0U2VsZWN0aW9uLmJldHdlZW4oJHN0YXJ0LCAkZW5kKVxufVxuZXhwb3J0IGNvbnN0IHRvZ2dsZUxpc3Q6IFJhd0NvbW1hbmRzWyd0b2dnbGVMaXN0J10gPVxuICAobGlzdFR5cGVPck5hbWUsIGl0ZW1UeXBlT3JOYW1lLCBrZWVwTWFya3MsIGF0dHJpYnV0ZXMgPSB7fSkgPT5cbiAgKHsgZWRpdG9yLCB0ciwgc3RhdGUsIGRpc3BhdGNoLCBjaGFpbiwgY29tbWFuZHMsIGNhbiB9KSA9PiB7XG4gICAgY29uc3QgeyBleHRlbnNpb25zLCBzcGxpdHRhYmxlTWFya3MgfSA9IGVkaXRvci5leHRlbnNpb25NYW5hZ2VyXG4gICAgY29uc3QgbGlzdFR5cGUgPSBnZXROb2RlVHlwZShsaXN0VHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuICAgIGNvbnN0IGl0ZW1UeXBlID0gZ2V0Tm9kZVR5cGUoaXRlbVR5cGVPck5hbWUsIHN0YXRlLnNjaGVtYSlcbiAgICBjb25zdCB7IHNlbGVjdGlvbiwgc3RvcmVkTWFya3MgfSA9IHN0YXRlXG4gICAgY29uc3QgeyAkZnJvbSwgJHRvIH0gPSBzZWxlY3Rpb25cbiAgICBjb25zdCByYW5nZSA9ICRmcm9tLmJsb2NrUmFuZ2UoJHRvKVxuXG4gICAgY29uc3QgbWFya3MgPSBzdG9yZWRNYXJrcyB8fCAoc2VsZWN0aW9uLiR0by5wYXJlbnRPZmZzZXQgJiYgc2VsZWN0aW9uLiRmcm9tLm1hcmtzKCkpXG5cbiAgICBpZiAoIXJhbmdlKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBjb25zdCBwYXJlbnRMaXN0ID0gZmluZFBhcmVudE5vZGUobm9kZSA9PiBpc0xpc3Qobm9kZS50eXBlLm5hbWUsIGV4dGVuc2lvbnMpKShzZWxlY3Rpb24pXG5cbiAgICAvLyBXaGVuIHRoZSB1c2VyIHByZXNzZXMgQ3RybC9DbWQrQSwgUHJvc2VNaXJyb3IgY3JlYXRlcyBhbiBgQWxsU2VsZWN0aW9uYFxuICAgIC8vIGNvdmVyaW5nIHRoZSBlbnRpcmUgZG9jdW1lbnQgKDAuLmRvYy5jb250ZW50LnNpemUpLiBJbiB0aGF0IGNhc2VcbiAgICAvLyBgZmluZFBhcmVudE5vZGVgIGNhbm5vdCBkZXRlY3QgdGhlIHN1cnJvdW5kaW5nIGxpc3QgYmVjYXVzZSB0aGVcbiAgICAvLyBzZWxlY3Rpb24gc2l0cyBhdCB0aGUgZG9jdW1lbnQgcm9vdC4gSWYgdGhlIGRvY3VtZW50IGNvbnNpc3RzIG9mIGFcbiAgICAvLyBzaW5nbGUgdG9wLWxldmVsIGxpc3Qgbm9kZSwgdHJlYXQgdGhhdCBsaXN0IGFzIHRoZSBhY3RpdmUgbGlzdCBzbyB0aGVcbiAgICAvLyB0b2dnbGUgbG9naWMgY2FuIGNvcnJlY3RseSBsaWZ0IG9yIGNoYW5nZSBpdC5cbiAgICBjb25zdCBpc0FsbFNlbGVjdGlvbiA9IHNlbGVjdGlvbi5mcm9tID09PSAwICYmIHNlbGVjdGlvbi50byA9PT0gc3RhdGUuZG9jLmNvbnRlbnQuc2l6ZVxuICAgIGNvbnN0IHRvcExldmVsTm9kZXMgPSBzdGF0ZS5kb2MuY29udGVudC5jb250ZW50XG4gICAgY29uc3Qgc29sZVRvcExldmVsTm9kZSA9IHRvcExldmVsTm9kZXMubGVuZ3RoID09PSAxID8gdG9wTGV2ZWxOb2Rlc1swXSA6IG51bGxcbiAgICBjb25zdCBhbGxTZWxlY3Rpb25MaXN0ID1cbiAgICAgIGlzQWxsU2VsZWN0aW9uICYmIHNvbGVUb3BMZXZlbE5vZGUgJiYgaXNMaXN0KHNvbGVUb3BMZXZlbE5vZGUudHlwZS5uYW1lLCBleHRlbnNpb25zKVxuICAgICAgICA/IHtcbiAgICAgICAgICAgIG5vZGU6IHNvbGVUb3BMZXZlbE5vZGUsXG4gICAgICAgICAgICBwb3M6IDAsXG4gICAgICAgICAgICBkZXB0aDogMCxcbiAgICAgICAgICB9XG4gICAgICAgIDogbnVsbFxuXG4gICAgY29uc3QgY3VycmVudExpc3QgPSBwYXJlbnRMaXN0ID8/IGFsbFNlbGVjdGlvbkxpc3RcblxuICAgIGNvbnN0IGlzSW5zaWRlRXhpc3RpbmdMaXN0ID1cbiAgICAgICEhcGFyZW50TGlzdCAmJiByYW5nZS5kZXB0aCA+PSAxICYmIHJhbmdlLmRlcHRoIC0gcGFyZW50TGlzdC5kZXB0aCA8PSAxXG5cbiAgICBjb25zdCBoYXNXaG9sZURvY1NlbGVjdGVkTGlzdCA9ICEhYWxsU2VsZWN0aW9uTGlzdFxuICAgIGlmICgoaXNJbnNpZGVFeGlzdGluZ0xpc3QgfHwgaGFzV2hvbGVEb2NTZWxlY3RlZExpc3QpICYmIGN1cnJlbnRMaXN0KSB7XG4gICAgICAvLyByZW1vdmUgbGlzdFxuICAgICAgaWYgKGN1cnJlbnRMaXN0Lm5vZGUudHlwZSA9PT0gbGlzdFR5cGUpIHtcbiAgICAgICAgaWYgKGlzQWxsU2VsZWN0aW9uICYmIGhhc1dob2xlRG9jU2VsZWN0ZWRMaXN0KSB7XG4gICAgICAgICAgcmV0dXJuIGNoYWluKClcbiAgICAgICAgICAgIC5jb21tYW5kKCh7IHRyOiB0cngsIGRpc3BhdGNoOiBkaXNwIH0pID0+IHtcbiAgICAgICAgICAgICAgLy8gQ3RybC9DbWQrQSBjcmVhdGVzIGFuIEFsbFNlbGVjdGlvbiBhdCB0aGUgZG9jdW1lbnQgcm9vdC5cbiAgICAgICAgICAgICAgLy8gV2hlbiB0aGUgd2hvbGUgZG9jdW1lbnQgaXMgYSBzaW5nbGUgdG9wLWxldmVsIGxpc3QsIG5vcm1hbGl6ZSB0aGVcbiAgICAgICAgICAgICAgLy8gc2VsZWN0aW9uIGludG8gdGhhdCBsaXN0IGJlZm9yZSBsaWZ0aW5nLCBzaW5jZSBsaWZ0TGlzdEl0ZW0gZXhwZWN0c1xuICAgICAgICAgICAgICAvLyBhIHNlbGVjdGlvbiBpbnNpZGUgYSBsaXN0IGl0ZW0uXG4gICAgICAgICAgICAgIGNvbnN0IG5leHRTZWxlY3Rpb24gPSBjcmVhdGVJbm5lclNlbGVjdGlvbkZvcldob2xlRG9jTGlzdCh0cngpXG5cbiAgICAgICAgICAgICAgaWYgKCFuZXh0U2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICB0cnguc2V0U2VsZWN0aW9uKG5leHRTZWxlY3Rpb24pXG5cbiAgICAgICAgICAgICAgaWYgKGRpc3ApIHtcbiAgICAgICAgICAgICAgICBkaXNwKHRyeClcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmxpZnRMaXN0SXRlbShpdGVtVHlwZSlcbiAgICAgICAgICAgIC5ydW4oKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbW1hbmRzLmxpZnRMaXN0SXRlbShpdGVtVHlwZSlcbiAgICAgIH1cblxuICAgICAgLy8gY2hhbmdlIGxpc3QgdHlwZVxuICAgICAgaWYgKFxuICAgICAgICBpc0xpc3QoY3VycmVudExpc3Qubm9kZS50eXBlLm5hbWUsIGV4dGVuc2lvbnMpICYmXG4gICAgICAgIGxpc3RUeXBlLnZhbGlkQ29udGVudChjdXJyZW50TGlzdC5ub2RlLmNvbnRlbnQpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIGNoYWluKClcbiAgICAgICAgICAuY29tbWFuZCgoKSA9PiB7XG4gICAgICAgICAgICB0ci5zZXROb2RlTWFya3VwKGN1cnJlbnRMaXN0LnBvcywgbGlzdFR5cGUpXG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY29tbWFuZCgoKSA9PiBqb2luTGlzdEJhY2t3YXJkcyh0ciwgbGlzdFR5cGUpKVxuICAgICAgICAgIC5jb21tYW5kKCgpID0+IGpvaW5MaXN0Rm9yd2FyZHModHIsIGxpc3RUeXBlKSlcbiAgICAgICAgICAucnVuKClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWtlZXBNYXJrcyB8fCAhbWFya3MgfHwgIWRpc3BhdGNoKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBjaGFpbigpXG4gICAgICAgICAgLy8gdHJ5IHRvIGNvbnZlcnQgbm9kZSB0byBkZWZhdWx0IG5vZGUgaWYgbmVlZGVkXG4gICAgICAgICAgLmNvbW1hbmQoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2FuV3JhcEluTGlzdCA9IGNhbigpLndyYXBJbkxpc3QobGlzdFR5cGUsIGF0dHJpYnV0ZXMpXG4gICAgICAgICAgICBpZiAoY2FuV3JhcEluTGlzdCkge1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLmNsZWFyTm9kZXMoKVxuICAgICAgICAgIH0pXG4gICAgICAgICAgLndyYXBJbkxpc3QobGlzdFR5cGUsIGF0dHJpYnV0ZXMpXG4gICAgICAgICAgLmNvbW1hbmQoKCkgPT4gam9pbkxpc3RCYWNrd2FyZHModHIsIGxpc3RUeXBlKSlcbiAgICAgICAgICAuY29tbWFuZCgoKSA9PiBqb2luTGlzdEZvcndhcmRzKHRyLCBsaXN0VHlwZSkpXG4gICAgICAgICAgLnJ1bigpXG4gICAgICApXG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIGNoYWluKClcbiAgICAgICAgLy8gdHJ5IHRvIGNvbnZlcnQgbm9kZSB0byBkZWZhdWx0IG5vZGUgaWYgbmVlZGVkXG4gICAgICAgIC5jb21tYW5kKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBjYW5XcmFwSW5MaXN0ID0gY2FuKCkud3JhcEluTGlzdChsaXN0VHlwZSwgYXR0cmlidXRlcylcblxuICAgICAgICAgIGNvbnN0IGZpbHRlcmVkTWFya3MgPSBtYXJrcy5maWx0ZXIobWFyayA9PiBzcGxpdHRhYmxlTWFya3MuaW5jbHVkZXMobWFyay50eXBlLm5hbWUpKVxuXG4gICAgICAgICAgdHIuZW5zdXJlTWFya3MoZmlsdGVyZWRNYXJrcylcblxuICAgICAgICAgIGlmIChjYW5XcmFwSW5MaXN0KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gY29tbWFuZHMuY2xlYXJOb2RlcygpXG4gICAgICAgIH0pXG4gICAgICAgIC53cmFwSW5MaXN0KGxpc3RUeXBlLCBhdHRyaWJ1dGVzKVxuICAgICAgICAuY29tbWFuZCgoKSA9PiBqb2luTGlzdEJhY2t3YXJkcyh0ciwgbGlzdFR5cGUpKVxuICAgICAgICAuY29tbWFuZCgoKSA9PiBqb2luTGlzdEZvcndhcmRzKHRyLCBsaXN0VHlwZSkpXG4gICAgICAgIC5ydW4oKVxuICAgIClcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgTWFya1R5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXRNYXJrVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0TWFya1R5cGUuanMnXG5pbXBvcnQgeyBpc01hcmtBY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL2lzTWFya0FjdGl2ZS5qcydcbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHRvZ2dsZU1hcms6IHtcbiAgICAgIC8qKlxuICAgICAgICogVG9nZ2xlIGEgbWFyayBvbiBhbmQgb2ZmLlxuICAgICAgICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIG1hcmsgdHlwZSBvciBuYW1lLlxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG1hcmsuXG4gICAgICAgKiBAcGFyYW0gb3B0aW9ucy5leHRlbmRFbXB0eU1hcmtSYW5nZSBSZW1vdmVzIHRoZSBtYXJrIGV2ZW4gYWNyb3NzIHRoZSBjdXJyZW50IHNlbGVjdGlvbi4gRGVmYXVsdHMgdG8gYGZhbHNlYC5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVNYXJrKCdib2xkJylcbiAgICAgICAqL1xuICAgICAgdG9nZ2xlTWFyazogKFxuICAgICAgICAvKipcbiAgICAgICAgICogVGhlIG1hcmsgdHlwZSBvciBuYW1lLlxuICAgICAgICAgKi9cbiAgICAgICAgdHlwZU9yTmFtZTogc3RyaW5nIHwgTWFya1R5cGUsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBtYXJrLlxuICAgICAgICAgKi9cbiAgICAgICAgYXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIGFueT4sXG5cbiAgICAgICAgb3B0aW9ucz86IHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBSZW1vdmVzIHRoZSBtYXJrIGV2ZW4gYWNyb3NzIHRoZSBjdXJyZW50IHNlbGVjdGlvbi4gRGVmYXVsdHMgdG8gYGZhbHNlYC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBleHRlbmRFbXB0eU1hcmtSYW5nZT86IGJvb2xlYW5cbiAgICAgICAgfSxcbiAgICAgICkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgdG9nZ2xlTWFyazogUmF3Q29tbWFuZHNbJ3RvZ2dsZU1hcmsnXSA9XG4gICh0eXBlT3JOYW1lLCBhdHRyaWJ1dGVzID0ge30sIG9wdGlvbnMgPSB7fSkgPT5cbiAgKHsgc3RhdGUsIGNvbW1hbmRzIH0pID0+IHtcbiAgICBjb25zdCB7IGV4dGVuZEVtcHR5TWFya1JhbmdlID0gZmFsc2UgfSA9IG9wdGlvbnNcbiAgICBjb25zdCB0eXBlID0gZ2V0TWFya1R5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuICAgIGNvbnN0IGlzQWN0aXZlID0gaXNNYXJrQWN0aXZlKHN0YXRlLCB0eXBlLCBhdHRyaWJ1dGVzKVxuXG4gICAgaWYgKGlzQWN0aXZlKSB7XG4gICAgICByZXR1cm4gY29tbWFuZHMudW5zZXRNYXJrKHR5cGUsIHsgZXh0ZW5kRW1wdHlNYXJrUmFuZ2UgfSlcbiAgICB9XG5cbiAgICByZXR1cm4gY29tbWFuZHMuc2V0TWFyayh0eXBlLCBhdHRyaWJ1dGVzKVxuICB9XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IGdldE5vZGVUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXROb2RlVHlwZS5qcydcbmltcG9ydCB7IGlzTm9kZUFjdGl2ZSB9IGZyb20gJy4uL2hlbHBlcnMvaXNOb2RlQWN0aXZlLmpzJ1xuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgdG9nZ2xlTm9kZToge1xuICAgICAgLyoqXG4gICAgICAgKiBUb2dnbGUgYSBub2RlIHdpdGggYW5vdGhlciBub2RlLlxuICAgICAgICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIHR5cGUgb3IgbmFtZSBvZiB0aGUgbm9kZS5cbiAgICAgICAqIEBwYXJhbSB0b2dnbGVUeXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUgdG8gdG9nZ2xlLlxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudG9nZ2xlTm9kZSgnaGVhZGluZycsICdwYXJhZ3JhcGgnKVxuICAgICAgICovXG4gICAgICB0b2dnbGVOb2RlOiAoXG4gICAgICAgIHR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlLFxuICAgICAgICB0b2dnbGVUeXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSxcbiAgICAgICAgYXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHRvZ2dsZU5vZGU6IFJhd0NvbW1hbmRzWyd0b2dnbGVOb2RlJ10gPVxuICAodHlwZU9yTmFtZSwgdG9nZ2xlVHlwZU9yTmFtZSwgYXR0cmlidXRlcyA9IHt9KSA9PlxuICAoeyBzdGF0ZSwgY29tbWFuZHMgfSkgPT4ge1xuICAgIGNvbnN0IHR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gICAgY29uc3QgdG9nZ2xlVHlwZSA9IGdldE5vZGVUeXBlKHRvZ2dsZVR5cGVPck5hbWUsIHN0YXRlLnNjaGVtYSlcbiAgICBjb25zdCBpc0FjdGl2ZSA9IGlzTm9kZUFjdGl2ZShzdGF0ZSwgdHlwZSwgYXR0cmlidXRlcylcblxuICAgIGxldCBhdHRyaWJ1dGVzVG9Db3B5OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgdW5kZWZpbmVkXG5cbiAgICBpZiAoc3RhdGUuc2VsZWN0aW9uLiRhbmNob3Iuc2FtZVBhcmVudChzdGF0ZS5zZWxlY3Rpb24uJGhlYWQpKSB7XG4gICAgICAvLyBvbmx5IGNvcHkgYXR0cmlidXRlcyBpZiB0aGUgc2VsZWN0aW9uIGlzIHBvaW50aW5nIHRvIGEgbm9kZSBvZiB0aGUgc2FtZSB0eXBlXG4gICAgICBhdHRyaWJ1dGVzVG9Db3B5ID0gc3RhdGUuc2VsZWN0aW9uLiRhbmNob3IucGFyZW50LmF0dHJzXG4gICAgfVxuXG4gICAgaWYgKGlzQWN0aXZlKSB7XG4gICAgICByZXR1cm4gY29tbWFuZHMuc2V0Tm9kZSh0b2dnbGVUeXBlLCBhdHRyaWJ1dGVzVG9Db3B5KVxuICAgIH1cblxuICAgIC8vIElmIHRoZSBub2RlIGlzIG5vdCBhY3RpdmUsIHdlIHdhbnQgdG8gc2V0IHRoZSBuZXcgbm9kZSB0eXBlIHdpdGggdGhlIGdpdmVuIGF0dHJpYnV0ZXNcbiAgICAvLyBDb3B5aW5nIG92ZXIgdGhlIGF0dHJpYnV0ZXMgZnJvbSB0aGUgY3VycmVudCBub2RlIGlmIHRoZSBzZWxlY3Rpb24gaXMgcG9pbnRpbmcgdG8gYSBub2RlIG9mIHRoZSBzYW1lIHR5cGVcbiAgICByZXR1cm4gY29tbWFuZHMuc2V0Tm9kZSh0eXBlLCB7IC4uLmF0dHJpYnV0ZXNUb0NvcHksIC4uLmF0dHJpYnV0ZXMgfSlcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBpc05vZGVBY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL2lzTm9kZUFjdGl2ZS5qcydcbmltcG9ydCB0eXBlIHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHRvZ2dsZVdyYXA6IHtcbiAgICAgIC8qKlxuICAgICAgICogV3JhcHMgbm9kZXMgaW4gYW5vdGhlciBub2RlLCBvciByZW1vdmVzIGFuIGV4aXN0aW5nIHdyYXAuXG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBub2RlLlxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudG9nZ2xlV3JhcCgnYmxvY2txdW90ZScpXG4gICAgICAgKi9cbiAgICAgIHRvZ2dsZVdyYXA6ICh0eXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSwgYXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIGFueT4pID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHRvZ2dsZVdyYXA6IFJhd0NvbW1hbmRzWyd0b2dnbGVXcmFwJ10gPVxuICAodHlwZU9yTmFtZSwgYXR0cmlidXRlcyA9IHt9KSA9PlxuICAoeyBzdGF0ZSwgY29tbWFuZHMgfSkgPT4ge1xuICAgIGNvbnN0IHR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gICAgY29uc3QgaXNBY3RpdmUgPSBpc05vZGVBY3RpdmUoc3RhdGUsIHR5cGUsIGF0dHJpYnV0ZXMpXG5cbiAgICBpZiAoaXNBY3RpdmUpIHtcbiAgICAgIHJldHVybiBjb21tYW5kcy5saWZ0KHR5cGUpXG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbW1hbmRzLndyYXBJbih0eXBlLCBhdHRyaWJ1dGVzKVxuICB9XG4iLCAiaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgdW5kb0lucHV0UnVsZToge1xuICAgICAgLyoqXG4gICAgICAgKiBVbmRvIGFuIGlucHV0IHJ1bGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudW5kb0lucHV0UnVsZSgpXG4gICAgICAgKi9cbiAgICAgIHVuZG9JbnB1dFJ1bGU6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHVuZG9JbnB1dFJ1bGU6IFJhd0NvbW1hbmRzWyd1bmRvSW5wdXRSdWxlJ10gPVxuICAoKSA9PlxuICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgIGNvbnN0IHBsdWdpbnMgPSBzdGF0ZS5wbHVnaW5zXG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBsdWdpbnMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0IHBsdWdpbiA9IHBsdWdpbnNbaV1cbiAgICAgIGxldCB1bmRvYWJsZVxuXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAvLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgIGlmIChwbHVnaW4uc3BlYy5pc0lucHV0UnVsZXMgJiYgKHVuZG9hYmxlID0gcGx1Z2luLmdldFN0YXRlKHN0YXRlKSkpIHtcbiAgICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgICAgY29uc3QgdHIgPSBzdGF0ZS50clxuICAgICAgICAgIGNvbnN0IHRvVW5kbyA9IHVuZG9hYmxlLnRyYW5zZm9ybVxuXG4gICAgICAgICAgZm9yIChsZXQgaiA9IHRvVW5kby5zdGVwcy5sZW5ndGggLSAxOyBqID49IDA7IGogLT0gMSkge1xuICAgICAgICAgICAgdHIuc3RlcCh0b1VuZG8uc3RlcHNbal0uaW52ZXJ0KHRvVW5kby5kb2NzW2pdKSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodW5kb2FibGUudGV4dCkge1xuICAgICAgICAgICAgY29uc3QgbWFya3MgPSB0ci5kb2MucmVzb2x2ZSh1bmRvYWJsZS5mcm9tKS5tYXJrcygpXG5cbiAgICAgICAgICAgIHRyLnJlcGxhY2VXaXRoKHVuZG9hYmxlLmZyb20sIHVuZG9hYmxlLnRvLCBzdGF0ZS5zY2hlbWEudGV4dCh1bmRvYWJsZS50ZXh0LCBtYXJrcykpXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRyLmRlbGV0ZSh1bmRvYWJsZS5mcm9tLCB1bmRvYWJsZS50bylcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG4iLCAiaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgdW5zZXRBbGxNYXJrczoge1xuICAgICAgLyoqXG4gICAgICAgKiBSZW1vdmUgYWxsIGNsZWFyYWJsZSBtYXJrcyBpbiB0aGUgY3VycmVudCBzZWxlY3Rpb24uXG4gICAgICAgKiBNYXJrcyB3aXRoIGBjbGVhcmFibGU6IGZhbHNlYCBhcmUgcHJlc2VydmVkXG4gICAgICAgKiBAcGFyYW0gb3B0aW9ucy5pZ25vcmVDbGVhcmFibGUgSWYgdHJ1ZSwgcmVtb3ZlcyBhbGwgbWFya3MgcmVnYXJkbGVzcyBvZiBgY2xlYXJhYmxlYCBzZXR0aW5nLiBEZWZhdWx0cyB0byBgZmFsc2VgLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnVuc2V0QWxsTWFya3MoKVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnVuc2V0QWxsTWFya3MoeyBpZ25vcmVDbGVhcmFibGU6IHRydWUgfSlcbiAgICAgICAqL1xuICAgICAgdW5zZXRBbGxNYXJrczogKG9wdGlvbnM/OiB7IGlnbm9yZUNsZWFyYWJsZT86IGJvb2xlYW4gfSkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgdW5zZXRBbGxNYXJrczogUmF3Q29tbWFuZHNbJ3Vuc2V0QWxsTWFya3MnXSA9XG4gIChvcHRpb25zID0ge30pID0+XG4gICh7IHRyLCBkaXNwYXRjaCwgZWRpdG9yIH0pID0+IHtcbiAgICBjb25zdCB7IGlnbm9yZUNsZWFyYWJsZSA9IGZhbHNlIH0gPSBvcHRpb25zXG4gICAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IHRyXG4gICAgY29uc3QgeyBlbXB0eSwgcmFuZ2VzIH0gPSBzZWxlY3Rpb25cblxuICAgIGlmIChlbXB0eSkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBjb25zdCB7IG5vbkNsZWFyYWJsZU1hcmtzIH0gPSBlZGl0b3IuZXh0ZW5zaW9uTWFuYWdlclxuXG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICBjb25zdCBjbGVhcmFibGVNYXJrVHlwZXMgPSBPYmplY3QudmFsdWVzKGVkaXRvci5zY2hlbWEubWFya3MpLmZpbHRlcihcbiAgICAgICAgbWFya1R5cGUgPT4gaWdub3JlQ2xlYXJhYmxlIHx8ICFub25DbGVhcmFibGVNYXJrcy5pbmNsdWRlcyhtYXJrVHlwZS5uYW1lKSxcbiAgICAgIClcblxuICAgICAgcmFuZ2VzLmZvckVhY2gocmFuZ2UgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IG1hcmtUeXBlIG9mIGNsZWFyYWJsZU1hcmtUeXBlcykge1xuICAgICAgICAgIHRyLnJlbW92ZU1hcmsocmFuZ2UuJGZyb20ucG9zLCByYW5nZS4kdG8ucG9zLCBtYXJrVHlwZSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG4iLCAiaW1wb3J0IHR5cGUgeyBNYXJrVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IGdldE1hcmtSYW5nZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0TWFya1JhbmdlLmpzJ1xuaW1wb3J0IHsgZ2V0TWFya1R5cGUgfSBmcm9tICcuLi9oZWxwZXJzL2dldE1hcmtUeXBlLmpzJ1xuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgdW5zZXRNYXJrOiB7XG4gICAgICAvKipcbiAgICAgICAqIFJlbW92ZSBhbGwgbWFya3MgaW4gdGhlIGN1cnJlbnQgc2VsZWN0aW9uLlxuICAgICAgICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIG1hcmsgdHlwZSBvciBuYW1lLlxuICAgICAgICogQHBhcmFtIG9wdGlvbnMuZXh0ZW5kRW1wdHlNYXJrUmFuZ2UgUmVtb3ZlcyB0aGUgbWFyayBldmVuIGFjcm9zcyB0aGUgY3VycmVudCBzZWxlY3Rpb24uIERlZmF1bHRzIHRvIGBmYWxzZWAuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudW5zZXRNYXJrKCdib2xkJylcbiAgICAgICAqL1xuICAgICAgdW5zZXRNYXJrOiAoXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbWFyayB0eXBlIG9yIG5hbWUuXG4gICAgICAgICAqL1xuICAgICAgICB0eXBlT3JOYW1lOiBzdHJpbmcgfCBNYXJrVHlwZSxcblxuICAgICAgICBvcHRpb25zPzoge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFJlbW92ZXMgdGhlIG1hcmsgZXZlbiBhY3Jvc3MgdGhlIGN1cnJlbnQgc2VsZWN0aW9uLiBEZWZhdWx0cyB0byBgZmFsc2VgLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGV4dGVuZEVtcHR5TWFya1JhbmdlPzogYm9vbGVhblxuICAgICAgICB9LFxuICAgICAgKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCB1bnNldE1hcms6IFJhd0NvbW1hbmRzWyd1bnNldE1hcmsnXSA9XG4gICh0eXBlT3JOYW1lLCBvcHRpb25zID0ge30pID0+XG4gICh7IHRyLCBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgIGNvbnN0IHsgZXh0ZW5kRW1wdHlNYXJrUmFuZ2UgPSBmYWxzZSB9ID0gb3B0aW9uc1xuICAgIGNvbnN0IHsgc2VsZWN0aW9uIH0gPSB0clxuICAgIGNvbnN0IHR5cGUgPSBnZXRNYXJrVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gICAgY29uc3QgeyAkZnJvbSwgZW1wdHksIHJhbmdlcyB9ID0gc2VsZWN0aW9uXG5cbiAgICBpZiAoIWRpc3BhdGNoKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGlmIChlbXB0eSAmJiBleHRlbmRFbXB0eU1hcmtSYW5nZSkge1xuICAgICAgbGV0IHsgZnJvbSwgdG8gfSA9IHNlbGVjdGlvblxuICAgICAgY29uc3QgYXR0cnMgPSAkZnJvbS5tYXJrcygpLmZpbmQobWFyayA9PiBtYXJrLnR5cGUgPT09IHR5cGUpPy5hdHRyc1xuICAgICAgY29uc3QgcmFuZ2UgPSBnZXRNYXJrUmFuZ2UoJGZyb20sIHR5cGUsIGF0dHJzKVxuXG4gICAgICBpZiAocmFuZ2UpIHtcbiAgICAgICAgZnJvbSA9IHJhbmdlLmZyb21cbiAgICAgICAgdG8gPSByYW5nZS50b1xuICAgICAgfVxuXG4gICAgICB0ci5yZW1vdmVNYXJrKGZyb20sIHRvLCB0eXBlKVxuICAgIH0gZWxzZSB7XG4gICAgICByYW5nZXMuZm9yRWFjaChyYW5nZSA9PiB7XG4gICAgICAgIHRyLnJlbW92ZU1hcmsocmFuZ2UuJGZyb20ucG9zLCByYW5nZS4kdG8ucG9zLCB0eXBlKVxuICAgICAgfSlcbiAgICB9XG5cbiAgICB0ci5yZW1vdmVTdG9yZWRNYXJrKHR5cGUpXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG4iLCAiaW1wb3J0IHR5cGUgeyBSYW5nZSwgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHVuc2V0VGV4dERpcmVjdGlvbjoge1xuICAgICAgLyoqXG4gICAgICAgKiBSZW1vdmUgdGhlIHRleHQgZGlyZWN0aW9uIGF0dHJpYnV0ZSBmcm9tIG5vZGVzLlxuICAgICAgICogSWYgbm8gcG9zaXRpb24gaXMgcHJvdmlkZWQsIGl0IHdpbGwgdXNlIHRoZSBjdXJyZW50IHNlbGVjdGlvbi5cbiAgICAgICAqIEBwYXJhbSBwb3NpdGlvbiBPcHRpb25hbCBwb3NpdGlvbiBvciByYW5nZSB0byByZW1vdmUgdGhlIGRpcmVjdGlvbiBmcm9tXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudW5zZXRUZXh0RGlyZWN0aW9uKClcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy51bnNldFRleHREaXJlY3Rpb24oeyBmcm9tOiAwLCB0bzogMTAgfSlcbiAgICAgICAqL1xuICAgICAgdW5zZXRUZXh0RGlyZWN0aW9uOiAocG9zaXRpb24/OiBudW1iZXIgfCBSYW5nZSkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgdW5zZXRUZXh0RGlyZWN0aW9uOiBSYXdDb21tYW5kc1sndW5zZXRUZXh0RGlyZWN0aW9uJ10gPVxuICBwb3NpdGlvbiA9PlxuICAoeyB0ciwgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gc3RhdGVcbiAgICBsZXQgZnJvbTogbnVtYmVyXG4gICAgbGV0IHRvOiBudW1iZXJcblxuICAgIGlmICh0eXBlb2YgcG9zaXRpb24gPT09ICdudW1iZXInKSB7XG4gICAgICBmcm9tID0gcG9zaXRpb25cbiAgICAgIHRvID0gcG9zaXRpb25cbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uICYmICdmcm9tJyBpbiBwb3NpdGlvbiAmJiAndG8nIGluIHBvc2l0aW9uKSB7XG4gICAgICBmcm9tID0gcG9zaXRpb24uZnJvbVxuICAgICAgdG8gPSBwb3NpdGlvbi50b1xuICAgIH0gZWxzZSB7XG4gICAgICBmcm9tID0gc2VsZWN0aW9uLmZyb21cbiAgICAgIHRvID0gc2VsZWN0aW9uLnRvXG4gICAgfVxuXG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICB0ci5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgIGlmIChub2RlLmlzVGV4dCkge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV3QXR0cnMgPSB7IC4uLm5vZGUuYXR0cnMgfVxuXG4gICAgICAgIGRlbGV0ZSBuZXdBdHRycy5kaXJcblxuICAgICAgICB0ci5zZXROb2RlTWFya3VwKHBvcywgdW5kZWZpbmVkLCBuZXdBdHRycylcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgTWFyaywgTWFya1R5cGUsIE5vZGUsIE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB0eXBlIHsgU2VsZWN0aW9uUmFuZ2UgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBnZXRNYXJrVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0TWFya1R5cGUuanMnXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBnZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUuanMnXG5pbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICB1cGRhdGVBdHRyaWJ1dGVzOiB7XG4gICAgICAvKipcbiAgICAgICAqIFVwZGF0ZSBhdHRyaWJ1dGVzIG9mIGEgbm9kZSBvciBtYXJrLlxuICAgICAgICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIHR5cGUgb3IgbmFtZSBvZiB0aGUgbm9kZSBvciBtYXJrLlxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG5vZGUgb3IgbWFyay5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy51cGRhdGVBdHRyaWJ1dGVzKCdtZW50aW9uJywgeyB1c2VySWQ6IFwiMlwiIH0pXG4gICAgICAgKi9cbiAgICAgIHVwZGF0ZUF0dHJpYnV0ZXM6IChcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUgb3IgbWFyay5cbiAgICAgICAgICovXG4gICAgICAgIHR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlIHwgTWFya1R5cGUsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBub2RlIG9yIG1hcmsuXG4gICAgICAgICAqL1xuICAgICAgICBhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgICAgKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCB1cGRhdGVBdHRyaWJ1dGVzOiBSYXdDb21tYW5kc1sndXBkYXRlQXR0cmlidXRlcyddID1cbiAgKHR5cGVPck5hbWUsIGF0dHJpYnV0ZXMgPSB7fSkgPT5cbiAgKHsgdHIsIHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgbGV0IG5vZGVUeXBlOiBOb2RlVHlwZSB8IG51bGwgPSBudWxsXG4gICAgbGV0IG1hcmtUeXBlOiBNYXJrVHlwZSB8IG51bGwgPSBudWxsXG5cbiAgICBjb25zdCBzY2hlbWFUeXBlID0gZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUoXG4gICAgICB0eXBlb2YgdHlwZU9yTmFtZSA9PT0gJ3N0cmluZycgPyB0eXBlT3JOYW1lIDogdHlwZU9yTmFtZS5uYW1lLFxuICAgICAgc3RhdGUuc2NoZW1hLFxuICAgIClcblxuICAgIGlmICghc2NoZW1hVHlwZSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKHNjaGVtYVR5cGUgPT09ICdub2RlJykge1xuICAgICAgbm9kZVR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lIGFzIE5vZGVUeXBlLCBzdGF0ZS5zY2hlbWEpXG4gICAgfVxuXG4gICAgaWYgKHNjaGVtYVR5cGUgPT09ICdtYXJrJykge1xuICAgICAgbWFya1R5cGUgPSBnZXRNYXJrVHlwZSh0eXBlT3JOYW1lIGFzIE1hcmtUeXBlLCBzdGF0ZS5zY2hlbWEpXG4gICAgfVxuXG4gICAgbGV0IGNhblVwZGF0ZSA9IGZhbHNlXG5cbiAgICB0ci5zZWxlY3Rpb24ucmFuZ2VzLmZvckVhY2goKHJhbmdlOiBTZWxlY3Rpb25SYW5nZSkgPT4ge1xuICAgICAgY29uc3QgZnJvbSA9IHJhbmdlLiRmcm9tLnBvc1xuICAgICAgY29uc3QgdG8gPSByYW5nZS4kdG8ucG9zXG5cbiAgICAgIGxldCBsYXN0UG9zOiBudW1iZXIgfCB1bmRlZmluZWRcbiAgICAgIGxldCBsYXN0Tm9kZTogTm9kZSB8IHVuZGVmaW5lZFxuICAgICAgbGV0IHRyaW1tZWRGcm9tOiBudW1iZXJcbiAgICAgIGxldCB0cmltbWVkVG86IG51bWJlclxuXG4gICAgICBpZiAodHIuc2VsZWN0aW9uLmVtcHR5KSB7XG4gICAgICAgIHN0YXRlLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlOiBOb2RlLCBwb3M6IG51bWJlcikgPT4ge1xuICAgICAgICAgIGlmIChub2RlVHlwZSAmJiBub2RlVHlwZSA9PT0gbm9kZS50eXBlKSB7XG4gICAgICAgICAgICBjYW5VcGRhdGUgPSB0cnVlXG4gICAgICAgICAgICB0cmltbWVkRnJvbSA9IE1hdGgubWF4KHBvcywgZnJvbSlcbiAgICAgICAgICAgIHRyaW1tZWRUbyA9IE1hdGgubWluKHBvcyArIG5vZGUubm9kZVNpemUsIHRvKVxuICAgICAgICAgICAgbGFzdFBvcyA9IHBvc1xuICAgICAgICAgICAgbGFzdE5vZGUgPSBub2RlXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhdGUuZG9jLm5vZGVzQmV0d2Vlbihmcm9tLCB0bywgKG5vZGU6IE5vZGUsIHBvczogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgaWYgKHBvcyA8IGZyb20gJiYgbm9kZVR5cGUgJiYgbm9kZVR5cGUgPT09IG5vZGUudHlwZSkge1xuICAgICAgICAgICAgY2FuVXBkYXRlID0gdHJ1ZVxuICAgICAgICAgICAgdHJpbW1lZEZyb20gPSBNYXRoLm1heChwb3MsIGZyb20pXG4gICAgICAgICAgICB0cmltbWVkVG8gPSBNYXRoLm1pbihwb3MgKyBub2RlLm5vZGVTaXplLCB0bylcbiAgICAgICAgICAgIGxhc3RQb3MgPSBwb3NcbiAgICAgICAgICAgIGxhc3ROb2RlID0gbm9kZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwb3MgPj0gZnJvbSAmJiBwb3MgPD0gdG8pIHtcbiAgICAgICAgICAgIGlmIChub2RlVHlwZSAmJiBub2RlVHlwZSA9PT0gbm9kZS50eXBlKSB7XG4gICAgICAgICAgICAgIGNhblVwZGF0ZSA9IHRydWVcblxuICAgICAgICAgICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgICAgICAgICB0ci5zZXROb2RlTWFya3VwKHBvcywgdW5kZWZpbmVkLCB7XG4gICAgICAgICAgICAgICAgICAuLi5ub2RlLmF0dHJzLFxuICAgICAgICAgICAgICAgICAgLi4uYXR0cmlidXRlcyxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtYXJrVHlwZSAmJiBub2RlLm1hcmtzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBub2RlLm1hcmtzLmZvckVhY2goKG1hcms6IE1hcmspID0+IHtcbiAgICAgICAgICAgICAgICBpZiAobWFya1R5cGUgPT09IG1hcmsudHlwZSkge1xuICAgICAgICAgICAgICAgICAgY2FuVXBkYXRlID0gdHJ1ZVxuXG4gICAgICAgICAgICAgICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdHJpbW1lZEZyb20yID0gTWF0aC5tYXgocG9zLCBmcm9tKVxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0cmltbWVkVG8yID0gTWF0aC5taW4ocG9zICsgbm9kZS5ub2RlU2l6ZSwgdG8pXG5cbiAgICAgICAgICAgICAgICAgICAgdHIuYWRkTWFyayhcbiAgICAgICAgICAgICAgICAgICAgICB0cmltbWVkRnJvbTIsXG4gICAgICAgICAgICAgICAgICAgICAgdHJpbW1lZFRvMixcbiAgICAgICAgICAgICAgICAgICAgICBtYXJrVHlwZS5jcmVhdGUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4ubWFyay5hdHRycyxcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmF0dHJpYnV0ZXMsXG4gICAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBpZiAobGFzdE5vZGUpIHtcbiAgICAgICAgaWYgKGxhc3RQb3MgIT09IHVuZGVmaW5lZCAmJiBkaXNwYXRjaCkge1xuICAgICAgICAgIHRyLnNldE5vZGVNYXJrdXAobGFzdFBvcywgdW5kZWZpbmVkLCB7XG4gICAgICAgICAgICAuLi5sYXN0Tm9kZS5hdHRycyxcbiAgICAgICAgICAgIC4uLmF0dHJpYnV0ZXMsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtYXJrVHlwZSAmJiBsYXN0Tm9kZS5tYXJrcy5sZW5ndGgpIHtcbiAgICAgICAgICBsYXN0Tm9kZS5tYXJrcy5mb3JFYWNoKChtYXJrOiBNYXJrKSA9PiB7XG4gICAgICAgICAgICBpZiAobWFya1R5cGUgPT09IG1hcmsudHlwZSAmJiBkaXNwYXRjaCkge1xuICAgICAgICAgICAgICB0ci5hZGRNYXJrKFxuICAgICAgICAgICAgICAgIHRyaW1tZWRGcm9tLFxuICAgICAgICAgICAgICAgIHRyaW1tZWRUbyxcbiAgICAgICAgICAgICAgICBtYXJrVHlwZS5jcmVhdGUoe1xuICAgICAgICAgICAgICAgICAgLi4ubWFyay5hdHRycyxcbiAgICAgICAgICAgICAgICAgIC4uLmF0dHJpYnV0ZXMsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcblxuICAgIHJldHVybiBjYW5VcGRhdGVcbiAgfVxuIiwgImltcG9ydCB7IHdyYXBJbiBhcyBvcmlnaW5hbFdyYXBJbiB9IGZyb20gJ0B0aXB0YXAvcG0vY29tbWFuZHMnXG5pbXBvcnQgdHlwZSB7IE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgZ2V0Tm9kZVR5cGUgfSBmcm9tICcuLi9oZWxwZXJzL2dldE5vZGVUeXBlLmpzJ1xuaW1wb3J0IHR5cGUgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgd3JhcEluOiB7XG4gICAgICAvKipcbiAgICAgICAqIFdyYXBzIG5vZGVzIGluIGFub3RoZXIgbm9kZS5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBvZiB0aGUgbm9kZS5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy53cmFwSW4oJ2Jsb2NrcXVvdGUnKVxuICAgICAgICovXG4gICAgICB3cmFwSW46ICh0eXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSwgYXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIGFueT4pID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHdyYXBJbjogUmF3Q29tbWFuZHNbJ3dyYXBJbiddID1cbiAgKHR5cGVPck5hbWUsIGF0dHJpYnV0ZXMgPSB7fSkgPT5cbiAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICBjb25zdCB0eXBlID0gZ2V0Tm9kZVR5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuXG4gICAgcmV0dXJuIG9yaWdpbmFsV3JhcEluKHR5cGUsIGF0dHJpYnV0ZXMpKHN0YXRlLCBkaXNwYXRjaClcbiAgfVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgd3JhcEluTGlzdCBhcyBvcmlnaW5hbFdyYXBJbkxpc3QgfSBmcm9tICdAdGlwdGFwL3BtL3NjaGVtYS1saXN0J1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgdHlwZSB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICB3cmFwSW5MaXN0OiB7XG4gICAgICAvKipcbiAgICAgICAqIFdyYXAgYSBub2RlIGluIGEgbGlzdC5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBvZiB0aGUgbm9kZS5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy53cmFwSW5MaXN0KCdidWxsZXRMaXN0JylcbiAgICAgICAqL1xuICAgICAgd3JhcEluTGlzdDogKHR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlLCBhdHRyaWJ1dGVzPzogUmVjb3JkPHN0cmluZywgYW55PikgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgd3JhcEluTGlzdDogUmF3Q29tbWFuZHNbJ3dyYXBJbkxpc3QnXSA9XG4gICh0eXBlT3JOYW1lLCBhdHRyaWJ1dGVzID0ge30pID0+XG4gICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgY29uc3QgdHlwZSA9IGdldE5vZGVUeXBlKHR5cGVPck5hbWUsIHN0YXRlLnNjaGVtYSlcblxuICAgIHJldHVybiBvcmlnaW5hbFdyYXBJbkxpc3QodHlwZSwgYXR0cmlidXRlcykoc3RhdGUsIGRpc3BhdGNoKVxuICB9XG4iLCAiLyogb3NsaW50LWRpc2FibGVuby1lbXB0eS1vYmplY3QtdHlwZSAqL1xuaW1wb3J0IHR5cGUgeyBNYXJrVHlwZSwgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUsIE5vZGVUeXBlLCBTY2hlbWEgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHR5cGUgeyBQbHVnaW4sIFBsdWdpbktleSwgVHJhbnNhY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHsgdHlwZSBEaXJlY3RFZGl0b3JQcm9wcywgRWRpdG9yVmlldyB9IGZyb20gJ0B0aXB0YXAvcG0vdmlldydcblxuaW1wb3J0IHsgQ29tbWFuZE1hbmFnZXIgfSBmcm9tICcuL0NvbW1hbmRNYW5hZ2VyLmpzJ1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnLi9FdmVudEVtaXR0ZXIuanMnXG5pbXBvcnQgeyBFeHRlbnNpb25NYW5hZ2VyIH0gZnJvbSAnLi9FeHRlbnNpb25NYW5hZ2VyLmpzJ1xuaW1wb3J0IHtcbiAgQ2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXIsXG4gIENvbW1hbmRzLFxuICBEZWxldGUsXG4gIERyb3AsXG4gIEVkaXRhYmxlLFxuICBGb2N1c0V2ZW50cyxcbiAgS2V5bWFwLFxuICBQYXN0ZSxcbiAgVGFiaW5kZXgsXG4gIFRleHREaXJlY3Rpb24sXG59IGZyb20gJy4vZXh0ZW5zaW9ucy9pbmRleC5qcydcbmltcG9ydCB7IGNyZWF0ZURvY3VtZW50IH0gZnJvbSAnLi9oZWxwZXJzL2NyZWF0ZURvY3VtZW50LmpzJ1xuaW1wb3J0IHsgZ2V0QXR0cmlidXRlcyB9IGZyb20gJy4vaGVscGVycy9nZXRBdHRyaWJ1dGVzLmpzJ1xuaW1wb3J0IHsgZ2V0SFRNTEZyb21GcmFnbWVudCB9IGZyb20gJy4vaGVscGVycy9nZXRIVE1MRnJvbUZyYWdtZW50LmpzJ1xuaW1wb3J0IHsgZ2V0VGV4dCB9IGZyb20gJy4vaGVscGVycy9nZXRUZXh0LmpzJ1xuaW1wb3J0IHsgZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYSB9IGZyb20gJy4vaGVscGVycy9nZXRUZXh0U2VyaWFsaXplcnNGcm9tU2NoZW1hLmpzJ1xuaW1wb3J0IHsgaXNBY3RpdmUgfSBmcm9tICcuL2hlbHBlcnMvaXNBY3RpdmUuanMnXG5pbXBvcnQgeyBpc05vZGVFbXB0eSB9IGZyb20gJy4vaGVscGVycy9pc05vZGVFbXB0eS5qcydcbmltcG9ydCB7IGNyZWF0ZU1hcHBhYmxlUG9zaXRpb24sIGdldFVwZGF0ZWRQb3NpdGlvbiB9IGZyb20gJy4vaGVscGVycy9NYXBwYWJsZVBvc2l0aW9uLmpzJ1xuaW1wb3J0IHsgcmVzb2x2ZUZvY3VzUG9zaXRpb24gfSBmcm9tICcuL2hlbHBlcnMvcmVzb2x2ZUZvY3VzUG9zaXRpb24uanMnXG5pbXBvcnQgdHlwZSB7IFN0b3JhZ2UgfSBmcm9tICcuL2luZGV4LmpzJ1xuaW1wb3J0IHsgTm9kZVBvcyB9IGZyb20gJy4vTm9kZVBvcy5qcydcbmltcG9ydCB7IHN0eWxlIH0gZnJvbSAnLi9zdHlsZS5qcydcbmltcG9ydCB0eXBlIHtcbiAgQ2FuQ29tbWFuZHMsXG4gIENoYWluZWRDb21tYW5kcyxcbiAgRG9jdW1lbnRUeXBlLFxuICBFZGl0b3JFdmVudHMsXG4gIEVkaXRvck9wdGlvbnMsXG4gIE5vZGVUeXBlIGFzIFROb2RlVHlwZSxcbiAgU2luZ2xlQ29tbWFuZHMsXG4gIFRleHRTZXJpYWxpemVyLFxuICBUZXh0VHlwZSBhcyBUVGV4dFR5cGUsXG4gIFV0aWxzLFxufSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHsgY3JlYXRlU3R5bGVUYWcgfSBmcm9tICcuL3V0aWxpdGllcy9jcmVhdGVTdHlsZVRhZy5qcydcbmltcG9ydCB7IGlzRnVuY3Rpb24gfSBmcm9tICcuL3V0aWxpdGllcy9pc0Z1bmN0aW9uLmpzJ1xuXG5leHBvcnQgKiBhcyBleHRlbnNpb25zIGZyb20gJy4vZXh0ZW5zaW9ucy9pbmRleC5qcydcblxuLy8gQHRzLWlnbm9yZVxuZXhwb3J0IGludGVyZmFjZSBUaXB0YXBFZGl0b3JIVE1MRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHtcbiAgZWRpdG9yPzogRWRpdG9yXG59XG5cbmV4cG9ydCBjbGFzcyBFZGl0b3IgZXh0ZW5kcyBFdmVudEVtaXR0ZXI8RWRpdG9yRXZlbnRzPiB7XG4gIHByaXZhdGUgY29tbWFuZE1hbmFnZXIhOiBDb21tYW5kTWFuYWdlclxuXG4gIHB1YmxpYyBleHRlbnNpb25NYW5hZ2VyITogRXh0ZW5zaW9uTWFuYWdlclxuXG4gIHByaXZhdGUgY3NzOiBIVE1MU3R5bGVFbGVtZW50IHwgbnVsbCA9IG51bGxcblxuICBwcml2YXRlIGNsYXNzTmFtZSA9ICd0aXB0YXAnXG5cbiAgcHVibGljIHNjaGVtYSE6IFNjaGVtYVxuXG4gIHByaXZhdGUgZWRpdG9yVmlldzogRWRpdG9yVmlldyB8IG51bGwgPSBudWxsXG5cbiAgcHVibGljIGlzRm9jdXNlZCA9IGZhbHNlXG5cbiAgcHJpdmF0ZSBkZXN0cm95ZWQgPSBmYWxzZVxuXG4gIHByaXZhdGUgZWRpdG9yU3RhdGUhOiBFZGl0b3JTdGF0ZVxuXG4gIC8qKlxuICAgKiBUaGUgZWRpdG9yIGlzIGNvbnNpZGVyZWQgaW5pdGlhbGl6ZWQgYWZ0ZXIgdGhlIGBjcmVhdGVgIGV2ZW50IGhhcyBiZWVuIGVtaXR0ZWQuXG4gICAqL1xuICBwdWJsaWMgaXNJbml0aWFsaXplZCA9IGZhbHNlXG5cbiAgcHVibGljIGV4dGVuc2lvblN0b3JhZ2U6IFN0b3JhZ2UgPSB7fSBhcyBTdG9yYWdlXG5cbiAgLyoqXG4gICAqIEEgdW5pcXVlIElEIGZvciB0aGlzIGVkaXRvciBpbnN0YW5jZS5cbiAgICovXG4gIHB1YmxpYyBpbnN0YW5jZUlkID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgOSlcblxuICBwdWJsaWMgb3B0aW9uczogRWRpdG9yT3B0aW9ucyA9IHtcbiAgICBlbGVtZW50OiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnID8gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JykgOiBudWxsLFxuICAgIGNvbnRlbnQ6ICcnLFxuICAgIGluamVjdENTUzogdHJ1ZSxcbiAgICBpbmplY3ROb25jZTogdW5kZWZpbmVkLFxuICAgIGV4dGVuc2lvbnM6IFtdLFxuICAgIGF1dG9mb2N1czogZmFsc2UsXG4gICAgZWRpdGFibGU6IHRydWUsXG4gICAgdGV4dERpcmVjdGlvbjogdW5kZWZpbmVkLFxuICAgIGVkaXRvclByb3BzOiB7fSxcbiAgICBwYXJzZU9wdGlvbnM6IHt9LFxuICAgIGNvcmVFeHRlbnNpb25PcHRpb25zOiB7fSxcbiAgICBlbmFibGVJbnB1dFJ1bGVzOiB0cnVlLFxuICAgIGVuYWJsZVBhc3RlUnVsZXM6IHRydWUsXG4gICAgZW5hYmxlQ29yZUV4dGVuc2lvbnM6IHRydWUsXG4gICAgZW5hYmxlQ29udGVudENoZWNrOiBmYWxzZSxcbiAgICBlbWl0Q29udGVudEVycm9yOiBmYWxzZSxcbiAgICBvbkJlZm9yZUNyZWF0ZTogKCkgPT4gbnVsbCxcbiAgICBvbkNyZWF0ZTogKCkgPT4gbnVsbCxcbiAgICBvbk1vdW50OiAoKSA9PiBudWxsLFxuICAgIG9uVW5tb3VudDogKCkgPT4gbnVsbCxcbiAgICBvblVwZGF0ZTogKCkgPT4gbnVsbCxcbiAgICBvblNlbGVjdGlvblVwZGF0ZTogKCkgPT4gbnVsbCxcbiAgICBvblRyYW5zYWN0aW9uOiAoKSA9PiBudWxsLFxuICAgIG9uRm9jdXM6ICgpID0+IG51bGwsXG4gICAgb25CbHVyOiAoKSA9PiBudWxsLFxuICAgIG9uRGVzdHJveTogKCkgPT4gbnVsbCxcbiAgICBvbkNvbnRlbnRFcnJvcjogKHsgZXJyb3IgfSkgPT4ge1xuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9LFxuICAgIG9uUGFzdGU6ICgpID0+IG51bGwsXG4gICAgb25Ecm9wOiAoKSA9PiBudWxsLFxuICAgIG9uRGVsZXRlOiAoKSA9PiBudWxsLFxuICAgIGVuYWJsZUV4dGVuc2lvbkRpc3BhdGNoVHJhbnNhY3Rpb246IHRydWUsXG4gIH1cblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBQYXJ0aWFsPEVkaXRvck9wdGlvbnM+ID0ge30pIHtcbiAgICBzdXBlcigpXG4gICAgdGhpcy5zZXRPcHRpb25zKG9wdGlvbnMpXG4gICAgdGhpcy5jcmVhdGVFeHRlbnNpb25NYW5hZ2VyKClcbiAgICB0aGlzLmNyZWF0ZUNvbW1hbmRNYW5hZ2VyKClcbiAgICB0aGlzLmNyZWF0ZVNjaGVtYSgpXG4gICAgdGhpcy5vbignYmVmb3JlQ3JlYXRlJywgdGhpcy5vcHRpb25zLm9uQmVmb3JlQ3JlYXRlKVxuICAgIHRoaXMuZW1pdCgnYmVmb3JlQ3JlYXRlJywgeyBlZGl0b3I6IHRoaXMgfSlcbiAgICB0aGlzLm9uKCdtb3VudCcsIHRoaXMub3B0aW9ucy5vbk1vdW50KVxuICAgIHRoaXMub24oJ3VubW91bnQnLCB0aGlzLm9wdGlvbnMub25Vbm1vdW50KVxuICAgIHRoaXMub24oJ2NvbnRlbnRFcnJvcicsIHRoaXMub3B0aW9ucy5vbkNvbnRlbnRFcnJvcilcbiAgICB0aGlzLm9uKCdjcmVhdGUnLCB0aGlzLm9wdGlvbnMub25DcmVhdGUpXG4gICAgdGhpcy5vbigndXBkYXRlJywgdGhpcy5vcHRpb25zLm9uVXBkYXRlKVxuICAgIHRoaXMub24oJ3NlbGVjdGlvblVwZGF0ZScsIHRoaXMub3B0aW9ucy5vblNlbGVjdGlvblVwZGF0ZSlcbiAgICB0aGlzLm9uKCd0cmFuc2FjdGlvbicsIHRoaXMub3B0aW9ucy5vblRyYW5zYWN0aW9uKVxuICAgIHRoaXMub24oJ2ZvY3VzJywgdGhpcy5vcHRpb25zLm9uRm9jdXMpXG4gICAgdGhpcy5vbignYmx1cicsIHRoaXMub3B0aW9ucy5vbkJsdXIpXG4gICAgdGhpcy5vbignZGVzdHJveScsIHRoaXMub3B0aW9ucy5vbkRlc3Ryb3kpXG4gICAgdGhpcy5vbignZHJvcCcsICh7IGV2ZW50LCBzbGljZSwgbW92ZWQgfSkgPT4gdGhpcy5vcHRpb25zLm9uRHJvcChldmVudCwgc2xpY2UsIG1vdmVkKSlcbiAgICB0aGlzLm9uKCdwYXN0ZScsICh7IGV2ZW50LCBzbGljZSB9KSA9PiB0aGlzLm9wdGlvbnMub25QYXN0ZShldmVudCwgc2xpY2UpKVxuICAgIHRoaXMub24oJ2RlbGV0ZScsIHRoaXMub3B0aW9ucy5vbkRlbGV0ZSlcblxuICAgIGNvbnN0IGluaXRpYWxEb2MgPSB0aGlzLmNyZWF0ZURvYygpXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gcmVzb2x2ZUZvY3VzUG9zaXRpb24oaW5pdGlhbERvYywgdGhpcy5vcHRpb25zLmF1dG9mb2N1cylcblxuICAgIC8vIFNldCBlZGl0b3Igc3RhdGUgaW1tZWRpYXRlbHksIHNvIHRoYXQgaXQncyBhdmFpbGFibGUgaW5kZXBlbmRlbnRseSBmcm9tIHRoZSB2aWV3XG4gICAgdGhpcy5lZGl0b3JTdGF0ZSA9IEVkaXRvclN0YXRlLmNyZWF0ZSh7XG4gICAgICBkb2M6IGluaXRpYWxEb2MsXG4gICAgICBzY2hlbWE6IHRoaXMuc2NoZW1hLFxuICAgICAgc2VsZWN0aW9uOiBzZWxlY3Rpb24gfHwgdW5kZWZpbmVkLFxuICAgIH0pXG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmVsZW1lbnQpIHtcbiAgICAgIHRoaXMubW91bnQodGhpcy5vcHRpb25zLmVsZW1lbnQpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaCB0aGUgZWRpdG9yIHRvIHRoZSBET00sIGNyZWF0aW5nIGEgbmV3IGVkaXRvciB2aWV3LlxuICAgKi9cbiAgcHVibGljIG1vdW50KGVsOiBOb25OdWxsYWJsZTxFZGl0b3JPcHRpb25zWydlbGVtZW50J10+ICYge30pIHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgW3RpcHRhcCBlcnJvcl06IFRoZSBlZGl0b3IgY2Fubm90IGJlIG1vdW50ZWQgYmVjYXVzZSB0aGVyZSBpcyBubyAnZG9jdW1lbnQnIGRlZmluZWQgaW4gdGhpcyBlbnZpcm9ubWVudC5gLFxuICAgICAgKVxuICAgIH1cbiAgICB0aGlzLmNyZWF0ZVZpZXcoZWwpXG4gICAgdGhpcy5lbWl0KCdtb3VudCcsIHsgZWRpdG9yOiB0aGlzIH0pXG5cbiAgICBpZiAodGhpcy5jc3MgJiYgIWRvY3VtZW50LmhlYWQuY29udGFpbnModGhpcy5jc3MpKSB7XG4gICAgICBkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKHRoaXMuY3NzKVxuICAgIH1cblxuICAgIHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmlzRGVzdHJveWVkKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmF1dG9mb2N1cyAhPT0gZmFsc2UgJiYgdGhpcy5vcHRpb25zLmF1dG9mb2N1cyAhPT0gbnVsbCkge1xuICAgICAgICB0aGlzLmNvbW1hbmRzLmZvY3VzKHRoaXMub3B0aW9ucy5hdXRvZm9jdXMpXG4gICAgICB9XG4gICAgICB0aGlzLmVtaXQoJ2NyZWF0ZScsIHsgZWRpdG9yOiB0aGlzIH0pXG4gICAgICB0aGlzLmlzSW5pdGlhbGl6ZWQgPSB0cnVlXG4gICAgfSwgMClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIGVkaXRvciBmcm9tIHRoZSBET00sIGJ1dCBzdGlsbCBhbGxvdyByZW1vdW50aW5nIGF0IGEgZGlmZmVyZW50IHBvaW50IGluIHRpbWVcbiAgICovXG4gIHB1YmxpYyB1bm1vdW50KCkge1xuICAgIGlmICh0aGlzLmVkaXRvclZpZXcpIHtcbiAgICAgIC8vIENsZWFudXAgb3VyIHJlZmVyZW5jZSB0byBwcmV2ZW50IGNpcmN1bGFyIHJlZmVyZW5jZXMgd2hpY2ggY2F1c2VkIG1lbW9yeSBsZWFrc1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgY29uc3QgZG9tID0gdGhpcy5lZGl0b3JWaWV3LmRvbSBhcyBUaXB0YXBFZGl0b3JIVE1MRWxlbWVudFxuXG4gICAgICBpZiAoZG9tPy5lZGl0b3IpIHtcbiAgICAgICAgZGVsZXRlIGRvbS5lZGl0b3JcbiAgICAgIH1cbiAgICAgIHRoaXMuZWRpdG9yVmlldy5kZXN0cm95KClcbiAgICB9XG4gICAgdGhpcy5lZGl0b3JWaWV3ID0gbnVsbFxuICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IGZhbHNlXG5cbiAgICAvLyBTYWZlbHkgcmVtb3ZlIENTUyBlbGVtZW50IHdpdGggZmFsbGJhY2sgZm9yIHRlc3QgZW52aXJvbm1lbnRzXG4gICAgLy8gT25seSByZW1vdmUgQ1NTIGlmIG5vIG90aGVyIGVkaXRvcnMgZXhpc3QgaW4gdGhlIGRvY3VtZW50IGFmdGVyIHVubW91bnRcbiAgICBpZiAodGhpcy5jc3MgJiYgIWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoYC4ke3RoaXMuY2xhc3NOYW1lfWApLmxlbmd0aCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmNzcy5yZW1vdmUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICB0aGlzLmNzcy5yZW1vdmUoKVxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuY3NzLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICB0aGlzLmNzcy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuY3NzKVxuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAvLyBTaWxlbnRseSBoYW5kbGUgYW55IHVuZXhwZWN0ZWQgRE9NIHJlbW92YWwgZXJyb3JzIGluIHRlc3QgZW52aXJvbm1lbnRzXG4gICAgICAgIGNvbnNvbGUud2FybignRmFpbGVkIHRvIHJlbW92ZSBDU1MgZWxlbWVudDonLCBlcnJvcilcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5jc3MgPSBudWxsXG4gICAgdGhpcy5lbWl0KCd1bm1vdW50JywgeyBlZGl0b3I6IHRoaXMgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBlZGl0b3Igc3RvcmFnZS5cbiAgICovXG4gIHB1YmxpYyBnZXQgc3RvcmFnZSgpOiBTdG9yYWdlIHtcbiAgICByZXR1cm4gdGhpcy5leHRlbnNpb25TdG9yYWdlXG4gIH1cblxuICAvKipcbiAgICogQW4gb2JqZWN0IG9mIGFsbCByZWdpc3RlcmVkIGNvbW1hbmRzLlxuICAgKi9cbiAgcHVibGljIGdldCBjb21tYW5kcygpOiBTaW5nbGVDb21tYW5kcyB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZE1hbmFnZXIuY29tbWFuZHNcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBjb21tYW5kIGNoYWluIHRvIGNhbGwgbXVsdGlwbGUgY29tbWFuZHMgYXQgb25jZS5cbiAgICovXG4gIHB1YmxpYyBjaGFpbigpOiBDaGFpbmVkQ29tbWFuZHMge1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmRNYW5hZ2VyLmNoYWluKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIGNvbW1hbmQgb3IgYSBjb21tYW5kIGNoYWluIGNhbiBiZSBleGVjdXRlZC4gV2l0aG91dCBleGVjdXRpbmcgaXQuXG4gICAqL1xuICBwdWJsaWMgY2FuKCk6IENhbkNvbW1hbmRzIHtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kTWFuYWdlci5jYW4oKVxuICB9XG5cbiAgLyoqXG4gICAqIEluamVjdCBDU1Mgc3R5bGVzLlxuICAgKi9cbiAgcHJpdmF0ZSBpbmplY3RDU1MoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5pbmplY3RDU1MgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5jc3MgPSBjcmVhdGVTdHlsZVRhZyhzdHlsZSwgdGhpcy5vcHRpb25zLmluamVjdE5vbmNlKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgZWRpdG9yIG9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIEEgbGlzdCBvZiBvcHRpb25zXG4gICAqL1xuICBwdWJsaWMgc2V0T3B0aW9ucyhvcHRpb25zOiBQYXJ0aWFsPEVkaXRvck9wdGlvbnM+ID0ge30pOiB2b2lkIHtcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAuLi50aGlzLm9wdGlvbnMsXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH1cblxuICAgIGlmICghdGhpcy5lZGl0b3JWaWV3IHx8ICF0aGlzLnN0YXRlIHx8IHRoaXMuaXNEZXN0cm95ZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMuZWRpdG9yUHJvcHMpIHtcbiAgICAgIHRoaXMudmlldy5zZXRQcm9wcyh0aGlzLm9wdGlvbnMuZWRpdG9yUHJvcHMpXG4gICAgfVxuXG4gICAgdGhpcy52aWV3LnVwZGF0ZVN0YXRlKHRoaXMuc3RhdGUpXG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlIGVkaXRhYmxlIHN0YXRlIG9mIHRoZSBlZGl0b3IuXG4gICAqL1xuICBwdWJsaWMgc2V0RWRpdGFibGUoZWRpdGFibGU6IGJvb2xlYW4sIGVtaXRVcGRhdGUgPSB0cnVlKTogdm9pZCB7XG4gICAgdGhpcy5zZXRPcHRpb25zKHsgZWRpdGFibGUgfSlcblxuICAgIGlmIChlbWl0VXBkYXRlKSB7XG4gICAgICB0aGlzLmVtaXQoJ3VwZGF0ZScsIHsgZWRpdG9yOiB0aGlzLCB0cmFuc2FjdGlvbjogdGhpcy5zdGF0ZS50ciwgYXBwZW5kZWRUcmFuc2FjdGlvbnM6IFtdIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciB0aGUgZWRpdG9yIGlzIGVkaXRhYmxlLlxuICAgKi9cbiAgcHVibGljIGdldCBpc0VkaXRhYmxlKCk6IGJvb2xlYW4ge1xuICAgIC8vIHNpbmNlIHBsdWdpbnMgYXJlIGFwcGxpZWQgYWZ0ZXIgY3JlYXRpbmcgdGhlIHZpZXdcbiAgICAvLyBgZWRpdGFibGVgIGlzIGFsd2F5cyBgdHJ1ZWAgZm9yIG9uZSB0aWNrLlxuICAgIC8vIHRoYXTigJlzIHdoeSB3ZSBhbHNvIGhhdmUgdG8gY2hlY2sgZm9yIGBvcHRpb25zLmVkaXRhYmxlYFxuICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZWRpdGFibGUgJiYgdGhpcy52aWV3ICYmIHRoaXMudmlldy5lZGl0YWJsZVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGVkaXRvciB2aWV3LlxuICAgKi9cbiAgcHVibGljIGdldCB2aWV3KCk6IEVkaXRvclZpZXcge1xuICAgIGlmICh0aGlzLmVkaXRvclZpZXcpIHtcbiAgICAgIHJldHVybiB0aGlzLmVkaXRvclZpZXdcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFByb3h5KFxuICAgICAge1xuICAgICAgICBzdGF0ZTogdGhpcy5lZGl0b3JTdGF0ZSxcbiAgICAgICAgdXBkYXRlU3RhdGU6IChzdGF0ZTogRWRpdG9yU3RhdGUpOiBSZXR1cm5UeXBlPEVkaXRvclZpZXdbJ3VwZGF0ZVN0YXRlJ10+ID0+IHtcbiAgICAgICAgICB0aGlzLmVkaXRvclN0YXRlID0gc3RhdGVcbiAgICAgICAgfSxcbiAgICAgICAgZGlzcGF0Y2g6ICh0cjogVHJhbnNhY3Rpb24pOiBSZXR1cm5UeXBlPEVkaXRvclZpZXdbJ2Rpc3BhdGNoJ10+ID0+IHtcbiAgICAgICAgICB0aGlzLmRpc3BhdGNoVHJhbnNhY3Rpb24odHIpXG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gU3R1YiBzb21lIGNvbW1vbmx5IGFjY2Vzc2VkIHByb3BlcnRpZXMgdG8gcHJldmVudCBlcnJvcnNcbiAgICAgICAgY29tcG9zaW5nOiBmYWxzZSxcbiAgICAgICAgZHJhZ2dpbmc6IG51bGwsXG4gICAgICAgIGVkaXRhYmxlOiB0cnVlLFxuICAgICAgICBpc0Rlc3Ryb3llZDogZmFsc2UsXG4gICAgICB9IGFzIEVkaXRvclZpZXcsXG4gICAgICB7XG4gICAgICAgIGdldDogKG9iaiwga2V5KSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuZWRpdG9yVmlldykge1xuICAgICAgICAgICAgLy8gSWYgdGhlIGVkaXRvciB2aWV3IGlzIGF2YWlsYWJsZSwgYnV0IHRoZSBjYWxsZXIgaGFzIGEgc3RhbGUgcmVmZXJlbmNlIHRvIHRoZSBwcm94eSxcbiAgICAgICAgICAgIC8vIEp1c3QgcmV0dXJuIHdoYXQgdGhlIGVkaXRvciB2aWV3IGhhcy5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVkaXRvclZpZXdba2V5IGFzIGtleW9mIEVkaXRvclZpZXddXG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFNwZWNpZmljYWxseSBhbHdheXMgcmV0dXJuIHRoZSBtb3N0IHJlY2VudCBlZGl0b3JTdGF0ZVxuICAgICAgICAgIGlmIChrZXkgPT09ICdzdGF0ZScpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVkaXRvclN0YXRlXG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChrZXkgaW4gb2JqKSB7XG4gICAgICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXQob2JqLCBrZXkpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gV2UgdGhyb3cgYW4gZXJyb3IgaGVyZSwgYmVjYXVzZSB3ZSBrbm93IHRoZSB2aWV3IGlzIG5vdCBhdmFpbGFibGVcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgW3RpcHRhcCBlcnJvcl06IFRoZSBlZGl0b3IgdmlldyBpcyBub3QgYXZhaWxhYmxlLiBDYW5ub3QgYWNjZXNzIHZpZXdbJyR7a2V5IGFzIHN0cmluZ30nXS4gVGhlIGVkaXRvciBtYXkgbm90IGJlIG1vdW50ZWQgeWV0LmAsXG4gICAgICAgICAgKVxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICApIGFzIEVkaXRvclZpZXdcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBlZGl0b3Igc3RhdGUuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHN0YXRlKCk6IEVkaXRvclN0YXRlIHtcbiAgICBpZiAodGhpcy5lZGl0b3JWaWV3KSB7XG4gICAgICB0aGlzLmVkaXRvclN0YXRlID0gdGhpcy52aWV3LnN0YXRlXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yU3RhdGVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhIFByb3NlTWlycm9yIHBsdWdpbi5cbiAgICpcbiAgICogQHBhcmFtIHBsdWdpbiBBIFByb3NlTWlycm9yIHBsdWdpblxuICAgKiBAcGFyYW0gaGFuZGxlUGx1Z2lucyBDb250cm9sIGhvdyB0byBtZXJnZSB0aGUgcGx1Z2luIGludG8gdGhlIGV4aXN0aW5nIHBsdWdpbnMuXG4gICAqIEByZXR1cm5zIFRoZSBuZXcgZWRpdG9yIHN0YXRlXG4gICAqL1xuICBwdWJsaWMgcmVnaXN0ZXJQbHVnaW4oXG4gICAgcGx1Z2luOiBQbHVnaW4sXG4gICAgaGFuZGxlUGx1Z2lucz86IChuZXdQbHVnaW46IFBsdWdpbiwgcGx1Z2luczogUGx1Z2luW10pID0+IFBsdWdpbltdLFxuICApOiBFZGl0b3JTdGF0ZSB7XG4gICAgY29uc3QgcGx1Z2lucyA9IGlzRnVuY3Rpb24oaGFuZGxlUGx1Z2lucylcbiAgICAgID8gaGFuZGxlUGx1Z2lucyhwbHVnaW4sIFsuLi50aGlzLnN0YXRlLnBsdWdpbnNdKVxuICAgICAgOiBbLi4udGhpcy5zdGF0ZS5wbHVnaW5zLCBwbHVnaW5dXG5cbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuc3RhdGUucmVjb25maWd1cmUoeyBwbHVnaW5zIH0pXG5cbiAgICB0aGlzLnZpZXcudXBkYXRlU3RhdGUoc3RhdGUpXG5cbiAgICByZXR1cm4gc3RhdGVcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVyIGEgUHJvc2VNaXJyb3IgcGx1Z2luLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZU9yUGx1Z2luS2V5VG9SZW1vdmUgVGhlIHBsdWdpbnMgbmFtZVxuICAgKiBAcmV0dXJucyBUaGUgbmV3IGVkaXRvciBzdGF0ZSBvciB1bmRlZmluZWQgaWYgdGhlIGVkaXRvciBpcyBkZXN0cm95ZWRcbiAgICovXG4gIHB1YmxpYyB1bnJlZ2lzdGVyUGx1Z2luKFxuICAgIG5hbWVPclBsdWdpbktleVRvUmVtb3ZlOiBzdHJpbmcgfCBQbHVnaW5LZXkgfCAoc3RyaW5nIHwgUGx1Z2luS2V5KVtdLFxuICApOiBFZGl0b3JTdGF0ZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRoaXMuaXNEZXN0cm95ZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBjb25zdCBwcmV2UGx1Z2lucyA9IHRoaXMuc3RhdGUucGx1Z2luc1xuICAgIGxldCBwbHVnaW5zID0gcHJldlBsdWdpbnNcblxuICAgIDsoW10gYXMgKHN0cmluZyB8IFBsdWdpbktleSlbXSkuY29uY2F0KG5hbWVPclBsdWdpbktleVRvUmVtb3ZlKS5mb3JFYWNoKG5hbWVPclBsdWdpbktleSA9PiB7XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBjb25zdCBuYW1lID0gdHlwZW9mIG5hbWVPclBsdWdpbktleSA9PT0gJ3N0cmluZycgPyBgJHtuYW1lT3JQbHVnaW5LZXl9JGAgOiBuYW1lT3JQbHVnaW5LZXkua2V5XG5cbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIHBsdWdpbnMgPSBwbHVnaW5zLmZpbHRlcihwbHVnaW4gPT4gIXBsdWdpbi5rZXkuc3RhcnRzV2l0aChuYW1lKSlcbiAgICB9KVxuXG4gICAgaWYgKHByZXZQbHVnaW5zLmxlbmd0aCA9PT0gcGx1Z2lucy5sZW5ndGgpIHtcbiAgICAgIC8vIE5vIHBsdWdpbiB3YXMgcmVtb3ZlZCwgc28gd2UgZG9u4oCZdCBuZWVkIHRvIHVwZGF0ZSB0aGUgc3RhdGVcbiAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuc3RhdGUucmVjb25maWd1cmUoe1xuICAgICAgcGx1Z2lucyxcbiAgICB9KVxuXG4gICAgdGhpcy52aWV3LnVwZGF0ZVN0YXRlKHN0YXRlKVxuXG4gICAgcmV0dXJuIHN0YXRlXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBleHRlbnNpb24gbWFuYWdlci5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlRXh0ZW5zaW9uTWFuYWdlcigpOiB2b2lkIHtcbiAgICBjb25zdCBjb3JlRXh0ZW5zaW9ucyA9IHRoaXMub3B0aW9ucy5lbmFibGVDb3JlRXh0ZW5zaW9uc1xuICAgICAgPyBbXG4gICAgICAgICAgRWRpdGFibGUsXG4gICAgICAgICAgQ2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXIuY29uZmlndXJlKHtcbiAgICAgICAgICAgIGJsb2NrU2VwYXJhdG9yOlxuICAgICAgICAgICAgICB0aGlzLm9wdGlvbnMuY29yZUV4dGVuc2lvbk9wdGlvbnM/LmNsaXBib2FyZFRleHRTZXJpYWxpemVyPy5ibG9ja1NlcGFyYXRvcixcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBDb21tYW5kcyxcbiAgICAgICAgICBGb2N1c0V2ZW50cyxcbiAgICAgICAgICBLZXltYXAsXG4gICAgICAgICAgVGFiaW5kZXguY29uZmlndXJlKHtcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLm9wdGlvbnMuY29yZUV4dGVuc2lvbk9wdGlvbnM/LnRhYmluZGV4Py52YWx1ZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBEcm9wLFxuICAgICAgICAgIFBhc3RlLFxuICAgICAgICAgIERlbGV0ZSxcbiAgICAgICAgICBUZXh0RGlyZWN0aW9uLmNvbmZpZ3VyZSh7XG4gICAgICAgICAgICBkaXJlY3Rpb246IHRoaXMub3B0aW9ucy50ZXh0RGlyZWN0aW9uLFxuICAgICAgICAgIH0pLFxuICAgICAgICBdLmZpbHRlcihleHQgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5vcHRpb25zLmVuYWJsZUNvcmVFeHRlbnNpb25zID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgdGhpcy5vcHRpb25zLmVuYWJsZUNvcmVFeHRlbnNpb25zW1xuICAgICAgICAgICAgICAgIGV4dC5uYW1lIGFzIGtleW9mIHR5cGVvZiB0aGlzLm9wdGlvbnMuZW5hYmxlQ29yZUV4dGVuc2lvbnNcbiAgICAgICAgICAgICAgXSAhPT0gZmFsc2VcbiAgICAgICAgICAgIClcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSlcbiAgICAgIDogW11cbiAgICBjb25zdCBhbGxFeHRlbnNpb25zID0gWy4uLmNvcmVFeHRlbnNpb25zLCAuLi50aGlzLm9wdGlvbnMuZXh0ZW5zaW9uc10uZmlsdGVyKGV4dGVuc2lvbiA9PiB7XG4gICAgICByZXR1cm4gWydleHRlbnNpb24nLCAnbm9kZScsICdtYXJrJ10uaW5jbHVkZXMoZXh0ZW5zaW9uPy50eXBlKVxuICAgIH0pXG5cbiAgICB0aGlzLmV4dGVuc2lvbk1hbmFnZXIgPSBuZXcgRXh0ZW5zaW9uTWFuYWdlcihhbGxFeHRlbnNpb25zLCB0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gY29tbWFuZCBtYW5hZ2VyLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVDb21tYW5kTWFuYWdlcigpOiB2b2lkIHtcbiAgICB0aGlzLmNvbW1hbmRNYW5hZ2VyID0gbmV3IENvbW1hbmRNYW5hZ2VyKHtcbiAgICAgIGVkaXRvcjogdGhpcyxcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBQcm9zZU1pcnJvciBzY2hlbWEuXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZVNjaGVtYSgpOiB2b2lkIHtcbiAgICB0aGlzLnNjaGVtYSA9IHRoaXMuZXh0ZW5zaW9uTWFuYWdlci5zY2hlbWFcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSBpbml0aWFsIGRvY3VtZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVEb2MoKTogUHJvc2VNaXJyb3JOb2RlIHtcbiAgICBsZXQgZG9jOiBQcm9zZU1pcnJvck5vZGVcblxuICAgIHRyeSB7XG4gICAgICBkb2MgPSBjcmVhdGVEb2N1bWVudCh0aGlzLm9wdGlvbnMuY29udGVudCwgdGhpcy5zY2hlbWEsIHRoaXMub3B0aW9ucy5wYXJzZU9wdGlvbnMsIHtcbiAgICAgICAgZXJyb3JPbkludmFsaWRDb250ZW50OiB0aGlzLm9wdGlvbnMuZW5hYmxlQ29udGVudENoZWNrLFxuICAgICAgfSlcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoXG4gICAgICAgICEoZSBpbnN0YW5jZW9mIEVycm9yKSB8fFxuICAgICAgICAhWydbdGlwdGFwIGVycm9yXTogSW52YWxpZCBKU09OIGNvbnRlbnQnLCAnW3RpcHRhcCBlcnJvcl06IEludmFsaWQgSFRNTCBjb250ZW50J10uaW5jbHVkZXMoXG4gICAgICAgICAgZS5tZXNzYWdlLFxuICAgICAgICApXG4gICAgICApIHtcbiAgICAgICAgLy8gTm90IHRoZSBjb250ZW50IGVycm9yIHdlIHdlcmUgZXhwZWN0aW5nXG4gICAgICAgIHRocm93IGVcbiAgICAgIH1cbiAgICAgIHRoaXMuZW1pdCgnY29udGVudEVycm9yJywge1xuICAgICAgICBlZGl0b3I6IHRoaXMsXG4gICAgICAgIGVycm9yOiBlIGFzIEVycm9yLFxuICAgICAgICBkaXNhYmxlQ29sbGFib3JhdGlvbjogKCkgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICdjb2xsYWJvcmF0aW9uJyBpbiB0aGlzLnN0b3JhZ2UgJiZcbiAgICAgICAgICAgIHR5cGVvZiB0aGlzLnN0b3JhZ2UuY29sbGFib3JhdGlvbiA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5jb2xsYWJvcmF0aW9uXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICA7KHRoaXMuc3RvcmFnZS5jb2xsYWJvcmF0aW9uIGFzIGFueSkuaXNEaXNhYmxlZCA9IHRydWVcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVG8gYXZvaWQgc3luY2luZyBiYWNrIGludmFsaWQgY29udGVudCwgcmVpbml0aWFsaXplIHRoZSBleHRlbnNpb25zIHdpdGhvdXQgdGhlIGNvbGxhYm9yYXRpb24gZXh0ZW5zaW9uXG4gICAgICAgICAgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMgPSB0aGlzLm9wdGlvbnMuZXh0ZW5zaW9ucy5maWx0ZXIoXG4gICAgICAgICAgICBleHRlbnNpb24gPT4gZXh0ZW5zaW9uLm5hbWUgIT09ICdjb2xsYWJvcmF0aW9uJyxcbiAgICAgICAgICApXG5cbiAgICAgICAgICAvLyBSZXN0YXJ0IHRoZSBpbml0aWFsaXphdGlvbiBwcm9jZXNzIGJ5IHJlY3JlYXRpbmcgdGhlIGV4dGVuc2lvbiBtYW5hZ2VyIHdpdGggdGhlIG5ldyBzZXQgb2YgZXh0ZW5zaW9uc1xuICAgICAgICAgIHRoaXMuY3JlYXRlRXh0ZW5zaW9uTWFuYWdlcigpXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBDb250ZW50IGlzIGludmFsaWQsIGJ1dCBhdHRlbXB0IHRvIGNyZWF0ZSBpdCBhbnl3YXksIHN0cmlwcGluZyBvdXQgdGhlIGludmFsaWQgcGFydHNcbiAgICAgIGRvYyA9IGNyZWF0ZURvY3VtZW50KHRoaXMub3B0aW9ucy5jb250ZW50LCB0aGlzLnNjaGVtYSwgdGhpcy5vcHRpb25zLnBhcnNlT3B0aW9ucywge1xuICAgICAgICBlcnJvck9uSW52YWxpZENvbnRlbnQ6IGZhbHNlLFxuICAgICAgfSlcbiAgICB9XG4gICAgcmV0dXJuIGRvY1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBQcm9zZU1pcnJvciB2aWV3LlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVWaWV3KGVsZW1lbnQ6IE5vbk51bGxhYmxlPEVkaXRvck9wdGlvbnNbJ2VsZW1lbnQnXT4pOiB2b2lkIHtcbiAgICBjb25zdCB7IGVkaXRvclByb3BzLCBlbmFibGVFeHRlbnNpb25EaXNwYXRjaFRyYW5zYWN0aW9uIH0gPSB0aGlzLm9wdGlvbnNcbiAgICAvLyBJZiBhIHVzZXIgcHJvdmlkZWQgYSBjdXN0b20gYGRpc3BhdGNoVHJhbnNhY3Rpb25gIHRocm91Z2ggYGVkaXRvclByb3BzYCxcbiAgICAvLyB3ZSB1c2UgdGhhdCBhcyB0aGUgYmFzZSBkaXNwYXRjaCBmdW5jdGlvbi5cbiAgICAvLyBPdGhlcndpc2UsIHdlIHVzZSBUaXB0YXAncyBpbnRlcm5hbCBgZGlzcGF0Y2hUcmFuc2FjdGlvbmAgbWV0aG9kLlxuICAgIGNvbnN0IGJhc2VEaXNwYXRjaCA9XG4gICAgICAoZWRpdG9yUHJvcHMgYXMgRGlyZWN0RWRpdG9yUHJvcHMpLmRpc3BhdGNoVHJhbnNhY3Rpb24gfHwgdGhpcy5kaXNwYXRjaFRyYW5zYWN0aW9uLmJpbmQodGhpcylcbiAgICBjb25zdCBkaXNwYXRjaCA9IGVuYWJsZUV4dGVuc2lvbkRpc3BhdGNoVHJhbnNhY3Rpb25cbiAgICAgID8gdGhpcy5leHRlbnNpb25NYW5hZ2VyLmRpc3BhdGNoVHJhbnNhY3Rpb24oYmFzZURpc3BhdGNoKVxuICAgICAgOiBiYXNlRGlzcGF0Y2hcblxuICAgIC8vIENvbXBvc2UgdHJhbnNmb3JtUGFzdGVkSFRNTCBmcm9tIGV4dGVuc2lvbnMgYW5kIHVzZXItcHJvdmlkZWQgZWRpdG9yUHJvcHNcbiAgICBjb25zdCBiYXNlVHJhbnNmb3JtUGFzdGVkSFRNTCA9IChlZGl0b3JQcm9wcyBhcyBEaXJlY3RFZGl0b3JQcm9wcykudHJhbnNmb3JtUGFzdGVkSFRNTFxuICAgIGNvbnN0IHRyYW5zZm9ybVBhc3RlZEhUTUwgPSB0aGlzLmV4dGVuc2lvbk1hbmFnZXIudHJhbnNmb3JtUGFzdGVkSFRNTChiYXNlVHJhbnNmb3JtUGFzdGVkSFRNTClcblxuICAgIHRoaXMuZWRpdG9yVmlldyA9IG5ldyBFZGl0b3JWaWV3KGVsZW1lbnQsIHtcbiAgICAgIC4uLmVkaXRvclByb3BzLFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAvLyBhZGQgYHJvbGU9XCJ0ZXh0Ym94XCJgIHRvIHRoZSBlZGl0b3IgZWxlbWVudFxuICAgICAgICByb2xlOiAndGV4dGJveCcsXG4gICAgICAgIC4uLmVkaXRvclByb3BzPy5hdHRyaWJ1dGVzLFxuICAgICAgfSxcbiAgICAgIGRpc3BhdGNoVHJhbnNhY3Rpb246IGRpc3BhdGNoLFxuICAgICAgdHJhbnNmb3JtUGFzdGVkSFRNTCxcbiAgICAgIHN0YXRlOiB0aGlzLmVkaXRvclN0YXRlLFxuICAgICAgbWFya1ZpZXdzOiB0aGlzLmV4dGVuc2lvbk1hbmFnZXIubWFya1ZpZXdzLFxuICAgICAgbm9kZVZpZXdzOiB0aGlzLmV4dGVuc2lvbk1hbmFnZXIubm9kZVZpZXdzLFxuICAgIH0pXG5cbiAgICAvLyBgZWRpdG9yLnZpZXdgIGlzIG5vdCB5ZXQgYXZhaWxhYmxlIGF0IHRoaXMgdGltZS5cbiAgICAvLyBUaGVyZWZvcmUgd2Ugd2lsbCBhZGQgYWxsIHBsdWdpbnMgYW5kIG5vZGUgdmlld3MgZGlyZWN0bHkgYWZ0ZXJ3YXJkcy5cbiAgICBjb25zdCBuZXdTdGF0ZSA9IHRoaXMuc3RhdGUucmVjb25maWd1cmUoe1xuICAgICAgcGx1Z2luczogdGhpcy5leHRlbnNpb25NYW5hZ2VyLnBsdWdpbnMsXG4gICAgfSlcblxuICAgIHRoaXMudmlldy51cGRhdGVTdGF0ZShuZXdTdGF0ZSlcblxuICAgIHRoaXMucHJlcGVuZENsYXNzKClcbiAgICB0aGlzLmluamVjdENTUygpXG5cbiAgICAvLyBMZXTigJlzIHN0b3JlIHRoZSBlZGl0b3IgaW5zdGFuY2UgaW4gdGhlIERPTSBlbGVtZW50LlxuICAgIC8vIFNvIHdl4oCZbGwgaGF2ZSBhY2Nlc3MgdG8gaXQgZm9yIHRlc3RzLlxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBjb25zdCBkb20gPSB0aGlzLnZpZXcuZG9tIGFzIFRpcHRhcEVkaXRvckhUTUxFbGVtZW50XG5cbiAgICBkb20uZWRpdG9yID0gdGhpc1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYWxsIG5vZGUgYW5kIG1hcmsgdmlld3MuXG4gICAqL1xuICBwdWJsaWMgY3JlYXRlTm9kZVZpZXdzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnZpZXcuaXNEZXN0cm95ZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMudmlldy5zZXRQcm9wcyh7XG4gICAgICBtYXJrVmlld3M6IHRoaXMuZXh0ZW5zaW9uTWFuYWdlci5tYXJrVmlld3MsXG4gICAgICBub2RlVmlld3M6IHRoaXMuZXh0ZW5zaW9uTWFuYWdlci5ub2RlVmlld3MsXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBQcmVwZW5kIGNsYXNzIG5hbWUgdG8gZWxlbWVudC5cbiAgICovXG4gIHB1YmxpYyBwcmVwZW5kQ2xhc3MoKTogdm9pZCB7XG4gICAgdGhpcy52aWV3LmRvbS5jbGFzc05hbWUgPSBgJHt0aGlzLmNsYXNzTmFtZX0gJHt0aGlzLnZpZXcuZG9tLmNsYXNzTmFtZX1gXG4gIH1cblxuICBwdWJsaWMgaXNDYXB0dXJpbmdUcmFuc2FjdGlvbiA9IGZhbHNlXG5cbiAgcHJpdmF0ZSBjYXB0dXJlZFRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbiB8IG51bGwgPSBudWxsXG5cbiAgcHVibGljIGNhcHR1cmVUcmFuc2FjdGlvbihmbjogKCkgPT4gdm9pZCkge1xuICAgIHRoaXMuaXNDYXB0dXJpbmdUcmFuc2FjdGlvbiA9IHRydWVcbiAgICBmbigpXG4gICAgdGhpcy5pc0NhcHR1cmluZ1RyYW5zYWN0aW9uID0gZmFsc2VcblxuICAgIGNvbnN0IHRyID0gdGhpcy5jYXB0dXJlZFRyYW5zYWN0aW9uXG5cbiAgICB0aGlzLmNhcHR1cmVkVHJhbnNhY3Rpb24gPSBudWxsXG5cbiAgICByZXR1cm4gdHJcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgY2FsbGJhY2sgb3ZlciB3aGljaCB0byBzZW5kIHRyYW5zYWN0aW9ucyAoc3RhdGUgdXBkYXRlcykgcHJvZHVjZWQgYnkgdGhlIHZpZXcuXG4gICAqXG4gICAqIEBwYXJhbSB0cmFuc2FjdGlvbiBBbiBlZGl0b3Igc3RhdGUgdHJhbnNhY3Rpb25cbiAgICovXG4gIHByaXZhdGUgZGlzcGF0Y2hUcmFuc2FjdGlvbih0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb24pOiB2b2lkIHtcbiAgICAvLyBpZiB0aGUgZWRpdG9yIC8gdGhlIHZpZXcgb2YgdGhlIGVkaXRvciB3YXMgZGVzdHJveWVkXG4gICAgLy8gdGhlIHRyYW5zYWN0aW9uIHNob3VsZCBub3QgYmUgZGlzcGF0Y2hlZCBhcyB0aGVyZSBpcyBubyB2aWV3IGFueW1vcmUuXG4gICAgaWYgKHRoaXMudmlldy5pc0Rlc3Ryb3llZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNDYXB0dXJpbmdUcmFuc2FjdGlvbikge1xuICAgICAgaWYgKCF0aGlzLmNhcHR1cmVkVHJhbnNhY3Rpb24pIHtcbiAgICAgICAgdGhpcy5jYXB0dXJlZFRyYW5zYWN0aW9uID0gdHJhbnNhY3Rpb25cblxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgdHJhbnNhY3Rpb24uc3RlcHMuZm9yRWFjaChzdGVwID0+IHRoaXMuY2FwdHVyZWRUcmFuc2FjdGlvbj8uc3RlcChzdGVwKSlcblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gQXBwbHkgdHJhbnNhY3Rpb24gYW5kIGdldCByZXN1bHRpbmcgc3RhdGUgYW5kIHRyYW5zYWN0aW9uc1xuICAgIGNvbnN0IHsgc3RhdGUsIHRyYW5zYWN0aW9ucyB9ID0gdGhpcy5zdGF0ZS5hcHBseVRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKVxuICAgIGNvbnN0IHNlbGVjdGlvbkhhc0NoYW5nZWQgPSAhdGhpcy5zdGF0ZS5zZWxlY3Rpb24uZXEoc3RhdGUuc2VsZWN0aW9uKVxuICAgIGNvbnN0IHJvb3RUcldhc0FwcGxpZWQgPSB0cmFuc2FjdGlvbnMuaW5jbHVkZXModHJhbnNhY3Rpb24pXG4gICAgY29uc3QgcHJldlN0YXRlID0gdGhpcy5zdGF0ZVxuXG4gICAgdGhpcy5lbWl0KCdiZWZvcmVUcmFuc2FjdGlvbicsIHtcbiAgICAgIGVkaXRvcjogdGhpcyxcbiAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgbmV4dFN0YXRlOiBzdGF0ZSxcbiAgICB9KVxuXG4gICAgLy8gSWYgdHJhbnNhY3Rpb24gd2FzIGZpbHRlcmVkIG91dCwgd2UgY2FuIHJldHVybiBlYXJseVxuICAgIGlmICghcm9vdFRyV2FzQXBwbGllZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy52aWV3LnVwZGF0ZVN0YXRlKHN0YXRlKVxuXG4gICAgLy8gRW1pdCB0cmFuc2FjdGlvbiBldmVudCB3aXRoIGFwcGVuZGVkIHRyYW5zYWN0aW9ucyBpbmZvXG4gICAgdGhpcy5lbWl0KCd0cmFuc2FjdGlvbicsIHtcbiAgICAgIGVkaXRvcjogdGhpcyxcbiAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgYXBwZW5kZWRUcmFuc2FjdGlvbnM6IHRyYW5zYWN0aW9ucy5zbGljZSgxKSxcbiAgICB9KVxuXG4gICAgaWYgKHNlbGVjdGlvbkhhc0NoYW5nZWQpIHtcbiAgICAgIHRoaXMuZW1pdCgnc2VsZWN0aW9uVXBkYXRlJywge1xuICAgICAgICBlZGl0b3I6IHRoaXMsXG4gICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICAvLyBPbmx5IGVtaXQgdGhlIGxhdGVzdCBiZXR3ZWVuIGZvY3VzIGFuZCBibHVyIGV2ZW50c1xuICAgIGNvbnN0IG1vc3RSZWNlbnRGb2N1c1RyID0gdHJhbnNhY3Rpb25zLmZpbmRMYXN0KHRyID0+IHRyLmdldE1ldGEoJ2ZvY3VzJykgfHwgdHIuZ2V0TWV0YSgnYmx1cicpKVxuICAgIGNvbnN0IGZvY3VzID0gbW9zdFJlY2VudEZvY3VzVHI/LmdldE1ldGEoJ2ZvY3VzJylcbiAgICBjb25zdCBibHVyID0gbW9zdFJlY2VudEZvY3VzVHI/LmdldE1ldGEoJ2JsdXInKVxuXG4gICAgaWYgKGZvY3VzKSB7XG4gICAgICB0aGlzLmVtaXQoJ2ZvY3VzJywge1xuICAgICAgICBlZGl0b3I6IHRoaXMsXG4gICAgICAgIGV2ZW50OiBmb2N1cy5ldmVudCxcbiAgICAgICAgLy8gb3hsaW50LWRpc2FibGUtbmV4dC1saW5lbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgIHRyYW5zYWN0aW9uOiBtb3N0UmVjZW50Rm9jdXNUciEsXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmIChibHVyKSB7XG4gICAgICB0aGlzLmVtaXQoJ2JsdXInLCB7XG4gICAgICAgIGVkaXRvcjogdGhpcyxcbiAgICAgICAgZXZlbnQ6IGJsdXIuZXZlbnQsXG4gICAgICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZW5vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICB0cmFuc2FjdGlvbjogbW9zdFJlY2VudEZvY3VzVHIhLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICAvLyBDb21wYXJlIHN0YXRlcyBmb3IgdXBkYXRlIGV2ZW50XG4gICAgaWYgKFxuICAgICAgdHJhbnNhY3Rpb24uZ2V0TWV0YSgncHJldmVudFVwZGF0ZScpIHx8XG4gICAgICAhdHJhbnNhY3Rpb25zLnNvbWUodHIgPT4gdHIuZG9jQ2hhbmdlZCkgfHxcbiAgICAgIHByZXZTdGF0ZS5kb2MuZXEoc3RhdGUuZG9jKVxuICAgICkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5lbWl0KCd1cGRhdGUnLCB7XG4gICAgICBlZGl0b3I6IHRoaXMsXG4gICAgICB0cmFuc2FjdGlvbixcbiAgICAgIGFwcGVuZGVkVHJhbnNhY3Rpb25zOiB0cmFuc2FjdGlvbnMuc2xpY2UoMSksXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYXR0cmlidXRlcyBvZiB0aGUgY3VycmVudGx5IHNlbGVjdGVkIG5vZGUgb3IgbWFyay5cbiAgICovXG4gIHB1YmxpYyBnZXRBdHRyaWJ1dGVzKG5hbWVPclR5cGU6IHN0cmluZyB8IE5vZGVUeXBlIHwgTWFya1R5cGUpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICByZXR1cm4gZ2V0QXR0cmlidXRlcyh0aGlzLnN0YXRlLCBuYW1lT3JUeXBlKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgaWYgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBub2RlIG9yIG1hcmsgaXMgYWN0aXZlLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSBub2RlIG9yIG1hcmtcbiAgICogQHBhcmFtIGF0dHJpYnV0ZXMgQXR0cmlidXRlcyBvZiB0aGUgbm9kZSBvciBtYXJrXG4gICAqL1xuICBwdWJsaWMgaXNBY3RpdmUobmFtZTogc3RyaW5nLCBhdHRyaWJ1dGVzPzoge30pOiBib29sZWFuXG4gIHB1YmxpYyBpc0FjdGl2ZShhdHRyaWJ1dGVzOiB7fSk6IGJvb2xlYW5cbiAgcHVibGljIGlzQWN0aXZlKG5hbWVPckF0dHJpYnV0ZXM6IHN0cmluZywgYXR0cmlidXRlc09yVW5kZWZpbmVkPzoge30pOiBib29sZWFuIHtcbiAgICBjb25zdCBuYW1lID0gdHlwZW9mIG5hbWVPckF0dHJpYnV0ZXMgPT09ICdzdHJpbmcnID8gbmFtZU9yQXR0cmlidXRlcyA6IG51bGxcblxuICAgIGNvbnN0IGF0dHJpYnV0ZXMgPVxuICAgICAgdHlwZW9mIG5hbWVPckF0dHJpYnV0ZXMgPT09ICdzdHJpbmcnID8gYXR0cmlidXRlc09yVW5kZWZpbmVkIDogbmFtZU9yQXR0cmlidXRlc1xuXG4gICAgcmV0dXJuIGlzQWN0aXZlKHRoaXMuc3RhdGUsIG5hbWUsIGF0dHJpYnV0ZXMpXG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBkb2N1bWVudCBhcyBKU09OLlxuICAgKi9cbiAgcHVibGljIGdldEpTT04oKTogRG9jdW1lbnRUeXBlPFxuICAgIFJlY29yZDxzdHJpbmcsIGFueT4gfCB1bmRlZmluZWQsXG4gICAgVE5vZGVUeXBlPHN0cmluZywgdW5kZWZpbmVkIHwgUmVjb3JkPHN0cmluZywgYW55PiwgYW55LCAoVE5vZGVUeXBlIHwgVFRleHRUeXBlKVtdPltdXG4gID4ge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmRvYy50b0pTT04oKVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZG9jdW1lbnQgYXMgSFRNTC5cbiAgICovXG4gIHB1YmxpYyBnZXRIVE1MKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGdldEhUTUxGcm9tRnJhZ21lbnQodGhpcy5zdGF0ZS5kb2MuY29udGVudCwgdGhpcy5zY2hlbWEpXG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBkb2N1bWVudCBhcyB0ZXh0LlxuICAgKi9cbiAgcHVibGljIGdldFRleHQob3B0aW9ucz86IHtcbiAgICBibG9ja1NlcGFyYXRvcj86IHN0cmluZ1xuICAgIHRleHRTZXJpYWxpemVycz86IFJlY29yZDxzdHJpbmcsIFRleHRTZXJpYWxpemVyPlxuICB9KTogc3RyaW5nIHtcbiAgICBjb25zdCB7IGJsb2NrU2VwYXJhdG9yID0gJ1xcblxcbicsIHRleHRTZXJpYWxpemVycyA9IHt9IH0gPSBvcHRpb25zIHx8IHt9XG5cbiAgICByZXR1cm4gZ2V0VGV4dCh0aGlzLnN0YXRlLmRvYywge1xuICAgICAgYmxvY2tTZXBhcmF0b3IsXG4gICAgICB0ZXh0U2VyaWFsaXplcnM6IHtcbiAgICAgICAgLi4uZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYSh0aGlzLnNjaGVtYSksXG4gICAgICAgIC4uLnRleHRTZXJpYWxpemVycyxcbiAgICAgIH0sXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGVyZSBpcyBubyBjb250ZW50LlxuICAgKi9cbiAgcHVibGljIGdldCBpc0VtcHR5KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc05vZGVFbXB0eSh0aGlzLnN0YXRlLmRvYylcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cm95IHRoZSBlZGl0b3IuXG4gICAqL1xuICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kZXN0cm95ZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuZGVzdHJveWVkID0gdHJ1ZVxuXG4gICAgdGhpcy5lbWl0KCdkZXN0cm95JylcblxuICAgIHRoaXMudW5tb3VudCgpXG5cbiAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygpXG5cbiAgICB0aGlzLmV4dGVuc2lvbk1hbmFnZXIuZGVzdHJveSgpXG4gICAgdGhpcy5leHRlbnNpb25NYW5hZ2VyID0gbnVsbCBhcyBhbnlcbiAgICB0aGlzLnNjaGVtYSA9IG51bGwgYXMgYW55XG4gICAgdGhpcy5jb21tYW5kTWFuYWdlciA9IG51bGwgYXMgYW55XG4gICAgdGhpcy5leHRlbnNpb25TdG9yYWdlID0ge30gYXMgU3RvcmFnZVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRoZSBlZGl0b3IgaXMgYWxyZWFkeSBkZXN0cm95ZWQuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGlzRGVzdHJveWVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVkaXRvclZpZXc/LmlzRGVzdHJveWVkID8/IHRydWVcbiAgfVxuXG4gIHB1YmxpYyAkbm9kZShzZWxlY3Rvcjogc3RyaW5nLCBhdHRyaWJ1dGVzPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfSk6IE5vZGVQb3MgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy4kZG9jPy5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yLCBhdHRyaWJ1dGVzKSB8fCBudWxsXG4gIH1cblxuICBwdWJsaWMgJG5vZGVzKHNlbGVjdG9yOiBzdHJpbmcsIGF0dHJpYnV0ZXM/OiB7IFtrZXk6IHN0cmluZ106IGFueSB9KTogTm9kZVBvc1tdIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuJGRvYz8ucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvciwgYXR0cmlidXRlcykgfHwgbnVsbFxuICB9XG5cbiAgcHVibGljICRwb3MocG9zOiBudW1iZXIpIHtcbiAgICBjb25zdCAkcG9zID0gdGhpcy5zdGF0ZS5kb2MucmVzb2x2ZShwb3MpXG4gICAgLy8gV2hlbiB0aGUgcG9zaXRpb24gc2l0cyBkaXJlY3RseSBiZWZvcmUgYSBub24tdGV4dCBub2RlIChlLmcuIGFuIGltYWdlIG9yXG4gICAgLy8gb3RoZXIgYXRvbSksIG5vZGVBZnRlciBpcyB0aGF0IG5vZGUgYnV0IHJlc29sdmVkUG9zLm5vZGUoKSB3b3VsZCByZXR1cm5cbiAgICAvLyB0aGUgcGFyZW50IChvZnRlbiB0aGUgZG9jIGF0IGRlcHRoIDApLiBQYXNzIG5vZGVBZnRlciBhcyB0aGUgZXhwbGljaXQgbm9kZVxuICAgIC8vIHNvIE5vZGVQb3Mubm9kZSByZXR1cm5zIHRoZSBleHBlY3RlZCBub2RlIGluc3RlYWQgb2YgdGhlIHBhcmVudC5cbiAgICAvLyBLZWVwICRwb3MoMCkgcmV0dXJuaW5nIHRoZSBkb2Mgbm9kZTsgZm9yIG90aGVyIHBvc2l0aW9ucywgcHJlZmVyIG5vZGVBZnRlclxuICAgIC8vIHdoZW4gaXQgcG9pbnRzIGF0IGEgbm9uLXRleHQgbm9kZS5cbiAgICBjb25zdCBub2RlID0gcG9zID4gMCAmJiAkcG9zLm5vZGVBZnRlciAmJiAhJHBvcy5ub2RlQWZ0ZXIuaXNUZXh0ID8gJHBvcy5ub2RlQWZ0ZXIgOiBudWxsXG5cbiAgICByZXR1cm4gbmV3IE5vZGVQb3MoJHBvcywgdGhpcywgZmFsc2UsIG5vZGUpXG4gIH1cblxuICBnZXQgJGRvYygpIHtcbiAgICByZXR1cm4gdGhpcy4kcG9zKDApXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHNldCBvZiB1dGlsaXRpZXMgZm9yIHdvcmtpbmcgd2l0aCBwb3NpdGlvbnMgYW5kIHJhbmdlcy5cbiAgICovXG4gIHB1YmxpYyB1dGlsczogVXRpbHMgPSB7XG4gICAgZ2V0VXBkYXRlZFBvc2l0aW9uLFxuICAgIGNyZWF0ZU1hcHBhYmxlUG9zaXRpb24sXG4gIH1cbn1cbiIsICJ0eXBlIFN0cmluZ0tleU9mPFQ+ID0gRXh0cmFjdDxrZXlvZiBULCBzdHJpbmc+XG50eXBlIENhbGxiYWNrVHlwZTxcbiAgVCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIEV2ZW50TmFtZSBleHRlbmRzIFN0cmluZ0tleU9mPFQ+LFxuPiA9IFRbRXZlbnROYW1lXSBleHRlbmRzIGFueVtdID8gVFtFdmVudE5hbWVdIDogW1RbRXZlbnROYW1lXV1cbnR5cGUgQ2FsbGJhY2tGdW5jdGlvbjxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PiwgRXZlbnROYW1lIGV4dGVuZHMgU3RyaW5nS2V5T2Y8VD4+ID0gKFxuICAuLi5wcm9wczogQ2FsbGJhY2tUeXBlPFQsIEV2ZW50TmFtZT5cbikgPT4gYW55XG5cbmV4cG9ydCBjbGFzcyBFdmVudEVtaXR0ZXI8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAgcHJpdmF0ZSBjYWxsYmFja3M6IHsgW2tleTogc3RyaW5nXTogQXJyYXk8KC4uLmFyZ3M6IGFueVtdKSA9PiB2b2lkPiB9ID0ge31cblxuICBwdWJsaWMgb248RXZlbnROYW1lIGV4dGVuZHMgU3RyaW5nS2V5T2Y8VD4+KFxuICAgIGV2ZW50OiBFdmVudE5hbWUsXG4gICAgZm46IENhbGxiYWNrRnVuY3Rpb248VCwgRXZlbnROYW1lPixcbiAgKTogdGhpcyB7XG4gICAgaWYgKCF0aGlzLmNhbGxiYWNrc1tldmVudF0pIHtcbiAgICAgIHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IFtdXG4gICAgfVxuXG4gICAgdGhpcy5jYWxsYmFja3NbZXZlbnRdLnB1c2goZm4pXG5cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgcHVibGljIGVtaXQ8RXZlbnROYW1lIGV4dGVuZHMgU3RyaW5nS2V5T2Y8VD4+KFxuICAgIGV2ZW50OiBFdmVudE5hbWUsXG4gICAgLi4uYXJnczogQ2FsbGJhY2tUeXBlPFQsIEV2ZW50TmFtZT5cbiAgKTogdGhpcyB7XG4gICAgY29uc3QgY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3NbZXZlbnRdXG5cbiAgICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgICBjYWxsYmFja3MuZm9yRWFjaChjYWxsYmFjayA9PiBjYWxsYmFjay5hcHBseSh0aGlzLCBhcmdzKSlcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgcHVibGljIG9mZjxFdmVudE5hbWUgZXh0ZW5kcyBTdHJpbmdLZXlPZjxUPj4oXG4gICAgZXZlbnQ6IEV2ZW50TmFtZSxcbiAgICBmbj86IENhbGxiYWNrRnVuY3Rpb248VCwgRXZlbnROYW1lPixcbiAgKTogdGhpcyB7XG4gICAgY29uc3QgY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3NbZXZlbnRdXG5cbiAgICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgICBpZiAoZm4pIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3NbZXZlbnRdID0gY2FsbGJhY2tzLmZpbHRlcihjYWxsYmFjayA9PiBjYWxsYmFjayAhPT0gZm4pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja3NbZXZlbnRdXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXNcbiAgfVxuXG4gIHB1YmxpYyBvbmNlPEV2ZW50TmFtZSBleHRlbmRzIFN0cmluZ0tleU9mPFQ+PihcbiAgICBldmVudDogRXZlbnROYW1lLFxuICAgIGZuOiBDYWxsYmFja0Z1bmN0aW9uPFQsIEV2ZW50TmFtZT4sXG4gICk6IHRoaXMge1xuICAgIGNvbnN0IG9uY2VGbiA9ICguLi5hcmdzOiBDYWxsYmFja1R5cGU8VCwgRXZlbnROYW1lPikgPT4ge1xuICAgICAgdGhpcy5vZmYoZXZlbnQsIG9uY2VGbilcbiAgICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3MpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMub24oZXZlbnQsIG9uY2VGbilcbiAgfVxuXG4gIHB1YmxpYyByZW1vdmVBbGxMaXN0ZW5lcnMoKTogdm9pZCB7XG4gICAgdGhpcy5jYWxsYmFja3MgPSB7fVxuICB9XG59XG4iLCAiaW1wb3J0IHsga2V5bWFwIH0gZnJvbSAnQHRpcHRhcC9wbS9rZXltYXAnXG5pbXBvcnQgdHlwZSB7IFNjaGVtYSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgdHlwZSB7IFBsdWdpbiwgVHJhbnNhY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHR5cGUgeyBFZGl0b3JWaWV3LCBNYXJrVmlld0NvbnN0cnVjdG9yLCBOb2RlVmlld0NvbnN0cnVjdG9yIH0gZnJvbSAnQHRpcHRhcC9wbS92aWV3J1xuXG5pbXBvcnQgdHlwZSB7IEVkaXRvciB9IGZyb20gJy4vRWRpdG9yLmpzJ1xuaW1wb3J0IHtcbiAgZmxhdHRlbkV4dGVuc2lvbnMsXG4gIGdldEF0dHJpYnV0ZXNGcm9tRXh0ZW5zaW9ucyxcbiAgZ2V0RXh0ZW5zaW9uRmllbGQsXG4gIGdldE5vZGVUeXBlLFxuICBnZXRSZW5kZXJlZEF0dHJpYnV0ZXMsXG4gIGdldFNjaGVtYUJ5UmVzb2x2ZWRFeHRlbnNpb25zLFxuICBnZXRTY2hlbWFUeXBlQnlOYW1lLFxuICBpc0V4dGVuc2lvblJ1bGVzRW5hYmxlZCxcbiAgcmVzb2x2ZUV4dGVuc2lvbnMsXG4gIHNvcnRFeHRlbnNpb25zLFxuICBzcGxpdEV4dGVuc2lvbnMsXG59IGZyb20gJy4vaGVscGVycy9pbmRleC5qcydcbmltcG9ydCB7XG4gIHR5cGUgTWFya0NvbmZpZyxcbiAgdHlwZSBOb2RlQ29uZmlnLFxuICB0eXBlIFN0b3JhZ2UsXG4gIGdldE1hcmtUeXBlLFxuICB1cGRhdGVNYXJrVmlld0F0dHJpYnV0ZXMsXG59IGZyb20gJy4vaW5kZXguanMnXG5pbXBvcnQgeyBpbnB1dFJ1bGVzUGx1Z2luIH0gZnJvbSAnLi9JbnB1dFJ1bGUuanMnXG5pbXBvcnQgeyBNYXJrIH0gZnJvbSAnLi9NYXJrLmpzJ1xuaW1wb3J0IHsgcGFzdGVSdWxlc1BsdWdpbiB9IGZyb20gJy4vUGFzdGVSdWxlLmpzJ1xuaW1wb3J0IHR5cGUgeyBBbnlDb25maWcsIEV4dGVuc2lvbnMsIFJhd0NvbW1hbmRzIH0gZnJvbSAnLi90eXBlcy5qcydcbmltcG9ydCB7IGNhbGxPclJldHVybiB9IGZyb20gJy4vdXRpbGl0aWVzL2NhbGxPclJldHVybi5qcydcblxuZXhwb3J0IGNsYXNzIEV4dGVuc2lvbk1hbmFnZXIge1xuICBlZGl0b3I6IEVkaXRvclxuXG4gIHNjaGVtYTogU2NoZW1hXG5cbiAgLyoqXG4gICAqIEEgZmxhdHRlbmVkIGFuZCBzb3J0ZWQgYXJyYXkgb2YgYWxsIGV4dGVuc2lvbnNcbiAgICovXG4gIGV4dGVuc2lvbnM6IEV4dGVuc2lvbnNcblxuICAvKipcbiAgICogQSBub24tZmxhdHRlbmVkIGFycmF5IG9mIGJhc2UgZXh0ZW5zaW9ucyAobm8gc3ViLWV4dGVuc2lvbnMpXG4gICAqL1xuICBiYXNlRXh0ZW5zaW9uczogRXh0ZW5zaW9uc1xuXG4gIHNwbGl0dGFibGVNYXJrczogc3RyaW5nW10gPSBbXVxuXG4gIG5vbkNsZWFyYWJsZU1hcmtzOiBzdHJpbmdbXSA9IFtdXG5cbiAgY29uc3RydWN0b3IoZXh0ZW5zaW9uczogRXh0ZW5zaW9ucywgZWRpdG9yOiBFZGl0b3IpIHtcbiAgICB0aGlzLmVkaXRvciA9IGVkaXRvclxuICAgIHRoaXMuYmFzZUV4dGVuc2lvbnMgPSBleHRlbnNpb25zXG4gICAgdGhpcy5leHRlbnNpb25zID0gcmVzb2x2ZUV4dGVuc2lvbnMoZXh0ZW5zaW9ucylcbiAgICB0aGlzLnNjaGVtYSA9IGdldFNjaGVtYUJ5UmVzb2x2ZWRFeHRlbnNpb25zKHRoaXMuZXh0ZW5zaW9ucywgZWRpdG9yKVxuICAgIHRoaXMuc2V0dXBFeHRlbnNpb25zKClcbiAgfVxuXG4gIHN0YXRpYyByZXNvbHZlID0gcmVzb2x2ZUV4dGVuc2lvbnNcblxuICBzdGF0aWMgc29ydCA9IHNvcnRFeHRlbnNpb25zXG5cbiAgc3RhdGljIGZsYXR0ZW4gPSBmbGF0dGVuRXh0ZW5zaW9uc1xuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGNvbW1hbmRzIGZyb20gdGhlIGV4dGVuc2lvbnMuXG4gICAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIGFsbCBjb21tYW5kcyB3aGVyZSB0aGUga2V5IGlzIHRoZSBjb21tYW5kIG5hbWUgYW5kIHRoZSB2YWx1ZSBpcyB0aGUgY29tbWFuZCBmdW5jdGlvblxuICAgKi9cbiAgZ2V0IGNvbW1hbmRzKCk6IFJhd0NvbW1hbmRzIHtcbiAgICByZXR1cm4gdGhpcy5leHRlbnNpb25zLnJlZHVjZSgoY29tbWFuZHMsIGV4dGVuc2lvbikgPT4ge1xuICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgIG9wdGlvbnM6IGV4dGVuc2lvbi5vcHRpb25zLFxuICAgICAgICBzdG9yYWdlOiB0aGlzLmVkaXRvci5leHRlbnNpb25TdG9yYWdlW2V4dGVuc2lvbi5uYW1lIGFzIGtleW9mIFN0b3JhZ2VdLFxuICAgICAgICBlZGl0b3I6IHRoaXMuZWRpdG9yLFxuICAgICAgICB0eXBlOiBnZXRTY2hlbWFUeXBlQnlOYW1lKGV4dGVuc2lvbi5uYW1lLCB0aGlzLnNjaGVtYSksXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFkZENvbW1hbmRzID0gZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydhZGRDb21tYW5kcyddPihcbiAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAnYWRkQ29tbWFuZHMnLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKVxuXG4gICAgICBpZiAoIWFkZENvbW1hbmRzKSB7XG4gICAgICAgIHJldHVybiBjb21tYW5kc1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5jb21tYW5kcyxcbiAgICAgICAgLi4uYWRkQ29tbWFuZHMoKSxcbiAgICAgIH1cbiAgICB9LCB7fSBhcyBSYXdDb21tYW5kcylcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIHJlZ2lzdGVyZWQgUHJvc2VtaXJyb3IgcGx1Z2lucyBmcm9tIHRoZSBleHRlbnNpb25zLlxuICAgKiBAcmV0dXJucyBBbiBhcnJheSBvZiBQcm9zZW1pcnJvciBwbHVnaW5zXG4gICAqL1xuICBnZXQgcGx1Z2lucygpOiBQbHVnaW5bXSB7XG4gICAgY29uc3QgeyBlZGl0b3IgfSA9IHRoaXNcblxuICAgIC8vIFdpdGggUHJvc2VNaXJyb3IsIGZpcnN0IHBsdWdpbnMgd2l0aGluIGFuIGFycmF5IGFyZSBleGVjdXRlZCBmaXJzdC5cbiAgICAvLyBJbiBUaXB0YXAsIHdlIHByb3ZpZGUgdGhlIGFiaWxpdHkgdG8gb3ZlcnJpZGUgcGx1Z2lucyxcbiAgICAvLyBzbyBpdCBmZWVscyBtb3JlIG5hdHVyYWwgdG8gcnVuIHBsdWdpbnMgYXQgdGhlIGVuZCBvZiBhbiBhcnJheSBmaXJzdC5cbiAgICAvLyBUaGF04oCZcyB3aHkgd2UgaGF2ZSB0byByZXZlcnNlIHRoZSBgZXh0ZW5zaW9uc2AgYXJyYXkgYW5kIHNvcnQgYWdhaW5cbiAgICAvLyBiYXNlZCBvbiB0aGUgYHByaW9yaXR5YCBvcHRpb24uXG4gICAgY29uc3QgZXh0ZW5zaW9ucyA9IHNvcnRFeHRlbnNpb25zKFsuLi50aGlzLmV4dGVuc2lvbnNdLnJldmVyc2UoKSlcblxuICAgIGNvbnN0IGFsbFBsdWdpbnMgPSBleHRlbnNpb25zLmZsYXRNYXAoZXh0ZW5zaW9uID0+IHtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgICAgIG5hbWU6IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgICBvcHRpb25zOiBleHRlbnNpb24ub3B0aW9ucyxcbiAgICAgICAgc3RvcmFnZTogdGhpcy5lZGl0b3IuZXh0ZW5zaW9uU3RvcmFnZVtleHRlbnNpb24ubmFtZSBhcyBrZXlvZiBTdG9yYWdlXSxcbiAgICAgICAgZWRpdG9yLFxuICAgICAgICB0eXBlOiBnZXRTY2hlbWFUeXBlQnlOYW1lKGV4dGVuc2lvbi5uYW1lLCB0aGlzLnNjaGVtYSksXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBsdWdpbnM6IFBsdWdpbltdID0gW11cblxuICAgICAgY29uc3QgYWRkS2V5Ym9hcmRTaG9ydGN1dHMgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZEtleWJvYXJkU2hvcnRjdXRzJ10+KFxuICAgICAgICBleHRlbnNpb24sXG4gICAgICAgICdhZGRLZXlib2FyZFNob3J0Y3V0cycsXG4gICAgICAgIGNvbnRleHQsXG4gICAgICApXG5cbiAgICAgIGxldCBkZWZhdWx0QmluZGluZ3M6IFJlY29yZDxzdHJpbmcsICgpID0+IGJvb2xlYW4+ID0ge31cblxuICAgICAgLy8gYmluZCBleGl0IGhhbmRsaW5nXG4gICAgICBpZiAoXG4gICAgICAgIGV4dGVuc2lvbi50eXBlID09PSAnbWFyaycgJiZcbiAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8TWFya0NvbmZpZ1snZXhpdGFibGUnXT4oZXh0ZW5zaW9uLCAnZXhpdGFibGUnLCBjb250ZXh0KVxuICAgICAgKSB7XG4gICAgICAgIGRlZmF1bHRCaW5kaW5ncy5BcnJvd1JpZ2h0ID0gKCkgPT4gTWFyay5oYW5kbGVFeGl0KHsgZWRpdG9yLCBtYXJrOiBleHRlbnNpb24gYXMgTWFyayB9KVxuICAgICAgfVxuXG4gICAgICBpZiAoYWRkS2V5Ym9hcmRTaG9ydGN1dHMpIHtcbiAgICAgICAgY29uc3QgYmluZGluZ3MgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgT2JqZWN0LmVudHJpZXMoYWRkS2V5Ym9hcmRTaG9ydGN1dHMoKSkubWFwKChbc2hvcnRjdXQsIG1ldGhvZF0pID0+IHtcbiAgICAgICAgICAgIHJldHVybiBbc2hvcnRjdXQsICgpID0+IG1ldGhvZCh7IGVkaXRvciB9KV1cbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuXG4gICAgICAgIGRlZmF1bHRCaW5kaW5ncyA9IHsgLi4uZGVmYXVsdEJpbmRpbmdzLCAuLi5iaW5kaW5ncyB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGtleU1hcFBsdWdpbiA9IGtleW1hcChkZWZhdWx0QmluZGluZ3MpXG5cbiAgICAgIHBsdWdpbnMucHVzaChrZXlNYXBQbHVnaW4pXG5cbiAgICAgIGNvbnN0IGFkZElucHV0UnVsZXMgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZElucHV0UnVsZXMnXT4oXG4gICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgJ2FkZElucHV0UnVsZXMnLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKVxuXG4gICAgICBpZiAoaXNFeHRlbnNpb25SdWxlc0VuYWJsZWQoZXh0ZW5zaW9uLCBlZGl0b3Iub3B0aW9ucy5lbmFibGVJbnB1dFJ1bGVzKSAmJiBhZGRJbnB1dFJ1bGVzKSB7XG4gICAgICAgIGNvbnN0IHJ1bGVzID0gYWRkSW5wdXRSdWxlcygpXG5cbiAgICAgICAgaWYgKHJ1bGVzICYmIHJ1bGVzLmxlbmd0aCkge1xuICAgICAgICAgIGNvbnN0IGlucHV0UmVzdWx0ID0gaW5wdXRSdWxlc1BsdWdpbih7XG4gICAgICAgICAgICBlZGl0b3IsXG4gICAgICAgICAgICBydWxlcyxcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgY29uc3QgaW5wdXRQbHVnaW5zID0gQXJyYXkuaXNBcnJheShpbnB1dFJlc3VsdCkgPyBpbnB1dFJlc3VsdCA6IFtpbnB1dFJlc3VsdF1cblxuICAgICAgICAgIHBsdWdpbnMucHVzaCguLi5pbnB1dFBsdWdpbnMpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgYWRkUGFzdGVSdWxlcyA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snYWRkUGFzdGVSdWxlcyddPihcbiAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAnYWRkUGFzdGVSdWxlcycsXG4gICAgICAgIGNvbnRleHQsXG4gICAgICApXG5cbiAgICAgIGlmIChpc0V4dGVuc2lvblJ1bGVzRW5hYmxlZChleHRlbnNpb24sIGVkaXRvci5vcHRpb25zLmVuYWJsZVBhc3RlUnVsZXMpICYmIGFkZFBhc3RlUnVsZXMpIHtcbiAgICAgICAgY29uc3QgcnVsZXMgPSBhZGRQYXN0ZVJ1bGVzKClcblxuICAgICAgICBpZiAocnVsZXMgJiYgcnVsZXMubGVuZ3RoKSB7XG4gICAgICAgICAgY29uc3QgcGFzdGVSdWxlcyA9IHBhc3RlUnVsZXNQbHVnaW4oeyBlZGl0b3IsIHJ1bGVzIH0pXG5cbiAgICAgICAgICBwbHVnaW5zLnB1c2goLi4ucGFzdGVSdWxlcylcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBhZGRQcm9zZU1pcnJvclBsdWdpbnMgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZFByb3NlTWlycm9yUGx1Z2lucyddPihcbiAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAnYWRkUHJvc2VNaXJyb3JQbHVnaW5zJyxcbiAgICAgICAgY29udGV4dCxcbiAgICAgIClcblxuICAgICAgaWYgKGFkZFByb3NlTWlycm9yUGx1Z2lucykge1xuICAgICAgICBjb25zdCBwcm9zZU1pcnJvclBsdWdpbnMgPSBhZGRQcm9zZU1pcnJvclBsdWdpbnMoKVxuXG4gICAgICAgIHBsdWdpbnMucHVzaCguLi5wcm9zZU1pcnJvclBsdWdpbnMpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwbHVnaW5zXG4gICAgfSlcblxuICAgIHJldHVybiBhbGxQbHVnaW5zXG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBhdHRyaWJ1dGVzIGZyb20gdGhlIGV4dGVuc2lvbnMuXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGF0dHJpYnV0ZXNcbiAgICovXG4gIGdldCBhdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBnZXRBdHRyaWJ1dGVzRnJvbUV4dGVuc2lvbnModGhpcy5leHRlbnNpb25zKVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgbm9kZSB2aWV3cyBmcm9tIHRoZSBleHRlbnNpb25zLlxuICAgKiBAcmV0dXJucyBBbiBvYmplY3Qgd2l0aCBhbGwgbm9kZSB2aWV3cyB3aGVyZSB0aGUga2V5IGlzIHRoZSBub2RlIG5hbWUgYW5kIHRoZSB2YWx1ZSBpcyB0aGUgbm9kZSB2aWV3IGZ1bmN0aW9uXG4gICAqL1xuICBnZXQgbm9kZVZpZXdzKCk6IFJlY29yZDxzdHJpbmcsIE5vZGVWaWV3Q29uc3RydWN0b3I+IHtcbiAgICBjb25zdCB7IGVkaXRvciB9ID0gdGhpc1xuICAgIGNvbnN0IHsgbm9kZUV4dGVuc2lvbnMgfSA9IHNwbGl0RXh0ZW5zaW9ucyh0aGlzLmV4dGVuc2lvbnMpXG5cbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgbm9kZUV4dGVuc2lvbnNcbiAgICAgICAgLmZpbHRlcihleHRlbnNpb24gPT4gISFnZXRFeHRlbnNpb25GaWVsZChleHRlbnNpb24sICdhZGROb2RlVmlldycpKVxuICAgICAgICAubWFwKGV4dGVuc2lvbiA9PiB7XG4gICAgICAgICAgY29uc3QgZXh0ZW5zaW9uQXR0cmlidXRlcyA9IHRoaXMuYXR0cmlidXRlcy5maWx0ZXIoXG4gICAgICAgICAgICBhdHRyaWJ1dGUgPT4gYXR0cmlidXRlLnR5cGUgPT09IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgICAgIClcbiAgICAgICAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgICAgICBvcHRpb25zOiBleHRlbnNpb24ub3B0aW9ucyxcbiAgICAgICAgICAgIHN0b3JhZ2U6IHRoaXMuZWRpdG9yLmV4dGVuc2lvblN0b3JhZ2VbZXh0ZW5zaW9uLm5hbWUgYXMga2V5b2YgU3RvcmFnZV0sXG4gICAgICAgICAgICBlZGl0b3IsXG4gICAgICAgICAgICB0eXBlOiBnZXROb2RlVHlwZShleHRlbnNpb24ubmFtZSwgdGhpcy5zY2hlbWEpLFxuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhZGROb2RlVmlldyA9IGdldEV4dGVuc2lvbkZpZWxkPE5vZGVDb25maWdbJ2FkZE5vZGVWaWV3J10+KFxuICAgICAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAgICAgJ2FkZE5vZGVWaWV3JyxcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgKVxuXG4gICAgICAgICAgaWYgKCFhZGROb2RlVmlldykge1xuICAgICAgICAgICAgcmV0dXJuIFtdXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3Qgbm9kZVZpZXdSZXN1bHQgPSBhZGROb2RlVmlldygpXG5cbiAgICAgICAgICBpZiAoIW5vZGVWaWV3UmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gW11cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBub2RldmlldzogTm9kZVZpZXdDb25zdHJ1Y3RvciA9IChcbiAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICB2aWV3LFxuICAgICAgICAgICAgZ2V0UG9zLFxuICAgICAgICAgICAgZGVjb3JhdGlvbnMsXG4gICAgICAgICAgICBpbm5lckRlY29yYXRpb25zLFxuICAgICAgICAgICkgPT4ge1xuICAgICAgICAgICAgY29uc3QgSFRNTEF0dHJpYnV0ZXMgPSBnZXRSZW5kZXJlZEF0dHJpYnV0ZXMobm9kZSwgZXh0ZW5zaW9uQXR0cmlidXRlcylcblxuICAgICAgICAgICAgcmV0dXJuIG5vZGVWaWV3UmVzdWx0KHtcbiAgICAgICAgICAgICAgLy8gcGFzcy10aHJvdWdoXG4gICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgIHZpZXcsXG4gICAgICAgICAgICAgIGdldFBvczogZ2V0UG9zIGFzICgpID0+IG51bWJlcixcbiAgICAgICAgICAgICAgZGVjb3JhdGlvbnMsXG4gICAgICAgICAgICAgIGlubmVyRGVjb3JhdGlvbnMsXG4gICAgICAgICAgICAgIC8vIHRpcHRhcC1zcGVjaWZpY1xuICAgICAgICAgICAgICBlZGl0b3IsXG4gICAgICAgICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgICAgICAgSFRNTEF0dHJpYnV0ZXMsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBbZXh0ZW5zaW9uLm5hbWUsIG5vZGV2aWV3XVxuICAgICAgICB9KSxcbiAgICApXG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjb21wb3NlZCBkaXNwYXRjaFRyYW5zYWN0aW9uIGZ1bmN0aW9uIGZyb20gYWxsIGV4dGVuc2lvbnMuXG4gICAqIEBwYXJhbSBiYXNlRGlzcGF0Y2ggVGhlIGJhc2UgZGlzcGF0Y2ggZnVuY3Rpb24gKGUuZy4gZnJvbSB0aGUgZWRpdG9yIG9yIHVzZXIgcHJvcHMpXG4gICAqIEByZXR1cm5zIEEgY29tcG9zZWQgZGlzcGF0Y2ggZnVuY3Rpb25cbiAgICovXG4gIGRpc3BhdGNoVHJhbnNhY3Rpb24oYmFzZURpc3BhdGNoOiAodHI6IFRyYW5zYWN0aW9uKSA9PiB2b2lkKTogKHRyOiBUcmFuc2FjdGlvbikgPT4gdm9pZCB7XG4gICAgY29uc3QgeyBlZGl0b3IgfSA9IHRoaXNcbiAgICBjb25zdCBleHRlbnNpb25zID0gc29ydEV4dGVuc2lvbnMoWy4uLnRoaXMuZXh0ZW5zaW9uc10ucmV2ZXJzZSgpKVxuXG4gICAgcmV0dXJuIGV4dGVuc2lvbnMucmVkdWNlUmlnaHQoKG5leHQsIGV4dGVuc2lvbikgPT4ge1xuICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgIG9wdGlvbnM6IGV4dGVuc2lvbi5vcHRpb25zLFxuICAgICAgICBzdG9yYWdlOiB0aGlzLmVkaXRvci5leHRlbnNpb25TdG9yYWdlW2V4dGVuc2lvbi5uYW1lIGFzIGtleW9mIFN0b3JhZ2VdLFxuICAgICAgICBlZGl0b3IsXG4gICAgICAgIHR5cGU6IGdldFNjaGVtYVR5cGVCeU5hbWUoZXh0ZW5zaW9uLm5hbWUsIHRoaXMuc2NoZW1hKSxcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGlzcGF0Y2hUcmFuc2FjdGlvbiA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snZGlzcGF0Y2hUcmFuc2FjdGlvbiddPihcbiAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAnZGlzcGF0Y2hUcmFuc2FjdGlvbicsXG4gICAgICAgIGNvbnRleHQsXG4gICAgICApXG5cbiAgICAgIGlmICghZGlzcGF0Y2hUcmFuc2FjdGlvbikge1xuICAgICAgICByZXR1cm4gbmV4dFxuICAgICAgfVxuXG4gICAgICByZXR1cm4gKHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbikgPT4ge1xuICAgICAgICBkaXNwYXRjaFRyYW5zYWN0aW9uLmNhbGwoY29udGV4dCwgeyB0cmFuc2FjdGlvbiwgbmV4dCB9KVxuICAgICAgfVxuICAgIH0sIGJhc2VEaXNwYXRjaClcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGNvbXBvc2VkIHRyYW5zZm9ybVBhc3RlZEhUTUwgZnVuY3Rpb24gZnJvbSBhbGwgZXh0ZW5zaW9ucy5cbiAgICogQHBhcmFtIGJhc2VUcmFuc2Zvcm0gVGhlIGJhc2UgdHJhbnNmb3JtIGZ1bmN0aW9uIChlLmcuIGZyb20gdGhlIGVkaXRvciBwcm9wcylcbiAgICogQHJldHVybnMgQSBjb21wb3NlZCB0cmFuc2Zvcm0gZnVuY3Rpb24gdGhhdCBjaGFpbnMgYWxsIGV4dGVuc2lvbiB0cmFuc2Zvcm1zXG4gICAqL1xuICB0cmFuc2Zvcm1QYXN0ZWRIVE1MKFxuICAgIGJhc2VUcmFuc2Zvcm0/OiAoaHRtbDogc3RyaW5nLCB2aWV3PzogYW55KSA9PiBzdHJpbmcsXG4gICk6IChodG1sOiBzdHJpbmcsIHZpZXc/OiBFZGl0b3JWaWV3KSA9PiBzdHJpbmcge1xuICAgIGNvbnN0IHsgZWRpdG9yIH0gPSB0aGlzXG4gICAgY29uc3QgZXh0ZW5zaW9ucyA9IHNvcnRFeHRlbnNpb25zKFsuLi50aGlzLmV4dGVuc2lvbnNdKVxuXG4gICAgcmV0dXJuIGV4dGVuc2lvbnMucmVkdWNlKFxuICAgICAgKHRyYW5zZm9ybSwgZXh0ZW5zaW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgICAgb3B0aW9uczogZXh0ZW5zaW9uLm9wdGlvbnMsXG4gICAgICAgICAgc3RvcmFnZTogdGhpcy5lZGl0b3IuZXh0ZW5zaW9uU3RvcmFnZVtleHRlbnNpb24ubmFtZSBhcyBrZXlvZiBTdG9yYWdlXSxcbiAgICAgICAgICBlZGl0b3IsXG4gICAgICAgICAgdHlwZTogZ2V0U2NoZW1hVHlwZUJ5TmFtZShleHRlbnNpb24ubmFtZSwgdGhpcy5zY2hlbWEpLFxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uVHJhbnNmb3JtID0gZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWyd0cmFuc2Zvcm1QYXN0ZWRIVE1MJ10+KFxuICAgICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgICAndHJhbnNmb3JtUGFzdGVkSFRNTCcsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgKVxuXG4gICAgICAgIGlmICghZXh0ZW5zaW9uVHJhbnNmb3JtKSB7XG4gICAgICAgICAgcmV0dXJuIHRyYW5zZm9ybVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChodG1sOiBzdHJpbmcsIHZpZXc/OiBhbnkpID0+IHtcbiAgICAgICAgICAvLyBDaGFpbiB0aGUgdHJhbnNmb3JtczogcGFzcyB0aGUgcmVzdWx0IG9mIHRoZSBwcmV2aW91cyB0cmFuc2Zvcm0gdG8gdGhlIG5leHRcbiAgICAgICAgICBjb25zdCB0cmFuc2Zvcm1lZEh0bWwgPSB0cmFuc2Zvcm0oaHRtbCwgdmlldylcbiAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uVHJhbnNmb3JtLmNhbGwoY29udGV4dCwgdHJhbnNmb3JtZWRIdG1sKVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgYmFzZVRyYW5zZm9ybSB8fCAoKGh0bWw6IHN0cmluZykgPT4gaHRtbCksXG4gICAgKVxuICB9XG5cbiAgZ2V0IG1hcmtWaWV3cygpOiBSZWNvcmQ8c3RyaW5nLCBNYXJrVmlld0NvbnN0cnVjdG9yPiB7XG4gICAgY29uc3QgeyBlZGl0b3IgfSA9IHRoaXNcbiAgICBjb25zdCB7IG1hcmtFeHRlbnNpb25zIH0gPSBzcGxpdEV4dGVuc2lvbnModGhpcy5leHRlbnNpb25zKVxuXG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIG1hcmtFeHRlbnNpb25zXG4gICAgICAgIC5maWx0ZXIoZXh0ZW5zaW9uID0+ICEhZ2V0RXh0ZW5zaW9uRmllbGQoZXh0ZW5zaW9uLCAnYWRkTWFya1ZpZXcnKSlcbiAgICAgICAgLm1hcChleHRlbnNpb24gPT4ge1xuICAgICAgICAgIGNvbnN0IGV4dGVuc2lvbkF0dHJpYnV0ZXMgPSB0aGlzLmF0dHJpYnV0ZXMuZmlsdGVyKFxuICAgICAgICAgICAgYXR0cmlidXRlID0+IGF0dHJpYnV0ZS50eXBlID09PSBleHRlbnNpb24ubmFtZSxcbiAgICAgICAgICApXG4gICAgICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgICAgIG5hbWU6IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgICAgICAgb3B0aW9uczogZXh0ZW5zaW9uLm9wdGlvbnMsXG4gICAgICAgICAgICBzdG9yYWdlOiB0aGlzLmVkaXRvci5leHRlbnNpb25TdG9yYWdlW2V4dGVuc2lvbi5uYW1lIGFzIGtleW9mIFN0b3JhZ2VdLFxuICAgICAgICAgICAgZWRpdG9yLFxuICAgICAgICAgICAgdHlwZTogZ2V0TWFya1R5cGUoZXh0ZW5zaW9uLm5hbWUsIHRoaXMuc2NoZW1hKSxcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgYWRkTWFya1ZpZXcgPSBnZXRFeHRlbnNpb25GaWVsZDxNYXJrQ29uZmlnWydhZGRNYXJrVmlldyddPihcbiAgICAgICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgICAgICdhZGRNYXJrVmlldycsXG4gICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIClcblxuICAgICAgICAgIGlmICghYWRkTWFya1ZpZXcpIHtcbiAgICAgICAgICAgIHJldHVybiBbXVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IG1hcmtWaWV3OiBNYXJrVmlld0NvbnN0cnVjdG9yID0gKG1hcmssIHZpZXcsIGlubGluZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgSFRNTEF0dHJpYnV0ZXMgPSBnZXRSZW5kZXJlZEF0dHJpYnV0ZXMobWFyaywgZXh0ZW5zaW9uQXR0cmlidXRlcylcblxuICAgICAgICAgICAgcmV0dXJuIGFkZE1hcmtWaWV3KCkoe1xuICAgICAgICAgICAgICAvLyBwYXNzLXRocm91Z2hcbiAgICAgICAgICAgICAgbWFyayxcbiAgICAgICAgICAgICAgdmlldyxcbiAgICAgICAgICAgICAgaW5saW5lLFxuICAgICAgICAgICAgICAvLyB0aXB0YXAtc3BlY2lmaWNcbiAgICAgICAgICAgICAgZWRpdG9yLFxuICAgICAgICAgICAgICBleHRlbnNpb24sXG4gICAgICAgICAgICAgIEhUTUxBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICB1cGRhdGVBdHRyaWJ1dGVzOiAoYXR0cnM6IFJlY29yZDxzdHJpbmcsIGFueT4pID0+IHtcbiAgICAgICAgICAgICAgICB1cGRhdGVNYXJrVmlld0F0dHJpYnV0ZXMobWFyaywgZWRpdG9yLCBhdHRycylcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIFtleHRlbnNpb24ubmFtZSwgbWFya1ZpZXddXG4gICAgICAgIH0pLFxuICAgIClcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cm95IHRoZSBleHRlbnNpb24gbWFuYWdlciBhbmQgY2xlYW4gdXAgYWxsIGV4dGVuc2lvbiByZWZlcmVuY2VzXG4gICAqIHRvIHByZXZlbnQgbWVtb3J5IGxlYWtzIHRocm91Z2ggcGFyZW50L2NoaWxkIGV4dGVuc2lvbiBjaGFpbnMuXG4gICAqXG4gICAqIFdhbGtzIGVhY2ggZXh0ZW5zaW9uJ3MgZnVsbCBwYXJlbnQgY2hhaW4gYW5kIG51bGxzIGV2ZXJ5IGZvcndhcmRcbiAgICogYHBhcmVudC5jaGlsZCDihpIgY3VycmVudGAgbGluayB3aGVyZSB0aGUgcGFyZW50IHN0aWxsIHBvaW50cyB0byB0aGVcbiAgICogY3VycmVudCBub2RlLiBUaGlzIGJyZWFrcyB0aGUgcmV0ZW50aW9uIHBhdGggZnJvbSBtb2R1bGUtc2NvcGVcbiAgICogc2luZ2xldG9uIHJvb3RzIHRocm91Z2ggZGVlcCBleHRlbmQoKSBjaGFpbnMuXG4gICAqXG4gICAqIE9ubHkgYW5jZXN0b3IgYC5jaGlsZGAgbGlua3MgbWF0Y2hpbmcgdGhlIGN1cnJlbnQgY2hhaW4gYXJlIGNsZWFyZWQuXG4gICAqIFRoZSBgLnBhcmVudGAgcG9pbnRlciBvbiBhbmNlc3RvcnMgaXMgbmV2ZXIgdG91Y2hlZCDigJQgZXh0ZW5zaW9uc1xuICAgKiBtYXkgYmUgc2hhcmVkIGFjcm9zcyBsaXZlIGVkaXRvcnMsIHNvIHRoZWlyIG93biBiYWNrd2FyZCByZWZlcmVuY2VzXG4gICAqIGFuZCBub24tbWF0Y2hpbmcgZm9yd2FyZCBsaW5rcyBtdXN0IHJlbWFpbiBpbnRhY3QuXG4gICAqL1xuICBkZXN0cm95KCkge1xuICAgIHRoaXMuZXh0ZW5zaW9ucy5mb3JFYWNoKGV4dGVuc2lvbiA9PiB7XG4gICAgICBsZXQgY3VycmVudDogYW55ID0gZXh0ZW5zaW9uXG5cbiAgICAgIHdoaWxlIChjdXJyZW50LnBhcmVudCkge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBjdXJyZW50LnBhcmVudFxuXG4gICAgICAgIGlmIChwYXJlbnQuY2hpbGQgPT09IGN1cnJlbnQpIHtcbiAgICAgICAgICBwYXJlbnQuY2hpbGQgPSBudWxsXG4gICAgICAgIH1cblxuICAgICAgICBjdXJyZW50ID0gcGFyZW50XG4gICAgICB9XG4gICAgfSlcblxuICAgIHRoaXMuZXh0ZW5zaW9ucyA9IFtdXG4gICAgdGhpcy5iYXNlRXh0ZW5zaW9ucyA9IFtdXG4gICAgdGhpcy5zY2hlbWEgPSBudWxsIGFzIGFueVxuICAgIHRoaXMuZWRpdG9yID0gbnVsbCBhcyBhbnlcbiAgfVxuXG4gIC8qKlxuICAgKiBHbyB0aHJvdWdoIGFsbCBleHRlbnNpb25zLCBjcmVhdGUgZXh0ZW5zaW9uIHN0b3JhZ2VzICYgc2V0dXAgbWFya3NcbiAgICogJiBiaW5kIGVkaXRvciBldmVudCBsaXN0ZW5lci5cbiAgICovXG4gIHByaXZhdGUgc2V0dXBFeHRlbnNpb25zKCkge1xuICAgIGNvbnN0IGV4dGVuc2lvbnMgPSB0aGlzLmV4dGVuc2lvbnNcbiAgICAvLyByZS1pbml0aWFsaXplIHRoZSBleHRlbnNpb24gc3RvcmFnZSBvYmplY3QgaW5zdGFuY2VcbiAgICB0aGlzLmVkaXRvci5leHRlbnNpb25TdG9yYWdlID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgZXh0ZW5zaW9ucy5tYXAoZXh0ZW5zaW9uID0+IFtleHRlbnNpb24ubmFtZSwgZXh0ZW5zaW9uLnN0b3JhZ2VdKSxcbiAgICApIGFzIHVua25vd24gYXMgU3RvcmFnZVxuXG4gICAgZXh0ZW5zaW9ucy5mb3JFYWNoKGV4dGVuc2lvbiA9PiB7XG4gICAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgICBuYW1lOiBleHRlbnNpb24ubmFtZSxcbiAgICAgICAgb3B0aW9uczogZXh0ZW5zaW9uLm9wdGlvbnMsXG4gICAgICAgIHN0b3JhZ2U6IHRoaXMuZWRpdG9yLmV4dGVuc2lvblN0b3JhZ2VbZXh0ZW5zaW9uLm5hbWUgYXMga2V5b2YgU3RvcmFnZV0sXG4gICAgICAgIGVkaXRvcjogdGhpcy5lZGl0b3IsXG4gICAgICAgIHR5cGU6IGdldFNjaGVtYVR5cGVCeU5hbWUoZXh0ZW5zaW9uLm5hbWUsIHRoaXMuc2NoZW1hKSxcbiAgICAgIH1cblxuICAgICAgaWYgKGV4dGVuc2lvbi50eXBlID09PSAnbWFyaycpIHtcbiAgICAgICAgY29uc3Qga2VlcE9uU3BsaXQgPVxuICAgICAgICAgIGNhbGxPclJldHVybihnZXRFeHRlbnNpb25GaWVsZChleHRlbnNpb24sICdrZWVwT25TcGxpdCcsIGNvbnRleHQpKSA/PyB0cnVlXG5cbiAgICAgICAgaWYgKGtlZXBPblNwbGl0KSB7XG4gICAgICAgICAgdGhpcy5zcGxpdHRhYmxlTWFya3MucHVzaChleHRlbnNpb24ubmFtZSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsZWFyYWJsZSA9XG4gICAgICAgICAgY2FsbE9yUmV0dXJuKFxuICAgICAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8TWFya0NvbmZpZ1snY2xlYXJhYmxlJ10+KGV4dGVuc2lvbiwgJ2NsZWFyYWJsZScsIGNvbnRleHQpLFxuICAgICAgICAgICkgPz8gdHJ1ZVxuXG4gICAgICAgIGlmICghY2xlYXJhYmxlKSB7XG4gICAgICAgICAgdGhpcy5ub25DbGVhcmFibGVNYXJrcy5wdXNoKGV4dGVuc2lvbi5uYW1lKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9uQmVmb3JlQ3JlYXRlID0gZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydvbkJlZm9yZUNyZWF0ZSddPihcbiAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAnb25CZWZvcmVDcmVhdGUnLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKVxuICAgICAgY29uc3Qgb25DcmVhdGUgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ29uQ3JlYXRlJ10+KGV4dGVuc2lvbiwgJ29uQ3JlYXRlJywgY29udGV4dClcbiAgICAgIGNvbnN0IG9uVXBkYXRlID0gZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydvblVwZGF0ZSddPihleHRlbnNpb24sICdvblVwZGF0ZScsIGNvbnRleHQpXG4gICAgICBjb25zdCBvblNlbGVjdGlvblVwZGF0ZSA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snb25TZWxlY3Rpb25VcGRhdGUnXT4oXG4gICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgJ29uU2VsZWN0aW9uVXBkYXRlJyxcbiAgICAgICAgY29udGV4dCxcbiAgICAgIClcbiAgICAgIGNvbnN0IG9uVHJhbnNhY3Rpb24gPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ29uVHJhbnNhY3Rpb24nXT4oXG4gICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgJ29uVHJhbnNhY3Rpb24nLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKVxuICAgICAgY29uc3Qgb25Gb2N1cyA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snb25Gb2N1cyddPihleHRlbnNpb24sICdvbkZvY3VzJywgY29udGV4dClcbiAgICAgIGNvbnN0IG9uQmx1ciA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snb25CbHVyJ10+KGV4dGVuc2lvbiwgJ29uQmx1cicsIGNvbnRleHQpXG4gICAgICBjb25zdCBvbkRlc3Ryb3kgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ29uRGVzdHJveSddPihleHRlbnNpb24sICdvbkRlc3Ryb3knLCBjb250ZXh0KVxuXG4gICAgICBpZiAob25CZWZvcmVDcmVhdGUpIHtcbiAgICAgICAgdGhpcy5lZGl0b3Iub24oJ2JlZm9yZUNyZWF0ZScsIG9uQmVmb3JlQ3JlYXRlKVxuICAgICAgfVxuXG4gICAgICBpZiAob25DcmVhdGUpIHtcbiAgICAgICAgdGhpcy5lZGl0b3Iub24oJ2NyZWF0ZScsIG9uQ3JlYXRlKVxuICAgICAgfVxuXG4gICAgICBpZiAob25VcGRhdGUpIHtcbiAgICAgICAgdGhpcy5lZGl0b3Iub24oJ3VwZGF0ZScsIG9uVXBkYXRlKVxuICAgICAgfVxuXG4gICAgICBpZiAob25TZWxlY3Rpb25VcGRhdGUpIHtcbiAgICAgICAgdGhpcy5lZGl0b3Iub24oJ3NlbGVjdGlvblVwZGF0ZScsIG9uU2VsZWN0aW9uVXBkYXRlKVxuICAgICAgfVxuXG4gICAgICBpZiAob25UcmFuc2FjdGlvbikge1xuICAgICAgICB0aGlzLmVkaXRvci5vbigndHJhbnNhY3Rpb24nLCBvblRyYW5zYWN0aW9uKVxuICAgICAgfVxuXG4gICAgICBpZiAob25Gb2N1cykge1xuICAgICAgICB0aGlzLmVkaXRvci5vbignZm9jdXMnLCBvbkZvY3VzKVxuICAgICAgfVxuXG4gICAgICBpZiAob25CbHVyKSB7XG4gICAgICAgIHRoaXMuZWRpdG9yLm9uKCdibHVyJywgb25CbHVyKVxuICAgICAgfVxuXG4gICAgICBpZiAob25EZXN0cm95KSB7XG4gICAgICAgIHRoaXMuZWRpdG9yLm9uKCdkZXN0cm95Jywgb25EZXN0cm95KVxuICAgICAgfVxuICAgIH0pXG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IEZyYWdtZW50IH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUsIFRleHRTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgQ29tbWFuZE1hbmFnZXIgfSBmcm9tICcuL0NvbW1hbmRNYW5hZ2VyLmpzJ1xuaW1wb3J0IHR5cGUgeyBFZGl0b3IgfSBmcm9tICcuL0VkaXRvci5qcydcbmltcG9ydCB7IGNyZWF0ZUNoYWluYWJsZVN0YXRlIH0gZnJvbSAnLi9oZWxwZXJzL2NyZWF0ZUNoYWluYWJsZVN0YXRlLmpzJ1xuaW1wb3J0IHsgZ2V0SFRNTEZyb21GcmFnbWVudCB9IGZyb20gJy4vaGVscGVycy9nZXRIVE1MRnJvbUZyYWdtZW50LmpzJ1xuaW1wb3J0IHsgZ2V0VGV4dENvbnRlbnRGcm9tTm9kZXMgfSBmcm9tICcuL2hlbHBlcnMvZ2V0VGV4dENvbnRlbnRGcm9tTm9kZXMuanMnXG5pbXBvcnQgdHlwZSB7XG4gIENhbkNvbW1hbmRzLFxuICBDaGFpbmVkQ29tbWFuZHMsXG4gIEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheSxcbiAgUmFuZ2UsXG4gIFNpbmdsZUNvbW1hbmRzLFxufSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHsgaXNSZWdFeHAgfSBmcm9tICcuL3V0aWxpdGllcy9pc1JlZ0V4cC5qcydcblxuZXhwb3J0IHR5cGUgSW5wdXRSdWxlTWF0Y2ggPSB7XG4gIGluZGV4OiBudW1iZXJcbiAgdGV4dDogc3RyaW5nXG4gIHJlcGxhY2VXaXRoPzogc3RyaW5nXG4gIG1hdGNoPzogUmVnRXhwTWF0Y2hBcnJheVxuICBkYXRhPzogUmVjb3JkPHN0cmluZywgYW55PlxufVxuXG5leHBvcnQgdHlwZSBJbnB1dFJ1bGVGaW5kZXIgPSBSZWdFeHAgfCAoKHRleHQ6IHN0cmluZykgPT4gSW5wdXRSdWxlTWF0Y2ggfCBudWxsKVxuXG5leHBvcnQgY2xhc3MgSW5wdXRSdWxlIHtcbiAgZmluZDogSW5wdXRSdWxlRmluZGVyXG5cbiAgaGFuZGxlcjogKHByb3BzOiB7XG4gICAgc3RhdGU6IEVkaXRvclN0YXRlXG4gICAgcmFuZ2U6IFJhbmdlXG4gICAgbWF0Y2g6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheVxuICAgIGNvbW1hbmRzOiBTaW5nbGVDb21tYW5kc1xuICAgIGNoYWluOiAoKSA9PiBDaGFpbmVkQ29tbWFuZHNcbiAgICBjYW46ICgpID0+IENhbkNvbW1hbmRzXG4gIH0pID0+IHZvaWQgfCBudWxsXG5cbiAgdW5kb2FibGU6IGJvb2xlYW5cblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IHtcbiAgICBmaW5kOiBJbnB1dFJ1bGVGaW5kZXJcbiAgICBoYW5kbGVyOiAocHJvcHM6IHtcbiAgICAgIHN0YXRlOiBFZGl0b3JTdGF0ZVxuICAgICAgcmFuZ2U6IFJhbmdlXG4gICAgICBtYXRjaDogRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5XG4gICAgICBjb21tYW5kczogU2luZ2xlQ29tbWFuZHNcbiAgICAgIGNoYWluOiAoKSA9PiBDaGFpbmVkQ29tbWFuZHNcbiAgICAgIGNhbjogKCkgPT4gQ2FuQ29tbWFuZHNcbiAgICB9KSA9PiB2b2lkIHwgbnVsbFxuICAgIHVuZG9hYmxlPzogYm9vbGVhblxuICB9KSB7XG4gICAgdGhpcy5maW5kID0gY29uZmlnLmZpbmRcbiAgICB0aGlzLmhhbmRsZXIgPSBjb25maWcuaGFuZGxlclxuICAgIHRoaXMudW5kb2FibGUgPSBjb25maWcudW5kb2FibGUgPz8gdHJ1ZVxuICB9XG59XG5cbmNvbnN0IGlucHV0UnVsZU1hdGNoZXJIYW5kbGVyID0gKFxuICB0ZXh0OiBzdHJpbmcsXG4gIGZpbmQ6IElucHV0UnVsZUZpbmRlcixcbik6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheSB8IG51bGwgPT4ge1xuICBpZiAoaXNSZWdFeHAoZmluZCkpIHtcbiAgICByZXR1cm4gZmluZC5leGVjKHRleHQpXG4gIH1cblxuICBjb25zdCBpbnB1dFJ1bGVNYXRjaCA9IGZpbmQodGV4dClcblxuICBpZiAoIWlucHV0UnVsZU1hdGNoKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGNvbnN0IHJlc3VsdDogRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5ID0gW2lucHV0UnVsZU1hdGNoLnRleHRdXG5cbiAgcmVzdWx0LmluZGV4ID0gaW5wdXRSdWxlTWF0Y2guaW5kZXhcbiAgcmVzdWx0LmlucHV0ID0gdGV4dFxuICByZXN1bHQuZGF0YSA9IGlucHV0UnVsZU1hdGNoLmRhdGFcblxuICBpZiAoaW5wdXRSdWxlTWF0Y2gucmVwbGFjZVdpdGgpIHtcbiAgICBpZiAoIWlucHV0UnVsZU1hdGNoLnRleHQuaW5jbHVkZXMoaW5wdXRSdWxlTWF0Y2gucmVwbGFjZVdpdGgpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdbdGlwdGFwIHdhcm5dOiBcImlucHV0UnVsZU1hdGNoLnJlcGxhY2VXaXRoXCIgbXVzdCBiZSBwYXJ0IG9mIFwiaW5wdXRSdWxlTWF0Y2gudGV4dFwiLicsXG4gICAgICApXG4gICAgfVxuXG4gICAgcmVzdWx0LnB1c2goaW5wdXRSdWxlTWF0Y2gucmVwbGFjZVdpdGgpXG4gIH1cblxuICByZXR1cm4gcmVzdWx0XG59XG5cbmZ1bmN0aW9uIHJ1bihjb25maWc6IHtcbiAgZWRpdG9yOiBFZGl0b3JcbiAgZnJvbTogbnVtYmVyXG4gIHRvOiBudW1iZXJcbiAgdGV4dDogc3RyaW5nXG4gIHJ1bGVzOiBJbnB1dFJ1bGVbXVxuICBwbHVnaW46IFBsdWdpblxufSk6IGJvb2xlYW4ge1xuICBjb25zdCB7IGVkaXRvciwgZnJvbSwgdG8sIHRleHQsIHJ1bGVzLCBwbHVnaW4gfSA9IGNvbmZpZ1xuICBjb25zdCB7IHZpZXcgfSA9IGVkaXRvclxuXG4gIGlmICh2aWV3LmNvbXBvc2luZykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgY29uc3QgJGZyb20gPSB2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKGZyb20pXG5cbiAgaWYgKFxuICAgIC8vIGNoZWNrIGZvciBjb2RlIG5vZGVcbiAgICAkZnJvbS5wYXJlbnQudHlwZS5zcGVjLmNvZGUgfHxcbiAgICAvLyBjaGVjayBmb3IgY29kZSBtYXJrXG4gICAgISEoJGZyb20ubm9kZUJlZm9yZSB8fCAkZnJvbS5ub2RlQWZ0ZXIpPy5tYXJrcy5maW5kKG1hcmsgPT4gbWFyay50eXBlLnNwZWMuY29kZSlcbiAgKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBsZXQgbWF0Y2hlZCA9IGZhbHNlXG5cbiAgY29uc3QgdGV4dEJlZm9yZSA9IGdldFRleHRDb250ZW50RnJvbU5vZGVzKCRmcm9tKSArIHRleHRcblxuICBydWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgIGlmIChtYXRjaGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBtYXRjaCA9IGlucHV0UnVsZU1hdGNoZXJIYW5kbGVyKHRleHRCZWZvcmUsIHJ1bGUuZmluZClcblxuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHRyID0gdmlldy5zdGF0ZS50clxuICAgIGNvbnN0IHN0YXRlID0gY3JlYXRlQ2hhaW5hYmxlU3RhdGUoe1xuICAgICAgc3RhdGU6IHZpZXcuc3RhdGUsXG4gICAgICB0cmFuc2FjdGlvbjogdHIsXG4gICAgfSlcbiAgICBjb25zdCByYW5nZSA9IHtcbiAgICAgIGZyb206IGZyb20gLSAobWF0Y2hbMF0ubGVuZ3RoIC0gdGV4dC5sZW5ndGgpLFxuICAgICAgdG8sXG4gICAgfVxuXG4gICAgY29uc3QgeyBjb21tYW5kcywgY2hhaW4sIGNhbiB9ID0gbmV3IENvbW1hbmRNYW5hZ2VyKHtcbiAgICAgIGVkaXRvcixcbiAgICAgIHN0YXRlLFxuICAgIH0pXG5cbiAgICBjb25zdCBoYW5kbGVyID0gcnVsZS5oYW5kbGVyKHtcbiAgICAgIHN0YXRlLFxuICAgICAgcmFuZ2UsXG4gICAgICBtYXRjaCxcbiAgICAgIGNvbW1hbmRzLFxuICAgICAgY2hhaW4sXG4gICAgICBjYW4sXG4gICAgfSlcblxuICAgIC8vIHN0b3AgaWYgdGhlcmUgYXJlIG5vIGNoYW5nZXNcbiAgICBpZiAoaGFuZGxlciA9PT0gbnVsbCB8fCAhdHIuc3RlcHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBzdG9yZSB0cmFuc2Zvcm0gYXMgbWV0YSBkYXRhXG4gICAgLy8gc28gd2UgY2FuIHVuZG8gaW5wdXQgcnVsZXMgd2l0aGluIHRoZSBgdW5kb0lucHV0UnVsZXNgIGNvbW1hbmRcbiAgICBpZiAocnVsZS51bmRvYWJsZSkge1xuICAgICAgdHIuc2V0TWV0YShwbHVnaW4sIHtcbiAgICAgICAgdHJhbnNmb3JtOiB0cixcbiAgICAgICAgZnJvbSxcbiAgICAgICAgdG8sXG4gICAgICAgIHRleHQsXG4gICAgICB9KVxuICAgIH1cblxuICAgIHZpZXcuZGlzcGF0Y2godHIpXG4gICAgbWF0Y2hlZCA9IHRydWVcbiAgfSlcblxuICByZXR1cm4gbWF0Y2hlZFxufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBpbnB1dCBydWxlcyBwbHVnaW4uIFdoZW4gZW5hYmxlZCwgaXQgd2lsbCBjYXVzZSB0ZXh0XG4gKiBpbnB1dCB0aGF0IG1hdGNoZXMgYW55IG9mIHRoZSBnaXZlbiBydWxlcyB0byB0cmlnZ2VyIHRoZSBydWxl4oCZc1xuICogYWN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5wdXRSdWxlc1BsdWdpbihwcm9wczogeyBlZGl0b3I6IEVkaXRvcjsgcnVsZXM6IElucHV0UnVsZVtdIH0pOiBQbHVnaW4ge1xuICBjb25zdCB7IGVkaXRvciwgcnVsZXMgfSA9IHByb3BzXG4gIGNvbnN0IHBsdWdpbiA9IG5ldyBQbHVnaW4oe1xuICAgIHN0YXRlOiB7XG4gICAgICBpbml0KCkge1xuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgfSxcbiAgICAgIGFwcGx5KHRyLCBwcmV2LCBzdGF0ZSkge1xuICAgICAgICBjb25zdCBzdG9yZWQgPSB0ci5nZXRNZXRhKHBsdWdpbilcblxuICAgICAgICBpZiAoc3RvcmVkKSB7XG4gICAgICAgICAgcmV0dXJuIHN0b3JlZFxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgSW5wdXRSdWxlIGlzIHRyaWdnZXJlZCBieSBpbnNlcnRDb250ZW50KClcbiAgICAgICAgY29uc3Qgc2ltdWxhdGVkSW5wdXRNZXRhID0gdHIuZ2V0TWV0YSgnYXBwbHlJbnB1dFJ1bGVzJykgYXNcbiAgICAgICAgICB8IHVuZGVmaW5lZFxuICAgICAgICAgIHwge1xuICAgICAgICAgICAgICBmcm9tOiBudW1iZXJcbiAgICAgICAgICAgICAgdGV4dDogc3RyaW5nIHwgUHJvc2VNaXJyb3JOb2RlIHwgRnJhZ21lbnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgY29uc3QgaXNTaW11bGF0ZWRJbnB1dCA9ICEhc2ltdWxhdGVkSW5wdXRNZXRhXG5cbiAgICAgICAgaWYgKGlzU2ltdWxhdGVkSW5wdXQpIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGxldCB7IHRleHQgfSA9IHNpbXVsYXRlZElucHV0TWV0YVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIHRleHQgPSB0ZXh0IGFzIHN0cmluZ1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGV4dCA9IGdldEhUTUxGcm9tRnJhZ21lbnQoRnJhZ21lbnQuZnJvbSh0ZXh0KSwgc3RhdGUuc2NoZW1hKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB7IGZyb20gfSA9IHNpbXVsYXRlZElucHV0TWV0YVxuICAgICAgICAgICAgY29uc3QgdG8gPSBmcm9tICsgdGV4dC5sZW5ndGhcblxuICAgICAgICAgICAgcnVuKHtcbiAgICAgICAgICAgICAgZWRpdG9yLFxuICAgICAgICAgICAgICBmcm9tLFxuICAgICAgICAgICAgICB0byxcbiAgICAgICAgICAgICAgdGV4dCxcbiAgICAgICAgICAgICAgcnVsZXMsXG4gICAgICAgICAgICAgIHBsdWdpbixcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0ci5zZWxlY3Rpb25TZXQgfHwgdHIuZG9jQ2hhbmdlZCA/IG51bGwgOiBwcmV2XG4gICAgICB9LFxuICAgIH0sXG5cbiAgICBwcm9wczoge1xuICAgICAgaGFuZGxlVGV4dElucHV0KHZpZXcsIGZyb20sIHRvLCB0ZXh0KSB7XG4gICAgICAgIHJldHVybiBydW4oe1xuICAgICAgICAgIGVkaXRvcixcbiAgICAgICAgICBmcm9tLFxuICAgICAgICAgIHRvLFxuICAgICAgICAgIHRleHQsXG4gICAgICAgICAgcnVsZXMsXG4gICAgICAgICAgcGx1Z2luLFxuICAgICAgICB9KVxuICAgICAgfSxcblxuICAgICAgaGFuZGxlRE9NRXZlbnRzOiB7XG4gICAgICAgIGNvbXBvc2l0aW9uZW5kOiB2aWV3ID0+IHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgJGN1cnNvciB9ID0gdmlldy5zdGF0ZS5zZWxlY3Rpb24gYXMgVGV4dFNlbGVjdGlvblxuXG4gICAgICAgICAgICBpZiAoJGN1cnNvcikge1xuICAgICAgICAgICAgICBydW4oe1xuICAgICAgICAgICAgICAgIGVkaXRvcixcbiAgICAgICAgICAgICAgICBmcm9tOiAkY3Vyc29yLnBvcyxcbiAgICAgICAgICAgICAgICB0bzogJGN1cnNvci5wb3MsXG4gICAgICAgICAgICAgICAgdGV4dDogJycsXG4gICAgICAgICAgICAgICAgcnVsZXMsXG4gICAgICAgICAgICAgICAgcGx1Z2luLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIC8vIGFkZCBzdXBwb3J0IGZvciBpbnB1dCBydWxlcyB0byB0cmlnZ2VyIG9uIGVudGVyXG4gICAgICAvLyB0aGlzIGlzIHVzZWZ1bCBmb3IgZXhhbXBsZSBmb3IgY29kZSBibG9ja3NcbiAgICAgIGhhbmRsZUtleURvd24odmlldywgZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmtleSAhPT0gJ0VudGVyJykge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeyAkY3Vyc29yIH0gPSB2aWV3LnN0YXRlLnNlbGVjdGlvbiBhcyBUZXh0U2VsZWN0aW9uXG5cbiAgICAgICAgaWYgKCRjdXJzb3IpIHtcbiAgICAgICAgICByZXR1cm4gcnVuKHtcbiAgICAgICAgICAgIGVkaXRvcixcbiAgICAgICAgICAgIGZyb206ICRjdXJzb3IucG9zLFxuICAgICAgICAgICAgdG86ICRjdXJzb3IucG9zLFxuICAgICAgICAgICAgdGV4dDogJ1xcbicsXG4gICAgICAgICAgICBydWxlcyxcbiAgICAgICAgICAgIHBsdWdpbixcbiAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9LFxuICAgIH0sXG5cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgaXNJbnB1dFJ1bGVzOiB0cnVlLFxuICB9KSBhcyBQbHVnaW5cblxuICByZXR1cm4gcGx1Z2luXG59XG4iLCAiLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vbWVzcXVlZWIvaXMtd2hhdC9ibG9iLzg4ZDZlNGNhOTJmYjJiYWFiNjAwM2M1NGUwMmVlZGY0ZTcyOWU1YWIvc3JjL2luZGV4LnRzXG5cbmZ1bmN0aW9uIGdldFR5cGUodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLnNsaWNlKDgsIC0xKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZTogYW55KTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgYW55PiB7XG4gIGlmIChnZXRUeXBlKHZhbHVlKSAhPT0gJ09iamVjdCcpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiB2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0ICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSkgPT09IE9iamVjdC5wcm90b3R5cGVcbn1cbiIsICJpbXBvcnQgeyBpc1BsYWluT2JqZWN0IH0gZnJvbSAnLi9pc1BsYWluT2JqZWN0LmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEZWVwKFxuICB0YXJnZXQ6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIHNvdXJjZTogUmVjb3JkPHN0cmluZywgYW55Pixcbik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBjb25zdCBvdXRwdXQgPSB7IC4uLnRhcmdldCB9XG5cbiAgaWYgKGlzUGxhaW5PYmplY3QodGFyZ2V0KSAmJiBpc1BsYWluT2JqZWN0KHNvdXJjZSkpIHtcbiAgICBPYmplY3Qua2V5cyhzb3VyY2UpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmIChpc1BsYWluT2JqZWN0KHNvdXJjZVtrZXldKSAmJiBpc1BsYWluT2JqZWN0KHRhcmdldFtrZXldKSkge1xuICAgICAgICBvdXRwdXRba2V5XSA9IG1lcmdlRGVlcCh0YXJnZXRba2V5XSwgc291cmNlW2tleV0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXRba2V5XSA9IHNvdXJjZVtrZXldXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBvdXRwdXRcbn1cbiIsICJpbXBvcnQgdHlwZSB7IFBsdWdpbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB0eXBlIHsgRWRpdG9yIH0gZnJvbSAnLi9FZGl0b3IuanMnXG5pbXBvcnQgeyBnZXRFeHRlbnNpb25GaWVsZCB9IGZyb20gJy4vaGVscGVycy9nZXRFeHRlbnNpb25GaWVsZC5qcydcbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uQ29uZmlnLCBNYXJrQ29uZmlnLCBOb2RlQ29uZmlnIH0gZnJvbSAnLi9pbmRleC5qcydcbmltcG9ydCB0eXBlIHsgSW5wdXRSdWxlIH0gZnJvbSAnLi9JbnB1dFJ1bGUuanMnXG5pbXBvcnQgdHlwZSB7IE1hcmsgfSBmcm9tICcuL01hcmsuanMnXG5pbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tICcuL05vZGUuanMnXG5pbXBvcnQgdHlwZSB7IFBhc3RlUnVsZSB9IGZyb20gJy4vUGFzdGVSdWxlLmpzJ1xuaW1wb3J0IHR5cGUge1xuICBBbnlDb25maWcsXG4gIERpc3BhdGNoVHJhbnNhY3Rpb25Qcm9wcyxcbiAgRWRpdG9yRXZlbnRzLFxuICBFeHRlbnNpb25zLFxuICBHbG9iYWxBdHRyaWJ1dGVzLFxuICBKU09OQ29udGVudCxcbiAgS2V5Ym9hcmRTaG9ydGN1dENvbW1hbmQsXG4gIE1hcmtkb3duUGFyc2VIZWxwZXJzLFxuICBNYXJrZG93blBhcnNlUmVzdWx0LFxuICBNYXJrZG93blJlbmRlcmVySGVscGVycyxcbiAgTWFya2Rvd25Ub2tlbixcbiAgTWFya2Rvd25Ub2tlbml6ZXIsXG4gIFBhcmVudENvbmZpZyxcbiAgUmF3Q29tbWFuZHMsXG4gIFJlbmRlckNvbnRleHQsXG59IGZyb20gJy4vdHlwZXMuanMnXG5pbXBvcnQgeyBjYWxsT3JSZXR1cm4gfSBmcm9tICcuL3V0aWxpdGllcy9jYWxsT3JSZXR1cm4uanMnXG5pbXBvcnQgeyBtZXJnZURlZXAgfSBmcm9tICcuL3V0aWxpdGllcy9tZXJnZURlZXAuanMnXG5cbmV4cG9ydCBpbnRlcmZhY2UgRXh0ZW5kYWJsZUNvbmZpZzxcbiAgT3B0aW9ucyA9IGFueSxcbiAgU3RvcmFnZSA9IGFueSxcbiAgQ29uZmlnIGV4dGVuZHNcbiAgICB8IEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPlxuICAgIHwgTm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPlxuICAgIHwgTWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPlxuICAgIHwgRXh0ZW5kYWJsZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPiA9IEV4dGVuZGFibGVDb25maWc8T3B0aW9ucywgU3RvcmFnZSwgYW55LCBhbnk+LFxuICBQTVR5cGUgPSBhbnksXG4+IHtcbiAgLyoqXG4gICAqIFRoZSBleHRlbnNpb24gbmFtZSAtIHRoaXMgbXVzdCBiZSB1bmlxdWUuXG4gICAqIEl0IHdpbGwgYmUgdXNlZCB0byBpZGVudGlmeSB0aGUgZXh0ZW5zaW9uLlxuICAgKlxuICAgKiBAZXhhbXBsZSAnbXlFeHRlbnNpb24nXG4gICAqL1xuICBuYW1lOiBzdHJpbmdcblxuICAvKipcbiAgICogVGhlIHByaW9yaXR5IG9mIHlvdXIgZXh0ZW5zaW9uLiBUaGUgaGlnaGVyLCB0aGUgZWFybGllciBpdCB3aWxsIGJlIGNhbGxlZFxuICAgKiBhbmQgd2lsbCB0YWtlIHByZWNlZGVuY2Ugb3ZlciBvdGhlciBleHRlbnNpb25zIHdpdGggYSBsb3dlciBwcmlvcml0eS5cbiAgICogQGRlZmF1bHQgMTAwXG4gICAqIEBleGFtcGxlIDEwMVxuICAgKi9cbiAgcHJpb3JpdHk/OiBudW1iZXJcblxuICAvKipcbiAgICogVGhpcyBtZXRob2Qgd2lsbCBhZGQgb3B0aW9ucyB0byB0aGlzIGV4dGVuc2lvblxuICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNzZXR0aW5nc1xuICAgKiBAZXhhbXBsZVxuICAgKiBhZGRPcHRpb25zKCkge1xuICAgKiAgcmV0dXJuIHtcbiAgICogICAgbXlPcHRpb246ICdmb28nLFxuICAgKiAgICBteU90aGVyT3B0aW9uOiAxMCxcbiAgICogfVxuICAgKi9cbiAgYWRkT3B0aW9ucz86ICh0aGlzOiB7IG5hbWU6IHN0cmluZzsgcGFyZW50OiBQYXJlbnRDb25maWc8Q29uZmlnPlsnYWRkT3B0aW9ucyddIH0pID0+IE9wdGlvbnNcblxuICAvKipcbiAgICogVGhlIGRlZmF1bHQgc3RvcmFnZSB0aGlzIGV4dGVuc2lvbiBjYW4gc2F2ZSBkYXRhIHRvLlxuICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNzdG9yYWdlXG4gICAqIEBleGFtcGxlXG4gICAqIGRlZmF1bHRTdG9yYWdlOiB7XG4gICAqICAgcHJlZmV0Y2hlZFVzZXJzOiBbXSxcbiAgICogICBsb2FkaW5nOiBmYWxzZSxcbiAgICogfVxuICAgKi9cbiAgYWRkU3RvcmFnZT86ICh0aGlzOiB7XG4gICAgbmFtZTogc3RyaW5nXG4gICAgb3B0aW9uczogT3B0aW9uc1xuICAgIHBhcmVudDogUGFyZW50Q29uZmlnPENvbmZpZz5bJ2FkZFN0b3JhZ2UnXVxuICB9KSA9PiBTdG9yYWdlXG5cbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gYWRkcyBnbG9iYWxBdHRyaWJ1dGVzIHRvIHNwZWNpZmljIG5vZGVzLlxuICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNnbG9iYWwtYXR0cmlidXRlc1xuICAgKiBAZXhhbXBsZVxuICAgKiBhZGRHbG9iYWxBdHRyaWJ1dGVzKCkge1xuICAgKiAgIHJldHVybiBbXG4gICAqICAgICB7XG4gICAgICAgICAgIC8vIEV4dGVuZCB0aGUgZm9sbG93aW5nIGV4dGVuc2lvbnNcbiAgICogICAgICAgdHlwZXM6IFtcbiAgICogICAgICAgICAnaGVhZGluZycsXG4gICAqICAgICAgICAgJ3BhcmFncmFwaCcsXG4gICAqICAgICAgIF0sXG4gICAqICAgICAgIC8vIOKApiB3aXRoIHRob3NlIGF0dHJpYnV0ZXNcbiAgICogICAgICAgYXR0cmlidXRlczoge1xuICAgKiAgICAgICAgIHRleHRBbGlnbjoge1xuICAgKiAgICAgICAgICAgZGVmYXVsdDogJ2xlZnQnLFxuICAgKiAgICAgICAgICAgcmVuZGVySFRNTDogYXR0cmlidXRlcyA9PiAoe1xuICAgKiAgICAgICAgICAgICBzdHlsZTogYHRleHQtYWxpZ246ICR7YXR0cmlidXRlcy50ZXh0QWxpZ259YCxcbiAgICogICAgICAgICAgIH0pLFxuICAgKiAgICAgICAgICAgcGFyc2VIVE1MOiBlbGVtZW50ID0+IGVsZW1lbnQuc3R5bGUudGV4dEFsaWduIHx8ICdsZWZ0JyxcbiAgICogICAgICAgICB9LFxuICAgKiAgICAgICB9LFxuICAgKiAgICAgfSxcbiAgICogICBdXG4gICAqIH1cbiAgICovXG4gIGFkZEdsb2JhbEF0dHJpYnV0ZXM/OiAodGhpczoge1xuICAgIG5hbWU6IHN0cmluZ1xuICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgZXh0ZW5zaW9uczogKE5vZGUgfCBNYXJrKVtdXG4gICAgcGFyZW50OiBQYXJlbnRDb25maWc8Q29uZmlnPlsnYWRkR2xvYmFsQXR0cmlidXRlcyddXG4gIH0pID0+IEdsb2JhbEF0dHJpYnV0ZXNcblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBhZGRzIGNvbW1hbmRzIHRvIHRoZSBlZGl0b3JcbiAgICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZG9jcy9lZGl0b3IvZ3VpZGUvY3VzdG9tLWV4dGVuc2lvbnMjY29tbWFuZHNcbiAgICogQGV4YW1wbGVcbiAgICogYWRkQ29tbWFuZHMoKSB7XG4gICAqICAgcmV0dXJuIHtcbiAgICogICAgIG15Q29tbWFuZDogKCkgPT4gKHsgY2hhaW4gfSkgPT4gY2hhaW4oKS5zZXRNYXJrKCd0eXBlJywgJ2ZvbycpLnJ1bigpLFxuICAgKiAgIH1cbiAgICogfVxuICAgKi9cbiAgYWRkQ29tbWFuZHM/OiAodGhpczoge1xuICAgIG5hbWU6IHN0cmluZ1xuICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgZWRpdG9yOiBFZGl0b3JcbiAgICB0eXBlOiBQTVR5cGVcbiAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxDb25maWc+WydhZGRDb21tYW5kcyddXG4gIH0pID0+IFBhcnRpYWw8UmF3Q29tbWFuZHM+XG5cbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gcmVnaXN0ZXJzIGtleWJvYXJkIHNob3J0Y3V0cy5cbiAgICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZG9jcy9lZGl0b3IvZ3VpZGUvY3VzdG9tLWV4dGVuc2lvbnMja2V5Ym9hcmQtc2hvcnRjdXRzXG4gICAqIEBleGFtcGxlXG4gICAqIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgKiAgIHJldHVybiB7XG4gICAqICAgICAnTW9kLWwnOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVCdWxsZXRMaXN0KCksXG4gICAqICAgfVxuICAgKiB9LFxuICAgKi9cbiAgYWRkS2V5Ym9hcmRTaG9ydGN1dHM/OiAodGhpczoge1xuICAgIG5hbWU6IHN0cmluZ1xuICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgZWRpdG9yOiBFZGl0b3JcbiAgICB0eXBlOiBQTVR5cGVcbiAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxDb25maWc+WydhZGRLZXlib2FyZFNob3J0Y3V0cyddXG4gIH0pID0+IHtcbiAgICBba2V5OiBzdHJpbmddOiBLZXlib2FyZFNob3J0Y3V0Q29tbWFuZFxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gYWRkcyBpbnB1dCBydWxlcyB0byB0aGUgZWRpdG9yLlxuICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNpbnB1dC1ydWxlc1xuICAgKiBAZXhhbXBsZVxuICAgKiBhZGRJbnB1dFJ1bGVzKCkge1xuICAgKiAgIHJldHVybiBbXG4gICAqICAgICBtYXJrSW5wdXRSdWxlKHtcbiAgICogICAgICAgZmluZDogaW5wdXRSZWdleCxcbiAgICogICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgKiAgICAgfSksXG4gICAqICAgXVxuICAgKiB9LFxuICAgKi9cbiAgYWRkSW5wdXRSdWxlcz86ICh0aGlzOiB7XG4gICAgbmFtZTogc3RyaW5nXG4gICAgb3B0aW9uczogT3B0aW9uc1xuICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICBlZGl0b3I6IEVkaXRvclxuICAgIHR5cGU6IFBNVHlwZVxuICAgIHBhcmVudDogUGFyZW50Q29uZmlnPENvbmZpZz5bJ2FkZElucHV0UnVsZXMnXVxuICB9KSA9PiBJbnB1dFJ1bGVbXVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGFkZHMgcGFzdGUgcnVsZXMgdG8gdGhlIGVkaXRvci5cbiAgICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZG9jcy9lZGl0b3IvZ3VpZGUvY3VzdG9tLWV4dGVuc2lvbnMjcGFzdGUtcnVsZXNcbiAgICogQGV4YW1wbGVcbiAgICogYWRkUGFzdGVSdWxlcygpIHtcbiAgICogICByZXR1cm4gW1xuICAgKiAgICAgbWFya1Bhc3RlUnVsZSh7XG4gICAqICAgICAgIGZpbmQ6IHBhc3RlUmVnZXgsXG4gICAqICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICogICAgIH0pLFxuICAgKiAgIF1cbiAgICogfSxcbiAgICovXG4gIGFkZFBhc3RlUnVsZXM/OiAodGhpczoge1xuICAgIG5hbWU6IHN0cmluZ1xuICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgZWRpdG9yOiBFZGl0b3JcbiAgICB0eXBlOiBQTVR5cGVcbiAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxDb25maWc+WydhZGRQYXN0ZVJ1bGVzJ11cbiAgfSkgPT4gUGFzdGVSdWxlW11cblxuICAvKipcbiAgICogVGhpcyBmdW5jdGlvbiBhZGRzIFByb3NlbWlycm9yIHBsdWdpbnMgdG8gdGhlIGVkaXRvclxuICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNwcm9zZW1pcnJvci1wbHVnaW5zXG4gICAqIEBleGFtcGxlXG4gICAqIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICogICByZXR1cm4gW1xuICAgKiAgICAgY3VzdG9tUGx1Z2luKCksXG4gICAqICAgXVxuICAgKiB9XG4gICAqL1xuICBhZGRQcm9zZU1pcnJvclBsdWdpbnM/OiAodGhpczoge1xuICAgIG5hbWU6IHN0cmluZ1xuICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgZWRpdG9yOiBFZGl0b3JcbiAgICB0eXBlOiBQTVR5cGVcbiAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxDb25maWc+WydhZGRQcm9zZU1pcnJvclBsdWdpbnMnXVxuICB9KSA9PiBQbHVnaW5bXVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIHRyYW5zZm9ybXMgcGFzdGVkIEhUTUwgY29udGVudCBiZWZvcmUgaXQncyBwYXJzZWQuXG4gICAqIEV4dGVuc2lvbnMgY2FuIHVzZSB0aGlzIHRvIG1vZGlmeSBvciBjbGVhbiB1cCBwYXN0ZWQgSFRNTC5cbiAgICogVGhlIHRyYW5zZm9ybWF0aW9ucyBhcmUgY2hhaW5lZCAtIGVhY2ggZXh0ZW5zaW9uJ3MgdHJhbnNmb3JtIHJlY2VpdmVzXG4gICAqIHRoZSBvdXRwdXQgZnJvbSB0aGUgcHJldmlvdXMgZXh0ZW5zaW9uJ3MgdHJhbnNmb3JtLlxuICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyN0cmFuc2Zvcm0tcGFzdGVkLWh0bWxcbiAgICogQGV4YW1wbGVcbiAgICogdHJhbnNmb3JtUGFzdGVkSFRNTChodG1sKSB7XG4gICAqICAgLy8gUmVtb3ZlIGFsbCBzdHlsZSBhdHRyaWJ1dGVzXG4gICAqICAgcmV0dXJuIGh0bWwucmVwbGFjZSgvc3R5bGU9XCJbXlwiXSpcIi9nLCAnJylcbiAgICogfVxuICAgKi9cbiAgdHJhbnNmb3JtUGFzdGVkSFRNTD86IChcbiAgICB0aGlzOiB7XG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICB0eXBlOiBQTVR5cGVcbiAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPENvbmZpZz5bJ3RyYW5zZm9ybVBhc3RlZEhUTUwnXVxuICAgIH0sXG4gICAgaHRtbDogc3RyaW5nLFxuICApID0+IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGFkZHMgYWRkaXRpb25hbCBleHRlbnNpb25zIHRvIHRoZSBlZGl0b3IuIFRoaXMgaXMgdXNlZnVsIGZvclxuICAgKiBidWlsZGluZyBleHRlbnNpb24ga2l0cy5cbiAgICogQGV4YW1wbGVcbiAgICogYWRkRXh0ZW5zaW9ucygpIHtcbiAgICogICByZXR1cm4gW1xuICAgKiAgICAgQnVsbGV0TGlzdCxcbiAgICogICAgIE9yZGVyZWRMaXN0LFxuICAgKiAgICAgTGlzdEl0ZW1cbiAgICogICBdXG4gICAqIH1cbiAgICovXG4gIGFkZEV4dGVuc2lvbnM/OiAodGhpczoge1xuICAgIG5hbWU6IHN0cmluZ1xuICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgcGFyZW50OiBQYXJlbnRDb25maWc8Q29uZmlnPlsnYWRkRXh0ZW5zaW9ucyddXG4gIH0pID0+IEV4dGVuc2lvbnNcblxuICAvKipcbiAgICogVGhlIG1hcmtkb3duIHRva2VuIG5hbWVcbiAgICpcbiAgICogVGhpcyBpcyB0aGUgbmFtZSBvZiB0aGUgdG9rZW4gdGhhdCB0aGlzIGV4dGVuc2lvbiB1c2VzIHRvIHBhcnNlIGFuZCByZW5kZXIgbWFya2Rvd24gYW5kIGNvbWVzIGZyb20gdGhlIE1hcmtlZCBMZXhlci5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vbWFya2VkanMvbWFya2VkL2Jsb2IvbWFzdGVyL3NyYy9Ub2tlbnMudHNcbiAgICpcbiAgICovXG4gIG1hcmtkb3duVG9rZW5OYW1lPzogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSBwYXJzZSBmdW5jdGlvbiB1c2VkIGJ5IHRoZSBtYXJrZG93biBwYXJzZXIgdG8gY29udmVydCBtYXJrZG93biB0b2tlbnMgdG8gUHJvc2VNaXJyb3Igbm9kZXMuXG4gICAqL1xuICBwYXJzZU1hcmtkb3duPzogKHRva2VuOiBNYXJrZG93blRva2VuLCBoZWxwZXJzOiBNYXJrZG93blBhcnNlSGVscGVycykgPT4gTWFya2Rvd25QYXJzZVJlc3VsdFxuXG4gIC8qKlxuICAgKiBUaGUgc2VyaWFsaXplciBmdW5jdGlvbiB1c2VkIGJ5IHRoZSBtYXJrZG93biBzZXJpYWxpemVyIHRvIGNvbnZlcnQgUHJvc2VNaXJyb3Igbm9kZXMgdG8gbWFya2Rvd24gdG9rZW5zLlxuICAgKi9cbiAgcmVuZGVyTWFya2Rvd24/OiAoXG4gICAgbm9kZTogSlNPTkNvbnRlbnQsXG4gICAgaGVscGVyczogTWFya2Rvd25SZW5kZXJlckhlbHBlcnMsXG4gICAgY3R4OiBSZW5kZXJDb250ZXh0LFxuICApID0+IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBUaGUgbWFya2Rvd24gdG9rZW5pemVyIHJlc3BvbnNpYmxlIGZvciB0dXJuaW5nIGEgbWFya2Rvd24gc3RyaW5nIGludG8gdG9rZW5zXG4gICAqXG4gICAqIEN1c3RvbSB0b2tlbml6ZXJzIGFyZSBvbmx5IG5lZWRlZCB3aGVuIHlvdSB3YW50IHRvIHBhcnNlIG5vbi1zdGFuZGFyZCBtYXJrZG93biB0b2tlbi5cbiAgICovXG4gIG1hcmtkb3duVG9rZW5pemVyPzogTWFya2Rvd25Ub2tlbml6ZXJcblxuICAvKipcbiAgICogT3B0aW9uYWwgbWFya2Rvd24gb3B0aW9ucyBmb3IgaW5kZW50YXRpb25cbiAgICovXG4gIG1hcmtkb3duT3B0aW9ucz86IHtcbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIGlmIHRoaXMgbWFya2Rvd24gZWxlbWVudCBzaG91bGQgaW5kZW50IGl0J3MgY2hpbGQgZWxlbWVudHNcbiAgICAgKi9cbiAgICBpbmRlbnRzQ29udGVudD86IGJvb2xlYW5cblxuICAgIC8qKlxuICAgICAqIExldHMgYSBtYXJrIHRlbGwgdGhlIE1hcmtkb3duIHNlcmlhbGl6ZXIgd2hpY2ggaW5saW5lIEhUTUwgdGFncyBpdCBjYW5cbiAgICAgKiBzYWZlbHkgdXNlIHdoZW4gcGxhaW4gbWFya2Rvd24gZGVsaW1pdGVycyB3b3VsZCBiZWNvbWUgYW1iaWd1b3VzLlxuICAgICAqXG4gICAgICogVGhpcyBpcyBtYWlubHkgdXNlZnVsIGZvciBvdmVybGFwcGluZyBtYXJrcy4gRm9yIGV4YW1wbGUsIGJvbGQgZm9sbG93ZWRcbiAgICAgKiBieSBib2xkK2l0YWxpYyBmb2xsb3dlZCBieSBpdGFsaWMgY2Fubm90IGFsd2F5cyBiZSB3cml0dGVuIGJhY2sgd2l0aCBvbmx5XG4gICAgICogYCpgIGFuZCBgKipgIGluIGEgd2F5IHRoYXQgc3RpbGwgcGFyc2VzIGNvcnJlY3RseS4gSW4gdGhhdCBjYXNlLCB0aGVcbiAgICAgKiBzZXJpYWxpemVyIGNhbiBjbG9zZSB0aGUgb3ZlcmxhcHBpbmcgc2VjdGlvbiB3aXRoIG1hcmtkb3duIGFuZCByZW9wZW4gdGhlXG4gICAgICogcmVtYWluaW5nIHRhaWwgd2l0aCBIVE1MIGluc3RlYWQuXG4gICAgICpcbiAgICAgKiBFeGFtcGxlOlxuICAgICAqIC0gZGVzaXJlZCBmb3JtYXR0aW5nOiBgKioxMjNgICsgYCo0NTYqYCArIGA3ODkgaXRhbGljYFxuICAgICAqIC0gc2VyaWFsaXplZCByZXN1bHQ6IGAqKjEyMyo0NTYqKio8ZW0+Nzg5PC9lbT5gXG4gICAgICpcbiAgICAgKiBJZiB5b3VyIGV4dGVuc2lvbiBkZWZpbmVzIGN1c3RvbSBtYXJrIG5hbWVzLCBzZXQgYGh0bWxSZW9wZW5gIG9uIHRoYXRcbiAgICAgKiBleHRlbnNpb24gc28gdGhlIHNlcmlhbGl6ZXIgY2FuIHJldXNlIGl0cyBIVE1MIGZvcm0gZm9yIG92ZXJsYXAgY2FzZXMuXG4gICAgICovXG4gICAgaHRtbFJlb3Blbj86IHtcbiAgICAgIG9wZW46IHN0cmluZ1xuICAgICAgY2xvc2U6IHN0cmluZ1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGV4dGVuZHMgdGhlIHNjaGVtYSBvZiB0aGUgbm9kZS5cbiAgICogQGV4YW1wbGVcbiAgICogZXh0ZW5kTm9kZVNjaGVtYSgpIHtcbiAgICogICByZXR1cm4ge1xuICAgKiAgICAgZ3JvdXA6ICdpbmxpbmUnLFxuICAgKiAgICAgc2VsZWN0YWJsZTogZmFsc2UsXG4gICAqICAgfVxuICAgKiB9XG4gICAqL1xuICBleHRlbmROb2RlU2NoZW1hPzpcbiAgICB8ICgoXG4gICAgICAgIHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPENvbmZpZz5bJ2V4dGVuZE5vZGVTY2hlbWEnXVxuICAgICAgICB9LFxuICAgICAgICBleHRlbnNpb246IE5vZGUsXG4gICAgICApID0+IFJlY29yZDxzdHJpbmcsIGFueT4pXG4gICAgfCBudWxsXG5cbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gZXh0ZW5kcyB0aGUgc2NoZW1hIG9mIHRoZSBtYXJrLlxuICAgKiBAZXhhbXBsZVxuICAgKiBleHRlbmRNYXJrU2NoZW1hKCkge1xuICAgKiAgIHJldHVybiB7XG4gICAqICAgICBncm91cDogJ2lubGluZScsXG4gICAqICAgICBzZWxlY3RhYmxlOiBmYWxzZSxcbiAgICogICB9XG4gICAqIH1cbiAgICovXG4gIGV4dGVuZE1hcmtTY2hlbWE/OlxuICAgIHwgKChcbiAgICAgICAgdGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Q29uZmlnPlsnZXh0ZW5kTWFya1NjaGVtYSddXG4gICAgICAgIH0sXG4gICAgICAgIGV4dGVuc2lvbjogTWFyayxcbiAgICAgICkgPT4gUmVjb3JkPHN0cmluZywgYW55PilcbiAgICB8IG51bGxcblxuICAvKipcbiAgICogVGhlIGVkaXRvciBpcyBub3QgcmVhZHkgeWV0LlxuICAgKi9cbiAgb25CZWZvcmVDcmVhdGU/OlxuICAgIHwgKChcbiAgICAgICAgdGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICB0eXBlOiBQTVR5cGVcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxDb25maWc+WydvbkJlZm9yZUNyZWF0ZSddXG4gICAgICAgIH0sXG4gICAgICAgIGV2ZW50OiBFZGl0b3JFdmVudHNbJ2JlZm9yZUNyZWF0ZSddLFxuICAgICAgKSA9PiB2b2lkKVxuICAgIHwgbnVsbFxuXG4gIC8qKlxuICAgKiBUaGUgZWRpdG9yIGlzIHJlYWR5LlxuICAgKi9cbiAgb25DcmVhdGU/OlxuICAgIHwgKChcbiAgICAgICAgdGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICB0eXBlOiBQTVR5cGVcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxDb25maWc+WydvbkNyZWF0ZSddXG4gICAgICAgIH0sXG4gICAgICAgIGV2ZW50OiBFZGl0b3JFdmVudHNbJ2NyZWF0ZSddLFxuICAgICAgKSA9PiB2b2lkKVxuICAgIHwgbnVsbFxuXG4gIC8qKlxuICAgKiBUaGUgY29udGVudCBoYXMgY2hhbmdlZC5cbiAgICovXG4gIG9uVXBkYXRlPzpcbiAgICB8ICgoXG4gICAgICAgIHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgdHlwZTogUE1UeXBlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Q29uZmlnPlsnb25VcGRhdGUnXVxuICAgICAgICB9LFxuICAgICAgICBldmVudDogRWRpdG9yRXZlbnRzWyd1cGRhdGUnXSxcbiAgICAgICkgPT4gdm9pZClcbiAgICB8IG51bGxcblxuICAvKipcbiAgICogVGhlIHNlbGVjdGlvbiBoYXMgY2hhbmdlZC5cbiAgICovXG4gIG9uU2VsZWN0aW9uVXBkYXRlPzpcbiAgICB8ICgoXG4gICAgICAgIHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgdHlwZTogUE1UeXBlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Q29uZmlnPlsnb25TZWxlY3Rpb25VcGRhdGUnXVxuICAgICAgICB9LFxuICAgICAgICBldmVudDogRWRpdG9yRXZlbnRzWydzZWxlY3Rpb25VcGRhdGUnXSxcbiAgICAgICkgPT4gdm9pZClcbiAgICB8IG51bGxcblxuICAvKipcbiAgICogVGhlIGVkaXRvciBzdGF0ZSBoYXMgY2hhbmdlZC5cbiAgICovXG4gIG9uVHJhbnNhY3Rpb24/OlxuICAgIHwgKChcbiAgICAgICAgdGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICB0eXBlOiBQTVR5cGVcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxDb25maWc+WydvblRyYW5zYWN0aW9uJ11cbiAgICAgICAgfSxcbiAgICAgICAgZXZlbnQ6IEVkaXRvckV2ZW50c1sndHJhbnNhY3Rpb24nXSxcbiAgICAgICkgPT4gdm9pZClcbiAgICB8IG51bGxcblxuICAvKipcbiAgICogVGhlIGVkaXRvciBpcyBmb2N1c2VkLlxuICAgKi9cbiAgb25Gb2N1cz86XG4gICAgfCAoKFxuICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgIHR5cGU6IFBNVHlwZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPENvbmZpZz5bJ29uRm9jdXMnXVxuICAgICAgICB9LFxuICAgICAgICBldmVudDogRWRpdG9yRXZlbnRzWydmb2N1cyddLFxuICAgICAgKSA9PiB2b2lkKVxuICAgIHwgbnVsbFxuXG4gIC8qKlxuICAgKiBUaGUgZWRpdG9yIGlzbuKAmXQgZm9jdXNlZCBhbnltb3JlLlxuICAgKi9cbiAgb25CbHVyPzpcbiAgICB8ICgoXG4gICAgICAgIHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgdHlwZTogUE1UeXBlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Q29uZmlnPlsnb25CbHVyJ11cbiAgICAgICAgfSxcbiAgICAgICAgZXZlbnQ6IEVkaXRvckV2ZW50c1snYmx1ciddLFxuICAgICAgKSA9PiB2b2lkKVxuICAgIHwgbnVsbFxuXG4gIC8qKlxuICAgKiBUaGUgZWRpdG9yIGlzIGRlc3Ryb3llZC5cbiAgICovXG4gIG9uRGVzdHJveT86XG4gICAgfCAoKFxuICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgIHR5cGU6IFBNVHlwZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPENvbmZpZz5bJ29uRGVzdHJveSddXG4gICAgICAgIH0sXG4gICAgICAgIGV2ZW50OiBFZGl0b3JFdmVudHNbJ2Rlc3Ryb3knXSxcbiAgICAgICkgPT4gdm9pZClcbiAgICB8IG51bGxcblxuICAvKipcbiAgICogVGhpcyBob29rIGFsbG93cyB5b3UgdG8gaW50ZXJjZXB0IGFuZCBtb2RpZnkgdHJhbnNhY3Rpb25zIGJlZm9yZSB0aGV5IGFyZSBkaXNwYXRjaGVkLlxuICAgKlxuICAgKiBFeGFtcGxlXG4gICAqIGBgYHRzXG4gICAqIGRpc3BhdGNoVHJhbnNhY3Rpb24oeyB0cmFuc2FjdGlvbiwgbmV4dCB9KSB7XG4gICAqICAgY29uc29sZS5sb2coJ0Rpc3BhdGNoaW5nIHRyYW5zYWN0aW9uOicsIHRyYW5zYWN0aW9uKVxuICAgKiAgIG5leHQodHJhbnNhY3Rpb24pXG4gICAqIH1cbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSBwcm9wcyAtIFRoZSBkaXNwYXRjaCB0cmFuc2FjdGlvbiBwcm9wc1xuICAgKi9cbiAgZGlzcGF0Y2hUcmFuc2FjdGlvbj86XG4gICAgfCAoKFxuICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgIHR5cGU6IFBNVHlwZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPENvbmZpZz5bJ2Rpc3BhdGNoVHJhbnNhY3Rpb24nXVxuICAgICAgICB9LFxuICAgICAgICBwcm9wczogRGlzcGF0Y2hUcmFuc2FjdGlvblByb3BzLFxuICAgICAgKSA9PiB2b2lkKVxuICAgIHwgbnVsbFxufVxuXG5leHBvcnQgY2xhc3MgRXh0ZW5kYWJsZTxcbiAgT3B0aW9ucyA9IGFueSxcbiAgU3RvcmFnZSA9IGFueSxcbiAgQ29uZmlnID1cbiAgICB8IEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPlxuICAgIHwgTm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPlxuICAgIHwgTWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPixcbj4ge1xuICB0eXBlID0gJ2V4dGVuZGFibGUnXG4gIHBhcmVudDogRXh0ZW5kYWJsZSB8IG51bGwgPSBudWxsXG5cbiAgY2hpbGQ6IEV4dGVuZGFibGUgfCBudWxsID0gbnVsbFxuXG4gIG5hbWUgPSAnJ1xuXG4gIGNvbmZpZzogQ29uZmlnID0ge1xuICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgfSBhcyBDb25maWdcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFBhcnRpYWw8Q29uZmlnPiA9IHt9KSB7XG4gICAgdGhpcy5jb25maWcgPSB7XG4gICAgICAuLi50aGlzLmNvbmZpZyxcbiAgICAgIC4uLmNvbmZpZyxcbiAgICB9XG5cbiAgICB0aGlzLm5hbWUgPSAodGhpcy5jb25maWcgYXMgYW55KS5uYW1lXG4gIH1cblxuICBnZXQgb3B0aW9ucygpOiBPcHRpb25zIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uY2FsbE9yUmV0dXJuKFxuICAgICAgICBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZE9wdGlvbnMnXT4odGhpcyBhcyBhbnksICdhZGRPcHRpb25zJywge1xuICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgIH1cbiAgfVxuXG4gIGdldCBzdG9yYWdlKCk6IFJlYWRvbmx5PFN0b3JhZ2U+IHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uY2FsbE9yUmV0dXJuKFxuICAgICAgICBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZFN0b3JhZ2UnXT4odGhpcyBhcyBhbnksICdhZGRTdG9yYWdlJywge1xuICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnMsXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICB9XG4gIH1cblxuICBjb25maWd1cmUob3B0aW9uczogUGFydGlhbDxPcHRpb25zPiA9IHt9KSB7XG4gICAgY29uc3QgZXh0ZW5zaW9uID0gdGhpcy5leHRlbmQ8T3B0aW9ucywgU3RvcmFnZSwgQ29uZmlnPih7XG4gICAgICAuLi50aGlzLmNvbmZpZyxcbiAgICAgIGFkZE9wdGlvbnM6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIG1lcmdlRGVlcCh0aGlzLm9wdGlvbnMgYXMgUmVjb3JkPHN0cmluZywgYW55Piwgb3B0aW9ucykgYXMgT3B0aW9uc1xuICAgICAgfSxcbiAgICB9KVxuXG4gICAgZXh0ZW5zaW9uLm5hbWUgPSB0aGlzLm5hbWVcbiAgICBleHRlbnNpb24ucGFyZW50ID0gdGhpcy5wYXJlbnRcblxuICAgIHRoaXMuY2hpbGQgPSBudWxsXG5cbiAgICByZXR1cm4gZXh0ZW5zaW9uXG4gIH1cblxuICBleHRlbmQ8XG4gICAgRXh0ZW5kZWRPcHRpb25zID0gT3B0aW9ucyxcbiAgICBFeHRlbmRlZFN0b3JhZ2UgPSBTdG9yYWdlLFxuICAgIEV4dGVuZGVkQ29uZmlnID1cbiAgICAgIHwgRXh0ZW5zaW9uQ29uZmlnPEV4dGVuZGVkT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlPlxuICAgICAgfCBOb2RlQ29uZmlnPEV4dGVuZGVkT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlPlxuICAgICAgfCBNYXJrQ29uZmlnPEV4dGVuZGVkT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlPixcbiAgPihleHRlbmRlZENvbmZpZzogUGFydGlhbDxFeHRlbmRlZENvbmZpZz4gPSB7fSk6IEV4dGVuZGFibGU8RXh0ZW5kZWRPcHRpb25zLCBFeHRlbmRlZFN0b3JhZ2U+IHtcbiAgICBjb25zdCBleHRlbnNpb24gPSBuZXcgKHRoaXMuY29uc3RydWN0b3IgYXMgYW55KSh7IC4uLnRoaXMuY29uZmlnLCAuLi5leHRlbmRlZENvbmZpZyB9KVxuXG4gICAgZXh0ZW5zaW9uLnBhcmVudCA9IHRoaXNcbiAgICB0aGlzLmNoaWxkID0gZXh0ZW5zaW9uXG4gICAgZXh0ZW5zaW9uLm5hbWUgPSAnbmFtZScgaW4gZXh0ZW5kZWRDb25maWcgPyBleHRlbmRlZENvbmZpZy5uYW1lIDogZXh0ZW5zaW9uLnBhcmVudC5uYW1lXG5cbiAgICByZXR1cm4gZXh0ZW5zaW9uXG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IERPTU91dHB1dFNwZWMsIE1hcmsgYXMgUHJvc2VNaXJyb3JNYXJrLCBNYXJrU3BlYywgTWFya1R5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgdHlwZSB7IEVkaXRvciB9IGZyb20gJy4vRWRpdG9yLmpzJ1xuaW1wb3J0IHR5cGUgeyBFeHRlbmRhYmxlQ29uZmlnIH0gZnJvbSAnLi9FeHRlbmRhYmxlLmpzJ1xuaW1wb3J0IHsgRXh0ZW5kYWJsZSB9IGZyb20gJy4vRXh0ZW5kYWJsZS5qcydcbmltcG9ydCB0eXBlIHsgQXR0cmlidXRlcywgTWFya1ZpZXdSZW5kZXJlciwgUGFyZW50Q29uZmlnIH0gZnJvbSAnLi90eXBlcy5qcydcblxuZXhwb3J0IGludGVyZmFjZSBNYXJrQ29uZmlnPE9wdGlvbnMgPSBhbnksIFN0b3JhZ2UgPSBhbnk+IGV4dGVuZHMgRXh0ZW5kYWJsZUNvbmZpZzxcbiAgT3B0aW9ucyxcbiAgU3RvcmFnZSxcbiAgTWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPixcbiAgTWFya1R5cGVcbj4ge1xuICAvKipcbiAgICogTWFyayBWaWV3XG4gICAqL1xuICBhZGRNYXJrVmlldz86XG4gICAgfCAoKHRoaXM6IHtcbiAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICB0eXBlOiBNYXJrVHlwZVxuICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkTWFya1ZpZXcnXVxuICAgICAgfSkgPT4gTWFya1ZpZXdSZW5kZXJlcilcbiAgICB8IG51bGxcblxuICAvKipcbiAgICogS2VlcCBtYXJrIGFmdGVyIHNwbGl0IG5vZGVcbiAgICovXG4gIGtlZXBPblNwbGl0PzogYm9vbGVhbiB8ICgoKSA9PiBib29sZWFuKVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgbWFyayBpcyByZW1vdmVkIGJ5IGB1bnNldEFsbE1hcmtzYC5cbiAgICogU2V0IHRvIGBmYWxzZWAgZm9yIHNlbWFudGljIG1hcmtzIChjb21tZW50cywgc3VnZ2VzdGlvbnMpIHRoYXQgc2hvdWxkIHN1cnZpdmUgXCJjbGVhciBmb3JtYXR0aW5nXCIuXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIGNsZWFyYWJsZT86IGJvb2xlYW4gfCAoKCkgPT4gYm9vbGVhbilcblxuICAvKipcbiAgICogSW5jbHVzaXZlXG4gICAqL1xuICBpbmNsdXNpdmU/OlxuICAgIHwgTWFya1NwZWNbJ2luY2x1c2l2ZSddXG4gICAgfCAoKHRoaXM6IHtcbiAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnaW5jbHVzaXZlJ11cbiAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICB9KSA9PiBNYXJrU3BlY1snaW5jbHVzaXZlJ10pXG5cbiAgLyoqXG4gICAqIEV4Y2x1ZGVzXG4gICAqL1xuICBleGNsdWRlcz86XG4gICAgfCBNYXJrU3BlY1snZXhjbHVkZXMnXVxuICAgIHwgKCh0aGlzOiB7XG4gICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2V4Y2x1ZGVzJ11cbiAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICB9KSA9PiBNYXJrU3BlY1snZXhjbHVkZXMnXSlcblxuICAvKipcbiAgICogTWFya3MgdGhpcyBNYXJrIGFzIGV4aXRhYmxlXG4gICAqL1xuICBleGl0YWJsZT86IGJvb2xlYW4gfCAoKCkgPT4gYm9vbGVhbilcblxuICAvKipcbiAgICogR3JvdXBcbiAgICovXG4gIGdyb3VwPzpcbiAgICB8IE1hcmtTcGVjWydncm91cCddXG4gICAgfCAoKHRoaXM6IHtcbiAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnZ3JvdXAnXVxuICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgIH0pID0+IE1hcmtTcGVjWydncm91cCddKVxuXG4gIC8qKlxuICAgKiBTcGFubmluZ1xuICAgKi9cbiAgc3Bhbm5pbmc/OlxuICAgIHwgTWFya1NwZWNbJ3NwYW5uaW5nJ11cbiAgICB8ICgodGhpczoge1xuICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE1hcmtDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydzcGFubmluZyddXG4gICAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgICAgfSkgPT4gTWFya1NwZWNbJ3NwYW5uaW5nJ10pXG5cbiAgLyoqXG4gICAqIENvZGVcbiAgICovXG4gIGNvZGU/OlxuICAgIHwgYm9vbGVhblxuICAgIHwgKCh0aGlzOiB7XG4gICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2NvZGUnXVxuICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgIH0pID0+IGJvb2xlYW4pXG5cbiAgLyoqXG4gICAqIFBhcnNlIEhUTUxcbiAgICovXG4gIHBhcnNlSFRNTD86ICh0aGlzOiB7XG4gICAgbmFtZTogc3RyaW5nXG4gICAgb3B0aW9uczogT3B0aW9uc1xuICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsncGFyc2VIVE1MJ11cbiAgICBlZGl0b3I/OiBFZGl0b3JcbiAgfSkgPT4gTWFya1NwZWNbJ3BhcnNlRE9NJ11cblxuICAvKipcbiAgICogUmVuZGVyIEhUTUxcbiAgICovXG4gIHJlbmRlckhUTUw/OlxuICAgIHwgKChcbiAgICAgICAgdGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ3JlbmRlckhUTUwnXVxuICAgICAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgICAgICB9LFxuICAgICAgICBwcm9wczoge1xuICAgICAgICAgIG1hcms6IFByb3NlTWlycm9yTWFya1xuICAgICAgICAgIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgICAgIH0sXG4gICAgICApID0+IERPTU91dHB1dFNwZWMpXG4gICAgfCBudWxsXG5cbiAgLyoqXG4gICAqIEF0dHJpYnV0ZXNcbiAgICovXG4gIGFkZEF0dHJpYnV0ZXM/OiAodGhpczoge1xuICAgIG5hbWU6IHN0cmluZ1xuICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZEF0dHJpYnV0ZXMnXVxuICAgIGVkaXRvcj86IEVkaXRvclxuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZW5vLWVtcHR5LW9iamVjdC10eXBlXG4gIH0pID0+IEF0dHJpYnV0ZXMgfCB7fVxufVxuXG4vKipcbiAqIFRoZSBNYXJrIGNsYXNzIGlzIHVzZWQgdG8gY3JlYXRlIGN1c3RvbSBtYXJrIGV4dGVuc2lvbnMuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9hcGkvZXh0ZW5zaW9ucyNjcmVhdGUtYS1uZXctZXh0ZW5zaW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBNYXJrPE9wdGlvbnMgPSBhbnksIFN0b3JhZ2UgPSBhbnk+IGV4dGVuZHMgRXh0ZW5kYWJsZTxcbiAgT3B0aW9ucyxcbiAgU3RvcmFnZSxcbiAgTWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPlxuPiB7XG4gIHR5cGUgPSAnbWFyaydcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IE1hcmsgaW5zdGFuY2VcbiAgICogQHBhcmFtIGNvbmZpZyAtIE1hcmsgY29uZmlndXJhdGlvbiBvYmplY3Qgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBjb25maWd1cmF0aW9uIG9iamVjdFxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZTxPID0gYW55LCBTID0gYW55PihcbiAgICBjb25maWc6IFBhcnRpYWw8TWFya0NvbmZpZzxPLCBTPj4gfCAoKCkgPT4gUGFydGlhbDxNYXJrQ29uZmlnPE8sIFM+PikgPSB7fSxcbiAgKSB7XG4gICAgLy8gSWYgdGhlIGNvbmZpZyBpcyBhIGZ1bmN0aW9uLCBleGVjdXRlIGl0IHRvIGdldCB0aGUgY29uZmlndXJhdGlvbiBvYmplY3RcbiAgICBjb25zdCByZXNvbHZlZENvbmZpZyA9IHR5cGVvZiBjb25maWcgPT09ICdmdW5jdGlvbicgPyBjb25maWcoKSA6IGNvbmZpZ1xuICAgIHJldHVybiBuZXcgTWFyazxPLCBTPihyZXNvbHZlZENvbmZpZylcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVFeGl0KHsgZWRpdG9yLCBtYXJrIH06IHsgZWRpdG9yOiBFZGl0b3I7IG1hcms6IE1hcmsgfSkge1xuICAgIGNvbnN0IHsgdHIgfSA9IGVkaXRvci5zdGF0ZVxuICAgIGNvbnN0IGN1cnJlbnRQb3MgPSBlZGl0b3Iuc3RhdGUuc2VsZWN0aW9uLiRmcm9tXG4gICAgY29uc3QgaXNBdEVuZCA9IGN1cnJlbnRQb3MucG9zID09PSBjdXJyZW50UG9zLmVuZCgpXG5cbiAgICBpZiAoaXNBdEVuZCkge1xuICAgICAgY29uc3QgY3VycmVudE1hcmtzID0gY3VycmVudFBvcy5tYXJrcygpXG4gICAgICBjb25zdCBpc0luTWFyayA9ICEhY3VycmVudE1hcmtzLmZpbmQobSA9PiBtPy50eXBlLm5hbWUgPT09IG1hcmsubmFtZSlcblxuICAgICAgaWYgKCFpc0luTWFyaykge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVtb3ZlTWFyayA9IGN1cnJlbnRNYXJrcy5maW5kKG0gPT4gbT8udHlwZS5uYW1lID09PSBtYXJrLm5hbWUpXG5cbiAgICAgIGlmIChyZW1vdmVNYXJrKSB7XG4gICAgICAgIHRyLnJlbW92ZVN0b3JlZE1hcmsocmVtb3ZlTWFyaylcbiAgICAgIH1cbiAgICAgIHRyLmluc2VydFRleHQoJyAnLCBjdXJyZW50UG9zLnBvcylcblxuICAgICAgZWRpdG9yLnZpZXcuZGlzcGF0Y2godHIpXG5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBjb25maWd1cmUob3B0aW9ucz86IFBhcnRpYWw8T3B0aW9ucz4pIHtcbiAgICByZXR1cm4gc3VwZXIuY29uZmlndXJlKG9wdGlvbnMpIGFzIE1hcms8T3B0aW9ucywgU3RvcmFnZT5cbiAgfVxuXG4gIGV4dGVuZDxcbiAgICBFeHRlbmRlZE9wdGlvbnMgPSBPcHRpb25zLFxuICAgIEV4dGVuZGVkU3RvcmFnZSA9IFN0b3JhZ2UsXG4gICAgRXh0ZW5kZWRDb25maWcgZXh0ZW5kcyBNYXJrQ29uZmlnPEV4dGVuZGVkT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlPiA9IE1hcmtDb25maWc8XG4gICAgICBFeHRlbmRlZE9wdGlvbnMsXG4gICAgICBFeHRlbmRlZFN0b3JhZ2VcbiAgICA+LFxuICA+KFxuICAgIGV4dGVuZGVkQ29uZmlnPzpcbiAgICAgIHwgKCgpID0+IFBhcnRpYWw8RXh0ZW5kZWRDb25maWc+KVxuICAgICAgfCAoUGFydGlhbDxFeHRlbmRlZENvbmZpZz4gJlxuICAgICAgICAgIFRoaXNUeXBlPHtcbiAgICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgICAgb3B0aW9uczogRXh0ZW5kZWRPcHRpb25zXG4gICAgICAgICAgICBzdG9yYWdlOiBFeHRlbmRlZFN0b3JhZ2VcbiAgICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgICB0eXBlOiBNYXJrVHlwZVxuICAgICAgICAgIH0+KSxcbiAgKTogTWFyazxFeHRlbmRlZE9wdGlvbnMsIEV4dGVuZGVkU3RvcmFnZT4ge1xuICAgIC8vIElmIHRoZSBleHRlbmRlZCBjb25maWcgaXMgYSBmdW5jdGlvbiwgZXhlY3V0ZSBpdCB0byBnZXQgdGhlIGNvbmZpZ3VyYXRpb24gb2JqZWN0XG4gICAgY29uc3QgcmVzb2x2ZWRDb25maWcgPSB0eXBlb2YgZXh0ZW5kZWRDb25maWcgPT09ICdmdW5jdGlvbicgPyBleHRlbmRlZENvbmZpZygpIDogZXh0ZW5kZWRDb25maWdcbiAgICByZXR1cm4gc3VwZXIuZXh0ZW5kKHJlc29sdmVkQ29uZmlnKSBhcyBNYXJrPEV4dGVuZGVkT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlPlxuICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBGcmFnbWVudCB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgdHlwZSB7IEVkaXRvclN0YXRlIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcbmltcG9ydCB7IFBsdWdpbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IENvbW1hbmRNYW5hZ2VyIH0gZnJvbSAnLi9Db21tYW5kTWFuYWdlci5qcydcbmltcG9ydCB0eXBlIHsgRWRpdG9yIH0gZnJvbSAnLi9FZGl0b3IuanMnXG5pbXBvcnQgeyBjcmVhdGVDaGFpbmFibGVTdGF0ZSB9IGZyb20gJy4vaGVscGVycy9jcmVhdGVDaGFpbmFibGVTdGF0ZS5qcydcbmltcG9ydCB7IGdldEhUTUxGcm9tRnJhZ21lbnQgfSBmcm9tICcuL2hlbHBlcnMvZ2V0SFRNTEZyb21GcmFnbWVudC5qcydcbmltcG9ydCB0eXBlIHtcbiAgQ2FuQ29tbWFuZHMsXG4gIENoYWluZWRDb21tYW5kcyxcbiAgRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5LFxuICBSYW5nZSxcbiAgU2luZ2xlQ29tbWFuZHMsXG59IGZyb20gJy4vdHlwZXMuanMnXG5pbXBvcnQgeyBpc051bWJlciB9IGZyb20gJy4vdXRpbGl0aWVzL2lzTnVtYmVyLmpzJ1xuaW1wb3J0IHsgaXNSZWdFeHAgfSBmcm9tICcuL3V0aWxpdGllcy9pc1JlZ0V4cC5qcydcblxuZXhwb3J0IHR5cGUgUGFzdGVSdWxlTWF0Y2ggPSB7XG4gIGluZGV4OiBudW1iZXJcbiAgdGV4dDogc3RyaW5nXG4gIHJlcGxhY2VXaXRoPzogc3RyaW5nXG4gIG1hdGNoPzogUmVnRXhwTWF0Y2hBcnJheVxuICBkYXRhPzogUmVjb3JkPHN0cmluZywgYW55PlxufVxuXG5leHBvcnQgdHlwZSBQYXN0ZVJ1bGVGaW5kZXIgPVxuICB8IFJlZ0V4cFxuICB8ICgodGV4dDogc3RyaW5nLCBldmVudD86IENsaXBib2FyZEV2ZW50IHwgbnVsbCkgPT4gUGFzdGVSdWxlTWF0Y2hbXSB8IG51bGwgfCB1bmRlZmluZWQpXG5cbi8qKlxuICogUGFzdGUgcnVsZXMgYXJlIHVzZWQgdG8gcmVhY3QgdG8gcGFzdGVkIGNvbnRlbnQuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9leHRlbnNpb25zL2N1c3RvbS1leHRlbnNpb25zL2V4dGVuZC1leGlzdGluZyNwYXN0ZS1ydWxlc1xuICovXG5leHBvcnQgY2xhc3MgUGFzdGVSdWxlIHtcbiAgZmluZDogUGFzdGVSdWxlRmluZGVyXG5cbiAgaGFuZGxlcjogKHByb3BzOiB7XG4gICAgc3RhdGU6IEVkaXRvclN0YXRlXG4gICAgcmFuZ2U6IFJhbmdlXG4gICAgbWF0Y2g6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheVxuICAgIGNvbW1hbmRzOiBTaW5nbGVDb21tYW5kc1xuICAgIGNoYWluOiAoKSA9PiBDaGFpbmVkQ29tbWFuZHNcbiAgICBjYW46ICgpID0+IENhbkNvbW1hbmRzXG4gICAgcGFzdGVFdmVudDogQ2xpcGJvYXJkRXZlbnQgfCBudWxsXG4gICAgZHJvcEV2ZW50OiBEcmFnRXZlbnQgfCBudWxsXG4gIH0pID0+IHZvaWQgfCBudWxsXG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiB7XG4gICAgZmluZDogUGFzdGVSdWxlRmluZGVyXG4gICAgaGFuZGxlcjogKHByb3BzOiB7XG4gICAgICBjYW46ICgpID0+IENhbkNvbW1hbmRzXG4gICAgICBjaGFpbjogKCkgPT4gQ2hhaW5lZENvbW1hbmRzXG4gICAgICBjb21tYW5kczogU2luZ2xlQ29tbWFuZHNcbiAgICAgIGRyb3BFdmVudDogRHJhZ0V2ZW50IHwgbnVsbFxuICAgICAgbWF0Y2g6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheVxuICAgICAgcGFzdGVFdmVudDogQ2xpcGJvYXJkRXZlbnQgfCBudWxsXG4gICAgICByYW5nZTogUmFuZ2VcbiAgICAgIHN0YXRlOiBFZGl0b3JTdGF0ZVxuICAgIH0pID0+IHZvaWQgfCBudWxsXG4gIH0pIHtcbiAgICB0aGlzLmZpbmQgPSBjb25maWcuZmluZFxuICAgIHRoaXMuaGFuZGxlciA9IGNvbmZpZy5oYW5kbGVyXG4gIH1cbn1cblxuY29uc3QgcGFzdGVSdWxlTWF0Y2hlckhhbmRsZXIgPSAoXG4gIHRleHQ6IHN0cmluZyxcbiAgZmluZDogUGFzdGVSdWxlRmluZGVyLFxuICBldmVudD86IENsaXBib2FyZEV2ZW50IHwgbnVsbCxcbik6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheVtdID0+IHtcbiAgaWYgKGlzUmVnRXhwKGZpbmQpKSB7XG4gICAgcmV0dXJuIFsuLi50ZXh0Lm1hdGNoQWxsKGZpbmQpXVxuICB9XG5cbiAgY29uc3QgbWF0Y2hlcyA9IGZpbmQodGV4dCwgZXZlbnQpXG5cbiAgaWYgKCFtYXRjaGVzKSB7XG4gICAgcmV0dXJuIFtdXG4gIH1cblxuICByZXR1cm4gbWF0Y2hlcy5tYXAocGFzdGVSdWxlTWF0Y2ggPT4ge1xuICAgIGNvbnN0IHJlc3VsdDogRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5ID0gW3Bhc3RlUnVsZU1hdGNoLnRleHRdXG5cbiAgICByZXN1bHQuaW5kZXggPSBwYXN0ZVJ1bGVNYXRjaC5pbmRleFxuICAgIHJlc3VsdC5pbnB1dCA9IHRleHRcbiAgICByZXN1bHQuZGF0YSA9IHBhc3RlUnVsZU1hdGNoLmRhdGFcblxuICAgIGlmIChwYXN0ZVJ1bGVNYXRjaC5yZXBsYWNlV2l0aCkge1xuICAgICAgaWYgKCFwYXN0ZVJ1bGVNYXRjaC50ZXh0LmluY2x1ZGVzKHBhc3RlUnVsZU1hdGNoLnJlcGxhY2VXaXRoKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgJ1t0aXB0YXAgd2Fybl06IFwicGFzdGVSdWxlTWF0Y2gucmVwbGFjZVdpdGhcIiBtdXN0IGJlIHBhcnQgb2YgXCJwYXN0ZVJ1bGVNYXRjaC50ZXh0XCIuJyxcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICByZXN1bHQucHVzaChwYXN0ZVJ1bGVNYXRjaC5yZXBsYWNlV2l0aClcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0XG4gIH0pXG59XG5cbmZ1bmN0aW9uIHJ1bihjb25maWc6IHtcbiAgZWRpdG9yOiBFZGl0b3JcbiAgc3RhdGU6IEVkaXRvclN0YXRlXG4gIGZyb206IG51bWJlclxuICB0bzogbnVtYmVyXG4gIHJ1bGU6IFBhc3RlUnVsZVxuICBwYXN0ZUV2ZW50OiBDbGlwYm9hcmRFdmVudCB8IG51bGxcbiAgZHJvcEV2ZW50OiBEcmFnRXZlbnQgfCBudWxsXG59KTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgZWRpdG9yLCBzdGF0ZSwgZnJvbSwgdG8sIHJ1bGUsIHBhc3RlRXZlbnQsIGRyb3BFdmVudCB9ID0gY29uZmlnXG5cbiAgY29uc3QgeyBjb21tYW5kcywgY2hhaW4sIGNhbiB9ID0gbmV3IENvbW1hbmRNYW5hZ2VyKHtcbiAgICBlZGl0b3IsXG4gICAgc3RhdGUsXG4gIH0pXG5cbiAgY29uc3QgaGFuZGxlcnM6ICh2b2lkIHwgbnVsbClbXSA9IFtdXG5cbiAgc3RhdGUuZG9jLm5vZGVzQmV0d2Vlbihmcm9tLCB0bywgKG5vZGUsIHBvcykgPT4ge1xuICAgIC8vIFNraXAgY29kZSBibG9ja3MgYW5kIG5vbi10ZXh0dWFsIG5vZGVzLlxuICAgIC8vIEJlIGRlZmVuc2l2ZTogYG5vZGVgIG1heSBiZSBhIEZyYWdtZW50IHdpdGhvdXQgYSBgdHlwZWAuIE9ubHkgdGV4dCxcbiAgICAvLyBpbmxpbmUsIG9yIHRleHRibG9jayBub2RlcyBhcmUgcHJvY2Vzc2VkIGJ5IHBhc3RlIHJ1bGVzLlxuICAgIGlmIChub2RlLnR5cGU/LnNwZWM/LmNvZGUgfHwgIShub2RlLmlzVGV4dCB8fCBub2RlLmlzVGV4dGJsb2NrIHx8IG5vZGUuaXNJbmxpbmUpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBGb3IgdGV4dGJsb2NrIGFuZCBpbmxpbmUvdGV4dCBub2RlcywgY29tcHV0ZSB0aGUgcmFuZ2UgcmVsYXRpdmUgdG8gdGhlIG5vZGUuXG4gICAgLy8gUHJlZmVyIGBub2RlLm5vZGVTaXplYCB3aGVuIGF2YWlsYWJsZSAoc29tZSBOb2RlIHNoYXBlcyBleHBvc2UgdGhpcyksXG4gICAgLy8gb3RoZXJ3aXNlIGZhbGwgYmFjayB0byBgbm9kZS5jb250ZW50Py5zaXplYC4gRGVmYXVsdCB0byAwIGlmIG5laXRoZXIgZXhpc3RzLlxuICAgIGNvbnN0IGNvbnRlbnRTaXplID0gbm9kZS5jb250ZW50Py5zaXplID8/IG5vZGUubm9kZVNpemUgPz8gMFxuICAgIGNvbnN0IHJlc29sdmVkRnJvbSA9IE1hdGgubWF4KGZyb20sIHBvcylcbiAgICBjb25zdCByZXNvbHZlZFRvID0gTWF0aC5taW4odG8sIHBvcyArIGNvbnRlbnRTaXplKVxuXG4gICAgLy8gSWYgdGhlIHJlc29sdmVkIHJhbmdlIGlzIGVtcHR5IG9yIGludmFsaWQgZm9yIHRoaXMgbm9kZSwgc2tpcCBpdC4gVGhpc1xuICAgIC8vIGF2b2lkcyBjYWxsaW5nIGB0ZXh0QmV0d2VlbmAgd2l0aCBzdGFydCA+IGVuZCB3aGljaCBjYW4gY2F1c2UgaW50ZXJuYWxcbiAgICAvLyBGcmFnbWVudC9Ob2RlIHRyYXZlcnNhbCB0byBhY2Nlc3MgdW5kZWZpbmVkIGBub2RlU2l6ZWAgdmFsdWVzLlxuICAgIGlmIChyZXNvbHZlZEZyb20gPj0gcmVzb2x2ZWRUbykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgdGV4dFRvTWF0Y2ggPSBub2RlLmlzVGV4dFxuICAgICAgPyBub2RlLnRleHQgfHwgJydcbiAgICAgIDogbm9kZS50ZXh0QmV0d2VlbihyZXNvbHZlZEZyb20gLSBwb3MsIHJlc29sdmVkVG8gLSBwb3MsIHVuZGVmaW5lZCwgJ1xcdWZmZmMnKVxuXG4gICAgY29uc3QgbWF0Y2hlcyA9IHBhc3RlUnVsZU1hdGNoZXJIYW5kbGVyKHRleHRUb01hdGNoLCBydWxlLmZpbmQsIHBhc3RlRXZlbnQpXG5cbiAgICBtYXRjaGVzLmZvckVhY2gobWF0Y2ggPT4ge1xuICAgICAgaWYgKG1hdGNoLmluZGV4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN0YXJ0ID0gcmVzb2x2ZWRGcm9tICsgbWF0Y2guaW5kZXggKyAxXG4gICAgICBjb25zdCBlbmQgPSBzdGFydCArIG1hdGNoWzBdLmxlbmd0aFxuICAgICAgY29uc3QgcmFuZ2UgPSB7XG4gICAgICAgIGZyb206IHN0YXRlLnRyLm1hcHBpbmcubWFwKHN0YXJ0KSxcbiAgICAgICAgdG86IHN0YXRlLnRyLm1hcHBpbmcubWFwKGVuZCksXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhhbmRsZXIgPSBydWxlLmhhbmRsZXIoe1xuICAgICAgICBzdGF0ZSxcbiAgICAgICAgcmFuZ2UsXG4gICAgICAgIG1hdGNoLFxuICAgICAgICBjb21tYW5kcyxcbiAgICAgICAgY2hhaW4sXG4gICAgICAgIGNhbixcbiAgICAgICAgcGFzdGVFdmVudCxcbiAgICAgICAgZHJvcEV2ZW50LFxuICAgICAgfSlcblxuICAgICAgaGFuZGxlcnMucHVzaChoYW5kbGVyKVxuICAgIH0pXG4gIH0pXG5cbiAgY29uc3Qgc3VjY2VzcyA9IGhhbmRsZXJzLmV2ZXJ5KGhhbmRsZXIgPT4gaGFuZGxlciAhPT0gbnVsbClcblxuICByZXR1cm4gc3VjY2Vzc1xufVxuXG4vLyBXaGVuIGRyYWdnaW5nIGFjcm9zcyBlZGl0b3JzLCBtdXN0IGdldCBhbm90aGVyIGVkaXRvciBpbnN0YW5jZSB0byBkZWxldGUgc2VsZWN0aW9uIGNvbnRlbnQuXG5sZXQgdGlwdGFwRHJhZ0Zyb21PdGhlckVkaXRvcjogRWRpdG9yIHwgbnVsbCA9IG51bGxcblxuY29uc3QgY3JlYXRlQ2xpcGJvYXJkUGFzdGVFdmVudCA9ICh0ZXh0OiBzdHJpbmcpID0+IHtcbiAgY29uc3QgZXZlbnQgPSBuZXcgQ2xpcGJvYXJkRXZlbnQoJ3Bhc3RlJywge1xuICAgIGNsaXBib2FyZERhdGE6IG5ldyBEYXRhVHJhbnNmZXIoKSxcbiAgfSlcblxuICBldmVudC5jbGlwYm9hcmREYXRhPy5zZXREYXRhKCd0ZXh0L2h0bWwnLCB0ZXh0KVxuXG4gIHJldHVybiBldmVudFxufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBwYXN0ZSBydWxlcyBwbHVnaW4uIFdoZW4gZW5hYmxlZCwgaXQgd2lsbCBjYXVzZSBwYXN0ZWRcbiAqIHRleHQgdGhhdCBtYXRjaGVzIGFueSBvZiB0aGUgZ2l2ZW4gcnVsZXMgdG8gdHJpZ2dlciB0aGUgcnVsZeKAmXNcbiAqIGFjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhc3RlUnVsZXNQbHVnaW4ocHJvcHM6IHsgZWRpdG9yOiBFZGl0b3I7IHJ1bGVzOiBQYXN0ZVJ1bGVbXSB9KTogUGx1Z2luW10ge1xuICBjb25zdCB7IGVkaXRvciwgcnVsZXMgfSA9IHByb3BzXG4gIGxldCBkcmFnU291cmNlRWxlbWVudDogRWxlbWVudCB8IG51bGwgPSBudWxsXG4gIGxldCBpc1Bhc3RlZEZyb21Qcm9zZU1pcnJvciA9IGZhbHNlXG4gIGxldCBpc0Ryb3BwZWRGcm9tUHJvc2VNaXJyb3IgPSBmYWxzZVxuICBsZXQgcGFzdGVFdmVudCA9IHR5cGVvZiBDbGlwYm9hcmRFdmVudCAhPT0gJ3VuZGVmaW5lZCcgPyBuZXcgQ2xpcGJvYXJkRXZlbnQoJ3Bhc3RlJykgOiBudWxsXG4gIGxldCBkcm9wRXZlbnQ6IERyYWdFdmVudCB8IG51bGxcblxuICB0cnkge1xuICAgIGRyb3BFdmVudCA9IHR5cGVvZiBEcmFnRXZlbnQgIT09ICd1bmRlZmluZWQnID8gbmV3IERyYWdFdmVudCgnZHJvcCcpIDogbnVsbFxuICB9IGNhdGNoIHtcbiAgICBkcm9wRXZlbnQgPSBudWxsXG4gIH1cblxuICBjb25zdCBwcm9jZXNzRXZlbnQgPSAoe1xuICAgIHN0YXRlLFxuICAgIGZyb20sXG4gICAgdG8sXG4gICAgcnVsZSxcbiAgICBwYXN0ZUV2dCxcbiAgfToge1xuICAgIHN0YXRlOiBFZGl0b3JTdGF0ZVxuICAgIGZyb206IG51bWJlclxuICAgIHRvOiB7IGI6IG51bWJlciB9XG4gICAgcnVsZTogUGFzdGVSdWxlXG4gICAgcGFzdGVFdnQ6IENsaXBib2FyZEV2ZW50IHwgbnVsbFxuICB9KSA9PiB7XG4gICAgY29uc3QgdHIgPSBzdGF0ZS50clxuICAgIGNvbnN0IGNoYWluYWJsZVN0YXRlID0gY3JlYXRlQ2hhaW5hYmxlU3RhdGUoe1xuICAgICAgc3RhdGUsXG4gICAgICB0cmFuc2FjdGlvbjogdHIsXG4gICAgfSlcblxuICAgIGNvbnN0IGhhbmRsZXIgPSBydW4oe1xuICAgICAgZWRpdG9yLFxuICAgICAgc3RhdGU6IGNoYWluYWJsZVN0YXRlLFxuICAgICAgZnJvbTogTWF0aC5tYXgoZnJvbSAtIDEsIDApLFxuICAgICAgdG86IHRvLmIgLSAxLFxuICAgICAgcnVsZSxcbiAgICAgIHBhc3RlRXZlbnQ6IHBhc3RlRXZ0LFxuICAgICAgZHJvcEV2ZW50LFxuICAgIH0pXG5cbiAgICBpZiAoIWhhbmRsZXIgfHwgIXRyLnN0ZXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGRyb3BFdmVudCA9IHR5cGVvZiBEcmFnRXZlbnQgIT09ICd1bmRlZmluZWQnID8gbmV3IERyYWdFdmVudCgnZHJvcCcpIDogbnVsbFxuICAgIH0gY2F0Y2gge1xuICAgICAgZHJvcEV2ZW50ID0gbnVsbFxuICAgIH1cbiAgICBwYXN0ZUV2ZW50ID0gdHlwZW9mIENsaXBib2FyZEV2ZW50ICE9PSAndW5kZWZpbmVkJyA/IG5ldyBDbGlwYm9hcmRFdmVudCgncGFzdGUnKSA6IG51bGxcblxuICAgIHJldHVybiB0clxuICB9XG5cbiAgY29uc3QgcGx1Z2lucyA9IHJ1bGVzLm1hcChydWxlID0+IHtcbiAgICByZXR1cm4gbmV3IFBsdWdpbih7XG4gICAgICAvLyB3ZSByZWdpc3RlciBhIGdsb2JhbCBkcmFnIGhhbmRsZXIgdG8gdHJhY2sgdGhlIGN1cnJlbnQgZHJhZyBzb3VyY2UgZWxlbWVudFxuICAgICAgdmlldyh2aWV3KSB7XG4gICAgICAgIGNvbnN0IGhhbmRsZURyYWdzdGFydCA9IChldmVudDogRHJhZ0V2ZW50KSA9PiB7XG4gICAgICAgICAgZHJhZ1NvdXJjZUVsZW1lbnQgPSB2aWV3LmRvbS5wYXJlbnRFbGVtZW50Py5jb250YWlucyhldmVudC50YXJnZXQgYXMgRWxlbWVudClcbiAgICAgICAgICAgID8gdmlldy5kb20ucGFyZW50RWxlbWVudFxuICAgICAgICAgICAgOiBudWxsXG5cbiAgICAgICAgICBpZiAoZHJhZ1NvdXJjZUVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRpcHRhcERyYWdGcm9tT3RoZXJFZGl0b3IgPSBlZGl0b3JcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBoYW5kbGVEcmFnZW5kID0gKCkgPT4ge1xuICAgICAgICAgIGlmICh0aXB0YXBEcmFnRnJvbU90aGVyRWRpdG9yKSB7XG4gICAgICAgICAgICB0aXB0YXBEcmFnRnJvbU90aGVyRWRpdG9yID0gbnVsbFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdkcmFnc3RhcnQnLCBoYW5kbGVEcmFnc3RhcnQpXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdkcmFnZW5kJywgaGFuZGxlRHJhZ2VuZClcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGRlc3Ryb3koKSB7XG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignZHJhZ3N0YXJ0JywgaGFuZGxlRHJhZ3N0YXJ0KVxuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2RyYWdlbmQnLCBoYW5kbGVEcmFnZW5kKVxuICAgICAgICAgIH0sXG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIHByb3BzOiB7XG4gICAgICAgIGhhbmRsZURPTUV2ZW50czoge1xuICAgICAgICAgIGRyb3A6ICh2aWV3LCBldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlzRHJvcHBlZEZyb21Qcm9zZU1pcnJvciA9IGRyYWdTb3VyY2VFbGVtZW50ID09PSB2aWV3LmRvbS5wYXJlbnRFbGVtZW50XG4gICAgICAgICAgICBkcm9wRXZlbnQgPSBldmVudCBhcyBEcmFnRXZlbnRcblxuICAgICAgICAgICAgaWYgKCFpc0Ryb3BwZWRGcm9tUHJvc2VNaXJyb3IpIHtcbiAgICAgICAgICAgICAgY29uc3QgZHJhZ0Zyb21PdGhlckVkaXRvciA9IHRpcHRhcERyYWdGcm9tT3RoZXJFZGl0b3JcblxuICAgICAgICAgICAgICBpZiAoZHJhZ0Zyb21PdGhlckVkaXRvcj8uaXNFZGl0YWJsZSkge1xuICAgICAgICAgICAgICAgIC8vIHNldFRpbWVvdXQgdG8gYXZvaWQgdGhlIHdyb25nIGNvbnRlbnQgYWZ0ZXIgZHJvcCwgdGltZW91dCBhcmcgY2FuJ3QgYmUgZW1wdHkgb3IgMFxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgY29uc3Qgc2VsZWN0aW9uID0gZHJhZ0Zyb21PdGhlckVkaXRvci5zdGF0ZS5zZWxlY3Rpb25cblxuICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBkcmFnRnJvbU90aGVyRWRpdG9yLmNvbW1hbmRzLmRlbGV0ZVJhbmdlKHtcbiAgICAgICAgICAgICAgICAgICAgICBmcm9tOiBzZWxlY3Rpb24uZnJvbSxcbiAgICAgICAgICAgICAgICAgICAgICB0bzogc2VsZWN0aW9uLnRvLFxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sIDEwKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICB9LFxuXG4gICAgICAgICAgcGFzdGU6IChfdmlldywgZXZlbnQ6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBodG1sID0gKGV2ZW50IGFzIENsaXBib2FyZEV2ZW50KS5jbGlwYm9hcmREYXRhPy5nZXREYXRhKCd0ZXh0L2h0bWwnKVxuXG4gICAgICAgICAgICBwYXN0ZUV2ZW50ID0gZXZlbnQgYXMgQ2xpcGJvYXJkRXZlbnRcblxuICAgICAgICAgICAgaXNQYXN0ZWRGcm9tUHJvc2VNaXJyb3IgPSAhIWh0bWw/LmluY2x1ZGVzKCdkYXRhLXBtLXNsaWNlJylcblxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIGFwcGVuZFRyYW5zYWN0aW9uOiAodHJhbnNhY3Rpb25zLCBvbGRTdGF0ZSwgc3RhdGUpID0+IHtcbiAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSB0cmFuc2FjdGlvbnNbMF1cbiAgICAgICAgY29uc3QgaXNQYXN0ZSA9IHRyYW5zYWN0aW9uLmdldE1ldGEoJ3VpRXZlbnQnKSA9PT0gJ3Bhc3RlJyAmJiAhaXNQYXN0ZWRGcm9tUHJvc2VNaXJyb3JcbiAgICAgICAgY29uc3QgaXNEcm9wID0gdHJhbnNhY3Rpb24uZ2V0TWV0YSgndWlFdmVudCcpID09PSAnZHJvcCcgJiYgIWlzRHJvcHBlZEZyb21Qcm9zZU1pcnJvclxuXG4gICAgICAgIC8vIGlmIFBhc3RlUnVsZSBpcyB0cmlnZ2VyZWQgYnkgaW5zZXJ0Q29udGVudCgpXG4gICAgICAgIGNvbnN0IHNpbXVsYXRlZFBhc3RlTWV0YSA9IHRyYW5zYWN0aW9uLmdldE1ldGEoJ2FwcGx5UGFzdGVSdWxlcycpIGFzXG4gICAgICAgICAgfCB1bmRlZmluZWRcbiAgICAgICAgICB8IHsgZnJvbTogbnVtYmVyOyB0ZXh0OiBzdHJpbmcgfCBQcm9zZU1pcnJvck5vZGUgfCBGcmFnbWVudCB9XG4gICAgICAgIGNvbnN0IGlzU2ltdWxhdGVkUGFzdGUgPSAhIXNpbXVsYXRlZFBhc3RlTWV0YVxuXG4gICAgICAgIGlmICghaXNQYXN0ZSAmJiAhaXNEcm9wICYmICFpc1NpbXVsYXRlZFBhc3RlKSB7XG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgc2ltdWxhdGVkIHBhc3RlXG4gICAgICAgIGlmIChpc1NpbXVsYXRlZFBhc3RlKSB7XG4gICAgICAgICAgbGV0IHsgdGV4dCB9ID0gc2ltdWxhdGVkUGFzdGVNZXRhXG5cbiAgICAgICAgICBpZiAodHlwZW9mIHRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0ZXh0ID0gdGV4dCBhcyBzdHJpbmdcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGV4dCA9IGdldEhUTUxGcm9tRnJhZ21lbnQoRnJhZ21lbnQuZnJvbSh0ZXh0KSwgc3RhdGUuc2NoZW1hKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHsgZnJvbSB9ID0gc2ltdWxhdGVkUGFzdGVNZXRhXG4gICAgICAgICAgY29uc3QgdG8gPSBmcm9tICsgdGV4dC5sZW5ndGhcblxuICAgICAgICAgIGNvbnN0IHBhc3RlRXZ0ID0gY3JlYXRlQ2xpcGJvYXJkUGFzdGVFdmVudCh0ZXh0KVxuXG4gICAgICAgICAgcmV0dXJuIHByb2Nlc3NFdmVudCh7XG4gICAgICAgICAgICBydWxlLFxuICAgICAgICAgICAgc3RhdGUsXG4gICAgICAgICAgICBmcm9tLFxuICAgICAgICAgICAgdG86IHsgYjogdG8gfSxcbiAgICAgICAgICAgIHBhc3RlRXZ0LFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICAvLyBoYW5kbGUgYWN0dWFsIHBhc3RlL2Ryb3BcbiAgICAgICAgY29uc3QgZnJvbSA9IG9sZFN0YXRlLmRvYy5jb250ZW50LmZpbmREaWZmU3RhcnQoc3RhdGUuZG9jLmNvbnRlbnQpXG4gICAgICAgIGNvbnN0IHRvID0gb2xkU3RhdGUuZG9jLmNvbnRlbnQuZmluZERpZmZFbmQoc3RhdGUuZG9jLmNvbnRlbnQpXG5cbiAgICAgICAgLy8gc3RvcCBpZiB0aGVyZSBpcyBubyBjaGFuZ2VkIHJhbmdlXG4gICAgICAgIGlmICghaXNOdW1iZXIoZnJvbSkgfHwgIXRvIHx8IGZyb20gPT09IHRvLmIpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwcm9jZXNzRXZlbnQoe1xuICAgICAgICAgIHJ1bGUsXG4gICAgICAgICAgc3RhdGUsXG4gICAgICAgICAgZnJvbSxcbiAgICAgICAgICB0byxcbiAgICAgICAgICBwYXN0ZUV2dDogcGFzdGVFdmVudCxcbiAgICAgICAgfSlcbiAgICAgIH0sXG4gICAgfSlcbiAgfSlcblxuICByZXR1cm4gcGx1Z2luc1xufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpc051bWJlcih2YWx1ZTogYW55KTogdmFsdWUgaXMgbnVtYmVyIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcidcbn1cbiIsICJleHBvcnQgeyBDbGlwYm9hcmRUZXh0U2VyaWFsaXplciB9IGZyb20gJy4vY2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXIuanMnXG5leHBvcnQgeyBDb21tYW5kcyB9IGZyb20gJy4vY29tbWFuZHMuanMnXG5leHBvcnQgeyBEZWxldGUgfSBmcm9tICcuL2RlbGV0ZS5qcydcbmV4cG9ydCB7IERyb3AgfSBmcm9tICcuL2Ryb3AuanMnXG5leHBvcnQgeyBFZGl0YWJsZSB9IGZyb20gJy4vZWRpdGFibGUuanMnXG5leHBvcnQgeyBGb2N1c0V2ZW50cywgZm9jdXNFdmVudHNQbHVnaW5LZXkgfSBmcm9tICcuL2ZvY3VzRXZlbnRzLmpzJ1xuZXhwb3J0IHsgS2V5bWFwIH0gZnJvbSAnLi9rZXltYXAuanMnXG5leHBvcnQgeyBQYXN0ZSB9IGZyb20gJy4vcGFzdGUuanMnXG5leHBvcnQgeyBUYWJpbmRleCB9IGZyb20gJy4vdGFiaW5kZXguanMnXG5leHBvcnQgeyBUZXh0RGlyZWN0aW9uIH0gZnJvbSAnLi90ZXh0RGlyZWN0aW9uLmpzJ1xuIiwgImltcG9ydCB7IFBsdWdpbiwgUGx1Z2luS2V5IH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgRXh0ZW5zaW9uIH0gZnJvbSAnLi4vRXh0ZW5zaW9uLmpzJ1xuaW1wb3J0IHsgZ2V0VGV4dEJldHdlZW4gfSBmcm9tICcuLi9oZWxwZXJzL2dldFRleHRCZXR3ZWVuLmpzJ1xuaW1wb3J0IHsgZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYS5qcydcblxuZXhwb3J0IHR5cGUgQ2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXJPcHRpb25zID0ge1xuICBibG9ja1NlcGFyYXRvcj86IHN0cmluZ1xufVxuXG5leHBvcnQgY29uc3QgQ2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXIgPSBFeHRlbnNpb24uY3JlYXRlPENsaXBib2FyZFRleHRTZXJpYWxpemVyT3B0aW9ucz4oe1xuICBuYW1lOiAnY2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXInLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGJsb2NrU2VwYXJhdG9yOiB1bmRlZmluZWQsXG4gICAgfVxuICB9LFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleSgnY2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXInKSxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICBjbGlwYm9hcmRUZXh0U2VyaWFsaXplcjogKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlZGl0b3IgfSA9IHRoaXNcbiAgICAgICAgICAgIGNvbnN0IHsgc3RhdGUsIHNjaGVtYSB9ID0gZWRpdG9yXG4gICAgICAgICAgICBjb25zdCB7IGRvYywgc2VsZWN0aW9uIH0gPSBzdGF0ZVxuICAgICAgICAgICAgY29uc3QgdGV4dFNlcmlhbGl6ZXJzID0gZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYShzY2hlbWEpXG4gICAgICAgICAgICBjb25zdCB7IGJsb2NrU2VwYXJhdG9yIH0gPSB0aGlzLm9wdGlvbnNcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgIC4uLihibG9ja1NlcGFyYXRvciAhPT0gdW5kZWZpbmVkID8geyBibG9ja1NlcGFyYXRvciB9IDoge30pLFxuICAgICAgICAgICAgICB0ZXh0U2VyaWFsaXplcnMsXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNlcmlhbGl6ZSBlYWNoIHNlbGVjdGlvbiByYW5nZSBpbmRlcGVuZGVudGx5IGFuZCBqb2luIHRoZSByZXN1bHRzLlxuICAgICAgICAgICAgLy8gQ2VsbFNlbGVjdGlvbiBleHBvc2VzIG9uZSByYW5nZSBwZXIgc2VsZWN0ZWQgY2VsbDsgZmxhdHRlbmluZyB0b1xuICAgICAgICAgICAgLy8gbWluKGZyb20pL21heCh0bykgd291bGQgcHVsbCBpbiB1bnNlbGVjdGVkIGNlbGxzIGJldHdlZW4gdGhlbS5cbiAgICAgICAgICAgIC8vIFNvcnQgYnkgZG9jdW1lbnQgcG9zaXRpb24gc28gcmV2ZXJzZSBzZWxlY3Rpb25zIChlLmcuIGRyYWdnaW5nXG4gICAgICAgICAgICAvLyB1cHdhcmQpIHN0aWxsIGVtaXQgdGV4dCBpbiBkb2N1bWVudCBvcmRlci5cbiAgICAgICAgICAgIGNvbnN0IHNvcnRlZFJhbmdlcyA9IFsuLi5zZWxlY3Rpb24ucmFuZ2VzXS5zb3J0KChhLCBiKSA9PiBhLiRmcm9tLnBvcyAtIGIuJGZyb20ucG9zKVxuXG4gICAgICAgICAgICByZXR1cm4gc29ydGVkUmFuZ2VzXG4gICAgICAgICAgICAgIC5tYXAoKHsgJGZyb20sICR0byB9KSA9PlxuICAgICAgICAgICAgICAgIGdldFRleHRCZXR3ZWVuKGRvYywgeyBmcm9tOiAkZnJvbS5wb3MsIHRvOiAkdG8ucG9zIH0sIG9wdGlvbnMpLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIC5qb2luKGJsb2NrU2VwYXJhdG9yID8/ICdcXG5cXG4nKVxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yIH0gZnJvbSAnLi9FZGl0b3IuanMnXG5pbXBvcnQgeyB0eXBlIEV4dGVuZGFibGVDb25maWcsIEV4dGVuZGFibGUgfSBmcm9tICcuL0V4dGVuZGFibGUuanMnXG5cbi8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZW5vLWVtcHR5LW9iamVjdC10eXBlXG5leHBvcnQgaW50ZXJmYWNlIEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zID0gYW55LCBTdG9yYWdlID0gYW55PiBleHRlbmRzIEV4dGVuZGFibGVDb25maWc8XG4gIE9wdGlvbnMsXG4gIFN0b3JhZ2UsXG4gIEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPixcbiAgbnVsbFxuPiB7fVxuXG4vKipcbiAqIFRoZSBFeHRlbnNpb24gY2xhc3MgaXMgdGhlIGJhc2UgY2xhc3MgZm9yIGFsbCBleHRlbnNpb25zLlxuICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvYXBpL2V4dGVuc2lvbnMjY3JlYXRlLWEtbmV3LWV4dGVuc2lvblxuICovXG5leHBvcnQgY2xhc3MgRXh0ZW5zaW9uPE9wdGlvbnMgPSBhbnksIFN0b3JhZ2UgPSBhbnk+IGV4dGVuZHMgRXh0ZW5kYWJsZTxcbiAgT3B0aW9ucyxcbiAgU3RvcmFnZSxcbiAgRXh0ZW5zaW9uQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+XG4+IHtcbiAgdHlwZSA9ICdleHRlbnNpb24nXG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBFeHRlbnNpb24gaW5zdGFuY2VcbiAgICogQHBhcmFtIGNvbmZpZyAtIEV4dGVuc2lvbiBjb25maWd1cmF0aW9uIG9iamVjdCBvciBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0XG4gICAqL1xuICBzdGF0aWMgY3JlYXRlPE8gPSBhbnksIFMgPSBhbnk+KFxuICAgIGNvbmZpZzogUGFydGlhbDxFeHRlbnNpb25Db25maWc8TywgUz4+IHwgKCgpID0+IFBhcnRpYWw8RXh0ZW5zaW9uQ29uZmlnPE8sIFM+PikgPSB7fSxcbiAgKSB7XG4gICAgLy8gSWYgdGhlIGNvbmZpZyBpcyBhIGZ1bmN0aW9uLCBleGVjdXRlIGl0IHRvIGdldCB0aGUgY29uZmlndXJhdGlvbiBvYmplY3RcbiAgICBjb25zdCByZXNvbHZlZENvbmZpZyA9IHR5cGVvZiBjb25maWcgPT09ICdmdW5jdGlvbicgPyBjb25maWcoKSA6IGNvbmZpZ1xuICAgIHJldHVybiBuZXcgRXh0ZW5zaW9uPE8sIFM+KHJlc29sdmVkQ29uZmlnKVxuICB9XG5cbiAgY29uZmlndXJlKG9wdGlvbnM/OiBQYXJ0aWFsPE9wdGlvbnM+KSB7XG4gICAgcmV0dXJuIHN1cGVyLmNvbmZpZ3VyZShvcHRpb25zKSBhcyBFeHRlbnNpb248T3B0aW9ucywgU3RvcmFnZT5cbiAgfVxuXG4gIGV4dGVuZDxcbiAgICBFeHRlbmRlZE9wdGlvbnMgPSBPcHRpb25zLFxuICAgIEV4dGVuZGVkU3RvcmFnZSA9IFN0b3JhZ2UsXG4gICAgRXh0ZW5kZWRDb25maWcgPSBFeHRlbnNpb25Db25maWc8RXh0ZW5kZWRPcHRpb25zLCBFeHRlbmRlZFN0b3JhZ2U+LFxuICA+KFxuICAgIGV4dGVuZGVkQ29uZmlnPzpcbiAgICAgIHwgKCgpID0+IFBhcnRpYWw8RXh0ZW5kZWRDb25maWc+KVxuICAgICAgfCAoUGFydGlhbDxFeHRlbmRlZENvbmZpZz4gJlxuICAgICAgICAgIFRoaXNUeXBlPHtcbiAgICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgICAgb3B0aW9uczogRXh0ZW5kZWRPcHRpb25zXG4gICAgICAgICAgICBzdG9yYWdlOiBFeHRlbmRlZFN0b3JhZ2VcbiAgICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgICB0eXBlOiBudWxsXG4gICAgICAgICAgfT4pLFxuICApOiBFeHRlbnNpb248RXh0ZW5kZWRPcHRpb25zLCBFeHRlbmRlZFN0b3JhZ2U+IHtcbiAgICAvLyBJZiB0aGUgZXh0ZW5kZWQgY29uZmlnIGlzIGEgZnVuY3Rpb24sIGV4ZWN1dGUgaXQgdG8gZ2V0IHRoZSBjb25maWd1cmF0aW9uIG9iamVjdFxuICAgIGNvbnN0IHJlc29sdmVkQ29uZmlnID0gdHlwZW9mIGV4dGVuZGVkQ29uZmlnID09PSAnZnVuY3Rpb24nID8gZXh0ZW5kZWRDb25maWcoKSA6IGV4dGVuZGVkQ29uZmlnXG4gICAgcmV0dXJuIHN1cGVyLmV4dGVuZChyZXNvbHZlZENvbmZpZykgYXMgRXh0ZW5zaW9uPEV4dGVuZGVkT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlPlxuICB9XG59XG4iLCAiaW1wb3J0ICogYXMgY29tbWFuZHMgZnJvbSAnLi4vY29tbWFuZHMvaW5kZXguanMnXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5cbmV4cG9ydCAqIGZyb20gJy4uL2NvbW1hbmRzL2luZGV4LmpzJ1xuXG5leHBvcnQgY29uc3QgQ29tbWFuZHMgPSBFeHRlbnNpb24uY3JlYXRlKHtcbiAgbmFtZTogJ2NvbW1hbmRzJyxcblxuICBhZGRDb21tYW5kcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uY29tbWFuZHMsXG4gICAgfVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBSZW1vdmVNYXJrU3RlcCB9IGZyb20gJ0B0aXB0YXAvcG0vdHJhbnNmb3JtJ1xuXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5pbXBvcnQgeyBjb21iaW5lVHJhbnNhY3Rpb25TdGVwcywgZ2V0Q2hhbmdlZFJhbmdlcyB9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnXG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBiZSBub3RpZmllZCB3aGVuIHRoZSB1c2VyIGRlbGV0ZXMgY29udGVudCB5b3UgYXJlIGludGVyZXN0ZWQgaW4uXG4gKi9cbmV4cG9ydCBjb25zdCBEZWxldGUgPSBFeHRlbnNpb24uY3JlYXRlKHtcbiAgbmFtZTogJ2RlbGV0ZScsXG5cbiAgb25VcGRhdGUoeyB0cmFuc2FjdGlvbiwgYXBwZW5kZWRUcmFuc2FjdGlvbnMgfSkge1xuICAgIGNvbnN0IGNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLmVkaXRvci5vcHRpb25zLmNvcmVFeHRlbnNpb25PcHRpb25zPy5kZWxldGU/LmZpbHRlclRyYW5zYWN0aW9uPy4odHJhbnNhY3Rpb24pID8/XG4gICAgICAgIHRyYW5zYWN0aW9uLmdldE1ldGEoJ3ktc3luYyQnKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgY29uc3QgbmV4dFRyYW5zYWN0aW9uID0gY29tYmluZVRyYW5zYWN0aW9uU3RlcHModHJhbnNhY3Rpb24uYmVmb3JlLCBbXG4gICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgICAuLi5hcHBlbmRlZFRyYW5zYWN0aW9ucyxcbiAgICAgIF0pXG4gICAgICBjb25zdCBjaGFuZ2VzID0gZ2V0Q2hhbmdlZFJhbmdlcyhuZXh0VHJhbnNhY3Rpb24pXG5cbiAgICAgIGNoYW5nZXMuZm9yRWFjaChjaGFuZ2UgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgbmV4dFRyYW5zYWN0aW9uLm1hcHBpbmcubWFwUmVzdWx0KGNoYW5nZS5vbGRSYW5nZS5mcm9tKS5kZWxldGVkQWZ0ZXIgJiZcbiAgICAgICAgICBuZXh0VHJhbnNhY3Rpb24ubWFwcGluZy5tYXBSZXN1bHQoY2hhbmdlLm9sZFJhbmdlLnRvKS5kZWxldGVkQmVmb3JlXG4gICAgICAgICkge1xuICAgICAgICAgIG5leHRUcmFuc2FjdGlvbi5iZWZvcmUubm9kZXNCZXR3ZWVuKFxuICAgICAgICAgICAgY2hhbmdlLm9sZFJhbmdlLmZyb20sXG4gICAgICAgICAgICBjaGFuZ2Uub2xkUmFuZ2UudG8sXG4gICAgICAgICAgICAobm9kZSwgZnJvbSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB0byA9IGZyb20gKyBub2RlLm5vZGVTaXplIC0gMlxuICAgICAgICAgICAgICBjb25zdCBpc0Z1bGx5V2l0aGluUmFuZ2UgPSBjaGFuZ2Uub2xkUmFuZ2UuZnJvbSA8PSBmcm9tICYmIHRvIDw9IGNoYW5nZS5vbGRSYW5nZS50b1xuXG4gICAgICAgICAgICAgIHRoaXMuZWRpdG9yLmVtaXQoJ2RlbGV0ZScsIHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnbm9kZScsXG4gICAgICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgICAgICBmcm9tLFxuICAgICAgICAgICAgICAgIHRvLFxuICAgICAgICAgICAgICAgIG5ld0Zyb206IG5leHRUcmFuc2FjdGlvbi5tYXBwaW5nLm1hcChmcm9tKSxcbiAgICAgICAgICAgICAgICBuZXdUbzogbmV4dFRyYW5zYWN0aW9uLm1hcHBpbmcubWFwKHRvKSxcbiAgICAgICAgICAgICAgICBkZWxldGVkUmFuZ2U6IGNoYW5nZS5vbGRSYW5nZSxcbiAgICAgICAgICAgICAgICBuZXdSYW5nZTogY2hhbmdlLm5ld1JhbmdlLFxuICAgICAgICAgICAgICAgIHBhcnRpYWw6ICFpc0Z1bGx5V2l0aGluUmFuZ2UsXG4gICAgICAgICAgICAgICAgZWRpdG9yOiB0aGlzLmVkaXRvcixcbiAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbixcbiAgICAgICAgICAgICAgICBjb21iaW5lZFRyYW5zZm9ybTogbmV4dFRyYW5zYWN0aW9uLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgIH0pXG5cbiAgICAgIGNvbnN0IG1hcHBpbmcgPSBuZXh0VHJhbnNhY3Rpb24ubWFwcGluZ1xuICAgICAgbmV4dFRyYW5zYWN0aW9uLnN0ZXBzLmZvckVhY2goKHN0ZXAsIGluZGV4KSA9PiB7XG4gICAgICAgIGlmIChzdGVwIGluc3RhbmNlb2YgUmVtb3ZlTWFya1N0ZXApIHtcbiAgICAgICAgICBjb25zdCBuZXdTdGFydCA9IG1hcHBpbmcuc2xpY2UoaW5kZXgpLm1hcChzdGVwLmZyb20sIC0xKVxuICAgICAgICAgIGNvbnN0IG5ld0VuZCA9IG1hcHBpbmcuc2xpY2UoaW5kZXgpLm1hcChzdGVwLnRvKVxuICAgICAgICAgIGNvbnN0IG9sZFN0YXJ0ID0gbWFwcGluZy5pbnZlcnQoKS5tYXAobmV3U3RhcnQsIC0xKVxuICAgICAgICAgIGNvbnN0IG9sZEVuZCA9IG1hcHBpbmcuaW52ZXJ0KCkubWFwKG5ld0VuZClcblxuICAgICAgICAgIGNvbnN0IGZvdW5kQmVmb3JlTWFyayA9XG4gICAgICAgICAgICBuZXdTdGFydCA+IDBcbiAgICAgICAgICAgICAgPyBuZXh0VHJhbnNhY3Rpb24uZG9jLm5vZGVBdChuZXdTdGFydCAtIDEpPy5tYXJrcy5zb21lKG1hcmsgPT4gbWFyay5lcShzdGVwLm1hcmspKVxuICAgICAgICAgICAgICA6IGZhbHNlXG4gICAgICAgICAgY29uc3QgZm91bmRBZnRlck1hcmsgPSBuZXh0VHJhbnNhY3Rpb24uZG9jXG4gICAgICAgICAgICAubm9kZUF0KG5ld0VuZClcbiAgICAgICAgICAgID8ubWFya3Muc29tZShtYXJrID0+IG1hcmsuZXEoc3RlcC5tYXJrKSlcblxuICAgICAgICAgIHRoaXMuZWRpdG9yLmVtaXQoJ2RlbGV0ZScsIHtcbiAgICAgICAgICAgIHR5cGU6ICdtYXJrJyxcbiAgICAgICAgICAgIG1hcms6IHN0ZXAubWFyayxcbiAgICAgICAgICAgIGZyb206IHN0ZXAuZnJvbSxcbiAgICAgICAgICAgIHRvOiBzdGVwLnRvLFxuICAgICAgICAgICAgZGVsZXRlZFJhbmdlOiB7XG4gICAgICAgICAgICAgIGZyb206IG9sZFN0YXJ0LFxuICAgICAgICAgICAgICB0bzogb2xkRW5kLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG5ld1JhbmdlOiB7XG4gICAgICAgICAgICAgIGZyb206IG5ld1N0YXJ0LFxuICAgICAgICAgICAgICB0bzogbmV3RW5kLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHBhcnRpYWw6IEJvb2xlYW4oZm91bmRBZnRlck1hcmsgfHwgZm91bmRCZWZvcmVNYXJrKSxcbiAgICAgICAgICAgIGVkaXRvcjogdGhpcy5lZGl0b3IsXG4gICAgICAgICAgICB0cmFuc2FjdGlvbixcbiAgICAgICAgICAgIGNvbWJpbmVkVHJhbnNmb3JtOiBuZXh0VHJhbnNhY3Rpb24sXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5lZGl0b3Iub3B0aW9ucy5jb3JlRXh0ZW5zaW9uT3B0aW9ucz8uZGVsZXRlPy5hc3luYyA/PyB0cnVlKSB7XG4gICAgICBzZXRUaW1lb3V0KGNhbGxiYWNrLCAwKVxuICAgIH0gZWxzZSB7XG4gICAgICBjYWxsYmFjaygpXG4gICAgfVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBQbHVnaW4sIFBsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJy4uL0V4dGVuc2lvbi5qcydcblxuZXhwb3J0IGNvbnN0IERyb3AgPSBFeHRlbnNpb24uY3JlYXRlKHtcbiAgbmFtZTogJ2Ryb3AnLFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleSgndGlwdGFwRHJvcCcpLFxuXG4gICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgaGFuZGxlRHJvcDogKF8sIGUsIHNsaWNlLCBtb3ZlZCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lZGl0b3IuZW1pdCgnZHJvcCcsIHtcbiAgICAgICAgICAgICAgZWRpdG9yOiB0aGlzLmVkaXRvcixcbiAgICAgICAgICAgICAgZXZlbnQ6IGUsXG4gICAgICAgICAgICAgIHNsaWNlLFxuICAgICAgICAgICAgICBtb3ZlZCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5cbmV4cG9ydCBjb25zdCBFZGl0YWJsZSA9IEV4dGVuc2lvbi5jcmVhdGUoe1xuICBuYW1lOiAnZWRpdGFibGUnLFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleSgnZWRpdGFibGUnKSxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICBlZGl0YWJsZTogKCkgPT4gdGhpcy5lZGl0b3Iub3B0aW9ucy5lZGl0YWJsZSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5cbmV4cG9ydCBjb25zdCBmb2N1c0V2ZW50c1BsdWdpbktleSA9IG5ldyBQbHVnaW5LZXkoJ2ZvY3VzRXZlbnRzJylcblxuZXhwb3J0IGNvbnN0IEZvY3VzRXZlbnRzID0gRXh0ZW5zaW9uLmNyZWF0ZSh7XG4gIG5hbWU6ICdmb2N1c0V2ZW50cycsXG5cbiAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuICAgIGNvbnN0IHsgZWRpdG9yIH0gPSB0aGlzXG5cbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogZm9jdXNFdmVudHNQbHVnaW5LZXksXG4gICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgaGFuZGxlRE9NRXZlbnRzOiB7XG4gICAgICAgICAgICBmb2N1czogKHZpZXcsIGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICAgICAgICBlZGl0b3IuaXNGb2N1c2VkID0gdHJ1ZVxuXG4gICAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gZWRpdG9yLnN0YXRlLnRyXG4gICAgICAgICAgICAgICAgLnNldE1ldGEoJ2ZvY3VzJywgeyBldmVudCB9KVxuICAgICAgICAgICAgICAgIC5zZXRNZXRhKCdhZGRUb0hpc3RvcnknLCBmYWxzZSlcblxuICAgICAgICAgICAgICB2aWV3LmRpc3BhdGNoKHRyYW5zYWN0aW9uKVxuXG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJsdXI6ICh2aWV3LCBldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgZWRpdG9yLmlzRm9jdXNlZCA9IGZhbHNlXG5cbiAgICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBlZGl0b3Iuc3RhdGUudHJcbiAgICAgICAgICAgICAgICAuc2V0TWV0YSgnYmx1cicsIHsgZXZlbnQgfSlcbiAgICAgICAgICAgICAgICAuc2V0TWV0YSgnYWRkVG9IaXN0b3J5JywgZmFsc2UpXG5cbiAgICAgICAgICAgICAgdmlldy5kaXNwYXRjaCh0cmFuc2FjdGlvbilcblxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXksIFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IENvbW1hbmRNYW5hZ2VyIH0gZnJvbSAnLi4vQ29tbWFuZE1hbmFnZXIuanMnXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5pbXBvcnQgeyBjcmVhdGVDaGFpbmFibGVTdGF0ZSB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlQ2hhaW5hYmxlU3RhdGUuanMnXG5pbXBvcnQgeyBpc05vZGVFbXB0eSB9IGZyb20gJy4uL2hlbHBlcnMvaXNOb2RlRW1wdHkuanMnXG5pbXBvcnQgeyBpc2lPUyB9IGZyb20gJy4uL3V0aWxpdGllcy9pc2lPUy5qcydcbmltcG9ydCB7IGlzTWFjT1MgfSBmcm9tICcuLi91dGlsaXRpZXMvaXNNYWNPUy5qcydcblxuZXhwb3J0IGNvbnN0IEtleW1hcCA9IEV4dGVuc2lvbi5jcmVhdGUoe1xuICBuYW1lOiAna2V5bWFwJyxcblxuICBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICBjb25zdCBoYW5kbGVCYWNrc3BhY2UgPSAoKSA9PlxuICAgICAgdGhpcy5lZGl0b3IuY29tbWFuZHMuZmlyc3QoKHsgY29tbWFuZHMgfSkgPT4gW1xuICAgICAgICAoKSA9PiBjb21tYW5kcy51bmRvSW5wdXRSdWxlKCksXG5cbiAgICAgICAgLy8gbWF5YmUgY29udmVydCBmaXJzdCB0ZXh0IGJsb2NrIG5vZGUgdG8gZGVmYXVsdCBub2RlXG4gICAgICAgICgpID0+XG4gICAgICAgICAgY29tbWFuZHMuY29tbWFuZCgoeyB0ciB9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IHNlbGVjdGlvbiwgZG9jIH0gPSB0clxuICAgICAgICAgICAgY29uc3QgeyBlbXB0eSwgJGFuY2hvciB9ID0gc2VsZWN0aW9uXG4gICAgICAgICAgICBjb25zdCB7IHBvcywgcGFyZW50IH0gPSAkYW5jaG9yXG4gICAgICAgICAgICBjb25zdCAkcGFyZW50UG9zID1cbiAgICAgICAgICAgICAgJGFuY2hvci5wYXJlbnQuaXNUZXh0YmxvY2sgJiYgcG9zID4gMCA/IHRyLmRvYy5yZXNvbHZlKHBvcyAtIDEpIDogJGFuY2hvclxuICAgICAgICAgICAgY29uc3QgcGFyZW50SXNJc29sYXRpbmcgPSAkcGFyZW50UG9zLnBhcmVudC50eXBlLnNwZWMuaXNvbGF0aW5nXG5cbiAgICAgICAgICAgIGNvbnN0IHBhcmVudFBvcyA9ICRhbmNob3IucG9zIC0gJGFuY2hvci5wYXJlbnRPZmZzZXRcblxuICAgICAgICAgICAgY29uc3QgaXNBdFN0YXJ0ID1cbiAgICAgICAgICAgICAgcGFyZW50SXNJc29sYXRpbmcgJiYgJHBhcmVudFBvcy5wYXJlbnQuY2hpbGRDb3VudCA9PT0gMVxuICAgICAgICAgICAgICAgID8gcGFyZW50UG9zID09PSAkYW5jaG9yLnBvc1xuICAgICAgICAgICAgICAgIDogU2VsZWN0aW9uLmF0U3RhcnQoZG9jKS5mcm9tID09PSBwb3NcblxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAhZW1wdHkgfHxcbiAgICAgICAgICAgICAgIXBhcmVudC50eXBlLmlzVGV4dGJsb2NrIHx8XG4gICAgICAgICAgICAgIHBhcmVudC50ZXh0Q29udGVudC5sZW5ndGggfHxcbiAgICAgICAgICAgICAgIWlzQXRTdGFydCB8fFxuICAgICAgICAgICAgICAoaXNBdFN0YXJ0ICYmICRhbmNob3IucGFyZW50LnR5cGUubmFtZSA9PT0gJ3BhcmFncmFwaCcpIC8vIHByZXZlbnQgY2xlYXJOb2RlcyB3aGVuIG5vIG5vZGVzIHRvIGNsZWFyLCBvdGhlcndpc2UgaGlzdG9yeSBzdGFjayBpcyBhcHBlbmRlZFxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gY29tbWFuZHMuY2xlYXJOb2RlcygpXG4gICAgICAgICAgfSksXG5cbiAgICAgICAgKCkgPT4gY29tbWFuZHMuZGVsZXRlU2VsZWN0aW9uKCksXG4gICAgICAgICgpID0+IGNvbW1hbmRzLmpvaW5CYWNrd2FyZCgpLFxuICAgICAgICAoKSA9PiBjb21tYW5kcy5zZWxlY3ROb2RlQmFja3dhcmQoKSxcbiAgICAgIF0pXG5cbiAgICBjb25zdCBoYW5kbGVEZWxldGUgPSAoKSA9PlxuICAgICAgdGhpcy5lZGl0b3IuY29tbWFuZHMuZmlyc3QoKHsgY29tbWFuZHMgfSkgPT4gW1xuICAgICAgICAoKSA9PiBjb21tYW5kcy5kZWxldGVTZWxlY3Rpb24oKSxcbiAgICAgICAgKCkgPT4gY29tbWFuZHMuZGVsZXRlQ3VycmVudE5vZGUoKSxcbiAgICAgICAgKCkgPT4gY29tbWFuZHMuam9pbkZvcndhcmQoKSxcbiAgICAgICAgKCkgPT4gY29tbWFuZHMuc2VsZWN0Tm9kZUZvcndhcmQoKSxcbiAgICAgIF0pXG5cbiAgICBjb25zdCBoYW5kbGVFbnRlciA9ICgpID0+XG4gICAgICB0aGlzLmVkaXRvci5jb21tYW5kcy5maXJzdCgoeyBjb21tYW5kcyB9KSA9PiBbXG4gICAgICAgICgpID0+IGNvbW1hbmRzLm5ld2xpbmVJbkNvZGUoKSxcbiAgICAgICAgKCkgPT4gY29tbWFuZHMuY3JlYXRlUGFyYWdyYXBoTmVhcigpLFxuICAgICAgICAoKSA9PiBjb21tYW5kcy5saWZ0RW1wdHlCbG9jaygpLFxuICAgICAgICAoKSA9PiBjb21tYW5kcy5zcGxpdEJsb2NrKCksXG4gICAgICBdKVxuXG4gICAgY29uc3QgYmFzZUtleW1hcCA9IHtcbiAgICAgIEVudGVyOiBoYW5kbGVFbnRlcixcbiAgICAgICdNb2QtRW50ZXInOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5leGl0Q29kZSgpLFxuICAgICAgQmFja3NwYWNlOiBoYW5kbGVCYWNrc3BhY2UsXG4gICAgICAnTW9kLUJhY2tzcGFjZSc6IGhhbmRsZUJhY2tzcGFjZSxcbiAgICAgICdTaGlmdC1CYWNrc3BhY2UnOiBoYW5kbGVCYWNrc3BhY2UsXG4gICAgICBEZWxldGU6IGhhbmRsZURlbGV0ZSxcbiAgICAgICdNb2QtRGVsZXRlJzogaGFuZGxlRGVsZXRlLFxuICAgICAgJ01vZC1hJzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMuc2VsZWN0QWxsKCksXG4gICAgfVxuXG4gICAgY29uc3QgcGNLZXltYXAgPSB7XG4gICAgICAuLi5iYXNlS2V5bWFwLFxuICAgIH1cblxuICAgIGNvbnN0IG1hY0tleW1hcCA9IHtcbiAgICAgIC4uLmJhc2VLZXltYXAsXG4gICAgICAnQ3RybC1oJzogaGFuZGxlQmFja3NwYWNlLFxuICAgICAgJ0FsdC1CYWNrc3BhY2UnOiBoYW5kbGVCYWNrc3BhY2UsXG4gICAgICAnQ3RybC1kJzogaGFuZGxlRGVsZXRlLFxuICAgICAgJ0N0cmwtQWx0LUJhY2tzcGFjZSc6IGhhbmRsZURlbGV0ZSxcbiAgICAgICdBbHQtRGVsZXRlJzogaGFuZGxlRGVsZXRlLFxuICAgICAgJ0FsdC1kJzogaGFuZGxlRGVsZXRlLFxuICAgICAgJ0N0cmwtYSc6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnNlbGVjdFRleHRibG9ja1N0YXJ0KCksXG4gICAgICAnQ3RybC1lJzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMuc2VsZWN0VGV4dGJsb2NrRW5kKCksXG4gICAgfVxuXG4gICAgaWYgKGlzaU9TKCkgfHwgaXNNYWNPUygpKSB7XG4gICAgICByZXR1cm4gbWFjS2V5bWFwXG4gICAgfVxuXG4gICAgcmV0dXJuIHBjS2V5bWFwXG4gIH0sXG5cbiAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuICAgIHJldHVybiBbXG4gICAgICAvLyBXaXRoIHRoaXMgcGx1Z2luIHdlIGNoZWNrIGlmIHRoZSB3aG9sZSBkb2N1bWVudCB3YXMgc2VsZWN0ZWQgYW5kIGRlbGV0ZWQuXG4gICAgICAvLyBJbiB0aGlzIGNhc2Ugd2Ugd2lsbCBhZGRpdGlvbmFsbHkgY2FsbCBgY2xlYXJOb2RlcygpYCB0byBjb252ZXJ0IGUuZy4gYSBoZWFkaW5nXG4gICAgICAvLyB0byBhIHBhcmFncmFwaCBpZiBuZWNlc3NhcnkuXG4gICAgICAvLyBUaGlzIGlzIGFuIGFsdGVybmF0aXZlIHRvIFByb3NlTWlycm9yJ3MgYEFsbFNlbGVjdGlvbmAsIHdoaWNoIGRvZXNu4oCZdCB3b3JrIHdlbGxcbiAgICAgIC8vIHdpdGggbWFueSBvdGhlciBjb21tYW5kcy5cbiAgICAgIG5ldyBQbHVnaW4oe1xuICAgICAgICBrZXk6IG5ldyBQbHVnaW5LZXkoJ2NsZWFyRG9jdW1lbnQnKSxcbiAgICAgICAgYXBwZW5kVHJhbnNhY3Rpb246ICh0cmFuc2FjdGlvbnMsIG9sZFN0YXRlLCBuZXdTdGF0ZSkgPT4ge1xuICAgICAgICAgIGlmICh0cmFuc2FjdGlvbnMuc29tZSh0ciA9PiB0ci5nZXRNZXRhKCdjb21wb3NpdGlvbicpKSkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZG9jQ2hhbmdlcyA9XG4gICAgICAgICAgICB0cmFuc2FjdGlvbnMuc29tZSh0cmFuc2FjdGlvbiA9PiB0cmFuc2FjdGlvbi5kb2NDaGFuZ2VkKSAmJlxuICAgICAgICAgICAgIW9sZFN0YXRlLmRvYy5lcShuZXdTdGF0ZS5kb2MpXG5cbiAgICAgICAgICBjb25zdCBpZ25vcmVUciA9IHRyYW5zYWN0aW9ucy5zb21lKHRyYW5zYWN0aW9uID0+XG4gICAgICAgICAgICB0cmFuc2FjdGlvbi5nZXRNZXRhKCdwcmV2ZW50Q2xlYXJEb2N1bWVudCcpLFxuICAgICAgICAgIClcblxuICAgICAgICAgIGlmICghZG9jQ2hhbmdlcyB8fCBpZ25vcmVUcikge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgeyBlbXB0eSwgZnJvbSwgdG8gfSA9IG9sZFN0YXRlLnNlbGVjdGlvblxuICAgICAgICAgIGNvbnN0IGFsbEZyb20gPSBTZWxlY3Rpb24uYXRTdGFydChvbGRTdGF0ZS5kb2MpLmZyb21cbiAgICAgICAgICBjb25zdCBhbGxFbmQgPSBTZWxlY3Rpb24uYXRFbmQob2xkU3RhdGUuZG9jKS50b1xuICAgICAgICAgIGNvbnN0IGFsbFdhc1NlbGVjdGVkID0gZnJvbSA9PT0gYWxsRnJvbSAmJiB0byA9PT0gYWxsRW5kXG5cbiAgICAgICAgICBpZiAoZW1wdHkgfHwgIWFsbFdhc1NlbGVjdGVkKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBpc0VtcHR5ID0gaXNOb2RlRW1wdHkobmV3U3RhdGUuZG9jKVxuXG4gICAgICAgICAgaWYgKCFpc0VtcHR5KSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCB0ciA9IG5ld1N0YXRlLnRyXG4gICAgICAgICAgY29uc3Qgc3RhdGUgPSBjcmVhdGVDaGFpbmFibGVTdGF0ZSh7XG4gICAgICAgICAgICBzdGF0ZTogbmV3U3RhdGUsXG4gICAgICAgICAgICB0cmFuc2FjdGlvbjogdHIsXG4gICAgICAgICAgfSlcbiAgICAgICAgICBjb25zdCB7IGNvbW1hbmRzIH0gPSBuZXcgQ29tbWFuZE1hbmFnZXIoe1xuICAgICAgICAgICAgZWRpdG9yOiB0aGlzLmVkaXRvcixcbiAgICAgICAgICAgIHN0YXRlLFxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICBjb21tYW5kcy5jbGVhck5vZGVzKClcblxuICAgICAgICAgIGlmICghdHIuc3RlcHMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdHJcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5cbmV4cG9ydCBjb25zdCBQYXN0ZSA9IEV4dGVuc2lvbi5jcmVhdGUoe1xuICBuYW1lOiAncGFzdGUnLFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleSgndGlwdGFwUGFzdGUnKSxcblxuICAgICAgICBwcm9wczoge1xuICAgICAgICAgIGhhbmRsZVBhc3RlOiAoX3ZpZXcsIGUsIHNsaWNlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVkaXRvci5lbWl0KCdwYXN0ZScsIHtcbiAgICAgICAgICAgICAgZWRpdG9yOiB0aGlzLmVkaXRvcixcbiAgICAgICAgICAgICAgZXZlbnQ6IGUsXG4gICAgICAgICAgICAgIHNsaWNlLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgXVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBQbHVnaW4sIFBsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJy4uL0V4dGVuc2lvbi5qcydcblxuLyoqXG4gKiBPcHRpb25zIGZvciB0aGUgVGFiaW5kZXggZXh0ZW5zaW9uLlxuICovXG5leHBvcnQgdHlwZSBUYWJpbmRleE9wdGlvbnMgPSB7XG4gIC8qKlxuICAgKiBUaGUgdmFsdWUgZm9yIHRoZSBgdGFiaW5kZXhgIGF0dHJpYnV0ZSBvbiB0aGUgZWRpdG9yIGVsZW1lbnQuXG4gICAqIFdoZW4gdW5kZWZpbmVkLCBlZGl0YWJsZSBlZGl0b3JzIGRlZmF1bHQgdG8gYDBgIGFuZCBub24tZWRpdGFibGUgZWRpdG9ycyBnZXQgbm8gdGFiaW5kZXguXG4gICAqL1xuICB2YWx1ZT86IHN0cmluZ1xufVxuXG4vKipcbiAqIFRoZSBUYWJpbmRleCBleHRlbnNpb24gYWRkcyBhIGNvbmZpZ3VyYWJsZSB0YWJpbmRleCBhdHRyaWJ1dGUgdG8gdGhlIGVkaXRvci5cbiAqXG4gKiBCeSBkZWZhdWx0LCB0aGUgZWRpdG9yIGdldHMgdGFiaW5kZXg9XCIwXCIgd2hlbiBlZGl0YWJsZS4gVGhpcyBjYW4gYmUgY3VzdG9taXplZFxuICogdmlhIGNvcmVFeHRlbnNpb25PcHRpb25zIHRvIHN1cHBvcnQgc3BlY2lmaWMgZm9jdXMgb3JkZXJpbmcgcmVxdWlyZW1lbnRzIGluIGZvcm1zXG4gKiBvciB0byBlbmFibGUgZm9jdXNpbmcgb24gbm9uLWVkaXRhYmxlIGVkaXRvcnMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBuZXcgRWRpdG9yKHtcbiAqICAgY29yZUV4dGVuc2lvbk9wdGlvbnM6IHtcbiAqICAgICB0YWJpbmRleDoge1xuICogICAgICAgdmFsdWU6ICctMScsXG4gKiAgICAgfSxcbiAqICAgfSxcbiAqIH0pXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IFRhYmluZGV4ID0gRXh0ZW5zaW9uLmNyZWF0ZTxUYWJpbmRleE9wdGlvbnM+KHtcbiAgbmFtZTogJ3RhYmluZGV4JyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICB2YWx1ZTogdW5kZWZpbmVkLFxuICAgIH1cbiAgfSxcblxuICBhZGRQcm9zZU1pcnJvclBsdWdpbnMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG5ldyBQbHVnaW4oe1xuICAgICAgICBrZXk6IG5ldyBQbHVnaW5LZXkoJ3RhYmluZGV4JyksXG4gICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgYXR0cmlidXRlczogKCk6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9ID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5lZGl0b3IuaXNFZGl0YWJsZSAmJiB0aGlzLm9wdGlvbnMudmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICByZXR1cm4ge31cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7IHRhYmluZGV4OiB0aGlzLm9wdGlvbnMudmFsdWUgPz8gJzAnIH1cbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgXVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBQbHVnaW4sIFBsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJy4uL0V4dGVuc2lvbi5qcydcbmltcG9ydCB7IHNwbGl0RXh0ZW5zaW9ucyB9IGZyb20gJy4uL2hlbHBlcnMvc3BsaXRFeHRlbnNpb25zLmpzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFRleHREaXJlY3Rpb25PcHRpb25zIHtcbiAgZGlyZWN0aW9uOiAnbHRyJyB8ICdydGwnIHwgJ2F1dG8nIHwgdW5kZWZpbmVkXG59XG5cbi8qKlxuICogVGhlIFRleHREaXJlY3Rpb24gZXh0ZW5zaW9uIGFkZHMgc3VwcG9ydCBmb3Igc2V0dGluZyB0ZXh0IGRpcmVjdGlvbiAoTFRSL1JUTC9hdXRvKVxuICogb24gYWxsIG5vZGVzIGluIHRoZSBlZGl0b3IuXG4gKlxuICogVGhpcyBleHRlbnNpb24gYWRkcyBhIGdsb2JhbCBgZGlyYCBhdHRyaWJ1dGUgdG8gYWxsIG5vZGUgdHlwZXMsIHdoaWNoIGNhbiBiZSB1c2VkXG4gKiB0byBjb250cm9sIGJpZGlyZWN0aW9uYWwgdGV4dCByZW5kZXJpbmcuIFRoZSBkaXJlY3Rpb24gY2FuIGJlIHNldCBnbG9iYWxseSB2aWFcbiAqIGVkaXRvciBvcHRpb25zIG9yIHBlci1ub2RlIHVzaW5nIGNvbW1hbmRzLlxuICovXG5leHBvcnQgY29uc3QgVGV4dERpcmVjdGlvbiA9IEV4dGVuc2lvbi5jcmVhdGU8VGV4dERpcmVjdGlvbk9wdGlvbnM+KHtcbiAgbmFtZTogJ3RleHREaXJlY3Rpb24nLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGRpcmVjdGlvbjogdW5kZWZpbmVkLFxuICAgIH1cbiAgfSxcblxuICBhZGRHbG9iYWxBdHRyaWJ1dGVzKCkge1xuICAgIC8vIE9ubHkgYWRkIHRoZSBkaXIgYXR0cmlidXRlIHRvIG5vZGVzIGlmIHRleHQgZGlyZWN0aW9uIGlzIGNvbmZpZ3VyZWRcbiAgICAvLyBUaGlzIHByZXZlbnRzIG51bGwvdW5kZWZpbmVkIHZhbHVlcyBmcm9tIGFwcGVhcmluZyBpbiBKU09OIGV4cG9ydHNcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5kaXJlY3Rpb24pIHtcbiAgICAgIHJldHVybiBbXVxuICAgIH1cblxuICAgIGNvbnN0IHsgbm9kZUV4dGVuc2lvbnMgfSA9IHNwbGl0RXh0ZW5zaW9ucyh0aGlzLmV4dGVuc2lvbnMpXG5cbiAgICByZXR1cm4gW1xuICAgICAge1xuICAgICAgICB0eXBlczogbm9kZUV4dGVuc2lvbnNcbiAgICAgICAgICAuZmlsdGVyKGV4dGVuc2lvbiA9PiBleHRlbnNpb24ubmFtZSAhPT0gJ3RleHQnKVxuICAgICAgICAgIC5tYXAoZXh0ZW5zaW9uID0+IGV4dGVuc2lvbi5uYW1lKSxcbiAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgIGRpcjoge1xuICAgICAgICAgICAgZGVmYXVsdDogdGhpcy5vcHRpb25zLmRpcmVjdGlvbixcbiAgICAgICAgICAgIHBhcnNlSFRNTDogZWxlbWVudCA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGRpciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkaXInKVxuXG4gICAgICAgICAgICAgIGlmIChkaXIgJiYgKGRpciA9PT0gJ2x0cicgfHwgZGlyID09PSAncnRsJyB8fCBkaXIgPT09ICdhdXRvJykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGlyXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmRpcmVjdGlvblxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbmRlckhUTUw6IGF0dHJpYnV0ZXMgPT4ge1xuICAgICAgICAgICAgICBpZiAoIWF0dHJpYnV0ZXMuZGlyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHt9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGRpcjogYXR0cmlidXRlcy5kaXIsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgXVxuICB9LFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleSgndGV4dERpcmVjdGlvbicpLFxuICAgICAgICBwcm9wczoge1xuICAgICAgICAgIGF0dHJpYnV0ZXM6ICgpOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfSA9PiB7XG4gICAgICAgICAgICBjb25zdCBkaXJlY3Rpb24gPSB0aGlzLm9wdGlvbnMuZGlyZWN0aW9uXG5cbiAgICAgICAgICAgIGlmICghZGlyZWN0aW9uKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7fVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBkaXI6IGRpcmVjdGlvbixcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgXVxuICB9LFxufSlcbiIsICJpbXBvcnQgdHlwZSB7IEZyYWdtZW50LCBOb2RlLCBSZXNvbHZlZFBvcyB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB0eXBlIHsgRWRpdG9yIH0gZnJvbSAnLi9FZGl0b3IuanMnXG5pbXBvcnQgdHlwZSB7IENvbnRlbnQsIFJhbmdlIH0gZnJvbSAnLi90eXBlcy5qcydcblxuZXhwb3J0IGNsYXNzIE5vZGVQb3Mge1xuICBwcml2YXRlIHJlc29sdmVkUG9zOiBSZXNvbHZlZFBvc1xuXG4gIHByaXZhdGUgaXNCbG9jazogYm9vbGVhblxuXG4gIHByaXZhdGUgZWRpdG9yOiBFZGl0b3JcblxuICBwcml2YXRlIGdldCBuYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMubm9kZS50eXBlLm5hbWVcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHBvczogUmVzb2x2ZWRQb3MsIGVkaXRvcjogRWRpdG9yLCBpc0Jsb2NrID0gZmFsc2UsIG5vZGU6IE5vZGUgfCBudWxsID0gbnVsbCkge1xuICAgIHRoaXMuaXNCbG9jayA9IGlzQmxvY2tcbiAgICB0aGlzLnJlc29sdmVkUG9zID0gcG9zXG4gICAgdGhpcy5lZGl0b3IgPSBlZGl0b3JcbiAgICB0aGlzLmN1cnJlbnROb2RlID0gbm9kZVxuICB9XG5cbiAgcHJpdmF0ZSBjdXJyZW50Tm9kZTogTm9kZSB8IG51bGwgPSBudWxsXG5cbiAgZ2V0IG5vZGUoKTogTm9kZSB7XG4gICAgcmV0dXJuIHRoaXMuY3VycmVudE5vZGUgfHwgdGhpcy5yZXNvbHZlZFBvcy5ub2RlKClcbiAgfVxuXG4gIGdldCBlbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5lZGl0b3Iudmlldy5kb21BdFBvcyh0aGlzLnBvcykubm9kZSBhcyBIVE1MRWxlbWVudFxuICB9XG5cbiAgcHVibGljIGFjdHVhbERlcHRoOiBudW1iZXIgfCBudWxsID0gbnVsbFxuXG4gIGdldCBkZXB0aCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmFjdHVhbERlcHRoID8/IHRoaXMucmVzb2x2ZWRQb3MuZGVwdGhcbiAgfVxuXG4gIGdldCBwb3MoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlZFBvcy5wb3NcbiAgfVxuXG4gIGdldCBjb250ZW50KCk6IEZyYWdtZW50IHtcbiAgICByZXR1cm4gdGhpcy5ub2RlLmNvbnRlbnRcbiAgfVxuXG4gIHNldCBjb250ZW50KGNvbnRlbnQ6IENvbnRlbnQpIHtcbiAgICBsZXQgZnJvbSA9IHRoaXMuZnJvbVxuICAgIGxldCB0byA9IHRoaXMudG9cblxuICAgIGlmICh0aGlzLmlzQmxvY2spIHtcbiAgICAgIGlmICh0aGlzLmNvbnRlbnQuc2l6ZSA9PT0gMCkge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgIGBZb3UgY2Fu4oCZdCBzZXQgY29udGVudCBvbiBhIGJsb2NrIG5vZGUuIFRyaWVkIHRvIHNldCBjb250ZW50IG9uICR7dGhpcy5uYW1lfSBhdCAke3RoaXMucG9zfWAsXG4gICAgICAgIClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGZyb20gPSB0aGlzLmZyb20gKyAxXG4gICAgICB0byA9IHRoaXMudG8gLSAxXG4gICAgfVxuXG4gICAgdGhpcy5lZGl0b3IuY29tbWFuZHMuaW5zZXJ0Q29udGVudEF0KHsgZnJvbSwgdG8gfSwgY29udGVudClcbiAgfVxuXG4gIGdldCBhdHRyaWJ1dGVzKCk6IHsgW2tleTogc3RyaW5nXTogYW55IH0ge1xuICAgIHJldHVybiB0aGlzLm5vZGUuYXR0cnNcbiAgfVxuXG4gIGdldCB0ZXh0Q29udGVudCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm5vZGUudGV4dENvbnRlbnRcbiAgfVxuXG4gIGdldCBzaXplKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMubm9kZS5ub2RlU2l6ZVxuICB9XG5cbiAgZ2V0IGZyb20oKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5pc0Jsb2NrKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3NcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlZFBvcy5zdGFydCh0aGlzLnJlc29sdmVkUG9zLmRlcHRoKVxuICB9XG5cbiAgZ2V0IHJhbmdlKCk6IFJhbmdlIHtcbiAgICByZXR1cm4ge1xuICAgICAgZnJvbTogdGhpcy5mcm9tLFxuICAgICAgdG86IHRoaXMudG8sXG4gICAgfVxuICB9XG5cbiAgZ2V0IHRvKCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuaXNCbG9jaykge1xuICAgICAgcmV0dXJuIHRoaXMucG9zICsgdGhpcy5zaXplXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZWRQb3MuZW5kKHRoaXMucmVzb2x2ZWRQb3MuZGVwdGgpICsgKHRoaXMubm9kZS5pc1RleHQgPyAwIDogMSlcbiAgfVxuXG4gIGdldCBwYXJlbnQoKTogTm9kZVBvcyB8IG51bGwge1xuICAgIGlmICh0aGlzLmRlcHRoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIGNvbnN0IHBhcmVudFBvcyA9IHRoaXMucmVzb2x2ZWRQb3Muc3RhcnQodGhpcy5yZXNvbHZlZFBvcy5kZXB0aCAtIDEpXG4gICAgY29uc3QgJHBvcyA9IHRoaXMucmVzb2x2ZWRQb3MuZG9jLnJlc29sdmUocGFyZW50UG9zKVxuXG4gICAgcmV0dXJuIG5ldyBOb2RlUG9zKCRwb3MsIHRoaXMuZWRpdG9yKVxuICB9XG5cbiAgZ2V0IGJlZm9yZSgpOiBOb2RlUG9zIHwgbnVsbCB7XG4gICAgbGV0ICRwb3MgPSB0aGlzLnJlc29sdmVkUG9zLmRvYy5yZXNvbHZlKHRoaXMuZnJvbSAtICh0aGlzLmlzQmxvY2sgPyAxIDogMikpXG5cbiAgICBpZiAoJHBvcy5kZXB0aCAhPT0gdGhpcy5kZXB0aCkge1xuICAgICAgJHBvcyA9IHRoaXMucmVzb2x2ZWRQb3MuZG9jLnJlc29sdmUodGhpcy5mcm9tIC0gMylcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE5vZGVQb3MoJHBvcywgdGhpcy5lZGl0b3IpXG4gIH1cblxuICBnZXQgYWZ0ZXIoKTogTm9kZVBvcyB8IG51bGwge1xuICAgIGxldCAkcG9zID0gdGhpcy5yZXNvbHZlZFBvcy5kb2MucmVzb2x2ZSh0aGlzLnRvICsgKHRoaXMuaXNCbG9jayA/IDIgOiAxKSlcblxuICAgIGlmICgkcG9zLmRlcHRoICE9PSB0aGlzLmRlcHRoKSB7XG4gICAgICAkcG9zID0gdGhpcy5yZXNvbHZlZFBvcy5kb2MucmVzb2x2ZSh0aGlzLnRvICsgMylcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE5vZGVQb3MoJHBvcywgdGhpcy5lZGl0b3IpXG4gIH1cblxuICBnZXQgY2hpbGRyZW4oKTogTm9kZVBvc1tdIHtcbiAgICBjb25zdCBjaGlsZHJlbjogTm9kZVBvc1tdID0gW11cblxuICAgIHRoaXMubm9kZS5jb250ZW50LmZvckVhY2goKG5vZGUsIG9mZnNldCkgPT4ge1xuICAgICAgY29uc3QgaXNCbG9jayA9IG5vZGUuaXNCbG9jayAmJiAhbm9kZS5pc1RleHRibG9ja1xuICAgICAgY29uc3QgaXNOb25UZXh0QXRvbSA9IG5vZGUuaXNBdG9tICYmICFub2RlLmlzVGV4dFxuICAgICAgY29uc3QgaXNJbmxpbmUgPSBub2RlLmlzSW5saW5lXG5cbiAgICAgIGNvbnN0IHRhcmdldFBvcyA9IHRoaXMucG9zICsgb2Zmc2V0ICsgKGlzTm9uVGV4dEF0b20gPyAwIDogMSlcblxuICAgICAgLy8gQ2hlY2sgaWYgdGFyZ2V0UG9zIGlzIHdpdGhpbiB2YWxpZCBkb2N1bWVudCByYW5nZVxuICAgICAgaWYgKHRhcmdldFBvcyA8IDAgfHwgdGFyZ2V0UG9zID4gdGhpcy5yZXNvbHZlZFBvcy5kb2Mubm9kZVNpemUgLSAyKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBjb25zdCAkcG9zID0gdGhpcy5yZXNvbHZlZFBvcy5kb2MucmVzb2x2ZSh0YXJnZXRQb3MpXG5cbiAgICAgIC8vIE9ubHkgYXBwbHkgZGVwdGggY2hlY2sgZm9yIG5vbi1ibG9jaywgbm9uLWlubGluZSBub2RlcyAoaS5lLiwgdGV4dGJsb2NrcylcbiAgICAgIC8vIElubGluZSBub2RlcyBzaG91bGQgYWx3YXlzIGJlIGluY2x1ZGVkIGFzIGNoaWxkcmVuIHNpbmNlIHdlJ3JlIGl0ZXJhdGluZ1xuICAgICAgLy8gb3ZlciBkaXJlY3QgY2hpbGRyZW4gdmlhIHRoaXMubm9kZS5jb250ZW50XG4gICAgICBpZiAoIWlzQmxvY2sgJiYgIWlzSW5saW5lICYmICRwb3MuZGVwdGggPD0gdGhpcy5kZXB0aCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgLy8gUGFzcyB0aGUgbm9kZSBmb3IgYm90aCBibG9jayBhbmQgaW5saW5lIG5vZGVzIHRvIGVuc3VyZSBjb3JyZWN0IG5vZGUgcmVmZXJlbmNlXG4gICAgICBjb25zdCBjaGlsZE5vZGVQb3MgPSBuZXcgTm9kZVBvcyhcbiAgICAgICAgJHBvcyxcbiAgICAgICAgdGhpcy5lZGl0b3IsXG4gICAgICAgIGlzQmxvY2ssXG4gICAgICAgIGlzQmxvY2sgfHwgaXNJbmxpbmUgPyBub2RlIDogbnVsbCxcbiAgICAgIClcblxuICAgICAgaWYgKGlzQmxvY2spIHtcbiAgICAgICAgY2hpbGROb2RlUG9zLmFjdHVhbERlcHRoID0gdGhpcy5kZXB0aCArIDFcbiAgICAgIH1cblxuICAgICAgY2hpbGRyZW4ucHVzaChjaGlsZE5vZGVQb3MpXG4gICAgfSlcblxuICAgIHJldHVybiBjaGlsZHJlblxuICB9XG5cbiAgZ2V0IGZpcnN0Q2hpbGQoKTogTm9kZVBvcyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNoaWxkcmVuWzBdIHx8IG51bGxcbiAgfVxuXG4gIGdldCBsYXN0Q2hpbGQoKTogTm9kZVBvcyB8IG51bGwge1xuICAgIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlblxuXG4gICAgcmV0dXJuIGNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aCAtIDFdIHx8IG51bGxcbiAgfVxuXG4gIGNsb3Nlc3Qoc2VsZWN0b3I6IHN0cmluZywgYXR0cmlidXRlczogeyBba2V5OiBzdHJpbmddOiBhbnkgfSA9IHt9KTogTm9kZVBvcyB8IG51bGwge1xuICAgIGxldCBub2RlOiBOb2RlUG9zIHwgbnVsbCA9IG51bGxcbiAgICBsZXQgY3VycmVudE5vZGUgPSB0aGlzLnBhcmVudFxuXG4gICAgd2hpbGUgKGN1cnJlbnROb2RlICYmICFub2RlKSB7XG4gICAgICBpZiAoY3VycmVudE5vZGUubm9kZS50eXBlLm5hbWUgPT09IHNlbGVjdG9yKSB7XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhhdHRyaWJ1dGVzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3Qgbm9kZUF0dHJpYnV0ZXMgPSBjdXJyZW50Tm9kZS5ub2RlLmF0dHJzXG4gICAgICAgICAgY29uc3QgYXR0cktleXMgPSBPYmplY3Qua2V5cyhhdHRyaWJ1dGVzKVxuXG4gICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGF0dHJLZXlzLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gYXR0cktleXNbaW5kZXhdXG5cbiAgICAgICAgICAgIGlmIChub2RlQXR0cmlidXRlc1trZXldICE9PSBhdHRyaWJ1dGVzW2tleV0pIHtcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbm9kZSA9IGN1cnJlbnROb2RlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5wYXJlbnRcbiAgICB9XG5cbiAgICByZXR1cm4gbm9kZVxuICB9XG5cbiAgcXVlcnlTZWxlY3RvcihzZWxlY3Rvcjogc3RyaW5nLCBhdHRyaWJ1dGVzOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge30pOiBOb2RlUG9zIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvciwgYXR0cmlidXRlcywgdHJ1ZSlbMF0gfHwgbnVsbFxuICB9XG5cbiAgcXVlcnlTZWxlY3RvckFsbChcbiAgICBzZWxlY3Rvcjogc3RyaW5nLFxuICAgIGF0dHJpYnV0ZXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gPSB7fSxcbiAgICBmaXJzdEl0ZW1Pbmx5ID0gZmFsc2UsXG4gICk6IE5vZGVQb3NbXSB7XG4gICAgbGV0IG5vZGVzOiBOb2RlUG9zW10gPSBbXVxuXG4gICAgaWYgKCF0aGlzLmNoaWxkcmVuIHx8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbm9kZXNcbiAgICB9XG4gICAgY29uc3QgYXR0cktleXMgPSBPYmplY3Qua2V5cyhhdHRyaWJ1dGVzKVxuXG4gICAgLyoqXG4gICAgICogRmluZHMgYWxsIGNoaWxkcmVuIHJlY3Vyc2l2ZWx5IHRoYXQgbWF0Y2ggdGhlIHNlbGVjdG9yIGFuZCBhdHRyaWJ1dGVzXG4gICAgICogSWYgZmlyc3RJdGVtT25seSBpcyB0cnVlLCBpdCB3aWxsIHJldHVybiB0aGUgZmlyc3QgaXRlbSBmb3VuZFxuICAgICAqL1xuICAgIHRoaXMuY2hpbGRyZW4uZm9yRWFjaChjaGlsZFBvcyA9PiB7XG4gICAgICAvLyBJZiB3ZSBhbHJlYWR5IGZvdW5kIGEgbm9kZSBhbmQgd2Ugb25seSB3YW50IHRoZSBmaXJzdCBpdGVtLCB3ZSBkb250IG5lZWQgdG8ga2VlcCBnb2luZ1xuICAgICAgaWYgKGZpcnN0SXRlbU9ubHkgJiYgbm9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKGNoaWxkUG9zLm5vZGUudHlwZS5uYW1lID09PSBzZWxlY3Rvcikge1xuICAgICAgICBjb25zdCBkb2VzQWxsQXR0cmlidXRlc01hdGNoID0gYXR0cktleXMuZXZlcnkoXG4gICAgICAgICAga2V5ID0+IGF0dHJpYnV0ZXNba2V5XSA9PT0gY2hpbGRQb3Mubm9kZS5hdHRyc1trZXldLFxuICAgICAgICApXG5cbiAgICAgICAgaWYgKGRvZXNBbGxBdHRyaWJ1dGVzTWF0Y2gpIHtcbiAgICAgICAgICBub2Rlcy5wdXNoKGNoaWxkUG9zKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIElmIHdlIGFscmVhZHkgZm91bmQgYSBub2RlIGFuZCB3ZSBvbmx5IHdhbnQgdGhlIGZpcnN0IGl0ZW0sIHdlIGNhbiBzdG9wIGhlcmUgYW5kIHNraXAgdGhlIHJlY3Vyc2lvblxuICAgICAgaWYgKGZpcnN0SXRlbU9ubHkgJiYgbm9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgbm9kZXMgPSBub2Rlcy5jb25jYXQoY2hpbGRQb3MucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvciwgYXR0cmlidXRlcywgZmlyc3RJdGVtT25seSkpXG4gICAgfSlcblxuICAgIHJldHVybiBub2Rlc1xuICB9XG5cbiAgc2V0QXR0cmlidXRlKGF0dHJpYnV0ZXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0pIHtcbiAgICBjb25zdCB7IHRyIH0gPSB0aGlzLmVkaXRvci5zdGF0ZVxuXG4gICAgdHIuc2V0Tm9kZU1hcmt1cCh0aGlzLmZyb20sIHVuZGVmaW5lZCwge1xuICAgICAgLi4udGhpcy5ub2RlLmF0dHJzLFxuICAgICAgLi4uYXR0cmlidXRlcyxcbiAgICB9KVxuXG4gICAgdGhpcy5lZGl0b3Iudmlldy5kaXNwYXRjaCh0cilcbiAgfVxufVxuIiwgImV4cG9ydCBjb25zdCBzdHlsZSA9IGAuUHJvc2VNaXJyb3Ige1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi5Qcm9zZU1pcnJvciB7XG4gIHdvcmQtd3JhcDogYnJlYWstd29yZDtcbiAgd2hpdGUtc3BhY2U6IHByZS13cmFwO1xuICB3aGl0ZS1zcGFjZTogYnJlYWstc3BhY2VzO1xuICAtd2Via2l0LWZvbnQtdmFyaWFudC1saWdhdHVyZXM6IG5vbmU7XG4gIGZvbnQtdmFyaWFudC1saWdhdHVyZXM6IG5vbmU7XG4gIGZvbnQtZmVhdHVyZS1zZXR0aW5nczogXCJsaWdhXCIgMDsgLyogdGhlIGFib3ZlIGRvZXNuJ3Qgc2VlbSB0byB3b3JrIGluIEVkZ2UgKi9cbn1cblxuLlByb3NlTWlycm9yIFtjb250ZW50ZWRpdGFibGU9XCJmYWxzZVwiXSB7XG4gIHdoaXRlLXNwYWNlOiBub3JtYWw7XG59XG5cbi5Qcm9zZU1pcnJvciBbY29udGVudGVkaXRhYmxlPVwiZmFsc2VcIl0gW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0ge1xuICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XG59XG5cbi5Qcm9zZU1pcnJvciBwcmUge1xuICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XG59XG5cbmltZy5Qcm9zZU1pcnJvci1zZXBhcmF0b3Ige1xuICBkaXNwbGF5OiBpbmxpbmUgIWltcG9ydGFudDtcbiAgYm9yZGVyOiBub25lICFpbXBvcnRhbnQ7XG4gIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICB3aWR0aDogMCAhaW1wb3J0YW50O1xuICBoZWlnaHQ6IDAgIWltcG9ydGFudDtcbn1cblxuLlByb3NlTWlycm9yLWdhcGN1cnNvciB7XG4gIGRpc3BsYXk6IG5vbmU7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIG1hcmdpbjogMDtcbn1cblxuLlByb3NlTWlycm9yLWdhcGN1cnNvcjphZnRlciB7XG4gIGNvbnRlbnQ6IFwiXCI7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogLTJweDtcbiAgd2lkdGg6IDIwcHg7XG4gIGJvcmRlci10b3A6IDFweCBzb2xpZCBibGFjaztcbiAgYW5pbWF0aW9uOiBQcm9zZU1pcnJvci1jdXJzb3ItYmxpbmsgMS4xcyBzdGVwcygyLCBzdGFydCkgaW5maW5pdGU7XG59XG5cbkBrZXlmcmFtZXMgUHJvc2VNaXJyb3ItY3Vyc29yLWJsaW5rIHtcbiAgdG8ge1xuICAgIHZpc2liaWxpdHk6IGhpZGRlbjtcbiAgfVxufVxuXG4uUHJvc2VNaXJyb3ItaGlkZXNlbGVjdGlvbiAqOjpzZWxlY3Rpb24ge1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbn1cblxuLlByb3NlTWlycm9yLWhpZGVzZWxlY3Rpb24gKjo6LW1vei1zZWxlY3Rpb24ge1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbn1cblxuLlByb3NlTWlycm9yLWhpZGVzZWxlY3Rpb24gKiB7XG4gIGNhcmV0LWNvbG9yOiB0cmFuc3BhcmVudDtcbn1cblxuLlByb3NlTWlycm9yLWZvY3VzZWQgLlByb3NlTWlycm9yLWdhcGN1cnNvciB7XG4gIGRpc3BsYXk6IGJsb2NrO1xufWBcbiIsICJleHBvcnQgZnVuY3Rpb24gY3JlYXRlU3R5bGVUYWcoc3R5bGU6IHN0cmluZywgbm9uY2U/OiBzdHJpbmcsIHN1ZmZpeD86IHN0cmluZyk6IEhUTUxTdHlsZUVsZW1lbnQge1xuICBjb25zdCB0aXB0YXBTdHlsZVRhZyA9IDxIVE1MU3R5bGVFbGVtZW50PihcbiAgICBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBzdHlsZVtkYXRhLXRpcHRhcC1zdHlsZSR7c3VmZml4ID8gYC0ke3N1ZmZpeH1gIDogJyd9XWApXG4gIClcblxuICBpZiAodGlwdGFwU3R5bGVUYWcgIT09IG51bGwpIHtcbiAgICByZXR1cm4gdGlwdGFwU3R5bGVUYWdcbiAgfVxuXG4gIGNvbnN0IHN0eWxlTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJylcblxuICBpZiAobm9uY2UpIHtcbiAgICBzdHlsZU5vZGUuc2V0QXR0cmlidXRlKCdub25jZScsIG5vbmNlKVxuICB9XG5cbiAgc3R5bGVOb2RlLnNldEF0dHJpYnV0ZShgZGF0YS10aXB0YXAtc3R5bGUke3N1ZmZpeCA/IGAtJHtzdWZmaXh9YCA6ICcnfWAsICcnKVxuICBzdHlsZU5vZGUuaW5uZXJIVE1MID0gc3R5bGVcbiAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXS5hcHBlbmRDaGlsZChzdHlsZU5vZGUpXG5cbiAgcmV0dXJuIHN0eWxlTm9kZVxufVxuIiwgImltcG9ydCB0eXBlIHsgTWFya1R5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXRNYXJrc0JldHdlZW4gfSBmcm9tICcuLi9oZWxwZXJzL2dldE1hcmtzQmV0d2Vlbi5qcydcbmltcG9ydCB0eXBlIHsgSW5wdXRSdWxlRmluZGVyIH0gZnJvbSAnLi4vSW5wdXRSdWxlLmpzJ1xuaW1wb3J0IHsgSW5wdXRSdWxlIH0gZnJvbSAnLi4vSW5wdXRSdWxlLmpzJ1xuaW1wb3J0IHR5cGUgeyBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXkgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGNhbGxPclJldHVybiB9IGZyb20gJy4uL3V0aWxpdGllcy9jYWxsT3JSZXR1cm4uanMnXG5cbi8qKlxuICogQnVpbGQgYW4gaW5wdXQgcnVsZSB0aGF0IGFkZHMgYSBtYXJrIHdoZW4gdGhlXG4gKiBtYXRjaGVkIHRleHQgaXMgdHlwZWQgaW50byBpdC5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2V4dGVuc2lvbnMvY3VzdG9tLWV4dGVuc2lvbnMvZXh0ZW5kLWV4aXN0aW5nI2lucHV0LXJ1bGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrSW5wdXRSdWxlKGNvbmZpZzoge1xuICBmaW5kOiBJbnB1dFJ1bGVGaW5kZXJcbiAgdHlwZTogTWFya1R5cGVcbiAgdW5kb2FibGU/OiBib29sZWFuXG4gIGdldEF0dHJpYnV0ZXM/OlxuICAgIHwgUmVjb3JkPHN0cmluZywgYW55PlxuICAgIHwgKChtYXRjaDogRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5KSA9PiBSZWNvcmQ8c3RyaW5nLCBhbnk+KVxuICAgIHwgZmFsc2VcbiAgICB8IG51bGxcbn0pIHtcbiAgcmV0dXJuIG5ldyBJbnB1dFJ1bGUoe1xuICAgIGZpbmQ6IGNvbmZpZy5maW5kLFxuICAgIGhhbmRsZXI6ICh7IHN0YXRlLCByYW5nZSwgbWF0Y2ggfSkgPT4ge1xuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IGNhbGxPclJldHVybihjb25maWcuZ2V0QXR0cmlidXRlcywgdW5kZWZpbmVkLCBtYXRjaClcblxuICAgICAgaWYgKGF0dHJpYnV0ZXMgPT09IGZhbHNlIHx8IGF0dHJpYnV0ZXMgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyB0ciB9ID0gc3RhdGVcbiAgICAgIGNvbnN0IGNhcHR1cmVHcm91cCA9IG1hdGNoW21hdGNoLmxlbmd0aCAtIDFdXG4gICAgICBjb25zdCBmdWxsTWF0Y2ggPSBtYXRjaFswXVxuXG4gICAgICBpZiAoY2FwdHVyZUdyb3VwKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0U3BhY2VzID0gZnVsbE1hdGNoLnNlYXJjaCgvXFxTLylcbiAgICAgICAgY29uc3QgdGV4dFN0YXJ0ID0gcmFuZ2UuZnJvbSArIGZ1bGxNYXRjaC5pbmRleE9mKGNhcHR1cmVHcm91cClcbiAgICAgICAgY29uc3QgdGV4dEVuZCA9IHRleHRTdGFydCArIGNhcHR1cmVHcm91cC5sZW5ndGhcblxuICAgICAgICBjb25zdCBleGNsdWRlZE1hcmtzID0gZ2V0TWFya3NCZXR3ZWVuKHJhbmdlLmZyb20sIHJhbmdlLnRvLCBzdGF0ZS5kb2MpXG4gICAgICAgICAgLmZpbHRlcihpdGVtID0+IHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbnN0IGV4Y2x1ZGVkID0gaXRlbS5tYXJrLnR5cGUuZXhjbHVkZWQgYXMgTWFya1R5cGVbXVxuXG4gICAgICAgICAgICByZXR1cm4gZXhjbHVkZWQuZmluZCh0eXBlID0+IHR5cGUgPT09IGNvbmZpZy50eXBlICYmIHR5cGUgIT09IGl0ZW0ubWFyay50eXBlKVxuICAgICAgICAgIH0pXG4gICAgICAgICAgLmZpbHRlcihpdGVtID0+IGl0ZW0udG8gPiB0ZXh0U3RhcnQpXG5cbiAgICAgICAgaWYgKGV4Y2x1ZGVkTWFya3MubGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0ZXh0RW5kIDwgcmFuZ2UudG8pIHtcbiAgICAgICAgICB0ci5kZWxldGUodGV4dEVuZCwgcmFuZ2UudG8pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGV4dFN0YXJ0ID4gcmFuZ2UuZnJvbSkge1xuICAgICAgICAgIHRyLmRlbGV0ZShyYW5nZS5mcm9tICsgc3RhcnRTcGFjZXMsIHRleHRTdGFydClcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG1hcmtFbmQgPSByYW5nZS5mcm9tICsgc3RhcnRTcGFjZXMgKyBjYXB0dXJlR3JvdXAubGVuZ3RoXG5cbiAgICAgICAgdHIuYWRkTWFyayhyYW5nZS5mcm9tICsgc3RhcnRTcGFjZXMsIG1hcmtFbmQsIGNvbmZpZy50eXBlLmNyZWF0ZShhdHRyaWJ1dGVzIHx8IHt9KSlcblxuICAgICAgICB0ci5yZW1vdmVTdG9yZWRNYXJrKGNvbmZpZy50eXBlKVxuICAgICAgfVxuICAgIH0sXG4gICAgdW5kb2FibGU6IGNvbmZpZy51bmRvYWJsZSxcbiAgfSlcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBJbnB1dFJ1bGVGaW5kZXIgfSBmcm9tICcuLi9JbnB1dFJ1bGUuanMnXG5pbXBvcnQgeyBJbnB1dFJ1bGUgfSBmcm9tICcuLi9JbnB1dFJ1bGUuanMnXG5pbXBvcnQgdHlwZSB7IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgY2FsbE9yUmV0dXJuIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2NhbGxPclJldHVybi5qcydcblxuLyoqXG4gKiBCdWlsZCBhbiBpbnB1dCBydWxlIHRoYXQgYWRkcyBhIG5vZGUgd2hlbiB0aGVcbiAqIG1hdGNoZWQgdGV4dCBpcyB0eXBlZCBpbnRvIGl0LlxuICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZG9jcy9lZGl0b3IvZXh0ZW5zaW9ucy9jdXN0b20tZXh0ZW5zaW9ucy9leHRlbmQtZXhpc3RpbmcjaW5wdXQtcnVsZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vZGVJbnB1dFJ1bGUoY29uZmlnOiB7XG4gIC8qKlxuICAgKiBUaGUgcmVnZXggdG8gbWF0Y2guXG4gICAqL1xuICBmaW5kOiBJbnB1dFJ1bGVGaW5kZXJcblxuICAvKipcbiAgICogVGhlIG5vZGUgdHlwZSB0byBhZGQuXG4gICAqL1xuICB0eXBlOiBOb2RlVHlwZVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBpbnB1dCBydWxlIHNob3VsZCBiZSB1bmRvYWJsZVxuICAgKiB3aGVuIHRoZSB1c2VyIHByZXNzZXMgYmFja3NwYWNlLlxuICAgKi9cbiAgdW5kb2FibGU/OiBib29sZWFuXG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBhdHRyaWJ1dGVzIGZvciB0aGUgbm9kZVxuICAgKiBjYW4gYWxzbyBiZSBhbiBvYmplY3Qgb2YgYXR0cmlidXRlc1xuICAgKi9cbiAgZ2V0QXR0cmlidXRlcz86XG4gICAgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgfCAoKG1hdGNoOiBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXkpID0+IFJlY29yZDxzdHJpbmcsIGFueT4pXG4gICAgfCBmYWxzZVxuICAgIHwgbnVsbFxufSkge1xuICByZXR1cm4gbmV3IElucHV0UnVsZSh7XG4gICAgZmluZDogY29uZmlnLmZpbmQsXG4gICAgaGFuZGxlcjogKHsgc3RhdGUsIHJhbmdlLCBtYXRjaCB9KSA9PiB7XG4gICAgICBjb25zdCBhdHRyaWJ1dGVzID0gY2FsbE9yUmV0dXJuKGNvbmZpZy5nZXRBdHRyaWJ1dGVzLCB1bmRlZmluZWQsIG1hdGNoKSB8fCB7fVxuICAgICAgY29uc3QgeyB0ciB9ID0gc3RhdGVcbiAgICAgIGNvbnN0IHN0YXJ0ID0gcmFuZ2UuZnJvbVxuICAgICAgbGV0IGVuZCA9IHJhbmdlLnRvXG5cbiAgICAgIGNvbnN0IG5ld05vZGUgPSBjb25maWcudHlwZS5jcmVhdGUoYXR0cmlidXRlcylcblxuICAgICAgaWYgKG1hdGNoWzFdKSB7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IG1hdGNoWzBdLmxhc3RJbmRleE9mKG1hdGNoWzFdKVxuICAgICAgICBsZXQgbWF0Y2hTdGFydCA9IHN0YXJ0ICsgb2Zmc2V0XG5cbiAgICAgICAgaWYgKG1hdGNoU3RhcnQgPiBlbmQpIHtcbiAgICAgICAgICBtYXRjaFN0YXJ0ID0gZW5kXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW5kID0gbWF0Y2hTdGFydCArIG1hdGNoWzFdLmxlbmd0aFxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaW5zZXJ0IGxhc3QgdHlwZWQgY2hhcmFjdGVyXG4gICAgICAgIGNvbnN0IGxhc3RDaGFyID0gbWF0Y2hbMF1bbWF0Y2hbMF0ubGVuZ3RoIC0gMV1cblxuICAgICAgICB0ci5pbnNlcnRUZXh0KGxhc3RDaGFyLCBzdGFydCArIG1hdGNoWzBdLmxlbmd0aCAtIDEpXG5cbiAgICAgICAgLy8gaW5zZXJ0IG5vZGUgZnJvbSBpbnB1dCBydWxlXG4gICAgICAgIHRyLnJlcGxhY2VXaXRoKG1hdGNoU3RhcnQsIGVuZCwgbmV3Tm9kZSlcbiAgICAgIH0gZWxzZSBpZiAobWF0Y2hbMF0pIHtcbiAgICAgICAgY29uc3QgaW5zZXJ0aW9uU3RhcnQgPSBjb25maWcudHlwZS5pc0lubGluZSA/IHN0YXJ0IDogc3RhcnQgLSAxXG5cbiAgICAgICAgdHIuaW5zZXJ0KGluc2VydGlvblN0YXJ0LCBjb25maWcudHlwZS5jcmVhdGUoYXR0cmlidXRlcykpLmRlbGV0ZShcbiAgICAgICAgICB0ci5tYXBwaW5nLm1hcChzdGFydCksXG4gICAgICAgICAgdHIubWFwcGluZy5tYXAoZW5kKSxcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICB0ci5zY3JvbGxJbnRvVmlldygpXG4gICAgfSxcbiAgICB1bmRvYWJsZTogY29uZmlnLnVuZG9hYmxlLFxuICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgdHlwZSB7IElucHV0UnVsZUZpbmRlciB9IGZyb20gJy4uL0lucHV0UnVsZS5qcydcbmltcG9ydCB7IElucHV0UnVsZSB9IGZyb20gJy4uL0lucHV0UnVsZS5qcydcbmltcG9ydCB0eXBlIHsgRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5IH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBjYWxsT3JSZXR1cm4gfSBmcm9tICcuLi91dGlsaXRpZXMvY2FsbE9yUmV0dXJuLmpzJ1xuXG4vKipcbiAqIEJ1aWxkIGFuIGlucHV0IHJ1bGUgdGhhdCBjaGFuZ2VzIHRoZSB0eXBlIG9mIGEgdGV4dGJsb2NrIHdoZW4gdGhlXG4gKiBtYXRjaGVkIHRleHQgaXMgdHlwZWQgaW50byBpdC4gV2hlbiB1c2luZyBhIHJlZ3VsYXIgZXhwcmVzaW9uIHlvdeKAmWxsXG4gKiBwcm9iYWJseSB3YW50IHRoZSByZWdleHAgdG8gc3RhcnQgd2l0aCBgXmAsIHNvIHRoYXQgdGhlIHBhdHRlcm4gY2FuXG4gKiBvbmx5IG9jY3VyIGF0IHRoZSBzdGFydCBvZiBhIHRleHRibG9jay5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2V4dGVuc2lvbnMvY3VzdG9tLWV4dGVuc2lvbnMvZXh0ZW5kLWV4aXN0aW5nI2lucHV0LXJ1bGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0ZXh0YmxvY2tUeXBlSW5wdXRSdWxlKGNvbmZpZzoge1xuICBmaW5kOiBJbnB1dFJ1bGVGaW5kZXJcbiAgdHlwZTogTm9kZVR5cGVcbiAgdW5kb2FibGU/OiBib29sZWFuXG4gIGdldEF0dHJpYnV0ZXM/OlxuICAgIHwgUmVjb3JkPHN0cmluZywgYW55PlxuICAgIHwgKChtYXRjaDogRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5KSA9PiBSZWNvcmQ8c3RyaW5nLCBhbnk+KVxuICAgIHwgZmFsc2VcbiAgICB8IG51bGxcbn0pIHtcbiAgcmV0dXJuIG5ldyBJbnB1dFJ1bGUoe1xuICAgIGZpbmQ6IGNvbmZpZy5maW5kLFxuICAgIGhhbmRsZXI6ICh7IHN0YXRlLCByYW5nZSwgbWF0Y2ggfSkgPT4ge1xuICAgICAgY29uc3QgJHN0YXJ0ID0gc3RhdGUuZG9jLnJlc29sdmUocmFuZ2UuZnJvbSlcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBjYWxsT3JSZXR1cm4oY29uZmlnLmdldEF0dHJpYnV0ZXMsIHVuZGVmaW5lZCwgbWF0Y2gpIHx8IHt9XG5cbiAgICAgIGlmICghJHN0YXJ0Lm5vZGUoLTEpLmNhblJlcGxhY2VXaXRoKCRzdGFydC5pbmRleCgtMSksICRzdGFydC5pbmRleEFmdGVyKC0xKSwgY29uZmlnLnR5cGUpKSB7XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG5cbiAgICAgIHN0YXRlLnRyXG4gICAgICAgIC5kZWxldGUocmFuZ2UuZnJvbSwgcmFuZ2UudG8pXG4gICAgICAgIC5zZXRCbG9ja1R5cGUocmFuZ2UuZnJvbSwgcmFuZ2UuZnJvbSwgY29uZmlnLnR5cGUsIGF0dHJpYnV0ZXMpXG4gICAgfSxcbiAgICB1bmRvYWJsZTogY29uZmlnLnVuZG9hYmxlLFxuICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgSW5wdXRSdWxlRmluZGVyIH0gZnJvbSAnLi4vSW5wdXRSdWxlLmpzJ1xuaW1wb3J0IHsgSW5wdXRSdWxlIH0gZnJvbSAnLi4vSW5wdXRSdWxlLmpzJ1xuXG4vKipcbiAqIEJ1aWxkIGFuIGlucHV0IHJ1bGUgdGhhdCByZXBsYWNlcyB0ZXh0IHdoZW4gdGhlXG4gKiBtYXRjaGVkIHRleHQgaXMgdHlwZWQgaW50byBpdC5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2V4dGVuc2lvbnMvY3VzdG9tLWV4dGVuc2lvbnMvZXh0ZW5kLWV4aXN0aW5nI2lucHV0LXJ1bGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0ZXh0SW5wdXRSdWxlKGNvbmZpZzoge1xuICBmaW5kOiBJbnB1dFJ1bGVGaW5kZXJcbiAgcmVwbGFjZTogc3RyaW5nXG4gIHVuZG9hYmxlPzogYm9vbGVhblxufSkge1xuICByZXR1cm4gbmV3IElucHV0UnVsZSh7XG4gICAgZmluZDogY29uZmlnLmZpbmQsXG4gICAgaGFuZGxlcjogKHsgc3RhdGUsIHJhbmdlLCBtYXRjaCB9KSA9PiB7XG4gICAgICBsZXQgaW5zZXJ0ID0gY29uZmlnLnJlcGxhY2VcbiAgICAgIGxldCBzdGFydCA9IHJhbmdlLmZyb21cbiAgICAgIGNvbnN0IGVuZCA9IHJhbmdlLnRvXG5cbiAgICAgIGlmIChtYXRjaFsxXSkge1xuICAgICAgICBjb25zdCBvZmZzZXQgPSBtYXRjaFswXS5sYXN0SW5kZXhPZihtYXRjaFsxXSlcblxuICAgICAgICBpbnNlcnQgKz0gbWF0Y2hbMF0uc2xpY2Uob2Zmc2V0ICsgbWF0Y2hbMV0ubGVuZ3RoKVxuICAgICAgICBzdGFydCArPSBvZmZzZXRcblxuICAgICAgICBjb25zdCBjdXRPZmYgPSBzdGFydCAtIGVuZFxuXG4gICAgICAgIGlmIChjdXRPZmYgPiAwKSB7XG4gICAgICAgICAgaW5zZXJ0ID0gbWF0Y2hbMF0uc2xpY2Uob2Zmc2V0IC0gY3V0T2ZmLCBvZmZzZXQpICsgaW5zZXJ0XG4gICAgICAgICAgc3RhcnQgPSBlbmRcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzdGF0ZS50ci5pbnNlcnRUZXh0KGluc2VydCwgc3RhcnQsIGVuZClcbiAgICB9LFxuICAgIHVuZG9hYmxlOiBjb25maWcudW5kb2FibGUsXG4gIH0pXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSwgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgY2FuSm9pbiwgZmluZFdyYXBwaW5nIH0gZnJvbSAnQHRpcHRhcC9wbS90cmFuc2Zvcm0nXG5cbmltcG9ydCB0eXBlIHsgRWRpdG9yIH0gZnJvbSAnLi4vRWRpdG9yLmpzJ1xuaW1wb3J0IHR5cGUgeyBJbnB1dFJ1bGVGaW5kZXIgfSBmcm9tICcuLi9JbnB1dFJ1bGUuanMnXG5pbXBvcnQgeyBJbnB1dFJ1bGUgfSBmcm9tICcuLi9JbnB1dFJ1bGUuanMnXG5pbXBvcnQgdHlwZSB7IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgY2FsbE9yUmV0dXJuIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2NhbGxPclJldHVybi5qcydcblxuLyoqXG4gKiBCdWlsZCBhbiBpbnB1dCBydWxlIGZvciBhdXRvbWF0aWNhbGx5IHdyYXBwaW5nIGEgdGV4dGJsb2NrIHdoZW4gYVxuICogZ2l2ZW4gc3RyaW5nIGlzIHR5cGVkLiBXaGVuIHVzaW5nIGEgcmVndWxhciBleHByZXNpb24geW914oCZbGxcbiAqIHByb2JhYmx5IHdhbnQgdGhlIHJlZ2V4cCB0byBzdGFydCB3aXRoIGBeYCwgc28gdGhhdCB0aGUgcGF0dGVybiBjYW5cbiAqIG9ubHkgb2NjdXIgYXQgdGhlIHN0YXJ0IG9mIGEgdGV4dGJsb2NrLlxuICpcbiAqIGB0eXBlYCBpcyB0aGUgdHlwZSBvZiBub2RlIHRvIHdyYXAgaW4uXG4gKlxuICogQnkgZGVmYXVsdCwgaWYgdGhlcmXigJlzIGEgbm9kZSB3aXRoIHRoZSBzYW1lIHR5cGUgYWJvdmUgdGhlIG5ld2x5XG4gKiB3cmFwcGVkIG5vZGUsIHRoZSBydWxlIHdpbGwgdHJ5IHRvIGpvaW4gdGhvc2VcbiAqIHR3byBub2Rlcy4gWW91IGNhbiBwYXNzIGEgam9pbiBwcmVkaWNhdGUsIHdoaWNoIHRha2VzIGEgcmVndWxhclxuICogZXhwcmVzc2lvbiBtYXRjaCBhbmQgdGhlIG5vZGUgYmVmb3JlIHRoZSB3cmFwcGVkIG5vZGUsIGFuZCBjYW5cbiAqIHJldHVybiBhIGJvb2xlYW4gdG8gaW5kaWNhdGUgd2hldGhlciBhIGpvaW4gc2hvdWxkIGhhcHBlbi5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2V4dGVuc2lvbnMvY3VzdG9tLWV4dGVuc2lvbnMvZXh0ZW5kLWV4aXN0aW5nI2lucHV0LXJ1bGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwcGluZ0lucHV0UnVsZShjb25maWc6IHtcbiAgZmluZDogSW5wdXRSdWxlRmluZGVyXG4gIHR5cGU6IE5vZGVUeXBlXG4gIGtlZXBNYXJrcz86IGJvb2xlYW5cbiAga2VlcEF0dHJpYnV0ZXM/OiBib29sZWFuXG4gIGVkaXRvcj86IEVkaXRvclxuICB1bmRvYWJsZT86IGJvb2xlYW5cbiAgZ2V0QXR0cmlidXRlcz86XG4gICAgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgfCAoKG1hdGNoOiBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXkpID0+IFJlY29yZDxzdHJpbmcsIGFueT4pXG4gICAgfCBmYWxzZVxuICAgIHwgbnVsbFxuICBqb2luUHJlZGljYXRlPzogKG1hdGNoOiBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXksIG5vZGU6IFByb3NlTWlycm9yTm9kZSkgPT4gYm9vbGVhblxufSkge1xuICByZXR1cm4gbmV3IElucHV0UnVsZSh7XG4gICAgZmluZDogY29uZmlnLmZpbmQsXG4gICAgaGFuZGxlcjogKHsgc3RhdGUsIHJhbmdlLCBtYXRjaCwgY2hhaW4gfSkgPT4ge1xuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IGNhbGxPclJldHVybihjb25maWcuZ2V0QXR0cmlidXRlcywgdW5kZWZpbmVkLCBtYXRjaCkgfHwge31cbiAgICAgIGNvbnN0IHRyID0gc3RhdGUudHIuZGVsZXRlKHJhbmdlLmZyb20sIHJhbmdlLnRvKVxuICAgICAgY29uc3QgJHN0YXJ0ID0gdHIuZG9jLnJlc29sdmUocmFuZ2UuZnJvbSlcbiAgICAgIGNvbnN0IGJsb2NrUmFuZ2UgPSAkc3RhcnQuYmxvY2tSYW5nZSgpXG4gICAgICBjb25zdCB3cmFwcGluZyA9IGJsb2NrUmFuZ2UgJiYgZmluZFdyYXBwaW5nKGJsb2NrUmFuZ2UsIGNvbmZpZy50eXBlLCBhdHRyaWJ1dGVzKVxuXG4gICAgICBpZiAoIXdyYXBwaW5nKSB7XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG5cbiAgICAgIHRyLndyYXAoYmxvY2tSYW5nZSwgd3JhcHBpbmcpXG5cbiAgICAgIGlmIChjb25maWcua2VlcE1hcmtzICYmIGNvbmZpZy5lZGl0b3IpIHtcbiAgICAgICAgY29uc3QgeyBzZWxlY3Rpb24sIHN0b3JlZE1hcmtzIH0gPSBzdGF0ZVxuICAgICAgICBjb25zdCB7IHNwbGl0dGFibGVNYXJrcyB9ID0gY29uZmlnLmVkaXRvci5leHRlbnNpb25NYW5hZ2VyXG4gICAgICAgIGNvbnN0IG1hcmtzID0gc3RvcmVkTWFya3MgfHwgKHNlbGVjdGlvbi4kdG8ucGFyZW50T2Zmc2V0ICYmIHNlbGVjdGlvbi4kZnJvbS5tYXJrcygpKVxuXG4gICAgICAgIGlmIChtYXJrcykge1xuICAgICAgICAgIGNvbnN0IGZpbHRlcmVkTWFya3MgPSBtYXJrcy5maWx0ZXIobWFyayA9PiBzcGxpdHRhYmxlTWFya3MuaW5jbHVkZXMobWFyay50eXBlLm5hbWUpKVxuXG4gICAgICAgICAgdHIuZW5zdXJlTWFya3MoZmlsdGVyZWRNYXJrcylcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGNvbmZpZy5rZWVwQXR0cmlidXRlcykge1xuICAgICAgICAvKiogSWYgdGhlIG5vZGVUeXBlIGlzIGBidWxsZXRMaXN0YCBvciBgb3JkZXJlZExpc3RgIHNldCB0aGUgYG5vZGVUeXBlYCBhcyBgbGlzdEl0ZW1gICovXG4gICAgICAgIGNvbnN0IG5vZGVUeXBlID1cbiAgICAgICAgICBjb25maWcudHlwZS5uYW1lID09PSAnYnVsbGV0TGlzdCcgfHwgY29uZmlnLnR5cGUubmFtZSA9PT0gJ29yZGVyZWRMaXN0J1xuICAgICAgICAgICAgPyAnbGlzdEl0ZW0nXG4gICAgICAgICAgICA6ICd0YXNrTGlzdCdcblxuICAgICAgICBjaGFpbigpLnVwZGF0ZUF0dHJpYnV0ZXMobm9kZVR5cGUsIGF0dHJpYnV0ZXMpLnJ1bigpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJlZm9yZSA9IHRyLmRvYy5yZXNvbHZlKHJhbmdlLmZyb20gLSAxKS5ub2RlQmVmb3JlXG5cbiAgICAgIGlmIChcbiAgICAgICAgYmVmb3JlICYmXG4gICAgICAgIGJlZm9yZS50eXBlID09PSBjb25maWcudHlwZSAmJlxuICAgICAgICBjYW5Kb2luKHRyLmRvYywgcmFuZ2UuZnJvbSAtIDEpICYmXG4gICAgICAgICghY29uZmlnLmpvaW5QcmVkaWNhdGUgfHwgY29uZmlnLmpvaW5QcmVkaWNhdGUobWF0Y2gsIGJlZm9yZSkpXG4gICAgICApIHtcbiAgICAgICAgdHIuam9pbihyYW5nZS5mcm9tIC0gMSlcbiAgICAgIH1cbiAgICB9LFxuICAgIHVuZG9hYmxlOiBjb25maWcudW5kb2FibGUsXG4gIH0pXG59XG4iLCAiZXhwb3J0IHR5cGUgQXR0cmlidXRlcyA9IFJlY29yZDxzdHJpbmcsIGFueT5cblxuZXhwb3J0IHR5cGUgRE9NT3V0cHV0U3BlY0VsZW1lbnQgPSAwIHwgQXR0cmlidXRlcyB8IERPTU91dHB1dFNwZWNBcnJheVxuLyoqXG4gKiBCZXR0ZXIgZGVzY3JpYmVzIHRoZSBvdXRwdXQgb2YgYSBgcmVuZGVySFRNTGAgZnVuY3Rpb24gaW4gcHJvc2VtaXJyb3JcbiAqIEBzZWUgaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLkRPTU91dHB1dFNwZWNcbiAqL1xuZXhwb3J0IHR5cGUgRE9NT3V0cHV0U3BlY0FycmF5ID1cbiAgfCBbc3RyaW5nXVxuICB8IFtzdHJpbmcsIEF0dHJpYnV0ZXNdXG4gIHwgW3N0cmluZywgMF1cbiAgfCBbc3RyaW5nLCBBdHRyaWJ1dGVzLCAwXVxuICB8IFtzdHJpbmcsIEF0dHJpYnV0ZXMsIERPTU91dHB1dFNwZWNBcnJheSB8IDBdXG4gIHwgW3N0cmluZywgRE9NT3V0cHV0U3BlY0FycmF5XVxuXG4vLyBKU1ggdHlwZXMgZm9yIFRpcHRhcCdzIEpTWCBydW50aW1lXG4vLyBUaGVzZSB0eXBlcyBvbmx5IGFwcGx5IHdoZW4gdXNpbmcgQGpzeEltcG9ydFNvdXJjZSBAdGlwdGFwL2NvcmVcbi8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZW5vLW5hbWVzcGFjZVxuZXhwb3J0IG5hbWVzcGFjZSBKU1gge1xuICBleHBvcnQgdHlwZSBFbGVtZW50ID0gRE9NT3V0cHV0U3BlY0FycmF5XG4gIGV4cG9ydCBpbnRlcmZhY2UgSW50cmluc2ljRWxlbWVudHMge1xuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZW5vLWV4cGxpY2l0LWFueVxuICAgIFtrZXk6IHN0cmluZ106IGFueVxuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgRWxlbWVudENoaWxkcmVuQXR0cmlidXRlIHtcbiAgICBjaGlsZHJlbjogdW5rbm93blxuICB9XG59XG5cbmV4cG9ydCB0eXBlIEpTWFJlbmRlcmVyID0gKFxuICB0YWc6ICdzbG90JyB8IHN0cmluZyB8ICgocHJvcHM/OiBBdHRyaWJ1dGVzKSA9PiBET01PdXRwdXRTcGVjQXJyYXkgfCBET01PdXRwdXRTcGVjRWxlbWVudCksXG4gIHByb3BzPzogQXR0cmlidXRlcyxcbiAgLi4uY2hpbGRyZW46IEpTWFJlbmRlcmVyW11cbikgPT4gRE9NT3V0cHV0U3BlY0FycmF5IHwgRE9NT3V0cHV0U3BlY0VsZW1lbnRcblxuZXhwb3J0IGZ1bmN0aW9uIEZyYWdtZW50KHByb3BzOiB7IGNoaWxkcmVuOiBKU1hSZW5kZXJlcltdIH0pIHtcbiAgcmV0dXJuIHByb3BzLmNoaWxkcmVuXG59XG5cbmV4cG9ydCBjb25zdCBoOiBKU1hSZW5kZXJlciA9ICh0YWcsIGF0dHJpYnV0ZXMpID0+IHtcbiAgLy8gVHJlYXQgdGhlIHNsb3QgdGFnIGFzIHRoZSBQcm9zZW1pcnJvciBob2xlIHRvIHJlbmRlciBjb250ZW50IGludG9cbiAgaWYgKHRhZyA9PT0gJ3Nsb3QnKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuXG4gIC8vIElmIHRoZSB0YWcgaXMgYSBmdW5jdGlvbiwgY2FsbCBpdCB3aXRoIHRoZSBwcm9wc1xuICBpZiAodGFnIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICByZXR1cm4gdGFnKGF0dHJpYnV0ZXMpXG4gIH1cblxuICBjb25zdCB7IGNoaWxkcmVuLCAuLi5yZXN0IH0gPSBhdHRyaWJ1dGVzID8/IHt9XG5cbiAgaWYgKHRhZyA9PT0gJ3N2ZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnU1ZHIGVsZW1lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluIHRoZSBKU1ggc3ludGF4LCB1c2UgdGhlIGFycmF5IHN5bnRheCBpbnN0ZWFkJyxcbiAgICApXG4gIH1cblxuICAvLyBPdGhlcndpc2UsIHJldHVybiB0aGUgdGFnLCBhdHRyaWJ1dGVzLCBhbmQgY2hpbGRyZW5cbiAgcmV0dXJuIFt0YWcsIHJlc3QsIGNoaWxkcmVuXVxufVxuXG4vLyBTZWVcbi8vIGh0dHBzOi8vZXNidWlsZC5naXRodWIuaW8vYXBpLyNqc3gtaW1wb3J0LXNvdXJjZVxuLy8gaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL3RzY29uZmlnLyNqc3hJbXBvcnRTb3VyY2VcblxuZXhwb3J0IHsgaCBhcyBjcmVhdGVFbGVtZW50LCBoIGFzIGpzeCwgaCBhcyBqc3hERVYsIGggYXMganN4cyB9XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIGFzIFBNTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgdHlwZSB7IERlY29yYXRpb24sIERlY29yYXRpb25Tb3VyY2UsIE5vZGVWaWV3IH0gZnJvbSAnQHRpcHRhcC9wbS92aWV3J1xuXG5pbXBvcnQgdHlwZSB7IEVkaXRvciB9IGZyb20gJy4uL0VkaXRvci5qcydcblxuY29uc3QgaXNUb3VjaEV2ZW50ID0gKGU6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogZSBpcyBUb3VjaEV2ZW50ID0+IHtcbiAgcmV0dXJuICd0b3VjaGVzJyBpbiBlXG59XG5cbi8qKlxuICogRGlyZWN0aW9ucyB3aGVyZSByZXNpemUgaGFuZGxlcyBjYW4gYmUgcGxhY2VkXG4gKlxuICogQGV4YW1wbGVcbiAqIC0gYCd0b3AnYCAtIFRvcCBlZGdlIGhhbmRsZVxuICogLSBgJ2JvdHRvbS1yaWdodCdgIC0gQm90dG9tLXJpZ2h0IGNvcm5lciBoYW5kbGVcbiAqL1xuZXhwb3J0IHR5cGUgUmVzaXphYmxlTm9kZVZpZXdEaXJlY3Rpb24gPVxuICB8ICd0b3AnXG4gIHwgJ3JpZ2h0J1xuICB8ICdib3R0b20nXG4gIHwgJ2xlZnQnXG4gIHwgJ3RvcC1yaWdodCdcbiAgfCAndG9wLWxlZnQnXG4gIHwgJ2JvdHRvbS1yaWdodCdcbiAgfCAnYm90dG9tLWxlZnQnXG5cbi8qKlxuICogRGltZW5zaW9ucyBmb3IgdGhlIHJlc2l6YWJsZSBub2RlIGluIHBpeGVsc1xuICovXG5leHBvcnQgdHlwZSBSZXNpemFibGVOb2RlRGltZW5zaW9ucyA9IHtcbiAgLyoqIFdpZHRoIGluIHBpeGVscyAqL1xuICB3aWR0aDogbnVtYmVyXG4gIC8qKiBIZWlnaHQgaW4gcGl4ZWxzICovXG4gIGhlaWdodDogbnVtYmVyXG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBjcmVhdGluZyBhIFJlc2l6YWJsZU5vZGVWaWV3XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBuZXcgUmVzaXphYmxlTm9kZVZpZXcoe1xuICogICBlbGVtZW50OiBpbWdFbGVtZW50LFxuICogICBub2RlLFxuICogICBnZXRQb3MsXG4gKiAgIG9uUmVzaXplOiAod2lkdGgsIGhlaWdodCkgPT4ge1xuICogICAgIGltZ0VsZW1lbnQuc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGBcbiAqICAgICBpbWdFbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGBcbiAqICAgfSxcbiAqICAgb25Db21taXQ6ICh3aWR0aCwgaGVpZ2h0KSA9PiB7XG4gKiAgICAgZWRpdG9yLmNvbW1hbmRzLnVwZGF0ZUF0dHJpYnV0ZXMoJ2ltYWdlJywgeyB3aWR0aCwgaGVpZ2h0IH0pXG4gKiAgIH0sXG4gKiAgIG9uVXBkYXRlOiAobm9kZSkgPT4gdHJ1ZSxcbiAqICAgb3B0aW9uczoge1xuICogICAgIGRpcmVjdGlvbnM6IFsnYm90dG9tLXJpZ2h0JywgJ2JvdHRvbS1sZWZ0J10sXG4gKiAgICAgbWluOiB7IHdpZHRoOiAxMDAsIGhlaWdodDogMTAwIH0sXG4gKiAgICAgcHJlc2VydmVBc3BlY3RSYXRpbzogdHJ1ZVxuICogICB9XG4gKiB9KVxuICogYGBgXG4gKi9cbmV4cG9ydCB0eXBlIFJlc2l6YWJsZU5vZGVWaWV3T3B0aW9ucyA9IHtcbiAgLyoqXG4gICAqIFRoZSBET00gZWxlbWVudCB0byBtYWtlIHJlc2l6YWJsZSAoZS5nLiwgYW4gaW1nLCB2aWRlbywgb3IgaWZyYW1lIGVsZW1lbnQpXG4gICAqL1xuICBlbGVtZW50OiBIVE1MRWxlbWVudFxuXG4gIC8qKlxuICAgKiBUaGUgRE9NIGVsZW1lbnQgdGhhdCB3aWxsIGhvbGQgdGhlIGVkaXRhYmxlIGNvbnRlbnQgZWxlbWVudFxuICAgKi9cbiAgY29udGVudEVsZW1lbnQ/OiBIVE1MRWxlbWVudFxuXG4gIC8qKlxuICAgKiBUaGUgUHJvc2VNaXJyb3Igbm9kZSBpbnN0YW5jZVxuICAgKi9cbiAgbm9kZTogUE1Ob2RlXG5cbiAgLyoqXG4gICAqIFRoZSBUaXB0YXAgZWRpdG9yIGluc3RhbmNlXG4gICAqL1xuICBlZGl0b3I6IEVkaXRvclxuXG4gIC8qKlxuICAgKiBGdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIGN1cnJlbnQgcG9zaXRpb24gb2YgdGhlIG5vZGUgaW4gdGhlIGRvY3VtZW50XG4gICAqL1xuICBnZXRQb3M6ICgpID0+IG51bWJlciB8IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBDYWxsYmFjayBmaXJlZCBjb250aW51b3VzbHkgZHVyaW5nIHJlc2l6ZSB3aXRoIGN1cnJlbnQgZGltZW5zaW9ucy5cbiAgICogVXNlIHRoaXMgdG8gdXBkYXRlIHRoZSBlbGVtZW50J3MgdmlzdWFsIHNpemUgaW4gcmVhbC10aW1lLlxuICAgKlxuICAgKiBAcGFyYW0gd2lkdGggLSBDdXJyZW50IHdpZHRoIGluIHBpeGVsc1xuICAgKiBAcGFyYW0gaGVpZ2h0IC0gQ3VycmVudCBoZWlnaHQgaW4gcGl4ZWxzXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHRzXG4gICAqIG9uUmVzaXplOiAod2lkdGgsIGhlaWdodCkgPT4ge1xuICAgKiAgIGVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGBcbiAgICogICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGBcbiAgICogfVxuICAgKiBgYGBcbiAgICovXG4gIG9uUmVzaXplPzogKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKSA9PiB2b2lkXG5cbiAgLyoqXG4gICAqIENhbGxiYWNrIGZpcmVkIG9uY2Ugd2hlbiByZXNpemUgY29tcGxldGVzIHdpdGggZmluYWwgZGltZW5zaW9ucy5cbiAgICogVXNlIHRoaXMgdG8gcGVyc2lzdCB0aGUgbmV3IHNpemUgdG8gdGhlIG5vZGUncyBhdHRyaWJ1dGVzLlxuICAgKlxuICAgKiBAcGFyYW0gd2lkdGggLSBGaW5hbCB3aWR0aCBpbiBwaXhlbHNcbiAgICogQHBhcmFtIGhlaWdodCAtIEZpbmFsIGhlaWdodCBpbiBwaXhlbHNcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHNcbiAgICogb25Db21taXQ6ICh3aWR0aCwgaGVpZ2h0KSA9PiB7XG4gICAqICAgY29uc3QgcG9zID0gZ2V0UG9zKClcbiAgICogICBpZiAocG9zICE9PSB1bmRlZmluZWQpIHtcbiAgICogICAgIGVkaXRvci5jb21tYW5kcy51cGRhdGVBdHRyaWJ1dGVzKCdpbWFnZScsIHsgd2lkdGgsIGhlaWdodCB9KVxuICAgKiAgIH1cbiAgICogfVxuICAgKiBgYGBcbiAgICovXG4gIG9uQ29tbWl0OiAod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpID0+IHZvaWRcblxuICAvKipcbiAgICogQ2FsbGJhY2sgZm9yIGhhbmRsaW5nIG5vZGUgdXBkYXRlcy5cbiAgICogUmV0dXJuIGB0cnVlYCB0byBhY2NlcHQgdGhlIHVwZGF0ZSwgYGZhbHNlYCB0byByZWplY3QgaXQuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHRzXG4gICAqIG9uVXBkYXRlOiAobm9kZSwgZGVjb3JhdGlvbnMsIGlubmVyRGVjb3JhdGlvbnMpID0+IHtcbiAgICogICBpZiAobm9kZS50eXBlICE9PSB0aGlzLm5vZGUudHlwZSkgcmV0dXJuIGZhbHNlXG4gICAqICAgcmV0dXJuIHRydWVcbiAgICogfVxuICAgKiBgYGBcbiAgICovXG4gIG9uVXBkYXRlOiBOb2RlVmlld1sndXBkYXRlJ11cblxuICAvKipcbiAgICogT3B0aW9uYWwgY29uZmlndXJhdGlvbiBmb3IgcmVzaXplIGJlaGF2aW9yIGFuZCBzdHlsaW5nXG4gICAqL1xuICBvcHRpb25zPzoge1xuICAgIC8qKlxuICAgICAqIFdoaWNoIHJlc2l6ZSBoYW5kbGVzIHRvIGRpc3BsYXkuXG4gICAgICogQGRlZmF1bHQgWydib3R0b20tbGVmdCcsICdib3R0b20tcmlnaHQnLCAndG9wLWxlZnQnLCAndG9wLXJpZ2h0J11cbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBgdHNcbiAgICAgKiAvLyBPbmx5IHNob3cgY29ybmVyIGhhbmRsZXNcbiAgICAgKiBkaXJlY3Rpb25zOiBbJ3RvcC1sZWZ0JywgJ3RvcC1yaWdodCcsICdib3R0b20tbGVmdCcsICdib3R0b20tcmlnaHQnXVxuICAgICAqXG4gICAgICogLy8gT25seSBzaG93IHJpZ2h0IGVkZ2UgaGFuZGxlXG4gICAgICogZGlyZWN0aW9uczogWydyaWdodCddXG4gICAgICogYGBgXG4gICAgICovXG4gICAgZGlyZWN0aW9ucz86IFJlc2l6YWJsZU5vZGVWaWV3RGlyZWN0aW9uW11cblxuICAgIC8qKlxuICAgICAqIE1pbmltdW0gZGltZW5zaW9ucyBpbiBwaXhlbHNcbiAgICAgKiBAZGVmYXVsdCB7IHdpZHRoOiA4LCBoZWlnaHQ6IDggfVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGB0c1xuICAgICAqIG1pbjogeyB3aWR0aDogMTAwLCBoZWlnaHQ6IDUwIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBtaW4/OiBQYXJ0aWFsPFJlc2l6YWJsZU5vZGVEaW1lbnNpb25zPlxuXG4gICAgLyoqXG4gICAgICogTWF4aW11bSBkaW1lbnNpb25zIGluIHBpeGVsc1xuICAgICAqIEBkZWZhdWx0IHVuZGVmaW5lZCAobm8gbWF4aW11bSlcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBgdHNcbiAgICAgKiBtYXg6IHsgd2lkdGg6IDEwMDAsIGhlaWdodDogODAwIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBtYXg/OiBQYXJ0aWFsPFJlc2l6YWJsZU5vZGVEaW1lbnNpb25zPlxuXG4gICAgLyoqXG4gICAgICogQWx3YXlzIHByZXNlcnZlIGFzcGVjdCByYXRpbyB3aGVuIHJlc2l6aW5nLlxuICAgICAqIFdoZW4gYGZhbHNlYCwgYXNwZWN0IHJhdGlvIGlzIHByZXNlcnZlZCBvbmx5IHdoZW4gU2hpZnQga2V5IGlzIHByZXNzZWQuXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKlxuICAgICAqIEBleGFtcGxlXG4gICAgICogYGBgdHNcbiAgICAgKiBwcmVzZXJ2ZUFzcGVjdFJhdGlvOiB0cnVlIC8vIEFsd2F5cyBsb2NrIGFzcGVjdCByYXRpb1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHByZXNlcnZlQXNwZWN0UmF0aW8/OiBib29sZWFuXG5cbiAgICAvKipcbiAgICAgKiBDdXN0b20gQ1NTIGNsYXNzIG5hbWVzIGZvciBzdHlsaW5nXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYHRzXG4gICAgICogY2xhc3NOYW1lOiB7XG4gICAgICogICBjb250YWluZXI6ICdyZXNpemUtY29udGFpbmVyJyxcbiAgICAgKiAgIHdyYXBwZXI6ICdyZXNpemUtd3JhcHBlcicsXG4gICAgICogICBoYW5kbGU6ICdyZXNpemUtaGFuZGxlJyxcbiAgICAgKiAgIHJlc2l6aW5nOiAnaXMtcmVzaXppbmcnXG4gICAgICogfVxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIGNsYXNzTmFtZT86IHtcbiAgICAgIC8qKiBDbGFzcyBmb3IgdGhlIG91dGVyIGNvbnRhaW5lciBlbGVtZW50ICovXG4gICAgICBjb250YWluZXI/OiBzdHJpbmdcbiAgICAgIC8qKiBDbGFzcyBmb3IgdGhlIHdyYXBwZXIgZWxlbWVudCB0aGF0IGNvbnRhaW5zIHRoZSByZXNpemFibGUgZWxlbWVudCAqL1xuICAgICAgd3JhcHBlcj86IHN0cmluZ1xuICAgICAgLyoqIENsYXNzIGFwcGxpZWQgdG8gYWxsIHJlc2l6ZSBoYW5kbGVzICovXG4gICAgICBoYW5kbGU/OiBzdHJpbmdcbiAgICAgIC8qKiBDbGFzcyBhZGRlZCB0byBjb250YWluZXIgd2hpbGUgYWN0aXZlbHkgcmVzaXppbmcgKi9cbiAgICAgIHJlc2l6aW5nPzogc3RyaW5nXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3B0aW9uYWwgY2FsbGJhY2sgZm9yIGNyZWF0aW5nIGN1c3RvbSByZXNpemUgaGFuZGxlIGVsZW1lbnRzLlxuICAgICAqXG4gICAgICogVGhpcyBmdW5jdGlvbiBhbGxvd3MgZGV2ZWxvcGVycyB0byBkZWZpbmUgdGhlaXIgb3duIGhhbmRsZSBlbGVtZW50XG4gICAgICogKGUuZy4sIGN1c3RvbSBpY29ucywgY2xhc3Nlcywgb3Igc3R5bGVzKSBmb3IgYSBnaXZlbiByZXNpemUgZGlyZWN0aW9uLlxuICAgICAqIEl0IGlzIGNhbGxlZCBpbnRlcm5hbGx5IGZvciBlYWNoIGhhbmRsZSBkaXJlY3Rpb24uXG4gICAgICpcbiAgICAgKiBAcGFyYW0gZGlyZWN0aW9uIC0gVGhlIGRpcmVjdGlvbiBvZiB0aGUgaGFuZGxlIGJlaW5nIGNyZWF0ZWQgKGUuZy4sICd0b3AnLCAnYm90dG9tLXJpZ2h0JykuXG4gICAgICogQHJldHVybnMgVGhlIGN1c3RvbSBoYW5kbGUgSFRNTEVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGBgYHRzXG4gICAgICogY3JlYXRlQ3VzdG9tSGFuZGxlOiAoZGlyZWN0aW9uKSA9PiB7XG4gICAgICogICBjb25zdCBoYW5kbGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgICAqICAgaGFuZGxlLmRhdGFzZXQucmVzaXplSGFuZGxlID0gZGlyZWN0aW9uXG4gICAgICogICBoYW5kbGUuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnXG4gICAgICogICBoYW5kbGUuY2xhc3NOYW1lID0gJ3RpcHRhcC1jdXN0b20taGFuZGxlJ1xuICAgICAqXG4gICAgICogICBjb25zdCBpc1RvcCA9IGRpcmVjdGlvbi5pbmNsdWRlcygndG9wJylcbiAgICAgKiAgIGNvbnN0IGlzQm90dG9tID0gZGlyZWN0aW9uLmluY2x1ZGVzKCdib3R0b20nKVxuICAgICAqICAgY29uc3QgaXNMZWZ0ID0gZGlyZWN0aW9uLmluY2x1ZGVzKCdsZWZ0JylcbiAgICAgKiAgIGNvbnN0IGlzUmlnaHQgPSBkaXJlY3Rpb24uaW5jbHVkZXMoJ3JpZ2h0JylcbiAgICAgKlxuICAgICAqICAgaWYgKGlzVG9wKSBoYW5kbGUuc3R5bGUudG9wID0gJzAnXG4gICAgICogICBpZiAoaXNCb3R0b20pIGhhbmRsZS5zdHlsZS5ib3R0b20gPSAnMCdcbiAgICAgKiAgIGlmIChpc0xlZnQpIGhhbmRsZS5zdHlsZS5sZWZ0ID0gJzAnXG4gICAgICogICBpZiAoaXNSaWdodCkgaGFuZGxlLnN0eWxlLnJpZ2h0ID0gJzAnXG4gICAgICpcbiAgICAgKiAgIC8vIEVkZ2UgaGFuZGxlcyBzcGFuIHRoZSBmdWxsIHdpZHRoIG9yIGhlaWdodFxuICAgICAqICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3RvcCcgfHwgZGlyZWN0aW9uID09PSAnYm90dG9tJykge1xuICAgICAqICAgICBoYW5kbGUuc3R5bGUubGVmdCA9ICcwJ1xuICAgICAqICAgICBoYW5kbGUuc3R5bGUucmlnaHQgPSAnMCdcbiAgICAgKiAgIH1cbiAgICAgKlxuICAgICAqICAgaWYgKGRpcmVjdGlvbiA9PT0gJ2xlZnQnIHx8IGRpcmVjdGlvbiA9PT0gJ3JpZ2h0Jykge1xuICAgICAqICAgICBoYW5kbGUuc3R5bGUudG9wID0gJzAnXG4gICAgICogICAgIGhhbmRsZS5zdHlsZS5ib3R0b20gPSAnMCdcbiAgICAgKiAgIH1cbiAgICAgKlxuICAgICAqICAgcmV0dXJuIGhhbmRsZVxuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBjcmVhdGVDdXN0b21IYW5kbGU/OiAoZGlyZWN0aW9uOiBSZXNpemFibGVOb2RlVmlld0RpcmVjdGlvbikgPT4gSFRNTEVsZW1lbnRcbiAgfVxufVxuXG4vKipcbiAqIEEgTm9kZVZpZXcgaW1wbGVtZW50YXRpb24gdGhhdCBhZGRzIHJlc2l6ZSBoYW5kbGVzIHRvIGFueSBET00gZWxlbWVudC5cbiAqXG4gKiBUaGlzIGNsYXNzIGNyZWF0ZXMgYSByZXNpemFibGUgbm9kZSB2aWV3IGZvciBUaXB0YXAvUHJvc2VNaXJyb3IgZWRpdG9ycy5cbiAqIEl0IHdyYXBzIHlvdXIgZWxlbWVudCB3aXRoIHJlc2l6ZSBoYW5kbGVzIGFuZCBtYW5hZ2VzIHRoZSByZXNpemUgaW50ZXJhY3Rpb24sXG4gKiBpbmNsdWRpbmcgYXNwZWN0IHJhdGlvIHByZXNlcnZhdGlvbiwgbWluL21heCBjb25zdHJhaW50cywgYW5kIGtleWJvYXJkIG1vZGlmaWVycy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIC8vIEJhc2ljIHVzYWdlIGluIGEgVGlwdGFwIGV4dGVuc2lvblxuICogYWRkTm9kZVZpZXcoKSB7XG4gKiAgIHJldHVybiAoeyBub2RlLCBnZXRQb3MgfSkgPT4ge1xuICogICAgIGNvbnN0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpXG4gKiAgICAgaW1nLnNyYyA9IG5vZGUuYXR0cnMuc3JjXG4gKlxuICogICAgIHJldHVybiBuZXcgUmVzaXphYmxlTm9kZVZpZXcoe1xuICogICAgICAgZWxlbWVudDogaW1nLFxuICogICAgICAgbm9kZSxcbiAqICAgICAgIGdldFBvcyxcbiAqICAgICAgIG9uUmVzaXplOiAod2lkdGgsIGhlaWdodCkgPT4ge1xuICogICAgICAgICBpbWcuc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGBcbiAqICAgICAgICAgaW1nLnN0eWxlLmhlaWdodCA9IGAke2hlaWdodH1weGBcbiAqICAgICAgIH0sXG4gKiAgICAgICBvbkNvbW1pdDogKHdpZHRoLCBoZWlnaHQpID0+IHtcbiAqICAgICAgICAgdGhpcy5lZGl0b3IuY29tbWFuZHMudXBkYXRlQXR0cmlidXRlcygnaW1hZ2UnLCB7IHdpZHRoLCBoZWlnaHQgfSlcbiAqICAgICAgIH0sXG4gKiAgICAgICBvblVwZGF0ZTogKCkgPT4gdHJ1ZSxcbiAqICAgICAgIG9wdGlvbnM6IHtcbiAqICAgICAgICAgbWluOiB7IHdpZHRoOiAxMDAsIGhlaWdodDogMTAwIH0sXG4gKiAgICAgICAgIHByZXNlcnZlQXNwZWN0UmF0aW86IHRydWVcbiAqICAgICAgIH1cbiAqICAgICB9KVxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIFJlc2l6YWJsZU5vZGVWaWV3IHtcbiAgLyoqIFRoZSBQcm9zZU1pcnJvciBub2RlIGluc3RhbmNlICovXG4gIG5vZGU6IFBNTm9kZVxuXG4gIC8qKiBUaGUgVGlwdGFwIGVkaXRvciBpbnN0YW5jZSAqL1xuICBlZGl0b3I6IEVkaXRvclxuXG4gIC8qKiBUaGUgRE9NIGVsZW1lbnQgYmVpbmcgbWFkZSByZXNpemFibGUgKi9cbiAgZWxlbWVudDogSFRNTEVsZW1lbnRcblxuICAvKiogVGhlIGVkaXRhYmxlIERPTSBlbGVtZW50IGluc2lkZSB0aGUgRE9NICovXG4gIGNvbnRlbnRFbGVtZW50PzogSFRNTEVsZW1lbnRcblxuICAvKiogVGhlIG91dGVyIGNvbnRhaW5lciBlbGVtZW50IChyZXR1cm5lZCBhcyBOb2RlVmlldy5kb20pICovXG4gIGNvbnRhaW5lcjogSFRNTEVsZW1lbnRcblxuICAvKiogVGhlIHdyYXBwZXIgZWxlbWVudCB0aGF0IGNvbnRhaW5zIHRoZSBlbGVtZW50IGFuZCBoYW5kbGVzICovXG4gIHdyYXBwZXI6IEhUTUxFbGVtZW50XG5cbiAgLyoqIEZ1bmN0aW9uIHRvIGdldCB0aGUgY3VycmVudCBub2RlIHBvc2l0aW9uICovXG4gIGdldFBvczogKCkgPT4gbnVtYmVyIHwgdW5kZWZpbmVkXG5cbiAgLyoqIENhbGxiYWNrIGZpcmVkIGR1cmluZyByZXNpemUgKi9cbiAgb25SZXNpemU/OiAod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpID0+IHZvaWRcblxuICAvKiogQ2FsbGJhY2sgZmlyZWQgd2hlbiByZXNpemUgY29tcGxldGVzICovXG4gIG9uQ29tbWl0OiAod2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIpID0+IHZvaWRcblxuICAvKiogQ2FsbGJhY2sgZm9yIG5vZGUgdXBkYXRlcyAqL1xuICBvblVwZGF0ZT86IE5vZGVWaWV3Wyd1cGRhdGUnXVxuXG4gIC8qKiBBY3RpdmUgcmVzaXplIGhhbmRsZSBkaXJlY3Rpb25zICovXG4gIGRpcmVjdGlvbnM6IFJlc2l6YWJsZU5vZGVWaWV3RGlyZWN0aW9uW10gPSBbXG4gICAgJ2JvdHRvbS1sZWZ0JyxcbiAgICAnYm90dG9tLXJpZ2h0JyxcbiAgICAndG9wLWxlZnQnLFxuICAgICd0b3AtcmlnaHQnLFxuICBdXG5cbiAgLyoqIE1pbmltdW0gYWxsb3dlZCBkaW1lbnNpb25zICovXG4gIG1pblNpemU6IFJlc2l6YWJsZU5vZGVEaW1lbnNpb25zID0ge1xuICAgIGhlaWdodDogOCxcbiAgICB3aWR0aDogOCxcbiAgfVxuXG4gIC8qKiBNYXhpbXVtIGFsbG93ZWQgZGltZW5zaW9ucyAob3B0aW9uYWwpICovXG4gIG1heFNpemU/OiBQYXJ0aWFsPFJlc2l6YWJsZU5vZGVEaW1lbnNpb25zPlxuXG4gIC8qKiBXaGV0aGVyIHRvIGFsd2F5cyBwcmVzZXJ2ZSBhc3BlY3QgcmF0aW8gKi9cbiAgcHJlc2VydmVBc3BlY3RSYXRpbzogYm9vbGVhbiA9IGZhbHNlXG5cbiAgLyoqIENTUyBjbGFzcyBuYW1lcyBmb3IgZWxlbWVudHMgKi9cbiAgY2xhc3NOYW1lcyA9IHtcbiAgICBjb250YWluZXI6ICcnLFxuICAgIHdyYXBwZXI6ICcnLFxuICAgIGhhbmRsZTogJycsXG4gICAgcmVzaXppbmc6ICcnLFxuICB9XG5cbiAgLyoqIE9wdGlvbmFsIGNhbGxiYWNrIGZvciBjcmVhdGluZyBjdXN0b20gcmVzaXplIGhhbmRsZXMgKi9cbiAgY3JlYXRlQ3VzdG9tSGFuZGxlPzogKGRpcmVjdGlvbjogUmVzaXphYmxlTm9kZVZpZXdEaXJlY3Rpb24pID0+IEhUTUxFbGVtZW50XG5cbiAgLyoqIEluaXRpYWwgd2lkdGggb2YgdGhlIGVsZW1lbnQgKGZvciBhc3BlY3QgcmF0aW8gY2FsY3VsYXRpb24pICovXG4gIHByaXZhdGUgaW5pdGlhbFdpZHRoOiBudW1iZXIgPSAwXG5cbiAgLyoqIEluaXRpYWwgaGVpZ2h0IG9mIHRoZSBlbGVtZW50IChmb3IgYXNwZWN0IHJhdGlvIGNhbGN1bGF0aW9uKSAqL1xuICBwcml2YXRlIGluaXRpYWxIZWlnaHQ6IG51bWJlciA9IDBcblxuICAvKiogQ2FsY3VsYXRlZCBhc3BlY3QgcmF0aW8gKHdpZHRoIC8gaGVpZ2h0KSAqL1xuICBwcml2YXRlIGFzcGVjdFJhdGlvOiBudW1iZXIgPSAxXG5cbiAgLyoqIFdoZXRoZXIgYSByZXNpemUgb3BlcmF0aW9uIGlzIGN1cnJlbnRseSBhY3RpdmUgKi9cbiAgcHJpdmF0ZSBpc1Jlc2l6aW5nOiBib29sZWFuID0gZmFsc2VcblxuICAvKiogVGhlIGhhbmRsZSBjdXJyZW50bHkgYmVpbmcgZHJhZ2dlZCAqL1xuICBwcml2YXRlIGFjdGl2ZUhhbmRsZTogUmVzaXphYmxlTm9kZVZpZXdEaXJlY3Rpb24gfCBudWxsID0gbnVsbFxuXG4gIC8qKiBTdGFydGluZyBtb3VzZSBYIHBvc2l0aW9uIHdoZW4gcmVzaXplIGJlZ2FuICovXG4gIHByaXZhdGUgc3RhcnRYOiBudW1iZXIgPSAwXG5cbiAgLyoqIFN0YXJ0aW5nIG1vdXNlIFkgcG9zaXRpb24gd2hlbiByZXNpemUgYmVnYW4gKi9cbiAgcHJpdmF0ZSBzdGFydFk6IG51bWJlciA9IDBcblxuICAvKiogRWxlbWVudCB3aWR0aCB3aGVuIHJlc2l6ZSBiZWdhbiAqL1xuICBwcml2YXRlIHN0YXJ0V2lkdGg6IG51bWJlciA9IDBcblxuICAvKiogRWxlbWVudCBoZWlnaHQgd2hlbiByZXNpemUgYmVnYW4gKi9cbiAgcHJpdmF0ZSBzdGFydEhlaWdodDogbnVtYmVyID0gMFxuXG4gIC8qKiBXaGV0aGVyIFNoaWZ0IGtleSBpcyBjdXJyZW50bHkgcHJlc3NlZCAoZm9yIHRlbXBvcmFyeSBhc3BlY3QgcmF0aW8gbG9jaykgKi9cbiAgcHJpdmF0ZSBpc1NoaWZ0S2V5UHJlc3NlZDogYm9vbGVhbiA9IGZhbHNlXG5cbiAgLyoqIExhc3Qga25vd24gZWRpdGFibGUgc3RhdGUgb2YgdGhlIGVkaXRvciAqL1xuICBwcml2YXRlIGxhc3RFZGl0YWJsZVN0YXRlOiBib29sZWFuIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkXG5cbiAgLyoqIE1hcCBvZiBoYW5kbGUgZWxlbWVudHMgYnkgZGlyZWN0aW9uICovXG4gIHByaXZhdGUgaGFuZGxlTWFwID0gbmV3IE1hcDxSZXNpemFibGVOb2RlVmlld0RpcmVjdGlvbiwgSFRNTEVsZW1lbnQ+KClcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBSZXNpemFibGVOb2RlVmlldyBpbnN0YW5jZS5cbiAgICpcbiAgICogVGhlIGNvbnN0cnVjdG9yIHNldHMgdXAgdGhlIHJlc2l6ZSBoYW5kbGVzLCBhcHBsaWVzIGluaXRpYWwgc2l6aW5nIGZyb21cbiAgICogbm9kZSBhdHRyaWJ1dGVzLCBhbmQgY29uZmlndXJlcyBhbGwgcmVzaXplIGJlaGF2aW9yIG9wdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciB0aGUgcmVzaXphYmxlIG5vZGUgdmlld1xuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9uczogUmVzaXphYmxlTm9kZVZpZXdPcHRpb25zKSB7XG4gICAgdGhpcy5ub2RlID0gb3B0aW9ucy5ub2RlXG4gICAgdGhpcy5lZGl0b3IgPSBvcHRpb25zLmVkaXRvclxuICAgIHRoaXMuZWxlbWVudCA9IG9wdGlvbnMuZWxlbWVudFxuICAgIHRoaXMuZWxlbWVudC5kcmFnZ2FibGUgPSBmYWxzZVxuICAgIHRoaXMuY29udGVudEVsZW1lbnQgPSBvcHRpb25zLmNvbnRlbnRFbGVtZW50XG5cbiAgICB0aGlzLmdldFBvcyA9IG9wdGlvbnMuZ2V0UG9zXG5cbiAgICB0aGlzLm9uUmVzaXplID0gb3B0aW9ucy5vblJlc2l6ZVxuICAgIHRoaXMub25Db21taXQgPSBvcHRpb25zLm9uQ29tbWl0XG4gICAgdGhpcy5vblVwZGF0ZSA9IG9wdGlvbnMub25VcGRhdGVcblxuICAgIGlmIChvcHRpb25zLm9wdGlvbnM/Lm1pbikge1xuICAgICAgdGhpcy5taW5TaXplID0ge1xuICAgICAgICAuLi50aGlzLm1pblNpemUsXG4gICAgICAgIC4uLm9wdGlvbnMub3B0aW9ucy5taW4sXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMub3B0aW9ucz8ubWF4KSB7XG4gICAgICB0aGlzLm1heFNpemUgPSBvcHRpb25zLm9wdGlvbnMubWF4XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnM/Lm9wdGlvbnM/LmRpcmVjdGlvbnMpIHtcbiAgICAgIHRoaXMuZGlyZWN0aW9ucyA9IG9wdGlvbnMub3B0aW9ucy5kaXJlY3Rpb25zXG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMub3B0aW9ucz8ucHJlc2VydmVBc3BlY3RSYXRpbykge1xuICAgICAgdGhpcy5wcmVzZXJ2ZUFzcGVjdFJhdGlvID0gb3B0aW9ucy5vcHRpb25zLnByZXNlcnZlQXNwZWN0UmF0aW9cbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5vcHRpb25zPy5jbGFzc05hbWUpIHtcbiAgICAgIHRoaXMuY2xhc3NOYW1lcyA9IHtcbiAgICAgICAgY29udGFpbmVyOiBvcHRpb25zLm9wdGlvbnMuY2xhc3NOYW1lLmNvbnRhaW5lciB8fCAnJyxcbiAgICAgICAgd3JhcHBlcjogb3B0aW9ucy5vcHRpb25zLmNsYXNzTmFtZS53cmFwcGVyIHx8ICcnLFxuICAgICAgICBoYW5kbGU6IG9wdGlvbnMub3B0aW9ucy5jbGFzc05hbWUuaGFuZGxlIHx8ICcnLFxuICAgICAgICByZXNpemluZzogb3B0aW9ucy5vcHRpb25zLmNsYXNzTmFtZS5yZXNpemluZyB8fCAnJyxcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5vcHRpb25zPy5jcmVhdGVDdXN0b21IYW5kbGUpIHtcbiAgICAgIHRoaXMuY3JlYXRlQ3VzdG9tSGFuZGxlID0gb3B0aW9ucy5vcHRpb25zLmNyZWF0ZUN1c3RvbUhhbmRsZVxuICAgIH1cblxuICAgIHRoaXMud3JhcHBlciA9IHRoaXMuY3JlYXRlV3JhcHBlcigpXG4gICAgdGhpcy5jb250YWluZXIgPSB0aGlzLmNyZWF0ZUNvbnRhaW5lcigpXG5cbiAgICB0aGlzLmFwcGx5SW5pdGlhbFNpemUoKVxuICAgIHRoaXMuYXR0YWNoSGFuZGxlcygpXG5cbiAgICB0aGlzLmVkaXRvci5vbigndXBkYXRlJywgdGhpcy5oYW5kbGVFZGl0b3JVcGRhdGUuYmluZCh0aGlzKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB0b3AtbGV2ZWwgRE9NIG5vZGUgdGhhdCBzaG91bGQgYmUgcGxhY2VkIGluIHRoZSBlZGl0b3IuXG4gICAqXG4gICAqIFRoaXMgaXMgcmVxdWlyZWQgYnkgdGhlIFByb3NlTWlycm9yIE5vZGVWaWV3IGludGVyZmFjZS4gVGhlIGNvbnRhaW5lclxuICAgKiBpbmNsdWRlcyB0aGUgd3JhcHBlciwgaGFuZGxlcywgYW5kIHRoZSBhY3R1YWwgY29udGVudCBlbGVtZW50LlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgY29udGFpbmVyIGVsZW1lbnQgdG8gYmUgaW5zZXJ0ZWQgaW50byB0aGUgZWRpdG9yXG4gICAqL1xuICBnZXQgZG9tKCkge1xuICAgIHJldHVybiB0aGlzLmNvbnRhaW5lclxuICB9XG5cbiAgZ2V0IGNvbnRlbnRET00oKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZW50RWxlbWVudCA/PyBudWxsXG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUVkaXRvclVwZGF0ZSgpIHtcbiAgICBjb25zdCBpc0VkaXRhYmxlID0gdGhpcy5lZGl0b3IuaXNFZGl0YWJsZVxuXG4gICAgLy8gT25seSBpZiBzdGF0ZSBhY3R1YWxseSBjaGFuZ2VkXG4gICAgaWYgKGlzRWRpdGFibGUgPT09IHRoaXMubGFzdEVkaXRhYmxlU3RhdGUpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMubGFzdEVkaXRhYmxlU3RhdGUgPSBpc0VkaXRhYmxlXG5cbiAgICBpZiAoIWlzRWRpdGFibGUpIHtcbiAgICAgIHRoaXMucmVtb3ZlSGFuZGxlcygpXG4gICAgfSBlbHNlIGlmIChpc0VkaXRhYmxlICYmIHRoaXMuaGFuZGxlTWFwLnNpemUgPT09IDApIHtcbiAgICAgIHRoaXMuYXR0YWNoSGFuZGxlcygpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGxlZCB3aGVuIHRoZSBub2RlJ3MgY29udGVudCBvciBhdHRyaWJ1dGVzIGNoYW5nZS5cbiAgICpcbiAgICogVXBkYXRlcyB0aGUgaW50ZXJuYWwgbm9kZSByZWZlcmVuY2UuIElmIGEgY3VzdG9tIGBvblVwZGF0ZWAgY2FsbGJhY2tcbiAgICogd2FzIHByb3ZpZGVkLCBpdCB3aWxsIGJlIGNhbGxlZCB0byBoYW5kbGUgYWRkaXRpb25hbCB1cGRhdGUgbG9naWMuXG4gICAqXG4gICAqIEBwYXJhbSBub2RlIC0gVGhlIG5ldy91cGRhdGVkIG5vZGVcbiAgICogQHBhcmFtIGRlY29yYXRpb25zIC0gTm9kZSBkZWNvcmF0aW9uc1xuICAgKiBAcGFyYW0gaW5uZXJEZWNvcmF0aW9ucyAtIElubmVyIGRlY29yYXRpb25zXG4gICAqIEByZXR1cm5zIGBmYWxzZWAgaWYgdGhlIG5vZGUgdHlwZSBoYXMgY2hhbmdlZCAocmVxdWlyZXMgZnVsbCByZWJ1aWxkKSwgb3RoZXJ3aXNlIHRoZSByZXN1bHQgb2YgYG9uVXBkYXRlYCBvciBgdHJ1ZWBcbiAgICovXG4gIHVwZGF0ZShcbiAgICBub2RlOiBQTU5vZGUsXG4gICAgZGVjb3JhdGlvbnM6IHJlYWRvbmx5IERlY29yYXRpb25bXSxcbiAgICBpbm5lckRlY29yYXRpb25zOiBEZWNvcmF0aW9uU291cmNlLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAobm9kZS50eXBlICE9PSB0aGlzLm5vZGUudHlwZSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgdGhpcy5ub2RlID0gbm9kZVxuXG4gICAgaWYgKHRoaXMub25VcGRhdGUpIHtcbiAgICAgIHJldHVybiB0aGlzLm9uVXBkYXRlKG5vZGUsIGRlY29yYXRpb25zLCBpbm5lckRlY29yYXRpb25zKVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQ2xlYW51cCBtZXRob2QgY2FsbGVkIHdoZW4gdGhlIG5vZGUgdmlldyBpcyBiZWluZyByZW1vdmVkLlxuICAgKlxuICAgKiBSZW1vdmVzIGFsbCBldmVudCBsaXN0ZW5lcnMgdG8gcHJldmVudCBtZW1vcnkgbGVha3MuIFRoaXMgaXMgcmVxdWlyZWRcbiAgICogYnkgdGhlIFByb3NlTWlycm9yIE5vZGVWaWV3IGludGVyZmFjZS4gSWYgYSByZXNpemUgaXMgYWN0aXZlIHdoZW5cbiAgICogZGVzdHJveSBpcyBjYWxsZWQsIGl0IHdpbGwgYmUgcHJvcGVybHkgY2FuY2VsbGVkLlxuICAgKi9cbiAgZGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy5pc1Jlc2l6aW5nKSB7XG4gICAgICB0aGlzLmNvbnRhaW5lci5kYXRhc2V0LnJlc2l6ZVN0YXRlID0gJ2ZhbHNlJ1xuXG4gICAgICBpZiAodGhpcy5jbGFzc05hbWVzLnJlc2l6aW5nKSB7XG4gICAgICAgIHRoaXMuY29udGFpbmVyLmNsYXNzTGlzdC5yZW1vdmUodGhpcy5jbGFzc05hbWVzLnJlc2l6aW5nKVxuICAgICAgfVxuXG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmhhbmRsZU1vdXNlTW92ZSlcbiAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmhhbmRsZU1vdXNlVXApXG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5oYW5kbGVLZXlEb3duKVxuICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5dXAnLCB0aGlzLmhhbmRsZUtleVVwKVxuICAgICAgdGhpcy5pc1Jlc2l6aW5nID0gZmFsc2VcbiAgICAgIHRoaXMuYWN0aXZlSGFuZGxlID0gbnVsbFxuICAgIH1cblxuICAgIHRoaXMuZWRpdG9yLm9mZigndXBkYXRlJywgdGhpcy5oYW5kbGVFZGl0b3JVcGRhdGUuYmluZCh0aGlzKSlcblxuICAgIHRoaXMuY29udGFpbmVyLnJlbW92ZSgpXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgb3V0ZXIgY29udGFpbmVyIGVsZW1lbnQuXG4gICAqXG4gICAqIFRoZSBjb250YWluZXIgaXMgdGhlIHRvcC1sZXZlbCBlbGVtZW50IHJldHVybmVkIGJ5IHRoZSBOb2RlVmlldyBhbmRcbiAgICogd3JhcHMgdGhlIGVudGlyZSByZXNpemFibGUgbm9kZS4gSXQncyBzZXQgdXAgd2l0aCBmbGV4Ym94IHRvIGhhbmRsZVxuICAgKiBhbGlnbm1lbnQgYW5kIGluY2x1ZGVzIGRhdGEgYXR0cmlidXRlcyBmb3Igc3R5bGluZyBhbmQgaWRlbnRpZmljYXRpb24uXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBjb250YWluZXIgZWxlbWVudFxuICAgKi9cbiAgY3JlYXRlQ29udGFpbmVyKCkge1xuICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICAgIGVsZW1lbnQuZGF0YXNldC5yZXNpemVDb250YWluZXIgPSAnJ1xuICAgIGVsZW1lbnQuZGF0YXNldC5ub2RlID0gdGhpcy5ub2RlLnR5cGUubmFtZVxuICAgIGVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IHRoaXMubm9kZS50eXBlLmlzSW5saW5lID8gJ2lubGluZS1mbGV4JyA6ICdmbGV4J1xuXG4gICAgaWYgKHRoaXMuY2xhc3NOYW1lcy5jb250YWluZXIpIHtcbiAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gdGhpcy5jbGFzc05hbWVzLmNvbnRhaW5lclxuICAgIH1cblxuICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy53cmFwcGVyKVxuXG4gICAgcmV0dXJuIGVsZW1lbnRcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSB3cmFwcGVyIGVsZW1lbnQgdGhhdCBjb250YWlucyB0aGUgY29udGVudCBhbmQgaGFuZGxlcy5cbiAgICpcbiAgICogVGhlIHdyYXBwZXIgdXNlcyByZWxhdGl2ZSBwb3NpdGlvbmluZyBzbyB0aGF0IHJlc2l6ZSBoYW5kbGVzIGNhbiBiZVxuICAgKiBwb3NpdGlvbmVkIGFic29sdXRlbHkgd2l0aGluIGl0LiBUaGlzIGlzIHRoZSBkaXJlY3QgcGFyZW50IG9mIHRoZVxuICAgKiBjb250ZW50IGVsZW1lbnQgYmVpbmcgbWFkZSByZXNpemFibGUuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSB3cmFwcGVyIGVsZW1lbnRcbiAgICovXG4gIGNyZWF0ZVdyYXBwZXIoKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSdcbiAgICBlbGVtZW50LnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snXG4gICAgZWxlbWVudC5kYXRhc2V0LnJlc2l6ZVdyYXBwZXIgPSAnJ1xuXG4gICAgaWYgKHRoaXMuY2xhc3NOYW1lcy53cmFwcGVyKSB7XG4gICAgICBlbGVtZW50LmNsYXNzTmFtZSA9IHRoaXMuY2xhc3NOYW1lcy53cmFwcGVyXG4gICAgfVxuXG4gICAgZWxlbWVudC5hcHBlbmRDaGlsZCh0aGlzLmVsZW1lbnQpXG5cbiAgICByZXR1cm4gZWxlbWVudFxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSByZXNpemUgaGFuZGxlIGVsZW1lbnQgZm9yIGEgc3BlY2lmaWMgZGlyZWN0aW9uLlxuICAgKlxuICAgKiBFYWNoIGhhbmRsZSBpcyBhYnNvbHV0ZWx5IHBvc2l0aW9uZWQgYW5kIGluY2x1ZGVzIGEgZGF0YSBhdHRyaWJ1dGVcbiAgICogaWRlbnRpZnlpbmcgaXRzIGRpcmVjdGlvbiBmb3Igc3R5bGluZyBwdXJwb3Nlcy5cbiAgICpcbiAgICogQHBhcmFtIGRpcmVjdGlvbiAtIFRoZSByZXNpemUgZGlyZWN0aW9uIGZvciB0aGlzIGhhbmRsZVxuICAgKiBAcmV0dXJucyBUaGUgaGFuZGxlIGVsZW1lbnRcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlSGFuZGxlKGRpcmVjdGlvbjogUmVzaXphYmxlTm9kZVZpZXdEaXJlY3Rpb24pOiBIVE1MRWxlbWVudCB7XG4gICAgY29uc3QgaGFuZGxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICBoYW5kbGUuZGF0YXNldC5yZXNpemVIYW5kbGUgPSBkaXJlY3Rpb25cbiAgICBoYW5kbGUuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnXG5cbiAgICBpZiAodGhpcy5jbGFzc05hbWVzLmhhbmRsZSkge1xuICAgICAgaGFuZGxlLmNsYXNzTmFtZSA9IHRoaXMuY2xhc3NOYW1lcy5oYW5kbGVcbiAgICB9XG5cbiAgICByZXR1cm4gaGFuZGxlXG4gIH1cblxuICAvKipcbiAgICogUG9zaXRpb25zIGEgaGFuZGxlIGVsZW1lbnQgYWNjb3JkaW5nIHRvIGl0cyBkaXJlY3Rpb24uXG4gICAqXG4gICAqIENvcm5lciBoYW5kbGVzIChlLmcuLCAndG9wLWxlZnQnKSBhcmUgcG9zaXRpb25lZCBhdCB0aGUgaW50ZXJzZWN0aW9uXG4gICAqIG9mIHR3byBlZGdlcy4gRWRnZSBoYW5kbGVzIChlLmcuLCAndG9wJykgc3BhbiB0aGUgZnVsbCB3aWR0aCBvciBoZWlnaHQuXG4gICAqXG4gICAqIEBwYXJhbSBoYW5kbGUgLSBUaGUgaGFuZGxlIGVsZW1lbnQgdG8gcG9zaXRpb25cbiAgICogQHBhcmFtIGRpcmVjdGlvbiAtIFRoZSBkaXJlY3Rpb24gZGV0ZXJtaW5pbmcgdGhlIHBvc2l0aW9uXG4gICAqL1xuICBwcml2YXRlIHBvc2l0aW9uSGFuZGxlKGhhbmRsZTogSFRNTEVsZW1lbnQsIGRpcmVjdGlvbjogUmVzaXphYmxlTm9kZVZpZXdEaXJlY3Rpb24pOiB2b2lkIHtcbiAgICBjb25zdCBpc1RvcCA9IGRpcmVjdGlvbi5pbmNsdWRlcygndG9wJylcbiAgICBjb25zdCBpc0JvdHRvbSA9IGRpcmVjdGlvbi5pbmNsdWRlcygnYm90dG9tJylcbiAgICBjb25zdCBpc0xlZnQgPSBkaXJlY3Rpb24uaW5jbHVkZXMoJ2xlZnQnKVxuICAgIGNvbnN0IGlzUmlnaHQgPSBkaXJlY3Rpb24uaW5jbHVkZXMoJ3JpZ2h0JylcblxuICAgIGlmIChpc1RvcCkge1xuICAgICAgaGFuZGxlLnN0eWxlLnRvcCA9ICcwJ1xuICAgIH1cblxuICAgIGlmIChpc0JvdHRvbSkge1xuICAgICAgaGFuZGxlLnN0eWxlLmJvdHRvbSA9ICcwJ1xuICAgIH1cblxuICAgIGlmIChpc0xlZnQpIHtcbiAgICAgIGhhbmRsZS5zdHlsZS5sZWZ0ID0gJzAnXG4gICAgfVxuXG4gICAgaWYgKGlzUmlnaHQpIHtcbiAgICAgIGhhbmRsZS5zdHlsZS5yaWdodCA9ICcwJ1xuICAgIH1cblxuICAgIC8vIEVkZ2UgaGFuZGxlcyBzcGFuIHRoZSBmdWxsIHdpZHRoIG9yIGhlaWdodFxuICAgIGlmIChkaXJlY3Rpb24gPT09ICd0b3AnIHx8IGRpcmVjdGlvbiA9PT0gJ2JvdHRvbScpIHtcbiAgICAgIGhhbmRsZS5zdHlsZS5sZWZ0ID0gJzAnXG4gICAgICBoYW5kbGUuc3R5bGUucmlnaHQgPSAnMCdcbiAgICB9XG5cbiAgICBpZiAoZGlyZWN0aW9uID09PSAnbGVmdCcgfHwgZGlyZWN0aW9uID09PSAncmlnaHQnKSB7XG4gICAgICBoYW5kbGUuc3R5bGUudG9wID0gJzAnXG4gICAgICBoYW5kbGUuc3R5bGUuYm90dG9tID0gJzAnXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW5kIGF0dGFjaGVzIGFsbCByZXNpemUgaGFuZGxlcyB0byB0aGUgd3JhcHBlci5cbiAgICpcbiAgICogSXRlcmF0ZXMgdGhyb3VnaCB0aGUgY29uZmlndXJlZCBkaXJlY3Rpb25zLCBjcmVhdGVzIGEgaGFuZGxlIGZvciBlYWNoLFxuICAgKiBwb3NpdGlvbnMgaXQsIGF0dGFjaGVzIHRoZSBtb3VzZWRvd24gbGlzdGVuZXIsIGFuZCBhcHBlbmRzIGl0IHRvIHRoZSBET00uXG4gICAqL1xuICBwcml2YXRlIGF0dGFjaEhhbmRsZXMoKTogdm9pZCB7XG4gICAgdGhpcy5kaXJlY3Rpb25zLmZvckVhY2goZGlyZWN0aW9uID0+IHtcbiAgICAgIGxldCBoYW5kbGU6IEhUTUxFbGVtZW50XG5cbiAgICAgIGlmICh0aGlzLmNyZWF0ZUN1c3RvbUhhbmRsZSkge1xuICAgICAgICBoYW5kbGUgPSB0aGlzLmNyZWF0ZUN1c3RvbUhhbmRsZShkaXJlY3Rpb24pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoYW5kbGUgPSB0aGlzLmNyZWF0ZUhhbmRsZShkaXJlY3Rpb24pXG4gICAgICB9XG5cbiAgICAgIGlmICghKGhhbmRsZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYFtSZXNpemFibGVOb2RlVmlld10gY3JlYXRlQ3VzdG9tSGFuZGxlKFwiJHtkaXJlY3Rpb259XCIpIGRpZCBub3QgcmV0dXJuIGFuIEhUTUxFbGVtZW50LiBGYWxsaW5nIGJhY2sgdG8gZGVmYXVsdCBoYW5kbGUuYCxcbiAgICAgICAgKVxuICAgICAgICBoYW5kbGUgPSB0aGlzLmNyZWF0ZUhhbmRsZShkaXJlY3Rpb24pXG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5jcmVhdGVDdXN0b21IYW5kbGUpIHtcbiAgICAgICAgdGhpcy5wb3NpdGlvbkhhbmRsZShoYW5kbGUsIGRpcmVjdGlvbilcbiAgICAgIH1cblxuICAgICAgaGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIGV2ZW50ID0+IHRoaXMuaGFuZGxlUmVzaXplU3RhcnQoZXZlbnQsIGRpcmVjdGlvbikpXG4gICAgICBoYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGV2ZW50ID0+XG4gICAgICAgIHRoaXMuaGFuZGxlUmVzaXplU3RhcnQoZXZlbnQgYXMgdW5rbm93biBhcyBNb3VzZUV2ZW50LCBkaXJlY3Rpb24pLFxuICAgICAgKVxuXG4gICAgICB0aGlzLmhhbmRsZU1hcC5zZXQoZGlyZWN0aW9uLCBoYW5kbGUpXG5cbiAgICAgIHRoaXMud3JhcHBlci5hcHBlbmRDaGlsZChoYW5kbGUpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGFsbCByZXNpemUgaGFuZGxlcyBmcm9tIHRoZSB3cmFwcGVyLlxuICAgKlxuICAgKiBDbGVhbnMgdXAgdGhlIGhhbmRsZSBtYXAgYW5kIHJlbW92ZXMgZWFjaCBoYW5kbGUgZWxlbWVudCBmcm9tIHRoZSBET00uXG4gICAqL1xuICBwcml2YXRlIHJlbW92ZUhhbmRsZXMoKTogdm9pZCB7XG4gICAgdGhpcy5oYW5kbGVNYXAuZm9yRWFjaChlbCA9PiBlbC5yZW1vdmUoKSlcbiAgICB0aGlzLmhhbmRsZU1hcC5jbGVhcigpXG4gIH1cblxuICAvKipcbiAgICogQXBwbGllcyBpbml0aWFsIHNpemluZyBmcm9tIG5vZGUgYXR0cmlidXRlcyB0byB0aGUgZWxlbWVudC5cbiAgICpcbiAgICogSWYgd2lkdGgvaGVpZ2h0IGF0dHJpYnV0ZXMgZXhpc3Qgb24gdGhlIG5vZGUsIHRoZXkncmUgYXBwbGllZCB0byB0aGUgZWxlbWVudC5cbiAgICogT3RoZXJ3aXNlLCB0aGUgZWxlbWVudCdzIG5hdHVyYWwvY3VycmVudCBkaW1lbnNpb25zIGFyZSBtZWFzdXJlZC4gVGhlIGFzcGVjdFxuICAgKiByYXRpbyBpcyBjYWxjdWxhdGVkIGZvciBsYXRlciB1c2UgaW4gYXNwZWN0LXJhdGlvLXByZXNlcnZpbmcgcmVzaXplcy5cbiAgICovXG4gIHByaXZhdGUgYXBwbHlJbml0aWFsU2l6ZSgpOiB2b2lkIHtcbiAgICBjb25zdCB3aWR0aCA9IHRoaXMubm9kZS5hdHRycy53aWR0aCBhcyBudW1iZXIgfCB1bmRlZmluZWRcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLm5vZGUuYXR0cnMuaGVpZ2h0IGFzIG51bWJlciB8IHVuZGVmaW5lZFxuXG4gICAgaWYgKHdpZHRoKSB7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGBcbiAgICAgIHRoaXMuaW5pdGlhbFdpZHRoID0gd2lkdGhcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pbml0aWFsV2lkdGggPSB0aGlzLmVsZW1lbnQub2Zmc2V0V2lkdGhcbiAgICB9XG5cbiAgICBpZiAoaGVpZ2h0KSB7XG4gICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YFxuICAgICAgdGhpcy5pbml0aWFsSGVpZ2h0ID0gaGVpZ2h0XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaW5pdGlhbEhlaWdodCA9IHRoaXMuZWxlbWVudC5vZmZzZXRIZWlnaHRcbiAgICB9XG5cbiAgICAvLyBDYWxjdWxhdGUgYXNwZWN0IHJhdGlvIGZvciB1c2UgZHVyaW5nIHJlc2l6aW5nXG4gICAgaWYgKHRoaXMuaW5pdGlhbFdpZHRoID4gMCAmJiB0aGlzLmluaXRpYWxIZWlnaHQgPiAwKSB7XG4gICAgICB0aGlzLmFzcGVjdFJhdGlvID0gdGhpcy5pbml0aWFsV2lkdGggLyB0aGlzLmluaXRpYWxIZWlnaHRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhdGVzIGEgcmVzaXplIG9wZXJhdGlvbiB3aGVuIGEgaGFuZGxlIGlzIGNsaWNrZWQuXG4gICAqXG4gICAqIENhcHR1cmVzIHRoZSBzdGFydGluZyBtb3VzZSBwb3NpdGlvbiBhbmQgZWxlbWVudCBkaW1lbnNpb25zLCBzZXRzIHVwXG4gICAqIHRoZSByZXNpemUgc3RhdGUsIGFkZHMgdGhlIHJlc2l6aW5nIGNsYXNzIGFuZCBzdGF0ZSBhdHRyaWJ1dGUsIGFuZFxuICAgKiBhdHRhY2hlcyBkb2N1bWVudC1sZXZlbCBsaXN0ZW5lcnMgZm9yIG1vdXNlIG1vdmVtZW50IGFuZCBrZXlib2FyZCBpbnB1dC5cbiAgICpcbiAgICogQHBhcmFtIGV2ZW50IC0gVGhlIG1vdXNlIGRvd24gZXZlbnRcbiAgICogQHBhcmFtIGRpcmVjdGlvbiAtIFRoZSBkaXJlY3Rpb24gb2YgdGhlIGhhbmRsZSBiZWluZyBkcmFnZ2VkXG4gICAqL1xuICBwcml2YXRlIGhhbmRsZVJlc2l6ZVN0YXJ0KFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCxcbiAgICBkaXJlY3Rpb246IFJlc2l6YWJsZU5vZGVWaWV3RGlyZWN0aW9uLFxuICApOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcblxuICAgIC8vIENhcHR1cmUgaW5pdGlhbCBzdGF0ZVxuICAgIHRoaXMuaXNSZXNpemluZyA9IHRydWVcbiAgICB0aGlzLmFjdGl2ZUhhbmRsZSA9IGRpcmVjdGlvblxuXG4gICAgaWYgKGlzVG91Y2hFdmVudChldmVudCkpIHtcbiAgICAgIHRoaXMuc3RhcnRYID0gZXZlbnQudG91Y2hlc1swXS5jbGllbnRYXG4gICAgICB0aGlzLnN0YXJ0WSA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YXJ0WCA9IGV2ZW50LmNsaWVudFhcbiAgICAgIHRoaXMuc3RhcnRZID0gZXZlbnQuY2xpZW50WVxuICAgIH1cblxuICAgIHRoaXMuc3RhcnRXaWR0aCA9IHRoaXMuZWxlbWVudC5vZmZzZXRXaWR0aFxuICAgIHRoaXMuc3RhcnRIZWlnaHQgPSB0aGlzLmVsZW1lbnQub2Zmc2V0SGVpZ2h0XG5cbiAgICAvLyBSZWNhbGN1bGF0ZSBhc3BlY3QgcmF0aW8gYXQgcmVzaXplIHN0YXJ0IGZvciBhY2N1cmFjeVxuICAgIGlmICh0aGlzLnN0YXJ0V2lkdGggPiAwICYmIHRoaXMuc3RhcnRIZWlnaHQgPiAwKSB7XG4gICAgICB0aGlzLmFzcGVjdFJhdGlvID0gdGhpcy5zdGFydFdpZHRoIC8gdGhpcy5zdGFydEhlaWdodFxuICAgIH1cblxuICAgIGNvbnN0IHBvcyA9IHRoaXMuZ2V0UG9zKClcbiAgICBpZiAocG9zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIFRPRE86IFNlbGVjdCB0aGUgbm9kZSBpbiB0aGUgZWRpdG9yXG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIFVJIHN0YXRlXG4gICAgdGhpcy5jb250YWluZXIuZGF0YXNldC5yZXNpemVTdGF0ZSA9ICd0cnVlJ1xuXG4gICAgaWYgKHRoaXMuY2xhc3NOYW1lcy5yZXNpemluZykge1xuICAgICAgdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LmFkZCh0aGlzLmNsYXNzTmFtZXMucmVzaXppbmcpXG4gICAgfVxuXG4gICAgLy8gQXR0YWNoIGRvY3VtZW50LWxldmVsIGxpc3RlbmVycyBmb3IgcmVzaXplXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5oYW5kbGVNb3VzZU1vdmUpXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgdGhpcy5oYW5kbGVUb3VjaE1vdmUpXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuaGFuZGxlTW91c2VVcClcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5oYW5kbGVLZXlEb3duKVxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGhpcy5oYW5kbGVLZXlVcClcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIG1vdXNlIG1vdmVtZW50IGR1cmluZyBhbiBhY3RpdmUgcmVzaXplLlxuICAgKlxuICAgKiBDYWxjdWxhdGVzIHRoZSBkZWx0YSBmcm9tIHRoZSBzdGFydGluZyBwb3NpdGlvbiwgY29tcHV0ZXMgbmV3IGRpbWVuc2lvbnNcbiAgICogYmFzZWQgb24gdGhlIGFjdGl2ZSBoYW5kbGUgZGlyZWN0aW9uLCBhcHBsaWVzIGNvbnN0cmFpbnRzIGFuZCBhc3BlY3QgcmF0aW8sXG4gICAqIHRoZW4gdXBkYXRlcyB0aGUgZWxlbWVudCdzIHN0eWxlIGFuZCBjYWxscyB0aGUgb25SZXNpemUgY2FsbGJhY2suXG4gICAqXG4gICAqIEBwYXJhbSBldmVudCAtIFRoZSBtb3VzZSBtb3ZlIGV2ZW50XG4gICAqL1xuICBwcml2YXRlIGhhbmRsZU1vdXNlTW92ZSA9IChldmVudDogTW91c2VFdmVudCk6IHZvaWQgPT4ge1xuICAgIGlmICghdGhpcy5pc1Jlc2l6aW5nIHx8ICF0aGlzLmFjdGl2ZUhhbmRsZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgZGVsdGFYID0gZXZlbnQuY2xpZW50WCAtIHRoaXMuc3RhcnRYXG4gICAgY29uc3QgZGVsdGFZID0gZXZlbnQuY2xpZW50WSAtIHRoaXMuc3RhcnRZXG5cbiAgICB0aGlzLmhhbmRsZVJlc2l6ZShkZWx0YVgsIGRlbHRhWSlcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlVG91Y2hNb3ZlID0gKGV2ZW50OiBUb3VjaEV2ZW50KTogdm9pZCA9PiB7XG4gICAgaWYgKCF0aGlzLmlzUmVzaXppbmcgfHwgIXRoaXMuYWN0aXZlSGFuZGxlKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCB0b3VjaCA9IGV2ZW50LnRvdWNoZXNbMF1cbiAgICBpZiAoIXRvdWNoKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBkZWx0YVggPSB0b3VjaC5jbGllbnRYIC0gdGhpcy5zdGFydFhcbiAgICBjb25zdCBkZWx0YVkgPSB0b3VjaC5jbGllbnRZIC0gdGhpcy5zdGFydFlcblxuICAgIHRoaXMuaGFuZGxlUmVzaXplKGRlbHRhWCwgZGVsdGFZKVxuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVSZXNpemUoZGVsdGFYOiBudW1iZXIsIGRlbHRhWTogbnVtYmVyKSB7XG4gICAgaWYgKCF0aGlzLmFjdGl2ZUhhbmRsZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3Qgc2hvdWxkUHJlc2VydmVBc3BlY3RSYXRpbyA9IHRoaXMucHJlc2VydmVBc3BlY3RSYXRpbyB8fCB0aGlzLmlzU2hpZnRLZXlQcmVzc2VkXG4gICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSB0aGlzLmNhbGN1bGF0ZU5ld0RpbWVuc2lvbnModGhpcy5hY3RpdmVIYW5kbGUsIGRlbHRhWCwgZGVsdGFZKVxuICAgIGNvbnN0IGNvbnN0cmFpbmVkID0gdGhpcy5hcHBseUNvbnN0cmFpbnRzKHdpZHRoLCBoZWlnaHQsIHNob3VsZFByZXNlcnZlQXNwZWN0UmF0aW8pXG5cbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUud2lkdGggPSBgJHtjb25zdHJhaW5lZC53aWR0aH1weGBcbiAgICB0aGlzLmVsZW1lbnQuc3R5bGUuaGVpZ2h0ID0gYCR7Y29uc3RyYWluZWQuaGVpZ2h0fXB4YFxuXG4gICAgaWYgKHRoaXMub25SZXNpemUpIHtcbiAgICAgIHRoaXMub25SZXNpemUoY29uc3RyYWluZWQud2lkdGgsIGNvbnN0cmFpbmVkLmhlaWdodClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ29tcGxldGVzIHRoZSByZXNpemUgb3BlcmF0aW9uIHdoZW4gdGhlIG1vdXNlIGJ1dHRvbiBpcyByZWxlYXNlZC5cbiAgICpcbiAgICogQ2FwdHVyZXMgZmluYWwgZGltZW5zaW9ucywgY2FsbHMgdGhlIG9uQ29tbWl0IGNhbGxiYWNrIHRvIHBlcnNpc3QgY2hhbmdlcyxcbiAgICogcmVtb3ZlcyB0aGUgcmVzaXppbmcgc3RhdGUgYW5kIGNsYXNzLCBhbmQgY2xlYW5zIHVwIGRvY3VtZW50LWxldmVsIGxpc3RlbmVycy5cbiAgICovXG4gIHByaXZhdGUgaGFuZGxlTW91c2VVcCA9ICgpOiB2b2lkID0+IHtcbiAgICBpZiAoIXRoaXMuaXNSZXNpemluZykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgZmluYWxXaWR0aCA9IHRoaXMuZWxlbWVudC5vZmZzZXRXaWR0aFxuICAgIGNvbnN0IGZpbmFsSGVpZ2h0ID0gdGhpcy5lbGVtZW50Lm9mZnNldEhlaWdodFxuXG4gICAgdGhpcy5vbkNvbW1pdChmaW5hbFdpZHRoLCBmaW5hbEhlaWdodClcblxuICAgIHRoaXMuaXNSZXNpemluZyA9IGZhbHNlXG4gICAgdGhpcy5hY3RpdmVIYW5kbGUgPSBudWxsXG5cbiAgICAvLyBSZW1vdmUgVUkgc3RhdGVcbiAgICB0aGlzLmNvbnRhaW5lci5kYXRhc2V0LnJlc2l6ZVN0YXRlID0gJ2ZhbHNlJ1xuXG4gICAgaWYgKHRoaXMuY2xhc3NOYW1lcy5yZXNpemluZykge1xuICAgICAgdGhpcy5jb250YWluZXIuY2xhc3NMaXN0LnJlbW92ZSh0aGlzLmNsYXNzTmFtZXMucmVzaXppbmcpXG4gICAgfVxuXG4gICAgLy8gQ2xlYW4gdXAgZG9jdW1lbnQtbGV2ZWwgbGlzdGVuZXJzXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5oYW5kbGVNb3VzZU1vdmUpXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuaGFuZGxlTW91c2VVcClcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5oYW5kbGVLZXlEb3duKVxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleXVwJywgdGhpcy5oYW5kbGVLZXlVcClcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFja3MgU2hpZnQga2V5IHN0YXRlIHRvIGVuYWJsZSB0ZW1wb3JhcnkgYXNwZWN0IHJhdGlvIGxvY2tpbmcuXG4gICAqXG4gICAqIFdoZW4gU2hpZnQgaXMgcHJlc3NlZCBkdXJpbmcgcmVzaXplLCBhc3BlY3QgcmF0aW8gaXMgcHJlc2VydmVkIGV2ZW4gaWZcbiAgICogcHJlc2VydmVBc3BlY3RSYXRpbyBpcyBmYWxzZS5cbiAgICpcbiAgICogQHBhcmFtIGV2ZW50IC0gVGhlIGtleWJvYXJkIGV2ZW50XG4gICAqL1xuICBwcml2YXRlIGhhbmRsZUtleURvd24gPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnU2hpZnQnKSB7XG4gICAgICB0aGlzLmlzU2hpZnRLZXlQcmVzc2VkID0gdHJ1ZVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFja3MgU2hpZnQga2V5IHJlbGVhc2UgdG8gZGlzYWJsZSB0ZW1wb3JhcnkgYXNwZWN0IHJhdGlvIGxvY2tpbmcuXG4gICAqXG4gICAqIEBwYXJhbSBldmVudCAtIFRoZSBrZXlib2FyZCBldmVudFxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVLZXlVcCA9IChldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQgPT4ge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdTaGlmdCcpIHtcbiAgICAgIHRoaXMuaXNTaGlmdEtleVByZXNzZWQgPSBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIG5ldyBkaW1lbnNpb25zIGJhc2VkIG9uIG1vdXNlIGRlbHRhIGFuZCByZXNpemUgZGlyZWN0aW9uLlxuICAgKlxuICAgKiBUYWtlcyB0aGUgc3RhcnRpbmcgZGltZW5zaW9ucyBhbmQgYXBwbGllcyB0aGUgbW91c2UgbW92ZW1lbnQgZGVsdGFcbiAgICogYWNjb3JkaW5nIHRvIHRoZSBoYW5kbGUgZGlyZWN0aW9uLiBGb3IgY29ybmVyIGhhbmRsZXMsIGJvdGggZGltZW5zaW9uc1xuICAgKiBhcmUgYWZmZWN0ZWQuIEZvciBlZGdlIGhhbmRsZXMsIG9ubHkgb25lIGRpbWVuc2lvbiBjaGFuZ2VzLiBJZiBhc3BlY3RcbiAgICogcmF0aW8gc2hvdWxkIGJlIHByZXNlcnZlZCwgZGVsZWdhdGVzIHRvIGFwcGx5QXNwZWN0UmF0aW8uXG4gICAqXG4gICAqIEBwYXJhbSBkaXJlY3Rpb24gLSBUaGUgYWN0aXZlIHJlc2l6ZSBoYW5kbGUgZGlyZWN0aW9uXG4gICAqIEBwYXJhbSBkZWx0YVggLSBIb3Jpem9udGFsIG1vdXNlIG1vdmVtZW50IHNpbmNlIHJlc2l6ZSBzdGFydFxuICAgKiBAcGFyYW0gZGVsdGFZIC0gVmVydGljYWwgbW91c2UgbW92ZW1lbnQgc2luY2UgcmVzaXplIHN0YXJ0XG4gICAqIEByZXR1cm5zIFRoZSBjYWxjdWxhdGVkIHdpZHRoIGFuZCBoZWlnaHRcbiAgICovXG4gIHByaXZhdGUgY2FsY3VsYXRlTmV3RGltZW5zaW9ucyhcbiAgICBkaXJlY3Rpb246IFJlc2l6YWJsZU5vZGVWaWV3RGlyZWN0aW9uLFxuICAgIGRlbHRhWDogbnVtYmVyLFxuICAgIGRlbHRhWTogbnVtYmVyLFxuICApOiBSZXNpemFibGVOb2RlRGltZW5zaW9ucyB7XG4gICAgbGV0IG5ld1dpZHRoID0gdGhpcy5zdGFydFdpZHRoXG4gICAgbGV0IG5ld0hlaWdodCA9IHRoaXMuc3RhcnRIZWlnaHRcblxuICAgIGNvbnN0IGlzUmlnaHQgPSBkaXJlY3Rpb24uaW5jbHVkZXMoJ3JpZ2h0JylcbiAgICBjb25zdCBpc0xlZnQgPSBkaXJlY3Rpb24uaW5jbHVkZXMoJ2xlZnQnKVxuICAgIGNvbnN0IGlzQm90dG9tID0gZGlyZWN0aW9uLmluY2x1ZGVzKCdib3R0b20nKVxuICAgIGNvbnN0IGlzVG9wID0gZGlyZWN0aW9uLmluY2x1ZGVzKCd0b3AnKVxuXG4gICAgLy8gQXBwbHkgaG9yaXpvbnRhbCBkZWx0YVxuICAgIGlmIChpc1JpZ2h0KSB7XG4gICAgICBuZXdXaWR0aCA9IHRoaXMuc3RhcnRXaWR0aCArIGRlbHRhWFxuICAgIH0gZWxzZSBpZiAoaXNMZWZ0KSB7XG4gICAgICBuZXdXaWR0aCA9IHRoaXMuc3RhcnRXaWR0aCAtIGRlbHRhWFxuICAgIH1cblxuICAgIC8vIEFwcGx5IHZlcnRpY2FsIGRlbHRhXG4gICAgaWYgKGlzQm90dG9tKSB7XG4gICAgICBuZXdIZWlnaHQgPSB0aGlzLnN0YXJ0SGVpZ2h0ICsgZGVsdGFZXG4gICAgfSBlbHNlIGlmIChpc1RvcCkge1xuICAgICAgbmV3SGVpZ2h0ID0gdGhpcy5zdGFydEhlaWdodCAtIGRlbHRhWVxuICAgIH1cblxuICAgIC8vIEZvciBwdXJlIGhvcml6b250YWwvdmVydGljYWwgaGFuZGxlcywgb25seSBvbmUgZGltZW5zaW9uIGNoYW5nZXNcbiAgICBpZiAoZGlyZWN0aW9uID09PSAncmlnaHQnIHx8IGRpcmVjdGlvbiA9PT0gJ2xlZnQnKSB7XG4gICAgICBuZXdXaWR0aCA9IHRoaXMuc3RhcnRXaWR0aCArIChpc1JpZ2h0ID8gZGVsdGFYIDogLWRlbHRhWClcbiAgICB9XG5cbiAgICBpZiAoZGlyZWN0aW9uID09PSAndG9wJyB8fCBkaXJlY3Rpb24gPT09ICdib3R0b20nKSB7XG4gICAgICBuZXdIZWlnaHQgPSB0aGlzLnN0YXJ0SGVpZ2h0ICsgKGlzQm90dG9tID8gZGVsdGFZIDogLWRlbHRhWSlcbiAgICB9XG5cbiAgICBjb25zdCBzaG91bGRQcmVzZXJ2ZUFzcGVjdFJhdGlvID0gdGhpcy5wcmVzZXJ2ZUFzcGVjdFJhdGlvIHx8IHRoaXMuaXNTaGlmdEtleVByZXNzZWRcblxuICAgIGlmIChzaG91bGRQcmVzZXJ2ZUFzcGVjdFJhdGlvKSB7XG4gICAgICByZXR1cm4gdGhpcy5hcHBseUFzcGVjdFJhdGlvKG5ld1dpZHRoLCBuZXdIZWlnaHQsIGRpcmVjdGlvbilcbiAgICB9XG5cbiAgICByZXR1cm4geyB3aWR0aDogbmV3V2lkdGgsIGhlaWdodDogbmV3SGVpZ2h0IH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBsaWVzIG1pbi9tYXggY29uc3RyYWludHMgdG8gZGltZW5zaW9ucy5cbiAgICpcbiAgICogV2hlbiBhc3BlY3QgcmF0aW8gaXMgTk9UIHByZXNlcnZlZCwgY29uc3RyYWludHMgYXJlIGFwcGxpZWQgaW5kZXBlbmRlbnRseVxuICAgKiB0byB3aWR0aCBhbmQgaGVpZ2h0LiBXaGVuIGFzcGVjdCByYXRpbyBJUyBwcmVzZXJ2ZWQsIGNvbnN0cmFpbnRzIGFyZVxuICAgKiBhcHBsaWVkIHdoaWxlIG1haW50YWluaW5nIHRoZSBhc3BlY3QgcmF0aW/igJRpZiBvbmUgZGltZW5zaW9uIGhpdHMgYSBsaW1pdCxcbiAgICogdGhlIG90aGVyIGlzIHJlY2FsY3VsYXRlZCBwcm9wb3J0aW9uYWxseS5cbiAgICpcbiAgICogVGhpcyBlbnN1cmVzIHRoYXQgYXNwZWN0IHJhdGlvIGlzIG5ldmVyIGJyb2tlbiB3aGVuIGNvbnN0cmFpbmVkLlxuICAgKlxuICAgKiBAcGFyYW0gd2lkdGggLSBUaGUgdW5jb25zdHJhaW5lZCB3aWR0aFxuICAgKiBAcGFyYW0gaGVpZ2h0IC0gVGhlIHVuY29uc3RyYWluZWQgaGVpZ2h0XG4gICAqIEBwYXJhbSBwcmVzZXJ2ZUFzcGVjdFJhdGlvIC0gV2hldGhlciB0byBtYWludGFpbiBhc3BlY3QgcmF0aW8gd2hpbGUgY29uc3RyYWluaW5nXG4gICAqIEByZXR1cm5zIFRoZSBjb25zdHJhaW5lZCBkaW1lbnNpb25zXG4gICAqL1xuICBwcml2YXRlIGFwcGx5Q29uc3RyYWludHMoXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICBwcmVzZXJ2ZUFzcGVjdFJhdGlvOiBib29sZWFuLFxuICApOiBSZXNpemFibGVOb2RlRGltZW5zaW9ucyB7XG4gICAgaWYgKCFwcmVzZXJ2ZUFzcGVjdFJhdGlvKSB7XG4gICAgICAvLyBJbmRlcGVuZGVudCBjb25zdHJhaW50cyBmb3IgZWFjaCBkaW1lbnNpb25cbiAgICAgIGxldCBjb25zdHJhaW5lZFdpZHRoID0gTWF0aC5tYXgodGhpcy5taW5TaXplLndpZHRoLCB3aWR0aClcbiAgICAgIGxldCBjb25zdHJhaW5lZEhlaWdodCA9IE1hdGgubWF4KHRoaXMubWluU2l6ZS5oZWlnaHQsIGhlaWdodClcblxuICAgICAgaWYgKHRoaXMubWF4U2l6ZT8ud2lkdGgpIHtcbiAgICAgICAgY29uc3RyYWluZWRXaWR0aCA9IE1hdGgubWluKHRoaXMubWF4U2l6ZS53aWR0aCwgY29uc3RyYWluZWRXaWR0aClcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMubWF4U2l6ZT8uaGVpZ2h0KSB7XG4gICAgICAgIGNvbnN0cmFpbmVkSGVpZ2h0ID0gTWF0aC5taW4odGhpcy5tYXhTaXplLmhlaWdodCwgY29uc3RyYWluZWRIZWlnaHQpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7IHdpZHRoOiBjb25zdHJhaW5lZFdpZHRoLCBoZWlnaHQ6IGNvbnN0cmFpbmVkSGVpZ2h0IH1cbiAgICB9XG5cbiAgICAvLyBBc3BlY3QtcmF0aW8tYXdhcmUgY29uc3RyYWludHM6IGFkanVzdCBib3RoIGRpbWVuc2lvbnMgcHJvcG9ydGlvbmFsbHlcbiAgICBsZXQgY29uc3RyYWluZWRXaWR0aCA9IHdpZHRoXG4gICAgbGV0IGNvbnN0cmFpbmVkSGVpZ2h0ID0gaGVpZ2h0XG5cbiAgICAvLyBDaGVjayBtaW5pbXVtIGNvbnN0cmFpbnRzXG4gICAgaWYgKGNvbnN0cmFpbmVkV2lkdGggPCB0aGlzLm1pblNpemUud2lkdGgpIHtcbiAgICAgIGNvbnN0cmFpbmVkV2lkdGggPSB0aGlzLm1pblNpemUud2lkdGhcbiAgICAgIGNvbnN0cmFpbmVkSGVpZ2h0ID0gY29uc3RyYWluZWRXaWR0aCAvIHRoaXMuYXNwZWN0UmF0aW9cbiAgICB9XG5cbiAgICBpZiAoY29uc3RyYWluZWRIZWlnaHQgPCB0aGlzLm1pblNpemUuaGVpZ2h0KSB7XG4gICAgICBjb25zdHJhaW5lZEhlaWdodCA9IHRoaXMubWluU2l6ZS5oZWlnaHRcbiAgICAgIGNvbnN0cmFpbmVkV2lkdGggPSBjb25zdHJhaW5lZEhlaWdodCAqIHRoaXMuYXNwZWN0UmF0aW9cbiAgICB9XG5cbiAgICAvLyBDaGVjayBtYXhpbXVtIGNvbnN0cmFpbnRzXG4gICAgaWYgKHRoaXMubWF4U2l6ZT8ud2lkdGggJiYgY29uc3RyYWluZWRXaWR0aCA+IHRoaXMubWF4U2l6ZS53aWR0aCkge1xuICAgICAgY29uc3RyYWluZWRXaWR0aCA9IHRoaXMubWF4U2l6ZS53aWR0aFxuICAgICAgY29uc3RyYWluZWRIZWlnaHQgPSBjb25zdHJhaW5lZFdpZHRoIC8gdGhpcy5hc3BlY3RSYXRpb1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1heFNpemU/LmhlaWdodCAmJiBjb25zdHJhaW5lZEhlaWdodCA+IHRoaXMubWF4U2l6ZS5oZWlnaHQpIHtcbiAgICAgIGNvbnN0cmFpbmVkSGVpZ2h0ID0gdGhpcy5tYXhTaXplLmhlaWdodFxuICAgICAgY29uc3RyYWluZWRXaWR0aCA9IGNvbnN0cmFpbmVkSGVpZ2h0ICogdGhpcy5hc3BlY3RSYXRpb1xuICAgIH1cblxuICAgIHJldHVybiB7IHdpZHRoOiBjb25zdHJhaW5lZFdpZHRoLCBoZWlnaHQ6IGNvbnN0cmFpbmVkSGVpZ2h0IH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGp1c3RzIGRpbWVuc2lvbnMgdG8gbWFpbnRhaW4gdGhlIG9yaWdpbmFsIGFzcGVjdCByYXRpby5cbiAgICpcbiAgICogRm9yIGhvcml6b250YWwgaGFuZGxlcyAobGVmdC9yaWdodCksIHVzZXMgd2lkdGggYXMgdGhlIHByaW1hcnkgZGltZW5zaW9uXG4gICAqIGFuZCBjYWxjdWxhdGVzIGhlaWdodCBmcm9tIGl0LiBGb3IgdmVydGljYWwgaGFuZGxlcyAodG9wL2JvdHRvbSksIHVzZXNcbiAgICogaGVpZ2h0IGFzIHByaW1hcnkgYW5kIGNhbGN1bGF0ZXMgd2lkdGguIEZvciBjb3JuZXIgaGFuZGxlcywgdXNlcyB3aWR0aFxuICAgKiBhcyB0aGUgcHJpbWFyeSBkaW1lbnNpb24uXG4gICAqXG4gICAqIEBwYXJhbSB3aWR0aCAtIFRoZSBuZXcgd2lkdGhcbiAgICogQHBhcmFtIGhlaWdodCAtIFRoZSBuZXcgaGVpZ2h0XG4gICAqIEBwYXJhbSBkaXJlY3Rpb24gLSBUaGUgYWN0aXZlIHJlc2l6ZSBkaXJlY3Rpb25cbiAgICogQHJldHVybnMgRGltZW5zaW9ucyBhZGp1c3RlZCB0byBwcmVzZXJ2ZSBhc3BlY3QgcmF0aW9cbiAgICovXG4gIHByaXZhdGUgYXBwbHlBc3BlY3RSYXRpbyhcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIGRpcmVjdGlvbjogUmVzaXphYmxlTm9kZVZpZXdEaXJlY3Rpb24sXG4gICk6IFJlc2l6YWJsZU5vZGVEaW1lbnNpb25zIHtcbiAgICBjb25zdCBpc0hvcml6b250YWwgPSBkaXJlY3Rpb24gPT09ICdsZWZ0JyB8fCBkaXJlY3Rpb24gPT09ICdyaWdodCdcbiAgICBjb25zdCBpc1ZlcnRpY2FsID0gZGlyZWN0aW9uID09PSAndG9wJyB8fCBkaXJlY3Rpb24gPT09ICdib3R0b20nXG5cbiAgICBpZiAoaXNIb3Jpem9udGFsKSB7XG4gICAgICAvLyBGb3IgaG9yaXpvbnRhbCByZXNpemUsIHdpZHRoIGlzIHByaW1hcnlcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQ6IHdpZHRoIC8gdGhpcy5hc3BlY3RSYXRpbyxcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNWZXJ0aWNhbCkge1xuICAgICAgLy8gRm9yIHZlcnRpY2FsIHJlc2l6ZSwgaGVpZ2h0IGlzIHByaW1hcnlcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHdpZHRoOiBoZWlnaHQgKiB0aGlzLmFzcGVjdFJhdGlvLFxuICAgICAgICBoZWlnaHQsXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRm9yIGNvcm5lciByZXNpemUsIHdpZHRoIGlzIHByaW1hcnlcbiAgICByZXR1cm4ge1xuICAgICAgd2lkdGgsXG4gICAgICBoZWlnaHQ6IHdpZHRoIC8gdGhpcy5hc3BlY3RSYXRpbyxcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBBbGlhcyBmb3IgUmVzaXphYmxlTm9kZVZpZXcgdG8gbWFpbnRhaW4gY29uc2lzdGVudCBuYW1pbmcuXG4gKiBAZGVwcmVjYXRlZCBVc2UgUmVzaXphYmxlTm9kZVZpZXcgaW5zdGVhZCAtIHdpbGwgYmUgcmVtb3ZlZCBpbiBmdXR1cmUgdmVyc2lvbnMuXG4gKi9cbmV4cG9ydCBjb25zdCBSZXNpemFibGVOb2RldmlldyA9IFJlc2l6YWJsZU5vZGVWaWV3XG4iLCAiLyoqXG4gKiBDb21wYXJlIHR3byBhdHRyaWJ1dGUgb2JqZWN0cyBmb3IgZXF1YWxpdHkuXG4gKiBIYW5kbGVzIG51bGwvdW5kZWZpbmVkIGFuZCBhc3NlcnRzIGtleSBwcmVzZW5jZSBpbiBib3RoIG9iamVjdHMgc28gdGhhdFxuICogYHsgZm9vOiB1bmRlZmluZWQgfWAgYW5kIGB7IGJhcjogdW5kZWZpbmVkIH1gIGFyZSBub3QgdHJlYXRlZCBhcyBlcXVhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF0dHJzRXF1YWwoXG4gIGE6IFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsIHwgdW5kZWZpbmVkLFxuICBiOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IGJvb2xlYW4ge1xuICBpZiAoYSA9PT0gYikge1xuICAgIHJldHVybiB0cnVlXG4gIH1cbiAgaWYgKCFhIHx8ICFiKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBjb25zdCBrZXlzQSA9IE9iamVjdC5rZXlzKGEpXG4gIGNvbnN0IGtleXNCID0gT2JqZWN0LmtleXMoYilcblxuICBpZiAoa2V5c0EubGVuZ3RoICE9PSBrZXlzQi5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiBrZXlzQS5ldmVyeShcbiAgICBrZXkgPT4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIGtleSkgJiYgT2JqZWN0LmlzKGFba2V5XSwgYltrZXldKSxcbiAgKVxufVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgdHlwZSBFZGl0b3JTdGF0ZSwgTm9kZVNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmV4cG9ydCBmdW5jdGlvbiBjYW5JbnNlcnROb2RlKHN0YXRlOiBFZGl0b3JTdGF0ZSwgbm9kZVR5cGU6IE5vZGVUeXBlKTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgc2VsZWN0aW9uIH0gPSBzdGF0ZVxuICBjb25zdCB7ICRmcm9tIH0gPSBzZWxlY3Rpb25cblxuICAvLyBTcGVjaWFsIGhhbmRsaW5nIGZvciBOb2RlU2VsZWN0aW9uXG4gIGlmIChzZWxlY3Rpb24gaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uKSB7XG4gICAgY29uc3QgaW5kZXggPSAkZnJvbS5pbmRleCgpXG4gICAgY29uc3QgcGFyZW50ID0gJGZyb20ucGFyZW50XG5cbiAgICAvLyBDYW4gd2UgcmVwbGFjZSB0aGUgc2VsZWN0ZWQgbm9kZSB3aXRoIHRoZSBob3Jpem9udGFsIHJ1bGU/XG4gICAgcmV0dXJuIHBhcmVudC5jYW5SZXBsYWNlV2l0aChpbmRleCwgaW5kZXggKyAxLCBub2RlVHlwZSlcbiAgfVxuXG4gIC8vIERlZmF1bHQ6IGNoZWNrIGlmIHdlIGNhbiBpbnNlcnQgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb25cbiAgbGV0IGRlcHRoID0gJGZyb20uZGVwdGhcblxuICB3aGlsZSAoZGVwdGggPj0gMCkge1xuICAgIGNvbnN0IGluZGV4ID0gJGZyb20uaW5kZXgoZGVwdGgpXG4gICAgY29uc3QgcGFyZW50ID0gJGZyb20ubm9kZShkZXB0aClcbiAgICBjb25zdCBtYXRjaCA9IHBhcmVudC5jb250ZW50TWF0Y2hBdChpbmRleClcbiAgICBpZiAobWF0Y2gubWF0Y2hUeXBlKG5vZGVUeXBlKSkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gICAgZGVwdGggLT0gMVxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuIiwgIi8vIHNvdXJjZTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzY5Njk0ODZcbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVGb3JSZWdFeChzdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBzdHJpbmcucmVwbGFjZSgvWy0vXFxcXF4kKis/LigpfFtcXF17fV0vZywgJ1xcXFwkJicpXG59XG4iLCAiLyoqXG4gKiBSZWFkIGEgQ1NTIHByb3BlcnR5IHZhbHVlIGRpcmVjdGx5IGZyb20gYW4gZWxlbWVudCdzIHJhdyBpbmxpbmUgYHN0eWxlYFxuICogYXR0cmlidXRlLCBieXBhc3NpbmcgdGhlIENTU09NIChlLmcuIGBlbGVtZW50LnN0eWxlLmZvbnRGYW1pbHlgKSB3aGljaFxuICogY2Fub25pY2FsaXplcyB2YWx1ZXMgYW5kIGNhbiBjaGFuZ2UgZm9ybWF0dGluZy4gVGhlIG9yaWdpbmFsIGZvcm1hdCBpc1xuICogcHJlc2VydmVkIChxdW90ZXMsIGhleCB2cyByZ2IsIGV0Yy4pLlxuICpcbiAqIFdoZW4gYSBwcm9wZXJ0eSBpcyBkZWNsYXJlZCBtb3JlIHRoYW4gb25jZSwgdGhlIGxhc3QgZGVjbGFyYXRpb24gd2lucyDigJRcbiAqIHRoaXMgbWF0Y2hlcyBDU1MgY2FzY2FkZSBvcmRlciBhbmQgaXMgdXNlZnVsIHdoZW4gbmVzdGVkIHNwYW5zIGFyZSBtZXJnZWRcbiAqIGFuZCB0aGUgY2hpbGQncyB2YWx1ZSBzaG91bGQgdGFrZSBwcmlvcml0eS5cbiAqXG4gKiBQcm9wZXJ0eSBuYW1lIGNvbXBhcmlzb24gaXMgY2FzZS1pbnNlbnNpdGl2ZS5cbiAqXG4gKiBAcGFyYW0gZWxlbWVudCAtIFRoZSBlbGVtZW50IHdob3NlIGBzdHlsZWAgYXR0cmlidXRlIHNob3VsZCBiZSByZWFkLlxuICogQHBhcmFtIHByb3BlcnR5TmFtZSAtIFRoZSBDU1MgcHJvcGVydHkgbmFtZSAoZS5nLiBgZm9udC1mYW1pbHlgKS5cbiAqIEByZXR1cm5zIFRoZSByYXcgdmFsdWUgc3RyaW5nLCBvciBgbnVsbGAgaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBwcmVzZW50LlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogcGFyc2VIVE1MOiBlbGVtZW50ID0+IGdldFN0eWxlUHJvcGVydHkoZWxlbWVudCwgJ2ZvbnQtZmFtaWx5JylcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3R5bGVQcm9wZXJ0eShlbGVtZW50OiBIVE1MRWxlbWVudCwgcHJvcGVydHlOYW1lOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgY29uc3Qgc3R5bGVBdHRyID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3N0eWxlJylcblxuICBpZiAoIXN0eWxlQXR0cikge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBjb25zdCBkZWNscyA9IHN0eWxlQXR0clxuICAgIC5zcGxpdCgnOycpXG4gICAgLm1hcChkZWNsID0+IGRlY2wudHJpbSgpKVxuICAgIC5maWx0ZXIoQm9vbGVhbilcblxuICBjb25zdCB0YXJnZXQgPSBwcm9wZXJ0eU5hbWUudG9Mb3dlckNhc2UoKVxuXG4gIGZvciAobGV0IGkgPSBkZWNscy5sZW5ndGggLSAxOyBpID49IDA7IGkgLT0gMSkge1xuICAgIGNvbnN0IGRlY2wgPSBkZWNsc1tpXVxuICAgIGNvbnN0IGNvbG9uSW5kZXggPSBkZWNsLmluZGV4T2YoJzonKVxuXG4gICAgaWYgKGNvbG9uSW5kZXggPT09IC0xKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGNvbnN0IHByb3AgPSBkZWNsLnNsaWNlKDAsIGNvbG9uSW5kZXgpLnRyaW0oKS50b0xvd2VyQ2FzZSgpXG5cbiAgICBpZiAocHJvcCA9PT0gdGFyZ2V0KSB7XG4gICAgICByZXR1cm4gZGVjbC5zbGljZShjb2xvbkluZGV4ICsgMSkudHJpbSgpXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGxcbn1cbiIsICIvKipcbiAqIERlY29kZSBjb21tb24gSFRNTCBlbnRpdGllcyBpbiB0ZXh0IGNvbnRlbnQgc28gdGhleSBkaXNwbGF5IGFzIGxpdGVyYWxcbiAqIGNoYXJhY3RlcnMgaW5zaWRlIHRoZSBlZGl0b3IuICBUaGUgZGVjb2RlIG9yZGVyIG1hdHRlcnM6IGAmYW1wO2AgbXVzdCBiZVxuICogZGVjb2RlZCAqKmxhc3QqKiBzbyB0aGF0IGRvdWJseS1lbmNvZGVkIHNlcXVlbmNlcyBsaWtlIGAmYW1wO2x0O2AgZmlyc3RcbiAqIHN1cnZpdmUgdGhlIGAmbHQ7YCBwYXNzIGFuZCB0aGVuIGNvcnJlY3RseSBiZWNvbWUgYCZsdDtgIChub3QgYDxgKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZUh0bWxFbnRpdGllcyh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dFxuICAgIC5yZXBsYWNlKC8mbHQ7L2csICc8JylcbiAgICAucmVwbGFjZSgvJmd0Oy9nLCAnPicpXG4gICAgLnJlcGxhY2UoLyZxdW90Oy9nLCAnXCInKVxuICAgIC5yZXBsYWNlKC8mYW1wOy9nLCAnJicpXG59XG5cbi8qKlxuICogRW5jb2RlIEhUTUwgc3BlY2lhbCBjaGFyYWN0ZXJzIHNvIHRoZXkgcm91bmR0cmlwIHNhZmVseSB0aHJvdWdoIG1hcmtkb3duLlxuICogYCZgIGlzIGVuY29kZWQgKipmaXJzdCoqIHRvIGF2b2lkIGRvdWJsZS1lbmNvZGluZyB0aGUgYW1wZXJzYW5kIGluIG90aGVyXG4gKiBlbnRpdGllcyAoZS5nLiBgPGAg4oaSIGAmbHQ7YCwgbm90IGAmYW1wO2x0O2ApLlxuICpcbiAqIE5vdGU6IGBcImAgaXMgaW50ZW50aW9uYWxseSBOT1QgZW5jb2RlZCBoZXJlIGJlY2F1c2UgZG91YmxlIHF1b3RlcyBhcmVcbiAqIG9yZGluYXJ5IGNoYXJhY3RlcnMgaW4gbWFya2Rvd24gYW5kIGRvIG5vdCBuZWVkIGVzY2FwaW5nLiAgVGhlIGRlY29kZVxuICogZnVuY3Rpb24gc3RpbGwgaGFuZGxlcyBgJnF1b3Q7YCBiZWNhdXNlIHRoZSBtYXJrZG93biB0b2tlbml6ZXIgbWF5IGVtaXQgaXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVIdG1sRW50aXRpZXModGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHQucmVwbGFjZSgvJi9nLCAnJmFtcDsnKS5yZXBsYWNlKC88L2csICcmbHQ7JykucmVwbGFjZSgvPi9nLCAnJmd0OycpXG59XG4iLCAiLyoqXG4gKiBEZXRlY3RzIGlmIHRoZSBjdXJyZW50IGJyb3dzZXIgaXMgRmlyZWZveC5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgYnJvd3NlciBpcyBGaXJlZm94LCBgZmFsc2VgIG90aGVyd2lzZS5cbiAqIEBleGFtcGxlXG4gKiBpZiAoaXNGaXJlZm94KCkpIHtcbiAqICAgLy8gRmlyZWZveC1zcGVjaWZpYyBoYW5kbGluZ1xuICogfVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNGaXJlZm94KCk6IGJvb2xlYW4ge1xuICByZXR1cm4gdHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgPyAvRmlyZWZveC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSA6IGZhbHNlXG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGlzU3RyaW5nKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBzdHJpbmcge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJ1xufVxuIiwgIi8qKlxuICogQGZpbGVvdmVydmlldyBNYXJrZG93biB1dGlsaXRpZXMgZm9yIGNyZWF0aW5nIHN0YW5kYXJkaXplZCBtYXJrZG93biBzcGVjcy5cbiAqXG4gKiBUaGlzIG1vZHVsZSBwcm92aWRlcyB1dGlsaXRpZXMgZm9yIGNyZWF0aW5nIGNvbXBsZXRlIG1hcmtkb3duIHNwZWNpZmljYXRpb25zXG4gKiBmb3IgZGlmZmVyZW50IHR5cGVzIG9mIG5vZGVzIHVzaW5nIHVuaWZpZWQgc3ludGF4IHBhdHRlcm5zLlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vYXR0cmlidXRlVXRpbHMuanMnXG5leHBvcnQgKiBmcm9tICcuL2NyZWF0ZUF0b21CbG9ja01hcmtkb3duU3BlYy5qcydcbmV4cG9ydCAqIGZyb20gJy4vY3JlYXRlQmxvY2tNYXJrZG93blNwZWMuanMnXG5leHBvcnQgKiBmcm9tICcuL2NyZWF0ZUlubGluZU1hcmtkb3duU3BlYy5qcydcbmV4cG9ydCAqIGZyb20gJy4vcGFyc2VJbmRlbnRlZEJsb2Nrcy5qcydcbmV4cG9ydCAqIGZyb20gJy4vcmVuZGVyTmVzdGVkTWFya2Rvd25Db250ZW50LmpzJ1xuIiwgIi8qKlxuICogQGZpbGVvdmVydmlldyBVdGlsaXR5IGZ1bmN0aW9ucyBmb3IgcGFyc2luZyBhbmQgc2VyaWFsaXppbmcgbWFya2Rvd24gYXR0cmlidXRlcy5cbiAqXG4gKiBUaGVzZSB1dGlsaXRpZXMgaGFuZGxlIHRoZSBjb21tb24gcGF0dGVybnMgZm9yIHBhcnNpbmcgYXR0cmlidXRlIHN0cmluZ3NcbiAqIGluIHZhcmlvdXMgbWFya2Rvd24gc3ludGF4ZXMgbGlrZSBQYW5kb2MgYXR0cmlidXRlcy5cbiAqL1xuXG4vKipcbiAqIFBhcnNlcyBhIFBhbmRvYy1zdHlsZSBhdHRyaWJ1dGUgc3RyaW5nIGludG8gYW4gb2JqZWN0LlxuICpcbiAqIFN1cHBvcnRzIHRoZSBmb2xsb3dpbmcgcGF0dGVybnM6XG4gKiAtIENsYXNzZXM6IGAuY2xhc3NOYW1lYCDihpIgYHsgY2xhc3M6ICdjbGFzc05hbWUnIH1gXG4gKiAtIElEczogYCNteUlkYCDihpIgYHsgaWQ6ICdteUlkJyB9YFxuICogLSBLZXktdmFsdWUgcGFpcnM6IGBrZXk9XCJ2YWx1ZVwiYCDihpIgYHsga2V5OiAndmFsdWUnIH1gXG4gKiAtIEJvb2xlYW4gYXR0cmlidXRlczogYGRpc2FibGVkYCDihpIgYHsgZGlzYWJsZWQ6IHRydWUgfWBcbiAqXG4gKiBAcGFyYW0gYXR0clN0cmluZyAtIFRoZSBhdHRyaWJ1dGUgc3RyaW5nIHRvIHBhcnNlXG4gKiBAcmV0dXJucyBQYXJzZWQgYXR0cmlidXRlcyBvYmplY3RcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIHBhcnNlQXR0cmlidXRlcygnLmJ0biAjc3VibWl0IGRpc2FibGVkIHR5cGU9XCJidXR0b25cIicpXG4gKiAvLyDihpIgeyBjbGFzczogJ2J0bicsIGlkOiAnc3VibWl0JywgZGlzYWJsZWQ6IHRydWUsIHR5cGU6ICdidXR0b24nIH1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VBdHRyaWJ1dGVzKGF0dHJTdHJpbmc6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBpZiAoIWF0dHJTdHJpbmc/LnRyaW0oKSkge1xuICAgIHJldHVybiB7fVxuICB9XG5cbiAgY29uc3QgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9XG5cbiAgLy8gRmlyc3QsIGV4dHJhY3QgYW5kIHJlbW92ZSBxdW90ZWQgc3RyaW5ncyB0byBhdm9pZCBwYXJzaW5nIGNvbnRlbnQgaW5zaWRlIHRoZW1cbiAgY29uc3QgcXVvdGVkU3RyaW5nczogc3RyaW5nW10gPSBbXVxuICBjb25zdCB0ZW1wU3RyaW5nID0gYXR0clN0cmluZy5yZXBsYWNlKC9bXCInXShbXlwiJ10qKVtcIiddL2csIG1hdGNoID0+IHtcbiAgICBxdW90ZWRTdHJpbmdzLnB1c2gobWF0Y2gpXG4gICAgcmV0dXJuIGBfX1FVT1RFRF8ke3F1b3RlZFN0cmluZ3MubGVuZ3RoIC0gMX1fX2BcbiAgfSlcblxuICAvLyBQYXJzZSBjbGFzc2VzICguY2xhc3NOYW1lKSAtIG9ubHkgb3V0c2lkZSBvZiBxdW90ZWQgc3RyaW5nc1xuICBjb25zdCBjbGFzc01hdGNoZXMgPSB0ZW1wU3RyaW5nLm1hdGNoKC8oPzpefFxccylcXC4oW2EtekEtWl1bXFx3LV0qKS9nKVxuICBpZiAoY2xhc3NNYXRjaGVzKSB7XG4gICAgY29uc3QgY2xhc3NlcyA9IGNsYXNzTWF0Y2hlcy5tYXAobWF0Y2ggPT4gbWF0Y2gudHJpbSgpLnNsaWNlKDEpKSAvLyBSZW1vdmUgdGhlIGRvdFxuICAgIGF0dHJpYnV0ZXMuY2xhc3MgPSBjbGFzc2VzLmpvaW4oJyAnKVxuICB9XG5cbiAgLy8gUGFyc2UgSURzICgjbXlJZCkgLSBvbmx5IG91dHNpZGUgb2YgcXVvdGVkIHN0cmluZ3NcbiAgY29uc3QgaWRNYXRjaCA9IHRlbXBTdHJpbmcubWF0Y2goLyg/Ol58XFxzKSMoW2EtekEtWl1bXFx3LV0qKS8pXG4gIGlmIChpZE1hdGNoKSB7XG4gICAgYXR0cmlidXRlcy5pZCA9IGlkTWF0Y2hbMV1cbiAgfVxuXG4gIC8vIFBhcnNlIGtleS12YWx1ZSBwYWlycyAoa2V5PVwidmFsdWVcIiBvciBrZXk9J3ZhbHVlJykgLSByZXN0b3JlIHF1b3RlZCBzdHJpbmdzXG4gIGNvbnN0IGt2UmVnZXggPSAvKFthLXpBLVpdW1xcdy1dKilcXHMqPVxccyooX19RVU9URURfXFxkK19fKS9nXG4gIGNvbnN0IGt2TWF0Y2hlcyA9IEFycmF5LmZyb20odGVtcFN0cmluZy5tYXRjaEFsbChrdlJlZ2V4KSlcbiAga3ZNYXRjaGVzLmZvckVhY2goKFssIGtleSwgcXVvdGVkUmVmXSkgPT4ge1xuICAgIGNvbnN0IHF1b3RlZEluZGV4ID0gcGFyc2VJbnQocXVvdGVkUmVmLm1hdGNoKC9fX1FVT1RFRF8oXFxkKylfXy8pPy5bMV0gfHwgJzAnLCAxMClcbiAgICBjb25zdCBxdW90ZWRWYWx1ZSA9IHF1b3RlZFN0cmluZ3NbcXVvdGVkSW5kZXhdXG4gICAgaWYgKHF1b3RlZFZhbHVlKSB7XG4gICAgICAvLyBSZW1vdmUgdGhlIG91dGVyIHF1b3Rlc1xuICAgICAgYXR0cmlidXRlc1trZXldID0gcXVvdGVkVmFsdWUuc2xpY2UoMSwgLTEpXG4gICAgfVxuICB9KVxuXG4gIC8vIFBhcnNlIGJvb2xlYW4gYXR0cmlidXRlcyAoc3RhbmRhbG9uZSB3b3JkcyB0aGF0IGFyZW4ndCBjbGFzc2VzL0lEcylcbiAgY29uc3QgY2xlYW5TdHJpbmcgPSB0ZW1wU3RyaW5nXG4gICAgLnJlcGxhY2UoLyg/Ol58XFxzKVxcLihbYS16QS1aXVtcXHctXSopL2csICcnKSAvLyBSZW1vdmUgY2xhc3Nlc1xuICAgIC5yZXBsYWNlKC8oPzpefFxccykjKFthLXpBLVpdW1xcdy1dKikvZywgJycpIC8vIFJlbW92ZSBJRHNcbiAgICAucmVwbGFjZSgvKFthLXpBLVpdW1xcdy1dKilcXHMqPVxccypfX1FVT1RFRF9cXGQrX18vZywgJycpIC8vIFJlbW92ZSBrZXktdmFsdWUgcGFpcnNcbiAgICAudHJpbSgpXG5cbiAgaWYgKGNsZWFuU3RyaW5nKSB7XG4gICAgY29uc3QgYm9vbGVhbkF0dHJzID0gY2xlYW5TdHJpbmcuc3BsaXQoL1xccysvKS5maWx0ZXIoQm9vbGVhbilcbiAgICBib29sZWFuQXR0cnMuZm9yRWFjaChhdHRyID0+IHtcbiAgICAgIGlmIChhdHRyLm1hdGNoKC9eW2EtekEtWl1bXFx3LV0qJC8pKSB7XG4gICAgICAgIGF0dHJpYnV0ZXNbYXR0cl0gPSB0cnVlXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBhdHRyaWJ1dGVzXG59XG5cbi8qKlxuICogU2VyaWFsaXplcyBhbiBhdHRyaWJ1dGVzIG9iamVjdCBiYWNrIHRvIGEgUGFuZG9jLXN0eWxlIGF0dHJpYnV0ZSBzdHJpbmcuXG4gKlxuICogQHBhcmFtIGF0dHJpYnV0ZXMgLSBUaGUgYXR0cmlidXRlcyBvYmplY3QgdG8gc2VyaWFsaXplXG4gKiBAcmV0dXJucyBTZXJpYWxpemVkIGF0dHJpYnV0ZSBzdHJpbmdcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIHNlcmlhbGl6ZUF0dHJpYnV0ZXMoeyBjbGFzczogJ2J0biBwcmltYXJ5JywgaWQ6ICdzdWJtaXQnLCBkaXNhYmxlZDogdHJ1ZSwgdHlwZTogJ2J1dHRvbicgfSlcbiAqIC8vIOKGkiAnLmJ0bi5wcmltYXJ5ICNzdWJtaXQgZGlzYWJsZWQgdHlwZT1cImJ1dHRvblwiJ1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVBdHRyaWJ1dGVzKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT4pOiBzdHJpbmcge1xuICBpZiAoIWF0dHJpYnV0ZXMgfHwgT2JqZWN0LmtleXMoYXR0cmlidXRlcykubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXVxuXG4gIC8vIEhhbmRsZSBjbGFzc2VzXG4gIGlmIChhdHRyaWJ1dGVzLmNsYXNzKSB7XG4gICAgY29uc3QgY2xhc3NlcyA9IFN0cmluZyhhdHRyaWJ1dGVzLmNsYXNzKS5zcGxpdCgvXFxzKy8pLmZpbHRlcihCb29sZWFuKVxuICAgIGNsYXNzZXMuZm9yRWFjaChjbHMgPT4gcGFydHMucHVzaChgLiR7Y2xzfWApKVxuICB9XG5cbiAgLy8gSGFuZGxlIElEXG4gIGlmIChhdHRyaWJ1dGVzLmlkKSB7XG4gICAgcGFydHMucHVzaChgIyR7YXR0cmlidXRlcy5pZH1gKVxuICB9XG5cbiAgLy8gSGFuZGxlIG90aGVyIGF0dHJpYnV0ZXNcbiAgT2JqZWN0LmVudHJpZXMoYXR0cmlidXRlcykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgaWYgKGtleSA9PT0gJ2NsYXNzJyB8fCBrZXkgPT09ICdpZCcpIHtcbiAgICAgIHJldHVybiAvLyBBbHJlYWR5IGhhbmRsZWRcbiAgICB9XG5cbiAgICBpZiAodmFsdWUgPT09IHRydWUpIHtcbiAgICAgIC8vIEJvb2xlYW4gYXR0cmlidXRlXG4gICAgICBwYXJ0cy5wdXNoKGtleSlcbiAgICB9IGVsc2UgaWYgKHZhbHVlICE9PSBmYWxzZSAmJiB2YWx1ZSAhPSBudWxsKSB7XG4gICAgICAvLyBLZXktdmFsdWUgYXR0cmlidXRlXG4gICAgICBwYXJ0cy5wdXNoKGAke2tleX09XCIke1N0cmluZyh2YWx1ZSl9XCJgKVxuICAgIH1cbiAgfSlcblxuICByZXR1cm4gcGFydHMuam9pbignICcpXG59XG4iLCAiaW1wb3J0IHR5cGUge1xuICBKU09OQ29udGVudCxcbiAgTWFya2Rvd25QYXJzZUhlbHBlcnMsXG4gIE1hcmtkb3duUGFyc2VSZXN1bHQsXG4gIE1hcmtkb3duVG9rZW4sXG4gIE1hcmtkb3duVG9rZW5pemVyLFxufSBmcm9tICcuLi8uLi90eXBlcy5qcydcbmltcG9ydCB7XG4gIHBhcnNlQXR0cmlidXRlcyBhcyBkZWZhdWx0UGFyc2VBdHRyaWJ1dGVzLFxuICBzZXJpYWxpemVBdHRyaWJ1dGVzIGFzIGRlZmF1bHRTZXJpYWxpemVBdHRyaWJ1dGVzLFxufSBmcm9tICcuL2F0dHJpYnV0ZVV0aWxzLmpzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIEF0b21CbG9ja01hcmtkb3duU3BlY09wdGlvbnMge1xuICAvKiogVGhlIFRpcHRhcCBub2RlIG5hbWUgdGhpcyBzcGVjIGlzIGZvciAqL1xuICBub2RlTmFtZTogc3RyaW5nXG4gIC8qKiBUaGUgbWFya2Rvd24gc3ludGF4IG5hbWUgKGRlZmF1bHRzIHRvIG5vZGVOYW1lIGlmIG5vdCBwcm92aWRlZCkgKi9cbiAgbmFtZT86IHN0cmluZ1xuICAvKiogRnVuY3Rpb24gdG8gcGFyc2UgYXR0cmlidXRlcyBmcm9tIHRva2VuIGF0dHJpYnV0ZSBzdHJpbmcgKi9cbiAgcGFyc2VBdHRyaWJ1dGVzPzogKGF0dHJTdHJpbmc6IHN0cmluZykgPT4gUmVjb3JkPHN0cmluZywgYW55PlxuICAvKiogRnVuY3Rpb24gdG8gc2VyaWFsaXplIGF0dHJpYnV0ZXMgYmFjayB0byBzdHJpbmcgZm9yIHJlbmRlcmluZyAqL1xuICBzZXJpYWxpemVBdHRyaWJ1dGVzPzogKGF0dHJzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBzdHJpbmdcbiAgLyoqIERlZmF1bHQgYXR0cmlidXRlcyB0byBhcHBseSB3aGVuIHBhcnNpbmcgKi9cbiAgZGVmYXVsdEF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gIC8qKiBSZXF1aXJlZCBhdHRyaWJ1dGVzIHRoYXQgbXVzdCBiZSBwcmVzZW50IGZvciBzdWNjZXNzZnVsIHBhcnNpbmcgKi9cbiAgcmVxdWlyZWRBdHRyaWJ1dGVzPzogc3RyaW5nW11cbiAgLyoqIEF0dHJpYnV0ZXMgdGhhdCBhcmUgYWxsb3dlZCB0byBiZSByZW5kZXJlZCBiYWNrIHRvIG1hcmtkb3duICh3aGl0ZWxpc3QpICovXG4gIGFsbG93ZWRBdHRyaWJ1dGVzPzogc3RyaW5nW11cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgY29tcGxldGUgbWFya2Rvd24gc3BlYyBmb3IgYXRvbWljIGJsb2NrIG5vZGVzIHVzaW5nIFBhbmRvYyBzeW50YXguXG4gKlxuICogVGhlIGdlbmVyYXRlZCBzcGVjIGhhbmRsZXM6XG4gKiAtIFBhcnNpbmcgc2VsZi1jbG9zaW5nIGJsb2NrcyB3aXRoIGA6OjpibG9ja05hbWUge2F0dHJpYnV0ZXN9YFxuICogLSBFeHRyYWN0aW5nIGFuZCBwYXJzaW5nIGF0dHJpYnV0ZXNcbiAqIC0gVmFsaWRhdGluZyByZXF1aXJlZCBhdHRyaWJ1dGVzXG4gKiAtIFJlbmRlcmluZyBibG9ja3MgYmFjayB0byBtYXJrZG93blxuICpcbiAqIEBwYXJhbSBvcHRpb25zIC0gQ29uZmlndXJhdGlvbiBmb3IgdGhlIGF0b21pYyBibG9jayBtYXJrZG93biBzcGVjXG4gKiBAcmV0dXJucyBDb21wbGV0ZSBtYXJrZG93biBzcGVjaWZpY2F0aW9uIG9iamVjdFxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogY29uc3QgeW91dHViZVNwZWMgPSBjcmVhdGVBdG9tQmxvY2tNYXJrZG93blNwZWMoe1xuICogICBub2RlTmFtZTogJ3lvdXR1YmUnLFxuICogICByZXF1aXJlZEF0dHJpYnV0ZXM6IFsnc3JjJ10sXG4gKiAgIGRlZmF1bHRBdHRyaWJ1dGVzOiB7IHN0YXJ0OiAwIH0sXG4gKiAgIGFsbG93ZWRBdHRyaWJ1dGVzOiBbJ3NyYycsICdzdGFydCcsICd3aWR0aCcsICdoZWlnaHQnXSAvLyBPbmx5IHRoZXNlIGdldCByZW5kZXJlZCB0byBtYXJrZG93blxuICogfSlcbiAqXG4gKiAvLyBVc2FnZSBpbiBleHRlbnNpb246XG4gKiBleHBvcnQgY29uc3QgWW91dHViZSA9IE5vZGUuY3JlYXRlKHtcbiAqICAgLy8gLi4uIG90aGVyIGNvbmZpZ1xuICogICBtYXJrZG93bjogeW91dHViZVNwZWNcbiAqIH0pXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUF0b21CbG9ja01hcmtkb3duU3BlYyhvcHRpb25zOiBBdG9tQmxvY2tNYXJrZG93blNwZWNPcHRpb25zKToge1xuICBwYXJzZU1hcmtkb3duOiAodG9rZW46IE1hcmtkb3duVG9rZW4sIGg6IE1hcmtkb3duUGFyc2VIZWxwZXJzKSA9PiBNYXJrZG93blBhcnNlUmVzdWx0XG4gIG1hcmtkb3duVG9rZW5pemVyOiBNYXJrZG93blRva2VuaXplclxuICByZW5kZXJNYXJrZG93bjogKG5vZGU6IEpTT05Db250ZW50KSA9PiBzdHJpbmdcbn0ge1xuICBjb25zdCB7XG4gICAgbm9kZU5hbWUsXG4gICAgbmFtZTogbWFya2Rvd25OYW1lLFxuICAgIHBhcnNlQXR0cmlidXRlcyA9IGRlZmF1bHRQYXJzZUF0dHJpYnV0ZXMsXG4gICAgc2VyaWFsaXplQXR0cmlidXRlcyA9IGRlZmF1bHRTZXJpYWxpemVBdHRyaWJ1dGVzLFxuICAgIGRlZmF1bHRBdHRyaWJ1dGVzID0ge30sXG4gICAgcmVxdWlyZWRBdHRyaWJ1dGVzID0gW10sXG4gICAgYWxsb3dlZEF0dHJpYnV0ZXMsXG4gIH0gPSBvcHRpb25zXG5cbiAgLy8gVXNlIG1hcmtkb3duTmFtZSBmb3Igc3ludGF4LCBmYWxsYmFjayB0byBub2RlTmFtZVxuICBjb25zdCBibG9ja05hbWUgPSBtYXJrZG93bk5hbWUgfHwgbm9kZU5hbWVcblxuICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gZmlsdGVyIGF0dHJpYnV0ZXMgYmFzZWQgb24gYWxsb3dsaXN0XG4gIGNvbnN0IGZpbHRlckF0dHJpYnV0ZXMgPSAoYXR0cnM6IFJlY29yZDxzdHJpbmcsIGFueT4pID0+IHtcbiAgICBpZiAoIWFsbG93ZWRBdHRyaWJ1dGVzKSB7XG4gICAgICByZXR1cm4gYXR0cnNcbiAgICB9XG5cbiAgICBjb25zdCBmaWx0ZXJlZDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9XG4gICAgYWxsb3dlZEF0dHJpYnV0ZXMuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgaWYgKGtleSBpbiBhdHRycykge1xuICAgICAgICBmaWx0ZXJlZFtrZXldID0gYXR0cnNba2V5XVxuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIGZpbHRlcmVkXG4gIH1cblxuICByZXR1cm4ge1xuICAgIHBhcnNlTWFya2Rvd246ICh0b2tlbjogTWFya2Rvd25Ub2tlbiwgaDogTWFya2Rvd25QYXJzZUhlbHBlcnMpID0+IHtcbiAgICAgIGNvbnN0IGF0dHJzID0geyAuLi5kZWZhdWx0QXR0cmlidXRlcywgLi4udG9rZW4uYXR0cmlidXRlcyB9XG4gICAgICByZXR1cm4gaC5jcmVhdGVOb2RlKG5vZGVOYW1lLCBhdHRycywgW10pXG4gICAgfSxcblxuICAgIG1hcmtkb3duVG9rZW5pemVyOiB7XG4gICAgICBuYW1lOiBub2RlTmFtZSxcbiAgICAgIGxldmVsOiAnYmxvY2snIGFzIGNvbnN0LFxuICAgICAgc3RhcnQoc3JjOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKGBeOjo6JHtibG9ja05hbWV9KD86XFxcXHN8JClgLCAnbScpXG4gICAgICAgIGNvbnN0IGluZGV4ID0gc3JjLm1hdGNoKHJlZ2V4KT8uaW5kZXhcbiAgICAgICAgcmV0dXJuIGluZGV4ICE9PSB1bmRlZmluZWQgPyBpbmRleCA6IC0xXG4gICAgICB9LFxuICAgICAgdG9rZW5pemUoc3JjLCBfdG9rZW5zLCBfbGV4ZXIpIHtcbiAgICAgICAgLy8gVXNlIG5vbi1nbG9iYWwgcmVnZXggdG8gbWF0Y2ggZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHN0cmluZ1xuICAgICAgICAvLyBJbmNsdWRlIG9wdGlvbmFsIG5ld2xpbmUgdG8gZW5zdXJlIHdlIGNvbnN1bWUgdGhlIGVudGlyZSBsaW5lXG4gICAgICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXjo6OiR7YmxvY2tOYW1lfSg/OlxcXFxzK1xcXFx7KFtefV0qKVxcXFx9KT9cXFxccyo6OjooPzpcXFxcbnwkKWApXG4gICAgICAgIGNvbnN0IG1hdGNoID0gc3JjLm1hdGNoKHJlZ2V4KVxuXG4gICAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIH1cblxuICAgICAgICAvLyBQYXJzZSBhdHRyaWJ1dGVzIGlmIHByZXNlbnRcbiAgICAgICAgY29uc3QgYXR0clN0cmluZyA9IG1hdGNoWzFdIHx8ICcnXG4gICAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBwYXJzZUF0dHJpYnV0ZXMoYXR0clN0cmluZylcblxuICAgICAgICAvLyBWYWxpZGF0ZSByZXF1aXJlZCBhdHRyaWJ1dGVzXG4gICAgICAgIGNvbnN0IG1pc3NpbmdSZXF1aXJlZCA9IHJlcXVpcmVkQXR0cmlidXRlcy5maW5kKHJlcXVpcmVkID0+ICEocmVxdWlyZWQgaW4gYXR0cmlidXRlcykpXG4gICAgICAgIGlmIChtaXNzaW5nUmVxdWlyZWQpIHtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6IG5vZGVOYW1lLFxuICAgICAgICAgIHJhdzogbWF0Y2hbMF0sXG4gICAgICAgICAgYXR0cmlidXRlcyxcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuXG4gICAgcmVuZGVyTWFya2Rvd246IG5vZGUgPT4ge1xuICAgICAgY29uc3QgZmlsdGVyZWRBdHRycyA9IGZpbHRlckF0dHJpYnV0ZXMobm9kZS5hdHRycyB8fCB7fSlcbiAgICAgIGNvbnN0IGF0dHJzID0gc2VyaWFsaXplQXR0cmlidXRlcyhmaWx0ZXJlZEF0dHJzKVxuICAgICAgY29uc3QgYXR0clN0cmluZyA9IGF0dHJzID8gYCB7JHthdHRyc319YCA6ICcnXG5cbiAgICAgIHJldHVybiBgOjo6JHtibG9ja05hbWV9JHthdHRyU3RyaW5nfSA6OjpgXG4gICAgfSxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHtcbiAgSlNPTkNvbnRlbnQsXG4gIE1hcmtkb3duUGFyc2VIZWxwZXJzLFxuICBNYXJrZG93blBhcnNlUmVzdWx0LFxuICBNYXJrZG93blJlbmRlcmVySGVscGVycyxcbiAgTWFya2Rvd25Ub2tlbixcbiAgTWFya2Rvd25Ub2tlbml6ZXIsXG59IGZyb20gJy4uLy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHtcbiAgcGFyc2VBdHRyaWJ1dGVzIGFzIGRlZmF1bHRQYXJzZUF0dHJpYnV0ZXMsXG4gIHNlcmlhbGl6ZUF0dHJpYnV0ZXMgYXMgZGVmYXVsdFNlcmlhbGl6ZUF0dHJpYnV0ZXMsXG59IGZyb20gJy4vYXR0cmlidXRlVXRpbHMuanMnXG5cbmV4cG9ydCBpbnRlcmZhY2UgQmxvY2tNYXJrZG93blNwZWNPcHRpb25zIHtcbiAgLyoqIFRoZSBUaXB0YXAgbm9kZSBuYW1lIHRoaXMgc3BlYyBpcyBmb3IgKi9cbiAgbm9kZU5hbWU6IHN0cmluZ1xuICAvKiogVGhlIG1hcmtkb3duIHN5bnRheCBuYW1lIChkZWZhdWx0cyB0byBub2RlTmFtZSBpZiBub3QgcHJvdmlkZWQpICovXG4gIG5hbWU/OiBzdHJpbmdcbiAgLyoqIEZ1bmN0aW9uIHRvIGV4dHJhY3QgY29udGVudCBmcm9tIHRoZSBub2RlIGZvciBzZXJpYWxpemF0aW9uICovXG4gIGdldENvbnRlbnQ/OiAodG9rZW46IE1hcmtkb3duVG9rZW4pID0+IHN0cmluZ1xuICAvKiogRnVuY3Rpb24gdG8gcGFyc2UgYXR0cmlidXRlcyBmcm9tIHRoZSBhdHRyaWJ1dGUgc3RyaW5nICovXG4gIHBhcnNlQXR0cmlidXRlcz86IChhdHRyU3RyaW5nOiBzdHJpbmcpID0+IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgLyoqIEZ1bmN0aW9uIHRvIHNlcmlhbGl6ZSBhdHRyaWJ1dGVzIHRvIHN0cmluZyAqL1xuICBzZXJpYWxpemVBdHRyaWJ1dGVzPzogKGF0dHJzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBzdHJpbmdcbiAgLyoqIERlZmF1bHQgYXR0cmlidXRlcyB0byBhcHBseSB3aGVuIHBhcnNpbmcgKi9cbiAgZGVmYXVsdEF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gIC8qKiBDb250ZW50IHR5cGU6ICdibG9jaycgYWxsb3dzIHBhcmFncmFwaHMvbGlzdHMvZXRjLCAnaW5saW5lJyBvbmx5IGFsbG93cyBib2xkL2l0YWxpYy9saW5rcy9ldGMgKi9cbiAgY29udGVudD86ICdibG9jaycgfCAnaW5saW5lJ1xuICAvKiogQWxsb3dsaXN0IG9mIGF0dHJpYnV0ZXMgdG8gaW5jbHVkZSBpbiBtYXJrZG93biAoaWYgbm90IHByb3ZpZGVkLCBhbGwgYXR0cmlidXRlcyBhcmUgaW5jbHVkZWQpICovXG4gIGFsbG93ZWRBdHRyaWJ1dGVzPzogc3RyaW5nW11cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgY29tcGxldGUgbWFya2Rvd24gc3BlYyBmb3IgYmxvY2stbGV2ZWwgbm9kZXMgdXNpbmcgUGFuZG9jIHN5bnRheC5cbiAqXG4gKiBUaGUgZ2VuZXJhdGVkIHNwZWMgaGFuZGxlczpcbiAqIC0gUGFyc2luZyBibG9ja3Mgd2l0aCBgOjo6YmxvY2tOYW1lIHthdHRyaWJ1dGVzfWAgc3ludGF4XG4gKiAtIEV4dHJhY3RpbmcgYW5kIHBhcnNpbmcgYXR0cmlidXRlc1xuICogLSBSZW5kZXJpbmcgYmxvY2tzIGJhY2sgdG8gbWFya2Rvd24gd2l0aCBwcm9wZXIgZm9ybWF0dGluZ1xuICogLSBOZXN0ZWQgY29udGVudCBzdXBwb3J0XG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBDb25maWd1cmF0aW9uIGZvciB0aGUgYmxvY2sgbWFya2Rvd24gc3BlY1xuICogQHJldHVybnMgQ29tcGxldGUgbWFya2Rvd24gc3BlY2lmaWNhdGlvbiBvYmplY3RcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGNvbnN0IGNhbGxvdXRTcGVjID0gY3JlYXRlQmxvY2tNYXJrZG93blNwZWMoe1xuICogICBub2RlTmFtZTogJ2NhbGxvdXQnLFxuICogICBkZWZhdWx0QXR0cmlidXRlczogeyB0eXBlOiAnaW5mbycgfSxcbiAqICAgYWxsb3dlZEF0dHJpYnV0ZXM6IFsndHlwZScsICd0aXRsZSddIC8vIE9ubHkgdGhlc2UgZ2V0IHJlbmRlcmVkIHRvIG1hcmtkb3duXG4gKiB9KVxuICpcbiAqIC8vIFVzYWdlIGluIGV4dGVuc2lvbjpcbiAqIGV4cG9ydCBjb25zdCBDYWxsb3V0ID0gTm9kZS5jcmVhdGUoe1xuICogICAvLyAuLi4gb3RoZXIgY29uZmlnXG4gKiAgIG1hcmtkb3duOiBjYWxsb3V0U3BlY1xuICogfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQmxvY2tNYXJrZG93blNwZWMob3B0aW9uczogQmxvY2tNYXJrZG93blNwZWNPcHRpb25zKToge1xuICBwYXJzZU1hcmtkb3duOiAodG9rZW46IE1hcmtkb3duVG9rZW4sIGg6IE1hcmtkb3duUGFyc2VIZWxwZXJzKSA9PiBNYXJrZG93blBhcnNlUmVzdWx0XG4gIG1hcmtkb3duVG9rZW5pemVyOiBNYXJrZG93blRva2VuaXplclxuICByZW5kZXJNYXJrZG93bjogKG5vZGU6IEpTT05Db250ZW50LCBoOiBNYXJrZG93blJlbmRlcmVySGVscGVycykgPT4gc3RyaW5nXG59IHtcbiAgY29uc3Qge1xuICAgIG5vZGVOYW1lLFxuICAgIG5hbWU6IG1hcmtkb3duTmFtZSxcbiAgICBnZXRDb250ZW50LFxuICAgIHBhcnNlQXR0cmlidXRlcyA9IGRlZmF1bHRQYXJzZUF0dHJpYnV0ZXMsXG4gICAgc2VyaWFsaXplQXR0cmlidXRlcyA9IGRlZmF1bHRTZXJpYWxpemVBdHRyaWJ1dGVzLFxuICAgIGRlZmF1bHRBdHRyaWJ1dGVzID0ge30sXG4gICAgY29udGVudCA9ICdibG9jaycsXG4gICAgYWxsb3dlZEF0dHJpYnV0ZXMsXG4gIH0gPSBvcHRpb25zXG5cbiAgLy8gVXNlIG1hcmtkb3duTmFtZSBmb3Igc3ludGF4LCBmYWxsYmFjayB0byBub2RlTmFtZVxuICBjb25zdCBibG9ja05hbWUgPSBtYXJrZG93bk5hbWUgfHwgbm9kZU5hbWVcblxuICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gZmlsdGVyIGF0dHJpYnV0ZXMgYmFzZWQgb24gYWxsb3dsaXN0XG4gIGNvbnN0IGZpbHRlckF0dHJpYnV0ZXMgPSAoYXR0cnM6IFJlY29yZDxzdHJpbmcsIGFueT4pID0+IHtcbiAgICBpZiAoIWFsbG93ZWRBdHRyaWJ1dGVzKSB7XG4gICAgICByZXR1cm4gYXR0cnNcbiAgICB9XG5cbiAgICBjb25zdCBmaWx0ZXJlZDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9XG4gICAgYWxsb3dlZEF0dHJpYnV0ZXMuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgaWYgKGtleSBpbiBhdHRycykge1xuICAgICAgICBmaWx0ZXJlZFtrZXldID0gYXR0cnNba2V5XVxuICAgICAgfVxuICAgIH0pXG4gICAgcmV0dXJuIGZpbHRlcmVkXG4gIH1cblxuICByZXR1cm4ge1xuICAgIHBhcnNlTWFya2Rvd246ICh0b2tlbiwgaCkgPT4ge1xuICAgICAgbGV0IG5vZGVDb250ZW50OiBKU09OQ29udGVudFtdXG5cbiAgICAgIGlmIChnZXRDb250ZW50KSB7XG4gICAgICAgIGNvbnN0IGNvbnRlbnRSZXN1bHQgPSBnZXRDb250ZW50KHRva2VuKVxuICAgICAgICAvLyBJZiBnZXRDb250ZW50IHJldHVybnMgYSBzdHJpbmcsIHdyYXAgaXQgaW4gYSB0ZXh0IG5vZGVcbiAgICAgICAgbm9kZUNvbnRlbnQgPVxuICAgICAgICAgIHR5cGVvZiBjb250ZW50UmVzdWx0ID09PSAnc3RyaW5nJ1xuICAgICAgICAgICAgPyBbeyB0eXBlOiAndGV4dCcsIHRleHQ6IGNvbnRlbnRSZXN1bHQgfV1cbiAgICAgICAgICAgIDogY29udGVudFJlc3VsdFxuICAgICAgfSBlbHNlIGlmIChjb250ZW50ID09PSAnYmxvY2snKSB7XG4gICAgICAgIG5vZGVDb250ZW50ID0gaC5wYXJzZUNoaWxkcmVuKHRva2VuLnRva2VucyB8fCBbXSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vZGVDb250ZW50ID0gaC5wYXJzZUlubGluZSh0b2tlbi50b2tlbnMgfHwgW10pXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGF0dHJzID0geyAuLi5kZWZhdWx0QXR0cmlidXRlcywgLi4udG9rZW4uYXR0cmlidXRlcyB9XG5cbiAgICAgIHJldHVybiBoLmNyZWF0ZU5vZGUobm9kZU5hbWUsIGF0dHJzLCBub2RlQ29udGVudClcbiAgICB9LFxuXG4gICAgbWFya2Rvd25Ub2tlbml6ZXI6IHtcbiAgICAgIG5hbWU6IG5vZGVOYW1lLFxuICAgICAgbGV2ZWw6ICdibG9jaycgYXMgY29uc3QsXG4gICAgICBzdGFydChzcmMpIHtcbiAgICAgICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKGBeOjo6JHtibG9ja05hbWV9YCwgJ20nKVxuICAgICAgICBjb25zdCBpbmRleCA9IHNyYy5tYXRjaChyZWdleCk/LmluZGV4XG4gICAgICAgIHJldHVybiBpbmRleCAhPT0gdW5kZWZpbmVkID8gaW5kZXggOiAtMVxuICAgICAgfSxcbiAgICAgIHRva2VuaXplKHNyYywgX3Rva2VucywgbGV4ZXIpIHtcbiAgICAgICAgLy8gTWF0Y2ggdGhlIG9wZW5pbmcgdGFnIHdpdGggb3B0aW9uYWwgYXR0cmlidXRlc1xuICAgICAgICBjb25zdCBvcGVuaW5nUmVnZXggPSBuZXcgUmVnRXhwKGBeOjo6JHtibG9ja05hbWV9KD86XFxcXHMrXFxcXHsoW159XSopXFxcXH0pP1xcXFxzKlxcXFxuYClcbiAgICAgICAgY29uc3Qgb3BlbmluZ01hdGNoID0gc3JjLm1hdGNoKG9wZW5pbmdSZWdleClcblxuICAgICAgICBpZiAoIW9wZW5pbmdNYXRjaCkge1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IFtvcGVuaW5nVGFnLCBhdHRyU3RyaW5nID0gJyddID0gb3BlbmluZ01hdGNoXG4gICAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBwYXJzZUF0dHJpYnV0ZXMoYXR0clN0cmluZylcblxuICAgICAgICAvLyBGaW5kIHRoZSBtYXRjaGluZyBjbG9zaW5nIHRhZyBieSB0cmFja2luZyBuZXN0aW5nIGxldmVsXG4gICAgICAgIGxldCBsZXZlbCA9IDFcbiAgICAgICAgY29uc3QgcG9zaXRpb24gPSBvcGVuaW5nVGFnLmxlbmd0aFxuICAgICAgICBsZXQgbWF0Y2hlZENvbnRlbnQgPSAnJ1xuXG4gICAgICAgIC8vIFBhdHRlcm4gdG8gbWF0Y2ggYW55IGJsb2NrIG9wZW5pbmcgKDo6OndvcmQpIG9yIGNsb3NpbmcgKDo6OilcbiAgICAgICAgY29uc3QgYmxvY2tQYXR0ZXJuID0gL146OjooW1xcdy1dKikoXFxzLiopPy9nbVxuICAgICAgICBjb25zdCByZW1haW5pbmcgPSBzcmMuc2xpY2UocG9zaXRpb24pXG5cbiAgICAgICAgYmxvY2tQYXR0ZXJuLmxhc3RJbmRleCA9IDBcblxuICAgICAgICAvLyBydW4gdW50aWwgbm8gbW9yZSBtYXRjaGVzIGFyZSBmb3VuZFxuICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgY29uc3QgbWF0Y2ggPSBibG9ja1BhdHRlcm4uZXhlYyhyZW1haW5pbmcpXG4gICAgICAgICAgaWYgKG1hdGNoID09PSBudWxsKSB7XG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBtYXRjaFBvcyA9IG1hdGNoLmluZGV4XG4gICAgICAgICAgY29uc3QgYmxvY2tUeXBlID0gbWF0Y2hbMV0gLy8gRW1wdHkgc3RyaW5nIGZvciBjbG9zaW5nIHRhZywgYmxvY2sgbmFtZSBmb3Igb3BlbmluZ1xuXG4gICAgICAgICAgaWYgKG1hdGNoWzJdPy5lbmRzV2l0aCgnOjo6JykpIHtcbiAgICAgICAgICAgIC8vIHRoaXMgaXMgYW4gYXRvbSA6Ojogbm9kZSwgd2Ugc2tpcCBpdFxuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoYmxvY2tUeXBlKSB7XG4gICAgICAgICAgICAvLyBPcGVuaW5nIHRhZyBmb3VuZCAtIGluY3JlYXNlIGxldmVsXG4gICAgICAgICAgICBsZXZlbCArPSAxXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIENsb3NpbmcgdGFnIGZvdW5kIC0gZGVjcmVhc2UgbGV2ZWxcbiAgICAgICAgICAgIGxldmVsIC09IDFcblxuICAgICAgICAgICAgaWYgKGxldmVsID09PSAwKSB7XG4gICAgICAgICAgICAgIC8vIEZvdW5kIG91ciBtYXRjaGluZyBjbG9zaW5nIHRhZ1xuICAgICAgICAgICAgICAvLyBEb24ndCB0cmltIHlldCAtIGtlZXAgbmV3bGluZXMgZm9yIHRva2VuaXplciByZWdleCBtYXRjaGluZ1xuICAgICAgICAgICAgICBjb25zdCByYXdDb250ZW50ID0gcmVtYWluaW5nLnNsaWNlKDAsIG1hdGNoUG9zKVxuICAgICAgICAgICAgICBtYXRjaGVkQ29udGVudCA9IHJhd0NvbnRlbnQudHJpbSgpXG4gICAgICAgICAgICAgIGNvbnN0IGZ1bGxNYXRjaCA9IHNyYy5zbGljZSgwLCBwb3NpdGlvbiArIG1hdGNoUG9zICsgbWF0Y2hbMF0ubGVuZ3RoKVxuXG4gICAgICAgICAgICAgIC8vIFRva2VuaXplIHRoZSBjb250ZW50XG4gICAgICAgICAgICAgIGxldCBjb250ZW50VG9rZW5zOiBNYXJrZG93blRva2VuW10gPSBbXVxuICAgICAgICAgICAgICBpZiAobWF0Y2hlZENvbnRlbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29udGVudCA9PT0gJ2Jsb2NrJykge1xuICAgICAgICAgICAgICAgICAgLy8gVXNlIHJhd0NvbnRlbnQgZm9yIHRva2VuaXphdGlvbiB0byBwcmVzZXJ2ZSBsaW5lIGJvdW5kYXJpZXMgZm9yIHJlZ2V4IG1hdGNoaW5nXG4gICAgICAgICAgICAgICAgICBjb250ZW50VG9rZW5zID0gbGV4ZXIuYmxvY2tUb2tlbnMocmF3Q29udGVudClcblxuICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgaW5saW5lIHRva2VucyBmb3IgYW55IHRva2VuIHRoYXQgaGFzIHRleHQgY29udGVudCBidXQgbm8gdG9rZW5zXG4gICAgICAgICAgICAgICAgICBjb250ZW50VG9rZW5zLmZvckVhY2godG9rZW4gPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAodG9rZW4udGV4dCAmJiAoIXRva2VuLnRva2VucyB8fCB0b2tlbi50b2tlbnMubGVuZ3RoID09PSAwKSkge1xuICAgICAgICAgICAgICAgICAgICAgIHRva2VuLnRva2VucyA9IGxleGVyLmlubGluZVRva2Vucyh0b2tlbi50ZXh0KVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgICAvLyBDbGVhbiB1cCBlbXB0eSB0cmFpbGluZyBwYXJhZ3JhcGhzXG4gICAgICAgICAgICAgICAgICB3aGlsZSAoY29udGVudFRva2Vucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxhc3RUb2tlbiA9IGNvbnRlbnRUb2tlbnNbY29udGVudFRva2Vucy5sZW5ndGggLSAxXVxuICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgbGFzdFRva2VuLnR5cGUgPT09ICdwYXJhZ3JhcGgnICYmXG4gICAgICAgICAgICAgICAgICAgICAgKCFsYXN0VG9rZW4udGV4dCB8fCBsYXN0VG9rZW4udGV4dC50cmltKCkgPT09ICcnKVxuICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb250ZW50VG9rZW5zLnBvcCgpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBjb250ZW50VG9rZW5zID0gbGV4ZXIuaW5saW5lVG9rZW5zKG1hdGNoZWRDb250ZW50KVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdHlwZTogbm9kZU5hbWUsXG4gICAgICAgICAgICAgICAgcmF3OiBmdWxsTWF0Y2gsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlcyxcbiAgICAgICAgICAgICAgICBjb250ZW50OiBtYXRjaGVkQ29udGVudCxcbiAgICAgICAgICAgICAgICB0b2tlbnM6IGNvbnRlbnRUb2tlbnMsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBObyBtYXRjaGluZyBjbG9zaW5nIHRhZyBmb3VuZFxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICB9LFxuICAgIH0sXG5cbiAgICByZW5kZXJNYXJrZG93bjogKG5vZGUsIGgpID0+IHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkQXR0cnMgPSBmaWx0ZXJBdHRyaWJ1dGVzKG5vZGUuYXR0cnMgfHwge30pXG4gICAgICBjb25zdCBhdHRycyA9IHNlcmlhbGl6ZUF0dHJpYnV0ZXMoZmlsdGVyZWRBdHRycylcbiAgICAgIGNvbnN0IGF0dHJTdHJpbmcgPSBhdHRycyA/IGAgeyR7YXR0cnN9fWAgOiAnJ1xuICAgICAgY29uc3QgcmVuZGVyZWRDb250ZW50ID0gaC5yZW5kZXJDaGlsZHJlbihub2RlLmNvbnRlbnQgfHwgW10sICdcXG5cXG4nKVxuXG4gICAgICByZXR1cm4gYDo6OiR7YmxvY2tOYW1lfSR7YXR0clN0cmluZ31cXG5cXG4ke3JlbmRlcmVkQ29udGVudH1cXG5cXG46OjpgXG4gICAgfSxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHtcbiAgSlNPTkNvbnRlbnQsXG4gIE1hcmtkb3duUGFyc2VIZWxwZXJzLFxuICBNYXJrZG93blBhcnNlUmVzdWx0LFxuICBNYXJrZG93blRva2VuLFxuICBNYXJrZG93blRva2VuaXplcixcbn0gZnJvbSAnLi4vLi4vdHlwZXMuanMnXG5cbi8qKlxuICogUGFyc2Ugc2hvcnRjb2RlIGF0dHJpYnV0ZXMgbGlrZSAnaWQ9XCJtYWRvbm5hXCIgaGFuZGxlPVwiam9oblwiIG5hbWU9XCJKb2huIERvZVwiJ1xuICogUmVxdWlyZXMgYWxsIHZhbHVlcyB0byBiZSBxdW90ZWQgd2l0aCBlaXRoZXIgc2luZ2xlIG9yIGRvdWJsZSBxdW90ZXNcbiAqL1xuZnVuY3Rpb24gcGFyc2VTaG9ydGNvZGVBdHRyaWJ1dGVzKGF0dHJTdHJpbmc6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBpZiAoIWF0dHJTdHJpbmcudHJpbSgpKSB7XG4gICAgcmV0dXJuIHt9XG4gIH1cblxuICBjb25zdCBhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge31cbiAgLy8gTWF0Y2gga2V5PXZhbHVlIHBhaXJzLCBvbmx5IGFjY2VwdGluZyBxdW90ZWQgdmFsdWVzXG4gIGNvbnN0IHJlZ2V4ID0gLyhcXHcrKT0oPzpcIihbXlwiXSopXCJ8JyhbXiddKiknKS9nXG4gIGxldCBtYXRjaCA9IHJlZ2V4LmV4ZWMoYXR0clN0cmluZylcblxuICB3aGlsZSAobWF0Y2ggIT09IG51bGwpIHtcbiAgICBjb25zdCBbLCBrZXksIGRvdWJsZVF1b3RlZCwgc2luZ2xlUXVvdGVkXSA9IG1hdGNoXG4gICAgYXR0cmlidXRlc1trZXldID0gZG91YmxlUXVvdGVkIHx8IHNpbmdsZVF1b3RlZFxuICAgIG1hdGNoID0gcmVnZXguZXhlYyhhdHRyU3RyaW5nKVxuICB9XG5cbiAgcmV0dXJuIGF0dHJpYnV0ZXNcbn1cblxuLyoqXG4gKiBTZXJpYWxpemUgYXR0cmlidXRlcyBiYWNrIHRvIHNob3J0Y29kZSBmb3JtYXRcbiAqIEFsd2F5cyBxdW90ZXMgYWxsIHZhbHVlcyB3aXRoIGRvdWJsZSBxdW90ZXNcbiAqL1xuZnVuY3Rpb24gc2VyaWFsaXplU2hvcnRjb2RlQXR0cmlidXRlcyhhdHRyczogUmVjb3JkPHN0cmluZywgYW55Pik6IHN0cmluZyB7XG4gIHJldHVybiBPYmplY3QuZW50cmllcyhhdHRycylcbiAgICAuZmlsdGVyKChbLCB2YWx1ZV0pID0+IHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwpXG4gICAgLm1hcCgoW2tleSwgdmFsdWVdKSA9PiBgJHtrZXl9PVwiJHt2YWx1ZX1cImApXG4gICAgLmpvaW4oJyAnKVxufVxuXG4vKipcbiAqIENvbmZpZ3VyYXRpb24gZm9yIGFuIGFsbG93ZWQgYXR0cmlidXRlIGluIG1hcmtkb3duIHNlcmlhbGl6YXRpb24uXG4gKiBDYW4gYmUgYSBzaW1wbGUgc3RyaW5nIChhdHRyaWJ1dGUgbmFtZSkgb3IgYW4gb2JqZWN0IHdpdGggYWRkaXRpb25hbCBvcHRpb25zLlxuICovXG5leHBvcnQgdHlwZSBBbGxvd2VkQXR0cmlidXRlID1cbiAgfCBzdHJpbmdcbiAgfCB7XG4gICAgICAvKiogVGhlIGF0dHJpYnV0ZSBuYW1lICovXG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIC8qKlxuICAgICAgICogSWYgcHJvdmlkZWQsIHRoZSBhdHRyaWJ1dGUgd2lsbCBiZSBza2lwcGVkIGR1cmluZyBzZXJpYWxpemF0aW9uIHdoZW4gaXRzIHZhbHVlXG4gICAgICAgKiBlcXVhbHMgdGhpcyBkZWZhdWx0IHZhbHVlLiBUaGlzIGtlZXBzIG1hcmtkb3duIG91dHB1dCBjbGVhbiBieSBvbWl0dGluZ1xuICAgICAgICogYXR0cmlidXRlcyB0aGF0IGhhdmUgdGhlaXIgZGVmYXVsdCB2YWx1ZXMuXG4gICAgICAgKi9cbiAgICAgIHNraXBJZkRlZmF1bHQ/OiBhbnlcbiAgICB9XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5saW5lTWFya2Rvd25TcGVjT3B0aW9ucyB7XG4gIC8qKiBUaGUgVGlwdGFwIG5vZGUgbmFtZSB0aGlzIHNwZWMgaXMgZm9yICovXG4gIG5vZGVOYW1lOiBzdHJpbmdcbiAgLyoqIFRoZSBzaG9ydGNvZGUgbmFtZSAoZGVmYXVsdHMgdG8gbm9kZU5hbWUgaWYgbm90IHByb3ZpZGVkKSAqL1xuICBuYW1lPzogc3RyaW5nXG4gIC8qKiBGdW5jdGlvbiB0byBleHRyYWN0IGNvbnRlbnQgZnJvbSB0aGUgbm9kZSBmb3Igc2VyaWFsaXphdGlvbiAqL1xuICBnZXRDb250ZW50PzogKG5vZGU6IGFueSkgPT4gc3RyaW5nXG4gIC8qKiBGdW5jdGlvbiB0byBwYXJzZSBhdHRyaWJ1dGVzIGZyb20gdGhlIGF0dHJpYnV0ZSBzdHJpbmcgKi9cbiAgcGFyc2VBdHRyaWJ1dGVzPzogKGF0dHJTdHJpbmc6IHN0cmluZykgPT4gUmVjb3JkPHN0cmluZywgYW55PlxuICAvKiogRnVuY3Rpb24gdG8gc2VyaWFsaXplIGF0dHJpYnV0ZXMgdG8gc3RyaW5nICovXG4gIHNlcmlhbGl6ZUF0dHJpYnV0ZXM/OiAoYXR0cnM6IFJlY29yZDxzdHJpbmcsIGFueT4pID0+IHN0cmluZ1xuICAvKiogRGVmYXVsdCBhdHRyaWJ1dGVzIHRvIGFwcGx5IHdoZW4gcGFyc2luZyAqL1xuICBkZWZhdWx0QXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgLyoqIFdoZXRoZXIgdGhpcyBpcyBhIHNlbGYtY2xvc2luZyBzaG9ydGNvZGUgKG5vIGNvbnRlbnQsIGxpa2UgW2Vtb2ppIG5hbWU9cGFydHldKSAqL1xuICBzZWxmQ2xvc2luZz86IGJvb2xlYW5cbiAgLyoqXG4gICAqIEFsbG93bGlzdCBvZiBhdHRyaWJ1dGVzIHRvIGluY2x1ZGUgaW4gbWFya2Rvd24gc2VyaWFsaXphdGlvbi5cbiAgICogSWYgbm90IHByb3ZpZGVkLCBhbGwgYXR0cmlidXRlcyBhcmUgaW5jbHVkZWQuXG4gICAqXG4gICAqIEVhY2ggaXRlbSBjYW4gYmUgZWl0aGVyOlxuICAgKiAtIEEgc3RyaW5nOiB0aGUgYXR0cmlidXRlIG5hbWUgKGFsd2F5cyBpbmNsdWRlZCBpZiBwcmVzZW50KVxuICAgKiAtIEFuIG9iamVjdDogYHsgbmFtZTogc3RyaW5nLCBza2lwSWZEZWZhdWx0PzogYW55IH1gIGZvciBjb25kaXRpb25hbCBpbmNsdXNpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogLy8gU2ltcGxlIHN0cmluZyBhdHRyaWJ1dGVzIChiYWNrd2FyZCBjb21wYXRpYmxlKVxuICAgKiBhbGxvd2VkQXR0cmlidXRlczogWydpZCcsICdsYWJlbCddXG4gICAqXG4gICAqIC8vIE1peGVkIHdpdGggY29uZGl0aW9uYWwgYXR0cmlidXRlc1xuICAgKiBhbGxvd2VkQXR0cmlidXRlczogW1xuICAgKiAgICdpZCcsXG4gICAqICAgJ2xhYmVsJyxcbiAgICogICB7IG5hbWU6ICdtZW50aW9uU3VnZ2VzdGlvbkNoYXInLCBza2lwSWZEZWZhdWx0OiAnQCcgfVxuICAgKiBdXG4gICAqL1xuICBhbGxvd2VkQXR0cmlidXRlcz86IEFsbG93ZWRBdHRyaWJ1dGVbXVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBjb21wbGV0ZSBtYXJrZG93biBzcGVjIGZvciBpbmxpbmUgbm9kZXMgdXNpbmcgYXR0cmlidXRlIHN5bnRheC5cbiAqXG4gKiBUaGUgZ2VuZXJhdGVkIHNwZWMgaGFuZGxlczpcbiAqIC0gUGFyc2luZyBzaG9ydGNvZGUgc3ludGF4IHdpdGggYFtub2RlTmFtZSBhdHRyaWJ1dGVzXWNvbnRlbnRbL25vZGVOYW1lXWAgZm9ybWF0XG4gKiAtIFNlbGYtY2xvc2luZyBzaG9ydGNvZGVzIGxpa2UgYFtlbW9qaSBuYW1lPXBhcnR5X3BvcHBlcl1gXG4gKiAtIEV4dHJhY3RpbmcgYW5kIHBhcnNpbmcgYXR0cmlidXRlcyBmcm9tIHRoZSBvcGVuaW5nIHRhZ1xuICogLSBSZW5kZXJpbmcgaW5saW5lIGVsZW1lbnRzIGJhY2sgdG8gc2hvcnRjb2RlIG1hcmtkb3duXG4gKiAtIFN1cHBvcnRpbmcgYm90aCBjb250ZW50LWJhc2VkIGFuZCBzZWxmLWNsb3NpbmcgaW5saW5lIGVsZW1lbnRzXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBDb25maWd1cmF0aW9uIGZvciB0aGUgaW5saW5lIG1hcmtkb3duIHNwZWNcbiAqIEByZXR1cm5zIENvbXBsZXRlIG1hcmtkb3duIHNwZWNpZmljYXRpb24gb2JqZWN0XG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiAvLyBTZWxmLWNsb3NpbmcgbWVudGlvbjogW21lbnRpb24gaWQ9XCJtYWRvbm5hXCIgbGFiZWw9XCJNYWRvbm5hXCJdXG4gKiBjb25zdCBtZW50aW9uU3BlYyA9IGNyZWF0ZUlubGluZU1hcmtkb3duU3BlYyh7XG4gKiAgIG5vZGVOYW1lOiAnbWVudGlvbicsXG4gKiAgIHNlbGZDbG9zaW5nOiB0cnVlLFxuICogICBkZWZhdWx0QXR0cmlidXRlczogeyB0eXBlOiAndXNlcicgfSxcbiAqICAgYWxsb3dlZEF0dHJpYnV0ZXM6IFsnaWQnLCAnbGFiZWwnXSAvLyBPbmx5IHRoZXNlIGdldCByZW5kZXJlZCB0byBtYXJrZG93blxuICogfSlcbiAqXG4gKiAvLyBTZWxmLWNsb3NpbmcgZW1vamk6IFtlbW9qaSBuYW1lPVwicGFydHlfcG9wcGVyXCJdXG4gKiBjb25zdCBlbW9qaVNwZWMgPSBjcmVhdGVJbmxpbmVNYXJrZG93blNwZWMoe1xuICogICBub2RlTmFtZTogJ2Vtb2ppJyxcbiAqICAgc2VsZkNsb3Npbmc6IHRydWUsXG4gKiAgIGFsbG93ZWRBdHRyaWJ1dGVzOiBbJ25hbWUnXVxuICogfSlcbiAqXG4gKiAvLyBXaXRoIGNvbnRlbnQ6IFtoaWdobGlnaHQgY29sb3I9XCJ5ZWxsb3dcIl10ZXh0Wy9oaWdobGlnaHRdXG4gKiBjb25zdCBoaWdobGlnaHRTcGVjID0gY3JlYXRlSW5saW5lTWFya2Rvd25TcGVjKHtcbiAqICAgbm9kZU5hbWU6ICdoaWdobGlnaHQnLFxuICogICBzZWxmQ2xvc2luZzogZmFsc2UsXG4gKiAgIGFsbG93ZWRBdHRyaWJ1dGVzOiBbJ2NvbG9yJywgJ3N0eWxlJ11cbiAqIH0pXG4gKlxuICogLy8gVXNhZ2UgaW4gZXh0ZW5zaW9uOlxuICogZXhwb3J0IGNvbnN0IE1lbnRpb24gPSBOb2RlLmNyZWF0ZSh7XG4gKiAgIG5hbWU6ICdtZW50aW9uJywgLy8gTXVzdCBtYXRjaCBub2RlTmFtZVxuICogICAvLyAuLi4gb3RoZXIgY29uZmlnXG4gKiAgIG1hcmtkb3duOiBtZW50aW9uU3BlY1xuICogfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSW5saW5lTWFya2Rvd25TcGVjKG9wdGlvbnM6IElubGluZU1hcmtkb3duU3BlY09wdGlvbnMpOiB7XG4gIHBhcnNlTWFya2Rvd246ICh0b2tlbjogTWFya2Rvd25Ub2tlbiwgaDogTWFya2Rvd25QYXJzZUhlbHBlcnMpID0+IE1hcmtkb3duUGFyc2VSZXN1bHRcbiAgbWFya2Rvd25Ub2tlbml6ZXI6IE1hcmtkb3duVG9rZW5pemVyXG4gIHJlbmRlck1hcmtkb3duOiAobm9kZTogSlNPTkNvbnRlbnQpID0+IHN0cmluZ1xufSB7XG4gIGNvbnN0IHtcbiAgICBub2RlTmFtZSxcbiAgICBuYW1lOiBzaG9ydGNvZGVOYW1lLFxuICAgIGdldENvbnRlbnQsXG4gICAgcGFyc2VBdHRyaWJ1dGVzID0gcGFyc2VTaG9ydGNvZGVBdHRyaWJ1dGVzLFxuICAgIHNlcmlhbGl6ZUF0dHJpYnV0ZXMgPSBzZXJpYWxpemVTaG9ydGNvZGVBdHRyaWJ1dGVzLFxuICAgIGRlZmF1bHRBdHRyaWJ1dGVzID0ge30sXG4gICAgc2VsZkNsb3NpbmcgPSBmYWxzZSxcbiAgICBhbGxvd2VkQXR0cmlidXRlcyxcbiAgfSA9IG9wdGlvbnNcblxuICAvLyBVc2Ugc2hvcnRjb2RlTmFtZSBmb3IgbWFya2Rvd24gc3ludGF4LCBmYWxsYmFjayB0byBub2RlTmFtZVxuICBjb25zdCBzaG9ydGNvZGUgPSBzaG9ydGNvZGVOYW1lIHx8IG5vZGVOYW1lXG5cbiAgLy8gSGVscGVyIGZ1bmN0aW9uIHRvIGZpbHRlciBhdHRyaWJ1dGVzIGJhc2VkIG9uIGFsbG93bGlzdFxuICBjb25zdCBmaWx0ZXJBdHRyaWJ1dGVzID0gKGF0dHJzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiB7XG4gICAgaWYgKCFhbGxvd2VkQXR0cmlidXRlcykge1xuICAgICAgcmV0dXJuIGF0dHJzXG4gICAgfVxuXG4gICAgY29uc3QgZmlsdGVyZWQ6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fVxuICAgIGFsbG93ZWRBdHRyaWJ1dGVzLmZvckVhY2goYXR0ciA9PiB7XG4gICAgICAvLyBIYW5kbGUgYm90aCBzdHJpbmcgYW5kIG9iamVjdCBmb3JtYXRzIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XG4gICAgICBjb25zdCBhdHRyTmFtZSA9IHR5cGVvZiBhdHRyID09PSAnc3RyaW5nJyA/IGF0dHIgOiBhdHRyLm5hbWVcbiAgICAgIGNvbnN0IHNraXBJZkRlZmF1bHQgPSB0eXBlb2YgYXR0ciA9PT0gJ3N0cmluZycgPyB1bmRlZmluZWQgOiBhdHRyLnNraXBJZkRlZmF1bHRcblxuICAgICAgaWYgKGF0dHJOYW1lIGluIGF0dHJzKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gYXR0cnNbYXR0ck5hbWVdXG5cbiAgICAgICAgLy8gU2tpcCBpZiB2YWx1ZSBlcXVhbHMgdGhlIGRlZmF1bHQgKHdoZW4gc2tpcElmRGVmYXVsdCBpcyBzcGVjaWZpZWQpXG4gICAgICAgIGlmIChza2lwSWZEZWZhdWx0ICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgPT09IHNraXBJZkRlZmF1bHQpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGZpbHRlcmVkW2F0dHJOYW1lXSA9IHZhbHVlXG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gZmlsdGVyZWRcbiAgfVxuXG4gIC8vIEVzY2FwZSBzcGVjaWFsIHJlZ2V4IGNoYXJhY3RlcnMgaW4gc2hvcnRjb2RlIG5hbWVcbiAgY29uc3QgZXNjYXBlZFNob3J0Y29kZSA9IHNob3J0Y29kZS5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgJ1xcXFwkJicpXG5cbiAgcmV0dXJuIHtcbiAgICBwYXJzZU1hcmtkb3duOiAodG9rZW46IE1hcmtkb3duVG9rZW4sIGg6IE1hcmtkb3duUGFyc2VIZWxwZXJzKSA9PiB7XG4gICAgICBjb25zdCBhdHRycyA9IHsgLi4uZGVmYXVsdEF0dHJpYnV0ZXMsIC4uLnRva2VuLmF0dHJpYnV0ZXMgfVxuXG4gICAgICBpZiAoc2VsZkNsb3NpbmcpIHtcbiAgICAgICAgLy8gU2VsZi1jbG9zaW5nIG5vZGVzIGxpa2UgbWVudGlvbnMgYXJlIGF0b21pYyAtIG5vIGNvbnRlbnRcbiAgICAgICAgcmV0dXJuIGguY3JlYXRlTm9kZShub2RlTmFtZSwgYXR0cnMpXG4gICAgICB9XG5cbiAgICAgIC8vIE5vZGVzIHdpdGggY29udGVudFxuICAgICAgY29uc3QgY29udGVudCA9IGdldENvbnRlbnQgPyBnZXRDb250ZW50KHRva2VuKSA6IHRva2VuLmNvbnRlbnQgfHwgJydcbiAgICAgIGlmIChjb250ZW50KSB7XG4gICAgICAgIC8vIEZvciBpbmxpbmUgY29udGVudCwgY3JlYXRlIHRleHQgbm9kZXMgdXNpbmcgdGhlIHByb3BlciBoZWxwZXJcbiAgICAgICAgcmV0dXJuIGguY3JlYXRlTm9kZShub2RlTmFtZSwgYXR0cnMsIFtoLmNyZWF0ZVRleHROb2RlKGNvbnRlbnQpXSlcbiAgICAgIH1cbiAgICAgIHJldHVybiBoLmNyZWF0ZU5vZGUobm9kZU5hbWUsIGF0dHJzLCBbXSlcbiAgICB9LFxuXG4gICAgbWFya2Rvd25Ub2tlbml6ZXI6IHtcbiAgICAgIG5hbWU6IG5vZGVOYW1lLFxuICAgICAgbGV2ZWw6ICdpbmxpbmUnIGFzIGNvbnN0LFxuICAgICAgc3RhcnQoc3JjOiBzdHJpbmcpIHtcbiAgICAgICAgLy8gQ3JlYXRlIGEgbm9uLWdsb2JhbCB2ZXJzaW9uIGZvciBmaW5kaW5nIHRoZSBzdGFydCBwb3NpdGlvblxuICAgICAgICBjb25zdCBzdGFydFBhdHRlcm4gPSBzZWxmQ2xvc2luZ1xuICAgICAgICAgID8gbmV3IFJlZ0V4cChgXFxcXFske2VzY2FwZWRTaG9ydGNvZGV9XFxcXHMqW15cXFxcXV0qXFxcXF1gKVxuICAgICAgICAgIDogbmV3IFJlZ0V4cChgXFxcXFske2VzY2FwZWRTaG9ydGNvZGV9XFxcXHMqW15cXFxcXV0qXFxcXF1bXFxcXHNcXFxcU10qP1xcXFxbXFxcXC8ke2VzY2FwZWRTaG9ydGNvZGV9XFxcXF1gKVxuXG4gICAgICAgIGNvbnN0IG1hdGNoID0gc3JjLm1hdGNoKHN0YXJ0UGF0dGVybilcbiAgICAgICAgY29uc3QgaW5kZXggPSBtYXRjaD8uaW5kZXhcbiAgICAgICAgcmV0dXJuIGluZGV4ICE9PSB1bmRlZmluZWQgPyBpbmRleCA6IC0xXG4gICAgICB9LFxuICAgICAgdG9rZW5pemUoc3JjLCBfdG9rZW5zLCBfbGV4ZXIpIHtcbiAgICAgICAgLy8gVXNlIG5vbi1nbG9iYWwgcmVnZXggdG8gbWF0Y2ggZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHN0cmluZ1xuICAgICAgICBjb25zdCB0b2tlblBhdHRlcm4gPSBzZWxmQ2xvc2luZ1xuICAgICAgICAgID8gbmV3IFJlZ0V4cChgXlxcXFxbJHtlc2NhcGVkU2hvcnRjb2RlfVxcXFxzKihbXlxcXFxdXSopXFxcXF1gKVxuICAgICAgICAgIDogbmV3IFJlZ0V4cChcbiAgICAgICAgICAgICAgYF5cXFxcWyR7ZXNjYXBlZFNob3J0Y29kZX1cXFxccyooW15cXFxcXV0qKVxcXFxdKFtcXFxcc1xcXFxTXSo/KVxcXFxbXFxcXC8ke2VzY2FwZWRTaG9ydGNvZGV9XFxcXF1gLFxuICAgICAgICAgICAgKVxuXG4gICAgICAgIGNvbnN0IG1hdGNoID0gc3JjLm1hdGNoKHRva2VuUGF0dGVybilcblxuICAgICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNvbnRlbnQgPSAnJ1xuICAgICAgICBsZXQgYXR0clN0cmluZyA9ICcnXG5cbiAgICAgICAgaWYgKHNlbGZDbG9zaW5nKSB7XG4gICAgICAgICAgLy8gU2VsZi1jbG9zaW5nOiBbc2hvcnRjb2RlIGF0dHI9XCJ2YWx1ZVwiXVxuICAgICAgICAgIGNvbnN0IFssIGF0dHJzXSA9IG1hdGNoXG4gICAgICAgICAgYXR0clN0cmluZyA9IGF0dHJzXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gV2l0aCBjb250ZW50OiBbc2hvcnRjb2RlIGF0dHI9XCJ2YWx1ZVwiXWNvbnRlbnRbL3Nob3J0Y29kZV1cbiAgICAgICAgICBjb25zdCBbLCBhdHRycywgY29udGVudE1hdGNoXSA9IG1hdGNoXG4gICAgICAgICAgYXR0clN0cmluZyA9IGF0dHJzXG4gICAgICAgICAgY29udGVudCA9IGNvbnRlbnRNYXRjaCB8fCAnJ1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUGFyc2UgYXR0cmlidXRlcyBmcm9tIHRoZSBhdHRyaWJ1dGUgc3RyaW5nXG4gICAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBwYXJzZUF0dHJpYnV0ZXMoYXR0clN0cmluZy50cmltKCkpXG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlOiBub2RlTmFtZSxcbiAgICAgICAgICByYXc6IG1hdGNoWzBdLFxuICAgICAgICAgIGNvbnRlbnQ6IGNvbnRlbnQudHJpbSgpLFxuICAgICAgICAgIGF0dHJpYnV0ZXMsXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcblxuICAgIHJlbmRlck1hcmtkb3duOiAobm9kZTogSlNPTkNvbnRlbnQpID0+IHtcbiAgICAgIGxldCBjb250ZW50ID0gJydcbiAgICAgIGlmIChnZXRDb250ZW50KSB7XG4gICAgICAgIGNvbnRlbnQgPSBnZXRDb250ZW50KG5vZGUpXG4gICAgICB9IGVsc2UgaWYgKG5vZGUuY29udGVudCAmJiBub2RlLmNvbnRlbnQubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyBFeHRyYWN0IHRleHQgZnJvbSBjb250ZW50IGFycmF5IGZvciBpbmxpbmUgbm9kZXNcbiAgICAgICAgY29udGVudCA9IG5vZGUuY29udGVudFxuICAgICAgICAgIC5maWx0ZXIoKGNoaWxkOiBhbnkpID0+IGNoaWxkLnR5cGUgPT09ICd0ZXh0JylcbiAgICAgICAgICAubWFwKChjaGlsZDogYW55KSA9PiBjaGlsZC50ZXh0KVxuICAgICAgICAgIC5qb2luKCcnKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBmaWx0ZXJlZEF0dHJzID0gZmlsdGVyQXR0cmlidXRlcyhub2RlLmF0dHJzIHx8IHt9KVxuICAgICAgY29uc3QgYXR0cnMgPSBzZXJpYWxpemVBdHRyaWJ1dGVzKGZpbHRlcmVkQXR0cnMpXG4gICAgICBjb25zdCBhdHRyU3RyaW5nID0gYXR0cnMgPyBgICR7YXR0cnN9YCA6ICcnXG5cbiAgICAgIGlmIChzZWxmQ2xvc2luZykge1xuICAgICAgICByZXR1cm4gYFske3Nob3J0Y29kZX0ke2F0dHJTdHJpbmd9XWBcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGBbJHtzaG9ydGNvZGV9JHthdHRyU3RyaW5nfV0ke2NvbnRlbnR9Wy8ke3Nob3J0Y29kZX1dYFxuICAgIH0sXG4gIH1cbn1cbiIsICIvKipcbiAqIEBmaWxlb3ZlcnZpZXcgVXRpbGl0eSBmb3IgcGFyc2luZyBpbmRlbnRlZCBtYXJrZG93biBibG9ja3Mgd2l0aCBoaWVyYXJjaGljYWwgbmVzdGluZy5cbiAqXG4gKiBUaGlzIHV0aWxpdHkgaGFuZGxlcyB0aGUgY29tcGxleCBsb2dpYyBvZiBwYXJzaW5nIG1hcmtkb3duIGJsb2NrcyB0aGF0IGNhbiBjb250YWluXG4gKiBuZXN0ZWQgY29udGVudCBiYXNlZCBvbiBpbmRlbnRhdGlvbiBsZXZlbHMsIG1haW50YWluaW5nIHByb3BlciBoaWVyYXJjaGljYWwgc3RydWN0dXJlXG4gKiBmb3IgbGlzdHMsIHRhc2sgbGlzdHMsIGFuZCBvdGhlciBpbmRlbnRlZCBibG9jayB0eXBlcy5cbiAqL1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlZEJsb2NrIHtcbiAgdHlwZTogc3RyaW5nXG4gIHJhdzogc3RyaW5nXG4gIG1haW5Db250ZW50OiBzdHJpbmdcbiAgaW5kZW50TGV2ZWw6IG51bWJlclxuICBuZXN0ZWRDb250ZW50Pzogc3RyaW5nXG4gIG5lc3RlZFRva2Vucz86IGFueVtdXG4gIFtrZXk6IHN0cmluZ106IGFueVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJsb2NrUGFyc2VyQ29uZmlnIHtcbiAgLyoqIFJlZ2V4IHBhdHRlcm4gdG8gbWF0Y2ggYmxvY2sgaXRlbXMgKi9cbiAgaXRlbVBhdHRlcm46IFJlZ0V4cFxuICAvKiogRnVuY3Rpb24gdG8gZXh0cmFjdCBkYXRhIGZyb20gcmVnZXggbWF0Y2ggKi9cbiAgZXh0cmFjdEl0ZW1EYXRhOiAobWF0Y2g6IFJlZ0V4cE1hdGNoQXJyYXkpID0+IHtcbiAgICBtYWluQ29udGVudDogc3RyaW5nXG4gICAgaW5kZW50TGV2ZWw6IG51bWJlclxuICAgIFtrZXk6IHN0cmluZ106IGFueVxuICB9XG4gIC8qKiBGdW5jdGlvbiB0byBjcmVhdGUgdGhlIGZpbmFsIHRva2VuICovXG4gIGNyZWF0ZVRva2VuOiAoZGF0YTogYW55LCBuZXN0ZWRUb2tlbnM/OiBhbnlbXSkgPT4gUGFyc2VkQmxvY2tcbiAgLyoqIEJhc2UgaW5kZW50YXRpb24gdG8gcmVtb3ZlIGZyb20gbmVzdGVkIGNvbnRlbnQgKGRlZmF1bHQ6IDIgc3BhY2VzKSAqL1xuICBiYXNlSW5kZW50U2l6ZT86IG51bWJlclxuICAvKipcbiAgICogQ3VzdG9tIHBhcnNlciBmb3IgbmVzdGVkIGNvbnRlbnQuIElmIHByb3ZpZGVkLCB0aGlzIHdpbGwgYmUgY2FsbGVkIGluc3RlYWRcbiAgICogb2YgdGhlIGRlZmF1bHQgbGV4ZXIuYmxvY2tUb2tlbnMoKSBmb3IgcGFyc2luZyBuZXN0ZWQgY29udGVudC5cbiAgICogVGhpcyBhbGxvd3MgcmVjdXJzaXZlIHBhcnNpbmcgb2YgdGhlIHNhbWUgYmxvY2sgdHlwZS5cbiAgICovXG4gIGN1c3RvbU5lc3RlZFBhcnNlcj86IChkZWRlbnRlZENvbnRlbnQ6IHN0cmluZykgPT4gYW55W10gfCB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBQYXJzZXMgbWFya2Rvd24gdGV4dCBpbnRvIGhpZXJhcmNoaWNhbCBpbmRlbnRlZCBibG9ja3Mgd2l0aCBwcm9wZXIgbmVzdGluZy5cbiAqXG4gKiBUaGlzIHV0aWxpdHkgaGFuZGxlczpcbiAqIC0gTGluZS1ieS1saW5lIHBhcnNpbmcgd2l0aCBwYXR0ZXJuIG1hdGNoaW5nXG4gKiAtIEhpZXJhcmNoaWNhbCBuZXN0aW5nIGJhc2VkIG9uIGluZGVudGF0aW9uIGxldmVsc1xuICogLSBOZXN0ZWQgY29udGVudCBjb2xsZWN0aW9uIGFuZCBwYXJzaW5nXG4gKiAtIEVtcHR5IGxpbmUgaGFuZGxpbmdcbiAqIC0gQ29udGVudCBkZWRlbnRpbmcgZm9yIG5lc3RlZCBibG9ja3NcbiAqXG4gKiBUaGUga2V5IGRpZmZlcmVuY2UgZnJvbSBmbGF0IHBhcnNpbmcgaXMgdGhhdCB0aGlzIG1haW50YWlucyB0aGUgaGllcmFyY2hpY2FsXG4gKiBzdHJ1Y3R1cmUgd2hlcmUgbmVzdGVkIGl0ZW1zIGJlY29tZSBgbmVzdGVkVG9rZW5zYCBvZiB0aGVpciBwYXJlbnQgaXRlbXMsXG4gKiByYXRoZXIgdGhhbiBiZWluZyBmbGF0dGVuZWQgaW50byBhIHNpbmdsZSBhcnJheS5cbiAqXG4gKiBAcGFyYW0gc3JjIC0gVGhlIG1hcmtkb3duIHNvdXJjZSB0ZXh0IHRvIHBhcnNlXG4gKiBAcGFyYW0gY29uZmlnIC0gQ29uZmlndXJhdGlvbiBvYmplY3QgZGVmaW5pbmcgaG93IHRvIHBhcnNlIGFuZCBjcmVhdGUgdG9rZW5zXG4gKiBAcGFyYW0gbGV4ZXIgLSBNYXJrZG93biBsZXhlciBmb3IgcGFyc2luZyBuZXN0ZWQgY29udGVudFxuICogQHJldHVybnMgUGFyc2VkIHJlc3VsdCB3aXRoIGhpZXJhcmNoaWNhbCBpdGVtcywgb3IgdW5kZWZpbmVkIGlmIG5vIG1hdGNoZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGNvbnN0IHJlc3VsdCA9IHBhcnNlSW5kZW50ZWRCbG9ja3Moc3JjLCB7XG4gKiAgIGl0ZW1QYXR0ZXJuOiAvXihcXHMqKShbLSsqXSlcXHMrXFxbKFsgeFhdKVxcXVxccysoLiopJC8sXG4gKiAgIGV4dHJhY3RJdGVtRGF0YTogKG1hdGNoKSA9PiAoe1xuICogICAgIGluZGVudExldmVsOiBtYXRjaFsxXS5sZW5ndGgsXG4gKiAgICAgbWFpbkNvbnRlbnQ6IG1hdGNoWzRdLFxuICogICAgIGNoZWNrZWQ6IG1hdGNoWzNdLnRvTG93ZXJDYXNlKCkgPT09ICd4J1xuICogICB9KSxcbiAqICAgY3JlYXRlVG9rZW46IChkYXRhLCBuZXN0ZWRUb2tlbnMpID0+ICh7XG4gKiAgICAgdHlwZTogJ3Rhc2tJdGVtJyxcbiAqICAgICBjaGVja2VkOiBkYXRhLmNoZWNrZWQsXG4gKiAgICAgdGV4dDogZGF0YS5tYWluQ29udGVudCxcbiAqICAgICBuZXN0ZWRUb2tlbnNcbiAqICAgfSlcbiAqIH0sIGxleGVyKVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUluZGVudGVkQmxvY2tzKFxuICBzcmM6IHN0cmluZyxcbiAgY29uZmlnOiBCbG9ja1BhcnNlckNvbmZpZyxcbiAgbGV4ZXI6IHtcbiAgICBpbmxpbmVUb2tlbnM6IChzcmM6IHN0cmluZykgPT4gYW55W11cbiAgICBibG9ja1Rva2VuczogKHNyYzogc3RyaW5nKSA9PiBhbnlbXVxuICB9LFxuKTpcbiAgfCB7XG4gICAgICBpdGVtczogUGFyc2VkQmxvY2tbXVxuICAgICAgcmF3OiBzdHJpbmdcbiAgICB9XG4gIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgbGluZXMgPSBzcmMuc3BsaXQoJ1xcbicpXG4gIGNvbnN0IGl0ZW1zOiBQYXJzZWRCbG9ja1tdID0gW11cbiAgbGV0IHRvdGFsUmF3ID0gJydcbiAgbGV0IGkgPSAwXG4gIGNvbnN0IGJhc2VJbmRlbnRTaXplID0gY29uZmlnLmJhc2VJbmRlbnRTaXplIHx8IDJcblxuICB3aGlsZSAoaSA8IGxpbmVzLmxlbmd0aCkge1xuICAgIGNvbnN0IGN1cnJlbnRMaW5lID0gbGluZXNbaV1cbiAgICBjb25zdCBpdGVtTWF0Y2ggPSBjdXJyZW50TGluZS5tYXRjaChjb25maWcuaXRlbVBhdHRlcm4pXG5cbiAgICBpZiAoIWl0ZW1NYXRjaCkge1xuICAgICAgLy8gTm90IGEgbWF0Y2hpbmcgaXRlbSAtIHN0b3AgaWYgd2UgaGF2ZSBpdGVtcywgb3RoZXJ3aXNlIHRoaXMgaXNuJ3Qgb3VyIGJsb2NrIHR5cGVcbiAgICAgIGlmIChpdGVtcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGJyZWFrXG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRMaW5lLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgaSArPSAxXG4gICAgICAgIHRvdGFsUmF3ID0gYCR7dG90YWxSYXd9JHtjdXJyZW50TGluZX1cXG5gXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaXRlbURhdGEgPSBjb25maWcuZXh0cmFjdEl0ZW1EYXRhKGl0ZW1NYXRjaClcbiAgICBjb25zdCB7IGluZGVudExldmVsLCBtYWluQ29udGVudCB9ID0gaXRlbURhdGFcbiAgICB0b3RhbFJhdyA9IGAke3RvdGFsUmF3fSR7Y3VycmVudExpbmV9XFxuYFxuXG4gICAgLy8gQ29sbGVjdCBjb250ZW50IGZvciB0aGlzIGl0ZW0gKGluY2x1ZGluZyBuZXN0ZWQgaXRlbXMpXG4gICAgY29uc3QgaXRlbUNvbnRlbnQgPSBbbWFpbkNvbnRlbnRdIC8vIFN0YXJ0IHdpdGggdGhlIG1haW4gdGV4dFxuICAgIGkgKz0gMVxuXG4gICAgLy8gTG9vayBhaGVhZCBmb3IgbmVzdGVkIGNvbnRlbnQgKGluZGVudGVkIG1vcmUgdGhhbiBjdXJyZW50IGl0ZW0pXG4gICAgd2hpbGUgKGkgPCBsaW5lcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5leHRMaW5lID0gbGluZXNbaV1cblxuICAgICAgaWYgKG5leHRMaW5lLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgLy8gRW1wdHkgbGluZSAtIG1pZ2h0IGJlIGVuZCBvZiBuZXN0ZWQgY29udGVudFxuICAgICAgICBjb25zdCBuZXh0Tm9uRW1wdHlJbmRleCA9IGxpbmVzLnNsaWNlKGkgKyAxKS5maW5kSW5kZXgobCA9PiBsLnRyaW0oKSAhPT0gJycpXG4gICAgICAgIGlmIChuZXh0Tm9uRW1wdHlJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAvLyBObyBtb3JlIGNvbnRlbnRcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbmV4dE5vbkVtcHR5ID0gbGluZXNbaSArIDEgKyBuZXh0Tm9uRW1wdHlJbmRleF1cbiAgICAgICAgY29uc3QgbmV4dEluZGVudCA9IG5leHROb25FbXB0eS5tYXRjaCgvXihcXHMqKS8pPy5bMV0/Lmxlbmd0aCB8fCAwXG5cbiAgICAgICAgaWYgKG5leHRJbmRlbnQgPiBpbmRlbnRMZXZlbCkge1xuICAgICAgICAgIC8vIE5lc3RlZCBjb250ZW50IGNvbnRpbnVlcyBhZnRlciBlbXB0eSBsaW5lXG4gICAgICAgICAgaXRlbUNvbnRlbnQucHVzaChuZXh0TGluZSlcbiAgICAgICAgICB0b3RhbFJhdyA9IGAke3RvdGFsUmF3fSR7bmV4dExpbmV9XFxuYFxuICAgICAgICAgIGkgKz0gMVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gRW5kIG9mIG5lc3RlZCBjb250ZW50XG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBuZXh0SW5kZW50ID0gbmV4dExpbmUubWF0Y2goL14oXFxzKikvKT8uWzFdPy5sZW5ndGggfHwgMFxuXG4gICAgICBpZiAobmV4dEluZGVudCA+IGluZGVudExldmVsKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgbmVzdGVkIGNvbnRlbnQgZm9yIHRoZSBjdXJyZW50IGl0ZW1cbiAgICAgICAgaXRlbUNvbnRlbnQucHVzaChuZXh0TGluZSlcbiAgICAgICAgdG90YWxSYXcgPSBgJHt0b3RhbFJhd30ke25leHRMaW5lfVxcbmBcbiAgICAgICAgaSArPSAxXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBTYW1lIG9yIGxlc3MgaW5kZW50YXRpb24gLSB0aGlzIGJlbG9uZ3MgdG8gcGFyZW50IGxldmVsXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUGFyc2UgbmVzdGVkIGNvbnRlbnQgaWYgcHJlc2VudFxuICAgIGxldCBuZXN0ZWRUb2tlbnM6IGFueVtdIHwgdW5kZWZpbmVkXG4gICAgY29uc3QgbmVzdGVkQ29udGVudCA9IGl0ZW1Db250ZW50LnNsaWNlKDEpXG5cbiAgICBpZiAobmVzdGVkQ29udGVudC5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBSZW1vdmUgdGhlIGJhc2UgaW5kZW50YXRpb24gZnJvbSBuZXN0ZWQgY29udGVudFxuICAgICAgY29uc3QgZGVkZW50ZWROZXN0ZWQgPSBuZXN0ZWRDb250ZW50XG4gICAgICAgIC5tYXAobmVzdGVkTGluZSA9PiBuZXN0ZWRMaW5lLnNsaWNlKGluZGVudExldmVsICsgYmFzZUluZGVudFNpemUpKSAvLyBSZW1vdmUgYmFzZSBpbmRlbnQgKyAyIHNwYWNlc1xuICAgICAgICAuam9pbignXFxuJylcblxuICAgICAgaWYgKGRlZGVudGVkTmVzdGVkLnRyaW0oKSkge1xuICAgICAgICAvLyBVc2UgY3VzdG9tIG5lc3RlZCBwYXJzZXIgaWYgcHJvdmlkZWQsIG90aGVyd2lzZSBmYWxsIGJhY2sgdG8gZGVmYXVsdFxuICAgICAgICBpZiAoY29uZmlnLmN1c3RvbU5lc3RlZFBhcnNlcikge1xuICAgICAgICAgIG5lc3RlZFRva2VucyA9IGNvbmZpZy5jdXN0b21OZXN0ZWRQYXJzZXIoZGVkZW50ZWROZXN0ZWQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmVzdGVkVG9rZW5zID0gbGV4ZXIuYmxvY2tUb2tlbnMoZGVkZW50ZWROZXN0ZWQpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDcmVhdGUgdGhlIHRva2VuIHVzaW5nIHRoZSBwcm92aWRlZCBmYWN0b3J5IGZ1bmN0aW9uXG4gICAgY29uc3QgdG9rZW4gPSBjb25maWcuY3JlYXRlVG9rZW4oaXRlbURhdGEsIG5lc3RlZFRva2VucylcbiAgICBpdGVtcy5wdXNoKHRva2VuKVxuICB9XG5cbiAgaWYgKGl0ZW1zLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgaXRlbXMsXG4gICAgcmF3OiB0b3RhbFJhdyxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgSlNPTkNvbnRlbnQgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5cbi8qKlxuICogQGZpbGVvdmVydmlldyBVdGlsaXR5IGZ1bmN0aW9ucyBmb3IgcmVuZGVyaW5nIG5lc3RlZCBjb250ZW50IGluIG1hcmtkb3duLlxuICpcbiAqIFRoaXMgbW9kdWxlIHByb3ZpZGVzIHJldXNhYmxlIHV0aWxpdGllcyBmb3IgZXh0ZW5zaW9ucyB0aGF0IG5lZWQgdG8gcmVuZGVyXG4gKiBjb250ZW50IHdpdGggYSBwcmVmaXggb24gdGhlIG1haW4gbGluZSBhbmQgcHJvcGVybHkgaW5kZW50ZWQgbmVzdGVkIGNvbnRlbnQuXG4gKi9cblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIGZvciByZW5kZXJpbmcgY29udGVudCB3aXRoIGEgbWFpbiBsaW5lIHByZWZpeCBhbmQgbmVzdGVkIGluZGVudGVkIGNvbnRlbnQuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBoYW5kbGVzIHRoZSBjb21tb24gcGF0dGVybiBvZiByZW5kZXJpbmcgY29udGVudCB3aXRoOlxuICogMS4gQSBtYWluIGxpbmUgd2l0aCBhIHByZWZpeCAobGlrZSBcIi0gXCIgZm9yIGxpc3RzLCBcIj4gXCIgZm9yIGJsb2NrcXVvdGVzLCBldGMuKVxuICogMi4gTmVzdGVkIGNvbnRlbnQgdGhhdCBnZXRzIGluZGVudGVkIHByb3Blcmx5XG4gKlxuICogQHBhcmFtIG5vZGUgLSBUaGUgUHJvc2VNaXJyb3Igbm9kZSByZXByZXNlbnRpbmcgdGhlIGNvbnRlbnRcbiAqIEBwYXJhbSBoIC0gVGhlIG1hcmtkb3duIHJlbmRlcmVyIGhlbHBlclxuICogQHBhcmFtIHByZWZpeE9yR2VuZXJhdG9yIC0gRWl0aGVyIGEgc3RyaW5nIHByZWZpeCBvciBhIGZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIHRoZSBwcmVmaXggZnJvbSBjb250ZXh0XG4gKiBAcGFyYW0gY3R4IC0gT3B0aW9uYWwgY29udGV4dCBvYmplY3QgKHVzZWQgd2hlbiBwcmVmaXhPckdlbmVyYXRvciBpcyBhIGZ1bmN0aW9uKVxuICogQHJldHVybnMgVGhlIHJlbmRlcmVkIG1hcmtkb3duIHN0cmluZ1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogLy8gRm9yIGEgYnVsbGV0IGxpc3QgaXRlbSB3aXRoIHN0YXRpYyBwcmVmaXhcbiAqIHJldHVybiByZW5kZXJOZXN0ZWRNYXJrZG93bkNvbnRlbnQobm9kZSwgaCwgJy0gJylcbiAqXG4gKiAvLyBGb3IgYSB0YXNrIGl0ZW0gd2l0aCBzdGF0aWMgcHJlZml4XG4gKiBjb25zdCBwcmVmaXggPSBgLSBbJHtub2RlLmF0dHJzPy5jaGVja2VkID8gJ3gnIDogJyAnfV0gYFxuICogcmV0dXJuIHJlbmRlck5lc3RlZE1hcmtkb3duQ29udGVudChub2RlLCBoLCBwcmVmaXgpXG4gKlxuICogLy8gRm9yIGEgYmxvY2txdW90ZSB3aXRoIHN0YXRpYyBwcmVmaXhcbiAqIHJldHVybiByZW5kZXJOZXN0ZWRNYXJrZG93bkNvbnRlbnQobm9kZSwgaCwgJz4gJylcbiAqXG4gKiAvLyBGb3IgY29udGVudCB3aXRoIGR5bmFtaWMgcHJlZml4IGJhc2VkIG9uIGNvbnRleHRcbiAqIHJldHVybiByZW5kZXJOZXN0ZWRNYXJrZG93bkNvbnRlbnQobm9kZSwgaCwgY3R4ID0+IHtcbiAqICAgaWYgKGN0eC5wYXJlbnRUeXBlID09PSAnb3JkZXJlZExpc3QnKSB7XG4gKiAgICAgcmV0dXJuIGAke2N0eC5pbmRleCArIDF9LiBgXG4gKiAgIH1cbiAqICAgcmV0dXJuICctICdcbiAqIH0sIGN0eClcbiAqXG4gKiAvLyBDdXN0b20gZXh0ZW5zaW9uIGV4YW1wbGVcbiAqIGNvbnN0IEN1c3RvbUNvbnRhaW5lciA9IE5vZGUuY3JlYXRlKHtcbiAqICAgbmFtZTogJ2N1c3RvbUNvbnRhaW5lcicsXG4gKiAgIC8vIC4uLiBvdGhlciBjb25maWdcbiAqICAgbWFya2Rvd246IHtcbiAqICAgICByZW5kZXI6IChub2RlLCBoKSA9PiB7XG4gKiAgICAgICBjb25zdCB0eXBlID0gbm9kZS5hdHRycz8udHlwZSB8fCAnaW5mbydcbiAqICAgICAgIHJldHVybiByZW5kZXJOZXN0ZWRNYXJrZG93bkNvbnRlbnQobm9kZSwgaCwgYFske3R5cGV9XSBgKVxuICogICAgIH1cbiAqICAgfVxuICogfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyTmVzdGVkTWFya2Rvd25Db250ZW50KFxuICBub2RlOiBKU09OQ29udGVudCxcbiAgaDoge1xuICAgIHJlbmRlckNoaWxkcmVuOiAobm9kZXM6IEpTT05Db250ZW50W10pID0+IHN0cmluZ1xuICAgIHJlbmRlckNoaWxkPzogKG5vZGU6IEpTT05Db250ZW50LCBpbmRleDogbnVtYmVyKSA9PiBzdHJpbmdcbiAgICBpbmRlbnQ6ICh0ZXh0OiBzdHJpbmcpID0+IHN0cmluZ1xuICB9LFxuICBwcmVmaXhPckdlbmVyYXRvcjogc3RyaW5nIHwgKChjdHg6IGFueSkgPT4gc3RyaW5nKSxcbiAgY3R4PzogYW55LFxuKTogc3RyaW5nIHtcbiAgaWYgKCFub2RlIHx8ICFBcnJheS5pc0FycmF5KG5vZGUuY29udGVudCkpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIC8vIERldGVybWluZSB0aGUgcHJlZml4IGJhc2VkIG9uIHRoZSBpbnB1dFxuICBjb25zdCBwcmVmaXggPVxuICAgIHR5cGVvZiBwcmVmaXhPckdlbmVyYXRvciA9PT0gJ2Z1bmN0aW9uJyA/IHByZWZpeE9yR2VuZXJhdG9yKGN0eCkgOiBwcmVmaXhPckdlbmVyYXRvclxuXG4gIGNvbnN0IFtjb250ZW50LCAuLi5jaGlsZHJlbl0gPSBub2RlLmNvbnRlbnRcblxuICAvLyBSZW5kZXIgdGhlIG1haW4gY29udGVudCAodHlwaWNhbGx5IGEgcGFyYWdyYXBoKVxuICBjb25zdCBtYWluQ29udGVudCA9IGgucmVuZGVyQ2hpbGRyZW4oW2NvbnRlbnRdKVxuICBsZXQgb3V0cHV0ID0gYCR7cHJlZml4fSR7bWFpbkNvbnRlbnR9YFxuXG4gIC8vIEhhbmRsZSBuZXN0ZWQgY2hpbGRyZW4gd2l0aCBwcm9wZXIgaW5kZW50YXRpb25cbiAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKChjaGlsZCwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGNoaWxkQ29udGVudCA9IGgucmVuZGVyQ2hpbGQ/LihjaGlsZCwgaW5kZXggKyAxKSA/PyBoLnJlbmRlckNoaWxkcmVuKFtjaGlsZF0pXG4gICAgICBpZiAoY2hpbGRDb250ZW50ICE9PSB1bmRlZmluZWQgJiYgY2hpbGRDb250ZW50ICE9PSBudWxsKSB7XG4gICAgICAgIC8vIFNwbGl0IHRoZSBjaGlsZCBjb250ZW50IGJ5IGxpbmVzIGFuZCBpbmRlbnQgZWFjaCBsaW5lXG4gICAgICAgIGNvbnN0IGluZGVudGVkQ2hpbGQgPSBjaGlsZENvbnRlbnRcbiAgICAgICAgICAuc3BsaXQoJ1xcbicpXG4gICAgICAgICAgLm1hcChsaW5lID0+IChsaW5lID8gaC5pbmRlbnQobGluZSkgOiBoLmluZGVudCgnJykpKVxuICAgICAgICAgIC5qb2luKCdcXG4nKVxuXG4gICAgICAgIG91dHB1dCArPSBjaGlsZC50eXBlID09PSAncGFyYWdyYXBoJyA/IGBcXG5cXG4ke2luZGVudGVkQ2hpbGR9YCA6IGBcXG4ke2luZGVudGVkQ2hpbGR9YFxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICByZXR1cm4gb3V0cHV0XG59XG4iLCAiaW1wb3J0IHsgYXR0cnNFcXVhbCB9IGZyb20gJy4vYXR0cnNFcXVhbC5qcydcblxuLyoqXG4gKiBDb21wYXJlIHR3byBhcnJheXMgb2YgbWFyayBvYmplY3RzIGZvciBlcXVhbGl0eS5cbiAqIE1hcmtzIGFyZSBjb21wYXJlZCBieSB0eXBlIGFuZCBhdHRyaWJ1dGVzICh1c2luZyBhdHRyc0VxdWFsKSxcbiAqIHNvIGtleSBvcmRlcmluZyBpbiBhdHRycyBkb2VzIG5vdCBtYXR0ZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrc0VxdWFsKFxuICBhOiB7IHR5cGU6IHN0cmluZzsgYXR0cnM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IH1bXSxcbiAgYjogeyB0eXBlOiBzdHJpbmc7IGF0dHJzPzogUmVjb3JkPHN0cmluZywgYW55PiB9W10sXG4pOiBib29sZWFuIHtcbiAgaWYgKGEubGVuZ3RoICE9PSBiLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIGEuZXZlcnkoKG1hcmssIGkpID0+IHtcbiAgICBjb25zdCBvdGhlciA9IGJbaV1cbiAgICByZXR1cm4gbWFyay50eXBlID09PSBvdGhlci50eXBlICYmIGF0dHJzRXF1YWwobWFyay5hdHRycywgb3RoZXIuYXR0cnMpXG4gIH0pXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBNYXJrIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB0eXBlIHsgVmlld011dGF0aW9uUmVjb3JkIH0gZnJvbSAnQHRpcHRhcC9wbS92aWV3J1xuXG5pbXBvcnQgdHlwZSB7IEVkaXRvciB9IGZyb20gJy4vRWRpdG9yLmpzJ1xuaW1wb3J0IHR5cGUgeyBNYXJrVmlld1Byb3BzLCBNYXJrVmlld1JlbmRlcmVyT3B0aW9ucyB9IGZyb20gJy4vdHlwZXMuanMnXG5pbXBvcnQgeyBpc0FuZHJvaWQsIGlzaU9TIH0gZnJvbSAnLi91dGlsaXRpZXMvaW5kZXguanMnXG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVNYXJrVmlld0F0dHJpYnV0ZXMoXG4gIGNoZWNrTWFyazogTWFyayxcbiAgZWRpdG9yOiBFZGl0b3IsXG4gIGF0dHJzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge30sXG4pOiB2b2lkIHtcbiAgY29uc3QgeyBzdGF0ZSB9ID0gZWRpdG9yXG4gIGNvbnN0IHsgZG9jLCB0ciB9ID0gc3RhdGVcbiAgY29uc3QgdGhpc01hcmsgPSBjaGVja01hcmtcblxuICBkb2MuZGVzY2VuZGFudHMoKG5vZGUsIHBvcykgPT4ge1xuICAgIGNvbnN0IGZyb20gPSB0ci5tYXBwaW5nLm1hcChwb3MpXG4gICAgY29uc3QgdG8gPSB0ci5tYXBwaW5nLm1hcChwb3MpICsgbm9kZS5ub2RlU2l6ZVxuICAgIGxldCBmb3VuZE1hcms6IE1hcmsgfCBudWxsID0gbnVsbFxuXG4gICAgLy8gZmluZCB0aGUgbWFyayBvbiB0aGUgY3VycmVudCBub2RlXG4gICAgbm9kZS5tYXJrcy5mb3JFYWNoKG1hcmsgPT4ge1xuICAgICAgaWYgKG1hcmsgIT09IHRoaXNNYXJrKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuXG4gICAgICBmb3VuZE1hcmsgPSBtYXJrXG4gICAgfSlcblxuICAgIGlmICghZm91bmRNYXJrKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBjaGVjayBpZiB3ZSBuZWVkIHRvIHVwZGF0ZSBnaXZlbiB0aGUgYXR0cmlidXRlc1xuICAgIGxldCBuZWVkc1VwZGF0ZSA9IGZhbHNlXG4gICAgT2JqZWN0LmtleXMoYXR0cnMpLmZvckVhY2goayA9PiB7XG4gICAgICBpZiAoYXR0cnNba10gIT09IGZvdW5kTWFyayEuYXR0cnNba10pIHtcbiAgICAgICAgbmVlZHNVcGRhdGUgPSB0cnVlXG4gICAgICB9XG4gICAgfSlcblxuICAgIGlmIChuZWVkc1VwZGF0ZSkge1xuICAgICAgY29uc3QgdXBkYXRlZE1hcmsgPSBjaGVja01hcmsudHlwZS5jcmVhdGUoe1xuICAgICAgICAuLi5jaGVja01hcmsuYXR0cnMsXG4gICAgICAgIC4uLmF0dHJzLFxuICAgICAgfSlcblxuICAgICAgdHIucmVtb3ZlTWFyayhmcm9tLCB0bywgY2hlY2tNYXJrLnR5cGUpXG4gICAgICB0ci5hZGRNYXJrKGZyb20sIHRvLCB1cGRhdGVkTWFyaylcbiAgICB9XG4gIH0pXG5cbiAgaWYgKHRyLmRvY0NoYW5nZWQpIHtcbiAgICBlZGl0b3Iudmlldy5kaXNwYXRjaCh0cilcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTWFya1ZpZXc8XG4gIENvbXBvbmVudCxcbiAgT3B0aW9ucyBleHRlbmRzIE1hcmtWaWV3UmVuZGVyZXJPcHRpb25zID0gTWFya1ZpZXdSZW5kZXJlck9wdGlvbnMsXG4+IHtcbiAgY29tcG9uZW50OiBDb21wb25lbnRcbiAgZWRpdG9yOiBFZGl0b3JcbiAgb3B0aW9uczogT3B0aW9uc1xuICBtYXJrOiBNYXJrVmlld1Byb3BzWydtYXJrJ11cbiAgSFRNTEF0dHJpYnV0ZXM6IE1hcmtWaWV3UHJvcHNbJ0hUTUxBdHRyaWJ1dGVzJ11cblxuICBjb25zdHJ1Y3Rvcihjb21wb25lbnQ6IENvbXBvbmVudCwgcHJvcHM6IE1hcmtWaWV3UHJvcHMsIG9wdGlvbnM/OiBQYXJ0aWFsPE9wdGlvbnM+KSB7XG4gICAgdGhpcy5jb21wb25lbnQgPSBjb21wb25lbnRcbiAgICB0aGlzLmVkaXRvciA9IHByb3BzLmVkaXRvclxuICAgIHRoaXMub3B0aW9ucyA9IHsgLi4ub3B0aW9ucyB9IGFzIE9wdGlvbnNcbiAgICB0aGlzLm1hcmsgPSBwcm9wcy5tYXJrXG4gICAgdGhpcy5IVE1MQXR0cmlidXRlcyA9IHByb3BzLkhUTUxBdHRyaWJ1dGVzXG4gIH1cblxuICBnZXQgZG9tKCk6IEhUTUxFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5lZGl0b3Iudmlldy5kb21cbiAgfVxuXG4gIGdldCBjb250ZW50RE9NKCk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG1hcmsgaW4gdGhlIGRvY3VtZW50LlxuICAgKiBAcGFyYW0gYXR0cnMgVGhlIGF0dHJpYnV0ZXMgdG8gdXBkYXRlLlxuICAgKi9cbiAgdXBkYXRlQXR0cmlidXRlcyhhdHRyczogUmVjb3JkPHN0cmluZywgYW55PiwgY2hlY2tNYXJrPzogTWFyayk6IHZvaWQge1xuICAgIHVwZGF0ZU1hcmtWaWV3QXR0cmlidXRlcyhjaGVja01hcmsgfHwgdGhpcy5tYXJrLCB0aGlzLmVkaXRvciwgYXR0cnMpXG4gIH1cblxuICBpZ25vcmVNdXRhdGlvbihtdXRhdGlvbjogVmlld011dGF0aW9uUmVjb3JkKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmRvbSB8fCAhdGhpcy5jb250ZW50RE9NKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5vcHRpb25zLmlnbm9yZU11dGF0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmlnbm9yZU11dGF0aW9uKHsgbXV0YXRpb24gfSlcbiAgICB9XG5cbiAgICBpZiAobXV0YXRpb24udHlwZSA9PT0gJ3NlbGVjdGlvbicpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMuZG9tLmNvbnRhaW5zKG11dGF0aW9uLnRhcmdldCkgJiZcbiAgICAgIG11dGF0aW9uLnR5cGUgPT09ICdjaGlsZExpc3QnICYmXG4gICAgICAoaXNpT1MoKSB8fCBpc0FuZHJvaWQoKSkgJiZcbiAgICAgIHRoaXMuZWRpdG9yLmlzRm9jdXNlZFxuICAgICkge1xuICAgICAgY29uc3QgY2hhbmdlZE5vZGVzID0gW1xuICAgICAgICAuLi5BcnJheS5mcm9tKG11dGF0aW9uLmFkZGVkTm9kZXMpLFxuICAgICAgICAuLi5BcnJheS5mcm9tKG11dGF0aW9uLnJlbW92ZWROb2RlcyksXG4gICAgICBdIGFzIEhUTUxFbGVtZW50W11cblxuICAgICAgaWYgKGNoYW5nZWROb2Rlcy5ldmVyeShub2RlID0+IG5vZGUuaXNDb250ZW50RWRpdGFibGUpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbnRlbnRET00gPT09IG11dGF0aW9uLnRhcmdldCAmJiBtdXRhdGlvbi50eXBlID09PSAnYXR0cmlidXRlcycpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29udGVudERPTS5jb250YWlucyhtdXRhdGlvbi50YXJnZXQpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBET01PdXRwdXRTcGVjLCBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSwgTm9kZVNwZWMsIE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBFZGl0b3IgfSBmcm9tICcuL0VkaXRvci5qcydcbmltcG9ydCB0eXBlIHsgRXh0ZW5kYWJsZUNvbmZpZyB9IGZyb20gJy4vRXh0ZW5kYWJsZS5qcydcbmltcG9ydCB7IEV4dGVuZGFibGUgfSBmcm9tICcuL0V4dGVuZGFibGUuanMnXG5pbXBvcnQgdHlwZSB7IEF0dHJpYnV0ZXMsIE5vZGVWaWV3UmVuZGVyZXIsIFBhcmVudENvbmZpZyB9IGZyb20gJy4vdHlwZXMuanMnXG5cbmV4cG9ydCBpbnRlcmZhY2UgTm9kZUNvbmZpZzxPcHRpb25zID0gYW55LCBTdG9yYWdlID0gYW55PiBleHRlbmRzIEV4dGVuZGFibGVDb25maWc8XG4gIE9wdGlvbnMsXG4gIFN0b3JhZ2UsXG4gIE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4sXG4gIE5vZGVUeXBlXG4+IHtcbiAgLyoqXG4gICAqIE5vZGUgVmlld1xuICAgKi9cbiAgYWRkTm9kZVZpZXc/OlxuICAgIHwgKCh0aGlzOiB7XG4gICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgdHlwZTogTm9kZVR5cGVcbiAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZE5vZGVWaWV3J11cbiAgICAgIH0pID0+IE5vZGVWaWV3UmVuZGVyZXIgfCBudWxsKVxuICAgIHwgbnVsbFxuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGlmIHRoaXMgbm9kZSBzaG91bGQgYmUgYSB0b3AgbGV2ZWwgbm9kZSAoZG9jKVxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKiBAZXhhbXBsZSB0cnVlXG4gICAqL1xuICB0b3BOb2RlPzogYm9vbGVhblxuXG4gIC8qKlxuICAgKiBUaGUgY29udGVudCBleHByZXNzaW9uIGZvciB0aGlzIG5vZGUsIGFzIGRlc2NyaWJlZCBpbiB0aGUgW3NjaGVtYVxuICAgKiBndWlkZV0oL2RvY3MvZ3VpZGUvI3NjaGVtYS5jb250ZW50X2V4cHJlc3Npb25zKS4gV2hlbiBub3QgZ2l2ZW4sXG4gICAqIHRoZSBub2RlIGRvZXMgbm90IGFsbG93IGFueSBjb250ZW50LlxuICAgKlxuICAgKiBZb3UgY2FuIHJlYWQgbW9yZSBhYm91dCBpdCBvbiB0aGUgUHJvc2VtaXJyb3IgZG9jdW1lbnRhdGlvbiBoZXJlXG4gICAqIEBzZWUgaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9ndWlkZS8jc2NoZW1hLmNvbnRlbnRfZXhwcmVzc2lvbnNcbiAgICogQGRlZmF1bHQgdW5kZWZpbmVkXG4gICAqIEBleGFtcGxlIGNvbnRlbnQ6ICdibG9jaysnXG4gICAqIEBleGFtcGxlIGNvbnRlbnQ6ICdoZWFkbGluZSBwYXJhZ3JhcGggYmxvY2sqJ1xuICAgKi9cbiAgY29udGVudD86XG4gICAgfCBOb2RlU3BlY1snY29udGVudCddXG4gICAgfCAoKHRoaXM6IHtcbiAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnY29udGVudCddXG4gICAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgICAgfSkgPT4gTm9kZVNwZWNbJ2NvbnRlbnQnXSlcblxuICAvKipcbiAgICogVGhlIG1hcmtzIHRoYXQgYXJlIGFsbG93ZWQgaW5zaWRlIG9mIHRoaXMgbm9kZS4gTWF5IGJlIGFcbiAgICogc3BhY2Utc2VwYXJhdGVkIHN0cmluZyByZWZlcnJpbmcgdG8gbWFyayBuYW1lcyBvciBncm91cHMsIGBcIl9cImBcbiAgICogdG8gZXhwbGljaXRseSBhbGxvdyBhbGwgbWFya3MsIG9yIGBcIlwiYCB0byBkaXNhbGxvdyBtYXJrcy4gV2hlblxuICAgKiBub3QgZ2l2ZW4sIG5vZGVzIHdpdGggaW5saW5lIGNvbnRlbnQgZGVmYXVsdCB0byBhbGxvd2luZyBhbGxcbiAgICogbWFya3MsIG90aGVyIG5vZGVzIGRlZmF1bHQgdG8gbm90IGFsbG93aW5nIG1hcmtzLlxuICAgKlxuICAgKiBAZXhhbXBsZSBtYXJrczogJ3N0cm9uZyBlbSdcbiAgICovXG4gIG1hcmtzPzpcbiAgICB8IE5vZGVTcGVjWydtYXJrcyddXG4gICAgfCAoKHRoaXM6IHtcbiAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnbWFya3MnXVxuICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgIH0pID0+IE5vZGVTcGVjWydtYXJrcyddKVxuXG4gIC8qKlxuICAgKiBUaGUgZ3JvdXAgb3Igc3BhY2Utc2VwYXJhdGVkIGdyb3VwcyB0byB3aGljaCB0aGlzIG5vZGUgYmVsb25ncyxcbiAgICogd2hpY2ggY2FuIGJlIHJlZmVycmVkIHRvIGluIHRoZSBjb250ZW50IGV4cHJlc3Npb25zIGZvciB0aGVcbiAgICogc2NoZW1hLlxuICAgKlxuICAgKiBCeSBkZWZhdWx0IFRpcHRhcCB1c2VzIHRoZSBncm91cHMgJ2Jsb2NrJyBhbmQgJ2lubGluZScgZm9yIG5vZGVzLiBZb3VcbiAgICogY2FuIGFsc28gdXNlIGN1c3RvbSBncm91cHMgaWYgeW91IHdhbnQgdG8gZ3JvdXAgc3BlY2lmaWMgbm9kZXMgdG9nZXRoZXJcbiAgICogYW5kIGhhbmRsZSB0aGVtIGluIHlvdXIgc2NoZW1hLlxuICAgKiBAZXhhbXBsZSBncm91cDogJ2Jsb2NrJ1xuICAgKiBAZXhhbXBsZSBncm91cDogJ2lubGluZSdcbiAgICogQGV4YW1wbGUgZ3JvdXA6ICdjdXN0b21CbG9jaycgLy8gdGhpcyB1c2VzIGEgY3VzdG9tIGdyb3VwXG4gICAqL1xuICBncm91cD86XG4gICAgfCBOb2RlU3BlY1snZ3JvdXAnXVxuICAgIHwgKCh0aGlzOiB7XG4gICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2dyb3VwJ11cbiAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICB9KSA9PiBOb2RlU3BlY1snZ3JvdXAnXSlcblxuICAvKipcbiAgICogU2hvdWxkIGJlIHNldCB0byB0cnVlIGZvciBpbmxpbmUgbm9kZXMuIChJbXBsaWVkIGZvciB0ZXh0IG5vZGVzLilcbiAgICovXG4gIGlubGluZT86XG4gICAgfCBOb2RlU3BlY1snaW5saW5lJ11cbiAgICB8ICgodGhpczoge1xuICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydpbmxpbmUnXVxuICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgIH0pID0+IE5vZGVTcGVjWydpbmxpbmUnXSlcblxuICAvKipcbiAgICogQ2FuIGJlIHNldCB0byB0cnVlIHRvIGluZGljYXRlIHRoYXQsIHRob3VnaCB0aGlzIGlzbid0IGEgW2xlYWZcbiAgICogbm9kZV0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVUeXBlLmlzTGVhZiksIGl0IGRvZXNuJ3QgaGF2ZSBkaXJlY3RseSBlZGl0YWJsZVxuICAgKiBjb250ZW50IGFuZCBzaG91bGQgYmUgdHJlYXRlZCBhcyBhIHNpbmdsZSB1bml0IGluIHRoZSB2aWV3LlxuICAgKlxuICAgKiBAZXhhbXBsZSBhdG9tOiB0cnVlXG4gICAqL1xuICBhdG9tPzpcbiAgICB8IE5vZGVTcGVjWydhdG9tJ11cbiAgICB8ICgodGhpczoge1xuICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhdG9tJ11cbiAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICB9KSA9PiBOb2RlU3BlY1snYXRvbSddKVxuXG4gIC8qKlxuICAgKiBDb250cm9scyB3aGV0aGVyIG5vZGVzIG9mIHRoaXMgdHlwZSBjYW4gYmUgc2VsZWN0ZWQgYXMgYSBbbm9kZVxuICAgKiBzZWxlY3Rpb25dKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5Ob2RlU2VsZWN0aW9uKS4gRGVmYXVsdHMgdG8gdHJ1ZSBmb3Igbm9uLXRleHRcbiAgICogbm9kZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICogQGV4YW1wbGUgc2VsZWN0YWJsZTogZmFsc2VcbiAgICovXG4gIHNlbGVjdGFibGU/OlxuICAgIHwgTm9kZVNwZWNbJ3NlbGVjdGFibGUnXVxuICAgIHwgKCh0aGlzOiB7XG4gICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ3NlbGVjdGFibGUnXVxuICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgIH0pID0+IE5vZGVTcGVjWydzZWxlY3RhYmxlJ10pXG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgd2hldGhlciBub2RlcyBvZiB0aGlzIHR5cGUgY2FuIGJlIGRyYWdnZWQgd2l0aG91dFxuICAgKiBiZWluZyBzZWxlY3RlZC4gRGVmYXVsdHMgdG8gZmFsc2UuXG4gICAqXG4gICAqIEBkZWZhdWx0OiBmYWxzZVxuICAgKiBAZXhhbXBsZTogZHJhZ2dhYmxlOiB0cnVlXG4gICAqL1xuICBkcmFnZ2FibGU/OlxuICAgIHwgTm9kZVNwZWNbJ2RyYWdnYWJsZSddXG4gICAgfCAoKHRoaXM6IHtcbiAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnZHJhZ2dhYmxlJ11cbiAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICB9KSA9PiBOb2RlU3BlY1snZHJhZ2dhYmxlJ10pXG5cbiAgLyoqXG4gICAqIENhbiBiZSB1c2VkIHRvIGluZGljYXRlIHRoYXQgdGhpcyBub2RlIGNvbnRhaW5zIGNvZGUsIHdoaWNoXG4gICAqIGNhdXNlcyBzb21lIGNvbW1hbmRzIHRvIGJlaGF2ZSBkaWZmZXJlbnRseS5cbiAgICovXG4gIGNvZGU/OlxuICAgIHwgTm9kZVNwZWNbJ2NvZGUnXVxuICAgIHwgKCh0aGlzOiB7XG4gICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2NvZGUnXVxuICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgIH0pID0+IE5vZGVTcGVjWydjb2RlJ10pXG5cbiAgLyoqXG4gICAqIENvbnRyb2xzIHdheSB3aGl0ZXNwYWNlIGluIHRoaXMgYSBub2RlIGlzIHBhcnNlZC4gVGhlIGRlZmF1bHQgaXNcbiAgICogYFwibm9ybWFsXCJgLCB3aGljaCBjYXVzZXMgdGhlIFtET00gcGFyc2VyXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuRE9NUGFyc2VyKSB0b1xuICAgKiBjb2xsYXBzZSB3aGl0ZXNwYWNlIGluIG5vcm1hbCBtb2RlLCBhbmQgbm9ybWFsaXplIGl0IChyZXBsYWNpbmdcbiAgICogbmV3bGluZXMgYW5kIHN1Y2ggd2l0aCBzcGFjZXMpIG90aGVyd2lzZS4gYFwicHJlXCJgIGNhdXNlcyB0aGVcbiAgICogcGFyc2VyIHRvIHByZXNlcnZlIHNwYWNlcyBpbnNpZGUgdGhlIG5vZGUuIFdoZW4gdGhpcyBvcHRpb24gaXNuJ3RcbiAgICogZ2l2ZW4sIGJ1dCBbYGNvZGVgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuY29kZSkgaXMgdHJ1ZSwgYHdoaXRlc3BhY2VgXG4gICAqIHdpbGwgZGVmYXVsdCB0byBgXCJwcmVcImAuIE5vdGUgdGhhdCB0aGlzIG9wdGlvbiBkb2Vzbid0IGluZmx1ZW5jZVxuICAgKiB0aGUgd2F5IHRoZSBub2RlIGlzIHJlbmRlcmVk4oCUdGhhdCBzaG91bGQgYmUgaGFuZGxlZCBieSBgdG9ET01gXG4gICAqIGFuZC9vciBzdHlsaW5nLlxuICAgKi9cbiAgd2hpdGVzcGFjZT86XG4gICAgfCBOb2RlU3BlY1snd2hpdGVzcGFjZSddXG4gICAgfCAoKHRoaXM6IHtcbiAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnd2hpdGVzcGFjZSddXG4gICAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgICAgfSkgPT4gTm9kZVNwZWNbJ3doaXRlc3BhY2UnXSlcblxuICAvKipcbiAgICogQWxsb3dzIGEgKipzaW5nbGUqKiBub2RlIHRvIGJlIHNldCBhcyBsaW5lYnJlYWsgZXF1aXZhbGVudCAoZS5nLiBoYXJkQnJlYWspLlxuICAgKiBXaGVuIGNvbnZlcnRpbmcgYmV0d2VlbiBibG9jayB0eXBlcyB0aGF0IGhhdmUgd2hpdGVzcGFjZSBzZXQgdG8gXCJwcmVcIlxuICAgKiBhbmQgZG9uJ3Qgc3VwcG9ydCB0aGUgbGluZWJyZWFrIG5vZGUgKGUuZy4gY29kZUJsb2NrKSBhbmQgb3RoZXIgYmxvY2sgdHlwZXNcbiAgICogdGhhdCBkbyBzdXBwb3J0IHRoZSBsaW5lYnJlYWsgbm9kZSAoZS5nLiBwYXJhZ3JhcGhzKSAtIHRoaXMgbm9kZSB3aWxsIGJlIHVzZWRcbiAgICogYXMgdGhlIGxpbmVicmVhayBpbnN0ZWFkIG9mIHN0cmlwcGluZyB0aGUgbmV3bGluZS5cbiAgICpcbiAgICogU2VlIFtsaW5lYnJlYWtSZXBsYWNlbWVudF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmxpbmVicmVha1JlcGxhY2VtZW50KS5cbiAgICovXG4gIGxpbmVicmVha1JlcGxhY2VtZW50PzpcbiAgICB8IE5vZGVTcGVjWydsaW5lYnJlYWtSZXBsYWNlbWVudCddXG4gICAgfCAoKHRoaXM6IHtcbiAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnbGluZWJyZWFrUmVwbGFjZW1lbnQnXVxuICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgIH0pID0+IE5vZGVTcGVjWydsaW5lYnJlYWtSZXBsYWNlbWVudCddKVxuXG4gIC8qKlxuICAgKiBXaGVuIGVuYWJsZWQsIGVuYWJsZXMgYm90aFxuICAgKiBbYGRlZmluaW5nQXNDb250ZXh0YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmRlZmluaW5nQXNDb250ZXh0KSBhbmRcbiAgICogW2BkZWZpbmluZ0ZvckNvbnRlbnRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuZGVmaW5pbmdGb3JDb250ZW50KS5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGV4YW1wbGUgaXNvbGF0aW5nOiB0cnVlXG4gICAqL1xuICBkZWZpbmluZz86XG4gICAgfCBOb2RlU3BlY1snZGVmaW5pbmcnXVxuICAgIHwgKCh0aGlzOiB7XG4gICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2RlZmluaW5nJ11cbiAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICB9KSA9PiBOb2RlU3BlY1snZGVmaW5pbmcnXSlcblxuICAvKipcbiAgICogV2hlbiBlbmFibGVkIChkZWZhdWx0IGlzIGZhbHNlKSwgdGhlIHNpZGVzIG9mIG5vZGVzIG9mIHRoaXMgdHlwZVxuICAgKiBjb3VudCBhcyBib3VuZGFyaWVzIHRoYXQgcmVndWxhciBlZGl0aW5nIG9wZXJhdGlvbnMsIGxpa2VcbiAgICogYmFja3NwYWNpbmcgb3IgbGlmdGluZywgd29uJ3QgY3Jvc3MuIEFuIGV4YW1wbGUgb2YgYSBub2RlIHRoYXRcbiAgICogc2hvdWxkIHByb2JhYmx5IGhhdmUgdGhpcyBlbmFibGVkIGlzIGEgdGFibGUgY2VsbC5cbiAgICovXG4gIGlzb2xhdGluZz86XG4gICAgfCBOb2RlU3BlY1snaXNvbGF0aW5nJ11cbiAgICB8ICgodGhpczoge1xuICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+Wydpc29sYXRpbmcnXVxuICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgIH0pID0+IE5vZGVTcGVjWydpc29sYXRpbmcnXSlcblxuICAvKipcbiAgICogQXNzb2NpYXRlcyBET00gcGFyc2VyIGluZm9ybWF0aW9uIHdpdGggdGhpcyBub2RlLCB3aGljaCBjYW4gYmVcbiAgICogdXNlZCBieSBbYERPTVBhcnNlci5mcm9tU2NoZW1hYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLkRPTVBhcnNlcl5mcm9tU2NoZW1hKSB0b1xuICAgKiBhdXRvbWF0aWNhbGx5IGRlcml2ZSBhIHBhcnNlci4gVGhlIGBub2RlYCBmaWVsZCBpbiB0aGUgcnVsZXMgaXNcbiAgICogaW1wbGllZCAodGhlIG5hbWUgb2YgdGhpcyBub2RlIHdpbGwgYmUgZmlsbGVkIGluIGF1dG9tYXRpY2FsbHkpLlxuICAgKiBJZiB5b3Ugc3VwcGx5IHlvdXIgb3duIHBhcnNlciwgeW91IGRvIG5vdCBuZWVkIHRvIGFsc28gc3BlY2lmeVxuICAgKiBwYXJzaW5nIHJ1bGVzIGluIHlvdXIgc2NoZW1hLlxuICAgKlxuICAgKiBAZXhhbXBsZSBwYXJzZUhUTUw6IFt7IHRhZzogJ2RpdicsIGF0dHJzOiB7ICdkYXRhLWlkJzogJ215LWJsb2NrJyB9IH1dXG4gICAqL1xuICBwYXJzZUhUTUw/OiAodGhpczoge1xuICAgIG5hbWU6IHN0cmluZ1xuICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ3BhcnNlSFRNTCddXG4gICAgZWRpdG9yPzogRWRpdG9yXG4gIH0pID0+IE5vZGVTcGVjWydwYXJzZURPTSddXG5cbiAgLyoqXG4gICAqIEEgZGVzY3JpcHRpb24gb2YgYSBET00gc3RydWN0dXJlLiBDYW4gYmUgZWl0aGVyIGEgc3RyaW5nLCB3aGljaCBpc1xuICAgKiBpbnRlcnByZXRlZCBhcyBhIHRleHQgbm9kZSwgYSBET00gbm9kZSwgd2hpY2ggaXMgaW50ZXJwcmV0ZWQgYXNcbiAgICogaXRzZWxmLCBhIGB7ZG9tLCBjb250ZW50RE9NfWAgb2JqZWN0LCBvciBhbiBhcnJheS5cbiAgICpcbiAgICogQW4gYXJyYXkgZGVzY3JpYmVzIGEgRE9NIGVsZW1lbnQuIFRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXlcbiAgICogc2hvdWxkIGJlIGEgc3RyaW5n4oCUdGhlIG5hbWUgb2YgdGhlIERPTSBlbGVtZW50LCBvcHRpb25hbGx5IHByZWZpeGVkXG4gICAqIGJ5IGEgbmFtZXNwYWNlIFVSTCBhbmQgYSBzcGFjZS4gSWYgdGhlIHNlY29uZCBlbGVtZW50IGlzIHBsYWluXG4gICAqIG9iamVjdCwgaXQgaXMgaW50ZXJwcmV0ZWQgYXMgYSBzZXQgb2YgYXR0cmlidXRlcyBmb3IgdGhlIGVsZW1lbnQuXG4gICAqIEFueSBlbGVtZW50cyBhZnRlciB0aGF0IChpbmNsdWRpbmcgdGhlIDJuZCBpZiBpdCdzIG5vdCBhbiBhdHRyaWJ1dGVcbiAgICogb2JqZWN0KSBhcmUgaW50ZXJwcmV0ZWQgYXMgY2hpbGRyZW4gb2YgdGhlIERPTSBlbGVtZW50cywgYW5kIG11c3RcbiAgICogZWl0aGVyIGJlIHZhbGlkIGBET01PdXRwdXRTcGVjYCB2YWx1ZXMsIG9yIHRoZSBudW1iZXIgemVyby5cbiAgICpcbiAgICogVGhlIG51bWJlciB6ZXJvIChwcm9ub3VuY2VkIOKAnGhvbGXigJ0pIGlzIHVzZWQgdG8gaW5kaWNhdGUgdGhlIHBsYWNlXG4gICAqIHdoZXJlIGEgbm9kZSdzIGNoaWxkIG5vZGVzIHNob3VsZCBiZSBpbnNlcnRlZC4gSWYgaXQgb2NjdXJzIGluIGFuXG4gICAqIG91dHB1dCBzcGVjLCBpdCBzaG91bGQgYmUgdGhlIG9ubHkgY2hpbGQgZWxlbWVudCBpbiBpdHMgcGFyZW50XG4gICAqIG5vZGUuXG4gICAqXG4gICAqIEBleGFtcGxlIHRvRE9NOiBbJ2RpdltkYXRhLWlkPVwibXktYmxvY2tcIl0nLCB7IGNsYXNzOiAnbXktYmxvY2snIH0sIDBdXG4gICAqL1xuICByZW5kZXJIVE1MPzpcbiAgICB8ICgoXG4gICAgICAgIHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydyZW5kZXJIVE1MJ11cbiAgICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgICAgfSxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICBub2RlOiBQcm9zZU1pcnJvck5vZGVcbiAgICAgICAgICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PlxuICAgICAgICB9LFxuICAgICAgKSA9PiBET01PdXRwdXRTcGVjKVxuICAgIHwgbnVsbFxuXG4gIC8qKlxuICAgKiByZW5kZXJzIHRoZSBub2RlIGFzIHRleHRcbiAgICogQGV4YW1wbGUgcmVuZGVyVGV4dDogKCkgPT4gJ2Zvb1xuICAgKi9cbiAgcmVuZGVyVGV4dD86XG4gICAgfCAoKFxuICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsncmVuZGVyVGV4dCddXG4gICAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICAgIH0sXG4gICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgbm9kZTogUHJvc2VNaXJyb3JOb2RlXG4gICAgICAgICAgcG9zOiBudW1iZXJcbiAgICAgICAgICBwYXJlbnQ6IFByb3NlTWlycm9yTm9kZVxuICAgICAgICAgIGluZGV4OiBudW1iZXJcbiAgICAgICAgfSxcbiAgICAgICkgPT4gc3RyaW5nKVxuICAgIHwgbnVsbFxuXG4gIC8qKlxuICAgKiBBZGQgYXR0cmlidXRlcyB0byB0aGUgbm9kZVxuICAgKiBAZXhhbXBsZSBhZGRBdHRyaWJ1dGVzOiAoKSA9PiAoeyBjbGFzczogJ2ZvbycgfSlcbiAgICovXG4gIGFkZEF0dHJpYnV0ZXM/OiAodGhpczoge1xuICAgIG5hbWU6IHN0cmluZ1xuICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZEF0dHJpYnV0ZXMnXVxuICAgIGVkaXRvcj86IEVkaXRvclxuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZW5vLWVtcHR5LW9iamVjdC10eXBlXG4gIH0pID0+IEF0dHJpYnV0ZXMgfCB7fVxufVxuXG4vKipcbiAqIFRoZSBOb2RlIGNsYXNzIGlzIHVzZWQgdG8gY3JlYXRlIGN1c3RvbSBub2RlIGV4dGVuc2lvbnMuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9hcGkvZXh0ZW5zaW9ucyNjcmVhdGUtYS1uZXctZXh0ZW5zaW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBOb2RlPE9wdGlvbnMgPSBhbnksIFN0b3JhZ2UgPSBhbnk+IGV4dGVuZHMgRXh0ZW5kYWJsZTxcbiAgT3B0aW9ucyxcbiAgU3RvcmFnZSxcbiAgTm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPlxuPiB7XG4gIHR5cGUgPSAnbm9kZSdcblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IE5vZGUgaW5zdGFuY2VcbiAgICogQHBhcmFtIGNvbmZpZyAtIE5vZGUgY29uZmlndXJhdGlvbiBvYmplY3Qgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBjb25maWd1cmF0aW9uIG9iamVjdFxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZTxPID0gYW55LCBTID0gYW55PihcbiAgICBjb25maWc6IFBhcnRpYWw8Tm9kZUNvbmZpZzxPLCBTPj4gfCAoKCkgPT4gUGFydGlhbDxOb2RlQ29uZmlnPE8sIFM+PikgPSB7fSxcbiAgKSB7XG4gICAgLy8gSWYgdGhlIGNvbmZpZyBpcyBhIGZ1bmN0aW9uLCBleGVjdXRlIGl0IHRvIGdldCB0aGUgY29uZmlndXJhdGlvbiBvYmplY3RcbiAgICBjb25zdCByZXNvbHZlZENvbmZpZyA9IHR5cGVvZiBjb25maWcgPT09ICdmdW5jdGlvbicgPyBjb25maWcoKSA6IGNvbmZpZ1xuICAgIHJldHVybiBuZXcgTm9kZTxPLCBTPihyZXNvbHZlZENvbmZpZylcbiAgfVxuXG4gIGNvbmZpZ3VyZShvcHRpb25zPzogUGFydGlhbDxPcHRpb25zPikge1xuICAgIHJldHVybiBzdXBlci5jb25maWd1cmUob3B0aW9ucykgYXMgTm9kZTxPcHRpb25zLCBTdG9yYWdlPlxuICB9XG5cbiAgZXh0ZW5kPFxuICAgIEV4dGVuZGVkT3B0aW9ucyA9IE9wdGlvbnMsXG4gICAgRXh0ZW5kZWRTdG9yYWdlID0gU3RvcmFnZSxcbiAgICBFeHRlbmRlZENvbmZpZyBleHRlbmRzIE5vZGVDb25maWc8RXh0ZW5kZWRPcHRpb25zLCBFeHRlbmRlZFN0b3JhZ2U+ID0gTm9kZUNvbmZpZzxcbiAgICAgIEV4dGVuZGVkT3B0aW9ucyxcbiAgICAgIEV4dGVuZGVkU3RvcmFnZVxuICAgID4sXG4gID4oXG4gICAgZXh0ZW5kZWRDb25maWc/OlxuICAgICAgfCAoKCkgPT4gUGFydGlhbDxFeHRlbmRlZENvbmZpZz4pXG4gICAgICB8IChQYXJ0aWFsPEV4dGVuZGVkQ29uZmlnPiAmXG4gICAgICAgICAgVGhpc1R5cGU8e1xuICAgICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgICBvcHRpb25zOiBFeHRlbmRlZE9wdGlvbnNcbiAgICAgICAgICAgIHN0b3JhZ2U6IEV4dGVuZGVkU3RvcmFnZVxuICAgICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICAgIHR5cGU6IE5vZGVUeXBlXG4gICAgICAgICAgfT4pLFxuICApOiBOb2RlPEV4dGVuZGVkT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlPiB7XG4gICAgLy8gSWYgdGhlIGV4dGVuZGVkIGNvbmZpZyBpcyBhIGZ1bmN0aW9uLCBleGVjdXRlIGl0IHRvIGdldCB0aGUgY29uZmlndXJhdGlvbiBvYmplY3RcbiAgICBjb25zdCByZXNvbHZlZENvbmZpZyA9IHR5cGVvZiBleHRlbmRlZENvbmZpZyA9PT0gJ2Z1bmN0aW9uJyA/IGV4dGVuZGVkQ29uZmlnKCkgOiBleHRlbmRlZENvbmZpZ1xuICAgIHJldHVybiBzdXBlci5leHRlbmQocmVzb2x2ZWRDb25maWcpIGFzIE5vZGU8RXh0ZW5kZWRPcHRpb25zLCBFeHRlbmRlZFN0b3JhZ2U+XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBOb2RlU2VsZWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcbmltcG9ydCB0eXBlIHsgTm9kZVZpZXcgYXMgUHJvc2VNaXJyb3JOb2RlVmlldywgVmlld011dGF0aW9uUmVjb3JkIH0gZnJvbSAnQHRpcHRhcC9wbS92aWV3J1xuXG5pbXBvcnQgdHlwZSB7IEVkaXRvciBhcyBDb3JlRWRpdG9yIH0gZnJvbSAnLi9FZGl0b3IuanMnXG5pbXBvcnQgdHlwZSB7IERlY29yYXRpb25XaXRoVHlwZSwgTm9kZVZpZXdSZW5kZXJlck9wdGlvbnMsIE5vZGVWaWV3UmVuZGVyZXJQcm9wcyB9IGZyb20gJy4vdHlwZXMuanMnXG5pbXBvcnQgeyBpc0FuZHJvaWQgfSBmcm9tICcuL3V0aWxpdGllcy9pc0FuZHJvaWQuanMnXG5pbXBvcnQgeyBpc2lPUyB9IGZyb20gJy4vdXRpbGl0aWVzL2lzaU9TLmpzJ1xuXG4vKipcbiAqIE5vZGUgdmlld3MgYXJlIHVzZWQgdG8gY3VzdG9taXplIHRoZSByZW5kZXJlZCBET00gc3RydWN0dXJlIG9mIGEgbm9kZS5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2d1aWRlL25vZGUtdmlld3NcbiAqL1xuZXhwb3J0IGNsYXNzIE5vZGVWaWV3PFxuICBDb21wb25lbnQsXG4gIE5vZGVFZGl0b3IgZXh0ZW5kcyBDb3JlRWRpdG9yID0gQ29yZUVkaXRvcixcbiAgT3B0aW9ucyBleHRlbmRzIE5vZGVWaWV3UmVuZGVyZXJPcHRpb25zID0gTm9kZVZpZXdSZW5kZXJlck9wdGlvbnMsXG4+IGltcGxlbWVudHMgUHJvc2VNaXJyb3JOb2RlVmlldyB7XG4gIGNvbXBvbmVudDogQ29tcG9uZW50XG5cbiAgZWRpdG9yOiBOb2RlRWRpdG9yXG5cbiAgb3B0aW9uczogT3B0aW9uc1xuXG4gIGV4dGVuc2lvbjogTm9kZVZpZXdSZW5kZXJlclByb3BzWydleHRlbnNpb24nXVxuXG4gIG5vZGU6IE5vZGVWaWV3UmVuZGVyZXJQcm9wc1snbm9kZSddXG5cbiAgZGVjb3JhdGlvbnM6IE5vZGVWaWV3UmVuZGVyZXJQcm9wc1snZGVjb3JhdGlvbnMnXVxuXG4gIGlubmVyRGVjb3JhdGlvbnM6IE5vZGVWaWV3UmVuZGVyZXJQcm9wc1snaW5uZXJEZWNvcmF0aW9ucyddXG5cbiAgdmlldzogTm9kZVZpZXdSZW5kZXJlclByb3BzWyd2aWV3J11cblxuICBnZXRQb3M6IE5vZGVWaWV3UmVuZGVyZXJQcm9wc1snZ2V0UG9zJ11cblxuICBIVE1MQXR0cmlidXRlczogTm9kZVZpZXdSZW5kZXJlclByb3BzWydIVE1MQXR0cmlidXRlcyddXG5cbiAgaXNEcmFnZ2luZyA9IGZhbHNlXG5cbiAgY29uc3RydWN0b3IoY29tcG9uZW50OiBDb21wb25lbnQsIHByb3BzOiBOb2RlVmlld1JlbmRlcmVyUHJvcHMsIG9wdGlvbnM/OiBQYXJ0aWFsPE9wdGlvbnM+KSB7XG4gICAgdGhpcy5jb21wb25lbnQgPSBjb21wb25lbnRcbiAgICB0aGlzLmVkaXRvciA9IHByb3BzLmVkaXRvciBhcyBOb2RlRWRpdG9yXG4gICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgc3RvcEV2ZW50OiBudWxsLFxuICAgICAgaWdub3JlTXV0YXRpb246IG51bGwsXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH0gYXMgT3B0aW9uc1xuICAgIHRoaXMuZXh0ZW5zaW9uID0gcHJvcHMuZXh0ZW5zaW9uXG4gICAgdGhpcy5ub2RlID0gcHJvcHMubm9kZVxuICAgIHRoaXMuZGVjb3JhdGlvbnMgPSBwcm9wcy5kZWNvcmF0aW9ucyBhcyBEZWNvcmF0aW9uV2l0aFR5cGVbXVxuICAgIHRoaXMuaW5uZXJEZWNvcmF0aW9ucyA9IHByb3BzLmlubmVyRGVjb3JhdGlvbnNcbiAgICB0aGlzLnZpZXcgPSBwcm9wcy52aWV3XG4gICAgdGhpcy5IVE1MQXR0cmlidXRlcyA9IHByb3BzLkhUTUxBdHRyaWJ1dGVzXG4gICAgdGhpcy5nZXRQb3MgPSBwcm9wcy5nZXRQb3NcbiAgICB0aGlzLm1vdW50KClcbiAgfVxuXG4gIG1vdW50KCkge1xuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIHJldHVyblxuICB9XG5cbiAgZ2V0IGRvbSgpOiBIVE1MRWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yLnZpZXcuZG9tIGFzIEhUTUxFbGVtZW50XG4gIH1cblxuICBnZXQgY29udGVudERPTSgpOiBIVE1MRWxlbWVudCB8IG51bGwge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBvbkRyYWdTdGFydChldmVudDogRHJhZ0V2ZW50KSB7XG4gICAgY29uc3QgeyB2aWV3IH0gPSB0aGlzLmVkaXRvclxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudFxuXG4gICAgLy8gZ2V0IHRoZSBkcmFnIGhhbmRsZSBlbGVtZW50XG4gICAgLy8gYGNsb3Nlc3RgIGlzIG5vdCBhdmFpbGFibGUgZm9yIHRleHQgbm9kZXMgc28gd2UgbWF5IGhhdmUgdG8gdXNlIGl0cyBwYXJlbnRcbiAgICBjb25zdCBkcmFnSGFuZGxlID1cbiAgICAgIHRhcmdldC5ub2RlVHlwZSA9PT0gM1xuICAgICAgICA/IHRhcmdldC5wYXJlbnRFbGVtZW50Py5jbG9zZXN0KCdbZGF0YS1kcmFnLWhhbmRsZV0nKVxuICAgICAgICA6IHRhcmdldC5jbG9zZXN0KCdbZGF0YS1kcmFnLWhhbmRsZV0nKVxuXG4gICAgaWYgKCF0aGlzLmRvbSB8fCB0aGlzLmNvbnRlbnRET00/LmNvbnRhaW5zKHRhcmdldCkgfHwgIWRyYWdIYW5kbGUpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGxldCB4ID0gMFxuICAgIGxldCB5ID0gMFxuXG4gICAgLy8gY2FsY3VsYXRlIG9mZnNldCBmb3IgZHJhZyBlbGVtZW50IGlmIHdlIHVzZSBhIGRpZmZlcmVudCBkcmFnIGhhbmRsZSBlbGVtZW50XG4gICAgaWYgKHRoaXMuZG9tICE9PSBkcmFnSGFuZGxlKSB7XG4gICAgICBjb25zdCBkb21Cb3ggPSB0aGlzLmRvbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgY29uc3QgaGFuZGxlQm94ID0gZHJhZ0hhbmRsZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuXG4gICAgICAvLyBJbiBSZWFjdCwgd2UgaGF2ZSB0byBnbyB0aHJvdWdoIG5hdGl2ZUV2ZW50IHRvIHJlYWNoIG9mZnNldFgvb2Zmc2V0WS5cbiAgICAgIGNvbnN0IG9mZnNldFggPSBldmVudC5vZmZzZXRYID8/IChldmVudCBhcyBhbnkpLm5hdGl2ZUV2ZW50Py5vZmZzZXRYXG4gICAgICBjb25zdCBvZmZzZXRZID0gZXZlbnQub2Zmc2V0WSA/PyAoZXZlbnQgYXMgYW55KS5uYXRpdmVFdmVudD8ub2Zmc2V0WVxuXG4gICAgICB4ID0gaGFuZGxlQm94LnggLSBkb21Cb3gueCArIG9mZnNldFhcbiAgICAgIHkgPSBoYW5kbGVCb3gueSAtIGRvbUJveC55ICsgb2Zmc2V0WVxuICAgIH1cblxuICAgIGNvbnN0IGNsb25lZE5vZGUgPSB0aGlzLmRvbS5jbG9uZU5vZGUodHJ1ZSkgYXMgSFRNTEVsZW1lbnRcblxuICAgIC8vIFByZXNlcnZlIHRoZSB2aXN1YWwgc2l6ZSBvZiB0aGUgb3JpZ2luYWwgd2hlbiB1c2luZyB0aGUgY2xvbmUgYXNcbiAgICAvLyB0aGUgZHJhZyBpbWFnZS5cbiAgICB0cnkge1xuICAgICAgY29uc3QgZG9tQm94ID0gdGhpcy5kb20uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICAgIGNsb25lZE5vZGUuc3R5bGUud2lkdGggPSBgJHtNYXRoLnJvdW5kKGRvbUJveC53aWR0aCl9cHhgXG4gICAgICBjbG9uZWROb2RlLnN0eWxlLmhlaWdodCA9IGAke01hdGgucm91bmQoZG9tQm94LmhlaWdodCl9cHhgXG4gICAgICBjbG9uZWROb2RlLnN0eWxlLmJveFNpemluZyA9ICdib3JkZXItYm94J1xuICAgICAgLy8gRW5zdXJlIHRoZSBjbG9uZSBkb2Vzbid0IGNhcHR1cmUgcG9pbnRlciBldmVudHMgd2hpbGUgb2Zmc2NyZWVuXG4gICAgICBjbG9uZWROb2RlLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSdcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIGlnbm9yZSBtZWFzdXJlbWVudCBlcnJvcnMgKGUuZy4gaWYgZWxlbWVudCBub3QgaW4gRE9NKVxuICAgIH1cblxuICAgIC8vIFNvbWUgYnJvd3NlcnMgKG5vdGFibHkgU2FmYXJpKSByZXF1aXJlIHRoZSBlbGVtZW50IHBhc3NlZCB0b1xuICAgIC8vIHNldERyYWdJbWFnZSB0byBiZSBwcmVzZW50IGluIHRoZSBET00uIFVzaW5nIGEgZGV0YWNoZWQgbm9kZSBjYW5cbiAgICAvLyBjYXVzZSB0aGUgZHJhZyB0byBpbW1lZGlhdGVseSBlbmQuXG4gICAgbGV0IGRyYWdJbWFnZVdyYXBwZXI6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGxcblxuICAgIHRyeSB7XG4gICAgICBkcmFnSW1hZ2VXcmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgIGRyYWdJbWFnZVdyYXBwZXIuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnXG4gICAgICBkcmFnSW1hZ2VXcmFwcGVyLnN0eWxlLnRvcCA9ICctOTk5OXB4J1xuICAgICAgZHJhZ0ltYWdlV3JhcHBlci5zdHlsZS5sZWZ0ID0gJy05OTk5cHgnXG4gICAgICBkcmFnSW1hZ2VXcmFwcGVyLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSdcbiAgICAgIGRyYWdJbWFnZVdyYXBwZXIuYXBwZW5kQ2hpbGQoY2xvbmVkTm9kZSlcbiAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZHJhZ0ltYWdlV3JhcHBlcilcblxuICAgICAgZXZlbnQuZGF0YVRyYW5zZmVyPy5zZXREcmFnSW1hZ2UoY2xvbmVkTm9kZSwgeCwgeSlcbiAgICB9IGZpbmFsbHkge1xuICAgICAgLy8gUmVtb3ZlIHRoZSB3cmFwcGVyIG9uIHRoZSBuZXh0IHRpY2sgc28gdGhlIGJyb3dzZXIgY2FuIHVzZSB0aGVcbiAgICAgIC8vIGVsZW1lbnQgYXMgdGhlIGRyYWcgaW1hZ2UuIEEgMG1zIHRpbWVvdXQgaXMgZW5vdWdoIGluIHByYWN0aWNlLlxuICAgICAgaWYgKGRyYWdJbWFnZVdyYXBwZXIpIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGRyYWdJbWFnZVdyYXBwZXI/LnJlbW92ZSgpXG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBpZ25vcmUgcmVtb3ZhbCBlcnJvcnNcbiAgICAgICAgICB9XG4gICAgICAgIH0sIDApXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcG9zID0gdGhpcy5nZXRQb3MoKVxuXG4gICAgaWYgKHR5cGVvZiBwb3MgIT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgLy8gd2UgbmVlZCB0byB0ZWxsIFByb3NlTWlycm9yIHRoYXQgd2Ugd2FudCB0byBtb3ZlIHRoZSB3aG9sZSBub2RlXG4gICAgLy8gc28gd2UgY3JlYXRlIGEgTm9kZVNlbGVjdGlvblxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IE5vZGVTZWxlY3Rpb24uY3JlYXRlKHZpZXcuc3RhdGUuZG9jLCBwb3MpXG4gICAgY29uc3QgdHJhbnNhY3Rpb24gPSB2aWV3LnN0YXRlLnRyLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pXG5cbiAgICB2aWV3LmRpc3BhdGNoKHRyYW5zYWN0aW9uKVxuICB9XG5cbiAgc3RvcEV2ZW50KGV2ZW50OiBFdmVudCkge1xuICAgIGlmICghdGhpcy5kb20pIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdGhpcy5vcHRpb25zLnN0b3BFdmVudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5zdG9wRXZlbnQoeyBldmVudCB9KVxuICAgIH1cblxuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudFxuICAgIGNvbnN0IGlzSW5FbGVtZW50ID0gdGhpcy5kb20uY29udGFpbnModGFyZ2V0KSAmJiAhdGhpcy5jb250ZW50RE9NPy5jb250YWlucyh0YXJnZXQpXG5cbiAgICAvLyBhbnkgZXZlbnQgZnJvbSBjaGlsZCBub2RlcyBzaG91bGQgYmUgaGFuZGxlZCBieSBQcm9zZU1pcnJvclxuICAgIGlmICghaXNJbkVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGNvbnN0IGlzRHJhZ0V2ZW50ID0gZXZlbnQudHlwZS5zdGFydHNXaXRoKCdkcmFnJylcbiAgICBjb25zdCBpc0RyYWdPdmVyRW50ZXJFdmVudCA9IGV2ZW50LnR5cGUgPT09ICdkcmFnb3ZlcicgfHwgZXZlbnQudHlwZSA9PT0gJ2RyYWdlbnRlcidcbiAgICBjb25zdCBpc0Ryb3BFdmVudCA9IGV2ZW50LnR5cGUgPT09ICdkcm9wJ1xuICAgIGNvbnN0IGlzSW5wdXQgPVxuICAgICAgWydJTlBVVCcsICdCVVRUT04nLCAnU0VMRUNUJywgJ1RFWFRBUkVBJ10uaW5jbHVkZXModGFyZ2V0LnRhZ05hbWUpIHx8IHRhcmdldC5pc0NvbnRlbnRFZGl0YWJsZVxuXG4gICAgLy8gYW55IGlucHV0IGV2ZW50IHdpdGhpbiBub2RlIHZpZXdzIHNob3VsZCBiZSBpZ25vcmVkIGJ5IFByb3NlTWlycm9yXG4gICAgaWYgKGlzSW5wdXQgJiYgIWlzRHJvcEV2ZW50ICYmICFpc0RyYWdFdmVudCkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICBjb25zdCB7IGlzRWRpdGFibGUgfSA9IHRoaXMuZWRpdG9yXG4gICAgY29uc3QgeyBpc0RyYWdnaW5nIH0gPSB0aGlzXG4gICAgY29uc3QgaXNEcmFnZ2FibGUgPSAhIXRoaXMubm9kZS50eXBlLnNwZWMuZHJhZ2dhYmxlXG4gICAgY29uc3QgaXNTZWxlY3RhYmxlID0gTm9kZVNlbGVjdGlvbi5pc1NlbGVjdGFibGUodGhpcy5ub2RlKVxuICAgIGNvbnN0IGlzQ29weUV2ZW50ID0gZXZlbnQudHlwZSA9PT0gJ2NvcHknXG4gICAgY29uc3QgaXNQYXN0ZUV2ZW50ID0gZXZlbnQudHlwZSA9PT0gJ3Bhc3RlJ1xuICAgIGNvbnN0IGlzQ3V0RXZlbnQgPSBldmVudC50eXBlID09PSAnY3V0J1xuICAgIGNvbnN0IGlzQ2xpY2tFdmVudCA9IGV2ZW50LnR5cGUgPT09ICdtb3VzZWRvd24nXG5cbiAgICAvLyBQcm9zZU1pcnJvciB0cmllcyB0byBkcmFnIHNlbGVjdGFibGUgbm9kZXNcbiAgICAvLyBldmVuIGlmIGBkcmFnZ2FibGVgIGlzIHNldCB0byBgZmFsc2VgXG4gICAgLy8gdGhpcyBmaXggcHJldmVudHMgdGhhdFxuICAgIGlmICghaXNEcmFnZ2FibGUgJiYgaXNTZWxlY3RhYmxlICYmIGlzRHJhZ0V2ZW50ICYmIGV2ZW50LnRhcmdldCA9PT0gdGhpcy5kb20pIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICB9XG5cbiAgICBpZiAoaXNEcmFnZ2FibGUgJiYgaXNEcmFnRXZlbnQgJiYgIWlzRHJhZ2dpbmcgJiYgZXZlbnQudGFyZ2V0ID09PSB0aGlzLmRvbSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gd2UgaGF2ZSB0byBzdG9yZSB0aGF0IGRyYWdnaW5nIHN0YXJ0ZWRcbiAgICBpZiAoaXNEcmFnZ2FibGUgJiYgaXNFZGl0YWJsZSAmJiAhaXNEcmFnZ2luZyAmJiBpc0NsaWNrRXZlbnQpIHtcbiAgICAgIGNvbnN0IGRyYWdIYW5kbGUgPSB0YXJnZXQuY2xvc2VzdCgnW2RhdGEtZHJhZy1oYW5kbGVdJylcbiAgICAgIGNvbnN0IGlzVmFsaWREcmFnSGFuZGxlID1cbiAgICAgICAgZHJhZ0hhbmRsZSAmJiAodGhpcy5kb20gPT09IGRyYWdIYW5kbGUgfHwgdGhpcy5kb20uY29udGFpbnMoZHJhZ0hhbmRsZSkpXG5cbiAgICAgIGlmIChpc1ZhbGlkRHJhZ0hhbmRsZSkge1xuICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlXG5cbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAnZHJhZ2VuZCcsXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2VcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgb25jZTogdHJ1ZSB9LFxuICAgICAgICApXG5cbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAnZHJvcCcsXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2VcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgb25jZTogdHJ1ZSB9LFxuICAgICAgICApXG5cbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcbiAgICAgICAgICAnbW91c2V1cCcsXG4gICAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2VcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgb25jZTogdHJ1ZSB9LFxuICAgICAgICApXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhlc2UgZXZlbnRzIGFyZSBoYW5kbGVkIGJ5IHByb3NlbWlycm9yXG4gICAgaWYgKFxuICAgICAgaXNEcmFnZ2luZyB8fFxuICAgICAgaXNEcmFnT3ZlckVudGVyRXZlbnQgfHxcbiAgICAgIGlzRHJvcEV2ZW50IHx8XG4gICAgICBpc0NvcHlFdmVudCB8fFxuICAgICAgaXNQYXN0ZUV2ZW50IHx8XG4gICAgICBpc0N1dEV2ZW50IHx8XG4gICAgICAoaXNDbGlja0V2ZW50ICYmIGlzU2VsZWN0YWJsZSlcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gYSBET00gW211dGF0aW9uXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTXV0YXRpb25PYnNlcnZlcikgb3IgYSBzZWxlY3Rpb24gY2hhbmdlIGhhcHBlbnMgd2l0aGluIHRoZSB2aWV3LlxuICAgKiBAcmV0dXJuIGBmYWxzZWAgaWYgdGhlIGVkaXRvciBzaG91bGQgcmUtcmVhZCB0aGUgc2VsZWN0aW9uIG9yIHJlLXBhcnNlIHRoZSByYW5nZSBhcm91bmQgdGhlIG11dGF0aW9uXG4gICAqIEByZXR1cm4gYHRydWVgIGlmIGl0IGNhbiBzYWZlbHkgYmUgaWdub3JlZC5cbiAgICovXG4gIGlnbm9yZU11dGF0aW9uKG11dGF0aW9uOiBWaWV3TXV0YXRpb25SZWNvcmQpIHtcbiAgICBpZiAoIXRoaXMuZG9tIHx8ICF0aGlzLmNvbnRlbnRET00pIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMuaWdub3JlTXV0YXRpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuaWdub3JlTXV0YXRpb24oeyBtdXRhdGlvbiB9KVxuICAgIH1cblxuICAgIC8vIGEgbGVhZi9hdG9tIG5vZGUgaXMgbGlrZSBhIGJsYWNrIGJveCBmb3IgUHJvc2VNaXJyb3JcbiAgICAvLyBhbmQgc2hvdWxkIGJlIGZ1bGx5IGhhbmRsZWQgYnkgdGhlIG5vZGUgdmlld1xuICAgIGlmICh0aGlzLm5vZGUuaXNMZWFmIHx8IHRoaXMubm9kZS5pc0F0b20pIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gUHJvc2VNaXJyb3Igc2hvdWxkIGhhbmRsZSBhbnkgc2VsZWN0aW9uc1xuICAgIGlmIChtdXRhdGlvbi50eXBlID09PSAnc2VsZWN0aW9uJykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gdHJ5IHRvIHByZXZlbnQgYSBidWcgb24gaU9TIGFuZCBBbmRyb2lkIHRoYXQgd2lsbCBicmVhayBub2RlIHZpZXdzIG9uIGVudGVyXG4gICAgLy8gdGhpcyBpcyBiZWNhdXNlIFByb3NlTWlycm9yIGNhbuKAmXQgcHJldmVudERpc3BhdGNoIG9uIGVudGVyXG4gICAgLy8gdGhpcyB3aWxsIGxlYWQgdG8gYSByZS1yZW5kZXIgb2YgdGhlIG5vZGUgdmlldyBvbiBlbnRlclxuICAgIC8vIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL3VlYmVyZG9zaXMvdGlwdGFwL2lzc3Vlcy8xMjE0XG4gICAgLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vdWViZXJkb3Npcy90aXB0YXAvaXNzdWVzLzI1MzRcbiAgICBpZiAoXG4gICAgICB0aGlzLmRvbS5jb250YWlucyhtdXRhdGlvbi50YXJnZXQpICYmXG4gICAgICBtdXRhdGlvbi50eXBlID09PSAnY2hpbGRMaXN0JyAmJlxuICAgICAgKGlzaU9TKCkgfHwgaXNBbmRyb2lkKCkpICYmXG4gICAgICB0aGlzLmVkaXRvci5pc0ZvY3VzZWRcbiAgICApIHtcbiAgICAgIGNvbnN0IGNoYW5nZWROb2RlcyA9IFtcbiAgICAgICAgLi4uQXJyYXkuZnJvbShtdXRhdGlvbi5hZGRlZE5vZGVzKSxcbiAgICAgICAgLi4uQXJyYXkuZnJvbShtdXRhdGlvbi5yZW1vdmVkTm9kZXMpLFxuICAgICAgXSBhcyBIVE1MRWxlbWVudFtdXG5cbiAgICAgIC8vIHdl4oCZbGwgY2hlY2sgaWYgZXZlcnkgY2hhbmdlZCBub2RlIGlzIGNvbnRlbnRFZGl0YWJsZVxuICAgICAgLy8gdG8gbWFrZSBzdXJlIGl04oCZcyBwcm9iYWJseSBtdXRhdGVkIGJ5IFByb3NlTWlycm9yXG4gICAgICBpZiAoY2hhbmdlZE5vZGVzLmV2ZXJ5KG5vZGUgPT4gbm9kZS5pc0NvbnRlbnRFZGl0YWJsZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gd2Ugd2lsbCBhbGxvdyBtdXRhdGlvbiBjb250ZW50RE9NIHdpdGggYXR0cmlidXRlc1xuICAgIC8vIHNvIHdlIGNhbiBmb3IgZXhhbXBsZSBhZGRpbmcgY2xhc3NlcyB3aXRoaW4gb3VyIG5vZGUgdmlld1xuICAgIGlmICh0aGlzLmNvbnRlbnRET00gPT09IG11dGF0aW9uLnRhcmdldCAmJiBtdXRhdGlvbi50eXBlID09PSAnYXR0cmlidXRlcycpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gUHJvc2VNaXJyb3Igc2hvdWxkIGhhbmRsZSBhbnkgY2hhbmdlcyB3aXRoaW4gY29udGVudERPTVxuICAgIGlmICh0aGlzLmNvbnRlbnRET00uY29udGFpbnMobXV0YXRpb24udGFyZ2V0KSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIHByb3NlbWlycm9yIG5vZGUuXG4gICAqL1xuICB1cGRhdGVBdHRyaWJ1dGVzKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT4pOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRvci5jb21tYW5kcy5jb21tYW5kKCh7IHRyIH0pID0+IHtcbiAgICAgIGNvbnN0IHBvcyA9IHRoaXMuZ2V0UG9zKClcblxuICAgICAgaWYgKHR5cGVvZiBwb3MgIT09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuXG4gICAgICB0ci5zZXROb2RlTWFya3VwKHBvcywgdW5kZWZpbmVkLCB7XG4gICAgICAgIC4uLnRoaXMubm9kZS5hdHRycyxcbiAgICAgICAgLi4uYXR0cmlidXRlcyxcbiAgICAgIH0pXG5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIG5vZGUuXG4gICAqL1xuICBkZWxldGVOb2RlKCk6IHZvaWQge1xuICAgIGNvbnN0IGZyb20gPSB0aGlzLmdldFBvcygpXG5cbiAgICBpZiAodHlwZW9mIGZyb20gIT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY29uc3QgdG8gPSBmcm9tICsgdGhpcy5ub2RlLm5vZGVTaXplXG5cbiAgICB0aGlzLmVkaXRvci5jb21tYW5kcy5kZWxldGVSYW5nZSh7IGZyb20sIHRvIH0pXG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IE1hcmtUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgZ2V0TWFya3NCZXR3ZWVuIH0gZnJvbSAnLi4vaGVscGVycy9nZXRNYXJrc0JldHdlZW4uanMnXG5pbXBvcnQgdHlwZSB7IFBhc3RlUnVsZUZpbmRlciB9IGZyb20gJy4uL1Bhc3RlUnVsZS5qcydcbmltcG9ydCB7IFBhc3RlUnVsZSB9IGZyb20gJy4uL1Bhc3RlUnVsZS5qcydcbmltcG9ydCB0eXBlIHsgRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5IH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBjYWxsT3JSZXR1cm4gfSBmcm9tICcuLi91dGlsaXRpZXMvY2FsbE9yUmV0dXJuLmpzJ1xuXG4vKipcbiAqIEJ1aWxkIGFuIHBhc3RlIHJ1bGUgdGhhdCBhZGRzIGEgbWFyayB3aGVuIHRoZVxuICogbWF0Y2hlZCB0ZXh0IGlzIHBhc3RlZCBpbnRvIGl0LlxuICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZG9jcy9lZGl0b3IvZXh0ZW5zaW9ucy9jdXN0b20tZXh0ZW5zaW9ucy9leHRlbmQtZXhpc3RpbmcjcGFzdGUtcnVsZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcmtQYXN0ZVJ1bGUoY29uZmlnOiB7XG4gIGZpbmQ6IFBhc3RlUnVsZUZpbmRlclxuICB0eXBlOiBNYXJrVHlwZVxuICBnZXRBdHRyaWJ1dGVzPzpcbiAgICB8IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICB8ICgobWF0Y2g6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheSwgZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiBSZWNvcmQ8c3RyaW5nLCBhbnk+KVxuICAgIHwgZmFsc2VcbiAgICB8IG51bGxcbn0pIHtcbiAgcmV0dXJuIG5ldyBQYXN0ZVJ1bGUoe1xuICAgIGZpbmQ6IGNvbmZpZy5maW5kLFxuICAgIGhhbmRsZXI6ICh7IHN0YXRlLCByYW5nZSwgbWF0Y2gsIHBhc3RlRXZlbnQgfSkgPT4ge1xuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IGNhbGxPclJldHVybihjb25maWcuZ2V0QXR0cmlidXRlcywgdW5kZWZpbmVkLCBtYXRjaCwgcGFzdGVFdmVudClcblxuICAgICAgaWYgKGF0dHJpYnV0ZXMgPT09IGZhbHNlIHx8IGF0dHJpYnV0ZXMgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyB0ciB9ID0gc3RhdGVcbiAgICAgIGNvbnN0IGNhcHR1cmVHcm91cCA9IG1hdGNoW21hdGNoLmxlbmd0aCAtIDFdXG4gICAgICBjb25zdCBmdWxsTWF0Y2ggPSBtYXRjaFswXVxuICAgICAgbGV0IG1hcmtFbmQgPSByYW5nZS50b1xuXG4gICAgICBpZiAoY2FwdHVyZUdyb3VwKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0U3BhY2VzID0gZnVsbE1hdGNoLnNlYXJjaCgvXFxTLylcbiAgICAgICAgY29uc3QgdGV4dFN0YXJ0ID0gcmFuZ2UuZnJvbSArIGZ1bGxNYXRjaC5pbmRleE9mKGNhcHR1cmVHcm91cClcbiAgICAgICAgY29uc3QgdGV4dEVuZCA9IHRleHRTdGFydCArIGNhcHR1cmVHcm91cC5sZW5ndGhcblxuICAgICAgICBjb25zdCBleGNsdWRlZE1hcmtzID0gZ2V0TWFya3NCZXR3ZWVuKHJhbmdlLmZyb20sIHJhbmdlLnRvLCBzdGF0ZS5kb2MpXG4gICAgICAgICAgLmZpbHRlcihpdGVtID0+IHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbnN0IGV4Y2x1ZGVkID0gaXRlbS5tYXJrLnR5cGUuZXhjbHVkZWQgYXMgTWFya1R5cGVbXVxuXG4gICAgICAgICAgICByZXR1cm4gZXhjbHVkZWQuZmluZCh0eXBlID0+IHR5cGUgPT09IGNvbmZpZy50eXBlICYmIHR5cGUgIT09IGl0ZW0ubWFyay50eXBlKVxuICAgICAgICAgIH0pXG4gICAgICAgICAgLmZpbHRlcihpdGVtID0+IGl0ZW0udG8gPiB0ZXh0U3RhcnQpXG5cbiAgICAgICAgaWYgKGV4Y2x1ZGVkTWFya3MubGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0ZXh0RW5kIDwgcmFuZ2UudG8pIHtcbiAgICAgICAgICB0ci5kZWxldGUodGV4dEVuZCwgcmFuZ2UudG8pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGV4dFN0YXJ0ID4gcmFuZ2UuZnJvbSkge1xuICAgICAgICAgIHRyLmRlbGV0ZShyYW5nZS5mcm9tICsgc3RhcnRTcGFjZXMsIHRleHRTdGFydClcbiAgICAgICAgfVxuXG4gICAgICAgIG1hcmtFbmQgPSByYW5nZS5mcm9tICsgc3RhcnRTcGFjZXMgKyBjYXB0dXJlR3JvdXAubGVuZ3RoXG5cbiAgICAgICAgdHIuYWRkTWFyayhyYW5nZS5mcm9tICsgc3RhcnRTcGFjZXMsIG1hcmtFbmQsIGNvbmZpZy50eXBlLmNyZWF0ZShhdHRyaWJ1dGVzIHx8IHt9KSlcblxuICAgICAgICAvLyBPbmx5IHJlbW92ZSB0aGUgc3RvcmVkIG1hcmsgaWYgdGhlIG1hdGNoIGlzIG5vdCBhdCB0aGUgZW5kIG9mIHRoZVxuICAgICAgICAvLyBwYXN0ZWQgdGV4dC4gV2hlbiBhIG1hcmsgZXh0ZW5kcyB0byB0aGUgZW5kIG9mIHRoZSBjb250ZW50LCByZW1vdmluZ1xuICAgICAgICAvLyBpdCBvdmVycmlkZXMgdGhlIG1hcmsncyBgaW5jbHVzaXZlYCBiZWhhdmlvciBhbmQgaW5jb3JyZWN0bHkgcGxhY2VzXG4gICAgICAgIC8vIHRoZSBjdXJzb3Igb3V0c2lkZSB0aGUgbWFyay5cbiAgICAgICAgY29uc3QgaXNNYXRjaEF0RW5kT2ZUZXh0ID1cbiAgICAgICAgICBtYXRjaC5pbmRleCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgbWF0Y2guaW5wdXQgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgIG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoID49IG1hdGNoLmlucHV0Lmxlbmd0aFxuXG4gICAgICAgIGlmICghaXNNYXRjaEF0RW5kT2ZUZXh0KSB7XG4gICAgICAgICAgdHIucmVtb3ZlU3RvcmVkTWFyayhjb25maWcudHlwZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gIH0pXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB0eXBlIHsgUGFzdGVSdWxlRmluZGVyIH0gZnJvbSAnLi4vUGFzdGVSdWxlLmpzJ1xuaW1wb3J0IHsgUGFzdGVSdWxlIH0gZnJvbSAnLi4vUGFzdGVSdWxlLmpzJ1xuaW1wb3J0IHR5cGUgeyBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXksIEpTT05Db250ZW50IH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBjYWxsT3JSZXR1cm4gfSBmcm9tICcuLi91dGlsaXRpZXMvaW5kZXguanMnXG5cbi8qKlxuICogQnVpbGQgYW4gcGFzdGUgcnVsZSB0aGF0IGFkZHMgYSBub2RlIHdoZW4gdGhlXG4gKiBtYXRjaGVkIHRleHQgaXMgcGFzdGVkIGludG8gaXQuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9hcGkvcGFzdGUtcnVsZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vZGVQYXN0ZVJ1bGUoY29uZmlnOiB7XG4gIGZpbmQ6IFBhc3RlUnVsZUZpbmRlclxuICB0eXBlOiBOb2RlVHlwZVxuICBnZXRBdHRyaWJ1dGVzPzpcbiAgICB8IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICB8ICgobWF0Y2g6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheSwgZXZlbnQ6IENsaXBib2FyZEV2ZW50KSA9PiBSZWNvcmQ8c3RyaW5nLCBhbnk+KVxuICAgIHwgZmFsc2VcbiAgICB8IG51bGxcbiAgZ2V0Q29udGVudD86IEpTT05Db250ZW50W10gfCAoKGF0dHJzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBKU09OQ29udGVudFtdKSB8IGZhbHNlIHwgbnVsbFxufSkge1xuICByZXR1cm4gbmV3IFBhc3RlUnVsZSh7XG4gICAgZmluZDogY29uZmlnLmZpbmQsXG4gICAgaGFuZGxlcih7IG1hdGNoLCBjaGFpbiwgcmFuZ2UsIHBhc3RlRXZlbnQgfSkge1xuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IGNhbGxPclJldHVybihjb25maWcuZ2V0QXR0cmlidXRlcywgdW5kZWZpbmVkLCBtYXRjaCwgcGFzdGVFdmVudClcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBjYWxsT3JSZXR1cm4oY29uZmlnLmdldENvbnRlbnQsIHVuZGVmaW5lZCwgYXR0cmlidXRlcylcblxuICAgICAgaWYgKGF0dHJpYnV0ZXMgPT09IGZhbHNlIHx8IGF0dHJpYnV0ZXMgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm9kZSA9IHsgdHlwZTogY29uZmlnLnR5cGUubmFtZSwgYXR0cnM6IGF0dHJpYnV0ZXMgfSBhcyBKU09OQ29udGVudFxuXG4gICAgICBpZiAoY29udGVudCkge1xuICAgICAgICBub2RlLmNvbnRlbnQgPSBjb250ZW50XG4gICAgICB9XG5cbiAgICAgIGlmIChtYXRjaC5pbnB1dCkge1xuICAgICAgICBjaGFpbigpLmRlbGV0ZVJhbmdlKHJhbmdlKS5pbnNlcnRDb250ZW50QXQocmFuZ2UuZnJvbSwgbm9kZSlcbiAgICAgIH1cbiAgICB9LFxuICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgUGFzdGVSdWxlRmluZGVyIH0gZnJvbSAnLi4vUGFzdGVSdWxlLmpzJ1xuaW1wb3J0IHsgUGFzdGVSdWxlIH0gZnJvbSAnLi4vUGFzdGVSdWxlLmpzJ1xuXG4vKipcbiAqIEJ1aWxkIGFuIHBhc3RlIHJ1bGUgdGhhdCByZXBsYWNlcyB0ZXh0IHdoZW4gdGhlXG4gKiBtYXRjaGVkIHRleHQgaXMgcGFzdGVkIGludG8gaXQuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9leHRlbnNpb25zL2N1c3RvbS1leHRlbnNpb25zL2V4dGVuZC1leGlzdGluZyNwYXN0ZS1ydWxlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdGV4dFBhc3RlUnVsZShjb25maWc6IHsgZmluZDogUGFzdGVSdWxlRmluZGVyOyByZXBsYWNlOiBzdHJpbmcgfSkge1xuICByZXR1cm4gbmV3IFBhc3RlUnVsZSh7XG4gICAgZmluZDogY29uZmlnLmZpbmQsXG4gICAgaGFuZGxlcjogKHsgc3RhdGUsIHJhbmdlLCBtYXRjaCB9KSA9PiB7XG4gICAgICBsZXQgaW5zZXJ0ID0gY29uZmlnLnJlcGxhY2VcbiAgICAgIGxldCBzdGFydCA9IHJhbmdlLmZyb21cbiAgICAgIGNvbnN0IGVuZCA9IHJhbmdlLnRvXG5cbiAgICAgIGlmIChtYXRjaFsxXSkge1xuICAgICAgICBjb25zdCBvZmZzZXQgPSBtYXRjaFswXS5sYXN0SW5kZXhPZihtYXRjaFsxXSlcblxuICAgICAgICBpbnNlcnQgKz0gbWF0Y2hbMF0uc2xpY2Uob2Zmc2V0ICsgbWF0Y2hbMV0ubGVuZ3RoKVxuICAgICAgICBzdGFydCArPSBvZmZzZXRcblxuICAgICAgICBjb25zdCBjdXRPZmYgPSBzdGFydCAtIGVuZFxuXG4gICAgICAgIGlmIChjdXRPZmYgPiAwKSB7XG4gICAgICAgICAgaW5zZXJ0ID0gbWF0Y2hbMF0uc2xpY2Uob2Zmc2V0IC0gY3V0T2ZmLCBvZmZzZXQpICsgaW5zZXJ0XG4gICAgICAgICAgc3RhcnQgPSBlbmRcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzdGF0ZS50ci5pbnNlcnRUZXh0KGluc2VydCwgc3RhcnQsIGVuZClcbiAgICB9LFxuICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgVHJhbnNhY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWNrZXJSZXN1bHQge1xuICBwb3NpdGlvbjogbnVtYmVyXG4gIGRlbGV0ZWQ6IGJvb2xlYW5cbn1cblxuZXhwb3J0IGNsYXNzIFRyYWNrZXIge1xuICB0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb25cblxuICBjdXJyZW50U3RlcDogbnVtYmVyXG5cbiAgY29uc3RydWN0b3IodHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uKSB7XG4gICAgdGhpcy50cmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uXG4gICAgdGhpcy5jdXJyZW50U3RlcCA9IHRoaXMudHJhbnNhY3Rpb24uc3RlcHMubGVuZ3RoXG4gIH1cblxuICBtYXAocG9zaXRpb246IG51bWJlcik6IFRyYWNrZXJSZXN1bHQge1xuICAgIGxldCBkZWxldGVkID0gZmFsc2VcblxuICAgIGNvbnN0IG1hcHBlZFBvc2l0aW9uID0gdGhpcy50cmFuc2FjdGlvbi5zdGVwc1xuICAgICAgLnNsaWNlKHRoaXMuY3VycmVudFN0ZXApXG4gICAgICAucmVkdWNlKChuZXdQb3NpdGlvbiwgc3RlcCkgPT4ge1xuICAgICAgICBjb25zdCBtYXBSZXN1bHQgPSBzdGVwLmdldE1hcCgpLm1hcFJlc3VsdChuZXdQb3NpdGlvbilcblxuICAgICAgICBpZiAobWFwUmVzdWx0LmRlbGV0ZWQpIHtcbiAgICAgICAgICBkZWxldGVkID0gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1hcFJlc3VsdC5wb3NcbiAgICAgIH0sIHBvc2l0aW9uKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHBvc2l0aW9uOiBtYXBwZWRQb3NpdGlvbixcbiAgICAgIGRlbGV0ZWQsXG4gICAgfVxuICB9XG59XG4iLCAiZXhwb3J0IHR5cGUgQXR0cmlidXRlcyA9IFJlY29yZDxzdHJpbmcsIGFueT5cblxuZXhwb3J0IHR5cGUgRE9NT3V0cHV0U3BlY0VsZW1lbnQgPSAwIHwgQXR0cmlidXRlcyB8IERPTU91dHB1dFNwZWNBcnJheVxuLyoqXG4gKiBCZXR0ZXIgZGVzY3JpYmVzIHRoZSBvdXRwdXQgb2YgYSBgcmVuZGVySFRNTGAgZnVuY3Rpb24gaW4gcHJvc2VtaXJyb3JcbiAqIEBzZWUgaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLkRPTU91dHB1dFNwZWNcbiAqL1xuZXhwb3J0IHR5cGUgRE9NT3V0cHV0U3BlY0FycmF5ID1cbiAgfCBbc3RyaW5nXVxuICB8IFtzdHJpbmcsIEF0dHJpYnV0ZXNdXG4gIHwgW3N0cmluZywgMF1cbiAgfCBbc3RyaW5nLCBBdHRyaWJ1dGVzLCAwXVxuICB8IFtzdHJpbmcsIEF0dHJpYnV0ZXMsIERPTU91dHB1dFNwZWNBcnJheSB8IDBdXG4gIHwgW3N0cmluZywgRE9NT3V0cHV0U3BlY0FycmF5XVxuXG4vLyBKU1ggdHlwZXMgZm9yIFRpcHRhcCdzIEpTWCBydW50aW1lXG4vLyBUaGVzZSB0eXBlcyBvbmx5IGFwcGx5IHdoZW4gdXNpbmcgQGpzeEltcG9ydFNvdXJjZSBAdGlwdGFwL2NvcmVcbi8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZW5vLW5hbWVzcGFjZVxuZXhwb3J0IG5hbWVzcGFjZSBKU1gge1xuICBleHBvcnQgdHlwZSBFbGVtZW50ID0gRE9NT3V0cHV0U3BlY0FycmF5XG4gIGV4cG9ydCBpbnRlcmZhY2UgSW50cmluc2ljRWxlbWVudHMge1xuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZW5vLWV4cGxpY2l0LWFueVxuICAgIFtrZXk6IHN0cmluZ106IGFueVxuICB9XG4gIGV4cG9ydCBpbnRlcmZhY2UgRWxlbWVudENoaWxkcmVuQXR0cmlidXRlIHtcbiAgICBjaGlsZHJlbjogdW5rbm93blxuICB9XG59XG5cbmV4cG9ydCB0eXBlIEpTWFJlbmRlcmVyID0gKFxuICB0YWc6ICdzbG90JyB8IHN0cmluZyB8ICgocHJvcHM/OiBBdHRyaWJ1dGVzKSA9PiBET01PdXRwdXRTcGVjQXJyYXkgfCBET01PdXRwdXRTcGVjRWxlbWVudCksXG4gIHByb3BzPzogQXR0cmlidXRlcyxcbiAgLi4uY2hpbGRyZW46IEpTWFJlbmRlcmVyW11cbikgPT4gRE9NT3V0cHV0U3BlY0FycmF5IHwgRE9NT3V0cHV0U3BlY0VsZW1lbnRcblxuZXhwb3J0IGZ1bmN0aW9uIEZyYWdtZW50KHByb3BzOiB7IGNoaWxkcmVuOiBKU1hSZW5kZXJlcltdIH0pIHtcbiAgcmV0dXJuIHByb3BzLmNoaWxkcmVuXG59XG5cbmV4cG9ydCBjb25zdCBoOiBKU1hSZW5kZXJlciA9ICh0YWcsIGF0dHJpYnV0ZXMpID0+IHtcbiAgLy8gVHJlYXQgdGhlIHNsb3QgdGFnIGFzIHRoZSBQcm9zZW1pcnJvciBob2xlIHRvIHJlbmRlciBjb250ZW50IGludG9cbiAgaWYgKHRhZyA9PT0gJ3Nsb3QnKSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuXG4gIC8vIElmIHRoZSB0YWcgaXMgYSBmdW5jdGlvbiwgY2FsbCBpdCB3aXRoIHRoZSBwcm9wc1xuICBpZiAodGFnIGluc3RhbmNlb2YgRnVuY3Rpb24pIHtcbiAgICByZXR1cm4gdGFnKGF0dHJpYnV0ZXMpXG4gIH1cblxuICBjb25zdCB7IGNoaWxkcmVuLCAuLi5yZXN0IH0gPSBhdHRyaWJ1dGVzID8/IHt9XG5cbiAgaWYgKHRhZyA9PT0gJ3N2ZycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnU1ZHIGVsZW1lbnRzIGFyZSBub3Qgc3VwcG9ydGVkIGluIHRoZSBKU1ggc3ludGF4LCB1c2UgdGhlIGFycmF5IHN5bnRheCBpbnN0ZWFkJyxcbiAgICApXG4gIH1cblxuICAvLyBPdGhlcndpc2UsIHJldHVybiB0aGUgdGFnLCBhdHRyaWJ1dGVzLCBhbmQgY2hpbGRyZW5cbiAgcmV0dXJuIFt0YWcsIHJlc3QsIGNoaWxkcmVuXVxufVxuXG4vLyBTZWVcbi8vIGh0dHBzOi8vZXNidWlsZC5naXRodWIuaW8vYXBpLyNqc3gtaW1wb3J0LXNvdXJjZVxuLy8gaHR0cHM6Ly93d3cudHlwZXNjcmlwdGxhbmcub3JnL3RzY29uZmlnLyNqc3hJbXBvcnRTb3VyY2VcblxuZXhwb3J0IHsgaCBhcyBjcmVhdGVFbGVtZW50LCBoIGFzIGpzeCwgaCBhcyBqc3hERVYsIGggYXMganN4cyB9XG4iLCAiLyoqIEBqc3hJbXBvcnRTb3VyY2UgQHRpcHRhcC9jb3JlICovXG5pbXBvcnQgeyBtZXJnZUF0dHJpYnV0ZXMsIE5vZGUsIHdyYXBwaW5nSW5wdXRSdWxlIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5pbXBvcnQgeyBoYW5kbGVCYWNrc3BhY2UgfSBmcm9tICcuL2hhbmRsZUJhY2tzcGFjZS5qcydcblxuZXhwb3J0IGludGVyZmFjZSBCbG9ja3F1b3RlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBIVE1MIGF0dHJpYnV0ZXMgdG8gYWRkIHRvIHRoZSBibG9ja3F1b3RlIGVsZW1lbnRcbiAgICogQGRlZmF1bHQge31cbiAgICogQGV4YW1wbGUgeyBjbGFzczogJ2ZvbycgfVxuICAgKi9cbiAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT5cbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGJsb2NrUXVvdGU6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2V0IGEgYmxvY2txdW90ZSBub2RlXG4gICAgICAgKi9cbiAgICAgIHNldEJsb2NrcXVvdGU6ICgpID0+IFJldHVyblR5cGVcbiAgICAgIC8qKlxuICAgICAgICogVG9nZ2xlIGEgYmxvY2txdW90ZSBub2RlXG4gICAgICAgKi9cbiAgICAgIHRvZ2dsZUJsb2NrcXVvdGU6ICgpID0+IFJldHVyblR5cGVcbiAgICAgIC8qKlxuICAgICAgICogVW5zZXQgYSBibG9ja3F1b3RlIG5vZGVcbiAgICAgICAqL1xuICAgICAgdW5zZXRCbG9ja3F1b3RlOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogTWF0Y2hlcyBhIGJsb2NrcXVvdGUgdG8gYSBgPmAgYXMgaW5wdXQuXG4gKi9cbmV4cG9ydCBjb25zdCBpbnB1dFJlZ2V4ID0gL15cXHMqPlxccyQvXG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBjcmVhdGUgYmxvY2txdW90ZXMuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9hcGkvbm9kZXMvYmxvY2txdW90ZVxuICovXG5leHBvcnQgY29uc3QgQmxvY2txdW90ZSA9IE5vZGUuY3JlYXRlPEJsb2NrcXVvdGVPcHRpb25zPih7XG4gIG5hbWU6ICdibG9ja3F1b3RlJyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBIVE1MQXR0cmlidXRlczoge30sXG4gICAgfVxuICB9LFxuXG4gIGNvbnRlbnQ6ICdibG9jaysnLFxuXG4gIGdyb3VwOiAnYmxvY2snLFxuXG4gIGRlZmluaW5nOiB0cnVlLFxuXG4gIHBhcnNlSFRNTCgpIHtcbiAgICByZXR1cm4gW3sgdGFnOiAnYmxvY2txdW90ZScgfV1cbiAgfSxcblxuICByZW5kZXJIVE1MKHsgSFRNTEF0dHJpYnV0ZXMgfSkge1xuICAgIHJldHVybiAoXG4gICAgICA8YmxvY2txdW90ZSB7Li4ubWVyZ2VBdHRyaWJ1dGVzKHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcywgSFRNTEF0dHJpYnV0ZXMpfT5cbiAgICAgICAgPHNsb3QgLz5cbiAgICAgIDwvYmxvY2txdW90ZT5cbiAgICApXG4gIH0sXG5cbiAgcGFyc2VNYXJrZG93bjogKHRva2VuLCBoZWxwZXJzKSA9PiB7XG4gICAgY29uc3QgcGFyc2VCbG9ja0NoaWxkcmVuID0gaGVscGVycy5wYXJzZUJsb2NrQ2hpbGRyZW4gPz8gaGVscGVycy5wYXJzZUNoaWxkcmVuXG5cbiAgICByZXR1cm4gaGVscGVycy5jcmVhdGVOb2RlKCdibG9ja3F1b3RlJywgdW5kZWZpbmVkLCBwYXJzZUJsb2NrQ2hpbGRyZW4odG9rZW4udG9rZW5zIHx8IFtdKSlcbiAgfSxcblxuICByZW5kZXJNYXJrZG93bjogKG5vZGUsIGgpID0+IHtcbiAgICBpZiAoIW5vZGUuY29udGVudCkge1xuICAgICAgcmV0dXJuICcnXG4gICAgfVxuXG4gICAgLy8gVXNlIGEgc2luZ2xlICc+JyBwcmVmaXggcmVnYXJkbGVzcyBvZiBuZXN0aW5nIGxldmVsXG4gICAgLy8gTmVzdGVkIGJsb2NrcXVvdGVzIHdpbGwgYWRkIHRoZWlyIG93biAnPicgcHJlZml4IHJlY3Vyc2l2ZWx5XG4gICAgY29uc3QgcHJlZml4ID0gJz4nXG4gICAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXSA9IFtdXG5cbiAgICBub2RlLmNvbnRlbnQuZm9yRWFjaCgoY2hpbGQsIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBjaGlsZENvbnRlbnQgPSBoLnJlbmRlckNoaWxkPy4oY2hpbGQsIGluZGV4KSA/PyBoLnJlbmRlckNoaWxkcmVuKFtjaGlsZF0pXG4gICAgICBjb25zdCBsaW5lcyA9IGNoaWxkQ29udGVudC5zcGxpdCgnXFxuJylcblxuICAgICAgY29uc3QgbGluZXNXaXRoUHJlZml4ID0gbGluZXMubWFwKGxpbmUgPT4ge1xuICAgICAgICAvLyBEb24ndCBhZGQgcHJlZml4IHRvIGVtcHR5IGxpbmVzXG4gICAgICAgIGlmIChsaW5lLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgICAgICByZXR1cm4gcHJlZml4XG4gICAgICAgIH1cblxuICAgICAgICAvLyBOZXN0ZWQgYmxvY2txdW90ZXMgd2lsbCBhbHJlYWR5IGhhdmUgdGhlaXIgb3duIHByZWZpeGVzXG4gICAgICAgIC8vIFdlIGp1c3QgbmVlZCB0byBhZGQgb3VyIG93biBwcmVmaXggYXQgdGhlIHN0YXJ0XG4gICAgICAgIHJldHVybiBgJHtwcmVmaXh9ICR7bGluZX1gXG4gICAgICB9KVxuXG4gICAgICByZXN1bHQucHVzaChsaW5lc1dpdGhQcmVmaXguam9pbignXFxuJykpXG4gICAgfSlcblxuICAgIC8vIEFkZCBzZXBhcmF0b3IgbGluZXMgYmV0d2VlbiBjaGlsZHJlblxuICAgIHJldHVybiByZXN1bHQuam9pbihgXFxuJHtwcmVmaXh9XFxuYClcbiAgfSxcblxuICBhZGRDb21tYW5kcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2V0QmxvY2txdW90ZTpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy53cmFwSW4odGhpcy5uYW1lKVxuICAgICAgICB9LFxuICAgICAgdG9nZ2xlQmxvY2txdW90ZTpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy50b2dnbGVXcmFwKHRoaXMubmFtZSlcbiAgICAgICAgfSxcbiAgICAgIHVuc2V0QmxvY2txdW90ZTpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy5saWZ0KHRoaXMubmFtZSlcbiAgICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkS2V5Ym9hcmRTaG9ydGN1dHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdNb2QtU2hpZnQtYic6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZUJsb2NrcXVvdGUoKSxcbiAgICAgIEJhY2tzcGFjZTogKCkgPT4gaGFuZGxlQmFja3NwYWNlKHRoaXMuZWRpdG9yLCB0aGlzLnR5cGUpLFxuICAgIH1cbiAgfSxcblxuICBhZGRJbnB1dFJ1bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICB3cmFwcGluZ0lucHV0UnVsZSh7XG4gICAgICAgIGZpbmQ6IGlucHV0UmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IE9yZGVyZWRNYXAgZnJvbSAnb3JkZXJlZG1hcCc7XG5cbmZ1bmN0aW9uIGZpbmREaWZmU3RhcnQoYSwgYiwgcG9zKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7OyBpKyspIHtcbiAgICAgICAgaWYgKGkgPT0gYS5jaGlsZENvdW50IHx8IGkgPT0gYi5jaGlsZENvdW50KVxuICAgICAgICAgICAgcmV0dXJuIGEuY2hpbGRDb3VudCA9PSBiLmNoaWxkQ291bnQgPyBudWxsIDogcG9zO1xuICAgICAgICBsZXQgY2hpbGRBID0gYS5jaGlsZChpKSwgY2hpbGRCID0gYi5jaGlsZChpKTtcbiAgICAgICAgaWYgKGNoaWxkQSA9PSBjaGlsZEIpIHtcbiAgICAgICAgICAgIHBvcyArPSBjaGlsZEEubm9kZVNpemU7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNoaWxkQS5zYW1lTWFya3VwKGNoaWxkQikpXG4gICAgICAgICAgICByZXR1cm4gcG9zO1xuICAgICAgICBpZiAoY2hpbGRBLmlzVGV4dCAmJiBjaGlsZEEudGV4dCAhPSBjaGlsZEIudGV4dCkge1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGNoaWxkQS50ZXh0W2pdID09IGNoaWxkQi50ZXh0W2pdOyBqKyspXG4gICAgICAgICAgICAgICAgcG9zKys7XG4gICAgICAgICAgICByZXR1cm4gcG9zO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGlsZEEuY29udGVudC5zaXplIHx8IGNoaWxkQi5jb250ZW50LnNpemUpIHtcbiAgICAgICAgICAgIGxldCBpbm5lciA9IGZpbmREaWZmU3RhcnQoY2hpbGRBLmNvbnRlbnQsIGNoaWxkQi5jb250ZW50LCBwb3MgKyAxKTtcbiAgICAgICAgICAgIGlmIChpbm5lciAhPSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybiBpbm5lcjtcbiAgICAgICAgfVxuICAgICAgICBwb3MgKz0gY2hpbGRBLm5vZGVTaXplO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGZpbmREaWZmRW5kKGEsIGIsIHBvc0EsIHBvc0IpIHtcbiAgICBmb3IgKGxldCBpQSA9IGEuY2hpbGRDb3VudCwgaUIgPSBiLmNoaWxkQ291bnQ7Oykge1xuICAgICAgICBpZiAoaUEgPT0gMCB8fCBpQiA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIGlBID09IGlCID8gbnVsbCA6IHsgYTogcG9zQSwgYjogcG9zQiB9O1xuICAgICAgICBsZXQgY2hpbGRBID0gYS5jaGlsZCgtLWlBKSwgY2hpbGRCID0gYi5jaGlsZCgtLWlCKSwgc2l6ZSA9IGNoaWxkQS5ub2RlU2l6ZTtcbiAgICAgICAgaWYgKGNoaWxkQSA9PSBjaGlsZEIpIHtcbiAgICAgICAgICAgIHBvc0EgLT0gc2l6ZTtcbiAgICAgICAgICAgIHBvc0IgLT0gc2l6ZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY2hpbGRBLnNhbWVNYXJrdXAoY2hpbGRCKSlcbiAgICAgICAgICAgIHJldHVybiB7IGE6IHBvc0EsIGI6IHBvc0IgfTtcbiAgICAgICAgaWYgKGNoaWxkQS5pc1RleHQgJiYgY2hpbGRBLnRleHQgIT0gY2hpbGRCLnRleHQpIHtcbiAgICAgICAgICAgIGxldCBzYW1lID0gMCwgbWluU2l6ZSA9IE1hdGgubWluKGNoaWxkQS50ZXh0Lmxlbmd0aCwgY2hpbGRCLnRleHQubGVuZ3RoKTtcbiAgICAgICAgICAgIHdoaWxlIChzYW1lIDwgbWluU2l6ZSAmJiBjaGlsZEEudGV4dFtjaGlsZEEudGV4dC5sZW5ndGggLSBzYW1lIC0gMV0gPT0gY2hpbGRCLnRleHRbY2hpbGRCLnRleHQubGVuZ3RoIC0gc2FtZSAtIDFdKSB7XG4gICAgICAgICAgICAgICAgc2FtZSsrO1xuICAgICAgICAgICAgICAgIHBvc0EtLTtcbiAgICAgICAgICAgICAgICBwb3NCLS07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4geyBhOiBwb3NBLCBiOiBwb3NCIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoaWxkQS5jb250ZW50LnNpemUgfHwgY2hpbGRCLmNvbnRlbnQuc2l6ZSkge1xuICAgICAgICAgICAgbGV0IGlubmVyID0gZmluZERpZmZFbmQoY2hpbGRBLmNvbnRlbnQsIGNoaWxkQi5jb250ZW50LCBwb3NBIC0gMSwgcG9zQiAtIDEpO1xuICAgICAgICAgICAgaWYgKGlubmVyKVxuICAgICAgICAgICAgICAgIHJldHVybiBpbm5lcjtcbiAgICAgICAgfVxuICAgICAgICBwb3NBIC09IHNpemU7XG4gICAgICAgIHBvc0IgLT0gc2l6ZTtcbiAgICB9XG59XG5cbi8qKlxuQSBmcmFnbWVudCByZXByZXNlbnRzIGEgbm9kZSdzIGNvbGxlY3Rpb24gb2YgY2hpbGQgbm9kZXMuXG5cbkxpa2Ugbm9kZXMsIGZyYWdtZW50cyBhcmUgcGVyc2lzdGVudCBkYXRhIHN0cnVjdHVyZXMsIGFuZCB5b3VcbnNob3VsZCBub3QgbXV0YXRlIHRoZW0gb3IgdGhlaXIgY29udGVudC4gUmF0aGVyLCB5b3UgY3JlYXRlIG5ld1xuaW5zdGFuY2VzIHdoZW5ldmVyIG5lZWRlZC4gVGhlIEFQSSB0cmllcyB0byBtYWtlIHRoaXMgZWFzeS5cbiovXG5jbGFzcyBGcmFnbWVudCB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgY2hpbGQgbm9kZXMgaW4gdGhpcyBmcmFnbWVudC5cbiAgICAqL1xuICAgIGNvbnRlbnQsIHNpemUpIHtcbiAgICAgICAgdGhpcy5jb250ZW50ID0gY29udGVudDtcbiAgICAgICAgdGhpcy5zaXplID0gc2l6ZSB8fCAwO1xuICAgICAgICBpZiAoc2l6ZSA9PSBudWxsKVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb250ZW50Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIHRoaXMuc2l6ZSArPSBjb250ZW50W2ldLm5vZGVTaXplO1xuICAgIH1cbiAgICAvKipcbiAgICBJbnZva2UgYSBjYWxsYmFjayBmb3IgYWxsIGRlc2NlbmRhbnQgbm9kZXMgYmV0d2VlbiB0aGUgZ2l2ZW4gdHdvXG4gICAgcG9zaXRpb25zIChyZWxhdGl2ZSB0byBzdGFydCBvZiB0aGlzIGZyYWdtZW50KS4gRG9lc24ndCBkZXNjZW5kXG4gICAgaW50byBhIG5vZGUgd2hlbiB0aGUgY2FsbGJhY2sgcmV0dXJucyBgZmFsc2VgLlxuICAgICovXG4gICAgbm9kZXNCZXR3ZWVuKGZyb20sIHRvLCBmLCBub2RlU3RhcnQgPSAwLCBwYXJlbnQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIHBvcyA9IDA7IHBvcyA8IHRvOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMuY29udGVudFtpXSwgZW5kID0gcG9zICsgY2hpbGQubm9kZVNpemU7XG4gICAgICAgICAgICBpZiAoZW5kID4gZnJvbSAmJiBmKGNoaWxkLCBub2RlU3RhcnQgKyBwb3MsIHBhcmVudCB8fCBudWxsLCBpKSAhPT0gZmFsc2UgJiYgY2hpbGQuY29udGVudC5zaXplKSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0YXJ0ID0gcG9zICsgMTtcbiAgICAgICAgICAgICAgICBjaGlsZC5ub2Rlc0JldHdlZW4oTWF0aC5tYXgoMCwgZnJvbSAtIHN0YXJ0KSwgTWF0aC5taW4oY2hpbGQuY29udGVudC5zaXplLCB0byAtIHN0YXJ0KSwgZiwgbm9kZVN0YXJ0ICsgc3RhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcG9zID0gZW5kO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIENhbGwgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBldmVyeSBkZXNjZW5kYW50IG5vZGUuIGBwb3NgIHdpbGwgYmVcbiAgICByZWxhdGl2ZSB0byB0aGUgc3RhcnQgb2YgdGhlIGZyYWdtZW50LiBUaGUgY2FsbGJhY2sgbWF5IHJldHVyblxuICAgIGBmYWxzZWAgdG8gcHJldmVudCB0cmF2ZXJzYWwgb2YgYSBnaXZlbiBub2RlJ3MgY2hpbGRyZW4uXG4gICAgKi9cbiAgICBkZXNjZW5kYW50cyhmKSB7XG4gICAgICAgIHRoaXMubm9kZXNCZXR3ZWVuKDAsIHRoaXMuc2l6ZSwgZik7XG4gICAgfVxuICAgIC8qKlxuICAgIEV4dHJhY3QgdGhlIHRleHQgYmV0d2VlbiBgZnJvbWAgYW5kIGB0b2AuIFNlZSB0aGUgc2FtZSBtZXRob2Qgb25cbiAgICBbYE5vZGVgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZS50ZXh0QmV0d2VlbikuXG4gICAgKi9cbiAgICB0ZXh0QmV0d2Vlbihmcm9tLCB0bywgYmxvY2tTZXBhcmF0b3IsIGxlYWZUZXh0KSB7XG4gICAgICAgIGxldCB0ZXh0ID0gXCJcIiwgZmlyc3QgPSB0cnVlO1xuICAgICAgICB0aGlzLm5vZGVzQmV0d2Vlbihmcm9tLCB0bywgKG5vZGUsIHBvcykgPT4ge1xuICAgICAgICAgICAgbGV0IG5vZGVUZXh0ID0gbm9kZS5pc1RleHQgPyBub2RlLnRleHQuc2xpY2UoTWF0aC5tYXgoZnJvbSwgcG9zKSAtIHBvcywgdG8gLSBwb3MpXG4gICAgICAgICAgICAgICAgOiAhbm9kZS5pc0xlYWYgPyBcIlwiXG4gICAgICAgICAgICAgICAgICAgIDogbGVhZlRleHQgPyAodHlwZW9mIGxlYWZUZXh0ID09PSBcImZ1bmN0aW9uXCIgPyBsZWFmVGV4dChub2RlKSA6IGxlYWZUZXh0KVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBub2RlLnR5cGUuc3BlYy5sZWFmVGV4dCA/IG5vZGUudHlwZS5zcGVjLmxlYWZUZXh0KG5vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBcIlwiO1xuICAgICAgICAgICAgaWYgKG5vZGUuaXNCbG9jayAmJiAobm9kZS5pc0xlYWYgJiYgbm9kZVRleHQgfHwgbm9kZS5pc1RleHRibG9jaykgJiYgYmxvY2tTZXBhcmF0b3IpIHtcbiAgICAgICAgICAgICAgICBpZiAoZmlyc3QpXG4gICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICB0ZXh0ICs9IGJsb2NrU2VwYXJhdG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGV4dCArPSBub2RlVGV4dDtcbiAgICAgICAgfSwgMCk7XG4gICAgICAgIHJldHVybiB0ZXh0O1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBuZXcgZnJhZ21lbnQgY29udGFpbmluZyB0aGUgY29tYmluZWQgY29udGVudCBvZiB0aGlzXG4gICAgZnJhZ21lbnQgYW5kIHRoZSBvdGhlci5cbiAgICAqL1xuICAgIGFwcGVuZChvdGhlcikge1xuICAgICAgICBpZiAoIW90aGVyLnNpemUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgaWYgKCF0aGlzLnNpemUpXG4gICAgICAgICAgICByZXR1cm4gb3RoZXI7XG4gICAgICAgIGxldCBsYXN0ID0gdGhpcy5sYXN0Q2hpbGQsIGZpcnN0ID0gb3RoZXIuZmlyc3RDaGlsZCwgY29udGVudCA9IHRoaXMuY29udGVudC5zbGljZSgpLCBpID0gMDtcbiAgICAgICAgaWYgKGxhc3QuaXNUZXh0ICYmIGxhc3Quc2FtZU1hcmt1cChmaXJzdCkpIHtcbiAgICAgICAgICAgIGNvbnRlbnRbY29udGVudC5sZW5ndGggLSAxXSA9IGxhc3Qud2l0aFRleHQobGFzdC50ZXh0ICsgZmlyc3QudGV4dCk7XG4gICAgICAgICAgICBpID0gMTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKDsgaSA8IG90aGVyLmNvbnRlbnQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBjb250ZW50LnB1c2gob3RoZXIuY29udGVudFtpXSk7XG4gICAgICAgIHJldHVybiBuZXcgRnJhZ21lbnQoY29udGVudCwgdGhpcy5zaXplICsgb3RoZXIuc2l6ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEN1dCBvdXQgdGhlIHN1Yi1mcmFnbWVudCBiZXR3ZWVuIHRoZSB0d28gZ2l2ZW4gcG9zaXRpb25zLlxuICAgICovXG4gICAgY3V0KGZyb20sIHRvID0gdGhpcy5zaXplKSB7XG4gICAgICAgIGlmIChmcm9tID09IDAgJiYgdG8gPT0gdGhpcy5zaXplKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIGxldCByZXN1bHQgPSBbXSwgc2l6ZSA9IDA7XG4gICAgICAgIGlmICh0byA+IGZyb20pXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgcG9zID0gMDsgcG9zIDwgdG87IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMuY29udGVudFtpXSwgZW5kID0gcG9zICsgY2hpbGQubm9kZVNpemU7XG4gICAgICAgICAgICAgICAgaWYgKGVuZCA+IGZyb20pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvcyA8IGZyb20gfHwgZW5kID4gdG8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5pc1RleHQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5jdXQoTWF0aC5tYXgoMCwgZnJvbSAtIHBvcyksIE1hdGgubWluKGNoaWxkLnRleHQubGVuZ3RoLCB0byAtIHBvcykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuY3V0KE1hdGgubWF4KDAsIGZyb20gLSBwb3MgLSAxKSwgTWF0aC5taW4oY2hpbGQuY29udGVudC5zaXplLCB0byAtIHBvcyAtIDEpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChjaGlsZCk7XG4gICAgICAgICAgICAgICAgICAgIHNpemUgKz0gY2hpbGQubm9kZVNpemU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHBvcyA9IGVuZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBGcmFnbWVudChyZXN1bHQsIHNpemUpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGN1dEJ5SW5kZXgoZnJvbSwgdG8pIHtcbiAgICAgICAgaWYgKGZyb20gPT0gdG8pXG4gICAgICAgICAgICByZXR1cm4gRnJhZ21lbnQuZW1wdHk7XG4gICAgICAgIGlmIChmcm9tID09IDAgJiYgdG8gPT0gdGhpcy5jb250ZW50Lmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IEZyYWdtZW50KHRoaXMuY29udGVudC5zbGljZShmcm9tLCB0bykpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBuZXcgZnJhZ21lbnQgaW4gd2hpY2ggdGhlIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4IGlzXG4gICAgcmVwbGFjZWQgYnkgdGhlIGdpdmVuIG5vZGUuXG4gICAgKi9cbiAgICByZXBsYWNlQ2hpbGQoaW5kZXgsIG5vZGUpIHtcbiAgICAgICAgbGV0IGN1cnJlbnQgPSB0aGlzLmNvbnRlbnRbaW5kZXhdO1xuICAgICAgICBpZiAoY3VycmVudCA9PSBub2RlKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIGxldCBjb3B5ID0gdGhpcy5jb250ZW50LnNsaWNlKCk7XG4gICAgICAgIGxldCBzaXplID0gdGhpcy5zaXplICsgbm9kZS5ub2RlU2l6ZSAtIGN1cnJlbnQubm9kZVNpemU7XG4gICAgICAgIGNvcHlbaW5kZXhdID0gbm9kZTtcbiAgICAgICAgcmV0dXJuIG5ldyBGcmFnbWVudChjb3B5LCBzaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbmV3IGZyYWdtZW50IGJ5IHByZXBlbmRpbmcgdGhlIGdpdmVuIG5vZGUgdG8gdGhpc1xuICAgIGZyYWdtZW50LlxuICAgICovXG4gICAgYWRkVG9TdGFydChub2RlKSB7XG4gICAgICAgIHJldHVybiBuZXcgRnJhZ21lbnQoW25vZGVdLmNvbmNhdCh0aGlzLmNvbnRlbnQpLCB0aGlzLnNpemUgKyBub2RlLm5vZGVTaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbmV3IGZyYWdtZW50IGJ5IGFwcGVuZGluZyB0aGUgZ2l2ZW4gbm9kZSB0byB0aGlzXG4gICAgZnJhZ21lbnQuXG4gICAgKi9cbiAgICBhZGRUb0VuZChub2RlKSB7XG4gICAgICAgIHJldHVybiBuZXcgRnJhZ21lbnQodGhpcy5jb250ZW50LmNvbmNhdChub2RlKSwgdGhpcy5zaXplICsgbm9kZS5ub2RlU2l6ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENvbXBhcmUgdGhpcyBmcmFnbWVudCB0byBhbm90aGVyIG9uZS5cbiAgICAqL1xuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRlbnQubGVuZ3RoICE9IG90aGVyLmNvbnRlbnQubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY29udGVudC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmICghdGhpcy5jb250ZW50W2ldLmVxKG90aGVyLmNvbnRlbnRbaV0pKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgZnJhZ21lbnQsIG9yIGBudWxsYCBpZiBpdCBpcyBlbXB0eS5cbiAgICAqL1xuICAgIGdldCBmaXJzdENoaWxkKCkgeyByZXR1cm4gdGhpcy5jb250ZW50Lmxlbmd0aCA/IHRoaXMuY29udGVudFswXSA6IG51bGw7IH1cbiAgICAvKipcbiAgICBUaGUgbGFzdCBjaGlsZCBvZiB0aGUgZnJhZ21lbnQsIG9yIGBudWxsYCBpZiBpdCBpcyBlbXB0eS5cbiAgICAqL1xuICAgIGdldCBsYXN0Q2hpbGQoKSB7IHJldHVybiB0aGlzLmNvbnRlbnQubGVuZ3RoID8gdGhpcy5jb250ZW50W3RoaXMuY29udGVudC5sZW5ndGggLSAxXSA6IG51bGw7IH1cbiAgICAvKipcbiAgICBUaGUgbnVtYmVyIG9mIGNoaWxkIG5vZGVzIGluIHRoaXMgZnJhZ21lbnQuXG4gICAgKi9cbiAgICBnZXQgY2hpbGRDb3VudCgpIHsgcmV0dXJuIHRoaXMuY29udGVudC5sZW5ndGg7IH1cbiAgICAvKipcbiAgICBHZXQgdGhlIGNoaWxkIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4LiBSYWlzZSBhbiBlcnJvciB3aGVuIHRoZVxuICAgIGluZGV4IGlzIG91dCBvZiByYW5nZS5cbiAgICAqL1xuICAgIGNoaWxkKGluZGV4KSB7XG4gICAgICAgIGxldCBmb3VuZCA9IHRoaXMuY29udGVudFtpbmRleF07XG4gICAgICAgIGlmICghZm91bmQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkluZGV4IFwiICsgaW5kZXggKyBcIiBvdXQgb2YgcmFuZ2UgZm9yIFwiICsgdGhpcyk7XG4gICAgICAgIHJldHVybiBmb3VuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBjaGlsZCBub2RlIGF0IHRoZSBnaXZlbiBpbmRleCwgaWYgaXQgZXhpc3RzLlxuICAgICovXG4gICAgbWF5YmVDaGlsZChpbmRleCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZW50W2luZGV4XSB8fCBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBDYWxsIGBmYCBmb3IgZXZlcnkgY2hpbGQgbm9kZSwgcGFzc2luZyB0aGUgbm9kZSwgaXRzIG9mZnNldFxuICAgIGludG8gdGhpcyBwYXJlbnQgbm9kZSwgYW5kIGl0cyBpbmRleC5cbiAgICAqL1xuICAgIGZvckVhY2goZikge1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgcCA9IDA7IGkgPCB0aGlzLmNvbnRlbnQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMuY29udGVudFtpXTtcbiAgICAgICAgICAgIGYoY2hpbGQsIHAsIGkpO1xuICAgICAgICAgICAgcCArPSBjaGlsZC5ub2RlU2l6ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSBmaXJzdCBwb3NpdGlvbiBhdCB3aGljaCB0aGlzIGZyYWdtZW50IGFuZCBhbm90aGVyXG4gICAgZnJhZ21lbnQgZGlmZmVyLCBvciBgbnVsbGAgaWYgdGhleSBhcmUgdGhlIHNhbWUuXG4gICAgKi9cbiAgICBmaW5kRGlmZlN0YXJ0KG90aGVyLCBwb3MgPSAwKSB7XG4gICAgICAgIHJldHVybiBmaW5kRGlmZlN0YXJ0KHRoaXMsIG90aGVyLCBwb3MpO1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSBmaXJzdCBwb3NpdGlvbiwgc2VhcmNoaW5nIGZyb20gdGhlIGVuZCwgYXQgd2hpY2ggdGhpc1xuICAgIGZyYWdtZW50IGFuZCB0aGUgZ2l2ZW4gZnJhZ21lbnQgZGlmZmVyLCBvciBgbnVsbGAgaWYgdGhleSBhcmVcbiAgICB0aGUgc2FtZS4gU2luY2UgdGhpcyBwb3NpdGlvbiB3aWxsIG5vdCBiZSB0aGUgc2FtZSBpbiBib3RoXG4gICAgbm9kZXMsIGFuIG9iamVjdCB3aXRoIHR3byBzZXBhcmF0ZSBwb3NpdGlvbnMgaXMgcmV0dXJuZWQuXG4gICAgKi9cbiAgICBmaW5kRGlmZkVuZChvdGhlciwgcG9zID0gdGhpcy5zaXplLCBvdGhlclBvcyA9IG90aGVyLnNpemUpIHtcbiAgICAgICAgcmV0dXJuIGZpbmREaWZmRW5kKHRoaXMsIG90aGVyLCBwb3MsIG90aGVyUG9zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCB0aGUgaW5kZXggYW5kIGlubmVyIG9mZnNldCBjb3JyZXNwb25kaW5nIHRvIGEgZ2l2ZW4gcmVsYXRpdmVcbiAgICBwb3NpdGlvbiBpbiB0aGlzIGZyYWdtZW50LiBUaGUgcmVzdWx0IG9iamVjdCB3aWxsIGJlIHJldXNlZFxuICAgIChvdmVyd3JpdHRlbikgdGhlIG5leHQgdGltZSB0aGUgZnVuY3Rpb24gaXMgY2FsbGVkLiBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGZpbmRJbmRleChwb3MpIHtcbiAgICAgICAgaWYgKHBvcyA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIHJldEluZGV4KDAsIHBvcyk7XG4gICAgICAgIGlmIChwb3MgPT0gdGhpcy5zaXplKVxuICAgICAgICAgICAgcmV0dXJuIHJldEluZGV4KHRoaXMuY29udGVudC5sZW5ndGgsIHBvcyk7XG4gICAgICAgIGlmIChwb3MgPiB0aGlzLnNpemUgfHwgcG9zIDwgMClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBQb3NpdGlvbiAke3Bvc30gb3V0c2lkZSBvZiBmcmFnbWVudCAoJHt0aGlzfSlgKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGN1clBvcyA9IDA7OyBpKyspIHtcbiAgICAgICAgICAgIGxldCBjdXIgPSB0aGlzLmNoaWxkKGkpLCBlbmQgPSBjdXJQb3MgKyBjdXIubm9kZVNpemU7XG4gICAgICAgICAgICBpZiAoZW5kID49IHBvcykge1xuICAgICAgICAgICAgICAgIGlmIChlbmQgPT0gcG9zKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmV0SW5kZXgoaSArIDEsIGVuZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJldEluZGV4KGksIGN1clBvcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJQb3MgPSBlbmQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJuIGEgZGVidWdnaW5nIHN0cmluZyB0aGF0IGRlc2NyaWJlcyB0aGlzIGZyYWdtZW50LlxuICAgICovXG4gICAgdG9TdHJpbmcoKSB7IHJldHVybiBcIjxcIiArIHRoaXMudG9TdHJpbmdJbm5lcigpICsgXCI+XCI7IH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHRvU3RyaW5nSW5uZXIoKSB7IHJldHVybiB0aGlzLmNvbnRlbnQuam9pbihcIiwgXCIpOyB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgSlNPTi1zZXJpYWxpemVhYmxlIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgZnJhZ21lbnQuXG4gICAgKi9cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRlbnQubGVuZ3RoID8gdGhpcy5jb250ZW50Lm1hcChuID0+IG4udG9KU09OKCkpIDogbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgRGVzZXJpYWxpemUgYSBmcmFnbWVudCBmcm9tIGl0cyBKU09OIHJlcHJlc2VudGF0aW9uLlxuICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKHNjaGVtYSwgdmFsdWUpIHtcbiAgICAgICAgaWYgKCF2YWx1ZSlcbiAgICAgICAgICAgIHJldHVybiBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgRnJhZ21lbnQuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBGcmFnbWVudC5mcm9tQXJyYXkodmFsdWUubWFwKHNjaGVtYS5ub2RlRnJvbUpTT04pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQnVpbGQgYSBmcmFnbWVudCBmcm9tIGFuIGFycmF5IG9mIG5vZGVzLiBFbnN1cmVzIHRoYXQgYWRqYWNlbnRcbiAgICB0ZXh0IG5vZGVzIHdpdGggdGhlIHNhbWUgbWFya3MgYXJlIGpvaW5lZCB0b2dldGhlci5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tQXJyYXkoYXJyYXkpIHtcbiAgICAgICAgaWYgKCFhcnJheS5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gRnJhZ21lbnQuZW1wdHk7XG4gICAgICAgIGxldCBqb2luZWQsIHNpemUgPSAwO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbm9kZSA9IGFycmF5W2ldO1xuICAgICAgICAgICAgc2l6ZSArPSBub2RlLm5vZGVTaXplO1xuICAgICAgICAgICAgaWYgKGkgJiYgbm9kZS5pc1RleHQgJiYgYXJyYXlbaSAtIDFdLnNhbWVNYXJrdXAobm9kZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWpvaW5lZClcbiAgICAgICAgICAgICAgICAgICAgam9pbmVkID0gYXJyYXkuc2xpY2UoMCwgaSk7XG4gICAgICAgICAgICAgICAgam9pbmVkW2pvaW5lZC5sZW5ndGggLSAxXSA9IG5vZGVcbiAgICAgICAgICAgICAgICAgICAgLndpdGhUZXh0KGpvaW5lZFtqb2luZWQubGVuZ3RoIC0gMV0udGV4dCArIG5vZGUudGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChqb2luZWQpIHtcbiAgICAgICAgICAgICAgICBqb2luZWQucHVzaChub2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IEZyYWdtZW50KGpvaW5lZCB8fCBhcnJheSwgc2l6ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIGZyYWdtZW50IGZyb20gc29tZXRoaW5nIHRoYXQgY2FuIGJlIGludGVycHJldGVkIGFzIGFcbiAgICBzZXQgb2Ygbm9kZXMuIEZvciBgbnVsbGAsIGl0IHJldHVybnMgdGhlIGVtcHR5IGZyYWdtZW50LiBGb3IgYVxuICAgIGZyYWdtZW50LCB0aGUgZnJhZ21lbnQgaXRzZWxmLiBGb3IgYSBub2RlIG9yIGFycmF5IG9mIG5vZGVzLCBhXG4gICAgZnJhZ21lbnQgY29udGFpbmluZyB0aG9zZSBub2Rlcy5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tKG5vZGVzKSB7XG4gICAgICAgIGlmICghbm9kZXMpXG4gICAgICAgICAgICByZXR1cm4gRnJhZ21lbnQuZW1wdHk7XG4gICAgICAgIGlmIChub2RlcyBpbnN0YW5jZW9mIEZyYWdtZW50KVxuICAgICAgICAgICAgcmV0dXJuIG5vZGVzO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShub2RlcykpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mcm9tQXJyYXkobm9kZXMpO1xuICAgICAgICBpZiAobm9kZXMuYXR0cnMpXG4gICAgICAgICAgICByZXR1cm4gbmV3IEZyYWdtZW50KFtub2Rlc10sIG5vZGVzLm5vZGVTaXplKTtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJDYW4gbm90IGNvbnZlcnQgXCIgKyBub2RlcyArIFwiIHRvIGEgRnJhZ21lbnRcIiArXG4gICAgICAgICAgICAobm9kZXMubm9kZXNCZXR3ZWVuID8gXCIgKGxvb2tzIGxpa2UgbXVsdGlwbGUgdmVyc2lvbnMgb2YgcHJvc2VtaXJyb3ItbW9kZWwgd2VyZSBsb2FkZWQpXCIgOiBcIlwiKSk7XG4gICAgfVxufVxuLyoqXG5BbiBlbXB0eSBmcmFnbWVudC4gSW50ZW5kZWQgdG8gYmUgcmV1c2VkIHdoZW5ldmVyIGEgbm9kZSBkb2Vzbid0XG5jb250YWluIGFueXRoaW5nIChyYXRoZXIgdGhhbiBhbGxvY2F0aW5nIGEgbmV3IGVtcHR5IGZyYWdtZW50IGZvclxuZWFjaCBsZWFmIG5vZGUpLlxuKi9cbkZyYWdtZW50LmVtcHR5ID0gbmV3IEZyYWdtZW50KFtdLCAwKTtcbmNvbnN0IGZvdW5kID0geyBpbmRleDogMCwgb2Zmc2V0OiAwIH07XG5mdW5jdGlvbiByZXRJbmRleChpbmRleCwgb2Zmc2V0KSB7XG4gICAgZm91bmQuaW5kZXggPSBpbmRleDtcbiAgICBmb3VuZC5vZmZzZXQgPSBvZmZzZXQ7XG4gICAgcmV0dXJuIGZvdW5kO1xufVxuXG5mdW5jdGlvbiBjb21wYXJlRGVlcChhLCBiKSB7XG4gICAgaWYgKGEgPT09IGIpXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIGlmICghKGEgJiYgdHlwZW9mIGEgPT0gXCJvYmplY3RcIikgfHxcbiAgICAgICAgIShiICYmIHR5cGVvZiBiID09IFwib2JqZWN0XCIpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IGFycmF5ID0gQXJyYXkuaXNBcnJheShhKTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShiKSAhPSBhcnJheSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChhcnJheSkge1xuICAgICAgICBpZiAoYS5sZW5ndGggIT0gYi5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmICghY29tcGFyZURlZXAoYVtpXSwgYltpXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZm9yIChsZXQgcCBpbiBhKVxuICAgICAgICAgICAgaWYgKCEocCBpbiBiKSB8fCAhY29tcGFyZURlZXAoYVtwXSwgYltwXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBwIGluIGIpXG4gICAgICAgICAgICBpZiAoIShwIGluIGEpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuQSBtYXJrIGlzIGEgcGllY2Ugb2YgaW5mb3JtYXRpb24gdGhhdCBjYW4gYmUgYXR0YWNoZWQgdG8gYSBub2RlLFxuc3VjaCBhcyBpdCBiZWluZyBlbXBoYXNpemVkLCBpbiBjb2RlIGZvbnQsIG9yIGEgbGluay4gSXQgaGFzIGFcbnR5cGUgYW5kIG9wdGlvbmFsbHkgYSBzZXQgb2YgYXR0cmlidXRlcyB0aGF0IHByb3ZpZGUgZnVydGhlclxuaW5mb3JtYXRpb24gKHN1Y2ggYXMgdGhlIHRhcmdldCBvZiB0aGUgbGluaykuIE1hcmtzIGFyZSBjcmVhdGVkXG50aHJvdWdoIGEgYFNjaGVtYWAsIHdoaWNoIGNvbnRyb2xzIHdoaWNoIHR5cGVzIGV4aXN0IGFuZCB3aGljaFxuYXR0cmlidXRlcyB0aGV5IGhhdmUuXG4qL1xuY2xhc3MgTWFyayB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgdHlwZSBvZiB0aGlzIG1hcmsuXG4gICAgKi9cbiAgICB0eXBlLCBcbiAgICAvKipcbiAgICBUaGUgYXR0cmlidXRlcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBtYXJrLlxuICAgICovXG4gICAgYXR0cnMpIHtcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICAgICAgdGhpcy5hdHRycyA9IGF0dHJzO1xuICAgIH1cbiAgICAvKipcbiAgICBHaXZlbiBhIHNldCBvZiBtYXJrcywgY3JlYXRlIGEgbmV3IHNldCB3aGljaCBjb250YWlucyB0aGlzIG9uZSBhc1xuICAgIHdlbGwsIGluIHRoZSByaWdodCBwb3NpdGlvbi4gSWYgdGhpcyBtYXJrIGlzIGFscmVhZHkgaW4gdGhlIHNldCxcbiAgICB0aGUgc2V0IGl0c2VsZiBpcyByZXR1cm5lZC4gSWYgYW55IG1hcmtzIHRoYXQgYXJlIHNldCB0byBiZVxuICAgIFtleGNsdXNpdmVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5NYXJrU3BlYy5leGNsdWRlcykgd2l0aCB0aGlzIG1hcmsgYXJlIHByZXNlbnQsXG4gICAgdGhvc2UgYXJlIHJlcGxhY2VkIGJ5IHRoaXMgb25lLlxuICAgICovXG4gICAgYWRkVG9TZXQoc2V0KSB7XG4gICAgICAgIGxldCBjb3B5LCBwbGFjZWQgPSBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBvdGhlciA9IHNldFtpXTtcbiAgICAgICAgICAgIGlmICh0aGlzLmVxKG90aGVyKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gc2V0O1xuICAgICAgICAgICAgaWYgKHRoaXMudHlwZS5leGNsdWRlcyhvdGhlci50eXBlKSkge1xuICAgICAgICAgICAgICAgIGlmICghY29weSlcbiAgICAgICAgICAgICAgICAgICAgY29weSA9IHNldC5zbGljZSgwLCBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKG90aGVyLnR5cGUuZXhjbHVkZXModGhpcy50eXBlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBzZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoIXBsYWNlZCAmJiBvdGhlci50eXBlLnJhbmsgPiB0aGlzLnR5cGUucmFuaykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWNvcHkpXG4gICAgICAgICAgICAgICAgICAgICAgICBjb3B5ID0gc2V0LnNsaWNlKDAsIGkpO1xuICAgICAgICAgICAgICAgICAgICBjb3B5LnB1c2godGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIHBsYWNlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChjb3B5KVxuICAgICAgICAgICAgICAgICAgICBjb3B5LnB1c2gob3RoZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghY29weSlcbiAgICAgICAgICAgIGNvcHkgPSBzZXQuc2xpY2UoKTtcbiAgICAgICAgaWYgKCFwbGFjZWQpXG4gICAgICAgICAgICBjb3B5LnB1c2godGhpcyk7XG4gICAgICAgIHJldHVybiBjb3B5O1xuICAgIH1cbiAgICAvKipcbiAgICBSZW1vdmUgdGhpcyBtYXJrIGZyb20gdGhlIGdpdmVuIHNldCwgcmV0dXJuaW5nIGEgbmV3IHNldC4gSWYgdGhpc1xuICAgIG1hcmsgaXMgbm90IGluIHRoZSBzZXQsIHRoZSBzZXQgaXRzZWxmIGlzIHJldHVybmVkLlxuICAgICovXG4gICAgcmVtb3ZlRnJvbVNldChzZXQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAodGhpcy5lcShzZXRbaV0pKVxuICAgICAgICAgICAgICAgIHJldHVybiBzZXQuc2xpY2UoMCwgaSkuY29uY2F0KHNldC5zbGljZShpICsgMSkpO1xuICAgICAgICByZXR1cm4gc2V0O1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgdGhpcyBtYXJrIGlzIGluIHRoZSBnaXZlbiBzZXQgb2YgbWFya3MuXG4gICAgKi9cbiAgICBpc0luU2V0KHNldCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmICh0aGlzLmVxKHNldFtpXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGVzdCB3aGV0aGVyIHRoaXMgbWFyayBoYXMgdGhlIHNhbWUgdHlwZSBhbmQgYXR0cmlidXRlcyBhc1xuICAgIGFub3RoZXIgbWFyay5cbiAgICAqL1xuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzID09IG90aGVyIHx8XG4gICAgICAgICAgICAodGhpcy50eXBlID09IG90aGVyLnR5cGUgJiYgY29tcGFyZURlZXAodGhpcy5hdHRycywgb3RoZXIuYXR0cnMpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ29udmVydCB0aGlzIG1hcmsgdG8gYSBKU09OLXNlcmlhbGl6ZWFibGUgcmVwcmVzZW50YXRpb24uXG4gICAgKi9cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGxldCBvYmogPSB7IHR5cGU6IHRoaXMudHlwZS5uYW1lIH07XG4gICAgICAgIGZvciAobGV0IF8gaW4gdGhpcy5hdHRycykge1xuICAgICAgICAgICAgb2JqLmF0dHJzID0gdGhpcy5hdHRycztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICAgIC8qKlxuICAgIERlc2VyaWFsaXplIGEgbWFyayBmcm9tIEpTT04uXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICghanNvbilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgTWFyay5mcm9tSlNPTlwiKTtcbiAgICAgICAgbGV0IHR5cGUgPSBzY2hlbWEubWFya3NbanNvbi50eXBlXTtcbiAgICAgICAgaWYgKCF0eXBlKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYFRoZXJlIGlzIG5vIG1hcmsgdHlwZSAke2pzb24udHlwZX0gaW4gdGhpcyBzY2hlbWFgKTtcbiAgICAgICAgbGV0IG1hcmsgPSB0eXBlLmNyZWF0ZShqc29uLmF0dHJzKTtcbiAgICAgICAgdHlwZS5jaGVja0F0dHJzKG1hcmsuYXR0cnMpO1xuICAgICAgICByZXR1cm4gbWFyaztcbiAgICB9XG4gICAgLyoqXG4gICAgVGVzdCB3aGV0aGVyIHR3byBzZXRzIG9mIG1hcmtzIGFyZSBpZGVudGljYWwuXG4gICAgKi9cbiAgICBzdGF0aWMgc2FtZVNldChhLCBiKSB7XG4gICAgICAgIGlmIChhID09IGIpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgaWYgKGEubGVuZ3RoICE9IGIubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGEubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAoIWFbaV0uZXEoYltpXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgcHJvcGVybHkgc29ydGVkIG1hcmsgc2V0IGZyb20gbnVsbCwgYSBzaW5nbGUgbWFyaywgb3IgYW5cbiAgICB1bnNvcnRlZCBhcnJheSBvZiBtYXJrcy5cbiAgICAqL1xuICAgIHN0YXRpYyBzZXRGcm9tKG1hcmtzKSB7XG4gICAgICAgIGlmICghbWFya3MgfHwgQXJyYXkuaXNBcnJheShtYXJrcykgJiYgbWFya3MubGVuZ3RoID09IDApXG4gICAgICAgICAgICByZXR1cm4gTWFyay5ub25lO1xuICAgICAgICBpZiAobWFya3MgaW5zdGFuY2VvZiBNYXJrKVxuICAgICAgICAgICAgcmV0dXJuIFttYXJrc107XG4gICAgICAgIGxldCBjb3B5ID0gbWFya3Muc2xpY2UoKTtcbiAgICAgICAgY29weS5zb3J0KChhLCBiKSA9PiBhLnR5cGUucmFuayAtIGIudHlwZS5yYW5rKTtcbiAgICAgICAgcmV0dXJuIGNvcHk7XG4gICAgfVxufVxuLyoqXG5UaGUgZW1wdHkgc2V0IG9mIG1hcmtzLlxuKi9cbk1hcmsubm9uZSA9IFtdO1xuXG4vKipcbkVycm9yIHR5cGUgcmFpc2VkIGJ5IFtgTm9kZS5yZXBsYWNlYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGUucmVwbGFjZSkgd2hlblxuZ2l2ZW4gYW4gaW52YWxpZCByZXBsYWNlbWVudC5cbiovXG5jbGFzcyBSZXBsYWNlRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG59XG4vKipcbkEgc2xpY2UgcmVwcmVzZW50cyBhIHBpZWNlIGN1dCBvdXQgb2YgYSBsYXJnZXIgZG9jdW1lbnQuIEl0XG5zdG9yZXMgbm90IG9ubHkgYSBmcmFnbWVudCwgYnV0IGFsc28gdGhlIGRlcHRoIHVwIHRvIHdoaWNoIG5vZGVzIG9uXG5ib3RoIHNpZGUgYXJlIOKAmG9wZW7igJkgKGN1dCB0aHJvdWdoKS5cbiovXG5jbGFzcyBTbGljZSB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgc2xpY2UuIFdoZW4gc3BlY2lmeWluZyBhIG5vbi16ZXJvIG9wZW4gZGVwdGgsIHlvdSBtdXN0XG4gICAgbWFrZSBzdXJlIHRoYXQgdGhlcmUgYXJlIG5vZGVzIG9mIGF0IGxlYXN0IHRoYXQgZGVwdGggYXQgdGhlXG4gICAgYXBwcm9wcmlhdGUgc2lkZSBvZiB0aGUgZnJhZ21lbnTigJRpLmUuIGlmIHRoZSBmcmFnbWVudCBpcyBhblxuICAgIGVtcHR5IHBhcmFncmFwaCBub2RlLCBgb3BlblN0YXJ0YCBhbmQgYG9wZW5FbmRgIGNhbid0IGJlIGdyZWF0ZXJcbiAgICB0aGFuIDEuXG4gICAgXG4gICAgSXQgaXMgbm90IG5lY2Vzc2FyeSBmb3IgdGhlIGNvbnRlbnQgb2Ygb3BlbiBub2RlcyB0byBjb25mb3JtIHRvXG4gICAgdGhlIHNjaGVtYSdzIGNvbnRlbnQgY29uc3RyYWludHMsIHRob3VnaCBpdCBzaG91bGQgYmUgYSB2YWxpZFxuICAgIHN0YXJ0L2VuZC9taWRkbGUgZm9yIHN1Y2ggYSBub2RlLCBkZXBlbmRpbmcgb24gd2hpY2ggc2lkZXMgYXJlXG4gICAgb3Blbi5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBzbGljZSdzIGNvbnRlbnQuXG4gICAgKi9cbiAgICBjb250ZW50LCBcbiAgICAvKipcbiAgICBUaGUgb3BlbiBkZXB0aCBhdCB0aGUgc3RhcnQgb2YgdGhlIGZyYWdtZW50LlxuICAgICovXG4gICAgb3BlblN0YXJ0LCBcbiAgICAvKipcbiAgICBUaGUgb3BlbiBkZXB0aCBhdCB0aGUgZW5kLlxuICAgICovXG4gICAgb3BlbkVuZCkge1xuICAgICAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xuICAgICAgICB0aGlzLm9wZW5TdGFydCA9IG9wZW5TdGFydDtcbiAgICAgICAgdGhpcy5vcGVuRW5kID0gb3BlbkVuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHNpemUgdGhpcyBzbGljZSB3b3VsZCBhZGQgd2hlbiBpbnNlcnRlZCBpbnRvIGEgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudC5zaXplIC0gdGhpcy5vcGVuU3RhcnQgLSB0aGlzLm9wZW5FbmQ7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgaW5zZXJ0QXQocG9zLCBmcmFnbWVudCkge1xuICAgICAgICBsZXQgY29udGVudCA9IGluc2VydEludG8odGhpcy5jb250ZW50LCBwb3MgKyB0aGlzLm9wZW5TdGFydCwgZnJhZ21lbnQsIHRoaXMub3BlblN0YXJ0ICsgMSwgdGhpcy5vcGVuRW5kICsgMSk7XG4gICAgICAgIHJldHVybiBjb250ZW50ICYmIG5ldyBTbGljZShjb250ZW50LCB0aGlzLm9wZW5TdGFydCwgdGhpcy5vcGVuRW5kKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICByZW1vdmVCZXR3ZWVuKGZyb20sIHRvKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2xpY2UocmVtb3ZlUmFuZ2UodGhpcy5jb250ZW50LCBmcm9tICsgdGhpcy5vcGVuU3RhcnQsIHRvICsgdGhpcy5vcGVuU3RhcnQpLCB0aGlzLm9wZW5TdGFydCwgdGhpcy5vcGVuRW5kKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGVzdHMgd2hldGhlciB0aGlzIHNsaWNlIGlzIGVxdWFsIHRvIGFub3RoZXIgc2xpY2UuXG4gICAgKi9cbiAgICBlcShvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZW50LmVxKG90aGVyLmNvbnRlbnQpICYmIHRoaXMub3BlblN0YXJ0ID09IG90aGVyLm9wZW5TdGFydCAmJiB0aGlzLm9wZW5FbmQgPT0gb3RoZXIub3BlbkVuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudCArIFwiKFwiICsgdGhpcy5vcGVuU3RhcnQgKyBcIixcIiArIHRoaXMub3BlbkVuZCArIFwiKVwiO1xuICAgIH1cbiAgICAvKipcbiAgICBDb252ZXJ0IGEgc2xpY2UgdG8gYSBKU09OLXNlcmlhbGl6YWJsZSByZXByZXNlbnRhdGlvbi5cbiAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgaWYgKCF0aGlzLmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBsZXQganNvbiA9IHsgY29udGVudDogdGhpcy5jb250ZW50LnRvSlNPTigpIH07XG4gICAgICAgIGlmICh0aGlzLm9wZW5TdGFydCA+IDApXG4gICAgICAgICAgICBqc29uLm9wZW5TdGFydCA9IHRoaXMub3BlblN0YXJ0O1xuICAgICAgICBpZiAodGhpcy5vcGVuRW5kID4gMClcbiAgICAgICAgICAgIGpzb24ub3BlbkVuZCA9IHRoaXMub3BlbkVuZDtcbiAgICAgICAgcmV0dXJuIGpzb247XG4gICAgfVxuICAgIC8qKlxuICAgIERlc2VyaWFsaXplIGEgc2xpY2UgZnJvbSBpdHMgSlNPTiByZXByZXNlbnRhdGlvbi5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uKVxuICAgICAgICAgICAgcmV0dXJuIFNsaWNlLmVtcHR5O1xuICAgICAgICBsZXQgb3BlblN0YXJ0ID0ganNvbi5vcGVuU3RhcnQgfHwgMCwgb3BlbkVuZCA9IGpzb24ub3BlbkVuZCB8fCAwO1xuICAgICAgICBpZiAodHlwZW9mIG9wZW5TdGFydCAhPSBcIm51bWJlclwiIHx8IHR5cGVvZiBvcGVuRW5kICE9IFwibnVtYmVyXCIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIFNsaWNlLmZyb21KU09OXCIpO1xuICAgICAgICByZXR1cm4gbmV3IFNsaWNlKEZyYWdtZW50LmZyb21KU09OKHNjaGVtYSwganNvbi5jb250ZW50KSwgb3BlblN0YXJ0LCBvcGVuRW5kKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgc2xpY2UgZnJvbSBhIGZyYWdtZW50IGJ5IHRha2luZyB0aGUgbWF4aW11bSBwb3NzaWJsZVxuICAgIG9wZW4gdmFsdWUgb24gYm90aCBzaWRlIG9mIHRoZSBmcmFnbWVudC5cbiAgICAqL1xuICAgIHN0YXRpYyBtYXhPcGVuKGZyYWdtZW50LCBvcGVuSXNvbGF0aW5nID0gdHJ1ZSkge1xuICAgICAgICBsZXQgb3BlblN0YXJ0ID0gMCwgb3BlbkVuZCA9IDA7XG4gICAgICAgIGZvciAobGV0IG4gPSBmcmFnbWVudC5maXJzdENoaWxkOyBuICYmICFuLmlzTGVhZiAmJiAob3Blbklzb2xhdGluZyB8fCAhbi50eXBlLnNwZWMuaXNvbGF0aW5nKTsgbiA9IG4uZmlyc3RDaGlsZClcbiAgICAgICAgICAgIG9wZW5TdGFydCsrO1xuICAgICAgICBmb3IgKGxldCBuID0gZnJhZ21lbnQubGFzdENoaWxkOyBuICYmICFuLmlzTGVhZiAmJiAob3Blbklzb2xhdGluZyB8fCAhbi50eXBlLnNwZWMuaXNvbGF0aW5nKTsgbiA9IG4ubGFzdENoaWxkKVxuICAgICAgICAgICAgb3BlbkVuZCsrO1xuICAgICAgICByZXR1cm4gbmV3IFNsaWNlKGZyYWdtZW50LCBvcGVuU3RhcnQsIG9wZW5FbmQpO1xuICAgIH1cbn1cbi8qKlxuVGhlIGVtcHR5IHNsaWNlLlxuKi9cblNsaWNlLmVtcHR5ID0gbmV3IFNsaWNlKEZyYWdtZW50LmVtcHR5LCAwLCAwKTtcbmZ1bmN0aW9uIHJlbW92ZVJhbmdlKGNvbnRlbnQsIGZyb20sIHRvKSB7XG4gICAgbGV0IHsgaW5kZXgsIG9mZnNldCB9ID0gY29udGVudC5maW5kSW5kZXgoZnJvbSksIGNoaWxkID0gY29udGVudC5tYXliZUNoaWxkKGluZGV4KTtcbiAgICBsZXQgeyBpbmRleDogaW5kZXhUbywgb2Zmc2V0OiBvZmZzZXRUbyB9ID0gY29udGVudC5maW5kSW5kZXgodG8pO1xuICAgIGlmIChvZmZzZXQgPT0gZnJvbSB8fCBjaGlsZC5pc1RleHQpIHtcbiAgICAgICAgaWYgKG9mZnNldFRvICE9IHRvICYmICFjb250ZW50LmNoaWxkKGluZGV4VG8pLmlzVGV4dClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiUmVtb3Zpbmcgbm9uLWZsYXQgcmFuZ2VcIik7XG4gICAgICAgIHJldHVybiBjb250ZW50LmN1dCgwLCBmcm9tKS5hcHBlbmQoY29udGVudC5jdXQodG8pKTtcbiAgICB9XG4gICAgaWYgKGluZGV4ICE9IGluZGV4VG8pXG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiUmVtb3Zpbmcgbm9uLWZsYXQgcmFuZ2VcIik7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZUNoaWxkKGluZGV4LCBjaGlsZC5jb3B5KHJlbW92ZVJhbmdlKGNoaWxkLmNvbnRlbnQsIGZyb20gLSBvZmZzZXQgLSAxLCB0byAtIG9mZnNldCAtIDEpKSk7XG59XG5mdW5jdGlvbiBpbnNlcnRJbnRvKGNvbnRlbnQsIGRpc3QsIGluc2VydCwgb3BlblN0YXJ0LCBvcGVuRW5kLCBwYXJlbnQpIHtcbiAgICBsZXQgeyBpbmRleCwgb2Zmc2V0IH0gPSBjb250ZW50LmZpbmRJbmRleChkaXN0KSwgY2hpbGQgPSBjb250ZW50Lm1heWJlQ2hpbGQoaW5kZXgpO1xuICAgIGlmIChvZmZzZXQgPT0gZGlzdCB8fCBjaGlsZC5pc1RleHQpIHtcbiAgICAgICAgaWYgKHBhcmVudCAmJiBvcGVuU3RhcnQgPD0gMCAmJiBvcGVuRW5kIDw9IDAgJiYgIXBhcmVudC5jYW5SZXBsYWNlKGluZGV4LCBpbmRleCwgaW5zZXJ0KSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gY29udGVudC5jdXQoMCwgZGlzdCkuYXBwZW5kKGluc2VydCkuYXBwZW5kKGNvbnRlbnQuY3V0KGRpc3QpKTtcbiAgICB9XG4gICAgbGV0IGlubmVyID0gaW5zZXJ0SW50byhjaGlsZC5jb250ZW50LCBkaXN0IC0gb2Zmc2V0IC0gMSwgaW5zZXJ0LCBpbmRleCA9PSAwID8gb3BlblN0YXJ0IC0gMSA6IDAsIGluZGV4ID09IGNvbnRlbnQuY2hpbGRDb3VudCAtIDEgPyBvcGVuRW5kIC0gMSA6IDAsIGNoaWxkKTtcbiAgICByZXR1cm4gaW5uZXIgJiYgY29udGVudC5yZXBsYWNlQ2hpbGQoaW5kZXgsIGNoaWxkLmNvcHkoaW5uZXIpKTtcbn1cbmZ1bmN0aW9uIHJlcGxhY2UoJGZyb20sICR0bywgc2xpY2UpIHtcbiAgICBpZiAoc2xpY2Uub3BlblN0YXJ0ID4gJGZyb20uZGVwdGgpXG4gICAgICAgIHRocm93IG5ldyBSZXBsYWNlRXJyb3IoXCJJbnNlcnRlZCBjb250ZW50IGRlZXBlciB0aGFuIGluc2VydGlvbiBwb3NpdGlvblwiKTtcbiAgICBpZiAoJGZyb20uZGVwdGggLSBzbGljZS5vcGVuU3RhcnQgIT0gJHRvLmRlcHRoIC0gc2xpY2Uub3BlbkVuZClcbiAgICAgICAgdGhyb3cgbmV3IFJlcGxhY2VFcnJvcihcIkluY29uc2lzdGVudCBvcGVuIGRlcHRoc1wiKTtcbiAgICByZXR1cm4gcmVwbGFjZU91dGVyKCRmcm9tLCAkdG8sIHNsaWNlLCAwKTtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VPdXRlcigkZnJvbSwgJHRvLCBzbGljZSwgZGVwdGgpIHtcbiAgICBsZXQgaW5kZXggPSAkZnJvbS5pbmRleChkZXB0aCksIG5vZGUgPSAkZnJvbS5ub2RlKGRlcHRoKTtcbiAgICBpZiAoaW5kZXggPT0gJHRvLmluZGV4KGRlcHRoKSAmJiBkZXB0aCA8ICRmcm9tLmRlcHRoIC0gc2xpY2Uub3BlblN0YXJ0KSB7XG4gICAgICAgIGxldCBpbm5lciA9IHJlcGxhY2VPdXRlcigkZnJvbSwgJHRvLCBzbGljZSwgZGVwdGggKyAxKTtcbiAgICAgICAgcmV0dXJuIG5vZGUuY29weShub2RlLmNvbnRlbnQucmVwbGFjZUNoaWxkKGluZGV4LCBpbm5lcikpO1xuICAgIH1cbiAgICBlbHNlIGlmICghc2xpY2UuY29udGVudC5zaXplKSB7XG4gICAgICAgIHJldHVybiBjbG9zZShub2RlLCByZXBsYWNlVHdvV2F5KCRmcm9tLCAkdG8sIGRlcHRoKSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKCFzbGljZS5vcGVuU3RhcnQgJiYgIXNsaWNlLm9wZW5FbmQgJiYgJGZyb20uZGVwdGggPT0gZGVwdGggJiYgJHRvLmRlcHRoID09IGRlcHRoKSB7IC8vIFNpbXBsZSwgZmxhdCBjYXNlXG4gICAgICAgIGxldCBwYXJlbnQgPSAkZnJvbS5wYXJlbnQsIGNvbnRlbnQgPSBwYXJlbnQuY29udGVudDtcbiAgICAgICAgcmV0dXJuIGNsb3NlKHBhcmVudCwgY29udGVudC5jdXQoMCwgJGZyb20ucGFyZW50T2Zmc2V0KS5hcHBlbmQoc2xpY2UuY29udGVudCkuYXBwZW5kKGNvbnRlbnQuY3V0KCR0by5wYXJlbnRPZmZzZXQpKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBsZXQgeyBzdGFydCwgZW5kIH0gPSBwcmVwYXJlU2xpY2VGb3JSZXBsYWNlKHNsaWNlLCAkZnJvbSk7XG4gICAgICAgIHJldHVybiBjbG9zZShub2RlLCByZXBsYWNlVGhyZWVXYXkoJGZyb20sIHN0YXJ0LCBlbmQsICR0bywgZGVwdGgpKTtcbiAgICB9XG59XG5mdW5jdGlvbiBjaGVja0pvaW4obWFpbiwgc3ViKSB7XG4gICAgaWYgKCFzdWIudHlwZS5jb21wYXRpYmxlQ29udGVudChtYWluLnR5cGUpKVxuICAgICAgICB0aHJvdyBuZXcgUmVwbGFjZUVycm9yKFwiQ2Fubm90IGpvaW4gXCIgKyBzdWIudHlwZS5uYW1lICsgXCIgb250byBcIiArIG1haW4udHlwZS5uYW1lKTtcbn1cbmZ1bmN0aW9uIGpvaW5hYmxlKCRiZWZvcmUsICRhZnRlciwgZGVwdGgpIHtcbiAgICBsZXQgbm9kZSA9ICRiZWZvcmUubm9kZShkZXB0aCk7XG4gICAgY2hlY2tKb2luKG5vZGUsICRhZnRlci5ub2RlKGRlcHRoKSk7XG4gICAgcmV0dXJuIG5vZGU7XG59XG5mdW5jdGlvbiBhZGROb2RlKGNoaWxkLCB0YXJnZXQpIHtcbiAgICBsZXQgbGFzdCA9IHRhcmdldC5sZW5ndGggLSAxO1xuICAgIGlmIChsYXN0ID49IDAgJiYgY2hpbGQuaXNUZXh0ICYmIGNoaWxkLnNhbWVNYXJrdXAodGFyZ2V0W2xhc3RdKSlcbiAgICAgICAgdGFyZ2V0W2xhc3RdID0gY2hpbGQud2l0aFRleHQodGFyZ2V0W2xhc3RdLnRleHQgKyBjaGlsZC50ZXh0KTtcbiAgICBlbHNlXG4gICAgICAgIHRhcmdldC5wdXNoKGNoaWxkKTtcbn1cbmZ1bmN0aW9uIGFkZFJhbmdlKCRzdGFydCwgJGVuZCwgZGVwdGgsIHRhcmdldCkge1xuICAgIGxldCBub2RlID0gKCRlbmQgfHwgJHN0YXJ0KS5ub2RlKGRlcHRoKTtcbiAgICBsZXQgc3RhcnRJbmRleCA9IDAsIGVuZEluZGV4ID0gJGVuZCA/ICRlbmQuaW5kZXgoZGVwdGgpIDogbm9kZS5jaGlsZENvdW50O1xuICAgIGlmICgkc3RhcnQpIHtcbiAgICAgICAgc3RhcnRJbmRleCA9ICRzdGFydC5pbmRleChkZXB0aCk7XG4gICAgICAgIGlmICgkc3RhcnQuZGVwdGggPiBkZXB0aCkge1xuICAgICAgICAgICAgc3RhcnRJbmRleCsrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCRzdGFydC50ZXh0T2Zmc2V0KSB7XG4gICAgICAgICAgICBhZGROb2RlKCRzdGFydC5ub2RlQWZ0ZXIsIHRhcmdldCk7XG4gICAgICAgICAgICBzdGFydEluZGV4Kys7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0SW5kZXg7IGkgPCBlbmRJbmRleDsgaSsrKVxuICAgICAgICBhZGROb2RlKG5vZGUuY2hpbGQoaSksIHRhcmdldCk7XG4gICAgaWYgKCRlbmQgJiYgJGVuZC5kZXB0aCA9PSBkZXB0aCAmJiAkZW5kLnRleHRPZmZzZXQpXG4gICAgICAgIGFkZE5vZGUoJGVuZC5ub2RlQmVmb3JlLCB0YXJnZXQpO1xufVxuZnVuY3Rpb24gY2xvc2Uobm9kZSwgY29udGVudCkge1xuICAgIG5vZGUudHlwZS5jaGVja0NvbnRlbnQoY29udGVudCk7XG4gICAgcmV0dXJuIG5vZGUuY29weShjb250ZW50KTtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VUaHJlZVdheSgkZnJvbSwgJHN0YXJ0LCAkZW5kLCAkdG8sIGRlcHRoKSB7XG4gICAgbGV0IG9wZW5TdGFydCA9ICRmcm9tLmRlcHRoID4gZGVwdGggJiYgam9pbmFibGUoJGZyb20sICRzdGFydCwgZGVwdGggKyAxKTtcbiAgICBsZXQgb3BlbkVuZCA9ICR0by5kZXB0aCA+IGRlcHRoICYmIGpvaW5hYmxlKCRlbmQsICR0bywgZGVwdGggKyAxKTtcbiAgICBsZXQgY29udGVudCA9IFtdO1xuICAgIGFkZFJhbmdlKG51bGwsICRmcm9tLCBkZXB0aCwgY29udGVudCk7XG4gICAgaWYgKG9wZW5TdGFydCAmJiBvcGVuRW5kICYmICRzdGFydC5pbmRleChkZXB0aCkgPT0gJGVuZC5pbmRleChkZXB0aCkpIHtcbiAgICAgICAgY2hlY2tKb2luKG9wZW5TdGFydCwgb3BlbkVuZCk7XG4gICAgICAgIGFkZE5vZGUoY2xvc2Uob3BlblN0YXJ0LCByZXBsYWNlVGhyZWVXYXkoJGZyb20sICRzdGFydCwgJGVuZCwgJHRvLCBkZXB0aCArIDEpKSwgY29udGVudCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpZiAob3BlblN0YXJ0KVxuICAgICAgICAgICAgYWRkTm9kZShjbG9zZShvcGVuU3RhcnQsIHJlcGxhY2VUd29XYXkoJGZyb20sICRzdGFydCwgZGVwdGggKyAxKSksIGNvbnRlbnQpO1xuICAgICAgICBhZGRSYW5nZSgkc3RhcnQsICRlbmQsIGRlcHRoLCBjb250ZW50KTtcbiAgICAgICAgaWYgKG9wZW5FbmQpXG4gICAgICAgICAgICBhZGROb2RlKGNsb3NlKG9wZW5FbmQsIHJlcGxhY2VUd29XYXkoJGVuZCwgJHRvLCBkZXB0aCArIDEpKSwgY29udGVudCk7XG4gICAgfVxuICAgIGFkZFJhbmdlKCR0bywgbnVsbCwgZGVwdGgsIGNvbnRlbnQpO1xuICAgIHJldHVybiBuZXcgRnJhZ21lbnQoY29udGVudCk7XG59XG5mdW5jdGlvbiByZXBsYWNlVHdvV2F5KCRmcm9tLCAkdG8sIGRlcHRoKSB7XG4gICAgbGV0IGNvbnRlbnQgPSBbXTtcbiAgICBhZGRSYW5nZShudWxsLCAkZnJvbSwgZGVwdGgsIGNvbnRlbnQpO1xuICAgIGlmICgkZnJvbS5kZXB0aCA+IGRlcHRoKSB7XG4gICAgICAgIGxldCB0eXBlID0gam9pbmFibGUoJGZyb20sICR0bywgZGVwdGggKyAxKTtcbiAgICAgICAgYWRkTm9kZShjbG9zZSh0eXBlLCByZXBsYWNlVHdvV2F5KCRmcm9tLCAkdG8sIGRlcHRoICsgMSkpLCBjb250ZW50KTtcbiAgICB9XG4gICAgYWRkUmFuZ2UoJHRvLCBudWxsLCBkZXB0aCwgY29udGVudCk7XG4gICAgcmV0dXJuIG5ldyBGcmFnbWVudChjb250ZW50KTtcbn1cbmZ1bmN0aW9uIHByZXBhcmVTbGljZUZvclJlcGxhY2Uoc2xpY2UsICRhbG9uZykge1xuICAgIGxldCBleHRyYSA9ICRhbG9uZy5kZXB0aCAtIHNsaWNlLm9wZW5TdGFydCwgcGFyZW50ID0gJGFsb25nLm5vZGUoZXh0cmEpO1xuICAgIGxldCBub2RlID0gcGFyZW50LmNvcHkoc2xpY2UuY29udGVudCk7XG4gICAgZm9yIChsZXQgaSA9IGV4dHJhIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgIG5vZGUgPSAkYWxvbmcubm9kZShpKS5jb3B5KEZyYWdtZW50LmZyb20obm9kZSkpO1xuICAgIHJldHVybiB7IHN0YXJ0OiBub2RlLnJlc29sdmVOb0NhY2hlKHNsaWNlLm9wZW5TdGFydCArIGV4dHJhKSxcbiAgICAgICAgZW5kOiBub2RlLnJlc29sdmVOb0NhY2hlKG5vZGUuY29udGVudC5zaXplIC0gc2xpY2Uub3BlbkVuZCAtIGV4dHJhKSB9O1xufVxuXG4vKipcbllvdSBjYW4gW19yZXNvbHZlX10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGUucmVzb2x2ZSkgYSBwb3NpdGlvbiB0byBnZXQgbW9yZVxuaW5mb3JtYXRpb24gYWJvdXQgaXQuIE9iamVjdHMgb2YgdGhpcyBjbGFzcyByZXByZXNlbnQgc3VjaCBhXG5yZXNvbHZlZCBwb3NpdGlvbiwgcHJvdmlkaW5nIHZhcmlvdXMgcGllY2VzIG9mIGNvbnRleHRcbmluZm9ybWF0aW9uLCBhbmQgc29tZSBoZWxwZXIgbWV0aG9kcy5cblxuVGhyb3VnaG91dCB0aGlzIGludGVyZmFjZSwgbWV0aG9kcyB0aGF0IHRha2UgYW4gb3B0aW9uYWwgYGRlcHRoYFxucGFyYW1ldGVyIHdpbGwgaW50ZXJwcmV0IHVuZGVmaW5lZCBhcyBgdGhpcy5kZXB0aGAgYW5kIG5lZ2F0aXZlXG5udW1iZXJzIGFzIGB0aGlzLmRlcHRoICsgdmFsdWVgLlxuKi9cbmNsYXNzIFJlc29sdmVkUG9zIHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBwb3NpdGlvbiB0aGF0IHdhcyByZXNvbHZlZC5cbiAgICAqL1xuICAgIHBvcywgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBwYXRoLCBcbiAgICAvKipcbiAgICBUaGUgb2Zmc2V0IHRoaXMgcG9zaXRpb24gaGFzIGludG8gaXRzIHBhcmVudCBub2RlLlxuICAgICovXG4gICAgcGFyZW50T2Zmc2V0KSB7XG4gICAgICAgIHRoaXMucG9zID0gcG9zO1xuICAgICAgICB0aGlzLnBhdGggPSBwYXRoO1xuICAgICAgICB0aGlzLnBhcmVudE9mZnNldCA9IHBhcmVudE9mZnNldDtcbiAgICAgICAgdGhpcy5kZXB0aCA9IHBhdGgubGVuZ3RoIC8gMyAtIDE7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgcmVzb2x2ZURlcHRoKHZhbCkge1xuICAgICAgICBpZiAodmFsID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZXB0aDtcbiAgICAgICAgaWYgKHZhbCA8IDApXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZXB0aCArIHZhbDtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHBhcmVudCBub2RlIHRoYXQgdGhlIHBvc2l0aW9uIHBvaW50cyBpbnRvLiBOb3RlIHRoYXQgZXZlbiBpZlxuICAgIGEgcG9zaXRpb24gcG9pbnRzIGludG8gYSB0ZXh0IG5vZGUsIHRoYXQgbm9kZSBpcyBub3QgY29uc2lkZXJlZFxuICAgIHRoZSBwYXJlbnTigJR0ZXh0IG5vZGVzIGFyZSDigJhmbGF04oCZIGluIHRoaXMgbW9kZWwsIGFuZCBoYXZlIG5vIGNvbnRlbnQuXG4gICAgKi9cbiAgICBnZXQgcGFyZW50KCkgeyByZXR1cm4gdGhpcy5ub2RlKHRoaXMuZGVwdGgpOyB9XG4gICAgLyoqXG4gICAgVGhlIHJvb3Qgbm9kZSBpbiB3aGljaCB0aGUgcG9zaXRpb24gd2FzIHJlc29sdmVkLlxuICAgICovXG4gICAgZ2V0IGRvYygpIHsgcmV0dXJuIHRoaXMubm9kZSgwKTsgfVxuICAgIC8qKlxuICAgIFRoZSBhbmNlc3RvciBub2RlIGF0IHRoZSBnaXZlbiBsZXZlbC4gYHAubm9kZShwLmRlcHRoKWAgaXMgdGhlXG4gICAgc2FtZSBhcyBgcC5wYXJlbnRgLlxuICAgICovXG4gICAgbm9kZShkZXB0aCkgeyByZXR1cm4gdGhpcy5wYXRoW3RoaXMucmVzb2x2ZURlcHRoKGRlcHRoKSAqIDNdOyB9XG4gICAgLyoqXG4gICAgVGhlIGluZGV4IGludG8gdGhlIGFuY2VzdG9yIGF0IHRoZSBnaXZlbiBsZXZlbC4gSWYgdGhpcyBwb2ludHNcbiAgICBhdCB0aGUgM3JkIG5vZGUgaW4gdGhlIDJuZCBwYXJhZ3JhcGggb24gdGhlIHRvcCBsZXZlbCwgZm9yXG4gICAgZXhhbXBsZSwgYHAuaW5kZXgoMClgIGlzIDEgYW5kIGBwLmluZGV4KDEpYCBpcyAyLlxuICAgICovXG4gICAgaW5kZXgoZGVwdGgpIHsgcmV0dXJuIHRoaXMucGF0aFt0aGlzLnJlc29sdmVEZXB0aChkZXB0aCkgKiAzICsgMV07IH1cbiAgICAvKipcbiAgICBUaGUgaW5kZXggcG9pbnRpbmcgYWZ0ZXIgdGhpcyBwb3NpdGlvbiBpbnRvIHRoZSBhbmNlc3RvciBhdCB0aGVcbiAgICBnaXZlbiBsZXZlbC5cbiAgICAqL1xuICAgIGluZGV4QWZ0ZXIoZGVwdGgpIHtcbiAgICAgICAgZGVwdGggPSB0aGlzLnJlc29sdmVEZXB0aChkZXB0aCk7XG4gICAgICAgIHJldHVybiB0aGlzLmluZGV4KGRlcHRoKSArIChkZXB0aCA9PSB0aGlzLmRlcHRoICYmICF0aGlzLnRleHRPZmZzZXQgPyAwIDogMSk7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSAoYWJzb2x1dGUpIHBvc2l0aW9uIGF0IHRoZSBzdGFydCBvZiB0aGUgbm9kZSBhdCB0aGUgZ2l2ZW5cbiAgICBsZXZlbC5cbiAgICAqL1xuICAgIHN0YXJ0KGRlcHRoKSB7XG4gICAgICAgIGRlcHRoID0gdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpO1xuICAgICAgICByZXR1cm4gZGVwdGggPT0gMCA/IDAgOiB0aGlzLnBhdGhbZGVwdGggKiAzIC0gMV0gKyAxO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgKGFic29sdXRlKSBwb3NpdGlvbiBhdCB0aGUgZW5kIG9mIHRoZSBub2RlIGF0IHRoZSBnaXZlblxuICAgIGxldmVsLlxuICAgICovXG4gICAgZW5kKGRlcHRoKSB7XG4gICAgICAgIGRlcHRoID0gdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpO1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFydChkZXB0aCkgKyB0aGlzLm5vZGUoZGVwdGgpLmNvbnRlbnQuc2l6ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIChhYnNvbHV0ZSkgcG9zaXRpb24gZGlyZWN0bHkgYmVmb3JlIHRoZSB3cmFwcGluZyBub2RlIGF0IHRoZVxuICAgIGdpdmVuIGxldmVsLCBvciwgd2hlbiBgZGVwdGhgIGlzIGB0aGlzLmRlcHRoICsgMWAsIHRoZSBvcmlnaW5hbFxuICAgIHBvc2l0aW9uLlxuICAgICovXG4gICAgYmVmb3JlKGRlcHRoKSB7XG4gICAgICAgIGRlcHRoID0gdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpO1xuICAgICAgICBpZiAoIWRlcHRoKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGVyZSBpcyBubyBwb3NpdGlvbiBiZWZvcmUgdGhlIHRvcC1sZXZlbCBub2RlXCIpO1xuICAgICAgICByZXR1cm4gZGVwdGggPT0gdGhpcy5kZXB0aCArIDEgPyB0aGlzLnBvcyA6IHRoaXMucGF0aFtkZXB0aCAqIDMgLSAxXTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIChhYnNvbHV0ZSkgcG9zaXRpb24gZGlyZWN0bHkgYWZ0ZXIgdGhlIHdyYXBwaW5nIG5vZGUgYXQgdGhlXG4gICAgZ2l2ZW4gbGV2ZWwsIG9yIHRoZSBvcmlnaW5hbCBwb3NpdGlvbiB3aGVuIGBkZXB0aGAgaXMgYHRoaXMuZGVwdGggKyAxYC5cbiAgICAqL1xuICAgIGFmdGVyKGRlcHRoKSB7XG4gICAgICAgIGRlcHRoID0gdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpO1xuICAgICAgICBpZiAoIWRlcHRoKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGVyZSBpcyBubyBwb3NpdGlvbiBhZnRlciB0aGUgdG9wLWxldmVsIG5vZGVcIik7XG4gICAgICAgIHJldHVybiBkZXB0aCA9PSB0aGlzLmRlcHRoICsgMSA/IHRoaXMucG9zIDogdGhpcy5wYXRoW2RlcHRoICogMyAtIDFdICsgdGhpcy5wYXRoW2RlcHRoICogM10ubm9kZVNpemU7XG4gICAgfVxuICAgIC8qKlxuICAgIFdoZW4gdGhpcyBwb3NpdGlvbiBwb2ludHMgaW50byBhIHRleHQgbm9kZSwgdGhpcyByZXR1cm5zIHRoZVxuICAgIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvc2l0aW9uIGFuZCB0aGUgc3RhcnQgb2YgdGhlIHRleHQgbm9kZS5cbiAgICBXaWxsIGJlIHplcm8gZm9yIHBvc2l0aW9ucyB0aGF0IHBvaW50IGJldHdlZW4gbm9kZXMuXG4gICAgKi9cbiAgICBnZXQgdGV4dE9mZnNldCgpIHsgcmV0dXJuIHRoaXMucG9zIC0gdGhpcy5wYXRoW3RoaXMucGF0aC5sZW5ndGggLSAxXTsgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgbm9kZSBkaXJlY3RseSBhZnRlciB0aGUgcG9zaXRpb24sIGlmIGFueS4gSWYgdGhlIHBvc2l0aW9uXG4gICAgcG9pbnRzIGludG8gYSB0ZXh0IG5vZGUsIG9ubHkgdGhlIHBhcnQgb2YgdGhhdCBub2RlIGFmdGVyIHRoZVxuICAgIHBvc2l0aW9uIGlzIHJldHVybmVkLlxuICAgICovXG4gICAgZ2V0IG5vZGVBZnRlcigpIHtcbiAgICAgICAgbGV0IHBhcmVudCA9IHRoaXMucGFyZW50LCBpbmRleCA9IHRoaXMuaW5kZXgodGhpcy5kZXB0aCk7XG4gICAgICAgIGlmIChpbmRleCA9PSBwYXJlbnQuY2hpbGRDb3VudClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBsZXQgZE9mZiA9IHRoaXMucG9zIC0gdGhpcy5wYXRoW3RoaXMucGF0aC5sZW5ndGggLSAxXSwgY2hpbGQgPSBwYXJlbnQuY2hpbGQoaW5kZXgpO1xuICAgICAgICByZXR1cm4gZE9mZiA/IHBhcmVudC5jaGlsZChpbmRleCkuY3V0KGRPZmYpIDogY2hpbGQ7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgbm9kZSBkaXJlY3RseSBiZWZvcmUgdGhlIHBvc2l0aW9uLCBpZiBhbnkuIElmIHRoZVxuICAgIHBvc2l0aW9uIHBvaW50cyBpbnRvIGEgdGV4dCBub2RlLCBvbmx5IHRoZSBwYXJ0IG9mIHRoYXQgbm9kZVxuICAgIGJlZm9yZSB0aGUgcG9zaXRpb24gaXMgcmV0dXJuZWQuXG4gICAgKi9cbiAgICBnZXQgbm9kZUJlZm9yZSgpIHtcbiAgICAgICAgbGV0IGluZGV4ID0gdGhpcy5pbmRleCh0aGlzLmRlcHRoKTtcbiAgICAgICAgbGV0IGRPZmYgPSB0aGlzLnBvcyAtIHRoaXMucGF0aFt0aGlzLnBhdGgubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmIChkT2ZmKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmNoaWxkKGluZGV4KS5jdXQoMCwgZE9mZik7XG4gICAgICAgIHJldHVybiBpbmRleCA9PSAwID8gbnVsbCA6IHRoaXMucGFyZW50LmNoaWxkKGluZGV4IC0gMSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgcG9zaXRpb24gYXQgdGhlIGdpdmVuIGluZGV4IGluIHRoZSBwYXJlbnQgbm9kZSBhdCB0aGVcbiAgICBnaXZlbiBkZXB0aCAod2hpY2ggZGVmYXVsdHMgdG8gYHRoaXMuZGVwdGhgKS5cbiAgICAqL1xuICAgIHBvc0F0SW5kZXgoaW5kZXgsIGRlcHRoKSB7XG4gICAgICAgIGRlcHRoID0gdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpO1xuICAgICAgICBsZXQgbm9kZSA9IHRoaXMucGF0aFtkZXB0aCAqIDNdLCBwb3MgPSBkZXB0aCA9PSAwID8gMCA6IHRoaXMucGF0aFtkZXB0aCAqIDMgLSAxXSArIDE7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kZXg7IGkrKylcbiAgICAgICAgICAgIHBvcyArPSBub2RlLmNoaWxkKGkpLm5vZGVTaXplO1xuICAgICAgICByZXR1cm4gcG9zO1xuICAgIH1cbiAgICAvKipcbiAgICBHZXQgdGhlIG1hcmtzIGF0IHRoaXMgcG9zaXRpb24sIGZhY3RvcmluZyBpbiB0aGUgc3Vycm91bmRpbmdcbiAgICBtYXJrcycgW2BpbmNsdXNpdmVgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTWFya1NwZWMuaW5jbHVzaXZlKSBwcm9wZXJ0eS4gSWYgdGhlXG4gICAgcG9zaXRpb24gaXMgYXQgdGhlIHN0YXJ0IG9mIGEgbm9uLWVtcHR5IG5vZGUsIHRoZSBtYXJrcyBvZiB0aGVcbiAgICBub2RlIGFmdGVyIGl0IChpZiBhbnkpIGFyZSByZXR1cm5lZC5cbiAgICAqL1xuICAgIG1hcmtzKCkge1xuICAgICAgICBsZXQgcGFyZW50ID0gdGhpcy5wYXJlbnQsIGluZGV4ID0gdGhpcy5pbmRleCgpO1xuICAgICAgICAvLyBJbiBhbiBlbXB0eSBwYXJlbnQsIHJldHVybiB0aGUgZW1wdHkgYXJyYXlcbiAgICAgICAgaWYgKHBhcmVudC5jb250ZW50LnNpemUgPT0gMClcbiAgICAgICAgICAgIHJldHVybiBNYXJrLm5vbmU7XG4gICAgICAgIC8vIFdoZW4gaW5zaWRlIGEgdGV4dCBub2RlLCBqdXN0IHJldHVybiB0aGUgdGV4dCBub2RlJ3MgbWFya3NcbiAgICAgICAgaWYgKHRoaXMudGV4dE9mZnNldClcbiAgICAgICAgICAgIHJldHVybiBwYXJlbnQuY2hpbGQoaW5kZXgpLm1hcmtzO1xuICAgICAgICBsZXQgbWFpbiA9IHBhcmVudC5tYXliZUNoaWxkKGluZGV4IC0gMSksIG90aGVyID0gcGFyZW50Lm1heWJlQ2hpbGQoaW5kZXgpO1xuICAgICAgICAvLyBJZiB0aGUgYGFmdGVyYCBmbGFnIGlzIHRydWUgb2YgdGhlcmUgaXMgbm8gbm9kZSBiZWZvcmUsIG1ha2VcbiAgICAgICAgLy8gdGhlIG5vZGUgYWZ0ZXIgdGhpcyBwb3NpdGlvbiB0aGUgbWFpbiByZWZlcmVuY2UuXG4gICAgICAgIGlmICghbWFpbikge1xuICAgICAgICAgICAgbGV0IHRtcCA9IG1haW47XG4gICAgICAgICAgICBtYWluID0gb3RoZXI7XG4gICAgICAgICAgICBvdGhlciA9IHRtcDtcbiAgICAgICAgfVxuICAgICAgICAvLyBVc2UgYWxsIG1hcmtzIGluIHRoZSBtYWluIG5vZGUsIGV4Y2VwdCB0aG9zZSB0aGF0IGhhdmVcbiAgICAgICAgLy8gYGluY2x1c2l2ZWAgc2V0IHRvIGZhbHNlIGFuZCBhcmUgbm90IHByZXNlbnQgaW4gdGhlIG90aGVyIG5vZGUuXG4gICAgICAgIGxldCBtYXJrcyA9IG1haW4ubWFya3M7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFya3MubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAobWFya3NbaV0udHlwZS5zcGVjLmluY2x1c2l2ZSA9PT0gZmFsc2UgJiYgKCFvdGhlciB8fCAhbWFya3NbaV0uaXNJblNldChvdGhlci5tYXJrcykpKVxuICAgICAgICAgICAgICAgIG1hcmtzID0gbWFya3NbaS0tXS5yZW1vdmVGcm9tU2V0KG1hcmtzKTtcbiAgICAgICAgcmV0dXJuIG1hcmtzO1xuICAgIH1cbiAgICAvKipcbiAgICBHZXQgdGhlIG1hcmtzIGFmdGVyIHRoZSBjdXJyZW50IHBvc2l0aW9uLCBpZiBhbnksIGV4Y2VwdCB0aG9zZVxuICAgIHRoYXQgYXJlIG5vbi1pbmNsdXNpdmUgYW5kIG5vdCBwcmVzZW50IGF0IHBvc2l0aW9uIGAkZW5kYC4gVGhpc1xuICAgIGlzIG1vc3RseSB1c2VmdWwgZm9yIGdldHRpbmcgdGhlIHNldCBvZiBtYXJrcyB0byBwcmVzZXJ2ZSBhZnRlciBhXG4gICAgZGVsZXRpb24uIFdpbGwgcmV0dXJuIGBudWxsYCBpZiB0aGlzIHBvc2l0aW9uIGlzIGF0IHRoZSBlbmQgb2ZcbiAgICBpdHMgcGFyZW50IG5vZGUgb3IgaXRzIHBhcmVudCBub2RlIGlzbid0IGEgdGV4dGJsb2NrIChpbiB3aGljaFxuICAgIGNhc2Ugbm8gbWFya3Mgc2hvdWxkIGJlIHByZXNlcnZlZCkuXG4gICAgKi9cbiAgICBtYXJrc0Fjcm9zcygkZW5kKSB7XG4gICAgICAgIGxldCBhZnRlciA9IHRoaXMucGFyZW50Lm1heWJlQ2hpbGQodGhpcy5pbmRleCgpKTtcbiAgICAgICAgaWYgKCFhZnRlciB8fCAhYWZ0ZXIuaXNJbmxpbmUpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgbGV0IG1hcmtzID0gYWZ0ZXIubWFya3MsIG5leHQgPSAkZW5kLnBhcmVudC5tYXliZUNoaWxkKCRlbmQuaW5kZXgoKSk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFya3MubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAobWFya3NbaV0udHlwZS5zcGVjLmluY2x1c2l2ZSA9PT0gZmFsc2UgJiYgKCFuZXh0IHx8ICFtYXJrc1tpXS5pc0luU2V0KG5leHQubWFya3MpKSlcbiAgICAgICAgICAgICAgICBtYXJrcyA9IG1hcmtzW2ktLV0ucmVtb3ZlRnJvbVNldChtYXJrcyk7XG4gICAgICAgIHJldHVybiBtYXJrcztcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIGRlcHRoIHVwIHRvIHdoaWNoIHRoaXMgcG9zaXRpb24gYW5kIHRoZSBnaXZlbiAobm9uLXJlc29sdmVkKVxuICAgIHBvc2l0aW9uIHNoYXJlIHRoZSBzYW1lIHBhcmVudCBub2Rlcy5cbiAgICAqL1xuICAgIHNoYXJlZERlcHRoKHBvcykge1xuICAgICAgICBmb3IgKGxldCBkZXB0aCA9IHRoaXMuZGVwdGg7IGRlcHRoID4gMDsgZGVwdGgtLSlcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXJ0KGRlcHRoKSA8PSBwb3MgJiYgdGhpcy5lbmQoZGVwdGgpID49IHBvcylcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVwdGg7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm5zIGEgcmFuZ2UgYmFzZWQgb24gdGhlIHBsYWNlIHdoZXJlIHRoaXMgcG9zaXRpb24gYW5kIHRoZVxuICAgIGdpdmVuIHBvc2l0aW9uIGRpdmVyZ2UgYXJvdW5kIGJsb2NrIGNvbnRlbnQuIElmIGJvdGggcG9pbnQgaW50b1xuICAgIHRoZSBzYW1lIHRleHRibG9jaywgZm9yIGV4YW1wbGUsIGEgcmFuZ2UgYXJvdW5kIHRoYXQgdGV4dGJsb2NrXG4gICAgd2lsbCBiZSByZXR1cm5lZC4gSWYgdGhleSBwb2ludCBpbnRvIGRpZmZlcmVudCBibG9ja3MsIHRoZSByYW5nZVxuICAgIGFyb3VuZCB0aG9zZSBibG9ja3MgaW4gdGhlaXIgc2hhcmVkIGFuY2VzdG9yIGlzIHJldHVybmVkLiBZb3UgY2FuXG4gICAgcGFzcyBpbiBhbiBvcHRpb25hbCBwcmVkaWNhdGUgdGhhdCB3aWxsIGJlIGNhbGxlZCB3aXRoIGEgcGFyZW50XG4gICAgbm9kZSB0byBzZWUgaWYgYSByYW5nZSBpbnRvIHRoYXQgcGFyZW50IGlzIGFjY2VwdGFibGUuXG4gICAgKi9cbiAgICBibG9ja1JhbmdlKG90aGVyID0gdGhpcywgcHJlZCkge1xuICAgICAgICBpZiAob3RoZXIucG9zIDwgdGhpcy5wb3MpXG4gICAgICAgICAgICByZXR1cm4gb3RoZXIuYmxvY2tSYW5nZSh0aGlzKTtcbiAgICAgICAgZm9yIChsZXQgZCA9IHRoaXMuZGVwdGggLSAodGhpcy5wYXJlbnQuaW5saW5lQ29udGVudCB8fCB0aGlzLnBvcyA9PSBvdGhlci5wb3MgPyAxIDogMCk7IGQgPj0gMDsgZC0tKVxuICAgICAgICAgICAgaWYgKG90aGVyLnBvcyA8PSB0aGlzLmVuZChkKSAmJiAoIXByZWQgfHwgcHJlZCh0aGlzLm5vZGUoZCkpKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE5vZGVSYW5nZSh0aGlzLCBvdGhlciwgZCk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBRdWVyeSB3aGV0aGVyIHRoZSBnaXZlbiBwb3NpdGlvbiBzaGFyZXMgdGhlIHNhbWUgcGFyZW50IG5vZGUuXG4gICAgKi9cbiAgICBzYW1lUGFyZW50KG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBvcyAtIHRoaXMucGFyZW50T2Zmc2V0ID09IG90aGVyLnBvcyAtIG90aGVyLnBhcmVudE9mZnNldDtcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJuIHRoZSBncmVhdGVyIG9mIHRoaXMgYW5kIHRoZSBnaXZlbiBwb3NpdGlvbi5cbiAgICAqL1xuICAgIG1heChvdGhlcikge1xuICAgICAgICByZXR1cm4gb3RoZXIucG9zID4gdGhpcy5wb3MgPyBvdGhlciA6IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHVybiB0aGUgc21hbGxlciBvZiB0aGlzIGFuZCB0aGUgZ2l2ZW4gcG9zaXRpb24uXG4gICAgKi9cbiAgICBtaW4ob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIG90aGVyLnBvcyA8IHRoaXMucG9zID8gb3RoZXIgOiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICBsZXQgc3RyID0gXCJcIjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gdGhpcy5kZXB0aDsgaSsrKVxuICAgICAgICAgICAgc3RyICs9IChzdHIgPyBcIi9cIiA6IFwiXCIpICsgdGhpcy5ub2RlKGkpLnR5cGUubmFtZSArIFwiX1wiICsgdGhpcy5pbmRleChpIC0gMSk7XG4gICAgICAgIHJldHVybiBzdHIgKyBcIjpcIiArIHRoaXMucGFyZW50T2Zmc2V0O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyByZXNvbHZlKGRvYywgcG9zKSB7XG4gICAgICAgIGlmICghKHBvcyA+PSAwICYmIHBvcyA8PSBkb2MuY29udGVudC5zaXplKSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiUG9zaXRpb24gXCIgKyBwb3MgKyBcIiBvdXQgb2YgcmFuZ2VcIik7XG4gICAgICAgIGxldCBwYXRoID0gW107XG4gICAgICAgIGxldCBzdGFydCA9IDAsIHBhcmVudE9mZnNldCA9IHBvcztcbiAgICAgICAgZm9yIChsZXQgbm9kZSA9IGRvYzs7KSB7XG4gICAgICAgICAgICBsZXQgeyBpbmRleCwgb2Zmc2V0IH0gPSBub2RlLmNvbnRlbnQuZmluZEluZGV4KHBhcmVudE9mZnNldCk7XG4gICAgICAgICAgICBsZXQgcmVtID0gcGFyZW50T2Zmc2V0IC0gb2Zmc2V0O1xuICAgICAgICAgICAgcGF0aC5wdXNoKG5vZGUsIGluZGV4LCBzdGFydCArIG9mZnNldCk7XG4gICAgICAgICAgICBpZiAoIXJlbSlcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLmNoaWxkKGluZGV4KTtcbiAgICAgICAgICAgIGlmIChub2RlLmlzVGV4dClcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIHBhcmVudE9mZnNldCA9IHJlbSAtIDE7XG4gICAgICAgICAgICBzdGFydCArPSBvZmZzZXQgKyAxO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgUmVzb2x2ZWRQb3MocG9zLCBwYXRoLCBwYXJlbnRPZmZzZXQpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyByZXNvbHZlQ2FjaGVkKGRvYywgcG9zKSB7XG4gICAgICAgIGxldCBjYWNoZSA9IHJlc29sdmVDYWNoZS5nZXQoZG9jKTtcbiAgICAgICAgaWYgKGNhY2hlKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNhY2hlLmVsdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgZWx0ID0gY2FjaGUuZWx0c1tpXTtcbiAgICAgICAgICAgICAgICBpZiAoZWx0LnBvcyA9PSBwb3MpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBlbHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXNvbHZlQ2FjaGUuc2V0KGRvYywgY2FjaGUgPSBuZXcgUmVzb2x2ZUNhY2hlKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzdWx0ID0gY2FjaGUuZWx0c1tjYWNoZS5pXSA9IFJlc29sdmVkUG9zLnJlc29sdmUoZG9jLCBwb3MpO1xuICAgICAgICBjYWNoZS5pID0gKGNhY2hlLmkgKyAxKSAlIHJlc29sdmVDYWNoZVNpemU7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxufVxuY2xhc3MgUmVzb2x2ZUNhY2hlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5lbHRzID0gW107XG4gICAgICAgIHRoaXMuaSA9IDA7XG4gICAgfVxufVxuY29uc3QgcmVzb2x2ZUNhY2hlU2l6ZSA9IDEyLCByZXNvbHZlQ2FjaGUgPSBuZXcgV2Vha01hcCgpO1xuLyoqXG5SZXByZXNlbnRzIGEgZmxhdCByYW5nZSBvZiBjb250ZW50LCBpLmUuIG9uZSB0aGF0IHN0YXJ0cyBhbmRcbmVuZHMgaW4gdGhlIHNhbWUgbm9kZS5cbiovXG5jbGFzcyBOb2RlUmFuZ2Uge1xuICAgIC8qKlxuICAgIENvbnN0cnVjdCBhIG5vZGUgcmFuZ2UuIGAkZnJvbWAgYW5kIGAkdG9gIHNob3VsZCBwb2ludCBpbnRvIHRoZVxuICAgIHNhbWUgbm9kZSB1bnRpbCBhdCBsZWFzdCB0aGUgZ2l2ZW4gYGRlcHRoYCwgc2luY2UgYSBub2RlIHJhbmdlXG4gICAgZGVub3RlcyBhbiBhZGphY2VudCBzZXQgb2Ygbm9kZXMgaW4gYSBzaW5nbGUgcGFyZW50IG5vZGUuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBBIHJlc29sdmVkIHBvc2l0aW9uIGFsb25nIHRoZSBzdGFydCBvZiB0aGUgY29udGVudC4gTWF5IGhhdmUgYVxuICAgIGBkZXB0aGAgZ3JlYXRlciB0aGFuIHRoaXMgb2JqZWN0J3MgYGRlcHRoYCBwcm9wZXJ0eSwgc2luY2VcbiAgICB0aGVzZSBhcmUgdGhlIHBvc2l0aW9ucyB0aGF0IHdlcmUgdXNlZCB0byBjb21wdXRlIHRoZSByYW5nZSxcbiAgICBub3QgcmUtcmVzb2x2ZWQgcG9zaXRpb25zIGRpcmVjdGx5IGF0IGl0cyBib3VuZGFyaWVzLlxuICAgICovXG4gICAgJGZyb20sIFxuICAgIC8qKlxuICAgIEEgcG9zaXRpb24gYWxvbmcgdGhlIGVuZCBvZiB0aGUgY29udGVudC4gU2VlXG4gICAgY2F2ZWF0IGZvciBbYCRmcm9tYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVSYW5nZS4kZnJvbSkuXG4gICAgKi9cbiAgICAkdG8sIFxuICAgIC8qKlxuICAgIFRoZSBkZXB0aCBvZiB0aGUgbm9kZSB0aGF0IHRoaXMgcmFuZ2UgcG9pbnRzIGludG8uXG4gICAgKi9cbiAgICBkZXB0aCkge1xuICAgICAgICB0aGlzLiRmcm9tID0gJGZyb207XG4gICAgICAgIHRoaXMuJHRvID0gJHRvO1xuICAgICAgICB0aGlzLmRlcHRoID0gZGVwdGg7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSBwb3NpdGlvbiBhdCB0aGUgc3RhcnQgb2YgdGhlIHJhbmdlLlxuICAgICovXG4gICAgZ2V0IHN0YXJ0KCkgeyByZXR1cm4gdGhpcy4kZnJvbS5iZWZvcmUodGhpcy5kZXB0aCArIDEpOyB9XG4gICAgLyoqXG4gICAgVGhlIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIHJhbmdlLlxuICAgICovXG4gICAgZ2V0IGVuZCgpIHsgcmV0dXJuIHRoaXMuJHRvLmFmdGVyKHRoaXMuZGVwdGggKyAxKTsgfVxuICAgIC8qKlxuICAgIFRoZSBwYXJlbnQgbm9kZSB0aGF0IHRoZSByYW5nZSBwb2ludHMgaW50by5cbiAgICAqL1xuICAgIGdldCBwYXJlbnQoKSB7IHJldHVybiB0aGlzLiRmcm9tLm5vZGUodGhpcy5kZXB0aCk7IH1cbiAgICAvKipcbiAgICBUaGUgc3RhcnQgaW5kZXggb2YgdGhlIHJhbmdlIGluIHRoZSBwYXJlbnQgbm9kZS5cbiAgICAqL1xuICAgIGdldCBzdGFydEluZGV4KCkgeyByZXR1cm4gdGhpcy4kZnJvbS5pbmRleCh0aGlzLmRlcHRoKTsgfVxuICAgIC8qKlxuICAgIFRoZSBlbmQgaW5kZXggb2YgdGhlIHJhbmdlIGluIHRoZSBwYXJlbnQgbm9kZS5cbiAgICAqL1xuICAgIGdldCBlbmRJbmRleCgpIHsgcmV0dXJuIHRoaXMuJHRvLmluZGV4QWZ0ZXIodGhpcy5kZXB0aCk7IH1cbn1cblxuY29uc3QgZW1wdHlBdHRycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4vKipcblRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIG5vZGUgaW4gdGhlIHRyZWUgdGhhdCBtYWtlcyB1cCBhXG5Qcm9zZU1pcnJvciBkb2N1bWVudC4gU28gYSBkb2N1bWVudCBpcyBhbiBpbnN0YW5jZSBvZiBgTm9kZWAsIHdpdGhcbmNoaWxkcmVuIHRoYXQgYXJlIGFsc28gaW5zdGFuY2VzIG9mIGBOb2RlYC5cblxuTm9kZXMgYXJlIHBlcnNpc3RlbnQgZGF0YSBzdHJ1Y3R1cmVzLiBJbnN0ZWFkIG9mIGNoYW5naW5nIHRoZW0sIHlvdVxuY3JlYXRlIG5ldyBvbmVzIHdpdGggdGhlIGNvbnRlbnQgeW91IHdhbnQuIE9sZCBvbmVzIGtlZXAgcG9pbnRpbmdcbmF0IHRoZSBvbGQgZG9jdW1lbnQgc2hhcGUuIFRoaXMgaXMgbWFkZSBjaGVhcGVyIGJ5IHNoYXJpbmdcbnN0cnVjdHVyZSBiZXR3ZWVuIHRoZSBvbGQgYW5kIG5ldyBkYXRhIGFzIG11Y2ggYXMgcG9zc2libGUsIHdoaWNoIGFcbnRyZWUgc2hhcGUgbGlrZSB0aGlzICh3aXRob3V0IGJhY2sgcG9pbnRlcnMpIG1ha2VzIGVhc3kuXG5cbioqRG8gbm90KiogZGlyZWN0bHkgbXV0YXRlIHRoZSBwcm9wZXJ0aWVzIG9mIGEgYE5vZGVgIG9iamVjdC4gU2VlXG5bdGhlIGd1aWRlXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL2d1aWRlLyNkb2MpIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuKi9cbmNsYXNzIE5vZGUge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHR5cGUgb2Ygbm9kZSB0aGF0IHRoaXMgaXMuXG4gICAgKi9cbiAgICB0eXBlLCBcbiAgICAvKipcbiAgICBBbiBvYmplY3QgbWFwcGluZyBhdHRyaWJ1dGUgbmFtZXMgdG8gdmFsdWVzLiBUaGUga2luZCBvZlxuICAgIGF0dHJpYnV0ZXMgYWxsb3dlZCBhbmQgcmVxdWlyZWQgYXJlXG4gICAgW2RldGVybWluZWRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5hdHRycykgYnkgdGhlIG5vZGUgdHlwZS5cbiAgICAqL1xuICAgIGF0dHJzLCBcbiAgICAvLyBBIGZyYWdtZW50IGhvbGRpbmcgdGhlIG5vZGUncyBjaGlsZHJlbi5cbiAgICBjb250ZW50LCBcbiAgICAvKipcbiAgICBUaGUgbWFya3MgKHRoaW5ncyBsaWtlIHdoZXRoZXIgaXQgaXMgZW1waGFzaXplZCBvciBwYXJ0IG9mIGFcbiAgICBsaW5rKSBhcHBsaWVkIHRvIHRoaXMgbm9kZS5cbiAgICAqL1xuICAgIG1hcmtzID0gTWFyay5ub25lKSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuYXR0cnMgPSBhdHRycztcbiAgICAgICAgdGhpcy5tYXJrcyA9IG1hcmtzO1xuICAgICAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50IHx8IEZyYWdtZW50LmVtcHR5O1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgYXJyYXkgb2YgdGhpcyBub2RlJ3MgY2hpbGQgbm9kZXMuXG4gICAgKi9cbiAgICBnZXQgY2hpbGRyZW4oKSB7IHJldHVybiB0aGlzLmNvbnRlbnQuY29udGVudDsgfVxuICAgIC8qKlxuICAgIFRoZSBzaXplIG9mIHRoaXMgbm9kZSwgYXMgZGVmaW5lZCBieSB0aGUgaW50ZWdlci1iYXNlZCBbaW5kZXhpbmdcbiAgICBzY2hlbWVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvZ3VpZGUvI2RvYy5pbmRleGluZykuIEZvciB0ZXh0IG5vZGVzLCB0aGlzIGlzIHRoZVxuICAgIGFtb3VudCBvZiBjaGFyYWN0ZXJzLiBGb3Igb3RoZXIgbGVhZiBub2RlcywgaXQgaXMgb25lLiBGb3JcbiAgICBub24tbGVhZiBub2RlcywgaXQgaXMgdGhlIHNpemUgb2YgdGhlIGNvbnRlbnQgcGx1cyB0d28gKHRoZVxuICAgIHN0YXJ0IGFuZCBlbmQgdG9rZW4pLlxuICAgICovXG4gICAgZ2V0IG5vZGVTaXplKCkgeyByZXR1cm4gdGhpcy5pc0xlYWYgPyAxIDogMiArIHRoaXMuY29udGVudC5zaXplOyB9XG4gICAgLyoqXG4gICAgVGhlIG51bWJlciBvZiBjaGlsZHJlbiB0aGF0IHRoZSBub2RlIGhhcy5cbiAgICAqL1xuICAgIGdldCBjaGlsZENvdW50KCkgeyByZXR1cm4gdGhpcy5jb250ZW50LmNoaWxkQ291bnQ7IH1cbiAgICAvKipcbiAgICBHZXQgdGhlIGNoaWxkIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4LiBSYWlzZXMgYW4gZXJyb3Igd2hlbiB0aGVcbiAgICBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuXG4gICAgKi9cbiAgICBjaGlsZChpbmRleCkgeyByZXR1cm4gdGhpcy5jb250ZW50LmNoaWxkKGluZGV4KTsgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgY2hpbGQgbm9kZSBhdCB0aGUgZ2l2ZW4gaW5kZXgsIGlmIGl0IGV4aXN0cy5cbiAgICAqL1xuICAgIG1heWJlQ2hpbGQoaW5kZXgpIHsgcmV0dXJuIHRoaXMuY29udGVudC5tYXliZUNoaWxkKGluZGV4KTsgfVxuICAgIC8qKlxuICAgIENhbGwgYGZgIGZvciBldmVyeSBjaGlsZCBub2RlLCBwYXNzaW5nIHRoZSBub2RlLCBpdHMgb2Zmc2V0XG4gICAgaW50byB0aGlzIHBhcmVudCBub2RlLCBhbmQgaXRzIGluZGV4LlxuICAgICovXG4gICAgZm9yRWFjaChmKSB7IHRoaXMuY29udGVudC5mb3JFYWNoKGYpOyB9XG4gICAgLyoqXG4gICAgSW52b2tlIGEgY2FsbGJhY2sgZm9yIGFsbCBkZXNjZW5kYW50IG5vZGVzIHJlY3Vyc2l2ZWx5IG92ZXJsYXBwaW5nXG4gICAgdGhlIGdpdmVuIHR3byBwb3NpdGlvbnMgdGhhdCBhcmUgcmVsYXRpdmUgdG8gc3RhcnQgb2YgdGhpc1xuICAgIG5vZGUncyBjb250ZW50LiBUaGlzIGluY2x1ZGVzIGFsbCBhbmNlc3RvcnMgb2YgdGhlIG5vZGVzXG4gICAgY29udGFpbmluZyB0aGUgdHdvIHBvc2l0aW9ucy4gVGhlIGNhbGxiYWNrIGlzIGludm9rZWQgd2l0aCB0aGVcbiAgICBub2RlLCBpdHMgcG9zaXRpb24gcmVsYXRpdmUgdG8gdGhlIG9yaWdpbmFsIG5vZGUgKG1ldGhvZCByZWNlaXZlciksXG4gICAgaXRzIHBhcmVudCBub2RlLCBhbmQgaXRzIGNoaWxkIGluZGV4LiBXaGVuIHRoZSBjYWxsYmFjayByZXR1cm5zXG4gICAgZmFsc2UgZm9yIGEgZ2l2ZW4gbm9kZSwgdGhhdCBub2RlJ3MgY2hpbGRyZW4gd2lsbCBub3QgYmVcbiAgICByZWN1cnNlZCBvdmVyLiBUaGUgbGFzdCBwYXJhbWV0ZXIgY2FuIGJlIHVzZWQgdG8gc3BlY2lmeSBhXG4gICAgc3RhcnRpbmcgcG9zaXRpb24gdG8gY291bnQgZnJvbS5cbiAgICAqL1xuICAgIG5vZGVzQmV0d2Vlbihmcm9tLCB0bywgZiwgc3RhcnRQb3MgPSAwKSB7XG4gICAgICAgIHRoaXMuY29udGVudC5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIGYsIHN0YXJ0UG9zLCB0aGlzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ2FsbCB0aGUgZ2l2ZW4gY2FsbGJhY2sgZm9yIGV2ZXJ5IGRlc2NlbmRhbnQgbm9kZS4gRG9lc24ndFxuICAgIGRlc2NlbmQgaW50byBhIG5vZGUgd2hlbiB0aGUgY2FsbGJhY2sgcmV0dXJucyBgZmFsc2VgLlxuICAgICovXG4gICAgZGVzY2VuZGFudHMoZikge1xuICAgICAgICB0aGlzLm5vZGVzQmV0d2VlbigwLCB0aGlzLmNvbnRlbnQuc2l6ZSwgZik7XG4gICAgfVxuICAgIC8qKlxuICAgIENvbmNhdGVuYXRlcyBhbGwgdGhlIHRleHQgbm9kZXMgZm91bmQgaW4gdGhpcyBmcmFnbWVudCBhbmQgaXRzXG4gICAgY2hpbGRyZW4uXG4gICAgKi9cbiAgICBnZXQgdGV4dENvbnRlbnQoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy5pc0xlYWYgJiYgdGhpcy50eXBlLnNwZWMubGVhZlRleHQpXG4gICAgICAgICAgICA/IHRoaXMudHlwZS5zcGVjLmxlYWZUZXh0KHRoaXMpXG4gICAgICAgICAgICA6IHRoaXMudGV4dEJldHdlZW4oMCwgdGhpcy5jb250ZW50LnNpemUsIFwiXCIpO1xuICAgIH1cbiAgICAvKipcbiAgICBHZXQgYWxsIHRleHQgYmV0d2VlbiBwb3NpdGlvbnMgYGZyb21gIGFuZCBgdG9gLiBXaGVuXG4gICAgYGJsb2NrU2VwYXJhdG9yYCBpcyBnaXZlbiwgaXQgd2lsbCBiZSBpbnNlcnRlZCB0byBzZXBhcmF0ZSB0ZXh0XG4gICAgZnJvbSBkaWZmZXJlbnQgYmxvY2sgbm9kZXMuIElmIGBsZWFmVGV4dGAgaXMgZ2l2ZW4sIGl0J2xsIGJlXG4gICAgaW5zZXJ0ZWQgZm9yIGV2ZXJ5IG5vbi10ZXh0IGxlYWYgbm9kZSBlbmNvdW50ZXJlZCwgb3RoZXJ3aXNlXG4gICAgW2BsZWFmVGV4dGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5sZWFmVGV4dCkgd2lsbCBiZSB1c2VkLlxuICAgICovXG4gICAgdGV4dEJldHdlZW4oZnJvbSwgdG8sIGJsb2NrU2VwYXJhdG9yLCBsZWFmVGV4dCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZW50LnRleHRCZXR3ZWVuKGZyb20sIHRvLCBibG9ja1NlcGFyYXRvciwgbGVhZlRleHQpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm5zIHRoaXMgbm9kZSdzIGZpcnN0IGNoaWxkLCBvciBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vXG4gICAgY2hpbGRyZW4uXG4gICAgKi9cbiAgICBnZXQgZmlyc3RDaGlsZCgpIHsgcmV0dXJuIHRoaXMuY29udGVudC5maXJzdENoaWxkOyB9XG4gICAgLyoqXG4gICAgUmV0dXJucyB0aGlzIG5vZGUncyBsYXN0IGNoaWxkLCBvciBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vXG4gICAgY2hpbGRyZW4uXG4gICAgKi9cbiAgICBnZXQgbGFzdENoaWxkKCkgeyByZXR1cm4gdGhpcy5jb250ZW50Lmxhc3RDaGlsZDsgfVxuICAgIC8qKlxuICAgIFRlc3Qgd2hldGhlciB0d28gbm9kZXMgcmVwcmVzZW50IHRoZSBzYW1lIHBpZWNlIG9mIGRvY3VtZW50LlxuICAgICovXG4gICAgZXEob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXIgfHwgKHRoaXMuc2FtZU1hcmt1cChvdGhlcikgJiYgdGhpcy5jb250ZW50LmVxKG90aGVyLmNvbnRlbnQpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ29tcGFyZSB0aGUgbWFya3VwICh0eXBlLCBhdHRyaWJ1dGVzLCBhbmQgbWFya3MpIG9mIHRoaXMgbm9kZSB0b1xuICAgIHRob3NlIG9mIGFub3RoZXIuIFJldHVybnMgYHRydWVgIGlmIGJvdGggaGF2ZSB0aGUgc2FtZSBtYXJrdXAuXG4gICAgKi9cbiAgICBzYW1lTWFya3VwKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhhc01hcmt1cChvdGhlci50eXBlLCBvdGhlci5hdHRycywgb3RoZXIubWFya3MpO1xuICAgIH1cbiAgICAvKipcbiAgICBDaGVjayB3aGV0aGVyIHRoaXMgbm9kZSdzIG1hcmt1cCBjb3JyZXNwb25kIHRvIHRoZSBnaXZlbiB0eXBlLFxuICAgIGF0dHJpYnV0ZXMsIGFuZCBtYXJrcy5cbiAgICAqL1xuICAgIGhhc01hcmt1cCh0eXBlLCBhdHRycywgbWFya3MpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZSA9PSB0eXBlICYmXG4gICAgICAgICAgICBjb21wYXJlRGVlcCh0aGlzLmF0dHJzLCBhdHRycyB8fCB0eXBlLmRlZmF1bHRBdHRycyB8fCBlbXB0eUF0dHJzKSAmJlxuICAgICAgICAgICAgTWFyay5zYW1lU2V0KHRoaXMubWFya3MsIG1hcmtzIHx8IE1hcmsubm9uZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5ldyBub2RlIHdpdGggdGhlIHNhbWUgbWFya3VwIGFzIHRoaXMgbm9kZSwgY29udGFpbmluZ1xuICAgIHRoZSBnaXZlbiBjb250ZW50IChvciBlbXB0eSwgaWYgbm8gY29udGVudCBpcyBnaXZlbikuXG4gICAgKi9cbiAgICBjb3B5KGNvbnRlbnQgPSBudWxsKSB7XG4gICAgICAgIGlmIChjb250ZW50ID09IHRoaXMuY29udGVudClcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IE5vZGUodGhpcy50eXBlLCB0aGlzLmF0dHJzLCBjb250ZW50LCB0aGlzLm1hcmtzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgY29weSBvZiB0aGlzIG5vZGUsIHdpdGggdGhlIGdpdmVuIHNldCBvZiBtYXJrcyBpbnN0ZWFkXG4gICAgb2YgdGhlIG5vZGUncyBvd24gbWFya3MuXG4gICAgKi9cbiAgICBtYXJrKG1hcmtzKSB7XG4gICAgICAgIHJldHVybiBtYXJrcyA9PSB0aGlzLm1hcmtzID8gdGhpcyA6IG5ldyBOb2RlKHRoaXMudHlwZSwgdGhpcy5hdHRycywgdGhpcy5jb250ZW50LCBtYXJrcyk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIGNvcHkgb2YgdGhpcyBub2RlIHdpdGggb25seSB0aGUgY29udGVudCBiZXR3ZWVuIHRoZVxuICAgIGdpdmVuIHBvc2l0aW9ucy4gSWYgYHRvYCBpcyBub3QgZ2l2ZW4sIGl0IGRlZmF1bHRzIHRvIHRoZSBlbmQgb2ZcbiAgICB0aGUgbm9kZS5cbiAgICAqL1xuICAgIGN1dChmcm9tLCB0byA9IHRoaXMuY29udGVudC5zaXplKSB7XG4gICAgICAgIGlmIChmcm9tID09IDAgJiYgdG8gPT0gdGhpcy5jb250ZW50LnNpemUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgcmV0dXJuIHRoaXMuY29weSh0aGlzLmNvbnRlbnQuY3V0KGZyb20sIHRvKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEN1dCBvdXQgdGhlIHBhcnQgb2YgdGhlIGRvY3VtZW50IGJldHdlZW4gdGhlIGdpdmVuIHBvc2l0aW9ucywgYW5kXG4gICAgcmV0dXJuIGl0IGFzIGEgYFNsaWNlYCBvYmplY3QuXG4gICAgKi9cbiAgICBzbGljZShmcm9tLCB0byA9IHRoaXMuY29udGVudC5zaXplLCBpbmNsdWRlUGFyZW50cyA9IGZhbHNlKSB7XG4gICAgICAgIGlmIChmcm9tID09IHRvKVxuICAgICAgICAgICAgcmV0dXJuIFNsaWNlLmVtcHR5O1xuICAgICAgICBsZXQgJGZyb20gPSB0aGlzLnJlc29sdmUoZnJvbSksICR0byA9IHRoaXMucmVzb2x2ZSh0byk7XG4gICAgICAgIGxldCBkZXB0aCA9IGluY2x1ZGVQYXJlbnRzID8gMCA6ICRmcm9tLnNoYXJlZERlcHRoKHRvKTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gJGZyb20uc3RhcnQoZGVwdGgpLCBub2RlID0gJGZyb20ubm9kZShkZXB0aCk7XG4gICAgICAgIGxldCBjb250ZW50ID0gbm9kZS5jb250ZW50LmN1dCgkZnJvbS5wb3MgLSBzdGFydCwgJHRvLnBvcyAtIHN0YXJ0KTtcbiAgICAgICAgcmV0dXJuIG5ldyBTbGljZShjb250ZW50LCAkZnJvbS5kZXB0aCAtIGRlcHRoLCAkdG8uZGVwdGggLSBkZXB0aCk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIHBhcnQgb2YgdGhlIGRvY3VtZW50IGJldHdlZW4gdGhlIGdpdmVuIHBvc2l0aW9ucyB3aXRoXG4gICAgdGhlIGdpdmVuIHNsaWNlLiBUaGUgc2xpY2UgbXVzdCAnZml0JywgbWVhbmluZyBpdHMgb3BlbiBzaWRlc1xuICAgIG11c3QgYmUgYWJsZSB0byBjb25uZWN0IHRvIHRoZSBzdXJyb3VuZGluZyBjb250ZW50LCBhbmQgaXRzXG4gICAgY29udGVudCBub2RlcyBtdXN0IGJlIHZhbGlkIGNoaWxkcmVuIGZvciB0aGUgbm9kZSB0aGV5IGFyZSBwbGFjZWRcbiAgICBpbnRvLiBJZiBhbnkgb2YgdGhpcyBpcyB2aW9sYXRlZCwgYW4gZXJyb3Igb2YgdHlwZVxuICAgIFtgUmVwbGFjZUVycm9yYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLlJlcGxhY2VFcnJvcikgaXMgdGhyb3duLlxuICAgICovXG4gICAgcmVwbGFjZShmcm9tLCB0bywgc2xpY2UpIHtcbiAgICAgICAgcmV0dXJuIHJlcGxhY2UodGhpcy5yZXNvbHZlKGZyb20pLCB0aGlzLnJlc29sdmUodG8pLCBzbGljZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgdGhlIG5vZGUgZGlyZWN0bHkgYWZ0ZXIgdGhlIGdpdmVuIHBvc2l0aW9uLlxuICAgICovXG4gICAgbm9kZUF0KHBvcykge1xuICAgICAgICBmb3IgKGxldCBub2RlID0gdGhpczs7KSB7XG4gICAgICAgICAgICBsZXQgeyBpbmRleCwgb2Zmc2V0IH0gPSBub2RlLmNvbnRlbnQuZmluZEluZGV4KHBvcyk7XG4gICAgICAgICAgICBub2RlID0gbm9kZS5tYXliZUNoaWxkKGluZGV4KTtcbiAgICAgICAgICAgIGlmICghbm9kZSlcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPT0gcG9zIHx8IG5vZGUuaXNUZXh0KVxuICAgICAgICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICAgICAgcG9zIC09IG9mZnNldCArIDE7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCB0aGUgKGRpcmVjdCkgY2hpbGQgbm9kZSBhZnRlciB0aGUgZ2l2ZW4gb2Zmc2V0LCBpZiBhbnksXG4gICAgYW5kIHJldHVybiBpdCBhbG9uZyB3aXRoIGl0cyBpbmRleCBhbmQgb2Zmc2V0IHJlbGF0aXZlIHRvIHRoaXNcbiAgICBub2RlLlxuICAgICovXG4gICAgY2hpbGRBZnRlcihwb3MpIHtcbiAgICAgICAgbGV0IHsgaW5kZXgsIG9mZnNldCB9ID0gdGhpcy5jb250ZW50LmZpbmRJbmRleChwb3MpO1xuICAgICAgICByZXR1cm4geyBub2RlOiB0aGlzLmNvbnRlbnQubWF5YmVDaGlsZChpbmRleCksIGluZGV4LCBvZmZzZXQgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCB0aGUgKGRpcmVjdCkgY2hpbGQgbm9kZSBiZWZvcmUgdGhlIGdpdmVuIG9mZnNldCwgaWYgYW55LFxuICAgIGFuZCByZXR1cm4gaXQgYWxvbmcgd2l0aCBpdHMgaW5kZXggYW5kIG9mZnNldCByZWxhdGl2ZSB0byB0aGlzXG4gICAgbm9kZS5cbiAgICAqL1xuICAgIGNoaWxkQmVmb3JlKHBvcykge1xuICAgICAgICBpZiAocG9zID09IDApXG4gICAgICAgICAgICByZXR1cm4geyBub2RlOiBudWxsLCBpbmRleDogMCwgb2Zmc2V0OiAwIH07XG4gICAgICAgIGxldCB7IGluZGV4LCBvZmZzZXQgfSA9IHRoaXMuY29udGVudC5maW5kSW5kZXgocG9zKTtcbiAgICAgICAgaWYgKG9mZnNldCA8IHBvcylcbiAgICAgICAgICAgIHJldHVybiB7IG5vZGU6IHRoaXMuY29udGVudC5jaGlsZChpbmRleCksIGluZGV4LCBvZmZzZXQgfTtcbiAgICAgICAgbGV0IG5vZGUgPSB0aGlzLmNvbnRlbnQuY2hpbGQoaW5kZXggLSAxKTtcbiAgICAgICAgcmV0dXJuIHsgbm9kZSwgaW5kZXg6IGluZGV4IC0gMSwgb2Zmc2V0OiBvZmZzZXQgLSBub2RlLm5vZGVTaXplIH07XG4gICAgfVxuICAgIC8qKlxuICAgIFJlc29sdmUgdGhlIGdpdmVuIHBvc2l0aW9uIGluIHRoZSBkb2N1bWVudCwgcmV0dXJuaW5nIGFuXG4gICAgW29iamVjdF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLlJlc29sdmVkUG9zKSB3aXRoIGluZm9ybWF0aW9uIGFib3V0IGl0cyBjb250ZXh0LlxuICAgICovXG4gICAgcmVzb2x2ZShwb3MpIHsgcmV0dXJuIFJlc29sdmVkUG9zLnJlc29sdmVDYWNoZWQodGhpcywgcG9zKTsgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgcmVzb2x2ZU5vQ2FjaGUocG9zKSB7IHJldHVybiBSZXNvbHZlZFBvcy5yZXNvbHZlKHRoaXMsIHBvcyk7IH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgYSBnaXZlbiBtYXJrIG9yIG1hcmsgdHlwZSBvY2N1cnMgaW4gdGhpcyBkb2N1bWVudFxuICAgIGJldHdlZW4gdGhlIHR3byBnaXZlbiBwb3NpdGlvbnMuXG4gICAgKi9cbiAgICByYW5nZUhhc01hcmsoZnJvbSwgdG8sIHR5cGUpIHtcbiAgICAgICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgICAgIGlmICh0byA+IGZyb20pXG4gICAgICAgICAgICB0aGlzLm5vZGVzQmV0d2Vlbihmcm9tLCB0bywgbm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGUuaXNJblNldChub2RlLm1hcmtzKSlcbiAgICAgICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiAhZm91bmQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZvdW5kO1xuICAgIH1cbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhpcyBpcyBhIGJsb2NrIChub24taW5saW5lIG5vZGUpXG4gICAgKi9cbiAgICBnZXQgaXNCbG9jaygpIHsgcmV0dXJuIHRoaXMudHlwZS5pc0Jsb2NrOyB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoaXMgaXMgYSB0ZXh0YmxvY2sgbm9kZSwgYSBibG9jayBub2RlIHdpdGggaW5saW5lXG4gICAgY29udGVudC5cbiAgICAqL1xuICAgIGdldCBpc1RleHRibG9jaygpIHsgcmV0dXJuIHRoaXMudHlwZS5pc1RleHRibG9jazsgfVxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGlzIG5vZGUgYWxsb3dzIGlubGluZSBjb250ZW50LlxuICAgICovXG4gICAgZ2V0IGlubGluZUNvbnRlbnQoKSB7IHJldHVybiB0aGlzLnR5cGUuaW5saW5lQ29udGVudDsgfVxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGlzIGlzIGFuIGlubGluZSBub2RlIChhIHRleHQgbm9kZSBvciBhIG5vZGUgdGhhdCBjYW5cbiAgICBhcHBlYXIgYW1vbmcgdGV4dCkuXG4gICAgKi9cbiAgICBnZXQgaXNJbmxpbmUoKSB7IHJldHVybiB0aGlzLnR5cGUuaXNJbmxpbmU7IH1cbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhpcyBpcyBhIHRleHQgbm9kZS5cbiAgICAqL1xuICAgIGdldCBpc1RleHQoKSB7IHJldHVybiB0aGlzLnR5cGUuaXNUZXh0OyB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoaXMgaXMgYSBsZWFmIG5vZGUuXG4gICAgKi9cbiAgICBnZXQgaXNMZWFmKCkgeyByZXR1cm4gdGhpcy50eXBlLmlzTGVhZjsgfVxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGlzIGlzIGFuIGF0b20sIGkuZS4gd2hlbiBpdCBkb2VzIG5vdCBoYXZlIGRpcmVjdGx5XG4gICAgZWRpdGFibGUgY29udGVudC4gVGhpcyBpcyB1c3VhbGx5IHRoZSBzYW1lIGFzIGBpc0xlYWZgLCBidXQgY2FuXG4gICAgYmUgY29uZmlndXJlZCB3aXRoIHRoZSBbYGF0b21gIHByb3BlcnR5XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuYXRvbSlcbiAgICBvbiBhIG5vZGUncyBzcGVjICh0eXBpY2FsbHkgdXNlZCB3aGVuIHRoZSBub2RlIGlzIGRpc3BsYXllZCBhc1xuICAgIGFuIHVuZWRpdGFibGUgW25vZGUgdmlld10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuTm9kZVZpZXcpKS5cbiAgICAqL1xuICAgIGdldCBpc0F0b20oKSB7IHJldHVybiB0aGlzLnR5cGUuaXNBdG9tOyB9XG4gICAgLyoqXG4gICAgUmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgbm9kZSBmb3IgZGVidWdnaW5nXG4gICAgcHVycG9zZXMuXG4gICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgaWYgKHRoaXMudHlwZS5zcGVjLnRvRGVidWdTdHJpbmcpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50eXBlLnNwZWMudG9EZWJ1Z1N0cmluZyh0aGlzKTtcbiAgICAgICAgbGV0IG5hbWUgPSB0aGlzLnR5cGUubmFtZTtcbiAgICAgICAgaWYgKHRoaXMuY29udGVudC5zaXplKVxuICAgICAgICAgICAgbmFtZSArPSBcIihcIiArIHRoaXMuY29udGVudC50b1N0cmluZ0lubmVyKCkgKyBcIilcIjtcbiAgICAgICAgcmV0dXJuIHdyYXBNYXJrcyh0aGlzLm1hcmtzLCBuYW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBjb250ZW50IG1hdGNoIGluIHRoaXMgbm9kZSBhdCB0aGUgZ2l2ZW4gaW5kZXguXG4gICAgKi9cbiAgICBjb250ZW50TWF0Y2hBdChpbmRleCkge1xuICAgICAgICBsZXQgbWF0Y2ggPSB0aGlzLnR5cGUuY29udGVudE1hdGNoLm1hdGNoRnJhZ21lbnQodGhpcy5jb250ZW50LCAwLCBpbmRleCk7XG4gICAgICAgIGlmICghbWF0Y2gpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYWxsZWQgY29udGVudE1hdGNoQXQgb24gYSBub2RlIHdpdGggaW52YWxpZCBjb250ZW50XCIpO1xuICAgICAgICByZXR1cm4gbWF0Y2g7XG4gICAgfVxuICAgIC8qKlxuICAgIFRlc3Qgd2hldGhlciByZXBsYWNpbmcgdGhlIHJhbmdlIGJldHdlZW4gYGZyb21gIGFuZCBgdG9gIChieVxuICAgIGNoaWxkIGluZGV4KSB3aXRoIHRoZSBnaXZlbiByZXBsYWNlbWVudCBmcmFnbWVudCAod2hpY2ggZGVmYXVsdHNcbiAgICB0byB0aGUgZW1wdHkgZnJhZ21lbnQpIHdvdWxkIGxlYXZlIHRoZSBub2RlJ3MgY29udGVudCB2YWxpZC4gWW91XG4gICAgY2FuIG9wdGlvbmFsbHkgcGFzcyBgc3RhcnRgIGFuZCBgZW5kYCBpbmRpY2VzIGludG8gdGhlXG4gICAgcmVwbGFjZW1lbnQgZnJhZ21lbnQuXG4gICAgKi9cbiAgICBjYW5SZXBsYWNlKGZyb20sIHRvLCByZXBsYWNlbWVudCA9IEZyYWdtZW50LmVtcHR5LCBzdGFydCA9IDAsIGVuZCA9IHJlcGxhY2VtZW50LmNoaWxkQ291bnQpIHtcbiAgICAgICAgbGV0IG9uZSA9IHRoaXMuY29udGVudE1hdGNoQXQoZnJvbSkubWF0Y2hGcmFnbWVudChyZXBsYWNlbWVudCwgc3RhcnQsIGVuZCk7XG4gICAgICAgIGxldCB0d28gPSBvbmUgJiYgb25lLm1hdGNoRnJhZ21lbnQodGhpcy5jb250ZW50LCB0byk7XG4gICAgICAgIGlmICghdHdvIHx8ICF0d28udmFsaWRFbmQpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKVxuICAgICAgICAgICAgaWYgKCF0aGlzLnR5cGUuYWxsb3dzTWFya3MocmVwbGFjZW1lbnQuY2hpbGQoaSkubWFya3MpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgIFRlc3Qgd2hldGhlciByZXBsYWNpbmcgdGhlIHJhbmdlIGBmcm9tYCB0byBgdG9gIChieSBpbmRleCkgd2l0aFxuICAgIGEgbm9kZSBvZiB0aGUgZ2l2ZW4gdHlwZSB3b3VsZCBsZWF2ZSB0aGUgbm9kZSdzIGNvbnRlbnQgdmFsaWQuXG4gICAgKi9cbiAgICBjYW5SZXBsYWNlV2l0aChmcm9tLCB0bywgdHlwZSwgbWFya3MpIHtcbiAgICAgICAgaWYgKG1hcmtzICYmICF0aGlzLnR5cGUuYWxsb3dzTWFya3MobWFya3MpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLmNvbnRlbnRNYXRjaEF0KGZyb20pLm1hdGNoVHlwZSh0eXBlKTtcbiAgICAgICAgbGV0IGVuZCA9IHN0YXJ0ICYmIHN0YXJ0Lm1hdGNoRnJhZ21lbnQodGhpcy5jb250ZW50LCB0byk7XG4gICAgICAgIHJldHVybiBlbmQgPyBlbmQudmFsaWRFbmQgOiBmYWxzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGVzdCB3aGV0aGVyIHRoZSBnaXZlbiBub2RlJ3MgY29udGVudCBjb3VsZCBiZSBhcHBlbmRlZCB0byB0aGlzXG4gICAgbm9kZS4gSWYgdGhhdCBub2RlIGlzIGVtcHR5LCB0aGlzIHdpbGwgb25seSByZXR1cm4gdHJ1ZSBpZiB0aGVyZVxuICAgIGlzIGF0IGxlYXN0IG9uZSBub2RlIHR5cGUgdGhhdCBjYW4gYXBwZWFyIGluIGJvdGggbm9kZXMgKHRvIGF2b2lkXG4gICAgbWVyZ2luZyBjb21wbGV0ZWx5IGluY29tcGF0aWJsZSBub2RlcykuXG4gICAgKi9cbiAgICBjYW5BcHBlbmQob3RoZXIpIHtcbiAgICAgICAgaWYgKG90aGVyLmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNhblJlcGxhY2UodGhpcy5jaGlsZENvdW50LCB0aGlzLmNoaWxkQ291bnQsIG90aGVyLmNvbnRlbnQpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50eXBlLmNvbXBhdGlibGVDb250ZW50KG90aGVyLnR5cGUpO1xuICAgIH1cbiAgICAvKipcbiAgICBDaGVjayB3aGV0aGVyIHRoaXMgbm9kZSBhbmQgaXRzIGRlc2NlbmRhbnRzIGNvbmZvcm0gdG8gdGhlXG4gICAgc2NoZW1hLCBhbmQgcmFpc2UgYW4gZXhjZXB0aW9uIHdoZW4gdGhleSBkbyBub3QuXG4gICAgKi9cbiAgICBjaGVjaygpIHtcbiAgICAgICAgdGhpcy50eXBlLmNoZWNrQ29udGVudCh0aGlzLmNvbnRlbnQpO1xuICAgICAgICB0aGlzLnR5cGUuY2hlY2tBdHRycyh0aGlzLmF0dHJzKTtcbiAgICAgICAgbGV0IGNvcHkgPSBNYXJrLm5vbmU7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5tYXJrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG1hcmsgPSB0aGlzLm1hcmtzW2ldO1xuICAgICAgICAgICAgbWFyay50eXBlLmNoZWNrQXR0cnMobWFyay5hdHRycyk7XG4gICAgICAgICAgICBjb3B5ID0gbWFyay5hZGRUb1NldChjb3B5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIU1hcmsuc2FtZVNldChjb3B5LCB0aGlzLm1hcmtzKSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBJbnZhbGlkIGNvbGxlY3Rpb24gb2YgbWFya3MgZm9yIG5vZGUgJHt0aGlzLnR5cGUubmFtZX06ICR7dGhpcy5tYXJrcy5tYXAobSA9PiBtLnR5cGUubmFtZSl9YCk7XG4gICAgICAgIHRoaXMuY29udGVudC5mb3JFYWNoKG5vZGUgPT4gbm9kZS5jaGVjaygpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJuIGEgSlNPTi1zZXJpYWxpemVhYmxlIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgbm9kZS5cbiAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgbGV0IG9iaiA9IHsgdHlwZTogdGhpcy50eXBlLm5hbWUgfTtcbiAgICAgICAgZm9yIChsZXQgXyBpbiB0aGlzLmF0dHJzKSB7XG4gICAgICAgICAgICBvYmouYXR0cnMgPSB0aGlzLmF0dHJzO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuY29udGVudC5zaXplKVxuICAgICAgICAgICAgb2JqLmNvbnRlbnQgPSB0aGlzLmNvbnRlbnQudG9KU09OKCk7XG4gICAgICAgIGlmICh0aGlzLm1hcmtzLmxlbmd0aClcbiAgICAgICAgICAgIG9iai5tYXJrcyA9IHRoaXMubWFya3MubWFwKG4gPT4gbi50b0pTT04oKSk7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfVxuICAgIC8qKlxuICAgIERlc2VyaWFsaXplIGEgbm9kZSBmcm9tIGl0cyBKU09OIHJlcHJlc2VudGF0aW9uLlxuICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKHNjaGVtYSwganNvbikge1xuICAgICAgICBpZiAoIWpzb24pXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIE5vZGUuZnJvbUpTT05cIik7XG4gICAgICAgIGxldCBtYXJrcyA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGpzb24ubWFya3MpIHtcbiAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShqc29uLm1hcmtzKSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgbWFyayBkYXRhIGZvciBOb2RlLmZyb21KU09OXCIpO1xuICAgICAgICAgICAgbWFya3MgPSBqc29uLm1hcmtzLm1hcChzY2hlbWEubWFya0Zyb21KU09OKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvbi50eXBlID09IFwidGV4dFwiKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGpzb24udGV4dCAhPSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCB0ZXh0IG5vZGUgaW4gSlNPTlwiKTtcbiAgICAgICAgICAgIHJldHVybiBzY2hlbWEudGV4dChqc29uLnRleHQsIG1hcmtzKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY29udGVudCA9IEZyYWdtZW50LmZyb21KU09OKHNjaGVtYSwganNvbi5jb250ZW50KTtcbiAgICAgICAgbGV0IG5vZGUgPSBzY2hlbWEubm9kZVR5cGUoanNvbi50eXBlKS5jcmVhdGUoanNvbi5hdHRycywgY29udGVudCwgbWFya3MpO1xuICAgICAgICBub2RlLnR5cGUuY2hlY2tBdHRycyhub2RlLmF0dHJzKTtcbiAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxufVxuTm9kZS5wcm90b3R5cGUudGV4dCA9IHVuZGVmaW5lZDtcbmNsYXNzIFRleHROb2RlIGV4dGVuZHMgTm9kZSB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3Rvcih0eXBlLCBhdHRycywgY29udGVudCwgbWFya3MpIHtcbiAgICAgICAgc3VwZXIodHlwZSwgYXR0cnMsIG51bGwsIG1hcmtzKTtcbiAgICAgICAgaWYgKCFjb250ZW50KVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJFbXB0eSB0ZXh0IG5vZGVzIGFyZSBub3QgYWxsb3dlZFwiKTtcbiAgICAgICAgdGhpcy50ZXh0ID0gY29udGVudDtcbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUuc3BlYy50b0RlYnVnU3RyaW5nKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHlwZS5zcGVjLnRvRGVidWdTdHJpbmcodGhpcyk7XG4gICAgICAgIHJldHVybiB3cmFwTWFya3ModGhpcy5tYXJrcywgSlNPTi5zdHJpbmdpZnkodGhpcy50ZXh0KSk7XG4gICAgfVxuICAgIGdldCB0ZXh0Q29udGVudCgpIHsgcmV0dXJuIHRoaXMudGV4dDsgfVxuICAgIHRleHRCZXR3ZWVuKGZyb20sIHRvKSB7IHJldHVybiB0aGlzLnRleHQuc2xpY2UoZnJvbSwgdG8pOyB9XG4gICAgZ2V0IG5vZGVTaXplKCkgeyByZXR1cm4gdGhpcy50ZXh0Lmxlbmd0aDsgfVxuICAgIG1hcmsobWFya3MpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtzID09IHRoaXMubWFya3MgPyB0aGlzIDogbmV3IFRleHROb2RlKHRoaXMudHlwZSwgdGhpcy5hdHRycywgdGhpcy50ZXh0LCBtYXJrcyk7XG4gICAgfVxuICAgIHdpdGhUZXh0KHRleHQpIHtcbiAgICAgICAgaWYgKHRleHQgPT0gdGhpcy50ZXh0KVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dE5vZGUodGhpcy50eXBlLCB0aGlzLmF0dHJzLCB0ZXh0LCB0aGlzLm1hcmtzKTtcbiAgICB9XG4gICAgY3V0KGZyb20gPSAwLCB0byA9IHRoaXMudGV4dC5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGZyb20gPT0gMCAmJiB0byA9PSB0aGlzLnRleHQubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIHJldHVybiB0aGlzLndpdGhUZXh0KHRoaXMudGV4dC5zbGljZShmcm9tLCB0bykpO1xuICAgIH1cbiAgICBlcShvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5zYW1lTWFya3VwKG90aGVyKSAmJiB0aGlzLnRleHQgPT0gb3RoZXIudGV4dDtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICBsZXQgYmFzZSA9IHN1cGVyLnRvSlNPTigpO1xuICAgICAgICBiYXNlLnRleHQgPSB0aGlzLnRleHQ7XG4gICAgICAgIHJldHVybiBiYXNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHdyYXBNYXJrcyhtYXJrcywgc3RyKSB7XG4gICAgZm9yIChsZXQgaSA9IG1hcmtzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKVxuICAgICAgICBzdHIgPSBtYXJrc1tpXS50eXBlLm5hbWUgKyBcIihcIiArIHN0ciArIFwiKVwiO1xuICAgIHJldHVybiBzdHI7XG59XG5cbi8qKlxuSW5zdGFuY2VzIG9mIHRoaXMgY2xhc3MgcmVwcmVzZW50IGEgbWF0Y2ggc3RhdGUgb2YgYSBub2RlIHR5cGUnc1xuW2NvbnRlbnQgZXhwcmVzc2lvbl0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmNvbnRlbnQpLCBhbmQgY2FuIGJlIHVzZWQgdG9cbmZpbmQgb3V0IHdoZXRoZXIgZnVydGhlciBjb250ZW50IG1hdGNoZXMgaGVyZSwgYW5kIHdoZXRoZXIgYSBnaXZlblxucG9zaXRpb24gaXMgYSB2YWxpZCBlbmQgb2YgdGhlIG5vZGUuXG4qL1xuY2xhc3MgQ29udGVudE1hdGNoIHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGlzIG1hdGNoIHN0YXRlIHJlcHJlc2VudHMgYSB2YWxpZCBlbmQgb2YgdGhlIG5vZGUuXG4gICAgKi9cbiAgICB2YWxpZEVuZCkge1xuICAgICAgICB0aGlzLnZhbGlkRW5kID0gdmFsaWRFbmQ7XG4gICAgICAgIC8qKlxuICAgICAgICBAaW50ZXJuYWxcbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5uZXh0ID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICBAaW50ZXJuYWxcbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy53cmFwQ2FjaGUgPSBbXTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgcGFyc2Uoc3RyaW5nLCBub2RlVHlwZXMpIHtcbiAgICAgICAgbGV0IHN0cmVhbSA9IG5ldyBUb2tlblN0cmVhbShzdHJpbmcsIG5vZGVUeXBlcyk7XG4gICAgICAgIGlmIChzdHJlYW0ubmV4dCA9PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIENvbnRlbnRNYXRjaC5lbXB0eTtcbiAgICAgICAgbGV0IGV4cHIgPSBwYXJzZUV4cHIoc3RyZWFtKTtcbiAgICAgICAgaWYgKHN0cmVhbS5uZXh0KVxuICAgICAgICAgICAgc3RyZWFtLmVycihcIlVuZXhwZWN0ZWQgdHJhaWxpbmcgdGV4dFwiKTtcbiAgICAgICAgbGV0IG1hdGNoID0gZGZhKG5mYShleHByKSk7XG4gICAgICAgIGNoZWNrRm9yRGVhZEVuZHMobWF0Y2gsIHN0cmVhbSk7XG4gICAgICAgIHJldHVybiBtYXRjaDtcbiAgICB9XG4gICAgLyoqXG4gICAgTWF0Y2ggYSBub2RlIHR5cGUsIHJldHVybmluZyBhIG1hdGNoIGFmdGVyIHRoYXQgbm9kZSBpZlxuICAgIHN1Y2Nlc3NmdWwuXG4gICAgKi9cbiAgICBtYXRjaFR5cGUodHlwZSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmV4dC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmICh0aGlzLm5leHRbaV0udHlwZSA9PSB0eXBlKVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm5leHRbaV0ubmV4dDtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIFRyeSB0byBtYXRjaCBhIGZyYWdtZW50LiBSZXR1cm5zIHRoZSByZXN1bHRpbmcgbWF0Y2ggd2hlblxuICAgIHN1Y2Nlc3NmdWwuXG4gICAgKi9cbiAgICBtYXRjaEZyYWdtZW50KGZyYWcsIHN0YXJ0ID0gMCwgZW5kID0gZnJhZy5jaGlsZENvdW50KSB7XG4gICAgICAgIGxldCBjdXIgPSB0aGlzO1xuICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGN1ciAmJiBpIDwgZW5kOyBpKyspXG4gICAgICAgICAgICBjdXIgPSBjdXIubWF0Y2hUeXBlKGZyYWcuY2hpbGQoaSkudHlwZSk7XG4gICAgICAgIHJldHVybiBjdXI7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgZ2V0IGlubGluZUNvbnRlbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5leHQubGVuZ3RoICE9IDAgJiYgdGhpcy5uZXh0WzBdLnR5cGUuaXNJbmxpbmU7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgZmlyc3QgbWF0Y2hpbmcgbm9kZSB0eXBlIGF0IHRoaXMgbWF0Y2ggcG9zaXRpb24gdGhhdCBjYW5cbiAgICBiZSBnZW5lcmF0ZWQuXG4gICAgKi9cbiAgICBnZXQgZGVmYXVsdFR5cGUoKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgeyB0eXBlIH0gPSB0aGlzLm5leHRbaV07XG4gICAgICAgICAgICBpZiAoISh0eXBlLmlzVGV4dCB8fCB0eXBlLmhhc1JlcXVpcmVkQXR0cnMoKSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29tcGF0aWJsZShvdGhlcikge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmV4dC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgb3RoZXIubmV4dC5sZW5ndGg7IGorKylcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5uZXh0W2ldLnR5cGUgPT0gb3RoZXIubmV4dFtqXS50eXBlKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvKipcbiAgICBUcnkgdG8gbWF0Y2ggdGhlIGdpdmVuIGZyYWdtZW50LCBhbmQgaWYgdGhhdCBmYWlscywgc2VlIGlmIGl0IGNhblxuICAgIGJlIG1hZGUgdG8gbWF0Y2ggYnkgaW5zZXJ0aW5nIG5vZGVzIGluIGZyb250IG9mIGl0LiBXaGVuXG4gICAgc3VjY2Vzc2Z1bCwgcmV0dXJuIGEgZnJhZ21lbnQgb2YgaW5zZXJ0ZWQgbm9kZXMgKHdoaWNoIG1heSBiZVxuICAgIGVtcHR5IGlmIG5vdGhpbmcgaGFkIHRvIGJlIGluc2VydGVkKS4gV2hlbiBgdG9FbmRgIGlzIHRydWUsIG9ubHlcbiAgICByZXR1cm4gYSBmcmFnbWVudCBpZiB0aGUgcmVzdWx0aW5nIG1hdGNoIGdvZXMgdG8gdGhlIGVuZCBvZiB0aGVcbiAgICBjb250ZW50IGV4cHJlc3Npb24uXG4gICAgKi9cbiAgICBmaWxsQmVmb3JlKGFmdGVyLCB0b0VuZCA9IGZhbHNlLCBzdGFydEluZGV4ID0gMCkge1xuICAgICAgICBsZXQgc2VlbiA9IFt0aGlzXTtcbiAgICAgICAgZnVuY3Rpb24gc2VhcmNoKG1hdGNoLCB0eXBlcykge1xuICAgICAgICAgICAgbGV0IGZpbmlzaGVkID0gbWF0Y2gubWF0Y2hGcmFnbWVudChhZnRlciwgc3RhcnRJbmRleCk7XG4gICAgICAgICAgICBpZiAoZmluaXNoZWQgJiYgKCF0b0VuZCB8fCBmaW5pc2hlZC52YWxpZEVuZCkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIEZyYWdtZW50LmZyb20odHlwZXMubWFwKHRwID0+IHRwLmNyZWF0ZUFuZEZpbGwoKSkpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXRjaC5uZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHsgdHlwZSwgbmV4dCB9ID0gbWF0Y2gubmV4dFtpXTtcbiAgICAgICAgICAgICAgICBpZiAoISh0eXBlLmlzVGV4dCB8fCB0eXBlLmhhc1JlcXVpcmVkQXR0cnMoKSkgJiYgc2Vlbi5pbmRleE9mKG5leHQpID09IC0xKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlZW4ucHVzaChuZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGZvdW5kID0gc2VhcmNoKG5leHQsIHR5cGVzLmNvbmNhdCh0eXBlKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChmb3VuZClcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmb3VuZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2VhcmNoKHRoaXMsIFtdKTtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCBhIHNldCBvZiB3cmFwcGluZyBub2RlIHR5cGVzIHRoYXQgd291bGQgYWxsb3cgYSBub2RlIG9mIHRoZVxuICAgIGdpdmVuIHR5cGUgdG8gYXBwZWFyIGF0IHRoaXMgcG9zaXRpb24uIFRoZSByZXN1bHQgbWF5IGJlIGVtcHR5XG4gICAgKHdoZW4gaXQgZml0cyBkaXJlY3RseSkgYW5kIHdpbGwgYmUgbnVsbCB3aGVuIG5vIHN1Y2ggd3JhcHBpbmdcbiAgICBleGlzdHMuXG4gICAgKi9cbiAgICBmaW5kV3JhcHBpbmcodGFyZ2V0KSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy53cmFwQ2FjaGUubGVuZ3RoOyBpICs9IDIpXG4gICAgICAgICAgICBpZiAodGhpcy53cmFwQ2FjaGVbaV0gPT0gdGFyZ2V0KVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLndyYXBDYWNoZVtpICsgMV07XG4gICAgICAgIGxldCBjb21wdXRlZCA9IHRoaXMuY29tcHV0ZVdyYXBwaW5nKHRhcmdldCk7XG4gICAgICAgIHRoaXMud3JhcENhY2hlLnB1c2godGFyZ2V0LCBjb21wdXRlZCk7XG4gICAgICAgIHJldHVybiBjb21wdXRlZDtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb21wdXRlV3JhcHBpbmcodGFyZ2V0KSB7XG4gICAgICAgIGxldCBzZWVuID0gT2JqZWN0LmNyZWF0ZShudWxsKSwgYWN0aXZlID0gW3sgbWF0Y2g6IHRoaXMsIHR5cGU6IG51bGwsIHZpYTogbnVsbCB9XTtcbiAgICAgICAgd2hpbGUgKGFjdGl2ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGxldCBjdXJyZW50ID0gYWN0aXZlLnNoaWZ0KCksIG1hdGNoID0gY3VycmVudC5tYXRjaDtcbiAgICAgICAgICAgIGlmIChtYXRjaC5tYXRjaFR5cGUodGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBvYmogPSBjdXJyZW50OyBvYmoudHlwZTsgb2JqID0gb2JqLnZpYSlcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gob2JqLnR5cGUpO1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQucmV2ZXJzZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXRjaC5uZXh0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHsgdHlwZSwgbmV4dCB9ID0gbWF0Y2gubmV4dFtpXTtcbiAgICAgICAgICAgICAgICBpZiAoIXR5cGUuaXNMZWFmICYmICF0eXBlLmhhc1JlcXVpcmVkQXR0cnMoKSAmJiAhKHR5cGUubmFtZSBpbiBzZWVuKSAmJiAoIWN1cnJlbnQudHlwZSB8fCBuZXh0LnZhbGlkRW5kKSkge1xuICAgICAgICAgICAgICAgICAgICBhY3RpdmUucHVzaCh7IG1hdGNoOiB0eXBlLmNvbnRlbnRNYXRjaCwgdHlwZSwgdmlhOiBjdXJyZW50IH0pO1xuICAgICAgICAgICAgICAgICAgICBzZWVuW3R5cGUubmFtZV0gPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIG51bWJlciBvZiBvdXRnb2luZyBlZGdlcyB0aGlzIG5vZGUgaGFzIGluIHRoZSBmaW5pdGVcbiAgICBhdXRvbWF0b24gdGhhdCBkZXNjcmliZXMgdGhlIGNvbnRlbnQgZXhwcmVzc2lvbi5cbiAgICAqL1xuICAgIGdldCBlZGdlQ291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5leHQubGVuZ3RoO1xuICAgIH1cbiAgICAvKipcbiAgICBHZXQgdGhlIF9uX+KAi3RoIG91dGdvaW5nIGVkZ2UgZnJvbSB0aGlzIG5vZGUgaW4gdGhlIGZpbml0ZVxuICAgIGF1dG9tYXRvbiB0aGF0IGRlc2NyaWJlcyB0aGUgY29udGVudCBleHByZXNzaW9uLlxuICAgICovXG4gICAgZWRnZShuKSB7XG4gICAgICAgIGlmIChuID49IHRoaXMubmV4dC5sZW5ndGgpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgVGhlcmUncyBubyAke259dGggZWRnZSBpbiB0aGlzIGNvbnRlbnQgbWF0Y2hgKTtcbiAgICAgICAgcmV0dXJuIHRoaXMubmV4dFtuXTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgbGV0IHNlZW4gPSBbXTtcbiAgICAgICAgZnVuY3Rpb24gc2NhbihtKSB7XG4gICAgICAgICAgICBzZWVuLnB1c2gobSk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG0ubmV4dC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICBpZiAoc2Vlbi5pbmRleE9mKG0ubmV4dFtpXS5uZXh0KSA9PSAtMSlcbiAgICAgICAgICAgICAgICAgICAgc2NhbihtLm5leHRbaV0ubmV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgc2Nhbih0aGlzKTtcbiAgICAgICAgcmV0dXJuIHNlZW4ubWFwKChtLCBpKSA9PiB7XG4gICAgICAgICAgICBsZXQgb3V0ID0gaSArIChtLnZhbGlkRW5kID8gXCIqXCIgOiBcIiBcIikgKyBcIiBcIjtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbS5uZXh0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIG91dCArPSAoaSA/IFwiLCBcIiA6IFwiXCIpICsgbS5uZXh0W2ldLnR5cGUubmFtZSArIFwiLT5cIiArIHNlZW4uaW5kZXhPZihtLm5leHRbaV0ubmV4dCk7XG4gICAgICAgICAgICByZXR1cm4gb3V0O1xuICAgICAgICB9KS5qb2luKFwiXFxuXCIpO1xuICAgIH1cbn1cbi8qKlxuQGludGVybmFsXG4qL1xuQ29udGVudE1hdGNoLmVtcHR5ID0gbmV3IENvbnRlbnRNYXRjaCh0cnVlKTtcbmNsYXNzIFRva2VuU3RyZWFtIHtcbiAgICBjb25zdHJ1Y3RvcihzdHJpbmcsIG5vZGVUeXBlcykge1xuICAgICAgICB0aGlzLnN0cmluZyA9IHN0cmluZztcbiAgICAgICAgdGhpcy5ub2RlVHlwZXMgPSBub2RlVHlwZXM7XG4gICAgICAgIHRoaXMuaW5saW5lID0gbnVsbDtcbiAgICAgICAgdGhpcy5wb3MgPSAwO1xuICAgICAgICB0aGlzLnRva2VucyA9IHN0cmluZy5zcGxpdCgvXFxzKig/PVxcYnxcXFd8JCkvKTtcbiAgICAgICAgaWYgKHRoaXMudG9rZW5zW3RoaXMudG9rZW5zLmxlbmd0aCAtIDFdID09IFwiXCIpXG4gICAgICAgICAgICB0aGlzLnRva2Vucy5wb3AoKTtcbiAgICAgICAgaWYgKHRoaXMudG9rZW5zWzBdID09IFwiXCIpXG4gICAgICAgICAgICB0aGlzLnRva2Vucy5zaGlmdCgpO1xuICAgIH1cbiAgICBnZXQgbmV4dCgpIHsgcmV0dXJuIHRoaXMudG9rZW5zW3RoaXMucG9zXTsgfVxuICAgIGVhdCh0b2spIHsgcmV0dXJuIHRoaXMubmV4dCA9PSB0b2sgJiYgKHRoaXMucG9zKysgfHwgdHJ1ZSk7IH1cbiAgICBlcnIoc3RyKSB7IHRocm93IG5ldyBTeW50YXhFcnJvcihzdHIgKyBcIiAoaW4gY29udGVudCBleHByZXNzaW9uICdcIiArIHRoaXMuc3RyaW5nICsgXCInKVwiKTsgfVxufVxuZnVuY3Rpb24gcGFyc2VFeHByKHN0cmVhbSkge1xuICAgIGxldCBleHBycyA9IFtdO1xuICAgIGRvIHtcbiAgICAgICAgZXhwcnMucHVzaChwYXJzZUV4cHJTZXEoc3RyZWFtKSk7XG4gICAgfSB3aGlsZSAoc3RyZWFtLmVhdChcInxcIikpO1xuICAgIHJldHVybiBleHBycy5sZW5ndGggPT0gMSA/IGV4cHJzWzBdIDogeyB0eXBlOiBcImNob2ljZVwiLCBleHBycyB9O1xufVxuZnVuY3Rpb24gcGFyc2VFeHByU2VxKHN0cmVhbSkge1xuICAgIGxldCBleHBycyA9IFtdO1xuICAgIGRvIHtcbiAgICAgICAgZXhwcnMucHVzaChwYXJzZUV4cHJTdWJzY3JpcHQoc3RyZWFtKSk7XG4gICAgfSB3aGlsZSAoc3RyZWFtLm5leHQgJiYgc3RyZWFtLm5leHQgIT0gXCIpXCIgJiYgc3RyZWFtLm5leHQgIT0gXCJ8XCIpO1xuICAgIHJldHVybiBleHBycy5sZW5ndGggPT0gMSA/IGV4cHJzWzBdIDogeyB0eXBlOiBcInNlcVwiLCBleHBycyB9O1xufVxuZnVuY3Rpb24gcGFyc2VFeHByU3Vic2NyaXB0KHN0cmVhbSkge1xuICAgIGxldCBleHByID0gcGFyc2VFeHByQXRvbShzdHJlYW0pO1xuICAgIGZvciAoOzspIHtcbiAgICAgICAgaWYgKHN0cmVhbS5lYXQoXCIrXCIpKVxuICAgICAgICAgICAgZXhwciA9IHsgdHlwZTogXCJwbHVzXCIsIGV4cHIgfTtcbiAgICAgICAgZWxzZSBpZiAoc3RyZWFtLmVhdChcIipcIikpXG4gICAgICAgICAgICBleHByID0geyB0eXBlOiBcInN0YXJcIiwgZXhwciB9O1xuICAgICAgICBlbHNlIGlmIChzdHJlYW0uZWF0KFwiP1wiKSlcbiAgICAgICAgICAgIGV4cHIgPSB7IHR5cGU6IFwib3B0XCIsIGV4cHIgfTtcbiAgICAgICAgZWxzZSBpZiAoc3RyZWFtLmVhdChcIntcIikpXG4gICAgICAgICAgICBleHByID0gcGFyc2VFeHByUmFuZ2Uoc3RyZWFtLCBleHByKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBleHByO1xufVxuZnVuY3Rpb24gcGFyc2VOdW0oc3RyZWFtKSB7XG4gICAgaWYgKC9cXEQvLnRlc3Qoc3RyZWFtLm5leHQpKVxuICAgICAgICBzdHJlYW0uZXJyKFwiRXhwZWN0ZWQgbnVtYmVyLCBnb3QgJ1wiICsgc3RyZWFtLm5leHQgKyBcIidcIik7XG4gICAgbGV0IHJlc3VsdCA9IE51bWJlcihzdHJlYW0ubmV4dCk7XG4gICAgc3RyZWFtLnBvcysrO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBwYXJzZUV4cHJSYW5nZShzdHJlYW0sIGV4cHIpIHtcbiAgICBsZXQgbWluID0gcGFyc2VOdW0oc3RyZWFtKSwgbWF4ID0gbWluO1xuICAgIGlmIChzdHJlYW0uZWF0KFwiLFwiKSkge1xuICAgICAgICBpZiAoc3RyZWFtLm5leHQgIT0gXCJ9XCIpXG4gICAgICAgICAgICBtYXggPSBwYXJzZU51bShzdHJlYW0pO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBtYXggPSAtMTtcbiAgICB9XG4gICAgaWYgKCFzdHJlYW0uZWF0KFwifVwiKSlcbiAgICAgICAgc3RyZWFtLmVycihcIlVuY2xvc2VkIGJyYWNlZCByYW5nZVwiKTtcbiAgICByZXR1cm4geyB0eXBlOiBcInJhbmdlXCIsIG1pbiwgbWF4LCBleHByIH07XG59XG5mdW5jdGlvbiByZXNvbHZlTmFtZShzdHJlYW0sIG5hbWUpIHtcbiAgICBsZXQgdHlwZXMgPSBzdHJlYW0ubm9kZVR5cGVzLCB0eXBlID0gdHlwZXNbbmFtZV07XG4gICAgaWYgKHR5cGUpXG4gICAgICAgIHJldHVybiBbdHlwZV07XG4gICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgIGZvciAobGV0IHR5cGVOYW1lIGluIHR5cGVzKSB7XG4gICAgICAgIGxldCB0eXBlID0gdHlwZXNbdHlwZU5hbWVdO1xuICAgICAgICBpZiAodHlwZS5pc0luR3JvdXAobmFtZSkpXG4gICAgICAgICAgICByZXN1bHQucHVzaCh0eXBlKTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC5sZW5ndGggPT0gMClcbiAgICAgICAgc3RyZWFtLmVycihcIk5vIG5vZGUgdHlwZSBvciBncm91cCAnXCIgKyBuYW1lICsgXCInIGZvdW5kXCIpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBwYXJzZUV4cHJBdG9tKHN0cmVhbSkge1xuICAgIGlmIChzdHJlYW0uZWF0KFwiKFwiKSkge1xuICAgICAgICBsZXQgZXhwciA9IHBhcnNlRXhwcihzdHJlYW0pO1xuICAgICAgICBpZiAoIXN0cmVhbS5lYXQoXCIpXCIpKVxuICAgICAgICAgICAgc3RyZWFtLmVycihcIk1pc3NpbmcgY2xvc2luZyBwYXJlblwiKTtcbiAgICAgICAgcmV0dXJuIGV4cHI7XG4gICAgfVxuICAgIGVsc2UgaWYgKCEvXFxXLy50ZXN0KHN0cmVhbS5uZXh0KSkge1xuICAgICAgICBsZXQgZXhwcnMgPSByZXNvbHZlTmFtZShzdHJlYW0sIHN0cmVhbS5uZXh0KS5tYXAodHlwZSA9PiB7XG4gICAgICAgICAgICBpZiAoc3RyZWFtLmlubGluZSA9PSBudWxsKVxuICAgICAgICAgICAgICAgIHN0cmVhbS5pbmxpbmUgPSB0eXBlLmlzSW5saW5lO1xuICAgICAgICAgICAgZWxzZSBpZiAoc3RyZWFtLmlubGluZSAhPSB0eXBlLmlzSW5saW5lKVxuICAgICAgICAgICAgICAgIHN0cmVhbS5lcnIoXCJNaXhpbmcgaW5saW5lIGFuZCBibG9jayBjb250ZW50XCIpO1xuICAgICAgICAgICAgcmV0dXJuIHsgdHlwZTogXCJuYW1lXCIsIHZhbHVlOiB0eXBlIH07XG4gICAgICAgIH0pO1xuICAgICAgICBzdHJlYW0ucG9zKys7XG4gICAgICAgIHJldHVybiBleHBycy5sZW5ndGggPT0gMSA/IGV4cHJzWzBdIDogeyB0eXBlOiBcImNob2ljZVwiLCBleHBycyB9O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgc3RyZWFtLmVycihcIlVuZXhwZWN0ZWQgdG9rZW4gJ1wiICsgc3RyZWFtLm5leHQgKyBcIidcIik7XG4gICAgfVxufVxuLy8gQ29uc3RydWN0IGFuIE5GQSBmcm9tIGFuIGV4cHJlc3Npb24gYXMgcmV0dXJuZWQgYnkgdGhlIHBhcnNlci4gVGhlXG4vLyBORkEgaXMgcmVwcmVzZW50ZWQgYXMgYW4gYXJyYXkgb2Ygc3RhdGVzLCB3aGljaCBhcmUgdGhlbXNlbHZlc1xuLy8gYXJyYXlzIG9mIGVkZ2VzLCB3aGljaCBhcmUgYHt0ZXJtLCB0b31gIG9iamVjdHMuIFRoZSBmaXJzdCBzdGF0ZSBpc1xuLy8gdGhlIGVudHJ5IHN0YXRlIGFuZCB0aGUgbGFzdCBub2RlIGlzIHRoZSBzdWNjZXNzIHN0YXRlLlxuLy9cbi8vIE5vdGUgdGhhdCB1bmxpa2UgdHlwaWNhbCBORkFzLCB0aGUgZWRnZSBvcmRlcmluZyBpbiB0aGlzIG9uZSBpc1xuLy8gc2lnbmlmaWNhbnQsIGluIHRoYXQgaXQgaXMgdXNlZCB0byBjb250cnVjdCBmaWxsZXIgY29udGVudCB3aGVuXG4vLyBuZWNlc3NhcnkuXG5mdW5jdGlvbiBuZmEoZXhwcikge1xuICAgIGxldCBuZmEgPSBbW11dO1xuICAgIGNvbm5lY3QoY29tcGlsZShleHByLCAwKSwgbm9kZSgpKTtcbiAgICByZXR1cm4gbmZhO1xuICAgIGZ1bmN0aW9uIG5vZGUoKSB7IHJldHVybiBuZmEucHVzaChbXSkgLSAxOyB9XG4gICAgZnVuY3Rpb24gZWRnZShmcm9tLCB0bywgdGVybSkge1xuICAgICAgICBsZXQgZWRnZSA9IHsgdGVybSwgdG8gfTtcbiAgICAgICAgbmZhW2Zyb21dLnB1c2goZWRnZSk7XG4gICAgICAgIHJldHVybiBlZGdlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjb25uZWN0KGVkZ2VzLCB0bykge1xuICAgICAgICBlZGdlcy5mb3JFYWNoKGVkZ2UgPT4gZWRnZS50byA9IHRvKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY29tcGlsZShleHByLCBmcm9tKSB7XG4gICAgICAgIGlmIChleHByLnR5cGUgPT0gXCJjaG9pY2VcIikge1xuICAgICAgICAgICAgcmV0dXJuIGV4cHIuZXhwcnMucmVkdWNlKChvdXQsIGV4cHIpID0+IG91dC5jb25jYXQoY29tcGlsZShleHByLCBmcm9tKSksIFtdKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChleHByLnR5cGUgPT0gXCJzZXFcIikge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7OyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IGNvbXBpbGUoZXhwci5leHByc1tpXSwgZnJvbSk7XG4gICAgICAgICAgICAgICAgaWYgKGkgPT0gZXhwci5leHBycy5sZW5ndGggLSAxKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV4dDtcbiAgICAgICAgICAgICAgICBjb25uZWN0KG5leHQsIGZyb20gPSBub2RlKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV4cHIudHlwZSA9PSBcInN0YXJcIikge1xuICAgICAgICAgICAgbGV0IGxvb3AgPSBub2RlKCk7XG4gICAgICAgICAgICBlZGdlKGZyb20sIGxvb3ApO1xuICAgICAgICAgICAgY29ubmVjdChjb21waWxlKGV4cHIuZXhwciwgbG9vcCksIGxvb3ApO1xuICAgICAgICAgICAgcmV0dXJuIFtlZGdlKGxvb3ApXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChleHByLnR5cGUgPT0gXCJwbHVzXCIpIHtcbiAgICAgICAgICAgIGxldCBsb29wID0gbm9kZSgpO1xuICAgICAgICAgICAgY29ubmVjdChjb21waWxlKGV4cHIuZXhwciwgZnJvbSksIGxvb3ApO1xuICAgICAgICAgICAgY29ubmVjdChjb21waWxlKGV4cHIuZXhwciwgbG9vcCksIGxvb3ApO1xuICAgICAgICAgICAgcmV0dXJuIFtlZGdlKGxvb3ApXTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChleHByLnR5cGUgPT0gXCJvcHRcIikge1xuICAgICAgICAgICAgcmV0dXJuIFtlZGdlKGZyb20pXS5jb25jYXQoY29tcGlsZShleHByLmV4cHIsIGZyb20pKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChleHByLnR5cGUgPT0gXCJyYW5nZVwiKSB7XG4gICAgICAgICAgICBsZXQgY3VyID0gZnJvbTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwci5taW47IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gbm9kZSgpO1xuICAgICAgICAgICAgICAgIGNvbm5lY3QoY29tcGlsZShleHByLmV4cHIsIGN1ciksIG5leHQpO1xuICAgICAgICAgICAgICAgIGN1ciA9IG5leHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZXhwci5tYXggPT0gLTEpIHtcbiAgICAgICAgICAgICAgICBjb25uZWN0KGNvbXBpbGUoZXhwci5leHByLCBjdXIpLCBjdXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IGV4cHIubWluOyBpIDwgZXhwci5tYXg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IG5vZGUoKTtcbiAgICAgICAgICAgICAgICAgICAgZWRnZShjdXIsIG5leHQpO1xuICAgICAgICAgICAgICAgICAgICBjb25uZWN0KGNvbXBpbGUoZXhwci5leHByLCBjdXIpLCBuZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgY3VyID0gbmV4dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gW2VkZ2UoY3VyKV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXhwci50eXBlID09IFwibmFtZVwiKSB7XG4gICAgICAgICAgICByZXR1cm4gW2VkZ2UoZnJvbSwgdW5kZWZpbmVkLCBleHByLnZhbHVlKV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIGV4cHIgdHlwZVwiKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGNtcChhLCBiKSB7IHJldHVybiBiIC0gYTsgfVxuLy8gR2V0IHRoZSBzZXQgb2Ygbm9kZXMgcmVhY2hhYmxlIGJ5IG51bGwgZWRnZXMgZnJvbSBgbm9kZWAuIE9taXRcbi8vIG5vZGVzIHdpdGggb25seSBhIHNpbmdsZSBudWxsLW91dC1lZGdlLCBzaW5jZSB0aGV5IG1heSBsZWFkIHRvXG4vLyBuZWVkbGVzcyBkdXBsaWNhdGVkIG5vZGVzLlxuZnVuY3Rpb24gbnVsbEZyb20obmZhLCBub2RlKSB7XG4gICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgIHNjYW4obm9kZSk7XG4gICAgcmV0dXJuIHJlc3VsdC5zb3J0KGNtcCk7XG4gICAgZnVuY3Rpb24gc2Nhbihub2RlKSB7XG4gICAgICAgIGxldCBlZGdlcyA9IG5mYVtub2RlXTtcbiAgICAgICAgaWYgKGVkZ2VzLmxlbmd0aCA9PSAxICYmICFlZGdlc1swXS50ZXJtKVxuICAgICAgICAgICAgcmV0dXJuIHNjYW4oZWRnZXNbMF0udG8pO1xuICAgICAgICByZXN1bHQucHVzaChub2RlKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBlZGdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHsgdGVybSwgdG8gfSA9IGVkZ2VzW2ldO1xuICAgICAgICAgICAgaWYgKCF0ZXJtICYmIHJlc3VsdC5pbmRleE9mKHRvKSA9PSAtMSlcbiAgICAgICAgICAgICAgICBzY2FuKHRvKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbi8vIENvbXBpbGVzIGFuIE5GQSBhcyBwcm9kdWNlZCBieSBgbmZhYCBpbnRvIGEgREZBLCBtb2RlbGVkIGFzIGEgc2V0XG4vLyBvZiBzdGF0ZSBvYmplY3RzIChgQ29udGVudE1hdGNoYCBpbnN0YW5jZXMpIHdpdGggdHJhbnNpdGlvbnNcbi8vIGJldHdlZW4gdGhlbS5cbmZ1bmN0aW9uIGRmYShuZmEpIHtcbiAgICBsZXQgbGFiZWxlZCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgcmV0dXJuIGV4cGxvcmUobnVsbEZyb20obmZhLCAwKSk7XG4gICAgZnVuY3Rpb24gZXhwbG9yZShzdGF0ZXMpIHtcbiAgICAgICAgbGV0IG91dCA9IFtdO1xuICAgICAgICBzdGF0ZXMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgIG5mYVtub2RlXS5mb3JFYWNoKCh7IHRlcm0sIHRvIH0pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXRlcm0pXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICBsZXQgc2V0O1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgICAgICBpZiAob3V0W2ldWzBdID09IHRlcm0pXG4gICAgICAgICAgICAgICAgICAgICAgICBzZXQgPSBvdXRbaV1bMV07XG4gICAgICAgICAgICAgICAgbnVsbEZyb20obmZhLCB0bykuZm9yRWFjaChub2RlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzZXQpXG4gICAgICAgICAgICAgICAgICAgICAgICBvdXQucHVzaChbdGVybSwgc2V0ID0gW11dKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNldC5pbmRleE9mKG5vZGUpID09IC0xKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0LnB1c2gobm9kZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGxldCBzdGF0ZSA9IGxhYmVsZWRbc3RhdGVzLmpvaW4oXCIsXCIpXSA9IG5ldyBDb250ZW50TWF0Y2goc3RhdGVzLmluZGV4T2YobmZhLmxlbmd0aCAtIDEpID4gLTEpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHN0YXRlcyA9IG91dFtpXVsxXS5zb3J0KGNtcCk7XG4gICAgICAgICAgICBzdGF0ZS5uZXh0LnB1c2goeyB0eXBlOiBvdXRbaV1bMF0sIG5leHQ6IGxhYmVsZWRbc3RhdGVzLmpvaW4oXCIsXCIpXSB8fCBleHBsb3JlKHN0YXRlcykgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN0YXRlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNoZWNrRm9yRGVhZEVuZHMobWF0Y2gsIHN0cmVhbSkge1xuICAgIGZvciAobGV0IGkgPSAwLCB3b3JrID0gW21hdGNoXTsgaSA8IHdvcmsubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IHN0YXRlID0gd29ya1tpXSwgZGVhZCA9ICFzdGF0ZS52YWxpZEVuZCwgbm9kZXMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBzdGF0ZS5uZXh0Lmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICBsZXQgeyB0eXBlLCBuZXh0IH0gPSBzdGF0ZS5uZXh0W2pdO1xuICAgICAgICAgICAgbm9kZXMucHVzaCh0eXBlLm5hbWUpO1xuICAgICAgICAgICAgaWYgKGRlYWQgJiYgISh0eXBlLmlzVGV4dCB8fCB0eXBlLmhhc1JlcXVpcmVkQXR0cnMoKSkpXG4gICAgICAgICAgICAgICAgZGVhZCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKHdvcmsuaW5kZXhPZihuZXh0KSA9PSAtMSlcbiAgICAgICAgICAgICAgICB3b3JrLnB1c2gobmV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlYWQpXG4gICAgICAgICAgICBzdHJlYW0uZXJyKFwiT25seSBub24tZ2VuZXJhdGFibGUgbm9kZXMgKFwiICsgbm9kZXMuam9pbihcIiwgXCIpICsgXCIpIGluIGEgcmVxdWlyZWQgcG9zaXRpb24gKHNlZSBodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL2d1aWRlLyNnZW5lcmF0YWJsZSlcIik7XG4gICAgfVxufVxuXG4vLyBGb3Igbm9kZSB0eXBlcyB3aGVyZSBhbGwgYXR0cnMgaGF2ZSBhIGRlZmF1bHQgdmFsdWUgKG9yIHdoaWNoIGRvbid0XG4vLyBoYXZlIGFueSBhdHRyaWJ1dGVzKSwgYnVpbGQgdXAgYSBzaW5nbGUgcmV1c2FibGUgZGVmYXVsdCBhdHRyaWJ1dGVcbi8vIG9iamVjdCwgYW5kIHVzZSBpdCBmb3IgYWxsIG5vZGVzIHRoYXQgZG9uJ3Qgc3BlY2lmeSBzcGVjaWZpY1xuLy8gYXR0cmlidXRlcy5cbmZ1bmN0aW9uIGRlZmF1bHRBdHRycyhhdHRycykge1xuICAgIGxldCBkZWZhdWx0cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgZm9yIChsZXQgYXR0ck5hbWUgaW4gYXR0cnMpIHtcbiAgICAgICAgbGV0IGF0dHIgPSBhdHRyc1thdHRyTmFtZV07XG4gICAgICAgIGlmICghYXR0ci5oYXNEZWZhdWx0KVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGRlZmF1bHRzW2F0dHJOYW1lXSA9IGF0dHIuZGVmYXVsdDtcbiAgICB9XG4gICAgcmV0dXJuIGRlZmF1bHRzO1xufVxuZnVuY3Rpb24gY29tcHV0ZUF0dHJzKGF0dHJzLCB2YWx1ZSkge1xuICAgIGxldCBidWlsdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgZm9yIChsZXQgbmFtZSBpbiBhdHRycykge1xuICAgICAgICBsZXQgZ2l2ZW4gPSB2YWx1ZSAmJiB2YWx1ZVtuYW1lXTtcbiAgICAgICAgaWYgKGdpdmVuID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxldCBhdHRyID0gYXR0cnNbbmFtZV07XG4gICAgICAgICAgICBpZiAoYXR0ci5oYXNEZWZhdWx0KVxuICAgICAgICAgICAgICAgIGdpdmVuID0gYXR0ci5kZWZhdWx0O1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTm8gdmFsdWUgc3VwcGxpZWQgZm9yIGF0dHJpYnV0ZSBcIiArIG5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGJ1aWx0W25hbWVdID0gZ2l2ZW47XG4gICAgfVxuICAgIHJldHVybiBidWlsdDtcbn1cbmZ1bmN0aW9uIGNoZWNrQXR0cnMoYXR0cnMsIHZhbHVlcywgdHlwZSwgbmFtZSkge1xuICAgIGZvciAobGV0IG5hbWUgaW4gdmFsdWVzKVxuICAgICAgICBpZiAoIShuYW1lIGluIGF0dHJzKSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBVbnN1cHBvcnRlZCBhdHRyaWJ1dGUgJHtuYW1lfSBmb3IgJHt0eXBlfSBvZiB0eXBlICR7bmFtZX1gKTtcbiAgICBmb3IgKGxldCBuYW1lIGluIGF0dHJzKSB7XG4gICAgICAgIGxldCBhdHRyID0gYXR0cnNbbmFtZV07XG4gICAgICAgIGlmIChhdHRyLnZhbGlkYXRlKVxuICAgICAgICAgICAgYXR0ci52YWxpZGF0ZSh2YWx1ZXNbbmFtZV0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGluaXRBdHRycyh0eXBlTmFtZSwgYXR0cnMpIHtcbiAgICBsZXQgcmVzdWx0ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICBpZiAoYXR0cnMpXG4gICAgICAgIGZvciAobGV0IG5hbWUgaW4gYXR0cnMpXG4gICAgICAgICAgICByZXN1bHRbbmFtZV0gPSBuZXcgQXR0cmlidXRlKHR5cGVOYW1lLCBuYW1lLCBhdHRyc1tuYW1lXSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuTm9kZSB0eXBlcyBhcmUgb2JqZWN0cyBhbGxvY2F0ZWQgb25jZSBwZXIgYFNjaGVtYWAgYW5kIHVzZWQgdG9cblt0YWddKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlLnR5cGUpIGBOb2RlYCBpbnN0YW5jZXMuIFRoZXkgY29udGFpbiBpbmZvcm1hdGlvblxuYWJvdXQgdGhlIG5vZGUgdHlwZSwgc3VjaCBhcyBpdHMgbmFtZSBhbmQgd2hhdCBraW5kIG9mIG5vZGUgaXRcbnJlcHJlc2VudHMuXG4qL1xuY2xhc3MgTm9kZVR5cGUge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIG5hbWUgdGhlIG5vZGUgdHlwZSBoYXMgaW4gdGhpcyBzY2hlbWEuXG4gICAgKi9cbiAgICBuYW1lLCBcbiAgICAvKipcbiAgICBBIGxpbmsgYmFjayB0byB0aGUgYFNjaGVtYWAgdGhlIG5vZGUgdHlwZSBiZWxvbmdzIHRvLlxuICAgICovXG4gICAgc2NoZW1hLCBcbiAgICAvKipcbiAgICBUaGUgc3BlYyB0aGF0IHRoaXMgdHlwZSBpcyBiYXNlZCBvblxuICAgICovXG4gICAgc3BlYykge1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLnNjaGVtYSA9IHNjaGVtYTtcbiAgICAgICAgdGhpcy5zcGVjID0gc3BlYztcbiAgICAgICAgLyoqXG4gICAgICAgIFRoZSBzZXQgb2YgbWFya3MgYWxsb3dlZCBpbiB0aGlzIG5vZGUuIGBudWxsYCBtZWFucyBhbGwgbWFya3NcbiAgICAgICAgYXJlIGFsbG93ZWQuXG4gICAgICAgICovXG4gICAgICAgIHRoaXMubWFya1NldCA9IG51bGw7XG4gICAgICAgIHRoaXMuZ3JvdXBzID0gc3BlYy5ncm91cCA/IHNwZWMuZ3JvdXAuc3BsaXQoXCIgXCIpIDogW107XG4gICAgICAgIHRoaXMuYXR0cnMgPSBpbml0QXR0cnMobmFtZSwgc3BlYy5hdHRycyk7XG4gICAgICAgIHRoaXMuZGVmYXVsdEF0dHJzID0gZGVmYXVsdEF0dHJzKHRoaXMuYXR0cnMpO1xuICAgICAgICB0aGlzLmNvbnRlbnRNYXRjaCA9IG51bGw7XG4gICAgICAgIHRoaXMuaW5saW5lQ29udGVudCA9IG51bGw7XG4gICAgICAgIHRoaXMuaXNCbG9jayA9ICEoc3BlYy5pbmxpbmUgfHwgbmFtZSA9PSBcInRleHRcIik7XG4gICAgICAgIHRoaXMuaXNUZXh0ID0gbmFtZSA9PSBcInRleHRcIjtcbiAgICB9XG4gICAgLyoqXG4gICAgVHJ1ZSBpZiB0aGlzIGlzIGFuIGlubGluZSB0eXBlLlxuICAgICovXG4gICAgZ2V0IGlzSW5saW5lKCkgeyByZXR1cm4gIXRoaXMuaXNCbG9jazsgfVxuICAgIC8qKlxuICAgIFRydWUgaWYgdGhpcyBpcyBhIHRleHRibG9jayB0eXBlLCBhIGJsb2NrIHRoYXQgY29udGFpbnMgaW5saW5lXG4gICAgY29udGVudC5cbiAgICAqL1xuICAgIGdldCBpc1RleHRibG9jaygpIHsgcmV0dXJuIHRoaXMuaXNCbG9jayAmJiB0aGlzLmlubGluZUNvbnRlbnQ7IH1cbiAgICAvKipcbiAgICBUcnVlIGZvciBub2RlIHR5cGVzIHRoYXQgYWxsb3cgbm8gY29udGVudC5cbiAgICAqL1xuICAgIGdldCBpc0xlYWYoKSB7IHJldHVybiB0aGlzLmNvbnRlbnRNYXRjaCA9PSBDb250ZW50TWF0Y2guZW1wdHk7IH1cbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhpcyBub2RlIGlzIGFuIGF0b20sIGkuZS4gd2hlbiBpdCBkb2VzIG5vdCBoYXZlXG4gICAgZGlyZWN0bHkgZWRpdGFibGUgY29udGVudC5cbiAgICAqL1xuICAgIGdldCBpc0F0b20oKSB7IHJldHVybiB0aGlzLmlzTGVhZiB8fCAhIXRoaXMuc3BlYy5hdG9tOyB9XG4gICAgLyoqXG4gICAgUmV0dXJuIHRydWUgd2hlbiB0aGlzIG5vZGUgdHlwZSBpcyBwYXJ0IG9mIHRoZSBnaXZlblxuICAgIFtncm91cF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmdyb3VwKS5cbiAgICAqL1xuICAgIGlzSW5Hcm91cChncm91cCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ncm91cHMuaW5kZXhPZihncm91cCkgPiAtMTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIG5vZGUgdHlwZSdzIFt3aGl0ZXNwYWNlXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMud2hpdGVzcGFjZSkgb3B0aW9uLlxuICAgICovXG4gICAgZ2V0IHdoaXRlc3BhY2UoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNwZWMud2hpdGVzcGFjZSB8fCAodGhpcy5zcGVjLmNvZGUgPyBcInByZVwiIDogXCJub3JtYWxcIik7XG4gICAgfVxuICAgIC8qKlxuICAgIFRlbGxzIHlvdSB3aGV0aGVyIHRoaXMgbm9kZSB0eXBlIGhhcyBhbnkgcmVxdWlyZWQgYXR0cmlidXRlcy5cbiAgICAqL1xuICAgIGhhc1JlcXVpcmVkQXR0cnMoKSB7XG4gICAgICAgIGZvciAobGV0IG4gaW4gdGhpcy5hdHRycylcbiAgICAgICAgICAgIGlmICh0aGlzLmF0dHJzW25dLmlzUmVxdWlyZWQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBub2RlIGFsbG93cyBzb21lIG9mIHRoZSBzYW1lIGNvbnRlbnQgYXNcbiAgICB0aGUgZ2l2ZW4gbm9kZSB0eXBlLlxuICAgICovXG4gICAgY29tcGF0aWJsZUNvbnRlbnQob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXIgfHwgdGhpcy5jb250ZW50TWF0Y2guY29tcGF0aWJsZShvdGhlci5jb250ZW50TWF0Y2gpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbXB1dGVBdHRycyhhdHRycykge1xuICAgICAgICBpZiAoIWF0dHJzICYmIHRoaXMuZGVmYXVsdEF0dHJzKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVmYXVsdEF0dHJzO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gY29tcHV0ZUF0dHJzKHRoaXMuYXR0cnMsIGF0dHJzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgYE5vZGVgIG9mIHRoaXMgdHlwZS4gVGhlIGdpdmVuIGF0dHJpYnV0ZXMgYXJlXG4gICAgY2hlY2tlZCBhbmQgZGVmYXVsdGVkICh5b3UgY2FuIHBhc3MgYG51bGxgIHRvIHVzZSB0aGUgdHlwZSdzXG4gICAgZGVmYXVsdHMgZW50aXJlbHksIGlmIG5vIHJlcXVpcmVkIGF0dHJpYnV0ZXMgZXhpc3QpLiBgY29udGVudGBcbiAgICBtYXkgYmUgYSBgRnJhZ21lbnRgLCBhIG5vZGUsIGFuIGFycmF5IG9mIG5vZGVzLCBvclxuICAgIGBudWxsYC4gU2ltaWxhcmx5IGBtYXJrc2AgbWF5IGJlIGBudWxsYCB0byBkZWZhdWx0IHRvIHRoZSBlbXB0eVxuICAgIHNldCBvZiBtYXJrcy5cbiAgICAqL1xuICAgIGNyZWF0ZShhdHRycyA9IG51bGwsIGNvbnRlbnQsIG1hcmtzKSB7XG4gICAgICAgIGlmICh0aGlzLmlzVGV4dClcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vZGVUeXBlLmNyZWF0ZSBjYW4ndCBjb25zdHJ1Y3QgdGV4dCBub2Rlc1wiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBOb2RlKHRoaXMsIHRoaXMuY29tcHV0ZUF0dHJzKGF0dHJzKSwgRnJhZ21lbnQuZnJvbShjb250ZW50KSwgTWFyay5zZXRGcm9tKG1hcmtzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIExpa2UgW2BjcmVhdGVgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVR5cGUuY3JlYXRlKSwgYnV0IGNoZWNrIHRoZSBnaXZlbiBjb250ZW50XG4gICAgYWdhaW5zdCB0aGUgbm9kZSB0eXBlJ3MgY29udGVudCByZXN0cmljdGlvbnMsIGFuZCB0aHJvdyBhbiBlcnJvclxuICAgIGlmIGl0IGRvZXNuJ3QgbWF0Y2guXG4gICAgKi9cbiAgICBjcmVhdGVDaGVja2VkKGF0dHJzID0gbnVsbCwgY29udGVudCwgbWFya3MpIHtcbiAgICAgICAgY29udGVudCA9IEZyYWdtZW50LmZyb20oY29udGVudCk7XG4gICAgICAgIHRoaXMuY2hlY2tDb250ZW50KGNvbnRlbnQpO1xuICAgICAgICByZXR1cm4gbmV3IE5vZGUodGhpcywgdGhpcy5jb21wdXRlQXR0cnMoYXR0cnMpLCBjb250ZW50LCBNYXJrLnNldEZyb20obWFya3MpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgTGlrZSBbYGNyZWF0ZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlVHlwZS5jcmVhdGUpLCBidXQgc2VlIGlmIGl0IGlzXG4gICAgbmVjZXNzYXJ5IHRvIGFkZCBub2RlcyB0byB0aGUgc3RhcnQgb3IgZW5kIG9mIHRoZSBnaXZlbiBmcmFnbWVudFxuICAgIHRvIG1ha2UgaXQgZml0IHRoZSBub2RlLiBJZiBubyBmaXR0aW5nIHdyYXBwaW5nIGNhbiBiZSBmb3VuZCxcbiAgICByZXR1cm4gbnVsbC4gTm90ZSB0aGF0LCBkdWUgdG8gdGhlIGZhY3QgdGhhdCByZXF1aXJlZCBub2RlcyBjYW5cbiAgICBhbHdheXMgYmUgY3JlYXRlZCwgdGhpcyB3aWxsIGFsd2F5cyBzdWNjZWVkIGlmIHlvdSBwYXNzIG51bGwgb3JcbiAgICBgRnJhZ21lbnQuZW1wdHlgIGFzIGNvbnRlbnQuXG4gICAgKi9cbiAgICBjcmVhdGVBbmRGaWxsKGF0dHJzID0gbnVsbCwgY29udGVudCwgbWFya3MpIHtcbiAgICAgICAgYXR0cnMgPSB0aGlzLmNvbXB1dGVBdHRycyhhdHRycyk7XG4gICAgICAgIGNvbnRlbnQgPSBGcmFnbWVudC5mcm9tKGNvbnRlbnQpO1xuICAgICAgICBpZiAoY29udGVudC5zaXplKSB7XG4gICAgICAgICAgICBsZXQgYmVmb3JlID0gdGhpcy5jb250ZW50TWF0Y2guZmlsbEJlZm9yZShjb250ZW50KTtcbiAgICAgICAgICAgIGlmICghYmVmb3JlKVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgY29udGVudCA9IGJlZm9yZS5hcHBlbmQoY29udGVudCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG1hdGNoZWQgPSB0aGlzLmNvbnRlbnRNYXRjaC5tYXRjaEZyYWdtZW50KGNvbnRlbnQpO1xuICAgICAgICBsZXQgYWZ0ZXIgPSBtYXRjaGVkICYmIG1hdGNoZWQuZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSk7XG4gICAgICAgIGlmICghYWZ0ZXIpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgcmV0dXJuIG5ldyBOb2RlKHRoaXMsIGF0dHJzLCBjb250ZW50LmFwcGVuZChhZnRlciksIE1hcmsuc2V0RnJvbShtYXJrcykpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIGZyYWdtZW50IGlzIHZhbGlkIGNvbnRlbnQgZm9yIHRoaXMgbm9kZVxuICAgIHR5cGUuXG4gICAgKi9cbiAgICB2YWxpZENvbnRlbnQoY29udGVudCkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gdGhpcy5jb250ZW50TWF0Y2gubWF0Y2hGcmFnbWVudChjb250ZW50KTtcbiAgICAgICAgaWYgKCFyZXN1bHQgfHwgIXJlc3VsdC52YWxpZEVuZClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb250ZW50LmNoaWxkQ291bnQ7IGkrKylcbiAgICAgICAgICAgIGlmICghdGhpcy5hbGxvd3NNYXJrcyhjb250ZW50LmNoaWxkKGkpLm1hcmtzKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICBUaHJvd3MgYSBSYW5nZUVycm9yIGlmIHRoZSBnaXZlbiBmcmFnbWVudCBpcyBub3QgdmFsaWQgY29udGVudCBmb3IgdGhpc1xuICAgIG5vZGUgdHlwZS5cbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNoZWNrQ29udGVudChjb250ZW50KSB7XG4gICAgICAgIGlmICghdGhpcy52YWxpZENvbnRlbnQoY29udGVudCkpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgSW52YWxpZCBjb250ZW50IGZvciBub2RlICR7dGhpcy5uYW1lfTogJHtjb250ZW50LnRvU3RyaW5nKCkuc2xpY2UoMCwgNTApfWApO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNoZWNrQXR0cnMoYXR0cnMpIHtcbiAgICAgICAgY2hlY2tBdHRycyh0aGlzLmF0dHJzLCBhdHRycywgXCJub2RlXCIsIHRoaXMubmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENoZWNrIHdoZXRoZXIgdGhlIGdpdmVuIG1hcmsgdHlwZSBpcyBhbGxvd2VkIGluIHRoaXMgbm9kZS5cbiAgICAqL1xuICAgIGFsbG93c01hcmtUeXBlKG1hcmtUeXBlKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcmtTZXQgPT0gbnVsbCB8fCB0aGlzLm1hcmtTZXQuaW5kZXhPZihtYXJrVHlwZSkgPiAtMTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGVzdCB3aGV0aGVyIHRoZSBnaXZlbiBzZXQgb2YgbWFya3MgYXJlIGFsbG93ZWQgaW4gdGhpcyBub2RlLlxuICAgICovXG4gICAgYWxsb3dzTWFya3MobWFya3MpIHtcbiAgICAgICAgaWYgKHRoaXMubWFya1NldCA9PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWFya3MubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAoIXRoaXMuYWxsb3dzTWFya1R5cGUobWFya3NbaV0udHlwZSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmVtb3ZlcyB0aGUgbWFya3MgdGhhdCBhcmUgbm90IGFsbG93ZWQgaW4gdGhpcyBub2RlIGZyb20gdGhlIGdpdmVuIHNldC5cbiAgICAqL1xuICAgIGFsbG93ZWRNYXJrcyhtYXJrcykge1xuICAgICAgICBpZiAodGhpcy5tYXJrU2V0ID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gbWFya3M7XG4gICAgICAgIGxldCBjb3B5O1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hcmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuYWxsb3dzTWFya1R5cGUobWFya3NbaV0udHlwZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWNvcHkpXG4gICAgICAgICAgICAgICAgICAgIGNvcHkgPSBtYXJrcy5zbGljZSgwLCBpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGNvcHkpIHtcbiAgICAgICAgICAgICAgICBjb3B5LnB1c2gobWFya3NbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhY29weSA/IG1hcmtzIDogY29weS5sZW5ndGggPyBjb3B5IDogTWFyay5ub25lO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBjb21waWxlKG5vZGVzLCBzY2hlbWEpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIG5vZGVzLmZvckVhY2goKG5hbWUsIHNwZWMpID0+IHJlc3VsdFtuYW1lXSA9IG5ldyBOb2RlVHlwZShuYW1lLCBzY2hlbWEsIHNwZWMpKTtcbiAgICAgICAgbGV0IHRvcFR5cGUgPSBzY2hlbWEuc3BlYy50b3BOb2RlIHx8IFwiZG9jXCI7XG4gICAgICAgIGlmICghcmVzdWx0W3RvcFR5cGVdKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJTY2hlbWEgaXMgbWlzc2luZyBpdHMgdG9wIG5vZGUgdHlwZSAoJ1wiICsgdG9wVHlwZSArIFwiJylcIik7XG4gICAgICAgIGlmICghcmVzdWx0LnRleHQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkV2ZXJ5IHNjaGVtYSBuZWVkcyBhICd0ZXh0JyB0eXBlXCIpO1xuICAgICAgICBmb3IgKGxldCBfIGluIHJlc3VsdC50ZXh0LmF0dHJzKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgdGV4dCBub2RlIHR5cGUgc2hvdWxkIG5vdCBoYXZlIGF0dHJpYnV0ZXNcIik7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxufVxuZnVuY3Rpb24gdmFsaWRhdGVUeXBlKHR5cGVOYW1lLCBhdHRyTmFtZSwgdHlwZSkge1xuICAgIGxldCB0eXBlcyA9IHR5cGUuc3BsaXQoXCJ8XCIpO1xuICAgIHJldHVybiAodmFsdWUpID0+IHtcbiAgICAgICAgbGV0IG5hbWUgPSB2YWx1ZSA9PT0gbnVsbCA/IFwibnVsbFwiIDogdHlwZW9mIHZhbHVlO1xuICAgICAgICBpZiAodHlwZXMuaW5kZXhPZihuYW1lKSA8IDApXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgRXhwZWN0ZWQgdmFsdWUgb2YgdHlwZSAke3R5cGVzfSBmb3IgYXR0cmlidXRlICR7YXR0ck5hbWV9IG9uIHR5cGUgJHt0eXBlTmFtZX0sIGdvdCAke25hbWV9YCk7XG4gICAgfTtcbn1cbi8vIEF0dHJpYnV0ZSBkZXNjcmlwdG9yc1xuY2xhc3MgQXR0cmlidXRlIHtcbiAgICBjb25zdHJ1Y3Rvcih0eXBlTmFtZSwgYXR0ck5hbWUsIG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5oYXNEZWZhdWx0ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9wdGlvbnMsIFwiZGVmYXVsdFwiKTtcbiAgICAgICAgdGhpcy5kZWZhdWx0ID0gb3B0aW9ucy5kZWZhdWx0O1xuICAgICAgICB0aGlzLnZhbGlkYXRlID0gdHlwZW9mIG9wdGlvbnMudmFsaWRhdGUgPT0gXCJzdHJpbmdcIiA/IHZhbGlkYXRlVHlwZSh0eXBlTmFtZSwgYXR0ck5hbWUsIG9wdGlvbnMudmFsaWRhdGUpIDogb3B0aW9ucy52YWxpZGF0ZTtcbiAgICB9XG4gICAgZ2V0IGlzUmVxdWlyZWQoKSB7XG4gICAgICAgIHJldHVybiAhdGhpcy5oYXNEZWZhdWx0O1xuICAgIH1cbn1cbi8vIE1hcmtzXG4vKipcbkxpa2Ugbm9kZXMsIG1hcmtzICh3aGljaCBhcmUgYXNzb2NpYXRlZCB3aXRoIG5vZGVzIHRvIHNpZ25pZnlcbnRoaW5ncyBsaWtlIGVtcGhhc2lzIG9yIGJlaW5nIHBhcnQgb2YgYSBsaW5rKSBhcmVcblt0YWdnZWRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5NYXJrLnR5cGUpIHdpdGggdHlwZSBvYmplY3RzLCB3aGljaCBhcmVcbmluc3RhbnRpYXRlZCBvbmNlIHBlciBgU2NoZW1hYC5cbiovXG5jbGFzcyBNYXJrVHlwZSB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgbmFtZSBvZiB0aGUgbWFyayB0eXBlLlxuICAgICovXG4gICAgbmFtZSwgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICByYW5rLCBcbiAgICAvKipcbiAgICBUaGUgc2NoZW1hIHRoYXQgdGhpcyBtYXJrIHR5cGUgaW5zdGFuY2UgaXMgcGFydCBvZi5cbiAgICAqL1xuICAgIHNjaGVtYSwgXG4gICAgLyoqXG4gICAgVGhlIHNwZWMgb24gd2hpY2ggdGhlIHR5cGUgaXMgYmFzZWQuXG4gICAgKi9cbiAgICBzcGVjKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMucmFuayA9IHJhbms7XG4gICAgICAgIHRoaXMuc2NoZW1hID0gc2NoZW1hO1xuICAgICAgICB0aGlzLnNwZWMgPSBzcGVjO1xuICAgICAgICB0aGlzLmF0dHJzID0gaW5pdEF0dHJzKG5hbWUsIHNwZWMuYXR0cnMpO1xuICAgICAgICB0aGlzLmV4Y2x1ZGVkID0gbnVsbDtcbiAgICAgICAgbGV0IGRlZmF1bHRzID0gZGVmYXVsdEF0dHJzKHRoaXMuYXR0cnMpO1xuICAgICAgICB0aGlzLmluc3RhbmNlID0gZGVmYXVsdHMgPyBuZXcgTWFyayh0aGlzLCBkZWZhdWx0cykgOiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBtYXJrIG9mIHRoaXMgdHlwZS4gYGF0dHJzYCBtYXkgYmUgYG51bGxgIG9yIGFuIG9iamVjdFxuICAgIGNvbnRhaW5pbmcgb25seSBzb21lIG9mIHRoZSBtYXJrJ3MgYXR0cmlidXRlcy4gVGhlIG90aGVycywgaWZcbiAgICB0aGV5IGhhdmUgZGVmYXVsdHMsIHdpbGwgYmUgYWRkZWQuXG4gICAgKi9cbiAgICBjcmVhdGUoYXR0cnMgPSBudWxsKSB7XG4gICAgICAgIGlmICghYXR0cnMgJiYgdGhpcy5pbnN0YW5jZSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmluc3RhbmNlO1xuICAgICAgICByZXR1cm4gbmV3IE1hcmsodGhpcywgY29tcHV0ZUF0dHJzKHRoaXMuYXR0cnMsIGF0dHJzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIGNvbXBpbGUobWFya3MsIHNjaGVtYSkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gT2JqZWN0LmNyZWF0ZShudWxsKSwgcmFuayA9IDA7XG4gICAgICAgIG1hcmtzLmZvckVhY2goKG5hbWUsIHNwZWMpID0+IHJlc3VsdFtuYW1lXSA9IG5ldyBNYXJrVHlwZShuYW1lLCByYW5rKyssIHNjaGVtYSwgc3BlYykpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvKipcbiAgICBXaGVuIHRoZXJlIGlzIGEgbWFyayBvZiB0aGlzIHR5cGUgaW4gdGhlIGdpdmVuIHNldCwgYSBuZXcgc2V0XG4gICAgd2l0aG91dCBpdCBpcyByZXR1cm5lZC4gT3RoZXJ3aXNlLCB0aGUgaW5wdXQgc2V0IGlzIHJldHVybmVkLlxuICAgICovXG4gICAgcmVtb3ZlRnJvbVNldChzZXQpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzZXQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAoc2V0W2ldLnR5cGUgPT0gdGhpcykge1xuICAgICAgICAgICAgICAgIHNldCA9IHNldC5zbGljZSgwLCBpKS5jb25jYXQoc2V0LnNsaWNlKGkgKyAxKSk7XG4gICAgICAgICAgICAgICAgaS0tO1xuICAgICAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2V0O1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0cyB3aGV0aGVyIHRoZXJlIGlzIGEgbWFyayBvZiB0aGlzIHR5cGUgaW4gdGhlIGdpdmVuIHNldC5cbiAgICAqL1xuICAgIGlzSW5TZXQoc2V0KSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2V0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKHNldFtpXS50eXBlID09IHRoaXMpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNldFtpXTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjaGVja0F0dHJzKGF0dHJzKSB7XG4gICAgICAgIGNoZWNrQXR0cnModGhpcy5hdHRycywgYXR0cnMsIFwibWFya1wiLCB0aGlzLm5hbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICBRdWVyaWVzIHdoZXRoZXIgYSBnaXZlbiBtYXJrIHR5cGUgaXNcbiAgICBbZXhjbHVkZWRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5NYXJrU3BlYy5leGNsdWRlcykgYnkgdGhpcyBvbmUuXG4gICAgKi9cbiAgICBleGNsdWRlcyhvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5leGNsdWRlZC5pbmRleE9mKG90aGVyKSA+IC0xO1xuICAgIH1cbn1cbi8qKlxuQSBkb2N1bWVudCBzY2hlbWEuIEhvbGRzIFtub2RlXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVR5cGUpIGFuZCBbbWFya1xudHlwZV0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk1hcmtUeXBlKSBvYmplY3RzIGZvciB0aGUgbm9kZXMgYW5kIG1hcmtzIHRoYXQgbWF5XG5vY2N1ciBpbiBjb25mb3JtaW5nIGRvY3VtZW50cywgYW5kIHByb3ZpZGVzIGZ1bmN0aW9uYWxpdHkgZm9yXG5jcmVhdGluZyBhbmQgZGVzZXJpYWxpemluZyBzdWNoIGRvY3VtZW50cy5cblxuV2hlbiBnaXZlbiwgdGhlIHR5cGUgcGFyYW1ldGVycyBwcm92aWRlIHRoZSBuYW1lcyBvZiB0aGUgbm9kZXMgYW5kXG5tYXJrcyBpbiB0aGlzIHNjaGVtYS5cbiovXG5jbGFzcyBTY2hlbWEge1xuICAgIC8qKlxuICAgIENvbnN0cnVjdCBhIHNjaGVtYSBmcm9tIGEgc2NoZW1hIFtzcGVjaWZpY2F0aW9uXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuU2NoZW1hU3BlYykuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihzcGVjKSB7XG4gICAgICAgIC8qKlxuICAgICAgICBUaGUgW2xpbmVicmVha1xuICAgICAgICByZXBsYWNlbWVudF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmxpbmVicmVha1JlcGxhY2VtZW50KSBub2RlIGRlZmluZWRcbiAgICAgICAgaW4gdGhpcyBzY2hlbWEsIGlmIGFueS5cbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5saW5lYnJlYWtSZXBsYWNlbWVudCA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICBBbiBvYmplY3QgZm9yIHN0b3Jpbmcgd2hhdGV2ZXIgdmFsdWVzIG1vZHVsZXMgbWF5IHdhbnQgdG9cbiAgICAgICAgY29tcHV0ZSBhbmQgY2FjaGUgcGVyIHNjaGVtYS4gKElmIHlvdSB3YW50IHRvIHN0b3JlIHNvbWV0aGluZ1xuICAgICAgICBpbiBpdCwgdHJ5IHRvIHVzZSBwcm9wZXJ0eSBuYW1lcyB1bmxpa2VseSB0byBjbGFzaC4pXG4gICAgICAgICovXG4gICAgICAgIHRoaXMuY2FjaGVkID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgbGV0IGluc3RhbmNlU3BlYyA9IHRoaXMuc3BlYyA9IHt9O1xuICAgICAgICBmb3IgKGxldCBwcm9wIGluIHNwZWMpXG4gICAgICAgICAgICBpbnN0YW5jZVNwZWNbcHJvcF0gPSBzcGVjW3Byb3BdO1xuICAgICAgICBpbnN0YW5jZVNwZWMubm9kZXMgPSBPcmRlcmVkTWFwLmZyb20oc3BlYy5ub2RlcyksXG4gICAgICAgICAgICBpbnN0YW5jZVNwZWMubWFya3MgPSBPcmRlcmVkTWFwLmZyb20oc3BlYy5tYXJrcyB8fCB7fSksXG4gICAgICAgICAgICB0aGlzLm5vZGVzID0gTm9kZVR5cGUuY29tcGlsZSh0aGlzLnNwZWMubm9kZXMsIHRoaXMpO1xuICAgICAgICB0aGlzLm1hcmtzID0gTWFya1R5cGUuY29tcGlsZSh0aGlzLnNwZWMubWFya3MsIHRoaXMpO1xuICAgICAgICBsZXQgY29udGVudEV4cHJDYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIGZvciAobGV0IHByb3AgaW4gdGhpcy5ub2Rlcykge1xuICAgICAgICAgICAgaWYgKHByb3AgaW4gdGhpcy5tYXJrcylcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihwcm9wICsgXCIgY2FuIG5vdCBiZSBib3RoIGEgbm9kZSBhbmQgYSBtYXJrXCIpO1xuICAgICAgICAgICAgbGV0IHR5cGUgPSB0aGlzLm5vZGVzW3Byb3BdLCBjb250ZW50RXhwciA9IHR5cGUuc3BlYy5jb250ZW50IHx8IFwiXCIsIG1hcmtFeHByID0gdHlwZS5zcGVjLm1hcmtzO1xuICAgICAgICAgICAgdHlwZS5jb250ZW50TWF0Y2ggPSBjb250ZW50RXhwckNhY2hlW2NvbnRlbnRFeHByXSB8fFxuICAgICAgICAgICAgICAgIChjb250ZW50RXhwckNhY2hlW2NvbnRlbnRFeHByXSA9IENvbnRlbnRNYXRjaC5wYXJzZShjb250ZW50RXhwciwgdGhpcy5ub2RlcykpO1xuICAgICAgICAgICAgdHlwZS5pbmxpbmVDb250ZW50ID0gdHlwZS5jb250ZW50TWF0Y2guaW5saW5lQ29udGVudDtcbiAgICAgICAgICAgIGlmICh0eXBlLnNwZWMubGluZWJyZWFrUmVwbGFjZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5saW5lYnJlYWtSZXBsYWNlbWVudClcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJNdWx0aXBsZSBsaW5lYnJlYWsgbm9kZXMgZGVmaW5lZFwiKTtcbiAgICAgICAgICAgICAgICBpZiAoIXR5cGUuaXNJbmxpbmUgfHwgIXR5cGUuaXNMZWFmKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkxpbmVicmVhayByZXBsYWNlbWVudCBub2RlcyBtdXN0IGJlIGlubGluZSBsZWFmIG5vZGVzXCIpO1xuICAgICAgICAgICAgICAgIHRoaXMubGluZWJyZWFrUmVwbGFjZW1lbnQgPSB0eXBlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdHlwZS5tYXJrU2V0ID0gbWFya0V4cHIgPT0gXCJfXCIgPyBudWxsIDpcbiAgICAgICAgICAgICAgICBtYXJrRXhwciA/IGdhdGhlck1hcmtzKHRoaXMsIG1hcmtFeHByLnNwbGl0KFwiIFwiKSkgOlxuICAgICAgICAgICAgICAgICAgICBtYXJrRXhwciA9PSBcIlwiIHx8ICF0eXBlLmlubGluZUNvbnRlbnQgPyBbXSA6IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgcHJvcCBpbiB0aGlzLm1hcmtzKSB7XG4gICAgICAgICAgICBsZXQgdHlwZSA9IHRoaXMubWFya3NbcHJvcF0sIGV4Y2wgPSB0eXBlLnNwZWMuZXhjbHVkZXM7XG4gICAgICAgICAgICB0eXBlLmV4Y2x1ZGVkID0gZXhjbCA9PSBudWxsID8gW3R5cGVdIDogZXhjbCA9PSBcIlwiID8gW10gOiBnYXRoZXJNYXJrcyh0aGlzLCBleGNsLnNwbGl0KFwiIFwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ub2RlRnJvbUpTT04gPSBqc29uID0+IE5vZGUuZnJvbUpTT04odGhpcywganNvbik7XG4gICAgICAgIHRoaXMubWFya0Zyb21KU09OID0ganNvbiA9PiBNYXJrLmZyb21KU09OKHRoaXMsIGpzb24pO1xuICAgICAgICB0aGlzLnRvcE5vZGVUeXBlID0gdGhpcy5ub2Rlc1t0aGlzLnNwZWMudG9wTm9kZSB8fCBcImRvY1wiXTtcbiAgICAgICAgdGhpcy5jYWNoZWQud3JhcHBpbmdzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbm9kZSBpbiB0aGlzIHNjaGVtYS4gVGhlIGB0eXBlYCBtYXkgYmUgYSBzdHJpbmcgb3IgYVxuICAgIGBOb2RlVHlwZWAgaW5zdGFuY2UuIEF0dHJpYnV0ZXMgd2lsbCBiZSBleHRlbmRlZCB3aXRoIGRlZmF1bHRzLFxuICAgIGBjb250ZW50YCBtYXkgYmUgYSBgRnJhZ21lbnRgLCBgbnVsbGAsIGEgYE5vZGVgLCBvciBhbiBhcnJheSBvZlxuICAgIG5vZGVzLlxuICAgICovXG4gICAgbm9kZSh0eXBlLCBhdHRycyA9IG51bGwsIGNvbnRlbnQsIG1hcmtzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdHlwZSA9PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgdHlwZSA9IHRoaXMubm9kZVR5cGUodHlwZSk7XG4gICAgICAgIGVsc2UgaWYgKCEodHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlKSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBub2RlIHR5cGU6IFwiICsgdHlwZSk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGUuc2NoZW1hICE9IHRoaXMpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIk5vZGUgdHlwZSBmcm9tIGRpZmZlcmVudCBzY2hlbWEgdXNlZCAoXCIgKyB0eXBlLm5hbWUgKyBcIilcIik7XG4gICAgICAgIHJldHVybiB0eXBlLmNyZWF0ZUNoZWNrZWQoYXR0cnMsIGNvbnRlbnQsIG1hcmtzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgdGV4dCBub2RlIGluIHRoZSBzY2hlbWEuIEVtcHR5IHRleHQgbm9kZXMgYXJlIG5vdFxuICAgIGFsbG93ZWQuXG4gICAgKi9cbiAgICB0ZXh0KHRleHQsIG1hcmtzKSB7XG4gICAgICAgIGxldCB0eXBlID0gdGhpcy5ub2Rlcy50ZXh0O1xuICAgICAgICByZXR1cm4gbmV3IFRleHROb2RlKHR5cGUsIHR5cGUuZGVmYXVsdEF0dHJzLCB0ZXh0LCBNYXJrLnNldEZyb20obWFya3MpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbWFyayB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBhdHRyaWJ1dGVzLlxuICAgICovXG4gICAgbWFyayh0eXBlLCBhdHRycykge1xuICAgICAgICBpZiAodHlwZW9mIHR5cGUgPT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgIHR5cGUgPSB0aGlzLm1hcmtzW3R5cGVdO1xuICAgICAgICByZXR1cm4gdHlwZS5jcmVhdGUoYXR0cnMpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIG5vZGVUeXBlKG5hbWUpIHtcbiAgICAgICAgbGV0IGZvdW5kID0gdGhpcy5ub2Rlc1tuYW1lXTtcbiAgICAgICAgaWYgKCFmb3VuZClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVW5rbm93biBub2RlIHR5cGU6IFwiICsgbmFtZSk7XG4gICAgICAgIHJldHVybiBmb3VuZDtcbiAgICB9XG59XG5mdW5jdGlvbiBnYXRoZXJNYXJrcyhzY2hlbWEsIG1hcmtzKSB7XG4gICAgbGV0IGZvdW5kID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgbmFtZSA9IG1hcmtzW2ldLCBtYXJrID0gc2NoZW1hLm1hcmtzW25hbWVdLCBvayA9IG1hcms7XG4gICAgICAgIGlmIChtYXJrKSB7XG4gICAgICAgICAgICBmb3VuZC5wdXNoKG1hcmspO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBzY2hlbWEubWFya3MpIHtcbiAgICAgICAgICAgICAgICBsZXQgbWFyayA9IHNjaGVtYS5tYXJrc1twcm9wXTtcbiAgICAgICAgICAgICAgICBpZiAobmFtZSA9PSBcIl9cIiB8fCAobWFyay5zcGVjLmdyb3VwICYmIG1hcmsuc3BlYy5ncm91cC5zcGxpdChcIiBcIikuaW5kZXhPZihuYW1lKSA+IC0xKSlcbiAgICAgICAgICAgICAgICAgICAgZm91bmQucHVzaChvayA9IG1hcmspO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghb2spXG4gICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJVbmtub3duIG1hcmsgdHlwZTogJ1wiICsgbWFya3NbaV0gKyBcIidcIik7XG4gICAgfVxuICAgIHJldHVybiBmb3VuZDtcbn1cblxuZnVuY3Rpb24gaXNUYWdSdWxlKHJ1bGUpIHsgcmV0dXJuIHJ1bGUudGFnICE9IG51bGw7IH1cbmZ1bmN0aW9uIGlzU3R5bGVSdWxlKHJ1bGUpIHsgcmV0dXJuIHJ1bGUuc3R5bGUgIT0gbnVsbDsgfVxuLyoqXG5BIERPTSBwYXJzZXIgcmVwcmVzZW50cyBhIHN0cmF0ZWd5IGZvciBwYXJzaW5nIERPTSBjb250ZW50IGludG8gYVxuUHJvc2VNaXJyb3IgZG9jdW1lbnQgY29uZm9ybWluZyB0byBhIGdpdmVuIHNjaGVtYS4gSXRzIGJlaGF2aW9yIGlzXG5kZWZpbmVkIGJ5IGFuIGFycmF5IG9mIFtydWxlc10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLlBhcnNlUnVsZSkuXG4qL1xuY2xhc3MgRE9NUGFyc2VyIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBwYXJzZXIgdGhhdCB0YXJnZXRzIHRoZSBnaXZlbiBzY2hlbWEsIHVzaW5nIHRoZSBnaXZlblxuICAgIHBhcnNpbmcgcnVsZXMuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgc2NoZW1hIGludG8gd2hpY2ggdGhlIHBhcnNlciBwYXJzZXMuXG4gICAgKi9cbiAgICBzY2hlbWEsIFxuICAgIC8qKlxuICAgIFRoZSBzZXQgb2YgW3BhcnNlIHJ1bGVzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuUGFyc2VSdWxlKSB0aGF0IHRoZSBwYXJzZXJcbiAgICB1c2VzLCBpbiBvcmRlciBvZiBwcmVjZWRlbmNlLlxuICAgICovXG4gICAgcnVsZXMpIHtcbiAgICAgICAgdGhpcy5zY2hlbWEgPSBzY2hlbWE7XG4gICAgICAgIHRoaXMucnVsZXMgPSBydWxlcztcbiAgICAgICAgLyoqXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLnRhZ3MgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLnN0eWxlcyA9IFtdO1xuICAgICAgICBsZXQgbWF0Y2hlZFN0eWxlcyA9IHRoaXMubWF0Y2hlZFN0eWxlcyA9IFtdO1xuICAgICAgICBydWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVGFnUnVsZShydWxlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMudGFncy5wdXNoKHJ1bGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNTdHlsZVJ1bGUocnVsZSkpIHtcbiAgICAgICAgICAgICAgICBsZXQgcHJvcCA9IC9bXj1dKi8uZXhlYyhydWxlLnN0eWxlKVswXTtcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2hlZFN0eWxlcy5pbmRleE9mKHByb3ApIDwgMClcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZFN0eWxlcy5wdXNoKHByb3ApO1xuICAgICAgICAgICAgICAgIHRoaXMuc3R5bGVzLnB1c2gocnVsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBPbmx5IG5vcm1hbGl6ZSBsaXN0IGVsZW1lbnRzIHdoZW4gbGlzdHMgaW4gdGhlIHNjaGVtYSBjYW4ndCBkaXJlY3RseSBjb250YWluIHRoZW1zZWx2ZXNcbiAgICAgICAgdGhpcy5ub3JtYWxpemVMaXN0cyA9ICF0aGlzLnRhZ3Muc29tZShyID0+IHtcbiAgICAgICAgICAgIGlmICghL14odWx8b2wpXFxiLy50ZXN0KHIudGFnKSB8fCAhci5ub2RlKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGxldCBub2RlID0gc2NoZW1hLm5vZGVzW3Iubm9kZV07XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5jb250ZW50TWF0Y2gubWF0Y2hUeXBlKG5vZGUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgUGFyc2UgYSBkb2N1bWVudCBmcm9tIHRoZSBjb250ZW50IG9mIGEgRE9NIG5vZGUuXG4gICAgKi9cbiAgICBwYXJzZShkb20sIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBsZXQgY29udGV4dCA9IG5ldyBQYXJzZUNvbnRleHQodGhpcywgb3B0aW9ucywgZmFsc2UpO1xuICAgICAgICBjb250ZXh0LmFkZEFsbChkb20sIE1hcmsubm9uZSwgb3B0aW9ucy5mcm9tLCBvcHRpb25zLnRvKTtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQuZmluaXNoKCk7XG4gICAgfVxuICAgIC8qKlxuICAgIFBhcnNlcyB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4gRE9NIG5vZGUsIGxpa2VcbiAgICBbYHBhcnNlYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLkRPTVBhcnNlci5wYXJzZSksIGFuZCB0YWtlcyB0aGUgc2FtZSBzZXQgb2ZcbiAgICBvcHRpb25zLiBCdXQgdW5saWtlIHRoYXQgbWV0aG9kLCB3aGljaCBwcm9kdWNlcyBhIHdob2xlIG5vZGUsXG4gICAgdGhpcyBvbmUgcmV0dXJucyBhIHNsaWNlIHRoYXQgaXMgb3BlbiBhdCB0aGUgc2lkZXMsIG1lYW5pbmcgdGhhdFxuICAgIHRoZSBzY2hlbWEgY29uc3RyYWludHMgYXJlbid0IGFwcGxpZWQgdG8gdGhlIHN0YXJ0IG9mIG5vZGVzIHRvXG4gICAgdGhlIGxlZnQgb2YgdGhlIGlucHV0IGFuZCB0aGUgZW5kIG9mIG5vZGVzIGF0IHRoZSBlbmQuXG4gICAgKi9cbiAgICBwYXJzZVNsaWNlKGRvbSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGxldCBjb250ZXh0ID0gbmV3IFBhcnNlQ29udGV4dCh0aGlzLCBvcHRpb25zLCB0cnVlKTtcbiAgICAgICAgY29udGV4dC5hZGRBbGwoZG9tLCBNYXJrLm5vbmUsIG9wdGlvbnMuZnJvbSwgb3B0aW9ucy50byk7XG4gICAgICAgIHJldHVybiBTbGljZS5tYXhPcGVuKGNvbnRleHQuZmluaXNoKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIG1hdGNoVGFnKGRvbSwgY29udGV4dCwgYWZ0ZXIpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IGFmdGVyID8gdGhpcy50YWdzLmluZGV4T2YoYWZ0ZXIpICsgMSA6IDA7IGkgPCB0aGlzLnRhZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBydWxlID0gdGhpcy50YWdzW2ldO1xuICAgICAgICAgICAgaWYgKG1hdGNoZXMoZG9tLCBydWxlLnRhZykgJiZcbiAgICAgICAgICAgICAgICAocnVsZS5uYW1lc3BhY2UgPT09IHVuZGVmaW5lZCB8fCBkb20ubmFtZXNwYWNlVVJJID09IHJ1bGUubmFtZXNwYWNlKSAmJlxuICAgICAgICAgICAgICAgICghcnVsZS5jb250ZXh0IHx8IGNvbnRleHQubWF0Y2hlc0NvbnRleHQocnVsZS5jb250ZXh0KSkpIHtcbiAgICAgICAgICAgICAgICBpZiAocnVsZS5nZXRBdHRycykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gcnVsZS5nZXRBdHRycyhkb20pO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09PSBmYWxzZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICBydWxlLmF0dHJzID0gcmVzdWx0IHx8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJ1bGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBtYXRjaFN0eWxlKHByb3AsIHZhbHVlLCBjb250ZXh0LCBhZnRlcikge1xuICAgICAgICBmb3IgKGxldCBpID0gYWZ0ZXIgPyB0aGlzLnN0eWxlcy5pbmRleE9mKGFmdGVyKSArIDEgOiAwOyBpIDwgdGhpcy5zdHlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBydWxlID0gdGhpcy5zdHlsZXNbaV0sIHN0eWxlID0gcnVsZS5zdHlsZTtcbiAgICAgICAgICAgIGlmIChzdHlsZS5pbmRleE9mKHByb3ApICE9IDAgfHxcbiAgICAgICAgICAgICAgICBydWxlLmNvbnRleHQgJiYgIWNvbnRleHQubWF0Y2hlc0NvbnRleHQocnVsZS5jb250ZXh0KSB8fFxuICAgICAgICAgICAgICAgIC8vIFRlc3QgdGhhdCB0aGUgc3R5bGUgc3RyaW5nIGVpdGhlciBwcmVjaXNlbHkgbWF0Y2hlcyB0aGUgcHJvcCxcbiAgICAgICAgICAgICAgICAvLyBvciBoYXMgYW4gJz0nIHNpZ24gYWZ0ZXIgdGhlIHByb3AsIGZvbGxvd2VkIGJ5IHRoZSBnaXZlblxuICAgICAgICAgICAgICAgIC8vIHZhbHVlLlxuICAgICAgICAgICAgICAgIHN0eWxlLmxlbmd0aCA+IHByb3AubGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgICAgIChzdHlsZS5jaGFyQ29kZUF0KHByb3AubGVuZ3RoKSAhPSA2MSB8fCBzdHlsZS5zbGljZShwcm9wLmxlbmd0aCArIDEpICE9IHZhbHVlKSlcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGlmIChydWxlLmdldEF0dHJzKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IHJ1bGUuZ2V0QXR0cnModmFsdWUpO1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBydWxlLmF0dHJzID0gcmVzdWx0IHx8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBydWxlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIHNjaGVtYVJ1bGVzKHNjaGVtYSkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgICAgIGZ1bmN0aW9uIGluc2VydChydWxlKSB7XG4gICAgICAgICAgICBsZXQgcHJpb3JpdHkgPSBydWxlLnByaW9yaXR5ID09IG51bGwgPyA1MCA6IHJ1bGUucHJpb3JpdHksIGkgPSAwO1xuICAgICAgICAgICAgZm9yICg7IGkgPCByZXN1bHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IHJlc3VsdFtpXSwgbmV4dFByaW9yaXR5ID0gbmV4dC5wcmlvcml0eSA9PSBudWxsID8gNTAgOiBuZXh0LnByaW9yaXR5O1xuICAgICAgICAgICAgICAgIGlmIChuZXh0UHJpb3JpdHkgPCBwcmlvcml0eSlcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN1bHQuc3BsaWNlKGksIDAsIHJ1bGUpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IG5hbWUgaW4gc2NoZW1hLm1hcmtzKSB7XG4gICAgICAgICAgICBsZXQgcnVsZXMgPSBzY2hlbWEubWFya3NbbmFtZV0uc3BlYy5wYXJzZURPTTtcbiAgICAgICAgICAgIGlmIChydWxlcylcbiAgICAgICAgICAgICAgICBydWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpbnNlcnQocnVsZSA9IGNvcHkocnVsZSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShydWxlLm1hcmsgfHwgcnVsZS5pZ25vcmUgfHwgcnVsZS5jbGVhck1hcmspKVxuICAgICAgICAgICAgICAgICAgICAgICAgcnVsZS5tYXJrID0gbmFtZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBuYW1lIGluIHNjaGVtYS5ub2Rlcykge1xuICAgICAgICAgICAgbGV0IHJ1bGVzID0gc2NoZW1hLm5vZGVzW25hbWVdLnNwZWMucGFyc2VET007XG4gICAgICAgICAgICBpZiAocnVsZXMpXG4gICAgICAgICAgICAgICAgcnVsZXMuZm9yRWFjaChydWxlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaW5zZXJ0KHJ1bGUgPSBjb3B5KHJ1bGUpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEocnVsZS5ub2RlIHx8IHJ1bGUuaWdub3JlIHx8IHJ1bGUubWFyaykpXG4gICAgICAgICAgICAgICAgICAgICAgICBydWxlLm5vZGUgPSBuYW1lO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKlxuICAgIENvbnN0cnVjdCBhIERPTSBwYXJzZXIgdXNpbmcgdGhlIHBhcnNpbmcgcnVsZXMgbGlzdGVkIGluIGFcbiAgICBzY2hlbWEncyBbbm9kZSBzcGVjc10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLnBhcnNlRE9NKSwgcmVvcmRlcmVkIGJ5XG4gICAgW3ByaW9yaXR5XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuR2VuZXJpY1BhcnNlUnVsZS5wcmlvcml0eSkuXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbVNjaGVtYShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYS5jYWNoZWQuZG9tUGFyc2VyIHx8XG4gICAgICAgICAgICAoc2NoZW1hLmNhY2hlZC5kb21QYXJzZXIgPSBuZXcgRE9NUGFyc2VyKHNjaGVtYSwgRE9NUGFyc2VyLnNjaGVtYVJ1bGVzKHNjaGVtYSkpKTtcbiAgICB9XG59XG5jb25zdCBibG9ja1RhZ3MgPSB7XG4gICAgYWRkcmVzczogdHJ1ZSwgYXJ0aWNsZTogdHJ1ZSwgYXNpZGU6IHRydWUsIGJsb2NrcXVvdGU6IHRydWUsIGNhbnZhczogdHJ1ZSxcbiAgICBkZDogdHJ1ZSwgZGl2OiB0cnVlLCBkbDogdHJ1ZSwgZmllbGRzZXQ6IHRydWUsIGZpZ2NhcHRpb246IHRydWUsIGZpZ3VyZTogdHJ1ZSxcbiAgICBmb290ZXI6IHRydWUsIGZvcm06IHRydWUsIGgxOiB0cnVlLCBoMjogdHJ1ZSwgaDM6IHRydWUsIGg0OiB0cnVlLCBoNTogdHJ1ZSxcbiAgICBoNjogdHJ1ZSwgaGVhZGVyOiB0cnVlLCBoZ3JvdXA6IHRydWUsIGhyOiB0cnVlLCBsaTogdHJ1ZSwgbm9zY3JpcHQ6IHRydWUsIG9sOiB0cnVlLFxuICAgIG91dHB1dDogdHJ1ZSwgcDogdHJ1ZSwgcHJlOiB0cnVlLCBzZWN0aW9uOiB0cnVlLCB0YWJsZTogdHJ1ZSwgdGZvb3Q6IHRydWUsIHVsOiB0cnVlXG59O1xuY29uc3QgaWdub3JlVGFncyA9IHtcbiAgICBoZWFkOiB0cnVlLCBub3NjcmlwdDogdHJ1ZSwgb2JqZWN0OiB0cnVlLCBzY3JpcHQ6IHRydWUsIHN0eWxlOiB0cnVlLCB0aXRsZTogdHJ1ZVxufTtcbmNvbnN0IGxpc3RUYWdzID0geyBvbDogdHJ1ZSwgdWw6IHRydWUgfTtcbi8vIFVzaW5nIGEgYml0ZmllbGQgZm9yIG5vZGUgY29udGV4dCBvcHRpb25zXG5jb25zdCBPUFRfUFJFU0VSVkVfV1MgPSAxLCBPUFRfUFJFU0VSVkVfV1NfRlVMTCA9IDIsIE9QVF9PUEVOX0xFRlQgPSA0O1xuZnVuY3Rpb24gd3NPcHRpb25zRm9yKHR5cGUsIHByZXNlcnZlV2hpdGVzcGFjZSwgYmFzZSkge1xuICAgIGlmIChwcmVzZXJ2ZVdoaXRlc3BhY2UgIT0gbnVsbClcbiAgICAgICAgcmV0dXJuIChwcmVzZXJ2ZVdoaXRlc3BhY2UgPyBPUFRfUFJFU0VSVkVfV1MgOiAwKSB8XG4gICAgICAgICAgICAocHJlc2VydmVXaGl0ZXNwYWNlID09PSBcImZ1bGxcIiA/IE9QVF9QUkVTRVJWRV9XU19GVUxMIDogMCk7XG4gICAgcmV0dXJuIHR5cGUgJiYgdHlwZS53aGl0ZXNwYWNlID09IFwicHJlXCIgPyBPUFRfUFJFU0VSVkVfV1MgfCBPUFRfUFJFU0VSVkVfV1NfRlVMTCA6IGJhc2UgJiB+T1BUX09QRU5fTEVGVDtcbn1cbmNsYXNzIE5vZGVDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3Rvcih0eXBlLCBhdHRycywgbWFya3MsIHNvbGlkLCBtYXRjaCwgb3B0aW9ucykge1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLmF0dHJzID0gYXR0cnM7XG4gICAgICAgIHRoaXMubWFya3MgPSBtYXJrcztcbiAgICAgICAgdGhpcy5zb2xpZCA9IHNvbGlkO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICB0aGlzLmNvbnRlbnQgPSBbXTtcbiAgICAgICAgLy8gTWFya3MgYXBwbGllZCB0byB0aGUgbm9kZSdzIGNoaWxkcmVuXG4gICAgICAgIHRoaXMuYWN0aXZlTWFya3MgPSBNYXJrLm5vbmU7XG4gICAgICAgIHRoaXMubWF0Y2ggPSBtYXRjaCB8fCAob3B0aW9ucyAmIE9QVF9PUEVOX0xFRlQgPyBudWxsIDogdHlwZS5jb250ZW50TWF0Y2gpO1xuICAgIH1cbiAgICBmaW5kV3JhcHBpbmcobm9kZSkge1xuICAgICAgICBpZiAoIXRoaXMubWF0Y2gpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy50eXBlKVxuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIGxldCBmaWxsID0gdGhpcy50eXBlLmNvbnRlbnRNYXRjaC5maWxsQmVmb3JlKEZyYWdtZW50LmZyb20obm9kZSkpO1xuICAgICAgICAgICAgaWYgKGZpbGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1hdGNoID0gdGhpcy50eXBlLmNvbnRlbnRNYXRjaC5tYXRjaEZyYWdtZW50KGZpbGwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0YXJ0ID0gdGhpcy50eXBlLmNvbnRlbnRNYXRjaCwgd3JhcDtcbiAgICAgICAgICAgICAgICBpZiAod3JhcCA9IHN0YXJ0LmZpbmRXcmFwcGluZyhub2RlLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWF0Y2ggPSBzdGFydDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdyYXA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMubWF0Y2guZmluZFdyYXBwaW5nKG5vZGUudHlwZSk7XG4gICAgfVxuICAgIGZpbmlzaChvcGVuRW5kKSB7XG4gICAgICAgIGlmICghKHRoaXMub3B0aW9ucyAmIE9QVF9QUkVTRVJWRV9XUykpIHsgLy8gU3RyaXAgdHJhaWxpbmcgd2hpdGVzcGFjZVxuICAgICAgICAgICAgbGV0IGxhc3QgPSB0aGlzLmNvbnRlbnRbdGhpcy5jb250ZW50Lmxlbmd0aCAtIDFdLCBtO1xuICAgICAgICAgICAgaWYgKGxhc3QgJiYgbGFzdC5pc1RleHQgJiYgKG0gPSAvWyBcXHRcXHJcXG5cXHUwMDBjXSskLy5leGVjKGxhc3QudGV4dCkpKSB7XG4gICAgICAgICAgICAgICAgbGV0IHRleHQgPSBsYXN0O1xuICAgICAgICAgICAgICAgIGlmIChsYXN0LnRleHQubGVuZ3RoID09IG1bMF0ubGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnQucG9wKCk7XG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRbdGhpcy5jb250ZW50Lmxlbmd0aCAtIDFdID0gdGV4dC53aXRoVGV4dCh0ZXh0LnRleHQuc2xpY2UoMCwgdGV4dC50ZXh0Lmxlbmd0aCAtIG1bMF0ubGVuZ3RoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNvbnRlbnQgPSBGcmFnbWVudC5mcm9tKHRoaXMuY29udGVudCk7XG4gICAgICAgIGlmICghb3BlbkVuZCAmJiB0aGlzLm1hdGNoKVxuICAgICAgICAgICAgY29udGVudCA9IGNvbnRlbnQuYXBwZW5kKHRoaXMubWF0Y2guZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSkpO1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID8gdGhpcy50eXBlLmNyZWF0ZSh0aGlzLmF0dHJzLCBjb250ZW50LCB0aGlzLm1hcmtzKSA6IGNvbnRlbnQ7XG4gICAgfVxuICAgIGlubGluZUNvbnRleHQobm9kZSkge1xuICAgICAgICBpZiAodGhpcy50eXBlKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHlwZS5pbmxpbmVDb250ZW50O1xuICAgICAgICBpZiAodGhpcy5jb250ZW50Lmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRlbnRbMF0uaXNJbmxpbmU7XG4gICAgICAgIHJldHVybiBub2RlLnBhcmVudE5vZGUgJiYgIWJsb2NrVGFncy5oYXNPd25Qcm9wZXJ0eShub2RlLnBhcmVudE5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSk7XG4gICAgfVxufVxuY2xhc3MgUGFyc2VDb250ZXh0IHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvLyBUaGUgcGFyc2VyIHdlIGFyZSB1c2luZy5cbiAgICBwYXJzZXIsIFxuICAgIC8vIFRoZSBvcHRpb25zIHBhc3NlZCB0byB0aGlzIHBhcnNlLlxuICAgIG9wdGlvbnMsIGlzT3Blbikge1xuICAgICAgICB0aGlzLnBhcnNlciA9IHBhcnNlcjtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgdGhpcy5pc09wZW4gPSBpc09wZW47XG4gICAgICAgIHRoaXMub3BlbiA9IDA7XG4gICAgICAgIHRoaXMubG9jYWxQcmVzZXJ2ZVdTID0gZmFsc2U7XG4gICAgICAgIGxldCB0b3BOb2RlID0gb3B0aW9ucy50b3BOb2RlLCB0b3BDb250ZXh0O1xuICAgICAgICBsZXQgdG9wT3B0aW9ucyA9IHdzT3B0aW9uc0ZvcihudWxsLCBvcHRpb25zLnByZXNlcnZlV2hpdGVzcGFjZSwgMCkgfCAoaXNPcGVuID8gT1BUX09QRU5fTEVGVCA6IDApO1xuICAgICAgICBpZiAodG9wTm9kZSlcbiAgICAgICAgICAgIHRvcENvbnRleHQgPSBuZXcgTm9kZUNvbnRleHQodG9wTm9kZS50eXBlLCB0b3BOb2RlLmF0dHJzLCBNYXJrLm5vbmUsIHRydWUsIG9wdGlvbnMudG9wTWF0Y2ggfHwgdG9wTm9kZS50eXBlLmNvbnRlbnRNYXRjaCwgdG9wT3B0aW9ucyk7XG4gICAgICAgIGVsc2UgaWYgKGlzT3BlbilcbiAgICAgICAgICAgIHRvcENvbnRleHQgPSBuZXcgTm9kZUNvbnRleHQobnVsbCwgbnVsbCwgTWFyay5ub25lLCB0cnVlLCBudWxsLCB0b3BPcHRpb25zKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdG9wQ29udGV4dCA9IG5ldyBOb2RlQ29udGV4dChwYXJzZXIuc2NoZW1hLnRvcE5vZGVUeXBlLCBudWxsLCBNYXJrLm5vbmUsIHRydWUsIG51bGwsIHRvcE9wdGlvbnMpO1xuICAgICAgICB0aGlzLm5vZGVzID0gW3RvcENvbnRleHRdO1xuICAgICAgICB0aGlzLmZpbmQgPSBvcHRpb25zLmZpbmRQb3NpdGlvbnM7XG4gICAgICAgIHRoaXMubmVlZHNCbG9jayA9IGZhbHNlO1xuICAgIH1cbiAgICBnZXQgdG9wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ub2Rlc1t0aGlzLm9wZW5dO1xuICAgIH1cbiAgICAvLyBBZGQgYSBET00gbm9kZSB0byB0aGUgY29udGVudC4gVGV4dCBpcyBpbnNlcnRlZCBhcyB0ZXh0IG5vZGUsXG4gICAgLy8gb3RoZXJ3aXNlLCB0aGUgbm9kZSBpcyBwYXNzZWQgdG8gYGFkZEVsZW1lbnRgIG9yLCBpZiBpdCBoYXMgYVxuICAgIC8vIGBzdHlsZWAgYXR0cmlidXRlLCBgYWRkRWxlbWVudFdpdGhTdHlsZXNgLlxuICAgIGFkZERPTShkb20sIG1hcmtzKSB7XG4gICAgICAgIGlmIChkb20ubm9kZVR5cGUgPT0gMylcbiAgICAgICAgICAgIHRoaXMuYWRkVGV4dE5vZGUoZG9tLCBtYXJrcyk7XG4gICAgICAgIGVsc2UgaWYgKGRvbS5ub2RlVHlwZSA9PSAxKVxuICAgICAgICAgICAgdGhpcy5hZGRFbGVtZW50KGRvbSwgbWFya3MpO1xuICAgIH1cbiAgICBhZGRUZXh0Tm9kZShkb20sIG1hcmtzKSB7XG4gICAgICAgIGxldCB2YWx1ZSA9IGRvbS5ub2RlVmFsdWU7XG4gICAgICAgIGxldCB0b3AgPSB0aGlzLnRvcCwgcHJlc2VydmVXUyA9ICh0b3Aub3B0aW9ucyAmIE9QVF9QUkVTRVJWRV9XU19GVUxMKSA/IFwiZnVsbFwiXG4gICAgICAgICAgICA6IHRoaXMubG9jYWxQcmVzZXJ2ZVdTIHx8ICh0b3Aub3B0aW9ucyAmIE9QVF9QUkVTRVJWRV9XUykgPiAwO1xuICAgICAgICBsZXQgeyBzY2hlbWEgfSA9IHRoaXMucGFyc2VyO1xuICAgICAgICBpZiAocHJlc2VydmVXUyA9PT0gXCJmdWxsXCIgfHxcbiAgICAgICAgICAgIHRvcC5pbmxpbmVDb250ZXh0KGRvbSkgfHxcbiAgICAgICAgICAgIC9bXiBcXHRcXHJcXG5cXHUwMDBjXS8udGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIGlmICghcHJlc2VydmVXUykge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvWyBcXHRcXHJcXG5cXHUwMDBjXSsvZywgXCIgXCIpO1xuICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgc3RhcnRzIHdpdGggd2hpdGVzcGFjZSwgYW5kIHRoZXJlIGlzIG5vIG5vZGUgYmVmb3JlIGl0LCBvclxuICAgICAgICAgICAgICAgIC8vIGEgaGFyZCBicmVhaywgb3IgYSB0ZXh0IG5vZGUgdGhhdCBlbmRzIHdpdGggd2hpdGVzcGFjZSwgc3RyaXAgdGhlXG4gICAgICAgICAgICAgICAgLy8gbGVhZGluZyBzcGFjZS5cbiAgICAgICAgICAgICAgICBpZiAoL15bIFxcdFxcclxcblxcdTAwMGNdLy50ZXN0KHZhbHVlKSAmJiB0aGlzLm9wZW4gPT0gdGhpcy5ub2Rlcy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBub2RlQmVmb3JlID0gdG9wLmNvbnRlbnRbdG9wLmNvbnRlbnQubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIGxldCBkb21Ob2RlQmVmb3JlID0gZG9tLnByZXZpb3VzU2libGluZztcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFub2RlQmVmb3JlIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAoZG9tTm9kZUJlZm9yZSAmJiBkb21Ob2RlQmVmb3JlLm5vZGVOYW1lID09ICdCUicpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAobm9kZUJlZm9yZS5pc1RleHQgJiYgL1sgXFx0XFxyXFxuXFx1MDAwY10kLy50ZXN0KG5vZGVCZWZvcmUudGV4dCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5zbGljZSgxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChwcmVzZXJ2ZVdTID09PSBcImZ1bGxcIikge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXFxyXFxuPy9nLCBcIlxcblwiKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHNjaGVtYS5saW5lYnJlYWtSZXBsYWNlbWVudCAmJiAvW1xcclxcbl0vLnRlc3QodmFsdWUpICYmIHRoaXMudG9wLmZpbmRXcmFwcGluZyhzY2hlbWEubGluZWJyZWFrUmVwbGFjZW1lbnQuY3JlYXRlKCkpKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxpbmVzID0gdmFsdWUuc3BsaXQoL1xccj9cXG58XFxyLyk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Tm9kZShzY2hlbWEubGluZWJyZWFrUmVwbGFjZW1lbnQuY3JlYXRlKCksIG1hcmtzLCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxpbmVzW2ldKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnNlcnROb2RlKHNjaGVtYS50ZXh0KGxpbmVzW2ldKSwgbWFya3MsICEvXFxTLy50ZXN0KGxpbmVzW2ldKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhbHVlID0gXCJcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXFxyP1xcbnxcXHIvZywgXCIgXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZhbHVlKVxuICAgICAgICAgICAgICAgIHRoaXMuaW5zZXJ0Tm9kZShzY2hlbWEudGV4dCh2YWx1ZSksIG1hcmtzLCAhL1xcUy8udGVzdCh2YWx1ZSkpO1xuICAgICAgICAgICAgdGhpcy5maW5kSW5UZXh0KGRvbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmZpbmRJbnNpZGUoZG9tKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBUcnkgdG8gZmluZCBhIGhhbmRsZXIgZm9yIHRoZSBnaXZlbiB0YWcgYW5kIHVzZSB0aGF0IHRvIHBhcnNlLiBJZlxuICAgIC8vIG5vbmUgaXMgZm91bmQsIHRoZSBlbGVtZW50J3MgY29udGVudCBub2RlcyBhcmUgYWRkZWQgZGlyZWN0bHkuXG4gICAgYWRkRWxlbWVudChkb20sIG1hcmtzLCBtYXRjaEFmdGVyKSB7XG4gICAgICAgIGxldCBvdXRlcldTID0gdGhpcy5sb2NhbFByZXNlcnZlV1MsIHRvcCA9IHRoaXMudG9wO1xuICAgICAgICBpZiAoZG9tLnRhZ05hbWUgPT0gXCJQUkVcIiB8fCAvcHJlLy50ZXN0KGRvbS5zdHlsZSAmJiBkb20uc3R5bGUud2hpdGVTcGFjZSkpXG4gICAgICAgICAgICB0aGlzLmxvY2FsUHJlc2VydmVXUyA9IHRydWU7XG4gICAgICAgIGxldCBuYW1lID0gZG9tLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCksIHJ1bGVJRDtcbiAgICAgICAgaWYgKGxpc3RUYWdzLmhhc093blByb3BlcnR5KG5hbWUpICYmIHRoaXMucGFyc2VyLm5vcm1hbGl6ZUxpc3RzKVxuICAgICAgICAgICAgbm9ybWFsaXplTGlzdChkb20pO1xuICAgICAgICBsZXQgcnVsZSA9ICh0aGlzLm9wdGlvbnMucnVsZUZyb21Ob2RlICYmIHRoaXMub3B0aW9ucy5ydWxlRnJvbU5vZGUoZG9tKSkgfHxcbiAgICAgICAgICAgIChydWxlSUQgPSB0aGlzLnBhcnNlci5tYXRjaFRhZyhkb20sIHRoaXMsIG1hdGNoQWZ0ZXIpKTtcbiAgICAgICAgb3V0OiBpZiAocnVsZSA/IHJ1bGUuaWdub3JlIDogaWdub3JlVGFncy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICAgICAgdGhpcy5maW5kSW5zaWRlKGRvbSk7XG4gICAgICAgICAgICB0aGlzLmlnbm9yZUZhbGxiYWNrKGRvbSwgbWFya3MpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFydWxlIHx8IHJ1bGUuc2tpcCB8fCBydWxlLmNsb3NlUGFyZW50KSB7XG4gICAgICAgICAgICBpZiAocnVsZSAmJiBydWxlLmNsb3NlUGFyZW50KVxuICAgICAgICAgICAgICAgIHRoaXMub3BlbiA9IE1hdGgubWF4KDAsIHRoaXMub3BlbiAtIDEpO1xuICAgICAgICAgICAgZWxzZSBpZiAocnVsZSAmJiBydWxlLnNraXAubm9kZVR5cGUpXG4gICAgICAgICAgICAgICAgZG9tID0gcnVsZS5za2lwO1xuICAgICAgICAgICAgbGV0IHN5bmMsIG9sZE5lZWRzQmxvY2sgPSB0aGlzLm5lZWRzQmxvY2s7XG4gICAgICAgICAgICBpZiAoYmxvY2tUYWdzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRvcC5jb250ZW50Lmxlbmd0aCAmJiB0b3AuY29udGVudFswXS5pc0lubGluZSAmJiB0aGlzLm9wZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vcGVuLS07XG4gICAgICAgICAgICAgICAgICAgIHRvcCA9IHRoaXMudG9wO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBzeW5jID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAoIXRvcC50eXBlKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLm5lZWRzQmxvY2sgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIWRvbS5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWFmRmFsbGJhY2soZG9tLCBtYXJrcyk7XG4gICAgICAgICAgICAgICAgYnJlYWsgb3V0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGlubmVyTWFya3MgPSBydWxlICYmIHJ1bGUuc2tpcCA/IG1hcmtzIDogdGhpcy5yZWFkU3R5bGVzKGRvbSwgbWFya3MpO1xuICAgICAgICAgICAgaWYgKGlubmVyTWFya3MpXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRBbGwoZG9tLCBpbm5lck1hcmtzKTtcbiAgICAgICAgICAgIGlmIChzeW5jKVxuICAgICAgICAgICAgICAgIHRoaXMuc3luYyh0b3ApO1xuICAgICAgICAgICAgdGhpcy5uZWVkc0Jsb2NrID0gb2xkTmVlZHNCbG9jaztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBpbm5lck1hcmtzID0gdGhpcy5yZWFkU3R5bGVzKGRvbSwgbWFya3MpO1xuICAgICAgICAgICAgaWYgKGlubmVyTWFya3MpXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRFbGVtZW50QnlSdWxlKGRvbSwgcnVsZSwgaW5uZXJNYXJrcywgcnVsZS5jb25zdW1pbmcgPT09IGZhbHNlID8gcnVsZUlEIDogdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvY2FsUHJlc2VydmVXUyA9IG91dGVyV1M7XG4gICAgfVxuICAgIC8vIENhbGxlZCBmb3IgbGVhZiBET00gbm9kZXMgdGhhdCB3b3VsZCBvdGhlcndpc2UgYmUgaWdub3JlZFxuICAgIGxlYWZGYWxsYmFjayhkb20sIG1hcmtzKSB7XG4gICAgICAgIGlmIChkb20ubm9kZU5hbWUgPT0gXCJCUlwiICYmIHRoaXMudG9wLnR5cGUgJiYgdGhpcy50b3AudHlwZS5pbmxpbmVDb250ZW50KVxuICAgICAgICAgICAgdGhpcy5hZGRUZXh0Tm9kZShkb20ub3duZXJEb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcIlxcblwiKSwgbWFya3MpO1xuICAgIH1cbiAgICAvLyBDYWxsZWQgZm9yIGlnbm9yZWQgbm9kZXNcbiAgICBpZ25vcmVGYWxsYmFjayhkb20sIG1hcmtzKSB7XG4gICAgICAgIC8vIElnbm9yZWQgQlIgbm9kZXMgc2hvdWxkIGF0IGxlYXN0IGNyZWF0ZSBhbiBpbmxpbmUgY29udGV4dFxuICAgICAgICBpZiAoZG9tLm5vZGVOYW1lID09IFwiQlJcIiAmJiAoIXRoaXMudG9wLnR5cGUgfHwgIXRoaXMudG9wLnR5cGUuaW5saW5lQ29udGVudCkpXG4gICAgICAgICAgICB0aGlzLmZpbmRQbGFjZSh0aGlzLnBhcnNlci5zY2hlbWEudGV4dChcIi1cIiksIG1hcmtzLCB0cnVlKTtcbiAgICB9XG4gICAgLy8gUnVuIGFueSBzdHlsZSBwYXJzZXIgYXNzb2NpYXRlZCB3aXRoIHRoZSBub2RlJ3Mgc3R5bGVzLiBFaXRoZXJcbiAgICAvLyByZXR1cm4gYW4gdXBkYXRlZCBhcnJheSBvZiBtYXJrcywgb3IgbnVsbCB0byBpbmRpY2F0ZSBzb21lIG9mIHRoZVxuICAgIC8vIHN0eWxlcyBoYWQgYSBydWxlIHdpdGggYGlnbm9yZWAgc2V0LlxuICAgIHJlYWRTdHlsZXMoZG9tLCBtYXJrcykge1xuICAgICAgICBsZXQgc3R5bGVzID0gZG9tLnN0eWxlO1xuICAgICAgICAvLyBCZWNhdXNlIG1hbnkgcHJvcGVydGllcyB3aWxsIG9ubHkgc2hvdyB1cCBpbiAnbm9ybWFsaXplZCcgZm9ybVxuICAgICAgICAvLyBpbiBgc3R5bGUuaXRlbWAgKGkuZS4gdGV4dC1kZWNvcmF0aW9uIGJlY29tZXNcbiAgICAgICAgLy8gdGV4dC1kZWNvcmF0aW9uLWxpbmUsIHRleHQtZGVjb3JhdGlvbi1jb2xvciwgZXRjKSwgd2UgZGlyZWN0bHlcbiAgICAgICAgLy8gcXVlcnkgdGhlIHN0eWxlcyBtZW50aW9uZWQgaW4gb3VyIHJ1bGVzIGluc3RlYWQgb2YgaXRlcmF0aW5nXG4gICAgICAgIC8vIG92ZXIgdGhlIGl0ZW1zLlxuICAgICAgICBpZiAoc3R5bGVzICYmIHN0eWxlcy5sZW5ndGgpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGFyc2VyLm1hdGNoZWRTdHlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgbmFtZSA9IHRoaXMucGFyc2VyLm1hdGNoZWRTdHlsZXNbaV0sIHZhbHVlID0gc3R5bGVzLmdldFByb3BlcnR5VmFsdWUobmFtZSk7XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlKVxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBhZnRlciA9IHVuZGVmaW5lZDs7KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcnVsZSA9IHRoaXMucGFyc2VyLm1hdGNoU3R5bGUobmFtZSwgdmFsdWUsIHRoaXMsIGFmdGVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghcnVsZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChydWxlLmlnbm9yZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChydWxlLmNsZWFyTWFyaylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJrcyA9IG1hcmtzLmZpbHRlcihtID0+ICFydWxlLmNsZWFyTWFyayhtKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFya3MgPSBtYXJrcy5jb25jYXQodGhpcy5wYXJzZXIuc2NoZW1hLm1hcmtzW3J1bGUubWFya10uY3JlYXRlKHJ1bGUuYXR0cnMpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChydWxlLmNvbnN1bWluZyA9PT0gZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWZ0ZXIgPSBydWxlO1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIHJldHVybiBtYXJrcztcbiAgICB9XG4gICAgLy8gTG9vayB1cCBhIGhhbmRsZXIgZm9yIHRoZSBnaXZlbiBub2RlLiBJZiBub25lIGFyZSBmb3VuZCwgcmV0dXJuXG4gICAgLy8gZmFsc2UuIE90aGVyd2lzZSwgYXBwbHkgaXQsIHVzZSBpdHMgcmV0dXJuIHZhbHVlIHRvIGRyaXZlIHRoZSB3YXlcbiAgICAvLyB0aGUgbm9kZSdzIGNvbnRlbnQgaXMgd3JhcHBlZCwgYW5kIHJldHVybiB0cnVlLlxuICAgIGFkZEVsZW1lbnRCeVJ1bGUoZG9tLCBydWxlLCBtYXJrcywgY29udGludWVBZnRlcikge1xuICAgICAgICBsZXQgc3luYywgbm9kZVR5cGU7XG4gICAgICAgIGlmIChydWxlLm5vZGUpIHtcbiAgICAgICAgICAgIG5vZGVUeXBlID0gdGhpcy5wYXJzZXIuc2NoZW1hLm5vZGVzW3J1bGUubm9kZV07XG4gICAgICAgICAgICBpZiAoIW5vZGVUeXBlLmlzTGVhZikge1xuICAgICAgICAgICAgICAgIGxldCBpbm5lciA9IHRoaXMuZW50ZXIobm9kZVR5cGUsIHJ1bGUuYXR0cnMgfHwgbnVsbCwgbWFya3MsIHJ1bGUucHJlc2VydmVXaGl0ZXNwYWNlKTtcbiAgICAgICAgICAgICAgICBpZiAoaW5uZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgc3luYyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIG1hcmtzID0gaW5uZXI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIXRoaXMuaW5zZXJ0Tm9kZShub2RlVHlwZS5jcmVhdGUocnVsZS5hdHRycyksIG1hcmtzLCBkb20ubm9kZU5hbWUgPT0gXCJCUlwiKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubGVhZkZhbGxiYWNrKGRvbSwgbWFya3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IG1hcmtUeXBlID0gdGhpcy5wYXJzZXIuc2NoZW1hLm1hcmtzW3J1bGUubWFya107XG4gICAgICAgICAgICBtYXJrcyA9IG1hcmtzLmNvbmNhdChtYXJrVHlwZS5jcmVhdGUocnVsZS5hdHRycykpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBzdGFydEluID0gdGhpcy50b3A7XG4gICAgICAgIGlmIChub2RlVHlwZSAmJiBub2RlVHlwZS5pc0xlYWYpIHtcbiAgICAgICAgICAgIHRoaXMuZmluZEluc2lkZShkb20pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGNvbnRpbnVlQWZ0ZXIpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkRWxlbWVudChkb20sIG1hcmtzLCBjb250aW51ZUFmdGVyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChydWxlLmdldENvbnRlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuZmluZEluc2lkZShkb20pO1xuICAgICAgICAgICAgcnVsZS5nZXRDb250ZW50KGRvbSwgdGhpcy5wYXJzZXIuc2NoZW1hKS5mb3JFYWNoKG5vZGUgPT4gdGhpcy5pbnNlcnROb2RlKG5vZGUsIG1hcmtzLCBmYWxzZSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IGNvbnRlbnRET00gPSBkb207XG4gICAgICAgICAgICBpZiAodHlwZW9mIHJ1bGUuY29udGVudEVsZW1lbnQgPT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICBjb250ZW50RE9NID0gZG9tLnF1ZXJ5U2VsZWN0b3IocnVsZS5jb250ZW50RWxlbWVudCk7XG4gICAgICAgICAgICBlbHNlIGlmICh0eXBlb2YgcnVsZS5jb250ZW50RWxlbWVudCA9PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgICAgICAgICAgY29udGVudERPTSA9IHJ1bGUuY29udGVudEVsZW1lbnQoZG9tKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHJ1bGUuY29udGVudEVsZW1lbnQpXG4gICAgICAgICAgICAgICAgY29udGVudERPTSA9IHJ1bGUuY29udGVudEVsZW1lbnQ7XG4gICAgICAgICAgICB0aGlzLmZpbmRBcm91bmQoZG9tLCBjb250ZW50RE9NLCB0cnVlKTtcbiAgICAgICAgICAgIHRoaXMuYWRkQWxsKGNvbnRlbnRET00sIG1hcmtzKTtcbiAgICAgICAgICAgIHRoaXMuZmluZEFyb3VuZChkb20sIGNvbnRlbnRET00sIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3luYyAmJiB0aGlzLnN5bmMoc3RhcnRJbikpXG4gICAgICAgICAgICB0aGlzLm9wZW4tLTtcbiAgICB9XG4gICAgLy8gQWRkIGFsbCBjaGlsZCBub2RlcyBiZXR3ZWVuIGBzdGFydEluZGV4YCBhbmQgYGVuZEluZGV4YCAob3IgdGhlXG4gICAgLy8gd2hvbGUgbm9kZSwgaWYgbm90IGdpdmVuKS4gSWYgYHN5bmNgIGlzIHBhc3NlZCwgdXNlIGl0IHRvXG4gICAgLy8gc3luY2hyb25pemUgYWZ0ZXIgZXZlcnkgYmxvY2sgZWxlbWVudC5cbiAgICBhZGRBbGwocGFyZW50LCBtYXJrcywgc3RhcnRJbmRleCwgZW5kSW5kZXgpIHtcbiAgICAgICAgbGV0IGluZGV4ID0gc3RhcnRJbmRleCB8fCAwO1xuICAgICAgICBmb3IgKGxldCBkb20gPSBzdGFydEluZGV4ID8gcGFyZW50LmNoaWxkTm9kZXNbc3RhcnRJbmRleF0gOiBwYXJlbnQuZmlyc3RDaGlsZCwgZW5kID0gZW5kSW5kZXggPT0gbnVsbCA/IG51bGwgOiBwYXJlbnQuY2hpbGROb2Rlc1tlbmRJbmRleF07IGRvbSAhPSBlbmQ7IGRvbSA9IGRvbS5uZXh0U2libGluZywgKytpbmRleCkge1xuICAgICAgICAgICAgdGhpcy5maW5kQXRQb2ludChwYXJlbnQsIGluZGV4KTtcbiAgICAgICAgICAgIHRoaXMuYWRkRE9NKGRvbSwgbWFya3MpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmluZEF0UG9pbnQocGFyZW50LCBpbmRleCk7XG4gICAgfVxuICAgIC8vIFRyeSB0byBmaW5kIGEgd2F5IHRvIGZpdCB0aGUgZ2l2ZW4gbm9kZSB0eXBlIGludG8gdGhlIGN1cnJlbnRcbiAgICAvLyBjb250ZXh0LiBNYXkgYWRkIGludGVybWVkaWF0ZSB3cmFwcGVycyBhbmQvb3IgbGVhdmUgbm9uLXNvbGlkXG4gICAgLy8gbm9kZXMgdGhhdCB3ZSdyZSBpbi5cbiAgICBmaW5kUGxhY2Uobm9kZSwgbWFya3MsIGNhdXRpb3VzKSB7XG4gICAgICAgIGxldCByb3V0ZSwgc3luYztcbiAgICAgICAgZm9yIChsZXQgZGVwdGggPSB0aGlzLm9wZW4sIHBlbmFsdHkgPSAwOyBkZXB0aCA+PSAwOyBkZXB0aC0tKSB7XG4gICAgICAgICAgICBsZXQgY3ggPSB0aGlzLm5vZGVzW2RlcHRoXTtcbiAgICAgICAgICAgIGxldCBmb3VuZCA9IGN4LmZpbmRXcmFwcGluZyhub2RlKTtcbiAgICAgICAgICAgIGlmIChmb3VuZCAmJiAoIXJvdXRlIHx8IHJvdXRlLmxlbmd0aCA+IGZvdW5kLmxlbmd0aCArIHBlbmFsdHkpKSB7XG4gICAgICAgICAgICAgICAgcm91dGUgPSBmb3VuZDtcbiAgICAgICAgICAgICAgICBzeW5jID0gY3g7XG4gICAgICAgICAgICAgICAgaWYgKCFmb3VuZC5sZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGN4LnNvbGlkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNhdXRpb3VzKVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBwZW5hbHR5ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyb3V0ZSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB0aGlzLnN5bmMoc3luYyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm91dGUubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBtYXJrcyA9IHRoaXMuZW50ZXJJbm5lcihyb3V0ZVtpXSwgbnVsbCwgbWFya3MsIGZhbHNlKTtcbiAgICAgICAgcmV0dXJuIG1hcmtzO1xuICAgIH1cbiAgICAvLyBUcnkgdG8gaW5zZXJ0IHRoZSBnaXZlbiBub2RlLCBhZGp1c3RpbmcgdGhlIGNvbnRleHQgd2hlbiBuZWVkZWQuXG4gICAgaW5zZXJ0Tm9kZShub2RlLCBtYXJrcywgY2F1dGlvdXMpIHtcbiAgICAgICAgaWYgKG5vZGUuaXNJbmxpbmUgJiYgdGhpcy5uZWVkc0Jsb2NrICYmICF0aGlzLnRvcC50eXBlKSB7XG4gICAgICAgICAgICBsZXQgYmxvY2sgPSB0aGlzLnRleHRibG9ja0Zyb21Db250ZXh0KCk7XG4gICAgICAgICAgICBpZiAoYmxvY2spXG4gICAgICAgICAgICAgICAgbWFya3MgPSB0aGlzLmVudGVySW5uZXIoYmxvY2ssIG51bGwsIG1hcmtzKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgaW5uZXJNYXJrcyA9IHRoaXMuZmluZFBsYWNlKG5vZGUsIG1hcmtzLCBjYXV0aW91cyk7XG4gICAgICAgIGlmIChpbm5lck1hcmtzKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlRXh0cmEoKTtcbiAgICAgICAgICAgIGxldCB0b3AgPSB0aGlzLnRvcDtcbiAgICAgICAgICAgIGlmICh0b3AubWF0Y2gpXG4gICAgICAgICAgICAgICAgdG9wLm1hdGNoID0gdG9wLm1hdGNoLm1hdGNoVHlwZShub2RlLnR5cGUpO1xuICAgICAgICAgICAgbGV0IG5vZGVNYXJrcyA9IE1hcmsubm9uZTtcbiAgICAgICAgICAgIGZvciAobGV0IG0gb2YgaW5uZXJNYXJrcy5jb25jYXQobm9kZS5tYXJrcykpXG4gICAgICAgICAgICAgICAgaWYgKHRvcC50eXBlID8gdG9wLnR5cGUuYWxsb3dzTWFya1R5cGUobS50eXBlKSA6IG1hcmtNYXlBcHBseShtLnR5cGUsIG5vZGUudHlwZSkpXG4gICAgICAgICAgICAgICAgICAgIG5vZGVNYXJrcyA9IG0uYWRkVG9TZXQobm9kZU1hcmtzKTtcbiAgICAgICAgICAgIHRvcC5jb250ZW50LnB1c2gobm9kZS5tYXJrKG5vZGVNYXJrcykpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBUcnkgdG8gc3RhcnQgYSBub2RlIG9mIHRoZSBnaXZlbiB0eXBlLCBhZGp1c3RpbmcgdGhlIGNvbnRleHQgd2hlblxuICAgIC8vIG5lY2Vzc2FyeS5cbiAgICBlbnRlcih0eXBlLCBhdHRycywgbWFya3MsIHByZXNlcnZlV1MpIHtcbiAgICAgICAgbGV0IGlubmVyTWFya3MgPSB0aGlzLmZpbmRQbGFjZSh0eXBlLmNyZWF0ZShhdHRycyksIG1hcmtzLCBmYWxzZSk7XG4gICAgICAgIGlmIChpbm5lck1hcmtzKVxuICAgICAgICAgICAgaW5uZXJNYXJrcyA9IHRoaXMuZW50ZXJJbm5lcih0eXBlLCBhdHRycywgbWFya3MsIHRydWUsIHByZXNlcnZlV1MpO1xuICAgICAgICByZXR1cm4gaW5uZXJNYXJrcztcbiAgICB9XG4gICAgLy8gT3BlbiBhIG5vZGUgb2YgdGhlIGdpdmVuIHR5cGVcbiAgICBlbnRlcklubmVyKHR5cGUsIGF0dHJzLCBtYXJrcywgc29saWQgPSBmYWxzZSwgcHJlc2VydmVXUykge1xuICAgICAgICB0aGlzLmNsb3NlRXh0cmEoKTtcbiAgICAgICAgbGV0IHRvcCA9IHRoaXMudG9wO1xuICAgICAgICB0b3AubWF0Y2ggPSB0b3AubWF0Y2ggJiYgdG9wLm1hdGNoLm1hdGNoVHlwZSh0eXBlKTtcbiAgICAgICAgbGV0IG9wdGlvbnMgPSB3c09wdGlvbnNGb3IodHlwZSwgcHJlc2VydmVXUywgdG9wLm9wdGlvbnMpO1xuICAgICAgICBpZiAoKHRvcC5vcHRpb25zICYgT1BUX09QRU5fTEVGVCkgJiYgdG9wLmNvbnRlbnQubGVuZ3RoID09IDApXG4gICAgICAgICAgICBvcHRpb25zIHw9IE9QVF9PUEVOX0xFRlQ7XG4gICAgICAgIGxldCBhcHBseU1hcmtzID0gTWFyay5ub25lO1xuICAgICAgICBtYXJrcyA9IG1hcmtzLmZpbHRlcihtID0+IHtcbiAgICAgICAgICAgIGlmICh0b3AudHlwZSA/IHRvcC50eXBlLmFsbG93c01hcmtUeXBlKG0udHlwZSkgOiBtYXJrTWF5QXBwbHkobS50eXBlLCB0eXBlKSkge1xuICAgICAgICAgICAgICAgIGFwcGx5TWFya3MgPSBtLmFkZFRvU2V0KGFwcGx5TWFya3MpO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5ub2Rlcy5wdXNoKG5ldyBOb2RlQ29udGV4dCh0eXBlLCBhdHRycywgYXBwbHlNYXJrcywgc29saWQsIG51bGwsIG9wdGlvbnMpKTtcbiAgICAgICAgdGhpcy5vcGVuKys7XG4gICAgICAgIHJldHVybiBtYXJrcztcbiAgICB9XG4gICAgLy8gTWFrZSBzdXJlIGFsbCBub2RlcyBhYm92ZSB0aGlzLm9wZW4gYXJlIGZpbmlzaGVkIGFuZCBhZGRlZCB0b1xuICAgIC8vIHRoZWlyIHBhcmVudHNcbiAgICBjbG9zZUV4dHJhKG9wZW5FbmQgPSBmYWxzZSkge1xuICAgICAgICBsZXQgaSA9IHRoaXMubm9kZXMubGVuZ3RoIC0gMTtcbiAgICAgICAgaWYgKGkgPiB0aGlzLm9wZW4pIHtcbiAgICAgICAgICAgIGZvciAoOyBpID4gdGhpcy5vcGVuOyBpLS0pXG4gICAgICAgICAgICAgICAgdGhpcy5ub2Rlc1tpIC0gMV0uY29udGVudC5wdXNoKHRoaXMubm9kZXNbaV0uZmluaXNoKG9wZW5FbmQpKTtcbiAgICAgICAgICAgIHRoaXMubm9kZXMubGVuZ3RoID0gdGhpcy5vcGVuICsgMTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmaW5pc2goKSB7XG4gICAgICAgIHRoaXMub3BlbiA9IDA7XG4gICAgICAgIHRoaXMuY2xvc2VFeHRyYSh0aGlzLmlzT3Blbik7XG4gICAgICAgIHJldHVybiB0aGlzLm5vZGVzWzBdLmZpbmlzaCghISh0aGlzLmlzT3BlbiB8fCB0aGlzLm9wdGlvbnMudG9wT3BlbikpO1xuICAgIH1cbiAgICBzeW5jKHRvKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLm9wZW47IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5ub2Rlc1tpXSA9PSB0bykge1xuICAgICAgICAgICAgICAgIHRoaXMub3BlbiA9IGk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLmxvY2FsUHJlc2VydmVXUykge1xuICAgICAgICAgICAgICAgIHRoaXMubm9kZXNbaV0ub3B0aW9ucyB8PSBPUFRfUFJFU0VSVkVfV1M7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBnZXQgY3VycmVudFBvcygpIHtcbiAgICAgICAgdGhpcy5jbG9zZUV4dHJhKCk7XG4gICAgICAgIGxldCBwb3MgPSAwO1xuICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5vcGVuOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgbGV0IGNvbnRlbnQgPSB0aGlzLm5vZGVzW2ldLmNvbnRlbnQ7XG4gICAgICAgICAgICBmb3IgKGxldCBqID0gY29udGVudC5sZW5ndGggLSAxOyBqID49IDA7IGotLSlcbiAgICAgICAgICAgICAgICBwb3MgKz0gY29udGVudFtqXS5ub2RlU2l6ZTtcbiAgICAgICAgICAgIGlmIChpKVxuICAgICAgICAgICAgICAgIHBvcysrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgfVxuICAgIGZpbmRBdFBvaW50KHBhcmVudCwgb2Zmc2V0KSB7XG4gICAgICAgIGlmICh0aGlzLmZpbmQpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZmluZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmZpbmRbaV0ubm9kZSA9PSBwYXJlbnQgJiYgdGhpcy5maW5kW2ldLm9mZnNldCA9PSBvZmZzZXQpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmluZFtpXS5wb3MgPSB0aGlzLmN1cnJlbnRQb3M7XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIGZpbmRJbnNpZGUocGFyZW50KSB7XG4gICAgICAgIGlmICh0aGlzLmZpbmQpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZmluZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmZpbmRbaV0ucG9zID09IG51bGwgJiYgcGFyZW50Lm5vZGVUeXBlID09IDEgJiYgcGFyZW50LmNvbnRhaW5zKHRoaXMuZmluZFtpXS5ub2RlKSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maW5kW2ldLnBvcyA9IHRoaXMuY3VycmVudFBvcztcbiAgICAgICAgICAgIH1cbiAgICB9XG4gICAgZmluZEFyb3VuZChwYXJlbnQsIGNvbnRlbnQsIGJlZm9yZSkge1xuICAgICAgICBpZiAocGFyZW50ICE9IGNvbnRlbnQgJiYgdGhpcy5maW5kKVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmZpbmQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5maW5kW2ldLnBvcyA9PSBudWxsICYmIHBhcmVudC5ub2RlVHlwZSA9PSAxICYmIHBhcmVudC5jb250YWlucyh0aGlzLmZpbmRbaV0ubm9kZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHBvcyA9IGNvbnRlbnQuY29tcGFyZURvY3VtZW50UG9zaXRpb24odGhpcy5maW5kW2ldLm5vZGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocG9zICYgKGJlZm9yZSA/IDIgOiA0KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZmluZFtpXS5wb3MgPSB0aGlzLmN1cnJlbnRQb3M7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgIH1cbiAgICBmaW5kSW5UZXh0KHRleHROb2RlKSB7XG4gICAgICAgIGlmICh0aGlzLmZpbmQpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZmluZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmZpbmRbaV0ubm9kZSA9PSB0ZXh0Tm9kZSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maW5kW2ldLnBvcyA9IHRoaXMuY3VycmVudFBvcyAtICh0ZXh0Tm9kZS5ub2RlVmFsdWUubGVuZ3RoIC0gdGhpcy5maW5kW2ldLm9mZnNldCk7XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIC8vIERldGVybWluZXMgd2hldGhlciB0aGUgZ2l2ZW4gY29udGV4dCBzdHJpbmcgbWF0Y2hlcyB0aGlzIGNvbnRleHQuXG4gICAgbWF0Y2hlc0NvbnRleHQoY29udGV4dCkge1xuICAgICAgICBpZiAoY29udGV4dC5pbmRleE9mKFwifFwiKSA+IC0xKVxuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQuc3BsaXQoL1xccypcXHxcXHMqLykuc29tZSh0aGlzLm1hdGNoZXNDb250ZXh0LCB0aGlzKTtcbiAgICAgICAgbGV0IHBhcnRzID0gY29udGV4dC5zcGxpdChcIi9cIik7XG4gICAgICAgIGxldCBvcHRpb24gPSB0aGlzLm9wdGlvbnMuY29udGV4dDtcbiAgICAgICAgbGV0IHVzZVJvb3QgPSAhdGhpcy5pc09wZW4gJiYgKCFvcHRpb24gfHwgb3B0aW9uLnBhcmVudC50eXBlID09IHRoaXMubm9kZXNbMF0udHlwZSk7XG4gICAgICAgIGxldCBtaW5EZXB0aCA9IC0ob3B0aW9uID8gb3B0aW9uLmRlcHRoICsgMSA6IDApICsgKHVzZVJvb3QgPyAwIDogMSk7XG4gICAgICAgIGxldCBtYXRjaCA9IChpLCBkZXB0aCkgPT4ge1xuICAgICAgICAgICAgZm9yICg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBhcnQgPSBwYXJ0c1tpXTtcbiAgICAgICAgICAgICAgICBpZiAocGFydCA9PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpID09IHBhcnRzLmxlbmd0aCAtIDEgfHwgaSA9PSAwKVxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBkZXB0aCA+PSBtaW5EZXB0aDsgZGVwdGgtLSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXRjaChpIC0gMSwgZGVwdGgpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IGRlcHRoID4gMCB8fCAoZGVwdGggPT0gMCAmJiB1c2VSb290KSA/IHRoaXMubm9kZXNbZGVwdGhdLnR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgIDogb3B0aW9uICYmIGRlcHRoID49IG1pbkRlcHRoID8gb3B0aW9uLm5vZGUoZGVwdGggLSBtaW5EZXB0aCkudHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuZXh0IHx8IChuZXh0Lm5hbWUgIT0gcGFydCAmJiAhbmV4dC5pc0luR3JvdXAocGFydCkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBkZXB0aC0tO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbWF0Y2gocGFydHMubGVuZ3RoIC0gMSwgdGhpcy5vcGVuKTtcbiAgICB9XG4gICAgdGV4dGJsb2NrRnJvbUNvbnRleHQoKSB7XG4gICAgICAgIGxldCAkY29udGV4dCA9IHRoaXMub3B0aW9ucy5jb250ZXh0O1xuICAgICAgICBpZiAoJGNvbnRleHQpXG4gICAgICAgICAgICBmb3IgKGxldCBkID0gJGNvbnRleHQuZGVwdGg7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgICAgICAgICAgbGV0IGRlZmx0ID0gJGNvbnRleHQubm9kZShkKS5jb250ZW50TWF0Y2hBdCgkY29udGV4dC5pbmRleEFmdGVyKGQpKS5kZWZhdWx0VHlwZTtcbiAgICAgICAgICAgICAgICBpZiAoZGVmbHQgJiYgZGVmbHQuaXNUZXh0YmxvY2sgJiYgZGVmbHQuZGVmYXVsdEF0dHJzKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVmbHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IG5hbWUgaW4gdGhpcy5wYXJzZXIuc2NoZW1hLm5vZGVzKSB7XG4gICAgICAgICAgICBsZXQgdHlwZSA9IHRoaXMucGFyc2VyLnNjaGVtYS5ub2Rlc1tuYW1lXTtcbiAgICAgICAgICAgIGlmICh0eXBlLmlzVGV4dGJsb2NrICYmIHR5cGUuZGVmYXVsdEF0dHJzKVxuICAgICAgICAgICAgICAgIHJldHVybiB0eXBlO1xuICAgICAgICB9XG4gICAgfVxufVxuLy8gS2x1ZGdlIHRvIHdvcmsgYXJvdW5kIGRpcmVjdGx5IG5lc3RlZCBsaXN0IG5vZGVzIHByb2R1Y2VkIGJ5IHNvbWVcbi8vIHRvb2xzIGFuZCBhbGxvd2VkIGJ5IGJyb3dzZXJzIHRvIG1lYW4gdGhhdCB0aGUgbmVzdGVkIGxpc3QgaXNcbi8vIGFjdHVhbGx5IHBhcnQgb2YgdGhlIGxpc3QgaXRlbSBhYm92ZSBpdC5cbmZ1bmN0aW9uIG5vcm1hbGl6ZUxpc3QoZG9tKSB7XG4gICAgZm9yIChsZXQgY2hpbGQgPSBkb20uZmlyc3RDaGlsZCwgcHJldkl0ZW0gPSBudWxsOyBjaGlsZDsgY2hpbGQgPSBjaGlsZC5uZXh0U2libGluZykge1xuICAgICAgICBsZXQgbmFtZSA9IGNoaWxkLm5vZGVUeXBlID09IDEgPyBjaGlsZC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIDogbnVsbDtcbiAgICAgICAgaWYgKG5hbWUgJiYgbGlzdFRhZ3MuaGFzT3duUHJvcGVydHkobmFtZSkgJiYgcHJldkl0ZW0pIHtcbiAgICAgICAgICAgIHByZXZJdGVtLmFwcGVuZENoaWxkKGNoaWxkKTtcbiAgICAgICAgICAgIGNoaWxkID0gcHJldkl0ZW07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobmFtZSA9PSBcImxpXCIpIHtcbiAgICAgICAgICAgIHByZXZJdGVtID0gY2hpbGQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobmFtZSkge1xuICAgICAgICAgICAgcHJldkl0ZW0gPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxufVxuLy8gQXBwbHkgYSBDU1Mgc2VsZWN0b3IuXG5mdW5jdGlvbiBtYXRjaGVzKGRvbSwgc2VsZWN0b3IpIHtcbiAgICByZXR1cm4gKGRvbS5tYXRjaGVzIHx8IGRvbS5tc01hdGNoZXNTZWxlY3RvciB8fCBkb20ud2Via2l0TWF0Y2hlc1NlbGVjdG9yIHx8IGRvbS5tb3pNYXRjaGVzU2VsZWN0b3IpLmNhbGwoZG9tLCBzZWxlY3Rvcik7XG59XG5mdW5jdGlvbiBjb3B5KG9iaikge1xuICAgIGxldCBjb3B5ID0ge307XG4gICAgZm9yIChsZXQgcHJvcCBpbiBvYmopXG4gICAgICAgIGNvcHlbcHJvcF0gPSBvYmpbcHJvcF07XG4gICAgcmV0dXJuIGNvcHk7XG59XG4vLyBVc2VkIHdoZW4gZmluZGluZyBhIG1hcmsgYXQgdGhlIHRvcCBsZXZlbCBvZiBhIGZyYWdtZW50IHBhcnNlLlxuLy8gQ2hlY2tzIHdoZXRoZXIgaXQgd291bGQgYmUgcmVhc29uYWJsZSB0byBhcHBseSBhIGdpdmVuIG1hcmsgdHlwZSB0b1xuLy8gYSBnaXZlbiBub2RlLCBieSBsb29raW5nIGF0IHRoZSB3YXkgdGhlIG1hcmsgb2NjdXJzIGluIHRoZSBzY2hlbWEuXG5mdW5jdGlvbiBtYXJrTWF5QXBwbHkobWFya1R5cGUsIG5vZGVUeXBlKSB7XG4gICAgbGV0IG5vZGVzID0gbm9kZVR5cGUuc2NoZW1hLm5vZGVzO1xuICAgIGZvciAobGV0IG5hbWUgaW4gbm9kZXMpIHtcbiAgICAgICAgbGV0IHBhcmVudCA9IG5vZGVzW25hbWVdO1xuICAgICAgICBpZiAoIXBhcmVudC5hbGxvd3NNYXJrVHlwZShtYXJrVHlwZSkpXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgbGV0IHNlZW4gPSBbXSwgc2NhbiA9IChtYXRjaCkgPT4ge1xuICAgICAgICAgICAgc2Vlbi5wdXNoKG1hdGNoKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF0Y2guZWRnZUNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgeyB0eXBlLCBuZXh0IH0gPSBtYXRjaC5lZGdlKGkpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlID09IG5vZGVUeXBlKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICBpZiAoc2Vlbi5pbmRleE9mKG5leHQpIDwgMCAmJiBzY2FuKG5leHQpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHNjYW4ocGFyZW50LmNvbnRlbnRNYXRjaCkpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5cbi8qKlxuQSBET00gc2VyaWFsaXplciBrbm93cyBob3cgdG8gY29udmVydCBQcm9zZU1pcnJvciBub2RlcyBhbmRcbm1hcmtzIG9mIHZhcmlvdXMgdHlwZXMgdG8gRE9NIG5vZGVzLlxuKi9cbmNsYXNzIERPTVNlcmlhbGl6ZXIge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIHNlcmlhbGl6ZXIuIGBub2Rlc2Agc2hvdWxkIG1hcCBub2RlIG5hbWVzIHRvIGZ1bmN0aW9uc1xuICAgIHRoYXQgdGFrZSBhIG5vZGUgYW5kIHJldHVybiBhIGRlc2NyaXB0aW9uIG9mIHRoZSBjb3JyZXNwb25kaW5nXG4gICAgRE9NLiBgbWFya3NgIGRvZXMgdGhlIHNhbWUgZm9yIG1hcmsgbmFtZXMsIGJ1dCBhbHNvIGdldHMgYW5cbiAgICBhcmd1bWVudCB0aGF0IHRlbGxzIGl0IHdoZXRoZXIgdGhlIG1hcmsncyBjb250ZW50IGlzIGJsb2NrIG9yXG4gICAgaW5saW5lIGNvbnRlbnQgKGZvciB0eXBpY2FsIHVzZSwgaXQnbGwgYWx3YXlzIGJlIGlubGluZSkuIEEgbWFya1xuICAgIHNlcmlhbGl6ZXIgbWF5IGJlIGBudWxsYCB0byBpbmRpY2F0ZSB0aGF0IG1hcmtzIG9mIHRoYXQgdHlwZVxuICAgIHNob3VsZCBub3QgYmUgc2VyaWFsaXplZC5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBub2RlIHNlcmlhbGl6YXRpb24gZnVuY3Rpb25zLlxuICAgICovXG4gICAgbm9kZXMsIFxuICAgIC8qKlxuICAgIFRoZSBtYXJrIHNlcmlhbGl6YXRpb24gZnVuY3Rpb25zLlxuICAgICovXG4gICAgbWFya3MpIHtcbiAgICAgICAgdGhpcy5ub2RlcyA9IG5vZGVzO1xuICAgICAgICB0aGlzLm1hcmtzID0gbWFya3M7XG4gICAgfVxuICAgIC8qKlxuICAgIFNlcmlhbGl6ZSB0aGUgY29udGVudCBvZiB0aGlzIGZyYWdtZW50IHRvIGEgRE9NIGZyYWdtZW50LiBXaGVuXG4gICAgbm90IGluIHRoZSBicm93c2VyLCB0aGUgYGRvY3VtZW50YCBvcHRpb24sIGNvbnRhaW5pbmcgYSBET01cbiAgICBkb2N1bWVudCwgc2hvdWxkIGJlIHBhc3NlZCBzbyB0aGF0IHRoZSBzZXJpYWxpemVyIGNhbiBjcmVhdGVcbiAgICBub2Rlcy5cbiAgICAqL1xuICAgIHNlcmlhbGl6ZUZyYWdtZW50KGZyYWdtZW50LCBvcHRpb25zID0ge30sIHRhcmdldCkge1xuICAgICAgICBpZiAoIXRhcmdldClcbiAgICAgICAgICAgIHRhcmdldCA9IGRvYyhvcHRpb25zKS5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gICAgICAgIGxldCB0b3AgPSB0YXJnZXQsIGFjdGl2ZSA9IFtdO1xuICAgICAgICBmcmFnbWVudC5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgICAgICAgaWYgKGFjdGl2ZS5sZW5ndGggfHwgbm9kZS5tYXJrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBsZXQga2VlcCA9IDAsIHJlbmRlcmVkID0gMDtcbiAgICAgICAgICAgICAgICB3aGlsZSAoa2VlcCA8IGFjdGl2ZS5sZW5ndGggJiYgcmVuZGVyZWQgPCBub2RlLm1hcmtzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IG5vZGUubWFya3NbcmVuZGVyZWRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMubWFya3NbbmV4dC50eXBlLm5hbWVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZW5kZXJlZCsrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKCFuZXh0LmVxKGFjdGl2ZVtrZWVwXVswXSkgfHwgbmV4dC50eXBlLnNwZWMuc3Bhbm5pbmcgPT09IGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIGtlZXArKztcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyZWQrKztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgd2hpbGUgKGtlZXAgPCBhY3RpdmUubGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICB0b3AgPSBhY3RpdmUucG9wKClbMV07XG4gICAgICAgICAgICAgICAgd2hpbGUgKHJlbmRlcmVkIDwgbm9kZS5tYXJrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGFkZCA9IG5vZGUubWFya3NbcmVuZGVyZWQrK107XG4gICAgICAgICAgICAgICAgICAgIGxldCBtYXJrRE9NID0gdGhpcy5zZXJpYWxpemVNYXJrKGFkZCwgbm9kZS5pc0lubGluZSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChtYXJrRE9NKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmUucHVzaChbYWRkLCB0b3BdKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcC5hcHBlbmRDaGlsZChtYXJrRE9NLmRvbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0b3AgPSBtYXJrRE9NLmNvbnRlbnRET00gfHwgbWFya0RPTS5kb207XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b3AuYXBwZW5kQ2hpbGQodGhpcy5zZXJpYWxpemVOb2RlSW5uZXIobm9kZSwgb3B0aW9ucykpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzZXJpYWxpemVOb2RlSW5uZXIobm9kZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAobm9kZS5pc1RleHQpXG4gICAgICAgICAgICByZXR1cm4gZG9jKG9wdGlvbnMpLmNyZWF0ZVRleHROb2RlKG5vZGUudGV4dCk7XG4gICAgICAgIGxldCB7IGRvbSwgY29udGVudERPTSB9ID0gcmVuZGVyU3BlYyhkb2Mob3B0aW9ucyksIHRoaXMubm9kZXNbbm9kZS50eXBlLm5hbWVdKG5vZGUpLCBudWxsLCBub2RlLmF0dHJzKTtcbiAgICAgICAgaWYgKGNvbnRlbnRET00pIHtcbiAgICAgICAgICAgIGlmIChub2RlLmlzTGVhZilcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkNvbnRlbnQgaG9sZSBub3QgYWxsb3dlZCBpbiBhIGxlYWYgbm9kZSBzcGVjXCIpO1xuICAgICAgICAgICAgdGhpcy5zZXJpYWxpemVGcmFnbWVudChub2RlLmNvbnRlbnQsIG9wdGlvbnMsIGNvbnRlbnRET00pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkb207XG4gICAgfVxuICAgIC8qKlxuICAgIFNlcmlhbGl6ZSB0aGlzIG5vZGUgdG8gYSBET00gbm9kZS4gVGhpcyBjYW4gYmUgdXNlZnVsIHdoZW4geW91XG4gICAgbmVlZCB0byBzZXJpYWxpemUgYSBwYXJ0IG9mIGEgZG9jdW1lbnQsIGFzIG9wcG9zZWQgdG8gdGhlIHdob2xlXG4gICAgZG9jdW1lbnQuIFRvIHNlcmlhbGl6ZSBhIHdob2xlIGRvY3VtZW50LCB1c2VcbiAgICBbYHNlcmlhbGl6ZUZyYWdtZW50YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLkRPTVNlcmlhbGl6ZXIuc2VyaWFsaXplRnJhZ21lbnQpIG9uXG4gICAgaXRzIFtjb250ZW50XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZS5jb250ZW50KS5cbiAgICAqL1xuICAgIHNlcmlhbGl6ZU5vZGUobm9kZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGxldCBkb20gPSB0aGlzLnNlcmlhbGl6ZU5vZGVJbm5lcihub2RlLCBvcHRpb25zKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IG5vZGUubWFya3MubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGxldCB3cmFwID0gdGhpcy5zZXJpYWxpemVNYXJrKG5vZGUubWFya3NbaV0sIG5vZGUuaXNJbmxpbmUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgaWYgKHdyYXApIHtcbiAgICAgICAgICAgICAgICAod3JhcC5jb250ZW50RE9NIHx8IHdyYXAuZG9tKS5hcHBlbmRDaGlsZChkb20pO1xuICAgICAgICAgICAgICAgIGRvbSA9IHdyYXAuZG9tO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkb207XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc2VyaWFsaXplTWFyayhtYXJrLCBpbmxpbmUsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBsZXQgdG9ET00gPSB0aGlzLm1hcmtzW21hcmsudHlwZS5uYW1lXTtcbiAgICAgICAgcmV0dXJuIHRvRE9NICYmIHJlbmRlclNwZWMoZG9jKG9wdGlvbnMpLCB0b0RPTShtYXJrLCBpbmxpbmUpLCBudWxsLCBtYXJrLmF0dHJzKTtcbiAgICB9XG4gICAgc3RhdGljIHJlbmRlclNwZWMoZG9jLCBzdHJ1Y3R1cmUsIHhtbE5TID0gbnVsbCwgYmxvY2tBcnJheXNJbikge1xuICAgICAgICAvLyBLbHVkZ2UgZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IHdpdGggYWNjaWRlbnRhbCBvcmlnaW5hbCBiZWhhdmlvdXNcbiAgICAgICAgaWYgKHR5cGVvZiBzdHJ1Y3R1cmUgPT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgIHJldHVybiB7IGRvbTogZG9jLmNyZWF0ZVRleHROb2RlKHN0cnVjdHVyZSkgfTtcbiAgICAgICAgcmV0dXJuIHJlbmRlclNwZWMoZG9jLCBzdHJ1Y3R1cmUsIHhtbE5TLCBibG9ja0FycmF5c0luKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQnVpbGQgYSBzZXJpYWxpemVyIHVzaW5nIHRoZSBbYHRvRE9NYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLnRvRE9NKVxuICAgIHByb3BlcnRpZXMgaW4gYSBzY2hlbWEncyBub2RlIGFuZCBtYXJrIHNwZWNzLlxuICAgICovXG4gICAgc3RhdGljIGZyb21TY2hlbWEoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBzY2hlbWEuY2FjaGVkLmRvbVNlcmlhbGl6ZXIgfHxcbiAgICAgICAgICAgIChzY2hlbWEuY2FjaGVkLmRvbVNlcmlhbGl6ZXIgPSBuZXcgRE9NU2VyaWFsaXplcih0aGlzLm5vZGVzRnJvbVNjaGVtYShzY2hlbWEpLCB0aGlzLm1hcmtzRnJvbVNjaGVtYShzY2hlbWEpKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEdhdGhlciB0aGUgc2VyaWFsaXplcnMgaW4gYSBzY2hlbWEncyBub2RlIHNwZWNzIGludG8gYW4gb2JqZWN0LlxuICAgIFRoaXMgY2FuIGJlIHVzZWZ1bCBhcyBhIGJhc2UgdG8gYnVpbGQgYSBjdXN0b20gc2VyaWFsaXplciBmcm9tLlxuICAgICovXG4gICAgc3RhdGljIG5vZGVzRnJvbVNjaGVtYShzY2hlbWEpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGdhdGhlclRvRE9NKHNjaGVtYS5ub2Rlcyk7XG4gICAgICAgIGlmICghcmVzdWx0LnRleHQpXG4gICAgICAgICAgICByZXN1bHQudGV4dCA9IG5vZGUgPT4gbm9kZS50ZXh0O1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvKipcbiAgICBHYXRoZXIgdGhlIHNlcmlhbGl6ZXJzIGluIGEgc2NoZW1hJ3MgbWFyayBzcGVjcyBpbnRvIGFuIG9iamVjdC5cbiAgICAqL1xuICAgIHN0YXRpYyBtYXJrc0Zyb21TY2hlbWEoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBnYXRoZXJUb0RPTShzY2hlbWEubWFya3MpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdhdGhlclRvRE9NKG9iaikge1xuICAgIGxldCByZXN1bHQgPSB7fTtcbiAgICBmb3IgKGxldCBuYW1lIGluIG9iaikge1xuICAgICAgICBsZXQgdG9ET00gPSBvYmpbbmFtZV0uc3BlYy50b0RPTTtcbiAgICAgICAgaWYgKHRvRE9NKVxuICAgICAgICAgICAgcmVzdWx0W25hbWVdID0gdG9ET007XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBkb2Mob3B0aW9ucykge1xuICAgIHJldHVybiBvcHRpb25zLmRvY3VtZW50IHx8IHdpbmRvdy5kb2N1bWVudDtcbn1cbmNvbnN0IHN1c3BpY2lvdXNBdHRyaWJ1dGVDYWNoZSA9IG5ldyBXZWFrTWFwKCk7XG5mdW5jdGlvbiBzdXNwaWNpb3VzQXR0cmlidXRlcyhhdHRycykge1xuICAgIGxldCB2YWx1ZSA9IHN1c3BpY2lvdXNBdHRyaWJ1dGVDYWNoZS5nZXQoYXR0cnMpO1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICBzdXNwaWNpb3VzQXR0cmlidXRlQ2FjaGUuc2V0KGF0dHJzLCB2YWx1ZSA9IHN1c3BpY2lvdXNBdHRyaWJ1dGVzSW5uZXIoYXR0cnMpKTtcbiAgICByZXR1cm4gdmFsdWU7XG59XG5mdW5jdGlvbiBzdXNwaWNpb3VzQXR0cmlidXRlc0lubmVyKGF0dHJzKSB7XG4gICAgbGV0IHJlc3VsdCA9IG51bGw7XG4gICAgZnVuY3Rpb24gc2Nhbih2YWx1ZSkge1xuICAgICAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWVbMF0gPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdClcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFtdO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2Nhbih2YWx1ZVtpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiB2YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgc2Nhbih2YWx1ZVtwcm9wXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2NhbihhdHRycyk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIHJlbmRlclNwZWMoZG9jLCBzdHJ1Y3R1cmUsIHhtbE5TLCBibG9ja0FycmF5c0luKSB7XG4gICAgaWYgKHN0cnVjdHVyZS5ub2RlVHlwZSA9PSAxKVxuICAgICAgICByZXR1cm4geyBkb206IHN0cnVjdHVyZSB9O1xuICAgIGlmIChzdHJ1Y3R1cmUuZG9tICYmIHN0cnVjdHVyZS5kb20ubm9kZVR5cGUgPT0gMSlcbiAgICAgICAgcmV0dXJuIHN0cnVjdHVyZTtcbiAgICBsZXQgdGFnTmFtZSA9IHN0cnVjdHVyZVswXSwgc3VzcGljaW91cztcbiAgICBpZiAodHlwZW9mIHRhZ05hbWUgIT0gXCJzdHJpbmdcIilcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGFycmF5IHBhc3NlZCB0byByZW5kZXJTcGVjXCIpO1xuICAgIGlmIChibG9ja0FycmF5c0luICYmIChzdXNwaWNpb3VzID0gc3VzcGljaW91c0F0dHJpYnV0ZXMoYmxvY2tBcnJheXNJbikpICYmXG4gICAgICAgIHN1c3BpY2lvdXMuaW5kZXhPZihzdHJ1Y3R1cmUpID4gLTEpXG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVXNpbmcgYW4gYXJyYXkgZnJvbSBhbiBhdHRyaWJ1dGUgb2JqZWN0IGFzIGEgRE9NIHNwZWMuIFRoaXMgbWF5IGJlIGFuIGF0dGVtcHRlZCBjcm9zcyBzaXRlIHNjcmlwdGluZyBhdHRhY2suXCIpO1xuICAgIGxldCBzcGFjZSA9IHRhZ05hbWUuaW5kZXhPZihcIiBcIik7XG4gICAgaWYgKHNwYWNlID4gMCkge1xuICAgICAgICB4bWxOUyA9IHRhZ05hbWUuc2xpY2UoMCwgc3BhY2UpO1xuICAgICAgICB0YWdOYW1lID0gdGFnTmFtZS5zbGljZShzcGFjZSArIDEpO1xuICAgIH1cbiAgICBsZXQgY29udGVudERPTTtcbiAgICBsZXQgZG9tID0gKHhtbE5TID8gZG9jLmNyZWF0ZUVsZW1lbnROUyh4bWxOUywgdGFnTmFtZSkgOiBkb2MuY3JlYXRlRWxlbWVudCh0YWdOYW1lKSk7XG4gICAgbGV0IGF0dHJzID0gc3RydWN0dXJlWzFdLCBzdGFydCA9IDE7XG4gICAgaWYgKGF0dHJzICYmIHR5cGVvZiBhdHRycyA9PSBcIm9iamVjdFwiICYmIGF0dHJzLm5vZGVUeXBlID09IG51bGwgJiYgIUFycmF5LmlzQXJyYXkoYXR0cnMpKSB7XG4gICAgICAgIHN0YXJ0ID0gMjtcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBhdHRycylcbiAgICAgICAgICAgIGlmIChhdHRyc1tuYW1lXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbGV0IHNwYWNlID0gbmFtZS5pbmRleE9mKFwiIFwiKTtcbiAgICAgICAgICAgICAgICBpZiAoc3BhY2UgPiAwKVxuICAgICAgICAgICAgICAgICAgICBkb20uc2V0QXR0cmlidXRlTlMobmFtZS5zbGljZSgwLCBzcGFjZSksIG5hbWUuc2xpY2Uoc3BhY2UgKyAxKSwgYXR0cnNbbmFtZV0pO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUgPT0gXCJzdHlsZVwiICYmIGRvbS5zdHlsZSlcbiAgICAgICAgICAgICAgICAgICAgZG9tLnN0eWxlLmNzc1RleHQgPSBhdHRyc1tuYW1lXTtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIGRvbS5zZXRBdHRyaWJ1dGUobmFtZSwgYXR0cnNbbmFtZV0pO1xuICAgICAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBzdHJ1Y3R1cmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IGNoaWxkID0gc3RydWN0dXJlW2ldO1xuICAgICAgICBpZiAoY2hpbGQgPT09IDApIHtcbiAgICAgICAgICAgIGlmIChpIDwgc3RydWN0dXJlLmxlbmd0aCAtIDEgfHwgaSA+IHN0YXJ0KVxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiQ29udGVudCBob2xlIG11c3QgYmUgdGhlIG9ubHkgY2hpbGQgb2YgaXRzIHBhcmVudCBub2RlXCIpO1xuICAgICAgICAgICAgcmV0dXJuIHsgZG9tLCBjb250ZW50RE9NOiBkb20gfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgY2hpbGQgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgZG9tLmFwcGVuZENoaWxkKGRvYy5jcmVhdGVUZXh0Tm9kZShjaGlsZCkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IHsgZG9tOiBpbm5lciwgY29udGVudERPTTogaW5uZXJDb250ZW50IH0gPSByZW5kZXJTcGVjKGRvYywgY2hpbGQsIHhtbE5TLCBibG9ja0FycmF5c0luKTtcbiAgICAgICAgICAgIGRvbS5hcHBlbmRDaGlsZChpbm5lcik7XG4gICAgICAgICAgICBpZiAoaW5uZXJDb250ZW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRET00pXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTXVsdGlwbGUgY29udGVudCBob2xlc1wiKTtcbiAgICAgICAgICAgICAgICBjb250ZW50RE9NID0gaW5uZXJDb250ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGRvbSwgY29udGVudERPTSB9O1xufVxuXG5leHBvcnQgeyBDb250ZW50TWF0Y2gsIERPTVBhcnNlciwgRE9NU2VyaWFsaXplciwgRnJhZ21lbnQsIE1hcmssIE1hcmtUeXBlLCBOb2RlLCBOb2RlUmFuZ2UsIE5vZGVUeXBlLCBSZXBsYWNlRXJyb3IsIFJlc29sdmVkUG9zLCBTY2hlbWEsIFNsaWNlIH07XG4iLCAiaW1wb3J0IHsgUmVwbGFjZUVycm9yLCBTbGljZSwgRnJhZ21lbnQsIE1hcmtUeXBlLCBNYXJrIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuXG4vLyBSZWNvdmVyeSB2YWx1ZXMgZW5jb2RlIGEgcmFuZ2UgaW5kZXggYW5kIGFuIG9mZnNldC4gVGhleSBhcmVcbi8vIHJlcHJlc2VudGVkIGFzIG51bWJlcnMsIGJlY2F1c2UgdG9ucyBvZiB0aGVtIHdpbGwgYmUgY3JlYXRlZCB3aGVuXG4vLyBtYXBwaW5nLCBmb3IgZXhhbXBsZSwgYSBsYXJnZSBudW1iZXIgb2YgZGVjb3JhdGlvbnMuIFRoZSBudW1iZXInc1xuLy8gbG93ZXIgMTYgYml0cyBwcm92aWRlIHRoZSBpbmRleCwgdGhlIHJlbWFpbmluZyBiaXRzIHRoZSBvZmZzZXQuXG4vL1xuLy8gTm90ZTogV2UgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYml0IHNoaWZ0IG9wZXJhdG9ycyB0byBlbi0gYW5kXG4vLyBkZWNvZGUgdGhlc2UsIHNpbmNlIHRob3NlIGNsaXAgdG8gMzIgYml0cywgd2hpY2ggd2UgbWlnaHQgaW4gcmFyZVxuLy8gY2FzZXMgd2FudCB0byBvdmVyZmxvdy4gQSA2NC1iaXQgZmxvYXQgY2FuIHJlcHJlc2VudCA0OC1iaXRcbi8vIGludGVnZXJzIHByZWNpc2VseS5cbmNvbnN0IGxvd2VyMTYgPSAweGZmZmY7XG5jb25zdCBmYWN0b3IxNiA9IE1hdGgucG93KDIsIDE2KTtcbmZ1bmN0aW9uIG1ha2VSZWNvdmVyKGluZGV4LCBvZmZzZXQpIHsgcmV0dXJuIGluZGV4ICsgb2Zmc2V0ICogZmFjdG9yMTY7IH1cbmZ1bmN0aW9uIHJlY292ZXJJbmRleCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgJiBsb3dlcjE2OyB9XG5mdW5jdGlvbiByZWNvdmVyT2Zmc2V0KHZhbHVlKSB7IHJldHVybiAodmFsdWUgLSAodmFsdWUgJiBsb3dlcjE2KSkgLyBmYWN0b3IxNjsgfVxuY29uc3QgREVMX0JFRk9SRSA9IDEsIERFTF9BRlRFUiA9IDIsIERFTF9BQ1JPU1MgPSA0LCBERUxfU0lERSA9IDg7XG4vKipcbkFuIG9iamVjdCByZXByZXNlbnRpbmcgYSBtYXBwZWQgcG9zaXRpb24gd2l0aCBleHRyYVxuaW5mb3JtYXRpb24uXG4qL1xuY2xhc3MgTWFwUmVzdWx0IHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBtYXBwZWQgdmVyc2lvbiBvZiB0aGUgcG9zaXRpb24uXG4gICAgKi9cbiAgICBwb3MsIFxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgZGVsSW5mbywgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICByZWNvdmVyKSB7XG4gICAgICAgIHRoaXMucG9zID0gcG9zO1xuICAgICAgICB0aGlzLmRlbEluZm8gPSBkZWxJbmZvO1xuICAgICAgICB0aGlzLnJlY292ZXIgPSByZWNvdmVyO1xuICAgIH1cbiAgICAvKipcbiAgICBUZWxscyB5b3Ugd2hldGhlciB0aGUgcG9zaXRpb24gd2FzIGRlbGV0ZWQsIHRoYXQgaXMsIHdoZXRoZXIgdGhlXG4gICAgc3RlcCByZW1vdmVkIHRoZSB0b2tlbiBvbiB0aGUgc2lkZSBxdWVyaWVkICh2aWEgdGhlIGBhc3NvY2ApXG4gICAgYXJndW1lbnQgZnJvbSB0aGUgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBnZXQgZGVsZXRlZCgpIHsgcmV0dXJuICh0aGlzLmRlbEluZm8gJiBERUxfU0lERSkgPiAwOyB9XG4gICAgLyoqXG4gICAgVGVsbHMgeW91IHdoZXRoZXIgdGhlIHRva2VuIGJlZm9yZSB0aGUgbWFwcGVkIHBvc2l0aW9uIHdhcyBkZWxldGVkLlxuICAgICovXG4gICAgZ2V0IGRlbGV0ZWRCZWZvcmUoKSB7IHJldHVybiAodGhpcy5kZWxJbmZvICYgKERFTF9CRUZPUkUgfCBERUxfQUNST1NTKSkgPiAwOyB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoZSB0b2tlbiBhZnRlciB0aGUgbWFwcGVkIHBvc2l0aW9uIHdhcyBkZWxldGVkLlxuICAgICovXG4gICAgZ2V0IGRlbGV0ZWRBZnRlcigpIHsgcmV0dXJuICh0aGlzLmRlbEluZm8gJiAoREVMX0FGVEVSIHwgREVMX0FDUk9TUykpID4gMDsgfVxuICAgIC8qKlxuICAgIFRlbGxzIHdoZXRoZXIgYW55IG9mIHRoZSBzdGVwcyBtYXBwZWQgdGhyb3VnaCBkZWxldGVzIGFjcm9zcyB0aGVcbiAgICBwb3NpdGlvbiAoaW5jbHVkaW5nIGJvdGggdGhlIHRva2VuIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlXG4gICAgcG9zaXRpb24pLlxuICAgICovXG4gICAgZ2V0IGRlbGV0ZWRBY3Jvc3MoKSB7IHJldHVybiAodGhpcy5kZWxJbmZvICYgREVMX0FDUk9TUykgPiAwOyB9XG59XG4vKipcbkEgbWFwIGRlc2NyaWJpbmcgdGhlIGRlbGV0aW9ucyBhbmQgaW5zZXJ0aW9ucyBtYWRlIGJ5IGEgc3RlcCwgd2hpY2hcbmNhbiBiZSB1c2VkIHRvIGZpbmQgdGhlIGNvcnJlc3BvbmRlbmNlIGJldHdlZW4gcG9zaXRpb25zIGluIHRoZVxucHJlLXN0ZXAgdmVyc2lvbiBvZiBhIGRvY3VtZW50IGFuZCB0aGUgc2FtZSBwb3NpdGlvbiBpbiB0aGVcbnBvc3Qtc3RlcCB2ZXJzaW9uLlxuKi9cbmNsYXNzIFN0ZXBNYXAge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIHBvc2l0aW9uIG1hcC4gVGhlIG1vZGlmaWNhdGlvbnMgdG8gdGhlIGRvY3VtZW50IGFyZVxuICAgIHJlcHJlc2VudGVkIGFzIGFuIGFycmF5IG9mIG51bWJlcnMsIGluIHdoaWNoIGVhY2ggZ3JvdXAgb2YgdGhyZWVcbiAgICByZXByZXNlbnRzIGEgbW9kaWZpZWQgY2h1bmsgYXMgYFtzdGFydCwgb2xkU2l6ZSwgbmV3U2l6ZV1gLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICByYW5nZXMsIFxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgaW52ZXJ0ZWQgPSBmYWxzZSkge1xuICAgICAgICB0aGlzLnJhbmdlcyA9IHJhbmdlcztcbiAgICAgICAgdGhpcy5pbnZlcnRlZCA9IGludmVydGVkO1xuICAgICAgICBpZiAoIXJhbmdlcy5sZW5ndGggJiYgU3RlcE1hcC5lbXB0eSlcbiAgICAgICAgICAgIHJldHVybiBTdGVwTWFwLmVtcHR5O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHJlY292ZXIodmFsdWUpIHtcbiAgICAgICAgbGV0IGRpZmYgPSAwLCBpbmRleCA9IHJlY292ZXJJbmRleCh2YWx1ZSk7XG4gICAgICAgIGlmICghdGhpcy5pbnZlcnRlZClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kZXg7IGkrKylcbiAgICAgICAgICAgICAgICBkaWZmICs9IHRoaXMucmFuZ2VzW2kgKiAzICsgMl0gLSB0aGlzLnJhbmdlc1tpICogMyArIDFdO1xuICAgICAgICByZXR1cm4gdGhpcy5yYW5nZXNbaW5kZXggKiAzXSArIGRpZmYgKyByZWNvdmVyT2Zmc2V0KHZhbHVlKTtcbiAgICB9XG4gICAgbWFwUmVzdWx0KHBvcywgYXNzb2MgPSAxKSB7IHJldHVybiB0aGlzLl9tYXAocG9zLCBhc3NvYywgZmFsc2UpOyB9XG4gICAgbWFwKHBvcywgYXNzb2MgPSAxKSB7IHJldHVybiB0aGlzLl9tYXAocG9zLCBhc3NvYywgdHJ1ZSk7IH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIF9tYXAocG9zLCBhc3NvYywgc2ltcGxlKSB7XG4gICAgICAgIGxldCBkaWZmID0gMCwgb2xkSW5kZXggPSB0aGlzLmludmVydGVkID8gMiA6IDEsIG5ld0luZGV4ID0gdGhpcy5pbnZlcnRlZCA/IDEgOiAyO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucmFuZ2VzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLnJhbmdlc1tpXSAtICh0aGlzLmludmVydGVkID8gZGlmZiA6IDApO1xuICAgICAgICAgICAgaWYgKHN0YXJ0ID4gcG9zKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgbGV0IG9sZFNpemUgPSB0aGlzLnJhbmdlc1tpICsgb2xkSW5kZXhdLCBuZXdTaXplID0gdGhpcy5yYW5nZXNbaSArIG5ld0luZGV4XSwgZW5kID0gc3RhcnQgKyBvbGRTaXplO1xuICAgICAgICAgICAgaWYgKHBvcyA8PSBlbmQpIHtcbiAgICAgICAgICAgICAgICBsZXQgc2lkZSA9ICFvbGRTaXplID8gYXNzb2MgOiBwb3MgPT0gc3RhcnQgPyAtMSA6IHBvcyA9PSBlbmQgPyAxIDogYXNzb2M7XG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IHN0YXJ0ICsgZGlmZiArIChzaWRlIDwgMCA/IDAgOiBuZXdTaXplKTtcbiAgICAgICAgICAgICAgICBpZiAoc2ltcGxlKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIGxldCByZWNvdmVyID0gcG9zID09IChhc3NvYyA8IDAgPyBzdGFydCA6IGVuZCkgPyBudWxsIDogbWFrZVJlY292ZXIoaSAvIDMsIHBvcyAtIHN0YXJ0KTtcbiAgICAgICAgICAgICAgICBsZXQgZGVsID0gcG9zID09IHN0YXJ0ID8gREVMX0FGVEVSIDogcG9zID09IGVuZCA/IERFTF9CRUZPUkUgOiBERUxfQUNST1NTO1xuICAgICAgICAgICAgICAgIGlmIChhc3NvYyA8IDAgPyBwb3MgIT0gc3RhcnQgOiBwb3MgIT0gZW5kKVxuICAgICAgICAgICAgICAgICAgICBkZWwgfD0gREVMX1NJREU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXBSZXN1bHQocmVzdWx0LCBkZWwsIHJlY292ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGlmZiArPSBuZXdTaXplIC0gb2xkU2l6ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2ltcGxlID8gcG9zICsgZGlmZiA6IG5ldyBNYXBSZXN1bHQocG9zICsgZGlmZiwgMCwgbnVsbCk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgdG91Y2hlcyhwb3MsIHJlY292ZXIpIHtcbiAgICAgICAgbGV0IGRpZmYgPSAwLCBpbmRleCA9IHJlY292ZXJJbmRleChyZWNvdmVyKTtcbiAgICAgICAgbGV0IG9sZEluZGV4ID0gdGhpcy5pbnZlcnRlZCA/IDIgOiAxLCBuZXdJbmRleCA9IHRoaXMuaW52ZXJ0ZWQgPyAxIDogMjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnJhbmdlcy5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgICAgICAgbGV0IHN0YXJ0ID0gdGhpcy5yYW5nZXNbaV0gLSAodGhpcy5pbnZlcnRlZCA/IGRpZmYgOiAwKTtcbiAgICAgICAgICAgIGlmIChzdGFydCA+IHBvcylcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGxldCBvbGRTaXplID0gdGhpcy5yYW5nZXNbaSArIG9sZEluZGV4XSwgZW5kID0gc3RhcnQgKyBvbGRTaXplO1xuICAgICAgICAgICAgaWYgKHBvcyA8PSBlbmQgJiYgaSA9PSBpbmRleCAqIDMpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICBkaWZmICs9IHRoaXMucmFuZ2VzW2kgKyBuZXdJbmRleF0gLSBvbGRTaXplO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ2FsbHMgdGhlIGdpdmVuIGZ1bmN0aW9uIG9uIGVhY2ggb2YgdGhlIGNoYW5nZWQgcmFuZ2VzIGluY2x1ZGVkIGluXG4gICAgdGhpcyBtYXAuXG4gICAgKi9cbiAgICBmb3JFYWNoKGYpIHtcbiAgICAgICAgbGV0IG9sZEluZGV4ID0gdGhpcy5pbnZlcnRlZCA/IDIgOiAxLCBuZXdJbmRleCA9IHRoaXMuaW52ZXJ0ZWQgPyAxIDogMjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGRpZmYgPSAwOyBpIDwgdGhpcy5yYW5nZXMubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgIGxldCBzdGFydCA9IHRoaXMucmFuZ2VzW2ldLCBvbGRTdGFydCA9IHN0YXJ0IC0gKHRoaXMuaW52ZXJ0ZWQgPyBkaWZmIDogMCksIG5ld1N0YXJ0ID0gc3RhcnQgKyAodGhpcy5pbnZlcnRlZCA/IDAgOiBkaWZmKTtcbiAgICAgICAgICAgIGxldCBvbGRTaXplID0gdGhpcy5yYW5nZXNbaSArIG9sZEluZGV4XSwgbmV3U2l6ZSA9IHRoaXMucmFuZ2VzW2kgKyBuZXdJbmRleF07XG4gICAgICAgICAgICBmKG9sZFN0YXJ0LCBvbGRTdGFydCArIG9sZFNpemUsIG5ld1N0YXJ0LCBuZXdTdGFydCArIG5ld1NpemUpO1xuICAgICAgICAgICAgZGlmZiArPSBuZXdTaXplIC0gb2xkU2l6ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYW4gaW52ZXJ0ZWQgdmVyc2lvbiBvZiB0aGlzIG1hcC4gVGhlIHJlc3VsdCBjYW4gYmUgdXNlZCB0b1xuICAgIG1hcCBwb3NpdGlvbnMgaW4gdGhlIHBvc3Qtc3RlcCBkb2N1bWVudCB0byB0aGUgcHJlLXN0ZXAgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBpbnZlcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RlcE1hcCh0aGlzLnJhbmdlcywgIXRoaXMuaW52ZXJ0ZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gKHRoaXMuaW52ZXJ0ZWQgPyBcIi1cIiA6IFwiXCIpICsgSlNPTi5zdHJpbmdpZnkodGhpcy5yYW5nZXMpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBtYXAgdGhhdCBtb3ZlcyBhbGwgcG9zaXRpb25zIGJ5IG9mZnNldCBgbmAgKHdoaWNoIG1heSBiZVxuICAgIG5lZ2F0aXZlKS4gVGhpcyBjYW4gYmUgdXNlZnVsIHdoZW4gYXBwbHlpbmcgc3RlcHMgbWVhbnQgZm9yIGFcbiAgICBzdWItZG9jdW1lbnQgdG8gYSBsYXJnZXIgZG9jdW1lbnQsIG9yIHZpY2UtdmVyc2EuXG4gICAgKi9cbiAgICBzdGF0aWMgb2Zmc2V0KG4pIHtcbiAgICAgICAgcmV0dXJuIG4gPT0gMCA/IFN0ZXBNYXAuZW1wdHkgOiBuZXcgU3RlcE1hcChuIDwgMCA/IFswLCAtbiwgMF0gOiBbMCwgMCwgbl0pO1xuICAgIH1cbn1cbi8qKlxuQSBTdGVwTWFwIHRoYXQgY29udGFpbnMgbm8gY2hhbmdlZCByYW5nZXMuXG4qL1xuU3RlcE1hcC5lbXB0eSA9IG5ldyBTdGVwTWFwKFtdKTtcbi8qKlxuQSBtYXBwaW5nIHJlcHJlc2VudHMgYSBwaXBlbGluZSBvZiB6ZXJvIG9yIG1vcmUgW3N0ZXBcbm1hcHNdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0uU3RlcE1hcCkuIEl0IGhhcyBzcGVjaWFsIHByb3Zpc2lvbnMgZm9yIGxvc3NsZXNzbHlcbmhhbmRsaW5nIG1hcHBpbmcgcG9zaXRpb25zIHRocm91Z2ggYSBzZXJpZXMgb2Ygc3RlcHMgaW4gd2hpY2ggc29tZVxuc3RlcHMgYXJlIGludmVydGVkIHZlcnNpb25zIG9mIGVhcmxpZXIgc3RlcHMuIChUaGlzIGNvbWVzIHVwIHdoZW5cbuKAmFtyZWJhc2luZ10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9ndWlkZS8jdHJhbnNmb3JtLnJlYmFzaW5nKeKAmSBzdGVwcyBmb3JcbmNvbGxhYm9yYXRpb24gb3IgaGlzdG9yeSBtYW5hZ2VtZW50LilcbiovXG5jbGFzcyBNYXBwaW5nIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBuZXcgbWFwcGluZyB3aXRoIHRoZSBnaXZlbiBwb3NpdGlvbiBtYXBzLlxuICAgICovXG4gICAgY29uc3RydWN0b3IobWFwcywgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBtaXJyb3IsIFxuICAgIC8qKlxuICAgIFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYG1hcHNgIGFycmF5LCB1c2VkIHdoZW4gYG1hcGAgb3JcbiAgICBgbWFwUmVzdWx0YCBpcyBjYWxsZWQuXG4gICAgKi9cbiAgICBmcm9tID0gMCwgXG4gICAgLyoqXG4gICAgVGhlIGVuZCBwb3NpdGlvbiBpbiB0aGUgYG1hcHNgIGFycmF5LlxuICAgICovXG4gICAgdG8gPSBtYXBzID8gbWFwcy5sZW5ndGggOiAwKSB7XG4gICAgICAgIHRoaXMubWlycm9yID0gbWlycm9yO1xuICAgICAgICB0aGlzLmZyb20gPSBmcm9tO1xuICAgICAgICB0aGlzLnRvID0gdG87XG4gICAgICAgIHRoaXMuX21hcHMgPSBtYXBzIHx8IFtdO1xuICAgICAgICB0aGlzLm93bkRhdGEgPSAhKG1hcHMgfHwgbWlycm9yKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHN0ZXAgbWFwcyBpbiB0aGlzIG1hcHBpbmcuXG4gICAgKi9cbiAgICBnZXQgbWFwcygpIHsgcmV0dXJuIHRoaXMuX21hcHM7IH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBtYXBwaW5nIHRoYXQgbWFwcyBvbmx5IHRocm91Z2ggYSBwYXJ0IG9mIHRoaXMgb25lLlxuICAgICovXG4gICAgc2xpY2UoZnJvbSA9IDAsIHRvID0gdGhpcy5tYXBzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gbmV3IE1hcHBpbmcodGhpcy5fbWFwcywgdGhpcy5taXJyb3IsIGZyb20sIHRvKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQWRkIGEgc3RlcCBtYXAgdG8gdGhlIGVuZCBvZiB0aGlzIG1hcHBpbmcuIElmIGBtaXJyb3JzYCBpc1xuICAgIGdpdmVuLCBpdCBzaG91bGQgYmUgdGhlIGluZGV4IG9mIHRoZSBzdGVwIG1hcCB0aGF0IGlzIHRoZSBtaXJyb3JcbiAgICBpbWFnZSBvZiB0aGlzIG9uZS5cbiAgICAqL1xuICAgIGFwcGVuZE1hcChtYXAsIG1pcnJvcnMpIHtcbiAgICAgICAgaWYgKCF0aGlzLm93bkRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuX21hcHMgPSB0aGlzLl9tYXBzLnNsaWNlKCk7XG4gICAgICAgICAgICB0aGlzLm1pcnJvciA9IHRoaXMubWlycm9yICYmIHRoaXMubWlycm9yLnNsaWNlKCk7XG4gICAgICAgICAgICB0aGlzLm93bkRhdGEgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudG8gPSB0aGlzLl9tYXBzLnB1c2gobWFwKTtcbiAgICAgICAgaWYgKG1pcnJvcnMgIT0gbnVsbClcbiAgICAgICAgICAgIHRoaXMuc2V0TWlycm9yKHRoaXMuX21hcHMubGVuZ3RoIC0gMSwgbWlycm9ycyk7XG4gICAgfVxuICAgIC8qKlxuICAgIEFkZCBhbGwgdGhlIHN0ZXAgbWFwcyBpbiBhIGdpdmVuIG1hcHBpbmcgdG8gdGhpcyBvbmUgKHByZXNlcnZpbmdcbiAgICBtaXJyb3JpbmcgaW5mb3JtYXRpb24pLlxuICAgICovXG4gICAgYXBwZW5kTWFwcGluZyhtYXBwaW5nKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBzdGFydFNpemUgPSB0aGlzLl9tYXBzLmxlbmd0aDsgaSA8IG1hcHBpbmcuX21hcHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBtaXJyID0gbWFwcGluZy5nZXRNaXJyb3IoaSk7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZE1hcChtYXBwaW5nLl9tYXBzW2ldLCBtaXJyICE9IG51bGwgJiYgbWlyciA8IGkgPyBzdGFydFNpemUgKyBtaXJyIDogdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBGaW5kcyB0aGUgb2Zmc2V0IG9mIHRoZSBzdGVwIG1hcCB0aGF0IG1pcnJvcnMgdGhlIG1hcCBhdCB0aGVcbiAgICBnaXZlbiBvZmZzZXQsIGluIHRoaXMgbWFwcGluZyAoYXMgcGVyIHRoZSBzZWNvbmQgYXJndW1lbnQgdG9cbiAgICBgYXBwZW5kTWFwYCkuXG4gICAgKi9cbiAgICBnZXRNaXJyb3Iobikge1xuICAgICAgICBpZiAodGhpcy5taXJyb3IpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubWlycm9yLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm1pcnJvcltpXSA9PSBuKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5taXJyb3JbaSArIChpICUgMiA/IC0xIDogMSldO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHNldE1pcnJvcihuLCBtKSB7XG4gICAgICAgIGlmICghdGhpcy5taXJyb3IpXG4gICAgICAgICAgICB0aGlzLm1pcnJvciA9IFtdO1xuICAgICAgICB0aGlzLm1pcnJvci5wdXNoKG4sIG0pO1xuICAgIH1cbiAgICAvKipcbiAgICBBcHBlbmQgdGhlIGludmVyc2Ugb2YgdGhlIGdpdmVuIG1hcHBpbmcgdG8gdGhpcyBvbmUuXG4gICAgKi9cbiAgICBhcHBlbmRNYXBwaW5nSW52ZXJ0ZWQobWFwcGluZykge1xuICAgICAgICBmb3IgKGxldCBpID0gbWFwcGluZy5tYXBzLmxlbmd0aCAtIDEsIHRvdGFsU2l6ZSA9IHRoaXMuX21hcHMubGVuZ3RoICsgbWFwcGluZy5fbWFwcy5sZW5ndGg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgbWlyciA9IG1hcHBpbmcuZ2V0TWlycm9yKGkpO1xuICAgICAgICAgICAgdGhpcy5hcHBlbmRNYXAobWFwcGluZy5fbWFwc1tpXS5pbnZlcnQoKSwgbWlyciAhPSBudWxsICYmIG1pcnIgPiBpID8gdG90YWxTaXplIC0gbWlyciAtIDEgOiB1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhbiBpbnZlcnRlZCB2ZXJzaW9uIG9mIHRoaXMgbWFwcGluZy5cbiAgICAqL1xuICAgIGludmVydCgpIHtcbiAgICAgICAgbGV0IGludmVyc2UgPSBuZXcgTWFwcGluZztcbiAgICAgICAgaW52ZXJzZS5hcHBlbmRNYXBwaW5nSW52ZXJ0ZWQodGhpcyk7XG4gICAgICAgIHJldHVybiBpbnZlcnNlO1xuICAgIH1cbiAgICAvKipcbiAgICBNYXAgYSBwb3NpdGlvbiB0aHJvdWdoIHRoaXMgbWFwcGluZy5cbiAgICAqL1xuICAgIG1hcChwb3MsIGFzc29jID0gMSkge1xuICAgICAgICBpZiAodGhpcy5taXJyb3IpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWFwKHBvcywgYXNzb2MsIHRydWUpO1xuICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5mcm9tOyBpIDwgdGhpcy50bzsgaSsrKVxuICAgICAgICAgICAgcG9zID0gdGhpcy5fbWFwc1tpXS5tYXAocG9zLCBhc3NvYyk7XG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgfVxuICAgIC8qKlxuICAgIE1hcCBhIHBvc2l0aW9uIHRocm91Z2ggdGhpcyBtYXBwaW5nLCByZXR1cm5pbmcgYSBtYXBwaW5nXG4gICAgcmVzdWx0LlxuICAgICovXG4gICAgbWFwUmVzdWx0KHBvcywgYXNzb2MgPSAxKSB7IHJldHVybiB0aGlzLl9tYXAocG9zLCBhc3NvYywgZmFsc2UpOyB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBfbWFwKHBvcywgYXNzb2MsIHNpbXBsZSkge1xuICAgICAgICBsZXQgZGVsSW5mbyA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLmZyb207IGkgPCB0aGlzLnRvOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBtYXAgPSB0aGlzLl9tYXBzW2ldLCByZXN1bHQgPSBtYXAubWFwUmVzdWx0KHBvcywgYXNzb2MpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5yZWNvdmVyICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBsZXQgY29yciA9IHRoaXMuZ2V0TWlycm9yKGkpO1xuICAgICAgICAgICAgICAgIGlmIChjb3JyICE9IG51bGwgJiYgY29yciA+IGkgJiYgY29yciA8IHRoaXMudG8pIHtcbiAgICAgICAgICAgICAgICAgICAgaSA9IGNvcnI7XG4gICAgICAgICAgICAgICAgICAgIHBvcyA9IHRoaXMuX21hcHNbY29ycl0ucmVjb3ZlcihyZXN1bHQucmVjb3Zlcik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbEluZm8gfD0gcmVzdWx0LmRlbEluZm87XG4gICAgICAgICAgICBwb3MgPSByZXN1bHQucG9zO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzaW1wbGUgPyBwb3MgOiBuZXcgTWFwUmVzdWx0KHBvcywgZGVsSW5mbywgbnVsbCk7XG4gICAgfVxufVxuXG5jb25zdCBzdGVwc0J5SUQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuLyoqXG5BIHN0ZXAgb2JqZWN0IHJlcHJlc2VudHMgYW4gYXRvbWljIGNoYW5nZS4gSXQgZ2VuZXJhbGx5IGFwcGxpZXNcbm9ubHkgdG8gdGhlIGRvY3VtZW50IGl0IHdhcyBjcmVhdGVkIGZvciwgc2luY2UgdGhlIHBvc2l0aW9uc1xuc3RvcmVkIGluIGl0IHdpbGwgb25seSBtYWtlIHNlbnNlIGZvciB0aGF0IGRvY3VtZW50LlxuXG5OZXcgc3RlcHMgYXJlIGRlZmluZWQgYnkgY3JlYXRpbmcgY2xhc3NlcyB0aGF0IGV4dGVuZCBgU3RlcGAsXG5vdmVycmlkaW5nIHRoZSBgYXBwbHlgLCBgaW52ZXJ0YCwgYG1hcGAsIGBnZXRNYXBgIGFuZCBgZnJvbUpTT05gXG5tZXRob2RzLCBhbmQgcmVnaXN0ZXJpbmcgeW91ciBjbGFzcyB3aXRoIGEgdW5pcXVlXG5KU09OLXNlcmlhbGl6YXRpb24gaWRlbnRpZmllciB1c2luZ1xuW2BTdGVwLmpzb25JRGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0uU3RlcF5qc29uSUQpLlxuKi9cbmNsYXNzIFN0ZXAge1xuICAgIC8qKlxuICAgIEdldCB0aGUgc3RlcCBtYXAgdGhhdCByZXByZXNlbnRzIHRoZSBjaGFuZ2VzIG1hZGUgYnkgdGhpcyBzdGVwLFxuICAgIGFuZCB3aGljaCBjYW4gYmUgdXNlZCB0byB0cmFuc2Zvcm0gYmV0d2VlbiBwb3NpdGlvbnMgaW4gdGhlIG9sZFxuICAgIGFuZCB0aGUgbmV3IGRvY3VtZW50LlxuICAgICovXG4gICAgZ2V0TWFwKCkgeyByZXR1cm4gU3RlcE1hcC5lbXB0eTsgfVxuICAgIC8qKlxuICAgIFRyeSB0byBtZXJnZSB0aGlzIHN0ZXAgd2l0aCBhbm90aGVyIG9uZSwgdG8gYmUgYXBwbGllZCBkaXJlY3RseVxuICAgIGFmdGVyIGl0LiBSZXR1cm5zIHRoZSBtZXJnZWQgc3RlcCB3aGVuIHBvc3NpYmxlLCBudWxsIGlmIHRoZVxuICAgIHN0ZXBzIGNhbid0IGJlIG1lcmdlZC5cbiAgICAqL1xuICAgIG1lcmdlKG90aGVyKSB7IHJldHVybiBudWxsOyB9XG4gICAgLyoqXG4gICAgRGVzZXJpYWxpemUgYSBzdGVwIGZyb20gaXRzIEpTT04gcmVwcmVzZW50YXRpb24uIFdpbGwgY2FsbFxuICAgIHRocm91Z2ggdG8gdGhlIHN0ZXAgY2xhc3MnIG93biBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZC5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uIHx8ICFqc29uLnN0ZXBUeXBlKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBTdGVwLmZyb21KU09OXCIpO1xuICAgICAgICBsZXQgdHlwZSA9IHN0ZXBzQnlJRFtqc29uLnN0ZXBUeXBlXTtcbiAgICAgICAgaWYgKCF0eXBlKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYE5vIHN0ZXAgdHlwZSAke2pzb24uc3RlcFR5cGV9IGRlZmluZWRgKTtcbiAgICAgICAgcmV0dXJuIHR5cGUuZnJvbUpTT04oc2NoZW1hLCBqc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVG8gYmUgYWJsZSB0byBzZXJpYWxpemUgc3RlcHMgdG8gSlNPTiwgZWFjaCBzdGVwIG5lZWRzIGEgc3RyaW5nXG4gICAgSUQgdG8gYXR0YWNoIHRvIGl0cyBKU09OIHJlcHJlc2VudGF0aW9uLiBVc2UgdGhpcyBtZXRob2QgdG9cbiAgICByZWdpc3RlciBhbiBJRCBmb3IgeW91ciBzdGVwIGNsYXNzZXMuIFRyeSB0byBwaWNrIHNvbWV0aGluZ1xuICAgIHRoYXQncyB1bmxpa2VseSB0byBjbGFzaCB3aXRoIHN0ZXBzIGZyb20gb3RoZXIgbW9kdWxlcy5cbiAgICAqL1xuICAgIHN0YXRpYyBqc29uSUQoaWQsIHN0ZXBDbGFzcykge1xuICAgICAgICBpZiAoaWQgaW4gc3RlcHNCeUlEKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJEdXBsaWNhdGUgdXNlIG9mIHN0ZXAgSlNPTiBJRCBcIiArIGlkKTtcbiAgICAgICAgc3RlcHNCeUlEW2lkXSA9IHN0ZXBDbGFzcztcbiAgICAgICAgc3RlcENsYXNzLnByb3RvdHlwZS5qc29uSUQgPSBpZDtcbiAgICAgICAgcmV0dXJuIHN0ZXBDbGFzcztcbiAgICB9XG59XG4vKipcblRoZSByZXN1bHQgb2YgW2FwcGx5aW5nXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdHJhbnNmb3JtLlN0ZXAuYXBwbHkpIGEgc3RlcC4gQ29udGFpbnMgZWl0aGVyIGFcbm5ldyBkb2N1bWVudCBvciBhIGZhaWx1cmUgdmFsdWUuXG4qL1xuY2xhc3MgU3RlcFJlc3VsdCB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgdHJhbnNmb3JtZWQgZG9jdW1lbnQsIGlmIHN1Y2Nlc3NmdWwuXG4gICAgKi9cbiAgICBkb2MsIFxuICAgIC8qKlxuICAgIFRoZSBmYWlsdXJlIG1lc3NhZ2UsIGlmIHVuc3VjY2Vzc2Z1bC5cbiAgICAqL1xuICAgIGZhaWxlZCkge1xuICAgICAgICB0aGlzLmRvYyA9IGRvYztcbiAgICAgICAgdGhpcy5mYWlsZWQgPSBmYWlsZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIHN1Y2Nlc3NmdWwgc3RlcCByZXN1bHQuXG4gICAgKi9cbiAgICBzdGF0aWMgb2soZG9jKSB7IHJldHVybiBuZXcgU3RlcFJlc3VsdChkb2MsIG51bGwpOyB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgZmFpbGVkIHN0ZXAgcmVzdWx0LlxuICAgICovXG4gICAgc3RhdGljIGZhaWwobWVzc2FnZSkgeyByZXR1cm4gbmV3IFN0ZXBSZXN1bHQobnVsbCwgbWVzc2FnZSk7IH1cbiAgICAvKipcbiAgICBDYWxsIFtgTm9kZS5yZXBsYWNlYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGUucmVwbGFjZSkgd2l0aCB0aGUgZ2l2ZW5cbiAgICBhcmd1bWVudHMuIENyZWF0ZSBhIHN1Y2Nlc3NmdWwgcmVzdWx0IGlmIGl0IHN1Y2NlZWRzLCBhbmQgYVxuICAgIGZhaWxlZCBvbmUgaWYgaXQgdGhyb3dzIGEgYFJlcGxhY2VFcnJvcmAuXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbVJlcGxhY2UoZG9jLCBmcm9tLCB0bywgc2xpY2UpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0Lm9rKGRvYy5yZXBsYWNlKGZyb20sIHRvLCBzbGljZSkpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFJlcGxhY2VFcnJvcilcbiAgICAgICAgICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mYWlsKGUubWVzc2FnZSk7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYXBGcmFnbWVudChmcmFnbWVudCwgZiwgcGFyZW50KSB7XG4gICAgbGV0IG1hcHBlZCA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZnJhZ21lbnQuY2hpbGRDb3VudDsgaSsrKSB7XG4gICAgICAgIGxldCBjaGlsZCA9IGZyYWdtZW50LmNoaWxkKGkpO1xuICAgICAgICBpZiAoY2hpbGQuY29udGVudC5zaXplKVxuICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5jb3B5KG1hcEZyYWdtZW50KGNoaWxkLmNvbnRlbnQsIGYsIGNoaWxkKSk7XG4gICAgICAgIGlmIChjaGlsZC5pc0lubGluZSlcbiAgICAgICAgICAgIGNoaWxkID0gZihjaGlsZCwgcGFyZW50LCBpKTtcbiAgICAgICAgbWFwcGVkLnB1c2goY2hpbGQpO1xuICAgIH1cbiAgICByZXR1cm4gRnJhZ21lbnQuZnJvbUFycmF5KG1hcHBlZCk7XG59XG4vKipcbkFkZCBhIG1hcmsgdG8gYWxsIGlubGluZSBjb250ZW50IGJldHdlZW4gdHdvIHBvc2l0aW9ucy5cbiovXG5jbGFzcyBBZGRNYXJrU3RlcCBleHRlbmRzIFN0ZXAge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIG1hcmsgc3RlcC5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBzdGFydCBvZiB0aGUgbWFya2VkIHJhbmdlLlxuICAgICovXG4gICAgZnJvbSwgXG4gICAgLyoqXG4gICAgVGhlIGVuZCBvZiB0aGUgbWFya2VkIHJhbmdlLlxuICAgICovXG4gICAgdG8sIFxuICAgIC8qKlxuICAgIFRoZSBtYXJrIHRvIGFkZC5cbiAgICAqL1xuICAgIG1hcmspIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICAgICAgdGhpcy50byA9IHRvO1xuICAgICAgICB0aGlzLm1hcmsgPSBtYXJrO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgbGV0IG9sZFNsaWNlID0gZG9jLnNsaWNlKHRoaXMuZnJvbSwgdGhpcy50byksICRmcm9tID0gZG9jLnJlc29sdmUodGhpcy5mcm9tKTtcbiAgICAgICAgbGV0IHBhcmVudCA9ICRmcm9tLm5vZGUoJGZyb20uc2hhcmVkRGVwdGgodGhpcy50bykpO1xuICAgICAgICBsZXQgc2xpY2UgPSBuZXcgU2xpY2UobWFwRnJhZ21lbnQob2xkU2xpY2UuY29udGVudCwgKG5vZGUsIHBhcmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFub2RlLmlzQXRvbSB8fCAhcGFyZW50LnR5cGUuYWxsb3dzTWFya1R5cGUodGhpcy5tYXJrLnR5cGUpKVxuICAgICAgICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICAgICAgcmV0dXJuIG5vZGUubWFyayh0aGlzLm1hcmsuYWRkVG9TZXQobm9kZS5tYXJrcykpO1xuICAgICAgICB9LCBwYXJlbnQpLCBvbGRTbGljZS5vcGVuU3RhcnQsIG9sZFNsaWNlLm9wZW5FbmQpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMuZnJvbSwgdGhpcy50bywgc2xpY2UpO1xuICAgIH1cbiAgICBpbnZlcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVtb3ZlTWFya1N0ZXAodGhpcy5mcm9tLCB0aGlzLnRvLCB0aGlzLm1hcmspO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICBsZXQgZnJvbSA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMuZnJvbSwgMSksIHRvID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy50bywgLTEpO1xuICAgICAgICBpZiAoZnJvbS5kZWxldGVkICYmIHRvLmRlbGV0ZWQgfHwgZnJvbS5wb3MgPj0gdG8ucG9zKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBuZXcgQWRkTWFya1N0ZXAoZnJvbS5wb3MsIHRvLnBvcywgdGhpcy5tYXJrKTtcbiAgICB9XG4gICAgbWVyZ2Uob3RoZXIpIHtcbiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgQWRkTWFya1N0ZXAgJiZcbiAgICAgICAgICAgIG90aGVyLm1hcmsuZXEodGhpcy5tYXJrKSAmJlxuICAgICAgICAgICAgdGhpcy5mcm9tIDw9IG90aGVyLnRvICYmIHRoaXMudG8gPj0gb3RoZXIuZnJvbSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgQWRkTWFya1N0ZXAoTWF0aC5taW4odGhpcy5mcm9tLCBvdGhlci5mcm9tKSwgTWF0aC5tYXgodGhpcy50bywgb3RoZXIudG8pLCB0aGlzLm1hcmspO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyBzdGVwVHlwZTogXCJhZGRNYXJrXCIsIG1hcms6IHRoaXMubWFyay50b0pTT04oKSxcbiAgICAgICAgICAgIGZyb206IHRoaXMuZnJvbSwgdG86IHRoaXMudG8gfTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5mcm9tICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24udG8gIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgQWRkTWFya1N0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgQWRkTWFya1N0ZXAoanNvbi5mcm9tLCBqc29uLnRvLCBzY2hlbWEubWFya0Zyb21KU09OKGpzb24ubWFyaykpO1xuICAgIH1cbn1cblN0ZXAuanNvbklEKFwiYWRkTWFya1wiLCBBZGRNYXJrU3RlcCk7XG4vKipcblJlbW92ZSBhIG1hcmsgZnJvbSBhbGwgaW5saW5lIGNvbnRlbnQgYmV0d2VlbiB0d28gcG9zaXRpb25zLlxuKi9cbmNsYXNzIFJlbW92ZU1hcmtTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbWFyay1yZW1vdmluZyBzdGVwLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHN0YXJ0IG9mIHRoZSB1bm1hcmtlZCByYW5nZS5cbiAgICAqL1xuICAgIGZyb20sIFxuICAgIC8qKlxuICAgIFRoZSBlbmQgb2YgdGhlIHVubWFya2VkIHJhbmdlLlxuICAgICovXG4gICAgdG8sIFxuICAgIC8qKlxuICAgIFRoZSBtYXJrIHRvIHJlbW92ZS5cbiAgICAqL1xuICAgIG1hcmspIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICAgICAgdGhpcy50byA9IHRvO1xuICAgICAgICB0aGlzLm1hcmsgPSBtYXJrO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgbGV0IG9sZFNsaWNlID0gZG9jLnNsaWNlKHRoaXMuZnJvbSwgdGhpcy50byk7XG4gICAgICAgIGxldCBzbGljZSA9IG5ldyBTbGljZShtYXBGcmFnbWVudChvbGRTbGljZS5jb250ZW50LCBub2RlID0+IHtcbiAgICAgICAgICAgIHJldHVybiBub2RlLm1hcmsodGhpcy5tYXJrLnJlbW92ZUZyb21TZXQobm9kZS5tYXJrcykpO1xuICAgICAgICB9LCBkb2MpLCBvbGRTbGljZS5vcGVuU3RhcnQsIG9sZFNsaWNlLm9wZW5FbmQpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMuZnJvbSwgdGhpcy50bywgc2xpY2UpO1xuICAgIH1cbiAgICBpbnZlcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgQWRkTWFya1N0ZXAodGhpcy5mcm9tLCB0aGlzLnRvLCB0aGlzLm1hcmspO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICBsZXQgZnJvbSA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMuZnJvbSwgMSksIHRvID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy50bywgLTEpO1xuICAgICAgICBpZiAoZnJvbS5kZWxldGVkICYmIHRvLmRlbGV0ZWQgfHwgZnJvbS5wb3MgPj0gdG8ucG9zKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBuZXcgUmVtb3ZlTWFya1N0ZXAoZnJvbS5wb3MsIHRvLnBvcywgdGhpcy5tYXJrKTtcbiAgICB9XG4gICAgbWVyZ2Uob3RoZXIpIHtcbiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgUmVtb3ZlTWFya1N0ZXAgJiZcbiAgICAgICAgICAgIG90aGVyLm1hcmsuZXEodGhpcy5tYXJrKSAmJlxuICAgICAgICAgICAgdGhpcy5mcm9tIDw9IG90aGVyLnRvICYmIHRoaXMudG8gPj0gb3RoZXIuZnJvbSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVtb3ZlTWFya1N0ZXAoTWF0aC5taW4odGhpcy5mcm9tLCBvdGhlci5mcm9tKSwgTWF0aC5tYXgodGhpcy50bywgb3RoZXIudG8pLCB0aGlzLm1hcmspO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyBzdGVwVHlwZTogXCJyZW1vdmVNYXJrXCIsIG1hcms6IHRoaXMubWFyay50b0pTT04oKSxcbiAgICAgICAgICAgIGZyb206IHRoaXMuZnJvbSwgdG86IHRoaXMudG8gfTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5mcm9tICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24udG8gIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgUmVtb3ZlTWFya1N0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgUmVtb3ZlTWFya1N0ZXAoanNvbi5mcm9tLCBqc29uLnRvLCBzY2hlbWEubWFya0Zyb21KU09OKGpzb24ubWFyaykpO1xuICAgIH1cbn1cblN0ZXAuanNvbklEKFwicmVtb3ZlTWFya1wiLCBSZW1vdmVNYXJrU3RlcCk7XG4vKipcbkFkZCBhIG1hcmsgdG8gYSBzcGVjaWZpYyBub2RlLlxuKi9cbmNsYXNzIEFkZE5vZGVNYXJrU3RlcCBleHRlbmRzIFN0ZXAge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5vZGUgbWFyayBzdGVwLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHBvc2l0aW9uIG9mIHRoZSB0YXJnZXQgbm9kZS5cbiAgICAqL1xuICAgIHBvcywgXG4gICAgLyoqXG4gICAgVGhlIG1hcmsgdG8gYWRkLlxuICAgICovXG4gICAgbWFyaykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnBvcyA9IHBvcztcbiAgICAgICAgdGhpcy5tYXJrID0gbWFyaztcbiAgICB9XG4gICAgYXBwbHkoZG9jKSB7XG4gICAgICAgIGxldCBub2RlID0gZG9jLm5vZGVBdCh0aGlzLnBvcyk7XG4gICAgICAgIGlmICghbm9kZSlcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZhaWwoXCJObyBub2RlIGF0IG1hcmsgc3RlcCdzIHBvc2l0aW9uXCIpO1xuICAgICAgICBsZXQgdXBkYXRlZCA9IG5vZGUudHlwZS5jcmVhdGUobm9kZS5hdHRycywgbnVsbCwgdGhpcy5tYXJrLmFkZFRvU2V0KG5vZGUubWFya3MpKTtcbiAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZnJvbVJlcGxhY2UoZG9jLCB0aGlzLnBvcywgdGhpcy5wb3MgKyAxLCBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbSh1cGRhdGVkKSwgMCwgbm9kZS5pc0xlYWYgPyAwIDogMSkpO1xuICAgIH1cbiAgICBpbnZlcnQoZG9jKSB7XG4gICAgICAgIGxldCBub2RlID0gZG9jLm5vZGVBdCh0aGlzLnBvcyk7XG4gICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgICBsZXQgbmV3U2V0ID0gdGhpcy5tYXJrLmFkZFRvU2V0KG5vZGUubWFya3MpO1xuICAgICAgICAgICAgaWYgKG5ld1NldC5sZW5ndGggPT0gbm9kZS5tYXJrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGUubWFya3MubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9kZS5tYXJrc1tpXS5pc0luU2V0KG5ld1NldCkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFkZE5vZGVNYXJrU3RlcCh0aGlzLnBvcywgbm9kZS5tYXJrc1tpXSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBZGROb2RlTWFya1N0ZXAodGhpcy5wb3MsIHRoaXMubWFyayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBSZW1vdmVOb2RlTWFya1N0ZXAodGhpcy5wb3MsIHRoaXMubWFyayk7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nKSB7XG4gICAgICAgIGxldCBwb3MgPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLnBvcywgMSk7XG4gICAgICAgIHJldHVybiBwb3MuZGVsZXRlZEFmdGVyID8gbnVsbCA6IG5ldyBBZGROb2RlTWFya1N0ZXAocG9zLnBvcywgdGhpcy5tYXJrKTtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyBzdGVwVHlwZTogXCJhZGROb2RlTWFya1wiLCBwb3M6IHRoaXMucG9zLCBtYXJrOiB0aGlzLm1hcmsudG9KU09OKCkgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5wb3MgIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgQWRkTm9kZU1hcmtTdGVwLmZyb21KU09OXCIpO1xuICAgICAgICByZXR1cm4gbmV3IEFkZE5vZGVNYXJrU3RlcChqc29uLnBvcywgc2NoZW1hLm1hcmtGcm9tSlNPTihqc29uLm1hcmspKTtcbiAgICB9XG59XG5TdGVwLmpzb25JRChcImFkZE5vZGVNYXJrXCIsIEFkZE5vZGVNYXJrU3RlcCk7XG4vKipcblJlbW92ZSBhIG1hcmsgZnJvbSBhIHNwZWNpZmljIG5vZGUuXG4qL1xuY2xhc3MgUmVtb3ZlTm9kZU1hcmtTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbWFyay1yZW1vdmluZyBzdGVwLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHBvc2l0aW9uIG9mIHRoZSB0YXJnZXQgbm9kZS5cbiAgICAqL1xuICAgIHBvcywgXG4gICAgLyoqXG4gICAgVGhlIG1hcmsgdG8gcmVtb3ZlLlxuICAgICovXG4gICAgbWFyaykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnBvcyA9IHBvcztcbiAgICAgICAgdGhpcy5tYXJrID0gbWFyaztcbiAgICB9XG4gICAgYXBwbHkoZG9jKSB7XG4gICAgICAgIGxldCBub2RlID0gZG9jLm5vZGVBdCh0aGlzLnBvcyk7XG4gICAgICAgIGlmICghbm9kZSlcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZhaWwoXCJObyBub2RlIGF0IG1hcmsgc3RlcCdzIHBvc2l0aW9uXCIpO1xuICAgICAgICBsZXQgdXBkYXRlZCA9IG5vZGUudHlwZS5jcmVhdGUobm9kZS5hdHRycywgbnVsbCwgdGhpcy5tYXJrLnJlbW92ZUZyb21TZXQobm9kZS5tYXJrcykpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMucG9zLCB0aGlzLnBvcyArIDEsIG5ldyBTbGljZShGcmFnbWVudC5mcm9tKHVwZGF0ZWQpLCAwLCBub2RlLmlzTGVhZiA/IDAgOiAxKSk7XG4gICAgfVxuICAgIGludmVydChkb2MpIHtcbiAgICAgICAgbGV0IG5vZGUgPSBkb2Mubm9kZUF0KHRoaXMucG9zKTtcbiAgICAgICAgaWYgKCFub2RlIHx8ICF0aGlzLm1hcmsuaXNJblNldChub2RlLm1hcmtzKSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IEFkZE5vZGVNYXJrU3RlcCh0aGlzLnBvcywgdGhpcy5tYXJrKTtcbiAgICB9XG4gICAgbWFwKG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IHBvcyA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMucG9zLCAxKTtcbiAgICAgICAgcmV0dXJuIHBvcy5kZWxldGVkQWZ0ZXIgPyBudWxsIDogbmV3IFJlbW92ZU5vZGVNYXJrU3RlcChwb3MucG9zLCB0aGlzLm1hcmspO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB7IHN0ZXBUeXBlOiBcInJlbW92ZU5vZGVNYXJrXCIsIHBvczogdGhpcy5wb3MsIG1hcms6IHRoaXMubWFyay50b0pTT04oKSB9O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBqc29uLnBvcyAhPSBcIm51bWJlclwiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBSZW1vdmVOb2RlTWFya1N0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgUmVtb3ZlTm9kZU1hcmtTdGVwKGpzb24ucG9zLCBzY2hlbWEubWFya0Zyb21KU09OKGpzb24ubWFyaykpO1xuICAgIH1cbn1cblN0ZXAuanNvbklEKFwicmVtb3ZlTm9kZU1hcmtcIiwgUmVtb3ZlTm9kZU1hcmtTdGVwKTtcblxuLyoqXG5SZXBsYWNlIGEgcGFydCBvZiB0aGUgZG9jdW1lbnQgd2l0aCBhIHNsaWNlIG9mIG5ldyBjb250ZW50LlxuKi9cbmNsYXNzIFJlcGxhY2VTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgVGhlIGdpdmVuIGBzbGljZWAgc2hvdWxkIGZpdCB0aGUgJ2dhcCcgYmV0d2VlbiBgZnJvbWAgYW5kXG4gICAgYHRvYOKAlHRoZSBkZXB0aHMgbXVzdCBsaW5lIHVwLCBhbmQgdGhlIHN1cnJvdW5kaW5nIG5vZGVzIG11c3QgYmVcbiAgICBhYmxlIHRvIGJlIGpvaW5lZCB3aXRoIHRoZSBvcGVuIHNpZGVzIG9mIHRoZSBzbGljZS4gV2hlblxuICAgIGBzdHJ1Y3R1cmVgIGlzIHRydWUsIHRoZSBzdGVwIHdpbGwgZmFpbCBpZiB0aGUgY29udGVudCBiZXR3ZWVuXG4gICAgZnJvbSBhbmQgdG8gaXMgbm90IGp1c3QgYSBzZXF1ZW5jZSBvZiBjbG9zaW5nIGFuZCB0aGVuIG9wZW5pbmdcbiAgICB0b2tlbnMgKHRoaXMgaXMgdG8gZ3VhcmQgYWdhaW5zdCByZWJhc2VkIHJlcGxhY2Ugc3RlcHNcbiAgICBvdmVyd3JpdGluZyBzb21ldGhpbmcgdGhleSB3ZXJlbid0IHN1cHBvc2VkIHRvKS5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVwbGFjZWQgcmFuZ2UuXG4gICAgKi9cbiAgICBmcm9tLCBcbiAgICAvKipcbiAgICBUaGUgZW5kIHBvc2l0aW9uIG9mIHRoZSByZXBsYWNlZCByYW5nZS5cbiAgICAqL1xuICAgIHRvLCBcbiAgICAvKipcbiAgICBUaGUgc2xpY2UgdG8gaW5zZXJ0LlxuICAgICovXG4gICAgc2xpY2UsIFxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RydWN0dXJlID0gZmFsc2UpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICAgICAgdGhpcy50byA9IHRvO1xuICAgICAgICB0aGlzLnNsaWNlID0gc2xpY2U7XG4gICAgICAgIHRoaXMuc3RydWN0dXJlID0gc3RydWN0dXJlO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RydWN0dXJlICYmIGNvbnRlbnRCZXR3ZWVuKGRvYywgdGhpcy5mcm9tLCB0aGlzLnRvKSlcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZhaWwoXCJTdHJ1Y3R1cmUgcmVwbGFjZSB3b3VsZCBvdmVyd3JpdGUgY29udGVudFwiKTtcbiAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZnJvbVJlcGxhY2UoZG9jLCB0aGlzLmZyb20sIHRoaXMudG8sIHRoaXMuc2xpY2UpO1xuICAgIH1cbiAgICBnZXRNYXAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RlcE1hcChbdGhpcy5mcm9tLCB0aGlzLnRvIC0gdGhpcy5mcm9tLCB0aGlzLnNsaWNlLnNpemVdKTtcbiAgICB9XG4gICAgaW52ZXJ0KGRvYykge1xuICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VTdGVwKHRoaXMuZnJvbSwgdGhpcy5mcm9tICsgdGhpcy5zbGljZS5zaXplLCBkb2Muc2xpY2UodGhpcy5mcm9tLCB0aGlzLnRvKSk7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nKSB7XG4gICAgICAgIGxldCB0byA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMudG8sIC0xKTtcbiAgICAgICAgbGV0IGZyb20gPSB0aGlzLmZyb20gPT0gdGhpcy50byAmJiBSZXBsYWNlU3RlcC5NQVBfQklBUyA8IDAgPyB0byA6IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMuZnJvbSwgMSk7XG4gICAgICAgIGlmIChmcm9tLmRlbGV0ZWRBY3Jvc3MgJiYgdG8uZGVsZXRlZEFjcm9zcylcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VTdGVwKGZyb20ucG9zLCBNYXRoLm1heChmcm9tLnBvcywgdG8ucG9zKSwgdGhpcy5zbGljZSwgdGhpcy5zdHJ1Y3R1cmUpO1xuICAgIH1cbiAgICBtZXJnZShvdGhlcikge1xuICAgICAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFJlcGxhY2VTdGVwKSB8fCBvdGhlci5zdHJ1Y3R1cmUgfHwgdGhpcy5zdHJ1Y3R1cmUpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgaWYgKHRoaXMuZnJvbSArIHRoaXMuc2xpY2Uuc2l6ZSA9PSBvdGhlci5mcm9tICYmICF0aGlzLnNsaWNlLm9wZW5FbmQgJiYgIW90aGVyLnNsaWNlLm9wZW5TdGFydCkge1xuICAgICAgICAgICAgbGV0IHNsaWNlID0gdGhpcy5zbGljZS5zaXplICsgb3RoZXIuc2xpY2Uuc2l6ZSA9PSAwID8gU2xpY2UuZW1wdHlcbiAgICAgICAgICAgICAgICA6IG5ldyBTbGljZSh0aGlzLnNsaWNlLmNvbnRlbnQuYXBwZW5kKG90aGVyLnNsaWNlLmNvbnRlbnQpLCB0aGlzLnNsaWNlLm9wZW5TdGFydCwgb3RoZXIuc2xpY2Uub3BlbkVuZCk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VTdGVwKHRoaXMuZnJvbSwgdGhpcy50byArIChvdGhlci50byAtIG90aGVyLmZyb20pLCBzbGljZSwgdGhpcy5zdHJ1Y3R1cmUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG90aGVyLnRvID09IHRoaXMuZnJvbSAmJiAhdGhpcy5zbGljZS5vcGVuU3RhcnQgJiYgIW90aGVyLnNsaWNlLm9wZW5FbmQpIHtcbiAgICAgICAgICAgIGxldCBzbGljZSA9IHRoaXMuc2xpY2Uuc2l6ZSArIG90aGVyLnNsaWNlLnNpemUgPT0gMCA/IFNsaWNlLmVtcHR5XG4gICAgICAgICAgICAgICAgOiBuZXcgU2xpY2Uob3RoZXIuc2xpY2UuY29udGVudC5hcHBlbmQodGhpcy5zbGljZS5jb250ZW50KSwgb3RoZXIuc2xpY2Uub3BlblN0YXJ0LCB0aGlzLnNsaWNlLm9wZW5FbmQpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXBsYWNlU3RlcChvdGhlci5mcm9tLCB0aGlzLnRvLCBzbGljZSwgdGhpcy5zdHJ1Y3R1cmUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICBsZXQganNvbiA9IHsgc3RlcFR5cGU6IFwicmVwbGFjZVwiLCBmcm9tOiB0aGlzLmZyb20sIHRvOiB0aGlzLnRvIH07XG4gICAgICAgIGlmICh0aGlzLnNsaWNlLnNpemUpXG4gICAgICAgICAgICBqc29uLnNsaWNlID0gdGhpcy5zbGljZS50b0pTT04oKTtcbiAgICAgICAgaWYgKHRoaXMuc3RydWN0dXJlKVxuICAgICAgICAgICAganNvbi5zdHJ1Y3R1cmUgPSB0cnVlO1xuICAgICAgICByZXR1cm4ganNvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5mcm9tICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24udG8gIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgUmVwbGFjZVN0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgUmVwbGFjZVN0ZXAoanNvbi5mcm9tLCBqc29uLnRvLCBTbGljZS5mcm9tSlNPTihzY2hlbWEsIGpzb24uc2xpY2UpLCAhIWpzb24uc3RydWN0dXJlKTtcbiAgICB9XG59XG4vKipcbkJ5IGRlZmF1bHQsIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgYW4gaW5zZXJ0aW5nIHN0ZXBcbm1hcHBlZCBvdmVyIGFuIGluc2VydGlvbiBhdCB0aGF0IHNhbWUgcG9zaXRpb24gZmlsbCBtb3ZlIGFmdGVyXG50aGUgaW5zZXJ0ZWQgY29udGVudC4gSW4gYSBjb2xsYWJvcmF0aXZlIGVkaXRpbmcgc2l0dWF0aW9uLCB0aGF0XG5jYW4gbWFrZSByZWRvbmUgaW5zZXJ0aW9ucyBhcHBlYXIgaW4gdW5leHBlY3RlZCBwbGFjZXMuIFlvdSBjYW5cbnNldCB0aGlzIHRvIC0xIHRvIG1ha2Ugc3VjaCBtYXBwaW5nIGtlZXAgdGhlIHN0ZXAgYmVmb3JlIHRoZVxuaW5zZXJ0aW9uIGluc3RlYWQuXG4qL1xuUmVwbGFjZVN0ZXAuTUFQX0JJQVMgPSAxO1xuU3RlcC5qc29uSUQoXCJyZXBsYWNlXCIsIFJlcGxhY2VTdGVwKTtcbi8qKlxuUmVwbGFjZSBhIHBhcnQgb2YgdGhlIGRvY3VtZW50IHdpdGggYSBzbGljZSBvZiBjb250ZW50LCBidXRcbnByZXNlcnZlIGEgcmFuZ2Ugb2YgdGhlIHJlcGxhY2VkIGNvbnRlbnQgYnkgbW92aW5nIGl0IGludG8gdGhlXG5zbGljZS5cbiovXG5jbGFzcyBSZXBsYWNlQXJvdW5kU3RlcCBleHRlbmRzIFN0ZXAge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIHJlcGxhY2UtYXJvdW5kIHN0ZXAgd2l0aCB0aGUgZ2l2ZW4gcmFuZ2UgYW5kIGdhcC5cbiAgICBgaW5zZXJ0YCBzaG91bGQgYmUgdGhlIHBvaW50IGluIHRoZSBzbGljZSBpbnRvIHdoaWNoIHRoZSBjb250ZW50XG4gICAgb2YgdGhlIGdhcCBzaG91bGQgYmUgbW92ZWQuIGBzdHJ1Y3R1cmVgIGhhcyB0aGUgc2FtZSBtZWFuaW5nIGFzXG4gICAgaXQgaGFzIGluIHRoZSBbYFJlcGxhY2VTdGVwYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5SZXBsYWNlU3RlcCkgY2xhc3MuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHJlcGxhY2VkIHJhbmdlLlxuICAgICovXG4gICAgZnJvbSwgXG4gICAgLyoqXG4gICAgVGhlIGVuZCBwb3NpdGlvbiBvZiB0aGUgcmVwbGFjZWQgcmFuZ2UuXG4gICAgKi9cbiAgICB0bywgXG4gICAgLyoqXG4gICAgVGhlIHN0YXJ0IG9mIHByZXNlcnZlZCByYW5nZS5cbiAgICAqL1xuICAgIGdhcEZyb20sIFxuICAgIC8qKlxuICAgIFRoZSBlbmQgb2YgcHJlc2VydmVkIHJhbmdlLlxuICAgICovXG4gICAgZ2FwVG8sIFxuICAgIC8qKlxuICAgIFRoZSBzbGljZSB0byBpbnNlcnQuXG4gICAgKi9cbiAgICBzbGljZSwgXG4gICAgLyoqXG4gICAgVGhlIHBvc2l0aW9uIGluIHRoZSBzbGljZSB3aGVyZSB0aGUgcHJlc2VydmVkIHJhbmdlIHNob3VsZCBiZVxuICAgIGluc2VydGVkLlxuICAgICovXG4gICAgaW5zZXJ0LCBcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0cnVjdHVyZSA9IGZhbHNlKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgICAgIHRoaXMudG8gPSB0bztcbiAgICAgICAgdGhpcy5nYXBGcm9tID0gZ2FwRnJvbTtcbiAgICAgICAgdGhpcy5nYXBUbyA9IGdhcFRvO1xuICAgICAgICB0aGlzLnNsaWNlID0gc2xpY2U7XG4gICAgICAgIHRoaXMuaW5zZXJ0ID0gaW5zZXJ0O1xuICAgICAgICB0aGlzLnN0cnVjdHVyZSA9IHN0cnVjdHVyZTtcbiAgICB9XG4gICAgYXBwbHkoZG9jKSB7XG4gICAgICAgIGlmICh0aGlzLnN0cnVjdHVyZSAmJiAoY29udGVudEJldHdlZW4oZG9jLCB0aGlzLmZyb20sIHRoaXMuZ2FwRnJvbSkgfHxcbiAgICAgICAgICAgIGNvbnRlbnRCZXR3ZWVuKGRvYywgdGhpcy5nYXBUbywgdGhpcy50bykpKVxuICAgICAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZmFpbChcIlN0cnVjdHVyZSBnYXAtcmVwbGFjZSB3b3VsZCBvdmVyd3JpdGUgY29udGVudFwiKTtcbiAgICAgICAgbGV0IGdhcCA9IGRvYy5zbGljZSh0aGlzLmdhcEZyb20sIHRoaXMuZ2FwVG8pO1xuICAgICAgICBpZiAoZ2FwLm9wZW5TdGFydCB8fCBnYXAub3BlbkVuZClcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZhaWwoXCJHYXAgaXMgbm90IGEgZmxhdCByYW5nZVwiKTtcbiAgICAgICAgbGV0IGluc2VydGVkID0gdGhpcy5zbGljZS5pbnNlcnRBdCh0aGlzLmluc2VydCwgZ2FwLmNvbnRlbnQpO1xuICAgICAgICBpZiAoIWluc2VydGVkKVxuICAgICAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZmFpbChcIkNvbnRlbnQgZG9lcyBub3QgZml0IGluIGdhcFwiKTtcbiAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZnJvbVJlcGxhY2UoZG9jLCB0aGlzLmZyb20sIHRoaXMudG8sIGluc2VydGVkKTtcbiAgICB9XG4gICAgZ2V0TWFwKCkge1xuICAgICAgICByZXR1cm4gbmV3IFN0ZXBNYXAoW3RoaXMuZnJvbSwgdGhpcy5nYXBGcm9tIC0gdGhpcy5mcm9tLCB0aGlzLmluc2VydCxcbiAgICAgICAgICAgIHRoaXMuZ2FwVG8sIHRoaXMudG8gLSB0aGlzLmdhcFRvLCB0aGlzLnNsaWNlLnNpemUgLSB0aGlzLmluc2VydF0pO1xuICAgIH1cbiAgICBpbnZlcnQoZG9jKSB7XG4gICAgICAgIGxldCBnYXAgPSB0aGlzLmdhcFRvIC0gdGhpcy5nYXBGcm9tO1xuICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VBcm91bmRTdGVwKHRoaXMuZnJvbSwgdGhpcy5mcm9tICsgdGhpcy5zbGljZS5zaXplICsgZ2FwLCB0aGlzLmZyb20gKyB0aGlzLmluc2VydCwgdGhpcy5mcm9tICsgdGhpcy5pbnNlcnQgKyBnYXAsIGRvYy5zbGljZSh0aGlzLmZyb20sIHRoaXMudG8pLnJlbW92ZUJldHdlZW4odGhpcy5nYXBGcm9tIC0gdGhpcy5mcm9tLCB0aGlzLmdhcFRvIC0gdGhpcy5mcm9tKSwgdGhpcy5nYXBGcm9tIC0gdGhpcy5mcm9tLCB0aGlzLnN0cnVjdHVyZSk7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nKSB7XG4gICAgICAgIGxldCBmcm9tID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy5mcm9tLCAxKSwgdG8gPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLnRvLCAtMSk7XG4gICAgICAgIGxldCBnYXBGcm9tID0gdGhpcy5mcm9tID09IHRoaXMuZ2FwRnJvbSA/IGZyb20ucG9zIDogbWFwcGluZy5tYXAodGhpcy5nYXBGcm9tLCAtMSk7XG4gICAgICAgIGxldCBnYXBUbyA9IHRoaXMudG8gPT0gdGhpcy5nYXBUbyA/IHRvLnBvcyA6IG1hcHBpbmcubWFwKHRoaXMuZ2FwVG8sIDEpO1xuICAgICAgICBpZiAoKGZyb20uZGVsZXRlZEFjcm9zcyAmJiB0by5kZWxldGVkQWNyb3NzKSB8fCBnYXBGcm9tIDwgZnJvbS5wb3MgfHwgZ2FwVG8gPiB0by5wb3MpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBsYWNlQXJvdW5kU3RlcChmcm9tLnBvcywgdG8ucG9zLCBnYXBGcm9tLCBnYXBUbywgdGhpcy5zbGljZSwgdGhpcy5pbnNlcnQsIHRoaXMuc3RydWN0dXJlKTtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICBsZXQganNvbiA9IHsgc3RlcFR5cGU6IFwicmVwbGFjZUFyb3VuZFwiLCBmcm9tOiB0aGlzLmZyb20sIHRvOiB0aGlzLnRvLFxuICAgICAgICAgICAgZ2FwRnJvbTogdGhpcy5nYXBGcm9tLCBnYXBUbzogdGhpcy5nYXBUbywgaW5zZXJ0OiB0aGlzLmluc2VydCB9O1xuICAgICAgICBpZiAodGhpcy5zbGljZS5zaXplKVxuICAgICAgICAgICAganNvbi5zbGljZSA9IHRoaXMuc2xpY2UudG9KU09OKCk7XG4gICAgICAgIGlmICh0aGlzLnN0cnVjdHVyZSlcbiAgICAgICAgICAgIGpzb24uc3RydWN0dXJlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGpzb247XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKHNjaGVtYSwganNvbikge1xuICAgICAgICBpZiAodHlwZW9mIGpzb24uZnJvbSAhPSBcIm51bWJlclwiIHx8IHR5cGVvZiBqc29uLnRvICE9IFwibnVtYmVyXCIgfHxcbiAgICAgICAgICAgIHR5cGVvZiBqc29uLmdhcEZyb20gIT0gXCJudW1iZXJcIiB8fCB0eXBlb2YganNvbi5nYXBUbyAhPSBcIm51bWJlclwiIHx8IHR5cGVvZiBqc29uLmluc2VydCAhPSBcIm51bWJlclwiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBSZXBsYWNlQXJvdW5kU3RlcC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBsYWNlQXJvdW5kU3RlcChqc29uLmZyb20sIGpzb24udG8sIGpzb24uZ2FwRnJvbSwganNvbi5nYXBUbywgU2xpY2UuZnJvbUpTT04oc2NoZW1hLCBqc29uLnNsaWNlKSwganNvbi5pbnNlcnQsICEhanNvbi5zdHJ1Y3R1cmUpO1xuICAgIH1cbn1cblN0ZXAuanNvbklEKFwicmVwbGFjZUFyb3VuZFwiLCBSZXBsYWNlQXJvdW5kU3RlcCk7XG5mdW5jdGlvbiBjb250ZW50QmV0d2Vlbihkb2MsIGZyb20sIHRvKSB7XG4gICAgbGV0ICRmcm9tID0gZG9jLnJlc29sdmUoZnJvbSksIGRpc3QgPSB0byAtIGZyb20sIGRlcHRoID0gJGZyb20uZGVwdGg7XG4gICAgd2hpbGUgKGRpc3QgPiAwICYmIGRlcHRoID4gMCAmJiAkZnJvbS5pbmRleEFmdGVyKGRlcHRoKSA9PSAkZnJvbS5ub2RlKGRlcHRoKS5jaGlsZENvdW50KSB7XG4gICAgICAgIGRlcHRoLS07XG4gICAgICAgIGRpc3QtLTtcbiAgICB9XG4gICAgaWYgKGRpc3QgPiAwKSB7XG4gICAgICAgIGxldCBuZXh0ID0gJGZyb20ubm9kZShkZXB0aCkubWF5YmVDaGlsZCgkZnJvbS5pbmRleEFmdGVyKGRlcHRoKSk7XG4gICAgICAgIHdoaWxlIChkaXN0ID4gMCkge1xuICAgICAgICAgICAgaWYgKCFuZXh0IHx8IG5leHQuaXNMZWFmKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgbmV4dCA9IG5leHQuZmlyc3RDaGlsZDtcbiAgICAgICAgICAgIGRpc3QtLTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGFkZE1hcmsodHIsIGZyb20sIHRvLCBtYXJrKSB7XG4gICAgbGV0IHJlbW92ZWQgPSBbXSwgYWRkZWQgPSBbXTtcbiAgICBsZXQgcmVtb3ZpbmcsIGFkZGluZztcbiAgICB0ci5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zLCBwYXJlbnQpID0+IHtcbiAgICAgICAgaWYgKCFub2RlLmlzSW5saW5lKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBsZXQgbWFya3MgPSBub2RlLm1hcmtzO1xuICAgICAgICBpZiAoIW1hcmsuaXNJblNldChtYXJrcykgJiYgcGFyZW50LnR5cGUuYWxsb3dzTWFya1R5cGUobWFyay50eXBlKSkge1xuICAgICAgICAgICAgbGV0IHN0YXJ0ID0gTWF0aC5tYXgocG9zLCBmcm9tKSwgZW5kID0gTWF0aC5taW4ocG9zICsgbm9kZS5ub2RlU2l6ZSwgdG8pO1xuICAgICAgICAgICAgbGV0IG5ld1NldCA9IG1hcmsuYWRkVG9TZXQobWFya3MpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghbWFya3NbaV0uaXNJblNldChuZXdTZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW1vdmluZyAmJiByZW1vdmluZy50byA9PSBzdGFydCAmJiByZW1vdmluZy5tYXJrLmVxKG1hcmtzW2ldKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92aW5nLnRvID0gZW5kO1xuICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmVkLnB1c2gocmVtb3ZpbmcgPSBuZXcgUmVtb3ZlTWFya1N0ZXAoc3RhcnQsIGVuZCwgbWFya3NbaV0pKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYWRkaW5nICYmIGFkZGluZy50byA9PSBzdGFydClcbiAgICAgICAgICAgICAgICBhZGRpbmcudG8gPSBlbmQ7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgYWRkZWQucHVzaChhZGRpbmcgPSBuZXcgQWRkTWFya1N0ZXAoc3RhcnQsIGVuZCwgbWFyaykpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmVtb3ZlZC5mb3JFYWNoKHMgPT4gdHIuc3RlcChzKSk7XG4gICAgYWRkZWQuZm9yRWFjaChzID0+IHRyLnN0ZXAocykpO1xufVxuZnVuY3Rpb24gcmVtb3ZlTWFyayh0ciwgZnJvbSwgdG8sIG1hcmspIHtcbiAgICBsZXQgbWF0Y2hlZCA9IFtdLCBzdGVwID0gMDtcbiAgICB0ci5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgIGlmICghbm9kZS5pc0lubGluZSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgc3RlcCsrO1xuICAgICAgICBsZXQgdG9SZW1vdmUgPSBudWxsO1xuICAgICAgICBpZiAobWFyayBpbnN0YW5jZW9mIE1hcmtUeXBlKSB7XG4gICAgICAgICAgICBsZXQgc2V0ID0gbm9kZS5tYXJrcywgZm91bmQ7XG4gICAgICAgICAgICB3aGlsZSAoZm91bmQgPSBtYXJrLmlzSW5TZXQoc2V0KSkge1xuICAgICAgICAgICAgICAgICh0b1JlbW92ZSB8fCAodG9SZW1vdmUgPSBbXSkpLnB1c2goZm91bmQpO1xuICAgICAgICAgICAgICAgIHNldCA9IGZvdW5kLnJlbW92ZUZyb21TZXQoc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChtYXJrKSB7XG4gICAgICAgICAgICBpZiAobWFyay5pc0luU2V0KG5vZGUubWFya3MpKVxuICAgICAgICAgICAgICAgIHRvUmVtb3ZlID0gW21hcmtdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdG9SZW1vdmUgPSBub2RlLm1hcmtzO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b1JlbW92ZSAmJiB0b1JlbW92ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGxldCBlbmQgPSBNYXRoLm1pbihwb3MgKyBub2RlLm5vZGVTaXplLCB0byk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRvUmVtb3ZlLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0eWxlID0gdG9SZW1vdmVbaV0sIGZvdW5kO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbWF0Y2hlZC5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbSA9IG1hdGNoZWRbal07XG4gICAgICAgICAgICAgICAgICAgIGlmIChtLnN0ZXAgPT0gc3RlcCAtIDEgJiYgc3R5bGUuZXEobWF0Y2hlZFtqXS5zdHlsZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IG07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICAgICAgICAgICAgICBmb3VuZC50byA9IGVuZDtcbiAgICAgICAgICAgICAgICAgICAgZm91bmQuc3RlcCA9IHN0ZXA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBtYXRjaGVkLnB1c2goeyBzdHlsZSwgZnJvbTogTWF0aC5tYXgocG9zLCBmcm9tKSwgdG86IGVuZCwgc3RlcCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBtYXRjaGVkLmZvckVhY2gobSA9PiB0ci5zdGVwKG5ldyBSZW1vdmVNYXJrU3RlcChtLmZyb20sIG0udG8sIG0uc3R5bGUpKSk7XG59XG5mdW5jdGlvbiBjbGVhckluY29tcGF0aWJsZSh0ciwgcG9zLCBwYXJlbnRUeXBlLCBtYXRjaCA9IHBhcmVudFR5cGUuY29udGVudE1hdGNoLCBjbGVhck5ld2xpbmVzID0gdHJ1ZSkge1xuICAgIGxldCBub2RlID0gdHIuZG9jLm5vZGVBdChwb3MpO1xuICAgIGxldCByZXBsU3RlcHMgPSBbXSwgY3VyID0gcG9zICsgMTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGUuY2hpbGRDb3VudDsgaSsrKSB7XG4gICAgICAgIGxldCBjaGlsZCA9IG5vZGUuY2hpbGQoaSksIGVuZCA9IGN1ciArIGNoaWxkLm5vZGVTaXplO1xuICAgICAgICBsZXQgYWxsb3dlZCA9IG1hdGNoLm1hdGNoVHlwZShjaGlsZC50eXBlKTtcbiAgICAgICAgaWYgKCFhbGxvd2VkKSB7XG4gICAgICAgICAgICByZXBsU3RlcHMucHVzaChuZXcgUmVwbGFjZVN0ZXAoY3VyLCBlbmQsIFNsaWNlLmVtcHR5KSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBtYXRjaCA9IGFsbG93ZWQ7XG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNoaWxkLm1hcmtzLmxlbmd0aDsgaisrKVxuICAgICAgICAgICAgICAgIGlmICghcGFyZW50VHlwZS5hbGxvd3NNYXJrVHlwZShjaGlsZC5tYXJrc1tqXS50eXBlKSlcbiAgICAgICAgICAgICAgICAgICAgdHIuc3RlcChuZXcgUmVtb3ZlTWFya1N0ZXAoY3VyLCBlbmQsIGNoaWxkLm1hcmtzW2pdKSk7XG4gICAgICAgICAgICBpZiAoY2xlYXJOZXdsaW5lcyAmJiBjaGlsZC5pc1RleHQgJiYgcGFyZW50VHlwZS53aGl0ZXNwYWNlICE9IFwicHJlXCIpIHtcbiAgICAgICAgICAgICAgICBsZXQgbSwgbmV3bGluZSA9IC9cXHI/XFxufFxcci9nLCBzbGljZTtcbiAgICAgICAgICAgICAgICB3aGlsZSAobSA9IG5ld2xpbmUuZXhlYyhjaGlsZC50ZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXNsaWNlKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2xpY2UgPSBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbShwYXJlbnRUeXBlLnNjaGVtYS50ZXh0KFwiIFwiLCBwYXJlbnRUeXBlLmFsbG93ZWRNYXJrcyhjaGlsZC5tYXJrcykpKSwgMCwgMCk7XG4gICAgICAgICAgICAgICAgICAgIHJlcGxTdGVwcy5wdXNoKG5ldyBSZXBsYWNlU3RlcChjdXIgKyBtLmluZGV4LCBjdXIgKyBtLmluZGV4ICsgbVswXS5sZW5ndGgsIHNsaWNlKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGN1ciA9IGVuZDtcbiAgICB9XG4gICAgaWYgKCFtYXRjaC52YWxpZEVuZCkge1xuICAgICAgICBsZXQgZmlsbCA9IG1hdGNoLmZpbGxCZWZvcmUoRnJhZ21lbnQuZW1wdHksIHRydWUpO1xuICAgICAgICB0ci5yZXBsYWNlKGN1ciwgY3VyLCBuZXcgU2xpY2UoZmlsbCwgMCwgMCkpO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gcmVwbFN0ZXBzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKVxuICAgICAgICB0ci5zdGVwKHJlcGxTdGVwc1tpXSk7XG59XG5cbmZ1bmN0aW9uIGNhbkN1dChub2RlLCBzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIChzdGFydCA9PSAwIHx8IG5vZGUuY2FuUmVwbGFjZShzdGFydCwgbm9kZS5jaGlsZENvdW50KSkgJiZcbiAgICAgICAgKGVuZCA9PSBub2RlLmNoaWxkQ291bnQgfHwgbm9kZS5jYW5SZXBsYWNlKDAsIGVuZCkpO1xufVxuLyoqXG5UcnkgdG8gZmluZCBhIHRhcmdldCBkZXB0aCB0byB3aGljaCB0aGUgY29udGVudCBpbiB0aGUgZ2l2ZW4gcmFuZ2VcbmNhbiBiZSBsaWZ0ZWQuIFdpbGwgbm90IGdvIGFjcm9zc1xuW2lzb2xhdGluZ10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmlzb2xhdGluZykgcGFyZW50IG5vZGVzLlxuKi9cbmZ1bmN0aW9uIGxpZnRUYXJnZXQocmFuZ2UpIHtcbiAgICBsZXQgcGFyZW50ID0gcmFuZ2UucGFyZW50O1xuICAgIGxldCBjb250ZW50ID0gcGFyZW50LmNvbnRlbnQuY3V0QnlJbmRleChyYW5nZS5zdGFydEluZGV4LCByYW5nZS5lbmRJbmRleCk7XG4gICAgZm9yIChsZXQgZGVwdGggPSByYW5nZS5kZXB0aCwgY29udGVudEJlZm9yZSA9IDAsIGNvbnRlbnRBZnRlciA9IDA7OyAtLWRlcHRoKSB7XG4gICAgICAgIGxldCBub2RlID0gcmFuZ2UuJGZyb20ubm9kZShkZXB0aCk7XG4gICAgICAgIGxldCBpbmRleCA9IHJhbmdlLiRmcm9tLmluZGV4KGRlcHRoKSArIGNvbnRlbnRCZWZvcmUsIGVuZEluZGV4ID0gcmFuZ2UuJHRvLmluZGV4QWZ0ZXIoZGVwdGgpIC0gY29udGVudEFmdGVyO1xuICAgICAgICBpZiAoZGVwdGggPCByYW5nZS5kZXB0aCAmJiBub2RlLmNhblJlcGxhY2UoaW5kZXgsIGVuZEluZGV4LCBjb250ZW50KSlcbiAgICAgICAgICAgIHJldHVybiBkZXB0aDtcbiAgICAgICAgaWYgKGRlcHRoID09IDAgfHwgbm9kZS50eXBlLnNwZWMuaXNvbGF0aW5nIHx8ICFjYW5DdXQobm9kZSwgaW5kZXgsIGVuZEluZGV4KSlcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBpZiAoaW5kZXgpXG4gICAgICAgICAgICBjb250ZW50QmVmb3JlID0gMTtcbiAgICAgICAgaWYgKGVuZEluZGV4IDwgbm9kZS5jaGlsZENvdW50KVxuICAgICAgICAgICAgY29udGVudEFmdGVyID0gMTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBsaWZ0KHRyLCByYW5nZSwgdGFyZ2V0KSB7XG4gICAgbGV0IHsgJGZyb20sICR0bywgZGVwdGggfSA9IHJhbmdlO1xuICAgIGxldCBnYXBTdGFydCA9ICRmcm9tLmJlZm9yZShkZXB0aCArIDEpLCBnYXBFbmQgPSAkdG8uYWZ0ZXIoZGVwdGggKyAxKTtcbiAgICBsZXQgc3RhcnQgPSBnYXBTdGFydCwgZW5kID0gZ2FwRW5kO1xuICAgIGxldCBiZWZvcmUgPSBGcmFnbWVudC5lbXB0eSwgb3BlblN0YXJ0ID0gMDtcbiAgICBmb3IgKGxldCBkID0gZGVwdGgsIHNwbGl0dGluZyA9IGZhbHNlOyBkID4gdGFyZ2V0OyBkLS0pXG4gICAgICAgIGlmIChzcGxpdHRpbmcgfHwgJGZyb20uaW5kZXgoZCkgPiAwKSB7XG4gICAgICAgICAgICBzcGxpdHRpbmcgPSB0cnVlO1xuICAgICAgICAgICAgYmVmb3JlID0gRnJhZ21lbnQuZnJvbSgkZnJvbS5ub2RlKGQpLmNvcHkoYmVmb3JlKSk7XG4gICAgICAgICAgICBvcGVuU3RhcnQrKztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN0YXJ0LS07XG4gICAgICAgIH1cbiAgICBsZXQgYWZ0ZXIgPSBGcmFnbWVudC5lbXB0eSwgb3BlbkVuZCA9IDA7XG4gICAgZm9yIChsZXQgZCA9IGRlcHRoLCBzcGxpdHRpbmcgPSBmYWxzZTsgZCA+IHRhcmdldDsgZC0tKVxuICAgICAgICBpZiAoc3BsaXR0aW5nIHx8ICR0by5hZnRlcihkICsgMSkgPCAkdG8uZW5kKGQpKSB7XG4gICAgICAgICAgICBzcGxpdHRpbmcgPSB0cnVlO1xuICAgICAgICAgICAgYWZ0ZXIgPSBGcmFnbWVudC5mcm9tKCR0by5ub2RlKGQpLmNvcHkoYWZ0ZXIpKTtcbiAgICAgICAgICAgIG9wZW5FbmQrKztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGVuZCsrO1xuICAgICAgICB9XG4gICAgdHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAoc3RhcnQsIGVuZCwgZ2FwU3RhcnQsIGdhcEVuZCwgbmV3IFNsaWNlKGJlZm9yZS5hcHBlbmQoYWZ0ZXIpLCBvcGVuU3RhcnQsIG9wZW5FbmQpLCBiZWZvcmUuc2l6ZSAtIG9wZW5TdGFydCwgdHJ1ZSkpO1xufVxuLyoqXG5UcnkgdG8gZmluZCBhIHZhbGlkIHdheSB0byB3cmFwIHRoZSBjb250ZW50IGluIHRoZSBnaXZlbiByYW5nZSBpbiBhXG5ub2RlIG9mIHRoZSBnaXZlbiB0eXBlLiBNYXkgaW50cm9kdWNlIGV4dHJhIG5vZGVzIGFyb3VuZCBhbmQgaW5zaWRlXG50aGUgd3JhcHBlciBub2RlLCBpZiBuZWNlc3NhcnkuIFJldHVybnMgbnVsbCBpZiBubyB2YWxpZCB3cmFwcGluZ1xuY291bGQgYmUgZm91bmQuIFdoZW4gYGlubmVyUmFuZ2VgIGlzIGdpdmVuLCB0aGF0IHJhbmdlJ3MgY29udGVudCBpc1xudXNlZCBhcyB0aGUgY29udGVudCB0byBmaXQgaW50byB0aGUgd3JhcHBpbmcsIGluc3RlYWQgb2YgdGhlXG5jb250ZW50IG9mIGByYW5nZWAuXG4qL1xuZnVuY3Rpb24gZmluZFdyYXBwaW5nKHJhbmdlLCBub2RlVHlwZSwgYXR0cnMgPSBudWxsLCBpbm5lclJhbmdlID0gcmFuZ2UpIHtcbiAgICBsZXQgYXJvdW5kID0gZmluZFdyYXBwaW5nT3V0c2lkZShyYW5nZSwgbm9kZVR5cGUpO1xuICAgIGxldCBpbm5lciA9IGFyb3VuZCAmJiBmaW5kV3JhcHBpbmdJbnNpZGUoaW5uZXJSYW5nZSwgbm9kZVR5cGUpO1xuICAgIGlmICghaW5uZXIpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIHJldHVybiBhcm91bmQubWFwKHdpdGhBdHRycylcbiAgICAgICAgLmNvbmNhdCh7IHR5cGU6IG5vZGVUeXBlLCBhdHRycyB9KS5jb25jYXQoaW5uZXIubWFwKHdpdGhBdHRycykpO1xufVxuZnVuY3Rpb24gd2l0aEF0dHJzKHR5cGUpIHsgcmV0dXJuIHsgdHlwZSwgYXR0cnM6IG51bGwgfTsgfVxuZnVuY3Rpb24gZmluZFdyYXBwaW5nT3V0c2lkZShyYW5nZSwgdHlwZSkge1xuICAgIGxldCB7IHBhcmVudCwgc3RhcnRJbmRleCwgZW5kSW5kZXggfSA9IHJhbmdlO1xuICAgIGxldCBhcm91bmQgPSBwYXJlbnQuY29udGVudE1hdGNoQXQoc3RhcnRJbmRleCkuZmluZFdyYXBwaW5nKHR5cGUpO1xuICAgIGlmICghYXJvdW5kKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBsZXQgb3V0ZXIgPSBhcm91bmQubGVuZ3RoID8gYXJvdW5kWzBdIDogdHlwZTtcbiAgICByZXR1cm4gcGFyZW50LmNhblJlcGxhY2VXaXRoKHN0YXJ0SW5kZXgsIGVuZEluZGV4LCBvdXRlcikgPyBhcm91bmQgOiBudWxsO1xufVxuZnVuY3Rpb24gZmluZFdyYXBwaW5nSW5zaWRlKHJhbmdlLCB0eXBlKSB7XG4gICAgbGV0IHsgcGFyZW50LCBzdGFydEluZGV4LCBlbmRJbmRleCB9ID0gcmFuZ2U7XG4gICAgbGV0IGlubmVyID0gcGFyZW50LmNoaWxkKHN0YXJ0SW5kZXgpO1xuICAgIGxldCBpbnNpZGUgPSB0eXBlLmNvbnRlbnRNYXRjaC5maW5kV3JhcHBpbmcoaW5uZXIudHlwZSk7XG4gICAgaWYgKCFpbnNpZGUpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGxldCBsYXN0VHlwZSA9IGluc2lkZS5sZW5ndGggPyBpbnNpZGVbaW5zaWRlLmxlbmd0aCAtIDFdIDogdHlwZTtcbiAgICBsZXQgaW5uZXJNYXRjaCA9IGxhc3RUeXBlLmNvbnRlbnRNYXRjaDtcbiAgICBmb3IgKGxldCBpID0gc3RhcnRJbmRleDsgaW5uZXJNYXRjaCAmJiBpIDwgZW5kSW5kZXg7IGkrKylcbiAgICAgICAgaW5uZXJNYXRjaCA9IGlubmVyTWF0Y2gubWF0Y2hUeXBlKHBhcmVudC5jaGlsZChpKS50eXBlKTtcbiAgICBpZiAoIWlubmVyTWF0Y2ggfHwgIWlubmVyTWF0Y2gudmFsaWRFbmQpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIHJldHVybiBpbnNpZGU7XG59XG5mdW5jdGlvbiB3cmFwKHRyLCByYW5nZSwgd3JhcHBlcnMpIHtcbiAgICBsZXQgY29udGVudCA9IEZyYWdtZW50LmVtcHR5O1xuICAgIGZvciAobGV0IGkgPSB3cmFwcGVycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBpZiAoY29udGVudC5zaXplKSB7XG4gICAgICAgICAgICBsZXQgbWF0Y2ggPSB3cmFwcGVyc1tpXS50eXBlLmNvbnRlbnRNYXRjaC5tYXRjaEZyYWdtZW50KGNvbnRlbnQpO1xuICAgICAgICAgICAgaWYgKCFtYXRjaCB8fCAhbWF0Y2gudmFsaWRFbmQpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJXcmFwcGVyIHR5cGUgZ2l2ZW4gdG8gVHJhbnNmb3JtLndyYXAgZG9lcyBub3QgZm9ybSB2YWxpZCBjb250ZW50IG9mIGl0cyBwYXJlbnQgd3JhcHBlclwiKTtcbiAgICAgICAgfVxuICAgICAgICBjb250ZW50ID0gRnJhZ21lbnQuZnJvbSh3cmFwcGVyc1tpXS50eXBlLmNyZWF0ZSh3cmFwcGVyc1tpXS5hdHRycywgY29udGVudCkpO1xuICAgIH1cbiAgICBsZXQgc3RhcnQgPSByYW5nZS5zdGFydCwgZW5kID0gcmFuZ2UuZW5kO1xuICAgIHRyLnN0ZXAobmV3IFJlcGxhY2VBcm91bmRTdGVwKHN0YXJ0LCBlbmQsIHN0YXJ0LCBlbmQsIG5ldyBTbGljZShjb250ZW50LCAwLCAwKSwgd3JhcHBlcnMubGVuZ3RoLCB0cnVlKSk7XG59XG5mdW5jdGlvbiBzZXRCbG9ja1R5cGUodHIsIGZyb20sIHRvLCB0eXBlLCBhdHRycykge1xuICAgIGlmICghdHlwZS5pc1RleHRibG9jaylcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUeXBlIGdpdmVuIHRvIHNldEJsb2NrVHlwZSBzaG91bGQgYmUgYSB0ZXh0YmxvY2tcIik7XG4gICAgbGV0IG1hcEZyb20gPSB0ci5zdGVwcy5sZW5ndGg7XG4gICAgdHIuZG9jLm5vZGVzQmV0d2Vlbihmcm9tLCB0bywgKG5vZGUsIHBvcykgPT4ge1xuICAgICAgICBsZXQgYXR0cnNIZXJlID0gdHlwZW9mIGF0dHJzID09IFwiZnVuY3Rpb25cIiA/IGF0dHJzKG5vZGUpIDogYXR0cnM7XG4gICAgICAgIGlmIChub2RlLmlzVGV4dGJsb2NrICYmICFub2RlLmhhc01hcmt1cCh0eXBlLCBhdHRyc0hlcmUpICYmXG4gICAgICAgICAgICBjYW5DaGFuZ2VUeXBlKHRyLmRvYywgdHIubWFwcGluZy5zbGljZShtYXBGcm9tKS5tYXAocG9zKSwgdHlwZSkpIHtcbiAgICAgICAgICAgIGxldCBjb252ZXJ0TmV3bGluZXMgPSBudWxsO1xuICAgICAgICAgICAgaWYgKHR5cGUuc2NoZW1hLmxpbmVicmVha1JlcGxhY2VtZW50KSB7XG4gICAgICAgICAgICAgICAgbGV0IHByZSA9IHR5cGUud2hpdGVzcGFjZSA9PSBcInByZVwiLCBzdXBwb3J0TGluZWJyZWFrID0gISF0eXBlLmNvbnRlbnRNYXRjaC5tYXRjaFR5cGUodHlwZS5zY2hlbWEubGluZWJyZWFrUmVwbGFjZW1lbnQpO1xuICAgICAgICAgICAgICAgIGlmIChwcmUgJiYgIXN1cHBvcnRMaW5lYnJlYWspXG4gICAgICAgICAgICAgICAgICAgIGNvbnZlcnROZXdsaW5lcyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFwcmUgJiYgc3VwcG9ydExpbmVicmVhaylcbiAgICAgICAgICAgICAgICAgICAgY29udmVydE5ld2xpbmVzID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEVuc3VyZSBhbGwgbWFya3VwIHRoYXQgaXNuJ3QgYWxsb3dlZCBpbiB0aGUgbmV3IG5vZGUgdHlwZSBpcyBjbGVhcmVkXG4gICAgICAgICAgICBpZiAoY29udmVydE5ld2xpbmVzID09PSBmYWxzZSlcbiAgICAgICAgICAgICAgICByZXBsYWNlTGluZWJyZWFrcyh0ciwgbm9kZSwgcG9zLCBtYXBGcm9tKTtcbiAgICAgICAgICAgIGNsZWFySW5jb21wYXRpYmxlKHRyLCB0ci5tYXBwaW5nLnNsaWNlKG1hcEZyb20pLm1hcChwb3MsIDEpLCB0eXBlLCB1bmRlZmluZWQsIGNvbnZlcnROZXdsaW5lcyA9PT0gbnVsbCk7XG4gICAgICAgICAgICBsZXQgbWFwcGluZyA9IHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSk7XG4gICAgICAgICAgICBsZXQgc3RhcnRNID0gbWFwcGluZy5tYXAocG9zLCAxKSwgZW5kTSA9IG1hcHBpbmcubWFwKHBvcyArIG5vZGUubm9kZVNpemUsIDEpO1xuICAgICAgICAgICAgdHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAoc3RhcnRNLCBlbmRNLCBzdGFydE0gKyAxLCBlbmRNIC0gMSwgbmV3IFNsaWNlKEZyYWdtZW50LmZyb20odHlwZS5jcmVhdGUoYXR0cnNIZXJlLCBudWxsLCBub2RlLm1hcmtzKSksIDAsIDApLCAxLCB0cnVlKSk7XG4gICAgICAgICAgICBpZiAoY29udmVydE5ld2xpbmVzID09PSB0cnVlKVxuICAgICAgICAgICAgICAgIHJlcGxhY2VOZXdsaW5lcyh0ciwgbm9kZSwgcG9zLCBtYXBGcm9tKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gcmVwbGFjZU5ld2xpbmVzKHRyLCBub2RlLCBwb3MsIG1hcEZyb20pIHtcbiAgICBub2RlLmZvckVhY2goKGNoaWxkLCBvZmZzZXQpID0+IHtcbiAgICAgICAgaWYgKGNoaWxkLmlzVGV4dCkge1xuICAgICAgICAgICAgbGV0IG0sIG5ld2xpbmUgPSAvXFxyP1xcbnxcXHIvZztcbiAgICAgICAgICAgIHdoaWxlIChtID0gbmV3bGluZS5leGVjKGNoaWxkLnRleHQpKSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0YXJ0ID0gdHIubWFwcGluZy5zbGljZShtYXBGcm9tKS5tYXAocG9zICsgMSArIG9mZnNldCArIG0uaW5kZXgpO1xuICAgICAgICAgICAgICAgIHRyLnJlcGxhY2VXaXRoKHN0YXJ0LCBzdGFydCArIDEsIG5vZGUudHlwZS5zY2hlbWEubGluZWJyZWFrUmVwbGFjZW1lbnQuY3JlYXRlKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSk7XG59XG5mdW5jdGlvbiByZXBsYWNlTGluZWJyZWFrcyh0ciwgbm9kZSwgcG9zLCBtYXBGcm9tKSB7XG4gICAgbm9kZS5mb3JFYWNoKChjaGlsZCwgb2Zmc2V0KSA9PiB7XG4gICAgICAgIGlmIChjaGlsZC50eXBlID09IGNoaWxkLnR5cGUuc2NoZW1hLmxpbmVicmVha1JlcGxhY2VtZW50KSB7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSB0ci5tYXBwaW5nLnNsaWNlKG1hcEZyb20pLm1hcChwb3MgKyAxICsgb2Zmc2V0KTtcbiAgICAgICAgICAgIHRyLnJlcGxhY2VXaXRoKHN0YXJ0LCBzdGFydCArIDEsIG5vZGUudHlwZS5zY2hlbWEudGV4dChcIlxcblwiKSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGNhbkNoYW5nZVR5cGUoZG9jLCBwb3MsIHR5cGUpIHtcbiAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHBvcyksIGluZGV4ID0gJHBvcy5pbmRleCgpO1xuICAgIHJldHVybiAkcG9zLnBhcmVudC5jYW5SZXBsYWNlV2l0aChpbmRleCwgaW5kZXggKyAxLCB0eXBlKTtcbn1cbi8qKlxuQ2hhbmdlIHRoZSB0eXBlLCBhdHRyaWJ1dGVzLCBhbmQvb3IgbWFya3Mgb2YgdGhlIG5vZGUgYXQgYHBvc2AuXG5XaGVuIGB0eXBlYCBpc24ndCBnaXZlbiwgdGhlIGV4aXN0aW5nIG5vZGUgdHlwZSBpcyBwcmVzZXJ2ZWQsXG4qL1xuZnVuY3Rpb24gc2V0Tm9kZU1hcmt1cCh0ciwgcG9zLCB0eXBlLCBhdHRycywgbWFya3MpIHtcbiAgICBsZXQgbm9kZSA9IHRyLmRvYy5ub2RlQXQocG9zKTtcbiAgICBpZiAoIW5vZGUpXG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTm8gbm9kZSBhdCBnaXZlbiBwb3NpdGlvblwiKTtcbiAgICBpZiAoIXR5cGUpXG4gICAgICAgIHR5cGUgPSBub2RlLnR5cGU7XG4gICAgbGV0IG5ld05vZGUgPSB0eXBlLmNyZWF0ZShhdHRycywgbnVsbCwgbWFya3MgfHwgbm9kZS5tYXJrcyk7XG4gICAgaWYgKG5vZGUuaXNMZWFmKVxuICAgICAgICByZXR1cm4gdHIucmVwbGFjZVdpdGgocG9zLCBwb3MgKyBub2RlLm5vZGVTaXplLCBuZXdOb2RlKTtcbiAgICBpZiAoIXR5cGUudmFsaWRDb250ZW50KG5vZGUuY29udGVudCkpXG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBjb250ZW50IGZvciBub2RlIHR5cGUgXCIgKyB0eXBlLm5hbWUpO1xuICAgIHRyLnN0ZXAobmV3IFJlcGxhY2VBcm91bmRTdGVwKHBvcywgcG9zICsgbm9kZS5ub2RlU2l6ZSwgcG9zICsgMSwgcG9zICsgbm9kZS5ub2RlU2l6ZSAtIDEsIG5ldyBTbGljZShGcmFnbWVudC5mcm9tKG5ld05vZGUpLCAwLCAwKSwgMSwgdHJ1ZSkpO1xufVxuLyoqXG5DaGVjayB3aGV0aGVyIHNwbGl0dGluZyBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24gaXMgYWxsb3dlZC5cbiovXG5mdW5jdGlvbiBjYW5TcGxpdChkb2MsIHBvcywgZGVwdGggPSAxLCB0eXBlc0FmdGVyKSB7XG4gICAgbGV0ICRwb3MgPSBkb2MucmVzb2x2ZShwb3MpLCBiYXNlID0gJHBvcy5kZXB0aCAtIGRlcHRoO1xuICAgIGxldCBpbm5lclR5cGUgPSAodHlwZXNBZnRlciAmJiB0eXBlc0FmdGVyW3R5cGVzQWZ0ZXIubGVuZ3RoIC0gMV0pIHx8ICRwb3MucGFyZW50O1xuICAgIGlmIChiYXNlIDwgMCB8fCAkcG9zLnBhcmVudC50eXBlLnNwZWMuaXNvbGF0aW5nIHx8XG4gICAgICAgICEkcG9zLnBhcmVudC5jYW5SZXBsYWNlKCRwb3MuaW5kZXgoKSwgJHBvcy5wYXJlbnQuY2hpbGRDb3VudCkgfHxcbiAgICAgICAgIWlubmVyVHlwZS50eXBlLnZhbGlkQ29udGVudCgkcG9zLnBhcmVudC5jb250ZW50LmN1dEJ5SW5kZXgoJHBvcy5pbmRleCgpLCAkcG9zLnBhcmVudC5jaGlsZENvdW50KSkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aCAtIDEsIGkgPSBkZXB0aCAtIDI7IGQgPiBiYXNlOyBkLS0sIGktLSkge1xuICAgICAgICBsZXQgbm9kZSA9ICRwb3Mubm9kZShkKSwgaW5kZXggPSAkcG9zLmluZGV4KGQpO1xuICAgICAgICBpZiAobm9kZS50eXBlLnNwZWMuaXNvbGF0aW5nKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgcmVzdCA9IG5vZGUuY29udGVudC5jdXRCeUluZGV4KGluZGV4LCBub2RlLmNoaWxkQ291bnQpO1xuICAgICAgICBsZXQgb3ZlcnJpZGVDaGlsZCA9IHR5cGVzQWZ0ZXIgJiYgdHlwZXNBZnRlcltpICsgMV07XG4gICAgICAgIGlmIChvdmVycmlkZUNoaWxkKVxuICAgICAgICAgICAgcmVzdCA9IHJlc3QucmVwbGFjZUNoaWxkKDAsIG92ZXJyaWRlQ2hpbGQudHlwZS5jcmVhdGUob3ZlcnJpZGVDaGlsZC5hdHRycykpO1xuICAgICAgICBsZXQgYWZ0ZXIgPSAodHlwZXNBZnRlciAmJiB0eXBlc0FmdGVyW2ldKSB8fCBub2RlO1xuICAgICAgICBpZiAoIW5vZGUuY2FuUmVwbGFjZShpbmRleCArIDEsIG5vZGUuY2hpbGRDb3VudCkgfHwgIWFmdGVyLnR5cGUudmFsaWRDb250ZW50KHJlc3QpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBsZXQgaW5kZXggPSAkcG9zLmluZGV4QWZ0ZXIoYmFzZSk7XG4gICAgbGV0IGJhc2VUeXBlID0gdHlwZXNBZnRlciAmJiB0eXBlc0FmdGVyWzBdO1xuICAgIHJldHVybiAkcG9zLm5vZGUoYmFzZSkuY2FuUmVwbGFjZVdpdGgoaW5kZXgsIGluZGV4LCBiYXNlVHlwZSA/IGJhc2VUeXBlLnR5cGUgOiAkcG9zLm5vZGUoYmFzZSArIDEpLnR5cGUpO1xufVxuZnVuY3Rpb24gc3BsaXQodHIsIHBvcywgZGVwdGggPSAxLCB0eXBlc0FmdGVyKSB7XG4gICAgbGV0ICRwb3MgPSB0ci5kb2MucmVzb2x2ZShwb3MpLCBiZWZvcmUgPSBGcmFnbWVudC5lbXB0eSwgYWZ0ZXIgPSBGcmFnbWVudC5lbXB0eTtcbiAgICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aCwgZSA9ICRwb3MuZGVwdGggLSBkZXB0aCwgaSA9IGRlcHRoIC0gMTsgZCA+IGU7IGQtLSwgaS0tKSB7XG4gICAgICAgIGJlZm9yZSA9IEZyYWdtZW50LmZyb20oJHBvcy5ub2RlKGQpLmNvcHkoYmVmb3JlKSk7XG4gICAgICAgIGxldCB0eXBlQWZ0ZXIgPSB0eXBlc0FmdGVyICYmIHR5cGVzQWZ0ZXJbaV07XG4gICAgICAgIGFmdGVyID0gRnJhZ21lbnQuZnJvbSh0eXBlQWZ0ZXIgPyB0eXBlQWZ0ZXIudHlwZS5jcmVhdGUodHlwZUFmdGVyLmF0dHJzLCBhZnRlcikgOiAkcG9zLm5vZGUoZCkuY29weShhZnRlcikpO1xuICAgIH1cbiAgICB0ci5zdGVwKG5ldyBSZXBsYWNlU3RlcChwb3MsIHBvcywgbmV3IFNsaWNlKGJlZm9yZS5hcHBlbmQoYWZ0ZXIpLCBkZXB0aCwgZGVwdGgpLCB0cnVlKSk7XG59XG4vKipcblRlc3Qgd2hldGhlciB0aGUgYmxvY2tzIGJlZm9yZSBhbmQgYWZ0ZXIgYSBnaXZlbiBwb3NpdGlvbiBjYW4gYmVcbmpvaW5lZC5cbiovXG5mdW5jdGlvbiBjYW5Kb2luKGRvYywgcG9zKSB7XG4gICAgbGV0ICRwb3MgPSBkb2MucmVzb2x2ZShwb3MpLCBpbmRleCA9ICRwb3MuaW5kZXgoKTtcbiAgICByZXR1cm4gam9pbmFibGUoJHBvcy5ub2RlQmVmb3JlLCAkcG9zLm5vZGVBZnRlcikgJiZcbiAgICAgICAgJHBvcy5wYXJlbnQuY2FuUmVwbGFjZShpbmRleCwgaW5kZXggKyAxKTtcbn1cbmZ1bmN0aW9uIGNhbkFwcGVuZFdpdGhTdWJzdGl0dXRlZExpbmVicmVha3MoYSwgYikge1xuICAgIGlmICghYi5jb250ZW50LnNpemUpXG4gICAgICAgIGEudHlwZS5jb21wYXRpYmxlQ29udGVudChiLnR5cGUpO1xuICAgIGxldCBtYXRjaCA9IGEuY29udGVudE1hdGNoQXQoYS5jaGlsZENvdW50KTtcbiAgICBsZXQgeyBsaW5lYnJlYWtSZXBsYWNlbWVudCB9ID0gYS50eXBlLnNjaGVtYTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGIuY2hpbGRDb3VudDsgaSsrKSB7XG4gICAgICAgIGxldCBjaGlsZCA9IGIuY2hpbGQoaSk7XG4gICAgICAgIGxldCB0eXBlID0gY2hpbGQudHlwZSA9PSBsaW5lYnJlYWtSZXBsYWNlbWVudCA/IGEudHlwZS5zY2hlbWEubm9kZXMudGV4dCA6IGNoaWxkLnR5cGU7XG4gICAgICAgIG1hdGNoID0gbWF0Y2gubWF0Y2hUeXBlKHR5cGUpO1xuICAgICAgICBpZiAoIW1hdGNoKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoIWEudHlwZS5hbGxvd3NNYXJrcyhjaGlsZC5tYXJrcykpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaC52YWxpZEVuZDtcbn1cbmZ1bmN0aW9uIGpvaW5hYmxlKGEsIGIpIHtcbiAgICByZXR1cm4gISEoYSAmJiBiICYmICFhLmlzTGVhZiAmJiBjYW5BcHBlbmRXaXRoU3Vic3RpdHV0ZWRMaW5lYnJlYWtzKGEsIGIpKTtcbn1cbi8qKlxuRmluZCBhbiBhbmNlc3RvciBvZiB0aGUgZ2l2ZW4gcG9zaXRpb24gdGhhdCBjYW4gYmUgam9pbmVkIHRvIHRoZVxuYmxvY2sgYmVmb3JlIChvciBhZnRlciBpZiBgZGlyYCBpcyBwb3NpdGl2ZSkuIFJldHVybnMgdGhlIGpvaW5hYmxlXG5wb2ludCwgaWYgYW55LlxuKi9cbmZ1bmN0aW9uIGpvaW5Qb2ludChkb2MsIHBvcywgZGlyID0gLTEpIHtcbiAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHBvcyk7XG4gICAgZm9yIChsZXQgZCA9ICRwb3MuZGVwdGg7OyBkLS0pIHtcbiAgICAgICAgbGV0IGJlZm9yZSwgYWZ0ZXIsIGluZGV4ID0gJHBvcy5pbmRleChkKTtcbiAgICAgICAgaWYgKGQgPT0gJHBvcy5kZXB0aCkge1xuICAgICAgICAgICAgYmVmb3JlID0gJHBvcy5ub2RlQmVmb3JlO1xuICAgICAgICAgICAgYWZ0ZXIgPSAkcG9zLm5vZGVBZnRlcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChkaXIgPiAwKSB7XG4gICAgICAgICAgICBiZWZvcmUgPSAkcG9zLm5vZGUoZCArIDEpO1xuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgICAgIGFmdGVyID0gJHBvcy5ub2RlKGQpLm1heWJlQ2hpbGQoaW5kZXgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgYmVmb3JlID0gJHBvcy5ub2RlKGQpLm1heWJlQ2hpbGQoaW5kZXggLSAxKTtcbiAgICAgICAgICAgIGFmdGVyID0gJHBvcy5ub2RlKGQgKyAxKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYmVmb3JlICYmICFiZWZvcmUuaXNUZXh0YmxvY2sgJiYgam9pbmFibGUoYmVmb3JlLCBhZnRlcikgJiZcbiAgICAgICAgICAgICRwb3Mubm9kZShkKS5jYW5SZXBsYWNlKGluZGV4LCBpbmRleCArIDEpKVxuICAgICAgICAgICAgcmV0dXJuIHBvcztcbiAgICAgICAgaWYgKGQgPT0gMClcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBwb3MgPSBkaXIgPCAwID8gJHBvcy5iZWZvcmUoZCkgOiAkcG9zLmFmdGVyKGQpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGpvaW4odHIsIHBvcywgZGVwdGgpIHtcbiAgICBsZXQgY29udmVydE5ld2xpbmVzID0gbnVsbDtcbiAgICBsZXQgeyBsaW5lYnJlYWtSZXBsYWNlbWVudCB9ID0gdHIuZG9jLnR5cGUuc2NoZW1hO1xuICAgIGxldCAkYmVmb3JlID0gdHIuZG9jLnJlc29sdmUocG9zIC0gZGVwdGgpLCBiZWZvcmVUeXBlID0gJGJlZm9yZS5ub2RlKCkudHlwZTtcbiAgICBpZiAobGluZWJyZWFrUmVwbGFjZW1lbnQgJiYgYmVmb3JlVHlwZS5pbmxpbmVDb250ZW50KSB7XG4gICAgICAgIGxldCBwcmUgPSBiZWZvcmVUeXBlLndoaXRlc3BhY2UgPT0gXCJwcmVcIjtcbiAgICAgICAgbGV0IHN1cHBvcnRMaW5lYnJlYWsgPSAhIWJlZm9yZVR5cGUuY29udGVudE1hdGNoLm1hdGNoVHlwZShsaW5lYnJlYWtSZXBsYWNlbWVudCk7XG4gICAgICAgIGlmIChwcmUgJiYgIXN1cHBvcnRMaW5lYnJlYWspXG4gICAgICAgICAgICBjb252ZXJ0TmV3bGluZXMgPSBmYWxzZTtcbiAgICAgICAgZWxzZSBpZiAoIXByZSAmJiBzdXBwb3J0TGluZWJyZWFrKVxuICAgICAgICAgICAgY29udmVydE5ld2xpbmVzID0gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IG1hcEZyb20gPSB0ci5zdGVwcy5sZW5ndGg7XG4gICAgaWYgKGNvbnZlcnROZXdsaW5lcyA9PT0gZmFsc2UpIHtcbiAgICAgICAgbGV0ICRhZnRlciA9IHRyLmRvYy5yZXNvbHZlKHBvcyArIGRlcHRoKTtcbiAgICAgICAgcmVwbGFjZUxpbmVicmVha3ModHIsICRhZnRlci5ub2RlKCksICRhZnRlci5iZWZvcmUoKSwgbWFwRnJvbSk7XG4gICAgfVxuICAgIGlmIChiZWZvcmVUeXBlLmlubGluZUNvbnRlbnQpXG4gICAgICAgIGNsZWFySW5jb21wYXRpYmxlKHRyLCBwb3MgKyBkZXB0aCAtIDEsIGJlZm9yZVR5cGUsICRiZWZvcmUubm9kZSgpLmNvbnRlbnRNYXRjaEF0KCRiZWZvcmUuaW5kZXgoKSksIGNvbnZlcnROZXdsaW5lcyA9PSBudWxsKTtcbiAgICBsZXQgbWFwcGluZyA9IHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSksIHN0YXJ0ID0gbWFwcGluZy5tYXAocG9zIC0gZGVwdGgpO1xuICAgIHRyLnN0ZXAobmV3IFJlcGxhY2VTdGVwKHN0YXJ0LCBtYXBwaW5nLm1hcChwb3MgKyBkZXB0aCwgLTEpLCBTbGljZS5lbXB0eSwgdHJ1ZSkpO1xuICAgIGlmIChjb252ZXJ0TmV3bGluZXMgPT09IHRydWUpIHtcbiAgICAgICAgbGV0ICRmdWxsID0gdHIuZG9jLnJlc29sdmUoc3RhcnQpO1xuICAgICAgICByZXBsYWNlTmV3bGluZXModHIsICRmdWxsLm5vZGUoKSwgJGZ1bGwuYmVmb3JlKCksIHRyLnN0ZXBzLmxlbmd0aCk7XG4gICAgfVxuICAgIHJldHVybiB0cjtcbn1cbi8qKlxuVHJ5IHRvIGZpbmQgYSBwb2ludCB3aGVyZSBhIG5vZGUgb2YgdGhlIGdpdmVuIHR5cGUgY2FuIGJlIGluc2VydGVkXG5uZWFyIGBwb3NgLCBieSBzZWFyY2hpbmcgdXAgdGhlIG5vZGUgaGllcmFyY2h5IHdoZW4gYHBvc2AgaXRzZWxmXG5pc24ndCBhIHZhbGlkIHBsYWNlIGJ1dCBpcyBhdCB0aGUgc3RhcnQgb3IgZW5kIG9mIGEgbm9kZS4gUmV0dXJuXG5udWxsIGlmIG5vIHBvc2l0aW9uIHdhcyBmb3VuZC5cbiovXG5mdW5jdGlvbiBpbnNlcnRQb2ludChkb2MsIHBvcywgbm9kZVR5cGUpIHtcbiAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHBvcyk7XG4gICAgaWYgKCRwb3MucGFyZW50LmNhblJlcGxhY2VXaXRoKCRwb3MuaW5kZXgoKSwgJHBvcy5pbmRleCgpLCBub2RlVHlwZSkpXG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgaWYgKCRwb3MucGFyZW50T2Zmc2V0ID09IDApXG4gICAgICAgIGZvciAobGV0IGQgPSAkcG9zLmRlcHRoIC0gMTsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgICAgIGxldCBpbmRleCA9ICRwb3MuaW5kZXgoZCk7XG4gICAgICAgICAgICBpZiAoJHBvcy5ub2RlKGQpLmNhblJlcGxhY2VXaXRoKGluZGV4LCBpbmRleCwgbm9kZVR5cGUpKVxuICAgICAgICAgICAgICAgIHJldHVybiAkcG9zLmJlZm9yZShkICsgMSk7XG4gICAgICAgICAgICBpZiAoaW5kZXggPiAwKVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgaWYgKCRwb3MucGFyZW50T2Zmc2V0ID09ICRwb3MucGFyZW50LmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgZm9yIChsZXQgZCA9ICRwb3MuZGVwdGggLSAxOyBkID49IDA7IGQtLSkge1xuICAgICAgICAgICAgbGV0IGluZGV4ID0gJHBvcy5pbmRleEFmdGVyKGQpO1xuICAgICAgICAgICAgaWYgKCRwb3Mubm9kZShkKS5jYW5SZXBsYWNlV2l0aChpbmRleCwgaW5kZXgsIG5vZGVUeXBlKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gJHBvcy5hZnRlcihkICsgMSk7XG4gICAgICAgICAgICBpZiAoaW5kZXggPCAkcG9zLm5vZGUoZCkuY2hpbGRDb3VudClcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuLyoqXG5GaW5kcyBhIHBvc2l0aW9uIGF0IG9yIGFyb3VuZCB0aGUgZ2l2ZW4gcG9zaXRpb24gd2hlcmUgdGhlIGdpdmVuXG5zbGljZSBjYW4gYmUgaW5zZXJ0ZWQuIFdpbGwgbG9vayBhdCBwYXJlbnQgbm9kZXMnIG5lYXJlc3QgYm91bmRhcnlcbmFuZCB0cnkgdGhlcmUsIGV2ZW4gaWYgdGhlIG9yaWdpbmFsIHBvc2l0aW9uIHdhc24ndCBkaXJlY3RseSBhdCB0aGVcbnN0YXJ0IG9yIGVuZCBvZiB0aGF0IG5vZGUuIFJldHVybnMgbnVsbCB3aGVuIG5vIHBvc2l0aW9uIHdhcyBmb3VuZC5cbiovXG5mdW5jdGlvbiBkcm9wUG9pbnQoZG9jLCBwb3MsIHNsaWNlKSB7XG4gICAgbGV0ICRwb3MgPSBkb2MucmVzb2x2ZShwb3MpO1xuICAgIGlmICghc2xpY2UuY29udGVudC5zaXplKVxuICAgICAgICByZXR1cm4gcG9zO1xuICAgIGxldCBjb250ZW50ID0gc2xpY2UuY29udGVudDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNsaWNlLm9wZW5TdGFydDsgaSsrKVxuICAgICAgICBjb250ZW50ID0gY29udGVudC5maXJzdENoaWxkLmNvbnRlbnQ7XG4gICAgZm9yIChsZXQgcGFzcyA9IDE7IHBhc3MgPD0gKHNsaWNlLm9wZW5TdGFydCA9PSAwICYmIHNsaWNlLnNpemUgPyAyIDogMSk7IHBhc3MrKykge1xuICAgICAgICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aDsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgICAgIGxldCBiaWFzID0gZCA9PSAkcG9zLmRlcHRoID8gMCA6ICRwb3MucG9zIDw9ICgkcG9zLnN0YXJ0KGQgKyAxKSArICRwb3MuZW5kKGQgKyAxKSkgLyAyID8gLTEgOiAxO1xuICAgICAgICAgICAgbGV0IGluc2VydFBvcyA9ICRwb3MuaW5kZXgoZCkgKyAoYmlhcyA+IDAgPyAxIDogMCk7XG4gICAgICAgICAgICBsZXQgcGFyZW50ID0gJHBvcy5ub2RlKGQpLCBmaXRzID0gZmFsc2U7XG4gICAgICAgICAgICBpZiAocGFzcyA9PSAxKSB7XG4gICAgICAgICAgICAgICAgZml0cyA9IHBhcmVudC5jYW5SZXBsYWNlKGluc2VydFBvcywgaW5zZXJ0UG9zLCBjb250ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCB3cmFwcGluZyA9IHBhcmVudC5jb250ZW50TWF0Y2hBdChpbnNlcnRQb3MpLmZpbmRXcmFwcGluZyhjb250ZW50LmZpcnN0Q2hpbGQudHlwZSk7XG4gICAgICAgICAgICAgICAgZml0cyA9IHdyYXBwaW5nICYmIHBhcmVudC5jYW5SZXBsYWNlV2l0aChpbnNlcnRQb3MsIGluc2VydFBvcywgd3JhcHBpbmdbMF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZpdHMpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJpYXMgPT0gMCA/ICRwb3MucG9zIDogYmlhcyA8IDAgPyAkcG9zLmJlZm9yZShkICsgMSkgOiAkcG9zLmFmdGVyKGQgKyAxKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG7igJhGaXTigJkgYSBzbGljZSBpbnRvIGEgZ2l2ZW4gcG9zaXRpb24gaW4gdGhlIGRvY3VtZW50LCBwcm9kdWNpbmcgYVxuW3N0ZXBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0uU3RlcCkgdGhhdCBpbnNlcnRzIGl0LiBXaWxsIHJldHVybiBudWxsIGlmXG50aGVyZSdzIG5vIG1lYW5pbmdmdWwgd2F5IHRvIGluc2VydCB0aGUgc2xpY2UgaGVyZSwgb3IgaW5zZXJ0aW5nIGl0XG53b3VsZCBiZSBhIG5vLW9wIChhbiBlbXB0eSBzbGljZSBvdmVyIGFuIGVtcHR5IHJhbmdlKS5cbiovXG5mdW5jdGlvbiByZXBsYWNlU3RlcChkb2MsIGZyb20sIHRvID0gZnJvbSwgc2xpY2UgPSBTbGljZS5lbXB0eSkge1xuICAgIGlmIChmcm9tID09IHRvICYmICFzbGljZS5zaXplKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBsZXQgJGZyb20gPSBkb2MucmVzb2x2ZShmcm9tKSwgJHRvID0gZG9jLnJlc29sdmUodG8pO1xuICAgIC8vIE9wdGltaXphdGlvbiAtLSBhdm9pZCB3b3JrIGlmIGl0J3Mgb2J2aW91cyB0aGF0IGl0J3Mgbm90IG5lZWRlZC5cbiAgICBpZiAoZml0c1RyaXZpYWxseSgkZnJvbSwgJHRvLCBzbGljZSkpXG4gICAgICAgIHJldHVybiBuZXcgUmVwbGFjZVN0ZXAoZnJvbSwgdG8sIHNsaWNlKTtcbiAgICByZXR1cm4gbmV3IEZpdHRlcigkZnJvbSwgJHRvLCBzbGljZSkuZml0KCk7XG59XG5mdW5jdGlvbiBmaXRzVHJpdmlhbGx5KCRmcm9tLCAkdG8sIHNsaWNlKSB7XG4gICAgcmV0dXJuICFzbGljZS5vcGVuU3RhcnQgJiYgIXNsaWNlLm9wZW5FbmQgJiYgJGZyb20uc3RhcnQoKSA9PSAkdG8uc3RhcnQoKSAmJlxuICAgICAgICAkZnJvbS5wYXJlbnQuY2FuUmVwbGFjZSgkZnJvbS5pbmRleCgpLCAkdG8uaW5kZXgoKSwgc2xpY2UuY29udGVudCk7XG59XG4vLyBBbGdvcml0aG0gZm9yICdwbGFjaW5nJyB0aGUgZWxlbWVudHMgb2YgYSBzbGljZSBpbnRvIGEgZ2FwOlxuLy9cbi8vIFdlIGNvbnNpZGVyIHRoZSBjb250ZW50IG9mIGVhY2ggbm9kZSB0aGF0IGlzIG9wZW4gdG8gdGhlIGxlZnQgdG8gYmVcbi8vIGluZGVwZW5kZW50bHkgcGxhY2VhYmxlLiBJLmUuIGluIDxwKFwiZm9vXCIpLCBwKFwiYmFyXCIpPiwgd2hlbiB0aGVcbi8vIHBhcmFncmFwaCBvbiB0aGUgbGVmdCBpcyBvcGVuLCBcImZvb1wiIGNhbiBiZSBwbGFjZWQgKHNvbWV3aGVyZSBvblxuLy8gdGhlIGxlZnQgc2lkZSBvZiB0aGUgcmVwbGFjZW1lbnQgZ2FwKSBpbmRlcGVuZGVudGx5IGZyb20gcChcImJhclwiKS5cbi8vXG4vLyBUaGlzIGNsYXNzIHRyYWNrcyB0aGUgc3RhdGUgb2YgdGhlIHBsYWNlbWVudCBwcm9ncmVzcyBpbiB0aGVcbi8vIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuLy9cbi8vICAtIGBmcm9udGllcmAgaG9sZHMgYSBzdGFjayBvZiBge3R5cGUsIG1hdGNofWAgb2JqZWN0cyB0aGF0XG4vLyAgICByZXByZXNlbnQgdGhlIG9wZW4gc2lkZSBvZiB0aGUgcmVwbGFjZW1lbnQuIEl0IHN0YXJ0cyBhdFxuLy8gICAgYCRmcm9tYCwgdGhlbiBtb3ZlcyBmb3J3YXJkIGFzIGNvbnRlbnQgaXMgcGxhY2VkLCBhbmQgaXMgZmluYWxseVxuLy8gICAgcmVjb25jaWxlZCB3aXRoIGAkdG9gLlxuLy9cbi8vICAtIGB1bnBsYWNlZGAgaXMgYSBzbGljZSB0aGF0IHJlcHJlc2VudHMgdGhlIGNvbnRlbnQgdGhhdCBoYXNuJ3Rcbi8vICAgIGJlZW4gcGxhY2VkIHlldC5cbi8vXG4vLyAgLSBgcGxhY2VkYCBpcyBhIGZyYWdtZW50IG9mIHBsYWNlZCBjb250ZW50LiBJdHMgb3Blbi1zdGFydCB2YWx1ZVxuLy8gICAgaXMgaW1wbGljaXQgaW4gYCRmcm9tYCwgYW5kIGl0cyBvcGVuLWVuZCB2YWx1ZSBpbiBgZnJvbnRpZXJgLlxuY2xhc3MgRml0dGVyIHtcbiAgICBjb25zdHJ1Y3RvcigkZnJvbSwgJHRvLCB1bnBsYWNlZCkge1xuICAgICAgICB0aGlzLiRmcm9tID0gJGZyb207XG4gICAgICAgIHRoaXMuJHRvID0gJHRvO1xuICAgICAgICB0aGlzLnVucGxhY2VkID0gdW5wbGFjZWQ7XG4gICAgICAgIHRoaXMuZnJvbnRpZXIgPSBbXTtcbiAgICAgICAgdGhpcy5wbGFjZWQgPSBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gJGZyb20uZGVwdGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG5vZGUgPSAkZnJvbS5ub2RlKGkpO1xuICAgICAgICAgICAgdGhpcy5mcm9udGllci5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiBub2RlLnR5cGUsXG4gICAgICAgICAgICAgICAgbWF0Y2g6IG5vZGUuY29udGVudE1hdGNoQXQoJGZyb20uaW5kZXhBZnRlcihpKSlcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAkZnJvbS5kZXB0aDsgaSA+IDA7IGktLSlcbiAgICAgICAgICAgIHRoaXMucGxhY2VkID0gRnJhZ21lbnQuZnJvbSgkZnJvbS5ub2RlKGkpLmNvcHkodGhpcy5wbGFjZWQpKTtcbiAgICB9XG4gICAgZ2V0IGRlcHRoKCkgeyByZXR1cm4gdGhpcy5mcm9udGllci5sZW5ndGggLSAxOyB9XG4gICAgZml0KCkge1xuICAgICAgICAvLyBBcyBsb25nIGFzIHRoZXJlJ3MgdW5wbGFjZWQgY29udGVudCwgdHJ5IHRvIHBsYWNlIHNvbWUgb2YgaXQuXG4gICAgICAgIC8vIElmIHRoYXQgZmFpbHMsIGVpdGhlciBpbmNyZWFzZSB0aGUgb3BlbiBzY29yZSBvZiB0aGUgdW5wbGFjZWRcbiAgICAgICAgLy8gc2xpY2UsIG9yIGRyb3Agbm9kZXMgZnJvbSBpdCwgYW5kIHRoZW4gdHJ5IGFnYWluLlxuICAgICAgICB3aGlsZSAodGhpcy51bnBsYWNlZC5zaXplKSB7XG4gICAgICAgICAgICBsZXQgZml0ID0gdGhpcy5maW5kRml0dGFibGUoKTtcbiAgICAgICAgICAgIGlmIChmaXQpXG4gICAgICAgICAgICAgICAgdGhpcy5wbGFjZU5vZGVzKGZpdCk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuTW9yZSgpIHx8IHRoaXMuZHJvcE5vZGUoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBXaGVuIHRoZXJlJ3MgaW5saW5lIGNvbnRlbnQgZGlyZWN0bHkgYWZ0ZXIgdGhlIGZyb250aWVyIF9hbmRfXG4gICAgICAgIC8vIGRpcmVjdGx5IGFmdGVyIGB0aGlzLiR0b2AsIHdlIG11c3QgZ2VuZXJhdGUgYSBgUmVwbGFjZUFyb3VuZGBcbiAgICAgICAgLy8gc3RlcCB0aGF0IHB1bGxzIHRoYXQgY29udGVudCBpbnRvIHRoZSBub2RlIGFmdGVyIHRoZSBmcm9udGllci5cbiAgICAgICAgLy8gVGhhdCBtZWFucyB0aGUgZml0dGluZyBtdXN0IGJlIGRvbmUgdG8gdGhlIGVuZCBvZiB0aGUgdGV4dGJsb2NrXG4gICAgICAgIC8vIG5vZGUgYWZ0ZXIgYHRoaXMuJHRvYCwgbm90IGB0aGlzLiR0b2AgaXRzZWxmLlxuICAgICAgICBsZXQgbW92ZUlubGluZSA9IHRoaXMubXVzdE1vdmVJbmxpbmUoKSwgcGxhY2VkU2l6ZSA9IHRoaXMucGxhY2VkLnNpemUgLSB0aGlzLmRlcHRoIC0gdGhpcy4kZnJvbS5kZXB0aDtcbiAgICAgICAgbGV0ICRmcm9tID0gdGhpcy4kZnJvbSwgJHRvID0gdGhpcy5jbG9zZShtb3ZlSW5saW5lIDwgMCA/IHRoaXMuJHRvIDogJGZyb20uZG9jLnJlc29sdmUobW92ZUlubGluZSkpO1xuICAgICAgICBpZiAoISR0bylcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAvLyBJZiBjbG9zaW5nIHRvIGAkdG9gIHN1Y2NlZWRlZCwgY3JlYXRlIGEgc3RlcFxuICAgICAgICBsZXQgY29udGVudCA9IHRoaXMucGxhY2VkLCBvcGVuU3RhcnQgPSAkZnJvbS5kZXB0aCwgb3BlbkVuZCA9ICR0by5kZXB0aDtcbiAgICAgICAgd2hpbGUgKG9wZW5TdGFydCAmJiBvcGVuRW5kICYmIGNvbnRlbnQuY2hpbGRDb3VudCA9PSAxKSB7IC8vIE5vcm1hbGl6ZSBieSBkcm9wcGluZyBvcGVuIHBhcmVudCBub2Rlc1xuICAgICAgICAgICAgY29udGVudCA9IGNvbnRlbnQuZmlyc3RDaGlsZC5jb250ZW50O1xuICAgICAgICAgICAgb3BlblN0YXJ0LS07XG4gICAgICAgICAgICBvcGVuRW5kLS07XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHNsaWNlID0gbmV3IFNsaWNlKGNvbnRlbnQsIG9wZW5TdGFydCwgb3BlbkVuZCk7XG4gICAgICAgIGlmIChtb3ZlSW5saW5lID4gLTEpXG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VBcm91bmRTdGVwKCRmcm9tLnBvcywgbW92ZUlubGluZSwgdGhpcy4kdG8ucG9zLCB0aGlzLiR0by5lbmQoKSwgc2xpY2UsIHBsYWNlZFNpemUpO1xuICAgICAgICBpZiAoc2xpY2Uuc2l6ZSB8fCAkZnJvbS5wb3MgIT0gdGhpcy4kdG8ucG9zKSAvLyBEb24ndCBnZW5lcmF0ZSBuby1vcCBzdGVwc1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXBsYWNlU3RlcCgkZnJvbS5wb3MsICR0by5wb3MsIHNsaWNlKTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8vIEZpbmQgYSBwb3NpdGlvbiBvbiB0aGUgc3RhcnQgc3BpbmUgb2YgYHRoaXMudW5wbGFjZWRgIHRoYXQgaGFzXG4gICAgLy8gY29udGVudCB0aGF0IGNhbiBiZSBtb3ZlZCBzb21ld2hlcmUgb24gdGhlIGZyb250aWVyLiBSZXR1cm5zIHR3b1xuICAgIC8vIGRlcHRocywgb25lIGZvciB0aGUgc2xpY2UgYW5kIG9uZSBmb3IgdGhlIGZyb250aWVyLlxuICAgIGZpbmRGaXR0YWJsZSgpIHtcbiAgICAgICAgbGV0IHN0YXJ0RGVwdGggPSB0aGlzLnVucGxhY2VkLm9wZW5TdGFydDtcbiAgICAgICAgZm9yIChsZXQgY3VyID0gdGhpcy51bnBsYWNlZC5jb250ZW50LCBkID0gMCwgb3BlbkVuZCA9IHRoaXMudW5wbGFjZWQub3BlbkVuZDsgZCA8IHN0YXJ0RGVwdGg7IGQrKykge1xuICAgICAgICAgICAgbGV0IG5vZGUgPSBjdXIuZmlyc3RDaGlsZDtcbiAgICAgICAgICAgIGlmIChjdXIuY2hpbGRDb3VudCA+IDEpXG4gICAgICAgICAgICAgICAgb3BlbkVuZCA9IDA7XG4gICAgICAgICAgICBpZiAobm9kZS50eXBlLnNwZWMuaXNvbGF0aW5nICYmIG9wZW5FbmQgPD0gZCkge1xuICAgICAgICAgICAgICAgIHN0YXJ0RGVwdGggPSBkO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VyID0gbm9kZS5jb250ZW50O1xuICAgICAgICB9XG4gICAgICAgIC8vIE9ubHkgdHJ5IHdyYXBwaW5nIG5vZGVzIChwYXNzIDIpIGFmdGVyIGZpbmRpbmcgYSBwbGFjZSB3aXRob3V0XG4gICAgICAgIC8vIHdyYXBwaW5nIGZhaWxlZC5cbiAgICAgICAgZm9yIChsZXQgcGFzcyA9IDE7IHBhc3MgPD0gMjsgcGFzcysrKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBzbGljZURlcHRoID0gcGFzcyA9PSAxID8gc3RhcnREZXB0aCA6IHRoaXMudW5wbGFjZWQub3BlblN0YXJ0OyBzbGljZURlcHRoID49IDA7IHNsaWNlRGVwdGgtLSkge1xuICAgICAgICAgICAgICAgIGxldCBmcmFnbWVudCwgcGFyZW50ID0gbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAoc2xpY2VEZXB0aCkge1xuICAgICAgICAgICAgICAgICAgICBwYXJlbnQgPSBjb250ZW50QXQodGhpcy51bnBsYWNlZC5jb250ZW50LCBzbGljZURlcHRoIC0gMSkuZmlyc3RDaGlsZDtcbiAgICAgICAgICAgICAgICAgICAgZnJhZ21lbnQgPSBwYXJlbnQuY29udGVudDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZyYWdtZW50ID0gdGhpcy51bnBsYWNlZC5jb250ZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgZmlyc3QgPSBmcmFnbWVudC5maXJzdENoaWxkO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGZyb250aWVyRGVwdGggPSB0aGlzLmRlcHRoOyBmcm9udGllckRlcHRoID49IDA7IGZyb250aWVyRGVwdGgtLSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgeyB0eXBlLCBtYXRjaCB9ID0gdGhpcy5mcm9udGllcltmcm9udGllckRlcHRoXSwgd3JhcCwgaW5qZWN0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgLy8gSW4gcGFzcyAxLCBpZiB0aGUgbmV4dCBub2RlIG1hdGNoZXMsIG9yIHRoZXJlIGlzIG5vIG5leHRcbiAgICAgICAgICAgICAgICAgICAgLy8gbm9kZSBidXQgdGhlIHBhcmVudHMgbG9vayBjb21wYXRpYmxlLCB3ZSd2ZSBmb3VuZCBhXG4gICAgICAgICAgICAgICAgICAgIC8vIHBsYWNlLlxuICAgICAgICAgICAgICAgICAgICBpZiAocGFzcyA9PSAxICYmIChmaXJzdCA/IG1hdGNoLm1hdGNoVHlwZShmaXJzdC50eXBlKSB8fCAoaW5qZWN0ID0gbWF0Y2guZmlsbEJlZm9yZShGcmFnbWVudC5mcm9tKGZpcnN0KSwgZmFsc2UpKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBwYXJlbnQgJiYgdHlwZS5jb21wYXRpYmxlQ29udGVudChwYXJlbnQudHlwZSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgc2xpY2VEZXB0aCwgZnJvbnRpZXJEZXB0aCwgcGFyZW50LCBpbmplY3QgfTtcbiAgICAgICAgICAgICAgICAgICAgLy8gSW4gcGFzcyAyLCBsb29rIGZvciBhIHNldCBvZiB3cmFwcGluZyBub2RlcyB0aGF0IG1ha2VcbiAgICAgICAgICAgICAgICAgICAgLy8gYGZpcnN0YCBmaXQgaGVyZS5cbiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocGFzcyA9PSAyICYmIGZpcnN0ICYmICh3cmFwID0gbWF0Y2guZmluZFdyYXBwaW5nKGZpcnN0LnR5cGUpKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHNsaWNlRGVwdGgsIGZyb250aWVyRGVwdGgsIHBhcmVudCwgd3JhcCB9O1xuICAgICAgICAgICAgICAgICAgICAvLyBEb24ndCBjb250aW51ZSBsb29raW5nIGZ1cnRoZXIgdXAgaWYgdGhlIHBhcmVudCBub2RlXG4gICAgICAgICAgICAgICAgICAgIC8vIHdvdWxkIGZpdCBoZXJlLlxuICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50ICYmIG1hdGNoLm1hdGNoVHlwZShwYXJlbnQudHlwZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgb3Blbk1vcmUoKSB7XG4gICAgICAgIGxldCB7IGNvbnRlbnQsIG9wZW5TdGFydCwgb3BlbkVuZCB9ID0gdGhpcy51bnBsYWNlZDtcbiAgICAgICAgbGV0IGlubmVyID0gY29udGVudEF0KGNvbnRlbnQsIG9wZW5TdGFydCk7XG4gICAgICAgIGlmICghaW5uZXIuY2hpbGRDb3VudCB8fCBpbm5lci5maXJzdENoaWxkLmlzTGVhZilcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgdGhpcy51bnBsYWNlZCA9IG5ldyBTbGljZShjb250ZW50LCBvcGVuU3RhcnQgKyAxLCBNYXRoLm1heChvcGVuRW5kLCBpbm5lci5zaXplICsgb3BlblN0YXJ0ID49IGNvbnRlbnQuc2l6ZSAtIG9wZW5FbmQgPyBvcGVuU3RhcnQgKyAxIDogMCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgZHJvcE5vZGUoKSB7XG4gICAgICAgIGxldCB7IGNvbnRlbnQsIG9wZW5TdGFydCwgb3BlbkVuZCB9ID0gdGhpcy51bnBsYWNlZDtcbiAgICAgICAgbGV0IGlubmVyID0gY29udGVudEF0KGNvbnRlbnQsIG9wZW5TdGFydCk7XG4gICAgICAgIGlmIChpbm5lci5jaGlsZENvdW50IDw9IDEgJiYgb3BlblN0YXJ0ID4gMCkge1xuICAgICAgICAgICAgbGV0IG9wZW5BdEVuZCA9IGNvbnRlbnQuc2l6ZSAtIG9wZW5TdGFydCA8PSBvcGVuU3RhcnQgKyBpbm5lci5zaXplO1xuICAgICAgICAgICAgdGhpcy51bnBsYWNlZCA9IG5ldyBTbGljZShkcm9wRnJvbUZyYWdtZW50KGNvbnRlbnQsIG9wZW5TdGFydCAtIDEsIDEpLCBvcGVuU3RhcnQgLSAxLCBvcGVuQXRFbmQgPyBvcGVuU3RhcnQgLSAxIDogb3BlbkVuZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnVucGxhY2VkID0gbmV3IFNsaWNlKGRyb3BGcm9tRnJhZ21lbnQoY29udGVudCwgb3BlblN0YXJ0LCAxKSwgb3BlblN0YXJ0LCBvcGVuRW5kKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBNb3ZlIGNvbnRlbnQgZnJvbSB0aGUgdW5wbGFjZWQgc2xpY2UgYXQgYHNsaWNlRGVwdGhgIHRvIHRoZVxuICAgIC8vIGZyb250aWVyIG5vZGUgYXQgYGZyb250aWVyRGVwdGhgLiBDbG9zZSB0aGF0IGZyb250aWVyIG5vZGUgd2hlblxuICAgIC8vIGFwcGxpY2FibGUuXG4gICAgcGxhY2VOb2Rlcyh7IHNsaWNlRGVwdGgsIGZyb250aWVyRGVwdGgsIHBhcmVudCwgaW5qZWN0LCB3cmFwIH0pIHtcbiAgICAgICAgd2hpbGUgKHRoaXMuZGVwdGggPiBmcm9udGllckRlcHRoKVxuICAgICAgICAgICAgdGhpcy5jbG9zZUZyb250aWVyTm9kZSgpO1xuICAgICAgICBpZiAod3JhcClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgd3JhcC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW5Gcm9udGllck5vZGUod3JhcFtpXSk7XG4gICAgICAgIGxldCBzbGljZSA9IHRoaXMudW5wbGFjZWQsIGZyYWdtZW50ID0gcGFyZW50ID8gcGFyZW50LmNvbnRlbnQgOiBzbGljZS5jb250ZW50O1xuICAgICAgICBsZXQgb3BlblN0YXJ0ID0gc2xpY2Uub3BlblN0YXJ0IC0gc2xpY2VEZXB0aDtcbiAgICAgICAgbGV0IHRha2VuID0gMCwgYWRkID0gW107XG4gICAgICAgIGxldCB7IG1hdGNoLCB0eXBlIH0gPSB0aGlzLmZyb250aWVyW2Zyb250aWVyRGVwdGhdO1xuICAgICAgICBpZiAoaW5qZWN0KSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGluamVjdC5jaGlsZENvdW50OyBpKyspXG4gICAgICAgICAgICAgICAgYWRkLnB1c2goaW5qZWN0LmNoaWxkKGkpKTtcbiAgICAgICAgICAgIG1hdGNoID0gbWF0Y2gubWF0Y2hGcmFnbWVudChpbmplY3QpO1xuICAgICAgICB9XG4gICAgICAgIC8vIENvbXB1dGVzIHRoZSBhbW91bnQgb2YgKGVuZCkgb3BlbiBub2RlcyBhdCB0aGUgZW5kIG9mIHRoZVxuICAgICAgICAvLyBmcmFnbWVudC4gV2hlbiAwLCB0aGUgcGFyZW50IGlzIG9wZW4sIGJ1dCBubyBtb3JlLiBXaGVuXG4gICAgICAgIC8vIG5lZ2F0aXZlLCBub3RoaW5nIGlzIG9wZW4uXG4gICAgICAgIGxldCBvcGVuRW5kQ291bnQgPSAoZnJhZ21lbnQuc2l6ZSArIHNsaWNlRGVwdGgpIC0gKHNsaWNlLmNvbnRlbnQuc2l6ZSAtIHNsaWNlLm9wZW5FbmQpO1xuICAgICAgICAvLyBTY2FuIG92ZXIgdGhlIGZyYWdtZW50LCBmaXR0aW5nIGFzIG1hbnkgY2hpbGQgbm9kZXMgYXNcbiAgICAgICAgLy8gcG9zc2libGUuXG4gICAgICAgIHdoaWxlICh0YWtlbiA8IGZyYWdtZW50LmNoaWxkQ291bnQpIHtcbiAgICAgICAgICAgIGxldCBuZXh0ID0gZnJhZ21lbnQuY2hpbGQodGFrZW4pLCBtYXRjaGVzID0gbWF0Y2gubWF0Y2hUeXBlKG5leHQudHlwZSk7XG4gICAgICAgICAgICBpZiAoIW1hdGNoZXMpXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB0YWtlbisrO1xuICAgICAgICAgICAgaWYgKHRha2VuID4gMSB8fCBvcGVuU3RhcnQgPT0gMCB8fCBuZXh0LmNvbnRlbnQuc2l6ZSkgeyAvLyBEcm9wIGVtcHR5IG9wZW4gbm9kZXNcbiAgICAgICAgICAgICAgICBtYXRjaCA9IG1hdGNoZXM7XG4gICAgICAgICAgICAgICAgYWRkLnB1c2goY2xvc2VOb2RlU3RhcnQobmV4dC5tYXJrKHR5cGUuYWxsb3dlZE1hcmtzKG5leHQubWFya3MpKSwgdGFrZW4gPT0gMSA/IG9wZW5TdGFydCA6IDAsIHRha2VuID09IGZyYWdtZW50LmNoaWxkQ291bnQgPyBvcGVuRW5kQ291bnQgOiAtMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCB0b0VuZCA9IHRha2VuID09IGZyYWdtZW50LmNoaWxkQ291bnQ7XG4gICAgICAgIGlmICghdG9FbmQpXG4gICAgICAgICAgICBvcGVuRW5kQ291bnQgPSAtMTtcbiAgICAgICAgdGhpcy5wbGFjZWQgPSBhZGRUb0ZyYWdtZW50KHRoaXMucGxhY2VkLCBmcm9udGllckRlcHRoLCBGcmFnbWVudC5mcm9tKGFkZCkpO1xuICAgICAgICB0aGlzLmZyb250aWVyW2Zyb250aWVyRGVwdGhdLm1hdGNoID0gbWF0Y2g7XG4gICAgICAgIC8vIElmIHRoZSBwYXJlbnQgdHlwZXMgbWF0Y2gsIGFuZCB0aGUgZW50aXJlIG5vZGUgd2FzIG1vdmVkLCBhbmRcbiAgICAgICAgLy8gaXQncyBub3Qgb3BlbiwgY2xvc2UgdGhpcyBmcm9udGllciBub2RlIHJpZ2h0IGF3YXkuXG4gICAgICAgIGlmICh0b0VuZCAmJiBvcGVuRW5kQ291bnQgPCAwICYmIHBhcmVudCAmJiBwYXJlbnQudHlwZSA9PSB0aGlzLmZyb250aWVyW3RoaXMuZGVwdGhdLnR5cGUgJiYgdGhpcy5mcm9udGllci5sZW5ndGggPiAxKVxuICAgICAgICAgICAgdGhpcy5jbG9zZUZyb250aWVyTm9kZSgpO1xuICAgICAgICAvLyBBZGQgbmV3IGZyb250aWVyIG5vZGVzIGZvciBhbnkgb3BlbiBub2RlcyBhdCB0aGUgZW5kLlxuICAgICAgICBmb3IgKGxldCBpID0gMCwgY3VyID0gZnJhZ21lbnQ7IGkgPCBvcGVuRW5kQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgbGV0IG5vZGUgPSBjdXIubGFzdENoaWxkO1xuICAgICAgICAgICAgdGhpcy5mcm9udGllci5wdXNoKHsgdHlwZTogbm9kZS50eXBlLCBtYXRjaDogbm9kZS5jb250ZW50TWF0Y2hBdChub2RlLmNoaWxkQ291bnQpIH0pO1xuICAgICAgICAgICAgY3VyID0gbm9kZS5jb250ZW50O1xuICAgICAgICB9XG4gICAgICAgIC8vIFVwZGF0ZSBgdGhpcy51bnBsYWNlZGAuIERyb3AgdGhlIGVudGlyZSBub2RlIGZyb20gd2hpY2ggd2VcbiAgICAgICAgLy8gcGxhY2VkIGl0IHdlIGdvdCB0byBpdHMgZW5kLCBvdGhlcndpc2UganVzdCBkcm9wIHRoZSBwbGFjZWRcbiAgICAgICAgLy8gbm9kZXMuXG4gICAgICAgIHRoaXMudW5wbGFjZWQgPSAhdG9FbmQgPyBuZXcgU2xpY2UoZHJvcEZyb21GcmFnbWVudChzbGljZS5jb250ZW50LCBzbGljZURlcHRoLCB0YWtlbiksIHNsaWNlLm9wZW5TdGFydCwgc2xpY2Uub3BlbkVuZClcbiAgICAgICAgICAgIDogc2xpY2VEZXB0aCA9PSAwID8gU2xpY2UuZW1wdHlcbiAgICAgICAgICAgICAgICA6IG5ldyBTbGljZShkcm9wRnJvbUZyYWdtZW50KHNsaWNlLmNvbnRlbnQsIHNsaWNlRGVwdGggLSAxLCAxKSwgc2xpY2VEZXB0aCAtIDEsIG9wZW5FbmRDb3VudCA8IDAgPyBzbGljZS5vcGVuRW5kIDogc2xpY2VEZXB0aCAtIDEpO1xuICAgIH1cbiAgICBtdXN0TW92ZUlubGluZSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLiR0by5wYXJlbnQuaXNUZXh0YmxvY2spXG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIGxldCB0b3AgPSB0aGlzLmZyb250aWVyW3RoaXMuZGVwdGhdLCBsZXZlbDtcbiAgICAgICAgaWYgKCF0b3AudHlwZS5pc1RleHRibG9jayB8fCAhY29udGVudEFmdGVyRml0cyh0aGlzLiR0bywgdGhpcy4kdG8uZGVwdGgsIHRvcC50eXBlLCB0b3AubWF0Y2gsIGZhbHNlKSB8fFxuICAgICAgICAgICAgKHRoaXMuJHRvLmRlcHRoID09IHRoaXMuZGVwdGggJiYgKGxldmVsID0gdGhpcy5maW5kQ2xvc2VMZXZlbCh0aGlzLiR0bykpICYmIGxldmVsLmRlcHRoID09IHRoaXMuZGVwdGgpKVxuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICBsZXQgeyBkZXB0aCB9ID0gdGhpcy4kdG8sIGFmdGVyID0gdGhpcy4kdG8uYWZ0ZXIoZGVwdGgpO1xuICAgICAgICB3aGlsZSAoZGVwdGggPiAxICYmIGFmdGVyID09IHRoaXMuJHRvLmVuZCgtLWRlcHRoKSlcbiAgICAgICAgICAgICsrYWZ0ZXI7XG4gICAgICAgIHJldHVybiBhZnRlcjtcbiAgICB9XG4gICAgZmluZENsb3NlTGV2ZWwoJHRvKSB7XG4gICAgICAgIHNjYW46IGZvciAobGV0IGkgPSBNYXRoLm1pbih0aGlzLmRlcHRoLCAkdG8uZGVwdGgpOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgbGV0IHsgbWF0Y2gsIHR5cGUgfSA9IHRoaXMuZnJvbnRpZXJbaV07XG4gICAgICAgICAgICBsZXQgZHJvcElubmVyID0gaSA8ICR0by5kZXB0aCAmJiAkdG8uZW5kKGkgKyAxKSA9PSAkdG8ucG9zICsgKCR0by5kZXB0aCAtIChpICsgMSkpO1xuICAgICAgICAgICAgbGV0IGZpdCA9IGNvbnRlbnRBZnRlckZpdHMoJHRvLCBpLCB0eXBlLCBtYXRjaCwgZHJvcElubmVyKTtcbiAgICAgICAgICAgIGlmICghZml0KVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgZm9yIChsZXQgZCA9IGkgLSAxOyBkID49IDA7IGQtLSkge1xuICAgICAgICAgICAgICAgIGxldCB7IG1hdGNoLCB0eXBlIH0gPSB0aGlzLmZyb250aWVyW2RdO1xuICAgICAgICAgICAgICAgIGxldCBtYXRjaGVzID0gY29udGVudEFmdGVyRml0cygkdG8sIGQsIHR5cGUsIG1hdGNoLCB0cnVlKTtcbiAgICAgICAgICAgICAgICBpZiAoIW1hdGNoZXMgfHwgbWF0Y2hlcy5jaGlsZENvdW50KVxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBzY2FuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHsgZGVwdGg6IGksIGZpdCwgbW92ZTogZHJvcElubmVyID8gJHRvLmRvYy5yZXNvbHZlKCR0by5hZnRlcihpICsgMSkpIDogJHRvIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2xvc2UoJHRvKSB7XG4gICAgICAgIGxldCBjbG9zZSA9IHRoaXMuZmluZENsb3NlTGV2ZWwoJHRvKTtcbiAgICAgICAgaWYgKCFjbG9zZSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB3aGlsZSAodGhpcy5kZXB0aCA+IGNsb3NlLmRlcHRoKVxuICAgICAgICAgICAgdGhpcy5jbG9zZUZyb250aWVyTm9kZSgpO1xuICAgICAgICBpZiAoY2xvc2UuZml0LmNoaWxkQ291bnQpXG4gICAgICAgICAgICB0aGlzLnBsYWNlZCA9IGFkZFRvRnJhZ21lbnQodGhpcy5wbGFjZWQsIGNsb3NlLmRlcHRoLCBjbG9zZS5maXQpO1xuICAgICAgICAkdG8gPSBjbG9zZS5tb3ZlO1xuICAgICAgICBmb3IgKGxldCBkID0gY2xvc2UuZGVwdGggKyAxOyBkIDw9ICR0by5kZXB0aDsgZCsrKSB7XG4gICAgICAgICAgICBsZXQgbm9kZSA9ICR0by5ub2RlKGQpLCBhZGQgPSBub2RlLnR5cGUuY29udGVudE1hdGNoLmZpbGxCZWZvcmUobm9kZS5jb250ZW50LCB0cnVlLCAkdG8uaW5kZXgoZCkpO1xuICAgICAgICAgICAgdGhpcy5vcGVuRnJvbnRpZXJOb2RlKG5vZGUudHlwZSwgbm9kZS5hdHRycywgYWRkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJHRvO1xuICAgIH1cbiAgICBvcGVuRnJvbnRpZXJOb2RlKHR5cGUsIGF0dHJzID0gbnVsbCwgY29udGVudCkge1xuICAgICAgICBsZXQgdG9wID0gdGhpcy5mcm9udGllclt0aGlzLmRlcHRoXTtcbiAgICAgICAgdG9wLm1hdGNoID0gdG9wLm1hdGNoLm1hdGNoVHlwZSh0eXBlKTtcbiAgICAgICAgdGhpcy5wbGFjZWQgPSBhZGRUb0ZyYWdtZW50KHRoaXMucGxhY2VkLCB0aGlzLmRlcHRoLCBGcmFnbWVudC5mcm9tKHR5cGUuY3JlYXRlKGF0dHJzLCBjb250ZW50KSkpO1xuICAgICAgICB0aGlzLmZyb250aWVyLnB1c2goeyB0eXBlLCBtYXRjaDogdHlwZS5jb250ZW50TWF0Y2ggfSk7XG4gICAgfVxuICAgIGNsb3NlRnJvbnRpZXJOb2RlKCkge1xuICAgICAgICBsZXQgb3BlbiA9IHRoaXMuZnJvbnRpZXIucG9wKCk7XG4gICAgICAgIGxldCBhZGQgPSBvcGVuLm1hdGNoLmZpbGxCZWZvcmUoRnJhZ21lbnQuZW1wdHksIHRydWUpO1xuICAgICAgICBpZiAoYWRkLmNoaWxkQ291bnQpXG4gICAgICAgICAgICB0aGlzLnBsYWNlZCA9IGFkZFRvRnJhZ21lbnQodGhpcy5wbGFjZWQsIHRoaXMuZnJvbnRpZXIubGVuZ3RoLCBhZGQpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGRyb3BGcm9tRnJhZ21lbnQoZnJhZ21lbnQsIGRlcHRoLCBjb3VudCkge1xuICAgIGlmIChkZXB0aCA9PSAwKVxuICAgICAgICByZXR1cm4gZnJhZ21lbnQuY3V0QnlJbmRleChjb3VudCwgZnJhZ21lbnQuY2hpbGRDb3VudCk7XG4gICAgcmV0dXJuIGZyYWdtZW50LnJlcGxhY2VDaGlsZCgwLCBmcmFnbWVudC5maXJzdENoaWxkLmNvcHkoZHJvcEZyb21GcmFnbWVudChmcmFnbWVudC5maXJzdENoaWxkLmNvbnRlbnQsIGRlcHRoIC0gMSwgY291bnQpKSk7XG59XG5mdW5jdGlvbiBhZGRUb0ZyYWdtZW50KGZyYWdtZW50LCBkZXB0aCwgY29udGVudCkge1xuICAgIGlmIChkZXB0aCA9PSAwKVxuICAgICAgICByZXR1cm4gZnJhZ21lbnQuYXBwZW5kKGNvbnRlbnQpO1xuICAgIHJldHVybiBmcmFnbWVudC5yZXBsYWNlQ2hpbGQoZnJhZ21lbnQuY2hpbGRDb3VudCAtIDEsIGZyYWdtZW50Lmxhc3RDaGlsZC5jb3B5KGFkZFRvRnJhZ21lbnQoZnJhZ21lbnQubGFzdENoaWxkLmNvbnRlbnQsIGRlcHRoIC0gMSwgY29udGVudCkpKTtcbn1cbmZ1bmN0aW9uIGNvbnRlbnRBdChmcmFnbWVudCwgZGVwdGgpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlcHRoOyBpKyspXG4gICAgICAgIGZyYWdtZW50ID0gZnJhZ21lbnQuZmlyc3RDaGlsZC5jb250ZW50O1xuICAgIHJldHVybiBmcmFnbWVudDtcbn1cbmZ1bmN0aW9uIGNsb3NlTm9kZVN0YXJ0KG5vZGUsIG9wZW5TdGFydCwgb3BlbkVuZCkge1xuICAgIGlmIChvcGVuU3RhcnQgPD0gMClcbiAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgbGV0IGZyYWcgPSBub2RlLmNvbnRlbnQ7XG4gICAgaWYgKG9wZW5TdGFydCA+IDEpXG4gICAgICAgIGZyYWcgPSBmcmFnLnJlcGxhY2VDaGlsZCgwLCBjbG9zZU5vZGVTdGFydChmcmFnLmZpcnN0Q2hpbGQsIG9wZW5TdGFydCAtIDEsIGZyYWcuY2hpbGRDb3VudCA9PSAxID8gb3BlbkVuZCAtIDEgOiAwKSk7XG4gICAgaWYgKG9wZW5TdGFydCA+IDApIHtcbiAgICAgICAgZnJhZyA9IG5vZGUudHlwZS5jb250ZW50TWF0Y2guZmlsbEJlZm9yZShmcmFnKS5hcHBlbmQoZnJhZyk7XG4gICAgICAgIGlmIChvcGVuRW5kIDw9IDApXG4gICAgICAgICAgICBmcmFnID0gZnJhZy5hcHBlbmQobm9kZS50eXBlLmNvbnRlbnRNYXRjaC5tYXRjaEZyYWdtZW50KGZyYWcpLmZpbGxCZWZvcmUoRnJhZ21lbnQuZW1wdHksIHRydWUpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5vZGUuY29weShmcmFnKTtcbn1cbmZ1bmN0aW9uIGNvbnRlbnRBZnRlckZpdHMoJHRvLCBkZXB0aCwgdHlwZSwgbWF0Y2gsIG9wZW4pIHtcbiAgICBsZXQgbm9kZSA9ICR0by5ub2RlKGRlcHRoKSwgaW5kZXggPSBvcGVuID8gJHRvLmluZGV4QWZ0ZXIoZGVwdGgpIDogJHRvLmluZGV4KGRlcHRoKTtcbiAgICBpZiAoaW5kZXggPT0gbm9kZS5jaGlsZENvdW50ICYmICF0eXBlLmNvbXBhdGlibGVDb250ZW50KG5vZGUudHlwZSkpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGxldCBmaXQgPSBtYXRjaC5maWxsQmVmb3JlKG5vZGUuY29udGVudCwgdHJ1ZSwgaW5kZXgpO1xuICAgIHJldHVybiBmaXQgJiYgIWludmFsaWRNYXJrcyh0eXBlLCBub2RlLmNvbnRlbnQsIGluZGV4KSA/IGZpdCA6IG51bGw7XG59XG5mdW5jdGlvbiBpbnZhbGlkTWFya3ModHlwZSwgZnJhZ21lbnQsIHN0YXJ0KSB7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZnJhZ21lbnQuY2hpbGRDb3VudDsgaSsrKVxuICAgICAgICBpZiAoIXR5cGUuYWxsb3dzTWFya3MoZnJhZ21lbnQuY2hpbGQoaSkubWFya3MpKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gZGVmaW5lc0NvbnRlbnQodHlwZSkge1xuICAgIHJldHVybiB0eXBlLnNwZWMuZGVmaW5pbmcgfHwgdHlwZS5zcGVjLmRlZmluaW5nRm9yQ29udGVudDtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VSYW5nZSh0ciwgZnJvbSwgdG8sIHNsaWNlKSB7XG4gICAgaWYgKCFzbGljZS5zaXplKVxuICAgICAgICByZXR1cm4gdHIuZGVsZXRlUmFuZ2UoZnJvbSwgdG8pO1xuICAgIGxldCAkZnJvbSA9IHRyLmRvYy5yZXNvbHZlKGZyb20pLCAkdG8gPSB0ci5kb2MucmVzb2x2ZSh0byk7XG4gICAgaWYgKGZpdHNUcml2aWFsbHkoJGZyb20sICR0bywgc2xpY2UpKVxuICAgICAgICByZXR1cm4gdHIuc3RlcChuZXcgUmVwbGFjZVN0ZXAoZnJvbSwgdG8sIHNsaWNlKSk7XG4gICAgbGV0IHRhcmdldERlcHRocyA9IGNvdmVyZWREZXB0aHMoJGZyb20sICR0byk7XG4gICAgLy8gQ2FuJ3QgcmVwbGFjZSB0aGUgd2hvbGUgZG9jdW1lbnQsIHNvIHJlbW92ZSAwIGlmIGl0J3MgcHJlc2VudFxuICAgIGlmICh0YXJnZXREZXB0aHNbdGFyZ2V0RGVwdGhzLmxlbmd0aCAtIDFdID09IDApXG4gICAgICAgIHRhcmdldERlcHRocy5wb3AoKTtcbiAgICAvLyBOZWdhdGl2ZSBudW1iZXJzIHJlcHJlc2VudCBub3QgZXhwYW5zaW9uIG92ZXIgdGhlIHdob2xlIG5vZGUgYXRcbiAgICAvLyB0aGF0IGRlcHRoLCBidXQgcmVwbGFjaW5nIGZyb20gJGZyb20uYmVmb3JlKC1EKSB0byAkdG8ucG9zLlxuICAgIGxldCBwcmVmZXJyZWRUYXJnZXQgPSAtKCRmcm9tLmRlcHRoICsgMSk7XG4gICAgdGFyZ2V0RGVwdGhzLnVuc2hpZnQocHJlZmVycmVkVGFyZ2V0KTtcbiAgICAvLyBUaGlzIGxvb3AgcGlja3MgYSBwcmVmZXJyZWQgdGFyZ2V0IGRlcHRoLCBpZiBvbmUgb2YgdGhlIGNvdmVyaW5nXG4gICAgLy8gZGVwdGhzIGlzIG5vdCBvdXRzaWRlIG9mIGEgZGVmaW5pbmcgbm9kZSwgYW5kIGFkZHMgbmVnYXRpdmVcbiAgICAvLyBkZXB0aHMgZm9yIGFueSBkZXB0aCB0aGF0IGhhcyAkZnJvbSBhdCBpdHMgc3RhcnQgYW5kIGRvZXMgbm90XG4gICAgLy8gY3Jvc3MgYSBkZWZpbmluZyBub2RlLlxuICAgIGZvciAobGV0IGQgPSAkZnJvbS5kZXB0aCwgcG9zID0gJGZyb20ucG9zIC0gMTsgZCA+IDA7IGQtLSwgcG9zLS0pIHtcbiAgICAgICAgbGV0IHNwZWMgPSAkZnJvbS5ub2RlKGQpLnR5cGUuc3BlYztcbiAgICAgICAgaWYgKHNwZWMuZGVmaW5pbmcgfHwgc3BlYy5kZWZpbmluZ0FzQ29udGV4dCB8fCBzcGVjLmlzb2xhdGluZylcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBpZiAodGFyZ2V0RGVwdGhzLmluZGV4T2YoZCkgPiAtMSlcbiAgICAgICAgICAgIHByZWZlcnJlZFRhcmdldCA9IGQ7XG4gICAgICAgIGVsc2UgaWYgKCRmcm9tLmJlZm9yZShkKSA9PSBwb3MpXG4gICAgICAgICAgICB0YXJnZXREZXB0aHMuc3BsaWNlKDEsIDAsIC1kKTtcbiAgICB9XG4gICAgLy8gVHJ5IHRvIGZpdCBlYWNoIHBvc3NpYmxlIGRlcHRoIG9mIHRoZSBzbGljZSBpbnRvIGVhY2ggcG9zc2libGVcbiAgICAvLyB0YXJnZXQgZGVwdGgsIHN0YXJ0aW5nIHdpdGggdGhlIHByZWZlcnJlZCBkZXB0aHMuXG4gICAgbGV0IHByZWZlcnJlZFRhcmdldEluZGV4ID0gdGFyZ2V0RGVwdGhzLmluZGV4T2YocHJlZmVycmVkVGFyZ2V0KTtcbiAgICBsZXQgbGVmdE5vZGVzID0gW10sIHByZWZlcnJlZERlcHRoID0gc2xpY2Uub3BlblN0YXJ0O1xuICAgIGZvciAobGV0IGNvbnRlbnQgPSBzbGljZS5jb250ZW50LCBpID0gMDs7IGkrKykge1xuICAgICAgICBsZXQgbm9kZSA9IGNvbnRlbnQuZmlyc3RDaGlsZDtcbiAgICAgICAgbGVmdE5vZGVzLnB1c2gobm9kZSk7XG4gICAgICAgIGlmIChpID09IHNsaWNlLm9wZW5TdGFydClcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjb250ZW50ID0gbm9kZS5jb250ZW50O1xuICAgIH1cbiAgICAvLyBCYWNrIHVwIHByZWZlcnJlZERlcHRoIHRvIGNvdmVyIGRlZmluaW5nIHRleHRibG9ja3MgZGlyZWN0bHlcbiAgICAvLyBhYm92ZSBpdCwgcG9zc2libHkgc2tpcHBpbmcgYSBub24tZGVmaW5pbmcgdGV4dGJsb2NrLlxuICAgIGZvciAobGV0IGQgPSBwcmVmZXJyZWREZXB0aCAtIDE7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgIGxldCBsZWZ0Tm9kZSA9IGxlZnROb2Rlc1tkXSwgZGVmID0gZGVmaW5lc0NvbnRlbnQobGVmdE5vZGUudHlwZSk7XG4gICAgICAgIGlmIChkZWYgJiYgIWxlZnROb2RlLnNhbWVNYXJrdXAoJGZyb20ubm9kZShNYXRoLmFicyhwcmVmZXJyZWRUYXJnZXQpIC0gMSkpKVxuICAgICAgICAgICAgcHJlZmVycmVkRGVwdGggPSBkO1xuICAgICAgICBlbHNlIGlmIChkZWYgfHwgIWxlZnROb2RlLnR5cGUuaXNUZXh0YmxvY2spXG4gICAgICAgICAgICBicmVhaztcbiAgICB9XG4gICAgZm9yIChsZXQgaiA9IHNsaWNlLm9wZW5TdGFydDsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgbGV0IG9wZW5EZXB0aCA9IChqICsgcHJlZmVycmVkRGVwdGggKyAxKSAlIChzbGljZS5vcGVuU3RhcnQgKyAxKTtcbiAgICAgICAgbGV0IGluc2VydCA9IGxlZnROb2Rlc1tvcGVuRGVwdGhdO1xuICAgICAgICBpZiAoIWluc2VydClcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRhcmdldERlcHRocy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgLy8gTG9vcCBvdmVyIHBvc3NpYmxlIGV4cGFuc2lvbiBsZXZlbHMsIHN0YXJ0aW5nIHdpdGggdGhlXG4gICAgICAgICAgICAvLyBwcmVmZXJyZWQgb25lXG4gICAgICAgICAgICBsZXQgdGFyZ2V0RGVwdGggPSB0YXJnZXREZXB0aHNbKGkgKyBwcmVmZXJyZWRUYXJnZXRJbmRleCkgJSB0YXJnZXREZXB0aHMubGVuZ3RoXSwgZXhwYW5kID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmICh0YXJnZXREZXB0aCA8IDApIHtcbiAgICAgICAgICAgICAgICBleHBhbmQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB0YXJnZXREZXB0aCA9IC10YXJnZXREZXB0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBwYXJlbnQgPSAkZnJvbS5ub2RlKHRhcmdldERlcHRoIC0gMSksIGluZGV4ID0gJGZyb20uaW5kZXgodGFyZ2V0RGVwdGggLSAxKTtcbiAgICAgICAgICAgIGlmIChwYXJlbnQuY2FuUmVwbGFjZVdpdGgoaW5kZXgsIGluZGV4LCBpbnNlcnQudHlwZSwgaW5zZXJ0Lm1hcmtzKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gdHIucmVwbGFjZSgkZnJvbS5iZWZvcmUodGFyZ2V0RGVwdGgpLCBleHBhbmQgPyAkdG8uYWZ0ZXIodGFyZ2V0RGVwdGgpIDogdG8sIG5ldyBTbGljZShjbG9zZUZyYWdtZW50KHNsaWNlLmNvbnRlbnQsIDAsIHNsaWNlLm9wZW5TdGFydCwgb3BlbkRlcHRoKSwgb3BlbkRlcHRoLCBzbGljZS5vcGVuRW5kKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGV0IHN0YXJ0U3RlcHMgPSB0ci5zdGVwcy5sZW5ndGg7XG4gICAgZm9yIChsZXQgaSA9IHRhcmdldERlcHRocy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICB0ci5yZXBsYWNlKGZyb20sIHRvLCBzbGljZSk7XG4gICAgICAgIGlmICh0ci5zdGVwcy5sZW5ndGggPiBzdGFydFN0ZXBzKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGxldCBkZXB0aCA9IHRhcmdldERlcHRoc1tpXTtcbiAgICAgICAgaWYgKGRlcHRoIDwgMClcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBmcm9tID0gJGZyb20uYmVmb3JlKGRlcHRoKTtcbiAgICAgICAgdG8gPSAkdG8uYWZ0ZXIoZGVwdGgpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNsb3NlRnJhZ21lbnQoZnJhZ21lbnQsIGRlcHRoLCBvbGRPcGVuLCBuZXdPcGVuLCBwYXJlbnQpIHtcbiAgICBpZiAoZGVwdGggPCBvbGRPcGVuKSB7XG4gICAgICAgIGxldCBmaXJzdCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7XG4gICAgICAgIGZyYWdtZW50ID0gZnJhZ21lbnQucmVwbGFjZUNoaWxkKDAsIGZpcnN0LmNvcHkoY2xvc2VGcmFnbWVudChmaXJzdC5jb250ZW50LCBkZXB0aCArIDEsIG9sZE9wZW4sIG5ld09wZW4sIGZpcnN0KSkpO1xuICAgIH1cbiAgICBpZiAoZGVwdGggPiBuZXdPcGVuKSB7XG4gICAgICAgIGxldCBtYXRjaCA9IHBhcmVudC5jb250ZW50TWF0Y2hBdCgwKTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gbWF0Y2guZmlsbEJlZm9yZShmcmFnbWVudCkuYXBwZW5kKGZyYWdtZW50KTtcbiAgICAgICAgZnJhZ21lbnQgPSBzdGFydC5hcHBlbmQobWF0Y2gubWF0Y2hGcmFnbWVudChzdGFydCkuZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gZnJhZ21lbnQ7XG59XG5mdW5jdGlvbiByZXBsYWNlUmFuZ2VXaXRoKHRyLCBmcm9tLCB0bywgbm9kZSkge1xuICAgIGlmICghbm9kZS5pc0lubGluZSAmJiBmcm9tID09IHRvICYmIHRyLmRvYy5yZXNvbHZlKGZyb20pLnBhcmVudC5jb250ZW50LnNpemUpIHtcbiAgICAgICAgbGV0IHBvaW50ID0gaW5zZXJ0UG9pbnQodHIuZG9jLCBmcm9tLCBub2RlLnR5cGUpO1xuICAgICAgICBpZiAocG9pbnQgIT0gbnVsbClcbiAgICAgICAgICAgIGZyb20gPSB0byA9IHBvaW50O1xuICAgIH1cbiAgICB0ci5yZXBsYWNlUmFuZ2UoZnJvbSwgdG8sIG5ldyBTbGljZShGcmFnbWVudC5mcm9tKG5vZGUpLCAwLCAwKSk7XG59XG5mdW5jdGlvbiBkZWxldGVSYW5nZSh0ciwgZnJvbSwgdG8pIHtcbiAgICBsZXQgJGZyb20gPSB0ci5kb2MucmVzb2x2ZShmcm9tKSwgJHRvID0gdHIuZG9jLnJlc29sdmUodG8pO1xuICAgIC8vIFdoZW4gdGhlIGRlbGV0ZWQgcmFuZ2Ugc3BhbnMgZnJvbSB0aGUgc3RhcnQgb2Ygb25lIHRleHRibG9jayB0b1xuICAgIC8vIHRoZSBzdGFydCBvZiBhbm90aGVyIG9uZSwgbW92ZSBvdXQgb2YgdGhlIHN0YXJ0IG9mIGJvdGggYmxvY2tzLlxuICAgIGlmICgkZnJvbS5wYXJlbnQuaXNUZXh0YmxvY2sgJiYgJHRvLnBhcmVudC5pc1RleHRibG9jayAmJiAkZnJvbS5zdGFydCgpICE9ICR0by5zdGFydCgpICYmXG4gICAgICAgICRmcm9tLnBhcmVudE9mZnNldCA9PSAwICYmICR0by5wYXJlbnRPZmZzZXQgPT0gMCkge1xuICAgICAgICBsZXQgc2hhcmVkID0gJGZyb20uc2hhcmVkRGVwdGgodG8pLCBpc29sYXRlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBkID0gJGZyb20uZGVwdGg7IGQgPiBzaGFyZWQ7IGQtLSlcbiAgICAgICAgICAgIGlmICgkZnJvbS5ub2RlKGQpLnR5cGUuc3BlYy5pc29sYXRpbmcpXG4gICAgICAgICAgICAgICAgaXNvbGF0ZWQgPSB0cnVlO1xuICAgICAgICBmb3IgKGxldCBkID0gJHRvLmRlcHRoOyBkID4gc2hhcmVkOyBkLS0pXG4gICAgICAgICAgICBpZiAoJHRvLm5vZGUoZCkudHlwZS5zcGVjLmlzb2xhdGluZylcbiAgICAgICAgICAgICAgICBpc29sYXRlZCA9IHRydWU7XG4gICAgICAgIGlmICghaXNvbGF0ZWQpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGQgPSAkZnJvbS5kZXB0aDsgZCA+IDAgJiYgZnJvbSA9PSAkZnJvbS5zdGFydChkKTsgZC0tKVxuICAgICAgICAgICAgICAgIGZyb20gPSAkZnJvbS5iZWZvcmUoZCk7XG4gICAgICAgICAgICBmb3IgKGxldCBkID0gJHRvLmRlcHRoOyBkID4gMCAmJiB0byA9PSAkdG8uc3RhcnQoZCk7IGQtLSlcbiAgICAgICAgICAgICAgICB0byA9ICR0by5iZWZvcmUoZCk7XG4gICAgICAgICAgICAkZnJvbSA9IHRyLmRvYy5yZXNvbHZlKGZyb20pO1xuICAgICAgICAgICAgJHRvID0gdHIuZG9jLnJlc29sdmUodG8pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBjb3ZlcmVkID0gY292ZXJlZERlcHRocygkZnJvbSwgJHRvKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdmVyZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IGRlcHRoID0gY292ZXJlZFtpXSwgbGFzdCA9IGkgPT0gY292ZXJlZC5sZW5ndGggLSAxO1xuICAgICAgICBpZiAoKGxhc3QgJiYgZGVwdGggPT0gMCkgfHwgJGZyb20ubm9kZShkZXB0aCkudHlwZS5jb250ZW50TWF0Y2gudmFsaWRFbmQpXG4gICAgICAgICAgICByZXR1cm4gdHIuZGVsZXRlKCRmcm9tLnN0YXJ0KGRlcHRoKSwgJHRvLmVuZChkZXB0aCkpO1xuICAgICAgICBpZiAoZGVwdGggPiAwICYmIChsYXN0IHx8ICRmcm9tLm5vZGUoZGVwdGggLSAxKS5jYW5SZXBsYWNlKCRmcm9tLmluZGV4KGRlcHRoIC0gMSksICR0by5pbmRleEFmdGVyKGRlcHRoIC0gMSkpKSlcbiAgICAgICAgICAgIHJldHVybiB0ci5kZWxldGUoJGZyb20uYmVmb3JlKGRlcHRoKSwgJHRvLmFmdGVyKGRlcHRoKSk7XG4gICAgfVxuICAgIGZvciAobGV0IGQgPSAxOyBkIDw9ICRmcm9tLmRlcHRoICYmIGQgPD0gJHRvLmRlcHRoOyBkKyspIHtcbiAgICAgICAgaWYgKGZyb20gLSAkZnJvbS5zdGFydChkKSA9PSAkZnJvbS5kZXB0aCAtIGQgJiYgdG8gPiAkZnJvbS5lbmQoZCkgJiYgJHRvLmVuZChkKSAtIHRvICE9ICR0by5kZXB0aCAtIGQgJiZcbiAgICAgICAgICAgICRmcm9tLnN0YXJ0KGQgLSAxKSA9PSAkdG8uc3RhcnQoZCAtIDEpICYmICRmcm9tLm5vZGUoZCAtIDEpLmNhblJlcGxhY2UoJGZyb20uaW5kZXgoZCAtIDEpLCAkdG8uaW5kZXgoZCAtIDEpKSlcbiAgICAgICAgICAgIHJldHVybiB0ci5kZWxldGUoJGZyb20uYmVmb3JlKGQpLCB0byk7XG4gICAgfVxuICAgIHRyLmRlbGV0ZShmcm9tLCB0byk7XG59XG4vLyBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBkZXB0aHMgZm9yIHdoaWNoICRmcm9tIC0gJHRvIHNwYW5zIHRoZVxuLy8gd2hvbGUgY29udGVudCBvZiB0aGUgbm9kZXMgYXQgdGhhdCBkZXB0aC5cbmZ1bmN0aW9uIGNvdmVyZWREZXB0aHMoJGZyb20sICR0bykge1xuICAgIGxldCByZXN1bHQgPSBbXSwgbWluRGVwdGggPSBNYXRoLm1pbigkZnJvbS5kZXB0aCwgJHRvLmRlcHRoKTtcbiAgICBmb3IgKGxldCBkID0gbWluRGVwdGg7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgIGxldCBzdGFydCA9ICRmcm9tLnN0YXJ0KGQpO1xuICAgICAgICBpZiAoc3RhcnQgPCAkZnJvbS5wb3MgLSAoJGZyb20uZGVwdGggLSBkKSB8fFxuICAgICAgICAgICAgJHRvLmVuZChkKSA+ICR0by5wb3MgKyAoJHRvLmRlcHRoIC0gZCkgfHxcbiAgICAgICAgICAgICRmcm9tLm5vZGUoZCkudHlwZS5zcGVjLmlzb2xhdGluZyB8fFxuICAgICAgICAgICAgJHRvLm5vZGUoZCkudHlwZS5zcGVjLmlzb2xhdGluZylcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBpZiAoc3RhcnQgPT0gJHRvLnN0YXJ0KGQpIHx8XG4gICAgICAgICAgICAoZCA9PSAkZnJvbS5kZXB0aCAmJiBkID09ICR0by5kZXB0aCAmJiAkZnJvbS5wYXJlbnQuaW5saW5lQ29udGVudCAmJiAkdG8ucGFyZW50LmlubGluZUNvbnRlbnQgJiZcbiAgICAgICAgICAgICAgICBkICYmICR0by5zdGFydChkIC0gMSkgPT0gc3RhcnQgLSAxKSlcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcblVwZGF0ZSBhbiBhdHRyaWJ1dGUgaW4gYSBzcGVjaWZpYyBub2RlLlxuKi9cbmNsYXNzIEF0dHJTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgQ29uc3RydWN0IGFuIGF0dHJpYnV0ZSBzdGVwLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHBvc2l0aW9uIG9mIHRoZSB0YXJnZXQgbm9kZS5cbiAgICAqL1xuICAgIHBvcywgXG4gICAgLyoqXG4gICAgVGhlIGF0dHJpYnV0ZSB0byBzZXQuXG4gICAgKi9cbiAgICBhdHRyLCBcbiAgICAvLyBUaGUgYXR0cmlidXRlJ3MgbmV3IHZhbHVlLlxuICAgIHZhbHVlKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMucG9zID0gcG9zO1xuICAgICAgICB0aGlzLmF0dHIgPSBhdHRyO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIGFwcGx5KGRvYykge1xuICAgICAgICBsZXQgbm9kZSA9IGRvYy5ub2RlQXQodGhpcy5wb3MpO1xuICAgICAgICBpZiAoIW5vZGUpXG4gICAgICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mYWlsKFwiTm8gbm9kZSBhdCBhdHRyaWJ1dGUgc3RlcCdzIHBvc2l0aW9uXCIpO1xuICAgICAgICBsZXQgYXR0cnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBmb3IgKGxldCBuYW1lIGluIG5vZGUuYXR0cnMpXG4gICAgICAgICAgICBhdHRyc1tuYW1lXSA9IG5vZGUuYXR0cnNbbmFtZV07XG4gICAgICAgIGF0dHJzW3RoaXMuYXR0cl0gPSB0aGlzLnZhbHVlO1xuICAgICAgICBsZXQgdXBkYXRlZCA9IG5vZGUudHlwZS5jcmVhdGUoYXR0cnMsIG51bGwsIG5vZGUubWFya3MpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMucG9zLCB0aGlzLnBvcyArIDEsIG5ldyBTbGljZShGcmFnbWVudC5mcm9tKHVwZGF0ZWQpLCAwLCBub2RlLmlzTGVhZiA/IDAgOiAxKSk7XG4gICAgfVxuICAgIGdldE1hcCgpIHtcbiAgICAgICAgcmV0dXJuIFN0ZXBNYXAuZW1wdHk7XG4gICAgfVxuICAgIGludmVydChkb2MpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBBdHRyU3RlcCh0aGlzLnBvcywgdGhpcy5hdHRyLCBkb2Mubm9kZUF0KHRoaXMucG9zKS5hdHRyc1t0aGlzLmF0dHJdKTtcbiAgICB9XG4gICAgbWFwKG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IHBvcyA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMucG9zLCAxKTtcbiAgICAgICAgcmV0dXJuIHBvcy5kZWxldGVkQWZ0ZXIgPyBudWxsIDogbmV3IEF0dHJTdGVwKHBvcy5wb3MsIHRoaXMuYXR0ciwgdGhpcy52YWx1ZSk7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RlcFR5cGU6IFwiYXR0clwiLCBwb3M6IHRoaXMucG9zLCBhdHRyOiB0aGlzLmF0dHIsIHZhbHVlOiB0aGlzLnZhbHVlIH07XG4gICAgfVxuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBqc29uLnBvcyAhPSBcIm51bWJlclwiIHx8IHR5cGVvZiBqc29uLmF0dHIgIT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgQXR0clN0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgQXR0clN0ZXAoanNvbi5wb3MsIGpzb24uYXR0ciwganNvbi52YWx1ZSk7XG4gICAgfVxufVxuU3RlcC5qc29uSUQoXCJhdHRyXCIsIEF0dHJTdGVwKTtcbi8qKlxuVXBkYXRlIGFuIGF0dHJpYnV0ZSBpbiB0aGUgZG9jIG5vZGUuXG4qL1xuY2xhc3MgRG9jQXR0clN0ZXAgZXh0ZW5kcyBTdGVwIHtcbiAgICAvKipcbiAgICBDb25zdHJ1Y3QgYW4gYXR0cmlidXRlIHN0ZXAuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgYXR0cmlidXRlIHRvIHNldC5cbiAgICAqL1xuICAgIGF0dHIsIFxuICAgIC8vIFRoZSBhdHRyaWJ1dGUncyBuZXcgdmFsdWUuXG4gICAgdmFsdWUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5hdHRyID0gYXR0cjtcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgbGV0IGF0dHJzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBkb2MuYXR0cnMpXG4gICAgICAgICAgICBhdHRyc1tuYW1lXSA9IGRvYy5hdHRyc1tuYW1lXTtcbiAgICAgICAgYXR0cnNbdGhpcy5hdHRyXSA9IHRoaXMudmFsdWU7XG4gICAgICAgIGxldCB1cGRhdGVkID0gZG9jLnR5cGUuY3JlYXRlKGF0dHJzLCBkb2MuY29udGVudCwgZG9jLm1hcmtzKTtcbiAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQub2sodXBkYXRlZCk7XG4gICAgfVxuICAgIGdldE1hcCgpIHtcbiAgICAgICAgcmV0dXJuIFN0ZXBNYXAuZW1wdHk7XG4gICAgfVxuICAgIGludmVydChkb2MpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEb2NBdHRyU3RlcCh0aGlzLmF0dHIsIGRvYy5hdHRyc1t0aGlzLmF0dHJdKTtcbiAgICB9XG4gICAgbWFwKG1hcHBpbmcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RlcFR5cGU6IFwiZG9jQXR0clwiLCBhdHRyOiB0aGlzLmF0dHIsIHZhbHVlOiB0aGlzLnZhbHVlIH07XG4gICAgfVxuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBqc29uLmF0dHIgIT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgRG9jQXR0clN0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgRG9jQXR0clN0ZXAoanNvbi5hdHRyLCBqc29uLnZhbHVlKTtcbiAgICB9XG59XG5TdGVwLmpzb25JRChcImRvY0F0dHJcIiwgRG9jQXR0clN0ZXApO1xuXG4vKipcbkBpbnRlcm5hbFxuKi9cbmxldCBUcmFuc2Zvcm1FcnJvciA9IGNsYXNzIGV4dGVuZHMgRXJyb3Ige1xufTtcblRyYW5zZm9ybUVycm9yID0gZnVuY3Rpb24gVHJhbnNmb3JtRXJyb3IobWVzc2FnZSkge1xuICAgIGxldCBlcnIgPSBFcnJvci5jYWxsKHRoaXMsIG1lc3NhZ2UpO1xuICAgIGVyci5fX3Byb3RvX18gPSBUcmFuc2Zvcm1FcnJvci5wcm90b3R5cGU7XG4gICAgcmV0dXJuIGVycjtcbn07XG5UcmFuc2Zvcm1FcnJvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEVycm9yLnByb3RvdHlwZSk7XG5UcmFuc2Zvcm1FcnJvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBUcmFuc2Zvcm1FcnJvcjtcblRyYW5zZm9ybUVycm9yLnByb3RvdHlwZS5uYW1lID0gXCJUcmFuc2Zvcm1FcnJvclwiO1xuLyoqXG5BYnN0cmFjdGlvbiB0byBidWlsZCB1cCBhbmQgdHJhY2sgYW4gYXJyYXkgb2ZcbltzdGVwc10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5TdGVwKSByZXByZXNlbnRpbmcgYSBkb2N1bWVudCB0cmFuc2Zvcm1hdGlvbi5cblxuTW9zdCB0cmFuc2Zvcm1pbmcgbWV0aG9kcyByZXR1cm4gdGhlIGBUcmFuc2Zvcm1gIG9iamVjdCBpdHNlbGYsIHNvXG50aGF0IHRoZXkgY2FuIGJlIGNoYWluZWQuXG4qL1xuY2xhc3MgVHJhbnNmb3JtIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSB0cmFuc2Zvcm0gdGhhdCBzdGFydHMgd2l0aCB0aGUgZ2l2ZW4gZG9jdW1lbnQuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgY3VycmVudCBkb2N1bWVudCAodGhlIHJlc3VsdCBvZiBhcHBseWluZyB0aGUgc3RlcHMgaW4gdGhlXG4gICAgdHJhbnNmb3JtKS5cbiAgICAqL1xuICAgIGRvYykge1xuICAgICAgICB0aGlzLmRvYyA9IGRvYztcbiAgICAgICAgLyoqXG4gICAgICAgIFRoZSBzdGVwcyBpbiB0aGlzIHRyYW5zZm9ybS5cbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5zdGVwcyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgVGhlIGRvY3VtZW50cyBiZWZvcmUgZWFjaCBvZiB0aGUgc3RlcHMuXG4gICAgICAgICovXG4gICAgICAgIHRoaXMuZG9jcyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgQSBtYXBwaW5nIHdpdGggdGhlIG1hcHMgZm9yIGVhY2ggb2YgdGhlIHN0ZXBzIGluIHRoaXMgdHJhbnNmb3JtLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLm1hcHBpbmcgPSBuZXcgTWFwcGluZztcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHN0YXJ0aW5nIGRvY3VtZW50LlxuICAgICovXG4gICAgZ2V0IGJlZm9yZSgpIHsgcmV0dXJuIHRoaXMuZG9jcy5sZW5ndGggPyB0aGlzLmRvY3NbMF0gOiB0aGlzLmRvYzsgfVxuICAgIC8qKlxuICAgIEFwcGx5IGEgbmV3IHN0ZXAgaW4gdGhpcyB0cmFuc2Zvcm0sIHNhdmluZyB0aGUgcmVzdWx0LiBUaHJvd3MgYW5cbiAgICBlcnJvciB3aGVuIHRoZSBzdGVwIGZhaWxzLlxuICAgICovXG4gICAgc3RlcChzdGVwKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSB0aGlzLm1heWJlU3RlcChzdGVwKTtcbiAgICAgICAgaWYgKHJlc3VsdC5mYWlsZWQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHJhbnNmb3JtRXJyb3IocmVzdWx0LmZhaWxlZCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBUcnkgdG8gYXBwbHkgYSBzdGVwIGluIHRoaXMgdHJhbnNmb3JtYXRpb24sIGlnbm9yaW5nIGl0IGlmIGl0XG4gICAgZmFpbHMuIFJldHVybnMgdGhlIHN0ZXAgcmVzdWx0LlxuICAgICovXG4gICAgbWF5YmVTdGVwKHN0ZXApIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IHN0ZXAuYXBwbHkodGhpcy5kb2MpO1xuICAgICAgICBpZiAoIXJlc3VsdC5mYWlsZWQpXG4gICAgICAgICAgICB0aGlzLmFkZFN0ZXAoc3RlcCwgcmVzdWx0LmRvYyk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGUgZG9jdW1lbnQgaGFzIGJlZW4gY2hhbmdlZCAod2hlbiB0aGVyZSBhcmUgYW55XG4gICAgc3RlcHMpLlxuICAgICovXG4gICAgZ2V0IGRvY0NoYW5nZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0ZXBzLmxlbmd0aCA+IDA7XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHVybiBhIHNpbmdsZSByYW5nZSwgaW4gcG9zdC10cmFuc2Zvcm0gZG9jdW1lbnQgcG9zaXRpb25zLFxuICAgIHRoYXQgY292ZXJzIGFsbCBjb250ZW50IGNoYW5nZWQgYnkgdGhpcyB0cmFuc2Zvcm0uIFJldHVybnMgbnVsbFxuICAgIGlmIG5vIHJlcGxhY2VtZW50cyBhcmUgbWFkZS4gTm90ZSB0aGF0IHRoaXMgd2lsbCBpZ25vcmUgY2hhbmdlc1xuICAgIHRoYXQgYWRkL3JlbW92ZSBtYXJrcyB3aXRob3V0IHJlcGxhY2luZyB0aGUgdW5kZXJseWluZyBjb250ZW50LlxuICAgICovXG4gICAgY2hhbmdlZFJhbmdlKCkge1xuICAgICAgICBsZXQgZnJvbSA9IDFlOSwgdG8gPSAtMWU5O1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubWFwcGluZy5tYXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbWFwID0gdGhpcy5tYXBwaW5nLm1hcHNbaV07XG4gICAgICAgICAgICBpZiAoaSkge1xuICAgICAgICAgICAgICAgIGZyb20gPSBtYXAubWFwKGZyb20sIDEpO1xuICAgICAgICAgICAgICAgIHRvID0gbWFwLm1hcCh0bywgLTEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWFwLmZvckVhY2goKF9mLCBfdCwgZnJvbUIsIHRvQikgPT4ge1xuICAgICAgICAgICAgICAgIGZyb20gPSBNYXRoLm1pbihmcm9tLCBmcm9tQik7XG4gICAgICAgICAgICAgICAgdG8gPSBNYXRoLm1heCh0bywgdG9CKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmcm9tID09IDFlOSA/IG51bGwgOiB7IGZyb20sIHRvIH07XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgYWRkU3RlcChzdGVwLCBkb2MpIHtcbiAgICAgICAgdGhpcy5kb2NzLnB1c2godGhpcy5kb2MpO1xuICAgICAgICB0aGlzLnN0ZXBzLnB1c2goc3RlcCk7XG4gICAgICAgIHRoaXMubWFwcGluZy5hcHBlbmRNYXAoc3RlcC5nZXRNYXAoKSk7XG4gICAgICAgIHRoaXMuZG9jID0gZG9jO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXBsYWNlIHRoZSBwYXJ0IG9mIHRoZSBkb2N1bWVudCBiZXR3ZWVuIGBmcm9tYCBhbmQgYHRvYCB3aXRoIHRoZVxuICAgIGdpdmVuIGBzbGljZWAuXG4gICAgKi9cbiAgICByZXBsYWNlKGZyb20sIHRvID0gZnJvbSwgc2xpY2UgPSBTbGljZS5lbXB0eSkge1xuICAgICAgICBsZXQgc3RlcCA9IHJlcGxhY2VTdGVwKHRoaXMuZG9jLCBmcm9tLCB0bywgc2xpY2UpO1xuICAgICAgICBpZiAoc3RlcClcbiAgICAgICAgICAgIHRoaXMuc3RlcChzdGVwKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIGdpdmVuIHJhbmdlIHdpdGggdGhlIGdpdmVuIGNvbnRlbnQsIHdoaWNoIG1heSBiZSBhXG4gICAgZnJhZ21lbnQsIG5vZGUsIG9yIGFycmF5IG9mIG5vZGVzLlxuICAgICovXG4gICAgcmVwbGFjZVdpdGgoZnJvbSwgdG8sIGNvbnRlbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZShmcm9tLCB0bywgbmV3IFNsaWNlKEZyYWdtZW50LmZyb20oY29udGVudCksIDAsIDApKTtcbiAgICB9XG4gICAgLyoqXG4gICAgRGVsZXRlIHRoZSBjb250ZW50IGJldHdlZW4gdGhlIGdpdmVuIHBvc2l0aW9ucy5cbiAgICAqL1xuICAgIGRlbGV0ZShmcm9tLCB0bykge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXBsYWNlKGZyb20sIHRvLCBTbGljZS5lbXB0eSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEluc2VydCB0aGUgZ2l2ZW4gY29udGVudCBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uXG4gICAgKi9cbiAgICBpbnNlcnQocG9zLCBjb250ZW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VXaXRoKHBvcywgcG9zLCBjb250ZW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmVwbGFjZSBhIHJhbmdlIG9mIHRoZSBkb2N1bWVudCB3aXRoIGEgZ2l2ZW4gc2xpY2UsIHVzaW5nXG4gICAgYGZyb21gLCBgdG9gLCBhbmQgdGhlIHNsaWNlJ3NcbiAgICBbYG9wZW5TdGFydGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5TbGljZS5vcGVuU3RhcnQpIHByb3BlcnR5IGFzIGhpbnRzLCByYXRoZXJcbiAgICB0aGFuIGZpeGVkIHN0YXJ0IGFuZCBlbmQgcG9pbnRzLiBUaGlzIG1ldGhvZCBtYXkgZ3JvdyB0aGVcbiAgICByZXBsYWNlZCBhcmVhIG9yIGNsb3NlIG9wZW4gbm9kZXMgaW4gdGhlIHNsaWNlIGluIG9yZGVyIHRvIGdldCBhXG4gICAgZml0IHRoYXQgaXMgbW9yZSBpbiBsaW5lIHdpdGggV1lTSVdZRyBleHBlY3RhdGlvbnMsIGJ5IGRyb3BwaW5nXG4gICAgZnVsbHkgY292ZXJlZCBwYXJlbnQgbm9kZXMgb2YgdGhlIHJlcGxhY2VkIHJlZ2lvbiB3aGVuIHRoZXkgYXJlXG4gICAgbWFya2VkIFtub24tZGVmaW5pbmcgYXNcbiAgICBjb250ZXh0XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuZGVmaW5pbmdBc0NvbnRleHQpLCBvciBpbmNsdWRpbmcgYW5cbiAgICBvcGVuIHBhcmVudCBub2RlIGZyb20gdGhlIHNsaWNlIHRoYXQgX2lzXyBtYXJrZWQgYXMgW2RlZmluaW5nXG4gICAgaXRzIGNvbnRlbnRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5kZWZpbmluZ0ZvckNvbnRlbnQpLlxuICAgIFxuICAgIFRoaXMgaXMgdGhlIG1ldGhvZCwgZm9yIGV4YW1wbGUsIHRvIGhhbmRsZSBwYXN0ZS4gVGhlIHNpbWlsYXJcbiAgICBbYHJlcGxhY2VgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdHJhbnNmb3JtLlRyYW5zZm9ybS5yZXBsYWNlKSBtZXRob2QgaXMgYSBtb3JlXG4gICAgcHJpbWl0aXZlIHRvb2wgd2hpY2ggd2lsbCBfbm90XyBtb3ZlIHRoZSBzdGFydCBhbmQgZW5kIG9mIGl0cyBnaXZlblxuICAgIHJhbmdlLCBhbmQgaXMgdXNlZnVsIGluIHNpdHVhdGlvbnMgd2hlcmUgeW91IG5lZWQgbW9yZSBwcmVjaXNlXG4gICAgY29udHJvbCBvdmVyIHdoYXQgaGFwcGVucy5cbiAgICAqL1xuICAgIHJlcGxhY2VSYW5nZShmcm9tLCB0bywgc2xpY2UpIHtcbiAgICAgICAgcmVwbGFjZVJhbmdlKHRoaXMsIGZyb20sIHRvLCBzbGljZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXBsYWNlIHRoZSBnaXZlbiByYW5nZSB3aXRoIGEgbm9kZSwgYnV0IHVzZSBgZnJvbWAgYW5kIGB0b2AgYXNcbiAgICBoaW50cywgcmF0aGVyIHRoYW4gcHJlY2lzZSBwb3NpdGlvbnMuIFdoZW4gZnJvbSBhbmQgdG8gYXJlIHRoZSBzYW1lXG4gICAgYW5kIGFyZSBhdCB0aGUgc3RhcnQgb3IgZW5kIG9mIGEgcGFyZW50IG5vZGUgaW4gd2hpY2ggdGhlIGdpdmVuXG4gICAgbm9kZSBkb2Vzbid0IGZpdCwgdGhpcyBtZXRob2QgbWF5IF9tb3ZlXyB0aGVtIG91dCB0b3dhcmRzIGEgcGFyZW50XG4gICAgdGhhdCBkb2VzIGFsbG93IHRoZSBnaXZlbiBub2RlIHRvIGJlIHBsYWNlZC4gV2hlbiB0aGUgZ2l2ZW4gcmFuZ2VcbiAgICBjb21wbGV0ZWx5IGNvdmVycyBhIHBhcmVudCBub2RlLCB0aGlzIG1ldGhvZCBtYXkgY29tcGxldGVseSByZXBsYWNlXG4gICAgdGhhdCBwYXJlbnQgbm9kZS5cbiAgICAqL1xuICAgIHJlcGxhY2VSYW5nZVdpdGgoZnJvbSwgdG8sIG5vZGUpIHtcbiAgICAgICAgcmVwbGFjZVJhbmdlV2l0aCh0aGlzLCBmcm9tLCB0bywgbm9kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBEZWxldGUgdGhlIGdpdmVuIHJhbmdlLCBleHBhbmRpbmcgaXQgdG8gY292ZXIgZnVsbHkgY292ZXJlZFxuICAgIHBhcmVudCBub2RlcyB1bnRpbCBhIHZhbGlkIHJlcGxhY2UgaXMgZm91bmQuXG4gICAgKi9cbiAgICBkZWxldGVSYW5nZShmcm9tLCB0bykge1xuICAgICAgICBkZWxldGVSYW5nZSh0aGlzLCBmcm9tLCB0byk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBTcGxpdCB0aGUgY29udGVudCBpbiB0aGUgZ2l2ZW4gcmFuZ2Ugb2ZmIGZyb20gaXRzIHBhcmVudCwgaWYgdGhlcmVcbiAgICBpcyBzaWJsaW5nIGNvbnRlbnQgYmVmb3JlIG9yIGFmdGVyIGl0LCBhbmQgbW92ZSBpdCB1cCB0aGUgdHJlZSB0b1xuICAgIHRoZSBkZXB0aCBzcGVjaWZpZWQgYnkgYHRhcmdldGAuIFlvdSdsbCBwcm9iYWJseSB3YW50IHRvIHVzZVxuICAgIFtgbGlmdFRhcmdldGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0ubGlmdFRhcmdldCkgdG8gY29tcHV0ZSBgdGFyZ2V0YCwgdG8gbWFrZVxuICAgIHN1cmUgdGhlIGxpZnQgaXMgdmFsaWQuXG4gICAgKi9cbiAgICBsaWZ0KHJhbmdlLCB0YXJnZXQpIHtcbiAgICAgICAgbGlmdCh0aGlzLCByYW5nZSwgdGFyZ2V0KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIEpvaW4gdGhlIGJsb2NrcyBhcm91bmQgdGhlIGdpdmVuIHBvc2l0aW9uLiBJZiBkZXB0aCBpcyAyLCB0aGVpclxuICAgIGxhc3QgYW5kIGZpcnN0IHNpYmxpbmdzIGFyZSBhbHNvIGpvaW5lZCwgYW5kIHNvIG9uLlxuICAgICovXG4gICAgam9pbihwb3MsIGRlcHRoID0gMSkge1xuICAgICAgICBqb2luKHRoaXMsIHBvcywgZGVwdGgpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgV3JhcCB0aGUgZ2l2ZW4gW3JhbmdlXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVJhbmdlKSBpbiB0aGUgZ2l2ZW4gc2V0IG9mIHdyYXBwZXJzLlxuICAgIFRoZSB3cmFwcGVycyBhcmUgYXNzdW1lZCB0byBiZSB2YWxpZCBpbiB0aGlzIHBvc2l0aW9uLCBhbmQgc2hvdWxkXG4gICAgcHJvYmFibHkgYmUgY29tcHV0ZWQgd2l0aCBbYGZpbmRXcmFwcGluZ2BdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0uZmluZFdyYXBwaW5nKS5cbiAgICAqL1xuICAgIHdyYXAocmFuZ2UsIHdyYXBwZXJzKSB7XG4gICAgICAgIHdyYXAodGhpcywgcmFuZ2UsIHdyYXBwZXJzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFNldCB0aGUgdHlwZSBvZiBhbGwgdGV4dGJsb2NrcyAocGFydGx5KSBiZXR3ZWVuIGBmcm9tYCBhbmQgYHRvYCB0b1xuICAgIHRoZSBnaXZlbiBub2RlIHR5cGUgd2l0aCB0aGUgZ2l2ZW4gYXR0cmlidXRlcy5cbiAgICAqL1xuICAgIHNldEJsb2NrVHlwZShmcm9tLCB0byA9IGZyb20sIHR5cGUsIGF0dHJzID0gbnVsbCkge1xuICAgICAgICBzZXRCbG9ja1R5cGUodGhpcywgZnJvbSwgdG8sIHR5cGUsIGF0dHJzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIENoYW5nZSB0aGUgdHlwZSwgYXR0cmlidXRlcywgYW5kL29yIG1hcmtzIG9mIHRoZSBub2RlIGF0IGBwb3NgLlxuICAgIFdoZW4gYHR5cGVgIGlzbid0IGdpdmVuLCB0aGUgZXhpc3Rpbmcgbm9kZSB0eXBlIGlzIHByZXNlcnZlZCxcbiAgICAqL1xuICAgIHNldE5vZGVNYXJrdXAocG9zLCB0eXBlLCBhdHRycyA9IG51bGwsIG1hcmtzKSB7XG4gICAgICAgIHNldE5vZGVNYXJrdXAodGhpcywgcG9zLCB0eXBlLCBhdHRycywgbWFya3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgU2V0IGEgc2luZ2xlIGF0dHJpYnV0ZSBvbiBhIGdpdmVuIG5vZGUgdG8gYSBuZXcgdmFsdWUuXG4gICAgVGhlIGBwb3NgIGFkZHJlc3NlcyB0aGUgZG9jdW1lbnQgY29udGVudC4gVXNlIGBzZXREb2NBdHRyaWJ1dGVgXG4gICAgdG8gc2V0IGF0dHJpYnV0ZXMgb24gdGhlIGRvY3VtZW50IGl0c2VsZi5cbiAgICAqL1xuICAgIHNldE5vZGVBdHRyaWJ1dGUocG9zLCBhdHRyLCB2YWx1ZSkge1xuICAgICAgICB0aGlzLnN0ZXAobmV3IEF0dHJTdGVwKHBvcywgYXR0ciwgdmFsdWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFNldCBhIHNpbmdsZSBhdHRyaWJ1dGUgb24gdGhlIGRvY3VtZW50IHRvIGEgbmV3IHZhbHVlLlxuICAgICovXG4gICAgc2V0RG9jQXR0cmlidXRlKGF0dHIsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuc3RlcChuZXcgRG9jQXR0clN0ZXAoYXR0ciwgdmFsdWUpKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIEFkZCBhIG1hcmsgdG8gdGhlIG5vZGUgYXQgcG9zaXRpb24gYHBvc2AuXG4gICAgKi9cbiAgICBhZGROb2RlTWFyayhwb3MsIG1hcmspIHtcbiAgICAgICAgdGhpcy5zdGVwKG5ldyBBZGROb2RlTWFya1N0ZXAocG9zLCBtYXJrKSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBSZW1vdmUgYSBtYXJrIChvciBhbGwgbWFya3Mgb2YgdGhlIGdpdmVuIHR5cGUpIGZyb20gdGhlIG5vZGUgYXRcbiAgICBwb3NpdGlvbiBgcG9zYC5cbiAgICAqL1xuICAgIHJlbW92ZU5vZGVNYXJrKHBvcywgbWFyaykge1xuICAgICAgICBsZXQgbm9kZSA9IHRoaXMuZG9jLm5vZGVBdChwb3MpO1xuICAgICAgICBpZiAoIW5vZGUpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIk5vIG5vZGUgYXQgcG9zaXRpb24gXCIgKyBwb3MpO1xuICAgICAgICBpZiAobWFyayBpbnN0YW5jZW9mIE1hcmspIHtcbiAgICAgICAgICAgIGlmIChtYXJrLmlzSW5TZXQobm9kZS5tYXJrcykpXG4gICAgICAgICAgICAgICAgdGhpcy5zdGVwKG5ldyBSZW1vdmVOb2RlTWFya1N0ZXAocG9zLCBtYXJrKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgc2V0ID0gbm9kZS5tYXJrcywgZm91bmQsIHN0ZXBzID0gW107XG4gICAgICAgICAgICB3aGlsZSAoZm91bmQgPSBtYXJrLmlzSW5TZXQoc2V0KSkge1xuICAgICAgICAgICAgICAgIHN0ZXBzLnB1c2gobmV3IFJlbW92ZU5vZGVNYXJrU3RlcChwb3MsIGZvdW5kKSk7XG4gICAgICAgICAgICAgICAgc2V0ID0gZm91bmQucmVtb3ZlRnJvbVNldChzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0ZXBzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKVxuICAgICAgICAgICAgICAgIHRoaXMuc3RlcChzdGVwc1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFNwbGl0IHRoZSBub2RlIGF0IHRoZSBnaXZlbiBwb3NpdGlvbiwgYW5kIG9wdGlvbmFsbHksIGlmIGBkZXB0aGAgaXNcbiAgICBncmVhdGVyIHRoYW4gb25lLCBhbnkgbnVtYmVyIG9mIG5vZGVzIGFib3ZlIHRoYXQuIEJ5IGRlZmF1bHQsIHRoZVxuICAgIHBhcnRzIHNwbGl0IG9mZiB3aWxsIGluaGVyaXQgdGhlIG5vZGUgdHlwZSBvZiB0aGUgb3JpZ2luYWwgbm9kZS5cbiAgICBUaGlzIGNhbiBiZSBjaGFuZ2VkIGJ5IHBhc3NpbmcgYW4gYXJyYXkgb2YgdHlwZXMgYW5kIGF0dHJpYnV0ZXMgdG9cbiAgICB1c2UgYWZ0ZXIgdGhlIHNwbGl0ICh3aXRoIHRoZSBvdXRlcm1vc3Qgbm9kZXMgY29taW5nIGZpcnN0KS5cbiAgICAqL1xuICAgIHNwbGl0KHBvcywgZGVwdGggPSAxLCB0eXBlc0FmdGVyKSB7XG4gICAgICAgIHNwbGl0KHRoaXMsIHBvcywgZGVwdGgsIHR5cGVzQWZ0ZXIpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgQWRkIHRoZSBnaXZlbiBtYXJrIHRvIHRoZSBpbmxpbmUgY29udGVudCBiZXR3ZWVuIGBmcm9tYCBhbmQgYHRvYC5cbiAgICAqL1xuICAgIGFkZE1hcmsoZnJvbSwgdG8sIG1hcmspIHtcbiAgICAgICAgYWRkTWFyayh0aGlzLCBmcm9tLCB0bywgbWFyayk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBSZW1vdmUgbWFya3MgZnJvbSBpbmxpbmUgbm9kZXMgYmV0d2VlbiBgZnJvbWAgYW5kIGB0b2AuIFdoZW5cbiAgICBgbWFya2AgaXMgYSBzaW5nbGUgbWFyaywgcmVtb3ZlIHByZWNpc2VseSB0aGF0IG1hcmsuIFdoZW4gaXQgaXNcbiAgICBhIG1hcmsgdHlwZSwgcmVtb3ZlIGFsbCBtYXJrcyBvZiB0aGF0IHR5cGUuIFdoZW4gaXQgaXMgbnVsbCxcbiAgICByZW1vdmUgYWxsIG1hcmtzIG9mIGFueSB0eXBlLlxuICAgICovXG4gICAgcmVtb3ZlTWFyayhmcm9tLCB0bywgbWFyaykge1xuICAgICAgICByZW1vdmVNYXJrKHRoaXMsIGZyb20sIHRvLCBtYXJrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlbW92ZXMgYWxsIG1hcmtzIGFuZCBub2RlcyBmcm9tIHRoZSBjb250ZW50IG9mIHRoZSBub2RlIGF0XG4gICAgYHBvc2AgdGhhdCBkb24ndCBtYXRjaCB0aGUgZ2l2ZW4gbmV3IHBhcmVudCBub2RlIHR5cGUuIEFjY2VwdHNcbiAgICBhbiBvcHRpb25hbCBzdGFydGluZyBbY29udGVudCBtYXRjaF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLkNvbnRlbnRNYXRjaCkgYXNcbiAgICB0aGlyZCBhcmd1bWVudC5cbiAgICAqL1xuICAgIGNsZWFySW5jb21wYXRpYmxlKHBvcywgcGFyZW50VHlwZSwgbWF0Y2gpIHtcbiAgICAgICAgY2xlYXJJbmNvbXBhdGlibGUodGhpcywgcG9zLCBwYXJlbnRUeXBlLCBtYXRjaCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuZXhwb3J0IHsgQWRkTWFya1N0ZXAsIEFkZE5vZGVNYXJrU3RlcCwgQXR0clN0ZXAsIERvY0F0dHJTdGVwLCBNYXBSZXN1bHQsIE1hcHBpbmcsIFJlbW92ZU1hcmtTdGVwLCBSZW1vdmVOb2RlTWFya1N0ZXAsIFJlcGxhY2VBcm91bmRTdGVwLCBSZXBsYWNlU3RlcCwgU3RlcCwgU3RlcE1hcCwgU3RlcFJlc3VsdCwgVHJhbnNmb3JtLCBUcmFuc2Zvcm1FcnJvciwgY2FuSm9pbiwgY2FuU3BsaXQsIGRyb3BQb2ludCwgZmluZFdyYXBwaW5nLCBpbnNlcnRQb2ludCwgam9pblBvaW50LCBsaWZ0VGFyZ2V0LCByZXBsYWNlU3RlcCB9O1xuIiwgImltcG9ydCB7IFNsaWNlLCBGcmFnbWVudCwgTWFyaywgTm9kZSB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB7IFJlcGxhY2VTdGVwLCBSZXBsYWNlQXJvdW5kU3RlcCwgVHJhbnNmb3JtIH0gZnJvbSAncHJvc2VtaXJyb3ItdHJhbnNmb3JtJztcblxuY29uc3QgY2xhc3Nlc0J5SWQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuLyoqXG5TdXBlcmNsYXNzIGZvciBlZGl0b3Igc2VsZWN0aW9ucy4gRXZlcnkgc2VsZWN0aW9uIHR5cGUgc2hvdWxkXG5leHRlbmQgdGhpcy4gU2hvdWxkIG5vdCBiZSBpbnN0YW50aWF0ZWQgZGlyZWN0bHkuXG4qL1xuY2xhc3MgU2VsZWN0aW9uIHtcbiAgICAvKipcbiAgICBJbml0aWFsaXplIGEgc2VsZWN0aW9uIHdpdGggdGhlIGhlYWQgYW5kIGFuY2hvciBhbmQgcmFuZ2VzLiBJZiBub1xuICAgIHJhbmdlcyBhcmUgZ2l2ZW4sIGNvbnN0cnVjdHMgYSBzaW5nbGUgcmFuZ2UgYWNyb3NzIGAkYW5jaG9yYCBhbmRcbiAgICBgJGhlYWRgLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHJlc29sdmVkIGFuY2hvciBvZiB0aGUgc2VsZWN0aW9uICh0aGUgc2lkZSB0aGF0IHN0YXlzIGluXG4gICAgcGxhY2Ugd2hlbiB0aGUgc2VsZWN0aW9uIGlzIG1vZGlmaWVkKS5cbiAgICAqL1xuICAgICRhbmNob3IsIFxuICAgIC8qKlxuICAgIFRoZSByZXNvbHZlZCBoZWFkIG9mIHRoZSBzZWxlY3Rpb24gKHRoZSBzaWRlIHRoYXQgbW92ZXMgd2hlblxuICAgIHRoZSBzZWxlY3Rpb24gaXMgbW9kaWZpZWQpLlxuICAgICovXG4gICAgJGhlYWQsIHJhbmdlcykge1xuICAgICAgICB0aGlzLiRhbmNob3IgPSAkYW5jaG9yO1xuICAgICAgICB0aGlzLiRoZWFkID0gJGhlYWQ7XG4gICAgICAgIHRoaXMucmFuZ2VzID0gcmFuZ2VzIHx8IFtuZXcgU2VsZWN0aW9uUmFuZ2UoJGFuY2hvci5taW4oJGhlYWQpLCAkYW5jaG9yLm1heCgkaGVhZCkpXTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHNlbGVjdGlvbidzIGFuY2hvciwgYXMgYW4gdW5yZXNvbHZlZCBwb3NpdGlvbi5cbiAgICAqL1xuICAgIGdldCBhbmNob3IoKSB7IHJldHVybiB0aGlzLiRhbmNob3IucG9zOyB9XG4gICAgLyoqXG4gICAgVGhlIHNlbGVjdGlvbidzIGhlYWQuXG4gICAgKi9cbiAgICBnZXQgaGVhZCgpIHsgcmV0dXJuIHRoaXMuJGhlYWQucG9zOyB9XG4gICAgLyoqXG4gICAgVGhlIGxvd2VyIGJvdW5kIG9mIHRoZSBzZWxlY3Rpb24ncyBtYWluIHJhbmdlLlxuICAgICovXG4gICAgZ2V0IGZyb20oKSB7IHJldHVybiB0aGlzLiRmcm9tLnBvczsgfVxuICAgIC8qKlxuICAgIFRoZSB1cHBlciBib3VuZCBvZiB0aGUgc2VsZWN0aW9uJ3MgbWFpbiByYW5nZS5cbiAgICAqL1xuICAgIGdldCB0bygpIHsgcmV0dXJuIHRoaXMuJHRvLnBvczsgfVxuICAgIC8qKlxuICAgIFRoZSByZXNvbHZlZCBsb3dlciAgYm91bmQgb2YgdGhlIHNlbGVjdGlvbidzIG1haW4gcmFuZ2UuXG4gICAgKi9cbiAgICBnZXQgJGZyb20oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJhbmdlc1swXS4kZnJvbTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHJlc29sdmVkIHVwcGVyIGJvdW5kIG9mIHRoZSBzZWxlY3Rpb24ncyBtYWluIHJhbmdlLlxuICAgICovXG4gICAgZ2V0ICR0bygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmFuZ2VzWzBdLiR0bztcbiAgICB9XG4gICAgLyoqXG4gICAgSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHNlbGVjdGlvbiBjb250YWlucyBhbnkgY29udGVudC5cbiAgICAqL1xuICAgIGdldCBlbXB0eSgpIHtcbiAgICAgICAgbGV0IHJhbmdlcyA9IHRoaXMucmFuZ2VzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmIChyYW5nZXNbaV0uJGZyb20ucG9zICE9IHJhbmdlc1tpXS4kdG8ucG9zKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgY29udGVudCBvZiB0aGlzIHNlbGVjdGlvbiBhcyBhIHNsaWNlLlxuICAgICovXG4gICAgY29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJGZyb20uZG9jLnNsaWNlKHRoaXMuZnJvbSwgdGhpcy50bywgdHJ1ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIHNlbGVjdGlvbiB3aXRoIGEgc2xpY2Ugb3IsIGlmIG5vIHNsaWNlIGlzIGdpdmVuLFxuICAgIGRlbGV0ZSB0aGUgc2VsZWN0aW9uLiBXaWxsIGFwcGVuZCB0byB0aGUgZ2l2ZW4gdHJhbnNhY3Rpb24uXG4gICAgKi9cbiAgICByZXBsYWNlKHRyLCBjb250ZW50ID0gU2xpY2UuZW1wdHkpIHtcbiAgICAgICAgLy8gUHV0IHRoZSBuZXcgc2VsZWN0aW9uIGF0IHRoZSBwb3NpdGlvbiBhZnRlciB0aGUgaW5zZXJ0ZWRcbiAgICAgICAgLy8gY29udGVudC4gV2hlbiB0aGF0IGVuZGVkIGluIGFuIGlubGluZSBub2RlLCBzZWFyY2ggYmFja3dhcmRzLFxuICAgICAgICAvLyB0byBnZXQgdGhlIHBvc2l0aW9uIGFmdGVyIHRoYXQgbm9kZS4gSWYgbm90LCBzZWFyY2ggZm9yd2FyZC5cbiAgICAgICAgbGV0IGxhc3ROb2RlID0gY29udGVudC5jb250ZW50Lmxhc3RDaGlsZCwgbGFzdFBhcmVudCA9IG51bGw7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29udGVudC5vcGVuRW5kOyBpKyspIHtcbiAgICAgICAgICAgIGxhc3RQYXJlbnQgPSBsYXN0Tm9kZTtcbiAgICAgICAgICAgIGxhc3ROb2RlID0gbGFzdE5vZGUubGFzdENoaWxkO1xuICAgICAgICB9XG4gICAgICAgIGxldCBtYXBGcm9tID0gdHIuc3RlcHMubGVuZ3RoLCByYW5nZXMgPSB0aGlzLnJhbmdlcztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB7ICRmcm9tLCAkdG8gfSA9IHJhbmdlc1tpXSwgbWFwcGluZyA9IHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSk7XG4gICAgICAgICAgICB0ci5yZXBsYWNlUmFuZ2UobWFwcGluZy5tYXAoJGZyb20ucG9zKSwgbWFwcGluZy5tYXAoJHRvLnBvcyksIGkgPyBTbGljZS5lbXB0eSA6IGNvbnRlbnQpO1xuICAgICAgICAgICAgaWYgKGkgPT0gMClcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25Ub0luc2VydGlvbkVuZCh0ciwgbWFwRnJvbSwgKGxhc3ROb2RlID8gbGFzdE5vZGUuaXNJbmxpbmUgOiBsYXN0UGFyZW50ICYmIGxhc3RQYXJlbnQuaXNUZXh0YmxvY2spID8gLTEgOiAxKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBSZXBsYWNlIHRoZSBzZWxlY3Rpb24gd2l0aCB0aGUgZ2l2ZW4gbm9kZSwgYXBwZW5kaW5nIHRoZSBjaGFuZ2VzXG4gICAgdG8gdGhlIGdpdmVuIHRyYW5zYWN0aW9uLlxuICAgICovXG4gICAgcmVwbGFjZVdpdGgodHIsIG5vZGUpIHtcbiAgICAgICAgbGV0IG1hcEZyb20gPSB0ci5zdGVwcy5sZW5ndGgsIHJhbmdlcyA9IHRoaXMucmFuZ2VzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHsgJGZyb20sICR0byB9ID0gcmFuZ2VzW2ldLCBtYXBwaW5nID0gdHIubWFwcGluZy5zbGljZShtYXBGcm9tKTtcbiAgICAgICAgICAgIGxldCBmcm9tID0gbWFwcGluZy5tYXAoJGZyb20ucG9zKSwgdG8gPSBtYXBwaW5nLm1hcCgkdG8ucG9zKTtcbiAgICAgICAgICAgIGlmIChpKSB7XG4gICAgICAgICAgICAgICAgdHIuZGVsZXRlUmFuZ2UoZnJvbSwgdG8pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdHIucmVwbGFjZVJhbmdlV2l0aChmcm9tLCB0bywgbm9kZSk7XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uVG9JbnNlcnRpb25FbmQodHIsIG1hcEZyb20sIG5vZGUuaXNJbmxpbmUgPyAtMSA6IDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgYSB2YWxpZCBjdXJzb3Igb3IgbGVhZiBub2RlIHNlbGVjdGlvbiBzdGFydGluZyBhdCB0aGUgZ2l2ZW5cbiAgICBwb3NpdGlvbiBhbmQgc2VhcmNoaW5nIGJhY2sgaWYgYGRpcmAgaXMgbmVnYXRpdmUsIGFuZCBmb3J3YXJkIGlmXG4gICAgcG9zaXRpdmUuIFdoZW4gYHRleHRPbmx5YCBpcyB0cnVlLCBvbmx5IGNvbnNpZGVyIGN1cnNvclxuICAgIHNlbGVjdGlvbnMuIFdpbGwgcmV0dXJuIG51bGwgd2hlbiBubyB2YWxpZCBzZWxlY3Rpb24gcG9zaXRpb24gaXNcbiAgICBmb3VuZC5cbiAgICAqL1xuICAgIHN0YXRpYyBmaW5kRnJvbSgkcG9zLCBkaXIsIHRleHRPbmx5ID0gZmFsc2UpIHtcbiAgICAgICAgbGV0IGlubmVyID0gJHBvcy5wYXJlbnQuaW5saW5lQ29udGVudCA/IG5ldyBUZXh0U2VsZWN0aW9uKCRwb3MpXG4gICAgICAgICAgICA6IGZpbmRTZWxlY3Rpb25JbigkcG9zLm5vZGUoMCksICRwb3MucGFyZW50LCAkcG9zLnBvcywgJHBvcy5pbmRleCgpLCBkaXIsIHRleHRPbmx5KTtcbiAgICAgICAgaWYgKGlubmVyKVxuICAgICAgICAgICAgcmV0dXJuIGlubmVyO1xuICAgICAgICBmb3IgKGxldCBkZXB0aCA9ICRwb3MuZGVwdGggLSAxOyBkZXB0aCA+PSAwOyBkZXB0aC0tKSB7XG4gICAgICAgICAgICBsZXQgZm91bmQgPSBkaXIgPCAwXG4gICAgICAgICAgICAgICAgPyBmaW5kU2VsZWN0aW9uSW4oJHBvcy5ub2RlKDApLCAkcG9zLm5vZGUoZGVwdGgpLCAkcG9zLmJlZm9yZShkZXB0aCArIDEpLCAkcG9zLmluZGV4KGRlcHRoKSwgZGlyLCB0ZXh0T25seSlcbiAgICAgICAgICAgICAgICA6IGZpbmRTZWxlY3Rpb25JbigkcG9zLm5vZGUoMCksICRwb3Mubm9kZShkZXB0aCksICRwb3MuYWZ0ZXIoZGVwdGggKyAxKSwgJHBvcy5pbmRleChkZXB0aCkgKyAxLCBkaXIsIHRleHRPbmx5KTtcbiAgICAgICAgICAgIGlmIChmb3VuZClcbiAgICAgICAgICAgICAgICByZXR1cm4gZm91bmQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgYSB2YWxpZCBjdXJzb3Igb3IgbGVhZiBub2RlIHNlbGVjdGlvbiBuZWFyIHRoZSBnaXZlblxuICAgIHBvc2l0aW9uLiBTZWFyY2hlcyBmb3J3YXJkIGZpcnN0IGJ5IGRlZmF1bHQsIGJ1dCBpZiBgYmlhc2AgaXNcbiAgICBuZWdhdGl2ZSwgaXQgd2lsbCBzZWFyY2ggYmFja3dhcmRzIGZpcnN0LlxuICAgICovXG4gICAgc3RhdGljIG5lYXIoJHBvcywgYmlhcyA9IDEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmluZEZyb20oJHBvcywgYmlhcykgfHwgdGhpcy5maW5kRnJvbSgkcG9zLCAtYmlhcykgfHwgbmV3IEFsbFNlbGVjdGlvbigkcG9zLm5vZGUoMCkpO1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSBjdXJzb3Igb3IgbGVhZiBub2RlIHNlbGVjdGlvbiBjbG9zZXN0IHRvIHRoZSBzdGFydCBvZlxuICAgIHRoZSBnaXZlbiBkb2N1bWVudC4gV2lsbCByZXR1cm4gYW5cbiAgICBbYEFsbFNlbGVjdGlvbmBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5BbGxTZWxlY3Rpb24pIGlmIG5vIHZhbGlkIHBvc2l0aW9uXG4gICAgZXhpc3RzLlxuICAgICovXG4gICAgc3RhdGljIGF0U3RhcnQoZG9jKSB7XG4gICAgICAgIHJldHVybiBmaW5kU2VsZWN0aW9uSW4oZG9jLCBkb2MsIDAsIDAsIDEpIHx8IG5ldyBBbGxTZWxlY3Rpb24oZG9jKTtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCB0aGUgY3Vyc29yIG9yIGxlYWYgbm9kZSBzZWxlY3Rpb24gY2xvc2VzdCB0byB0aGUgZW5kIG9mIHRoZVxuICAgIGdpdmVuIGRvY3VtZW50LlxuICAgICovXG4gICAgc3RhdGljIGF0RW5kKGRvYykge1xuICAgICAgICByZXR1cm4gZmluZFNlbGVjdGlvbkluKGRvYywgZG9jLCBkb2MuY29udGVudC5zaXplLCBkb2MuY2hpbGRDb3VudCwgLTEpIHx8IG5ldyBBbGxTZWxlY3Rpb24oZG9jKTtcbiAgICB9XG4gICAgLyoqXG4gICAgRGVzZXJpYWxpemUgdGhlIEpTT04gcmVwcmVzZW50YXRpb24gb2YgYSBzZWxlY3Rpb24uIE11c3QgYmVcbiAgICBpbXBsZW1lbnRlZCBmb3IgY3VzdG9tIGNsYXNzZXMgKGFzIGEgc3RhdGljIGNsYXNzIG1ldGhvZCkuXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oZG9jLCBqc29uKSB7XG4gICAgICAgIGlmICghanNvbiB8fCAhanNvbi50eXBlKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBTZWxlY3Rpb24uZnJvbUpTT05cIik7XG4gICAgICAgIGxldCBjbHMgPSBjbGFzc2VzQnlJZFtqc29uLnR5cGVdO1xuICAgICAgICBpZiAoIWNscylcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBObyBzZWxlY3Rpb24gdHlwZSAke2pzb24udHlwZX0gZGVmaW5lZGApO1xuICAgICAgICByZXR1cm4gY2xzLmZyb21KU09OKGRvYywganNvbik7XG4gICAgfVxuICAgIC8qKlxuICAgIFRvIGJlIGFibGUgdG8gZGVzZXJpYWxpemUgc2VsZWN0aW9ucyBmcm9tIEpTT04sIGN1c3RvbSBzZWxlY3Rpb25cbiAgICBjbGFzc2VzIG11c3QgcmVnaXN0ZXIgdGhlbXNlbHZlcyB3aXRoIGFuIElEIHN0cmluZywgc28gdGhhdCB0aGV5XG4gICAgY2FuIGJlIGRpc2FtYmlndWF0ZWQuIFRyeSB0byBwaWNrIHNvbWV0aGluZyB0aGF0J3MgdW5saWtlbHkgdG9cbiAgICBjbGFzaCB3aXRoIGNsYXNzZXMgZnJvbSBvdGhlciBtb2R1bGVzLlxuICAgICovXG4gICAgc3RhdGljIGpzb25JRChpZCwgc2VsZWN0aW9uQ2xhc3MpIHtcbiAgICAgICAgaWYgKGlkIGluIGNsYXNzZXNCeUlkKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJEdXBsaWNhdGUgdXNlIG9mIHNlbGVjdGlvbiBKU09OIElEIFwiICsgaWQpO1xuICAgICAgICBjbGFzc2VzQnlJZFtpZF0gPSBzZWxlY3Rpb25DbGFzcztcbiAgICAgICAgc2VsZWN0aW9uQ2xhc3MucHJvdG90eXBlLmpzb25JRCA9IGlkO1xuICAgICAgICByZXR1cm4gc2VsZWN0aW9uQ2xhc3M7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCBhIFtib29rbWFya10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLlNlbGVjdGlvbkJvb2ttYXJrKSBmb3IgdGhpcyBzZWxlY3Rpb24sXG4gICAgd2hpY2ggaXMgYSB2YWx1ZSB0aGF0IGNhbiBiZSBtYXBwZWQgd2l0aG91dCBoYXZpbmcgYWNjZXNzIHRvIGFcbiAgICBjdXJyZW50IGRvY3VtZW50LCBhbmQgbGF0ZXIgcmVzb2x2ZWQgdG8gYSByZWFsIHNlbGVjdGlvbiBmb3IgYVxuICAgIGdpdmVuIGRvY3VtZW50IGFnYWluLiAoVGhpcyBpcyB1c2VkIG1vc3RseSBieSB0aGUgaGlzdG9yeSB0b1xuICAgIHRyYWNrIGFuZCByZXN0b3JlIG9sZCBzZWxlY3Rpb25zLikgVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gb2ZcbiAgICB0aGlzIG1ldGhvZCBqdXN0IGNvbnZlcnRzIHRoZSBzZWxlY3Rpb24gdG8gYSB0ZXh0IHNlbGVjdGlvbiBhbmRcbiAgICByZXR1cm5zIHRoZSBib29rbWFyayBmb3IgdGhhdC5cbiAgICAqL1xuICAgIGdldEJvb2ttYXJrKCkge1xuICAgICAgICByZXR1cm4gVGV4dFNlbGVjdGlvbi5iZXR3ZWVuKHRoaXMuJGFuY2hvciwgdGhpcy4kaGVhZCkuZ2V0Qm9va21hcmsoKTtcbiAgICB9XG59XG5TZWxlY3Rpb24ucHJvdG90eXBlLnZpc2libGUgPSB0cnVlO1xuLyoqXG5SZXByZXNlbnRzIGEgc2VsZWN0ZWQgcmFuZ2UgaW4gYSBkb2N1bWVudC5cbiovXG5jbGFzcyBTZWxlY3Rpb25SYW5nZSB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgcmFuZ2UuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgbG93ZXIgYm91bmQgb2YgdGhlIHJhbmdlLlxuICAgICovXG4gICAgJGZyb20sIFxuICAgIC8qKlxuICAgIFRoZSB1cHBlciBib3VuZCBvZiB0aGUgcmFuZ2UuXG4gICAgKi9cbiAgICAkdG8pIHtcbiAgICAgICAgdGhpcy4kZnJvbSA9ICRmcm9tO1xuICAgICAgICB0aGlzLiR0byA9ICR0bztcbiAgICB9XG59XG5sZXQgd2FybmVkQWJvdXRUZXh0U2VsZWN0aW9uID0gZmFsc2U7XG5mdW5jdGlvbiBjaGVja1RleHRTZWxlY3Rpb24oJHBvcykge1xuICAgIGlmICghd2FybmVkQWJvdXRUZXh0U2VsZWN0aW9uICYmICEkcG9zLnBhcmVudC5pbmxpbmVDb250ZW50KSB7XG4gICAgICAgIHdhcm5lZEFib3V0VGV4dFNlbGVjdGlvbiA9IHRydWU7XG4gICAgICAgIGNvbnNvbGVbXCJ3YXJuXCJdKFwiVGV4dFNlbGVjdGlvbiBlbmRwb2ludCBub3QgcG9pbnRpbmcgaW50byBhIG5vZGUgd2l0aCBpbmxpbmUgY29udGVudCAoXCIgKyAkcG9zLnBhcmVudC50eXBlLm5hbWUgKyBcIilcIik7XG4gICAgfVxufVxuLyoqXG5BIHRleHQgc2VsZWN0aW9uIHJlcHJlc2VudHMgYSBjbGFzc2ljYWwgZWRpdG9yIHNlbGVjdGlvbiwgd2l0aCBhXG5oZWFkICh0aGUgbW92aW5nIHNpZGUpIGFuZCBhbmNob3IgKGltbW9iaWxlIHNpZGUpLCBib3RoIG9mIHdoaWNoXG5wb2ludCBpbnRvIHRleHRibG9jayBub2Rlcy4gSXQgY2FuIGJlIGVtcHR5IChhIHJlZ3VsYXIgY3Vyc29yXG5wb3NpdGlvbikuXG4qL1xuY2xhc3MgVGV4dFNlbGVjdGlvbiBleHRlbmRzIFNlbGVjdGlvbiB7XG4gICAgLyoqXG4gICAgQ29uc3RydWN0IGEgdGV4dCBzZWxlY3Rpb24gYmV0d2VlbiB0aGUgZ2l2ZW4gcG9pbnRzLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoJGFuY2hvciwgJGhlYWQgPSAkYW5jaG9yKSB7XG4gICAgICAgIGNoZWNrVGV4dFNlbGVjdGlvbigkYW5jaG9yKTtcbiAgICAgICAgY2hlY2tUZXh0U2VsZWN0aW9uKCRoZWFkKTtcbiAgICAgICAgc3VwZXIoJGFuY2hvciwgJGhlYWQpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm5zIGEgcmVzb2x2ZWQgcG9zaXRpb24gaWYgdGhpcyBpcyBhIGN1cnNvciBzZWxlY3Rpb24gKGFuXG4gICAgZW1wdHkgdGV4dCBzZWxlY3Rpb24pLCBhbmQgbnVsbCBvdGhlcndpc2UuXG4gICAgKi9cbiAgICBnZXQgJGN1cnNvcigpIHsgcmV0dXJuIHRoaXMuJGFuY2hvci5wb3MgPT0gdGhpcy4kaGVhZC5wb3MgPyB0aGlzLiRoZWFkIDogbnVsbDsgfVxuICAgIG1hcChkb2MsIG1hcHBpbmcpIHtcbiAgICAgICAgbGV0ICRoZWFkID0gZG9jLnJlc29sdmUobWFwcGluZy5tYXAodGhpcy5oZWFkKSk7XG4gICAgICAgIGlmICghJGhlYWQucGFyZW50LmlubGluZUNvbnRlbnQpXG4gICAgICAgICAgICByZXR1cm4gU2VsZWN0aW9uLm5lYXIoJGhlYWQpO1xuICAgICAgICBsZXQgJGFuY2hvciA9IGRvYy5yZXNvbHZlKG1hcHBpbmcubWFwKHRoaXMuYW5jaG9yKSk7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dFNlbGVjdGlvbigkYW5jaG9yLnBhcmVudC5pbmxpbmVDb250ZW50ID8gJGFuY2hvciA6ICRoZWFkLCAkaGVhZCk7XG4gICAgfVxuICAgIHJlcGxhY2UodHIsIGNvbnRlbnQgPSBTbGljZS5lbXB0eSkge1xuICAgICAgICBzdXBlci5yZXBsYWNlKHRyLCBjb250ZW50KTtcbiAgICAgICAgaWYgKGNvbnRlbnQgPT0gU2xpY2UuZW1wdHkpIHtcbiAgICAgICAgICAgIGxldCBtYXJrcyA9IHRoaXMuJGZyb20ubWFya3NBY3Jvc3ModGhpcy4kdG8pO1xuICAgICAgICAgICAgaWYgKG1hcmtzKVxuICAgICAgICAgICAgICAgIHRyLmVuc3VyZU1hcmtzKG1hcmtzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlcShvdGhlcikge1xuICAgICAgICByZXR1cm4gb3RoZXIgaW5zdGFuY2VvZiBUZXh0U2VsZWN0aW9uICYmIG90aGVyLmFuY2hvciA9PSB0aGlzLmFuY2hvciAmJiBvdGhlci5oZWFkID09IHRoaXMuaGVhZDtcbiAgICB9XG4gICAgZ2V0Qm9va21hcmsoKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dEJvb2ttYXJrKHRoaXMuYW5jaG9yLCB0aGlzLmhlYWQpO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB7IHR5cGU6IFwidGV4dFwiLCBhbmNob3I6IHRoaXMuYW5jaG9yLCBoZWFkOiB0aGlzLmhlYWQgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oZG9jLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5hbmNob3IgIT0gXCJudW1iZXJcIiB8fCB0eXBlb2YganNvbi5oZWFkICE9IFwibnVtYmVyXCIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIFRleHRTZWxlY3Rpb24uZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dFNlbGVjdGlvbihkb2MucmVzb2x2ZShqc29uLmFuY2hvciksIGRvYy5yZXNvbHZlKGpzb24uaGVhZCkpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSB0ZXh0IHNlbGVjdGlvbiBmcm9tIG5vbi1yZXNvbHZlZCBwb3NpdGlvbnMuXG4gICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlKGRvYywgYW5jaG9yLCBoZWFkID0gYW5jaG9yKSB7XG4gICAgICAgIGxldCAkYW5jaG9yID0gZG9jLnJlc29sdmUoYW5jaG9yKTtcbiAgICAgICAgcmV0dXJuIG5ldyB0aGlzKCRhbmNob3IsIGhlYWQgPT0gYW5jaG9yID8gJGFuY2hvciA6IGRvYy5yZXNvbHZlKGhlYWQpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJuIGEgdGV4dCBzZWxlY3Rpb24gdGhhdCBzcGFucyB0aGUgZ2l2ZW4gcG9zaXRpb25zIG9yLCBpZlxuICAgIHRoZXkgYXJlbid0IHRleHQgcG9zaXRpb25zLCBmaW5kIGEgdGV4dCBzZWxlY3Rpb24gbmVhciB0aGVtLlxuICAgIGBiaWFzYCBkZXRlcm1pbmVzIHdoZXRoZXIgdGhlIG1ldGhvZCBzZWFyY2hlcyBmb3J3YXJkIChkZWZhdWx0KVxuICAgIG9yIGJhY2t3YXJkcyAobmVnYXRpdmUgbnVtYmVyKSBmaXJzdC4gV2lsbCBmYWxsIGJhY2sgdG8gY2FsbGluZ1xuICAgIFtgU2VsZWN0aW9uLm5lYXJgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuU2VsZWN0aW9uXm5lYXIpIHdoZW4gdGhlIGRvY3VtZW50XG4gICAgZG9lc24ndCBjb250YWluIGEgdmFsaWQgdGV4dCBwb3NpdGlvbi5cbiAgICAqL1xuICAgIHN0YXRpYyBiZXR3ZWVuKCRhbmNob3IsICRoZWFkLCBiaWFzKSB7XG4gICAgICAgIGxldCBkUG9zID0gJGFuY2hvci5wb3MgLSAkaGVhZC5wb3M7XG4gICAgICAgIGlmICghYmlhcyB8fCBkUG9zKVxuICAgICAgICAgICAgYmlhcyA9IGRQb3MgPj0gMCA/IDEgOiAtMTtcbiAgICAgICAgaWYgKCEkaGVhZC5wYXJlbnQuaW5saW5lQ29udGVudCkge1xuICAgICAgICAgICAgbGV0IGZvdW5kID0gU2VsZWN0aW9uLmZpbmRGcm9tKCRoZWFkLCBiaWFzLCB0cnVlKSB8fCBTZWxlY3Rpb24uZmluZEZyb20oJGhlYWQsIC1iaWFzLCB0cnVlKTtcbiAgICAgICAgICAgIGlmIChmb3VuZClcbiAgICAgICAgICAgICAgICAkaGVhZCA9IGZvdW5kLiRoZWFkO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHJldHVybiBTZWxlY3Rpb24ubmVhcigkaGVhZCwgYmlhcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEkYW5jaG9yLnBhcmVudC5pbmxpbmVDb250ZW50KSB7XG4gICAgICAgICAgICBpZiAoZFBvcyA9PSAwKSB7XG4gICAgICAgICAgICAgICAgJGFuY2hvciA9ICRoZWFkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgJGFuY2hvciA9IChTZWxlY3Rpb24uZmluZEZyb20oJGFuY2hvciwgLWJpYXMsIHRydWUpIHx8IFNlbGVjdGlvbi5maW5kRnJvbSgkYW5jaG9yLCBiaWFzLCB0cnVlKSkuJGFuY2hvcjtcbiAgICAgICAgICAgICAgICBpZiAoKCRhbmNob3IucG9zIDwgJGhlYWQucG9zKSAhPSAoZFBvcyA8IDApKVxuICAgICAgICAgICAgICAgICAgICAkYW5jaG9yID0gJGhlYWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0U2VsZWN0aW9uKCRhbmNob3IsICRoZWFkKTtcbiAgICB9XG59XG5TZWxlY3Rpb24uanNvbklEKFwidGV4dFwiLCBUZXh0U2VsZWN0aW9uKTtcbmNsYXNzIFRleHRCb29rbWFyayB7XG4gICAgY29uc3RydWN0b3IoYW5jaG9yLCBoZWFkKSB7XG4gICAgICAgIHRoaXMuYW5jaG9yID0gYW5jaG9yO1xuICAgICAgICB0aGlzLmhlYWQgPSBoZWFkO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICByZXR1cm4gbmV3IFRleHRCb29rbWFyayhtYXBwaW5nLm1hcCh0aGlzLmFuY2hvciksIG1hcHBpbmcubWFwKHRoaXMuaGVhZCkpO1xuICAgIH1cbiAgICByZXNvbHZlKGRvYykge1xuICAgICAgICByZXR1cm4gVGV4dFNlbGVjdGlvbi5iZXR3ZWVuKGRvYy5yZXNvbHZlKHRoaXMuYW5jaG9yKSwgZG9jLnJlc29sdmUodGhpcy5oZWFkKSk7XG4gICAgfVxufVxuLyoqXG5BIG5vZGUgc2VsZWN0aW9uIGlzIGEgc2VsZWN0aW9uIHRoYXQgcG9pbnRzIGF0IGEgc2luZ2xlIG5vZGUuIEFsbFxubm9kZXMgbWFya2VkIFtzZWxlY3RhYmxlXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuc2VsZWN0YWJsZSkgY2FuIGJlIHRoZVxudGFyZ2V0IG9mIGEgbm9kZSBzZWxlY3Rpb24uIEluIHN1Y2ggYSBzZWxlY3Rpb24sIGBmcm9tYCBhbmQgYHRvYFxucG9pbnQgZGlyZWN0bHkgYmVmb3JlIGFuZCBhZnRlciB0aGUgc2VsZWN0ZWQgbm9kZSwgYGFuY2hvcmAgZXF1YWxzXG5gZnJvbWAsIGFuZCBgaGVhZGAgZXF1YWxzIGB0b2AuLlxuKi9cbmNsYXNzIE5vZGVTZWxlY3Rpb24gZXh0ZW5kcyBTZWxlY3Rpb24ge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5vZGUgc2VsZWN0aW9uLiBEb2VzIG5vdCB2ZXJpZnkgdGhlIHZhbGlkaXR5IG9mIGl0c1xuICAgIGFyZ3VtZW50LlxuICAgICovXG4gICAgY29uc3RydWN0b3IoJHBvcykge1xuICAgICAgICBsZXQgbm9kZSA9ICRwb3Mubm9kZUFmdGVyO1xuICAgICAgICBsZXQgJGVuZCA9ICRwb3Mubm9kZSgwKS5yZXNvbHZlKCRwb3MucG9zICsgbm9kZS5ub2RlU2l6ZSk7XG4gICAgICAgIHN1cGVyKCRwb3MsICRlbmQpO1xuICAgICAgICB0aGlzLm5vZGUgPSBub2RlO1xuICAgIH1cbiAgICBtYXAoZG9jLCBtYXBwaW5nKSB7XG4gICAgICAgIGxldCB7IGRlbGV0ZWQsIHBvcyB9ID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy5hbmNob3IpO1xuICAgICAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHBvcyk7XG4gICAgICAgIGlmIChkZWxldGVkKVxuICAgICAgICAgICAgcmV0dXJuIFNlbGVjdGlvbi5uZWFyKCRwb3MpO1xuICAgICAgICByZXR1cm4gbmV3IE5vZGVTZWxlY3Rpb24oJHBvcyk7XG4gICAgfVxuICAgIGNvbnRlbnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbSh0aGlzLm5vZGUpLCAwLCAwKTtcbiAgICB9XG4gICAgZXEob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIG90aGVyIGluc3RhbmNlb2YgTm9kZVNlbGVjdGlvbiAmJiBvdGhlci5hbmNob3IgPT0gdGhpcy5hbmNob3I7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHsgdHlwZTogXCJub2RlXCIsIGFuY2hvcjogdGhpcy5hbmNob3IgfTtcbiAgICB9XG4gICAgZ2V0Qm9va21hcmsoKSB7IHJldHVybiBuZXcgTm9kZUJvb2ttYXJrKHRoaXMuYW5jaG9yKTsgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKGRvYywganNvbikge1xuICAgICAgICBpZiAodHlwZW9mIGpzb24uYW5jaG9yICE9IFwibnVtYmVyXCIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIE5vZGVTZWxlY3Rpb24uZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZVNlbGVjdGlvbihkb2MucmVzb2x2ZShqc29uLmFuY2hvcikpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBub2RlIHNlbGVjdGlvbiBmcm9tIG5vbi1yZXNvbHZlZCBwb3NpdGlvbnMuXG4gICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlKGRvYywgZnJvbSkge1xuICAgICAgICByZXR1cm4gbmV3IE5vZGVTZWxlY3Rpb24oZG9jLnJlc29sdmUoZnJvbSkpO1xuICAgIH1cbiAgICAvKipcbiAgICBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIGdpdmVuIG5vZGUgbWF5IGJlIHNlbGVjdGVkIGFzIGEgbm9kZVxuICAgIHNlbGVjdGlvbi5cbiAgICAqL1xuICAgIHN0YXRpYyBpc1NlbGVjdGFibGUobm9kZSkge1xuICAgICAgICByZXR1cm4gIW5vZGUuaXNUZXh0ICYmIG5vZGUudHlwZS5zcGVjLnNlbGVjdGFibGUgIT09IGZhbHNlO1xuICAgIH1cbn1cbk5vZGVTZWxlY3Rpb24ucHJvdG90eXBlLnZpc2libGUgPSBmYWxzZTtcblNlbGVjdGlvbi5qc29uSUQoXCJub2RlXCIsIE5vZGVTZWxlY3Rpb24pO1xuY2xhc3MgTm9kZUJvb2ttYXJrIHtcbiAgICBjb25zdHJ1Y3RvcihhbmNob3IpIHtcbiAgICAgICAgdGhpcy5hbmNob3IgPSBhbmNob3I7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nKSB7XG4gICAgICAgIGxldCB7IGRlbGV0ZWQsIHBvcyB9ID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy5hbmNob3IpO1xuICAgICAgICByZXR1cm4gZGVsZXRlZCA/IG5ldyBUZXh0Qm9va21hcmsocG9zLCBwb3MpIDogbmV3IE5vZGVCb29rbWFyayhwb3MpO1xuICAgIH1cbiAgICByZXNvbHZlKGRvYykge1xuICAgICAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHRoaXMuYW5jaG9yKSwgbm9kZSA9ICRwb3Mubm9kZUFmdGVyO1xuICAgICAgICBpZiAobm9kZSAmJiBOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZShub2RlKSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgTm9kZVNlbGVjdGlvbigkcG9zKTtcbiAgICAgICAgcmV0dXJuIFNlbGVjdGlvbi5uZWFyKCRwb3MpO1xuICAgIH1cbn1cbi8qKlxuQSBzZWxlY3Rpb24gdHlwZSB0aGF0IHJlcHJlc2VudHMgc2VsZWN0aW5nIHRoZSB3aG9sZSBkb2N1bWVudFxuKHdoaWNoIGNhbiBub3QgbmVjZXNzYXJpbHkgYmUgZXhwcmVzc2VkIHdpdGggYSB0ZXh0IHNlbGVjdGlvbiwgd2hlblxudGhlcmUgYXJlIGZvciBleGFtcGxlIGxlYWYgYmxvY2sgbm9kZXMgYXQgdGhlIHN0YXJ0IG9yIGVuZCBvZiB0aGVcbmRvY3VtZW50KS5cbiovXG5jbGFzcyBBbGxTZWxlY3Rpb24gZXh0ZW5kcyBTZWxlY3Rpb24ge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhbiBhbGwtc2VsZWN0aW9uIG92ZXIgdGhlIGdpdmVuIGRvY3VtZW50LlxuICAgICovXG4gICAgY29uc3RydWN0b3IoZG9jKSB7XG4gICAgICAgIHN1cGVyKGRvYy5yZXNvbHZlKDApLCBkb2MucmVzb2x2ZShkb2MuY29udGVudC5zaXplKSk7XG4gICAgfVxuICAgIHJlcGxhY2UodHIsIGNvbnRlbnQgPSBTbGljZS5lbXB0eSkge1xuICAgICAgICBpZiAoY29udGVudCA9PSBTbGljZS5lbXB0eSkge1xuICAgICAgICAgICAgdHIuZGVsZXRlKDAsIHRyLmRvYy5jb250ZW50LnNpemUpO1xuICAgICAgICAgICAgbGV0IHNlbCA9IFNlbGVjdGlvbi5hdFN0YXJ0KHRyLmRvYyk7XG4gICAgICAgICAgICBpZiAoIXNlbC5lcSh0ci5zZWxlY3Rpb24pKVxuICAgICAgICAgICAgICAgIHRyLnNldFNlbGVjdGlvbihzZWwpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc3VwZXIucmVwbGFjZSh0ciwgY29udGVudCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdG9KU09OKCkgeyByZXR1cm4geyB0eXBlOiBcImFsbFwiIH07IH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihkb2MpIHsgcmV0dXJuIG5ldyBBbGxTZWxlY3Rpb24oZG9jKTsgfVxuICAgIG1hcChkb2MpIHsgcmV0dXJuIG5ldyBBbGxTZWxlY3Rpb24oZG9jKTsgfVxuICAgIGVxKG90aGVyKSB7IHJldHVybiBvdGhlciBpbnN0YW5jZW9mIEFsbFNlbGVjdGlvbjsgfVxuICAgIGdldEJvb2ttYXJrKCkgeyByZXR1cm4gQWxsQm9va21hcms7IH1cbn1cblNlbGVjdGlvbi5qc29uSUQoXCJhbGxcIiwgQWxsU2VsZWN0aW9uKTtcbmNvbnN0IEFsbEJvb2ttYXJrID0ge1xuICAgIG1hcCgpIHsgcmV0dXJuIHRoaXM7IH0sXG4gICAgcmVzb2x2ZShkb2MpIHsgcmV0dXJuIG5ldyBBbGxTZWxlY3Rpb24oZG9jKTsgfVxufTtcbi8vIEZJWE1FIHdlJ2xsIG5lZWQgc29tZSBhd2FyZW5lc3Mgb2YgdGV4dCBkaXJlY3Rpb24gd2hlbiBzY2FubmluZyBmb3Igc2VsZWN0aW9uc1xuLy8gVHJ5IHRvIGZpbmQgYSBzZWxlY3Rpb24gaW5zaWRlIHRoZSBnaXZlbiBub2RlLiBgcG9zYCBwb2ludHMgYXQgdGhlXG4vLyBwb3NpdGlvbiB3aGVyZSB0aGUgc2VhcmNoIHN0YXJ0cy4gV2hlbiBgdGV4dGAgaXMgdHJ1ZSwgb25seSByZXR1cm5cbi8vIHRleHQgc2VsZWN0aW9ucy5cbmZ1bmN0aW9uIGZpbmRTZWxlY3Rpb25Jbihkb2MsIG5vZGUsIHBvcywgaW5kZXgsIGRpciwgdGV4dCA9IGZhbHNlKSB7XG4gICAgaWYgKG5vZGUuaW5saW5lQ29udGVudClcbiAgICAgICAgcmV0dXJuIFRleHRTZWxlY3Rpb24uY3JlYXRlKGRvYywgcG9zKTtcbiAgICBmb3IgKGxldCBpID0gaW5kZXggLSAoZGlyID4gMCA/IDAgOiAxKTsgZGlyID4gMCA/IGkgPCBub2RlLmNoaWxkQ291bnQgOiBpID49IDA7IGkgKz0gZGlyKSB7XG4gICAgICAgIGxldCBjaGlsZCA9IG5vZGUuY2hpbGQoaSk7XG4gICAgICAgIGlmICghY2hpbGQuaXNBdG9tKSB7XG4gICAgICAgICAgICBsZXQgaW5uZXIgPSBmaW5kU2VsZWN0aW9uSW4oZG9jLCBjaGlsZCwgcG9zICsgZGlyLCBkaXIgPCAwID8gY2hpbGQuY2hpbGRDb3VudCA6IDAsIGRpciwgdGV4dCk7XG4gICAgICAgICAgICBpZiAoaW5uZXIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGlubmVyO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCF0ZXh0ICYmIE5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKGNoaWxkKSkge1xuICAgICAgICAgICAgcmV0dXJuIE5vZGVTZWxlY3Rpb24uY3JlYXRlKGRvYywgcG9zIC0gKGRpciA8IDAgPyBjaGlsZC5ub2RlU2l6ZSA6IDApKTtcbiAgICAgICAgfVxuICAgICAgICBwb3MgKz0gY2hpbGQubm9kZVNpemUgKiBkaXI7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gc2VsZWN0aW9uVG9JbnNlcnRpb25FbmQodHIsIHN0YXJ0TGVuLCBiaWFzKSB7XG4gICAgbGV0IGxhc3QgPSB0ci5zdGVwcy5sZW5ndGggLSAxO1xuICAgIGlmIChsYXN0IDwgc3RhcnRMZW4pXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgc3RlcCA9IHRyLnN0ZXBzW2xhc3RdO1xuICAgIGlmICghKHN0ZXAgaW5zdGFuY2VvZiBSZXBsYWNlU3RlcCB8fCBzdGVwIGluc3RhbmNlb2YgUmVwbGFjZUFyb3VuZFN0ZXApKVxuICAgICAgICByZXR1cm47XG4gICAgbGV0IG1hcCA9IHRyLm1hcHBpbmcubWFwc1tsYXN0XSwgZW5kO1xuICAgIG1hcC5mb3JFYWNoKChfZnJvbSwgX3RvLCBfbmV3RnJvbSwgbmV3VG8pID0+IHsgaWYgKGVuZCA9PSBudWxsKVxuICAgICAgICBlbmQgPSBuZXdUbzsgfSk7XG4gICAgdHIuc2V0U2VsZWN0aW9uKFNlbGVjdGlvbi5uZWFyKHRyLmRvYy5yZXNvbHZlKGVuZCksIGJpYXMpKTtcbn1cblxuY29uc3QgVVBEQVRFRF9TRUwgPSAxLCBVUERBVEVEX01BUktTID0gMiwgVVBEQVRFRF9TQ1JPTEwgPSA0O1xuLyoqXG5BbiBlZGl0b3Igc3RhdGUgdHJhbnNhY3Rpb24sIHdoaWNoIGNhbiBiZSBhcHBsaWVkIHRvIGEgc3RhdGUgdG9cbmNyZWF0ZSBhbiB1cGRhdGVkIHN0YXRlLiBVc2VcbltgRWRpdG9yU3RhdGUudHJgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuRWRpdG9yU3RhdGUudHIpIHRvIGNyZWF0ZSBhbiBpbnN0YW5jZS5cblxuVHJhbnNhY3Rpb25zIHRyYWNrIGNoYW5nZXMgdG8gdGhlIGRvY3VtZW50ICh0aGV5IGFyZSBhIHN1YmNsYXNzIG9mXG5bYFRyYW5zZm9ybWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0uVHJhbnNmb3JtKSksIGJ1dCBhbHNvIG90aGVyIHN0YXRlIGNoYW5nZXMsXG5saWtlIHNlbGVjdGlvbiB1cGRhdGVzIGFuZCBhZGp1c3RtZW50cyBvZiB0aGUgc2V0IG9mIFtzdG9yZWRcbm1hcmtzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuRWRpdG9yU3RhdGUuc3RvcmVkTWFya3MpLiBJbiBhZGRpdGlvbiwgeW91IGNhbiBzdG9yZVxubWV0YWRhdGEgcHJvcGVydGllcyBpbiBhIHRyYW5zYWN0aW9uLCB3aGljaCBhcmUgZXh0cmEgcGllY2VzIG9mXG5pbmZvcm1hdGlvbiB0aGF0IGNsaWVudCBjb2RlIG9yIHBsdWdpbnMgY2FuIHVzZSB0byBkZXNjcmliZSB3aGF0IGFcbnRyYW5zYWN0aW9uIHJlcHJlc2VudHMsIHNvIHRoYXQgdGhleSBjYW4gdXBkYXRlIHRoZWlyIFtvd25cbnN0YXRlXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuU3RhdGVGaWVsZCkgYWNjb3JkaW5nbHkuXG5cblRoZSBbZWRpdG9yIHZpZXddKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3LkVkaXRvclZpZXcpIHVzZXMgYSBmZXcgbWV0YWRhdGFcbnByb3BlcnRpZXM6IGl0IHdpbGwgYXR0YWNoIGEgcHJvcGVydHkgYFwicG9pbnRlclwiYCB3aXRoIHRoZSB2YWx1ZVxuYHRydWVgIHRvIHNlbGVjdGlvbiB0cmFuc2FjdGlvbnMgZGlyZWN0bHkgY2F1c2VkIGJ5IG1vdXNlIG9yIHRvdWNoXG5pbnB1dCwgYSBgXCJjb21wb3NpdGlvblwiYCBwcm9wZXJ0eSBob2xkaW5nIGFuIElEIGlkZW50aWZ5aW5nIHRoZVxuY29tcG9zaXRpb24gdGhhdCBjYXVzZWQgaXQgdG8gdHJhbnNhY3Rpb25zIGNhdXNlZCBieSBjb21wb3NlZCBET01cbmlucHV0LCBhbmQgYSBgXCJ1aUV2ZW50XCJgIHByb3BlcnR5IG9mIHRoYXQgbWF5IGJlIGBcInBhc3RlXCJgLFxuYFwiY3V0XCJgLCBvciBgXCJkcm9wXCJgLlxuKi9cbmNsYXNzIFRyYW5zYWN0aW9uIGV4dGVuZHMgVHJhbnNmb3JtIHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHN0YXRlKSB7XG4gICAgICAgIHN1cGVyKHN0YXRlLmRvYyk7XG4gICAgICAgIC8vIFRoZSBzdGVwIGNvdW50IGZvciB3aGljaCB0aGUgY3VycmVudCBzZWxlY3Rpb24gaXMgdmFsaWQuXG4gICAgICAgIHRoaXMuY3VyU2VsZWN0aW9uRm9yID0gMDtcbiAgICAgICAgLy8gQml0ZmllbGQgdG8gdHJhY2sgd2hpY2ggYXNwZWN0cyBvZiB0aGUgc3RhdGUgd2VyZSB1cGRhdGVkIGJ5XG4gICAgICAgIC8vIHRoaXMgdHJhbnNhY3Rpb24uXG4gICAgICAgIHRoaXMudXBkYXRlZCA9IDA7XG4gICAgICAgIC8vIE9iamVjdCB1c2VkIHRvIHN0b3JlIG1ldGFkYXRhIHByb3BlcnRpZXMgZm9yIHRoZSB0cmFuc2FjdGlvbi5cbiAgICAgICAgdGhpcy5tZXRhID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy50aW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdGhpcy5jdXJTZWxlY3Rpb24gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgICAgIHRoaXMuc3RvcmVkTWFya3MgPSBzdGF0ZS5zdG9yZWRNYXJrcztcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHRyYW5zYWN0aW9uJ3MgY3VycmVudCBzZWxlY3Rpb24uIFRoaXMgZGVmYXVsdHMgdG8gdGhlIGVkaXRvclxuICAgIHNlbGVjdGlvbiBbbWFwcGVkXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuU2VsZWN0aW9uLm1hcCkgdGhyb3VnaCB0aGUgc3RlcHMgaW4gdGhlXG4gICAgdHJhbnNhY3Rpb24sIGJ1dCBjYW4gYmUgb3ZlcndyaXR0ZW4gd2l0aFxuICAgIFtgc2V0U2VsZWN0aW9uYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLlRyYW5zYWN0aW9uLnNldFNlbGVjdGlvbikuXG4gICAgKi9cbiAgICBnZXQgc2VsZWN0aW9uKCkge1xuICAgICAgICBpZiAodGhpcy5jdXJTZWxlY3Rpb25Gb3IgPCB0aGlzLnN0ZXBzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5jdXJTZWxlY3Rpb24gPSB0aGlzLmN1clNlbGVjdGlvbi5tYXAodGhpcy5kb2MsIHRoaXMubWFwcGluZy5zbGljZSh0aGlzLmN1clNlbGVjdGlvbkZvcikpO1xuICAgICAgICAgICAgdGhpcy5jdXJTZWxlY3Rpb25Gb3IgPSB0aGlzLnN0ZXBzLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5jdXJTZWxlY3Rpb247XG4gICAgfVxuICAgIC8qKlxuICAgIFVwZGF0ZSB0aGUgdHJhbnNhY3Rpb24ncyBjdXJyZW50IHNlbGVjdGlvbi4gV2lsbCBkZXRlcm1pbmUgdGhlXG4gICAgc2VsZWN0aW9uIHRoYXQgdGhlIGVkaXRvciBnZXRzIHdoZW4gdGhlIHRyYW5zYWN0aW9uIGlzIGFwcGxpZWQuXG4gICAgKi9cbiAgICBzZXRTZWxlY3Rpb24oc2VsZWN0aW9uKSB7XG4gICAgICAgIGlmIChzZWxlY3Rpb24uJGZyb20uZG9jICE9IHRoaXMuZG9jKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJTZWxlY3Rpb24gcGFzc2VkIHRvIHNldFNlbGVjdGlvbiBtdXN0IHBvaW50IGF0IHRoZSBjdXJyZW50IGRvY3VtZW50XCIpO1xuICAgICAgICB0aGlzLmN1clNlbGVjdGlvbiA9IHNlbGVjdGlvbjtcbiAgICAgICAgdGhpcy5jdXJTZWxlY3Rpb25Gb3IgPSB0aGlzLnN0ZXBzLmxlbmd0aDtcbiAgICAgICAgdGhpcy51cGRhdGVkID0gKHRoaXMudXBkYXRlZCB8IFVQREFURURfU0VMKSAmIH5VUERBVEVEX01BUktTO1xuICAgICAgICB0aGlzLnN0b3JlZE1hcmtzID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFdoZXRoZXIgdGhlIHNlbGVjdGlvbiB3YXMgZXhwbGljaXRseSB1cGRhdGVkIGJ5IHRoaXMgdHJhbnNhY3Rpb24uXG4gICAgKi9cbiAgICBnZXQgc2VsZWN0aW9uU2V0KCkge1xuICAgICAgICByZXR1cm4gKHRoaXMudXBkYXRlZCAmIFVQREFURURfU0VMKSA+IDA7XG4gICAgfVxuICAgIC8qKlxuICAgIFNldCB0aGUgY3VycmVudCBzdG9yZWQgbWFya3MuXG4gICAgKi9cbiAgICBzZXRTdG9yZWRNYXJrcyhtYXJrcykge1xuICAgICAgICB0aGlzLnN0b3JlZE1hcmtzID0gbWFya3M7XG4gICAgICAgIHRoaXMudXBkYXRlZCB8PSBVUERBVEVEX01BUktTO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgTWFrZSBzdXJlIHRoZSBjdXJyZW50IHN0b3JlZCBtYXJrcyBvciwgaWYgdGhhdCBpcyBudWxsLCB0aGUgbWFya3NcbiAgICBhdCB0aGUgc2VsZWN0aW9uLCBtYXRjaCB0aGUgZ2l2ZW4gc2V0IG9mIG1hcmtzLiBEb2VzIG5vdGhpbmcgaWZcbiAgICB0aGlzIGlzIGFscmVhZHkgdGhlIGNhc2UuXG4gICAgKi9cbiAgICBlbnN1cmVNYXJrcyhtYXJrcykge1xuICAgICAgICBpZiAoIU1hcmsuc2FtZVNldCh0aGlzLnN0b3JlZE1hcmtzIHx8IHRoaXMuc2VsZWN0aW9uLiRmcm9tLm1hcmtzKCksIG1hcmtzKSlcbiAgICAgICAgICAgIHRoaXMuc2V0U3RvcmVkTWFya3MobWFya3MpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgQWRkIGEgbWFyayB0byB0aGUgc2V0IG9mIHN0b3JlZCBtYXJrcy5cbiAgICAqL1xuICAgIGFkZFN0b3JlZE1hcmsobWFyaykge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnN1cmVNYXJrcyhtYXJrLmFkZFRvU2V0KHRoaXMuc3RvcmVkTWFya3MgfHwgdGhpcy5zZWxlY3Rpb24uJGhlYWQubWFya3MoKSkpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZW1vdmUgYSBtYXJrIG9yIG1hcmsgdHlwZSBmcm9tIHRoZSBzZXQgb2Ygc3RvcmVkIG1hcmtzLlxuICAgICovXG4gICAgcmVtb3ZlU3RvcmVkTWFyayhtYXJrKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuc3VyZU1hcmtzKG1hcmsucmVtb3ZlRnJvbVNldCh0aGlzLnN0b3JlZE1hcmtzIHx8IHRoaXMuc2VsZWN0aW9uLiRoZWFkLm1hcmtzKCkpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgV2hldGhlciB0aGUgc3RvcmVkIG1hcmtzIHdlcmUgZXhwbGljaXRseSBzZXQgZm9yIHRoaXMgdHJhbnNhY3Rpb24uXG4gICAgKi9cbiAgICBnZXQgc3RvcmVkTWFya3NTZXQoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy51cGRhdGVkICYgVVBEQVRFRF9NQVJLUykgPiAwO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGFkZFN0ZXAoc3RlcCwgZG9jKSB7XG4gICAgICAgIHN1cGVyLmFkZFN0ZXAoc3RlcCwgZG9jKTtcbiAgICAgICAgdGhpcy51cGRhdGVkID0gdGhpcy51cGRhdGVkICYgflVQREFURURfTUFSS1M7XG4gICAgICAgIHRoaXMuc3RvcmVkTWFya3MgPSBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBVcGRhdGUgdGhlIHRpbWVzdGFtcCBmb3IgdGhlIHRyYW5zYWN0aW9uLlxuICAgICovXG4gICAgc2V0VGltZSh0aW1lKSB7XG4gICAgICAgIHRoaXMudGltZSA9IHRpbWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXBsYWNlIHRoZSBjdXJyZW50IHNlbGVjdGlvbiB3aXRoIHRoZSBnaXZlbiBzbGljZS5cbiAgICAqL1xuICAgIHJlcGxhY2VTZWxlY3Rpb24oc2xpY2UpIHtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb24ucmVwbGFjZSh0aGlzLCBzbGljZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXBsYWNlIHRoZSBzZWxlY3Rpb24gd2l0aCB0aGUgZ2l2ZW4gbm9kZS4gV2hlbiBgaW5oZXJpdE1hcmtzYCBpc1xuICAgIHRydWUgYW5kIHRoZSBjb250ZW50IGlzIGlubGluZSwgaXQgaW5oZXJpdHMgdGhlIG1hcmtzIGZyb20gdGhlXG4gICAgcGxhY2Ugd2hlcmUgaXQgaXMgaW5zZXJ0ZWQuXG4gICAgKi9cbiAgICByZXBsYWNlU2VsZWN0aW9uV2l0aChub2RlLCBpbmhlcml0TWFya3MgPSB0cnVlKSB7XG4gICAgICAgIGxldCBzZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvbjtcbiAgICAgICAgaWYgKGluaGVyaXRNYXJrcylcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLm1hcmsodGhpcy5zdG9yZWRNYXJrcyB8fCAoc2VsZWN0aW9uLmVtcHR5ID8gc2VsZWN0aW9uLiRmcm9tLm1hcmtzKCkgOiAoc2VsZWN0aW9uLiRmcm9tLm1hcmtzQWNyb3NzKHNlbGVjdGlvbi4kdG8pIHx8IE1hcmsubm9uZSkpKTtcbiAgICAgICAgc2VsZWN0aW9uLnJlcGxhY2VXaXRoKHRoaXMsIG5vZGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgRGVsZXRlIHRoZSBzZWxlY3Rpb24uXG4gICAgKi9cbiAgICBkZWxldGVTZWxlY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uLnJlcGxhY2UodGhpcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXBsYWNlIHRoZSBnaXZlbiByYW5nZSwgb3IgdGhlIHNlbGVjdGlvbiBpZiBubyByYW5nZSBpcyBnaXZlbixcbiAgICB3aXRoIGEgdGV4dCBub2RlIGNvbnRhaW5pbmcgdGhlIGdpdmVuIHN0cmluZy5cbiAgICAqL1xuICAgIGluc2VydFRleHQodGV4dCwgZnJvbSwgdG8pIHtcbiAgICAgICAgbGV0IHNjaGVtYSA9IHRoaXMuZG9jLnR5cGUuc2NoZW1hO1xuICAgICAgICBpZiAoZnJvbSA9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAoIXRleHQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVsZXRlU2VsZWN0aW9uKCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5yZXBsYWNlU2VsZWN0aW9uV2l0aChzY2hlbWEudGV4dCh0ZXh0KSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAodG8gPT0gbnVsbClcbiAgICAgICAgICAgICAgICB0byA9IGZyb207XG4gICAgICAgICAgICBpZiAoIXRleHQpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGVsZXRlUmFuZ2UoZnJvbSwgdG8pO1xuICAgICAgICAgICAgbGV0IG1hcmtzID0gdGhpcy5zdG9yZWRNYXJrcztcbiAgICAgICAgICAgIGlmICghbWFya3MpIHtcbiAgICAgICAgICAgICAgICBsZXQgJGZyb20gPSB0aGlzLmRvYy5yZXNvbHZlKGZyb20pO1xuICAgICAgICAgICAgICAgIG1hcmtzID0gdG8gPT0gZnJvbSA/ICRmcm9tLm1hcmtzKCkgOiAkZnJvbS5tYXJrc0Fjcm9zcyh0aGlzLmRvYy5yZXNvbHZlKHRvKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnJlcGxhY2VSYW5nZVdpdGgoZnJvbSwgdG8sIHNjaGVtYS50ZXh0KHRleHQsIG1hcmtzKSk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2VsZWN0aW9uLmVtcHR5ICYmIHRoaXMuc2VsZWN0aW9uLnRvID09IGZyb20gKyB0ZXh0Lmxlbmd0aClcbiAgICAgICAgICAgICAgICB0aGlzLnNldFNlbGVjdGlvbihTZWxlY3Rpb24ubmVhcih0aGlzLnNlbGVjdGlvbi4kdG8pKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIFN0b3JlIGEgbWV0YWRhdGEgcHJvcGVydHkgaW4gdGhpcyB0cmFuc2FjdGlvbiwga2V5ZWQgZWl0aGVyIGJ5XG4gICAgbmFtZSBvciBieSBwbHVnaW4uXG4gICAgKi9cbiAgICBzZXRNZXRhKGtleSwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5tZXRhW3R5cGVvZiBrZXkgPT0gXCJzdHJpbmdcIiA/IGtleSA6IGtleS5rZXldID0gdmFsdWU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXRyaWV2ZSBhIG1ldGFkYXRhIHByb3BlcnR5IGZvciBhIGdpdmVuIG5hbWUgb3IgcGx1Z2luLlxuICAgICovXG4gICAgZ2V0TWV0YShrZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWV0YVt0eXBlb2Yga2V5ID09IFwic3RyaW5nXCIgPyBrZXkgOiBrZXkua2V5XTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJucyB0cnVlIGlmIHRoaXMgdHJhbnNhY3Rpb24gZG9lc24ndCBjb250YWluIGFueSBtZXRhZGF0YSxcbiAgICBhbmQgY2FuIHRodXMgc2FmZWx5IGJlIGV4dGVuZGVkLlxuICAgICovXG4gICAgZ2V0IGlzR2VuZXJpYygpIHtcbiAgICAgICAgZm9yIChsZXQgXyBpbiB0aGlzLm1ldGEpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICBJbmRpY2F0ZSB0aGF0IHRoZSBlZGl0b3Igc2hvdWxkIHNjcm9sbCB0aGUgc2VsZWN0aW9uIGludG8gdmlld1xuICAgIHdoZW4gdXBkYXRlZCB0byB0aGUgc3RhdGUgcHJvZHVjZWQgYnkgdGhpcyB0cmFuc2FjdGlvbi5cbiAgICAqL1xuICAgIHNjcm9sbEludG9WaWV3KCkge1xuICAgICAgICB0aGlzLnVwZGF0ZWQgfD0gVVBEQVRFRF9TQ1JPTEw7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhpcyB0cmFuc2FjdGlvbiBoYXMgaGFkIGBzY3JvbGxJbnRvVmlld2AgY2FsbGVkIG9uIGl0LlxuICAgICovXG4gICAgZ2V0IHNjcm9sbGVkSW50b1ZpZXcoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy51cGRhdGVkICYgVVBEQVRFRF9TQ1JPTEwpID4gMDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGJpbmQoZiwgc2VsZikge1xuICAgIHJldHVybiAhc2VsZiB8fCAhZiA/IGYgOiBmLmJpbmQoc2VsZik7XG59XG5jbGFzcyBGaWVsZERlc2Mge1xuICAgIGNvbnN0cnVjdG9yKG5hbWUsIGRlc2MsIHNlbGYpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5pbml0ID0gYmluZChkZXNjLmluaXQsIHNlbGYpO1xuICAgICAgICB0aGlzLmFwcGx5ID0gYmluZChkZXNjLmFwcGx5LCBzZWxmKTtcbiAgICB9XG59XG5jb25zdCBiYXNlRmllbGRzID0gW1xuICAgIG5ldyBGaWVsZERlc2MoXCJkb2NcIiwge1xuICAgICAgICBpbml0KGNvbmZpZykgeyByZXR1cm4gY29uZmlnLmRvYyB8fCBjb25maWcuc2NoZW1hLnRvcE5vZGVUeXBlLmNyZWF0ZUFuZEZpbGwoKTsgfSxcbiAgICAgICAgYXBwbHkodHIpIHsgcmV0dXJuIHRyLmRvYzsgfVxuICAgIH0pLFxuICAgIG5ldyBGaWVsZERlc2MoXCJzZWxlY3Rpb25cIiwge1xuICAgICAgICBpbml0KGNvbmZpZywgaW5zdGFuY2UpIHsgcmV0dXJuIGNvbmZpZy5zZWxlY3Rpb24gfHwgU2VsZWN0aW9uLmF0U3RhcnQoaW5zdGFuY2UuZG9jKTsgfSxcbiAgICAgICAgYXBwbHkodHIpIHsgcmV0dXJuIHRyLnNlbGVjdGlvbjsgfVxuICAgIH0pLFxuICAgIG5ldyBGaWVsZERlc2MoXCJzdG9yZWRNYXJrc1wiLCB7XG4gICAgICAgIGluaXQoY29uZmlnKSB7IHJldHVybiBjb25maWcuc3RvcmVkTWFya3MgfHwgbnVsbDsgfSxcbiAgICAgICAgYXBwbHkodHIsIF9tYXJrcywgX29sZCwgc3RhdGUpIHsgcmV0dXJuIHN0YXRlLnNlbGVjdGlvbi4kY3Vyc29yID8gdHIuc3RvcmVkTWFya3MgOiBudWxsOyB9XG4gICAgfSksXG4gICAgbmV3IEZpZWxkRGVzYyhcInNjcm9sbFRvU2VsZWN0aW9uXCIsIHtcbiAgICAgICAgaW5pdCgpIHsgcmV0dXJuIDA7IH0sXG4gICAgICAgIGFwcGx5KHRyLCBwcmV2KSB7IHJldHVybiB0ci5zY3JvbGxlZEludG9WaWV3ID8gcHJldiArIDEgOiBwcmV2OyB9XG4gICAgfSlcbl07XG4vLyBPYmplY3Qgd3JhcHBpbmcgdGhlIHBhcnQgb2YgYSBzdGF0ZSBvYmplY3QgdGhhdCBzdGF5cyB0aGUgc2FtZVxuLy8gYWNyb3NzIHRyYW5zYWN0aW9ucy4gU3RvcmVkIGluIHRoZSBzdGF0ZSdzIGBjb25maWdgIHByb3BlcnR5LlxuY2xhc3MgQ29uZmlndXJhdGlvbiB7XG4gICAgY29uc3RydWN0b3Ioc2NoZW1hLCBwbHVnaW5zKSB7XG4gICAgICAgIHRoaXMuc2NoZW1hID0gc2NoZW1hO1xuICAgICAgICB0aGlzLnBsdWdpbnMgPSBbXTtcbiAgICAgICAgdGhpcy5wbHVnaW5zQnlLZXkgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLmZpZWxkcyA9IGJhc2VGaWVsZHMuc2xpY2UoKTtcbiAgICAgICAgaWYgKHBsdWdpbnMpXG4gICAgICAgICAgICBwbHVnaW5zLmZvckVhY2gocGx1Z2luID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wbHVnaW5zQnlLZXlbcGx1Z2luLmtleV0pXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiQWRkaW5nIGRpZmZlcmVudCBpbnN0YW5jZXMgb2YgYSBrZXllZCBwbHVnaW4gKFwiICsgcGx1Z2luLmtleSArIFwiKVwiKTtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnMucHVzaChwbHVnaW4pO1xuICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luc0J5S2V5W3BsdWdpbi5rZXldID0gcGx1Z2luO1xuICAgICAgICAgICAgICAgIGlmIChwbHVnaW4uc3BlYy5zdGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maWVsZHMucHVzaChuZXcgRmllbGREZXNjKHBsdWdpbi5rZXksIHBsdWdpbi5zcGVjLnN0YXRlLCBwbHVnaW4pKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cbn1cbi8qKlxuVGhlIHN0YXRlIG9mIGEgUHJvc2VNaXJyb3IgZWRpdG9yIGlzIHJlcHJlc2VudGVkIGJ5IGFuIG9iamVjdCBvZlxudGhpcyB0eXBlLiBBIHN0YXRlIGlzIGEgcGVyc2lzdGVudCBkYXRhIHN0cnVjdHVyZeKAlGl0IGlzbid0XG51cGRhdGVkLCBidXQgcmF0aGVyIGEgbmV3IHN0YXRlIHZhbHVlIGlzIGNvbXB1dGVkIGZyb20gYW4gb2xkIG9uZVxudXNpbmcgdGhlIFtgYXBwbHlgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuRWRpdG9yU3RhdGUuYXBwbHkpIG1ldGhvZC5cblxuQSBzdGF0ZSBob2xkcyBhIG51bWJlciBvZiBidWlsdC1pbiBmaWVsZHMsIGFuZCBwbHVnaW5zIGNhblxuW2RlZmluZV0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLlBsdWdpblNwZWMuc3RhdGUpIGFkZGl0aW9uYWwgZmllbGRzLlxuKi9cbmNsYXNzIEVkaXRvclN0YXRlIHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uZmlnKSB7XG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgc2NoZW1hIG9mIHRoZSBzdGF0ZSdzIGRvY3VtZW50LlxuICAgICovXG4gICAgZ2V0IHNjaGVtYSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnNjaGVtYTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHBsdWdpbnMgdGhhdCBhcmUgYWN0aXZlIGluIHRoaXMgc3RhdGUuXG4gICAgKi9cbiAgICBnZXQgcGx1Z2lucygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnLnBsdWdpbnM7XG4gICAgfVxuICAgIC8qKlxuICAgIEFwcGx5IHRoZSBnaXZlbiB0cmFuc2FjdGlvbiB0byBwcm9kdWNlIGEgbmV3IHN0YXRlLlxuICAgICovXG4gICAgYXBwbHkodHIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXBwbHlUcmFuc2FjdGlvbih0cikuc3RhdGU7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgZmlsdGVyVHJhbnNhY3Rpb24odHIsIGlnbm9yZSA9IC0xKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jb25maWcucGx1Z2lucy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmIChpICE9IGlnbm9yZSkge1xuICAgICAgICAgICAgICAgIGxldCBwbHVnaW4gPSB0aGlzLmNvbmZpZy5wbHVnaW5zW2ldO1xuICAgICAgICAgICAgICAgIGlmIChwbHVnaW4uc3BlYy5maWx0ZXJUcmFuc2FjdGlvbiAmJiAhcGx1Z2luLnNwZWMuZmlsdGVyVHJhbnNhY3Rpb24uY2FsbChwbHVnaW4sIHRyLCB0aGlzKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgVmVyYm9zZSB2YXJpYW50IG9mIFtgYXBwbHlgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuRWRpdG9yU3RhdGUuYXBwbHkpIHRoYXRcbiAgICByZXR1cm5zIHRoZSBwcmVjaXNlIHRyYW5zYWN0aW9ucyB0aGF0IHdlcmUgYXBwbGllZCAod2hpY2ggbWlnaHRcbiAgICBiZSBpbmZsdWVuY2VkIGJ5IHRoZSBbdHJhbnNhY3Rpb25cbiAgICBob29rc10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLlBsdWdpblNwZWMuZmlsdGVyVHJhbnNhY3Rpb24pIG9mXG4gICAgcGx1Z2lucykgYWxvbmcgd2l0aCB0aGUgbmV3IHN0YXRlLlxuICAgICovXG4gICAgYXBwbHlUcmFuc2FjdGlvbihyb290VHIpIHtcbiAgICAgICAgaWYgKCF0aGlzLmZpbHRlclRyYW5zYWN0aW9uKHJvb3RUcikpXG4gICAgICAgICAgICByZXR1cm4geyBzdGF0ZTogdGhpcywgdHJhbnNhY3Rpb25zOiBbXSB9O1xuICAgICAgICBsZXQgdHJzID0gW3Jvb3RUcl0sIG5ld1N0YXRlID0gdGhpcy5hcHBseUlubmVyKHJvb3RUciksIHNlZW4gPSBudWxsO1xuICAgICAgICAvLyBUaGlzIGxvb3AgcmVwZWF0ZWRseSBnaXZlcyBwbHVnaW5zIGEgY2hhbmNlIHRvIHJlc3BvbmQgdG9cbiAgICAgICAgLy8gdHJhbnNhY3Rpb25zIGFzIG5ldyB0cmFuc2FjdGlvbnMgYXJlIGFkZGVkLCBtYWtpbmcgc3VyZSB0byBvbmx5XG4gICAgICAgIC8vIHBhc3MgdGhlIHRyYW5zYWN0aW9ucyB0aGUgcGx1Z2luIGRpZCBub3Qgc2VlIGJlZm9yZS5cbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgICAgbGV0IGhhdmVOZXcgPSBmYWxzZTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jb25maWcucGx1Z2lucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBwbHVnaW4gPSB0aGlzLmNvbmZpZy5wbHVnaW5zW2ldO1xuICAgICAgICAgICAgICAgIGlmIChwbHVnaW4uc3BlYy5hcHBlbmRUcmFuc2FjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbiA9IHNlZW4gPyBzZWVuW2ldLm4gOiAwLCBvbGRTdGF0ZSA9IHNlZW4gPyBzZWVuW2ldLnN0YXRlIDogdGhpcztcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRyID0gbiA8IHRycy5sZW5ndGggJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsdWdpbi5zcGVjLmFwcGVuZFRyYW5zYWN0aW9uLmNhbGwocGx1Z2luLCBuID8gdHJzLnNsaWNlKG4pIDogdHJzLCBvbGRTdGF0ZSwgbmV3U3RhdGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHIgJiYgbmV3U3RhdGUuZmlsdGVyVHJhbnNhY3Rpb24odHIsIGkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ci5zZXRNZXRhKFwiYXBwZW5kZWRUcmFuc2FjdGlvblwiLCByb290VHIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzZWVuKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlbiA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5jb25maWcucGx1Z2lucy5sZW5ndGg7IGorKylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vlbi5wdXNoKGogPCBpID8geyBzdGF0ZTogbmV3U3RhdGUsIG46IHRycy5sZW5ndGggfSA6IHsgc3RhdGU6IHRoaXMsIG46IDAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB0cnMucHVzaCh0cik7XG4gICAgICAgICAgICAgICAgICAgICAgICBuZXdTdGF0ZSA9IG5ld1N0YXRlLmFwcGx5SW5uZXIodHIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaGF2ZU5ldyA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlZW4pXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWVuW2ldID0geyBzdGF0ZTogbmV3U3RhdGUsIG46IHRycy5sZW5ndGggfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWhhdmVOZXcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc3RhdGU6IG5ld1N0YXRlLCB0cmFuc2FjdGlvbnM6IHRycyB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgYXBwbHlJbm5lcih0cikge1xuICAgICAgICBpZiAoIXRyLmJlZm9yZS5lcSh0aGlzLmRvYykpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkFwcGx5aW5nIGEgbWlzbWF0Y2hlZCB0cmFuc2FjdGlvblwiKTtcbiAgICAgICAgbGV0IG5ld0luc3RhbmNlID0gbmV3IEVkaXRvclN0YXRlKHRoaXMuY29uZmlnKSwgZmllbGRzID0gdGhpcy5jb25maWcuZmllbGRzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGZpZWxkID0gZmllbGRzW2ldO1xuICAgICAgICAgICAgbmV3SW5zdGFuY2VbZmllbGQubmFtZV0gPSBmaWVsZC5hcHBseSh0ciwgdGhpc1tmaWVsZC5uYW1lXSwgdGhpcywgbmV3SW5zdGFuY2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXdJbnN0YW5jZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQWNjZXNzb3IgdGhhdCBjb25zdHJ1Y3RzIGFuZCByZXR1cm5zIGEgbmV3IFt0cmFuc2FjdGlvbl0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLlRyYW5zYWN0aW9uKSBmcm9tIHRoaXMgc3RhdGUuXG4gICAgKi9cbiAgICBnZXQgdHIoKSB7IHJldHVybiBuZXcgVHJhbnNhY3Rpb24odGhpcyk7IH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBuZXcgc3RhdGUuXG4gICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlKGNvbmZpZykge1xuICAgICAgICBsZXQgJGNvbmZpZyA9IG5ldyBDb25maWd1cmF0aW9uKGNvbmZpZy5kb2MgPyBjb25maWcuZG9jLnR5cGUuc2NoZW1hIDogY29uZmlnLnNjaGVtYSwgY29uZmlnLnBsdWdpbnMpO1xuICAgICAgICBsZXQgaW5zdGFuY2UgPSBuZXcgRWRpdG9yU3RhdGUoJGNvbmZpZyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgJGNvbmZpZy5maWVsZHMubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpbnN0YW5jZVskY29uZmlnLmZpZWxkc1tpXS5uYW1lXSA9ICRjb25maWcuZmllbGRzW2ldLmluaXQoY29uZmlnLCBpbnN0YW5jZSk7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbmV3IHN0YXRlIGJhc2VkIG9uIHRoaXMgb25lLCBidXQgd2l0aCBhbiBhZGp1c3RlZCBzZXRcbiAgICBvZiBhY3RpdmUgcGx1Z2lucy4gU3RhdGUgZmllbGRzIHRoYXQgZXhpc3QgaW4gYm90aCBzZXRzIG9mXG4gICAgcGx1Z2lucyBhcmUga2VwdCB1bmNoYW5nZWQuIFRob3NlIHRoYXQgbm8gbG9uZ2VyIGV4aXN0IGFyZVxuICAgIGRyb3BwZWQsIGFuZCB0aG9zZSB0aGF0IGFyZSBuZXcgYXJlIGluaXRpYWxpemVkIHVzaW5nIHRoZWlyXG4gICAgW2Bpbml0YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLlN0YXRlRmllbGQuaW5pdCkgbWV0aG9kLCBwYXNzaW5nIGluIHRoZSBuZXdcbiAgICBjb25maWd1cmF0aW9uIG9iamVjdC4uXG4gICAgKi9cbiAgICByZWNvbmZpZ3VyZShjb25maWcpIHtcbiAgICAgICAgbGV0ICRjb25maWcgPSBuZXcgQ29uZmlndXJhdGlvbih0aGlzLnNjaGVtYSwgY29uZmlnLnBsdWdpbnMpO1xuICAgICAgICBsZXQgZmllbGRzID0gJGNvbmZpZy5maWVsZHMsIGluc3RhbmNlID0gbmV3IEVkaXRvclN0YXRlKCRjb25maWcpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG5hbWUgPSBmaWVsZHNbaV0ubmFtZTtcbiAgICAgICAgICAgIGluc3RhbmNlW25hbWVdID0gdGhpcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSA/IHRoaXNbbmFtZV0gOiBmaWVsZHNbaV0uaW5pdChjb25maWcsIGluc3RhbmNlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgfVxuICAgIC8qKlxuICAgIFNlcmlhbGl6ZSB0aGlzIHN0YXRlIHRvIEpTT04uIElmIHlvdSB3YW50IHRvIHNlcmlhbGl6ZSB0aGUgc3RhdGVcbiAgICBvZiBwbHVnaW5zLCBwYXNzIGFuIG9iamVjdCBtYXBwaW5nIHByb3BlcnR5IG5hbWVzIHRvIHVzZSBpbiB0aGVcbiAgICByZXN1bHRpbmcgSlNPTiBvYmplY3QgdG8gcGx1Z2luIG9iamVjdHMuIFRoZSBhcmd1bWVudCBtYXkgYWxzbyBiZVxuICAgIGEgc3RyaW5nIG9yIG51bWJlciwgaW4gd2hpY2ggY2FzZSBpdCBpcyBpZ25vcmVkLCB0byBzdXBwb3J0IHRoZVxuICAgIHdheSBgSlNPTi5zdHJpbmdpZnlgIGNhbGxzIGB0b1N0cmluZ2AgbWV0aG9kcy5cbiAgICAqL1xuICAgIHRvSlNPTihwbHVnaW5GaWVsZHMpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IHsgZG9jOiB0aGlzLmRvYy50b0pTT04oKSwgc2VsZWN0aW9uOiB0aGlzLnNlbGVjdGlvbi50b0pTT04oKSB9O1xuICAgICAgICBpZiAodGhpcy5zdG9yZWRNYXJrcylcbiAgICAgICAgICAgIHJlc3VsdC5zdG9yZWRNYXJrcyA9IHRoaXMuc3RvcmVkTWFya3MubWFwKG0gPT4gbS50b0pTT04oKSk7XG4gICAgICAgIGlmIChwbHVnaW5GaWVsZHMgJiYgdHlwZW9mIHBsdWdpbkZpZWxkcyA9PSAnb2JqZWN0JylcbiAgICAgICAgICAgIGZvciAobGV0IHByb3AgaW4gcGx1Z2luRmllbGRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHByb3AgPT0gXCJkb2NcIiB8fCBwcm9wID09IFwic2VsZWN0aW9uXCIpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIEpTT04gZmllbGRzIGBkb2NgIGFuZCBgc2VsZWN0aW9uYCBhcmUgcmVzZXJ2ZWRcIik7XG4gICAgICAgICAgICAgICAgbGV0IHBsdWdpbiA9IHBsdWdpbkZpZWxkc1twcm9wXSwgc3RhdGUgPSBwbHVnaW4uc3BlYy5zdGF0ZTtcbiAgICAgICAgICAgICAgICBpZiAoc3RhdGUgJiYgc3RhdGUudG9KU09OKVxuICAgICAgICAgICAgICAgICAgICByZXN1bHRbcHJvcF0gPSBzdGF0ZS50b0pTT04uY2FsbChwbHVnaW4sIHRoaXNbcGx1Z2luLmtleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvKipcbiAgICBEZXNlcmlhbGl6ZSBhIEpTT04gcmVwcmVzZW50YXRpb24gb2YgYSBzdGF0ZS4gYGNvbmZpZ2Agc2hvdWxkXG4gICAgaGF2ZSBhdCBsZWFzdCBhIGBzY2hlbWFgIGZpZWxkLCBhbmQgc2hvdWxkIGNvbnRhaW4gYXJyYXkgb2ZcbiAgICBwbHVnaW5zIHRvIGluaXRpYWxpemUgdGhlIHN0YXRlIHdpdGguIGBwbHVnaW5GaWVsZHNgIGNhbiBiZSB1c2VkXG4gICAgdG8gZGVzZXJpYWxpemUgdGhlIHN0YXRlIG9mIHBsdWdpbnMsIGJ5IGFzc29jaWF0aW5nIHBsdWdpblxuICAgIGluc3RhbmNlcyB3aXRoIHRoZSBwcm9wZXJ0eSBuYW1lcyB0aGV5IHVzZSBpbiB0aGUgSlNPTiBvYmplY3QuXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oY29uZmlnLCBqc29uLCBwbHVnaW5GaWVsZHMpIHtcbiAgICAgICAgaWYgKCFqc29uKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBFZGl0b3JTdGF0ZS5mcm9tSlNPTlwiKTtcbiAgICAgICAgaWYgKCFjb25maWcuc2NoZW1hKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJSZXF1aXJlZCBjb25maWcgZmllbGQgJ3NjaGVtYScgbWlzc2luZ1wiKTtcbiAgICAgICAgbGV0ICRjb25maWcgPSBuZXcgQ29uZmlndXJhdGlvbihjb25maWcuc2NoZW1hLCBjb25maWcucGx1Z2lucyk7XG4gICAgICAgIGxldCBpbnN0YW5jZSA9IG5ldyBFZGl0b3JTdGF0ZSgkY29uZmlnKTtcbiAgICAgICAgJGNvbmZpZy5maWVsZHMuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICAgICAgICBpZiAoZmllbGQubmFtZSA9PSBcImRvY1wiKSB7XG4gICAgICAgICAgICAgICAgaW5zdGFuY2UuZG9jID0gTm9kZS5mcm9tSlNPTihjb25maWcuc2NoZW1hLCBqc29uLmRvYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChmaWVsZC5uYW1lID09IFwic2VsZWN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5zZWxlY3Rpb24gPSBTZWxlY3Rpb24uZnJvbUpTT04oaW5zdGFuY2UuZG9jLCBqc29uLnNlbGVjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChmaWVsZC5uYW1lID09IFwic3RvcmVkTWFya3NcIikge1xuICAgICAgICAgICAgICAgIGlmIChqc29uLnN0b3JlZE1hcmtzKVxuICAgICAgICAgICAgICAgICAgICBpbnN0YW5jZS5zdG9yZWRNYXJrcyA9IGpzb24uc3RvcmVkTWFya3MubWFwKGNvbmZpZy5zY2hlbWEubWFya0Zyb21KU09OKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmIChwbHVnaW5GaWVsZHMpXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHByb3AgaW4gcGx1Z2luRmllbGRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcGx1Z2luID0gcGx1Z2luRmllbGRzW3Byb3BdLCBzdGF0ZSA9IHBsdWdpbi5zcGVjLnN0YXRlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBsdWdpbi5rZXkgPT0gZmllbGQubmFtZSAmJiBzdGF0ZSAmJiBzdGF0ZS5mcm9tSlNPTiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChqc29uLCBwcm9wKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbmNlW2ZpZWxkLm5hbWVdID0gc3RhdGUuZnJvbUpTT04uY2FsbChwbHVnaW4sIGNvbmZpZywganNvbltwcm9wXSwgaW5zdGFuY2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGluc3RhbmNlW2ZpZWxkLm5hbWVdID0gZmllbGQuaW5pdChjb25maWcsIGluc3RhbmNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGJpbmRQcm9wcyhvYmosIHNlbGYsIHRhcmdldCkge1xuICAgIGZvciAobGV0IHByb3AgaW4gb2JqKSB7XG4gICAgICAgIGxldCB2YWwgPSBvYmpbcHJvcF07XG4gICAgICAgIGlmICh2YWwgaW5zdGFuY2VvZiBGdW5jdGlvbilcbiAgICAgICAgICAgIHZhbCA9IHZhbC5iaW5kKHNlbGYpO1xuICAgICAgICBlbHNlIGlmIChwcm9wID09IFwiaGFuZGxlRE9NRXZlbnRzXCIpXG4gICAgICAgICAgICB2YWwgPSBiaW5kUHJvcHModmFsLCBzZWxmLCB7fSk7XG4gICAgICAgIHRhcmdldFtwcm9wXSA9IHZhbDtcbiAgICB9XG4gICAgcmV0dXJuIHRhcmdldDtcbn1cbi8qKlxuUGx1Z2lucyBidW5kbGUgZnVuY3Rpb25hbGl0eSB0aGF0IGNhbiBiZSBhZGRlZCB0byBhbiBlZGl0b3IuXG5UaGV5IGFyZSBwYXJ0IG9mIHRoZSBbZWRpdG9yIHN0YXRlXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuRWRpdG9yU3RhdGUpIGFuZFxubWF5IGluZmx1ZW5jZSB0aGF0IHN0YXRlIGFuZCB0aGUgdmlldyB0aGF0IGNvbnRhaW5zIGl0LlxuKi9cbmNsYXNzIFBsdWdpbiB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgcGx1Z2luLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHBsdWdpbidzIFtzcGVjIG9iamVjdF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLlBsdWdpblNwZWMpLlxuICAgICovXG4gICAgc3BlYykge1xuICAgICAgICB0aGlzLnNwZWMgPSBzcGVjO1xuICAgICAgICAvKipcbiAgICAgICAgVGhlIFtwcm9wc10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuRWRpdG9yUHJvcHMpIGV4cG9ydGVkIGJ5IHRoaXMgcGx1Z2luLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLnByb3BzID0ge307XG4gICAgICAgIGlmIChzcGVjLnByb3BzKVxuICAgICAgICAgICAgYmluZFByb3BzKHNwZWMucHJvcHMsIHRoaXMsIHRoaXMucHJvcHMpO1xuICAgICAgICB0aGlzLmtleSA9IHNwZWMua2V5ID8gc3BlYy5rZXkua2V5IDogY3JlYXRlS2V5KFwicGx1Z2luXCIpO1xuICAgIH1cbiAgICAvKipcbiAgICBFeHRyYWN0IHRoZSBwbHVnaW4ncyBzdGF0ZSBmaWVsZCBmcm9tIGFuIGVkaXRvciBzdGF0ZS5cbiAgICAqL1xuICAgIGdldFN0YXRlKHN0YXRlKSB7IHJldHVybiBzdGF0ZVt0aGlzLmtleV07IH1cbn1cbmNvbnN0IGtleXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuZnVuY3Rpb24gY3JlYXRlS2V5KG5hbWUpIHtcbiAgICBpZiAobmFtZSBpbiBrZXlzKVxuICAgICAgICByZXR1cm4gbmFtZSArIFwiJFwiICsgKytrZXlzW25hbWVdO1xuICAgIGtleXNbbmFtZV0gPSAwO1xuICAgIHJldHVybiBuYW1lICsgXCIkXCI7XG59XG4vKipcbkEga2V5IGlzIHVzZWQgdG8gW3RhZ10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLlBsdWdpblNwZWMua2V5KSBwbHVnaW5zIGluIGEgd2F5XG50aGF0IG1ha2VzIGl0IHBvc3NpYmxlIHRvIGZpbmQgdGhlbSwgZ2l2ZW4gYW4gZWRpdG9yIHN0YXRlLlxuQXNzaWduaW5nIGEga2V5IGRvZXMgbWVhbiBvbmx5IG9uZSBwbHVnaW4gb2YgdGhhdCB0eXBlIGNhbiBiZVxuYWN0aXZlIGluIGEgc3RhdGUuXG4qL1xuY2xhc3MgUGx1Z2luS2V5IHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBwbHVnaW4ga2V5LlxuICAgICovXG4gICAgY29uc3RydWN0b3IobmFtZSA9IFwia2V5XCIpIHsgdGhpcy5rZXkgPSBjcmVhdGVLZXkobmFtZSk7IH1cbiAgICAvKipcbiAgICBHZXQgdGhlIGFjdGl2ZSBwbHVnaW4gd2l0aCB0aGlzIGtleSwgaWYgYW55LCBmcm9tIGFuIGVkaXRvclxuICAgIHN0YXRlLlxuICAgICovXG4gICAgZ2V0KHN0YXRlKSB7IHJldHVybiBzdGF0ZS5jb25maWcucGx1Z2luc0J5S2V5W3RoaXMua2V5XTsgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgcGx1Z2luJ3Mgc3RhdGUgZnJvbSBhbiBlZGl0b3Igc3RhdGUuXG4gICAgKi9cbiAgICBnZXRTdGF0ZShzdGF0ZSkgeyByZXR1cm4gc3RhdGVbdGhpcy5rZXldOyB9XG59XG5cbmV4cG9ydCB7IEFsbFNlbGVjdGlvbiwgRWRpdG9yU3RhdGUsIE5vZGVTZWxlY3Rpb24sIFBsdWdpbiwgUGx1Z2luS2V5LCBTZWxlY3Rpb24sIFNlbGVjdGlvblJhbmdlLCBUZXh0U2VsZWN0aW9uLCBUcmFuc2FjdGlvbiB9O1xuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHR5cGUgeyBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBUZXh0U2VsZWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuLyoqXG4gKiBSZXN0cnVjdHVyZSB0aGUgYmxvY2txdW90ZSBib3VuZGFyeSBhdCB0aGUgY2FyZXQuXG4gKlxuICogVHdvIGNhc2VzIGFyZSBoYW5kbGVkIGluIGEgc2luZ2xlIGJhY2tzcGFjZTpcbiAqXG4gKiAxLiBDYXJldCBhdCB0aGUgc3RhcnQgb2YgYSBub24tZmlyc3QgY2hpbGQgb2YgYSBibG9ja3F1b3RlIOKAlCBsaWZ0IHRoZVxuICogICAgY3VycmVudCBjaGlsZCBvdXQsIHNwbGl0dGluZyB0aGUgYmxvY2txdW90ZSBhcm91bmQgaXQuXG4gKiAyLiBDYXJldCBhdCB0aGUgc3RhcnQgb2YgYSB0b3AtbGV2ZWwgdGV4dGJsb2NrIHdob3NlIHByZXZpb3VzIHNpYmxpbmcgaXNcbiAqICAgIGEgYmxvY2txdW90ZSB3aXRoIGEgdGV4dGJsb2NrIGxhc3QgY2hpbGQg4oCUIG1lcmdlIHRoZSBjdXJyZW50XG4gKiAgICB0ZXh0YmxvY2sncyBpbmxpbmUgY29udGVudCBpbnRvIHRoZSBibG9ja3F1b3RlJ3MgbGFzdCB0ZXh0YmxvY2tcbiAqICAgIGluc3RlYWQgb2YgbGV0dGluZyBqb2luQmFja3dhcmQgcHVsbCB0aGUgcGFyYWdyYXBoIGJhY2sgaW5zaWRlLlxuICpcbiAqIFJldHVybnMgdHJ1ZSB3aGVuIHRoZSBiYWNrc3BhY2Ugd2FzIGNvbnN1bWVkLlxuICovXG5leHBvcnQgY29uc3QgaGFuZGxlQmFja3NwYWNlID0gKGVkaXRvcjogRWRpdG9yLCB0eXBlOiBOb2RlVHlwZSk6IGJvb2xlYW4gPT4ge1xuICBjb25zdCB7IHN0YXRlLCB2aWV3IH0gPSBlZGl0b3JcbiAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IHN0YXRlXG4gIGlmICghc2VsZWN0aW9uLmVtcHR5KSByZXR1cm4gZmFsc2VcblxuICBjb25zdCB7ICRmcm9tIH0gPSBzZWxlY3Rpb25cbiAgaWYgKCRmcm9tLnBhcmVudE9mZnNldCAhPT0gMCkgcmV0dXJuIGZhbHNlXG5cbiAgY29uc3QgcGFyZW50RGVwdGggPSAkZnJvbS5kZXB0aCAtIDFcbiAgY29uc3QgcGFyZW50ID0gJGZyb20ubm9kZShwYXJlbnREZXB0aClcbiAgY29uc3QgaW5kZXggPSAkZnJvbS5pbmRleChwYXJlbnREZXB0aClcbiAgaWYgKGluZGV4ID09PSAwKSByZXR1cm4gZmFsc2VcblxuICAvLyBOb24tZmlyc3QgY2hpbGQgb2YgYSBibG9ja3F1b3RlOiBsaWZ0IHRvIHNwbGl0IHRoZSBibG9ja3F1b3RlIGFyb3VuZCBpdC5cbiAgaWYgKHBhcmVudC50eXBlID09PSB0eXBlKSB7XG4gICAgcmV0dXJuIGVkaXRvci5jb21tYW5kcy5saWZ0KHR5cGUubmFtZSlcbiAgfVxuXG4gIC8vIFByZXZpb3VzIHNpYmxpbmcgaXMgYSBibG9ja3F1b3RlIHdob3NlIGxhc3QgY2hpbGQgaXMgYSB0ZXh0YmxvY2s6XG4gIC8vIG1lcmdlIHRoZSBpbmxpbmUgY29udGVudCBpbiBpbnN0ZWFkIG9mIGxldHRpbmcgam9pbkJhY2t3YXJkIHB1bGwgdGhlXG4gIC8vIHBhcmFncmFwaCBiYWNrIGluc2lkZSB0aGUgYmxvY2txdW90ZS5cbiAgY29uc3QgcHJldmlvdXMgPSBwYXJlbnQuY2hpbGQoaW5kZXggLSAxKVxuICBpZiAocHJldmlvdXMudHlwZSAhPT0gdHlwZSB8fCAhcHJldmlvdXMubGFzdENoaWxkPy5pc1RleHRibG9jaykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgY29uc3QgYmxvY2tTdGFydCA9ICRmcm9tLmJlZm9yZSgpXG4gIC8vIGBibG9ja1N0YXJ0YCBzaXRzIGluIHRoZSBzaGFyZWQgcGFyZW50IGF0IHRoZSBwb3NpdGlvbiByaWdodCBhZnRlclxuICAvLyB0aGUgcHJldmlvdXMgYmxvY2txdW90ZS4gSW4gUHJvc2VNaXJyb3IgY29vcmRpbmF0ZXMsIGVhY2ggY2xvc2luZ1xuICAvLyB0b2tlbiBjb3N0cyBvbmUgcG9zaXRpb246IHN0ZXAgb25lIGJhY2sgdG8gbGFuZCBpbnNpZGUgdGhlIGJsb2NrcXVvdGVcbiAgLy8gcmlnaHQgYWZ0ZXIgaXRzIGxhc3QgY2hpbGQsIHRoZW4gb25lIG1vcmUgdG8gbGFuZCBpbnNpZGUgdGhhdCBsYXN0XG4gIC8vIGNoaWxkIGF0IHRoZSBlbmQgb2YgaXRzIGlubGluZSBjb250ZW50LlxuICBjb25zdCBpbnNpZGVCbG9ja3F1b3RlRW5kID0gYmxvY2tTdGFydCAtIDFcbiAgY29uc3QgdGFyZ2V0UG9zID0gaW5zaWRlQmxvY2txdW90ZUVuZCAtIDFcbiAgY29uc3QgeyB0ciB9ID0gc3RhdGVcbiAgdHIuZGVsZXRlKGJsb2NrU3RhcnQsICRmcm9tLmFmdGVyKCkpLmluc2VydCh0YXJnZXRQb3MsICRmcm9tLnBhcmVudC5jb250ZW50KVxuICB0ci5zZXRTZWxlY3Rpb24oVGV4dFNlbGVjdGlvbi5jcmVhdGUodHIuZG9jLCB0YXJnZXRQb3MpKVxuICB2aWV3LmRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpXG4gIHJldHVybiB0cnVlXG59XG4iLCAiaW1wb3J0IHsgQmxvY2txdW90ZSB9IGZyb20gJy4vYmxvY2txdW90ZS5qc3gnXG5cbmV4cG9ydCAqIGZyb20gJy4vYmxvY2txdW90ZS5qc3gnXG5cbmV4cG9ydCBkZWZhdWx0IEJsb2NrcXVvdGVcbiIsICIvKiogQGpzeEltcG9ydFNvdXJjZSBAdGlwdGFwL2NvcmUgKi9cbmltcG9ydCB7IE1hcmssIG1hcmtJbnB1dFJ1bGUsIG1hcmtQYXN0ZVJ1bGUsIG1lcmdlQXR0cmlidXRlcyB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuZXhwb3J0IGludGVyZmFjZSBCb2xkT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBIVE1MIGF0dHJpYnV0ZXMgdG8gYWRkIHRvIHRoZSBib2xkIGVsZW1lbnQuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBib2xkOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNldCBhIGJvbGQgbWFya1xuICAgICAgICovXG4gICAgICBzZXRCb2xkOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgICAvKipcbiAgICAgICAqIFRvZ2dsZSBhIGJvbGQgbWFya1xuICAgICAgICovXG4gICAgICB0b2dnbGVCb2xkOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgICAvKipcbiAgICAgICAqIFVuc2V0IGEgYm9sZCBtYXJrXG4gICAgICAgKi9cbiAgICAgIHVuc2V0Qm9sZDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE1hdGNoZXMgYm9sZCB0ZXh0IHZpYSBgKipgIGFzIGlucHV0LlxuICovXG5leHBvcnQgY29uc3Qgc3RhcklucHV0UmVnZXggPSAvKD86XnxcXHMpKFxcKlxcKig/IVxccytcXCpcXCopKCg/OlteKl0rKSlcXCpcXCooPyFcXHMrXFwqXFwqKSkkL1xuXG4vKipcbiAqIE1hdGNoZXMgYm9sZCB0ZXh0IHZpYSBgKipgIHdoaWxlIHBhc3RpbmcuXG4gKi9cbmV4cG9ydCBjb25zdCBzdGFyUGFzdGVSZWdleCA9IC8oPzpefFxccykoXFwqXFwqKD8hXFxzK1xcKlxcKikoKD86W14qXSspKVxcKlxcKig/IVxccytcXCpcXCopKS9nXG5cbi8qKlxuICogTWF0Y2hlcyBib2xkIHRleHQgdmlhIGBfX2AgYXMgaW5wdXQuXG4gKi9cbmV4cG9ydCBjb25zdCB1bmRlcnNjb3JlSW5wdXRSZWdleCA9IC8oPzpefFxccykoX18oPyFcXHMrX18pKCg/OlteX10rKSlfXyg/IVxccytfXykpJC9cblxuLyoqXG4gKiBNYXRjaGVzIGJvbGQgdGV4dCB2aWEgYF9fYCB3aGlsZSBwYXN0aW5nLlxuICovXG5leHBvcnQgY29uc3QgdW5kZXJzY29yZVBhc3RlUmVnZXggPSAvKD86XnxcXHMpKF9fKD8hXFxzK19fKSgoPzpbXl9dKykpX18oPyFcXHMrX18pKS9nXG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBtYXJrIHRleHQgYXMgYm9sZC5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2FwaS9tYXJrcy9ib2xkXG4gKi9cbmV4cG9ydCBjb25zdCBCb2xkID0gTWFyay5jcmVhdGU8Qm9sZE9wdGlvbnM+KHtcbiAgbmFtZTogJ2JvbGQnLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIHRhZzogJ3N0cm9uZycsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0YWc6ICdiJyxcbiAgICAgICAgZ2V0QXR0cnM6IG5vZGUgPT4gKG5vZGUgYXMgSFRNTEVsZW1lbnQpLnN0eWxlLmZvbnRXZWlnaHQgIT09ICdub3JtYWwnICYmIG51bGwsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBzdHlsZTogJ2ZvbnQtd2VpZ2h0PTQwMCcsXG4gICAgICAgIGNsZWFyTWFyazogbWFyayA9PiBtYXJrLnR5cGUubmFtZSA9PT0gdGhpcy5uYW1lLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3R5bGU6ICdmb250LXdlaWdodCcsXG4gICAgICAgIGdldEF0dHJzOiB2YWx1ZSA9PiAvXihib2xkKGVyKT98WzUtOV1cXGR7Mix9KSQvLnRlc3QodmFsdWUgYXMgc3RyaW5nKSAmJiBudWxsLFxuICAgICAgfSxcbiAgICBdXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICByZXR1cm4gKFxuICAgICAgPHN0cm9uZyB7Li4ubWVyZ2VBdHRyaWJ1dGVzKHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcywgSFRNTEF0dHJpYnV0ZXMpfT5cbiAgICAgICAgPHNsb3QgLz5cbiAgICAgIDwvc3Ryb25nPlxuICAgIClcbiAgfSxcblxuICBtYXJrZG93blRva2VuTmFtZTogJ3N0cm9uZycsXG5cbiAgcGFyc2VNYXJrZG93bjogKHRva2VuLCBoZWxwZXJzKSA9PiB7XG4gICAgLy8gQ29udmVydCAnc3Ryb25nJyB0b2tlbiB0byBib2xkIG1hcmtcbiAgICByZXR1cm4gaGVscGVycy5hcHBseU1hcmsoJ2JvbGQnLCBoZWxwZXJzLnBhcnNlSW5saW5lKHRva2VuLnRva2VucyB8fCBbXSkpXG4gIH0sXG5cbiAgbWFya2Rvd25PcHRpb25zOiB7XG4gICAgaHRtbFJlb3Blbjoge1xuICAgICAgb3BlbjogJzxzdHJvbmc+JyxcbiAgICAgIGNsb3NlOiAnPC9zdHJvbmc+JyxcbiAgICB9LFxuICB9LFxuXG4gIHJlbmRlck1hcmtkb3duOiAobm9kZSwgaCkgPT4ge1xuICAgIHJldHVybiBgKioke2gucmVuZGVyQ2hpbGRyZW4obm9kZSl9KipgXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldEJvbGQ6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gY29tbWFuZHMuc2V0TWFyayh0aGlzLm5hbWUpXG4gICAgICAgIH0sXG4gICAgICB0b2dnbGVCb2xkOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnRvZ2dsZU1hcmsodGhpcy5uYW1lKVxuICAgICAgICB9LFxuICAgICAgdW5zZXRCb2xkOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnVuc2V0TWFyayh0aGlzLm5hbWUpXG4gICAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnTW9kLWInOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVCb2xkKCksXG4gICAgICAnTW9kLUInOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVCb2xkKCksXG4gICAgfVxuICB9LFxuXG4gIGFkZElucHV0UnVsZXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG1hcmtJbnB1dFJ1bGUoe1xuICAgICAgICBmaW5kOiBzdGFySW5wdXRSZWdleCxcbiAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgfSksXG4gICAgICBtYXJrSW5wdXRSdWxlKHtcbiAgICAgICAgZmluZDogdW5kZXJzY29yZUlucHV0UmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcblxuICBhZGRQYXN0ZVJ1bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICBtYXJrUGFzdGVSdWxlKHtcbiAgICAgICAgZmluZDogc3RhclBhc3RlUmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgICAgbWFya1Bhc3RlUnVsZSh7XG4gICAgICAgIGZpbmQ6IHVuZGVyc2NvcmVQYXN0ZVJlZ2V4LFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IEJvbGQgfSBmcm9tICcuL2JvbGQuanN4J1xuXG5leHBvcnQgKiBmcm9tICcuL2JvbGQuanN4J1xuXG5leHBvcnQgZGVmYXVsdCBCb2xkXG4iLCAiaW1wb3J0IHR5cGUgeyBJbnB1dFJ1bGVNYXRjaCwgUGFzdGVSdWxlTWF0Y2ggfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5pbXBvcnQgeyBNYXJrLCBtYXJrSW5wdXRSdWxlLCBtYXJrUGFzdGVSdWxlLCBtZXJnZUF0dHJpYnV0ZXMgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29kZU9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIEhUTUwgYXR0cmlidXRlcyBhcHBsaWVkIHRvIHRoZSBjb2RlIGVsZW1lbnQuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBjb2RlOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNldCBhIGNvZGUgbWFya1xuICAgICAgICovXG4gICAgICBzZXRDb2RlOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgICAvKipcbiAgICAgICAqIFRvZ2dsZSBpbmxpbmUgY29kZVxuICAgICAgICovXG4gICAgICB0b2dnbGVDb2RlOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgICAvKipcbiAgICAgICAqIFVuc2V0IGEgY29kZSBtYXJrXG4gICAgICAgKi9cbiAgICAgIHVuc2V0Q29kZTogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gdXNlZCBmb3IgdGhlIGlubGluZSBjb2RlIGlucHV0IHJ1bGUuXG4gKiBAZGVwcmVjYXRlZCBUaGUgZXh0ZW5zaW9uIG5vdyB1c2VzIGEgZnVuY3Rpb24tYmFzZWQgZmluZGVyIGludGVybmFsbHkuXG4gKiBUaGlzIHJlZ2V4IGlzIGtlcHQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuXG4gKi9cbmV4cG9ydCBjb25zdCBpbnB1dFJlZ2V4ID0gLyhefFteYF0pYChbXmBdKylgKD8hYCkkL1xuXG4vKipcbiAqIFRoZSByZWd1bGFyIGV4cHJlc3Npb24gdXNlZCBmb3IgdGhlIGlubGluZSBjb2RlIHBhc3RlIHJ1bGUuXG4gKiBAZGVwcmVjYXRlZCBUaGUgZXh0ZW5zaW9uIG5vdyB1c2VzIGEgZnVuY3Rpb24tYmFzZWQgZmluZGVyIGludGVybmFsbHkuXG4gKiBUaGlzIHJlZ2V4IGlzIGtlcHQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuXG4gKi9cbmV4cG9ydCBjb25zdCBwYXN0ZVJlZ2V4ID0gLyhefFteYF0pYChbXmBdKylgKD8hYCkvZ1xuXG4vKipcbiAqIEEgZnVuY3Rpb24tYmFzZWQgZmluZGVyIGZvciB0aGUgaW5saW5lIGNvZGUgaW5wdXQgcnVsZS5cbiAqIFVzZWQgaW50ZXJuYWxseSBieSB0aGUgZXh0ZW5zaW9uIHRvIGVuc3VyZSB0aGUgcHJlY2VkaW5nIGNoYXJhY3RlclxuICogaXMgbm90IGNvbnN1bWVkIGFzIHBhcnQgb2YgdGhlIG1hdGNoLCBwcmV2ZW50aW5nIGl0IGZyb20gYmVpbmcgZGVsZXRlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IGlucHV0UmVnZXhNYXRjaCA9ICh0ZXh0OiBzdHJpbmcpOiBJbnB1dFJ1bGVNYXRjaCB8IG51bGwgPT4ge1xuICBjb25zdCBtYXRjaCA9IC9gKFteYF0rKWAoPyFgKSQvLmV4ZWModGV4dClcblxuICBpZiAoIW1hdGNoKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8vIEVuc3VyZSB0aGUgb3BlbmluZyBiYWNrdGljayBpc24ndCBwcmVjZWRlZCBieSBhbm90aGVyIGJhY2t0aWNrXG4gIGlmIChtYXRjaC5pbmRleCA+IDAgJiYgdGV4dFttYXRjaC5pbmRleCAtIDFdID09PSAnYCcpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBpbmRleDogbWF0Y2guaW5kZXgsXG4gICAgdGV4dDogbWF0Y2hbMF0sXG4gICAgcmVwbGFjZVdpdGg6IG1hdGNoWzFdLFxuICB9XG59XG5cbi8qKlxuICogQSBmdW5jdGlvbi1iYXNlZCBmaW5kZXIgZm9yIHRoZSBpbmxpbmUgY29kZSBwYXN0ZSBydWxlLlxuICogVXNlZCBpbnRlcm5hbGx5IGJ5IHRoZSBleHRlbnNpb24gdG8gYXZvaWQgY29uc3VtaW5nIHRoZSBwcmVjZWRpbmdcbiAqIGNoYXJhY3RlciBhcyBwYXJ0IG9mIHRoZSBtYXRjaC5cbiAqL1xuZXhwb3J0IGNvbnN0IHBhc3RlUmVnZXhNYXRjaCA9ICh0ZXh0OiBzdHJpbmcpOiBQYXN0ZVJ1bGVNYXRjaFtdID0+IHtcbiAgY29uc3QgcmVnZXggPSAvYChbXmBdKylgKD8hYCkvZ1xuICBjb25zdCBtYXRjaGVzOiBQYXN0ZVJ1bGVNYXRjaFtdID0gW11cbiAgbGV0IG1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsXG5cbiAgd2hpbGUgKChtYXRjaCA9IHJlZ2V4LmV4ZWModGV4dCkpICE9PSBudWxsKSB7XG4gICAgLy8gRW5zdXJlIHRoZSBvcGVuaW5nIGJhY2t0aWNrIGlzbid0IHByZWNlZGVkIGJ5IGFub3RoZXIgYmFja3RpY2tcbiAgICBpZiAobWF0Y2guaW5kZXggPiAwICYmIHRleHRbbWF0Y2guaW5kZXggLSAxXSA9PT0gJ2AnKSB7XG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIG1hdGNoZXMucHVzaCh7XG4gICAgICBpbmRleDogbWF0Y2guaW5kZXgsXG4gICAgICB0ZXh0OiBtYXRjaFswXSxcbiAgICAgIHJlcGxhY2VXaXRoOiBtYXRjaFsxXSxcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIG1hdGNoZXNcbn1cblxuLyoqXG4gKiBUaGlzIGV4dGVuc2lvbiBhbGxvd3MgeW91IHRvIG1hcmsgdGV4dCBhcyBpbmxpbmUgY29kZS5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2FwaS9tYXJrcy9jb2RlXG4gKi9cbmV4cG9ydCBjb25zdCBDb2RlID0gTWFyay5jcmVhdGU8Q29kZU9wdGlvbnM+KHtcbiAgbmFtZTogJ2NvZGUnLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgZXhjbHVkZXM6ICdfJyxcblxuICBjb2RlOiB0cnVlLFxuXG4gIGV4aXRhYmxlOiB0cnVlLFxuXG4gIHBhcnNlSFRNTCgpIHtcbiAgICByZXR1cm4gW3sgdGFnOiAnY29kZScgfV1cbiAgfSxcblxuICByZW5kZXJIVE1MKHsgSFRNTEF0dHJpYnV0ZXMgfSkge1xuICAgIHJldHVybiBbJ2NvZGUnLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyksIDBdXG4gIH0sXG5cbiAgbWFya2Rvd25Ub2tlbk5hbWU6ICdjb2Rlc3BhbicsXG5cbiAgcGFyc2VNYXJrZG93bjogKHRva2VuLCBoZWxwZXJzKSA9PiB7XG4gICAgLy8gQ29udmVydCAnY29kZXNwYW4nIHRva2VuIHRvIGNvZGUgbWFya1xuICAgIC8vIEZvciBjb2Rlc3BhbiB0b2tlbnMsIHdlIHVzZSB0aGUgcmF3IHRleHQgY29udGVudCwgbm90IHRva2Vuc1xuICAgIHJldHVybiBoZWxwZXJzLmFwcGx5TWFyaygnY29kZScsIFt7IHR5cGU6ICd0ZXh0JywgdGV4dDogdG9rZW4udGV4dCB8fCAnJyB9XSlcbiAgfSxcblxuICByZW5kZXJNYXJrZG93bjogKG5vZGUsIGgpID0+IHtcbiAgICBpZiAoIW5vZGUuY29udGVudCkge1xuICAgICAgcmV0dXJuICcnXG4gICAgfVxuXG4gICAgcmV0dXJuIGBcXGAke2gucmVuZGVyQ2hpbGRyZW4obm9kZS5jb250ZW50KX1cXGBgXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldENvZGU6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gY29tbWFuZHMuc2V0TWFyayh0aGlzLm5hbWUpXG4gICAgICAgIH0sXG4gICAgICB0b2dnbGVDb2RlOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnRvZ2dsZU1hcmsodGhpcy5uYW1lKVxuICAgICAgICB9LFxuICAgICAgdW5zZXRDb2RlOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnVuc2V0TWFyayh0aGlzLm5hbWUpXG4gICAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnTW9kLWUnOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVDb2RlKCksXG4gICAgfVxuICB9LFxuXG4gIGFkZElucHV0UnVsZXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG1hcmtJbnB1dFJ1bGUoe1xuICAgICAgICBmaW5kOiBpbnB1dFJlZ2V4TWF0Y2gsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcblxuICBhZGRQYXN0ZVJ1bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICBtYXJrUGFzdGVSdWxlKHtcbiAgICAgICAgZmluZDogcGFzdGVSZWdleE1hdGNoLFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IENvZGUgfSBmcm9tICcuL2NvZGUuanMnXG5cbmV4cG9ydCAqIGZyb20gJy4vY29kZS5qcydcblxuZXhwb3J0IGRlZmF1bHQgQ29kZVxuIiwgImltcG9ydCB7IG1lcmdlQXR0cmlidXRlcywgTm9kZSwgdGV4dGJsb2NrVHlwZUlucHV0UnVsZSB9IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB7IFBsdWdpbiwgUGx1Z2luS2V5LCBTZWxlY3Rpb24sIFRleHRTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5jb25zdCBERUZBVUxUX1RBQl9TSVpFID0gNFxuXG5leHBvcnQgaW50ZXJmYWNlIENvZGVCbG9ja09wdGlvbnMge1xuICAvKipcbiAgICogQWRkcyBhIHByZWZpeCB0byBsYW5ndWFnZSBjbGFzc2VzIHRoYXQgYXJlIGFwcGxpZWQgdG8gY29kZSB0YWdzLlxuICAgKiBAZGVmYXVsdCAnbGFuZ3VhZ2UtJ1xuICAgKi9cbiAgbGFuZ3VhZ2VDbGFzc1ByZWZpeDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZFxuICAvKipcbiAgICogRGVmaW5lIHdoZXRoZXIgdGhlIG5vZGUgc2hvdWxkIGJlIGV4aXRlZCBvbiB0cmlwbGUgZW50ZXIuXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIGV4aXRPblRyaXBsZUVudGVyOiBib29sZWFuIHwgbnVsbCB8IHVuZGVmaW5lZFxuICAvKipcbiAgICogRGVmaW5lIHdoZXRoZXIgdGhlIG5vZGUgc2hvdWxkIGJlIGV4aXRlZCBvbiBhcnJvdyBkb3duIGlmIHRoZXJlIGlzIG5vIG5vZGUgYWZ0ZXIgaXQuXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIGV4aXRPbkFycm93RG93bjogYm9vbGVhbiB8IG51bGwgfCB1bmRlZmluZWRcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGxhbmd1YWdlLlxuICAgKiBAZGVmYXVsdCBudWxsXG4gICAqIEBleGFtcGxlICdqcydcbiAgICovXG4gIGRlZmF1bHRMYW5ndWFnZTogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZFxuICAvKipcbiAgICogRW5hYmxlIHRhYiBrZXkgZm9yIGluZGVudGF0aW9uIGluIGNvZGUgYmxvY2tzLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgZW5hYmxlVGFiSW5kZW50YXRpb246IGJvb2xlYW4gfCBudWxsIHwgdW5kZWZpbmVkXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIHNwYWNlcyB0byB1c2UgZm9yIHRhYiBpbmRlbnRhdGlvbi5cbiAgICogQGRlZmF1bHQgNFxuICAgKi9cbiAgdGFiU2l6ZTogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZFxuICAvKipcbiAgICogQ3VzdG9tIEhUTUwgYXR0cmlidXRlcyB0aGF0IHNob3VsZCBiZSBhZGRlZCB0byB0aGUgcmVuZGVyZWQgSFRNTCB0YWcuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBjb2RlQmxvY2s6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2V0IGEgY29kZSBibG9ja1xuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgQ29kZSBibG9jayBhdHRyaWJ1dGVzXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2V0Q29kZUJsb2NrKHsgbGFuZ3VhZ2U6ICdqYXZhc2NyaXB0JyB9KVxuICAgICAgICovXG4gICAgICBzZXRDb2RlQmxvY2s6IChhdHRyaWJ1dGVzPzogeyBsYW5ndWFnZTogc3RyaW5nIH0pID0+IFJldHVyblR5cGVcbiAgICAgIC8qKlxuICAgICAgICogVG9nZ2xlIGEgY29kZSBibG9ja1xuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgQ29kZSBibG9jayBhdHRyaWJ1dGVzXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudG9nZ2xlQ29kZUJsb2NrKHsgbGFuZ3VhZ2U6ICdqYXZhc2NyaXB0JyB9KVxuICAgICAgICovXG4gICAgICB0b2dnbGVDb2RlQmxvY2s6IChhdHRyaWJ1dGVzPzogeyBsYW5ndWFnZTogc3RyaW5nIH0pID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNYXRjaGVzIGEgY29kZSBibG9jayB3aXRoIGJhY2t0aWNrcy5cbiAqL1xuZXhwb3J0IGNvbnN0IGJhY2t0aWNrSW5wdXRSZWdleCA9IC9eYGBgKFthLXpdKyk/W1xcc1xcbl0kL1xuXG4vKipcbiAqIE1hdGNoZXMgYSBjb2RlIGJsb2NrIHdpdGggdGlsZGVzLlxuICovXG5leHBvcnQgY29uc3QgdGlsZGVJbnB1dFJlZ2V4ID0gL15+fn4oW2Etel0rKT9bXFxzXFxuXSQvXG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBjcmVhdGUgY29kZSBibG9ja3MuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9hcGkvbm9kZXMvY29kZS1ibG9ja1xuICovXG5leHBvcnQgY29uc3QgQ29kZUJsb2NrID0gTm9kZS5jcmVhdGU8Q29kZUJsb2NrT3B0aW9ucz4oe1xuICBuYW1lOiAnY29kZUJsb2NrJyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBsYW5ndWFnZUNsYXNzUHJlZml4OiAnbGFuZ3VhZ2UtJyxcbiAgICAgIGV4aXRPblRyaXBsZUVudGVyOiB0cnVlLFxuICAgICAgZXhpdE9uQXJyb3dEb3duOiB0cnVlLFxuICAgICAgZGVmYXVsdExhbmd1YWdlOiBudWxsLFxuICAgICAgZW5hYmxlVGFiSW5kZW50YXRpb246IGZhbHNlLFxuICAgICAgdGFiU2l6ZTogREVGQVVMVF9UQUJfU0laRSxcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgY29udGVudDogJ3RleHQqJyxcblxuICBtYXJrczogJycsXG5cbiAgZ3JvdXA6ICdibG9jaycsXG5cbiAgY29kZTogdHJ1ZSxcblxuICBkZWZpbmluZzogdHJ1ZSxcblxuICBhZGRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBsYW5ndWFnZToge1xuICAgICAgICBkZWZhdWx0OiB0aGlzLm9wdGlvbnMuZGVmYXVsdExhbmd1YWdlLFxuICAgICAgICBwYXJzZUhUTUw6IGVsZW1lbnQgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgbGFuZ3VhZ2VDbGFzc1ByZWZpeCB9ID0gdGhpcy5vcHRpb25zXG5cbiAgICAgICAgICBpZiAoIWxhbmd1YWdlQ2xhc3NQcmVmaXgpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgY2xhc3NOYW1lcyA9IFsuLi4oZWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZD8uY2xhc3NMaXN0IHx8IFtdKV1cbiAgICAgICAgICBjb25zdCBsYW5ndWFnZXMgPSBjbGFzc05hbWVzXG4gICAgICAgICAgICAuZmlsdGVyKGNsYXNzTmFtZSA9PiBjbGFzc05hbWUuc3RhcnRzV2l0aChsYW5ndWFnZUNsYXNzUHJlZml4KSlcbiAgICAgICAgICAgIC5tYXAoY2xhc3NOYW1lID0+IGNsYXNzTmFtZS5yZXBsYWNlKGxhbmd1YWdlQ2xhc3NQcmVmaXgsICcnKSlcbiAgICAgICAgICBjb25zdCBsYW5ndWFnZSA9IGxhbmd1YWdlc1swXVxuXG4gICAgICAgICAgaWYgKCFsYW5ndWFnZSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gbGFuZ3VhZ2VcbiAgICAgICAgfSxcbiAgICAgICAgcmVuZGVyZWQ6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIHRhZzogJ3ByZScsXG4gICAgICAgIHByZXNlcnZlV2hpdGVzcGFjZTogJ2Z1bGwnLFxuICAgICAgfSxcbiAgICBdXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IG5vZGUsIEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICByZXR1cm4gW1xuICAgICAgJ3ByZScsXG4gICAgICBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyksXG4gICAgICBbXG4gICAgICAgICdjb2RlJyxcbiAgICAgICAge1xuICAgICAgICAgIGNsYXNzOiBub2RlLmF0dHJzLmxhbmd1YWdlXG4gICAgICAgICAgICA/IHRoaXMub3B0aW9ucy5sYW5ndWFnZUNsYXNzUHJlZml4ICsgbm9kZS5hdHRycy5sYW5ndWFnZVxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICB9LFxuICAgICAgICAwLFxuICAgICAgXSxcbiAgICBdXG4gIH0sXG5cbiAgbWFya2Rvd25Ub2tlbk5hbWU6ICdjb2RlJyxcblxuICBwYXJzZU1hcmtkb3duOiAodG9rZW4sIGhlbHBlcnMpID0+IHtcbiAgICBpZiAoXG4gICAgICB0b2tlbi5yYXc/LnN0YXJ0c1dpdGgoJ2BgYCcpID09PSBmYWxzZSAmJlxuICAgICAgdG9rZW4ucmF3Py5zdGFydHNXaXRoKCd+fn4nKSA9PT0gZmFsc2UgJiZcbiAgICAgIHRva2VuLmNvZGVCbG9ja1N0eWxlICE9PSAnaW5kZW50ZWQnXG4gICAgKSB7XG4gICAgICByZXR1cm4gW11cbiAgICB9XG5cbiAgICByZXR1cm4gaGVscGVycy5jcmVhdGVOb2RlKFxuICAgICAgJ2NvZGVCbG9jaycsXG4gICAgICB7IGxhbmd1YWdlOiB0b2tlbi5sYW5nIHx8IG51bGwgfSxcbiAgICAgIHRva2VuLnRleHQgPyBbaGVscGVycy5jcmVhdGVUZXh0Tm9kZSh0b2tlbi50ZXh0KV0gOiBbXSxcbiAgICApXG4gIH0sXG5cbiAgcmVuZGVyTWFya2Rvd246IChub2RlLCBoKSA9PiB7XG4gICAgbGV0IG91dHB1dCA9ICcnXG4gICAgY29uc3QgbGFuZ3VhZ2UgPSBub2RlLmF0dHJzPy5sYW5ndWFnZSB8fCAnJ1xuXG4gICAgaWYgKCFub2RlLmNvbnRlbnQpIHtcbiAgICAgIG91dHB1dCA9IGBcXGBcXGBcXGAke2xhbmd1YWdlfVxcblxcblxcYFxcYFxcYGBcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbGluZXMgPSBbYFxcYFxcYFxcYCR7bGFuZ3VhZ2V9YCwgaC5yZW5kZXJDaGlsZHJlbihub2RlLmNvbnRlbnQpLCAnYGBgJ11cbiAgICAgIG91dHB1dCA9IGxpbmVzLmpvaW4oJ1xcbicpXG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dFxuICB9LFxuXG4gIGFkZENvbW1hbmRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzZXRDb2RlQmxvY2s6XG4gICAgICAgIGF0dHJpYnV0ZXMgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy5zZXROb2RlKHRoaXMubmFtZSwgYXR0cmlidXRlcylcbiAgICAgICAgfSxcbiAgICAgIHRvZ2dsZUNvZGVCbG9jazpcbiAgICAgICAgYXR0cmlidXRlcyA9PlxuICAgICAgICAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnRvZ2dsZU5vZGUodGhpcy5uYW1lLCAncGFyYWdyYXBoJywgYXR0cmlidXRlcylcbiAgICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkS2V5Ym9hcmRTaG9ydGN1dHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdNb2QtQWx0LWMnOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVDb2RlQmxvY2soKSxcblxuICAgICAgLy8gcmVtb3ZlIGNvZGUgYmxvY2sgd2hlbiBhdCBzdGFydCBvZiBkb2N1bWVudCBvciBjb2RlIGJsb2NrIGlzIGVtcHR5XG4gICAgICBCYWNrc3BhY2U6ICgpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbXB0eSwgJGFuY2hvciB9ID0gdGhpcy5lZGl0b3Iuc3RhdGUuc2VsZWN0aW9uXG4gICAgICAgIGNvbnN0IGlzQXRTdGFydCA9ICRhbmNob3IucG9zID09PSAxXG5cbiAgICAgICAgaWYgKCFlbXB0eSB8fCAkYW5jaG9yLnBhcmVudC50eXBlLm5hbWUgIT09IHRoaXMubmFtZSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzQXRTdGFydCB8fCAhJGFuY2hvci5wYXJlbnQudGV4dENvbnRlbnQubGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZWRpdG9yLmNvbW1hbmRzLmNsZWFyTm9kZXMoKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9LFxuXG4gICAgICAvLyBoYW5kbGUgdGFiIGluZGVudGF0aW9uXG4gICAgICBUYWI6ICh7IGVkaXRvciB9KSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5vcHRpb25zLmVuYWJsZVRhYkluZGVudGF0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB0YWJTaXplID0gdGhpcy5vcHRpb25zLnRhYlNpemUgPz8gREVGQVVMVF9UQUJfU0laRVxuICAgICAgICBjb25zdCB7IHN0YXRlIH0gPSBlZGl0b3JcbiAgICAgICAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IHN0YXRlXG4gICAgICAgIGNvbnN0IHsgJGZyb20sIGVtcHR5IH0gPSBzZWxlY3Rpb25cblxuICAgICAgICBpZiAoJGZyb20ucGFyZW50LnR5cGUgIT09IHRoaXMudHlwZSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5kZW50ID0gJyAnLnJlcGVhdCh0YWJTaXplKVxuXG4gICAgICAgIGlmIChlbXB0eSkge1xuICAgICAgICAgIHJldHVybiBlZGl0b3IuY29tbWFuZHMuaW5zZXJ0Q29udGVudChpbmRlbnQpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZWRpdG9yLmNvbW1hbmRzLmNvbW1hbmQoKHsgdHIgfSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZnJvbSwgdG8gfSA9IHNlbGVjdGlvblxuICAgICAgICAgIGNvbnN0IHRleHQgPSBzdGF0ZS5kb2MudGV4dEJldHdlZW4oZnJvbSwgdG8sICdcXG4nLCAnXFxuJylcbiAgICAgICAgICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoJ1xcbicpXG4gICAgICAgICAgY29uc3QgaW5kZW50ZWRUZXh0ID0gbGluZXMubWFwKGxpbmUgPT4gaW5kZW50ICsgbGluZSkuam9pbignXFxuJylcblxuICAgICAgICAgIHRyLnJlcGxhY2VXaXRoKGZyb20sIHRvLCBzdGF0ZS5zY2hlbWEudGV4dChpbmRlbnRlZFRleHQpKVxuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0pXG4gICAgICB9LFxuXG4gICAgICAvLyBoYW5kbGUgc2hpZnQrdGFiIHJldmVyc2UgaW5kZW50YXRpb25cbiAgICAgICdTaGlmdC1UYWInOiAoeyBlZGl0b3IgfSkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5lbmFibGVUYWJJbmRlbnRhdGlvbikge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGFiU2l6ZSA9IHRoaXMub3B0aW9ucy50YWJTaXplID8/IERFRkFVTFRfVEFCX1NJWkVcbiAgICAgICAgY29uc3QgeyBzdGF0ZSB9ID0gZWRpdG9yXG4gICAgICAgIGNvbnN0IHsgc2VsZWN0aW9uIH0gPSBzdGF0ZVxuICAgICAgICBjb25zdCB7ICRmcm9tLCBlbXB0eSB9ID0gc2VsZWN0aW9uXG5cbiAgICAgICAgaWYgKCRmcm9tLnBhcmVudC50eXBlICE9PSB0aGlzLnR5cGUpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbXB0eSkge1xuICAgICAgICAgIHJldHVybiBlZGl0b3IuY29tbWFuZHMuY29tbWFuZCgoeyB0ciB9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IHBvcyB9ID0gJGZyb21cbiAgICAgICAgICAgIGNvbnN0IGNvZGVCbG9ja1N0YXJ0ID0gJGZyb20uc3RhcnQoKVxuICAgICAgICAgICAgY29uc3QgY29kZUJsb2NrRW5kID0gJGZyb20uZW5kKClcblxuICAgICAgICAgICAgY29uc3QgYWxsVGV4dCA9IHN0YXRlLmRvYy50ZXh0QmV0d2Vlbihjb2RlQmxvY2tTdGFydCwgY29kZUJsb2NrRW5kLCAnXFxuJywgJ1xcbicpXG4gICAgICAgICAgICBjb25zdCBsaW5lcyA9IGFsbFRleHQuc3BsaXQoJ1xcbicpXG5cbiAgICAgICAgICAgIGxldCBjdXJyZW50TGluZUluZGV4ID0gMFxuICAgICAgICAgICAgbGV0IGNoYXJDb3VudCA9IDBcbiAgICAgICAgICAgIGNvbnN0IHJlbGF0aXZlQ3Vyc29yUG9zID0gcG9zIC0gY29kZUJsb2NrU3RhcnRcblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgICBpZiAoY2hhckNvdW50ICsgbGluZXNbaV0ubGVuZ3RoID49IHJlbGF0aXZlQ3Vyc29yUG9zKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudExpbmVJbmRleCA9IGlcbiAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGNoYXJDb3VudCArPSBsaW5lc1tpXS5sZW5ndGggKyAxXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRMaW5lID0gbGluZXNbY3VycmVudExpbmVJbmRleF1cbiAgICAgICAgICAgIGNvbnN0IGxlYWRpbmdTcGFjZXMgPSBjdXJyZW50TGluZS5tYXRjaCgvXiAqLyk/LlswXSB8fCAnJ1xuICAgICAgICAgICAgY29uc3Qgc3BhY2VzVG9SZW1vdmUgPSBNYXRoLm1pbihsZWFkaW5nU3BhY2VzLmxlbmd0aCwgdGFiU2l6ZSlcblxuICAgICAgICAgICAgaWYgKHNwYWNlc1RvUmVtb3ZlID09PSAwKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBsaW5lU3RhcnRQb3MgPSBjb2RlQmxvY2tTdGFydFxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjdXJyZW50TGluZUluZGV4OyBpICs9IDEpIHtcbiAgICAgICAgICAgICAgbGluZVN0YXJ0UG9zICs9IGxpbmVzW2ldLmxlbmd0aCArIDFcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHIuZGVsZXRlKGxpbmVTdGFydFBvcywgbGluZVN0YXJ0UG9zICsgc3BhY2VzVG9SZW1vdmUpXG5cbiAgICAgICAgICAgIGNvbnN0IGN1cnNvclBvc0luTGluZSA9IHBvcyAtIGxpbmVTdGFydFBvc1xuICAgICAgICAgICAgaWYgKGN1cnNvclBvc0luTGluZSA8PSBzcGFjZXNUb1JlbW92ZSkge1xuICAgICAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24oVGV4dFNlbGVjdGlvbi5jcmVhdGUodHIuZG9jLCBsaW5lU3RhcnRQb3MpKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZWRpdG9yLmNvbW1hbmRzLmNvbW1hbmQoKHsgdHIgfSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZnJvbSwgdG8gfSA9IHNlbGVjdGlvblxuICAgICAgICAgIGNvbnN0IHRleHQgPSBzdGF0ZS5kb2MudGV4dEJldHdlZW4oZnJvbSwgdG8sICdcXG4nLCAnXFxuJylcbiAgICAgICAgICBjb25zdCBsaW5lcyA9IHRleHQuc3BsaXQoJ1xcbicpXG4gICAgICAgICAgY29uc3QgcmV2ZXJzZUluZGVudFRleHQgPSBsaW5lc1xuICAgICAgICAgICAgLm1hcChsaW5lID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbGVhZGluZ1NwYWNlcyA9IGxpbmUubWF0Y2goL14gKi8pPy5bMF0gfHwgJydcbiAgICAgICAgICAgICAgY29uc3Qgc3BhY2VzVG9SZW1vdmUgPSBNYXRoLm1pbihsZWFkaW5nU3BhY2VzLmxlbmd0aCwgdGFiU2l6ZSlcbiAgICAgICAgICAgICAgcmV0dXJuIGxpbmUuc2xpY2Uoc3BhY2VzVG9SZW1vdmUpXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmpvaW4oJ1xcbicpXG5cbiAgICAgICAgICB0ci5yZXBsYWNlV2l0aChmcm9tLCB0bywgc3RhdGUuc2NoZW1hLnRleHQocmV2ZXJzZUluZGVudFRleHQpKVxuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0pXG4gICAgICB9LFxuXG4gICAgICAvLyBleGl0IG5vZGUgb24gdHJpcGxlIGVudGVyXG4gICAgICBFbnRlcjogKHsgZWRpdG9yIH0pID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuZXhpdE9uVHJpcGxlRW50ZXIpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgc3RhdGUgfSA9IGVkaXRvclxuICAgICAgICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gc3RhdGVcbiAgICAgICAgY29uc3QgeyAkZnJvbSwgZW1wdHkgfSA9IHNlbGVjdGlvblxuXG4gICAgICAgIGlmICghZW1wdHkgfHwgJGZyb20ucGFyZW50LnR5cGUgIT09IHRoaXMudHlwZSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXNBdEVuZCA9ICRmcm9tLnBhcmVudE9mZnNldCA9PT0gJGZyb20ucGFyZW50Lm5vZGVTaXplIC0gMlxuICAgICAgICBjb25zdCBlbmRzV2l0aERvdWJsZU5ld2xpbmUgPSAkZnJvbS5wYXJlbnQudGV4dENvbnRlbnQuZW5kc1dpdGgoJ1xcblxcbicpXG5cbiAgICAgICAgaWYgKCFpc0F0RW5kIHx8ICFlbmRzV2l0aERvdWJsZU5ld2xpbmUpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlZGl0b3JcbiAgICAgICAgICAuY2hhaW4oKVxuICAgICAgICAgIC5jb21tYW5kKCh7IHRyIH0pID0+IHtcbiAgICAgICAgICAgIHRyLmRlbGV0ZSgkZnJvbS5wb3MgLSAyLCAkZnJvbS5wb3MpXG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuZXhpdENvZGUoKVxuICAgICAgICAgIC5ydW4oKVxuICAgICAgfSxcblxuICAgICAgLy8gZXhpdCBub2RlIG9uIGFycm93IGRvd25cbiAgICAgIEFycm93RG93bjogKHsgZWRpdG9yIH0pID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuZXhpdE9uQXJyb3dEb3duKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IHN0YXRlIH0gPSBlZGl0b3JcbiAgICAgICAgY29uc3QgeyBzZWxlY3Rpb24sIGRvYyB9ID0gc3RhdGVcbiAgICAgICAgY29uc3QgeyAkZnJvbSwgZW1wdHkgfSA9IHNlbGVjdGlvblxuXG4gICAgICAgIGlmICghZW1wdHkgfHwgJGZyb20ucGFyZW50LnR5cGUgIT09IHRoaXMudHlwZSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXNBdEVuZCA9ICRmcm9tLnBhcmVudE9mZnNldCA9PT0gJGZyb20ucGFyZW50Lm5vZGVTaXplIC0gMlxuXG4gICAgICAgIGlmICghaXNBdEVuZCkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYWZ0ZXIgPSAkZnJvbS5hZnRlcigpXG5cbiAgICAgICAgaWYgKGFmdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG5vZGVBZnRlciA9IGRvYy5ub2RlQXQoYWZ0ZXIpXG5cbiAgICAgICAgaWYgKG5vZGVBZnRlcikge1xuICAgICAgICAgIHJldHVybiBlZGl0b3IuY29tbWFuZHMuY29tbWFuZCgoeyB0ciB9KSA9PiB7XG4gICAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24oU2VsZWN0aW9uLm5lYXIoZG9jLnJlc29sdmUoYWZ0ZXIpKSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlZGl0b3IuY29tbWFuZHMuZXhpdENvZGUoKVxuICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkSW5wdXRSdWxlcygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgdGV4dGJsb2NrVHlwZUlucHV0UnVsZSh7XG4gICAgICAgIGZpbmQ6IGJhY2t0aWNrSW5wdXRSZWdleCxcbiAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgICBnZXRBdHRyaWJ1dGVzOiBtYXRjaCA9PiAoe1xuICAgICAgICAgIGxhbmd1YWdlOiBtYXRjaFsxXSxcbiAgICAgICAgfSksXG4gICAgICB9KSxcbiAgICAgIHRleHRibG9ja1R5cGVJbnB1dFJ1bGUoe1xuICAgICAgICBmaW5kOiB0aWxkZUlucHV0UmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgICAgZ2V0QXR0cmlidXRlczogbWF0Y2ggPT4gKHtcbiAgICAgICAgICBsYW5ndWFnZTogbWF0Y2hbMV0sXG4gICAgICAgIH0pLFxuICAgICAgfSksXG4gICAgXVxuICB9LFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgLy8gdGhpcyBwbHVnaW4gY3JlYXRlcyBhIGNvZGUgYmxvY2sgZm9yIHBhc3RlZCBjb250ZW50IGZyb20gVlMgQ29kZVxuICAgICAgLy8gd2UgY2FuIGFsc28gZGV0ZWN0IHRoZSBjb3BpZWQgY29kZSBsYW5ndWFnZVxuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleSgnY29kZUJsb2NrVlNDb2RlSGFuZGxlcicpLFxuICAgICAgICBwcm9wczoge1xuICAgICAgICAgIGhhbmRsZVBhc3RlOiAodmlldywgZXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICghZXZlbnQuY2xpcGJvYXJkRGF0YSkge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gZG9u4oCZdCBjcmVhdGUgYSBuZXcgY29kZSBibG9jayB3aXRoaW4gY29kZSBibG9ja3NcbiAgICAgICAgICAgIGlmICh0aGlzLmVkaXRvci5pc0FjdGl2ZSh0aGlzLnR5cGUubmFtZSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHRleHQgPSBldmVudC5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQvcGxhaW4nKVxuICAgICAgICAgICAgY29uc3QgdnNjb2RlID0gZXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd2c2NvZGUtZWRpdG9yLWRhdGEnKVxuICAgICAgICAgICAgY29uc3QgdnNjb2RlRGF0YSA9IHZzY29kZSA/IEpTT04ucGFyc2UodnNjb2RlKSA6IHVuZGVmaW5lZFxuICAgICAgICAgICAgY29uc3QgbGFuZ3VhZ2UgPSB2c2NvZGVEYXRhPy5tb2RlXG5cbiAgICAgICAgICAgIGlmICghdGV4dCB8fCAhbGFuZ3VhZ2UpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHsgdHIsIHNjaGVtYSB9ID0gdmlldy5zdGF0ZVxuXG4gICAgICAgICAgICAvLyBwcmVwYXJlIGEgdGV4dCBub2RlXG4gICAgICAgICAgICAvLyBzdHJpcCBjYXJyaWFnZSByZXR1cm4gY2hhcnMgZnJvbSB0ZXh0IHBhc3RlZCBhcyBjb2RlXG4gICAgICAgICAgICAvLyBzZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9Qcm9zZU1pcnJvci9wcm9zZW1pcnJvci12aWV3L2NvbW1pdC9hNTBhNmJjY2ViNGNlNTJhYzhmY2M2MTYyNDg4ZDg4NzU2MTNhYWNkXG4gICAgICAgICAgICBjb25zdCB0ZXh0Tm9kZSA9IHNjaGVtYS50ZXh0KHRleHQucmVwbGFjZSgvXFxyXFxuPy9nLCAnXFxuJykpXG5cbiAgICAgICAgICAgIC8vIGNyZWF0ZSBhIGNvZGUgYmxvY2sgd2l0aCB0aGUgdGV4dCBub2RlXG4gICAgICAgICAgICAvLyByZXBsYWNlIHNlbGVjdGlvbiB3aXRoIHRoZSBjb2RlIGJsb2NrXG4gICAgICAgICAgICB0ci5yZXBsYWNlU2VsZWN0aW9uV2l0aCh0aGlzLnR5cGUuY3JlYXRlKHsgbGFuZ3VhZ2UgfSwgdGV4dE5vZGUpKVxuXG4gICAgICAgICAgICBpZiAodHIuc2VsZWN0aW9uLiRmcm9tLnBhcmVudC50eXBlICE9PSB0aGlzLnR5cGUpIHtcbiAgICAgICAgICAgICAgLy8gcHV0IGN1cnNvciBpbnNpZGUgdGhlIG5ld2x5IGNyZWF0ZWQgY29kZSBibG9ja1xuICAgICAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24oXG4gICAgICAgICAgICAgICAgVGV4dFNlbGVjdGlvbi5uZWFyKHRyLmRvYy5yZXNvbHZlKE1hdGgubWF4KDAsIHRyLnNlbGVjdGlvbi5mcm9tIC0gMikpKSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBzdG9yZSBtZXRhIGluZm9ybWF0aW9uXG4gICAgICAgICAgICAvLyB0aGlzIGlzIHVzZWZ1bCBmb3Igb3RoZXIgcGx1Z2lucyB0aGF0IGRlcGVuZHMgb24gdGhlIHBhc3RlIGV2ZW50XG4gICAgICAgICAgICAvLyBsaWtlIHRoZSBwYXN0ZSBydWxlIHBsdWdpblxuICAgICAgICAgICAgdHIuc2V0TWV0YSgncGFzdGUnLCB0cnVlKVxuXG4gICAgICAgICAgICB2aWV3LmRpc3BhdGNoKHRyKVxuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IENvZGVCbG9jayB9IGZyb20gJy4vY29kZS1ibG9jay5qcydcblxuZXhwb3J0ICogZnJvbSAnLi9jb2RlLWJsb2NrLmpzJ1xuXG5leHBvcnQgZGVmYXVsdCBDb2RlQmxvY2tcbiIsICJpbXBvcnQgeyBOb2RlIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG4vKipcbiAqIFRoZSBkZWZhdWx0IGRvY3VtZW50IG5vZGUgd2hpY2ggcmVwcmVzZW50cyB0aGUgdG9wIGxldmVsIG5vZGUgb2YgdGhlIGVkaXRvci5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2FwaS9ub2Rlcy9kb2N1bWVudFxuICovXG5leHBvcnQgY29uc3QgRG9jdW1lbnQgPSBOb2RlLmNyZWF0ZSh7XG4gIG5hbWU6ICdkb2MnLFxuICB0b3BOb2RlOiB0cnVlLFxuICBjb250ZW50OiAnYmxvY2srJyxcblxuICByZW5kZXJNYXJrZG93bjogKG5vZGUsIGgpID0+IHtcbiAgICBpZiAoIW5vZGUuY29udGVudCkge1xuICAgICAgcmV0dXJuICcnXG4gICAgfVxuXG4gICAgcmV0dXJuIGgucmVuZGVyQ2hpbGRyZW4obm9kZS5jb250ZW50LCAnXFxuXFxuJylcbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgRG9jdW1lbnQgfSBmcm9tICcuL2RvY3VtZW50LmpzJ1xuXG5leHBvcnQgKiBmcm9tICcuL2RvY3VtZW50LmpzJ1xuXG5leHBvcnQgZGVmYXVsdCBEb2N1bWVudFxuIiwgImltcG9ydCB7IG1lcmdlQXR0cmlidXRlcywgTm9kZSB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuZXhwb3J0IGludGVyZmFjZSBIYXJkQnJlYWtPcHRpb25zIHtcbiAgLyoqXG4gICAqIENvbnRyb2xzIGlmIG1hcmtzIHNob3VsZCBiZSBrZXB0IGFmdGVyIGJlaW5nIHNwbGl0IGJ5IGEgaGFyZCBicmVhay5cbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKiBAZXhhbXBsZSBmYWxzZVxuICAgKi9cbiAga2VlcE1hcmtzOiBib29sZWFuXG5cbiAgLyoqXG4gICAqIEhUTUwgYXR0cmlidXRlcyB0byBhZGQgdG8gdGhlIGhhcmQgYnJlYWsgZWxlbWVudC5cbiAgICogQGRlZmF1bHQge31cbiAgICogQGV4YW1wbGUgeyBjbGFzczogJ2ZvbycgfVxuICAgKi9cbiAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT5cbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGhhcmRCcmVhazoge1xuICAgICAgLyoqXG4gICAgICAgKiBBZGQgYSBoYXJkIGJyZWFrXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2V0SGFyZEJyZWFrKClcbiAgICAgICAqL1xuICAgICAgc2V0SGFyZEJyZWFrOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBpbnNlcnQgaGFyZCBicmVha3MuXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnRpcHRhcC5kZXYvYXBpL25vZGVzL2hhcmQtYnJlYWtcbiAqL1xuZXhwb3J0IGNvbnN0IEhhcmRCcmVhayA9IE5vZGUuY3JlYXRlPEhhcmRCcmVha09wdGlvbnM+KHtcbiAgbmFtZTogJ2hhcmRCcmVhaycsXG5cbiAgbWFya2Rvd25Ub2tlbk5hbWU6ICdicicsXG5cbiAgYWRkT3B0aW9ucygpIHtcbiAgICByZXR1cm4ge1xuICAgICAga2VlcE1hcmtzOiB0cnVlLFxuICAgICAgSFRNTEF0dHJpYnV0ZXM6IHt9LFxuICAgIH1cbiAgfSxcblxuICBpbmxpbmU6IHRydWUsXG5cbiAgZ3JvdXA6ICdpbmxpbmUnLFxuXG4gIHNlbGVjdGFibGU6IGZhbHNlLFxuXG4gIGxpbmVicmVha1JlcGxhY2VtZW50OiB0cnVlLFxuXG4gIHBhcnNlSFRNTCgpIHtcbiAgICByZXR1cm4gW3sgdGFnOiAnYnInIH1dXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICByZXR1cm4gWydicicsIG1lcmdlQXR0cmlidXRlcyh0aGlzLm9wdGlvbnMuSFRNTEF0dHJpYnV0ZXMsIEhUTUxBdHRyaWJ1dGVzKV1cbiAgfSxcblxuICByZW5kZXJUZXh0KCkge1xuICAgIHJldHVybiAnXFxuJ1xuICB9LFxuXG4gIHJlbmRlck1hcmtkb3duOiAoKSA9PiBgICBcXG5gLFxuXG4gIHBhcnNlTWFya2Rvd246ICgpID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ2hhcmRCcmVhaycsXG4gICAgfVxuICB9LFxuXG4gIGFkZENvbW1hbmRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzZXRIYXJkQnJlYWs6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IGNvbW1hbmRzLCBjaGFpbiwgc3RhdGUsIGVkaXRvciB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLmZpcnN0KFtcbiAgICAgICAgICAgICgpID0+IGNvbW1hbmRzLmV4aXRDb2RlKCksXG4gICAgICAgICAgICAoKSA9PlxuICAgICAgICAgICAgICBjb21tYW5kcy5jb21tYW5kKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHNlbGVjdGlvbiwgc3RvcmVkTWFya3MgfSA9IHN0YXRlXG5cbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uLiRmcm9tLnBhcmVudC50eXBlLnNwZWMuaXNvbGF0aW5nKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCB7IGtlZXBNYXJrcyB9ID0gdGhpcy5vcHRpb25zXG4gICAgICAgICAgICAgICAgY29uc3QgeyBzcGxpdHRhYmxlTWFya3MgfSA9IGVkaXRvci5leHRlbnNpb25NYW5hZ2VyXG4gICAgICAgICAgICAgICAgY29uc3QgbWFya3MgPSBzdG9yZWRNYXJrcyB8fCAoc2VsZWN0aW9uLiR0by5wYXJlbnRPZmZzZXQgJiYgc2VsZWN0aW9uLiRmcm9tLm1hcmtzKCkpXG5cbiAgICAgICAgICAgICAgICByZXR1cm4gY2hhaW4oKVxuICAgICAgICAgICAgICAgICAgLmluc2VydENvbnRlbnQoeyB0eXBlOiB0aGlzLm5hbWUgfSlcbiAgICAgICAgICAgICAgICAgIC5jb21tYW5kKCh7IHRyLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkaXNwYXRjaCAmJiBtYXJrcyAmJiBrZWVwTWFya3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZE1hcmtzID0gbWFya3MuZmlsdGVyKG1hcmsgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNwbGl0dGFibGVNYXJrcy5pbmNsdWRlcyhtYXJrLnR5cGUubmFtZSksXG4gICAgICAgICAgICAgICAgICAgICAgKVxuXG4gICAgICAgICAgICAgICAgICAgICAgdHIuZW5zdXJlTWFya3MoZmlsdGVyZWRNYXJrcylcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgLnJ1bigpXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgIF0pXG4gICAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnTW9kLUVudGVyJzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMuc2V0SGFyZEJyZWFrKCksXG4gICAgICAnU2hpZnQtRW50ZXInOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5zZXRIYXJkQnJlYWsoKSxcbiAgICB9XG4gIH0sXG59KVxuIiwgImltcG9ydCB7IEhhcmRCcmVhayB9IGZyb20gJy4vaGFyZC1icmVhay5qcydcblxuZXhwb3J0ICogZnJvbSAnLi9oYXJkLWJyZWFrLmpzJ1xuXG5leHBvcnQgZGVmYXVsdCBIYXJkQnJlYWtcbiIsICJpbXBvcnQgeyBtZXJnZUF0dHJpYnV0ZXMsIE5vZGUsIHRleHRibG9ja1R5cGVJbnB1dFJ1bGUgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5cbi8qKlxuICogVGhlIGhlYWRpbmcgbGV2ZWwgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IHR5cGUgTGV2ZWwgPSAxIHwgMiB8IDMgfCA0IHwgNSB8IDZcblxuZXhwb3J0IGludGVyZmFjZSBIZWFkaW5nT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgYXZhaWxhYmxlIGhlYWRpbmcgbGV2ZWxzLlxuICAgKiBAZGVmYXVsdCBbMSwgMiwgMywgNCwgNSwgNl1cbiAgICogQGV4YW1wbGUgWzEsIDIsIDNdXG4gICAqL1xuICBsZXZlbHM6IExldmVsW11cblxuICAvKipcbiAgICogVGhlIEhUTUwgYXR0cmlidXRlcyBmb3IgYSBoZWFkaW5nIG5vZGUuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBoZWFkaW5nOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNldCBhIGhlYWRpbmcgbm9kZVxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGhlYWRpbmcgYXR0cmlidXRlc1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldEhlYWRpbmcoeyBsZXZlbDogMSB9KVxuICAgICAgICovXG4gICAgICBzZXRIZWFkaW5nOiAoYXR0cmlidXRlczogeyBsZXZlbDogTGV2ZWwgfSkgPT4gUmV0dXJuVHlwZVxuICAgICAgLyoqXG4gICAgICAgKiBUb2dnbGUgYSBoZWFkaW5nIG5vZGVcbiAgICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBoZWFkaW5nIGF0dHJpYnV0ZXNcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVIZWFkaW5nKHsgbGV2ZWw6IDEgfSlcbiAgICAgICAqL1xuICAgICAgdG9nZ2xlSGVhZGluZzogKGF0dHJpYnV0ZXM6IHsgbGV2ZWw6IExldmVsIH0pID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBUaGlzIGV4dGVuc2lvbiBhbGxvd3MgeW91IHRvIGNyZWF0ZSBoZWFkaW5ncy5cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvbm9kZXMvaGVhZGluZ1xuICovXG5leHBvcnQgY29uc3QgSGVhZGluZyA9IE5vZGUuY3JlYXRlPEhlYWRpbmdPcHRpb25zPih7XG4gIG5hbWU6ICdoZWFkaW5nJyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBsZXZlbHM6IFsxLCAyLCAzLCA0LCA1LCA2XSxcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgY29udGVudDogJ2lubGluZSonLFxuXG4gIGdyb3VwOiAnYmxvY2snLFxuXG4gIGRlZmluaW5nOiB0cnVlLFxuXG4gIGFkZEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxldmVsOiB7XG4gICAgICAgIGRlZmF1bHQ6IDEsXG4gICAgICAgIHJlbmRlcmVkOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIHBhcnNlSFRNTCgpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmxldmVscy5tYXAoKGxldmVsOiBMZXZlbCkgPT4gKHtcbiAgICAgIHRhZzogYGgke2xldmVsfWAsXG4gICAgICBhdHRyczogeyBsZXZlbCB9LFxuICAgIH0pKVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBub2RlLCBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgY29uc3QgaGFzTGV2ZWwgPSB0aGlzLm9wdGlvbnMubGV2ZWxzLmluY2x1ZGVzKG5vZGUuYXR0cnMubGV2ZWwpXG4gICAgY29uc3QgbGV2ZWwgPSBoYXNMZXZlbCA/IG5vZGUuYXR0cnMubGV2ZWwgOiB0aGlzLm9wdGlvbnMubGV2ZWxzWzBdXG5cbiAgICByZXR1cm4gW2BoJHtsZXZlbH1gLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyksIDBdXG4gIH0sXG5cbiAgcGFyc2VNYXJrZG93bjogKHRva2VuLCBoZWxwZXJzKSA9PiB7XG4gICAgLy8gQ29udmVydCAnaGVhZGluZycgdG9rZW4gdG8gaGVhZGluZyBub2RlXG4gICAgLy8gbWFya2VkIHByb3ZpZGVzICdkZXB0aCcgcHJvcGVydHkgKDEtNikgZm9yIGhlYWRpbmcgbGV2ZWxcbiAgICByZXR1cm4gaGVscGVycy5jcmVhdGVOb2RlKFxuICAgICAgJ2hlYWRpbmcnLFxuICAgICAgeyBsZXZlbDogdG9rZW4uZGVwdGggfHwgMSB9LFxuICAgICAgaGVscGVycy5wYXJzZUlubGluZSh0b2tlbi50b2tlbnMgfHwgW10pLFxuICAgIClcbiAgfSxcblxuICByZW5kZXJNYXJrZG93bjogKG5vZGUsIGgpID0+IHtcbiAgICBjb25zdCBsZXZlbCA9IG5vZGUuYXR0cnM/LmxldmVsID8gcGFyc2VJbnQobm9kZS5hdHRycy5sZXZlbCBhcyBzdHJpbmcsIDEwKSA6IDFcbiAgICBjb25zdCBoZWFkaW5nQ2hhcnMgPSAnIycucmVwZWF0KGxldmVsKVxuXG4gICAgaWYgKCFub2RlLmNvbnRlbnQpIHtcbiAgICAgIHJldHVybiAnJ1xuICAgIH1cblxuICAgIC8vIFVzZSBjdXJyZW50IGNvbnRleHQgZm9yIHByb3BlciBqb2luaW5nL3NwYWNpbmdcbiAgICByZXR1cm4gYCR7aGVhZGluZ0NoYXJzfSAke2gucmVuZGVyQ2hpbGRyZW4obm9kZS5jb250ZW50KX1gXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldEhlYWRpbmc6XG4gICAgICAgIGF0dHJpYnV0ZXMgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5vcHRpb25zLmxldmVscy5pbmNsdWRlcyhhdHRyaWJ1dGVzLmxldmVsKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnNldE5vZGUodGhpcy5uYW1lLCBhdHRyaWJ1dGVzKVxuICAgICAgICB9LFxuICAgICAgdG9nZ2xlSGVhZGluZzpcbiAgICAgICAgYXR0cmlidXRlcyA9PlxuICAgICAgICAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgICAgaWYgKCF0aGlzLm9wdGlvbnMubGV2ZWxzLmluY2x1ZGVzKGF0dHJpYnV0ZXMubGV2ZWwpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gY29tbWFuZHMudG9nZ2xlTm9kZSh0aGlzLm5hbWUsICdwYXJhZ3JhcGgnLCBhdHRyaWJ1dGVzKVxuICAgICAgICB9LFxuICAgIH1cbiAgfSxcblxuICBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmxldmVscy5yZWR1Y2UoXG4gICAgICAoaXRlbXMsIGxldmVsKSA9PiAoe1xuICAgICAgICAuLi5pdGVtcyxcbiAgICAgICAgW2BNb2QtQWx0LSR7bGV2ZWx9YF06ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZUhlYWRpbmcoeyBsZXZlbCB9KSxcbiAgICAgIH0pLFxuICAgICAge30sXG4gICAgKVxuICB9LFxuXG4gIGFkZElucHV0UnVsZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5sZXZlbHMubWFwKGxldmVsID0+IHtcbiAgICAgIHJldHVybiB0ZXh0YmxvY2tUeXBlSW5wdXRSdWxlKHtcbiAgICAgICAgZmluZDogbmV3IFJlZ0V4cChgXigjeyR7TWF0aC5taW4oLi4udGhpcy5vcHRpb25zLmxldmVscyl9LCR7bGV2ZWx9fSlcXFxccyRgKSxcbiAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgICBnZXRBdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgbGV2ZWwsXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH0pXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IEhlYWRpbmcgfSBmcm9tICcuL2hlYWRpbmcuanMnXG5cbmV4cG9ydCAqIGZyb20gJy4vaGVhZGluZy5qcydcblxuZXhwb3J0IGRlZmF1bHQgSGVhZGluZ1xuIiwgImltcG9ydCB7IGNhbkluc2VydE5vZGUsIGlzTm9kZVNlbGVjdGlvbiwgbWVyZ2VBdHRyaWJ1dGVzLCBOb2RlLCBub2RlSW5wdXRSdWxlIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHsgTm9kZVNlbGVjdGlvbiwgVGV4dFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmV4cG9ydCBpbnRlcmZhY2UgSG9yaXpvbnRhbFJ1bGVPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBIVE1MIGF0dHJpYnV0ZXMgZm9yIGEgaG9yaXpvbnRhbCBydWxlIG5vZGUuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCB0eXBlIHRvIGluc2VydCBhZnRlciB0aGUgaG9yaXpvbnRhbCBydWxlLlxuICAgKiBAZGVmYXVsdCBcInBhcmFncmFwaFwiXG4gICAqIEBleGFtcGxlIFwiaGVhZGluZ1wiXG4gICAqL1xuICBuZXh0Tm9kZVR5cGU6IHN0cmluZ1xufVxuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgaG9yaXpvbnRhbFJ1bGU6IHtcbiAgICAgIC8qKlxuICAgICAgICogQWRkIGEgaG9yaXpvbnRhbCBydWxlXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2V0SG9yaXpvbnRhbFJ1bGUoKVxuICAgICAgICovXG4gICAgICBzZXRIb3Jpem9udGFsUnVsZTogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gaW5zZXJ0IGhvcml6b250YWwgcnVsZXMuXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnRpcHRhcC5kZXYvYXBpL25vZGVzL2hvcml6b250YWwtcnVsZVxuICovXG5leHBvcnQgY29uc3QgSG9yaXpvbnRhbFJ1bGUgPSBOb2RlLmNyZWF0ZTxIb3Jpem9udGFsUnVsZU9wdGlvbnM+KHtcbiAgbmFtZTogJ2hvcml6b250YWxSdWxlJyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBIVE1MQXR0cmlidXRlczoge30sXG4gICAgICBuZXh0Tm9kZVR5cGU6ICdwYXJhZ3JhcGgnLFxuICAgIH1cbiAgfSxcblxuICBncm91cDogJ2Jsb2NrJyxcblxuICBwYXJzZUhUTUwoKSB7XG4gICAgcmV0dXJuIFt7IHRhZzogJ2hyJyB9XVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgcmV0dXJuIFsnaHInLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyldXG4gIH0sXG5cbiAgbWFya2Rvd25Ub2tlbk5hbWU6ICdocicsXG5cbiAgcGFyc2VNYXJrZG93bjogKHRva2VuLCBoZWxwZXJzKSA9PiB7XG4gICAgcmV0dXJuIGhlbHBlcnMuY3JlYXRlTm9kZSgnaG9yaXpvbnRhbFJ1bGUnKVxuICB9LFxuXG4gIHJlbmRlck1hcmtkb3duOiAoKSA9PiB7XG4gICAgcmV0dXJuICctLS0nXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldEhvcml6b250YWxSdWxlOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBjaGFpbiwgc3RhdGUgfSkgPT4ge1xuICAgICAgICAgIC8vIENoZWNrIGlmIHdlIGNhbiBpbnNlcnQgdGhlIG5vZGUgYXQgdGhlIGN1cnJlbnQgc2VsZWN0aW9uXG4gICAgICAgICAgaWYgKCFjYW5JbnNlcnROb2RlKHN0YXRlLCBzdGF0ZS5zY2hlbWEubm9kZXNbdGhpcy5uYW1lXSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHsgc2VsZWN0aW9uIH0gPSBzdGF0ZVxuICAgICAgICAgIGNvbnN0IHsgJHRvOiAkb3JpZ2luVG8gfSA9IHNlbGVjdGlvblxuXG4gICAgICAgICAgY29uc3QgY3VycmVudENoYWluID0gY2hhaW4oKVxuXG4gICAgICAgICAgaWYgKGlzTm9kZVNlbGVjdGlvbihzZWxlY3Rpb24pKSB7XG4gICAgICAgICAgICBjdXJyZW50Q2hhaW4uaW5zZXJ0Q29udGVudEF0KCRvcmlnaW5Uby5wb3MsIHtcbiAgICAgICAgICAgICAgdHlwZTogdGhpcy5uYW1lLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3VycmVudENoYWluLmluc2VydENvbnRlbnQoeyB0eXBlOiB0aGlzLm5hbWUgfSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgY3VycmVudENoYWluXG4gICAgICAgICAgICAgIC8vIHNldCBjdXJzb3IgYWZ0ZXIgaG9yaXpvbnRhbCBydWxlXG4gICAgICAgICAgICAgIC5jb21tYW5kKCh7IHN0YXRlOiBjaGFpblN0YXRlLCB0ciwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgICAgICAgICAgY29uc3QgeyAkdG8gfSA9IHRyLnNlbGVjdGlvblxuICAgICAgICAgICAgICAgICAgY29uc3QgcG9zQWZ0ZXIgPSAkdG8uZW5kKClcblxuICAgICAgICAgICAgICAgICAgaWYgKCR0by5ub2RlQWZ0ZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCR0by5ub2RlQWZ0ZXIuaXNUZXh0YmxvY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24oVGV4dFNlbGVjdGlvbi5jcmVhdGUodHIuZG9jLCAkdG8ucG9zICsgMSkpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoJHRvLm5vZGVBZnRlci5pc0Jsb2NrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgdHIuc2V0U2VsZWN0aW9uKE5vZGVTZWxlY3Rpb24uY3JlYXRlKHRyLmRvYywgJHRvLnBvcykpXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgdHIuc2V0U2VsZWN0aW9uKFRleHRTZWxlY3Rpb24uY3JlYXRlKHRyLmRvYywgJHRvLnBvcykpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFkZCBub2RlIGFmdGVyIGhvcml6b250YWwgcnVsZSBpZiBpdOKAmXMgdGhlIGVuZCBvZiB0aGUgZG9jdW1lbnRcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZVR5cGUgPVxuICAgICAgICAgICAgICAgICAgICAgIGNoYWluU3RhdGUuc2NoZW1hLm5vZGVzW3RoaXMub3B0aW9ucy5uZXh0Tm9kZVR5cGVdIHx8XG4gICAgICAgICAgICAgICAgICAgICAgJHRvLnBhcmVudC50eXBlLmNvbnRlbnRNYXRjaC5kZWZhdWx0VHlwZVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBub2RlID0gbm9kZVR5cGU/LmNyZWF0ZSgpXG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICB0ci5pbnNlcnQocG9zQWZ0ZXIsIG5vZGUpXG4gICAgICAgICAgICAgICAgICAgICAgdHIuc2V0U2VsZWN0aW9uKFRleHRTZWxlY3Rpb24uY3JlYXRlKHRyLmRvYywgcG9zQWZ0ZXIgKyAxKSlcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICB0ci5zY3JvbGxJbnRvVmlldygpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLnJ1bigpXG4gICAgICAgICAgKVxuICAgICAgICB9LFxuICAgIH1cbiAgfSxcblxuICBhZGRJbnB1dFJ1bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICBub2RlSW5wdXRSdWxlKHtcbiAgICAgICAgZmluZDogL14oPzotLS184oCULXxfX19cXHN8XFwqXFwqXFwqXFxzKSQvLFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IEhvcml6b250YWxSdWxlIH0gZnJvbSAnLi9ob3Jpem9udGFsLXJ1bGUuanMnXG5cbmV4cG9ydCAqIGZyb20gJy4vaG9yaXpvbnRhbC1ydWxlLmpzJ1xuXG5leHBvcnQgZGVmYXVsdCBIb3Jpem9udGFsUnVsZVxuIiwgImltcG9ydCB7IE1hcmssIG1hcmtJbnB1dFJ1bGUsIG1hcmtQYXN0ZVJ1bGUsIG1lcmdlQXR0cmlidXRlcyB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuZXhwb3J0IGludGVyZmFjZSBJdGFsaWNPcHRpb25zIHtcbiAgLyoqXG4gICAqIEhUTUwgYXR0cmlidXRlcyB0byBhZGQgdG8gdGhlIGl0YWxpYyBlbGVtZW50LlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAZXhhbXBsZSB7IGNsYXNzOiAnZm9vJyB9XG4gICAqL1xuICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PlxufVxuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgaXRhbGljOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNldCBhbiBpdGFsaWMgbWFya1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldEl0YWxpYygpXG4gICAgICAgKi9cbiAgICAgIHNldEl0YWxpYzogKCkgPT4gUmV0dXJuVHlwZVxuICAgICAgLyoqXG4gICAgICAgKiBUb2dnbGUgYW4gaXRhbGljIG1hcmtcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVJdGFsaWMoKVxuICAgICAgICovXG4gICAgICB0b2dnbGVJdGFsaWM6ICgpID0+IFJldHVyblR5cGVcbiAgICAgIC8qKlxuICAgICAgICogVW5zZXQgYW4gaXRhbGljIG1hcmtcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy51bnNldEl0YWxpYygpXG4gICAgICAgKi9cbiAgICAgIHVuc2V0SXRhbGljOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogTWF0Y2hlcyBhbiBpdGFsaWMgdG8gYSAqaXRhbGljKiBvbiBpbnB1dC5cbiAqL1xuZXhwb3J0IGNvbnN0IHN0YXJJbnB1dFJlZ2V4ID0gLyg/Ol58XFxzKShcXCooPyFcXHMrXFwqKSgoPzpbXipdKykpXFwqKD8hXFxzK1xcKikpJC9cblxuLyoqXG4gKiBNYXRjaGVzIGFuIGl0YWxpYyB0byBhICppdGFsaWMqIG9uIHBhc3RlLlxuICovXG5leHBvcnQgY29uc3Qgc3RhclBhc3RlUmVnZXggPSAvKD86XnxcXHMpKFxcKig/IVxccytcXCopKCg/OlteKl0rKSlcXCooPyFcXHMrXFwqKSkvZ1xuXG4vKipcbiAqIE1hdGNoZXMgYW4gaXRhbGljIHRvIGEgX2l0YWxpY18gb24gaW5wdXQuXG4gKi9cbmV4cG9ydCBjb25zdCB1bmRlcnNjb3JlSW5wdXRSZWdleCA9IC8oPzpefFxccykoXyg/IVxccytfKSgoPzpbXl9dKykpXyg/IVxccytfKSkkL1xuXG4vKipcbiAqIE1hdGNoZXMgYW4gaXRhbGljIHRvIGEgX2l0YWxpY18gb24gcGFzdGUuXG4gKi9cbmV4cG9ydCBjb25zdCB1bmRlcnNjb3JlUGFzdGVSZWdleCA9IC8oPzpefFxccykoXyg/IVxccytfKSgoPzpbXl9dKykpXyg/IVxccytfKSkvZ1xuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gY3JlYXRlIGl0YWxpYyB0ZXh0LlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9tYXJrcy9pdGFsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IEl0YWxpYyA9IE1hcmsuY3JlYXRlPEl0YWxpY09wdGlvbnM+KHtcbiAgbmFtZTogJ2l0YWxpYycsXG5cbiAgYWRkT3B0aW9ucygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgSFRNTEF0dHJpYnV0ZXM6IHt9LFxuICAgIH1cbiAgfSxcblxuICBwYXJzZUhUTUwoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgdGFnOiAnZW0nLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdGFnOiAnaScsXG4gICAgICAgIGdldEF0dHJzOiBub2RlID0+IChub2RlIGFzIEhUTUxFbGVtZW50KS5zdHlsZS5mb250U3R5bGUgIT09ICdub3JtYWwnICYmIG51bGwsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBzdHlsZTogJ2ZvbnQtc3R5bGU9bm9ybWFsJyxcbiAgICAgICAgY2xlYXJNYXJrOiBtYXJrID0+IG1hcmsudHlwZS5uYW1lID09PSB0aGlzLm5hbWUsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBzdHlsZTogJ2ZvbnQtc3R5bGU9aXRhbGljJyxcbiAgICAgIH0sXG4gICAgXVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgcmV0dXJuIFsnZW0nLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyksIDBdXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldEl0YWxpYzpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy5zZXRNYXJrKHRoaXMubmFtZSlcbiAgICAgICAgfSxcbiAgICAgIHRvZ2dsZUl0YWxpYzpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy50b2dnbGVNYXJrKHRoaXMubmFtZSlcbiAgICAgICAgfSxcbiAgICAgIHVuc2V0SXRhbGljOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnVuc2V0TWFyayh0aGlzLm5hbWUpXG4gICAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIG1hcmtkb3duVG9rZW5OYW1lOiAnZW0nLFxuXG4gIHBhcnNlTWFya2Rvd246ICh0b2tlbiwgaGVscGVycykgPT4ge1xuICAgIC8vIENvbnZlcnQgJ2VtJyB0b2tlbiB0byBpdGFsaWMgbWFya1xuICAgIHJldHVybiBoZWxwZXJzLmFwcGx5TWFyaygnaXRhbGljJywgaGVscGVycy5wYXJzZUlubGluZSh0b2tlbi50b2tlbnMgfHwgW10pKVxuICB9LFxuXG4gIG1hcmtkb3duT3B0aW9uczoge1xuICAgIGh0bWxSZW9wZW46IHtcbiAgICAgIG9wZW46ICc8ZW0+JyxcbiAgICAgIGNsb3NlOiAnPC9lbT4nLFxuICAgIH0sXG4gIH0sXG5cbiAgcmVuZGVyTWFya2Rvd246IChub2RlLCBoKSA9PiB7XG4gICAgcmV0dXJuIGAqJHtoLnJlbmRlckNoaWxkcmVuKG5vZGUpfSpgXG4gIH0sXG5cbiAgYWRkS2V5Ym9hcmRTaG9ydGN1dHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdNb2QtaSc6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZUl0YWxpYygpLFxuICAgICAgJ01vZC1JJzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMudG9nZ2xlSXRhbGljKCksXG4gICAgfVxuICB9LFxuXG4gIGFkZElucHV0UnVsZXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG1hcmtJbnB1dFJ1bGUoe1xuICAgICAgICBmaW5kOiBzdGFySW5wdXRSZWdleCxcbiAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgfSksXG4gICAgICBtYXJrSW5wdXRSdWxlKHtcbiAgICAgICAgZmluZDogdW5kZXJzY29yZUlucHV0UmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcblxuICBhZGRQYXN0ZVJ1bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICBtYXJrUGFzdGVSdWxlKHtcbiAgICAgICAgZmluZDogc3RhclBhc3RlUmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgICAgbWFya1Bhc3RlUnVsZSh7XG4gICAgICAgIGZpbmQ6IHVuZGVyc2NvcmVQYXN0ZVJlZ2V4LFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IEl0YWxpYyB9IGZyb20gJy4vaXRhbGljLmpzJ1xuXG5leHBvcnQgKiBmcm9tICcuL2l0YWxpYy5qcydcblxuZXhwb3J0IGRlZmF1bHQgSXRhbGljXG4iLCAiLy8gVEhJUyBGSUxFIElTIEFVVE9NQVRJQ0FMTFkgR0VORVJBVEVEIERPIE5PVCBFRElUIERJUkVDVExZXG4vLyBTZWUgdXBkYXRlLXRsZHMuanMgZm9yIGVuY29kaW5nL2RlY29kaW5nIGZvcm1hdFxuLy8gaHR0cHM6Ly9kYXRhLmlhbmEub3JnL1RMRC90bGRzLWFscGhhLWJ5LWRvbWFpbi50eHRcbmNvbnN0IGVuY29kZWRUbGRzID0gJ2FhYTFycDNiYjBvdHQzdmllNGMxbGUyb2dhZG81dWRoYWJpN2MwYWRlbXk1Y2VudHVyZTZvdW50YW50MHM5bzF0b3I0ZDBzMXVsdDRlMGcxcm8ydG5hNGYwbDFyaWNhNWcwYWtoYW41ZW5jeTVpMGcxcmJ1czNmb3JjZTV0ZWw1a2RuM2wwaWJhYmE0cGF5NGxmaW5hbno2c3RhdGU1eTJzYWNlM3RvbTVtMGF6b240ZXJpY2FuZXhwcmVzczdmYW1pbHkxMXgyZmFtM2ljYTNzdGVyZGFtOG5hbHl0aWNzN2Ryb2lkNXF1YW40ejJvMGwycGFydG1lbnRzOHAwbGU0cTB1YXJlbGxlOHIwYWIxbWNvNGNoaTNteTJwYTJ0MGUzczBkYTJpYTJzb2NpYXRlczl0MGhsZXRhNXRvcm5leTd1MGN0aW9uNWRpMGJsZTNvM3Nwb3N0NXRob3IzbzBzNHcwczJ4MGEyejB1cmU1YmEwYnkyaWR1M25hbWV4NGQxazJyMGNlbG9uYTVsYXljYXJkNHM1ZWZvb3Q1Z2FpbnM2c2ViYWxsNWtldGJhbGw4dWhhdXM1eWVybjViMGMxdDF2YTNjZzFuMmQxZTBhdHMydXR5NGVyMnJsaW40c3QwYnV5NXQyZjFnMWgwYXJ0aTVpMGJsZTNkMWtlMm5nMG8zbzF6MmoxbGFjazBmcmlkYXk5b2NrYnVzdGVyOGcxb21iZXJnN3VlM20wczF3Mm4wcHBhcmliYXM5bzBhdHMzZWhyaW5nZXI4ZmEybTFuZDJvMGswaW5nNXNjaDJ0aWsyb240dDF1dGlxdWU2eDJyMGFkZXNjbzZpZGdlc3RvbmU5b2Fkd2F5NWtlcjN0aGVyNXVzc2VsczdzMXQxdWlsZDBlcnM2c2luZXNzNnkxenozdjF3MXkxejBoM2NhMGIxZmUybDBsMXZpbmtsZWluOW0wZXJhM3Aybm9uM3BldG93bjVpdGFsMG9uZThyMGF2YW40ZHMyZTBlcjBzNHMyc2ExZTFoMWlubzR0MGVyaW5nNWhvbGljN2JhMW4xcmUzYzFkMWVudGVyNG8xcm4zZjBhMWQyZzFoMGFuZWwybmVsNHJpdHk0c2UydDJlYXAzaW50YWk1cmlzdG1hczZvbWU0dXJjaDVpMHByaWFuaTZyY2xlNHNjbzN0YWRlbDRpMGMyeTNrMWwwYWltczRlYW5pbmc2aWNrMm5pYzFxdWU2b3RoaW5nNXVkM3ViMG1lZDZtMW4xbzBhY2gzZGVzM2ZmZWU0bGxlZ2U0b2duZTVtMG1iYW5rNHVuaXR5NnBhbnkycmUzdXRlcjVzZWM0bmRvczNzdHJ1Y3Rpb244dWx0aW5nN3RhY3QzcmFjdG9yczlva2luZzRsMXAycnNpY2E1dW50cnk0cG9uMHM0cnNlczZwYTJyMGVkaXQwY2FyZDR1bmlvbjlpY2tldDVvd24zczF1aXNlMHM2dTBpc2luZWxsYTl2MXcxeDF5MG1ydTNvdTN6MmRhZDFuY2UzdGExZTFpbmczc3VuNHkyY2xrM2RzMmUwYWwwZXIyczNncmVlNGxpdmVyeTVsMW9pdHRlNXRhM21vY3JhdDZudGFsMmlzdDVzaTBnbjR2MmhsMmlhbW9uZHM2ZXQyZ2l0YWw1cmVjdDBvcnk3c2NvdW50M3ZlcjVoMnkyajFrMW0xbnAybzBjczF0b3I0ZzFtYWluczV0MXdubG9hZDdyaXZlNHR2MnViYWkzcG9udDRyYmFuNXZhZzJyMnoyZWFydGgzdDJjMG8yZGVrYTN1MGNhdGlvbjhlMWcxbWFpbDNlcmNrNW5lcmd5NGdpbmVlcjBpbmc5dGVycHJpc2VzMTBwc29uNHF1aXBtZW50OHIwaWNzc29uNm5pM3MwcTF0YXRlNXQxdTByb3Zpc2lvbjhzMnZlbnRzNXhjaGFuZ2U2cGVydDNvc2VkNHJlc3M1dHJhc3BhY2UxMGZhZ2UyaWwxcndpbmRzNnRoM21pbHk0bjBzMnJtMGVyczVzaGlvbjR0M2VkZXgzZWRiYWNrNnJyYXJpM2VybzZpMGRlbGl0eTVvMmxtMm5hbDFuY2UxaWFsN3JlMHN0b25lNm1kYWxlNnNoMGluZzV0MG5lc3M2ajFrMWxpY2tyM2dodHM0cjJvcmlzdDR3ZXJzNXkybTFvMG8wZDF0YmFsbDZyZDFleDJzYWxlNHVtM3VuZGF0aW9uOHgycjBlZTFzZW5pdXM3bDFvZ2FuczRudGllcjd0cjJ1aml0c3U1bjBkMnJuaXR1cmU3dGJvbDV5aTNnYTBsMGxlcnkzbzF1cDRtZTBzM3AxcmRlbjR5MmIwaXozZDBuMmUwYTFudDBpbmc1b3JnZTVmMWcwZWUzaDFpMGZ0MHMzdmVzMmluZzVsMGFzczNlMW9iYWwybzRtMGFpbDNiaDJvMXgybjFvZGFkZHk1bGQwcG9pbnQ2ZjJvZHllYXI1ZzBsZTRwMXQxdjJwMXExcjBhaW5nZXI1cGhpY3M1dGlzNGVlbjNpcGUzb2Nlcnk0dXA0czF0MXUwY2NpM2dlMmlkZTJ0YXJzNXJ1M3cxeTJoYWlyMm1idXJnNW5nb3V0NXVzM2JvMmRmYzBiYW5rN2VhbHRoMGNhcmU4bHAxc2lua2k2cmUxbWVzNWlwaG9wNHNhbWl0c3U3dGFjaGk1djJrMHQybTFuMW9ja2V5NGxkaW5nczVpZGF5NW1lZGVwb3Q1Z29vZHM1czBlbnNlN25kYTNyc2Uzc3BpdGFsNXQwaW5nNXQwZWxzM21haWw1dXNlM3cycjFzYmMzdDF1MGdoZXM1eWF0dDN1bmRhaTdpYm0yY2JjMmUxdTJkMWUwZWUzZm0ya2FubzRsMW0wYW1hdDRkYjJtbzBiaWxpZW45bjBjMWR1c3RyaWVzOGZpbml0aTVvMmcxazFzdGl0dXRlNnVyYW5jZTRlNHQwZXJuYXRpb25hbDEwdWl0NHZlc3RtZW50czEwbzFwaXJhbmdhN3ExcjBpc2g0czBtYWlsaTV0MGFuYnVsN3QwYXUydjNqYWd1YXI0dmEzY2IyZTBlcDJ0enQzd2Vscnk2aW8ybGwybTBwMm5qMm8wYnMxdXJnNHQxeTJwMG1vcmdhbjZyczN1ZWdvczRuaXBlcjdrYXVmZW41ZGRpM2UwcnJ5aG90ZWxzNnByb3BlcnRpZXMxNGZoMmcxaDFpMGExZHMybTFuZGxlNHRjaGVuNXdpM20xbjFvZWxuM21hdHN1NXNoZXI1cDBtZzJuMnIwZDFlZDN1b2tncm91cDh3MXkwb3RvNHoybGEwY2FpeGE1bWJvcmdoaW5pOGVyM25kMHJvdmVyNnhlc3M1c2FsbGU1dDBpbm8zcm9iZTV3MHllcjViMWMxZHMyZWFzZTNjbGVyYzVmcmFrNGdhbDJvMnh1czRnYnQzaTBkbDJmZTBpbnN1cmFuY2U5c3R5bGU3Z2h0aW5nNmtlMmxseTNtaXRlZDRvMm5jb2xuNGsydmUxaW5nNWsxbGMxcDJvYW4wczNja2VyM3VzM2wxbmRvbjR0dGUxbzN2ZTNwbDBmaW5hbmNpYWwxMXIxczF0MGQwYTN1MG5kYmVjazZ4ZTF1cnk1djF5Mm1hMGRyaWQ0aWYxc29uNGtldXA0bjBhZ2VtZW50N2dvM3AxcmtldDBpbmczczRyaW90dDVzaGFsbHM3dHRlbDViYTJjMGtpbnNleTdkMWUwZDBpYTNldDJsYm91cm5lN21lMW9yaWFsNm4wdTJyY2swbXNkN2cxaDFpYW1pM2Nyb3NvZnQ3bDFuaTF0MnQwc3ViaXNoaTlrMWwwYjFzMm0wYTJuMW8wYmkwbGU0ZGEyZTFpMW0xbmFzaDNleTJzdGVyNXJtb24zdGdhZ2U2c2NvdzR0bzByY3ljbGVzOXYwaWU0cDFxMXIxczBkMnQwbjFyMnUwc2V1bTNpYzR2MXcxeDF5MXoybmEwYjFnb3lhNG1lMnZ5M2JhMmMxZTBjMXQwYmFuazRmbGl4NHdvcms1dXN0YXI1dzBzMnh0MGRpcmVjdDd1czRmMGwyZzBvMmhrMmkwY28ya2Uxb24zbmphM3NzYW4xeTVsMW8wa2lhM3J0b240dzBydXozdHY0cDFyMGExdzJ0dDJ1MXljMnoyb2JpMXNlcnZlcjdmZmljZTVraW5hd2E2bGF5YW4wZ3JvdXA5bG8zbTBlZ2E0bmUxZzFsMGluZTVvbzJwZW4zcmFjbGUzbmdlNGcwYW5pYzVpZ2luczZzYWthNHRzdWthNHQydmgzcGEwZ2UybmFzb25pYzdyaXMyczF0bmVyczRzMXkzeTJjY3czZTB0MmYwaXplcjVnMWgwYXJtYWN5NmQxaWxpcHM1b25lMnRvMGdyYXBoeTZzNHlzaW81aWNzMXRldDJ1cmVzNmQxbjBnMWsyb25lZXI1enphNGsxbDBhY2UyeTBzdGF0aW9uOXVtYmluZzVzM20xbjBjMm9obDJrZXIzbGl0aWU1cm4yc3QzcjBheGkzZXNzM2ltZTNvMGQwdWN0aW9uczhmMWdyZXNzaXZlOG1vMnBlcnRpZXMzeTV0ZWN0aW9uOHUwZGVudGlhbDlzMXQxdWIydzBjMnkycWExcG9uM3VlYmVjM3N0NXJhY2luZzRkaW80ZTBhZDFsZXN0YXRlNnRvcjJ5NGNpcGVzNWQwdW1icmVsbGE5aGFiM2lzZTBuM3QybGlhbmNlNm4wdDBhbHM1cGFpcjNvcnQzdWJsaWNhbjhzdDBhdXJhbnQ4dmlldzBzNXhyb3RoNmljaDBhcmRsaTZvaDNsMW8xcDJvMGNrczNkZW8zZ2VyczRvbTNzMHZwM3UwZ2J5M2hyMm4ydzBlMnl1a3l1NnNhMGFybGFuZDZmZTB0eTRrdXJhNGxlMW9uM21zY2x1YjR1bmc1bmR2aWswY29yb21hbnQxMm9maTRwMXJsMnMxdmUyeG8zYjBpMXMyYzBiMWhhZWZmbGVyN21pZHQ0b2xhcnNoaXBzOG9sM3VsZTN3YXJ6NWllbmNlNW90M2QxZTBhcmNoM3QyY3VyZTFpdHk2ZWsybGVjdDRuZXIzcnZpY2VzNnZlbjN3MXgweTNmcjJnMWgwYW5ncmlsYTZycDNlbGwzaWExa3NoYTVvZXMycDBwaW5nNXVqaTN3M2kwbGsybmExZ2xlczV0ZTNqMWswaTBuMnkwcGU0bDBpbmc0bTBhcnQzaWxlNG4wY2YzbzBjY2VyM2lhbDRmdGJhbms0d2FyZTZodTJsYXIydXRpb25zN25nMXkyeTJwYTBjZTNvcnQydDNyMGwyczF0MGFkYTJwbGVzNHIxdGViYW5rNGZhcm03YzBncm91cDZvY2tob2xtNnJhZ2UzZTNyZWFtNHVkaW8yeTN5bGU0dTBja3MzcHBsaWVzM3kyb3J0NXJmMWdlcnk1enVraTV2MXdhdGNoNGlzczR4MXkwZG5leTRzdGVtczZ6MnRhYjFpcGVpNGxrMm9iYW80cmdldDR0YW1vdG9yczZyMnRvbzR4MGkzYzBpMmQwazJlYW0yY2gwbm9sb2d5OGwxbWFzZWs1bm5pczR2YTNmMWcxaDBkMWVhdGVyMnJlNmlhYTJja2V0czVlbmRhNHBzMnJlczJvbDRqMG1heHg0eDJrMG1heHg1bDFtMGFsbDRuMW8wZGF5M2t5bzNvbHMzcDFyYXkzc2hpYmE1dGFsM3VyczN3bjJ5b3RhM3MzcjBhZGUxaW5nNGluaW5nNXZlbDBlcnMwaW5zdXJhbmNlMTZ1c3QzdjJ0MXViZTJpMW5lczNzaHU0djBzMncxejJ1YTFiYW5rM3MyZzFrMW5pY29tM3ZlcnNpdHk4bzJvbDJwczJzMXkxejJ2YTBjYXRpb25zN25hMWd1YXJkN2MxZTBnYXMzbnR1cmVzNnJpc2lnbjVtXHUwMEY2Z2Vuc2JlcmF0ZXIydW5nMTRzaWNoZXJ1bmcxMHQyZzFpMGFqZXM0ZGVvM2cxa2luZzRsbGFzNG4xcDFyZ2luNHNhMWlvbjR2YTFvM2xhYW5kZXJlbjluMW9ka2EzbHZvM3RlMWluZzNvMnlhZ2U1dTJ3YWxlczJtYXJ0NHRlcjRuZzBnb3U1dGNoMGVzNmVhdGhlcjBjaGFubmVsMTJiY2FtM2VyMnNpdGU1ZDBkaW5nNWlibzJyM2YxaG9zd2hvNmllbjJraTJsbGlhbWhpbGw5bjBkb3dzNGUxbmVyczZtZTJvb2RzaWRlNnJrMHMybGQzdzJzMXRjMWYzeGJveDNlcm94NGlodWFuNG4yeHgyeXozeWFjaHRzNGhvbzNtYXh1bjVuZGV4NWUxb2RvYmFzaGk3Z2Eya29oYW1hNnUwdHViZTZ0MXVuM3phMHBwb3M0cmEzZXJvM2lwMm0xb25lM3VlcmljaDZ3Mic7XG4vLyBJbnRlcm5hdGlvbmFsaXplZCBkb21haW4gbmFtZXMgY29udGFpbmluZyBub24tQVNDSUlcbmNvbnN0IGVuY29kZWRVdGxkcyA9ICdcdTAzQjVcdTAzQkIxXHUwM0M1Mlx1MDQzMVx1MDQzMzFcdTA0MzVcdTA0M0IzXHUwNDM0XHUwNDM1XHUwNDQyXHUwNDM4NFx1MDQzNVx1MDQ0RTJcdTA0M0FcdTA0MzBcdTA0NDJcdTA0M0VcdTA0M0JcdTA0MzhcdTA0M0E2XHUwNDNFXHUwNDNDM1x1MDQzQ1x1MDQzQVx1MDQzNDJcdTA0M0VcdTA0M0QxXHUwNDQxXHUwNDNBXHUwNDMyXHUwNDMwNlx1MDQzRVx1MDQzRFx1MDQzQlx1MDQzMFx1MDQzOVx1MDQzRDVcdTA0NDBcdTA0MzMzXHUwNDQwXHUwNDQzXHUwNDQxMlx1MDQ0NDJcdTA0NDFcdTA0MzBcdTA0MzlcdTA0NDIzXHUwNDQwXHUwNDMxM1x1MDQ0M1x1MDQzQVx1MDQ0MDNcdTA0OUJcdTA0MzBcdTA0MzczXHUwNTcwXHUwNTYxXHUwNTc1M1x1MDVEOVx1MDVFOVx1MDVFOFx1MDVEMFx1MDVEQzVcdTA1RTdcdTA1RDVcdTA1REQzXHUwNjI3XHUwNjI4XHUwNjQ4XHUwNjM4XHUwNjI4XHUwNjRBNVx1MDYzMVx1MDYyN1x1MDY0NVx1MDY0M1x1MDY0ODVcdTA2NDRcdTA2MjdcdTA2MzFcdTA2MkZcdTA2NDY0XHUwNjI4XHUwNjJEXHUwNjMxXHUwNjRBXHUwNjQ2NVx1MDYyQ1x1MDYzMlx1MDYyN1x1MDYyNlx1MDYzMTVcdTA2MzNcdTA2MzlcdTA2NDhcdTA2MkZcdTA2NEFcdTA2Mjk2XHUwNjM5XHUwNjQ0XHUwNjRBXHUwNjI3XHUwNjQ2NVx1MDY0NVx1MDYzQVx1MDYzMVx1MDYyODVcdTA2NDVcdTA2MjdcdTA2MzFcdTA2MjdcdTA2MkE1XHUwNkNDXHUwNjMxXHUwNjI3XHUwNjQ2NVx1MDYyOFx1MDYyN1x1MDYzMVx1MDYyQTJcdTA2MzJcdTA2MjdcdTA2MzE0XHUwNjRBXHUwNjJBXHUwNjQzM1x1MDZCRVx1MDYyN1x1MDYzMVx1MDYyQTVcdTA2MkFcdTA2NDhcdTA2NDZcdTA2MzM0XHUwNjMzXHUwNjQ4XHUwNjJGXHUwNjI3XHUwNjQ2M1x1MDYzMVx1MDY0QVx1MDYyOTVcdTA2MzRcdTA2MjhcdTA2NDNcdTA2Mjk0XHUwNjM5XHUwNjMxXHUwNjI3XHUwNjQyMlx1MDYyODJcdTA2NDVcdTA2MjdcdTA2NDY0XHUwNjQxXHUwNjQ0XHUwNjMzXHUwNjM3XHUwNjRBXHUwNjQ2Nlx1MDY0Mlx1MDYzN1x1MDYzMTNcdTA2NDNcdTA2MjdcdTA2MkJcdTA2NDhcdTA2NDRcdTA2NEFcdTA2NDM2XHUwNjQ4XHUwNjQ1M1x1MDY0NVx1MDYzNVx1MDYzMTJcdTA2NDRcdTA2NEFcdTA2MzNcdTA2NEFcdTA2Mjc1XHUwNjQ4XHUwNjMxXHUwNjRBXHUwNjJBXHUwNjI3XHUwNjQ2XHUwNjRBXHUwNjI3N1x1MDY0Mlx1MDYzOTRcdTA2NDdcdTA2NDVcdTA2MzFcdTA2MjdcdTA2NDc1XHUwNjdFXHUwNjI3XHUwNkE5XHUwNjMzXHUwNjJBXHUwNjI3XHUwNjQ2N1x1MDY4MFx1MDYyN1x1MDYzMVx1MDYyQTRcdTA5MTVcdTA5NDlcdTA5MkUzXHUwOTI4XHUwOTQ3XHUwOTFGM1x1MDkyRFx1MDkzRVx1MDkzMFx1MDkyNDBcdTA5MkVcdTA5NEQzXHUwOTRCXHUwOTI0NVx1MDkzOFx1MDkwMlx1MDkxN1x1MDkyMFx1MDkyODVcdTA5QUNcdTA5QkVcdTA5ODJcdTA5QjJcdTA5QkU1XHUwOUFEXHUwOUJFXHUwOUIwXHUwOUE0Mlx1MDlGMFx1MDlBNDRcdTBBMkRcdTBBM0VcdTBBMzBcdTBBMjQ0XHUwQUFEXHUwQUJFXHUwQUIwXHUwQUE0NFx1MEIyRFx1MEIzRVx1MEIzMFx1MEIyNDRcdTBCODdcdTBCQThcdTBCQ0RcdTBCQTRcdTBCQkZcdTBCQUZcdTBCQkU2XHUwQkIyXHUwQjk5XHUwQkNEXHUwQjk1XHUwQkM4Nlx1MEI5QVx1MEJCRlx1MEI5OVx1MEJDRFx1MEI5NVx1MEJBQVx1MEJDRFx1MEJBQVx1MEJDMlx1MEJCMFx1MEJDRDExXHUwQzJEXHUwQzNFXHUwQzMwXHUwQzI0XHUwQzRENVx1MENBRFx1MENCRVx1MENCMFx1MENBNDRcdTBEMkRcdTBEM0VcdTBEMzBcdTBEMjRcdTBEMDI1XHUwREJEXHUwRDgyXHUwRDlBXHUwRENGNFx1MEUwNFx1MEUyRFx1MEUyMTNcdTBFNDRcdTBFMTdcdTBFMjIzXHUwRUE1XHUwRUIyXHUwRUE3M1x1MTBEMlx1MTBENDJcdTMwN0ZcdTMwOTNcdTMwNkEzXHUzMEEyXHUzMERFXHUzMEJFXHUzMEYzNFx1MzBBRlx1MzBFOVx1MzBBNlx1MzBDOTRcdTMwQjBcdTMwRkNcdTMwQjBcdTMwRUI0XHUzMEIzXHUzMEUwMlx1MzBCOVx1MzBDOFx1MzBBMjNcdTMwQkJcdTMwRkNcdTMwRUIzXHUzMEQ1XHUzMEExXHUzMEMzXHUzMEI3XHUzMEU3XHUzMEYzNlx1MzBERFx1MzBBNFx1MzBGM1x1MzBDODRcdTRFMTZcdTc1NEMyXHU0RTJEXHU0RkUxMVx1NTZGRDFcdTU3MEIxXHU2NTg3XHU3RjUxM1x1NEU5QVx1OUE2Q1x1OTAwQTNcdTRGMDFcdTRFMUEyXHU0RjVCXHU1QzcxMlx1NEZFMVx1NjA2RjJcdTUwNjVcdTVFQjcyXHU1MTZCXHU1MzY2Mlx1NTE2Q1x1NTNGODFcdTc2Q0EyXHU1M0YwXHU2RTdFMVx1NzA2MzJcdTU1NDZcdTU3Q0UxXHU1RTk3MVx1NjgwNzJcdTU2MDlcdTkxQ0MwXHU1OTI3XHU5MTUyXHU1RTk3NVx1NTcyOFx1N0VCRjJcdTU5MjdcdTYyRkYyXHU1OTI5XHU0RTNCXHU2NTU5M1x1NUEzMVx1NEU1MDJcdTVCQjZcdTk2RkIyXHU1RTdGXHU0RTFDMlx1NUZBRVx1NTM1QTJcdTYxNDhcdTU1ODQyXHU2MjExXHU3MjMxXHU0RjYwM1x1NjI0Qlx1NjczQTJcdTYyREJcdTgwNTgyXHU2NTNGXHU1MkExMVx1NUU5QzJcdTY1QjBcdTUyQTBcdTU3NjEyXHU5NUZCMlx1NjVGNlx1NUMxQTJcdTY2RjhcdTdDNEQyXHU2NzNBXHU2Nzg0Mlx1NkRFMVx1OUE2Q1x1OTUyMTNcdTZFMzhcdTYyMEYyXHU2RkIzXHU5NTgwMlx1NzBCOVx1NzcwQjJcdTc5RkJcdTUyQTgyXHU3RUM0XHU3RUM3XHU2NzNBXHU2Nzg0NFx1N0Y1MVx1NTc0MDFcdTVFOTcxXHU3QUQ5MVx1N0VEQzJcdTgwNTRcdTkwMUEyXHU4QzM3XHU2QjRDMlx1OEQyRFx1NzI2OTJcdTkwMUFcdThDQTkyXHU5NkM2XHU1NkUyMlx1OTZGQlx1OEEwQVx1NzZDOFx1NzlEMTRcdTk4REVcdTUyMjlcdTZENjYzXHU5OERGXHU1NEMxMlx1OTkxMFx1NTM4NTJcdTk5OTlcdTY4M0NcdTkxQ0NcdTYyQzkzXHU2RTJGMlx1QjJGN1x1QjEzNzFcdUNFRjQyXHVDMEJDXHVDMTMxMlx1RDU1Q1x1QUQ2RDInO1xuXG4vKipcbiAqIEZpbml0ZSBTdGF0ZSBNYWNoaW5lIGdlbmVyYXRpb24gdXRpbGl0aWVzXG4gKi9cblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHR5cGVkZWYge3sgW2dyb3VwOiBzdHJpbmddOiBUW10gfX0gQ29sbGVjdGlvbnNcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHt7IFtncm91cDogc3RyaW5nXTogdHJ1ZSB9fSBGbGFnc1xuICovXG5cbi8vIEtleXMgaW4gc2Nhbm5lciBDb2xsZWN0aW9ucyBpbnN0YW5jZXNcbmNvbnN0IG51bWVyaWMgPSAnbnVtZXJpYyc7XG5jb25zdCBhc2NpaSA9ICdhc2NpaSc7XG5jb25zdCBhbHBoYSA9ICdhbHBoYSc7XG5jb25zdCBhc2NpaW51bWVyaWMgPSAnYXNjaWludW1lcmljJztcbmNvbnN0IGFscGhhbnVtZXJpYyA9ICdhbHBoYW51bWVyaWMnO1xuY29uc3QgZG9tYWluID0gJ2RvbWFpbic7XG5jb25zdCBlbW9qaSA9ICdlbW9qaSc7XG5jb25zdCBzY2hlbWUgPSAnc2NoZW1lJztcbmNvbnN0IHNsYXNoc2NoZW1lID0gJ3NsYXNoc2NoZW1lJztcbmNvbnN0IHdoaXRlc3BhY2UgPSAnd2hpdGVzcGFjZSc7XG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0ge0NvbGxlY3Rpb25zPFQ+fSBncm91cHMgdG8gcmVnaXN0ZXIgaW5cbiAqIEByZXR1cm5zIHtUW119IEN1cnJlbnQgbGlzdCBvZiB0b2tlbnMgaW4gdGhlIGdpdmVuIGNvbGxlY3Rpb25cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJHcm91cChuYW1lLCBncm91cHMpIHtcbiAgaWYgKCEobmFtZSBpbiBncm91cHMpKSB7XG4gICAgZ3JvdXBzW25hbWVdID0gW107XG4gIH1cbiAgcmV0dXJuIGdyb3Vwc1tuYW1lXTtcbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtUfSB0IHRva2VuIHRvIGFkZFxuICogQHBhcmFtIHtDb2xsZWN0aW9uczxUPn0gZ3JvdXBzXG4gKiBAcGFyYW0ge0ZsYWdzfSBmbGFnc1xuICovXG5mdW5jdGlvbiBhZGRUb0dyb3Vwcyh0LCBmbGFncywgZ3JvdXBzKSB7XG4gIGlmIChmbGFnc1tudW1lcmljXSkge1xuICAgIGZsYWdzW2FzY2lpbnVtZXJpY10gPSB0cnVlO1xuICAgIGZsYWdzW2FscGhhbnVtZXJpY10gPSB0cnVlO1xuICB9XG4gIGlmIChmbGFnc1thc2NpaV0pIHtcbiAgICBmbGFnc1thc2NpaW51bWVyaWNdID0gdHJ1ZTtcbiAgICBmbGFnc1thbHBoYV0gPSB0cnVlO1xuICB9XG4gIGlmIChmbGFnc1thc2NpaW51bWVyaWNdKSB7XG4gICAgZmxhZ3NbYWxwaGFudW1lcmljXSA9IHRydWU7XG4gIH1cbiAgaWYgKGZsYWdzW2FscGhhXSkge1xuICAgIGZsYWdzW2FscGhhbnVtZXJpY10gPSB0cnVlO1xuICB9XG4gIGlmIChmbGFnc1thbHBoYW51bWVyaWNdKSB7XG4gICAgZmxhZ3NbZG9tYWluXSA9IHRydWU7XG4gIH1cbiAgaWYgKGZsYWdzW2Vtb2ppXSkge1xuICAgIGZsYWdzW2RvbWFpbl0gPSB0cnVlO1xuICB9XG4gIGZvciAoY29uc3QgayBpbiBmbGFncykge1xuICAgIGNvbnN0IGdyb3VwID0gcmVnaXN0ZXJHcm91cChrLCBncm91cHMpO1xuICAgIGlmIChncm91cC5pbmRleE9mKHQpIDwgMCkge1xuICAgICAgZ3JvdXAucHVzaCh0KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtUfSB0IHRva2VuIHRvIGNoZWNrXG4gKiBAcGFyYW0ge0NvbGxlY3Rpb25zPFQ+fSBncm91cHNcbiAqIEByZXR1cm5zIHtGbGFnc30gZ3JvdXAgZmxhZ3MgdGhhdCBjb250YWluIHRoaXMgdG9rZW5cbiAqL1xuZnVuY3Rpb24gZmxhZ3NGb3JUb2tlbih0LCBncm91cHMpIHtcbiAgY29uc3QgcmVzdWx0ID0ge307XG4gIGZvciAoY29uc3QgYyBpbiBncm91cHMpIHtcbiAgICBpZiAoZ3JvdXBzW2NdLmluZGV4T2YodCkgPj0gMCkge1xuICAgICAgcmVzdWx0W2NdID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHR5cGVkZWYge251bGwgfCBUIH0gVHJhbnNpdGlvblxuICovXG5cbi8qKlxuICogRGVmaW5lIGEgYmFzaWMgc3RhdGUgbWFjaGluZSBzdGF0ZS4gaiBpcyB0aGUgbGlzdCBvZiBjaGFyYWN0ZXIgdHJhbnNpdGlvbnMsXG4gKiBqciBpcyB0aGUgbGlzdCBvZiByZWdleC1tYXRjaCB0cmFuc2l0aW9ucywgamQgaXMgdGhlIGRlZmF1bHQgc3RhdGUgdG9cbiAqIHRyYW5zaXRpb24gdG8gdCBpcyB0aGUgYWNjZXB0aW5nIHRva2VuIHR5cGUsIGlmIGFueS4gSWYgdGhpcyBpcyB0aGUgdGVybWluYWxcbiAqIHN0YXRlLCB0aGVuIGl0IGRvZXMgbm90IGVtaXQgYSB0b2tlbi5cbiAqXG4gKiBUaGUgdGVtcGxhdGUgdHlwZSBUIHJlcHJlc2VudHMgdGhlIHR5cGUgb2YgdGhlIHRva2VuIHRoaXMgc3RhdGUgYWNjZXB0cy4gVGhpc1xuICogc2hvdWxkIGJlIGEgc3RyaW5nIChzdWNoIGFzIG9mIHRoZSB0b2tlbiBleHBvcnRzIGluIGB0ZXh0LmpzYCkgb3IgYVxuICogTXVsdGlUb2tlbiBzdWJjbGFzcyAoZnJvbSBgbXVsdGkuanNgKVxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge1R9IFt0b2tlbl0gVG9rZW4gdGhhdCB0aGlzIHN0YXRlIGVtaXRzXG4gKi9cbmZ1bmN0aW9uIFN0YXRlKHRva2VuID0gbnVsbCkge1xuICAvLyB0aGlzLm4gPSBudWxsOyAvLyBERUJVRzogU3RhdGUgbmFtZVxuICAvKiogQHR5cGUge3sgW2lucHV0OiBzdHJpbmddOiBTdGF0ZTxUPiB9fSBqICovXG4gIHRoaXMuaiA9IHt9OyAvLyBJTVBMRU1FTlRBVElPTiAxXG4gIC8vIHRoaXMuaiA9IFtdOyAvLyBJTVBMRU1FTlRBVElPTiAyXG4gIC8qKiBAdHlwZSB7W1JlZ0V4cCwgU3RhdGU8VD5dW119IGpyICovXG4gIHRoaXMuanIgPSBbXTtcbiAgLyoqIEB0eXBlIHs/U3RhdGU8VD59IGpkICovXG4gIHRoaXMuamQgPSBudWxsO1xuICAvKiogQHR5cGUgez9UfSB0ICovXG4gIHRoaXMudCA9IHRva2VuO1xufVxuXG4vKipcbiAqIFNjYW5uZXIgdG9rZW4gZ3JvdXBzXG4gKiBAdHlwZSBDb2xsZWN0aW9uczxzdHJpbmc+XG4gKi9cblN0YXRlLmdyb3VwcyA9IHt9O1xuU3RhdGUucHJvdG90eXBlID0ge1xuICBhY2NlcHRzKCkge1xuICAgIHJldHVybiAhIXRoaXMudDtcbiAgfSxcbiAgLyoqXG4gICAqIEZvbGxvdyBhbiBleGlzdGluZyB0cmFuc2l0aW9uIGZyb20gdGhlIGdpdmVuIGlucHV0IHRvIHRoZSBuZXh0IHN0YXRlLlxuICAgKiBEb2VzIG5vdCBtdXRhdGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dCBjaGFyYWN0ZXIgb3IgdG9rZW4gdHlwZSB0byB0cmFuc2l0aW9uIG9uXG4gICAqIEByZXR1cm5zIHs/U3RhdGU8VD59IHRoZSBuZXh0IHN0YXRlLCBpZiBhbnlcbiAgICovXG4gIGdvKGlucHV0KSB7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzO1xuICAgIGNvbnN0IG5leHRTdGF0ZSA9IHN0YXRlLmpbaW5wdXRdO1xuICAgIGlmIChuZXh0U3RhdGUpIHtcbiAgICAgIHJldHVybiBuZXh0U3RhdGU7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhdGUuanIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHJlZ2V4ID0gc3RhdGUuanJbaV1bMF07XG4gICAgICBjb25zdCBuZXh0U3RhdGUgPSBzdGF0ZS5qcltpXVsxXTsgLy8gbm90ZTogbWlnaHQgYmUgZW1wdHkgdG8gcHJldmVudCBkZWZhdWx0IGp1bXBcbiAgICAgIGlmIChuZXh0U3RhdGUgJiYgcmVnZXgudGVzdChpbnB1dCkpIHtcbiAgICAgICAgcmV0dXJuIG5leHRTdGF0ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gTm93aGVyZSBsZWZ0IHRvIGp1bXAhIFJldHVybiBkZWZhdWx0LCBpZiBhbnlcbiAgICByZXR1cm4gc3RhdGUuamQ7XG4gIH0sXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBzdGF0ZSBoYXMgYSB0cmFuc2l0aW9uIGZvciB0aGUgZ2l2ZW4gaW5wdXQuIFNldCB0aGUgc2Vjb25kXG4gICAqIGFyZ3VtZW50IHRvIHRydWUgdG8gb25seSBsb29rIGZvciBhbiBleGFjdCBtYXRjaCAoYW5kIG5vdCBhIGRlZmF1bHQgb3JcbiAgICogcmVndWxhci1leHByZXNzaW9uLWJhc2VkIHRyYW5zaXRpb24pXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGV4YWN0T25seVxuICAgKi9cbiAgaGFzKGlucHV0LCBleGFjdE9ubHkgPSBmYWxzZSkge1xuICAgIHJldHVybiBleGFjdE9ubHkgPyBpbnB1dCBpbiB0aGlzLmogOiAhIXRoaXMuZ28oaW5wdXQpO1xuICB9LFxuICAvKipcbiAgICogU2hvcnQgZm9yIFwidHJhbnNpdGlvbiBhbGxcIjsgY3JlYXRlIGEgdHJhbnNpdGlvbiBmcm9tIHRoZSBhcnJheSBvZiBpdGVtc1xuICAgKiBpbiB0aGUgZ2l2ZW4gbGlzdCB0byB0aGUgc2FtZSBmaW5hbCByZXN1bHRpbmcgc3RhdGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgc3RyaW5nW119IGlucHV0cyBHcm91cCBvZiBpbnB1dHMgdG8gdHJhbnNpdGlvbiBvblxuICAgKiBAcGFyYW0ge1RyYW5zaXRpb248VD4gfCBTdGF0ZTxUPn0gW25leHRdIFRyYW5zaXRpb24gb3B0aW9uc1xuICAgKiBAcGFyYW0ge0ZsYWdzfSBbZmxhZ3NdIENvbGxlY3Rpb25zIGZsYWdzIHRvIGFkZCB0b2tlbiB0b1xuICAgKiBAcGFyYW0ge0NvbGxlY3Rpb25zPFQ+fSBbZ3JvdXBzXSBNYXN0ZXIgbGlzdCBvZiB0b2tlbiBncm91cHNcbiAgICovXG4gIHRhKGlucHV0cywgbmV4dCwgZmxhZ3MsIGdyb3Vwcykge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLnR0KGlucHV0c1tpXSwgbmV4dCwgZmxhZ3MsIGdyb3Vwcyk7XG4gICAgfVxuICB9LFxuICAvKipcbiAgICogU2hvcnQgZm9yIFwidGFrZSByZWdleHAgdHJhbnNpdGlvblwiOyBkZWZpbmVzIGEgdHJhbnNpdGlvbiBmb3IgdGhpcyBzdGF0ZVxuICAgKiB3aGVuIGl0IGVuY291bnRlcnMgYSB0b2tlbiB3aGljaCBtYXRjaGVzIHRoZSBnaXZlbiByZWd1bGFyIGV4cHJlc3Npb25cbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cCBSZWd1bGFyIGV4cHJlc3Npb24gdHJhbnNpdGlvbiAocG9wdWxhdGUgZmlyc3QpXG4gICAqIEBwYXJhbSB7VCB8IFN0YXRlPFQ+fSBbbmV4dF0gVHJhbnNpdGlvbiBvcHRpb25zXG4gICAqIEBwYXJhbSB7RmxhZ3N9IFtmbGFnc10gQ29sbGVjdGlvbnMgZmxhZ3MgdG8gYWRkIHRva2VuIHRvXG4gICAqIEBwYXJhbSB7Q29sbGVjdGlvbnM8VD59IFtncm91cHNdIE1hc3RlciBsaXN0IG9mIHRva2VuIGdyb3Vwc1xuICAgKiBAcmV0dXJucyB7U3RhdGU8VD59IHRha2VuIGFmdGVyIHRoZSBnaXZlbiBpbnB1dFxuICAgKi9cbiAgdHIocmVnZXhwLCBuZXh0LCBmbGFncywgZ3JvdXBzKSB7XG4gICAgZ3JvdXBzID0gZ3JvdXBzIHx8IFN0YXRlLmdyb3VwcztcbiAgICBsZXQgbmV4dFN0YXRlO1xuICAgIGlmIChuZXh0ICYmIG5leHQuaikge1xuICAgICAgbmV4dFN0YXRlID0gbmV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVG9rZW4gd2l0aCBtYXliZSB0b2tlbiBncm91cHNcbiAgICAgIG5leHRTdGF0ZSA9IG5ldyBTdGF0ZShuZXh0KTtcbiAgICAgIGlmIChmbGFncyAmJiBncm91cHMpIHtcbiAgICAgICAgYWRkVG9Hcm91cHMobmV4dCwgZmxhZ3MsIGdyb3Vwcyk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuanIucHVzaChbcmVnZXhwLCBuZXh0U3RhdGVdKTtcbiAgICByZXR1cm4gbmV4dFN0YXRlO1xuICB9LFxuICAvKipcbiAgICogU2hvcnQgZm9yIFwidGFrZSB0cmFuc2l0aW9uc1wiLCB3aWxsIHRha2UgYXMgbWFueSBzZXF1ZW50aWFsIHRyYW5zaXRpb25zIGFzXG4gICAqIHRoZSBsZW5ndGggb2YgdGhlIGdpdmVuIGlucHV0IGFuZCByZXR1cm5zIHRoZVxuICAgKiByZXN1bHRpbmcgZmluYWwgc3RhdGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgc3RyaW5nW119IGlucHV0XG4gICAqIEBwYXJhbSB7VCB8IFN0YXRlPFQ+fSBbbmV4dF0gVHJhbnNpdGlvbiBvcHRpb25zXG4gICAqIEBwYXJhbSB7RmxhZ3N9IFtmbGFnc10gQ29sbGVjdGlvbnMgZmxhZ3MgdG8gYWRkIHRva2VuIHRvXG4gICAqIEBwYXJhbSB7Q29sbGVjdGlvbnM8VD59IFtncm91cHNdIE1hc3RlciBsaXN0IG9mIHRva2VuIGdyb3Vwc1xuICAgKiBAcmV0dXJucyB7U3RhdGU8VD59IHRha2VuIGFmdGVyIHRoZSBnaXZlbiBpbnB1dFxuICAgKi9cbiAgdHMoaW5wdXQsIG5leHQsIGZsYWdzLCBncm91cHMpIHtcbiAgICBsZXQgc3RhdGUgPSB0aGlzO1xuICAgIGNvbnN0IGxlbiA9IGlucHV0Lmxlbmd0aDtcbiAgICBpZiAoIWxlbikge1xuICAgICAgcmV0dXJuIHN0YXRlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbiAtIDE7IGkrKykge1xuICAgICAgc3RhdGUgPSBzdGF0ZS50dChpbnB1dFtpXSk7XG4gICAgfVxuICAgIHJldHVybiBzdGF0ZS50dChpbnB1dFtsZW4gLSAxXSwgbmV4dCwgZmxhZ3MsIGdyb3Vwcyk7XG4gIH0sXG4gIC8qKlxuICAgKiBTaG9ydCBmb3IgXCJ0YWtlIHRyYW5zaXRpb25cIiwgdGhpcyBpcyBhIG1ldGhvZCBmb3IgYnVpbGRpbmcvd29ya2luZyB3aXRoXG4gICAqIHN0YXRlIG1hY2hpbmVzLlxuICAgKlxuICAgKiBJZiBhIHN0YXRlIGFscmVhZHkgZXhpc3RzIGZvciB0aGUgZ2l2ZW4gaW5wdXQsIHJldHVybnMgaXQuXG4gICAqXG4gICAqIElmIGEgdG9rZW4gaXMgc3BlY2lmaWVkLCB0aGF0IHN0YXRlIHdpbGwgZW1pdCB0aGF0IHRva2VuIHdoZW4gcmVhY2hlZCBieVxuICAgKiB0aGUgbGlua2lmeSBlbmdpbmUuXG4gICAqXG4gICAqIElmIG5vIHN0YXRlIGV4aXN0cywgaXQgd2lsbCBiZSBpbml0aWFsaXplZCB3aXRoIHNvbWUgZGVmYXVsdCB0cmFuc2l0aW9uc1xuICAgKiB0aGF0IHJlc2VtYmxlIGV4aXN0aW5nIGRlZmF1bHQgdHJhbnNpdGlvbnMuXG4gICAqXG4gICAqIElmIGEgc3RhdGUgaXMgZ2l2ZW4gZm9yIHRoZSBzZWNvbmQgYXJndW1lbnQsIHRoYXQgc3RhdGUgd2lsbCBiZVxuICAgKiB0cmFuc2l0aW9uZWQgdG8gb24gdGhlIGdpdmVuIGlucHV0IHJlZ2FyZGxlc3Mgb2Ygd2hhdCB0aGF0IGlucHV0XG4gICAqIHByZXZpb3VzbHkgZGlkLlxuICAgKlxuICAgKiBTcGVjaWZ5IGEgdG9rZW4gZ3JvdXAgZmxhZ3MgdG8gZGVmaW5lIGdyb3VwcyB0aGF0IHRoaXMgdG9rZW4gYmVsb25ncyB0by5cbiAgICogVGhlIHRva2VuIHdpbGwgYmUgYWRkZWQgdG8gY29ycmVzcG9uZGluZyBlbnRpcmVzIGluIHRoZSBnaXZlbiBncm91cHNcbiAgICogb2JqZWN0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgY2hhcmFjdGVyLCB0b2tlbiB0eXBlIHRvIHRyYW5zaXRpb24gb25cbiAgICogQHBhcmFtIHtUIHwgU3RhdGU8VD59IFtuZXh0XSBUcmFuc2l0aW9uIG9wdGlvbnNcbiAgICogQHBhcmFtIHtGbGFnc30gW2ZsYWdzXSBDb2xsZWN0aW9ucyBmbGFncyB0byBhZGQgdG9rZW4gdG9cbiAgICogQHBhcmFtIHtDb2xsZWN0aW9uczxUPn0gW2dyb3Vwc10gTWFzdGVyIGxpc3Qgb2YgZ3JvdXBzXG4gICAqIEByZXR1cm5zIHtTdGF0ZTxUPn0gdGFrZW4gYWZ0ZXIgdGhlIGdpdmVuIGlucHV0XG4gICAqL1xuICB0dChpbnB1dCwgbmV4dCwgZmxhZ3MsIGdyb3Vwcykge1xuICAgIGdyb3VwcyA9IGdyb3VwcyB8fCBTdGF0ZS5ncm91cHM7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzO1xuXG4gICAgLy8gQ2hlY2sgaWYgZXhpc3Rpbmcgc3RhdGUgZ2l2ZW4sIGp1c3QgYSBiYXNpYyB0cmFuc2l0aW9uXG4gICAgaWYgKG5leHQgJiYgbmV4dC5qKSB7XG4gICAgICBzdGF0ZS5qW2lucHV0XSA9IG5leHQ7XG4gICAgICByZXR1cm4gbmV4dDtcbiAgICB9XG4gICAgY29uc3QgdCA9IG5leHQ7XG5cbiAgICAvLyBUYWtlIHRoZSB0cmFuc2l0aW9uIHdpdGggdGhlIHVzdWFsIGRlZmF1bHQgbWVjaGFuaXNtcyBhbmQgdXNlIHRoYXQgYXNcbiAgICAvLyBhIHRlbXBsYXRlIGZvciBjcmVhdGluZyB0aGUgbmV4dCBzdGF0ZVxuICAgIGxldCBuZXh0U3RhdGUsXG4gICAgICB0ZW1wbGF0ZVN0YXRlID0gc3RhdGUuZ28oaW5wdXQpO1xuICAgIGlmICh0ZW1wbGF0ZVN0YXRlKSB7XG4gICAgICBuZXh0U3RhdGUgPSBuZXcgU3RhdGUoKTtcbiAgICAgIE9iamVjdC5hc3NpZ24obmV4dFN0YXRlLmosIHRlbXBsYXRlU3RhdGUuaik7XG4gICAgICBuZXh0U3RhdGUuanIucHVzaC5hcHBseShuZXh0U3RhdGUuanIsIHRlbXBsYXRlU3RhdGUuanIpO1xuICAgICAgbmV4dFN0YXRlLmpkID0gdGVtcGxhdGVTdGF0ZS5qZDtcbiAgICAgIG5leHRTdGF0ZS50ID0gdGVtcGxhdGVTdGF0ZS50O1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0U3RhdGUgPSBuZXcgU3RhdGUoKTtcbiAgICB9XG4gICAgaWYgKHQpIHtcbiAgICAgIC8vIEVuc3VyZSBuZXdseSB0b2tlbiBpcyBpbiB0aGUgc2FtZSBncm91cHMgYXMgdGhlIG9sZCB0b2tlblxuICAgICAgaWYgKGdyb3Vwcykge1xuICAgICAgICBpZiAobmV4dFN0YXRlLnQgJiYgdHlwZW9mIG5leHRTdGF0ZS50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGNvbnN0IGFsbEZsYWdzID0gT2JqZWN0LmFzc2lnbihmbGFnc0ZvclRva2VuKG5leHRTdGF0ZS50LCBncm91cHMpLCBmbGFncyk7XG4gICAgICAgICAgYWRkVG9Hcm91cHModCwgYWxsRmxhZ3MsIGdyb3Vwcyk7XG4gICAgICAgIH0gZWxzZSBpZiAoZmxhZ3MpIHtcbiAgICAgICAgICBhZGRUb0dyb3Vwcyh0LCBmbGFncywgZ3JvdXBzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbmV4dFN0YXRlLnQgPSB0OyAvLyBvdmVyd3JpdGUgYW55dGhpbmcgdGhhdCB3YXMgcHJldmlvdXNseSB0aGVyZVxuICAgIH1cbiAgICBzdGF0ZS5qW2lucHV0XSA9IG5leHRTdGF0ZTtcbiAgICByZXR1cm4gbmV4dFN0YXRlO1xuICB9XG59O1xuXG4vLyBIZWxwZXIgZnVuY3Rpb25zIHRvIGltcHJvdmUgbWluaWZpY2F0aW9uIChub3QgZXhwb3J0ZWQgb3V0c2lkZSBsaW5raWZ5anMgbW9kdWxlKVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge1N0YXRlPFQ+fSBzdGF0ZVxuICogQHBhcmFtIHtzdHJpbmcgfCBzdHJpbmdbXX0gaW5wdXRcbiAqIEBwYXJhbSB7RmxhZ3N9IFtmbGFnc11cbiAqIEBwYXJhbSB7Q29sbGVjdGlvbnM8VD59IFtncm91cHNdXG4gKi9cbmNvbnN0IHRhID0gKHN0YXRlLCBpbnB1dCwgbmV4dCwgZmxhZ3MsIGdyb3VwcykgPT4gc3RhdGUudGEoaW5wdXQsIG5leHQsIGZsYWdzLCBncm91cHMpO1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge1N0YXRlPFQ+fSBzdGF0ZVxuICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICogQHBhcmFtIHtUIHwgU3RhdGU8VD59IFtuZXh0XVxuICogQHBhcmFtIHtGbGFnc30gW2ZsYWdzXVxuICogQHBhcmFtIHtDb2xsZWN0aW9uczxUPn0gW2dyb3Vwc11cbiAqL1xuY29uc3QgdHIgPSAoc3RhdGUsIHJlZ2V4cCwgbmV4dCwgZmxhZ3MsIGdyb3VwcykgPT4gc3RhdGUudHIocmVnZXhwLCBuZXh0LCBmbGFncywgZ3JvdXBzKTtcblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtTdGF0ZTxUPn0gc3RhdGVcbiAqIEBwYXJhbSB7c3RyaW5nIHwgc3RyaW5nW119IGlucHV0XG4gKiBAcGFyYW0ge1QgfCBTdGF0ZTxUPn0gW25leHRdXG4gKiBAcGFyYW0ge0ZsYWdzfSBbZmxhZ3NdXG4gKiBAcGFyYW0ge0NvbGxlY3Rpb25zPFQ+fSBbZ3JvdXBzXVxuICovXG5jb25zdCB0cyA9IChzdGF0ZSwgaW5wdXQsIG5leHQsIGZsYWdzLCBncm91cHMpID0+IHN0YXRlLnRzKGlucHV0LCBuZXh0LCBmbGFncywgZ3JvdXBzKTtcblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtTdGF0ZTxUPn0gc3RhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dFxuICogQHBhcmFtIHtUIHwgU3RhdGU8VD59IFtuZXh0XVxuICogQHBhcmFtIHtDb2xsZWN0aW9uczxUPn0gW2dyb3Vwc11cbiAqIEBwYXJhbSB7RmxhZ3N9IFtmbGFnc11cbiAqL1xuY29uc3QgdHQgPSAoc3RhdGUsIGlucHV0LCBuZXh0LCBmbGFncywgZ3JvdXBzKSA9PiBzdGF0ZS50dChpbnB1dCwgbmV4dCwgZmxhZ3MsIGdyb3Vwcyk7XG5cbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblRleHQgVG9rZW5zXG5JZGVudGlmaWVycyBmb3IgdG9rZW4gb3V0cHV0cyBmcm9tIHRoZSByZWdleHAgc2Nhbm5lclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vLyBBIHZhbGlkIHdlYiBkb21haW4gdG9rZW5cbmNvbnN0IFdPUkQgPSAnV09SRCc7IC8vIG9ubHkgY29udGFpbnMgYS16XG5jb25zdCBVV09SRCA9ICdVV09SRCc7IC8vIGNvbnRhaW5zIGxldHRlcnMgb3RoZXIgdGhhbiBhLXosIHVzZWQgZm9yIElETlxuY29uc3QgQVNDSUlOVU1FUklDQUwgPSAnQVNDSUlOVU1FUklDQUwnOyAvLyBjb250YWlucyBhLXosIDAtOVxuY29uc3QgQUxQSEFOVU1FUklDQUwgPSAnQUxQSEFOVU1FUklDQUwnOyAvLyBjb250YWlucyBudW1iZXJzIGFuZCBsZXR0ZXJzIG90aGVyIHRoYW4gYS16LCB1c2VkIGZvciBJRE5cblxuLy8gU3BlY2lhbCBjYXNlIG9mIHdvcmRcbmNvbnN0IExPQ0FMSE9TVCA9ICdMT0NBTEhPU1QnO1xuXG4vLyBWYWxpZCB0b3AtbGV2ZWwgZG9tYWluLCBzcGVjaWFsIGNhc2Ugb2YgV09SRCAoc2VlIHRsZHMuanMpXG5jb25zdCBUTEQgPSAnVExEJztcblxuLy8gVmFsaWQgSUROIFRMRCwgc3BlY2lhbCBjYXNlIG9mIFVXT1JEIChzZWUgdGxkcy5qcylcbmNvbnN0IFVUTEQgPSAnVVRMRCc7XG5cbi8vIFRoZSBzY2hlbWUgcG9ydGlvbiBvZiBhIHdlYiBVUkkgcHJvdG9jb2wuIFN1cHBvcnRlZCB0eXBlcyBpbmNsdWRlOiBgbWFpbHRvYCxcbi8vIGBmaWxlYCwgYW5kIHVzZXItZGVmaW5lZCBjdXN0b20gcHJvdG9jb2xzLiBMaW1pdGVkIHRvIHNjaGVtZXMgdGhhdCBjb250YWluXG4vLyBvbmx5IGxldHRlcnNcbmNvbnN0IFNDSEVNRSA9ICdTQ0hFTUUnO1xuXG4vLyBTaW1pbGFyIHRvIFNDSEVNRSwgZXhjZXB0IG1ha2VzIGRpc3RpbmN0aW9uIGZvciBzY2hlbWVzIHRoYXQgbXVzdCBhbHdheXMgYmVcbi8vIGZvbGxvd2VkIGJ5IGA6Ly9gLCBub3QganVzdCBgOmAuIFN1cHBvcnRlZCB0eXBlcyBpbmNsdWRlIGBodHRwYCwgYGh0dHBzYCxcbi8vIGBmdHBgLCBgZnRwc2BcbmNvbnN0IFNMQVNIX1NDSEVNRSA9ICdTTEFTSF9TQ0hFTUUnO1xuXG4vLyBBbnkgc2VxdWVuY2Ugb2YgZGlnaXRzIDAtOVxuY29uc3QgTlVNID0gJ05VTSc7XG5cbi8vIEFueSBudW1iZXIgb2YgY29uc2VjdXRpdmUgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBuZXdsaW5lXG5jb25zdCBXUyA9ICdXUyc7XG5cbi8vIE5ldyBsaW5lICh1bml4IHN0eWxlKVxuY29uc3QgTkwgPSAnTkwnOyAvLyBcXG5cblxuLy8gT3BlbmluZy9jbG9zaW5nIGJyYWNrZXQgY2xhc3Nlc1xuLy8gVE9ETzogUmVuYW1lIE9QRU4gLT4gTEVGVCBhbmQgQ0xPU0UgLT4gUklHSFQgaW4gdjUgdG8gZml0IHdpdGggVW5pY29kZSBuYW1lc1xuLy8gQWxzbyByZW5hbWUgYW5nbGUgYnJhY2tlcyB0byBMRVNTVEhBTiBhbmQgR1JFQVRFUiBUSEFOXG5jb25zdCBPUEVOQlJBQ0UgPSAnT1BFTkJSQUNFJzsgLy8ge1xuY29uc3QgQ0xPU0VCUkFDRSA9ICdDTE9TRUJSQUNFJzsgLy8gfVxuY29uc3QgT1BFTkJSQUNLRVQgPSAnT1BFTkJSQUNLRVQnOyAvLyBbXG5jb25zdCBDTE9TRUJSQUNLRVQgPSAnQ0xPU0VCUkFDS0VUJzsgLy8gXVxuY29uc3QgT1BFTlBBUkVOID0gJ09QRU5QQVJFTic7IC8vIChcbmNvbnN0IENMT1NFUEFSRU4gPSAnQ0xPU0VQQVJFTic7IC8vIClcbmNvbnN0IE9QRU5BTkdMRUJSQUNLRVQgPSAnT1BFTkFOR0xFQlJBQ0tFVCc7IC8vIDxcbmNvbnN0IENMT1NFQU5HTEVCUkFDS0VUID0gJ0NMT1NFQU5HTEVCUkFDS0VUJzsgLy8gPlxuY29uc3QgRlVMTFdJRFRITEVGVFBBUkVOID0gJ0ZVTExXSURUSExFRlRQQVJFTic7IC8vIFx1RkYwOFxuY29uc3QgRlVMTFdJRFRIUklHSFRQQVJFTiA9ICdGVUxMV0lEVEhSSUdIVFBBUkVOJzsgLy8gXHVGRjA5XG5jb25zdCBMRUZUQ09STkVSQlJBQ0tFVCA9ICdMRUZUQ09STkVSQlJBQ0tFVCc7IC8vIFx1MzAwQ1xuY29uc3QgUklHSFRDT1JORVJCUkFDS0VUID0gJ1JJR0hUQ09STkVSQlJBQ0tFVCc7IC8vIFx1MzAwRFxuY29uc3QgTEVGVFdISVRFQ09STkVSQlJBQ0tFVCA9ICdMRUZUV0hJVEVDT1JORVJCUkFDS0VUJzsgLy8gXHUzMDBFXG5jb25zdCBSSUdIVFdISVRFQ09STkVSQlJBQ0tFVCA9ICdSSUdIVFdISVRFQ09STkVSQlJBQ0tFVCc7IC8vIFx1MzAwRlxuY29uc3QgRlVMTFdJRFRITEVTU1RIQU4gPSAnRlVMTFdJRFRITEVTU1RIQU4nOyAvLyBcdUZGMUNcbmNvbnN0IEZVTExXSURUSEdSRUFURVJUSEFOID0gJ0ZVTExXSURUSEdSRUFURVJUSEFOJzsgLy8gXHVGRjFFXG5cbi8vIFZhcmlvdXMgc3ltYm9sc1xuY29uc3QgQU1QRVJTQU5EID0gJ0FNUEVSU0FORCc7IC8vICZcbmNvbnN0IEFQT1NUUk9QSEUgPSAnQVBPU1RST1BIRSc7IC8vICdcbmNvbnN0IEFTVEVSSVNLID0gJ0FTVEVSSVNLJzsgLy8gKlxuY29uc3QgQVQgPSAnQVQnOyAvLyBAXG5jb25zdCBCQUNLU0xBU0ggPSAnQkFDS1NMQVNIJzsgLy8gXFxcbmNvbnN0IEJBQ0tUSUNLID0gJ0JBQ0tUSUNLJzsgLy8gYFxuY29uc3QgQ0FSRVQgPSAnQ0FSRVQnOyAvLyBeXG5jb25zdCBDT0xPTiA9ICdDT0xPTic7IC8vIDpcbmNvbnN0IENPTU1BID0gJ0NPTU1BJzsgLy8gLFxuY29uc3QgRE9MTEFSID0gJ0RPTExBUic7IC8vICRcbmNvbnN0IERPVCA9ICdET1QnOyAvLyAuXG5jb25zdCBFUVVBTFMgPSAnRVFVQUxTJzsgLy8gPVxuY29uc3QgRVhDTEFNQVRJT04gPSAnRVhDTEFNQVRJT04nOyAvLyAhXG5jb25zdCBIWVBIRU4gPSAnSFlQSEVOJzsgLy8gLVxuY29uc3QgUEVSQ0VOVCA9ICdQRVJDRU5UJzsgLy8gJVxuY29uc3QgUElQRSA9ICdQSVBFJzsgLy8gfFxuY29uc3QgUExVUyA9ICdQTFVTJzsgLy8gK1xuY29uc3QgUE9VTkQgPSAnUE9VTkQnOyAvLyAjXG5jb25zdCBRVUVSWSA9ICdRVUVSWSc7IC8vID9cbmNvbnN0IFFVT1RFID0gJ1FVT1RFJzsgLy8gXCJcbmNvbnN0IEZVTExXSURUSE1JRERMRURPVCA9ICdGVUxMV0lEVEhNSURETEVET1QnOyAvLyBcdTMwRkJcblxuY29uc3QgU0VNSSA9ICdTRU1JJzsgLy8gO1xuY29uc3QgU0xBU0ggPSAnU0xBU0gnOyAvLyAvXG5jb25zdCBUSUxERSA9ICdUSUxERSc7IC8vIH5cbmNvbnN0IFVOREVSU0NPUkUgPSAnVU5ERVJTQ09SRSc7IC8vIF9cblxuLy8gRW1vamkgc3ltYm9sXG5jb25zdCBFTU9KSSQxID0gJ0VNT0pJJztcblxuLy8gRGVmYXVsdCB0b2tlbiAtIGFueXRoaW5nIHRoYXQgaXMgbm90IG9uZSBvZiB0aGUgYWJvdmVcbmNvbnN0IFNZTSA9ICdTWU0nO1xuXG52YXIgdGsgPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7XG5cdF9fcHJvdG9fXzogbnVsbCxcblx0QUxQSEFOVU1FUklDQUw6IEFMUEhBTlVNRVJJQ0FMLFxuXHRBTVBFUlNBTkQ6IEFNUEVSU0FORCxcblx0QVBPU1RST1BIRTogQVBPU1RST1BIRSxcblx0QVNDSUlOVU1FUklDQUw6IEFTQ0lJTlVNRVJJQ0FMLFxuXHRBU1RFUklTSzogQVNURVJJU0ssXG5cdEFUOiBBVCxcblx0QkFDS1NMQVNIOiBCQUNLU0xBU0gsXG5cdEJBQ0tUSUNLOiBCQUNLVElDSyxcblx0Q0FSRVQ6IENBUkVULFxuXHRDTE9TRUFOR0xFQlJBQ0tFVDogQ0xPU0VBTkdMRUJSQUNLRVQsXG5cdENMT1NFQlJBQ0U6IENMT1NFQlJBQ0UsXG5cdENMT1NFQlJBQ0tFVDogQ0xPU0VCUkFDS0VULFxuXHRDTE9TRVBBUkVOOiBDTE9TRVBBUkVOLFxuXHRDT0xPTjogQ09MT04sXG5cdENPTU1BOiBDT01NQSxcblx0RE9MTEFSOiBET0xMQVIsXG5cdERPVDogRE9ULFxuXHRFTU9KSTogRU1PSkkkMSxcblx0RVFVQUxTOiBFUVVBTFMsXG5cdEVYQ0xBTUFUSU9OOiBFWENMQU1BVElPTixcblx0RlVMTFdJRFRIR1JFQVRFUlRIQU46IEZVTExXSURUSEdSRUFURVJUSEFOLFxuXHRGVUxMV0lEVEhMRUZUUEFSRU46IEZVTExXSURUSExFRlRQQVJFTixcblx0RlVMTFdJRFRITEVTU1RIQU46IEZVTExXSURUSExFU1NUSEFOLFxuXHRGVUxMV0lEVEhNSURETEVET1Q6IEZVTExXSURUSE1JRERMRURPVCxcblx0RlVMTFdJRFRIUklHSFRQQVJFTjogRlVMTFdJRFRIUklHSFRQQVJFTixcblx0SFlQSEVOOiBIWVBIRU4sXG5cdExFRlRDT1JORVJCUkFDS0VUOiBMRUZUQ09STkVSQlJBQ0tFVCxcblx0TEVGVFdISVRFQ09STkVSQlJBQ0tFVDogTEVGVFdISVRFQ09STkVSQlJBQ0tFVCxcblx0TE9DQUxIT1NUOiBMT0NBTEhPU1QsXG5cdE5MOiBOTCxcblx0TlVNOiBOVU0sXG5cdE9QRU5BTkdMRUJSQUNLRVQ6IE9QRU5BTkdMRUJSQUNLRVQsXG5cdE9QRU5CUkFDRTogT1BFTkJSQUNFLFxuXHRPUEVOQlJBQ0tFVDogT1BFTkJSQUNLRVQsXG5cdE9QRU5QQVJFTjogT1BFTlBBUkVOLFxuXHRQRVJDRU5UOiBQRVJDRU5ULFxuXHRQSVBFOiBQSVBFLFxuXHRQTFVTOiBQTFVTLFxuXHRQT1VORDogUE9VTkQsXG5cdFFVRVJZOiBRVUVSWSxcblx0UVVPVEU6IFFVT1RFLFxuXHRSSUdIVENPUk5FUkJSQUNLRVQ6IFJJR0hUQ09STkVSQlJBQ0tFVCxcblx0UklHSFRXSElURUNPUk5FUkJSQUNLRVQ6IFJJR0hUV0hJVEVDT1JORVJCUkFDS0VULFxuXHRTQ0hFTUU6IFNDSEVNRSxcblx0U0VNSTogU0VNSSxcblx0U0xBU0g6IFNMQVNILFxuXHRTTEFTSF9TQ0hFTUU6IFNMQVNIX1NDSEVNRSxcblx0U1lNOiBTWU0sXG5cdFRJTERFOiBUSUxERSxcblx0VExEOiBUTEQsXG5cdFVOREVSU0NPUkU6IFVOREVSU0NPUkUsXG5cdFVUTEQ6IFVUTEQsXG5cdFVXT1JEOiBVV09SRCxcblx0V09SRDogV09SRCxcblx0V1M6IFdTXG59KTtcblxuLy8gTm90ZSB0aGF0IHRoZXNlIHR3byBVbmljb2RlIG9uZXMgZXhwYW5kIGludG8gYSByZWFsbHkgYmlnIG9uZSB3aXRoIEJhYmVsXG5jb25zdCBBU0NJSV9MRVRURVIgPSAvW2Etel0vO1xuY29uc3QgTEVUVEVSID0gL1xccHtMfS91OyAvLyBBbnkgVW5pY29kZSBjaGFyYWN0ZXIgd2l0aCBsZXR0ZXIgZGF0YSB0eXBlXG5jb25zdCBFTU9KSSA9IC9cXHB7RW1vaml9L3U7IC8vIEFueSBVbmljb2RlIGVtb2ppIGNoYXJhY3RlclxuY29uc3QgRU1PSklfVkFSSUFUSU9OJDEgPSAvXFx1ZmUwZi87XG5jb25zdCBESUdJVCA9IC9cXGQvO1xuY29uc3QgU1BBQ0UgPSAvXFxzLztcblxudmFyIHJlZ2V4cCA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcblx0X19wcm90b19fOiBudWxsLFxuXHRBU0NJSV9MRVRURVI6IEFTQ0lJX0xFVFRFUixcblx0RElHSVQ6IERJR0lULFxuXHRFTU9KSTogRU1PSkksXG5cdEVNT0pJX1ZBUklBVElPTjogRU1PSklfVkFSSUFUSU9OJDEsXG5cdExFVFRFUjogTEVUVEVSLFxuXHRTUEFDRTogU1BBQ0Vcbn0pO1xuXG4vKipcblx0VGhlIHNjYW5uZXIgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRoYXQgdGFrZXMgYSBzdHJpbmcgb2YgdGV4dCBhcyBpbnB1dCwgYW5kXG5cdG91dHB1dHMgYW4gYXJyYXkgb2YgdG9rZW5zIGluc3RhbmNlcyB0aGF0IGNhbiBiZSB1c2VkIGZvciBlYXN5IFVSTCBwYXJzaW5nLlxuKi9cblxuY29uc3QgQ1IgPSAnXFxyJzsgLy8gY2FycmlhZ2UtcmV0dXJuIGNoYXJhY3RlclxuY29uc3QgTEYgPSAnXFxuJzsgLy8gbGluZS1mZWVkIGNoYXJhY3RlclxuY29uc3QgRU1PSklfVkFSSUFUSU9OID0gJ1xcdWZlMGYnOyAvLyBWYXJpYXRpb24gc2VsZWN0b3IsIGZvbGxvd3MgaGVhcnQgYW5kIG90aGVyc1xuY29uc3QgRU1PSklfSk9JTkVSID0gJ1xcdTIwMGQnOyAvLyB6ZXJvLXdpZHRoIGpvaW5lclxuY29uc3QgT0JKRUNUX1JFUExBQ0VNRU5UID0gJ1xcdWZmZmMnOyAvLyB3aGl0ZXNwYWNlIHBsYWNlaG9sZGVyIHRoYXQgc29tZXRpbWVzIGFwcGVhcnMgaW4gcmljaCB0ZXh0IGVkaXRvcnNcblxubGV0IHRsZHMgPSBudWxsLFxuICB1dGxkcyA9IG51bGw7IC8vIGRvbid0IGNoYW5nZSBzbyBvbmx5IGhhdmUgdG8gYmUgY29tcHV0ZWQgb25jZVxuXG4vKipcbiAqIFNjYW5uZXIgb3V0cHV0IHRva2VuOlxuICogLSBgdGAgaXMgdGhlIHRva2VuIG5hbWUgKGUuZy4sICdOVU0nLCAnRU1PSkknLCAnVExEJylcbiAqIC0gYHZgIGlzIHRoZSB2YWx1ZSBvZiB0aGUgdG9rZW4gKGUuZy4sICcxMjMnLCAnXHUyNzY0XHVGRTBGJywgJ2NvbScpXG4gKiAtIGBzYCBpcyB0aGUgc3RhcnQgaW5kZXggb2YgdGhlIHRva2VuIGluIHRoZSBvcmlnaW5hbCBzdHJpbmdcbiAqIC0gYGVgIGlzIHRoZSBlbmQgaW5kZXggb2YgdGhlIHRva2VuIGluIHRoZSBvcmlnaW5hbCBzdHJpbmdcbiAqIEB0eXBlZGVmIHt7dDogc3RyaW5nLCB2OiBzdHJpbmcsIHM6IG51bWJlciwgZTogbnVtYmVyfX0gVG9rZW5cbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZWRlZiB7eyBbY29sbGVjdGlvbjogc3RyaW5nXTogVFtdIH19IENvbGxlY3Rpb25zXG4gKi9cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBzY2FubmVyIGNoYXJhY3Rlci1iYXNlZCBzdGF0ZSBtYWNoaW5lIGZvciB0aGUgZ2l2ZW4gc3RhcnRcbiAqIHN0YXRlXG4gKiBAcGFyYW0ge1tzdHJpbmcsIGJvb2xlYW5dW119IGN1c3RvbVNjaGVtZXMgTGlzdCBvZiBjdXN0b20gc2NoZW1lcywgd2hlcmUgZWFjaFxuICogaXRlbSBpcyBhIGxlbmd0aC0yIHR1cGxlIHdpdGggdGhlIGZpcnN0IGVsZW1lbnQgc2V0IHRvIHRoZSBzdHJpbmcgc2NoZW1lLCBhbmRcbiAqIHRoZSBzZWNvbmQgZWxlbWVudCBzZXQgdG8gYHRydWVgIGlmIHRoZSBgOi8vYCBhZnRlciB0aGUgc2NoZW1lIGlzIG9wdGlvbmFsXG4gKi9cbmZ1bmN0aW9uIGluaXQkMihjdXN0b21TY2hlbWVzID0gW10pIHtcbiAgLy8gRnJlcXVlbnRseSB1c2VkIHN0YXRlcyAobmFtZSBhcmd1bWVudCByZW1vdmVkIGR1cmluZyBtaW5pZmljYXRpb24pXG4gIC8qKiBAdHlwZSBDb2xsZWN0aW9uczxzdHJpbmc+ICovXG4gIGNvbnN0IGdyb3VwcyA9IHt9OyAvLyBvZiB0b2tlbnNcbiAgU3RhdGUuZ3JvdXBzID0gZ3JvdXBzO1xuICAvKiogQHR5cGUgU3RhdGU8c3RyaW5nPiAqL1xuICBjb25zdCBTdGFydCA9IG5ldyBTdGF0ZSgpO1xuICBpZiAodGxkcyA9PSBudWxsKSB7XG4gICAgdGxkcyA9IGRlY29kZVRsZHMoZW5jb2RlZFRsZHMpO1xuICB9XG4gIGlmICh1dGxkcyA9PSBudWxsKSB7XG4gICAgdXRsZHMgPSBkZWNvZGVUbGRzKGVuY29kZWRVdGxkcyk7XG4gIH1cblxuICAvLyBTdGF0ZXMgZm9yIHNwZWNpYWwgVVJMIHN5bWJvbHMgdGhhdCBhY2NlcHQgaW1tZWRpYXRlbHkgYWZ0ZXIgc3RhcnRcbiAgdHQoU3RhcnQsIFwiJ1wiLCBBUE9TVFJPUEhFKTtcbiAgdHQoU3RhcnQsICd7JywgT1BFTkJSQUNFKTtcbiAgdHQoU3RhcnQsICd9JywgQ0xPU0VCUkFDRSk7XG4gIHR0KFN0YXJ0LCAnWycsIE9QRU5CUkFDS0VUKTtcbiAgdHQoU3RhcnQsICddJywgQ0xPU0VCUkFDS0VUKTtcbiAgdHQoU3RhcnQsICcoJywgT1BFTlBBUkVOKTtcbiAgdHQoU3RhcnQsICcpJywgQ0xPU0VQQVJFTik7XG4gIHR0KFN0YXJ0LCAnPCcsIE9QRU5BTkdMRUJSQUNLRVQpO1xuICB0dChTdGFydCwgJz4nLCBDTE9TRUFOR0xFQlJBQ0tFVCk7XG4gIHR0KFN0YXJ0LCAnXHVGRjA4JywgRlVMTFdJRFRITEVGVFBBUkVOKTtcbiAgdHQoU3RhcnQsICdcdUZGMDknLCBGVUxMV0lEVEhSSUdIVFBBUkVOKTtcbiAgdHQoU3RhcnQsICdcdTMwMEMnLCBMRUZUQ09STkVSQlJBQ0tFVCk7XG4gIHR0KFN0YXJ0LCAnXHUzMDBEJywgUklHSFRDT1JORVJCUkFDS0VUKTtcbiAgdHQoU3RhcnQsICdcdTMwMEUnLCBMRUZUV0hJVEVDT1JORVJCUkFDS0VUKTtcbiAgdHQoU3RhcnQsICdcdTMwMEYnLCBSSUdIVFdISVRFQ09STkVSQlJBQ0tFVCk7XG4gIHR0KFN0YXJ0LCAnXHVGRjFDJywgRlVMTFdJRFRITEVTU1RIQU4pO1xuICB0dChTdGFydCwgJ1x1RkYxRScsIEZVTExXSURUSEdSRUFURVJUSEFOKTtcbiAgdHQoU3RhcnQsICcmJywgQU1QRVJTQU5EKTtcbiAgdHQoU3RhcnQsICcqJywgQVNURVJJU0spO1xuICB0dChTdGFydCwgJ0AnLCBBVCk7XG4gIHR0KFN0YXJ0LCAnYCcsIEJBQ0tUSUNLKTtcbiAgdHQoU3RhcnQsICdeJywgQ0FSRVQpO1xuICB0dChTdGFydCwgJzonLCBDT0xPTik7XG4gIHR0KFN0YXJ0LCAnLCcsIENPTU1BKTtcbiAgdHQoU3RhcnQsICckJywgRE9MTEFSKTtcbiAgdHQoU3RhcnQsICcuJywgRE9UKTtcbiAgdHQoU3RhcnQsICc9JywgRVFVQUxTKTtcbiAgdHQoU3RhcnQsICchJywgRVhDTEFNQVRJT04pO1xuICB0dChTdGFydCwgJy0nLCBIWVBIRU4pO1xuICB0dChTdGFydCwgJyUnLCBQRVJDRU5UKTtcbiAgdHQoU3RhcnQsICd8JywgUElQRSk7XG4gIHR0KFN0YXJ0LCAnKycsIFBMVVMpO1xuICB0dChTdGFydCwgJyMnLCBQT1VORCk7XG4gIHR0KFN0YXJ0LCAnPycsIFFVRVJZKTtcbiAgdHQoU3RhcnQsICdcIicsIFFVT1RFKTtcbiAgdHQoU3RhcnQsICcvJywgU0xBU0gpO1xuICB0dChTdGFydCwgJzsnLCBTRU1JKTtcbiAgdHQoU3RhcnQsICd+JywgVElMREUpO1xuICB0dChTdGFydCwgJ18nLCBVTkRFUlNDT1JFKTtcbiAgdHQoU3RhcnQsICdcXFxcJywgQkFDS1NMQVNIKTtcbiAgdHQoU3RhcnQsICdcdTMwRkInLCBGVUxMV0lEVEhNSURETEVET1QpO1xuICBjb25zdCBOdW0gPSB0cihTdGFydCwgRElHSVQsIE5VTSwge1xuICAgIFtudW1lcmljXTogdHJ1ZVxuICB9KTtcbiAgdHIoTnVtLCBESUdJVCwgTnVtKTtcbiAgY29uc3QgQXNjaWludW1lcmljID0gdHIoTnVtLCBBU0NJSV9MRVRURVIsIEFTQ0lJTlVNRVJJQ0FMLCB7XG4gICAgW2FzY2lpbnVtZXJpY106IHRydWVcbiAgfSk7XG4gIGNvbnN0IEFscGhhbnVtZXJpYyA9IHRyKE51bSwgTEVUVEVSLCBBTFBIQU5VTUVSSUNBTCwge1xuICAgIFthbHBoYW51bWVyaWNdOiB0cnVlXG4gIH0pO1xuXG4gIC8vIFN0YXRlIHdoaWNoIGVtaXRzIGEgd29yZCB0b2tlblxuICBjb25zdCBXb3JkID0gdHIoU3RhcnQsIEFTQ0lJX0xFVFRFUiwgV09SRCwge1xuICAgIFthc2NpaV06IHRydWVcbiAgfSk7XG4gIHRyKFdvcmQsIERJR0lULCBBc2NpaW51bWVyaWMpO1xuICB0cihXb3JkLCBBU0NJSV9MRVRURVIsIFdvcmQpO1xuICB0cihBc2NpaW51bWVyaWMsIERJR0lULCBBc2NpaW51bWVyaWMpO1xuICB0cihBc2NpaW51bWVyaWMsIEFTQ0lJX0xFVFRFUiwgQXNjaWludW1lcmljKTtcblxuICAvLyBTYW1lIGFzIHByZXZpb3VzLCBidXQgc3BlY2lmaWMgdG8gbm9uLWZzbS5hc2NpaSBhbHBoYWJldCB3b3Jkc1xuICBjb25zdCBVV29yZCA9IHRyKFN0YXJ0LCBMRVRURVIsIFVXT1JELCB7XG4gICAgW2FscGhhXTogdHJ1ZVxuICB9KTtcbiAgdHIoVVdvcmQsIEFTQ0lJX0xFVFRFUik7IC8vIE5vbi1hY2NlcHRpbmdcbiAgdHIoVVdvcmQsIERJR0lULCBBbHBoYW51bWVyaWMpO1xuICB0cihVV29yZCwgTEVUVEVSLCBVV29yZCk7XG4gIHRyKEFscGhhbnVtZXJpYywgRElHSVQsIEFscGhhbnVtZXJpYyk7XG4gIHRyKEFscGhhbnVtZXJpYywgQVNDSUlfTEVUVEVSKTsgLy8gTm9uLWFjY2VwdGluZ1xuICB0cihBbHBoYW51bWVyaWMsIExFVFRFUiwgQWxwaGFudW1lcmljKTsgLy8gTm9uLWFjY2VwdGluZ1xuXG4gIC8vIFdoaXRlc3BhY2UganVtcHNcbiAgLy8gVG9rZW5zIG9mIG9ubHkgbm9uLW5ld2xpbmUgd2hpdGVzcGFjZSBhcmUgYXJiaXRyYXJpbHkgbG9uZ1xuICAvLyBJZiBhbnkgd2hpdGVzcGFjZSBleGNlcHQgbmV3bGluZSwgbW9yZSB3aGl0ZXNwYWNlIVxuICBjb25zdCBObCA9IHR0KFN0YXJ0LCBMRiwgTkwsIHtcbiAgICBbd2hpdGVzcGFjZV06IHRydWVcbiAgfSk7XG4gIGNvbnN0IENyID0gdHQoU3RhcnQsIENSLCBXUywge1xuICAgIFt3aGl0ZXNwYWNlXTogdHJ1ZVxuICB9KTtcbiAgY29uc3QgV3MgPSB0cihTdGFydCwgU1BBQ0UsIFdTLCB7XG4gICAgW3doaXRlc3BhY2VdOiB0cnVlXG4gIH0pO1xuICB0dChTdGFydCwgT0JKRUNUX1JFUExBQ0VNRU5ULCBXcyk7XG4gIHR0KENyLCBMRiwgTmwpOyAvLyBcXHJcXG5cbiAgdHQoQ3IsIE9CSkVDVF9SRVBMQUNFTUVOVCwgV3MpO1xuICB0cihDciwgU1BBQ0UsIFdzKTtcbiAgdHQoV3MsIENSKTsgLy8gbm9uLWFjY2VwdGluZyBzdGF0ZSB0byBhdm9pZCBtaXhpbmcgd2hpdGVzcGFjZXNcbiAgdHQoV3MsIExGKTsgLy8gbm9uLWFjY2VwdGluZyBzdGF0ZSB0byBhdm9pZCBtaXhpbmcgd2hpdGVzcGFjZXNcbiAgdHIoV3MsIFNQQUNFLCBXcyk7XG4gIHR0KFdzLCBPQkpFQ1RfUkVQTEFDRU1FTlQsIFdzKTtcblxuICAvLyBFbW9qaSB0b2tlbnMuIFRoZXkgYXJlIG5vdCBncm91cGVkIGJ5IHRoZSBzY2FubmVyIGV4Y2VwdCBpbiBjYXNlcyB3aGVyZSBhXG4gIC8vIHplcm8td2lkdGggam9pbmVyIGlzIHByZXNlbnRcbiAgY29uc3QgRW1vamkgPSB0cihTdGFydCwgRU1PSkksIEVNT0pJJDEsIHtcbiAgICBbZW1vamldOiB0cnVlXG4gIH0pO1xuICB0dChFbW9qaSwgJyMnKTsgLy8gbm8gdHJhbnNpdGlvbiwgZW1vamkgcmVnZXggc2VlbXMgdG8gbWF0Y2ggI1xuICB0cihFbW9qaSwgRU1PSkksIEVtb2ppKTtcbiAgdHQoRW1vamksIEVNT0pJX1ZBUklBVElPTiwgRW1vamkpO1xuICAvLyB0dChTdGFydCwgRU1PSklfVkFSSUFUSU9OLCBFbW9qaSk7IC8vIFRoaXMgb25lIGlzIHNrZXRjaHlcblxuICBjb25zdCBFbW9qaUpvaW5lciA9IHR0KEVtb2ppLCBFTU9KSV9KT0lORVIpO1xuICB0dChFbW9qaUpvaW5lciwgJyMnKTtcbiAgdHIoRW1vamlKb2luZXIsIEVNT0pJLCBFbW9qaSk7XG4gIC8vIHR0KEVtb2ppSm9pbmVyLCBFTU9KSV9WQVJJQVRJT04sIEVtb2ppKTsgLy8gYWxzbyBza2V0Y2h5XG5cbiAgLy8gR2VuZXJhdGVzIHN0YXRlcyBmb3IgdG9wLWxldmVsIGRvbWFpbnNcbiAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgbW9zdCBhY2N1cmF0ZSB3aGVuIHRsZHMgYXJlIGluIGFscGhhYmV0aWNhbCBvcmRlclxuICBjb25zdCB3b3JkanIgPSBbW0FTQ0lJX0xFVFRFUiwgV29yZF0sIFtESUdJVCwgQXNjaWludW1lcmljXV07XG4gIGNvbnN0IHV3b3JkanIgPSBbW0FTQ0lJX0xFVFRFUiwgbnVsbF0sIFtMRVRURVIsIFVXb3JkXSwgW0RJR0lULCBBbHBoYW51bWVyaWNdXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0bGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgZmFzdHRzKFN0YXJ0LCB0bGRzW2ldLCBUTEQsIFdPUkQsIHdvcmRqcik7XG4gIH1cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB1dGxkcy5sZW5ndGg7IGkrKykge1xuICAgIGZhc3R0cyhTdGFydCwgdXRsZHNbaV0sIFVUTEQsIFVXT1JELCB1d29yZGpyKTtcbiAgfVxuICBhZGRUb0dyb3VwcyhUTEQsIHtcbiAgICB0bGQ6IHRydWUsXG4gICAgYXNjaWk6IHRydWVcbiAgfSwgZ3JvdXBzKTtcbiAgYWRkVG9Hcm91cHMoVVRMRCwge1xuICAgIHV0bGQ6IHRydWUsXG4gICAgYWxwaGE6IHRydWVcbiAgfSwgZ3JvdXBzKTtcblxuICAvLyBDb2xsZWN0IHRoZSBzdGF0ZXMgZ2VuZXJhdGVkIGJ5IGRpZmZlcmVudCBwcm90b2NvbHMuIE5PVEU6IElmIGFueSBuZXcgVExEc1xuICAvLyBnZXQgYWRkZWQgdGhhdCBhcmUgYWxzbyBwcm90b2NvbHMsIHNldCB0aGUgdG9rZW4gdG8gYmUgdGhlIHNhbWUgYXMgdGhlXG4gIC8vIHByb3RvY29sIHRvIGVuc3VyZSBwYXJzaW5nIHdvcmtzIGFzIGV4cGVjdGVkLlxuICBmYXN0dHMoU3RhcnQsICdmaWxlJywgU0NIRU1FLCBXT1JELCB3b3JkanIpO1xuICBmYXN0dHMoU3RhcnQsICdtYWlsdG8nLCBTQ0hFTUUsIFdPUkQsIHdvcmRqcik7XG4gIGZhc3R0cyhTdGFydCwgJ2h0dHAnLCBTTEFTSF9TQ0hFTUUsIFdPUkQsIHdvcmRqcik7XG4gIGZhc3R0cyhTdGFydCwgJ2h0dHBzJywgU0xBU0hfU0NIRU1FLCBXT1JELCB3b3JkanIpO1xuICBmYXN0dHMoU3RhcnQsICdmdHAnLCBTTEFTSF9TQ0hFTUUsIFdPUkQsIHdvcmRqcik7XG4gIGZhc3R0cyhTdGFydCwgJ2Z0cHMnLCBTTEFTSF9TQ0hFTUUsIFdPUkQsIHdvcmRqcik7XG4gIGFkZFRvR3JvdXBzKFNDSEVNRSwge1xuICAgIHNjaGVtZTogdHJ1ZSxcbiAgICBhc2NpaTogdHJ1ZVxuICB9LCBncm91cHMpO1xuICBhZGRUb0dyb3VwcyhTTEFTSF9TQ0hFTUUsIHtcbiAgICBzbGFzaHNjaGVtZTogdHJ1ZSxcbiAgICBhc2NpaTogdHJ1ZVxuICB9LCBncm91cHMpO1xuXG4gIC8vIFJlZ2lzdGVyIGN1c3RvbSBzY2hlbWVzLiBBc3N1bWVzIGVhY2ggc2NoZW1lIGlzIGFzY2lpbnVtZXJpYyB3aXRoIGh5cGhlbnNcbiAgY3VzdG9tU2NoZW1lcyA9IGN1c3RvbVNjaGVtZXMuc29ydCgoYSwgYikgPT4gYVswXSA+IGJbMF0gPyAxIDogLTEpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGN1c3RvbVNjaGVtZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzY2ggPSBjdXN0b21TY2hlbWVzW2ldWzBdO1xuICAgIGNvbnN0IG9wdGlvbmFsU2xhc2hTbGFzaCA9IGN1c3RvbVNjaGVtZXNbaV1bMV07XG4gICAgY29uc3QgZmxhZ3MgPSBvcHRpb25hbFNsYXNoU2xhc2ggPyB7XG4gICAgICBbc2NoZW1lXTogdHJ1ZVxuICAgIH0gOiB7XG4gICAgICBbc2xhc2hzY2hlbWVdOiB0cnVlXG4gICAgfTtcbiAgICBpZiAoc2NoLmluZGV4T2YoJy0nKSA+PSAwKSB7XG4gICAgICBmbGFnc1tkb21haW5dID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCFBU0NJSV9MRVRURVIudGVzdChzY2gpKSB7XG4gICAgICBmbGFnc1tudW1lcmljXSA9IHRydWU7IC8vIG51bWJlcnMgb25seVxuICAgIH0gZWxzZSBpZiAoRElHSVQudGVzdChzY2gpKSB7XG4gICAgICBmbGFnc1thc2NpaW51bWVyaWNdID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhZ3NbYXNjaWldID0gdHJ1ZTtcbiAgICB9XG4gICAgdHMoU3RhcnQsIHNjaCwgc2NoLCBmbGFncyk7XG4gIH1cblxuICAvLyBMb2NhbGhvc3QgdG9rZW5cbiAgdHMoU3RhcnQsICdsb2NhbGhvc3QnLCBMT0NBTEhPU1QsIHtcbiAgICBhc2NpaTogdHJ1ZVxuICB9KTtcblxuICAvLyBTZXQgZGVmYXVsdCB0cmFuc2l0aW9uIGZvciBzdGFydCBzdGF0ZSAoc29tZSBzeW1ib2wpXG4gIFN0YXJ0LmpkID0gbmV3IFN0YXRlKFNZTSk7XG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IFN0YXJ0LFxuICAgIHRva2VuczogT2JqZWN0LmFzc2lnbih7XG4gICAgICBncm91cHNcbiAgICB9LCB0aylcbiAgfTtcbn1cblxuLyoqXG5cdEdpdmVuIGEgc3RyaW5nLCByZXR1cm5zIGFuIGFycmF5IG9mIFRPS0VOIGluc3RhbmNlcyByZXByZXNlbnRpbmcgdGhlXG5cdGNvbXBvc2l0aW9uIG9mIHRoYXQgc3RyaW5nLlxuXG5cdEBtZXRob2QgcnVuXG5cdEBwYXJhbSB7U3RhdGU8c3RyaW5nPn0gc3RhcnQgc2Nhbm5lciBzdGFydGluZyBzdGF0ZVxuXHRAcGFyYW0ge3N0cmluZ30gc3RyIGlucHV0IHN0cmluZyB0byBzY2FuXG5cdEByZXR1cm4ge1Rva2VuW119IGxpc3Qgb2YgdG9rZW5zLCBlYWNoIHdpdGggYSB0eXBlIGFuZCB2YWx1ZVxuKi9cbmZ1bmN0aW9uIHJ1biQxKHN0YXJ0LCBzdHIpIHtcbiAgLy8gU3RhdGUgbWFjaGluZSBpcyBub3QgY2FzZSBzZW5zaXRpdmUsIHNvIGlucHV0IGlzIHRva2VuaXplZCBpbiBsb3dlcmNhc2VkXG4gIC8vIGZvcm0gKHN0aWxsIHJldHVybnMgcmVndWxhciBjYXNlKS4gVXNlcyBzZWxlY3RpdmUgYHRvTG93ZXJDYXNlYCBiZWNhdXNlXG4gIC8vIGxvd2VyY2FzaW5nIHRoZSBlbnRpcmUgc3RyaW5nIGNhdXNlcyB0aGUgbGVuZ3RoIGFuZCBjaGFyYWN0ZXIgcG9zaXRpb24gdG9cbiAgLy8gdmFyeSBpbiBzb21lIG5vbi1FbmdsaXNoIHN0cmluZ3Mgd2l0aCBWOC1iYXNlZCBydW50aW1lcy5cbiAgY29uc3QgaXRlcmFibGUgPSBzdHJpbmdUb0FycmF5KHN0ci5yZXBsYWNlKC9bQS1aXS9nLCBjID0+IGMudG9Mb3dlckNhc2UoKSkpO1xuICBjb25zdCBjaGFyQ291bnQgPSBpdGVyYWJsZS5sZW5ndGg7IC8vIDw9IGxlbiBpZiB0aGVyZSBhcmUgZW1vamlzLCBldGNcbiAgY29uc3QgdG9rZW5zID0gW107IC8vIHJldHVybiB2YWx1ZVxuXG4gIC8vIGN1cnNvciB0aHJvdWdoIHRoZSBzdHJpbmcgaXRzZWxmLCBhY2NvdW50aW5nIGZvciBjaGFyYWN0ZXJzIHRoYXQgaGF2ZVxuICAvLyB3aWR0aCB3aXRoIGxlbmd0aCAyIHN1Y2ggYXMgZW1vamlzXG4gIGxldCBjdXJzb3IgPSAwO1xuXG4gIC8vIEN1cnNvciB0aHJvdWdoIHRoZSBhcnJheS1yZXByZXNlbnRhdGlvbiBvZiB0aGUgc3RyaW5nXG4gIGxldCBjaGFyQ3Vyc29yID0gMDtcblxuICAvLyBUb2tlbml6ZSB0aGUgc3RyaW5nXG4gIHdoaWxlIChjaGFyQ3Vyc29yIDwgY2hhckNvdW50KSB7XG4gICAgbGV0IHN0YXRlID0gc3RhcnQ7XG4gICAgbGV0IG5leHRTdGF0ZSA9IG51bGw7XG4gICAgbGV0IHRva2VuTGVuZ3RoID0gMDtcbiAgICBsZXQgbGF0ZXN0QWNjZXB0aW5nID0gbnVsbDtcbiAgICBsZXQgc2luY2VBY2NlcHRzID0gLTE7XG4gICAgbGV0IGNoYXJzU2luY2VBY2NlcHRzID0gLTE7XG4gICAgd2hpbGUgKGNoYXJDdXJzb3IgPCBjaGFyQ291bnQgJiYgKG5leHRTdGF0ZSA9IHN0YXRlLmdvKGl0ZXJhYmxlW2NoYXJDdXJzb3JdKSkpIHtcbiAgICAgIHN0YXRlID0gbmV4dFN0YXRlO1xuXG4gICAgICAvLyBLZWVwIHRyYWNrIG9mIHRoZSBsYXRlc3QgYWNjZXB0aW5nIHN0YXRlXG4gICAgICBpZiAoc3RhdGUuYWNjZXB0cygpKSB7XG4gICAgICAgIHNpbmNlQWNjZXB0cyA9IDA7XG4gICAgICAgIGNoYXJzU2luY2VBY2NlcHRzID0gMDtcbiAgICAgICAgbGF0ZXN0QWNjZXB0aW5nID0gc3RhdGU7XG4gICAgICB9IGVsc2UgaWYgKHNpbmNlQWNjZXB0cyA+PSAwKSB7XG4gICAgICAgIHNpbmNlQWNjZXB0cyArPSBpdGVyYWJsZVtjaGFyQ3Vyc29yXS5sZW5ndGg7XG4gICAgICAgIGNoYXJzU2luY2VBY2NlcHRzKys7XG4gICAgICB9XG4gICAgICB0b2tlbkxlbmd0aCArPSBpdGVyYWJsZVtjaGFyQ3Vyc29yXS5sZW5ndGg7XG4gICAgICBjdXJzb3IgKz0gaXRlcmFibGVbY2hhckN1cnNvcl0ubGVuZ3RoO1xuICAgICAgY2hhckN1cnNvcisrO1xuICAgIH1cblxuICAgIC8vIFJvbGwgYmFjayB0byB0aGUgbGF0ZXN0IGFjY2VwdGluZyBzdGF0ZVxuICAgIGN1cnNvciAtPSBzaW5jZUFjY2VwdHM7XG4gICAgY2hhckN1cnNvciAtPSBjaGFyc1NpbmNlQWNjZXB0cztcbiAgICB0b2tlbkxlbmd0aCAtPSBzaW5jZUFjY2VwdHM7XG5cbiAgICAvLyBObyBtb3JlIGp1bXBzLCBqdXN0IG1ha2UgYSBuZXcgdG9rZW4gZnJvbSB0aGUgbGFzdCBhY2NlcHRpbmcgb25lXG4gICAgdG9rZW5zLnB1c2goe1xuICAgICAgdDogbGF0ZXN0QWNjZXB0aW5nLnQsXG4gICAgICAvLyB0b2tlbiB0eXBlL25hbWVcbiAgICAgIHY6IHN0ci5zbGljZShjdXJzb3IgLSB0b2tlbkxlbmd0aCwgY3Vyc29yKSxcbiAgICAgIC8vIHN0cmluZyB2YWx1ZVxuICAgICAgczogY3Vyc29yIC0gdG9rZW5MZW5ndGgsXG4gICAgICAvLyBzdGFydCBpbmRleFxuICAgICAgZTogY3Vyc29yIC8vIGVuZCBpbmRleCAoZXhjbHVkaW5nKVxuICAgIH0pO1xuICB9XG4gIHJldHVybiB0b2tlbnM7XG59XG5cbi8qKlxuICogQ29udmVydCBhIFN0cmluZyB0byBhbiBBcnJheSBvZiBjaGFyYWN0ZXJzLCB0YWtpbmcgaW50byBhY2NvdW50IHRoYXQgc29tZVxuICogY2hhcmFjdGVycyBsaWtlIGVtb2ppcyB0YWtlIHVwIHR3byBzdHJpbmcgaW5kZXhlcy5cbiAqXG4gKiBBZGFwdGVkIGZyb20gY29yZS1qcyAoTUlUIGxpY2Vuc2UpXG4gKiBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9ibG9iLzJkNjljZjVmOTlhYjNlYTM0NjNjMzk1ZGY4MWU1YTE1YjY4ZjQ5ZDkvcGFja2FnZXMvY29yZS1qcy9pbnRlcm5hbHMvc3RyaW5nLW11bHRpYnl0ZS5qc1xuICpcbiAqIEBmdW5jdGlvbiBzdHJpbmdUb0FycmF5XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcmV0dXJucyB7c3RyaW5nW119XG4gKi9cbmZ1bmN0aW9uIHN0cmluZ1RvQXJyYXkoc3RyKSB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBsZW4gPSBzdHIubGVuZ3RoO1xuICBsZXQgaW5kZXggPSAwO1xuICB3aGlsZSAoaW5kZXggPCBsZW4pIHtcbiAgICBsZXQgZmlyc3QgPSBzdHIuY2hhckNvZGVBdChpbmRleCk7XG4gICAgbGV0IHNlY29uZDtcbiAgICBsZXQgY2hhciA9IGZpcnN0IDwgMHhkODAwIHx8IGZpcnN0ID4gMHhkYmZmIHx8IGluZGV4ICsgMSA9PT0gbGVuIHx8IChzZWNvbmQgPSBzdHIuY2hhckNvZGVBdChpbmRleCArIDEpKSA8IDB4ZGMwMCB8fCBzZWNvbmQgPiAweGRmZmYgPyBzdHJbaW5kZXhdIC8vIHNpbmdsZSBjaGFyYWN0ZXJcbiAgICA6IHN0ci5zbGljZShpbmRleCwgaW5kZXggKyAyKTsgLy8gdHdvLWluZGV4IGNoYXJhY3RlcnNcbiAgICByZXN1bHQucHVzaChjaGFyKTtcbiAgICBpbmRleCArPSBjaGFyLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEZhc3QgdmVyc2lvbiBvZiB0cyBmdW5jdGlvbiBmb3Igd2hlbiB0cmFuc2l0aW9uIGRlZmF1bHRzIGFyZSB3ZWxsIGtub3duXG4gKiBAcGFyYW0ge1N0YXRlPHN0cmluZz59IHN0YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXRcbiAqIEBwYXJhbSB7c3RyaW5nfSB0XG4gKiBAcGFyYW0ge3N0cmluZ30gZGVmYXVsdHRcbiAqIEBwYXJhbSB7W1JlZ0V4cCwgU3RhdGU8c3RyaW5nPl1bXX0ganJcbiAqIEByZXR1cm5zIHtTdGF0ZTxzdHJpbmc+fVxuICovXG5mdW5jdGlvbiBmYXN0dHMoc3RhdGUsIGlucHV0LCB0LCBkZWZhdWx0dCwganIpIHtcbiAgbGV0IG5leHQ7XG4gIGNvbnN0IGxlbiA9IGlucHV0Lmxlbmd0aDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW4gLSAxOyBpKyspIHtcbiAgICBjb25zdCBjaGFyID0gaW5wdXRbaV07XG4gICAgaWYgKHN0YXRlLmpbY2hhcl0pIHtcbiAgICAgIG5leHQgPSBzdGF0ZS5qW2NoYXJdO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0ID0gbmV3IFN0YXRlKGRlZmF1bHR0KTtcbiAgICAgIG5leHQuanIgPSBqci5zbGljZSgpO1xuICAgICAgc3RhdGUualtjaGFyXSA9IG5leHQ7XG4gICAgfVxuICAgIHN0YXRlID0gbmV4dDtcbiAgfVxuICBuZXh0ID0gbmV3IFN0YXRlKHQpO1xuICBuZXh0LmpyID0ganIuc2xpY2UoKTtcbiAgc3RhdGUualtpbnB1dFtsZW4gLSAxXV0gPSBuZXh0O1xuICByZXR1cm4gbmV4dDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHN0cmluZyBvZiBUb3AtTGV2ZWwgRG9tYWluIG5hbWVzIGVuY29kZWQgaW4gdXBkYXRlLXRsZHMuanMgYmFja1xuICogaW50byBhIGxpc3Qgb2Ygc3RyaW5ncy5cbiAqIEBwYXJhbSB7c3RyfSBlbmNvZGVkIGVuY29kZWQgVExEcyBzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJbXX0gb3JpZ2luYWwgVExEcyBsaXN0XG4gKi9cbmZ1bmN0aW9uIGRlY29kZVRsZHMoZW5jb2RlZCkge1xuICBjb25zdCB3b3JkcyA9IFtdO1xuICBjb25zdCBzdGFjayA9IFtdO1xuICBsZXQgaSA9IDA7XG4gIGxldCBkaWdpdHMgPSAnMDEyMzQ1Njc4OSc7XG4gIHdoaWxlIChpIDwgZW5jb2RlZC5sZW5ndGgpIHtcbiAgICBsZXQgcG9wRGlnaXRDb3VudCA9IDA7XG4gICAgd2hpbGUgKGRpZ2l0cy5pbmRleE9mKGVuY29kZWRbaSArIHBvcERpZ2l0Q291bnRdKSA+PSAwKSB7XG4gICAgICBwb3BEaWdpdENvdW50Kys7IC8vIGVuY291bnRlcmVkIHNvbWUgZGlnaXRzLCBoYXZlIHRvIHBvcCB0byBnbyBvbmUgbGV2ZWwgdXAgdHJpZVxuICAgIH1cbiAgICBpZiAocG9wRGlnaXRDb3VudCA+IDApIHtcbiAgICAgIHdvcmRzLnB1c2goc3RhY2suam9pbignJykpOyAvLyB3aGF0ZXZlciBwcmVjZWRlZCB0aGUgcG9wIGRpZ2l0cyBtdXN0IGJlIGEgd29yZFxuICAgICAgZm9yIChsZXQgcG9wQ291bnQgPSBwYXJzZUludChlbmNvZGVkLnN1YnN0cmluZyhpLCBpICsgcG9wRGlnaXRDb3VudCksIDEwKTsgcG9wQ291bnQgPiAwOyBwb3BDb3VudC0tKSB7XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgfVxuICAgICAgaSArPSBwb3BEaWdpdENvdW50O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGFjay5wdXNoKGVuY29kZWRbaV0pOyAvLyBkcm9wIGRvd24gYSBsZXZlbCBpbnRvIHRoZSB0cmllXG4gICAgICBpKys7XG4gICAgfVxuICB9XG4gIHJldHVybiB3b3Jkcztcbn1cblxuLyoqXG4gKiBBbiBvYmplY3Qgd2hlcmUgZWFjaCBrZXkgaXMgYSB2YWxpZCBET00gRXZlbnQgTmFtZSBzdWNoIGFzIGBjbGlja2Agb3IgYGZvY3VzYFxuICogYW5kIGVhY2ggdmFsdWUgaXMgYW4gZXZlbnQgaGFuZGxlciBmdW5jdGlvbi5cbiAqXG4gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudCNldmVudHNcbiAqIEB0eXBlZGVmIHs/eyBbZXZlbnQ6IHN0cmluZ106IEZ1bmN0aW9uIH19IEV2ZW50TGlzdGVuZXJzXG4gKi9cblxuLyoqXG4gKiBBbGwgZm9ybWF0dGVkIHByb3BlcnRpZXMgcmVxdWlyZWQgdG8gcmVuZGVyIGEgbGluaywgaW5jbHVkaW5nIGB0YWdOYW1lYCxcbiAqIGBhdHRyaWJ1dGVzYCwgYGNvbnRlbnRgIGFuZCBgZXZlbnRMaXN0ZW5lcnNgLlxuICogQHR5cGVkZWYge3sgdGFnTmFtZTogYW55LCBhdHRyaWJ1dGVzOiB7W2F0dHI6IHN0cmluZ106IGFueX0sIGNvbnRlbnQ6IHN0cmluZyxcbiAqIGV2ZW50TGlzdGVuZXJzOiBFdmVudExpc3RlbmVycyB9fSBJbnRlcm1lZGlhdGVSZXByZXNlbnRhdGlvblxuICovXG5cbi8qKlxuICogU3BlY2lmeSBlaXRoZXIgYW4gb2JqZWN0IGRlc2NyaWJlZCBieSB0aGUgdGVtcGxhdGUgdHlwZSBgT2Agb3IgYSBmdW5jdGlvbi5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gdGFrZXMgYSBzdHJpbmcgdmFsdWUgKHVzdWFsbHkgdGhlIGxpbmsncyBocmVmIGF0dHJpYnV0ZSksIHRoZVxuICogbGluayB0eXBlIChgJ3VybCdgLCBgJ2hhc2h0YWdgJywgZXRjLikgYW5kIGFuIGludGVybmFsIHRva2VuIHJlcHJlc2VudGF0aW9uXG4gKiBvZiB0aGUgbGluay4gSXQgc2hvdWxkIHJldHVybiBhbiBvYmplY3Qgb2YgdGhlIHRlbXBsYXRlIHR5cGUgYE9gXG4gKiBAdGVtcGxhdGUgT1xuICogQHR5cGVkZWYge08gfCAoKHZhbHVlOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgdG9rZW46IE11bHRpVG9rZW4pID0+IE8pfSBPcHRPYmpcbiAqL1xuXG4vKipcbiAqIFNwZWNpZnkgZWl0aGVyIGEgZnVuY3Rpb24gZGVzY3JpYmVkIGJ5IHRlbXBsYXRlIHR5cGUgYEZgIG9yIGFuIG9iamVjdC5cbiAqXG4gKiBFYWNoIGtleSBpbiB0aGUgb2JqZWN0IHNob3VsZCBiZSBhIGxpbmsgdHlwZSAoYCd1cmwnYCwgYCdoYXNodGFnYCcsIGV0Yy4pLiBFYWNoXG4gKiB2YWx1ZSBzaG91bGQgYmUgYSBmdW5jdGlvbiB3aXRoIHRlbXBsYXRlIHR5cGUgYEZgIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlXG4gKiBjb3JyZXNwb25kaW5nIGxpbmsgdHlwZSBpcyBlbmNvdW50ZXJlZC5cbiAqIEB0ZW1wbGF0ZSBGXG4gKiBAdHlwZWRlZiB7RiB8IHsgW3R5cGU6IHN0cmluZ106IEZ9fSBPcHRGblxuICovXG5cbi8qKlxuICogU3BlY2lmeSBlaXRoZXIgYSB2YWx1ZSB3aXRoIHRlbXBsYXRlIHR5cGUgYFZgLCBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBgVmAgb3JcbiAqIGFuIG9iamVjdCB3aGVyZSBlYWNoIHZhbHVlIHJlc29sdmVzIHRvIGBWYC5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gdGFrZXMgYSBzdHJpbmcgdmFsdWUgKHVzdWFsbHkgdGhlIGxpbmsncyBocmVmIGF0dHJpYnV0ZSksIHRoZVxuICogbGluayB0eXBlIChgJ3VybCdgLCBgJ2hhc2h0YWdgJywgZXRjLikgYW5kIGFuIGludGVybmFsIHRva2VuIHJlcHJlc2VudGF0aW9uXG4gKiBvZiB0aGUgbGluay4gSXQgc2hvdWxkIHJldHVybiBhbiBvYmplY3Qgb2YgdGhlIHRlbXBsYXRlIHR5cGUgYFZgXG4gKlxuICogRm9yIHRoZSBvYmplY3QsIGVhY2gga2V5IHNob3VsZCBiZSBhIGxpbmsgdHlwZSAoYCd1cmwnYCwgYCdoYXNodGFnYCcsIGV0Yy4pLlxuICogRWFjaCB2YWx1ZSBzaG91bGQgZWl0aGVyIGhhdmUgdHlwZSBgVmAgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgVi4gVGhpc1xuICogZnVuY3Rpb24gc2ltaWxhcmx5IHRha2VzIGEgc3RyaW5nIHZhbHVlIGFuZCBhIHRva2VuLlxuICpcbiAqIEV4YW1wbGUgdmFsaWQgdHlwZXMgZm9yIGBPcHQ8c3RyaW5nPmA6XG4gKlxuICogYGBganNcbiAqICdoZWxsbydcbiAqICh2YWx1ZSwgdHlwZSwgdG9rZW4pID0+ICd3b3JsZCdcbiAqIHsgdXJsOiAnaGVsbG8nLCBlbWFpbDogKHZhbHVlLCB0b2tlbikgPT4gJ3dvcmxkJ31cbiAqIGBgYFxuICogQHRlbXBsYXRlIFZcbiAqIEB0eXBlZGVmIHtWIHwgKCh2YWx1ZTogc3RyaW5nLCB0eXBlOiBzdHJpbmcsIHRva2VuOiBNdWx0aVRva2VuKSA9PiBWKSB8IHsgW3R5cGU6IHN0cmluZ106IFYgfCAoKHZhbHVlOiBzdHJpbmcsIHRva2VuOiBNdWx0aVRva2VuKSA9PiBWKSB9fSBPcHRcbiAqL1xuXG4vKipcbiAqIFNlZSBhdmFpbGFibGUgb3B0aW9uczogaHR0cHM6Ly9saW5raWZ5LmpzLm9yZy9kb2NzL29wdGlvbnMuaHRtbFxuICogQHR5cGVkZWYge3tcbiAqIFx0ZGVmYXVsdFByb3RvY29sPzogc3RyaW5nLFxuICogIGV2ZW50cz86IE9wdE9iajxFdmVudExpc3RlbmVycz4sXG4gKiBcdGZvcm1hdD86IE9wdDxzdHJpbmc+LFxuICogXHRmb3JtYXRIcmVmPzogT3B0PHN0cmluZz4sXG4gKiBcdG5sMmJyPzogYm9vbGVhbixcbiAqIFx0dGFnTmFtZT86IE9wdDxhbnk+LFxuICogXHR0YXJnZXQ/OiBPcHQ8c3RyaW5nPixcbiAqIFx0cmVsPzogT3B0PHN0cmluZz4sXG4gKiBcdHZhbGlkYXRlPzogT3B0PGJvb2xlYW4+LFxuICogXHR0cnVuY2F0ZT86IE9wdDxudW1iZXI+LFxuICogXHRjbGFzc05hbWU/OiBPcHQ8c3RyaW5nPixcbiAqIFx0YXR0cmlidXRlcz86IE9wdE9iajwoeyBbYXR0cjogc3RyaW5nXTogYW55IH0pPixcbiAqICBpZ25vcmVUYWdzPzogc3RyaW5nW10sXG4gKiBcdHJlbmRlcj86IE9wdEZuPCgoaXI6IEludGVybWVkaWF0ZVJlcHJlc2VudGF0aW9uKSA9PiBhbnkpPlxuICogfX0gT3B0c1xuICovXG5cbi8qKlxuICogQHR5cGUgUmVxdWlyZWQ8T3B0cz5cbiAqL1xuY29uc3QgZGVmYXVsdHMgPSB7XG4gIGRlZmF1bHRQcm90b2NvbDogJ2h0dHAnLFxuICBldmVudHM6IG51bGwsXG4gIGZvcm1hdDogbm9vcCxcbiAgZm9ybWF0SHJlZjogbm9vcCxcbiAgbmwyYnI6IGZhbHNlLFxuICB0YWdOYW1lOiAnYScsXG4gIHRhcmdldDogbnVsbCxcbiAgcmVsOiBudWxsLFxuICB2YWxpZGF0ZTogdHJ1ZSxcbiAgdHJ1bmNhdGU6IEluZmluaXR5LFxuICBjbGFzc05hbWU6IG51bGwsXG4gIGF0dHJpYnV0ZXM6IG51bGwsXG4gIGlnbm9yZVRhZ3M6IFtdLFxuICByZW5kZXI6IG51bGxcbn07XG5cbi8qKlxuICogVXRpbGl0eSBjbGFzcyBmb3IgbGlua2lmeSBpbnRlcmZhY2VzIHRvIGFwcGx5IHNwZWNpZmllZFxuICoge0BsaW5rIE9wdHMgZm9ybWF0dGluZyBhbmQgcmVuZGVyaW5nIG9wdGlvbnN9LlxuICpcbiAqIEBwYXJhbSB7T3B0cyB8IE9wdGlvbnN9IFtvcHRzXSBPcHRpb24gdmFsdWUgb3ZlcnJpZGVzLlxuICogQHBhcmFtIHsoaXI6IEludGVybWVkaWF0ZVJlcHJlc2VudGF0aW9uKSA9PiBhbnl9IFtkZWZhdWx0UmVuZGVyXSAoRm9yXG4gKiAgIGludGVybmFsIHVzZSkgZGVmYXVsdCByZW5kZXIgZnVuY3Rpb24gdGhhdCBkZXRlcm1pbmVzIGhvdyB0byBnZW5lcmF0ZSBhblxuICogICBIVE1MIGVsZW1lbnQgYmFzZWQgb24gYSBsaW5rIHRva2VuJ3MgZGVyaXZlZCB0YWdOYW1lLCBhdHRyaWJ1dGVzIGFuZCBIVE1MLlxuICogICBTaW1pbGFyIHRvIHJlbmRlciBvcHRpb25cbiAqL1xuZnVuY3Rpb24gT3B0aW9ucyhvcHRzLCBkZWZhdWx0UmVuZGVyID0gbnVsbCkge1xuICBsZXQgbyA9IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRzKTtcbiAgaWYgKG9wdHMpIHtcbiAgICBvID0gT2JqZWN0LmFzc2lnbihvLCBvcHRzIGluc3RhbmNlb2YgT3B0aW9ucyA/IG9wdHMubyA6IG9wdHMpO1xuICB9XG5cbiAgLy8gRW5zdXJlIGFsbCBpZ25vcmVkIHRhZ3MgYXJlIHVwcGVyY2FzZVxuICBjb25zdCBpZ25vcmVkVGFncyA9IG8uaWdub3JlVGFncztcbiAgY29uc3QgdXBwZXJjYXNlSWdub3JlZFRhZ3MgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpZ25vcmVkVGFncy5sZW5ndGg7IGkrKykge1xuICAgIHVwcGVyY2FzZUlnbm9yZWRUYWdzLnB1c2goaWdub3JlZFRhZ3NbaV0udG9VcHBlckNhc2UoKSk7XG4gIH1cbiAgLyoqIEBwcm90ZWN0ZWQgKi9cbiAgdGhpcy5vID0gbztcbiAgaWYgKGRlZmF1bHRSZW5kZXIpIHtcbiAgICB0aGlzLmRlZmF1bHRSZW5kZXIgPSBkZWZhdWx0UmVuZGVyO1xuICB9XG4gIHRoaXMuaWdub3JlVGFncyA9IHVwcGVyY2FzZUlnbm9yZWRUYWdzO1xufVxuT3B0aW9ucy5wcm90b3R5cGUgPSB7XG4gIG86IGRlZmF1bHRzLFxuICAvKipcbiAgICogQHR5cGUgc3RyaW5nW11cbiAgICovXG4gIGlnbm9yZVRhZ3M6IFtdLFxuICAvKipcbiAgICogQHBhcmFtIHtJbnRlcm1lZGlhdGVSZXByZXNlbnRhdGlvbn0gaXJcbiAgICogQHJldHVybnMge2FueX1cbiAgICovXG4gIGRlZmF1bHRSZW5kZXIoaXIpIHtcbiAgICByZXR1cm4gaXI7XG4gIH0sXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgb3IgZmFsc2UgYmFzZWQgb24gd2hldGhlciBhIHRva2VuIHNob3VsZCBiZSBkaXNwbGF5ZWQgYXMgYVxuICAgKiBsaW5rIGJhc2VkIG9uIHRoZSB1c2VyIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7TXVsdGlUb2tlbn0gdG9rZW5cbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBjaGVjayh0b2tlbikge1xuICAgIHJldHVybiB0aGlzLmdldCgndmFsaWRhdGUnLCB0b2tlbi50b1N0cmluZygpLCB0b2tlbik7XG4gIH0sXG4gIC8vIFByaXZhdGUgbWV0aG9kc1xuXG4gIC8qKlxuICAgKiBSZXNvbHZlIGFuIG9wdGlvbidzIHZhbHVlIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiB0aGUgb3B0aW9uIGFuZCB0aGUgZ2l2ZW5cbiAgICogcGFyYW1zLiBJZiBvcGVyYXRvciBhbmQgdG9rZW4gYXJlIHNwZWNpZmllZCBhbmQgdGhlIHRhcmdldCBvcHRpb24gaXNcbiAgICogY2FsbGFibGUsIGF1dG9tYXRpY2FsbHkgY2FsbHMgdGhlIGZ1bmN0aW9uIHdpdGggdGhlIGdpdmVuIGFyZ3VtZW50LlxuICAgKiBAdGVtcGxhdGUge2tleW9mIE9wdHN9IEtcbiAgICogQHBhcmFtIHtLfSBrZXkgTmFtZSBvZiBvcHRpb24gdG8gdXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3BlcmF0b3JdIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSB0YXJnZXQgb3B0aW9uIGlmIGl0J3MgYVxuICAgKiBmdW5jdGlvbi4gSWYgbm90IHNwZWNpZmllZCwgUkFXIGZ1bmN0aW9uIHZhbHVlIGdldHMgcmV0dXJuZWRcbiAgICogQHBhcmFtIHtNdWx0aVRva2VufSBbdG9rZW5dIFRoZSB0b2tlbiBmcm9tIGxpbmtpZnkudG9rZW5pemVcbiAgICogQHJldHVybnMge09wdHNbS10gfCBhbnl9XG4gICAqL1xuICBnZXQoa2V5LCBvcGVyYXRvciwgdG9rZW4pIHtcbiAgICBjb25zdCBpc0NhbGxhYmxlID0gb3BlcmF0b3IgIT0gbnVsbDtcbiAgICBsZXQgb3B0aW9uID0gdGhpcy5vW2tleV07XG4gICAgaWYgKCFvcHRpb24pIHtcbiAgICAgIHJldHVybiBvcHRpb247XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb3B0aW9uID09PSAnb2JqZWN0Jykge1xuICAgICAgb3B0aW9uID0gdG9rZW4udCBpbiBvcHRpb24gPyBvcHRpb25bdG9rZW4udF0gOiBkZWZhdWx0c1trZXldO1xuICAgICAgaWYgKHR5cGVvZiBvcHRpb24gPT09ICdmdW5jdGlvbicgJiYgaXNDYWxsYWJsZSkge1xuICAgICAgICBvcHRpb24gPSBvcHRpb24ob3BlcmF0b3IsIHRva2VuKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBvcHRpb24gPT09ICdmdW5jdGlvbicgJiYgaXNDYWxsYWJsZSkge1xuICAgICAgb3B0aW9uID0gb3B0aW9uKG9wZXJhdG9yLCB0b2tlbi50LCB0b2tlbik7XG4gICAgfVxuICAgIHJldHVybiBvcHRpb247XG4gIH0sXG4gIC8qKlxuICAgKiBAdGVtcGxhdGUge2tleW9mIE9wdHN9IExcbiAgICogQHBhcmFtIHtMfSBrZXkgTmFtZSBvZiBvcHRpb25zIG9iamVjdCB0byB1c2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcGVyYXRvcl1cbiAgICogQHBhcmFtIHtNdWx0aVRva2VufSBbdG9rZW5dXG4gICAqIEByZXR1cm5zIHtPcHRzW0xdIHwgYW55fVxuICAgKi9cbiAgZ2V0T2JqKGtleSwgb3BlcmF0b3IsIHRva2VuKSB7XG4gICAgbGV0IG9iaiA9IHRoaXMub1trZXldO1xuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nICYmIG9wZXJhdG9yICE9IG51bGwpIHtcbiAgICAgIG9iaiA9IG9iaihvcGVyYXRvciwgdG9rZW4udCwgdG9rZW4pO1xuICAgIH1cbiAgICByZXR1cm4gb2JqO1xuICB9LFxuICAvKipcbiAgICogQ29udmVydCB0aGUgZ2l2ZW4gdG9rZW4gdG8gYSByZW5kZXJlZCBlbGVtZW50IHRoYXQgbWF5IGJlIGFkZGVkIHRvIHRoZVxuICAgKiBjYWxsaW5nLWludGVyZmFjZSdzIERPTVxuICAgKiBAcGFyYW0ge011bHRpVG9rZW59IHRva2VuIFRva2VuIHRvIHJlbmRlciB0byBhbiBIVE1MIGVsZW1lbnRcbiAgICogQHJldHVybnMge2FueX0gUmVuZGVyIHJlc3VsdDsgZS5nLiwgSFRNTCBzdHJpbmcsIERPTSBlbGVtZW50LCBSZWFjdFxuICAgKiAgIENvbXBvbmVudCwgZXRjLlxuICAgKi9cbiAgcmVuZGVyKHRva2VuKSB7XG4gICAgY29uc3QgaXIgPSB0b2tlbi5yZW5kZXIodGhpcyk7IC8vIGludGVybWVkaWF0ZSByZXByZXNlbnRhdGlvblxuICAgIGNvbnN0IHJlbmRlckZuID0gdGhpcy5nZXQoJ3JlbmRlcicsIG51bGwsIHRva2VuKSB8fCB0aGlzLmRlZmF1bHRSZW5kZXI7XG4gICAgcmV0dXJuIHJlbmRlckZuKGlyLCB0b2tlbi50LCB0b2tlbik7XG4gIH1cbn07XG5mdW5jdGlvbiBub29wKHZhbCkge1xuICByZXR1cm4gdmFsO1xufVxuXG52YXIgb3B0aW9ucyA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcblx0X19wcm90b19fOiBudWxsLFxuXHRPcHRpb25zOiBPcHRpb25zLFxuXHRkZWZhdWx0czogZGVmYXVsdHNcbn0pO1xuXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cdE11bHRpLVRva2Vuc1xuXHRUb2tlbnMgY29tcG9zZWQgb2YgYXJyYXlzIG9mIFRleHRUb2tlbnNcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAqIEBwYXJhbSB7VG9rZW5bXX0gdG9rZW5zXG4gKi9cbmZ1bmN0aW9uIE11bHRpVG9rZW4odmFsdWUsIHRva2Vucykge1xuICB0aGlzLnQgPSAndG9rZW4nO1xuICB0aGlzLnYgPSB2YWx1ZTtcbiAgdGhpcy50ayA9IHRva2Vucztcbn1cblxuLyoqXG4gKiBBYnN0cmFjdCBjbGFzcyB1c2VkIGZvciBtYW51ZmFjdHVyaW5nIHRva2VucyBvZiB0ZXh0IHRva2Vucy4gVGhhdCBpcyByYXRoZXJcbiAqIHRoYW4gdGhlIHZhbHVlIGZvciBhIHRva2VuIGJlaW5nIGEgc21hbGwgc3RyaW5nIG9mIHRleHQsIGl0J3MgdmFsdWUgYW4gYXJyYXlcbiAqIG9mIHRleHQgdG9rZW5zLlxuICpcbiAqIFVzZWQgZm9yIGdyb3VwaW5nIHRvZ2V0aGVyIFVSTHMsIGVtYWlscywgaGFzaHRhZ3MsIGFuZCBvdGhlciBwb3RlbnRpYWxcbiAqIGNyZWF0aW9ucy5cbiAqIEBjbGFzcyBNdWx0aVRva2VuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdFxuICogQHByb3BlcnR5IHtzdHJpbmd9IHZcbiAqIEBwcm9wZXJ0eSB7VG9rZW5bXX0gdGtcbiAqIEBhYnN0cmFjdFxuICovXG5NdWx0aVRva2VuLnByb3RvdHlwZSA9IHtcbiAgaXNMaW5rOiBmYWxzZSxcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgc3RyaW5nIHRoaXMgdG9rZW4gcmVwcmVzZW50cy5cbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMudjtcbiAgfSxcbiAgLyoqXG4gICAqIFdoYXQgc2hvdWxkIHRoZSB2YWx1ZSBmb3IgdGhpcyB0b2tlbiBiZSBpbiB0aGUgYGhyZWZgIEhUTUwgYXR0cmlidXRlP1xuICAgKiBSZXR1cm5zIHRoZSBgLnRvU3RyaW5nYCB2YWx1ZSBieSBkZWZhdWx0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3NjaGVtZV1cbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9IcmVmKHNjaGVtZSkge1xuICAgIHJldHVybiB0aGlzLnRvU3RyaW5nKCk7XG4gIH0sXG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgRm9ybWF0dGluZyBvcHRpb25zXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICB0b0Zvcm1hdHRlZFN0cmluZyhvcHRpb25zKSB7XG4gICAgY29uc3QgdmFsID0gdGhpcy50b1N0cmluZygpO1xuICAgIGNvbnN0IHRydW5jYXRlID0gb3B0aW9ucy5nZXQoJ3RydW5jYXRlJywgdmFsLCB0aGlzKTtcbiAgICBjb25zdCBmb3JtYXR0ZWQgPSBvcHRpb25zLmdldCgnZm9ybWF0JywgdmFsLCB0aGlzKTtcbiAgICByZXR1cm4gdHJ1bmNhdGUgJiYgZm9ybWF0dGVkLmxlbmd0aCA+IHRydW5jYXRlID8gZm9ybWF0dGVkLnN1YnN0cmluZygwLCB0cnVuY2F0ZSkgKyAnXHUyMDI2JyA6IGZvcm1hdHRlZDtcbiAgfSxcbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9uc1xuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgdG9Gb3JtYXR0ZWRIcmVmKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gb3B0aW9ucy5nZXQoJ2Zvcm1hdEhyZWYnLCB0aGlzLnRvSHJlZihvcHRpb25zLmdldCgnZGVmYXVsdFByb3RvY29sJykpLCB0aGlzKTtcbiAgfSxcbiAgLyoqXG4gICAqIFRoZSBzdGFydCBpbmRleCBvZiB0aGlzIHRva2VuIGluIHRoZSBvcmlnaW5hbCBpbnB1dCBzdHJpbmdcbiAgICogQHJldHVybnMge251bWJlcn1cbiAgICovXG4gIHN0YXJ0SW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMudGtbMF0ucztcbiAgfSxcbiAgLyoqXG4gICAqIFRoZSBlbmQgaW5kZXggb2YgdGhpcyB0b2tlbiBpbiB0aGUgb3JpZ2luYWwgaW5wdXQgc3RyaW5nICh1cCB0byB0aGlzXG4gICAqIGluZGV4IGJ1dCBub3QgaW5jbHVkaW5nIGl0KVxuICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgKi9cbiAgZW5kSW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMudGtbdGhpcy50ay5sZW5ndGggLSAxXS5lO1xuICB9LFxuICAvKipcbiAgXHRSZXR1cm5zIGFuIG9iamVjdCAgb2YgcmVsZXZhbnQgdmFsdWVzIGZvciB0aGlzIHRva2VuLCB3aGljaCBpbmNsdWRlcyBrZXlzXG4gIFx0KiB0eXBlIC0gS2luZCBvZiB0b2tlbiAoJ3VybCcsICdlbWFpbCcsIGV0Yy4pXG4gIFx0KiB2YWx1ZSAtIE9yaWdpbmFsIHRleHRcbiAgXHQqIGhyZWYgLSBUaGUgdmFsdWUgdGhhdCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIGFuY2hvciB0YWcncyBocmVmXG4gIFx0XHRhdHRyaWJ1dGVcbiAgXHRcdEBtZXRob2QgdG9PYmplY3RcbiAgXHRAcGFyYW0ge3N0cmluZ30gW3Byb3RvY29sXSBgJ2h0dHAnYCBieSBkZWZhdWx0XG4gICovXG4gIHRvT2JqZWN0KHByb3RvY29sID0gZGVmYXVsdHMuZGVmYXVsdFByb3RvY29sKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHRoaXMudCxcbiAgICAgIHZhbHVlOiB0aGlzLnRvU3RyaW5nKCksXG4gICAgICBpc0xpbms6IHRoaXMuaXNMaW5rLFxuICAgICAgaHJlZjogdGhpcy50b0hyZWYocHJvdG9jb2wpLFxuICAgICAgc3RhcnQ6IHRoaXMuc3RhcnRJbmRleCgpLFxuICAgICAgZW5kOiB0aGlzLmVuZEluZGV4KClcbiAgICB9O1xuICB9LFxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIEZvcm1hdHRpbmcgb3B0aW9uXG4gICAqL1xuICB0b0Zvcm1hdHRlZE9iamVjdChvcHRpb25zKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHRoaXMudCxcbiAgICAgIHZhbHVlOiB0aGlzLnRvRm9ybWF0dGVkU3RyaW5nKG9wdGlvbnMpLFxuICAgICAgaXNMaW5rOiB0aGlzLmlzTGluayxcbiAgICAgIGhyZWY6IHRoaXMudG9Gb3JtYXR0ZWRIcmVmKG9wdGlvbnMpLFxuICAgICAgc3RhcnQ6IHRoaXMuc3RhcnRJbmRleCgpLFxuICAgICAgZW5kOiB0aGlzLmVuZEluZGV4KClcbiAgICB9O1xuICB9LFxuICAvKipcbiAgICogV2hldGhlciB0aGlzIHRva2VuIHNob3VsZCBiZSByZW5kZXJlZCBhcyBhIGxpbmsgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBvcHRpb25zXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9uc1xuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIHZhbGlkYXRlKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gb3B0aW9ucy5nZXQoJ3ZhbGlkYXRlJywgdGhpcy50b1N0cmluZygpLCB0aGlzKTtcbiAgfSxcbiAgLyoqXG4gICAqIFJldHVybiBhbiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGhvdyB0aGlzIGxpbmsgc2hvdWxkIGJlIHJlbmRlcmVkLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgRm9ybWF0dGlubmcgb3B0aW9uc1xuICAgKi9cbiAgcmVuZGVyKG9wdGlvbnMpIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXM7XG4gICAgY29uc3QgaHJlZiA9IHRoaXMudG9IcmVmKG9wdGlvbnMuZ2V0KCdkZWZhdWx0UHJvdG9jb2wnKSk7XG4gICAgY29uc3QgZm9ybWF0dGVkSHJlZiA9IG9wdGlvbnMuZ2V0KCdmb3JtYXRIcmVmJywgaHJlZiwgdGhpcyk7XG4gICAgY29uc3QgdGFnTmFtZSA9IG9wdGlvbnMuZ2V0KCd0YWdOYW1lJywgaHJlZiwgdG9rZW4pO1xuICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLnRvRm9ybWF0dGVkU3RyaW5nKG9wdGlvbnMpO1xuICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSB7fTtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBvcHRpb25zLmdldCgnY2xhc3NOYW1lJywgaHJlZiwgdG9rZW4pO1xuICAgIGNvbnN0IHRhcmdldCA9IG9wdGlvbnMuZ2V0KCd0YXJnZXQnLCBocmVmLCB0b2tlbik7XG4gICAgY29uc3QgcmVsID0gb3B0aW9ucy5nZXQoJ3JlbCcsIGhyZWYsIHRva2VuKTtcbiAgICBjb25zdCBhdHRycyA9IG9wdGlvbnMuZ2V0T2JqKCdhdHRyaWJ1dGVzJywgaHJlZiwgdG9rZW4pO1xuICAgIGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gb3B0aW9ucy5nZXRPYmooJ2V2ZW50cycsIGhyZWYsIHRva2VuKTtcbiAgICBhdHRyaWJ1dGVzLmhyZWYgPSBmb3JtYXR0ZWRIcmVmO1xuICAgIGlmIChjbGFzc05hbWUpIHtcbiAgICAgIGF0dHJpYnV0ZXMuY2xhc3MgPSBjbGFzc05hbWU7XG4gICAgfVxuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgIGF0dHJpYnV0ZXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIH1cbiAgICBpZiAocmVsKSB7XG4gICAgICBhdHRyaWJ1dGVzLnJlbCA9IHJlbDtcbiAgICB9XG4gICAgaWYgKGF0dHJzKSB7XG4gICAgICBPYmplY3QuYXNzaWduKGF0dHJpYnV0ZXMsIGF0dHJzKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHRhZ05hbWUsXG4gICAgICBhdHRyaWJ1dGVzLFxuICAgICAgY29udGVudCxcbiAgICAgIGV2ZW50TGlzdGVuZXJzXG4gICAgfTtcbiAgfVxufTtcblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgdG9rZW4gdGhhdCBjYW4gYmUgZW1pdHRlZCBieSB0aGUgcGFyc2VyIHN0YXRlIG1hY2hpbmVcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIHJlYWRhYmxlIHR5cGUgb2YgdGhlIHRva2VuXG4gKiBAcGFyYW0ge29iamVjdH0gcHJvcHMgcHJvcGVydGllcyB0byBhc3NpZ24gb3Igb3ZlcnJpZGUsIGluY2x1ZGluZyBpc0xpbmsgPSB0cnVlIG9yIGZhbHNlXG4gKiBAcmV0dXJucyB7bmV3ICh2YWx1ZTogc3RyaW5nLCB0b2tlbnM6IFRva2VuW10pID0+IE11bHRpVG9rZW59IG5ldyB0b2tlbiBjbGFzc1xuICovXG5mdW5jdGlvbiBjcmVhdGVUb2tlbkNsYXNzKHR5cGUsIHByb3BzKSB7XG4gIGNsYXNzIFRva2VuIGV4dGVuZHMgTXVsdGlUb2tlbiB7XG4gICAgY29uc3RydWN0b3IodmFsdWUsIHRva2Vucykge1xuICAgICAgc3VwZXIodmFsdWUsIHRva2Vucyk7XG4gICAgICB0aGlzLnQgPSB0eXBlO1xuICAgIH1cbiAgfVxuICBmb3IgKGNvbnN0IHAgaW4gcHJvcHMpIHtcbiAgICBUb2tlbi5wcm90b3R5cGVbcF0gPSBwcm9wc1twXTtcbiAgfVxuICBUb2tlbi50ID0gdHlwZTtcbiAgcmV0dXJuIFRva2VuO1xufVxuXG4vKipcblx0UmVwcmVzZW50cyBhIGxpc3Qgb2YgdG9rZW5zIG1ha2luZyB1cCBhIHZhbGlkIGVtYWlsIGFkZHJlc3NcbiovXG5jb25zdCBFbWFpbCA9IGNyZWF0ZVRva2VuQ2xhc3MoJ2VtYWlsJywge1xuICBpc0xpbms6IHRydWUsXG4gIHRvSHJlZigpIHtcbiAgICByZXR1cm4gJ21haWx0bzonICsgdGhpcy50b1N0cmluZygpO1xuICB9XG59KTtcblxuLyoqXG5cdFJlcHJlc2VudHMgc29tZSBwbGFpbiB0ZXh0XG4qL1xuY29uc3QgVGV4dCA9IGNyZWF0ZVRva2VuQ2xhc3MoJ3RleHQnKTtcblxuLyoqXG5cdE11bHRpLWxpbmVicmVhayB0b2tlbiAtIHJlcHJlc2VudHMgYSBsaW5lIGJyZWFrXG5cdEBjbGFzcyBObFxuKi9cbmNvbnN0IE5sID0gY3JlYXRlVG9rZW5DbGFzcygnbmwnKTtcblxuLyoqXG5cdFJlcHJlc2VudHMgYSBsaXN0IG9mIHRleHQgdG9rZW5zIG1ha2luZyB1cCBhIHZhbGlkIFVSTFxuXHRAY2xhc3MgVXJsXG4qL1xuY29uc3QgVXJsID0gY3JlYXRlVG9rZW5DbGFzcygndXJsJywge1xuICBpc0xpbms6IHRydWUsXG4gIC8qKlxuICBcdExvd2VyY2FzZXMgcmVsZXZhbnQgcGFydHMgb2YgdGhlIGRvbWFpbiBhbmQgYWRkcyB0aGUgcHJvdG9jb2wgaWZcbiAgXHRyZXF1aXJlZC4gTm90ZSB0aGF0IHRoaXMgd2lsbCBub3QgZXNjYXBlIHVuc2FmZSBIVE1MIGNoYXJhY3RlcnMgaW4gdGhlXG4gIFx0VVJMLlxuICBcdFx0QHBhcmFtIHtzdHJpbmd9IFtzY2hlbWVdIGRlZmF1bHQgc2NoZW1lIChlLmcuLCAnaHR0cHMnKVxuICBcdEByZXR1cm4ge3N0cmluZ30gdGhlIGZ1bGwgaHJlZlxuICAqL1xuICB0b0hyZWYoc2NoZW1lID0gZGVmYXVsdHMuZGVmYXVsdFByb3RvY29sKSB7XG4gICAgLy8gQ2hlY2sgaWYgYWxyZWFkeSBoYXMgYSBwcmVmaXggc2NoZW1lXG4gICAgcmV0dXJuIHRoaXMuaGFzUHJvdG9jb2woKSA/IHRoaXMudiA6IGAke3NjaGVtZX06Ly8ke3RoaXMudn1gO1xuICB9LFxuICAvKipcbiAgICogQ2hlY2sgd2hldGhlciB0aGlzIFVSTCB0b2tlbiBoYXMgYSBwcm90b2NvbFxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaGFzUHJvdG9jb2woKSB7XG4gICAgY29uc3QgdG9rZW5zID0gdGhpcy50aztcbiAgICByZXR1cm4gdG9rZW5zLmxlbmd0aCA+PSAyICYmIHRva2Vuc1swXS50ICE9PSBMT0NBTEhPU1QgJiYgdG9rZW5zWzFdLnQgPT09IENPTE9OO1xuICB9XG59KTtcblxudmFyIG11bHRpID0gLyojX19QVVJFX18qL09iamVjdC5mcmVlemUoe1xuXHRfX3Byb3RvX186IG51bGwsXG5cdEJhc2U6IE11bHRpVG9rZW4sXG5cdEVtYWlsOiBFbWFpbCxcblx0TXVsdGlUb2tlbjogTXVsdGlUb2tlbixcblx0Tmw6IE5sLFxuXHRUZXh0OiBUZXh0LFxuXHRVcmw6IFVybCxcblx0Y3JlYXRlVG9rZW5DbGFzczogY3JlYXRlVG9rZW5DbGFzc1xufSk7XG5cbi8qKlxuXHROb3QgZXhhY3RseSBwYXJzZXIsIG1vcmUgbGlrZSB0aGUgc2Vjb25kLXN0YWdlIHNjYW5uZXIgKGFsdGhvdWdoIHdlIGNhblxuXHR0aGVvcmV0aWNhbGx5IGhvdHN3YXAgdGhlIGNvZGUgaGVyZSB3aXRoIGEgcmVhbCBwYXJzZXIgaW4gdGhlIGZ1dHVyZS4uLiBidXRcblx0Zm9yIGEgbGl0dGxlIFVSTC1maW5kaW5nIHV0aWxpdHkgYWJzdHJhY3Qgc3ludGF4IHRyZWVzIG1heSBiZSBhIGxpdHRsZVxuXHRvdmVya2lsbCkuXG5cblx0VVJMIGZvcm1hdDogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VUklfc2NoZW1lXG5cdEVtYWlsIGZvcm1hdDogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FbWFpbEFkZHJlc3MgKGxpbmtzIHRvIFJGQyBpblxuXHRyZWZlcmVuY2UpXG5cblx0QG1vZHVsZSBsaW5raWZ5XG5cdEBzdWJtb2R1bGUgcGFyc2VyXG5cdEBtYWluIHJ1blxuKi9cblxuY29uc3QgbWFrZVN0YXRlID0gYXJnID0+IG5ldyBTdGF0ZShhcmcpO1xuXG4vKipcbiAqIEdlbmVyYXRlIHRoZSBwYXJzZXIgbXVsdGkgdG9rZW4tYmFzZWQgc3RhdGUgbWFjaGluZVxuICogQHBhcmFtIHt7IGdyb3VwczogQ29sbGVjdGlvbnM8c3RyaW5nPiB9fSB0b2tlbnNcbiAqL1xuZnVuY3Rpb24gaW5pdCQxKHtcbiAgZ3JvdXBzXG59KSB7XG4gIC8vIFR5cGVzIG9mIGNoYXJhY3RlcnMgdGhlIFVSTCBjYW4gZGVmaW5pdGVseSBlbmQgaW5cbiAgY29uc3QgcXNBY2NlcHRpbmcgPSBncm91cHMuZG9tYWluLmNvbmNhdChbQU1QRVJTQU5ELCBBU1RFUklTSywgQVQsIEJBQ0tTTEFTSCwgQkFDS1RJQ0ssIENBUkVULCBET0xMQVIsIEVRVUFMUywgSFlQSEVOLCBOVU0sIFBFUkNFTlQsIFBJUEUsIFBMVVMsIFBPVU5ELCBTTEFTSCwgU1lNLCBUSUxERSwgVU5ERVJTQ09SRV0pO1xuXG4gIC8vIFR5cGVzIG9mIHRva2VucyB0aGF0IGNhbiBmb2xsb3cgYSBVUkwgYW5kIGJlIHBhcnQgb2YgdGhlIHF1ZXJ5IHN0cmluZ1xuICAvLyBidXQgY2Fubm90IGJlIHRoZSB2ZXJ5IGxhc3QgY2hhcmFjdGVyc1xuICAvLyBDaGFyYWN0ZXJzIHRoYXQgY2Fubm90IGFwcGVhciBpbiB0aGUgVVJMIGF0IGFsbCBzaG91bGQgYmUgZXhjbHVkZWRcbiAgY29uc3QgcXNOb25BY2NlcHRpbmcgPSBbQVBPU1RST1BIRSwgQ09MT04sIENPTU1BLCBET1QsIEVYQ0xBTUFUSU9OLCBQRVJDRU5ULCBRVUVSWSwgUVVPVEUsIFNFTUksIE9QRU5BTkdMRUJSQUNLRVQsIENMT1NFQU5HTEVCUkFDS0VULCBPUEVOQlJBQ0UsIENMT1NFQlJBQ0UsIENMT1NFQlJBQ0tFVCwgT1BFTkJSQUNLRVQsIE9QRU5QQVJFTiwgQ0xPU0VQQVJFTiwgRlVMTFdJRFRITEVGVFBBUkVOLCBGVUxMV0lEVEhSSUdIVFBBUkVOLCBMRUZUQ09STkVSQlJBQ0tFVCwgUklHSFRDT1JORVJCUkFDS0VULCBMRUZUV0hJVEVDT1JORVJCUkFDS0VULCBSSUdIVFdISVRFQ09STkVSQlJBQ0tFVCwgRlVMTFdJRFRITEVTU1RIQU4sIEZVTExXSURUSEdSRUFURVJUSEFOXTtcblxuICAvLyBGb3IgYWRkcmVzc2VzIHdpdGhvdXQgdGhlIG1haWx0byBwcmVmaXhcbiAgLy8gVG9rZW5zIGFsbG93ZWQgaW4gdGhlIGxvY2FscGFydCBvZiB0aGUgZW1haWxcbiAgY29uc3QgbG9jYWxwYXJ0QWNjZXB0aW5nID0gW0FNUEVSU0FORCwgQVBPU1RST1BIRSwgQVNURVJJU0ssIEJBQ0tTTEFTSCwgQkFDS1RJQ0ssIENBUkVULCBET0xMQVIsIEVRVUFMUywgSFlQSEVOLCBPUEVOQlJBQ0UsIENMT1NFQlJBQ0UsIFBFUkNFTlQsIFBJUEUsIFBMVVMsIFBPVU5ELCBRVUVSWSwgU0xBU0gsIFNZTSwgVElMREUsIFVOREVSU0NPUkVdO1xuXG4gIC8vIFRoZSB1bml2ZXJzYWwgc3RhcnRpbmcgc3RhdGUuXG4gIC8qKlxuICAgKiBAdHlwZSBTdGF0ZTxUb2tlbj5cbiAgICovXG4gIGNvbnN0IFN0YXJ0ID0gbWFrZVN0YXRlKCk7XG4gIGNvbnN0IExvY2FscGFydCA9IHR0KFN0YXJ0LCBUSUxERSk7IC8vIExvY2FsIHBhcnQgb2YgdGhlIGVtYWlsIGFkZHJlc3NcbiAgdGEoTG9jYWxwYXJ0LCBsb2NhbHBhcnRBY2NlcHRpbmcsIExvY2FscGFydCk7XG4gIHRhKExvY2FscGFydCwgZ3JvdXBzLmRvbWFpbiwgTG9jYWxwYXJ0KTtcbiAgY29uc3QgRG9tYWluID0gbWFrZVN0YXRlKCksXG4gICAgU2NoZW1lID0gbWFrZVN0YXRlKCksXG4gICAgU2xhc2hTY2hlbWUgPSBtYWtlU3RhdGUoKTtcbiAgdGEoU3RhcnQsIGdyb3Vwcy5kb21haW4sIERvbWFpbik7IC8vIHBhcnNlZCBzdHJpbmcgZW5kcyB3aXRoIGEgcG90ZW50aWFsIGRvbWFpbiBuYW1lIChBKVxuICB0YShTdGFydCwgZ3JvdXBzLnNjaGVtZSwgU2NoZW1lKTsgLy8gZS5nLiwgJ21haWx0bydcbiAgdGEoU3RhcnQsIGdyb3Vwcy5zbGFzaHNjaGVtZSwgU2xhc2hTY2hlbWUpOyAvLyBlLmcuLCAnaHR0cCdcblxuICB0YShEb21haW4sIGxvY2FscGFydEFjY2VwdGluZywgTG9jYWxwYXJ0KTtcbiAgdGEoRG9tYWluLCBncm91cHMuZG9tYWluLCBEb21haW4pO1xuICBjb25zdCBMb2NhbHBhcnRBdCA9IHR0KERvbWFpbiwgQVQpOyAvLyBMb2NhbCBwYXJ0IG9mIHRoZSBlbWFpbCBhZGRyZXNzIHBsdXMgQFxuXG4gIHR0KExvY2FscGFydCwgQVQsIExvY2FscGFydEF0KTsgLy8gY2xvc2UgdG8gYW4gZW1haWwgYWRkcmVzcyBub3dcblxuICAvLyBMb2NhbCBwYXJ0IG9mIGFuIGVtYWlsIGFkZHJlc3MgY2FuIGJlIGUuZy4gJ2h0dHAnIG9yICdtYWlsdG8nXG4gIHR0KFNjaGVtZSwgQVQsIExvY2FscGFydEF0KTtcbiAgdHQoU2xhc2hTY2hlbWUsIEFULCBMb2NhbHBhcnRBdCk7XG4gIGNvbnN0IExvY2FscGFydERvdCA9IHR0KExvY2FscGFydCwgRE9UKTsgLy8gTG9jYWwgcGFydCBvZiB0aGUgZW1haWwgYWRkcmVzcyBwbHVzICcuJyAobG9jYWxwYXJ0IGNhbm5vdCBlbmQgaW4gLilcbiAgdGEoTG9jYWxwYXJ0RG90LCBsb2NhbHBhcnRBY2NlcHRpbmcsIExvY2FscGFydCk7XG4gIHRhKExvY2FscGFydERvdCwgZ3JvdXBzLmRvbWFpbiwgTG9jYWxwYXJ0KTtcbiAgY29uc3QgRW1haWxEb21haW4gPSBtYWtlU3RhdGUoKTtcbiAgdGEoTG9jYWxwYXJ0QXQsIGdyb3Vwcy5kb21haW4sIEVtYWlsRG9tYWluKTsgLy8gcGFyc2VkIHN0cmluZyBzdGFydHMgd2l0aCBsb2NhbCBlbWFpbCBpbmZvICsgQCB3aXRoIGEgcG90ZW50aWFsIGRvbWFpbiBuYW1lXG4gIHRhKEVtYWlsRG9tYWluLCBncm91cHMuZG9tYWluLCBFbWFpbERvbWFpbik7XG4gIGNvbnN0IEVtYWlsRG9tYWluRG90ID0gdHQoRW1haWxEb21haW4sIERPVCk7IC8vIGRvbWFpbiBmb2xsb3dlZCBieSBET1RcbiAgdGEoRW1haWxEb21haW5Eb3QsIGdyb3Vwcy5kb21haW4sIEVtYWlsRG9tYWluKTtcbiAgY29uc3QgRW1haWwkMSA9IG1ha2VTdGF0ZShFbWFpbCk7IC8vIFBvc3NpYmxlIGVtYWlsIGFkZHJlc3MgKGNvdWxkIGhhdmUgbW9yZSB0bGRzKVxuICB0YShFbWFpbERvbWFpbkRvdCwgZ3JvdXBzLnRsZCwgRW1haWwkMSk7XG4gIHRhKEVtYWlsRG9tYWluRG90LCBncm91cHMudXRsZCwgRW1haWwkMSk7XG4gIHR0KExvY2FscGFydEF0LCBMT0NBTEhPU1QsIEVtYWlsJDEpO1xuXG4gIC8vIEh5cGhlbiBjYW4ganVtcCBiYWNrIHRvIGEgZG9tYWluIG5hbWVcbiAgY29uc3QgRW1haWxEb21haW5IeXBoZW4gPSB0dChFbWFpbERvbWFpbiwgSFlQSEVOKTsgLy8gcGFyc2VkIHN0cmluZyBzdGFydHMgd2l0aCBsb2NhbCBlbWFpbCBpbmZvICsgQCB3aXRoIGEgcG90ZW50aWFsIGRvbWFpbiBuYW1lXG4gIHR0KEVtYWlsRG9tYWluSHlwaGVuLCBIWVBIRU4sIEVtYWlsRG9tYWluSHlwaGVuKTtcbiAgdGEoRW1haWxEb21haW5IeXBoZW4sIGdyb3Vwcy5kb21haW4sIEVtYWlsRG9tYWluKTtcbiAgdGEoRW1haWwkMSwgZ3JvdXBzLmRvbWFpbiwgRW1haWxEb21haW4pO1xuICB0dChFbWFpbCQxLCBET1QsIEVtYWlsRG9tYWluRG90KTtcbiAgdHQoRW1haWwkMSwgSFlQSEVOLCBFbWFpbERvbWFpbkh5cGhlbik7XG5cbiAgLy8gQWNjb3VudCBmb3IgZG90cyBhbmQgaHlwaGVucy4gSHlwaGVucyBhcmUgdXN1YWxseSBwYXJ0cyBvZiBkb21haW4gbmFtZXNcbiAgLy8gKGJ1dCBub3QgVExEcylcbiAgY29uc3QgRG9tYWluSHlwaGVuID0gdHQoRG9tYWluLCBIWVBIRU4pOyAvLyBkb21haW4gZm9sbG93ZWQgYnkgaHlwaGVuXG4gIGNvbnN0IERvbWFpbkRvdCA9IHR0KERvbWFpbiwgRE9UKTsgLy8gZG9tYWluIGZvbGxvd2VkIGJ5IERPVFxuICB0dChEb21haW5IeXBoZW4sIEhZUEhFTiwgRG9tYWluSHlwaGVuKTtcbiAgdGEoRG9tYWluSHlwaGVuLCBncm91cHMuZG9tYWluLCBEb21haW4pO1xuICB0YShEb21haW5Eb3QsIGxvY2FscGFydEFjY2VwdGluZywgTG9jYWxwYXJ0KTtcbiAgdGEoRG9tYWluRG90LCBncm91cHMuZG9tYWluLCBEb21haW4pO1xuICBjb25zdCBEb21haW5Eb3RUbGQgPSBtYWtlU3RhdGUoVXJsKTsgLy8gU2ltcGxlc3QgcG9zc2libGUgVVJMIHdpdGggbm8gcXVlcnkgc3RyaW5nXG4gIHRhKERvbWFpbkRvdCwgZ3JvdXBzLnRsZCwgRG9tYWluRG90VGxkKTtcbiAgdGEoRG9tYWluRG90LCBncm91cHMudXRsZCwgRG9tYWluRG90VGxkKTtcbiAgdGEoRG9tYWluRG90VGxkLCBncm91cHMuZG9tYWluLCBEb21haW4pO1xuICB0YShEb21haW5Eb3RUbGQsIGxvY2FscGFydEFjY2VwdGluZywgTG9jYWxwYXJ0KTtcbiAgdHQoRG9tYWluRG90VGxkLCBET1QsIERvbWFpbkRvdCk7XG4gIHR0KERvbWFpbkRvdFRsZCwgSFlQSEVOLCBEb21haW5IeXBoZW4pO1xuICB0dChEb21haW5Eb3RUbGQsIEFULCBMb2NhbHBhcnRBdCk7XG4gIGNvbnN0IERvbWFpbkRvdFRsZENvbG9uID0gdHQoRG9tYWluRG90VGxkLCBDT0xPTik7IC8vIFVSTCBmb2xsb3dlZCBieSBjb2xvbiAocG90ZW50aWFsIHBvcnQgbnVtYmVyIGhlcmUpXG4gIGNvbnN0IERvbWFpbkRvdFRsZENvbG9uUG9ydCA9IG1ha2VTdGF0ZShVcmwpOyAvLyBUTEQgZm9sbG93ZWQgYnkgYSBwb3J0IG51bWJlclxuICB0YShEb21haW5Eb3RUbGRDb2xvbiwgZ3JvdXBzLm51bWVyaWMsIERvbWFpbkRvdFRsZENvbG9uUG9ydCk7XG5cbiAgLy8gTG9uZyBVUkwgd2l0aCBvcHRpb25hbCBwb3J0IGFuZCBtYXliZSBxdWVyeSBzdHJpbmdcbiAgY29uc3QgVXJsJDEgPSBtYWtlU3RhdGUoVXJsKTtcblxuICAvLyBVUkwgd2l0aCBleHRyYSBzeW1ib2xzIGF0IHRoZSBlbmQsIGZvbGxvd2VkIGJ5IGFuIG9wZW5pbmcgYnJhY2tldFxuICBjb25zdCBVcmxOb25hY2NlcHQgPSBtYWtlU3RhdGUoKTsgLy8gVVJMIGZvbGxvd2VkIGJ5IHNvbWUgc3ltYm9scyAod2lsbCBub3QgYmUgcGFydCBvZiB0aGUgZmluYWwgVVJMKVxuXG4gIC8vIFF1ZXJ5IHN0cmluZ3NcbiAgdGEoVXJsJDEsIHFzQWNjZXB0aW5nLCBVcmwkMSk7XG4gIHRhKFVybCQxLCBxc05vbkFjY2VwdGluZywgVXJsTm9uYWNjZXB0KTtcbiAgdGEoVXJsTm9uYWNjZXB0LCBxc0FjY2VwdGluZywgVXJsJDEpO1xuICB0YShVcmxOb25hY2NlcHQsIHFzTm9uQWNjZXB0aW5nLCBVcmxOb25hY2NlcHQpO1xuXG4gIC8vIEJlY29tZSByZWFsIFVSTHMgYWZ0ZXIgYFNMQVNIYCBvciBgQ09MT04gTlVNIFNMQVNIYFxuICAvLyBIZXJlIHdvcmtzIHdpdGggb3Igd2l0aG91dCBzY2hlbWU6Ly8gcHJlZml4XG4gIHR0KERvbWFpbkRvdFRsZCwgU0xBU0gsIFVybCQxKTtcbiAgdHQoRG9tYWluRG90VGxkQ29sb25Qb3J0LCBTTEFTSCwgVXJsJDEpO1xuXG4gIC8vIE5vdGUgdGhhdCBkb21haW5zIHRoYXQgYmVnaW4gd2l0aCBzY2hlbWVzIGFyZSB0cmVhdGVkIHNsaWdobHkgZGlmZmVyZW50bHlcbiAgY29uc3QgU2NoZW1lQ29sb24gPSB0dChTY2hlbWUsIENPTE9OKTsgLy8gZS5nLiwgJ21haWx0bzonXG4gIGNvbnN0IFNsYXNoU2NoZW1lQ29sb24gPSB0dChTbGFzaFNjaGVtZSwgQ09MT04pOyAvLyBlLmcuLCAnaHR0cDonXG4gIGNvbnN0IFNsYXNoU2NoZW1lQ29sb25TbGFzaCA9IHR0KFNsYXNoU2NoZW1lQ29sb24sIFNMQVNIKTsgLy8gZS5nLiwgJ2h0dHA6LydcblxuICBjb25zdCBVcmlQcmVmaXggPSB0dChTbGFzaFNjaGVtZUNvbG9uU2xhc2gsIFNMQVNIKTsgLy8gZS5nLiwgJ2h0dHA6Ly8nXG5cbiAgLy8gU2NoZW1lIHN0YXRlcyBjYW4gdHJhbnNpdGlvbiB0byBkb21haW4gc3RhdGVzXG4gIHRhKFNjaGVtZSwgZ3JvdXBzLmRvbWFpbiwgRG9tYWluKTtcbiAgdHQoU2NoZW1lLCBET1QsIERvbWFpbkRvdCk7XG4gIHR0KFNjaGVtZSwgSFlQSEVOLCBEb21haW5IeXBoZW4pO1xuICB0YShTbGFzaFNjaGVtZSwgZ3JvdXBzLmRvbWFpbiwgRG9tYWluKTtcbiAgdHQoU2xhc2hTY2hlbWUsIERPVCwgRG9tYWluRG90KTtcbiAgdHQoU2xhc2hTY2hlbWUsIEhZUEhFTiwgRG9tYWluSHlwaGVuKTtcblxuICAvLyBGb3JjZSBVUkwgd2l0aCBzY2hlbWUgcHJlZml4IGZvbGxvd2VkIGJ5IGFueXRoaW5nIHNhbmVcbiAgdGEoU2NoZW1lQ29sb24sIGdyb3Vwcy5kb21haW4sIFVybCQxKTtcbiAgdHQoU2NoZW1lQ29sb24sIFNMQVNILCBVcmwkMSk7XG4gIHR0KFNjaGVtZUNvbG9uLCBRVUVSWSwgVXJsJDEpO1xuICB0YShVcmlQcmVmaXgsIGdyb3Vwcy5kb21haW4sIFVybCQxKTtcbiAgdGEoVXJpUHJlZml4LCBxc0FjY2VwdGluZywgVXJsJDEpO1xuICB0dChVcmlQcmVmaXgsIFNMQVNILCBVcmwkMSk7XG4gIGNvbnN0IGJyYWNrZXRQYWlycyA9IFtbT1BFTkJSQUNFLCBDTE9TRUJSQUNFXSxcbiAgLy8ge31cbiAgW09QRU5CUkFDS0VULCBDTE9TRUJSQUNLRVRdLFxuICAvLyBbXVxuICBbT1BFTlBBUkVOLCBDTE9TRVBBUkVOXSxcbiAgLy8gKClcbiAgW09QRU5BTkdMRUJSQUNLRVQsIENMT1NFQU5HTEVCUkFDS0VUXSxcbiAgLy8gPD5cbiAgW0ZVTExXSURUSExFRlRQQVJFTiwgRlVMTFdJRFRIUklHSFRQQVJFTl0sXG4gIC8vIFx1RkYwOFx1RkYwOVxuICBbTEVGVENPUk5FUkJSQUNLRVQsIFJJR0hUQ09STkVSQlJBQ0tFVF0sXG4gIC8vIFx1MzAwQ1x1MzAwRFxuICBbTEVGVFdISVRFQ09STkVSQlJBQ0tFVCwgUklHSFRXSElURUNPUk5FUkJSQUNLRVRdLFxuICAvLyBcdTMwMEVcdTMwMEZcbiAgW0ZVTExXSURUSExFU1NUSEFOLCBGVUxMV0lEVEhHUkVBVEVSVEhBTl0gLy8gXHVGRjFDXHVGRjFFXG4gIF07XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnJhY2tldFBhaXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgW09QRU4sIENMT1NFXSA9IGJyYWNrZXRQYWlyc1tpXTtcbiAgICBjb25zdCBVcmxPcGVuID0gdHQoVXJsJDEsIE9QRU4pOyAvLyBVUkwgZm9sbG93ZWQgYnkgb3BlbiBicmFja2V0XG5cbiAgICAvLyBDb250aW51ZSBub3QgYWNjZXB0aW5nIGZvciBvcGVuIGJyYWNrZXRzXG4gICAgdHQoVXJsTm9uYWNjZXB0LCBPUEVOLCBVcmxPcGVuKTtcblxuICAgIC8vIFVSTCB0aGF0IGJlZ2lucyB3aXRoIGFuIG9wZW5pbmcgYnJhY2tldCwgZm9sbG93ZWQgYnkgYSBzeW1ib2xzLlxuICAgIC8vIE5vdGUgdGhhdCB0aGUgZmluYWwgc3RhdGUgY2FuIHN0aWxsIGJlIGBVcmxPcGVuYCAoaWYgdGhlIFVSTCBoYXMgYVxuICAgIC8vIHNpbmdsZSBvcGVuaW5nIGJyYWNrZXQgZm9yIHNvbWUgcmVhc29uKS5cbiAgICBjb25zdCBVcmxPcGVuUSA9IG1ha2VTdGF0ZShVcmwpO1xuICAgIHRhKFVybE9wZW4sIHFzQWNjZXB0aW5nLCBVcmxPcGVuUSk7XG4gICAgY29uc3QgVXJsT3BlblN5bXMgPSBtYWtlU3RhdGUoKTsgLy8gVXJsT3BlbiBmb2xsb3dlZCBieSBzb21lIHN5bWJvbHMgaXQgY2Fubm90IGVuZCBpdFxuICAgIHRhKFVybE9wZW4sIHFzTm9uQWNjZXB0aW5nLCBVcmxPcGVuU3ltcyk7XG5cbiAgICAvLyBDbG9zaW5nIGJyYWNrZXQgY29tcG9uZW50LiBUaGlzIGNoYXJhY3RlciBXSUxMIGJlIGluY2x1ZGVkIGluIHRoZSBVUkwuXG4gICAgLy8gTXVzdCBjb21lIGFmdGVyIHFzTm9uQWNjZXB0aW5nICh3aGljaCBpbmNsdWRlcyBhbGwgY2xvc2UtYnJhY2tldCB0b2tlbnMpXG4gICAgLy8gc28gdGhhdCBDTE9TRSAtPiBVcmwgd2lucyBvdmVyIENMT1NFIC0+IFVybE9wZW5TeW1zLlxuICAgIHR0KFVybE9wZW4sIENMT1NFLCBVcmwkMSk7XG5cbiAgICAvLyBVUkwgdGhhdCBiZWdpbnMgd2l0aCBhbiBvcGVuaW5nIGJyYWNrZXQsIGZvbGxvd2VkIGJ5IHNvbWUgc3ltYm9sc1xuICAgIHRhKFVybE9wZW5RLCBxc0FjY2VwdGluZywgVXJsT3BlblEpO1xuICAgIHRhKFVybE9wZW5RLCBxc05vbkFjY2VwdGluZywgVXJsT3BlblN5bXMpO1xuICAgIHRhKFVybE9wZW5TeW1zLCBxc0FjY2VwdGluZywgVXJsT3BlblEpO1xuICAgIHRhKFVybE9wZW5TeW1zLCBxc05vbkFjY2VwdGluZywgVXJsT3BlblN5bXMpO1xuXG4gICAgLy8gQ2xvc2UgYnJhY2UvYnJhY2tldCB0byBiZWNvbWUgcmVndWxhciBVUkxcbiAgICB0dChVcmxPcGVuUSwgQ0xPU0UsIFVybCQxKTtcbiAgICB0dChVcmxPcGVuU3ltcywgQ0xPU0UsIFVybCQxKTtcbiAgfVxuICB0dChTdGFydCwgTE9DQUxIT1NULCBEb21haW5Eb3RUbGQpOyAvLyBsb2NhbGhvc3QgaXMgYSB2YWxpZCBVUkwgc3RhdGVcbiAgdHQoU3RhcnQsIE5MLCBObCk7IC8vIHNpbmdsZSBuZXcgbGluZVxuXG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IFN0YXJ0LFxuICAgIHRva2VuczogdGtcbiAgfTtcbn1cblxuLyoqXG4gKiBSdW4gdGhlIHBhcnNlciBzdGF0ZSBtYWNoaW5lIG9uIGEgbGlzdCBvZiBzY2FubmVkIHN0cmluZy1iYXNlZCB0b2tlbnMgdG9cbiAqIGNyZWF0ZSBhIGxpc3Qgb2YgbXVsdGkgdG9rZW5zLCBlYWNoIG9mIHdoaWNoIHJlcHJlc2VudHMgYSBVUkwsIGVtYWlsIGFkZHJlc3MsXG4gKiBwbGFpbiB0ZXh0LCBldGMuXG4gKlxuICogQHBhcmFtIHtTdGF0ZTxNdWx0aVRva2VuPn0gc3RhcnQgcGFyc2VyIHN0YXJ0IHN0YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgdGhlIG9yaWdpbmFsIGlucHV0IHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGdpdmVuIHRva2Vuc1xuICogQHBhcmFtIHtUb2tlbltdfSB0b2tlbnMgbGlzdCBvZiBzY2FubmVkIHRva2Vuc1xuICogQHJldHVybnMge011bHRpVG9rZW5bXX1cbiAqL1xuZnVuY3Rpb24gcnVuKHN0YXJ0LCBpbnB1dCwgdG9rZW5zKSB7XG4gIGxldCBsZW4gPSB0b2tlbnMubGVuZ3RoO1xuICBsZXQgY3Vyc29yID0gMDtcbiAgbGV0IG11bHRpcyA9IFtdO1xuICBsZXQgdGV4dFRva2VucyA9IFtdO1xuICB3aGlsZSAoY3Vyc29yIDwgbGVuKSB7XG4gICAgbGV0IHN0YXRlID0gc3RhcnQ7XG4gICAgbGV0IHNlY29uZFN0YXRlID0gbnVsbDtcbiAgICBsZXQgbmV4dFN0YXRlID0gbnVsbDtcbiAgICBsZXQgbXVsdGlMZW5ndGggPSAwO1xuICAgIGxldCBsYXRlc3RBY2NlcHRpbmcgPSBudWxsO1xuICAgIGxldCBzaW5jZUFjY2VwdHMgPSAtMTtcbiAgICB3aGlsZSAoY3Vyc29yIDwgbGVuICYmICEoc2Vjb25kU3RhdGUgPSBzdGF0ZS5nbyh0b2tlbnNbY3Vyc29yXS50KSkpIHtcbiAgICAgIC8vIFN0YXJ0aW5nIHRva2VucyB3aXRoIG5vd2hlcmUgdG8ganVtcCB0by5cbiAgICAgIC8vIENvbnNpZGVyIHRoZXNlIHRvIGJlIGp1c3QgcGxhaW4gdGV4dFxuICAgICAgdGV4dFRva2Vucy5wdXNoKHRva2Vuc1tjdXJzb3IrK10pO1xuICAgIH1cbiAgICB3aGlsZSAoY3Vyc29yIDwgbGVuICYmIChuZXh0U3RhdGUgPSBzZWNvbmRTdGF0ZSB8fCBzdGF0ZS5nbyh0b2tlbnNbY3Vyc29yXS50KSkpIHtcbiAgICAgIC8vIEdldCB0aGUgbmV4dCBzdGF0ZVxuICAgICAgc2Vjb25kU3RhdGUgPSBudWxsO1xuICAgICAgc3RhdGUgPSBuZXh0U3RhdGU7XG5cbiAgICAgIC8vIEtlZXAgdHJhY2sgb2YgdGhlIGxhdGVzdCBhY2NlcHRpbmcgc3RhdGVcbiAgICAgIGlmIChzdGF0ZS5hY2NlcHRzKCkpIHtcbiAgICAgICAgc2luY2VBY2NlcHRzID0gMDtcbiAgICAgICAgbGF0ZXN0QWNjZXB0aW5nID0gc3RhdGU7XG4gICAgICB9IGVsc2UgaWYgKHNpbmNlQWNjZXB0cyA+PSAwKSB7XG4gICAgICAgIHNpbmNlQWNjZXB0cysrO1xuICAgICAgfVxuICAgICAgY3Vyc29yKys7XG4gICAgICBtdWx0aUxlbmd0aCsrO1xuICAgIH1cbiAgICBpZiAoc2luY2VBY2NlcHRzIDwgMCkge1xuICAgICAgLy8gTm8gYWNjZXB0aW5nIHN0YXRlIHdhcyBmb3VuZCwgcGFydCBvZiBhIHJlZ3VsYXIgdGV4dCB0b2tlbiBhZGRcbiAgICAgIC8vIHRoZSBmaXJzdCB0ZXh0IHRva2VuIHRvIHRoZSB0ZXh0IHRva2VucyBhcnJheSBhbmQgdHJ5IGFnYWluIGZyb21cbiAgICAgIC8vIHRoZSBuZXh0XG4gICAgICBjdXJzb3IgLT0gbXVsdGlMZW5ndGg7XG4gICAgICBpZiAoY3Vyc29yIDwgbGVuKSB7XG4gICAgICAgIHRleHRUb2tlbnMucHVzaCh0b2tlbnNbY3Vyc29yXSk7XG4gICAgICAgIGN1cnNvcisrO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBBY2NlcHRpbmcgc3RhdGUhXG4gICAgICAvLyBGaXJzdCBjbG9zZSBvZmYgdGhlIHRleHRUb2tlbnMgKGlmIGF2YWlsYWJsZSlcbiAgICAgIGlmICh0ZXh0VG9rZW5zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbXVsdGlzLnB1c2goaW5pdE11bHRpVG9rZW4oVGV4dCwgaW5wdXQsIHRleHRUb2tlbnMpKTtcbiAgICAgICAgdGV4dFRva2VucyA9IFtdO1xuICAgICAgfVxuXG4gICAgICAvLyBSb2xsIGJhY2sgdG8gdGhlIGxhdGVzdCBhY2NlcHRpbmcgc3RhdGVcbiAgICAgIGN1cnNvciAtPSBzaW5jZUFjY2VwdHM7XG4gICAgICBtdWx0aUxlbmd0aCAtPSBzaW5jZUFjY2VwdHM7XG5cbiAgICAgIC8vIENyZWF0ZSBhIG5ldyBtdWx0aXRva2VuXG4gICAgICBjb25zdCBNdWx0aSA9IGxhdGVzdEFjY2VwdGluZy50O1xuICAgICAgY29uc3Qgc3VidG9rZW5zID0gdG9rZW5zLnNsaWNlKGN1cnNvciAtIG11bHRpTGVuZ3RoLCBjdXJzb3IpO1xuICAgICAgbXVsdGlzLnB1c2goaW5pdE11bHRpVG9rZW4oTXVsdGksIGlucHV0LCBzdWJ0b2tlbnMpKTtcbiAgICB9XG4gIH1cblxuICAvLyBGaW5hbGx5IGNsb3NlIG9mZiB0aGUgdGV4dFRva2VucyAoaWYgYXZhaWxhYmxlKVxuICBpZiAodGV4dFRva2Vucy5sZW5ndGggPiAwKSB7XG4gICAgbXVsdGlzLnB1c2goaW5pdE11bHRpVG9rZW4oVGV4dCwgaW5wdXQsIHRleHRUb2tlbnMpKTtcbiAgfVxuICByZXR1cm4gbXVsdGlzO1xufVxuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gZm9yIGluc3RhbnRpYXRpbmcgYSBuZXcgbXVsdGl0b2tlbiB3aXRoIGFsbCB0aGUgcmVsZXZhbnRcbiAqIGZpZWxkcyBkdXJpbmcgcGFyc2luZy5cbiAqIEBwYXJhbSB7bmV3ICh2YWx1ZTogc3RyaW5nLCB0b2tlbnM6IFRva2VuW10pID0+IE11bHRpVG9rZW59IE11bHRpIGNsYXNzIHRvIGluc3RhbnRpYXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgb3JpZ2luYWwgaW5wdXQgc3RyaW5nXG4gKiBAcGFyYW0ge1Rva2VuW119IHRva2VucyBjb25zZWN1dGl2ZSB0b2tlbnMgc2Nhbm5lZCBmcm9tIGlucHV0IHN0cmluZ1xuICogQHJldHVybnMge011bHRpVG9rZW59XG4gKi9cbmZ1bmN0aW9uIGluaXRNdWx0aVRva2VuKE11bHRpLCBpbnB1dCwgdG9rZW5zKSB7XG4gIGNvbnN0IHN0YXJ0SWR4ID0gdG9rZW5zWzBdLnM7XG4gIGNvbnN0IGVuZElkeCA9IHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV0uZTtcbiAgY29uc3QgdmFsdWUgPSBpbnB1dC5zbGljZShzdGFydElkeCwgZW5kSWR4KTtcbiAgcmV0dXJuIG5ldyBNdWx0aSh2YWx1ZSwgdG9rZW5zKTtcbn1cblxuY29uc3Qgd2FybiA9IHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJiBjb25zb2xlICYmIGNvbnNvbGUud2FybiB8fCAoKCkgPT4ge30pO1xuY29uc3Qgd2FybkFkdmljZSA9ICd1bnRpbCBtYW51YWwgY2FsbCBvZiBsaW5raWZ5LmluaXQoKS4gUmVnaXN0ZXIgYWxsIHNjaGVtZXMgYW5kIHBsdWdpbnMgYmVmb3JlIGludm9raW5nIGxpbmtpZnkgdGhlIGZpcnN0IHRpbWUuJztcblxuLy8gU2lkZS1lZmZlY3QgaW5pdGlhbGl6YXRpb24gc3RhdGVcbmNvbnN0IElOSVQgPSB7XG4gIHNjYW5uZXI6IG51bGwsXG4gIHBhcnNlcjogbnVsbCxcbiAgdG9rZW5RdWV1ZTogW10sXG4gIHBsdWdpblF1ZXVlOiBbXSxcbiAgY3VzdG9tU2NoZW1lczogW10sXG4gIGluaXRpYWxpemVkOiBmYWxzZVxufTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7e1xuICogXHRzdGFydDogU3RhdGU8c3RyaW5nPixcbiAqIFx0dG9rZW5zOiB7IGdyb3VwczogQ29sbGVjdGlvbnM8c3RyaW5nPiB9ICYgdHlwZW9mIHRrXG4gKiB9fSBTY2FubmVySW5pdFxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge3tcbiAqIFx0c3RhcnQ6IFN0YXRlPE11bHRpVG9rZW4+LFxuICogXHR0b2tlbnM6IHR5cGVvZiBtdWx0aVxuICogfX0gUGFyc2VySW5pdFxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgeyhhcmc6IHsgc2Nhbm5lcjogU2Nhbm5lckluaXQgfSkgPT4gdm9pZH0gVG9rZW5QbHVnaW5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHsoYXJnOiB7IHNjYW5uZXI6IFNjYW5uZXJJbml0LCBwYXJzZXI6IFBhcnNlckluaXQgfSkgPT4gdm9pZH0gUGx1Z2luXG4gKi9cblxuLyoqXG4gKiBEZS1yZWdpc3RlciBhbGwgcGx1Z2lucyBhbmQgcmVzZXQgdGhlIGludGVybmFsIHN0YXRlLW1hY2hpbmUuIFVzZWQgZm9yXG4gKiB0ZXN0aW5nOyBub3QgcmVxdWlyZWQgaW4gcHJhY3RpY2UuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiByZXNldCgpIHtcbiAgU3RhdGUuZ3JvdXBzID0ge307XG4gIElOSVQuc2Nhbm5lciA9IG51bGw7XG4gIElOSVQucGFyc2VyID0gbnVsbDtcbiAgSU5JVC50b2tlblF1ZXVlID0gW107XG4gIElOSVQucGx1Z2luUXVldWUgPSBbXTtcbiAgSU5JVC5jdXN0b21TY2hlbWVzID0gW107XG4gIElOSVQuaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgcmV0dXJuIElOSVQ7XG59XG5cbi8qKlxuICogUmVnaXN0ZXIgYSB0b2tlbiBwbHVnaW4gdG8gYWxsb3cgdGhlIHNjYW5uZXIgdG8gcmVjb2duaXplIGFkZGl0aW9uYWwgdG9rZW5cbiAqIHR5cGVzIGJlZm9yZSB0aGUgcGFyc2VyIHN0YXRlIG1hY2hpbmUgaXMgY29uc3RydWN0ZWQgZnJvbSB0aGUgcmVzdWx0cy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIG9mIHBsdWdpbiB0byByZWdpc3RlclxuICogQHBhcmFtIHtUb2tlblBsdWdpbn0gcGx1Z2luIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyB0aGUgc2Nhbm5lciBzdGF0ZSBtYWNoaW5lXG4gKiBhbmQgYXZhaWxhYmxlIHNjYW5uZXIgdG9rZW5zIGFuZCBjb2xsZWN0aW9ucyBhbmQgZXh0ZW5kcyB0aGUgc3RhdGUgbWFjaGluZSB0b1xuICogcmVjb2duaXplIGFkZGl0aW9uYWwgdG9rZW5zIG9yIGdyb3Vwcy5cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJUb2tlblBsdWdpbihuYW1lLCBwbHVnaW4pIHtcbiAgaWYgKHR5cGVvZiBwbHVnaW4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGxpbmtpZnlqczogSW52YWxpZCB0b2tlbiBwbHVnaW4gJHtwbHVnaW59IChleHBlY3RzIGZ1bmN0aW9uKWApO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgSU5JVC50b2tlblF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKG5hbWUgPT09IElOSVQudG9rZW5RdWV1ZVtpXVswXSkge1xuICAgICAgd2FybihgbGlua2lmeWpzOiB0b2tlbiBwbHVnaW4gXCIke25hbWV9XCIgYWxyZWFkeSByZWdpc3RlcmVkIC0gd2lsbCBiZSBvdmVyd3JpdHRlbmApO1xuICAgICAgSU5JVC50b2tlblF1ZXVlW2ldID0gW25hbWUsIHBsdWdpbl07XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG4gIElOSVQudG9rZW5RdWV1ZS5wdXNoKFtuYW1lLCBwbHVnaW5dKTtcbiAgaWYgKElOSVQuaW5pdGlhbGl6ZWQpIHtcbiAgICB3YXJuKGBsaW5raWZ5anM6IGFscmVhZHkgaW5pdGlhbGl6ZWQgLSB3aWxsIG5vdCByZWdpc3RlciB0b2tlbiBwbHVnaW4gXCIke25hbWV9XCIgJHt3YXJuQWR2aWNlfWApO1xuICB9XG59XG5cbi8qKlxuICogUmVnaXN0ZXIgYSBsaW5raWZ5IHBsdWdpblxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgb2YgcGx1Z2luIHRvIHJlZ2lzdGVyXG4gKiBAcGFyYW0ge1BsdWdpbn0gcGx1Z2luIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyB0aGUgcGFyc2VyIHN0YXRlIG1hY2hpbmUgYW5kXG4gKiBleHRlbmRzIHRoZSBwYXJzZXIgdG8gcmVjb2duaXplIGFkZGl0aW9uYWwgbGluayB0eXBlc1xuICovXG5mdW5jdGlvbiByZWdpc3RlclBsdWdpbihuYW1lLCBwbHVnaW4pIHtcbiAgaWYgKHR5cGVvZiBwbHVnaW4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGxpbmtpZnlqczogSW52YWxpZCBwbHVnaW4gJHtwbHVnaW59IChleHBlY3RzIGZ1bmN0aW9uKWApO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgSU5JVC5wbHVnaW5RdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChuYW1lID09PSBJTklULnBsdWdpblF1ZXVlW2ldWzBdKSB7XG4gICAgICB3YXJuKGBsaW5raWZ5anM6IHBsdWdpbiBcIiR7bmFtZX1cIiBhbHJlYWR5IHJlZ2lzdGVyZWQgLSB3aWxsIGJlIG92ZXJ3cml0dGVuYCk7XG4gICAgICBJTklULnBsdWdpblF1ZXVlW2ldID0gW25hbWUsIHBsdWdpbl07XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG4gIElOSVQucGx1Z2luUXVldWUucHVzaChbbmFtZSwgcGx1Z2luXSk7XG4gIGlmIChJTklULmluaXRpYWxpemVkKSB7XG4gICAgd2FybihgbGlua2lmeWpzOiBhbHJlYWR5IGluaXRpYWxpemVkIC0gd2lsbCBub3QgcmVnaXN0ZXIgcGx1Z2luIFwiJHtuYW1lfVwiICR7d2FybkFkdmljZX1gKTtcbiAgfVxufVxuXG4vKipcbiAqIERldGVjdCBVUkxzIHdpdGggdGhlIGZvbGxvd2luZyBhZGRpdGlvbmFsIHByb3RvY29sLiBBbnl0aGluZyB3aXRoIGZvcm1hdFxuICogXCJwcm90b2NvbDovLy4uLlwiIHdpbGwgYmUgY29uc2lkZXJlZCBhIGxpbmsuIElmIGBvcHRpb25hbFNsYXNoU2xhc2hgIGlzIHNldCB0b1xuICogYHRydWVgLCBhbnl0aGluZyB3aXRoIGZvcm1hdCBcInByb3RvY29sOi4uLlwiIHdpbGwgYmUgY29uc2lkZXJlZCBhIGxpbmsuXG4gKiBAcGFyYW0ge3N0cmluZ30gc2NoZW1lXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25hbFNsYXNoU2xhc2hdXG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyQ3VzdG9tUHJvdG9jb2woc2NoZW1lLCBvcHRpb25hbFNsYXNoU2xhc2ggPSBmYWxzZSkge1xuICBpZiAoSU5JVC5pbml0aWFsaXplZCkge1xuICAgIHdhcm4oYGxpbmtpZnlqczogYWxyZWFkeSBpbml0aWFsaXplZCAtIHdpbGwgbm90IHJlZ2lzdGVyIGN1c3RvbSBzY2hlbWUgXCIke3NjaGVtZX1cIiAke3dhcm5BZHZpY2V9YCk7XG4gIH1cbiAgaWYgKCEvXlswLTlhLXpdKygtWzAtOWEtel0rKSokLy50ZXN0KHNjaGVtZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGxpbmtpZnlqczogaW5jb3JyZWN0IHNjaGVtZSBmb3JtYXQuXG4xLiBNdXN0IG9ubHkgY29udGFpbiBkaWdpdHMsIGxvd2VyY2FzZSBBU0NJSSBsZXR0ZXJzIG9yIFwiLVwiXG4yLiBDYW5ub3Qgc3RhcnQgb3IgZW5kIHdpdGggXCItXCJcbjMuIFwiLVwiIGNhbm5vdCByZXBlYXRgKTtcbiAgfVxuICBJTklULmN1c3RvbVNjaGVtZXMucHVzaChbc2NoZW1lLCBvcHRpb25hbFNsYXNoU2xhc2hdKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBsaW5raWZ5IHN0YXRlIG1hY2hpbmUuIENhbGxlZCBhdXRvbWF0aWNhbGx5IHRoZSBmaXJzdCB0aW1lXG4gKiBsaW5raWZ5IGlzIGNhbGxlZCBvbiBhIHN0cmluZywgYnV0IG1heSBiZSBjYWxsZWQgbWFudWFsbHkgYXMgd2VsbC5cbiAqL1xuZnVuY3Rpb24gaW5pdCgpIHtcbiAgLy8gSW5pdGlhbGl6ZSBzY2FubmVyIHN0YXRlIG1hY2hpbmUgYW5kIHBsdWdpbnNcbiAgSU5JVC5zY2FubmVyID0gaW5pdCQyKElOSVQuY3VzdG9tU2NoZW1lcyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgSU5JVC50b2tlblF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgSU5JVC50b2tlblF1ZXVlW2ldWzFdKHtcbiAgICAgIHNjYW5uZXI6IElOSVQuc2Nhbm5lclxuICAgIH0pO1xuICB9XG5cbiAgLy8gSW5pdGlhbGl6ZSBwYXJzZXIgc3RhdGUgbWFjaGluZSBhbmQgcGx1Z2luc1xuICBJTklULnBhcnNlciA9IGluaXQkMShJTklULnNjYW5uZXIudG9rZW5zKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBJTklULnBsdWdpblF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgSU5JVC5wbHVnaW5RdWV1ZVtpXVsxXSh7XG4gICAgICBzY2FubmVyOiBJTklULnNjYW5uZXIsXG4gICAgICBwYXJzZXI6IElOSVQucGFyc2VyXG4gICAgfSk7XG4gIH1cbiAgSU5JVC5pbml0aWFsaXplZCA9IHRydWU7XG4gIHJldHVybiBJTklUO1xufVxuXG4vKipcbiAqIFBhcnNlIGEgc3RyaW5nIGludG8gdG9rZW5zIHRoYXQgcmVwcmVzZW50IGxpbmthYmxlIGFuZCBub24tbGlua2FibGUgc3ViLWNvbXBvbmVudHNcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge011bHRpVG9rZW5bXX0gdG9rZW5zXG4gKi9cbmZ1bmN0aW9uIHRva2VuaXplKHN0cikge1xuICBpZiAoIUlOSVQuaW5pdGlhbGl6ZWQpIHtcbiAgICBpbml0KCk7XG4gIH1cbiAgcmV0dXJuIHJ1bihJTklULnBhcnNlci5zdGFydCwgc3RyLCBydW4kMShJTklULnNjYW5uZXIuc3RhcnQsIHN0cikpO1xufVxudG9rZW5pemUuc2NhbiA9IHJ1biQxOyAvLyBmb3IgdGVzdGluZ1xuXG4vKipcbiAqIEZpbmQgYSBsaXN0IG9mIGxpbmthYmxlIGl0ZW1zIGluIHRoZSBnaXZlbiBzdHJpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIHN0cmluZyB0byBmaW5kIGxpbmtzIGluXG4gKiBAcGFyYW0ge3N0cmluZyB8IE9wdHN9IFt0eXBlXSBlaXRoZXIgZm9ybWF0dGluZyBvcHRpb25zIG9yIHNwZWNpZmljIHR5cGUgb2ZcbiAqIGxpbmtzIHRvIGZpbmQsIGUuZy4sICd1cmwnIG9yICdlbWFpbCdcbiAqIEBwYXJhbSB7T3B0c30gW29wdHNdIGZvcm1hdHRpbmcgb3B0aW9ucyBmb3IgZmluYWwgb3V0cHV0LiBDYW5ub3QgYmUgc3BlY2lmaWVkXG4gKiBpZiBvcHRzIGFscmVhZHkgcHJvdmlkZWQgaW4gYHR5cGVgIGFyZ3VtZW50XG4gKi9cbmZ1bmN0aW9uIGZpbmQoc3RyLCB0eXBlID0gbnVsbCwgb3B0cyA9IG51bGwpIHtcbiAgaWYgKHR5cGUgJiYgdHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgaWYgKG9wdHMpIHtcbiAgICAgIHRocm93IEVycm9yKGBsaW5raWZ5anM6IEludmFsaWQgbGluayB0eXBlICR7dHlwZX07IG11c3QgYmUgYSBzdHJpbmdgKTtcbiAgICB9XG4gICAgb3B0cyA9IHR5cGU7XG4gICAgdHlwZSA9IG51bGw7XG4gIH1cbiAgY29uc3Qgb3B0aW9ucyA9IG5ldyBPcHRpb25zKG9wdHMpO1xuICBjb25zdCB0b2tlbnMgPSB0b2tlbml6ZShzdHIpO1xuICBjb25zdCBmaWx0ZXJlZCA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHRva2VuID0gdG9rZW5zW2ldO1xuICAgIGlmICh0b2tlbi5pc0xpbmsgJiYgKCF0eXBlIHx8IHRva2VuLnQgPT09IHR5cGUpICYmIG9wdGlvbnMuY2hlY2sodG9rZW4pKSB7XG4gICAgICBmaWx0ZXJlZC5wdXNoKHRva2VuLnRvRm9ybWF0dGVkT2JqZWN0KG9wdGlvbnMpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZpbHRlcmVkO1xufVxuXG4vKipcbiAqIElzIHRoZSBnaXZlbiBzdHJpbmcgdmFsaWQgbGlua2FibGUgdGV4dCBvZiBzb21lIHNvcnQuIE5vdGUgdGhhdCB0aGlzIGRvZXMgbm90XG4gKiB0cmltIHRoZSB0ZXh0IGZvciB5b3UuXG4gKlxuICogT3B0aW9uYWxseSBwYXNzIGluIGEgc2Vjb25kIGB0eXBlYCBwYXJhbSwgd2hpY2ggaXMgdGhlIHR5cGUgb2YgbGluayB0byB0ZXN0XG4gKiBmb3IuXG4gKlxuICogRm9yIGV4YW1wbGUsXG4gKlxuICogICAgIGxpbmtpZnkudGVzdChzdHIsICdlbWFpbCcpO1xuICpcbiAqIFJldHVybnMgYHRydWVgIGlmIHN0ciBpcyBhIHZhbGlkIGVtYWlsLlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciBzdHJpbmcgdG8gdGVzdCBmb3IgbGlua3NcbiAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZV0gb3B0aW9uYWwgc3BlY2lmaWMgbGluayB0eXBlIHRvIGxvb2sgZm9yXG4gKiBAcmV0dXJucyBib29sZWFuIHRydWUvZmFsc2VcbiAqL1xuZnVuY3Rpb24gdGVzdChzdHIsIHR5cGUgPSBudWxsKSB7XG4gIGNvbnN0IHRva2VucyA9IHRva2VuaXplKHN0cik7XG4gIHJldHVybiB0b2tlbnMubGVuZ3RoID09PSAxICYmIHRva2Vuc1swXS5pc0xpbmsgJiYgKCF0eXBlIHx8IHRva2Vuc1swXS50ID09PSB0eXBlKTtcbn1cblxuZXhwb3J0IHsgTXVsdGlUb2tlbiwgT3B0aW9ucywgU3RhdGUsIGNyZWF0ZVRva2VuQ2xhc3MsIGZpbmQsIGluaXQsIG11bHRpLCBvcHRpb25zLCByZWdleHAsIHJlZ2lzdGVyQ3VzdG9tUHJvdG9jb2wsIHJlZ2lzdGVyUGx1Z2luLCByZWdpc3RlclRva2VuUGx1Z2luLCByZXNldCwgc3RyaW5nVG9BcnJheSwgdGVzdCwgbXVsdGkgYXMgdGV4dCwgdG9rZW5pemUgfTtcbiIsICJpbXBvcnQgdHlwZSB7IFBhc3RlUnVsZU1hdGNoIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHsgTWFyaywgbWFya1Bhc3RlUnVsZSwgbWVyZ2VBdHRyaWJ1dGVzIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHR5cGUgeyBQbHVnaW4gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHsgZmluZCwgcmVnaXN0ZXJDdXN0b21Qcm90b2NvbCwgcmVzZXQgfSBmcm9tICdsaW5raWZ5anMnXG5cbmltcG9ydCB7IGF1dG9saW5rIH0gZnJvbSAnLi9oZWxwZXJzL2F1dG9saW5rLmpzJ1xuaW1wb3J0IHsgY2xpY2tIYW5kbGVyIH0gZnJvbSAnLi9oZWxwZXJzL2NsaWNrSGFuZGxlci5qcydcbmltcG9ydCB7IHBhc3RlSGFuZGxlciB9IGZyb20gJy4vaGVscGVycy9wYXN0ZUhhbmRsZXIuanMnXG5pbXBvcnQgeyBVTklDT0RFX1dISVRFU1BBQ0VfUkVHRVhfR0xPQkFMIH0gZnJvbSAnLi9oZWxwZXJzL3doaXRlc3BhY2UuanMnXG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlua1Byb3RvY29sT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgcHJvdG9jb2wgc2NoZW1lIHRvIGJlIHJlZ2lzdGVyZWQuXG4gICAqIEBkZWZhdWx0ICcnJ1xuICAgKiBAZXhhbXBsZSAnZnRwJ1xuICAgKiBAZXhhbXBsZSAnZ2l0J1xuICAgKi9cbiAgc2NoZW1lOiBzdHJpbmdcblxuICAvKipcbiAgICogSWYgZW5hYmxlZCwgaXQgYWxsb3dzIG9wdGlvbmFsIHNsYXNoZXMgYWZ0ZXIgdGhlIHByb3RvY29sLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKiBAZXhhbXBsZSB0cnVlXG4gICAqL1xuICBvcHRpb25hbFNsYXNoZXM/OiBib29sZWFuXG59XG5cbmV4cG9ydCBjb25zdCBwYXN0ZVJlZ2V4ID1cbiAgL2h0dHBzPzpcXC9cXC8oPzp3d3dcXC4pP1stYS16QS1aMC05QDolLl8rfiM9XXsxLDI1Nn1cXC5bYS16QS1aXXsyLH1cXGIoPzpbLWEtekEtWjAtOUA6JS5fK34jPT8hJi9dKikoPzpbLWEtekEtWjAtOUA6JS5fK34jPT8hJi9dKikvZ2lcblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBUaGUgZGVmYXVsdCBiZWhhdmlvciBpcyBub3cgdG8gb3BlbiBsaW5rcyB3aGVuIHRoZSBlZGl0b3IgaXMgbm90IGVkaXRhYmxlLlxuICovXG50eXBlIERlcHJlY2F0ZWRPcGVuV2hlbk5vdEVkaXRhYmxlID0gJ3doZW5Ob3RFZGl0YWJsZSdcblxuZXhwb3J0IGludGVyZmFjZSBMaW5rT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBJZiBlbmFibGVkLCB0aGUgZXh0ZW5zaW9uIHdpbGwgYXV0b21hdGljYWxseSBhZGQgbGlua3MgYXMgeW91IHR5cGUuXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICogQGV4YW1wbGUgZmFsc2VcbiAgICovXG4gIGF1dG9saW5rOiBib29sZWFuXG5cbiAgLyoqXG4gICAqIEFuIGFycmF5IG9mIGN1c3RvbSBwcm90b2NvbHMgdG8gYmUgcmVnaXN0ZXJlZCB3aXRoIGxpbmtpZnlqcy5cbiAgICogQGRlZmF1bHQgW11cbiAgICogQGV4YW1wbGUgWydmdHAnLCAnZ2l0J11cbiAgICovXG4gIHByb3RvY29sczogQXJyYXk8TGlua1Byb3RvY29sT3B0aW9ucyB8IHN0cmluZz5cblxuICAvKipcbiAgICogRGVmYXVsdCBwcm90b2NvbCB0byB1c2Ugd2hlbiBubyBwcm90b2NvbCBpcyBzcGVjaWZpZWQuXG4gICAqIEBkZWZhdWx0ICdodHRwJ1xuICAgKi9cbiAgZGVmYXVsdFByb3RvY29sOiBzdHJpbmdcbiAgLyoqXG4gICAqIElmIGVuYWJsZWQsIGxpbmtzIHdpbGwgYmUgb3BlbmVkIG9uIGNsaWNrLlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqIEBleGFtcGxlIGZhbHNlXG4gICAqL1xuICBvcGVuT25DbGljazogYm9vbGVhbiB8IERlcHJlY2F0ZWRPcGVuV2hlbk5vdEVkaXRhYmxlXG4gIC8qKlxuICAgKiBJZiBlbmFibGVkLCB0aGUgbGluayB3aWxsIGJlIHNlbGVjdGVkIHdoZW4gY2xpY2tlZC5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGV4YW1wbGUgdHJ1ZVxuICAgKi9cbiAgZW5hYmxlQ2xpY2tTZWxlY3Rpb246IGJvb2xlYW5cbiAgLyoqXG4gICAqIEFkZHMgYSBsaW5rIHRvIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpZiB0aGUgcGFzdGVkIGNvbnRlbnQgb25seSBjb250YWlucyBhbiB1cmwuXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICogQGV4YW1wbGUgZmFsc2VcbiAgICovXG4gIGxpbmtPblBhc3RlOiBib29sZWFuXG5cbiAgLyoqXG4gICAqIEhUTUwgYXR0cmlidXRlcyB0byBhZGQgdG8gdGhlIGxpbmsgZWxlbWVudC5cbiAgICogQGRlZmF1bHQge31cbiAgICogQGV4YW1wbGUgeyBjbGFzczogJ2ZvbycgfVxuICAgKi9cbiAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT5cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBgc2hvdWxkQXV0b0xpbmtgIG9wdGlvbiBpbnN0ZWFkLlxuICAgKiBBIHZhbGlkYXRpb24gZnVuY3Rpb24gdGhhdCBtb2RpZmllcyBsaW5rIHZlcmlmaWNhdGlvbiBmb3IgdGhlIGF1dG8gbGlua2VyLlxuICAgKiBAcGFyYW0gdXJsIC0gVGhlIHVybCB0byBiZSB2YWxpZGF0ZWQuXG4gICAqIEByZXR1cm5zIC0gVHJ1ZSBpZiB0aGUgdXJsIGlzIHZhbGlkLCBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICB2YWxpZGF0ZTogKHVybDogc3RyaW5nKSA9PiBib29sZWFuXG5cbiAgLyoqXG4gICAqIEEgdmFsaWRhdGlvbiBmdW5jdGlvbiB3aGljaCBpcyB1c2VkIGZvciBjb25maWd1cmluZyBsaW5rIHZlcmlmaWNhdGlvbiBmb3IgcHJldmVudGluZyBYU1MgYXR0YWNrcy5cbiAgICogT25seSBtb2RpZnkgdGhpcyBpZiB5b3Uga25vdyB3aGF0IHlvdSdyZSBkb2luZy5cbiAgICpcbiAgICogQHJldHVybnMge2Jvb2xlYW59IGB0cnVlYCBpZiB0aGUgVVJMIGlzIHZhbGlkLCBgZmFsc2VgIG90aGVyd2lzZS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogaXNBbGxvd2VkVXJpOiAodXJsLCB7IGRlZmF1bHRWYWxpZGF0ZSwgcHJvdG9jb2xzLCBkZWZhdWx0UHJvdG9jb2wgfSkgPT4ge1xuICAgKiByZXR1cm4gdXJsLnN0YXJ0c1dpdGgoJy4vJykgfHwgZGVmYXVsdFZhbGlkYXRlKHVybClcbiAgICogfVxuICAgKi9cbiAgaXNBbGxvd2VkVXJpOiAoXG4gICAgLyoqXG4gICAgICogVGhlIFVSTCB0byBiZSB2YWxpZGF0ZWQuXG4gICAgICovXG4gICAgdXJsOiBzdHJpbmcsXG4gICAgY3R4OiB7XG4gICAgICAvKipcbiAgICAgICAqIFRoZSBkZWZhdWx0IHZhbGlkYXRpb24gZnVuY3Rpb24uXG4gICAgICAgKi9cbiAgICAgIGRlZmF1bHRWYWxpZGF0ZTogKHVybDogc3RyaW5nKSA9PiBib29sZWFuXG4gICAgICAvKipcbiAgICAgICAqIEFuIGFycmF5IG9mIGFsbG93ZWQgcHJvdG9jb2xzIGZvciB0aGUgVVJMIChlLmcuLCBcImh0dHBcIiwgXCJodHRwc1wiKS4gQXMgZGVmaW5lZCBpbiB0aGUgYHByb3RvY29sc2Agb3B0aW9uLlxuICAgICAgICovXG4gICAgICBwcm90b2NvbHM6IEFycmF5PExpbmtQcm90b2NvbE9wdGlvbnMgfCBzdHJpbmc+XG4gICAgICAvKipcbiAgICAgICAqIEEgc3RyaW5nIHRoYXQgcmVwcmVzZW50cyB0aGUgZGVmYXVsdCBwcm90b2NvbCAoZS5nLiwgJ2h0dHAnKS4gQXMgZGVmaW5lZCBpbiB0aGUgYGRlZmF1bHRQcm90b2NvbGAgb3B0aW9uLlxuICAgICAgICovXG4gICAgICBkZWZhdWx0UHJvdG9jb2w6IHN0cmluZ1xuICAgIH0sXG4gICkgPT4gYm9vbGVhblxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgYSB2YWxpZCBsaW5rIHNob3VsZCBiZSBhdXRvbWF0aWNhbGx5IGxpbmtlZCBpbiB0aGUgY29udGVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVybCAtIFRoZSBVUkwgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIHZhbGlkYXRlZC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gVHJ1ZSBpZiB0aGUgbGluayBzaG91bGQgYmUgYXV0by1saW5rZWQ7IGZhbHNlIGlmIGl0IHNob3VsZCBub3QgYmUgYXV0by1saW5rZWQuXG4gICAqL1xuICBzaG91bGRBdXRvTGluazogKHVybDogc3RyaW5nKSA9PiBib29sZWFuXG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBsaW5rOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNldCBhIGxpbmsgbWFya1xuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGxpbmsgYXR0cmlidXRlc1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldExpbmsoeyBocmVmOiAnaHR0cHM6Ly90aXB0YXAuZGV2JyB9KVxuICAgICAgICovXG4gICAgICBzZXRMaW5rOiAoYXR0cmlidXRlczoge1xuICAgICAgICBocmVmOiBzdHJpbmdcbiAgICAgICAgdGFyZ2V0Pzogc3RyaW5nIHwgbnVsbFxuICAgICAgICByZWw/OiBzdHJpbmcgfCBudWxsXG4gICAgICAgIGNsYXNzPzogc3RyaW5nIHwgbnVsbFxuICAgICAgICB0aXRsZT86IHN0cmluZyB8IG51bGxcbiAgICAgIH0pID0+IFJldHVyblR5cGVcbiAgICAgIC8qKlxuICAgICAgICogVG9nZ2xlIGEgbGluayBtYXJrXG4gICAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgbGluayBhdHRyaWJ1dGVzXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudG9nZ2xlTGluayh7IGhyZWY6ICdodHRwczovL3RpcHRhcC5kZXYnIH0pXG4gICAgICAgKi9cbiAgICAgIHRvZ2dsZUxpbms6IChhdHRyaWJ1dGVzPzoge1xuICAgICAgICBocmVmOiBzdHJpbmdcbiAgICAgICAgdGFyZ2V0Pzogc3RyaW5nIHwgbnVsbFxuICAgICAgICByZWw/OiBzdHJpbmcgfCBudWxsXG4gICAgICAgIGNsYXNzPzogc3RyaW5nIHwgbnVsbFxuICAgICAgICB0aXRsZT86IHN0cmluZyB8IG51bGxcbiAgICAgIH0pID0+IFJldHVyblR5cGVcbiAgICAgIC8qKlxuICAgICAgICogVW5zZXQgYSBsaW5rIG1hcmtcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy51bnNldExpbmsoKVxuICAgICAgICovXG4gICAgICB1bnNldExpbms6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQWxsb3dlZFVyaSh1cmk6IHN0cmluZyB8IHVuZGVmaW5lZCwgcHJvdG9jb2xzPzogTGlua09wdGlvbnNbJ3Byb3RvY29scyddKSB7XG4gIGNvbnN0IGFsbG93ZWRQcm90b2NvbHM6IHN0cmluZ1tdID0gW1xuICAgICdodHRwJyxcbiAgICAnaHR0cHMnLFxuICAgICdmdHAnLFxuICAgICdmdHBzJyxcbiAgICAnbWFpbHRvJyxcbiAgICAndGVsJyxcbiAgICAnY2FsbHRvJyxcbiAgICAnc21zJyxcbiAgICAnY2lkJyxcbiAgICAneG1wcCcsXG4gIF1cblxuICBpZiAocHJvdG9jb2xzKSB7XG4gICAgcHJvdG9jb2xzLmZvckVhY2gocHJvdG9jb2wgPT4ge1xuICAgICAgY29uc3QgbmV4dFByb3RvY29sID0gdHlwZW9mIHByb3RvY29sID09PSAnc3RyaW5nJyA/IHByb3RvY29sIDogcHJvdG9jb2wuc2NoZW1lXG5cbiAgICAgIGlmIChuZXh0UHJvdG9jb2wpIHtcbiAgICAgICAgYWxsb3dlZFByb3RvY29scy5wdXNoKG5leHRQcm90b2NvbClcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIChcbiAgICAhdXJpIHx8XG4gICAgdXJpLnJlcGxhY2UoVU5JQ09ERV9XSElURVNQQUNFX1JFR0VYX0dMT0JBTCwgJycpLm1hdGNoKFxuICAgICAgbmV3IFJlZ0V4cChcbiAgICAgICAgLy8gb3hsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZWxlc3MtZXNjYXBlXG4gICAgICAgIGBeKD86KD86JHthbGxvd2VkUHJvdG9jb2xzLmpvaW4oJ3wnKX0pOnxbXmEtel18W2EtejAtOSsuXFwtXSsoPzpbXmEteisuXFwtOl18JCkpYCxcbiAgICAgICAgJ2knLFxuICAgICAgKSxcbiAgICApXG4gIClcbn1cblxuLyoqXG4gKiBUaGlzIGV4dGVuc2lvbiBhbGxvd3MgeW91IHRvIGNyZWF0ZSBsaW5rcy5cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvbWFya3MvbGlua1xuICovXG5leHBvcnQgY29uc3QgTGluayA9IE1hcmsuY3JlYXRlPExpbmtPcHRpb25zPih7XG4gIG5hbWU6ICdsaW5rJyxcblxuICBwcmlvcml0eTogMTAwMCxcblxuICBrZWVwT25TcGxpdDogZmFsc2UsXG5cbiAgZXhpdGFibGU6IHRydWUsXG5cbiAgb25DcmVhdGUoKSB7XG4gICAgLy8gVE9ETzogdjQgLSByZW1vdmUgdmFsaWRhdGUgb3B0aW9uXG4gICAgaWYgKHRoaXMub3B0aW9ucy52YWxpZGF0ZSAmJiAhdGhpcy5vcHRpb25zLnNob3VsZEF1dG9MaW5rKSB7XG4gICAgICAvLyBDb3B5IHRoZSB2YWxpZGF0ZSBmdW5jdGlvbiB0byB0aGUgc2hvdWxkQXV0b0xpbmsgb3B0aW9uXG4gICAgICB0aGlzLm9wdGlvbnMuc2hvdWxkQXV0b0xpbmsgPSB0aGlzLm9wdGlvbnMudmFsaWRhdGVcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgJ1RoZSBgdmFsaWRhdGVgIG9wdGlvbiBpcyBkZXByZWNhdGVkLiBSZW5hbWUgdG8gdGhlIGBzaG91bGRBdXRvTGlua2Agb3B0aW9uIGluc3RlYWQuJyxcbiAgICAgIClcbiAgICB9XG4gICAgdGhpcy5vcHRpb25zLnByb3RvY29scy5mb3JFYWNoKHByb3RvY29sID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcHJvdG9jb2wgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJlZ2lzdGVyQ3VzdG9tUHJvdG9jb2wocHJvdG9jb2wpXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgcmVnaXN0ZXJDdXN0b21Qcm90b2NvbChwcm90b2NvbC5zY2hlbWUsIHByb3RvY29sLm9wdGlvbmFsU2xhc2hlcylcbiAgICB9KVxuICB9LFxuXG4gIG9uRGVzdHJveSgpIHtcbiAgICByZXNldCgpXG4gIH0sXG5cbiAgaW5jbHVzaXZlKCkge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMuYXV0b2xpbmtcbiAgfSxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBvcGVuT25DbGljazogdHJ1ZSxcbiAgICAgIGVuYWJsZUNsaWNrU2VsZWN0aW9uOiBmYWxzZSxcbiAgICAgIGxpbmtPblBhc3RlOiB0cnVlLFxuICAgICAgYXV0b2xpbms6IHRydWUsXG4gICAgICBwcm90b2NvbHM6IFtdLFxuICAgICAgZGVmYXVsdFByb3RvY29sOiAnaHR0cCcsXG4gICAgICBIVE1MQXR0cmlidXRlczoge1xuICAgICAgICB0YXJnZXQ6ICdfYmxhbmsnLFxuICAgICAgICByZWw6ICdub29wZW5lciBub3JlZmVycmVyIG5vZm9sbG93JyxcbiAgICAgICAgY2xhc3M6IG51bGwsXG4gICAgICB9LFxuICAgICAgaXNBbGxvd2VkVXJpOiAodXJsLCBjdHgpID0+ICEhaXNBbGxvd2VkVXJpKHVybCwgY3R4LnByb3RvY29scyksXG4gICAgICB2YWxpZGF0ZTogdXJsID0+ICEhdXJsLFxuICAgICAgc2hvdWxkQXV0b0xpbms6IHVybCA9PiB7XG4gICAgICAgIC8vIFVSTHMgd2l0aCBleHBsaWNpdCBwcm90b2NvbHMgKGUuZy4sIGh0dHBzOi8vKSBzaG91bGQgYmUgYXV0by1saW5rZWRcbiAgICAgICAgLy8gQnV0IG5vdCBpZiBAIGFwcGVhcnMgYmVmb3JlIDovLyAodGhhdCB3b3VsZCBiZSB1c2VyaW5mbyBsaWtlIHVzZXI6cGFzc0Bob3N0KVxuICAgICAgICBjb25zdCBoYXNQcm90b2NvbCA9IC9eW2Etel1bYS16MC05Ky4tXSo6XFwvXFwvL2kudGVzdCh1cmwpXG4gICAgICAgIGNvbnN0IGhhc01heWJlUHJvdG9jb2wgPSAvXlthLXpdW2EtejAtOSsuLV0qOi9pLnRlc3QodXJsKVxuXG4gICAgICAgIGlmIChoYXNQcm90b2NvbCB8fCAoaGFzTWF5YmVQcm90b2NvbCAmJiAhdXJsLmluY2x1ZGVzKCdAJykpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuICAgICAgICAvLyBTdHJpcCB1c2VyaW5mbyAodXNlcjpwYXNzQCkgaWYgcHJlc2VudCwgdGhlbiBleHRyYWN0IGhvc3RuYW1lXG4gICAgICAgIGNvbnN0IHVybFdpdGhvdXRVc2VyaW5mbyA9IHVybC5pbmNsdWRlcygnQCcpID8gdXJsLnNwbGl0KCdAJykucG9wKCkhIDogdXJsXG4gICAgICAgIGNvbnN0IGhvc3RuYW1lID0gdXJsV2l0aG91dFVzZXJpbmZvLnNwbGl0KC9bLz8jOl0vKVswXVxuXG4gICAgICAgIC8vIERvbid0IGF1dG8tbGluayBJUCBhZGRyZXNzZXMgd2l0aG91dCBwcm90b2NvbFxuICAgICAgICBpZiAoL15cXGR7MSwzfShcXC5cXGR7MSwzfSl7M30kLy50ZXN0KGhvc3RuYW1lKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICAgIC8vIERvbid0IGF1dG8tbGluayBzaW5nbGUtd29yZCBob3N0bmFtZXMgd2l0aG91dCBUTEQgKGUuZy4sIFwibG9jYWxob3N0XCIpXG4gICAgICAgIGlmICghL1xcLi8udGVzdChob3N0bmFtZSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaHJlZjoge1xuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgICBwYXJzZUhUTUwoZWxlbWVudCkge1xuICAgICAgICAgIHJldHVybiBlbGVtZW50LmdldEF0dHJpYnV0ZSgnaHJlZicpXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgdGFyZ2V0OiB7XG4gICAgICAgIGRlZmF1bHQ6IHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcy50YXJnZXQsXG4gICAgICB9LFxuICAgICAgcmVsOiB7XG4gICAgICAgIGRlZmF1bHQ6IHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcy5yZWwsXG4gICAgICB9LFxuICAgICAgY2xhc3M6IHtcbiAgICAgICAgZGVmYXVsdDogdGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLmNsYXNzLFxuICAgICAgfSxcbiAgICAgIHRpdGxlOiB7XG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgIH1cbiAgfSxcblxuICBwYXJzZUhUTUwoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgdGFnOiAnYVtocmVmXScsXG4gICAgICAgIGdldEF0dHJzOiBkb20gPT4ge1xuICAgICAgICAgIGNvbnN0IGhyZWYgPSAoZG9tIGFzIEhUTUxFbGVtZW50KS5nZXRBdHRyaWJ1dGUoJ2hyZWYnKVxuXG4gICAgICAgICAgLy8gcHJldmVudCBYU1MgYXR0YWNrc1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFocmVmIHx8XG4gICAgICAgICAgICAhdGhpcy5vcHRpb25zLmlzQWxsb3dlZFVyaShocmVmLCB7XG4gICAgICAgICAgICAgIGRlZmF1bHRWYWxpZGF0ZTogdXJsID0+ICEhaXNBbGxvd2VkVXJpKHVybCwgdGhpcy5vcHRpb25zLnByb3RvY29scyksXG4gICAgICAgICAgICAgIHByb3RvY29sczogdGhpcy5vcHRpb25zLnByb3RvY29scyxcbiAgICAgICAgICAgICAgZGVmYXVsdFByb3RvY29sOiB0aGlzLm9wdGlvbnMuZGVmYXVsdFByb3RvY29sLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICBdXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICAvLyBwcmV2ZW50IFhTUyBhdHRhY2tzXG4gICAgaWYgKFxuICAgICAgIXRoaXMub3B0aW9ucy5pc0FsbG93ZWRVcmkoSFRNTEF0dHJpYnV0ZXMuaHJlZiwge1xuICAgICAgICBkZWZhdWx0VmFsaWRhdGU6IGhyZWYgPT4gISFpc0FsbG93ZWRVcmkoaHJlZiwgdGhpcy5vcHRpb25zLnByb3RvY29scyksXG4gICAgICAgIHByb3RvY29sczogdGhpcy5vcHRpb25zLnByb3RvY29scyxcbiAgICAgICAgZGVmYXVsdFByb3RvY29sOiB0aGlzLm9wdGlvbnMuZGVmYXVsdFByb3RvY29sLFxuICAgICAgfSlcbiAgICApIHtcbiAgICAgIC8vIHN0cmlwIG91dCB0aGUgaHJlZlxuICAgICAgcmV0dXJuIFsnYScsIG1lcmdlQXR0cmlidXRlcyh0aGlzLm9wdGlvbnMuSFRNTEF0dHJpYnV0ZXMsIHsgLi4uSFRNTEF0dHJpYnV0ZXMsIGhyZWY6ICcnIH0pLCAwXVxuICAgIH1cblxuICAgIHJldHVybiBbJ2EnLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyksIDBdXG4gIH0sXG5cbiAgbWFya2Rvd25Ub2tlbk5hbWU6ICdsaW5rJyxcblxuICBwYXJzZU1hcmtkb3duOiAodG9rZW4sIGhlbHBlcnMpID0+IHtcbiAgICByZXR1cm4gaGVscGVycy5hcHBseU1hcmsoJ2xpbmsnLCBoZWxwZXJzLnBhcnNlSW5saW5lKHRva2VuLnRva2VucyB8fCBbXSksIHtcbiAgICAgIGhyZWY6IHRva2VuLmhyZWYsXG4gICAgICB0aXRsZTogdG9rZW4udGl0bGUgfHwgbnVsbCxcbiAgICB9KVxuICB9LFxuXG4gIHJlbmRlck1hcmtkb3duOiAobm9kZSwgaCkgPT4ge1xuICAgIGNvbnN0IGhyZWYgPSBub2RlLmF0dHJzPy5ocmVmID8/ICcnXG4gICAgY29uc3QgdGl0bGUgPSBub2RlLmF0dHJzPy50aXRsZSA/PyAnJ1xuICAgIGNvbnN0IHRleHQgPSBoLnJlbmRlckNoaWxkcmVuKG5vZGUpXG5cbiAgICByZXR1cm4gdGl0bGUgPyBgWyR7dGV4dH1dKCR7aHJlZn0gXCIke3RpdGxlfVwiKWAgOiBgWyR7dGV4dH1dKCR7aHJlZn0pYFxuICB9LFxuXG4gIGFkZENvbW1hbmRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzZXRMaW5rOlxuICAgICAgICBhdHRyaWJ1dGVzID0+XG4gICAgICAgICh7IGNoYWluIH0pID0+IHtcbiAgICAgICAgICBjb25zdCB7IGhyZWYgfSA9IGF0dHJpYnV0ZXNcblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLm9wdGlvbnMuaXNBbGxvd2VkVXJpKGhyZWYsIHtcbiAgICAgICAgICAgICAgZGVmYXVsdFZhbGlkYXRlOiB1cmwgPT4gISFpc0FsbG93ZWRVcmkodXJsLCB0aGlzLm9wdGlvbnMucHJvdG9jb2xzKSxcbiAgICAgICAgICAgICAgcHJvdG9jb2xzOiB0aGlzLm9wdGlvbnMucHJvdG9jb2xzLFxuICAgICAgICAgICAgICBkZWZhdWx0UHJvdG9jb2w6IHRoaXMub3B0aW9ucy5kZWZhdWx0UHJvdG9jb2wsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGNoYWluKCkuc2V0TWFyayh0aGlzLm5hbWUsIGF0dHJpYnV0ZXMpLnNldE1ldGEoJ3ByZXZlbnRBdXRvbGluaycsIHRydWUpLnJ1bigpXG4gICAgICAgIH0sXG5cbiAgICAgIHRvZ2dsZUxpbms6XG4gICAgICAgIGF0dHJpYnV0ZXMgPT5cbiAgICAgICAgKHsgY2hhaW4gfSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgaHJlZiB9ID0gYXR0cmlidXRlcyB8fCB7fVxuXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgaHJlZiAmJlxuICAgICAgICAgICAgIXRoaXMub3B0aW9ucy5pc0FsbG93ZWRVcmkoaHJlZiwge1xuICAgICAgICAgICAgICBkZWZhdWx0VmFsaWRhdGU6IHVybCA9PiAhIWlzQWxsb3dlZFVyaSh1cmwsIHRoaXMub3B0aW9ucy5wcm90b2NvbHMpLFxuICAgICAgICAgICAgICBwcm90b2NvbHM6IHRoaXMub3B0aW9ucy5wcm90b2NvbHMsXG4gICAgICAgICAgICAgIGRlZmF1bHRQcm90b2NvbDogdGhpcy5vcHRpb25zLmRlZmF1bHRQcm90b2NvbCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gY2hhaW4oKVxuICAgICAgICAgICAgLnRvZ2dsZU1hcmsodGhpcy5uYW1lLCBhdHRyaWJ1dGVzLCB7IGV4dGVuZEVtcHR5TWFya1JhbmdlOiB0cnVlIH0pXG4gICAgICAgICAgICAuc2V0TWV0YSgncHJldmVudEF1dG9saW5rJywgdHJ1ZSlcbiAgICAgICAgICAgIC5ydW4oKVxuICAgICAgICB9LFxuXG4gICAgICB1bnNldExpbms6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IGNoYWluIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gY2hhaW4oKVxuICAgICAgICAgICAgLnVuc2V0TWFyayh0aGlzLm5hbWUsIHsgZXh0ZW5kRW1wdHlNYXJrUmFuZ2U6IHRydWUgfSlcbiAgICAgICAgICAgIC5zZXRNZXRhKCdwcmV2ZW50QXV0b2xpbmsnLCB0cnVlKVxuICAgICAgICAgICAgLnJ1bigpXG4gICAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZFBhc3RlUnVsZXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG1hcmtQYXN0ZVJ1bGUoe1xuICAgICAgICBmaW5kOiB0ZXh0ID0+IHtcbiAgICAgICAgICBjb25zdCBmb3VuZExpbmtzOiBQYXN0ZVJ1bGVNYXRjaFtdID0gW11cblxuICAgICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgICBjb25zdCB7IHByb3RvY29scywgZGVmYXVsdFByb3RvY29sIH0gPSB0aGlzLm9wdGlvbnNcbiAgICAgICAgICAgIGNvbnN0IGxpbmtzID0gZmluZCh0ZXh0KS5maWx0ZXIoXG4gICAgICAgICAgICAgIGl0ZW0gPT5cbiAgICAgICAgICAgICAgICBpdGVtLmlzTGluayAmJlxuICAgICAgICAgICAgICAgIHRoaXMub3B0aW9ucy5pc0FsbG93ZWRVcmkoaXRlbS52YWx1ZSwge1xuICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbGlkYXRlOiBocmVmID0+ICEhaXNBbGxvd2VkVXJpKGhyZWYsIHByb3RvY29scyksXG4gICAgICAgICAgICAgICAgICBwcm90b2NvbHMsXG4gICAgICAgICAgICAgICAgICBkZWZhdWx0UHJvdG9jb2wsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApXG5cbiAgICAgICAgICAgIGlmIChsaW5rcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgbGlua3MuZm9yRWFjaChsaW5rID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5zaG91bGRBdXRvTGluayhsaW5rLnZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZm91bmRMaW5rcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgIHRleHQ6IGxpbmsudmFsdWUsXG4gICAgICAgICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgICAgIGhyZWY6IGxpbmsuaHJlZixcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBpbmRleDogbGluay5zdGFydCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBmb3VuZExpbmtzXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgICAgZ2V0QXR0cmlidXRlczogbWF0Y2ggPT4ge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBocmVmOiBtYXRjaC5kYXRhPy5ocmVmLFxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcblxuICBhZGRQcm9zZU1pcnJvclBsdWdpbnMoKSB7XG4gICAgY29uc3QgcGx1Z2luczogUGx1Z2luW10gPSBbXVxuICAgIGNvbnN0IHsgcHJvdG9jb2xzLCBkZWZhdWx0UHJvdG9jb2wgfSA9IHRoaXMub3B0aW9uc1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hdXRvbGluaykge1xuICAgICAgcGx1Z2lucy5wdXNoKFxuICAgICAgICBhdXRvbGluayh7XG4gICAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgICAgIGRlZmF1bHRQcm90b2NvbDogdGhpcy5vcHRpb25zLmRlZmF1bHRQcm90b2NvbCxcbiAgICAgICAgICB2YWxpZGF0ZTogdXJsID0+XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMuaXNBbGxvd2VkVXJpKHVybCwge1xuICAgICAgICAgICAgICBkZWZhdWx0VmFsaWRhdGU6IGhyZWYgPT4gISFpc0FsbG93ZWRVcmkoaHJlZiwgcHJvdG9jb2xzKSxcbiAgICAgICAgICAgICAgcHJvdG9jb2xzLFxuICAgICAgICAgICAgICBkZWZhdWx0UHJvdG9jb2wsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBzaG91bGRBdXRvTGluazogdGhpcy5vcHRpb25zLnNob3VsZEF1dG9MaW5rLFxuICAgICAgICB9KSxcbiAgICAgIClcbiAgICB9XG5cbiAgICBwbHVnaW5zLnB1c2goXG4gICAgICBjbGlja0hhbmRsZXIoe1xuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICAgIGVkaXRvcjogdGhpcy5lZGl0b3IsXG4gICAgICAgIG9wZW5PbkNsaWNrOlxuICAgICAgICAgIHRoaXMub3B0aW9ucy5vcGVuT25DbGljayA9PT0gJ3doZW5Ob3RFZGl0YWJsZScgPyB0cnVlIDogdGhpcy5vcHRpb25zLm9wZW5PbkNsaWNrLFxuICAgICAgICBlbmFibGVDbGlja1NlbGVjdGlvbjogdGhpcy5vcHRpb25zLmVuYWJsZUNsaWNrU2VsZWN0aW9uLFxuICAgICAgfSksXG4gICAgKVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5saW5rT25QYXN0ZSkge1xuICAgICAgcGx1Z2lucy5wdXNoKFxuICAgICAgICBwYXN0ZUhhbmRsZXIoe1xuICAgICAgICAgIGVkaXRvcjogdGhpcy5lZGl0b3IsXG4gICAgICAgICAgZGVmYXVsdFByb3RvY29sOiB0aGlzLm9wdGlvbnMuZGVmYXVsdFByb3RvY29sLFxuICAgICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgICAgICBzaG91bGRBdXRvTGluazogdGhpcy5vcHRpb25zLnNob3VsZEF1dG9MaW5rLFxuICAgICAgICB9KSxcbiAgICAgIClcbiAgICB9XG5cbiAgICByZXR1cm4gcGx1Z2luc1xuICB9LFxufSlcbiIsICJpbXBvcnQgdHlwZSB7IE5vZGVXaXRoUG9zIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHtcbiAgY29tYmluZVRyYW5zYWN0aW9uU3RlcHMsXG4gIGZpbmRDaGlsZHJlbkluUmFuZ2UsXG4gIGdldENoYW5nZWRSYW5nZXMsXG4gIGdldE1hcmtzQmV0d2Vlbixcbn0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHR5cGUgeyBNYXJrVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBQbHVnaW4sIFBsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgdHlwZSB7IE11bHRpVG9rZW4gfSBmcm9tICdsaW5raWZ5anMnXG5pbXBvcnQgeyB0b2tlbml6ZSB9IGZyb20gJ2xpbmtpZnlqcydcblxuaW1wb3J0IHsgVU5JQ09ERV9XSElURVNQQUNFX1JFR0VYLCBVTklDT0RFX1dISVRFU1BBQ0VfUkVHRVhfRU5EIH0gZnJvbSAnLi93aGl0ZXNwYWNlLmpzJ1xuXG4vKipcbiAqIENoZWNrIGlmIHRoZSBwcm92aWRlZCB0b2tlbnMgZm9ybSBhIHZhbGlkIGxpbmsgc3RydWN0dXJlLCB3aGljaCBjYW4gZWl0aGVyIGJlIGEgc2luZ2xlIGxpbmsgdG9rZW5cbiAqIG9yIGEgbGluayB0b2tlbiBzdXJyb3VuZGVkIGJ5IHBhcmVudGhlc2VzIG9yIHNxdWFyZSBicmFja2V0cy5cbiAqXG4gKiBUaGlzIGVuc3VyZXMgdGhhdCBvbmx5IGNvbXBsZXRlIGFuZCB2YWxpZCB0ZXh0IGlzIGh5cGVybGlua2VkLCBwcmV2ZW50aW5nIGNhc2VzIHdoZXJlIGEgdmFsaWRcbiAqIHRvcC1sZXZlbCBkb21haW4gKFRMRCkgaXMgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgYW4gaW52YWxpZCBjaGFyYWN0ZXIsIGxpa2UgYSBudW1iZXIuIEZvclxuICogZXhhbXBsZSwgd2l0aCB0aGUgYGZpbmRgIG1ldGhvZCBmcm9tIExpbmtpZnksIGVudGVyaW5nIGBleGFtcGxlLmNvbTFgIHdvdWxkIHJlc3VsdCBpblxuICogYGV4YW1wbGUuY29tYCBiZWluZyBsaW5rZWQgYW5kIHRoZSB0cmFpbGluZyBgMWAgbGVmdCBhcyBwbGFpbiB0ZXh0LiBCeSB1c2luZyB0aGUgYHRva2VuaXplYFxuICogbWV0aG9kLCB3ZSBjYW4gcGVyZm9ybSBtb3JlIGNvbXByZWhlbnNpdmUgdmFsaWRhdGlvbiBvbiB0aGUgaW5wdXQgdGV4dC5cbiAqL1xuZnVuY3Rpb24gaXNWYWxpZExpbmtTdHJ1Y3R1cmUodG9rZW5zOiBBcnJheTxSZXR1cm5UeXBlPE11bHRpVG9rZW5bJ3RvT2JqZWN0J10+Pikge1xuICBpZiAodG9rZW5zLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiB0b2tlbnNbMF0uaXNMaW5rXG4gIH1cblxuICBpZiAodG9rZW5zLmxlbmd0aCA9PT0gMyAmJiB0b2tlbnNbMV0uaXNMaW5rKSB7XG4gICAgcmV0dXJuIFsnKCknLCAnW10nXS5pbmNsdWRlcyh0b2tlbnNbMF0udmFsdWUgKyB0b2tlbnNbMl0udmFsdWUpXG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cblxudHlwZSBBdXRvbGlua09wdGlvbnMgPSB7XG4gIHR5cGU6IE1hcmtUeXBlXG4gIGRlZmF1bHRQcm90b2NvbDogc3RyaW5nXG4gIHZhbGlkYXRlOiAodXJsOiBzdHJpbmcpID0+IGJvb2xlYW5cbiAgc2hvdWxkQXV0b0xpbms6ICh1cmw6IHN0cmluZykgPT4gYm9vbGVhblxufVxuXG4vKipcbiAqIFRoaXMgcGx1Z2luIGFsbG93cyB5b3UgdG8gYXV0b21hdGljYWxseSBhZGQgbGlua3MgdG8geW91ciBlZGl0b3IuXG4gKiBAcGFyYW0gb3B0aW9ucyBUaGUgcGx1Z2luIG9wdGlvbnNcbiAqIEByZXR1cm5zIFRoZSBwbHVnaW4gaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF1dG9saW5rKG9wdGlvbnM6IEF1dG9saW5rT3B0aW9ucyk6IFBsdWdpbiB7XG4gIHJldHVybiBuZXcgUGx1Z2luKHtcbiAgICBrZXk6IG5ldyBQbHVnaW5LZXkoJ2F1dG9saW5rJyksXG4gICAgYXBwZW5kVHJhbnNhY3Rpb246ICh0cmFuc2FjdGlvbnMsIG9sZFN0YXRlLCBuZXdTdGF0ZSkgPT4ge1xuICAgICAgLyoqXG4gICAgICAgKiBEb2VzIHRoZSB0cmFuc2FjdGlvbiBjaGFuZ2UgdGhlIGRvY3VtZW50P1xuICAgICAgICovXG4gICAgICBjb25zdCBkb2NDaGFuZ2VzID1cbiAgICAgICAgdHJhbnNhY3Rpb25zLnNvbWUodHJhbnNhY3Rpb24gPT4gdHJhbnNhY3Rpb24uZG9jQ2hhbmdlZCkgJiYgIW9sZFN0YXRlLmRvYy5lcShuZXdTdGF0ZS5kb2MpXG5cbiAgICAgIC8qKlxuICAgICAgICogUHJldmVudCBhdXRvbGluayBpZiB0aGUgdHJhbnNhY3Rpb24gaXMgbm90IGEgZG9jdW1lbnQgY2hhbmdlIG9yIGlmIHRoZSB0cmFuc2FjdGlvbiBoYXMgdGhlIG1ldGEgYHByZXZlbnRBdXRvbGlua2AuXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IHByZXZlbnRBdXRvbGluayA9IHRyYW5zYWN0aW9ucy5zb21lKHRyYW5zYWN0aW9uID0+XG4gICAgICAgIHRyYW5zYWN0aW9uLmdldE1ldGEoJ3ByZXZlbnRBdXRvbGluaycpLFxuICAgICAgKVxuXG4gICAgICAvKipcbiAgICAgICAqIFByZXZlbnQgYXV0b2xpbmsgaWYgdGhlIHRyYW5zYWN0aW9uIGlzIG5vdCBhIGRvY3VtZW50IGNoYW5nZVxuICAgICAgICogb3IgaWYgdGhlIHRyYW5zYWN0aW9uIGhhcyB0aGUgbWV0YSBgcHJldmVudEF1dG9saW5rYC5cbiAgICAgICAqL1xuICAgICAgaWYgKCFkb2NDaGFuZ2VzIHx8IHByZXZlbnRBdXRvbGluaykge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgY29uc3QgeyB0ciB9ID0gbmV3U3RhdGVcbiAgICAgIGNvbnN0IHRyYW5zZm9ybSA9IGNvbWJpbmVUcmFuc2FjdGlvblN0ZXBzKG9sZFN0YXRlLmRvYywgWy4uLnRyYW5zYWN0aW9uc10pXG4gICAgICBjb25zdCBjaGFuZ2VzID0gZ2V0Q2hhbmdlZFJhbmdlcyh0cmFuc2Zvcm0pXG5cbiAgICAgIGNoYW5nZXMuZm9yRWFjaCgoeyBuZXdSYW5nZSB9KSA9PiB7XG4gICAgICAgIC8vIE5vdyBsZXTigJlzIHNlZSBpZiB3ZSBjYW4gYWRkIG5ldyBsaW5rcy5cbiAgICAgICAgY29uc3Qgbm9kZXNJbkNoYW5nZWRSYW5nZXMgPSBmaW5kQ2hpbGRyZW5JblJhbmdlKFxuICAgICAgICAgIG5ld1N0YXRlLmRvYyxcbiAgICAgICAgICBuZXdSYW5nZSxcbiAgICAgICAgICBub2RlID0+IG5vZGUuaXNUZXh0YmxvY2ssXG4gICAgICAgIClcblxuICAgICAgICBsZXQgdGV4dEJsb2NrOiBOb2RlV2l0aFBvcyB8IHVuZGVmaW5lZFxuICAgICAgICBsZXQgdGV4dEJlZm9yZVdoaXRlc3BhY2U6IHN0cmluZyB8IHVuZGVmaW5lZFxuXG4gICAgICAgIGlmIChub2Rlc0luQ2hhbmdlZFJhbmdlcy5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgLy8gR3JhYiB0aGUgZmlyc3Qgbm9kZSB3aXRoaW4gdGhlIGNoYW5nZWQgcmFuZ2VzIChleC4gdGhlIGZpcnN0IG9mIHR3byBwYXJhZ3JhcGhzIHdoZW4gaGl0dGluZyBlbnRlcikuXG4gICAgICAgICAgdGV4dEJsb2NrID0gbm9kZXNJbkNoYW5nZWRSYW5nZXNbMF1cbiAgICAgICAgICB0ZXh0QmVmb3JlV2hpdGVzcGFjZSA9IG5ld1N0YXRlLmRvYy50ZXh0QmV0d2VlbihcbiAgICAgICAgICAgIHRleHRCbG9jay5wb3MsXG4gICAgICAgICAgICB0ZXh0QmxvY2sucG9zICsgdGV4dEJsb2NrLm5vZGUubm9kZVNpemUsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAnICcsXG4gICAgICAgICAgKVxuICAgICAgICB9IGVsc2UgaWYgKG5vZGVzSW5DaGFuZ2VkUmFuZ2VzLmxlbmd0aCkge1xuICAgICAgICAgIGNvbnN0IGVuZFRleHQgPSBuZXdTdGF0ZS5kb2MudGV4dEJldHdlZW4obmV3UmFuZ2UuZnJvbSwgbmV3UmFuZ2UudG8sICcgJywgJyAnKVxuICAgICAgICAgIGlmICghVU5JQ09ERV9XSElURVNQQUNFX1JFR0VYX0VORC50ZXN0KGVuZFRleHQpKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG4gICAgICAgICAgdGV4dEJsb2NrID0gbm9kZXNJbkNoYW5nZWRSYW5nZXNbMF1cbiAgICAgICAgICB0ZXh0QmVmb3JlV2hpdGVzcGFjZSA9IG5ld1N0YXRlLmRvYy50ZXh0QmV0d2VlbihcbiAgICAgICAgICAgIHRleHRCbG9jay5wb3MsXG4gICAgICAgICAgICBuZXdSYW5nZS50byxcbiAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICcgJyxcbiAgICAgICAgICApXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGV4dEJsb2NrICYmIHRleHRCZWZvcmVXaGl0ZXNwYWNlKSB7XG4gICAgICAgICAgY29uc3Qgd29yZHNCZWZvcmVXaGl0ZXNwYWNlID0gdGV4dEJlZm9yZVdoaXRlc3BhY2VcbiAgICAgICAgICAgIC5zcGxpdChVTklDT0RFX1dISVRFU1BBQ0VfUkVHRVgpXG4gICAgICAgICAgICAuZmlsdGVyKEJvb2xlYW4pXG5cbiAgICAgICAgICBpZiAod29yZHNCZWZvcmVXaGl0ZXNwYWNlLmxlbmd0aCA8PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBsYXN0V29yZEJlZm9yZVNwYWNlID0gd29yZHNCZWZvcmVXaGl0ZXNwYWNlW3dvcmRzQmVmb3JlV2hpdGVzcGFjZS5sZW5ndGggLSAxXVxuICAgICAgICAgIGNvbnN0IGxhc3RXb3JkQW5kQmxvY2tPZmZzZXQgPVxuICAgICAgICAgICAgdGV4dEJsb2NrLnBvcyArIHRleHRCZWZvcmVXaGl0ZXNwYWNlLmxhc3RJbmRleE9mKGxhc3RXb3JkQmVmb3JlU3BhY2UpXG5cbiAgICAgICAgICBpZiAoIWxhc3RXb3JkQmVmb3JlU3BhY2UpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGxpbmtzQmVmb3JlU3BhY2UgPSB0b2tlbml6ZShsYXN0V29yZEJlZm9yZVNwYWNlKS5tYXAodCA9PlxuICAgICAgICAgICAgdC50b09iamVjdChvcHRpb25zLmRlZmF1bHRQcm90b2NvbCksXG4gICAgICAgICAgKVxuXG4gICAgICAgICAgaWYgKCFpc1ZhbGlkTGlua1N0cnVjdHVyZShsaW5rc0JlZm9yZVNwYWNlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbGlua3NCZWZvcmVTcGFjZVxuICAgICAgICAgICAgLmZpbHRlcihsaW5rID0+IGxpbmsuaXNMaW5rKVxuICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIGxpbmsgcG9zaXRpb24uXG4gICAgICAgICAgICAubWFwKGxpbmsgPT4gKHtcbiAgICAgICAgICAgICAgLi4ubGluayxcbiAgICAgICAgICAgICAgZnJvbTogbGFzdFdvcmRBbmRCbG9ja09mZnNldCArIGxpbmsuc3RhcnQgKyAxLFxuICAgICAgICAgICAgICB0bzogbGFzdFdvcmRBbmRCbG9ja09mZnNldCArIGxpbmsuZW5kICsgMSxcbiAgICAgICAgICAgIH0pKVxuICAgICAgICAgICAgLy8gaWdub3JlIGxpbmsgaW5zaWRlIGNvZGUgbWFya1xuICAgICAgICAgICAgLmZpbHRlcihsaW5rID0+IHtcbiAgICAgICAgICAgICAgaWYgKCFuZXdTdGF0ZS5zY2hlbWEubWFya3MuY29kZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICByZXR1cm4gIW5ld1N0YXRlLmRvYy5yYW5nZUhhc01hcmsobGluay5mcm9tLCBsaW5rLnRvLCBuZXdTdGF0ZS5zY2hlbWEubWFya3MuY29kZSlcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAvLyB2YWxpZGF0ZSBsaW5rXG4gICAgICAgICAgICAuZmlsdGVyKGxpbmsgPT4gb3B0aW9ucy52YWxpZGF0ZShsaW5rLnZhbHVlKSlcbiAgICAgICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgc2hvdWxkIGF1dG9saW5rXG4gICAgICAgICAgICAuZmlsdGVyKGxpbmsgPT4gb3B0aW9ucy5zaG91bGRBdXRvTGluayhsaW5rLnZhbHVlKSlcbiAgICAgICAgICAgIC8vIEFkZCBsaW5rIG1hcmsuXG4gICAgICAgICAgICAuZm9yRWFjaChsaW5rID0+IHtcbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIGdldE1hcmtzQmV0d2VlbihsaW5rLmZyb20sIGxpbmsudG8sIG5ld1N0YXRlLmRvYykuc29tZShcbiAgICAgICAgICAgICAgICAgIGl0ZW0gPT4gaXRlbS5tYXJrLnR5cGUgPT09IG9wdGlvbnMudHlwZSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgdHIuYWRkTWFyayhcbiAgICAgICAgICAgICAgICBsaW5rLmZyb20sXG4gICAgICAgICAgICAgICAgbGluay50byxcbiAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUuY3JlYXRlKHtcbiAgICAgICAgICAgICAgICAgIGhyZWY6IGxpbmsuaHJlZixcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgaWYgKCF0ci5zdGVwcy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0clxuICAgIH0sXG4gIH0pXG59XG4iLCAiLy8gRnJvbSBET01QdXJpZnlcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jdXJlNTMvRE9NUHVyaWZ5L2Jsb2IvbWFpbi9zcmMvcmVnZXhwLnRzXG5leHBvcnQgY29uc3QgVU5JQ09ERV9XSElURVNQQUNFX1BBVFRFUk4gPVxuICAnW1xcdTAwMDAtXFx1MDAyMFxcdTAwQTBcXHUxNjgwXFx1MTgwRVxcdTIwMDAtXFx1MjAyOVxcdTIwNUZcXHUzMDAwXSdcblxuZXhwb3J0IGNvbnN0IFVOSUNPREVfV0hJVEVTUEFDRV9SRUdFWCA9IG5ldyBSZWdFeHAoVU5JQ09ERV9XSElURVNQQUNFX1BBVFRFUk4pXG5leHBvcnQgY29uc3QgVU5JQ09ERV9XSElURVNQQUNFX1JFR0VYX0VORCA9IG5ldyBSZWdFeHAoYCR7VU5JQ09ERV9XSElURVNQQUNFX1BBVFRFUk59JGApXG5leHBvcnQgY29uc3QgVU5JQ09ERV9XSElURVNQQUNFX1JFR0VYX0dMT0JBTCA9IG5ldyBSZWdFeHAoVU5JQ09ERV9XSElURVNQQUNFX1BBVFRFUk4sICdnJylcbiIsICJpbXBvcnQgdHlwZSB7IEVkaXRvciB9IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB7IGdldEF0dHJpYnV0ZXMgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5pbXBvcnQgdHlwZSB7IE1hcmtUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IFBsdWdpbiwgUGx1Z2luS2V5IH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxudHlwZSBDbGlja0hhbmRsZXJPcHRpb25zID0ge1xuICB0eXBlOiBNYXJrVHlwZVxuICBlZGl0b3I6IEVkaXRvclxuICBvcGVuT25DbGljaz86IGJvb2xlYW5cbiAgZW5hYmxlQ2xpY2tTZWxlY3Rpb24/OiBib29sZWFuXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbGlja0hhbmRsZXIob3B0aW9uczogQ2xpY2tIYW5kbGVyT3B0aW9ucyk6IFBsdWdpbiB7XG4gIHJldHVybiBuZXcgUGx1Z2luKHtcbiAgICBrZXk6IG5ldyBQbHVnaW5LZXkoJ2hhbmRsZUNsaWNrTGluaycpLFxuICAgIHByb3BzOiB7XG4gICAgICBoYW5kbGVDbGljazogKHZpZXcsIHBvcywgZXZlbnQpID0+IHtcbiAgICAgICAgaWYgKGV2ZW50LmJ1dHRvbiAhPT0gMCkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF2aWV3LmVkaXRhYmxlKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbGluazogSFRNTEFuY2hvckVsZW1lbnQgfCBudWxsID0gbnVsbFxuXG4gICAgICAgIGlmIChldmVudC50YXJnZXQgaW5zdGFuY2VvZiBIVE1MQW5jaG9yRWxlbWVudCkge1xuICAgICAgICAgIGxpbmsgPSBldmVudC50YXJnZXRcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQgfCBudWxsXG4gICAgICAgICAgaWYgKCF0YXJnZXQpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHJvb3QgPSBvcHRpb25zLmVkaXRvci52aWV3LmRvbVxuXG4gICAgICAgICAgLy8gVG50ZW50aW9uYWxseSBsaW1pdCB0aGUgbG9va3VwIHRvIHRoZSBlZGl0b3Igcm9vdC5cbiAgICAgICAgICAvLyBVc2luZyB0YWcgbmFtZXMgbGlrZSBESVYgYXMgYm91bmRhcmllcyBicmVha3Mgd2l0aCBjdXN0b20gTm9kZVZpZXdzLFxuICAgICAgICAgIGxpbmsgPSB0YXJnZXQuY2xvc2VzdDxIVE1MQW5jaG9yRWxlbWVudD4oJ2EnKVxuXG4gICAgICAgICAgaWYgKGxpbmsgJiYgIXJvb3QuY29udGFpbnMobGluaykpIHtcbiAgICAgICAgICAgIGxpbmsgPSBudWxsXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFsaW5rKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICBsZXQgaGFuZGxlZCA9IGZhbHNlXG5cbiAgICAgICAgaWYgKG9wdGlvbnMuZW5hYmxlQ2xpY2tTZWxlY3Rpb24pIHtcbiAgICAgICAgICBjb25zdCBjb21tYW5kUmVzdWx0ID0gb3B0aW9ucy5lZGl0b3IuY29tbWFuZHMuZXh0ZW5kTWFya1JhbmdlKG9wdGlvbnMudHlwZS5uYW1lKVxuICAgICAgICAgIGhhbmRsZWQgPSBjb21tYW5kUmVzdWx0XG4gICAgICAgIH1cblxuICAgICAgICBpZiAob3B0aW9ucy5vcGVuT25DbGljaykge1xuICAgICAgICAgIGNvbnN0IGF0dHJzID0gZ2V0QXR0cmlidXRlcyh2aWV3LnN0YXRlLCBvcHRpb25zLnR5cGUubmFtZSlcbiAgICAgICAgICBjb25zdCBocmVmID0gbGluay5ocmVmID8/IGF0dHJzLmhyZWZcbiAgICAgICAgICBjb25zdCB0YXJnZXQgPSBsaW5rLnRhcmdldCA/PyBhdHRycy50YXJnZXRcblxuICAgICAgICAgIGlmIChocmVmKSB7XG4gICAgICAgICAgICB3aW5kb3cub3BlbihocmVmLCB0YXJnZXQpXG4gICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBoYW5kbGVkXG4gICAgICB9LFxuICAgIH0sXG4gIH0pXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBFZGl0b3IgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5pbXBvcnQgdHlwZSB7IE1hcmtUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IFBsdWdpbiwgUGx1Z2luS2V5IH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcbmltcG9ydCB7IGZpbmQgfSBmcm9tICdsaW5raWZ5anMnXG5cbmltcG9ydCB0eXBlIHsgTGlua09wdGlvbnMgfSBmcm9tICcuLi9saW5rLmpzJ1xuXG50eXBlIFBhc3RlSGFuZGxlck9wdGlvbnMgPSB7XG4gIGVkaXRvcjogRWRpdG9yXG4gIGRlZmF1bHRQcm90b2NvbDogc3RyaW5nXG4gIHR5cGU6IE1hcmtUeXBlXG4gIHNob3VsZEF1dG9MaW5rPzogTGlua09wdGlvbnNbJ3Nob3VsZEF1dG9MaW5rJ11cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhc3RlSGFuZGxlcihvcHRpb25zOiBQYXN0ZUhhbmRsZXJPcHRpb25zKTogUGx1Z2luIHtcbiAgcmV0dXJuIG5ldyBQbHVnaW4oe1xuICAgIGtleTogbmV3IFBsdWdpbktleSgnaGFuZGxlUGFzdGVMaW5rJyksXG4gICAgcHJvcHM6IHtcbiAgICAgIGhhbmRsZVBhc3RlOiAodmlldywgX2V2ZW50LCBzbGljZSkgPT4ge1xuICAgICAgICBjb25zdCB7IHNob3VsZEF1dG9MaW5rIH0gPSBvcHRpb25zXG4gICAgICAgIGNvbnN0IHsgc3RhdGUgfSA9IHZpZXdcbiAgICAgICAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IHN0YXRlXG4gICAgICAgIGNvbnN0IHsgZW1wdHkgfSA9IHNlbGVjdGlvblxuXG4gICAgICAgIGlmIChlbXB0eSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHRleHRDb250ZW50ID0gJydcblxuICAgICAgICBzbGljZS5jb250ZW50LmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgdGV4dENvbnRlbnQgKz0gbm9kZS50ZXh0Q29udGVudFxuICAgICAgICB9KVxuXG4gICAgICAgIGNvbnN0IGxpbmsgPSBmaW5kKHRleHRDb250ZW50LCB7IGRlZmF1bHRQcm90b2NvbDogb3B0aW9ucy5kZWZhdWx0UHJvdG9jb2wgfSkuZmluZChcbiAgICAgICAgICBpdGVtID0+IGl0ZW0uaXNMaW5rICYmIGl0ZW0udmFsdWUgPT09IHRleHRDb250ZW50LFxuICAgICAgICApXG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICF0ZXh0Q29udGVudCB8fFxuICAgICAgICAgICFsaW5rIHx8XG4gICAgICAgICAgKHNob3VsZEF1dG9MaW5rICE9PSB1bmRlZmluZWQgJiYgIXNob3VsZEF1dG9MaW5rKGxpbmsudmFsdWUpKVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBvcHRpb25zLmVkaXRvci5jb21tYW5kcy5zZXRNYXJrKG9wdGlvbnMudHlwZSwge1xuICAgICAgICAgIGhyZWY6IGxpbmsuaHJlZixcbiAgICAgICAgfSlcbiAgICAgIH0sXG4gICAgfSxcbiAgfSlcbn1cbiIsICJpbXBvcnQgeyBMaW5rIH0gZnJvbSAnLi9saW5rLmpzJ1xuXG5leHBvcnQgKiBmcm9tICcuL2xpbmsuanMnXG5cbmV4cG9ydCBkZWZhdWx0IExpbmtcbiIsICJpbXBvcnQgeyBtZXJnZUF0dHJpYnV0ZXMsIE5vZGUsIHdyYXBwaW5nSW5wdXRSdWxlIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5jb25zdCBMaXN0SXRlbU5hbWUgPSAnbGlzdEl0ZW0nXG5jb25zdCBUZXh0U3R5bGVOYW1lID0gJ3RleHRTdHlsZSdcblxuZXhwb3J0IGludGVyZmFjZSBCdWxsZXRMaXN0T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgbm9kZSBuYW1lIGZvciB0aGUgbGlzdCBpdGVtc1xuICAgKiBAZGVmYXVsdCAnbGlzdEl0ZW0nXG4gICAqIEBleGFtcGxlICdwYXJhZ3JhcGgnXG4gICAqL1xuICBpdGVtVHlwZU5hbWU6IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBIVE1MIGF0dHJpYnV0ZXMgdG8gYWRkIHRvIHRoZSBidWxsZXQgbGlzdCBlbGVtZW50XG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG5cbiAgLyoqXG4gICAqIEtlZXAgdGhlIG1hcmtzIHdoZW4gc3BsaXR0aW5nIHRoZSBsaXN0XG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqIEBleGFtcGxlIHRydWVcbiAgICovXG4gIGtlZXBNYXJrczogYm9vbGVhblxuXG4gIC8qKlxuICAgKiBLZWVwIHRoZSBhdHRyaWJ1dGVzIHdoZW4gc3BsaXR0aW5nIHRoZSBsaXN0XG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqIEBleGFtcGxlIHRydWVcbiAgICovXG4gIGtlZXBBdHRyaWJ1dGVzOiBib29sZWFuXG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBidWxsZXRMaXN0OiB7XG4gICAgICAvKipcbiAgICAgICAqIFRvZ2dsZSBhIGJ1bGxldCBsaXN0XG4gICAgICAgKi9cbiAgICAgIHRvZ2dsZUJ1bGxldExpc3Q6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNYXRjaGVzIGEgYnVsbGV0IGxpc3QgdG8gYSBkYXNoIG9yIGFzdGVyaXNrLlxuICovXG5leHBvcnQgY29uc3QgYnVsbGV0TGlzdElucHV0UmVnZXggPSAvXlxccyooWy0rKl0pXFxzJC9cblxuLyoqXG4gKiBUaGlzIGV4dGVuc2lvbiBhbGxvd3MgeW91IHRvIGNyZWF0ZSBidWxsZXQgbGlzdHMuXG4gKiBUaGlzIHJlcXVpcmVzIHRoZSBMaXN0SXRlbSBleHRlbnNpb25cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2FwaS9ub2Rlcy9idWxsZXQtbGlzdFxuICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvYXBpL25vZGVzL2xpc3QtaXRlbS5cbiAqL1xuZXhwb3J0IGNvbnN0IEJ1bGxldExpc3QgPSBOb2RlLmNyZWF0ZTxCdWxsZXRMaXN0T3B0aW9ucz4oe1xuICBuYW1lOiAnYnVsbGV0TGlzdCcsXG5cbiAgYWRkT3B0aW9ucygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaXRlbVR5cGVOYW1lOiAnbGlzdEl0ZW0nLFxuICAgICAgSFRNTEF0dHJpYnV0ZXM6IHt9LFxuICAgICAga2VlcE1hcmtzOiBmYWxzZSxcbiAgICAgIGtlZXBBdHRyaWJ1dGVzOiBmYWxzZSxcbiAgICB9XG4gIH0sXG5cbiAgZ3JvdXA6ICdibG9jayBsaXN0JyxcblxuICBjb250ZW50KCkge1xuICAgIHJldHVybiBgJHt0aGlzLm9wdGlvbnMuaXRlbVR5cGVOYW1lfStgXG4gIH0sXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbeyB0YWc6ICd1bCcgfV1cbiAgfSxcblxuICByZW5kZXJIVE1MKHsgSFRNTEF0dHJpYnV0ZXMgfSkge1xuICAgIHJldHVybiBbJ3VsJywgbWVyZ2VBdHRyaWJ1dGVzKHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcywgSFRNTEF0dHJpYnV0ZXMpLCAwXVxuICB9LFxuXG4gIG1hcmtkb3duVG9rZW5OYW1lOiAnbGlzdCcsXG5cbiAgcGFyc2VNYXJrZG93bjogKHRva2VuLCBoZWxwZXJzKSA9PiB7XG4gICAgaWYgKHRva2VuLnR5cGUgIT09ICdsaXN0JyB8fCAodG9rZW4gYXMgYW55KS5vcmRlcmVkKSB7XG4gICAgICByZXR1cm4gW11cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ2J1bGxldExpc3QnLFxuICAgICAgY29udGVudDogdG9rZW4uaXRlbXMgPyBoZWxwZXJzLnBhcnNlQ2hpbGRyZW4odG9rZW4uaXRlbXMpIDogW10sXG4gICAgfVxuICB9LFxuXG4gIHJlbmRlck1hcmtkb3duOiAobm9kZSwgaCkgPT4ge1xuICAgIGlmICghbm9kZS5jb250ZW50KSB7XG4gICAgICByZXR1cm4gJydcbiAgICB9XG5cbiAgICByZXR1cm4gaC5yZW5kZXJDaGlsZHJlbihub2RlLmNvbnRlbnQsICdcXG4nKVxuICB9LFxuXG4gIG1hcmtkb3duT3B0aW9uczoge1xuICAgIGluZGVudHNDb250ZW50OiB0cnVlLFxuICB9LFxuXG4gIGFkZENvbW1hbmRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICB0b2dnbGVCdWxsZXRMaXN0OlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBjb21tYW5kcywgY2hhaW4gfSkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMua2VlcEF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBjaGFpbigpXG4gICAgICAgICAgICAgIC50b2dnbGVMaXN0KHRoaXMubmFtZSwgdGhpcy5vcHRpb25zLml0ZW1UeXBlTmFtZSwgdGhpcy5vcHRpb25zLmtlZXBNYXJrcylcbiAgICAgICAgICAgICAgLnVwZGF0ZUF0dHJpYnV0ZXMoTGlzdEl0ZW1OYW1lLCB0aGlzLmVkaXRvci5nZXRBdHRyaWJ1dGVzKFRleHRTdHlsZU5hbWUpKVxuICAgICAgICAgICAgICAucnVuKClcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnRvZ2dsZUxpc3QodGhpcy5uYW1lLCB0aGlzLm9wdGlvbnMuaXRlbVR5cGVOYW1lLCB0aGlzLm9wdGlvbnMua2VlcE1hcmtzKVxuICAgICAgICB9LFxuICAgIH1cbiAgfSxcblxuICBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgJ01vZC1TaGlmdC04JzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMudG9nZ2xlQnVsbGV0TGlzdCgpLFxuICAgIH1cbiAgfSxcblxuICBhZGRJbnB1dFJ1bGVzKCkge1xuICAgIGxldCBpbnB1dFJ1bGUgPSB3cmFwcGluZ0lucHV0UnVsZSh7XG4gICAgICBmaW5kOiBidWxsZXRMaXN0SW5wdXRSZWdleCxcbiAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICB9KVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5rZWVwTWFya3MgfHwgdGhpcy5vcHRpb25zLmtlZXBBdHRyaWJ1dGVzKSB7XG4gICAgICBpbnB1dFJ1bGUgPSB3cmFwcGluZ0lucHV0UnVsZSh7XG4gICAgICAgIGZpbmQ6IGJ1bGxldExpc3RJbnB1dFJlZ2V4LFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICAgIGtlZXBNYXJrczogdGhpcy5vcHRpb25zLmtlZXBNYXJrcyxcbiAgICAgICAga2VlcEF0dHJpYnV0ZXM6IHRoaXMub3B0aW9ucy5rZWVwQXR0cmlidXRlcyxcbiAgICAgICAgZ2V0QXR0cmlidXRlczogKCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLmVkaXRvci5nZXRBdHRyaWJ1dGVzKFRleHRTdHlsZU5hbWUpXG4gICAgICAgIH0sXG4gICAgICAgIGVkaXRvcjogdGhpcy5lZGl0b3IsXG4gICAgICB9KVxuICAgIH1cbiAgICByZXR1cm4gW2lucHV0UnVsZV1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHR5cGUgeyBKU09OQ29udGVudCwgTWFya2Rvd25QYXJzZUhlbHBlcnMsIE1hcmtkb3duVG9rZW4gfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5pbXBvcnQgeyBtZXJnZUF0dHJpYnV0ZXMsIE5vZGUsIHJlbmRlck5lc3RlZE1hcmtkb3duQ29udGVudCB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuaW1wb3J0IHsgY3JlYXRlQnJhbmNoaW5nTGlzdERlbGV0ZUtleW1hcCB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlQnJhbmNoaW5nTGlzdERlbGV0ZUtleW1hcC5qcydcblxuZXhwb3J0IGludGVyZmFjZSBMaXN0SXRlbU9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIEhUTUwgYXR0cmlidXRlcyBmb3IgYSBsaXN0IGl0ZW0gbm9kZS5cbiAgICogQGRlZmF1bHQge31cbiAgICogQGV4YW1wbGUgeyBjbGFzczogJ2ZvbycgfVxuICAgKi9cbiAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT5cblxuICAvKipcbiAgICogVGhlIG5vZGUgdHlwZSBmb3IgYnVsbGV0TGlzdCBub2Rlc1xuICAgKiBAZGVmYXVsdCAnYnVsbGV0TGlzdCdcbiAgICogQGV4YW1wbGUgJ215Q3VzdG9tQnVsbGV0TGlzdCdcbiAgICovXG4gIGJ1bGxldExpc3RUeXBlTmFtZTogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSBub2RlIHR5cGUgZm9yIG9yZGVyZWRMaXN0IG5vZGVzXG4gICAqIEBkZWZhdWx0ICdvcmRlcmVkTGlzdCdcbiAgICogQGV4YW1wbGUgJ215Q3VzdG9tT3JkZXJlZExpc3QnXG4gICAqL1xuICBvcmRlcmVkTGlzdFR5cGVOYW1lOiBzdHJpbmdcbn1cblxuZnVuY3Rpb24gaXNTYW1lTGluZU9yZGVyZWRMaXN0VG9rZW4odG9rZW46IE1hcmtkb3duVG9rZW4pOiBib29sZWFuIHtcbiAgY29uc3QgbmVzdGVkVG9rZW4gPSB0b2tlbi50b2tlbnM/LlswXVxuXG4gIHJldHVybiBCb29sZWFuKFxuICAgIHRva2VuLnRleHQgJiZcbiAgICB0b2tlbi50b2tlbnM/Lmxlbmd0aCA9PT0gMSAmJlxuICAgIG5lc3RlZFRva2VuPy50eXBlID09PSAnbGlzdCcgJiZcbiAgICBuZXN0ZWRUb2tlbi5vcmRlcmVkICYmXG4gICAgbmVzdGVkVG9rZW4ucmF3ID09PSB0b2tlbi50ZXh0LFxuICApXG59XG5cbmZ1bmN0aW9uIHBhcnNlU2FtZUxpbmVPcmRlcmVkTGlzdFRleHQodGV4dDogc3RyaW5nLCBoZWxwZXJzOiBNYXJrZG93blBhcnNlSGVscGVycyk6IEpTT05Db250ZW50W10ge1xuICBpZiAoaGVscGVycy50b2tlbml6ZUlubGluZSkge1xuICAgIHJldHVybiBoZWxwZXJzLnBhcnNlSW5saW5lKGhlbHBlcnMudG9rZW5pemVJbmxpbmUodGV4dCkpXG4gIH1cblxuICByZXR1cm4gaGVscGVycy5wYXJzZUlubGluZShbXG4gICAge1xuICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgcmF3OiB0ZXh0LFxuICAgICAgdGV4dCxcbiAgICB9LFxuICBdKVxufVxuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gY3JlYXRlIGxpc3QgaXRlbXMuXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnRpcHRhcC5kZXYvYXBpL25vZGVzL2xpc3QtaXRlbVxuICovXG5leHBvcnQgY29uc3QgTGlzdEl0ZW0gPSBOb2RlLmNyZWF0ZTxMaXN0SXRlbU9wdGlvbnM+KHtcbiAgbmFtZTogJ2xpc3RJdGVtJyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBIVE1MQXR0cmlidXRlczoge30sXG4gICAgICBidWxsZXRMaXN0VHlwZU5hbWU6ICdidWxsZXRMaXN0JyxcbiAgICAgIG9yZGVyZWRMaXN0VHlwZU5hbWU6ICdvcmRlcmVkTGlzdCcsXG4gICAgfVxuICB9LFxuXG4gIGNvbnRlbnQ6ICdwYXJhZ3JhcGggYmxvY2sqJyxcblxuICBkZWZpbmluZzogdHJ1ZSxcblxuICBwYXJzZUhUTUwoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgdGFnOiAnbGknLFxuICAgICAgfSxcbiAgICBdXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICByZXR1cm4gWydsaScsIG1lcmdlQXR0cmlidXRlcyh0aGlzLm9wdGlvbnMuSFRNTEF0dHJpYnV0ZXMsIEhUTUxBdHRyaWJ1dGVzKSwgMF1cbiAgfSxcblxuICBtYXJrZG93blRva2VuTmFtZTogJ2xpc3RfaXRlbScsXG5cbiAgcGFyc2VNYXJrZG93bjogKHRva2VuLCBoZWxwZXJzKSA9PiB7XG4gICAgaWYgKHRva2VuLnR5cGUgIT09ICdsaXN0X2l0ZW0nKSB7XG4gICAgICByZXR1cm4gW11cbiAgICB9XG5cbiAgICBjb25zdCBwYXJzZUJsb2NrQ2hpbGRyZW4gPSBoZWxwZXJzLnBhcnNlQmxvY2tDaGlsZHJlbiA/PyBoZWxwZXJzLnBhcnNlQ2hpbGRyZW5cbiAgICBsZXQgY29udGVudDogYW55W10gPSBbXVxuXG4gICAgaWYgKHRva2VuLnRva2VucyAmJiB0b2tlbi50b2tlbnMubGVuZ3RoID4gMCkge1xuICAgICAgaWYgKGlzU2FtZUxpbmVPcmRlcmVkTGlzdFRva2VuKHRva2VuKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6ICdsaXN0SXRlbScsXG4gICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiAncGFyYWdyYXBoJyxcbiAgICAgICAgICAgICAgY29udGVudDogcGFyc2VTYW1lTGluZU9yZGVyZWRMaXN0VGV4dCh0b2tlbi50ZXh0IHx8ICcnLCBoZWxwZXJzKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIHBhcmFncmFwaCB0b2tlbnMgKGNvbXBsZXggbGlzdCBpdGVtcylcbiAgICAgIGNvbnN0IGhhc1BhcmFncmFwaFRva2VucyA9IHRva2VuLnRva2Vucy5zb21lKHQgPT4gdC50eXBlID09PSAncGFyYWdyYXBoJylcblxuICAgICAgaWYgKGhhc1BhcmFncmFwaFRva2Vucykge1xuICAgICAgICAvLyBJZiB3ZSBoYXZlIHBhcmFncmFwaCB0b2tlbnMsIHBhcnNlIHRoZW0gYXMgYmxvY2sgZWxlbWVudHNcbiAgICAgICAgY29udGVudCA9IHBhcnNlQmxvY2tDaGlsZHJlbih0b2tlbi50b2tlbnMpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBDaGVjayBpZiB0aGUgZmlyc3QgdG9rZW4gaXMgYSB0ZXh0IHRva2VuIHdpdGggbmVzdGVkIGlubGluZSB0b2tlbnNcbiAgICAgICAgY29uc3QgZmlyc3RUb2tlbiA9IHRva2VuLnRva2Vuc1swXVxuXG4gICAgICAgIGlmIChcbiAgICAgICAgICBmaXJzdFRva2VuICYmXG4gICAgICAgICAgZmlyc3RUb2tlbi50eXBlID09PSAndGV4dCcgJiZcbiAgICAgICAgICBmaXJzdFRva2VuLnRva2VucyAmJlxuICAgICAgICAgIGZpcnN0VG9rZW4udG9rZW5zLmxlbmd0aCA+IDBcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gUGFyc2UgdGhlIGlubGluZSBjb250ZW50IGZyb20gdGhlIHRleHQgdG9rZW5cbiAgICAgICAgICBjb25zdCBpbmxpbmVDb250ZW50ID0gaGVscGVycy5wYXJzZUlubGluZShmaXJzdFRva2VuLnRva2VucylcblxuICAgICAgICAgIC8vIFN0YXJ0IHdpdGggdGhlIHBhcmFncmFwaCBjb250YWluaW5nIHRoZSBpbmxpbmUgY29udGVudFxuICAgICAgICAgIGNvbnRlbnQgPSBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHR5cGU6ICdwYXJhZ3JhcGgnLFxuICAgICAgICAgICAgICBjb250ZW50OiBpbmxpbmVDb250ZW50LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdXG5cbiAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWRkaXRpb25hbCB0b2tlbnMgYWZ0ZXIgdGhlIGZpcnN0IHRleHQgdG9rZW4gKGxpa2UgbmVzdGVkIGxpc3RzKSxcbiAgICAgICAgICAvLyBwYXJzZSB0aGVtIGFzIGJsb2NrIGVsZW1lbnRzIGFuZCBhZGQgdGhlbVxuICAgICAgICAgIGlmICh0b2tlbi50b2tlbnMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgY29uc3QgcmVtYWluaW5nVG9rZW5zID0gdG9rZW4udG9rZW5zLnNsaWNlKDEpXG4gICAgICAgICAgICBjb25zdCBhZGRpdGlvbmFsQ29udGVudCA9IHBhcnNlQmxvY2tDaGlsZHJlbihyZW1haW5pbmdUb2tlbnMpXG4gICAgICAgICAgICBjb250ZW50LnB1c2goLi4uYWRkaXRpb25hbENvbnRlbnQpXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEZhbGxiYWNrOiBwYXJzZSBhbGwgdG9rZW5zIGFzIGJsb2NrIGVsZW1lbnRzXG4gICAgICAgICAgY29udGVudCA9IHBhcnNlQmxvY2tDaGlsZHJlbih0b2tlbi50b2tlbnMpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBFbnN1cmUgd2UgYWx3YXlzIGhhdmUgYXQgbGVhc3QgYW4gZW1wdHkgcGFyYWdyYXBoXG4gICAgaWYgKGNvbnRlbnQubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb250ZW50ID0gW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ3BhcmFncmFwaCcsXG4gICAgICAgICAgY29udGVudDogW10sXG4gICAgICAgIH0sXG4gICAgICBdXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdsaXN0SXRlbScsXG4gICAgICBjb250ZW50LFxuICAgIH1cbiAgfSxcblxuICByZW5kZXJNYXJrZG93bjogKG5vZGUsIGgsIGN0eCkgPT4ge1xuICAgIHJldHVybiByZW5kZXJOZXN0ZWRNYXJrZG93bkNvbnRlbnQoXG4gICAgICBub2RlLFxuICAgICAgaCxcbiAgICAgIChjb250ZXh0OiBhbnkpID0+IHtcbiAgICAgICAgaWYgKGNvbnRleHQucGFyZW50VHlwZSA9PT0gJ2J1bGxldExpc3QnKSB7XG4gICAgICAgICAgcmV0dXJuICctICdcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29udGV4dC5wYXJlbnRUeXBlID09PSAnb3JkZXJlZExpc3QnKSB7XG4gICAgICAgICAgY29uc3Qgc3RhcnQgPSBjb250ZXh0Lm1ldGE/LnBhcmVudEF0dHJzPy5zdGFydCB8fCAxXG4gICAgICAgICAgcmV0dXJuIGAke3N0YXJ0ICsgY29udGV4dC5pbmRleH0uIGBcbiAgICAgICAgfVxuICAgICAgICAvLyBGYWxsYmFjayB0byBidWxsZXQgbGlzdCBmb3IgdW5rbm93biBwYXJlbnQgdHlwZXNcbiAgICAgICAgcmV0dXJuICctICdcbiAgICAgIH0sXG4gICAgICBjdHgsXG4gICAgKVxuICB9LFxuXG4gIGFkZEV4dGVuc2lvbnMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIGNyZWF0ZUJyYW5jaGluZ0xpc3REZWxldGVLZXltYXAodGhpcy5uYW1lLCBbXG4gICAgICAgIHRoaXMub3B0aW9ucy5idWxsZXRMaXN0VHlwZU5hbWUsXG4gICAgICAgIHRoaXMub3B0aW9ucy5vcmRlcmVkTGlzdFR5cGVOYW1lLFxuICAgICAgXSksXG4gICAgXVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBFbnRlcjogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMuc3BsaXRMaXN0SXRlbSh0aGlzLm5hbWUpLFxuICAgICAgVGFiOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5zaW5rTGlzdEl0ZW0odGhpcy5uYW1lKSxcbiAgICAgICdTaGlmdC1UYWInOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5saWZ0TGlzdEl0ZW0odGhpcy5uYW1lKSxcbiAgICB9XG4gIH0sXG59KVxuIiwgImltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuaW1wb3J0IHsgaGFuZGxlRGVsZXRlQnJhbmNoaW5nTmVzdGVkTGlzdCB9IGZyb20gJy4vaGFuZGxlRGVsZXRlQnJhbmNoaW5nTmVzdGVkTGlzdC5qcydcblxuLyoqXG4gKiBDcmVhdGVzIGEgaGlnaC1wcmlvcml0eSBrZXltYXAgZXh0ZW5zaW9uIHRoYXQgaGFuZGxlcyBEZWxldGUgZm9yIGJyYW5jaGluZyBuZXN0ZWQgbGlzdHMuXG4gKiBLZXB0IHNlcGFyYXRlIGZyb20gdGhlIGxpc3QgaXRlbSBub2RlIHNvIEVudGVyL1RhYiBzaG9ydGN1dHMga2VlcCB0aGVpciBkZWZhdWx0IHByaW9yaXR5LlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlQnJhbmNoaW5nTGlzdERlbGV0ZUtleW1hcCA9IChpdGVtTmFtZTogc3RyaW5nLCB3cmFwcGVyTmFtZXM6IHN0cmluZ1tdKSA9PiB7XG4gIHJldHVybiBFeHRlbnNpb24uY3JlYXRlKHtcbiAgICBuYW1lOiBgJHtpdGVtTmFtZX1CcmFuY2hpbmdEZWxldGVLZXltYXBgLFxuICAgIHByaW9yaXR5OiAxMDEsXG5cbiAgICBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICAgIGNvbnN0IGhhbmRsZURlbGV0ZSA9ICgpID0+XG4gICAgICAgIGhhbmRsZURlbGV0ZUJyYW5jaGluZ05lc3RlZExpc3QodGhpcy5lZGl0b3IsIGl0ZW1OYW1lLCB3cmFwcGVyTmFtZXMpXG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIERlbGV0ZTogaGFuZGxlRGVsZXRlLFxuICAgICAgICAnTW9kLURlbGV0ZSc6IGhhbmRsZURlbGV0ZSxcbiAgICAgIH1cbiAgICB9LFxuICB9KVxufVxuIiwgImltcG9ydCB7IEZyYWdtZW50IH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUsIFRyYW5zYWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgZ2V0QnJhbmNoaW5nTmVzdGVkTGlzdEF0Q3Vyc29yIH0gZnJvbSAnLi9nZXRCcmFuY2hpbmdOZXN0ZWRMaXN0QXRDdXJzb3IuanMnXG5cbi8qKlxuICogSG9pc3RzIGFsbCBsaXN0IGl0ZW1zIGZyb20gYSBicmFuY2hpbmcgbmVzdGVkIGxpc3QgYWZ0ZXIgdGhlIGN1cnNvciBpbnRvIHRoZSBwYXJlbnQgbGlzdC5cbiAqXG4gKiBVc2UgdGhpcyB3aGVuIGBqb2luRm9yd2FyZGAgY2Fubm90IHJlc3RydWN0dXJlIGEgbmVzdGVkIGxpc3QgdGhhdCBjb250YWlucyBsaXN0IGl0ZW1zXG4gKiB3aXRoIHN1Ymxpc3RzIChzZWUgaXNzdWUgIzY5MDYpLlxuICpcbiAqIEBwYXJhbSBzdGF0ZSAtIFRoZSBlZGl0b3Igc3RhdGUgdG8gdHJhbnNmb3JtLlxuICogQHBhcmFtIGRpc3BhdGNoIC0gT3B0aW9uYWwgZGlzcGF0Y2ggZnVuY3Rpb24gZm9yIHRoZSB0cmFuc2FjdGlvbi5cbiAqIEBwYXJhbSBpdGVtTmFtZSAtIFRoZSBsaXN0IGl0ZW0gbm9kZSBuYW1lIChmb3IgZXhhbXBsZSBgbGlzdEl0ZW1gIG9yIGB0YXNrSXRlbWApLlxuICogQHBhcmFtIHdyYXBwZXJOYW1lcyAtIExpc3Qgd3JhcHBlciBub2RlIG5hbWVzIChmb3IgZXhhbXBsZSBgYnVsbGV0TGlzdGAgYW5kIGBvcmRlcmVkTGlzdGApLlxuICogQHJldHVybnMgYHRydWVgIHdoZW4gdGhlIG5lc3RlZCBsaXN0IHdhcyBob2lzdGVkLCBvdGhlcndpc2UgYGZhbHNlYC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIC8vIEN1cnNvciBhdCB0aGUgZW5kIG9mIFwiSXRlbSAxXCIgYmVmb3JlIGEgbmVzdGVkIGxpc3Qgd2l0aCBicmFuY2hpbmcgaXRlbXMuXG4gKiBob2lzdEJyYW5jaGluZ05lc3RlZExpc3QoZWRpdG9yLnN0YXRlLCBlZGl0b3Iudmlldy5kaXNwYXRjaCwgJ2xpc3RJdGVtJywgW1xuICogICAnYnVsbGV0TGlzdCcsXG4gKiAgICdvcmRlcmVkTGlzdCcsXG4gKiBdKVxuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBob2lzdEJyYW5jaGluZ05lc3RlZExpc3QgPSAoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgZGlzcGF0Y2g6ICgodHI6IFRyYW5zYWN0aW9uKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCxcbiAgaXRlbU5hbWU6IHN0cmluZyxcbiAgd3JhcHBlck5hbWVzOiBzdHJpbmdbXSxcbikgPT4ge1xuICBjb25zdCBjb250ZXh0ID0gZ2V0QnJhbmNoaW5nTmVzdGVkTGlzdEF0Q3Vyc29yKHN0YXRlLCBpdGVtTmFtZSwgd3JhcHBlck5hbWVzKVxuXG4gIGlmICghY29udGV4dCkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IHN0YXRlXG4gIGNvbnN0IHsgbmVzdGVkTGlzdCwgbmVzdGVkTGlzdFBvcywgaW5zZXJ0UG9zLCBpdGVtcyB9ID0gY29udGV4dFxuICBjb25zdCB0ciA9IHN0YXRlLnRyXG5cbiAgdHIuZGVsZXRlKG5lc3RlZExpc3RQb3MsIG5lc3RlZExpc3RQb3MgKyBuZXN0ZWRMaXN0Lm5vZGVTaXplKVxuXG4gIGNvbnN0IG1hcHBlZEluc2VydFBvcyA9IHRyLm1hcHBpbmcubWFwKGluc2VydFBvcylcblxuICB0ci5pbnNlcnQobWFwcGVkSW5zZXJ0UG9zLCBGcmFnbWVudC5mcm9tKGl0ZW1zKSlcblxuICB0ci5zZXRTZWxlY3Rpb24oc2VsZWN0aW9uLm1hcCh0ci5kb2MsIHRyLm1hcHBpbmcpKVxuXG4gIGlmIChkaXNwYXRjaCkge1xuICAgIGRpc3BhdGNoKHRyKVxuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHR5cGUgeyBFZGl0b3JTdGF0ZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmV4cG9ydCB0eXBlIEJyYW5jaGluZ05lc3RlZExpc3RBdEN1cnNvciA9IHtcbiAgbGlzdEl0ZW1EZXB0aDogbnVtYmVyXG4gIG5lc3RlZExpc3Q6IE5vZGVcbiAgbmVzdGVkTGlzdFBvczogbnVtYmVyXG4gIGluc2VydFBvczogbnVtYmVyXG4gIGl0ZW1zOiBOb2RlW11cbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhIGJyYW5jaGluZyBuZXN0ZWQgbGlzdCBpbW1lZGlhdGVseSBhZnRlciB0aGUgY3Vyc29yIHdoZW4gdGhlIHNlbGVjdGlvbiBpc1xuICogY29sbGFwc2VkIGF0IHRoZSBlbmQgb2YgYSB0ZXh0YmxvY2sgaW5zaWRlIGEgbGlzdCBpdGVtLlxuICpcbiAqIEBwYXJhbSBzdGF0ZSAtIFRoZSBlZGl0b3Igc3RhdGUgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSBpdGVtTmFtZSAtIFRoZSBsaXN0IGl0ZW0gbm9kZSBuYW1lIChmb3IgZXhhbXBsZSBgbGlzdEl0ZW1gIG9yIGB0YXNrSXRlbWApLlxuICogQHBhcmFtIHdyYXBwZXJOYW1lcyAtIExpc3Qgd3JhcHBlciBub2RlIG5hbWVzIChmb3IgZXhhbXBsZSBgYnVsbGV0TGlzdGAgYW5kIGBvcmRlcmVkTGlzdGApLlxuICogQHJldHVybnMgUmVzb2x2ZWQgcG9zaXRpb25zIGFuZCBub2RlcyBmb3IgaG9pc3RpbmcsIG9yIGBudWxsYCB3aGVuIG5vdCBhcHBsaWNhYmxlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogY29uc3QgY29udGV4dCA9IGdldEJyYW5jaGluZ05lc3RlZExpc3RBdEN1cnNvcihlZGl0b3Iuc3RhdGUsICdsaXN0SXRlbScsIFtcbiAqICAgJ2J1bGxldExpc3QnLFxuICogICAnb3JkZXJlZExpc3QnLFxuICogXSlcbiAqXG4gKiBpZiAoY29udGV4dCkge1xuICogICAvLyBjdXJzb3IgaXMgYXQgdGhlIGVuZCBvZiBJdGVtIDEgYmVmb3JlIGEgYnJhbmNoaW5nIG5lc3RlZCBzdWJsaXN0XG4gKiB9XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNvbnN0IGdldEJyYW5jaGluZ05lc3RlZExpc3RBdEN1cnNvciA9IChcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuICBpdGVtTmFtZTogc3RyaW5nLFxuICB3cmFwcGVyTmFtZXM6IHN0cmluZ1tdLFxuKTogQnJhbmNoaW5nTmVzdGVkTGlzdEF0Q3Vyc29yIHwgbnVsbCA9PiB7XG4gIGNvbnN0IHsgc2VsZWN0aW9uIH0gPSBzdGF0ZVxuXG4gIGlmICghc2VsZWN0aW9uLmVtcHR5KSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGNvbnN0IHsgJGZyb20gfSA9IHNlbGVjdGlvblxuXG4gIGlmICghJGZyb20ucGFyZW50LmlzVGV4dGJsb2NrKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGlmICgkZnJvbS5wYXJlbnRPZmZzZXQgIT09ICRmcm9tLnBhcmVudC5jb250ZW50LnNpemUpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgbGV0IGxpc3RJdGVtRGVwdGggPSAtMVxuXG4gIGZvciAobGV0IGRlcHRoID0gJGZyb20uZGVwdGg7IGRlcHRoID4gMDsgZGVwdGggLT0gMSkge1xuICAgIGlmICgkZnJvbS5ub2RlKGRlcHRoKS50eXBlLm5hbWUgPT09IGl0ZW1OYW1lKSB7XG4gICAgICBsaXN0SXRlbURlcHRoID0gZGVwdGhcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKGxpc3RJdGVtRGVwdGggPCAwKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGNvbnN0IGxpc3RJdGVtID0gJGZyb20ubm9kZShsaXN0SXRlbURlcHRoKVxuICBjb25zdCBpbmRleEluTGlzdEl0ZW0gPSAkZnJvbS5pbmRleChsaXN0SXRlbURlcHRoKVxuXG4gIGlmIChpbmRleEluTGlzdEl0ZW0gKyAxID49IGxpc3RJdGVtLmNoaWxkQ291bnQpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgY29uc3QgbmV4dENoaWxkID0gbGlzdEl0ZW0uY2hpbGQoaW5kZXhJbkxpc3RJdGVtICsgMSlcblxuICBpZiAoIXdyYXBwZXJOYW1lcy5pbmNsdWRlcyhuZXh0Q2hpbGQudHlwZS5uYW1lKSkge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBjb25zdCBpdGVtVHlwZSA9IHN0YXRlLnNjaGVtYS5ub2Rlc1tpdGVtTmFtZV1cbiAgbGV0IGhhc0JyYW5jaGluZyA9IGZhbHNlXG5cbiAgbmV4dENoaWxkLmZvckVhY2goY2hpbGQgPT4ge1xuICAgIGlmIChjaGlsZC50eXBlID09PSBpdGVtVHlwZSAmJiBjaGlsZC5jaGlsZENvdW50ID4gMSkge1xuICAgICAgaGFzQnJhbmNoaW5nID0gdHJ1ZVxuICAgIH1cbiAgfSlcblxuICBpZiAoIWhhc0JyYW5jaGluZykge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBjb25zdCBub2RlQWZ0ZXIgPSBzdGF0ZS5kb2MucmVzb2x2ZSgkZnJvbS5hZnRlcigpKS5ub2RlQWZ0ZXJcblxuICBpZiAoIW5vZGVBZnRlciB8fCAhd3JhcHBlck5hbWVzLmluY2x1ZGVzKG5vZGVBZnRlci50eXBlLm5hbWUpKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIGNvbnN0IGl0ZW1zOiBOb2RlW10gPSBbXVxuXG4gIG5vZGVBZnRlci5mb3JFYWNoKGNoaWxkID0+IHtcbiAgICBpdGVtcy5wdXNoKGNoaWxkKVxuICB9KVxuXG4gIGlmIChpdGVtcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBsaXN0SXRlbURlcHRoLFxuICAgIG5lc3RlZExpc3Q6IG5vZGVBZnRlcixcbiAgICBuZXN0ZWRMaXN0UG9zOiAkZnJvbS5hZnRlcigpLFxuICAgIGluc2VydFBvczogJGZyb20uYWZ0ZXIobGlzdEl0ZW1EZXB0aCksXG4gICAgaXRlbXMsXG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IEVkaXRvciB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuaW1wb3J0IHsgaG9pc3RCcmFuY2hpbmdOZXN0ZWRMaXN0IH0gZnJvbSAnLi9ob2lzdEJyYW5jaGluZ05lc3RlZExpc3QuanMnXG5cbi8qKlxuICogSGFuZGxlcyBEZWxldGUgZm9yIGEgbGlzdCBpdGVtIHdoZW4gYSBicmFuY2hpbmcgbmVzdGVkIHN1Ymxpc3QgZm9sbG93cyB0aGUgY3Vyc29yLlxuICpcbiAqIEBwYXJhbSBlZGl0b3IgLSBUaGUgZWRpdG9yIGluc3RhbmNlIHdob3NlIHN0YXRlIHNob3VsZCBiZSB1cGRhdGVkLlxuICogQHBhcmFtIGl0ZW1OYW1lIC0gVGhlIGxpc3QgaXRlbSBub2RlIG5hbWUgKGZvciBleGFtcGxlIGBsaXN0SXRlbWAgb3IgYHRhc2tJdGVtYCkuXG4gKiBAcGFyYW0gd3JhcHBlck5hbWVzIC0gTGlzdCB3cmFwcGVyIG5vZGUgbmFtZXMgKGZvciBleGFtcGxlIGBidWxsZXRMaXN0YCBhbmQgYG9yZGVyZWRMaXN0YCkuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgd2hlbiB0aGUgbmVzdGVkIGxpc3Qgd2FzIGhvaXN0ZWQsIG90aGVyd2lzZSBgZmFsc2VgLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogRGVsZXRlOiAoKSA9PlxuICogICBoYW5kbGVEZWxldGVCcmFuY2hpbmdOZXN0ZWRMaXN0KGVkaXRvciwgJ2xpc3RJdGVtJywgWydidWxsZXRMaXN0JywgJ29yZGVyZWRMaXN0J10pLFxuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBoYW5kbGVEZWxldGVCcmFuY2hpbmdOZXN0ZWRMaXN0ID0gKFxuICBlZGl0b3I6IEVkaXRvcixcbiAgaXRlbU5hbWU6IHN0cmluZyxcbiAgd3JhcHBlck5hbWVzOiBzdHJpbmdbXSxcbikgPT4ge1xuICByZXR1cm4gaG9pc3RCcmFuY2hpbmdOZXN0ZWRMaXN0KGVkaXRvci5zdGF0ZSwgZWRpdG9yLnZpZXcuZGlzcGF0Y2gsIGl0ZW1OYW1lLCB3cmFwcGVyTmFtZXMpXG59XG4iLCAiaW1wb3J0IHsgRXh0ZW5zaW9uIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5pbXBvcnQgeyBoYW5kbGVCYWNrc3BhY2UsIGhhbmRsZURlbGV0ZSB9IGZyb20gJy4vbGlzdEhlbHBlcnMvaW5kZXguanMnXG5cbmV4cG9ydCB0eXBlIExpc3RLZXltYXBPcHRpb25zID0ge1xuICAvKipcbiAgICogQW4gYXJyYXkgb2YgbGlzdCB0eXBlcy4gVGhpcyBpcyB1c2VkIGZvciBpdGVtIGFuZCB3cmFwcGVyIGxpc3QgbWF0Y2hpbmcuXG4gICAqIEBkZWZhdWx0IFtdXG4gICAqIEBleGFtcGxlIFt7IGl0ZW1OYW1lOiAnbGlzdEl0ZW0nLCB3cmFwcGVyTmFtZXM6IFsnYnVsbGV0TGlzdCcsICdvcmRlcmVkTGlzdCddIH1dXG4gICAqL1xuICBsaXN0VHlwZXM6IEFycmF5PHtcbiAgICBpdGVtTmFtZTogc3RyaW5nXG4gICAgd3JhcHBlck5hbWVzOiBzdHJpbmdbXVxuICB9PlxufVxuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIHJlZ2lzdGVycyBjdXN0b20ga2V5bWFwcyB0byBjaGFuZ2UgdGhlIGJlaGF2aW91ciBvZiB0aGUgYmFja3NwYWNlIGFuZCBkZWxldGUga2V5cy5cbiAqIEJ5IGRlZmF1bHQgUHJvc2VtaXJyb3Iga2V5aGFuZGxpbmcgd2lsbCBhbHdheXMgbGlmdCBvciBzaW5rIGl0ZW1zIHNvIHBhcmFncmFwaHMgYXJlIGpvaW5lZCBpbnRvXG4gKiB0aGUgYWRqYWNlbnQgb3IgcHJldmlvdXMgbGlzdCBpdGVtLiBUaGlzIGV4dGVuc2lvbiB3aWxsIHByZXZlbnQgdGhpcyBiZWhhdmlvdXIgYW5kIGluc3RlYWQgd2lsbFxuICogdHJ5IHRvIGpvaW4gcGFyYWdyYXBocyBmcm9tIHR3byBsaXN0IGl0ZW1zIGludG8gYSBzaW5nbGUgbGlzdCBpdGVtLlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9leHRlbnNpb25zL2xpc3Qta2V5bWFwXG4gKi9cbmV4cG9ydCBjb25zdCBMaXN0S2V5bWFwID0gRXh0ZW5zaW9uLmNyZWF0ZTxMaXN0S2V5bWFwT3B0aW9ucz4oe1xuICBuYW1lOiAnbGlzdEtleW1hcCcsXG5cbiAgYWRkT3B0aW9ucygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbGlzdFR5cGVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBpdGVtTmFtZTogJ2xpc3RJdGVtJyxcbiAgICAgICAgICB3cmFwcGVyTmFtZXM6IFsnYnVsbGV0TGlzdCcsICdvcmRlcmVkTGlzdCddLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaXRlbU5hbWU6ICd0YXNrSXRlbScsXG4gICAgICAgICAgd3JhcHBlck5hbWVzOiBbJ3Rhc2tMaXN0J10sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH1cbiAgfSxcblxuICBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgRGVsZXRlOiAoeyBlZGl0b3IgfSkgPT4ge1xuICAgICAgICBsZXQgaGFuZGxlZCA9IGZhbHNlXG5cbiAgICAgICAgdGhpcy5vcHRpb25zLmxpc3RUeXBlcy5mb3JFYWNoKCh7IGl0ZW1OYW1lIH0pID0+IHtcbiAgICAgICAgICBpZiAoZWRpdG9yLnN0YXRlLnNjaGVtYS5ub2Rlc1tpdGVtTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGhhbmRsZURlbGV0ZShlZGl0b3IsIGl0ZW1OYW1lKSkge1xuICAgICAgICAgICAgaGFuZGxlZCA9IHRydWVcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgcmV0dXJuIGhhbmRsZWRcbiAgICAgIH0sXG4gICAgICAnTW9kLURlbGV0ZSc6ICh7IGVkaXRvciB9KSA9PiB7XG4gICAgICAgIGxldCBoYW5kbGVkID0gZmFsc2VcblxuICAgICAgICB0aGlzLm9wdGlvbnMubGlzdFR5cGVzLmZvckVhY2goKHsgaXRlbU5hbWUgfSkgPT4ge1xuICAgICAgICAgIGlmIChlZGl0b3Iuc3RhdGUuc2NoZW1hLm5vZGVzW2l0ZW1OYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaGFuZGxlRGVsZXRlKGVkaXRvciwgaXRlbU5hbWUpKSB7XG4gICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICByZXR1cm4gaGFuZGxlZFxuICAgICAgfSxcbiAgICAgIEJhY2tzcGFjZTogKHsgZWRpdG9yIH0pID0+IHtcbiAgICAgICAgbGV0IGhhbmRsZWQgPSBmYWxzZVxuXG4gICAgICAgIHRoaXMub3B0aW9ucy5saXN0VHlwZXMuZm9yRWFjaCgoeyBpdGVtTmFtZSwgd3JhcHBlck5hbWVzIH0pID0+IHtcbiAgICAgICAgICBpZiAoZWRpdG9yLnN0YXRlLnNjaGVtYS5ub2Rlc1tpdGVtTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGhhbmRsZUJhY2tzcGFjZShlZGl0b3IsIGl0ZW1OYW1lLCB3cmFwcGVyTmFtZXMpKSB7XG4gICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICByZXR1cm4gaGFuZGxlZFxuICAgICAgfSxcbiAgICAgICdNb2QtQmFja3NwYWNlJzogKHsgZWRpdG9yIH0pID0+IHtcbiAgICAgICAgbGV0IGhhbmRsZWQgPSBmYWxzZVxuXG4gICAgICAgIHRoaXMub3B0aW9ucy5saXN0VHlwZXMuZm9yRWFjaCgoeyBpdGVtTmFtZSwgd3JhcHBlck5hbWVzIH0pID0+IHtcbiAgICAgICAgICBpZiAoZWRpdG9yLnN0YXRlLnNjaGVtYS5ub2Rlc1tpdGVtTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGhhbmRsZUJhY2tzcGFjZShlZGl0b3IsIGl0ZW1OYW1lLCB3cmFwcGVyTmFtZXMpKSB7XG4gICAgICAgICAgICBoYW5kbGVkID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcblxuICAgICAgICByZXR1cm4gaGFuZGxlZFxuICAgICAgfSxcbiAgICB9XG4gIH0sXG59KVxuIiwgImV4cG9ydCAqIGZyb20gJy4vZmluZExpc3RJdGVtUG9zLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9nZXROZXh0TGlzdERlcHRoLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi9oYW5kbGVCYWNrc3BhY2UuanMnXG5leHBvcnQgKiBmcm9tICcuL2hhbmRsZURlbGV0ZS5qcydcbmV4cG9ydCAqIGZyb20gJy4vaGFzTGlzdEJlZm9yZS5qcydcbmV4cG9ydCAqIGZyb20gJy4vaGFzTGlzdEl0ZW1BZnRlci5qcydcbmV4cG9ydCAqIGZyb20gJy4vaGFzTGlzdEl0ZW1CZWZvcmUuanMnXG5leHBvcnQgKiBmcm9tICcuL2xpc3RJdGVtSGFzU3ViTGlzdC5qcydcbmV4cG9ydCAqIGZyb20gJy4vbmV4dExpc3RJc0RlZXBlci5qcydcbmV4cG9ydCAqIGZyb20gJy4vbmV4dExpc3RJc0hpZ2hlci5qcydcbiIsICJpbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB0eXBlIHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHR5cGUgeyBFZGl0b3JTdGF0ZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmV4cG9ydCBjb25zdCBmaW5kTGlzdEl0ZW1Qb3MgPSAodHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUsIHN0YXRlOiBFZGl0b3JTdGF0ZSkgPT4ge1xuICBjb25zdCB7ICRmcm9tIH0gPSBzdGF0ZS5zZWxlY3Rpb25cbiAgY29uc3Qgbm9kZVR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG5cbiAgbGV0IGN1cnJlbnROb2RlID0gbnVsbFxuICBsZXQgY3VycmVudERlcHRoID0gJGZyb20uZGVwdGhcbiAgbGV0IGN1cnJlbnRQb3MgPSAkZnJvbS5wb3NcbiAgbGV0IHRhcmdldERlcHRoOiBudW1iZXIgfCBudWxsID0gbnVsbFxuXG4gIHdoaWxlIChjdXJyZW50RGVwdGggPiAwICYmIHRhcmdldERlcHRoID09PSBudWxsKSB7XG4gICAgY3VycmVudE5vZGUgPSAkZnJvbS5ub2RlKGN1cnJlbnREZXB0aClcblxuICAgIGlmIChjdXJyZW50Tm9kZS50eXBlID09PSBub2RlVHlwZSkge1xuICAgICAgdGFyZ2V0RGVwdGggPSBjdXJyZW50RGVwdGhcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudERlcHRoIC09IDFcbiAgICAgIGN1cnJlbnRQb3MgLT0gMVxuICAgIH1cbiAgfVxuXG4gIGlmICh0YXJnZXREZXB0aCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICByZXR1cm4geyAkcG9zOiBzdGF0ZS5kb2MucmVzb2x2ZShjdXJyZW50UG9zKSwgZGVwdGg6IHRhcmdldERlcHRoIH1cbn1cbiIsICJpbXBvcnQgeyBnZXROb2RlQXRQb3NpdGlvbiB9IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBmaW5kTGlzdEl0ZW1Qb3MgfSBmcm9tICcuL2ZpbmRMaXN0SXRlbVBvcy5qcydcblxuZXhwb3J0IGNvbnN0IGdldE5leHRMaXN0RGVwdGggPSAodHlwZU9yTmFtZTogc3RyaW5nLCBzdGF0ZTogRWRpdG9yU3RhdGUpID0+IHtcbiAgY29uc3QgbGlzdEl0ZW1Qb3MgPSBmaW5kTGlzdEl0ZW1Qb3ModHlwZU9yTmFtZSwgc3RhdGUpXG5cbiAgaWYgKCFsaXN0SXRlbVBvcykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgY29uc3QgWywgZGVwdGhdID0gZ2V0Tm9kZUF0UG9zaXRpb24oc3RhdGUsIHR5cGVPck5hbWUsIGxpc3RJdGVtUG9zLiRwb3MucG9zICsgNClcblxuICByZXR1cm4gZGVwdGhcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEVkaXRvciB9IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB7IGlzQXRTdGFydE9mTm9kZSwgaXNOb2RlQWN0aXZlIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgaGFzTGlzdEJlZm9yZSB9IGZyb20gJy4vaGFzTGlzdEJlZm9yZS5qcydcblxuZXhwb3J0IGNvbnN0IGhhbmRsZUJhY2tzcGFjZSA9IChlZGl0b3I6IEVkaXRvciwgbmFtZTogc3RyaW5nLCBwYXJlbnRMaXN0VHlwZXM6IHN0cmluZ1tdKSA9PiB7XG4gIC8vIHRoaXMgaXMgcmVxdWlyZWQgdG8gc3RpbGwgaGFuZGxlIHRoZSB1bmRvIGhhbmRsaW5nXG4gIGlmIChlZGl0b3IuY29tbWFuZHMudW5kb0lucHV0UnVsZSgpKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8vIGlmIHRoZSBzZWxlY3Rpb24gaXMgbm90IGNvbGxhcHNlZFxuICAvLyB3ZSBjYW4gcmVseSBvbiB0aGUgZGVmYXVsdCBiYWNrc3BhY2UgYmVoYXZpb3JcbiAgaWYgKGVkaXRvci5zdGF0ZS5zZWxlY3Rpb24uZnJvbSAhPT0gZWRpdG9yLnN0YXRlLnNlbGVjdGlvbi50bykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gaWYgdGhlIGN1cnJlbnQgaXRlbSBpcyBOT1QgaW5zaWRlIGEgbGlzdCBpdGVtICZcbiAgLy8gdGhlIHByZXZpb3VzIGl0ZW0gaXMgYSBsaXN0IChvcmRlcmVkTGlzdCBvciBidWxsZXRMaXN0KVxuICAvLyBtb3ZlIHRoZSBjdXJzb3IgaW50byB0aGUgbGlzdCBhbmQgZGVsZXRlIHRoZSBjdXJyZW50IGl0ZW1cbiAgaWYgKCFpc05vZGVBY3RpdmUoZWRpdG9yLnN0YXRlLCBuYW1lKSAmJiBoYXNMaXN0QmVmb3JlKGVkaXRvci5zdGF0ZSwgbmFtZSwgcGFyZW50TGlzdFR5cGVzKSkge1xuICAgIGNvbnN0IHsgJGFuY2hvciB9ID0gZWRpdG9yLnN0YXRlLnNlbGVjdGlvblxuXG4gICAgY29uc3QgJGxpc3RQb3MgPSBlZGl0b3Iuc3RhdGUuZG9jLnJlc29sdmUoJGFuY2hvci5iZWZvcmUoKSAtIDEpXG5cbiAgICBjb25zdCBsaXN0RGVzY2VuZGFudHM6IEFycmF5PHsgbm9kZTogTm9kZTsgcG9zOiBudW1iZXIgfT4gPSBbXVxuXG4gICAgJGxpc3RQb3Mubm9kZSgpLmRlc2NlbmRhbnRzKChub2RlLCBwb3MpID0+IHtcbiAgICAgIGlmIChub2RlLnR5cGUubmFtZSA9PT0gbmFtZSkge1xuICAgICAgICBsaXN0RGVzY2VuZGFudHMucHVzaCh7IG5vZGUsIHBvcyB9KVxuICAgICAgfVxuICAgIH0pXG5cbiAgICBjb25zdCBsYXN0SXRlbSA9IGxpc3REZXNjZW5kYW50cy5hdCgtMSlcblxuICAgIGlmICghbGFzdEl0ZW0pIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGNvbnN0ICRsYXN0SXRlbVBvcyA9IGVkaXRvci5zdGF0ZS5kb2MucmVzb2x2ZSgkbGlzdFBvcy5zdGFydCgpICsgbGFzdEl0ZW0ucG9zICsgMSlcblxuICAgIHJldHVybiBlZGl0b3JcbiAgICAgIC5jaGFpbigpXG4gICAgICAuY3V0KHsgZnJvbTogJGFuY2hvci5zdGFydCgpIC0gMSwgdG86ICRhbmNob3IuZW5kKCkgKyAxIH0sICRsYXN0SXRlbVBvcy5lbmQoKSlcbiAgICAgIC5qb2luRm9yd2FyZCgpXG4gICAgICAucnVuKClcbiAgfVxuXG4gIC8vIGlmIHRoZSBjdXJzb3IgaXMgbm90IGluc2lkZSB0aGUgY3VycmVudCBub2RlIHR5cGVcbiAgLy8gZG8gbm90aGluZyBhbmQgcHJvY2VlZFxuICBpZiAoIWlzTm9kZUFjdGl2ZShlZGl0b3Iuc3RhdGUsIG5hbWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBpZiB0aGUgY3Vyc29yIGlzIG5vdCBhdCB0aGUgc3RhcnQgb2YgYSBub2RlXG4gIC8vIGRvIG5vdGhpbmcgYW5kIHByb2NlZWRcbiAgaWYgKCFpc0F0U3RhcnRPZk5vZGUoZWRpdG9yLnN0YXRlKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gQXQgdGhlIHN0YXJ0IG9mIGEgbGlzdCBpdGVtLCBsaWZ0IGl0IG91dC4gVG9wLWxldmVsIGl0ZW1zIHNwbGl0IHRoZVxuICAvLyB3cmFwcGluZyBsaXN0IGFyb3VuZCB0aGVtOyBuZXN0ZWQgaXRlbXMgZ2V0IHByb21vdGVkIGludG8gdGhlIG91dGVyXG4gIC8vIGxpc3QuIEEgc2Vjb25kIGJhY2tzcGFjZSB0aGVuIGZhbGxzIHRocm91Z2ggdG8gdGhlIG1lcmdlIGJyYW5jaCBhYm92ZS5cbiAgcmV0dXJuIGVkaXRvci5jaGFpbigpLmxpZnRMaXN0SXRlbShuYW1lKS5ydW4oKVxufVxuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5leHBvcnQgY29uc3QgaGFzTGlzdEJlZm9yZSA9IChcbiAgZWRpdG9yU3RhdGU6IEVkaXRvclN0YXRlLFxuICBuYW1lOiBzdHJpbmcsXG4gIHBhcmVudExpc3RUeXBlczogc3RyaW5nW10sXG4pID0+IHtcbiAgY29uc3QgeyAkYW5jaG9yIH0gPSBlZGl0b3JTdGF0ZS5zZWxlY3Rpb25cblxuICBjb25zdCBwcmV2aW91c05vZGVQb3MgPSBNYXRoLm1heCgwLCAkYW5jaG9yLnBvcyAtIDIpXG5cbiAgY29uc3QgcHJldmlvdXNOb2RlID0gZWRpdG9yU3RhdGUuZG9jLnJlc29sdmUocHJldmlvdXNOb2RlUG9zKS5ub2RlKClcblxuICBpZiAoIXByZXZpb3VzTm9kZSB8fCAhcGFyZW50TGlzdFR5cGVzLmluY2x1ZGVzKHByZXZpb3VzTm9kZS50eXBlLm5hbWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHsgaXNBdEVuZE9mTm9kZSwgaXNOb2RlQWN0aXZlIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5pbXBvcnQgeyBuZXh0TGlzdElzRGVlcGVyIH0gZnJvbSAnLi9uZXh0TGlzdElzRGVlcGVyLmpzJ1xuaW1wb3J0IHsgbmV4dExpc3RJc0hpZ2hlciB9IGZyb20gJy4vbmV4dExpc3RJc0hpZ2hlci5qcydcblxuZXhwb3J0IGNvbnN0IGhhbmRsZURlbGV0ZSA9IChlZGl0b3I6IEVkaXRvciwgbmFtZTogc3RyaW5nKSA9PiB7XG4gIC8vIGlmIHRoZSBjdXJzb3IgaXMgbm90IGluc2lkZSB0aGUgY3VycmVudCBub2RlIHR5cGVcbiAgLy8gZG8gbm90aGluZyBhbmQgcHJvY2VlZFxuICBpZiAoIWlzTm9kZUFjdGl2ZShlZGl0b3Iuc3RhdGUsIG5hbWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBpZiB0aGUgY3Vyc29yIGlzIG5vdCBhdCB0aGUgZW5kIG9mIGEgbm9kZVxuICAvLyBkbyBub3RoaW5nIGFuZCBwcm9jZWVkXG4gIGlmICghaXNBdEVuZE9mTm9kZShlZGl0b3Iuc3RhdGUsIG5hbWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBpZiB0aGUgc2VsZWN0aW9uIGlzIG5vdCBjb2xsYXBzZWQsIG9yIG5vdCB3aXRoaW4gYSBzaW5nbGUgbm9kZVxuICAvLyBkbyBub3RoaW5nIGFuZCBwcm9jZWVkXG4gIGNvbnN0IHsgc2VsZWN0aW9uIH0gPSBlZGl0b3Iuc3RhdGVcbiAgY29uc3QgeyAkZnJvbSwgJHRvIH0gPSBzZWxlY3Rpb25cblxuICBpZiAoIXNlbGVjdGlvbi5lbXB0eSAmJiAkZnJvbS5zYW1lUGFyZW50KCR0bykpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8vIGNoZWNrIGlmIHRoZSBuZXh0IG5vZGUgaXMgYSBsaXN0IHdpdGggYSBkZWVwZXIgZGVwdGhcbiAgaWYgKG5leHRMaXN0SXNEZWVwZXIobmFtZSwgZWRpdG9yLnN0YXRlKSkge1xuICAgIHJldHVybiBlZGl0b3JcbiAgICAgIC5jaGFpbigpXG4gICAgICAuZm9jdXMoZWRpdG9yLnN0YXRlLnNlbGVjdGlvbi5mcm9tICsgNClcbiAgICAgIC5saWZ0KG5hbWUpXG4gICAgICAuam9pbkJhY2t3YXJkKClcbiAgICAgIC5ydW4oKVxuICB9XG5cbiAgaWYgKG5leHRMaXN0SXNIaWdoZXIobmFtZSwgZWRpdG9yLnN0YXRlKSkge1xuICAgIHJldHVybiBlZGl0b3IuY2hhaW4oKS5qb2luRm9yd2FyZCgpLmpvaW5CYWNrd2FyZCgpLnJ1bigpXG4gIH1cblxuICByZXR1cm4gZWRpdG9yLmNvbW1hbmRzLmpvaW5JdGVtRm9yd2FyZCgpXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBFZGl0b3JTdGF0ZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IGZpbmRMaXN0SXRlbVBvcyB9IGZyb20gJy4vZmluZExpc3RJdGVtUG9zLmpzJ1xuaW1wb3J0IHsgZ2V0TmV4dExpc3REZXB0aCB9IGZyb20gJy4vZ2V0TmV4dExpc3REZXB0aC5qcydcblxuZXhwb3J0IGNvbnN0IG5leHRMaXN0SXNEZWVwZXIgPSAodHlwZU9yTmFtZTogc3RyaW5nLCBzdGF0ZTogRWRpdG9yU3RhdGUpID0+IHtcbiAgY29uc3QgbGlzdERlcHRoID0gZ2V0TmV4dExpc3REZXB0aCh0eXBlT3JOYW1lLCBzdGF0ZSlcbiAgY29uc3QgbGlzdEl0ZW1Qb3MgPSBmaW5kTGlzdEl0ZW1Qb3ModHlwZU9yTmFtZSwgc3RhdGUpXG5cbiAgaWYgKCFsaXN0SXRlbVBvcyB8fCAhbGlzdERlcHRoKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAobGlzdERlcHRoID4gbGlzdEl0ZW1Qb3MuZGVwdGgpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBFZGl0b3JTdGF0ZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IGZpbmRMaXN0SXRlbVBvcyB9IGZyb20gJy4vZmluZExpc3RJdGVtUG9zLmpzJ1xuaW1wb3J0IHsgZ2V0TmV4dExpc3REZXB0aCB9IGZyb20gJy4vZ2V0TmV4dExpc3REZXB0aC5qcydcblxuZXhwb3J0IGNvbnN0IG5leHRMaXN0SXNIaWdoZXIgPSAodHlwZU9yTmFtZTogc3RyaW5nLCBzdGF0ZTogRWRpdG9yU3RhdGUpID0+IHtcbiAgY29uc3QgbGlzdERlcHRoID0gZ2V0TmV4dExpc3REZXB0aCh0eXBlT3JOYW1lLCBzdGF0ZSlcbiAgY29uc3QgbGlzdEl0ZW1Qb3MgPSBmaW5kTGlzdEl0ZW1Qb3ModHlwZU9yTmFtZSwgc3RhdGUpXG5cbiAgaWYgKCFsaXN0SXRlbVBvcyB8fCAhbGlzdERlcHRoKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAobGlzdERlcHRoIDwgbGlzdEl0ZW1Qb3MuZGVwdGgpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBFZGl0b3JTdGF0ZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmV4cG9ydCBjb25zdCBoYXNMaXN0SXRlbUFmdGVyID0gKHR5cGVPck5hbWU6IHN0cmluZywgc3RhdGU6IEVkaXRvclN0YXRlKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IHsgJGFuY2hvciB9ID0gc3RhdGUuc2VsZWN0aW9uXG5cbiAgY29uc3QgJHRhcmdldFBvcyA9IHN0YXRlLmRvYy5yZXNvbHZlKCRhbmNob3IucG9zIC0gJGFuY2hvci5wYXJlbnRPZmZzZXQgLSAyKVxuXG4gIGlmICgkdGFyZ2V0UG9zLmluZGV4KCkgPT09ICR0YXJnZXRQb3MucGFyZW50LmNoaWxkQ291bnQgLSAxKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAoJHRhcmdldFBvcy5ub2RlQWZ0ZXI/LnR5cGUubmFtZSAhPT0gdHlwZU9yTmFtZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEVkaXRvclN0YXRlIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuZXhwb3J0IGNvbnN0IGhhc0xpc3RJdGVtQmVmb3JlID0gKHR5cGVPck5hbWU6IHN0cmluZywgc3RhdGU6IEVkaXRvclN0YXRlKTogYm9vbGVhbiA9PiB7XG4gIGNvbnN0IHsgJGFuY2hvciB9ID0gc3RhdGUuc2VsZWN0aW9uXG5cbiAgY29uc3QgJHRhcmdldFBvcyA9IHN0YXRlLmRvYy5yZXNvbHZlKCRhbmNob3IucG9zIC0gMilcblxuICBpZiAoJHRhcmdldFBvcy5pbmRleCgpID09PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAoJHRhcmdldFBvcy5ub2RlQmVmb3JlPy50eXBlLm5hbWUgIT09IHR5cGVPck5hbWUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG4iLCAiaW1wb3J0IHsgZ2V0Tm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5pbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHR5cGUgeyBFZGl0b3JTdGF0ZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmV4cG9ydCBjb25zdCBsaXN0SXRlbUhhc1N1Ykxpc3QgPSAodHlwZU9yTmFtZTogc3RyaW5nLCBzdGF0ZTogRWRpdG9yU3RhdGUsIG5vZGU/OiBOb2RlKSA9PiB7XG4gIGlmICghbm9kZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgY29uc3Qgbm9kZVR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG5cbiAgbGV0IGhhc1N1Ykxpc3QgPSBmYWxzZVxuXG4gIG5vZGUuZGVzY2VuZGFudHMoY2hpbGQgPT4ge1xuICAgIGlmIChjaGlsZC50eXBlID09PSBub2RlVHlwZSkge1xuICAgICAgaGFzU3ViTGlzdCA9IHRydWVcbiAgICB9XG4gIH0pXG5cbiAgcmV0dXJuIGhhc1N1Ykxpc3Rcbn1cbiIsICJpbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5cbmltcG9ydCB0eXBlIHsgQnVsbGV0TGlzdE9wdGlvbnMgfSBmcm9tICcuLi9idWxsZXQtbGlzdC9pbmRleC5qcydcbmltcG9ydCB7IEJ1bGxldExpc3QgfSBmcm9tICcuLi9idWxsZXQtbGlzdC9pbmRleC5qcydcbmltcG9ydCB0eXBlIHsgTGlzdEl0ZW1PcHRpb25zIH0gZnJvbSAnLi4vaXRlbS9pbmRleC5qcydcbmltcG9ydCB7IExpc3RJdGVtIH0gZnJvbSAnLi4vaXRlbS9pbmRleC5qcydcbmltcG9ydCB0eXBlIHsgTGlzdEtleW1hcE9wdGlvbnMgfSBmcm9tICcuLi9rZXltYXAvaW5kZXguanMnXG5pbXBvcnQgeyBMaXN0S2V5bWFwIH0gZnJvbSAnLi4va2V5bWFwL2luZGV4LmpzJ1xuaW1wb3J0IHR5cGUgeyBPcmRlcmVkTGlzdE9wdGlvbnMgfSBmcm9tICcuLi9vcmRlcmVkLWxpc3QvaW5kZXguanMnXG5pbXBvcnQgeyBPcmRlcmVkTGlzdCB9IGZyb20gJy4uL29yZGVyZWQtbGlzdC9pbmRleC5qcydcbmltcG9ydCB0eXBlIHsgVGFza0l0ZW1PcHRpb25zIH0gZnJvbSAnLi4vdGFzay1pdGVtL2luZGV4LmpzJ1xuaW1wb3J0IHsgVGFza0l0ZW0gfSBmcm9tICcuLi90YXNrLWl0ZW0vaW5kZXguanMnXG5pbXBvcnQgdHlwZSB7IFRhc2tMaXN0T3B0aW9ucyB9IGZyb20gJy4uL3Rhc2stbGlzdC9pbmRleC5qcydcbmltcG9ydCB7IFRhc2tMaXN0IH0gZnJvbSAnLi4vdGFzay1saXN0L2luZGV4LmpzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIExpc3RLaXRPcHRpb25zIHtcbiAgLyoqXG4gICAqIElmIHNldCB0byBmYWxzZSwgdGhlIGJ1bGxldExpc3QgZXh0ZW5zaW9uIHdpbGwgbm90IGJlIHJlZ2lzdGVyZWRcbiAgICogQGV4YW1wbGUgdGFibGU6IGZhbHNlXG4gICAqL1xuICBidWxsZXRMaXN0OiBQYXJ0aWFsPEJ1bGxldExpc3RPcHRpb25zPiB8IGZhbHNlXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBsaXN0SXRlbSBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKi9cbiAgbGlzdEl0ZW06IFBhcnRpYWw8TGlzdEl0ZW1PcHRpb25zPiB8IGZhbHNlXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBsaXN0S2V5bWFwIGV4dGVuc2lvbiB3aWxsIG5vdCBiZSByZWdpc3RlcmVkXG4gICAqL1xuICBsaXN0S2V5bWFwOiBQYXJ0aWFsPExpc3RLZXltYXBPcHRpb25zPiB8IGZhbHNlXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBvcmRlcmVkTGlzdCBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKi9cbiAgb3JkZXJlZExpc3Q6IFBhcnRpYWw8T3JkZXJlZExpc3RPcHRpb25zPiB8IGZhbHNlXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSB0YXNrSXRlbSBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKi9cbiAgdGFza0l0ZW06IFBhcnRpYWw8VGFza0l0ZW1PcHRpb25zPiB8IGZhbHNlXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSB0YXNrTGlzdCBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKi9cbiAgdGFza0xpc3Q6IFBhcnRpYWw8VGFza0xpc3RPcHRpb25zPiB8IGZhbHNlXG59XG5cbi8qKlxuICogVGhlIHRhYmxlIGtpdCBpcyBhIGNvbGxlY3Rpb24gb2YgdGFibGUgZWRpdG9yIGV4dGVuc2lvbnMuXG4gKlxuICogSXTigJlzIGEgZ29vZCBzdGFydGluZyBwb2ludCBmb3IgYnVpbGRpbmcgeW91ciBvd24gdGFibGUgaW4gVGlwdGFwLlxuICovXG5leHBvcnQgY29uc3QgTGlzdEtpdCA9IEV4dGVuc2lvbi5jcmVhdGU8TGlzdEtpdE9wdGlvbnM+KHtcbiAgbmFtZTogJ2xpc3RLaXQnLFxuXG4gIGFkZEV4dGVuc2lvbnMoKSB7XG4gICAgY29uc3QgZXh0ZW5zaW9ucyA9IFtdXG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmJ1bGxldExpc3QgIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goQnVsbGV0TGlzdC5jb25maWd1cmUodGhpcy5vcHRpb25zLmJ1bGxldExpc3QpKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMubGlzdEl0ZW0gIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goTGlzdEl0ZW0uY29uZmlndXJlKHRoaXMub3B0aW9ucy5saXN0SXRlbSkpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5saXN0S2V5bWFwICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKExpc3RLZXltYXAuY29uZmlndXJlKHRoaXMub3B0aW9ucy5saXN0S2V5bWFwKSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLm9yZGVyZWRMaXN0ICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKE9yZGVyZWRMaXN0LmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMub3JkZXJlZExpc3QpKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMudGFza0l0ZW0gIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goVGFza0l0ZW0uY29uZmlndXJlKHRoaXMub3B0aW9ucy50YXNrSXRlbSkpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy50YXNrTGlzdCAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChUYXNrTGlzdC5jb25maWd1cmUodGhpcy5vcHRpb25zLnRhc2tMaXN0KSlcbiAgICB9XG5cbiAgICByZXR1cm4gZXh0ZW5zaW9uc1xuICB9LFxufSlcbiIsICJpbXBvcnQgeyBtZXJnZUF0dHJpYnV0ZXMsIE5vZGUsIHdyYXBwaW5nSW5wdXRSdWxlIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5pbXBvcnQgeyBidWlsZE5lc3RlZFN0cnVjdHVyZSwgY29sbGVjdE9yZGVyZWRMaXN0SXRlbXMsIHBhcnNlTGlzdEl0ZW1zIH0gZnJvbSAnLi91dGlscy5qcydcblxuY29uc3QgTGlzdEl0ZW1OYW1lID0gJ2xpc3RJdGVtJ1xuY29uc3QgVGV4dFN0eWxlTmFtZSA9ICd0ZXh0U3R5bGUnXG5cbmV4cG9ydCBpbnRlcmZhY2UgT3JkZXJlZExpc3RPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBub2RlIHR5cGUgbmFtZSBmb3IgbGlzdCBpdGVtcy5cbiAgICogQGRlZmF1bHQgJ2xpc3RJdGVtJ1xuICAgKiBAZXhhbXBsZSAnbXlMaXN0SXRlbSdcbiAgICovXG4gIGl0ZW1UeXBlTmFtZTogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSBIVE1MIGF0dHJpYnV0ZXMgZm9yIGFuIG9yZGVyZWQgbGlzdCBub2RlLlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAZXhhbXBsZSB7IGNsYXNzOiAnZm9vJyB9XG4gICAqL1xuICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PlxuXG4gIC8qKlxuICAgKiBLZWVwIHRoZSBtYXJrcyB3aGVuIHNwbGl0dGluZyBhIGxpc3QgaXRlbS5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGV4YW1wbGUgdHJ1ZVxuICAgKi9cbiAga2VlcE1hcmtzOiBib29sZWFuXG5cbiAgLyoqXG4gICAqIEtlZXAgdGhlIGF0dHJpYnV0ZXMgd2hlbiBzcGxpdHRpbmcgYSBsaXN0IGl0ZW0uXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqIEBleGFtcGxlIHRydWVcbiAgICovXG4gIGtlZXBBdHRyaWJ1dGVzOiBib29sZWFuXG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBvcmRlcmVkTGlzdDoge1xuICAgICAgLyoqXG4gICAgICAgKiBUb2dnbGUgYW4gb3JkZXJlZCBsaXN0XG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudG9nZ2xlT3JkZXJlZExpc3QoKVxuICAgICAgICovXG4gICAgICB0b2dnbGVPcmRlcmVkTGlzdDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE1hdGNoZXMgYW4gb3JkZXJlZCBsaXN0IHRvIGEgMS4gb24gaW5wdXQgKG9yIGFueSBudW1iZXIgZm9sbG93ZWQgYnkgYSBkb3QpLlxuICovXG5leHBvcnQgY29uc3Qgb3JkZXJlZExpc3RJbnB1dFJlZ2V4ID0gL14oXFxkKylcXC5cXHMkL1xuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gY3JlYXRlIG9yZGVyZWQgbGlzdHMuXG4gKiBUaGlzIHJlcXVpcmVzIHRoZSBMaXN0SXRlbSBleHRlbnNpb25cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvbm9kZXMvb3JkZXJlZC1saXN0XG4gKiBAc2VlIGh0dHBzOi8vd3d3LnRpcHRhcC5kZXYvYXBpL25vZGVzL2xpc3QtaXRlbVxuICovXG5leHBvcnQgY29uc3QgT3JkZXJlZExpc3QgPSBOb2RlLmNyZWF0ZTxPcmRlcmVkTGlzdE9wdGlvbnM+KHtcbiAgbmFtZTogJ29yZGVyZWRMaXN0JyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBpdGVtVHlwZU5hbWU6ICdsaXN0SXRlbScsXG4gICAgICBIVE1MQXR0cmlidXRlczoge30sXG4gICAgICBrZWVwTWFya3M6IGZhbHNlLFxuICAgICAga2VlcEF0dHJpYnV0ZXM6IGZhbHNlLFxuICAgIH1cbiAgfSxcblxuICBncm91cDogJ2Jsb2NrIGxpc3QnLFxuXG4gIGNvbnRlbnQoKSB7XG4gICAgcmV0dXJuIGAke3RoaXMub3B0aW9ucy5pdGVtVHlwZU5hbWV9K2BcbiAgfSxcblxuICBhZGRBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGFydDoge1xuICAgICAgICBkZWZhdWx0OiAxLFxuICAgICAgICBwYXJzZUhUTUw6IGVsZW1lbnQgPT4ge1xuICAgICAgICAgIHJldHVybiBlbGVtZW50Lmhhc0F0dHJpYnV0ZSgnc3RhcnQnKVxuICAgICAgICAgICAgPyBwYXJzZUludChlbGVtZW50LmdldEF0dHJpYnV0ZSgnc3RhcnQnKSB8fCAnJywgMTApXG4gICAgICAgICAgICA6IDFcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB0eXBlOiB7XG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICAgIHBhcnNlSFRNTDogZWxlbWVudCA9PiBlbGVtZW50LmdldEF0dHJpYnV0ZSgndHlwZScpLFxuICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIHRhZzogJ29sJyxcbiAgICAgIH0sXG4gICAgXVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgY29uc3QgeyBzdGFydCwgLi4uYXR0cmlidXRlc1dpdGhvdXRTdGFydCB9ID0gSFRNTEF0dHJpYnV0ZXNcblxuICAgIHJldHVybiBzdGFydCA9PT0gMVxuICAgICAgPyBbJ29sJywgbWVyZ2VBdHRyaWJ1dGVzKHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcywgYXR0cmlidXRlc1dpdGhvdXRTdGFydCksIDBdXG4gICAgICA6IFsnb2wnLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyksIDBdXG4gIH0sXG5cbiAgbWFya2Rvd25Ub2tlbk5hbWU6ICdsaXN0JyxcblxuICBwYXJzZU1hcmtkb3duOiAodG9rZW4sIGhlbHBlcnMpID0+IHtcbiAgICBpZiAodG9rZW4udHlwZSAhPT0gJ2xpc3QnIHx8ICF0b2tlbi5vcmRlcmVkKSB7XG4gICAgICByZXR1cm4gW11cbiAgICB9XG5cbiAgICBjb25zdCBzdGFydFZhbHVlID0gdG9rZW4uc3RhcnQgfHwgMVxuICAgIGNvbnN0IGNvbnRlbnQgPSB0b2tlbi5pdGVtcyA/IHBhcnNlTGlzdEl0ZW1zKHRva2VuLml0ZW1zLCBoZWxwZXJzKSA6IFtdXG5cbiAgICBpZiAoc3RhcnRWYWx1ZSAhPT0gMSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ29yZGVyZWRMaXN0JyxcbiAgICAgICAgYXR0cnM6IHsgc3RhcnQ6IHN0YXJ0VmFsdWUgfSxcbiAgICAgICAgY29udGVudCxcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogJ29yZGVyZWRMaXN0JyxcbiAgICAgIGNvbnRlbnQsXG4gICAgfVxuICB9LFxuXG4gIHJlbmRlck1hcmtkb3duOiAobm9kZSwgaCkgPT4ge1xuICAgIGlmICghbm9kZS5jb250ZW50KSB7XG4gICAgICByZXR1cm4gJydcbiAgICB9XG5cbiAgICByZXR1cm4gaC5yZW5kZXJDaGlsZHJlbihub2RlLmNvbnRlbnQsICdcXG4nKVxuICB9LFxuXG4gIG1hcmtkb3duVG9rZW5pemVyOiB7XG4gICAgbmFtZTogJ29yZGVyZWRMaXN0JyxcbiAgICBsZXZlbDogJ2Jsb2NrJyxcbiAgICBzdGFydDogKHNyYzogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBtYXRjaCA9IHNyYy5tYXRjaCgvXihcXHMqKShcXGQrKVxcLlxccysvKVxuICAgICAgY29uc3QgaW5kZXggPSBtYXRjaD8uaW5kZXhcbiAgICAgIHJldHVybiBpbmRleCAhPT0gdW5kZWZpbmVkID8gaW5kZXggOiAtMVxuICAgIH0sXG4gICAgdG9rZW5pemU6IChzcmM6IHN0cmluZywgX3Rva2VucywgbGV4ZXIpID0+IHtcbiAgICAgIGNvbnN0IGxpbmVzID0gc3JjLnNwbGl0KCdcXG4nKVxuICAgICAgY29uc3QgW2xpc3RJdGVtcywgY29uc3VtZWRdID0gY29sbGVjdE9yZGVyZWRMaXN0SXRlbXMobGluZXMpXG5cbiAgICAgIGlmIChsaXN0SXRlbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXRlbXMgPSBidWlsZE5lc3RlZFN0cnVjdHVyZShsaXN0SXRlbXMsIDAsIGxleGVyKVxuXG4gICAgICBpZiAoaXRlbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWRcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhcnRWYWx1ZSA9IGxpc3RJdGVtc1swXT8ubnVtYmVyIHx8IDFcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2xpc3QnLFxuICAgICAgICBvcmRlcmVkOiB0cnVlLFxuICAgICAgICBzdGFydDogc3RhcnRWYWx1ZSxcbiAgICAgICAgaXRlbXMsXG4gICAgICAgIHJhdzogbGluZXMuc2xpY2UoMCwgY29uc3VtZWQpLmpvaW4oJ1xcbicpLFxuICAgICAgfSBhcyB1bmtub3duIGFzIG9iamVjdFxuICAgIH0sXG4gIH0sXG5cbiAgbWFya2Rvd25PcHRpb25zOiB7XG4gICAgaW5kZW50c0NvbnRlbnQ6IHRydWUsXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRvZ2dsZU9yZGVyZWRMaXN0OlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBjb21tYW5kcywgY2hhaW4gfSkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMua2VlcEF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgIHJldHVybiBjaGFpbigpXG4gICAgICAgICAgICAgIC50b2dnbGVMaXN0KHRoaXMubmFtZSwgdGhpcy5vcHRpb25zLml0ZW1UeXBlTmFtZSwgdGhpcy5vcHRpb25zLmtlZXBNYXJrcylcbiAgICAgICAgICAgICAgLnVwZGF0ZUF0dHJpYnV0ZXMoTGlzdEl0ZW1OYW1lLCB0aGlzLmVkaXRvci5nZXRBdHRyaWJ1dGVzKFRleHRTdHlsZU5hbWUpKVxuICAgICAgICAgICAgICAucnVuKClcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnRvZ2dsZUxpc3QodGhpcy5uYW1lLCB0aGlzLm9wdGlvbnMuaXRlbVR5cGVOYW1lLCB0aGlzLm9wdGlvbnMua2VlcE1hcmtzKVxuICAgICAgICB9LFxuICAgIH1cbiAgfSxcblxuICBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgJ01vZC1TaGlmdC03JzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMudG9nZ2xlT3JkZXJlZExpc3QoKSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkSW5wdXRSdWxlcygpIHtcbiAgICBsZXQgaW5wdXRSdWxlID0gd3JhcHBpbmdJbnB1dFJ1bGUoe1xuICAgICAgZmluZDogb3JkZXJlZExpc3RJbnB1dFJlZ2V4LFxuICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgZ2V0QXR0cmlidXRlczogbWF0Y2ggPT4gKHsgc3RhcnQ6ICttYXRjaFsxXSB9KSxcbiAgICAgIGpvaW5QcmVkaWNhdGU6IChtYXRjaCwgbm9kZSkgPT4gbm9kZS5jaGlsZENvdW50ICsgbm9kZS5hdHRycy5zdGFydCA9PT0gK21hdGNoWzFdLFxuICAgIH0pXG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmtlZXBNYXJrcyB8fCB0aGlzLm9wdGlvbnMua2VlcEF0dHJpYnV0ZXMpIHtcbiAgICAgIGlucHV0UnVsZSA9IHdyYXBwaW5nSW5wdXRSdWxlKHtcbiAgICAgICAgZmluZDogb3JkZXJlZExpc3RJbnB1dFJlZ2V4LFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICAgIGtlZXBNYXJrczogdGhpcy5vcHRpb25zLmtlZXBNYXJrcyxcbiAgICAgICAga2VlcEF0dHJpYnV0ZXM6IHRoaXMub3B0aW9ucy5rZWVwQXR0cmlidXRlcyxcbiAgICAgICAgZ2V0QXR0cmlidXRlczogbWF0Y2ggPT4gKHsgc3RhcnQ6ICttYXRjaFsxXSwgLi4udGhpcy5lZGl0b3IuZ2V0QXR0cmlidXRlcyhUZXh0U3R5bGVOYW1lKSB9KSxcbiAgICAgICAgam9pblByZWRpY2F0ZTogKG1hdGNoLCBub2RlKSA9PiBub2RlLmNoaWxkQ291bnQgKyBub2RlLmF0dHJzLnN0YXJ0ID09PSArbWF0Y2hbMV0sXG4gICAgICAgIGVkaXRvcjogdGhpcy5lZGl0b3IsXG4gICAgICB9KVxuICAgIH1cbiAgICByZXR1cm4gW2lucHV0UnVsZV1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHR5cGUge1xuICBKU09OQ29udGVudCxcbiAgTWFya2Rvd25MZXhlckNvbmZpZ3VyYXRpb24sXG4gIE1hcmtkb3duUGFyc2VIZWxwZXJzLFxuICBNYXJrZG93blRva2VuLFxufSBmcm9tICdAdGlwdGFwL2NvcmUnXG5cbi8qKlxuICogTWF0Y2hlcyBhbiBvcmRlcmVkIGxpc3QgaXRlbSBsaW5lIHdpdGggb3B0aW9uYWwgbGVhZGluZyB3aGl0ZXNwYWNlLlxuICogQ2FwdHVyZXM6ICgxKSBpbmRlbnRhdGlvbiBzcGFjZXMsICgyKSBpdGVtIG51bWJlciwgKDMpIGNvbnRlbnQgYWZ0ZXIgbWFya2VyXG4gKiBFeGFtcGxlIG1hdGNoZXM6IFwiMS4gSXRlbVwiLCBcIiAgMi4gTmVzdGVkIGl0ZW1cIiwgXCIgICAgMy4gRGVlcGx5IG5lc3RlZFwiXG4gKi9cbmNvbnN0IE9SREVSRURfTElTVF9JVEVNX1JFR0VYID0gL14oXFxzKikoXFxkKylcXC5cXHMrKC4qKSQvXG5cbi8qKlxuICogTWF0Y2hlcyBhbnkgbGluZSB0aGF0IHN0YXJ0cyB3aXRoIHdoaXRlc3BhY2UgKGluZGVudGVkIGNvbnRlbnQpLlxuICogVXNlZCB0byBpZGVudGlmeSBjb250aW51YXRpb24gY29udGVudCB0aGF0IGJlbG9uZ3MgdG8gYSBsaXN0IGl0ZW0uXG4gKi9cbmNvbnN0IElOREVOVEVEX0xJTkVfUkVHRVggPSAvXlxccy9cblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgcGFyc2VkIG9yZGVyZWQgbGlzdCBpdGVtIHdpdGggaW5kZW50YXRpb24gaW5mb3JtYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcmRlcmVkTGlzdEl0ZW0ge1xuICBpbmRlbnQ6IG51bWJlclxuICBudW1iZXI6IG51bWJlclxuICBjb250ZW50OiBzdHJpbmdcbiAgY29udGVudExpbmVzOiBzdHJpbmdbXVxuICByYXc6IHN0cmluZ1xufVxuXG5mdW5jdGlvbiBpc0Jsb2NrQ29udGVudExpbmUobGluZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IHRyaW1tZWRMaW5lID0gbGluZS50cmltU3RhcnQoKVxuXG4gIHJldHVybiAoXG4gICAgLy8gb3hsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1zdHJpbmctc3RhcnRzLWVuZHMtd2l0aFxuICAgIC9eWy0rKl1cXHMrLy50ZXN0KHRyaW1tZWRMaW5lKSB8fFxuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItc3RyaW5nLXN0YXJ0cy1lbmRzLXdpdGhcbiAgICAvXlxcZCtcXC5cXHMrLy50ZXN0KHRyaW1tZWRMaW5lKSB8fFxuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItc3RyaW5nLXN0YXJ0cy1lbmRzLXdpdGhcbiAgICAvXj5cXHM/Ly50ZXN0KHRyaW1tZWRMaW5lKSB8fFxuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItc3RyaW5nLXN0YXJ0cy1lbmRzLXdpdGhcbiAgICAvXmBgYC8udGVzdCh0cmltbWVkTGluZSkgfHxcbiAgICAvLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcHJlZmVyLXN0cmluZy1zdGFydHMtZW5kcy13aXRoXG4gICAgL15+fn4vLnRlc3QodHJpbW1lZExpbmUpXG4gIClcbn1cblxuZnVuY3Rpb24gc3BsaXRJdGVtQ29udGVudChjb250ZW50TGluZXM6IHN0cmluZ1tdKToge1xuICBwYXJhZ3JhcGhMaW5lczogc3RyaW5nW11cbiAgYmxvY2tMaW5lczogc3RyaW5nW11cbn0ge1xuICBjb25zdCBwYXJhZ3JhcGhMaW5lczogc3RyaW5nW10gPSBbXVxuICBjb25zdCBibG9ja0xpbmVzOiBzdHJpbmdbXSA9IFtdXG4gIGxldCByZWFjaGVkQmxvY2tCb3VuZGFyeSA9IGZhbHNlXG5cbiAgY29udGVudExpbmVzLmZvckVhY2gobGluZSA9PiB7XG4gICAgaWYgKHJlYWNoZWRCbG9ja0JvdW5kYXJ5KSB7XG4gICAgICBibG9ja0xpbmVzLnB1c2gobGluZSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChsaW5lLnRyaW0oKSA9PT0gJycpIHtcbiAgICAgIHJlYWNoZWRCbG9ja0JvdW5kYXJ5ID0gdHJ1ZVxuICAgICAgYmxvY2tMaW5lcy5wdXNoKGxpbmUpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAocGFyYWdyYXBoTGluZXMubGVuZ3RoID4gMCAmJiBpc0Jsb2NrQ29udGVudExpbmUobGluZSkpIHtcbiAgICAgIHJlYWNoZWRCbG9ja0JvdW5kYXJ5ID0gdHJ1ZVxuICAgICAgYmxvY2tMaW5lcy5wdXNoKGxpbmUpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBwYXJhZ3JhcGhMaW5lcy5wdXNoKGxpbmUpXG4gIH0pXG5cbiAgcmV0dXJuIHtcbiAgICBwYXJhZ3JhcGhMaW5lcyxcbiAgICBibG9ja0xpbmVzLFxuICB9XG59XG5cbi8qKlxuICogQ29sbGVjdHMgYWxsIG9yZGVyZWQgbGlzdCBpdGVtcyBmcm9tIGxpbmVzLCBwYXJzaW5nIHRoZW0gaW50byBhIGZsYXQgYXJyYXlcbiAqIHdpdGggaW5kZW50YXRpb24gaW5mb3JtYXRpb24uIFN0b3BzIGNvbGxlY3RpbmcgY29udGludWF0aW9uIGNvbnRlbnQgd2hlblxuICogZW5jb3VudGVyaW5nIG5lc3RlZCBsaXN0IGl0ZW1zLCBhbGxvd2luZyB0aGVtIHRvIGJlIHByb2Nlc3NlZCBzZXBhcmF0ZWx5LlxuICpcbiAqIEBwYXJhbSBsaW5lcyAtIEFycmF5IG9mIHNvdXJjZSBsaW5lcyB0byBwYXJzZVxuICogQHJldHVybnMgVHVwbGUgb2YgW2xpc3RJdGVtcyBhcnJheSwgbnVtYmVyIG9mIGxpbmVzIGNvbnN1bWVkXVxuICovXG5leHBvcnQgZnVuY3Rpb24gY29sbGVjdE9yZGVyZWRMaXN0SXRlbXMobGluZXM6IHN0cmluZ1tdKTogW09yZGVyZWRMaXN0SXRlbVtdLCBudW1iZXJdIHtcbiAgY29uc3QgbGlzdEl0ZW1zOiBPcmRlcmVkTGlzdEl0ZW1bXSA9IFtdXG4gIGxldCBjdXJyZW50TGluZUluZGV4ID0gMFxuICBsZXQgY29uc3VtZWQgPSAwXG5cbiAgd2hpbGUgKGN1cnJlbnRMaW5lSW5kZXggPCBsaW5lcy5sZW5ndGgpIHtcbiAgICBjb25zdCBsaW5lID0gbGluZXNbY3VycmVudExpbmVJbmRleF1cbiAgICBjb25zdCBtYXRjaCA9IGxpbmUubWF0Y2goT1JERVJFRF9MSVNUX0lURU1fUkVHRVgpXG5cbiAgICBpZiAoIW1hdGNoKSB7XG4gICAgICBicmVha1xuICAgIH1cblxuICAgIGNvbnN0IFssIGluZGVudCwgbnVtYmVyLCBjb250ZW50XSA9IG1hdGNoXG4gICAgY29uc3QgaW5kZW50TGV2ZWwgPSBpbmRlbnQubGVuZ3RoXG4gICAgY29uc3QgaXRlbUNvbnRlbnRMaW5lcyA9IFtjb250ZW50XVxuICAgIGxldCBuZXh0TGluZUluZGV4ID0gY3VycmVudExpbmVJbmRleCArIDFcbiAgICBjb25zdCBpdGVtTGluZXMgPSBbbGluZV1cbiAgICBsZXQgc2F3QmxhbmtMaW5lID0gZmFsc2VcblxuICAgIC8vIENvbGxlY3QgY29udGludWF0aW9uIGxpbmVzIGZvciB0aGlzIGl0ZW0gKGJ1dCBOT1QgbmVzdGVkIGxpc3QgaXRlbXMpXG4gICAgd2hpbGUgKG5leHRMaW5lSW5kZXggPCBsaW5lcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5leHRMaW5lID0gbGluZXNbbmV4dExpbmVJbmRleF1cbiAgICAgIGNvbnN0IG5leHRNYXRjaCA9IG5leHRMaW5lLm1hdGNoKE9SREVSRURfTElTVF9JVEVNX1JFR0VYKVxuXG4gICAgICAvLyBJZiBpdCdzIGFub3RoZXIgbGlzdCBpdGVtIChuZXN0ZWQgb3Igbm90KSwgc3RvcCBjb2xsZWN0aW5nXG4gICAgICBpZiAobmV4dE1hdGNoKSB7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGZvciBjb250aW51YXRpb24gY29udGVudCAobm9uLWxpc3QgY29udGVudClcbiAgICAgIGlmIChuZXh0TGluZS50cmltKCkgPT09ICcnKSB7XG4gICAgICAgIC8vIEVtcHR5IGxpbmVcbiAgICAgICAgaXRlbUxpbmVzLnB1c2gobmV4dExpbmUpXG4gICAgICAgIGl0ZW1Db250ZW50TGluZXMucHVzaCgnJylcbiAgICAgICAgc2F3QmxhbmtMaW5lID0gdHJ1ZVxuICAgICAgICBuZXh0TGluZUluZGV4ICs9IDFcbiAgICAgIH0gZWxzZSBpZiAobmV4dExpbmUubWF0Y2goSU5ERU5URURfTElORV9SRUdFWCkpIHtcbiAgICAgICAgLy8gSW5kZW50ZWQgY29udGVudCAtIHBhcnQgb2YgdGhpcyBpdGVtIChidXQgbm90IGEgbGlzdCBpdGVtKVxuICAgICAgICBpdGVtTGluZXMucHVzaChuZXh0TGluZSlcbiAgICAgICAgaXRlbUNvbnRlbnRMaW5lcy5wdXNoKG5leHRMaW5lLnNsaWNlKGluZGVudExldmVsICsgMikpXG4gICAgICAgIG5leHRMaW5lSW5kZXggKz0gMVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNhd0JsYW5rTGluZSkge1xuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cblxuICAgICAgICBpdGVtTGluZXMucHVzaChuZXh0TGluZSlcbiAgICAgICAgaXRlbUNvbnRlbnRMaW5lcy5wdXNoKG5leHRMaW5lKVxuICAgICAgICBuZXh0TGluZUluZGV4ICs9IDFcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsaXN0SXRlbXMucHVzaCh7XG4gICAgICBpbmRlbnQ6IGluZGVudExldmVsLFxuICAgICAgbnVtYmVyOiBwYXJzZUludChudW1iZXIsIDEwKSxcbiAgICAgIGNvbnRlbnQ6IGl0ZW1Db250ZW50TGluZXMuam9pbignXFxuJykudHJpbSgpLFxuICAgICAgY29udGVudExpbmVzOiBpdGVtQ29udGVudExpbmVzLFxuICAgICAgcmF3OiBpdGVtTGluZXMuam9pbignXFxuJyksXG4gICAgfSlcblxuICAgIGNvbnN1bWVkID0gbmV4dExpbmVJbmRleFxuICAgIGN1cnJlbnRMaW5lSW5kZXggPSBuZXh0TGluZUluZGV4XG4gIH1cblxuICByZXR1cm4gW2xpc3RJdGVtcywgY29uc3VtZWRdXG59XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgYnVpbGRzIGEgbmVzdGVkIHN0cnVjdHVyZSBmcm9tIGEgZmxhdCBhcnJheSBvZiBsaXN0IGl0ZW1zXG4gKiBiYXNlZCBvbiB0aGVpciBpbmRlbnRhdGlvbiBsZXZlbHMuIENyZWF0ZXMgcHJvcGVyIG1hcmtkb3duIHRva2VucyB3aXRoXG4gKiBuZXN0ZWQgbGlzdHMgd2hlcmUgYXBwcm9wcmlhdGUuXG4gKlxuICogQHBhcmFtIGl0ZW1zIC0gRmxhdCBhcnJheSBvZiBsaXN0IGl0ZW1zIHdpdGggaW5kZW50YXRpb24gaW5mb1xuICogQHBhcmFtIGJhc2VJbmRlbnQgLSBUaGUgaW5kZW50YXRpb24gbGV2ZWwgdG8gcHJvY2VzcyBhdCB0aGlzIHJlY3Vyc2lvbiBsZXZlbFxuICogQHBhcmFtIGxleGVyIC0gTWFya2Rvd24gbGV4ZXIgZm9yIHBhcnNpbmcgaW5saW5lIGFuZCBibG9jayBjb250ZW50XG4gKiBAcmV0dXJucyBBcnJheSBvZiBsaXN0X2l0ZW0gdG9rZW5zIHdpdGggcHJvcGVyIG5lc3RpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkTmVzdGVkU3RydWN0dXJlKFxuICBpdGVtczogT3JkZXJlZExpc3RJdGVtW10sXG4gIGJhc2VJbmRlbnQ6IG51bWJlcixcbiAgbGV4ZXI6IE1hcmtkb3duTGV4ZXJDb25maWd1cmF0aW9uLFxuKTogdW5rbm93bltdIHtcbiAgY29uc3QgcmVzdWx0OiB1bmtub3duW10gPSBbXVxuICBsZXQgY3VycmVudEluZGV4ID0gMFxuXG4gIHdoaWxlIChjdXJyZW50SW5kZXggPCBpdGVtcy5sZW5ndGgpIHtcbiAgICBjb25zdCBpdGVtID0gaXRlbXNbY3VycmVudEluZGV4XVxuXG4gICAgaWYgKGl0ZW0uaW5kZW50ID09PSBiYXNlSW5kZW50KSB7XG4gICAgICAvLyBUaGlzIGl0ZW0gYmVsb25ncyBhdCB0aGUgY3VycmVudCBsZXZlbFxuICAgICAgY29uc3QgeyBwYXJhZ3JhcGhMaW5lcywgYmxvY2tMaW5lcyB9ID0gc3BsaXRJdGVtQ29udGVudChpdGVtLmNvbnRlbnRMaW5lcylcbiAgICAgIGNvbnN0IG1haW5UZXh0ID0gcGFyYWdyYXBoTGluZXMuam9pbignXFxuJykudHJpbSgpXG5cbiAgICAgIGNvbnN0IHRva2VucyA9IFtdXG5cbiAgICAgIC8vIEFsd2F5cyB3cmFwIHRoZSBtYWluIHRleHQgaW4gYSBwYXJhZ3JhcGggdG9rZW5cbiAgICAgIGlmIChtYWluVGV4dCkge1xuICAgICAgICB0b2tlbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ3BhcmFncmFwaCcsXG4gICAgICAgICAgcmF3OiBtYWluVGV4dCxcbiAgICAgICAgICB0b2tlbnM6IGxleGVyLmlubGluZVRva2VucyhtYWluVGV4dCksXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFkZGl0aW9uYWxDb250ZW50ID0gYmxvY2tMaW5lcy5qb2luKCdcXG4nKS50cmltKClcbiAgICAgIGlmIChhZGRpdGlvbmFsQ29udGVudCkge1xuICAgICAgICBjb25zdCBibG9ja1Rva2VucyA9IGxleGVyLmJsb2NrVG9rZW5zKGFkZGl0aW9uYWxDb250ZW50KVxuICAgICAgICB0b2tlbnMucHVzaCguLi5ibG9ja1Rva2VucylcbiAgICAgIH1cblxuICAgICAgLy8gTG9vayBhaGVhZCB0byBmaW5kIG5lc3RlZCBpdGVtcyBhdCBkZWVwZXIgaW5kZW50IGxldmVsc1xuICAgICAgbGV0IGxvb2tBaGVhZEluZGV4ID0gY3VycmVudEluZGV4ICsgMVxuICAgICAgY29uc3QgbmVzdGVkSXRlbXMgPSBbXVxuXG4gICAgICB3aGlsZSAobG9va0FoZWFkSW5kZXggPCBpdGVtcy5sZW5ndGggJiYgaXRlbXNbbG9va0FoZWFkSW5kZXhdLmluZGVudCA+IGJhc2VJbmRlbnQpIHtcbiAgICAgICAgbmVzdGVkSXRlbXMucHVzaChpdGVtc1tsb29rQWhlYWRJbmRleF0pXG4gICAgICAgIGxvb2tBaGVhZEluZGV4ICs9IDFcbiAgICAgIH1cblxuICAgICAgLy8gSWYgd2UgaGF2ZSBuZXN0ZWQgaXRlbXMsIHJlY3Vyc2l2ZWx5IGJ1aWxkIHRoZWlyIHN0cnVjdHVyZVxuICAgICAgaWYgKG5lc3RlZEl0ZW1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gRmluZCB0aGUgbmV4dCBpbmRlbnQgbGV2ZWwgKGltbWVkaWF0ZSBjaGlsZHJlbilcbiAgICAgICAgY29uc3QgbmV4dEluZGVudCA9IE1hdGgubWluKC4uLm5lc3RlZEl0ZW1zLm1hcChuZXN0ZWRJdGVtID0+IG5lc3RlZEl0ZW0uaW5kZW50KSlcblxuICAgICAgICAvLyBCdWlsZCB0aGUgbmVzdGVkIGxpc3QgcmVjdXJzaXZlbHkgd2l0aCBhbGwgbmVzdGVkIGl0ZW1zXG4gICAgICAgIC8vIFRoZSByZWN1cnNpdmUgY2FsbCB3aWxsIGhhbmRsZSBmdXJ0aGVyIG5lc3RpbmdcbiAgICAgICAgY29uc3QgbmVzdGVkTGlzdEl0ZW1zID0gYnVpbGROZXN0ZWRTdHJ1Y3R1cmUobmVzdGVkSXRlbXMsIG5leHRJbmRlbnQsIGxleGVyKVxuXG4gICAgICAgIC8vIENyZWF0ZSBhIG5lc3RlZCBsaXN0IHRva2VuXG4gICAgICAgIHRva2Vucy5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAnbGlzdCcsXG4gICAgICAgICAgb3JkZXJlZDogdHJ1ZSxcbiAgICAgICAgICBzdGFydDogbmVzdGVkSXRlbXNbMF0ubnVtYmVyLFxuICAgICAgICAgIGl0ZW1zOiBuZXN0ZWRMaXN0SXRlbXMsXG4gICAgICAgICAgcmF3OiBuZXN0ZWRJdGVtcy5tYXAobmVzdGVkSXRlbSA9PiBuZXN0ZWRJdGVtLnJhdykuam9pbignXFxuJyksXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgdHlwZTogJ2xpc3RfaXRlbScsXG4gICAgICAgIHJhdzogaXRlbS5yYXcsXG4gICAgICAgIHRva2VucyxcbiAgICAgIH0pXG5cbiAgICAgIC8vIFNraXAgdGhlIG5lc3RlZCBpdGVtcyB3ZSBqdXN0IHByb2Nlc3NlZFxuICAgICAgY3VycmVudEluZGV4ID0gbG9va0FoZWFkSW5kZXhcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVGhpcyBpdGVtIGhhcyBkZWVwZXIgaW5kZW50IHRoYW4gd2UncmUgY3VycmVudGx5IHByb2Nlc3NpbmdcbiAgICAgIC8vIEl0IHNob3VsZCBiZSBoYW5kbGVkIGJ5IGEgcmVjdXJzaXZlIGNhbGxcbiAgICAgIGN1cnJlbnRJbmRleCArPSAxXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vKipcbiAqIFBhcnNlcyBtYXJrZG93biBsaXN0IGl0ZW0gdG9rZW5zIGludG8gVGlwdGFwIEpTT05Db250ZW50IHN0cnVjdHVyZSxcbiAqIGVuc3VyaW5nIHRleHQgY29udGVudCBpcyBwcm9wZXJseSB3cmFwcGVkIGluIHBhcmFncmFwaCBub2Rlcy5cbiAqXG4gKiBAcGFyYW0gaXRlbXMgLSBBcnJheSBvZiBtYXJrZG93biB0b2tlbnMgcmVwcmVzZW50aW5nIGxpc3QgaXRlbXNcbiAqIEBwYXJhbSBoZWxwZXJzIC0gTWFya2Rvd24gcGFyc2UgaGVscGVycyBmb3IgcmVjdXJzaXZlIHBhcnNpbmdcbiAqIEByZXR1cm5zIEFycmF5IG9mIGxpc3RJdGVtIEpTT05Db250ZW50IG5vZGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxpc3RJdGVtcyhcbiAgaXRlbXM6IE1hcmtkb3duVG9rZW5bXSxcbiAgaGVscGVyczogTWFya2Rvd25QYXJzZUhlbHBlcnMsXG4pOiBKU09OQ29udGVudFtdIHtcbiAgcmV0dXJuIGl0ZW1zLm1hcChpdGVtID0+IHtcbiAgICBpZiAoaXRlbS50eXBlICE9PSAnbGlzdF9pdGVtJykge1xuICAgICAgcmV0dXJuIGhlbHBlcnMucGFyc2VDaGlsZHJlbihbaXRlbV0pWzBdXG4gICAgfVxuXG4gICAgLy8gUGFyc2UgdGhlIHRva2VucyB3aXRoaW4gdGhlIGxpc3QgaXRlbVxuICAgIGNvbnN0IGNvbnRlbnQ6IEpTT05Db250ZW50W10gPSBbXVxuXG4gICAgaWYgKGl0ZW0udG9rZW5zICYmIGl0ZW0udG9rZW5zLmxlbmd0aCA+IDApIHtcbiAgICAgIGl0ZW0udG9rZW5zLmZvckVhY2goaXRlbVRva2VuID0+IHtcbiAgICAgICAgLy8gSWYgaXQncyBhbHJlYWR5IGEgcHJvcGVyIGJsb2NrIG5vZGUgKHBhcmFncmFwaCwgbGlzdCwgZXRjLiksIHBhcnNlIGl0IGRpcmVjdGx5XG4gICAgICAgIGlmIChcbiAgICAgICAgICBpdGVtVG9rZW4udHlwZSA9PT0gJ3BhcmFncmFwaCcgfHxcbiAgICAgICAgICBpdGVtVG9rZW4udHlwZSA9PT0gJ2xpc3QnIHx8XG4gICAgICAgICAgaXRlbVRva2VuLnR5cGUgPT09ICdibG9ja3F1b3RlJyB8fFxuICAgICAgICAgIGl0ZW1Ub2tlbi50eXBlID09PSAnY29kZSdcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29udGVudC5wdXNoKC4uLmhlbHBlcnMucGFyc2VDaGlsZHJlbihbaXRlbVRva2VuXSkpXG4gICAgICAgIH0gZWxzZSBpZiAoaXRlbVRva2VuLnR5cGUgPT09ICd0ZXh0JyAmJiBpdGVtVG9rZW4udG9rZW5zKSB7XG4gICAgICAgICAgLy8gSWYgaXQncyBpbmxpbmUgdGV4dCB0b2tlbnMsIHdyYXAgdGhlbSBpbiBhIHBhcmFncmFwaFxuICAgICAgICAgIGNvbnN0IGlubGluZUNvbnRlbnQgPSBoZWxwZXJzLnBhcnNlQ2hpbGRyZW4oW2l0ZW1Ub2tlbl0pXG4gICAgICAgICAgY29udGVudC5wdXNoKHtcbiAgICAgICAgICAgIHR5cGU6ICdwYXJhZ3JhcGgnLFxuICAgICAgICAgICAgY29udGVudDogaW5saW5lQ29udGVudCxcbiAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIEZvciBhbnkgb3RoZXIgY29udGVudCwgdHJ5IHRvIHBhcnNlIGl0XG4gICAgICAgICAgY29uc3QgcGFyc2VkID0gaGVscGVycy5wYXJzZUNoaWxkcmVuKFtpdGVtVG9rZW5dKVxuICAgICAgICAgIGlmIChwYXJzZWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29udGVudC5wdXNoKC4uLnBhcnNlZClcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdsaXN0SXRlbScsXG4gICAgICBjb250ZW50LFxuICAgIH1cbiAgfSlcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEtleWJvYXJkU2hvcnRjdXRDb21tYW5kIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHtcbiAgZ2V0UmVuZGVyZWRBdHRyaWJ1dGVzLFxuICBtZXJnZUF0dHJpYnV0ZXMsXG4gIE5vZGUsXG4gIHJlbmRlck5lc3RlZE1hcmtkb3duQ29udGVudCxcbiAgd3JhcHBpbmdJbnB1dFJ1bGUsXG59IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB0eXBlIHsgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBjcmVhdGVCcmFuY2hpbmdMaXN0RGVsZXRlS2V5bWFwIH0gZnJvbSAnLi4vaGVscGVycy9jcmVhdGVCcmFuY2hpbmdMaXN0RGVsZXRlS2V5bWFwLmpzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFRhc2tJdGVtT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlIGNoZWNrYm94IGlzIGNsaWNrZWQgd2hpbGUgdGhlIGVkaXRvciBpcyBpbiByZWFkb25seSBtb2RlLlxuICAgKiBAcGFyYW0gbm9kZSBUaGUgcHJvc2VtaXJyb3Igbm9kZSBvZiB0aGUgdGFzayBpdGVtXG4gICAqIEBwYXJhbSBjaGVja2VkIFRoZSBuZXcgY2hlY2tlZCBzdGF0ZVxuICAgKiBAcmV0dXJucyBib29sZWFuXG4gICAqL1xuICBvblJlYWRPbmx5Q2hlY2tlZD86IChub2RlOiBQcm9zZU1pcnJvck5vZGUsIGNoZWNrZWQ6IGJvb2xlYW4pID0+IGJvb2xlYW5cblxuICAvKipcbiAgICogQ29udHJvbHMgd2hldGhlciB0aGUgdGFzayBpdGVtcyBjYW4gYmUgbmVzdGVkIG9yIG5vdC5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGV4YW1wbGUgdHJ1ZVxuICAgKi9cbiAgbmVzdGVkOiBib29sZWFuXG5cbiAgLyoqXG4gICAqIEhUTUwgYXR0cmlidXRlcyB0byBhZGQgdG8gdGhlIHRhc2sgaXRlbSBlbGVtZW50LlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAZXhhbXBsZSB7IGNsYXNzOiAnZm9vJyB9XG4gICAqL1xuICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PlxuXG4gIC8qKlxuICAgKiBUaGUgbm9kZSB0eXBlIGZvciB0YXNrTGlzdCBub2Rlc1xuICAgKiBAZGVmYXVsdCAndGFza0xpc3QnXG4gICAqIEBleGFtcGxlICdteUN1c3RvbVRhc2tMaXN0J1xuICAgKi9cbiAgdGFza0xpc3RUeXBlTmFtZTogc3RyaW5nXG5cbiAgLyoqXG4gICAqIEFjY2Vzc2liaWxpdHkgb3B0aW9ucyBmb3IgdGhlIHRhc2sgaXRlbS5cbiAgICogQGRlZmF1bHQge31cbiAgICogQGV4YW1wbGVcbiAgICogYGBganNcbiAgICoge1xuICAgKiAgIGNoZWNrYm94TGFiZWw6IChub2RlKSA9PiBgVGFzayBpdGVtOiAke25vZGUudGV4dENvbnRlbnQgfHwgJ2VtcHR5IHRhc2sgaXRlbSd9YFxuICAgKiB9XG4gICAqL1xuICBhMTF5Pzoge1xuICAgIGNoZWNrYm94TGFiZWw/OiAobm9kZTogUHJvc2VNaXJyb3JOb2RlLCBjaGVja2VkOiBib29sZWFuKSA9PiBzdHJpbmdcbiAgfVxufVxuXG4vKipcbiAqIE1hdGNoZXMgYSB0YXNrIGl0ZW0gdG8gYSAtIFsgXSBvbiBpbnB1dC5cbiAqL1xuZXhwb3J0IGNvbnN0IGlucHV0UmVnZXggPSAvXlxccyooXFxbKFsoIHx4XSk/XFxdKVxccyQvXG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBjcmVhdGUgdGFzayBpdGVtcy5cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvbm9kZXMvdGFzay1pdGVtXG4gKi9cbmV4cG9ydCBjb25zdCBUYXNrSXRlbSA9IE5vZGUuY3JlYXRlPFRhc2tJdGVtT3B0aW9ucz4oe1xuICBuYW1lOiAndGFza0l0ZW0nLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5lc3RlZDogZmFsc2UsXG4gICAgICBIVE1MQXR0cmlidXRlczoge30sXG4gICAgICB0YXNrTGlzdFR5cGVOYW1lOiAndGFza0xpc3QnLFxuICAgICAgYTExeTogdW5kZWZpbmVkLFxuICAgIH1cbiAgfSxcblxuICBjb250ZW50KCkge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMubmVzdGVkID8gJ3BhcmFncmFwaCBibG9jayonIDogJ3BhcmFncmFwaCsnXG4gIH0sXG5cbiAgZGVmaW5pbmc6IHRydWUsXG5cbiAgYWRkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY2hlY2tlZDoge1xuICAgICAgICBkZWZhdWx0OiBmYWxzZSxcbiAgICAgICAga2VlcE9uU3BsaXQ6IGZhbHNlLFxuICAgICAgICBwYXJzZUhUTUw6IGVsZW1lbnQgPT4ge1xuICAgICAgICAgIGNvbnN0IGRhdGFDaGVja2VkID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtY2hlY2tlZCcpXG5cbiAgICAgICAgICByZXR1cm4gZGF0YUNoZWNrZWQgPT09ICcnIHx8IGRhdGFDaGVja2VkID09PSAndHJ1ZSdcbiAgICAgICAgfSxcbiAgICAgICAgcmVuZGVySFRNTDogYXR0cmlidXRlcyA9PiAoe1xuICAgICAgICAgICdkYXRhLWNoZWNrZWQnOiBhdHRyaWJ1dGVzLmNoZWNrZWQsXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIHRhZzogYGxpW2RhdGEtdHlwZT1cIiR7dGhpcy5uYW1lfVwiXWAsXG4gICAgICAgIHByaW9yaXR5OiA1MSxcbiAgICAgIH0sXG4gICAgXVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBub2RlLCBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgcmV0dXJuIFtcbiAgICAgICdsaScsXG4gICAgICBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcywge1xuICAgICAgICAnZGF0YS10eXBlJzogdGhpcy5uYW1lLFxuICAgICAgfSksXG4gICAgICBbXG4gICAgICAgICdsYWJlbCcsXG4gICAgICAgIFtcbiAgICAgICAgICAnaW5wdXQnLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6ICdjaGVja2JveCcsXG4gICAgICAgICAgICBjaGVja2VkOiBub2RlLmF0dHJzLmNoZWNrZWQgPyAnY2hlY2tlZCcgOiBudWxsLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIFsnc3BhbiddLFxuICAgICAgXSxcbiAgICAgIFsnZGl2JywgMF0sXG4gICAgXVxuICB9LFxuXG4gIHBhcnNlTWFya2Rvd246ICh0b2tlbiwgaCkgPT4ge1xuICAgIC8vIFBhcnNlIHRoZSB0YXNrIGl0ZW0ncyB0ZXh0IGNvbnRlbnQgaW50byBwYXJhZ3JhcGggY29udGVudFxuICAgIGNvbnN0IGNvbnRlbnQgPSBbXVxuXG4gICAgLy8gRmlyc3QsIGFkZCB0aGUgbWFpbiBwYXJhZ3JhcGggY29udGVudFxuICAgIGlmICh0b2tlbi50b2tlbnMgJiYgdG9rZW4udG9rZW5zLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIElmIHdlIGhhdmUgdG9rZW5zLCBjcmVhdGUgYSBwYXJhZ3JhcGggd2l0aCB0aGUgaW5saW5lIGNvbnRlbnRcbiAgICAgIGNvbnRlbnQucHVzaChoLmNyZWF0ZU5vZGUoJ3BhcmFncmFwaCcsIHt9LCBoLnBhcnNlSW5saW5lKHRva2VuLnRva2VucykpKVxuICAgIH0gZWxzZSBpZiAodG9rZW4udGV4dCkge1xuICAgICAgLy8gSWYgd2UgaGF2ZSByYXcgdGV4dCwgY3JlYXRlIGEgcGFyYWdyYXBoIHdpdGggdGV4dCBub2RlXG4gICAgICBjb250ZW50LnB1c2goaC5jcmVhdGVOb2RlKCdwYXJhZ3JhcGgnLCB7fSwgW2guY3JlYXRlTm9kZSgndGV4dCcsIHsgdGV4dDogdG9rZW4udGV4dCB9KV0pKVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGYWxsYmFjazogZW1wdHkgcGFyYWdyYXBoXG4gICAgICBjb250ZW50LnB1c2goaC5jcmVhdGVOb2RlKCdwYXJhZ3JhcGgnLCB7fSwgW10pKVxuICAgIH1cblxuICAgIC8vIFRoZW4sIGFkZCBhbnkgbmVzdGVkIGNvbnRlbnQgKGxpa2UgbmVzdGVkIHRhc2sgbGlzdHMpXG4gICAgaWYgKHRva2VuLm5lc3RlZFRva2VucyAmJiB0b2tlbi5uZXN0ZWRUb2tlbnMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgbmVzdGVkQ29udGVudCA9IGgucGFyc2VDaGlsZHJlbih0b2tlbi5uZXN0ZWRUb2tlbnMpXG4gICAgICBjb250ZW50LnB1c2goLi4ubmVzdGVkQ29udGVudClcbiAgICB9XG5cbiAgICByZXR1cm4gaC5jcmVhdGVOb2RlKCd0YXNrSXRlbScsIHsgY2hlY2tlZDogdG9rZW4uY2hlY2tlZCB8fCBmYWxzZSB9LCBjb250ZW50KVxuICB9LFxuXG4gIHJlbmRlck1hcmtkb3duOiAobm9kZSwgaCkgPT4ge1xuICAgIGNvbnN0IGNoZWNrZWRDaGFyID0gbm9kZS5hdHRycz8uY2hlY2tlZCA/ICd4JyA6ICcgJ1xuICAgIGNvbnN0IHByZWZpeCA9IGAtIFske2NoZWNrZWRDaGFyfV0gYFxuXG4gICAgcmV0dXJuIHJlbmRlck5lc3RlZE1hcmtkb3duQ29udGVudChub2RlLCBoLCBwcmVmaXgpXG4gIH0sXG5cbiAgYWRkRXh0ZW5zaW9ucygpIHtcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5uZXN0ZWQpIHtcbiAgICAgIHJldHVybiBbXVxuICAgIH1cblxuICAgIHJldHVybiBbY3JlYXRlQnJhbmNoaW5nTGlzdERlbGV0ZUtleW1hcCh0aGlzLm5hbWUsIFt0aGlzLm9wdGlvbnMudGFza0xpc3RUeXBlTmFtZV0pXVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIGNvbnN0IHNob3J0Y3V0czoge1xuICAgICAgW2tleTogc3RyaW5nXTogS2V5Ym9hcmRTaG9ydGN1dENvbW1hbmRcbiAgICB9ID0ge1xuICAgICAgRW50ZXI6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnNwbGl0TGlzdEl0ZW0odGhpcy5uYW1lKSxcbiAgICAgICdTaGlmdC1UYWInOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5saWZ0TGlzdEl0ZW0odGhpcy5uYW1lKSxcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMub3B0aW9ucy5uZXN0ZWQpIHtcbiAgICAgIHJldHVybiBzaG9ydGN1dHNcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uc2hvcnRjdXRzLFxuICAgICAgVGFiOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5zaW5rTGlzdEl0ZW0odGhpcy5uYW1lKSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkTm9kZVZpZXcoKSB7XG4gICAgcmV0dXJuICh7IG5vZGUsIEhUTUxBdHRyaWJ1dGVzLCBnZXRQb3MsIGVkaXRvciB9KSA9PiB7XG4gICAgICBjb25zdCBsaXN0SXRlbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJylcbiAgICAgIGNvbnN0IGNoZWNrYm94V3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xhYmVsJylcbiAgICAgIGNvbnN0IGNoZWNrYm94U3R5bGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpXG4gICAgICBjb25zdCBjaGVja2JveCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0JylcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuXG4gICAgICBjb25zdCB1cGRhdGVBMTFZID0gKGN1cnJlbnROb2RlOiBQcm9zZU1pcnJvck5vZGUpID0+IHtcbiAgICAgICAgY2hlY2tib3guYXJpYUxhYmVsID1cbiAgICAgICAgICB0aGlzLm9wdGlvbnMuYTExeT8uY2hlY2tib3hMYWJlbD8uKGN1cnJlbnROb2RlLCBjaGVja2JveC5jaGVja2VkKSB8fFxuICAgICAgICAgIGBUYXNrIGl0ZW0gY2hlY2tib3ggZm9yICR7Y3VycmVudE5vZGUudGV4dENvbnRlbnQgfHwgJ2VtcHR5IHRhc2sgaXRlbSd9YFxuICAgICAgfVxuXG4gICAgICB1cGRhdGVBMTFZKG5vZGUpXG5cbiAgICAgIGNoZWNrYm94V3JhcHBlci5jb250ZW50RWRpdGFibGUgPSAnZmFsc2UnXG4gICAgICBjaGVja2JveC50eXBlID0gJ2NoZWNrYm94J1xuICAgICAgY2hlY2tib3guYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgZXZlbnQgPT4gZXZlbnQucHJldmVudERlZmF1bHQoKSlcbiAgICAgIGNoZWNrYm94LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGV2ZW50ID0+IHtcbiAgICAgICAgLy8gaWYgdGhlIGVkaXRvciBpc27igJl0IGVkaXRhYmxlIGFuZCB3ZSBkb24ndCBoYXZlIGEgaGFuZGxlciBmb3JcbiAgICAgICAgLy8gcmVhZG9ubHkgY2hlY2tzIHdlIGhhdmUgdG8gdW5kbyB0aGUgbGF0ZXN0IGNoYW5nZVxuICAgICAgICBpZiAoIWVkaXRvci5pc0VkaXRhYmxlICYmICF0aGlzLm9wdGlvbnMub25SZWFkT25seUNoZWNrZWQpIHtcbiAgICAgICAgICBjaGVja2JveC5jaGVja2VkID0gIWNoZWNrYm94LmNoZWNrZWRcblxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeyBjaGVja2VkIH0gPSBldmVudC50YXJnZXQgYXMgYW55XG5cbiAgICAgICAgaWYgKGVkaXRvci5pc0VkaXRhYmxlICYmIHR5cGVvZiBnZXRQb3MgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICBlZGl0b3JcbiAgICAgICAgICAgIC5jaGFpbigpXG4gICAgICAgICAgICAuZm9jdXModW5kZWZpbmVkLCB7IHNjcm9sbEludG9WaWV3OiBmYWxzZSB9KVxuICAgICAgICAgICAgLmNvbW1hbmQoKHsgdHIgfSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGdldFBvcygpXG5cbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwb3NpdGlvbiAhPT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjb25zdCBjdXJyZW50Tm9kZSA9IHRyLmRvYy5ub2RlQXQocG9zaXRpb24pXG5cbiAgICAgICAgICAgICAgdHIuc2V0Tm9kZU1hcmt1cChwb3NpdGlvbiwgdW5kZWZpbmVkLCB7XG4gICAgICAgICAgICAgICAgLi4uY3VycmVudE5vZGU/LmF0dHJzLFxuICAgICAgICAgICAgICAgIGNoZWNrZWQsXG4gICAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAucnVuKClcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWVkaXRvci5pc0VkaXRhYmxlICYmIHRoaXMub3B0aW9ucy5vblJlYWRPbmx5Q2hlY2tlZCkge1xuICAgICAgICAgIC8vIFJlc2V0IHN0YXRlIGlmIG9uUmVhZE9ubHlDaGVja2VkIHJldHVybnMgZmFsc2VcbiAgICAgICAgICBpZiAoIXRoaXMub3B0aW9ucy5vblJlYWRPbmx5Q2hlY2tlZChub2RlLCBjaGVja2VkKSkge1xuICAgICAgICAgICAgY2hlY2tib3guY2hlY2tlZCA9ICFjaGVja2JveC5jaGVja2VkXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLm9wdGlvbnMuSFRNTEF0dHJpYnV0ZXMpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICBsaXN0SXRlbS5zZXRBdHRyaWJ1dGUoa2V5LCB2YWx1ZSlcbiAgICAgIH0pXG5cbiAgICAgIGxpc3RJdGVtLmRhdGFzZXQuY2hlY2tlZCA9IG5vZGUuYXR0cnMuY2hlY2tlZFxuICAgICAgY2hlY2tib3guY2hlY2tlZCA9IG5vZGUuYXR0cnMuY2hlY2tlZFxuXG4gICAgICBjaGVja2JveFdyYXBwZXIuYXBwZW5kKGNoZWNrYm94LCBjaGVja2JveFN0eWxlcilcbiAgICAgIGxpc3RJdGVtLmFwcGVuZChjaGVja2JveFdyYXBwZXIsIGNvbnRlbnQpXG5cbiAgICAgIE9iamVjdC5lbnRyaWVzKEhUTUxBdHRyaWJ1dGVzKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgbGlzdEl0ZW0uc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmFjayB0aGUga2V5cyBvZiBwcmV2aW91c2x5IHJlbmRlcmVkIEhUTUwgYXR0cmlidXRlcyBmb3IgcHJvcGVyIHJlbW92YWxcbiAgICAgIGxldCBwcmV2UmVuZGVyZWRBdHRyaWJ1dGVLZXlzID0gbmV3IFNldChPYmplY3Qua2V5cyhIVE1MQXR0cmlidXRlcykpXG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGRvbTogbGlzdEl0ZW0sXG4gICAgICAgIGNvbnRlbnRET006IGNvbnRlbnQsXG4gICAgICAgIHVwZGF0ZTogdXBkYXRlZE5vZGUgPT4ge1xuICAgICAgICAgIGlmICh1cGRhdGVkTm9kZS50eXBlICE9PSB0aGlzLnR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGxpc3RJdGVtLmRhdGFzZXQuY2hlY2tlZCA9IHVwZGF0ZWROb2RlLmF0dHJzLmNoZWNrZWRcbiAgICAgICAgICBjaGVja2JveC5jaGVja2VkID0gdXBkYXRlZE5vZGUuYXR0cnMuY2hlY2tlZFxuICAgICAgICAgIHVwZGF0ZUExMVkodXBkYXRlZE5vZGUpXG5cbiAgICAgICAgICAvLyBTeW5jIGFsbCBIVE1MIGF0dHJpYnV0ZXMgZnJvbSB0aGUgdXBkYXRlZCBub2RlXG4gICAgICAgICAgY29uc3QgZXh0ZW5zaW9uQXR0cmlidXRlcyA9IGVkaXRvci5leHRlbnNpb25NYW5hZ2VyLmF0dHJpYnV0ZXNcbiAgICAgICAgICBjb25zdCBuZXdIVE1MQXR0cmlidXRlcyA9IGdldFJlbmRlcmVkQXR0cmlidXRlcyh1cGRhdGVkTm9kZSwgZXh0ZW5zaW9uQXR0cmlidXRlcylcbiAgICAgICAgICBjb25zdCBuZXdLZXlzID0gbmV3IFNldChPYmplY3Qua2V5cyhuZXdIVE1MQXR0cmlidXRlcykpXG5cbiAgICAgICAgICAvLyBSZW1vdmUgYXR0cmlidXRlcyB0aGF0IHdlcmUgcHJldmlvdXNseSByZW5kZXJlZCBidXQgYXJlIG5vIGxvbmdlciBwcmVzZW50XG4gICAgICAgICAgLy8gSWYgdGhlIGF0dHJpYnV0ZSBleGlzdHMgaW4gc3RhdGljIG9wdGlvbnMsIHJlc3RvcmUgaXQgaW5zdGVhZCBvZiByZW1vdmluZ1xuICAgICAgICAgIGNvbnN0IHN0YXRpY0F0dHJzID0gdGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzXG5cbiAgICAgICAgICBwcmV2UmVuZGVyZWRBdHRyaWJ1dGVLZXlzLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGlmICghbmV3S2V5cy5oYXMoa2V5KSkge1xuICAgICAgICAgICAgICBpZiAoa2V5IGluIHN0YXRpY0F0dHJzKSB7XG4gICAgICAgICAgICAgICAgbGlzdEl0ZW0uc2V0QXR0cmlidXRlKGtleSwgc3RhdGljQXR0cnNba2V5XSlcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsaXN0SXRlbS5yZW1vdmVBdHRyaWJ1dGUoa2V5KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcblxuICAgICAgICAgIC8vIFVwZGF0ZSBvciBhZGQgbmV3IGF0dHJpYnV0ZXNcbiAgICAgICAgICBPYmplY3QuZW50cmllcyhuZXdIVE1MQXR0cmlidXRlcykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAvLyBJZiB0aGUgYXR0cmlidXRlIGV4aXN0cyBpbiBzdGF0aWMgb3B0aW9ucywgcmVzdG9yZSBpdCBpbnN0ZWFkIG9mIHJlbW92aW5nXG4gICAgICAgICAgICAgIGlmIChrZXkgaW4gc3RhdGljQXR0cnMpIHtcbiAgICAgICAgICAgICAgICBsaXN0SXRlbS5zZXRBdHRyaWJ1dGUoa2V5LCBzdGF0aWNBdHRyc1trZXldKVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxpc3RJdGVtLnJlbW92ZUF0dHJpYnV0ZShrZXkpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGxpc3RJdGVtLnNldEF0dHJpYnV0ZShrZXksIHZhbHVlKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICAvLyBVcGRhdGUgdGhlIHRyYWNrZWQga2V5cyBmb3IgbmV4dCB1cGRhdGVcbiAgICAgICAgICBwcmV2UmVuZGVyZWRBdHRyaWJ1dGVLZXlzID0gbmV3S2V5c1xuXG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSxcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgYWRkSW5wdXRSdWxlcygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgd3JhcHBpbmdJbnB1dFJ1bGUoe1xuICAgICAgICBmaW5kOiBpbnB1dFJlZ2V4LFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICAgIGdldEF0dHJpYnV0ZXM6IG1hdGNoID0+ICh7XG4gICAgICAgICAgY2hlY2tlZDogbWF0Y2hbbWF0Y2gubGVuZ3RoIC0gMV0gPT09ICd4JyxcbiAgICAgICAgfSksXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IG1lcmdlQXR0cmlidXRlcywgTm9kZSwgcGFyc2VJbmRlbnRlZEJsb2NrcyB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuZXhwb3J0IGludGVyZmFjZSBUYXNrTGlzdE9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIG5vZGUgdHlwZSBuYW1lIGZvciBhIHRhc2sgaXRlbS5cbiAgICogQGRlZmF1bHQgJ3Rhc2tJdGVtJ1xuICAgKiBAZXhhbXBsZSAnbXlDdXN0b21UYXNrSXRlbSdcbiAgICovXG4gIGl0ZW1UeXBlTmFtZTogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSBIVE1MIGF0dHJpYnV0ZXMgZm9yIGEgdGFzayBsaXN0IG5vZGUuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICB0YXNrTGlzdDoge1xuICAgICAgLyoqXG4gICAgICAgKiBUb2dnbGUgYSB0YXNrIGxpc3RcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVUYXNrTGlzdCgpXG4gICAgICAgKi9cbiAgICAgIHRvZ2dsZVRhc2tMaXN0OiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBjcmVhdGUgdGFzayBsaXN0cy5cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvbm9kZXMvdGFzay1saXN0XG4gKi9cbmV4cG9ydCBjb25zdCBUYXNrTGlzdCA9IE5vZGUuY3JlYXRlPFRhc2tMaXN0T3B0aW9ucz4oe1xuICBuYW1lOiAndGFza0xpc3QnLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGl0ZW1UeXBlTmFtZTogJ3Rhc2tJdGVtJyxcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgZ3JvdXA6ICdibG9jayBsaXN0JyxcblxuICBjb250ZW50KCkge1xuICAgIHJldHVybiBgJHt0aGlzLm9wdGlvbnMuaXRlbVR5cGVOYW1lfStgXG4gIH0sXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIHRhZzogYHVsW2RhdGEtdHlwZT1cIiR7dGhpcy5uYW1lfVwiXWAsXG4gICAgICAgIHByaW9yaXR5OiA1MSxcbiAgICAgIH0sXG4gICAgXVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgcmV0dXJuIFtcbiAgICAgICd1bCcsXG4gICAgICBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcywgeyAnZGF0YS10eXBlJzogdGhpcy5uYW1lIH0pLFxuICAgICAgMCxcbiAgICBdXG4gIH0sXG5cbiAgcGFyc2VNYXJrZG93bjogKHRva2VuLCBoKSA9PiB7XG4gICAgcmV0dXJuIGguY3JlYXRlTm9kZSgndGFza0xpc3QnLCB7fSwgaC5wYXJzZUNoaWxkcmVuKHRva2VuLml0ZW1zIHx8IFtdKSlcbiAgfSxcblxuICByZW5kZXJNYXJrZG93bjogKG5vZGUsIGgpID0+IHtcbiAgICBpZiAoIW5vZGUuY29udGVudCkge1xuICAgICAgcmV0dXJuICcnXG4gICAgfVxuXG4gICAgcmV0dXJuIGgucmVuZGVyQ2hpbGRyZW4obm9kZS5jb250ZW50LCAnXFxuJylcbiAgfSxcblxuICBtYXJrZG93blRva2VuaXplcjoge1xuICAgIG5hbWU6ICd0YXNrTGlzdCcsXG4gICAgbGV2ZWw6ICdibG9jaycsXG4gICAgc3RhcnQoc3JjKSB7XG4gICAgICAvLyBMb29rIGZvciB0aGUgc3RhcnQgb2YgYSB0YXNrIGxpc3QgaXRlbVxuICAgICAgY29uc3QgaW5kZXggPSBzcmMubWF0Y2goL15cXHMqWy0rKl1cXHMrXFxbKFsgeFhdKVxcXVxccysvKT8uaW5kZXhcbiAgICAgIHJldHVybiBpbmRleCAhPT0gdW5kZWZpbmVkID8gaW5kZXggOiAtMVxuICAgIH0sXG4gICAgdG9rZW5pemUoc3JjLCB0b2tlbnMsIGxleGVyKSB7XG4gICAgICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gcmVjdXJzaXZlbHkgcGFyc2UgdGFzayBsaXN0c1xuICAgICAgY29uc3QgcGFyc2VUYXNrTGlzdENvbnRlbnQgPSAoY29udGVudDogc3RyaW5nKTogYW55W10gfCB1bmRlZmluZWQgPT4ge1xuICAgICAgICBjb25zdCBuZXN0ZWRSZXN1bHQgPSBwYXJzZUluZGVudGVkQmxvY2tzKFxuICAgICAgICAgIGNvbnRlbnQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgaXRlbVBhdHRlcm46IC9eKFxccyopKFstKypdKVxccytcXFsoWyB4WF0pXFxdXFxzKyguKikkLyxcbiAgICAgICAgICAgIGV4dHJhY3RJdGVtRGF0YTogbWF0Y2ggPT4gKHtcbiAgICAgICAgICAgICAgaW5kZW50TGV2ZWw6IG1hdGNoWzFdLmxlbmd0aCxcbiAgICAgICAgICAgICAgbWFpbkNvbnRlbnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgICBjaGVja2VkOiBtYXRjaFszXS50b0xvd2VyQ2FzZSgpID09PSAneCcsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGNyZWF0ZVRva2VuOiAoZGF0YSwgbmVzdGVkVG9rZW5zKSA9PiAoe1xuICAgICAgICAgICAgICB0eXBlOiAndGFza0l0ZW0nLFxuICAgICAgICAgICAgICByYXc6ICcnLFxuICAgICAgICAgICAgICBtYWluQ29udGVudDogZGF0YS5tYWluQ29udGVudCxcbiAgICAgICAgICAgICAgaW5kZW50TGV2ZWw6IGRhdGEuaW5kZW50TGV2ZWwsXG4gICAgICAgICAgICAgIGNoZWNrZWQ6IGRhdGEuY2hlY2tlZCxcbiAgICAgICAgICAgICAgdGV4dDogZGF0YS5tYWluQ29udGVudCxcbiAgICAgICAgICAgICAgdG9rZW5zOiBsZXhlci5pbmxpbmVUb2tlbnMoZGF0YS5tYWluQ29udGVudCksXG4gICAgICAgICAgICAgIG5lc3RlZFRva2VucyxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgLy8gQWxsb3cgcmVjdXJzaXZlIG5lc3RpbmdcbiAgICAgICAgICAgIGN1c3RvbU5lc3RlZFBhcnNlcjogcGFyc2VUYXNrTGlzdENvbnRlbnQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBsZXhlcixcbiAgICAgICAgKVxuXG4gICAgICAgIGlmIChuZXN0ZWRSZXN1bHQpIHtcbiAgICAgICAgICAvLyBSZXR1cm4gYXMgdGFzayBsaXN0IHRva2VuXG4gICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogJ3Rhc2tMaXN0JyxcbiAgICAgICAgICAgICAgcmF3OiBuZXN0ZWRSZXN1bHQucmF3LFxuICAgICAgICAgICAgICBpdGVtczogbmVzdGVkUmVzdWx0Lml0ZW1zLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdXG4gICAgICAgIH1cblxuICAgICAgICAvLyBGYWxsIGJhY2sgdG8gcmVndWxhciBtYXJrZG93biBwYXJzaW5nIGlmIG5vdCBhIHRhc2sgbGlzdFxuICAgICAgICByZXR1cm4gbGV4ZXIuYmxvY2tUb2tlbnMoY29udGVudClcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzdWx0ID0gcGFyc2VJbmRlbnRlZEJsb2NrcyhcbiAgICAgICAgc3JjLFxuICAgICAgICB7XG4gICAgICAgICAgaXRlbVBhdHRlcm46IC9eKFxccyopKFstKypdKVxccytcXFsoWyB4WF0pXFxdXFxzKyguKikkLyxcbiAgICAgICAgICBleHRyYWN0SXRlbURhdGE6IG1hdGNoID0+ICh7XG4gICAgICAgICAgICBpbmRlbnRMZXZlbDogbWF0Y2hbMV0ubGVuZ3RoLFxuICAgICAgICAgICAgbWFpbkNvbnRlbnQ6IG1hdGNoWzRdLFxuICAgICAgICAgICAgY2hlY2tlZDogbWF0Y2hbM10udG9Mb3dlckNhc2UoKSA9PT0gJ3gnLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGNyZWF0ZVRva2VuOiAoZGF0YSwgbmVzdGVkVG9rZW5zKSA9PiAoe1xuICAgICAgICAgICAgdHlwZTogJ3Rhc2tJdGVtJyxcbiAgICAgICAgICAgIHJhdzogJycsXG4gICAgICAgICAgICBtYWluQ29udGVudDogZGF0YS5tYWluQ29udGVudCxcbiAgICAgICAgICAgIGluZGVudExldmVsOiBkYXRhLmluZGVudExldmVsLFxuICAgICAgICAgICAgY2hlY2tlZDogZGF0YS5jaGVja2VkLFxuICAgICAgICAgICAgdGV4dDogZGF0YS5tYWluQ29udGVudCxcbiAgICAgICAgICAgIHRva2VuczogbGV4ZXIuaW5saW5lVG9rZW5zKGRhdGEubWFpbkNvbnRlbnQpLFxuICAgICAgICAgICAgbmVzdGVkVG9rZW5zLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIC8vIFVzZSB0aGUgcmVjdXJzaXZlIHBhcnNlciBmb3IgbmVzdGVkIGNvbnRlbnRcbiAgICAgICAgICBjdXN0b21OZXN0ZWRQYXJzZXI6IHBhcnNlVGFza0xpc3RDb250ZW50LFxuICAgICAgICB9LFxuICAgICAgICBsZXhlcixcbiAgICAgIClcblxuICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAndGFza0xpc3QnLFxuICAgICAgICByYXc6IHJlc3VsdC5yYXcsXG4gICAgICAgIGl0ZW1zOiByZXN1bHQuaXRlbXMsXG4gICAgICB9XG4gICAgfSxcbiAgfSxcblxuICBtYXJrZG93bk9wdGlvbnM6IHtcbiAgICBpbmRlbnRzQ29udGVudDogdHJ1ZSxcbiAgfSxcblxuICBhZGRDb21tYW5kcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdG9nZ2xlVGFza0xpc3Q6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gY29tbWFuZHMudG9nZ2xlTGlzdCh0aGlzLm5hbWUsIHRoaXMub3B0aW9ucy5pdGVtVHlwZU5hbWUpXG4gICAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnTW9kLVNoaWZ0LTknOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVUYXNrTGlzdCgpLFxuICAgIH1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgbWVyZ2VBdHRyaWJ1dGVzLCBOb2RlIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhcmFncmFwaE9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIEhUTUwgYXR0cmlidXRlcyBmb3IgYSBwYXJhZ3JhcGggbm9kZS5cbiAgICogQGRlZmF1bHQge31cbiAgICogQGV4YW1wbGUgeyBjbGFzczogJ2ZvbycgfVxuICAgKi9cbiAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT5cbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHBhcmFncmFwaDoge1xuICAgICAgLyoqXG4gICAgICAgKiBUb2dnbGUgYSBwYXJhZ3JhcGhcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVQYXJhZ3JhcGgoKVxuICAgICAgICovXG4gICAgICBzZXRQYXJhZ3JhcGg6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNYXJrZG93biBtYXJrZXIgZm9yIGVtcHR5IHBhcmFncmFwaHMgdG8gcHJlc2VydmUgYmxhbmsgbGluZXMuXG4gKiBVc2luZyAmbmJzcDsgKG5vbi1icmVha2luZyBzcGFjZSBIVE1MIGVudGl0eSkgZW5zdXJlcyB0aGUgcGFyYWdyYXBoXG4gKiBpcyBub3QgY29sbGFwc2VkIGJ5IG1hcmtkb3duIHBhcnNlcnMgd2hpbGUgcmVtYWluaW5nIGh1bWFuLXJlYWRhYmxlLlxuICovXG5jb25zdCBFTVBUWV9QQVJBR1JBUEhfTUFSS0RPV04gPSAnJm5ic3A7J1xuXG4vKipcbiAqIFVuaWNvZGUgY2hhcmFjdGVyIGZvciBub24tYnJlYWtpbmcgc3BhY2UgKFUrMDBBMCkuXG4gKiBTb21lIG1hcmtkb3duIHBhcnNlcnMgbWF5IGNvbnZlcnQgJm5ic3A7IGVudGl0aWVzIHRvIHRoaXMgbGl0ZXJhbCBjaGFyYWN0ZXIuXG4gKi9cbmNvbnN0IE5CU1BfQ0hBUiA9ICdcXHUwMEEwJ1xuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gY3JlYXRlIHBhcmFncmFwaHMuXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnRpcHRhcC5kZXYvYXBpL25vZGVzL3BhcmFncmFwaFxuICovXG5leHBvcnQgY29uc3QgUGFyYWdyYXBoID0gTm9kZS5jcmVhdGU8UGFyYWdyYXBoT3B0aW9ucz4oe1xuICBuYW1lOiAncGFyYWdyYXBoJyxcblxuICBwcmlvcml0eTogMTAwMCxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBIVE1MQXR0cmlidXRlczoge30sXG4gICAgfVxuICB9LFxuXG4gIGdyb3VwOiAnYmxvY2snLFxuXG4gIGNvbnRlbnQ6ICdpbmxpbmUqJyxcblxuICBwYXJzZUhUTUwoKSB7XG4gICAgcmV0dXJuIFt7IHRhZzogJ3AnIH1dXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICByZXR1cm4gWydwJywgbWVyZ2VBdHRyaWJ1dGVzKHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcywgSFRNTEF0dHJpYnV0ZXMpLCAwXVxuICB9LFxuXG4gIHBhcnNlTWFya2Rvd246ICh0b2tlbiwgaGVscGVycykgPT4ge1xuICAgIGNvbnN0IHRva2VucyA9IHRva2VuLnRva2VucyB8fCBbXVxuXG4gICAgLy8gU3BlY2lhbCBjYXNlOiBpZiBwYXJhZ3JhcGggY29udGFpbnMgb25seSBhIHNpbmdsZSBpbWFnZSB0b2tlbixcbiAgICAvLyB1bndyYXAgaXQgdG8gYXZvaWQgbmVzdGluZyBibG9jayBlbGVtZW50cyBpbmNvcnJlY3RseVxuICAgIGlmICh0b2tlbnMubGVuZ3RoID09PSAxICYmIHRva2Vuc1swXS50eXBlID09PSAnaW1hZ2UnKSB7XG4gICAgICAvLyBQYXJzZSB0aGUgaW1hZ2UgdG9rZW4gZGlyZWN0bHkgYXMgYSBibG9jayBlbGVtZW50XG4gICAgICByZXR1cm4gaGVscGVycy5wYXJzZUNoaWxkcmVuKFt0b2tlbnNbMF1dKVxuICAgIH1cblxuICAgIC8vIFBhcnNlIHRoZSBpbmxpbmUgdG9rZW5zXG4gICAgY29uc3QgY29udGVudCA9IGhlbHBlcnMucGFyc2VJbmxpbmUodG9rZW5zKVxuXG4gICAgLy8gU3BlY2lhbCBjYXNlOiBpZiBwYXJhZ3JhcGggY29udGFpbnMgb25seSAmbmJzcDsgKG5vbi1icmVha2luZyBzcGFjZSksXG4gICAgLy8gdHJlYXQgaXQgYXMgYW4gZW1wdHkgcGFyYWdyYXBoIHRvIHByZXNlcnZlIGJsYW5rIGxpbmVzXG4gICAgY29uc3QgaGFzRXhwbGljaXRFbXB0eVBhcmFncmFwaE1hcmtlciA9XG4gICAgICB0b2tlbnMubGVuZ3RoID09PSAxICYmXG4gICAgICB0b2tlbnNbMF0udHlwZSA9PT0gJ3RleHQnICYmXG4gICAgICAodG9rZW5zWzBdLnJhdyA9PT0gRU1QVFlfUEFSQUdSQVBIX01BUktET1dOIHx8XG4gICAgICAgIHRva2Vuc1swXS50ZXh0ID09PSBFTVBUWV9QQVJBR1JBUEhfTUFSS0RPV04gfHxcbiAgICAgICAgdG9rZW5zWzBdLnJhdyA9PT0gTkJTUF9DSEFSIHx8XG4gICAgICAgIHRva2Vuc1swXS50ZXh0ID09PSBOQlNQX0NIQVIpXG5cbiAgICBpZiAoXG4gICAgICBoYXNFeHBsaWNpdEVtcHR5UGFyYWdyYXBoTWFya2VyICYmXG4gICAgICBjb250ZW50Lmxlbmd0aCA9PT0gMSAmJlxuICAgICAgY29udGVudFswXS50eXBlID09PSAndGV4dCcgJiZcbiAgICAgIChjb250ZW50WzBdLnRleHQgPT09IEVNUFRZX1BBUkFHUkFQSF9NQVJLRE9XTiB8fCBjb250ZW50WzBdLnRleHQgPT09IE5CU1BfQ0hBUilcbiAgICApIHtcbiAgICAgIHJldHVybiBoZWxwZXJzLmNyZWF0ZU5vZGUoJ3BhcmFncmFwaCcsIHVuZGVmaW5lZCwgW10pXG4gICAgfVxuXG4gICAgLy8gQ29udmVydCAncGFyYWdyYXBoJyB0b2tlbiB0byBwYXJhZ3JhcGggbm9kZVxuICAgIHJldHVybiBoZWxwZXJzLmNyZWF0ZU5vZGUoJ3BhcmFncmFwaCcsIHVuZGVmaW5lZCwgY29udGVudClcbiAgfSxcblxuICByZW5kZXJNYXJrZG93bjogKG5vZGUsIGgsIGN0eCkgPT4ge1xuICAgIGlmICghbm9kZSkge1xuICAgICAgcmV0dXJuICcnXG4gICAgfVxuXG4gICAgLy8gTm9ybWFsaXplIGNvbnRlbnQ6IHRyZWF0IHVuZGVmaW5lZC9udWxsIGFzIGVtcHR5IGFycmF5XG4gICAgY29uc3QgY29udGVudCA9IEFycmF5LmlzQXJyYXkobm9kZS5jb250ZW50KSA/IG5vZGUuY29udGVudCA6IFtdXG5cbiAgICBpZiAoY29udGVudC5sZW5ndGggPT09IDApIHtcbiAgICAgIC8vIEVtaXQgJm5ic3A7IGZvciB0aGUgc2Vjb25kIGFuZCBsYXRlciBlbXB0eSBwYXJhZ3JhcGhzIGluIGEgY29uc2VjdXRpdmVcbiAgICAgIC8vIHJ1biBhdCB0aGUgY3VycmVudCBuZXN0aW5nIGxldmVsLiBUaGUgZmlyc3QgZW1wdHkgcGFyYWdyYXBoIHN0YXlzIGVtcHR5XG4gICAgICAvLyBzbyBtYXJrZG93biBzcGFjaW5nIGlzIHByZXNlcnZlZCBuYXR1cmFsbHkuXG4gICAgICBjb25zdCBwcmV2aW91c0NvbnRlbnQgPSBBcnJheS5pc0FycmF5KGN0eD8ucHJldmlvdXNOb2RlPy5jb250ZW50KVxuICAgICAgICA/IGN0eC5wcmV2aW91c05vZGUuY29udGVudFxuICAgICAgICA6IFtdXG4gICAgICBjb25zdCBwcmV2aW91c05vZGVJc0VtcHR5UGFyYWdyYXBoID1cbiAgICAgICAgY3R4Py5wcmV2aW91c05vZGU/LnR5cGUgPT09ICdwYXJhZ3JhcGgnICYmIHByZXZpb3VzQ29udGVudC5sZW5ndGggPT09IDBcblxuICAgICAgcmV0dXJuIHByZXZpb3VzTm9kZUlzRW1wdHlQYXJhZ3JhcGggPyBFTVBUWV9QQVJBR1JBUEhfTUFSS0RPV04gOiAnJ1xuICAgIH1cblxuICAgIHJldHVybiBoLnJlbmRlckNoaWxkcmVuKGNvbnRlbnQpXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldFBhcmFncmFwaDpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy5zZXROb2RlKHRoaXMubmFtZSlcbiAgICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkS2V5Ym9hcmRTaG9ydGN1dHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdNb2QtQWx0LTAnOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5zZXRQYXJhZ3JhcGgoKSxcbiAgICB9XG4gIH0sXG59KVxuIiwgImltcG9ydCB7IFBhcmFncmFwaCB9IGZyb20gJy4vcGFyYWdyYXBoLmpzJ1xuXG5leHBvcnQgKiBmcm9tICcuL3BhcmFncmFwaC5qcydcblxuZXhwb3J0IGRlZmF1bHQgUGFyYWdyYXBoXG4iLCAiaW1wb3J0IHsgTWFyaywgbWFya0lucHV0UnVsZSwgbWFya1Bhc3RlUnVsZSwgbWVyZ2VBdHRyaWJ1dGVzIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0cmlrZU9wdGlvbnMge1xuICAvKipcbiAgICogSFRNTCBhdHRyaWJ1dGVzIHRvIGFkZCB0byB0aGUgc3RyaWtlIGVsZW1lbnQuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzdHJpa2U6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2V0IGEgc3RyaWtlIG1hcmtcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5zZXRTdHJpa2UoKVxuICAgICAgICovXG4gICAgICBzZXRTdHJpa2U6ICgpID0+IFJldHVyblR5cGVcbiAgICAgIC8qKlxuICAgICAgICogVG9nZ2xlIGEgc3RyaWtlIG1hcmtcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVTdHJpa2UoKVxuICAgICAgICovXG4gICAgICB0b2dnbGVTdHJpa2U6ICgpID0+IFJldHVyblR5cGVcbiAgICAgIC8qKlxuICAgICAgICogVW5zZXQgYSBzdHJpa2UgbWFya1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnVuc2V0U3RyaWtlKClcbiAgICAgICAqL1xuICAgICAgdW5zZXRTdHJpa2U6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNYXRjaGVzIGEgc3RyaWtlIHRvIGEgfn5zdHJpa2V+fiBvbiBpbnB1dC5cbiAqL1xuZXhwb3J0IGNvbnN0IGlucHV0UmVnZXggPSAvKD86XnxcXHMpKH5+KD8hXFxzK35+KSgoPzpbXn5dKykpfn4oPyFcXHMrfn4pKSQvXG5cbi8qKlxuICogTWF0Y2hlcyBhIHN0cmlrZSB0byBhIH5+c3RyaWtlfn4gb24gcGFzdGUuXG4gKi9cbmV4cG9ydCBjb25zdCBwYXN0ZVJlZ2V4ID0gLyg/Ol58XFxzKSh+fig/IVxccyt+fikoKD86W15+XSspKX5+KD8hXFxzK35+KSkvZ1xuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gY3JlYXRlIHN0cmlrZSB0ZXh0LlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9tYXJrcy9zdHJpa2VcbiAqL1xuZXhwb3J0IGNvbnN0IFN0cmlrZSA9IE1hcmsuY3JlYXRlPFN0cmlrZU9wdGlvbnM+KHtcbiAgbmFtZTogJ3N0cmlrZScsXG5cbiAgYWRkT3B0aW9ucygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgSFRNTEF0dHJpYnV0ZXM6IHt9LFxuICAgIH1cbiAgfSxcblxuICBwYXJzZUhUTUwoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgdGFnOiAncycsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0YWc6ICdkZWwnLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgdGFnOiAnc3RyaWtlJyxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHN0eWxlOiAndGV4dC1kZWNvcmF0aW9uJyxcbiAgICAgICAgY29uc3VtaW5nOiBmYWxzZSxcbiAgICAgICAgZ2V0QXR0cnM6IHN0eWxlID0+ICgoc3R5bGUgYXMgc3RyaW5nKS5pbmNsdWRlcygnbGluZS10aHJvdWdoJykgPyB7fSA6IGZhbHNlKSxcbiAgICAgIH0sXG4gICAgXVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgcmV0dXJuIFsncycsIG1lcmdlQXR0cmlidXRlcyh0aGlzLm9wdGlvbnMuSFRNTEF0dHJpYnV0ZXMsIEhUTUxBdHRyaWJ1dGVzKSwgMF1cbiAgfSxcblxuICBtYXJrZG93blRva2VuTmFtZTogJ2RlbCcsXG5cbiAgcGFyc2VNYXJrZG93bjogKHRva2VuLCBoZWxwZXJzKSA9PiB7XG4gICAgLy8gQ29udmVydCAnZGVsJyB0b2tlbiB0byBzdHJpa2UgbWFya1xuICAgIHJldHVybiBoZWxwZXJzLmFwcGx5TWFyaygnc3RyaWtlJywgaGVscGVycy5wYXJzZUlubGluZSh0b2tlbi50b2tlbnMgfHwgW10pKVxuICB9LFxuXG4gIHJlbmRlck1hcmtkb3duOiAobm9kZSwgaCkgPT4ge1xuICAgIHJldHVybiBgfn4ke2gucmVuZGVyQ2hpbGRyZW4obm9kZSl9fn5gXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldFN0cmlrZTpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy5zZXRNYXJrKHRoaXMubmFtZSlcbiAgICAgICAgfSxcbiAgICAgIHRvZ2dsZVN0cmlrZTpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy50b2dnbGVNYXJrKHRoaXMubmFtZSlcbiAgICAgICAgfSxcbiAgICAgIHVuc2V0U3RyaWtlOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnVuc2V0TWFyayh0aGlzLm5hbWUpXG4gICAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnTW9kLVNoaWZ0LXMnOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVTdHJpa2UoKSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkSW5wdXRSdWxlcygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbWFya0lucHV0UnVsZSh7XG4gICAgICAgIGZpbmQ6IGlucHV0UmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcblxuICBhZGRQYXN0ZVJ1bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICBtYXJrUGFzdGVSdWxlKHtcbiAgICAgICAgZmluZDogcGFzdGVSZWdleCxcbiAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgfSksXG4gICAgXVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBTdHJpa2UgfSBmcm9tICcuL3N0cmlrZS5qcydcblxuZXhwb3J0ICogZnJvbSAnLi9zdHJpa2UuanMnXG5cbmV4cG9ydCBkZWZhdWx0IFN0cmlrZVxuIiwgImltcG9ydCB7IE5vZGUgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBjcmVhdGUgdGV4dCBub2Rlcy5cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvbm9kZXMvdGV4dFxuICovXG5leHBvcnQgY29uc3QgVGV4dCA9IE5vZGUuY3JlYXRlKHtcbiAgbmFtZTogJ3RleHQnLFxuICBncm91cDogJ2lubGluZScsXG5cbiAgcGFyc2VNYXJrZG93bjogdG9rZW4gPT4ge1xuICAgIC8vIENvbnZlcnQgJ3RleHQnIHRva2VuIHRvIHRleHQgbm9kZSAtIHRleHQgbm9kZXMgYXJlIHNwZWNpYWwgYXMgdGhleSBzdG9yZSB0ZXh0IGRpcmVjdGx5XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgIHRleHQ6IHRva2VuLnRleHQgfHwgJycsXG4gICAgfVxuICB9LFxuXG4gIHJlbmRlck1hcmtkb3duOiBub2RlID0+IG5vZGUudGV4dCB8fCAnJyxcbn0pXG4iLCAiaW1wb3J0IHsgVGV4dCB9IGZyb20gJy4vdGV4dC5qcydcblxuZXhwb3J0ICogZnJvbSAnLi90ZXh0LmpzJ1xuXG5leHBvcnQgZGVmYXVsdCBUZXh0XG4iLCAiaW1wb3J0IHsgTWFyaywgbWVyZ2VBdHRyaWJ1dGVzIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFVuZGVybGluZU9wdGlvbnMge1xuICAvKipcbiAgICogSFRNTCBhdHRyaWJ1dGVzIHRvIGFkZCB0byB0aGUgdW5kZXJsaW5lIGVsZW1lbnQuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICB1bmRlcmxpbmU6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2V0IGFuIHVuZGVybGluZSBtYXJrXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2V0VW5kZXJsaW5lKClcbiAgICAgICAqL1xuICAgICAgc2V0VW5kZXJsaW5lOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgICAvKipcbiAgICAgICAqIFRvZ2dsZSBhbiB1bmRlcmxpbmUgbWFya1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZVVuZGVybGluZSgpXG4gICAgICAgKi9cbiAgICAgIHRvZ2dsZVVuZGVybGluZTogKCkgPT4gUmV0dXJuVHlwZVxuICAgICAgLyoqXG4gICAgICAgKiBVbnNldCBhbiB1bmRlcmxpbmUgbWFya1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnVuc2V0VW5kZXJsaW5lKClcbiAgICAgICAqL1xuICAgICAgdW5zZXRVbmRlcmxpbmU6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBUaGlzIGV4dGVuc2lvbiBhbGxvd3MgeW91IHRvIGNyZWF0ZSB1bmRlcmxpbmUgdGV4dC5cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvbWFya3MvdW5kZXJsaW5lXG4gKi9cbmV4cG9ydCBjb25zdCBVbmRlcmxpbmUgPSBNYXJrLmNyZWF0ZTxVbmRlcmxpbmVPcHRpb25zPih7XG4gIG5hbWU6ICd1bmRlcmxpbmUnLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIHRhZzogJ3UnLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3R5bGU6ICd0ZXh0LWRlY29yYXRpb24nLFxuICAgICAgICBjb25zdW1pbmc6IGZhbHNlLFxuICAgICAgICBnZXRBdHRyczogc3R5bGUgPT4gKChzdHlsZSBhcyBzdHJpbmcpLmluY2x1ZGVzKCd1bmRlcmxpbmUnKSA/IHt9IDogZmFsc2UpLFxuICAgICAgfSxcbiAgICBdXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICByZXR1cm4gWyd1JywgbWVyZ2VBdHRyaWJ1dGVzKHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcywgSFRNTEF0dHJpYnV0ZXMpLCAwXVxuICB9LFxuXG4gIHBhcnNlTWFya2Rvd24odG9rZW4sIGhlbHBlcnMpIHtcbiAgICByZXR1cm4gaGVscGVycy5hcHBseU1hcmsodGhpcy5uYW1lIHx8ICd1bmRlcmxpbmUnLCBoZWxwZXJzLnBhcnNlSW5saW5lKHRva2VuLnRva2VucyB8fCBbXSkpXG4gIH0sXG5cbiAgcmVuZGVyTWFya2Rvd24obm9kZSwgaGVscGVycykge1xuICAgIHJldHVybiBgKyske2hlbHBlcnMucmVuZGVyQ2hpbGRyZW4obm9kZSl9KytgXG4gIH0sXG5cbiAgbWFya2Rvd25Ub2tlbml6ZXI6IHtcbiAgICBuYW1lOiAndW5kZXJsaW5lJyxcbiAgICBsZXZlbDogJ2lubGluZScsXG4gICAgc3RhcnQoc3JjKSB7XG4gICAgICByZXR1cm4gc3JjLmluZGV4T2YoJysrJylcbiAgICB9LFxuICAgIHRva2VuaXplKHNyYywgX3Rva2VucywgbGV4ZXIpIHtcbiAgICAgIGNvbnN0IHJ1bGUgPSAvXihcXCtcXCspKFtcXHNcXFNdKz8pKFxcK1xcKykvXG4gICAgICBjb25zdCBtYXRjaCA9IHJ1bGUuZXhlYyhzcmMpXG5cbiAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgfVxuXG4gICAgICBjb25zdCBpbm5lckNvbnRlbnQgPSBtYXRjaFsyXS50cmltKClcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3VuZGVybGluZScsXG4gICAgICAgIHJhdzogbWF0Y2hbMF0sXG4gICAgICAgIHRleHQ6IGlubmVyQ29udGVudCxcbiAgICAgICAgdG9rZW5zOiBsZXhlci5pbmxpbmVUb2tlbnMoaW5uZXJDb250ZW50KSxcbiAgICAgIH1cbiAgICB9LFxuICB9LFxuXG4gIGFkZENvbW1hbmRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzZXRVbmRlcmxpbmU6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gY29tbWFuZHMuc2V0TWFyayh0aGlzLm5hbWUpXG4gICAgICAgIH0sXG4gICAgICB0b2dnbGVVbmRlcmxpbmU6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gY29tbWFuZHMudG9nZ2xlTWFyayh0aGlzLm5hbWUpXG4gICAgICAgIH0sXG4gICAgICB1bnNldFVuZGVybGluZTpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBjb21tYW5kcy51bnNldE1hcmsodGhpcy5uYW1lKVxuICAgICAgICB9LFxuICAgIH1cbiAgfSxcblxuICBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgJ01vZC11JzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMudG9nZ2xlVW5kZXJsaW5lKCksXG4gICAgICAnTW9kLVUnOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVVbmRlcmxpbmUoKSxcbiAgICB9XG4gIH0sXG59KVxuIiwgImltcG9ydCB7IFVuZGVybGluZSB9IGZyb20gJy4vdW5kZXJsaW5lLmpzJ1xuXG5leHBvcnQgKiBmcm9tICcuL3VuZGVybGluZS5qcydcblxuZXhwb3J0IGRlZmF1bHQgVW5kZXJsaW5lXG4iLCAiaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuaW1wb3J0IHsgZHJvcFBvaW50IH0gZnJvbSAncHJvc2VtaXJyb3ItdHJhbnNmb3JtJztcblxuLyoqXG5DcmVhdGUgYSBwbHVnaW4gdGhhdCwgd2hlbiBhZGRlZCB0byBhIFByb3NlTWlycm9yIGluc3RhbmNlLFxuY2F1c2VzIGEgZGVjb3JhdGlvbiB0byBzaG93IHVwIGF0IHRoZSBkcm9wIHBvc2l0aW9uIHdoZW4gc29tZXRoaW5nXG5pcyBkcmFnZ2VkIG92ZXIgdGhlIGVkaXRvci5cblxuTm9kZXMgbWF5IGFkZCBhIGBkaXNhYmxlRHJvcEN1cnNvcmAgcHJvcGVydHkgdG8gdGhlaXIgc3BlYyB0b1xuY29udHJvbCB0aGUgc2hvd2luZyBvZiBhIGRyb3AgY3Vyc29yIGluc2lkZSB0aGVtLiBUaGlzIG1heSBiZSBhXG5ib29sZWFuIG9yIGEgZnVuY3Rpb24sIHdoaWNoIHdpbGwgYmUgY2FsbGVkIHdpdGggYSB2aWV3IGFuZCBhXG5wb3NpdGlvbiwgYW5kIHNob3VsZCByZXR1cm4gYSBib29sZWFuLlxuKi9cbmZ1bmN0aW9uIGRyb3BDdXJzb3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgcmV0dXJuIG5ldyBQbHVnaW4oe1xuICAgICAgICB2aWV3KGVkaXRvclZpZXcpIHsgcmV0dXJuIG5ldyBEcm9wQ3Vyc29yVmlldyhlZGl0b3JWaWV3LCBvcHRpb25zKTsgfVxuICAgIH0pO1xufVxuY2xhc3MgRHJvcEN1cnNvclZpZXcge1xuICAgIGNvbnN0cnVjdG9yKGVkaXRvclZpZXcsIG9wdGlvbnMpIHtcbiAgICAgICAgdmFyIF9hO1xuICAgICAgICB0aGlzLmVkaXRvclZpZXcgPSBlZGl0b3JWaWV3O1xuICAgICAgICB0aGlzLmN1cnNvclBvcyA9IG51bGw7XG4gICAgICAgIHRoaXMuZWxlbWVudCA9IG51bGw7XG4gICAgICAgIHRoaXMudGltZW91dCA9IC0xO1xuICAgICAgICB0aGlzLndpZHRoID0gKF9hID0gb3B0aW9ucy53aWR0aCkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogMTtcbiAgICAgICAgdGhpcy5jb2xvciA9IG9wdGlvbnMuY29sb3IgPT09IGZhbHNlID8gdW5kZWZpbmVkIDogKG9wdGlvbnMuY29sb3IgfHwgXCJibGFja1wiKTtcbiAgICAgICAgdGhpcy5jbGFzcyA9IG9wdGlvbnMuY2xhc3M7XG4gICAgICAgIHRoaXMuaGFuZGxlcnMgPSBbXCJkcmFnb3ZlclwiLCBcImRyYWdlbmRcIiwgXCJkcm9wXCIsIFwiZHJhZ2xlYXZlXCJdLm1hcChuYW1lID0+IHtcbiAgICAgICAgICAgIGxldCBoYW5kbGVyID0gKGUpID0+IHsgdGhpc1tuYW1lXShlKTsgfTtcbiAgICAgICAgICAgIGVkaXRvclZpZXcuZG9tLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgaGFuZGxlcik7XG4gICAgICAgICAgICByZXR1cm4geyBuYW1lLCBoYW5kbGVyIH07XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLmhhbmRsZXJzLmZvckVhY2goKHsgbmFtZSwgaGFuZGxlciB9KSA9PiB0aGlzLmVkaXRvclZpZXcuZG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgaGFuZGxlcikpO1xuICAgIH1cbiAgICB1cGRhdGUoZWRpdG9yVmlldywgcHJldlN0YXRlKSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnNvclBvcyAhPSBudWxsICYmIHByZXZTdGF0ZS5kb2MgIT0gZWRpdG9yVmlldy5zdGF0ZS5kb2MpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmN1cnNvclBvcyA+IGVkaXRvclZpZXcuc3RhdGUuZG9jLmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgICAgICAgICB0aGlzLnNldEN1cnNvcihudWxsKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZU92ZXJsYXkoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXRDdXJzb3IocG9zKSB7XG4gICAgICAgIGlmIChwb3MgPT0gdGhpcy5jdXJzb3JQb3MpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHRoaXMuY3Vyc29yUG9zID0gcG9zO1xuICAgICAgICBpZiAocG9zID09IG51bGwpIHtcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuZWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVPdmVybGF5KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdXBkYXRlT3ZlcmxheSgpIHtcbiAgICAgICAgbGV0ICRwb3MgPSB0aGlzLmVkaXRvclZpZXcuc3RhdGUuZG9jLnJlc29sdmUodGhpcy5jdXJzb3JQb3MpO1xuICAgICAgICBsZXQgaXNCbG9jayA9ICEkcG9zLnBhcmVudC5pbmxpbmVDb250ZW50LCByZWN0O1xuICAgICAgICBsZXQgZWRpdG9yRE9NID0gdGhpcy5lZGl0b3JWaWV3LmRvbSwgZWRpdG9yUmVjdCA9IGVkaXRvckRPTS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgbGV0IHNjYWxlWCA9IGVkaXRvclJlY3Qud2lkdGggLyBlZGl0b3JET00ub2Zmc2V0V2lkdGgsIHNjYWxlWSA9IGVkaXRvclJlY3QuaGVpZ2h0IC8gZWRpdG9yRE9NLm9mZnNldEhlaWdodDtcbiAgICAgICAgaWYgKGlzQmxvY2spIHtcbiAgICAgICAgICAgIGxldCBiZWZvcmUgPSAkcG9zLm5vZGVCZWZvcmUsIGFmdGVyID0gJHBvcy5ub2RlQWZ0ZXI7XG4gICAgICAgICAgICBpZiAoYmVmb3JlIHx8IGFmdGVyKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5vZGUgPSB0aGlzLmVkaXRvclZpZXcubm9kZURPTSh0aGlzLmN1cnNvclBvcyAtIChiZWZvcmUgPyBiZWZvcmUubm9kZVNpemUgOiAwKSk7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG5vZGVSZWN0ID0gbm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRvcCA9IGJlZm9yZSA/IG5vZGVSZWN0LmJvdHRvbSA6IG5vZGVSZWN0LnRvcDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGJlZm9yZSAmJiBhZnRlcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcCA9ICh0b3AgKyB0aGlzLmVkaXRvclZpZXcubm9kZURPTSh0aGlzLmN1cnNvclBvcykuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wKSAvIDI7XG4gICAgICAgICAgICAgICAgICAgIGxldCBoYWxmV2lkdGggPSAodGhpcy53aWR0aCAvIDIpICogc2NhbGVZO1xuICAgICAgICAgICAgICAgICAgICByZWN0ID0geyBsZWZ0OiBub2RlUmVjdC5sZWZ0LCByaWdodDogbm9kZVJlY3QucmlnaHQsIHRvcDogdG9wIC0gaGFsZldpZHRoLCBib3R0b206IHRvcCArIGhhbGZXaWR0aCB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIXJlY3QpIHtcbiAgICAgICAgICAgIGxldCBjb29yZHMgPSB0aGlzLmVkaXRvclZpZXcuY29vcmRzQXRQb3ModGhpcy5jdXJzb3JQb3MpO1xuICAgICAgICAgICAgbGV0IGhhbGZXaWR0aCA9ICh0aGlzLndpZHRoIC8gMikgKiBzY2FsZVg7XG4gICAgICAgICAgICByZWN0ID0geyBsZWZ0OiBjb29yZHMubGVmdCAtIGhhbGZXaWR0aCwgcmlnaHQ6IGNvb3Jkcy5sZWZ0ICsgaGFsZldpZHRoLCB0b3A6IGNvb3Jkcy50b3AsIGJvdHRvbTogY29vcmRzLmJvdHRvbSB9O1xuICAgICAgICB9XG4gICAgICAgIGxldCBwYXJlbnQgPSB0aGlzLmVkaXRvclZpZXcuZG9tLm9mZnNldFBhcmVudDtcbiAgICAgICAgaWYgKCF0aGlzLmVsZW1lbnQpIHtcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IHBhcmVudC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmNsYXNzKVxuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudC5jbGFzc05hbWUgPSB0aGlzLmNsYXNzO1xuICAgICAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmNzc1RleHQgPSBcInBvc2l0aW9uOiBhYnNvbHV0ZTsgei1pbmRleDogNTA7IHBvaW50ZXItZXZlbnRzOiBub25lO1wiO1xuICAgICAgICAgICAgaWYgKHRoaXMuY29sb3IpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZENvbG9yID0gdGhpcy5jb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZShcInByb3NlbWlycm9yLWRyb3BjdXJzb3ItYmxvY2tcIiwgaXNCbG9jayk7XG4gICAgICAgIHRoaXMuZWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKFwicHJvc2VtaXJyb3ItZHJvcGN1cnNvci1pbmxpbmVcIiwgIWlzQmxvY2spO1xuICAgICAgICBsZXQgcGFyZW50TGVmdCwgcGFyZW50VG9wO1xuICAgICAgICBpZiAoIXBhcmVudCB8fCBwYXJlbnQgPT0gZG9jdW1lbnQuYm9keSAmJiBnZXRDb21wdXRlZFN0eWxlKHBhcmVudCkucG9zaXRpb24gPT0gXCJzdGF0aWNcIikge1xuICAgICAgICAgICAgcGFyZW50TGVmdCA9IC1wYWdlWE9mZnNldDtcbiAgICAgICAgICAgIHBhcmVudFRvcCA9IC1wYWdlWU9mZnNldDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCByZWN0ID0gcGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgbGV0IHBhcmVudFNjYWxlWCA9IHJlY3Qud2lkdGggLyBwYXJlbnQub2Zmc2V0V2lkdGgsIHBhcmVudFNjYWxlWSA9IHJlY3QuaGVpZ2h0IC8gcGFyZW50Lm9mZnNldEhlaWdodDtcbiAgICAgICAgICAgIHBhcmVudExlZnQgPSByZWN0LmxlZnQgLSBwYXJlbnQuc2Nyb2xsTGVmdCAqIHBhcmVudFNjYWxlWDtcbiAgICAgICAgICAgIHBhcmVudFRvcCA9IHJlY3QudG9wIC0gcGFyZW50LnNjcm9sbFRvcCAqIHBhcmVudFNjYWxlWTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVsZW1lbnQuc3R5bGUubGVmdCA9IChyZWN0LmxlZnQgLSBwYXJlbnRMZWZ0KSAvIHNjYWxlWCArIFwicHhcIjtcbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLnRvcCA9IChyZWN0LnRvcCAtIHBhcmVudFRvcCkgLyBzY2FsZVkgKyBcInB4XCI7XG4gICAgICAgIHRoaXMuZWxlbWVudC5zdHlsZS53aWR0aCA9IChyZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0KSAvIHNjYWxlWCArIFwicHhcIjtcbiAgICAgICAgdGhpcy5lbGVtZW50LnN0eWxlLmhlaWdodCA9IChyZWN0LmJvdHRvbSAtIHJlY3QudG9wKSAvIHNjYWxlWSArIFwicHhcIjtcbiAgICB9XG4gICAgc2NoZWR1bGVSZW1vdmFsKHRpbWVvdXQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dCk7XG4gICAgICAgIHRoaXMudGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZXRDdXJzb3IobnVsbCksIHRpbWVvdXQpO1xuICAgIH1cbiAgICBkcmFnb3ZlcihldmVudCkge1xuICAgICAgICBpZiAoIXRoaXMuZWRpdG9yVmlldy5lZGl0YWJsZSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgbGV0IHBvcyA9IHRoaXMuZWRpdG9yVmlldy5wb3NBdENvb3Jkcyh7IGxlZnQ6IGV2ZW50LmNsaWVudFgsIHRvcDogZXZlbnQuY2xpZW50WSB9KTtcbiAgICAgICAgbGV0IG5vZGUgPSBwb3MgJiYgcG9zLmluc2lkZSA+PSAwICYmIHRoaXMuZWRpdG9yVmlldy5zdGF0ZS5kb2Mubm9kZUF0KHBvcy5pbnNpZGUpO1xuICAgICAgICBsZXQgZGlzYWJsZURyb3BDdXJzb3IgPSBub2RlICYmIG5vZGUudHlwZS5zcGVjLmRpc2FibGVEcm9wQ3Vyc29yO1xuICAgICAgICBsZXQgZGlzYWJsZWQgPSB0eXBlb2YgZGlzYWJsZURyb3BDdXJzb3IgPT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICA/IGRpc2FibGVEcm9wQ3Vyc29yKHRoaXMuZWRpdG9yVmlldywgcG9zLCBldmVudClcbiAgICAgICAgICAgIDogZGlzYWJsZURyb3BDdXJzb3I7XG4gICAgICAgIGlmIChwb3MgJiYgIWRpc2FibGVkKSB7XG4gICAgICAgICAgICBsZXQgdGFyZ2V0ID0gcG9zLnBvcztcbiAgICAgICAgICAgIGlmICh0aGlzLmVkaXRvclZpZXcuZHJhZ2dpbmcgJiYgdGhpcy5lZGl0b3JWaWV3LmRyYWdnaW5nLnNsaWNlKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBvaW50ID0gZHJvcFBvaW50KHRoaXMuZWRpdG9yVmlldy5zdGF0ZS5kb2MsIHRhcmdldCwgdGhpcy5lZGl0b3JWaWV3LmRyYWdnaW5nLnNsaWNlKTtcbiAgICAgICAgICAgICAgICBpZiAocG9pbnQgIT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gcG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldEN1cnNvcih0YXJnZXQpO1xuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZVJlbW92YWwoNTAwMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZHJhZ2VuZCgpIHtcbiAgICAgICAgdGhpcy5zY2hlZHVsZVJlbW92YWwoMjApO1xuICAgIH1cbiAgICBkcm9wKCkge1xuICAgICAgICB0aGlzLnNjaGVkdWxlUmVtb3ZhbCgyMCk7XG4gICAgfVxuICAgIGRyYWdsZWF2ZShldmVudCkge1xuICAgICAgICBpZiAoIXRoaXMuZWRpdG9yVmlldy5kb20uY29udGFpbnMoZXZlbnQucmVsYXRlZFRhcmdldCkpXG4gICAgICAgICAgICB0aGlzLnNldEN1cnNvcihudWxsKTtcbiAgICB9XG59XG5cbmV4cG9ydCB7IGRyb3BDdXJzb3IgfTtcbiIsICJpbXBvcnQgeyBrZXlkb3duSGFuZGxlciB9IGZyb20gJ3Byb3NlbWlycm9yLWtleW1hcCc7XG5pbXBvcnQgeyBTZWxlY3Rpb24sIE5vZGVTZWxlY3Rpb24sIFRleHRTZWxlY3Rpb24sIFBsdWdpbiB9IGZyb20gJ3Byb3NlbWlycm9yLXN0YXRlJztcbmltcG9ydCB7IFNsaWNlLCBGcmFnbWVudCB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB7IERlY29yYXRpb25TZXQsIERlY29yYXRpb24gfSBmcm9tICdwcm9zZW1pcnJvci12aWV3JztcblxuLyoqXG5HYXAgY3Vyc29yIHNlbGVjdGlvbnMgYXJlIHJlcHJlc2VudGVkIHVzaW5nIHRoaXMgY2xhc3MuIEl0c1xuYCRhbmNob3JgIGFuZCBgJGhlYWRgIHByb3BlcnRpZXMgYm90aCBwb2ludCBhdCB0aGUgY3Vyc29yIHBvc2l0aW9uLlxuKi9cbmNsYXNzIEdhcEN1cnNvciBleHRlbmRzIFNlbGVjdGlvbiB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgZ2FwIGN1cnNvci5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKCRwb3MpIHtcbiAgICAgICAgc3VwZXIoJHBvcywgJHBvcyk7XG4gICAgfVxuICAgIG1hcChkb2MsIG1hcHBpbmcpIHtcbiAgICAgICAgbGV0ICRwb3MgPSBkb2MucmVzb2x2ZShtYXBwaW5nLm1hcCh0aGlzLmhlYWQpKTtcbiAgICAgICAgcmV0dXJuIEdhcEN1cnNvci52YWxpZCgkcG9zKSA/IG5ldyBHYXBDdXJzb3IoJHBvcykgOiBTZWxlY3Rpb24ubmVhcigkcG9zKTtcbiAgICB9XG4gICAgY29udGVudCgpIHsgcmV0dXJuIFNsaWNlLmVtcHR5OyB9XG4gICAgZXEob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIG90aGVyIGluc3RhbmNlb2YgR2FwQ3Vyc29yICYmIG90aGVyLmhlYWQgPT0gdGhpcy5oZWFkO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB7IHR5cGU6IFwiZ2FwY3Vyc29yXCIsIHBvczogdGhpcy5oZWFkIH07XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKGRvYywganNvbikge1xuICAgICAgICBpZiAodHlwZW9mIGpzb24ucG9zICE9IFwibnVtYmVyXCIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIEdhcEN1cnNvci5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBHYXBDdXJzb3IoZG9jLnJlc29sdmUoanNvbi5wb3MpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBnZXRCb29rbWFyaygpIHsgcmV0dXJuIG5ldyBHYXBCb29rbWFyayh0aGlzLmFuY2hvcik7IH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyB2YWxpZCgkcG9zKSB7XG4gICAgICAgIGxldCBwYXJlbnQgPSAkcG9zLnBhcmVudDtcbiAgICAgICAgaWYgKHBhcmVudC5pbmxpbmVDb250ZW50IHx8ICFjbG9zZWRCZWZvcmUoJHBvcykgfHwgIWNsb3NlZEFmdGVyKCRwb3MpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgb3ZlcnJpZGUgPSBwYXJlbnQudHlwZS5zcGVjLmFsbG93R2FwQ3Vyc29yO1xuICAgICAgICBpZiAob3ZlcnJpZGUgIT0gbnVsbClcbiAgICAgICAgICAgIHJldHVybiBvdmVycmlkZTtcbiAgICAgICAgbGV0IGRlZmx0ID0gcGFyZW50LmNvbnRlbnRNYXRjaEF0KCRwb3MuaW5kZXgoKSkuZGVmYXVsdFR5cGU7XG4gICAgICAgIHJldHVybiBkZWZsdCAmJiBkZWZsdC5pc1RleHRibG9jaztcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZmluZEdhcEN1cnNvckZyb20oJHBvcywgZGlyLCBtdXN0TW92ZSA9IGZhbHNlKSB7XG4gICAgICAgIHNlYXJjaDogZm9yICg7Oykge1xuICAgICAgICAgICAgaWYgKCFtdXN0TW92ZSAmJiBHYXBDdXJzb3IudmFsaWQoJHBvcykpXG4gICAgICAgICAgICAgICAgcmV0dXJuICRwb3M7XG4gICAgICAgICAgICBsZXQgcG9zID0gJHBvcy5wb3MsIG5leHQgPSBudWxsO1xuICAgICAgICAgICAgLy8gU2NhbiB1cCBmcm9tIHRoaXMgcG9zaXRpb25cbiAgICAgICAgICAgIGZvciAobGV0IGQgPSAkcG9zLmRlcHRoOzsgZC0tKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBhcmVudCA9ICRwb3Mubm9kZShkKTtcbiAgICAgICAgICAgICAgICBpZiAoZGlyID4gMCA/ICRwb3MuaW5kZXhBZnRlcihkKSA8IHBhcmVudC5jaGlsZENvdW50IDogJHBvcy5pbmRleChkKSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgbmV4dCA9IHBhcmVudC5jaGlsZChkaXIgPiAwID8gJHBvcy5pbmRleEFmdGVyKGQpIDogJHBvcy5pbmRleChkKSAtIDEpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoZCA9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwb3MgKz0gZGlyO1xuICAgICAgICAgICAgICAgIGxldCAkY3VyID0gJHBvcy5kb2MucmVzb2x2ZShwb3MpO1xuICAgICAgICAgICAgICAgIGlmIChHYXBDdXJzb3IudmFsaWQoJGN1cikpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAkY3VyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQW5kIHRoZW4gZG93biBpbnRvIHRoZSBuZXh0IG5vZGVcbiAgICAgICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICAgICAgICBsZXQgaW5zaWRlID0gZGlyID4gMCA/IG5leHQuZmlyc3RDaGlsZCA6IG5leHQubGFzdENoaWxkO1xuICAgICAgICAgICAgICAgIGlmICghaW5zaWRlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0LmlzQXRvbSAmJiAhbmV4dC5pc1RleHQgJiYgIU5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKG5leHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAkcG9zID0gJHBvcy5kb2MucmVzb2x2ZShwb3MgKyBuZXh0Lm5vZGVTaXplICogZGlyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIG11c3RNb3ZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZSBzZWFyY2g7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG5leHQgPSBpbnNpZGU7XG4gICAgICAgICAgICAgICAgcG9zICs9IGRpcjtcbiAgICAgICAgICAgICAgICBsZXQgJGN1ciA9ICRwb3MuZG9jLnJlc29sdmUocG9zKTtcbiAgICAgICAgICAgICAgICBpZiAoR2FwQ3Vyc29yLnZhbGlkKCRjdXIpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGN1cjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxufVxuR2FwQ3Vyc29yLnByb3RvdHlwZS52aXNpYmxlID0gZmFsc2U7XG5HYXBDdXJzb3IuZmluZEZyb20gPSBHYXBDdXJzb3IuZmluZEdhcEN1cnNvckZyb207XG5TZWxlY3Rpb24uanNvbklEKFwiZ2FwY3Vyc29yXCIsIEdhcEN1cnNvcik7XG5jbGFzcyBHYXBCb29rbWFyayB7XG4gICAgY29uc3RydWN0b3IocG9zKSB7XG4gICAgICAgIHRoaXMucG9zID0gcG9zO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICByZXR1cm4gbmV3IEdhcEJvb2ttYXJrKG1hcHBpbmcubWFwKHRoaXMucG9zKSk7XG4gICAgfVxuICAgIHJlc29sdmUoZG9jKSB7XG4gICAgICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUodGhpcy5wb3MpO1xuICAgICAgICByZXR1cm4gR2FwQ3Vyc29yLnZhbGlkKCRwb3MpID8gbmV3IEdhcEN1cnNvcigkcG9zKSA6IFNlbGVjdGlvbi5uZWFyKCRwb3MpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG5lZWRzR2FwKHR5cGUpIHtcbiAgICByZXR1cm4gdHlwZS5pc0F0b20gfHwgdHlwZS5zcGVjLmlzb2xhdGluZyB8fCB0eXBlLnNwZWMuY3JlYXRlR2FwQ3Vyc29yO1xufVxuZnVuY3Rpb24gY2xvc2VkQmVmb3JlKCRwb3MpIHtcbiAgICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aDsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgbGV0IGluZGV4ID0gJHBvcy5pbmRleChkKSwgcGFyZW50ID0gJHBvcy5ub2RlKGQpO1xuICAgICAgICAvLyBBdCB0aGUgc3RhcnQgb2YgdGhpcyBwYXJlbnQsIGxvb2sgYXQgbmV4dCBvbmVcbiAgICAgICAgaWYgKGluZGV4ID09IDApIHtcbiAgICAgICAgICAgIGlmIChwYXJlbnQudHlwZS5zcGVjLmlzb2xhdGluZylcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIFNlZSBpZiB0aGUgbm9kZSBiZWZvcmUgKG9yIGl0cyBmaXJzdCBhbmNlc3RvcikgaXMgY2xvc2VkXG4gICAgICAgIGZvciAobGV0IGJlZm9yZSA9IHBhcmVudC5jaGlsZChpbmRleCAtIDEpOzsgYmVmb3JlID0gYmVmb3JlLmxhc3RDaGlsZCkge1xuICAgICAgICAgICAgaWYgKChiZWZvcmUuY2hpbGRDb3VudCA9PSAwICYmICFiZWZvcmUuaW5saW5lQ29udGVudCkgfHwgbmVlZHNHYXAoYmVmb3JlLnR5cGUpKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgaWYgKGJlZm9yZS5pbmxpbmVDb250ZW50KVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBIaXQgc3RhcnQgb2YgZG9jdW1lbnRcbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGNsb3NlZEFmdGVyKCRwb3MpIHtcbiAgICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aDsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgbGV0IGluZGV4ID0gJHBvcy5pbmRleEFmdGVyKGQpLCBwYXJlbnQgPSAkcG9zLm5vZGUoZCk7XG4gICAgICAgIGlmIChpbmRleCA9PSBwYXJlbnQuY2hpbGRDb3VudCkge1xuICAgICAgICAgICAgaWYgKHBhcmVudC50eXBlLnNwZWMuaXNvbGF0aW5nKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgYWZ0ZXIgPSBwYXJlbnQuY2hpbGQoaW5kZXgpOzsgYWZ0ZXIgPSBhZnRlci5maXJzdENoaWxkKSB7XG4gICAgICAgICAgICBpZiAoKGFmdGVyLmNoaWxkQ291bnQgPT0gMCAmJiAhYWZ0ZXIuaW5saW5lQ29udGVudCkgfHwgbmVlZHNHYXAoYWZ0ZXIudHlwZSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICBpZiAoYWZ0ZXIuaW5saW5lQ29udGVudClcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuQ3JlYXRlIGEgZ2FwIGN1cnNvciBwbHVnaW4uIFdoZW4gZW5hYmxlZCwgdGhpcyB3aWxsIGNhcHR1cmUgY2xpY2tzXG5uZWFyIGFuZCBhcnJvdy1rZXktbW90aW9uIHBhc3QgcGxhY2VzIHRoYXQgZG9uJ3QgaGF2ZSBhIG5vcm1hbGx5XG5zZWxlY3RhYmxlIHBvc2l0aW9uIG5lYXJieSwgYW5kIGNyZWF0ZSBhIGdhcCBjdXJzb3Igc2VsZWN0aW9uIGZvclxudGhlbS4gVGhlIGN1cnNvciBpcyBkcmF3biBhcyBhbiBlbGVtZW50IHdpdGggY2xhc3NcbmBQcm9zZU1pcnJvci1nYXBjdXJzb3JgLiBZb3UgY2FuIGVpdGhlciBpbmNsdWRlXG5gc3R5bGUvZ2FwY3Vyc29yLmNzc2AgZnJvbSB0aGUgcGFja2FnZSdzIGRpcmVjdG9yeSBvciBhZGQgeW91ciBvd25cbnN0eWxlcyB0byBtYWtlIGl0IHZpc2libGUuXG4qL1xuZnVuY3Rpb24gZ2FwQ3Vyc29yKCkge1xuICAgIHJldHVybiBuZXcgUGx1Z2luKHtcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICAgIGRlY29yYXRpb25zOiBkcmF3R2FwQ3Vyc29yLFxuICAgICAgICAgICAgY3JlYXRlU2VsZWN0aW9uQmV0d2VlbihfdmlldywgJGFuY2hvciwgJGhlYWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gJGFuY2hvci5wb3MgPT0gJGhlYWQucG9zICYmIEdhcEN1cnNvci52YWxpZCgkaGVhZCkgPyBuZXcgR2FwQ3Vyc29yKCRoZWFkKSA6IG51bGw7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaGFuZGxlQ2xpY2ssXG4gICAgICAgICAgICBoYW5kbGVLZXlEb3duLFxuICAgICAgICAgICAgaGFuZGxlRE9NRXZlbnRzOiB7IGJlZm9yZWlucHV0OiBiZWZvcmVpbnB1dCB9XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmNvbnN0IGhhbmRsZUtleURvd24gPSBrZXlkb3duSGFuZGxlcih7XG4gICAgXCJBcnJvd0xlZnRcIjogYXJyb3coXCJob3JpelwiLCAtMSksXG4gICAgXCJBcnJvd1JpZ2h0XCI6IGFycm93KFwiaG9yaXpcIiwgMSksXG4gICAgXCJBcnJvd1VwXCI6IGFycm93KFwidmVydFwiLCAtMSksXG4gICAgXCJBcnJvd0Rvd25cIjogYXJyb3coXCJ2ZXJ0XCIsIDEpXG59KTtcbmZ1bmN0aW9uIGFycm93KGF4aXMsIGRpcikge1xuICAgIGNvbnN0IGRpclN0ciA9IGF4aXMgPT0gXCJ2ZXJ0XCIgPyAoZGlyID4gMCA/IFwiZG93blwiIDogXCJ1cFwiKSA6IChkaXIgPiAwID8gXCJyaWdodFwiIDogXCJsZWZ0XCIpO1xuICAgIHJldHVybiBmdW5jdGlvbiAoc3RhdGUsIGRpc3BhdGNoLCB2aWV3KSB7XG4gICAgICAgIGxldCBzZWwgPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgICAgIGxldCAkc3RhcnQgPSBkaXIgPiAwID8gc2VsLiR0byA6IHNlbC4kZnJvbSwgbXVzdE1vdmUgPSBzZWwuZW1wdHk7XG4gICAgICAgIGlmIChzZWwgaW5zdGFuY2VvZiBUZXh0U2VsZWN0aW9uKSB7XG4gICAgICAgICAgICBpZiAoIXZpZXcuZW5kT2ZUZXh0YmxvY2soZGlyU3RyKSB8fCAkc3RhcnQuZGVwdGggPT0gMClcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBtdXN0TW92ZSA9IGZhbHNlO1xuICAgICAgICAgICAgJHN0YXJ0ID0gc3RhdGUuZG9jLnJlc29sdmUoZGlyID4gMCA/ICRzdGFydC5hZnRlcigpIDogJHN0YXJ0LmJlZm9yZSgpKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgJGZvdW5kID0gR2FwQ3Vyc29yLmZpbmRHYXBDdXJzb3JGcm9tKCRzdGFydCwgZGlyLCBtdXN0TW92ZSk7XG4gICAgICAgIGlmICghJGZvdW5kKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5zZXRTZWxlY3Rpb24obmV3IEdhcEN1cnNvcigkZm91bmQpKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG59XG5mdW5jdGlvbiBoYW5kbGVDbGljayh2aWV3LCBwb3MsIGV2ZW50KSB7XG4gICAgaWYgKCF2aWV3IHx8ICF2aWV3LmVkaXRhYmxlKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0ICRwb3MgPSB2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKHBvcyk7XG4gICAgaWYgKCFHYXBDdXJzb3IudmFsaWQoJHBvcykpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgY2xpY2tQb3MgPSB2aWV3LnBvc0F0Q29vcmRzKHsgbGVmdDogZXZlbnQuY2xpZW50WCwgdG9wOiBldmVudC5jbGllbnRZIH0pO1xuICAgIGlmIChjbGlja1BvcyAmJiBjbGlja1Bvcy5pbnNpZGUgPiAtMSAmJiBOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZSh2aWV3LnN0YXRlLmRvYy5ub2RlQXQoY2xpY2tQb3MuaW5zaWRlKSkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB2aWV3LmRpc3BhdGNoKHZpZXcuc3RhdGUudHIuc2V0U2VsZWN0aW9uKG5ldyBHYXBDdXJzb3IoJHBvcykpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn1cbi8vIFRoaXMgaXMgYSBoYWNrIHRoYXQsIHdoZW4gYSBjb21wb3NpdGlvbiBzdGFydHMgd2hpbGUgYSBnYXAgY3Vyc29yXG4vLyBpcyBhY3RpdmUsIHF1aWNrbHkgY3JlYXRlcyBhbiBpbmxpbmUgY29udGV4dCBmb3IgdGhlIGNvbXBvc2l0aW9uIHRvXG4vLyBoYXBwZW4gaW4sIHRvIGF2b2lkIGl0IGJlaW5nIGFib3J0ZWQgYnkgdGhlIERPTSBzZWxlY3Rpb24gYmVpbmdcbi8vIG1vdmVkIGludG8gYSB2YWxpZCBwb3NpdGlvbi5cbmZ1bmN0aW9uIGJlZm9yZWlucHV0KHZpZXcsIGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LmlucHV0VHlwZSAhPSBcImluc2VydENvbXBvc2l0aW9uVGV4dFwiIHx8ICEodmlldy5zdGF0ZS5zZWxlY3Rpb24gaW5zdGFuY2VvZiBHYXBDdXJzb3IpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IHsgJGZyb20gfSA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uO1xuICAgIGxldCBpbnNlcnQgPSAkZnJvbS5wYXJlbnQuY29udGVudE1hdGNoQXQoJGZyb20uaW5kZXgoKSkuZmluZFdyYXBwaW5nKHZpZXcuc3RhdGUuc2NoZW1hLm5vZGVzLnRleHQpO1xuICAgIGlmICghaW5zZXJ0KVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IGZyYWcgPSBGcmFnbWVudC5lbXB0eTtcbiAgICBmb3IgKGxldCBpID0gaW5zZXJ0Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKVxuICAgICAgICBmcmFnID0gRnJhZ21lbnQuZnJvbShpbnNlcnRbaV0uY3JlYXRlQW5kRmlsbChudWxsLCBmcmFnKSk7XG4gICAgbGV0IHRyID0gdmlldy5zdGF0ZS50ci5yZXBsYWNlKCRmcm9tLnBvcywgJGZyb20ucG9zLCBuZXcgU2xpY2UoZnJhZywgMCwgMCkpO1xuICAgIHRyLnNldFNlbGVjdGlvbihUZXh0U2VsZWN0aW9uLm5lYXIodHIuZG9jLnJlc29sdmUoJGZyb20ucG9zICsgMSkpKTtcbiAgICB2aWV3LmRpc3BhdGNoKHRyKTtcbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBkcmF3R2FwQ3Vyc29yKHN0YXRlKSB7XG4gICAgaWYgKCEoc3RhdGUuc2VsZWN0aW9uIGluc3RhbmNlb2YgR2FwQ3Vyc29yKSlcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgbGV0IG5vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIG5vZGUuY2xhc3NOYW1lID0gXCJQcm9zZU1pcnJvci1nYXBjdXJzb3JcIjtcbiAgICByZXR1cm4gRGVjb3JhdGlvblNldC5jcmVhdGUoc3RhdGUuZG9jLCBbRGVjb3JhdGlvbi53aWRnZXQoc3RhdGUuc2VsZWN0aW9uLmhlYWQsIG5vZGUsIHsga2V5OiBcImdhcGN1cnNvclwiIH0pXSk7XG59XG5cbmV4cG9ydCB7IEdhcEN1cnNvciwgZ2FwQ3Vyc29yIH07XG4iLCAidmFyIEdPT0RfTEVBRl9TSVpFID0gMjAwO1xuXG4vLyA6OiBjbGFzczxUPiBBIHJvcGUgc2VxdWVuY2UgaXMgYSBwZXJzaXN0ZW50IHNlcXVlbmNlIGRhdGEgc3RydWN0dXJlXG4vLyB0aGF0IHN1cHBvcnRzIGFwcGVuZGluZywgcHJlcGVuZGluZywgYW5kIHNsaWNpbmcgd2l0aG91dCBkb2luZyBhXG4vLyBmdWxsIGNvcHkuIEl0IGlzIHJlcHJlc2VudGVkIGFzIGEgbW9zdGx5LWJhbGFuY2VkIHRyZWUuXG52YXIgUm9wZVNlcXVlbmNlID0gZnVuY3Rpb24gUm9wZVNlcXVlbmNlICgpIHt9O1xuXG5Sb3BlU2VxdWVuY2UucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uIGFwcGVuZCAob3RoZXIpIHtcbiAgaWYgKCFvdGhlci5sZW5ndGgpIHsgcmV0dXJuIHRoaXMgfVxuICBvdGhlciA9IFJvcGVTZXF1ZW5jZS5mcm9tKG90aGVyKTtcblxuICByZXR1cm4gKCF0aGlzLmxlbmd0aCAmJiBvdGhlcikgfHxcbiAgICAob3RoZXIubGVuZ3RoIDwgR09PRF9MRUFGX1NJWkUgJiYgdGhpcy5sZWFmQXBwZW5kKG90aGVyKSkgfHxcbiAgICAodGhpcy5sZW5ndGggPCBHT09EX0xFQUZfU0laRSAmJiBvdGhlci5sZWFmUHJlcGVuZCh0aGlzKSkgfHxcbiAgICB0aGlzLmFwcGVuZElubmVyKG90aGVyKVxufTtcblxuLy8gOjogKHVuaW9uPFtUXSwgUm9wZVNlcXVlbmNlPFQ+PikgXHUyMTkyIFJvcGVTZXF1ZW5jZTxUPlxuLy8gUHJlcGVuZCBhbiBhcnJheSBvciBvdGhlciByb3BlIHRvIHRoaXMgb25lLCByZXR1cm5pbmcgYSBuZXcgcm9wZS5cblJvcGVTZXF1ZW5jZS5wcm90b3R5cGUucHJlcGVuZCA9IGZ1bmN0aW9uIHByZXBlbmQgKG90aGVyKSB7XG4gIGlmICghb3RoZXIubGVuZ3RoKSB7IHJldHVybiB0aGlzIH1cbiAgcmV0dXJuIFJvcGVTZXF1ZW5jZS5mcm9tKG90aGVyKS5hcHBlbmQodGhpcylcbn07XG5cblJvcGVTZXF1ZW5jZS5wcm90b3R5cGUuYXBwZW5kSW5uZXIgPSBmdW5jdGlvbiBhcHBlbmRJbm5lciAob3RoZXIpIHtcbiAgcmV0dXJuIG5ldyBBcHBlbmQodGhpcywgb3RoZXIpXG59O1xuXG4vLyA6OiAoP251bWJlciwgP251bWJlcikgXHUyMTkyIFJvcGVTZXF1ZW5jZTxUPlxuLy8gQ3JlYXRlIGEgcm9wZSByZXBlc2VudGluZyBhIHN1Yi1zZXF1ZW5jZSBvZiB0aGlzIHJvcGUuXG5Sb3BlU2VxdWVuY2UucHJvdG90eXBlLnNsaWNlID0gZnVuY3Rpb24gc2xpY2UgKGZyb20sIHRvKSB7XG4gICAgaWYgKCBmcm9tID09PSB2b2lkIDAgKSBmcm9tID0gMDtcbiAgICBpZiAoIHRvID09PSB2b2lkIDAgKSB0byA9IHRoaXMubGVuZ3RoO1xuXG4gIGlmIChmcm9tID49IHRvKSB7IHJldHVybiBSb3BlU2VxdWVuY2UuZW1wdHkgfVxuICByZXR1cm4gdGhpcy5zbGljZUlubmVyKE1hdGgubWF4KDAsIGZyb20pLCBNYXRoLm1pbih0aGlzLmxlbmd0aCwgdG8pKVxufTtcblxuLy8gOjogKG51bWJlcikgXHUyMTkyIFRcbi8vIFJldHJpZXZlIHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBwb3NpdGlvbiBmcm9tIHRoaXMgcm9wZS5cblJvcGVTZXF1ZW5jZS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gZ2V0IChpKSB7XG4gIGlmIChpIDwgMCB8fCBpID49IHRoaXMubGVuZ3RoKSB7IHJldHVybiB1bmRlZmluZWQgfVxuICByZXR1cm4gdGhpcy5nZXRJbm5lcihpKVxufTtcblxuLy8gOjogKChlbGVtZW50OiBULCBpbmRleDogbnVtYmVyKSBcdTIxOTIgP2Jvb2wsID9udW1iZXIsID9udW1iZXIpXG4vLyBDYWxsIHRoZSBnaXZlbiBmdW5jdGlvbiBmb3IgZWFjaCBlbGVtZW50IGJldHdlZW4gdGhlIGdpdmVuXG4vLyBpbmRpY2VzLiBUaGlzIHRlbmRzIHRvIGJlIG1vcmUgZWZmaWNpZW50IHRoYW4gbG9vcGluZyBvdmVyIHRoZVxuLy8gaW5kaWNlcyBhbmQgY2FsbGluZyBgZ2V0YCwgYmVjYXVzZSBpdCBkb2Vzbid0IGhhdmUgdG8gZGVzY2VuZCB0aGVcbi8vIHRyZWUgZm9yIGV2ZXJ5IGVsZW1lbnQuXG5Sb3BlU2VxdWVuY2UucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbiBmb3JFYWNoIChmLCBmcm9tLCB0bykge1xuICAgIGlmICggZnJvbSA9PT0gdm9pZCAwICkgZnJvbSA9IDA7XG4gICAgaWYgKCB0byA9PT0gdm9pZCAwICkgdG8gPSB0aGlzLmxlbmd0aDtcblxuICBpZiAoZnJvbSA8PSB0bylcbiAgICB7IHRoaXMuZm9yRWFjaElubmVyKGYsIGZyb20sIHRvLCAwKTsgfVxuICBlbHNlXG4gICAgeyB0aGlzLmZvckVhY2hJbnZlcnRlZElubmVyKGYsIGZyb20sIHRvLCAwKTsgfVxufTtcblxuLy8gOjogKChlbGVtZW50OiBULCBpbmRleDogbnVtYmVyKSBcdTIxOTIgVSwgP251bWJlciwgP251bWJlcikgXHUyMTkyIFtVXVxuLy8gTWFwIHRoZSBnaXZlbiBmdW5jdGlvbnMgb3ZlciB0aGUgZWxlbWVudHMgb2YgdGhlIHJvcGUsIHByb2R1Y2luZ1xuLy8gYSBmbGF0IGFycmF5LlxuUm9wZVNlcXVlbmNlLnByb3RvdHlwZS5tYXAgPSBmdW5jdGlvbiBtYXAgKGYsIGZyb20sIHRvKSB7XG4gICAgaWYgKCBmcm9tID09PSB2b2lkIDAgKSBmcm9tID0gMDtcbiAgICBpZiAoIHRvID09PSB2b2lkIDAgKSB0byA9IHRoaXMubGVuZ3RoO1xuXG4gIHZhciByZXN1bHQgPSBbXTtcbiAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbHQsIGkpIHsgcmV0dXJuIHJlc3VsdC5wdXNoKGYoZWx0LCBpKSk7IH0sIGZyb20sIHRvKTtcbiAgcmV0dXJuIHJlc3VsdFxufTtcblxuLy8gOjogKD91bmlvbjxbVF0sIFJvcGVTZXF1ZW5jZTxUPj4pIFx1MjE5MiBSb3BlU2VxdWVuY2U8VD5cbi8vIENyZWF0ZSBhIHJvcGUgcmVwcmVzZW50aW5nIHRoZSBnaXZlbiBhcnJheSwgb3IgcmV0dXJuIHRoZSByb3BlXG4vLyBpdHNlbGYgaWYgYSByb3BlIHdhcyBnaXZlbi5cblJvcGVTZXF1ZW5jZS5mcm9tID0gZnVuY3Rpb24gZnJvbSAodmFsdWVzKSB7XG4gIGlmICh2YWx1ZXMgaW5zdGFuY2VvZiBSb3BlU2VxdWVuY2UpIHsgcmV0dXJuIHZhbHVlcyB9XG4gIHJldHVybiB2YWx1ZXMgJiYgdmFsdWVzLmxlbmd0aCA/IG5ldyBMZWFmKHZhbHVlcykgOiBSb3BlU2VxdWVuY2UuZW1wdHlcbn07XG5cbnZhciBMZWFmID0gLypAX19QVVJFX18qLyhmdW5jdGlvbiAoUm9wZVNlcXVlbmNlKSB7XG4gIGZ1bmN0aW9uIExlYWYodmFsdWVzKSB7XG4gICAgUm9wZVNlcXVlbmNlLmNhbGwodGhpcyk7XG4gICAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7XG4gIH1cblxuICBpZiAoIFJvcGVTZXF1ZW5jZSApIExlYWYuX19wcm90b19fID0gUm9wZVNlcXVlbmNlO1xuICBMZWFmLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoIFJvcGVTZXF1ZW5jZSAmJiBSb3BlU2VxdWVuY2UucHJvdG90eXBlICk7XG4gIExlYWYucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gTGVhZjtcblxuICB2YXIgcHJvdG90eXBlQWNjZXNzb3JzID0geyBsZW5ndGg6IHsgY29uZmlndXJhYmxlOiB0cnVlIH0sZGVwdGg6IHsgY29uZmlndXJhYmxlOiB0cnVlIH0gfTtcblxuICBMZWFmLnByb3RvdHlwZS5mbGF0dGVuID0gZnVuY3Rpb24gZmxhdHRlbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWVzXG4gIH07XG5cbiAgTGVhZi5wcm90b3R5cGUuc2xpY2VJbm5lciA9IGZ1bmN0aW9uIHNsaWNlSW5uZXIgKGZyb20sIHRvKSB7XG4gICAgaWYgKGZyb20gPT0gMCAmJiB0byA9PSB0aGlzLmxlbmd0aCkgeyByZXR1cm4gdGhpcyB9XG4gICAgcmV0dXJuIG5ldyBMZWFmKHRoaXMudmFsdWVzLnNsaWNlKGZyb20sIHRvKSlcbiAgfTtcblxuICBMZWFmLnByb3RvdHlwZS5nZXRJbm5lciA9IGZ1bmN0aW9uIGdldElubmVyIChpKSB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWVzW2ldXG4gIH07XG5cbiAgTGVhZi5wcm90b3R5cGUuZm9yRWFjaElubmVyID0gZnVuY3Rpb24gZm9yRWFjaElubmVyIChmLCBmcm9tLCB0bywgc3RhcnQpIHtcbiAgICBmb3IgKHZhciBpID0gZnJvbTsgaSA8IHRvOyBpKyspXG4gICAgICB7IGlmIChmKHRoaXMudmFsdWVzW2ldLCBzdGFydCArIGkpID09PSBmYWxzZSkgeyByZXR1cm4gZmFsc2UgfSB9XG4gIH07XG5cbiAgTGVhZi5wcm90b3R5cGUuZm9yRWFjaEludmVydGVkSW5uZXIgPSBmdW5jdGlvbiBmb3JFYWNoSW52ZXJ0ZWRJbm5lciAoZiwgZnJvbSwgdG8sIHN0YXJ0KSB7XG4gICAgZm9yICh2YXIgaSA9IGZyb20gLSAxOyBpID49IHRvOyBpLS0pXG4gICAgICB7IGlmIChmKHRoaXMudmFsdWVzW2ldLCBzdGFydCArIGkpID09PSBmYWxzZSkgeyByZXR1cm4gZmFsc2UgfSB9XG4gIH07XG5cbiAgTGVhZi5wcm90b3R5cGUubGVhZkFwcGVuZCA9IGZ1bmN0aW9uIGxlYWZBcHBlbmQgKG90aGVyKSB7XG4gICAgaWYgKHRoaXMubGVuZ3RoICsgb3RoZXIubGVuZ3RoIDw9IEdPT0RfTEVBRl9TSVpFKVxuICAgICAgeyByZXR1cm4gbmV3IExlYWYodGhpcy52YWx1ZXMuY29uY2F0KG90aGVyLmZsYXR0ZW4oKSkpIH1cbiAgfTtcblxuICBMZWFmLnByb3RvdHlwZS5sZWFmUHJlcGVuZCA9IGZ1bmN0aW9uIGxlYWZQcmVwZW5kIChvdGhlcikge1xuICAgIGlmICh0aGlzLmxlbmd0aCArIG90aGVyLmxlbmd0aCA8PSBHT09EX0xFQUZfU0laRSlcbiAgICAgIHsgcmV0dXJuIG5ldyBMZWFmKG90aGVyLmZsYXR0ZW4oKS5jb25jYXQodGhpcy52YWx1ZXMpKSB9XG4gIH07XG5cbiAgcHJvdG90eXBlQWNjZXNzb3JzLmxlbmd0aC5nZXQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLnZhbHVlcy5sZW5ndGggfTtcblxuICBwcm90b3R5cGVBY2Nlc3NvcnMuZGVwdGguZ2V0ID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gMCB9O1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKCBMZWFmLnByb3RvdHlwZSwgcHJvdG90eXBlQWNjZXNzb3JzICk7XG5cbiAgcmV0dXJuIExlYWY7XG59KFJvcGVTZXF1ZW5jZSkpO1xuXG4vLyA6OiBSb3BlU2VxdWVuY2Vcbi8vIFRoZSBlbXB0eSByb3BlIHNlcXVlbmNlLlxuUm9wZVNlcXVlbmNlLmVtcHR5ID0gbmV3IExlYWYoW10pO1xuXG52YXIgQXBwZW5kID0gLypAX19QVVJFX18qLyhmdW5jdGlvbiAoUm9wZVNlcXVlbmNlKSB7XG4gIGZ1bmN0aW9uIEFwcGVuZChsZWZ0LCByaWdodCkge1xuICAgIFJvcGVTZXF1ZW5jZS5jYWxsKHRoaXMpO1xuICAgIHRoaXMubGVmdCA9IGxlZnQ7XG4gICAgdGhpcy5yaWdodCA9IHJpZ2h0O1xuICAgIHRoaXMubGVuZ3RoID0gbGVmdC5sZW5ndGggKyByaWdodC5sZW5ndGg7XG4gICAgdGhpcy5kZXB0aCA9IE1hdGgubWF4KGxlZnQuZGVwdGgsIHJpZ2h0LmRlcHRoKSArIDE7XG4gIH1cblxuICBpZiAoIFJvcGVTZXF1ZW5jZSApIEFwcGVuZC5fX3Byb3RvX18gPSBSb3BlU2VxdWVuY2U7XG4gIEFwcGVuZC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKCBSb3BlU2VxdWVuY2UgJiYgUm9wZVNlcXVlbmNlLnByb3RvdHlwZSApO1xuICBBcHBlbmQucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gQXBwZW5kO1xuXG4gIEFwcGVuZC5wcm90b3R5cGUuZmxhdHRlbiA9IGZ1bmN0aW9uIGZsYXR0ZW4gKCkge1xuICAgIHJldHVybiB0aGlzLmxlZnQuZmxhdHRlbigpLmNvbmNhdCh0aGlzLnJpZ2h0LmZsYXR0ZW4oKSlcbiAgfTtcblxuICBBcHBlbmQucHJvdG90eXBlLmdldElubmVyID0gZnVuY3Rpb24gZ2V0SW5uZXIgKGkpIHtcbiAgICByZXR1cm4gaSA8IHRoaXMubGVmdC5sZW5ndGggPyB0aGlzLmxlZnQuZ2V0KGkpIDogdGhpcy5yaWdodC5nZXQoaSAtIHRoaXMubGVmdC5sZW5ndGgpXG4gIH07XG5cbiAgQXBwZW5kLnByb3RvdHlwZS5mb3JFYWNoSW5uZXIgPSBmdW5jdGlvbiBmb3JFYWNoSW5uZXIgKGYsIGZyb20sIHRvLCBzdGFydCkge1xuICAgIHZhciBsZWZ0TGVuID0gdGhpcy5sZWZ0Lmxlbmd0aDtcbiAgICBpZiAoZnJvbSA8IGxlZnRMZW4gJiZcbiAgICAgICAgdGhpcy5sZWZ0LmZvckVhY2hJbm5lcihmLCBmcm9tLCBNYXRoLm1pbih0bywgbGVmdExlbiksIHN0YXJ0KSA9PT0gZmFsc2UpXG4gICAgICB7IHJldHVybiBmYWxzZSB9XG4gICAgaWYgKHRvID4gbGVmdExlbiAmJlxuICAgICAgICB0aGlzLnJpZ2h0LmZvckVhY2hJbm5lcihmLCBNYXRoLm1heChmcm9tIC0gbGVmdExlbiwgMCksIE1hdGgubWluKHRoaXMubGVuZ3RoLCB0bykgLSBsZWZ0TGVuLCBzdGFydCArIGxlZnRMZW4pID09PSBmYWxzZSlcbiAgICAgIHsgcmV0dXJuIGZhbHNlIH1cbiAgfTtcblxuICBBcHBlbmQucHJvdG90eXBlLmZvckVhY2hJbnZlcnRlZElubmVyID0gZnVuY3Rpb24gZm9yRWFjaEludmVydGVkSW5uZXIgKGYsIGZyb20sIHRvLCBzdGFydCkge1xuICAgIHZhciBsZWZ0TGVuID0gdGhpcy5sZWZ0Lmxlbmd0aDtcbiAgICBpZiAoZnJvbSA+IGxlZnRMZW4gJiZcbiAgICAgICAgdGhpcy5yaWdodC5mb3JFYWNoSW52ZXJ0ZWRJbm5lcihmLCBmcm9tIC0gbGVmdExlbiwgTWF0aC5tYXgodG8sIGxlZnRMZW4pIC0gbGVmdExlbiwgc3RhcnQgKyBsZWZ0TGVuKSA9PT0gZmFsc2UpXG4gICAgICB7IHJldHVybiBmYWxzZSB9XG4gICAgaWYgKHRvIDwgbGVmdExlbiAmJlxuICAgICAgICB0aGlzLmxlZnQuZm9yRWFjaEludmVydGVkSW5uZXIoZiwgTWF0aC5taW4oZnJvbSwgbGVmdExlbiksIHRvLCBzdGFydCkgPT09IGZhbHNlKVxuICAgICAgeyByZXR1cm4gZmFsc2UgfVxuICB9O1xuXG4gIEFwcGVuZC5wcm90b3R5cGUuc2xpY2VJbm5lciA9IGZ1bmN0aW9uIHNsaWNlSW5uZXIgKGZyb20sIHRvKSB7XG4gICAgaWYgKGZyb20gPT0gMCAmJiB0byA9PSB0aGlzLmxlbmd0aCkgeyByZXR1cm4gdGhpcyB9XG4gICAgdmFyIGxlZnRMZW4gPSB0aGlzLmxlZnQubGVuZ3RoO1xuICAgIGlmICh0byA8PSBsZWZ0TGVuKSB7IHJldHVybiB0aGlzLmxlZnQuc2xpY2UoZnJvbSwgdG8pIH1cbiAgICBpZiAoZnJvbSA+PSBsZWZ0TGVuKSB7IHJldHVybiB0aGlzLnJpZ2h0LnNsaWNlKGZyb20gLSBsZWZ0TGVuLCB0byAtIGxlZnRMZW4pIH1cbiAgICByZXR1cm4gdGhpcy5sZWZ0LnNsaWNlKGZyb20sIGxlZnRMZW4pLmFwcGVuZCh0aGlzLnJpZ2h0LnNsaWNlKDAsIHRvIC0gbGVmdExlbikpXG4gIH07XG5cbiAgQXBwZW5kLnByb3RvdHlwZS5sZWFmQXBwZW5kID0gZnVuY3Rpb24gbGVhZkFwcGVuZCAob3RoZXIpIHtcbiAgICB2YXIgaW5uZXIgPSB0aGlzLnJpZ2h0LmxlYWZBcHBlbmQob3RoZXIpO1xuICAgIGlmIChpbm5lcikgeyByZXR1cm4gbmV3IEFwcGVuZCh0aGlzLmxlZnQsIGlubmVyKSB9XG4gIH07XG5cbiAgQXBwZW5kLnByb3RvdHlwZS5sZWFmUHJlcGVuZCA9IGZ1bmN0aW9uIGxlYWZQcmVwZW5kIChvdGhlcikge1xuICAgIHZhciBpbm5lciA9IHRoaXMubGVmdC5sZWFmUHJlcGVuZChvdGhlcik7XG4gICAgaWYgKGlubmVyKSB7IHJldHVybiBuZXcgQXBwZW5kKGlubmVyLCB0aGlzLnJpZ2h0KSB9XG4gIH07XG5cbiAgQXBwZW5kLnByb3RvdHlwZS5hcHBlbmRJbm5lciA9IGZ1bmN0aW9uIGFwcGVuZElubmVyIChvdGhlcikge1xuICAgIGlmICh0aGlzLmxlZnQuZGVwdGggPj0gTWF0aC5tYXgodGhpcy5yaWdodC5kZXB0aCwgb3RoZXIuZGVwdGgpICsgMSlcbiAgICAgIHsgcmV0dXJuIG5ldyBBcHBlbmQodGhpcy5sZWZ0LCBuZXcgQXBwZW5kKHRoaXMucmlnaHQsIG90aGVyKSkgfVxuICAgIHJldHVybiBuZXcgQXBwZW5kKHRoaXMsIG90aGVyKVxuICB9O1xuXG4gIHJldHVybiBBcHBlbmQ7XG59KFJvcGVTZXF1ZW5jZSkpO1xuXG5leHBvcnQgZGVmYXVsdCBSb3BlU2VxdWVuY2U7XG4iLCAiaW1wb3J0IFJvcGVTZXF1ZW5jZSBmcm9tICdyb3BlLXNlcXVlbmNlJztcbmltcG9ydCB7IE1hcHBpbmcgfSBmcm9tICdwcm9zZW1pcnJvci10cmFuc2Zvcm0nO1xuaW1wb3J0IHsgUGx1Z2luS2V5LCBQbHVnaW4gfSBmcm9tICdwcm9zZW1pcnJvci1zdGF0ZSc7XG5cbi8vIFByb3NlTWlycm9yJ3MgaGlzdG9yeSBpc24ndCBzaW1wbHkgYSB3YXkgdG8gcm9sbCBiYWNrIHRvIGEgcHJldmlvdXNcbi8vIHN0YXRlLCBiZWNhdXNlIFByb3NlTWlycm9yIHN1cHBvcnRzIGFwcGx5aW5nIGNoYW5nZXMgd2l0aG91dCBhZGRpbmdcbi8vIHRoZW0gdG8gdGhlIGhpc3RvcnkgKGZvciBleGFtcGxlIGR1cmluZyBjb2xsYWJvcmF0aW9uKS5cbi8vXG4vLyBUbyB0aGlzIGVuZCwgZWFjaCAnQnJhbmNoJyAob25lIGZvciB0aGUgdW5kbyBoaXN0b3J5IGFuZCBvbmUgZm9yXG4vLyB0aGUgcmVkbyBoaXN0b3J5KSBrZWVwcyBhbiBhcnJheSBvZiAnSXRlbXMnLCB3aGljaCBjYW4gb3B0aW9uYWxseVxuLy8gaG9sZCBhIHN0ZXAgKGFuIGFjdHVhbCB1bmRvYWJsZSBjaGFuZ2UpLCBhbmQgYWx3YXlzIGhvbGQgYSBwb3NpdGlvblxuLy8gbWFwICh3aGljaCBpcyBuZWVkZWQgdG8gbW92ZSBjaGFuZ2VzIGJlbG93IHRoZW0gdG8gYXBwbHkgdG8gdGhlXG4vLyBjdXJyZW50IGRvY3VtZW50KS5cbi8vXG4vLyBBbiBpdGVtIHRoYXQgaGFzIGJvdGggYSBzdGVwIGFuZCBhIHNlbGVjdGlvbiBib29rbWFyayBpcyB0aGUgc3RhcnRcbi8vIG9mIGFuICdldmVudCcgXHUyMDE0IGEgZ3JvdXAgb2YgY2hhbmdlcyB0aGF0IHdpbGwgYmUgdW5kb25lIG9yIHJlZG9uZSBhdFxuLy8gb25jZS4gKEl0IHN0b3JlcyBvbmx5IHRoZSBib29rbWFyaywgc2luY2UgdGhhdCB3YXkgd2UgZG9uJ3QgaGF2ZSB0b1xuLy8gcHJvdmlkZSBhIGRvY3VtZW50IHVudGlsIHRoZSBzZWxlY3Rpb24gaXMgYWN0dWFsbHkgYXBwbGllZCwgd2hpY2hcbi8vIGlzIHVzZWZ1bCB3aGVuIGNvbXByZXNzaW5nLilcbi8vIFVzZWQgdG8gc2NoZWR1bGUgaGlzdG9yeSBjb21wcmVzc2lvblxuY29uc3QgbWF4X2VtcHR5X2l0ZW1zID0gNTAwO1xuY2xhc3MgQnJhbmNoIHtcbiAgICBjb25zdHJ1Y3RvcihpdGVtcywgZXZlbnRDb3VudCkge1xuICAgICAgICB0aGlzLml0ZW1zID0gaXRlbXM7XG4gICAgICAgIHRoaXMuZXZlbnRDb3VudCA9IGV2ZW50Q291bnQ7XG4gICAgfVxuICAgIC8vIFBvcCB0aGUgbGF0ZXN0IGV2ZW50IG9mZiB0aGUgYnJhbmNoJ3MgaGlzdG9yeSBhbmQgYXBwbHkgaXRcbiAgICAvLyB0byBhIGRvY3VtZW50IHRyYW5zZm9ybS5cbiAgICBwb3BFdmVudChzdGF0ZSwgcHJlc2VydmVJdGVtcykge1xuICAgICAgICBpZiAodGhpcy5ldmVudENvdW50ID09IDApXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgbGV0IGVuZCA9IHRoaXMuaXRlbXMubGVuZ3RoO1xuICAgICAgICBmb3IgKDs7IGVuZC0tKSB7XG4gICAgICAgICAgICBsZXQgbmV4dCA9IHRoaXMuaXRlbXMuZ2V0KGVuZCAtIDEpO1xuICAgICAgICAgICAgaWYgKG5leHQuc2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgLS1lbmQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHJlbWFwLCBtYXBGcm9tO1xuICAgICAgICBpZiAocHJlc2VydmVJdGVtcykge1xuICAgICAgICAgICAgcmVtYXAgPSB0aGlzLnJlbWFwcGluZyhlbmQsIHRoaXMuaXRlbXMubGVuZ3RoKTtcbiAgICAgICAgICAgIG1hcEZyb20gPSByZW1hcC5tYXBzLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgdHJhbnNmb3JtID0gc3RhdGUudHI7XG4gICAgICAgIGxldCBzZWxlY3Rpb24sIHJlbWFpbmluZztcbiAgICAgICAgbGV0IGFkZEFmdGVyID0gW10sIGFkZEJlZm9yZSA9IFtdO1xuICAgICAgICB0aGlzLml0ZW1zLmZvckVhY2goKGl0ZW0sIGkpID0+IHtcbiAgICAgICAgICAgIGlmICghaXRlbS5zdGVwKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFyZW1hcCkge1xuICAgICAgICAgICAgICAgICAgICByZW1hcCA9IHRoaXMucmVtYXBwaW5nKGVuZCwgaSArIDEpO1xuICAgICAgICAgICAgICAgICAgICBtYXBGcm9tID0gcmVtYXAubWFwcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG1hcEZyb20tLTtcbiAgICAgICAgICAgICAgICBhZGRCZWZvcmUucHVzaChpdGVtKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVtYXApIHtcbiAgICAgICAgICAgICAgICBhZGRCZWZvcmUucHVzaChuZXcgSXRlbShpdGVtLm1hcCkpO1xuICAgICAgICAgICAgICAgIGxldCBzdGVwID0gaXRlbS5zdGVwLm1hcChyZW1hcC5zbGljZShtYXBGcm9tKSksIG1hcDtcbiAgICAgICAgICAgICAgICBpZiAoc3RlcCAmJiB0cmFuc2Zvcm0ubWF5YmVTdGVwKHN0ZXApLmRvYykge1xuICAgICAgICAgICAgICAgICAgICBtYXAgPSB0cmFuc2Zvcm0ubWFwcGluZy5tYXBzW3RyYW5zZm9ybS5tYXBwaW5nLm1hcHMubGVuZ3RoIC0gMV07XG4gICAgICAgICAgICAgICAgICAgIGFkZEFmdGVyLnB1c2gobmV3IEl0ZW0obWFwLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgYWRkQWZ0ZXIubGVuZ3RoICsgYWRkQmVmb3JlLmxlbmd0aCkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBtYXBGcm9tLS07XG4gICAgICAgICAgICAgICAgaWYgKG1hcClcbiAgICAgICAgICAgICAgICAgICAgcmVtYXAuYXBwZW5kTWFwKG1hcCwgbWFwRnJvbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0cmFuc2Zvcm0ubWF5YmVTdGVwKGl0ZW0uc3RlcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXRlbS5zZWxlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb24gPSByZW1hcCA/IGl0ZW0uc2VsZWN0aW9uLm1hcChyZW1hcC5zbGljZShtYXBGcm9tKSkgOiBpdGVtLnNlbGVjdGlvbjtcbiAgICAgICAgICAgICAgICByZW1haW5pbmcgPSBuZXcgQnJhbmNoKHRoaXMuaXRlbXMuc2xpY2UoMCwgZW5kKS5hcHBlbmQoYWRkQmVmb3JlLnJldmVyc2UoKS5jb25jYXQoYWRkQWZ0ZXIpKSwgdGhpcy5ldmVudENvdW50IC0gMSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB0aGlzLml0ZW1zLmxlbmd0aCwgMCk7XG4gICAgICAgIHJldHVybiB7IHJlbWFpbmluZzogcmVtYWluaW5nLCB0cmFuc2Zvcm0sIHNlbGVjdGlvbjogc2VsZWN0aW9uIH07XG4gICAgfVxuICAgIC8vIENyZWF0ZSBhIG5ldyBicmFuY2ggd2l0aCB0aGUgZ2l2ZW4gdHJhbnNmb3JtIGFkZGVkLlxuICAgIGFkZFRyYW5zZm9ybSh0cmFuc2Zvcm0sIHNlbGVjdGlvbiwgaGlzdE9wdGlvbnMsIHByZXNlcnZlSXRlbXMpIHtcbiAgICAgICAgbGV0IG5ld0l0ZW1zID0gW10sIGV2ZW50Q291bnQgPSB0aGlzLmV2ZW50Q291bnQ7XG4gICAgICAgIGxldCBvbGRJdGVtcyA9IHRoaXMuaXRlbXMsIGxhc3RJdGVtID0gIXByZXNlcnZlSXRlbXMgJiYgb2xkSXRlbXMubGVuZ3RoID8gb2xkSXRlbXMuZ2V0KG9sZEl0ZW1zLmxlbmd0aCAtIDEpIDogbnVsbDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0cmFuc2Zvcm0uc3RlcHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBzdGVwID0gdHJhbnNmb3JtLnN0ZXBzW2ldLmludmVydCh0cmFuc2Zvcm0uZG9jc1tpXSk7XG4gICAgICAgICAgICBsZXQgaXRlbSA9IG5ldyBJdGVtKHRyYW5zZm9ybS5tYXBwaW5nLm1hcHNbaV0sIHN0ZXAsIHNlbGVjdGlvbiksIG1lcmdlZDtcbiAgICAgICAgICAgIGlmIChtZXJnZWQgPSBsYXN0SXRlbSAmJiBsYXN0SXRlbS5tZXJnZShpdGVtKSkge1xuICAgICAgICAgICAgICAgIGl0ZW0gPSBtZXJnZWQ7XG4gICAgICAgICAgICAgICAgaWYgKGkpXG4gICAgICAgICAgICAgICAgICAgIG5ld0l0ZW1zLnBvcCgpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgb2xkSXRlbXMgPSBvbGRJdGVtcy5zbGljZSgwLCBvbGRJdGVtcy5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5ld0l0ZW1zLnB1c2goaXRlbSk7XG4gICAgICAgICAgICBpZiAoc2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgZXZlbnRDb3VudCsrO1xuICAgICAgICAgICAgICAgIHNlbGVjdGlvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghcHJlc2VydmVJdGVtcylcbiAgICAgICAgICAgICAgICBsYXN0SXRlbSA9IGl0ZW07XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG92ZXJmbG93ID0gZXZlbnRDb3VudCAtIGhpc3RPcHRpb25zLmRlcHRoO1xuICAgICAgICBpZiAob3ZlcmZsb3cgPiBERVBUSF9PVkVSRkxPVykge1xuICAgICAgICAgICAgb2xkSXRlbXMgPSBjdXRPZmZFdmVudHMob2xkSXRlbXMsIG92ZXJmbG93KTtcbiAgICAgICAgICAgIGV2ZW50Q291bnQgLT0gb3ZlcmZsb3c7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBCcmFuY2gob2xkSXRlbXMuYXBwZW5kKG5ld0l0ZW1zKSwgZXZlbnRDb3VudCk7XG4gICAgfVxuICAgIHJlbWFwcGluZyhmcm9tLCB0bykge1xuICAgICAgICBsZXQgbWFwcyA9IG5ldyBNYXBwaW5nO1xuICAgICAgICB0aGlzLml0ZW1zLmZvckVhY2goKGl0ZW0sIGkpID0+IHtcbiAgICAgICAgICAgIGxldCBtaXJyb3JQb3MgPSBpdGVtLm1pcnJvck9mZnNldCAhPSBudWxsICYmIGkgLSBpdGVtLm1pcnJvck9mZnNldCA+PSBmcm9tXG4gICAgICAgICAgICAgICAgPyBtYXBzLm1hcHMubGVuZ3RoIC0gaXRlbS5taXJyb3JPZmZzZXQgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBtYXBzLmFwcGVuZE1hcChpdGVtLm1hcCwgbWlycm9yUG9zKTtcbiAgICAgICAgfSwgZnJvbSwgdG8pO1xuICAgICAgICByZXR1cm4gbWFwcztcbiAgICB9XG4gICAgYWRkTWFwcyhhcnJheSkge1xuICAgICAgICBpZiAodGhpcy5ldmVudENvdW50ID09IDApXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgcmV0dXJuIG5ldyBCcmFuY2godGhpcy5pdGVtcy5hcHBlbmQoYXJyYXkubWFwKG1hcCA9PiBuZXcgSXRlbShtYXApKSksIHRoaXMuZXZlbnRDb3VudCk7XG4gICAgfVxuICAgIC8vIFdoZW4gdGhlIGNvbGxhYiBtb2R1bGUgcmVjZWl2ZXMgcmVtb3RlIGNoYW5nZXMsIHRoZSBoaXN0b3J5IGhhc1xuICAgIC8vIHRvIGtub3cgYWJvdXQgdGhvc2UsIHNvIHRoYXQgaXQgY2FuIGFkanVzdCB0aGUgc3RlcHMgdGhhdCB3ZXJlXG4gICAgLy8gcmViYXNlZCBvbiB0b3Agb2YgdGhlIHJlbW90ZSBjaGFuZ2VzLCBhbmQgaW5jbHVkZSB0aGUgcG9zaXRpb25cbiAgICAvLyBtYXBzIGZvciB0aGUgcmVtb3RlIGNoYW5nZXMgaW4gaXRzIGFycmF5IG9mIGl0ZW1zLlxuICAgIHJlYmFzZWQocmViYXNlZFRyYW5zZm9ybSwgcmViYXNlZENvdW50KSB7XG4gICAgICAgIGlmICghdGhpcy5ldmVudENvdW50KVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIGxldCByZWJhc2VkSXRlbXMgPSBbXSwgc3RhcnQgPSBNYXRoLm1heCgwLCB0aGlzLml0ZW1zLmxlbmd0aCAtIHJlYmFzZWRDb3VudCk7XG4gICAgICAgIGxldCBtYXBwaW5nID0gcmViYXNlZFRyYW5zZm9ybS5tYXBwaW5nO1xuICAgICAgICBsZXQgbmV3VW50aWwgPSByZWJhc2VkVHJhbnNmb3JtLnN0ZXBzLmxlbmd0aDtcbiAgICAgICAgbGV0IGV2ZW50Q291bnQgPSB0aGlzLmV2ZW50Q291bnQ7XG4gICAgICAgIHRoaXMuaXRlbXMuZm9yRWFjaChpdGVtID0+IHsgaWYgKGl0ZW0uc2VsZWN0aW9uKVxuICAgICAgICAgICAgZXZlbnRDb3VudC0tOyB9LCBzdGFydCk7XG4gICAgICAgIGxldCBpUmViYXNlZCA9IHJlYmFzZWRDb3VudDtcbiAgICAgICAgdGhpcy5pdGVtcy5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgbGV0IHBvcyA9IG1hcHBpbmcuZ2V0TWlycm9yKC0taVJlYmFzZWQpO1xuICAgICAgICAgICAgaWYgKHBvcyA9PSBudWxsKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIG5ld1VudGlsID0gTWF0aC5taW4obmV3VW50aWwsIHBvcyk7XG4gICAgICAgICAgICBsZXQgbWFwID0gbWFwcGluZy5tYXBzW3Bvc107XG4gICAgICAgICAgICBpZiAoaXRlbS5zdGVwKSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0ZXAgPSByZWJhc2VkVHJhbnNmb3JtLnN0ZXBzW3Bvc10uaW52ZXJ0KHJlYmFzZWRUcmFuc2Zvcm0uZG9jc1twb3NdKTtcbiAgICAgICAgICAgICAgICBsZXQgc2VsZWN0aW9uID0gaXRlbS5zZWxlY3Rpb24gJiYgaXRlbS5zZWxlY3Rpb24ubWFwKG1hcHBpbmcuc2xpY2UoaVJlYmFzZWQgKyAxLCBwb3MpKTtcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0aW9uKVxuICAgICAgICAgICAgICAgICAgICBldmVudENvdW50Kys7XG4gICAgICAgICAgICAgICAgcmViYXNlZEl0ZW1zLnB1c2gobmV3IEl0ZW0obWFwLCBzdGVwLCBzZWxlY3Rpb24pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlYmFzZWRJdGVtcy5wdXNoKG5ldyBJdGVtKG1hcCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBzdGFydCk7XG4gICAgICAgIGxldCBuZXdNYXBzID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSByZWJhc2VkQ291bnQ7IGkgPCBuZXdVbnRpbDsgaSsrKVxuICAgICAgICAgICAgbmV3TWFwcy5wdXNoKG5ldyBJdGVtKG1hcHBpbmcubWFwc1tpXSkpO1xuICAgICAgICBsZXQgaXRlbXMgPSB0aGlzLml0ZW1zLnNsaWNlKDAsIHN0YXJ0KS5hcHBlbmQobmV3TWFwcykuYXBwZW5kKHJlYmFzZWRJdGVtcyk7XG4gICAgICAgIGxldCBicmFuY2ggPSBuZXcgQnJhbmNoKGl0ZW1zLCBldmVudENvdW50KTtcbiAgICAgICAgaWYgKGJyYW5jaC5lbXB0eUl0ZW1Db3VudCgpID4gbWF4X2VtcHR5X2l0ZW1zKVxuICAgICAgICAgICAgYnJhbmNoID0gYnJhbmNoLmNvbXByZXNzKHRoaXMuaXRlbXMubGVuZ3RoIC0gcmViYXNlZEl0ZW1zLmxlbmd0aCk7XG4gICAgICAgIHJldHVybiBicmFuY2g7XG4gICAgfVxuICAgIGVtcHR5SXRlbUNvdW50KCkge1xuICAgICAgICBsZXQgY291bnQgPSAwO1xuICAgICAgICB0aGlzLml0ZW1zLmZvckVhY2goaXRlbSA9PiB7IGlmICghaXRlbS5zdGVwKVxuICAgICAgICAgICAgY291bnQrKzsgfSk7XG4gICAgICAgIHJldHVybiBjb3VudDtcbiAgICB9XG4gICAgLy8gQ29tcHJlc3NpbmcgYSBicmFuY2ggbWVhbnMgcmV3cml0aW5nIGl0IHRvIHB1c2ggdGhlIGFpciAobWFwLW9ubHlcbiAgICAvLyBpdGVtcykgb3V0LiBEdXJpbmcgY29sbGFib3JhdGlvbiwgdGhlc2UgbmF0dXJhbGx5IGFjY3VtdWxhdGVcbiAgICAvLyBiZWNhdXNlIGVhY2ggcmVtb3RlIGNoYW5nZSBhZGRzIG9uZS4gVGhlIGB1cHRvYCBhcmd1bWVudCBpcyB1c2VkXG4gICAgLy8gdG8gZW5zdXJlIHRoYXQgb25seSB0aGUgaXRlbXMgYmVsb3cgYSBnaXZlbiBsZXZlbCBhcmUgY29tcHJlc3NlZCxcbiAgICAvLyBiZWNhdXNlIGByZWJhc2VkYCByZWxpZXMgb24gYSBjbGVhbiwgdW50b3VjaGVkIHNldCBvZiBpdGVtcyBpblxuICAgIC8vIG9yZGVyIHRvIGFzc29jaWF0ZSBvbGQgaXRlbXMgd2l0aCByZWJhc2VkIHN0ZXBzLlxuICAgIGNvbXByZXNzKHVwdG8gPSB0aGlzLml0ZW1zLmxlbmd0aCkge1xuICAgICAgICBsZXQgcmVtYXAgPSB0aGlzLnJlbWFwcGluZygwLCB1cHRvKSwgbWFwRnJvbSA9IHJlbWFwLm1hcHMubGVuZ3RoO1xuICAgICAgICBsZXQgaXRlbXMgPSBbXSwgZXZlbnRzID0gMDtcbiAgICAgICAgdGhpcy5pdGVtcy5mb3JFYWNoKChpdGVtLCBpKSA9PiB7XG4gICAgICAgICAgICBpZiAoaSA+PSB1cHRvKSB7XG4gICAgICAgICAgICAgICAgaXRlbXMucHVzaChpdGVtKTtcbiAgICAgICAgICAgICAgICBpZiAoaXRlbS5zZWxlY3Rpb24pXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50cysrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXRlbS5zdGVwKSB7XG4gICAgICAgICAgICAgICAgbGV0IHN0ZXAgPSBpdGVtLnN0ZXAubWFwKHJlbWFwLnNsaWNlKG1hcEZyb20pKSwgbWFwID0gc3RlcCAmJiBzdGVwLmdldE1hcCgpO1xuICAgICAgICAgICAgICAgIG1hcEZyb20tLTtcbiAgICAgICAgICAgICAgICBpZiAobWFwKVxuICAgICAgICAgICAgICAgICAgICByZW1hcC5hcHBlbmRNYXAobWFwLCBtYXBGcm9tKTtcbiAgICAgICAgICAgICAgICBpZiAoc3RlcCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgc2VsZWN0aW9uID0gaXRlbS5zZWxlY3Rpb24gJiYgaXRlbS5zZWxlY3Rpb24ubWFwKHJlbWFwLnNsaWNlKG1hcEZyb20pKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvbilcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50cysrO1xuICAgICAgICAgICAgICAgICAgICBsZXQgbmV3SXRlbSA9IG5ldyBJdGVtKG1hcC5pbnZlcnQoKSwgc3RlcCwgc2VsZWN0aW9uKSwgbWVyZ2VkLCBsYXN0ID0gaXRlbXMubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1lcmdlZCA9IGl0ZW1zLmxlbmd0aCAmJiBpdGVtc1tsYXN0XS5tZXJnZShuZXdJdGVtKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zW2xhc3RdID0gbWVyZ2VkO1xuICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtcy5wdXNoKG5ld0l0ZW0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGl0ZW0ubWFwKSB7XG4gICAgICAgICAgICAgICAgbWFwRnJvbS0tO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCB0aGlzLml0ZW1zLmxlbmd0aCwgMCk7XG4gICAgICAgIHJldHVybiBuZXcgQnJhbmNoKFJvcGVTZXF1ZW5jZS5mcm9tKGl0ZW1zLnJldmVyc2UoKSksIGV2ZW50cyk7XG4gICAgfVxufVxuQnJhbmNoLmVtcHR5ID0gbmV3IEJyYW5jaChSb3BlU2VxdWVuY2UuZW1wdHksIDApO1xuZnVuY3Rpb24gY3V0T2ZmRXZlbnRzKGl0ZW1zLCBuKSB7XG4gICAgbGV0IGN1dFBvaW50O1xuICAgIGl0ZW1zLmZvckVhY2goKGl0ZW0sIGkpID0+IHtcbiAgICAgICAgaWYgKGl0ZW0uc2VsZWN0aW9uICYmIChuLS0gPT0gMCkpIHtcbiAgICAgICAgICAgIGN1dFBvaW50ID0gaTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBpdGVtcy5zbGljZShjdXRQb2ludCk7XG59XG5jbGFzcyBJdGVtIHtcbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvLyBUaGUgKGZvcndhcmQpIHN0ZXAgbWFwIGZvciB0aGlzIGl0ZW0uXG4gICAgbWFwLCBcbiAgICAvLyBUaGUgaW52ZXJ0ZWQgc3RlcFxuICAgIHN0ZXAsIFxuICAgIC8vIElmIHRoaXMgaXMgbm9uLW51bGwsIHRoaXMgaXRlbSBpcyB0aGUgc3RhcnQgb2YgYSBncm91cCwgYW5kXG4gICAgLy8gdGhpcyBzZWxlY3Rpb24gaXMgdGhlIHN0YXJ0aW5nIHNlbGVjdGlvbiBmb3IgdGhlIGdyb3VwICh0aGUgb25lXG4gICAgLy8gdGhhdCB3YXMgYWN0aXZlIGJlZm9yZSB0aGUgZmlyc3Qgc3RlcCB3YXMgYXBwbGllZClcbiAgICBzZWxlY3Rpb24sIFxuICAgIC8vIElmIHRoaXMgaXRlbSBpcyB0aGUgaW52ZXJzZSBvZiBhIHByZXZpb3VzIG1hcHBpbmcgb24gdGhlIHN0YWNrLFxuICAgIC8vIHRoaXMgcG9pbnRzIGF0IHRoZSBpbnZlcnNlJ3Mgb2Zmc2V0XG4gICAgbWlycm9yT2Zmc2V0KSB7XG4gICAgICAgIHRoaXMubWFwID0gbWFwO1xuICAgICAgICB0aGlzLnN0ZXAgPSBzdGVwO1xuICAgICAgICB0aGlzLnNlbGVjdGlvbiA9IHNlbGVjdGlvbjtcbiAgICAgICAgdGhpcy5taXJyb3JPZmZzZXQgPSBtaXJyb3JPZmZzZXQ7XG4gICAgfVxuICAgIG1lcmdlKG90aGVyKSB7XG4gICAgICAgIGlmICh0aGlzLnN0ZXAgJiYgb3RoZXIuc3RlcCAmJiAhb3RoZXIuc2VsZWN0aW9uKSB7XG4gICAgICAgICAgICBsZXQgc3RlcCA9IG90aGVyLnN0ZXAubWVyZ2UodGhpcy5zdGVwKTtcbiAgICAgICAgICAgIGlmIChzdGVwKVxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSXRlbShzdGVwLmdldE1hcCgpLmludmVydCgpLCBzdGVwLCB0aGlzLnNlbGVjdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyBUaGUgdmFsdWUgb2YgdGhlIHN0YXRlIGZpZWxkIHRoYXQgdHJhY2tzIHVuZG8vcmVkbyBoaXN0b3J5IGZvciB0aGF0XG4vLyBzdGF0ZS4gV2lsbCBiZSBzdG9yZWQgaW4gdGhlIHBsdWdpbiBzdGF0ZSB3aGVuIHRoZSBoaXN0b3J5IHBsdWdpblxuLy8gaXMgYWN0aXZlLlxuY2xhc3MgSGlzdG9yeVN0YXRlIHtcbiAgICBjb25zdHJ1Y3Rvcihkb25lLCB1bmRvbmUsIHByZXZSYW5nZXMsIHByZXZUaW1lLCBwcmV2Q29tcG9zaXRpb24pIHtcbiAgICAgICAgdGhpcy5kb25lID0gZG9uZTtcbiAgICAgICAgdGhpcy51bmRvbmUgPSB1bmRvbmU7XG4gICAgICAgIHRoaXMucHJldlJhbmdlcyA9IHByZXZSYW5nZXM7XG4gICAgICAgIHRoaXMucHJldlRpbWUgPSBwcmV2VGltZTtcbiAgICAgICAgdGhpcy5wcmV2Q29tcG9zaXRpb24gPSBwcmV2Q29tcG9zaXRpb247XG4gICAgfVxufVxuY29uc3QgREVQVEhfT1ZFUkZMT1cgPSAyMDtcbi8vIFJlY29yZCBhIHRyYW5zZm9ybWF0aW9uIGluIHVuZG8gaGlzdG9yeS5cbmZ1bmN0aW9uIGFwcGx5VHJhbnNhY3Rpb24oaGlzdG9yeSwgc3RhdGUsIHRyLCBvcHRpb25zKSB7XG4gICAgbGV0IGhpc3RvcnlUciA9IHRyLmdldE1ldGEoaGlzdG9yeUtleSksIHJlYmFzZWQ7XG4gICAgaWYgKGhpc3RvcnlUcilcbiAgICAgICAgcmV0dXJuIGhpc3RvcnlUci5oaXN0b3J5U3RhdGU7XG4gICAgaWYgKHRyLmdldE1ldGEoY2xvc2VIaXN0b3J5S2V5KSlcbiAgICAgICAgaGlzdG9yeSA9IG5ldyBIaXN0b3J5U3RhdGUoaGlzdG9yeS5kb25lLCBoaXN0b3J5LnVuZG9uZSwgbnVsbCwgMCwgLTEpO1xuICAgIGxldCBhcHBlbmRlZCA9IHRyLmdldE1ldGEoXCJhcHBlbmRlZFRyYW5zYWN0aW9uXCIpO1xuICAgIGlmICh0ci5zdGVwcy5sZW5ndGggPT0gMCkge1xuICAgICAgICByZXR1cm4gaGlzdG9yeTtcbiAgICB9XG4gICAgZWxzZSBpZiAoYXBwZW5kZWQgJiYgYXBwZW5kZWQuZ2V0TWV0YShoaXN0b3J5S2V5KSkge1xuICAgICAgICBpZiAoYXBwZW5kZWQuZ2V0TWV0YShoaXN0b3J5S2V5KS5yZWRvKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBIaXN0b3J5U3RhdGUoaGlzdG9yeS5kb25lLmFkZFRyYW5zZm9ybSh0ciwgdW5kZWZpbmVkLCBvcHRpb25zLCBtdXN0UHJlc2VydmVJdGVtcyhzdGF0ZSkpLCBoaXN0b3J5LnVuZG9uZSwgcmFuZ2VzRm9yKHRyLm1hcHBpbmcubWFwcyksIGhpc3RvcnkucHJldlRpbWUsIGhpc3RvcnkucHJldkNvbXBvc2l0aW9uKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBIaXN0b3J5U3RhdGUoaGlzdG9yeS5kb25lLCBoaXN0b3J5LnVuZG9uZS5hZGRUcmFuc2Zvcm0odHIsIHVuZGVmaW5lZCwgb3B0aW9ucywgbXVzdFByZXNlcnZlSXRlbXMoc3RhdGUpKSwgbnVsbCwgaGlzdG9yeS5wcmV2VGltZSwgaGlzdG9yeS5wcmV2Q29tcG9zaXRpb24pO1xuICAgIH1cbiAgICBlbHNlIGlmICh0ci5nZXRNZXRhKFwiYWRkVG9IaXN0b3J5XCIpICE9PSBmYWxzZSAmJiAhKGFwcGVuZGVkICYmIGFwcGVuZGVkLmdldE1ldGEoXCJhZGRUb0hpc3RvcnlcIikgPT09IGZhbHNlKSkge1xuICAgICAgICAvLyBHcm91cCB0cmFuc2Zvcm1zIHRoYXQgb2NjdXIgaW4gcXVpY2sgc3VjY2Vzc2lvbiBpbnRvIG9uZSBldmVudC5cbiAgICAgICAgbGV0IGNvbXBvc2l0aW9uID0gdHIuZ2V0TWV0YShcImNvbXBvc2l0aW9uXCIpO1xuICAgICAgICBsZXQgbmV3R3JvdXAgPSBoaXN0b3J5LnByZXZUaW1lID09IDAgfHxcbiAgICAgICAgICAgICghYXBwZW5kZWQgJiYgaGlzdG9yeS5wcmV2Q29tcG9zaXRpb24gIT0gY29tcG9zaXRpb24gJiZcbiAgICAgICAgICAgICAgICAoaGlzdG9yeS5wcmV2VGltZSA8ICh0ci50aW1lIHx8IDApIC0gb3B0aW9ucy5uZXdHcm91cERlbGF5IHx8ICFpc0FkamFjZW50VG8odHIsIGhpc3RvcnkucHJldlJhbmdlcykpKTtcbiAgICAgICAgbGV0IHByZXZSYW5nZXMgPSBhcHBlbmRlZCA/IG1hcFJhbmdlcyhoaXN0b3J5LnByZXZSYW5nZXMsIHRyLm1hcHBpbmcpIDogcmFuZ2VzRm9yKHRyLm1hcHBpbmcubWFwcyk7XG4gICAgICAgIHJldHVybiBuZXcgSGlzdG9yeVN0YXRlKGhpc3RvcnkuZG9uZS5hZGRUcmFuc2Zvcm0odHIsIG5ld0dyb3VwID8gc3RhdGUuc2VsZWN0aW9uLmdldEJvb2ttYXJrKCkgOiB1bmRlZmluZWQsIG9wdGlvbnMsIG11c3RQcmVzZXJ2ZUl0ZW1zKHN0YXRlKSksIEJyYW5jaC5lbXB0eSwgcHJldlJhbmdlcywgdHIudGltZSwgY29tcG9zaXRpb24gPT0gbnVsbCA/IGhpc3RvcnkucHJldkNvbXBvc2l0aW9uIDogY29tcG9zaXRpb24pO1xuICAgIH1cbiAgICBlbHNlIGlmIChyZWJhc2VkID0gdHIuZ2V0TWV0YShcInJlYmFzZWRcIikpIHtcbiAgICAgICAgLy8gVXNlZCBieSB0aGUgY29sbGFiIG1vZHVsZSB0byB0ZWxsIHRoZSBoaXN0b3J5IHRoYXQgc29tZSBvZiBpdHNcbiAgICAgICAgLy8gY29udGVudCBoYXMgYmVlbiByZWJhc2VkLlxuICAgICAgICByZXR1cm4gbmV3IEhpc3RvcnlTdGF0ZShoaXN0b3J5LmRvbmUucmViYXNlZCh0ciwgcmViYXNlZCksIGhpc3RvcnkudW5kb25lLnJlYmFzZWQodHIsIHJlYmFzZWQpLCBtYXBSYW5nZXMoaGlzdG9yeS5wcmV2UmFuZ2VzLCB0ci5tYXBwaW5nKSwgaGlzdG9yeS5wcmV2VGltZSwgaGlzdG9yeS5wcmV2Q29tcG9zaXRpb24pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG5ldyBIaXN0b3J5U3RhdGUoaGlzdG9yeS5kb25lLmFkZE1hcHModHIubWFwcGluZy5tYXBzKSwgaGlzdG9yeS51bmRvbmUuYWRkTWFwcyh0ci5tYXBwaW5nLm1hcHMpLCBtYXBSYW5nZXMoaGlzdG9yeS5wcmV2UmFuZ2VzLCB0ci5tYXBwaW5nKSwgaGlzdG9yeS5wcmV2VGltZSwgaGlzdG9yeS5wcmV2Q29tcG9zaXRpb24pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGlzQWRqYWNlbnRUbyh0cmFuc2Zvcm0sIHByZXZSYW5nZXMpIHtcbiAgICBpZiAoIXByZXZSYW5nZXMpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBpZiAoIXRyYW5zZm9ybS5kb2NDaGFuZ2VkKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICBsZXQgYWRqYWNlbnQgPSBmYWxzZTtcbiAgICB0cmFuc2Zvcm0ubWFwcGluZy5tYXBzWzBdLmZvckVhY2goKHN0YXJ0LCBlbmQpID0+IHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcmV2UmFuZ2VzLmxlbmd0aDsgaSArPSAyKVxuICAgICAgICAgICAgaWYgKHN0YXJ0IDw9IHByZXZSYW5nZXNbaSArIDFdICYmIGVuZCA+PSBwcmV2UmFuZ2VzW2ldKVxuICAgICAgICAgICAgICAgIGFkamFjZW50ID0gdHJ1ZTtcbiAgICB9KTtcbiAgICByZXR1cm4gYWRqYWNlbnQ7XG59XG5mdW5jdGlvbiByYW5nZXNGb3IobWFwcykge1xuICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gbWFwcy5sZW5ndGggLSAxOyBpID49IDAgJiYgcmVzdWx0Lmxlbmd0aCA9PSAwOyBpLS0pXG4gICAgICAgIG1hcHNbaV0uZm9yRWFjaCgoX2Zyb20sIF90bywgZnJvbSwgdG8pID0+IHJlc3VsdC5wdXNoKGZyb20sIHRvKSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIG1hcFJhbmdlcyhyYW5nZXMsIG1hcHBpbmcpIHtcbiAgICBpZiAoIXJhbmdlcylcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgIGxldCBmcm9tID0gbWFwcGluZy5tYXAocmFuZ2VzW2ldLCAxKSwgdG8gPSBtYXBwaW5nLm1hcChyYW5nZXNbaSArIDFdLCAtMSk7XG4gICAgICAgIGlmIChmcm9tIDw9IHRvKVxuICAgICAgICAgICAgcmVzdWx0LnB1c2goZnJvbSwgdG8pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLy8gQXBwbHkgdGhlIGxhdGVzdCBldmVudCBmcm9tIG9uZSBicmFuY2ggdG8gdGhlIGRvY3VtZW50IGFuZCBzaGlmdCB0aGUgZXZlbnRcbi8vIG9udG8gdGhlIG90aGVyIGJyYW5jaC5cbmZ1bmN0aW9uIGhpc3RUcmFuc2FjdGlvbihoaXN0b3J5LCBzdGF0ZSwgcmVkbykge1xuICAgIGxldCBwcmVzZXJ2ZUl0ZW1zID0gbXVzdFByZXNlcnZlSXRlbXMoc3RhdGUpO1xuICAgIGxldCBoaXN0T3B0aW9ucyA9IGhpc3RvcnlLZXkuZ2V0KHN0YXRlKS5zcGVjLmNvbmZpZztcbiAgICBsZXQgcG9wID0gKHJlZG8gPyBoaXN0b3J5LnVuZG9uZSA6IGhpc3RvcnkuZG9uZSkucG9wRXZlbnQoc3RhdGUsIHByZXNlcnZlSXRlbXMpO1xuICAgIGlmICghcG9wKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBsZXQgc2VsZWN0aW9uID0gcG9wLnNlbGVjdGlvbi5yZXNvbHZlKHBvcC50cmFuc2Zvcm0uZG9jKTtcbiAgICBsZXQgYWRkZWQgPSAocmVkbyA/IGhpc3RvcnkuZG9uZSA6IGhpc3RvcnkudW5kb25lKS5hZGRUcmFuc2Zvcm0ocG9wLnRyYW5zZm9ybSwgc3RhdGUuc2VsZWN0aW9uLmdldEJvb2ttYXJrKCksIGhpc3RPcHRpb25zLCBwcmVzZXJ2ZUl0ZW1zKTtcbiAgICBsZXQgbmV3SGlzdCA9IG5ldyBIaXN0b3J5U3RhdGUocmVkbyA/IGFkZGVkIDogcG9wLnJlbWFpbmluZywgcmVkbyA/IHBvcC5yZW1haW5pbmcgOiBhZGRlZCwgbnVsbCwgMCwgLTEpO1xuICAgIHJldHVybiBwb3AudHJhbnNmb3JtLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pLnNldE1ldGEoaGlzdG9yeUtleSwgeyByZWRvLCBoaXN0b3J5U3RhdGU6IG5ld0hpc3QgfSk7XG59XG5sZXQgY2FjaGVkUHJlc2VydmVJdGVtcyA9IGZhbHNlLCBjYWNoZWRQcmVzZXJ2ZUl0ZW1zUGx1Z2lucyA9IG51bGw7XG4vLyBDaGVjayB3aGV0aGVyIGFueSBwbHVnaW4gaW4gdGhlIGdpdmVuIHN0YXRlIGhhcyBhXG4vLyBgaGlzdG9yeVByZXNlcnZlSXRlbXNgIHByb3BlcnR5IGluIGl0cyBzcGVjLCBpbiB3aGljaCBjYXNlIHdlIG11c3Rcbi8vIHByZXNlcnZlIHN0ZXBzIGV4YWN0bHkgYXMgdGhleSBjYW1lIGluLCBzbyB0aGF0IHRoZXkgY2FuIGJlXG4vLyByZWJhc2VkLlxuZnVuY3Rpb24gbXVzdFByZXNlcnZlSXRlbXMoc3RhdGUpIHtcbiAgICBsZXQgcGx1Z2lucyA9IHN0YXRlLnBsdWdpbnM7XG4gICAgaWYgKGNhY2hlZFByZXNlcnZlSXRlbXNQbHVnaW5zICE9IHBsdWdpbnMpIHtcbiAgICAgICAgY2FjaGVkUHJlc2VydmVJdGVtcyA9IGZhbHNlO1xuICAgICAgICBjYWNoZWRQcmVzZXJ2ZUl0ZW1zUGx1Z2lucyA9IHBsdWdpbnM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGx1Z2lucy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmIChwbHVnaW5zW2ldLnNwZWMuaGlzdG9yeVByZXNlcnZlSXRlbXMpIHtcbiAgICAgICAgICAgICAgICBjYWNoZWRQcmVzZXJ2ZUl0ZW1zID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNhY2hlZFByZXNlcnZlSXRlbXM7XG59XG4vKipcblNldCBhIGZsYWcgb24gdGhlIGdpdmVuIHRyYW5zYWN0aW9uIHRoYXQgd2lsbCBwcmV2ZW50IGZ1cnRoZXIgc3RlcHNcbmZyb20gYmVpbmcgYXBwZW5kZWQgdG8gYW4gZXhpc3RpbmcgaGlzdG9yeSBldmVudCAoc28gdGhhdCB0aGV5XG5yZXF1aXJlIGEgc2VwYXJhdGUgdW5kbyBjb21tYW5kIHRvIHVuZG8pLlxuKi9cbmZ1bmN0aW9uIGNsb3NlSGlzdG9yeSh0cikge1xuICAgIHJldHVybiB0ci5zZXRNZXRhKGNsb3NlSGlzdG9yeUtleSwgdHJ1ZSk7XG59XG5jb25zdCBoaXN0b3J5S2V5ID0gbmV3IFBsdWdpbktleShcImhpc3RvcnlcIik7XG5jb25zdCBjbG9zZUhpc3RvcnlLZXkgPSBuZXcgUGx1Z2luS2V5KFwiY2xvc2VIaXN0b3J5XCIpO1xuLyoqXG5SZXR1cm5zIGEgcGx1Z2luIHRoYXQgZW5hYmxlcyB0aGUgdW5kbyBoaXN0b3J5IGZvciBhbiBlZGl0b3IuIFRoZVxucGx1Z2luIHdpbGwgdHJhY2sgdW5kbyBhbmQgcmVkbyBzdGFja3MsIHdoaWNoIGNhbiBiZSB1c2VkIHdpdGggdGhlXG5bYHVuZG9gXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jaGlzdG9yeS51bmRvKSBhbmQgW2ByZWRvYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI2hpc3RvcnkucmVkbykgY29tbWFuZHMuXG5cbllvdSBjYW4gc2V0IGFuIGBcImFkZFRvSGlzdG9yeVwiYCBbbWV0YWRhdGFcbnByb3BlcnR5XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuVHJhbnNhY3Rpb24uc2V0TWV0YSkgb2YgYGZhbHNlYCBvbiBhIHRyYW5zYWN0aW9uXG50byBwcmV2ZW50IGl0IGZyb20gYmVpbmcgcm9sbGVkIGJhY2sgYnkgdW5kby5cbiovXG5mdW5jdGlvbiBoaXN0b3J5KGNvbmZpZyA9IHt9KSB7XG4gICAgY29uZmlnID0geyBkZXB0aDogY29uZmlnLmRlcHRoIHx8IDEwMCxcbiAgICAgICAgbmV3R3JvdXBEZWxheTogY29uZmlnLm5ld0dyb3VwRGVsYXkgfHwgNTAwIH07XG4gICAgcmV0dXJuIG5ldyBQbHVnaW4oe1xuICAgICAgICBrZXk6IGhpc3RvcnlLZXksXG4gICAgICAgIHN0YXRlOiB7XG4gICAgICAgICAgICBpbml0KCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSGlzdG9yeVN0YXRlKEJyYW5jaC5lbXB0eSwgQnJhbmNoLmVtcHR5LCBudWxsLCAwLCAtMSk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYXBwbHkodHIsIGhpc3QsIHN0YXRlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFwcGx5VHJhbnNhY3Rpb24oaGlzdCwgc3RhdGUsIHRyLCBjb25maWcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgICBoYW5kbGVET01FdmVudHM6IHtcbiAgICAgICAgICAgICAgICBiZWZvcmVpbnB1dCh2aWV3LCBlKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBpbnB1dFR5cGUgPSBlLmlucHV0VHlwZTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbW1hbmQgPSBpbnB1dFR5cGUgPT0gXCJoaXN0b3J5VW5kb1wiID8gdW5kbyA6IGlucHV0VHlwZSA9PSBcImhpc3RvcnlSZWRvXCIgPyByZWRvIDogbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFjb21tYW5kIHx8ICF2aWV3LmVkaXRhYmxlKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjb21tYW5kKHZpZXcuc3RhdGUsIHZpZXcuZGlzcGF0Y2gpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gYnVpbGRDb21tYW5kKHJlZG8sIHNjcm9sbCkge1xuICAgIHJldHVybiAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgICAgIGxldCBoaXN0ID0gaGlzdG9yeUtleS5nZXRTdGF0ZShzdGF0ZSk7XG4gICAgICAgIGlmICghaGlzdCB8fCAocmVkbyA/IGhpc3QudW5kb25lIDogaGlzdC5kb25lKS5ldmVudENvdW50ID09IDApXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgICAgbGV0IHRyID0gaGlzdFRyYW5zYWN0aW9uKGhpc3QsIHN0YXRlLCByZWRvKTtcbiAgICAgICAgICAgIGlmICh0cilcbiAgICAgICAgICAgICAgICBkaXNwYXRjaChzY3JvbGwgPyB0ci5zY3JvbGxJbnRvVmlldygpIDogdHIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG59XG4vKipcbkEgY29tbWFuZCBmdW5jdGlvbiB0aGF0IHVuZG9lcyB0aGUgbGFzdCBjaGFuZ2UsIGlmIGFueS5cbiovXG5jb25zdCB1bmRvID0gYnVpbGRDb21tYW5kKGZhbHNlLCB0cnVlKTtcbi8qKlxuQSBjb21tYW5kIGZ1bmN0aW9uIHRoYXQgcmVkb2VzIHRoZSBsYXN0IHVuZG9uZSBjaGFuZ2UsIGlmIGFueS5cbiovXG5jb25zdCByZWRvID0gYnVpbGRDb21tYW5kKHRydWUsIHRydWUpO1xuLyoqXG5BIGNvbW1hbmQgZnVuY3Rpb24gdGhhdCB1bmRvZXMgdGhlIGxhc3QgY2hhbmdlLiBEb24ndCBzY3JvbGwgdGhlXG5zZWxlY3Rpb24gaW50byB2aWV3LlxuKi9cbmNvbnN0IHVuZG9Ob1Njcm9sbCA9IGJ1aWxkQ29tbWFuZChmYWxzZSwgZmFsc2UpO1xuLyoqXG5BIGNvbW1hbmQgZnVuY3Rpb24gdGhhdCByZWRvZXMgdGhlIGxhc3QgdW5kb25lIGNoYW5nZS4gRG9uJ3RcbnNjcm9sbCB0aGUgc2VsZWN0aW9uIGludG8gdmlldy5cbiovXG5jb25zdCByZWRvTm9TY3JvbGwgPSBidWlsZENvbW1hbmQodHJ1ZSwgZmFsc2UpO1xuLyoqXG5UaGUgYW1vdW50IG9mIHVuZG9hYmxlIGV2ZW50cyBhdmFpbGFibGUgaW4gYSBnaXZlbiBzdGF0ZS5cbiovXG5mdW5jdGlvbiB1bmRvRGVwdGgoc3RhdGUpIHtcbiAgICBsZXQgaGlzdCA9IGhpc3RvcnlLZXkuZ2V0U3RhdGUoc3RhdGUpO1xuICAgIHJldHVybiBoaXN0ID8gaGlzdC5kb25lLmV2ZW50Q291bnQgOiAwO1xufVxuLyoqXG5UaGUgYW1vdW50IG9mIHJlZG9hYmxlIGV2ZW50cyBhdmFpbGFibGUgaW4gYSBnaXZlbiBlZGl0b3Igc3RhdGUuXG4qL1xuZnVuY3Rpb24gcmVkb0RlcHRoKHN0YXRlKSB7XG4gICAgbGV0IGhpc3QgPSBoaXN0b3J5S2V5LmdldFN0YXRlKHN0YXRlKTtcbiAgICByZXR1cm4gaGlzdCA/IGhpc3QudW5kb25lLmV2ZW50Q291bnQgOiAwO1xufVxuLyoqXG5SZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIHRyYW5zYWN0aW9uIHdhcyBnZW5lcmF0ZWQgYnkgdGhlIGhpc3RvcnlcbnBsdWdpbi5cbiovXG5mdW5jdGlvbiBpc0hpc3RvcnlUcmFuc2FjdGlvbih0cikge1xuICAgIHJldHVybiB0ci5nZXRNZXRhKGhpc3RvcnlLZXkpICE9IG51bGw7XG59XG5cbmV4cG9ydCB7IGNsb3NlSGlzdG9yeSwgaGlzdG9yeSwgaXNIaXN0b3J5VHJhbnNhY3Rpb24sIHJlZG8sIHJlZG9EZXB0aCwgcmVkb05vU2Nyb2xsLCB1bmRvLCB1bmRvRGVwdGgsIHVuZG9Ob1Njcm9sbCB9O1xuIiwgImltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB0eXBlIHsgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIENoYXJhY3RlckNvdW50T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0aGF0IHNob3VsZCBiZSBhbGxvd2VkLiBEZWZhdWx0cyB0byBgMGAuXG4gICAqIEBkZWZhdWx0IG51bGxcbiAgICogQGV4YW1wbGUgMTgwXG4gICAqL1xuICBsaW1pdDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZFxuICAvKipcbiAgICogVGhlIG1vZGUgYnkgd2hpY2ggdGhlIHNpemUgaXMgY2FsY3VsYXRlZC4gSWYgc2V0IHRvIGB0ZXh0U2l6ZWAsIHRoZSB0ZXh0Q29udGVudCBvZiB0aGUgZG9jdW1lbnQgaXMgdXNlZC5cbiAgICogSWYgc2V0IHRvIGBub2RlU2l6ZWAsIHRoZSBub2RlU2l6ZSBvZiB0aGUgZG9jdW1lbnQgaXMgdXNlZC5cbiAgICogQGRlZmF1bHQgJ3RleHRTaXplJ1xuICAgKiBAZXhhbXBsZSAndGV4dFNpemUnXG4gICAqL1xuICBtb2RlOiAndGV4dFNpemUnIHwgJ25vZGVTaXplJ1xuICAvKipcbiAgICogU2V0cyB3aGV0aGVyIHRoZSBjb250ZW50IHdpbGwgYmUgYXV0b21hdGljYWxseSB0cmltbWVkIHdoZW4gcHJvZ3JhbWF0aWNhbGx5IHNldHRpbmcgY29udGVudCBvdmVyIHRoZSBsaW1pdC5cbiAgICogSWYgc2V0IHRvIGZhbHNlLCB0aGUgdXNlciB3aWxsIGJlIGFibGUgdG8gdHJpbSB0aGUgdGV4dCBtYW51YWxseS5cbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKiBAZXhhbXBsZSBmYWxzZVxuICAgKi9cbiAgYXV0b1RyaW0/OiBib29sZWFuXG4gIC8qKlxuICAgKiBUaGUgdGV4dCBjb3VudGVyIGZ1bmN0aW9uIHRvIHVzZS4gRGVmYXVsdHMgdG8gYSBzaW1wbGUgY2hhcmFjdGVyIGNvdW50LlxuICAgKiBAZGVmYXVsdCAodGV4dCkgPT4gdGV4dC5sZW5ndGhcbiAgICogQGV4YW1wbGUgKHRleHQpID0+IFsuLi5uZXcgSW50bC5TZWdtZW50ZXIoKS5zZWdtZW50KHRleHQpXS5sZW5ndGhcbiAgICovXG4gIHRleHRDb3VudGVyOiAodGV4dDogc3RyaW5nKSA9PiBudW1iZXJcbiAgLyoqXG4gICAqIFRoZSB3b3JkIGNvdW50ZXIgZnVuY3Rpb24gdG8gdXNlLiBEZWZhdWx0cyB0byBhIHNpbXBsZSB3b3JkIGNvdW50LlxuICAgKiBAZGVmYXVsdCAodGV4dCkgPT4gdGV4dC5zcGxpdCgnICcpLmZpbHRlcih3b3JkID0+IHdvcmQgIT09ICcnKS5sZW5ndGhcbiAgICogQGV4YW1wbGUgKHRleHQpID0+IHRleHQuc3BsaXQoL1xccysvKS5maWx0ZXIod29yZCA9PiB3b3JkICE9PSAnJykubGVuZ3RoXG4gICAqL1xuICB3b3JkQ291bnRlcjogKHRleHQ6IHN0cmluZykgPT4gbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hhcmFjdGVyQ291bnRTdG9yYWdlIHtcbiAgLyoqXG4gICAqIEdldCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50LlxuICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgdGhlIGNoYXJhY3RlciBjb3VudC4gKG9wdGlvbmFsKVxuICAgKiBAcGFyYW0gb3B0aW9ucy5ub2RlIFRoZSBub2RlIHRvIGdldCB0aGUgY2hhcmFjdGVycyBmcm9tLiBEZWZhdWx0cyB0byB0aGUgY3VycmVudCBkb2N1bWVudC5cbiAgICogQHBhcmFtIG9wdGlvbnMubW9kZSBUaGUgbW9kZSBieSB3aGljaCB0aGUgc2l6ZSBpcyBjYWxjdWxhdGVkLiBJZiBzZXQgdG8gYHRleHRTaXplYCwgdGhlIHRleHRDb250ZW50IG9mIHRoZSBkb2N1bWVudCBpcyB1c2VkLlxuICAgKi9cbiAgY2hhcmFjdGVyczogKG9wdGlvbnM/OiB7IG5vZGU/OiBQcm9zZU1pcnJvck5vZGU7IG1vZGU/OiAndGV4dFNpemUnIHwgJ25vZGVTaXplJyB9KSA9PiBudW1iZXJcblxuICAvKipcbiAgICogR2V0IHRoZSBudW1iZXIgb2Ygd29yZHMgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50LlxuICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgb3B0aW9ucyBmb3IgdGhlIGNoYXJhY3RlciBjb3VudC4gKG9wdGlvbmFsKVxuICAgKiBAcGFyYW0gb3B0aW9ucy5ub2RlIFRoZSBub2RlIHRvIGdldCB0aGUgd29yZHMgZnJvbS4gRGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgZG9jdW1lbnQuXG4gICAqL1xuICB3b3JkczogKG9wdGlvbnM/OiB7IG5vZGU/OiBQcm9zZU1pcnJvck5vZGUgfSkgPT4gbnVtYmVyXG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIFN0b3JhZ2Uge1xuICAgIGNoYXJhY3RlckNvdW50OiBDaGFyYWN0ZXJDb3VudFN0b3JhZ2VcbiAgfVxufVxuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gY291bnQgdGhlIGNoYXJhY3RlcnMgYW5kIHdvcmRzIG9mIHlvdXIgZG9jdW1lbnQuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9hcGkvZXh0ZW5zaW9ucy9jaGFyYWN0ZXItY291bnRcbiAqL1xuZXhwb3J0IGNvbnN0IENoYXJhY3RlckNvdW50ID0gRXh0ZW5zaW9uLmNyZWF0ZTxDaGFyYWN0ZXJDb3VudE9wdGlvbnMsIENoYXJhY3RlckNvdW50U3RvcmFnZT4oe1xuICBuYW1lOiAnY2hhcmFjdGVyQ291bnQnLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxpbWl0OiBudWxsLFxuICAgICAgYXV0b1RyaW06IHRydWUsXG4gICAgICBtb2RlOiAndGV4dFNpemUnLFxuICAgICAgdGV4dENvdW50ZXI6IHRleHQgPT4gdGV4dC5sZW5ndGgsXG4gICAgICB3b3JkQ291bnRlcjogdGV4dCA9PiB0ZXh0LnNwbGl0KCcgJykuZmlsdGVyKHdvcmQgPT4gd29yZCAhPT0gJycpLmxlbmd0aCxcbiAgICB9XG4gIH0sXG5cbiAgYWRkU3RvcmFnZSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY2hhcmFjdGVyczogKCkgPT4gMCxcbiAgICAgIHdvcmRzOiAoKSA9PiAwLFxuICAgIH1cbiAgfSxcblxuICBvbkJlZm9yZUNyZWF0ZSgpIHtcbiAgICB0aGlzLnN0b3JhZ2UuY2hhcmFjdGVycyA9IG9wdGlvbnMgPT4ge1xuICAgICAgY29uc3Qgbm9kZSA9IG9wdGlvbnM/Lm5vZGUgfHwgdGhpcy5lZGl0b3Iuc3RhdGUuZG9jXG4gICAgICBjb25zdCBtb2RlID0gb3B0aW9ucz8ubW9kZSB8fCB0aGlzLm9wdGlvbnMubW9kZVxuXG4gICAgICBpZiAobW9kZSA9PT0gJ3RleHRTaXplJykge1xuICAgICAgICBjb25zdCB0ZXh0ID0gbm9kZS50ZXh0QmV0d2VlbigwLCBub2RlLmNvbnRlbnQuc2l6ZSwgdW5kZWZpbmVkLCAnICcpXG5cbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy50ZXh0Q291bnRlcih0ZXh0KVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbm9kZS5ub2RlU2l6ZVxuICAgIH1cblxuICAgIHRoaXMuc3RvcmFnZS53b3JkcyA9IG9wdGlvbnMgPT4ge1xuICAgICAgY29uc3Qgbm9kZSA9IG9wdGlvbnM/Lm5vZGUgfHwgdGhpcy5lZGl0b3Iuc3RhdGUuZG9jXG4gICAgICBjb25zdCB0ZXh0ID0gbm9kZS50ZXh0QmV0d2VlbigwLCBub2RlLmNvbnRlbnQuc2l6ZSwgJyAnLCAnICcpXG5cbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMud29yZENvdW50ZXIodGV4dClcbiAgICB9XG4gIH0sXG5cbiAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuICAgIGxldCBpbml0aWFsRXZhbHVhdGlvbkRvbmUgPSBmYWxzZVxuXG4gICAgcmV0dXJuIFtcbiAgICAgIG5ldyBQbHVnaW4oe1xuICAgICAgICBrZXk6IG5ldyBQbHVnaW5LZXkoJ2NoYXJhY3RlckNvdW50JyksXG4gICAgICAgIGFwcGVuZFRyYW5zYWN0aW9uOiAodHJhbnNhY3Rpb25zLCBvbGRTdGF0ZSwgbmV3U3RhdGUpID0+IHtcbiAgICAgICAgICBpZiAoaW5pdGlhbEV2YWx1YXRpb25Eb25lKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBsaW1pdCA9IHRoaXMub3B0aW9ucy5saW1pdFxuICAgICAgICAgIGNvbnN0IGF1dG9UcmltID0gdGhpcy5vcHRpb25zLmF1dG9UcmltXG5cbiAgICAgICAgICBpZiAobGltaXQgPT09IG51bGwgfHwgbGltaXQgPT09IHVuZGVmaW5lZCB8fCBsaW1pdCA9PT0gMCB8fCBhdXRvVHJpbSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGluaXRpYWxFdmFsdWF0aW9uRG9uZSA9IHRydWVcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGluaXRpYWxDb250ZW50U2l6ZSA9IHRoaXMuc3RvcmFnZS5jaGFyYWN0ZXJzKHsgbm9kZTogbmV3U3RhdGUuZG9jIH0pXG5cbiAgICAgICAgICBpZiAoaW5pdGlhbENvbnRlbnRTaXplID4gbGltaXQpIHtcbiAgICAgICAgICAgIGNvbnN0IG92ZXIgPSBpbml0aWFsQ29udGVudFNpemUgLSBsaW1pdFxuICAgICAgICAgICAgY29uc3QgZnJvbSA9IDBcbiAgICAgICAgICAgIGNvbnN0IHRvID0gb3ZlclxuXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgIGBbQ2hhcmFjdGVyQ291bnRdIEluaXRpYWwgY29udGVudCBleGNlZWRlZCBsaW1pdCBvZiAke2xpbWl0fSBjaGFyYWN0ZXJzLiBDb250ZW50IHdhcyBhdXRvbWF0aWNhbGx5IHRyaW1tZWQuYCxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIGNvbnN0IHRyID0gbmV3U3RhdGUudHIuZGVsZXRlUmFuZ2UoZnJvbSwgdG8pXG4gICAgICAgICAgICBpbml0aWFsRXZhbHVhdGlvbkRvbmUgPSB0cnVlXG4gICAgICAgICAgICByZXR1cm4gdHJcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpbml0aWFsRXZhbHVhdGlvbkRvbmUgPSB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIGZpbHRlclRyYW5zYWN0aW9uOiAodHJhbnNhY3Rpb24sIHN0YXRlKSA9PiB7XG4gICAgICAgICAgY29uc3QgbGltaXQgPSB0aGlzLm9wdGlvbnMubGltaXRcblxuICAgICAgICAgIC8vIE5vdGhpbmcgaGFzIGNoYW5nZWQgb3Igbm8gbGltaXQgaXMgZGVmaW5lZC4gSWdub3JlIGl0LlxuICAgICAgICAgIGlmICghdHJhbnNhY3Rpb24uZG9jQ2hhbmdlZCB8fCBsaW1pdCA9PT0gMCB8fCBsaW1pdCA9PT0gbnVsbCB8fCBsaW1pdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IG9sZFNpemUgPSB0aGlzLnN0b3JhZ2UuY2hhcmFjdGVycyh7IG5vZGU6IHN0YXRlLmRvYyB9KVxuICAgICAgICAgIGNvbnN0IG5ld1NpemUgPSB0aGlzLnN0b3JhZ2UuY2hhcmFjdGVycyh7IG5vZGU6IHRyYW5zYWN0aW9uLmRvYyB9KVxuXG4gICAgICAgICAgLy8gRXZlcnl0aGluZyBpcyBpbiB0aGUgbGltaXQuIEdvb2QuXG4gICAgICAgICAgaWYgKG5ld1NpemUgPD0gbGltaXQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gVGhlIGxpbWl0IGhhcyBhbHJlYWR5IGJlZW4gZXhjZWVkZWQgYnV0IHdpbGwgYmUgcmVkdWNlZC5cbiAgICAgICAgICBpZiAob2xkU2l6ZSA+IGxpbWl0ICYmIG5ld1NpemUgPiBsaW1pdCAmJiBuZXdTaXplIDw9IG9sZFNpemUpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gVGhlIGxpbWl0IGhhcyBhbHJlYWR5IGJlZW4gZXhjZWVkZWQgYW5kIHdpbGwgYmUgaW5jcmVhc2VkIGZ1cnRoZXIuXG4gICAgICAgICAgaWYgKG9sZFNpemUgPiBsaW1pdCAmJiBuZXdTaXplID4gbGltaXQgJiYgbmV3U2l6ZSA+IG9sZFNpemUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGlzUGFzdGUgPSB0cmFuc2FjdGlvbi5nZXRNZXRhKCdwYXN0ZScpXG5cbiAgICAgICAgICAvLyBCbG9jayBhbGwgZXhjZWVkaW5nIHRyYW5zYWN0aW9ucyB0aGF0IHdlcmUgbm90IHBhc3RlZC5cbiAgICAgICAgICBpZiAoIWlzUGFzdGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEZvciBwYXN0ZWQgY29udGVudCwgd2UgdHJ5IHRvIHJlbW92ZSB0aGUgZXhjZWVkaW5nIGNvbnRlbnQuXG4gICAgICAgICAgY29uc3QgcG9zID0gdHJhbnNhY3Rpb24uc2VsZWN0aW9uLiRoZWFkLnBvc1xuICAgICAgICAgIGNvbnN0IG92ZXIgPSBuZXdTaXplIC0gbGltaXRcbiAgICAgICAgICBjb25zdCBmcm9tID0gcG9zIC0gb3ZlclxuICAgICAgICAgIGNvbnN0IHRvID0gcG9zXG5cbiAgICAgICAgICAvLyBJdOKAmXMgcHJvYmFibHkgYSBiYWQgaWRlYSB0byBtdXRhdGUgdHJhbnNhY3Rpb25zIHdpdGhpbiBgZmlsdGVyVHJhbnNhY3Rpb25gXG4gICAgICAgICAgLy8gYnV0IGZvciBub3cgdGhpcyBpcyB3b3JraW5nIGZpbmUuXG4gICAgICAgICAgdHJhbnNhY3Rpb24uZGVsZXRlUmFuZ2UoZnJvbSwgdG8pXG5cbiAgICAgICAgICAvLyBJbiBzb21lIHNpdHVhdGlvbnMsIHRoZSBsaW1pdCB3aWxsIGNvbnRpbnVlIHRvIGJlIGV4Y2VlZGVkIGFmdGVyIHRyaW1taW5nLlxuICAgICAgICAgIC8vIFRoaXMgaGFwcGVucyBlLmcuIHdoZW4gdHJ1bmNhdGluZyB3aXRoaW4gYSBjb21wbGV4IG5vZGUgKGUuZy4gdGFibGUpXG4gICAgICAgICAgLy8gYW5kIFByb3NlTWlycm9yIGhhcyB0byBjbG9zZSB0aGlzIG5vZGUgYWdhaW4uXG4gICAgICAgICAgLy8gSWYgdGhpcyBpcyB0aGUgY2FzZSwgd2UgcHJldmVudCB0aGUgdHJhbnNhY3Rpb24gY29tcGxldGVseS5cbiAgICAgICAgICBjb25zdCB1cGRhdGVkU2l6ZSA9IHRoaXMuc3RvcmFnZS5jaGFyYWN0ZXJzKHsgbm9kZTogdHJhbnNhY3Rpb24uZG9jIH0pXG5cbiAgICAgICAgICBpZiAodXBkYXRlZFNpemUgPiBsaW1pdCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgRXh0ZW5zaW9uIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHsgZHJvcEN1cnNvciB9IGZyb20gJ0B0aXB0YXAvcG0vZHJvcGN1cnNvcidcblxuZXhwb3J0IGludGVyZmFjZSBEcm9wY3Vyc29yT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgY29sb3Igb2YgdGhlIGRyb3AgY3Vyc29yLiBVc2UgYGZhbHNlYCB0byBhcHBseSBubyBjb2xvciBhbmQgcmVseSBvbmx5IG9uIGNsYXNzLlxuICAgKiBAZGVmYXVsdCAnY3VycmVudENvbG9yJ1xuICAgKiBAZXhhbXBsZSAncmVkJ1xuICAgKi9cbiAgY29sb3I/OiBzdHJpbmcgfCBmYWxzZVxuXG4gIC8qKlxuICAgKiBUaGUgd2lkdGggb2YgdGhlIGRyb3AgY3Vyc29yXG4gICAqIEBkZWZhdWx0IDFcbiAgICogQGV4YW1wbGUgMlxuICAgKi9cbiAgd2lkdGg6IG51bWJlciB8IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBUaGUgY2xhc3Mgb2YgdGhlIGRyb3AgY3Vyc29yXG4gICAqIEBkZWZhdWx0IHVuZGVmaW5lZFxuICAgKiBAZXhhbXBsZSAnZHJvcC1jdXJzb3InXG4gICAqL1xuICBjbGFzczogc3RyaW5nIHwgdW5kZWZpbmVkXG59XG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBhZGQgYSBkcm9wIGN1cnNvciB0byB5b3VyIGVkaXRvci5cbiAqIEEgZHJvcCBjdXJzb3IgaXMgYSBsaW5lIHRoYXQgYXBwZWFycyB3aGVuIHlvdSBkcmFnIGFuZCBkcm9wIGNvbnRlbnRcbiAqIGluLWJldHdlZW4gbm9kZXMuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9hcGkvZXh0ZW5zaW9ucy9kcm9wY3Vyc29yXG4gKi9cbmV4cG9ydCBjb25zdCBEcm9wY3Vyc29yID0gRXh0ZW5zaW9uLmNyZWF0ZTxEcm9wY3Vyc29yT3B0aW9ucz4oe1xuICBuYW1lOiAnZHJvcEN1cnNvcicsXG5cbiAgYWRkT3B0aW9ucygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29sb3I6ICdjdXJyZW50Q29sb3InLFxuICAgICAgd2lkdGg6IDEsXG4gICAgICBjbGFzczogdW5kZWZpbmVkLFxuICAgIH1cbiAgfSxcblxuICBhZGRQcm9zZU1pcnJvclBsdWdpbnMoKSB7XG4gICAgcmV0dXJuIFtkcm9wQ3Vyc29yKHRoaXMub3B0aW9ucyldXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB7IFBsdWdpbiwgUGx1Z2luS2V5IH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcbmltcG9ydCB7IERlY29yYXRpb24sIERlY29yYXRpb25TZXQgfSBmcm9tICdAdGlwdGFwL3BtL3ZpZXcnXG5cbmV4cG9ydCBpbnRlcmZhY2UgRm9jdXNPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBjbGFzcyBuYW1lIHRoYXQgc2hvdWxkIGJlIGFkZGVkIHRvIHRoZSBmb2N1c2VkIG5vZGUuXG4gICAqIEBkZWZhdWx0ICdoYXMtZm9jdXMnXG4gICAqIEBleGFtcGxlICdpcy1mb2N1c2VkJ1xuICAgKi9cbiAgY2xhc3NOYW1lOiBzdHJpbmdcblxuICAvKipcbiAgICogVGhlIG1vZGUgYnkgd2hpY2ggdGhlIGZvY3VzZWQgbm9kZSBpcyBkZXRlcm1pbmVkLlxuICAgKiAtIEFsbDogQWxsIG5vZGVzIGFyZSBtYXJrZWQgYXMgZm9jdXNlZC5cbiAgICogLSBEZWVwZXN0OiBPbmx5IHRoZSBkZWVwZXN0IG5vZGUgaXMgbWFya2VkIGFzIGZvY3VzZWQuXG4gICAqIC0gU2hhbGxvd2VzdDogT25seSB0aGUgc2hhbGxvd2VzdCBub2RlIGlzIG1hcmtlZCBhcyBmb2N1c2VkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAnYWxsJ1xuICAgKiBAZXhhbXBsZSAnZGVlcGVzdCdcbiAgICogQGV4YW1wbGUgJ3NoYWxsb3dlc3QnXG4gICAqL1xuICBtb2RlOiAnYWxsJyB8ICdkZWVwZXN0JyB8ICdzaGFsbG93ZXN0J1xufVxuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gYWRkIGEgY2xhc3MgdG8gdGhlIGZvY3VzZWQgbm9kZS5cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvZXh0ZW5zaW9ucy9mb2N1c1xuICovXG5leHBvcnQgY29uc3QgRm9jdXMgPSBFeHRlbnNpb24uY3JlYXRlPEZvY3VzT3B0aW9ucz4oe1xuICBuYW1lOiAnZm9jdXMnLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYXNzTmFtZTogJ2hhcy1mb2N1cycsXG4gICAgICBtb2RlOiAnYWxsJyxcbiAgICB9XG4gIH0sXG5cbiAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuICAgIHJldHVybiBbXG4gICAgICBuZXcgUGx1Z2luKHtcbiAgICAgICAga2V5OiBuZXcgUGx1Z2luS2V5KCdmb2N1cycpLFxuICAgICAgICBwcm9wczoge1xuICAgICAgICAgIGRlY29yYXRpb25zOiAoeyBkb2MsIHNlbGVjdGlvbiB9KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGlzRWRpdGFibGUsIGlzRm9jdXNlZCB9ID0gdGhpcy5lZGl0b3JcbiAgICAgICAgICAgIGNvbnN0IHsgYW5jaG9yIH0gPSBzZWxlY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IGRlY29yYXRpb25zOiBEZWNvcmF0aW9uW10gPSBbXVxuXG4gICAgICAgICAgICBpZiAoIWlzRWRpdGFibGUgfHwgIWlzRm9jdXNlZCkge1xuICAgICAgICAgICAgICByZXR1cm4gRGVjb3JhdGlvblNldC5jcmVhdGUoZG9jLCBbXSlcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gTWF4aW11bSBMZXZlbHNcbiAgICAgICAgICAgIGxldCBtYXhMZXZlbHMgPSAwXG5cbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMubW9kZSA9PT0gJ2RlZXBlc3QnKSB7XG4gICAgICAgICAgICAgIGRvYy5kZXNjZW5kYW50cygobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUuaXNUZXh0KSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBpc0N1cnJlbnQgPSBhbmNob3IgPj0gcG9zICYmIGFuY2hvciA8PSBwb3MgKyBub2RlLm5vZGVTaXplIC0gMVxuXG4gICAgICAgICAgICAgICAgaWYgKCFpc0N1cnJlbnQpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG1heExldmVscyArPSAxXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIExvb3AgdGhyb3VnaCBjdXJyZW50XG4gICAgICAgICAgICBsZXQgY3VycmVudExldmVsID0gMFxuXG4gICAgICAgICAgICBkb2MuZGVzY2VuZGFudHMoKG5vZGUsIHBvcykgPT4ge1xuICAgICAgICAgICAgICBpZiAobm9kZS5pc1RleHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNvbnN0IGlzQ3VycmVudCA9IGFuY2hvciA+PSBwb3MgJiYgYW5jaG9yIDw9IHBvcyArIG5vZGUubm9kZVNpemUgLSAxXG5cbiAgICAgICAgICAgICAgaWYgKCFpc0N1cnJlbnQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGN1cnJlbnRMZXZlbCArPSAxXG5cbiAgICAgICAgICAgICAgY29uc3Qgb3V0T2ZTY29wZSA9XG4gICAgICAgICAgICAgICAgKHRoaXMub3B0aW9ucy5tb2RlID09PSAnZGVlcGVzdCcgJiYgbWF4TGV2ZWxzIC0gY3VycmVudExldmVsID4gMCkgfHxcbiAgICAgICAgICAgICAgICAodGhpcy5vcHRpb25zLm1vZGUgPT09ICdzaGFsbG93ZXN0JyAmJiBjdXJyZW50TGV2ZWwgPiAxKVxuXG4gICAgICAgICAgICAgIGlmIChvdXRPZlNjb3BlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5tb2RlID09PSAnZGVlcGVzdCdcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGRlY29yYXRpb25zLnB1c2goXG4gICAgICAgICAgICAgICAgRGVjb3JhdGlvbi5ub2RlKHBvcywgcG9zICsgbm9kZS5ub2RlU2l6ZSwge1xuICAgICAgICAgICAgICAgICAgY2xhc3M6IHRoaXMub3B0aW9ucy5jbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH0pXG5cbiAgICAgICAgICAgIHJldHVybiBEZWNvcmF0aW9uU2V0LmNyZWF0ZShkb2MsIGRlY29yYXRpb25zKVxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB0eXBlIHsgUGFyZW50Q29uZmlnIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHsgY2FsbE9yUmV0dXJuLCBFeHRlbnNpb24sIGdldEV4dGVuc2lvbkZpZWxkIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHsgZ2FwQ3Vyc29yIH0gZnJvbSAnQHRpcHRhcC9wbS9nYXBjdXJzb3InXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4ge1xuICAgIC8qKlxuICAgICAqIEEgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIGdhcCBjdXJzb3IgaXMgYWxsb3dlZCBhdCB0aGUgY3VycmVudCBwb3NpdGlvbi4gTXVzdCByZXR1cm4gYHRydWVgIG9yIGBmYWxzZWAuXG4gICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAqL1xuICAgIGFsbG93R2FwQ3Vyc29yPzpcbiAgICAgIHwgYm9vbGVhblxuICAgICAgfCBudWxsXG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zPj5bJ2FsbG93R2FwQ3Vyc29yJ11cbiAgICAgICAgfSkgPT4gYm9vbGVhbiB8IG51bGwpXG4gIH1cbn1cblxuLyoqXG4gKiBUaGlzIGV4dGVuc2lvbiBhbGxvd3MgeW91IHRvIGFkZCBhIGdhcCBjdXJzb3IgdG8geW91ciBlZGl0b3IuXG4gKiBBIGdhcCBjdXJzb3IgaXMgYSBjdXJzb3IgdGhhdCBhcHBlYXJzIHdoZW4geW91IGNsaWNrIG9uIGEgcGxhY2VcbiAqIHdoZXJlIG5vIGNvbnRlbnQgaXMgcHJlc2VudCwgZm9yIGV4YW1wbGUgaW5iZXR3ZWVuIG5vZGVzLlxuICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvYXBpL2V4dGVuc2lvbnMvZ2FwY3Vyc29yXG4gKi9cbmV4cG9ydCBjb25zdCBHYXBjdXJzb3IgPSBFeHRlbnNpb24uY3JlYXRlKHtcbiAgbmFtZTogJ2dhcEN1cnNvcicsXG5cbiAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuICAgIHJldHVybiBbZ2FwQ3Vyc29yKCldXG4gIH0sXG5cbiAgZXh0ZW5kTm9kZVNjaGVtYShleHRlbnNpb24pIHtcbiAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICBvcHRpb25zOiBleHRlbnNpb24ub3B0aW9ucyxcbiAgICAgIHN0b3JhZ2U6IGV4dGVuc2lvbi5zdG9yYWdlLFxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBhbGxvd0dhcEN1cnNvcjogY2FsbE9yUmV0dXJuKGdldEV4dGVuc2lvbkZpZWxkKGV4dGVuc2lvbiwgJ2FsbG93R2FwQ3Vyc29yJywgY29udGV4dCkpID8/IG51bGwsXG4gICAgfVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBQbHVnaW5LZXkgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgdHlwZSB7IFZpZXdwb3J0U3RhdGUgfSBmcm9tICcuL3R5cGVzLmpzJ1xuXG4vKiogVGhlIGRlZmF1bHQgZGF0YSBhdHRyaWJ1dGUgbGFiZWwgKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0RBVEFfQVRUUklCVVRFID0gJ3BsYWNlaG9sZGVyJ1xuXG4vKiogVGhlIHBsdWdpbiBrZXkgdXNlZCB0byBzdG9yZSBhbmQgcmVhZCB0aGUgcGxhY2Vob2xkZXIgdmlld3BvcnQgc3RhdGUgKi9cbmV4cG9ydCBjb25zdCBQTFVHSU5fS0VZID0gbmV3IFBsdWdpbktleTxWaWV3cG9ydFN0YXRlPigndGlwdGFwX19wbGFjZWhvbGRlcicpXG5cbi8qKlxuICogRXh0cmEgcGl4ZWxzIGFkZGVkIGFib3ZlIGFuZCBiZWxvdyB0aGUgdmlzaWJsZSB2aWV3cG9ydCB3aGVuIGNvbXB1dGluZyB0aGVcbiAqIHJhbmdlIG9mIG5vZGVzIHRvIGRlY29yYXRlLiBEZWNvcmF0aW5nIHNsaWdodGx5IGJleW9uZCB0aGUgZm9sZCBtZWFucyBhXG4gKiBub2RlIGFscmVhZHkgaGFzIGl0cyBwbGFjZWhvbGRlciBiZWZvcmUgaXQgc2Nyb2xscyBpbnRvIHZpZXcsIHdoaWNoIGhpZGVzXG4gKiB0aGUgbGF0ZW5jeSBpbnRyb2R1Y2VkIGJ5IHRoZSB0aHJvdHRsZWQgdmlld3BvcnQgcmVjb21wdXRlLlxuICovXG5leHBvcnQgY29uc3QgVklFV1BPUlRfT1ZFUlNDQU5fUFggPSAyMDBcbiIsICJpbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5cbmltcG9ydCB7IERFRkFVTFRfREFUQV9BVFRSSUJVVEUgfSBmcm9tICcuL2NvbnN0YW50cy5qcydcbmltcG9ydCB7IGNyZWF0ZVBsYWNlaG9sZGVyUGx1Z2luIH0gZnJvbSAnLi9wbHVnaW5zL1BsYWNlaG9sZGVyUGx1Z2luLmpzJ1xuaW1wb3J0IHR5cGUgeyBQbGFjZWhvbGRlck9wdGlvbnMgfSBmcm9tICcuL3R5cGVzLmpzJ1xuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gYWRkIGEgcGxhY2Vob2xkZXIgdG8geW91ciBlZGl0b3IuXG4gKiBBIHBsYWNlaG9sZGVyIGlzIGEgdGV4dCB0aGF0IGFwcGVhcnMgd2hlbiB0aGUgZWRpdG9yIG9yIGEgbm9kZSBpcyBlbXB0eS5cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvZXh0ZW5zaW9ucy9wbGFjZWhvbGRlclxuICovXG5leHBvcnQgY29uc3QgUGxhY2Vob2xkZXIgPSBFeHRlbnNpb24uY3JlYXRlPFBsYWNlaG9sZGVyT3B0aW9ucz4oe1xuICBuYW1lOiAncGxhY2Vob2xkZXInLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVtcHR5RWRpdG9yQ2xhc3M6ICdpcy1lZGl0b3ItZW1wdHknLFxuICAgICAgZW1wdHlOb2RlQ2xhc3M6ICdpcy1lbXB0eScsXG4gICAgICBkYXRhQXR0cmlidXRlOiBERUZBVUxUX0RBVEFfQVRUUklCVVRFLFxuICAgICAgcGxhY2Vob2xkZXI6ICdXcml0ZSBzb21ldGhpbmcg4oCmJyxcbiAgICAgIHNob3dPbmx5V2hlbkVkaXRhYmxlOiB0cnVlLFxuICAgICAgc2hvd09ubHlDdXJyZW50OiB0cnVlLFxuICAgICAgaW5jbHVkZUNoaWxkcmVuOiBmYWxzZSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuICAgIHJldHVybiBbY3JlYXRlUGxhY2Vob2xkZXJQbHVnaW4oeyBlZGl0b3I6IHRoaXMuZWRpdG9yLCBvcHRpb25zOiB0aGlzLm9wdGlvbnMgfSldXG4gIH0sXG59KVxuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgREVGQVVMVF9EQVRBX0FUVFJJQlVURSwgUExVR0lOX0tFWSB9IGZyb20gJy4uL2NvbnN0YW50cy5qcydcbmltcG9ydCB0eXBlIHsgUGxhY2Vob2xkZXJPcHRpb25zIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBidWlsZFBsYWNlaG9sZGVyRGVjb3JhdGlvbnMgfSBmcm9tICcuLi91dGlscy9idWlsZFBsYWNlaG9sZGVyRGVjb3JhdGlvbnMuanMnXG5pbXBvcnQgeyBwcmVwYXJlUGxhY2Vob2xkZXJBdHRyaWJ1dGUgfSBmcm9tICcuLi91dGlscy9wcmVwYXJlUGxhY2Vob2xkZXJBdHRyaWJ1dGUuanMnXG5pbXBvcnQgeyBjcmVhdGVWaWV3cG9ydFBsdWdpblZpZXcsIHZpZXdwb3J0UGx1Z2luU3RhdGUgfSBmcm9tICcuLi91dGlscy92aWV3cG9ydFRyYWNraW5nLmpzJ1xuXG5leHBvcnQgdHlwZSBDcmVhdGVQbHVnaW5PcHRpb25zID0ge1xuICBlZGl0b3I6IEVkaXRvclxuICBvcHRpb25zOiBQbGFjZWhvbGRlck9wdGlvbnNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBQcm9zZU1pcnJvciBwbHVnaW4gdGhhdCByZW5kZXJzIHBsYWNlaG9sZGVyIGRlY29yYXRpb25zLlxuICogQHBhcmFtIG9wdGlvbnMuZWRpdG9yIC0gVGhlIGVkaXRvciBpbnN0YW5jZS5cbiAqIEBwYXJhbSBvcHRpb25zLm9wdGlvbnMgLSBUaGUgcmVzb2x2ZWQgcGxhY2Vob2xkZXIgb3B0aW9ucy5cbiAqIEByZXR1cm5zIFRoZSBjb25maWd1cmVkIHBsYWNlaG9sZGVyIHBsdWdpbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBsYWNlaG9sZGVyUGx1Z2luKHsgZWRpdG9yLCBvcHRpb25zIH06IENyZWF0ZVBsdWdpbk9wdGlvbnMpIHtcbiAgY29uc3QgZGF0YUF0dHJpYnV0ZSA9IG9wdGlvbnMuZGF0YUF0dHJpYnV0ZVxuICAgID8gYGRhdGEtJHtwcmVwYXJlUGxhY2Vob2xkZXJBdHRyaWJ1dGUob3B0aW9ucy5kYXRhQXR0cmlidXRlKX1gXG4gICAgOiBgZGF0YS0ke0RFRkFVTFRfREFUQV9BVFRSSUJVVEV9YFxuXG4gIHJldHVybiBuZXcgUGx1Z2luKHtcbiAgICBrZXk6IFBMVUdJTl9LRVksXG4gICAgc3RhdGU6IHZpZXdwb3J0UGx1Z2luU3RhdGUsXG4gICAgdmlldzogY3JlYXRlVmlld3BvcnRQbHVnaW5WaWV3LFxuICAgIHByb3BzOiB7XG4gICAgICBkZWNvcmF0aW9uczogKHsgZG9jLCBzZWxlY3Rpb24gfSkgPT5cbiAgICAgICAgYnVpbGRQbGFjZWhvbGRlckRlY29yYXRpb25zKHsgZWRpdG9yLCBvcHRpb25zLCBkYXRhQXR0cmlidXRlLCBkb2MsIHNlbGVjdGlvbiB9KSxcbiAgICB9LFxuICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHsgaXNOb2RlRW1wdHkgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5pbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHR5cGUgeyBTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHR5cGUgeyBEZWNvcmF0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS92aWV3J1xuaW1wb3J0IHsgRGVjb3JhdGlvblNldCB9IGZyb20gJ0B0aXB0YXAvcG0vdmlldydcblxuaW1wb3J0IHsgUExVR0lOX0tFWSB9IGZyb20gJy4uL2NvbnN0YW50cy5qcydcbmltcG9ydCB0eXBlIHsgUGxhY2Vob2xkZXJPcHRpb25zIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBjcmVhdGVQbGFjZWhvbGRlckRlY29yYXRpb24gfSBmcm9tICcuL2NyZWF0ZVBsYWNlaG9sZGVyRGVjb3JhdGlvbi5qcydcblxuZnVuY3Rpb24gcmVzb2x2ZUVtcHR5Tm9kZUNsYXNzKFxuICBlbXB0eU5vZGVDbGFzczogUGxhY2Vob2xkZXJPcHRpb25zWydlbXB0eU5vZGVDbGFzcyddLFxuICBwcm9wczogeyBlZGl0b3I6IEVkaXRvcjsgbm9kZTogTm9kZTsgcG9zOiBudW1iZXI7IGhhc0FuY2hvcjogYm9vbGVhbiB9LFxuKTogc3RyaW5nIHtcbiAgcmV0dXJuIHR5cGVvZiBlbXB0eU5vZGVDbGFzcyA9PT0gJ2Z1bmN0aW9uJyA/IGVtcHR5Tm9kZUNsYXNzKHByb3BzKSA6IGVtcHR5Tm9kZUNsYXNzXG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBwbGFjZWhvbGRlciBkZWNvcmF0aW9ucyBmb3IgdGhlIGN1cnJlbnQgZG9jdW1lbnQgc3RhdGUuXG4gKiBAcGFyYW0gb3B0aW9ucy5lZGl0b3IgLSBUaGUgZWRpdG9yIGluc3RhbmNlLlxuICogQHBhcmFtIG9wdGlvbnMub3B0aW9ucyAtIFRoZSByZXNvbHZlZCBwbGFjZWhvbGRlciBvcHRpb25zLlxuICogQHBhcmFtIG9wdGlvbnMuZGF0YUF0dHJpYnV0ZSAtIFRoZSBwcmVwYXJlZCBgZGF0YS0qYCBhdHRyaWJ1dGUgbmFtZS5cbiAqIEBwYXJhbSBvcHRpb25zLmRvYyAtIFRoZSBjdXJyZW50IGRvY3VtZW50IG5vZGUuXG4gKiBAcGFyYW0gb3B0aW9ucy5zZWxlY3Rpb24gLSBUaGUgY3VycmVudCBzZWxlY3Rpb24uXG4gKiBAcmV0dXJucyBBIGRlY29yYXRpb24gc2V0LCBvciBgbnVsbGAgd2hlbiBubyBwbGFjZWhvbGRlcnMgc2hvdWxkIGJlIHNob3duLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRQbGFjZWhvbGRlckRlY29yYXRpb25zKHtcbiAgZWRpdG9yLFxuICBvcHRpb25zLFxuICBkYXRhQXR0cmlidXRlLFxuICBkb2MsXG4gIHNlbGVjdGlvbixcbn06IHtcbiAgZWRpdG9yOiBFZGl0b3JcbiAgb3B0aW9uczogUGxhY2Vob2xkZXJPcHRpb25zXG4gIGRhdGFBdHRyaWJ1dGU6IHN0cmluZ1xuICBkb2M6IE5vZGVcbiAgc2VsZWN0aW9uOiBTZWxlY3Rpb25cbn0pOiBEZWNvcmF0aW9uU2V0IHwgbnVsbCB7XG4gIGNvbnN0IGFjdGl2ZSA9IGVkaXRvci5pc0VkaXRhYmxlIHx8ICFvcHRpb25zLnNob3dPbmx5V2hlbkVkaXRhYmxlXG5cbiAgaWYgKCFhY3RpdmUpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgY29uc3QgeyBhbmNob3IgfSA9IHNlbGVjdGlvblxuICBjb25zdCBkZWNvcmF0aW9uczogRGVjb3JhdGlvbltdID0gW11cbiAgY29uc3QgaXNFbXB0eURvYyA9IGVkaXRvci5pc0VtcHR5XG5cbiAgY29uc3QgdXNlUmVzb2x2ZWRQYXRoID0gb3B0aW9ucy5zaG93T25seUN1cnJlbnQgJiYgIW9wdGlvbnMuaW5jbHVkZUNoaWxkcmVuXG5cbiAgaWYgKHVzZVJlc29sdmVkUGF0aCkge1xuICAgIGNvbnN0IHJlc29sdmVkID0gZG9jLnJlc29sdmUoYW5jaG9yKVxuXG4gICAgLy8gV2hlbiB0aGUgc2VsZWN0aW9uIHNwYW5zIHRoZSB3aG9sZSBkb2N1bWVudCAoZS5nLiBhbiBgQWxsU2VsZWN0aW9uYFxuICAgIC8vIGFmdGVyIENtZCtBKSwgdGhlIGFuY2hvciByZXNvbHZlcyB0byB0aGUgZG9jdW1lbnQgbGV2ZWwgKGRlcHRoIDApLiBJblxuICAgIC8vIHRoYXQgY2FzZSB0aGUgcmVsZXZhbnQgdGV4dGJsb2NrIGlzIHRoZSBub2RlIGRpcmVjdGx5IGFmdGVyIHRoZVxuICAgIC8vIHBvc2l0aW9uIHJhdGhlciB0aGFuIGFuIGFuY2VzdG9yLiBvdGhlcndpc2UgdGhlIHBsYWNlaG9sZGVyIHdvdWxkXG4gICAgLy8gZGlzYXBwZWFyIGFmdGVyIHNlbGVjdGluZyBhbGwgYW5kIGRlbGV0aW5nLlxuICAgIGNvbnN0IG5vZGUgPSByZXNvbHZlZC5kZXB0aCA+IDAgPyByZXNvbHZlZC5ub2RlKDEpIDogcmVzb2x2ZWQubm9kZUFmdGVyXG4gICAgY29uc3Qgbm9kZVN0YXJ0ID0gcmVzb2x2ZWQuZGVwdGggPiAwID8gcmVzb2x2ZWQuYmVmb3JlKDEpIDogYW5jaG9yXG5cbiAgICBpZiAobm9kZSAmJiBub2RlLnR5cGUuaXNUZXh0YmxvY2sgJiYgaXNOb2RlRW1wdHkobm9kZSkpIHtcbiAgICAgIGNvbnN0IGhhc0FuY2hvciA9IGFuY2hvciA+PSBub2RlU3RhcnQgJiYgYW5jaG9yIDw9IG5vZGVTdGFydCArIG5vZGUubm9kZVNpemVcblxuICAgICAgZGVjb3JhdGlvbnMucHVzaChcbiAgICAgICAgY3JlYXRlUGxhY2Vob2xkZXJEZWNvcmF0aW9uKHtcbiAgICAgICAgICBlZGl0b3IsXG4gICAgICAgICAgaXNFbXB0eURvYyxcbiAgICAgICAgICBkYXRhQXR0cmlidXRlLFxuICAgICAgICAgIGhhc0FuY2hvcixcbiAgICAgICAgICBwbGFjZWhvbGRlcjogb3B0aW9ucy5wbGFjZWhvbGRlcixcbiAgICAgICAgICBjbGFzc2VzOiB7XG4gICAgICAgICAgICBlbXB0eUVkaXRvcjogb3B0aW9ucy5lbXB0eUVkaXRvckNsYXNzLFxuICAgICAgICAgICAgZW1wdHlOb2RlOiByZXNvbHZlRW1wdHlOb2RlQ2xhc3Mob3B0aW9ucy5lbXB0eU5vZGVDbGFzcywge1xuICAgICAgICAgICAgICBlZGl0b3IsXG4gICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgIHBvczogbm9kZVN0YXJ0LFxuICAgICAgICAgICAgICBoYXNBbmNob3IsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgcG9zOiBub2RlU3RhcnQsXG4gICAgICAgIH0pLFxuICAgICAgKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBjb25zdCBwbHVnaW5TdGF0ZSA9IFBMVUdJTl9LRVkuZ2V0U3RhdGUoZWRpdG9yLnN0YXRlKVxuICAgIGNvbnN0IGZyb20gPSBwbHVnaW5TdGF0ZT8udG9wUG9zID8/IDBcbiAgICBjb25zdCB0byA9IHBsdWdpblN0YXRlPy5ib3R0b21Qb3MgPz8gZG9jLmNvbnRlbnQuc2l6ZVxuXG4gICAgZG9jLm5vZGVzQmV0d2Vlbihmcm9tLCB0bywgKG5vZGUsIHBvcykgPT4ge1xuICAgICAgY29uc3QgaGFzQW5jaG9yID0gYW5jaG9yID49IHBvcyAmJiBhbmNob3IgPD0gcG9zICsgbm9kZS5ub2RlU2l6ZVxuICAgICAgY29uc3QgaXNFbXB0eSA9ICFub2RlLmlzTGVhZiAmJiBpc05vZGVFbXB0eShub2RlKVxuXG4gICAgICBpZiAoIW5vZGUudHlwZS5pc1RleHRibG9jaykge1xuICAgICAgICByZXR1cm4gb3B0aW9ucy5pbmNsdWRlQ2hpbGRyZW5cbiAgICAgIH1cblxuICAgICAgaWYgKChoYXNBbmNob3IgfHwgIW9wdGlvbnMuc2hvd09ubHlDdXJyZW50KSAmJiBpc0VtcHR5KSB7XG4gICAgICAgIGRlY29yYXRpb25zLnB1c2goXG4gICAgICAgICAgY3JlYXRlUGxhY2Vob2xkZXJEZWNvcmF0aW9uKHtcbiAgICAgICAgICAgIGVkaXRvcixcbiAgICAgICAgICAgIGlzRW1wdHlEb2MsXG4gICAgICAgICAgICBkYXRhQXR0cmlidXRlLFxuICAgICAgICAgICAgaGFzQW5jaG9yLFxuICAgICAgICAgICAgcGxhY2Vob2xkZXI6IG9wdGlvbnMucGxhY2Vob2xkZXIsXG4gICAgICAgICAgICBjbGFzc2VzOiB7XG4gICAgICAgICAgICAgIGVtcHR5RWRpdG9yOiBvcHRpb25zLmVtcHR5RWRpdG9yQ2xhc3MsXG4gICAgICAgICAgICAgIGVtcHR5Tm9kZTogcmVzb2x2ZUVtcHR5Tm9kZUNsYXNzKG9wdGlvbnMuZW1wdHlOb2RlQ2xhc3MsIHtcbiAgICAgICAgICAgICAgICBlZGl0b3IsXG4gICAgICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgICAgICBwb3MsXG4gICAgICAgICAgICAgICAgaGFzQW5jaG9yLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgcG9zLFxuICAgICAgICAgIH0pLFxuICAgICAgICApXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBvcHRpb25zLmluY2x1ZGVDaGlsZHJlblxuICAgIH0pXG4gIH1cblxuICByZXR1cm4gRGVjb3JhdGlvblNldC5jcmVhdGUoZG9jLCBkZWNvcmF0aW9ucylcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEVkaXRvciB9IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB0eXBlIHsgTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBEZWNvcmF0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS92aWV3J1xuXG5pbXBvcnQgdHlwZSB7IFBsYWNlaG9sZGVyT3B0aW9ucyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG4vKipcbiAqIENyZWF0ZXMgYSBQcm9zZU1pcnJvciBub2RlIGRlY29yYXRpb24gdGhhdCBhcHBsaWVzIGEgcGxhY2Vob2xkZXJcbiAqIENTUyBjbGFzcyBhbmQgZGF0YSBhdHRyaWJ1dGUgdG8gYW4gZW1wdHkgbm9kZS5cbiAqIEBwYXJhbSBvcHRpb25zLmVkaXRvciAtIFRoZSBlZGl0b3IgaW5zdGFuY2VcbiAqIEBwYXJhbSBvcHRpb25zLnBvcyAtIFRoZSBwb3NpdGlvbiBvZiB0aGUgbm9kZSBpbiB0aGUgZG9jdW1lbnRcbiAqIEBwYXJhbSBvcHRpb25zLm5vZGUgLSBUaGUgUHJvc2VNaXJyb3Igbm9kZVxuICogQHBhcmFtIG9wdGlvbnMuaXNFbXB0eURvYyAtIFdoZXRoZXIgdGhlIGVudGlyZSBkb2N1bWVudCBpcyBlbXB0eVxuICogQHBhcmFtIG9wdGlvbnMuaGFzQW5jaG9yIC0gV2hldGhlciB0aGUgc2VsZWN0aW9uIGFuY2hvciBpcyB3aXRoaW4gdGhlIG5vZGVcbiAqIEBwYXJhbSBvcHRpb25zLmRhdGFBdHRyaWJ1dGUgLSBUaGUgZGF0YSBhdHRyaWJ1dGUgbmFtZSAoZS5nLiBgZGF0YS1wbGFjZWhvbGRlcmApXG4gKiBAcGFyYW0gb3B0aW9ucy5jbGFzc2VzIC0gQ1NTIGNsYXNzZXMgZm9yIGVtcHR5IG5vZGVzIGFuZCB0aGUgZW1wdHkgZWRpdG9yXG4gKiBAcGFyYW0gb3B0aW9ucy5wbGFjZWhvbGRlciAtIFRoZSBwbGFjZWhvbGRlciB0ZXh0IG9yIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGl0XG4gKiBAcmV0dXJucyBBIFByb3NlTWlycm9yIG5vZGUgZGVjb3JhdGlvbiB3aXRoIHBsYWNlaG9sZGVyIGNsYXNzZXMgYW5kIGRhdGEgYXR0cmlidXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQbGFjZWhvbGRlckRlY29yYXRpb24ob3B0aW9uczoge1xuICBlZGl0b3I6IEVkaXRvclxuICBwb3M6IG51bWJlclxuICBub2RlOiBOb2RlXG4gIGlzRW1wdHlEb2M6IGJvb2xlYW5cbiAgaGFzQW5jaG9yOiBib29sZWFuXG4gIGRhdGFBdHRyaWJ1dGU6IHN0cmluZ1xuICBjbGFzc2VzOiB7XG4gICAgZW1wdHlFZGl0b3I6IFBsYWNlaG9sZGVyT3B0aW9uc1snZW1wdHlFZGl0b3JDbGFzcyddXG4gICAgZW1wdHlOb2RlOiBzdHJpbmdcbiAgfVxuICBwbGFjZWhvbGRlcjogUGxhY2Vob2xkZXJPcHRpb25zWydwbGFjZWhvbGRlciddXG59KSB7XG4gIGNvbnN0IHtcbiAgICBlZGl0b3IsXG4gICAgcGxhY2Vob2xkZXIsXG4gICAgZGF0YUF0dHJpYnV0ZSxcbiAgICBwb3MsXG4gICAgbm9kZSxcbiAgICBpc0VtcHR5RG9jLFxuICAgIGhhc0FuY2hvcixcbiAgICBjbGFzc2VzOiB7IGVtcHR5Tm9kZSwgZW1wdHlFZGl0b3IgfSxcbiAgfSA9IG9wdGlvbnNcbiAgY29uc3QgY2xhc3NlcyA9IFtlbXB0eU5vZGVdXG5cbiAgaWYgKGlzRW1wdHlEb2MpIHtcbiAgICBjbGFzc2VzLnB1c2goZW1wdHlFZGl0b3IpXG4gIH1cblxuICByZXR1cm4gRGVjb3JhdGlvbi5ub2RlKHBvcywgcG9zICsgbm9kZS5ub2RlU2l6ZSwge1xuICAgIGNsYXNzOiBjbGFzc2VzLmpvaW4oJyAnKSxcbiAgICBbZGF0YUF0dHJpYnV0ZV06XG4gICAgICB0eXBlb2YgcGxhY2Vob2xkZXIgPT09ICdmdW5jdGlvbidcbiAgICAgICAgPyBwbGFjZWhvbGRlcih7XG4gICAgICAgICAgICBlZGl0b3IsXG4gICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgcG9zLFxuICAgICAgICAgICAgaGFzQW5jaG9yLFxuICAgICAgICAgIH0pXG4gICAgICAgIDogcGxhY2Vob2xkZXIsXG4gIH0pXG59XG4iLCAiLyoqXG4gKiBQcmVwYXJlcyB0aGUgcGxhY2Vob2xkZXIgYXR0cmlidXRlIGJ5IGVuc3VyaW5nIGl0IGlzIHByb3Blcmx5IGZvcm1hdHRlZC5cbiAqIEBwYXJhbSBhdHRyIC0gVGhlIHBsYWNlaG9sZGVyIGF0dHJpYnV0ZSBzdHJpbmcuXG4gKiBAcmV0dXJucyBUaGUgcHJlcGFyZWQgcGxhY2Vob2xkZXIgYXR0cmlidXRlIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByZXBhcmVQbGFjZWhvbGRlckF0dHJpYnV0ZShhdHRyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gKFxuICAgIGF0dHJcbiAgICAgIC8vIHJlcGxhY2Ugd2hpdGVzcGFjZSB3aXRoIGRhc2hlc1xuICAgICAgLnJlcGxhY2UoL1xccysvZywgJy0nKVxuICAgICAgLy8gcmVwbGFjZSBub24tYWxwaGFudW1lcmljICBjaGFyYWN0ZXJzXG4gICAgICAvLyBvciBzcGVjaWFsIGNoYXJzIGxpa2UgJCwgJSwgJiwgZXRjLlxuICAgICAgLy8gYnV0IG5vdCBkYXNoZXNcbiAgICAgIC5yZXBsYWNlKC9bXmEtekEtWjAtOS1dL2csICcnKVxuICAgICAgLy8gYW5kIHJlcGxhY2UgYW55IG51bWVyaWMgY2hhcmFjdGVyIGF0IHRoZSBzdGFydFxuICAgICAgLnJlcGxhY2UoL15bMC05LV0rLywgJycpXG4gICAgICAvLyBhbmQgZmluYWxseSByZXBsYWNlIGFueSBzdHJheSwgbGVhZGluZyBkYXNoZXNcbiAgICAgIC5yZXBsYWNlKC9eLSsvLCAnJylcbiAgICAgIC50b0xvd2VyQ2FzZSgpXG4gIClcbn1cbiIsICIvKipcbiAqIENoZWNrcyBpZiBhbiBlbGVtZW50IGlzIHNjcm9sbGFibGUgYnkgdGVzdGluZyBpdHMgb3ZlcmZsb3cgcHJvcGVydGllcy5cbiAqIEVsZW1lbnRzIHdpdGggYG92ZXJmbG93OiBoaWRkZW5gIG9yIGBvdmVyZmxvdzogY2xpcGAgYXJlIGludGVudGlvbmFsbHlcbiAqIGV4Y2x1ZGVkIOKAlCB0aGV5IGNsaXAgY29udGVudCBidXQgZG9uJ3QgZW1pdCBzY3JvbGwgZXZlbnRzLlxuICovXG5mdW5jdGlvbiBpc1Njcm9sbGFibGUoZWw6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG4gIGNvbnN0IHN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbClcbiAgY29uc3Qgb3ZlcmZsb3cgPSBgJHtzdHlsZS5vdmVyZmxvd30gJHtzdHlsZS5vdmVyZmxvd1l9ICR7c3R5bGUub3ZlcmZsb3dYfWBcblxuICByZXR1cm4gL2F1dG98c2Nyb2xsfG92ZXJsYXkvLnRlc3Qob3ZlcmZsb3cpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaW5kU2Nyb2xsUGFyZW50KGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogSFRNTEVsZW1lbnQgfCBXaW5kb3cge1xuICBsZXQgZWw6IEhUTUxFbGVtZW50IHwgbnVsbCA9IGVsZW1lbnRcblxuICB3aGlsZSAoZWwpIHtcbiAgICBpZiAoaXNTY3JvbGxhYmxlKGVsKSkge1xuICAgICAgcmV0dXJuIGVsXG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgd2UgaGl0IGEgU2hhZG93IERPTSBib3VuZGFyeS4gSWYgc28sIGp1bXAgdG8gdGhlIHNoYWRvdyBob3N0XG4gICAgLy8gYW5kIGNvbnRpbnVlIHRyYXZlcnNpbmcgdGhlIGxpZ2h0IERPTS5cbiAgICBjb25zdCBwYXJlbnQgPSBlbC5wYXJlbnRFbGVtZW50XG4gICAgaWYgKCFwYXJlbnQpIHtcbiAgICAgIGNvbnN0IHJvb3QgPSBlbC5nZXRSb290Tm9kZSgpXG4gICAgICBpZiAocm9vdCBpbnN0YW5jZW9mIFNoYWRvd1Jvb3QpIHtcbiAgICAgICAgZWwgPSByb290Lmhvc3QgYXMgSFRNTEVsZW1lbnRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHdpbmRvd1xuICAgIH1cblxuICAgIGVsID0gcGFyZW50XG4gIH1cblxuICByZXR1cm4gd2luZG93XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB0eXBlIHsgRWRpdG9yVmlldyB9IGZyb20gJ0B0aXB0YXAvcG0vdmlldydcblxuaW1wb3J0IHsgVklFV1BPUlRfT1ZFUlNDQU5fUFggfSBmcm9tICcuLi9jb25zdGFudHMuanMnXG5cbmZ1bmN0aW9uIGdldENvbnRhaW5lclJlY3QoY29udGFpbmVyOiBIVE1MRWxlbWVudCB8IFdpbmRvdyk6IHsgdG9wOiBudW1iZXI7IGJvdHRvbTogbnVtYmVyIH0ge1xuICBpZiAoY29udGFpbmVyID09PSB3aW5kb3cpIHtcbiAgICByZXR1cm4geyB0b3A6IDAsIGJvdHRvbTogd2luZG93LmlubmVySGVpZ2h0IH1cbiAgfVxuXG4gIHJldHVybiAoY29udGFpbmVyIGFzIEhUTUxFbGVtZW50KS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Vmlld3BvcnRCb3VuZGFyeVBvc2l0aW9ucyh7XG4gIGRvYyxcbiAgdmlldyxcbiAgc2Nyb2xsQ29udGFpbmVyLFxufToge1xuICBkb2M6IE5vZGVcbiAgdmlldzogRWRpdG9yVmlld1xuICBzY3JvbGxDb250YWluZXI/OiBIVE1MRWxlbWVudCB8IFdpbmRvd1xufSkge1xuICBjb25zdCBlZGl0b3JSZWN0ID0gdmlldy5kb20uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgY29uc3QgY29udGFpbmVyUmVjdCA9IHNjcm9sbENvbnRhaW5lclxuICAgID8gZ2V0Q29udGFpbmVyUmVjdChzY3JvbGxDb250YWluZXIpXG4gICAgOiB7IHRvcDogMCwgYm90dG9tOiB3aW5kb3cuaW5uZXJIZWlnaHQgfVxuXG4gIGNvbnN0IHZpc2libGVUb3AgPSBNYXRoLm1heChlZGl0b3JSZWN0LnRvcCwgY29udGFpbmVyUmVjdC50b3ApIC0gVklFV1BPUlRfT1ZFUlNDQU5fUFhcbiAgY29uc3QgdmlzaWJsZUJvdHRvbSA9IE1hdGgubWluKGVkaXRvclJlY3QuYm90dG9tLCBjb250YWluZXJSZWN0LmJvdHRvbSkgKyBWSUVXUE9SVF9PVkVSU0NBTl9QWFxuXG4gIGlmICh2aXNpYmxlVG9wID49IHZpc2libGVCb3R0b20pIHtcbiAgICAvLyBFZGl0b3IgaXMgbm90IHZpc2libGUg4oCUIGZhbGwgYmFjayB0byBmdWxsIGRvY3VtZW50IHJhbmdlXG4gICAgcmV0dXJuIHsgdG9wOiAwLCBib3R0b206IGRvYy5jb250ZW50LnNpemUgfVxuICB9XG5cbiAgLy8gUGljayB0aGUgeC1jb29yZGluYXRlIGJhc2VkIG9uIHRleHQgZGlyZWN0aW9uLiBJbiBMVFIgdGhlIGNvbnRlbnRcbiAgLy8gc3RhcnRzIGF0IHRoZSBsZWZ0IGVkZ2U7IGluIFJUTCBpdCBzdGFydHMgYXQgdGhlIHJpZ2h0IGVkZ2UuXG4gIC8vIENsYW1wIHRvIGVuc3VyZSB0aGUgY29vcmRpbmF0ZSBzdGF5cyBpbnNpZGUgdGhlIGVkaXRvciBib3VuZHMuXG4gIGNvbnN0IGlzUlRMID0gZ2V0Q29tcHV0ZWRTdHlsZSh2aWV3LmRvbSkuZGlyZWN0aW9uID09PSAncnRsJ1xuICBjb25zdCB4ID0gaXNSVEwgPyBNYXRoLm1heChlZGl0b3JSZWN0LnJpZ2h0IC0gMiwgZWRpdG9yUmVjdC5sZWZ0ICsgMikgOiBlZGl0b3JSZWN0LmxlZnQgKyAyXG5cbiAgY29uc3QgdG9wUG9zID0gdmlldy5wb3NBdENvb3Jkcyh7IGxlZnQ6IHgsIHRvcDogdmlzaWJsZVRvcCArIDIgfSlcbiAgY29uc3QgYm90dG9tUG9zID0gdmlldy5wb3NBdENvb3Jkcyh7IGxlZnQ6IHgsIHRvcDogdmlzaWJsZUJvdHRvbSAtIDIgfSlcblxuICByZXR1cm4ge1xuICAgIHRvcDogdG9wUG9zID8gdG9wUG9zLnBvcyA6IDAsXG4gICAgYm90dG9tOiBib3R0b21Qb3MgPyBib3R0b21Qb3MucG9zIDogZG9jLmNvbnRlbnQuc2l6ZSxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUsIFBsdWdpblZpZXcsIFN0YXRlRmllbGQsIFRyYW5zYWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcbmltcG9ydCB0eXBlIHsgRWRpdG9yVmlldyB9IGZyb20gJ0B0aXB0YXAvcG0vdmlldydcblxuaW1wb3J0IHsgUExVR0lOX0tFWSB9IGZyb20gJy4uL2NvbnN0YW50cy5qcydcbmltcG9ydCB0eXBlIHsgVmlld3BvcnRTdGF0ZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgZmluZFNjcm9sbFBhcmVudCB9IGZyb20gJy4vZmluZFNjcm9sbFBhcmVudC5qcydcbmltcG9ydCB7IGdldFZpZXdwb3J0Qm91bmRhcnlQb3NpdGlvbnMgfSBmcm9tICcuL2dldFZpZXdwb3J0Qm91bmRhcnlQb3NpdGlvbnMuanMnXG5cbi8qKlxuICogVGhlIHBsdWdpbiBgc3RhdGVgIGNvbmZpZyB0aGF0IHRyYWNrcyB0aGUgdmlzaWJsZSB2aWV3cG9ydCBib3VuZGFyaWVzIHNvIHRoZVxuICogZGVjb3JhdGlvbiBjYWxsYmFjayBvbmx5IHNjYW5zIHRoZSBub2RlcyBjdXJyZW50bHkgb24gc2NyZWVuLlxuICovXG5leHBvcnQgY29uc3Qgdmlld3BvcnRQbHVnaW5TdGF0ZTogU3RhdGVGaWVsZDxWaWV3cG9ydFN0YXRlPiA9IHtcbiAgLyoqXG4gICAqIEluaXRpYWxpc2VzIHRoZSB2aWV3cG9ydCBzdGF0ZSB3aXRoIG5vIGtub3duIHBvc2l0aW9ucy5cbiAgICogQHJldHVybnMgVGhlIGluaXRpYWwgdmlld3BvcnQgc3RhdGUuXG4gICAqL1xuICBpbml0KCk6IFZpZXdwb3J0U3RhdGUge1xuICAgIHJldHVybiB7IHRvcFBvczogbnVsbCwgYm90dG9tUG9zOiBudWxsIH1cbiAgfSxcblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgdmlld3BvcnQgc3RhdGUgZnJvbSBpbmNvbWluZyB0cmFuc2FjdGlvbnMuXG4gICAqIEBwYXJhbSB0ciAtIFRoZSB0cmFuc2FjdGlvbiBiZWluZyBhcHBsaWVkLlxuICAgKiBAcGFyYW0gcHJldiAtIFRoZSBwcmV2aW91cyB2aWV3cG9ydCBzdGF0ZS5cbiAgICogQHJldHVybnMgVGhlIG5leHQgdmlld3BvcnQgc3RhdGUuXG4gICAqL1xuICBhcHBseSh0cjogVHJhbnNhY3Rpb24sIHByZXY6IFZpZXdwb3J0U3RhdGUpOiBWaWV3cG9ydFN0YXRlIHtcbiAgICBjb25zdCBtZXRhID0gdHIuZ2V0TWV0YShQTFVHSU5fS0VZKSBhc1xuICAgICAgfCB7IHBvc2l0aW9ucz86IHsgdG9wOiBudW1iZXI7IGJvdHRvbTogbnVtYmVyIH0gfVxuICAgICAgfCB1bmRlZmluZWRcblxuICAgIGlmIChtZXRhPy5wb3NpdGlvbnMpIHtcbiAgICAgIHJldHVybiB7IHRvcFBvczogbWV0YS5wb3NpdGlvbnMudG9wLCBib3R0b21Qb3M6IG1ldGEucG9zaXRpb25zLmJvdHRvbSB9XG4gICAgfVxuXG4gICAgaWYgKCF0ci5kb2NDaGFuZ2VkKSB7XG4gICAgICByZXR1cm4gcHJldlxuICAgIH1cblxuICAgIC8vIFByZXNlcnZlIGxhc3Qga25vd24gdmlld3BvcnQgcG9zaXRpb25zIGFjcm9zcyB0cmFuc2FjdGlvbnMuXG4gICAgLy8gV2l0aG91dCB0aGlzLCBldmVyeSBrZXlzdHJva2UgcmVzZXRzIGJhY2sgdG8gYSBmdWxsIGRvY3VtZW50XG4gICAgLy8gc2NhbiwgZGVmZWF0aW5nIHRoZSB2aWV3cG9ydCBvcHRpbWlzYXRpb24uXG4gICAgLy8gT25seSBtYXAgd2hlbiB3ZSBoYXZlIGFjdHVhbCBwb3NpdGlvbnMg4oCUIG51bGwgbWVhbnMgXCJubyB2aWV3cG9ydFxuICAgIC8vIGluZm8geWV0XCIgYW5kIHNob3VsZCBzdGF5IG51bGwgdG8gZmFsbCBiYWNrIHRvIGZ1bGwgZG9jIHNjYW4uXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvcFBvczogcHJldi50b3BQb3MgIT09IG51bGwgPyB0ci5tYXBwaW5nLm1hcChwcmV2LnRvcFBvcykgOiBudWxsLFxuICAgICAgYm90dG9tUG9zOiBwcmV2LmJvdHRvbVBvcyAhPT0gbnVsbCA/IHRyLm1hcHBpbmcubWFwKHByZXYuYm90dG9tUG9zKSA6IG51bGwsXG4gICAgfVxuICB9LFxufVxuXG4vKipcbiAqIENyZWF0ZXMgdGhlIHBsdWdpbiBgdmlld2AgdGhhdCByZWNvbXB1dGVzIHRoZSB2aXNpYmxlIHZpZXdwb3J0IG9uIHNjcm9sbCBhbmRcbiAqIGRvY3VtZW50IHNpemUgY2hhbmdlcywgZGlzcGF0Y2hpbmcgdGhlIHJlc3VsdCBpbnRvIHRoZSBwbHVnaW4gc3RhdGUuXG4gKiBAcGFyYW0gdmlldyAtIFRoZSBlZGl0b3IgdmlldyB0aGUgcGx1Z2luIGlzIGF0dGFjaGVkIHRvLlxuICogQHJldHVybnMgQSBwbHVnaW4gdmlldyB3aXRoIGB1cGRhdGVgIGFuZCBgZGVzdHJveWAgaGFuZGxlcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVWaWV3cG9ydFBsdWdpblZpZXcodmlldzogRWRpdG9yVmlldyk6IFBsdWdpblZpZXcge1xuICBjb25zdCBzY3JvbGxDb250YWluZXIgPSBmaW5kU2Nyb2xsUGFyZW50KHZpZXcuZG9tKVxuXG4gIGNvbnN0IGNvbXB1dGVBbmREaXNwYXRjaCA9ICgpID0+IHtcbiAgICBjb25zdCBwb3NpdGlvbnMgPSBnZXRWaWV3cG9ydEJvdW5kYXJ5UG9zaXRpb25zKHtcbiAgICAgIHZpZXcsXG4gICAgICBkb2M6IHZpZXcuc3RhdGUuZG9jLFxuICAgICAgc2Nyb2xsQ29udGFpbmVyLFxuICAgIH0pXG5cbiAgICBjb25zdCBwcmV2ID0gUExVR0lOX0tFWS5nZXRTdGF0ZSh2aWV3LnN0YXRlKVxuICAgIGlmIChwcmV2Py50b3BQb3MgPT09IHBvc2l0aW9ucy50b3AgJiYgcHJldj8uYm90dG9tUG9zID09PSBwb3NpdGlvbnMuYm90dG9tKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCB0ciA9IHZpZXcuc3RhdGUudHIuc2V0TWV0YShQTFVHSU5fS0VZLCB7IHBvc2l0aW9ucyB9KVxuICAgIHZpZXcuZGlzcGF0Y2godHIpXG4gIH1cblxuICAvLyByQUYtYmFzZWQgc2NoZWR1bGVyIHdpdGggaW50ZXJ2YWwgZ3VhcmQgKDE1MG1zIOKGkiB+NuKAkzcgSHopIHVzZWQgYnlcbiAgLy8gc2Nyb2xsIGV2ZW50cyBhbmQgdXBkYXRlKCkuIFRoZSBvdmVyc2NhbiBtYXJnaW4gaGlkZXMgdGhlIGV4dHJhXG4gIC8vIGxhdGVuY3kuIFdoZW4gdGhlIGd1YXJkIGJsb2NrcywgdGhlIGNhbGxiYWNrIHJlc2NoZWR1bGVzIGl0c2VsZiBzb1xuICAvLyB0aGUgdHJhaWxpbmcgcG9zaXRpb24gaXMgYWx3YXlzIGNhcHR1cmVkLlxuICBsZXQgZnJhbWU6IG51bWJlciB8IG51bGwgPSBudWxsXG4gIGxldCBsYXN0Q29tcHV0ZSA9IDBcbiAgY29uc3QgTUlOX1NDUk9MTF9JTlRFUlZBTCA9IDE1MFxuXG4gIGNvbnN0IHNjaGVkdWxlRnJhbWUgPSAoKSA9PiB7XG4gICAgaWYgKGZyYW1lICE9PSBudWxsKSByZXR1cm5cbiAgICBmcmFtZSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICBmcmFtZSA9IG51bGxcbiAgICAgIGNvbnN0IG5vdyA9IHBlcmZvcm1hbmNlLm5vdygpXG4gICAgICBpZiAobm93IC0gbGFzdENvbXB1dGUgPj0gTUlOX1NDUk9MTF9JTlRFUlZBTCkge1xuICAgICAgICBsYXN0Q29tcHV0ZSA9IG5vd1xuICAgICAgICBjb21wdXRlQW5kRGlzcGF0Y2goKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2NoZWR1bGVGcmFtZSgpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIHNjcm9sbENvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBzY2hlZHVsZUZyYW1lLCB7IHBhc3NpdmU6IHRydWUgfSlcblxuICAvLyBGaXJlIG9uY2UgdG8gcG9wdWxhdGUgaW5pdGlhbCB2aWV3cG9ydFxuICBjb21wdXRlQW5kRGlzcGF0Y2goKVxuXG4gIHJldHVybiB7XG4gICAgdXBkYXRlKF92aWV3OiBFZGl0b3JWaWV3LCBwcmV2U3RhdGU6IEVkaXRvclN0YXRlKSB7XG4gICAgICBpZiAodmlldy5zdGF0ZS5kb2MuY29udGVudC5zaXplICE9PSBwcmV2U3RhdGUuZG9jLmNvbnRlbnQuc2l6ZSkge1xuICAgICAgICBzY2hlZHVsZUZyYW1lKClcbiAgICAgIH1cbiAgICB9LFxuICAgIGRlc3Ryb3k6ICgpID0+IHtcbiAgICAgIGlmIChmcmFtZSAhPT0gbnVsbCkge1xuICAgICAgICBjYW5jZWxBbmltYXRpb25GcmFtZShmcmFtZSlcbiAgICAgIH1cbiAgICAgIHNjcm9sbENvbnRhaW5lci5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBzY2hlZHVsZUZyYW1lKVxuICAgIH0sXG4gIH1cbn1cbiIsICJpbXBvcnQgeyBjcmVhdGVTdHlsZVRhZywgRXh0ZW5zaW9uLCBpc05vZGVTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5pbXBvcnQgeyBQbHVnaW4sIFBsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgeyBEZWNvcmF0aW9uLCBEZWNvcmF0aW9uU2V0IH0gZnJvbSAnQHRpcHRhcC9wbS92aWV3J1xuXG5jb25zdCBzZWxlY3Rpb25TdHlsZSA9IGAuUHJvc2VNaXJyb3I6bm90KC5Qcm9zZU1pcnJvci1mb2N1c2VkKSAqOjpzZWxlY3Rpb24ge1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbn1cblxuLlByb3NlTWlycm9yOm5vdCguUHJvc2VNaXJyb3ItZm9jdXNlZCkgKjo6LW1vei1zZWxlY3Rpb24ge1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbn1gXG5cbmV4cG9ydCB0eXBlIFNlbGVjdGlvbk9wdGlvbnMgPSB7XG4gIC8qKlxuICAgKiBUaGUgY2xhc3MgbmFtZSB0aGF0IHNob3VsZCBiZSBhZGRlZCB0byB0aGUgc2VsZWN0ZWQgdGV4dC5cbiAgICogQGRlZmF1bHQgJ3NlbGVjdGlvbidcbiAgICogQGV4YW1wbGUgJ2lzLXNlbGVjdGVkJ1xuICAgKi9cbiAgY2xhc3NOYW1lOiBzdHJpbmdcbn1cblxuLyoqXG4gKiBUaGlzIGV4dGVuc2lvbiBhbGxvd3MgeW91IHRvIGFkZCBhIGNsYXNzIHRvIHRoZSBzZWxlY3RlZCB0ZXh0LlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9leHRlbnNpb25zL3NlbGVjdGlvblxuICovXG5leHBvcnQgY29uc3QgU2VsZWN0aW9uID0gRXh0ZW5zaW9uLmNyZWF0ZTxTZWxlY3Rpb25PcHRpb25zPih7XG4gIG5hbWU6ICdzZWxlY3Rpb24nLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYXNzTmFtZTogJ3NlbGVjdGlvbicsXG4gICAgfVxuICB9LFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICBjb25zdCB7IGVkaXRvciwgb3B0aW9ucyB9ID0gdGhpc1xuXG4gICAgaWYgKGVkaXRvci5vcHRpb25zLmluamVjdENTUyAmJiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjcmVhdGVTdHlsZVRhZyhzZWxlY3Rpb25TdHlsZSwgZWRpdG9yLm9wdGlvbnMuaW5qZWN0Tm9uY2UsICdzZWxlY3Rpb24nKVxuICAgIH1cblxuICAgIHJldHVybiBbXG4gICAgICBuZXcgUGx1Z2luKHtcbiAgICAgICAga2V5OiBuZXcgUGx1Z2luS2V5KCdzZWxlY3Rpb24nKSxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICBkZWNvcmF0aW9ucyhzdGF0ZSkge1xuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICBzdGF0ZS5zZWxlY3Rpb24uZW1wdHkgfHxcbiAgICAgICAgICAgICAgZWRpdG9yLmlzRm9jdXNlZCB8fFxuICAgICAgICAgICAgICAhZWRpdG9yLmlzRWRpdGFibGUgfHxcbiAgICAgICAgICAgICAgaXNOb2RlU2VsZWN0aW9uKHN0YXRlLnNlbGVjdGlvbikgfHxcbiAgICAgICAgICAgICAgZWRpdG9yLnZpZXcuZHJhZ2dpbmdcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gRGVjb3JhdGlvblNldC5jcmVhdGUoc3RhdGUuZG9jLCBbXG4gICAgICAgICAgICAgIERlY29yYXRpb24uaW5saW5lKHN0YXRlLnNlbGVjdGlvbi5mcm9tLCBzdGF0ZS5zZWxlY3Rpb24udG8sIHtcbiAgICAgICAgICAgICAgICBjbGFzczogb3B0aW9ucy5jbGFzc05hbWUsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgXSlcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgXVxuICB9LFxufSlcblxuZXhwb3J0IGRlZmF1bHQgU2VsZWN0aW9uXG4iLCAiaW1wb3J0IHsgRXh0ZW5zaW9uIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHR5cGUgeyBOb2RlLCBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBQbHVnaW4sIFBsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmV4cG9ydCBjb25zdCBza2lwVHJhaWxpbmdOb2RlTWV0YSA9ICdza2lwVHJhaWxpbmdOb2RlJ1xuXG5mdW5jdGlvbiBub2RlRXF1YWxzVHlwZSh7XG4gIHR5cGVzLFxuICBub2RlLFxufToge1xuICB0eXBlczogTm9kZVR5cGUgfCBOb2RlVHlwZVtdXG4gIG5vZGU6IE5vZGUgfCBudWxsIHwgdW5kZWZpbmVkXG59KSB7XG4gIHJldHVybiAobm9kZSAmJiBBcnJheS5pc0FycmF5KHR5cGVzKSAmJiB0eXBlcy5pbmNsdWRlcyhub2RlLnR5cGUpKSB8fCBub2RlPy50eXBlID09PSB0eXBlc1xufVxuXG4vKipcbiAqIEV4dGVuc2lvbiBiYXNlZCBvbjpcbiAqIC0gaHR0cHM6Ly9naXRodWIuY29tL3VlYmVyZG9zaXMvdGlwdGFwL2Jsb2IvdjEvcGFja2FnZXMvdGlwdGFwLWV4dGVuc2lvbnMvc3JjL2V4dGVuc2lvbnMvVHJhaWxpbmdOb2RlLmpzXG4gKiAtIGh0dHBzOi8vZ2l0aHViLmNvbS9yZW1pcnJvci9yZW1pcnJvci9ibG9iL2UwZjFiZWM0YTFlODA3M2NlOGY1NTAwZDYyMTkzZTUyMzIxMTU1YjkvcGFja2FnZXMvcHJvc2VtaXJyb3ItdHJhaWxpbmctbm9kZS9zcmMvdHJhaWxpbmctbm9kZS1wbHVnaW4udHNcbiAqL1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWlsaW5nTm9kZU9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIG5vZGUgdHlwZSB0aGF0IHNob3VsZCBiZSBpbnNlcnRlZCBhdCB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC5cbiAgICogQG5vdGUgdGhlIG5vZGUgd2lsbCBhbHdheXMgYmUgYWRkZWQgdG8gdGhlIGBub3RBZnRlcmAgbGlzdHMgdG9cbiAgICogcHJldmVudCBhbiBpbmZpbml0ZSBsb29wLlxuICAgKiBAZGVmYXVsdCB1bmRlZmluZWRcbiAgICovXG4gIG5vZGU/OiBzdHJpbmdcbiAgLyoqXG4gICAqIFRoZSBub2RlIHR5cGVzIGFmdGVyIHdoaWNoIHRoZSB0cmFpbGluZyBub2RlIHNob3VsZCBub3QgYmUgaW5zZXJ0ZWQuXG4gICAqIEBkZWZhdWx0IFsncGFyYWdyYXBoJ11cbiAgICovXG4gIG5vdEFmdGVyPzogc3RyaW5nIHwgc3RyaW5nW11cbn1cblxuLyoqXG4gKiBUaGlzIGV4dGVuc2lvbiBhbGxvd3MgeW91IHRvIGFkZCBhbiBleHRyYSBub2RlIGF0IHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9leHRlbnNpb25zL3RyYWlsaW5nLW5vZGVcbiAqL1xuZXhwb3J0IGNvbnN0IFRyYWlsaW5nTm9kZSA9IEV4dGVuc2lvbi5jcmVhdGU8VHJhaWxpbmdOb2RlT3B0aW9ucz4oe1xuICBuYW1lOiAndHJhaWxpbmdOb2RlJyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBub2RlOiB1bmRlZmluZWQsXG4gICAgICBub3RBZnRlcjogW10sXG4gICAgfVxuICB9LFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICBjb25zdCBwbHVnaW4gPSBuZXcgUGx1Z2luS2V5KHRoaXMubmFtZSlcbiAgICBjb25zdCBkZWZhdWx0Tm9kZSA9XG4gICAgICB0aGlzLm9wdGlvbnMubm9kZSB8fFxuICAgICAgdGhpcy5lZGl0b3Iuc2NoZW1hLnRvcE5vZGVUeXBlLmNvbnRlbnRNYXRjaC5kZWZhdWx0VHlwZT8ubmFtZSB8fFxuICAgICAgJ3BhcmFncmFwaCdcblxuICAgIGNvbnN0IGRpc2FibGVkTm9kZXMgPSBPYmplY3QuZW50cmllcyh0aGlzLmVkaXRvci5zY2hlbWEubm9kZXMpXG4gICAgICAubWFwKChbLCB2YWx1ZV0pID0+IHZhbHVlKVxuICAgICAgLmZpbHRlcihub2RlID0+ICh0aGlzLm9wdGlvbnMubm90QWZ0ZXIgfHwgW10pLmNvbmNhdChkZWZhdWx0Tm9kZSkuaW5jbHVkZXMobm9kZS5uYW1lKSlcblxuICAgIHJldHVybiBbXG4gICAgICBuZXcgUGx1Z2luKHtcbiAgICAgICAga2V5OiBwbHVnaW4sXG4gICAgICAgIGFwcGVuZFRyYW5zYWN0aW9uOiAodHJhbnNhY3Rpb25zLCBfXywgc3RhdGUpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGRvYywgdHIsIHNjaGVtYSB9ID0gc3RhdGVcbiAgICAgICAgICBjb25zdCBzaG91bGRJbnNlcnROb2RlQXRFbmQgPSBwbHVnaW4uZ2V0U3RhdGUoc3RhdGUpXG4gICAgICAgICAgY29uc3QgZW5kUG9zaXRpb24gPSBkb2MuY29udGVudC5zaXplXG4gICAgICAgICAgY29uc3QgdHlwZSA9IHNjaGVtYS5ub2Rlc1tkZWZhdWx0Tm9kZV1cblxuICAgICAgICAgIGlmICh0cmFuc2FjdGlvbnMuc29tZSh0cmFuc2FjdGlvbiA9PiB0cmFuc2FjdGlvbi5nZXRNZXRhKHNraXBUcmFpbGluZ05vZGVNZXRhKSkpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghc2hvdWxkSW5zZXJ0Tm9kZUF0RW5kKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdHIuaW5zZXJ0KGVuZFBvc2l0aW9uLCB0eXBlLmNyZWF0ZSgpKVxuICAgICAgICB9LFxuICAgICAgICBzdGF0ZToge1xuICAgICAgICAgIGluaXQ6IChfLCBzdGF0ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbGFzdE5vZGUgPSBzdGF0ZS50ci5kb2MubGFzdENoaWxkXG5cbiAgICAgICAgICAgIHJldHVybiAhbm9kZUVxdWFsc1R5cGUoeyBub2RlOiBsYXN0Tm9kZSwgdHlwZXM6IGRpc2FibGVkTm9kZXMgfSlcbiAgICAgICAgICB9LFxuICAgICAgICAgIGFwcGx5OiAodHIsIHZhbHVlKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRyLmRvY0NoYW5nZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElnbm9yZSB0cmFuc2FjdGlvbnMgZnJvbSBVbmlxdWVJRCBleHRlbnNpb24gdG8gcHJldmVudCBpbmZpbml0ZSBsb29wc1xuICAgICAgICAgICAgLy8gd2hlbiBVbmlxdWVJRCBhZGRzIElEcyB0byBuZXdseSBpbnNlcnRlZCB0cmFpbGluZyBub2Rlc1xuICAgICAgICAgICAgaWYgKHRyLmdldE1ldGEoJ19fdW5pcXVlSURUcmFuc2FjdGlvbicpKSB7XG4gICAgICAgICAgICAgIHJldHVybiB2YWx1ZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBsYXN0Tm9kZSA9IHRyLmRvYy5sYXN0Q2hpbGRcblxuICAgICAgICAgICAgcmV0dXJuICFub2RlRXF1YWxzVHlwZSh7IG5vZGU6IGxhc3ROb2RlLCB0eXBlczogZGlzYWJsZWROb2RlcyB9KVxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB7IGhpc3RvcnksIHJlZG8sIHVuZG8gfSBmcm9tICdAdGlwdGFwL3BtL2hpc3RvcnknXG5cbmV4cG9ydCBpbnRlcmZhY2UgVW5kb1JlZG9PcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBhbW91bnQgb2YgaGlzdG9yeSBldmVudHMgdGhhdCBhcmUgY29sbGVjdGVkIGJlZm9yZSB0aGUgb2xkZXN0IGV2ZW50cyBhcmUgZGlzY2FyZGVkLlxuICAgKiBAZGVmYXVsdCAxMDBcbiAgICogQGV4YW1wbGUgNTBcbiAgICovXG4gIGRlcHRoOiBudW1iZXJcblxuICAvKipcbiAgICogVGhlIGRlbGF5IChpbiBtaWxsaXNlY29uZHMpIGJldHdlZW4gY2hhbmdlcyBhZnRlciB3aGljaCBhIG5ldyBncm91cCBzaG91bGQgYmUgc3RhcnRlZC5cbiAgICogQGRlZmF1bHQgNTAwXG4gICAqIEBleGFtcGxlIDEwMDBcbiAgICovXG4gIG5ld0dyb3VwRGVsYXk6IG51bWJlclxufVxuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgdW5kb1JlZG86IHtcbiAgICAgIC8qKlxuICAgICAgICogVW5kbyByZWNlbnQgY2hhbmdlc1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnVuZG8oKVxuICAgICAgICovXG4gICAgICB1bmRvOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgICAvKipcbiAgICAgICAqIFJlYXBwbHkgcmV2ZXJ0ZWQgY2hhbmdlc1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnJlZG8oKVxuICAgICAgICovXG4gICAgICByZWRvOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byB1bmRvIGFuZCByZWRvIHJlY2VudCBjaGFuZ2VzLlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9leHRlbnNpb25zL3VuZG8tcmVkb1xuICpcbiAqICoqSW1wb3J0YW50Kio6IElmIHRoZSBgQHRpcHRhcC9leHRlbnNpb24tY29sbGFib3JhdGlvbmAgcGFja2FnZSBpcyB1c2VkLCBtYWtlIHN1cmUgdG8gcmVtb3ZlXG4gKiB0aGUgYHVuZG8tcmVkb2AgZXh0ZW5zaW9uLCBhcyBpdCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIHRoZSBgY29sbGFib3JhdGlvbmAgZXh0ZW5zaW9uLlxuICpcbiAqIGBAdGlwdGFwL2V4dGVuc2lvbi1jb2xsYWJvcmF0aW9uYCB1c2VzIGl0cyBvd24gaGlzdG9yeSBpbXBsZW1lbnRhdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IFVuZG9SZWRvID0gRXh0ZW5zaW9uLmNyZWF0ZTxVbmRvUmVkb09wdGlvbnM+KHtcbiAgbmFtZTogJ3VuZG9SZWRvJyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBkZXB0aDogMTAwLFxuICAgICAgbmV3R3JvdXBEZWxheTogNTAwLFxuICAgIH1cbiAgfSxcblxuICBhZGRDb21tYW5kcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdW5kbzpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gdW5kbyhzdGF0ZSwgZGlzcGF0Y2gpXG4gICAgICAgIH0sXG4gICAgICByZWRvOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgICAgICAgIHJldHVybiByZWRvKHN0YXRlLCBkaXNwYXRjaClcbiAgICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuICAgIHJldHVybiBbaGlzdG9yeSh0aGlzLm9wdGlvbnMpXVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnTW9kLXonOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy51bmRvKCksXG4gICAgICAnU2hpZnQtTW9kLXonOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5yZWRvKCksXG4gICAgICAnTW9kLXknOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5yZWRvKCksXG5cbiAgICAgIC8vIFJ1c3NpYW4ga2V5Ym9hcmQgbGF5b3V0c1xuICAgICAgJ01vZC3Rjyc6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnVuZG8oKSxcbiAgICAgICdTaGlmdC1Nb2Qt0Y8nOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5yZWRvKCksXG4gICAgfVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5pbXBvcnQgdHlwZSB7IEJsb2NrcXVvdGVPcHRpb25zIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tYmxvY2txdW90ZSdcbmltcG9ydCB7IEJsb2NrcXVvdGUgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1ibG9ja3F1b3RlJ1xuaW1wb3J0IHR5cGUgeyBCb2xkT3B0aW9ucyB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLWJvbGQnXG5pbXBvcnQgeyBCb2xkIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tYm9sZCdcbmltcG9ydCB0eXBlIHsgQ29kZU9wdGlvbnMgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1jb2RlJ1xuaW1wb3J0IHsgQ29kZSB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLWNvZGUnXG5pbXBvcnQgdHlwZSB7IENvZGVCbG9ja09wdGlvbnMgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1jb2RlLWJsb2NrJ1xuaW1wb3J0IHsgQ29kZUJsb2NrIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tY29kZS1ibG9jaydcbmltcG9ydCB7IERvY3VtZW50IH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tZG9jdW1lbnQnXG5pbXBvcnQgdHlwZSB7IEhhcmRCcmVha09wdGlvbnMgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1oYXJkLWJyZWFrJ1xuaW1wb3J0IHsgSGFyZEJyZWFrIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24taGFyZC1icmVhaydcbmltcG9ydCB0eXBlIHsgSGVhZGluZ09wdGlvbnMgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1oZWFkaW5nJ1xuaW1wb3J0IHsgSGVhZGluZyB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLWhlYWRpbmcnXG5pbXBvcnQgdHlwZSB7IEhvcml6b250YWxSdWxlT3B0aW9ucyB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLWhvcml6b250YWwtcnVsZSdcbmltcG9ydCB7IEhvcml6b250YWxSdWxlIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24taG9yaXpvbnRhbC1ydWxlJ1xuaW1wb3J0IHR5cGUgeyBJdGFsaWNPcHRpb25zIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24taXRhbGljJ1xuaW1wb3J0IHsgSXRhbGljIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24taXRhbGljJ1xuaW1wb3J0IHR5cGUgeyBMaW5rT3B0aW9ucyB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLWxpbmsnXG5pbXBvcnQgeyBMaW5rIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tbGluaydcbmltcG9ydCB0eXBlIHtcbiAgQnVsbGV0TGlzdE9wdGlvbnMsXG4gIExpc3RJdGVtT3B0aW9ucyxcbiAgTGlzdEtleW1hcE9wdGlvbnMsXG4gIE9yZGVyZWRMaXN0T3B0aW9ucyxcbn0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tbGlzdCdcbmltcG9ydCB7IEJ1bGxldExpc3QsIExpc3RJdGVtLCBMaXN0S2V5bWFwLCBPcmRlcmVkTGlzdCB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLWxpc3QnXG5pbXBvcnQgdHlwZSB7IFBhcmFncmFwaE9wdGlvbnMgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1wYXJhZ3JhcGgnXG5pbXBvcnQgeyBQYXJhZ3JhcGggfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1wYXJhZ3JhcGgnXG5pbXBvcnQgdHlwZSB7IFN0cmlrZU9wdGlvbnMgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1zdHJpa2UnXG5pbXBvcnQgeyBTdHJpa2UgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1zdHJpa2UnXG5pbXBvcnQgeyBUZXh0IH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tdGV4dCdcbmltcG9ydCB0eXBlIHsgVW5kZXJsaW5lT3B0aW9ucyB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLXVuZGVybGluZSdcbmltcG9ydCB7IFVuZGVybGluZSB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLXVuZGVybGluZSdcbmltcG9ydCB0eXBlIHsgRHJvcGN1cnNvck9wdGlvbnMsIFRyYWlsaW5nTm9kZU9wdGlvbnMsIFVuZG9SZWRvT3B0aW9ucyB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9ucydcbmltcG9ydCB7IERyb3BjdXJzb3IsIEdhcGN1cnNvciwgVHJhaWxpbmdOb2RlLCBVbmRvUmVkbyB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9ucydcblxuZXhwb3J0IGludGVyZmFjZSBTdGFydGVyS2l0T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBibG9ja3F1b3RlIGV4dGVuc2lvbiB3aWxsIG5vdCBiZSByZWdpc3RlcmVkXG4gICAqIEBleGFtcGxlIGJsb2NrcXVvdGU6IGZhbHNlXG4gICAqL1xuICBibG9ja3F1b3RlOiBQYXJ0aWFsPEJsb2NrcXVvdGVPcHRpb25zPiB8IGZhbHNlXG5cbiAgLyoqXG4gICAqIElmIHNldCB0byBmYWxzZSwgdGhlIGJvbGQgZXh0ZW5zaW9uIHdpbGwgbm90IGJlIHJlZ2lzdGVyZWRcbiAgICogQGV4YW1wbGUgYm9sZDogZmFsc2VcbiAgICovXG4gIGJvbGQ6IFBhcnRpYWw8Qm9sZE9wdGlvbnM+IHwgZmFsc2VcblxuICAvKipcbiAgICogSWYgc2V0IHRvIGZhbHNlLCB0aGUgYnVsbGV0TGlzdCBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSBidWxsZXRMaXN0OiBmYWxzZVxuICAgKi9cbiAgYnVsbGV0TGlzdDogUGFydGlhbDxCdWxsZXRMaXN0T3B0aW9ucz4gfCBmYWxzZVxuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBjb2RlIGV4dGVuc2lvbiB3aWxsIG5vdCBiZSByZWdpc3RlcmVkXG4gICAqIEBleGFtcGxlIGNvZGU6IGZhbHNlXG4gICAqL1xuICBjb2RlOiBQYXJ0aWFsPENvZGVPcHRpb25zPiB8IGZhbHNlXG5cbiAgLyoqXG4gICAqIElmIHNldCB0byBmYWxzZSwgdGhlIGNvZGVCbG9jayBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSBjb2RlQmxvY2s6IGZhbHNlXG4gICAqL1xuICBjb2RlQmxvY2s6IFBhcnRpYWw8Q29kZUJsb2NrT3B0aW9ucz4gfCBmYWxzZVxuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBkb2N1bWVudCBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSBkb2N1bWVudDogZmFsc2VcbiAgICovXG4gIGRvY3VtZW50OiBmYWxzZVxuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBkcm9wY3Vyc29yIGV4dGVuc2lvbiB3aWxsIG5vdCBiZSByZWdpc3RlcmVkXG4gICAqIEBleGFtcGxlIGRyb3BjdXJzb3I6IGZhbHNlXG4gICAqL1xuICBkcm9wY3Vyc29yOiBQYXJ0aWFsPERyb3BjdXJzb3JPcHRpb25zPiB8IGZhbHNlXG5cbiAgLyoqXG4gICAqIElmIHNldCB0byBmYWxzZSwgdGhlIGdhcGN1cnNvciBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSBnYXBjdXJzb3I6IGZhbHNlXG4gICAqL1xuICBnYXBjdXJzb3I6IGZhbHNlXG5cbiAgLyoqXG4gICAqIElmIHNldCB0byBmYWxzZSwgdGhlIGhhcmRCcmVhayBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSBoYXJkQnJlYWs6IGZhbHNlXG4gICAqL1xuICBoYXJkQnJlYWs6IFBhcnRpYWw8SGFyZEJyZWFrT3B0aW9ucz4gfCBmYWxzZVxuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBoZWFkaW5nIGV4dGVuc2lvbiB3aWxsIG5vdCBiZSByZWdpc3RlcmVkXG4gICAqIEBleGFtcGxlIGhlYWRpbmc6IGZhbHNlXG4gICAqL1xuICBoZWFkaW5nOiBQYXJ0aWFsPEhlYWRpbmdPcHRpb25zPiB8IGZhbHNlXG5cbiAgLyoqXG4gICAqIElmIHNldCB0byBmYWxzZSwgdGhlIHVuZG8tcmVkbyBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSB1bmRvUmVkbzogZmFsc2VcbiAgICovXG4gIHVuZG9SZWRvOiBQYXJ0aWFsPFVuZG9SZWRvT3B0aW9ucz4gfCBmYWxzZVxuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBob3Jpem9udGFsUnVsZSBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSBob3Jpem9udGFsUnVsZTogZmFsc2VcbiAgICovXG4gIGhvcml6b250YWxSdWxlOiBQYXJ0aWFsPEhvcml6b250YWxSdWxlT3B0aW9ucz4gfCBmYWxzZVxuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBpdGFsaWMgZXh0ZW5zaW9uIHdpbGwgbm90IGJlIHJlZ2lzdGVyZWRcbiAgICogQGV4YW1wbGUgaXRhbGljOiBmYWxzZVxuICAgKi9cbiAgaXRhbGljOiBQYXJ0aWFsPEl0YWxpY09wdGlvbnM+IHwgZmFsc2VcblxuICAvKipcbiAgICogSWYgc2V0IHRvIGZhbHNlLCB0aGUgbGlzdEl0ZW0gZXh0ZW5zaW9uIHdpbGwgbm90IGJlIHJlZ2lzdGVyZWRcbiAgICogQGV4YW1wbGUgbGlzdEl0ZW06IGZhbHNlXG4gICAqL1xuICBsaXN0SXRlbTogUGFydGlhbDxMaXN0SXRlbU9wdGlvbnM+IHwgZmFsc2VcblxuICAvKipcbiAgICogSWYgc2V0IHRvIGZhbHNlLCB0aGUgbGlzdEl0ZW1LZXltYXAgZXh0ZW5zaW9uIHdpbGwgbm90IGJlIHJlZ2lzdGVyZWRcbiAgICogQGV4YW1wbGUgbGlzdEtleW1hcDogZmFsc2VcbiAgICovXG4gIGxpc3RLZXltYXA6IFBhcnRpYWw8TGlzdEtleW1hcE9wdGlvbnM+IHwgZmFsc2VcblxuICAvKipcbiAgICogSWYgc2V0IHRvIGZhbHNlLCB0aGUgbGluayBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSBsaW5rOiBmYWxzZVxuICAgKi9cbiAgbGluazogUGFydGlhbDxMaW5rT3B0aW9ucz4gfCBmYWxzZVxuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBvcmRlcmVkTGlzdCBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSBvcmRlcmVkTGlzdDogZmFsc2VcbiAgICovXG4gIG9yZGVyZWRMaXN0OiBQYXJ0aWFsPE9yZGVyZWRMaXN0T3B0aW9ucz4gfCBmYWxzZVxuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSBwYXJhZ3JhcGggZXh0ZW5zaW9uIHdpbGwgbm90IGJlIHJlZ2lzdGVyZWRcbiAgICogQGV4YW1wbGUgcGFyYWdyYXBoOiBmYWxzZVxuICAgKi9cbiAgcGFyYWdyYXBoOiBQYXJ0aWFsPFBhcmFncmFwaE9wdGlvbnM+IHwgZmFsc2VcblxuICAvKipcbiAgICogSWYgc2V0IHRvIGZhbHNlLCB0aGUgc3RyaWtlIGV4dGVuc2lvbiB3aWxsIG5vdCBiZSByZWdpc3RlcmVkXG4gICAqIEBleGFtcGxlIHN0cmlrZTogZmFsc2VcbiAgICovXG4gIHN0cmlrZTogUGFydGlhbDxTdHJpa2VPcHRpb25zPiB8IGZhbHNlXG5cbiAgLyoqXG4gICAqIElmIHNldCB0byBmYWxzZSwgdGhlIHRleHQgZXh0ZW5zaW9uIHdpbGwgbm90IGJlIHJlZ2lzdGVyZWRcbiAgICogQGV4YW1wbGUgdGV4dDogZmFsc2VcbiAgICovXG4gIHRleHQ6IGZhbHNlXG5cbiAgLyoqXG4gICAqIElmIHNldCB0byBmYWxzZSwgdGhlIHVuZGVybGluZSBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSB1bmRlcmxpbmU6IGZhbHNlXG4gICAqL1xuICB1bmRlcmxpbmU6IFBhcnRpYWw8VW5kZXJsaW5lT3B0aW9ucz4gfCBmYWxzZVxuXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSB0cmFpbGluZ05vZGUgZXh0ZW5zaW9uIHdpbGwgbm90IGJlIHJlZ2lzdGVyZWRcbiAgICogQGV4YW1wbGUgdHJhaWxpbmdOb2RlOiBmYWxzZVxuICAgKi9cbiAgdHJhaWxpbmdOb2RlOiBQYXJ0aWFsPFRyYWlsaW5nTm9kZU9wdGlvbnM+IHwgZmFsc2Vcbn1cblxuLyoqXG4gKiBUaGUgc3RhcnRlciBraXQgaXMgYSBjb2xsZWN0aW9uIG9mIGVzc2VudGlhbCBlZGl0b3IgZXh0ZW5zaW9ucy5cbiAqXG4gKiBJdOKAmXMgYSBnb29kIHN0YXJ0aW5nIHBvaW50IGZvciBidWlsZGluZyB5b3VyIG93biBlZGl0b3IuXG4gKi9cbmV4cG9ydCBjb25zdCBTdGFydGVyS2l0ID0gRXh0ZW5zaW9uLmNyZWF0ZTxTdGFydGVyS2l0T3B0aW9ucz4oe1xuICBuYW1lOiAnc3RhcnRlcktpdCcsXG5cbiAgYWRkRXh0ZW5zaW9ucygpIHtcbiAgICBjb25zdCBleHRlbnNpb25zID0gW11cblxuICAgIGlmICh0aGlzLm9wdGlvbnMuYm9sZCAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChCb2xkLmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMuYm9sZCkpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5ibG9ja3F1b3RlICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKEJsb2NrcXVvdGUuY29uZmlndXJlKHRoaXMub3B0aW9ucy5ibG9ja3F1b3RlKSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmJ1bGxldExpc3QgIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goQnVsbGV0TGlzdC5jb25maWd1cmUodGhpcy5vcHRpb25zLmJ1bGxldExpc3QpKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMuY29kZSAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChDb2RlLmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMuY29kZSkpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5jb2RlQmxvY2sgIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goQ29kZUJsb2NrLmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMuY29kZUJsb2NrKSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmRvY3VtZW50ICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKERvY3VtZW50LmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMuZG9jdW1lbnQpKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMuZHJvcGN1cnNvciAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChEcm9wY3Vyc29yLmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMuZHJvcGN1cnNvcikpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5nYXBjdXJzb3IgIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goR2FwY3Vyc29yLmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMuZ2FwY3Vyc29yKSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmhhcmRCcmVhayAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChIYXJkQnJlYWsuY29uZmlndXJlKHRoaXMub3B0aW9ucy5oYXJkQnJlYWspKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMuaGVhZGluZyAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChIZWFkaW5nLmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMuaGVhZGluZykpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy51bmRvUmVkbyAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChVbmRvUmVkby5jb25maWd1cmUodGhpcy5vcHRpb25zLnVuZG9SZWRvKSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmhvcml6b250YWxSdWxlICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKEhvcml6b250YWxSdWxlLmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMuaG9yaXpvbnRhbFJ1bGUpKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMuaXRhbGljICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKEl0YWxpYy5jb25maWd1cmUodGhpcy5vcHRpb25zLml0YWxpYykpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5saXN0SXRlbSAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChMaXN0SXRlbS5jb25maWd1cmUodGhpcy5vcHRpb25zLmxpc3RJdGVtKSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmxpc3RLZXltYXAgIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goTGlzdEtleW1hcC5jb25maWd1cmUodGhpcy5vcHRpb25zPy5saXN0S2V5bWFwKSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLmxpbmsgIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goTGluay5jb25maWd1cmUodGhpcy5vcHRpb25zPy5saW5rKSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLm9yZGVyZWRMaXN0ICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKE9yZGVyZWRMaXN0LmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMub3JkZXJlZExpc3QpKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMucGFyYWdyYXBoICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKFBhcmFncmFwaC5jb25maWd1cmUodGhpcy5vcHRpb25zLnBhcmFncmFwaCkpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5zdHJpa2UgIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goU3RyaWtlLmNvbmZpZ3VyZSh0aGlzLm9wdGlvbnMuc3RyaWtlKSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnRleHQgIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goVGV4dC5jb25maWd1cmUodGhpcy5vcHRpb25zLnRleHQpKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMudW5kZXJsaW5lICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKFVuZGVybGluZS5jb25maWd1cmUodGhpcy5vcHRpb25zPy51bmRlcmxpbmUpKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMudHJhaWxpbmdOb2RlICE9PSBmYWxzZSkge1xuICAgICAgZXh0ZW5zaW9ucy5wdXNoKFRyYWlsaW5nTm9kZS5jb25maWd1cmUodGhpcy5vcHRpb25zPy50cmFpbGluZ05vZGUpKVxuICAgIH1cblxuICAgIHJldHVybiBleHRlbnNpb25zXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IFN0YXJ0ZXJLaXQgfSBmcm9tICcuL3N0YXJ0ZXIta2l0LmpzJ1xuXG5leHBvcnQgdHlwZSB7IFN0YXJ0ZXJLaXRPcHRpb25zIH0gZnJvbSAnLi9zdGFydGVyLWtpdC5qcydcbmV4cG9ydCAqIGZyb20gJy4vc3RhcnRlci1raXQuanMnXG5cbmV4cG9ydCBkZWZhdWx0IFN0YXJ0ZXJLaXRcbiIsICIvKipcbiAqIFV0aWxpdHkgbW9kdWxlIHRvIHdvcmsgd2l0aCBrZXktdmFsdWUgc3RvcmVzLlxuICpcbiAqIEBtb2R1bGUgbWFwXG4gKi9cblxuLyoqXG4gKiBAdGVtcGxhdGUgS1xuICogQHRlbXBsYXRlIFZcbiAqIEB0eXBlZGVmIHtNYXA8SyxWPn0gR2xvYmFsTWFwXG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IE1hcCBpbnN0YW5jZS5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm4ge01hcDxhbnksIGFueT59XG4gKlxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGUgPSAoKSA9PiBuZXcgTWFwKClcblxuLyoqXG4gKiBDb3B5IGEgTWFwIG9iamVjdCBpbnRvIGEgZnJlc2ggTWFwIG9iamVjdC5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEB0ZW1wbGF0ZSBLLFZcbiAqIEBwYXJhbSB7TWFwPEssVj59IG1cbiAqIEByZXR1cm4ge01hcDxLLFY+fVxuICovXG5leHBvcnQgY29uc3QgY29weSA9IG0gPT4ge1xuICBjb25zdCByID0gY3JlYXRlKClcbiAgbS5mb3JFYWNoKCh2LCBrKSA9PiB7IHIuc2V0KGssIHYpIH0pXG4gIHJldHVybiByXG59XG5cbi8qKlxuICogR2V0IG1hcCBwcm9wZXJ0eS4gQ3JlYXRlIFQgaWYgcHJvcGVydHkgaXMgdW5kZWZpbmVkIGFuZCBzZXQgVCBvbiBtYXAuXG4gKlxuICogYGBganNcbiAqIGNvbnN0IGxpc3RlbmVycyA9IG1hcC5zZXRJZlVuZGVmaW5lZChldmVudHMsICdldmVudE5hbWUnLCBzZXQuY3JlYXRlKVxuICogbGlzdGVuZXJzLmFkZChsaXN0ZW5lcilcbiAqIGBgYFxuICpcbiAqIEBmdW5jdGlvblxuICogQHRlbXBsYXRlIHtNYXA8YW55LCBhbnk+fSBNQVBcbiAqIEB0ZW1wbGF0ZSB7TUFQIGV4dGVuZHMgTWFwPGFueSxpbmZlciBWPiA/IGZ1bmN0aW9uKCk6ViA6IHVua25vd259IENGXG4gKiBAcGFyYW0ge01BUH0gbWFwXG4gKiBAcGFyYW0ge01BUCBleHRlbmRzIE1hcDxpbmZlciBLLGFueT4gPyBLIDogdW5rbm93bn0ga2V5XG4gKiBAcGFyYW0ge0NGfSBjcmVhdGVUXG4gKiBAcmV0dXJuIHtSZXR1cm5UeXBlPENGPn1cbiAqL1xuZXhwb3J0IGNvbnN0IHNldElmVW5kZWZpbmVkID0gKG1hcCwga2V5LCBjcmVhdGVUKSA9PiB7XG4gIGxldCBzZXQgPSBtYXAuZ2V0KGtleSlcbiAgaWYgKHNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgbWFwLnNldChrZXksIHNldCA9IGNyZWF0ZVQoKSlcbiAgfVxuICByZXR1cm4gc2V0XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBBcnJheSBhbmQgcG9wdWxhdGVzIGl0IHdpdGggdGhlIGNvbnRlbnQgb2YgYWxsIGtleS12YWx1ZSBwYWlycyB1c2luZyB0aGUgYGYodmFsdWUsIGtleSlgIGZ1bmN0aW9uLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHRlbXBsYXRlIEtcbiAqIEB0ZW1wbGF0ZSBWXG4gKiBAdGVtcGxhdGUgUlxuICogQHBhcmFtIHtNYXA8SyxWPn0gbVxuICogQHBhcmFtIHtmdW5jdGlvbihWLEspOlJ9IGZcbiAqIEByZXR1cm4ge0FycmF5PFI+fVxuICovXG5leHBvcnQgY29uc3QgbWFwID0gKG0sIGYpID0+IHtcbiAgY29uc3QgcmVzID0gW11cbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgbSkge1xuICAgIHJlcy5wdXNoKGYodmFsdWUsIGtleSkpXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG4vKipcbiAqIFRlc3RzIHdoZXRoZXIgYW55IGtleS12YWx1ZSBwYWlycyBwYXNzIHRoZSB0ZXN0IGltcGxlbWVudGVkIGJ5IGBmKHZhbHVlLCBrZXkpYC5cbiAqXG4gKiBAdG9kbyBzaG91bGQgcmVuYW1lIHRvIHNvbWUgLSBzaW1pbGFybHkgdG8gQXJyYXkuc29tZVxuICpcbiAqIEBmdW5jdGlvblxuICogQHRlbXBsYXRlIEtcbiAqIEB0ZW1wbGF0ZSBWXG4gKiBAcGFyYW0ge01hcDxLLFY+fSBtXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFYsSyk6Ym9vbGVhbn0gZlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGNvbnN0IGFueSA9IChtLCBmKSA9PiB7XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIG0pIHtcbiAgICBpZiAoZih2YWx1ZSwga2V5KSkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qKlxuICogVGVzdHMgd2hldGhlciBhbGwga2V5LXZhbHVlIHBhaXJzIHBhc3MgdGhlIHRlc3QgaW1wbGVtZW50ZWQgYnkgYGYodmFsdWUsIGtleSlgLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHRlbXBsYXRlIEtcbiAqIEB0ZW1wbGF0ZSBWXG4gKiBAcGFyYW0ge01hcDxLLFY+fSBtXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFYsSyk6Ym9vbGVhbn0gZlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGNvbnN0IGFsbCA9IChtLCBmKSA9PiB7XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIG0pIHtcbiAgICBpZiAoIWYodmFsdWUsIGtleSkpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuIiwgIi8qKlxuICogVXRpbGl0eSBtb2R1bGUgdG8gd29yayB3aXRoIHNldHMuXG4gKlxuICogQG1vZHVsZSBzZXRcbiAqL1xuXG5leHBvcnQgY29uc3QgY3JlYXRlID0gKCkgPT4gbmV3IFNldCgpXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7U2V0PFQ+fSBzZXRcbiAqIEByZXR1cm4ge0FycmF5PFQ+fVxuICovXG5leHBvcnQgY29uc3QgdG9BcnJheSA9IHNldCA9PiBBcnJheS5mcm9tKHNldClcblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtTZXQ8VD59IHNldFxuICogQHJldHVybiB7VHx1bmRlZmluZWR9XG4gKi9cbmV4cG9ydCBjb25zdCBmaXJzdCA9IHNldCA9PiBzZXQudmFsdWVzKCkubmV4dCgpLnZhbHVlXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7SXRlcmFibGU8VD59IGVudHJpZXNcbiAqIEByZXR1cm4ge1NldDxUPn1cbiAqL1xuZXhwb3J0IGNvbnN0IGZyb20gPSBlbnRyaWVzID0+IG5ldyBTZXQoZW50cmllcylcbiIsICIvKipcbiAqIFV0aWxpdHkgbW9kdWxlIHRvIHdvcmsgd2l0aCBBcnJheXMuXG4gKlxuICogQG1vZHVsZSBhcnJheVxuICovXG5cbmltcG9ydCAqIGFzIHNldCBmcm9tICcuL3NldC5qcydcblxuLyoqXG4gKiBSZXR1cm4gdGhlIGxhc3QgZWxlbWVudCBvZiBhbiBhcnJheS4gVGhlIGVsZW1lbnQgbXVzdCBleGlzdFxuICpcbiAqIEB0ZW1wbGF0ZSBMXG4gKiBAcGFyYW0ge0FycmF5TGlrZTxMPn0gYXJyXG4gKiBAcmV0dXJuIHtMfVxuICovXG5leHBvcnQgY29uc3QgbGFzdCA9IGFyciA9PiBhcnJbYXJyLmxlbmd0aCAtIDFdXG5cbi8qKlxuICogQHRlbXBsYXRlIENcbiAqIEByZXR1cm4ge0FycmF5PEM+fVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlID0gKCkgPT4gLyoqIEB0eXBlIHtBcnJheTxDPn0gKi8gKFtdKVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBEXG4gKiBAcGFyYW0ge0FycmF5PEQ+fSBhXG4gKiBAcmV0dXJuIHtBcnJheTxEPn1cbiAqL1xuZXhwb3J0IGNvbnN0IGNvcHkgPSBhID0+IC8qKiBAdHlwZSB7QXJyYXk8RD59ICovIChhLnNsaWNlKCkpXG5cbi8qKlxuICogQXBwZW5kIGVsZW1lbnRzIGZyb20gc3JjIHRvIGRlc3RcbiAqXG4gKiBAdGVtcGxhdGUgTVxuICogQHBhcmFtIHtBcnJheTxNPn0gZGVzdFxuICogQHBhcmFtIHtBcnJheTxNPn0gc3JjXG4gKi9cbmV4cG9ydCBjb25zdCBhcHBlbmRUbyA9IChkZXN0LCBzcmMpID0+IHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcmMubGVuZ3RoOyBpKyspIHtcbiAgICBkZXN0LnB1c2goc3JjW2ldKVxuICB9XG59XG5cbi8qKlxuICogVHJhbnNmb3JtcyBzb21ldGhpbmcgYXJyYXktbGlrZSB0byBhbiBhY3R1YWwgQXJyYXkuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtBcnJheUxpa2U8VD58SXRlcmFibGU8VD59IGFycmF5bGlrZVxuICogQHJldHVybiB7VH1cbiAqL1xuZXhwb3J0IGNvbnN0IGZyb20gPSBBcnJheS5mcm9tXG5cbi8qKlxuICogVHJ1ZSBpZmYgY29uZGl0aW9uIGhvbGRzIG9uIGV2ZXJ5IGVsZW1lbnQgaW4gdGhlIEFycmF5LlxuICpcbiAqIEBmdW5jdGlvblxuICogQHRlbXBsYXRlIHtBcnJheUxpa2U8YW55Pn0gQVJSXG4gKlxuICogQHBhcmFtIHtBUlJ9IGFyclxuICogQHBhcmFtIHtBUlIgZXh0ZW5kcyBBcnJheUxpa2U8aW5mZXIgUz4gPyAoKHZhbHVlOlMsIGluZGV4Om51bWJlciwgYXJyOkFSUikgPT4gYm9vbGVhbikgOiBhbnl9IGZcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBjb25zdCBldmVyeSA9IChhcnIsIGYpID0+IHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIWYoYXJyW2ldLCBpLCBhcnIpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuLyoqXG4gKiBUcnVlIGlmZiBjb25kaXRpb24gaG9sZHMgb24gc29tZSBlbGVtZW50IGluIHRoZSBBcnJheS5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEB0ZW1wbGF0ZSB7QXJyYXlMaWtlPGFueT59IEFSUlxuICpcbiAqIEBwYXJhbSB7QVJSfSBhcnJcbiAqIEBwYXJhbSB7QVJSIGV4dGVuZHMgQXJyYXlMaWtlPGluZmVyIFM+ID8gKCh2YWx1ZTpTLCBpbmRleDpudW1iZXIsIGFycjpBUlIpID0+IGJvb2xlYW4pIDogbmV2ZXJ9IGZcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBjb25zdCBzb21lID0gKGFyciwgZikgPT4ge1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGlmIChmKGFycltpXSwgaSwgYXJyKSkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qKlxuICogQHRlbXBsYXRlIEVMRU1cbiAqXG4gKiBAcGFyYW0ge0FycmF5TGlrZTxFTEVNPn0gYVxuICogQHBhcmFtIHtBcnJheUxpa2U8RUxFTT59IGJcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBjb25zdCBlcXVhbEZsYXQgPSAoYSwgYikgPT4gYS5sZW5ndGggPT09IGIubGVuZ3RoICYmIGV2ZXJ5KGEsIChpdGVtLCBpbmRleCkgPT4gaXRlbSA9PT0gYltpbmRleF0pXG5cbi8qKlxuICogQHRlbXBsYXRlIEVMRU1cbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXk8RUxFTT4+fSBhcnJcbiAqIEByZXR1cm4ge0FycmF5PEVMRU0+fVxuICovXG5leHBvcnQgY29uc3QgZmxhdHRlbiA9IGFyciA9PiBmb2xkKGFyciwgLyoqIEB0eXBlIHtBcnJheTxFTEVNPn0gKi8gKFtdKSwgKGFjYywgdmFsKSA9PiBhY2MuY29uY2F0KHZhbCkpXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24obnVtYmVyLCBBcnJheTxUPik6VH0gZlxuICogQHJldHVybiB7QXJyYXk8VD59XG4gKi9cbmV4cG9ydCBjb25zdCB1bmZvbGQgPSAobGVuLCBmKSA9PiB7XG4gIGNvbnN0IGFycmF5ID0gbmV3IEFycmF5KGxlbilcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGFycmF5W2ldID0gZihpLCBhcnJheSlcbiAgfVxuICByZXR1cm4gYXJyYXlcbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHRlbXBsYXRlIFJFU1VMVFxuICogQHBhcmFtIHtBcnJheTxUPn0gYXJyXG4gKiBAcGFyYW0ge1JFU1VMVH0gc2VlZFxuICogQHBhcmFtIHtmdW5jdGlvbihSRVNVTFQsIFQsIG51bWJlcik6UkVTVUxUfSBmb2xkZXJcbiAqL1xuZXhwb3J0IGNvbnN0IGZvbGQgPSAoYXJyLCBzZWVkLCBmb2xkZXIpID0+IGFyci5yZWR1Y2UoZm9sZGVyLCBzZWVkKVxuXG5leHBvcnQgY29uc3QgaXNBcnJheSA9IEFycmF5LmlzQXJyYXlcblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtBcnJheTxUPn0gYXJyXG4gKiBAcmV0dXJuIHtBcnJheTxUPn1cbiAqL1xuZXhwb3J0IGNvbnN0IHVuaXF1ZSA9IGFyciA9PiBmcm9tKHNldC5mcm9tKGFycikpXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0ZW1wbGF0ZSBNXG4gKiBAcGFyYW0ge0FycmF5TGlrZTxUPn0gYXJyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFQpOk19IG1hcHBlclxuICogQHJldHVybiB7QXJyYXk8VD59XG4gKi9cbmV4cG9ydCBjb25zdCB1bmlxdWVCeSA9IChhcnIsIG1hcHBlcikgPT4ge1xuICAvKipcbiAgICogQHR5cGUge1NldDxNPn1cbiAgICovXG4gIGNvbnN0IGhhcHBlbmVkID0gc2V0LmNyZWF0ZSgpXG4gIC8qKlxuICAgKiBAdHlwZSB7QXJyYXk8VD59XG4gICAqL1xuICBjb25zdCByZXN1bHQgPSBbXVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGVsID0gYXJyW2ldXG4gICAgY29uc3QgbWFwcGVkID0gbWFwcGVyKGVsKVxuICAgIGlmICghaGFwcGVuZWQuaGFzKG1hcHBlZCkpIHtcbiAgICAgIGhhcHBlbmVkLmFkZChtYXBwZWQpXG4gICAgICByZXN1bHQucHVzaChlbClcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7QXJyYXlMaWtlPGFueT59IEFSUlxuICogQHRlbXBsYXRlIHtmdW5jdGlvbihBUlIgZXh0ZW5kcyBBcnJheUxpa2U8aW5mZXIgVD4gPyBUIDogbmV2ZXIsIG51bWJlciwgQVJSKTphbnl9IE1BUFBFUlxuICogQHBhcmFtIHtBUlJ9IGFyclxuICogQHBhcmFtIHtNQVBQRVJ9IG1hcHBlclxuICogQHJldHVybiB7QXJyYXk8TUFQUEVSIGV4dGVuZHMgZnVuY3Rpb24oLi4uYW55KTogaW5mZXIgTSA/IE0gOiBuZXZlcj59XG4gKi9cbmV4cG9ydCBjb25zdCBtYXAgPSAoYXJyLCBtYXBwZXIpID0+IHtcbiAgLyoqXG4gICAqIEB0eXBlIHtBcnJheTxhbnk+fVxuICAgKi9cbiAgY29uc3QgcmVzID0gQXJyYXkoYXJyLmxlbmd0aClcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyBpKyspIHtcbiAgICByZXNbaV0gPSBtYXBwZXIoLyoqIEB0eXBlIHthbnl9ICovIChhcnJbaV0pLCBpLCAvKiogQHR5cGUge2FueX0gKi8gKGFycikpXG4gIH1cbiAgcmV0dXJuIC8qKiBAdHlwZSB7YW55fSAqLyAocmVzKVxufVxuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gYnViYmxlLXNvcnRzIGEgc2luZ2xlIGl0ZW0gdG8gdGhlIGNvcnJlY3QgcG9zaXRpb24uIFRoZSBzb3J0IGhhcHBlbnMgaW4tcGxhY2UgYW5kXG4gKiBtaWdodCBiZSB1c2VmdWwgdG8gZW5zdXJlIHRoYXQgYSBzaW5nbGUgaXRlbSBpcyBhdCB0aGUgY29ycmVjdCBwb3NpdGlvbiBpbiBhbiBvdGhlcndpc2Ugc29ydGVkXG4gKiBhcnJheS5cbiAqXG4gKiBAZXhhbXBsZVxuICogIGNvbnN0IGFyciA9IFszLCAyLCA1XVxuICogIGFyci5zb3J0KChhLCBiKSA9PiBhIC0gYilcbiAqICBhcnIgLy8gPT4gWzIsIDMsIDVdXG4gKiAgYXJyLnNwbGljZSgxLCAwLCA3KVxuICogIGFycmF5LmJ1YmJsZVNvcnRJdGVtKGFyciwgMSwgKGEsIGIpID0+IGEgLSBiKVxuICogIGFyciAvLyA9PiBbMiwgMywgNSwgN11cbiAqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtBcnJheTxUPn0gYXJyXG4gKiBAcGFyYW0ge251bWJlcn0gaVxuICogQHBhcmFtIHsoYTpULGI6VCkgPT4gbnVtYmVyfSBjb21wYXJlRm5cbiAqL1xuZXhwb3J0IGNvbnN0IGJ1YmJsZXNvcnRJdGVtID0gKGFyciwgaSwgY29tcGFyZUZuKSA9PiB7XG4gIGNvbnN0IG4gPSBhcnJbaV1cbiAgbGV0IGogPSBpXG4gIC8vIHRyeSB0byBzb3J0IHRvIHRoZSByaWdodFxuICB3aGlsZSAoaiArIDEgPCBhcnIubGVuZ3RoICYmIGNvbXBhcmVGbihuLCBhcnJbaiArIDFdKSA+IDApIHtcbiAgICBhcnJbal0gPSBhcnJbaiArIDFdXG4gICAgYXJyWysral0gPSBuXG4gIH1cbiAgaWYgKGkgPT09IGogJiYgaiA+IDApIHsgLy8gbm8gY2hhbmdlIHlldFxuICAgIC8vIHNvcnQgdG8gdGhlIGxlZnRcbiAgICB3aGlsZSAoaiA+IDAgJiYgY29tcGFyZUZuKGFycltqIC0gMV0sIG4pID4gMCkge1xuICAgICAgYXJyW2pdID0gYXJyW2ogLSAxXVxuICAgICAgYXJyWy0tal0gPSBuXG4gICAgfVxuICB9XG4gIHJldHVybiBqXG59XG4iLCAiLyoqXG4gKiBPYnNlcnZhYmxlIGNsYXNzIHByb3RvdHlwZS5cbiAqXG4gKiBAbW9kdWxlIG9ic2VydmFibGVcbiAqL1xuXG5pbXBvcnQgKiBhcyBtYXAgZnJvbSAnLi9tYXAuanMnXG5pbXBvcnQgKiBhcyBzZXQgZnJvbSAnLi9zZXQuanMnXG5pbXBvcnQgKiBhcyBhcnJheSBmcm9tICcuL2FycmF5LmpzJ1xuXG4vKipcbiAqIEhhbmRsZXMgbmFtZWQgZXZlbnRzLlxuICogQGV4cGVyaW1lbnRhbFxuICpcbiAqIFRoaXMgaXMgYmFzaWNhbGx5IGEgKGJldHRlciB0eXBlZCkgZHVwbGljYXRlIG9mIE9ic2VydmFibGUsIHdoaWNoIHdpbGwgcmVwbGFjZSBPYnNlcnZhYmxlIGluIHRoZVxuICogbmV4dCByZWxlYXNlLlxuICpcbiAqIEB0ZW1wbGF0ZSB7e1trZXkgaW4ga2V5b2YgRVZFTlRTXTogZnVuY3Rpb24oLi4uYW55KTp2b2lkfX0gRVZFTlRTXG4gKi9cbmV4cG9ydCBjbGFzcyBPYnNlcnZhYmxlVjIge1xuICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgLyoqXG4gICAgICogU29tZSBkZXNjLlxuICAgICAqIEB0eXBlIHtNYXA8c3RyaW5nLCBTZXQ8YW55Pj59XG4gICAgICovXG4gICAgdGhpcy5fb2JzZXJ2ZXJzID0gbWFwLmNyZWF0ZSgpXG4gIH1cblxuICAvKipcbiAgICogQHRlbXBsYXRlIHtrZXlvZiBFVkVOVFMgJiBzdHJpbmd9IE5BTUVcbiAgICogQHBhcmFtIHtOQU1FfSBuYW1lXG4gICAqIEBwYXJhbSB7RVZFTlRTW05BTUVdfSBmXG4gICAqL1xuICBvbiAobmFtZSwgZikge1xuICAgIG1hcC5zZXRJZlVuZGVmaW5lZCh0aGlzLl9vYnNlcnZlcnMsIC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAobmFtZSksIHNldC5jcmVhdGUpLmFkZChmKVxuICAgIHJldHVybiBmXG4gIH1cblxuICAvKipcbiAgICogQHRlbXBsYXRlIHtrZXlvZiBFVkVOVFMgJiBzdHJpbmd9IE5BTUVcbiAgICogQHBhcmFtIHtOQU1FfSBuYW1lXG4gICAqIEBwYXJhbSB7RVZFTlRTW05BTUVdfSBmXG4gICAqL1xuICBvbmNlIChuYW1lLCBmKSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtICB7Li4uYW55fSBhcmdzXG4gICAgICovXG4gICAgY29uc3QgX2YgPSAoLi4uYXJncykgPT4ge1xuICAgICAgdGhpcy5vZmYobmFtZSwgLyoqIEB0eXBlIHthbnl9ICovIChfZikpXG4gICAgICBmKC4uLmFyZ3MpXG4gICAgfVxuICAgIHRoaXMub24obmFtZSwgLyoqIEB0eXBlIHthbnl9ICovIChfZikpXG4gIH1cblxuICAvKipcbiAgICogQHRlbXBsYXRlIHtrZXlvZiBFVkVOVFMgJiBzdHJpbmd9IE5BTUVcbiAgICogQHBhcmFtIHtOQU1FfSBuYW1lXG4gICAqIEBwYXJhbSB7RVZFTlRTW05BTUVdfSBmXG4gICAqL1xuICBvZmYgKG5hbWUsIGYpIHtcbiAgICBjb25zdCBvYnNlcnZlcnMgPSB0aGlzLl9vYnNlcnZlcnMuZ2V0KG5hbWUpXG4gICAgaWYgKG9ic2VydmVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBvYnNlcnZlcnMuZGVsZXRlKGYpXG4gICAgICBpZiAob2JzZXJ2ZXJzLnNpemUgPT09IDApIHtcbiAgICAgICAgdGhpcy5fb2JzZXJ2ZXJzLmRlbGV0ZShuYW1lKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0IGEgbmFtZWQgZXZlbnQuIEFsbCByZWdpc3RlcmVkIGV2ZW50IGxpc3RlbmVycyB0aGF0IGxpc3RlbiB0byB0aGVcbiAgICogc3BlY2lmaWVkIG5hbWUgd2lsbCByZWNlaXZlIHRoZSBldmVudC5cbiAgICpcbiAgICogQHRvZG8gVGhpcyBzaG91bGQgY2F0Y2ggZXhjZXB0aW9uc1xuICAgKlxuICAgKiBAdGVtcGxhdGUge2tleW9mIEVWRU5UUyAmIHN0cmluZ30gTkFNRVxuICAgKiBAcGFyYW0ge05BTUV9IG5hbWUgVGhlIGV2ZW50IG5hbWUuXG4gICAqIEBwYXJhbSB7UGFyYW1ldGVyczxFVkVOVFNbTkFNRV0+fSBhcmdzIFRoZSBhcmd1bWVudHMgdGhhdCBhcmUgYXBwbGllZCB0byB0aGUgZXZlbnQgbGlzdGVuZXIuXG4gICAqL1xuICBlbWl0IChuYW1lLCBhcmdzKSB7XG4gICAgLy8gY29weSBhbGwgbGlzdGVuZXJzIHRvIGFuIGFycmF5IGZpcnN0IHRvIG1ha2Ugc3VyZSB0aGF0IG5vIGV2ZW50IGlzIGVtaXR0ZWQgdG8gbGlzdGVuZXJzIHRoYXQgYXJlIHN1YnNjcmliZWQgd2hpbGUgdGhlIGV2ZW50IGhhbmRsZXIgaXMgY2FsbGVkLlxuICAgIHJldHVybiBhcnJheS5mcm9tKCh0aGlzLl9vYnNlcnZlcnMuZ2V0KG5hbWUpIHx8IG1hcC5jcmVhdGUoKSkudmFsdWVzKCkpLmZvckVhY2goZiA9PiBmKC4uLmFyZ3MpKVxuICB9XG5cbiAgZGVzdHJveSAoKSB7XG4gICAgdGhpcy5fb2JzZXJ2ZXJzID0gbWFwLmNyZWF0ZSgpXG4gIH1cbn1cblxuLyogYzggaWdub3JlIHN0YXJ0ICovXG4vKipcbiAqIEhhbmRsZXMgbmFtZWQgZXZlbnRzLlxuICpcbiAqIEBkZXByZWNhdGVkXG4gKiBAdGVtcGxhdGUgTlxuICovXG5leHBvcnQgY2xhc3MgT2JzZXJ2YWJsZSB7XG4gIGNvbnN0cnVjdG9yICgpIHtcbiAgICAvKipcbiAgICAgKiBTb21lIGRlc2MuXG4gICAgICogQHR5cGUge01hcDxOLCBhbnk+fVxuICAgICAqL1xuICAgIHRoaXMuX29ic2VydmVycyA9IG1hcC5jcmVhdGUoKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Tn0gbmFtZVxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBmXG4gICAqL1xuICBvbiAobmFtZSwgZikge1xuICAgIG1hcC5zZXRJZlVuZGVmaW5lZCh0aGlzLl9vYnNlcnZlcnMsIG5hbWUsIHNldC5jcmVhdGUpLmFkZChmKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Tn0gbmFtZVxuICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBmXG4gICAqL1xuICBvbmNlIChuYW1lLCBmKSB7XG4gICAgLyoqXG4gICAgICogQHBhcmFtICB7Li4uYW55fSBhcmdzXG4gICAgICovXG4gICAgY29uc3QgX2YgPSAoLi4uYXJncykgPT4ge1xuICAgICAgdGhpcy5vZmYobmFtZSwgX2YpXG4gICAgICBmKC4uLmFyZ3MpXG4gICAgfVxuICAgIHRoaXMub24obmFtZSwgX2YpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtOfSBuYW1lXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb259IGZcbiAgICovXG4gIG9mZiAobmFtZSwgZikge1xuICAgIGNvbnN0IG9ic2VydmVycyA9IHRoaXMuX29ic2VydmVycy5nZXQobmFtZSlcbiAgICBpZiAob2JzZXJ2ZXJzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG9ic2VydmVycy5kZWxldGUoZilcbiAgICAgIGlmIChvYnNlcnZlcnMuc2l6ZSA9PT0gMCkge1xuICAgICAgICB0aGlzLl9vYnNlcnZlcnMuZGVsZXRlKG5hbWUpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVtaXQgYSBuYW1lZCBldmVudC4gQWxsIHJlZ2lzdGVyZWQgZXZlbnQgbGlzdGVuZXJzIHRoYXQgbGlzdGVuIHRvIHRoZVxuICAgKiBzcGVjaWZpZWQgbmFtZSB3aWxsIHJlY2VpdmUgdGhlIGV2ZW50LlxuICAgKlxuICAgKiBAdG9kbyBUaGlzIHNob3VsZCBjYXRjaCBleGNlcHRpb25zXG4gICAqXG4gICAqIEBwYXJhbSB7Tn0gbmFtZSBUaGUgZXZlbnQgbmFtZS5cbiAgICogQHBhcmFtIHtBcnJheTxhbnk+fSBhcmdzIFRoZSBhcmd1bWVudHMgdGhhdCBhcmUgYXBwbGllZCB0byB0aGUgZXZlbnQgbGlzdGVuZXIuXG4gICAqL1xuICBlbWl0IChuYW1lLCBhcmdzKSB7XG4gICAgLy8gY29weSBhbGwgbGlzdGVuZXJzIHRvIGFuIGFycmF5IGZpcnN0IHRvIG1ha2Ugc3VyZSB0aGF0IG5vIGV2ZW50IGlzIGVtaXR0ZWQgdG8gbGlzdGVuZXJzIHRoYXQgYXJlIHN1YnNjcmliZWQgd2hpbGUgdGhlIGV2ZW50IGhhbmRsZXIgaXMgY2FsbGVkLlxuICAgIHJldHVybiBhcnJheS5mcm9tKCh0aGlzLl9vYnNlcnZlcnMuZ2V0KG5hbWUpIHx8IG1hcC5jcmVhdGUoKSkudmFsdWVzKCkpLmZvckVhY2goZiA9PiBmKC4uLmFyZ3MpKVxuICB9XG5cbiAgZGVzdHJveSAoKSB7XG4gICAgdGhpcy5fb2JzZXJ2ZXJzID0gbWFwLmNyZWF0ZSgpXG4gIH1cbn1cbi8qIGM4IGlnbm9yZSBlbmQgKi9cbiIsICIvKipcbiAqIENvbW1vbiBNYXRoIGV4cHJlc3Npb25zLlxuICpcbiAqIEBtb2R1bGUgbWF0aFxuICovXG5cbmV4cG9ydCBjb25zdCBmbG9vciA9IE1hdGguZmxvb3JcbmV4cG9ydCBjb25zdCBjZWlsID0gTWF0aC5jZWlsXG5leHBvcnQgY29uc3QgYWJzID0gTWF0aC5hYnNcbmV4cG9ydCBjb25zdCBpbXVsID0gTWF0aC5pbXVsXG5leHBvcnQgY29uc3Qgcm91bmQgPSBNYXRoLnJvdW5kXG5leHBvcnQgY29uc3QgbG9nMTAgPSBNYXRoLmxvZzEwXG5leHBvcnQgY29uc3QgbG9nMiA9IE1hdGgubG9nMlxuZXhwb3J0IGNvbnN0IGxvZyA9IE1hdGgubG9nXG5leHBvcnQgY29uc3Qgc3FydCA9IE1hdGguc3FydFxuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGFcbiAqIEBwYXJhbSB7bnVtYmVyfSBiXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBzdW0gb2YgYSBhbmQgYlxuICovXG5leHBvcnQgY29uc3QgYWRkID0gKGEsIGIpID0+IGEgKyBiXG5cbi8qKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gYVxuICogQHBhcmFtIHtudW1iZXJ9IGJcbiAqIEByZXR1cm4ge251bWJlcn0gVGhlIHNtYWxsZXIgZWxlbWVudCBvZiBhIGFuZCBiXG4gKi9cbmV4cG9ydCBjb25zdCBtaW4gPSAoYSwgYikgPT4gYSA8IGIgPyBhIDogYlxuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IGFcbiAqIEBwYXJhbSB7bnVtYmVyfSBiXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBiaWdnZXIgZWxlbWVudCBvZiBhIGFuZCBiXG4gKi9cbmV4cG9ydCBjb25zdCBtYXggPSAoYSwgYikgPT4gYSA+IGIgPyBhIDogYlxuXG5leHBvcnQgY29uc3QgaXNOYU4gPSBOdW1iZXIuaXNOYU5cblxuZXhwb3J0IGNvbnN0IHBvdyA9IE1hdGgucG93XG4vKipcbiAqIEJhc2UgMTAgZXhwb25lbnRpYWwgZnVuY3Rpb24uIFJldHVybnMgdGhlIHZhbHVlIG9mIDEwIHJhaXNlZCB0byB0aGUgcG93ZXIgb2YgcG93LlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBleHBcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuZXhwb3J0IGNvbnN0IGV4cDEwID0gZXhwID0+IE1hdGgucG93KDEwLCBleHApXG5cbmV4cG9ydCBjb25zdCBzaWduID0gTWF0aC5zaWduXG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciBuIGlzIG5lZ2F0aXZlLCB3aGlsZSBjb25zaWRlcmluZyB0aGUgLTAgZWRnZSBjYXNlLiBXaGlsZSBgLTAgPCAwYCBpcyBmYWxzZSwgdGhpc1xuICogZnVuY3Rpb24gcmV0dXJucyB0cnVlIGZvciAtMCwtMSwsLi4gYW5kIHJldHVybnMgZmFsc2UgZm9yIDAsMSwyLC4uLlxuICogQHBhcmFtIHtudW1iZXJ9IG5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdldGhlciBuIGlzIG5lZ2F0aXZlLiBUaGlzIGZ1bmN0aW9uIGFsc28gZGlzdGluZ3Vpc2hlcyBiZXR3ZWVuIC0wIGFuZCArMFxuICovXG5leHBvcnQgY29uc3QgaXNOZWdhdGl2ZVplcm8gPSBuID0+IG4gIT09IDAgPyBuIDwgMCA6IDEgLyBuIDwgMFxuIiwgIi8qIGVzbGludC1lbnYgYnJvd3NlciAqL1xuXG4vKipcbiAqIEJpbmFyeSBkYXRhIGNvbnN0YW50cy5cbiAqXG4gKiBAbW9kdWxlIGJpbmFyeVxuICovXG5cbi8qKlxuICogbi10aCBiaXQgYWN0aXZhdGVkLlxuICpcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBjb25zdCBCSVQxID0gMVxuZXhwb3J0IGNvbnN0IEJJVDIgPSAyXG5leHBvcnQgY29uc3QgQklUMyA9IDRcbmV4cG9ydCBjb25zdCBCSVQ0ID0gOFxuZXhwb3J0IGNvbnN0IEJJVDUgPSAxNlxuZXhwb3J0IGNvbnN0IEJJVDYgPSAzMlxuZXhwb3J0IGNvbnN0IEJJVDcgPSA2NFxuZXhwb3J0IGNvbnN0IEJJVDggPSAxMjhcbmV4cG9ydCBjb25zdCBCSVQ5ID0gMjU2XG5leHBvcnQgY29uc3QgQklUMTAgPSA1MTJcbmV4cG9ydCBjb25zdCBCSVQxMSA9IDEwMjRcbmV4cG9ydCBjb25zdCBCSVQxMiA9IDIwNDhcbmV4cG9ydCBjb25zdCBCSVQxMyA9IDQwOTZcbmV4cG9ydCBjb25zdCBCSVQxNCA9IDgxOTJcbmV4cG9ydCBjb25zdCBCSVQxNSA9IDE2Mzg0XG5leHBvcnQgY29uc3QgQklUMTYgPSAzMjc2OFxuZXhwb3J0IGNvbnN0IEJJVDE3ID0gNjU1MzZcbmV4cG9ydCBjb25zdCBCSVQxOCA9IDEgPDwgMTdcbmV4cG9ydCBjb25zdCBCSVQxOSA9IDEgPDwgMThcbmV4cG9ydCBjb25zdCBCSVQyMCA9IDEgPDwgMTlcbmV4cG9ydCBjb25zdCBCSVQyMSA9IDEgPDwgMjBcbmV4cG9ydCBjb25zdCBCSVQyMiA9IDEgPDwgMjFcbmV4cG9ydCBjb25zdCBCSVQyMyA9IDEgPDwgMjJcbmV4cG9ydCBjb25zdCBCSVQyNCA9IDEgPDwgMjNcbmV4cG9ydCBjb25zdCBCSVQyNSA9IDEgPDwgMjRcbmV4cG9ydCBjb25zdCBCSVQyNiA9IDEgPDwgMjVcbmV4cG9ydCBjb25zdCBCSVQyNyA9IDEgPDwgMjZcbmV4cG9ydCBjb25zdCBCSVQyOCA9IDEgPDwgMjdcbmV4cG9ydCBjb25zdCBCSVQyOSA9IDEgPDwgMjhcbmV4cG9ydCBjb25zdCBCSVQzMCA9IDEgPDwgMjlcbmV4cG9ydCBjb25zdCBCSVQzMSA9IDEgPDwgMzBcbmV4cG9ydCBjb25zdCBCSVQzMiA9IDEgPDwgMzFcblxuLyoqXG4gKiBGaXJzdCBuIGJpdHMgYWN0aXZhdGVkLlxuICpcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBjb25zdCBCSVRTMCA9IDBcbmV4cG9ydCBjb25zdCBCSVRTMSA9IDFcbmV4cG9ydCBjb25zdCBCSVRTMiA9IDNcbmV4cG9ydCBjb25zdCBCSVRTMyA9IDdcbmV4cG9ydCBjb25zdCBCSVRTNCA9IDE1XG5leHBvcnQgY29uc3QgQklUUzUgPSAzMVxuZXhwb3J0IGNvbnN0IEJJVFM2ID0gNjNcbmV4cG9ydCBjb25zdCBCSVRTNyA9IDEyN1xuZXhwb3J0IGNvbnN0IEJJVFM4ID0gMjU1XG5leHBvcnQgY29uc3QgQklUUzkgPSA1MTFcbmV4cG9ydCBjb25zdCBCSVRTMTAgPSAxMDIzXG5leHBvcnQgY29uc3QgQklUUzExID0gMjA0N1xuZXhwb3J0IGNvbnN0IEJJVFMxMiA9IDQwOTVcbmV4cG9ydCBjb25zdCBCSVRTMTMgPSA4MTkxXG5leHBvcnQgY29uc3QgQklUUzE0ID0gMTYzODNcbmV4cG9ydCBjb25zdCBCSVRTMTUgPSAzMjc2N1xuZXhwb3J0IGNvbnN0IEJJVFMxNiA9IDY1NTM1XG5leHBvcnQgY29uc3QgQklUUzE3ID0gQklUMTggLSAxXG5leHBvcnQgY29uc3QgQklUUzE4ID0gQklUMTkgLSAxXG5leHBvcnQgY29uc3QgQklUUzE5ID0gQklUMjAgLSAxXG5leHBvcnQgY29uc3QgQklUUzIwID0gQklUMjEgLSAxXG5leHBvcnQgY29uc3QgQklUUzIxID0gQklUMjIgLSAxXG5leHBvcnQgY29uc3QgQklUUzIyID0gQklUMjMgLSAxXG5leHBvcnQgY29uc3QgQklUUzIzID0gQklUMjQgLSAxXG5leHBvcnQgY29uc3QgQklUUzI0ID0gQklUMjUgLSAxXG5leHBvcnQgY29uc3QgQklUUzI1ID0gQklUMjYgLSAxXG5leHBvcnQgY29uc3QgQklUUzI2ID0gQklUMjcgLSAxXG5leHBvcnQgY29uc3QgQklUUzI3ID0gQklUMjggLSAxXG5leHBvcnQgY29uc3QgQklUUzI4ID0gQklUMjkgLSAxXG5leHBvcnQgY29uc3QgQklUUzI5ID0gQklUMzAgLSAxXG5leHBvcnQgY29uc3QgQklUUzMwID0gQklUMzEgLSAxXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBjb25zdCBCSVRTMzEgPSAweDdGRkZGRkZGXG4vKipcbiAqIEB0eXBlIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBjb25zdCBCSVRTMzIgPSAweEZGRkZGRkZGXG4iLCAiLyoqXG4gKiBVdGlsaXR5IGhlbHBlcnMgZm9yIHdvcmtpbmcgd2l0aCBudW1iZXJzLlxuICpcbiAqIEBtb2R1bGUgbnVtYmVyXG4gKi9cblxuaW1wb3J0ICogYXMgbWF0aCBmcm9tICcuL21hdGguanMnXG5pbXBvcnQgKiBhcyBiaW5hcnkgZnJvbSAnLi9iaW5hcnkuanMnXG5cbmV4cG9ydCBjb25zdCBNQVhfU0FGRV9JTlRFR0VSID0gTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVJcbmV4cG9ydCBjb25zdCBNSU5fU0FGRV9JTlRFR0VSID0gTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVJcblxuZXhwb3J0IGNvbnN0IExPV0VTVF9JTlQzMiA9IDEgPDwgMzFcbmV4cG9ydCBjb25zdCBISUdIRVNUX0lOVDMyID0gYmluYXJ5LkJJVFMzMVxuZXhwb3J0IGNvbnN0IEhJR0hFU1RfVUlOVDMyID0gYmluYXJ5LkJJVFMzMlxuXG4vKiBjOCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0IGNvbnN0IGlzSW50ZWdlciA9IE51bWJlci5pc0ludGVnZXIgfHwgKG51bSA9PiB0eXBlb2YgbnVtID09PSAnbnVtYmVyJyAmJiBpc0Zpbml0ZShudW0pICYmIG1hdGguZmxvb3IobnVtKSA9PT0gbnVtKVxuZXhwb3J0IGNvbnN0IGlzTmFOID0gTnVtYmVyLmlzTmFOXG5leHBvcnQgY29uc3QgcGFyc2VJbnQgPSBOdW1iZXIucGFyc2VJbnRcblxuLyoqXG4gKiBDb3VudCB0aGUgbnVtYmVyIG9mIFwiMVwiIGJpdHMgaW4gYW4gdW5zaWduZWQgMzJiaXQgbnVtYmVyLlxuICpcbiAqIFN1cGVyIGZ1biBiaXRjb3VudCBhbGdvcml0aG0gYnkgQnJpYW4gS2VybmlnaGFuLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBuXG4gKi9cbmV4cG9ydCBjb25zdCBjb3VudEJpdHMgPSBuID0+IHtcbiAgbiAmPSBiaW5hcnkuQklUUzMyXG4gIGxldCBjb3VudCA9IDBcbiAgd2hpbGUgKG4pIHtcbiAgICBuICY9IChuIC0gMSlcbiAgICBjb3VudCsrXG4gIH1cbiAgcmV0dXJuIGNvdW50XG59XG4iLCAiaW1wb3J0ICogYXMgYXJyYXkgZnJvbSAnLi9hcnJheS5qcydcblxuLyoqXG4gKiBVdGlsaXR5IG1vZHVsZSB0byB3b3JrIHdpdGggc3RyaW5ncy5cbiAqXG4gKiBAbW9kdWxlIHN0cmluZ1xuICovXG5cbmV4cG9ydCBjb25zdCBmcm9tQ2hhckNvZGUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlXG5leHBvcnQgY29uc3QgZnJvbUNvZGVQb2ludCA9IFN0cmluZy5mcm9tQ29kZVBvaW50XG5cbi8qKlxuICogVGhlIGxhcmdlc3QgdXRmMTYgY2hhcmFjdGVyLlxuICogQ29ycmVzcG9uZHMgdG8gVWludDhBcnJheShbMjU1LCAyNTVdKSBvciBjaGFyY29kZW9mKDJ4Ml44KVxuICovXG5leHBvcnQgY29uc3QgTUFYX1VURjE2X0NIQVJBQ1RFUiA9IGZyb21DaGFyQ29kZSg2NTUzNSlcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gc1xuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5jb25zdCB0b0xvd2VyQ2FzZSA9IHMgPT4gcy50b0xvd2VyQ2FzZSgpXG5cbmNvbnN0IHRyaW1MZWZ0UmVnZXggPSAvXlxccyovZ1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBjb25zdCB0cmltTGVmdCA9IHMgPT4gcy5yZXBsYWNlKHRyaW1MZWZ0UmVnZXgsICcnKVxuXG5jb25zdCBmcm9tQ2FtZWxDYXNlUmVnZXggPSAvKFtBLVpdKS9nXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHNcbiAqIEBwYXJhbSB7c3RyaW5nfSBzZXBhcmF0b3JcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IGZyb21DYW1lbENhc2UgPSAocywgc2VwYXJhdG9yKSA9PiB0cmltTGVmdChzLnJlcGxhY2UoZnJvbUNhbWVsQ2FzZVJlZ2V4LCBtYXRjaCA9PiBgJHtzZXBhcmF0b3J9JHt0b0xvd2VyQ2FzZShtYXRjaCl9YCkpXG5cbi8qKlxuICogQ29tcHV0ZSB0aGUgdXRmOEJ5dGVMZW5ndGhcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuZXhwb3J0IGNvbnN0IHV0ZjhCeXRlTGVuZ3RoID0gc3RyID0+IHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChzdHIpKS5sZW5ndGhcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5PEFycmF5QnVmZmVyPn1cbiAqL1xuZXhwb3J0IGNvbnN0IF9lbmNvZGVVdGY4UG9seWZpbGwgPSBzdHIgPT4ge1xuICBjb25zdCBlbmNvZGVkU3RyaW5nID0gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHN0cikpXG4gIGNvbnN0IGxlbiA9IGVuY29kZWRTdHJpbmcubGVuZ3RoXG4gIGNvbnN0IGJ1ZiA9IG5ldyBVaW50OEFycmF5KGxlbilcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGJ1ZltpXSA9IC8qKiBAdHlwZSB7bnVtYmVyfSAqLyAoZW5jb2RlZFN0cmluZy5jb2RlUG9pbnRBdChpKSlcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbi8qIGM4IGlnbm9yZSBuZXh0ICovXG5leHBvcnQgY29uc3QgdXRmOFRleHRFbmNvZGVyID0gLyoqIEB0eXBlIHtUZXh0RW5jb2Rlcn0gKi8gKHR5cGVvZiBUZXh0RW5jb2RlciAhPT0gJ3VuZGVmaW5lZCcgPyBuZXcgVGV4dEVuY29kZXIoKSA6IG51bGwpXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICogQHJldHVybiB7VWludDhBcnJheTxBcnJheUJ1ZmZlcj59XG4gKi9cbmV4cG9ydCBjb25zdCBfZW5jb2RlVXRmOE5hdGl2ZSA9IHN0ciA9PiB1dGY4VGV4dEVuY29kZXIuZW5jb2RlKHN0cilcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICovXG4vKiBjOCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0IGNvbnN0IGVuY29kZVV0ZjggPSB1dGY4VGV4dEVuY29kZXIgPyBfZW5jb2RlVXRmOE5hdGl2ZSA6IF9lbmNvZGVVdGY4UG9seWZpbGxcblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgX2RlY29kZVV0ZjhQb2x5ZmlsbCA9IGJ1ZiA9PiB7XG4gIGxldCByZW1haW5pbmdMZW4gPSBidWYubGVuZ3RoXG4gIGxldCBlbmNvZGVkU3RyaW5nID0gJydcbiAgbGV0IGJ1ZlBvcyA9IDBcbiAgd2hpbGUgKHJlbWFpbmluZ0xlbiA+IDApIHtcbiAgICBjb25zdCBuZXh0TGVuID0gcmVtYWluaW5nTGVuIDwgMTAwMDAgPyByZW1haW5pbmdMZW4gOiAxMDAwMFxuICAgIGNvbnN0IGJ5dGVzID0gYnVmLnN1YmFycmF5KGJ1ZlBvcywgYnVmUG9zICsgbmV4dExlbilcbiAgICBidWZQb3MgKz0gbmV4dExlblxuICAgIC8vIFN0YXJ0aW5nIHdpdGggRVM1LjEgd2UgY2FuIHN1cHBseSBhIGdlbmVyaWMgYXJyYXktbGlrZSBvYmplY3QgYXMgYXJndW1lbnRzXG4gICAgZW5jb2RlZFN0cmluZyArPSBTdHJpbmcuZnJvbUNvZGVQb2ludC5hcHBseShudWxsLCAvKiogQHR5cGUge2FueX0gKi8gKGJ5dGVzKSlcbiAgICByZW1haW5pbmdMZW4gLT0gbmV4dExlblxuICB9XG4gIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKGVuY29kZWRTdHJpbmcpKVxufVxuXG4vKiBjOCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0IGxldCB1dGY4VGV4dERlY29kZXIgPSB0eXBlb2YgVGV4dERlY29kZXIgPT09ICd1bmRlZmluZWQnID8gbnVsbCA6IG5ldyBUZXh0RGVjb2RlcigndXRmLTgnLCB7IGZhdGFsOiB0cnVlLCBpZ25vcmVCT006IHRydWUgfSlcblxuLyogYzggaWdub3JlIHN0YXJ0ICovXG5pZiAodXRmOFRleHREZWNvZGVyICYmIHV0ZjhUZXh0RGVjb2Rlci5kZWNvZGUobmV3IFVpbnQ4QXJyYXkoKSkubGVuZ3RoID09PSAxKSB7XG4gIC8vIFNhZmFyaSBkb2Vzbid0IGhhbmRsZSBCT00gY29ycmVjdGx5LlxuICAvLyBUaGlzIGZpeGVzIGEgYnVnIGluIFNhZmFyaSAxMy4wLjUgd2hlcmUgaXQgcHJvZHVjZXMgYSBCT00gdGhlIGZpcnN0IHRpbWUgaXQgaXMgY2FsbGVkLlxuICAvLyB1dGY4VGV4dERlY29kZXIuZGVjb2RlKG5ldyBVaW50OEFycmF5KCkpLmxlbmd0aCA9PT0gMSBvbiB0aGUgZmlyc3QgY2FsbCBhbmRcbiAgLy8gdXRmOFRleHREZWNvZGVyLmRlY29kZShuZXcgVWludDhBcnJheSgpKS5sZW5ndGggPT09IDEgb24gdGhlIHNlY29uZCBjYWxsXG4gIC8vIEFub3RoZXIgaXNzdWUgaXMgdGhhdCBmcm9tIHRoZW4gb24gbm8gQk9NIGNoYXJzIGFyZSByZWNvZ25pemVkIGFueW1vcmVcbiAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgdXRmOFRleHREZWNvZGVyID0gbnVsbFxufVxuLyogYzggaWdub3JlIHN0b3AgKi9cblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgX2RlY29kZVV0ZjhOYXRpdmUgPSBidWYgPT4gLyoqIEB0eXBlIHtUZXh0RGVjb2Rlcn0gKi8gKHV0ZjhUZXh0RGVjb2RlcikuZGVjb2RlKGJ1ZilcblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZlxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG4vKiBjOCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0IGNvbnN0IGRlY29kZVV0ZjggPSB1dGY4VGV4dERlY29kZXIgPyBfZGVjb2RlVXRmOE5hdGl2ZSA6IF9kZWNvZGVVdGY4UG9seWZpbGxcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSBpbml0aWFsIHN0cmluZ1xuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFN0YXJ0aW5nIHBvc2l0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gcmVtb3ZlIE51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHJlbW92ZVxuICogQHBhcmFtIHtzdHJpbmd9IGluc2VydCBOZXcgY29udGVudCB0byBpbnNlcnRcbiAqL1xuZXhwb3J0IGNvbnN0IHNwbGljZSA9IChzdHIsIGluZGV4LCByZW1vdmUsIGluc2VydCA9ICcnKSA9PiBzdHIuc2xpY2UoMCwgaW5kZXgpICsgaW5zZXJ0ICsgc3RyLnNsaWNlKGluZGV4ICsgcmVtb3ZlKVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2VcbiAqIEBwYXJhbSB7bnVtYmVyfSBuXG4gKi9cbmV4cG9ydCBjb25zdCByZXBlYXQgPSAoc291cmNlLCBuKSA9PiBhcnJheS51bmZvbGQobiwgKCkgPT4gc291cmNlKS5qb2luKCcnKVxuXG4vKipcbiAqIEVzY2FwZSBIVE1MIGNoYXJhY3RlcnMgJiw8LD4sJyxcIiB0byB0aGVpciByZXNwZWN0aXZlIEhUTUwgZW50aXRpZXMgJmFtcDssJmx0OywmZ3Q7LCYjMzk7LCZxdW90O1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqL1xuZXhwb3J0IGNvbnN0IGVzY2FwZUhUTUwgPSBzdHIgPT5cbiAgc3RyLnJlcGxhY2UoL1smPD4nXCJdL2csIHIgPT4gLyoqIEB0eXBlIHtzdHJpbmd9ICovICh7XG4gICAgJyYnOiAnJmFtcDsnLFxuICAgICc8JzogJyZsdDsnLFxuICAgICc+JzogJyZndDsnLFxuICAgIFwiJ1wiOiAnJiMzOTsnLFxuICAgICdcIic6ICcmcXVvdDsnXG4gIH1bcl0pKVxuXG4vKipcbiAqIFJldmVyc2Ugb2YgYGVzY2FwZUhUTUxgXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICovXG5leHBvcnQgY29uc3QgdW5lc2NhcGVIVE1MID0gc3RyID0+XG4gIHN0ci5yZXBsYWNlKC8mYW1wO3wmbHQ7fCZndDt8JiMzOTt8JnF1b3Q7L2csIHIgPT4gLyoqIEB0eXBlIHtzdHJpbmd9ICovICh7XG4gICAgJyZhbXA7JzogJyYnLFxuICAgICcmbHQ7JzogJzwnLFxuICAgICcmZ3Q7JzogJz4nLFxuICAgICcmIzM5Oyc6IFwiJ1wiLFxuICAgICcmcXVvdDsnOiAnXCInXG4gIH1bcl0pKVxuIiwgIi8qKlxuICogRWZmaWNpZW50IHNjaGVtYS1sZXNzIGJpbmFyeSBlbmNvZGluZyB3aXRoIHN1cHBvcnQgZm9yIHZhcmlhYmxlIGxlbmd0aCBlbmNvZGluZy5cbiAqXG4gKiBVc2UgW2xpYjAvZW5jb2RpbmddIHdpdGggW2xpYjAvZGVjb2RpbmddLiBFdmVyeSBlbmNvZGluZyBmdW5jdGlvbiBoYXMgYSBjb3JyZXNwb25kaW5nIGRlY29kaW5nIGZ1bmN0aW9uLlxuICpcbiAqIEVuY29kZXMgbnVtYmVycyBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyIChsZWFzdCB0byBtb3N0IHNpZ25pZmljYW50IGJ5dGUgb3JkZXIpXG4gKiBhbmQgaXMgY29tcGF0aWJsZSB3aXRoIEdvbGFuZydzIGJpbmFyeSBlbmNvZGluZyAoaHR0cHM6Ly9nb2xhbmcub3JnL3BrZy9lbmNvZGluZy9iaW5hcnkvKVxuICogd2hpY2ggaXMgYWxzbyB1c2VkIGluIFByb3RvY29sIEJ1ZmZlcnMuXG4gKlxuICogYGBganNcbiAqIC8vIGVuY29kaW5nIHN0ZXBcbiAqIGNvbnN0IGVuY29kZXIgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKClcbiAqIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLCAyNTYpXG4gKiBlbmNvZGluZy53cml0ZVZhclN0cmluZyhlbmNvZGVyLCAnSGVsbG8gd29ybGQhJylcbiAqIGNvbnN0IGJ1ZiA9IGVuY29kaW5nLnRvVWludDhBcnJheShlbmNvZGVyKVxuICogYGBgXG4gKlxuICogYGBganNcbiAqIC8vIGRlY29kaW5nIHN0ZXBcbiAqIGNvbnN0IGRlY29kZXIgPSBkZWNvZGluZy5jcmVhdGVEZWNvZGVyKGJ1ZilcbiAqIGRlY29kaW5nLnJlYWRWYXJVaW50KGRlY29kZXIpIC8vID0+IDI1NlxuICogZGVjb2RpbmcucmVhZFZhclN0cmluZyhkZWNvZGVyKSAvLyA9PiAnSGVsbG8gd29ybGQhJ1xuICogZGVjb2RpbmcuaGFzQ29udGVudChkZWNvZGVyKSAvLyA9PiBmYWxzZSAtIGFsbCBkYXRhIGlzIHJlYWRcbiAqIGBgYFxuICpcbiAqIEBtb2R1bGUgZW5jb2RpbmdcbiAqL1xuXG5pbXBvcnQgKiBhcyBtYXRoIGZyb20gJy4vbWF0aC5qcydcbmltcG9ydCAqIGFzIG51bWJlciBmcm9tICcuL251bWJlci5qcydcbmltcG9ydCAqIGFzIGJpbmFyeSBmcm9tICcuL2JpbmFyeS5qcydcbmltcG9ydCAqIGFzIHN0cmluZyBmcm9tICcuL3N0cmluZy5qcydcbmltcG9ydCAqIGFzIGFycmF5IGZyb20gJy4vYXJyYXkuanMnXG5cbi8qKlxuICogQSBCaW5hcnlFbmNvZGVyIGhhbmRsZXMgdGhlIGVuY29kaW5nIHRvIGFuIFVpbnQ4QXJyYXkuXG4gKi9cbmV4cG9ydCBjbGFzcyBFbmNvZGVyIHtcbiAgY29uc3RydWN0b3IgKCkge1xuICAgIHRoaXMuY3BvcyA9IDBcbiAgICB0aGlzLmNidWYgPSBuZXcgVWludDhBcnJheSgxMDApXG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PFVpbnQ4QXJyYXk+fVxuICAgICAqL1xuICAgIHRoaXMuYnVmcyA9IFtdXG4gIH1cbn1cblxuLyoqXG4gKiBAZnVuY3Rpb25cbiAqIEByZXR1cm4ge0VuY29kZXJ9XG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVFbmNvZGVyID0gKCkgPT4gbmV3IEVuY29kZXIoKVxuXG4vKipcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oRW5jb2Rlcik6dm9pZH0gZlxuICovXG5leHBvcnQgY29uc3QgZW5jb2RlID0gKGYpID0+IHtcbiAgY29uc3QgZW5jb2RlciA9IGNyZWF0ZUVuY29kZXIoKVxuICBmKGVuY29kZXIpXG4gIHJldHVybiB0b1VpbnQ4QXJyYXkoZW5jb2Rlcilcbn1cblxuLyoqXG4gKiBUaGUgY3VycmVudCBsZW5ndGggb2YgdGhlIGVuY29kZWQgZGF0YS5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlclxuICogQHJldHVybiB7bnVtYmVyfVxuICovXG5leHBvcnQgY29uc3QgbGVuZ3RoID0gZW5jb2RlciA9PiB7XG4gIGxldCBsZW4gPSBlbmNvZGVyLmNwb3NcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbmNvZGVyLmJ1ZnMubGVuZ3RoOyBpKyspIHtcbiAgICBsZW4gKz0gZW5jb2Rlci5idWZzW2ldLmxlbmd0aFxuICB9XG4gIHJldHVybiBsZW5cbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGVuY29kZXIgaXMgZW1wdHkuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBjb25zdCBoYXNDb250ZW50ID0gZW5jb2RlciA9PiBlbmNvZGVyLmNwb3MgPiAwIHx8IGVuY29kZXIuYnVmcy5sZW5ndGggPiAwXG5cbi8qKlxuICogVHJhbnNmb3JtIHRvIFVpbnQ4QXJyYXkuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEByZXR1cm4ge1VpbnQ4QXJyYXk8QXJyYXlCdWZmZXI+fSBUaGUgY3JlYXRlZCBBcnJheUJ1ZmZlci5cbiAqL1xuZXhwb3J0IGNvbnN0IHRvVWludDhBcnJheSA9IGVuY29kZXIgPT4ge1xuICBjb25zdCB1aW50OGFyciA9IG5ldyBVaW50OEFycmF5KGxlbmd0aChlbmNvZGVyKSlcbiAgbGV0IGN1clBvcyA9IDBcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBlbmNvZGVyLmJ1ZnMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBkID0gZW5jb2Rlci5idWZzW2ldXG4gICAgdWludDhhcnIuc2V0KGQsIGN1clBvcylcbiAgICBjdXJQb3MgKz0gZC5sZW5ndGhcbiAgfVxuICB1aW50OGFyci5zZXQobmV3IFVpbnQ4QXJyYXkoZW5jb2Rlci5jYnVmLmJ1ZmZlciwgMCwgZW5jb2Rlci5jcG9zKSwgY3VyUG9zKVxuICByZXR1cm4gdWludDhhcnJcbn1cblxuLyoqXG4gKiBWZXJpZnkgdGhhdCBpdCBpcyBwb3NzaWJsZSB0byB3cml0ZSBgbGVuYCBieXRlcyB3dGlob3V0IGNoZWNraW5nLiBJZlxuICogbmVjZXNzYXJ5LCBhIG5ldyBCdWZmZXIgd2l0aCB0aGUgcmVxdWlyZWQgbGVuZ3RoIGlzIGF0dGFjaGVkLlxuICpcbiAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlclxuICogQHBhcmFtIHtudW1iZXJ9IGxlblxuICovXG5leHBvcnQgY29uc3QgdmVyaWZ5TGVuID0gKGVuY29kZXIsIGxlbikgPT4ge1xuICBjb25zdCBidWZmZXJMZW4gPSBlbmNvZGVyLmNidWYubGVuZ3RoXG4gIGlmIChidWZmZXJMZW4gLSBlbmNvZGVyLmNwb3MgPCBsZW4pIHtcbiAgICBlbmNvZGVyLmJ1ZnMucHVzaChuZXcgVWludDhBcnJheShlbmNvZGVyLmNidWYuYnVmZmVyLCAwLCBlbmNvZGVyLmNwb3MpKVxuICAgIGVuY29kZXIuY2J1ZiA9IG5ldyBVaW50OEFycmF5KG1hdGgubWF4KGJ1ZmZlckxlbiwgbGVuKSAqIDIpXG4gICAgZW5jb2Rlci5jcG9zID0gMFxuICB9XG59XG5cbi8qKlxuICogV3JpdGUgb25lIGJ5dGUgdG8gdGhlIGVuY29kZXIuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW0gVGhlIGJ5dGUgdGhhdCBpcyB0byBiZSBlbmNvZGVkLlxuICovXG5leHBvcnQgY29uc3Qgd3JpdGUgPSAoZW5jb2RlciwgbnVtKSA9PiB7XG4gIGNvbnN0IGJ1ZmZlckxlbiA9IGVuY29kZXIuY2J1Zi5sZW5ndGhcbiAgaWYgKGVuY29kZXIuY3BvcyA9PT0gYnVmZmVyTGVuKSB7XG4gICAgZW5jb2Rlci5idWZzLnB1c2goZW5jb2Rlci5jYnVmKVxuICAgIGVuY29kZXIuY2J1ZiA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlckxlbiAqIDIpXG4gICAgZW5jb2Rlci5jcG9zID0gMFxuICB9XG4gIGVuY29kZXIuY2J1ZltlbmNvZGVyLmNwb3MrK10gPSBudW1cbn1cblxuLyoqXG4gKiBXcml0ZSBvbmUgYnl0ZSBhdCBhIHNwZWNpZmljIHBvc2l0aW9uLlxuICogUG9zaXRpb24gbXVzdCBhbHJlYWR5IGJlIHdyaXR0ZW4gKGkuZS4gZW5jb2Rlci5sZW5ndGggPiBwb3MpXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3MgUG9zaXRpb24gdG8gd2hpY2ggdG8gd3JpdGUgZGF0YVxuICogQHBhcmFtIHtudW1iZXJ9IG51bSBVbnNpZ25lZCA4LWJpdCBpbnRlZ2VyXG4gKi9cbmV4cG9ydCBjb25zdCBzZXQgPSAoZW5jb2RlciwgcG9zLCBudW0pID0+IHtcbiAgbGV0IGJ1ZmZlciA9IG51bGxcbiAgLy8gaXRlcmF0ZSBhbGwgYnVmZmVycyBhbmQgYWRqdXN0IHBvc2l0aW9uXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZW5jb2Rlci5idWZzLmxlbmd0aCAmJiBidWZmZXIgPT09IG51bGw7IGkrKykge1xuICAgIGNvbnN0IGIgPSBlbmNvZGVyLmJ1ZnNbaV1cbiAgICBpZiAocG9zIDwgYi5sZW5ndGgpIHtcbiAgICAgIGJ1ZmZlciA9IGIgLy8gZm91bmQgYnVmZmVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHBvcyAtPSBiLmxlbmd0aFxuICAgIH1cbiAgfVxuICBpZiAoYnVmZmVyID09PSBudWxsKSB7XG4gICAgLy8gdXNlIGN1cnJlbnQgYnVmZmVyXG4gICAgYnVmZmVyID0gZW5jb2Rlci5jYnVmXG4gIH1cbiAgYnVmZmVyW3Bvc10gPSBudW1cbn1cblxuLyoqXG4gKiBXcml0ZSBvbmUgYnl0ZSBhcyBhbiB1bnNpZ25lZCBpbnRlZ2VyLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtFbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtIFRoZSBudW1iZXIgdGhhdCBpcyB0byBiZSBlbmNvZGVkLlxuICovXG5leHBvcnQgY29uc3Qgd3JpdGVVaW50OCA9IHdyaXRlXG5cbi8qKlxuICogV3JpdGUgb25lIGJ5dGUgYXMgYW4gdW5zaWduZWQgSW50ZWdlciBhdCBhIHNwZWNpZmljIGxvY2F0aW9uLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtFbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFRoZSBsb2NhdGlvbiB3aGVyZSB0aGUgZGF0YSB3aWxsIGJlIHdyaXR0ZW4uXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtIFRoZSBudW1iZXIgdGhhdCBpcyB0byBiZSBlbmNvZGVkLlxuICovXG5leHBvcnQgY29uc3Qgc2V0VWludDggPSBzZXRcblxuLyoqXG4gKiBXcml0ZSB0d28gYnl0ZXMgYXMgYW4gdW5zaWduZWQgaW50ZWdlci5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlclxuICogQHBhcmFtIHtudW1iZXJ9IG51bSBUaGUgbnVtYmVyIHRoYXQgaXMgdG8gYmUgZW5jb2RlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IHdyaXRlVWludDE2ID0gKGVuY29kZXIsIG51bSkgPT4ge1xuICB3cml0ZShlbmNvZGVyLCBudW0gJiBiaW5hcnkuQklUUzgpXG4gIHdyaXRlKGVuY29kZXIsIChudW0gPj4+IDgpICYgYmluYXJ5LkJJVFM4KVxufVxuLyoqXG4gKiBXcml0ZSB0d28gYnl0ZXMgYXMgYW4gdW5zaWduZWQgaW50ZWdlciBhdCBhIHNwZWNpZmljIGxvY2F0aW9uLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtFbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFRoZSBsb2NhdGlvbiB3aGVyZSB0aGUgZGF0YSB3aWxsIGJlIHdyaXR0ZW4uXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtIFRoZSBudW1iZXIgdGhhdCBpcyB0byBiZSBlbmNvZGVkLlxuICovXG5leHBvcnQgY29uc3Qgc2V0VWludDE2ID0gKGVuY29kZXIsIHBvcywgbnVtKSA9PiB7XG4gIHNldChlbmNvZGVyLCBwb3MsIG51bSAmIGJpbmFyeS5CSVRTOClcbiAgc2V0KGVuY29kZXIsIHBvcyArIDEsIChudW0gPj4+IDgpICYgYmluYXJ5LkJJVFM4KVxufVxuXG4vKipcbiAqIFdyaXRlIHR3byBieXRlcyBhcyBhbiB1bnNpZ25lZCBpbnRlZ2VyXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW0gVGhlIG51bWJlciB0aGF0IGlzIHRvIGJlIGVuY29kZWQuXG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZVVpbnQzMiA9IChlbmNvZGVyLCBudW0pID0+IHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCA0OyBpKyspIHtcbiAgICB3cml0ZShlbmNvZGVyLCBudW0gJiBiaW5hcnkuQklUUzgpXG4gICAgbnVtID4+Pj0gOFxuICB9XG59XG5cbi8qKlxuICogV3JpdGUgdHdvIGJ5dGVzIGFzIGFuIHVuc2lnbmVkIGludGVnZXIgaW4gYmlnIGVuZGlhbiBvcmRlci5cbiAqIChtb3N0IHNpZ25pZmljYW50IGJ5dGUgZmlyc3QpXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW0gVGhlIG51bWJlciB0aGF0IGlzIHRvIGJlIGVuY29kZWQuXG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZVVpbnQzMkJpZ0VuZGlhbiA9IChlbmNvZGVyLCBudW0pID0+IHtcbiAgZm9yIChsZXQgaSA9IDM7IGkgPj0gMDsgaS0tKSB7XG4gICAgd3JpdGUoZW5jb2RlciwgKG51bSA+Pj4gKDggKiBpKSkgJiBiaW5hcnkuQklUUzgpXG4gIH1cbn1cblxuLyoqXG4gKiBXcml0ZSB0d28gYnl0ZXMgYXMgYW4gdW5zaWduZWQgaW50ZWdlciBhdCBhIHNwZWNpZmljIGxvY2F0aW9uLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtFbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge251bWJlcn0gcG9zIFRoZSBsb2NhdGlvbiB3aGVyZSB0aGUgZGF0YSB3aWxsIGJlIHdyaXR0ZW4uXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtIFRoZSBudW1iZXIgdGhhdCBpcyB0byBiZSBlbmNvZGVkLlxuICovXG5leHBvcnQgY29uc3Qgc2V0VWludDMyID0gKGVuY29kZXIsIHBvcywgbnVtKSA9PiB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgc2V0KGVuY29kZXIsIHBvcyArIGksIG51bSAmIGJpbmFyeS5CSVRTOClcbiAgICBudW0gPj4+PSA4XG4gIH1cbn1cblxuLyoqXG4gKiBXcml0ZSBhIHZhcmlhYmxlIGxlbmd0aCB1bnNpZ25lZCBpbnRlZ2VyLiBNYXggZW5jb2RhYmxlIGludGVnZXIgaXMgMl41My5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlclxuICogQHBhcmFtIHtudW1iZXJ9IG51bSBUaGUgbnVtYmVyIHRoYXQgaXMgdG8gYmUgZW5jb2RlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IHdyaXRlVmFyVWludCA9IChlbmNvZGVyLCBudW0pID0+IHtcbiAgd2hpbGUgKG51bSA+IGJpbmFyeS5CSVRTNykge1xuICAgIHdyaXRlKGVuY29kZXIsIGJpbmFyeS5CSVQ4IHwgKGJpbmFyeS5CSVRTNyAmIG51bSkpXG4gICAgbnVtID0gbWF0aC5mbG9vcihudW0gLyAxMjgpIC8vIHNoaWZ0ID4+PiA3XG4gIH1cbiAgd3JpdGUoZW5jb2RlciwgYmluYXJ5LkJJVFM3ICYgbnVtKVxufVxuXG4vKipcbiAqIFdyaXRlIGEgdmFyaWFibGUgbGVuZ3RoIGludGVnZXIuXG4gKlxuICogV2UgdXNlIHRoZSA3dGggYml0IGluc3RlYWQgZm9yIHNpZ25hbGluZyB0aGF0IHRoaXMgaXMgYSBuZWdhdGl2ZSBudW1iZXIuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSBudW0gVGhlIG51bWJlciB0aGF0IGlzIHRvIGJlIGVuY29kZWQuXG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZVZhckludCA9IChlbmNvZGVyLCBudW0pID0+IHtcbiAgY29uc3QgaXNOZWdhdGl2ZSA9IG1hdGguaXNOZWdhdGl2ZVplcm8obnVtKVxuICBpZiAoaXNOZWdhdGl2ZSkge1xuICAgIG51bSA9IC1udW1cbiAgfVxuICAvLyAgICAgICAgICAgICB8LSB3aGV0aGVyIHRvIGNvbnRpbnVlIHJlYWRpbmcgICAgICAgICB8LSB3aGV0aGVyIGlzIG5lZ2F0aXZlICAgICB8LSBudW1iZXJcbiAgd3JpdGUoZW5jb2RlciwgKG51bSA+IGJpbmFyeS5CSVRTNiA/IGJpbmFyeS5CSVQ4IDogMCkgfCAoaXNOZWdhdGl2ZSA/IGJpbmFyeS5CSVQ3IDogMCkgfCAoYmluYXJ5LkJJVFM2ICYgbnVtKSlcbiAgbnVtID0gbWF0aC5mbG9vcihudW0gLyA2NCkgLy8gc2hpZnQgPj4+IDZcbiAgLy8gV2UgZG9uJ3QgbmVlZCB0byBjb25zaWRlciB0aGUgY2FzZSBvZiBudW0gPT09IDAgc28gd2UgY2FuIHVzZSBhIGRpZmZlcmVudFxuICAvLyBwYXR0ZXJuIGhlcmUgdGhhbiBhYm92ZS5cbiAgd2hpbGUgKG51bSA+IDApIHtcbiAgICB3cml0ZShlbmNvZGVyLCAobnVtID4gYmluYXJ5LkJJVFM3ID8gYmluYXJ5LkJJVDggOiAwKSB8IChiaW5hcnkuQklUUzcgJiBudW0pKVxuICAgIG51bSA9IG1hdGguZmxvb3IobnVtIC8gMTI4KSAvLyBzaGlmdCA+Pj4gN1xuICB9XG59XG5cbi8qKlxuICogQSBjYWNoZSB0byBzdG9yZSBzdHJpbmdzIHRlbXBvcmFyaWx5XG4gKi9cbmNvbnN0IF9zdHJCdWZmZXIgPSBuZXcgVWludDhBcnJheSgzMDAwMClcbmNvbnN0IF9tYXhTdHJCU2l6ZSA9IF9zdHJCdWZmZXIubGVuZ3RoIC8gM1xuXG4vKipcbiAqIFdyaXRlIGEgdmFyaWFibGUgbGVuZ3RoIHN0cmluZy5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlclxuICogQHBhcmFtIHtTdHJpbmd9IHN0ciBUaGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgZW5jb2RlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IF93cml0ZVZhclN0cmluZ05hdGl2ZSA9IChlbmNvZGVyLCBzdHIpID0+IHtcbiAgaWYgKHN0ci5sZW5ndGggPCBfbWF4U3RyQlNpemUpIHtcbiAgICAvLyBXZSBjYW4gZW5jb2RlIHRoZSBzdHJpbmcgaW50byB0aGUgZXhpc3RpbmcgYnVmZmVyXG4gICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICBjb25zdCB3cml0dGVuID0gc3RyaW5nLnV0ZjhUZXh0RW5jb2Rlci5lbmNvZGVJbnRvKHN0ciwgX3N0ckJ1ZmZlcikud3JpdHRlbiB8fCAwXG4gICAgd3JpdGVWYXJVaW50KGVuY29kZXIsIHdyaXR0ZW4pXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB3cml0dGVuOyBpKyspIHtcbiAgICAgIHdyaXRlKGVuY29kZXIsIF9zdHJCdWZmZXJbaV0pXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHdyaXRlVmFyVWludDhBcnJheShlbmNvZGVyLCBzdHJpbmcuZW5jb2RlVXRmOChzdHIpKVxuICB9XG59XG5cbi8qKlxuICogV3JpdGUgYSB2YXJpYWJsZSBsZW5ndGggc3RyaW5nLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtFbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyIFRoZSBzdHJpbmcgdGhhdCBpcyB0byBiZSBlbmNvZGVkLlxuICovXG5leHBvcnQgY29uc3QgX3dyaXRlVmFyU3RyaW5nUG9seWZpbGwgPSAoZW5jb2Rlciwgc3RyKSA9PiB7XG4gIGNvbnN0IGVuY29kZWRTdHJpbmcgPSB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSlcbiAgY29uc3QgbGVuID0gZW5jb2RlZFN0cmluZy5sZW5ndGhcbiAgd3JpdGVWYXJVaW50KGVuY29kZXIsIGxlbilcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIHdyaXRlKGVuY29kZXIsIC8qKiBAdHlwZSB7bnVtYmVyfSAqLyAoZW5jb2RlZFN0cmluZy5jb2RlUG9pbnRBdChpKSkpXG4gIH1cbn1cblxuLyoqXG4gKiBXcml0ZSBhIHZhcmlhYmxlIGxlbmd0aCBzdHJpbmcuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgVGhlIHN0cmluZyB0aGF0IGlzIHRvIGJlIGVuY29kZWQuXG4gKi9cbi8qIGM4IGlnbm9yZSBuZXh0ICovXG5leHBvcnQgY29uc3Qgd3JpdGVWYXJTdHJpbmcgPSAoc3RyaW5nLnV0ZjhUZXh0RW5jb2RlciAmJiAvKiogQHR5cGUge2FueX0gKi8gKHN0cmluZy51dGY4VGV4dEVuY29kZXIpLmVuY29kZUludG8pID8gX3dyaXRlVmFyU3RyaW5nTmF0aXZlIDogX3dyaXRlVmFyU3RyaW5nUG9seWZpbGxcblxuLyoqXG4gKiBXcml0ZSBhIHN0cmluZyB0ZXJtaW5hdGVkIGJ5IGEgc3BlY2lhbCBieXRlIHNlcXVlbmNlLiBUaGlzIGlzIG5vdCB2ZXJ5IHBlcmZvcm1hbnQgYW5kIGlzXG4gKiBnZW5lcmFsbHkgZGlzY291cmFnZWQuIEhvd2V2ZXIsIHRoZSByZXN1bHRpbmcgYnl0ZSBhcnJheXMgYXJlIGxleGlvZ3JhcGhpY2FsbHkgb3JkZXJlZCB3aGljaFxuICogbWFrZXMgdGhpcyBhIG5pY2UgZmVhdHVyZSBmb3IgZGF0YWJhc2VzLlxuICpcbiAqIFRoZSBzdHJpbmcgd2lsbCBiZSBlbmNvZGVkIHVzaW5nIHV0ZjggYW5kIHRoZW4gdGVybWluYXRlZCBhbmQgZXNjYXBlZCB1c2luZyB3cml0ZVRlcm1pbmF0aW5nVWludDhBcnJheS5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlclxuICogQHBhcmFtIHtTdHJpbmd9IHN0ciBUaGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgZW5jb2RlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IHdyaXRlVGVybWluYXRlZFN0cmluZyA9IChlbmNvZGVyLCBzdHIpID0+XG4gIHdyaXRlVGVybWluYXRlZFVpbnQ4QXJyYXkoZW5jb2Rlciwgc3RyaW5nLmVuY29kZVV0Zjgoc3RyKSlcblxuLyoqXG4gKiBXcml0ZSBhIHRlcm1pbmF0aW5nIFVpbnQ4QXJyYXkuIE5vdGUgdGhhdCB0aGlzIGlzIG5vdCBwZXJmb3JtYW50IGFuZCBpcyBnZW5lcmFsbHlcbiAqIGRpc2NvdXJhZ2VkLiBUaGVyZSBhcmUgZmV3IHNpdHVhdGlvbnMgd2hlbiB0aGlzIGlzIG5lZWRlZC5cbiAqXG4gKiBXZSB1c2UgMHgwIGFzIGEgdGVybWluYXRpbmcgY2hhcmFjdGVyLiAweDEgc2VydmVzIGFzIGFuIGVzY2FwZSBjaGFyYWN0ZXIgZm9yIDB4MCBhbmQgMHgxLlxuICpcbiAqIEV4YW1wbGU6IFswLDEsMl0gaXMgZW5jb2RlZCB0byBbMSwwLDEsMSwyLDBdLiAweDAsIGFuZCAweDEgbmVlZGVkIHRvIGJlIGVzY2FwZWQgdXNpbmcgMHgxLiBUaGVuXG4gKiB0aGUgcmVzdWx0IGlzIHRlcm1pbmF0ZWQgdXNpbmcgdGhlIDB4MCBjaGFyYWN0ZXIuXG4gKlxuICogVGhpcyBpcyBiYXNpY2FsbHkgaG93IG1hbnkgc3lzdGVtcyBpbXBsZW1lbnQgbnVsbCB0ZXJtaW5hdGVkIHN0cmluZ3MuIEhvd2V2ZXIsIHdlIHVzZSBhbiBlc2NhcGVcbiAqIGNoYXJhY3RlciAweDEgdG8gYXZvaWQgaXNzdWVzIGFuZCBwb3RlbmlhbCBhdHRhY2tzIG9uIG91ciBkYXRhYmFzZSAoaWYgdGhpcyBpcyB1c2VkIGFzIGEga2V5XG4gKiBlbmNvZGVyIGZvciBOb1NxbCBkYXRhYmFzZXMpLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtFbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZiBUaGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgZW5jb2RlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IHdyaXRlVGVybWluYXRlZFVpbnQ4QXJyYXkgPSAoZW5jb2RlciwgYnVmKSA9PiB7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgYiA9IGJ1ZltpXVxuICAgIGlmIChiID09PSAwIHx8IGIgPT09IDEpIHtcbiAgICAgIHdyaXRlKGVuY29kZXIsIDEpXG4gICAgfVxuICAgIHdyaXRlKGVuY29kZXIsIGJ1ZltpXSlcbiAgfVxuICB3cml0ZShlbmNvZGVyLCAwKVxufVxuXG4vKipcbiAqIFdyaXRlIHRoZSBjb250ZW50IG9mIGFub3RoZXIgRW5jb2Rlci5cbiAqXG4gKiBAVE9ETzogY2FuIGJlIGltcHJvdmVkIVxuICogICAgICAgIC0gTm90ZTogU2hvdWxkIGNvbnNpZGVyIHRoYXQgd2hlbiBhcHBlbmRpbmcgYSBsb3Qgb2Ygc21hbGwgRW5jb2RlcnMsIHdlIHNob3VsZCByYXRoZXIgY2xvbmUgdGhhbiByZWZlcmVuY2luZyB0aGUgb2xkIHN0cnVjdHVyZS5cbiAqICAgICAgICAgICAgICAgIEVuY29kZXJzIHN0YXJ0IHdpdGggYSByYXRoZXIgYmlnIGluaXRpYWwgYnVmZmVyLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtFbmNvZGVyfSBlbmNvZGVyIFRoZSBlblVpbnQ4QXJyXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGFwcGVuZCBUaGUgQmluYXJ5RW5jb2RlciB0byBiZSB3cml0dGVuLlxuICovXG5leHBvcnQgY29uc3Qgd3JpdGVCaW5hcnlFbmNvZGVyID0gKGVuY29kZXIsIGFwcGVuZCkgPT4gd3JpdGVVaW50OEFycmF5KGVuY29kZXIsIHRvVWludDhBcnJheShhcHBlbmQpKVxuXG4vKipcbiAqIEFwcGVuZCBmaXhlZC1sZW5ndGggVWludDhBcnJheSB0byB0aGUgZW5jb2Rlci5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlclxuICogQHBhcmFtIHtVaW50OEFycmF5fSB1aW50OEFycmF5XG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZVVpbnQ4QXJyYXkgPSAoZW5jb2RlciwgdWludDhBcnJheSkgPT4ge1xuICBjb25zdCBidWZmZXJMZW4gPSBlbmNvZGVyLmNidWYubGVuZ3RoXG4gIGNvbnN0IGNwb3MgPSBlbmNvZGVyLmNwb3NcbiAgY29uc3QgbGVmdENvcHlMZW4gPSBtYXRoLm1pbihidWZmZXJMZW4gLSBjcG9zLCB1aW50OEFycmF5Lmxlbmd0aClcbiAgY29uc3QgcmlnaHRDb3B5TGVuID0gdWludDhBcnJheS5sZW5ndGggLSBsZWZ0Q29weUxlblxuICBlbmNvZGVyLmNidWYuc2V0KHVpbnQ4QXJyYXkuc3ViYXJyYXkoMCwgbGVmdENvcHlMZW4pLCBjcG9zKVxuICBlbmNvZGVyLmNwb3MgKz0gbGVmdENvcHlMZW5cbiAgaWYgKHJpZ2h0Q29weUxlbiA+IDApIHtcbiAgICAvLyBTdGlsbCBzb21ldGhpbmcgdG8gd3JpdGUsIHdyaXRlIHJpZ2h0IGhhbGYuLlxuICAgIC8vIEFwcGVuZCBuZXcgYnVmZmVyXG4gICAgZW5jb2Rlci5idWZzLnB1c2goZW5jb2Rlci5jYnVmKVxuICAgIC8vIG11c3QgaGF2ZSBhdCBsZWFzdCBzaXplIG9mIHJlbWFpbmluZyBidWZmZXJcbiAgICBlbmNvZGVyLmNidWYgPSBuZXcgVWludDhBcnJheShtYXRoLm1heChidWZmZXJMZW4gKiAyLCByaWdodENvcHlMZW4pKVxuICAgIC8vIGNvcHkgYXJyYXlcbiAgICBlbmNvZGVyLmNidWYuc2V0KHVpbnQ4QXJyYXkuc3ViYXJyYXkobGVmdENvcHlMZW4pKVxuICAgIGVuY29kZXIuY3BvcyA9IHJpZ2h0Q29weUxlblxuICB9XG59XG5cbi8qKlxuICogQXBwZW5kIGFuIFVpbnQ4QXJyYXkgdG8gRW5jb2Rlci5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlclxuICogQHBhcmFtIHtVaW50OEFycmF5fSB1aW50OEFycmF5XG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZVZhclVpbnQ4QXJyYXkgPSAoZW5jb2RlciwgdWludDhBcnJheSkgPT4ge1xuICB3cml0ZVZhclVpbnQoZW5jb2RlciwgdWludDhBcnJheS5ieXRlTGVuZ3RoKVxuICB3cml0ZVVpbnQ4QXJyYXkoZW5jb2RlciwgdWludDhBcnJheSlcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW4gRGF0YVZpZXcgb2YgdGhlIG5leHQgYGxlbmAgYnl0ZXMuIFVzZSBpdCB0byB3cml0ZSBkYXRhIGFmdGVyXG4gKiBjYWxsaW5nIHRoaXMgZnVuY3Rpb24uXG4gKlxuICogYGBganNcbiAqIC8vIHdyaXRlIGZsb2F0MzIgdXNpbmcgRGF0YVZpZXdcbiAqIGNvbnN0IGR2ID0gd3JpdGVPbkRhdGFWaWV3KGVuY29kZXIsIDQpXG4gKiBkdi5zZXRGbG9hdDMyKDAsIDEuMSlcbiAqIC8vIHJlYWQgZmxvYXQzMiB1c2luZyBEYXRhVmlld1xuICogY29uc3QgZHYgPSByZWFkRnJvbURhdGFWaWV3KGVuY29kZXIsIDQpXG4gKiBkdi5nZXRGbG9hdDMyKDApIC8vID0+IDEuMTAwMDAwMDIzODQxODU4IChsZWF2aW5nIGl0IHRvIHRoZSByZWFkZXIgdG8gZmluZCBvdXQgd2h5IHRoaXMgaXMgdGhlIGNvcnJlY3QgcmVzdWx0KVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtFbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuXG4gKiBAcmV0dXJuIHtEYXRhVmlld31cbiAqL1xuZXhwb3J0IGNvbnN0IHdyaXRlT25EYXRhVmlldyA9IChlbmNvZGVyLCBsZW4pID0+IHtcbiAgdmVyaWZ5TGVuKGVuY29kZXIsIGxlbilcbiAgY29uc3QgZHZpZXcgPSBuZXcgRGF0YVZpZXcoZW5jb2Rlci5jYnVmLmJ1ZmZlciwgZW5jb2Rlci5jcG9zLCBsZW4pXG4gIGVuY29kZXIuY3BvcyArPSBsZW5cbiAgcmV0dXJuIGR2aWV3XG59XG5cbi8qKlxuICogQHBhcmFtIHtFbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtXG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZUZsb2F0MzIgPSAoZW5jb2RlciwgbnVtKSA9PiB3cml0ZU9uRGF0YVZpZXcoZW5jb2RlciwgNCkuc2V0RmxvYXQzMigwLCBudW0sIGZhbHNlKVxuXG4vKipcbiAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlclxuICogQHBhcmFtIHtudW1iZXJ9IG51bVxuICovXG5leHBvcnQgY29uc3Qgd3JpdGVGbG9hdDY0ID0gKGVuY29kZXIsIG51bSkgPT4gd3JpdGVPbkRhdGFWaWV3KGVuY29kZXIsIDgpLnNldEZsb2F0NjQoMCwgbnVtLCBmYWxzZSlcblxuLyoqXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7YmlnaW50fSBudW1cbiAqL1xuZXhwb3J0IGNvbnN0IHdyaXRlQmlnSW50NjQgPSAoZW5jb2RlciwgbnVtKSA9PiAvKiogQHR5cGUge2FueX0gKi8gKHdyaXRlT25EYXRhVmlldyhlbmNvZGVyLCA4KSkuc2V0QmlnSW50NjQoMCwgbnVtLCBmYWxzZSlcblxuLyoqXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7YmlnaW50fSBudW1cbiAqL1xuZXhwb3J0IGNvbnN0IHdyaXRlQmlnVWludDY0ID0gKGVuY29kZXIsIG51bSkgPT4gLyoqIEB0eXBlIHthbnl9ICovICh3cml0ZU9uRGF0YVZpZXcoZW5jb2RlciwgOCkpLnNldEJpZ1VpbnQ2NCgwLCBudW0sIGZhbHNlKVxuXG5jb25zdCBmbG9hdFRlc3RCZWQgPSBuZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDQpKVxuLyoqXG4gKiBDaGVjayBpZiBhIG51bWJlciBjYW4gYmUgZW5jb2RlZCBhcyBhIDMyIGJpdCBmbG9hdC5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gbnVtXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5jb25zdCBpc0Zsb2F0MzIgPSBudW0gPT4ge1xuICBmbG9hdFRlc3RCZWQuc2V0RmxvYXQzMigwLCBudW0pXG4gIHJldHVybiBmbG9hdFRlc3RCZWQuZ2V0RmxvYXQzMigwKSA9PT0gbnVtXG59XG5cbi8qKlxuICogQHR5cGVkZWYge0FycmF5PEFueUVuY29kYWJsZT59IEFueUVuY29kYWJsZUFycmF5XG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7dW5kZWZpbmVkfG51bGx8bnVtYmVyfGJpZ2ludHxib29sZWFufHN0cmluZ3x7W2s6c3RyaW5nXTpBbnlFbmNvZGFibGV9fEFueUVuY29kYWJsZUFycmF5fFVpbnQ4QXJyYXl9IEFueUVuY29kYWJsZVxuICovXG5cbi8qKlxuICogRW5jb2RlIGRhdGEgd2l0aCBlZmZpY2llbnQgYmluYXJ5IGZvcm1hdC5cbiAqXG4gKiBEaWZmZXJlbmNlcyB0byBKU09OOlxuICogXHUyMDIyIFRyYW5zZm9ybXMgZGF0YSB0byBhIGJpbmFyeSBmb3JtYXQgKG5vdCB0byBhIHN0cmluZylcbiAqIFx1MjAyMiBFbmNvZGVzIHVuZGVmaW5lZCwgTmFOLCBhbmQgQXJyYXlCdWZmZXIgKHRoZXNlIGNhbid0IGJlIHJlcHJlc2VudGVkIGluIEpTT04pXG4gKiBcdTIwMjIgTnVtYmVycyBhcmUgZWZmaWNpZW50bHkgZW5jb2RlZCBlaXRoZXIgYXMgYSB2YXJpYWJsZSBsZW5ndGggaW50ZWdlciwgYXMgYVxuICogICAzMiBiaXQgZmxvYXQsIGFzIGEgNjQgYml0IGZsb2F0LCBvciBhcyBhIDY0IGJpdCBiaWdpbnQuXG4gKlxuICogRW5jb2RpbmcgdGFibGU6XG4gKlxuICogfCBEYXRhIFR5cGUgICAgICAgICAgIHwgUHJlZml4ICAgfCBFbmNvZGluZyBNZXRob2QgICAgfCBDb21tZW50IHxcbiAqIHwgLS0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tIHwgLS0tLS0tLS0tLS0tLS0tLS0tIHwgLS0tLS0tLSB8XG4gKiB8IHVuZGVmaW5lZCAgICAgICAgICAgfCAxMjcgICAgICB8ICAgICAgICAgICAgICAgICAgICB8IEZ1bmN0aW9ucywgc3ltYm9sLCBhbmQgZXZlcnl0aGluZyB0aGF0IGNhbm5vdCBiZSBpZGVudGlmaWVkIGlzIGVuY29kZWQgYXMgdW5kZWZpbmVkIHxcbiAqIHwgbnVsbCAgICAgICAgICAgICAgICB8IDEyNiAgICAgIHwgICAgICAgICAgICAgICAgICAgIHwgfFxuICogfCBpbnRlZ2VyICAgICAgICAgICAgIHwgMTI1ICAgICAgfCB3cml0ZVZhckludCAgICAgICAgfCBPbmx5IGVuY29kZXMgMzIgYml0IHNpZ25lZCBpbnRlZ2VycyB8XG4gKiB8IGZsb2F0MzIgICAgICAgICAgICAgfCAxMjQgICAgICB8IHdyaXRlRmxvYXQzMiAgICAgICB8IHxcbiAqIHwgZmxvYXQ2NCAgICAgICAgICAgICB8IDEyMyAgICAgIHwgd3JpdGVGbG9hdDY0ICAgICAgIHwgfFxuICogfCBiaWdpbnQgICAgICAgICAgICAgIHwgMTIyICAgICAgfCB3cml0ZUJpZ0ludDY0ICAgICAgfCB8XG4gKiB8IGJvb2xlYW4gKGZhbHNlKSAgICAgfCAxMjEgICAgICB8ICAgICAgICAgICAgICAgICAgICB8IFRydWUgYW5kIGZhbHNlIGFyZSBkaWZmZXJlbnQgZGF0YSB0eXBlcyBzbyB3ZSBzYXZlIHRoZSBmb2xsb3dpbmcgYnl0ZSB8XG4gKiB8IGJvb2xlYW4gKHRydWUpICAgICAgfCAxMjAgICAgICB8ICAgICAgICAgICAgICAgICAgICB8IC0gMGIwMTExMTAwMCBzbyB0aGUgbGFzdCBiaXQgZGV0ZXJtaW5lcyB3aGV0aGVyIHRydWUgb3IgZmFsc2UgfFxuICogfCBzdHJpbmcgICAgICAgICAgICAgIHwgMTE5ICAgICAgfCB3cml0ZVZhclN0cmluZyAgICAgfCB8XG4gKiB8IG9iamVjdDxzdHJpbmcsYW55PiAgfCAxMTggICAgICB8IGN1c3RvbSAgICAgICAgICAgICB8IFdyaXRlcyB7bGVuZ3RofSB0aGVuIHtsZW5ndGh9IGtleS12YWx1ZSBwYWlycyB8XG4gKiB8IGFycmF5PGFueT4gICAgICAgICAgfCAxMTcgICAgICB8IGN1c3RvbSAgICAgICAgICAgICB8IFdyaXRlcyB7bGVuZ3RofSB0aGVuIHtsZW5ndGh9IGpzb24gdmFsdWVzIHxcbiAqIHwgVWludDhBcnJheSAgICAgICAgICB8IDExNiAgICAgIHwgd3JpdGVWYXJVaW50OEFycmF5IHwgV2UgdXNlIFVpbnQ4QXJyYXkgZm9yIGFueSBraW5kIG9mIGJpbmFyeSBkYXRhIHxcbiAqXG4gKiBSZWFzb25zIGZvciB0aGUgZGVjcmVhc2luZyBwcmVmaXg6XG4gKiBXZSBuZWVkIHRoZSBmaXJzdCBiaXQgZm9yIGV4dGVuZGFiaWxpdHkgKGxhdGVyIHdlIG1heSB3YW50IHRvIGVuY29kZSB0aGVcbiAqIHByZWZpeCB3aXRoIHdyaXRlVmFyVWludCkuIFRoZSByZW1haW5pbmcgNyBiaXRzIGFyZSBkaXZpZGVkIGFzIGZvbGxvd3M6XG4gKiBbMC0zMF0gICB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkYXRhIHJhbmdlIGlzIHVzZWQgZm9yIGN1c3RvbSBwdXJwb3Nlc1xuICogICAgICAgICAgKGRlZmluZWQgYnkgdGhlIGZ1bmN0aW9uIHRoYXQgdXNlcyB0aGlzIGxpYnJhcnkpXG4gKiBbMzEtMTI3XSB0aGUgZW5kIG9mIHRoZSBkYXRhIHJhbmdlIGlzIHVzZWQgZm9yIGRhdGEgZW5jb2RpbmcgYnlcbiAqICAgICAgICAgIGxpYjAvZW5jb2RpbmcuanNcbiAqXG4gKiBAcGFyYW0ge0VuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7QW55RW5jb2RhYmxlfSBkYXRhXG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZUFueSA9IChlbmNvZGVyLCBkYXRhKSA9PiB7XG4gIHN3aXRjaCAodHlwZW9mIGRhdGEpIHtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgLy8gVFlQRSAxMTk6IFNUUklOR1xuICAgICAgd3JpdGUoZW5jb2RlciwgMTE5KVxuICAgICAgd3JpdGVWYXJTdHJpbmcoZW5jb2RlciwgZGF0YSlcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgIGlmIChudW1iZXIuaXNJbnRlZ2VyKGRhdGEpICYmIG1hdGguYWJzKGRhdGEpIDw9IGJpbmFyeS5CSVRTMzEpIHtcbiAgICAgICAgLy8gVFlQRSAxMjU6IElOVEVHRVJcbiAgICAgICAgd3JpdGUoZW5jb2RlciwgMTI1KVxuICAgICAgICB3cml0ZVZhckludChlbmNvZGVyLCBkYXRhKVxuICAgICAgfSBlbHNlIGlmIChpc0Zsb2F0MzIoZGF0YSkpIHtcbiAgICAgICAgLy8gVFlQRSAxMjQ6IEZMT0FUMzJcbiAgICAgICAgd3JpdGUoZW5jb2RlciwgMTI0KVxuICAgICAgICB3cml0ZUZsb2F0MzIoZW5jb2RlciwgZGF0YSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFRZUEUgMTIzOiBGTE9BVDY0XG4gICAgICAgIHdyaXRlKGVuY29kZXIsIDEyMylcbiAgICAgICAgd3JpdGVGbG9hdDY0KGVuY29kZXIsIGRhdGEpXG4gICAgICB9XG4gICAgICBicmVha1xuICAgIGNhc2UgJ2JpZ2ludCc6XG4gICAgICAvLyBUWVBFIDEyMjogQmlnSW50XG4gICAgICB3cml0ZShlbmNvZGVyLCAxMjIpXG4gICAgICB3cml0ZUJpZ0ludDY0KGVuY29kZXIsIGRhdGEpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICBpZiAoZGF0YSA9PT0gbnVsbCkge1xuICAgICAgICAvLyBUWVBFIDEyNjogbnVsbFxuICAgICAgICB3cml0ZShlbmNvZGVyLCAxMjYpXG4gICAgICB9IGVsc2UgaWYgKGFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgLy8gVFlQRSAxMTc6IEFycmF5XG4gICAgICAgIHdyaXRlKGVuY29kZXIsIDExNylcbiAgICAgICAgd3JpdGVWYXJVaW50KGVuY29kZXIsIGRhdGEubGVuZ3RoKVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB3cml0ZUFueShlbmNvZGVyLCBkYXRhW2ldKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB7XG4gICAgICAgIC8vIFRZUEUgMTE2OiBBcnJheUJ1ZmZlclxuICAgICAgICB3cml0ZShlbmNvZGVyLCAxMTYpXG4gICAgICAgIHdyaXRlVmFyVWludDhBcnJheShlbmNvZGVyLCBkYXRhKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVFlQRSAxMTg6IE9iamVjdFxuICAgICAgICB3cml0ZShlbmNvZGVyLCAxMTgpXG4gICAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhkYXRhKVxuICAgICAgICB3cml0ZVZhclVpbnQoZW5jb2Rlciwga2V5cy5sZW5ndGgpXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGtleSA9IGtleXNbaV1cbiAgICAgICAgICB3cml0ZVZhclN0cmluZyhlbmNvZGVyLCBrZXkpXG4gICAgICAgICAgd3JpdGVBbnkoZW5jb2RlciwgZGF0YVtrZXldKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVha1xuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgICAgLy8gVFlQRSAxMjAvMTIxOiBib29sZWFuICh0cnVlL2ZhbHNlKVxuICAgICAgd3JpdGUoZW5jb2RlciwgZGF0YSA/IDEyMCA6IDEyMSlcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIFRZUEUgMTI3OiB1bmRlZmluZWRcbiAgICAgIHdyaXRlKGVuY29kZXIsIDEyNylcbiAgfVxufVxuXG4vKipcbiAqIE5vdyBjb21lIGEgZmV3IHN0YXRlZnVsIGVuY29kZXIgdGhhdCBoYXZlIHRoZWlyIG93biBjbGFzc2VzLlxuICovXG5cbi8qKlxuICogQmFzaWMgUnVuIExlbmd0aCBFbmNvZGVyIC0gYSBiYXNpYyBjb21wcmVzc2lvbiBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKiBFbmNvZGVzIFsxLDEsMSw3XSB0byBbMSwzLDcsMV0gKDMgdGltZXMgMSwgMSB0aW1lIDcpLiBUaGlzIGVuY29kZXIgbWlnaHQgZG8gbW9yZSBoYXJtIHRoYW4gZ29vZCBpZiB0aGVyZSBhcmUgYSBsb3Qgb2YgdmFsdWVzIHRoYXQgYXJlIG5vdCByZXBlYXRlZC5cbiAqXG4gKiBJdCB3YXMgb3JpZ2luYWxseSB1c2VkIGZvciBpbWFnZSBjb21wcmVzc2lvbi4gQ29vbCAuLiBhcnRpY2xlIGh0dHA6Ly9jc2JydWNlLmNvbS9jYm0vdHJhbnNhY3Rvci9wZGZzL3RyYW5zX3Y3X2kwNi5wZGZcbiAqXG4gKiBAbm90ZSBUIG11c3Qgbm90IGJlIG51bGwhXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqL1xuZXhwb3J0IGNsYXNzIFJsZUVuY29kZXIgZXh0ZW5kcyBFbmNvZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oRW5jb2RlciwgVCk6dm9pZH0gd3JpdGVyXG4gICAqL1xuICBjb25zdHJ1Y3RvciAod3JpdGVyKSB7XG4gICAgc3VwZXIoKVxuICAgIC8qKlxuICAgICAqIFRoZSB3cml0ZXJcbiAgICAgKi9cbiAgICB0aGlzLncgPSB3cml0ZXJcbiAgICAvKipcbiAgICAgKiBDdXJyZW50IHN0YXRlXG4gICAgICogQHR5cGUge1R8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLnMgPSBudWxsXG4gICAgdGhpcy5jb3VudCA9IDBcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1R9IHZcbiAgICovXG4gIHdyaXRlICh2KSB7XG4gICAgaWYgKHRoaXMucyA9PT0gdikge1xuICAgICAgdGhpcy5jb3VudCsrXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmNvdW50ID4gMCkge1xuICAgICAgICAvLyBmbHVzaCBjb3VudGVyLCB1bmxlc3MgdGhpcyBpcyB0aGUgZmlyc3QgdmFsdWUgKGNvdW50ID0gMClcbiAgICAgICAgd3JpdGVWYXJVaW50KHRoaXMsIHRoaXMuY291bnQgLSAxKSAvLyBzaW5jZSBjb3VudCBpcyBhbHdheXMgPiAwLCB3ZSBjYW4gZGVjcmVtZW50IGJ5IG9uZS4gbm9uLXN0YW5kYXJkIGVuY29kaW5nIGZ0d1xuICAgICAgfVxuICAgICAgdGhpcy5jb3VudCA9IDFcbiAgICAgIC8vIHdyaXRlIGZpcnN0IHZhbHVlXG4gICAgICB0aGlzLncodGhpcywgdilcbiAgICAgIHRoaXMucyA9IHZcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBCYXNpYyBkaWZmIGRlY29kZXIgdXNpbmcgdmFyaWFibGUgbGVuZ3RoIGVuY29kaW5nLlxuICpcbiAqIEVuY29kZXMgdGhlIHZhbHVlcyBbMywgMTEwMCwgMTEwMSwgMTA1MCwgMF0gdG8gWzMsIDEwOTcsIDEsIC01MSwgLTEwNTBdIHVzaW5nIHdyaXRlVmFySW50LlxuICovXG5leHBvcnQgY2xhc3MgSW50RGlmZkVuY29kZXIgZXh0ZW5kcyBFbmNvZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydFxuICAgKi9cbiAgY29uc3RydWN0b3IgKHN0YXJ0KSB7XG4gICAgc3VwZXIoKVxuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgc3RhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMucyA9IHN0YXJ0XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHZcbiAgICovXG4gIHdyaXRlICh2KSB7XG4gICAgd3JpdGVWYXJJbnQodGhpcywgdiAtIHRoaXMucylcbiAgICB0aGlzLnMgPSB2XG4gIH1cbn1cblxuLyoqXG4gKiBBIGNvbWJpbmF0aW9uIG9mIEludERpZmZFbmNvZGVyIGFuZCBSbGVFbmNvZGVyLlxuICpcbiAqIEJhc2ljYWxseSBmaXJzdCB3cml0ZXMgdGhlIEludERpZmZFbmNvZGVyIGFuZCB0aGVuIGNvdW50cyBkdXBsaWNhdGUgZGlmZnMgdXNpbmcgUmxlRW5jb2RpbmcuXG4gKlxuICogRW5jb2RlcyB0aGUgdmFsdWVzIFsxLDEsMSwyLDMsNCw1LDZdIGFzIFsxLDEsMCwyLDEsNV0gKFJMRShbMSwwLDAsMSwxLDEsMSwxXSkgXHUyMUQyIFJsZUludERpZmZbMSwxLDAsMiwxLDVdKVxuICovXG5leHBvcnQgY2xhc3MgUmxlSW50RGlmZkVuY29kZXIgZXh0ZW5kcyBFbmNvZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydFxuICAgKi9cbiAgY29uc3RydWN0b3IgKHN0YXJ0KSB7XG4gICAgc3VwZXIoKVxuICAgIC8qKlxuICAgICAqIEN1cnJlbnQgc3RhdGVcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMucyA9IHN0YXJ0XG4gICAgdGhpcy5jb3VudCA9IDBcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdlxuICAgKi9cbiAgd3JpdGUgKHYpIHtcbiAgICBpZiAodGhpcy5zID09PSB2ICYmIHRoaXMuY291bnQgPiAwKSB7XG4gICAgICB0aGlzLmNvdW50KytcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuY291bnQgPiAwKSB7XG4gICAgICAgIC8vIGZsdXNoIGNvdW50ZXIsIHVubGVzcyB0aGlzIGlzIHRoZSBmaXJzdCB2YWx1ZSAoY291bnQgPSAwKVxuICAgICAgICB3cml0ZVZhclVpbnQodGhpcywgdGhpcy5jb3VudCAtIDEpIC8vIHNpbmNlIGNvdW50IGlzIGFsd2F5cyA+IDAsIHdlIGNhbiBkZWNyZW1lbnQgYnkgb25lLiBub24tc3RhbmRhcmQgZW5jb2RpbmcgZnR3XG4gICAgICB9XG4gICAgICB0aGlzLmNvdW50ID0gMVxuICAgICAgLy8gd3JpdGUgZmlyc3QgdmFsdWVcbiAgICAgIHdyaXRlVmFySW50KHRoaXMsIHYgLSB0aGlzLnMpXG4gICAgICB0aGlzLnMgPSB2XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtVaW50T3B0UmxlRW5jb2Rlcn0gZW5jb2RlclxuICovXG5jb25zdCBmbHVzaFVpbnRPcHRSbGVFbmNvZGVyID0gZW5jb2RlciA9PiB7XG4gIGlmIChlbmNvZGVyLmNvdW50ID4gMCkge1xuICAgIC8vIGZsdXNoIGNvdW50ZXIsIHVubGVzcyB0aGlzIGlzIHRoZSBmaXJzdCB2YWx1ZSAoY291bnQgPSAwKVxuICAgIC8vIGNhc2UgMToganVzdCBhIHNpbmdsZSB2YWx1ZS4gc2V0IHNpZ24gdG8gcG9zaXRpdmVcbiAgICAvLyBjYXNlIDI6IHdyaXRlIHNldmVyYWwgdmFsdWVzLiBzZXQgc2lnbiB0byBuZWdhdGl2ZSB0byBpbmRpY2F0ZSB0aGF0IHRoZXJlIGlzIGEgbGVuZ3RoIGNvbWluZ1xuICAgIHdyaXRlVmFySW50KGVuY29kZXIuZW5jb2RlciwgZW5jb2Rlci5jb3VudCA9PT0gMSA/IGVuY29kZXIucyA6IC1lbmNvZGVyLnMpXG4gICAgaWYgKGVuY29kZXIuY291bnQgPiAxKSB7XG4gICAgICB3cml0ZVZhclVpbnQoZW5jb2Rlci5lbmNvZGVyLCBlbmNvZGVyLmNvdW50IC0gMikgLy8gc2luY2UgY291bnQgaXMgYWx3YXlzID4gMSwgd2UgY2FuIGRlY3JlbWVudCBieSBvbmUuIG5vbi1zdGFuZGFyZCBlbmNvZGluZyBmdHdcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBPcHRpbWl6ZWQgUmxlIGVuY29kZXIgdGhhdCBkb2VzIG5vdCBzdWZmZXIgZnJvbSB0aGUgbWVudGlvbmVkIHByb2JsZW0gb2YgdGhlIGJhc2ljIFJsZSBlbmNvZGVyLlxuICpcbiAqIEludGVybmFsbHkgdXNlcyBWYXJJbnQgZW5jb2RlciB0byB3cml0ZSB1bnNpZ25lZCBpbnRlZ2Vycy4gSWYgdGhlIGlucHV0IG9jY3VycyBtdWx0aXBsZSB0aW1lcywgd2Ugd3JpdGVcbiAqIHdyaXRlIGl0IGFzIGEgbmVnYXRpdmUgbnVtYmVyLiBUaGUgVWludE9wdFJsZURlY29kZXIgdGhlbiB1bmRlcnN0YW5kcyB0aGF0IGl0IG5lZWRzIHRvIHJlYWQgYSBjb3VudC5cbiAqXG4gKiBFbmNvZGVzIFsxLDIsMywzLDNdIGFzIFsxLDIsLTMsM10gKG9uY2UgMSwgb25jZSAyLCB0aHJlZSB0aW1lcyAzKVxuICovXG5leHBvcnQgY2xhc3MgVWludE9wdFJsZUVuY29kZXIge1xuICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgdGhpcy5lbmNvZGVyID0gbmV3IEVuY29kZXIoKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5zID0gMFxuICAgIHRoaXMuY291bnQgPSAwXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHZcbiAgICovXG4gIHdyaXRlICh2KSB7XG4gICAgaWYgKHRoaXMucyA9PT0gdikge1xuICAgICAgdGhpcy5jb3VudCsrXG4gICAgfSBlbHNlIHtcbiAgICAgIGZsdXNoVWludE9wdFJsZUVuY29kZXIodGhpcylcbiAgICAgIHRoaXMuY291bnQgPSAxXG4gICAgICB0aGlzLnMgPSB2XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZsdXNoIHRoZSBlbmNvZGVkIHN0YXRlIGFuZCB0cmFuc2Zvcm0gdGhpcyB0byBhIFVpbnQ4QXJyYXkuXG4gICAqXG4gICAqIE5vdGUgdGhhdCB0aGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbmNlLlxuICAgKi9cbiAgdG9VaW50OEFycmF5ICgpIHtcbiAgICBmbHVzaFVpbnRPcHRSbGVFbmNvZGVyKHRoaXMpXG4gICAgcmV0dXJuIHRvVWludDhBcnJheSh0aGlzLmVuY29kZXIpXG4gIH1cbn1cblxuLyoqXG4gKiBJbmNyZWFzaW5nIFVpbnQgT3B0aW1pemVkIFJMRSBFbmNvZGVyXG4gKlxuICogVGhlIFJMRSBlbmNvZGVyIGNvdW50cyB0aGUgbnVtYmVyIG9mIHNhbWUgb2NjdXJlbmNlcyBvZiB0aGUgc2FtZSB2YWx1ZS5cbiAqIFRoZSBJbmNVaW50T3B0UmxlIGVuY29kZXIgY291bnRzIGlmIHRoZSB2YWx1ZSBpbmNyZWFzZXMuXG4gKiBJLmUuIDcsIDgsIDksIDEwIHdpbGwgYmUgZW5jb2RlZCBhcyBbLTcsIDRdLiAxLCAzLCA1IHdpbGwgYmUgZW5jb2RlZFxuICogYXMgWzEsIDMsIDVdLlxuICovXG5leHBvcnQgY2xhc3MgSW5jVWludE9wdFJsZUVuY29kZXIge1xuICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgdGhpcy5lbmNvZGVyID0gbmV3IEVuY29kZXIoKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5zID0gMFxuICAgIHRoaXMuY291bnQgPSAwXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHZcbiAgICovXG4gIHdyaXRlICh2KSB7XG4gICAgaWYgKHRoaXMucyArIHRoaXMuY291bnQgPT09IHYpIHtcbiAgICAgIHRoaXMuY291bnQrK1xuICAgIH0gZWxzZSB7XG4gICAgICBmbHVzaFVpbnRPcHRSbGVFbmNvZGVyKHRoaXMpXG4gICAgICB0aGlzLmNvdW50ID0gMVxuICAgICAgdGhpcy5zID0gdlxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBGbHVzaCB0aGUgZW5jb2RlZCBzdGF0ZSBhbmQgdHJhbnNmb3JtIHRoaXMgdG8gYSBVaW50OEFycmF5LlxuICAgKlxuICAgKiBOb3RlIHRoYXQgdGhpcyBzaG91bGQgb25seSBiZSBjYWxsZWQgb25jZS5cbiAgICovXG4gIHRvVWludDhBcnJheSAoKSB7XG4gICAgZmx1c2hVaW50T3B0UmxlRW5jb2Rlcih0aGlzKVxuICAgIHJldHVybiB0b1VpbnQ4QXJyYXkodGhpcy5lbmNvZGVyKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtJbnREaWZmT3B0UmxlRW5jb2Rlcn0gZW5jb2RlclxuICovXG5jb25zdCBmbHVzaEludERpZmZPcHRSbGVFbmNvZGVyID0gZW5jb2RlciA9PiB7XG4gIGlmIChlbmNvZGVyLmNvdW50ID4gMCkge1xuICAgIC8vICAgICAgICAgIDMxIGJpdCBtYWtpbmcgdXAgdGhlIGRpZmYgfCB3ZXRoZXIgdG8gd3JpdGUgdGhlIGNvdW50ZXJcbiAgICAvLyBjb25zdCBlbmNvZGVkRGlmZiA9IGVuY29kZXIuZGlmZiA8PCAxIHwgKGVuY29kZXIuY291bnQgPT09IDEgPyAwIDogMSlcbiAgICBjb25zdCBlbmNvZGVkRGlmZiA9IGVuY29kZXIuZGlmZiAqIDIgKyAoZW5jb2Rlci5jb3VudCA9PT0gMSA/IDAgOiAxKVxuICAgIC8vIGZsdXNoIGNvdW50ZXIsIHVubGVzcyB0aGlzIGlzIHRoZSBmaXJzdCB2YWx1ZSAoY291bnQgPSAwKVxuICAgIC8vIGNhc2UgMToganVzdCBhIHNpbmdsZSB2YWx1ZS4gc2V0IGZpcnN0IGJpdCB0byBwb3NpdGl2ZVxuICAgIC8vIGNhc2UgMjogd3JpdGUgc2V2ZXJhbCB2YWx1ZXMuIHNldCBmaXJzdCBiaXQgdG8gbmVnYXRpdmUgdG8gaW5kaWNhdGUgdGhhdCB0aGVyZSBpcyBhIGxlbmd0aCBjb21pbmdcbiAgICB3cml0ZVZhckludChlbmNvZGVyLmVuY29kZXIsIGVuY29kZWREaWZmKVxuICAgIGlmIChlbmNvZGVyLmNvdW50ID4gMSkge1xuICAgICAgd3JpdGVWYXJVaW50KGVuY29kZXIuZW5jb2RlciwgZW5jb2Rlci5jb3VudCAtIDIpIC8vIHNpbmNlIGNvdW50IGlzIGFsd2F5cyA+IDEsIHdlIGNhbiBkZWNyZW1lbnQgYnkgb25lLiBub24tc3RhbmRhcmQgZW5jb2RpbmcgZnR3XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQSBjb21iaW5hdGlvbiBvZiB0aGUgSW50RGlmZkVuY29kZXIgYW5kIHRoZSBVaW50T3B0UmxlRW5jb2Rlci5cbiAqXG4gKiBUaGUgY291bnQgYXBwcm9hY2ggaXMgc2ltaWxhciB0byB0aGUgVWludERpZmZPcHRSbGVFbmNvZGVyLCBidXQgaW5zdGVhZCBvZiB1c2luZyB0aGUgbmVnYXRpdmUgYml0ZmxhZywgaXQgZW5jb2Rlc1xuICogaW4gdGhlIExTQiB3aGV0aGVyIGEgY291bnQgaXMgdG8gYmUgcmVhZC4gVGhlcmVmb3JlIHRoaXMgRW5jb2RlciBvbmx5IHN1cHBvcnRzIDMxIGJpdCBpbnRlZ2VycyFcbiAqXG4gKiBFbmNvZGVzIFsxLCAyLCAzLCAyXSBhcyBbMywgMSwgNiwgLTFdIChtb3JlIHNwZWNpZmljYWxseSBbKDEgPDwgMSkgfCAxLCAoMyA8PCAwKSB8IDAsIC0xXSlcbiAqXG4gKiBJbnRlcm5hbGx5IHVzZXMgdmFyaWFibGUgbGVuZ3RoIGVuY29kaW5nLiBDb250cmFyeSB0byBub3JtYWwgVWludFZhciBlbmNvZGluZywgdGhlIGZpcnN0IGJ5dGUgY29udGFpbnM6XG4gKiAqIDEgYml0IHRoYXQgZGVub3RlcyB3aGV0aGVyIHRoZSBuZXh0IHZhbHVlIGlzIGEgY291bnQgKExTQilcbiAqICogMSBiaXQgdGhhdCBkZW5vdGVzIHdoZXRoZXIgdGhpcyB2YWx1ZSBpcyBuZWdhdGl2ZSAoTVNCIC0gMSlcbiAqICogMSBiaXQgdGhhdCBkZW5vdGVzIHdoZXRoZXIgdG8gY29udGludWUgcmVhZGluZyB0aGUgdmFyaWFibGUgbGVuZ3RoIGludGVnZXIgKE1TQilcbiAqXG4gKiBUaGVyZWZvcmUsIG9ubHkgZml2ZSBiaXRzIHJlbWFpbiB0byBlbmNvZGUgZGlmZiByYW5nZXMuXG4gKlxuICogVXNlIHRoaXMgRW5jb2RlciBvbmx5IHdoZW4gYXBwcm9wcmlhdGUuIEluIG1vc3QgY2FzZXMsIHRoaXMgaXMgcHJvYmFibHkgYSBiYWQgaWRlYS5cbiAqL1xuZXhwb3J0IGNsYXNzIEludERpZmZPcHRSbGVFbmNvZGVyIHtcbiAgY29uc3RydWN0b3IgKCkge1xuICAgIHRoaXMuZW5jb2RlciA9IG5ldyBFbmNvZGVyKClcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMucyA9IDBcbiAgICB0aGlzLmNvdW50ID0gMFxuICAgIHRoaXMuZGlmZiA9IDBcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gdlxuICAgKi9cbiAgd3JpdGUgKHYpIHtcbiAgICBpZiAodGhpcy5kaWZmID09PSB2IC0gdGhpcy5zKSB7XG4gICAgICB0aGlzLnMgPSB2XG4gICAgICB0aGlzLmNvdW50KytcbiAgICB9IGVsc2Uge1xuICAgICAgZmx1c2hJbnREaWZmT3B0UmxlRW5jb2Rlcih0aGlzKVxuICAgICAgdGhpcy5jb3VudCA9IDFcbiAgICAgIHRoaXMuZGlmZiA9IHYgLSB0aGlzLnNcbiAgICAgIHRoaXMucyA9IHZcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRmx1c2ggdGhlIGVuY29kZWQgc3RhdGUgYW5kIHRyYW5zZm9ybSB0aGlzIHRvIGEgVWludDhBcnJheS5cbiAgICpcbiAgICogTm90ZSB0aGF0IHRoaXMgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIG9uY2UuXG4gICAqL1xuICB0b1VpbnQ4QXJyYXkgKCkge1xuICAgIGZsdXNoSW50RGlmZk9wdFJsZUVuY29kZXIodGhpcylcbiAgICByZXR1cm4gdG9VaW50OEFycmF5KHRoaXMuZW5jb2RlcilcbiAgfVxufVxuXG4vKipcbiAqIE9wdGltaXplZCBTdHJpbmcgRW5jb2Rlci5cbiAqXG4gKiBFbmNvZGluZyBtYW55IHNtYWxsIHN0cmluZ3MgaW4gYSBzaW1wbGUgRW5jb2RlciBpcyBub3QgdmVyeSBlZmZpY2llbnQuIFRoZSBmdW5jdGlvbiBjYWxsIHRvIGRlY29kZSBhIHN0cmluZyB0YWtlcyBzb21lIHRpbWUgYW5kIGNyZWF0ZXMgcmVmZXJlbmNlcyB0aGF0IG11c3QgYmUgZXZlbnR1YWxseSBkZWxldGVkLlxuICogSW4gcHJhY3RpY2UsIHdoZW4gZGVjb2Rpbmcgc2V2ZXJhbCBtaWxsaW9uIHNtYWxsIHN0cmluZ3MsIHRoZSBHQyB3aWxsIGtpY2sgaW4gbW9yZSBhbmQgbW9yZSBvZnRlbiB0byBjb2xsZWN0IG9ycGhhbmVkIHN0cmluZyBvYmplY3RzIChvciBtYXliZSB0aGVyZSBpcyBhbm90aGVyIHJlYXNvbj8pLlxuICpcbiAqIFRoaXMgc3RyaW5nIGVuY29kZXIgc29sdmVzIHRoZSBhYm92ZSBwcm9ibGVtLiBBbGwgc3RyaW5ncyBhcmUgY29uY2F0ZW5hdGVkIGFuZCB3cml0dGVuIGFzIGEgc2luZ2xlIHN0cmluZyB1c2luZyBhIHNpbmdsZSBlbmNvZGluZyBjYWxsLlxuICpcbiAqIFRoZSBsZW5ndGhzIGFyZSBlbmNvZGVkIHVzaW5nIGEgVWludE9wdFJsZUVuY29kZXIuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJpbmdFbmNvZGVyIHtcbiAgY29uc3RydWN0b3IgKCkge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxzdHJpbmc+fVxuICAgICAqL1xuICAgIHRoaXMuc2FyciA9IFtdXG4gICAgdGhpcy5zID0gJydcbiAgICB0aGlzLmxlbnNFID0gbmV3IFVpbnRPcHRSbGVFbmNvZGVyKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyaW5nXG4gICAqL1xuICB3cml0ZSAoc3RyaW5nKSB7XG4gICAgdGhpcy5zICs9IHN0cmluZ1xuICAgIGlmICh0aGlzLnMubGVuZ3RoID4gMTkpIHtcbiAgICAgIHRoaXMuc2Fyci5wdXNoKHRoaXMucylcbiAgICAgIHRoaXMucyA9ICcnXG4gICAgfVxuICAgIHRoaXMubGVuc0Uud3JpdGUoc3RyaW5nLmxlbmd0aClcbiAgfVxuXG4gIHRvVWludDhBcnJheSAoKSB7XG4gICAgY29uc3QgZW5jb2RlciA9IG5ldyBFbmNvZGVyKClcbiAgICB0aGlzLnNhcnIucHVzaCh0aGlzLnMpXG4gICAgdGhpcy5zID0gJydcbiAgICB3cml0ZVZhclN0cmluZyhlbmNvZGVyLCB0aGlzLnNhcnIuam9pbignJykpXG4gICAgd3JpdGVVaW50OEFycmF5KGVuY29kZXIsIHRoaXMubGVuc0UudG9VaW50OEFycmF5KCkpXG4gICAgcmV0dXJuIHRvVWludDhBcnJheShlbmNvZGVyKVxuICB9XG59XG4iLCAiLyoqXG4gKiBFcnJvciBoZWxwZXJzLlxuICpcbiAqIEBtb2R1bGUgZXJyb3JcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzXG4gKiBAcmV0dXJuIHtFcnJvcn1cbiAqL1xuLyogYzggaWdub3JlIG5leHQgKi9cbmV4cG9ydCBjb25zdCBjcmVhdGUgPSBzID0+IG5ldyBFcnJvcihzKVxuXG4vKipcbiAqIEB0aHJvd3Mge0Vycm9yfVxuICogQHJldHVybiB7bmV2ZXJ9XG4gKi9cbi8qIGM4IGlnbm9yZSBuZXh0IDMgKi9cbmV4cG9ydCBjb25zdCBtZXRob2RVbmltcGxlbWVudGVkID0gKCkgPT4ge1xuICB0aHJvdyBjcmVhdGUoJ01ldGhvZCB1bmltcGxlbWVudGVkJylcbn1cblxuLyoqXG4gKiBAdGhyb3dzIHtFcnJvcn1cbiAqIEByZXR1cm4ge25ldmVyfVxuICovXG4vKiBjOCBpZ25vcmUgbmV4dCAzICovXG5leHBvcnQgY29uc3QgdW5leHBlY3RlZENhc2UgPSAoKSA9PiB7XG4gIHRocm93IGNyZWF0ZSgnVW5leHBlY3RlZCBjYXNlJylcbn1cblxuLyoqXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHByb3BlcnR5XG4gKiBAcmV0dXJuIHthc3NlcnRzIHByb3BlcnR5IGlzIHRydWV9XG4gKi9cbmV4cG9ydCBjb25zdCBhc3NlcnQgPSBwcm9wZXJ0eSA9PiB7IGlmICghcHJvcGVydHkpIHRocm93IGNyZWF0ZSgnQXNzZXJ0IGZhaWxlZCcpIH1cbiIsICIvKipcbiAqIEVmZmljaWVudCBzY2hlbWEtbGVzcyBiaW5hcnkgZGVjb2Rpbmcgd2l0aCBzdXBwb3J0IGZvciB2YXJpYWJsZSBsZW5ndGggZW5jb2RpbmcuXG4gKlxuICogVXNlIFtsaWIwL2RlY29kaW5nXSB3aXRoIFtsaWIwL2VuY29kaW5nXS4gRXZlcnkgZW5jb2RpbmcgZnVuY3Rpb24gaGFzIGEgY29ycmVzcG9uZGluZyBkZWNvZGluZyBmdW5jdGlvbi5cbiAqXG4gKiBFbmNvZGVzIG51bWJlcnMgaW4gbGl0dGxlLWVuZGlhbiBvcmRlciAobGVhc3QgdG8gbW9zdCBzaWduaWZpY2FudCBieXRlIG9yZGVyKVxuICogYW5kIGlzIGNvbXBhdGlibGUgd2l0aCBHb2xhbmcncyBiaW5hcnkgZW5jb2RpbmcgKGh0dHBzOi8vZ29sYW5nLm9yZy9wa2cvZW5jb2RpbmcvYmluYXJ5LylcbiAqIHdoaWNoIGlzIGFsc28gdXNlZCBpbiBQcm90b2NvbCBCdWZmZXJzLlxuICpcbiAqIGBgYGpzXG4gKiAvLyBlbmNvZGluZyBzdGVwXG4gKiBjb25zdCBlbmNvZGVyID0gZW5jb2RpbmcuY3JlYXRlRW5jb2RlcigpXG4gKiBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2RlciwgMjU2KVxuICogZW5jb2Rpbmcud3JpdGVWYXJTdHJpbmcoZW5jb2RlciwgJ0hlbGxvIHdvcmxkIScpXG4gKiBjb25zdCBidWYgPSBlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlcilcbiAqIGBgYFxuICpcbiAqIGBgYGpzXG4gKiAvLyBkZWNvZGluZyBzdGVwXG4gKiBjb25zdCBkZWNvZGVyID0gZGVjb2RpbmcuY3JlYXRlRGVjb2RlcihidWYpXG4gKiBkZWNvZGluZy5yZWFkVmFyVWludChkZWNvZGVyKSAvLyA9PiAyNTZcbiAqIGRlY29kaW5nLnJlYWRWYXJTdHJpbmcoZGVjb2RlcikgLy8gPT4gJ0hlbGxvIHdvcmxkISdcbiAqIGRlY29kaW5nLmhhc0NvbnRlbnQoZGVjb2RlcikgLy8gPT4gZmFsc2UgLSBhbGwgZGF0YSBpcyByZWFkXG4gKiBgYGBcbiAqXG4gKiBAbW9kdWxlIGRlY29kaW5nXG4gKi9cblxuaW1wb3J0ICogYXMgYmluYXJ5IGZyb20gJy4vYmluYXJ5LmpzJ1xuaW1wb3J0ICogYXMgbWF0aCBmcm9tICcuL21hdGguanMnXG5pbXBvcnQgKiBhcyBudW1iZXIgZnJvbSAnLi9udW1iZXIuanMnXG5pbXBvcnQgKiBhcyBzdHJpbmcgZnJvbSAnLi9zdHJpbmcuanMnXG5pbXBvcnQgKiBhcyBlcnJvciBmcm9tICcuL2Vycm9yLmpzJ1xuaW1wb3J0ICogYXMgZW5jb2RpbmcgZnJvbSAnLi9lbmNvZGluZy5qcydcblxuY29uc3QgZXJyb3JVbmV4cGVjdGVkRW5kT2ZBcnJheSA9IGVycm9yLmNyZWF0ZSgnVW5leHBlY3RlZCBlbmQgb2YgYXJyYXknKVxuY29uc3QgZXJyb3JJbnRlZ2VyT3V0T2ZSYW5nZSA9IGVycm9yLmNyZWF0ZSgnSW50ZWdlciBvdXQgb2YgUmFuZ2UnKVxuXG4vKipcbiAqIEEgRGVjb2RlciBoYW5kbGVzIHRoZSBkZWNvZGluZyBvZiBhbiBVaW50OEFycmF5LlxuICogQHRlbXBsYXRlIHtBcnJheUJ1ZmZlckxpa2V9IFtCdWY9QXJyYXlCdWZmZXJMaWtlXVxuICovXG5leHBvcnQgY2xhc3MgRGVjb2RlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXk8QnVmPn0gdWludDhBcnJheSBCaW5hcnkgZGF0YSB0byBkZWNvZGVcbiAgICovXG4gIGNvbnN0cnVjdG9yICh1aW50OEFycmF5KSB7XG4gICAgLyoqXG4gICAgICogRGVjb2RpbmcgdGFyZ2V0LlxuICAgICAqXG4gICAgICogQHR5cGUge1VpbnQ4QXJyYXk8QnVmPn1cbiAgICAgKi9cbiAgICB0aGlzLmFyciA9IHVpbnQ4QXJyYXlcbiAgICAvKipcbiAgICAgKiBDdXJyZW50IGRlY29kaW5nIHBvc2l0aW9uLlxuICAgICAqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLnBvcyA9IDBcbiAgfVxufVxuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHRlbXBsYXRlIHtBcnJheUJ1ZmZlckxpa2V9IEJ1ZlxuICogQHBhcmFtIHtVaW50OEFycmF5PEJ1Zj59IHVpbnQ4QXJyYXlcbiAqIEByZXR1cm4ge0RlY29kZXI8QnVmPn1cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlY29kZXIgPSB1aW50OEFycmF5ID0+IG5ldyBEZWNvZGVyKHVpbnQ4QXJyYXkpXG5cbi8qKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0RlY29kZXJ9IGRlY29kZXJcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBjb25zdCBoYXNDb250ZW50ID0gZGVjb2RlciA9PiBkZWNvZGVyLnBvcyAhPT0gZGVjb2Rlci5hcnIubGVuZ3RoXG5cbi8qKlxuICogQ2xvbmUgYSBkZWNvZGVyIGluc3RhbmNlLlxuICogT3B0aW9uYWxseSBzZXQgYSBuZXcgcG9zaXRpb24gcGFyYW1ldGVyLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtEZWNvZGVyfSBkZWNvZGVyIFRoZSBkZWNvZGVyIGluc3RhbmNlXG4gKiBAcGFyYW0ge251bWJlcn0gW25ld1Bvc10gRGVmYXVsdHMgdG8gY3VycmVudCBwb3NpdGlvblxuICogQHJldHVybiB7RGVjb2Rlcn0gQSBjbG9uZSBvZiBgZGVjb2RlcmBcbiAqL1xuZXhwb3J0IGNvbnN0IGNsb25lID0gKGRlY29kZXIsIG5ld1BvcyA9IGRlY29kZXIucG9zKSA9PiB7XG4gIGNvbnN0IF9kZWNvZGVyID0gY3JlYXRlRGVjb2RlcihkZWNvZGVyLmFycilcbiAgX2RlY29kZXIucG9zID0gbmV3UG9zXG4gIHJldHVybiBfZGVjb2RlclxufVxuXG4vKipcbiAqIENyZWF0ZSBhbiBVaW50OEFycmF5IHZpZXcgb2YgdGhlIG5leHQgYGxlbmAgYnl0ZXMgYW5kIGFkdmFuY2UgdGhlIHBvc2l0aW9uIGJ5IGBsZW5gLlxuICpcbiAqIEltcG9ydGFudDogVGhlIFVpbnQ4QXJyYXkgc3RpbGwgcG9pbnRzIHRvIHRoZSB1bmRlcmx5aW5nIEFycmF5QnVmZmVyLiBNYWtlIHN1cmUgdG8gZGlzY2FyZCB0aGUgcmVzdWx0IGFzIHNvb24gYXMgcG9zc2libGUgdG8gcHJldmVudCBhbnkgbWVtb3J5IGxlYWtzLlxuICogICAgICAgICAgICBVc2UgYGJ1ZmZlci5jb3B5VWludDhBcnJheWAgdG8gY29weSB0aGUgcmVzdWx0IGludG8gYSBuZXcgVWludDhBcnJheS5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEB0ZW1wbGF0ZSB7QXJyYXlCdWZmZXJMaWtlfSBCdWZcbiAqIEBwYXJhbSB7RGVjb2RlcjxCdWY+fSBkZWNvZGVyIFRoZSBkZWNvZGVyIGluc3RhbmNlXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuIFRoZSBsZW5ndGggb2YgYnl0ZXMgdG8gcmVhZFxuICogQHJldHVybiB7VWludDhBcnJheTxCdWY+fVxuICovXG5leHBvcnQgY29uc3QgcmVhZFVpbnQ4QXJyYXkgPSAoZGVjb2RlciwgbGVuKSA9PiB7XG4gIGNvbnN0IHZpZXcgPSBuZXcgVWludDhBcnJheShkZWNvZGVyLmFyci5idWZmZXIsIGRlY29kZXIucG9zICsgZGVjb2Rlci5hcnIuYnl0ZU9mZnNldCwgbGVuKVxuICBkZWNvZGVyLnBvcyArPSBsZW5cbiAgcmV0dXJuIHZpZXdcbn1cblxuLyoqXG4gKiBSZWFkIHZhcmlhYmxlIGxlbmd0aCBVaW50OEFycmF5LlxuICpcbiAqIEltcG9ydGFudDogVGhlIFVpbnQ4QXJyYXkgc3RpbGwgcG9pbnRzIHRvIHRoZSB1bmRlcmx5aW5nIEFycmF5QnVmZmVyLiBNYWtlIHN1cmUgdG8gZGlzY2FyZCB0aGUgcmVzdWx0IGFzIHNvb24gYXMgcG9zc2libGUgdG8gcHJldmVudCBhbnkgbWVtb3J5IGxlYWtzLlxuICogICAgICAgICAgICBVc2UgYGJ1ZmZlci5jb3B5VWludDhBcnJheWAgdG8gY29weSB0aGUgcmVzdWx0IGludG8gYSBuZXcgVWludDhBcnJheS5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEB0ZW1wbGF0ZSB7QXJyYXlCdWZmZXJMaWtlfSBCdWZcbiAqIEBwYXJhbSB7RGVjb2RlcjxCdWY+fSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5PEJ1Zj59XG4gKi9cbmV4cG9ydCBjb25zdCByZWFkVmFyVWludDhBcnJheSA9IGRlY29kZXIgPT4gcmVhZFVpbnQ4QXJyYXkoZGVjb2RlciwgcmVhZFZhclVpbnQoZGVjb2RlcikpXG5cbi8qKlxuICogUmVhZCB0aGUgcmVzdCBvZiB0aGUgY29udGVudCBhcyBhbiBBcnJheUJ1ZmZlclxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0RlY29kZXJ9IGRlY29kZXJcbiAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9XG4gKi9cbmV4cG9ydCBjb25zdCByZWFkVGFpbEFzVWludDhBcnJheSA9IGRlY29kZXIgPT4gcmVhZFVpbnQ4QXJyYXkoZGVjb2RlciwgZGVjb2Rlci5hcnIubGVuZ3RoIC0gZGVjb2Rlci5wb3MpXG5cbi8qKlxuICogU2tpcCBvbmUgYnl0ZSwganVtcCB0byB0aGUgbmV4dCBwb3NpdGlvbi5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtEZWNvZGVyfSBkZWNvZGVyIFRoZSBkZWNvZGVyIGluc3RhbmNlXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFRoZSBuZXh0IHBvc2l0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBza2lwOCA9IGRlY29kZXIgPT4gZGVjb2Rlci5wb3MrK1xuXG4vKipcbiAqIFJlYWQgb25lIGJ5dGUgYXMgdW5zaWduZWQgaW50ZWdlci5cbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtEZWNvZGVyfSBkZWNvZGVyIFRoZSBkZWNvZGVyIGluc3RhbmNlXG4gKiBAcmV0dXJuIHtudW1iZXJ9IFVuc2lnbmVkIDgtYml0IGludGVnZXJcbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRVaW50OCA9IGRlY29kZXIgPT4gZGVjb2Rlci5hcnJbZGVjb2Rlci5wb3MrK11cblxuLyoqXG4gKiBSZWFkIDIgYnl0ZXMgYXMgdW5zaWduZWQgaW50ZWdlci5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RGVjb2Rlcn0gZGVjb2RlclxuICogQHJldHVybiB7bnVtYmVyfSBBbiB1bnNpZ25lZCBpbnRlZ2VyLlxuICovXG5leHBvcnQgY29uc3QgcmVhZFVpbnQxNiA9IGRlY29kZXIgPT4ge1xuICBjb25zdCB1aW50ID1cbiAgICBkZWNvZGVyLmFycltkZWNvZGVyLnBvc10gK1xuICAgIChkZWNvZGVyLmFycltkZWNvZGVyLnBvcyArIDFdIDw8IDgpXG4gIGRlY29kZXIucG9zICs9IDJcbiAgcmV0dXJuIHVpbnRcbn1cblxuLyoqXG4gKiBSZWFkIDQgYnl0ZXMgYXMgdW5zaWduZWQgaW50ZWdlci5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RGVjb2Rlcn0gZGVjb2RlclxuICogQHJldHVybiB7bnVtYmVyfSBBbiB1bnNpZ25lZCBpbnRlZ2VyLlxuICovXG5leHBvcnQgY29uc3QgcmVhZFVpbnQzMiA9IGRlY29kZXIgPT4ge1xuICBjb25zdCB1aW50ID1cbiAgICAoZGVjb2Rlci5hcnJbZGVjb2Rlci5wb3NdICtcbiAgICAoZGVjb2Rlci5hcnJbZGVjb2Rlci5wb3MgKyAxXSA8PCA4KSArXG4gICAgKGRlY29kZXIuYXJyW2RlY29kZXIucG9zICsgMl0gPDwgMTYpICtcbiAgICAoZGVjb2Rlci5hcnJbZGVjb2Rlci5wb3MgKyAzXSA8PCAyNCkpID4+PiAwXG4gIGRlY29kZXIucG9zICs9IDRcbiAgcmV0dXJuIHVpbnRcbn1cblxuLyoqXG4gKiBSZWFkIDQgYnl0ZXMgYXMgdW5zaWduZWQgaW50ZWdlciBpbiBiaWcgZW5kaWFuIG9yZGVyLlxuICogKG1vc3Qgc2lnbmlmaWNhbnQgYnl0ZSBmaXJzdClcbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RGVjb2Rlcn0gZGVjb2RlclxuICogQHJldHVybiB7bnVtYmVyfSBBbiB1bnNpZ25lZCBpbnRlZ2VyLlxuICovXG5leHBvcnQgY29uc3QgcmVhZFVpbnQzMkJpZ0VuZGlhbiA9IGRlY29kZXIgPT4ge1xuICBjb25zdCB1aW50ID1cbiAgICAoZGVjb2Rlci5hcnJbZGVjb2Rlci5wb3MgKyAzXSArXG4gICAgKGRlY29kZXIuYXJyW2RlY29kZXIucG9zICsgMl0gPDwgOCkgK1xuICAgIChkZWNvZGVyLmFycltkZWNvZGVyLnBvcyArIDFdIDw8IDE2KSArXG4gICAgKGRlY29kZXIuYXJyW2RlY29kZXIucG9zXSA8PCAyNCkpID4+PiAwXG4gIGRlY29kZXIucG9zICs9IDRcbiAgcmV0dXJuIHVpbnRcbn1cblxuLyoqXG4gKiBMb29rIGFoZWFkIHdpdGhvdXQgaW5jcmVtZW50aW5nIHRoZSBwb3NpdGlvblxuICogdG8gdGhlIG5leHQgYnl0ZSBhbmQgcmVhZCBpdCBhcyB1bnNpZ25lZCBpbnRlZ2VyLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtEZWNvZGVyfSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEFuIHVuc2lnbmVkIGludGVnZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBwZWVrVWludDggPSBkZWNvZGVyID0+IGRlY29kZXIuYXJyW2RlY29kZXIucG9zXVxuXG4vKipcbiAqIExvb2sgYWhlYWQgd2l0aG91dCBpbmNyZW1lbnRpbmcgdGhlIHBvc2l0aW9uXG4gKiB0byB0aGUgbmV4dCBieXRlIGFuZCByZWFkIGl0IGFzIHVuc2lnbmVkIGludGVnZXIuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0RlY29kZXJ9IGRlY29kZXJcbiAqIEByZXR1cm4ge251bWJlcn0gQW4gdW5zaWduZWQgaW50ZWdlci5cbiAqL1xuZXhwb3J0IGNvbnN0IHBlZWtVaW50MTYgPSBkZWNvZGVyID0+XG4gIGRlY29kZXIuYXJyW2RlY29kZXIucG9zXSArXG4gIChkZWNvZGVyLmFycltkZWNvZGVyLnBvcyArIDFdIDw8IDgpXG5cbi8qKlxuICogTG9vayBhaGVhZCB3aXRob3V0IGluY3JlbWVudGluZyB0aGUgcG9zaXRpb25cbiAqIHRvIHRoZSBuZXh0IGJ5dGUgYW5kIHJlYWQgaXQgYXMgdW5zaWduZWQgaW50ZWdlci5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RGVjb2Rlcn0gZGVjb2RlclxuICogQHJldHVybiB7bnVtYmVyfSBBbiB1bnNpZ25lZCBpbnRlZ2VyLlxuICovXG5leHBvcnQgY29uc3QgcGVla1VpbnQzMiA9IGRlY29kZXIgPT4gKFxuICBkZWNvZGVyLmFycltkZWNvZGVyLnBvc10gK1xuICAoZGVjb2Rlci5hcnJbZGVjb2Rlci5wb3MgKyAxXSA8PCA4KSArXG4gIChkZWNvZGVyLmFycltkZWNvZGVyLnBvcyArIDJdIDw8IDE2KSArXG4gIChkZWNvZGVyLmFycltkZWNvZGVyLnBvcyArIDNdIDw8IDI0KVxuKSA+Pj4gMFxuXG4vKipcbiAqIFJlYWQgdW5zaWduZWQgaW50ZWdlciAoMzJiaXQpIHdpdGggdmFyaWFibGUgbGVuZ3RoLlxuICogMS84dGggb2YgdGhlIHN0b3JhZ2UgaXMgdXNlZCBhcyBlbmNvZGluZyBvdmVyaGVhZC5cbiAqICAqIG51bWJlcnMgPCAyXjcgaXMgc3RvcmVkIGluIG9uZSBieXRsZW5ndGhcbiAqICAqIG51bWJlcnMgPCAyXjE0IGlzIHN0b3JlZCBpbiB0d28gYnlsZW5ndGhcbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RGVjb2Rlcn0gZGVjb2RlclxuICogQHJldHVybiB7bnVtYmVyfSBBbiB1bnNpZ25lZCBpbnRlZ2VyLmxlbmd0aFxuICovXG5leHBvcnQgY29uc3QgcmVhZFZhclVpbnQgPSBkZWNvZGVyID0+IHtcbiAgbGV0IG51bSA9IDBcbiAgbGV0IG11bHQgPSAxXG4gIGNvbnN0IGxlbiA9IGRlY29kZXIuYXJyLmxlbmd0aFxuICB3aGlsZSAoZGVjb2Rlci5wb3MgPCBsZW4pIHtcbiAgICBjb25zdCByID0gZGVjb2Rlci5hcnJbZGVjb2Rlci5wb3MrK11cbiAgICAvLyBudW0gPSBudW0gfCAoKHIgJiBiaW5hcnkuQklUUzcpIDw8IGxlbilcbiAgICBudW0gPSBudW0gKyAociAmIGJpbmFyeS5CSVRTNykgKiBtdWx0IC8vIHNoaWZ0ICRyIDw8ICg3KiNpdGVyYXRpb25zKSBhbmQgYWRkIGl0IHRvIG51bVxuICAgIG11bHQgKj0gMTI4IC8vIG5leHQgaXRlcmF0aW9uLCBzaGlmdCA3IFwibW9yZVwiIHRvIHRoZSBsZWZ0XG4gICAgaWYgKHIgPCBiaW5hcnkuQklUOCkge1xuICAgICAgcmV0dXJuIG51bVxuICAgIH1cbiAgICAvKiBjOCBpZ25vcmUgc3RhcnQgKi9cbiAgICBpZiAobnVtID4gbnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgIHRocm93IGVycm9ySW50ZWdlck91dE9mUmFuZ2VcbiAgICB9XG4gICAgLyogYzggaWdub3JlIHN0b3AgKi9cbiAgfVxuICB0aHJvdyBlcnJvclVuZXhwZWN0ZWRFbmRPZkFycmF5XG59XG5cbi8qKlxuICogUmVhZCBzaWduZWQgaW50ZWdlciAoMzJiaXQpIHdpdGggdmFyaWFibGUgbGVuZ3RoLlxuICogMS84dGggb2YgdGhlIHN0b3JhZ2UgaXMgdXNlZCBhcyBlbmNvZGluZyBvdmVyaGVhZC5cbiAqICAqIG51bWJlcnMgPCAyXjcgaXMgc3RvcmVkIGluIG9uZSBieXRsZW5ndGhcbiAqICAqIG51bWJlcnMgPCAyXjE0IGlzIHN0b3JlZCBpbiB0d28gYnlsZW5ndGhcbiAqIEB0b2RvIFRoaXMgc2hvdWxkIHByb2JhYmx5IGNyZWF0ZSB0aGUgaW52ZXJzZSB+bnVtIGlmIG51bWJlciBpcyBuZWdhdGl2ZSAtIGJ1dCB0aGlzIHdvdWxkIGJlIGEgYnJlYWtpbmcgY2hhbmdlLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtEZWNvZGVyfSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtudW1iZXJ9IEFuIHVuc2lnbmVkIGludGVnZXIubGVuZ3RoXG4gKi9cbmV4cG9ydCBjb25zdCByZWFkVmFySW50ID0gZGVjb2RlciA9PiB7XG4gIGxldCByID0gZGVjb2Rlci5hcnJbZGVjb2Rlci5wb3MrK11cbiAgbGV0IG51bSA9IHIgJiBiaW5hcnkuQklUUzZcbiAgbGV0IG11bHQgPSA2NFxuICBjb25zdCBzaWduID0gKHIgJiBiaW5hcnkuQklUNykgPiAwID8gLTEgOiAxXG4gIGlmICgociAmIGJpbmFyeS5CSVQ4KSA9PT0gMCkge1xuICAgIC8vIGRvbid0IGNvbnRpbnVlIHJlYWRpbmdcbiAgICByZXR1cm4gc2lnbiAqIG51bVxuICB9XG4gIGNvbnN0IGxlbiA9IGRlY29kZXIuYXJyLmxlbmd0aFxuICB3aGlsZSAoZGVjb2Rlci5wb3MgPCBsZW4pIHtcbiAgICByID0gZGVjb2Rlci5hcnJbZGVjb2Rlci5wb3MrK11cbiAgICAvLyBudW0gPSBudW0gfCAoKHIgJiBiaW5hcnkuQklUUzcpIDw8IGxlbilcbiAgICBudW0gPSBudW0gKyAociAmIGJpbmFyeS5CSVRTNykgKiBtdWx0XG4gICAgbXVsdCAqPSAxMjhcbiAgICBpZiAociA8IGJpbmFyeS5CSVQ4KSB7XG4gICAgICByZXR1cm4gc2lnbiAqIG51bVxuICAgIH1cbiAgICAvKiBjOCBpZ25vcmUgc3RhcnQgKi9cbiAgICBpZiAobnVtID4gbnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpIHtcbiAgICAgIHRocm93IGVycm9ySW50ZWdlck91dE9mUmFuZ2VcbiAgICB9XG4gICAgLyogYzggaWdub3JlIHN0b3AgKi9cbiAgfVxuICB0aHJvdyBlcnJvclVuZXhwZWN0ZWRFbmRPZkFycmF5XG59XG5cbi8qKlxuICogTG9vayBhaGVhZCBhbmQgcmVhZCB2YXJVaW50IHdpdGhvdXQgaW5jcmVtZW50aW5nIHBvc2l0aW9uXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0RlY29kZXJ9IGRlY29kZXJcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuZXhwb3J0IGNvbnN0IHBlZWtWYXJVaW50ID0gZGVjb2RlciA9PiB7XG4gIGNvbnN0IHBvcyA9IGRlY29kZXIucG9zXG4gIGNvbnN0IHMgPSByZWFkVmFyVWludChkZWNvZGVyKVxuICBkZWNvZGVyLnBvcyA9IHBvc1xuICByZXR1cm4gc1xufVxuXG4vKipcbiAqIExvb2sgYWhlYWQgYW5kIHJlYWQgdmFyVWludCB3aXRob3V0IGluY3JlbWVudGluZyBwb3NpdGlvblxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtEZWNvZGVyfSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtudW1iZXJ9XG4gKi9cbmV4cG9ydCBjb25zdCBwZWVrVmFySW50ID0gZGVjb2RlciA9PiB7XG4gIGNvbnN0IHBvcyA9IGRlY29kZXIucG9zXG4gIGNvbnN0IHMgPSByZWFkVmFySW50KGRlY29kZXIpXG4gIGRlY29kZXIucG9zID0gcG9zXG4gIHJldHVybiBzXG59XG5cbi8qKlxuICogV2UgZG9uJ3QgdGVzdCB0aGlzIGZ1bmN0aW9uIGFueW1vcmUgYXMgd2UgdXNlIG5hdGl2ZSBkZWNvZGluZy9lbmNvZGluZyBieSBkZWZhdWx0IG5vdy5cbiAqIEJldHRlciBub3QgbW9kaWZ5IHRoaXMgYW55bW9yZS4uXG4gKlxuICogVHJhbnNmb3JtaW5nIHV0ZjggdG8gYSBzdHJpbmcgaXMgcHJldHR5IGV4cGVuc2l2ZS4gVGhlIGNvZGUgcGVyZm9ybXMgMTB4IGJldHRlclxuICogd2hlbiBTdHJpbmcuZnJvbUNvZGVQb2ludCBpcyBmZWQgd2l0aCBhbGwgY2hhcmFjdGVycyBhcyBhcmd1bWVudHMuXG4gKiBCdXQgbW9zdCBlbnZpcm9ubWVudHMgaGF2ZSBhIG1heGltdW0gbnVtYmVyIG9mIGFyZ3VtZW50cyBwZXIgZnVuY3Rpb25zLlxuICogRm9yIGVmZmllbmN5IHJlYXNvbnMgd2UgYXBwbHkgYSBtYXhpbXVtIG9mIDEwMDAwIGNoYXJhY3RlcnMgYXQgb25jZS5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7RGVjb2Rlcn0gZGVjb2RlclxuICogQHJldHVybiB7U3RyaW5nfSBUaGUgcmVhZCBTdHJpbmcuXG4gKi9cbi8qIGM4IGlnbm9yZSBzdGFydCAqL1xuZXhwb3J0IGNvbnN0IF9yZWFkVmFyU3RyaW5nUG9seWZpbGwgPSBkZWNvZGVyID0+IHtcbiAgbGV0IHJlbWFpbmluZ0xlbiA9IHJlYWRWYXJVaW50KGRlY29kZXIpXG4gIGlmIChyZW1haW5pbmdMZW4gPT09IDApIHtcbiAgICByZXR1cm4gJydcbiAgfSBlbHNlIHtcbiAgICBsZXQgZW5jb2RlZFN0cmluZyA9IFN0cmluZy5mcm9tQ29kZVBvaW50KHJlYWRVaW50OChkZWNvZGVyKSkgLy8gcmVtZW1iZXIgdG8gZGVjcmVhc2UgcmVtYWluaW5nTGVuXG4gICAgaWYgKC0tcmVtYWluaW5nTGVuIDwgMTAwKSB7IC8vIGRvIG5vdCBjcmVhdGUgYSBVaW50OEFycmF5IGZvciBzbWFsbCBzdHJpbmdzXG4gICAgICB3aGlsZSAocmVtYWluaW5nTGVuLS0pIHtcbiAgICAgICAgZW5jb2RlZFN0cmluZyArPSBTdHJpbmcuZnJvbUNvZGVQb2ludChyZWFkVWludDgoZGVjb2RlcikpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlIChyZW1haW5pbmdMZW4gPiAwKSB7XG4gICAgICAgIGNvbnN0IG5leHRMZW4gPSByZW1haW5pbmdMZW4gPCAxMDAwMCA/IHJlbWFpbmluZ0xlbiA6IDEwMDAwXG4gICAgICAgIC8vIHRoaXMgaXMgZGFuZ2Vyb3VzLCB3ZSBjcmVhdGUgYSBmcmVzaCBhcnJheSB2aWV3IGZyb20gdGhlIGV4aXN0aW5nIGJ1ZmZlclxuICAgICAgICBjb25zdCBieXRlcyA9IGRlY29kZXIuYXJyLnN1YmFycmF5KGRlY29kZXIucG9zLCBkZWNvZGVyLnBvcyArIG5leHRMZW4pXG4gICAgICAgIGRlY29kZXIucG9zICs9IG5leHRMZW5cbiAgICAgICAgLy8gU3RhcnRpbmcgd2l0aCBFUzUuMSB3ZSBjYW4gc3VwcGx5IGEgZ2VuZXJpYyBhcnJheS1saWtlIG9iamVjdCBhcyBhcmd1bWVudHNcbiAgICAgICAgZW5jb2RlZFN0cmluZyArPSBTdHJpbmcuZnJvbUNvZGVQb2ludC5hcHBseShudWxsLCAvKiogQHR5cGUge2FueX0gKi8gKGJ5dGVzKSlcbiAgICAgICAgcmVtYWluaW5nTGVuIC09IG5leHRMZW5cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChlc2NhcGUoZW5jb2RlZFN0cmluZykpXG4gIH1cbn1cbi8qIGM4IGlnbm9yZSBzdG9wICovXG5cbi8qKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0RlY29kZXJ9IGRlY29kZXJcbiAqIEByZXR1cm4ge1N0cmluZ30gVGhlIHJlYWQgU3RyaW5nXG4gKi9cbmV4cG9ydCBjb25zdCBfcmVhZFZhclN0cmluZ05hdGl2ZSA9IGRlY29kZXIgPT5cbiAgLyoqIEB0eXBlIGFueSAqLyAoc3RyaW5nLnV0ZjhUZXh0RGVjb2RlcikuZGVjb2RlKHJlYWRWYXJVaW50OEFycmF5KGRlY29kZXIpKVxuXG4vKipcbiAqIFJlYWQgc3RyaW5nIG9mIHZhcmlhYmxlIGxlbmd0aFxuICogKiB2YXJVaW50IGlzIHVzZWQgdG8gc3RvcmUgdGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge0RlY29kZXJ9IGRlY29kZXJcbiAqIEByZXR1cm4ge1N0cmluZ30gVGhlIHJlYWQgU3RyaW5nXG4gKlxuICovXG4vKiBjOCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0IGNvbnN0IHJlYWRWYXJTdHJpbmcgPSBzdHJpbmcudXRmOFRleHREZWNvZGVyID8gX3JlYWRWYXJTdHJpbmdOYXRpdmUgOiBfcmVhZFZhclN0cmluZ1BvbHlmaWxsXG5cbi8qKlxuICogQHBhcmFtIHtEZWNvZGVyfSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICovXG5leHBvcnQgY29uc3QgcmVhZFRlcm1pbmF0ZWRVaW50OEFycmF5ID0gZGVjb2RlciA9PiB7XG4gIGNvbnN0IGVuY29kZXIgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKClcbiAgbGV0IGJcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBiID0gcmVhZFVpbnQ4KGRlY29kZXIpXG4gICAgaWYgKGIgPT09IDApIHtcbiAgICAgIHJldHVybiBlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlcilcbiAgICB9XG4gICAgaWYgKGIgPT09IDEpIHtcbiAgICAgIGIgPSByZWFkVWludDgoZGVjb2RlcilcbiAgICB9XG4gICAgZW5jb2Rpbmcud3JpdGUoZW5jb2RlciwgYilcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7RGVjb2Rlcn0gZGVjb2RlclxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgcmVhZFRlcm1pbmF0ZWRTdHJpbmcgPSBkZWNvZGVyID0+IHN0cmluZy5kZWNvZGVVdGY4KHJlYWRUZXJtaW5hdGVkVWludDhBcnJheShkZWNvZGVyKSlcblxuLyoqXG4gKiBMb29rIGFoZWFkIGFuZCByZWFkIHZhclN0cmluZyB3aXRob3V0IGluY3JlbWVudGluZyBwb3NpdGlvblxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtEZWNvZGVyfSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBjb25zdCBwZWVrVmFyU3RyaW5nID0gZGVjb2RlciA9PiB7XG4gIGNvbnN0IHBvcyA9IGRlY29kZXIucG9zXG4gIGNvbnN0IHMgPSByZWFkVmFyU3RyaW5nKGRlY29kZXIpXG4gIGRlY29kZXIucG9zID0gcG9zXG4gIHJldHVybiBzXG59XG5cbi8qKlxuICogQHBhcmFtIHtEZWNvZGVyfSBkZWNvZGVyXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuXG4gKiBAcmV0dXJuIHtEYXRhVmlld31cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRGcm9tRGF0YVZpZXcgPSAoZGVjb2RlciwgbGVuKSA9PiB7XG4gIGNvbnN0IGR2ID0gbmV3IERhdGFWaWV3KGRlY29kZXIuYXJyLmJ1ZmZlciwgZGVjb2Rlci5hcnIuYnl0ZU9mZnNldCArIGRlY29kZXIucG9zLCBsZW4pXG4gIGRlY29kZXIucG9zICs9IGxlblxuICByZXR1cm4gZHZcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0RlY29kZXJ9IGRlY29kZXJcbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRGbG9hdDMyID0gZGVjb2RlciA9PiByZWFkRnJvbURhdGFWaWV3KGRlY29kZXIsIDQpLmdldEZsb2F0MzIoMCwgZmFsc2UpXG5cbi8qKlxuICogQHBhcmFtIHtEZWNvZGVyfSBkZWNvZGVyXG4gKi9cbmV4cG9ydCBjb25zdCByZWFkRmxvYXQ2NCA9IGRlY29kZXIgPT4gcmVhZEZyb21EYXRhVmlldyhkZWNvZGVyLCA4KS5nZXRGbG9hdDY0KDAsIGZhbHNlKVxuXG4vKipcbiAqIEBwYXJhbSB7RGVjb2Rlcn0gZGVjb2RlclxuICovXG5leHBvcnQgY29uc3QgcmVhZEJpZ0ludDY0ID0gZGVjb2RlciA9PiAvKiogQHR5cGUge2FueX0gKi8gKHJlYWRGcm9tRGF0YVZpZXcoZGVjb2RlciwgOCkpLmdldEJpZ0ludDY0KDAsIGZhbHNlKVxuXG4vKipcbiAqIEBwYXJhbSB7RGVjb2Rlcn0gZGVjb2RlclxuICovXG5leHBvcnQgY29uc3QgcmVhZEJpZ1VpbnQ2NCA9IGRlY29kZXIgPT4gLyoqIEB0eXBlIHthbnl9ICovIChyZWFkRnJvbURhdGFWaWV3KGRlY29kZXIsIDgpKS5nZXRCaWdVaW50NjQoMCwgZmFsc2UpXG5cbi8qKlxuICogQHR5cGUge0FycmF5PGZ1bmN0aW9uKERlY29kZXIpOmFueT59XG4gKi9cbmNvbnN0IHJlYWRBbnlMb29rdXBUYWJsZSA9IFtcbiAgZGVjb2RlciA9PiB1bmRlZmluZWQsIC8vIENBU0UgMTI3OiB1bmRlZmluZWRcbiAgZGVjb2RlciA9PiBudWxsLCAvLyBDQVNFIDEyNjogbnVsbFxuICByZWFkVmFySW50LCAvLyBDQVNFIDEyNTogaW50ZWdlclxuICByZWFkRmxvYXQzMiwgLy8gQ0FTRSAxMjQ6IGZsb2F0MzJcbiAgcmVhZEZsb2F0NjQsIC8vIENBU0UgMTIzOiBmbG9hdDY0XG4gIHJlYWRCaWdJbnQ2NCwgLy8gQ0FTRSAxMjI6IGJpZ2ludFxuICBkZWNvZGVyID0+IGZhbHNlLCAvLyBDQVNFIDEyMTogYm9vbGVhbiAoZmFsc2UpXG4gIGRlY29kZXIgPT4gdHJ1ZSwgLy8gQ0FTRSAxMjA6IGJvb2xlYW4gKHRydWUpXG4gIHJlYWRWYXJTdHJpbmcsIC8vIENBU0UgMTE5OiBzdHJpbmdcbiAgZGVjb2RlciA9PiB7IC8vIENBU0UgMTE4OiBvYmplY3Q8c3RyaW5nLGFueT5cbiAgICBjb25zdCBsZW4gPSByZWFkVmFyVWludChkZWNvZGVyKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLGFueT59XG4gICAgICovXG4gICAgY29uc3Qgb2JqID0ge31cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBjb25zdCBrZXkgPSByZWFkVmFyU3RyaW5nKGRlY29kZXIpXG4gICAgICBvYmpba2V5XSA9IHJlYWRBbnkoZGVjb2RlcilcbiAgICB9XG4gICAgcmV0dXJuIG9ialxuICB9LFxuICBkZWNvZGVyID0+IHsgLy8gQ0FTRSAxMTc6IGFycmF5PGFueT5cbiAgICBjb25zdCBsZW4gPSByZWFkVmFyVWludChkZWNvZGVyKVxuICAgIGNvbnN0IGFyciA9IFtdXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgYXJyLnB1c2gocmVhZEFueShkZWNvZGVyKSlcbiAgICB9XG4gICAgcmV0dXJuIGFyclxuICB9LFxuICByZWFkVmFyVWludDhBcnJheSAvLyBDQVNFIDExNjogVWludDhBcnJheVxuXVxuXG4vKipcbiAqIEBwYXJhbSB7RGVjb2Rlcn0gZGVjb2RlclxuICovXG5leHBvcnQgY29uc3QgcmVhZEFueSA9IGRlY29kZXIgPT4gcmVhZEFueUxvb2t1cFRhYmxlWzEyNyAtIHJlYWRVaW50OChkZWNvZGVyKV0oZGVjb2RlcilcblxuLyoqXG4gKiBUIG11c3Qgbm90IGJlIG51bGwuXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqL1xuZXhwb3J0IGNsYXNzIFJsZURlY29kZXIgZXh0ZW5kcyBEZWNvZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7VWludDhBcnJheX0gdWludDhBcnJheVxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKERlY29kZXIpOlR9IHJlYWRlclxuICAgKi9cbiAgY29uc3RydWN0b3IgKHVpbnQ4QXJyYXksIHJlYWRlcikge1xuICAgIHN1cGVyKHVpbnQ4QXJyYXkpXG4gICAgLyoqXG4gICAgICogVGhlIHJlYWRlclxuICAgICAqL1xuICAgIHRoaXMucmVhZGVyID0gcmVhZGVyXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBzdGF0ZVxuICAgICAqIEB0eXBlIHtUfG51bGx9XG4gICAgICovXG4gICAgdGhpcy5zID0gbnVsbFxuICAgIHRoaXMuY291bnQgPSAwXG4gIH1cblxuICByZWFkICgpIHtcbiAgICBpZiAodGhpcy5jb3VudCA9PT0gMCkge1xuICAgICAgdGhpcy5zID0gdGhpcy5yZWFkZXIodGhpcylcbiAgICAgIGlmIChoYXNDb250ZW50KHRoaXMpKSB7XG4gICAgICAgIHRoaXMuY291bnQgPSByZWFkVmFyVWludCh0aGlzKSArIDEgLy8gc2VlIGVuY29kZXIgaW1wbGVtZW50YXRpb24gZm9yIHRoZSByZWFzb24gd2h5IHRoaXMgaXMgaW5jcmVtZW50ZWRcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY291bnQgPSAtMSAvLyByZWFkIHRoZSBjdXJyZW50IHZhbHVlIGZvcmV2ZXJcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5jb3VudC0tXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7VH0gKi8gKHRoaXMucylcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW50RGlmZkRlY29kZXIgZXh0ZW5kcyBEZWNvZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7VWludDhBcnJheX0gdWludDhBcnJheVxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRcbiAgICovXG4gIGNvbnN0cnVjdG9yICh1aW50OEFycmF5LCBzdGFydCkge1xuICAgIHN1cGVyKHVpbnQ4QXJyYXkpXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBzdGF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5zID0gc3RhcnRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICByZWFkICgpIHtcbiAgICB0aGlzLnMgKz0gcmVhZFZhckludCh0aGlzKVxuICAgIHJldHVybiB0aGlzLnNcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUmxlSW50RGlmZkRlY29kZXIgZXh0ZW5kcyBEZWNvZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7VWludDhBcnJheX0gdWludDhBcnJheVxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnRcbiAgICovXG4gIGNvbnN0cnVjdG9yICh1aW50OEFycmF5LCBzdGFydCkge1xuICAgIHN1cGVyKHVpbnQ4QXJyYXkpXG4gICAgLyoqXG4gICAgICogQ3VycmVudCBzdGF0ZVxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5zID0gc3RhcnRcbiAgICB0aGlzLmNvdW50ID0gMFxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIHJlYWQgKCkge1xuICAgIGlmICh0aGlzLmNvdW50ID09PSAwKSB7XG4gICAgICB0aGlzLnMgKz0gcmVhZFZhckludCh0aGlzKVxuICAgICAgaWYgKGhhc0NvbnRlbnQodGhpcykpIHtcbiAgICAgICAgdGhpcy5jb3VudCA9IHJlYWRWYXJVaW50KHRoaXMpICsgMSAvLyBzZWUgZW5jb2RlciBpbXBsZW1lbnRhdGlvbiBmb3IgdGhlIHJlYXNvbiB3aHkgdGhpcyBpcyBpbmNyZW1lbnRlZFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5jb3VudCA9IC0xIC8vIHJlYWQgdGhlIGN1cnJlbnQgdmFsdWUgZm9yZXZlclxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmNvdW50LS1cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtudW1iZXJ9ICovICh0aGlzLnMpXG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFVpbnRPcHRSbGVEZWNvZGVyIGV4dGVuZHMgRGVjb2RlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVpbnQ4QXJyYXlcbiAgICovXG4gIGNvbnN0cnVjdG9yICh1aW50OEFycmF5KSB7XG4gICAgc3VwZXIodWludDhBcnJheSlcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMucyA9IDBcbiAgICB0aGlzLmNvdW50ID0gMFxuICB9XG5cbiAgcmVhZCAoKSB7XG4gICAgaWYgKHRoaXMuY291bnQgPT09IDApIHtcbiAgICAgIHRoaXMucyA9IHJlYWRWYXJJbnQodGhpcylcbiAgICAgIC8vIGlmIHRoZSBzaWduIGlzIG5lZ2F0aXZlLCB3ZSByZWFkIHRoZSBjb3VudCB0b28sIG90aGVyd2lzZSBjb3VudCBpcyAxXG4gICAgICBjb25zdCBpc05lZ2F0aXZlID0gbWF0aC5pc05lZ2F0aXZlWmVybyh0aGlzLnMpXG4gICAgICB0aGlzLmNvdW50ID0gMVxuICAgICAgaWYgKGlzTmVnYXRpdmUpIHtcbiAgICAgICAgdGhpcy5zID0gLXRoaXMuc1xuICAgICAgICB0aGlzLmNvdW50ID0gcmVhZFZhclVpbnQodGhpcykgKyAyXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuY291bnQtLVxuICAgIHJldHVybiAvKiogQHR5cGUge251bWJlcn0gKi8gKHRoaXMucylcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgSW5jVWludE9wdFJsZURlY29kZXIgZXh0ZW5kcyBEZWNvZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7VWludDhBcnJheX0gdWludDhBcnJheVxuICAgKi9cbiAgY29uc3RydWN0b3IgKHVpbnQ4QXJyYXkpIHtcbiAgICBzdXBlcih1aW50OEFycmF5KVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5zID0gMFxuICAgIHRoaXMuY291bnQgPSAwXG4gIH1cblxuICByZWFkICgpIHtcbiAgICBpZiAodGhpcy5jb3VudCA9PT0gMCkge1xuICAgICAgdGhpcy5zID0gcmVhZFZhckludCh0aGlzKVxuICAgICAgLy8gaWYgdGhlIHNpZ24gaXMgbmVnYXRpdmUsIHdlIHJlYWQgdGhlIGNvdW50IHRvbywgb3RoZXJ3aXNlIGNvdW50IGlzIDFcbiAgICAgIGNvbnN0IGlzTmVnYXRpdmUgPSBtYXRoLmlzTmVnYXRpdmVaZXJvKHRoaXMucylcbiAgICAgIHRoaXMuY291bnQgPSAxXG4gICAgICBpZiAoaXNOZWdhdGl2ZSkge1xuICAgICAgICB0aGlzLnMgPSAtdGhpcy5zXG4gICAgICAgIHRoaXMuY291bnQgPSByZWFkVmFyVWludCh0aGlzKSArIDJcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5jb3VudC0tXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7bnVtYmVyfSAqLyAodGhpcy5zKyspXG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEludERpZmZPcHRSbGVEZWNvZGVyIGV4dGVuZHMgRGVjb2RlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVpbnQ4QXJyYXlcbiAgICovXG4gIGNvbnN0cnVjdG9yICh1aW50OEFycmF5KSB7XG4gICAgc3VwZXIodWludDhBcnJheSlcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMucyA9IDBcbiAgICB0aGlzLmNvdW50ID0gMFxuICAgIHRoaXMuZGlmZiA9IDBcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICByZWFkICgpIHtcbiAgICBpZiAodGhpcy5jb3VudCA9PT0gMCkge1xuICAgICAgY29uc3QgZGlmZiA9IHJlYWRWYXJJbnQodGhpcylcbiAgICAgIC8vIGlmIHRoZSBmaXJzdCBiaXQgaXMgc2V0LCB3ZSByZWFkIG1vcmUgZGF0YVxuICAgICAgY29uc3QgaGFzQ291bnQgPSBkaWZmICYgMVxuICAgICAgdGhpcy5kaWZmID0gbWF0aC5mbG9vcihkaWZmIC8gMikgLy8gc2hpZnQgPj4gMVxuICAgICAgdGhpcy5jb3VudCA9IDFcbiAgICAgIGlmIChoYXNDb3VudCkge1xuICAgICAgICB0aGlzLmNvdW50ID0gcmVhZFZhclVpbnQodGhpcykgKyAyXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucyArPSB0aGlzLmRpZmZcbiAgICB0aGlzLmNvdW50LS1cbiAgICByZXR1cm4gdGhpcy5zXG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFN0cmluZ0RlY29kZXIge1xuICAvKipcbiAgICogQHBhcmFtIHtVaW50OEFycmF5fSB1aW50OEFycmF5XG4gICAqL1xuICBjb25zdHJ1Y3RvciAodWludDhBcnJheSkge1xuICAgIHRoaXMuZGVjb2RlciA9IG5ldyBVaW50T3B0UmxlRGVjb2Rlcih1aW50OEFycmF5KVxuICAgIHRoaXMuc3RyID0gcmVhZFZhclN0cmluZyh0aGlzLmRlY29kZXIpXG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLnNwb3MgPSAwXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgcmVhZCAoKSB7XG4gICAgY29uc3QgZW5kID0gdGhpcy5zcG9zICsgdGhpcy5kZWNvZGVyLnJlYWQoKVxuICAgIGNvbnN0IHJlcyA9IHRoaXMuc3RyLnNsaWNlKHRoaXMuc3BvcywgZW5kKVxuICAgIHRoaXMuc3BvcyA9IGVuZFxuICAgIHJldHVybiByZXNcbiAgfVxufVxuIiwgIi8qIGVzbGludC1lbnYgYnJvd3NlciAqL1xuXG5leHBvcnQgY29uc3Qgc3VidGxlID0gY3J5cHRvLnN1YnRsZVxuZXhwb3J0IGNvbnN0IGdldFJhbmRvbVZhbHVlcyA9IGNyeXB0by5nZXRSYW5kb21WYWx1ZXMuYmluZChjcnlwdG8pXG4iLCAiLyoqXG4gKiBJc29tb3JwaGljIG1vZHVsZSBmb3IgdHJ1ZSByYW5kb20gbnVtYmVycyAvIGJ1ZmZlcnMgLyB1dWlkcy5cbiAqXG4gKiBBdHRlbnRpb246IGZhbGxzIGJhY2sgdG8gTWF0aC5yYW5kb20gaWYgdGhlIGJyb3dzZXIgZG9lcyBub3Qgc3VwcG9ydCBjcnlwdG8uXG4gKlxuICogQG1vZHVsZSByYW5kb21cbiAqL1xuXG5pbXBvcnQgKiBhcyBtYXRoIGZyb20gJy4vbWF0aC5qcydcbmltcG9ydCAqIGFzIGJpbmFyeSBmcm9tICcuL2JpbmFyeS5qcydcbmltcG9ydCB7IGdldFJhbmRvbVZhbHVlcyB9IGZyb20gJ2xpYjAvd2ViY3J5cHRvJ1xuXG5leHBvcnQgY29uc3QgcmFuZCA9IE1hdGgucmFuZG9tXG5cbmV4cG9ydCBjb25zdCB1aW50MzIgPSAoKSA9PiBnZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQzMkFycmF5KDEpKVswXVxuXG5leHBvcnQgY29uc3QgdWludDUzID0gKCkgPT4ge1xuICBjb25zdCBhcnIgPSBnZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQzMkFycmF5KDgpKVxuICByZXR1cm4gKGFyclswXSAmIGJpbmFyeS5CSVRTMjEpICogKGJpbmFyeS5CSVRTMzIgKyAxKSArIChhcnJbMV0gPj4+IDApXG59XG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7QXJyYXk8VD59IGFyclxuICogQHJldHVybiB7VH1cbiAqL1xuZXhwb3J0IGNvbnN0IG9uZU9mID0gYXJyID0+IGFyclttYXRoLmZsb29yKHJhbmQoKSAqIGFyci5sZW5ndGgpXVxuXG4vLyBAdHMtaWdub3JlXG5jb25zdCB1dWlkdjRUZW1wbGF0ZSA9IFsxZTddICsgLTFlMyArIC00ZTMgKyAtOGUzICsgLTFlMTFcblxuLyoqXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmV4cG9ydCBjb25zdCB1dWlkdjQgPSAoKSA9PiB1dWlkdjRUZW1wbGF0ZS5yZXBsYWNlKC9bMDE4XS9nLCAvKiogQHBhcmFtIHtudW1iZXJ9IGMgKi8gYyA9PlxuICAoYyBeIHVpbnQzMigpICYgMTUgPj4gYyAvIDQpLnRvU3RyaW5nKDE2KVxuKVxuIiwgIi8qKlxuICogVXRpbGl0eSBtb2R1bGUgdG8gd29yayB3aXRoIHRpbWUuXG4gKlxuICogQG1vZHVsZSB0aW1lXG4gKi9cblxuaW1wb3J0ICogYXMgbWV0cmljIGZyb20gJy4vbWV0cmljLmpzJ1xuaW1wb3J0ICogYXMgbWF0aCBmcm9tICcuL21hdGguanMnXG5cbi8qKlxuICogUmV0dXJuIGN1cnJlbnQgdGltZS5cbiAqXG4gKiBAcmV0dXJuIHtEYXRlfVxuICovXG5leHBvcnQgY29uc3QgZ2V0RGF0ZSA9ICgpID0+IG5ldyBEYXRlKClcblxuLyoqXG4gKiBSZXR1cm4gY3VycmVudCB1bml4IHRpbWUuXG4gKlxuICogQHJldHVybiB7bnVtYmVyfVxuICovXG5leHBvcnQgY29uc3QgZ2V0VW5peFRpbWUgPSBEYXRlLm5vd1xuXG4vKipcbiAqIFRyYW5zZm9ybSB0aW1lIChpbiBtcykgdG8gYSBodW1hbiByZWFkYWJsZSBmb3JtYXQuIEUuZy4gMTEwMCA9PiAxLjFzLiA2MHMgPT4gMW1pbi4gLjAwMSA9PiAxMFx1MDNCQ3MuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGQgZHVyYXRpb24gaW4gbWlsbGlzZWNvbmRzXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGh1bWFuaXplZCBhcHByb3hpbWF0aW9uIG9mIHRpbWVcbiAqL1xuZXhwb3J0IGNvbnN0IGh1bWFuaXplRHVyYXRpb24gPSBkID0+IHtcbiAgaWYgKGQgPCA2MDAwMCkge1xuICAgIGNvbnN0IHAgPSBtZXRyaWMucHJlZml4KGQsIC0xKVxuICAgIHJldHVybiBtYXRoLnJvdW5kKHAubiAqIDEwMCkgLyAxMDAgKyBwLnByZWZpeCArICdzJ1xuICB9XG4gIGQgPSBtYXRoLmZsb29yKGQgLyAxMDAwKVxuICBjb25zdCBzZWNvbmRzID0gZCAlIDYwXG4gIGNvbnN0IG1pbnV0ZXMgPSBtYXRoLmZsb29yKGQgLyA2MCkgJSA2MFxuICBjb25zdCBob3VycyA9IG1hdGguZmxvb3IoZCAvIDM2MDApICUgMjRcbiAgY29uc3QgZGF5cyA9IG1hdGguZmxvb3IoZCAvIDg2NDAwKVxuICBpZiAoZGF5cyA+IDApIHtcbiAgICByZXR1cm4gZGF5cyArICdkJyArICgoaG91cnMgPiAwIHx8IG1pbnV0ZXMgPiAzMCkgPyAnICcgKyAobWludXRlcyA+IDMwID8gaG91cnMgKyAxIDogaG91cnMpICsgJ2gnIDogJycpXG4gIH1cbiAgaWYgKGhvdXJzID4gMCkge1xuICAgIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gICAgcmV0dXJuIGhvdXJzICsgJ2gnICsgKChtaW51dGVzID4gMCB8fCBzZWNvbmRzID4gMzApID8gJyAnICsgKHNlY29uZHMgPiAzMCA/IG1pbnV0ZXMgKyAxIDogbWludXRlcykgKyAnbWluJyA6ICcnKVxuICB9XG4gIHJldHVybiBtaW51dGVzICsgJ21pbicgKyAoc2Vjb25kcyA+IDAgPyAnICcgKyBzZWNvbmRzICsgJ3MnIDogJycpXG59XG4iLCAiLyoqXG4gKiBVdGlsaXR5IGhlbHBlcnMgdG8gd29yayB3aXRoIHByb21pc2VzLlxuICpcbiAqIEBtb2R1bGUgcHJvbWlzZVxuICovXG5cbmltcG9ydCAqIGFzIHRpbWUgZnJvbSAnLi90aW1lLmpzJ1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAY2FsbGJhY2sgUHJvbWlzZVJlc29sdmVcbiAqIEBwYXJhbSB7VHxQcm9taXNlTGlrZTxUPn0gW3Jlc3VsdF1cbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFByb21pc2VSZXNvbHZlPFQ+LGZ1bmN0aW9uKEVycm9yKTp2b2lkKTphbnl9IGZcbiAqIEByZXR1cm4ge1Byb21pc2U8VD59XG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGUgPSBmID0+IC8qKiBAdHlwZSB7UHJvbWlzZTxUPn0gKi8gKG5ldyBQcm9taXNlKGYpKVxuXG4vKipcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oZnVuY3Rpb24oKTp2b2lkLGZ1bmN0aW9uKEVycm9yKTp2b2lkKTp2b2lkfSBmXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlRW1wdHkgPSBmID0+IG5ldyBQcm9taXNlKGYpXG5cbi8qKlxuICogYFByb21pc2UuYWxsYCB3YWl0IGZvciBhbGwgcHJvbWlzZXMgaW4gdGhlIGFycmF5IHRvIHJlc29sdmUgYW5kIHJldHVybiB0aGUgcmVzdWx0XG4gKiBAdGVtcGxhdGUge3Vua25vd25bXSB8IFtdfSBQU1xuICpcbiAqIEBwYXJhbSB7UFN9IHBzXG4gKiBAcmV0dXJuIHtQcm9taXNlPHsgLXJlYWRvbmx5IFtQIGluIGtleW9mIFBTXTogQXdhaXRlZDxQU1tQXT4gfT59XG4gKi9cbmV4cG9ydCBjb25zdCBhbGwgPSBQcm9taXNlLmFsbC5iaW5kKFByb21pc2UpXG5cbi8qKlxuICogQHBhcmFtIHtFcnJvcn0gW3JlYXNvbl1cbiAqIEByZXR1cm4ge1Byb21pc2U8bmV2ZXI+fVxuICovXG5leHBvcnQgY29uc3QgcmVqZWN0ID0gcmVhc29uID0+IFByb21pc2UucmVqZWN0KHJlYXNvbilcblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtUfHZvaWR9IHJlc1xuICogQHJldHVybiB7UHJvbWlzZTxUfHZvaWQ+fVxuICovXG5leHBvcnQgY29uc3QgcmVzb2x2ZSA9IHJlcyA9PiBQcm9taXNlLnJlc29sdmUocmVzKVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge1R9IHJlc1xuICogQHJldHVybiB7UHJvbWlzZTxUPn1cbiAqL1xuZXhwb3J0IGNvbnN0IHJlc29sdmVXaXRoID0gcmVzID0+IFByb21pc2UucmVzb2x2ZShyZXMpXG5cbi8qKlxuICogQHRvZG8gTmV4dCB2ZXJzaW9uLCByZW9yZGVyIHBhcmFtZXRlcnM6IGNoZWNrLCBbdGltZW91dCwgW2ludGVydmFsUmVzb2x1dGlvbl1dXG4gKiBAZGVwcmVjYXRlZCB1c2UgdW50aWxBc3luYyBpbnN0ZWFkXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKTpib29sZWFufSBjaGVja1xuICogQHBhcmFtIHtudW1iZXJ9IFtpbnRlcnZhbFJlc29sdXRpb25dXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fVxuICovXG5leHBvcnQgY29uc3QgdW50aWwgPSAodGltZW91dCwgY2hlY2ssIGludGVydmFsUmVzb2x1dGlvbiA9IDEwKSA9PiBjcmVhdGUoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICBjb25zdCBzdGFydFRpbWUgPSB0aW1lLmdldFVuaXhUaW1lKClcbiAgY29uc3QgaGFzVGltZW91dCA9IHRpbWVvdXQgPiAwXG4gIGNvbnN0IHVudGlsSW50ZXJ2YWwgPSAoKSA9PiB7XG4gICAgaWYgKGNoZWNrKCkpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxIYW5kbGUpXG4gICAgICByZXNvbHZlKClcbiAgICB9IGVsc2UgaWYgKGhhc1RpbWVvdXQpIHtcbiAgICAgIC8qIGM4IGlnbm9yZSBlbHNlICovXG4gICAgICBpZiAodGltZS5nZXRVbml4VGltZSgpIC0gc3RhcnRUaW1lID4gdGltZW91dCkge1xuICAgICAgICBjbGVhckludGVydmFsKGludGVydmFsSGFuZGxlKVxuICAgICAgICByZWplY3QobmV3IEVycm9yKCdUaW1lb3V0JykpXG4gICAgICB9XG4gICAgfVxuICB9XG4gIGNvbnN0IGludGVydmFsSGFuZGxlID0gc2V0SW50ZXJ2YWwodW50aWxJbnRlcnZhbCwgaW50ZXJ2YWxSZXNvbHV0aW9uKVxufSlcblxuLyoqXG4gKiBAcGFyYW0geygpPT5Qcm9taXNlPGJvb2xlYW4+fGJvb2xlYW59IGNoZWNrXG4gKiBAcGFyYW0ge251bWJlcn0gdGltZW91dFxuICogQHBhcmFtIHtudW1iZXJ9IGludGVydmFsUmVzb2x1dGlvblxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn1cbiAqL1xuZXhwb3J0IGNvbnN0IHVudGlsQXN5bmMgPSBhc3luYyAoY2hlY2ssIHRpbWVvdXQgPSAwLCBpbnRlcnZhbFJlc29sdXRpb24gPSAxMCkgPT4ge1xuICBjb25zdCBzdGFydFRpbWUgPSB0aW1lLmdldFVuaXhUaW1lKClcbiAgY29uc3Qgbm9UaW1lb3V0ID0gdGltZW91dCA8PSAwXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bm1vZGlmaWVkLWxvb3AtY29uZGl0aW9uXG4gIHdoaWxlIChub1RpbWVvdXQgfHwgdGltZS5nZXRVbml4VGltZSgpIC0gc3RhcnRUaW1lIDw9IHRpbWVvdXQpIHtcbiAgICBpZiAoYXdhaXQgY2hlY2soKSkgcmV0dXJuXG4gICAgYXdhaXQgd2FpdChpbnRlcnZhbFJlc29sdXRpb24pXG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdUaW1lb3V0Jylcbn1cblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdGltZW91dFxuICogQHJldHVybiB7UHJvbWlzZTx1bmRlZmluZWQ+fVxuICovXG5leHBvcnQgY29uc3Qgd2FpdCA9IHRpbWVvdXQgPT4gY3JlYXRlKChyZXNvbHZlLCBfcmVqZWN0KSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIHRpbWVvdXQpKVxuXG4vKipcbiAqIENoZWNrcyBpZiBhbiBvYmplY3QgaXMgYSBwcm9taXNlIHVzaW5nIGR1Y2t0eXBpbmcuXG4gKlxuICogUHJvbWlzZXMgYXJlIG9mdGVuIHBvbHlmaWxsZWQsIHNvIGl0IG1ha2VzIHNlbnNlIHRvIGFkZCBzb21lIGFkZGl0aW9uYWwgZ3VhcmFudGVlcyBpZiB0aGUgdXNlciBvZiB0aGlzXG4gKiBsaWJyYXJ5IGhhcyBzb21lIGluc2FuZSBlbnZpcm9ubWVudCB3aGVyZSBnbG9iYWwgUHJvbWlzZSBvYmplY3RzIGFyZSBvdmVyd3JpdHRlbi5cbiAqXG4gKiBAcGFyYW0ge2FueX0gcFxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGNvbnN0IGlzUHJvbWlzZSA9IHAgPT4gcCBpbnN0YW5jZW9mIFByb21pc2UgfHwgKHAgJiYgcC50aGVuICYmIHAuY2F0Y2ggJiYgcC5maW5hbGx5KVxuIiwgIi8qKlxuICogT2Z0ZW4gdXNlZCBjb25kaXRpb25zLlxuICpcbiAqIEBtb2R1bGUgY29uZGl0aW9uc1xuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7VHxudWxsfHVuZGVmaW5lZH0gdlxuICogQHJldHVybiB7VHxudWxsfVxuICovXG4vKiBjOCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0IGNvbnN0IHVuZGVmaW5lZFRvTnVsbCA9IHYgPT4gdiA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IHZcbiIsICIvKiBlc2xpbnQtZW52IGJyb3dzZXIgKi9cblxuLyoqXG4gKiBJc29tb3JwaGljIHZhcmlhYmxlIHN0b3JhZ2UuXG4gKlxuICogVXNlcyBMb2NhbFN0b3JhZ2UgaW4gdGhlIGJyb3dzZXIgYW5kIGZhbGxzIGJhY2sgdG8gaW4tbWVtb3J5IHN0b3JhZ2UuXG4gKlxuICogQG1vZHVsZSBzdG9yYWdlXG4gKi9cblxuLyogYzggaWdub3JlIHN0YXJ0ICovXG5jbGFzcyBWYXJTdG9yYWdlUG9seWZpbGwge1xuICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgdGhpcy5tYXAgPSBuZXcgTWFwKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gICAqIEBwYXJhbSB7YW55fSBuZXdWYWx1ZVxuICAgKi9cbiAgc2V0SXRlbSAoa2V5LCBuZXdWYWx1ZSkge1xuICAgIHRoaXMubWFwLnNldChrZXksIG5ld1ZhbHVlKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAgICovXG4gIGdldEl0ZW0gKGtleSkge1xuICAgIHJldHVybiB0aGlzLm1hcC5nZXQoa2V5KVxuICB9XG59XG4vKiBjOCBpZ25vcmUgc3RvcCAqL1xuXG4vKipcbiAqIEB0eXBlIHthbnl9XG4gKi9cbmxldCBfbG9jYWxTdG9yYWdlID0gbmV3IFZhclN0b3JhZ2VQb2x5ZmlsbCgpXG5sZXQgdXNlUG9seWZpbGwgPSB0cnVlXG5cbi8qIGM4IGlnbm9yZSBzdGFydCAqL1xudHJ5IHtcbiAgLy8gaWYgdGhlIHNhbWUtb3JpZ2luIHJ1bGUgaXMgdmlvbGF0ZWQsIGFjY2Vzc2luZyBsb2NhbFN0b3JhZ2UgbWlnaHQgdGhyb3duIGFuIGVycm9yXG4gIGlmICh0eXBlb2YgbG9jYWxTdG9yYWdlICE9PSAndW5kZWZpbmVkJyAmJiBsb2NhbFN0b3JhZ2UpIHtcbiAgICBfbG9jYWxTdG9yYWdlID0gbG9jYWxTdG9yYWdlXG4gICAgdXNlUG9seWZpbGwgPSBmYWxzZVxuICB9XG59IGNhdGNoIChlKSB7IH1cbi8qIGM4IGlnbm9yZSBzdG9wICovXG5cbi8qKlxuICogVGhpcyBpcyBiYXNpY2FsbHkgbG9jYWxTdG9yYWdlIGluIGJyb3dzZXIsIG9yIGEgcG9seWZpbGwgaW4gbm9kZWpzXG4gKi9cbi8qIGM4IGlnbm9yZSBuZXh0ICovXG5leHBvcnQgY29uc3QgdmFyU3RvcmFnZSA9IF9sb2NhbFN0b3JhZ2VcblxuLyoqXG4gKiBBIHBvbHlmaWxsIGZvciBgYWRkRXZlbnRMaXN0ZW5lcignc3RvcmFnZScsIGV2ZW50ID0+IHsuLn0pYCB0aGF0IGRvZXMgbm90aGluZyBpZiB0aGUgcG9seWZpbGwgaXMgYmVpbmcgdXNlZC5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKHsga2V5OiBzdHJpbmcsIG5ld1ZhbHVlOiBzdHJpbmcsIG9sZFZhbHVlOiBzdHJpbmcgfSk6IHZvaWR9IGV2ZW50SGFuZGxlclxuICogQGZ1bmN0aW9uXG4gKi9cbi8qIGM4IGlnbm9yZSBuZXh0ICovXG5leHBvcnQgY29uc3Qgb25DaGFuZ2UgPSBldmVudEhhbmRsZXIgPT4gdXNlUG9seWZpbGwgfHwgYWRkRXZlbnRMaXN0ZW5lcignc3RvcmFnZScsIC8qKiBAdHlwZSB7YW55fSAqLyAoZXZlbnRIYW5kbGVyKSlcblxuLyoqXG4gKiBBIHBvbHlmaWxsIGZvciBgcmVtb3ZlRXZlbnRMaXN0ZW5lcignc3RvcmFnZScsIGV2ZW50ID0+IHsuLn0pYCB0aGF0IGRvZXMgbm90aGluZyBpZiB0aGUgcG9seWZpbGwgaXMgYmVpbmcgdXNlZC5cbiAqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKHsga2V5OiBzdHJpbmcsIG5ld1ZhbHVlOiBzdHJpbmcsIG9sZFZhbHVlOiBzdHJpbmcgfSk6IHZvaWR9IGV2ZW50SGFuZGxlclxuICogQGZ1bmN0aW9uXG4gKi9cbi8qIGM4IGlnbm9yZSBuZXh0ICovXG5leHBvcnQgY29uc3Qgb2ZmQ2hhbmdlID0gZXZlbnRIYW5kbGVyID0+IHVzZVBvbHlmaWxsIHx8IHJlbW92ZUV2ZW50TGlzdGVuZXIoJ3N0b3JhZ2UnLCAvKiogQHR5cGUge2FueX0gKi8gKGV2ZW50SGFuZGxlcikpXG4iLCAiZXhwb3J0IGNvbnN0IEVxdWFsaXR5VHJhaXRTeW1ib2wgPSBTeW1ib2woJ0VxdWFsaXR5JylcblxuLyoqXG4gKiBAdHlwZWRlZiB7eyBbRXF1YWxpdHlUcmFpdFN5bWJvbF06KG90aGVyOkVxdWFsaXR5VHJhaXQpPT5ib29sZWFuIH19IEVxdWFsaXR5VHJhaXRcbiAqL1xuXG4vKipcbiAqXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIHRvIGNvbXBhcmUgYW55IHR3byBvYmplY3RzLlxuICpcbiAqIE5vdGUgdGhhdCBpdCBpcyBleHBlY3RlZCB0aGF0IHRoZSBmaXJzdCBwYXJhbWV0ZXIgaXMgbW9yZSBzcGVjaWZpYyB0aGFuIHRoZSBsYXR0ZXIgb25lLlxuICpcbiAqIEBleGFtcGxlIGpzXG4gKiAgICAgY2xhc3MgWCB7IFt0cmFpdHMuRXF1YWxpdHlUcmFpdFN5bWJvbF0gKG90aGVyKSB7IHJldHVybiBvdGhlciA9PT0gdGhpcyB9ICB9XG4gKiAgICAgY2xhc3MgWDIgeyBbdHJhaXRzLkVxdWFsaXR5VHJhaXRTeW1ib2xdIChvdGhlcikgeyByZXR1cm4gb3RoZXIgPT09IHRoaXMgfSwgeDIgKCkgeyByZXR1cm4gMiB9ICB9XG4gKiAgICAgLy8gdGhpcyBpcyBmaW5lXG4gKiAgICAgdHJhaXRzLmVxdWFscyhuZXcgWDIoKSwgbmV3IFgoKSlcbiAqICAgICAvLyB0aGlzIGlzIG5vdCwgYmVjYXVzZSB0aGUgbGVmdCB0eXBlIGlzIGxlc3Mgc3BlY2lmaWMgdGhhbiB0aGUgcmlnaHQgb25lXG4gKiAgICAgdHJhaXRzLmVxdWFscyhuZXcgWCgpLCBuZXcgWDIoKSlcbiAqXG4gKiBAdGVtcGxhdGUge0VxdWFsaXR5VHJhaXR9IFRcbiAqIEBwYXJhbSB7Tm9JbmZlcjxUPn0gYVxuICogQHBhcmFtIHtUfSBiXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgY29uc3QgZXF1YWxzID0gKGEsIGIpID0+IGEgPT09IGIgfHwgISFhPy5bRXF1YWxpdHlUcmFpdFN5bWJvbF0/LihiKSB8fCBmYWxzZVxuIiwgImltcG9ydCAqIGFzIGVxdWFsaXR5VHJhaXQgZnJvbSAnLi90cmFpdC9lcXVhbGl0eS5qcydcblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9ucyBmb3Igd29ya2luZyB3aXRoIEVjbWFTY3JpcHQgb2JqZWN0cy5cbiAqXG4gKiBAbW9kdWxlIG9iamVjdFxuICovXG5cbi8qKlxuICogQHJldHVybiB7T2JqZWN0PHN0cmluZyxhbnk+fSBvYmpcbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZSA9ICgpID0+IE9iamVjdC5jcmVhdGUobnVsbClcblxuLyoqXG4gKiBAcGFyYW0ge2FueX0gb1xuICogQHJldHVybiB7byBpcyB7IFtrOnN0cmluZ106YW55IH19XG4gKi9cbmV4cG9ydCBjb25zdCBpc09iamVjdCA9IG8gPT4gdHlwZW9mIG8gPT09ICdvYmplY3QnXG5cbi8qKlxuICogT2JqZWN0LmFzc2lnblxuICovXG5leHBvcnQgY29uc3QgYXNzaWduID0gT2JqZWN0LmFzc2lnblxuXG4vKipcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZyxhbnk+fSBvYmpcbiAqL1xuZXhwb3J0IGNvbnN0IGtleXMgPSBPYmplY3Qua2V5c1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBWXG4gKiBAcGFyYW0ge3tba2V5OnN0cmluZ106IFZ9fSBvYmpcbiAqIEByZXR1cm4ge0FycmF5PFY+fVxuICovXG5leHBvcnQgY29uc3QgdmFsdWVzID0gT2JqZWN0LnZhbHVlc1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBWXG4gKiBAcGFyYW0ge3tbazpzdHJpbmddOlZ9fSBvYmpcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oVixzdHJpbmcpOmFueX0gZlxuICovXG5leHBvcnQgY29uc3QgZm9yRWFjaCA9IChvYmosIGYpID0+IHtcbiAgZm9yIChjb25zdCBrZXkgaW4gb2JqKSB7XG4gICAgZihvYmpba2V5XSwga2V5KVxuICB9XG59XG5cbi8qKlxuICogQHRvZG8gaW1wbGVtZW50IG1hcFRvQXJyYXkgJiBtYXBcbiAqXG4gKiBAdGVtcGxhdGUgUlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLGFueT59IG9ialxuICogQHBhcmFtIHtmdW5jdGlvbihhbnksc3RyaW5nKTpSfSBmXG4gKiBAcmV0dXJuIHtBcnJheTxSPn1cbiAqL1xuZXhwb3J0IGNvbnN0IG1hcCA9IChvYmosIGYpID0+IHtcbiAgY29uc3QgcmVzdWx0cyA9IFtdXG4gIGZvciAoY29uc3Qga2V5IGluIG9iaikge1xuICAgIHJlc3VsdHMucHVzaChmKG9ialtrZXldLCBrZXkpKVxuICB9XG4gIHJldHVybiByZXN1bHRzXG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgdXNlIG9iamVjdC5zaXplIGluc3RlYWRcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZyxhbnk+fSBvYmpcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuZXhwb3J0IGNvbnN0IGxlbmd0aCA9IG9iaiA9PiBrZXlzKG9iaikubGVuZ3RoXG5cbi8qKlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLGFueT59IG9ialxuICogQHJldHVybiB7bnVtYmVyfVxuICovXG5leHBvcnQgY29uc3Qgc2l6ZSA9IG9iaiA9PiBrZXlzKG9iaikubGVuZ3RoXG5cbi8qKlxuICogQHRlbXBsYXRlIHt7IFtrZXk6c3RyaW5nfG51bWJlcnxzeW1ib2xdOiBhbnkgfX0gVFxuICogQHBhcmFtIHtUfSBvYmpcbiAqIEBwYXJhbSB7KHY6VFtrZXlvZiBUXSxrOmtleW9mIFQpPT5ib29sZWFufSBmXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgY29uc3Qgc29tZSA9IChvYmosIGYpID0+IHtcbiAgZm9yIChjb25zdCBrZXkgaW4gb2JqKSB7XG4gICAgaWYgKGYob2JqW2tleV0sIGtleSkpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuXG4vKipcbiAqIEBwYXJhbSB7T2JqZWN0fG51bGx8dW5kZWZpbmVkfSBvYmpcbiAqL1xuZXhwb3J0IGNvbnN0IGlzRW1wdHkgPSBvYmogPT4ge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5yZWFjaGFibGUtbG9vcFxuICBmb3IgKGNvbnN0IF9rIGluIG9iaikge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogQHRlbXBsYXRlIHt7IFtrZXk6c3RyaW5nfG51bWJlcnxzeW1ib2xdOiBhbnkgfX0gVFxuICogQHBhcmFtIHtUfSBvYmpcbiAqIEBwYXJhbSB7KHY6VFtrZXlvZiBUXSxrOmtleW9mIFQpPT5ib29sZWFufSBmXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgY29uc3QgZXZlcnkgPSAob2JqLCBmKSA9PiB7XG4gIGZvciAoY29uc3Qga2V5IGluIG9iaikge1xuICAgIGlmICghZihvYmpba2V5XSwga2V5KSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogQ2FsbHMgYE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlgLlxuICpcbiAqIEBwYXJhbSB7YW55fSBvYmpcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcnxzeW1ib2x9IGtleVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGNvbnN0IGhhc1Byb3BlcnR5ID0gKG9iaiwga2V5KSA9PiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpXG5cbi8qKlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLGFueT59IGFcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZyxhbnk+fSBiXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgY29uc3QgZXF1YWxGbGF0ID0gKGEsIGIpID0+IGEgPT09IGIgfHwgKHNpemUoYSkgPT09IHNpemUoYikgJiYgZXZlcnkoYSwgKHZhbCwga2V5KSA9PiAodmFsICE9PSB1bmRlZmluZWQgfHwgaGFzUHJvcGVydHkoYiwga2V5KSkgJiYgZXF1YWxpdHlUcmFpdC5lcXVhbHMoYltrZXldLCB2YWwpKSlcblxuLyoqXG4gKiBNYWtlIGFuIG9iamVjdCBpbW11dGFibGUuIFRoaXMgaHVydHMgcGVyZm9ybWFuY2UgYW5kIGlzIHVzdWFsbHkgbm90IG5lZWRlZCBpZiB5b3UgcGVyZm9ybSBnb29kXG4gKiBjb2RpbmcgcHJhY3RpY2VzLlxuICovXG5leHBvcnQgY29uc3QgZnJlZXplID0gT2JqZWN0LmZyZWV6ZVxuXG4vKipcbiAqIE1ha2UgYW4gb2JqZWN0IGFuZCBhbGwgaXRzIGNoaWxkcmVuIGltbXV0YWJsZS5cbiAqIFRoaXMgKnJlYWxseSogaHVydHMgcGVyZm9ybWFuY2UgYW5kIGlzIHVzdWFsbHkgbm90IG5lZWRlZCBpZiB5b3UgcGVyZm9ybSBnb29kIGNvZGluZyBwcmFjdGljZXMuXG4gKlxuICogQHRlbXBsYXRlIHthbnl9IFRcbiAqIEBwYXJhbSB7VH0gb1xuICogQHJldHVybiB7UmVhZG9ubHk8VD59XG4gKi9cbmV4cG9ydCBjb25zdCBkZWVwRnJlZXplID0gKG8pID0+IHtcbiAgZm9yIChjb25zdCBrZXkgaW4gbykge1xuICAgIGNvbnN0IGMgPSBvW2tleV1cbiAgICBpZiAodHlwZW9mIGMgPT09ICdvYmplY3QnIHx8IHR5cGVvZiBjID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBkZWVwRnJlZXplKG9ba2V5XSlcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZyZWV6ZShvKVxufVxuXG4vKipcbiAqIEdldCBvYmplY3QgcHJvcGVydHkuIENyZWF0ZSBUIGlmIHByb3BlcnR5IGlzIHVuZGVmaW5lZCBhbmQgc2V0IFQgb24gb2JqZWN0LlxuICpcbiAqIEBmdW5jdGlvblxuICogQHRlbXBsYXRlIHtvYmplY3R9IEtWXG4gKiBAdGVtcGxhdGUge2tleW9mIEtWfSBbSz1rZXlvZiBLVl1cbiAqIEBwYXJhbSB7S1Z9IG9cbiAqIEBwYXJhbSB7S30ga2V5XG4gKiBAcGFyYW0geygpID0+IEtWW0tdfSBjcmVhdGVUXG4gKiBAcmV0dXJuIHtLVltLXX1cbiAqL1xuZXhwb3J0IGNvbnN0IHNldElmVW5kZWZpbmVkID0gKG8sIGtleSwgY3JlYXRlVCkgPT4gaGFzUHJvcGVydHkobywga2V5KSA/IG9ba2V5XSA6IChvW2tleV0gPSBjcmVhdGVUKCkpXG4iLCAiLyoqXG4gKiBDb21tb24gZnVuY3Rpb25zIGFuZCBmdW5jdGlvbiBjYWxsIGhlbHBlcnMuXG4gKlxuICogQG1vZHVsZSBmdW5jdGlvblxuICovXG5cbmltcG9ydCAqIGFzIGFycmF5IGZyb20gJy4vYXJyYXkuanMnXG5pbXBvcnQgKiBhcyBvYmplY3QgZnJvbSAnLi9vYmplY3QuanMnXG5pbXBvcnQgKiBhcyBlcXVhbGl0eVRyYWl0IGZyb20gJy4vdHJhaXQvZXF1YWxpdHkuanMnXG5cbi8qKlxuICogQ2FsbHMgYWxsIGZ1bmN0aW9ucyBpbiBgZnNgIHdpdGggYXJncy4gT25seSB0aHJvd3MgYWZ0ZXIgYWxsIGZ1bmN0aW9ucyB3ZXJlIGNhbGxlZC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGZ1bmN0aW9uPn0gZnNcbiAqIEBwYXJhbSB7QXJyYXk8YW55Pn0gYXJnc1xuICovXG5leHBvcnQgY29uc3QgY2FsbEFsbCA9IChmcywgYXJncywgaSA9IDApID0+IHtcbiAgdHJ5IHtcbiAgICBmb3IgKDsgaSA8IGZzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBmc1tpXSguLi5hcmdzKVxuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAoaSA8IGZzLmxlbmd0aCkge1xuICAgICAgY2FsbEFsbChmcywgYXJncywgaSArIDEpXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBub3AgPSAoKSA9PiB7fVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCk6VH0gZlxuICogQHJldHVybiB7VH1cbiAqL1xuZXhwb3J0IGNvbnN0IGFwcGx5ID0gZiA9PiBmKClcblxuLyoqXG4gKiBAdGVtcGxhdGUgQVxuICpcbiAqIEBwYXJhbSB7QX0gYVxuICogQHJldHVybiB7QX1cbiAqL1xuZXhwb3J0IGNvbnN0IGlkID0gYSA9PiBhXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqXG4gKiBAcGFyYW0ge1R9IGFcbiAqIEBwYXJhbSB7VH0gYlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGNvbnN0IGVxdWFsaXR5U3RyaWN0ID0gKGEsIGIpID0+IGEgPT09IGJcblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICpcbiAqIEBwYXJhbSB7QXJyYXk8VD58b2JqZWN0fSBhXG4gKiBAcGFyYW0ge0FycmF5PFQ+fG9iamVjdH0gYlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGNvbnN0IGVxdWFsaXR5RmxhdCA9IChhLCBiKSA9PiBhID09PSBiIHx8IChhICE9IG51bGwgJiYgYiAhPSBudWxsICYmIGEuY29uc3RydWN0b3IgPT09IGIuY29uc3RydWN0b3IgJiYgKChhcnJheS5pc0FycmF5KGEpICYmIGFycmF5LmVxdWFsRmxhdChhLCAvKiogQHR5cGUge0FycmF5PFQ+fSAqLyAoYikpKSB8fCAodHlwZW9mIGEgPT09ICdvYmplY3QnICYmIG9iamVjdC5lcXVhbEZsYXQoYSwgYikpKSlcblxuLyogYzggaWdub3JlIHN0YXJ0ICovXG5cbi8qKlxuICogQHBhcmFtIHthbnl9IGFcbiAqIEBwYXJhbSB7YW55fSBiXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgY29uc3QgZXF1YWxpdHlEZWVwID0gKGEsIGIpID0+IHtcbiAgaWYgKGEgPT09IGIpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG4gIGlmIChhID09IG51bGwgfHwgYiA9PSBudWxsIHx8IChhLmNvbnN0cnVjdG9yICE9PSBiLmNvbnN0cnVjdG9yICYmIChhLmNvbnN0cnVjdG9yIHx8IE9iamVjdCkgIT09IChiLmNvbnN0cnVjdG9yIHx8IE9iamVjdCkpKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgaWYgKGFbZXF1YWxpdHlUcmFpdC5FcXVhbGl0eVRyYWl0U3ltYm9sXSAhPSBudWxsKSB7XG4gICAgcmV0dXJuIGFbZXF1YWxpdHlUcmFpdC5FcXVhbGl0eVRyYWl0U3ltYm9sXShiKVxuICB9XG4gIHN3aXRjaCAoYS5jb25zdHJ1Y3Rvcikge1xuICAgIGNhc2UgQXJyYXlCdWZmZXI6XG4gICAgICBhID0gbmV3IFVpbnQ4QXJyYXkoYSlcbiAgICAgIGIgPSBuZXcgVWludDhBcnJheShiKVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuICAgIGNhc2UgVWludDhBcnJheToge1xuICAgICAgaWYgKGEuYnl0ZUxlbmd0aCAhPT0gYi5ieXRlTGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChhW2ldICE9PSBiW2ldKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrXG4gICAgfVxuICAgIGNhc2UgU2V0OiB7XG4gICAgICBpZiAoYS5zaXplICE9PSBiLnNpemUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIGEpIHtcbiAgICAgICAgaWYgKCFiLmhhcyh2YWx1ZSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYnJlYWtcbiAgICB9XG4gICAgY2FzZSBNYXA6IHtcbiAgICAgIGlmIChhLnNpemUgIT09IGIuc2l6ZSkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIGEua2V5cygpKSB7XG4gICAgICAgIGlmICghYi5oYXMoa2V5KSB8fCAhZXF1YWxpdHlEZWVwKGEuZ2V0KGtleSksIGIuZ2V0KGtleSkpKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrXG4gICAgfVxuICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgIGNhc2UgT2JqZWN0OlxuICAgICAgaWYgKG9iamVjdC5zaXplKGEpICE9PSBvYmplY3Quc2l6ZShiKSkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3Qga2V5IGluIGEpIHtcbiAgICAgICAgaWYgKCFvYmplY3QuaGFzUHJvcGVydHkoYSwga2V5KSB8fCAhZXF1YWxpdHlEZWVwKGFba2V5XSwgYltrZXldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVha1xuICAgIGNhc2UgQXJyYXk6XG4gICAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICghZXF1YWxpdHlEZWVwKGFbaV0sIGJbaV0pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogQHRlbXBsYXRlIFZcbiAqIEB0ZW1wbGF0ZSB7Vn0gT1BUU1xuICpcbiAqIEBwYXJhbSB7Vn0gdmFsdWVcbiAqIEBwYXJhbSB7QXJyYXk8T1BUUz59IG9wdGlvbnNcbiAqL1xuLy8gQHRzLWlnbm9yZVxuZXhwb3J0IGNvbnN0IGlzT25lT2YgPSAodmFsdWUsIG9wdGlvbnMpID0+IG9wdGlvbnMuaW5jbHVkZXModmFsdWUpXG4vKiBjOCBpZ25vcmUgc3RvcCAqL1xuXG5leHBvcnQgY29uc3QgaXNBcnJheSA9IGFycmF5LmlzQXJyYXlcblxuLyoqXG4gKiBAcGFyYW0ge2FueX0gc1xuICogQHJldHVybiB7cyBpcyBTdHJpbmd9XG4gKi9cbmV4cG9ydCBjb25zdCBpc1N0cmluZyA9IChzKSA9PiBzICYmIHMuY29uc3RydWN0b3IgPT09IFN0cmluZ1xuXG4vKipcbiAqIEBwYXJhbSB7YW55fSBuXG4gKiBAcmV0dXJuIHtuIGlzIE51bWJlcn1cbiAqL1xuZXhwb3J0IGNvbnN0IGlzTnVtYmVyID0gbiA9PiBuICE9IG51bGwgJiYgbi5jb25zdHJ1Y3RvciA9PT0gTnVtYmVyXG5cbi8qKlxuICogQHRlbXBsYXRlIHthYnN0cmFjdCBuZXcgKC4uLmFyZ3M6IGFueSkgPT4gYW55fSBUWVBFXG4gKiBAcGFyYW0ge2FueX0gblxuICogQHBhcmFtIHtUWVBFfSBUXG4gKiBAcmV0dXJuIHtuIGlzIEluc3RhbmNlVHlwZTxUWVBFPn1cbiAqL1xuZXhwb3J0IGNvbnN0IGlzID0gKG4sIFQpID0+IG4gJiYgbi5jb25zdHJ1Y3RvciA9PT0gVFxuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7YWJzdHJhY3QgbmV3ICguLi5hcmdzOiBhbnkpID0+IGFueX0gVFlQRVxuICogQHBhcmFtIHtUWVBFfSBUXG4gKi9cbmV4cG9ydCBjb25zdCBpc1RlbXBsYXRlID0gKFQpID0+XG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gblxuICAgKiBAcmV0dXJuIHtuIGlzIEluc3RhbmNlVHlwZTxUWVBFPn1cbiAgICoqL1xuICBuID0+IG4gJiYgbi5jb25zdHJ1Y3RvciA9PT0gVFxuIiwgIi8qKlxuICogSXNvbW9ycGhpYyBtb2R1bGUgdG8gd29yayBhY2Nlc3MgdGhlIGVudmlyb25tZW50IChxdWVyeSBwYXJhbXMsIGVudiB2YXJpYWJsZXMpLlxuICpcbiAqIEBtb2R1bGUgZW52aXJvbm1lbnRcbiAqL1xuXG5pbXBvcnQgKiBhcyBtYXAgZnJvbSAnLi9tYXAuanMnXG5pbXBvcnQgKiBhcyBzdHJpbmcgZnJvbSAnLi9zdHJpbmcuanMnXG5pbXBvcnQgKiBhcyBjb25kaXRpb25zIGZyb20gJy4vY29uZGl0aW9ucy5qcydcbmltcG9ydCAqIGFzIHN0b3JhZ2UgZnJvbSAnLi9zdG9yYWdlLmpzJ1xuaW1wb3J0ICogYXMgZiBmcm9tICcuL2Z1bmN0aW9uLmpzJ1xuXG4vKiBjOCBpZ25vcmUgbmV4dCAyICovXG4vLyBAdHMtaWdub3JlXG5leHBvcnQgY29uc3QgaXNOb2RlID0gdHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHByb2Nlc3MucmVsZWFzZSAmJiAvbm9kZXxpb1xcLmpzLy50ZXN0KHByb2Nlc3MucmVsZWFzZS5uYW1lKSAmJiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnID8gcHJvY2VzcyA6IDApID09PSAnW29iamVjdCBwcm9jZXNzXSdcblxuLyogYzggaWdub3JlIG5leHQgKi9cbmV4cG9ydCBjb25zdCBpc0Jyb3dzZXIgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmICFpc05vZGVcbi8qIGM4IGlnbm9yZSBuZXh0IDMgKi9cbmV4cG9ydCBjb25zdCBpc01hYyA9IHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnXG4gID8gL01hYy8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pXG4gIDogZmFsc2VcblxuLyoqXG4gKiBAdHlwZSB7TWFwPHN0cmluZyxzdHJpbmc+fVxuICovXG5sZXQgcGFyYW1zXG5jb25zdCBhcmdzID0gW11cblxuLyogYzggaWdub3JlIHN0YXJ0ICovXG5jb25zdCBjb21wdXRlUGFyYW1zID0gKCkgPT4ge1xuICBpZiAocGFyYW1zID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoaXNOb2RlKSB7XG4gICAgICBwYXJhbXMgPSBtYXAuY3JlYXRlKClcbiAgICAgIGNvbnN0IHBhcmdzID0gcHJvY2Vzcy5hcmd2XG4gICAgICBsZXQgY3VyclBhcmFtTmFtZSA9IG51bGxcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcGFyZyA9IHBhcmdzW2ldXG4gICAgICAgIGlmIChwYXJnWzBdID09PSAnLScpIHtcbiAgICAgICAgICBpZiAoY3VyclBhcmFtTmFtZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcGFyYW1zLnNldChjdXJyUGFyYW1OYW1lLCAnJylcbiAgICAgICAgICB9XG4gICAgICAgICAgY3VyclBhcmFtTmFtZSA9IHBhcmdcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoY3VyclBhcmFtTmFtZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcGFyYW1zLnNldChjdXJyUGFyYW1OYW1lLCBwYXJnKVxuICAgICAgICAgICAgY3VyclBhcmFtTmFtZSA9IG51bGxcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXJncy5wdXNoKHBhcmcpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoY3VyclBhcmFtTmFtZSAhPT0gbnVsbCkge1xuICAgICAgICBwYXJhbXMuc2V0KGN1cnJQYXJhbU5hbWUsICcnKVxuICAgICAgfVxuICAgICAgLy8gaW4gUmVhY3ROYXRpdmUgZm9yIGV4YW1wbGUgdGhpcyB3b3VsZCBub3QgYmUgdHJ1ZSAodW5sZXNzIGNvbm5lY3RlZCB0byB0aGUgUmVtb3RlIERlYnVnZ2VyKVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGxvY2F0aW9uID09PSAnb2JqZWN0Jykge1xuICAgICAgcGFyYW1zID0gbWFwLmNyZWF0ZSgpOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW5kZWZcbiAgICAgIChsb2NhdGlvbi5zZWFyY2ggfHwgJz8nKS5zbGljZSgxKS5zcGxpdCgnJicpLmZvckVhY2goKGt2KSA9PiB7XG4gICAgICAgIGlmIChrdi5sZW5ndGggIT09IDApIHtcbiAgICAgICAgICBjb25zdCBba2V5LCB2YWx1ZV0gPSBrdi5zcGxpdCgnPScpXG4gICAgICAgICAgcGFyYW1zLnNldChgLS0ke3N0cmluZy5mcm9tQ2FtZWxDYXNlKGtleSwgJy0nKX1gLCB2YWx1ZSlcbiAgICAgICAgICBwYXJhbXMuc2V0KGAtJHtzdHJpbmcuZnJvbUNhbWVsQ2FzZShrZXksICctJyl9YCwgdmFsdWUpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcmFtcyA9IG1hcC5jcmVhdGUoKVxuICAgIH1cbiAgfVxuICByZXR1cm4gcGFyYW1zXG59XG4vKiBjOCBpZ25vcmUgc3RvcCAqL1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG4vKiBjOCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0IGNvbnN0IGhhc1BhcmFtID0gKG5hbWUpID0+IGNvbXB1dGVQYXJhbXMoKS5oYXMobmFtZSlcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtzdHJpbmd9IGRlZmF1bHRWYWxcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuLyogYzggaWdub3JlIG5leHQgMiAqL1xuZXhwb3J0IGNvbnN0IGdldFBhcmFtID0gKG5hbWUsIGRlZmF1bHRWYWwpID0+XG4gIGNvbXB1dGVQYXJhbXMoKS5nZXQobmFtZSkgfHwgZGVmYXVsdFZhbFxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtzdHJpbmd8bnVsbH1cbiAqL1xuLyogYzggaWdub3JlIG5leHQgNCAqL1xuZXhwb3J0IGNvbnN0IGdldFZhcmlhYmxlID0gKG5hbWUpID0+XG4gIGlzTm9kZVxuICAgID8gY29uZGl0aW9ucy51bmRlZmluZWRUb051bGwocHJvY2Vzcy5lbnZbbmFtZS50b1VwcGVyQ2FzZSgpLnJlcGxhY2VBbGwoJy0nLCAnXycpXSlcbiAgICA6IGNvbmRpdGlvbnMudW5kZWZpbmVkVG9OdWxsKHN0b3JhZ2UudmFyU3RvcmFnZS5nZXRJdGVtKG5hbWUpKVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtzdHJpbmd8bnVsbH1cbiAqL1xuLyogYzggaWdub3JlIG5leHQgMiAqL1xuZXhwb3J0IGNvbnN0IGdldENvbmYgPSAobmFtZSkgPT5cbiAgY29tcHV0ZVBhcmFtcygpLmdldCgnLS0nICsgbmFtZSkgfHwgZ2V0VmFyaWFibGUobmFtZSlcblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG4vKiBjOCBpZ25vcmUgbmV4dCA1ICovXG5leHBvcnQgY29uc3QgZW5zdXJlQ29uZiA9IChuYW1lKSA9PiB7XG4gIGNvbnN0IGMgPSBnZXRDb25mKG5hbWUpXG4gIGlmIChjID09IG51bGwpIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgY29uZmlndXJhdGlvbiBcIiR7bmFtZS50b1VwcGVyQ2FzZSgpLnJlcGxhY2VBbGwoJy0nLCAnXycpfVwiYClcbiAgcmV0dXJuIGNcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuLyogYzggaWdub3JlIG5leHQgMiAqL1xuZXhwb3J0IGNvbnN0IGhhc0NvbmYgPSAobmFtZSkgPT5cbiAgaGFzUGFyYW0oJy0tJyArIG5hbWUpIHx8IGdldFZhcmlhYmxlKG5hbWUpICE9PSBudWxsXG5cbi8qIGM4IGlnbm9yZSBuZXh0ICovXG5leHBvcnQgY29uc3QgcHJvZHVjdGlvbiA9IGhhc0NvbmYoJ3Byb2R1Y3Rpb24nKVxuXG4vKiBjOCBpZ25vcmUgbmV4dCAyICovXG5jb25zdCBmb3JjZUNvbG9yID0gaXNOb2RlICYmXG4gIGYuaXNPbmVPZihwcm9jZXNzLmVudi5GT1JDRV9DT0xPUiwgWyd0cnVlJywgJzEnLCAnMiddKVxuXG4vKiBjOCBpZ25vcmUgc3RhcnQgKi9cbi8qKlxuICogQ29sb3IgaXMgZW5hYmxlZCBieSBkZWZhdWx0IGlmIHRoZSB0ZXJtaW5hbCBzdXBwb3J0cyBpdC5cbiAqXG4gKiBFeHBsaWNpdGx5IGVuYWJsZSBjb2xvciB1c2luZyBgLS1jb2xvcmAgcGFyYW1ldGVyXG4gKiBEaXNhYmxlIGNvbG9yIHVzaW5nIGAtLW5vLWNvbG9yYCBwYXJhbWV0ZXIgb3IgdXNpbmcgYE5PX0NPTE9SPTFgIGVudmlyb25tZW50IHZhcmlhYmxlLlxuICogYEZPUkNFX0NPTE9SPTFgIGVuYWJsZXMgY29sb3IgYW5kIHRha2VzIHByZWNlZGVuY2Ugb3ZlciBhbGwuXG4gKi9cbmV4cG9ydCBjb25zdCBzdXBwb3J0c0NvbG9yID0gZm9yY2VDb2xvciB8fCAoXG4gICFoYXNQYXJhbSgnLS1uby1jb2xvcnMnKSAmJiAvLyBAdG9kbyBkZXByZWNhdGUgLS1uby1jb2xvcnNcbiAgIWhhc0NvbmYoJ25vLWNvbG9yJykgJiZcbiAgKCFpc05vZGUgfHwgcHJvY2Vzcy5zdGRvdXQuaXNUVFkpICYmIChcbiAgICAhaXNOb2RlIHx8XG4gICAgaGFzUGFyYW0oJy0tY29sb3InKSB8fFxuICAgIGdldFZhcmlhYmxlKCdDT0xPUlRFUk0nKSAhPT0gbnVsbCB8fFxuICAgIChnZXRWYXJpYWJsZSgnVEVSTScpIHx8ICcnKS5pbmNsdWRlcygnY29sb3InKVxuICApXG4pXG4vKiBjOCBpZ25vcmUgc3RvcCAqL1xuIiwgIi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbnMgdG8gd29yayB3aXRoIGJ1ZmZlcnMgKFVpbnQ4QXJyYXkpLlxuICpcbiAqIEBtb2R1bGUgYnVmZmVyXG4gKi9cblxuaW1wb3J0ICogYXMgc3RyaW5nIGZyb20gJy4vc3RyaW5nLmpzJ1xuaW1wb3J0ICogYXMgZW52IGZyb20gJy4vZW52aXJvbm1lbnQuanMnXG5pbXBvcnQgKiBhcyBhcnJheSBmcm9tICcuL2FycmF5LmpzJ1xuaW1wb3J0ICogYXMgbWF0aCBmcm9tICcuL21hdGguanMnXG5pbXBvcnQgKiBhcyBlbmNvZGluZyBmcm9tICcuL2VuY29kaW5nLmpzJ1xuaW1wb3J0ICogYXMgZGVjb2RpbmcgZnJvbSAnLi9kZWNvZGluZy5qcydcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVVaW50OEFycmF5RnJvbUxlbiA9IGxlbiA9PiBuZXcgVWludDhBcnJheShsZW4pXG5cbi8qKlxuICogQ3JlYXRlIFVpbnQ4QXJyYXkgd2l0aCBpbml0aWFsIGNvbnRlbnQgZnJvbSBidWZmZXJcbiAqXG4gKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZmZXJcbiAqIEBwYXJhbSB7bnVtYmVyfSBieXRlT2Zmc2V0XG4gKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVVaW50OEFycmF5Vmlld0Zyb21BcnJheUJ1ZmZlciA9IChidWZmZXIsIGJ5dGVPZmZzZXQsIGxlbmd0aCkgPT4gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyLCBieXRlT2Zmc2V0LCBsZW5ndGgpXG5cbi8qKlxuICogQ3JlYXRlIFVpbnQ4QXJyYXkgd2l0aCBpbml0aWFsIGNvbnRlbnQgZnJvbSBidWZmZXJcbiAqXG4gKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZmZXJcbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVVpbnQ4QXJyYXlGcm9tQXJyYXlCdWZmZXIgPSBidWZmZXIgPT4gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyKVxuXG4vKiBjOCBpZ25vcmUgc3RhcnQgKi9cbi8qKlxuICogQHBhcmFtIHtVaW50OEFycmF5fSBieXRlc1xuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5jb25zdCB0b0Jhc2U2NEJyb3dzZXIgPSBieXRlcyA9PiB7XG4gIGxldCBzID0gJydcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBieXRlcy5ieXRlTGVuZ3RoOyBpKyspIHtcbiAgICBzICs9IHN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pXG4gIH1cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gIHJldHVybiBidG9hKHMpXG59XG4vKiBjOCBpZ25vcmUgc3RvcCAqL1xuXG4vKipcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnl0ZXNcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuY29uc3QgdG9CYXNlNjROb2RlID0gYnl0ZXMgPT4gQnVmZmVyLmZyb20oYnl0ZXMuYnVmZmVyLCBieXRlcy5ieXRlT2Zmc2V0LCBieXRlcy5ieXRlTGVuZ3RoKS50b1N0cmluZygnYmFzZTY0JylcblxuLyogYzggaWdub3JlIHN0YXJ0ICovXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5PEFycmF5QnVmZmVyPn1cbiAqL1xuY29uc3QgZnJvbUJhc2U2NEJyb3dzZXIgPSBzID0+IHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVmXG4gIGNvbnN0IGEgPSBhdG9iKHMpXG4gIGNvbnN0IGJ5dGVzID0gY3JlYXRlVWludDhBcnJheUZyb21MZW4oYS5sZW5ndGgpXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgIGJ5dGVzW2ldID0gYS5jaGFyQ29kZUF0KGkpXG4gIH1cbiAgcmV0dXJuIGJ5dGVzXG59XG4vKiBjOCBpZ25vcmUgc3RvcCAqL1xuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBzXG4gKi9cbmNvbnN0IGZyb21CYXNlNjROb2RlID0gcyA9PiB7XG4gIGNvbnN0IGJ1ZiA9IEJ1ZmZlci5mcm9tKHMsICdiYXNlNjQnKVxuICByZXR1cm4gY3JlYXRlVWludDhBcnJheVZpZXdGcm9tQXJyYXlCdWZmZXIoYnVmLmJ1ZmZlciwgYnVmLmJ5dGVPZmZzZXQsIGJ1Zi5ieXRlTGVuZ3RoKVxufVxuXG4vKiBjOCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0IGNvbnN0IHRvQmFzZTY0ID0gZW52LmlzQnJvd3NlciA/IHRvQmFzZTY0QnJvd3NlciA6IHRvQmFzZTY0Tm9kZVxuXG4vKiBjOCBpZ25vcmUgbmV4dCAqL1xuZXhwb3J0IGNvbnN0IGZyb21CYXNlNjQgPSBlbnYuaXNCcm93c2VyID8gZnJvbUJhc2U2NEJyb3dzZXIgOiBmcm9tQmFzZTY0Tm9kZVxuXG4vKipcbiAqIEltcGxlbWVudHMgYmFzZTY0dXJsIC0gc2VlIGh0dHBzOi8vZGF0YXRyYWNrZXIuaWV0Zi5vcmcvZG9jL2h0bWwvcmZjNDY0OCNzZWN0aW9uLTVcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmXG4gKi9cbmV4cG9ydCBjb25zdCB0b0Jhc2U2NFVybEVuY29kZWQgPSBidWYgPT4gdG9CYXNlNjQoYnVmKS5yZXBsYWNlQWxsKCcrJywgJy0nKS5yZXBsYWNlQWxsKCcvJywgJ18nKS5yZXBsYWNlQWxsKCc9JywgJycpXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2U2NFxuICovXG5leHBvcnQgY29uc3QgZnJvbUJhc2U2NFVybEVuY29kZWQgPSBiYXNlNjQgPT4gZnJvbUJhc2U2NChiYXNlNjQucmVwbGFjZUFsbCgnLScsICcrJykucmVwbGFjZUFsbCgnXycsICcvJykpXG5cbi8qKlxuICogQmFzZTY0IGlzIGFsd2F5cyBhIG1vcmUgZWZmaWNpZW50IGNob2ljZS4gVGhpcyBleGlzdHMgZm9yIHV0aWxpdHkgcHVycG9zZXMgb25seS5cbiAqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZlxuICovXG5leHBvcnQgY29uc3QgdG9IZXhTdHJpbmcgPSBidWYgPT4gYXJyYXkubWFwKGJ1ZiwgYiA9PiBiLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCAnMCcpKS5qb2luKCcnKVxuXG4vKipcbiAqIE5vdGU6IFRoaXMgZnVuY3Rpb24gZXhwZWN0cyB0aGF0IHRoZSBoZXggZG9lc24ndCBzdGFydCB3aXRoIDB4Li5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gaGV4XG4gKi9cbmV4cG9ydCBjb25zdCBmcm9tSGV4U3RyaW5nID0gaGV4ID0+IHtcbiAgY29uc3QgaGxlbiA9IGhleC5sZW5ndGhcbiAgY29uc3QgYnVmID0gbmV3IFVpbnQ4QXJyYXkobWF0aC5jZWlsKGhsZW4gLyAyKSlcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBobGVuOyBpICs9IDIpIHtcbiAgICBidWZbYnVmLmxlbmd0aCAtIGkgLyAyIC0gMV0gPSBOdW1iZXIucGFyc2VJbnQoaGV4LnNsaWNlKGhsZW4gLSBpIC0gMiwgaGxlbiAtIGkpLCAxNilcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbi8qKlxuICogQ29weSB0aGUgY29udGVudCBvZiBhbiBVaW50OEFycmF5IHZpZXcgdG8gYSBuZXcgQXJyYXlCdWZmZXIuXG4gKlxuICogQHBhcmFtIHtVaW50OEFycmF5fSB1aW50OEFycmF5XG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICovXG5leHBvcnQgY29uc3QgY29weVVpbnQ4QXJyYXkgPSB1aW50OEFycmF5ID0+IHtcbiAgY29uc3QgbmV3QnVmID0gY3JlYXRlVWludDhBcnJheUZyb21MZW4odWludDhBcnJheS5ieXRlTGVuZ3RoKVxuICBuZXdCdWYuc2V0KHVpbnQ4QXJyYXkpXG4gIHJldHVybiBuZXdCdWZcbn1cblxuLyoqXG4gKiBFbmNvZGUgYW55dGhpbmcgYXMgYSBVSW50OEFycmF5LiBJdCdzIGEgcHVuIG9uIHR5cGVzY3JpcHRzJ3MgYGFueWAgdHlwZS5cbiAqIFNlZSBlbmNvZGluZy53cml0ZUFueSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAqXG4gKiBAcGFyYW0ge2FueX0gZGF0YVxuICogQHJldHVybiB7VWludDhBcnJheX1cbiAqL1xuZXhwb3J0IGNvbnN0IGVuY29kZUFueSA9IGRhdGEgPT5cbiAgZW5jb2RpbmcuZW5jb2RlKGVuY29kZXIgPT4gZW5jb2Rpbmcud3JpdGVBbnkoZW5jb2RlciwgZGF0YSkpXG5cbi8qKlxuICogRGVjb2RlIGFuIGFueS1lbmNvZGVkIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmXG4gKiBAcmV0dXJuIHthbnl9XG4gKi9cbmV4cG9ydCBjb25zdCBkZWNvZGVBbnkgPSBidWYgPT4gZGVjb2RpbmcucmVhZEFueShkZWNvZGluZy5jcmVhdGVEZWNvZGVyKGJ1ZikpXG5cbi8qKlxuICogU2hpZnQgQnl0ZSBBcnJheSB7Tn0gYml0cyB0byB0aGUgbGVmdC4gRG9lcyBub3QgZXhwYW5kIGJ5dGUgYXJyYXkuXG4gKlxuICogQHBhcmFtIHtVaW50OEFycmF5fSBic1xuICogQHBhcmFtIHtudW1iZXJ9IE4gc2hvdWxkIGJlIGluIHRoZSByYW5nZSBvZiBbMC03XVxuICovXG5leHBvcnQgY29uc3Qgc2hpZnROQml0c0xlZnQgPSAoYnMsIE4pID0+IHtcbiAgaWYgKE4gPT09IDApIHJldHVybiBic1xuICBicyA9IG5ldyBVaW50OEFycmF5KGJzKVxuICBic1swXSA8PD0gTlxuICBmb3IgKGxldCBpID0gMTsgaSA8IGJzLmxlbmd0aDsgaSsrKSB7XG4gICAgYnNbaSAtIDFdIHw9IGJzW2ldID4+PiAoOCAtIE4pXG4gICAgYnNbaV0gPDw9IE5cbiAgfVxuICByZXR1cm4gYnNcbn1cbiIsICIvKipcbiAqIFdvcmtpbmcgd2l0aCB2YWx1ZSBwYWlycy5cbiAqXG4gKiBAbW9kdWxlIHBhaXJcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBMLFJcbiAqL1xuZXhwb3J0IGNsYXNzIFBhaXIge1xuICAvKipcbiAgICogQHBhcmFtIHtMfSBsZWZ0XG4gICAqIEBwYXJhbSB7Un0gcmlnaHRcbiAgICovXG4gIGNvbnN0cnVjdG9yIChsZWZ0LCByaWdodCkge1xuICAgIHRoaXMubGVmdCA9IGxlZnRcbiAgICB0aGlzLnJpZ2h0ID0gcmlnaHRcbiAgfVxufVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBMLFJcbiAqIEBwYXJhbSB7TH0gbGVmdFxuICogQHBhcmFtIHtSfSByaWdodFxuICogQHJldHVybiB7UGFpcjxMLFI+fVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlID0gKGxlZnQsIHJpZ2h0KSA9PiBuZXcgUGFpcihsZWZ0LCByaWdodClcblxuLyoqXG4gKiBAdGVtcGxhdGUgTCxSXG4gKiBAcGFyYW0ge1J9IHJpZ2h0XG4gKiBAcGFyYW0ge0x9IGxlZnRcbiAqIEByZXR1cm4ge1BhaXI8TCxSPn1cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZVJldmVyc2VkID0gKHJpZ2h0LCBsZWZ0KSA9PiBuZXcgUGFpcihsZWZ0LCByaWdodClcblxuLyoqXG4gKiBAdGVtcGxhdGUgTCxSXG4gKiBAcGFyYW0ge0FycmF5PFBhaXI8TCxSPj59IGFyclxuICogQHBhcmFtIHtmdW5jdGlvbihMLCBSKTphbnl9IGZcbiAqL1xuZXhwb3J0IGNvbnN0IGZvckVhY2ggPSAoYXJyLCBmKSA9PiBhcnIuZm9yRWFjaChwID0+IGYocC5sZWZ0LCBwLnJpZ2h0KSlcblxuLyoqXG4gKiBAdGVtcGxhdGUgTCxSLFhcbiAqIEBwYXJhbSB7QXJyYXk8UGFpcjxMLFI+Pn0gYXJyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKEwsIFIpOlh9IGZcbiAqIEByZXR1cm4ge0FycmF5PFg+fVxuICovXG5leHBvcnQgY29uc3QgbWFwID0gKGFyciwgZikgPT4gYXJyLm1hcChwID0+IGYocC5sZWZ0LCBwLnJpZ2h0KSlcbiIsICIvKipcbiAqIEZhc3QgUHNldWRvIFJhbmRvbSBOdW1iZXIgR2VuZXJhdG9ycy5cbiAqXG4gKiBHaXZlbiBhIHNlZWQgYSBQUk5HIGdlbmVyYXRlcyBhIHNlcXVlbmNlIG9mIG51bWJlcnMgdGhhdCBjYW5ub3QgYmUgcmVhc29uYWJseSBwcmVkaWN0ZWQuXG4gKiBUd28gUFJOR3MgbXVzdCBnZW5lcmF0ZSB0aGUgc2FtZSByYW5kb20gc2VxdWVuY2Ugb2YgbnVtYmVycyBpZiAgZ2l2ZW4gdGhlIHNhbWUgc2VlZC5cbiAqXG4gKiBAbW9kdWxlIHBybmdcbiAqL1xuXG5pbXBvcnQgKiBhcyBiaW5hcnkgZnJvbSAnLi9iaW5hcnkuanMnXG5pbXBvcnQgeyBmcm9tQ2hhckNvZGUsIGZyb21Db2RlUG9pbnQgfSBmcm9tICcuL3N0cmluZy5qcydcbmltcG9ydCAqIGFzIG1hdGggZnJvbSAnLi9tYXRoLmpzJ1xuaW1wb3J0IHsgWG9yb3NoaXJvMTI4cGx1cyB9IGZyb20gJy4vcHJuZy9Yb3Jvc2hpcm8xMjhwbHVzLmpzJ1xuaW1wb3J0ICogYXMgYnVmZmVyIGZyb20gJy4vYnVmZmVyLmpzJ1xuXG4vKipcbiAqIERlc2NyaXB0aW9uIG9mIHRoZSBmdW5jdGlvblxuICogIEBjYWxsYmFjayBnZW5lcmF0b3JOZXh0XG4gKiAgQHJldHVybiB7bnVtYmVyfSBBIHJhbmRvbSBmbG9hdCBpbiB0aGUgY2FuZ2Ugb2YgWzAsMSlcbiAqL1xuXG4vKipcbiAqIEEgcmFuZG9tIHR5cGUgZ2VuZXJhdG9yLlxuICpcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFBSTkdcbiAqIEBwcm9wZXJ0eSB7Z2VuZXJhdG9yTmV4dH0gbmV4dCBHZW5lcmF0ZSBuZXcgbnVtYmVyXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0UFJORyA9IFhvcm9zaGlybzEyOHBsdXNcblxuLyoqXG4gKiBDcmVhdGUgYSBYb3Jvc2hpcm8xMjhwbHVzIFBzZXVkby1SYW5kb20tTnVtYmVyLUdlbmVyYXRvci5cbiAqIFRoaXMgaXMgdGhlIGZhc3Rlc3QgZnVsbC1wZXJpb2QgZ2VuZXJhdG9yIHBhc3NpbmcgQmlnQ3J1c2ggd2l0aG91dCBzeXN0ZW1hdGljIGZhaWx1cmVzLlxuICogQnV0IHRoZXJlIGFyZSBtb3JlIFBSTkdzIGF2YWlsYWJsZSBpbiAuL1BSTkcvLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBzZWVkIEEgcG9zaXRpdmUgMzJiaXQgaW50ZWdlci4gRG8gbm90IHVzZSBuZWdhdGl2ZSBudW1iZXJzLlxuICogQHJldHVybiB7UFJOR31cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZSA9IHNlZWQgPT4gbmV3IERlZmF1bHRQUk5HKHNlZWQpXG5cbi8qKlxuICogR2VuZXJhdGVzIGEgc2luZ2xlIHJhbmRvbSBib29sLlxuICpcbiAqIEBwYXJhbSB7UFJOR30gZ2VuIEEgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IuXG4gKiBAcmV0dXJuIHtCb29sZWFufSBBIHJhbmRvbSBib29sZWFuXG4gKi9cbmV4cG9ydCBjb25zdCBib29sID0gZ2VuID0+IChnZW4ubmV4dCgpID49IDAuNSlcblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSByYW5kb20gaW50ZWdlciB3aXRoIDUzIGJpdCByZXNvbHV0aW9uLlxuICpcbiAqIEBwYXJhbSB7UFJOR30gZ2VuIEEgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IuXG4gKiBAcGFyYW0ge051bWJlcn0gbWluIFRoZSBsb3dlciBib3VuZCBvZiB0aGUgYWxsb3dlZCByZXR1cm4gdmFsdWVzIChpbmNsdXNpdmUpLlxuICogQHBhcmFtIHtOdW1iZXJ9IG1heCBUaGUgdXBwZXIgYm91bmQgb2YgdGhlIGFsbG93ZWQgcmV0dXJuIHZhbHVlcyAoaW5jbHVzaXZlKS5cbiAqIEByZXR1cm4ge051bWJlcn0gQSByYW5kb20gaW50ZWdlciBvbiBbbWluLCBtYXhdXG4gKi9cbmV4cG9ydCBjb25zdCBpbnQ1MyA9IChnZW4sIG1pbiwgbWF4KSA9PiBtYXRoLmZsb29yKGdlbi5uZXh0KCkgKiAobWF4ICsgMSAtIG1pbikgKyBtaW4pXG5cbi8qKlxuICogR2VuZXJhdGVzIGEgcmFuZG9tIGludGVnZXIgd2l0aCA1MyBiaXQgcmVzb2x1dGlvbi5cbiAqXG4gKiBAcGFyYW0ge1BSTkd9IGdlbiBBIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yLlxuICogQHBhcmFtIHtOdW1iZXJ9IG1pbiBUaGUgbG93ZXIgYm91bmQgb2YgdGhlIGFsbG93ZWQgcmV0dXJuIHZhbHVlcyAoaW5jbHVzaXZlKS5cbiAqIEBwYXJhbSB7TnVtYmVyfSBtYXggVGhlIHVwcGVyIGJvdW5kIG9mIHRoZSBhbGxvd2VkIHJldHVybiB2YWx1ZXMgKGluY2x1c2l2ZSkuXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IEEgcmFuZG9tIGludGVnZXIgb24gW21pbiwgbWF4XVxuICovXG5leHBvcnQgY29uc3QgdWludDUzID0gKGdlbiwgbWluLCBtYXgpID0+IG1hdGguYWJzKGludDUzKGdlbiwgbWluLCBtYXgpKVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIHJhbmRvbSBpbnRlZ2VyIHdpdGggMzIgYml0IHJlc29sdXRpb24uXG4gKlxuICogQHBhcmFtIHtQUk5HfSBnZW4gQSByYW5kb20gbnVtYmVyIGdlbmVyYXRvci5cbiAqIEBwYXJhbSB7TnVtYmVyfSBtaW4gVGhlIGxvd2VyIGJvdW5kIG9mIHRoZSBhbGxvd2VkIHJldHVybiB2YWx1ZXMgKGluY2x1c2l2ZSkuXG4gKiBAcGFyYW0ge051bWJlcn0gbWF4IFRoZSB1cHBlciBib3VuZCBvZiB0aGUgYWxsb3dlZCByZXR1cm4gdmFsdWVzIChpbmNsdXNpdmUpLlxuICogQHJldHVybiB7TnVtYmVyfSBBIHJhbmRvbSBpbnRlZ2VyIG9uIFttaW4sIG1heF1cbiAqL1xuZXhwb3J0IGNvbnN0IGludDMyID0gKGdlbiwgbWluLCBtYXgpID0+IG1hdGguZmxvb3IoZ2VuLm5leHQoKSAqIChtYXggKyAxIC0gbWluKSArIG1pbilcblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSByYW5kb20gaW50ZWdlciB3aXRoIDUzIGJpdCByZXNvbHV0aW9uLlxuICpcbiAqIEBwYXJhbSB7UFJOR30gZ2VuIEEgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IuXG4gKiBAcGFyYW0ge051bWJlcn0gbWluIFRoZSBsb3dlciBib3VuZCBvZiB0aGUgYWxsb3dlZCByZXR1cm4gdmFsdWVzIChpbmNsdXNpdmUpLlxuICogQHBhcmFtIHtOdW1iZXJ9IG1heCBUaGUgdXBwZXIgYm91bmQgb2YgdGhlIGFsbG93ZWQgcmV0dXJuIHZhbHVlcyAoaW5jbHVzaXZlKS5cbiAqIEByZXR1cm4ge051bWJlcn0gQSByYW5kb20gaW50ZWdlciBvbiBbbWluLCBtYXhdXG4gKi9cbmV4cG9ydCBjb25zdCB1aW50MzIgPSAoZ2VuLCBtaW4sIG1heCkgPT4gaW50MzIoZ2VuLCBtaW4sIG1heCkgPj4+IDBcblxuLyoqXG4gKiBAZGVwcmVjYXRlZFxuICogT3B0aW1pemVkIHZlcnNpb24gb2YgcHJuZy5pbnQzMi4gSXQgaGFzIHRoZSBzYW1lIHByZWNpc2lvbiBhcyBwcm5nLmludDMyLCBidXQgc2hvdWxkIGJlIHByZWZlcnJlZCB3aGVuXG4gKiBvcGVuYXJpbmcgb24gc21hbGxlciByYW5nZXMuXG4gKlxuICogQHBhcmFtIHtQUk5HfSBnZW4gQSByYW5kb20gbnVtYmVyIGdlbmVyYXRvci5cbiAqIEBwYXJhbSB7TnVtYmVyfSBtaW4gVGhlIGxvd2VyIGJvdW5kIG9mIHRoZSBhbGxvd2VkIHJldHVybiB2YWx1ZXMgKGluY2x1c2l2ZSkuXG4gKiBAcGFyYW0ge051bWJlcn0gbWF4IFRoZSB1cHBlciBib3VuZCBvZiB0aGUgYWxsb3dlZCByZXR1cm4gdmFsdWVzIChpbmNsdXNpdmUpLiBUaGUgbWF4IGluY2x1c2l2ZSBudW1iZXIgaXMgYGJpbmFyeS5CSVRTMzEtMWBcbiAqIEByZXR1cm4ge051bWJlcn0gQSByYW5kb20gaW50ZWdlciBvbiBbbWluLCBtYXhdXG4gKi9cbmV4cG9ydCBjb25zdCBpbnQzMSA9IChnZW4sIG1pbiwgbWF4KSA9PiBpbnQzMihnZW4sIG1pbiwgbWF4KVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIHJhbmRvbSByZWFsIG9uIFswLCAxKSB3aXRoIDUzIGJpdCByZXNvbHV0aW9uLlxuICpcbiAqIEBwYXJhbSB7UFJOR30gZ2VuIEEgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IuXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IEEgcmFuZG9tIHJlYWwgbnVtYmVyIG9uIFswLCAxKS5cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWw1MyA9IGdlbiA9PiBnZW4ubmV4dCgpIC8vICgoKGdlbi5uZXh0KCkgPj4+IDUpICogYmluYXJ5LkJJVDI2KSArIChnZW4ubmV4dCgpID4+PiA2KSkgLyBNQVhfU0FGRV9JTlRFR0VSXG5cbi8qKlxuICogR2VuZXJhdGVzIGEgcmFuZG9tIGNoYXJhY3RlciBmcm9tIGNoYXIgY29kZSAzMiAtIDEyNi4gSS5lLiBDaGFyYWN0ZXJzLCBOdW1iZXJzLCBzcGVjaWFsIGNoYXJhY3RlcnMsIGFuZCBTcGFjZTpcbiAqXG4gKiBAcGFyYW0ge1BSTkd9IGdlbiBBIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yLlxuICogQHJldHVybiB7c3RyaW5nfVxuICpcbiAqIChTcGFjZSkhXCIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWlsvXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9flxuICovXG5leHBvcnQgY29uc3QgY2hhciA9IGdlbiA9PiBmcm9tQ2hhckNvZGUoaW50MzEoZ2VuLCAzMiwgMTI2KSlcblxuLyoqXG4gKiBAcGFyYW0ge1BSTkd9IGdlblxuICogQHJldHVybiB7c3RyaW5nfSBBIHNpbmdsZSBsZXR0ZXIgKGEteilcbiAqL1xuZXhwb3J0IGNvbnN0IGxldHRlciA9IGdlbiA9PiBmcm9tQ2hhckNvZGUoaW50MzEoZ2VuLCA5NywgMTIyKSlcblxuLyoqXG4gKiBAcGFyYW0ge1BSTkd9IGdlblxuICogQHBhcmFtIHtudW1iZXJ9IFttaW5MZW49MF1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbbWF4TGVuPTIwXVxuICogQHJldHVybiB7c3RyaW5nfSBBIHJhbmRvbSB3b3JkICgwLTIwIGNoYXJhY3RlcnMpIHdpdGhvdXQgc3BhY2VzIGNvbnNpc3Rpbmcgb2YgbGV0dGVycyAoYS16KVxuICovXG5leHBvcnQgY29uc3Qgd29yZCA9IChnZW4sIG1pbkxlbiA9IDAsIG1heExlbiA9IDIwKSA9PiB7XG4gIGNvbnN0IGxlbiA9IGludDMxKGdlbiwgbWluTGVuLCBtYXhMZW4pXG4gIGxldCBzdHIgPSAnJ1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgc3RyICs9IGxldHRlcihnZW4pXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG4vKipcbiAqIFRPRE86IHRoaXMgZnVuY3Rpb24gcHJvZHVjZXMgaW52YWxpZCBydW5lcy4gRG9lcyBub3QgY292ZXIgYWxsIG9mIHV0ZjE2ISFcbiAqXG4gKiBAcGFyYW0ge1BSTkd9IGdlblxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgdXRmMTZSdW5lID0gZ2VuID0+IHtcbiAgY29uc3QgY29kZXBvaW50ID0gaW50MzEoZ2VuLCAwLCAyNTYpXG4gIHJldHVybiBmcm9tQ29kZVBvaW50KGNvZGVwb2ludClcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1BSTkd9IGdlblxuICogQHBhcmFtIHtudW1iZXJ9IFttYXhsZW4gPSAyMF1cbiAqL1xuZXhwb3J0IGNvbnN0IHV0ZjE2U3RyaW5nID0gKGdlbiwgbWF4bGVuID0gMjApID0+IHtcbiAgY29uc3QgbGVuID0gaW50MzEoZ2VuLCAwLCBtYXhsZW4pXG4gIGxldCBzdHIgPSAnJ1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgc3RyICs9IHV0ZjE2UnVuZShnZW4pXG4gIH1cbiAgcmV0dXJuIHN0clxufVxuXG4vKipcbiAqIFJldHVybnMgb25lIGVsZW1lbnQgb2YgYSBnaXZlbiBhcnJheS5cbiAqXG4gKiBAcGFyYW0ge1BSTkd9IGdlbiBBIHJhbmRvbSBudW1iZXIgZ2VuZXJhdG9yLlxuICogQHBhcmFtIHtBcnJheTxUPn0gYXJyYXkgTm9uIGVtcHR5IEFycmF5IG9mIHBvc3NpYmxlIHZhbHVlcy5cbiAqIEByZXR1cm4ge1R9IE9uZSBvZiB0aGUgdmFsdWVzIG9mIHRoZSBzdXBwbGllZCBBcnJheS5cbiAqIEB0ZW1wbGF0ZSBUXG4gKi9cbmV4cG9ydCBjb25zdCBvbmVPZiA9IChnZW4sIGFycmF5KSA9PiBhcnJheVtpbnQzMShnZW4sIDAsIGFycmF5Lmxlbmd0aCAtIDEpXVxuXG4vKipcbiAqIEBwYXJhbSB7UFJOR30gZ2VuXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5PEFycmF5QnVmZmVyPn1cbiAqL1xuZXhwb3J0IGNvbnN0IHVpbnQ4QXJyYXkgPSAoZ2VuLCBsZW4pID0+IHtcbiAgY29uc3QgYnVmID0gYnVmZmVyLmNyZWF0ZVVpbnQ4QXJyYXlGcm9tTGVuKGxlbilcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWYubGVuZ3RoOyBpKyspIHtcbiAgICBidWZbaV0gPSBpbnQzMihnZW4sIDAsIGJpbmFyeS5CSVRTOClcbiAgfVxuICByZXR1cm4gYnVmXG59XG5cbi8qIGM4IGlnbm9yZSBzdGFydCAqL1xuLyoqXG4gKiBAcGFyYW0ge1BSTkd9IGdlblxuICogQHBhcmFtIHtudW1iZXJ9IGxlblxuICogQHJldHVybiB7VWludDE2QXJyYXl9XG4gKi9cbmV4cG9ydCBjb25zdCB1aW50MTZBcnJheSA9IChnZW4sIGxlbikgPT4gbmV3IFVpbnQxNkFycmF5KHVpbnQ4QXJyYXkoZ2VuLCBsZW4gKiAyKS5idWZmZXIpXG5cbi8qKlxuICogQHBhcmFtIHtQUk5HfSBnZW5cbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW5cbiAqIEByZXR1cm4ge1VpbnQzMkFycmF5fVxuICovXG5leHBvcnQgY29uc3QgdWludDMyQXJyYXkgPSAoZ2VuLCBsZW4pID0+IG5ldyBVaW50MzJBcnJheSh1aW50OEFycmF5KGdlbiwgbGVuICogNCkuYnVmZmVyKVxuLyogYzggaWdub3JlIHN0b3AgKi9cbiIsICIvKipcbiAqIEBleHBlcmltZW50YWwgV0lQXG4gKlxuICogU2ltcGxlICYgZWZmaWNpZW50IHNjaGVtYXMgZm9yIHlvdXIgZGF0YS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBvYmogZnJvbSAnLi9vYmplY3QuanMnXG5pbXBvcnQgKiBhcyBhcnIgZnJvbSAnLi9hcnJheS5qcydcbmltcG9ydCAqIGFzIGVycm9yIGZyb20gJy4vZXJyb3IuanMnXG5pbXBvcnQgKiBhcyBlbnYgZnJvbSAnLi9lbnZpcm9ubWVudC5qcydcbmltcG9ydCAqIGFzIGVxdWFsaXR5VHJhaXRzIGZyb20gJy4vdHJhaXQvZXF1YWxpdHkuanMnXG5pbXBvcnQgKiBhcyBmdW4gZnJvbSAnLi9mdW5jdGlvbi5qcydcbmltcG9ydCAqIGFzIHN0cmluZyBmcm9tICcuL3N0cmluZy5qcydcbmltcG9ydCAqIGFzIHBybmcgZnJvbSAnLi9wcm5nLmpzJ1xuaW1wb3J0ICogYXMgbnVtYmVyIGZyb20gJy4vbnVtYmVyLmpzJ1xuXG4vKipcbiAqIEB0eXBlZGVmIHtzdHJpbmd8bnVtYmVyfGJpZ2ludHxib29sZWFufG51bGx8dW5kZWZpbmVkfHN5bWJvbH0gUHJpbWl0aXZlXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7eyBbazpzdHJpbmd8bnVtYmVyfHN5bWJvbF06IGFueSB9fSBBbnlPYmplY3RcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZWRlZiB7VCBleHRlbmRzIFNjaGVtYTxpbmZlciBYPiA/IFggOiBUfSBVbndyYXBcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZWRlZiB7VCBleHRlbmRzIFNjaGVtYTxpbmZlciBYPiA/IFggOiBUfSBUeXBlT2ZcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7cmVhZG9ubHkgdW5rbm93bltdfSBUXG4gKiBAdHlwZWRlZiB7VCBleHRlbmRzIHJlYWRvbmx5IFtTY2hlbWE8aW5mZXIgRmlyc3Q+LCAuLi5pbmZlciBSZXN0XSA/IFtGaXJzdCwgLi4uVW53cmFwQXJyYXk8UmVzdD5dIDogW10gfSBVbndyYXBBcnJheVxuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEB0eXBlZGVmIHtUIGV4dGVuZHMgU2NoZW1hPGluZmVyIFM+ID8gU2NoZW1hPFM+IDogbmV2ZXJ9IENhc3RUb1NjaGVtYVxuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIHt1bmtub3duW119IEFyclxuICogQHR5cGVkZWYge0FyciBleHRlbmRzIFsuLi51bmtub3duW10sIGluZmVyIExdID8gTCA6IG5ldmVyfSBUdXBsZUxhc3RcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7dW5rbm93bltdfSBBcnJcbiAqIEB0eXBlZGVmIHtBcnIgZXh0ZW5kcyBbLi4uaW5mZXIgRnMsIHVua25vd25dID8gRnMgOiBuZXZlcn0gVHVwbGVQb3BcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7cmVhZG9ubHkgdW5rbm93bltdfSBUXG4gKiBAdHlwZWRlZiB7VCBleHRlbmRzIFtdXG4gKiAgID8ge31cbiAqICAgOiBUIGV4dGVuZHMgW2luZmVyIEZpcnN0XVxuICogICA/IEZpcnN0XG4gKiAgIDogVCBleHRlbmRzIFtpbmZlciBGaXJzdCwgLi4uaW5mZXIgUmVzdF1cbiAqICAgPyBGaXJzdCAmIEludGVyc2VjdDxSZXN0PlxuICogICA6IG5ldmVyXG4gKiB9IEludGVyc2VjdFxuICovXG5cbmNvbnN0IHNjaGVtYVN5bWJvbCA9IFN5bWJvbCgnMHNjaGVtYScpXG5cbmV4cG9ydCBjbGFzcyBWYWxpZGF0aW9uRXJyb3Ige1xuICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgLyoqXG4gICAgICogUmV2ZXJzZSBlcnJvcnNcbiAgICAgKiBAdHlwZSB7QXJyYXk8eyBwYXRoOiBzdHJpbmc/LCBleHBlY3RlZDogc3RyaW5nLCBoYXM6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nPyB9Pn1cbiAgICAgKi9cbiAgICB0aGlzLl9yZXJycyA9IFtdXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmc/fSBwYXRoXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBleHBlY3RlZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gaGFzXG4gICAqIEBwYXJhbSB7c3RyaW5nP30gbWVzc2FnZVxuICAgKi9cbiAgZXh0ZW5kIChwYXRoLCBleHBlY3RlZCwgaGFzLCBtZXNzYWdlID0gbnVsbCkge1xuICAgIHRoaXMuX3JlcnJzLnB1c2goeyBwYXRoLCBleHBlY3RlZCwgaGFzLCBtZXNzYWdlIH0pXG4gIH1cblxuICB0b1N0cmluZyAoKSB7XG4gICAgY29uc3QgcyA9IFtdXG4gICAgZm9yIChsZXQgaSA9IHRoaXMuX3JlcnJzLmxlbmd0aCAtIDE7IGkgPiAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IHIgPSB0aGlzLl9yZXJyc1tpXVxuICAgICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgIHMucHVzaChzdHJpbmcucmVwZWF0KCcgJywgKHRoaXMuX3JlcnJzLmxlbmd0aCAtIGkpICogMikgKyBgJHtyLnBhdGggIT0gbnVsbCA/IGBbJHtyLnBhdGh9XSBgIDogJyd9JHtyLmhhc30gZG9lc24ndCBtYXRjaCAke3IuZXhwZWN0ZWR9LiAke3IubWVzc2FnZX1gKVxuICAgIH1cbiAgICByZXR1cm4gcy5qb2luKCdcXG4nKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHthbnl9IGFcbiAqIEBwYXJhbSB7YW55fSBiXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5jb25zdCBzaGFwZUV4dGVuZHMgPSAoYSwgYikgPT4ge1xuICBpZiAoYSA9PT0gYikgcmV0dXJuIHRydWVcbiAgaWYgKGEgPT0gbnVsbCB8fCBiID09IG51bGwgfHwgYS5jb25zdHJ1Y3RvciAhPT0gYi5jb25zdHJ1Y3RvcikgcmV0dXJuIGZhbHNlXG4gIGlmIChhW2VxdWFsaXR5VHJhaXRzLkVxdWFsaXR5VHJhaXRTeW1ib2xdKSByZXR1cm4gZXF1YWxpdHlUcmFpdHMuZXF1YWxzKGEsIGIpIC8vIGxhc3QgcmVzb3J0OiBjaGVjayBlcXVhbGl0eSAoZG8gdGhpcyBiZWZvcmUgYXJyYXkgYW5kIG9iaiBjaGVjayB3aGljaCBkb24ndCBpbXBsZW1lbnQgdGhlIGVxdWFsaXR5IHRyYWl0KVxuICBpZiAoYXJyLmlzQXJyYXkoYSkpIHtcbiAgICByZXR1cm4gYXJyLmV2ZXJ5KGEsIGFpdGVtID0+XG4gICAgICBhcnIuc29tZShiLCBiaXRlbSA9PiBzaGFwZUV4dGVuZHMoYWl0ZW0sIGJpdGVtKSlcbiAgICApXG4gIH0gZWxzZSBpZiAob2JqLmlzT2JqZWN0KGEpKSB7XG4gICAgcmV0dXJuIG9iai5ldmVyeShhLCAoYWl0ZW0sIGFrZXkpID0+XG4gICAgICBzaGFwZUV4dGVuZHMoYWl0ZW0sIGJbYWtleV0pXG4gICAgKVxuICB9XG4gIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gIHJldHVybiBmYWxzZVxufVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAaW1wbGVtZW50cyB7ZXF1YWxpdHlUcmFpdHMuRXF1YWxpdHlUcmFpdH1cbiAqL1xuZXhwb3J0IGNsYXNzIFNjaGVtYSB7XG4gIC8vIHRoaXMuc2hhcGUgbXVzdCBub3QgYmUgZGVmaW5lZCBvbiBTY2hlbWEuIE90aGVyd2lzZSB0eXBlY2hlY2sgb24gbWV0YXR5cGVzIChlLmcuICQkb2JqZWN0KSB3b24ndCB3b3JrIGFzIGV4cGVjdGVkIGFueW1vcmVcbiAgLyoqXG4gICAqIElmIHRydWUsIHRoZSBtb3JlIHRoaW5ncyBhcmUgYWRkZWQgdG8gdGhlIHNoYXBlIHRoZSBtb3JlIG9iamVjdHMgdGhpcyBzY2hlbWEgd2lsbCBhY2NlcHQgKGUuZy5cbiAgICogdW5pb24pLiBCeSBkZWZhdWx0LCB0aGUgbW9yZSBvYmplY3RzIGFyZSBhZGRlZCwgdGhlIHRoZSBmZXdlciBvYmplY3RzIHRoaXMgc2NoZW1hIHdpbGwgYWNjZXB0LlxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBzdGF0aWMgX2RpbHV0ZXMgPSBmYWxzZVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1NjaGVtYTxhbnk+fSBvdGhlclxuICAgKi9cbiAgZXh0ZW5kcyAob3RoZXIpIHtcbiAgICBsZXQgW2EsIGJdID0gWy8qKiBAdHlwZSB7YW55fSAqLyh0aGlzKS5zaGFwZSwgLyoqIEB0eXBlIHthbnl9ICovIChvdGhlcikuc2hhcGVdXG4gICAgaWYgKC8qKiBAdHlwZSB7dHlwZW9mIFNjaGVtYTxhbnk+fSAqLyAodGhpcy5jb25zdHJ1Y3RvcikuX2RpbHV0ZXMpIFtiLCBhXSA9IFthLCBiXVxuICAgIHJldHVybiBzaGFwZUV4dGVuZHMoYSwgYilcbiAgfVxuXG4gIC8qKlxuICAgKiBPdmVyd3JpdGUgdGhpcyB3aGVuIG5lY2Vzc2FyeS4gQnkgZGVmYXVsdCwgd2Ugb25seSBjaGVjayB0aGUgYHNoYXBlYCBwcm9wZXJ0eSB3aGljaCBldmVyeSBzaGFwZVxuICAgKiBzaG91bGQgaGF2ZS5cbiAgICogQHBhcmFtIHtTY2hlbWE8YW55Pn0gb3RoZXJcbiAgICovXG4gIGVxdWFscyAob3RoZXIpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IgPT09IG90aGVyLmNvbnN0cnVjdG9yICYmIGZ1bi5lcXVhbGl0eURlZXAodGhpcy5zaGFwZSwgb3RoZXIuc2hhcGUpXG4gIH1cblxuICBbc2NoZW1hU3ltYm9sXSAoKSB7IHJldHVybiB0cnVlIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IG90aGVyXG4gICAqL1xuICBbZXF1YWxpdHlUcmFpdHMuRXF1YWxpdHlUcmFpdFN5bWJvbF0gKG90aGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuZXF1YWxzKC8qKiBAdHlwZSB7YW55fSAqLyAob3RoZXIpKVxuICB9XG5cbiAgLyoqXG4gICAqIFVzZSBgc2NoZW1hLnZhbGlkYXRlKG9iailgIHdpdGggYSB0eXBlZCBwYXJhbWV0ZXIgdGhhdCBpcyBhbHJlYWR5IG9mIHR5cGVkIHRvIGJlIGFuIGluc3RhbmNlIG9mXG4gICAqIFNjaGVtYS4gVmFsaWRhdGUgd2lsbCBjaGVjayB0aGUgc3RydWN0dXJlIG9mIHRoZSBwYXJhbWV0ZXIgYW5kIHJldHVybiB0cnVlIGlmZiB0aGUgaW5zdGFuY2VcbiAgICogcmVhbGx5IGlzIGFuIGluc3RhbmNlIG9mIFNjaGVtYS5cbiAgICpcbiAgICogQHBhcmFtIHtUfSBvXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICB2YWxpZGF0ZSAobykge1xuICAgIHJldHVybiB0aGlzLmNoZWNrKG8pXG4gIH1cblxuICAvKiBjOCBpZ25vcmUgc3RhcnQgKi9cbiAgLyoqXG4gICAqIFNpbWlsYXIgdG8gdmFsaWRhdGUsIGJ1dCB0aGlzIG1ldGhvZCBhY2NlcHRzIHVudHlwZWQgcGFyYW1ldGVycy5cbiAgICpcbiAgICogQHBhcmFtIHthbnl9IF9vXG4gICAqIEBwYXJhbSB7VmFsaWRhdGlvbkVycm9yfSBbX2Vycl1cbiAgICogQHJldHVybiB7X28gaXMgVH1cbiAgICovXG4gIGNoZWNrIChfbywgX2Vycikge1xuICAgIGVycm9yLm1ldGhvZFVuaW1wbGVtZW50ZWQoKVxuICB9XG4gIC8qIGM4IGlnbm9yZSBzdG9wICovXG5cbiAgLyoqXG4gICAqIEB0eXBlIHtTY2hlbWE8VD8+fVxuICAgKi9cbiAgZ2V0IG51bGxhYmxlICgpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgcmV0dXJuICR1bmlvbih0aGlzLCAkbnVsbClcbiAgfVxuXG4gIC8qKlxuICAgKiBAdHlwZSB7JE9wdGlvbmFsPFNjaGVtYTxUPj59XG4gICAqL1xuICBnZXQgb3B0aW9uYWwgKCkge1xuICAgIHJldHVybiBuZXcgJE9wdGlvbmFsKC8qKiBAdHlwZSB7U2NoZW1hPFQ+fSAqLyAodGhpcykpXG4gIH1cblxuICAvKipcbiAgICogQ2FzdCBhIHZhcmlhYmxlIHRvIGEgc3BlY2lmaWMgdHlwZS4gUmV0dXJucyB0aGUgY2FzdGVkIHZhbHVlLCBvciB0aHJvd3MgYW4gZXhjZXB0aW9uIG90aGVyd2lzZS5cbiAgICogVXNlIHRoaXMgaWYgeW91IGtub3cgdGhhdCB0aGUgdHlwZSBpcyBvZiBhIHNwZWNpZmljIHR5cGUgYW5kIHlvdSBqdXN0IHdhbnQgdG8gY29udmluY2UgdGhlIHR5cGVcbiAgICogc3lzdGVtLlxuICAgKlxuICAgKiAqKkRvIG5vdCByZWx5IG9uIHRoZXNlIGVycm9yIG1lc3NhZ2VzISoqXG4gICAqIFBlcmZvcm1zIGFuIGFzc2VydGlvbiBjaGVjayBvbmx5IGlmIG5vdCBpbiBhIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBPT1xuICAgKiBAcGFyYW0ge09PfSBvXG4gICAqIEByZXR1cm4ge0V4dHJhY3Q8T08sIFQ+IGV4dGVuZHMgbmV2ZXIgPyBUIDogKE9PIGV4dGVuZHMgQXJyYXk8bmV2ZXI+ID8gVCA6IEV4dHJhY3Q8T08sVD4pfVxuICAgKi9cbiAgY2FzdCAobykge1xuICAgIGFzc2VydChvLCB0aGlzKVxuICAgIHJldHVybiAvKiogQHR5cGUge2FueX0gKi8gKG8pXG4gIH1cblxuICAvKipcbiAgICogRVhQRUNUTyBQQVRST05VTSEhIFx1RDgzRVx1REU4NFxuICAgKiBUaGlzIGZ1bmN0aW9uIHByb3RlY3RzIGFnYWluc3QgdHlwZSBlcnJvcnMuIFRob3VnaCBpdCBtYXkgbm90IHdvcmsgaW4gdGhlIHJlYWwgd29ybGQuXG4gICAqXG4gICAqIFwiQWZ0ZXIgYWxsIHRoaXMgdGltZT9cIlxuICAgKiBcIkFsd2F5cy5cIiAtIFNuYXBlLCB0YWxraW5nIGFib3V0IHR5cGUgc2FmZXR5XG4gICAqXG4gICAqIEVuc3VyZXMgdGhhdCBhIHZhcmlhYmxlIGlzIGEgYSBzcGVjaWZpYyB0eXBlLiBSZXR1cm5zIHRoZSB2YWx1ZSwgb3IgdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0aGUgYXNzZXJ0aW9uIGNoZWNrIGZhaWxlZC5cbiAgICogVXNlIHRoaXMgaWYgeW91IGtub3cgdGhhdCB0aGUgdHlwZSBpcyBvZiBhIHNwZWNpZmljIHR5cGUgYW5kIHlvdSBqdXN0IHdhbnQgdG8gY29udmluY2UgdGhlIHR5cGVcbiAgICogc3lzdGVtLlxuICAgKlxuICAgKiBDYW4gYmUgdXNlZnVsIHdoZW4gZGVmaW5pbmcgbGFtYmRhczogYHMubGFtYmRhKHMuJG51bWJlciwgcy4kdm9pZCkuZXhwZWN0KChuKSA9PiBuICsgMSlgXG4gICAqXG4gICAqICoqRG8gbm90IHJlbHkgb24gdGhlc2UgZXJyb3IgbWVzc2FnZXMhKipcbiAgICogUGVyZm9ybXMgYW4gYXNzZXJ0aW9uIGNoZWNrIGlmIG5vdCBpbiBhIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7VH0gb1xuICAgKiBAcmV0dXJuIHtvIGV4dGVuZHMgVCA/IFQgOiBuZXZlcn1cbiAgICovXG4gIGV4cGVjdCAobykge1xuICAgIGFzc2VydChvLCB0aGlzKVxuICAgIHJldHVybiBvXG4gIH1cbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgeyhuZXcgKC4uLmFyZ3M6YW55W10pID0+IGFueSkgfCAoKC4uLmFyZ3M6YW55W10pID0+IGFueSl9IENvbnN0clxuICogQHR5cGVkZWYge0NvbnN0ciBleHRlbmRzICgoLi4uYXJnczphbnlbXSkgPT4gaW5mZXIgVCkgPyBUIDogKENvbnN0ciBleHRlbmRzIChuZXcgKC4uLmFyZ3M6YW55W10pID0+IGFueSkgPyBJbnN0YW5jZVR5cGU8Q29uc3RyPiA6IG5ldmVyKX0gSW5zdGFuY2VcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7KG5ldyAoLi4uYXJnczphbnlbXSkgPT4gYW55KSB8ICgoLi4uYXJnczphbnlbXSkgPT4gYW55KX0gQ1xuICogQGV4dGVuZHMge1NjaGVtYTxJbnN0YW5jZTxDPj59XG4gKi9cbmV4cG9ydCBjbGFzcyAkQ29uc3RydWN0ZWRCeSBleHRlbmRzIFNjaGVtYSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0N9IGNcbiAgICogQHBhcmFtIHsoKG86SW5zdGFuY2U8Qz4pPT5ib29sZWFuKXxudWxsfSBjaGVja1xuICAgKi9cbiAgY29uc3RydWN0b3IgKGMsIGNoZWNrKSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuc2hhcGUgPSBjXG4gICAgdGhpcy5fYyA9IGNoZWNrXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHthbnl9IG9cbiAgICogQHBhcmFtIHtWYWxpZGF0aW9uRXJyb3J9IFtlcnJdXG4gICAqIEByZXR1cm4ge28gaXMgQyBleHRlbmRzICgoLi4uYXJnczphbnlbXSkgPT4gaW5mZXIgVCkgPyBUIDogKEMgZXh0ZW5kcyAobmV3ICguLi5hcmdzOmFueVtdKSA9PiBhbnkpID8gSW5zdGFuY2VUeXBlPEM+IDogbmV2ZXIpfSBvXG4gICAqL1xuICBjaGVjayAobywgZXJyID0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgYyA9IG8/LmNvbnN0cnVjdG9yID09PSB0aGlzLnNoYXBlICYmICh0aGlzLl9jID09IG51bGwgfHwgdGhpcy5fYyhvKSlcbiAgICAvKiBjOCBpZ25vcmUgbmV4dCAqL1xuICAgICFjICYmIGVycj8uZXh0ZW5kKG51bGwsIHRoaXMuc2hhcGUubmFtZSwgbz8uY29uc3RydWN0b3IubmFtZSwgbz8uY29uc3RydWN0b3IgIT09IHRoaXMuc2hhcGUgPyAnQ29uc3RydWN0b3IgbWF0Y2ggZmFpbGVkJyA6ICdDaGVjayBmYWlsZWQnKVxuICAgIHJldHVybiBjXG4gIH1cbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgeyhuZXcgKC4uLmFyZ3M6YW55W10pID0+IGFueSkgfCAoKC4uLmFyZ3M6YW55W10pID0+IGFueSl9IENcbiAqIEBwYXJhbSB7Q30gY1xuICogQHBhcmFtIHsoKG86SW5zdGFuY2U8Qz4pID0+IGJvb2xlYW4pfG51bGx9IGNoZWNrXG4gKiBAcmV0dXJuIHtDYXN0VG9TY2hlbWE8JENvbnN0cnVjdGVkQnk8Qz4+fVxuICovXG5leHBvcnQgY29uc3QgJGNvbnN0cnVjdGVkQnkgPSAoYywgY2hlY2sgPSBudWxsKSA9PiBuZXcgJENvbnN0cnVjdGVkQnkoYywgY2hlY2spXG5leHBvcnQgY29uc3QgJCRjb25zdHJ1Y3RlZEJ5ID0gJGNvbnN0cnVjdGVkQnkoJENvbnN0cnVjdGVkQnkpXG5cbi8qKlxuICogQ2hlY2sgY3VzdG9tIHByb3BlcnRpZXMgb24gYW55IG9iamVjdC4gWW91IG1heSB3YW50IHRvIG92ZXJ3cml0ZSB0aGUgZ2VuZXJhdGVkIFNjaGVtYTxhbnk+LlxuICpcbiAqIEBleHRlbmRzIHtTY2hlbWE8YW55Pn1cbiAqL1xuZXhwb3J0IGNsYXNzICRDdXN0b20gZXh0ZW5kcyBTY2hlbWEge1xuICAvKipcbiAgICogQHBhcmFtIHsobzphbnkpID0+IGJvb2xlYW59IGNoZWNrXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoY2hlY2spIHtcbiAgICBzdXBlcigpXG4gICAgLyoqXG4gICAgICogQHR5cGUgeyhvOmFueSkgPT4gYm9vbGVhbn1cbiAgICAgKi9cbiAgICB0aGlzLnNoYXBlID0gY2hlY2tcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gb1xuICAgKiBAcGFyYW0ge1ZhbGlkYXRpb25FcnJvcn0gZXJyXG4gICAqIEByZXR1cm4ge28gaXMgYW55fVxuICAgKi9cbiAgY2hlY2sgKG8sIGVycikge1xuICAgIGNvbnN0IGMgPSB0aGlzLnNoYXBlKG8pXG4gICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAhYyAmJiBlcnI/LmV4dGVuZChudWxsLCAnY3VzdG9tIHByb3AnLCBvPy5jb25zdHJ1Y3Rvci5uYW1lLCAnZmFpbGVkIHRvIGNoZWNrIGN1c3RvbSBwcm9wJylcbiAgICByZXR1cm4gY1xuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHsobzphbnkpID0+IGJvb2xlYW59IGNoZWNrXG4gKiBAcmV0dXJuIHtTY2hlbWE8YW55Pn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRjdXN0b20gPSAoY2hlY2spID0+IG5ldyAkQ3VzdG9tKGNoZWNrKVxuZXhwb3J0IGNvbnN0ICQkY3VzdG9tID0gJGNvbnN0cnVjdGVkQnkoJEN1c3RvbSlcblxuLyoqXG4gKiBAdGVtcGxhdGUge1ByaW1pdGl2ZX0gVFxuICogQGV4dGVuZHMge1NjaGVtYTxUPn1cbiAqL1xuZXhwb3J0IGNsYXNzICRMaXRlcmFsIGV4dGVuZHMgU2NoZW1hIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8VD59IGxpdGVyYWxzXG4gICAqL1xuICBjb25zdHJ1Y3RvciAobGl0ZXJhbHMpIHtcbiAgICBzdXBlcigpXG4gICAgdGhpcy5zaGFwZSA9IGxpdGVyYWxzXG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHthbnl9IG9cbiAgICogQHBhcmFtIHtWYWxpZGF0aW9uRXJyb3J9IFtlcnJdXG4gICAqIEByZXR1cm4ge28gaXMgVH1cbiAgICovXG4gIGNoZWNrIChvLCBlcnIpIHtcbiAgICBjb25zdCBjID0gdGhpcy5zaGFwZS5zb21lKGEgPT4gYSA9PT0gbylcbiAgICAvKiBjOCBpZ25vcmUgbmV4dCAqL1xuICAgICFjICYmIGVycj8uZXh0ZW5kKG51bGwsIHRoaXMuc2hhcGUuam9pbignIHwgJyksIG8udG9TdHJpbmcoKSlcbiAgICByZXR1cm4gY1xuICB9XG59XG5cbi8qKlxuICogQHRlbXBsYXRlIHtQcmltaXRpdmVbXX0gVFxuICogQHBhcmFtIHtUfSBsaXRlcmFsc1xuICogQHJldHVybiB7Q2FzdFRvU2NoZW1hPCRMaXRlcmFsPFRbbnVtYmVyXT4+fVxuICovXG5leHBvcnQgY29uc3QgJGxpdGVyYWwgPSAoLi4ubGl0ZXJhbHMpID0+IG5ldyAkTGl0ZXJhbChsaXRlcmFscylcbmV4cG9ydCBjb25zdCAkJGxpdGVyYWwgPSAkY29uc3RydWN0ZWRCeSgkTGl0ZXJhbClcblxuLyoqXG4gKiBAdGVtcGxhdGUge0FycmF5PHN0cmluZ3xTY2hlbWE8c3RyaW5nfG51bWJlcj4+fSBUc1xuICogQHR5cGVkZWYge1RzIGV4dGVuZHMgW10gPyBgYCA6IChUcyBleHRlbmRzIFtpbmZlciBUXSA/IChVbndyYXA8VD4gZXh0ZW5kcyAoc3RyaW5nfG51bWJlcikgPyBVbndyYXA8VD4gOiBuZXZlcikgOiAoVHMgZXh0ZW5kcyBbaW5mZXIgVDEsIC4uLmluZmVyIFJlc3RdID8gYCR7VW53cmFwPFQxPiBleHRlbmRzIChzdHJpbmd8bnVtYmVyKSA/IFVud3JhcDxUMT4gOiBuZXZlcn0ke1Jlc3QgZXh0ZW5kcyBBcnJheTxzdHJpbmd8U2NoZW1hPHN0cmluZ3xudW1iZXI+PiA/IENhc3RTdHJpbmdUZW1wbGF0ZUFyZ3NUb1RlbXBsYXRlPFJlc3Q+IDogbmV2ZXJ9YCA6IG5ldmVyKSl9IENhc3RTdHJpbmdUZW1wbGF0ZUFyZ3NUb1RlbXBsYXRlXG4gKi9cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmNvbnN0IF9yZWdleEVzY2FwZSA9IC8qKiBAdHlwZSB7YW55fSAqLyAoUmVnRXhwKS5lc2NhcGUgfHwgLyoqIEB0eXBlIHsoc3RyOnN0cmluZykgPT4gc3RyaW5nfSAqLyAoc3RyID0+XG4gIHN0ci5yZXBsYWNlKC9bKCkufCYsJF5bXFxdXS9nLCBzID0+ICdcXFxcJyArIHMpXG4pXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd8U2NoZW1hPGFueT59IHNcbiAqIEByZXR1cm4ge3N0cmluZ1tdfVxuICovXG5jb25zdCBfc2NoZW1hU3RyaW5nVGVtcGxhdGVUb1JlZ2V4ID0gcyA9PiB7XG4gIGlmICgkc3RyaW5nLmNoZWNrKHMpKSB7XG4gICAgcmV0dXJuIFtfcmVnZXhFc2NhcGUocyldXG4gIH1cbiAgaWYgKCQkbGl0ZXJhbC5jaGVjayhzKSkge1xuICAgIHJldHVybiAvKiogQHR5cGUge0FycmF5PHN0cmluZ3xudW1iZXI+fSAqLyAocy5zaGFwZSkubWFwKHYgPT4gdiArICcnKVxuICB9XG4gIGlmICgkJG51bWJlci5jaGVjayhzKSkge1xuICAgIHJldHVybiBbJ1srLV0/XFxcXGQrLj9cXFxcZConXVxuICB9XG4gIGlmICgkJHN0cmluZy5jaGVjayhzKSkge1xuICAgIHJldHVybiBbJy4qJ11cbiAgfVxuICBpZiAoJCR1bmlvbi5jaGVjayhzKSkge1xuICAgIHJldHVybiBzLnNoYXBlLm1hcChfc2NoZW1hU3RyaW5nVGVtcGxhdGVUb1JlZ2V4KS5mbGF0KDEpXG4gIH1cbiAgLyogYzggaWdub3JlIG5leHQgMiAqL1xuICAvLyB1bmV4cGVjdGVkIHNjaGVtYSBzdHJ1Y3R1cmUgKG9ubHkgc3VwcG9ydHMgdW5pb25zIGFuZCBzdHJpbmcgaW4gbGl0ZXJhbCB0eXBlcylcbiAgZXJyb3IudW5leHBlY3RlZENhc2UoKVxufVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7QXJyYXk8c3RyaW5nfFNjaGVtYTxzdHJpbmd8bnVtYmVyPj59IFRcbiAqIEBleHRlbmRzIHtTY2hlbWE8Q2FzdFN0cmluZ1RlbXBsYXRlQXJnc1RvVGVtcGxhdGU8VD4+fVxuICovXG5leHBvcnQgY2xhc3MgJFN0cmluZ1RlbXBsYXRlIGV4dGVuZHMgU2NoZW1hIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7VH0gc2hhcGVcbiAgICovXG4gIGNvbnN0cnVjdG9yIChzaGFwZSkge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLnNoYXBlID0gc2hhcGVcbiAgICB0aGlzLl9yID0gbmV3IFJlZ0V4cCgnXicgKyBzaGFwZS5tYXAoX3NjaGVtYVN0cmluZ1RlbXBsYXRlVG9SZWdleCkubWFwKG9wdHMgPT4gYCgke29wdHMuam9pbignfCcpfSlgKS5qb2luKCcnKSArICckJylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gb1xuICAgKiBAcGFyYW0ge1ZhbGlkYXRpb25FcnJvcn0gW2Vycl1cbiAgICogQHJldHVybiB7byBpcyBDYXN0U3RyaW5nVGVtcGxhdGVBcmdzVG9UZW1wbGF0ZTxUPn1cbiAgICovXG4gIGNoZWNrIChvLCBlcnIpIHtcbiAgICBjb25zdCBjID0gdGhpcy5fci5leGVjKG8pICE9IG51bGxcbiAgICAvKiBjOCBpZ25vcmUgbmV4dCAqL1xuICAgICFjICYmIGVycj8uZXh0ZW5kKG51bGwsIHRoaXMuX3IudG9TdHJpbmcoKSwgby50b1N0cmluZygpLCAnU3RyaW5nIGRvZXNuXFwndCBtYXRjaCBzdHJpbmcgdGVtcGxhdGUuJylcbiAgICByZXR1cm4gY1xuICB9XG59XG5cbi8qKlxuICogQHRlbXBsYXRlIHtBcnJheTxzdHJpbmd8U2NoZW1hPHN0cmluZ3xudW1iZXI+Pn0gVFxuICogQHBhcmFtIHtUfSBsaXRlcmFsc1xuICogQHJldHVybiB7Q2FzdFRvU2NoZW1hPCRTdHJpbmdUZW1wbGF0ZTxUPj59XG4gKi9cbmV4cG9ydCBjb25zdCAkc3RyaW5nVGVtcGxhdGUgPSAoLi4ubGl0ZXJhbHMpID0+IG5ldyAkU3RyaW5nVGVtcGxhdGUobGl0ZXJhbHMpXG5leHBvcnQgY29uc3QgJCRzdHJpbmdUZW1wbGF0ZSA9ICRjb25zdHJ1Y3RlZEJ5KCRTdHJpbmdUZW1wbGF0ZSlcblxuY29uc3QgaXNPcHRpb25hbFN5bWJvbCA9IFN5bWJvbCgnb3B0aW9uYWwnKVxuLyoqXG4gKiBAdGVtcGxhdGUge1NjaGVtYTxhbnk+fSBTXG4gKiBAZXh0ZW5kcyBTY2hlbWE8VW53cmFwPFM+fHVuZGVmaW5lZD5cbiAqL1xuY2xhc3MgJE9wdGlvbmFsIGV4dGVuZHMgU2NoZW1hIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7U30gc2hhcGVcbiAgICovXG4gIGNvbnN0cnVjdG9yIChzaGFwZSkge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLnNoYXBlID0gc2hhcGVcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gb1xuICAgKiBAcGFyYW0ge1ZhbGlkYXRpb25FcnJvcn0gW2Vycl1cbiAgICogQHJldHVybiB7byBpcyAoVW53cmFwPFM+fHVuZGVmaW5lZCl9XG4gICAqL1xuICBjaGVjayAobywgZXJyKSB7XG4gICAgY29uc3QgYyA9IG8gPT09IHVuZGVmaW5lZCB8fCB0aGlzLnNoYXBlLmNoZWNrKG8pXG4gICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAhYyAmJiBlcnI/LmV4dGVuZChudWxsLCAndW5kZWZpbmVkIChvcHRpb25hbCknLCAnKCknKVxuICAgIHJldHVybiBjXG4gIH1cblxuICBnZXQgW2lzT3B0aW9uYWxTeW1ib2xdICgpIHsgcmV0dXJuIHRydWUgfVxufVxuZXhwb3J0IGNvbnN0ICQkb3B0aW9uYWwgPSAkY29uc3RydWN0ZWRCeSgkT3B0aW9uYWwpXG5cbi8qKlxuICogQGV4dGVuZHMgU2NoZW1hPG5ldmVyPlxuICovXG5jbGFzcyAkTmV2ZXIgZXh0ZW5kcyBTY2hlbWEge1xuICAvKipcbiAgICogQHBhcmFtIHthbnl9IF9vXG4gICAqIEBwYXJhbSB7VmFsaWRhdGlvbkVycm9yfSBbZXJyXVxuICAgKiBAcmV0dXJuIHtfbyBpcyBuZXZlcn1cbiAgICovXG4gIGNoZWNrIChfbywgZXJyKSB7XG4gICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICBlcnI/LmV4dGVuZChudWxsLCAnbmV2ZXInLCB0eXBlb2YgX28pXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cblxuLyoqXG4gKiBAdHlwZSB7U2NoZW1hPG5ldmVyPn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRuZXZlciA9IG5ldyAkTmV2ZXIoKVxuZXhwb3J0IGNvbnN0ICQkbmV2ZXIgPSAkY29uc3RydWN0ZWRCeSgkTmV2ZXIpXG5cbi8qKlxuICogQHRlbXBsYXRlIHt7IFtrZXk6IHN0cmluZ3xzeW1ib2x8bnVtYmVyXTogU2NoZW1hPGFueT4gfX0gU1xuICogQHR5cGVkZWYge3sgW0tleSBpbiBrZXlvZiBTIGFzIFNbS2V5XSBleHRlbmRzICRPcHRpb25hbDxTY2hlbWE8YW55Pj4gPyBLZXkgOiBuZXZlcl0/OiBTW0tleV0gZXh0ZW5kcyAkT3B0aW9uYWw8U2NoZW1hPGluZmVyIFR5cGU+PiA/IFR5cGUgOiBuZXZlciB9ICYgeyBbS2V5IGluIGtleW9mIFMgYXMgU1tLZXldIGV4dGVuZHMgJE9wdGlvbmFsPFNjaGVtYTxhbnk+PiA/IG5ldmVyIDogS2V5XTogU1tLZXldIGV4dGVuZHMgU2NoZW1hPGluZmVyIFR5cGU+ID8gVHlwZSA6IG5ldmVyIH19ICRPYmplY3RUb1R5cGVcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7e1trZXk6c3RyaW5nfHN5bWJvbHxudW1iZXJdOiBTY2hlbWE8YW55Pn19IFNcbiAqIEBleHRlbmRzIHtTY2hlbWE8JE9iamVjdFRvVHlwZTxTPj59XG4gKi9cbmV4cG9ydCBjbGFzcyAkT2JqZWN0IGV4dGVuZHMgU2NoZW1hIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7U30gc2hhcGVcbiAgICogQHBhcmFtIHtib29sZWFufSBwYXJ0aWFsXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoc2hhcGUsIHBhcnRpYWwgPSBmYWxzZSkge1xuICAgIHN1cGVyKClcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7U31cbiAgICAgKi9cbiAgICB0aGlzLnNoYXBlID0gc2hhcGVcbiAgICB0aGlzLl9pc1BhcnRpYWwgPSBwYXJ0aWFsXG4gIH1cblxuICBzdGF0aWMgX2RpbHV0ZXMgPSB0cnVlXG5cbiAgLyoqXG4gICAqIEB0eXBlIHtTY2hlbWE8UGFydGlhbDwkT2JqZWN0VG9UeXBlPFM+Pj59XG4gICAqL1xuICBnZXQgcGFydGlhbCAoKSB7XG4gICAgcmV0dXJuIG5ldyAkT2JqZWN0KHRoaXMuc2hhcGUsIHRydWUpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHthbnl9IG9cbiAgICogQHBhcmFtIHtWYWxpZGF0aW9uRXJyb3J9IGVyclxuICAgKiBAcmV0dXJuIHtvIGlzICRPYmplY3RUb1R5cGU8Uz59XG4gICAqL1xuICBjaGVjayAobywgZXJyKSB7XG4gICAgaWYgKG8gPT0gbnVsbCkge1xuICAgICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgIGVycj8uZXh0ZW5kKG51bGwsICdvYmplY3QnLCAnbnVsbCcpXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG4gICAgcmV0dXJuIG9iai5ldmVyeSh0aGlzLnNoYXBlLCAodnYsIHZrKSA9PiB7XG4gICAgICBjb25zdCBjID0gKHRoaXMuX2lzUGFydGlhbCAmJiAhb2JqLmhhc1Byb3BlcnR5KG8sIHZrKSkgfHwgdnYuY2hlY2sob1t2a10sIGVycilcbiAgICAgICFjICYmIGVycj8uZXh0ZW5kKHZrLnRvU3RyaW5nKCksIHZ2LnRvU3RyaW5nKCksIHR5cGVvZiBvW3ZrXSwgJ09iamVjdCBwcm9wZXJ0eSBkb2VzIG5vdCBtYXRjaCcpXG4gICAgICByZXR1cm4gY1xuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgU1xuICogQHR5cGVkZWYge1NjaGVtYTx7IFtLZXkgaW4ga2V5b2YgUyBhcyBTW0tleV0gZXh0ZW5kcyAkT3B0aW9uYWw8U2NoZW1hPGFueT4+ID8gS2V5IDogbmV2ZXJdPzogU1tLZXldIGV4dGVuZHMgJE9wdGlvbmFsPFNjaGVtYTxpbmZlciBUeXBlPj4gPyBUeXBlIDogbmV2ZXIgfSAmIHsgW0tleSBpbiBrZXlvZiBTIGFzIFNbS2V5XSBleHRlbmRzICRPcHRpb25hbDxTY2hlbWE8YW55Pj4gPyBuZXZlciA6IEtleV06IFNbS2V5XSBleHRlbmRzIFNjaGVtYTxpbmZlciBUeXBlPiA/IFR5cGUgOiBuZXZlciB9Pn0gX09iamVjdERlZlRvU2NoZW1hXG4gKi9cblxuLy8gSSB1c2VkIGFuIGV4cGxpY2l0IHR5cGUgYW5ub3RhdGlvbiBpbnN0ZWFkIG9mICRPYmplY3RUb1R5cGUsIHNvIHRoYXQgdGhlIHVzZXIgZG9lc24ndCBzZWUgdGhlXG4vLyB3ZWlyZCB0eXBlIGRlZmluaXRpb25zIHdoZW4gaW5zcGVjdGluZyB0eXBlIGRlZmluaW9ucy5cbi8qKlxuICogQHRlbXBsYXRlIHt7IFtrZXk6c3RyaW5nfHN5bWJvbHxudW1iZXJdOiBTY2hlbWE8YW55PiB9fSBTXG4gKiBAcGFyYW0ge1N9IGRlZlxuICogQHJldHVybiB7X09iamVjdERlZlRvU2NoZW1hPFM+IGV4dGVuZHMgU2NoZW1hPGluZmVyIFM+ID8gU2NoZW1hPHsgW0sgaW4ga2V5b2YgU106IFNbS10gfT4gOiBuZXZlcn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRvYmplY3QgPSBkZWYgPT4gLyoqIEB0eXBlIHthbnl9ICovIChuZXcgJE9iamVjdChkZWYpKVxuZXhwb3J0IGNvbnN0ICQkb2JqZWN0ID0gJGNvbnN0cnVjdGVkQnkoJE9iamVjdClcbi8qKlxuICogQHR5cGUge1NjaGVtYTx7W2tleTpzdHJpbmddOiBhbnl9Pn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRvYmplY3RBbnkgPSAkY3VzdG9tKG8gPT4gbyAhPSBudWxsICYmIChvLmNvbnN0cnVjdG9yID09PSBPYmplY3QgfHwgby5jb25zdHJ1Y3RvciA9PSBudWxsKSlcblxuLyoqXG4gKiBAdGVtcGxhdGUge1NjaGVtYTxzdHJpbmd8bnVtYmVyfHN5bWJvbD59IEtleXNcbiAqIEB0ZW1wbGF0ZSB7U2NoZW1hPGFueT59IFZhbHVlc1xuICogQGV4dGVuZHMge1NjaGVtYTx7IFtrZXkgaW4gVW53cmFwPEtleXM+XTogVW53cmFwPFZhbHVlcz4gfT59XG4gKi9cbmV4cG9ydCBjbGFzcyAkUmVjb3JkIGV4dGVuZHMgU2NoZW1hIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7S2V5c30ga2V5c1xuICAgKiBAcGFyYW0ge1ZhbHVlc30gdmFsdWVzXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoa2V5cywgdmFsdWVzKSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuc2hhcGUgPSB7XG4gICAgICBrZXlzLCB2YWx1ZXNcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHthbnl9IG9cbiAgICogQHBhcmFtIHtWYWxpZGF0aW9uRXJyb3J9IGVyclxuICAgKiBAcmV0dXJuIHtvIGlzIHsgW2tleSBpbiBVbndyYXA8S2V5cz5dOiBVbndyYXA8VmFsdWVzPiB9fVxuICAgKi9cbiAgY2hlY2sgKG8sIGVycikge1xuICAgIHJldHVybiBvICE9IG51bGwgJiYgb2JqLmV2ZXJ5KG8sICh2diwgdmspID0+IHtcbiAgICAgIGNvbnN0IGNrID0gdGhpcy5zaGFwZS5rZXlzLmNoZWNrKHZrLCBlcnIpXG4gICAgICAvKiBjOCBpZ25vcmUgbmV4dCAqL1xuICAgICAgIWNrICYmIGVycj8uZXh0ZW5kKHZrICsgJycsICdSZWNvcmQnLCB0eXBlb2YgbywgY2sgPyAnS2V5IGRvZXNuXFwndCBtYXRjaCBzY2hlbWEnIDogJ1ZhbHVlIGRvZXNuXFwndCBtYXRjaCB2YWx1ZScpXG4gICAgICByZXR1cm4gY2sgJiYgdGhpcy5zaGFwZS52YWx1ZXMuY2hlY2sodnYsIGVycilcbiAgICB9KVxuICB9XG59XG5cbi8qKlxuICogQHRlbXBsYXRlIHtTY2hlbWE8c3RyaW5nfG51bWJlcnxzeW1ib2w+fSBLZXlzXG4gKiBAdGVtcGxhdGUge1NjaGVtYTxhbnk+fSBWYWx1ZXNcbiAqIEBwYXJhbSB7S2V5c30ga2V5c1xuICogQHBhcmFtIHtWYWx1ZXN9IHZhbHVlc1xuICogQHJldHVybiB7Q2FzdFRvU2NoZW1hPCRSZWNvcmQ8S2V5cyxWYWx1ZXM+Pn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRyZWNvcmQgPSAoa2V5cywgdmFsdWVzKSA9PiBuZXcgJFJlY29yZChrZXlzLCB2YWx1ZXMpXG5leHBvcnQgY29uc3QgJCRyZWNvcmQgPSAkY29uc3RydWN0ZWRCeSgkUmVjb3JkKVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7U2NoZW1hPGFueT5bXX0gU1xuICogQGV4dGVuZHMge1NjaGVtYTx7IFtLZXkgaW4ga2V5b2YgU106IFNbS2V5XSBleHRlbmRzIFNjaGVtYTxpbmZlciBUeXBlPiA/IFR5cGUgOiBuZXZlciB9Pn1cbiAqL1xuZXhwb3J0IGNsYXNzICRUdXBsZSBleHRlbmRzIFNjaGVtYSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1N9IHNoYXBlXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoc2hhcGUpIHtcbiAgICBzdXBlcigpXG4gICAgdGhpcy5zaGFwZSA9IHNoYXBlXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHthbnl9IG9cbiAgICogQHBhcmFtIHtWYWxpZGF0aW9uRXJyb3J9IGVyclxuICAgKiBAcmV0dXJuIHtvIGlzIHsgW0sgaW4ga2V5b2YgU106IFNbS10gZXh0ZW5kcyBTY2hlbWE8aW5mZXIgVHlwZT4gPyBUeXBlIDogbmV2ZXIgfX1cbiAgICovXG4gIGNoZWNrIChvLCBlcnIpIHtcbiAgICByZXR1cm4gbyAhPSBudWxsICYmIG9iai5ldmVyeSh0aGlzLnNoYXBlLCAodnYsIHZrKSA9PiB7XG4gICAgICBjb25zdCBjID0gLyoqIEB0eXBlIHtTY2hlbWE8YW55Pn0gKi8gKHZ2KS5jaGVjayhvW3ZrXSwgZXJyKVxuICAgICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAgICFjICYmIGVycj8uZXh0ZW5kKHZrLnRvU3RyaW5nKCksICdUdXBsZScsIHR5cGVvZiB2dilcbiAgICAgIHJldHVybiBjXG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7QXJyYXk8U2NoZW1hPGFueT4+fSBUXG4gKiBAcGFyYW0ge1R9IGRlZlxuICogQHJldHVybiB7Q2FzdFRvU2NoZW1hPCRUdXBsZTxUPj59XG4gKi9cbmV4cG9ydCBjb25zdCAkdHVwbGUgPSAoLi4uZGVmKSA9PiBuZXcgJFR1cGxlKGRlZilcbmV4cG9ydCBjb25zdCAkJHR1cGxlID0gJGNvbnN0cnVjdGVkQnkoJFR1cGxlKVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7U2NoZW1hPGFueT59IFNcbiAqIEBleHRlbmRzIHtTY2hlbWE8QXJyYXk8UyBleHRlbmRzIFNjaGVtYTxpbmZlciBUPiA/IFQgOiBuZXZlcj4+fVxuICovXG5leHBvcnQgY2xhc3MgJEFycmF5IGV4dGVuZHMgU2NoZW1hIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8Uz59IHZcbiAgICovXG4gIGNvbnN0cnVjdG9yICh2KSB7XG4gICAgc3VwZXIoKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtTY2hlbWE8UyBleHRlbmRzIFNjaGVtYTxpbmZlciBUPiA/IFQgOiBuZXZlcj59XG4gICAgICovXG4gICAgdGhpcy5zaGFwZSA9IHYubGVuZ3RoID09PSAxID8gdlswXSA6IG5ldyAkVW5pb24odilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gb1xuICAgKiBAcGFyYW0ge1ZhbGlkYXRpb25FcnJvcn0gW2Vycl1cbiAgICogQHJldHVybiB7byBpcyBBcnJheTxTIGV4dGVuZHMgU2NoZW1hPGluZmVyIFQ+ID8gVCA6IG5ldmVyPn0gb1xuICAgKi9cbiAgY2hlY2sgKG8sIGVycikge1xuICAgIGNvbnN0IGMgPSBhcnIuaXNBcnJheShvKSAmJiBhcnIuZXZlcnkobywgb2kgPT4gdGhpcy5zaGFwZS5jaGVjayhvaSkpXG4gICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAhYyAmJiBlcnI/LmV4dGVuZChudWxsLCAnQXJyYXknLCAnJylcbiAgICByZXR1cm4gY1xuICB9XG59XG5cbi8qKlxuICogQHRlbXBsYXRlIHtBcnJheTxTY2hlbWE8YW55Pj59IFRcbiAqIEBwYXJhbSB7VH0gZGVmXG4gKiBAcmV0dXJuIHtTY2hlbWE8QXJyYXk8VCBleHRlbmRzIEFycmF5PFNjaGVtYTxpbmZlciBTPj4gPyBTIDogbmV2ZXI+Pn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRhcnJheSA9ICguLi5kZWYpID0+IG5ldyAkQXJyYXkoZGVmKVxuZXhwb3J0IGNvbnN0ICQkYXJyYXkgPSAkY29uc3RydWN0ZWRCeSgkQXJyYXkpXG4vKipcbiAqIEB0eXBlIHtTY2hlbWE8QXJyYXk8YW55Pj59XG4gKi9cbmV4cG9ydCBjb25zdCAkYXJyYXlBbnkgPSAkY3VzdG9tKG8gPT4gYXJyLmlzQXJyYXkobykpXG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEBleHRlbmRzIHtTY2hlbWE8VD59XG4gKi9cbmV4cG9ydCBjbGFzcyAkSW5zdGFuY2VPZiBleHRlbmRzIFNjaGVtYSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge25ldyAoLi4uYXJnczphbnkpID0+IFR9IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7KChvOlQpID0+IGJvb2xlYW4pfG51bGx9IGNoZWNrXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoY29uc3RydWN0b3IsIGNoZWNrKSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuc2hhcGUgPSBjb25zdHJ1Y3RvclxuICAgIHRoaXMuX2MgPSBjaGVja1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7YW55fSBvXG4gICAqIEBwYXJhbSB7VmFsaWRhdGlvbkVycm9yfSBlcnJcbiAgICogQHJldHVybiB7byBpcyBUfVxuICAgKi9cbiAgY2hlY2sgKG8sIGVycikge1xuICAgIGNvbnN0IGMgPSBvIGluc3RhbmNlb2YgdGhpcy5zaGFwZSAmJiAodGhpcy5fYyA9PSBudWxsIHx8IHRoaXMuX2MobykpXG4gICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAhYyAmJiBlcnI/LmV4dGVuZChudWxsLCB0aGlzLnNoYXBlLm5hbWUsIG8/LmNvbnN0cnVjdG9yLm5hbWUpXG4gICAgcmV0dXJuIGNcbiAgfVxufVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge25ldyAoLi4uYXJnczphbnkpID0+IFR9IGNcbiAqIEBwYXJhbSB7KChvOlQpID0+IGJvb2xlYW4pfG51bGx9IGNoZWNrXG4gKiBAcmV0dXJuIHtTY2hlbWE8VD59XG4gKi9cbmV4cG9ydCBjb25zdCAkaW5zdGFuY2VPZiA9IChjLCBjaGVjayA9IG51bGwpID0+IG5ldyAkSW5zdGFuY2VPZihjLCBjaGVjaylcbmV4cG9ydCBjb25zdCAkJGluc3RhbmNlT2YgPSAkY29uc3RydWN0ZWRCeSgkSW5zdGFuY2VPZilcblxuZXhwb3J0IGNvbnN0ICQkc2NoZW1hID0gJGluc3RhbmNlT2YoU2NoZW1hKVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7U2NoZW1hPGFueT5bXX0gQXJnc1xuICogQHR5cGVkZWYgeyguLi5hcmdzOlVud3JhcEFycmF5PFR1cGxlUG9wPEFyZ3M+Pik9PlVud3JhcDxUdXBsZUxhc3Q8QXJncz4+fSBfTEFyZ3NUb0xhbWJkYURlZlxuICovXG5cbi8qKlxuICogQHRlbXBsYXRlIHtBcnJheTxTY2hlbWE8YW55Pj59IEFyZ3NcbiAqIEBleHRlbmRzIHtTY2hlbWE8X0xBcmdzVG9MYW1iZGFEZWY8QXJncz4+fVxuICovXG5leHBvcnQgY2xhc3MgJExhbWJkYSBleHRlbmRzIFNjaGVtYSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FyZ3N9IGFyZ3NcbiAgICovXG4gIGNvbnN0cnVjdG9yIChhcmdzKSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMubGVuID0gYXJncy5sZW5ndGggLSAxXG4gICAgdGhpcy5hcmdzID0gJHR1cGxlKC4uLmFyZ3Muc2xpY2UoLTEpKVxuICAgIHRoaXMucmVzID0gYXJnc1t0aGlzLmxlbl1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gZlxuICAgKiBAcGFyYW0ge1ZhbGlkYXRpb25FcnJvcn0gZXJyXG4gICAqIEByZXR1cm4ge2YgaXMgX0xBcmdzVG9MYW1iZGFEZWY8QXJncz59XG4gICAqL1xuICBjaGVjayAoZiwgZXJyKSB7XG4gICAgY29uc3QgYyA9IGYuY29uc3RydWN0b3IgPT09IEZ1bmN0aW9uICYmIGYubGVuZ3RoIDw9IHRoaXMubGVuXG4gICAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgICAhYyAmJiBlcnI/LmV4dGVuZChudWxsLCAnZnVuY3Rpb24nLCB0eXBlb2YgZilcbiAgICByZXR1cm4gY1xuICB9XG59XG5cbi8qKlxuICogQHRlbXBsYXRlIHtTY2hlbWE8YW55PltdfSBBcmdzXG4gKiBAcGFyYW0ge0FyZ3N9IGFyZ3NcbiAqIEByZXR1cm4ge1NjaGVtYTwoLi4uYXJnczpVbndyYXBBcnJheTxUdXBsZVBvcDxBcmdzPj4pPT5VbndyYXA8VHVwbGVMYXN0PEFyZ3M+Pj59XG4gKi9cbmV4cG9ydCBjb25zdCAkbGFtYmRhID0gKC4uLmFyZ3MpID0+IG5ldyAkTGFtYmRhKGFyZ3MubGVuZ3RoID4gMCA/IGFyZ3MgOiBbJHZvaWRdKVxuZXhwb3J0IGNvbnN0ICQkbGFtYmRhID0gJGNvbnN0cnVjdGVkQnkoJExhbWJkYSlcblxuLyoqXG4gKiBAdHlwZSB7U2NoZW1hPEZ1bmN0aW9uPn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRmdW5jdGlvbiA9ICRjdXN0b20obyA9PiB0eXBlb2YgbyA9PT0gJ2Z1bmN0aW9uJylcblxuLyoqXG4gKiBAdGVtcGxhdGUge0FycmF5PFNjaGVtYTxhbnk+Pn0gVFxuICogQGV4dGVuZHMge1NjaGVtYTxJbnRlcnNlY3Q8VW53cmFwQXJyYXk8VD4+Pn1cbiAqL1xuZXhwb3J0IGNsYXNzICRJbnRlcnNlY3Rpb24gZXh0ZW5kcyBTY2hlbWEge1xuICAvKipcbiAgICogQHBhcmFtIHtUfSB2XG4gICAqL1xuICBjb25zdHJ1Y3RvciAodikge1xuICAgIHN1cGVyKClcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7VH1cbiAgICAgKi9cbiAgICB0aGlzLnNoYXBlID0gdlxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7YW55fSBvXG4gICAqIEBwYXJhbSB7VmFsaWRhdGlvbkVycm9yfSBbZXJyXVxuICAgKiBAcmV0dXJuIHtvIGlzIEludGVyc2VjdDxVbndyYXBBcnJheTxUPj59XG4gICAqL1xuICBjaGVjayAobywgZXJyKSB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGMgPSBhcnIuZXZlcnkodGhpcy5zaGFwZSwgY2hlY2sgPT4gY2hlY2suY2hlY2sobywgZXJyKSlcbiAgICAvKiBjOCBpZ25vcmUgbmV4dCAqL1xuICAgICFjICYmIGVycj8uZXh0ZW5kKG51bGwsICdJbnRlcnNlY3Rpbm9uJywgdHlwZW9mIG8pXG4gICAgcmV0dXJuIGNcbiAgfVxufVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7U2NoZW1hPGFueT5bXX0gVFxuICogQHBhcmFtIHtUfSBkZWZcbiAqIEByZXR1cm4ge0Nhc3RUb1NjaGVtYTwkSW50ZXJzZWN0aW9uPFQ+Pn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRpbnRlcnNlY3QgPSAoLi4uZGVmKSA9PiBuZXcgJEludGVyc2VjdGlvbihkZWYpXG5leHBvcnQgY29uc3QgJCRpbnRlcnNlY3QgPSAkY29uc3RydWN0ZWRCeSgkSW50ZXJzZWN0aW9uLCBvID0+IG8uc2hhcGUubGVuZ3RoID4gMCkgLy8gSW50ZXJzZWN0aW9uIHdpdGggbGVuZ3RoPTAgaXMgY29uc2lkZXJlZCBcImFueVwiXG5cbi8qKlxuICogQHRlbXBsYXRlIFNcbiAqIEBleHRlbmRzIHtTY2hlbWE8Uz59XG4gKi9cbmV4cG9ydCBjbGFzcyAkVW5pb24gZXh0ZW5kcyBTY2hlbWEge1xuICBzdGF0aWMgX2RpbHV0ZXMgPSB0cnVlXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8U2NoZW1hPFM+Pn0gdlxuICAgKi9cbiAgY29uc3RydWN0b3IgKHYpIHtcbiAgICBzdXBlcigpXG4gICAgdGhpcy5zaGFwZSA9IHZcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gb1xuICAgKiBAcGFyYW0ge1ZhbGlkYXRpb25FcnJvcn0gW2Vycl1cbiAgICogQHJldHVybiB7byBpcyBTfVxuICAgKi9cbiAgY2hlY2sgKG8sIGVycikge1xuICAgIGNvbnN0IGMgPSBhcnIuc29tZSh0aGlzLnNoYXBlLCAodnYpID0+IHZ2LmNoZWNrKG8sIGVycikpXG4gICAgZXJyPy5leHRlbmQobnVsbCwgJ1VuaW9uJywgdHlwZW9mIG8pXG4gICAgcmV0dXJuIGNcbiAgfVxufVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7QXJyYXk8YW55Pn0gVFxuICogQHBhcmFtIHtUfSBzY2hlbWFzXG4gKiBAcmV0dXJuIHtDYXN0VG9TY2hlbWE8JFVuaW9uPFVud3JhcDxSZWFkU2NoZW1hPFQ+Pj4+fVxuICovXG5leHBvcnQgY29uc3QgJHVuaW9uID0gKC4uLnNjaGVtYXMpID0+IHNjaGVtYXMuZmluZEluZGV4KCRzID0+ICQkdW5pb24uY2hlY2soJHMpKSA+PSAwXG4gID8gJHVuaW9uKC4uLnNjaGVtYXMubWFwKCRzID0+ICQoJHMpKS5tYXAoJHMgPT4gJCR1bmlvbi5jaGVjaygkcykgPyAkcy5zaGFwZSA6IFskc10pLmZsYXQoMSkpXG4gIDogKHNjaGVtYXMubGVuZ3RoID09PSAxXG4gICAgICA/IHNjaGVtYXNbMF1cbiAgICAgIDogbmV3ICRVbmlvbihzY2hlbWFzKSlcbmV4cG9ydCBjb25zdCAkJHVuaW9uID0gLyoqIEB0eXBlIHtTY2hlbWE8JFVuaW9uPGFueT4+fSAqLyAoJGNvbnN0cnVjdGVkQnkoJFVuaW9uKSlcblxuY29uc3QgX3QgPSAoKSA9PiB0cnVlXG4vKipcbiAqIEB0eXBlIHtTY2hlbWE8YW55Pn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRhbnkgPSAkY3VzdG9tKF90KVxuZXhwb3J0IGNvbnN0ICQkYW55ID0gLyoqIEB0eXBlIHtTY2hlbWE8U2NoZW1hPGFueT4+fSAqLyAoJGNvbnN0cnVjdGVkQnkoJEN1c3RvbSwgbyA9PiBvLnNoYXBlID09PSBfdCkpXG5cbi8qKlxuICogQHR5cGUge1NjaGVtYTxiaWdpbnQ+fVxuICovXG5leHBvcnQgY29uc3QgJGJpZ2ludCA9ICRjdXN0b20obyA9PiB0eXBlb2YgbyA9PT0gJ2JpZ2ludCcpXG5leHBvcnQgY29uc3QgJCRiaWdpbnQgPSAvKiogQHR5cGUge1NjaGVtYTxTY2hlbWE8QmlnSW50Pj59ICovICgkY3VzdG9tKG8gPT4gbyA9PT0gJGJpZ2ludCkpXG5cbi8qKlxuICogQHR5cGUge1NjaGVtYTxzeW1ib2w+fVxuICovXG5leHBvcnQgY29uc3QgJHN5bWJvbCA9ICRjdXN0b20obyA9PiB0eXBlb2YgbyA9PT0gJ3N5bWJvbCcpXG5leHBvcnQgY29uc3QgJCRzeW1ib2wgPSAvKiogQHR5cGUge1NjaGVtYTxTY2hlbWE8U3ltYm9sPj59ICovICgkY3VzdG9tKG8gPT4gbyA9PT0gJHN5bWJvbCkpXG5cbi8qKlxuICogQHR5cGUge1NjaGVtYTxudW1iZXI+fVxuICovXG5leHBvcnQgY29uc3QgJG51bWJlciA9ICRjdXN0b20obyA9PiB0eXBlb2YgbyA9PT0gJ251bWJlcicpXG5leHBvcnQgY29uc3QgJCRudW1iZXIgPSAvKiogQHR5cGUge1NjaGVtYTxTY2hlbWE8bnVtYmVyPj59ICovICgkY3VzdG9tKG8gPT4gbyA9PT0gJG51bWJlcikpXG5cbi8qKlxuICogQHR5cGUge1NjaGVtYTxzdHJpbmc+fVxuICovXG5leHBvcnQgY29uc3QgJHN0cmluZyA9ICRjdXN0b20obyA9PiB0eXBlb2YgbyA9PT0gJ3N0cmluZycpXG5leHBvcnQgY29uc3QgJCRzdHJpbmcgPSAvKiogQHR5cGUge1NjaGVtYTxTY2hlbWE8c3RyaW5nPj59ICovICgkY3VzdG9tKG8gPT4gbyA9PT0gJHN0cmluZykpXG5cbi8qKlxuICogQHR5cGUge1NjaGVtYTxib29sZWFuPn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRib29sZWFuID0gJGN1c3RvbShvID0+IHR5cGVvZiBvID09PSAnYm9vbGVhbicpXG5leHBvcnQgY29uc3QgJCRib29sZWFuID0gLyoqIEB0eXBlIHtTY2hlbWE8U2NoZW1hPEJvb2xlYW4+Pn0gKi8gKCRjdXN0b20obyA9PiBvID09PSAkYm9vbGVhbikpXG5cbi8qKlxuICogQHR5cGUge1NjaGVtYTx1bmRlZmluZWQ+fVxuICovXG5leHBvcnQgY29uc3QgJHVuZGVmaW5lZCA9ICRsaXRlcmFsKHVuZGVmaW5lZClcbmV4cG9ydCBjb25zdCAkJHVuZGVmaW5lZCA9IC8qKiBAdHlwZSB7U2NoZW1hPFNjaGVtYTx1bmRlZmluZWQ+Pn0gKi8gKCRjb25zdHJ1Y3RlZEJ5KCRMaXRlcmFsLCBvID0+IG8uc2hhcGUubGVuZ3RoID09PSAxICYmIG8uc2hhcGVbMF0gPT09IHVuZGVmaW5lZCkpXG5cbi8qKlxuICogQHR5cGUge1NjaGVtYTx2b2lkPn1cbiAqL1xuZXhwb3J0IGNvbnN0ICR2b2lkID0gJGxpdGVyYWwodW5kZWZpbmVkKVxuZXhwb3J0IGNvbnN0ICQkdm9pZCA9IC8qKiBAdHlwZSB7U2NoZW1hPFNjaGVtYTx2b2lkPj59ICovICgkJHVuZGVmaW5lZClcblxuZXhwb3J0IGNvbnN0ICRudWxsID0gJGxpdGVyYWwobnVsbClcbmV4cG9ydCBjb25zdCAkJG51bGwgPSAvKiogQHR5cGUge1NjaGVtYTxTY2hlbWE8bnVsbD4+fSAqLyAoJGNvbnN0cnVjdGVkQnkoJExpdGVyYWwsIG8gPT4gby5zaGFwZS5sZW5ndGggPT09IDEgJiYgby5zaGFwZVswXSA9PT0gbnVsbCkpXG5cbmV4cG9ydCBjb25zdCAkdWludDhBcnJheSA9ICRjb25zdHJ1Y3RlZEJ5KFVpbnQ4QXJyYXkpXG5leHBvcnQgY29uc3QgJCR1aW50OEFycmF5ID0gLyoqIEB0eXBlIHtTY2hlbWE8U2NoZW1hPFVpbnQ4QXJyYXk+Pn0gKi8gKCRjb25zdHJ1Y3RlZEJ5KCRDb25zdHJ1Y3RlZEJ5LCBvID0+IG8uc2hhcGUgPT09IFVpbnQ4QXJyYXkpKVxuXG4vKipcbiAqIEB0eXBlIHtTY2hlbWE8UHJpbWl0aXZlPn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRwcmltaXRpdmUgPSAkdW5pb24oJG51bWJlciwgJHN0cmluZywgJG51bGwsICR1bmRlZmluZWQsICRiaWdpbnQsICRib29sZWFuLCAkc3ltYm9sKVxuXG4vKipcbiAqIEB0eXBlZGVmIHtKU09OW119IEpTT05BcnJheVxuICovXG4vKipcbiAqIEB0eXBlZGVmIHtQcmltaXRpdmV8SlNPTkFycmF5fHsgW2tleTpzdHJpbmddOkpTT04gfX0gSlNPTlxuICovXG4vKipcbiAqIEB0eXBlIHtTY2hlbWE8bnVsbHxudW1iZXJ8c3RyaW5nfGJvb2xlYW58SlNPTltdfHtba2V5OnN0cmluZ106SlNPTn0+fVxuICovXG5leHBvcnQgY29uc3QgJGpzb24gPSAoKCkgPT4ge1xuICBjb25zdCAkanNvbkFyciA9IC8qKiBAdHlwZSB7JEFycmF5PCRhbnk+fSAqLyAoJGFycmF5KCRhbnkpKVxuICBjb25zdCAkanNvblJlY29yZCA9IC8qKiBAdHlwZSB7JFJlY29yZDwkc3RyaW5nLCRhbnk+fSAqLyAoJHJlY29yZCgkc3RyaW5nLCAkYW55KSlcbiAgY29uc3QgJGpzb24gPSAkdW5pb24oJG51bWJlciwgJHN0cmluZywgJG51bGwsICRib29sZWFuLCAkanNvbkFyciwgJGpzb25SZWNvcmQpXG4gICRqc29uQXJyLnNoYXBlID0gJGpzb25cbiAgJGpzb25SZWNvcmQuc2hhcGUudmFsdWVzID0gJGpzb25cbiAgcmV0dXJuICRqc29uXG59KSgpXG5cbi8qKlxuICogQHRlbXBsYXRlIHthbnl9IElOXG4gKiBAdHlwZWRlZiB7SU4gZXh0ZW5kcyBTY2hlbWE8YW55PiA/IElOXG4gKiAgIDogKElOIGV4dGVuZHMgc3RyaW5nfG51bWJlcnxib29sZWFufG51bGwgPyBTY2hlbWE8SU4+XG4gKiAgICAgOiAoSU4gZXh0ZW5kcyBuZXcgKC4uLmFyZ3M6YW55W10pPT5hbnkgPyBTY2hlbWE8SW5zdGFuY2VUeXBlPElOPj5cbiAqICAgICAgIDogKElOIGV4dGVuZHMgYW55W10gPyBTY2hlbWE8eyBbSyBpbiBrZXlvZiBJTl06IFVud3JhcDxSZWFkU2NoZW1hPElOW0tdPj4gfVtudW1iZXJdPlxuICAgKiAgICAgICA6IChJTiBleHRlbmRzIG9iamVjdCA/IChfT2JqZWN0RGVmVG9TY2hlbWE8e1tLIGluIGtleW9mIElOXTpSZWFkU2NoZW1hPElOW0tdPn0+IGV4dGVuZHMgU2NoZW1hPGluZmVyIFM+ID8gU2NoZW1hPHsgW0sgaW4ga2V5b2YgU106IFNbS10gfT4gOiBuZXZlcilcbiAgICogICAgICAgICA6IG5ldmVyKVxuICogICAgICAgICApXG4gKiAgICAgICApXG4gKiAgICAgKVxuICogfSBSZWFkU2NoZW1hT2xkXG4gKi9cblxuLyoqXG4gKiBAdGVtcGxhdGUge2FueX0gSU5cbiAqIEB0eXBlZGVmIHtbRXh0cmFjdDxJTixTY2hlbWE8YW55Pj4sRXh0cmFjdDxJTixzdHJpbmd8bnVtYmVyfGJvb2xlYW58bnVsbD4sRXh0cmFjdDxJTixuZXcgKC4uLmFyZ3M6YW55W10pPT5hbnk+LEV4dHJhY3Q8SU4sYW55W10+LEV4dHJhY3Q8RXhjbHVkZTxJTixTY2hlbWE8YW55PnxzdHJpbmd8bnVtYmVyfGJvb2xlYW58bnVsbHwobmV3ICguLi5hcmdzOmFueVtdKT0+YW55KXxhbnlbXT4sb2JqZWN0Pl0gZXh0ZW5kcyBbaW5mZXIgU2NoZW1hcywgaW5mZXIgUHJpbWl0aXZlcywgaW5mZXIgQ29uc3RydWN0b3JzLCBpbmZlciBBcnJzLCBpbmZlciBPYmpdXG4gKiAgID8gU2NoZW1hPFxuICogICAgICAgKFNjaGVtYXMgZXh0ZW5kcyBTY2hlbWE8aW5mZXIgUz4gPyBTIDogbmV2ZXIpXG4gKiAgICAgfCBQcmltaXRpdmVzXG4gKiAgICAgfCAoQ29uc3RydWN0b3JzIGV4dGVuZHMgbmV3ICguLi5hcmdzOmFueVtdKT0+YW55ID8gSW5zdGFuY2VUeXBlPENvbnN0cnVjdG9ycz4gOiBuZXZlcilcbiAqICAgICB8IChBcnJzIGV4dGVuZHMgYW55W10gPyB7IFtLIGluIGtleW9mIEFycnNdOiBVbndyYXA8UmVhZFNjaGVtYTxBcnJzW0tdPj4gfVtudW1iZXJdIDogbmV2ZXIpXG4gKiAgICAgfCAoT2JqIGV4dGVuZHMgb2JqZWN0ID8gVW53cmFwPChfT2JqZWN0RGVmVG9TY2hlbWE8e1tLIGluIGtleW9mIE9ial06UmVhZFNjaGVtYTxPYmpbS10+fT4gZXh0ZW5kcyBTY2hlbWE8aW5mZXIgUz4gPyBTY2hlbWE8eyBbSyBpbiBrZXlvZiBTXTogU1tLXSB9PiA6IG5ldmVyKT4gOiBuZXZlcik+XG4gKiAgIDogbmV2ZXJcbiAqIH0gUmVhZFNjaGVtYVxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge1JlYWRTY2hlbWE8e3g6NDJ9fHt5Ojk5fXxTY2hlbWE8c3RyaW5nPnxbMSwyLHt9XT59IFFcbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBJTlxuICogQHBhcmFtIHtJTn0gb1xuICogQHJldHVybiB7UmVhZFNjaGVtYTxJTj59XG4gKi9cbmV4cG9ydCBjb25zdCAkID0gbyA9PiB7XG4gIGlmICgkJHNjaGVtYS5jaGVjayhvKSkge1xuICAgIHJldHVybiAvKiogQHR5cGUge2FueX0gKi8gKG8pXG4gIH0gZWxzZSBpZiAoJG9iamVjdEFueS5jaGVjayhvKSkge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHthbnl9XG4gICAgICovXG4gICAgY29uc3QgbzIgPSB7fVxuICAgIGZvciAoY29uc3QgayBpbiBvKSB7XG4gICAgICBvMltrXSA9ICQob1trXSlcbiAgICB9XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7YW55fSAqLyAoJG9iamVjdChvMikpXG4gIH0gZWxzZSBpZiAoJGFycmF5QW55LmNoZWNrKG8pKSB7XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7YW55fSAqLyAoJHVuaW9uKC4uLm8ubWFwKCQpKSlcbiAgfSBlbHNlIGlmICgkcHJpbWl0aXZlLmNoZWNrKG8pKSB7XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7YW55fSAqLyAoJGxpdGVyYWwobykpXG4gIH0gZWxzZSBpZiAoJGZ1bmN0aW9uLmNoZWNrKG8pKSB7XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7YW55fSAqLyAoJGNvbnN0cnVjdGVkQnkoLyoqIEB0eXBlIHthbnl9ICovIChvKSkpXG4gIH1cbiAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgZXJyb3IudW5leHBlY3RlZENhc2UoKVxufVxuXG4vKiBjOCBpZ25vcmUgc3RhcnQgKi9cbi8qKlxuICogQXNzZXJ0IHRoYXQgYSB2YXJpYWJsZSBpcyBvZiB0aGlzIHNwZWNpZmljIHR5cGUuXG4gKiBUaGUgYXNzZXJ0aW9uIGNoZWNrIGlzIG9ubHkgcGVyZm9ybWVkIGluIG5vbi1wcm9kdWN0aW9uIGVudmlyb25tZW50cy5cbiAqXG4gKiBAdHlwZSB7PFQ+KG86YW55LHNjaGVtYTpTY2hlbWE8VD4pID0+IGFzc2VydHMgbyBpcyBUfVxuICovXG5leHBvcnQgY29uc3QgYXNzZXJ0ID0gZW52LnByb2R1Y3Rpb25cbiAgPyAoKSA9PiB7fVxuICA6IChvLCBzY2hlbWEpID0+IHtcbiAgICAgIGNvbnN0IGVyciA9IG5ldyBWYWxpZGF0aW9uRXJyb3IoKVxuICAgICAgaWYgKCFzY2hlbWEuY2hlY2sobywgZXJyKSkge1xuICAgICAgICB0aHJvdyBlcnJvci5jcmVhdGUoYEV4cGVjdGVkIHZhbHVlIHRvIGJlIG9mIHR5cGUgJHtzY2hlbWEuY29uc3RydWN0b3IubmFtZX0uXFxuJHtlcnIudG9TdHJpbmcoKX1gKVxuICAgICAgfVxuICAgIH1cbi8qIGM4IGlnbm9yZSBlbmQgKi9cblxuLyoqXG4gKiBAdGVtcGxhdGUgSW5cbiAqIEB0ZW1wbGF0ZSBPdXRcbiAqIEB0eXBlZGVmIHt7IGlmOiBTY2hlbWE8SW4+LCBoOiAobzpJbixzdGF0ZT86YW55KT0+T3V0IH19IFBhdHRlcm5cbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7UGF0dGVybjxhbnksYW55Pn0gUFxuICogQHRlbXBsYXRlIEluXG4gKiBAdHlwZWRlZiB7UmV0dXJuVHlwZTxFeHRyYWN0PFAsUGF0dGVybjxJbiBleHRlbmRzIG51bWJlciA/IG51bWJlciA6IChJbiBleHRlbmRzIHN0cmluZyA/IHN0cmluZyA6IEluKSxhbnk+PlsnaCddPn0gUGF0dGVybk1hdGNoUmVzdWx0XG4gKi9cblxuLyoqXG4gKiBAdG9kbyBtb3ZlIHRoaXMgdG8gc2VwYXJhdGUgbGlicmFyeVxuICogQHRlbXBsYXRlIHthbnl9IFtTdGF0ZT11bmRlZmluZWRdXG4gKiBAdGVtcGxhdGUge1BhdHRlcm48YW55LGFueT59IFtQYXR0ZXJucz1uZXZlcl1cbiAqL1xuZXhwb3J0IGNsYXNzIFBhdHRlcm5NYXRjaGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7U2NoZW1hPFN0YXRlPn0gWyRzdGF0ZV1cbiAgICovXG4gIGNvbnN0cnVjdG9yICgkc3RhdGUpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8UGF0dGVybnM+fVxuICAgICAqL1xuICAgIHRoaXMucGF0dGVybnMgPSBbXVxuICAgIHRoaXMuJHN0YXRlID0gJHN0YXRlXG4gIH1cblxuICAvKipcbiAgICogQHRlbXBsYXRlIFBcbiAgICogQHRlbXBsYXRlIFJcbiAgICogQHBhcmFtIHtQfSBwYXR0ZXJuXG4gICAqIEBwYXJhbSB7KG86Tm9JbmZlcjxVbndyYXA8UmVhZFNjaGVtYTxQPj4+LHM6U3RhdGUpPT5SfSBoYW5kbGVyXG4gICAqIEByZXR1cm4ge1BhdHRlcm5NYXRjaGVyPFN0YXRlLFBhdHRlcm5zfFBhdHRlcm48VW53cmFwPFJlYWRTY2hlbWE8UD4+LFI+Pn1cbiAgICovXG4gIGlmIChwYXR0ZXJuLCBoYW5kbGVyKSB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHRoaXMucGF0dGVybnMucHVzaCh7IGlmOiAkKHBhdHRlcm4pLCBoOiBoYW5kbGVyIH0pXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICAvKipcbiAgICogQHRlbXBsYXRlIFJcbiAgICogQHBhcmFtIHsobzphbnksczpTdGF0ZSk9PlJ9IGhcbiAgICovXG4gIGVsc2UgKGgpIHtcbiAgICByZXR1cm4gdGhpcy5pZigkYW55LCBoKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1N0YXRlIGV4dGVuZHMgdW5kZWZpbmVkXG4gICAqICAgPyA8SW4gZXh0ZW5kcyBVbndyYXA8UGF0dGVybnNbJ2lmJ10+PihvOkluLHN0YXRlPzp1bmRlZmluZWQpPT5QYXR0ZXJuTWF0Y2hSZXN1bHQ8UGF0dGVybnMsSW4+XG4gICAqICAgOiA8SW4gZXh0ZW5kcyBVbndyYXA8UGF0dGVybnNbJ2lmJ10+PihvOkluLHN0YXRlOlN0YXRlKT0+UGF0dGVybk1hdGNoUmVzdWx0PFBhdHRlcm5zLEluPn1cbiAgICovXG4gIGRvbmUgKCkge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICByZXR1cm4gLyoqIEB0eXBlIHthbnl9ICovIChvLCBzKSA9PiB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGF0dGVybnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgcCA9IHRoaXMucGF0dGVybnNbaV1cbiAgICAgICAgaWYgKHAuaWYuY2hlY2sobykpIHtcbiAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgcmV0dXJuIHAuaChvLCBzKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvci5jcmVhdGUoJ1VuaGFuZGxlZCBwYXR0ZXJuJylcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgW1N0YXRlPXVuZGVmaW5lZF1cbiAqIEBwYXJhbSB7U3RhdGV9IFtzdGF0ZV1cbiAqIEByZXR1cm4ge1BhdHRlcm5NYXRjaGVyPFN0YXRlIGV4dGVuZHMgdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogVW53cmFwPFJlYWRTY2hlbWE8U3RhdGU+Pj59XG4gKi9cbmV4cG9ydCBjb25zdCBtYXRjaCA9IHN0YXRlID0+IG5ldyBQYXR0ZXJuTWF0Y2hlcigvKiogQHR5cGUge2FueX0gKi8gKHN0YXRlKSlcblxuLyoqXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2VuZXJhdGUgYSAobm9uLWV4aGF1c3RpdmUpIHNhbXBsZSBzZXQgZnJvbSBhIGdpdmVzIHNjaGVtYS5cbiAqXG4gKiBAdHlwZSB7PFQ+KG86VCxnZW46cHJuZy5QUk5HKT0+VH1cbiAqL1xuY29uc3QgX3JhbmRvbSA9IC8qKiBAdHlwZSB7YW55fSAqLyAobWF0Y2goLyoqIEB0eXBlIHtTY2hlbWE8cHJuZy5QUk5HPn0gKi8gKCRhbnkpKVxuICAuaWYoJCRudW1iZXIsIChfbywgZ2VuKSA9PiBwcm5nLmludDUzKGdlbiwgbnVtYmVyLk1JTl9TQUZFX0lOVEVHRVIsIG51bWJlci5NQVhfU0FGRV9JTlRFR0VSKSlcbiAgLmlmKCQkc3RyaW5nLCAoX28sIGdlbikgPT4gcHJuZy53b3JkKGdlbikpXG4gIC5pZigkJGJvb2xlYW4sIChfbywgZ2VuKSA9PiBwcm5nLmJvb2woZ2VuKSlcbiAgLmlmKCQkYmlnaW50LCAoX28sIGdlbikgPT4gQmlnSW50KHBybmcuaW50NTMoZ2VuLCBudW1iZXIuTUlOX1NBRkVfSU5URUdFUiwgbnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpKSlcbiAgLmlmKCQkdW5pb24sIChvLCBnZW4pID0+IHJhbmRvbShnZW4sIHBybmcub25lT2YoZ2VuLCBvLnNoYXBlKSkpXG4gIC5pZigkJG9iamVjdCwgKG8sIGdlbikgPT4ge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHthbnl9XG4gICAgICovXG4gICAgY29uc3QgcmVzID0ge31cbiAgICBmb3IgKGNvbnN0IGsgaW4gby5zaGFwZSkge1xuICAgICAgbGV0IHByb3AgPSBvLnNoYXBlW2tdXG4gICAgICBpZiAoJCRvcHRpb25hbC5jaGVjayhwcm9wKSkge1xuICAgICAgICBpZiAocHJuZy5ib29sKGdlbikpIHsgY29udGludWUgfVxuICAgICAgICBwcm9wID0gcHJvcC5zaGFwZVxuICAgICAgfVxuICAgICAgcmVzW2tdID0gX3JhbmRvbShwcm9wLCBnZW4pXG4gICAgfVxuICAgIHJldHVybiByZXNcbiAgfSlcbiAgLmlmKCQkYXJyYXksIChvLCBnZW4pID0+IHtcbiAgICBjb25zdCBhcnIgPSBbXVxuICAgIGNvbnN0IG4gPSBwcm5nLmludDMyKGdlbiwgMCwgNDIpXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgIGFyci5wdXNoKHJhbmRvbShnZW4sIG8uc2hhcGUpKVxuICAgIH1cbiAgICByZXR1cm4gYXJyXG4gIH0pXG4gIC5pZigkJGxpdGVyYWwsIChvLCBnZW4pID0+IHtcbiAgICByZXR1cm4gcHJuZy5vbmVPZihnZW4sIG8uc2hhcGUpXG4gIH0pXG4gIC5pZigkJG51bGwsIChvLCBnZW4pID0+IHtcbiAgICByZXR1cm4gbnVsbFxuICB9KVxuICAuaWYoJCRsYW1iZGEsIChvLCBnZW4pID0+IHtcbiAgICBjb25zdCByZXMgPSByYW5kb20oZ2VuLCBvLnJlcylcbiAgICByZXR1cm4gKCkgPT4gcmVzXG4gIH0pXG4gIC5pZigkJGFueSwgKG8sIGdlbikgPT4gcmFuZG9tKGdlbiwgcHJuZy5vbmVPZihnZW4sIFtcbiAgICAkbnVtYmVyLCAkc3RyaW5nLCAkbnVsbCwgJHVuZGVmaW5lZCwgJGJpZ2ludCwgJGJvb2xlYW4sXG4gICAgJGFycmF5KCRudW1iZXIpLFxuICAgICRyZWNvcmQoJHVuaW9uKCdhJywgJ2InLCAnYycpLCAkbnVtYmVyKVxuICBdKSkpXG4gIC5pZigkJHJlY29yZCwgKG8sIGdlbikgPT4ge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHthbnl9XG4gICAgICovXG4gICAgY29uc3QgcmVzID0ge31cbiAgICBjb25zdCBrZXlzTiA9IHBybmcuaW50NTMoZ2VuLCAwLCAzKVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5c047IGkrKykge1xuICAgICAgY29uc3Qga2V5ID0gcmFuZG9tKGdlbiwgby5zaGFwZS5rZXlzKVxuICAgICAgY29uc3QgdmFsID0gcmFuZG9tKGdlbiwgby5zaGFwZS52YWx1ZXMpXG4gICAgICByZXNba2V5XSA9IHZhbFxuICAgIH1cbiAgICByZXR1cm4gcmVzXG4gIH0pXG4gIC5kb25lKCkpXG5cbi8qKlxuICogQHRlbXBsYXRlIFNcbiAqIEBwYXJhbSB7cHJuZy5QUk5HfSBnZW5cbiAqIEBwYXJhbSB7U30gc2NoZW1hXG4gKiBAcmV0dXJuIHtVbndyYXA8UmVhZFNjaGVtYTxTPj59XG4gKi9cbmV4cG9ydCBjb25zdCByYW5kb20gPSAoZ2VuLCBzY2hlbWEpID0+IC8qKiBAdHlwZSB7YW55fSAqLyAoX3JhbmRvbSgkKHNjaGVtYSksIGdlbikpXG4iLCAiLyogZXNsaW50LWVudiBicm93c2VyICovXG5cbi8qKlxuICogVXRpbGl0eSBtb2R1bGUgdG8gd29yayB3aXRoIHRoZSBET00uXG4gKlxuICogQG1vZHVsZSBkb21cbiAqL1xuXG5pbXBvcnQgKiBhcyBwYWlyIGZyb20gJy4vcGFpci5qcydcbmltcG9ydCAqIGFzIG1hcCBmcm9tICcuL21hcC5qcydcbmltcG9ydCAqIGFzICQgZnJvbSAnLi9zY2hlbWEuanMnXG5cbi8qIGM4IGlnbm9yZSBzdGFydCAqL1xuLyoqXG4gKiBAdHlwZSB7RG9jdW1lbnR9XG4gKi9cbmV4cG9ydCBjb25zdCBkb2MgPSAvKiogQHR5cGUge0RvY3VtZW50fSAqLyAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyA/IGRvY3VtZW50IDoge30pXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlRWxlbWVudCA9IG5hbWUgPT4gZG9jLmNyZWF0ZUVsZW1lbnQobmFtZSlcblxuLyoqXG4gKiBAcmV0dXJuIHtEb2N1bWVudEZyYWdtZW50fVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlRG9jdW1lbnRGcmFnbWVudCA9ICgpID0+IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KClcblxuLyoqXG4gKiBAdHlwZSB7JC5TY2hlbWE8RG9jdW1lbnRGcmFnbWVudD59XG4gKi9cbmV4cG9ydCBjb25zdCAkZnJhZ21lbnQgPSAkLiRjdXN0b20oZWwgPT4gZWwubm9kZVR5cGUgPT09IERPQ1VNRU5UX0ZSQUdNRU5UX05PREUpXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqIEByZXR1cm4ge1RleHR9XG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVUZXh0Tm9kZSA9IHRleHQgPT4gZG9jLmNyZWF0ZVRleHROb2RlKHRleHQpXG5cbmV4cG9ydCBjb25zdCBkb21QYXJzZXIgPSAvKiogQHR5cGUge0RPTVBhcnNlcn0gKi8gKHR5cGVvZiBET01QYXJzZXIgIT09ICd1bmRlZmluZWQnID8gbmV3IERPTVBhcnNlcigpIDogbnVsbClcblxuLyoqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbFxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzXG4gKi9cbmV4cG9ydCBjb25zdCBlbWl0Q3VzdG9tRXZlbnQgPSAoZWwsIG5hbWUsIG9wdHMpID0+IGVsLmRpc3BhdGNoRXZlbnQobmV3IEN1c3RvbUV2ZW50KG5hbWUsIG9wdHMpKVxuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7QXJyYXk8cGFpci5QYWlyPHN0cmluZyxzdHJpbmd8Ym9vbGVhbj4+fSBhdHRycyBBcnJheSBvZiBrZXktdmFsdWUgcGFpcnNcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cbmV4cG9ydCBjb25zdCBzZXRBdHRyaWJ1dGVzID0gKGVsLCBhdHRycykgPT4ge1xuICBwYWlyLmZvckVhY2goYXR0cnMsIChrZXksIHZhbHVlKSA9PiB7XG4gICAgaWYgKHZhbHVlID09PSBmYWxzZSkge1xuICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKGtleSlcbiAgICB9IGVsc2UgaWYgKHZhbHVlID09PSB0cnVlKSB7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoa2V5LCAnJylcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgZWwuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpXG4gICAgfVxuICB9KVxuICByZXR1cm4gZWxcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIHN0cmluZz59IGF0dHJzIEFycmF5IG9mIGtleS12YWx1ZSBwYWlyc1xuICogQHJldHVybiB7RWxlbWVudH1cbiAqL1xuZXhwb3J0IGNvbnN0IHNldEF0dHJpYnV0ZXNNYXAgPSAoZWwsIGF0dHJzKSA9PiB7XG4gIGF0dHJzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHsgZWwuc2V0QXR0cmlidXRlKGtleSwgdmFsdWUpIH0pXG4gIHJldHVybiBlbFxufVxuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8Tm9kZT58SFRNTENvbGxlY3Rpb259IGNoaWxkcmVuXG4gKiBAcmV0dXJuIHtEb2N1bWVudEZyYWdtZW50fVxuICovXG5leHBvcnQgY29uc3QgZnJhZ21lbnQgPSBjaGlsZHJlbiA9PiB7XG4gIGNvbnN0IGZyYWdtZW50ID0gY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICBhcHBlbmRDaGlsZChmcmFnbWVudCwgY2hpbGRyZW5baV0pXG4gIH1cbiAgcmV0dXJuIGZyYWdtZW50XG59XG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSBwYXJlbnRcbiAqIEBwYXJhbSB7QXJyYXk8Tm9kZT59IG5vZGVzXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5leHBvcnQgY29uc3QgYXBwZW5kID0gKHBhcmVudCwgbm9kZXMpID0+IHtcbiAgYXBwZW5kQ2hpbGQocGFyZW50LCBmcmFnbWVudChub2RlcykpXG4gIHJldHVybiBwYXJlbnRcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbFxuICovXG5leHBvcnQgY29uc3QgcmVtb3ZlID0gZWwgPT4gZWwucmVtb3ZlKClcblxuLyoqXG4gKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSBlbFxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7RXZlbnRMaXN0ZW5lcn0gZlxuICovXG5leHBvcnQgY29uc3QgYWRkRXZlbnRMaXN0ZW5lciA9IChlbCwgbmFtZSwgZikgPT4gZWwuYWRkRXZlbnRMaXN0ZW5lcihuYW1lLCBmKVxuXG4vKipcbiAqIEBwYXJhbSB7RXZlbnRUYXJnZXR9IGVsXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtFdmVudExpc3RlbmVyfSBmXG4gKi9cbmV4cG9ydCBjb25zdCByZW1vdmVFdmVudExpc3RlbmVyID0gKGVsLCBuYW1lLCBmKSA9PiBlbC5yZW1vdmVFdmVudExpc3RlbmVyKG5hbWUsIGYpXG5cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKiBAcGFyYW0ge0FycmF5PHBhaXIuUGFpcjxzdHJpbmcsRXZlbnRMaXN0ZW5lcj4+fSBsaXN0ZW5lcnNcbiAqIEByZXR1cm4ge05vZGV9XG4gKi9cbmV4cG9ydCBjb25zdCBhZGRFdmVudExpc3RlbmVycyA9IChub2RlLCBsaXN0ZW5lcnMpID0+IHtcbiAgcGFpci5mb3JFYWNoKGxpc3RlbmVycywgKG5hbWUsIGYpID0+IGFkZEV2ZW50TGlzdGVuZXIobm9kZSwgbmFtZSwgZikpXG4gIHJldHVybiBub2RlXG59XG5cbi8qKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKiBAcGFyYW0ge0FycmF5PHBhaXIuUGFpcjxzdHJpbmcsRXZlbnRMaXN0ZW5lcj4+fSBsaXN0ZW5lcnNcbiAqIEByZXR1cm4ge05vZGV9XG4gKi9cbmV4cG9ydCBjb25zdCByZW1vdmVFdmVudExpc3RlbmVycyA9IChub2RlLCBsaXN0ZW5lcnMpID0+IHtcbiAgcGFpci5mb3JFYWNoKGxpc3RlbmVycywgKG5hbWUsIGYpID0+IHJlbW92ZUV2ZW50TGlzdGVuZXIobm9kZSwgbmFtZSwgZikpXG4gIHJldHVybiBub2RlXG59XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7QXJyYXk8cGFpci5QYWlyPHN0cmluZyxzdHJpbmc+fHBhaXIuUGFpcjxzdHJpbmcsYm9vbGVhbj4+fSBhdHRycyBBcnJheSBvZiBrZXktdmFsdWUgcGFpcnNcbiAqIEBwYXJhbSB7QXJyYXk8Tm9kZT59IGNoaWxkcmVuXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5leHBvcnQgY29uc3QgZWxlbWVudCA9IChuYW1lLCBhdHRycyA9IFtdLCBjaGlsZHJlbiA9IFtdKSA9PlxuICBhcHBlbmQoc2V0QXR0cmlidXRlcyhjcmVhdGVFbGVtZW50KG5hbWUpLCBhdHRycyksIGNoaWxkcmVuKVxuXG4vKipcbiAqIEB0eXBlIHskLlNjaGVtYTxFbGVtZW50Pn1cbiAqL1xuZXhwb3J0IGNvbnN0ICRlbGVtZW50ID0gJC4kY3VzdG9tKGVsID0+IGVsLm5vZGVUeXBlID09PSBFTEVNRU5UX05PREUpXG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0XG4gKi9cbmV4cG9ydCBjb25zdCBjYW52YXMgPSAod2lkdGgsIGhlaWdodCkgPT4ge1xuICBjb25zdCBjID0gLyoqIEB0eXBlIHtIVE1MQ2FudmFzRWxlbWVudH0gKi8gKGNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpKVxuICBjLmhlaWdodCA9IGhlaWdodFxuICBjLndpZHRoID0gd2lkdGhcbiAgcmV0dXJuIGNcbn1cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gdFxuICogQHJldHVybiB7VGV4dH1cbiAqL1xuZXhwb3J0IGNvbnN0IHRleHQgPSBjcmVhdGVUZXh0Tm9kZVxuXG4vKipcbiAqIEB0eXBlIHskLlNjaGVtYTxUZXh0Pn1cbiAqL1xuZXhwb3J0IGNvbnN0ICR0ZXh0ID0gJC4kY3VzdG9tKGVsID0+IGVsLm5vZGVUeXBlID09PSBURVhUX05PREUpXG5cbi8qKlxuICogQHBhcmFtIHtwYWlyLlBhaXI8c3RyaW5nLHN0cmluZz59IHBhaXJcbiAqL1xuZXhwb3J0IGNvbnN0IHBhaXJUb1N0eWxlU3RyaW5nID0gcGFpciA9PiBgJHtwYWlyLmxlZnR9OiR7cGFpci5yaWdodH07YFxuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8cGFpci5QYWlyPHN0cmluZyxzdHJpbmc+Pn0gcGFpcnNcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IHBhaXJzVG9TdHlsZVN0cmluZyA9IHBhaXJzID0+IHBhaXJzLm1hcChwYWlyVG9TdHlsZVN0cmluZykuam9pbignJylcblxuLyoqXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsc3RyaW5nPn0gbVxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgbWFwVG9TdHlsZVN0cmluZyA9IG0gPT4gbWFwLm1hcChtLCAodmFsdWUsIGtleSkgPT4gYCR7a2V5fToke3ZhbHVlfTtgKS5qb2luKCcnKVxuXG4vKipcbiAqIEB0b2RvIHNob3VsZCBhbHdheXMgcXVlcnkgb24gYSBkb20gZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR8U2hhZG93Um9vdH0gZWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBxdWVyeVxuICogQHJldHVybiB7SFRNTEVsZW1lbnQgfCBudWxsfVxuICovXG5leHBvcnQgY29uc3QgcXVlcnlTZWxlY3RvciA9IChlbCwgcXVlcnkpID0+IGVsLnF1ZXJ5U2VsZWN0b3IocXVlcnkpXG5cbi8qKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudHxTaGFkb3dSb290fSBlbFxuICogQHBhcmFtIHtzdHJpbmd9IHF1ZXJ5XG4gKiBAcmV0dXJuIHtOb2RlTGlzdE9mPEhUTUxFbGVtZW50Pn1cbiAqL1xuZXhwb3J0IGNvbnN0IHF1ZXJ5U2VsZWN0b3JBbGwgPSAoZWwsIHF1ZXJ5KSA9PiBlbC5xdWVyeVNlbGVjdG9yQWxsKHF1ZXJ5KVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuICogQHJldHVybiB7SFRNTEVsZW1lbnR9XG4gKi9cbmV4cG9ydCBjb25zdCBnZXRFbGVtZW50QnlJZCA9IGlkID0+IC8qKiBAdHlwZSB7SFRNTEVsZW1lbnR9ICovIChkb2MuZ2V0RWxlbWVudEJ5SWQoaWQpKVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sXG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAqL1xuY29uc3QgX3BhcnNlID0gaHRtbCA9PiBkb21QYXJzZXIucGFyc2VGcm9tU3RyaW5nKGA8aHRtbD48Ym9keT4ke2h0bWx9PC9ib2R5PjwvaHRtbD5gLCAndGV4dC9odG1sJykuYm9keVxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSBodG1sXG4gKiBAcmV0dXJuIHtEb2N1bWVudEZyYWdtZW50fVxuICovXG5leHBvcnQgY29uc3QgcGFyc2VGcmFnbWVudCA9IGh0bWwgPT4gZnJhZ21lbnQoLyoqIEB0eXBlIHthbnl9ICovIChfcGFyc2UoaHRtbCkuY2hpbGROb2RlcykpXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGh0bWxcbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fVxuICovXG5leHBvcnQgY29uc3QgcGFyc2VFbGVtZW50ID0gaHRtbCA9PiAvKiogQHR5cGUgSFRNTEVsZW1lbnQgKi8gKF9wYXJzZShodG1sKS5maXJzdEVsZW1lbnRDaGlsZClcblxuLyoqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBvbGRFbFxuICogQHBhcmFtIHtIVE1MRWxlbWVudHxEb2N1bWVudEZyYWdtZW50fSBuZXdFbFxuICovXG5leHBvcnQgY29uc3QgcmVwbGFjZVdpdGggPSAob2xkRWwsIG5ld0VsKSA9PiBvbGRFbC5yZXBsYWNlV2l0aChuZXdFbClcblxuLyoqXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBwYXJlbnRcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge05vZGV8bnVsbH0gcmVmXG4gKiBAcmV0dXJuIHtIVE1MRWxlbWVudH1cbiAqL1xuZXhwb3J0IGNvbnN0IGluc2VydEJlZm9yZSA9IChwYXJlbnQsIGVsLCByZWYpID0+IHBhcmVudC5pbnNlcnRCZWZvcmUoZWwsIHJlZilcblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IHBhcmVudFxuICogQHBhcmFtIHtOb2RlfSBjaGlsZFxuICogQHJldHVybiB7Tm9kZX1cbiAqL1xuZXhwb3J0IGNvbnN0IGFwcGVuZENoaWxkID0gKHBhcmVudCwgY2hpbGQpID0+IHBhcmVudC5hcHBlbmRDaGlsZChjaGlsZClcblxuZXhwb3J0IGNvbnN0IEVMRU1FTlRfTk9ERSA9IGRvYy5FTEVNRU5UX05PREVcbmV4cG9ydCBjb25zdCBURVhUX05PREUgPSBkb2MuVEVYVF9OT0RFXG5leHBvcnQgY29uc3QgQ0RBVEFfU0VDVElPTl9OT0RFID0gZG9jLkNEQVRBX1NFQ1RJT05fTk9ERVxuZXhwb3J0IGNvbnN0IENPTU1FTlRfTk9ERSA9IGRvYy5DT01NRU5UX05PREVcbmV4cG9ydCBjb25zdCBET0NVTUVOVF9OT0RFID0gZG9jLkRPQ1VNRU5UX05PREVcbmV4cG9ydCBjb25zdCBET0NVTUVOVF9UWVBFX05PREUgPSBkb2MuRE9DVU1FTlRfVFlQRV9OT0RFXG5leHBvcnQgY29uc3QgRE9DVU1FTlRfRlJBR01FTlRfTk9ERSA9IGRvYy5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFXG5cbi8qKlxuICogQHR5cGUgeyQuU2NoZW1hPE5vZGU+fVxuICovXG5leHBvcnQgY29uc3QgJG5vZGUgPSAkLiRjdXN0b20oZWwgPT4gZWwubm9kZVR5cGUgPT09IERPQ1VNRU5UX05PREUpXG5cbi8qKlxuICogQHBhcmFtIHthbnl9IG5vZGVcbiAqIEBwYXJhbSB7bnVtYmVyfSB0eXBlXG4gKi9cbmV4cG9ydCBjb25zdCBjaGVja05vZGVUeXBlID0gKG5vZGUsIHR5cGUpID0+IG5vZGUubm9kZVR5cGUgPT09IHR5cGVcblxuLyoqXG4gKiBAcGFyYW0ge05vZGV9IHBhcmVudFxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gY2hpbGRcbiAqL1xuZXhwb3J0IGNvbnN0IGlzUGFyZW50T2YgPSAocGFyZW50LCBjaGlsZCkgPT4ge1xuICBsZXQgcCA9IGNoaWxkLnBhcmVudE5vZGVcbiAgd2hpbGUgKHAgJiYgcCAhPT0gcGFyZW50KSB7XG4gICAgcCA9IHAucGFyZW50Tm9kZVxuICB9XG4gIHJldHVybiBwID09PSBwYXJlbnRcbn1cbi8qIGM4IGlnbm9yZSBzdG9wICovXG4iLCAiLyogZ2xvYmFsIHJlcXVlc3RJZGxlQ2FsbGJhY2ssIHJlcXVlc3RBbmltYXRpb25GcmFtZSwgY2FuY2VsSWRsZUNhbGxiYWNrLCBjYW5jZWxBbmltYXRpb25GcmFtZSAqL1xuXG5pbXBvcnQgKiBhcyB0aW1lIGZyb20gJy4vdGltZS5qcydcblxuLyoqXG4gKiBVdGlsaXR5IG1vZHVsZSB0byB3b3JrIHdpdGggRWNtYVNjcmlwdCdzIGV2ZW50IGxvb3AuXG4gKlxuICogQG1vZHVsZSBldmVudGxvb3BcbiAqL1xuXG4vKipcbiAqIEB0eXBlIHtBcnJheTxmdW5jdGlvbj59XG4gKi9cbmxldCBxdWV1ZSA9IFtdXG5cbmNvbnN0IF9ydW5RdWV1ZSA9ICgpID0+IHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgIHF1ZXVlW2ldKClcbiAgfVxuICBxdWV1ZSA9IFtdXG59XG5cbi8qKlxuICogQHBhcmFtIHtmdW5jdGlvbigpOnZvaWR9IGZcbiAqL1xuZXhwb3J0IGNvbnN0IGVucXVldWUgPSBmID0+IHtcbiAgcXVldWUucHVzaChmKVxuICBpZiAocXVldWUubGVuZ3RoID09PSAxKSB7XG4gICAgc2V0VGltZW91dChfcnVuUXVldWUsIDApXG4gIH1cbn1cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBUaW1lb3V0T2JqZWN0XG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBUaW1lb3V0T2JqZWN0LmRlc3Ryb3lcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7ZnVuY3Rpb24obnVtYmVyKTp2b2lkfSBjbGVhckZ1bmN0aW9uXG4gKi9cbmNvbnN0IGNyZWF0ZVRpbWVvdXRDbGFzcyA9IGNsZWFyRnVuY3Rpb24gPT4gY2xhc3MgVFQge1xuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRJZFxuICAgKi9cbiAgY29uc3RydWN0b3IgKHRpbWVvdXRJZCkge1xuICAgIHRoaXMuXyA9IHRpbWVvdXRJZFxuICB9XG5cbiAgZGVzdHJveSAoKSB7XG4gICAgY2xlYXJGdW5jdGlvbih0aGlzLl8pXG4gIH1cbn1cblxuY29uc3QgVGltZW91dCA9IGNyZWF0ZVRpbWVvdXRDbGFzcyhjbGVhclRpbWVvdXQpXG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtUaW1lb3V0T2JqZWN0fVxuICovXG5leHBvcnQgY29uc3QgdGltZW91dCA9ICh0aW1lb3V0LCBjYWxsYmFjaykgPT4gbmV3IFRpbWVvdXQoc2V0VGltZW91dChjYWxsYmFjaywgdGltZW91dCkpXG5cbmNvbnN0IEludGVydmFsID0gY3JlYXRlVGltZW91dENsYXNzKGNsZWFySW50ZXJ2YWwpXG5cbi8qKlxuICogQHBhcmFtIHtudW1iZXJ9IHRpbWVvdXRcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJuIHtUaW1lb3V0T2JqZWN0fVxuICovXG5leHBvcnQgY29uc3QgaW50ZXJ2YWwgPSAodGltZW91dCwgY2FsbGJhY2spID0+IG5ldyBJbnRlcnZhbChzZXRJbnRlcnZhbChjYWxsYmFjaywgdGltZW91dCkpXG5cbi8qIGM4IGlnbm9yZSBuZXh0ICovXG5leHBvcnQgY29uc3QgQW5pbWF0aW9uID0gY3JlYXRlVGltZW91dENsYXNzKGFyZyA9PiB0eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lICE9PSAndW5kZWZpbmVkJyAmJiBjYW5jZWxBbmltYXRpb25GcmFtZShhcmcpKVxuXG4vKipcbiAqIEBwYXJhbSB7ZnVuY3Rpb24obnVtYmVyKTp2b2lkfSBjYlxuICogQHJldHVybiB7VGltZW91dE9iamVjdH1cbiAqL1xuLyogYzggaWdub3JlIG5leHQgKi9cbmV4cG9ydCBjb25zdCBhbmltYXRpb25GcmFtZSA9IGNiID0+IHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPT09ICd1bmRlZmluZWQnID8gdGltZW91dCgwLCBjYikgOiBuZXcgQW5pbWF0aW9uKHJlcXVlc3RBbmltYXRpb25GcmFtZShjYikpXG5cbi8qIGM4IGlnbm9yZSBuZXh0ICovXG4vLyBAdHMtaWdub3JlXG5jb25zdCBJZGxlID0gY3JlYXRlVGltZW91dENsYXNzKGFyZyA9PiB0eXBlb2YgY2FuY2VsSWRsZUNhbGxiYWNrICE9PSAndW5kZWZpbmVkJyAmJiBjYW5jZWxJZGxlQ2FsbGJhY2soYXJnKSlcblxuLyoqXG4gKiBOb3RlOiB0aGlzIGlzIGV4cGVyaW1lbnRhbCBhbmQgaXMgcHJvYmFibHkgb25seSB1c2VmdWwgaW4gYnJvd3NlcnMuXG4gKlxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2JcbiAqIEByZXR1cm4ge1RpbWVvdXRPYmplY3R9XG4gKi9cbi8qIGM4IGlnbm9yZSBuZXh0IDIgKi9cbi8vIEB0cy1pZ25vcmVcbmV4cG9ydCBjb25zdCBpZGxlQ2FsbGJhY2sgPSBjYiA9PiB0eXBlb2YgcmVxdWVzdElkbGVDYWxsYmFjayAhPT0gJ3VuZGVmaW5lZCcgPyBuZXcgSWRsZShyZXF1ZXN0SWRsZUNhbGxiYWNrKGNiKSkgOiB0aW1lb3V0KDEwMDAsIGNiKVxuXG4vKipcbiAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lb3V0IFRpbWVvdXQgb2YgdGhlIGRlYm91bmNlIGFjdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHRyaWdnZXJBZnRlciBPcHRpb25hbC4gVHJpZ2dlciBjYWxsYmFjayBhZnRlciBhIGNlcnRhaW4gYW1vdW50IG9mIHRpbWVcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2l0aG91dCB3YWl0aW5nIGZvciBkZWJvdW5jZS5cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZURlYm91bmNlciA9ICh0aW1lb3V0LCB0cmlnZ2VyQWZ0ZXIgPSAtMSkgPT4ge1xuICBsZXQgdGltZXIgPSAtMVxuICAvKipcbiAgICogQHR5cGUge251bWJlcj99XG4gICAgKi9cbiAgbGV0IGxhc3RDYWxsID0gbnVsbFxuICAvKipcbiAgICogQHBhcmFtIHsoKC4uLmFyZ3M6IGFueSk9PnZvaWQpP30gY2IgZnVuY3Rpb24gdG8gdHJpZ2dlciBhZnRlciBkZWJvdW5jZS4gSWYgbnVsbCwgaXQgd2lsbCByZXNldCB0aGVcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgZGVib3VuY2UuXG4gICAqL1xuICByZXR1cm4gY2IgPT4ge1xuICAgIGNsZWFyVGltZW91dCh0aW1lcilcbiAgICBpZiAoY2IpIHtcbiAgICAgIGlmICh0cmlnZ2VyQWZ0ZXIgPj0gMCkge1xuICAgICAgICBjb25zdCBub3cgPSB0aW1lLmdldFVuaXhUaW1lKClcbiAgICAgICAgaWYgKGxhc3RDYWxsID09PSBudWxsKSBsYXN0Q2FsbCA9IG5vd1xuICAgICAgICBpZiAobm93IC0gbGFzdENhbGwgPiB0cmlnZ2VyQWZ0ZXIpIHtcbiAgICAgICAgICBsYXN0Q2FsbCA9IG51bGxcbiAgICAgICAgICB0aW1lciA9IC8qKiBAdHlwZSB7YW55fSAqLyAoc2V0VGltZW91dChjYiwgMCkpXG4gICAgICAgICAgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRpbWVyID0gLyoqIEB0eXBlIHthbnl9ICovIChzZXRUaW1lb3V0KCgpID0+IHsgbGFzdENhbGwgPSBudWxsOyBjYigpIH0sIHRpbWVvdXQpKVxuICAgIH0gZWxzZSB7XG4gICAgICBsYXN0Q2FsbCA9IG51bGxcbiAgICB9XG4gIH1cbn1cbiIsICIvKipcbiAqIFV0aWxpdHkgbW9kdWxlIHRvIHdvcmsgd2l0aCBFY21hU2NyaXB0IFN5bWJvbHMuXG4gKlxuICogQG1vZHVsZSBzeW1ib2xcbiAqL1xuXG4vKipcbiAqIFJldHVybiBmcmVzaCBzeW1ib2wuXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGUgPSBTeW1ib2xcblxuLyoqXG4gKiBAcGFyYW0ge2FueX0gc1xuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGNvbnN0IGlzU3ltYm9sID0gcyA9PiB0eXBlb2YgcyA9PT0gJ3N5bWJvbCdcbiIsICJpbXBvcnQgKiBhcyBzeW1ib2wgZnJvbSAnLi9zeW1ib2wuanMnXG5pbXBvcnQgKiBhcyB0aW1lIGZyb20gJy4vdGltZS5qcydcbmltcG9ydCAqIGFzIGVudiBmcm9tICcuL2Vudmlyb25tZW50LmpzJ1xuaW1wb3J0ICogYXMgZnVuYyBmcm9tICcuL2Z1bmN0aW9uLmpzJ1xuaW1wb3J0ICogYXMganNvbiBmcm9tICcuL2pzb24uanMnXG5cbmV4cG9ydCBjb25zdCBCT0xEID0gc3ltYm9sLmNyZWF0ZSgpXG5leHBvcnQgY29uc3QgVU5CT0xEID0gc3ltYm9sLmNyZWF0ZSgpXG5leHBvcnQgY29uc3QgQkxVRSA9IHN5bWJvbC5jcmVhdGUoKVxuZXhwb3J0IGNvbnN0IEdSRVkgPSBzeW1ib2wuY3JlYXRlKClcbmV4cG9ydCBjb25zdCBHUkVFTiA9IHN5bWJvbC5jcmVhdGUoKVxuZXhwb3J0IGNvbnN0IFJFRCA9IHN5bWJvbC5jcmVhdGUoKVxuZXhwb3J0IGNvbnN0IFBVUlBMRSA9IHN5bWJvbC5jcmVhdGUoKVxuZXhwb3J0IGNvbnN0IE9SQU5HRSA9IHN5bWJvbC5jcmVhdGUoKVxuZXhwb3J0IGNvbnN0IFVOQ09MT1IgPSBzeW1ib2wuY3JlYXRlKClcblxuLyogYzggaWdub3JlIHN0YXJ0ICovXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8dW5kZWZpbmVkfHN0cmluZ3xTeW1ib2x8T2JqZWN0fG51bWJlcnxmdW5jdGlvbigpOmFueT59IGFyZ3NcbiAqIEByZXR1cm4ge0FycmF5PHN0cmluZ3xvYmplY3R8bnVtYmVyfHVuZGVmaW5lZD59XG4gKi9cbmV4cG9ydCBjb25zdCBjb21wdXRlTm9Db2xvckxvZ2dpbmdBcmdzID0gYXJncyA9PiB7XG4gIGlmIChhcmdzLmxlbmd0aCA9PT0gMSAmJiBhcmdzWzBdPy5jb25zdHJ1Y3RvciA9PT0gRnVuY3Rpb24pIHtcbiAgICBhcmdzID0gLyoqIEB0eXBlIHtBcnJheTxzdHJpbmd8U3ltYm9sfE9iamVjdHxudW1iZXI+fSAqLyAoLyoqIEB0eXBlIHtbZnVuY3Rpb25dfSAqLyAoYXJncylbMF0oKSlcbiAgfVxuICBjb25zdCBzdHJCdWlsZGVyID0gW11cbiAgY29uc3QgbG9nQXJncyA9IFtdXG4gIC8vIHRyeSB3aXRoIGZvcm1hdHRpbmcgdW50aWwgd2UgZmluZCBzb21ldGhpbmcgdW5zdXBwb3J0ZWRcbiAgbGV0IGkgPSAwXG4gIGZvciAoOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGFyZyA9IGFyZ3NbaV1cbiAgICBpZiAoYXJnID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGJyZWFrXG4gICAgfSBlbHNlIGlmIChhcmcuY29uc3RydWN0b3IgPT09IFN0cmluZyB8fCBhcmcuY29uc3RydWN0b3IgPT09IE51bWJlcikge1xuICAgICAgc3RyQnVpbGRlci5wdXNoKGFyZylcbiAgICB9IGVsc2UgaWYgKGFyZy5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0KSB7XG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuICBpZiAoaSA+IDApIHtcbiAgICAvLyBjcmVhdGUgbG9nQXJncyB3aXRoIHdoYXQgd2UgaGF2ZSBzbyBmYXJcbiAgICBsb2dBcmdzLnB1c2goc3RyQnVpbGRlci5qb2luKCcnKSlcbiAgfVxuICAvLyBhcHBlbmQgdGhlIHJlc3RcbiAgZm9yICg7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgYXJnID0gYXJnc1tpXVxuICAgIGlmICghKGFyZyBpbnN0YW5jZW9mIFN5bWJvbCkpIHtcbiAgICAgIGxvZ0FyZ3MucHVzaChhcmcpXG4gICAgfVxuICB9XG4gIHJldHVybiBsb2dBcmdzXG59XG4vKiBjOCBpZ25vcmUgc3RvcCAqL1xuXG5jb25zdCBsb2dnaW5nQ29sb3JzID0gW0dSRUVOLCBQVVJQTEUsIE9SQU5HRSwgQkxVRV1cbmxldCBuZXh0Q29sb3IgPSAwXG5sZXQgbGFzdExvZ2dpbmdUaW1lID0gdGltZS5nZXRVbml4VGltZSgpXG5cbi8qIGM4IGlnbm9yZSBzdGFydCAqL1xuLyoqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKC4uLmFueSk6dm9pZH0gX3ByaW50XG4gKiBAcGFyYW0ge3N0cmluZ30gbW9kdWxlTmFtZVxuICogQHJldHVybiB7ZnVuY3Rpb24oLi4uYW55KTp2b2lkfVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlTW9kdWxlTG9nZ2VyID0gKF9wcmludCwgbW9kdWxlTmFtZSkgPT4ge1xuICBjb25zdCBjb2xvciA9IGxvZ2dpbmdDb2xvcnNbbmV4dENvbG9yXVxuICBjb25zdCBkZWJ1Z1JlZ2V4VmFyID0gZW52LmdldFZhcmlhYmxlKCdsb2cnKVxuICBjb25zdCBkb0xvZ2dpbmcgPSBkZWJ1Z1JlZ2V4VmFyICE9PSBudWxsICYmXG4gICAgKGRlYnVnUmVnZXhWYXIgPT09ICcqJyB8fCBkZWJ1Z1JlZ2V4VmFyID09PSAndHJ1ZScgfHxcbiAgICAgIG5ldyBSZWdFeHAoZGVidWdSZWdleFZhciwgJ2dpJykudGVzdChtb2R1bGVOYW1lKSlcbiAgbmV4dENvbG9yID0gKG5leHRDb2xvciArIDEpICUgbG9nZ2luZ0NvbG9ycy5sZW5ndGhcbiAgbW9kdWxlTmFtZSArPSAnOiAnXG4gIHJldHVybiAhZG9Mb2dnaW5nXG4gICAgPyBmdW5jLm5vcFxuICAgIDogKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgaWYgKGFyZ3MubGVuZ3RoID09PSAxICYmIGFyZ3NbMF0/LmNvbnN0cnVjdG9yID09PSBGdW5jdGlvbikge1xuICAgICAgICAgIGFyZ3MgPSBhcmdzWzBdKClcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0aW1lTm93ID0gdGltZS5nZXRVbml4VGltZSgpXG4gICAgICAgIGNvbnN0IHRpbWVEaWZmID0gdGltZU5vdyAtIGxhc3RMb2dnaW5nVGltZVxuICAgICAgICBsYXN0TG9nZ2luZ1RpbWUgPSB0aW1lTm93XG4gICAgICAgIF9wcmludChcbiAgICAgICAgICBjb2xvcixcbiAgICAgICAgICBtb2R1bGVOYW1lLFxuICAgICAgICAgIFVOQ09MT1IsXG4gICAgICAgICAgLi4uYXJncy5tYXAoKGFyZykgPT4ge1xuICAgICAgICAgICAgaWYgKGFyZyAhPSBudWxsICYmIGFyZy5jb25zdHJ1Y3RvciA9PT0gVWludDhBcnJheSkge1xuICAgICAgICAgICAgICBhcmcgPSBBcnJheS5mcm9tKGFyZylcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHQgPSB0eXBlb2YgYXJnXG4gICAgICAgICAgICBzd2l0Y2ggKHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgICAgICAgICAgY2FzZSAnc3ltYm9sJzpcbiAgICAgICAgICAgICAgICByZXR1cm4gYXJnXG4gICAgICAgICAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgICAgICAgICByZXR1cm4ganNvbi5zdHJpbmdpZnkoYXJnKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICAgY29sb3IsXG4gICAgICAgICAgJyArJyArIHRpbWVEaWZmICsgJ21zJ1xuICAgICAgICApXG4gICAgICB9XG59XG4vKiBjOCBpZ25vcmUgc3RvcCAqL1xuIiwgIi8qKlxuICogSXNvbW9ycGhpYyBsb2dnaW5nIG1vZHVsZSB3aXRoIHN1cHBvcnQgZm9yIGNvbG9ycyFcbiAqXG4gKiBAbW9kdWxlIGxvZ2dpbmdcbiAqL1xuXG5pbXBvcnQgKiBhcyBlbnYgZnJvbSAnLi9lbnZpcm9ubWVudC5qcydcbmltcG9ydCAqIGFzIHNldCBmcm9tICcuL3NldC5qcydcbmltcG9ydCAqIGFzIHBhaXIgZnJvbSAnLi9wYWlyLmpzJ1xuaW1wb3J0ICogYXMgZG9tIGZyb20gJy4vZG9tLmpzJ1xuaW1wb3J0ICogYXMganNvbiBmcm9tICcuL2pzb24uanMnXG5pbXBvcnQgKiBhcyBtYXAgZnJvbSAnLi9tYXAuanMnXG5pbXBvcnQgKiBhcyBldmVudGxvb3AgZnJvbSAnLi9ldmVudGxvb3AuanMnXG5pbXBvcnQgKiBhcyBtYXRoIGZyb20gJy4vbWF0aC5qcydcbmltcG9ydCAqIGFzIGNvbW1vbiBmcm9tICcuL2xvZ2dpbmcuY29tbW9uLmpzJ1xuXG5leHBvcnQgeyBCT0xELCBVTkJPTEQsIEJMVUUsIEdSRVksIEdSRUVOLCBSRUQsIFBVUlBMRSwgT1JBTkdFLCBVTkNPTE9SIH0gZnJvbSAnLi9sb2dnaW5nLmNvbW1vbi5qcydcblxuLyoqXG4gKiBAdHlwZSB7T2JqZWN0PFN5bWJvbCxwYWlyLlBhaXI8c3RyaW5nLHN0cmluZz4+fVxuICovXG5jb25zdCBfYnJvd3NlclN0eWxlTWFwID0ge1xuICBbY29tbW9uLkJPTERdOiBwYWlyLmNyZWF0ZSgnZm9udC13ZWlnaHQnLCAnYm9sZCcpLFxuICBbY29tbW9uLlVOQk9MRF06IHBhaXIuY3JlYXRlKCdmb250LXdlaWdodCcsICdub3JtYWwnKSxcbiAgW2NvbW1vbi5CTFVFXTogcGFpci5jcmVhdGUoJ2NvbG9yJywgJ2JsdWUnKSxcbiAgW2NvbW1vbi5HUkVFTl06IHBhaXIuY3JlYXRlKCdjb2xvcicsICdncmVlbicpLFxuICBbY29tbW9uLkdSRVldOiBwYWlyLmNyZWF0ZSgnY29sb3InLCAnZ3JleScpLFxuICBbY29tbW9uLlJFRF06IHBhaXIuY3JlYXRlKCdjb2xvcicsICdyZWQnKSxcbiAgW2NvbW1vbi5QVVJQTEVdOiBwYWlyLmNyZWF0ZSgnY29sb3InLCAncHVycGxlJyksXG4gIFtjb21tb24uT1JBTkdFXTogcGFpci5jcmVhdGUoJ2NvbG9yJywgJ29yYW5nZScpLCAvLyBub3Qgd2VsbCBzdXBwb3J0ZWQgaW4gY2hyb21lIHdoZW4gZGVidWdnaW5nIG5vZGUgd2l0aCBpbnNwZWN0b3IgLSBUT0RPOiBkZXByZWNhdGVcbiAgW2NvbW1vbi5VTkNPTE9SXTogcGFpci5jcmVhdGUoJ2NvbG9yJywgJ2JsYWNrJylcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZ3xTeW1ib2x8T2JqZWN0fG51bWJlcnxmdW5jdGlvbigpOmFueT59IGFyZ3NcbiAqIEByZXR1cm4ge0FycmF5PHN0cmluZ3xvYmplY3R8bnVtYmVyPn1cbiAqL1xuLyogYzggaWdub3JlIHN0YXJ0ICovXG5jb25zdCBjb21wdXRlQnJvd3NlckxvZ2dpbmdBcmdzID0gKGFyZ3MpID0+IHtcbiAgaWYgKGFyZ3MubGVuZ3RoID09PSAxICYmIGFyZ3NbMF0/LmNvbnN0cnVjdG9yID09PSBGdW5jdGlvbikge1xuICAgIGFyZ3MgPSAvKiogQHR5cGUge0FycmF5PHN0cmluZ3xTeW1ib2x8T2JqZWN0fG51bWJlcj59ICovICgvKiogQHR5cGUge1tmdW5jdGlvbl19ICovIChhcmdzKVswXSgpKVxuICB9XG4gIGNvbnN0IHN0ckJ1aWxkZXIgPSBbXVxuICBjb25zdCBzdHlsZXMgPSBbXVxuICBjb25zdCBjdXJyZW50U3R5bGUgPSBtYXAuY3JlYXRlKClcbiAgLyoqXG4gICAqIEB0eXBlIHtBcnJheTxzdHJpbmd8T2JqZWN0fG51bWJlcj59XG4gICAqL1xuICBsZXQgbG9nQXJncyA9IFtdXG4gIC8vIHRyeSB3aXRoIGZvcm1hdHRpbmcgdW50aWwgd2UgZmluZCBzb21ldGhpbmcgdW5zdXBwb3J0ZWRcbiAgbGV0IGkgPSAwXG4gIGZvciAoOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGFyZyA9IGFyZ3NbaV1cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgY29uc3Qgc3R5bGUgPSBfYnJvd3NlclN0eWxlTWFwW2FyZ11cbiAgICBpZiAoc3R5bGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY3VycmVudFN0eWxlLnNldChzdHlsZS5sZWZ0LCBzdHlsZS5yaWdodClcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGFyZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICBpZiAoYXJnLmNvbnN0cnVjdG9yID09PSBTdHJpbmcgfHwgYXJnLmNvbnN0cnVjdG9yID09PSBOdW1iZXIpIHtcbiAgICAgICAgY29uc3Qgc3R5bGUgPSBkb20ubWFwVG9TdHlsZVN0cmluZyhjdXJyZW50U3R5bGUpXG4gICAgICAgIGlmIChpID4gMCB8fCBzdHlsZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgc3RyQnVpbGRlci5wdXNoKCclYycgKyBhcmcpXG4gICAgICAgICAgc3R5bGVzLnB1c2goc3R5bGUpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyQnVpbGRlci5wdXNoKGFyZylcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKGkgPiAwKSB7XG4gICAgLy8gY3JlYXRlIGxvZ0FyZ3Mgd2l0aCB3aGF0IHdlIGhhdmUgc28gZmFyXG4gICAgbG9nQXJncyA9IHN0eWxlc1xuICAgIGxvZ0FyZ3MudW5zaGlmdChzdHJCdWlsZGVyLmpvaW4oJycpKVxuICB9XG4gIC8vIGFwcGVuZCB0aGUgcmVzdFxuICBmb3IgKDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBhcmcgPSBhcmdzW2ldXG4gICAgaWYgKCEoYXJnIGluc3RhbmNlb2YgU3ltYm9sKSkge1xuICAgICAgbG9nQXJncy5wdXNoKGFyZylcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGxvZ0FyZ3Ncbn1cbi8qIGM4IGlnbm9yZSBzdG9wICovXG5cbi8qIGM4IGlnbm9yZSBzdGFydCAqL1xuY29uc3QgY29tcHV0ZUxvZ2dpbmdBcmdzID0gZW52LnN1cHBvcnRzQ29sb3JcbiAgPyBjb21wdXRlQnJvd3NlckxvZ2dpbmdBcmdzXG4gIDogY29tbW9uLmNvbXB1dGVOb0NvbG9yTG9nZ2luZ0FyZ3Ncbi8qIGM4IGlnbm9yZSBzdG9wICovXG5cbi8qKlxuICogQHBhcmFtIHtBcnJheTxzdHJpbmd8U3ltYm9sfE9iamVjdHxudW1iZXI+fSBhcmdzXG4gKi9cbmV4cG9ydCBjb25zdCBwcmludCA9ICguLi5hcmdzKSA9PiB7XG4gIGNvbnNvbGUubG9nKC4uLmNvbXB1dGVMb2dnaW5nQXJncyhhcmdzKSlcbiAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgdmNvbnNvbGVzLmZvckVhY2goKHZjKSA9PiB2Yy5wcmludChhcmdzKSlcbn1cblxuLyogYzggaWdub3JlIHN0YXJ0ICovXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nfFN5bWJvbHxPYmplY3R8bnVtYmVyPn0gYXJnc1xuICovXG5leHBvcnQgY29uc3Qgd2FybiA9ICguLi5hcmdzKSA9PiB7XG4gIGNvbnNvbGUud2FybiguLi5jb21wdXRlTG9nZ2luZ0FyZ3MoYXJncykpXG4gIGFyZ3MudW5zaGlmdChjb21tb24uT1JBTkdFKVxuICB2Y29uc29sZXMuZm9yRWFjaCgodmMpID0+IHZjLnByaW50KGFyZ3MpKVxufVxuLyogYzggaWdub3JlIHN0b3AgKi9cblxuLyoqXG4gKiBAcGFyYW0ge0Vycm9yfSBlcnJcbiAqL1xuLyogYzggaWdub3JlIHN0YXJ0ICovXG5leHBvcnQgY29uc3QgcHJpbnRFcnJvciA9IChlcnIpID0+IHtcbiAgY29uc29sZS5lcnJvcihlcnIpXG4gIHZjb25zb2xlcy5mb3JFYWNoKCh2YykgPT4gdmMucHJpbnRFcnJvcihlcnIpKVxufVxuLyogYzggaWdub3JlIHN0b3AgKi9cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gdXJsIGltYWdlIGxvY2F0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IGhlaWdodCBvZiB0aGUgaW1hZ2UgaW4gcGl4ZWxcbiAqL1xuLyogYzggaWdub3JlIHN0YXJ0ICovXG5leHBvcnQgY29uc3QgcHJpbnRJbWcgPSAodXJsLCBoZWlnaHQpID0+IHtcbiAgaWYgKGVudi5pc0Jyb3dzZXIpIHtcbiAgICBjb25zb2xlLmxvZyhcbiAgICAgICclYyAgICAgICAgICAgICAgICAgICAgICAnLFxuICAgICAgYGZvbnQtc2l6ZTogJHtoZWlnaHR9cHg7IGJhY2tncm91bmQtc2l6ZTogY29udGFpbjsgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDsgYmFja2dyb3VuZC1pbWFnZTogdXJsKCR7dXJsfSlgXG4gICAgKVxuICAgIC8vIGNvbnNvbGUubG9nKCclYyAgICAgICAgICAgICAgICAnLCBgZm9udC1zaXplOiAke2hlaWdodH14OyBiYWNrZ3JvdW5kOiB1cmwoJHt1cmx9KSBuby1yZXBlYXQ7YClcbiAgfVxuICB2Y29uc29sZXMuZm9yRWFjaCgodmMpID0+IHZjLnByaW50SW1nKHVybCwgaGVpZ2h0KSlcbn1cbi8qIGM4IGlnbm9yZSBzdG9wICovXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGJhc2U2NFxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxuICovXG4vKiBjOCBpZ25vcmUgbmV4dCAyICovXG5leHBvcnQgY29uc3QgcHJpbnRJbWdCYXNlNjQgPSAoYmFzZTY0LCBoZWlnaHQpID0+XG4gIHByaW50SW1nKGBkYXRhOmltYWdlL2dpZjtiYXNlNjQsJHtiYXNlNjR9YCwgaGVpZ2h0KVxuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nfFN5bWJvbHxPYmplY3R8bnVtYmVyPn0gYXJnc1xuICovXG5leHBvcnQgY29uc3QgZ3JvdXAgPSAoLi4uYXJncykgPT4ge1xuICBjb25zb2xlLmdyb3VwKC4uLmNvbXB1dGVMb2dnaW5nQXJncyhhcmdzKSlcbiAgLyogYzggaWdub3JlIG5leHQgKi9cbiAgdmNvbnNvbGVzLmZvckVhY2goKHZjKSA9PiB2Yy5ncm91cChhcmdzKSlcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZ3xTeW1ib2x8T2JqZWN0fG51bWJlcj59IGFyZ3NcbiAqL1xuZXhwb3J0IGNvbnN0IGdyb3VwQ29sbGFwc2VkID0gKC4uLmFyZ3MpID0+IHtcbiAgY29uc29sZS5ncm91cENvbGxhcHNlZCguLi5jb21wdXRlTG9nZ2luZ0FyZ3MoYXJncykpXG4gIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gIHZjb25zb2xlcy5mb3JFYWNoKCh2YykgPT4gdmMuZ3JvdXBDb2xsYXBzZWQoYXJncykpXG59XG5cbmV4cG9ydCBjb25zdCBncm91cEVuZCA9ICgpID0+IHtcbiAgY29uc29sZS5ncm91cEVuZCgpXG4gIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gIHZjb25zb2xlcy5mb3JFYWNoKCh2YykgPT4gdmMuZ3JvdXBFbmQoKSlcbn1cblxuLyoqXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCk6Tm9kZX0gY3JlYXRlTm9kZVxuICovXG4vKiBjOCBpZ25vcmUgbmV4dCAyICovXG5leHBvcnQgY29uc3QgcHJpbnREb20gPSAoY3JlYXRlTm9kZSkgPT5cbiAgdmNvbnNvbGVzLmZvckVhY2goKHZjKSA9PiB2Yy5wcmludERvbShjcmVhdGVOb2RlKCkpKVxuXG4vKipcbiAqIEBwYXJhbSB7SFRNTENhbnZhc0VsZW1lbnR9IGNhbnZhc1xuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxuICovXG4vKiBjOCBpZ25vcmUgbmV4dCAyICovXG5leHBvcnQgY29uc3QgcHJpbnRDYW52YXMgPSAoY2FudmFzLCBoZWlnaHQpID0+XG4gIHByaW50SW1nKGNhbnZhcy50b0RhdGFVUkwoKSwgaGVpZ2h0KVxuXG5leHBvcnQgY29uc3QgdmNvbnNvbGVzID0gc2V0LmNyZWF0ZSgpXG5cbi8qKlxuICogQHBhcmFtIHtBcnJheTxzdHJpbmd8U3ltYm9sfE9iamVjdHxudW1iZXI+fSBhcmdzXG4gKiBAcmV0dXJuIHtBcnJheTxFbGVtZW50Pn1cbiAqL1xuLyogYzggaWdub3JlIHN0YXJ0ICovXG5jb25zdCBfY29tcHV0ZUxpbmVTcGFucyA9IChhcmdzKSA9PiB7XG4gIGNvbnN0IHNwYW5zID0gW11cbiAgY29uc3QgY3VycmVudFN0eWxlID0gbmV3IE1hcCgpXG4gIC8vIHRyeSB3aXRoIGZvcm1hdHRpbmcgdW50aWwgd2UgZmluZCBzb21ldGhpbmcgdW5zdXBwb3J0ZWRcbiAgbGV0IGkgPSAwXG4gIGZvciAoOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgIGxldCBhcmcgPSBhcmdzW2ldXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IHN0eWxlID0gX2Jyb3dzZXJTdHlsZU1hcFthcmddXG4gICAgaWYgKHN0eWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGN1cnJlbnRTdHlsZS5zZXQoc3R5bGUubGVmdCwgc3R5bGUucmlnaHQpXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChhcmcgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhcmcgPSAndW5kZWZpbmVkICdcbiAgICAgIH1cbiAgICAgIGlmIChhcmcuY29uc3RydWN0b3IgPT09IFN0cmluZyB8fCBhcmcuY29uc3RydWN0b3IgPT09IE51bWJlcikge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGNvbnN0IHNwYW4gPSBkb20uZWxlbWVudCgnc3BhbicsIFtcbiAgICAgICAgICBwYWlyLmNyZWF0ZSgnc3R5bGUnLCBkb20ubWFwVG9TdHlsZVN0cmluZyhjdXJyZW50U3R5bGUpKVxuICAgICAgICBdLCBbZG9tLnRleHQoYXJnLnRvU3RyaW5nKCkpXSlcbiAgICAgICAgaWYgKHNwYW4uaW5uZXJIVE1MID09PSAnJykge1xuICAgICAgICAgIHNwYW4uaW5uZXJIVE1MID0gJyZuYnNwOydcbiAgICAgICAgfVxuICAgICAgICBzcGFucy5wdXNoKHNwYW4pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgfVxuICAvLyBhcHBlbmQgdGhlIHJlc3RcbiAgZm9yICg7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7XG4gICAgbGV0IGNvbnRlbnQgPSBhcmdzW2ldXG4gICAgaWYgKCEoY29udGVudCBpbnN0YW5jZW9mIFN5bWJvbCkpIHtcbiAgICAgIGlmIChjb250ZW50LmNvbnN0cnVjdG9yICE9PSBTdHJpbmcgJiYgY29udGVudC5jb25zdHJ1Y3RvciAhPT0gTnVtYmVyKSB7XG4gICAgICAgIGNvbnRlbnQgPSAnICcgKyBqc29uLnN0cmluZ2lmeShjb250ZW50KSArICcgJ1xuICAgICAgfVxuICAgICAgc3BhbnMucHVzaChcbiAgICAgICAgZG9tLmVsZW1lbnQoJ3NwYW4nLCBbXSwgW2RvbS50ZXh0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoY29udGVudCkpXSlcbiAgICAgIClcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHNwYW5zXG59XG4vKiBjOCBpZ25vcmUgc3RvcCAqL1xuXG5jb25zdCBsaW5lU3R5bGUgPVxuICAnZm9udC1mYW1pbHk6bW9ub3NwYWNlO2JvcmRlci1ib3R0b206MXB4IHNvbGlkICNlMmUyZTI7cGFkZGluZzoycHg7J1xuXG4vKiBjOCBpZ25vcmUgc3RhcnQgKi9cbmV4cG9ydCBjbGFzcyBWQ29uc29sZSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VsZW1lbnR9IGRvbVxuICAgKi9cbiAgY29uc3RydWN0b3IgKGRvbSkge1xuICAgIHRoaXMuZG9tID0gZG9tXG4gICAgLyoqXG4gICAgICogQHR5cGUge0VsZW1lbnR9XG4gICAgICovXG4gICAgdGhpcy5jY29udGFpbmVyID0gdGhpcy5kb21cbiAgICB0aGlzLmRlcHRoID0gMFxuICAgIHZjb25zb2xlcy5hZGQodGhpcylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PHN0cmluZ3xTeW1ib2x8T2JqZWN0fG51bWJlcj59IGFyZ3NcbiAgICogQHBhcmFtIHtib29sZWFufSBjb2xsYXBzZWRcbiAgICovXG4gIGdyb3VwIChhcmdzLCBjb2xsYXBzZWQgPSBmYWxzZSkge1xuICAgIGV2ZW50bG9vcC5lbnF1ZXVlKCgpID0+IHtcbiAgICAgIGNvbnN0IHRyaWFuZ2xlRG93biA9IGRvbS5lbGVtZW50KCdzcGFuJywgW1xuICAgICAgICBwYWlyLmNyZWF0ZSgnaGlkZGVuJywgY29sbGFwc2VkKSxcbiAgICAgICAgcGFpci5jcmVhdGUoJ3N0eWxlJywgJ2NvbG9yOmdyZXk7Zm9udC1zaXplOjEyMCU7JylcbiAgICAgIF0sIFtkb20udGV4dCgnXHUyNUJDJyldKVxuICAgICAgY29uc3QgdHJpYW5nbGVSaWdodCA9IGRvbS5lbGVtZW50KCdzcGFuJywgW1xuICAgICAgICBwYWlyLmNyZWF0ZSgnaGlkZGVuJywgIWNvbGxhcHNlZCksXG4gICAgICAgIHBhaXIuY3JlYXRlKCdzdHlsZScsICdjb2xvcjpncmV5O2ZvbnQtc2l6ZToxMjUlOycpXG4gICAgICBdLCBbZG9tLnRleHQoJ1x1MjVCNicpXSlcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBkb20uZWxlbWVudChcbiAgICAgICAgJ2RpdicsXG4gICAgICAgIFtwYWlyLmNyZWF0ZShcbiAgICAgICAgICAnc3R5bGUnLFxuICAgICAgICAgIGAke2xpbmVTdHlsZX07cGFkZGluZy1sZWZ0OiR7dGhpcy5kZXB0aCAqIDEwfXB4YFxuICAgICAgICApXSxcbiAgICAgICAgW3RyaWFuZ2xlRG93biwgdHJpYW5nbGVSaWdodCwgZG9tLnRleHQoJyAnKV0uY29uY2F0KFxuICAgICAgICAgIF9jb21wdXRlTGluZVNwYW5zKGFyZ3MpXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIGNvbnN0IG5leHRDb250YWluZXIgPSBkb20uZWxlbWVudCgnZGl2JywgW1xuICAgICAgICBwYWlyLmNyZWF0ZSgnaGlkZGVuJywgY29sbGFwc2VkKVxuICAgICAgXSlcbiAgICAgIGNvbnN0IG5leHRMaW5lID0gZG9tLmVsZW1lbnQoJ2RpdicsIFtdLCBbY29udGVudCwgbmV4dENvbnRhaW5lcl0pXG4gICAgICBkb20uYXBwZW5kKHRoaXMuY2NvbnRhaW5lciwgW25leHRMaW5lXSlcbiAgICAgIHRoaXMuY2NvbnRhaW5lciA9IG5leHRDb250YWluZXJcbiAgICAgIHRoaXMuZGVwdGgrK1xuICAgICAgLy8gd2hlbiBoZWFkZXIgaXMgY2xpY2tlZCwgY29sbGFwc2UvdW5jb2xsYXBzZSBjb250YWluZXJcbiAgICAgIGRvbS5hZGRFdmVudExpc3RlbmVyKGNvbnRlbnQsICdjbGljaycsIChfZXZlbnQpID0+IHtcbiAgICAgICAgbmV4dENvbnRhaW5lci50b2dnbGVBdHRyaWJ1dGUoJ2hpZGRlbicpXG4gICAgICAgIHRyaWFuZ2xlRG93bi50b2dnbGVBdHRyaWJ1dGUoJ2hpZGRlbicpXG4gICAgICAgIHRyaWFuZ2xlUmlnaHQudG9nZ2xlQXR0cmlidXRlKCdoaWRkZW4nKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nfFN5bWJvbHxPYmplY3R8bnVtYmVyPn0gYXJnc1xuICAgKi9cbiAgZ3JvdXBDb2xsYXBzZWQgKGFyZ3MpIHtcbiAgICB0aGlzLmdyb3VwKGFyZ3MsIHRydWUpXG4gIH1cblxuICBncm91cEVuZCAoKSB7XG4gICAgZXZlbnRsb29wLmVucXVldWUoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuZGVwdGggPiAwKSB7XG4gICAgICAgIHRoaXMuZGVwdGgtLVxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHRoaXMuY2NvbnRhaW5lciA9IHRoaXMuY2NvbnRhaW5lci5wYXJlbnRFbGVtZW50LnBhcmVudEVsZW1lbnRcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nfFN5bWJvbHxPYmplY3R8bnVtYmVyPn0gYXJnc1xuICAgKi9cbiAgcHJpbnQgKGFyZ3MpIHtcbiAgICBldmVudGxvb3AuZW5xdWV1ZSgoKSA9PiB7XG4gICAgICBkb20uYXBwZW5kKHRoaXMuY2NvbnRhaW5lciwgW1xuICAgICAgICBkb20uZWxlbWVudCgnZGl2JywgW1xuICAgICAgICAgIHBhaXIuY3JlYXRlKFxuICAgICAgICAgICAgJ3N0eWxlJyxcbiAgICAgICAgICAgIGAke2xpbmVTdHlsZX07cGFkZGluZy1sZWZ0OiR7dGhpcy5kZXB0aCAqIDEwfXB4YFxuICAgICAgICAgIClcbiAgICAgICAgXSwgX2NvbXB1dGVMaW5lU3BhbnMoYXJncykpXG4gICAgICBdKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtFcnJvcn0gZXJyXG4gICAqL1xuICBwcmludEVycm9yIChlcnIpIHtcbiAgICB0aGlzLnByaW50KFtjb21tb24uUkVELCBjb21tb24uQk9MRCwgZXJyLnRvU3RyaW5nKCldKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1cmxcbiAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxuICAgKi9cbiAgcHJpbnRJbWcgKHVybCwgaGVpZ2h0KSB7XG4gICAgZXZlbnRsb29wLmVucXVldWUoKCkgPT4ge1xuICAgICAgZG9tLmFwcGVuZCh0aGlzLmNjb250YWluZXIsIFtcbiAgICAgICAgZG9tLmVsZW1lbnQoJ2ltZycsIFtcbiAgICAgICAgICBwYWlyLmNyZWF0ZSgnc3JjJywgdXJsKSxcbiAgICAgICAgICBwYWlyLmNyZWF0ZSgnaGVpZ2h0JywgYCR7bWF0aC5yb3VuZChoZWlnaHQgKiAxLjUpfXB4YClcbiAgICAgICAgXSlcbiAgICAgIF0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge05vZGV9IG5vZGVcbiAgICovXG4gIHByaW50RG9tIChub2RlKSB7XG4gICAgZXZlbnRsb29wLmVucXVldWUoKCkgPT4ge1xuICAgICAgZG9tLmFwcGVuZCh0aGlzLmNjb250YWluZXIsIFtub2RlXSlcbiAgICB9KVxuICB9XG5cbiAgZGVzdHJveSAoKSB7XG4gICAgZXZlbnRsb29wLmVucXVldWUoKCkgPT4ge1xuICAgICAgdmNvbnNvbGVzLmRlbGV0ZSh0aGlzKVxuICAgIH0pXG4gIH1cbn1cbi8qIGM4IGlnbm9yZSBzdG9wICovXG5cbi8qKlxuICogQHBhcmFtIHtFbGVtZW50fSBkb21cbiAqL1xuLyogYzggaWdub3JlIG5leHQgKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVWQ29uc29sZSA9IChkb20pID0+IG5ldyBWQ29uc29sZShkb20pXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IG1vZHVsZU5hbWVcbiAqIEByZXR1cm4ge2Z1bmN0aW9uKC4uLmFueSk6dm9pZH1cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU1vZHVsZUxvZ2dlciA9IChtb2R1bGVOYW1lKSA9PiBjb21tb24uY3JlYXRlTW9kdWxlTG9nZ2VyKHByaW50LCBtb2R1bGVOYW1lKVxuIiwgIi8qKlxuICogVXRpbGl0eSBtb2R1bGUgdG8gY3JlYXRlIGFuZCBtYW5pcHVsYXRlIEl0ZXJhdG9ycy5cbiAqXG4gKiBAbW9kdWxlIGl0ZXJhdG9yXG4gKi9cblxuLyoqXG4gKiBAdGVtcGxhdGUgVCxSXG4gKiBAcGFyYW0ge0l0ZXJhdG9yPFQ+fSBpdGVyYXRvclxuICogQHBhcmFtIHtmdW5jdGlvbihUKTpSfSBmXG4gKiBAcmV0dXJuIHtJdGVyYWJsZUl0ZXJhdG9yPFI+fVxuICovXG5leHBvcnQgY29uc3QgbWFwSXRlcmF0b3IgPSAoaXRlcmF0b3IsIGYpID0+ICh7XG4gIFtTeW1ib2wuaXRlcmF0b3JdICgpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9LFxuICAvLyBAdHMtaWdub3JlXG4gIG5leHQgKCkge1xuICAgIGNvbnN0IHIgPSBpdGVyYXRvci5uZXh0KClcbiAgICByZXR1cm4geyB2YWx1ZTogci5kb25lID8gdW5kZWZpbmVkIDogZihyLnZhbHVlKSwgZG9uZTogci5kb25lIH1cbiAgfVxufSlcblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtmdW5jdGlvbigpOkl0ZXJhdG9yUmVzdWx0PFQ+fSBuZXh0XG4gKiBAcmV0dXJuIHtJdGVyYWJsZUl0ZXJhdG9yPFQ+fVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlSXRlcmF0b3IgPSBuZXh0ID0+ICh7XG4gIC8qKlxuICAgKiBAcmV0dXJuIHtJdGVyYWJsZUl0ZXJhdG9yPFQ+fVxuICAgKi9cbiAgW1N5bWJvbC5pdGVyYXRvcl0gKCkge1xuICAgIHJldHVybiB0aGlzXG4gIH0sXG4gIC8vIEB0cy1pZ25vcmVcbiAgbmV4dFxufSlcblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtJdGVyYXRvcjxUPn0gaXRlcmF0b3JcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oVCk6Ym9vbGVhbn0gZmlsdGVyXG4gKi9cbmV4cG9ydCBjb25zdCBpdGVyYXRvckZpbHRlciA9IChpdGVyYXRvciwgZmlsdGVyKSA9PiBjcmVhdGVJdGVyYXRvcigoKSA9PiB7XG4gIGxldCByZXNcbiAgZG8ge1xuICAgIHJlcyA9IGl0ZXJhdG9yLm5leHQoKVxuICB9IHdoaWxlICghcmVzLmRvbmUgJiYgIWZpbHRlcihyZXMudmFsdWUpKVxuICByZXR1cm4gcmVzXG59KVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBULE1cbiAqIEBwYXJhbSB7SXRlcmF0b3I8VD59IGl0ZXJhdG9yXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFQpOk19IGZtYXBcbiAqL1xuZXhwb3J0IGNvbnN0IGl0ZXJhdG9yTWFwID0gKGl0ZXJhdG9yLCBmbWFwKSA9PiBjcmVhdGVJdGVyYXRvcigoKSA9PiB7XG4gIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGl0ZXJhdG9yLm5leHQoKVxuICByZXR1cm4geyBkb25lLCB2YWx1ZTogZG9uZSA/IHVuZGVmaW5lZCA6IGZtYXAodmFsdWUpIH1cbn0pXG4iLCAiaW1wb3J0IHsgT2JzZXJ2YWJsZVYyIH0gZnJvbSAnbGliMC9vYnNlcnZhYmxlJ1xuXG5pbXBvcnQge1xuICBEb2MgLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbi8qKlxuICogVGhpcyBpcyBhbiBhYnN0cmFjdCBpbnRlcmZhY2UgdGhhdCBhbGwgQ29ubmVjdG9ycyBzaG91bGQgaW1wbGVtZW50IHRvIGtlZXAgdGhlbSBpbnRlcmNoYW5nZWFibGUuXG4gKlxuICogQG5vdGUgVGhpcyBpbnRlcmZhY2UgaXMgZXhwZXJpbWVudGFsIGFuZCBpdCBpcyBub3QgYWR2aXNlZCB0byBhY3R1YWxseSBpbmhlcml0IHRoaXMgY2xhc3MuXG4gKiAgICAgICBJdCBqdXN0IHNlcnZlcyBhcyB0eXBpbmcgaW5mb3JtYXRpb24uXG4gKlxuICogQGV4dGVuZHMge09ic2VydmFibGVWMjxhbnk+fVxuICovXG5leHBvcnQgY2xhc3MgQWJzdHJhY3RDb25uZWN0b3IgZXh0ZW5kcyBPYnNlcnZhYmxlVjIge1xuICAvKipcbiAgICogQHBhcmFtIHtEb2N9IHlkb2NcbiAgICogQHBhcmFtIHthbnl9IGF3YXJlbmVzc1xuICAgKi9cbiAgY29uc3RydWN0b3IgKHlkb2MsIGF3YXJlbmVzcykge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLmRvYyA9IHlkb2NcbiAgICB0aGlzLmF3YXJlbmVzcyA9IGF3YXJlbmVzc1xuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgZmluZEluZGV4U1MsXG4gIGdldFN0YXRlLFxuICBzcGxpdEl0ZW0sXG4gIGl0ZXJhdGVTdHJ1Y3RzLFxuICBVcGRhdGVFbmNvZGVyVjIsXG4gIERTRGVjb2RlclYxLCBEU0VuY29kZXJWMSwgRFNEZWNvZGVyVjIsIERTRW5jb2RlclYyLCBJdGVtLCBHQywgU3RydWN0U3RvcmUsIFRyYW5zYWN0aW9uLCBJRCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcblxuaW1wb3J0ICogYXMgYXJyYXkgZnJvbSAnbGliMC9hcnJheSdcbmltcG9ydCAqIGFzIG1hdGggZnJvbSAnbGliMC9tYXRoJ1xuaW1wb3J0ICogYXMgbWFwIGZyb20gJ2xpYjAvbWFwJ1xuaW1wb3J0ICogYXMgZW5jb2RpbmcgZnJvbSAnbGliMC9lbmNvZGluZydcbmltcG9ydCAqIGFzIGRlY29kaW5nIGZyb20gJ2xpYjAvZGVjb2RpbmcnXG5cbmV4cG9ydCBjbGFzcyBEZWxldGVJdGVtIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjbG9ja1xuICAgKiBAcGFyYW0ge251bWJlcn0gbGVuXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoY2xvY2ssIGxlbikge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5jbG9jayA9IGNsb2NrXG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmxlbiA9IGxlblxuICB9XG59XG5cbi8qKlxuICogV2Ugbm8gbG9uZ2VyIG1haW50YWluIGEgRGVsZXRlU3RvcmUuIERlbGV0ZVNldCBpcyBhIHRlbXBvcmFyeSBvYmplY3QgdGhhdCBpcyBjcmVhdGVkIHdoZW4gbmVlZGVkLlxuICogLSBXaGVuIGNyZWF0ZWQgaW4gYSB0cmFuc2FjdGlvbiwgaXQgbXVzdCBvbmx5IGJlIGFjY2Vzc2VkIGFmdGVyIHNvcnRpbmcsIGFuZCBtZXJnaW5nXG4gKiAgIC0gVGhpcyBEZWxldGVTZXQgaXMgc2VuZCB0byBvdGhlciBjbGllbnRzXG4gKiAtIFdlIGRvIG5vdCBjcmVhdGUgYSBEZWxldGVTZXQgd2hlbiB3ZSBzZW5kIGEgc3luYyBtZXNzYWdlLiBUaGUgRGVsZXRlU2V0IG1lc3NhZ2UgaXMgY3JlYXRlZCBkaXJlY3RseSBmcm9tIFN0cnVjdFN0b3JlXG4gKiAtIFdlIHJlYWQgYSBEZWxldGVTZXQgYXMgcGFydCBvZiBhIHN5bmMvdXBkYXRlIG1lc3NhZ2UuIEluIHRoaXMgY2FzZSB0aGUgRGVsZXRlU2V0IGlzIGFscmVhZHkgc29ydGVkIGFuZCBtZXJnZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBEZWxldGVTZXQge1xuICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge01hcDxudW1iZXIsQXJyYXk8RGVsZXRlSXRlbT4+fVxuICAgICAqL1xuICAgIHRoaXMuY2xpZW50cyA9IG5ldyBNYXAoKVxuICB9XG59XG5cbi8qKlxuICogSXRlcmF0ZSBvdmVyIGFsbCBzdHJ1Y3RzIHRoYXQgdGhlIERlbGV0ZVNldCBnYydzLlxuICpcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gKiBAcGFyYW0ge0RlbGV0ZVNldH0gZHNcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oR0N8SXRlbSk6dm9pZH0gZlxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgaXRlcmF0ZURlbGV0ZWRTdHJ1Y3RzID0gKHRyYW5zYWN0aW9uLCBkcywgZikgPT5cbiAgZHMuY2xpZW50cy5mb3JFYWNoKChkZWxldGVzLCBjbGllbnRpZCkgPT4ge1xuICAgIGNvbnN0IHN0cnVjdHMgPSAvKiogQHR5cGUge0FycmF5PEdDfEl0ZW0+fSAqLyAodHJhbnNhY3Rpb24uZG9jLnN0b3JlLmNsaWVudHMuZ2V0KGNsaWVudGlkKSlcbiAgICBpZiAoc3RydWN0cyAhPSBudWxsKSB7XG4gICAgICBjb25zdCBsYXN0U3RydWN0ID0gc3RydWN0c1tzdHJ1Y3RzLmxlbmd0aCAtIDFdXG4gICAgICBjb25zdCBjbG9ja1N0YXRlID0gbGFzdFN0cnVjdC5pZC5jbG9jayArIGxhc3RTdHJ1Y3QubGVuZ3RoXG4gICAgICBmb3IgKGxldCBpID0gMCwgZGVsID0gZGVsZXRlc1tpXTsgaSA8IGRlbGV0ZXMubGVuZ3RoICYmIGRlbC5jbG9jayA8IGNsb2NrU3RhdGU7IGRlbCA9IGRlbGV0ZXNbKytpXSkge1xuICAgICAgICBpdGVyYXRlU3RydWN0cyh0cmFuc2FjdGlvbiwgc3RydWN0cywgZGVsLmNsb2NrLCBkZWwubGVuLCBmKVxuICAgICAgfVxuICAgIH1cbiAgfSlcblxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PERlbGV0ZUl0ZW0+fSBkaXNcbiAqIEBwYXJhbSB7bnVtYmVyfSBjbG9ja1xuICogQHJldHVybiB7bnVtYmVyfG51bGx9XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgZmluZEluZGV4RFMgPSAoZGlzLCBjbG9jaykgPT4ge1xuICBsZXQgbGVmdCA9IDBcbiAgbGV0IHJpZ2h0ID0gZGlzLmxlbmd0aCAtIDFcbiAgd2hpbGUgKGxlZnQgPD0gcmlnaHQpIHtcbiAgICBjb25zdCBtaWRpbmRleCA9IG1hdGguZmxvb3IoKGxlZnQgKyByaWdodCkgLyAyKVxuICAgIGNvbnN0IG1pZCA9IGRpc1ttaWRpbmRleF1cbiAgICBjb25zdCBtaWRjbG9jayA9IG1pZC5jbG9ja1xuICAgIGlmIChtaWRjbG9jayA8PSBjbG9jaykge1xuICAgICAgaWYgKGNsb2NrIDwgbWlkY2xvY2sgKyBtaWQubGVuKSB7XG4gICAgICAgIHJldHVybiBtaWRpbmRleFxuICAgICAgfVxuICAgICAgbGVmdCA9IG1pZGluZGV4ICsgMVxuICAgIH0gZWxzZSB7XG4gICAgICByaWdodCA9IG1pZGluZGV4IC0gMVxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbFxufVxuXG4vKipcbiAqIEBwYXJhbSB7RGVsZXRlU2V0fSBkc1xuICogQHBhcmFtIHtJRH0gaWRcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgaXNEZWxldGVkID0gKGRzLCBpZCkgPT4ge1xuICBjb25zdCBkaXMgPSBkcy5jbGllbnRzLmdldChpZC5jbGllbnQpXG4gIHJldHVybiBkaXMgIT09IHVuZGVmaW5lZCAmJiBmaW5kSW5kZXhEUyhkaXMsIGlkLmNsb2NrKSAhPT0gbnVsbFxufVxuXG4vKipcbiAqIEBwYXJhbSB7RGVsZXRlU2V0fSBkc1xuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHNvcnRBbmRNZXJnZURlbGV0ZVNldCA9IGRzID0+IHtcbiAgZHMuY2xpZW50cy5mb3JFYWNoKGRlbHMgPT4ge1xuICAgIGRlbHMuc29ydCgoYSwgYikgPT4gYS5jbG9jayAtIGIuY2xvY2spXG4gICAgLy8gbWVyZ2UgaXRlbXMgd2l0aG91dCBmaWx0ZXJpbmcgb3Igc3BsaWNpbmcgdGhlIGFycmF5XG4gICAgLy8gaSBpcyB0aGUgY3VycmVudCBwb2ludGVyXG4gICAgLy8gaiByZWZlcnMgdG8gdGhlIGN1cnJlbnQgaW5zZXJ0IHBvc2l0aW9uIGZvciB0aGUgcG9pbnRlZCBpdGVtXG4gICAgLy8gdHJ5IHRvIG1lcmdlIGRlbHNbaV0gaW50byBkZWxzW2otMV0gb3Igc2V0IGRlbHNbal09ZGVsc1tpXVxuICAgIGxldCBpLCBqXG4gICAgZm9yIChpID0gMSwgaiA9IDE7IGkgPCBkZWxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gZGVsc1tqIC0gMV1cbiAgICAgIGNvbnN0IHJpZ2h0ID0gZGVsc1tpXVxuICAgICAgaWYgKGxlZnQuY2xvY2sgKyBsZWZ0LmxlbiA+PSByaWdodC5jbG9jaykge1xuICAgICAgICBkZWxzW2ogLSAxXSA9IG5ldyBEZWxldGVJdGVtKGxlZnQuY2xvY2ssIG1hdGgubWF4KGxlZnQubGVuLCByaWdodC5jbG9jayArIHJpZ2h0LmxlbiAtIGxlZnQuY2xvY2spKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGogPCBpKSB7XG4gICAgICAgICAgZGVsc1tqXSA9IHJpZ2h0XG4gICAgICAgIH1cbiAgICAgICAgaisrXG4gICAgICB9XG4gICAgfVxuICAgIGRlbHMubGVuZ3RoID0galxuICB9KVxufVxuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8RGVsZXRlU2V0Pn0gZHNzXG4gKiBAcmV0dXJuIHtEZWxldGVTZXR9IEEgZnJlc2ggRGVsZXRlU2V0XG4gKi9cbmV4cG9ydCBjb25zdCBtZXJnZURlbGV0ZVNldHMgPSBkc3MgPT4ge1xuICBjb25zdCBtZXJnZWQgPSBuZXcgRGVsZXRlU2V0KClcbiAgZm9yIChsZXQgZHNzSSA9IDA7IGRzc0kgPCBkc3MubGVuZ3RoOyBkc3NJKyspIHtcbiAgICBkc3NbZHNzSV0uY2xpZW50cy5mb3JFYWNoKChkZWxzTGVmdCwgY2xpZW50KSA9PiB7XG4gICAgICBpZiAoIW1lcmdlZC5jbGllbnRzLmhhcyhjbGllbnQpKSB7XG4gICAgICAgIC8vIFdyaXRlIGFsbCBtaXNzaW5nIGtleXMgZnJvbSBjdXJyZW50IGRzIGFuZCBhbGwgZm9sbG93aW5nLlxuICAgICAgICAvLyBJZiBtZXJnZWQgYWxyZWFkeSBjb250YWlucyBgY2xpZW50YCBjdXJyZW50IGRzIGhhcyBhbHJlYWR5IGJlZW4gYWRkZWQuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAdHlwZSB7QXJyYXk8RGVsZXRlSXRlbT59XG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBkZWxzID0gZGVsc0xlZnQuc2xpY2UoKVxuICAgICAgICBmb3IgKGxldCBpID0gZHNzSSArIDE7IGkgPCBkc3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBhcnJheS5hcHBlbmRUbyhkZWxzLCBkc3NbaV0uY2xpZW50cy5nZXQoY2xpZW50KSB8fCBbXSlcbiAgICAgICAgfVxuICAgICAgICBtZXJnZWQuY2xpZW50cy5zZXQoY2xpZW50LCBkZWxzKVxuICAgICAgfVxuICAgIH0pXG4gIH1cbiAgc29ydEFuZE1lcmdlRGVsZXRlU2V0KG1lcmdlZClcbiAgcmV0dXJuIG1lcmdlZFxufVxuXG4vKipcbiAqIEBwYXJhbSB7RGVsZXRlU2V0fSBkc1xuICogQHBhcmFtIHtudW1iZXJ9IGNsaWVudFxuICogQHBhcmFtIHtudW1iZXJ9IGNsb2NrXG4gKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgYWRkVG9EZWxldGVTZXQgPSAoZHMsIGNsaWVudCwgY2xvY2ssIGxlbmd0aCkgPT4ge1xuICBtYXAuc2V0SWZVbmRlZmluZWQoZHMuY2xpZW50cywgY2xpZW50LCAoKSA9PiAvKiogQHR5cGUge0FycmF5PERlbGV0ZUl0ZW0+fSAqLyAoW10pKS5wdXNoKG5ldyBEZWxldGVJdGVtKGNsb2NrLCBsZW5ndGgpKVxufVxuXG5leHBvcnQgY29uc3QgY3JlYXRlRGVsZXRlU2V0ID0gKCkgPT4gbmV3IERlbGV0ZVNldCgpXG5cbi8qKlxuICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3NcbiAqIEByZXR1cm4ge0RlbGV0ZVNldH0gTWVyZ2VkIGFuZCBzb3J0ZWQgRGVsZXRlU2V0XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlRGVsZXRlU2V0RnJvbVN0cnVjdFN0b3JlID0gc3MgPT4ge1xuICBjb25zdCBkcyA9IGNyZWF0ZURlbGV0ZVNldCgpXG4gIHNzLmNsaWVudHMuZm9yRWFjaCgoc3RydWN0cywgY2xpZW50KSA9PiB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PERlbGV0ZUl0ZW0+fVxuICAgICAqL1xuICAgIGNvbnN0IGRzaXRlbXMgPSBbXVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RydWN0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgc3RydWN0ID0gc3RydWN0c1tpXVxuICAgICAgaWYgKHN0cnVjdC5kZWxldGVkKSB7XG4gICAgICAgIGNvbnN0IGNsb2NrID0gc3RydWN0LmlkLmNsb2NrXG4gICAgICAgIGxldCBsZW4gPSBzdHJ1Y3QubGVuZ3RoXG4gICAgICAgIGlmIChpICsgMSA8IHN0cnVjdHMubGVuZ3RoKSB7XG4gICAgICAgICAgZm9yIChsZXQgbmV4dCA9IHN0cnVjdHNbaSArIDFdOyBpICsgMSA8IHN0cnVjdHMubGVuZ3RoICYmIG5leHQuZGVsZXRlZDsgbmV4dCA9IHN0cnVjdHNbKytpICsgMV0pIHtcbiAgICAgICAgICAgIGxlbiArPSBuZXh0Lmxlbmd0aFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBkc2l0ZW1zLnB1c2gobmV3IERlbGV0ZUl0ZW0oY2xvY2ssIGxlbikpXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChkc2l0ZW1zLmxlbmd0aCA+IDApIHtcbiAgICAgIGRzLmNsaWVudHMuc2V0KGNsaWVudCwgZHNpdGVtcylcbiAgICB9XG4gIH0pXG4gIHJldHVybiBkc1xufVxuXG4vKipcbiAqIEBwYXJhbSB7RFNFbmNvZGVyVjEgfCBEU0VuY29kZXJWMn0gZW5jb2RlclxuICogQHBhcmFtIHtEZWxldGVTZXR9IGRzXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3Qgd3JpdGVEZWxldGVTZXQgPSAoZW5jb2RlciwgZHMpID0+IHtcbiAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIucmVzdEVuY29kZXIsIGRzLmNsaWVudHMuc2l6ZSlcblxuICAvLyBFbnN1cmUgdGhhdCB0aGUgZGVsZXRlIHNldCBpcyB3cml0dGVuIGluIGEgZGV0ZXJtaW5pc3RpYyBvcmRlclxuICBhcnJheS5mcm9tKGRzLmNsaWVudHMuZW50cmllcygpKVxuICAgIC5zb3J0KChhLCBiKSA9PiBiWzBdIC0gYVswXSlcbiAgICAuZm9yRWFjaCgoW2NsaWVudCwgZHNpdGVtc10pID0+IHtcbiAgICAgIGVuY29kZXIucmVzZXREc0N1clZhbCgpXG4gICAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2Rlci5yZXN0RW5jb2RlciwgY2xpZW50KVxuICAgICAgY29uc3QgbGVuID0gZHNpdGVtcy5sZW5ndGhcbiAgICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLnJlc3RFbmNvZGVyLCBsZW4pXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBkc2l0ZW1zW2ldXG4gICAgICAgIGVuY29kZXIud3JpdGVEc0Nsb2NrKGl0ZW0uY2xvY2spXG4gICAgICAgIGVuY29kZXIud3JpdGVEc0xlbihpdGVtLmxlbilcbiAgICAgIH1cbiAgICB9KVxufVxuXG4vKipcbiAqIEBwYXJhbSB7RFNEZWNvZGVyVjEgfCBEU0RlY29kZXJWMn0gZGVjb2RlclxuICogQHJldHVybiB7RGVsZXRlU2V0fVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWREZWxldGVTZXQgPSBkZWNvZGVyID0+IHtcbiAgY29uc3QgZHMgPSBuZXcgRGVsZXRlU2V0KClcbiAgY29uc3QgbnVtQ2xpZW50cyA9IGRlY29kaW5nLnJlYWRWYXJVaW50KGRlY29kZXIucmVzdERlY29kZXIpXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ2xpZW50czsgaSsrKSB7XG4gICAgZGVjb2Rlci5yZXNldERzQ3VyVmFsKClcbiAgICBjb25zdCBjbGllbnQgPSBkZWNvZGluZy5yZWFkVmFyVWludChkZWNvZGVyLnJlc3REZWNvZGVyKVxuICAgIGNvbnN0IG51bWJlck9mRGVsZXRlcyA9IGRlY29kaW5nLnJlYWRWYXJVaW50KGRlY29kZXIucmVzdERlY29kZXIpXG4gICAgaWYgKG51bWJlck9mRGVsZXRlcyA+IDApIHtcbiAgICAgIGNvbnN0IGRzRmllbGQgPSBtYXAuc2V0SWZVbmRlZmluZWQoZHMuY2xpZW50cywgY2xpZW50LCAoKSA9PiAvKiogQHR5cGUge0FycmF5PERlbGV0ZUl0ZW0+fSAqLyAoW10pKVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkRlbGV0ZXM7IGkrKykge1xuICAgICAgICBkc0ZpZWxkLnB1c2gobmV3IERlbGV0ZUl0ZW0oZGVjb2Rlci5yZWFkRHNDbG9jaygpLCBkZWNvZGVyLnJlYWREc0xlbigpKSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRzXG59XG5cbi8qKlxuICogQHRvZG8gWURlY29kZXIgYWxzbyBjb250YWlucyByZWZlcmVuY2VzIHRvIFN0cmluZyBhbmQgb3RoZXIgRGVjb2RlcnMuIFdvdWxkIG1ha2Ugc2Vuc2UgdG8gZXhjaGFuZ2UgWURlY29kZXIudG9VaW50OEFycmF5IGZvciBZRGVjb2Rlci5Ec1RvVWludDhBcnJheSgpLi5cbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7RFNEZWNvZGVyVjEgfCBEU0RlY29kZXJWMn0gZGVjb2RlclxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEBwYXJhbSB7U3RydWN0U3RvcmV9IHN0b3JlXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fG51bGx9IFJldHVybnMgYSB2MiB1cGRhdGUgY29udGFpbmluZyBhbGwgZGVsZXRlcyB0aGF0IGNvdWxkbid0IGJlIGFwcGxpZWQgeWV0OyBvciBudWxsIGlmIGFsbCBkZWxldGVzIHdlcmUgYXBwbGllZCBzdWNjZXNzZnVsbHkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgcmVhZEFuZEFwcGx5RGVsZXRlU2V0ID0gKGRlY29kZXIsIHRyYW5zYWN0aW9uLCBzdG9yZSkgPT4ge1xuICBjb25zdCB1bmFwcGxpZWREUyA9IG5ldyBEZWxldGVTZXQoKVxuICBjb25zdCBudW1DbGllbnRzID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2Rlci5yZXN0RGVjb2RlcilcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1DbGllbnRzOyBpKyspIHtcbiAgICBkZWNvZGVyLnJlc2V0RHNDdXJWYWwoKVxuICAgIGNvbnN0IGNsaWVudCA9IGRlY29kaW5nLnJlYWRWYXJVaW50KGRlY29kZXIucmVzdERlY29kZXIpXG4gICAgY29uc3QgbnVtYmVyT2ZEZWxldGVzID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2Rlci5yZXN0RGVjb2RlcilcbiAgICBjb25zdCBzdHJ1Y3RzID0gc3RvcmUuY2xpZW50cy5nZXQoY2xpZW50KSB8fCBbXVxuICAgIGNvbnN0IHN0YXRlID0gZ2V0U3RhdGUoc3RvcmUsIGNsaWVudClcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bWJlck9mRGVsZXRlczsgaSsrKSB7XG4gICAgICBjb25zdCBjbG9jayA9IGRlY29kZXIucmVhZERzQ2xvY2soKVxuICAgICAgY29uc3QgY2xvY2tFbmQgPSBjbG9jayArIGRlY29kZXIucmVhZERzTGVuKClcbiAgICAgIGlmIChjbG9jayA8IHN0YXRlKSB7XG4gICAgICAgIGlmIChzdGF0ZSA8IGNsb2NrRW5kKSB7XG4gICAgICAgICAgYWRkVG9EZWxldGVTZXQodW5hcHBsaWVkRFMsIGNsaWVudCwgc3RhdGUsIGNsb2NrRW5kIC0gc3RhdGUpXG4gICAgICAgIH1cbiAgICAgICAgbGV0IGluZGV4ID0gZmluZEluZGV4U1Moc3RydWN0cywgY2xvY2spXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXZSBjYW4gaWdub3JlIHRoZSBjYXNlIG9mIEdDIGFuZCBEZWxldGUgc3RydWN0cywgYmVjYXVzZSB3ZSBhcmUgZ29pbmcgdG8gc2tpcCB0aGVtXG4gICAgICAgICAqIEB0eXBlIHtJdGVtfVxuICAgICAgICAgKi9cbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBsZXQgc3RydWN0ID0gc3RydWN0c1tpbmRleF1cbiAgICAgICAgLy8gc3BsaXQgdGhlIGZpcnN0IGl0ZW0gaWYgbmVjZXNzYXJ5XG4gICAgICAgIGlmICghc3RydWN0LmRlbGV0ZWQgJiYgc3RydWN0LmlkLmNsb2NrIDwgY2xvY2spIHtcbiAgICAgICAgICBzdHJ1Y3RzLnNwbGljZShpbmRleCArIDEsIDAsIHNwbGl0SXRlbSh0cmFuc2FjdGlvbiwgc3RydWN0LCBjbG9jayAtIHN0cnVjdC5pZC5jbG9jaykpXG4gICAgICAgICAgaW5kZXgrKyAvLyBpbmNyZWFzZSB3ZSBub3cgd2FudCB0byB1c2UgdGhlIG5leHQgc3RydWN0XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGluZGV4IDwgc3RydWN0cy5sZW5ndGgpIHtcbiAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgc3RydWN0ID0gc3RydWN0c1tpbmRleCsrXVxuICAgICAgICAgIGlmIChzdHJ1Y3QuaWQuY2xvY2sgPCBjbG9ja0VuZCkge1xuICAgICAgICAgICAgaWYgKCFzdHJ1Y3QuZGVsZXRlZCkge1xuICAgICAgICAgICAgICBpZiAoY2xvY2tFbmQgPCBzdHJ1Y3QuaWQuY2xvY2sgKyBzdHJ1Y3QubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgc3RydWN0cy5zcGxpY2UoaW5kZXgsIDAsIHNwbGl0SXRlbSh0cmFuc2FjdGlvbiwgc3RydWN0LCBjbG9ja0VuZCAtIHN0cnVjdC5pZC5jbG9jaykpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgc3RydWN0LmRlbGV0ZSh0cmFuc2FjdGlvbilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFkZFRvRGVsZXRlU2V0KHVuYXBwbGllZERTLCBjbGllbnQsIGNsb2NrLCBjbG9ja0VuZCAtIGNsb2NrKVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAodW5hcHBsaWVkRFMuY2xpZW50cy5zaXplID4gMCkge1xuICAgIGNvbnN0IGRzID0gbmV3IFVwZGF0ZUVuY29kZXJWMigpXG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGRzLnJlc3RFbmNvZGVyLCAwKSAvLyBlbmNvZGUgMCBzdHJ1Y3RzXG4gICAgd3JpdGVEZWxldGVTZXQoZHMsIHVuYXBwbGllZERTKVxuICAgIHJldHVybiBkcy50b1VpbnQ4QXJyYXkoKVxuICB9XG4gIHJldHVybiBudWxsXG59XG5cbi8qKlxuICogQHBhcmFtIHtEZWxldGVTZXR9IGRzMVxuICogQHBhcmFtIHtEZWxldGVTZXR9IGRzMlxuICovXG5leHBvcnQgY29uc3QgZXF1YWxEZWxldGVTZXRzID0gKGRzMSwgZHMyKSA9PiB7XG4gIGlmIChkczEuY2xpZW50cy5zaXplICE9PSBkczIuY2xpZW50cy5zaXplKSByZXR1cm4gZmFsc2VcbiAgZm9yIChjb25zdCBbY2xpZW50LCBkZWxldGVJdGVtczFdIG9mIGRzMS5jbGllbnRzLmVudHJpZXMoKSkge1xuICAgIGNvbnN0IGRlbGV0ZUl0ZW1zMiA9IC8qKiBAdHlwZSB7QXJyYXk8aW1wb3J0KCcuLi9pbnRlcm5hbHMuanMnKS5EZWxldGVJdGVtPn0gKi8gKGRzMi5jbGllbnRzLmdldChjbGllbnQpKVxuICAgIGlmIChkZWxldGVJdGVtczIgPT09IHVuZGVmaW5lZCB8fCBkZWxldGVJdGVtczEubGVuZ3RoICE9PSBkZWxldGVJdGVtczIubGVuZ3RoKSByZXR1cm4gZmFsc2VcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlbGV0ZUl0ZW1zMS5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgZGkxID0gZGVsZXRlSXRlbXMxW2ldXG4gICAgICBjb25zdCBkaTIgPSBkZWxldGVJdGVtczJbaV1cbiAgICAgIGlmIChkaTEuY2xvY2sgIT09IGRpMi5jbG9jayB8fCBkaTEubGVuICE9PSBkaTIubGVuKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuIiwgIi8qKlxuICogQG1vZHVsZSBZXG4gKi9cblxuaW1wb3J0IHtcbiAgU3RydWN0U3RvcmUsXG4gIEFic3RyYWN0VHlwZSxcbiAgWUFycmF5LFxuICBZVGV4dCxcbiAgWU1hcCxcbiAgWVhtbEVsZW1lbnQsXG4gIFlYbWxGcmFnbWVudCxcbiAgdHJhbnNhY3QsXG4gIENvbnRlbnREb2MsIEl0ZW0sIFRyYW5zYWN0aW9uLCBZRXZlbnQgLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbmltcG9ydCB7IE9ic2VydmFibGVWMiB9IGZyb20gJ2xpYjAvb2JzZXJ2YWJsZSdcbmltcG9ydCAqIGFzIHJhbmRvbSBmcm9tICdsaWIwL3JhbmRvbSdcbmltcG9ydCAqIGFzIG1hcCBmcm9tICdsaWIwL21hcCdcbmltcG9ydCAqIGFzIGFycmF5IGZyb20gJ2xpYjAvYXJyYXknXG5pbXBvcnQgKiBhcyBwcm9taXNlIGZyb20gJ2xpYjAvcHJvbWlzZSdcblxuZXhwb3J0IGNvbnN0IGdlbmVyYXRlTmV3Q2xpZW50SWQgPSByYW5kb20udWludDMyXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gRG9jT3B0c1xuICogQHByb3BlcnR5IHtib29sZWFufSBbRG9jT3B0cy5nYz10cnVlXSBEaXNhYmxlIGdhcmJhZ2UgY29sbGVjdGlvbiAoZGVmYXVsdDogZ2M9dHJ1ZSlcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oSXRlbSk6Ym9vbGVhbn0gW0RvY09wdHMuZ2NGaWx0ZXJdIFdpbGwgYmUgY2FsbGVkIGJlZm9yZSBhbiBJdGVtIGlzIGdhcmJhZ2UgY29sbGVjdGVkLiBSZXR1cm4gZmFsc2UgdG8ga2VlcCB0aGUgSXRlbS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbRG9jT3B0cy5ndWlkXSBEZWZpbmUgYSBnbG9iYWxseSB1bmlxdWUgaWRlbnRpZmllciBmb3IgdGhpcyBkb2N1bWVudFxuICogQHByb3BlcnR5IHtzdHJpbmcgfCBudWxsfSBbRG9jT3B0cy5jb2xsZWN0aW9uaWRdIEFzc29jaWF0ZSB0aGlzIGRvY3VtZW50IHdpdGggYSBjb2xsZWN0aW9uLiBUaGlzIG9ubHkgcGxheXMgYSByb2xlIGlmIHlvdXIgcHJvdmlkZXIgaGFzIGEgY29uY2VwdCBvZiBjb2xsZWN0aW9uLlxuICogQHByb3BlcnR5IHthbnl9IFtEb2NPcHRzLm1ldGFdIEFueSBraW5kIG9mIG1ldGEgaW5mb3JtYXRpb24geW91IHdhbnQgdG8gYXNzb2NpYXRlIHdpdGggdGhpcyBkb2N1bWVudC4gSWYgdGhpcyBpcyBhIHN1YmRvY3VtZW50LCByZW1vdGUgcGVlcnMgd2lsbCBzdG9yZSB0aGUgbWV0YSBpbmZvcm1hdGlvbiBhcyB3ZWxsLlxuICogQHByb3BlcnR5IHtib29sZWFufSBbRG9jT3B0cy5hdXRvTG9hZF0gSWYgYSBzdWJkb2N1bWVudCwgYXV0b21hdGljYWxseSBsb2FkIGRvY3VtZW50LiBJZiB0aGlzIGlzIGEgc3ViZG9jdW1lbnQsIHJlbW90ZSBwZWVycyB3aWxsIGxvYWQgdGhlIGRvY3VtZW50IGFzIHdlbGwgYXV0b21hdGljYWxseS5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW0RvY09wdHMuc2hvdWxkTG9hZF0gV2hldGhlciB0aGUgZG9jdW1lbnQgc2hvdWxkIGJlIHN5bmNlZCBieSB0aGUgcHJvdmlkZXIgbm93LiBUaGlzIGlzIHRvZ2dsZWQgdG8gdHJ1ZSB3aGVuIHlvdSBjYWxsIHlkb2MubG9hZCgpXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBEb2NFdmVudHNcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oRG9jKTp2b2lkfSBEb2NFdmVudHMuZGVzdHJveVxuICogQHByb3BlcnR5IHtmdW5jdGlvbihEb2MpOnZvaWR9IERvY0V2ZW50cy5sb2FkXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKGJvb2xlYW4sIERvYyk6dm9pZH0gRG9jRXZlbnRzLnN5bmNcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oVWludDhBcnJheSwgYW55LCBEb2MsIFRyYW5zYWN0aW9uKTp2b2lkfSBEb2NFdmVudHMudXBkYXRlXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKFVpbnQ4QXJyYXksIGFueSwgRG9jLCBUcmFuc2FjdGlvbik6dm9pZH0gRG9jRXZlbnRzLnVwZGF0ZVYyXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKERvYyk6dm9pZH0gRG9jRXZlbnRzLmJlZm9yZUFsbFRyYW5zYWN0aW9uc1xuICogQHByb3BlcnR5IHtmdW5jdGlvbihUcmFuc2FjdGlvbiwgRG9jKTp2b2lkfSBEb2NFdmVudHMuYmVmb3JlVHJhbnNhY3Rpb25cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oVHJhbnNhY3Rpb24sIERvYyk6dm9pZH0gRG9jRXZlbnRzLmJlZm9yZU9ic2VydmVyQ2FsbHNcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oVHJhbnNhY3Rpb24sIERvYyk6dm9pZH0gRG9jRXZlbnRzLmFmdGVyVHJhbnNhY3Rpb25cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oVHJhbnNhY3Rpb24sIERvYyk6dm9pZH0gRG9jRXZlbnRzLmFmdGVyVHJhbnNhY3Rpb25DbGVhbnVwXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKERvYywgQXJyYXk8VHJhbnNhY3Rpb24+KTp2b2lkfSBEb2NFdmVudHMuYWZ0ZXJBbGxUcmFuc2FjdGlvbnNcbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oeyBsb2FkZWQ6IFNldDxEb2M+LCBhZGRlZDogU2V0PERvYz4sIHJlbW92ZWQ6IFNldDxEb2M+IH0sIERvYywgVHJhbnNhY3Rpb24pOnZvaWR9IERvY0V2ZW50cy5zdWJkb2NzXG4gKi9cblxuLyoqXG4gKiBBIFlqcyBpbnN0YW5jZSBoYW5kbGVzIHRoZSBzdGF0ZSBvZiBzaGFyZWQgZGF0YS5cbiAqIEBleHRlbmRzIE9ic2VydmFibGVWMjxEb2NFdmVudHM+XG4gKi9cbmV4cG9ydCBjbGFzcyBEb2MgZXh0ZW5kcyBPYnNlcnZhYmxlVjIge1xuICAvKipcbiAgICogQHBhcmFtIHtEb2NPcHRzfSBvcHRzIGNvbmZpZ3VyYXRpb25cbiAgICovXG4gIGNvbnN0cnVjdG9yICh7IGd1aWQgPSByYW5kb20udXVpZHY0KCksIGNvbGxlY3Rpb25pZCA9IG51bGwsIGdjID0gdHJ1ZSwgZ2NGaWx0ZXIgPSAoKSA9PiB0cnVlLCBtZXRhID0gbnVsbCwgYXV0b0xvYWQgPSBmYWxzZSwgc2hvdWxkTG9hZCA9IHRydWUgfSA9IHt9KSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuZ2MgPSBnY1xuICAgIHRoaXMuZ2NGaWx0ZXIgPSBnY0ZpbHRlclxuICAgIHRoaXMuY2xpZW50SUQgPSBnZW5lcmF0ZU5ld0NsaWVudElkKClcbiAgICB0aGlzLmd1aWQgPSBndWlkXG4gICAgdGhpcy5jb2xsZWN0aW9uaWQgPSBjb2xsZWN0aW9uaWRcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7TWFwPHN0cmluZywgQWJzdHJhY3RUeXBlPFlFdmVudDxhbnk+Pj59XG4gICAgICovXG4gICAgdGhpcy5zaGFyZSA9IG5ldyBNYXAoKVxuICAgIHRoaXMuc3RvcmUgPSBuZXcgU3RydWN0U3RvcmUoKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtUcmFuc2FjdGlvbiB8IG51bGx9XG4gICAgICovXG4gICAgdGhpcy5fdHJhbnNhY3Rpb24gPSBudWxsXG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PFRyYW5zYWN0aW9uPn1cbiAgICAgKi9cbiAgICB0aGlzLl90cmFuc2FjdGlvbkNsZWFudXBzID0gW11cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7U2V0PERvYz59XG4gICAgICovXG4gICAgdGhpcy5zdWJkb2NzID0gbmV3IFNldCgpXG4gICAgLyoqXG4gICAgICogSWYgdGhpcyBkb2N1bWVudCBpcyBhIHN1YmRvY3VtZW50IC0gYSBkb2N1bWVudCBpbnRlZ3JhdGVkIGludG8gYW5vdGhlciBkb2N1bWVudCAtIHRoZW4gX2l0ZW0gaXMgZGVmaW5lZC5cbiAgICAgKiBAdHlwZSB7SXRlbT99XG4gICAgICovXG4gICAgdGhpcy5faXRlbSA9IG51bGxcbiAgICB0aGlzLnNob3VsZExvYWQgPSBzaG91bGRMb2FkXG4gICAgdGhpcy5hdXRvTG9hZCA9IGF1dG9Mb2FkXG4gICAgdGhpcy5tZXRhID0gbWV0YVxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgc2V0IHRvIHRydWUgd2hlbiB0aGUgcGVyc2lzdGVuY2UgcHJvdmlkZXIgbG9hZGVkIHRoZSBkb2N1bWVudCBmcm9tIHRoZSBkYXRhYmFzZSBvciB3aGVuIHRoZSBgc3luY2AgZXZlbnQgZmlyZXMuXG4gICAgICogTm90ZSB0aGF0IG5vdCBhbGwgcHJvdmlkZXJzIGltcGxlbWVudCB0aGlzIGZlYXR1cmUuIFByb3ZpZGVyIGF1dGhvcnMgYXJlIGVuY291cmFnZWQgdG8gZmlyZSB0aGUgYGxvYWRgIGV2ZW50IHdoZW4gdGhlIGRvYyBjb250ZW50IGlzIGxvYWRlZCBmcm9tIHRoZSBkYXRhYmFzZS5cbiAgICAgKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMuaXNMb2FkZWQgPSBmYWxzZVxuICAgIC8qKlxuICAgICAqIFRoaXMgaXMgc2V0IHRvIHRydWUgd2hlbiB0aGUgY29ubmVjdGlvbiBwcm92aWRlciBoYXMgc3VjY2Vzc2Z1bGx5IHN5bmNlZCB3aXRoIGEgYmFja2VuZC5cbiAgICAgKiBOb3RlIHRoYXQgd2hlbiB1c2luZyBwZWVyLXRvLXBlZXIgcHJvdmlkZXJzIHRoaXMgZXZlbnQgbWF5IG5vdCBwcm92aWRlIHZlcnkgdXNlZnVsLlxuICAgICAqIEFsc28gbm90ZSB0aGF0IG5vdCBhbGwgcHJvdmlkZXJzIGltcGxlbWVudCB0aGlzIGZlYXR1cmUuIFByb3ZpZGVyIGF1dGhvcnMgYXJlIGVuY291cmFnZWQgdG8gZmlyZVxuICAgICAqIHRoZSBgc3luY2AgZXZlbnQgd2hlbiB0aGUgZG9jIGhhcyBiZWVuIHN5bmNlZCAod2l0aCBgdHJ1ZWAgYXMgYSBwYXJhbWV0ZXIpIG9yIGlmIGNvbm5lY3Rpb24gaXNcbiAgICAgKiBsb3N0ICh3aXRoIGZhbHNlIGFzIGEgcGFyYW1ldGVyKS5cbiAgICAgKi9cbiAgICB0aGlzLmlzU3luY2VkID0gZmFsc2VcbiAgICB0aGlzLmlzRGVzdHJveWVkID0gZmFsc2VcbiAgICAvKipcbiAgICAgKiBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgZG9jdW1lbnQgaGFzIGJlZW4gbG9hZGVkIGZyb20gYSBwZXJzaXN0ZW5jZSBwcm92aWRlci5cbiAgICAgKi9cbiAgICB0aGlzLndoZW5Mb2FkZWQgPSBwcm9taXNlLmNyZWF0ZShyZXNvbHZlID0+IHtcbiAgICAgIHRoaXMub24oJ2xvYWQnLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuaXNMb2FkZWQgPSB0cnVlXG4gICAgICAgIHJlc29sdmUodGhpcylcbiAgICAgIH0pXG4gICAgfSlcbiAgICBjb25zdCBwcm92aWRlU3luY2VkUHJvbWlzZSA9ICgpID0+IHByb21pc2UuY3JlYXRlKHJlc29sdmUgPT4ge1xuICAgICAgLyoqXG4gICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IGlzU3luY2VkXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IGV2ZW50SGFuZGxlciA9IChpc1N5bmNlZCkgPT4ge1xuICAgICAgICBpZiAoaXNTeW5jZWQgPT09IHVuZGVmaW5lZCB8fCBpc1N5bmNlZCA9PT0gdHJ1ZSkge1xuICAgICAgICAgIHRoaXMub2ZmKCdzeW5jJywgZXZlbnRIYW5kbGVyKVxuICAgICAgICAgIHJlc29sdmUoKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLm9uKCdzeW5jJywgZXZlbnRIYW5kbGVyKVxuICAgIH0pXG4gICAgdGhpcy5vbignc3luYycsIGlzU3luY2VkID0+IHtcbiAgICAgIGlmIChpc1N5bmNlZCA9PT0gZmFsc2UgJiYgdGhpcy5pc1N5bmNlZCkge1xuICAgICAgICB0aGlzLndoZW5TeW5jZWQgPSBwcm92aWRlU3luY2VkUHJvbWlzZSgpXG4gICAgICB9XG4gICAgICB0aGlzLmlzU3luY2VkID0gaXNTeW5jZWQgPT09IHVuZGVmaW5lZCB8fCBpc1N5bmNlZCA9PT0gdHJ1ZVxuICAgICAgaWYgKHRoaXMuaXNTeW5jZWQgJiYgIXRoaXMuaXNMb2FkZWQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdsb2FkJywgW3RoaXNdKVxuICAgICAgfVxuICAgIH0pXG4gICAgLyoqXG4gICAgICogUHJvbWlzZSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIGRvY3VtZW50IGhhcyBiZWVuIHN5bmNlZCB3aXRoIGEgYmFja2VuZC5cbiAgICAgKiBUaGlzIHByb21pc2UgaXMgcmVjcmVhdGVkIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgbG9zdC5cbiAgICAgKiBOb3RlIHRoZSBkb2N1bWVudGF0aW9uIGFib3V0IHRoZSBgaXNTeW5jZWRgIHByb3BlcnR5LlxuICAgICAqL1xuICAgIHRoaXMud2hlblN5bmNlZCA9IHByb3ZpZGVTeW5jZWRQcm9taXNlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RpZnkgdGhlIHBhcmVudCBkb2N1bWVudCB0aGF0IHlvdSByZXF1ZXN0IHRvIGxvYWQgZGF0YSBpbnRvIHRoaXMgc3ViZG9jdW1lbnQgKGlmIGl0IGlzIGEgc3ViZG9jdW1lbnQpLlxuICAgKlxuICAgKiBgbG9hZCgpYCBtaWdodCBiZSB1c2VkIGluIHRoZSBmdXR1cmUgdG8gcmVxdWVzdCBhbnkgcHJvdmlkZXIgdG8gbG9hZCB0aGUgbW9zdCBjdXJyZW50IGRhdGEuXG4gICAqXG4gICAqIEl0IGlzIHNhZmUgdG8gY2FsbCBgbG9hZCgpYCBtdWx0aXBsZSB0aW1lcy5cbiAgICovXG4gIGxvYWQgKCkge1xuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9pdGVtXG4gICAgaWYgKGl0ZW0gIT09IG51bGwgJiYgIXRoaXMuc2hvdWxkTG9hZCkge1xuICAgICAgdHJhbnNhY3QoLyoqIEB0eXBlIHthbnl9ICovIChpdGVtLnBhcmVudCkuZG9jLCB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIHRyYW5zYWN0aW9uLnN1YmRvY3NMb2FkZWQuYWRkKHRoaXMpXG4gICAgICB9LCBudWxsLCB0cnVlKVxuICAgIH1cbiAgICB0aGlzLnNob3VsZExvYWQgPSB0cnVlXG4gIH1cblxuICBnZXRTdWJkb2NzICgpIHtcbiAgICByZXR1cm4gdGhpcy5zdWJkb2NzXG4gIH1cblxuICBnZXRTdWJkb2NHdWlkcyAoKSB7XG4gICAgcmV0dXJuIG5ldyBTZXQoYXJyYXkuZnJvbSh0aGlzLnN1YmRvY3MpLm1hcChkb2MgPT4gZG9jLmd1aWQpKVxuICB9XG5cbiAgLyoqXG4gICAqIENoYW5nZXMgdGhhdCBoYXBwZW4gaW5zaWRlIG9mIGEgdHJhbnNhY3Rpb24gYXJlIGJ1bmRsZWQuIFRoaXMgbWVhbnMgdGhhdFxuICAgKiB0aGUgb2JzZXJ2ZXIgZmlyZXMgX2FmdGVyXyB0aGUgdHJhbnNhY3Rpb24gaXMgZmluaXNoZWQgYW5kIHRoYXQgYWxsIGNoYW5nZXNcbiAgICogdGhhdCBoYXBwZW5lZCBpbnNpZGUgb2YgdGhlIHRyYW5zYWN0aW9uIGFyZSBzZW50IGFzIG9uZSBtZXNzYWdlIHRvIHRoZVxuICAgKiBvdGhlciBwZWVycy5cbiAgICpcbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtmdW5jdGlvbihUcmFuc2FjdGlvbik6VH0gZiBUaGUgZnVuY3Rpb24gdGhhdCBzaG91bGQgYmUgZXhlY3V0ZWQgYXMgYSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge2FueX0gW29yaWdpbl0gT3JpZ2luIG9mIHdobyBzdGFydGVkIHRoZSB0cmFuc2FjdGlvbi4gV2lsbCBiZSBzdG9yZWQgb24gdHJhbnNhY3Rpb24ub3JpZ2luXG4gICAqIEByZXR1cm4gVFxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICB0cmFuc2FjdCAoZiwgb3JpZ2luID0gbnVsbCkge1xuICAgIHJldHVybiB0cmFuc2FjdCh0aGlzLCBmLCBvcmlnaW4pXG4gIH1cblxuICAvKipcbiAgICogRGVmaW5lIGEgc2hhcmVkIGRhdGEgdHlwZS5cbiAgICpcbiAgICogTXVsdGlwbGUgY2FsbHMgb2YgYHlkb2MuZ2V0KG5hbWUsIFR5cGVDb25zdHJ1Y3RvcilgIHlpZWxkIHRoZSBzYW1lIHJlc3VsdFxuICAgKiBhbmQgZG8gbm90IG92ZXJ3cml0ZSBlYWNoIG90aGVyLiBJLmUuXG4gICAqIGB5ZG9jLmdldChuYW1lLCBZLkFycmF5KSA9PT0geWRvYy5nZXQobmFtZSwgWS5BcnJheSlgXG4gICAqXG4gICAqIEFmdGVyIHRoaXMgbWV0aG9kIGlzIGNhbGxlZCwgdGhlIHR5cGUgaXMgYWxzbyBhdmFpbGFibGUgb24gYHlkb2Muc2hhcmUuZ2V0KG5hbWUpYC5cbiAgICpcbiAgICogKkJlc3QgUHJhY3RpY2VzOipcbiAgICogRGVmaW5lIGFsbCB0eXBlcyByaWdodCBhZnRlciB0aGUgWS5Eb2MgaW5zdGFuY2UgaXMgY3JlYXRlZCBhbmQgc3RvcmUgdGhlbSBpbiBhIHNlcGFyYXRlIG9iamVjdC5cbiAgICogQWxzbyB1c2UgdGhlIHR5cGVkIG1ldGhvZHMgYGdldFRleHQobmFtZSlgLCBgZ2V0QXJyYXkobmFtZSlgLCAuLlxuICAgKlxuICAgKiBAdGVtcGxhdGUge3R5cGVvZiBBYnN0cmFjdFR5cGU8YW55Pn0gVHlwZVxuICAgKiBAZXhhbXBsZVxuICAgKiAgIGNvbnN0IHlkb2MgPSBuZXcgWS5Eb2MoLi4pXG4gICAqICAgY29uc3QgYXBwU3RhdGUgPSB7XG4gICAqICAgICBkb2N1bWVudDogeWRvYy5nZXRUZXh0KCdkb2N1bWVudCcpXG4gICAqICAgICBjb21tZW50czogeWRvYy5nZXRBcnJheSgnY29tbWVudHMnKVxuICAgKiAgIH1cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICogQHBhcmFtIHtUeXBlfSBUeXBlQ29uc3RydWN0b3IgVGhlIGNvbnN0cnVjdG9yIG9mIHRoZSB0eXBlIGRlZmluaXRpb24uIEUuZy4gWS5UZXh0LCBZLkFycmF5LCBZLk1hcCwgLi4uXG4gICAqIEByZXR1cm4ge0luc3RhbmNlVHlwZTxUeXBlPn0gVGhlIGNyZWF0ZWQgdHlwZS4gQ29uc3RydWN0ZWQgd2l0aCBUeXBlQ29uc3RydWN0b3JcbiAgICpcbiAgICogQHB1YmxpY1xuICAgKi9cbiAgZ2V0IChuYW1lLCBUeXBlQ29uc3RydWN0b3IgPSAvKiogQHR5cGUge2FueX0gKi8gKEFic3RyYWN0VHlwZSkpIHtcbiAgICBjb25zdCB0eXBlID0gbWFwLnNldElmVW5kZWZpbmVkKHRoaXMuc2hhcmUsIG5hbWUsICgpID0+IHtcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIGNvbnN0IHQgPSBuZXcgVHlwZUNvbnN0cnVjdG9yKClcbiAgICAgIHQuX2ludGVncmF0ZSh0aGlzLCBudWxsKVxuICAgICAgcmV0dXJuIHRcbiAgICB9KVxuICAgIGNvbnN0IENvbnN0ciA9IHR5cGUuY29uc3RydWN0b3JcbiAgICBpZiAoVHlwZUNvbnN0cnVjdG9yICE9PSBBYnN0cmFjdFR5cGUgJiYgQ29uc3RyICE9PSBUeXBlQ29uc3RydWN0b3IpIHtcbiAgICAgIGlmIChDb25zdHIgPT09IEFic3RyYWN0VHlwZSkge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIGNvbnN0IHQgPSBuZXcgVHlwZUNvbnN0cnVjdG9yKClcbiAgICAgICAgdC5fbWFwID0gdHlwZS5fbWFwXG4gICAgICAgIHR5cGUuX21hcC5mb3JFYWNoKC8qKiBAcGFyYW0ge0l0ZW0/fSBuICovIG4gPT4ge1xuICAgICAgICAgIGZvciAoOyBuICE9PSBudWxsOyBuID0gbi5sZWZ0KSB7XG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBuLnBhcmVudCA9IHRcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIHQuX3N0YXJ0ID0gdHlwZS5fc3RhcnRcbiAgICAgICAgZm9yIChsZXQgbiA9IHQuX3N0YXJ0OyBuICE9PSBudWxsOyBuID0gbi5yaWdodCkge1xuICAgICAgICAgIG4ucGFyZW50ID0gdFxuICAgICAgICB9XG4gICAgICAgIHQuX2xlbmd0aCA9IHR5cGUuX2xlbmd0aFxuICAgICAgICB0aGlzLnNoYXJlLnNldChuYW1lLCB0KVxuICAgICAgICB0Ll9pbnRlZ3JhdGUodGhpcywgbnVsbClcbiAgICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7SW5zdGFuY2VUeXBlPFR5cGU+fSAqLyAodClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVHlwZSB3aXRoIHRoZSBuYW1lICR7bmFtZX0gaGFzIGFscmVhZHkgYmVlbiBkZWZpbmVkIHdpdGggYSBkaWZmZXJlbnQgY29uc3RydWN0b3JgKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtJbnN0YW5jZVR5cGU8VHlwZT59ICovICh0eXBlKVxuICB9XG5cbiAgLyoqXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZV1cbiAgICogQHJldHVybiB7WUFycmF5PFQ+fVxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICBnZXRBcnJheSAobmFtZSA9ICcnKSB7XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7WUFycmF5PFQ+fSAqLyAodGhpcy5nZXQobmFtZSwgWUFycmF5KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW25hbWVdXG4gICAqIEByZXR1cm4ge1lUZXh0fVxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICBnZXRUZXh0IChuYW1lID0gJycpIHtcbiAgICByZXR1cm4gdGhpcy5nZXQobmFtZSwgWVRleHQpXG4gIH1cblxuICAvKipcbiAgICogQHRlbXBsYXRlIFRcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtuYW1lXVxuICAgKiBAcmV0dXJuIHtZTWFwPFQ+fVxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICBnZXRNYXAgKG5hbWUgPSAnJykge1xuICAgIHJldHVybiAvKiogQHR5cGUge1lNYXA8VD59ICovICh0aGlzLmdldChuYW1lLCBZTWFwKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW25hbWVdXG4gICAqIEByZXR1cm4ge1lYbWxFbGVtZW50fVxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICBnZXRYbWxFbGVtZW50IChuYW1lID0gJycpIHtcbiAgICByZXR1cm4gLyoqIEB0eXBlIHtZWG1sRWxlbWVudDx7W2tleTpzdHJpbmddOnN0cmluZ30+fSAqLyAodGhpcy5nZXQobmFtZSwgWVhtbEVsZW1lbnQpKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZV1cbiAgICogQHJldHVybiB7WVhtbEZyYWdtZW50fVxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICBnZXRYbWxGcmFnbWVudCAobmFtZSA9ICcnKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KG5hbWUsIFlYbWxGcmFnbWVudClcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0aGUgZW50aXJlIGRvY3VtZW50IGludG8gYSBqcyBvYmplY3QsIHJlY3Vyc2l2ZWx5IHRyYXZlcnNpbmcgZWFjaCB5anMgdHlwZVxuICAgKiBEb2Vzbid0IGxvZyB0eXBlcyB0aGF0IGhhdmUgbm90IGJlZW4gZGVmaW5lZCAodXNpbmcgeWRvYy5nZXRUeXBlKC4uKSkuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIERvIG5vdCB1c2UgdGhpcyBtZXRob2QgYW5kIHJhdGhlciBjYWxsIHRvSlNPTiBkaXJlY3RseSBvbiB0aGUgc2hhcmVkIHR5cGVzLlxuICAgKlxuICAgKiBAcmV0dXJuIHtPYmplY3Q8c3RyaW5nLCBhbnk+fVxuICAgKi9cbiAgdG9KU09OICgpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZywgYW55Pn1cbiAgICAgKi9cbiAgICBjb25zdCBkb2MgPSB7fVxuXG4gICAgdGhpcy5zaGFyZS5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICBkb2Nba2V5XSA9IHZhbHVlLnRvSlNPTigpXG4gICAgfSlcblxuICAgIHJldHVybiBkb2NcbiAgfVxuXG4gIC8qKlxuICAgKiBFbWl0IGBkZXN0cm95YCBldmVudCBhbmQgdW5yZWdpc3RlciBhbGwgZXZlbnQgaGFuZGxlcnMuXG4gICAqL1xuICBkZXN0cm95ICgpIHtcbiAgICB0aGlzLmlzRGVzdHJveWVkID0gdHJ1ZVxuICAgIGFycmF5LmZyb20odGhpcy5zdWJkb2NzKS5mb3JFYWNoKHN1YmRvYyA9PiBzdWJkb2MuZGVzdHJveSgpKVxuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9pdGVtXG4gICAgaWYgKGl0ZW0gIT09IG51bGwpIHtcbiAgICAgIHRoaXMuX2l0ZW0gPSBudWxsXG4gICAgICBjb25zdCBjb250ZW50ID0gLyoqIEB0eXBlIHtDb250ZW50RG9jfSAqLyAoaXRlbS5jb250ZW50KVxuICAgICAgY29udGVudC5kb2MgPSBuZXcgRG9jKHsgZ3VpZDogdGhpcy5ndWlkLCAuLi5jb250ZW50Lm9wdHMsIHNob3VsZExvYWQ6IGZhbHNlIH0pXG4gICAgICBjb250ZW50LmRvYy5faXRlbSA9IGl0ZW1cbiAgICAgIHRyYW5zYWN0KC8qKiBAdHlwZSB7YW55fSAqLyAoaXRlbSkucGFyZW50LmRvYywgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICBjb25zdCBkb2MgPSBjb250ZW50LmRvY1xuICAgICAgICBpZiAoIWl0ZW0uZGVsZXRlZCkge1xuICAgICAgICAgIHRyYW5zYWN0aW9uLnN1YmRvY3NBZGRlZC5hZGQoZG9jKVxuICAgICAgICB9XG4gICAgICAgIHRyYW5zYWN0aW9uLnN1YmRvY3NSZW1vdmVkLmFkZCh0aGlzKVxuICAgICAgfSwgbnVsbCwgdHJ1ZSlcbiAgICB9XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHRoaXMuZW1pdCgnZGVzdHJveWVkJywgW3RydWVdKSAvLyBERVBSRUNBVEVEIVxuICAgIHRoaXMuZW1pdCgnZGVzdHJveScsIFt0aGlzXSlcbiAgICBzdXBlci5kZXN0cm95KClcbiAgfVxufVxuIiwgImltcG9ydCAqIGFzIGJ1ZmZlciBmcm9tICdsaWIwL2J1ZmZlcidcbmltcG9ydCAqIGFzIGRlY29kaW5nIGZyb20gJ2xpYjAvZGVjb2RpbmcnXG5pbXBvcnQge1xuICBJRCwgY3JlYXRlSURcbn0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJ1xuXG5leHBvcnQgY2xhc3MgRFNEZWNvZGVyVjEge1xuICAvKipcbiAgICogQHBhcmFtIHtkZWNvZGluZy5EZWNvZGVyfSBkZWNvZGVyXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoZGVjb2Rlcikge1xuICAgIHRoaXMucmVzdERlY29kZXIgPSBkZWNvZGVyXG4gIH1cblxuICByZXNldERzQ3VyVmFsICgpIHtcbiAgICAvLyBub3BcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICByZWFkRHNDbG9jayAoKSB7XG4gICAgcmV0dXJuIGRlY29kaW5nLnJlYWRWYXJVaW50KHRoaXMucmVzdERlY29kZXIpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgcmVhZERzTGVuICgpIHtcbiAgICByZXR1cm4gZGVjb2RpbmcucmVhZFZhclVpbnQodGhpcy5yZXN0RGVjb2RlcilcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgVXBkYXRlRGVjb2RlclYxIGV4dGVuZHMgRFNEZWNvZGVyVjEge1xuICAvKipcbiAgICogQHJldHVybiB7SUR9XG4gICAqL1xuICByZWFkTGVmdElEICgpIHtcbiAgICByZXR1cm4gY3JlYXRlSUQoZGVjb2RpbmcucmVhZFZhclVpbnQodGhpcy5yZXN0RGVjb2RlciksIGRlY29kaW5nLnJlYWRWYXJVaW50KHRoaXMucmVzdERlY29kZXIpKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0lEfVxuICAgKi9cbiAgcmVhZFJpZ2h0SUQgKCkge1xuICAgIHJldHVybiBjcmVhdGVJRChkZWNvZGluZy5yZWFkVmFyVWludCh0aGlzLnJlc3REZWNvZGVyKSwgZGVjb2RpbmcucmVhZFZhclVpbnQodGhpcy5yZXN0RGVjb2RlcikpXG4gIH1cblxuICAvKipcbiAgICogUmVhZCB0aGUgbmV4dCBjbGllbnQgaWQuXG4gICAqIFVzZSB0aGlzIGluIGZhdm9yIG9mIHJlYWRJRCB3aGVuZXZlciBwb3NzaWJsZSB0byByZWR1Y2UgdGhlIG51bWJlciBvZiBvYmplY3RzIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkQ2xpZW50ICgpIHtcbiAgICByZXR1cm4gZGVjb2RpbmcucmVhZFZhclVpbnQodGhpcy5yZXN0RGVjb2RlcilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IGluZm8gQW4gdW5zaWduZWQgOC1iaXQgaW50ZWdlclxuICAgKi9cbiAgcmVhZEluZm8gKCkge1xuICAgIHJldHVybiBkZWNvZGluZy5yZWFkVWludDgodGhpcy5yZXN0RGVjb2RlcilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICByZWFkU3RyaW5nICgpIHtcbiAgICByZXR1cm4gZGVjb2RpbmcucmVhZFZhclN0cmluZyh0aGlzLnJlc3REZWNvZGVyKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGlzS2V5XG4gICAqL1xuICByZWFkUGFyZW50SW5mbyAoKSB7XG4gICAgcmV0dXJuIGRlY29kaW5nLnJlYWRWYXJVaW50KHRoaXMucmVzdERlY29kZXIpID09PSAxXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfSBpbmZvIEFuIHVuc2lnbmVkIDgtYml0IGludGVnZXJcbiAgICovXG4gIHJlYWRUeXBlUmVmICgpIHtcbiAgICByZXR1cm4gZGVjb2RpbmcucmVhZFZhclVpbnQodGhpcy5yZXN0RGVjb2RlcilcbiAgfVxuXG4gIC8qKlxuICAgKiBXcml0ZSBsZW4gb2YgYSBzdHJ1Y3QgLSB3ZWxsIHN1aXRlZCBmb3IgT3B0IFJMRSBlbmNvZGVyLlxuICAgKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9IGxlblxuICAgKi9cbiAgcmVhZExlbiAoKSB7XG4gICAgcmV0dXJuIGRlY29kaW5nLnJlYWRWYXJVaW50KHRoaXMucmVzdERlY29kZXIpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7YW55fVxuICAgKi9cbiAgcmVhZEFueSAoKSB7XG4gICAgcmV0dXJuIGRlY29kaW5nLnJlYWRBbnkodGhpcy5yZXN0RGVjb2RlcilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICAgKi9cbiAgcmVhZEJ1ZiAoKSB7XG4gICAgcmV0dXJuIGJ1ZmZlci5jb3B5VWludDhBcnJheShkZWNvZGluZy5yZWFkVmFyVWludDhBcnJheSh0aGlzLnJlc3REZWNvZGVyKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBMZWdhY3kgaW1wbGVtZW50YXRpb24gdXNlcyBKU09OIHBhcnNlLiBXZSB1c2UgYW55LWRlY29kaW5nIGluIHYyLlxuICAgKlxuICAgKiBAcmV0dXJuIHthbnl9XG4gICAqL1xuICByZWFkSlNPTiAoKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoZGVjb2RpbmcucmVhZFZhclN0cmluZyh0aGlzLnJlc3REZWNvZGVyKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICByZWFkS2V5ICgpIHtcbiAgICByZXR1cm4gZGVjb2RpbmcucmVhZFZhclN0cmluZyh0aGlzLnJlc3REZWNvZGVyKVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEU0RlY29kZXJWMiB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge2RlY29kaW5nLkRlY29kZXJ9IGRlY29kZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yIChkZWNvZGVyKSB7XG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICB0aGlzLmRzQ3VyclZhbCA9IDBcbiAgICB0aGlzLnJlc3REZWNvZGVyID0gZGVjb2RlclxuICB9XG5cbiAgcmVzZXREc0N1clZhbCAoKSB7XG4gICAgdGhpcy5kc0N1cnJWYWwgPSAwXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgcmVhZERzQ2xvY2sgKCkge1xuICAgIHRoaXMuZHNDdXJyVmFsICs9IGRlY29kaW5nLnJlYWRWYXJVaW50KHRoaXMucmVzdERlY29kZXIpXG4gICAgcmV0dXJuIHRoaXMuZHNDdXJyVmFsXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgcmVhZERzTGVuICgpIHtcbiAgICBjb25zdCBkaWZmID0gZGVjb2RpbmcucmVhZFZhclVpbnQodGhpcy5yZXN0RGVjb2RlcikgKyAxXG4gICAgdGhpcy5kc0N1cnJWYWwgKz0gZGlmZlxuICAgIHJldHVybiBkaWZmXG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFVwZGF0ZURlY29kZXJWMiBleHRlbmRzIERTRGVjb2RlclYyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7ZGVjb2RpbmcuRGVjb2Rlcn0gZGVjb2RlclxuICAgKi9cbiAgY29uc3RydWN0b3IgKGRlY29kZXIpIHtcbiAgICBzdXBlcihkZWNvZGVyKVxuICAgIC8qKlxuICAgICAqIExpc3Qgb2YgY2FjaGVkIGtleXMuIElmIHRoZSBrZXlzW2lkXSBkb2VzIG5vdCBleGlzdCwgd2UgcmVhZCBhIG5ldyBrZXlcbiAgICAgKiBmcm9tIHN0cmluZ0VuY29kZXIgYW5kIHB1c2ggaXQgdG8ga2V5cy5cbiAgICAgKlxuICAgICAqIEB0eXBlIHtBcnJheTxzdHJpbmc+fVxuICAgICAqL1xuICAgIHRoaXMua2V5cyA9IFtdXG4gICAgZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2RlcikgLy8gcmVhZCBmZWF0dXJlIGZsYWcgLSBjdXJyZW50bHkgdW51c2VkXG4gICAgdGhpcy5rZXlDbG9ja0RlY29kZXIgPSBuZXcgZGVjb2RpbmcuSW50RGlmZk9wdFJsZURlY29kZXIoZGVjb2RpbmcucmVhZFZhclVpbnQ4QXJyYXkoZGVjb2RlcikpXG4gICAgdGhpcy5jbGllbnREZWNvZGVyID0gbmV3IGRlY29kaW5nLlVpbnRPcHRSbGVEZWNvZGVyKGRlY29kaW5nLnJlYWRWYXJVaW50OEFycmF5KGRlY29kZXIpKVxuICAgIHRoaXMubGVmdENsb2NrRGVjb2RlciA9IG5ldyBkZWNvZGluZy5JbnREaWZmT3B0UmxlRGVjb2RlcihkZWNvZGluZy5yZWFkVmFyVWludDhBcnJheShkZWNvZGVyKSlcbiAgICB0aGlzLnJpZ2h0Q2xvY2tEZWNvZGVyID0gbmV3IGRlY29kaW5nLkludERpZmZPcHRSbGVEZWNvZGVyKGRlY29kaW5nLnJlYWRWYXJVaW50OEFycmF5KGRlY29kZXIpKVxuICAgIHRoaXMuaW5mb0RlY29kZXIgPSBuZXcgZGVjb2RpbmcuUmxlRGVjb2RlcihkZWNvZGluZy5yZWFkVmFyVWludDhBcnJheShkZWNvZGVyKSwgZGVjb2RpbmcucmVhZFVpbnQ4KVxuICAgIHRoaXMuc3RyaW5nRGVjb2RlciA9IG5ldyBkZWNvZGluZy5TdHJpbmdEZWNvZGVyKGRlY29kaW5nLnJlYWRWYXJVaW50OEFycmF5KGRlY29kZXIpKVxuICAgIHRoaXMucGFyZW50SW5mb0RlY29kZXIgPSBuZXcgZGVjb2RpbmcuUmxlRGVjb2RlcihkZWNvZGluZy5yZWFkVmFyVWludDhBcnJheShkZWNvZGVyKSwgZGVjb2RpbmcucmVhZFVpbnQ4KVxuICAgIHRoaXMudHlwZVJlZkRlY29kZXIgPSBuZXcgZGVjb2RpbmcuVWludE9wdFJsZURlY29kZXIoZGVjb2RpbmcucmVhZFZhclVpbnQ4QXJyYXkoZGVjb2RlcikpXG4gICAgdGhpcy5sZW5EZWNvZGVyID0gbmV3IGRlY29kaW5nLlVpbnRPcHRSbGVEZWNvZGVyKGRlY29kaW5nLnJlYWRWYXJVaW50OEFycmF5KGRlY29kZXIpKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0lEfVxuICAgKi9cbiAgcmVhZExlZnRJRCAoKSB7XG4gICAgcmV0dXJuIG5ldyBJRCh0aGlzLmNsaWVudERlY29kZXIucmVhZCgpLCB0aGlzLmxlZnRDbG9ja0RlY29kZXIucmVhZCgpKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0lEfVxuICAgKi9cbiAgcmVhZFJpZ2h0SUQgKCkge1xuICAgIHJldHVybiBuZXcgSUQodGhpcy5jbGllbnREZWNvZGVyLnJlYWQoKSwgdGhpcy5yaWdodENsb2NrRGVjb2Rlci5yZWFkKCkpXG4gIH1cblxuICAvKipcbiAgICogUmVhZCB0aGUgbmV4dCBjbGllbnQgaWQuXG4gICAqIFVzZSB0aGlzIGluIGZhdm9yIG9mIHJlYWRJRCB3aGVuZXZlciBwb3NzaWJsZSB0byByZWR1Y2UgdGhlIG51bWJlciBvZiBvYmplY3RzIGNyZWF0ZWQuXG4gICAqL1xuICByZWFkQ2xpZW50ICgpIHtcbiAgICByZXR1cm4gdGhpcy5jbGllbnREZWNvZGVyLnJlYWQoKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn0gaW5mbyBBbiB1bnNpZ25lZCA4LWJpdCBpbnRlZ2VyXG4gICAqL1xuICByZWFkSW5mbyAoKSB7XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7bnVtYmVyfSAqLyAodGhpcy5pbmZvRGVjb2Rlci5yZWFkKCkpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgcmVhZFN0cmluZyAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RyaW5nRGVjb2Rlci5yZWFkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgcmVhZFBhcmVudEluZm8gKCkge1xuICAgIHJldHVybiB0aGlzLnBhcmVudEluZm9EZWNvZGVyLnJlYWQoKSA9PT0gMVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn0gQW4gdW5zaWduZWQgOC1iaXQgaW50ZWdlclxuICAgKi9cbiAgcmVhZFR5cGVSZWYgKCkge1xuICAgIHJldHVybiB0aGlzLnR5cGVSZWZEZWNvZGVyLnJlYWQoKVxuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlIGxlbiBvZiBhIHN0cnVjdCAtIHdlbGwgc3VpdGVkIGZvciBPcHQgUkxFIGVuY29kZXIuXG4gICAqXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIHJlYWRMZW4gKCkge1xuICAgIHJldHVybiB0aGlzLmxlbkRlY29kZXIucmVhZCgpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7YW55fVxuICAgKi9cbiAgcmVhZEFueSAoKSB7XG4gICAgcmV0dXJuIGRlY29kaW5nLnJlYWRBbnkodGhpcy5yZXN0RGVjb2RlcilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICAgKi9cbiAgcmVhZEJ1ZiAoKSB7XG4gICAgcmV0dXJuIGRlY29kaW5nLnJlYWRWYXJVaW50OEFycmF5KHRoaXMucmVzdERlY29kZXIpXG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyBtYWlubHkgaGVyZSBmb3IgbGVnYWN5IHB1cnBvc2VzLlxuICAgKlxuICAgKiBJbml0aWFsIHdlIGluY29kZWQgb2JqZWN0cyB1c2luZyBKU09OLiBOb3cgd2UgdXNlIHRoZSBtdWNoIGZhc3RlciBsaWIwL2FueS1lbmNvZGVyLiBUaGlzIG1ldGhvZCBtYWlubHkgZXhpc3RzIGZvciBsZWdhY3kgcHVycG9zZXMgZm9yIHRoZSB2MSBlbmNvZGVyLlxuICAgKlxuICAgKiBAcmV0dXJuIHthbnl9XG4gICAqL1xuICByZWFkSlNPTiAoKSB7XG4gICAgcmV0dXJuIGRlY29kaW5nLnJlYWRBbnkodGhpcy5yZXN0RGVjb2RlcilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICByZWFkS2V5ICgpIHtcbiAgICBjb25zdCBrZXlDbG9jayA9IHRoaXMua2V5Q2xvY2tEZWNvZGVyLnJlYWQoKVxuICAgIGlmIChrZXlDbG9jayA8IHRoaXMua2V5cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB0aGlzLmtleXNba2V5Q2xvY2tdXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGtleSA9IHRoaXMuc3RyaW5nRGVjb2Rlci5yZWFkKClcbiAgICAgIHRoaXMua2V5cy5wdXNoKGtleSlcbiAgICAgIHJldHVybiBrZXlcbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQgKiBhcyBlcnJvciBmcm9tICdsaWIwL2Vycm9yJ1xuaW1wb3J0ICogYXMgZW5jb2RpbmcgZnJvbSAnbGliMC9lbmNvZGluZydcblxuaW1wb3J0IHtcbiAgSUQgLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbmV4cG9ydCBjbGFzcyBEU0VuY29kZXJWMSB7XG4gIGNvbnN0cnVjdG9yICgpIHtcbiAgICB0aGlzLnJlc3RFbmNvZGVyID0gZW5jb2RpbmcuY3JlYXRlRW5jb2RlcigpXG4gIH1cblxuICB0b1VpbnQ4QXJyYXkgKCkge1xuICAgIHJldHVybiBlbmNvZGluZy50b1VpbnQ4QXJyYXkodGhpcy5yZXN0RW5jb2RlcilcbiAgfVxuXG4gIHJlc2V0RHNDdXJWYWwgKCkge1xuICAgIC8vIG5vcFxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjbG9ja1xuICAgKi9cbiAgd3JpdGVEc0Nsb2NrIChjbG9jaykge1xuICAgIGVuY29kaW5nLndyaXRlVmFyVWludCh0aGlzLnJlc3RFbmNvZGVyLCBjbG9jaylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gbGVuXG4gICAqL1xuICB3cml0ZURzTGVuIChsZW4pIHtcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQodGhpcy5yZXN0RW5jb2RlciwgbGVuKVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBVcGRhdGVFbmNvZGVyVjEgZXh0ZW5kcyBEU0VuY29kZXJWMSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0lEfSBpZFxuICAgKi9cbiAgd3JpdGVMZWZ0SUQgKGlkKSB7XG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KHRoaXMucmVzdEVuY29kZXIsIGlkLmNsaWVudClcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQodGhpcy5yZXN0RW5jb2RlciwgaWQuY2xvY2spXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtJRH0gaWRcbiAgICovXG4gIHdyaXRlUmlnaHRJRCAoaWQpIHtcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQodGhpcy5yZXN0RW5jb2RlciwgaWQuY2xpZW50KVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludCh0aGlzLnJlc3RFbmNvZGVyLCBpZC5jbG9jaylcbiAgfVxuXG4gIC8qKlxuICAgKiBVc2Ugd3JpdGVDbGllbnQgYW5kIHdyaXRlQ2xvY2sgaW5zdGVhZCBvZiB3cml0ZUlEIGlmIHBvc3NpYmxlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gY2xpZW50XG4gICAqL1xuICB3cml0ZUNsaWVudCAoY2xpZW50KSB7XG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KHRoaXMucmVzdEVuY29kZXIsIGNsaWVudClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5mbyBBbiB1bnNpZ25lZCA4LWJpdCBpbnRlZ2VyXG4gICAqL1xuICB3cml0ZUluZm8gKGluZm8pIHtcbiAgICBlbmNvZGluZy53cml0ZVVpbnQ4KHRoaXMucmVzdEVuY29kZXIsIGluZm8pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHNcbiAgICovXG4gIHdyaXRlU3RyaW5nIChzKSB7XG4gICAgZW5jb2Rpbmcud3JpdGVWYXJTdHJpbmcodGhpcy5yZXN0RW5jb2RlciwgcylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGlzWUtleVxuICAgKi9cbiAgd3JpdGVQYXJlbnRJbmZvIChpc1lLZXkpIHtcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQodGhpcy5yZXN0RW5jb2RlciwgaXNZS2V5ID8gMSA6IDApXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZm8gQW4gdW5zaWduZWQgOC1iaXQgaW50ZWdlclxuICAgKi9cbiAgd3JpdGVUeXBlUmVmIChpbmZvKSB7XG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KHRoaXMucmVzdEVuY29kZXIsIGluZm8pXG4gIH1cblxuICAvKipcbiAgICogV3JpdGUgbGVuIG9mIGEgc3RydWN0IC0gd2VsbCBzdWl0ZWQgZm9yIE9wdCBSTEUgZW5jb2Rlci5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IGxlblxuICAgKi9cbiAgd3JpdGVMZW4gKGxlbikge1xuICAgIGVuY29kaW5nLndyaXRlVmFyVWludCh0aGlzLnJlc3RFbmNvZGVyLCBsZW4pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHthbnl9IGFueVxuICAgKi9cbiAgd3JpdGVBbnkgKGFueSkge1xuICAgIGVuY29kaW5nLndyaXRlQW55KHRoaXMucmVzdEVuY29kZXIsIGFueSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZlxuICAgKi9cbiAgd3JpdGVCdWYgKGJ1Zikge1xuICAgIGVuY29kaW5nLndyaXRlVmFyVWludDhBcnJheSh0aGlzLnJlc3RFbmNvZGVyLCBidWYpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHthbnl9IGVtYmVkXG4gICAqL1xuICB3cml0ZUpTT04gKGVtYmVkKSB7XG4gICAgZW5jb2Rpbmcud3JpdGVWYXJTdHJpbmcodGhpcy5yZXN0RW5jb2RlciwgSlNPTi5zdHJpbmdpZnkoZW1iZWQpKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAgICovXG4gIHdyaXRlS2V5IChrZXkpIHtcbiAgICBlbmNvZGluZy53cml0ZVZhclN0cmluZyh0aGlzLnJlc3RFbmNvZGVyLCBrZXkpXG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIERTRW5jb2RlclYyIHtcbiAgY29uc3RydWN0b3IgKCkge1xuICAgIHRoaXMucmVzdEVuY29kZXIgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKCkgLy8gZW5jb2RlcyBhbGwgdGhlIHJlc3QgLyBub24tb3B0aW1pemVkXG4gICAgdGhpcy5kc0N1cnJWYWwgPSAwXG4gIH1cblxuICB0b1VpbnQ4QXJyYXkgKCkge1xuICAgIHJldHVybiBlbmNvZGluZy50b1VpbnQ4QXJyYXkodGhpcy5yZXN0RW5jb2RlcilcbiAgfVxuXG4gIHJlc2V0RHNDdXJWYWwgKCkge1xuICAgIHRoaXMuZHNDdXJyVmFsID0gMFxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjbG9ja1xuICAgKi9cbiAgd3JpdGVEc0Nsb2NrIChjbG9jaykge1xuICAgIGNvbnN0IGRpZmYgPSBjbG9jayAtIHRoaXMuZHNDdXJyVmFsXG4gICAgdGhpcy5kc0N1cnJWYWwgPSBjbG9ja1xuICAgIGVuY29kaW5nLndyaXRlVmFyVWludCh0aGlzLnJlc3RFbmNvZGVyLCBkaWZmKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5cbiAgICovXG4gIHdyaXRlRHNMZW4gKGxlbikge1xuICAgIGlmIChsZW4gPT09IDApIHtcbiAgICAgIGVycm9yLnVuZXhwZWN0ZWRDYXNlKClcbiAgICB9XG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KHRoaXMucmVzdEVuY29kZXIsIGxlbiAtIDEpXG4gICAgdGhpcy5kc0N1cnJWYWwgKz0gbGVuXG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFVwZGF0ZUVuY29kZXJWMiBleHRlbmRzIERTRW5jb2RlclYyIHtcbiAgY29uc3RydWN0b3IgKCkge1xuICAgIHN1cGVyKClcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7TWFwPHN0cmluZyxudW1iZXI+fVxuICAgICAqL1xuICAgIHRoaXMua2V5TWFwID0gbmV3IE1hcCgpXG4gICAgLyoqXG4gICAgICogUmVmZXJzIHRvIHRoZSBuZXh0IHVuaXF1ZSBrZXktaWRlbnRpZmllciB0byBtZSB1c2VkLlxuICAgICAqIFNlZSB3cml0ZUtleSBtZXRob2QgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMua2V5Q2xvY2sgPSAwXG4gICAgdGhpcy5rZXlDbG9ja0VuY29kZXIgPSBuZXcgZW5jb2RpbmcuSW50RGlmZk9wdFJsZUVuY29kZXIoKVxuICAgIHRoaXMuY2xpZW50RW5jb2RlciA9IG5ldyBlbmNvZGluZy5VaW50T3B0UmxlRW5jb2RlcigpXG4gICAgdGhpcy5sZWZ0Q2xvY2tFbmNvZGVyID0gbmV3IGVuY29kaW5nLkludERpZmZPcHRSbGVFbmNvZGVyKClcbiAgICB0aGlzLnJpZ2h0Q2xvY2tFbmNvZGVyID0gbmV3IGVuY29kaW5nLkludERpZmZPcHRSbGVFbmNvZGVyKClcbiAgICB0aGlzLmluZm9FbmNvZGVyID0gbmV3IGVuY29kaW5nLlJsZUVuY29kZXIoZW5jb2Rpbmcud3JpdGVVaW50OClcbiAgICB0aGlzLnN0cmluZ0VuY29kZXIgPSBuZXcgZW5jb2RpbmcuU3RyaW5nRW5jb2RlcigpXG4gICAgdGhpcy5wYXJlbnRJbmZvRW5jb2RlciA9IG5ldyBlbmNvZGluZy5SbGVFbmNvZGVyKGVuY29kaW5nLndyaXRlVWludDgpXG4gICAgdGhpcy50eXBlUmVmRW5jb2RlciA9IG5ldyBlbmNvZGluZy5VaW50T3B0UmxlRW5jb2RlcigpXG4gICAgdGhpcy5sZW5FbmNvZGVyID0gbmV3IGVuY29kaW5nLlVpbnRPcHRSbGVFbmNvZGVyKClcbiAgfVxuXG4gIHRvVWludDhBcnJheSAoKSB7XG4gICAgY29uc3QgZW5jb2RlciA9IGVuY29kaW5nLmNyZWF0ZUVuY29kZXIoKVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLCAwKSAvLyB0aGlzIGlzIGEgZmVhdHVyZSBmbGFnIHRoYXQgd2UgbWlnaHQgdXNlIGluIHRoZSBmdXR1cmVcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQ4QXJyYXkoZW5jb2RlciwgdGhpcy5rZXlDbG9ja0VuY29kZXIudG9VaW50OEFycmF5KCkpXG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50OEFycmF5KGVuY29kZXIsIHRoaXMuY2xpZW50RW5jb2Rlci50b1VpbnQ4QXJyYXkoKSlcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQ4QXJyYXkoZW5jb2RlciwgdGhpcy5sZWZ0Q2xvY2tFbmNvZGVyLnRvVWludDhBcnJheSgpKVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludDhBcnJheShlbmNvZGVyLCB0aGlzLnJpZ2h0Q2xvY2tFbmNvZGVyLnRvVWludDhBcnJheSgpKVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludDhBcnJheShlbmNvZGVyLCBlbmNvZGluZy50b1VpbnQ4QXJyYXkodGhpcy5pbmZvRW5jb2RlcikpXG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50OEFycmF5KGVuY29kZXIsIHRoaXMuc3RyaW5nRW5jb2Rlci50b1VpbnQ4QXJyYXkoKSlcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQ4QXJyYXkoZW5jb2RlciwgZW5jb2RpbmcudG9VaW50OEFycmF5KHRoaXMucGFyZW50SW5mb0VuY29kZXIpKVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludDhBcnJheShlbmNvZGVyLCB0aGlzLnR5cGVSZWZFbmNvZGVyLnRvVWludDhBcnJheSgpKVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludDhBcnJheShlbmNvZGVyLCB0aGlzLmxlbkVuY29kZXIudG9VaW50OEFycmF5KCkpXG4gICAgLy8gQG5vdGUgVGhlIHJlc3QgZW5jb2RlciBpcyBhcHBlbmRlZCEgKG5vdGUgdGhlIG1pc3NpbmcgdmFyKVxuICAgIGVuY29kaW5nLndyaXRlVWludDhBcnJheShlbmNvZGVyLCBlbmNvZGluZy50b1VpbnQ4QXJyYXkodGhpcy5yZXN0RW5jb2RlcikpXG4gICAgcmV0dXJuIGVuY29kaW5nLnRvVWludDhBcnJheShlbmNvZGVyKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SUR9IGlkXG4gICAqL1xuICB3cml0ZUxlZnRJRCAoaWQpIHtcbiAgICB0aGlzLmNsaWVudEVuY29kZXIud3JpdGUoaWQuY2xpZW50KVxuICAgIHRoaXMubGVmdENsb2NrRW5jb2Rlci53cml0ZShpZC5jbG9jaylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0lEfSBpZFxuICAgKi9cbiAgd3JpdGVSaWdodElEIChpZCkge1xuICAgIHRoaXMuY2xpZW50RW5jb2Rlci53cml0ZShpZC5jbGllbnQpXG4gICAgdGhpcy5yaWdodENsb2NrRW5jb2Rlci53cml0ZShpZC5jbG9jaylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gY2xpZW50XG4gICAqL1xuICB3cml0ZUNsaWVudCAoY2xpZW50KSB7XG4gICAgdGhpcy5jbGllbnRFbmNvZGVyLndyaXRlKGNsaWVudClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5mbyBBbiB1bnNpZ25lZCA4LWJpdCBpbnRlZ2VyXG4gICAqL1xuICB3cml0ZUluZm8gKGluZm8pIHtcbiAgICB0aGlzLmluZm9FbmNvZGVyLndyaXRlKGluZm8pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHNcbiAgICovXG4gIHdyaXRlU3RyaW5nIChzKSB7XG4gICAgdGhpcy5zdHJpbmdFbmNvZGVyLndyaXRlKHMpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtib29sZWFufSBpc1lLZXlcbiAgICovXG4gIHdyaXRlUGFyZW50SW5mbyAoaXNZS2V5KSB7XG4gICAgdGhpcy5wYXJlbnRJbmZvRW5jb2Rlci53cml0ZShpc1lLZXkgPyAxIDogMClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5mbyBBbiB1bnNpZ25lZCA4LWJpdCBpbnRlZ2VyXG4gICAqL1xuICB3cml0ZVR5cGVSZWYgKGluZm8pIHtcbiAgICB0aGlzLnR5cGVSZWZFbmNvZGVyLndyaXRlKGluZm8pXG4gIH1cblxuICAvKipcbiAgICogV3JpdGUgbGVuIG9mIGEgc3RydWN0IC0gd2VsbCBzdWl0ZWQgZm9yIE9wdCBSTEUgZW5jb2Rlci5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IGxlblxuICAgKi9cbiAgd3JpdGVMZW4gKGxlbikge1xuICAgIHRoaXMubGVuRW5jb2Rlci53cml0ZShsZW4pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHthbnl9IGFueVxuICAgKi9cbiAgd3JpdGVBbnkgKGFueSkge1xuICAgIGVuY29kaW5nLndyaXRlQW55KHRoaXMucmVzdEVuY29kZXIsIGFueSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZlxuICAgKi9cbiAgd3JpdGVCdWYgKGJ1Zikge1xuICAgIGVuY29kaW5nLndyaXRlVmFyVWludDhBcnJheSh0aGlzLnJlc3RFbmNvZGVyLCBidWYpXG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyBtYWlubHkgaGVyZSBmb3IgbGVnYWN5IHB1cnBvc2VzLlxuICAgKlxuICAgKiBJbml0aWFsIHdlIGluY29kZWQgb2JqZWN0cyB1c2luZyBKU09OLiBOb3cgd2UgdXNlIHRoZSBtdWNoIGZhc3RlciBsaWIwL2FueS1lbmNvZGVyLiBUaGlzIG1ldGhvZCBtYWlubHkgZXhpc3RzIGZvciBsZWdhY3kgcHVycG9zZXMgZm9yIHRoZSB2MSBlbmNvZGVyLlxuICAgKlxuICAgKiBAcGFyYW0ge2FueX0gZW1iZWRcbiAgICovXG4gIHdyaXRlSlNPTiAoZW1iZWQpIHtcbiAgICBlbmNvZGluZy53cml0ZUFueSh0aGlzLnJlc3RFbmNvZGVyLCBlbWJlZClcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9wZXJ0eSBrZXlzIGFyZSBvZnRlbiByZXVzZWQuIEZvciBleGFtcGxlLCBpbiB5LXByb3NlbWlycm9yIHRoZSBrZXkgYGJvbGRgIG1pZ2h0XG4gICAqIG9jY3VyIHZlcnkgb2Z0ZW4uIEZvciBhIDNkIGFwcGxpY2F0aW9uLCB0aGUga2V5IGBwb3NpdGlvbmAgbWlnaHQgb2NjdXIgdmVyeSBvZnRlbi5cbiAgICpcbiAgICogV2UgY2FjaGUgdGhlc2Uga2V5cyBpbiBhIE1hcCBhbmQgcmVmZXIgdG8gdGhlbSB2aWEgYSB1bmlxdWUgbnVtYmVyLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gICAqL1xuICB3cml0ZUtleSAoa2V5KSB7XG4gICAgY29uc3QgY2xvY2sgPSB0aGlzLmtleU1hcC5nZXQoa2V5KVxuICAgIGlmIChjbG9jayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvKipcbiAgICAgICAqIEB0b2RvIHVuY29tbWVudCB0byBpbnRyb2R1Y2UgdGhpcyBmZWF0dXJlIGZpbmFsbHlcbiAgICAgICAqXG4gICAgICAgKiBCYWNrZ3JvdW5kLiBUaGUgQ29udGVudEZvcm1hdCBvYmplY3Qgd2FzIGFsd2F5cyBlbmNvZGVkIHVzaW5nIHdyaXRlS2V5LCBidXQgdGhlIGRlY29kZXIgdXNlZCB0byB1c2UgcmVhZFN0cmluZy5cbiAgICAgICAqIEZ1cnRoZXJtb3JlLCBJIGZvcmdvdCB0byBzZXQgdGhlIGtleWNsb2NrLiBTbyBldmVyeXRoaW5nIHdhcyB3b3JraW5nIGZpbmUuXG4gICAgICAgKlxuICAgICAgICogSG93ZXZlciwgdGhpcyBmZWF0dXJlIGhlcmUgaXMgYmFzaWNhbGx5IHVzZWxlc3MgYXMgaXQgaXMgbm90IGJlaW5nIHVzZWQgKGl0IGFjdHVhbGx5IG9ubHkgY29uc3VtZXMgZXh0cmEgbWVtb3J5KS5cbiAgICAgICAqXG4gICAgICAgKiBJIGRvbid0IGtub3cgeWV0IGhvdyB0byByZWludHJvZHVjZSB0aGlzIGZlYXR1cmUuLlxuICAgICAgICpcbiAgICAgICAqIE9sZGVyIGNsaWVudHMgd29uJ3QgYmUgYWJsZSB0byByZWFkIHVwZGF0ZXMgd2hlbiB3ZSByZWludHJvZHVjZSB0aGlzIGZlYXR1cmUuIFNvIHRoaXMgc2hvdWxkIHByb2JhYmx5IGJlIGRvbmUgdXNpbmcgYSBmbGFnLlxuICAgICAgICpcbiAgICAgICAqL1xuICAgICAgLy8gdGhpcy5rZXlNYXAuc2V0KGtleSwgdGhpcy5rZXlDbG9jaylcbiAgICAgIHRoaXMua2V5Q2xvY2tFbmNvZGVyLndyaXRlKHRoaXMua2V5Q2xvY2srKylcbiAgICAgIHRoaXMuc3RyaW5nRW5jb2Rlci53cml0ZShrZXkpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMua2V5Q2xvY2tFbmNvZGVyLndyaXRlKGNsb2NrKVxuICAgIH1cbiAgfVxufVxuIiwgIi8qKlxuICogQG1vZHVsZSBlbmNvZGluZ1xuICovXG4vKlxuICogV2UgdXNlIHRoZSBmaXJzdCBmaXZlIGJpdHMgaW4gdGhlIGluZm8gZmxhZyBmb3IgZGV0ZXJtaW5pbmcgdGhlIHR5cGUgb2YgdGhlIHN0cnVjdC5cbiAqXG4gKiAwOiBHQ1xuICogMTogSXRlbSB3aXRoIERlbGV0ZWQgY29udGVudFxuICogMjogSXRlbSB3aXRoIEpTT04gY29udGVudFxuICogMzogSXRlbSB3aXRoIEJpbmFyeSBjb250ZW50XG4gKiA0OiBJdGVtIHdpdGggU3RyaW5nIGNvbnRlbnRcbiAqIDU6IEl0ZW0gd2l0aCBFbWJlZCBjb250ZW50IChmb3IgcmljaHRleHQgY29udGVudClcbiAqIDY6IEl0ZW0gd2l0aCBGb3JtYXQgY29udGVudCAoYSBmb3JtYXR0aW5nIG1hcmtlciBmb3IgcmljaHRleHQgY29udGVudClcbiAqIDc6IEl0ZW0gd2l0aCBUeXBlXG4gKi9cblxuaW1wb3J0IHtcbiAgZmluZEluZGV4U1MsXG4gIGdldFN0YXRlLFxuICBjcmVhdGVJRCxcbiAgZ2V0U3RhdGVWZWN0b3IsXG4gIHJlYWRBbmRBcHBseURlbGV0ZVNldCxcbiAgd3JpdGVEZWxldGVTZXQsXG4gIGNyZWF0ZURlbGV0ZVNldEZyb21TdHJ1Y3RTdG9yZSxcbiAgdHJhbnNhY3QsXG4gIHJlYWRJdGVtQ29udGVudCxcbiAgVXBkYXRlRGVjb2RlclYxLFxuICBVcGRhdGVEZWNvZGVyVjIsXG4gIFVwZGF0ZUVuY29kZXJWMSxcbiAgVXBkYXRlRW5jb2RlclYyLFxuICBEU0VuY29kZXJWMixcbiAgRFNEZWNvZGVyVjEsXG4gIERTRW5jb2RlclYxLFxuICBtZXJnZVVwZGF0ZXMsXG4gIG1lcmdlVXBkYXRlc1YyLFxuICBTa2lwLFxuICBkaWZmVXBkYXRlVjIsXG4gIGNvbnZlcnRVcGRhdGVGb3JtYXRWMlRvVjEsXG4gIERTRGVjb2RlclYyLCBEb2MsIFRyYW5zYWN0aW9uLCBHQywgSXRlbSwgU3RydWN0U3RvcmUgLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbmltcG9ydCAqIGFzIGVuY29kaW5nIGZyb20gJ2xpYjAvZW5jb2RpbmcnXG5pbXBvcnQgKiBhcyBkZWNvZGluZyBmcm9tICdsaWIwL2RlY29kaW5nJ1xuaW1wb3J0ICogYXMgYmluYXJ5IGZyb20gJ2xpYjAvYmluYXJ5J1xuaW1wb3J0ICogYXMgbWFwIGZyb20gJ2xpYjAvbWFwJ1xuaW1wb3J0ICogYXMgbWF0aCBmcm9tICdsaWIwL21hdGgnXG5pbXBvcnQgKiBhcyBhcnJheSBmcm9tICdsaWIwL2FycmF5J1xuXG4vKipcbiAqIEBwYXJhbSB7VXBkYXRlRW5jb2RlclYxIHwgVXBkYXRlRW5jb2RlclYyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge0FycmF5PEdDfEl0ZW0+fSBzdHJ1Y3RzIEFsbCBzdHJ1Y3RzIGJ5IGBjbGllbnRgXG4gKiBAcGFyYW0ge251bWJlcn0gY2xpZW50XG4gKiBAcGFyYW0ge251bWJlcn0gY2xvY2sgd3JpdGUgc3RydWN0cyBzdGFydGluZyB3aXRoIGBJRChjbGllbnQsY2xvY2spYFxuICpcbiAqIEBmdW5jdGlvblxuICovXG5jb25zdCB3cml0ZVN0cnVjdHMgPSAoZW5jb2Rlciwgc3RydWN0cywgY2xpZW50LCBjbG9jaykgPT4ge1xuICAvLyB3cml0ZSBmaXJzdCBpZFxuICBjbG9jayA9IG1hdGgubWF4KGNsb2NrLCBzdHJ1Y3RzWzBdLmlkLmNsb2NrKSAvLyBtYWtlIHN1cmUgdGhlIGZpcnN0IGlkIGV4aXN0c1xuICBjb25zdCBzdGFydE5ld1N0cnVjdHMgPSBmaW5kSW5kZXhTUyhzdHJ1Y3RzLCBjbG9jaylcbiAgLy8gd3JpdGUgIyBlbmNvZGVkIHN0cnVjdHNcbiAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIucmVzdEVuY29kZXIsIHN0cnVjdHMubGVuZ3RoIC0gc3RhcnROZXdTdHJ1Y3RzKVxuICBlbmNvZGVyLndyaXRlQ2xpZW50KGNsaWVudClcbiAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIucmVzdEVuY29kZXIsIGNsb2NrKVxuICBjb25zdCBmaXJzdFN0cnVjdCA9IHN0cnVjdHNbc3RhcnROZXdTdHJ1Y3RzXVxuICAvLyB3cml0ZSBmaXJzdCBzdHJ1Y3Qgd2l0aCBhbiBvZmZzZXRcbiAgZmlyc3RTdHJ1Y3Qud3JpdGUoZW5jb2RlciwgY2xvY2sgLSBmaXJzdFN0cnVjdC5pZC5jbG9jaylcbiAgZm9yIChsZXQgaSA9IHN0YXJ0TmV3U3RydWN0cyArIDE7IGkgPCBzdHJ1Y3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgc3RydWN0c1tpXS53cml0ZShlbmNvZGVyLCAwKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtVcGRhdGVFbmNvZGVyVjEgfCBVcGRhdGVFbmNvZGVyVjJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7U3RydWN0U3RvcmV9IHN0b3JlXG4gKiBAcGFyYW0ge01hcDxudW1iZXIsbnVtYmVyPn0gX3NtXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3Qgd3JpdGVDbGllbnRzU3RydWN0cyA9IChlbmNvZGVyLCBzdG9yZSwgX3NtKSA9PiB7XG4gIC8vIHdlIGZpbHRlciBhbGwgdmFsaWQgX3NtIGVudHJpZXMgaW50byBzbVxuICBjb25zdCBzbSA9IG5ldyBNYXAoKVxuICBfc20uZm9yRWFjaCgoY2xvY2ssIGNsaWVudCkgPT4ge1xuICAgIC8vIG9ubHkgd3JpdGUgaWYgbmV3IHN0cnVjdHMgYXJlIGF2YWlsYWJsZVxuICAgIGlmIChnZXRTdGF0ZShzdG9yZSwgY2xpZW50KSA+IGNsb2NrKSB7XG4gICAgICBzbS5zZXQoY2xpZW50LCBjbG9jaylcbiAgICB9XG4gIH0pXG4gIGdldFN0YXRlVmVjdG9yKHN0b3JlKS5mb3JFYWNoKChfY2xvY2ssIGNsaWVudCkgPT4ge1xuICAgIGlmICghX3NtLmhhcyhjbGllbnQpKSB7XG4gICAgICBzbS5zZXQoY2xpZW50LCAwKVxuICAgIH1cbiAgfSlcbiAgLy8gd3JpdGUgIyBzdGF0ZXMgdGhhdCB3ZXJlIHVwZGF0ZWRcbiAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIucmVzdEVuY29kZXIsIHNtLnNpemUpXG4gIC8vIFdyaXRlIGl0ZW1zIHdpdGggaGlnaGVyIGNsaWVudCBpZHMgZmlyc3RcbiAgLy8gVGhpcyBoZWF2aWx5IGltcHJvdmVzIHRoZSBjb25mbGljdCBhbGdvcml0aG0uXG4gIGFycmF5LmZyb20oc20uZW50cmllcygpKS5zb3J0KChhLCBiKSA9PiBiWzBdIC0gYVswXSkuZm9yRWFjaCgoW2NsaWVudCwgY2xvY2tdKSA9PiB7XG4gICAgd3JpdGVTdHJ1Y3RzKGVuY29kZXIsIC8qKiBAdHlwZSB7QXJyYXk8R0N8SXRlbT59ICovIChzdG9yZS5jbGllbnRzLmdldChjbGllbnQpKSwgY2xpZW50LCBjbG9jaylcbiAgfSlcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VwZGF0ZURlY29kZXJWMSB8IFVwZGF0ZURlY29kZXJWMn0gZGVjb2RlciBUaGUgZGVjb2RlciBvYmplY3QgdG8gcmVhZCBkYXRhIGZyb20uXG4gKiBAcGFyYW0ge0RvY30gZG9jXG4gKiBAcmV0dXJuIHtNYXA8bnVtYmVyLCB7IGk6IG51bWJlciwgcmVmczogQXJyYXk8SXRlbSB8IEdDPiB9Pn1cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCByZWFkQ2xpZW50c1N0cnVjdFJlZnMgPSAoZGVjb2RlciwgZG9jKSA9PiB7XG4gIC8qKlxuICAgKiBAdHlwZSB7TWFwPG51bWJlciwgeyBpOiBudW1iZXIsIHJlZnM6IEFycmF5PEl0ZW0gfCBHQz4gfT59XG4gICAqL1xuICBjb25zdCBjbGllbnRSZWZzID0gbWFwLmNyZWF0ZSgpXG4gIGNvbnN0IG51bU9mU3RhdGVVcGRhdGVzID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2Rlci5yZXN0RGVjb2RlcilcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1PZlN0YXRlVXBkYXRlczsgaSsrKSB7XG4gICAgY29uc3QgbnVtYmVyT2ZTdHJ1Y3RzID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2Rlci5yZXN0RGVjb2RlcilcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8R0N8SXRlbT59XG4gICAgICovXG4gICAgY29uc3QgcmVmcyA9IG5ldyBBcnJheShudW1iZXJPZlN0cnVjdHMpXG4gICAgY29uc3QgY2xpZW50ID0gZGVjb2Rlci5yZWFkQ2xpZW50KClcbiAgICBsZXQgY2xvY2sgPSBkZWNvZGluZy5yZWFkVmFyVWludChkZWNvZGVyLnJlc3REZWNvZGVyKVxuICAgIC8vIGNvbnN0IHN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KClcbiAgICBjbGllbnRSZWZzLnNldChjbGllbnQsIHsgaTogMCwgcmVmcyB9KVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZTdHJ1Y3RzOyBpKyspIHtcbiAgICAgIGNvbnN0IGluZm8gPSBkZWNvZGVyLnJlYWRJbmZvKClcbiAgICAgIHN3aXRjaCAoYmluYXJ5LkJJVFM1ICYgaW5mbykge1xuICAgICAgICBjYXNlIDA6IHsgLy8gR0NcbiAgICAgICAgICBjb25zdCBsZW4gPSBkZWNvZGVyLnJlYWRMZW4oKVxuICAgICAgICAgIHJlZnNbaV0gPSBuZXcgR0MoY3JlYXRlSUQoY2xpZW50LCBjbG9jayksIGxlbilcbiAgICAgICAgICBjbG9jayArPSBsZW5cbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMTA6IHsgLy8gU2tpcCBTdHJ1Y3QgKG5vdGhpbmcgdG8gYXBwbHkpXG4gICAgICAgICAgLy8gQHRvZG8gd2UgY291bGQgcmVkdWNlIHRoZSBhbW91bnQgb2YgY2hlY2tzIGJ5IGFkZGluZyBTa2lwIHN0cnVjdCB0byBjbGllbnRSZWZzIHNvIHdlIGtub3cgdGhhdCBzb21ldGhpbmcgaXMgbWlzc2luZy5cbiAgICAgICAgICBjb25zdCBsZW4gPSBkZWNvZGluZy5yZWFkVmFyVWludChkZWNvZGVyLnJlc3REZWNvZGVyKVxuICAgICAgICAgIHJlZnNbaV0gPSBuZXcgU2tpcChjcmVhdGVJRChjbGllbnQsIGNsb2NrKSwgbGVuKVxuICAgICAgICAgIGNsb2NrICs9IGxlblxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDogeyAvLyBJdGVtIHdpdGggY29udGVudFxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFRoZSBvcHRpbWl6ZWQgaW1wbGVtZW50YXRpb24gZG9lc24ndCB1c2UgYW55IHZhcmlhYmxlcyBiZWNhdXNlIGlubGluaW5nIHZhcmlhYmxlcyBpcyBmYXN0ZXIuXG4gICAgICAgICAgICogQmVsb3cgYSBub24tb3B0aW1pemVkIHZlcnNpb24gaXMgc2hvd24gdGhhdCBpbXBsZW1lbnRzIHRoZSBiYXNpYyBhbGdvcml0aG0gd2l0aFxuICAgICAgICAgICAqIGEgZmV3IGNvbW1lbnRzXG4gICAgICAgICAgICovXG4gICAgICAgICAgY29uc3QgY2FudENvcHlQYXJlbnRJbmZvID0gKGluZm8gJiAoYmluYXJ5LkJJVDcgfCBiaW5hcnkuQklUOCkpID09PSAwXG4gICAgICAgICAgLy8gSWYgcGFyZW50ID0gbnVsbCBhbmQgbmVpdGhlciBsZWZ0IG5vciByaWdodCBhcmUgZGVmaW5lZCwgdGhlbiB3ZSBrbm93IHRoYXQgYHBhcmVudGAgaXMgY2hpbGQgb2YgYHlgXG4gICAgICAgICAgLy8gYW5kIHdlIHJlYWQgdGhlIG5leHQgc3RyaW5nIGFzIHBhcmVudFlLZXkuXG4gICAgICAgICAgLy8gSXQgaW5kaWNhdGVzIGhvdyB3ZSBzdG9yZS9yZXRyaWV2ZSBwYXJlbnQgZnJvbSBgeS5zaGFyZWBcbiAgICAgICAgICAvLyBAdHlwZSB7c3RyaW5nfG51bGx9XG4gICAgICAgICAgY29uc3Qgc3RydWN0ID0gbmV3IEl0ZW0oXG4gICAgICAgICAgICBjcmVhdGVJRChjbGllbnQsIGNsb2NrKSxcbiAgICAgICAgICAgIG51bGwsIC8vIGxlZnRcbiAgICAgICAgICAgIChpbmZvICYgYmluYXJ5LkJJVDgpID09PSBiaW5hcnkuQklUOCA/IGRlY29kZXIucmVhZExlZnRJRCgpIDogbnVsbCwgLy8gb3JpZ2luXG4gICAgICAgICAgICBudWxsLCAvLyByaWdodFxuICAgICAgICAgICAgKGluZm8gJiBiaW5hcnkuQklUNykgPT09IGJpbmFyeS5CSVQ3ID8gZGVjb2Rlci5yZWFkUmlnaHRJRCgpIDogbnVsbCwgLy8gcmlnaHQgb3JpZ2luXG4gICAgICAgICAgICBjYW50Q29weVBhcmVudEluZm8gPyAoZGVjb2Rlci5yZWFkUGFyZW50SW5mbygpID8gZG9jLmdldChkZWNvZGVyLnJlYWRTdHJpbmcoKSkgOiBkZWNvZGVyLnJlYWRMZWZ0SUQoKSkgOiBudWxsLCAvLyBwYXJlbnRcbiAgICAgICAgICAgIGNhbnRDb3B5UGFyZW50SW5mbyAmJiAoaW5mbyAmIGJpbmFyeS5CSVQ2KSA9PT0gYmluYXJ5LkJJVDYgPyBkZWNvZGVyLnJlYWRTdHJpbmcoKSA6IG51bGwsIC8vIHBhcmVudFN1YlxuICAgICAgICAgICAgcmVhZEl0ZW1Db250ZW50KGRlY29kZXIsIGluZm8pIC8vIGl0ZW0gY29udGVudFxuICAgICAgICAgIClcbiAgICAgICAgICAvKiBBIG5vbi1vcHRpbWl6ZWQgaW1wbGVtZW50YXRpb24gb2YgdGhlIGFib3ZlIGFsZ29yaXRobTpcblxuICAgICAgICAgIC8vIFRoZSBpdGVtIHRoYXQgd2FzIG9yaWdpbmFsbHkgdG8gdGhlIGxlZnQgb2YgdGhpcyBpdGVtLlxuICAgICAgICAgIGNvbnN0IG9yaWdpbiA9IChpbmZvICYgYmluYXJ5LkJJVDgpID09PSBiaW5hcnkuQklUOCA/IGRlY29kZXIucmVhZExlZnRJRCgpIDogbnVsbFxuICAgICAgICAgIC8vIFRoZSBpdGVtIHRoYXQgd2FzIG9yaWdpbmFsbHkgdG8gdGhlIHJpZ2h0IG9mIHRoaXMgaXRlbS5cbiAgICAgICAgICBjb25zdCByaWdodE9yaWdpbiA9IChpbmZvICYgYmluYXJ5LkJJVDcpID09PSBiaW5hcnkuQklUNyA/IGRlY29kZXIucmVhZFJpZ2h0SUQoKSA6IG51bGxcbiAgICAgICAgICBjb25zdCBjYW50Q29weVBhcmVudEluZm8gPSAoaW5mbyAmIChiaW5hcnkuQklUNyB8IGJpbmFyeS5CSVQ4KSkgPT09IDBcbiAgICAgICAgICBjb25zdCBoYXNQYXJlbnRZS2V5ID0gY2FudENvcHlQYXJlbnRJbmZvID8gZGVjb2Rlci5yZWFkUGFyZW50SW5mbygpIDogZmFsc2VcbiAgICAgICAgICAvLyBJZiBwYXJlbnQgPSBudWxsIGFuZCBuZWl0aGVyIGxlZnQgbm9yIHJpZ2h0IGFyZSBkZWZpbmVkLCB0aGVuIHdlIGtub3cgdGhhdCBgcGFyZW50YCBpcyBjaGlsZCBvZiBgeWBcbiAgICAgICAgICAvLyBhbmQgd2UgcmVhZCB0aGUgbmV4dCBzdHJpbmcgYXMgcGFyZW50WUtleS5cbiAgICAgICAgICAvLyBJdCBpbmRpY2F0ZXMgaG93IHdlIHN0b3JlL3JldHJpZXZlIHBhcmVudCBmcm9tIGB5LnNoYXJlYFxuICAgICAgICAgIC8vIEB0eXBlIHtzdHJpbmd8bnVsbH1cbiAgICAgICAgICBjb25zdCBwYXJlbnRZS2V5ID0gY2FudENvcHlQYXJlbnRJbmZvICYmIGhhc1BhcmVudFlLZXkgPyBkZWNvZGVyLnJlYWRTdHJpbmcoKSA6IG51bGxcblxuICAgICAgICAgIGNvbnN0IHN0cnVjdCA9IG5ldyBJdGVtKFxuICAgICAgICAgICAgY3JlYXRlSUQoY2xpZW50LCBjbG9jayksXG4gICAgICAgICAgICBudWxsLCAvLyBsZWZ0XG4gICAgICAgICAgICBvcmlnaW4sIC8vIG9yaWdpblxuICAgICAgICAgICAgbnVsbCwgLy8gcmlnaHRcbiAgICAgICAgICAgIHJpZ2h0T3JpZ2luLCAvLyByaWdodCBvcmlnaW5cbiAgICAgICAgICAgIGNhbnRDb3B5UGFyZW50SW5mbyAmJiAhaGFzUGFyZW50WUtleSA/IGRlY29kZXIucmVhZExlZnRJRCgpIDogKHBhcmVudFlLZXkgIT09IG51bGwgPyBkb2MuZ2V0KHBhcmVudFlLZXkpIDogbnVsbCksIC8vIHBhcmVudFxuICAgICAgICAgICAgY2FudENvcHlQYXJlbnRJbmZvICYmIChpbmZvICYgYmluYXJ5LkJJVDYpID09PSBiaW5hcnkuQklUNiA/IGRlY29kZXIucmVhZFN0cmluZygpIDogbnVsbCwgLy8gcGFyZW50U3ViXG4gICAgICAgICAgICByZWFkSXRlbUNvbnRlbnQoZGVjb2RlciwgaW5mbykgLy8gaXRlbSBjb250ZW50XG4gICAgICAgICAgKVxuICAgICAgICAgICovXG4gICAgICAgICAgcmVmc1tpXSA9IHN0cnVjdFxuICAgICAgICAgIGNsb2NrICs9IHN0cnVjdC5sZW5ndGhcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBjb25zb2xlLmxvZygndGltZSB0byByZWFkOiAnLCBwZXJmb3JtYW5jZS5ub3coKSAtIHN0YXJ0KSAvLyBAdG9kbyByZW1vdmVcbiAgfVxuICByZXR1cm4gY2xpZW50UmVmc1xufVxuXG4vKipcbiAqIFJlc3VtZSBjb21wdXRpbmcgc3RydWN0cyBnZW5lcmF0ZWQgYnkgc3RydWN0IHJlYWRlcnMuXG4gKlxuICogV2hpbGUgdGhlcmUgaXMgc29tZXRoaW5nIHRvIGRvLCB3ZSBpbnRlZ3JhdGUgc3RydWN0cyBpbiB0aGlzIG9yZGVyXG4gKiAxLiB0b3AgZWxlbWVudCBvbiBzdGFjaywgaWYgc3RhY2sgaXMgbm90IGVtcHR5XG4gKiAyLiBuZXh0IGVsZW1lbnQgZnJvbSBjdXJyZW50IHN0cnVjdCByZWFkZXIgKGlmIGVtcHR5LCB1c2UgbmV4dCBzdHJ1Y3QgcmVhZGVyKVxuICpcbiAqIElmIHN0cnVjdCBjYXVzYWxseSBkZXBlbmRzIG9uIGFub3RoZXIgc3RydWN0IChyZWYubWlzc2luZyksIHdlIHB1dCBuZXh0IHJlYWRlciBvZlxuICogYHJlZi5pZC5jbGllbnRgIG9uIHRvcCBvZiBzdGFjay5cbiAqXG4gKiBBdCBzb21lIHBvaW50IHdlIGZpbmQgYSBzdHJ1Y3QgdGhhdCBoYXMgbm8gY2F1c2FsIGRlcGVuZGVuY2llcyxcbiAqIHRoZW4gd2Ugc3RhcnQgZW1wdHlpbmcgdGhlIHN0YWNrLlxuICpcbiAqIEl0IGlzIG5vdCBwb3NzaWJsZSB0byBoYXZlIGNpcmNsZXM6IGkuZS4gc3RydWN0MSAoZnJvbSBjbGllbnQxKSBkZXBlbmRzIG9uIHN0cnVjdDIgKGZyb20gY2xpZW50MilcbiAqIGRlcGVuZHMgb24gc3RydWN0MyAoZnJvbSBjbGllbnQxKS4gVGhlcmVmb3JlIHRoZSBtYXggc3RhY2sgc2l6ZSBpcyBlcXVhbCB0byBgc3RydWN0UmVhZGVycy5sZW5ndGhgLlxuICpcbiAqIFRoaXMgbWV0aG9kIGlzIGltcGxlbWVudGVkIGluIGEgd2F5IHNvIHRoYXQgd2UgY2FuIHJlc3VtZSBjb21wdXRhdGlvbiBpZiB0aGlzIHVwZGF0ZVxuICogY2F1c2FsbHkgZGVwZW5kcyBvbiBhbm90aGVyIHVwZGF0ZS5cbiAqXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAqIEBwYXJhbSB7TWFwPG51bWJlciwgeyBpOiBudW1iZXIsIHJlZnM6IChHQyB8IEl0ZW0pW10gfT59IGNsaWVudHNTdHJ1Y3RSZWZzXG4gKiBAcmV0dXJuIHsgbnVsbCB8IHsgdXBkYXRlOiBVaW50OEFycmF5LCBtaXNzaW5nOiBNYXA8bnVtYmVyLG51bWJlcj4gfSB9XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5jb25zdCBpbnRlZ3JhdGVTdHJ1Y3RzID0gKHRyYW5zYWN0aW9uLCBzdG9yZSwgY2xpZW50c1N0cnVjdFJlZnMpID0+IHtcbiAgLyoqXG4gICAqIEB0eXBlIHtBcnJheTxJdGVtIHwgR0M+fVxuICAgKi9cbiAgY29uc3Qgc3RhY2sgPSBbXVxuICAvLyBzb3J0IHRoZW0gc28gdGhhdCB3ZSB0YWtlIHRoZSBoaWdoZXIgaWQgZmlyc3QsIGluIGNhc2Ugb2YgY29uZmxpY3RzIHRoZSBsb3dlciBpZCB3aWxsIHByb2JhYmx5IG5vdCBjb25mbGljdCB3aXRoIHRoZSBpZCBmcm9tIHRoZSBoaWdoZXIgdXNlci5cbiAgbGV0IGNsaWVudHNTdHJ1Y3RSZWZzSWRzID0gYXJyYXkuZnJvbShjbGllbnRzU3RydWN0UmVmcy5rZXlzKCkpLnNvcnQoKGEsIGIpID0+IGEgLSBiKVxuICBpZiAoY2xpZW50c1N0cnVjdFJlZnNJZHMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuICBjb25zdCBnZXROZXh0U3RydWN0VGFyZ2V0ID0gKCkgPT4ge1xuICAgIGlmIChjbGllbnRzU3RydWN0UmVmc0lkcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICAgIGxldCBuZXh0U3RydWN0c1RhcmdldCA9IC8qKiBAdHlwZSB7e2k6bnVtYmVyLHJlZnM6QXJyYXk8R0N8SXRlbT59fSAqLyAoY2xpZW50c1N0cnVjdFJlZnMuZ2V0KGNsaWVudHNTdHJ1Y3RSZWZzSWRzW2NsaWVudHNTdHJ1Y3RSZWZzSWRzLmxlbmd0aCAtIDFdKSlcbiAgICB3aGlsZSAobmV4dFN0cnVjdHNUYXJnZXQucmVmcy5sZW5ndGggPT09IG5leHRTdHJ1Y3RzVGFyZ2V0LmkpIHtcbiAgICAgIGNsaWVudHNTdHJ1Y3RSZWZzSWRzLnBvcCgpXG4gICAgICBpZiAoY2xpZW50c1N0cnVjdFJlZnNJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBuZXh0U3RydWN0c1RhcmdldCA9IC8qKiBAdHlwZSB7e2k6bnVtYmVyLHJlZnM6QXJyYXk8R0N8SXRlbT59fSAqLyAoY2xpZW50c1N0cnVjdFJlZnMuZ2V0KGNsaWVudHNTdHJ1Y3RSZWZzSWRzW2NsaWVudHNTdHJ1Y3RSZWZzSWRzLmxlbmd0aCAtIDFdKSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXh0U3RydWN0c1RhcmdldFxuICB9XG4gIGxldCBjdXJTdHJ1Y3RzVGFyZ2V0ID0gZ2V0TmV4dFN0cnVjdFRhcmdldCgpXG4gIGlmIChjdXJTdHJ1Y3RzVGFyZ2V0ID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBAdHlwZSB7U3RydWN0U3RvcmV9XG4gICAqL1xuICBjb25zdCByZXN0U3RydWN0cyA9IG5ldyBTdHJ1Y3RTdG9yZSgpXG4gIGNvbnN0IG1pc3NpbmdTViA9IG5ldyBNYXAoKVxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGNsaWVudFxuICAgKiBAcGFyYW0ge251bWJlcn0gY2xvY2tcbiAgICovXG4gIGNvbnN0IHVwZGF0ZU1pc3NpbmdTdiA9IChjbGllbnQsIGNsb2NrKSA9PiB7XG4gICAgY29uc3QgbWNsb2NrID0gbWlzc2luZ1NWLmdldChjbGllbnQpXG4gICAgaWYgKG1jbG9jayA9PSBudWxsIHx8IG1jbG9jayA+IGNsb2NrKSB7XG4gICAgICBtaXNzaW5nU1Yuc2V0KGNsaWVudCwgY2xvY2spXG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBAdHlwZSB7R0N8SXRlbX1cbiAgICovXG4gIGxldCBzdGFja0hlYWQgPSAvKiogQHR5cGUge2FueX0gKi8gKGN1clN0cnVjdHNUYXJnZXQpLnJlZnNbLyoqIEB0eXBlIHthbnl9ICovIChjdXJTdHJ1Y3RzVGFyZ2V0KS5pKytdXG4gIC8vIGNhY2hpbmcgdGhlIHN0YXRlIGJlY2F1c2UgaXQgaXMgdXNlZCB2ZXJ5IG9mdGVuXG4gIGNvbnN0IHN0YXRlID0gbmV3IE1hcCgpXG5cbiAgY29uc3QgYWRkU3RhY2tUb1Jlc3RTUyA9ICgpID0+IHtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2Ygc3RhY2spIHtcbiAgICAgIGNvbnN0IGNsaWVudCA9IGl0ZW0uaWQuY2xpZW50XG4gICAgICBjb25zdCBpbmFwcGxpY2FibGVJdGVtcyA9IGNsaWVudHNTdHJ1Y3RSZWZzLmdldChjbGllbnQpXG4gICAgICBpZiAoaW5hcHBsaWNhYmxlSXRlbXMpIHtcbiAgICAgICAgLy8gZGVjcmVtZW50IGJlY2F1c2Ugd2Ugd2VyZW4ndCBhYmxlIHRvIGFwcGx5IHByZXZpb3VzIG9wZXJhdGlvblxuICAgICAgICBpbmFwcGxpY2FibGVJdGVtcy5pLS1cbiAgICAgICAgcmVzdFN0cnVjdHMuY2xpZW50cy5zZXQoY2xpZW50LCBpbmFwcGxpY2FibGVJdGVtcy5yZWZzLnNsaWNlKGluYXBwbGljYWJsZUl0ZW1zLmkpKVxuICAgICAgICBjbGllbnRzU3RydWN0UmVmcy5kZWxldGUoY2xpZW50KVxuICAgICAgICBpbmFwcGxpY2FibGVJdGVtcy5pID0gMFxuICAgICAgICBpbmFwcGxpY2FibGVJdGVtcy5yZWZzID0gW11cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGl0ZW0gd2FzIHRoZSBsYXN0IGl0ZW0gb24gY2xpZW50c1N0cnVjdFJlZnMgYW5kIHRoZSBmaWVsZCB3YXMgYWxyZWFkeSBjbGVhcmVkLiBBZGQgaXRlbSB0byByZXN0U3RydWN0cyBhbmQgY29udGludWVcbiAgICAgICAgcmVzdFN0cnVjdHMuY2xpZW50cy5zZXQoY2xpZW50LCBbaXRlbV0pXG4gICAgICB9XG4gICAgICAvLyByZW1vdmUgY2xpZW50IGZyb20gY2xpZW50c1N0cnVjdFJlZnNJZHMgdG8gcHJldmVudCB1c2VycyBmcm9tIGFwcGx5aW5nIHRoZSBzYW1lIHVwZGF0ZSBhZ2FpblxuICAgICAgY2xpZW50c1N0cnVjdFJlZnNJZHMgPSBjbGllbnRzU3RydWN0UmVmc0lkcy5maWx0ZXIoYyA9PiBjICE9PSBjbGllbnQpXG4gICAgfVxuICAgIHN0YWNrLmxlbmd0aCA9IDBcbiAgfVxuXG4gIC8vIGl0ZXJhdGUgb3ZlciBhbGwgc3RydWN0IHJlYWRlcnMgdW50aWwgd2UgYXJlIGRvbmVcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAoc3RhY2tIZWFkLmNvbnN0cnVjdG9yICE9PSBTa2lwKSB7XG4gICAgICBjb25zdCBsb2NhbENsb2NrID0gbWFwLnNldElmVW5kZWZpbmVkKHN0YXRlLCBzdGFja0hlYWQuaWQuY2xpZW50LCAoKSA9PiBnZXRTdGF0ZShzdG9yZSwgc3RhY2tIZWFkLmlkLmNsaWVudCkpXG4gICAgICBjb25zdCBvZmZzZXQgPSBsb2NhbENsb2NrIC0gc3RhY2tIZWFkLmlkLmNsb2NrXG4gICAgICBpZiAob2Zmc2V0IDwgMCkge1xuICAgICAgICAvLyB1cGRhdGUgZnJvbSB0aGUgc2FtZSBjbGllbnQgaXMgbWlzc2luZ1xuICAgICAgICBzdGFjay5wdXNoKHN0YWNrSGVhZClcbiAgICAgICAgdXBkYXRlTWlzc2luZ1N2KHN0YWNrSGVhZC5pZC5jbGllbnQsIHN0YWNrSGVhZC5pZC5jbG9jayAtIDEpXG4gICAgICAgIC8vIGhpZCBhIGRlYWQgd2FsbCwgYWRkIGFsbCBpdGVtcyBmcm9tIHN0YWNrIHRvIHJlc3RTU1xuICAgICAgICBhZGRTdGFja1RvUmVzdFNTKClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IG1pc3NpbmcgPSBzdGFja0hlYWQuZ2V0TWlzc2luZyh0cmFuc2FjdGlvbiwgc3RvcmUpXG4gICAgICAgIGlmIChtaXNzaW5nICE9PSBudWxsKSB7XG4gICAgICAgICAgc3RhY2sucHVzaChzdGFja0hlYWQpXG4gICAgICAgICAgLy8gZ2V0IHRoZSBzdHJ1Y3QgcmVhZGVyIHRoYXQgaGFzIHRoZSBtaXNzaW5nIHN0cnVjdFxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEB0eXBlIHt7IHJlZnM6IEFycmF5PEdDfEl0ZW0+LCBpOiBudW1iZXIgfX1cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBjb25zdCBzdHJ1Y3RSZWZzID0gY2xpZW50c1N0cnVjdFJlZnMuZ2V0KC8qKiBAdHlwZSB7bnVtYmVyfSAqLyAobWlzc2luZykpIHx8IHsgcmVmczogW10sIGk6IDAgfVxuICAgICAgICAgIGlmIChzdHJ1Y3RSZWZzLnJlZnMubGVuZ3RoID09PSBzdHJ1Y3RSZWZzLmkpIHtcbiAgICAgICAgICAgIC8vIFRoaXMgdXBkYXRlIG1lc3NhZ2UgY2F1c2FsbHkgZGVwZW5kcyBvbiBhbm90aGVyIHVwZGF0ZSBtZXNzYWdlIHRoYXQgZG9lc24ndCBleGlzdCB5ZXRcbiAgICAgICAgICAgIHVwZGF0ZU1pc3NpbmdTdigvKiogQHR5cGUge251bWJlcn0gKi8gKG1pc3NpbmcpLCBnZXRTdGF0ZShzdG9yZSwgbWlzc2luZykpXG4gICAgICAgICAgICBhZGRTdGFja1RvUmVzdFNTKClcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RhY2tIZWFkID0gc3RydWN0UmVmcy5yZWZzW3N0cnVjdFJlZnMuaSsrXVxuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAob2Zmc2V0ID09PSAwIHx8IG9mZnNldCA8IHN0YWNrSGVhZC5sZW5ndGgpIHtcbiAgICAgICAgICAvLyBhbGwgZmluZSwgYXBwbHkgdGhlIHN0YWNraGVhZFxuICAgICAgICAgIHN0YWNrSGVhZC5pbnRlZ3JhdGUodHJhbnNhY3Rpb24sIG9mZnNldClcbiAgICAgICAgICBzdGF0ZS5zZXQoc3RhY2tIZWFkLmlkLmNsaWVudCwgc3RhY2tIZWFkLmlkLmNsb2NrICsgc3RhY2tIZWFkLmxlbmd0aClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBpdGVyYXRlIHRvIG5leHQgc3RhY2tIZWFkXG4gICAgaWYgKHN0YWNrLmxlbmd0aCA+IDApIHtcbiAgICAgIHN0YWNrSGVhZCA9IC8qKiBAdHlwZSB7R0N8SXRlbX0gKi8gKHN0YWNrLnBvcCgpKVxuICAgIH0gZWxzZSBpZiAoY3VyU3RydWN0c1RhcmdldCAhPT0gbnVsbCAmJiBjdXJTdHJ1Y3RzVGFyZ2V0LmkgPCBjdXJTdHJ1Y3RzVGFyZ2V0LnJlZnMubGVuZ3RoKSB7XG4gICAgICBzdGFja0hlYWQgPSAvKiogQHR5cGUge0dDfEl0ZW19ICovIChjdXJTdHJ1Y3RzVGFyZ2V0LnJlZnNbY3VyU3RydWN0c1RhcmdldC5pKytdKVxuICAgIH0gZWxzZSB7XG4gICAgICBjdXJTdHJ1Y3RzVGFyZ2V0ID0gZ2V0TmV4dFN0cnVjdFRhcmdldCgpXG4gICAgICBpZiAoY3VyU3RydWN0c1RhcmdldCA9PT0gbnVsbCkge1xuICAgICAgICAvLyB3ZSBhcmUgZG9uZSFcbiAgICAgICAgYnJlYWtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YWNrSGVhZCA9IC8qKiBAdHlwZSB7R0N8SXRlbX0gKi8gKGN1clN0cnVjdHNUYXJnZXQucmVmc1tjdXJTdHJ1Y3RzVGFyZ2V0LmkrK10pXG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChyZXN0U3RydWN0cy5jbGllbnRzLnNpemUgPiAwKSB7XG4gICAgY29uc3QgZW5jb2RlciA9IG5ldyBVcGRhdGVFbmNvZGVyVjIoKVxuICAgIHdyaXRlQ2xpZW50c1N0cnVjdHMoZW5jb2RlciwgcmVzdFN0cnVjdHMsIG5ldyBNYXAoKSlcbiAgICAvLyB3cml0ZSBlbXB0eSBkZWxldGVzZXRcbiAgICAvLyB3cml0ZURlbGV0ZVNldChlbmNvZGVyLCBuZXcgRGVsZXRlU2V0KCkpXG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIucmVzdEVuY29kZXIsIDApIC8vID0+IG5vIG5lZWQgZm9yIGFuIGV4dHJhIGZ1bmN0aW9uIGNhbGwsIGp1c3Qgd3JpdGUgMCBkZWxldGVzXG4gICAgcmV0dXJuIHsgbWlzc2luZzogbWlzc2luZ1NWLCB1cGRhdGU6IGVuY29kZXIudG9VaW50OEFycmF5KCkgfVxuICB9XG4gIHJldHVybiBudWxsXG59XG5cbi8qKlxuICogQHBhcmFtIHtVcGRhdGVFbmNvZGVyVjEgfCBVcGRhdGVFbmNvZGVyVjJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3Qgd3JpdGVTdHJ1Y3RzRnJvbVRyYW5zYWN0aW9uID0gKGVuY29kZXIsIHRyYW5zYWN0aW9uKSA9PiB3cml0ZUNsaWVudHNTdHJ1Y3RzKGVuY29kZXIsIHRyYW5zYWN0aW9uLmRvYy5zdG9yZSwgdHJhbnNhY3Rpb24uYmVmb3JlU3RhdGUpXG5cbi8qKlxuICogUmVhZCBhbmQgYXBwbHkgYSBkb2N1bWVudCB1cGRhdGUuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGBhcHBseVVwZGF0ZWAgYnV0IGFjY2VwdHMgYSBkZWNvZGVyLlxuICpcbiAqIEBwYXJhbSB7ZGVjb2RpbmcuRGVjb2Rlcn0gZGVjb2RlclxuICogQHBhcmFtIHtEb2N9IHlkb2NcbiAqIEBwYXJhbSB7YW55fSBbdHJhbnNhY3Rpb25PcmlnaW5dIFRoaXMgd2lsbCBiZSBzdG9yZWQgb24gYHRyYW5zYWN0aW9uLm9yaWdpbmAgYW5kIGAub24oJ3VwZGF0ZScsICh1cGRhdGUsIG9yaWdpbikpYFxuICogQHBhcmFtIHtVcGRhdGVEZWNvZGVyVjEgfCBVcGRhdGVEZWNvZGVyVjJ9IFtzdHJ1Y3REZWNvZGVyXVxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgcmVhZFVwZGF0ZVYyID0gKGRlY29kZXIsIHlkb2MsIHRyYW5zYWN0aW9uT3JpZ2luLCBzdHJ1Y3REZWNvZGVyID0gbmV3IFVwZGF0ZURlY29kZXJWMihkZWNvZGVyKSkgPT5cbiAgdHJhbnNhY3QoeWRvYywgdHJhbnNhY3Rpb24gPT4ge1xuICAgIC8vIGZvcmNlIHRoYXQgdHJhbnNhY3Rpb24ubG9jYWwgaXMgc2V0IHRvIG5vbi1sb2NhbFxuICAgIHRyYW5zYWN0aW9uLmxvY2FsID0gZmFsc2VcbiAgICBsZXQgcmV0cnkgPSBmYWxzZVxuICAgIGNvbnN0IGRvYyA9IHRyYW5zYWN0aW9uLmRvY1xuICAgIGNvbnN0IHN0b3JlID0gZG9jLnN0b3JlXG4gICAgLy8gbGV0IHN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KClcbiAgICBjb25zdCBzcyA9IHJlYWRDbGllbnRzU3RydWN0UmVmcyhzdHJ1Y3REZWNvZGVyLCBkb2MpXG4gICAgLy8gY29uc29sZS5sb2coJ3RpbWUgdG8gcmVhZCBzdHJ1Y3RzOiAnLCBwZXJmb3JtYW5jZS5ub3coKSAtIHN0YXJ0KSAvLyBAdG9kbyByZW1vdmVcbiAgICAvLyBzdGFydCA9IHBlcmZvcm1hbmNlLm5vdygpXG4gICAgLy8gY29uc29sZS5sb2coJ3RpbWUgdG8gbWVyZ2U6ICcsIHBlcmZvcm1hbmNlLm5vdygpIC0gc3RhcnQpIC8vIEB0b2RvIHJlbW92ZVxuICAgIC8vIHN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KClcbiAgICBjb25zdCByZXN0U3RydWN0cyA9IGludGVncmF0ZVN0cnVjdHModHJhbnNhY3Rpb24sIHN0b3JlLCBzcylcbiAgICBjb25zdCBwZW5kaW5nID0gc3RvcmUucGVuZGluZ1N0cnVjdHNcbiAgICBpZiAocGVuZGluZykge1xuICAgICAgLy8gY2hlY2sgaWYgd2UgY2FuIGFwcGx5IHNvbWV0aGluZ1xuICAgICAgZm9yIChjb25zdCBbY2xpZW50LCBjbG9ja10gb2YgcGVuZGluZy5taXNzaW5nKSB7XG4gICAgICAgIGlmIChjbG9jayA8IGdldFN0YXRlKHN0b3JlLCBjbGllbnQpKSB7XG4gICAgICAgICAgcmV0cnkgPSB0cnVlXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHJlc3RTdHJ1Y3RzKSB7XG4gICAgICAgIC8vIG1lcmdlIHJlc3RTdHJ1Y3RzIGludG8gc3RvcmUucGVuZGluZ1xuICAgICAgICBmb3IgKGNvbnN0IFtjbGllbnQsIGNsb2NrXSBvZiByZXN0U3RydWN0cy5taXNzaW5nKSB7XG4gICAgICAgICAgY29uc3QgbWNsb2NrID0gcGVuZGluZy5taXNzaW5nLmdldChjbGllbnQpXG4gICAgICAgICAgaWYgKG1jbG9jayA9PSBudWxsIHx8IG1jbG9jayA+IGNsb2NrKSB7XG4gICAgICAgICAgICBwZW5kaW5nLm1pc3Npbmcuc2V0KGNsaWVudCwgY2xvY2spXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHBlbmRpbmcudXBkYXRlID0gbWVyZ2VVcGRhdGVzVjIoW3BlbmRpbmcudXBkYXRlLCByZXN0U3RydWN0cy51cGRhdGVdKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzdG9yZS5wZW5kaW5nU3RydWN0cyA9IHJlc3RTdHJ1Y3RzXG4gICAgfVxuICAgIC8vIGNvbnNvbGUubG9nKCd0aW1lIHRvIGludGVncmF0ZTogJywgcGVyZm9ybWFuY2Uubm93KCkgLSBzdGFydCkgLy8gQHRvZG8gcmVtb3ZlXG4gICAgLy8gc3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKVxuICAgIGNvbnN0IGRzUmVzdCA9IHJlYWRBbmRBcHBseURlbGV0ZVNldChzdHJ1Y3REZWNvZGVyLCB0cmFuc2FjdGlvbiwgc3RvcmUpXG4gICAgaWYgKHN0b3JlLnBlbmRpbmdEcykge1xuICAgICAgLy8gQHRvZG8gd2UgY291bGQgbWFrZSBhIGxvd2VyLWJvdW5kIHN0YXRlLXZlY3RvciBjaGVjayBhcyB3ZSBkbyBhYm92ZVxuICAgICAgY29uc3QgcGVuZGluZ0RTVXBkYXRlID0gbmV3IFVwZGF0ZURlY29kZXJWMihkZWNvZGluZy5jcmVhdGVEZWNvZGVyKHN0b3JlLnBlbmRpbmdEcykpXG4gICAgICBkZWNvZGluZy5yZWFkVmFyVWludChwZW5kaW5nRFNVcGRhdGUucmVzdERlY29kZXIpIC8vIHJlYWQgMCBzdHJ1Y3RzLCBiZWNhdXNlIHdlIG9ubHkgZW5jb2RlIGRlbGV0ZXMgaW4gcGVuZGluZ2RzdXBkYXRlXG4gICAgICBjb25zdCBkc1Jlc3QyID0gcmVhZEFuZEFwcGx5RGVsZXRlU2V0KHBlbmRpbmdEU1VwZGF0ZSwgdHJhbnNhY3Rpb24sIHN0b3JlKVxuICAgICAgaWYgKGRzUmVzdCAmJiBkc1Jlc3QyKSB7XG4gICAgICAgIC8vIGNhc2UgMTogZHMxICE9IG51bGwgJiYgZHMyICE9IG51bGxcbiAgICAgICAgc3RvcmUucGVuZGluZ0RzID0gbWVyZ2VVcGRhdGVzVjIoW2RzUmVzdCwgZHNSZXN0Ml0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBjYXNlIDI6IGRzMSAhPSBudWxsXG4gICAgICAgIC8vIGNhc2UgMzogZHMyICE9IG51bGxcbiAgICAgICAgLy8gY2FzZSA0OiBkczEgPT0gbnVsbCAmJiBkczIgPT0gbnVsbFxuICAgICAgICBzdG9yZS5wZW5kaW5nRHMgPSBkc1Jlc3QgfHwgZHNSZXN0MlxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBFaXRoZXIgZHNSZXN0ID09IG51bGwgJiYgcGVuZGluZ0RzID09IG51bGwgT1IgZHNSZXN0ICE9IG51bGxcbiAgICAgIHN0b3JlLnBlbmRpbmdEcyA9IGRzUmVzdFxuICAgIH1cbiAgICAvLyBjb25zb2xlLmxvZygndGltZSB0byBjbGVhbnVwOiAnLCBwZXJmb3JtYW5jZS5ub3coKSAtIHN0YXJ0KSAvLyBAdG9kbyByZW1vdmVcbiAgICAvLyBzdGFydCA9IHBlcmZvcm1hbmNlLm5vdygpXG5cbiAgICAvLyBjb25zb2xlLmxvZygndGltZSB0byByZXN1bWUgZGVsZXRlIHJlYWRlcnM6ICcsIHBlcmZvcm1hbmNlLm5vdygpIC0gc3RhcnQpIC8vIEB0b2RvIHJlbW92ZVxuICAgIC8vIHN0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KClcbiAgICBpZiAocmV0cnkpIHtcbiAgICAgIGNvbnN0IHVwZGF0ZSA9IC8qKiBAdHlwZSB7e3VwZGF0ZTogVWludDhBcnJheX19ICovIChzdG9yZS5wZW5kaW5nU3RydWN0cykudXBkYXRlXG4gICAgICBzdG9yZS5wZW5kaW5nU3RydWN0cyA9IG51bGxcbiAgICAgIGFwcGx5VXBkYXRlVjIodHJhbnNhY3Rpb24uZG9jLCB1cGRhdGUpXG4gICAgfVxuICB9LCB0cmFuc2FjdGlvbk9yaWdpbiwgZmFsc2UpXG5cbi8qKlxuICogUmVhZCBhbmQgYXBwbHkgYSBkb2N1bWVudCB1cGRhdGUuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGBhcHBseVVwZGF0ZWAgYnV0IGFjY2VwdHMgYSBkZWNvZGVyLlxuICpcbiAqIEBwYXJhbSB7ZGVjb2RpbmcuRGVjb2Rlcn0gZGVjb2RlclxuICogQHBhcmFtIHtEb2N9IHlkb2NcbiAqIEBwYXJhbSB7YW55fSBbdHJhbnNhY3Rpb25PcmlnaW5dIFRoaXMgd2lsbCBiZSBzdG9yZWQgb24gYHRyYW5zYWN0aW9uLm9yaWdpbmAgYW5kIGAub24oJ3VwZGF0ZScsICh1cGRhdGUsIG9yaWdpbikpYFxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgcmVhZFVwZGF0ZSA9IChkZWNvZGVyLCB5ZG9jLCB0cmFuc2FjdGlvbk9yaWdpbikgPT4gcmVhZFVwZGF0ZVYyKGRlY29kZXIsIHlkb2MsIHRyYW5zYWN0aW9uT3JpZ2luLCBuZXcgVXBkYXRlRGVjb2RlclYxKGRlY29kZXIpKVxuXG4vKipcbiAqIEFwcGx5IGEgZG9jdW1lbnQgdXBkYXRlIGNyZWF0ZWQgYnksIGZvciBleGFtcGxlLCBgeS5vbigndXBkYXRlJywgdXBkYXRlID0+IC4uKWAgb3IgYHVwZGF0ZSA9IGVuY29kZVN0YXRlQXNVcGRhdGUoKWAuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBoYXMgdGhlIHNhbWUgZWZmZWN0IGFzIGByZWFkVXBkYXRlYCBidXQgYWNjZXB0cyBhbiBVaW50OEFycmF5IGluc3RlYWQgb2YgYSBEZWNvZGVyLlxuICpcbiAqIEBwYXJhbSB7RG9jfSB5ZG9jXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICogQHBhcmFtIHthbnl9IFt0cmFuc2FjdGlvbk9yaWdpbl0gVGhpcyB3aWxsIGJlIHN0b3JlZCBvbiBgdHJhbnNhY3Rpb24ub3JpZ2luYCBhbmQgYC5vbigndXBkYXRlJywgKHVwZGF0ZSwgb3JpZ2luKSlgXG4gKiBAcGFyYW0ge3R5cGVvZiBVcGRhdGVEZWNvZGVyVjEgfCB0eXBlb2YgVXBkYXRlRGVjb2RlclYyfSBbWURlY29kZXJdXG4gKlxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBhcHBseVVwZGF0ZVYyID0gKHlkb2MsIHVwZGF0ZSwgdHJhbnNhY3Rpb25PcmlnaW4sIFlEZWNvZGVyID0gVXBkYXRlRGVjb2RlclYyKSA9PiB7XG4gIGNvbnN0IGRlY29kZXIgPSBkZWNvZGluZy5jcmVhdGVEZWNvZGVyKHVwZGF0ZSlcbiAgcmVhZFVwZGF0ZVYyKGRlY29kZXIsIHlkb2MsIHRyYW5zYWN0aW9uT3JpZ2luLCBuZXcgWURlY29kZXIoZGVjb2RlcikpXG59XG5cbi8qKlxuICogQXBwbHkgYSBkb2N1bWVudCB1cGRhdGUgY3JlYXRlZCBieSwgZm9yIGV4YW1wbGUsIGB5Lm9uKCd1cGRhdGUnLCB1cGRhdGUgPT4gLi4pYCBvciBgdXBkYXRlID0gZW5jb2RlU3RhdGVBc1VwZGF0ZSgpYC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGhhcyB0aGUgc2FtZSBlZmZlY3QgYXMgYHJlYWRVcGRhdGVgIGJ1dCBhY2NlcHRzIGFuIFVpbnQ4QXJyYXkgaW5zdGVhZCBvZiBhIERlY29kZXIuXG4gKlxuICogQHBhcmFtIHtEb2N9IHlkb2NcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gdXBkYXRlXG4gKiBAcGFyYW0ge2FueX0gW3RyYW5zYWN0aW9uT3JpZ2luXSBUaGlzIHdpbGwgYmUgc3RvcmVkIG9uIGB0cmFuc2FjdGlvbi5vcmlnaW5gIGFuZCBgLm9uKCd1cGRhdGUnLCAodXBkYXRlLCBvcmlnaW4pKWBcbiAqXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGFwcGx5VXBkYXRlID0gKHlkb2MsIHVwZGF0ZSwgdHJhbnNhY3Rpb25PcmlnaW4pID0+IGFwcGx5VXBkYXRlVjIoeWRvYywgdXBkYXRlLCB0cmFuc2FjdGlvbk9yaWdpbiwgVXBkYXRlRGVjb2RlclYxKVxuXG4vKipcbiAqIFdyaXRlIGFsbCB0aGUgZG9jdW1lbnQgYXMgYSBzaW5nbGUgdXBkYXRlIG1lc3NhZ2UuIElmIHlvdSBzcGVjaWZ5IHRoZSBzdGF0ZSBvZiB0aGUgcmVtb3RlIGNsaWVudCAoYHRhcmdldFN0YXRlVmVjdG9yYCkgaXQgd2lsbFxuICogb25seSB3cml0ZSB0aGUgb3BlcmF0aW9ucyB0aGF0IGFyZSBtaXNzaW5nLlxuICpcbiAqIEBwYXJhbSB7VXBkYXRlRW5jb2RlclYxIHwgVXBkYXRlRW5jb2RlclYyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge0RvY30gZG9jXG4gKiBAcGFyYW0ge01hcDxudW1iZXIsbnVtYmVyPn0gW3RhcmdldFN0YXRlVmVjdG9yXSBUaGUgc3RhdGUgb2YgdGhlIHRhcmdldCB0aGF0IHJlY2VpdmVzIHRoZSB1cGRhdGUuIExlYXZlIGVtcHR5IHRvIHdyaXRlIGFsbCBrbm93biBzdHJ1Y3RzXG4gKlxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZVN0YXRlQXNVcGRhdGUgPSAoZW5jb2RlciwgZG9jLCB0YXJnZXRTdGF0ZVZlY3RvciA9IG5ldyBNYXAoKSkgPT4ge1xuICB3cml0ZUNsaWVudHNTdHJ1Y3RzKGVuY29kZXIsIGRvYy5zdG9yZSwgdGFyZ2V0U3RhdGVWZWN0b3IpXG4gIHdyaXRlRGVsZXRlU2V0KGVuY29kZXIsIGNyZWF0ZURlbGV0ZVNldEZyb21TdHJ1Y3RTdG9yZShkb2Muc3RvcmUpKVxufVxuXG4vKipcbiAqIFdyaXRlIGFsbCB0aGUgZG9jdW1lbnQgYXMgYSBzaW5nbGUgdXBkYXRlIG1lc3NhZ2UgdGhhdCBjYW4gYmUgYXBwbGllZCBvbiB0aGUgcmVtb3RlIGRvY3VtZW50LiBJZiB5b3Ugc3BlY2lmeSB0aGUgc3RhdGUgb2YgdGhlIHJlbW90ZSBjbGllbnQgKGB0YXJnZXRTdGF0ZWApIGl0IHdpbGxcbiAqIG9ubHkgd3JpdGUgdGhlIG9wZXJhdGlvbnMgdGhhdCBhcmUgbWlzc2luZy5cbiAqXG4gKiBVc2UgYHdyaXRlU3RhdGVBc1VwZGF0ZWAgaW5zdGVhZCBpZiB5b3UgYXJlIHdvcmtpbmcgd2l0aCBsaWIwL2VuY29kaW5nLmpzI0VuY29kZXJcbiAqXG4gKiBAcGFyYW0ge0RvY30gZG9jXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IFtlbmNvZGVkVGFyZ2V0U3RhdGVWZWN0b3JdIFRoZSBzdGF0ZSBvZiB0aGUgdGFyZ2V0IHRoYXQgcmVjZWl2ZXMgdGhlIHVwZGF0ZS4gTGVhdmUgZW1wdHkgdG8gd3JpdGUgYWxsIGtub3duIHN0cnVjdHNcbiAqIEBwYXJhbSB7VXBkYXRlRW5jb2RlclYxIHwgVXBkYXRlRW5jb2RlclYyfSBbZW5jb2Rlcl1cbiAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9XG4gKlxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBlbmNvZGVTdGF0ZUFzVXBkYXRlVjIgPSAoZG9jLCBlbmNvZGVkVGFyZ2V0U3RhdGVWZWN0b3IgPSBuZXcgVWludDhBcnJheShbMF0pLCBlbmNvZGVyID0gbmV3IFVwZGF0ZUVuY29kZXJWMigpKSA9PiB7XG4gIGNvbnN0IHRhcmdldFN0YXRlVmVjdG9yID0gZGVjb2RlU3RhdGVWZWN0b3IoZW5jb2RlZFRhcmdldFN0YXRlVmVjdG9yKVxuICB3cml0ZVN0YXRlQXNVcGRhdGUoZW5jb2RlciwgZG9jLCB0YXJnZXRTdGF0ZVZlY3RvcilcbiAgY29uc3QgdXBkYXRlcyA9IFtlbmNvZGVyLnRvVWludDhBcnJheSgpXVxuICAvLyBhbHNvIGFkZCB0aGUgcGVuZGluZyB1cGRhdGVzIChpZiB0aGVyZSBhcmUgYW55KVxuICBpZiAoZG9jLnN0b3JlLnBlbmRpbmdEcykge1xuICAgIHVwZGF0ZXMucHVzaChkb2Muc3RvcmUucGVuZGluZ0RzKVxuICB9XG4gIGlmIChkb2Muc3RvcmUucGVuZGluZ1N0cnVjdHMpIHtcbiAgICB1cGRhdGVzLnB1c2goZGlmZlVwZGF0ZVYyKGRvYy5zdG9yZS5wZW5kaW5nU3RydWN0cy51cGRhdGUsIGVuY29kZWRUYXJnZXRTdGF0ZVZlY3RvcikpXG4gIH1cbiAgaWYgKHVwZGF0ZXMubGVuZ3RoID4gMSkge1xuICAgIGlmIChlbmNvZGVyLmNvbnN0cnVjdG9yID09PSBVcGRhdGVFbmNvZGVyVjEpIHtcbiAgICAgIHJldHVybiBtZXJnZVVwZGF0ZXModXBkYXRlcy5tYXAoKHVwZGF0ZSwgaSkgPT4gaSA9PT0gMCA/IHVwZGF0ZSA6IGNvbnZlcnRVcGRhdGVGb3JtYXRWMlRvVjEodXBkYXRlKSkpXG4gICAgfSBlbHNlIGlmIChlbmNvZGVyLmNvbnN0cnVjdG9yID09PSBVcGRhdGVFbmNvZGVyVjIpIHtcbiAgICAgIHJldHVybiBtZXJnZVVwZGF0ZXNWMih1cGRhdGVzKVxuICAgIH1cbiAgfVxuICByZXR1cm4gdXBkYXRlc1swXVxufVxuXG4vKipcbiAqIFdyaXRlIGFsbCB0aGUgZG9jdW1lbnQgYXMgYSBzaW5nbGUgdXBkYXRlIG1lc3NhZ2UgdGhhdCBjYW4gYmUgYXBwbGllZCBvbiB0aGUgcmVtb3RlIGRvY3VtZW50LiBJZiB5b3Ugc3BlY2lmeSB0aGUgc3RhdGUgb2YgdGhlIHJlbW90ZSBjbGllbnQgKGB0YXJnZXRTdGF0ZWApIGl0IHdpbGxcbiAqIG9ubHkgd3JpdGUgdGhlIG9wZXJhdGlvbnMgdGhhdCBhcmUgbWlzc2luZy5cbiAqXG4gKiBVc2UgYHdyaXRlU3RhdGVBc1VwZGF0ZWAgaW5zdGVhZCBpZiB5b3UgYXJlIHdvcmtpbmcgd2l0aCBsaWIwL2VuY29kaW5nLmpzI0VuY29kZXJcbiAqXG4gKiBAcGFyYW0ge0RvY30gZG9jXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IFtlbmNvZGVkVGFyZ2V0U3RhdGVWZWN0b3JdIFRoZSBzdGF0ZSBvZiB0aGUgdGFyZ2V0IHRoYXQgcmVjZWl2ZXMgdGhlIHVwZGF0ZS4gTGVhdmUgZW1wdHkgdG8gd3JpdGUgYWxsIGtub3duIHN0cnVjdHNcbiAqIEByZXR1cm4ge1VpbnQ4QXJyYXl9XG4gKlxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBlbmNvZGVTdGF0ZUFzVXBkYXRlID0gKGRvYywgZW5jb2RlZFRhcmdldFN0YXRlVmVjdG9yKSA9PiBlbmNvZGVTdGF0ZUFzVXBkYXRlVjIoZG9jLCBlbmNvZGVkVGFyZ2V0U3RhdGVWZWN0b3IsIG5ldyBVcGRhdGVFbmNvZGVyVjEoKSlcblxuLyoqXG4gKiBSZWFkIHN0YXRlIHZlY3RvciBmcm9tIERlY29kZXIgYW5kIHJldHVybiBhcyBNYXBcbiAqXG4gKiBAcGFyYW0ge0RTRGVjb2RlclYxIHwgRFNEZWNvZGVyVjJ9IGRlY29kZXJcbiAqIEByZXR1cm4ge01hcDxudW1iZXIsbnVtYmVyPn0gTWFwcyBgY2xpZW50YCB0byB0aGUgbnVtYmVyIG5leHQgZXhwZWN0ZWQgYGNsb2NrYCBmcm9tIHRoYXQgY2xpZW50LlxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgcmVhZFN0YXRlVmVjdG9yID0gZGVjb2RlciA9PiB7XG4gIGNvbnN0IHNzID0gbmV3IE1hcCgpXG4gIGNvbnN0IHNzTGVuZ3RoID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2Rlci5yZXN0RGVjb2RlcilcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzc0xlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2xpZW50ID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2Rlci5yZXN0RGVjb2RlcilcbiAgICBjb25zdCBjbG9jayA9IGRlY29kaW5nLnJlYWRWYXJVaW50KGRlY29kZXIucmVzdERlY29kZXIpXG4gICAgc3Muc2V0KGNsaWVudCwgY2xvY2spXG4gIH1cbiAgcmV0dXJuIHNzXG59XG5cbi8qKlxuICogUmVhZCBkZWNvZGVkU3RhdGUgYW5kIHJldHVybiBTdGF0ZSBhcyBNYXAuXG4gKlxuICogQHBhcmFtIHtVaW50OEFycmF5fSBkZWNvZGVkU3RhdGVcbiAqIEByZXR1cm4ge01hcDxudW1iZXIsbnVtYmVyPn0gTWFwcyBgY2xpZW50YCB0byB0aGUgbnVtYmVyIG5leHQgZXhwZWN0ZWQgYGNsb2NrYCBmcm9tIHRoYXQgY2xpZW50LlxuICpcbiAqIEBmdW5jdGlvblxuICovXG4vLyBleHBvcnQgY29uc3QgZGVjb2RlU3RhdGVWZWN0b3JWMiA9IGRlY29kZWRTdGF0ZSA9PiByZWFkU3RhdGVWZWN0b3IobmV3IERTRGVjb2RlclYyKGRlY29kaW5nLmNyZWF0ZURlY29kZXIoZGVjb2RlZFN0YXRlKSkpXG5cbi8qKlxuICogUmVhZCBkZWNvZGVkU3RhdGUgYW5kIHJldHVybiBTdGF0ZSBhcyBNYXAuXG4gKlxuICogQHBhcmFtIHtVaW50OEFycmF5fSBkZWNvZGVkU3RhdGVcbiAqIEByZXR1cm4ge01hcDxudW1iZXIsbnVtYmVyPn0gTWFwcyBgY2xpZW50YCB0byB0aGUgbnVtYmVyIG5leHQgZXhwZWN0ZWQgYGNsb2NrYCBmcm9tIHRoYXQgY2xpZW50LlxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgZGVjb2RlU3RhdGVWZWN0b3IgPSBkZWNvZGVkU3RhdGUgPT4gcmVhZFN0YXRlVmVjdG9yKG5ldyBEU0RlY29kZXJWMShkZWNvZGluZy5jcmVhdGVEZWNvZGVyKGRlY29kZWRTdGF0ZSkpKVxuXG4vKipcbiAqIEBwYXJhbSB7RFNFbmNvZGVyVjEgfCBEU0VuY29kZXJWMn0gZW5jb2RlclxuICogQHBhcmFtIHtNYXA8bnVtYmVyLG51bWJlcj59IHN2XG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHdyaXRlU3RhdGVWZWN0b3IgPSAoZW5jb2Rlciwgc3YpID0+IHtcbiAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIucmVzdEVuY29kZXIsIHN2LnNpemUpXG4gIGFycmF5LmZyb20oc3YuZW50cmllcygpKS5zb3J0KChhLCBiKSA9PiBiWzBdIC0gYVswXSkuZm9yRWFjaCgoW2NsaWVudCwgY2xvY2tdKSA9PiB7XG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIucmVzdEVuY29kZXIsIGNsaWVudCkgLy8gQHRvZG8gdXNlIGEgc3BlY2lhbCBjbGllbnQgZGVjb2RlciB0aGF0IGlzIGJhc2VkIG9uIG1hcHBpbmdcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2Rlci5yZXN0RW5jb2RlciwgY2xvY2spXG4gIH0pXG4gIHJldHVybiBlbmNvZGVyXG59XG5cbi8qKlxuICogQHBhcmFtIHtEU0VuY29kZXJWMSB8IERTRW5jb2RlclYyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge0RvY30gZG9jXG4gKlxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZURvY3VtZW50U3RhdGVWZWN0b3IgPSAoZW5jb2RlciwgZG9jKSA9PiB3cml0ZVN0YXRlVmVjdG9yKGVuY29kZXIsIGdldFN0YXRlVmVjdG9yKGRvYy5zdG9yZSkpXG5cbi8qKlxuICogRW5jb2RlIFN0YXRlIGFzIFVpbnQ4QXJyYXkuXG4gKlxuICogQHBhcmFtIHtEb2N8TWFwPG51bWJlcixudW1iZXI+fSBkb2NcbiAqIEBwYXJhbSB7RFNFbmNvZGVyVjEgfCBEU0VuY29kZXJWMn0gW2VuY29kZXJdXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgZW5jb2RlU3RhdGVWZWN0b3JWMiA9IChkb2MsIGVuY29kZXIgPSBuZXcgRFNFbmNvZGVyVjIoKSkgPT4ge1xuICBpZiAoZG9jIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgd3JpdGVTdGF0ZVZlY3RvcihlbmNvZGVyLCBkb2MpXG4gIH0gZWxzZSB7XG4gICAgd3JpdGVEb2N1bWVudFN0YXRlVmVjdG9yKGVuY29kZXIsIGRvYylcbiAgfVxuICByZXR1cm4gZW5jb2Rlci50b1VpbnQ4QXJyYXkoKVxufVxuXG4vKipcbiAqIEVuY29kZSBTdGF0ZSBhcyBVaW50OEFycmF5LlxuICpcbiAqIEBwYXJhbSB7RG9jfE1hcDxudW1iZXIsbnVtYmVyPn0gZG9jXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgZW5jb2RlU3RhdGVWZWN0b3IgPSBkb2MgPT4gZW5jb2RlU3RhdGVWZWN0b3JWMihkb2MsIG5ldyBEU0VuY29kZXJWMSgpKVxuIiwgImltcG9ydCAqIGFzIGYgZnJvbSAnbGliMC9mdW5jdGlvbidcblxuLyoqXG4gKiBHZW5lcmFsIGV2ZW50IGhhbmRsZXIgaW1wbGVtZW50YXRpb24uXG4gKlxuICogQHRlbXBsYXRlIEFSRzAsIEFSRzFcbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgRXZlbnRIYW5kbGVyIHtcbiAgY29uc3RydWN0b3IgKCkge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxmdW5jdGlvbihBUkcwLCBBUkcxKTp2b2lkPn1cbiAgICAgKi9cbiAgICB0aGlzLmwgPSBbXVxuICB9XG59XG5cbi8qKlxuICogQHRlbXBsYXRlIEFSRzAsQVJHMVxuICogQHJldHVybnMge0V2ZW50SGFuZGxlcjxBUkcwLEFSRzE+fVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZUV2ZW50SGFuZGxlciA9ICgpID0+IG5ldyBFdmVudEhhbmRsZXIoKVxuXG4vKipcbiAqIEFkZHMgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBpcyBjYWxsZWQgd2hlblxuICoge0BsaW5rIEV2ZW50SGFuZGxlciNjYWxsRXZlbnRMaXN0ZW5lcnN9IGlzIGNhbGxlZC5cbiAqXG4gKiBAdGVtcGxhdGUgQVJHMCxBUkcxXG4gKiBAcGFyYW0ge0V2ZW50SGFuZGxlcjxBUkcwLEFSRzE+fSBldmVudEhhbmRsZXJcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oQVJHMCxBUkcxKTp2b2lkfSBmIFRoZSBldmVudCBoYW5kbGVyLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGFkZEV2ZW50SGFuZGxlckxpc3RlbmVyID0gKGV2ZW50SGFuZGxlciwgZikgPT5cbiAgZXZlbnRIYW5kbGVyLmwucHVzaChmKVxuXG4vKipcbiAqIFJlbW92ZXMgYW4gZXZlbnQgbGlzdGVuZXIuXG4gKlxuICogQHRlbXBsYXRlIEFSRzAsQVJHMVxuICogQHBhcmFtIHtFdmVudEhhbmRsZXI8QVJHMCxBUkcxPn0gZXZlbnRIYW5kbGVyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKEFSRzAsQVJHMSk6dm9pZH0gZiBUaGUgZXZlbnQgaGFuZGxlciB0aGF0IHdhcyBhZGRlZCB3aXRoXG4gKiAgICAgICAgICAgICAgICAgICAgIHtAbGluayBFdmVudEhhbmRsZXIjYWRkRXZlbnRMaXN0ZW5lcn1cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCByZW1vdmVFdmVudEhhbmRsZXJMaXN0ZW5lciA9IChldmVudEhhbmRsZXIsIGYpID0+IHtcbiAgY29uc3QgbCA9IGV2ZW50SGFuZGxlci5sXG4gIGNvbnN0IGxlbiA9IGwubGVuZ3RoXG4gIGV2ZW50SGFuZGxlci5sID0gbC5maWx0ZXIoZyA9PiBmICE9PSBnKVxuICBpZiAobGVuID09PSBldmVudEhhbmRsZXIubC5sZW5ndGgpIHtcbiAgICBjb25zb2xlLmVycm9yKCdbeWpzXSBUcmllZCB0byByZW1vdmUgZXZlbnQgaGFuZGxlciB0aGF0IGRvZXNuXFwndCBleGlzdC4nKVxuICB9XG59XG5cbi8qKlxuICogUmVtb3ZlcyBhbGwgZXZlbnQgbGlzdGVuZXJzLlxuICogQHRlbXBsYXRlIEFSRzAsQVJHMVxuICogQHBhcmFtIHtFdmVudEhhbmRsZXI8QVJHMCxBUkcxPn0gZXZlbnRIYW5kbGVyXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgcmVtb3ZlQWxsRXZlbnRIYW5kbGVyTGlzdGVuZXJzID0gZXZlbnRIYW5kbGVyID0+IHtcbiAgZXZlbnRIYW5kbGVyLmwubGVuZ3RoID0gMFxufVxuXG4vKipcbiAqIENhbGwgYWxsIGV2ZW50IGxpc3RlbmVycyB0aGF0IHdlcmUgYWRkZWQgdmlhXG4gKiB7QGxpbmsgRXZlbnRIYW5kbGVyI2FkZEV2ZW50TGlzdGVuZXJ9LlxuICpcbiAqIEB0ZW1wbGF0ZSBBUkcwLEFSRzFcbiAqIEBwYXJhbSB7RXZlbnRIYW5kbGVyPEFSRzAsQVJHMT59IGV2ZW50SGFuZGxlclxuICogQHBhcmFtIHtBUkcwfSBhcmcwXG4gKiBAcGFyYW0ge0FSRzF9IGFyZzFcbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBjYWxsRXZlbnRIYW5kbGVyTGlzdGVuZXJzID0gKGV2ZW50SGFuZGxlciwgYXJnMCwgYXJnMSkgPT5cbiAgZi5jYWxsQWxsKGV2ZW50SGFuZGxlci5sLCBbYXJnMCwgYXJnMV0pXG4iLCAiaW1wb3J0IHsgQWJzdHJhY3RUeXBlIH0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cbmltcG9ydCAqIGFzIGRlY29kaW5nIGZyb20gJ2xpYjAvZGVjb2RpbmcnXG5pbXBvcnQgKiBhcyBlbmNvZGluZyBmcm9tICdsaWIwL2VuY29kaW5nJ1xuaW1wb3J0ICogYXMgZXJyb3IgZnJvbSAnbGliMC9lcnJvcidcblxuZXhwb3J0IGNsYXNzIElEIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjbGllbnQgY2xpZW50IGlkXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjbG9jayB1bmlxdWUgcGVyIGNsaWVudCBpZCwgY29udGludW91cyBudW1iZXJcbiAgICovXG4gIGNvbnN0cnVjdG9yIChjbGllbnQsIGNsb2NrKSB7XG4gICAgLyoqXG4gICAgICogQ2xpZW50IGlkXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudFxuICAgIC8qKlxuICAgICAqIHVuaXF1ZSBwZXIgY2xpZW50IGlkLCBjb250aW51b3VzIG51bWJlclxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5jbG9jayA9IGNsb2NrXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge0lEIHwgbnVsbH0gYVxuICogQHBhcmFtIHtJRCB8IG51bGx9IGJcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKlxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBjb21wYXJlSURzID0gKGEsIGIpID0+IGEgPT09IGIgfHwgKGEgIT09IG51bGwgJiYgYiAhPT0gbnVsbCAmJiBhLmNsaWVudCA9PT0gYi5jbGllbnQgJiYgYS5jbG9jayA9PT0gYi5jbG9jaylcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gY2xpZW50XG4gKiBAcGFyYW0ge251bWJlcn0gY2xvY2tcbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVJRCA9IChjbGllbnQsIGNsb2NrKSA9PiBuZXcgSUQoY2xpZW50LCBjbG9jaylcblxuLyoqXG4gKiBAcGFyYW0ge2VuY29kaW5nLkVuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7SUR9IGlkXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3Qgd3JpdGVJRCA9IChlbmNvZGVyLCBpZCkgPT4ge1xuICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2RlciwgaWQuY2xpZW50KVxuICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2RlciwgaWQuY2xvY2spXG59XG5cbi8qKlxuICogUmVhZCBJRC5cbiAqICogSWYgZmlyc3QgdmFyVWludCByZWFkIGlzIDB4RkZGRkZGIGEgUm9vdElEIGlzIHJldHVybmVkLlxuICogKiBPdGhlcndpc2UgYW4gSUQgaXMgcmV0dXJuZWRcbiAqXG4gKiBAcGFyYW0ge2RlY29kaW5nLkRlY29kZXJ9IGRlY29kZXJcbiAqIEByZXR1cm4ge0lEfVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRJRCA9IGRlY29kZXIgPT5cbiAgY3JlYXRlSUQoZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2RlciksIGRlY29kaW5nLnJlYWRWYXJVaW50KGRlY29kZXIpKVxuXG4vKipcbiAqIFRoZSB0b3AgdHlwZXMgYXJlIG1hcHBlZCBmcm9tIHkuc2hhcmUuZ2V0KGtleW5hbWUpID0+IHR5cGUuXG4gKiBgdHlwZWAgZG9lcyBub3Qgc3RvcmUgYW55IGluZm9ybWF0aW9uIGFib3V0IHRoZSBga2V5bmFtZWAuXG4gKiBUaGlzIGZ1bmN0aW9uIGZpbmRzIHRoZSBjb3JyZWN0IGBrZXluYW1lYCBmb3IgYHR5cGVgIGFuZCB0aHJvd3Mgb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHR5cGVcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBmaW5kUm9vdFR5cGVLZXkgPSB0eXBlID0+IHtcbiAgLy8gQHRzLWlnbm9yZSBfeSBtdXN0IGJlIGRlZmluZWQsIG90aGVyd2lzZSB1bmV4cGVjdGVkIGNhc2VcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgdHlwZS5kb2Muc2hhcmUuZW50cmllcygpKSB7XG4gICAgaWYgKHZhbHVlID09PSB0eXBlKSB7XG4gICAgICByZXR1cm4ga2V5XG4gICAgfVxuICB9XG4gIHRocm93IGVycm9yLnVuZXhwZWN0ZWRDYXNlKClcbn1cbiIsICJpbXBvcnQgeyBBYnN0cmFjdFR5cGUsIEl0ZW0gfSBmcm9tICcuLi9pbnRlcm5hbHMuanMnIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuLyoqXG4gKiBDaGVjayBpZiBgcGFyZW50YCBpcyBhIHBhcmVudCBvZiBgY2hpbGRgLlxuICpcbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHBhcmVudFxuICogQHBhcmFtIHtJdGVtfG51bGx9IGNoaWxkXG4gKiBAcmV0dXJuIHtCb29sZWFufSBXaGV0aGVyIGBwYXJlbnRgIGlzIGEgcGFyZW50IG9mIGBjaGlsZGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgaXNQYXJlbnRPZiA9IChwYXJlbnQsIGNoaWxkKSA9PiB7XG4gIHdoaWxlIChjaGlsZCAhPT0gbnVsbCkge1xuICAgIGlmIChjaGlsZC5wYXJlbnQgPT09IHBhcmVudCkge1xuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gICAgY2hpbGQgPSAvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAoY2hpbGQucGFyZW50KS5faXRlbVxuICB9XG4gIHJldHVybiBmYWxzZVxufVxuIiwgImltcG9ydCB7XG4gIEFic3RyYWN0VHlwZSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcblxuLyoqXG4gKiBDb252ZW5pZW50IGhlbHBlciB0byBsb2cgdHlwZSBpbmZvcm1hdGlvbi5cbiAqXG4gKiBEbyBub3QgdXNlIGluIHByb2R1Y3RpdmUgc3lzdGVtcyBhcyB0aGUgb3V0cHV0IGNhbiBiZSBpbW1lbnNlIVxuICpcbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHR5cGVcbiAqL1xuZXhwb3J0IGNvbnN0IGxvZ1R5cGUgPSB0eXBlID0+IHtcbiAgY29uc3QgcmVzID0gW11cbiAgbGV0IG4gPSB0eXBlLl9zdGFydFxuICB3aGlsZSAobikge1xuICAgIHJlcy5wdXNoKG4pXG4gICAgbiA9IG4ucmlnaHRcbiAgfVxuICBjb25zb2xlLmxvZygnQ2hpbGRyZW46ICcsIHJlcylcbiAgY29uc29sZS5sb2coJ0NoaWxkcmVuIGNvbnRlbnQ6ICcsIHJlcy5maWx0ZXIobSA9PiAhbS5kZWxldGVkKS5tYXAobSA9PiBtLmNvbnRlbnQpKVxufVxuIiwgImltcG9ydCB7XG4gIFlBcnJheSxcbiAgWU1hcCxcbiAgcmVhZERlbGV0ZVNldCxcbiAgd3JpdGVEZWxldGVTZXQsXG4gIGNyZWF0ZURlbGV0ZVNldCxcbiAgRFNFbmNvZGVyVjEsIERTRGVjb2RlclYxLCBJRCwgRGVsZXRlU2V0LCBZQXJyYXlFdmVudCwgVHJhbnNhY3Rpb24sIERvYyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcblxuaW1wb3J0ICogYXMgZGVjb2RpbmcgZnJvbSAnbGliMC9kZWNvZGluZydcblxuaW1wb3J0IHsgbWVyZ2VEZWxldGVTZXRzLCBpc0RlbGV0ZWQgfSBmcm9tICcuL0RlbGV0ZVNldC5qcydcblxuZXhwb3J0IGNsYXNzIFBlcm1hbmVudFVzZXJEYXRhIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RG9jfSBkb2NcbiAgICogQHBhcmFtIHtZTWFwPGFueT59IFtzdG9yZVR5cGVdXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoZG9jLCBzdG9yZVR5cGUgPSBkb2MuZ2V0TWFwKCd1c2VycycpKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge01hcDxzdHJpbmcsRGVsZXRlU2V0Pn1cbiAgICAgKi9cbiAgICBjb25zdCBkc3MgPSBuZXcgTWFwKClcbiAgICB0aGlzLnl1c2VycyA9IHN0b3JlVHlwZVxuICAgIHRoaXMuZG9jID0gZG9jXG4gICAgLyoqXG4gICAgICogTWFwcyBmcm9tIGNsaWVudGlkIHRvIHVzZXJEZXNjcmlwdGlvblxuICAgICAqXG4gICAgICogQHR5cGUge01hcDxudW1iZXIsc3RyaW5nPn1cbiAgICAgKi9cbiAgICB0aGlzLmNsaWVudHMgPSBuZXcgTWFwKClcbiAgICB0aGlzLmRzcyA9IGRzc1xuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7WU1hcDxhbnk+fSB1c2VyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJEZXNjcmlwdGlvblxuICAgICAqL1xuICAgIGNvbnN0IGluaXRVc2VyID0gKHVzZXIsIHVzZXJEZXNjcmlwdGlvbikgPT4ge1xuICAgICAgLyoqXG4gICAgICAgKiBAdHlwZSB7WUFycmF5PFVpbnQ4QXJyYXk+fVxuICAgICAgICovXG4gICAgICBjb25zdCBkcyA9IHVzZXIuZ2V0KCdkcycpXG4gICAgICBjb25zdCBpZHMgPSB1c2VyLmdldCgnaWRzJylcbiAgICAgIGNvbnN0IGFkZENsaWVudElkID0gLyoqIEBwYXJhbSB7bnVtYmVyfSBjbGllbnRpZCAqLyBjbGllbnRpZCA9PiB0aGlzLmNsaWVudHMuc2V0KGNsaWVudGlkLCB1c2VyRGVzY3JpcHRpb24pXG4gICAgICBkcy5vYnNlcnZlKC8qKiBAcGFyYW0ge1lBcnJheUV2ZW50PGFueT59IGV2ZW50ICovIGV2ZW50ID0+IHtcbiAgICAgICAgZXZlbnQuY2hhbmdlcy5hZGRlZC5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgIGl0ZW0uY29udGVudC5nZXRDb250ZW50KCkuZm9yRWFjaChlbmNvZGVkRHMgPT4ge1xuICAgICAgICAgICAgaWYgKGVuY29kZWREcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgICAgICAgICAgdGhpcy5kc3Muc2V0KHVzZXJEZXNjcmlwdGlvbiwgbWVyZ2VEZWxldGVTZXRzKFt0aGlzLmRzcy5nZXQodXNlckRlc2NyaXB0aW9uKSB8fCBjcmVhdGVEZWxldGVTZXQoKSwgcmVhZERlbGV0ZVNldChuZXcgRFNEZWNvZGVyVjEoZGVjb2RpbmcuY3JlYXRlRGVjb2RlcihlbmNvZGVkRHMpKSldKSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICB9KVxuICAgICAgfSlcbiAgICAgIHRoaXMuZHNzLnNldCh1c2VyRGVzY3JpcHRpb24sIG1lcmdlRGVsZXRlU2V0cyhkcy5tYXAoZW5jb2RlZERzID0+IHJlYWREZWxldGVTZXQobmV3IERTRGVjb2RlclYxKGRlY29kaW5nLmNyZWF0ZURlY29kZXIoZW5jb2RlZERzKSkpKSkpXG4gICAgICBpZHMub2JzZXJ2ZSgvKiogQHBhcmFtIHtZQXJyYXlFdmVudDxhbnk+fSBldmVudCAqLyBldmVudCA9PlxuICAgICAgICBldmVudC5jaGFuZ2VzLmFkZGVkLmZvckVhY2goaXRlbSA9PiBpdGVtLmNvbnRlbnQuZ2V0Q29udGVudCgpLmZvckVhY2goYWRkQ2xpZW50SWQpKVxuICAgICAgKVxuICAgICAgaWRzLmZvckVhY2goYWRkQ2xpZW50SWQpXG4gICAgfVxuICAgIC8vIG9ic2VydmUgdXNlcnNcbiAgICBzdG9yZVR5cGUub2JzZXJ2ZShldmVudCA9PiB7XG4gICAgICBldmVudC5rZXlzQ2hhbmdlZC5mb3JFYWNoKHVzZXJEZXNjcmlwdGlvbiA9PlxuICAgICAgICBpbml0VXNlcihzdG9yZVR5cGUuZ2V0KHVzZXJEZXNjcmlwdGlvbiksIHVzZXJEZXNjcmlwdGlvbilcbiAgICAgIClcbiAgICB9KVxuICAgIC8vIGFkZCBpbml0aWFsIGRhdGFcbiAgICBzdG9yZVR5cGUuZm9yRWFjaChpbml0VXNlcilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0RvY30gZG9jXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBjbGllbnRpZFxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlckRlc2NyaXB0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb25mXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oVHJhbnNhY3Rpb24sIERlbGV0ZVNldCk6Ym9vbGVhbn0gW2NvbmYuZmlsdGVyXVxuICAgKi9cbiAgc2V0VXNlck1hcHBpbmcgKGRvYywgY2xpZW50aWQsIHVzZXJEZXNjcmlwdGlvbiwgeyBmaWx0ZXIgPSAoKSA9PiB0cnVlIH0gPSB7fSkge1xuICAgIGNvbnN0IHVzZXJzID0gdGhpcy55dXNlcnNcbiAgICBsZXQgdXNlciA9IHVzZXJzLmdldCh1c2VyRGVzY3JpcHRpb24pXG4gICAgaWYgKCF1c2VyKSB7XG4gICAgICB1c2VyID0gbmV3IFlNYXAoKVxuICAgICAgdXNlci5zZXQoJ2lkcycsIG5ldyBZQXJyYXkoKSlcbiAgICAgIHVzZXIuc2V0KCdkcycsIG5ldyBZQXJyYXkoKSlcbiAgICAgIHVzZXJzLnNldCh1c2VyRGVzY3JpcHRpb24sIHVzZXIpXG4gICAgfVxuICAgIHVzZXIuZ2V0KCdpZHMnKS5wdXNoKFtjbGllbnRpZF0pXG4gICAgdXNlcnMub2JzZXJ2ZShfZXZlbnQgPT4ge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHVzZXJPdmVyd3JpdGUgPSB1c2Vycy5nZXQodXNlckRlc2NyaXB0aW9uKVxuICAgICAgICBpZiAodXNlck92ZXJ3cml0ZSAhPT0gdXNlcikge1xuICAgICAgICAgIC8vIHVzZXIgd2FzIG92ZXJ3cml0dGVuLCBwb3J0IGFsbCBkYXRhIG92ZXIgdG8gdGhlIG5leHQgdXNlciBvYmplY3RcbiAgICAgICAgICAvLyBAdG9kbyBFeHBlcmltZW50IHdpdGggWS5TZXRzIGhlcmVcbiAgICAgICAgICB1c2VyID0gdXNlck92ZXJ3cml0ZVxuICAgICAgICAgIC8vIEB0b2RvIGl0ZXJhdGUgb3ZlciBvbGQgdHlwZVxuICAgICAgICAgIHRoaXMuY2xpZW50cy5mb3JFYWNoKChfdXNlckRlc2NyaXB0aW9uLCBjbGllbnRpZCkgPT4ge1xuICAgICAgICAgICAgaWYgKHVzZXJEZXNjcmlwdGlvbiA9PT0gX3VzZXJEZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgICB1c2VyLmdldCgnaWRzJykucHVzaChbY2xpZW50aWRdKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgICAgY29uc3QgZW5jb2RlciA9IG5ldyBEU0VuY29kZXJWMSgpXG4gICAgICAgICAgY29uc3QgZHMgPSB0aGlzLmRzcy5nZXQodXNlckRlc2NyaXB0aW9uKVxuICAgICAgICAgIGlmIChkcykge1xuICAgICAgICAgICAgd3JpdGVEZWxldGVTZXQoZW5jb2RlciwgZHMpXG4gICAgICAgICAgICB1c2VyLmdldCgnZHMnKS5wdXNoKFtlbmNvZGVyLnRvVWludDhBcnJheSgpXSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIDApXG4gICAgfSlcbiAgICBkb2Mub24oJ2FmdGVyVHJhbnNhY3Rpb24nLCAvKiogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb24gKi8gdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IHlkcyA9IHVzZXIuZ2V0KCdkcycpXG4gICAgICAgIGNvbnN0IGRzID0gdHJhbnNhY3Rpb24uZGVsZXRlU2V0XG4gICAgICAgIGlmICh0cmFuc2FjdGlvbi5sb2NhbCAmJiBkcy5jbGllbnRzLnNpemUgPiAwICYmIGZpbHRlcih0cmFuc2FjdGlvbiwgZHMpKSB7XG4gICAgICAgICAgY29uc3QgZW5jb2RlciA9IG5ldyBEU0VuY29kZXJWMSgpXG4gICAgICAgICAgd3JpdGVEZWxldGVTZXQoZW5jb2RlciwgZHMpXG4gICAgICAgICAgeWRzLnB1c2goW2VuY29kZXIudG9VaW50OEFycmF5KCldKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGNsaWVudGlkXG4gICAqIEByZXR1cm4ge2FueX1cbiAgICovXG4gIGdldFVzZXJCeUNsaWVudElkIChjbGllbnRpZCkge1xuICAgIHJldHVybiB0aGlzLmNsaWVudHMuZ2V0KGNsaWVudGlkKSB8fCBudWxsXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtJRH0gaWRcbiAgICogQHJldHVybiB7c3RyaW5nIHwgbnVsbH1cbiAgICovXG4gIGdldFVzZXJCeURlbGV0ZWRJZCAoaWQpIHtcbiAgICBmb3IgKGNvbnN0IFt1c2VyRGVzY3JpcHRpb24sIGRzXSBvZiB0aGlzLmRzcy5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChpc0RlbGV0ZWQoZHMsIGlkKSkge1xuICAgICAgICByZXR1cm4gdXNlckRlc2NyaXB0aW9uXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsXG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICB3cml0ZUlELFxuICByZWFkSUQsXG4gIGNvbXBhcmVJRHMsXG4gIGdldFN0YXRlLFxuICBmaW5kUm9vdFR5cGVLZXksXG4gIEl0ZW0sXG4gIGNyZWF0ZUlELFxuICBDb250ZW50VHlwZSxcbiAgZm9sbG93UmVkb25lLFxuICBnZXRJdGVtLFxuICBTdHJ1Y3RTdG9yZSwgSUQsIERvYywgQWJzdHJhY3RUeXBlLCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcblxuaW1wb3J0ICogYXMgZW5jb2RpbmcgZnJvbSAnbGliMC9lbmNvZGluZydcbmltcG9ydCAqIGFzIGRlY29kaW5nIGZyb20gJ2xpYjAvZGVjb2RpbmcnXG5pbXBvcnQgKiBhcyBlcnJvciBmcm9tICdsaWIwL2Vycm9yJ1xuXG4vKipcbiAqIEEgcmVsYXRpdmUgcG9zaXRpb24gaXMgYmFzZWQgb24gdGhlIFlqcyBtb2RlbCBhbmQgaXMgbm90IGFmZmVjdGVkIGJ5IGRvY3VtZW50IGNoYW5nZXMuXG4gKiBFLmcuIElmIHlvdSBwbGFjZSBhIHJlbGF0aXZlIHBvc2l0aW9uIGJlZm9yZSBhIGNlcnRhaW4gY2hhcmFjdGVyLCBpdCB3aWxsIGFsd2F5cyBwb2ludCB0byB0aGlzIGNoYXJhY3Rlci5cbiAqIElmIHlvdSBwbGFjZSBhIHJlbGF0aXZlIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgYSB0eXBlLCBpdCB3aWxsIGFsd2F5cyBwb2ludCB0byB0aGUgZW5kIG9mIHRoZSB0eXBlLlxuICpcbiAqIEEgbnVtZXJpYyBwb3NpdGlvbiBpcyBvZnRlbiB1bnN1aXRlZCBmb3IgdXNlciBzZWxlY3Rpb25zLCBiZWNhdXNlIGl0IGRvZXMgbm90IGNoYW5nZSB3aGVuIGNvbnRlbnQgaXMgaW5zZXJ0ZWRcbiAqIGJlZm9yZSBvciBhZnRlci5cbiAqXG4gKiBgYGBJbnNlcnQoMCwgJ3gnKSgnYXxiYycpID0gJ3hhfGJjJ2BgYCBXaGVyZSB8IGlzIHRoZSByZWxhdGl2ZSBwb3NpdGlvbi5cbiAqXG4gKiBPbmUgb2YgdGhlIHByb3BlcnRpZXMgbXVzdCBiZSBkZWZpbmVkLlxuICpcbiAqIEBleGFtcGxlXG4gKiAgIC8vIEN1cnJlbnQgY3Vyc29yIHBvc2l0aW9uIGlzIGF0IHBvc2l0aW9uIDEwXG4gKiAgIGNvbnN0IHJlbGF0aXZlUG9zaXRpb24gPSBjcmVhdGVSZWxhdGl2ZVBvc2l0aW9uRnJvbUluZGV4KHlUZXh0LCAxMClcbiAqICAgLy8gbW9kaWZ5IHlUZXh0XG4gKiAgIHlUZXh0Lmluc2VydCgwLCAnYWJjJylcbiAqICAgeVRleHQuZGVsZXRlKDMsIDEwKVxuICogICAvLyBDb21wdXRlIHRoZSBjdXJzb3IgcG9zaXRpb25cbiAqICAgY29uc3QgYWJzb2x1dGVQb3NpdGlvbiA9IGNyZWF0ZUFic29sdXRlUG9zaXRpb25Gcm9tUmVsYXRpdmVQb3NpdGlvbih5LCByZWxhdGl2ZVBvc2l0aW9uKVxuICogICBhYnNvbHV0ZVBvc2l0aW9uLnR5cGUgPT09IHlUZXh0IC8vID0+IHRydWVcbiAqICAgY29uc29sZS5sb2coJ2N1cnNvciBsb2NhdGlvbiBpcyAnICsgYWJzb2x1dGVQb3NpdGlvbi5pbmRleCkgLy8gPT4gY3Vyc29yIGxvY2F0aW9uIGlzIDNcbiAqXG4gKi9cbmV4cG9ydCBjbGFzcyBSZWxhdGl2ZVBvc2l0aW9uIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7SUR8bnVsbH0gdHlwZVxuICAgKiBAcGFyYW0ge3N0cmluZ3xudWxsfSB0bmFtZVxuICAgKiBAcGFyYW0ge0lEfG51bGx9IGl0ZW1cbiAgICogQHBhcmFtIHtudW1iZXJ9IGFzc29jXG4gICAqL1xuICBjb25zdHJ1Y3RvciAodHlwZSwgdG5hbWUsIGl0ZW0sIGFzc29jID0gMCkge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtJRHxudWxsfVxuICAgICAqL1xuICAgIHRoaXMudHlwZSA9IHR5cGVcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7c3RyaW5nfG51bGx9XG4gICAgICovXG4gICAgdGhpcy50bmFtZSA9IHRuYW1lXG4gICAgLyoqXG4gICAgICogQHR5cGUge0lEIHwgbnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLml0ZW0gPSBpdGVtXG4gICAgLyoqXG4gICAgICogQSByZWxhdGl2ZSBwb3NpdGlvbiBpcyBhc3NvY2lhdGVkIHRvIGEgc3BlY2lmaWMgY2hhcmFjdGVyLiBCeSBkZWZhdWx0XG4gICAgICogYXNzb2MgPj0gMCwgdGhlIHJlbGF0aXZlIHBvc2l0aW9uIGlzIGFzc29jaWF0ZWQgdG8gdGhlIGNoYXJhY3RlclxuICAgICAqIGFmdGVyIHRoZSBtZWFudCBwb3NpdGlvbi5cbiAgICAgKiBJLmUuIHBvc2l0aW9uIDEgaW4gJ2FiJyBpcyBhc3NvY2lhdGVkIHRvIGNoYXJhY3RlciAnYicuXG4gICAgICpcbiAgICAgKiBJZiBhc3NvYyA8IDAsIHRoZW4gdGhlIHJlbGF0aXZlIHBvc2l0aW9uIGlzIGFzc29jaWF0ZWQgdG8gdGhlIGNoYXJhY3RlclxuICAgICAqIGJlZm9yZSB0aGUgbWVhbnQgcG9zaXRpb24uXG4gICAgICpcbiAgICAgKiBAdHlwZSB7bnVtYmVyfVxuICAgICAqL1xuICAgIHRoaXMuYXNzb2MgPSBhc3NvY1xuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtSZWxhdGl2ZVBvc2l0aW9ufSBycG9zXG4gKiBAcmV0dXJuIHthbnl9XG4gKi9cbmV4cG9ydCBjb25zdCByZWxhdGl2ZVBvc2l0aW9uVG9KU09OID0gcnBvcyA9PiB7XG4gIGNvbnN0IGpzb24gPSB7fVxuICBpZiAocnBvcy50eXBlKSB7XG4gICAganNvbi50eXBlID0gcnBvcy50eXBlXG4gIH1cbiAgaWYgKHJwb3MudG5hbWUpIHtcbiAgICBqc29uLnRuYW1lID0gcnBvcy50bmFtZVxuICB9XG4gIGlmIChycG9zLml0ZW0pIHtcbiAgICBqc29uLml0ZW0gPSBycG9zLml0ZW1cbiAgfVxuICBpZiAocnBvcy5hc3NvYyAhPSBudWxsKSB7XG4gICAganNvbi5hc3NvYyA9IHJwb3MuYXNzb2NcbiAgfVxuICByZXR1cm4ganNvblxufVxuXG4vKipcbiAqIEBwYXJhbSB7YW55fSBqc29uXG4gKiBAcmV0dXJuIHtSZWxhdGl2ZVBvc2l0aW9ufVxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlUmVsYXRpdmVQb3NpdGlvbkZyb21KU09OID0ganNvbiA9PiBuZXcgUmVsYXRpdmVQb3NpdGlvbihqc29uLnR5cGUgPT0gbnVsbCA/IG51bGwgOiBjcmVhdGVJRChqc29uLnR5cGUuY2xpZW50LCBqc29uLnR5cGUuY2xvY2spLCBqc29uLnRuYW1lID8/IG51bGwsIGpzb24uaXRlbSA9PSBudWxsID8gbnVsbCA6IGNyZWF0ZUlEKGpzb24uaXRlbS5jbGllbnQsIGpzb24uaXRlbS5jbG9jayksIGpzb24uYXNzb2MgPT0gbnVsbCA/IDAgOiBqc29uLmFzc29jKVxuXG5leHBvcnQgY2xhc3MgQWJzb2x1dGVQb3NpdGlvbiB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSB0eXBlXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuICAgKiBAcGFyYW0ge251bWJlcn0gW2Fzc29jXVxuICAgKi9cbiAgY29uc3RydWN0b3IgKHR5cGUsIGluZGV4LCBhc3NvYyA9IDApIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59XG4gICAgICovXG4gICAgdGhpcy50eXBlID0gdHlwZVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5pbmRleCA9IGluZGV4XG4gICAgdGhpcy5hc3NvYyA9IGFzc29jXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSB0eXBlXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXNzb2NdXG4gKlxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVBYnNvbHV0ZVBvc2l0aW9uID0gKHR5cGUsIGluZGV4LCBhc3NvYyA9IDApID0+IG5ldyBBYnNvbHV0ZVBvc2l0aW9uKHR5cGUsIGluZGV4LCBhc3NvYylcblxuLyoqXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSB0eXBlXG4gKiBAcGFyYW0ge0lEfG51bGx9IGl0ZW1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXNzb2NdXG4gKlxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVSZWxhdGl2ZVBvc2l0aW9uID0gKHR5cGUsIGl0ZW0sIGFzc29jKSA9PiB7XG4gIGxldCB0eXBlaWQgPSBudWxsXG4gIGxldCB0bmFtZSA9IG51bGxcbiAgaWYgKHR5cGUuX2l0ZW0gPT09IG51bGwpIHtcbiAgICB0bmFtZSA9IGZpbmRSb290VHlwZUtleSh0eXBlKVxuICB9IGVsc2Uge1xuICAgIHR5cGVpZCA9IGNyZWF0ZUlEKHR5cGUuX2l0ZW0uaWQuY2xpZW50LCB0eXBlLl9pdGVtLmlkLmNsb2NrKVxuICB9XG4gIHJldHVybiBuZXcgUmVsYXRpdmVQb3NpdGlvbih0eXBlaWQsIHRuYW1lLCBpdGVtLCBhc3NvYylcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSByZWxhdGl2ZVBvc2l0aW9uIGJhc2VkIG9uIGEgYWJzb2x1dGUgcG9zaXRpb24uXG4gKlxuICogQHBhcmFtIHtBYnN0cmFjdFR5cGU8YW55Pn0gdHlwZSBUaGUgYmFzZSB0eXBlIChlLmcuIFlUZXh0IG9yIFlBcnJheSkuXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXggVGhlIGFic29sdXRlIHBvc2l0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFthc3NvY11cbiAqIEByZXR1cm4ge1JlbGF0aXZlUG9zaXRpb259XG4gKlxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVSZWxhdGl2ZVBvc2l0aW9uRnJvbVR5cGVJbmRleCA9ICh0eXBlLCBpbmRleCwgYXNzb2MgPSAwKSA9PiB7XG4gIGxldCB0ID0gdHlwZS5fc3RhcnRcbiAgaWYgKGFzc29jIDwgMCkge1xuICAgIC8vIGFzc29jaWF0ZWQgdG8gdGhlIGxlZnQgY2hhcmFjdGVyIG9yIHRoZSBiZWdpbm5pbmcgb2YgYSB0eXBlLCBpbmNyZW1lbnQgaW5kZXggaWYgcG9zc2libGUuXG4gICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICByZXR1cm4gY3JlYXRlUmVsYXRpdmVQb3NpdGlvbih0eXBlLCBudWxsLCBhc3NvYylcbiAgICB9XG4gICAgaW5kZXgtLVxuICB9XG4gIHdoaWxlICh0ICE9PSBudWxsKSB7XG4gICAgaWYgKCF0LmRlbGV0ZWQgJiYgdC5jb3VudGFibGUpIHtcbiAgICAgIGlmICh0Lmxlbmd0aCA+IGluZGV4KSB7XG4gICAgICAgIC8vIGNhc2UgMTogZm91bmQgcG9zaXRpb24gc29tZXdoZXJlIGluIHRoZSBsaW5rZWQgbGlzdFxuICAgICAgICByZXR1cm4gY3JlYXRlUmVsYXRpdmVQb3NpdGlvbih0eXBlLCBjcmVhdGVJRCh0LmlkLmNsaWVudCwgdC5pZC5jbG9jayArIGluZGV4KSwgYXNzb2MpXG4gICAgICB9XG4gICAgICBpbmRleCAtPSB0Lmxlbmd0aFxuICAgIH1cbiAgICBpZiAodC5yaWdodCA9PT0gbnVsbCAmJiBhc3NvYyA8IDApIHtcbiAgICAgIC8vIGxlZnQtYXNzb2NpYXRlZCBwb3NpdGlvbiwgcmV0dXJuIGxhc3QgYXZhaWxhYmxlIGlkXG4gICAgICByZXR1cm4gY3JlYXRlUmVsYXRpdmVQb3NpdGlvbih0eXBlLCB0Lmxhc3RJZCwgYXNzb2MpXG4gICAgfVxuICAgIHQgPSB0LnJpZ2h0XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZVJlbGF0aXZlUG9zaXRpb24odHlwZSwgbnVsbCwgYXNzb2MpXG59XG5cbi8qKlxuICogQHBhcmFtIHtlbmNvZGluZy5FbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge1JlbGF0aXZlUG9zaXRpb259IHJwb3NcbiAqXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHdyaXRlUmVsYXRpdmVQb3NpdGlvbiA9IChlbmNvZGVyLCBycG9zKSA9PiB7XG4gIGNvbnN0IHsgdHlwZSwgdG5hbWUsIGl0ZW0sIGFzc29jIH0gPSBycG9zXG4gIGlmIChpdGVtICE9PSBudWxsKSB7XG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIsIDApXG4gICAgd3JpdGVJRChlbmNvZGVyLCBpdGVtKVxuICB9IGVsc2UgaWYgKHRuYW1lICE9PSBudWxsKSB7XG4gICAgLy8gY2FzZSAyOiBmb3VuZCBwb3NpdGlvbiBhdCB0aGUgZW5kIG9mIHRoZSBsaXN0IGFuZCB0eXBlIGlzIHN0b3JlZCBpbiB5LnNoYXJlXG4gICAgZW5jb2Rpbmcud3JpdGVVaW50OChlbmNvZGVyLCAxKVxuICAgIGVuY29kaW5nLndyaXRlVmFyU3RyaW5nKGVuY29kZXIsIHRuYW1lKVxuICB9IGVsc2UgaWYgKHR5cGUgIT09IG51bGwpIHtcbiAgICAvLyBjYXNlIDM6IGZvdW5kIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIGxpc3QgYW5kIHR5cGUgaXMgYXR0YWNoZWQgdG8gYW4gaXRlbVxuICAgIGVuY29kaW5nLndyaXRlVWludDgoZW5jb2RlciwgMilcbiAgICB3cml0ZUlEKGVuY29kZXIsIHR5cGUpXG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgZXJyb3IudW5leHBlY3RlZENhc2UoKVxuICB9XG4gIGVuY29kaW5nLndyaXRlVmFySW50KGVuY29kZXIsIGFzc29jKVxuICByZXR1cm4gZW5jb2RlclxufVxuXG4vKipcbiAqIEBwYXJhbSB7UmVsYXRpdmVQb3NpdGlvbn0gcnBvc1xuICogQHJldHVybiB7VWludDhBcnJheX1cbiAqL1xuZXhwb3J0IGNvbnN0IGVuY29kZVJlbGF0aXZlUG9zaXRpb24gPSBycG9zID0+IHtcbiAgY29uc3QgZW5jb2RlciA9IGVuY29kaW5nLmNyZWF0ZUVuY29kZXIoKVxuICB3cml0ZVJlbGF0aXZlUG9zaXRpb24oZW5jb2RlciwgcnBvcylcbiAgcmV0dXJuIGVuY29kaW5nLnRvVWludDhBcnJheShlbmNvZGVyKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7ZGVjb2RpbmcuRGVjb2Rlcn0gZGVjb2RlclxuICogQHJldHVybiB7UmVsYXRpdmVQb3NpdGlvbn1cbiAqXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRSZWxhdGl2ZVBvc2l0aW9uID0gZGVjb2RlciA9PiB7XG4gIGxldCB0eXBlID0gbnVsbFxuICBsZXQgdG5hbWUgPSBudWxsXG4gIGxldCBpdGVtSUQgPSBudWxsXG4gIHN3aXRjaCAoZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2RlcikpIHtcbiAgICBjYXNlIDA6XG4gICAgICAvLyBjYXNlIDE6IGZvdW5kIHBvc2l0aW9uIHNvbWV3aGVyZSBpbiB0aGUgbGlua2VkIGxpc3RcbiAgICAgIGl0ZW1JRCA9IHJlYWRJRChkZWNvZGVyKVxuICAgICAgYnJlYWtcbiAgICBjYXNlIDE6XG4gICAgICAvLyBjYXNlIDI6IGZvdW5kIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIGxpc3QgYW5kIHR5cGUgaXMgc3RvcmVkIGluIHkuc2hhcmVcbiAgICAgIHRuYW1lID0gZGVjb2RpbmcucmVhZFZhclN0cmluZyhkZWNvZGVyKVxuICAgICAgYnJlYWtcbiAgICBjYXNlIDI6IHtcbiAgICAgIC8vIGNhc2UgMzogZm91bmQgcG9zaXRpb24gYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCBhbmQgdHlwZSBpcyBhdHRhY2hlZCB0byBhbiBpdGVtXG4gICAgICB0eXBlID0gcmVhZElEKGRlY29kZXIpXG4gICAgfVxuICB9XG4gIGNvbnN0IGFzc29jID0gZGVjb2RpbmcuaGFzQ29udGVudChkZWNvZGVyKSA/IGRlY29kaW5nLnJlYWRWYXJJbnQoZGVjb2RlcikgOiAwXG4gIHJldHVybiBuZXcgUmVsYXRpdmVQb3NpdGlvbih0eXBlLCB0bmFtZSwgaXRlbUlELCBhc3NvYylcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVpbnQ4QXJyYXlcbiAqIEByZXR1cm4ge1JlbGF0aXZlUG9zaXRpb259XG4gKi9cbmV4cG9ydCBjb25zdCBkZWNvZGVSZWxhdGl2ZVBvc2l0aW9uID0gdWludDhBcnJheSA9PiByZWFkUmVsYXRpdmVQb3NpdGlvbihkZWNvZGluZy5jcmVhdGVEZWNvZGVyKHVpbnQ4QXJyYXkpKVxuXG4vKipcbiAqIEBwYXJhbSB7U3RydWN0U3RvcmV9IHN0b3JlXG4gKiBAcGFyYW0ge0lEfSBpZFxuICovXG5jb25zdCBnZXRJdGVtV2l0aE9mZnNldCA9IChzdG9yZSwgaWQpID0+IHtcbiAgY29uc3QgaXRlbSA9IGdldEl0ZW0oc3RvcmUsIGlkKVxuICBjb25zdCBkaWZmID0gaWQuY2xvY2sgLSBpdGVtLmlkLmNsb2NrXG4gIHJldHVybiB7XG4gICAgaXRlbSwgZGlmZlxuICB9XG59XG5cbi8qKlxuICogVHJhbnNmb3JtIGEgcmVsYXRpdmUgcG9zaXRpb24gdG8gYW4gYWJzb2x1dGUgcG9zaXRpb24uXG4gKlxuICogSWYgeW91IHdhbnQgdG8gc2hhcmUgdGhlIHJlbGF0aXZlIHBvc2l0aW9uIHdpdGggb3RoZXIgdXNlcnMsIHlvdSBzaG91bGQgc2V0XG4gKiBgZm9sbG93VW5kb25lRGVsZXRpb25zYCB0byBmYWxzZSB0byBnZXQgY29uc2lzdGVudCByZXN1bHRzIGFjcm9zcyBhbGwgY2xpZW50cy5cbiAqXG4gKiBXaGVuIGNhbGN1bGF0aW5nIHRoZSBhYnNvbHV0ZSBwb3NpdGlvbiwgd2UgdHJ5IHRvIGZvbGxvdyB0aGUgXCJ1bmRvbmUgZGVsZXRpb25zXCIuIFRoaXMgeWllbGRzXG4gKiBiZXR0ZXIgcmVzdWx0cyBmb3IgdGhlIHVzZXIgd2hvIHBlcmZvcm1lZCB1bmRvLiBIb3dldmVyLCBvbmx5IHRoZSB1c2VyIHdobyBwZXJmb3JtZWQgdGhlIHVuZG9cbiAqIHdpbGwgZ2V0IHRoZSBiZXR0ZXIgcmVzdWx0cywgdGhlIG90aGVyIHVzZXJzIGRvbid0IGtub3cgd2hpY2ggb3BlcmF0aW9ucyByZWNyZWF0ZWQgYSBkZWxldGVkXG4gKiByYW5nZSBvZiBjb250ZW50LiBUaGVyZSBpcyBtb3JlIGluZm9ybWF0aW9uIGluIHRoaXMgdGlja2V0OiBodHRwczovL2dpdGh1Yi5jb20veWpzL3lqcy9pc3N1ZXMvNjM4XG4gKlxuICogQHBhcmFtIHtSZWxhdGl2ZVBvc2l0aW9ufSBycG9zXG4gKiBAcGFyYW0ge0RvY30gZG9jXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGZvbGxvd1VuZG9uZURlbGV0aW9ucyAtIHdoZXRoZXIgdG8gZm9sbG93IHVuZG9uZSBkZWxldGlvbnMgLSBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3lqcy95anMvaXNzdWVzLzYzOFxuICogQHJldHVybiB7QWJzb2x1dGVQb3NpdGlvbnxudWxsfVxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlQWJzb2x1dGVQb3NpdGlvbkZyb21SZWxhdGl2ZVBvc2l0aW9uID0gKHJwb3MsIGRvYywgZm9sbG93VW5kb25lRGVsZXRpb25zID0gdHJ1ZSkgPT4ge1xuICBjb25zdCBzdG9yZSA9IGRvYy5zdG9yZVxuICBjb25zdCByaWdodElEID0gcnBvcy5pdGVtXG4gIGNvbnN0IHR5cGVJRCA9IHJwb3MudHlwZVxuICBjb25zdCB0bmFtZSA9IHJwb3MudG5hbWVcbiAgY29uc3QgYXNzb2MgPSBycG9zLmFzc29jXG4gIGxldCB0eXBlID0gbnVsbFxuICBsZXQgaW5kZXggPSAwXG4gIGlmIChyaWdodElEICE9PSBudWxsKSB7XG4gICAgaWYgKGdldFN0YXRlKHN0b3JlLCByaWdodElELmNsaWVudCkgPD0gcmlnaHRJRC5jbG9jaykge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gICAgY29uc3QgcmVzID0gZm9sbG93VW5kb25lRGVsZXRpb25zID8gZm9sbG93UmVkb25lKHN0b3JlLCByaWdodElEKSA6IGdldEl0ZW1XaXRoT2Zmc2V0KHN0b3JlLCByaWdodElEKVxuICAgIGNvbnN0IHJpZ2h0ID0gcmVzLml0ZW1cbiAgICBpZiAoIShyaWdodCBpbnN0YW5jZW9mIEl0ZW0pKSB7XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cbiAgICB0eXBlID0gLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKHJpZ2h0LnBhcmVudClcbiAgICBpZiAodHlwZS5faXRlbSA9PT0gbnVsbCB8fCAhdHlwZS5faXRlbS5kZWxldGVkKSB7XG4gICAgICBpbmRleCA9IChyaWdodC5kZWxldGVkIHx8ICFyaWdodC5jb3VudGFibGUpID8gMCA6IChyZXMuZGlmZiArIChhc3NvYyA+PSAwID8gMCA6IDEpKSAvLyBhZGp1c3QgcG9zaXRpb24gYmFzZWQgb24gbGVmdCBhc3NvY2lhdGlvbiBpZiBuZWNlc3NhcnlcbiAgICAgIGxldCBuID0gcmlnaHQubGVmdFxuICAgICAgd2hpbGUgKG4gIT09IG51bGwpIHtcbiAgICAgICAgaWYgKCFuLmRlbGV0ZWQgJiYgbi5jb3VudGFibGUpIHtcbiAgICAgICAgICBpbmRleCArPSBuLmxlbmd0aFxuICAgICAgICB9XG4gICAgICAgIG4gPSBuLmxlZnRcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKHRuYW1lICE9PSBudWxsKSB7XG4gICAgICB0eXBlID0gZG9jLmdldCh0bmFtZSlcbiAgICB9IGVsc2UgaWYgKHR5cGVJRCAhPT0gbnVsbCkge1xuICAgICAgaWYgKGdldFN0YXRlKHN0b3JlLCB0eXBlSUQuY2xpZW50KSA8PSB0eXBlSUQuY2xvY2spIHtcbiAgICAgICAgLy8gdHlwZSBkb2VzIG5vdCBleGlzdCB5ZXRcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgaXRlbSB9ID0gZm9sbG93VW5kb25lRGVsZXRpb25zID8gZm9sbG93UmVkb25lKHN0b3JlLCB0eXBlSUQpIDogeyBpdGVtOiBnZXRJdGVtKHN0b3JlLCB0eXBlSUQpIH1cbiAgICAgIGlmIChpdGVtIGluc3RhbmNlb2YgSXRlbSAmJiBpdGVtLmNvbnRlbnQgaW5zdGFuY2VvZiBDb250ZW50VHlwZSkge1xuICAgICAgICB0eXBlID0gaXRlbS5jb250ZW50LnR5cGVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHN0cnVjdCBpcyBnYXJiYWdlIGNvbGxlY3RlZFxuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBlcnJvci51bmV4cGVjdGVkQ2FzZSgpXG4gICAgfVxuICAgIGlmIChhc3NvYyA+PSAwKSB7XG4gICAgICBpbmRleCA9IHR5cGUuX2xlbmd0aFxuICAgIH0gZWxzZSB7XG4gICAgICBpbmRleCA9IDBcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUFic29sdXRlUG9zaXRpb24odHlwZSwgaW5kZXgsIHJwb3MuYXNzb2MpXG59XG5cbi8qKlxuICogQHBhcmFtIHtSZWxhdGl2ZVBvc2l0aW9ufG51bGx9IGFcbiAqIEBwYXJhbSB7UmVsYXRpdmVQb3NpdGlvbnxudWxsfSBiXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgY29tcGFyZVJlbGF0aXZlUG9zaXRpb25zID0gKGEsIGIpID0+IGEgPT09IGIgfHwgKFxuICBhICE9PSBudWxsICYmIGIgIT09IG51bGwgJiYgYS50bmFtZSA9PT0gYi50bmFtZSAmJiBjb21wYXJlSURzKGEuaXRlbSwgYi5pdGVtKSAmJiBjb21wYXJlSURzKGEudHlwZSwgYi50eXBlKSAmJiBhLmFzc29jID09PSBiLmFzc29jXG4pXG4iLCAiaW1wb3J0IHtcbiAgaXNEZWxldGVkLFxuICBjcmVhdGVEZWxldGVTZXRGcm9tU3RydWN0U3RvcmUsXG4gIGdldFN0YXRlVmVjdG9yLFxuICBnZXRJdGVtQ2xlYW5TdGFydCxcbiAgaXRlcmF0ZURlbGV0ZWRTdHJ1Y3RzLFxuICB3cml0ZURlbGV0ZVNldCxcbiAgd3JpdGVTdGF0ZVZlY3RvcixcbiAgcmVhZERlbGV0ZVNldCxcbiAgcmVhZFN0YXRlVmVjdG9yLFxuICBjcmVhdGVEZWxldGVTZXQsXG4gIGNyZWF0ZUlELFxuICBnZXRTdGF0ZSxcbiAgZmluZEluZGV4U1MsXG4gIFVwZGF0ZUVuY29kZXJWMixcbiAgYXBwbHlVcGRhdGVWMixcbiAgTGF6eVN0cnVjdFJlYWRlcixcbiAgZXF1YWxEZWxldGVTZXRzLFxuICBVcGRhdGVEZWNvZGVyVjEsIFVwZGF0ZURlY29kZXJWMiwgRFNFbmNvZGVyVjEsIERTRW5jb2RlclYyLCBEU0RlY29kZXJWMSwgRFNEZWNvZGVyVjIsIFRyYW5zYWN0aW9uLCBEb2MsIERlbGV0ZVNldCwgSXRlbSwgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuICBtZXJnZURlbGV0ZVNldHNcbn0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJ1xuXG5pbXBvcnQgKiBhcyBtYXAgZnJvbSAnbGliMC9tYXAnXG5pbXBvcnQgKiBhcyBzZXQgZnJvbSAnbGliMC9zZXQnXG5pbXBvcnQgKiBhcyBkZWNvZGluZyBmcm9tICdsaWIwL2RlY29kaW5nJ1xuaW1wb3J0ICogYXMgZW5jb2RpbmcgZnJvbSAnbGliMC9lbmNvZGluZydcblxuZXhwb3J0IGNsYXNzIFNuYXBzaG90IHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7RGVsZXRlU2V0fSBkc1xuICAgKiBAcGFyYW0ge01hcDxudW1iZXIsbnVtYmVyPn0gc3Ygc3RhdGUgbWFwXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoZHMsIHN2KSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0RlbGV0ZVNldH1cbiAgICAgKi9cbiAgICB0aGlzLmRzID0gZHNcbiAgICAvKipcbiAgICAgKiBTdGF0ZSBNYXBcbiAgICAgKiBAdHlwZSB7TWFwPG51bWJlcixudW1iZXI+fVxuICAgICAqL1xuICAgIHRoaXMuc3YgPSBzdlxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtTbmFwc2hvdH0gc25hcDFcbiAqIEBwYXJhbSB7U25hcHNob3R9IHNuYXAyXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgY29uc3QgZXF1YWxTbmFwc2hvdHMgPSAoc25hcDEsIHNuYXAyKSA9PiB7XG4gIGNvbnN0IGRzMSA9IHNuYXAxLmRzLmNsaWVudHNcbiAgY29uc3QgZHMyID0gc25hcDIuZHMuY2xpZW50c1xuICBjb25zdCBzdjEgPSBzbmFwMS5zdlxuICBjb25zdCBzdjIgPSBzbmFwMi5zdlxuICBpZiAoc3YxLnNpemUgIT09IHN2Mi5zaXplIHx8IGRzMS5zaXplICE9PSBkczIuc2l6ZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHN2MS5lbnRyaWVzKCkpIHtcbiAgICBpZiAoc3YyLmdldChrZXkpICE9PSB2YWx1ZSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICB9XG4gIGZvciAoY29uc3QgW2NsaWVudCwgZHNpdGVtczFdIG9mIGRzMS5lbnRyaWVzKCkpIHtcbiAgICBjb25zdCBkc2l0ZW1zMiA9IGRzMi5nZXQoY2xpZW50KSB8fCBbXVxuICAgIGlmIChkc2l0ZW1zMS5sZW5ndGggIT09IGRzaXRlbXMyLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZHNpdGVtczEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGRzaXRlbTEgPSBkc2l0ZW1zMVtpXVxuICAgICAgY29uc3QgZHNpdGVtMiA9IGRzaXRlbXMyW2ldXG4gICAgICBpZiAoZHNpdGVtMS5jbG9jayAhPT0gZHNpdGVtMi5jbG9jayB8fCBkc2l0ZW0xLmxlbiAhPT0gZHNpdGVtMi5sZW4pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbi8qKlxuICogQHBhcmFtIHtTbmFwc2hvdH0gc25hcHNob3RcbiAqIEBwYXJhbSB7RFNFbmNvZGVyVjEgfCBEU0VuY29kZXJWMn0gW2VuY29kZXJdXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICovXG5leHBvcnQgY29uc3QgZW5jb2RlU25hcHNob3RWMiA9IChzbmFwc2hvdCwgZW5jb2RlciA9IG5ldyBEU0VuY29kZXJWMigpKSA9PiB7XG4gIHdyaXRlRGVsZXRlU2V0KGVuY29kZXIsIHNuYXBzaG90LmRzKVxuICB3cml0ZVN0YXRlVmVjdG9yKGVuY29kZXIsIHNuYXBzaG90LnN2KVxuICByZXR1cm4gZW5jb2Rlci50b1VpbnQ4QXJyYXkoKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7U25hcHNob3R9IHNuYXBzaG90XG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICovXG5leHBvcnQgY29uc3QgZW5jb2RlU25hcHNob3QgPSBzbmFwc2hvdCA9PiBlbmNvZGVTbmFwc2hvdFYyKHNuYXBzaG90LCBuZXcgRFNFbmNvZGVyVjEoKSlcblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZlxuICogQHBhcmFtIHtEU0RlY29kZXJWMSB8IERTRGVjb2RlclYyfSBbZGVjb2Rlcl1cbiAqIEByZXR1cm4ge1NuYXBzaG90fVxuICovXG5leHBvcnQgY29uc3QgZGVjb2RlU25hcHNob3RWMiA9IChidWYsIGRlY29kZXIgPSBuZXcgRFNEZWNvZGVyVjIoZGVjb2RpbmcuY3JlYXRlRGVjb2RlcihidWYpKSkgPT4ge1xuICByZXR1cm4gbmV3IFNuYXBzaG90KHJlYWREZWxldGVTZXQoZGVjb2RlciksIHJlYWRTdGF0ZVZlY3RvcihkZWNvZGVyKSlcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGJ1ZlxuICogQHJldHVybiB7U25hcHNob3R9XG4gKi9cbmV4cG9ydCBjb25zdCBkZWNvZGVTbmFwc2hvdCA9IGJ1ZiA9PiBkZWNvZGVTbmFwc2hvdFYyKGJ1ZiwgbmV3IERTRGVjb2RlclYxKGRlY29kaW5nLmNyZWF0ZURlY29kZXIoYnVmKSkpXG5cbi8qKlxuICogQHBhcmFtIHtEZWxldGVTZXR9IGRzXG4gKiBAcGFyYW0ge01hcDxudW1iZXIsbnVtYmVyPn0gc21cbiAqIEByZXR1cm4ge1NuYXBzaG90fVxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlU25hcHNob3QgPSAoZHMsIHNtKSA9PiBuZXcgU25hcHNob3QoZHMsIHNtKVxuXG5leHBvcnQgY29uc3QgZW1wdHlTbmFwc2hvdCA9IGNyZWF0ZVNuYXBzaG90KGNyZWF0ZURlbGV0ZVNldCgpLCBuZXcgTWFwKCkpXG5cbi8qKlxuICogQHBhcmFtIHtEb2N9IGRvY1xuICogQHJldHVybiB7U25hcHNob3R9XG4gKi9cbmV4cG9ydCBjb25zdCBzbmFwc2hvdCA9IGRvYyA9PiBjcmVhdGVTbmFwc2hvdChjcmVhdGVEZWxldGVTZXRGcm9tU3RydWN0U3RvcmUoZG9jLnN0b3JlKSwgZ2V0U3RhdGVWZWN0b3IoZG9jLnN0b3JlKSlcblxuLyoqXG4gKiBAcGFyYW0ge0l0ZW19IGl0ZW1cbiAqIEBwYXJhbSB7U25hcHNob3R8dW5kZWZpbmVkfSBzbmFwc2hvdFxuICpcbiAqIEBwcm90ZWN0ZWRcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgaXNWaXNpYmxlID0gKGl0ZW0sIHNuYXBzaG90KSA9PiBzbmFwc2hvdCA9PT0gdW5kZWZpbmVkXG4gID8gIWl0ZW0uZGVsZXRlZFxuICA6IHNuYXBzaG90LnN2LmhhcyhpdGVtLmlkLmNsaWVudCkgJiYgKHNuYXBzaG90LnN2LmdldChpdGVtLmlkLmNsaWVudCkgfHwgMCkgPiBpdGVtLmlkLmNsb2NrICYmICFpc0RlbGV0ZWQoc25hcHNob3QuZHMsIGl0ZW0uaWQpXG5cbi8qKlxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEBwYXJhbSB7U25hcHNob3R9IHNuYXBzaG90XG4gKi9cbmV4cG9ydCBjb25zdCBzcGxpdFNuYXBzaG90QWZmZWN0ZWRTdHJ1Y3RzID0gKHRyYW5zYWN0aW9uLCBzbmFwc2hvdCkgPT4ge1xuICBjb25zdCBtZXRhID0gbWFwLnNldElmVW5kZWZpbmVkKHRyYW5zYWN0aW9uLm1ldGEsIHNwbGl0U25hcHNob3RBZmZlY3RlZFN0cnVjdHMsIHNldC5jcmVhdGUpXG4gIGNvbnN0IHN0b3JlID0gdHJhbnNhY3Rpb24uZG9jLnN0b3JlXG4gIC8vIGNoZWNrIGlmIHdlIGFscmVhZHkgc3BsaXQgZm9yIHRoaXMgc25hcHNob3RcbiAgaWYgKCFtZXRhLmhhcyhzbmFwc2hvdCkpIHtcbiAgICBzbmFwc2hvdC5zdi5mb3JFYWNoKChjbG9jaywgY2xpZW50KSA9PiB7XG4gICAgICBpZiAoY2xvY2sgPCBnZXRTdGF0ZShzdG9yZSwgY2xpZW50KSkge1xuICAgICAgICBnZXRJdGVtQ2xlYW5TdGFydCh0cmFuc2FjdGlvbiwgY3JlYXRlSUQoY2xpZW50LCBjbG9jaykpXG4gICAgICB9XG4gICAgfSlcbiAgICBpdGVyYXRlRGVsZXRlZFN0cnVjdHModHJhbnNhY3Rpb24sIHNuYXBzaG90LmRzLCBfaXRlbSA9PiB7fSlcbiAgICBtZXRhLmFkZChzbmFwc2hvdClcbiAgfVxufVxuXG4vKipcbiAqIEBleGFtcGxlXG4gKiAgY29uc3QgeWRvYyA9IG5ldyBZLkRvYyh7IGdjOiBmYWxzZSB9KVxuICogIHlkb2MuZ2V0VGV4dCgpLmluc2VydCgwLCAnd29ybGQhJylcbiAqICBjb25zdCBzbmFwc2hvdCA9IFkuc25hcHNob3QoeWRvYylcbiAqICB5ZG9jLmdldFRleHQoKS5pbnNlcnQoMCwgJ2hlbGxvICcpXG4gKiAgY29uc3QgcmVzdG9yZWQgPSBZLmNyZWF0ZURvY0Zyb21TbmFwc2hvdCh5ZG9jLCBzbmFwc2hvdClcbiAqICBhc3NlcnQocmVzdG9yZWQuZ2V0VGV4dCgpLnRvU3RyaW5nKCkgPT09ICd3b3JsZCEnKVxuICpcbiAqIEBwYXJhbSB7RG9jfSBvcmlnaW5Eb2NcbiAqIEBwYXJhbSB7U25hcHNob3R9IHNuYXBzaG90XG4gKiBAcGFyYW0ge0RvY30gW25ld0RvY10gT3B0aW9uYWxseSwgeW91IG1heSBkZWZpbmUgdGhlIFlqcyBkb2N1bWVudCB0aGF0IHJlY2VpdmVzIHRoZSBkYXRhIGZyb20gb3JpZ2luRG9jXG4gKiBAcmV0dXJuIHtEb2N9XG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVEb2NGcm9tU25hcHNob3QgPSAob3JpZ2luRG9jLCBzbmFwc2hvdCwgbmV3RG9jID0gbmV3IERvYygpKSA9PiB7XG4gIGlmIChvcmlnaW5Eb2MuZ2MpIHtcbiAgICAvLyB3ZSBzaG91bGQgbm90IHRyeSB0byByZXN0b3JlIGEgR0MtZWQgZG9jdW1lbnQsIGJlY2F1c2Ugc29tZSBvZiB0aGUgcmVzdG9yZWQgaXRlbXMgbWlnaHQgaGF2ZSB0aGVpciBjb250ZW50IGRlbGV0ZWRcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dhcmJhZ2UtY29sbGVjdGlvbiBtdXN0IGJlIGRpc2FibGVkIGluIGBvcmlnaW5Eb2NgIScpXG4gIH1cbiAgY29uc3QgeyBzdiwgZHMgfSA9IHNuYXBzaG90XG5cbiAgY29uc3QgZW5jb2RlciA9IG5ldyBVcGRhdGVFbmNvZGVyVjIoKVxuICBvcmlnaW5Eb2MudHJhbnNhY3QodHJhbnNhY3Rpb24gPT4ge1xuICAgIGxldCBzaXplID0gMFxuICAgIHN2LmZvckVhY2goY2xvY2sgPT4ge1xuICAgICAgaWYgKGNsb2NrID4gMCkge1xuICAgICAgICBzaXplKytcbiAgICAgIH1cbiAgICB9KVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLnJlc3RFbmNvZGVyLCBzaXplKVxuICAgIC8vIHNwbGl0dGluZyB0aGUgc3RydWN0cyBiZWZvcmUgd3JpdGluZyB0aGVtIHRvIHRoZSBlbmNvZGVyXG4gICAgZm9yIChjb25zdCBbY2xpZW50LCBjbG9ja10gb2Ygc3YpIHtcbiAgICAgIGlmIChjbG9jayA9PT0gMCkge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgaWYgKGNsb2NrIDwgZ2V0U3RhdGUob3JpZ2luRG9jLnN0b3JlLCBjbGllbnQpKSB7XG4gICAgICAgIGdldEl0ZW1DbGVhblN0YXJ0KHRyYW5zYWN0aW9uLCBjcmVhdGVJRChjbGllbnQsIGNsb2NrKSlcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0cnVjdHMgPSBvcmlnaW5Eb2Muc3RvcmUuY2xpZW50cy5nZXQoY2xpZW50KSB8fCBbXVxuICAgICAgY29uc3QgbGFzdFN0cnVjdEluZGV4ID0gZmluZEluZGV4U1Moc3RydWN0cywgY2xvY2sgLSAxKVxuICAgICAgLy8gd3JpdGUgIyBlbmNvZGVkIHN0cnVjdHNcbiAgICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLnJlc3RFbmNvZGVyLCBsYXN0U3RydWN0SW5kZXggKyAxKVxuICAgICAgZW5jb2Rlci53cml0ZUNsaWVudChjbGllbnQpXG4gICAgICAvLyBmaXJzdCBjbG9jayB3cml0dGVuIGlzIDBcbiAgICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLnJlc3RFbmNvZGVyLCAwKVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gbGFzdFN0cnVjdEluZGV4OyBpKyspIHtcbiAgICAgICAgc3RydWN0c1tpXS53cml0ZShlbmNvZGVyLCAwKVxuICAgICAgfVxuICAgIH1cbiAgICB3cml0ZURlbGV0ZVNldChlbmNvZGVyLCBkcylcbiAgfSlcblxuICBhcHBseVVwZGF0ZVYyKG5ld0RvYywgZW5jb2Rlci50b1VpbnQ4QXJyYXkoKSwgJ3NuYXBzaG90JylcbiAgcmV0dXJuIG5ld0RvY1xufVxuXG4vKipcbiAqIEBwYXJhbSB7U25hcHNob3R9IHNuYXBzaG90XG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICogQHBhcmFtIHt0eXBlb2YgVXBkYXRlRGVjb2RlclYyIHwgdHlwZW9mIFVwZGF0ZURlY29kZXJWMX0gW1lEZWNvZGVyXVxuICovXG5leHBvcnQgY29uc3Qgc25hcHNob3RDb250YWluc1VwZGF0ZVYyID0gKHNuYXBzaG90LCB1cGRhdGUsIFlEZWNvZGVyID0gVXBkYXRlRGVjb2RlclYyKSA9PiB7XG4gIGNvbnN0IHN0cnVjdHMgPSBbXVxuICBjb25zdCB1cGRhdGVEZWNvZGVyID0gbmV3IFlEZWNvZGVyKGRlY29kaW5nLmNyZWF0ZURlY29kZXIodXBkYXRlKSlcbiAgY29uc3QgbGF6eURlY29kZXIgPSBuZXcgTGF6eVN0cnVjdFJlYWRlcih1cGRhdGVEZWNvZGVyLCBmYWxzZSlcbiAgZm9yIChsZXQgY3VyciA9IGxhenlEZWNvZGVyLmN1cnI7IGN1cnIgIT09IG51bGw7IGN1cnIgPSBsYXp5RGVjb2Rlci5uZXh0KCkpIHtcbiAgICBzdHJ1Y3RzLnB1c2goY3VycilcbiAgICBpZiAoKHNuYXBzaG90LnN2LmdldChjdXJyLmlkLmNsaWVudCkgfHwgMCkgPCBjdXJyLmlkLmNsb2NrICsgY3Vyci5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuICBjb25zdCBtZXJnZWREUyA9IG1lcmdlRGVsZXRlU2V0cyhbc25hcHNob3QuZHMsIHJlYWREZWxldGVTZXQodXBkYXRlRGVjb2RlcildKVxuICByZXR1cm4gZXF1YWxEZWxldGVTZXRzKHNuYXBzaG90LmRzLCBtZXJnZWREUylcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1NuYXBzaG90fSBzbmFwc2hvdFxuICogQHBhcmFtIHtVaW50OEFycmF5fSB1cGRhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IHNuYXBzaG90Q29udGFpbnNVcGRhdGUgPSAoc25hcHNob3QsIHVwZGF0ZSkgPT4gc25hcHNob3RDb250YWluc1VwZGF0ZVYyKHNuYXBzaG90LCB1cGRhdGUsIFVwZGF0ZURlY29kZXJWMSlcbiIsICJpbXBvcnQge1xuICBHQyxcbiAgc3BsaXRJdGVtLFxuICBUcmFuc2FjdGlvbiwgSUQsIEl0ZW0sIERTRGVjb2RlclYyIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbn0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJ1xuXG5pbXBvcnQgKiBhcyBtYXRoIGZyb20gJ2xpYjAvbWF0aCdcbmltcG9ydCAqIGFzIGVycm9yIGZyb20gJ2xpYjAvZXJyb3InXG5cbmV4cG9ydCBjbGFzcyBTdHJ1Y3RTdG9yZSB7XG4gIGNvbnN0cnVjdG9yICgpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7TWFwPG51bWJlcixBcnJheTxHQ3xJdGVtPj59XG4gICAgICovXG4gICAgdGhpcy5jbGllbnRzID0gbmV3IE1hcCgpXG4gICAgLyoqXG4gICAgICogQHR5cGUge251bGwgfCB7IG1pc3Npbmc6IE1hcDxudW1iZXIsIG51bWJlcj4sIHVwZGF0ZTogVWludDhBcnJheSB9fVxuICAgICAqL1xuICAgIHRoaXMucGVuZGluZ1N0cnVjdHMgPSBudWxsXG4gICAgLyoqXG4gICAgICogQHR5cGUge251bGwgfCBVaW50OEFycmF5fVxuICAgICAqL1xuICAgIHRoaXMucGVuZGluZ0RzID0gbnVsbFxuICB9XG59XG5cbi8qKlxuICogUmV0dXJuIHRoZSBzdGF0ZXMgYXMgYSBNYXA8Y2xpZW50LGNsb2NrPi5cbiAqIE5vdGUgdGhhdCBjbG9jayByZWZlcnMgdG8gdGhlIG5leHQgZXhwZWN0ZWQgY2xvY2sgaWQuXG4gKlxuICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAqIEByZXR1cm4ge01hcDxudW1iZXIsbnVtYmVyPn1cbiAqXG4gKiBAcHVibGljXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGdldFN0YXRlVmVjdG9yID0gc3RvcmUgPT4ge1xuICBjb25zdCBzbSA9IG5ldyBNYXAoKVxuICBzdG9yZS5jbGllbnRzLmZvckVhY2goKHN0cnVjdHMsIGNsaWVudCkgPT4ge1xuICAgIGNvbnN0IHN0cnVjdCA9IHN0cnVjdHNbc3RydWN0cy5sZW5ndGggLSAxXVxuICAgIHNtLnNldChjbGllbnQsIHN0cnVjdC5pZC5jbG9jayArIHN0cnVjdC5sZW5ndGgpXG4gIH0pXG4gIHJldHVybiBzbVxufVxuXG4vKipcbiAqIEBwYXJhbSB7U3RydWN0U3RvcmV9IHN0b3JlXG4gKiBAcGFyYW0ge251bWJlcn0gY2xpZW50XG4gKiBAcmV0dXJuIHtudW1iZXJ9XG4gKlxuICogQHB1YmxpY1xuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRTdGF0ZSA9IChzdG9yZSwgY2xpZW50KSA9PiB7XG4gIGNvbnN0IHN0cnVjdHMgPSBzdG9yZS5jbGllbnRzLmdldChjbGllbnQpXG4gIGlmIChzdHJ1Y3RzID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gMFxuICB9XG4gIGNvbnN0IGxhc3RTdHJ1Y3QgPSBzdHJ1Y3RzW3N0cnVjdHMubGVuZ3RoIC0gMV1cbiAgcmV0dXJuIGxhc3RTdHJ1Y3QuaWQuY2xvY2sgKyBsYXN0U3RydWN0Lmxlbmd0aFxufVxuXG4vKipcbiAqIEBwYXJhbSB7U3RydWN0U3RvcmV9IHN0b3JlXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgaW50ZWdyaXR5Q2hlY2sgPSBzdG9yZSA9PiB7XG4gIHN0b3JlLmNsaWVudHMuZm9yRWFjaChzdHJ1Y3RzID0+IHtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHN0cnVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGwgPSBzdHJ1Y3RzW2kgLSAxXVxuICAgICAgY29uc3QgciA9IHN0cnVjdHNbaV1cbiAgICAgIGlmIChsLmlkLmNsb2NrICsgbC5sZW5ndGggIT09IHIuaWQuY2xvY2spIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTdHJ1Y3RTdG9yZSBmYWlsZWQgaW50ZWdyaXR5IGNoZWNrJylcbiAgICAgIH1cbiAgICB9XG4gIH0pXG59XG5cbi8qKlxuICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAqIEBwYXJhbSB7R0N8SXRlbX0gc3RydWN0XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgYWRkU3RydWN0ID0gKHN0b3JlLCBzdHJ1Y3QpID0+IHtcbiAgbGV0IHN0cnVjdHMgPSBzdG9yZS5jbGllbnRzLmdldChzdHJ1Y3QuaWQuY2xpZW50KVxuICBpZiAoc3RydWN0cyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RydWN0cyA9IFtdXG4gICAgc3RvcmUuY2xpZW50cy5zZXQoc3RydWN0LmlkLmNsaWVudCwgc3RydWN0cylcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBsYXN0U3RydWN0ID0gc3RydWN0c1tzdHJ1Y3RzLmxlbmd0aCAtIDFdXG4gICAgaWYgKGxhc3RTdHJ1Y3QuaWQuY2xvY2sgKyBsYXN0U3RydWN0Lmxlbmd0aCAhPT0gc3RydWN0LmlkLmNsb2NrKSB7XG4gICAgICB0aHJvdyBlcnJvci51bmV4cGVjdGVkQ2FzZSgpXG4gICAgfVxuICB9XG4gIHN0cnVjdHMucHVzaChzdHJ1Y3QpXG59XG5cbi8qKlxuICogUGVyZm9ybSBhIGJpbmFyeSBzZWFyY2ggb24gYSBzb3J0ZWQgYXJyYXlcbiAqIEBwYXJhbSB7QXJyYXk8SXRlbXxHQz59IHN0cnVjdHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBjbG9ja1xuICogQHJldHVybiB7bnVtYmVyfVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGZpbmRJbmRleFNTID0gKHN0cnVjdHMsIGNsb2NrKSA9PiB7XG4gIGxldCBsZWZ0ID0gMFxuICBsZXQgcmlnaHQgPSBzdHJ1Y3RzLmxlbmd0aCAtIDFcbiAgbGV0IG1pZCA9IHN0cnVjdHNbcmlnaHRdXG4gIGxldCBtaWRjbG9jayA9IG1pZC5pZC5jbG9ja1xuICBpZiAobWlkY2xvY2sgPT09IGNsb2NrKSB7XG4gICAgcmV0dXJuIHJpZ2h0XG4gIH1cbiAgLy8gQHRvZG8gZG9lcyBpdCBldmVuIG1ha2Ugc2Vuc2UgdG8gcGl2b3QgdGhlIHNlYXJjaD9cbiAgLy8gSWYgYSBnb29kIHNwbGl0IG1pc3NlcywgaXQgbWlnaHQgYWN0dWFsbHkgaW5jcmVhc2UgdGhlIHRpbWUgdG8gZmluZCB0aGUgY29ycmVjdCBpdGVtLlxuICAvLyBDdXJyZW50bHksIHRoZSBvbmx5IGFkdmFudGFnZSBpcyB0aGF0IHNlYXJjaCB3aXRoIHBpdm90aW5nIG1pZ2h0IGZpbmQgdGhlIGl0ZW0gb24gdGhlIGZpcnN0IHRyeS5cbiAgbGV0IG1pZGluZGV4ID0gbWF0aC5mbG9vcigoY2xvY2sgLyAobWlkY2xvY2sgKyBtaWQubGVuZ3RoIC0gMSkpICogcmlnaHQpIC8vIHBpdm90aW5nIHRoZSBzZWFyY2hcbiAgd2hpbGUgKGxlZnQgPD0gcmlnaHQpIHtcbiAgICBtaWQgPSBzdHJ1Y3RzW21pZGluZGV4XVxuICAgIG1pZGNsb2NrID0gbWlkLmlkLmNsb2NrXG4gICAgaWYgKG1pZGNsb2NrIDw9IGNsb2NrKSB7XG4gICAgICBpZiAoY2xvY2sgPCBtaWRjbG9jayArIG1pZC5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG1pZGluZGV4XG4gICAgICB9XG4gICAgICBsZWZ0ID0gbWlkaW5kZXggKyAxXG4gICAgfSBlbHNlIHtcbiAgICAgIHJpZ2h0ID0gbWlkaW5kZXggLSAxXG4gICAgfVxuICAgIG1pZGluZGV4ID0gbWF0aC5mbG9vcigobGVmdCArIHJpZ2h0KSAvIDIpXG4gIH1cbiAgLy8gQWx3YXlzIGNoZWNrIHN0YXRlIGJlZm9yZSBsb29raW5nIGZvciBhIHN0cnVjdCBpbiBTdHJ1Y3RTdG9yZVxuICAvLyBUaGVyZWZvcmUgdGhlIGNhc2Ugb2Ygbm90IGZpbmRpbmcgYSBzdHJ1Y3QgaXMgdW5leHBlY3RlZFxuICB0aHJvdyBlcnJvci51bmV4cGVjdGVkQ2FzZSgpXG59XG5cbi8qKlxuICogRXhwZWN0cyB0aGF0IGlkIGlzIGFjdHVhbGx5IGluIHN0b3JlLiBUaGlzIGZ1bmN0aW9uIHRocm93cyBvciBpcyBhbiBpbmZpbml0ZSBsb29wIG90aGVyd2lzZS5cbiAqXG4gKiBAcGFyYW0ge1N0cnVjdFN0b3JlfSBzdG9yZVxuICogQHBhcmFtIHtJRH0gaWRcbiAqIEByZXR1cm4ge0dDfEl0ZW19XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgZmluZCA9IChzdG9yZSwgaWQpID0+IHtcbiAgLyoqXG4gICAqIEB0eXBlIHtBcnJheTxHQ3xJdGVtPn1cbiAgICovXG4gIC8vIEB0cy1pZ25vcmVcbiAgY29uc3Qgc3RydWN0cyA9IHN0b3JlLmNsaWVudHMuZ2V0KGlkLmNsaWVudClcbiAgcmV0dXJuIHN0cnVjdHNbZmluZEluZGV4U1Moc3RydWN0cywgaWQuY2xvY2spXVxufVxuXG4vKipcbiAqIEV4cGVjdHMgdGhhdCBpZCBpcyBhY3R1YWxseSBpbiBzdG9yZS4gVGhpcyBmdW5jdGlvbiB0aHJvd3Mgb3IgaXMgYW4gaW5maW5pdGUgbG9vcCBvdGhlcndpc2UuXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRJdGVtID0gLyoqIEB0eXBlIHtmdW5jdGlvbihTdHJ1Y3RTdG9yZSxJRCk6SXRlbX0gKi8gKGZpbmQpXG5cbi8qKlxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXk8SXRlbXxHQz59IHN0cnVjdHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBjbG9ja1xuICovXG5leHBvcnQgY29uc3QgZmluZEluZGV4Q2xlYW5TdGFydCA9ICh0cmFuc2FjdGlvbiwgc3RydWN0cywgY2xvY2spID0+IHtcbiAgY29uc3QgaW5kZXggPSBmaW5kSW5kZXhTUyhzdHJ1Y3RzLCBjbG9jaylcbiAgY29uc3Qgc3RydWN0ID0gc3RydWN0c1tpbmRleF1cbiAgaWYgKHN0cnVjdC5pZC5jbG9jayA8IGNsb2NrICYmIHN0cnVjdCBpbnN0YW5jZW9mIEl0ZW0pIHtcbiAgICBzdHJ1Y3RzLnNwbGljZShpbmRleCArIDEsIDAsIHNwbGl0SXRlbSh0cmFuc2FjdGlvbiwgc3RydWN0LCBjbG9jayAtIHN0cnVjdC5pZC5jbG9jaykpXG4gICAgcmV0dXJuIGluZGV4ICsgMVxuICB9XG4gIHJldHVybiBpbmRleFxufVxuXG4vKipcbiAqIEV4cGVjdHMgdGhhdCBpZCBpcyBhY3R1YWxseSBpbiBzdG9yZS4gVGhpcyBmdW5jdGlvbiB0aHJvd3Mgb3IgaXMgYW4gaW5maW5pdGUgbG9vcCBvdGhlcndpc2UuXG4gKlxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEBwYXJhbSB7SUR9IGlkXG4gKiBAcmV0dXJuIHtJdGVtfVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGdldEl0ZW1DbGVhblN0YXJ0ID0gKHRyYW5zYWN0aW9uLCBpZCkgPT4ge1xuICBjb25zdCBzdHJ1Y3RzID0gLyoqIEB0eXBlIHtBcnJheTxJdGVtPn0gKi8gKHRyYW5zYWN0aW9uLmRvYy5zdG9yZS5jbGllbnRzLmdldChpZC5jbGllbnQpKVxuICByZXR1cm4gc3RydWN0c1tmaW5kSW5kZXhDbGVhblN0YXJ0KHRyYW5zYWN0aW9uLCBzdHJ1Y3RzLCBpZC5jbG9jayldXG59XG5cbi8qKlxuICogRXhwZWN0cyB0aGF0IGlkIGlzIGFjdHVhbGx5IGluIHN0b3JlLiBUaGlzIGZ1bmN0aW9uIHRocm93cyBvciBpcyBhbiBpbmZpbml0ZSBsb29wIG90aGVyd2lzZS5cbiAqXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAqIEBwYXJhbSB7SUR9IGlkXG4gKiBAcmV0dXJuIHtJdGVtfVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGdldEl0ZW1DbGVhbkVuZCA9ICh0cmFuc2FjdGlvbiwgc3RvcmUsIGlkKSA9PiB7XG4gIC8qKlxuICAgKiBAdHlwZSB7QXJyYXk8SXRlbT59XG4gICAqL1xuICAvLyBAdHMtaWdub3JlXG4gIGNvbnN0IHN0cnVjdHMgPSBzdG9yZS5jbGllbnRzLmdldChpZC5jbGllbnQpXG4gIGNvbnN0IGluZGV4ID0gZmluZEluZGV4U1Moc3RydWN0cywgaWQuY2xvY2spXG4gIGNvbnN0IHN0cnVjdCA9IHN0cnVjdHNbaW5kZXhdXG4gIGlmIChpZC5jbG9jayAhPT0gc3RydWN0LmlkLmNsb2NrICsgc3RydWN0Lmxlbmd0aCAtIDEgJiYgc3RydWN0LmNvbnN0cnVjdG9yICE9PSBHQykge1xuICAgIHN0cnVjdHMuc3BsaWNlKGluZGV4ICsgMSwgMCwgc3BsaXRJdGVtKHRyYW5zYWN0aW9uLCBzdHJ1Y3QsIGlkLmNsb2NrIC0gc3RydWN0LmlkLmNsb2NrICsgMSkpXG4gIH1cbiAgcmV0dXJuIHN0cnVjdFxufVxuXG4vKipcbiAqIFJlcGxhY2UgYGl0ZW1gIHdpdGggYG5ld2l0ZW1gIGluIHN0b3JlXG4gKiBAcGFyYW0ge1N0cnVjdFN0b3JlfSBzdG9yZVxuICogQHBhcmFtIHtHQ3xJdGVtfSBzdHJ1Y3RcbiAqIEBwYXJhbSB7R0N8SXRlbX0gbmV3U3RydWN0XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgcmVwbGFjZVN0cnVjdCA9IChzdG9yZSwgc3RydWN0LCBuZXdTdHJ1Y3QpID0+IHtcbiAgY29uc3Qgc3RydWN0cyA9IC8qKiBAdHlwZSB7QXJyYXk8R0N8SXRlbT59ICovIChzdG9yZS5jbGllbnRzLmdldChzdHJ1Y3QuaWQuY2xpZW50KSlcbiAgc3RydWN0c1tmaW5kSW5kZXhTUyhzdHJ1Y3RzLCBzdHJ1Y3QuaWQuY2xvY2spXSA9IG5ld1N0cnVjdFxufVxuXG4vKipcbiAqIEl0ZXJhdGUgb3ZlciBhIHJhbmdlIG9mIHN0cnVjdHNcbiAqXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtBcnJheTxJdGVtfEdDPn0gc3RydWN0c1xuICogQHBhcmFtIHtudW1iZXJ9IGNsb2NrU3RhcnQgSW5jbHVzaXZlIHN0YXJ0XG4gKiBAcGFyYW0ge251bWJlcn0gbGVuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKEdDfEl0ZW0pOnZvaWR9IGZcbiAqXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGl0ZXJhdGVTdHJ1Y3RzID0gKHRyYW5zYWN0aW9uLCBzdHJ1Y3RzLCBjbG9ja1N0YXJ0LCBsZW4sIGYpID0+IHtcbiAgaWYgKGxlbiA9PT0gMCkge1xuICAgIHJldHVyblxuICB9XG4gIGNvbnN0IGNsb2NrRW5kID0gY2xvY2tTdGFydCArIGxlblxuICBsZXQgaW5kZXggPSBmaW5kSW5kZXhDbGVhblN0YXJ0KHRyYW5zYWN0aW9uLCBzdHJ1Y3RzLCBjbG9ja1N0YXJ0KVxuICBsZXQgc3RydWN0XG4gIGRvIHtcbiAgICBzdHJ1Y3QgPSBzdHJ1Y3RzW2luZGV4KytdXG4gICAgaWYgKGNsb2NrRW5kIDwgc3RydWN0LmlkLmNsb2NrICsgc3RydWN0Lmxlbmd0aCkge1xuICAgICAgZmluZEluZGV4Q2xlYW5TdGFydCh0cmFuc2FjdGlvbiwgc3RydWN0cywgY2xvY2tFbmQpXG4gICAgfVxuICAgIGYoc3RydWN0KVxuICB9IHdoaWxlIChpbmRleCA8IHN0cnVjdHMubGVuZ3RoICYmIHN0cnVjdHNbaW5kZXhdLmlkLmNsb2NrIDwgY2xvY2tFbmQpXG59XG4iLCAiaW1wb3J0IHtcbiAgZ2V0U3RhdGUsXG4gIHdyaXRlU3RydWN0c0Zyb21UcmFuc2FjdGlvbixcbiAgd3JpdGVEZWxldGVTZXQsXG4gIERlbGV0ZVNldCxcbiAgc29ydEFuZE1lcmdlRGVsZXRlU2V0LFxuICBnZXRTdGF0ZVZlY3RvcixcbiAgZmluZEluZGV4U1MsXG4gIGNhbGxFdmVudEhhbmRsZXJMaXN0ZW5lcnMsXG4gIEl0ZW0sXG4gIGdlbmVyYXRlTmV3Q2xpZW50SWQsXG4gIGNyZWF0ZUlELFxuICBjbGVhbnVwWVRleHRBZnRlclRyYW5zYWN0aW9uLFxuICBVcGRhdGVFbmNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMiwgR0MsIFN0cnVjdFN0b3JlLCBBYnN0cmFjdFR5cGUsIEFic3RyYWN0U3RydWN0LCBZRXZlbnQsIERvYyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcblxuaW1wb3J0ICogYXMgbWFwIGZyb20gJ2xpYjAvbWFwJ1xuaW1wb3J0ICogYXMgbWF0aCBmcm9tICdsaWIwL21hdGgnXG5pbXBvcnQgKiBhcyBzZXQgZnJvbSAnbGliMC9zZXQnXG5pbXBvcnQgKiBhcyBsb2dnaW5nIGZyb20gJ2xpYjAvbG9nZ2luZydcbmltcG9ydCB7IGNhbGxBbGwgfSBmcm9tICdsaWIwL2Z1bmN0aW9uJ1xuXG4vKipcbiAqIEEgdHJhbnNhY3Rpb24gaXMgY3JlYXRlZCBmb3IgZXZlcnkgY2hhbmdlIG9uIHRoZSBZanMgbW9kZWwuIEl0IGlzIHBvc3NpYmxlXG4gKiB0byBidW5kbGUgY2hhbmdlcyBvbiB0aGUgWWpzIG1vZGVsIGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uIHRvXG4gKiBtaW5pbWl6ZSB0aGUgbnVtYmVyIG9uIG1lc3NhZ2VzIHNlbnQgYW5kIHRoZSBudW1iZXIgb2Ygb2JzZXJ2ZXIgY2FsbHMuXG4gKiBJZiBwb3NzaWJsZSB0aGUgdXNlciBvZiB0aGlzIGxpYnJhcnkgc2hvdWxkIGJ1bmRsZSBhcyBtYW55IGNoYW5nZXMgYXNcbiAqIHBvc3NpYmxlLiBIZXJlIGlzIGFuIGV4YW1wbGUgdG8gaWxsdXN0cmF0ZSB0aGUgYWR2YW50YWdlcyBvZiBidW5kbGluZzpcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgeWRvYyA9IG5ldyBZLkRvYygpXG4gKiBjb25zdCBtYXAgPSB5ZG9jLmdldE1hcCgnbWFwJylcbiAqIC8vIExvZyBjb250ZW50IHdoZW4gY2hhbmdlIGlzIHRyaWdnZXJlZFxuICogbWFwLm9ic2VydmUoKCkgPT4ge1xuICogICBjb25zb2xlLmxvZygnY2hhbmdlIHRyaWdnZXJlZCcpXG4gKiB9KVxuICogLy8gRWFjaCBjaGFuZ2Ugb24gdGhlIG1hcCB0eXBlIHRyaWdnZXJzIGEgbG9nIG1lc3NhZ2U6XG4gKiBtYXAuc2V0KCdhJywgMCkgLy8gPT4gXCJjaGFuZ2UgdHJpZ2dlcmVkXCJcbiAqIG1hcC5zZXQoJ2InLCAwKSAvLyA9PiBcImNoYW5nZSB0cmlnZ2VyZWRcIlxuICogLy8gV2hlbiBwdXQgaW4gYSB0cmFuc2FjdGlvbiwgaXQgd2lsbCB0cmlnZ2VyIHRoZSBsb2cgYWZ0ZXIgdGhlIHRyYW5zYWN0aW9uOlxuICogeWRvYy50cmFuc2FjdCgoKSA9PiB7XG4gKiAgIG1hcC5zZXQoJ2EnLCAxKVxuICogICBtYXAuc2V0KCdiJywgMSlcbiAqIH0pIC8vID0+IFwiY2hhbmdlIHRyaWdnZXJlZFwiXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY2xhc3MgVHJhbnNhY3Rpb24ge1xuICAvKipcbiAgICogQHBhcmFtIHtEb2N9IGRvY1xuICAgKiBAcGFyYW0ge2FueX0gb3JpZ2luXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gbG9jYWxcbiAgICovXG4gIGNvbnN0cnVjdG9yIChkb2MsIG9yaWdpbiwgbG9jYWwpIHtcbiAgICAvKipcbiAgICAgKiBUaGUgWWpzIGluc3RhbmNlLlxuICAgICAqIEB0eXBlIHtEb2N9XG4gICAgICovXG4gICAgdGhpcy5kb2MgPSBkb2NcbiAgICAvKipcbiAgICAgKiBEZXNjcmliZXMgdGhlIHNldCBvZiBkZWxldGVkIGl0ZW1zIGJ5IGlkc1xuICAgICAqIEB0eXBlIHtEZWxldGVTZXR9XG4gICAgICovXG4gICAgdGhpcy5kZWxldGVTZXQgPSBuZXcgRGVsZXRlU2V0KClcbiAgICAvKipcbiAgICAgKiBIb2xkcyB0aGUgc3RhdGUgYmVmb3JlIHRoZSB0cmFuc2FjdGlvbiBzdGFydGVkLlxuICAgICAqIEB0eXBlIHtNYXA8TnVtYmVyLE51bWJlcj59XG4gICAgICovXG4gICAgdGhpcy5iZWZvcmVTdGF0ZSA9IGdldFN0YXRlVmVjdG9yKGRvYy5zdG9yZSlcbiAgICAvKipcbiAgICAgKiBIb2xkcyB0aGUgc3RhdGUgYWZ0ZXIgdGhlIHRyYW5zYWN0aW9uLlxuICAgICAqIEB0eXBlIHtNYXA8TnVtYmVyLE51bWJlcj59XG4gICAgICovXG4gICAgdGhpcy5hZnRlclN0YXRlID0gbmV3IE1hcCgpXG4gICAgLyoqXG4gICAgICogQWxsIHR5cGVzIHRoYXQgd2VyZSBkaXJlY3RseSBtb2RpZmllZCAocHJvcGVydHkgYWRkZWQgb3IgY2hpbGRcbiAgICAgKiBpbnNlcnRlZC9kZWxldGVkKS4gTmV3IHR5cGVzIGFyZSBub3QgaW5jbHVkZWQgaW4gdGhpcyBTZXQuXG4gICAgICogTWFwcyBmcm9tIHR5cGUgdG8gcGFyZW50U3VicyAoYGl0ZW0ucGFyZW50U3ViID0gbnVsbGAgZm9yIFlBcnJheSlcbiAgICAgKiBAdHlwZSB7TWFwPEFic3RyYWN0VHlwZTxZRXZlbnQ8YW55Pj4sU2V0PFN0cmluZ3xudWxsPj59XG4gICAgICovXG4gICAgdGhpcy5jaGFuZ2VkID0gbmV3IE1hcCgpXG4gICAgLyoqXG4gICAgICogU3RvcmVzIHRoZSBldmVudHMgZm9yIHRoZSB0eXBlcyB0aGF0IG9ic2VydmUgYWxzbyBjaGlsZCBlbGVtZW50cy5cbiAgICAgKiBJdCBpcyBtYWlubHkgdXNlZCBieSBgb2JzZXJ2ZURlZXBgLlxuICAgICAqIEB0eXBlIHtNYXA8QWJzdHJhY3RUeXBlPFlFdmVudDxhbnk+PixBcnJheTxZRXZlbnQ8YW55Pj4+fVxuICAgICAqL1xuICAgIHRoaXMuY2hhbmdlZFBhcmVudFR5cGVzID0gbmV3IE1hcCgpXG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PEFic3RyYWN0U3RydWN0Pn1cbiAgICAgKi9cbiAgICB0aGlzLl9tZXJnZVN0cnVjdHMgPSBbXVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHthbnl9XG4gICAgICovXG4gICAgdGhpcy5vcmlnaW4gPSBvcmlnaW5cbiAgICAvKipcbiAgICAgKiBTdG9yZXMgbWV0YSBpbmZvcm1hdGlvbiBvbiB0aGUgdHJhbnNhY3Rpb25cbiAgICAgKiBAdHlwZSB7TWFwPGFueSxhbnk+fVxuICAgICAqL1xuICAgIHRoaXMubWV0YSA9IG5ldyBNYXAoKVxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhpcyBjaGFuZ2Ugb3JpZ2luYXRlcyBmcm9tIHRoaXMgZG9jLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMubG9jYWwgPSBsb2NhbFxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtTZXQ8RG9jPn1cbiAgICAgKi9cbiAgICB0aGlzLnN1YmRvY3NBZGRlZCA9IG5ldyBTZXQoKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtTZXQ8RG9jPn1cbiAgICAgKi9cbiAgICB0aGlzLnN1YmRvY3NSZW1vdmVkID0gbmV3IFNldCgpXG4gICAgLyoqXG4gICAgICogQHR5cGUge1NldDxEb2M+fVxuICAgICAqL1xuICAgIHRoaXMuc3ViZG9jc0xvYWRlZCA9IG5ldyBTZXQoKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMuX25lZWRGb3JtYXR0aW5nQ2xlYW51cCA9IGZhbHNlXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VwZGF0ZUVuY29kZXJWMSB8IFVwZGF0ZUVuY29kZXJWMn0gZW5jb2RlclxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgZGF0YSB3YXMgd3JpdHRlbi5cbiAqL1xuZXhwb3J0IGNvbnN0IHdyaXRlVXBkYXRlTWVzc2FnZUZyb21UcmFuc2FjdGlvbiA9IChlbmNvZGVyLCB0cmFuc2FjdGlvbikgPT4ge1xuICBpZiAodHJhbnNhY3Rpb24uZGVsZXRlU2V0LmNsaWVudHMuc2l6ZSA9PT0gMCAmJiAhbWFwLmFueSh0cmFuc2FjdGlvbi5hZnRlclN0YXRlLCAoY2xvY2ssIGNsaWVudCkgPT4gdHJhbnNhY3Rpb24uYmVmb3JlU3RhdGUuZ2V0KGNsaWVudCkgIT09IGNsb2NrKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHNvcnRBbmRNZXJnZURlbGV0ZVNldCh0cmFuc2FjdGlvbi5kZWxldGVTZXQpXG4gIHdyaXRlU3RydWN0c0Zyb21UcmFuc2FjdGlvbihlbmNvZGVyLCB0cmFuc2FjdGlvbilcbiAgd3JpdGVEZWxldGVTZXQoZW5jb2RlciwgdHJhbnNhY3Rpb24uZGVsZXRlU2V0KVxuICByZXR1cm4gdHJ1ZVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgbmV4dElEID0gdHJhbnNhY3Rpb24gPT4ge1xuICBjb25zdCB5ID0gdHJhbnNhY3Rpb24uZG9jXG4gIHJldHVybiBjcmVhdGVJRCh5LmNsaWVudElELCBnZXRTdGF0ZSh5LnN0b3JlLCB5LmNsaWVudElEKSlcbn1cblxuLyoqXG4gKiBJZiBgdHlwZS5wYXJlbnRgIHdhcyBhZGRlZCBpbiBjdXJyZW50IHRyYW5zYWN0aW9uLCBgdHlwZWAgdGVjaG5pY2FsbHlcbiAqIGRpZCBub3QgY2hhbmdlLCBpdCB3YXMganVzdCBhZGRlZCBhbmQgd2Ugc2hvdWxkIG5vdCBmaXJlIGV2ZW50cyBmb3IgYHR5cGVgLlxuICpcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxZRXZlbnQ8YW55Pj59IHR5cGVcbiAqIEBwYXJhbSB7c3RyaW5nfG51bGx9IHBhcmVudFN1YlxuICovXG5leHBvcnQgY29uc3QgYWRkQ2hhbmdlZFR5cGVUb1RyYW5zYWN0aW9uID0gKHRyYW5zYWN0aW9uLCB0eXBlLCBwYXJlbnRTdWIpID0+IHtcbiAgY29uc3QgaXRlbSA9IHR5cGUuX2l0ZW1cbiAgaWYgKGl0ZW0gPT09IG51bGwgfHwgKGl0ZW0uaWQuY2xvY2sgPCAodHJhbnNhY3Rpb24uYmVmb3JlU3RhdGUuZ2V0KGl0ZW0uaWQuY2xpZW50KSB8fCAwKSAmJiAhaXRlbS5kZWxldGVkKSkge1xuICAgIG1hcC5zZXRJZlVuZGVmaW5lZCh0cmFuc2FjdGlvbi5jaGFuZ2VkLCB0eXBlLCBzZXQuY3JlYXRlKS5hZGQocGFyZW50U3ViKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtBcnJheTxBYnN0cmFjdFN0cnVjdD59IHN0cnVjdHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBwb3NcbiAqIEByZXR1cm4ge251bWJlcn0gIyBvZiBtZXJnZWQgc3RydWN0c1xuICovXG5jb25zdCB0cnlUb01lcmdlV2l0aExlZnRzID0gKHN0cnVjdHMsIHBvcykgPT4ge1xuICBsZXQgcmlnaHQgPSBzdHJ1Y3RzW3Bvc11cbiAgbGV0IGxlZnQgPSBzdHJ1Y3RzW3BvcyAtIDFdXG4gIGxldCBpID0gcG9zXG4gIGZvciAoOyBpID4gMDsgcmlnaHQgPSBsZWZ0LCBsZWZ0ID0gc3RydWN0c1stLWkgLSAxXSkge1xuICAgIGlmIChsZWZ0LmRlbGV0ZWQgPT09IHJpZ2h0LmRlbGV0ZWQgJiYgbGVmdC5jb25zdHJ1Y3RvciA9PT0gcmlnaHQuY29uc3RydWN0b3IpIHtcbiAgICAgIGlmIChsZWZ0Lm1lcmdlV2l0aChyaWdodCkpIHtcbiAgICAgICAgaWYgKHJpZ2h0IGluc3RhbmNlb2YgSXRlbSAmJiByaWdodC5wYXJlbnRTdWIgIT09IG51bGwgJiYgLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKHJpZ2h0LnBhcmVudCkuX21hcC5nZXQocmlnaHQucGFyZW50U3ViKSA9PT0gcmlnaHQpIHtcbiAgICAgICAgICAvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAocmlnaHQucGFyZW50KS5fbWFwLnNldChyaWdodC5wYXJlbnRTdWIsIC8qKiBAdHlwZSB7SXRlbX0gKi8gKGxlZnQpKVxuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgfVxuICAgIGJyZWFrXG4gIH1cbiAgY29uc3QgbWVyZ2VkID0gcG9zIC0gaVxuICBpZiAobWVyZ2VkKSB7XG4gICAgLy8gcmVtb3ZlIGFsbCBtZXJnZWQgc3RydWN0cyBmcm9tIHRoZSBhcnJheVxuICAgIHN0cnVjdHMuc3BsaWNlKHBvcyArIDEgLSBtZXJnZWQsIG1lcmdlZClcbiAgfVxuICByZXR1cm4gbWVyZ2VkXG59XG5cbi8qKlxuICogQHBhcmFtIHtEZWxldGVTZXR9IGRzXG4gKiBAcGFyYW0ge1N0cnVjdFN0b3JlfSBzdG9yZVxuICogQHBhcmFtIHtmdW5jdGlvbihJdGVtKTpib29sZWFufSBnY0ZpbHRlclxuICovXG5jb25zdCB0cnlHY0RlbGV0ZVNldCA9IChkcywgc3RvcmUsIGdjRmlsdGVyKSA9PiB7XG4gIGZvciAoY29uc3QgW2NsaWVudCwgZGVsZXRlSXRlbXNdIG9mIGRzLmNsaWVudHMuZW50cmllcygpKSB7XG4gICAgY29uc3Qgc3RydWN0cyA9IC8qKiBAdHlwZSB7QXJyYXk8R0N8SXRlbT59ICovIChzdG9yZS5jbGllbnRzLmdldChjbGllbnQpKVxuICAgIGZvciAobGV0IGRpID0gZGVsZXRlSXRlbXMubGVuZ3RoIC0gMTsgZGkgPj0gMDsgZGktLSkge1xuICAgICAgY29uc3QgZGVsZXRlSXRlbSA9IGRlbGV0ZUl0ZW1zW2RpXVxuICAgICAgY29uc3QgZW5kRGVsZXRlSXRlbUNsb2NrID0gZGVsZXRlSXRlbS5jbG9jayArIGRlbGV0ZUl0ZW0ubGVuXG4gICAgICBmb3IgKFxuICAgICAgICBsZXQgc2kgPSBmaW5kSW5kZXhTUyhzdHJ1Y3RzLCBkZWxldGVJdGVtLmNsb2NrKSwgc3RydWN0ID0gc3RydWN0c1tzaV07XG4gICAgICAgIHNpIDwgc3RydWN0cy5sZW5ndGggJiYgc3RydWN0LmlkLmNsb2NrIDwgZW5kRGVsZXRlSXRlbUNsb2NrO1xuICAgICAgICBzdHJ1Y3QgPSBzdHJ1Y3RzWysrc2ldXG4gICAgICApIHtcbiAgICAgICAgY29uc3Qgc3RydWN0ID0gc3RydWN0c1tzaV1cbiAgICAgICAgaWYgKGRlbGV0ZUl0ZW0uY2xvY2sgKyBkZWxldGVJdGVtLmxlbiA8PSBzdHJ1Y3QuaWQuY2xvY2spIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdHJ1Y3QgaW5zdGFuY2VvZiBJdGVtICYmIHN0cnVjdC5kZWxldGVkICYmICFzdHJ1Y3Qua2VlcCAmJiBnY0ZpbHRlcihzdHJ1Y3QpKSB7XG4gICAgICAgICAgc3RydWN0LmdjKHN0b3JlLCBmYWxzZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7RGVsZXRlU2V0fSBkc1xuICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAqL1xuY29uc3QgdHJ5TWVyZ2VEZWxldGVTZXQgPSAoZHMsIHN0b3JlKSA9PiB7XG4gIC8vIHRyeSB0byBtZXJnZSBkZWxldGVkIC8gZ2MnZCBpdGVtc1xuICAvLyBtZXJnZSBmcm9tIHJpZ2h0IHRvIGxlZnQgZm9yIGJldHRlciBlZmZpY2llbmN5IGFuZCBzbyB3ZSBkb24ndCBtaXNzIGFueSBtZXJnZSB0YXJnZXRzXG4gIGRzLmNsaWVudHMuZm9yRWFjaCgoZGVsZXRlSXRlbXMsIGNsaWVudCkgPT4ge1xuICAgIGNvbnN0IHN0cnVjdHMgPSAvKiogQHR5cGUge0FycmF5PEdDfEl0ZW0+fSAqLyAoc3RvcmUuY2xpZW50cy5nZXQoY2xpZW50KSlcbiAgICBmb3IgKGxldCBkaSA9IGRlbGV0ZUl0ZW1zLmxlbmd0aCAtIDE7IGRpID49IDA7IGRpLS0pIHtcbiAgICAgIGNvbnN0IGRlbGV0ZUl0ZW0gPSBkZWxldGVJdGVtc1tkaV1cbiAgICAgIC8vIHN0YXJ0IHdpdGggbWVyZ2luZyB0aGUgaXRlbSBuZXh0IHRvIHRoZSBsYXN0IGRlbGV0ZWQgaXRlbVxuICAgICAgY29uc3QgbW9zdFJpZ2h0SW5kZXhUb0NoZWNrID0gbWF0aC5taW4oc3RydWN0cy5sZW5ndGggLSAxLCAxICsgZmluZEluZGV4U1Moc3RydWN0cywgZGVsZXRlSXRlbS5jbG9jayArIGRlbGV0ZUl0ZW0ubGVuIC0gMSkpXG4gICAgICBmb3IgKFxuICAgICAgICBsZXQgc2kgPSBtb3N0UmlnaHRJbmRleFRvQ2hlY2ssIHN0cnVjdCA9IHN0cnVjdHNbc2ldO1xuICAgICAgICBzaSA+IDAgJiYgc3RydWN0LmlkLmNsb2NrID49IGRlbGV0ZUl0ZW0uY2xvY2s7XG4gICAgICAgIHN0cnVjdCA9IHN0cnVjdHNbc2ldXG4gICAgICApIHtcbiAgICAgICAgc2kgLT0gMSArIHRyeVRvTWVyZ2VXaXRoTGVmdHMoc3RydWN0cywgc2kpXG4gICAgICB9XG4gICAgfVxuICB9KVxufVxuXG4vKipcbiAqIEBwYXJhbSB7RGVsZXRlU2V0fSBkc1xuICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oSXRlbSk6Ym9vbGVhbn0gZ2NGaWx0ZXJcbiAqL1xuZXhwb3J0IGNvbnN0IHRyeUdjID0gKGRzLCBzdG9yZSwgZ2NGaWx0ZXIpID0+IHtcbiAgdHJ5R2NEZWxldGVTZXQoZHMsIHN0b3JlLCBnY0ZpbHRlcilcbiAgdHJ5TWVyZ2VEZWxldGVTZXQoZHMsIHN0b3JlKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8VHJhbnNhY3Rpb24+fSB0cmFuc2FjdGlvbkNsZWFudXBzXG4gKiBAcGFyYW0ge251bWJlcn0gaVxuICovXG5jb25zdCBjbGVhbnVwVHJhbnNhY3Rpb25zID0gKHRyYW5zYWN0aW9uQ2xlYW51cHMsIGkpID0+IHtcbiAgaWYgKGkgPCB0cmFuc2FjdGlvbkNsZWFudXBzLmxlbmd0aCkge1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gdHJhbnNhY3Rpb25DbGVhbnVwc1tpXVxuICAgIGNvbnN0IGRvYyA9IHRyYW5zYWN0aW9uLmRvY1xuICAgIGNvbnN0IHN0b3JlID0gZG9jLnN0b3JlXG4gICAgY29uc3QgZHMgPSB0cmFuc2FjdGlvbi5kZWxldGVTZXRcbiAgICBjb25zdCBtZXJnZVN0cnVjdHMgPSB0cmFuc2FjdGlvbi5fbWVyZ2VTdHJ1Y3RzXG4gICAgdHJ5IHtcbiAgICAgIHNvcnRBbmRNZXJnZURlbGV0ZVNldChkcylcbiAgICAgIHRyYW5zYWN0aW9uLmFmdGVyU3RhdGUgPSBnZXRTdGF0ZVZlY3Rvcih0cmFuc2FjdGlvbi5kb2Muc3RvcmUpXG4gICAgICBkb2MuZW1pdCgnYmVmb3JlT2JzZXJ2ZXJDYWxscycsIFt0cmFuc2FjdGlvbiwgZG9jXSlcbiAgICAgIC8qKlxuICAgICAgICogQW4gYXJyYXkgb2YgZXZlbnQgY2FsbGJhY2tzLlxuICAgICAgICpcbiAgICAgICAqIEVhY2ggY2FsbGJhY2sgaXMgY2FsbGVkIGV2ZW4gaWYgdGhlIG90aGVyIG9uZXMgdGhyb3cgZXJyb3JzLlxuICAgICAgICpcbiAgICAgICAqIEB0eXBlIHtBcnJheTxmdW5jdGlvbigpOnZvaWQ+fVxuICAgICAgICovXG4gICAgICBjb25zdCBmcyA9IFtdXG4gICAgICAvLyBvYnNlcnZlIGV2ZW50cyBvbiBjaGFuZ2VkIHR5cGVzXG4gICAgICB0cmFuc2FjdGlvbi5jaGFuZ2VkLmZvckVhY2goKHN1YnMsIGl0ZW10eXBlKSA9PlxuICAgICAgICBmcy5wdXNoKCgpID0+IHtcbiAgICAgICAgICBpZiAoaXRlbXR5cGUuX2l0ZW0gPT09IG51bGwgfHwgIWl0ZW10eXBlLl9pdGVtLmRlbGV0ZWQpIHtcbiAgICAgICAgICAgIGl0ZW10eXBlLl9jYWxsT2JzZXJ2ZXIodHJhbnNhY3Rpb24sIHN1YnMpXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgZnMucHVzaCgoKSA9PiB7XG4gICAgICAgIC8vIGRlZXAgb2JzZXJ2ZSBldmVudHNcbiAgICAgICAgdHJhbnNhY3Rpb24uY2hhbmdlZFBhcmVudFR5cGVzLmZvckVhY2goKGV2ZW50cywgdHlwZSkgPT4ge1xuICAgICAgICAgIC8vIFdlIG5lZWQgdG8gdGhpbmsgYWJvdXQgdGhlIHBvc3NpYmlsaXR5IHRoYXQgdGhlIHVzZXIgdHJhbnNmb3JtcyB0aGVcbiAgICAgICAgICAvLyBZLkRvYyBpbiB0aGUgZXZlbnQuXG4gICAgICAgICAgaWYgKHR5cGUuX2RFSC5sLmxlbmd0aCA+IDAgJiYgKHR5cGUuX2l0ZW0gPT09IG51bGwgfHwgIXR5cGUuX2l0ZW0uZGVsZXRlZCkpIHtcbiAgICAgICAgICAgIGV2ZW50cyA9IGV2ZW50c1xuICAgICAgICAgICAgICAuZmlsdGVyKGV2ZW50ID0+XG4gICAgICAgICAgICAgICAgZXZlbnQudGFyZ2V0Ll9pdGVtID09PSBudWxsIHx8ICFldmVudC50YXJnZXQuX2l0ZW0uZGVsZXRlZFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICBldmVudHNcbiAgICAgICAgICAgICAgLmZvckVhY2goZXZlbnQgPT4ge1xuICAgICAgICAgICAgICAgIGV2ZW50LmN1cnJlbnRUYXJnZXQgPSB0eXBlXG4gICAgICAgICAgICAgICAgLy8gcGF0aCBpcyByZWxhdGl2ZSB0byB0aGUgY3VycmVudCB0YXJnZXRcbiAgICAgICAgICAgICAgICBldmVudC5fcGF0aCA9IG51bGxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC8vIHNvcnQgZXZlbnRzIGJ5IHBhdGggbGVuZ3RoIHNvIHRoYXQgdG9wLWxldmVsIGV2ZW50cyBhcmUgZmlyZWQgZmlyc3QuXG4gICAgICAgICAgICBldmVudHNcbiAgICAgICAgICAgICAgLnNvcnQoKGV2ZW50MSwgZXZlbnQyKSA9PiBldmVudDEucGF0aC5sZW5ndGggLSBldmVudDIucGF0aC5sZW5ndGgpXG4gICAgICAgICAgICBmcy5wdXNoKCgpID0+IHtcbiAgICAgICAgICAgICAgLy8gV2UgZG9uJ3QgbmVlZCB0byBjaGVjayBmb3IgZXZlbnRzLmxlbmd0aFxuICAgICAgICAgICAgICAvLyBiZWNhdXNlIHdlIGtub3cgaXQgaGFzIGF0IGxlYXN0IG9uZSBlbGVtZW50XG4gICAgICAgICAgICAgIGNhbGxFdmVudEhhbmRsZXJMaXN0ZW5lcnModHlwZS5fZEVILCBldmVudHMsIHRyYW5zYWN0aW9uKVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIGZzLnB1c2goKCkgPT4gZG9jLmVtaXQoJ2FmdGVyVHJhbnNhY3Rpb24nLCBbdHJhbnNhY3Rpb24sIGRvY10pKVxuICAgICAgICBmcy5wdXNoKCgpID0+IHtcbiAgICAgICAgICBpZiAodHJhbnNhY3Rpb24uX25lZWRGb3JtYXR0aW5nQ2xlYW51cCkge1xuICAgICAgICAgICAgY2xlYW51cFlUZXh0QWZ0ZXJUcmFuc2FjdGlvbih0cmFuc2FjdGlvbilcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgICAgY2FsbEFsbChmcywgW10pXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIC8vIFJlcGxhY2UgZGVsZXRlZCBpdGVtcyB3aXRoIEl0ZW1EZWxldGVkIC8gR0MuXG4gICAgICAvLyBUaGlzIGlzIHdoZXJlIGNvbnRlbnQgaXMgYWN0dWFsbHkgcmVtb3ZlIGZyb20gdGhlIFlqcyBEb2MuXG4gICAgICBpZiAoZG9jLmdjKSB7XG4gICAgICAgIHRyeUdjRGVsZXRlU2V0KGRzLCBzdG9yZSwgZG9jLmdjRmlsdGVyKVxuICAgICAgfVxuICAgICAgdHJ5TWVyZ2VEZWxldGVTZXQoZHMsIHN0b3JlKVxuXG4gICAgICAvLyBvbiBhbGwgYWZmZWN0ZWQgc3RvcmUuY2xpZW50cyBwcm9wcywgdHJ5IHRvIG1lcmdlXG4gICAgICB0cmFuc2FjdGlvbi5hZnRlclN0YXRlLmZvckVhY2goKGNsb2NrLCBjbGllbnQpID0+IHtcbiAgICAgICAgY29uc3QgYmVmb3JlQ2xvY2sgPSB0cmFuc2FjdGlvbi5iZWZvcmVTdGF0ZS5nZXQoY2xpZW50KSB8fCAwXG4gICAgICAgIGlmIChiZWZvcmVDbG9jayAhPT0gY2xvY2spIHtcbiAgICAgICAgICBjb25zdCBzdHJ1Y3RzID0gLyoqIEB0eXBlIHtBcnJheTxHQ3xJdGVtPn0gKi8gKHN0b3JlLmNsaWVudHMuZ2V0KGNsaWVudCkpXG4gICAgICAgICAgLy8gd2UgaXRlcmF0ZSBmcm9tIHJpZ2h0IHRvIGxlZnQgc28gd2UgY2FuIHNhZmVseSByZW1vdmUgZW50cmllc1xuICAgICAgICAgIGNvbnN0IGZpcnN0Q2hhbmdlUG9zID0gbWF0aC5tYXgoZmluZEluZGV4U1Moc3RydWN0cywgYmVmb3JlQ2xvY2spLCAxKVxuICAgICAgICAgIGZvciAobGV0IGkgPSBzdHJ1Y3RzLmxlbmd0aCAtIDE7IGkgPj0gZmlyc3RDaGFuZ2VQb3M7KSB7XG4gICAgICAgICAgICBpIC09IDEgKyB0cnlUb01lcmdlV2l0aExlZnRzKHN0cnVjdHMsIGkpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLy8gdHJ5IHRvIG1lcmdlIG1lcmdlU3RydWN0c1xuICAgICAgLy8gQHRvZG86IGl0IG1ha2VzIG1vcmUgc2Vuc2UgdG8gdHJhbnNmb3JtIG1lcmdlU3RydWN0cyB0byBhIERTLCBzb3J0IGl0LCBhbmQgbWVyZ2UgZnJvbSByaWdodCB0byBsZWZ0XG4gICAgICAvLyAgICAgICAgYnV0IGF0IHRoZSBtb21lbnQgRFMgZG9lcyBub3QgaGFuZGxlIGR1cGxpY2F0ZXNcbiAgICAgIGZvciAobGV0IGkgPSBtZXJnZVN0cnVjdHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgY29uc3QgeyBjbGllbnQsIGNsb2NrIH0gPSBtZXJnZVN0cnVjdHNbaV0uaWRcbiAgICAgICAgY29uc3Qgc3RydWN0cyA9IC8qKiBAdHlwZSB7QXJyYXk8R0N8SXRlbT59ICovIChzdG9yZS5jbGllbnRzLmdldChjbGllbnQpKVxuICAgICAgICBjb25zdCByZXBsYWNlZFN0cnVjdFBvcyA9IGZpbmRJbmRleFNTKHN0cnVjdHMsIGNsb2NrKVxuICAgICAgICBpZiAocmVwbGFjZWRTdHJ1Y3RQb3MgKyAxIDwgc3RydWN0cy5sZW5ndGgpIHtcbiAgICAgICAgICBpZiAodHJ5VG9NZXJnZVdpdGhMZWZ0cyhzdHJ1Y3RzLCByZXBsYWNlZFN0cnVjdFBvcyArIDEpID4gMSkge1xuICAgICAgICAgICAgY29udGludWUgLy8gbm8gbmVlZCB0byBwZXJmb3JtIG5leHQgY2hlY2ssIGJvdGggYXJlIGFscmVhZHkgbWVyZ2VkXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChyZXBsYWNlZFN0cnVjdFBvcyA+IDApIHtcbiAgICAgICAgICB0cnlUb01lcmdlV2l0aExlZnRzKHN0cnVjdHMsIHJlcGxhY2VkU3RydWN0UG9zKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIXRyYW5zYWN0aW9uLmxvY2FsICYmIHRyYW5zYWN0aW9uLmFmdGVyU3RhdGUuZ2V0KGRvYy5jbGllbnRJRCkgIT09IHRyYW5zYWN0aW9uLmJlZm9yZVN0YXRlLmdldChkb2MuY2xpZW50SUQpKSB7XG4gICAgICAgIGxvZ2dpbmcucHJpbnQobG9nZ2luZy5PUkFOR0UsIGxvZ2dpbmcuQk9MRCwgJ1t5anNdICcsIGxvZ2dpbmcuVU5CT0xELCBsb2dnaW5nLlJFRCwgJ0NoYW5nZWQgdGhlIGNsaWVudC1pZCBiZWNhdXNlIGFub3RoZXIgY2xpZW50IHNlZW1zIHRvIGJlIHVzaW5nIGl0LicpXG4gICAgICAgIGRvYy5jbGllbnRJRCA9IGdlbmVyYXRlTmV3Q2xpZW50SWQoKVxuICAgICAgfVxuICAgICAgLy8gQHRvZG8gTWVyZ2UgYWxsIHRoZSB0cmFuc2FjdGlvbnMgaW50byBvbmUgYW5kIHByb3ZpZGUgc2VuZCB0aGUgZGF0YSBhcyBhIHNpbmdsZSB1cGRhdGUgbWVzc2FnZVxuICAgICAgZG9jLmVtaXQoJ2FmdGVyVHJhbnNhY3Rpb25DbGVhbnVwJywgW3RyYW5zYWN0aW9uLCBkb2NdKVxuICAgICAgaWYgKGRvYy5fb2JzZXJ2ZXJzLmhhcygndXBkYXRlJykpIHtcbiAgICAgICAgY29uc3QgZW5jb2RlciA9IG5ldyBVcGRhdGVFbmNvZGVyVjEoKVxuICAgICAgICBjb25zdCBoYXNDb250ZW50ID0gd3JpdGVVcGRhdGVNZXNzYWdlRnJvbVRyYW5zYWN0aW9uKGVuY29kZXIsIHRyYW5zYWN0aW9uKVxuICAgICAgICBpZiAoaGFzQ29udGVudCkge1xuICAgICAgICAgIGRvYy5lbWl0KCd1cGRhdGUnLCBbZW5jb2Rlci50b1VpbnQ4QXJyYXkoKSwgdHJhbnNhY3Rpb24ub3JpZ2luLCBkb2MsIHRyYW5zYWN0aW9uXSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGRvYy5fb2JzZXJ2ZXJzLmhhcygndXBkYXRlVjInKSkge1xuICAgICAgICBjb25zdCBlbmNvZGVyID0gbmV3IFVwZGF0ZUVuY29kZXJWMigpXG4gICAgICAgIGNvbnN0IGhhc0NvbnRlbnQgPSB3cml0ZVVwZGF0ZU1lc3NhZ2VGcm9tVHJhbnNhY3Rpb24oZW5jb2RlciwgdHJhbnNhY3Rpb24pXG4gICAgICAgIGlmIChoYXNDb250ZW50KSB7XG4gICAgICAgICAgZG9jLmVtaXQoJ3VwZGF0ZVYyJywgW2VuY29kZXIudG9VaW50OEFycmF5KCksIHRyYW5zYWN0aW9uLm9yaWdpbiwgZG9jLCB0cmFuc2FjdGlvbl0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgc3ViZG9jc0FkZGVkLCBzdWJkb2NzTG9hZGVkLCBzdWJkb2NzUmVtb3ZlZCB9ID0gdHJhbnNhY3Rpb25cbiAgICAgIGlmIChzdWJkb2NzQWRkZWQuc2l6ZSA+IDAgfHwgc3ViZG9jc1JlbW92ZWQuc2l6ZSA+IDAgfHwgc3ViZG9jc0xvYWRlZC5zaXplID4gMCkge1xuICAgICAgICBzdWJkb2NzQWRkZWQuZm9yRWFjaChzdWJkb2MgPT4ge1xuICAgICAgICAgIHN1YmRvYy5jbGllbnRJRCA9IGRvYy5jbGllbnRJRFxuICAgICAgICAgIGlmIChzdWJkb2MuY29sbGVjdGlvbmlkID09IG51bGwpIHtcbiAgICAgICAgICAgIHN1YmRvYy5jb2xsZWN0aW9uaWQgPSBkb2MuY29sbGVjdGlvbmlkXG4gICAgICAgICAgfVxuICAgICAgICAgIGRvYy5zdWJkb2NzLmFkZChzdWJkb2MpXG4gICAgICAgIH0pXG4gICAgICAgIHN1YmRvY3NSZW1vdmVkLmZvckVhY2goc3ViZG9jID0+IGRvYy5zdWJkb2NzLmRlbGV0ZShzdWJkb2MpKVxuICAgICAgICBkb2MuZW1pdCgnc3ViZG9jcycsIFt7IGxvYWRlZDogc3ViZG9jc0xvYWRlZCwgYWRkZWQ6IHN1YmRvY3NBZGRlZCwgcmVtb3ZlZDogc3ViZG9jc1JlbW92ZWQgfSwgZG9jLCB0cmFuc2FjdGlvbl0pXG4gICAgICAgIHN1YmRvY3NSZW1vdmVkLmZvckVhY2goc3ViZG9jID0+IHN1YmRvYy5kZXN0cm95KCkpXG4gICAgICB9XG5cbiAgICAgIGlmICh0cmFuc2FjdGlvbkNsZWFudXBzLmxlbmd0aCA8PSBpICsgMSkge1xuICAgICAgICBkb2MuX3RyYW5zYWN0aW9uQ2xlYW51cHMgPSBbXVxuICAgICAgICBkb2MuZW1pdCgnYWZ0ZXJBbGxUcmFuc2FjdGlvbnMnLCBbZG9jLCB0cmFuc2FjdGlvbkNsZWFudXBzXSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNsZWFudXBUcmFuc2FjdGlvbnModHJhbnNhY3Rpb25DbGVhbnVwcywgaSArIDEpXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogSW1wbGVtZW50cyB0aGUgZnVuY3Rpb25hbGl0eSBvZiBgeS50cmFuc2FjdCgoKT0+ey4ufSlgXG4gKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7RG9jfSBkb2NcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oVHJhbnNhY3Rpb24pOlR9IGZcbiAqIEBwYXJhbSB7YW55fSBbb3JpZ2luPXRydWVdXG4gKiBAcmV0dXJuIHtUfVxuICpcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgdHJhbnNhY3QgPSAoZG9jLCBmLCBvcmlnaW4gPSBudWxsLCBsb2NhbCA9IHRydWUpID0+IHtcbiAgY29uc3QgdHJhbnNhY3Rpb25DbGVhbnVwcyA9IGRvYy5fdHJhbnNhY3Rpb25DbGVhbnVwc1xuICBsZXQgaW5pdGlhbENhbGwgPSBmYWxzZVxuICAvKipcbiAgICogQHR5cGUge2FueX1cbiAgICovXG4gIGxldCByZXN1bHQgPSBudWxsXG4gIGlmIChkb2MuX3RyYW5zYWN0aW9uID09PSBudWxsKSB7XG4gICAgaW5pdGlhbENhbGwgPSB0cnVlXG4gICAgZG9jLl90cmFuc2FjdGlvbiA9IG5ldyBUcmFuc2FjdGlvbihkb2MsIG9yaWdpbiwgbG9jYWwpXG4gICAgdHJhbnNhY3Rpb25DbGVhbnVwcy5wdXNoKGRvYy5fdHJhbnNhY3Rpb24pXG4gICAgaWYgKHRyYW5zYWN0aW9uQ2xlYW51cHMubGVuZ3RoID09PSAxKSB7XG4gICAgICBkb2MuZW1pdCgnYmVmb3JlQWxsVHJhbnNhY3Rpb25zJywgW2RvY10pXG4gICAgfVxuICAgIGRvYy5lbWl0KCdiZWZvcmVUcmFuc2FjdGlvbicsIFtkb2MuX3RyYW5zYWN0aW9uLCBkb2NdKVxuICB9XG4gIHRyeSB7XG4gICAgcmVzdWx0ID0gZihkb2MuX3RyYW5zYWN0aW9uKVxuICB9IGZpbmFsbHkge1xuICAgIGlmIChpbml0aWFsQ2FsbCkge1xuICAgICAgY29uc3QgZmluaXNoQ2xlYW51cCA9IGRvYy5fdHJhbnNhY3Rpb24gPT09IHRyYW5zYWN0aW9uQ2xlYW51cHNbMF1cbiAgICAgIGRvYy5fdHJhbnNhY3Rpb24gPSBudWxsXG4gICAgICBpZiAoZmluaXNoQ2xlYW51cCkge1xuICAgICAgICAvLyBUaGUgZmlyc3QgdHJhbnNhY3Rpb24gZW5kZWQsIG5vdyBwcm9jZXNzIG9ic2VydmVyIGNhbGxzLlxuICAgICAgICAvLyBPYnNlcnZlciBjYWxsIG1heSBjcmVhdGUgbmV3IHRyYW5zYWN0aW9ucyBmb3Igd2hpY2ggd2UgbmVlZCB0byBjYWxsIHRoZSBvYnNlcnZlcnMgYW5kIGRvIGNsZWFudXAuXG4gICAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gbmVzdCB0aGVzZSBjYWxscywgc28gd2UgZXhlY3V0ZSB0aGVzZSBjYWxscyBvbmUgYWZ0ZXJcbiAgICAgICAgLy8gYW5vdGhlci5cbiAgICAgICAgLy8gQWxzbyB3ZSBuZWVkIHRvIGVuc3VyZSB0aGF0IGFsbCBjbGVhbnVwcyBhcmUgY2FsbGVkLCBldmVuIGlmIHRoZVxuICAgICAgICAvLyBvYnNlcnZlcyB0aHJvdyBlcnJvcnMuXG4gICAgICAgIC8vIFRoaXMgZmlsZSBpcyBmdWxsIG9mIGhhY2t5IHRyeSB7fSBmaW5hbGx5IHt9IGJsb2NrcyB0byBlbnN1cmUgdGhhdCBhblxuICAgICAgICAvLyBldmVudCBjYW4gdGhyb3cgZXJyb3JzIGFuZCBhbHNvIHRoYXQgdGhlIGNsZWFudXAgaXMgY2FsbGVkLlxuICAgICAgICBjbGVhbnVwVHJhbnNhY3Rpb25zKHRyYW5zYWN0aW9uQ2xlYW51cHMsIDApXG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cbiIsICJpbXBvcnQge1xuICBtZXJnZURlbGV0ZVNldHMsXG4gIGl0ZXJhdGVEZWxldGVkU3RydWN0cyxcbiAga2VlcEl0ZW0sXG4gIHRyYW5zYWN0LFxuICBjcmVhdGVJRCxcbiAgcmVkb0l0ZW0sXG4gIGlzUGFyZW50T2YsXG4gIGZvbGxvd1JlZG9uZSxcbiAgZ2V0SXRlbUNsZWFuU3RhcnQsXG4gIGlzRGVsZXRlZCxcbiAgYWRkVG9EZWxldGVTZXQsXG4gIFlFdmVudCwgVHJhbnNhY3Rpb24sIERvYywgSXRlbSwgR0MsIERlbGV0ZVNldCwgQWJzdHJhY3RUeXBlIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbn0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJ1xuXG5pbXBvcnQgKiBhcyB0aW1lIGZyb20gJ2xpYjAvdGltZSdcbmltcG9ydCAqIGFzIGFycmF5IGZyb20gJ2xpYjAvYXJyYXknXG5pbXBvcnQgKiBhcyBsb2dnaW5nIGZyb20gJ2xpYjAvbG9nZ2luZydcbmltcG9ydCB7IE9ic2VydmFibGVWMiB9IGZyb20gJ2xpYjAvb2JzZXJ2YWJsZSdcblxuZXhwb3J0IGNsYXNzIFN0YWNrSXRlbSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0RlbGV0ZVNldH0gZGVsZXRpb25zXG4gICAqIEBwYXJhbSB7RGVsZXRlU2V0fSBpbnNlcnRpb25zXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoZGVsZXRpb25zLCBpbnNlcnRpb25zKSB7XG4gICAgdGhpcy5pbnNlcnRpb25zID0gaW5zZXJ0aW9uc1xuICAgIHRoaXMuZGVsZXRpb25zID0gZGVsZXRpb25zXG4gICAgLyoqXG4gICAgICogVXNlIHRoaXMgdG8gc2F2ZSBhbmQgcmVzdG9yZSBtZXRhZGF0YSBsaWtlIHNlbGVjdGlvbiByYW5nZVxuICAgICAqL1xuICAgIHRoaXMubWV0YSA9IG5ldyBNYXAoKVxuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyXG4gKiBAcGFyYW0ge1VuZG9NYW5hZ2VyfSB1bVxuICogQHBhcmFtIHtTdGFja0l0ZW19IHN0YWNrSXRlbVxuICovXG5jb25zdCBjbGVhclVuZG9NYW5hZ2VyU3RhY2tJdGVtID0gKHRyLCB1bSwgc3RhY2tJdGVtKSA9PiB7XG4gIGl0ZXJhdGVEZWxldGVkU3RydWN0cyh0ciwgc3RhY2tJdGVtLmRlbGV0aW9ucywgaXRlbSA9PiB7XG4gICAgaWYgKGl0ZW0gaW5zdGFuY2VvZiBJdGVtICYmIHVtLnNjb3BlLnNvbWUodHlwZSA9PiB0eXBlID09PSB0ci5kb2MgfHwgaXNQYXJlbnRPZigvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAodHlwZSksIGl0ZW0pKSkge1xuICAgICAga2VlcEl0ZW0oaXRlbSwgZmFsc2UpXG4gICAgfVxuICB9KVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VW5kb01hbmFnZXJ9IHVuZG9NYW5hZ2VyXG4gKiBAcGFyYW0ge0FycmF5PFN0YWNrSXRlbT59IHN0YWNrXG4gKiBAcGFyYW0geyd1bmRvJ3wncmVkbyd9IGV2ZW50VHlwZVxuICogQHJldHVybiB7U3RhY2tJdGVtP31cbiAqL1xuY29uc3QgcG9wU3RhY2tJdGVtID0gKHVuZG9NYW5hZ2VyLCBzdGFjaywgZXZlbnRUeXBlKSA9PiB7XG4gIC8qKlxuICAgKiBLZWVwIGEgcmVmZXJlbmNlIHRvIHRoZSB0cmFuc2FjdGlvbiBzbyB3ZSBjYW4gZmlyZSB0aGUgZXZlbnQgd2l0aCB0aGUgY2hhbmdlZFBhcmVudFR5cGVzXG4gICAqIEB0eXBlIHthbnl9XG4gICAqL1xuICBsZXQgX3RyID0gbnVsbFxuICBjb25zdCBkb2MgPSB1bmRvTWFuYWdlci5kb2NcbiAgY29uc3Qgc2NvcGUgPSB1bmRvTWFuYWdlci5zY29wZVxuICB0cmFuc2FjdChkb2MsIHRyYW5zYWN0aW9uID0+IHtcbiAgICB3aGlsZSAoc3RhY2subGVuZ3RoID4gMCAmJiB1bmRvTWFuYWdlci5jdXJyU3RhY2tJdGVtID09PSBudWxsKSB7XG4gICAgICBjb25zdCBzdG9yZSA9IGRvYy5zdG9yZVxuICAgICAgY29uc3Qgc3RhY2tJdGVtID0gLyoqIEB0eXBlIHtTdGFja0l0ZW19ICovIChzdGFjay5wb3AoKSlcbiAgICAgIC8qKlxuICAgICAgICogQHR5cGUge1NldDxJdGVtPn1cbiAgICAgICAqL1xuICAgICAgY29uc3QgaXRlbXNUb1JlZG8gPSBuZXcgU2V0KClcbiAgICAgIC8qKlxuICAgICAgICogQHR5cGUge0FycmF5PEl0ZW0+fVxuICAgICAgICovXG4gICAgICBjb25zdCBpdGVtc1RvRGVsZXRlID0gW11cbiAgICAgIGxldCBwZXJmb3JtZWRDaGFuZ2UgPSBmYWxzZVxuICAgICAgaXRlcmF0ZURlbGV0ZWRTdHJ1Y3RzKHRyYW5zYWN0aW9uLCBzdGFja0l0ZW0uaW5zZXJ0aW9ucywgc3RydWN0ID0+IHtcbiAgICAgICAgaWYgKHN0cnVjdCBpbnN0YW5jZW9mIEl0ZW0pIHtcbiAgICAgICAgICBpZiAoc3RydWN0LnJlZG9uZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IHsgaXRlbSwgZGlmZiB9ID0gZm9sbG93UmVkb25lKHN0b3JlLCBzdHJ1Y3QuaWQpXG4gICAgICAgICAgICBpZiAoZGlmZiA+IDApIHtcbiAgICAgICAgICAgICAgaXRlbSA9IGdldEl0ZW1DbGVhblN0YXJ0KHRyYW5zYWN0aW9uLCBjcmVhdGVJRChpdGVtLmlkLmNsaWVudCwgaXRlbS5pZC5jbG9jayArIGRpZmYpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc3RydWN0ID0gaXRlbVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIXN0cnVjdC5kZWxldGVkICYmIHNjb3BlLnNvbWUodHlwZSA9PiB0eXBlID09PSB0cmFuc2FjdGlvbi5kb2MgfHwgaXNQYXJlbnRPZigvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAodHlwZSksIC8qKiBAdHlwZSB7SXRlbX0gKi8gKHN0cnVjdCkpKSkge1xuICAgICAgICAgICAgaXRlbXNUb0RlbGV0ZS5wdXNoKHN0cnVjdClcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBpdGVyYXRlRGVsZXRlZFN0cnVjdHModHJhbnNhY3Rpb24sIHN0YWNrSXRlbS5kZWxldGlvbnMsIHN0cnVjdCA9PiB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzdHJ1Y3QgaW5zdGFuY2VvZiBJdGVtICYmXG4gICAgICAgICAgc2NvcGUuc29tZSh0eXBlID0+IHR5cGUgPT09IHRyYW5zYWN0aW9uLmRvYyB8fCBpc1BhcmVudE9mKC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovICh0eXBlKSwgc3RydWN0KSkgJiZcbiAgICAgICAgICAvLyBOZXZlciByZWRvIHN0cnVjdHMgaW4gc3RhY2tJdGVtLmluc2VydGlvbnMgYmVjYXVzZSB0aGV5IHdlcmUgY3JlYXRlZCBhbmQgZGVsZXRlZCBpbiB0aGUgc2FtZSBjYXB0dXJlIGludGVydmFsLlxuICAgICAgICAgICFpc0RlbGV0ZWQoc3RhY2tJdGVtLmluc2VydGlvbnMsIHN0cnVjdC5pZClcbiAgICAgICAgKSB7XG4gICAgICAgICAgaXRlbXNUb1JlZG8uYWRkKHN0cnVjdClcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIGl0ZW1zVG9SZWRvLmZvckVhY2goc3RydWN0ID0+IHtcbiAgICAgICAgcGVyZm9ybWVkQ2hhbmdlID0gcmVkb0l0ZW0odHJhbnNhY3Rpb24sIHN0cnVjdCwgaXRlbXNUb1JlZG8sIHN0YWNrSXRlbS5pbnNlcnRpb25zLCB1bmRvTWFuYWdlci5pZ25vcmVSZW1vdGVNYXBDaGFuZ2VzLCB1bmRvTWFuYWdlcikgIT09IG51bGwgfHwgcGVyZm9ybWVkQ2hhbmdlXG4gICAgICB9KVxuICAgICAgLy8gV2Ugd2FudCB0byBkZWxldGUgaW4gcmV2ZXJzZSBvcmRlciBzbyB0aGF0IGNoaWxkcmVuIGFyZSBkZWxldGVkIGJlZm9yZVxuICAgICAgLy8gcGFyZW50cywgc28gd2UgaGF2ZSBtb3JlIGluZm9ybWF0aW9uIGF2YWlsYWJsZSB3aGVuIGl0ZW1zIGFyZSBmaWx0ZXJlZC5cbiAgICAgIGZvciAobGV0IGkgPSBpdGVtc1RvRGVsZXRlLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtc1RvRGVsZXRlW2ldXG4gICAgICAgIGlmICh1bmRvTWFuYWdlci5kZWxldGVGaWx0ZXIoaXRlbSkpIHtcbiAgICAgICAgICBpdGVtLmRlbGV0ZSh0cmFuc2FjdGlvbilcbiAgICAgICAgICBwZXJmb3JtZWRDaGFuZ2UgPSB0cnVlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHVuZG9NYW5hZ2VyLmN1cnJTdGFja0l0ZW0gPSBwZXJmb3JtZWRDaGFuZ2UgPyBzdGFja0l0ZW0gOiBudWxsXG4gICAgfVxuICAgIHRyYW5zYWN0aW9uLmNoYW5nZWQuZm9yRWFjaCgoc3ViUHJvcHMsIHR5cGUpID0+IHtcbiAgICAgIC8vIGRlc3Ryb3kgc2VhcmNoIG1hcmtlciBpZiBuZWNlc3NhcnlcbiAgICAgIGlmIChzdWJQcm9wcy5oYXMobnVsbCkgJiYgdHlwZS5fc2VhcmNoTWFya2VyKSB7XG4gICAgICAgIHR5cGUuX3NlYXJjaE1hcmtlci5sZW5ndGggPSAwXG4gICAgICB9XG4gICAgfSlcbiAgICBfdHIgPSB0cmFuc2FjdGlvblxuICB9LCB1bmRvTWFuYWdlcilcbiAgY29uc3QgcmVzID0gdW5kb01hbmFnZXIuY3VyclN0YWNrSXRlbVxuICBpZiAocmVzICE9IG51bGwpIHtcbiAgICBjb25zdCBjaGFuZ2VkUGFyZW50VHlwZXMgPSBfdHIuY2hhbmdlZFBhcmVudFR5cGVzXG4gICAgdW5kb01hbmFnZXIuZW1pdCgnc3RhY2staXRlbS1wb3BwZWQnLCBbeyBzdGFja0l0ZW06IHJlcywgdHlwZTogZXZlbnRUeXBlLCBjaGFuZ2VkUGFyZW50VHlwZXMsIG9yaWdpbjogdW5kb01hbmFnZXIgfSwgdW5kb01hbmFnZXJdKVxuICAgIHVuZG9NYW5hZ2VyLmN1cnJTdGFja0l0ZW0gPSBudWxsXG4gIH1cbiAgcmV0dXJuIHJlc1xufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFVuZG9NYW5hZ2VyT3B0aW9uc1xuICogQHByb3BlcnR5IHtudW1iZXJ9IFtVbmRvTWFuYWdlck9wdGlvbnMuY2FwdHVyZVRpbWVvdXQ9NTAwXVxuICogQHByb3BlcnR5IHtmdW5jdGlvbihUcmFuc2FjdGlvbik6Ym9vbGVhbn0gW1VuZG9NYW5hZ2VyT3B0aW9ucy5jYXB0dXJlVHJhbnNhY3Rpb25dIERvIG5vdCBjYXB0dXJlIGNoYW5nZXMgb2YgYSBUcmFuc2FjdGlvbiBpZiByZXN1bHQgZmFsc2UuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9uKEl0ZW0pOmJvb2xlYW59IFtVbmRvTWFuYWdlck9wdGlvbnMuZGVsZXRlRmlsdGVyPSgpPT50cnVlXSBTb21ldGltZXNcbiAqIGl0IGlzIG5lY2Vzc2FyeSB0byBmaWx0ZXIgd2hhdCBhbiBVbmRvL1JlZG8gb3BlcmF0aW9uIGNhbiBkZWxldGUuIElmIHRoaXNcbiAqIGZpbHRlciByZXR1cm5zIGZhbHNlLCB0aGUgdHlwZS9pdGVtIHdvbid0IGJlIGRlbGV0ZWQgZXZlbiBpdCBpcyBpbiB0aGVcbiAqIHVuZG8vcmVkbyBzY29wZS5cbiAqIEBwcm9wZXJ0eSB7U2V0PGFueT59IFtVbmRvTWFuYWdlck9wdGlvbnMudHJhY2tlZE9yaWdpbnM9bmV3IFNldChbbnVsbF0pXVxuICogQHByb3BlcnR5IHtib29sZWFufSBbaWdub3JlUmVtb3RlTWFwQ2hhbmdlc10gRXhwZXJpbWVudGFsLiBCeSBkZWZhdWx0LCB0aGUgVW5kb01hbmFnZXIgd2lsbCBuZXZlciBvdmVyd3JpdGUgcmVtb3RlIGNoYW5nZXMuIEVuYWJsZSB0aGlzIHByb3BlcnR5IHRvIGVuYWJsZSBvdmVyd3JpdGluZyByZW1vdGUgY2hhbmdlcyBvbiBrZXktdmFsdWUgY2hhbmdlcyAoWS5NYXAsIHByb3BlcnRpZXMgb24gWS5YbWwsIGV0Yy4uKS5cbiAqIEBwcm9wZXJ0eSB7RG9jfSBbZG9jXSBUaGUgZG9jdW1lbnQgdGhhdCB0aGlzIFVuZG9NYW5hZ2VyIG9wZXJhdGVzIG9uLiBPbmx5IG5lZWRlZCBpZiB0eXBlU2NvcGUgaXMgZW1wdHkuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTdGFja0l0ZW1FdmVudFxuICogQHByb3BlcnR5IHtTdGFja0l0ZW19IFN0YWNrSXRlbUV2ZW50LnN0YWNrSXRlbVxuICogQHByb3BlcnR5IHthbnl9IFN0YWNrSXRlbUV2ZW50Lm9yaWdpblxuICogQHByb3BlcnR5IHsndW5kbyd8J3JlZG8nfSBTdGFja0l0ZW1FdmVudC50eXBlXG4gKiBAcHJvcGVydHkge01hcDxBYnN0cmFjdFR5cGU8WUV2ZW50PGFueT4+LEFycmF5PFlFdmVudDxhbnk+Pj59IFN0YWNrSXRlbUV2ZW50LmNoYW5nZWRQYXJlbnRUeXBlc1xuICovXG5cbi8qKlxuICogRmlyZXMgJ3N0YWNrLWl0ZW0tYWRkZWQnIGV2ZW50IHdoZW4gYSBzdGFjayBpdGVtIHdhcyBhZGRlZCB0byBlaXRoZXIgdGhlIHVuZG8tIG9yXG4gKiB0aGUgcmVkby1zdGFjay4gWW91IG1heSBzdG9yZSBhZGRpdGlvbmFsIHN0YWNrIGluZm9ybWF0aW9uIHZpYSB0aGVcbiAqIG1ldGFkYXRhIHByb3BlcnR5IG9uIGBldmVudC5zdGFja0l0ZW0ubWV0YWAgKGl0IGlzIGEgYE1hcGAgb2YgbWV0YWRhdGEgcHJvcGVydGllcykuXG4gKiBGaXJlcyAnc3RhY2staXRlbS1wb3BwZWQnIGV2ZW50IHdoZW4gYSBzdGFjayBpdGVtIHdhcyBwb3BwZWQgZnJvbSBlaXRoZXIgdGhlXG4gKiB1bmRvLSBvciB0aGUgcmVkby1zdGFjay4gWW91IG1heSByZXN0b3JlIHRoZSBzYXZlZCBzdGFjayBpbmZvcm1hdGlvbiBmcm9tIGBldmVudC5zdGFja0l0ZW0ubWV0YWAuXG4gKlxuICogQGV4dGVuZHMge09ic2VydmFibGVWMjx7J3N0YWNrLWl0ZW0tYWRkZWQnOmZ1bmN0aW9uKFN0YWNrSXRlbUV2ZW50LCBVbmRvTWFuYWdlcik6dm9pZCwgJ3N0YWNrLWl0ZW0tcG9wcGVkJzogZnVuY3Rpb24oU3RhY2tJdGVtRXZlbnQsIFVuZG9NYW5hZ2VyKTp2b2lkLCAnc3RhY2stY2xlYXJlZCc6IGZ1bmN0aW9uKHsgdW5kb1N0YWNrQ2xlYXJlZDogYm9vbGVhbiwgcmVkb1N0YWNrQ2xlYXJlZDogYm9vbGVhbiB9KTp2b2lkLCAnc3RhY2staXRlbS11cGRhdGVkJzogZnVuY3Rpb24oU3RhY2tJdGVtRXZlbnQsIFVuZG9NYW5hZ2VyKTp2b2lkIH0+fVxuICovXG5leHBvcnQgY2xhc3MgVW5kb01hbmFnZXIgZXh0ZW5kcyBPYnNlcnZhYmxlVjIge1xuICAvKipcbiAgICogQHBhcmFtIHtEb2N8QWJzdHJhY3RUeXBlPGFueT58QXJyYXk8QWJzdHJhY3RUeXBlPGFueT4+fSB0eXBlU2NvcGUgTGltaXRzIHRoZSBzY29wZSBvZiB0aGUgVW5kb01hbmFnZXIuIElmIHRoaXMgaXMgc2V0IHRvIGEgeWRvYyBpbnN0YW5jZSwgYWxsIGNoYW5nZXMgb24gdGhhdCB5ZG9jIHdpbGwgYmUgdW5kb25lLiBJZiBzZXQgdG8gYSBzcGVjaWZpYyB0eXBlLCBvbmx5IGNoYW5nZXMgb24gdGhhdCB0eXBlIG9yIGl0cyBjaGlsZHJlbiB3aWxsIGJlIHVuZG9uZS4gQWxzbyBhY2NlcHRzIGFuIGFycmF5IG9mIHR5cGVzLlxuICAgKiBAcGFyYW0ge1VuZG9NYW5hZ2VyT3B0aW9uc30gb3B0aW9uc1xuICAgKi9cbiAgY29uc3RydWN0b3IgKHR5cGVTY29wZSwge1xuICAgIGNhcHR1cmVUaW1lb3V0ID0gNTAwLFxuICAgIGNhcHR1cmVUcmFuc2FjdGlvbiA9IF90ciA9PiB0cnVlLFxuICAgIGRlbGV0ZUZpbHRlciA9ICgpID0+IHRydWUsXG4gICAgdHJhY2tlZE9yaWdpbnMgPSBuZXcgU2V0KFtudWxsXSksXG4gICAgaWdub3JlUmVtb3RlTWFwQ2hhbmdlcyA9IGZhbHNlLFxuICAgIGRvYyA9IC8qKiBAdHlwZSB7RG9jfSAqLyAoYXJyYXkuaXNBcnJheSh0eXBlU2NvcGUpID8gdHlwZVNjb3BlWzBdLmRvYyA6IHR5cGVTY29wZSBpbnN0YW5jZW9mIERvYyA/IHR5cGVTY29wZSA6IHR5cGVTY29wZS5kb2MpXG4gIH0gPSB7fSkge1xuICAgIHN1cGVyKClcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8QWJzdHJhY3RUeXBlPGFueT4gfCBEb2M+fVxuICAgICAqL1xuICAgIHRoaXMuc2NvcGUgPSBbXVxuICAgIHRoaXMuZG9jID0gZG9jXG4gICAgdGhpcy5hZGRUb1Njb3BlKHR5cGVTY29wZSlcbiAgICB0aGlzLmRlbGV0ZUZpbHRlciA9IGRlbGV0ZUZpbHRlclxuICAgIHRyYWNrZWRPcmlnaW5zLmFkZCh0aGlzKVxuICAgIHRoaXMudHJhY2tlZE9yaWdpbnMgPSB0cmFja2VkT3JpZ2luc1xuICAgIHRoaXMuY2FwdHVyZVRyYW5zYWN0aW9uID0gY2FwdHVyZVRyYW5zYWN0aW9uXG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PFN0YWNrSXRlbT59XG4gICAgICovXG4gICAgdGhpcy51bmRvU3RhY2sgPSBbXVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxTdGFja0l0ZW0+fVxuICAgICAqL1xuICAgIHRoaXMucmVkb1N0YWNrID0gW11cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBjbGllbnQgaXMgY3VycmVudGx5IHVuZG9pbmcgKGNhbGxpbmcgVW5kb01hbmFnZXIudW5kbylcbiAgICAgKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMudW5kb2luZyA9IGZhbHNlXG4gICAgdGhpcy5yZWRvaW5nID0gZmFsc2VcbiAgICAvKipcbiAgICAgKiBUaGUgY3VycmVudGx5IHBvcHBlZCBzdGFjayBpdGVtIGlmIFVuZG9NYW5hZ2VyLnVuZG9pbmcgb3IgVW5kb01hbmFnZXIucmVkb2luZ1xuICAgICAqXG4gICAgICogQHR5cGUge1N0YWNrSXRlbXxudWxsfVxuICAgICAqL1xuICAgIHRoaXMuY3VyclN0YWNrSXRlbSA9IG51bGxcbiAgICB0aGlzLmxhc3RDaGFuZ2UgPSAwXG4gICAgdGhpcy5pZ25vcmVSZW1vdGVNYXBDaGFuZ2VzID0gaWdub3JlUmVtb3RlTWFwQ2hhbmdlc1xuICAgIHRoaXMuY2FwdHVyZVRpbWVvdXQgPSBjYXB0dXJlVGltZW91dFxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAgICovXG4gICAgdGhpcy5hZnRlclRyYW5zYWN0aW9uSGFuZGxlciA9IHRyYW5zYWN0aW9uID0+IHtcbiAgICAgIC8vIE9ubHkgdHJhY2sgY2VydGFpbiB0cmFuc2FjdGlvbnNcbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuY2FwdHVyZVRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uKSB8fFxuICAgICAgICAhdGhpcy5zY29wZS5zb21lKHR5cGUgPT4gdHJhbnNhY3Rpb24uY2hhbmdlZFBhcmVudFR5cGVzLmhhcygvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAodHlwZSkpIHx8IHR5cGUgPT09IHRoaXMuZG9jKSB8fFxuICAgICAgICAoIXRoaXMudHJhY2tlZE9yaWdpbnMuaGFzKHRyYW5zYWN0aW9uLm9yaWdpbikgJiYgKCF0cmFuc2FjdGlvbi5vcmlnaW4gfHwgIXRoaXMudHJhY2tlZE9yaWdpbnMuaGFzKHRyYW5zYWN0aW9uLm9yaWdpbi5jb25zdHJ1Y3RvcikpKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgY29uc3QgdW5kb2luZyA9IHRoaXMudW5kb2luZ1xuICAgICAgY29uc3QgcmVkb2luZyA9IHRoaXMucmVkb2luZ1xuICAgICAgY29uc3Qgc3RhY2sgPSB1bmRvaW5nID8gdGhpcy5yZWRvU3RhY2sgOiB0aGlzLnVuZG9TdGFja1xuICAgICAgaWYgKHVuZG9pbmcpIHtcbiAgICAgICAgdGhpcy5zdG9wQ2FwdHVyaW5nKCkgLy8gbmV4dCB1bmRvIHNob3VsZCBub3QgYmUgYXBwZW5kZWQgdG8gbGFzdCBzdGFjayBpdGVtXG4gICAgICB9IGVsc2UgaWYgKCFyZWRvaW5nKSB7XG4gICAgICAgIC8vIG5laXRoZXIgdW5kb2luZyBub3IgcmVkb2luZzogZGVsZXRlIHJlZG9TdGFja1xuICAgICAgICB0aGlzLmNsZWFyKGZhbHNlLCB0cnVlKVxuICAgICAgfVxuICAgICAgY29uc3QgaW5zZXJ0aW9ucyA9IG5ldyBEZWxldGVTZXQoKVxuICAgICAgdHJhbnNhY3Rpb24uYWZ0ZXJTdGF0ZS5mb3JFYWNoKChlbmRDbG9jaywgY2xpZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0Q2xvY2sgPSB0cmFuc2FjdGlvbi5iZWZvcmVTdGF0ZS5nZXQoY2xpZW50KSB8fCAwXG4gICAgICAgIGNvbnN0IGxlbiA9IGVuZENsb2NrIC0gc3RhcnRDbG9ja1xuICAgICAgICBpZiAobGVuID4gMCkge1xuICAgICAgICAgIGFkZFRvRGVsZXRlU2V0KGluc2VydGlvbnMsIGNsaWVudCwgc3RhcnRDbG9jaywgbGVuKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgY29uc3Qgbm93ID0gdGltZS5nZXRVbml4VGltZSgpXG4gICAgICBsZXQgZGlkQWRkID0gZmFsc2VcbiAgICAgIGlmICh0aGlzLmxhc3RDaGFuZ2UgPiAwICYmIG5vdyAtIHRoaXMubGFzdENoYW5nZSA8IHRoaXMuY2FwdHVyZVRpbWVvdXQgJiYgc3RhY2subGVuZ3RoID4gMCAmJiAhdW5kb2luZyAmJiAhcmVkb2luZykge1xuICAgICAgICAvLyBhcHBlbmQgY2hhbmdlIHRvIGxhc3Qgc3RhY2sgb3BcbiAgICAgICAgY29uc3QgbGFzdE9wID0gc3RhY2tbc3RhY2subGVuZ3RoIC0gMV1cbiAgICAgICAgbGFzdE9wLmRlbGV0aW9ucyA9IG1lcmdlRGVsZXRlU2V0cyhbbGFzdE9wLmRlbGV0aW9ucywgdHJhbnNhY3Rpb24uZGVsZXRlU2V0XSlcbiAgICAgICAgbGFzdE9wLmluc2VydGlvbnMgPSBtZXJnZURlbGV0ZVNldHMoW2xhc3RPcC5pbnNlcnRpb25zLCBpbnNlcnRpb25zXSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGNyZWF0ZSBhIG5ldyBzdGFjayBvcFxuICAgICAgICBzdGFjay5wdXNoKG5ldyBTdGFja0l0ZW0odHJhbnNhY3Rpb24uZGVsZXRlU2V0LCBpbnNlcnRpb25zKSlcbiAgICAgICAgZGlkQWRkID0gdHJ1ZVxuICAgICAgfVxuICAgICAgaWYgKCF1bmRvaW5nICYmICFyZWRvaW5nKSB7XG4gICAgICAgIHRoaXMubGFzdENoYW5nZSA9IG5vd1xuICAgICAgfVxuICAgICAgLy8gbWFrZSBzdXJlIHRoYXQgZGVsZXRlZCBzdHJ1Y3RzIGFyZSBub3QgZ2MnZFxuICAgICAgaXRlcmF0ZURlbGV0ZWRTdHJ1Y3RzKHRyYW5zYWN0aW9uLCB0cmFuc2FjdGlvbi5kZWxldGVTZXQsIC8qKiBAcGFyYW0ge0l0ZW18R0N9IGl0ZW0gKi8gaXRlbSA9PiB7XG4gICAgICAgIGlmIChpdGVtIGluc3RhbmNlb2YgSXRlbSAmJiB0aGlzLnNjb3BlLnNvbWUodHlwZSA9PiB0eXBlID09PSB0cmFuc2FjdGlvbi5kb2MgfHwgaXNQYXJlbnRPZigvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAodHlwZSksIGl0ZW0pKSkge1xuICAgICAgICAgIGtlZXBJdGVtKGl0ZW0sIHRydWUpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAvKipcbiAgICAgICAqIEB0eXBlIHtbU3RhY2tJdGVtRXZlbnQsIFVuZG9NYW5hZ2VyXX1cbiAgICAgICAqL1xuICAgICAgY29uc3QgY2hhbmdlRXZlbnQgPSBbeyBzdGFja0l0ZW06IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDFdLCBvcmlnaW46IHRyYW5zYWN0aW9uLm9yaWdpbiwgdHlwZTogdW5kb2luZyA/ICdyZWRvJyA6ICd1bmRvJywgY2hhbmdlZFBhcmVudFR5cGVzOiB0cmFuc2FjdGlvbi5jaGFuZ2VkUGFyZW50VHlwZXMgfSwgdGhpc11cbiAgICAgIGlmIChkaWRBZGQpIHtcbiAgICAgICAgdGhpcy5lbWl0KCdzdGFjay1pdGVtLWFkZGVkJywgY2hhbmdlRXZlbnQpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmVtaXQoJ3N0YWNrLWl0ZW0tdXBkYXRlZCcsIGNoYW5nZUV2ZW50KVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmRvYy5vbignYWZ0ZXJUcmFuc2FjdGlvbicsIHRoaXMuYWZ0ZXJUcmFuc2FjdGlvbkhhbmRsZXIpXG4gICAgdGhpcy5kb2Mub24oJ2Rlc3Ryb3knLCAoKSA9PiB7XG4gICAgICB0aGlzLmRlc3Ryb3koKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogRXh0ZW5kIHRoZSBzY29wZS5cbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxBYnN0cmFjdFR5cGU8YW55PiB8IERvYz4gfCBBYnN0cmFjdFR5cGU8YW55PiB8IERvY30geXR5cGVzXG4gICAqL1xuICBhZGRUb1Njb3BlICh5dHlwZXMpIHtcbiAgICBjb25zdCB0bXBTZXQgPSBuZXcgU2V0KHRoaXMuc2NvcGUpXG4gICAgeXR5cGVzID0gYXJyYXkuaXNBcnJheSh5dHlwZXMpID8geXR5cGVzIDogW3l0eXBlc11cbiAgICB5dHlwZXMuZm9yRWFjaCh5dHlwZSA9PiB7XG4gICAgICBpZiAoIXRtcFNldC5oYXMoeXR5cGUpKSB7XG4gICAgICAgIHRtcFNldC5hZGQoeXR5cGUpXG4gICAgICAgIGlmICh5dHlwZSBpbnN0YW5jZW9mIEFic3RyYWN0VHlwZSA/IHl0eXBlLmRvYyAhPT0gdGhpcy5kb2MgOiB5dHlwZSAhPT0gdGhpcy5kb2MpIGxvZ2dpbmcud2FybignW3lqcyM1MDldIE5vdCBzYW1lIFkuRG9jJykgLy8gdXNlIE11bHRpRG9jVW5kb01hbmFnZXIgaW5zdGVhZC4gYWxzbyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL3lqcy95anMvaXNzdWVzLzUwOVxuICAgICAgICB0aGlzLnNjb3BlLnB1c2goeXR5cGUpXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2FueX0gb3JpZ2luXG4gICAqL1xuICBhZGRUcmFja2VkT3JpZ2luIChvcmlnaW4pIHtcbiAgICB0aGlzLnRyYWNrZWRPcmlnaW5zLmFkZChvcmlnaW4pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHthbnl9IG9yaWdpblxuICAgKi9cbiAgcmVtb3ZlVHJhY2tlZE9yaWdpbiAob3JpZ2luKSB7XG4gICAgdGhpcy50cmFja2VkT3JpZ2lucy5kZWxldGUob3JpZ2luKVxuICB9XG5cbiAgY2xlYXIgKGNsZWFyVW5kb1N0YWNrID0gdHJ1ZSwgY2xlYXJSZWRvU3RhY2sgPSB0cnVlKSB7XG4gICAgaWYgKChjbGVhclVuZG9TdGFjayAmJiB0aGlzLmNhblVuZG8oKSkgfHwgKGNsZWFyUmVkb1N0YWNrICYmIHRoaXMuY2FuUmVkbygpKSkge1xuICAgICAgdGhpcy5kb2MudHJhbnNhY3QodHIgPT4ge1xuICAgICAgICBpZiAoY2xlYXJVbmRvU3RhY2spIHtcbiAgICAgICAgICB0aGlzLnVuZG9TdGFjay5mb3JFYWNoKGl0ZW0gPT4gY2xlYXJVbmRvTWFuYWdlclN0YWNrSXRlbSh0ciwgdGhpcywgaXRlbSkpXG4gICAgICAgICAgdGhpcy51bmRvU3RhY2sgPSBbXVxuICAgICAgICB9XG4gICAgICAgIGlmIChjbGVhclJlZG9TdGFjaykge1xuICAgICAgICAgIHRoaXMucmVkb1N0YWNrLmZvckVhY2goaXRlbSA9PiBjbGVhclVuZG9NYW5hZ2VyU3RhY2tJdGVtKHRyLCB0aGlzLCBpdGVtKSlcbiAgICAgICAgICB0aGlzLnJlZG9TdGFjayA9IFtdXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lbWl0KCdzdGFjay1jbGVhcmVkJywgW3sgdW5kb1N0YWNrQ2xlYXJlZDogY2xlYXJVbmRvU3RhY2ssIHJlZG9TdGFja0NsZWFyZWQ6IGNsZWFyUmVkb1N0YWNrIH1dKVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVW5kb01hbmFnZXIgbWVyZ2VzIFVuZG8tU3RhY2tJdGVtIGlmIHRoZXkgYXJlIGNyZWF0ZWQgd2l0aGluIHRpbWUtZ2FwXG4gICAqIHNtYWxsZXIgdGhhbiBgb3B0aW9ucy5jYXB0dXJlVGltZW91dGAuIENhbGwgYHVtLnN0b3BDYXB0dXJpbmcoKWAgc28gdGhhdCB0aGUgbmV4dFxuICAgKiBTdGFja0l0ZW0gd29uJ3QgYmUgbWVyZ2VkLlxuICAgKlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAgICAgLy8gd2l0aG91dCBzdG9wQ2FwdHVyaW5nXG4gICAqICAgICB5dGV4dC5pbnNlcnQoMCwgJ2EnKVxuICAgKiAgICAgeXRleHQuaW5zZXJ0KDEsICdiJylcbiAgICogICAgIHVtLnVuZG8oKVxuICAgKiAgICAgeXRleHQudG9TdHJpbmcoKSAvLyA9PiAnJyAobm90ZSB0aGF0ICdhYicgd2FzIHJlbW92ZWQpXG4gICAqICAgICAvLyB3aXRoIHN0b3BDYXB0dXJpbmdcbiAgICogICAgIHl0ZXh0Lmluc2VydCgwLCAnYScpXG4gICAqICAgICB1bS5zdG9wQ2FwdHVyaW5nKClcbiAgICogICAgIHl0ZXh0Lmluc2VydCgwLCAnYicpXG4gICAqICAgICB1bS51bmRvKClcbiAgICogICAgIHl0ZXh0LnRvU3RyaW5nKCkgLy8gPT4gJ2EnIChub3RlIHRoYXQgb25seSAnYicgd2FzIHJlbW92ZWQpXG4gICAqXG4gICAqL1xuICBzdG9wQ2FwdHVyaW5nICgpIHtcbiAgICB0aGlzLmxhc3RDaGFuZ2UgPSAwXG4gIH1cblxuICAvKipcbiAgICogVW5kbyBsYXN0IGNoYW5nZXMgb24gdHlwZS5cbiAgICpcbiAgICogQHJldHVybiB7U3RhY2tJdGVtP30gUmV0dXJucyBTdGFja0l0ZW0gaWYgYSBjaGFuZ2Ugd2FzIGFwcGxpZWRcbiAgICovXG4gIHVuZG8gKCkge1xuICAgIHRoaXMudW5kb2luZyA9IHRydWVcbiAgICBsZXQgcmVzXG4gICAgdHJ5IHtcbiAgICAgIHJlcyA9IHBvcFN0YWNrSXRlbSh0aGlzLCB0aGlzLnVuZG9TdGFjaywgJ3VuZG8nKVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnVuZG9pbmcgPSBmYWxzZVxuICAgIH1cbiAgICByZXR1cm4gcmVzXG4gIH1cblxuICAvKipcbiAgICogUmVkbyBsYXN0IHVuZG8gb3BlcmF0aW9uLlxuICAgKlxuICAgKiBAcmV0dXJuIHtTdGFja0l0ZW0/fSBSZXR1cm5zIFN0YWNrSXRlbSBpZiBhIGNoYW5nZSB3YXMgYXBwbGllZFxuICAgKi9cbiAgcmVkbyAoKSB7XG4gICAgdGhpcy5yZWRvaW5nID0gdHJ1ZVxuICAgIGxldCByZXNcbiAgICB0cnkge1xuICAgICAgcmVzID0gcG9wU3RhY2tJdGVtKHRoaXMsIHRoaXMucmVkb1N0YWNrLCAncmVkbycpXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMucmVkb2luZyA9IGZhbHNlXG4gICAgfVxuICAgIHJldHVybiByZXNcbiAgfVxuXG4gIC8qKlxuICAgKiBBcmUgdW5kbyBzdGVwcyBhdmFpbGFibGU/XG4gICAqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IGB0cnVlYCBpZiB1bmRvIGlzIHBvc3NpYmxlXG4gICAqL1xuICBjYW5VbmRvICgpIHtcbiAgICByZXR1cm4gdGhpcy51bmRvU3RhY2subGVuZ3RoID4gMFxuICB9XG5cbiAgLyoqXG4gICAqIEFyZSByZWRvIHN0ZXBzIGF2YWlsYWJsZT9cbiAgICpcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gYHRydWVgIGlmIHJlZG8gaXMgcG9zc2libGVcbiAgICovXG4gIGNhblJlZG8gKCkge1xuICAgIHJldHVybiB0aGlzLnJlZG9TdGFjay5sZW5ndGggPiAwXG4gIH1cblxuICBkZXN0cm95ICgpIHtcbiAgICB0aGlzLnRyYWNrZWRPcmlnaW5zLmRlbGV0ZSh0aGlzKVxuICAgIHRoaXMuZG9jLm9mZignYWZ0ZXJUcmFuc2FjdGlvbicsIHRoaXMuYWZ0ZXJUcmFuc2FjdGlvbkhhbmRsZXIpXG4gICAgc3VwZXIuZGVzdHJveSgpXG4gIH1cbn1cbiIsICJpbXBvcnQgKiBhcyBiaW5hcnkgZnJvbSAnbGliMC9iaW5hcnknXG5pbXBvcnQgKiBhcyBkZWNvZGluZyBmcm9tICdsaWIwL2RlY29kaW5nJ1xuaW1wb3J0ICogYXMgZW5jb2RpbmcgZnJvbSAnbGliMC9lbmNvZGluZydcbmltcG9ydCAqIGFzIGVycm9yIGZyb20gJ2xpYjAvZXJyb3InXG5pbXBvcnQgKiBhcyBmIGZyb20gJ2xpYjAvZnVuY3Rpb24nXG5pbXBvcnQgKiBhcyBsb2dnaW5nIGZyb20gJ2xpYjAvbG9nZ2luZydcbmltcG9ydCAqIGFzIG1hcCBmcm9tICdsaWIwL21hcCdcbmltcG9ydCAqIGFzIG1hdGggZnJvbSAnbGliMC9tYXRoJ1xuaW1wb3J0ICogYXMgc3RyaW5nIGZyb20gJ2xpYjAvc3RyaW5nJ1xuXG5pbXBvcnQge1xuICBDb250ZW50QW55LFxuICBDb250ZW50QmluYXJ5LFxuICBDb250ZW50RGVsZXRlZCxcbiAgQ29udGVudERvYyxcbiAgQ29udGVudEVtYmVkLFxuICBDb250ZW50Rm9ybWF0LFxuICBDb250ZW50SlNPTixcbiAgQ29udGVudFN0cmluZyxcbiAgQ29udGVudFR5cGUsXG4gIGNyZWF0ZUlELFxuICBkZWNvZGVTdGF0ZVZlY3RvcixcbiAgRFNFbmNvZGVyVjEsXG4gIERTRW5jb2RlclYyLFxuICBHQyxcbiAgSXRlbSxcbiAgbWVyZ2VEZWxldGVTZXRzLFxuICByZWFkRGVsZXRlU2V0LFxuICByZWFkSXRlbUNvbnRlbnQsXG4gIFNraXAsXG4gIFVwZGF0ZURlY29kZXJWMSxcbiAgVXBkYXRlRGVjb2RlclYyLFxuICBVcGRhdGVFbmNvZGVyVjEsXG4gIFVwZGF0ZUVuY29kZXJWMixcbiAgd3JpdGVEZWxldGVTZXQsXG4gIFlYbWxFbGVtZW50LFxuICBZWG1sSG9va1xufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbi8qKlxuICogQHBhcmFtIHtVcGRhdGVEZWNvZGVyVjEgfCBVcGRhdGVEZWNvZGVyVjJ9IGRlY29kZXJcbiAqL1xuZnVuY3Rpb24gKiBsYXp5U3RydWN0UmVhZGVyR2VuZXJhdG9yIChkZWNvZGVyKSB7XG4gIGNvbnN0IG51bU9mU3RhdGVVcGRhdGVzID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2Rlci5yZXN0RGVjb2RlcilcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1PZlN0YXRlVXBkYXRlczsgaSsrKSB7XG4gICAgY29uc3QgbnVtYmVyT2ZTdHJ1Y3RzID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2Rlci5yZXN0RGVjb2RlcilcbiAgICBjb25zdCBjbGllbnQgPSBkZWNvZGVyLnJlYWRDbGllbnQoKVxuICAgIGxldCBjbG9jayA9IGRlY29kaW5nLnJlYWRWYXJVaW50KGRlY29kZXIucmVzdERlY29kZXIpXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZlN0cnVjdHM7IGkrKykge1xuICAgICAgY29uc3QgaW5mbyA9IGRlY29kZXIucmVhZEluZm8oKVxuICAgICAgLy8gQHRvZG8gdXNlIHN3aXRjaCBpbnN0ZWFkIG9mIGlmc1xuICAgICAgaWYgKGluZm8gPT09IDEwKSB7XG4gICAgICAgIGNvbnN0IGxlbiA9IGRlY29kaW5nLnJlYWRWYXJVaW50KGRlY29kZXIucmVzdERlY29kZXIpXG4gICAgICAgIHlpZWxkIG5ldyBTa2lwKGNyZWF0ZUlEKGNsaWVudCwgY2xvY2spLCBsZW4pXG4gICAgICAgIGNsb2NrICs9IGxlblxuICAgICAgfSBlbHNlIGlmICgoYmluYXJ5LkJJVFM1ICYgaW5mbykgIT09IDApIHtcbiAgICAgICAgY29uc3QgY2FudENvcHlQYXJlbnRJbmZvID0gKGluZm8gJiAoYmluYXJ5LkJJVDcgfCBiaW5hcnkuQklUOCkpID09PSAwXG4gICAgICAgIC8vIElmIHBhcmVudCA9IG51bGwgYW5kIG5laXRoZXIgbGVmdCBub3IgcmlnaHQgYXJlIGRlZmluZWQsIHRoZW4gd2Uga25vdyB0aGF0IGBwYXJlbnRgIGlzIGNoaWxkIG9mIGB5YFxuICAgICAgICAvLyBhbmQgd2UgcmVhZCB0aGUgbmV4dCBzdHJpbmcgYXMgcGFyZW50WUtleS5cbiAgICAgICAgLy8gSXQgaW5kaWNhdGVzIGhvdyB3ZSBzdG9yZS9yZXRyaWV2ZSBwYXJlbnQgZnJvbSBgeS5zaGFyZWBcbiAgICAgICAgLy8gQHR5cGUge3N0cmluZ3xudWxsfVxuICAgICAgICBjb25zdCBzdHJ1Y3QgPSBuZXcgSXRlbShcbiAgICAgICAgICBjcmVhdGVJRChjbGllbnQsIGNsb2NrKSxcbiAgICAgICAgICBudWxsLCAvLyBsZWZ0XG4gICAgICAgICAgKGluZm8gJiBiaW5hcnkuQklUOCkgPT09IGJpbmFyeS5CSVQ4ID8gZGVjb2Rlci5yZWFkTGVmdElEKCkgOiBudWxsLCAvLyBvcmlnaW5cbiAgICAgICAgICBudWxsLCAvLyByaWdodFxuICAgICAgICAgIChpbmZvICYgYmluYXJ5LkJJVDcpID09PSBiaW5hcnkuQklUNyA/IGRlY29kZXIucmVhZFJpZ2h0SUQoKSA6IG51bGwsIC8vIHJpZ2h0IG9yaWdpblxuICAgICAgICAgIC8vIEB0cy1pZ25vcmUgRm9yY2Ugd3JpdGluZyBhIHN0cmluZyBoZXJlLlxuICAgICAgICAgIGNhbnRDb3B5UGFyZW50SW5mbyA/IChkZWNvZGVyLnJlYWRQYXJlbnRJbmZvKCkgPyBkZWNvZGVyLnJlYWRTdHJpbmcoKSA6IGRlY29kZXIucmVhZExlZnRJRCgpKSA6IG51bGwsIC8vIHBhcmVudFxuICAgICAgICAgIGNhbnRDb3B5UGFyZW50SW5mbyAmJiAoaW5mbyAmIGJpbmFyeS5CSVQ2KSA9PT0gYmluYXJ5LkJJVDYgPyBkZWNvZGVyLnJlYWRTdHJpbmcoKSA6IG51bGwsIC8vIHBhcmVudFN1YlxuICAgICAgICAgIHJlYWRJdGVtQ29udGVudChkZWNvZGVyLCBpbmZvKSAvLyBpdGVtIGNvbnRlbnRcbiAgICAgICAgKVxuICAgICAgICB5aWVsZCBzdHJ1Y3RcbiAgICAgICAgY2xvY2sgKz0gc3RydWN0Lmxlbmd0aFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbGVuID0gZGVjb2Rlci5yZWFkTGVuKClcbiAgICAgICAgeWllbGQgbmV3IEdDKGNyZWF0ZUlEKGNsaWVudCwgY2xvY2spLCBsZW4pXG4gICAgICAgIGNsb2NrICs9IGxlblxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTGF6eVN0cnVjdFJlYWRlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1VwZGF0ZURlY29kZXJWMSB8IFVwZGF0ZURlY29kZXJWMn0gZGVjb2RlclxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGZpbHRlclNraXBzXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoZGVjb2RlciwgZmlsdGVyU2tpcHMpIHtcbiAgICB0aGlzLmdlbiA9IGxhenlTdHJ1Y3RSZWFkZXJHZW5lcmF0b3IoZGVjb2RlcilcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVsbCB8IEl0ZW0gfCBTa2lwIHwgR0N9XG4gICAgICovXG4gICAgdGhpcy5jdXJyID0gbnVsbFxuICAgIHRoaXMuZG9uZSA9IGZhbHNlXG4gICAgdGhpcy5maWx0ZXJTa2lwcyA9IGZpbHRlclNraXBzXG4gICAgdGhpcy5uZXh0KClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtJdGVtIHwgR0MgfCBTa2lwIHxudWxsfVxuICAgKi9cbiAgbmV4dCAoKSB7XG4gICAgLy8gaWdub3JlIFwiU2tpcFwiIHN0cnVjdHNcbiAgICBkbyB7XG4gICAgICB0aGlzLmN1cnIgPSB0aGlzLmdlbi5uZXh0KCkudmFsdWUgfHwgbnVsbFxuICAgIH0gd2hpbGUgKHRoaXMuZmlsdGVyU2tpcHMgJiYgdGhpcy5jdXJyICE9PSBudWxsICYmIHRoaXMuY3Vyci5jb25zdHJ1Y3RvciA9PT0gU2tpcClcbiAgICByZXR1cm4gdGhpcy5jdXJyXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICpcbiAqL1xuZXhwb3J0IGNvbnN0IGxvZ1VwZGF0ZSA9IHVwZGF0ZSA9PiBsb2dVcGRhdGVWMih1cGRhdGUsIFVwZGF0ZURlY29kZXJWMSlcblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICogQHBhcmFtIHt0eXBlb2YgVXBkYXRlRGVjb2RlclYyIHwgdHlwZW9mIFVwZGF0ZURlY29kZXJWMX0gW1lEZWNvZGVyXVxuICpcbiAqL1xuZXhwb3J0IGNvbnN0IGxvZ1VwZGF0ZVYyID0gKHVwZGF0ZSwgWURlY29kZXIgPSBVcGRhdGVEZWNvZGVyVjIpID0+IHtcbiAgY29uc3Qgc3RydWN0cyA9IFtdXG4gIGNvbnN0IHVwZGF0ZURlY29kZXIgPSBuZXcgWURlY29kZXIoZGVjb2RpbmcuY3JlYXRlRGVjb2Rlcih1cGRhdGUpKVxuICBjb25zdCBsYXp5RGVjb2RlciA9IG5ldyBMYXp5U3RydWN0UmVhZGVyKHVwZGF0ZURlY29kZXIsIGZhbHNlKVxuICBmb3IgKGxldCBjdXJyID0gbGF6eURlY29kZXIuY3VycjsgY3VyciAhPT0gbnVsbDsgY3VyciA9IGxhenlEZWNvZGVyLm5leHQoKSkge1xuICAgIHN0cnVjdHMucHVzaChjdXJyKVxuICB9XG4gIGxvZ2dpbmcucHJpbnQoJ1N0cnVjdHM6ICcsIHN0cnVjdHMpXG4gIGNvbnN0IGRzID0gcmVhZERlbGV0ZVNldCh1cGRhdGVEZWNvZGVyKVxuICBsb2dnaW5nLnByaW50KCdEZWxldGVTZXQ6ICcsIGRzKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gdXBkYXRlXG4gKlxuICovXG5leHBvcnQgY29uc3QgZGVjb2RlVXBkYXRlID0gKHVwZGF0ZSkgPT4gZGVjb2RlVXBkYXRlVjIodXBkYXRlLCBVcGRhdGVEZWNvZGVyVjEpXG5cbi8qKlxuICogQHBhcmFtIHtVaW50OEFycmF5fSB1cGRhdGVcbiAqIEBwYXJhbSB7dHlwZW9mIFVwZGF0ZURlY29kZXJWMiB8IHR5cGVvZiBVcGRhdGVEZWNvZGVyVjF9IFtZRGVjb2Rlcl1cbiAqXG4gKi9cbmV4cG9ydCBjb25zdCBkZWNvZGVVcGRhdGVWMiA9ICh1cGRhdGUsIFlEZWNvZGVyID0gVXBkYXRlRGVjb2RlclYyKSA9PiB7XG4gIGNvbnN0IHN0cnVjdHMgPSBbXVxuICBjb25zdCB1cGRhdGVEZWNvZGVyID0gbmV3IFlEZWNvZGVyKGRlY29kaW5nLmNyZWF0ZURlY29kZXIodXBkYXRlKSlcbiAgY29uc3QgbGF6eURlY29kZXIgPSBuZXcgTGF6eVN0cnVjdFJlYWRlcih1cGRhdGVEZWNvZGVyLCBmYWxzZSlcbiAgZm9yIChsZXQgY3VyciA9IGxhenlEZWNvZGVyLmN1cnI7IGN1cnIgIT09IG51bGw7IGN1cnIgPSBsYXp5RGVjb2Rlci5uZXh0KCkpIHtcbiAgICBzdHJ1Y3RzLnB1c2goY3VycilcbiAgfVxuICByZXR1cm4ge1xuICAgIHN0cnVjdHMsXG4gICAgZHM6IHJlYWREZWxldGVTZXQodXBkYXRlRGVjb2RlcilcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTGF6eVN0cnVjdFdyaXRlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1VwZGF0ZUVuY29kZXJWMSB8IFVwZGF0ZUVuY29kZXJWMn0gZW5jb2RlclxuICAgKi9cbiAgY29uc3RydWN0b3IgKGVuY29kZXIpIHtcbiAgICB0aGlzLmN1cnJDbGllbnQgPSAwXG4gICAgdGhpcy5zdGFydENsb2NrID0gMFxuICAgIHRoaXMud3JpdHRlbiA9IDBcbiAgICB0aGlzLmVuY29kZXIgPSBlbmNvZGVyXG4gICAgLyoqXG4gICAgICogV2Ugd2FudCB0byB3cml0ZSBvcGVyYXRpb25zIGxhemlseSwgYnV0IGFsc28gd2UgbmVlZCB0byBrbm93IGJlZm9yZWhhbmQgaG93IG1hbnkgb3BlcmF0aW9ucyB3ZSB3YW50IHRvIHdyaXRlIGZvciBlYWNoIGNsaWVudC5cbiAgICAgKlxuICAgICAqIFRoaXMga2luZCBvZiBtZXRhLWluZm9ybWF0aW9uICgjY2xpZW50cywgI3N0cnVjdHMtcGVyLWNsaWVudC13cml0dGVuKSBpcyB3cml0dGVuIHRvIHRoZSByZXN0RW5jb2Rlci5cbiAgICAgKlxuICAgICAqIFdlIGZyYWdtZW50IHRoZSByZXN0RW5jb2RlciBhbmQgc3RvcmUgYSBzbGljZSBvZiBpdCBwZXItY2xpZW50IHVudGlsIHdlIGtub3cgaG93IG1hbnkgY2xpZW50cyB0aGVyZSBhcmUuXG4gICAgICogV2hlbiB3ZSBmbHVzaCAodG9VaW50OEFycmF5KSB3ZSB3cml0ZSB0aGUgcmVzdEVuY29kZXIgdXNpbmcgdGhlIGZyYWdtZW50cyBhbmQgdGhlIG1ldGEtaW5mb3JtYXRpb24uXG4gICAgICpcbiAgICAgKiBAdHlwZSB7QXJyYXk8eyB3cml0dGVuOiBudW1iZXIsIHJlc3RFbmNvZGVyOiBVaW50OEFycmF5IH0+fVxuICAgICAqL1xuICAgIHRoaXMuY2xpZW50U3RydWN0cyA9IFtdXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PFVpbnQ4QXJyYXk+fSB1cGRhdGVzXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICovXG5leHBvcnQgY29uc3QgbWVyZ2VVcGRhdGVzID0gdXBkYXRlcyA9PiBtZXJnZVVwZGF0ZXNWMih1cGRhdGVzLCBVcGRhdGVEZWNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMSlcblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICogQHBhcmFtIHt0eXBlb2YgRFNFbmNvZGVyVjEgfCB0eXBlb2YgRFNFbmNvZGVyVjJ9IFlFbmNvZGVyXG4gKiBAcGFyYW0ge3R5cGVvZiBVcGRhdGVEZWNvZGVyVjEgfCB0eXBlb2YgVXBkYXRlRGVjb2RlclYyfSBZRGVjb2RlclxuICogQHJldHVybiB7VWludDhBcnJheX1cbiAqL1xuZXhwb3J0IGNvbnN0IGVuY29kZVN0YXRlVmVjdG9yRnJvbVVwZGF0ZVYyID0gKHVwZGF0ZSwgWUVuY29kZXIgPSBEU0VuY29kZXJWMiwgWURlY29kZXIgPSBVcGRhdGVEZWNvZGVyVjIpID0+IHtcbiAgY29uc3QgZW5jb2RlciA9IG5ldyBZRW5jb2RlcigpXG4gIGNvbnN0IHVwZGF0ZURlY29kZXIgPSBuZXcgTGF6eVN0cnVjdFJlYWRlcihuZXcgWURlY29kZXIoZGVjb2RpbmcuY3JlYXRlRGVjb2Rlcih1cGRhdGUpKSwgZmFsc2UpXG4gIGxldCBjdXJyID0gdXBkYXRlRGVjb2Rlci5jdXJyXG4gIGlmIChjdXJyICE9PSBudWxsKSB7XG4gICAgbGV0IHNpemUgPSAwXG4gICAgbGV0IGN1cnJDbGllbnQgPSBjdXJyLmlkLmNsaWVudFxuICAgIGxldCBzdG9wQ291bnRpbmcgPSBjdXJyLmlkLmNsb2NrICE9PSAwIC8vIG11c3Qgc3RhcnQgYXQgMFxuICAgIGxldCBjdXJyQ2xvY2sgPSBzdG9wQ291bnRpbmcgPyAwIDogY3Vyci5pZC5jbG9jayArIGN1cnIubGVuZ3RoXG4gICAgZm9yICg7IGN1cnIgIT09IG51bGw7IGN1cnIgPSB1cGRhdGVEZWNvZGVyLm5leHQoKSkge1xuICAgICAgaWYgKGN1cnJDbGllbnQgIT09IGN1cnIuaWQuY2xpZW50KSB7XG4gICAgICAgIGlmIChjdXJyQ2xvY2sgIT09IDApIHtcbiAgICAgICAgICBzaXplKytcbiAgICAgICAgICAvLyBXZSBmb3VuZCBhIG5ldyBjbGllbnRcbiAgICAgICAgICAvLyB3cml0ZSB3aGF0IHdlIGhhdmUgdG8gdGhlIGVuY29kZXJcbiAgICAgICAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2Rlci5yZXN0RW5jb2RlciwgY3VyckNsaWVudClcbiAgICAgICAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2Rlci5yZXN0RW5jb2RlciwgY3VyckNsb2NrKVxuICAgICAgICB9XG4gICAgICAgIGN1cnJDbGllbnQgPSBjdXJyLmlkLmNsaWVudFxuICAgICAgICBjdXJyQ2xvY2sgPSAwXG4gICAgICAgIHN0b3BDb3VudGluZyA9IGN1cnIuaWQuY2xvY2sgIT09IDBcbiAgICAgIH1cbiAgICAgIC8vIHdlIGlnbm9yZSBza2lwc1xuICAgICAgaWYgKGN1cnIuY29uc3RydWN0b3IgPT09IFNraXApIHtcbiAgICAgICAgc3RvcENvdW50aW5nID0gdHJ1ZVxuICAgICAgfVxuICAgICAgaWYgKCFzdG9wQ291bnRpbmcpIHtcbiAgICAgICAgY3VyckNsb2NrID0gY3Vyci5pZC5jbG9jayArIGN1cnIubGVuZ3RoXG4gICAgICB9XG4gICAgfVxuICAgIC8vIHdyaXRlIHdoYXQgd2UgaGF2ZVxuICAgIGlmIChjdXJyQ2xvY2sgIT09IDApIHtcbiAgICAgIHNpemUrK1xuICAgICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIucmVzdEVuY29kZXIsIGN1cnJDbGllbnQpXG4gICAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2Rlci5yZXN0RW5jb2RlciwgY3VyckNsb2NrKVxuICAgIH1cbiAgICAvLyBwcmVwZW5kIHRoZSBzaXplIG9mIHRoZSBzdGF0ZSB2ZWN0b3JcbiAgICBjb25zdCBlbmMgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKClcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jLCBzaXplKVxuICAgIGVuY29kaW5nLndyaXRlQmluYXJ5RW5jb2RlcihlbmMsIGVuY29kZXIucmVzdEVuY29kZXIpXG4gICAgZW5jb2Rlci5yZXN0RW5jb2RlciA9IGVuY1xuICAgIHJldHVybiBlbmNvZGVyLnRvVWludDhBcnJheSgpXG4gIH0gZWxzZSB7XG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIucmVzdEVuY29kZXIsIDApXG4gICAgcmV0dXJuIGVuY29kZXIudG9VaW50OEFycmF5KClcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gdXBkYXRlXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICovXG5leHBvcnQgY29uc3QgZW5jb2RlU3RhdGVWZWN0b3JGcm9tVXBkYXRlID0gdXBkYXRlID0+IGVuY29kZVN0YXRlVmVjdG9yRnJvbVVwZGF0ZVYyKHVwZGF0ZSwgRFNFbmNvZGVyVjEsIFVwZGF0ZURlY29kZXJWMSlcblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICogQHBhcmFtIHt0eXBlb2YgVXBkYXRlRGVjb2RlclYxIHwgdHlwZW9mIFVwZGF0ZURlY29kZXJWMn0gWURlY29kZXJcbiAqIEByZXR1cm4ge3sgZnJvbTogTWFwPG51bWJlcixudW1iZXI+LCB0bzogTWFwPG51bWJlcixudW1iZXI+IH19XG4gKi9cbmV4cG9ydCBjb25zdCBwYXJzZVVwZGF0ZU1ldGFWMiA9ICh1cGRhdGUsIFlEZWNvZGVyID0gVXBkYXRlRGVjb2RlclYyKSA9PiB7XG4gIC8qKlxuICAgKiBAdHlwZSB7TWFwPG51bWJlciwgbnVtYmVyPn1cbiAgICovXG4gIGNvbnN0IGZyb20gPSBuZXcgTWFwKClcbiAgLyoqXG4gICAqIEB0eXBlIHtNYXA8bnVtYmVyLCBudW1iZXI+fVxuICAgKi9cbiAgY29uc3QgdG8gPSBuZXcgTWFwKClcbiAgY29uc3QgdXBkYXRlRGVjb2RlciA9IG5ldyBMYXp5U3RydWN0UmVhZGVyKG5ldyBZRGVjb2RlcihkZWNvZGluZy5jcmVhdGVEZWNvZGVyKHVwZGF0ZSkpLCBmYWxzZSlcbiAgbGV0IGN1cnIgPSB1cGRhdGVEZWNvZGVyLmN1cnJcbiAgaWYgKGN1cnIgIT09IG51bGwpIHtcbiAgICBsZXQgY3VyckNsaWVudCA9IGN1cnIuaWQuY2xpZW50XG4gICAgbGV0IGN1cnJDbG9jayA9IGN1cnIuaWQuY2xvY2tcbiAgICAvLyB3cml0ZSB0aGUgYmVnaW5uaW5nIHRvIGBmcm9tYFxuICAgIGZyb20uc2V0KGN1cnJDbGllbnQsIGN1cnJDbG9jaylcbiAgICBmb3IgKDsgY3VyciAhPT0gbnVsbDsgY3VyciA9IHVwZGF0ZURlY29kZXIubmV4dCgpKSB7XG4gICAgICBpZiAoY3VyckNsaWVudCAhPT0gY3Vyci5pZC5jbGllbnQpIHtcbiAgICAgICAgLy8gV2UgZm91bmQgYSBuZXcgY2xpZW50XG4gICAgICAgIC8vIHdyaXRlIHRoZSBlbmQgdG8gYHRvYFxuICAgICAgICB0by5zZXQoY3VyckNsaWVudCwgY3VyckNsb2NrKVxuICAgICAgICAvLyB3cml0ZSB0aGUgYmVnaW5uaW5nIHRvIGBmcm9tYFxuICAgICAgICBmcm9tLnNldChjdXJyLmlkLmNsaWVudCwgY3Vyci5pZC5jbG9jaylcbiAgICAgICAgLy8gdXBkYXRlIGN1cnJDbGllbnRcbiAgICAgICAgY3VyckNsaWVudCA9IGN1cnIuaWQuY2xpZW50XG4gICAgICB9XG4gICAgICBjdXJyQ2xvY2sgPSBjdXJyLmlkLmNsb2NrICsgY3Vyci5sZW5ndGhcbiAgICB9XG4gICAgLy8gd3JpdGUgdGhlIGVuZCB0byBgdG9gXG4gICAgdG8uc2V0KGN1cnJDbGllbnQsIGN1cnJDbG9jaylcbiAgfVxuICByZXR1cm4geyBmcm9tLCB0byB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtVaW50OEFycmF5fSB1cGRhdGVcbiAqIEByZXR1cm4ge3sgZnJvbTogTWFwPG51bWJlcixudW1iZXI+LCB0bzogTWFwPG51bWJlcixudW1iZXI+IH19XG4gKi9cbmV4cG9ydCBjb25zdCBwYXJzZVVwZGF0ZU1ldGEgPSB1cGRhdGUgPT4gcGFyc2VVcGRhdGVNZXRhVjIodXBkYXRlLCBVcGRhdGVEZWNvZGVyVjEpXG5cbi8qKlxuICogVGhpcyBtZXRob2QgaXMgaW50ZW5kZWQgdG8gc2xpY2UgYW55IGtpbmQgb2Ygc3RydWN0IGFuZCByZXRyaWV2ZSB0aGUgcmlnaHQgcGFydC5cbiAqIEl0IGRvZXMgbm90IGhhbmRsZSBzaWRlLWVmZmVjdHMsIHNvIGl0IHNob3VsZCBvbmx5IGJlIHVzZWQgYnkgdGhlIGxhenktZW5jb2Rlci5cbiAqXG4gKiBAcGFyYW0ge0l0ZW0gfCBHQyB8IFNraXB9IGxlZnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBkaWZmXG4gKiBAcmV0dXJuIHtJdGVtIHwgR0N9XG4gKi9cbmNvbnN0IHNsaWNlU3RydWN0ID0gKGxlZnQsIGRpZmYpID0+IHtcbiAgaWYgKGxlZnQuY29uc3RydWN0b3IgPT09IEdDKSB7XG4gICAgY29uc3QgeyBjbGllbnQsIGNsb2NrIH0gPSBsZWZ0LmlkXG4gICAgcmV0dXJuIG5ldyBHQyhjcmVhdGVJRChjbGllbnQsIGNsb2NrICsgZGlmZiksIGxlZnQubGVuZ3RoIC0gZGlmZilcbiAgfSBlbHNlIGlmIChsZWZ0LmNvbnN0cnVjdG9yID09PSBTa2lwKSB7XG4gICAgY29uc3QgeyBjbGllbnQsIGNsb2NrIH0gPSBsZWZ0LmlkXG4gICAgcmV0dXJuIG5ldyBTa2lwKGNyZWF0ZUlEKGNsaWVudCwgY2xvY2sgKyBkaWZmKSwgbGVmdC5sZW5ndGggLSBkaWZmKVxuICB9IGVsc2Uge1xuICAgIGNvbnN0IGxlZnRJdGVtID0gLyoqIEB0eXBlIHtJdGVtfSAqLyAobGVmdClcbiAgICBjb25zdCB7IGNsaWVudCwgY2xvY2sgfSA9IGxlZnRJdGVtLmlkXG4gICAgcmV0dXJuIG5ldyBJdGVtKFxuICAgICAgY3JlYXRlSUQoY2xpZW50LCBjbG9jayArIGRpZmYpLFxuICAgICAgbnVsbCxcbiAgICAgIGNyZWF0ZUlEKGNsaWVudCwgY2xvY2sgKyBkaWZmIC0gMSksXG4gICAgICBudWxsLFxuICAgICAgbGVmdEl0ZW0ucmlnaHRPcmlnaW4sXG4gICAgICBsZWZ0SXRlbS5wYXJlbnQsXG4gICAgICBsZWZ0SXRlbS5wYXJlbnRTdWIsXG4gICAgICBsZWZ0SXRlbS5jb250ZW50LnNwbGljZShkaWZmKVxuICAgIClcbiAgfVxufVxuXG4vKipcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdvcmtzIHNpbWlsYXJseSB0byBgcmVhZFVwZGF0ZVYyYC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PFVpbnQ4QXJyYXk+fSB1cGRhdGVzXG4gKiBAcGFyYW0ge3R5cGVvZiBVcGRhdGVEZWNvZGVyVjEgfCB0eXBlb2YgVXBkYXRlRGVjb2RlclYyfSBbWURlY29kZXJdXG4gKiBAcGFyYW0ge3R5cGVvZiBVcGRhdGVFbmNvZGVyVjEgfCB0eXBlb2YgVXBkYXRlRW5jb2RlclYyfSBbWUVuY29kZXJdXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICovXG5leHBvcnQgY29uc3QgbWVyZ2VVcGRhdGVzVjIgPSAodXBkYXRlcywgWURlY29kZXIgPSBVcGRhdGVEZWNvZGVyVjIsIFlFbmNvZGVyID0gVXBkYXRlRW5jb2RlclYyKSA9PiB7XG4gIGlmICh1cGRhdGVzLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiB1cGRhdGVzWzBdXG4gIH1cbiAgY29uc3QgdXBkYXRlRGVjb2RlcnMgPSB1cGRhdGVzLm1hcCh1cGRhdGUgPT4gbmV3IFlEZWNvZGVyKGRlY29kaW5nLmNyZWF0ZURlY29kZXIodXBkYXRlKSkpXG4gIGxldCBsYXp5U3RydWN0RGVjb2RlcnMgPSB1cGRhdGVEZWNvZGVycy5tYXAoZGVjb2RlciA9PiBuZXcgTGF6eVN0cnVjdFJlYWRlcihkZWNvZGVyLCB0cnVlKSlcblxuICAvKipcbiAgICogQHRvZG8gd2UgZG9uJ3QgbmVlZCBvZmZzZXQgYmVjYXVzZSB3ZSBhbHdheXMgc2xpY2UgYmVmb3JlXG4gICAqIEB0eXBlIHtudWxsIHwgeyBzdHJ1Y3Q6IEl0ZW0gfCBHQyB8IFNraXAsIG9mZnNldDogbnVtYmVyIH19XG4gICAqL1xuICBsZXQgY3VycldyaXRlID0gbnVsbFxuXG4gIGNvbnN0IHVwZGF0ZUVuY29kZXIgPSBuZXcgWUVuY29kZXIoKVxuICAvLyB3cml0ZSBzdHJ1Y3RzIGxhemlseVxuICBjb25zdCBsYXp5U3RydWN0RW5jb2RlciA9IG5ldyBMYXp5U3RydWN0V3JpdGVyKHVwZGF0ZUVuY29kZXIpXG5cbiAgLy8gTm90ZTogV2UgbmVlZCB0byBlbnN1cmUgdGhhdCBhbGwgbGF6eVN0cnVjdERlY29kZXJzIGFyZSBmdWxseSBjb25zdW1lZFxuICAvLyBOb3RlOiBTaG91bGQgbWVyZ2UgZG9jdW1lbnQgdXBkYXRlcyB3aGVuZXZlciBwb3NzaWJsZSAtIGV2ZW4gZnJvbSBkaWZmZXJlbnQgdXBkYXRlc1xuICAvLyBOb3RlOiBTaG91bGQgaGFuZGxlIHRoYXQgc29tZSBvcGVyYXRpb25zIGNhbm5vdCBiZSBhcHBsaWVkIHlldCAoKVxuXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgLy8gV3JpdGUgaGlnaGVyIGNsaWVudHMgZmlyc3Qg4oeSIHNvcnQgYnkgY2xpZW50SUQgJiBjbG9jayBhbmQgcmVtb3ZlIGRlY29kZXJzIHdpdGhvdXQgY29udGVudFxuICAgIGxhenlTdHJ1Y3REZWNvZGVycyA9IGxhenlTdHJ1Y3REZWNvZGVycy5maWx0ZXIoZGVjID0+IGRlYy5jdXJyICE9PSBudWxsKVxuICAgIGxhenlTdHJ1Y3REZWNvZGVycy5zb3J0KFxuICAgICAgLyoqIEB0eXBlIHtmdW5jdGlvbihhbnksYW55KTpudW1iZXJ9ICovIChkZWMxLCBkZWMyKSA9PiB7XG4gICAgICAgIGlmIChkZWMxLmN1cnIuaWQuY2xpZW50ID09PSBkZWMyLmN1cnIuaWQuY2xpZW50KSB7XG4gICAgICAgICAgY29uc3QgY2xvY2tEaWZmID0gZGVjMS5jdXJyLmlkLmNsb2NrIC0gZGVjMi5jdXJyLmlkLmNsb2NrXG4gICAgICAgICAgaWYgKGNsb2NrRGlmZiA9PT0gMCkge1xuICAgICAgICAgICAgLy8gQHRvZG8gcmVtb3ZlIHJlZmVyZW5jZXMgdG8gc2tpcCBzaW5jZSB0aGUgc3RydWN0RGVjb2RlcnMgbXVzdCBmaWx0ZXIgU2tpcHMuXG4gICAgICAgICAgICByZXR1cm4gZGVjMS5jdXJyLmNvbnN0cnVjdG9yID09PSBkZWMyLmN1cnIuY29uc3RydWN0b3JcbiAgICAgICAgICAgICAgPyAwXG4gICAgICAgICAgICAgIDogZGVjMS5jdXJyLmNvbnN0cnVjdG9yID09PSBTa2lwID8gMSA6IC0xIC8vIHdlIGFyZSBmaWx0ZXJpbmcgc2tpcHMgYW55d2F5LlxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gY2xvY2tEaWZmXG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBkZWMyLmN1cnIuaWQuY2xpZW50IC0gZGVjMS5jdXJyLmlkLmNsaWVudFxuICAgICAgICB9XG4gICAgICB9XG4gICAgKVxuICAgIGlmIChsYXp5U3RydWN0RGVjb2RlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICBicmVha1xuICAgIH1cbiAgICBjb25zdCBjdXJyRGVjb2RlciA9IGxhenlTdHJ1Y3REZWNvZGVyc1swXVxuICAgIC8vIHdyaXRlIGZyb20gY3VyckRlY29kZXIgdW50aWwgdGhlIG5leHQgb3BlcmF0aW9uIGlzIGZyb20gYW5vdGhlciBjbGllbnQgb3IgaWYgZmlsbGVyLXN0cnVjdFxuICAgIC8vIHRoZW4gd2UgbmVlZCB0byByZW9yZGVyIHRoZSBkZWNvZGVycyBhbmQgZmluZCB0aGUgbmV4dCBvcGVyYXRpb24gdG8gd3JpdGVcbiAgICBjb25zdCBmaXJzdENsaWVudCA9IC8qKiBAdHlwZSB7SXRlbSB8IEdDfSAqLyAoY3VyckRlY29kZXIuY3VycikuaWQuY2xpZW50XG5cbiAgICBpZiAoY3VycldyaXRlICE9PSBudWxsKSB7XG4gICAgICBsZXQgY3VyciA9IC8qKiBAdHlwZSB7SXRlbSB8IEdDIHwgbnVsbH0gKi8gKGN1cnJEZWNvZGVyLmN1cnIpXG4gICAgICBsZXQgaXRlcmF0ZWQgPSBmYWxzZVxuXG4gICAgICAvLyBpdGVyYXRlIHVudGlsIHdlIGZpbmQgc29tZXRoaW5nIHRoYXQgd2UgaGF2ZW4ndCB3cml0dGVuIGFscmVhZHlcbiAgICAgIC8vIHJlbWVtYmVyOiBmaXJzdCB0aGUgaGlnaCBjbGllbnQtaWRzIGFyZSB3cml0dGVuXG4gICAgICB3aGlsZSAoY3VyciAhPT0gbnVsbCAmJiBjdXJyLmlkLmNsb2NrICsgY3Vyci5sZW5ndGggPD0gY3VycldyaXRlLnN0cnVjdC5pZC5jbG9jayArIGN1cnJXcml0ZS5zdHJ1Y3QubGVuZ3RoICYmIGN1cnIuaWQuY2xpZW50ID49IGN1cnJXcml0ZS5zdHJ1Y3QuaWQuY2xpZW50KSB7XG4gICAgICAgIGN1cnIgPSBjdXJyRGVjb2Rlci5uZXh0KClcbiAgICAgICAgaXRlcmF0ZWQgPSB0cnVlXG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIGN1cnIgPT09IG51bGwgfHwgLy8gY3VycmVudCBkZWNvZGVyIGlzIGVtcHR5XG4gICAgICAgIGN1cnIuaWQuY2xpZW50ICE9PSBmaXJzdENsaWVudCB8fCAvLyBjaGVjayB3aGV0aGVyIHRoZXJlIGlzIGFub3RoZXIgZGVjb2RlciB0aGF0IGhhcyBoYXMgdXBkYXRlcyBmcm9tIGBmaXJzdENsaWVudGBcbiAgICAgICAgKGl0ZXJhdGVkICYmIGN1cnIuaWQuY2xvY2sgPiBjdXJyV3JpdGUuc3RydWN0LmlkLmNsb2NrICsgY3VycldyaXRlLnN0cnVjdC5sZW5ndGgpIC8vIHRoZSBhYm92ZSB3aGlsZSBsb29wIHdhcyB1c2VkIGFuZCB3ZSBhcmUgcG90ZW50aWFsbHkgbWlzc2luZyB1cGRhdGVzXG4gICAgICApIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKGZpcnN0Q2xpZW50ICE9PSBjdXJyV3JpdGUuc3RydWN0LmlkLmNsaWVudCkge1xuICAgICAgICB3cml0ZVN0cnVjdFRvTGF6eVN0cnVjdFdyaXRlcihsYXp5U3RydWN0RW5jb2RlciwgY3VycldyaXRlLnN0cnVjdCwgY3VycldyaXRlLm9mZnNldClcbiAgICAgICAgY3VycldyaXRlID0geyBzdHJ1Y3Q6IGN1cnIsIG9mZnNldDogMCB9XG4gICAgICAgIGN1cnJEZWNvZGVyLm5leHQoKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGN1cnJXcml0ZS5zdHJ1Y3QuaWQuY2xvY2sgKyBjdXJyV3JpdGUuc3RydWN0Lmxlbmd0aCA8IGN1cnIuaWQuY2xvY2spIHtcbiAgICAgICAgICAvLyBAdG9kbyB3cml0ZSBjdXJyU3RydWN0ICYgc2V0IGN1cnJTdHJ1Y3QgPSBTa2lwKGNsb2NrID0gY3VyclN0cnVjdC5pZC5jbG9jayArIGN1cnJTdHJ1Y3QubGVuZ3RoLCBsZW5ndGggPSBjdXJyLmlkLmNsb2NrIC0gc2VsZi5jbG9jaylcbiAgICAgICAgICBpZiAoY3VycldyaXRlLnN0cnVjdC5jb25zdHJ1Y3RvciA9PT0gU2tpcCkge1xuICAgICAgICAgICAgLy8gZXh0ZW5kIGV4aXN0aW5nIHNraXBcbiAgICAgICAgICAgIGN1cnJXcml0ZS5zdHJ1Y3QubGVuZ3RoID0gY3Vyci5pZC5jbG9jayArIGN1cnIubGVuZ3RoIC0gY3VycldyaXRlLnN0cnVjdC5pZC5jbG9ja1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB3cml0ZVN0cnVjdFRvTGF6eVN0cnVjdFdyaXRlcihsYXp5U3RydWN0RW5jb2RlciwgY3VycldyaXRlLnN0cnVjdCwgY3VycldyaXRlLm9mZnNldClcbiAgICAgICAgICAgIGNvbnN0IGRpZmYgPSBjdXJyLmlkLmNsb2NrIC0gY3VycldyaXRlLnN0cnVjdC5pZC5jbG9jayAtIGN1cnJXcml0ZS5zdHJ1Y3QubGVuZ3RoXG4gICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAqIEB0eXBlIHtTa2lwfVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBzdHJ1Y3QgPSBuZXcgU2tpcChjcmVhdGVJRChmaXJzdENsaWVudCwgY3VycldyaXRlLnN0cnVjdC5pZC5jbG9jayArIGN1cnJXcml0ZS5zdHJ1Y3QubGVuZ3RoKSwgZGlmZilcbiAgICAgICAgICAgIGN1cnJXcml0ZSA9IHsgc3RydWN0LCBvZmZzZXQ6IDAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHsgLy8gaWYgKGN1cnJXcml0ZS5zdHJ1Y3QuaWQuY2xvY2sgKyBjdXJyV3JpdGUuc3RydWN0Lmxlbmd0aCA+PSBjdXJyLmlkLmNsb2NrKSB7XG4gICAgICAgICAgY29uc3QgZGlmZiA9IGN1cnJXcml0ZS5zdHJ1Y3QuaWQuY2xvY2sgKyBjdXJyV3JpdGUuc3RydWN0Lmxlbmd0aCAtIGN1cnIuaWQuY2xvY2tcbiAgICAgICAgICBpZiAoZGlmZiA+IDApIHtcbiAgICAgICAgICAgIGlmIChjdXJyV3JpdGUuc3RydWN0LmNvbnN0cnVjdG9yID09PSBTa2lwKSB7XG4gICAgICAgICAgICAgIC8vIHByZWZlciB0byBzbGljZSBTa2lwIGJlY2F1c2UgdGhlIG90aGVyIHN0cnVjdCBtaWdodCBjb250YWluIG1vcmUgaW5mb3JtYXRpb25cbiAgICAgICAgICAgICAgY3VycldyaXRlLnN0cnVjdC5sZW5ndGggLT0gZGlmZlxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY3VyciA9IHNsaWNlU3RydWN0KGN1cnIsIGRpZmYpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghY3VycldyaXRlLnN0cnVjdC5tZXJnZVdpdGgoLyoqIEB0eXBlIHthbnl9ICovIChjdXJyKSkpIHtcbiAgICAgICAgICAgIHdyaXRlU3RydWN0VG9MYXp5U3RydWN0V3JpdGVyKGxhenlTdHJ1Y3RFbmNvZGVyLCBjdXJyV3JpdGUuc3RydWN0LCBjdXJyV3JpdGUub2Zmc2V0KVxuICAgICAgICAgICAgY3VycldyaXRlID0geyBzdHJ1Y3Q6IGN1cnIsIG9mZnNldDogMCB9XG4gICAgICAgICAgICBjdXJyRGVjb2Rlci5uZXh0KClcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY3VycldyaXRlID0geyBzdHJ1Y3Q6IC8qKiBAdHlwZSB7SXRlbSB8IEdDfSAqLyAoY3VyckRlY29kZXIuY3VyciksIG9mZnNldDogMCB9XG4gICAgICBjdXJyRGVjb2Rlci5uZXh0KClcbiAgICB9XG4gICAgZm9yIChcbiAgICAgIGxldCBuZXh0ID0gY3VyckRlY29kZXIuY3VycjtcbiAgICAgIG5leHQgIT09IG51bGwgJiYgbmV4dC5pZC5jbGllbnQgPT09IGZpcnN0Q2xpZW50ICYmIG5leHQuaWQuY2xvY2sgPT09IGN1cnJXcml0ZS5zdHJ1Y3QuaWQuY2xvY2sgKyBjdXJyV3JpdGUuc3RydWN0Lmxlbmd0aCAmJiBuZXh0LmNvbnN0cnVjdG9yICE9PSBTa2lwO1xuICAgICAgbmV4dCA9IGN1cnJEZWNvZGVyLm5leHQoKVxuICAgICkge1xuICAgICAgd3JpdGVTdHJ1Y3RUb0xhenlTdHJ1Y3RXcml0ZXIobGF6eVN0cnVjdEVuY29kZXIsIGN1cnJXcml0ZS5zdHJ1Y3QsIGN1cnJXcml0ZS5vZmZzZXQpXG4gICAgICBjdXJyV3JpdGUgPSB7IHN0cnVjdDogbmV4dCwgb2Zmc2V0OiAwIH1cbiAgICB9XG4gIH1cbiAgaWYgKGN1cnJXcml0ZSAhPT0gbnVsbCkge1xuICAgIHdyaXRlU3RydWN0VG9MYXp5U3RydWN0V3JpdGVyKGxhenlTdHJ1Y3RFbmNvZGVyLCBjdXJyV3JpdGUuc3RydWN0LCBjdXJyV3JpdGUub2Zmc2V0KVxuICAgIGN1cnJXcml0ZSA9IG51bGxcbiAgfVxuICBmaW5pc2hMYXp5U3RydWN0V3JpdGluZyhsYXp5U3RydWN0RW5jb2RlcilcblxuICBjb25zdCBkc3MgPSB1cGRhdGVEZWNvZGVycy5tYXAoZGVjb2RlciA9PiByZWFkRGVsZXRlU2V0KGRlY29kZXIpKVxuICBjb25zdCBkcyA9IG1lcmdlRGVsZXRlU2V0cyhkc3MpXG4gIHdyaXRlRGVsZXRlU2V0KHVwZGF0ZUVuY29kZXIsIGRzKVxuICByZXR1cm4gdXBkYXRlRW5jb2Rlci50b1VpbnQ4QXJyYXkoKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gdXBkYXRlXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHN2XG4gKiBAcGFyYW0ge3R5cGVvZiBVcGRhdGVEZWNvZGVyVjEgfCB0eXBlb2YgVXBkYXRlRGVjb2RlclYyfSBbWURlY29kZXJdXG4gKiBAcGFyYW0ge3R5cGVvZiBVcGRhdGVFbmNvZGVyVjEgfCB0eXBlb2YgVXBkYXRlRW5jb2RlclYyfSBbWUVuY29kZXJdXG4gKi9cbmV4cG9ydCBjb25zdCBkaWZmVXBkYXRlVjIgPSAodXBkYXRlLCBzdiwgWURlY29kZXIgPSBVcGRhdGVEZWNvZGVyVjIsIFlFbmNvZGVyID0gVXBkYXRlRW5jb2RlclYyKSA9PiB7XG4gIGNvbnN0IHN0YXRlID0gZGVjb2RlU3RhdGVWZWN0b3Ioc3YpXG4gIGNvbnN0IGVuY29kZXIgPSBuZXcgWUVuY29kZXIoKVxuICBjb25zdCBsYXp5U3RydWN0V3JpdGVyID0gbmV3IExhenlTdHJ1Y3RXcml0ZXIoZW5jb2RlcilcbiAgY29uc3QgZGVjb2RlciA9IG5ldyBZRGVjb2RlcihkZWNvZGluZy5jcmVhdGVEZWNvZGVyKHVwZGF0ZSkpXG4gIGNvbnN0IHJlYWRlciA9IG5ldyBMYXp5U3RydWN0UmVhZGVyKGRlY29kZXIsIGZhbHNlKVxuICB3aGlsZSAocmVhZGVyLmN1cnIpIHtcbiAgICBjb25zdCBjdXJyID0gcmVhZGVyLmN1cnJcbiAgICBjb25zdCBjdXJyQ2xpZW50ID0gY3Vyci5pZC5jbGllbnRcbiAgICBjb25zdCBzdkNsb2NrID0gc3RhdGUuZ2V0KGN1cnJDbGllbnQpIHx8IDBcbiAgICBpZiAocmVhZGVyLmN1cnIuY29uc3RydWN0b3IgPT09IFNraXApIHtcbiAgICAgIC8vIHRoZSBmaXJzdCB3cml0dGVuIHN0cnVjdCBzaG91bGRuJ3QgYmUgYSBza2lwXG4gICAgICByZWFkZXIubmV4dCgpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAoY3Vyci5pZC5jbG9jayArIGN1cnIubGVuZ3RoID4gc3ZDbG9jaykge1xuICAgICAgd3JpdGVTdHJ1Y3RUb0xhenlTdHJ1Y3RXcml0ZXIobGF6eVN0cnVjdFdyaXRlciwgY3VyciwgbWF0aC5tYXgoc3ZDbG9jayAtIGN1cnIuaWQuY2xvY2ssIDApKVxuICAgICAgcmVhZGVyLm5leHQoKVxuICAgICAgd2hpbGUgKHJlYWRlci5jdXJyICYmIHJlYWRlci5jdXJyLmlkLmNsaWVudCA9PT0gY3VyckNsaWVudCkge1xuICAgICAgICB3cml0ZVN0cnVjdFRvTGF6eVN0cnVjdFdyaXRlcihsYXp5U3RydWN0V3JpdGVyLCByZWFkZXIuY3VyciwgMClcbiAgICAgICAgcmVhZGVyLm5leHQoKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyByZWFkIHVudGlsIHNvbWV0aGluZyBuZXcgY29tZXMgdXBcbiAgICAgIHdoaWxlIChyZWFkZXIuY3VyciAmJiByZWFkZXIuY3Vyci5pZC5jbGllbnQgPT09IGN1cnJDbGllbnQgJiYgcmVhZGVyLmN1cnIuaWQuY2xvY2sgKyByZWFkZXIuY3Vyci5sZW5ndGggPD0gc3ZDbG9jaykge1xuICAgICAgICByZWFkZXIubmV4dCgpXG4gICAgICB9XG4gICAgfVxuICB9XG4gIGZpbmlzaExhenlTdHJ1Y3RXcml0aW5nKGxhenlTdHJ1Y3RXcml0ZXIpXG4gIC8vIHdyaXRlIGRzXG4gIGNvbnN0IGRzID0gcmVhZERlbGV0ZVNldChkZWNvZGVyKVxuICB3cml0ZURlbGV0ZVNldChlbmNvZGVyLCBkcylcbiAgcmV0dXJuIGVuY29kZXIudG9VaW50OEFycmF5KClcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICogQHBhcmFtIHtVaW50OEFycmF5fSBzdlxuICovXG5leHBvcnQgY29uc3QgZGlmZlVwZGF0ZSA9ICh1cGRhdGUsIHN2KSA9PiBkaWZmVXBkYXRlVjIodXBkYXRlLCBzdiwgVXBkYXRlRGVjb2RlclYxLCBVcGRhdGVFbmNvZGVyVjEpXG5cbi8qKlxuICogQHBhcmFtIHtMYXp5U3RydWN0V3JpdGVyfSBsYXp5V3JpdGVyXG4gKi9cbmNvbnN0IGZsdXNoTGF6eVN0cnVjdFdyaXRlciA9IGxhenlXcml0ZXIgPT4ge1xuICBpZiAobGF6eVdyaXRlci53cml0dGVuID4gMCkge1xuICAgIGxhenlXcml0ZXIuY2xpZW50U3RydWN0cy5wdXNoKHsgd3JpdHRlbjogbGF6eVdyaXRlci53cml0dGVuLCByZXN0RW5jb2RlcjogZW5jb2RpbmcudG9VaW50OEFycmF5KGxhenlXcml0ZXIuZW5jb2Rlci5yZXN0RW5jb2RlcikgfSlcbiAgICBsYXp5V3JpdGVyLmVuY29kZXIucmVzdEVuY29kZXIgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKClcbiAgICBsYXp5V3JpdGVyLndyaXR0ZW4gPSAwXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge0xhenlTdHJ1Y3RXcml0ZXJ9IGxhenlXcml0ZXJcbiAqIEBwYXJhbSB7SXRlbSB8IEdDfSBzdHJ1Y3RcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqL1xuY29uc3Qgd3JpdGVTdHJ1Y3RUb0xhenlTdHJ1Y3RXcml0ZXIgPSAobGF6eVdyaXRlciwgc3RydWN0LCBvZmZzZXQpID0+IHtcbiAgLy8gZmx1c2ggY3VyciBpZiB3ZSBzdGFydCBhbm90aGVyIGNsaWVudFxuICBpZiAobGF6eVdyaXRlci53cml0dGVuID4gMCAmJiBsYXp5V3JpdGVyLmN1cnJDbGllbnQgIT09IHN0cnVjdC5pZC5jbGllbnQpIHtcbiAgICBmbHVzaExhenlTdHJ1Y3RXcml0ZXIobGF6eVdyaXRlcilcbiAgfVxuICBpZiAobGF6eVdyaXRlci53cml0dGVuID09PSAwKSB7XG4gICAgbGF6eVdyaXRlci5jdXJyQ2xpZW50ID0gc3RydWN0LmlkLmNsaWVudFxuICAgIC8vIHdyaXRlIG5leHQgY2xpZW50XG4gICAgbGF6eVdyaXRlci5lbmNvZGVyLndyaXRlQ2xpZW50KHN0cnVjdC5pZC5jbGllbnQpXG4gICAgLy8gd3JpdGUgc3RhcnRDbG9ja1xuICAgIGVuY29kaW5nLndyaXRlVmFyVWludChsYXp5V3JpdGVyLmVuY29kZXIucmVzdEVuY29kZXIsIHN0cnVjdC5pZC5jbG9jayArIG9mZnNldClcbiAgfVxuICBzdHJ1Y3Qud3JpdGUobGF6eVdyaXRlci5lbmNvZGVyLCBvZmZzZXQpXG4gIGxhenlXcml0ZXIud3JpdHRlbisrXG59XG4vKipcbiAqIENhbGwgdGhpcyBmdW5jdGlvbiB3aGVuIHdlIGNvbGxlY3RlZCBhbGwgcGFydHMgYW5kIHdhbnQgdG9cbiAqIHB1dCBhbGwgdGhlIHBhcnRzIHRvZ2V0aGVyLiBBZnRlciBjYWxsaW5nIHRoaXMgbWV0aG9kLFxuICogeW91IGNhbiBjb250aW51ZSB1c2luZyB0aGUgVXBkYXRlRW5jb2Rlci5cbiAqXG4gKiBAcGFyYW0ge0xhenlTdHJ1Y3RXcml0ZXJ9IGxhenlXcml0ZXJcbiAqL1xuY29uc3QgZmluaXNoTGF6eVN0cnVjdFdyaXRpbmcgPSAobGF6eVdyaXRlcikgPT4ge1xuICBmbHVzaExhenlTdHJ1Y3RXcml0ZXIobGF6eVdyaXRlcilcblxuICAvLyB0aGlzIGlzIGEgZnJlc2ggZW5jb2RlciBiZWNhdXNlIHdlIGNhbGxlZCBmbHVzaEN1cnJcbiAgY29uc3QgcmVzdEVuY29kZXIgPSBsYXp5V3JpdGVyLmVuY29kZXIucmVzdEVuY29kZXJcblxuICAvKipcbiAgICogTm93IHdlIHB1dCBhbGwgdGhlIGZyYWdtZW50cyB0b2dldGhlci5cbiAgICogVGhpcyB3b3JrcyBzaW1pbGFybHkgdG8gYHdyaXRlQ2xpZW50c1N0cnVjdHNgXG4gICAqL1xuXG4gIC8vIHdyaXRlICMgc3RhdGVzIHRoYXQgd2VyZSB1cGRhdGVkIC0gaS5lLiB0aGUgY2xpZW50c1xuICBlbmNvZGluZy53cml0ZVZhclVpbnQocmVzdEVuY29kZXIsIGxhenlXcml0ZXIuY2xpZW50U3RydWN0cy5sZW5ndGgpXG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsYXp5V3JpdGVyLmNsaWVudFN0cnVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBwYXJ0U3RydWN0cyA9IGxhenlXcml0ZXIuY2xpZW50U3RydWN0c1tpXVxuICAgIC8qKlxuICAgICAqIFdvcmtzIHNpbWlsYXJseSB0byBgd3JpdGVTdHJ1Y3RzYFxuICAgICAqL1xuICAgIC8vIHdyaXRlICMgZW5jb2RlZCBzdHJ1Y3RzXG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KHJlc3RFbmNvZGVyLCBwYXJ0U3RydWN0cy53cml0dGVuKVxuICAgIC8vIHdyaXRlIHRoZSByZXN0IG9mIHRoZSBmcmFnbWVudFxuICAgIGVuY29kaW5nLndyaXRlVWludDhBcnJheShyZXN0RW5jb2RlciwgcGFydFN0cnVjdHMucmVzdEVuY29kZXIpXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICogQHBhcmFtIHtmdW5jdGlvbihJdGVtfEdDfFNraXApOkl0ZW18R0N8U2tpcH0gYmxvY2tUcmFuc2Zvcm1lclxuICogQHBhcmFtIHt0eXBlb2YgVXBkYXRlRGVjb2RlclYyIHwgdHlwZW9mIFVwZGF0ZURlY29kZXJWMX0gWURlY29kZXJcbiAqIEBwYXJhbSB7dHlwZW9mIFVwZGF0ZUVuY29kZXJWMiB8IHR5cGVvZiBVcGRhdGVFbmNvZGVyVjEgfSBZRW5jb2RlclxuICovXG5leHBvcnQgY29uc3QgY29udmVydFVwZGF0ZUZvcm1hdCA9ICh1cGRhdGUsIGJsb2NrVHJhbnNmb3JtZXIsIFlEZWNvZGVyLCBZRW5jb2RlcikgPT4ge1xuICBjb25zdCB1cGRhdGVEZWNvZGVyID0gbmV3IFlEZWNvZGVyKGRlY29kaW5nLmNyZWF0ZURlY29kZXIodXBkYXRlKSlcbiAgY29uc3QgbGF6eURlY29kZXIgPSBuZXcgTGF6eVN0cnVjdFJlYWRlcih1cGRhdGVEZWNvZGVyLCBmYWxzZSlcbiAgY29uc3QgdXBkYXRlRW5jb2RlciA9IG5ldyBZRW5jb2RlcigpXG4gIGNvbnN0IGxhenlXcml0ZXIgPSBuZXcgTGF6eVN0cnVjdFdyaXRlcih1cGRhdGVFbmNvZGVyKVxuICBmb3IgKGxldCBjdXJyID0gbGF6eURlY29kZXIuY3VycjsgY3VyciAhPT0gbnVsbDsgY3VyciA9IGxhenlEZWNvZGVyLm5leHQoKSkge1xuICAgIHdyaXRlU3RydWN0VG9MYXp5U3RydWN0V3JpdGVyKGxhenlXcml0ZXIsIGJsb2NrVHJhbnNmb3JtZXIoY3VyciksIDApXG4gIH1cbiAgZmluaXNoTGF6eVN0cnVjdFdyaXRpbmcobGF6eVdyaXRlcilcbiAgY29uc3QgZHMgPSByZWFkRGVsZXRlU2V0KHVwZGF0ZURlY29kZXIpXG4gIHdyaXRlRGVsZXRlU2V0KHVwZGF0ZUVuY29kZXIsIGRzKVxuICByZXR1cm4gdXBkYXRlRW5jb2Rlci50b1VpbnQ4QXJyYXkoKVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IE9iZnVzY2F0b3JPcHRpb25zXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtPYmZ1c2NhdG9yT3B0aW9ucy5mb3JtYXR0aW5nPXRydWVdXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtPYmZ1c2NhdG9yT3B0aW9ucy5zdWJkb2NzPXRydWVdXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtPYmZ1c2NhdG9yT3B0aW9ucy55eG1sPXRydWVdIFdoZXRoZXIgdG8gb2JmdXNjYXRlIG5vZGVOYW1lIC8gaG9va05hbWVcbiAqL1xuXG4vKipcbiAqIEBwYXJhbSB7T2JmdXNjYXRvck9wdGlvbnN9IG9iZnVzY2F0b3JcbiAqL1xuY29uc3QgY3JlYXRlT2JmdXNjYXRvciA9ICh7IGZvcm1hdHRpbmcgPSB0cnVlLCBzdWJkb2NzID0gdHJ1ZSwgeXhtbCA9IHRydWUgfSA9IHt9KSA9PiB7XG4gIGxldCBpID0gMFxuICBjb25zdCBtYXBLZXlDYWNoZSA9IG1hcC5jcmVhdGUoKVxuICBjb25zdCBub2RlTmFtZUNhY2hlID0gbWFwLmNyZWF0ZSgpXG4gIGNvbnN0IGZvcm1hdHRpbmdLZXlDYWNoZSA9IG1hcC5jcmVhdGUoKVxuICBjb25zdCBmb3JtYXR0aW5nVmFsdWVDYWNoZSA9IG1hcC5jcmVhdGUoKVxuICBmb3JtYXR0aW5nVmFsdWVDYWNoZS5zZXQobnVsbCwgbnVsbCkgLy8gZW5kIG9mIGEgZm9ybWF0dGluZyByYW5nZSBzaG91bGQgYWx3YXlzIGJlIHRoZSBlbmQgb2YgYSBmb3JtYXR0aW5nIHJhbmdlXG4gIC8qKlxuICAgKiBAcGFyYW0ge0l0ZW18R0N8U2tpcH0gYmxvY2tcbiAgICogQHJldHVybiB7SXRlbXxHQ3xTa2lwfVxuICAgKi9cbiAgcmV0dXJuIGJsb2NrID0+IHtcbiAgICBzd2l0Y2ggKGJsb2NrLmNvbnN0cnVjdG9yKSB7XG4gICAgICBjYXNlIEdDOlxuICAgICAgY2FzZSBTa2lwOlxuICAgICAgICByZXR1cm4gYmxvY2tcbiAgICAgIGNhc2UgSXRlbToge1xuICAgICAgICBjb25zdCBpdGVtID0gLyoqIEB0eXBlIHtJdGVtfSAqLyAoYmxvY2spXG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBpdGVtLmNvbnRlbnRcbiAgICAgICAgc3dpdGNoIChjb250ZW50LmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgY2FzZSBDb250ZW50RGVsZXRlZDpcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgY2FzZSBDb250ZW50VHlwZToge1xuICAgICAgICAgICAgaWYgKHl4bWwpIHtcbiAgICAgICAgICAgICAgY29uc3QgdHlwZSA9IC8qKiBAdHlwZSB7Q29udGVudFR5cGV9ICovIChjb250ZW50KS50eXBlXG4gICAgICAgICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgWVhtbEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICB0eXBlLm5vZGVOYW1lID0gbWFwLnNldElmVW5kZWZpbmVkKG5vZGVOYW1lQ2FjaGUsIHR5cGUubm9kZU5hbWUsICgpID0+ICdub2RlLScgKyBpKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgWVhtbEhvb2spIHtcbiAgICAgICAgICAgICAgICB0eXBlLmhvb2tOYW1lID0gbWFwLnNldElmVW5kZWZpbmVkKG5vZGVOYW1lQ2FjaGUsIHR5cGUuaG9va05hbWUsICgpID0+ICdob29rLScgKyBpKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIENvbnRlbnRBbnk6IHtcbiAgICAgICAgICAgIGNvbnN0IGMgPSAvKiogQHR5cGUge0NvbnRlbnRBbnl9ICovIChjb250ZW50KVxuICAgICAgICAgICAgYy5hcnIgPSBjLmFyci5tYXAoKCkgPT4gaSlcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgQ29udGVudEJpbmFyeToge1xuICAgICAgICAgICAgY29uc3QgYyA9IC8qKiBAdHlwZSB7Q29udGVudEJpbmFyeX0gKi8gKGNvbnRlbnQpXG4gICAgICAgICAgICBjLmNvbnRlbnQgPSBuZXcgVWludDhBcnJheShbaV0pXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIENvbnRlbnREb2M6IHtcbiAgICAgICAgICAgIGNvbnN0IGMgPSAvKiogQHR5cGUge0NvbnRlbnREb2N9ICovIChjb250ZW50KVxuICAgICAgICAgICAgaWYgKHN1YmRvY3MpIHtcbiAgICAgICAgICAgICAgYy5vcHRzID0ge31cbiAgICAgICAgICAgICAgYy5kb2MuZ3VpZCA9IGkgKyAnJ1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSBDb250ZW50RW1iZWQ6IHtcbiAgICAgICAgICAgIGNvbnN0IGMgPSAvKiogQHR5cGUge0NvbnRlbnRFbWJlZH0gKi8gKGNvbnRlbnQpXG4gICAgICAgICAgICBjLmVtYmVkID0ge31cbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuICAgICAgICAgIGNhc2UgQ29udGVudEZvcm1hdDoge1xuICAgICAgICAgICAgY29uc3QgYyA9IC8qKiBAdHlwZSB7Q29udGVudEZvcm1hdH0gKi8gKGNvbnRlbnQpXG4gICAgICAgICAgICBpZiAoZm9ybWF0dGluZykge1xuICAgICAgICAgICAgICBjLmtleSA9IG1hcC5zZXRJZlVuZGVmaW5lZChmb3JtYXR0aW5nS2V5Q2FjaGUsIGMua2V5LCAoKSA9PiBpICsgJycpXG4gICAgICAgICAgICAgIGMudmFsdWUgPSBtYXAuc2V0SWZVbmRlZmluZWQoZm9ybWF0dGluZ1ZhbHVlQ2FjaGUsIGMudmFsdWUsICgpID0+ICh7IGkgfSkpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cbiAgICAgICAgICBjYXNlIENvbnRlbnRKU09OOiB7XG4gICAgICAgICAgICBjb25zdCBjID0gLyoqIEB0eXBlIHtDb250ZW50SlNPTn0gKi8gKGNvbnRlbnQpXG4gICAgICAgICAgICBjLmFyciA9IGMuYXJyLm1hcCgoKSA9PiBpKVxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgICAgY2FzZSBDb250ZW50U3RyaW5nOiB7XG4gICAgICAgICAgICBjb25zdCBjID0gLyoqIEB0eXBlIHtDb250ZW50U3RyaW5nfSAqLyAoY29udGVudClcbiAgICAgICAgICAgIGMuc3RyID0gc3RyaW5nLnJlcGVhdCgoaSAlIDEwKSArICcnLCBjLnN0ci5sZW5ndGgpXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgLy8gdW5rbm93biBjb250ZW50IHR5cGVcbiAgICAgICAgICAgIGVycm9yLnVuZXhwZWN0ZWRDYXNlKClcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXRlbS5wYXJlbnRTdWIpIHtcbiAgICAgICAgICBpdGVtLnBhcmVudFN1YiA9IG1hcC5zZXRJZlVuZGVmaW5lZChtYXBLZXlDYWNoZSwgaXRlbS5wYXJlbnRTdWIsICgpID0+IGkgKyAnJylcbiAgICAgICAgfVxuICAgICAgICBpKytcbiAgICAgICAgcmV0dXJuIGJsb2NrXG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyB1bmtub3duIGJsb2NrLXR5cGVcbiAgICAgICAgZXJyb3IudW5leHBlY3RlZENhc2UoKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoaXMgZnVuY3Rpb24gb2JmdXNjYXRlcyB0aGUgY29udGVudCBvZiBhIFlqcyB1cGRhdGUuIFRoaXMgaXMgdXNlZnVsIHRvIHNoYXJlXG4gKiBidWdneSBZanMgZG9jdW1lbnRzIHdoaWxlIHNpZ25pZmljYW50bHkgbGltaXRpbmcgdGhlIHBvc3NpYmlsaXR5IHRoYXQgYVxuICogZGV2ZWxvcGVyIGNhbiBvbiB0aGUgdXNlci4gTm90ZSB0aGF0IGl0IG1pZ2h0IHN0aWxsIGJlIHBvc3NpYmxlIHRvIGRlZHVjZVxuICogc29tZSBpbmZvcm1hdGlvbiBieSBhbmFseXppbmcgdGhlIFwic3RydWN0dXJlXCIgb2YgdGhlIGRvY3VtZW50IG9yIGJ5IGFuYWx5emluZ1xuICogdGhlIHR5cGluZyBiZWhhdmlvciB1c2luZyB0aGUgQ1JEVC1yZWxhdGVkIG1ldGFkYXRhIHRoYXQgaXMgc3RpbGwga2VwdCBmdWxseVxuICogaW50YWN0LlxuICpcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gdXBkYXRlXG4gKiBAcGFyYW0ge09iZnVzY2F0b3JPcHRpb25zfSBbb3B0c11cbiAqL1xuZXhwb3J0IGNvbnN0IG9iZnVzY2F0ZVVwZGF0ZSA9ICh1cGRhdGUsIG9wdHMpID0+IGNvbnZlcnRVcGRhdGVGb3JtYXQodXBkYXRlLCBjcmVhdGVPYmZ1c2NhdG9yKG9wdHMpLCBVcGRhdGVEZWNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMSlcblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICogQHBhcmFtIHtPYmZ1c2NhdG9yT3B0aW9uc30gW29wdHNdXG4gKi9cbmV4cG9ydCBjb25zdCBvYmZ1c2NhdGVVcGRhdGVWMiA9ICh1cGRhdGUsIG9wdHMpID0+IGNvbnZlcnRVcGRhdGVGb3JtYXQodXBkYXRlLCBjcmVhdGVPYmZ1c2NhdG9yKG9wdHMpLCBVcGRhdGVEZWNvZGVyVjIsIFVwZGF0ZUVuY29kZXJWMilcblxuLyoqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICovXG5leHBvcnQgY29uc3QgY29udmVydFVwZGF0ZUZvcm1hdFYxVG9WMiA9IHVwZGF0ZSA9PiBjb252ZXJ0VXBkYXRlRm9ybWF0KHVwZGF0ZSwgZi5pZCwgVXBkYXRlRGVjb2RlclYxLCBVcGRhdGVFbmNvZGVyVjIpXG5cbi8qKlxuICogQHBhcmFtIHtVaW50OEFycmF5fSB1cGRhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IGNvbnZlcnRVcGRhdGVGb3JtYXRWMlRvVjEgPSB1cGRhdGUgPT4gY29udmVydFVwZGF0ZUZvcm1hdCh1cGRhdGUsIGYuaWQsIFVwZGF0ZURlY29kZXJWMiwgVXBkYXRlRW5jb2RlclYxKVxuIiwgImltcG9ydCB7XG4gIGlzRGVsZXRlZCxcbiAgSXRlbSwgQWJzdHJhY3RUeXBlLCBUcmFuc2FjdGlvbiwgQWJzdHJhY3RTdHJ1Y3QgLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbmltcG9ydCAqIGFzIHNldCBmcm9tICdsaWIwL3NldCdcbmltcG9ydCAqIGFzIGFycmF5IGZyb20gJ2xpYjAvYXJyYXknXG5pbXBvcnQgKiBhcyBlcnJvciBmcm9tICdsaWIwL2Vycm9yJ1xuXG5jb25zdCBlcnJvckNvbXB1dGVDaGFuZ2VzID0gJ1lvdSBtdXN0IG5vdCBjb21wdXRlIGNoYW5nZXMgYWZ0ZXIgdGhlIGV2ZW50LWhhbmRsZXIgZmlyZWQuJ1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSB7QWJzdHJhY3RUeXBlPGFueT59IFRcbiAqIFlFdmVudCBkZXNjcmliZXMgdGhlIGNoYW5nZXMgb24gYSBZVHlwZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFlFdmVudCB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1R9IHRhcmdldCBUaGUgY2hhbmdlZCB0eXBlLlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKi9cbiAgY29uc3RydWN0b3IgKHRhcmdldCwgdHJhbnNhY3Rpb24pIHtcbiAgICAvKipcbiAgICAgKiBUaGUgdHlwZSBvbiB3aGljaCB0aGlzIGV2ZW50IHdhcyBjcmVhdGVkIG9uLlxuICAgICAqIEB0eXBlIHtUfVxuICAgICAqL1xuICAgIHRoaXMudGFyZ2V0ID0gdGFyZ2V0XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgdGFyZ2V0IG9uIHdoaWNoIHRoZSBvYnNlcnZlIGNhbGxiYWNrIGlzIGNhbGxlZC5cbiAgICAgKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59XG4gICAgICovXG4gICAgdGhpcy5jdXJyZW50VGFyZ2V0ID0gdGFyZ2V0XG4gICAgLyoqXG4gICAgICogVGhlIHRyYW5zYWN0aW9uIHRoYXQgdHJpZ2dlcmVkIHRoaXMgZXZlbnQuXG4gICAgICogQHR5cGUge1RyYW5zYWN0aW9ufVxuICAgICAqL1xuICAgIHRoaXMudHJhbnNhY3Rpb24gPSB0cmFuc2FjdGlvblxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtPYmplY3R8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLl9jaGFuZ2VzID0gbnVsbFxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudWxsIHwgTWFwPHN0cmluZywgeyBhY3Rpb246ICdhZGQnIHwgJ3VwZGF0ZScgfCAnZGVsZXRlJywgb2xkVmFsdWU6IGFueSB9Pn1cbiAgICAgKi9cbiAgICB0aGlzLl9rZXlzID0gbnVsbFxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudWxsIHwgQXJyYXk8eyBpbnNlcnQ/OiBzdHJpbmcgfCBBcnJheTxhbnk+IHwgb2JqZWN0IHwgQWJzdHJhY3RUeXBlPGFueT4sIHJldGFpbj86IG51bWJlciwgZGVsZXRlPzogbnVtYmVyLCBhdHRyaWJ1dGVzPzogT2JqZWN0PHN0cmluZywgYW55PiB9Pn1cbiAgICAgKi9cbiAgICB0aGlzLl9kZWx0YSA9IG51bGxcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8c3RyaW5nfG51bWJlcj58bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLl9wYXRoID0gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGVzIHRoZSBwYXRoIGZyb20gYHlgIHRvIHRoZSBjaGFuZ2VkIHR5cGUuXG4gICAqXG4gICAqIEB0b2RvIHYxNCBzaG91bGQgc3RhbmRhcmRpemUgb24gcGF0aDogQXJyYXk8e3BhcmVudCwgaW5kZXh9PiBiZWNhdXNlIHRoYXQgaXMgZWFzaWVyIHRvIHdvcmsgd2l0aC5cbiAgICpcbiAgICogVGhlIGZvbGxvd2luZyBwcm9wZXJ0eSBob2xkczpcbiAgICogQGV4YW1wbGVcbiAgICogICBsZXQgdHlwZSA9IHlcbiAgICogICBldmVudC5wYXRoLmZvckVhY2goZGlyID0+IHtcbiAgICogICAgIHR5cGUgPSB0eXBlLmdldChkaXIpXG4gICAqICAgfSlcbiAgICogICB0eXBlID09PSBldmVudC50YXJnZXQgLy8gPT4gdHJ1ZVxuICAgKi9cbiAgZ2V0IHBhdGggKCkge1xuICAgIHJldHVybiB0aGlzLl9wYXRoIHx8ICh0aGlzLl9wYXRoID0gZ2V0UGF0aFRvKHRoaXMuY3VycmVudFRhcmdldCwgdGhpcy50YXJnZXQpKVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgc3RydWN0IGlzIGRlbGV0ZWQgYnkgdGhpcyBldmVudC5cbiAgICpcbiAgICogSW4gY29udHJhc3QgdG8gY2hhbmdlLmRlbGV0ZWQsIHRoaXMgbWV0aG9kIGFsc28gcmV0dXJucyB0cnVlIGlmIHRoZSBzdHJ1Y3Qgd2FzIGFkZGVkIGFuZCB0aGVuIGRlbGV0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7QWJzdHJhY3RTdHJ1Y3R9IHN0cnVjdFxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgZGVsZXRlcyAoc3RydWN0KSB7XG4gICAgcmV0dXJuIGlzRGVsZXRlZCh0aGlzLnRyYW5zYWN0aW9uLmRlbGV0ZVNldCwgc3RydWN0LmlkKVxuICB9XG5cbiAgLyoqXG4gICAqIEB0eXBlIHtNYXA8c3RyaW5nLCB7IGFjdGlvbjogJ2FkZCcgfCAndXBkYXRlJyB8ICdkZWxldGUnLCBvbGRWYWx1ZTogYW55IH0+fVxuICAgKi9cbiAgZ2V0IGtleXMgKCkge1xuICAgIGlmICh0aGlzLl9rZXlzID09PSBudWxsKSB7XG4gICAgICBpZiAodGhpcy50cmFuc2FjdGlvbi5kb2MuX3RyYW5zYWN0aW9uQ2xlYW51cHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IGVycm9yLmNyZWF0ZShlcnJvckNvbXB1dGVDaGFuZ2VzKVxuICAgICAgfVxuICAgICAgY29uc3Qga2V5cyA9IG5ldyBNYXAoKVxuICAgICAgY29uc3QgdGFyZ2V0ID0gdGhpcy50YXJnZXRcbiAgICAgIGNvbnN0IGNoYW5nZWQgPSAvKiogQHR5cGUgU2V0PHN0cmluZ3xudWxsPiAqLyAodGhpcy50cmFuc2FjdGlvbi5jaGFuZ2VkLmdldCh0YXJnZXQpKVxuICAgICAgY2hhbmdlZC5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGlmIChrZXkgIT09IG51bGwpIHtcbiAgICAgICAgICBjb25zdCBpdGVtID0gLyoqIEB0eXBlIHtJdGVtfSAqLyAodGFyZ2V0Ll9tYXAuZ2V0KGtleSkpXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQHR5cGUgeydkZWxldGUnIHwgJ2FkZCcgfCAndXBkYXRlJ31cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBsZXQgYWN0aW9uXG4gICAgICAgICAgbGV0IG9sZFZhbHVlXG4gICAgICAgICAgaWYgKHRoaXMuYWRkcyhpdGVtKSkge1xuICAgICAgICAgICAgbGV0IHByZXYgPSBpdGVtLmxlZnRcbiAgICAgICAgICAgIHdoaWxlIChwcmV2ICE9PSBudWxsICYmIHRoaXMuYWRkcyhwcmV2KSkge1xuICAgICAgICAgICAgICBwcmV2ID0gcHJldi5sZWZ0XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5kZWxldGVzKGl0ZW0pKSB7XG4gICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsICYmIHRoaXMuZGVsZXRlcyhwcmV2KSkge1xuICAgICAgICAgICAgICAgIGFjdGlvbiA9ICdkZWxldGUnXG4gICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBhcnJheS5sYXN0KHByZXYuY29udGVudC5nZXRDb250ZW50KCkpXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChwcmV2ICE9PSBudWxsICYmIHRoaXMuZGVsZXRlcyhwcmV2KSkge1xuICAgICAgICAgICAgICAgIGFjdGlvbiA9ICd1cGRhdGUnXG4gICAgICAgICAgICAgICAgb2xkVmFsdWUgPSBhcnJheS5sYXN0KHByZXYuY29udGVudC5nZXRDb250ZW50KCkpXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYWN0aW9uID0gJ2FkZCdcbiAgICAgICAgICAgICAgICBvbGRWYWx1ZSA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmRlbGV0ZXMoaXRlbSkpIHtcbiAgICAgICAgICAgICAgYWN0aW9uID0gJ2RlbGV0ZSdcbiAgICAgICAgICAgICAgb2xkVmFsdWUgPSBhcnJheS5sYXN0KC8qKiBAdHlwZSB7SXRlbX0gKi8gaXRlbS5jb250ZW50LmdldENvbnRlbnQoKSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiAvLyBub3BcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAga2V5cy5zZXQoa2V5LCB7IGFjdGlvbiwgb2xkVmFsdWUgfSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIHRoaXMuX2tleXMgPSBrZXlzXG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9rZXlzXG4gIH1cblxuICAvKipcbiAgICogVGhpcyBpcyBhIGNvbXB1dGVkIHByb3BlcnR5LiBOb3RlIHRoYXQgdGhpcyBjYW4gb25seSBiZSBzYWZlbHkgY29tcHV0ZWQgZHVyaW5nIHRoZVxuICAgKiBldmVudCBjYWxsLiBDb21wdXRpbmcgdGhpcyBwcm9wZXJ0eSBhZnRlciBvdGhlciBjaGFuZ2VzIGhhcHBlbmVkIG1pZ2h0IHJlc3VsdCBpblxuICAgKiB1bmV4cGVjdGVkIGJlaGF2aW9yIChpbmNvcnJlY3QgY29tcHV0YXRpb24gb2YgZGVsdGFzKS4gQSBzYWZlIHdheSB0byBjb2xsZWN0IGNoYW5nZXNcbiAgICogaXMgdG8gc3RvcmUgdGhlIGBjaGFuZ2VzYCBvciB0aGUgYGRlbHRhYCBvYmplY3QuIEF2b2lkIHN0b3JpbmcgdGhlIGB0cmFuc2FjdGlvbmAgb2JqZWN0LlxuICAgKlxuICAgKiBAdHlwZSB7QXJyYXk8e2luc2VydD86IHN0cmluZyB8IEFycmF5PGFueT4gfCBvYmplY3QgfCBBYnN0cmFjdFR5cGU8YW55PiwgcmV0YWluPzogbnVtYmVyLCBkZWxldGU/OiBudW1iZXIsIGF0dHJpYnV0ZXM/OiBPYmplY3Q8c3RyaW5nLCBhbnk+fT59XG4gICAqL1xuICBnZXQgZGVsdGEgKCkge1xuICAgIHJldHVybiB0aGlzLmNoYW5nZXMuZGVsdGFcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhIHN0cnVjdCBpcyBhZGRlZCBieSB0aGlzIGV2ZW50LlxuICAgKlxuICAgKiBJbiBjb250cmFzdCB0byBjaGFuZ2UuZGVsZXRlZCwgdGhpcyBtZXRob2QgYWxzbyByZXR1cm5zIHRydWUgaWYgdGhlIHN0cnVjdCB3YXMgYWRkZWQgYW5kIHRoZW4gZGVsZXRlZC5cbiAgICpcbiAgICogQHBhcmFtIHtBYnN0cmFjdFN0cnVjdH0gc3RydWN0XG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBhZGRzIChzdHJ1Y3QpIHtcbiAgICByZXR1cm4gc3RydWN0LmlkLmNsb2NrID49ICh0aGlzLnRyYW5zYWN0aW9uLmJlZm9yZVN0YXRlLmdldChzdHJ1Y3QuaWQuY2xpZW50KSB8fCAwKVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgaXMgYSBjb21wdXRlZCBwcm9wZXJ0eS4gTm90ZSB0aGF0IHRoaXMgY2FuIG9ubHkgYmUgc2FmZWx5IGNvbXB1dGVkIGR1cmluZyB0aGVcbiAgICogZXZlbnQgY2FsbC4gQ29tcHV0aW5nIHRoaXMgcHJvcGVydHkgYWZ0ZXIgb3RoZXIgY2hhbmdlcyBoYXBwZW5lZCBtaWdodCByZXN1bHQgaW5cbiAgICogdW5leHBlY3RlZCBiZWhhdmlvciAoaW5jb3JyZWN0IGNvbXB1dGF0aW9uIG9mIGRlbHRhcykuIEEgc2FmZSB3YXkgdG8gY29sbGVjdCBjaGFuZ2VzXG4gICAqIGlzIHRvIHN0b3JlIHRoZSBgY2hhbmdlc2Agb3IgdGhlIGBkZWx0YWAgb2JqZWN0LiBBdm9pZCBzdG9yaW5nIHRoZSBgdHJhbnNhY3Rpb25gIG9iamVjdC5cbiAgICpcbiAgICogQHR5cGUge3thZGRlZDpTZXQ8SXRlbT4sZGVsZXRlZDpTZXQ8SXRlbT4sa2V5czpNYXA8c3RyaW5nLHthY3Rpb246J2FkZCd8J3VwZGF0ZSd8J2RlbGV0ZScsb2xkVmFsdWU6YW55fT4sZGVsdGE6QXJyYXk8e2luc2VydD86QXJyYXk8YW55PnxzdHJpbmcsIGRlbGV0ZT86bnVtYmVyLCByZXRhaW4/Om51bWJlcn0+fX1cbiAgICovXG4gIGdldCBjaGFuZ2VzICgpIHtcbiAgICBsZXQgY2hhbmdlcyA9IHRoaXMuX2NoYW5nZXNcbiAgICBpZiAoY2hhbmdlcyA9PT0gbnVsbCkge1xuICAgICAgaWYgKHRoaXMudHJhbnNhY3Rpb24uZG9jLl90cmFuc2FjdGlvbkNsZWFudXBzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBlcnJvci5jcmVhdGUoZXJyb3JDb21wdXRlQ2hhbmdlcylcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXMudGFyZ2V0XG4gICAgICBjb25zdCBhZGRlZCA9IHNldC5jcmVhdGUoKVxuICAgICAgY29uc3QgZGVsZXRlZCA9IHNldC5jcmVhdGUoKVxuICAgICAgLyoqXG4gICAgICAgKiBAdHlwZSB7QXJyYXk8e2luc2VydDpBcnJheTxhbnk+fXx7ZGVsZXRlOm51bWJlcn18e3JldGFpbjpudW1iZXJ9Pn1cbiAgICAgICAqL1xuICAgICAgY29uc3QgZGVsdGEgPSBbXVxuICAgICAgY2hhbmdlcyA9IHtcbiAgICAgICAgYWRkZWQsXG4gICAgICAgIGRlbGV0ZWQsXG4gICAgICAgIGRlbHRhLFxuICAgICAgICBrZXlzOiB0aGlzLmtleXNcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNoYW5nZWQgPSAvKiogQHR5cGUgU2V0PHN0cmluZ3xudWxsPiAqLyAodGhpcy50cmFuc2FjdGlvbi5jaGFuZ2VkLmdldCh0YXJnZXQpKVxuICAgICAgaWYgKGNoYW5nZWQuaGFzKG51bGwpKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAdHlwZSB7YW55fVxuICAgICAgICAgKi9cbiAgICAgICAgbGV0IGxhc3RPcCA9IG51bGxcbiAgICAgICAgY29uc3QgcGFja09wID0gKCkgPT4ge1xuICAgICAgICAgIGlmIChsYXN0T3ApIHtcbiAgICAgICAgICAgIGRlbHRhLnB1c2gobGFzdE9wKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpdGVtID0gdGFyZ2V0Ll9zdGFydDsgaXRlbSAhPT0gbnVsbDsgaXRlbSA9IGl0ZW0ucmlnaHQpIHtcbiAgICAgICAgICBpZiAoaXRlbS5kZWxldGVkKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5kZWxldGVzKGl0ZW0pICYmICF0aGlzLmFkZHMoaXRlbSkpIHtcbiAgICAgICAgICAgICAgaWYgKGxhc3RPcCA9PT0gbnVsbCB8fCBsYXN0T3AuZGVsZXRlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBwYWNrT3AoKVxuICAgICAgICAgICAgICAgIGxhc3RPcCA9IHsgZGVsZXRlOiAwIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsYXN0T3AuZGVsZXRlICs9IGl0ZW0ubGVuZ3RoXG4gICAgICAgICAgICAgIGRlbGV0ZWQuYWRkKGl0ZW0pXG4gICAgICAgICAgICB9IC8vIGVsc2Ugbm9wXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFkZHMoaXRlbSkpIHtcbiAgICAgICAgICAgICAgaWYgKGxhc3RPcCA9PT0gbnVsbCB8fCBsYXN0T3AuaW5zZXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBwYWNrT3AoKVxuICAgICAgICAgICAgICAgIGxhc3RPcCA9IHsgaW5zZXJ0OiBbXSB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgbGFzdE9wLmluc2VydCA9IGxhc3RPcC5pbnNlcnQuY29uY2F0KGl0ZW0uY29udGVudC5nZXRDb250ZW50KCkpXG4gICAgICAgICAgICAgIGFkZGVkLmFkZChpdGVtKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKGxhc3RPcCA9PT0gbnVsbCB8fCBsYXN0T3AucmV0YWluID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBwYWNrT3AoKVxuICAgICAgICAgICAgICAgIGxhc3RPcCA9IHsgcmV0YWluOiAwIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsYXN0T3AucmV0YWluICs9IGl0ZW0ubGVuZ3RoXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChsYXN0T3AgIT09IG51bGwgJiYgbGFzdE9wLnJldGFpbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcGFja09wKClcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5fY2hhbmdlcyA9IGNoYW5nZXNcbiAgICB9XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7YW55fSAqLyAoY2hhbmdlcylcbiAgfVxufVxuXG4vKipcbiAqIENvbXB1dGUgdGhlIHBhdGggZnJvbSB0aGlzIHR5cGUgdG8gdGhlIHNwZWNpZmllZCB0YXJnZXQuXG4gKlxuICogQGV4YW1wbGVcbiAqICAgLy8gYGNoaWxkYCBzaG91bGQgYmUgYWNjZXNzaWJsZSB2aWEgYHR5cGUuZ2V0KHBhdGhbMF0pLmdldChwYXRoWzFdKS4uYFxuICogICBjb25zdCBwYXRoID0gdHlwZS5nZXRQYXRoVG8oY2hpbGQpXG4gKiAgIC8vIGFzc3VtaW5nIGB0eXBlIGluc3RhbmNlb2YgWUFycmF5YFxuICogICBjb25zb2xlLmxvZyhwYXRoKSAvLyBtaWdodCBsb29rIGxpa2UgPT4gWzIsICdrZXkxJ11cbiAqICAgY2hpbGQgPT09IHR5cGUuZ2V0KHBhdGhbMF0pLmdldChwYXRoWzFdKVxuICpcbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHBhcmVudFxuICogQHBhcmFtIHtBYnN0cmFjdFR5cGU8YW55Pn0gY2hpbGQgdGFyZ2V0XG4gKiBAcmV0dXJuIHtBcnJheTxzdHJpbmd8bnVtYmVyPn0gUGF0aCB0byB0aGUgdGFyZ2V0XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5jb25zdCBnZXRQYXRoVG8gPSAocGFyZW50LCBjaGlsZCkgPT4ge1xuICBjb25zdCBwYXRoID0gW11cbiAgd2hpbGUgKGNoaWxkLl9pdGVtICE9PSBudWxsICYmIGNoaWxkICE9PSBwYXJlbnQpIHtcbiAgICBpZiAoY2hpbGQuX2l0ZW0ucGFyZW50U3ViICE9PSBudWxsKSB7XG4gICAgICAvLyBwYXJlbnQgaXMgbWFwLWlzaFxuICAgICAgcGF0aC51bnNoaWZ0KGNoaWxkLl9pdGVtLnBhcmVudFN1YilcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcGFyZW50IGlzIGFycmF5LWlzaFxuICAgICAgbGV0IGkgPSAwXG4gICAgICBsZXQgYyA9IC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovIChjaGlsZC5faXRlbS5wYXJlbnQpLl9zdGFydFxuICAgICAgd2hpbGUgKGMgIT09IGNoaWxkLl9pdGVtICYmIGMgIT09IG51bGwpIHtcbiAgICAgICAgaWYgKCFjLmRlbGV0ZWQgJiYgYy5jb3VudGFibGUpIHtcbiAgICAgICAgICBpICs9IGMubGVuZ3RoXG4gICAgICAgIH1cbiAgICAgICAgYyA9IGMucmlnaHRcbiAgICAgIH1cbiAgICAgIHBhdGgudW5zaGlmdChpKVxuICAgIH1cbiAgICBjaGlsZCA9IC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovIChjaGlsZC5faXRlbS5wYXJlbnQpXG4gIH1cbiAgcmV0dXJuIHBhdGhcbn1cbiIsICJpbXBvcnQge1xuICByZW1vdmVFdmVudEhhbmRsZXJMaXN0ZW5lcixcbiAgY2FsbEV2ZW50SGFuZGxlckxpc3RlbmVycyxcbiAgYWRkRXZlbnRIYW5kbGVyTGlzdGVuZXIsXG4gIGNyZWF0ZUV2ZW50SGFuZGxlcixcbiAgZ2V0U3RhdGUsXG4gIGlzVmlzaWJsZSxcbiAgQ29udGVudFR5cGUsXG4gIGNyZWF0ZUlELFxuICBDb250ZW50QW55LFxuICBDb250ZW50QmluYXJ5LFxuICBnZXRJdGVtQ2xlYW5TdGFydCxcbiAgQ29udGVudERvYywgWVRleHQsIFlBcnJheSwgVXBkYXRlRW5jb2RlclYxLCBVcGRhdGVFbmNvZGVyVjIsIERvYywgU25hcHNob3QsIFRyYW5zYWN0aW9uLCBFdmVudEhhbmRsZXIsIFlFdmVudCwgSXRlbSwgLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbmltcG9ydCAqIGFzIG1hcCBmcm9tICdsaWIwL21hcCdcbmltcG9ydCAqIGFzIGl0ZXJhdG9yIGZyb20gJ2xpYjAvaXRlcmF0b3InXG5pbXBvcnQgKiBhcyBlcnJvciBmcm9tICdsaWIwL2Vycm9yJ1xuaW1wb3J0ICogYXMgbWF0aCBmcm9tICdsaWIwL21hdGgnXG5pbXBvcnQgKiBhcyBsb2cgZnJvbSAnbGliMC9sb2dnaW5nJ1xuXG4vKipcbiAqIGh0dHBzOi8vZG9jcy55anMuZGV2L2dldHRpbmctc3RhcnRlZC93b3JraW5nLXdpdGgtc2hhcmVkLXR5cGVzI2NhdmVhdHNcbiAqL1xuZXhwb3J0IGNvbnN0IHdhcm5QcmVtYXR1cmVBY2Nlc3MgPSAoKSA9PiB7IGxvZy53YXJuKCdJbnZhbGlkIGFjY2VzczogQWRkIFlqcyB0eXBlIHRvIGEgZG9jdW1lbnQgYmVmb3JlIHJlYWRpbmcgZGF0YS4nKSB9XG5cbmNvbnN0IG1heFNlYXJjaE1hcmtlciA9IDgwXG5cbi8qKlxuICogQSB1bmlxdWUgdGltZXN0YW1wIHRoYXQgaWRlbnRpZmllcyBlYWNoIG1hcmtlci5cbiAqXG4gKiBUaW1lIGlzIHJlbGF0aXZlLC4uIHRoaXMgaXMgbW9yZSBsaWtlIGFuIGV2ZXItaW5jcmVhc2luZyBjbG9jay5cbiAqXG4gKiBAdHlwZSB7bnVtYmVyfVxuICovXG5sZXQgZ2xvYmFsU2VhcmNoTWFya2VyVGltZXN0YW1wID0gMFxuXG5leHBvcnQgY2xhc3MgQXJyYXlTZWFyY2hNYXJrZXIge1xuICAvKipcbiAgICogQHBhcmFtIHtJdGVtfSBwXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuICAgKi9cbiAgY29uc3RydWN0b3IgKHAsIGluZGV4KSB7XG4gICAgcC5tYXJrZXIgPSB0cnVlXG4gICAgdGhpcy5wID0gcFxuICAgIHRoaXMuaW5kZXggPSBpbmRleFxuICAgIHRoaXMudGltZXN0YW1wID0gZ2xvYmFsU2VhcmNoTWFya2VyVGltZXN0YW1wKytcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXlTZWFyY2hNYXJrZXJ9IG1hcmtlclxuICovXG5jb25zdCByZWZyZXNoTWFya2VyVGltZXN0YW1wID0gbWFya2VyID0+IHsgbWFya2VyLnRpbWVzdGFtcCA9IGdsb2JhbFNlYXJjaE1hcmtlclRpbWVzdGFtcCsrIH1cblxuLyoqXG4gKiBUaGlzIGlzIHJhdGhlciBjb21wbGV4IHNvIHRoaXMgZnVuY3Rpb24gaXMgdGhlIG9ubHkgdGhpbmcgdGhhdCBzaG91bGQgb3ZlcndyaXRlIGEgbWFya2VyXG4gKlxuICogQHBhcmFtIHtBcnJheVNlYXJjaE1hcmtlcn0gbWFya2VyXG4gKiBAcGFyYW0ge0l0ZW19IHBcbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuICovXG5jb25zdCBvdmVyd3JpdGVNYXJrZXIgPSAobWFya2VyLCBwLCBpbmRleCkgPT4ge1xuICBtYXJrZXIucC5tYXJrZXIgPSBmYWxzZVxuICBtYXJrZXIucCA9IHBcbiAgcC5tYXJrZXIgPSB0cnVlXG4gIG1hcmtlci5pbmRleCA9IGluZGV4XG4gIG1hcmtlci50aW1lc3RhbXAgPSBnbG9iYWxTZWFyY2hNYXJrZXJUaW1lc3RhbXArK1xufVxuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8QXJyYXlTZWFyY2hNYXJrZXI+fSBzZWFyY2hNYXJrZXJcbiAqIEBwYXJhbSB7SXRlbX0gcFxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG4gKi9cbmNvbnN0IG1hcmtQb3NpdGlvbiA9IChzZWFyY2hNYXJrZXIsIHAsIGluZGV4KSA9PiB7XG4gIGlmIChzZWFyY2hNYXJrZXIubGVuZ3RoID49IG1heFNlYXJjaE1hcmtlcikge1xuICAgIC8vIG92ZXJyaWRlIG9sZGVzdCBtYXJrZXIgKHdlIGRvbid0IHdhbnQgdG8gY3JlYXRlIG1vcmUgb2JqZWN0cylcbiAgICBjb25zdCBtYXJrZXIgPSBzZWFyY2hNYXJrZXIucmVkdWNlKChhLCBiKSA9PiBhLnRpbWVzdGFtcCA8IGIudGltZXN0YW1wID8gYSA6IGIpXG4gICAgb3ZlcndyaXRlTWFya2VyKG1hcmtlciwgcCwgaW5kZXgpXG4gICAgcmV0dXJuIG1hcmtlclxuICB9IGVsc2Uge1xuICAgIC8vIGNyZWF0ZSBuZXcgbWFya2VyXG4gICAgY29uc3QgcG0gPSBuZXcgQXJyYXlTZWFyY2hNYXJrZXIocCwgaW5kZXgpXG4gICAgc2VhcmNoTWFya2VyLnB1c2gocG0pXG4gICAgcmV0dXJuIHBtXG4gIH1cbn1cblxuLyoqXG4gKiBTZWFyY2ggbWFya2VyIGhlbHAgdXMgdG8gZmluZCBwb3NpdGlvbnMgaW4gdGhlIGFzc29jaWF0aXZlIGFycmF5IGZhc3Rlci5cbiAqXG4gKiBUaGV5IHNwZWVkIHVwIHRoZSBwcm9jZXNzIG9mIGZpbmRpbmcgYSBwb3NpdGlvbiB3aXRob3V0IG11Y2ggYm9va2tlZXBpbmcuXG4gKlxuICogQSBtYXhpbXVtIG9mIGBtYXhTZWFyY2hNYXJrZXJgIG9iamVjdHMgYXJlIGNyZWF0ZWQuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBhbHdheXMgcmV0dXJucyBhIHJlZnJlc2hlZCBtYXJrZXIgKHVwZGF0ZWQgdGltZXN0YW1wKVxuICpcbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHlhcnJheVxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG4gKi9cbmV4cG9ydCBjb25zdCBmaW5kTWFya2VyID0gKHlhcnJheSwgaW5kZXgpID0+IHtcbiAgaWYgKHlhcnJheS5fc3RhcnQgPT09IG51bGwgfHwgaW5kZXggPT09IDAgfHwgeWFycmF5Ll9zZWFyY2hNYXJrZXIgPT09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG4gIGNvbnN0IG1hcmtlciA9IHlhcnJheS5fc2VhcmNoTWFya2VyLmxlbmd0aCA9PT0gMCA/IG51bGwgOiB5YXJyYXkuX3NlYXJjaE1hcmtlci5yZWR1Y2UoKGEsIGIpID0+IG1hdGguYWJzKGluZGV4IC0gYS5pbmRleCkgPCBtYXRoLmFicyhpbmRleCAtIGIuaW5kZXgpID8gYSA6IGIpXG4gIGxldCBwID0geWFycmF5Ll9zdGFydFxuICBsZXQgcGluZGV4ID0gMFxuICBpZiAobWFya2VyICE9PSBudWxsKSB7XG4gICAgcCA9IG1hcmtlci5wXG4gICAgcGluZGV4ID0gbWFya2VyLmluZGV4XG4gICAgcmVmcmVzaE1hcmtlclRpbWVzdGFtcChtYXJrZXIpIC8vIHdlIHVzZWQgaXQsIHdlIG1pZ2h0IG5lZWQgdG8gdXNlIGl0IGFnYWluXG4gIH1cbiAgLy8gaXRlcmF0ZSB0byByaWdodCBpZiBwb3NzaWJsZVxuICB3aGlsZSAocC5yaWdodCAhPT0gbnVsbCAmJiBwaW5kZXggPCBpbmRleCkge1xuICAgIGlmICghcC5kZWxldGVkICYmIHAuY291bnRhYmxlKSB7XG4gICAgICBpZiAoaW5kZXggPCBwaW5kZXggKyBwLmxlbmd0aCkge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgcGluZGV4ICs9IHAubGVuZ3RoXG4gICAgfVxuICAgIHAgPSBwLnJpZ2h0XG4gIH1cbiAgLy8gaXRlcmF0ZSB0byBsZWZ0IGlmIG5lY2Vzc2FyeSAobWlnaHQgYmUgdGhhdCBwaW5kZXggPiBpbmRleClcbiAgd2hpbGUgKHAubGVmdCAhPT0gbnVsbCAmJiBwaW5kZXggPiBpbmRleCkge1xuICAgIHAgPSBwLmxlZnRcbiAgICBpZiAoIXAuZGVsZXRlZCAmJiBwLmNvdW50YWJsZSkge1xuICAgICAgcGluZGV4IC09IHAubGVuZ3RoXG4gICAgfVxuICB9XG4gIC8vIHdlIHdhbnQgdG8gbWFrZSBzdXJlIHRoYXQgcCBjYW4ndCBiZSBtZXJnZWQgd2l0aCBsZWZ0LCBiZWNhdXNlIHRoYXQgd291bGQgc2NyZXcgdXAgZXZlcnl0aGluZ1xuICAvLyBpbiB0aGF0IGNhcyBqdXN0IHJldHVybiB3aGF0IHdlIGhhdmUgKGl0IGlzIG1vc3QgbGlrZWx5IHRoZSBiZXN0IG1hcmtlciBhbnl3YXkpXG4gIC8vIGl0ZXJhdGUgdG8gbGVmdCB1bnRpbCBwIGNhbid0IGJlIG1lcmdlZCB3aXRoIGxlZnRcbiAgd2hpbGUgKHAubGVmdCAhPT0gbnVsbCAmJiBwLmxlZnQuaWQuY2xpZW50ID09PSBwLmlkLmNsaWVudCAmJiBwLmxlZnQuaWQuY2xvY2sgKyBwLmxlZnQubGVuZ3RoID09PSBwLmlkLmNsb2NrKSB7XG4gICAgcCA9IHAubGVmdFxuICAgIGlmICghcC5kZWxldGVkICYmIHAuY291bnRhYmxlKSB7XG4gICAgICBwaW5kZXggLT0gcC5sZW5ndGhcbiAgICB9XG4gIH1cblxuICAvLyBAdG9kbyByZW1vdmUhXG4gIC8vIGFzc3VyZSBwb3NpdGlvblxuICAvLyB7XG4gIC8vICAgbGV0IHN0YXJ0ID0geWFycmF5Ll9zdGFydFxuICAvLyAgIGxldCBwb3MgPSAwXG4gIC8vICAgd2hpbGUgKHN0YXJ0ICE9PSBwKSB7XG4gIC8vICAgICBpZiAoIXN0YXJ0LmRlbGV0ZWQgJiYgc3RhcnQuY291bnRhYmxlKSB7XG4gIC8vICAgICAgIHBvcyArPSBzdGFydC5sZW5ndGhcbiAgLy8gICAgIH1cbiAgLy8gICAgIHN0YXJ0ID0gLyoqIEB0eXBlIHtJdGVtfSAqLyAoc3RhcnQucmlnaHQpXG4gIC8vICAgfVxuICAvLyAgIGlmIChwb3MgIT09IHBpbmRleCkge1xuICAvLyAgICAgZGVidWdnZXJcbiAgLy8gICAgIHRocm93IG5ldyBFcnJvcignR290Y2hhIHBvc2l0aW9uIGZhaWwhJylcbiAgLy8gICB9XG4gIC8vIH1cbiAgLy8gaWYgKG1hcmtlcikge1xuICAvLyAgIGlmICh3aW5kb3cubGVuZ3RocyA9PSBudWxsKSB7XG4gIC8vICAgICB3aW5kb3cubGVuZ3RocyA9IFtdXG4gIC8vICAgICB3aW5kb3cuZ2V0TGVuZ3RocyA9ICgpID0+IHdpbmRvdy5sZW5ndGhzLnNvcnQoKGEsIGIpID0+IGEgLSBiKVxuICAvLyAgIH1cbiAgLy8gICB3aW5kb3cubGVuZ3Rocy5wdXNoKG1hcmtlci5pbmRleCAtIHBpbmRleClcbiAgLy8gICBjb25zb2xlLmxvZygnZGlzdGFuY2UnLCBtYXJrZXIuaW5kZXggLSBwaW5kZXgsICdsZW4nLCBwICYmIHAucGFyZW50Lmxlbmd0aClcbiAgLy8gfVxuICBpZiAobWFya2VyICE9PSBudWxsICYmIG1hdGguYWJzKG1hcmtlci5pbmRleCAtIHBpbmRleCkgPCAvKiogQHR5cGUge1lUZXh0fFlBcnJheTxhbnk+fSAqLyAocC5wYXJlbnQpLmxlbmd0aCAvIG1heFNlYXJjaE1hcmtlcikge1xuICAgIC8vIGFkanVzdCBleGlzdGluZyBtYXJrZXJcbiAgICBvdmVyd3JpdGVNYXJrZXIobWFya2VyLCBwLCBwaW5kZXgpXG4gICAgcmV0dXJuIG1hcmtlclxuICB9IGVsc2Uge1xuICAgIC8vIGNyZWF0ZSBuZXcgbWFya2VyXG4gICAgcmV0dXJuIG1hcmtQb3NpdGlvbih5YXJyYXkuX3NlYXJjaE1hcmtlciwgcCwgcGluZGV4KVxuICB9XG59XG5cbi8qKlxuICogVXBkYXRlIG1hcmtlcnMgd2hlbiBhIGNoYW5nZSBoYXBwZW5lZC5cbiAqXG4gKiBUaGlzIHNob3VsZCBiZSBjYWxsZWQgYmVmb3JlIGRvaW5nIGEgZGVsZXRpb24hXG4gKlxuICogQHBhcmFtIHtBcnJheTxBcnJheVNlYXJjaE1hcmtlcj59IHNlYXJjaE1hcmtlclxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG4gKiBAcGFyYW0ge251bWJlcn0gbGVuIElmIGluc2VydGlvbiwgbGVuIGlzIHBvc2l0aXZlLiBJZiBkZWxldGlvbiwgbGVuIGlzIG5lZ2F0aXZlLlxuICovXG5leHBvcnQgY29uc3QgdXBkYXRlTWFya2VyQ2hhbmdlcyA9IChzZWFyY2hNYXJrZXIsIGluZGV4LCBsZW4pID0+IHtcbiAgZm9yIChsZXQgaSA9IHNlYXJjaE1hcmtlci5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgIGNvbnN0IG0gPSBzZWFyY2hNYXJrZXJbaV1cbiAgICBpZiAobGVuID4gMCkge1xuICAgICAgLyoqXG4gICAgICAgKiBAdHlwZSB7SXRlbXxudWxsfVxuICAgICAgICovXG4gICAgICBsZXQgcCA9IG0ucFxuICAgICAgcC5tYXJrZXIgPSBmYWxzZVxuICAgICAgLy8gSWRlYWxseSB3ZSBqdXN0IHdhbnQgdG8gZG8gYSBzaW1wbGUgcG9zaXRpb24gY29tcGFyaXNvbiwgYnV0IHRoaXMgd2lsbCBvbmx5IHdvcmsgaWZcbiAgICAgIC8vIHNlYXJjaCBtYXJrZXJzIGRvbid0IHBvaW50IHRvIGRlbGV0ZWQgaXRlbXMgZm9yIGZvcm1hdHMuXG4gICAgICAvLyBJdGVyYXRlIG1hcmtlciB0byBwcmV2IHVuZGVsZXRlZCBjb3VudGFibGUgcG9zaXRpb24gc28gd2Uga25vdyB3aGF0IHRvIGRvIHdoZW4gdXBkYXRpbmcgYSBwb3NpdGlvblxuICAgICAgd2hpbGUgKHAgJiYgKHAuZGVsZXRlZCB8fCAhcC5jb3VudGFibGUpKSB7XG4gICAgICAgIHAgPSBwLmxlZnRcbiAgICAgICAgaWYgKHAgJiYgIXAuZGVsZXRlZCAmJiBwLmNvdW50YWJsZSkge1xuICAgICAgICAgIC8vIGFkanVzdCBwb3NpdGlvbi4gdGhlIGxvb3Agc2hvdWxkIGJyZWFrIG5vd1xuICAgICAgICAgIG0uaW5kZXggLT0gcC5sZW5ndGhcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHAgPT09IG51bGwgfHwgcC5tYXJrZXIgPT09IHRydWUpIHtcbiAgICAgICAgLy8gcmVtb3ZlIHNlYXJjaCBtYXJrZXIgaWYgdXBkYXRlZCBwb3NpdGlvbiBpcyBudWxsIG9yIGlmIHBvc2l0aW9uIGlzIGFscmVhZHkgbWFya2VkXG4gICAgICAgIHNlYXJjaE1hcmtlci5zcGxpY2UoaSwgMSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIG0ucCA9IHBcbiAgICAgIHAubWFya2VyID0gdHJ1ZVxuICAgIH1cbiAgICBpZiAoaW5kZXggPCBtLmluZGV4IHx8IChsZW4gPiAwICYmIGluZGV4ID09PSBtLmluZGV4KSkgeyAvLyBhIHNpbXBsZSBpbmRleCA8PSBtLmluZGV4IGNoZWNrIHdvdWxkIGFjdHVhbGx5IHN1ZmZpY2VcbiAgICAgIG0uaW5kZXggPSBtYXRoLm1heChpbmRleCwgbS5pbmRleCArIGxlbilcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBBY2N1bXVsYXRlIGFsbCAobGlzdCkgY2hpbGRyZW4gb2YgYSB0eXBlIGFuZCByZXR1cm4gdGhlbSBhcyBhbiBBcnJheS5cbiAqXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSB0XG4gKiBAcmV0dXJuIHtBcnJheTxJdGVtPn1cbiAqL1xuZXhwb3J0IGNvbnN0IGdldFR5cGVDaGlsZHJlbiA9IHQgPT4ge1xuICB0LmRvYyA/PyB3YXJuUHJlbWF0dXJlQWNjZXNzKClcbiAgbGV0IHMgPSB0Ll9zdGFydFxuICBjb25zdCBhcnIgPSBbXVxuICB3aGlsZSAocykge1xuICAgIGFyci5wdXNoKHMpXG4gICAgcyA9IHMucmlnaHRcbiAgfVxuICByZXR1cm4gYXJyXG59XG5cbi8qKlxuICogQ2FsbCBldmVudCBsaXN0ZW5lcnMgd2l0aCBhbiBldmVudC4gVGhpcyB3aWxsIGFsc28gYWRkIGFuIGV2ZW50IHRvIGFsbFxuICogcGFyZW50cyAoZm9yIGAub2JzZXJ2ZURlZXBgIGhhbmRsZXJzKS5cbiAqXG4gKiBAdGVtcGxhdGUgRXZlbnRUeXBlXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxFdmVudFR5cGU+fSB0eXBlXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtFdmVudFR5cGV9IGV2ZW50XG4gKi9cbmV4cG9ydCBjb25zdCBjYWxsVHlwZU9ic2VydmVycyA9ICh0eXBlLCB0cmFuc2FjdGlvbiwgZXZlbnQpID0+IHtcbiAgY29uc3QgY2hhbmdlZFR5cGUgPSB0eXBlXG4gIGNvbnN0IGNoYW5nZWRQYXJlbnRUeXBlcyA9IHRyYW5zYWN0aW9uLmNoYW5nZWRQYXJlbnRUeXBlc1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBtYXAuc2V0SWZVbmRlZmluZWQoY2hhbmdlZFBhcmVudFR5cGVzLCB0eXBlLCAoKSA9PiBbXSkucHVzaChldmVudClcbiAgICBpZiAodHlwZS5faXRlbSA9PT0gbnVsbCkge1xuICAgICAgYnJlYWtcbiAgICB9XG4gICAgdHlwZSA9IC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovICh0eXBlLl9pdGVtLnBhcmVudClcbiAgfVxuICBjYWxsRXZlbnRIYW5kbGVyTGlzdGVuZXJzKGNoYW5nZWRUeXBlLl9lSCwgZXZlbnQsIHRyYW5zYWN0aW9uKVxufVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBFdmVudFR5cGVcbiAqIEFic3RyYWN0IFlqcyBUeXBlIGNsYXNzXG4gKi9cbmV4cG9ydCBjbGFzcyBBYnN0cmFjdFR5cGUge1xuICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0l0ZW18bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLl9pdGVtID0gbnVsbFxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtNYXA8c3RyaW5nLEl0ZW0+fVxuICAgICAqL1xuICAgIHRoaXMuX21hcCA9IG5ldyBNYXAoKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtJdGVtfG51bGx9XG4gICAgICovXG4gICAgdGhpcy5fc3RhcnQgPSBudWxsXG4gICAgLyoqXG4gICAgICogQHR5cGUge0RvY3xudWxsfVxuICAgICAqL1xuICAgIHRoaXMuZG9jID0gbnVsbFxuICAgIHRoaXMuX2xlbmd0aCA9IDBcbiAgICAvKipcbiAgICAgKiBFdmVudCBoYW5kbGVyc1xuICAgICAqIEB0eXBlIHtFdmVudEhhbmRsZXI8RXZlbnRUeXBlLFRyYW5zYWN0aW9uPn1cbiAgICAgKi9cbiAgICB0aGlzLl9lSCA9IGNyZWF0ZUV2ZW50SGFuZGxlcigpXG4gICAgLyoqXG4gICAgICogRGVlcCBldmVudCBoYW5kbGVyc1xuICAgICAqIEB0eXBlIHtFdmVudEhhbmRsZXI8QXJyYXk8WUV2ZW50PGFueT4+LFRyYW5zYWN0aW9uPn1cbiAgICAgKi9cbiAgICB0aGlzLl9kRUggPSBjcmVhdGVFdmVudEhhbmRsZXIoKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudWxsIHwgQXJyYXk8QXJyYXlTZWFyY2hNYXJrZXI+fVxuICAgICAqL1xuICAgIHRoaXMuX3NlYXJjaE1hcmtlciA9IG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBYnN0cmFjdFR5cGU8YW55PnxudWxsfVxuICAgKi9cbiAgZ2V0IHBhcmVudCAoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2l0ZW0gPyAvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAodGhpcy5faXRlbS5wYXJlbnQpIDogbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEludGVncmF0ZSB0aGlzIHR5cGUgaW50byB0aGUgWWpzIGluc3RhbmNlLlxuICAgKlxuICAgKiAqIFNhdmUgdGhpcyBzdHJ1Y3QgaW4gdGhlIG9zXG4gICAqICogVGhpcyB0eXBlIGlzIHNlbnQgdG8gb3RoZXIgY2xpZW50XG4gICAqICogT2JzZXJ2ZXIgZnVuY3Rpb25zIGFyZSBmaXJlZFxuICAgKlxuICAgKiBAcGFyYW0ge0RvY30geSBUaGUgWWpzIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7SXRlbXxudWxsfSBpdGVtXG4gICAqL1xuICBfaW50ZWdyYXRlICh5LCBpdGVtKSB7XG4gICAgdGhpcy5kb2MgPSB5XG4gICAgdGhpcy5faXRlbSA9IGl0ZW1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBYnN0cmFjdFR5cGU8RXZlbnRUeXBlPn1cbiAgICovXG4gIF9jb3B5ICgpIHtcbiAgICB0aHJvdyBlcnJvci5tZXRob2RVbmltcGxlbWVudGVkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWtlcyBhIGNvcHkgb2YgdGhpcyBkYXRhIHR5cGUgdGhhdCBjYW4gYmUgaW5jbHVkZWQgc29tZXdoZXJlIGVsc2UuXG4gICAqXG4gICAqIE5vdGUgdGhhdCB0aGUgY29udGVudCBpcyBvbmx5IHJlYWRhYmxlIF9hZnRlcl8gaXQgaGFzIGJlZW4gaW5jbHVkZWQgc29tZXdoZXJlIGluIHRoZSBZZG9jLlxuICAgKlxuICAgKiBAcmV0dXJuIHtBYnN0cmFjdFR5cGU8RXZlbnRUeXBlPn1cbiAgICovXG4gIGNsb25lICgpIHtcbiAgICB0aHJvdyBlcnJvci5tZXRob2RVbmltcGxlbWVudGVkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1VwZGF0ZUVuY29kZXJWMSB8IFVwZGF0ZUVuY29kZXJWMn0gX2VuY29kZXJcbiAgICovXG4gIF93cml0ZSAoX2VuY29kZXIpIHsgfVxuXG4gIC8qKlxuICAgKiBUaGUgZmlyc3Qgbm9uLWRlbGV0ZWQgaXRlbVxuICAgKi9cbiAgZ2V0IF9maXJzdCAoKSB7XG4gICAgbGV0IG4gPSB0aGlzLl9zdGFydFxuICAgIHdoaWxlIChuICE9PSBudWxsICYmIG4uZGVsZXRlZCkge1xuICAgICAgbiA9IG4ucmlnaHRcbiAgICB9XG4gICAgcmV0dXJuIG5cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIFlFdmVudCBhbmQgY2FsbHMgYWxsIHR5cGUgb2JzZXJ2ZXJzLlxuICAgKiBNdXN0IGJlIGltcGxlbWVudGVkIGJ5IGVhY2ggdHlwZS5cbiAgICpcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtTZXQ8bnVsbHxzdHJpbmc+fSBfcGFyZW50U3VicyBLZXlzIGNoYW5nZWQgb24gdGhpcyB0eXBlLiBgbnVsbGAgaWYgbGlzdCB3YXMgbW9kaWZpZWQuXG4gICAqL1xuICBfY2FsbE9ic2VydmVyICh0cmFuc2FjdGlvbiwgX3BhcmVudFN1YnMpIHtcbiAgICBpZiAoIXRyYW5zYWN0aW9uLmxvY2FsICYmIHRoaXMuX3NlYXJjaE1hcmtlcikge1xuICAgICAgdGhpcy5fc2VhcmNoTWFya2VyLmxlbmd0aCA9IDBcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogT2JzZXJ2ZSBhbGwgZXZlbnRzIHRoYXQgYXJlIGNyZWF0ZWQgb24gdGhpcyB0eXBlLlxuICAgKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKEV2ZW50VHlwZSwgVHJhbnNhY3Rpb24pOnZvaWR9IGYgT2JzZXJ2ZXIgZnVuY3Rpb25cbiAgICovXG4gIG9ic2VydmUgKGYpIHtcbiAgICBhZGRFdmVudEhhbmRsZXJMaXN0ZW5lcih0aGlzLl9lSCwgZilcbiAgfVxuXG4gIC8qKlxuICAgKiBPYnNlcnZlIGFsbCBldmVudHMgdGhhdCBhcmUgY3JlYXRlZCBieSB0aGlzIHR5cGUgYW5kIGl0cyBjaGlsZHJlbi5cbiAgICpcbiAgICogQHBhcmFtIHtmdW5jdGlvbihBcnJheTxZRXZlbnQ8YW55Pj4sVHJhbnNhY3Rpb24pOnZvaWR9IGYgT2JzZXJ2ZXIgZnVuY3Rpb25cbiAgICovXG4gIG9ic2VydmVEZWVwIChmKSB7XG4gICAgYWRkRXZlbnRIYW5kbGVyTGlzdGVuZXIodGhpcy5fZEVILCBmKVxuICB9XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXIgYW4gb2JzZXJ2ZXIgZnVuY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oRXZlbnRUeXBlLFRyYW5zYWN0aW9uKTp2b2lkfSBmIE9ic2VydmVyIGZ1bmN0aW9uXG4gICAqL1xuICB1bm9ic2VydmUgKGYpIHtcbiAgICByZW1vdmVFdmVudEhhbmRsZXJMaXN0ZW5lcih0aGlzLl9lSCwgZilcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVyIGFuIG9ic2VydmVyIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKEFycmF5PFlFdmVudDxhbnk+PixUcmFuc2FjdGlvbik6dm9pZH0gZiBPYnNlcnZlciBmdW5jdGlvblxuICAgKi9cbiAgdW5vYnNlcnZlRGVlcCAoZikge1xuICAgIHJlbW92ZUV2ZW50SGFuZGxlckxpc3RlbmVyKHRoaXMuX2RFSCwgZilcbiAgfVxuXG4gIC8qKlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHJldHVybiB7YW55fVxuICAgKi9cbiAgdG9KU09OICgpIHt9XG59XG5cbi8qKlxuICogQHBhcmFtIHtBYnN0cmFjdFR5cGU8YW55Pn0gdHlwZVxuICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0XG4gKiBAcGFyYW0ge251bWJlcn0gZW5kXG4gKiBAcmV0dXJuIHtBcnJheTxhbnk+fVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHR5cGVMaXN0U2xpY2UgPSAodHlwZSwgc3RhcnQsIGVuZCkgPT4ge1xuICB0eXBlLmRvYyA/PyB3YXJuUHJlbWF0dXJlQWNjZXNzKClcbiAgaWYgKHN0YXJ0IDwgMCkge1xuICAgIHN0YXJ0ID0gdHlwZS5fbGVuZ3RoICsgc3RhcnRcbiAgfVxuICBpZiAoZW5kIDwgMCkge1xuICAgIGVuZCA9IHR5cGUuX2xlbmd0aCArIGVuZFxuICB9XG4gIGxldCBsZW4gPSBlbmQgLSBzdGFydFxuICBjb25zdCBjcyA9IFtdXG4gIGxldCBuID0gdHlwZS5fc3RhcnRcbiAgd2hpbGUgKG4gIT09IG51bGwgJiYgbGVuID4gMCkge1xuICAgIGlmIChuLmNvdW50YWJsZSAmJiAhbi5kZWxldGVkKSB7XG4gICAgICBjb25zdCBjID0gbi5jb250ZW50LmdldENvbnRlbnQoKVxuICAgICAgaWYgKGMubGVuZ3RoIDw9IHN0YXJ0KSB7XG4gICAgICAgIHN0YXJ0IC09IGMubGVuZ3RoXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBjLmxlbmd0aCAmJiBsZW4gPiAwOyBpKyspIHtcbiAgICAgICAgICBjcy5wdXNoKGNbaV0pXG4gICAgICAgICAgbGVuLS1cbiAgICAgICAgfVxuICAgICAgICBzdGFydCA9IDBcbiAgICAgIH1cbiAgICB9XG4gICAgbiA9IG4ucmlnaHRcbiAgfVxuICByZXR1cm4gY3Ncbn1cblxuLyoqXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSB0eXBlXG4gKiBAcmV0dXJuIHtBcnJheTxhbnk+fVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHR5cGVMaXN0VG9BcnJheSA9IHR5cGUgPT4ge1xuICB0eXBlLmRvYyA/PyB3YXJuUHJlbWF0dXJlQWNjZXNzKClcbiAgY29uc3QgY3MgPSBbXVxuICBsZXQgbiA9IHR5cGUuX3N0YXJ0XG4gIHdoaWxlIChuICE9PSBudWxsKSB7XG4gICAgaWYgKG4uY291bnRhYmxlICYmICFuLmRlbGV0ZWQpIHtcbiAgICAgIGNvbnN0IGMgPSBuLmNvbnRlbnQuZ2V0Q29udGVudCgpXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY3MucHVzaChjW2ldKVxuICAgICAgfVxuICAgIH1cbiAgICBuID0gbi5yaWdodFxuICB9XG4gIHJldHVybiBjc1xufVxuXG4vKipcbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHR5cGVcbiAqIEBwYXJhbSB7U25hcHNob3R9IHNuYXBzaG90XG4gKiBAcmV0dXJuIHtBcnJheTxhbnk+fVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHR5cGVMaXN0VG9BcnJheVNuYXBzaG90ID0gKHR5cGUsIHNuYXBzaG90KSA9PiB7XG4gIGNvbnN0IGNzID0gW11cbiAgbGV0IG4gPSB0eXBlLl9zdGFydFxuICB3aGlsZSAobiAhPT0gbnVsbCkge1xuICAgIGlmIChuLmNvdW50YWJsZSAmJiBpc1Zpc2libGUobiwgc25hcHNob3QpKSB7XG4gICAgICBjb25zdCBjID0gbi5jb250ZW50LmdldENvbnRlbnQoKVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNzLnB1c2goY1tpXSlcbiAgICAgIH1cbiAgICB9XG4gICAgbiA9IG4ucmlnaHRcbiAgfVxuICByZXR1cm4gY3Ncbn1cblxuLyoqXG4gKiBFeGVjdXRlcyBhIHByb3ZpZGVkIGZ1bmN0aW9uIG9uIG9uY2Ugb24gZXZlcnkgZWxlbWVudCBvZiB0aGlzIFlBcnJheS5cbiAqXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSB0eXBlXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKGFueSxudW1iZXIsYW55KTp2b2lkfSBmIEEgZnVuY3Rpb24gdG8gZXhlY3V0ZSBvbiBldmVyeSBlbGVtZW50IG9mIHRoaXMgWUFycmF5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHR5cGVMaXN0Rm9yRWFjaCA9ICh0eXBlLCBmKSA9PiB7XG4gIGxldCBpbmRleCA9IDBcbiAgbGV0IG4gPSB0eXBlLl9zdGFydFxuICB0eXBlLmRvYyA/PyB3YXJuUHJlbWF0dXJlQWNjZXNzKClcbiAgd2hpbGUgKG4gIT09IG51bGwpIHtcbiAgICBpZiAobi5jb3VudGFibGUgJiYgIW4uZGVsZXRlZCkge1xuICAgICAgY29uc3QgYyA9IG4uY29udGVudC5nZXRDb250ZW50KClcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYy5sZW5ndGg7IGkrKykge1xuICAgICAgICBmKGNbaV0sIGluZGV4KyssIHR5cGUpXG4gICAgICB9XG4gICAgfVxuICAgIG4gPSBuLnJpZ2h0XG4gIH1cbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgQyxSXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSB0eXBlXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKEMsbnVtYmVyLEFic3RyYWN0VHlwZTxhbnk+KTpSfSBmXG4gKiBAcmV0dXJuIHtBcnJheTxSPn1cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCB0eXBlTGlzdE1hcCA9ICh0eXBlLCBmKSA9PiB7XG4gIC8qKlxuICAgKiBAdHlwZSB7QXJyYXk8YW55Pn1cbiAgICovXG4gIGNvbnN0IHJlc3VsdCA9IFtdXG4gIHR5cGVMaXN0Rm9yRWFjaCh0eXBlLCAoYywgaSkgPT4ge1xuICAgIHJlc3VsdC5wdXNoKGYoYywgaSwgdHlwZSkpXG4gIH0pXG4gIHJldHVybiByZXN1bHRcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSB0eXBlXG4gKiBAcmV0dXJuIHtJdGVyYWJsZUl0ZXJhdG9yPGFueT59XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgdHlwZUxpc3RDcmVhdGVJdGVyYXRvciA9IHR5cGUgPT4ge1xuICBsZXQgbiA9IHR5cGUuX3N0YXJ0XG4gIC8qKlxuICAgKiBAdHlwZSB7QXJyYXk8YW55PnxudWxsfVxuICAgKi9cbiAgbGV0IGN1cnJlbnRDb250ZW50ID0gbnVsbFxuICBsZXQgY3VycmVudENvbnRlbnRJbmRleCA9IDBcbiAgcmV0dXJuIHtcbiAgICBbU3ltYm9sLml0ZXJhdG9yXSAoKSB7XG4gICAgICByZXR1cm4gdGhpc1xuICAgIH0sXG4gICAgbmV4dDogKCkgPT4ge1xuICAgICAgLy8gZmluZCBzb21lIGNvbnRlbnRcbiAgICAgIGlmIChjdXJyZW50Q29udGVudCA9PT0gbnVsbCkge1xuICAgICAgICB3aGlsZSAobiAhPT0gbnVsbCAmJiBuLmRlbGV0ZWQpIHtcbiAgICAgICAgICBuID0gbi5yaWdodFxuICAgICAgICB9XG4gICAgICAgIC8vIGNoZWNrIGlmIHdlIHJlYWNoZWQgdGhlIGVuZCwgbm8gbmVlZCB0byBjaGVjayBjdXJyZW50Q29udGVudCwgYmVjYXVzZSBpdCBkb2VzIG5vdCBleGlzdFxuICAgICAgICBpZiAobiA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkb25lOiB0cnVlLFxuICAgICAgICAgICAgdmFsdWU6IHVuZGVmaW5lZFxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyB3ZSBmb3VuZCBuLCBzbyB3ZSBjYW4gc2V0IGN1cnJlbnRDb250ZW50XG4gICAgICAgIGN1cnJlbnRDb250ZW50ID0gbi5jb250ZW50LmdldENvbnRlbnQoKVxuICAgICAgICBjdXJyZW50Q29udGVudEluZGV4ID0gMFxuICAgICAgICBuID0gbi5yaWdodCAvLyB3ZSB1c2VkIHRoZSBjb250ZW50IG9mIG4sIG5vdyBpdGVyYXRlIHRvIG5leHRcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZhbHVlID0gY3VycmVudENvbnRlbnRbY3VycmVudENvbnRlbnRJbmRleCsrXVxuICAgICAgLy8gY2hlY2sgaWYgd2UgbmVlZCB0byBlbXB0eSBjdXJyZW50Q29udGVudFxuICAgICAgaWYgKGN1cnJlbnRDb250ZW50Lmxlbmd0aCA8PSBjdXJyZW50Q29udGVudEluZGV4KSB7XG4gICAgICAgIGN1cnJlbnRDb250ZW50ID0gbnVsbFxuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZG9uZTogZmFsc2UsXG4gICAgICAgIHZhbHVlXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogRXhlY3V0ZXMgYSBwcm92aWRlZCBmdW5jdGlvbiBvbiBvbmNlIG9uIGV2ZXJ5IGVsZW1lbnQgb2YgdGhpcyBZQXJyYXkuXG4gKiBPcGVyYXRlcyBvbiBhIHNuYXBzaG90dGVkIHN0YXRlIG9mIHRoZSBkb2N1bWVudC5cbiAqXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSB0eXBlXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKGFueSxudW1iZXIsQWJzdHJhY3RUeXBlPGFueT4pOnZvaWR9IGYgQSBmdW5jdGlvbiB0byBleGVjdXRlIG9uIGV2ZXJ5IGVsZW1lbnQgb2YgdGhpcyBZQXJyYXkuXG4gKiBAcGFyYW0ge1NuYXBzaG90fSBzbmFwc2hvdFxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHR5cGVMaXN0Rm9yRWFjaFNuYXBzaG90ID0gKHR5cGUsIGYsIHNuYXBzaG90KSA9PiB7XG4gIGxldCBpbmRleCA9IDBcbiAgbGV0IG4gPSB0eXBlLl9zdGFydFxuICB3aGlsZSAobiAhPT0gbnVsbCkge1xuICAgIGlmIChuLmNvdW50YWJsZSAmJiBpc1Zpc2libGUobiwgc25hcHNob3QpKSB7XG4gICAgICBjb25zdCBjID0gbi5jb250ZW50LmdldENvbnRlbnQoKVxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGYoY1tpXSwgaW5kZXgrKywgdHlwZSlcbiAgICAgIH1cbiAgICB9XG4gICAgbiA9IG4ucmlnaHRcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHR5cGVcbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuICogQHJldHVybiB7YW55fVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHR5cGVMaXN0R2V0ID0gKHR5cGUsIGluZGV4KSA9PiB7XG4gIHR5cGUuZG9jID8/IHdhcm5QcmVtYXR1cmVBY2Nlc3MoKVxuICBjb25zdCBtYXJrZXIgPSBmaW5kTWFya2VyKHR5cGUsIGluZGV4KVxuICBsZXQgbiA9IHR5cGUuX3N0YXJ0XG4gIGlmIChtYXJrZXIgIT09IG51bGwpIHtcbiAgICBuID0gbWFya2VyLnBcbiAgICBpbmRleCAtPSBtYXJrZXIuaW5kZXhcbiAgfVxuICBmb3IgKDsgbiAhPT0gbnVsbDsgbiA9IG4ucmlnaHQpIHtcbiAgICBpZiAoIW4uZGVsZXRlZCAmJiBuLmNvdW50YWJsZSkge1xuICAgICAgaWYgKGluZGV4IDwgbi5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIG4uY29udGVudC5nZXRDb250ZW50KClbaW5kZXhdXG4gICAgICB9XG4gICAgICBpbmRleCAtPSBuLmxlbmd0aFxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSBwYXJlbnRcbiAqIEBwYXJhbSB7SXRlbT99IHJlZmVyZW5jZUl0ZW1cbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0PHN0cmluZyxhbnk+fEFycmF5PGFueT58Ym9vbGVhbnxudW1iZXJ8bnVsbHxzdHJpbmd8VWludDhBcnJheT59IGNvbnRlbnRcbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCB0eXBlTGlzdEluc2VydEdlbmVyaWNzQWZ0ZXIgPSAodHJhbnNhY3Rpb24sIHBhcmVudCwgcmVmZXJlbmNlSXRlbSwgY29udGVudCkgPT4ge1xuICBsZXQgbGVmdCA9IHJlZmVyZW5jZUl0ZW1cbiAgY29uc3QgZG9jID0gdHJhbnNhY3Rpb24uZG9jXG4gIGNvbnN0IG93bkNsaWVudElkID0gZG9jLmNsaWVudElEXG4gIGNvbnN0IHN0b3JlID0gZG9jLnN0b3JlXG4gIGNvbnN0IHJpZ2h0ID0gcmVmZXJlbmNlSXRlbSA9PT0gbnVsbCA/IHBhcmVudC5fc3RhcnQgOiByZWZlcmVuY2VJdGVtLnJpZ2h0XG4gIC8qKlxuICAgKiBAdHlwZSB7QXJyYXk8T2JqZWN0fEFycmF5PGFueT58bnVtYmVyfG51bGw+fVxuICAgKi9cbiAgbGV0IGpzb25Db250ZW50ID0gW11cbiAgY29uc3QgcGFja0pzb25Db250ZW50ID0gKCkgPT4ge1xuICAgIGlmIChqc29uQ29udGVudC5sZW5ndGggPiAwKSB7XG4gICAgICBsZWZ0ID0gbmV3IEl0ZW0oY3JlYXRlSUQob3duQ2xpZW50SWQsIGdldFN0YXRlKHN0b3JlLCBvd25DbGllbnRJZCkpLCBsZWZ0LCBsZWZ0ICYmIGxlZnQubGFzdElkLCByaWdodCwgcmlnaHQgJiYgcmlnaHQuaWQsIHBhcmVudCwgbnVsbCwgbmV3IENvbnRlbnRBbnkoanNvbkNvbnRlbnQpKVxuICAgICAgbGVmdC5pbnRlZ3JhdGUodHJhbnNhY3Rpb24sIDApXG4gICAgICBqc29uQ29udGVudCA9IFtdXG4gICAgfVxuICB9XG4gIGNvbnRlbnQuZm9yRWFjaChjID0+IHtcbiAgICBpZiAoYyA9PT0gbnVsbCkge1xuICAgICAganNvbkNvbnRlbnQucHVzaChjKVxuICAgIH0gZWxzZSB7XG4gICAgICBzd2l0Y2ggKGMuY29uc3RydWN0b3IpIHtcbiAgICAgICAgY2FzZSBOdW1iZXI6XG4gICAgICAgIGNhc2UgT2JqZWN0OlxuICAgICAgICBjYXNlIEJvb2xlYW46XG4gICAgICAgIGNhc2UgQXJyYXk6XG4gICAgICAgIGNhc2UgU3RyaW5nOlxuICAgICAgICAgIGpzb25Db250ZW50LnB1c2goYylcbiAgICAgICAgICBicmVha1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHBhY2tKc29uQ29udGVudCgpXG4gICAgICAgICAgc3dpdGNoIChjLmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICBjYXNlIFVpbnQ4QXJyYXk6XG4gICAgICAgICAgICBjYXNlIEFycmF5QnVmZmVyOlxuICAgICAgICAgICAgICBsZWZ0ID0gbmV3IEl0ZW0oY3JlYXRlSUQob3duQ2xpZW50SWQsIGdldFN0YXRlKHN0b3JlLCBvd25DbGllbnRJZCkpLCBsZWZ0LCBsZWZ0ICYmIGxlZnQubGFzdElkLCByaWdodCwgcmlnaHQgJiYgcmlnaHQuaWQsIHBhcmVudCwgbnVsbCwgbmV3IENvbnRlbnRCaW5hcnkobmV3IFVpbnQ4QXJyYXkoLyoqIEB0eXBlIHtVaW50OEFycmF5fSAqLyAoYykpKSlcbiAgICAgICAgICAgICAgbGVmdC5pbnRlZ3JhdGUodHJhbnNhY3Rpb24sIDApXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICBjYXNlIERvYzpcbiAgICAgICAgICAgICAgbGVmdCA9IG5ldyBJdGVtKGNyZWF0ZUlEKG93bkNsaWVudElkLCBnZXRTdGF0ZShzdG9yZSwgb3duQ2xpZW50SWQpKSwgbGVmdCwgbGVmdCAmJiBsZWZ0Lmxhc3RJZCwgcmlnaHQsIHJpZ2h0ICYmIHJpZ2h0LmlkLCBwYXJlbnQsIG51bGwsIG5ldyBDb250ZW50RG9jKC8qKiBAdHlwZSB7RG9jfSAqLyAoYykpKVxuICAgICAgICAgICAgICBsZWZ0LmludGVncmF0ZSh0cmFuc2FjdGlvbiwgMClcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGlmIChjIGluc3RhbmNlb2YgQWJzdHJhY3RUeXBlKSB7XG4gICAgICAgICAgICAgICAgbGVmdCA9IG5ldyBJdGVtKGNyZWF0ZUlEKG93bkNsaWVudElkLCBnZXRTdGF0ZShzdG9yZSwgb3duQ2xpZW50SWQpKSwgbGVmdCwgbGVmdCAmJiBsZWZ0Lmxhc3RJZCwgcmlnaHQsIHJpZ2h0ICYmIHJpZ2h0LmlkLCBwYXJlbnQsIG51bGwsIG5ldyBDb250ZW50VHlwZShjKSlcbiAgICAgICAgICAgICAgICBsZWZ0LmludGVncmF0ZSh0cmFuc2FjdGlvbiwgMClcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuZXhwZWN0ZWQgY29udGVudCB0eXBlIGluIGluc2VydCBvcGVyYXRpb24nKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSlcbiAgcGFja0pzb25Db250ZW50KClcbn1cblxuY29uc3QgbGVuZ3RoRXhjZWVkZWQgPSAoKSA9PiBlcnJvci5jcmVhdGUoJ0xlbmd0aCBleGNlZWRlZCEnKVxuXG4vKipcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSBwYXJlbnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuICogQHBhcmFtIHtBcnJheTxPYmplY3Q8c3RyaW5nLGFueT58QXJyYXk8YW55PnxudW1iZXJ8bnVsbHxzdHJpbmd8VWludDhBcnJheT59IGNvbnRlbnRcbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCB0eXBlTGlzdEluc2VydEdlbmVyaWNzID0gKHRyYW5zYWN0aW9uLCBwYXJlbnQsIGluZGV4LCBjb250ZW50KSA9PiB7XG4gIGlmIChpbmRleCA+IHBhcmVudC5fbGVuZ3RoKSB7XG4gICAgdGhyb3cgbGVuZ3RoRXhjZWVkZWQoKVxuICB9XG4gIGlmIChpbmRleCA9PT0gMCkge1xuICAgIGlmIChwYXJlbnQuX3NlYXJjaE1hcmtlcikge1xuICAgICAgdXBkYXRlTWFya2VyQ2hhbmdlcyhwYXJlbnQuX3NlYXJjaE1hcmtlciwgaW5kZXgsIGNvbnRlbnQubGVuZ3RoKVxuICAgIH1cbiAgICByZXR1cm4gdHlwZUxpc3RJbnNlcnRHZW5lcmljc0FmdGVyKHRyYW5zYWN0aW9uLCBwYXJlbnQsIG51bGwsIGNvbnRlbnQpXG4gIH1cbiAgY29uc3Qgc3RhcnRJbmRleCA9IGluZGV4XG4gIGNvbnN0IG1hcmtlciA9IGZpbmRNYXJrZXIocGFyZW50LCBpbmRleClcbiAgbGV0IG4gPSBwYXJlbnQuX3N0YXJ0XG4gIGlmIChtYXJrZXIgIT09IG51bGwpIHtcbiAgICBuID0gbWFya2VyLnBcbiAgICBpbmRleCAtPSBtYXJrZXIuaW5kZXhcbiAgICAvLyB3ZSBuZWVkIHRvIGl0ZXJhdGUgb25lIHRvIHRoZSBsZWZ0IHNvIHRoYXQgdGhlIGFsZ29yaXRobSB3b3Jrc1xuICAgIGlmIChpbmRleCA9PT0gMCkge1xuICAgICAgLy8gQHRvZG8gcmVmYWN0b3IgdGhpcyBhcyBpdCBhY3R1YWxseSBkb2Vzbid0IGNvbnNpZGVyIGZvcm1hdHNcbiAgICAgIG4gPSBuLnByZXYgLy8gaW1wb3J0YW50ISBnZXQgdGhlIGxlZnQgdW5kZWxldGVkIGl0ZW0gc28gdGhhdCB3ZSBjYW4gYWN0dWFsbHkgZGVjcmVhc2UgaW5kZXhcbiAgICAgIGluZGV4ICs9IChuICYmIG4uY291bnRhYmxlICYmICFuLmRlbGV0ZWQpID8gbi5sZW5ndGggOiAwXG4gICAgfVxuICB9XG4gIGZvciAoOyBuICE9PSBudWxsOyBuID0gbi5yaWdodCkge1xuICAgIGlmICghbi5kZWxldGVkICYmIG4uY291bnRhYmxlKSB7XG4gICAgICBpZiAoaW5kZXggPD0gbi5sZW5ndGgpIHtcbiAgICAgICAgaWYgKGluZGV4IDwgbi5sZW5ndGgpIHtcbiAgICAgICAgICAvLyBpbnNlcnQgaW4tYmV0d2VlblxuICAgICAgICAgIGdldEl0ZW1DbGVhblN0YXJ0KHRyYW5zYWN0aW9uLCBjcmVhdGVJRChuLmlkLmNsaWVudCwgbi5pZC5jbG9jayArIGluZGV4KSlcbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgaW5kZXggLT0gbi5sZW5ndGhcbiAgICB9XG4gIH1cbiAgaWYgKHBhcmVudC5fc2VhcmNoTWFya2VyKSB7XG4gICAgdXBkYXRlTWFya2VyQ2hhbmdlcyhwYXJlbnQuX3NlYXJjaE1hcmtlciwgc3RhcnRJbmRleCwgY29udGVudC5sZW5ndGgpXG4gIH1cbiAgcmV0dXJuIHR5cGVMaXN0SW5zZXJ0R2VuZXJpY3NBZnRlcih0cmFuc2FjdGlvbiwgcGFyZW50LCBuLCBjb250ZW50KVxufVxuXG4vKipcbiAqIFB1c2hpbmcgY29udGVudCBpcyBzcGVjaWFsIGFzIHdlIGdlbmVyYWxseSB3YW50IHRvIHB1c2ggYWZ0ZXIgdGhlIGxhc3QgaXRlbS4gU28gd2UgZG9uJ3QgaGF2ZSB0byB1cGRhdGVcbiAqIHRoZSBzZWFyY2ggbWFya2VyLlxuICpcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSBwYXJlbnRcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0PHN0cmluZyxhbnk+fEFycmF5PGFueT58bnVtYmVyfG51bGx8c3RyaW5nfFVpbnQ4QXJyYXk+fSBjb250ZW50XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgdHlwZUxpc3RQdXNoR2VuZXJpY3MgPSAodHJhbnNhY3Rpb24sIHBhcmVudCwgY29udGVudCkgPT4ge1xuICAvLyBVc2UgdGhlIG1hcmtlciB3aXRoIHRoZSBoaWdoZXN0IGluZGV4IGFuZCBpdGVyYXRlIHRvIHRoZSByaWdodC5cbiAgY29uc3QgbWFya2VyID0gKHBhcmVudC5fc2VhcmNoTWFya2VyIHx8IFtdKS5yZWR1Y2UoKG1heE1hcmtlciwgY3Vyck1hcmtlcikgPT4gY3Vyck1hcmtlci5pbmRleCA+IG1heE1hcmtlci5pbmRleCA/IGN1cnJNYXJrZXIgOiBtYXhNYXJrZXIsIHsgaW5kZXg6IDAsIHA6IHBhcmVudC5fc3RhcnQgfSlcbiAgbGV0IG4gPSBtYXJrZXIucFxuICBpZiAobikge1xuICAgIHdoaWxlIChuLnJpZ2h0KSB7XG4gICAgICBuID0gbi5yaWdodFxuICAgIH1cbiAgfVxuICByZXR1cm4gdHlwZUxpc3RJbnNlcnRHZW5lcmljc0FmdGVyKHRyYW5zYWN0aW9uLCBwYXJlbnQsIG4sIGNvbnRlbnQpXG59XG5cbi8qKlxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHBhcmVudFxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG4gKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgdHlwZUxpc3REZWxldGUgPSAodHJhbnNhY3Rpb24sIHBhcmVudCwgaW5kZXgsIGxlbmd0aCkgPT4ge1xuICBpZiAobGVuZ3RoID09PSAwKSB7IHJldHVybiB9XG4gIGNvbnN0IHN0YXJ0SW5kZXggPSBpbmRleFxuICBjb25zdCBzdGFydExlbmd0aCA9IGxlbmd0aFxuICBjb25zdCBtYXJrZXIgPSBmaW5kTWFya2VyKHBhcmVudCwgaW5kZXgpXG4gIGxldCBuID0gcGFyZW50Ll9zdGFydFxuICBpZiAobWFya2VyICE9PSBudWxsKSB7XG4gICAgbiA9IG1hcmtlci5wXG4gICAgaW5kZXggLT0gbWFya2VyLmluZGV4XG4gIH1cbiAgLy8gY29tcHV0ZSB0aGUgZmlyc3QgaXRlbSB0byBiZSBkZWxldGVkXG4gIGZvciAoOyBuICE9PSBudWxsICYmIGluZGV4ID4gMDsgbiA9IG4ucmlnaHQpIHtcbiAgICBpZiAoIW4uZGVsZXRlZCAmJiBuLmNvdW50YWJsZSkge1xuICAgICAgaWYgKGluZGV4IDwgbi5sZW5ndGgpIHtcbiAgICAgICAgZ2V0SXRlbUNsZWFuU3RhcnQodHJhbnNhY3Rpb24sIGNyZWF0ZUlEKG4uaWQuY2xpZW50LCBuLmlkLmNsb2NrICsgaW5kZXgpKVxuICAgICAgfVxuICAgICAgaW5kZXggLT0gbi5sZW5ndGhcbiAgICB9XG4gIH1cbiAgLy8gZGVsZXRlIGFsbCBpdGVtcyB1bnRpbCBkb25lXG4gIHdoaWxlIChsZW5ndGggPiAwICYmIG4gIT09IG51bGwpIHtcbiAgICBpZiAoIW4uZGVsZXRlZCkge1xuICAgICAgaWYgKGxlbmd0aCA8IG4ubGVuZ3RoKSB7XG4gICAgICAgIGdldEl0ZW1DbGVhblN0YXJ0KHRyYW5zYWN0aW9uLCBjcmVhdGVJRChuLmlkLmNsaWVudCwgbi5pZC5jbG9jayArIGxlbmd0aCkpXG4gICAgICB9XG4gICAgICBuLmRlbGV0ZSh0cmFuc2FjdGlvbilcbiAgICAgIGxlbmd0aCAtPSBuLmxlbmd0aFxuICAgIH1cbiAgICBuID0gbi5yaWdodFxuICB9XG4gIGlmIChsZW5ndGggPiAwKSB7XG4gICAgdGhyb3cgbGVuZ3RoRXhjZWVkZWQoKVxuICB9XG4gIGlmIChwYXJlbnQuX3NlYXJjaE1hcmtlcikge1xuICAgIHVwZGF0ZU1hcmtlckNoYW5nZXMocGFyZW50Ll9zZWFyY2hNYXJrZXIsIHN0YXJ0SW5kZXgsIC1zdGFydExlbmd0aCArIGxlbmd0aCAvKiBpbiBjYXNlIHdlIHJlbW92ZSB0aGUgYWJvdmUgZXhjZXB0aW9uICovKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHBhcmVudFxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHR5cGVNYXBEZWxldGUgPSAodHJhbnNhY3Rpb24sIHBhcmVudCwga2V5KSA9PiB7XG4gIGNvbnN0IGMgPSBwYXJlbnQuX21hcC5nZXQoa2V5KVxuICBpZiAoYyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgYy5kZWxldGUodHJhbnNhY3Rpb24pXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtBYnN0cmFjdFR5cGU8YW55Pn0gcGFyZW50XG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcGFyYW0ge09iamVjdHxudW1iZXJ8bnVsbHxBcnJheTxhbnk+fHN0cmluZ3xVaW50OEFycmF5fEFic3RyYWN0VHlwZTxhbnk+fSB2YWx1ZVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHR5cGVNYXBTZXQgPSAodHJhbnNhY3Rpb24sIHBhcmVudCwga2V5LCB2YWx1ZSkgPT4ge1xuICBjb25zdCBsZWZ0ID0gcGFyZW50Ll9tYXAuZ2V0KGtleSkgfHwgbnVsbFxuICBjb25zdCBkb2MgPSB0cmFuc2FjdGlvbi5kb2NcbiAgY29uc3Qgb3duQ2xpZW50SWQgPSBkb2MuY2xpZW50SURcbiAgbGV0IGNvbnRlbnRcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICBjb250ZW50ID0gbmV3IENvbnRlbnRBbnkoW3ZhbHVlXSlcbiAgfSBlbHNlIHtcbiAgICBzd2l0Y2ggKHZhbHVlLmNvbnN0cnVjdG9yKSB7XG4gICAgICBjYXNlIE51bWJlcjpcbiAgICAgIGNhc2UgT2JqZWN0OlxuICAgICAgY2FzZSBCb29sZWFuOlxuICAgICAgY2FzZSBBcnJheTpcbiAgICAgIGNhc2UgU3RyaW5nOlxuICAgICAgY2FzZSBEYXRlOlxuICAgICAgY2FzZSBCaWdJbnQ6XG4gICAgICAgIGNvbnRlbnQgPSBuZXcgQ29udGVudEFueShbdmFsdWVdKVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSBVaW50OEFycmF5OlxuICAgICAgICBjb250ZW50ID0gbmV3IENvbnRlbnRCaW5hcnkoLyoqIEB0eXBlIHtVaW50OEFycmF5fSAqLyAodmFsdWUpKVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSBEb2M6XG4gICAgICAgIGNvbnRlbnQgPSBuZXcgQ29udGVudERvYygvKiogQHR5cGUge0RvY30gKi8gKHZhbHVlKSlcbiAgICAgICAgYnJlYWtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEFic3RyYWN0VHlwZSkge1xuICAgICAgICAgIGNvbnRlbnQgPSBuZXcgQ29udGVudFR5cGUodmFsdWUpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIGNvbnRlbnQgdHlwZScpXG4gICAgICAgIH1cbiAgICB9XG4gIH1cbiAgbmV3IEl0ZW0oY3JlYXRlSUQob3duQ2xpZW50SWQsIGdldFN0YXRlKGRvYy5zdG9yZSwgb3duQ2xpZW50SWQpKSwgbGVmdCwgbGVmdCAmJiBsZWZ0Lmxhc3RJZCwgbnVsbCwgbnVsbCwgcGFyZW50LCBrZXksIGNvbnRlbnQpLmludGVncmF0ZSh0cmFuc2FjdGlvbiwgMClcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSBwYXJlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAqIEByZXR1cm4ge09iamVjdDxzdHJpbmcsYW55PnxudW1iZXJ8bnVsbHxBcnJheTxhbnk+fHN0cmluZ3xVaW50OEFycmF5fEFic3RyYWN0VHlwZTxhbnk+fHVuZGVmaW5lZH1cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCB0eXBlTWFwR2V0ID0gKHBhcmVudCwga2V5KSA9PiB7XG4gIHBhcmVudC5kb2MgPz8gd2FyblByZW1hdHVyZUFjY2VzcygpXG4gIGNvbnN0IHZhbCA9IHBhcmVudC5fbWFwLmdldChrZXkpXG4gIHJldHVybiB2YWwgIT09IHVuZGVmaW5lZCAmJiAhdmFsLmRlbGV0ZWQgPyB2YWwuY29udGVudC5nZXRDb250ZW50KClbdmFsLmxlbmd0aCAtIDFdIDogdW5kZWZpbmVkXG59XG5cbi8qKlxuICogQHBhcmFtIHtBYnN0cmFjdFR5cGU8YW55Pn0gcGFyZW50XG4gKiBAcmV0dXJuIHtPYmplY3Q8c3RyaW5nLE9iamVjdDxzdHJpbmcsYW55PnxudW1iZXJ8bnVsbHxBcnJheTxhbnk+fHN0cmluZ3xVaW50OEFycmF5fEFic3RyYWN0VHlwZTxhbnk+fHVuZGVmaW5lZD59XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgdHlwZU1hcEdldEFsbCA9IChwYXJlbnQpID0+IHtcbiAgLyoqXG4gICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLGFueT59XG4gICAqL1xuICBjb25zdCByZXMgPSB7fVxuICBwYXJlbnQuZG9jID8/IHdhcm5QcmVtYXR1cmVBY2Nlc3MoKVxuICBwYXJlbnQuX21hcC5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgaWYgKCF2YWx1ZS5kZWxldGVkKSB7XG4gICAgICByZXNba2V5XSA9IHZhbHVlLmNvbnRlbnQuZ2V0Q29udGVudCgpW3ZhbHVlLmxlbmd0aCAtIDFdXG4gICAgfVxuICB9KVxuICByZXR1cm4gcmVzXG59XG5cbi8qKlxuICogQHBhcmFtIHtBYnN0cmFjdFR5cGU8YW55Pn0gcGFyZW50XG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHR5cGVNYXBIYXMgPSAocGFyZW50LCBrZXkpID0+IHtcbiAgcGFyZW50LmRvYyA/PyB3YXJuUHJlbWF0dXJlQWNjZXNzKClcbiAgY29uc3QgdmFsID0gcGFyZW50Ll9tYXAuZ2V0KGtleSlcbiAgcmV0dXJuIHZhbCAhPT0gdW5kZWZpbmVkICYmICF2YWwuZGVsZXRlZFxufVxuXG4vKipcbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHBhcmVudFxuICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICogQHBhcmFtIHtTbmFwc2hvdH0gc25hcHNob3RcbiAqIEByZXR1cm4ge09iamVjdDxzdHJpbmcsYW55PnxudW1iZXJ8bnVsbHxBcnJheTxhbnk+fHN0cmluZ3xVaW50OEFycmF5fEFic3RyYWN0VHlwZTxhbnk+fHVuZGVmaW5lZH1cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCB0eXBlTWFwR2V0U25hcHNob3QgPSAocGFyZW50LCBrZXksIHNuYXBzaG90KSA9PiB7XG4gIGxldCB2ID0gcGFyZW50Ll9tYXAuZ2V0KGtleSkgfHwgbnVsbFxuICB3aGlsZSAodiAhPT0gbnVsbCAmJiAoIXNuYXBzaG90LnN2Lmhhcyh2LmlkLmNsaWVudCkgfHwgdi5pZC5jbG9jayA+PSAoc25hcHNob3Quc3YuZ2V0KHYuaWQuY2xpZW50KSB8fCAwKSkpIHtcbiAgICB2ID0gdi5sZWZ0XG4gIH1cbiAgcmV0dXJuIHYgIT09IG51bGwgJiYgaXNWaXNpYmxlKHYsIHNuYXBzaG90KSA/IHYuY29udGVudC5nZXRDb250ZW50KClbdi5sZW5ndGggLSAxXSA6IHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHBhcmVudFxuICogQHBhcmFtIHtTbmFwc2hvdH0gc25hcHNob3RcbiAqIEByZXR1cm4ge09iamVjdDxzdHJpbmcsT2JqZWN0PHN0cmluZyxhbnk+fG51bWJlcnxudWxsfEFycmF5PGFueT58c3RyaW5nfFVpbnQ4QXJyYXl8QWJzdHJhY3RUeXBlPGFueT58dW5kZWZpbmVkPn1cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCB0eXBlTWFwR2V0QWxsU25hcHNob3QgPSAocGFyZW50LCBzbmFwc2hvdCkgPT4ge1xuICAvKipcbiAgICogQHR5cGUge09iamVjdDxzdHJpbmcsYW55Pn1cbiAgICovXG4gIGNvbnN0IHJlcyA9IHt9XG4gIHBhcmVudC5fbWFwLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7SXRlbXxudWxsfVxuICAgICAqL1xuICAgIGxldCB2ID0gdmFsdWVcbiAgICB3aGlsZSAodiAhPT0gbnVsbCAmJiAoIXNuYXBzaG90LnN2Lmhhcyh2LmlkLmNsaWVudCkgfHwgdi5pZC5jbG9jayA+PSAoc25hcHNob3Quc3YuZ2V0KHYuaWQuY2xpZW50KSB8fCAwKSkpIHtcbiAgICAgIHYgPSB2LmxlZnRcbiAgICB9XG4gICAgaWYgKHYgIT09IG51bGwgJiYgaXNWaXNpYmxlKHYsIHNuYXBzaG90KSkge1xuICAgICAgcmVzW2tleV0gPSB2LmNvbnRlbnQuZ2V0Q29udGVudCgpW3YubGVuZ3RoIC0gMV1cbiAgICB9XG4gIH0pXG4gIHJldHVybiByZXNcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+ICYgeyBfbWFwOiBNYXA8c3RyaW5nLCBJdGVtPiB9fSB0eXBlXG4gKiBAcmV0dXJuIHtJdGVyYWJsZUl0ZXJhdG9yPEFycmF5PGFueT4+fVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IGNyZWF0ZU1hcEl0ZXJhdG9yID0gdHlwZSA9PiB7XG4gIHR5cGUuZG9jID8/IHdhcm5QcmVtYXR1cmVBY2Nlc3MoKVxuICByZXR1cm4gaXRlcmF0b3IuaXRlcmF0b3JGaWx0ZXIodHlwZS5fbWFwLmVudHJpZXMoKSwgLyoqIEBwYXJhbSB7YW55fSBlbnRyeSAqLyBlbnRyeSA9PiAhZW50cnlbMV0uZGVsZXRlZClcbn1cbiIsICIvKipcbiAqIEBtb2R1bGUgWUFycmF5XG4gKi9cblxuaW1wb3J0IHtcbiAgWUV2ZW50LFxuICBBYnN0cmFjdFR5cGUsXG4gIHR5cGVMaXN0R2V0LFxuICB0eXBlTGlzdFRvQXJyYXksXG4gIHR5cGVMaXN0Rm9yRWFjaCxcbiAgdHlwZUxpc3RDcmVhdGVJdGVyYXRvcixcbiAgdHlwZUxpc3RJbnNlcnRHZW5lcmljcyxcbiAgdHlwZUxpc3RQdXNoR2VuZXJpY3MsXG4gIHR5cGVMaXN0RGVsZXRlLFxuICB0eXBlTGlzdE1hcCxcbiAgWUFycmF5UmVmSUQsXG4gIGNhbGxUeXBlT2JzZXJ2ZXJzLFxuICB0cmFuc2FjdCxcbiAgd2FyblByZW1hdHVyZUFjY2VzcyxcbiAgQXJyYXlTZWFyY2hNYXJrZXIsIFVwZGF0ZURlY29kZXJWMSwgVXBkYXRlRGVjb2RlclYyLCBVcGRhdGVFbmNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMiwgRG9jLCBUcmFuc2FjdGlvbiwgSXRlbSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcbmltcG9ydCB7IHR5cGVMaXN0U2xpY2UgfSBmcm9tICcuL0Fic3RyYWN0VHlwZS5qcydcblxuLyoqXG4gKiBFdmVudCB0aGF0IGRlc2NyaWJlcyB0aGUgY2hhbmdlcyBvbiBhIFlBcnJheVxuICogQHRlbXBsYXRlIFRcbiAqIEBleHRlbmRzIFlFdmVudDxZQXJyYXk8VD4+XG4gKi9cbmV4cG9ydCBjbGFzcyBZQXJyYXlFdmVudCBleHRlbmRzIFlFdmVudCB7fVxuXG4vKipcbiAqIEEgc2hhcmVkIEFycmF5IGltcGxlbWVudGF0aW9uLlxuICogQHRlbXBsYXRlIFRcbiAqIEBleHRlbmRzIEFic3RyYWN0VHlwZTxZQXJyYXlFdmVudDxUPj5cbiAqIEBpbXBsZW1lbnRzIHtJdGVyYWJsZTxUPn1cbiAqL1xuZXhwb3J0IGNsYXNzIFlBcnJheSBleHRlbmRzIEFic3RyYWN0VHlwZSB7XG4gIGNvbnN0cnVjdG9yICgpIHtcbiAgICBzdXBlcigpXG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PGFueT4/fVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgdGhpcy5fcHJlbGltQ29udGVudCA9IFtdXG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PEFycmF5U2VhcmNoTWFya2VyPn1cbiAgICAgKi9cbiAgICB0aGlzLl9zZWFyY2hNYXJrZXIgPSBbXVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBZQXJyYXkgY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIGl0ZW1zLlxuICAgKiBAdGVtcGxhdGUge09iamVjdDxzdHJpbmcsYW55PnxBcnJheTxhbnk+fG51bWJlcnxudWxsfHN0cmluZ3xVaW50OEFycmF5fSBUXG4gICAqIEBwYXJhbSB7QXJyYXk8VD59IGl0ZW1zXG4gICAqIEByZXR1cm4ge1lBcnJheTxUPn1cbiAgICovXG4gIHN0YXRpYyBmcm9tIChpdGVtcykge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtZQXJyYXk8VD59XG4gICAgICovXG4gICAgY29uc3QgYSA9IG5ldyBZQXJyYXkoKVxuICAgIGEucHVzaChpdGVtcylcbiAgICByZXR1cm4gYVxuICB9XG5cbiAgLyoqXG4gICAqIEludGVncmF0ZSB0aGlzIHR5cGUgaW50byB0aGUgWWpzIGluc3RhbmNlLlxuICAgKlxuICAgKiAqIFNhdmUgdGhpcyBzdHJ1Y3QgaW4gdGhlIG9zXG4gICAqICogVGhpcyB0eXBlIGlzIHNlbnQgdG8gb3RoZXIgY2xpZW50XG4gICAqICogT2JzZXJ2ZXIgZnVuY3Rpb25zIGFyZSBmaXJlZFxuICAgKlxuICAgKiBAcGFyYW0ge0RvY30geSBUaGUgWWpzIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7SXRlbX0gaXRlbVxuICAgKi9cbiAgX2ludGVncmF0ZSAoeSwgaXRlbSkge1xuICAgIHN1cGVyLl9pbnRlZ3JhdGUoeSwgaXRlbSlcbiAgICB0aGlzLmluc2VydCgwLCAvKiogQHR5cGUge0FycmF5PGFueT59ICovICh0aGlzLl9wcmVsaW1Db250ZW50KSlcbiAgICB0aGlzLl9wcmVsaW1Db250ZW50ID0gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1lBcnJheTxUPn1cbiAgICovXG4gIF9jb3B5ICgpIHtcbiAgICByZXR1cm4gbmV3IFlBcnJheSgpXG4gIH1cblxuICAvKipcbiAgICogTWFrZXMgYSBjb3B5IG9mIHRoaXMgZGF0YSB0eXBlIHRoYXQgY2FuIGJlIGluY2x1ZGVkIHNvbWV3aGVyZSBlbHNlLlxuICAgKlxuICAgKiBOb3RlIHRoYXQgdGhlIGNvbnRlbnQgaXMgb25seSByZWFkYWJsZSBfYWZ0ZXJfIGl0IGhhcyBiZWVuIGluY2x1ZGVkIHNvbWV3aGVyZSBpbiB0aGUgWWRvYy5cbiAgICpcbiAgICogQHJldHVybiB7WUFycmF5PFQ+fVxuICAgKi9cbiAgY2xvbmUgKCkge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtZQXJyYXk8VD59XG4gICAgICovXG4gICAgY29uc3QgYXJyID0gbmV3IFlBcnJheSgpXG4gICAgYXJyLmluc2VydCgwLCB0aGlzLnRvQXJyYXkoKS5tYXAoZWwgPT5cbiAgICAgIGVsIGluc3RhbmNlb2YgQWJzdHJhY3RUeXBlID8gLyoqIEB0eXBlIHt0eXBlb2YgZWx9ICovIChlbC5jbG9uZSgpKSA6IGVsXG4gICAgKSlcbiAgICByZXR1cm4gYXJyXG4gIH1cblxuICBnZXQgbGVuZ3RoICgpIHtcbiAgICB0aGlzLmRvYyA/PyB3YXJuUHJlbWF0dXJlQWNjZXNzKClcbiAgICByZXR1cm4gdGhpcy5fbGVuZ3RoXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBZQXJyYXlFdmVudCBhbmQgY2FsbHMgb2JzZXJ2ZXJzLlxuICAgKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge1NldDxudWxsfHN0cmluZz59IHBhcmVudFN1YnMgS2V5cyBjaGFuZ2VkIG9uIHRoaXMgdHlwZS4gYG51bGxgIGlmIGxpc3Qgd2FzIG1vZGlmaWVkLlxuICAgKi9cbiAgX2NhbGxPYnNlcnZlciAodHJhbnNhY3Rpb24sIHBhcmVudFN1YnMpIHtcbiAgICBzdXBlci5fY2FsbE9ic2VydmVyKHRyYW5zYWN0aW9uLCBwYXJlbnRTdWJzKVxuICAgIGNhbGxUeXBlT2JzZXJ2ZXJzKHRoaXMsIHRyYW5zYWN0aW9uLCBuZXcgWUFycmF5RXZlbnQodGhpcywgdHJhbnNhY3Rpb24pKVxuICB9XG5cbiAgLyoqXG4gICAqIEluc2VydHMgbmV3IGNvbnRlbnQgYXQgYW4gaW5kZXguXG4gICAqXG4gICAqIEltcG9ydGFudDogVGhpcyBmdW5jdGlvbiBleHBlY3RzIGFuIGFycmF5IG9mIGNvbnRlbnQuIE5vdCBqdXN0IGEgY29udGVudFxuICAgKiBvYmplY3QuIFRoZSByZWFzb24gZm9yIHRoaXMgXCJ3ZWlyZG5lc3NcIiBpcyB0aGF0IGluc2VydGluZyBzZXZlcmFsIGVsZW1lbnRzXG4gICAqIGlzIHZlcnkgZWZmaWNpZW50IHdoZW4gaXQgaXMgZG9uZSBhcyBhIHNpbmdsZSBvcGVyYXRpb24uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqICAvLyBJbnNlcnQgY2hhcmFjdGVyICdhJyBhdCBwb3NpdGlvbiAwXG4gICAqICB5YXJyYXkuaW5zZXJ0KDAsIFsnYSddKVxuICAgKiAgLy8gSW5zZXJ0IG51bWJlcnMgMSwgMiBhdCBwb3NpdGlvbiAxXG4gICAqICB5YXJyYXkuaW5zZXJ0KDEsIFsxLCAyXSlcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBpbmRleCB0byBpbnNlcnQgY29udGVudCBhdC5cbiAgICogQHBhcmFtIHtBcnJheTxUPn0gY29udGVudCBUaGUgYXJyYXkgb2YgY29udGVudFxuICAgKi9cbiAgaW5zZXJ0IChpbmRleCwgY29udGVudCkge1xuICAgIGlmICh0aGlzLmRvYyAhPT0gbnVsbCkge1xuICAgICAgdHJhbnNhY3QodGhpcy5kb2MsIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgdHlwZUxpc3RJbnNlcnRHZW5lcmljcyh0cmFuc2FjdGlvbiwgdGhpcywgaW5kZXgsIC8qKiBAdHlwZSB7YW55fSAqLyAoY29udGVudCkpXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAvKiogQHR5cGUge0FycmF5PGFueT59ICovICh0aGlzLl9wcmVsaW1Db250ZW50KS5zcGxpY2UoaW5kZXgsIDAsIC4uLmNvbnRlbnQpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZHMgY29udGVudCB0byB0aGlzIFlBcnJheS5cbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxUPn0gY29udGVudCBBcnJheSBvZiBjb250ZW50IHRvIGFwcGVuZC5cbiAgICpcbiAgICogQHRvZG8gVXNlIHRoZSBmb2xsb3dpbmcgaW1wbGVtZW50YXRpb24gaW4gYWxsIHR5cGVzLlxuICAgKi9cbiAgcHVzaCAoY29udGVudCkge1xuICAgIGlmICh0aGlzLmRvYyAhPT0gbnVsbCkge1xuICAgICAgdHJhbnNhY3QodGhpcy5kb2MsIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgdHlwZUxpc3RQdXNoR2VuZXJpY3ModHJhbnNhY3Rpb24sIHRoaXMsIC8qKiBAdHlwZSB7YW55fSAqLyAoY29udGVudCkpXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAvKiogQHR5cGUge0FycmF5PGFueT59ICovICh0aGlzLl9wcmVsaW1Db250ZW50KS5wdXNoKC4uLmNvbnRlbnQpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByZXBlbmRzIGNvbnRlbnQgdG8gdGhpcyBZQXJyYXkuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXk8VD59IGNvbnRlbnQgQXJyYXkgb2YgY29udGVudCB0byBwcmVwZW5kLlxuICAgKi9cbiAgdW5zaGlmdCAoY29udGVudCkge1xuICAgIHRoaXMuaW5zZXJ0KDAsIGNvbnRlbnQpXG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlcyBlbGVtZW50cyBzdGFydGluZyBmcm9tIGFuIGluZGV4LlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kZXggYXQgd2hpY2ggdG8gc3RhcnQgZGVsZXRpbmcgZWxlbWVudHNcbiAgICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHJlbW92ZS4gRGVmYXVsdHMgdG8gMS5cbiAgICovXG4gIGRlbGV0ZSAoaW5kZXgsIGxlbmd0aCA9IDEpIHtcbiAgICBpZiAodGhpcy5kb2MgIT09IG51bGwpIHtcbiAgICAgIHRyYW5zYWN0KHRoaXMuZG9jLCB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIHR5cGVMaXN0RGVsZXRlKHRyYW5zYWN0aW9uLCB0aGlzLCBpbmRleCwgbGVuZ3RoKVxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgLyoqIEB0eXBlIHtBcnJheTxhbnk+fSAqLyAodGhpcy5fcHJlbGltQ29udGVudCkuc3BsaWNlKGluZGV4LCBsZW5ndGgpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGktdGggZWxlbWVudCBmcm9tIGEgWUFycmF5LlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggVGhlIGluZGV4IG9mIHRoZSBlbGVtZW50IHRvIHJldHVybiBmcm9tIHRoZSBZQXJyYXlcbiAgICogQHJldHVybiB7VH1cbiAgICovXG4gIGdldCAoaW5kZXgpIHtcbiAgICByZXR1cm4gdHlwZUxpc3RHZXQodGhpcywgaW5kZXgpXG4gIH1cblxuICAvKipcbiAgICogVHJhbnNmb3JtcyB0aGlzIFlBcnJheSB0byBhIEphdmFTY3JpcHQgQXJyYXkuXG4gICAqXG4gICAqIEByZXR1cm4ge0FycmF5PFQ+fVxuICAgKi9cbiAgdG9BcnJheSAoKSB7XG4gICAgcmV0dXJuIHR5cGVMaXN0VG9BcnJheSh0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBwb3J0aW9uIG9mIHRoaXMgWUFycmF5IGludG8gYSBKYXZhU2NyaXB0IEFycmF5IHNlbGVjdGVkXG4gICAqIGZyb20gc3RhcnQgdG8gZW5kIChlbmQgbm90IGluY2x1ZGVkKS5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydF1cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtlbmRdXG4gICAqIEByZXR1cm4ge0FycmF5PFQ+fVxuICAgKi9cbiAgc2xpY2UgKHN0YXJ0ID0gMCwgZW5kID0gdGhpcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdHlwZUxpc3RTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zZm9ybXMgdGhpcyBTaGFyZWQgVHlwZSB0byBhIEpTT04gb2JqZWN0LlxuICAgKlxuICAgKiBAcmV0dXJuIHtBcnJheTxhbnk+fVxuICAgKi9cbiAgdG9KU09OICgpIHtcbiAgICByZXR1cm4gdGhpcy5tYXAoYyA9PiBjIGluc3RhbmNlb2YgQWJzdHJhY3RUeXBlID8gYy50b0pTT04oKSA6IGMpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBBcnJheSB3aXRoIHRoZSByZXN1bHQgb2YgY2FsbGluZyBhIHByb3ZpZGVkIGZ1bmN0aW9uIG9uIGV2ZXJ5XG4gICAqIGVsZW1lbnQgb2YgdGhpcyBZQXJyYXkuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBNXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oVCxudW1iZXIsWUFycmF5PFQ+KTpNfSBmIEZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gZWxlbWVudCBvZiB0aGUgbmV3IEFycmF5XG4gICAqIEByZXR1cm4ge0FycmF5PE0+fSBBIG5ldyBhcnJheSB3aXRoIGVhY2ggZWxlbWVudCBiZWluZyB0aGUgcmVzdWx0IG9mIHRoZVxuICAgKiAgICAgICAgICAgICAgICAgY2FsbGJhY2sgZnVuY3Rpb25cbiAgICovXG4gIG1hcCAoZikge1xuICAgIHJldHVybiB0eXBlTGlzdE1hcCh0aGlzLCAvKiogQHR5cGUge2FueX0gKi8gKGYpKVxuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGVzIGEgcHJvdmlkZWQgZnVuY3Rpb24gb25jZSBvbiBldmVyeSBlbGVtZW50IG9mIHRoaXMgWUFycmF5LlxuICAgKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKFQsbnVtYmVyLFlBcnJheTxUPik6dm9pZH0gZiBBIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgb24gZXZlcnkgZWxlbWVudCBvZiB0aGlzIFlBcnJheS5cbiAgICovXG4gIGZvckVhY2ggKGYpIHtcbiAgICB0eXBlTGlzdEZvckVhY2godGhpcywgZilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtJdGVyYWJsZUl0ZXJhdG9yPFQ+fVxuICAgKi9cbiAgW1N5bWJvbC5pdGVyYXRvcl0gKCkge1xuICAgIHJldHVybiB0eXBlTGlzdENyZWF0ZUl0ZXJhdG9yKHRoaXMpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtVcGRhdGVFbmNvZGVyVjEgfCBVcGRhdGVFbmNvZGVyVjJ9IGVuY29kZXJcbiAgICovXG4gIF93cml0ZSAoZW5jb2Rlcikge1xuICAgIGVuY29kZXIud3JpdGVUeXBlUmVmKFlBcnJheVJlZklEKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtVcGRhdGVEZWNvZGVyVjEgfCBVcGRhdGVEZWNvZGVyVjJ9IF9kZWNvZGVyXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgcmVhZFlBcnJheSA9IF9kZWNvZGVyID0+IG5ldyBZQXJyYXkoKVxuIiwgIi8qKlxuICogQG1vZHVsZSBZTWFwXG4gKi9cblxuaW1wb3J0IHtcbiAgWUV2ZW50LFxuICBBYnN0cmFjdFR5cGUsXG4gIHR5cGVNYXBEZWxldGUsXG4gIHR5cGVNYXBTZXQsXG4gIHR5cGVNYXBHZXQsXG4gIHR5cGVNYXBIYXMsXG4gIGNyZWF0ZU1hcEl0ZXJhdG9yLFxuICBZTWFwUmVmSUQsXG4gIGNhbGxUeXBlT2JzZXJ2ZXJzLFxuICB0cmFuc2FjdCxcbiAgd2FyblByZW1hdHVyZUFjY2VzcyxcbiAgVXBkYXRlRGVjb2RlclYxLCBVcGRhdGVEZWNvZGVyVjIsIFVwZGF0ZUVuY29kZXJWMSwgVXBkYXRlRW5jb2RlclYyLCBEb2MsIFRyYW5zYWN0aW9uLCBJdGVtIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbn0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJ1xuXG5pbXBvcnQgKiBhcyBpdGVyYXRvciBmcm9tICdsaWIwL2l0ZXJhdG9yJ1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAZXh0ZW5kcyBZRXZlbnQ8WU1hcDxUPj5cbiAqIEV2ZW50IHRoYXQgZGVzY3JpYmVzIHRoZSBjaGFuZ2VzIG9uIGEgWU1hcC5cbiAqL1xuZXhwb3J0IGNsYXNzIFlNYXBFdmVudCBleHRlbmRzIFlFdmVudCB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1lNYXA8VD59IHltYXAgVGhlIFlBcnJheSB0aGF0IGNoYW5nZWQuXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7U2V0PGFueT59IHN1YnMgVGhlIGtleXMgdGhhdCBjaGFuZ2VkLlxuICAgKi9cbiAgY29uc3RydWN0b3IgKHltYXAsIHRyYW5zYWN0aW9uLCBzdWJzKSB7XG4gICAgc3VwZXIoeW1hcCwgdHJhbnNhY3Rpb24pXG4gICAgdGhpcy5rZXlzQ2hhbmdlZCA9IHN1YnNcbiAgfVxufVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBNYXBUeXBlXG4gKiBBIHNoYXJlZCBNYXAgaW1wbGVtZW50YXRpb24uXG4gKlxuICogQGV4dGVuZHMgQWJzdHJhY3RUeXBlPFlNYXBFdmVudDxNYXBUeXBlPj5cbiAqIEBpbXBsZW1lbnRzIHtJdGVyYWJsZTxbc3RyaW5nLCBNYXBUeXBlXT59XG4gKi9cbmV4cG9ydCBjbGFzcyBZTWFwIGV4dGVuZHMgQWJzdHJhY3RUeXBlIHtcbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7SXRlcmFibGU8cmVhZG9ubHkgW3N0cmluZywgYW55XT49fSBlbnRyaWVzIC0gYW4gb3B0aW9uYWwgaXRlcmFibGUgdG8gaW5pdGlhbGl6ZSB0aGUgWU1hcFxuICAgKi9cbiAgY29uc3RydWN0b3IgKGVudHJpZXMpIHtcbiAgICBzdXBlcigpXG4gICAgLyoqXG4gICAgICogQHR5cGUge01hcDxzdHJpbmcsYW55Pj99XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICB0aGlzLl9wcmVsaW1Db250ZW50ID0gbnVsbFxuXG4gICAgaWYgKGVudHJpZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5fcHJlbGltQ29udGVudCA9IG5ldyBNYXAoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9wcmVsaW1Db250ZW50ID0gbmV3IE1hcChlbnRyaWVzKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbnRlZ3JhdGUgdGhpcyB0eXBlIGludG8gdGhlIFlqcyBpbnN0YW5jZS5cbiAgICpcbiAgICogKiBTYXZlIHRoaXMgc3RydWN0IGluIHRoZSBvc1xuICAgKiAqIFRoaXMgdHlwZSBpcyBzZW50IHRvIG90aGVyIGNsaWVudFxuICAgKiAqIE9ic2VydmVyIGZ1bmN0aW9ucyBhcmUgZmlyZWRcbiAgICpcbiAgICogQHBhcmFtIHtEb2N9IHkgVGhlIFlqcyBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge0l0ZW19IGl0ZW1cbiAgICovXG4gIF9pbnRlZ3JhdGUgKHksIGl0ZW0pIHtcbiAgICBzdXBlci5faW50ZWdyYXRlKHksIGl0ZW0pXG4gICAgOy8qKiBAdHlwZSB7TWFwPHN0cmluZywgYW55Pn0gKi8gKHRoaXMuX3ByZWxpbUNvbnRlbnQpLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgIHRoaXMuc2V0KGtleSwgdmFsdWUpXG4gICAgfSlcbiAgICB0aGlzLl9wcmVsaW1Db250ZW50ID0gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge1lNYXA8TWFwVHlwZT59XG4gICAqL1xuICBfY29weSAoKSB7XG4gICAgcmV0dXJuIG5ldyBZTWFwKClcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWtlcyBhIGNvcHkgb2YgdGhpcyBkYXRhIHR5cGUgdGhhdCBjYW4gYmUgaW5jbHVkZWQgc29tZXdoZXJlIGVsc2UuXG4gICAqXG4gICAqIE5vdGUgdGhhdCB0aGUgY29udGVudCBpcyBvbmx5IHJlYWRhYmxlIF9hZnRlcl8gaXQgaGFzIGJlZW4gaW5jbHVkZWQgc29tZXdoZXJlIGluIHRoZSBZZG9jLlxuICAgKlxuICAgKiBAcmV0dXJuIHtZTWFwPE1hcFR5cGU+fVxuICAgKi9cbiAgY2xvbmUgKCkge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtZTWFwPE1hcFR5cGU+fVxuICAgICAqL1xuICAgIGNvbnN0IG1hcCA9IG5ldyBZTWFwKClcbiAgICB0aGlzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgIG1hcC5zZXQoa2V5LCB2YWx1ZSBpbnN0YW5jZW9mIEFic3RyYWN0VHlwZSA/IC8qKiBAdHlwZSB7dHlwZW9mIHZhbHVlfSAqLyAodmFsdWUuY2xvbmUoKSkgOiB2YWx1ZSlcbiAgICB9KVxuICAgIHJldHVybiBtYXBcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIFlNYXBFdmVudCBhbmQgY2FsbHMgb2JzZXJ2ZXJzLlxuICAgKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge1NldDxudWxsfHN0cmluZz59IHBhcmVudFN1YnMgS2V5cyBjaGFuZ2VkIG9uIHRoaXMgdHlwZS4gYG51bGxgIGlmIGxpc3Qgd2FzIG1vZGlmaWVkLlxuICAgKi9cbiAgX2NhbGxPYnNlcnZlciAodHJhbnNhY3Rpb24sIHBhcmVudFN1YnMpIHtcbiAgICBjYWxsVHlwZU9ic2VydmVycyh0aGlzLCB0cmFuc2FjdGlvbiwgbmV3IFlNYXBFdmVudCh0aGlzLCB0cmFuc2FjdGlvbiwgcGFyZW50U3VicykpXG4gIH1cblxuICAvKipcbiAgICogVHJhbnNmb3JtcyB0aGlzIFNoYXJlZCBUeXBlIHRvIGEgSlNPTiBvYmplY3QuXG4gICAqXG4gICAqIEByZXR1cm4ge09iamVjdDxzdHJpbmcsYW55Pn1cbiAgICovXG4gIHRvSlNPTiAoKSB7XG4gICAgdGhpcy5kb2MgPz8gd2FyblByZW1hdHVyZUFjY2VzcygpXG4gICAgLyoqXG4gICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsTWFwVHlwZT59XG4gICAgICovXG4gICAgY29uc3QgbWFwID0ge31cbiAgICB0aGlzLl9tYXAuZm9yRWFjaCgoaXRlbSwga2V5KSA9PiB7XG4gICAgICBpZiAoIWl0ZW0uZGVsZXRlZCkge1xuICAgICAgICBjb25zdCB2ID0gaXRlbS5jb250ZW50LmdldENvbnRlbnQoKVtpdGVtLmxlbmd0aCAtIDFdXG4gICAgICAgIG1hcFtrZXldID0gdiBpbnN0YW5jZW9mIEFic3RyYWN0VHlwZSA/IHYudG9KU09OKCkgOiB2XG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gbWFwXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgWU1hcCAoY291bnQgb2Yga2V5L3ZhbHVlIHBhaXJzKVxuICAgKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgc2l6ZSAoKSB7XG4gICAgcmV0dXJuIFsuLi5jcmVhdGVNYXBJdGVyYXRvcih0aGlzKV0ubGVuZ3RoXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUga2V5cyBmb3IgZWFjaCBlbGVtZW50IGluIHRoZSBZTWFwIFR5cGUuXG4gICAqXG4gICAqIEByZXR1cm4ge0l0ZXJhYmxlSXRlcmF0b3I8c3RyaW5nPn1cbiAgICovXG4gIGtleXMgKCkge1xuICAgIHJldHVybiBpdGVyYXRvci5pdGVyYXRvck1hcChjcmVhdGVNYXBJdGVyYXRvcih0aGlzKSwgLyoqIEBwYXJhbSB7YW55fSB2ICovIHYgPT4gdlswXSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB2YWx1ZXMgZm9yIGVhY2ggZWxlbWVudCBpbiB0aGUgWU1hcCBUeXBlLlxuICAgKlxuICAgKiBAcmV0dXJuIHtJdGVyYWJsZUl0ZXJhdG9yPE1hcFR5cGU+fVxuICAgKi9cbiAgdmFsdWVzICgpIHtcbiAgICByZXR1cm4gaXRlcmF0b3IuaXRlcmF0b3JNYXAoY3JlYXRlTWFwSXRlcmF0b3IodGhpcyksIC8qKiBAcGFyYW0ge2FueX0gdiAqLyB2ID0+IHZbMV0uY29udGVudC5nZXRDb250ZW50KClbdlsxXS5sZW5ndGggLSAxXSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIEl0ZXJhdG9yIG9mIFtrZXksIHZhbHVlXSBwYWlyc1xuICAgKlxuICAgKiBAcmV0dXJuIHtJdGVyYWJsZUl0ZXJhdG9yPFtzdHJpbmcsIE1hcFR5cGVdPn1cbiAgICovXG4gIGVudHJpZXMgKCkge1xuICAgIHJldHVybiBpdGVyYXRvci5pdGVyYXRvck1hcChjcmVhdGVNYXBJdGVyYXRvcih0aGlzKSwgLyoqIEBwYXJhbSB7YW55fSB2ICovIHYgPT4gLyoqIEB0eXBlIHthbnl9ICovIChbdlswXSwgdlsxXS5jb250ZW50LmdldENvbnRlbnQoKVt2WzFdLmxlbmd0aCAtIDFdXSkpXG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZXMgYSBwcm92aWRlZCBmdW5jdGlvbiBvbiBvbmNlIG9uIGV2ZXJ5IGtleS12YWx1ZSBwYWlyLlxuICAgKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKE1hcFR5cGUsc3RyaW5nLFlNYXA8TWFwVHlwZT4pOnZvaWR9IGYgQSBmdW5jdGlvbiB0byBleGVjdXRlIG9uIGV2ZXJ5IGVsZW1lbnQgb2YgdGhpcyBZQXJyYXkuXG4gICAqL1xuICBmb3JFYWNoIChmKSB7XG4gICAgdGhpcy5kb2MgPz8gd2FyblByZW1hdHVyZUFjY2VzcygpXG4gICAgdGhpcy5fbWFwLmZvckVhY2goKGl0ZW0sIGtleSkgPT4ge1xuICAgICAgaWYgKCFpdGVtLmRlbGV0ZWQpIHtcbiAgICAgICAgZihpdGVtLmNvbnRlbnQuZ2V0Q29udGVudCgpW2l0ZW0ubGVuZ3RoIC0gMV0sIGtleSwgdGhpcylcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gSXRlcmF0b3Igb2YgW2tleSwgdmFsdWVdIHBhaXJzXG4gICAqXG4gICAqIEByZXR1cm4ge0l0ZXJhYmxlSXRlcmF0b3I8W3N0cmluZywgTWFwVHlwZV0+fVxuICAgKi9cbiAgW1N5bWJvbC5pdGVyYXRvcl0gKCkge1xuICAgIHJldHVybiB0aGlzLmVudHJpZXMoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhIHNwZWNpZmllZCBlbGVtZW50IGZyb20gdGhpcyBZTWFwLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIGVsZW1lbnQgdG8gcmVtb3ZlLlxuICAgKi9cbiAgZGVsZXRlIChrZXkpIHtcbiAgICBpZiAodGhpcy5kb2MgIT09IG51bGwpIHtcbiAgICAgIHRyYW5zYWN0KHRoaXMuZG9jLCB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIHR5cGVNYXBEZWxldGUodHJhbnNhY3Rpb24sIHRoaXMsIGtleSlcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgYW55Pn0gKi8gKHRoaXMuX3ByZWxpbUNvbnRlbnQpLmRlbGV0ZShrZXkpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgb3IgdXBkYXRlcyBhbiBlbGVtZW50IHdpdGggYSBzcGVjaWZpZWQga2V5IGFuZCB2YWx1ZS5cbiAgICogQHRlbXBsYXRlIHtNYXBUeXBlfSBWQUxcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbGVtZW50IHRvIGFkZCB0byB0aGlzIFlNYXBcbiAgICogQHBhcmFtIHtWQUx9IHZhbHVlIFRoZSB2YWx1ZSBvZiB0aGUgZWxlbWVudCB0byBhZGRcbiAgICogQHJldHVybiB7VkFMfVxuICAgKi9cbiAgc2V0IChrZXksIHZhbHVlKSB7XG4gICAgaWYgKHRoaXMuZG9jICE9PSBudWxsKSB7XG4gICAgICB0cmFuc2FjdCh0aGlzLmRvYywgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICB0eXBlTWFwU2V0KHRyYW5zYWN0aW9uLCB0aGlzLCBrZXksIC8qKiBAdHlwZSB7YW55fSAqLyAodmFsdWUpKVxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBhbnk+fSAqLyAodGhpcy5fcHJlbGltQ29udGVudCkuc2V0KGtleSwgdmFsdWUpXG4gICAgfVxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBzcGVjaWZpZWQgZWxlbWVudCBmcm9tIHRoaXMgWU1hcC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICAgKiBAcmV0dXJuIHtNYXBUeXBlfHVuZGVmaW5lZH1cbiAgICovXG4gIGdldCAoa2V5KSB7XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7YW55fSAqLyAodHlwZU1hcEdldCh0aGlzLCBrZXkpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgc3BlY2lmaWVkIGtleSBleGlzdHMgb3Igbm90LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgdG8gdGVzdC5cbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGhhcyAoa2V5KSB7XG4gICAgcmV0dXJuIHR5cGVNYXBIYXModGhpcywga2V5KVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhpcyBZTWFwLlxuICAgKi9cbiAgY2xlYXIgKCkge1xuICAgIGlmICh0aGlzLmRvYyAhPT0gbnVsbCkge1xuICAgICAgdHJhbnNhY3QodGhpcy5kb2MsIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChfdmFsdWUsIGtleSwgbWFwKSB7XG4gICAgICAgICAgdHlwZU1hcERlbGV0ZSh0cmFuc2FjdGlvbiwgbWFwLCBrZXkpXG4gICAgICAgIH0pXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIGFueT59ICovICh0aGlzLl9wcmVsaW1Db250ZW50KS5jbGVhcigpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VXBkYXRlRW5jb2RlclYxIHwgVXBkYXRlRW5jb2RlclYyfSBlbmNvZGVyXG4gICAqL1xuICBfd3JpdGUgKGVuY29kZXIpIHtcbiAgICBlbmNvZGVyLndyaXRlVHlwZVJlZihZTWFwUmVmSUQpXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VwZGF0ZURlY29kZXJWMSB8IFVwZGF0ZURlY29kZXJWMn0gX2RlY29kZXJcbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCByZWFkWU1hcCA9IF9kZWNvZGVyID0+IG5ldyBZTWFwKClcbiIsICIvKipcbiAqIEBtb2R1bGUgWVRleHRcbiAqL1xuXG5pbXBvcnQge1xuICBZRXZlbnQsXG4gIEFic3RyYWN0VHlwZSxcbiAgZ2V0SXRlbUNsZWFuU3RhcnQsXG4gIGdldFN0YXRlLFxuICBpc1Zpc2libGUsXG4gIGNyZWF0ZUlELFxuICBZVGV4dFJlZklELFxuICBjYWxsVHlwZU9ic2VydmVycyxcbiAgdHJhbnNhY3QsXG4gIENvbnRlbnRFbWJlZCxcbiAgR0MsXG4gIENvbnRlbnRGb3JtYXQsXG4gIENvbnRlbnRTdHJpbmcsXG4gIHNwbGl0U25hcHNob3RBZmZlY3RlZFN0cnVjdHMsXG4gIGl0ZXJhdGVEZWxldGVkU3RydWN0cyxcbiAgaXRlcmF0ZVN0cnVjdHMsXG4gIGZpbmRNYXJrZXIsXG4gIHR5cGVNYXBEZWxldGUsXG4gIHR5cGVNYXBTZXQsXG4gIHR5cGVNYXBHZXQsXG4gIHR5cGVNYXBHZXRBbGwsXG4gIHVwZGF0ZU1hcmtlckNoYW5nZXMsXG4gIENvbnRlbnRUeXBlLFxuICB3YXJuUHJlbWF0dXJlQWNjZXNzLFxuICBBcnJheVNlYXJjaE1hcmtlciwgVXBkYXRlRGVjb2RlclYxLCBVcGRhdGVEZWNvZGVyVjIsIFVwZGF0ZUVuY29kZXJWMSwgVXBkYXRlRW5jb2RlclYyLCBJRCwgRG9jLCBJdGVtLCBTbmFwc2hvdCwgVHJhbnNhY3Rpb24gLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbmltcG9ydCAqIGFzIG9iamVjdCBmcm9tICdsaWIwL29iamVjdCdcbmltcG9ydCAqIGFzIG1hcCBmcm9tICdsaWIwL21hcCdcbmltcG9ydCAqIGFzIGVycm9yIGZyb20gJ2xpYjAvZXJyb3InXG5cbi8qKlxuICogQHBhcmFtIHthbnl9IGFcbiAqIEBwYXJhbSB7YW55fSBiXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5jb25zdCBlcXVhbEF0dHJzID0gKGEsIGIpID0+IGEgPT09IGIgfHwgKHR5cGVvZiBhID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgYiA9PT0gJ29iamVjdCcgJiYgYSAmJiBiICYmIG9iamVjdC5lcXVhbEZsYXQoYSwgYikpXG5cbmV4cG9ydCBjbGFzcyBJdGVtVGV4dExpc3RQb3NpdGlvbiB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0l0ZW18bnVsbH0gbGVmdFxuICAgKiBAcGFyYW0ge0l0ZW18bnVsbH0gcmlnaHRcbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG4gICAqIEBwYXJhbSB7TWFwPHN0cmluZyxhbnk+fSBjdXJyZW50QXR0cmlidXRlc1xuICAgKi9cbiAgY29uc3RydWN0b3IgKGxlZnQsIHJpZ2h0LCBpbmRleCwgY3VycmVudEF0dHJpYnV0ZXMpIHtcbiAgICB0aGlzLmxlZnQgPSBsZWZ0XG4gICAgdGhpcy5yaWdodCA9IHJpZ2h0XG4gICAgdGhpcy5pbmRleCA9IGluZGV4XG4gICAgdGhpcy5jdXJyZW50QXR0cmlidXRlcyA9IGN1cnJlbnRBdHRyaWJ1dGVzXG4gIH1cblxuICAvKipcbiAgICogT25seSBjYWxsIHRoaXMgaWYgeW91IGtub3cgdGhhdCB0aGlzLnJpZ2h0IGlzIGRlZmluZWRcbiAgICovXG4gIGZvcndhcmQgKCkge1xuICAgIGlmICh0aGlzLnJpZ2h0ID09PSBudWxsKSB7XG4gICAgICBlcnJvci51bmV4cGVjdGVkQ2FzZSgpXG4gICAgfVxuICAgIHN3aXRjaCAodGhpcy5yaWdodC5jb250ZW50LmNvbnN0cnVjdG9yKSB7XG4gICAgICBjYXNlIENvbnRlbnRGb3JtYXQ6XG4gICAgICAgIGlmICghdGhpcy5yaWdodC5kZWxldGVkKSB7XG4gICAgICAgICAgdXBkYXRlQ3VycmVudEF0dHJpYnV0ZXModGhpcy5jdXJyZW50QXR0cmlidXRlcywgLyoqIEB0eXBlIHtDb250ZW50Rm9ybWF0fSAqLyAodGhpcy5yaWdodC5jb250ZW50KSlcbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKCF0aGlzLnJpZ2h0LmRlbGV0ZWQpIHtcbiAgICAgICAgICB0aGlzLmluZGV4ICs9IHRoaXMucmlnaHQubGVuZ3RoXG4gICAgICAgIH1cbiAgICAgICAgYnJlYWtcbiAgICB9XG4gICAgdGhpcy5sZWZ0ID0gdGhpcy5yaWdodFxuICAgIHRoaXMucmlnaHQgPSB0aGlzLnJpZ2h0LnJpZ2h0XG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtJdGVtVGV4dExpc3RQb3NpdGlvbn0gcG9zXG4gKiBAcGFyYW0ge251bWJlcn0gY291bnQgc3RlcHMgdG8gbW92ZSBmb3J3YXJkXG4gKiBAcmV0dXJuIHtJdGVtVGV4dExpc3RQb3NpdGlvbn1cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmNvbnN0IGZpbmROZXh0UG9zaXRpb24gPSAodHJhbnNhY3Rpb24sIHBvcywgY291bnQpID0+IHtcbiAgd2hpbGUgKHBvcy5yaWdodCAhPT0gbnVsbCAmJiBjb3VudCA+IDApIHtcbiAgICBzd2l0Y2ggKHBvcy5yaWdodC5jb250ZW50LmNvbnN0cnVjdG9yKSB7XG4gICAgICBjYXNlIENvbnRlbnRGb3JtYXQ6XG4gICAgICAgIGlmICghcG9zLnJpZ2h0LmRlbGV0ZWQpIHtcbiAgICAgICAgICB1cGRhdGVDdXJyZW50QXR0cmlidXRlcyhwb3MuY3VycmVudEF0dHJpYnV0ZXMsIC8qKiBAdHlwZSB7Q29udGVudEZvcm1hdH0gKi8gKHBvcy5yaWdodC5jb250ZW50KSlcbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgaWYgKCFwb3MucmlnaHQuZGVsZXRlZCkge1xuICAgICAgICAgIGlmIChjb3VudCA8IHBvcy5yaWdodC5sZW5ndGgpIHtcbiAgICAgICAgICAgIC8vIHNwbGl0IHJpZ2h0XG4gICAgICAgICAgICBnZXRJdGVtQ2xlYW5TdGFydCh0cmFuc2FjdGlvbiwgY3JlYXRlSUQocG9zLnJpZ2h0LmlkLmNsaWVudCwgcG9zLnJpZ2h0LmlkLmNsb2NrICsgY291bnQpKVxuICAgICAgICAgIH1cbiAgICAgICAgICBwb3MuaW5kZXggKz0gcG9zLnJpZ2h0Lmxlbmd0aFxuICAgICAgICAgIGNvdW50IC09IHBvcy5yaWdodC5sZW5ndGhcbiAgICAgICAgfVxuICAgICAgICBicmVha1xuICAgIH1cbiAgICBwb3MubGVmdCA9IHBvcy5yaWdodFxuICAgIHBvcy5yaWdodCA9IHBvcy5yaWdodC5yaWdodFxuICAgIC8vIHBvcy5mb3J3YXJkKCkgLSB3ZSBkb24ndCBmb3J3YXJkIGJlY2F1c2UgdGhhdCB3b3VsZCBoYWx2ZSB0aGUgcGVyZm9ybWFuY2UgYmVjYXVzZSB3ZSBhbHJlYWR5IGRvIHRoZSBjaGVja3MgYWJvdmVcbiAgfVxuICByZXR1cm4gcG9zXG59XG5cbi8qKlxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHBhcmVudFxuICogQHBhcmFtIHtudW1iZXJ9IGluZGV4XG4gKiBAcGFyYW0ge2Jvb2xlYW59IHVzZVNlYXJjaE1hcmtlclxuICogQHJldHVybiB7SXRlbVRleHRMaXN0UG9zaXRpb259XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5jb25zdCBmaW5kUG9zaXRpb24gPSAodHJhbnNhY3Rpb24sIHBhcmVudCwgaW5kZXgsIHVzZVNlYXJjaE1hcmtlcikgPT4ge1xuICBjb25zdCBjdXJyZW50QXR0cmlidXRlcyA9IG5ldyBNYXAoKVxuICBjb25zdCBtYXJrZXIgPSB1c2VTZWFyY2hNYXJrZXIgPyBmaW5kTWFya2VyKHBhcmVudCwgaW5kZXgpIDogbnVsbFxuICBpZiAobWFya2VyKSB7XG4gICAgY29uc3QgcG9zID0gbmV3IEl0ZW1UZXh0TGlzdFBvc2l0aW9uKG1hcmtlci5wLmxlZnQsIG1hcmtlci5wLCBtYXJrZXIuaW5kZXgsIGN1cnJlbnRBdHRyaWJ1dGVzKVxuICAgIHJldHVybiBmaW5kTmV4dFBvc2l0aW9uKHRyYW5zYWN0aW9uLCBwb3MsIGluZGV4IC0gbWFya2VyLmluZGV4KVxuICB9IGVsc2Uge1xuICAgIGNvbnN0IHBvcyA9IG5ldyBJdGVtVGV4dExpc3RQb3NpdGlvbihudWxsLCBwYXJlbnQuX3N0YXJ0LCAwLCBjdXJyZW50QXR0cmlidXRlcylcbiAgICByZXR1cm4gZmluZE5leHRQb3NpdGlvbih0cmFuc2FjdGlvbiwgcG9zLCBpbmRleClcbiAgfVxufVxuXG4vKipcbiAqIE5lZ2F0ZSBhcHBsaWVkIGZvcm1hdHNcbiAqXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtBYnN0cmFjdFR5cGU8YW55Pn0gcGFyZW50XG4gKiBAcGFyYW0ge0l0ZW1UZXh0TGlzdFBvc2l0aW9ufSBjdXJyUG9zXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsYW55Pn0gbmVnYXRlZEF0dHJpYnV0ZXNcbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmNvbnN0IGluc2VydE5lZ2F0ZWRBdHRyaWJ1dGVzID0gKHRyYW5zYWN0aW9uLCBwYXJlbnQsIGN1cnJQb3MsIG5lZ2F0ZWRBdHRyaWJ1dGVzKSA9PiB7XG4gIC8vIGNoZWNrIGlmIHdlIHJlYWxseSBuZWVkIHRvIHJlbW92ZSBhdHRyaWJ1dGVzXG4gIHdoaWxlIChcbiAgICBjdXJyUG9zLnJpZ2h0ICE9PSBudWxsICYmIChcbiAgICAgIGN1cnJQb3MucmlnaHQuZGVsZXRlZCA9PT0gdHJ1ZSB8fCAoXG4gICAgICAgIGN1cnJQb3MucmlnaHQuY29udGVudC5jb25zdHJ1Y3RvciA9PT0gQ29udGVudEZvcm1hdCAmJlxuICAgICAgICBlcXVhbEF0dHJzKG5lZ2F0ZWRBdHRyaWJ1dGVzLmdldCgvKiogQHR5cGUge0NvbnRlbnRGb3JtYXR9ICovIChjdXJyUG9zLnJpZ2h0LmNvbnRlbnQpLmtleSksIC8qKiBAdHlwZSB7Q29udGVudEZvcm1hdH0gKi8gKGN1cnJQb3MucmlnaHQuY29udGVudCkudmFsdWUpXG4gICAgICApXG4gICAgKVxuICApIHtcbiAgICBpZiAoIWN1cnJQb3MucmlnaHQuZGVsZXRlZCkge1xuICAgICAgbmVnYXRlZEF0dHJpYnV0ZXMuZGVsZXRlKC8qKiBAdHlwZSB7Q29udGVudEZvcm1hdH0gKi8gKGN1cnJQb3MucmlnaHQuY29udGVudCkua2V5KVxuICAgIH1cbiAgICBjdXJyUG9zLmZvcndhcmQoKVxuICB9XG4gIGNvbnN0IGRvYyA9IHRyYW5zYWN0aW9uLmRvY1xuICBjb25zdCBvd25DbGllbnRJZCA9IGRvYy5jbGllbnRJRFxuICBuZWdhdGVkQXR0cmlidXRlcy5mb3JFYWNoKCh2YWwsIGtleSkgPT4ge1xuICAgIGNvbnN0IGxlZnQgPSBjdXJyUG9zLmxlZnRcbiAgICBjb25zdCByaWdodCA9IGN1cnJQb3MucmlnaHRcbiAgICBjb25zdCBuZXh0Rm9ybWF0ID0gbmV3IEl0ZW0oY3JlYXRlSUQob3duQ2xpZW50SWQsIGdldFN0YXRlKGRvYy5zdG9yZSwgb3duQ2xpZW50SWQpKSwgbGVmdCwgbGVmdCAmJiBsZWZ0Lmxhc3RJZCwgcmlnaHQsIHJpZ2h0ICYmIHJpZ2h0LmlkLCBwYXJlbnQsIG51bGwsIG5ldyBDb250ZW50Rm9ybWF0KGtleSwgdmFsKSlcbiAgICBuZXh0Rm9ybWF0LmludGVncmF0ZSh0cmFuc2FjdGlvbiwgMClcbiAgICBjdXJyUG9zLnJpZ2h0ID0gbmV4dEZvcm1hdFxuICAgIGN1cnJQb3MuZm9yd2FyZCgpXG4gIH0pXG59XG5cbi8qKlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLGFueT59IGN1cnJlbnRBdHRyaWJ1dGVzXG4gKiBAcGFyYW0ge0NvbnRlbnRGb3JtYXR9IGZvcm1hdFxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuY29uc3QgdXBkYXRlQ3VycmVudEF0dHJpYnV0ZXMgPSAoY3VycmVudEF0dHJpYnV0ZXMsIGZvcm1hdCkgPT4ge1xuICBjb25zdCB7IGtleSwgdmFsdWUgfSA9IGZvcm1hdFxuICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICBjdXJyZW50QXR0cmlidXRlcy5kZWxldGUoa2V5KVxuICB9IGVsc2Uge1xuICAgIGN1cnJlbnRBdHRyaWJ1dGVzLnNldChrZXksIHZhbHVlKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtJdGVtVGV4dExpc3RQb3NpdGlvbn0gY3VyclBvc1xuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLGFueT59IGF0dHJpYnV0ZXNcbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKi9cbmNvbnN0IG1pbmltaXplQXR0cmlidXRlQ2hhbmdlcyA9IChjdXJyUG9zLCBhdHRyaWJ1dGVzKSA9PiB7XG4gIC8vIGdvIHJpZ2h0IHdoaWxlIGF0dHJpYnV0ZXNbcmlnaHQua2V5XSA9PT0gcmlnaHQudmFsdWUgKG9yIHJpZ2h0IGlzIGRlbGV0ZWQpXG4gIHdoaWxlICh0cnVlKSB7XG4gICAgaWYgKGN1cnJQb3MucmlnaHQgPT09IG51bGwpIHtcbiAgICAgIGJyZWFrXG4gICAgfSBlbHNlIGlmIChjdXJyUG9zLnJpZ2h0LmRlbGV0ZWQgfHwgKGN1cnJQb3MucmlnaHQuY29udGVudC5jb25zdHJ1Y3RvciA9PT0gQ29udGVudEZvcm1hdCAmJiBlcXVhbEF0dHJzKGF0dHJpYnV0ZXNbKC8qKiBAdHlwZSB7Q29udGVudEZvcm1hdH0gKi8gKGN1cnJQb3MucmlnaHQuY29udGVudCkpLmtleV0gPz8gbnVsbCwgLyoqIEB0eXBlIHtDb250ZW50Rm9ybWF0fSAqLyAoY3VyclBvcy5yaWdodC5jb250ZW50KS52YWx1ZSkpKSB7XG4gICAgICAvL1xuICAgIH0gZWxzZSB7XG4gICAgICBicmVha1xuICAgIH1cbiAgICBjdXJyUG9zLmZvcndhcmQoKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT59IHBhcmVudFxuICogQHBhcmFtIHtJdGVtVGV4dExpc3RQb3NpdGlvbn0gY3VyclBvc1xuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLGFueT59IGF0dHJpYnV0ZXNcbiAqIEByZXR1cm4ge01hcDxzdHJpbmcsYW55Pn1cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKiovXG5jb25zdCBpbnNlcnRBdHRyaWJ1dGVzID0gKHRyYW5zYWN0aW9uLCBwYXJlbnQsIGN1cnJQb3MsIGF0dHJpYnV0ZXMpID0+IHtcbiAgY29uc3QgZG9jID0gdHJhbnNhY3Rpb24uZG9jXG4gIGNvbnN0IG93bkNsaWVudElkID0gZG9jLmNsaWVudElEXG4gIGNvbnN0IG5lZ2F0ZWRBdHRyaWJ1dGVzID0gbmV3IE1hcCgpXG4gIC8vIGluc2VydCBmb3JtYXQtc3RhcnQgaXRlbXNcbiAgZm9yIChjb25zdCBrZXkgaW4gYXR0cmlidXRlcykge1xuICAgIGNvbnN0IHZhbCA9IGF0dHJpYnV0ZXNba2V5XVxuICAgIGNvbnN0IGN1cnJlbnRWYWwgPSBjdXJyUG9zLmN1cnJlbnRBdHRyaWJ1dGVzLmdldChrZXkpID8/IG51bGxcbiAgICBpZiAoIWVxdWFsQXR0cnMoY3VycmVudFZhbCwgdmFsKSkge1xuICAgICAgLy8gc2F2ZSBuZWdhdGVkIGF0dHJpYnV0ZSAoc2V0IG51bGwgaWYgY3VycmVudFZhbCB1bmRlZmluZWQpXG4gICAgICBuZWdhdGVkQXR0cmlidXRlcy5zZXQoa2V5LCBjdXJyZW50VmFsKVxuICAgICAgY29uc3QgeyBsZWZ0LCByaWdodCB9ID0gY3VyclBvc1xuICAgICAgY3VyclBvcy5yaWdodCA9IG5ldyBJdGVtKGNyZWF0ZUlEKG93bkNsaWVudElkLCBnZXRTdGF0ZShkb2Muc3RvcmUsIG93bkNsaWVudElkKSksIGxlZnQsIGxlZnQgJiYgbGVmdC5sYXN0SWQsIHJpZ2h0LCByaWdodCAmJiByaWdodC5pZCwgcGFyZW50LCBudWxsLCBuZXcgQ29udGVudEZvcm1hdChrZXksIHZhbCkpXG4gICAgICBjdXJyUG9zLnJpZ2h0LmludGVncmF0ZSh0cmFuc2FjdGlvbiwgMClcbiAgICAgIGN1cnJQb3MuZm9yd2FyZCgpXG4gICAgfVxuICB9XG4gIHJldHVybiBuZWdhdGVkQXR0cmlidXRlc1xufVxuXG4vKipcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSBwYXJlbnRcbiAqIEBwYXJhbSB7SXRlbVRleHRMaXN0UG9zaXRpb259IGN1cnJQb3NcbiAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdHxBYnN0cmFjdFR5cGU8YW55Pn0gdGV4dFxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLGFueT59IGF0dHJpYnV0ZXNcbiAqXG4gKiBAcHJpdmF0ZVxuICogQGZ1bmN0aW9uXG4gKiovXG5jb25zdCBpbnNlcnRUZXh0ID0gKHRyYW5zYWN0aW9uLCBwYXJlbnQsIGN1cnJQb3MsIHRleHQsIGF0dHJpYnV0ZXMpID0+IHtcbiAgY3VyclBvcy5jdXJyZW50QXR0cmlidXRlcy5mb3JFYWNoKChfdmFsLCBrZXkpID0+IHtcbiAgICBpZiAoYXR0cmlidXRlc1trZXldID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGF0dHJpYnV0ZXNba2V5XSA9IG51bGxcbiAgICB9XG4gIH0pXG4gIGNvbnN0IGRvYyA9IHRyYW5zYWN0aW9uLmRvY1xuICBjb25zdCBvd25DbGllbnRJZCA9IGRvYy5jbGllbnRJRFxuICBtaW5pbWl6ZUF0dHJpYnV0ZUNoYW5nZXMoY3VyclBvcywgYXR0cmlidXRlcylcbiAgY29uc3QgbmVnYXRlZEF0dHJpYnV0ZXMgPSBpbnNlcnRBdHRyaWJ1dGVzKHRyYW5zYWN0aW9uLCBwYXJlbnQsIGN1cnJQb3MsIGF0dHJpYnV0ZXMpXG4gIC8vIGluc2VydCBjb250ZW50XG4gIGNvbnN0IGNvbnRlbnQgPSB0ZXh0LmNvbnN0cnVjdG9yID09PSBTdHJpbmcgPyBuZXcgQ29udGVudFN0cmluZygvKiogQHR5cGUge3N0cmluZ30gKi8gKHRleHQpKSA6ICh0ZXh0IGluc3RhbmNlb2YgQWJzdHJhY3RUeXBlID8gbmV3IENvbnRlbnRUeXBlKHRleHQpIDogbmV3IENvbnRlbnRFbWJlZCh0ZXh0KSlcbiAgbGV0IHsgbGVmdCwgcmlnaHQsIGluZGV4IH0gPSBjdXJyUG9zXG4gIGlmIChwYXJlbnQuX3NlYXJjaE1hcmtlcikge1xuICAgIHVwZGF0ZU1hcmtlckNoYW5nZXMocGFyZW50Ll9zZWFyY2hNYXJrZXIsIGN1cnJQb3MuaW5kZXgsIGNvbnRlbnQuZ2V0TGVuZ3RoKCkpXG4gIH1cbiAgcmlnaHQgPSBuZXcgSXRlbShjcmVhdGVJRChvd25DbGllbnRJZCwgZ2V0U3RhdGUoZG9jLnN0b3JlLCBvd25DbGllbnRJZCkpLCBsZWZ0LCBsZWZ0ICYmIGxlZnQubGFzdElkLCByaWdodCwgcmlnaHQgJiYgcmlnaHQuaWQsIHBhcmVudCwgbnVsbCwgY29udGVudClcbiAgcmlnaHQuaW50ZWdyYXRlKHRyYW5zYWN0aW9uLCAwKVxuICBjdXJyUG9zLnJpZ2h0ID0gcmlnaHRcbiAgY3VyclBvcy5pbmRleCA9IGluZGV4XG4gIGN1cnJQb3MuZm9yd2FyZCgpXG4gIGluc2VydE5lZ2F0ZWRBdHRyaWJ1dGVzKHRyYW5zYWN0aW9uLCBwYXJlbnQsIGN1cnJQb3MsIG5lZ2F0ZWRBdHRyaWJ1dGVzKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gKiBAcGFyYW0ge0Fic3RyYWN0VHlwZTxhbnk+fSBwYXJlbnRcbiAqIEBwYXJhbSB7SXRlbVRleHRMaXN0UG9zaXRpb259IGN1cnJQb3NcbiAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGhcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZyxhbnk+fSBhdHRyaWJ1dGVzXG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5jb25zdCBmb3JtYXRUZXh0ID0gKHRyYW5zYWN0aW9uLCBwYXJlbnQsIGN1cnJQb3MsIGxlbmd0aCwgYXR0cmlidXRlcykgPT4ge1xuICBjb25zdCBkb2MgPSB0cmFuc2FjdGlvbi5kb2NcbiAgY29uc3Qgb3duQ2xpZW50SWQgPSBkb2MuY2xpZW50SURcbiAgbWluaW1pemVBdHRyaWJ1dGVDaGFuZ2VzKGN1cnJQb3MsIGF0dHJpYnV0ZXMpXG4gIGNvbnN0IG5lZ2F0ZWRBdHRyaWJ1dGVzID0gaW5zZXJ0QXR0cmlidXRlcyh0cmFuc2FjdGlvbiwgcGFyZW50LCBjdXJyUG9zLCBhdHRyaWJ1dGVzKVxuICAvLyBpdGVyYXRlIHVudGlsIGZpcnN0IG5vbi1mb3JtYXQgb3IgbnVsbCBpcyBmb3VuZFxuICAvLyBkZWxldGUgYWxsIGZvcm1hdHMgd2l0aCBhdHRyaWJ1dGVzW2Zvcm1hdC5rZXldICE9IG51bGxcbiAgLy8gYWxzbyBjaGVjayB0aGUgYXR0cmlidXRlcyBhZnRlciB0aGUgZmlyc3Qgbm9uLWZvcm1hdCBhcyB3ZSBkbyBub3Qgd2FudCB0byBpbnNlcnQgcmVkdW5kYW50IG5lZ2F0ZWQgYXR0cmlidXRlcyB0aGVyZVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbGFiZWxzXG4gIGl0ZXJhdGlvbkxvb3A6IHdoaWxlIChcbiAgICBjdXJyUG9zLnJpZ2h0ICE9PSBudWxsICYmXG4gICAgKGxlbmd0aCA+IDAgfHxcbiAgICAgIChcbiAgICAgICAgbmVnYXRlZEF0dHJpYnV0ZXMuc2l6ZSA+IDAgJiZcbiAgICAgICAgKGN1cnJQb3MucmlnaHQuZGVsZXRlZCB8fCBjdXJyUG9zLnJpZ2h0LmNvbnRlbnQuY29uc3RydWN0b3IgPT09IENvbnRlbnRGb3JtYXQpXG4gICAgICApXG4gICAgKVxuICApIHtcbiAgICBpZiAoIWN1cnJQb3MucmlnaHQuZGVsZXRlZCkge1xuICAgICAgc3dpdGNoIChjdXJyUG9zLnJpZ2h0LmNvbnRlbnQuY29uc3RydWN0b3IpIHtcbiAgICAgICAgY2FzZSBDb250ZW50Rm9ybWF0OiB7XG4gICAgICAgICAgY29uc3QgeyBrZXksIHZhbHVlIH0gPSAvKiogQHR5cGUge0NvbnRlbnRGb3JtYXR9ICovIChjdXJyUG9zLnJpZ2h0LmNvbnRlbnQpXG4gICAgICAgICAgY29uc3QgYXR0ciA9IGF0dHJpYnV0ZXNba2V5XVxuICAgICAgICAgIGlmIChhdHRyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChlcXVhbEF0dHJzKGF0dHIsIHZhbHVlKSkge1xuICAgICAgICAgICAgICBuZWdhdGVkQXR0cmlidXRlcy5kZWxldGUoa2V5KVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKGxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIC8vIG5vIG5lZWQgdG8gZnVydGhlciBleHRlbmQgbmVnYXRlZEF0dHJpYnV0ZXNcbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbGFiZWxzXG4gICAgICAgICAgICAgICAgYnJlYWsgaXRlcmF0aW9uTG9vcFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIG5lZ2F0ZWRBdHRyaWJ1dGVzLnNldChrZXksIHZhbHVlKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VyclBvcy5yaWdodC5kZWxldGUodHJhbnNhY3Rpb24pXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGN1cnJQb3MuY3VycmVudEF0dHJpYnV0ZXMuc2V0KGtleSwgdmFsdWUpXG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrXG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBpZiAobGVuZ3RoIDwgY3VyclBvcy5yaWdodC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGdldEl0ZW1DbGVhblN0YXJ0KHRyYW5zYWN0aW9uLCBjcmVhdGVJRChjdXJyUG9zLnJpZ2h0LmlkLmNsaWVudCwgY3VyclBvcy5yaWdodC5pZC5jbG9jayArIGxlbmd0aCkpXG4gICAgICAgICAgfVxuICAgICAgICAgIGxlbmd0aCAtPSBjdXJyUG9zLnJpZ2h0Lmxlbmd0aFxuICAgICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuICAgIGN1cnJQb3MuZm9yd2FyZCgpXG4gIH1cbiAgLy8gUXVpbGwganVzdCBhc3N1bWVzIHRoYXQgdGhlIGVkaXRvciBzdGFydHMgd2l0aCBhIG5ld2xpbmUgYW5kIHRoYXQgaXQgYWx3YXlzXG4gIC8vIGVuZHMgd2l0aCBhIG5ld2xpbmUuIFdlIG9ubHkgaW5zZXJ0IHRoYXQgbmV3bGluZSB3aGVuIGEgbmV3IG5ld2xpbmUgaXNcbiAgLy8gaW5zZXJ0ZWQgLSBpLmUgd2hlbiBsZW5ndGggaXMgYmlnZ2VyIHRoYW4gdHlwZS5sZW5ndGhcbiAgaWYgKGxlbmd0aCA+IDApIHtcbiAgICBsZXQgbmV3bGluZXMgPSAnJ1xuICAgIGZvciAoOyBsZW5ndGggPiAwOyBsZW5ndGgtLSkge1xuICAgICAgbmV3bGluZXMgKz0gJ1xcbidcbiAgICB9XG4gICAgY3VyclBvcy5yaWdodCA9IG5ldyBJdGVtKGNyZWF0ZUlEKG93bkNsaWVudElkLCBnZXRTdGF0ZShkb2Muc3RvcmUsIG93bkNsaWVudElkKSksIGN1cnJQb3MubGVmdCwgY3VyclBvcy5sZWZ0ICYmIGN1cnJQb3MubGVmdC5sYXN0SWQsIGN1cnJQb3MucmlnaHQsIGN1cnJQb3MucmlnaHQgJiYgY3VyclBvcy5yaWdodC5pZCwgcGFyZW50LCBudWxsLCBuZXcgQ29udGVudFN0cmluZyhuZXdsaW5lcykpXG4gICAgY3VyclBvcy5yaWdodC5pbnRlZ3JhdGUodHJhbnNhY3Rpb24sIDApXG4gICAgY3VyclBvcy5mb3J3YXJkKClcbiAgfVxuICBpbnNlcnROZWdhdGVkQXR0cmlidXRlcyh0cmFuc2FjdGlvbiwgcGFyZW50LCBjdXJyUG9zLCBuZWdhdGVkQXR0cmlidXRlcylcbn1cblxuLyoqXG4gKiBDYWxsIHRoaXMgZnVuY3Rpb24gYWZ0ZXIgc3RyaW5nIGNvbnRlbnQgaGFzIGJlZW4gZGVsZXRlZCBpbiBvcmRlciB0b1xuICogY2xlYW4gdXAgZm9ybWF0dGluZyBJdGVtcy5cbiAqXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtJdGVtfSBzdGFydFxuICogQHBhcmFtIHtJdGVtfG51bGx9IGN1cnIgZXhjbHVzaXZlIGVuZCwgYXV0b21hdGljYWxseSBpdGVyYXRlcyB0byB0aGUgbmV4dCBDb250ZW50IEl0ZW1cbiAqIEBwYXJhbSB7TWFwPHN0cmluZyxhbnk+fSBzdGFydEF0dHJpYnV0ZXNcbiAqIEBwYXJhbSB7TWFwPHN0cmluZyxhbnk+fSBjdXJyQXR0cmlidXRlc1xuICogQHJldHVybiB7bnVtYmVyfSBUaGUgYW1vdW50IG9mIGZvcm1hdHRpbmcgSXRlbXMgZGVsZXRlZC5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqL1xuY29uc3QgY2xlYW51cEZvcm1hdHRpbmdHYXAgPSAodHJhbnNhY3Rpb24sIHN0YXJ0LCBjdXJyLCBzdGFydEF0dHJpYnV0ZXMsIGN1cnJBdHRyaWJ1dGVzKSA9PiB7XG4gIC8qKlxuICAgKiBAdHlwZSB7SXRlbXxudWxsfVxuICAgKi9cbiAgbGV0IGVuZCA9IHN0YXJ0XG4gIC8qKlxuICAgKiBAdHlwZSB7TWFwPHN0cmluZyxDb250ZW50Rm9ybWF0Pn1cbiAgICovXG4gIGNvbnN0IGVuZEZvcm1hdHMgPSBtYXAuY3JlYXRlKClcbiAgd2hpbGUgKGVuZCAmJiAoIWVuZC5jb3VudGFibGUgfHwgZW5kLmRlbGV0ZWQpKSB7XG4gICAgaWYgKCFlbmQuZGVsZXRlZCAmJiBlbmQuY29udGVudC5jb25zdHJ1Y3RvciA9PT0gQ29udGVudEZvcm1hdCkge1xuICAgICAgY29uc3QgY2YgPSAvKiogQHR5cGUge0NvbnRlbnRGb3JtYXR9ICovIChlbmQuY29udGVudClcbiAgICAgIGVuZEZvcm1hdHMuc2V0KGNmLmtleSwgY2YpXG4gICAgfVxuICAgIGVuZCA9IGVuZC5yaWdodFxuICB9XG4gIGxldCBjbGVhbnVwcyA9IDBcbiAgbGV0IHJlYWNoZWRDdXJyID0gZmFsc2VcbiAgd2hpbGUgKHN0YXJ0ICE9PSBlbmQpIHtcbiAgICBpZiAoY3VyciA9PT0gc3RhcnQpIHtcbiAgICAgIHJlYWNoZWRDdXJyID0gdHJ1ZVxuICAgIH1cbiAgICBpZiAoIXN0YXJ0LmRlbGV0ZWQpIHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBzdGFydC5jb250ZW50XG4gICAgICBzd2l0Y2ggKGNvbnRlbnQuY29uc3RydWN0b3IpIHtcbiAgICAgICAgY2FzZSBDb250ZW50Rm9ybWF0OiB7XG4gICAgICAgICAgY29uc3QgeyBrZXksIHZhbHVlIH0gPSAvKiogQHR5cGUge0NvbnRlbnRGb3JtYXR9ICovIChjb250ZW50KVxuICAgICAgICAgIGNvbnN0IHN0YXJ0QXR0clZhbHVlID0gc3RhcnRBdHRyaWJ1dGVzLmdldChrZXkpID8/IG51bGxcbiAgICAgICAgICBpZiAoZW5kRm9ybWF0cy5nZXQoa2V5KSAhPT0gY29udGVudCB8fCBzdGFydEF0dHJWYWx1ZSA9PT0gdmFsdWUpIHtcbiAgICAgICAgICAgIC8vIEVpdGhlciB0aGlzIGZvcm1hdCBpcyBvdmVyd3JpdHRlbiBvciBpdCBpcyBub3QgbmVjZXNzYXJ5IGJlY2F1c2UgdGhlIGF0dHJpYnV0ZSBhbHJlYWR5IGV4aXN0ZWQuXG4gICAgICAgICAgICBzdGFydC5kZWxldGUodHJhbnNhY3Rpb24pXG4gICAgICAgICAgICBjbGVhbnVwcysrXG4gICAgICAgICAgICBpZiAoIXJlYWNoZWRDdXJyICYmIChjdXJyQXR0cmlidXRlcy5nZXQoa2V5KSA/PyBudWxsKSA9PT0gdmFsdWUgJiYgc3RhcnRBdHRyVmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgIGlmIChzdGFydEF0dHJWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGN1cnJBdHRyaWJ1dGVzLmRlbGV0ZShrZXkpXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY3VyckF0dHJpYnV0ZXMuc2V0KGtleSwgc3RhcnRBdHRyVmFsdWUpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFyZWFjaGVkQ3VyciAmJiAhc3RhcnQuZGVsZXRlZCkge1xuICAgICAgICAgICAgdXBkYXRlQ3VycmVudEF0dHJpYnV0ZXMoY3VyckF0dHJpYnV0ZXMsIC8qKiBAdHlwZSB7Q29udGVudEZvcm1hdH0gKi8gKGNvbnRlbnQpKVxuICAgICAgICAgIH1cbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHN0YXJ0ID0gLyoqIEB0eXBlIHtJdGVtfSAqLyAoc3RhcnQucmlnaHQpXG4gIH1cbiAgcmV0dXJuIGNsZWFudXBzXG59XG5cbi8qKlxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEBwYXJhbSB7SXRlbSB8IG51bGx9IGl0ZW1cbiAqL1xuY29uc3QgY2xlYW51cENvbnRleHRsZXNzRm9ybWF0dGluZ0dhcCA9ICh0cmFuc2FjdGlvbiwgaXRlbSkgPT4ge1xuICAvLyBpdGVyYXRlIHVudGlsIGl0ZW0ucmlnaHQgaXMgbnVsbCBvciBjb250ZW50XG4gIHdoaWxlIChpdGVtICYmIGl0ZW0ucmlnaHQgJiYgKGl0ZW0ucmlnaHQuZGVsZXRlZCB8fCAhaXRlbS5yaWdodC5jb3VudGFibGUpKSB7XG4gICAgaXRlbSA9IGl0ZW0ucmlnaHRcbiAgfVxuICBjb25zdCBhdHRycyA9IG5ldyBTZXQoKVxuICAvLyBpdGVyYXRlIGJhY2sgdW50aWwgYSBjb250ZW50IGl0ZW0gaXMgZm91bmRcbiAgd2hpbGUgKGl0ZW0gJiYgKGl0ZW0uZGVsZXRlZCB8fCAhaXRlbS5jb3VudGFibGUpKSB7XG4gICAgaWYgKCFpdGVtLmRlbGV0ZWQgJiYgaXRlbS5jb250ZW50LmNvbnN0cnVjdG9yID09PSBDb250ZW50Rm9ybWF0KSB7XG4gICAgICBjb25zdCBrZXkgPSAvKiogQHR5cGUge0NvbnRlbnRGb3JtYXR9ICovIChpdGVtLmNvbnRlbnQpLmtleVxuICAgICAgaWYgKGF0dHJzLmhhcyhrZXkpKSB7XG4gICAgICAgIGl0ZW0uZGVsZXRlKHRyYW5zYWN0aW9uKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXR0cnMuYWRkKGtleSlcbiAgICAgIH1cbiAgICB9XG4gICAgaXRlbSA9IGl0ZW0ubGVmdFxuICB9XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBpcyBleHBlcmltZW50YWwgYW5kIHN1YmplY3QgdG8gY2hhbmdlIC8gYmUgcmVtb3ZlZC5cbiAqXG4gKiBJZGVhbGx5LCB3ZSBkb24ndCBuZWVkIHRoaXMgZnVuY3Rpb24gYXQgYWxsLiBGb3JtYXR0aW5nIGF0dHJpYnV0ZXMgc2hvdWxkIGJlIGNsZWFuZWQgdXBcbiAqIGF1dG9tYXRpY2FsbHkgYWZ0ZXIgZWFjaCBjaGFuZ2UuIFRoaXMgZnVuY3Rpb24gaXRlcmF0ZXMgdHdpY2Ugb3ZlciB0aGUgY29tcGxldGUgWVRleHQgdHlwZVxuICogYW5kIHJlbW92ZXMgdW5uZWNlc3NhcnkgZm9ybWF0dGluZyBhdHRyaWJ1dGVzLiBUaGlzIGlzIGFsc28gaGVscGZ1bCBmb3IgdGVzdGluZy5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHdvbid0IGJlIGV4cG9ydGVkIGFueW1vcmUgYXMgc29vbiBhcyB0aGVyZSBpcyBjb25maWRlbmNlIHRoYXQgdGhlIFlUZXh0IHR5cGUgd29ya3MgYXMgaW50ZW5kZWQuXG4gKlxuICogQHBhcmFtIHtZVGV4dH0gdHlwZVxuICogQHJldHVybiB7bnVtYmVyfSBIb3cgbWFueSBmb3JtYXR0aW5nIGF0dHJpYnV0ZXMgaGF2ZSBiZWVuIGNsZWFuZWQgdXAuXG4gKi9cbmV4cG9ydCBjb25zdCBjbGVhbnVwWVRleHRGb3JtYXR0aW5nID0gdHlwZSA9PiB7XG4gIGxldCByZXMgPSAwXG4gIHRyYW5zYWN0KC8qKiBAdHlwZSB7RG9jfSAqLyAodHlwZS5kb2MpLCB0cmFuc2FjdGlvbiA9PiB7XG4gICAgbGV0IHN0YXJ0ID0gLyoqIEB0eXBlIHtJdGVtfSAqLyAodHlwZS5fc3RhcnQpXG4gICAgbGV0IGVuZCA9IHR5cGUuX3N0YXJ0XG4gICAgbGV0IHN0YXJ0QXR0cmlidXRlcyA9IG1hcC5jcmVhdGUoKVxuICAgIGNvbnN0IGN1cnJlbnRBdHRyaWJ1dGVzID0gbWFwLmNvcHkoc3RhcnRBdHRyaWJ1dGVzKVxuICAgIHdoaWxlIChlbmQpIHtcbiAgICAgIGlmIChlbmQuZGVsZXRlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgc3dpdGNoIChlbmQuY29udGVudC5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgIGNhc2UgQ29udGVudEZvcm1hdDpcbiAgICAgICAgICAgIHVwZGF0ZUN1cnJlbnRBdHRyaWJ1dGVzKGN1cnJlbnRBdHRyaWJ1dGVzLCAvKiogQHR5cGUge0NvbnRlbnRGb3JtYXR9ICovIChlbmQuY29udGVudCkpXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXMgKz0gY2xlYW51cEZvcm1hdHRpbmdHYXAodHJhbnNhY3Rpb24sIHN0YXJ0LCBlbmQsIHN0YXJ0QXR0cmlidXRlcywgY3VycmVudEF0dHJpYnV0ZXMpXG4gICAgICAgICAgICBzdGFydEF0dHJpYnV0ZXMgPSBtYXAuY29weShjdXJyZW50QXR0cmlidXRlcylcbiAgICAgICAgICAgIHN0YXJ0ID0gZW5kXG4gICAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBlbmQgPSBlbmQucmlnaHRcbiAgICB9XG4gIH0pXG4gIHJldHVybiByZXNcbn1cblxuLyoqXG4gKiBUaGlzIHdpbGwgYmUgY2FsbGVkIGJ5IHRoZSB0cmFuc2FjdGlvbiBvbmNlIHRoZSBldmVudCBoYW5kbGVycyBhcmUgY2FsbGVkIHRvIHBvdGVudGlhbGx5IGNsZWFudXBcbiAqIGZvcm1hdHRpbmcgYXR0cmlidXRlcy5cbiAqXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICovXG5leHBvcnQgY29uc3QgY2xlYW51cFlUZXh0QWZ0ZXJUcmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uID0+IHtcbiAgLyoqXG4gICAqIEB0eXBlIHtTZXQ8WVRleHQ+fVxuICAgKi9cbiAgY29uc3QgbmVlZEZ1bGxDbGVhbnVwID0gbmV3IFNldCgpXG4gIC8vIGNoZWNrIGlmIGFub3RoZXIgZm9ybWF0dGluZyBpdGVtIHdhcyBpbnNlcnRlZFxuICBjb25zdCBkb2MgPSB0cmFuc2FjdGlvbi5kb2NcbiAgZm9yIChjb25zdCBbY2xpZW50LCBhZnRlckNsb2NrXSBvZiB0cmFuc2FjdGlvbi5hZnRlclN0YXRlLmVudHJpZXMoKSkge1xuICAgIGNvbnN0IGNsb2NrID0gdHJhbnNhY3Rpb24uYmVmb3JlU3RhdGUuZ2V0KGNsaWVudCkgfHwgMFxuICAgIGlmIChhZnRlckNsb2NrID09PSBjbG9jaykge1xuICAgICAgY29udGludWVcbiAgICB9XG4gICAgaXRlcmF0ZVN0cnVjdHModHJhbnNhY3Rpb24sIC8qKiBAdHlwZSB7QXJyYXk8SXRlbXxHQz59ICovIChkb2Muc3RvcmUuY2xpZW50cy5nZXQoY2xpZW50KSksIGNsb2NrLCBhZnRlckNsb2NrLCBpdGVtID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgIWl0ZW0uZGVsZXRlZCAmJiAvKiogQHR5cGUge0l0ZW19ICovIChpdGVtKS5jb250ZW50LmNvbnN0cnVjdG9yID09PSBDb250ZW50Rm9ybWF0ICYmIGl0ZW0uY29uc3RydWN0b3IgIT09IEdDXG4gICAgICApIHtcbiAgICAgICAgbmVlZEZ1bGxDbGVhbnVwLmFkZCgvKiogQHR5cGUge2FueX0gKi8gKGl0ZW0pLnBhcmVudClcbiAgICAgIH1cbiAgICB9KVxuICB9XG4gIC8vIGNsZWFudXAgaW4gYSBuZXcgdHJhbnNhY3Rpb25cbiAgdHJhbnNhY3QoZG9jLCAodCkgPT4ge1xuICAgIGl0ZXJhdGVEZWxldGVkU3RydWN0cyh0cmFuc2FjdGlvbiwgdHJhbnNhY3Rpb24uZGVsZXRlU2V0LCBpdGVtID0+IHtcbiAgICAgIGlmIChpdGVtIGluc3RhbmNlb2YgR0MgfHwgISgvKiogQHR5cGUge1lUZXh0fSAqLyAoaXRlbS5wYXJlbnQpLl9oYXNGb3JtYXR0aW5nKSB8fCBuZWVkRnVsbENsZWFudXAuaGFzKC8qKiBAdHlwZSB7WVRleHR9ICovIChpdGVtLnBhcmVudCkpKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgY29uc3QgcGFyZW50ID0gLyoqIEB0eXBlIHtZVGV4dH0gKi8gKGl0ZW0ucGFyZW50KVxuICAgICAgaWYgKGl0ZW0uY29udGVudC5jb25zdHJ1Y3RvciA9PT0gQ29udGVudEZvcm1hdCkge1xuICAgICAgICBuZWVkRnVsbENsZWFudXAuYWRkKHBhcmVudClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElmIG5vIGZvcm1hdHRpbmcgYXR0cmlidXRlIHdhcyBpbnNlcnRlZCBvciBkZWxldGVkLCB3ZSBjYW4gbWFrZSBkdWUgd2l0aCBjb250ZXh0bGVzc1xuICAgICAgICAvLyBmb3JtYXR0aW5nIGNsZWFudXBzLlxuICAgICAgICAvLyBDb250ZXh0bGVzczogaXQgaXMgbm90IG5lY2Vzc2FyeSB0byBjb21wdXRlIGN1cnJlbnRBdHRyaWJ1dGVzIGZvciB0aGUgYWZmZWN0ZWQgcG9zaXRpb24uXG4gICAgICAgIGNsZWFudXBDb250ZXh0bGVzc0Zvcm1hdHRpbmdHYXAodCwgaXRlbSlcbiAgICAgIH1cbiAgICB9KVxuICAgIC8vIElmIGEgZm9ybWF0dGluZyBpdGVtIHdhcyBpbnNlcnRlZCwgd2Ugc2ltcGx5IGNsZWFuIHRoZSB3aG9sZSB0eXBlLlxuICAgIC8vIFdlIG5lZWQgdG8gY29tcHV0ZSBjdXJyZW50QXR0cmlidXRlcyBmb3IgdGhlIGN1cnJlbnQgcG9zaXRpb24gYW55d2F5LlxuICAgIGZvciAoY29uc3QgeVRleHQgb2YgbmVlZEZ1bGxDbGVhbnVwKSB7XG4gICAgICBjbGVhbnVwWVRleHRGb3JtYXR0aW5nKHlUZXh0KVxuICAgIH1cbiAgfSlcbn1cblxuLyoqXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICogQHBhcmFtIHtJdGVtVGV4dExpc3RQb3NpdGlvbn0gY3VyclBvc1xuICogQHBhcmFtIHtudW1iZXJ9IGxlbmd0aFxuICogQHJldHVybiB7SXRlbVRleHRMaXN0UG9zaXRpb259XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5jb25zdCBkZWxldGVUZXh0ID0gKHRyYW5zYWN0aW9uLCBjdXJyUG9zLCBsZW5ndGgpID0+IHtcbiAgY29uc3Qgc3RhcnRMZW5ndGggPSBsZW5ndGhcbiAgY29uc3Qgc3RhcnRBdHRycyA9IG1hcC5jb3B5KGN1cnJQb3MuY3VycmVudEF0dHJpYnV0ZXMpXG4gIGNvbnN0IHN0YXJ0ID0gY3VyclBvcy5yaWdodFxuICB3aGlsZSAobGVuZ3RoID4gMCAmJiBjdXJyUG9zLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgaWYgKGN1cnJQb3MucmlnaHQuZGVsZXRlZCA9PT0gZmFsc2UpIHtcbiAgICAgIHN3aXRjaCAoY3VyclBvcy5yaWdodC5jb250ZW50LmNvbnN0cnVjdG9yKSB7XG4gICAgICAgIGNhc2UgQ29udGVudFR5cGU6XG4gICAgICAgIGNhc2UgQ29udGVudEVtYmVkOlxuICAgICAgICBjYXNlIENvbnRlbnRTdHJpbmc6XG4gICAgICAgICAgaWYgKGxlbmd0aCA8IGN1cnJQb3MucmlnaHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBnZXRJdGVtQ2xlYW5TdGFydCh0cmFuc2FjdGlvbiwgY3JlYXRlSUQoY3VyclBvcy5yaWdodC5pZC5jbGllbnQsIGN1cnJQb3MucmlnaHQuaWQuY2xvY2sgKyBsZW5ndGgpKVxuICAgICAgICAgIH1cbiAgICAgICAgICBsZW5ndGggLT0gY3VyclBvcy5yaWdodC5sZW5ndGhcbiAgICAgICAgICBjdXJyUG9zLnJpZ2h0LmRlbGV0ZSh0cmFuc2FjdGlvbilcbiAgICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgICBjdXJyUG9zLmZvcndhcmQoKVxuICB9XG4gIGlmIChzdGFydCkge1xuICAgIGNsZWFudXBGb3JtYXR0aW5nR2FwKHRyYW5zYWN0aW9uLCBzdGFydCwgY3VyclBvcy5yaWdodCwgc3RhcnRBdHRycywgY3VyclBvcy5jdXJyZW50QXR0cmlidXRlcylcbiAgfVxuICBjb25zdCBwYXJlbnQgPSAvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAoLyoqIEB0eXBlIHtJdGVtfSAqLyAoY3VyclBvcy5sZWZ0IHx8IGN1cnJQb3MucmlnaHQpLnBhcmVudClcbiAgaWYgKHBhcmVudC5fc2VhcmNoTWFya2VyKSB7XG4gICAgdXBkYXRlTWFya2VyQ2hhbmdlcyhwYXJlbnQuX3NlYXJjaE1hcmtlciwgY3VyclBvcy5pbmRleCwgLXN0YXJ0TGVuZ3RoICsgbGVuZ3RoKVxuICB9XG4gIHJldHVybiBjdXJyUG9zXG59XG5cbi8qKlxuICogVGhlIFF1aWxsIERlbHRhIGZvcm1hdCByZXByZXNlbnRzIGNoYW5nZXMgb24gYSB0ZXh0IGRvY3VtZW50IHdpdGhcbiAqIGZvcm1hdHRpbmcgaW5mb3JtYXRpb24uIEZvciBtb3JlIGluZm9ybWF0aW9uIHZpc2l0IHtAbGluayBodHRwczovL3F1aWxsanMuY29tL2RvY3MvZGVsdGEvfFF1aWxsIERlbHRhfVxuICpcbiAqIEBleGFtcGxlXG4gKiAgIHtcbiAqICAgICBvcHM6IFtcbiAqICAgICAgIHsgaW5zZXJ0OiAnR2FuZGFsZicsIGF0dHJpYnV0ZXM6IHsgYm9sZDogdHJ1ZSB9IH0sXG4gKiAgICAgICB7IGluc2VydDogJyB0aGUgJyB9LFxuICogICAgICAgeyBpbnNlcnQ6ICdHcmV5JywgYXR0cmlidXRlczogeyBjb2xvcjogJyNjY2NjY2MnIH0gfVxuICogICAgIF1cbiAqICAgfVxuICpcbiAqL1xuXG4vKipcbiAgKiBBdHRyaWJ1dGVzIHRoYXQgY2FuIGJlIGFzc2lnbmVkIHRvIGEgc2VsZWN0aW9uIG9mIHRleHQuXG4gICpcbiAgKiBAZXhhbXBsZVxuICAqICAge1xuICAqICAgICBib2xkOiB0cnVlLFxuICAqICAgICBmb250LXNpemU6ICc0MHB4J1xuICAqICAgfVxuICAqXG4gICogQHR5cGVkZWYge09iamVjdH0gVGV4dEF0dHJpYnV0ZXNcbiAgKi9cblxuLyoqXG4gKiBAZXh0ZW5kcyBZRXZlbnQ8WVRleHQ+XG4gKiBFdmVudCB0aGF0IGRlc2NyaWJlcyB0aGUgY2hhbmdlcyBvbiBhIFlUZXh0IHR5cGUuXG4gKi9cbmV4cG9ydCBjbGFzcyBZVGV4dEV2ZW50IGV4dGVuZHMgWUV2ZW50IHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7WVRleHR9IHl0ZXh0XG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7U2V0PGFueT59IHN1YnMgVGhlIGtleXMgdGhhdCBjaGFuZ2VkXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoeXRleHQsIHRyYW5zYWN0aW9uLCBzdWJzKSB7XG4gICAgc3VwZXIoeXRleHQsIHRyYW5zYWN0aW9uKVxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGNoaWxkcmVuIGNoYW5nZWQuXG4gICAgICogQHR5cGUge0Jvb2xlYW59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICB0aGlzLmNoaWxkTGlzdENoYW5nZWQgPSBmYWxzZVxuICAgIC8qKlxuICAgICAqIFNldCBvZiBhbGwgY2hhbmdlZCBhdHRyaWJ1dGVzLlxuICAgICAqIEB0eXBlIHtTZXQ8c3RyaW5nPn1cbiAgICAgKi9cbiAgICB0aGlzLmtleXNDaGFuZ2VkID0gbmV3IFNldCgpXG4gICAgc3Vicy5mb3JFYWNoKChzdWIpID0+IHtcbiAgICAgIGlmIChzdWIgPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5jaGlsZExpc3RDaGFuZ2VkID0gdHJ1ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5rZXlzQ2hhbmdlZC5hZGQoc3ViKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHR5cGUge3thZGRlZDpTZXQ8SXRlbT4sZGVsZXRlZDpTZXQ8SXRlbT4sa2V5czpNYXA8c3RyaW5nLHthY3Rpb246J2FkZCd8J3VwZGF0ZSd8J2RlbGV0ZScsb2xkVmFsdWU6YW55fT4sZGVsdGE6QXJyYXk8e2luc2VydD86QXJyYXk8YW55PnxzdHJpbmcsIGRlbGV0ZT86bnVtYmVyLCByZXRhaW4/Om51bWJlcn0+fX1cbiAgICovXG4gIGdldCBjaGFuZ2VzICgpIHtcbiAgICBpZiAodGhpcy5fY2hhbmdlcyA9PT0gbnVsbCkge1xuICAgICAgLyoqXG4gICAgICAgKiBAdHlwZSB7e2FkZGVkOlNldDxJdGVtPixkZWxldGVkOlNldDxJdGVtPixrZXlzOk1hcDxzdHJpbmcse2FjdGlvbjonYWRkJ3wndXBkYXRlJ3wnZGVsZXRlJyxvbGRWYWx1ZTphbnl9PixkZWx0YTpBcnJheTx7aW5zZXJ0PzpBcnJheTxhbnk+fHN0cmluZ3xBYnN0cmFjdFR5cGU8YW55PnxvYmplY3QsIGRlbGV0ZT86bnVtYmVyLCByZXRhaW4/Om51bWJlcn0+fX1cbiAgICAgICAqL1xuICAgICAgY29uc3QgY2hhbmdlcyA9IHtcbiAgICAgICAga2V5czogdGhpcy5rZXlzLFxuICAgICAgICBkZWx0YTogdGhpcy5kZWx0YSxcbiAgICAgICAgYWRkZWQ6IG5ldyBTZXQoKSxcbiAgICAgICAgZGVsZXRlZDogbmV3IFNldCgpXG4gICAgICB9XG4gICAgICB0aGlzLl9jaGFuZ2VzID0gY2hhbmdlc1xuICAgIH1cbiAgICByZXR1cm4gLyoqIEB0eXBlIHthbnl9ICovICh0aGlzLl9jaGFuZ2VzKVxuICB9XG5cbiAgLyoqXG4gICAqIENvbXB1dGUgdGhlIGNoYW5nZXMgaW4gdGhlIGRlbHRhIGZvcm1hdC5cbiAgICogQSB7QGxpbmsgaHR0cHM6Ly9xdWlsbGpzLmNvbS9kb2NzL2RlbHRhL3xRdWlsbCBEZWx0YX0pIHRoYXQgcmVwcmVzZW50cyB0aGUgY2hhbmdlcyBvbiB0aGUgZG9jdW1lbnQuXG4gICAqXG4gICAqIEB0eXBlIHtBcnJheTx7aW5zZXJ0PzpzdHJpbmd8b2JqZWN0fEFic3RyYWN0VHlwZTxhbnk+LCBkZWxldGU/Om51bWJlciwgcmV0YWluPzpudW1iZXIsIGF0dHJpYnV0ZXM/OiBPYmplY3Q8c3RyaW5nLGFueT59Pn1cbiAgICpcbiAgICogQHB1YmxpY1xuICAgKi9cbiAgZ2V0IGRlbHRhICgpIHtcbiAgICBpZiAodGhpcy5fZGVsdGEgPT09IG51bGwpIHtcbiAgICAgIGNvbnN0IHkgPSAvKiogQHR5cGUge0RvY30gKi8gKHRoaXMudGFyZ2V0LmRvYylcbiAgICAgIC8qKlxuICAgICAgICogQHR5cGUge0FycmF5PHtpbnNlcnQ/OnN0cmluZ3xvYmplY3R8QWJzdHJhY3RUeXBlPGFueT4sIGRlbGV0ZT86bnVtYmVyLCByZXRhaW4/Om51bWJlciwgYXR0cmlidXRlcz86IE9iamVjdDxzdHJpbmcsYW55Pn0+fVxuICAgICAgICovXG4gICAgICBjb25zdCBkZWx0YSA9IFtdXG4gICAgICB0cmFuc2FjdCh5LCB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRBdHRyaWJ1dGVzID0gbmV3IE1hcCgpIC8vIHNhdmVzIGFsbCBjdXJyZW50IGF0dHJpYnV0ZXMgZm9yIGluc2VydFxuICAgICAgICBjb25zdCBvbGRBdHRyaWJ1dGVzID0gbmV3IE1hcCgpXG4gICAgICAgIGxldCBpdGVtID0gdGhpcy50YXJnZXQuX3N0YXJ0XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAdHlwZSB7c3RyaW5nP31cbiAgICAgICAgICovXG4gICAgICAgIGxldCBhY3Rpb24gPSBudWxsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAdHlwZSB7T2JqZWN0PHN0cmluZyxhbnk+fVxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgYXR0cmlidXRlcyA9IHt9IC8vIGNvdW50cyBhZGRlZCBvciByZW1vdmVkIG5ldyBhdHRyaWJ1dGVzIGZvciByZXRhaW5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEB0eXBlIHtzdHJpbmd8b2JqZWN0fVxuICAgICAgICAgKi9cbiAgICAgICAgbGV0IGluc2VydCA9ICcnXG4gICAgICAgIGxldCByZXRhaW4gPSAwXG4gICAgICAgIGxldCBkZWxldGVMZW4gPSAwXG4gICAgICAgIGNvbnN0IGFkZE9wID0gKCkgPT4ge1xuICAgICAgICAgIGlmIChhY3Rpb24gIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQHR5cGUge2FueX1cbiAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgbGV0IG9wID0gbnVsbFxuICAgICAgICAgICAgc3dpdGNoIChhY3Rpb24pIHtcbiAgICAgICAgICAgICAgY2FzZSAnZGVsZXRlJzpcbiAgICAgICAgICAgICAgICBpZiAoZGVsZXRlTGVuID4gMCkge1xuICAgICAgICAgICAgICAgICAgb3AgPSB7IGRlbGV0ZTogZGVsZXRlTGVuIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlTGVuID0gMFxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIGNhc2UgJ2luc2VydCc6XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnNlcnQgPT09ICdvYmplY3QnIHx8IGluc2VydC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICBvcCA9IHsgaW5zZXJ0IH1cbiAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50QXR0cmlidXRlcy5zaXplID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBvcC5hdHRyaWJ1dGVzID0ge31cbiAgICAgICAgICAgICAgICAgICAgY3VycmVudEF0dHJpYnV0ZXMuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3AuYXR0cmlidXRlc1trZXldID0gdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGluc2VydCA9ICcnXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgY2FzZSAncmV0YWluJzpcbiAgICAgICAgICAgICAgICBpZiAocmV0YWluID4gMCkge1xuICAgICAgICAgICAgICAgICAgb3AgPSB7IHJldGFpbiB9XG4gICAgICAgICAgICAgICAgICBpZiAoIW9iamVjdC5pc0VtcHR5KGF0dHJpYnV0ZXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIG9wLmF0dHJpYnV0ZXMgPSBvYmplY3QuYXNzaWduKHt9LCBhdHRyaWJ1dGVzKVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXRhaW4gPSAwXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChvcCkgZGVsdGEucHVzaChvcClcbiAgICAgICAgICAgIGFjdGlvbiA9IG51bGxcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGl0ZW0gIT09IG51bGwpIHtcbiAgICAgICAgICBzd2l0Y2ggKGl0ZW0uY29udGVudC5jb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgY2FzZSBDb250ZW50VHlwZTpcbiAgICAgICAgICAgIGNhc2UgQ29udGVudEVtYmVkOlxuICAgICAgICAgICAgICBpZiAodGhpcy5hZGRzKGl0ZW0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmRlbGV0ZXMoaXRlbSkpIHtcbiAgICAgICAgICAgICAgICAgIGFkZE9wKClcbiAgICAgICAgICAgICAgICAgIGFjdGlvbiA9ICdpbnNlcnQnXG4gICAgICAgICAgICAgICAgICBpbnNlcnQgPSBpdGVtLmNvbnRlbnQuZ2V0Q29udGVudCgpWzBdXG4gICAgICAgICAgICAgICAgICBhZGRPcCgpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZGVsZXRlcyhpdGVtKSkge1xuICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gIT09ICdkZWxldGUnKSB7XG4gICAgICAgICAgICAgICAgICBhZGRPcCgpXG4gICAgICAgICAgICAgICAgICBhY3Rpb24gPSAnZGVsZXRlJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkZWxldGVMZW4gKz0gMVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpdGVtLmRlbGV0ZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uICE9PSAncmV0YWluJykge1xuICAgICAgICAgICAgICAgICAgYWRkT3AoKVxuICAgICAgICAgICAgICAgICAgYWN0aW9uID0gJ3JldGFpbidcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0YWluICs9IDFcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBDb250ZW50U3RyaW5nOlxuICAgICAgICAgICAgICBpZiAodGhpcy5hZGRzKGl0ZW0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmRlbGV0ZXMoaXRlbSkpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gIT09ICdpbnNlcnQnKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZE9wKClcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uID0gJ2luc2VydCdcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGluc2VydCArPSAvKiogQHR5cGUge0NvbnRlbnRTdHJpbmd9ICovIChpdGVtLmNvbnRlbnQpLnN0clxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRlbGV0ZXMoaXRlbSkpIHtcbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uICE9PSAnZGVsZXRlJykge1xuICAgICAgICAgICAgICAgICAgYWRkT3AoKVxuICAgICAgICAgICAgICAgICAgYWN0aW9uID0gJ2RlbGV0ZSdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlTGVuICs9IGl0ZW0ubGVuZ3RoXG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWl0ZW0uZGVsZXRlZCkge1xuICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gIT09ICdyZXRhaW4nKSB7XG4gICAgICAgICAgICAgICAgICBhZGRPcCgpXG4gICAgICAgICAgICAgICAgICBhY3Rpb24gPSAncmV0YWluJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXRhaW4gKz0gaXRlbS5sZW5ndGhcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgY2FzZSBDb250ZW50Rm9ybWF0OiB7XG4gICAgICAgICAgICAgIGNvbnN0IHsga2V5LCB2YWx1ZSB9ID0gLyoqIEB0eXBlIHtDb250ZW50Rm9ybWF0fSAqLyAoaXRlbS5jb250ZW50KVxuICAgICAgICAgICAgICBpZiAodGhpcy5hZGRzKGl0ZW0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmRlbGV0ZXMoaXRlbSkpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGN1clZhbCA9IGN1cnJlbnRBdHRyaWJ1dGVzLmdldChrZXkpID8/IG51bGxcbiAgICAgICAgICAgICAgICAgIGlmICghZXF1YWxBdHRycyhjdXJWYWwsIHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoYWN0aW9uID09PSAncmV0YWluJykge1xuICAgICAgICAgICAgICAgICAgICAgIGFkZE9wKClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoZXF1YWxBdHRycyh2YWx1ZSwgKG9sZEF0dHJpYnV0ZXMuZ2V0KGtleSkgPz8gbnVsbCkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIGF0dHJpYnV0ZXNba2V5XVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNba2V5XSA9IHZhbHVlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgaXRlbS5kZWxldGUodHJhbnNhY3Rpb24pXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZGVsZXRlcyhpdGVtKSkge1xuICAgICAgICAgICAgICAgIG9sZEF0dHJpYnV0ZXMuc2V0KGtleSwgdmFsdWUpXG4gICAgICAgICAgICAgICAgY29uc3QgY3VyVmFsID0gY3VycmVudEF0dHJpYnV0ZXMuZ2V0KGtleSkgPz8gbnVsbFxuICAgICAgICAgICAgICAgIGlmICghZXF1YWxBdHRycyhjdXJWYWwsIHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgaWYgKGFjdGlvbiA9PT0gJ3JldGFpbicpIHtcbiAgICAgICAgICAgICAgICAgICAgYWRkT3AoKVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc1trZXldID0gY3VyVmFsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFpdGVtLmRlbGV0ZWQpIHtcbiAgICAgICAgICAgICAgICBvbGRBdHRyaWJ1dGVzLnNldChrZXksIHZhbHVlKVxuICAgICAgICAgICAgICAgIGNvbnN0IGF0dHIgPSBhdHRyaWJ1dGVzW2tleV1cbiAgICAgICAgICAgICAgICBpZiAoYXR0ciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICBpZiAoIWVxdWFsQXR0cnMoYXR0ciwgdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhY3Rpb24gPT09ICdyZXRhaW4nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgYWRkT3AoKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBhdHRyaWJ1dGVzW2tleV1cbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzW2tleV0gPSB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGF0dHIgIT09IG51bGwpIHsgLy8gdGhpcyB3aWxsIGJlIGNsZWFuZWQgdXAgYXV0b21hdGljYWxseSBieSB0aGUgY29udGV4dGxlc3MgY2xlYW51cCBmdW5jdGlvblxuICAgICAgICAgICAgICAgICAgICBpdGVtLmRlbGV0ZSh0cmFuc2FjdGlvbilcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKCFpdGVtLmRlbGV0ZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uID09PSAnaW5zZXJ0Jykge1xuICAgICAgICAgICAgICAgICAgYWRkT3AoKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB1cGRhdGVDdXJyZW50QXR0cmlidXRlcyhjdXJyZW50QXR0cmlidXRlcywgLyoqIEB0eXBlIHtDb250ZW50Rm9ybWF0fSAqLyAoaXRlbS5jb250ZW50KSlcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpdGVtID0gaXRlbS5yaWdodFxuICAgICAgICB9XG4gICAgICAgIGFkZE9wKClcbiAgICAgICAgd2hpbGUgKGRlbHRhLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjb25zdCBsYXN0T3AgPSBkZWx0YVtkZWx0YS5sZW5ndGggLSAxXVxuICAgICAgICAgIGlmIChsYXN0T3AucmV0YWluICE9PSB1bmRlZmluZWQgJiYgbGFzdE9wLmF0dHJpYnV0ZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgLy8gcmV0YWluIGRlbHRhJ3MgaWYgdGhleSBkb24ndCBhc3NpZ24gYXR0cmlidXRlc1xuICAgICAgICAgICAgZGVsdGEucG9wKClcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICB0aGlzLl9kZWx0YSA9IGRlbHRhXG4gICAgfVxuICAgIHJldHVybiAvKiogQHR5cGUge2FueX0gKi8gKHRoaXMuX2RlbHRhKVxuICB9XG59XG5cbi8qKlxuICogVHlwZSB0aGF0IHJlcHJlc2VudHMgdGV4dCB3aXRoIGZvcm1hdHRpbmcgaW5mb3JtYXRpb24uXG4gKlxuICogVGhpcyB0eXBlIHJlcGxhY2VzIHktcmljaHRleHQgYXMgdGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBhYmxlIHRvIGhhbmRsZVxuICogYmxvY2sgZm9ybWF0cyAoZm9ybWF0IGluZm9ybWF0aW9uIG9uIGEgcGFyYWdyYXBoKSwgZW1iZWRzIChjb21wbGV4IGVsZW1lbnRzXG4gKiBsaWtlIHBpY3R1cmVzIGFuZCB2aWRlb3MpLCBhbmQgdGV4dCBmb3JtYXRzICgqKmJvbGQqKiwgKml0YWxpYyopLlxuICpcbiAqIEBleHRlbmRzIEFic3RyYWN0VHlwZTxZVGV4dEV2ZW50PlxuICovXG5leHBvcnQgY2xhc3MgWVRleHQgZXh0ZW5kcyBBYnN0cmFjdFR5cGUge1xuICAvKipcbiAgICogQHBhcmFtIHtTdHJpbmd9IFtzdHJpbmddIFRoZSBpbml0aWFsIHZhbHVlIG9mIHRoZSBZVGV4dC5cbiAgICovXG4gIGNvbnN0cnVjdG9yIChzdHJpbmcpIHtcbiAgICBzdXBlcigpXG4gICAgLyoqXG4gICAgICogQXJyYXkgb2YgcGVuZGluZyBvcGVyYXRpb25zIG9uIHRoaXMgdHlwZVxuICAgICAqIEB0eXBlIHtBcnJheTxmdW5jdGlvbigpOnZvaWQ+P31cbiAgICAgKi9cbiAgICB0aGlzLl9wZW5kaW5nID0gc3RyaW5nICE9PSB1bmRlZmluZWQgPyBbKCkgPT4gdGhpcy5pbnNlcnQoMCwgc3RyaW5nKV0gOiBbXVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtBcnJheTxBcnJheVNlYXJjaE1hcmtlcj58bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLl9zZWFyY2hNYXJrZXIgPSBbXVxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhpcyBZVGV4dCBjb250YWlucyBmb3JtYXR0aW5nIGF0dHJpYnV0ZXMuXG4gICAgICogVGhpcyBmbGFnIGlzIHVwZGF0ZWQgd2hlbiBhIGZvcm1hdHRpbmcgaXRlbSBpcyBpbnRlZ3JhdGVkIChzZWUgQ29udGVudEZvcm1hdC5pbnRlZ3JhdGUpXG4gICAgICovXG4gICAgdGhpcy5faGFzRm9ybWF0dGluZyA9IGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogTnVtYmVyIG9mIGNoYXJhY3RlcnMgb2YgdGhpcyB0ZXh0IHR5cGUuXG4gICAqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICBnZXQgbGVuZ3RoICgpIHtcbiAgICB0aGlzLmRvYyA/PyB3YXJuUHJlbWF0dXJlQWNjZXNzKClcbiAgICByZXR1cm4gdGhpcy5fbGVuZ3RoXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtEb2N9IHlcbiAgICogQHBhcmFtIHtJdGVtfSBpdGVtXG4gICAqL1xuICBfaW50ZWdyYXRlICh5LCBpdGVtKSB7XG4gICAgc3VwZXIuX2ludGVncmF0ZSh5LCBpdGVtKVxuICAgIHRyeSB7XG4gICAgICAvKiogQHR5cGUge0FycmF5PGZ1bmN0aW9uPn0gKi8gKHRoaXMuX3BlbmRpbmcpLmZvckVhY2goZiA9PiBmKCkpXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcihlKVxuICAgIH1cbiAgICB0aGlzLl9wZW5kaW5nID0gbnVsbFxuICB9XG5cbiAgX2NvcHkgKCkge1xuICAgIHJldHVybiBuZXcgWVRleHQoKVxuICB9XG5cbiAgLyoqXG4gICAqIE1ha2VzIGEgY29weSBvZiB0aGlzIGRhdGEgdHlwZSB0aGF0IGNhbiBiZSBpbmNsdWRlZCBzb21ld2hlcmUgZWxzZS5cbiAgICpcbiAgICogTm90ZSB0aGF0IHRoZSBjb250ZW50IGlzIG9ubHkgcmVhZGFibGUgX2FmdGVyXyBpdCBoYXMgYmVlbiBpbmNsdWRlZCBzb21ld2hlcmUgaW4gdGhlIFlkb2MuXG4gICAqXG4gICAqIEByZXR1cm4ge1lUZXh0fVxuICAgKi9cbiAgY2xvbmUgKCkge1xuICAgIGNvbnN0IHRleHQgPSBuZXcgWVRleHQoKVxuICAgIHRleHQuYXBwbHlEZWx0YSh0aGlzLnRvRGVsdGEoKSlcbiAgICByZXR1cm4gdGV4dFxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgWVRleHRFdmVudCBhbmQgY2FsbHMgb2JzZXJ2ZXJzLlxuICAgKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge1NldDxudWxsfHN0cmluZz59IHBhcmVudFN1YnMgS2V5cyBjaGFuZ2VkIG9uIHRoaXMgdHlwZS4gYG51bGxgIGlmIGxpc3Qgd2FzIG1vZGlmaWVkLlxuICAgKi9cbiAgX2NhbGxPYnNlcnZlciAodHJhbnNhY3Rpb24sIHBhcmVudFN1YnMpIHtcbiAgICBzdXBlci5fY2FsbE9ic2VydmVyKHRyYW5zYWN0aW9uLCBwYXJlbnRTdWJzKVxuICAgIGNvbnN0IGV2ZW50ID0gbmV3IFlUZXh0RXZlbnQodGhpcywgdHJhbnNhY3Rpb24sIHBhcmVudFN1YnMpXG4gICAgY2FsbFR5cGVPYnNlcnZlcnModGhpcywgdHJhbnNhY3Rpb24sIGV2ZW50KVxuICAgIC8vIElmIGEgcmVtb3RlIGNoYW5nZSBoYXBwZW5lZCwgd2UgdHJ5IHRvIGNsZWFudXAgcG90ZW50aWFsIGZvcm1hdHRpbmcgZHVwbGljYXRlcy5cbiAgICBpZiAoIXRyYW5zYWN0aW9uLmxvY2FsICYmIHRoaXMuX2hhc0Zvcm1hdHRpbmcpIHtcbiAgICAgIHRyYW5zYWN0aW9uLl9uZWVkRm9ybWF0dGluZ0NsZWFudXAgPSB0cnVlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHVuZm9ybWF0dGVkIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIFlUZXh0IHR5cGUuXG4gICAqXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIHRvU3RyaW5nICgpIHtcbiAgICB0aGlzLmRvYyA/PyB3YXJuUHJlbWF0dXJlQWNjZXNzKClcbiAgICBsZXQgc3RyID0gJydcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7SXRlbXxudWxsfVxuICAgICAqL1xuICAgIGxldCBuID0gdGhpcy5fc3RhcnRcbiAgICB3aGlsZSAobiAhPT0gbnVsbCkge1xuICAgICAgaWYgKCFuLmRlbGV0ZWQgJiYgbi5jb3VudGFibGUgJiYgbi5jb250ZW50LmNvbnN0cnVjdG9yID09PSBDb250ZW50U3RyaW5nKSB7XG4gICAgICAgIHN0ciArPSAvKiogQHR5cGUge0NvbnRlbnRTdHJpbmd9ICovIChuLmNvbnRlbnQpLnN0clxuICAgICAgfVxuICAgICAgbiA9IG4ucmlnaHRcbiAgICB9XG4gICAgcmV0dXJuIHN0clxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHVuZm9ybWF0dGVkIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIFlUZXh0IHR5cGUuXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZ31cbiAgICogQHB1YmxpY1xuICAgKi9cbiAgdG9KU09OICgpIHtcbiAgICByZXR1cm4gdGhpcy50b1N0cmluZygpXG4gIH1cblxuICAvKipcbiAgICogQXBwbHkgYSB7QGxpbmsgRGVsdGF9IG9uIHRoaXMgc2hhcmVkIFlUZXh0IHR5cGUuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXk8YW55Pn0gZGVsdGEgVGhlIGNoYW5nZXMgdG8gYXBwbHkgb24gdGhpcyBlbGVtZW50LlxuICAgKiBAcGFyYW0ge29iamVjdH0gIG9wdHNcbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5zYW5pdGl6ZV0gU2FuaXRpemUgaW5wdXQgZGVsdGEuIFJlbW92ZXMgZW5kaW5nIG5ld2xpbmVzIGlmIHNldCB0byB0cnVlLlxuICAgKlxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICBhcHBseURlbHRhIChkZWx0YSwgeyBzYW5pdGl6ZSA9IHRydWUgfSA9IHt9KSB7XG4gICAgaWYgKHRoaXMuZG9jICE9PSBudWxsKSB7XG4gICAgICB0cmFuc2FjdCh0aGlzLmRvYywgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICBjb25zdCBjdXJyUG9zID0gbmV3IEl0ZW1UZXh0TGlzdFBvc2l0aW9uKG51bGwsIHRoaXMuX3N0YXJ0LCAwLCBuZXcgTWFwKCkpXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVsdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBvcCA9IGRlbHRhW2ldXG4gICAgICAgICAgaWYgKG9wLmluc2VydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAvLyBRdWlsbCBhc3N1bWVzIHRoYXQgdGhlIGNvbnRlbnQgc3RhcnRzIHdpdGggYW4gZW1wdHkgcGFyYWdyYXBoLlxuICAgICAgICAgICAgLy8gWWpzL1kuVGV4dCBhc3N1bWVzIHRoYXQgaXQgc3RhcnRzIGVtcHR5LiBXZSBhbHdheXMgaGlkZSB0aGF0XG4gICAgICAgICAgICAvLyB0aGVyZSBpcyBhIG5ld2xpbmUgYXQgdGhlIGVuZCBvZiB0aGUgY29udGVudC5cbiAgICAgICAgICAgIC8vIElmIHdlIG9taXQgdGhpcyBzdGVwLCBjbGllbnRzIHdpbGwgc2VlIGEgZGlmZmVyZW50IG51bWJlciBvZlxuICAgICAgICAgICAgLy8gcGFyYWdyYXBocywgYnV0IG5vdGhpbmcgYmFkIHdpbGwgaGFwcGVuLlxuICAgICAgICAgICAgY29uc3QgaW5zID0gKCFzYW5pdGl6ZSAmJiB0eXBlb2Ygb3AuaW5zZXJ0ID09PSAnc3RyaW5nJyAmJiBpID09PSBkZWx0YS5sZW5ndGggLSAxICYmIGN1cnJQb3MucmlnaHQgPT09IG51bGwgJiYgb3AuaW5zZXJ0LnNsaWNlKC0xKSA9PT0gJ1xcbicpID8gb3AuaW5zZXJ0LnNsaWNlKDAsIC0xKSA6IG9wLmluc2VydFxuICAgICAgICAgICAgaWYgKHR5cGVvZiBpbnMgIT09ICdzdHJpbmcnIHx8IGlucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIGluc2VydFRleHQodHJhbnNhY3Rpb24sIHRoaXMsIGN1cnJQb3MsIGlucywgb3AuYXR0cmlidXRlcyB8fCB7fSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKG9wLnJldGFpbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBmb3JtYXRUZXh0KHRyYW5zYWN0aW9uLCB0aGlzLCBjdXJyUG9zLCBvcC5yZXRhaW4sIG9wLmF0dHJpYnV0ZXMgfHwge30pXG4gICAgICAgICAgfSBlbHNlIGlmIChvcC5kZWxldGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgZGVsZXRlVGV4dCh0cmFuc2FjdGlvbiwgY3VyclBvcywgb3AuZGVsZXRlKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgLyoqIEB0eXBlIHtBcnJheTxmdW5jdGlvbj59ICovICh0aGlzLl9wZW5kaW5nKS5wdXNoKCgpID0+IHRoaXMuYXBwbHlEZWx0YShkZWx0YSkpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIERlbHRhIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgWVRleHQgdHlwZS5cbiAgICpcbiAgICogQHBhcmFtIHtTbmFwc2hvdH0gW3NuYXBzaG90XVxuICAgKiBAcGFyYW0ge1NuYXBzaG90fSBbcHJldlNuYXBzaG90XVxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKCdyZW1vdmVkJyB8ICdhZGRlZCcsIElEKTphbnl9IFtjb21wdXRlWUNoYW5nZV1cbiAgICogQHJldHVybiB7YW55fSBUaGUgRGVsdGEgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB0eXBlLlxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICB0b0RlbHRhIChzbmFwc2hvdCwgcHJldlNuYXBzaG90LCBjb21wdXRlWUNoYW5nZSkge1xuICAgIHRoaXMuZG9jID8/IHdhcm5QcmVtYXR1cmVBY2Nlc3MoKVxuICAgIC8qKlxuICAgICAqIEB0eXBle0FycmF5PGFueT59XG4gICAgICovXG4gICAgY29uc3Qgb3BzID0gW11cbiAgICBjb25zdCBjdXJyZW50QXR0cmlidXRlcyA9IG5ldyBNYXAoKVxuICAgIGNvbnN0IGRvYyA9IC8qKiBAdHlwZSB7RG9jfSAqLyAodGhpcy5kb2MpXG4gICAgbGV0IHN0ciA9ICcnXG4gICAgbGV0IG4gPSB0aGlzLl9zdGFydFxuICAgIGZ1bmN0aW9uIHBhY2tTdHIgKCkge1xuICAgICAgaWYgKHN0ci5sZW5ndGggPiAwKSB7XG4gICAgICAgIC8vIHBhY2sgc3RyIHdpdGggYXR0cmlidXRlcyB0byBvcHNcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLGFueT59XG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBhdHRyaWJ1dGVzID0ge31cbiAgICAgICAgbGV0IGFkZEF0dHJpYnV0ZXMgPSBmYWxzZVxuICAgICAgICBjdXJyZW50QXR0cmlidXRlcy5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgICAgYWRkQXR0cmlidXRlcyA9IHRydWVcbiAgICAgICAgICBhdHRyaWJ1dGVzW2tleV0gPSB2YWx1ZVxuICAgICAgICB9KVxuICAgICAgICAvKipcbiAgICAgICAgICogQHR5cGUge09iamVjdDxzdHJpbmcsYW55Pn1cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IG9wID0geyBpbnNlcnQ6IHN0ciB9XG4gICAgICAgIGlmIChhZGRBdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgb3AuYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXNcbiAgICAgICAgfVxuICAgICAgICBvcHMucHVzaChvcClcbiAgICAgICAgc3RyID0gJydcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgY29tcHV0ZURlbHRhID0gKCkgPT4ge1xuICAgICAgd2hpbGUgKG4gIT09IG51bGwpIHtcbiAgICAgICAgaWYgKGlzVmlzaWJsZShuLCBzbmFwc2hvdCkgfHwgKHByZXZTbmFwc2hvdCAhPT0gdW5kZWZpbmVkICYmIGlzVmlzaWJsZShuLCBwcmV2U25hcHNob3QpKSkge1xuICAgICAgICAgIHN3aXRjaCAobi5jb250ZW50LmNvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICBjYXNlIENvbnRlbnRTdHJpbmc6IHtcbiAgICAgICAgICAgICAgY29uc3QgY3VyID0gY3VycmVudEF0dHJpYnV0ZXMuZ2V0KCd5Y2hhbmdlJylcbiAgICAgICAgICAgICAgaWYgKHNuYXBzaG90ICE9PSB1bmRlZmluZWQgJiYgIWlzVmlzaWJsZShuLCBzbmFwc2hvdCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoY3VyID09PSB1bmRlZmluZWQgfHwgY3VyLnVzZXIgIT09IG4uaWQuY2xpZW50IHx8IGN1ci50eXBlICE9PSAncmVtb3ZlZCcpIHtcbiAgICAgICAgICAgICAgICAgIHBhY2tTdHIoKVxuICAgICAgICAgICAgICAgICAgY3VycmVudEF0dHJpYnV0ZXMuc2V0KCd5Y2hhbmdlJywgY29tcHV0ZVlDaGFuZ2UgPyBjb21wdXRlWUNoYW5nZSgncmVtb3ZlZCcsIG4uaWQpIDogeyB0eXBlOiAncmVtb3ZlZCcgfSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAocHJldlNuYXBzaG90ICE9PSB1bmRlZmluZWQgJiYgIWlzVmlzaWJsZShuLCBwcmV2U25hcHNob3QpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGN1ciA9PT0gdW5kZWZpbmVkIHx8IGN1ci51c2VyICE9PSBuLmlkLmNsaWVudCB8fCBjdXIudHlwZSAhPT0gJ2FkZGVkJykge1xuICAgICAgICAgICAgICAgICAgcGFja1N0cigpXG4gICAgICAgICAgICAgICAgICBjdXJyZW50QXR0cmlidXRlcy5zZXQoJ3ljaGFuZ2UnLCBjb21wdXRlWUNoYW5nZSA/IGNvbXB1dGVZQ2hhbmdlKCdhZGRlZCcsIG4uaWQpIDogeyB0eXBlOiAnYWRkZWQnIH0pXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGN1ciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgcGFja1N0cigpXG4gICAgICAgICAgICAgICAgY3VycmVudEF0dHJpYnV0ZXMuZGVsZXRlKCd5Y2hhbmdlJylcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBzdHIgKz0gLyoqIEB0eXBlIHtDb250ZW50U3RyaW5nfSAqLyAobi5jb250ZW50KS5zdHJcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgQ29udGVudFR5cGU6XG4gICAgICAgICAgICBjYXNlIENvbnRlbnRFbWJlZDoge1xuICAgICAgICAgICAgICBwYWNrU3RyKClcbiAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLGFueT59XG4gICAgICAgICAgICAgICAqL1xuICAgICAgICAgICAgICBjb25zdCBvcCA9IHtcbiAgICAgICAgICAgICAgICBpbnNlcnQ6IG4uY29udGVudC5nZXRDb250ZW50KClbMF1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoY3VycmVudEF0dHJpYnV0ZXMuc2l6ZSA+IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhdHRycyA9IC8qKiBAdHlwZSB7T2JqZWN0PHN0cmluZyxhbnk+fSAqLyAoe30pXG4gICAgICAgICAgICAgICAgb3AuYXR0cmlidXRlcyA9IGF0dHJzXG4gICAgICAgICAgICAgICAgY3VycmVudEF0dHJpYnV0ZXMuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4ge1xuICAgICAgICAgICAgICAgICAgYXR0cnNba2V5XSA9IHZhbHVlXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBvcHMucHVzaChvcClcbiAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgQ29udGVudEZvcm1hdDpcbiAgICAgICAgICAgICAgaWYgKGlzVmlzaWJsZShuLCBzbmFwc2hvdCkpIHtcbiAgICAgICAgICAgICAgICBwYWNrU3RyKClcbiAgICAgICAgICAgICAgICB1cGRhdGVDdXJyZW50QXR0cmlidXRlcyhjdXJyZW50QXR0cmlidXRlcywgLyoqIEB0eXBlIHtDb250ZW50Rm9ybWF0fSAqLyAobi5jb250ZW50KSlcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBuID0gbi5yaWdodFxuICAgICAgfVxuICAgICAgcGFja1N0cigpXG4gICAgfVxuICAgIGlmIChzbmFwc2hvdCB8fCBwcmV2U25hcHNob3QpIHtcbiAgICAgIC8vIHNuYXBzaG90cyBhcmUgbWVyZ2VkIGFnYWluIGFmdGVyIHRoZSB0cmFuc2FjdGlvbiwgc28gd2UgbmVlZCB0byBrZWVwIHRoZVxuICAgICAgLy8gdHJhbnNhY3Rpb24gYWxpdmUgdW50aWwgd2UgYXJlIGRvbmVcbiAgICAgIHRyYW5zYWN0KGRvYywgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICBpZiAoc25hcHNob3QpIHtcbiAgICAgICAgICBzcGxpdFNuYXBzaG90QWZmZWN0ZWRTdHJ1Y3RzKHRyYW5zYWN0aW9uLCBzbmFwc2hvdClcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJldlNuYXBzaG90KSB7XG4gICAgICAgICAgc3BsaXRTbmFwc2hvdEFmZmVjdGVkU3RydWN0cyh0cmFuc2FjdGlvbiwgcHJldlNuYXBzaG90KVxuICAgICAgICB9XG4gICAgICAgIGNvbXB1dGVEZWx0YSgpXG4gICAgICB9LCAnY2xlYW51cCcpXG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbXB1dGVEZWx0YSgpXG4gICAgfVxuICAgIHJldHVybiBvcHNcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnNlcnQgdGV4dCBhdCBhIGdpdmVuIGluZGV4LlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggVGhlIGluZGV4IGF0IHdoaWNoIHRvIHN0YXJ0IGluc2VydGluZy5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHRleHQgVGhlIHRleHQgdG8gaW5zZXJ0IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24uXG4gICAqIEBwYXJhbSB7VGV4dEF0dHJpYnV0ZXN9IFthdHRyaWJ1dGVzXSBPcHRpb25hbGx5IGRlZmluZSBzb21lIGZvcm1hdHRpbmdcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1hdGlvbiB0byBhcHBseSBvbiB0aGUgaW5zZXJ0ZWRcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUZXh0LlxuICAgKiBAcHVibGljXG4gICAqL1xuICBpbnNlcnQgKGluZGV4LCB0ZXh0LCBhdHRyaWJ1dGVzKSB7XG4gICAgaWYgKHRleHQubGVuZ3RoIDw9IDApIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjb25zdCB5ID0gdGhpcy5kb2NcbiAgICBpZiAoeSAhPT0gbnVsbCkge1xuICAgICAgdHJhbnNhY3QoeSwgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICBjb25zdCBwb3MgPSBmaW5kUG9zaXRpb24odHJhbnNhY3Rpb24sIHRoaXMsIGluZGV4LCAhYXR0cmlidXRlcylcbiAgICAgICAgaWYgKCFhdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgYXR0cmlidXRlcyA9IHt9XG4gICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgIHBvcy5jdXJyZW50QXR0cmlidXRlcy5mb3JFYWNoKCh2LCBrKSA9PiB7IGF0dHJpYnV0ZXNba10gPSB2IH0pXG4gICAgICAgIH1cbiAgICAgICAgaW5zZXJ0VGV4dCh0cmFuc2FjdGlvbiwgdGhpcywgcG9zLCB0ZXh0LCBhdHRyaWJ1dGVzKVxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgLyoqIEB0eXBlIHtBcnJheTxmdW5jdGlvbj59ICovICh0aGlzLl9wZW5kaW5nKS5wdXNoKCgpID0+IHRoaXMuaW5zZXJ0KGluZGV4LCB0ZXh0LCBhdHRyaWJ1dGVzKSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5zZXJ0cyBhbiBlbWJlZCBhdCBhIGluZGV4LlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggVGhlIGluZGV4IHRvIGluc2VydCB0aGUgZW1iZWQgYXQuXG4gICAqIEBwYXJhbSB7T2JqZWN0IHwgQWJzdHJhY3RUeXBlPGFueT59IGVtYmVkIFRoZSBPYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBlbWJlZC5cbiAgICogQHBhcmFtIHtUZXh0QXR0cmlidXRlc30gW2F0dHJpYnV0ZXNdIEF0dHJpYnV0ZSBpbmZvcm1hdGlvbiB0byBhcHBseSBvbiB0aGVcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbWJlZFxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICBpbnNlcnRFbWJlZCAoaW5kZXgsIGVtYmVkLCBhdHRyaWJ1dGVzKSB7XG4gICAgY29uc3QgeSA9IHRoaXMuZG9jXG4gICAgaWYgKHkgIT09IG51bGwpIHtcbiAgICAgIHRyYW5zYWN0KHksIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgY29uc3QgcG9zID0gZmluZFBvc2l0aW9uKHRyYW5zYWN0aW9uLCB0aGlzLCBpbmRleCwgIWF0dHJpYnV0ZXMpXG4gICAgICAgIGluc2VydFRleHQodHJhbnNhY3Rpb24sIHRoaXMsIHBvcywgZW1iZWQsIGF0dHJpYnV0ZXMgfHwge30pXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAvKiogQHR5cGUge0FycmF5PGZ1bmN0aW9uPn0gKi8gKHRoaXMuX3BlbmRpbmcpLnB1c2goKCkgPT4gdGhpcy5pbnNlcnRFbWJlZChpbmRleCwgZW1iZWQsIGF0dHJpYnV0ZXMgfHwge30pKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIHRleHQgc3RhcnRpbmcgZnJvbSBhbiBpbmRleC5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IEluZGV4IGF0IHdoaWNoIHRvIHN0YXJ0IGRlbGV0aW5nLlxuICAgKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byByZW1vdmUuIERlZmF1bHRzIHRvIDEuXG4gICAqXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIGRlbGV0ZSAoaW5kZXgsIGxlbmd0aCkge1xuICAgIGlmIChsZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBjb25zdCB5ID0gdGhpcy5kb2NcbiAgICBpZiAoeSAhPT0gbnVsbCkge1xuICAgICAgdHJhbnNhY3QoeSwgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICBkZWxldGVUZXh0KHRyYW5zYWN0aW9uLCBmaW5kUG9zaXRpb24odHJhbnNhY3Rpb24sIHRoaXMsIGluZGV4LCB0cnVlKSwgbGVuZ3RoKVxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgLyoqIEB0eXBlIHtBcnJheTxmdW5jdGlvbj59ICovICh0aGlzLl9wZW5kaW5nKS5wdXNoKCgpID0+IHRoaXMuZGVsZXRlKGluZGV4LCBsZW5ndGgpKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NpZ25zIHByb3BlcnRpZXMgdG8gYSByYW5nZSBvZiB0ZXh0LlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggVGhlIHBvc2l0aW9uIHdoZXJlIHRvIHN0YXJ0IGZvcm1hdHRpbmcuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggVGhlIGFtb3VudCBvZiBjaGFyYWN0ZXJzIHRvIGFzc2lnbiBwcm9wZXJ0aWVzIHRvLlxuICAgKiBAcGFyYW0ge1RleHRBdHRyaWJ1dGVzfSBhdHRyaWJ1dGVzIEF0dHJpYnV0ZSBpbmZvcm1hdGlvbiB0byBhcHBseSBvbiB0aGVcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0LlxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICBmb3JtYXQgKGluZGV4LCBsZW5ndGgsIGF0dHJpYnV0ZXMpIHtcbiAgICBpZiAobGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY29uc3QgeSA9IHRoaXMuZG9jXG4gICAgaWYgKHkgIT09IG51bGwpIHtcbiAgICAgIHRyYW5zYWN0KHksIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgY29uc3QgcG9zID0gZmluZFBvc2l0aW9uKHRyYW5zYWN0aW9uLCB0aGlzLCBpbmRleCwgZmFsc2UpXG4gICAgICAgIGlmIChwb3MucmlnaHQgPT09IG51bGwpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBmb3JtYXRUZXh0KHRyYW5zYWN0aW9uLCB0aGlzLCBwb3MsIGxlbmd0aCwgYXR0cmlidXRlcylcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8ZnVuY3Rpb24+fSAqLyAodGhpcy5fcGVuZGluZykucHVzaCgoKSA9PiB0aGlzLmZvcm1hdChpbmRleCwgbGVuZ3RoLCBhdHRyaWJ1dGVzKSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbiBhdHRyaWJ1dGUuXG4gICAqXG4gICAqIEBub3RlIFhtbC1UZXh0IG5vZGVzIGRvbid0IGhhdmUgYXR0cmlidXRlcy4gWW91IGNhbiB1c2UgdGhpcyBmZWF0dXJlIHRvIGFzc2lnbiBwcm9wZXJ0aWVzIHRvIGNvbXBsZXRlIHRleHQtYmxvY2tzLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gYXR0cmlidXRlTmFtZSBUaGUgYXR0cmlidXRlIG5hbWUgdGhhdCBpcyB0byBiZSByZW1vdmVkLlxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICByZW1vdmVBdHRyaWJ1dGUgKGF0dHJpYnV0ZU5hbWUpIHtcbiAgICBpZiAodGhpcy5kb2MgIT09IG51bGwpIHtcbiAgICAgIHRyYW5zYWN0KHRoaXMuZG9jLCB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIHR5cGVNYXBEZWxldGUodHJhbnNhY3Rpb24sIHRoaXMsIGF0dHJpYnV0ZU5hbWUpXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAvKiogQHR5cGUge0FycmF5PGZ1bmN0aW9uPn0gKi8gKHRoaXMuX3BlbmRpbmcpLnB1c2goKCkgPT4gdGhpcy5yZW1vdmVBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSkpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgb3IgdXBkYXRlcyBhbiBhdHRyaWJ1dGUuXG4gICAqXG4gICAqIEBub3RlIFhtbC1UZXh0IG5vZGVzIGRvbid0IGhhdmUgYXR0cmlidXRlcy4gWW91IGNhbiB1c2UgdGhpcyBmZWF0dXJlIHRvIGFzc2lnbiBwcm9wZXJ0aWVzIHRvIGNvbXBsZXRlIHRleHQtYmxvY2tzLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gYXR0cmlidXRlTmFtZSBUaGUgYXR0cmlidXRlIG5hbWUgdGhhdCBpcyB0byBiZSBzZXQuXG4gICAqIEBwYXJhbSB7YW55fSBhdHRyaWJ1dGVWYWx1ZSBUaGUgYXR0cmlidXRlIHZhbHVlIHRoYXQgaXMgdG8gYmUgc2V0LlxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICBzZXRBdHRyaWJ1dGUgKGF0dHJpYnV0ZU5hbWUsIGF0dHJpYnV0ZVZhbHVlKSB7XG4gICAgaWYgKHRoaXMuZG9jICE9PSBudWxsKSB7XG4gICAgICB0cmFuc2FjdCh0aGlzLmRvYywgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICB0eXBlTWFwU2V0KHRyYW5zYWN0aW9uLCB0aGlzLCBhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVWYWx1ZSlcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIC8qKiBAdHlwZSB7QXJyYXk8ZnVuY3Rpb24+fSAqLyAodGhpcy5fcGVuZGluZykucHVzaCgoKSA9PiB0aGlzLnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVWYWx1ZSkpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gYXR0cmlidXRlIHZhbHVlIHRoYXQgYmVsb25ncyB0byB0aGUgYXR0cmlidXRlIG5hbWUuXG4gICAqXG4gICAqIEBub3RlIFhtbC1UZXh0IG5vZGVzIGRvbid0IGhhdmUgYXR0cmlidXRlcy4gWW91IGNhbiB1c2UgdGhpcyBmZWF0dXJlIHRvIGFzc2lnbiBwcm9wZXJ0aWVzIHRvIGNvbXBsZXRlIHRleHQtYmxvY2tzLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gYXR0cmlidXRlTmFtZSBUaGUgYXR0cmlidXRlIG5hbWUgdGhhdCBpZGVudGlmaWVzIHRoZVxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWVyaWVkIHZhbHVlLlxuICAgKiBAcmV0dXJuIHthbnl9IFRoZSBxdWVyaWVkIGF0dHJpYnV0ZSB2YWx1ZS5cbiAgICpcbiAgICogQHB1YmxpY1xuICAgKi9cbiAgZ2V0QXR0cmlidXRlIChhdHRyaWJ1dGVOYW1lKSB7XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7YW55fSAqLyAodHlwZU1hcEdldCh0aGlzLCBhdHRyaWJ1dGVOYW1lKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFsbCBhdHRyaWJ1dGUgbmFtZS92YWx1ZSBwYWlycyBpbiBhIEpTT04gT2JqZWN0LlxuICAgKlxuICAgKiBAbm90ZSBYbWwtVGV4dCBub2RlcyBkb24ndCBoYXZlIGF0dHJpYnV0ZXMuIFlvdSBjYW4gdXNlIHRoaXMgZmVhdHVyZSB0byBhc3NpZ24gcHJvcGVydGllcyB0byBjb21wbGV0ZSB0ZXh0LWJsb2Nrcy5cbiAgICpcbiAgICogQHJldHVybiB7T2JqZWN0PHN0cmluZywgYW55Pn0gQSBKU09OIE9iamVjdCB0aGF0IGRlc2NyaWJlcyB0aGUgYXR0cmlidXRlcy5cbiAgICpcbiAgICogQHB1YmxpY1xuICAgKi9cbiAgZ2V0QXR0cmlidXRlcyAoKSB7XG4gICAgcmV0dXJuIHR5cGVNYXBHZXRBbGwodGhpcylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1VwZGF0ZUVuY29kZXJWMSB8IFVwZGF0ZUVuY29kZXJWMn0gZW5jb2RlclxuICAgKi9cbiAgX3dyaXRlIChlbmNvZGVyKSB7XG4gICAgZW5jb2Rlci53cml0ZVR5cGVSZWYoWVRleHRSZWZJRClcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VXBkYXRlRGVjb2RlclYxIHwgVXBkYXRlRGVjb2RlclYyfSBfZGVjb2RlclxuICogQHJldHVybiB7WVRleHR9XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgcmVhZFlUZXh0ID0gX2RlY29kZXIgPT4gbmV3IFlUZXh0KClcbiIsICIvKipcbiAqIEBtb2R1bGUgWVhtbFxuICovXG5cbmltcG9ydCB7XG4gIFlYbWxFdmVudCxcbiAgWVhtbEVsZW1lbnQsXG4gIEFic3RyYWN0VHlwZSxcbiAgdHlwZUxpc3RNYXAsXG4gIHR5cGVMaXN0Rm9yRWFjaCxcbiAgdHlwZUxpc3RJbnNlcnRHZW5lcmljcyxcbiAgdHlwZUxpc3RJbnNlcnRHZW5lcmljc0FmdGVyLFxuICB0eXBlTGlzdERlbGV0ZSxcbiAgdHlwZUxpc3RUb0FycmF5LFxuICBZWG1sRnJhZ21lbnRSZWZJRCxcbiAgY2FsbFR5cGVPYnNlcnZlcnMsXG4gIHRyYW5zYWN0LFxuICB0eXBlTGlzdEdldCxcbiAgdHlwZUxpc3RTbGljZSxcbiAgd2FyblByZW1hdHVyZUFjY2VzcyxcbiAgVXBkYXRlRGVjb2RlclYxLCBVcGRhdGVEZWNvZGVyVjIsIFVwZGF0ZUVuY29kZXJWMSwgVXBkYXRlRW5jb2RlclYyLCBEb2MsIENvbnRlbnRUeXBlLCBUcmFuc2FjdGlvbiwgSXRlbSwgWVhtbFRleHQsIFlYbWxIb29rIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbn0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJ1xuXG5pbXBvcnQgKiBhcyBlcnJvciBmcm9tICdsaWIwL2Vycm9yJ1xuaW1wb3J0ICogYXMgYXJyYXkgZnJvbSAnbGliMC9hcnJheSdcblxuLyoqXG4gKiBEZWZpbmUgdGhlIGVsZW1lbnRzIHRvIHdoaWNoIGEgc2V0IG9mIENTUyBxdWVyaWVzIGFwcGx5LlxuICoge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9DU1NfU2VsZWN0b3JzfENTU19TZWxlY3RvcnN9XG4gKlxuICogQGV4YW1wbGVcbiAqICAgcXVlcnkgPSAnLmNsYXNzU2VsZWN0b3InXG4gKiAgIHF1ZXJ5ID0gJ25vZGVTZWxlY3RvcidcbiAqICAgcXVlcnkgPSAnI2lkU2VsZWN0b3InXG4gKlxuICogQHR5cGVkZWYge3N0cmluZ30gQ1NTX1NlbGVjdG9yXG4gKi9cblxuLyoqXG4gKiBEb20gZmlsdGVyIGZ1bmN0aW9uLlxuICpcbiAqIEBjYWxsYmFjayBkb21GaWx0ZXJcbiAqIEBwYXJhbSB7c3RyaW5nfSBub2RlTmFtZSBUaGUgbm9kZU5hbWUgb2YgdGhlIGVsZW1lbnRcbiAqIEBwYXJhbSB7TWFwfSBhdHRyaWJ1dGVzIFRoZSBtYXAgb2YgYXR0cmlidXRlcy5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgRG9tIG5vZGUgaW4gdGhlIFlYbWxFbGVtZW50LlxuICovXG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHN1YnNldCBvZiB0aGUgbm9kZXMgb2YgYSBZWG1sRWxlbWVudCAvIFlYbWxGcmFnbWVudCBhbmQgYVxuICogcG9zaXRpb24gd2l0aGluIHRoZW0uXG4gKlxuICogQ2FuIGJlIGNyZWF0ZWQgd2l0aCB7QGxpbmsgWVhtbEZyYWdtZW50I2NyZWF0ZVRyZWVXYWxrZXJ9XG4gKlxuICogQHB1YmxpY1xuICogQGltcGxlbWVudHMge0l0ZXJhYmxlPFlYbWxFbGVtZW50fFlYbWxUZXh0fFlYbWxFbGVtZW50fFlYbWxIb29rPn1cbiAqL1xuZXhwb3J0IGNsYXNzIFlYbWxUcmVlV2Fsa2VyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7WVhtbEZyYWdtZW50IHwgWVhtbEVsZW1lbnR9IHJvb3RcbiAgICogQHBhcmFtIHtmdW5jdGlvbihBYnN0cmFjdFR5cGU8YW55Pik6Ym9vbGVhbn0gW2ZdXG4gICAqL1xuICBjb25zdHJ1Y3RvciAocm9vdCwgZiA9ICgpID0+IHRydWUpIHtcbiAgICB0aGlzLl9maWx0ZXIgPSBmXG4gICAgdGhpcy5fcm9vdCA9IHJvb3RcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7SXRlbX1cbiAgICAgKi9cbiAgICB0aGlzLl9jdXJyZW50Tm9kZSA9IC8qKiBAdHlwZSB7SXRlbX0gKi8gKHJvb3QuX3N0YXJ0KVxuICAgIHRoaXMuX2ZpcnN0Q2FsbCA9IHRydWVcbiAgICByb290LmRvYyA/PyB3YXJuUHJlbWF0dXJlQWNjZXNzKClcbiAgfVxuXG4gIFtTeW1ib2wuaXRlcmF0b3JdICgpIHtcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbmV4dCBub2RlLlxuICAgKlxuICAgKiBAcmV0dXJuIHtJdGVyYXRvclJlc3VsdDxZWG1sRWxlbWVudHxZWG1sVGV4dHxZWG1sSG9vaz59IFRoZSBuZXh0IG5vZGUuXG4gICAqXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIG5leHQgKCkge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtJdGVtfG51bGx9XG4gICAgICovXG4gICAgbGV0IG4gPSB0aGlzLl9jdXJyZW50Tm9kZVxuICAgIGxldCB0eXBlID0gbiAmJiBuLmNvbnRlbnQgJiYgLyoqIEB0eXBlIHthbnl9ICovIChuLmNvbnRlbnQpLnR5cGVcbiAgICBpZiAobiAhPT0gbnVsbCAmJiAoIXRoaXMuX2ZpcnN0Q2FsbCB8fCBuLmRlbGV0ZWQgfHwgIXRoaXMuX2ZpbHRlcih0eXBlKSkpIHsgLy8gaWYgZmlyc3QgY2FsbCwgd2UgY2hlY2sgaWYgd2UgY2FuIHVzZSB0aGUgZmlyc3QgaXRlbVxuICAgICAgZG8ge1xuICAgICAgICB0eXBlID0gLyoqIEB0eXBlIHthbnl9ICovIChuLmNvbnRlbnQpLnR5cGVcbiAgICAgICAgaWYgKCFuLmRlbGV0ZWQgJiYgKHR5cGUuY29uc3RydWN0b3IgPT09IFlYbWxFbGVtZW50IHx8IHR5cGUuY29uc3RydWN0b3IgPT09IFlYbWxGcmFnbWVudCkgJiYgdHlwZS5fc3RhcnQgIT09IG51bGwpIHtcbiAgICAgICAgICAvLyB3YWxrIGRvd24gaW4gdGhlIHRyZWVcbiAgICAgICAgICBuID0gdHlwZS5fc3RhcnRcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyB3YWxrIHJpZ2h0IG9yIHVwIGluIHRoZSB0cmVlXG4gICAgICAgICAgd2hpbGUgKG4gIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICogQHR5cGUge0l0ZW0gfCBudWxsfVxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBjb25zdCBueHQgPSBuLm5leHRcbiAgICAgICAgICAgIGlmIChueHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgbiA9IG54dFxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfSBlbHNlIGlmIChuLnBhcmVudCA9PT0gdGhpcy5fcm9vdCkge1xuICAgICAgICAgICAgICBuID0gbnVsbFxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbiA9IC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovIChuLnBhcmVudCkuX2l0ZW1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKG4gIT09IG51bGwgJiYgKG4uZGVsZXRlZCB8fCAhdGhpcy5fZmlsdGVyKC8qKiBAdHlwZSB7Q29udGVudFR5cGV9ICovIChuLmNvbnRlbnQpLnR5cGUpKSlcbiAgICB9XG4gICAgdGhpcy5fZmlyc3RDYWxsID0gZmFsc2VcbiAgICBpZiAobiA9PT0gbnVsbCkge1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCwgZG9uZTogdHJ1ZSB9XG4gICAgfVxuICAgIHRoaXMuX2N1cnJlbnROb2RlID0gblxuICAgIHJldHVybiB7IHZhbHVlOiAvKiogQHR5cGUge2FueX0gKi8gKG4uY29udGVudCkudHlwZSwgZG9uZTogZmFsc2UgfVxuICB9XG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIGxpc3Qgb2Yge0BsaW5rIFlYbWxFbGVtZW50fS5hbmQge0BsaW5rIFlYbWxUZXh0fSB0eXBlcy5cbiAqIEEgWXhtbEZyYWdtZW50IGlzIHNpbWlsYXIgdG8gYSB7QGxpbmsgWVhtbEVsZW1lbnR9LCBidXQgaXQgZG9lcyBub3QgaGF2ZSBhXG4gKiBub2RlTmFtZSBhbmQgaXQgZG9lcyBub3QgaGF2ZSBhdHRyaWJ1dGVzLiBUaG91Z2ggaXQgY2FuIGJlIGJvdW5kIHRvIGEgRE9NXG4gKiBlbGVtZW50IC0gaW4gdGhpcyBjYXNlIHRoZSBhdHRyaWJ1dGVzIGFuZCB0aGUgbm9kZU5hbWUgYXJlIG5vdCBzaGFyZWQuXG4gKlxuICogQHB1YmxpY1xuICogQGV4dGVuZHMgQWJzdHJhY3RUeXBlPFlYbWxFdmVudD5cbiAqL1xuZXhwb3J0IGNsYXNzIFlYbWxGcmFnbWVudCBleHRlbmRzIEFic3RyYWN0VHlwZSB7XG4gIGNvbnN0cnVjdG9yICgpIHtcbiAgICBzdXBlcigpXG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PGFueT58bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLl9wcmVsaW1Db250ZW50ID0gW11cbiAgfVxuXG4gIC8qKlxuICAgKiBAdHlwZSB7WVhtbEVsZW1lbnR8WVhtbFRleHR8bnVsbH1cbiAgICovXG4gIGdldCBmaXJzdENoaWxkICgpIHtcbiAgICBjb25zdCBmaXJzdCA9IHRoaXMuX2ZpcnN0XG4gICAgcmV0dXJuIGZpcnN0ID8gZmlyc3QuY29udGVudC5nZXRDb250ZW50KClbMF0gOiBudWxsXG4gIH1cblxuICAvKipcbiAgICogSW50ZWdyYXRlIHRoaXMgdHlwZSBpbnRvIHRoZSBZanMgaW5zdGFuY2UuXG4gICAqXG4gICAqICogU2F2ZSB0aGlzIHN0cnVjdCBpbiB0aGUgb3NcbiAgICogKiBUaGlzIHR5cGUgaXMgc2VudCB0byBvdGhlciBjbGllbnRcbiAgICogKiBPYnNlcnZlciBmdW5jdGlvbnMgYXJlIGZpcmVkXG4gICAqXG4gICAqIEBwYXJhbSB7RG9jfSB5IFRoZSBZanMgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtJdGVtfSBpdGVtXG4gICAqL1xuICBfaW50ZWdyYXRlICh5LCBpdGVtKSB7XG4gICAgc3VwZXIuX2ludGVncmF0ZSh5LCBpdGVtKVxuICAgIHRoaXMuaW5zZXJ0KDAsIC8qKiBAdHlwZSB7QXJyYXk8YW55Pn0gKi8gKHRoaXMuX3ByZWxpbUNvbnRlbnQpKVxuICAgIHRoaXMuX3ByZWxpbUNvbnRlbnQgPSBudWxsXG4gIH1cblxuICBfY29weSAoKSB7XG4gICAgcmV0dXJuIG5ldyBZWG1sRnJhZ21lbnQoKVxuICB9XG5cbiAgLyoqXG4gICAqIE1ha2VzIGEgY29weSBvZiB0aGlzIGRhdGEgdHlwZSB0aGF0IGNhbiBiZSBpbmNsdWRlZCBzb21ld2hlcmUgZWxzZS5cbiAgICpcbiAgICogTm90ZSB0aGF0IHRoZSBjb250ZW50IGlzIG9ubHkgcmVhZGFibGUgX2FmdGVyXyBpdCBoYXMgYmVlbiBpbmNsdWRlZCBzb21ld2hlcmUgaW4gdGhlIFlkb2MuXG4gICAqXG4gICAqIEByZXR1cm4ge1lYbWxGcmFnbWVudH1cbiAgICovXG4gIGNsb25lICgpIHtcbiAgICBjb25zdCBlbCA9IG5ldyBZWG1sRnJhZ21lbnQoKVxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBlbC5pbnNlcnQoMCwgdGhpcy50b0FycmF5KCkubWFwKGl0ZW0gPT4gaXRlbSBpbnN0YW5jZW9mIEFic3RyYWN0VHlwZSA/IGl0ZW0uY2xvbmUoKSA6IGl0ZW0pKVxuICAgIHJldHVybiBlbFxuICB9XG5cbiAgZ2V0IGxlbmd0aCAoKSB7XG4gICAgdGhpcy5kb2MgPz8gd2FyblByZW1hdHVyZUFjY2VzcygpXG4gICAgcmV0dXJuIHRoaXMuX3ByZWxpbUNvbnRlbnQgPT09IG51bGwgPyB0aGlzLl9sZW5ndGggOiB0aGlzLl9wcmVsaW1Db250ZW50Lmxlbmd0aFxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIHN1YnRyZWUgb2YgY2hpbGROb2Rlcy5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY29uc3Qgd2Fsa2VyID0gZWxlbS5jcmVhdGVUcmVlV2Fsa2VyKGRvbSA9PiBkb20ubm9kZU5hbWUgPT09ICdkaXYnKVxuICAgKiBmb3IgKGxldCBub2RlIGluIHdhbGtlcikge1xuICAgKiAgIC8vIGBub2RlYCBpcyBhIGRpdiBub2RlXG4gICAqICAgbm9wKG5vZGUpXG4gICAqIH1cbiAgICpcbiAgICogQHBhcmFtIHtmdW5jdGlvbihBYnN0cmFjdFR5cGU8YW55Pik6Ym9vbGVhbn0gZmlsdGVyIEZ1bmN0aW9uIHRoYXQgaXMgY2FsbGVkIG9uIGVhY2ggY2hpbGQgZWxlbWVudCBhbmRcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybnMgYSBCb29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgY2hpbGRcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgIGlzIHRvIGJlIGluY2x1ZGVkIGluIHRoZSBzdWJ0cmVlLlxuICAgKiBAcmV0dXJuIHtZWG1sVHJlZVdhbGtlcn0gQSBzdWJ0cmVlIGFuZCBhIHBvc2l0aW9uIHdpdGhpbiBpdC5cbiAgICpcbiAgICogQHB1YmxpY1xuICAgKi9cbiAgY3JlYXRlVHJlZVdhbGtlciAoZmlsdGVyKSB7XG4gICAgcmV0dXJuIG5ldyBZWG1sVHJlZVdhbGtlcih0aGlzLCBmaWx0ZXIpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZmlyc3QgWVhtbEVsZW1lbnQgdGhhdCBtYXRjaGVzIHRoZSBxdWVyeS5cbiAgICogU2ltaWxhciB0byBET00ncyB7QGxpbmsgcXVlcnlTZWxlY3Rvcn0uXG4gICAqXG4gICAqIFF1ZXJ5IHN1cHBvcnQ6XG4gICAqICAgLSB0YWduYW1lXG4gICAqIFRPRE86XG4gICAqICAgLSBpZFxuICAgKiAgIC0gYXR0cmlidXRlXG4gICAqXG4gICAqIEBwYXJhbSB7Q1NTX1NlbGVjdG9yfSBxdWVyeSBUaGUgcXVlcnkgb24gdGhlIGNoaWxkcmVuLlxuICAgKiBAcmV0dXJuIHtZWG1sRWxlbWVudHxZWG1sVGV4dHxZWG1sSG9va3xudWxsfSBUaGUgZmlyc3QgZWxlbWVudCB0aGF0IG1hdGNoZXMgdGhlIHF1ZXJ5IG9yIG51bGwuXG4gICAqXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIHF1ZXJ5U2VsZWN0b3IgKHF1ZXJ5KSB7XG4gICAgcXVlcnkgPSBxdWVyeS50b1VwcGVyQ2FzZSgpXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGNvbnN0IGl0ZXJhdG9yID0gbmV3IFlYbWxUcmVlV2Fsa2VyKHRoaXMsIGVsZW1lbnQgPT4gZWxlbWVudC5ub2RlTmFtZSAmJiBlbGVtZW50Lm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT09IHF1ZXJ5KVxuICAgIGNvbnN0IG5leHQgPSBpdGVyYXRvci5uZXh0KClcbiAgICBpZiAobmV4dC5kb25lKSB7XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV4dC52YWx1ZVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFsbCBZWG1sRWxlbWVudHMgdGhhdCBtYXRjaCB0aGUgcXVlcnkuXG4gICAqIFNpbWlsYXIgdG8gRG9tJ3Mge0BsaW5rIHF1ZXJ5U2VsZWN0b3JBbGx9LlxuICAgKlxuICAgKiBAdG9kbyBEb2VzIG5vdCB5ZXQgc3VwcG9ydCBhbGwgcXVlcmllcy4gQ3VycmVudGx5IG9ubHkgcXVlcnkgYnkgdGFnTmFtZS5cbiAgICpcbiAgICogQHBhcmFtIHtDU1NfU2VsZWN0b3J9IHF1ZXJ5IFRoZSBxdWVyeSBvbiB0aGUgY2hpbGRyZW5cbiAgICogQHJldHVybiB7QXJyYXk8WVhtbEVsZW1lbnR8WVhtbFRleHR8WVhtbEhvb2t8bnVsbD59IFRoZSBlbGVtZW50cyB0aGF0IG1hdGNoIHRoaXMgcXVlcnkuXG4gICAqXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIHF1ZXJ5U2VsZWN0b3JBbGwgKHF1ZXJ5KSB7XG4gICAgcXVlcnkgPSBxdWVyeS50b1VwcGVyQ2FzZSgpXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHJldHVybiBhcnJheS5mcm9tKG5ldyBZWG1sVHJlZVdhbGtlcih0aGlzLCBlbGVtZW50ID0+IGVsZW1lbnQubm9kZU5hbWUgJiYgZWxlbWVudC5ub2RlTmFtZS50b1VwcGVyQ2FzZSgpID09PSBxdWVyeSkpXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBZWG1sRXZlbnQgYW5kIGNhbGxzIG9ic2VydmVycy5cbiAgICpcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtTZXQ8bnVsbHxzdHJpbmc+fSBwYXJlbnRTdWJzIEtleXMgY2hhbmdlZCBvbiB0aGlzIHR5cGUuIGBudWxsYCBpZiBsaXN0IHdhcyBtb2RpZmllZC5cbiAgICovXG4gIF9jYWxsT2JzZXJ2ZXIgKHRyYW5zYWN0aW9uLCBwYXJlbnRTdWJzKSB7XG4gICAgY2FsbFR5cGVPYnNlcnZlcnModGhpcywgdHJhbnNhY3Rpb24sIG5ldyBZWG1sRXZlbnQodGhpcywgcGFyZW50U3VicywgdHJhbnNhY3Rpb24pKVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIGFsbCB0aGUgY2hpbGRyZW4gb2YgdGhpcyBZWG1sRnJhZ21lbnQuXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBhbGwgY2hpbGRyZW4uXG4gICAqL1xuICB0b1N0cmluZyAoKSB7XG4gICAgcmV0dXJuIHR5cGVMaXN0TWFwKHRoaXMsIHhtbCA9PiB4bWwudG9TdHJpbmcoKSkuam9pbignJylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b0pTT04gKCkge1xuICAgIHJldHVybiB0aGlzLnRvU3RyaW5nKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgRG9tIEVsZW1lbnQgdGhhdCBtaXJyb3JzIHRoaXMgWVhtbEVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7RG9jdW1lbnR9IFtfZG9jdW1lbnQ9ZG9jdW1lbnRdIFRoZSBkb2N1bWVudCBvYmplY3QgKHlvdSBtdXN0IGRlZmluZVxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzIHdoZW4gY2FsbGluZyB0aGlzIG1ldGhvZCBpblxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlanMpXG4gICAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgYW55Pn0gW2hvb2tzPXt9XSBPcHRpb25hbCBwcm9wZXJ0eSB0byBjdXN0b21pemUgaG93IGhvb2tzXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlIHByZXNlbnRlZCBpbiB0aGUgRE9NXG4gICAqIEBwYXJhbSB7YW55fSBbYmluZGluZ10gWW91IHNob3VsZCBub3Qgc2V0IHRoaXMgcHJvcGVydHkuIFRoaXMgaXNcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlZCBpZiBEb21CaW5kaW5nIHdhbnRzIHRvIGNyZWF0ZSBhXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc29jaWF0aW9uIHRvIHRoZSBjcmVhdGVkIERPTSB0eXBlLlxuICAgKiBAcmV0dXJuIHtOb2RlfSBUaGUge0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9FbGVtZW50fERvbSBFbGVtZW50fVxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICB0b0RPTSAoX2RvY3VtZW50ID0gZG9jdW1lbnQsIGhvb2tzID0ge30sIGJpbmRpbmcpIHtcbiAgICBjb25zdCBmcmFnbWVudCA9IF9kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KClcbiAgICBpZiAoYmluZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBiaW5kaW5nLl9jcmVhdGVBc3NvY2lhdGlvbihmcmFnbWVudCwgdGhpcylcbiAgICB9XG4gICAgdHlwZUxpc3RGb3JFYWNoKHRoaXMsIHhtbFR5cGUgPT4ge1xuICAgICAgZnJhZ21lbnQuaW5zZXJ0QmVmb3JlKHhtbFR5cGUudG9ET00oX2RvY3VtZW50LCBob29rcywgYmluZGluZyksIG51bGwpXG4gICAgfSlcbiAgICByZXR1cm4gZnJhZ21lbnRcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnNlcnRzIG5ldyBjb250ZW50IGF0IGFuIGluZGV4LlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiAgLy8gSW5zZXJ0IGNoYXJhY3RlciAnYScgYXQgcG9zaXRpb24gMFxuICAgKiAgeG1sLmluc2VydCgwLCBbbmV3IFkuWG1sVGV4dCgndGV4dCcpXSlcbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IFRoZSBpbmRleCB0byBpbnNlcnQgY29udGVudCBhdFxuICAgKiBAcGFyYW0ge0FycmF5PFlYbWxFbGVtZW50fFlYbWxUZXh0Pn0gY29udGVudCBUaGUgYXJyYXkgb2YgY29udGVudFxuICAgKi9cbiAgaW5zZXJ0IChpbmRleCwgY29udGVudCkge1xuICAgIGlmICh0aGlzLmRvYyAhPT0gbnVsbCkge1xuICAgICAgdHJhbnNhY3QodGhpcy5kb2MsIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgdHlwZUxpc3RJbnNlcnRHZW5lcmljcyh0cmFuc2FjdGlvbiwgdGhpcywgaW5kZXgsIGNvbnRlbnQpXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBAdHMtaWdub3JlIF9wcmVsaW1Db250ZW50IGlzIGRlZmluZWQgYmVjYXVzZSB0aGlzIGlzIG5vdCB5ZXQgaW50ZWdyYXRlZFxuICAgICAgdGhpcy5fcHJlbGltQ29udGVudC5zcGxpY2UoaW5kZXgsIDAsIC4uLmNvbnRlbnQpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluc2VydHMgbmV3IGNvbnRlbnQgYXQgYW4gaW5kZXguXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqICAvLyBJbnNlcnQgY2hhcmFjdGVyICdhJyBhdCBwb3NpdGlvbiAwXG4gICAqICB4bWwuaW5zZXJ0KDAsIFtuZXcgWS5YbWxUZXh0KCd0ZXh0JyldKVxuICAgKlxuICAgKiBAcGFyYW0ge251bGx8SXRlbXxZWG1sRWxlbWVudHxZWG1sVGV4dH0gcmVmIFRoZSBpbmRleCB0byBpbnNlcnQgY29udGVudCBhdFxuICAgKiBAcGFyYW0ge0FycmF5PFlYbWxFbGVtZW50fFlYbWxUZXh0Pn0gY29udGVudCBUaGUgYXJyYXkgb2YgY29udGVudFxuICAgKi9cbiAgaW5zZXJ0QWZ0ZXIgKHJlZiwgY29udGVudCkge1xuICAgIGlmICh0aGlzLmRvYyAhPT0gbnVsbCkge1xuICAgICAgdHJhbnNhY3QodGhpcy5kb2MsIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgY29uc3QgcmVmSXRlbSA9IChyZWYgJiYgcmVmIGluc3RhbmNlb2YgQWJzdHJhY3RUeXBlKSA/IHJlZi5faXRlbSA6IHJlZlxuICAgICAgICB0eXBlTGlzdEluc2VydEdlbmVyaWNzQWZ0ZXIodHJhbnNhY3Rpb24sIHRoaXMsIHJlZkl0ZW0sIGNvbnRlbnQpXG4gICAgICB9KVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBwYyA9IC8qKiBAdHlwZSB7QXJyYXk8YW55Pn0gKi8gKHRoaXMuX3ByZWxpbUNvbnRlbnQpXG4gICAgICBjb25zdCBpbmRleCA9IHJlZiA9PT0gbnVsbCA/IDAgOiBwYy5maW5kSW5kZXgoZWwgPT4gZWwgPT09IHJlZikgKyAxXG4gICAgICBpZiAoaW5kZXggPT09IDAgJiYgcmVmICE9PSBudWxsKSB7XG4gICAgICAgIHRocm93IGVycm9yLmNyZWF0ZSgnUmVmZXJlbmNlIGl0ZW0gbm90IGZvdW5kJylcbiAgICAgIH1cbiAgICAgIHBjLnNwbGljZShpbmRleCwgMCwgLi4uY29udGVudClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlcyBlbGVtZW50cyBzdGFydGluZyBmcm9tIGFuIGluZGV4LlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggSW5kZXggYXQgd2hpY2ggdG8gc3RhcnQgZGVsZXRpbmcgZWxlbWVudHNcbiAgICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9MV0gVGhlIG51bWJlciBvZiBlbGVtZW50cyB0byByZW1vdmUuIERlZmF1bHRzIHRvIDEuXG4gICAqL1xuICBkZWxldGUgKGluZGV4LCBsZW5ndGggPSAxKSB7XG4gICAgaWYgKHRoaXMuZG9jICE9PSBudWxsKSB7XG4gICAgICB0cmFuc2FjdCh0aGlzLmRvYywgdHJhbnNhY3Rpb24gPT4ge1xuICAgICAgICB0eXBlTGlzdERlbGV0ZSh0cmFuc2FjdGlvbiwgdGhpcywgaW5kZXgsIGxlbmd0aClcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEB0cy1pZ25vcmUgX3ByZWxpbUNvbnRlbnQgaXMgZGVmaW5lZCBiZWNhdXNlIHRoaXMgaXMgbm90IHlldCBpbnRlZ3JhdGVkXG4gICAgICB0aGlzLl9wcmVsaW1Db250ZW50LnNwbGljZShpbmRleCwgbGVuZ3RoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFuc2Zvcm1zIHRoaXMgWUFycmF5IHRvIGEgSmF2YVNjcmlwdCBBcnJheS5cbiAgICpcbiAgICogQHJldHVybiB7QXJyYXk8WVhtbEVsZW1lbnR8WVhtbFRleHR8WVhtbEhvb2s+fVxuICAgKi9cbiAgdG9BcnJheSAoKSB7XG4gICAgcmV0dXJuIHR5cGVMaXN0VG9BcnJheSh0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZHMgY29udGVudCB0byB0aGlzIFlBcnJheS5cbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxZWG1sRWxlbWVudHxZWG1sVGV4dD59IGNvbnRlbnQgQXJyYXkgb2YgY29udGVudCB0byBhcHBlbmQuXG4gICAqL1xuICBwdXNoIChjb250ZW50KSB7XG4gICAgdGhpcy5pbnNlcnQodGhpcy5sZW5ndGgsIGNvbnRlbnQpXG4gIH1cblxuICAvKipcbiAgICogUHJlcGVuZHMgY29udGVudCB0byB0aGlzIFlBcnJheS5cbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxZWG1sRWxlbWVudHxZWG1sVGV4dD59IGNvbnRlbnQgQXJyYXkgb2YgY29udGVudCB0byBwcmVwZW5kLlxuICAgKi9cbiAgdW5zaGlmdCAoY29udGVudCkge1xuICAgIHRoaXMuaW5zZXJ0KDAsIGNvbnRlbnQpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgaS10aCBlbGVtZW50IGZyb20gYSBZQXJyYXkuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0dXJuIGZyb20gdGhlIFlBcnJheVxuICAgKiBAcmV0dXJuIHtZWG1sRWxlbWVudHxZWG1sVGV4dH1cbiAgICovXG4gIGdldCAoaW5kZXgpIHtcbiAgICByZXR1cm4gdHlwZUxpc3RHZXQodGhpcywgaW5kZXgpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIHBvcnRpb24gb2YgdGhpcyBZWG1sRnJhZ21lbnQgaW50byBhIEphdmFTY3JpcHQgQXJyYXkgc2VsZWN0ZWRcbiAgICogZnJvbSBzdGFydCB0byBlbmQgKGVuZCBub3QgaW5jbHVkZWQpLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0XVxuICAgKiBAcGFyYW0ge251bWJlcn0gW2VuZF1cbiAgICogQHJldHVybiB7QXJyYXk8WVhtbEVsZW1lbnR8WVhtbFRleHQ+fVxuICAgKi9cbiAgc2xpY2UgKHN0YXJ0ID0gMCwgZW5kID0gdGhpcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdHlwZUxpc3RTbGljZSh0aGlzLCBzdGFydCwgZW5kKVxuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGVzIGEgcHJvdmlkZWQgZnVuY3Rpb24gb24gb25jZSBvbiBldmVyeSBjaGlsZCBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge2Z1bmN0aW9uKFlYbWxFbGVtZW50fFlYbWxUZXh0LG51bWJlciwgdHlwZW9mIHNlbGYpOnZvaWR9IGYgQSBmdW5jdGlvbiB0byBleGVjdXRlIG9uIGV2ZXJ5IGVsZW1lbnQgb2YgdGhpcyBZQXJyYXkuXG4gICAqL1xuICBmb3JFYWNoIChmKSB7XG4gICAgdHlwZUxpc3RGb3JFYWNoKHRoaXMsIGYpXG4gIH1cblxuICAvKipcbiAgICogVHJhbnNmb3JtIHRoZSBwcm9wZXJ0aWVzIG9mIHRoaXMgdHlwZSB0byBiaW5hcnkgYW5kIHdyaXRlIGl0IHRvIGFuXG4gICAqIEJpbmFyeUVuY29kZXIuXG4gICAqXG4gICAqIFRoaXMgaXMgY2FsbGVkIHdoZW4gdGhpcyBJdGVtIGlzIHNlbnQgdG8gYSByZW1vdGUgcGVlci5cbiAgICpcbiAgICogQHBhcmFtIHtVcGRhdGVFbmNvZGVyVjEgfCBVcGRhdGVFbmNvZGVyVjJ9IGVuY29kZXIgVGhlIGVuY29kZXIgdG8gd3JpdGUgZGF0YSB0by5cbiAgICovXG4gIF93cml0ZSAoZW5jb2Rlcikge1xuICAgIGVuY29kZXIud3JpdGVUeXBlUmVmKFlYbWxGcmFnbWVudFJlZklEKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtVcGRhdGVEZWNvZGVyVjEgfCBVcGRhdGVEZWNvZGVyVjJ9IF9kZWNvZGVyXG4gKiBAcmV0dXJuIHtZWG1sRnJhZ21lbnR9XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgcmVhZFlYbWxGcmFnbWVudCA9IF9kZWNvZGVyID0+IG5ldyBZWG1sRnJhZ21lbnQoKVxuIiwgImltcG9ydCAqIGFzIG9iamVjdCBmcm9tICdsaWIwL29iamVjdCdcblxuaW1wb3J0IHtcbiAgWVhtbEZyYWdtZW50LFxuICB0cmFuc2FjdCxcbiAgdHlwZU1hcERlbGV0ZSxcbiAgdHlwZU1hcEhhcyxcbiAgdHlwZU1hcFNldCxcbiAgdHlwZU1hcEdldCxcbiAgdHlwZU1hcEdldEFsbCxcbiAgdHlwZU1hcEdldEFsbFNuYXBzaG90LFxuICB0eXBlTGlzdEZvckVhY2gsXG4gIFlYbWxFbGVtZW50UmVmSUQsXG4gIFNuYXBzaG90LCBZWG1sVGV4dCwgQ29udGVudFR5cGUsIEFic3RyYWN0VHlwZSwgVXBkYXRlRGVjb2RlclYxLCBVcGRhdGVEZWNvZGVyVjIsIFVwZGF0ZUVuY29kZXJWMSwgVXBkYXRlRW5jb2RlclYyLCBEb2MsIEl0ZW0gLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdHxudW1iZXJ8bnVsbHxBcnJheTxhbnk+fHN0cmluZ3xVaW50OEFycmF5fEFic3RyYWN0VHlwZTxhbnk+fSBWYWx1ZVR5cGVzXG4gKi9cblxuLyoqXG4gKiBBbiBZWG1sRWxlbWVudCBpbWl0YXRlcyB0aGUgYmVoYXZpb3Igb2YgYVxuICogaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnR8RG9tIEVsZW1lbnRcbiAqXG4gKiAqIEFuIFlYbWxFbGVtZW50IGhhcyBhdHRyaWJ1dGVzIChrZXkgdmFsdWUgcGFpcnMpXG4gKiAqIEFuIFlYbWxFbGVtZW50IGhhcyBjaGlsZEVsZW1lbnRzIHRoYXQgbXVzdCBpbmhlcml0IGZyb20gWVhtbEVsZW1lbnRcbiAqXG4gKiBAdGVtcGxhdGUge3sgW2tleTogc3RyaW5nXTogVmFsdWVUeXBlcyB9fSBbS1Y9eyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfV1cbiAqL1xuZXhwb3J0IGNsYXNzIFlYbWxFbGVtZW50IGV4dGVuZHMgWVhtbEZyYWdtZW50IHtcbiAgY29uc3RydWN0b3IgKG5vZGVOYW1lID0gJ1VOREVGSU5FRCcpIHtcbiAgICBzdXBlcigpXG4gICAgdGhpcy5ub2RlTmFtZSA9IG5vZGVOYW1lXG4gICAgLyoqXG4gICAgICogQHR5cGUge01hcDxzdHJpbmcsIGFueT58bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLl9wcmVsaW1BdHRycyA9IG5ldyBNYXAoKVxuICB9XG5cbiAgLyoqXG4gICAqIEB0eXBlIHtZWG1sRWxlbWVudHxZWG1sVGV4dHxudWxsfVxuICAgKi9cbiAgZ2V0IG5leHRTaWJsaW5nICgpIHtcbiAgICBjb25zdCBuID0gdGhpcy5faXRlbSA/IHRoaXMuX2l0ZW0ubmV4dCA6IG51bGxcbiAgICByZXR1cm4gbiA/IC8qKiBAdHlwZSB7WVhtbEVsZW1lbnR8WVhtbFRleHR9ICovICgvKiogQHR5cGUge0NvbnRlbnRUeXBlfSAqLyAobi5jb250ZW50KS50eXBlKSA6IG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBAdHlwZSB7WVhtbEVsZW1lbnR8WVhtbFRleHR8bnVsbH1cbiAgICovXG4gIGdldCBwcmV2U2libGluZyAoKSB7XG4gICAgY29uc3QgbiA9IHRoaXMuX2l0ZW0gPyB0aGlzLl9pdGVtLnByZXYgOiBudWxsXG4gICAgcmV0dXJuIG4gPyAvKiogQHR5cGUge1lYbWxFbGVtZW50fFlYbWxUZXh0fSAqLyAoLyoqIEB0eXBlIHtDb250ZW50VHlwZX0gKi8gKG4uY29udGVudCkudHlwZSkgOiBudWxsXG4gIH1cblxuICAvKipcbiAgICogSW50ZWdyYXRlIHRoaXMgdHlwZSBpbnRvIHRoZSBZanMgaW5zdGFuY2UuXG4gICAqXG4gICAqICogU2F2ZSB0aGlzIHN0cnVjdCBpbiB0aGUgb3NcbiAgICogKiBUaGlzIHR5cGUgaXMgc2VudCB0byBvdGhlciBjbGllbnRcbiAgICogKiBPYnNlcnZlciBmdW5jdGlvbnMgYXJlIGZpcmVkXG4gICAqXG4gICAqIEBwYXJhbSB7RG9jfSB5IFRoZSBZanMgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtJdGVtfSBpdGVtXG4gICAqL1xuICBfaW50ZWdyYXRlICh5LCBpdGVtKSB7XG4gICAgc3VwZXIuX2ludGVncmF0ZSh5LCBpdGVtKVxuICAgIDsoLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBhbnk+fSAqLyAodGhpcy5fcHJlbGltQXR0cnMpKS5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICB0aGlzLnNldEF0dHJpYnV0ZShrZXksIHZhbHVlKVxuICAgIH0pXG4gICAgdGhpcy5fcHJlbGltQXR0cnMgPSBudWxsXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBJdGVtIHdpdGggdGhlIHNhbWUgZWZmZWN0IGFzIHRoaXMgSXRlbSAod2l0aG91dCBwb3NpdGlvbiBlZmZlY3QpXG4gICAqXG4gICAqIEByZXR1cm4ge1lYbWxFbGVtZW50fVxuICAgKi9cbiAgX2NvcHkgKCkge1xuICAgIHJldHVybiBuZXcgWVhtbEVsZW1lbnQodGhpcy5ub2RlTmFtZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBNYWtlcyBhIGNvcHkgb2YgdGhpcyBkYXRhIHR5cGUgdGhhdCBjYW4gYmUgaW5jbHVkZWQgc29tZXdoZXJlIGVsc2UuXG4gICAqXG4gICAqIE5vdGUgdGhhdCB0aGUgY29udGVudCBpcyBvbmx5IHJlYWRhYmxlIF9hZnRlcl8gaXQgaGFzIGJlZW4gaW5jbHVkZWQgc29tZXdoZXJlIGluIHRoZSBZZG9jLlxuICAgKlxuICAgKiBAcmV0dXJuIHtZWG1sRWxlbWVudDxLVj59XG4gICAqL1xuICBjbG9uZSAoKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge1lYbWxFbGVtZW50PEtWPn1cbiAgICAgKi9cbiAgICBjb25zdCBlbCA9IG5ldyBZWG1sRWxlbWVudCh0aGlzLm5vZGVOYW1lKVxuICAgIGNvbnN0IGF0dHJzID0gdGhpcy5nZXRBdHRyaWJ1dGVzKClcbiAgICBvYmplY3QuZm9yRWFjaChhdHRycywgKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZShrZXksIC8qKiBAdHlwZSB7YW55fSAqLyAodmFsdWUpKVxuICAgIH0pXG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGVsLmluc2VydCgwLCB0aGlzLnRvQXJyYXkoKS5tYXAodiA9PiB2IGluc3RhbmNlb2YgQWJzdHJhY3RUeXBlID8gdi5jbG9uZSgpIDogdikpXG4gICAgcmV0dXJuIGVsXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgWE1MIHNlcmlhbGl6YXRpb24gb2YgdGhpcyBZWG1sRWxlbWVudC5cbiAgICogVGhlIGF0dHJpYnV0ZXMgYXJlIG9yZGVyZWQgYnkgYXR0cmlidXRlLW5hbWUsIHNvIHlvdSBjYW4gZWFzaWx5IHVzZSB0aGlzXG4gICAqIG1ldGhvZCB0byBjb21wYXJlIFlYbWxFbGVtZW50c1xuICAgKlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyB0eXBlLlxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICB0b1N0cmluZyAoKSB7XG4gICAgY29uc3QgYXR0cnMgPSB0aGlzLmdldEF0dHJpYnV0ZXMoKVxuICAgIGNvbnN0IHN0cmluZ0J1aWxkZXIgPSBbXVxuICAgIGNvbnN0IGtleXMgPSBbXVxuICAgIGZvciAoY29uc3Qga2V5IGluIGF0dHJzKSB7XG4gICAgICBrZXlzLnB1c2goa2V5KVxuICAgIH1cbiAgICBrZXlzLnNvcnQoKVxuICAgIGNvbnN0IGtleXNMZW4gPSBrZXlzLmxlbmd0aFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5c0xlbjsgaSsrKSB7XG4gICAgICBjb25zdCBrZXkgPSBrZXlzW2ldXG4gICAgICBzdHJpbmdCdWlsZGVyLnB1c2goa2V5ICsgJz1cIicgKyBhdHRyc1trZXldICsgJ1wiJylcbiAgICB9XG4gICAgY29uc3Qgbm9kZU5hbWUgPSB0aGlzLm5vZGVOYW1lLnRvTG9jYWxlTG93ZXJDYXNlKClcbiAgICBjb25zdCBhdHRyc1N0cmluZyA9IHN0cmluZ0J1aWxkZXIubGVuZ3RoID4gMCA/ICcgJyArIHN0cmluZ0J1aWxkZXIuam9pbignICcpIDogJydcbiAgICByZXR1cm4gYDwke25vZGVOYW1lfSR7YXR0cnNTdHJpbmd9PiR7c3VwZXIudG9TdHJpbmcoKX08LyR7bm9kZU5hbWV9PmBcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGFuIGF0dHJpYnV0ZSBmcm9tIHRoaXMgWVhtbEVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyaWJ1dGVOYW1lIFRoZSBhdHRyaWJ1dGUgbmFtZSB0aGF0IGlzIHRvIGJlIHJlbW92ZWQuXG4gICAqXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIHJlbW92ZUF0dHJpYnV0ZSAoYXR0cmlidXRlTmFtZSkge1xuICAgIGlmICh0aGlzLmRvYyAhPT0gbnVsbCkge1xuICAgICAgdHJhbnNhY3QodGhpcy5kb2MsIHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgdHlwZU1hcERlbGV0ZSh0cmFuc2FjdGlvbiwgdGhpcywgYXR0cmlidXRlTmFtZSlcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZyxhbnk+fSAqLyAodGhpcy5fcHJlbGltQXR0cnMpLmRlbGV0ZShhdHRyaWJ1dGVOYW1lKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIG9yIHVwZGF0ZXMgYW4gYXR0cmlidXRlLlxuICAgKlxuICAgKiBAdGVtcGxhdGUge2tleW9mIEtWICYgc3RyaW5nfSBLRVlcbiAgICpcbiAgICogQHBhcmFtIHtLRVl9IGF0dHJpYnV0ZU5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lIHRoYXQgaXMgdG8gYmUgc2V0LlxuICAgKiBAcGFyYW0ge0tWW0tFWV19IGF0dHJpYnV0ZVZhbHVlIFRoZSBhdHRyaWJ1dGUgdmFsdWUgdGhhdCBpcyB0byBiZSBzZXQuXG4gICAqXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIHNldEF0dHJpYnV0ZSAoYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVmFsdWUpIHtcbiAgICBpZiAodGhpcy5kb2MgIT09IG51bGwpIHtcbiAgICAgIHRyYW5zYWN0KHRoaXMuZG9jLCB0cmFuc2FjdGlvbiA9PiB7XG4gICAgICAgIHR5cGVNYXBTZXQodHJhbnNhY3Rpb24sIHRoaXMsIGF0dHJpYnV0ZU5hbWUsIGF0dHJpYnV0ZVZhbHVlKVxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBhbnk+fSAqLyAodGhpcy5fcHJlbGltQXR0cnMpLnNldChhdHRyaWJ1dGVOYW1lLCBhdHRyaWJ1dGVWYWx1ZSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBhdHRyaWJ1dGUgdmFsdWUgdGhhdCBiZWxvbmdzIHRvIHRoZSBhdHRyaWJ1dGUgbmFtZS5cbiAgICpcbiAgICogQHRlbXBsYXRlIHtrZXlvZiBLViAmIHN0cmluZ30gS0VZXG4gICAqXG4gICAqIEBwYXJhbSB7S0VZfSBhdHRyaWJ1dGVOYW1lIFRoZSBhdHRyaWJ1dGUgbmFtZSB0aGF0IGlkZW50aWZpZXMgdGhlXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJpZWQgdmFsdWUuXG4gICAqIEByZXR1cm4ge0tWW0tFWV18dW5kZWZpbmVkfSBUaGUgcXVlcmllZCBhdHRyaWJ1dGUgdmFsdWUuXG4gICAqXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIGdldEF0dHJpYnV0ZSAoYXR0cmlidXRlTmFtZSkge1xuICAgIHJldHVybiAvKiogQHR5cGUge2FueX0gKi8gKHR5cGVNYXBHZXQodGhpcywgYXR0cmlidXRlTmFtZSkpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIGFuIGF0dHJpYnV0ZSBleGlzdHNcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGF0dHJpYnV0ZU5hbWUgVGhlIGF0dHJpYnV0ZSBuYW1lIHRvIGNoZWNrIGZvciBleGlzdGVuY2UuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IHdoZXRoZXIgdGhlIGF0dHJpYnV0ZSBleGlzdHMuXG4gICAqXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIGhhc0F0dHJpYnV0ZSAoYXR0cmlidXRlTmFtZSkge1xuICAgIHJldHVybiAvKiogQHR5cGUge2FueX0gKi8gKHR5cGVNYXBIYXModGhpcywgYXR0cmlidXRlTmFtZSkpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbGwgYXR0cmlidXRlIG5hbWUvdmFsdWUgcGFpcnMgaW4gYSBKU09OIE9iamVjdC5cbiAgICpcbiAgICogQHBhcmFtIHtTbmFwc2hvdH0gW3NuYXBzaG90XVxuICAgKiBAcmV0dXJuIHt7IFtLZXkgaW4gRXh0cmFjdDxrZXlvZiBLVixzdHJpbmc+XT86IEtWW0tleV19fSBBIEpTT04gT2JqZWN0IHRoYXQgZGVzY3JpYmVzIHRoZSBhdHRyaWJ1dGVzLlxuICAgKlxuICAgKiBAcHVibGljXG4gICAqL1xuICBnZXRBdHRyaWJ1dGVzIChzbmFwc2hvdCkge1xuICAgIHJldHVybiAvKiogQHR5cGUge2FueX0gKi8gKHNuYXBzaG90ID8gdHlwZU1hcEdldEFsbFNuYXBzaG90KHRoaXMsIHNuYXBzaG90KSA6IHR5cGVNYXBHZXRBbGwodGhpcykpXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIERvbSBFbGVtZW50IHRoYXQgbWlycm9ycyB0aGlzIFlYbWxFbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge0RvY3VtZW50fSBbX2RvY3VtZW50PWRvY3VtZW50XSBUaGUgZG9jdW1lbnQgb2JqZWN0ICh5b3UgbXVzdCBkZWZpbmVcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyB3aGVuIGNhbGxpbmcgdGhpcyBtZXRob2QgaW5cbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZWpzKVxuICAgKiBAcGFyYW0ge09iamVjdDxzdHJpbmcsIGFueT59IFtob29rcz17fV0gT3B0aW9uYWwgcHJvcGVydHkgdG8gY3VzdG9taXplIGhvdyBob29rc1xuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZSBwcmVzZW50ZWQgaW4gdGhlIERPTVxuICAgKiBAcGFyYW0ge2FueX0gW2JpbmRpbmddIFlvdSBzaG91bGQgbm90IHNldCB0aGlzIHByb3BlcnR5LiBUaGlzIGlzXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZWQgaWYgRG9tQmluZGluZyB3YW50cyB0byBjcmVhdGUgYVxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NvY2lhdGlvbiB0byB0aGUgY3JlYXRlZCBET00gdHlwZS5cbiAgICogQHJldHVybiB7Tm9kZX0gVGhlIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudHxEb20gRWxlbWVudH1cbiAgICpcbiAgICogQHB1YmxpY1xuICAgKi9cbiAgdG9ET00gKF9kb2N1bWVudCA9IGRvY3VtZW50LCBob29rcyA9IHt9LCBiaW5kaW5nKSB7XG4gICAgY29uc3QgZG9tID0gX2RvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGhpcy5ub2RlTmFtZSlcbiAgICBjb25zdCBhdHRycyA9IHRoaXMuZ2V0QXR0cmlidXRlcygpXG4gICAgZm9yIChjb25zdCBrZXkgaW4gYXR0cnMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gYXR0cnNba2V5XVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZG9tLnNldEF0dHJpYnV0ZShrZXksIHZhbHVlKVxuICAgICAgfVxuICAgIH1cbiAgICB0eXBlTGlzdEZvckVhY2godGhpcywgeXhtbCA9PiB7XG4gICAgICBkb20uYXBwZW5kQ2hpbGQoeXhtbC50b0RPTShfZG9jdW1lbnQsIGhvb2tzLCBiaW5kaW5nKSlcbiAgICB9KVxuICAgIGlmIChiaW5kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGJpbmRpbmcuX2NyZWF0ZUFzc29jaWF0aW9uKGRvbSwgdGhpcylcbiAgICB9XG4gICAgcmV0dXJuIGRvbVxuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zZm9ybSB0aGUgcHJvcGVydGllcyBvZiB0aGlzIHR5cGUgdG8gYmluYXJ5IGFuZCB3cml0ZSBpdCB0byBhblxuICAgKiBCaW5hcnlFbmNvZGVyLlxuICAgKlxuICAgKiBUaGlzIGlzIGNhbGxlZCB3aGVuIHRoaXMgSXRlbSBpcyBzZW50IHRvIGEgcmVtb3RlIHBlZXIuXG4gICAqXG4gICAqIEBwYXJhbSB7VXBkYXRlRW5jb2RlclYxIHwgVXBkYXRlRW5jb2RlclYyfSBlbmNvZGVyIFRoZSBlbmNvZGVyIHRvIHdyaXRlIGRhdGEgdG8uXG4gICAqL1xuICBfd3JpdGUgKGVuY29kZXIpIHtcbiAgICBlbmNvZGVyLndyaXRlVHlwZVJlZihZWG1sRWxlbWVudFJlZklEKVxuICAgIGVuY29kZXIud3JpdGVLZXkodGhpcy5ub2RlTmFtZSlcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VXBkYXRlRGVjb2RlclYxIHwgVXBkYXRlRGVjb2RlclYyfSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtZWG1sRWxlbWVudH1cbiAqXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRZWG1sRWxlbWVudCA9IGRlY29kZXIgPT4gbmV3IFlYbWxFbGVtZW50KGRlY29kZXIucmVhZEtleSgpKVxuIiwgImltcG9ydCB7XG4gIFlFdmVudCxcbiAgWVhtbFRleHQsIFlYbWxFbGVtZW50LCBZWG1sRnJhZ21lbnQsIFRyYW5zYWN0aW9uIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbn0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJ1xuXG4vKipcbiAqIEBleHRlbmRzIFlFdmVudDxZWG1sRWxlbWVudHxZWG1sVGV4dHxZWG1sRnJhZ21lbnQ+XG4gKiBBbiBFdmVudCB0aGF0IGRlc2NyaWJlcyBjaGFuZ2VzIG9uIGEgWVhtbCBFbGVtZW50IG9yIFl4bWwgRnJhZ21lbnRcbiAqL1xuZXhwb3J0IGNsYXNzIFlYbWxFdmVudCBleHRlbmRzIFlFdmVudCB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1lYbWxFbGVtZW50fFlYbWxUZXh0fFlYbWxGcmFnbWVudH0gdGFyZ2V0IFRoZSB0YXJnZXQgb24gd2hpY2ggdGhlIGV2ZW50IGlzIGNyZWF0ZWQuXG4gICAqIEBwYXJhbSB7U2V0PHN0cmluZ3xudWxsPn0gc3VicyBUaGUgc2V0IG9mIGNoYW5nZWQgYXR0cmlidXRlcy4gYG51bGxgIGlzIGluY2x1ZGVkIGlmIHRoZVxuICAgKiAgICAgICAgICAgICAgICAgICBjaGlsZCBsaXN0IGNoYW5nZWQuXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uIFRoZSB0cmFuc2FjdGlvbiBpbnN0YW5jZSB3aXRoIHdoaWNoIHRoZVxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFuZ2Ugd2FzIGNyZWF0ZWQuXG4gICAqL1xuICBjb25zdHJ1Y3RvciAodGFyZ2V0LCBzdWJzLCB0cmFuc2FjdGlvbikge1xuICAgIHN1cGVyKHRhcmdldCwgdHJhbnNhY3Rpb24pXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgY2hpbGRyZW4gY2hhbmdlZC5cbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHRoaXMuY2hpbGRMaXN0Q2hhbmdlZCA9IGZhbHNlXG4gICAgLyoqXG4gICAgICogU2V0IG9mIGFsbCBjaGFuZ2VkIGF0dHJpYnV0ZXMuXG4gICAgICogQHR5cGUge1NldDxzdHJpbmc+fVxuICAgICAqL1xuICAgIHRoaXMuYXR0cmlidXRlc0NoYW5nZWQgPSBuZXcgU2V0KClcbiAgICBzdWJzLmZvckVhY2goKHN1YikgPT4ge1xuICAgICAgaWYgKHN1YiA9PT0gbnVsbCkge1xuICAgICAgICB0aGlzLmNoaWxkTGlzdENoYW5nZWQgPSB0cnVlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmF0dHJpYnV0ZXNDaGFuZ2VkLmFkZChzdWIpXG4gICAgICB9XG4gICAgfSlcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIFlNYXAsXG4gIFlYbWxIb29rUmVmSUQsXG4gIFVwZGF0ZURlY29kZXJWMSwgVXBkYXRlRGVjb2RlclYyLCBVcGRhdGVFbmNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcblxuLyoqXG4gKiBZb3UgY2FuIG1hbmFnZSBiaW5kaW5nIHRvIGEgY3VzdG9tIHR5cGUgd2l0aCBZWG1sSG9vay5cbiAqXG4gKiBAZXh0ZW5kcyB7WU1hcDxhbnk+fVxuICovXG5leHBvcnQgY2xhc3MgWVhtbEhvb2sgZXh0ZW5kcyBZTWFwIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBob29rTmFtZSBub2RlTmFtZSBvZiB0aGUgRG9tIE5vZGUuXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoaG9va05hbWUpIHtcbiAgICBzdXBlcigpXG4gICAgLyoqXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICB0aGlzLmhvb2tOYW1lID0gaG9va05hbWVcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIEl0ZW0gd2l0aCB0aGUgc2FtZSBlZmZlY3QgYXMgdGhpcyBJdGVtICh3aXRob3V0IHBvc2l0aW9uIGVmZmVjdClcbiAgICovXG4gIF9jb3B5ICgpIHtcbiAgICByZXR1cm4gbmV3IFlYbWxIb29rKHRoaXMuaG9va05hbWUpXG4gIH1cblxuICAvKipcbiAgICogTWFrZXMgYSBjb3B5IG9mIHRoaXMgZGF0YSB0eXBlIHRoYXQgY2FuIGJlIGluY2x1ZGVkIHNvbWV3aGVyZSBlbHNlLlxuICAgKlxuICAgKiBOb3RlIHRoYXQgdGhlIGNvbnRlbnQgaXMgb25seSByZWFkYWJsZSBfYWZ0ZXJfIGl0IGhhcyBiZWVuIGluY2x1ZGVkIHNvbWV3aGVyZSBpbiB0aGUgWWRvYy5cbiAgICpcbiAgICogQHJldHVybiB7WVhtbEhvb2t9XG4gICAqL1xuICBjbG9uZSAoKSB7XG4gICAgY29uc3QgZWwgPSBuZXcgWVhtbEhvb2sodGhpcy5ob29rTmFtZSlcbiAgICB0aGlzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgIGVsLnNldChrZXksIHZhbHVlKVxuICAgIH0pXG4gICAgcmV0dXJuIGVsXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIERvbSBFbGVtZW50IHRoYXQgbWlycm9ycyB0aGlzIFlYbWxFbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge0RvY3VtZW50fSBbX2RvY3VtZW50PWRvY3VtZW50XSBUaGUgZG9jdW1lbnQgb2JqZWN0ICh5b3UgbXVzdCBkZWZpbmVcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcyB3aGVuIGNhbGxpbmcgdGhpcyBtZXRob2QgaW5cbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZWpzKVxuICAgKiBAcGFyYW0ge09iamVjdC48c3RyaW5nLCBhbnk+fSBbaG9va3NdIE9wdGlvbmFsIHByb3BlcnR5IHRvIGN1c3RvbWl6ZSBob3cgaG9va3NcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmUgcHJlc2VudGVkIGluIHRoZSBET01cbiAgICogQHBhcmFtIHthbnl9IFtiaW5kaW5nXSBZb3Ugc2hvdWxkIG5vdCBzZXQgdGhpcyBwcm9wZXJ0eS4gVGhpcyBpc1xuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VkIGlmIERvbUJpbmRpbmcgd2FudHMgdG8gY3JlYXRlIGFcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzb2NpYXRpb24gdG8gdGhlIGNyZWF0ZWQgRE9NIHR5cGVcbiAgICogQHJldHVybiB7RWxlbWVudH0gVGhlIHtAbGluayBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudHxEb20gRWxlbWVudH1cbiAgICpcbiAgICogQHB1YmxpY1xuICAgKi9cbiAgdG9ET00gKF9kb2N1bWVudCA9IGRvY3VtZW50LCBob29rcyA9IHt9LCBiaW5kaW5nKSB7XG4gICAgY29uc3QgaG9vayA9IGhvb2tzW3RoaXMuaG9va05hbWVdXG4gICAgbGV0IGRvbVxuICAgIGlmIChob29rICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGRvbSA9IGhvb2suY3JlYXRlRG9tKHRoaXMpXG4gICAgfSBlbHNlIHtcbiAgICAgIGRvbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGhpcy5ob29rTmFtZSlcbiAgICB9XG4gICAgZG9tLnNldEF0dHJpYnV0ZSgnZGF0YS15anMtaG9vaycsIHRoaXMuaG9va05hbWUpXG4gICAgaWYgKGJpbmRpbmcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYmluZGluZy5fY3JlYXRlQXNzb2NpYXRpb24oZG9tLCB0aGlzKVxuICAgIH1cbiAgICByZXR1cm4gZG9tXG4gIH1cblxuICAvKipcbiAgICogVHJhbnNmb3JtIHRoZSBwcm9wZXJ0aWVzIG9mIHRoaXMgdHlwZSB0byBiaW5hcnkgYW5kIHdyaXRlIGl0IHRvIGFuXG4gICAqIEJpbmFyeUVuY29kZXIuXG4gICAqXG4gICAqIFRoaXMgaXMgY2FsbGVkIHdoZW4gdGhpcyBJdGVtIGlzIHNlbnQgdG8gYSByZW1vdGUgcGVlci5cbiAgICpcbiAgICogQHBhcmFtIHtVcGRhdGVFbmNvZGVyVjEgfCBVcGRhdGVFbmNvZGVyVjJ9IGVuY29kZXIgVGhlIGVuY29kZXIgdG8gd3JpdGUgZGF0YSB0by5cbiAgICovXG4gIF93cml0ZSAoZW5jb2Rlcikge1xuICAgIGVuY29kZXIud3JpdGVUeXBlUmVmKFlYbWxIb29rUmVmSUQpXG4gICAgZW5jb2Rlci53cml0ZUtleSh0aGlzLmhvb2tOYW1lKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtVcGRhdGVEZWNvZGVyVjEgfCBVcGRhdGVEZWNvZGVyVjJ9IGRlY29kZXJcbiAqIEByZXR1cm4ge1lYbWxIb29rfVxuICpcbiAqIEBwcml2YXRlXG4gKiBAZnVuY3Rpb25cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRZWG1sSG9vayA9IGRlY29kZXIgPT5cbiAgbmV3IFlYbWxIb29rKGRlY29kZXIucmVhZEtleSgpKVxuIiwgImltcG9ydCB7XG4gIFlUZXh0LFxuICBZWG1sVGV4dFJlZklELFxuICBDb250ZW50VHlwZSwgWVhtbEVsZW1lbnQsIFVwZGF0ZURlY29kZXJWMSwgVXBkYXRlRGVjb2RlclYyLCBVcGRhdGVFbmNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMiwgLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbi8qKlxuICogUmVwcmVzZW50cyB0ZXh0IGluIGEgRG9tIEVsZW1lbnQuIEluIHRoZSBmdXR1cmUgdGhpcyB0eXBlIHdpbGwgYWxzbyBoYW5kbGVcbiAqIHNpbXBsZSBmb3JtYXR0aW5nIGluZm9ybWF0aW9uIGxpa2UgYm9sZCBhbmQgaXRhbGljLlxuICovXG5leHBvcnQgY2xhc3MgWVhtbFRleHQgZXh0ZW5kcyBZVGV4dCB7XG4gIC8qKlxuICAgKiBAdHlwZSB7WVhtbEVsZW1lbnR8WVhtbFRleHR8bnVsbH1cbiAgICovXG4gIGdldCBuZXh0U2libGluZyAoKSB7XG4gICAgY29uc3QgbiA9IHRoaXMuX2l0ZW0gPyB0aGlzLl9pdGVtLm5leHQgOiBudWxsXG4gICAgcmV0dXJuIG4gPyAvKiogQHR5cGUge1lYbWxFbGVtZW50fFlYbWxUZXh0fSAqLyAoLyoqIEB0eXBlIHtDb250ZW50VHlwZX0gKi8gKG4uY29udGVudCkudHlwZSkgOiBudWxsXG4gIH1cblxuICAvKipcbiAgICogQHR5cGUge1lYbWxFbGVtZW50fFlYbWxUZXh0fG51bGx9XG4gICAqL1xuICBnZXQgcHJldlNpYmxpbmcgKCkge1xuICAgIGNvbnN0IG4gPSB0aGlzLl9pdGVtID8gdGhpcy5faXRlbS5wcmV2IDogbnVsbFxuICAgIHJldHVybiBuID8gLyoqIEB0eXBlIHtZWG1sRWxlbWVudHxZWG1sVGV4dH0gKi8gKC8qKiBAdHlwZSB7Q29udGVudFR5cGV9ICovIChuLmNvbnRlbnQpLnR5cGUpIDogbnVsbFxuICB9XG5cbiAgX2NvcHkgKCkge1xuICAgIHJldHVybiBuZXcgWVhtbFRleHQoKVxuICB9XG5cbiAgLyoqXG4gICAqIE1ha2VzIGEgY29weSBvZiB0aGlzIGRhdGEgdHlwZSB0aGF0IGNhbiBiZSBpbmNsdWRlZCBzb21ld2hlcmUgZWxzZS5cbiAgICpcbiAgICogTm90ZSB0aGF0IHRoZSBjb250ZW50IGlzIG9ubHkgcmVhZGFibGUgX2FmdGVyXyBpdCBoYXMgYmVlbiBpbmNsdWRlZCBzb21ld2hlcmUgaW4gdGhlIFlkb2MuXG4gICAqXG4gICAqIEByZXR1cm4ge1lYbWxUZXh0fVxuICAgKi9cbiAgY2xvbmUgKCkge1xuICAgIGNvbnN0IHRleHQgPSBuZXcgWVhtbFRleHQoKVxuICAgIHRleHQuYXBwbHlEZWx0YSh0aGlzLnRvRGVsdGEoKSlcbiAgICByZXR1cm4gdGV4dFxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBEb20gRWxlbWVudCB0aGF0IG1pcnJvcnMgdGhpcyBZWG1sVGV4dC5cbiAgICpcbiAgICogQHBhcmFtIHtEb2N1bWVudH0gW19kb2N1bWVudD1kb2N1bWVudF0gVGhlIGRvY3VtZW50IG9iamVjdCAoeW91IG11c3QgZGVmaW5lXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgd2hlbiBjYWxsaW5nIHRoaXMgbWV0aG9kIGluXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVqcylcbiAgICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLCBhbnk+fSBbaG9va3NdIE9wdGlvbmFsIHByb3BlcnR5IHRvIGN1c3RvbWl6ZSBob3cgaG9va3NcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmUgcHJlc2VudGVkIGluIHRoZSBET01cbiAgICogQHBhcmFtIHthbnl9IFtiaW5kaW5nXSBZb3Ugc2hvdWxkIG5vdCBzZXQgdGhpcyBwcm9wZXJ0eS4gVGhpcyBpc1xuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VkIGlmIERvbUJpbmRpbmcgd2FudHMgdG8gY3JlYXRlIGFcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzb2NpYXRpb24gdG8gdGhlIGNyZWF0ZWQgRE9NIHR5cGUuXG4gICAqIEByZXR1cm4ge1RleHR9IFRoZSB7QGxpbmsgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0VsZW1lbnR8RG9tIEVsZW1lbnR9XG4gICAqXG4gICAqIEBwdWJsaWNcbiAgICovXG4gIHRvRE9NIChfZG9jdW1lbnQgPSBkb2N1bWVudCwgaG9va3MsIGJpbmRpbmcpIHtcbiAgICBjb25zdCBkb20gPSBfZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGhpcy50b1N0cmluZygpKVxuICAgIGlmIChiaW5kaW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGJpbmRpbmcuX2NyZWF0ZUFzc29jaWF0aW9uKGRvbSwgdGhpcylcbiAgICB9XG4gICAgcmV0dXJuIGRvbVxuICB9XG5cbiAgdG9TdHJpbmcgKCkge1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICByZXR1cm4gdGhpcy50b0RlbHRhKCkubWFwKGRlbHRhID0+IHtcbiAgICAgIGNvbnN0IG5lc3RlZE5vZGVzID0gW11cbiAgICAgIGZvciAoY29uc3Qgbm9kZU5hbWUgaW4gZGVsdGEuYXR0cmlidXRlcykge1xuICAgICAgICBjb25zdCBhdHRycyA9IFtdXG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGRlbHRhLmF0dHJpYnV0ZXNbbm9kZU5hbWVdKSB7XG4gICAgICAgICAgYXR0cnMucHVzaCh7IGtleSwgdmFsdWU6IGRlbHRhLmF0dHJpYnV0ZXNbbm9kZU5hbWVdW2tleV0gfSlcbiAgICAgICAgfVxuICAgICAgICAvLyBzb3J0IGF0dHJpYnV0ZXMgdG8gZ2V0IGEgdW5pcXVlIG9yZGVyXG4gICAgICAgIGF0dHJzLnNvcnQoKGEsIGIpID0+IGEua2V5IDwgYi5rZXkgPyAtMSA6IDEpXG4gICAgICAgIG5lc3RlZE5vZGVzLnB1c2goeyBub2RlTmFtZSwgYXR0cnMgfSlcbiAgICAgIH1cbiAgICAgIC8vIHNvcnQgbm9kZSBvcmRlciB0byBnZXQgYSB1bmlxdWUgb3JkZXJcbiAgICAgIG5lc3RlZE5vZGVzLnNvcnQoKGEsIGIpID0+IGEubm9kZU5hbWUgPCBiLm5vZGVOYW1lID8gLTEgOiAxKVxuICAgICAgLy8gbm93IGNvbnZlcnQgdG8gZG9tIHN0cmluZ1xuICAgICAgbGV0IHN0ciA9ICcnXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5lc3RlZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IG5vZGUgPSBuZXN0ZWROb2Rlc1tpXVxuICAgICAgICBzdHIgKz0gYDwke25vZGUubm9kZU5hbWV9YFxuICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG5vZGUuYXR0cnMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICBjb25zdCBhdHRyID0gbm9kZS5hdHRyc1tqXVxuICAgICAgICAgIHN0ciArPSBgICR7YXR0ci5rZXl9PVwiJHthdHRyLnZhbHVlfVwiYFxuICAgICAgICB9XG4gICAgICAgIHN0ciArPSAnPidcbiAgICAgIH1cbiAgICAgIHN0ciArPSBkZWx0YS5pbnNlcnRcbiAgICAgIGZvciAobGV0IGkgPSBuZXN0ZWROb2Rlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBzdHIgKz0gYDwvJHtuZXN0ZWROb2Rlc1tpXS5ub2RlTmFtZX0+YFxuICAgICAgfVxuICAgICAgcmV0dXJuIHN0clxuICAgIH0pLmpvaW4oJycpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9KU09OICgpIHtcbiAgICByZXR1cm4gdGhpcy50b1N0cmluZygpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtVcGRhdGVFbmNvZGVyVjEgfCBVcGRhdGVFbmNvZGVyVjJ9IGVuY29kZXJcbiAgICovXG4gIF93cml0ZSAoZW5jb2Rlcikge1xuICAgIGVuY29kZXIud3JpdGVUeXBlUmVmKFlYbWxUZXh0UmVmSUQpXG4gIH1cbn1cblxuLyoqXG4gKiBAcGFyYW0ge1VwZGF0ZURlY29kZXJWMSB8IFVwZGF0ZURlY29kZXJWMn0gZGVjb2RlclxuICogQHJldHVybiB7WVhtbFRleHR9XG4gKlxuICogQHByaXZhdGVcbiAqIEBmdW5jdGlvblxuICovXG5leHBvcnQgY29uc3QgcmVhZFlYbWxUZXh0ID0gZGVjb2RlciA9PiBuZXcgWVhtbFRleHQoKVxuIiwgImltcG9ydCB7XG4gIFVwZGF0ZUVuY29kZXJWMSwgVXBkYXRlRW5jb2RlclYyLCBJRCwgVHJhbnNhY3Rpb24gLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbmltcG9ydCAqIGFzIGVycm9yIGZyb20gJ2xpYjAvZXJyb3InXG5cbmV4cG9ydCBjbGFzcyBBYnN0cmFjdFN0cnVjdCB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0lEfSBpZFxuICAgKiBAcGFyYW0ge251bWJlcn0gbGVuZ3RoXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoaWQsIGxlbmd0aCkge1xuICAgIHRoaXMuaWQgPSBpZFxuICAgIHRoaXMubGVuZ3RoID0gbGVuZ3RoXG4gIH1cblxuICAvKipcbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqL1xuICBnZXQgZGVsZXRlZCAoKSB7XG4gICAgdGhyb3cgZXJyb3IubWV0aG9kVW5pbXBsZW1lbnRlZCgpXG4gIH1cblxuICAvKipcbiAgICogTWVyZ2UgdGhpcyBzdHJ1Y3Qgd2l0aCB0aGUgaXRlbSB0byB0aGUgcmlnaHQuXG4gICAqIFRoaXMgbWV0aG9kIGlzIGFscmVhZHkgYXNzdW1pbmcgdGhhdCBgdGhpcy5pZC5jbG9jayArIHRoaXMubGVuZ3RoID09PSB0aGlzLmlkLmNsb2NrYC5cbiAgICogQWxzbyB0aGlzIG1ldGhvZCBkb2VzICpub3QqIHJlbW92ZSByaWdodCBmcm9tIFN0cnVjdFN0b3JlIVxuICAgKiBAcGFyYW0ge0Fic3RyYWN0U3RydWN0fSByaWdodFxuICAgKiBAcmV0dXJuIHtib29sZWFufSB3aGV0aGVyIHRoaXMgbWVyZ2VkIHdpdGggcmlnaHRcbiAgICovXG4gIG1lcmdlV2l0aCAocmlnaHQpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1VwZGF0ZUVuY29kZXJWMSB8IFVwZGF0ZUVuY29kZXJWMn0gZW5jb2RlciBUaGUgZW5jb2RlciB0byB3cml0ZSBkYXRhIHRvLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBlbmNvZGluZ1JlZlxuICAgKi9cbiAgd3JpdGUgKGVuY29kZXIsIG9mZnNldCwgZW5jb2RpbmdSZWYpIHtcbiAgICB0aHJvdyBlcnJvci5tZXRob2RVbmltcGxlbWVudGVkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICBpbnRlZ3JhdGUgKHRyYW5zYWN0aW9uLCBvZmZzZXQpIHtcbiAgICB0aHJvdyBlcnJvci5tZXRob2RVbmltcGxlbWVudGVkKClcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIEFic3RyYWN0U3RydWN0LFxuICBhZGRTdHJ1Y3QsXG4gIFVwZGF0ZURlY29kZXJWMSwgVXBkYXRlRGVjb2RlclYyLCBVcGRhdGVFbmNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMiwgU3RydWN0U3RvcmUsIFRyYW5zYWN0aW9uLCBJRCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcblxuZXhwb3J0IGNvbnN0IHN0cnVjdEdDUmVmTnVtYmVyID0gMFxuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBHQyBleHRlbmRzIEFic3RyYWN0U3RydWN0IHtcbiAgZ2V0IGRlbGV0ZWQgKCkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBkZWxldGUgKCkge31cblxuICAvKipcbiAgICogQHBhcmFtIHtHQ30gcmlnaHRcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIG1lcmdlV2l0aCAocmlnaHQpIHtcbiAgICBpZiAodGhpcy5jb25zdHJ1Y3RvciAhPT0gcmlnaHQuY29uc3RydWN0b3IpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICB0aGlzLmxlbmd0aCArPSByaWdodC5sZW5ndGhcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICovXG4gIGludGVncmF0ZSAodHJhbnNhY3Rpb24sIG9mZnNldCkge1xuICAgIGlmIChvZmZzZXQgPiAwKSB7XG4gICAgICB0aGlzLmlkLmNsb2NrICs9IG9mZnNldFxuICAgICAgdGhpcy5sZW5ndGggLT0gb2Zmc2V0XG4gICAgfVxuICAgIGFkZFN0cnVjdCh0cmFuc2FjdGlvbi5kb2Muc3RvcmUsIHRoaXMpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtVcGRhdGVFbmNvZGVyVjEgfCBVcGRhdGVFbmNvZGVyVjJ9IGVuY29kZXJcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICAgKi9cbiAgd3JpdGUgKGVuY29kZXIsIG9mZnNldCkge1xuICAgIGVuY29kZXIud3JpdGVJbmZvKHN0cnVjdEdDUmVmTnVtYmVyKVxuICAgIGVuY29kZXIud3JpdGVMZW4odGhpcy5sZW5ndGggLSBvZmZzZXQpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAgICogQHJldHVybiB7bnVsbCB8IG51bWJlcn1cbiAgICovXG4gIGdldE1pc3NpbmcgKHRyYW5zYWN0aW9uLCBzdG9yZSkge1xuICAgIHJldHVybiBudWxsXG4gIH1cbn1cbiIsICJpbXBvcnQge1xuICBVcGRhdGVEZWNvZGVyVjEsIFVwZGF0ZURlY29kZXJWMiwgVXBkYXRlRW5jb2RlclYxLCBVcGRhdGVFbmNvZGVyVjIsIFN0cnVjdFN0b3JlLCBJdGVtLCBUcmFuc2FjdGlvbiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcblxuaW1wb3J0ICogYXMgZXJyb3IgZnJvbSAnbGliMC9lcnJvcidcblxuZXhwb3J0IGNsYXNzIENvbnRlbnRCaW5hcnkge1xuICAvKipcbiAgICogQHBhcmFtIHtVaW50OEFycmF5fSBjb250ZW50XG4gICAqL1xuICBjb25zdHJ1Y3RvciAoY29udGVudCkge1xuICAgIHRoaXMuY29udGVudCA9IGNvbnRlbnRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICBnZXRMZW5ndGggKCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8YW55Pn1cbiAgICovXG4gIGdldENvbnRlbnQgKCkge1xuICAgIHJldHVybiBbdGhpcy5jb250ZW50XVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBpc0NvdW50YWJsZSAoKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtDb250ZW50QmluYXJ5fVxuICAgKi9cbiAgY29weSAoKSB7XG4gICAgcmV0dXJuIG5ldyBDb250ZW50QmluYXJ5KHRoaXMuY29udGVudClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqIEByZXR1cm4ge0NvbnRlbnRCaW5hcnl9XG4gICAqL1xuICBzcGxpY2UgKG9mZnNldCkge1xuICAgIHRocm93IGVycm9yLm1ldGhvZFVuaW1wbGVtZW50ZWQoKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Q29udGVudEJpbmFyeX0gcmlnaHRcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIG1lcmdlV2l0aCAocmlnaHQpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge0l0ZW19IGl0ZW1cbiAgICovXG4gIGludGVncmF0ZSAodHJhbnNhY3Rpb24sIGl0ZW0pIHt9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKi9cbiAgZGVsZXRlICh0cmFuc2FjdGlvbikge31cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RydWN0U3RvcmV9IHN0b3JlXG4gICAqL1xuICBnYyAoc3RvcmUpIHt9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1VwZGF0ZUVuY29kZXJWMSB8IFVwZGF0ZUVuY29kZXJWMn0gZW5jb2RlclxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICB3cml0ZSAoZW5jb2Rlciwgb2Zmc2V0KSB7XG4gICAgZW5jb2Rlci53cml0ZUJ1Zih0aGlzLmNvbnRlbnQpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0UmVmICgpIHtcbiAgICByZXR1cm4gM1xuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtVcGRhdGVEZWNvZGVyVjEgfCBVcGRhdGVEZWNvZGVyVjIgfSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtDb250ZW50QmluYXJ5fVxuICovXG5leHBvcnQgY29uc3QgcmVhZENvbnRlbnRCaW5hcnkgPSBkZWNvZGVyID0+IG5ldyBDb250ZW50QmluYXJ5KGRlY29kZXIucmVhZEJ1ZigpKVxuIiwgImltcG9ydCB7XG4gIGFkZFRvRGVsZXRlU2V0LFxuICBVcGRhdGVEZWNvZGVyVjEsIFVwZGF0ZURlY29kZXJWMiwgVXBkYXRlRW5jb2RlclYxLCBVcGRhdGVFbmNvZGVyVjIsIFN0cnVjdFN0b3JlLCBJdGVtLCBUcmFuc2FjdGlvbiAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcblxuZXhwb3J0IGNsYXNzIENvbnRlbnREZWxldGVkIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5cbiAgICovXG4gIGNvbnN0cnVjdG9yIChsZW4pIHtcbiAgICB0aGlzLmxlbiA9IGxlblxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldExlbmd0aCAoKSB7XG4gICAgcmV0dXJuIHRoaXMubGVuXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8YW55Pn1cbiAgICovXG4gIGdldENvbnRlbnQgKCkge1xuICAgIHJldHVybiBbXVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBpc0NvdW50YWJsZSAoKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7Q29udGVudERlbGV0ZWR9XG4gICAqL1xuICBjb3B5ICgpIHtcbiAgICByZXR1cm4gbmV3IENvbnRlbnREZWxldGVkKHRoaXMubGVuKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICogQHJldHVybiB7Q29udGVudERlbGV0ZWR9XG4gICAqL1xuICBzcGxpY2UgKG9mZnNldCkge1xuICAgIGNvbnN0IHJpZ2h0ID0gbmV3IENvbnRlbnREZWxldGVkKHRoaXMubGVuIC0gb2Zmc2V0KVxuICAgIHRoaXMubGVuID0gb2Zmc2V0XG4gICAgcmV0dXJuIHJpZ2h0XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtDb250ZW50RGVsZXRlZH0gcmlnaHRcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIG1lcmdlV2l0aCAocmlnaHQpIHtcbiAgICB0aGlzLmxlbiArPSByaWdodC5sZW5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7SXRlbX0gaXRlbVxuICAgKi9cbiAgaW50ZWdyYXRlICh0cmFuc2FjdGlvbiwgaXRlbSkge1xuICAgIGFkZFRvRGVsZXRlU2V0KHRyYW5zYWN0aW9uLmRlbGV0ZVNldCwgaXRlbS5pZC5jbGllbnQsIGl0ZW0uaWQuY2xvY2ssIHRoaXMubGVuKVxuICAgIGl0ZW0ubWFya0RlbGV0ZWQoKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqL1xuICBkZWxldGUgKHRyYW5zYWN0aW9uKSB7fVxuICAvKipcbiAgICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAgICovXG4gIGdjIChzdG9yZSkge31cbiAgLyoqXG4gICAqIEBwYXJhbSB7VXBkYXRlRW5jb2RlclYxIHwgVXBkYXRlRW5jb2RlclYyfSBlbmNvZGVyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICovXG4gIHdyaXRlIChlbmNvZGVyLCBvZmZzZXQpIHtcbiAgICBlbmNvZGVyLndyaXRlTGVuKHRoaXMubGVuIC0gb2Zmc2V0KVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldFJlZiAoKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKlxuICogQHBhcmFtIHtVcGRhdGVEZWNvZGVyVjEgfCBVcGRhdGVEZWNvZGVyVjIgfSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtDb250ZW50RGVsZXRlZH1cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRDb250ZW50RGVsZXRlZCA9IGRlY29kZXIgPT4gbmV3IENvbnRlbnREZWxldGVkKGRlY29kZXIucmVhZExlbigpKVxuIiwgImltcG9ydCB7XG4gIERvYywgVXBkYXRlRGVjb2RlclYxLCBVcGRhdGVEZWNvZGVyVjIsIFVwZGF0ZUVuY29kZXJWMSwgVXBkYXRlRW5jb2RlclYyLCBTdHJ1Y3RTdG9yZSwgVHJhbnNhY3Rpb24sIEl0ZW0gLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbmltcG9ydCAqIGFzIGVycm9yIGZyb20gJ2xpYjAvZXJyb3InXG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGd1aWRcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgYW55Pn0gb3B0c1xuICovXG5jb25zdCBjcmVhdGVEb2NGcm9tT3B0cyA9IChndWlkLCBvcHRzKSA9PiBuZXcgRG9jKHsgZ3VpZCwgLi4ub3B0cywgc2hvdWxkTG9hZDogb3B0cy5zaG91bGRMb2FkIHx8IG9wdHMuYXV0b0xvYWQgfHwgZmFsc2UgfSlcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgQ29udGVudERvYyB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0RvY30gZG9jXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoZG9jKSB7XG4gICAgaWYgKGRvYy5faXRlbSkge1xuICAgICAgY29uc29sZS5lcnJvcignVGhpcyBkb2N1bWVudCB3YXMgYWxyZWFkeSBpbnRlZ3JhdGVkIGFzIGEgc3ViLWRvY3VtZW50LiBZb3Ugc2hvdWxkIGNyZWF0ZSBhIHNlY29uZCBpbnN0YW5jZSBpbnN0ZWFkIHdpdGggdGhlIHNhbWUgZ3VpZC4nKVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7RG9jfVxuICAgICAqL1xuICAgIHRoaXMuZG9jID0gZG9jXG4gICAgLyoqXG4gICAgICogQHR5cGUge2FueX1cbiAgICAgKi9cbiAgICBjb25zdCBvcHRzID0ge31cbiAgICB0aGlzLm9wdHMgPSBvcHRzXG4gICAgaWYgKCFkb2MuZ2MpIHtcbiAgICAgIG9wdHMuZ2MgPSBmYWxzZVxuICAgIH1cbiAgICBpZiAoZG9jLmF1dG9Mb2FkKSB7XG4gICAgICBvcHRzLmF1dG9Mb2FkID0gdHJ1ZVxuICAgIH1cbiAgICBpZiAoZG9jLm1ldGEgIT09IG51bGwpIHtcbiAgICAgIG9wdHMubWV0YSA9IGRvYy5tZXRhXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldExlbmd0aCAoKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxhbnk+fVxuICAgKi9cbiAgZ2V0Q29udGVudCAoKSB7XG4gICAgcmV0dXJuIFt0aGlzLmRvY11cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaXNDb3VudGFibGUgKCkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7Q29udGVudERvY31cbiAgICovXG4gIGNvcHkgKCkge1xuICAgIHJldHVybiBuZXcgQ29udGVudERvYyhjcmVhdGVEb2NGcm9tT3B0cyh0aGlzLmRvYy5ndWlkLCB0aGlzLm9wdHMpKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICogQHJldHVybiB7Q29udGVudERvY31cbiAgICovXG4gIHNwbGljZSAob2Zmc2V0KSB7XG4gICAgdGhyb3cgZXJyb3IubWV0aG9kVW5pbXBsZW1lbnRlZCgpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtDb250ZW50RG9jfSByaWdodFxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgbWVyZ2VXaXRoIChyaWdodCkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7SXRlbX0gaXRlbVxuICAgKi9cbiAgaW50ZWdyYXRlICh0cmFuc2FjdGlvbiwgaXRlbSkge1xuICAgIC8vIHRoaXMgbmVlZHMgdG8gYmUgcmVmbGVjdGVkIGluIGRvYy5kZXN0cm95IGFzIHdlbGxcbiAgICB0aGlzLmRvYy5faXRlbSA9IGl0ZW1cbiAgICB0cmFuc2FjdGlvbi5zdWJkb2NzQWRkZWQuYWRkKHRoaXMuZG9jKVxuICAgIGlmICh0aGlzLmRvYy5zaG91bGRMb2FkKSB7XG4gICAgICB0cmFuc2FjdGlvbi5zdWJkb2NzTG9hZGVkLmFkZCh0aGlzLmRvYylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICovXG4gIGRlbGV0ZSAodHJhbnNhY3Rpb24pIHtcbiAgICBpZiAodHJhbnNhY3Rpb24uc3ViZG9jc0FkZGVkLmhhcyh0aGlzLmRvYykpIHtcbiAgICAgIHRyYW5zYWN0aW9uLnN1YmRvY3NBZGRlZC5kZWxldGUodGhpcy5kb2MpXG4gICAgfSBlbHNlIHtcbiAgICAgIHRyYW5zYWN0aW9uLnN1YmRvY3NSZW1vdmVkLmFkZCh0aGlzLmRvYylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAgICovXG4gIGdjIChzdG9yZSkgeyB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VXBkYXRlRW5jb2RlclYxIHwgVXBkYXRlRW5jb2RlclYyfSBlbmNvZGVyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICovXG4gIHdyaXRlIChlbmNvZGVyLCBvZmZzZXQpIHtcbiAgICBlbmNvZGVyLndyaXRlU3RyaW5nKHRoaXMuZG9jLmd1aWQpXG4gICAgZW5jb2Rlci53cml0ZUFueSh0aGlzLm9wdHMpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0UmVmICgpIHtcbiAgICByZXR1cm4gOVxuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqXG4gKiBAcGFyYW0ge1VwZGF0ZURlY29kZXJWMSB8IFVwZGF0ZURlY29kZXJWMn0gZGVjb2RlclxuICogQHJldHVybiB7Q29udGVudERvY31cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRDb250ZW50RG9jID0gZGVjb2RlciA9PiBuZXcgQ29udGVudERvYyhjcmVhdGVEb2NGcm9tT3B0cyhkZWNvZGVyLnJlYWRTdHJpbmcoKSwgZGVjb2Rlci5yZWFkQW55KCkpKVxuIiwgImltcG9ydCB7XG4gIFVwZGF0ZURlY29kZXJWMSwgVXBkYXRlRGVjb2RlclYyLCBVcGRhdGVFbmNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMiwgU3RydWN0U3RvcmUsIEl0ZW0sIFRyYW5zYWN0aW9uIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbn0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJ1xuXG5pbXBvcnQgKiBhcyBlcnJvciBmcm9tICdsaWIwL2Vycm9yJ1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBDb250ZW50RW1iZWQge1xuICAvKipcbiAgICogQHBhcmFtIHtPYmplY3R9IGVtYmVkXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoZW1iZWQpIHtcbiAgICB0aGlzLmVtYmVkID0gZW1iZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICBnZXRMZW5ndGggKCkge1xuICAgIHJldHVybiAxXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8YW55Pn1cbiAgICovXG4gIGdldENvbnRlbnQgKCkge1xuICAgIHJldHVybiBbdGhpcy5lbWJlZF1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaXNDb3VudGFibGUgKCkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7Q29udGVudEVtYmVkfVxuICAgKi9cbiAgY29weSAoKSB7XG4gICAgcmV0dXJuIG5ldyBDb250ZW50RW1iZWQodGhpcy5lbWJlZClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqIEByZXR1cm4ge0NvbnRlbnRFbWJlZH1cbiAgICovXG4gIHNwbGljZSAob2Zmc2V0KSB7XG4gICAgdGhyb3cgZXJyb3IubWV0aG9kVW5pbXBsZW1lbnRlZCgpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtDb250ZW50RW1iZWR9IHJpZ2h0XG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBtZXJnZVdpdGggKHJpZ2h0KSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtJdGVtfSBpdGVtXG4gICAqL1xuICBpbnRlZ3JhdGUgKHRyYW5zYWN0aW9uLCBpdGVtKSB7fVxuICAvKipcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICovXG4gIGRlbGV0ZSAodHJhbnNhY3Rpb24pIHt9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cnVjdFN0b3JlfSBzdG9yZVxuICAgKi9cbiAgZ2MgKHN0b3JlKSB7fVxuICAvKipcbiAgICogQHBhcmFtIHtVcGRhdGVFbmNvZGVyVjEgfCBVcGRhdGVFbmNvZGVyVjJ9IGVuY29kZXJcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICAgKi9cbiAgd3JpdGUgKGVuY29kZXIsIG9mZnNldCkge1xuICAgIGVuY29kZXIud3JpdGVKU09OKHRoaXMuZW1iZWQpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0UmVmICgpIHtcbiAgICByZXR1cm4gNVxuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqXG4gKiBAcGFyYW0ge1VwZGF0ZURlY29kZXJWMSB8IFVwZGF0ZURlY29kZXJWMn0gZGVjb2RlclxuICogQHJldHVybiB7Q29udGVudEVtYmVkfVxuICovXG5leHBvcnQgY29uc3QgcmVhZENvbnRlbnRFbWJlZCA9IGRlY29kZXIgPT4gbmV3IENvbnRlbnRFbWJlZChkZWNvZGVyLnJlYWRKU09OKCkpXG4iLCAiaW1wb3J0IHtcbiAgWVRleHQsIFVwZGF0ZURlY29kZXJWMSwgVXBkYXRlRGVjb2RlclYyLCBVcGRhdGVFbmNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMiwgSXRlbSwgU3RydWN0U3RvcmUsIFRyYW5zYWN0aW9uIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbn0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJ1xuXG5pbXBvcnQgKiBhcyBlcnJvciBmcm9tICdsaWIwL2Vycm9yJ1xuXG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjbGFzcyBDb250ZW50Rm9ybWF0IHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAgICogQHBhcmFtIHtPYmplY3R9IHZhbHVlXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoa2V5LCB2YWx1ZSkge1xuICAgIHRoaXMua2V5ID0ga2V5XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0TGVuZ3RoICgpIHtcbiAgICByZXR1cm4gMVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PGFueT59XG4gICAqL1xuICBnZXRDb250ZW50ICgpIHtcbiAgICByZXR1cm4gW11cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaXNDb3VudGFibGUgKCkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0NvbnRlbnRGb3JtYXR9XG4gICAqL1xuICBjb3B5ICgpIHtcbiAgICByZXR1cm4gbmV3IENvbnRlbnRGb3JtYXQodGhpcy5rZXksIHRoaXMudmFsdWUpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IF9vZmZzZXRcbiAgICogQHJldHVybiB7Q29udGVudEZvcm1hdH1cbiAgICovXG4gIHNwbGljZSAoX29mZnNldCkge1xuICAgIHRocm93IGVycm9yLm1ldGhvZFVuaW1wbGVtZW50ZWQoKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Q29udGVudEZvcm1hdH0gX3JpZ2h0XG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBtZXJnZVdpdGggKF9yaWdodCkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IF90cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge0l0ZW19IGl0ZW1cbiAgICovXG4gIGludGVncmF0ZSAoX3RyYW5zYWN0aW9uLCBpdGVtKSB7XG4gICAgLy8gQHRvZG8gc2VhcmNobWFya2VyIGFyZSBjdXJyZW50bHkgdW5zdXBwb3J0ZWQgZm9yIHJpY2ggdGV4dCBkb2N1bWVudHNcbiAgICBjb25zdCBwID0gLyoqIEB0eXBlIHtZVGV4dH0gKi8gKGl0ZW0ucGFyZW50KVxuICAgIHAuX3NlYXJjaE1hcmtlciA9IG51bGxcbiAgICBwLl9oYXNGb3JtYXR0aW5nID0gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqL1xuICBkZWxldGUgKHRyYW5zYWN0aW9uKSB7fVxuICAvKipcbiAgICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAgICovXG4gIGdjIChzdG9yZSkge31cbiAgLyoqXG4gICAqIEBwYXJhbSB7VXBkYXRlRW5jb2RlclYxIHwgVXBkYXRlRW5jb2RlclYyfSBlbmNvZGVyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICovXG4gIHdyaXRlIChlbmNvZGVyLCBvZmZzZXQpIHtcbiAgICBlbmNvZGVyLndyaXRlS2V5KHRoaXMua2V5KVxuICAgIGVuY29kZXIud3JpdGVKU09OKHRoaXMudmFsdWUpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0UmVmICgpIHtcbiAgICByZXR1cm4gNlxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtVcGRhdGVEZWNvZGVyVjEgfCBVcGRhdGVEZWNvZGVyVjJ9IGRlY29kZXJcbiAqIEByZXR1cm4ge0NvbnRlbnRGb3JtYXR9XG4gKi9cbmV4cG9ydCBjb25zdCByZWFkQ29udGVudEZvcm1hdCA9IGRlY29kZXIgPT4gbmV3IENvbnRlbnRGb3JtYXQoZGVjb2Rlci5yZWFkS2V5KCksIGRlY29kZXIucmVhZEpTT04oKSlcbiIsICJpbXBvcnQge1xuICBVcGRhdGVEZWNvZGVyVjEsIFVwZGF0ZURlY29kZXJWMiwgVXBkYXRlRW5jb2RlclYxLCBVcGRhdGVFbmNvZGVyVjIsIFRyYW5zYWN0aW9uLCBJdGVtLCBTdHJ1Y3RTdG9yZSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgQ29udGVudEpTT04ge1xuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxhbnk+fSBhcnJcbiAgICovXG4gIGNvbnN0cnVjdG9yIChhcnIpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QXJyYXk8YW55Pn1cbiAgICAgKi9cbiAgICB0aGlzLmFyciA9IGFyclxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldExlbmd0aCAoKSB7XG4gICAgcmV0dXJuIHRoaXMuYXJyLmxlbmd0aFxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PGFueT59XG4gICAqL1xuICBnZXRDb250ZW50ICgpIHtcbiAgICByZXR1cm4gdGhpcy5hcnJcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaXNDb3VudGFibGUgKCkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7Q29udGVudEpTT059XG4gICAqL1xuICBjb3B5ICgpIHtcbiAgICByZXR1cm4gbmV3IENvbnRlbnRKU09OKHRoaXMuYXJyKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICogQHJldHVybiB7Q29udGVudEpTT059XG4gICAqL1xuICBzcGxpY2UgKG9mZnNldCkge1xuICAgIGNvbnN0IHJpZ2h0ID0gbmV3IENvbnRlbnRKU09OKHRoaXMuYXJyLnNsaWNlKG9mZnNldCkpXG4gICAgdGhpcy5hcnIgPSB0aGlzLmFyci5zbGljZSgwLCBvZmZzZXQpXG4gICAgcmV0dXJuIHJpZ2h0XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtDb250ZW50SlNPTn0gcmlnaHRcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIG1lcmdlV2l0aCAocmlnaHQpIHtcbiAgICB0aGlzLmFyciA9IHRoaXMuYXJyLmNvbmNhdChyaWdodC5hcnIpXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge0l0ZW19IGl0ZW1cbiAgICovXG4gIGludGVncmF0ZSAodHJhbnNhY3Rpb24sIGl0ZW0pIHt9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKi9cbiAgZGVsZXRlICh0cmFuc2FjdGlvbikge31cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RydWN0U3RvcmV9IHN0b3JlXG4gICAqL1xuICBnYyAoc3RvcmUpIHt9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1VwZGF0ZUVuY29kZXJWMSB8IFVwZGF0ZUVuY29kZXJWMn0gZW5jb2RlclxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICB3cml0ZSAoZW5jb2Rlciwgb2Zmc2V0KSB7XG4gICAgY29uc3QgbGVuID0gdGhpcy5hcnIubGVuZ3RoXG4gICAgZW5jb2Rlci53cml0ZUxlbihsZW4gLSBvZmZzZXQpXG4gICAgZm9yIChsZXQgaSA9IG9mZnNldDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBjb25zdCBjID0gdGhpcy5hcnJbaV1cbiAgICAgIGVuY29kZXIud3JpdGVTdHJpbmcoYyA9PT0gdW5kZWZpbmVkID8gJ3VuZGVmaW5lZCcgOiBKU09OLnN0cmluZ2lmeShjKSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0UmVmICgpIHtcbiAgICByZXR1cm4gMlxuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqXG4gKiBAcGFyYW0ge1VwZGF0ZURlY29kZXJWMSB8IFVwZGF0ZURlY29kZXJWMn0gZGVjb2RlclxuICogQHJldHVybiB7Q29udGVudEpTT059XG4gKi9cbmV4cG9ydCBjb25zdCByZWFkQ29udGVudEpTT04gPSBkZWNvZGVyID0+IHtcbiAgY29uc3QgbGVuID0gZGVjb2Rlci5yZWFkTGVuKClcbiAgY29uc3QgY3MgPSBbXVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgY29uc3QgYyA9IGRlY29kZXIucmVhZFN0cmluZygpXG4gICAgaWYgKGMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjcy5wdXNoKHVuZGVmaW5lZClcbiAgICB9IGVsc2Uge1xuICAgICAgY3MucHVzaChKU09OLnBhcnNlKGMpKVxuICAgIH1cbiAgfVxuICByZXR1cm4gbmV3IENvbnRlbnRKU09OKGNzKVxufVxuIiwgImltcG9ydCB7XG4gIFVwZGF0ZUVuY29kZXJWMSwgVXBkYXRlRW5jb2RlclYyLCBVcGRhdGVEZWNvZGVyVjEsIFVwZGF0ZURlY29kZXJWMiwgVHJhbnNhY3Rpb24sIEl0ZW0sIFN0cnVjdFN0b3JlIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbn0gZnJvbSAnLi4vaW50ZXJuYWxzLmpzJ1xuXG5pbXBvcnQgKiBhcyBlbnYgZnJvbSAnbGliMC9lbnZpcm9ubWVudCdcbmltcG9ydCAqIGFzIG9iamVjdCBmcm9tICdsaWIwL29iamVjdCdcblxuY29uc3QgaXNEZXZNb2RlID0gZW52LmdldFZhcmlhYmxlKCdub2RlX2VudicpID09PSAnZGV2ZWxvcG1lbnQnXG5cbmV4cG9ydCBjbGFzcyBDb250ZW50QW55IHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7QXJyYXk8YW55Pn0gYXJyXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoYXJyKSB7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0FycmF5PGFueT59XG4gICAgICovXG4gICAgdGhpcy5hcnIgPSBhcnJcbiAgICBpc0Rldk1vZGUgJiYgb2JqZWN0LmRlZXBGcmVlemUoYXJyKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldExlbmd0aCAoKSB7XG4gICAgcmV0dXJuIHRoaXMuYXJyLmxlbmd0aFxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5PGFueT59XG4gICAqL1xuICBnZXRDb250ZW50ICgpIHtcbiAgICByZXR1cm4gdGhpcy5hcnJcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaXNDb3VudGFibGUgKCkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7Q29udGVudEFueX1cbiAgICovXG4gIGNvcHkgKCkge1xuICAgIHJldHVybiBuZXcgQ29udGVudEFueSh0aGlzLmFycilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqIEByZXR1cm4ge0NvbnRlbnRBbnl9XG4gICAqL1xuICBzcGxpY2UgKG9mZnNldCkge1xuICAgIGNvbnN0IHJpZ2h0ID0gbmV3IENvbnRlbnRBbnkodGhpcy5hcnIuc2xpY2Uob2Zmc2V0KSlcbiAgICB0aGlzLmFyciA9IHRoaXMuYXJyLnNsaWNlKDAsIG9mZnNldClcbiAgICByZXR1cm4gcmlnaHRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0NvbnRlbnRBbnl9IHJpZ2h0XG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBtZXJnZVdpdGggKHJpZ2h0KSB7XG4gICAgdGhpcy5hcnIgPSB0aGlzLmFyci5jb25jYXQocmlnaHQuYXJyKVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtJdGVtfSBpdGVtXG4gICAqL1xuICBpbnRlZ3JhdGUgKHRyYW5zYWN0aW9uLCBpdGVtKSB7fVxuICAvKipcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICovXG4gIGRlbGV0ZSAodHJhbnNhY3Rpb24pIHt9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cnVjdFN0b3JlfSBzdG9yZVxuICAgKi9cbiAgZ2MgKHN0b3JlKSB7fVxuICAvKipcbiAgICogQHBhcmFtIHtVcGRhdGVFbmNvZGVyVjEgfCBVcGRhdGVFbmNvZGVyVjJ9IGVuY29kZXJcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICAgKi9cbiAgd3JpdGUgKGVuY29kZXIsIG9mZnNldCkge1xuICAgIGNvbnN0IGxlbiA9IHRoaXMuYXJyLmxlbmd0aFxuICAgIGVuY29kZXIud3JpdGVMZW4obGVuIC0gb2Zmc2V0KVxuICAgIGZvciAobGV0IGkgPSBvZmZzZXQ7IGkgPCBsZW47IGkrKykge1xuICAgICAgY29uc3QgYyA9IHRoaXMuYXJyW2ldXG4gICAgICBlbmNvZGVyLndyaXRlQW55KGMpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldFJlZiAoKSB7XG4gICAgcmV0dXJuIDhcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VXBkYXRlRGVjb2RlclYxIHwgVXBkYXRlRGVjb2RlclYyfSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtDb250ZW50QW55fVxuICovXG5leHBvcnQgY29uc3QgcmVhZENvbnRlbnRBbnkgPSBkZWNvZGVyID0+IHtcbiAgY29uc3QgbGVuID0gZGVjb2Rlci5yZWFkTGVuKClcbiAgY29uc3QgY3MgPSBbXVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgY3MucHVzaChkZWNvZGVyLnJlYWRBbnkoKSlcbiAgfVxuICByZXR1cm4gbmV3IENvbnRlbnRBbnkoY3MpXG59XG4iLCAiaW1wb3J0IHtcbiAgVXBkYXRlRGVjb2RlclYxLCBVcGRhdGVEZWNvZGVyVjIsIFVwZGF0ZUVuY29kZXJWMSwgVXBkYXRlRW5jb2RlclYyLCBUcmFuc2FjdGlvbiwgSXRlbSwgU3RydWN0U3RvcmUgLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIENvbnRlbnRTdHJpbmcge1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICAgKi9cbiAgY29uc3RydWN0b3IgKHN0cikge1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtzdHJpbmd9XG4gICAgICovXG4gICAgdGhpcy5zdHIgPSBzdHJcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICBnZXRMZW5ndGggKCkge1xuICAgIHJldHVybiB0aGlzLnN0ci5sZW5ndGhcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxhbnk+fVxuICAgKi9cbiAgZ2V0Q29udGVudCAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RyLnNwbGl0KCcnKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBpc0NvdW50YWJsZSAoKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtDb250ZW50U3RyaW5nfVxuICAgKi9cbiAgY29weSAoKSB7XG4gICAgcmV0dXJuIG5ldyBDb250ZW50U3RyaW5nKHRoaXMuc3RyKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICogQHJldHVybiB7Q29udGVudFN0cmluZ31cbiAgICovXG4gIHNwbGljZSAob2Zmc2V0KSB7XG4gICAgY29uc3QgcmlnaHQgPSBuZXcgQ29udGVudFN0cmluZyh0aGlzLnN0ci5zbGljZShvZmZzZXQpKVxuICAgIHRoaXMuc3RyID0gdGhpcy5zdHIuc2xpY2UoMCwgb2Zmc2V0KVxuXG4gICAgLy8gUHJldmVudCBlbmNvZGluZyBpbnZhbGlkIGRvY3VtZW50cyBiZWNhdXNlIG9mIHNwbGl0dGluZyBvZiBzdXJyb2dhdGUgcGFpcnM6IGh0dHBzOi8vZ2l0aHViLmNvbS95anMveWpzL2lzc3Vlcy8yNDhcbiAgICBjb25zdCBmaXJzdENoYXJDb2RlID0gdGhpcy5zdHIuY2hhckNvZGVBdChvZmZzZXQgLSAxKVxuICAgIGlmIChmaXJzdENoYXJDb2RlID49IDB4RDgwMCAmJiBmaXJzdENoYXJDb2RlIDw9IDB4REJGRikge1xuICAgICAgLy8gTGFzdCBjaGFyYWN0ZXIgb2YgdGhlIGxlZnQgc3BsaXQgaXMgdGhlIHN0YXJ0IG9mIGEgc3Vycm9nYXRlIHV0ZjE2L3VjczIgcGFpci5cbiAgICAgIC8vIFdlIGRvbid0IHN1cHBvcnQgc3BsaXR0aW5nIG9mIHN1cnJvZ2F0ZSBwYWlycyBiZWNhdXNlIHRoaXMgbWF5IGxlYWQgdG8gaW52YWxpZCBkb2N1bWVudHMuXG4gICAgICAvLyBSZXBsYWNlIHRoZSBpbnZhbGlkIGNoYXJhY3RlciB3aXRoIGEgdW5pY29kZSByZXBsYWNlbWVudCBjaGFyYWN0ZXIgKO+/vSAvIFUrRkZGRClcbiAgICAgIHRoaXMuc3RyID0gdGhpcy5zdHIuc2xpY2UoMCwgb2Zmc2V0IC0gMSkgKyAn77+9J1xuICAgICAgLy8gcmVwbGFjZSByaWdodCBhcyB3ZWxsXG4gICAgICByaWdodC5zdHIgPSAn77+9JyArIHJpZ2h0LnN0ci5zbGljZSgxKVxuICAgIH1cbiAgICByZXR1cm4gcmlnaHRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0NvbnRlbnRTdHJpbmd9IHJpZ2h0XG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBtZXJnZVdpdGggKHJpZ2h0KSB7XG4gICAgdGhpcy5zdHIgKz0gcmlnaHQuc3RyXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge0l0ZW19IGl0ZW1cbiAgICovXG4gIGludGVncmF0ZSAodHJhbnNhY3Rpb24sIGl0ZW0pIHt9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKi9cbiAgZGVsZXRlICh0cmFuc2FjdGlvbikge31cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RydWN0U3RvcmV9IHN0b3JlXG4gICAqL1xuICBnYyAoc3RvcmUpIHt9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1VwZGF0ZUVuY29kZXJWMSB8IFVwZGF0ZUVuY29kZXJWMn0gZW5jb2RlclxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICB3cml0ZSAoZW5jb2Rlciwgb2Zmc2V0KSB7XG4gICAgZW5jb2Rlci53cml0ZVN0cmluZyhvZmZzZXQgPT09IDAgPyB0aGlzLnN0ciA6IHRoaXMuc3RyLnNsaWNlKG9mZnNldCkpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0UmVmICgpIHtcbiAgICByZXR1cm4gNFxuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqXG4gKiBAcGFyYW0ge1VwZGF0ZURlY29kZXJWMSB8IFVwZGF0ZURlY29kZXJWMn0gZGVjb2RlclxuICogQHJldHVybiB7Q29udGVudFN0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRDb250ZW50U3RyaW5nID0gZGVjb2RlciA9PiBuZXcgQ29udGVudFN0cmluZyhkZWNvZGVyLnJlYWRTdHJpbmcoKSlcbiIsICJpbXBvcnQge1xuICByZWFkWUFycmF5LFxuICByZWFkWU1hcCxcbiAgcmVhZFlUZXh0LFxuICByZWFkWVhtbEVsZW1lbnQsXG4gIHJlYWRZWG1sRnJhZ21lbnQsXG4gIHJlYWRZWG1sSG9vayxcbiAgcmVhZFlYbWxUZXh0LFxuICBVcGRhdGVEZWNvZGVyVjEsIFVwZGF0ZURlY29kZXJWMiwgVXBkYXRlRW5jb2RlclYxLCBVcGRhdGVFbmNvZGVyVjIsIFN0cnVjdFN0b3JlLCBUcmFuc2FjdGlvbiwgSXRlbSwgWUV2ZW50LCBBYnN0cmFjdFR5cGUgLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbmltcG9ydCAqIGFzIGVycm9yIGZyb20gJ2xpYjAvZXJyb3InXG5cbi8qKlxuICogQHR5cGUge0FycmF5PGZ1bmN0aW9uKFVwZGF0ZURlY29kZXJWMSB8IFVwZGF0ZURlY29kZXJWMik6QWJzdHJhY3RUeXBlPGFueT4+fVxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IHR5cGVSZWZzID0gW1xuICByZWFkWUFycmF5LFxuICByZWFkWU1hcCxcbiAgcmVhZFlUZXh0LFxuICByZWFkWVhtbEVsZW1lbnQsXG4gIHJlYWRZWG1sRnJhZ21lbnQsXG4gIHJlYWRZWG1sSG9vayxcbiAgcmVhZFlYbWxUZXh0XG5dXG5cbmV4cG9ydCBjb25zdCBZQXJyYXlSZWZJRCA9IDBcbmV4cG9ydCBjb25zdCBZTWFwUmVmSUQgPSAxXG5leHBvcnQgY29uc3QgWVRleHRSZWZJRCA9IDJcbmV4cG9ydCBjb25zdCBZWG1sRWxlbWVudFJlZklEID0gM1xuZXhwb3J0IGNvbnN0IFlYbWxGcmFnbWVudFJlZklEID0gNFxuZXhwb3J0IGNvbnN0IFlYbWxIb29rUmVmSUQgPSA1XG5leHBvcnQgY29uc3QgWVhtbFRleHRSZWZJRCA9IDZcblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY2xhc3MgQ29udGVudFR5cGUge1xuICAvKipcbiAgICogQHBhcmFtIHtBYnN0cmFjdFR5cGU8YW55Pn0gdHlwZVxuICAgKi9cbiAgY29uc3RydWN0b3IgKHR5cGUpIHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59XG4gICAgICovXG4gICAgdGhpcy50eXBlID0gdHlwZVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldExlbmd0aCAoKSB7XG4gICAgcmV0dXJuIDFcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheTxhbnk+fVxuICAgKi9cbiAgZ2V0Q29udGVudCAoKSB7XG4gICAgcmV0dXJuIFt0aGlzLnR5cGVdXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGlzQ291bnRhYmxlICgpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0NvbnRlbnRUeXBlfVxuICAgKi9cbiAgY29weSAoKSB7XG4gICAgcmV0dXJuIG5ldyBDb250ZW50VHlwZSh0aGlzLnR5cGUuX2NvcHkoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqIEByZXR1cm4ge0NvbnRlbnRUeXBlfVxuICAgKi9cbiAgc3BsaWNlIChvZmZzZXQpIHtcbiAgICB0aHJvdyBlcnJvci5tZXRob2RVbmltcGxlbWVudGVkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0NvbnRlbnRUeXBlfSByaWdodFxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgbWVyZ2VXaXRoIChyaWdodCkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7SXRlbX0gaXRlbVxuICAgKi9cbiAgaW50ZWdyYXRlICh0cmFuc2FjdGlvbiwgaXRlbSkge1xuICAgIHRoaXMudHlwZS5faW50ZWdyYXRlKHRyYW5zYWN0aW9uLmRvYywgaXRlbSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKi9cbiAgZGVsZXRlICh0cmFuc2FjdGlvbikge1xuICAgIGxldCBpdGVtID0gdGhpcy50eXBlLl9zdGFydFxuICAgIHdoaWxlIChpdGVtICE9PSBudWxsKSB7XG4gICAgICBpZiAoIWl0ZW0uZGVsZXRlZCkge1xuICAgICAgICBpdGVtLmRlbGV0ZSh0cmFuc2FjdGlvbilcbiAgICAgIH0gZWxzZSBpZiAoaXRlbS5pZC5jbG9jayA8ICh0cmFuc2FjdGlvbi5iZWZvcmVTdGF0ZS5nZXQoaXRlbS5pZC5jbGllbnQpIHx8IDApKSB7XG4gICAgICAgIC8vIFRoaXMgd2lsbCBiZSBnYydkIGxhdGVyIGFuZCB3ZSB3YW50IHRvIG1lcmdlIGl0IGlmIHBvc3NpYmxlXG4gICAgICAgIC8vIFdlIHRyeSB0byBtZXJnZSBhbGwgZGVsZXRlZCBpdGVtcyBhZnRlciBlYWNoIHRyYW5zYWN0aW9uLFxuICAgICAgICAvLyBidXQgd2UgaGF2ZSBubyBrbm93bGVkZ2UgYWJvdXQgdGhhdCB0aGlzIG5lZWRzIHRvIGJlIG1lcmdlZFxuICAgICAgICAvLyBzaW5jZSBpdCBpcyBub3QgaW4gdHJhbnNhY3Rpb24uZHMuIEhlbmNlIHdlIGFkZCBpdCB0byB0cmFuc2FjdGlvbi5fbWVyZ2VTdHJ1Y3RzXG4gICAgICAgIHRyYW5zYWN0aW9uLl9tZXJnZVN0cnVjdHMucHVzaChpdGVtKVxuICAgICAgfVxuICAgICAgaXRlbSA9IGl0ZW0ucmlnaHRcbiAgICB9XG4gICAgdGhpcy50eXBlLl9tYXAuZm9yRWFjaChpdGVtID0+IHtcbiAgICAgIGlmICghaXRlbS5kZWxldGVkKSB7XG4gICAgICAgIGl0ZW0uZGVsZXRlKHRyYW5zYWN0aW9uKVxuICAgICAgfSBlbHNlIGlmIChpdGVtLmlkLmNsb2NrIDwgKHRyYW5zYWN0aW9uLmJlZm9yZVN0YXRlLmdldChpdGVtLmlkLmNsaWVudCkgfHwgMCkpIHtcbiAgICAgICAgLy8gc2FtZSBhcyBhYm92ZVxuICAgICAgICB0cmFuc2FjdGlvbi5fbWVyZ2VTdHJ1Y3RzLnB1c2goaXRlbSlcbiAgICAgIH1cbiAgICB9KVxuICAgIHRyYW5zYWN0aW9uLmNoYW5nZWQuZGVsZXRlKHRoaXMudHlwZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cnVjdFN0b3JlfSBzdG9yZVxuICAgKi9cbiAgZ2MgKHN0b3JlKSB7XG4gICAgbGV0IGl0ZW0gPSB0aGlzLnR5cGUuX3N0YXJ0XG4gICAgd2hpbGUgKGl0ZW0gIT09IG51bGwpIHtcbiAgICAgIGl0ZW0uZ2Moc3RvcmUsIHRydWUpXG4gICAgICBpdGVtID0gaXRlbS5yaWdodFxuICAgIH1cbiAgICB0aGlzLnR5cGUuX3N0YXJ0ID0gbnVsbFxuICAgIHRoaXMudHlwZS5fbWFwLmZvckVhY2goLyoqIEBwYXJhbSB7SXRlbSB8IG51bGx9IGl0ZW0gKi8gKGl0ZW0pID0+IHtcbiAgICAgIHdoaWxlIChpdGVtICE9PSBudWxsKSB7XG4gICAgICAgIGl0ZW0uZ2Moc3RvcmUsIHRydWUpXG4gICAgICAgIGl0ZW0gPSBpdGVtLmxlZnRcbiAgICAgIH1cbiAgICB9KVxuICAgIHRoaXMudHlwZS5fbWFwID0gbmV3IE1hcCgpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtVcGRhdGVFbmNvZGVyVjEgfCBVcGRhdGVFbmNvZGVyVjJ9IGVuY29kZXJcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldFxuICAgKi9cbiAgd3JpdGUgKGVuY29kZXIsIG9mZnNldCkge1xuICAgIHRoaXMudHlwZS5fd3JpdGUoZW5jb2RlcilcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtudW1iZXJ9XG4gICAqL1xuICBnZXRSZWYgKCkge1xuICAgIHJldHVybiA3XG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICpcbiAqIEBwYXJhbSB7VXBkYXRlRGVjb2RlclYxIHwgVXBkYXRlRGVjb2RlclYyfSBkZWNvZGVyXG4gKiBAcmV0dXJuIHtDb250ZW50VHlwZX1cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRDb250ZW50VHlwZSA9IGRlY29kZXIgPT4gbmV3IENvbnRlbnRUeXBlKHR5cGVSZWZzW2RlY29kZXIucmVhZFR5cGVSZWYoKV0oZGVjb2RlcikpXG4iLCAiaW1wb3J0IHtcbiAgR0MsXG4gIGdldFN0YXRlLFxuICBBYnN0cmFjdFN0cnVjdCxcbiAgcmVwbGFjZVN0cnVjdCxcbiAgYWRkU3RydWN0LFxuICBhZGRUb0RlbGV0ZVNldCxcbiAgZmluZFJvb3RUeXBlS2V5LFxuICBjb21wYXJlSURzLFxuICBnZXRJdGVtLFxuICBnZXRJdGVtQ2xlYW5FbmQsXG4gIGdldEl0ZW1DbGVhblN0YXJ0LFxuICByZWFkQ29udGVudERlbGV0ZWQsXG4gIHJlYWRDb250ZW50QmluYXJ5LFxuICByZWFkQ29udGVudEpTT04sXG4gIHJlYWRDb250ZW50QW55LFxuICByZWFkQ29udGVudFN0cmluZyxcbiAgcmVhZENvbnRlbnRFbWJlZCxcbiAgcmVhZENvbnRlbnREb2MsXG4gIGNyZWF0ZUlELFxuICByZWFkQ29udGVudEZvcm1hdCxcbiAgcmVhZENvbnRlbnRUeXBlLFxuICBhZGRDaGFuZ2VkVHlwZVRvVHJhbnNhY3Rpb24sXG4gIGlzRGVsZXRlZCxcbiAgU3RhY2tJdGVtLCBEZWxldGVTZXQsIFVwZGF0ZURlY29kZXJWMSwgVXBkYXRlRGVjb2RlclYyLCBVcGRhdGVFbmNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMiwgQ29udGVudFR5cGUsIENvbnRlbnREZWxldGVkLCBTdHJ1Y3RTdG9yZSwgSUQsIEFic3RyYWN0VHlwZSwgVHJhbnNhY3Rpb24gLy8gZXNsaW50LWRpc2FibGUtbGluZVxufSBmcm9tICcuLi9pbnRlcm5hbHMuanMnXG5cbmltcG9ydCAqIGFzIGVycm9yIGZyb20gJ2xpYjAvZXJyb3InXG5pbXBvcnQgKiBhcyBiaW5hcnkgZnJvbSAnbGliMC9iaW5hcnknXG5pbXBvcnQgKiBhcyBhcnJheSBmcm9tICdsaWIwL2FycmF5J1xuXG4vKipcbiAqIEB0b2RvIFRoaXMgc2hvdWxkIHJldHVybiBzZXZlcmFsIGl0ZW1zXG4gKlxuICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAqIEBwYXJhbSB7SUR9IGlkXG4gKiBAcmV0dXJuIHt7aXRlbTpJdGVtLCBkaWZmOm51bWJlcn19XG4gKi9cbmV4cG9ydCBjb25zdCBmb2xsb3dSZWRvbmUgPSAoc3RvcmUsIGlkKSA9PiB7XG4gIC8qKlxuICAgKiBAdHlwZSB7SUR8bnVsbH1cbiAgICovXG4gIGxldCBuZXh0SUQgPSBpZFxuICBsZXQgZGlmZiA9IDBcbiAgbGV0IGl0ZW1cbiAgZG8ge1xuICAgIGlmIChkaWZmID4gMCkge1xuICAgICAgbmV4dElEID0gY3JlYXRlSUQobmV4dElELmNsaWVudCwgbmV4dElELmNsb2NrICsgZGlmZilcbiAgICB9XG4gICAgaXRlbSA9IGdldEl0ZW0oc3RvcmUsIG5leHRJRClcbiAgICBkaWZmID0gbmV4dElELmNsb2NrIC0gaXRlbS5pZC5jbG9ja1xuICAgIG5leHRJRCA9IGl0ZW0ucmVkb25lXG4gIH0gd2hpbGUgKG5leHRJRCAhPT0gbnVsbCAmJiBpdGVtIGluc3RhbmNlb2YgSXRlbSlcbiAgcmV0dXJuIHtcbiAgICBpdGVtLCBkaWZmXG4gIH1cbn1cblxuLyoqXG4gKiBNYWtlIHN1cmUgdGhhdCBuZWl0aGVyIGl0ZW0gbm9yIGFueSBvZiBpdHMgcGFyZW50cyBpcyBldmVyIGRlbGV0ZWQuXG4gKlxuICogVGhpcyBwcm9wZXJ0eSBkb2VzIG5vdCBwZXJzaXN0IHdoZW4gc3RvcmluZyBpdCBpbnRvIGEgZGF0YWJhc2Ugb3Igd2hlblxuICogc2VuZGluZyBpdCB0byBvdGhlciBwZWVyc1xuICpcbiAqIEBwYXJhbSB7SXRlbXxudWxsfSBpdGVtXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGtlZXBcbiAqL1xuZXhwb3J0IGNvbnN0IGtlZXBJdGVtID0gKGl0ZW0sIGtlZXApID0+IHtcbiAgd2hpbGUgKGl0ZW0gIT09IG51bGwgJiYgaXRlbS5rZWVwICE9PSBrZWVwKSB7XG4gICAgaXRlbS5rZWVwID0ga2VlcFxuICAgIGl0ZW0gPSAvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAoaXRlbS5wYXJlbnQpLl9pdGVtXG4gIH1cbn1cblxuLyoqXG4gKiBTcGxpdCBsZWZ0SXRlbSBpbnRvIHR3byBpdGVtc1xuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAqIEBwYXJhbSB7SXRlbX0gbGVmdEl0ZW1cbiAqIEBwYXJhbSB7bnVtYmVyfSBkaWZmXG4gKiBAcmV0dXJuIHtJdGVtfVxuICpcbiAqIEBmdW5jdGlvblxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IHNwbGl0SXRlbSA9ICh0cmFuc2FjdGlvbiwgbGVmdEl0ZW0sIGRpZmYpID0+IHtcbiAgLy8gY3JlYXRlIHJpZ2h0SXRlbVxuICBjb25zdCB7IGNsaWVudCwgY2xvY2sgfSA9IGxlZnRJdGVtLmlkXG4gIGNvbnN0IHJpZ2h0SXRlbSA9IG5ldyBJdGVtKFxuICAgIGNyZWF0ZUlEKGNsaWVudCwgY2xvY2sgKyBkaWZmKSxcbiAgICBsZWZ0SXRlbSxcbiAgICBjcmVhdGVJRChjbGllbnQsIGNsb2NrICsgZGlmZiAtIDEpLFxuICAgIGxlZnRJdGVtLnJpZ2h0LFxuICAgIGxlZnRJdGVtLnJpZ2h0T3JpZ2luLFxuICAgIGxlZnRJdGVtLnBhcmVudCxcbiAgICBsZWZ0SXRlbS5wYXJlbnRTdWIsXG4gICAgbGVmdEl0ZW0uY29udGVudC5zcGxpY2UoZGlmZilcbiAgKVxuICBpZiAobGVmdEl0ZW0uZGVsZXRlZCkge1xuICAgIHJpZ2h0SXRlbS5tYXJrRGVsZXRlZCgpXG4gIH1cbiAgaWYgKGxlZnRJdGVtLmtlZXApIHtcbiAgICByaWdodEl0ZW0ua2VlcCA9IHRydWVcbiAgfVxuICBpZiAobGVmdEl0ZW0ucmVkb25lICE9PSBudWxsKSB7XG4gICAgcmlnaHRJdGVtLnJlZG9uZSA9IGNyZWF0ZUlEKGxlZnRJdGVtLnJlZG9uZS5jbGllbnQsIGxlZnRJdGVtLnJlZG9uZS5jbG9jayArIGRpZmYpXG4gIH1cbiAgLy8gdXBkYXRlIGxlZnQgKGRvIG5vdCBzZXQgbGVmdEl0ZW0ucmlnaHRPcmlnaW4gYXMgaXQgd2lsbCBsZWFkIHRvIHByb2JsZW1zIHdoZW4gc3luY2luZylcbiAgbGVmdEl0ZW0ucmlnaHQgPSByaWdodEl0ZW1cbiAgLy8gdXBkYXRlIHJpZ2h0XG4gIGlmIChyaWdodEl0ZW0ucmlnaHQgIT09IG51bGwpIHtcbiAgICByaWdodEl0ZW0ucmlnaHQubGVmdCA9IHJpZ2h0SXRlbVxuICB9XG4gIC8vIHJpZ2h0IGlzIG1vcmUgc3BlY2lmaWMuXG4gIHRyYW5zYWN0aW9uLl9tZXJnZVN0cnVjdHMucHVzaChyaWdodEl0ZW0pXG4gIC8vIHVwZGF0ZSBwYXJlbnQuX21hcFxuICBpZiAocmlnaHRJdGVtLnBhcmVudFN1YiAhPT0gbnVsbCAmJiByaWdodEl0ZW0ucmlnaHQgPT09IG51bGwpIHtcbiAgICAvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAocmlnaHRJdGVtLnBhcmVudCkuX21hcC5zZXQocmlnaHRJdGVtLnBhcmVudFN1YiwgcmlnaHRJdGVtKVxuICB9XG4gIGxlZnRJdGVtLmxlbmd0aCA9IGRpZmZcbiAgcmV0dXJuIHJpZ2h0SXRlbVxufVxuXG4vKipcbiAqIEBwYXJhbSB7QXJyYXk8U3RhY2tJdGVtPn0gc3RhY2tcbiAqIEBwYXJhbSB7SUR9IGlkXG4gKi9cbmNvbnN0IGlzRGVsZXRlZEJ5VW5kb1N0YWNrID0gKHN0YWNrLCBpZCkgPT4gYXJyYXkuc29tZShzdGFjaywgLyoqIEBwYXJhbSB7U3RhY2tJdGVtfSBzICovIHMgPT4gaXNEZWxldGVkKHMuZGVsZXRpb25zLCBpZCkpXG5cbi8qKlxuICogUmVkb2VzIHRoZSBlZmZlY3Qgb2YgdGhpcyBvcGVyYXRpb24uXG4gKlxuICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb24gVGhlIFlqcyBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7SXRlbX0gaXRlbVxuICogQHBhcmFtIHtTZXQ8SXRlbT59IHJlZG9pdGVtc1xuICogQHBhcmFtIHtEZWxldGVTZXR9IGl0ZW1zVG9EZWxldGVcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaWdub3JlUmVtb3RlTWFwQ2hhbmdlc1xuICogQHBhcmFtIHtpbXBvcnQoJy4uL3V0aWxzL1VuZG9NYW5hZ2VyLmpzJykuVW5kb01hbmFnZXJ9IHVtXG4gKlxuICogQHJldHVybiB7SXRlbXxudWxsfVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjb25zdCByZWRvSXRlbSA9ICh0cmFuc2FjdGlvbiwgaXRlbSwgcmVkb2l0ZW1zLCBpdGVtc1RvRGVsZXRlLCBpZ25vcmVSZW1vdGVNYXBDaGFuZ2VzLCB1bSkgPT4ge1xuICBjb25zdCBkb2MgPSB0cmFuc2FjdGlvbi5kb2NcbiAgY29uc3Qgc3RvcmUgPSBkb2Muc3RvcmVcbiAgY29uc3Qgb3duQ2xpZW50SUQgPSBkb2MuY2xpZW50SURcbiAgY29uc3QgcmVkb25lID0gaXRlbS5yZWRvbmVcbiAgaWYgKHJlZG9uZSAhPT0gbnVsbCkge1xuICAgIHJldHVybiBnZXRJdGVtQ2xlYW5TdGFydCh0cmFuc2FjdGlvbiwgcmVkb25lKVxuICB9XG4gIGxldCBwYXJlbnRJdGVtID0gLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKGl0ZW0ucGFyZW50KS5faXRlbVxuICAvKipcbiAgICogQHR5cGUge0l0ZW18bnVsbH1cbiAgICovXG4gIGxldCBsZWZ0ID0gbnVsbFxuICAvKipcbiAgICogQHR5cGUge0l0ZW18bnVsbH1cbiAgICovXG4gIGxldCByaWdodFxuICAvLyBtYWtlIHN1cmUgdGhhdCBwYXJlbnQgaXMgcmVkb25lXG4gIGlmIChwYXJlbnRJdGVtICE9PSBudWxsICYmIHBhcmVudEl0ZW0uZGVsZXRlZCA9PT0gdHJ1ZSkge1xuICAgIC8vIHRyeSB0byB1bmRvIHBhcmVudCBpZiBpdCB3aWxsIGJlIHVuZG9uZSBhbnl3YXlcbiAgICBpZiAocGFyZW50SXRlbS5yZWRvbmUgPT09IG51bGwgJiYgKCFyZWRvaXRlbXMuaGFzKHBhcmVudEl0ZW0pIHx8IHJlZG9JdGVtKHRyYW5zYWN0aW9uLCBwYXJlbnRJdGVtLCByZWRvaXRlbXMsIGl0ZW1zVG9EZWxldGUsIGlnbm9yZVJlbW90ZU1hcENoYW5nZXMsIHVtKSA9PT0gbnVsbCkpIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICAgIHdoaWxlIChwYXJlbnRJdGVtLnJlZG9uZSAhPT0gbnVsbCkge1xuICAgICAgcGFyZW50SXRlbSA9IGdldEl0ZW1DbGVhblN0YXJ0KHRyYW5zYWN0aW9uLCBwYXJlbnRJdGVtLnJlZG9uZSlcbiAgICB9XG4gIH1cbiAgY29uc3QgcGFyZW50VHlwZSA9IHBhcmVudEl0ZW0gPT09IG51bGwgPyAvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAoaXRlbS5wYXJlbnQpIDogLyoqIEB0eXBlIHtDb250ZW50VHlwZX0gKi8gKHBhcmVudEl0ZW0uY29udGVudCkudHlwZVxuXG4gIGlmIChpdGVtLnBhcmVudFN1YiA9PT0gbnVsbCkge1xuICAgIC8vIElzIGFuIGFycmF5IGl0ZW0uIEluc2VydCBhdCB0aGUgb2xkIHBvc2l0aW9uXG4gICAgbGVmdCA9IGl0ZW0ubGVmdFxuICAgIHJpZ2h0ID0gaXRlbVxuICAgIC8vIGZpbmQgbmV4dCBjbG9uZWRfcmVkbyBpdGVtc1xuICAgIHdoaWxlIChsZWZ0ICE9PSBudWxsKSB7XG4gICAgICAvKipcbiAgICAgICAqIEB0eXBlIHtJdGVtfG51bGx9XG4gICAgICAgKi9cbiAgICAgIGxldCBsZWZ0VHJhY2UgPSBsZWZ0XG4gICAgICAvLyB0cmFjZSByZWRvbmUgdW50aWwgcGFyZW50IG1hdGNoZXNcbiAgICAgIHdoaWxlIChsZWZ0VHJhY2UgIT09IG51bGwgJiYgLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKGxlZnRUcmFjZS5wYXJlbnQpLl9pdGVtICE9PSBwYXJlbnRJdGVtKSB7XG4gICAgICAgIGxlZnRUcmFjZSA9IGxlZnRUcmFjZS5yZWRvbmUgPT09IG51bGwgPyBudWxsIDogZ2V0SXRlbUNsZWFuU3RhcnQodHJhbnNhY3Rpb24sIGxlZnRUcmFjZS5yZWRvbmUpXG4gICAgICB9XG4gICAgICBpZiAobGVmdFRyYWNlICE9PSBudWxsICYmIC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovIChsZWZ0VHJhY2UucGFyZW50KS5faXRlbSA9PT0gcGFyZW50SXRlbSkge1xuICAgICAgICBsZWZ0ID0gbGVmdFRyYWNlXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICBsZWZ0ID0gbGVmdC5sZWZ0XG4gICAgfVxuICAgIHdoaWxlIChyaWdodCAhPT0gbnVsbCkge1xuICAgICAgLyoqXG4gICAgICAgKiBAdHlwZSB7SXRlbXxudWxsfVxuICAgICAgICovXG4gICAgICBsZXQgcmlnaHRUcmFjZSA9IHJpZ2h0XG4gICAgICAvLyB0cmFjZSByZWRvbmUgdW50aWwgcGFyZW50IG1hdGNoZXNcbiAgICAgIHdoaWxlIChyaWdodFRyYWNlICE9PSBudWxsICYmIC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovIChyaWdodFRyYWNlLnBhcmVudCkuX2l0ZW0gIT09IHBhcmVudEl0ZW0pIHtcbiAgICAgICAgcmlnaHRUcmFjZSA9IHJpZ2h0VHJhY2UucmVkb25lID09PSBudWxsID8gbnVsbCA6IGdldEl0ZW1DbGVhblN0YXJ0KHRyYW5zYWN0aW9uLCByaWdodFRyYWNlLnJlZG9uZSlcbiAgICAgIH1cbiAgICAgIGlmIChyaWdodFRyYWNlICE9PSBudWxsICYmIC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovIChyaWdodFRyYWNlLnBhcmVudCkuX2l0ZW0gPT09IHBhcmVudEl0ZW0pIHtcbiAgICAgICAgcmlnaHQgPSByaWdodFRyYWNlXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICByaWdodCA9IHJpZ2h0LnJpZ2h0XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJpZ2h0ID0gbnVsbFxuICAgIGlmIChpdGVtLnJpZ2h0ICYmICFpZ25vcmVSZW1vdGVNYXBDaGFuZ2VzKSB7XG4gICAgICBsZWZ0ID0gaXRlbVxuICAgICAgLy8gSXRlcmF0ZSByaWdodCB3aGlsZSByaWdodCBpcyBpbiBpdGVtc1RvRGVsZXRlXG4gICAgICAvLyBJZiBpdCBpcyBpbnRlbmRlZCB0byBkZWxldGUgcmlnaHQgd2hpbGUgaXRlbSBpcyByZWRvbmUsIHdlIGNhbiBleHBlY3QgdGhhdCBpdGVtIHNob3VsZCByZXBsYWNlIHJpZ2h0LlxuICAgICAgd2hpbGUgKGxlZnQgIT09IG51bGwgJiYgbGVmdC5yaWdodCAhPT0gbnVsbCAmJiAobGVmdC5yaWdodC5yZWRvbmUgfHwgaXNEZWxldGVkKGl0ZW1zVG9EZWxldGUsIGxlZnQucmlnaHQuaWQpIHx8IGlzRGVsZXRlZEJ5VW5kb1N0YWNrKHVtLnVuZG9TdGFjaywgbGVmdC5yaWdodC5pZCkgfHwgaXNEZWxldGVkQnlVbmRvU3RhY2sodW0ucmVkb1N0YWNrLCBsZWZ0LnJpZ2h0LmlkKSkpIHtcbiAgICAgICAgbGVmdCA9IGxlZnQucmlnaHRcbiAgICAgICAgLy8gZm9sbG93IHJlZG9uZVxuICAgICAgICB3aGlsZSAobGVmdC5yZWRvbmUpIGxlZnQgPSBnZXRJdGVtQ2xlYW5TdGFydCh0cmFuc2FjdGlvbiwgbGVmdC5yZWRvbmUpXG4gICAgICB9XG4gICAgICBpZiAobGVmdCAmJiBsZWZ0LnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgIC8vIEl0IGlzIG5vdCBwb3NzaWJsZSB0byByZWRvIHRoaXMgaXRlbSBiZWNhdXNlIGl0IGNvbmZsaWN0cyB3aXRoIGFcbiAgICAgICAgLy8gY2hhbmdlIGZyb20gYW5vdGhlciBjbGllbnRcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGVmdCA9IHBhcmVudFR5cGUuX21hcC5nZXQoaXRlbS5wYXJlbnRTdWIpIHx8IG51bGxcbiAgICB9XG4gICAgLy8gZHJvcCBjcm9zcy1wYXJlbnQgbGVmdCBzbyBvcmlnaW4gZG9lc24ndCBtaXNsZWFkIHRoZSByZW1vdGUgKCM3NTcpXG4gICAgaWYgKGxlZnQgIT09IG51bGwgJiYgLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKGxlZnQucGFyZW50KS5faXRlbSAhPT0gcGFyZW50SXRlbSkge1xuICAgICAgbGVmdCA9IHBhcmVudFR5cGUuX21hcC5nZXQoaXRlbS5wYXJlbnRTdWIpIHx8IG51bGxcbiAgICB9XG4gIH1cbiAgY29uc3QgbmV4dENsb2NrID0gZ2V0U3RhdGUoc3RvcmUsIG93bkNsaWVudElEKVxuICBjb25zdCBuZXh0SWQgPSBjcmVhdGVJRChvd25DbGllbnRJRCwgbmV4dENsb2NrKVxuICBjb25zdCByZWRvbmVJdGVtID0gbmV3IEl0ZW0oXG4gICAgbmV4dElkLFxuICAgIGxlZnQsIGxlZnQgJiYgbGVmdC5sYXN0SWQsXG4gICAgcmlnaHQsIHJpZ2h0ICYmIHJpZ2h0LmlkLFxuICAgIHBhcmVudFR5cGUsXG4gICAgaXRlbS5wYXJlbnRTdWIsXG4gICAgaXRlbS5jb250ZW50LmNvcHkoKVxuICApXG4gIGl0ZW0ucmVkb25lID0gbmV4dElkXG4gIGtlZXBJdGVtKHJlZG9uZUl0ZW0sIHRydWUpXG4gIHJlZG9uZUl0ZW0uaW50ZWdyYXRlKHRyYW5zYWN0aW9uLCAwKVxuICByZXR1cm4gcmVkb25lSXRlbVxufVxuXG4vKipcbiAqIEFic3RyYWN0IGNsYXNzIHRoYXQgcmVwcmVzZW50cyBhbnkgY29udGVudC5cbiAqL1xuZXhwb3J0IGNsYXNzIEl0ZW0gZXh0ZW5kcyBBYnN0cmFjdFN0cnVjdCB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0lEfSBpZFxuICAgKiBAcGFyYW0ge0l0ZW0gfCBudWxsfSBsZWZ0XG4gICAqIEBwYXJhbSB7SUQgfCBudWxsfSBvcmlnaW5cbiAgICogQHBhcmFtIHtJdGVtIHwgbnVsbH0gcmlnaHRcbiAgICogQHBhcmFtIHtJRCB8IG51bGx9IHJpZ2h0T3JpZ2luXG4gICAqIEBwYXJhbSB7QWJzdHJhY3RUeXBlPGFueT58SUR8bnVsbH0gcGFyZW50IElzIGEgdHlwZSBpZiBpbnRlZ3JhdGVkLCBpcyBudWxsIGlmIGl0IGlzIHBvc3NpYmxlIHRvIGNvcHkgcGFyZW50IGZyb20gbGVmdCBvciByaWdodCwgaXMgSUQgYmVmb3JlIGludGVncmF0aW9uIHRvIHNlYXJjaCBmb3IgaXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVsbH0gcGFyZW50U3ViXG4gICAqIEBwYXJhbSB7QWJzdHJhY3RDb250ZW50fSBjb250ZW50XG4gICAqL1xuICBjb25zdHJ1Y3RvciAoaWQsIGxlZnQsIG9yaWdpbiwgcmlnaHQsIHJpZ2h0T3JpZ2luLCBwYXJlbnQsIHBhcmVudFN1YiwgY29udGVudCkge1xuICAgIHN1cGVyKGlkLCBjb250ZW50LmdldExlbmd0aCgpKVxuICAgIC8qKlxuICAgICAqIFRoZSBpdGVtIHRoYXQgd2FzIG9yaWdpbmFsbHkgdG8gdGhlIGxlZnQgb2YgdGhpcyBpdGVtLlxuICAgICAqIEB0eXBlIHtJRCB8IG51bGx9XG4gICAgICovXG4gICAgdGhpcy5vcmlnaW4gPSBvcmlnaW5cbiAgICAvKipcbiAgICAgKiBUaGUgaXRlbSB0aGF0IGlzIGN1cnJlbnRseSB0byB0aGUgbGVmdCBvZiB0aGlzIGl0ZW0uXG4gICAgICogQHR5cGUge0l0ZW0gfCBudWxsfVxuICAgICAqL1xuICAgIHRoaXMubGVmdCA9IGxlZnRcbiAgICAvKipcbiAgICAgKiBUaGUgaXRlbSB0aGF0IGlzIGN1cnJlbnRseSB0byB0aGUgcmlnaHQgb2YgdGhpcyBpdGVtLlxuICAgICAqIEB0eXBlIHtJdGVtIHwgbnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLnJpZ2h0ID0gcmlnaHRcbiAgICAvKipcbiAgICAgKiBUaGUgaXRlbSB0aGF0IHdhcyBvcmlnaW5hbGx5IHRvIHRoZSByaWdodCBvZiB0aGlzIGl0ZW0uXG4gICAgICogQHR5cGUge0lEIHwgbnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLnJpZ2h0T3JpZ2luID0gcmlnaHRPcmlnaW5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT58SUR8bnVsbH1cbiAgICAgKi9cbiAgICB0aGlzLnBhcmVudCA9IHBhcmVudFxuICAgIC8qKlxuICAgICAqIElmIHRoZSBwYXJlbnQgcmVmZXJzIHRvIHRoaXMgaXRlbSB3aXRoIHNvbWUga2luZCBvZiBrZXkgKGUuZy4gWU1hcCwgdGhlXG4gICAgICoga2V5IGlzIHNwZWNpZmllZCBoZXJlLiBUaGUga2V5IGlzIHRoZW4gdXNlZCB0byByZWZlciB0byB0aGUgbGlzdCBpbiB3aGljaFxuICAgICAqIHRvIGluc2VydCB0aGlzIGl0ZW0uIElmIGBwYXJlbnRTdWIgPSBudWxsYCB0eXBlLl9zdGFydCBpcyB0aGUgbGlzdCBpblxuICAgICAqIHdoaWNoIHRvIGluc2VydCB0by4gT3RoZXJ3aXNlIGl0IGlzIGBwYXJlbnQuX21hcGAuXG4gICAgICogQHR5cGUge1N0cmluZyB8IG51bGx9XG4gICAgICovXG4gICAgdGhpcy5wYXJlbnRTdWIgPSBwYXJlbnRTdWJcbiAgICAvKipcbiAgICAgKiBJZiB0aGlzIHR5cGUncyBlZmZlY3QgaXMgcmVkb25lIHRoaXMgdHlwZSByZWZlcnMgdG8gdGhlIHR5cGUgdGhhdCB1bmRpZFxuICAgICAqIHRoaXMgb3BlcmF0aW9uLlxuICAgICAqIEB0eXBlIHtJRCB8IG51bGx9XG4gICAgICovXG4gICAgdGhpcy5yZWRvbmUgPSBudWxsXG4gICAgLyoqXG4gICAgICogQHR5cGUge0Fic3RyYWN0Q29udGVudH1cbiAgICAgKi9cbiAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50XG4gICAgLyoqXG4gICAgICogYml0MToga2VlcFxuICAgICAqIGJpdDI6IGNvdW50YWJsZVxuICAgICAqIGJpdDM6IGRlbGV0ZWRcbiAgICAgKiBiaXQ0OiBtYXJrIC0gbWFyayBub2RlIGFzIGZhc3Qtc2VhcmNoLW1hcmtlclxuICAgICAqIEB0eXBlIHtudW1iZXJ9IGJ5dGVcbiAgICAgKi9cbiAgICB0aGlzLmluZm8gPSB0aGlzLmNvbnRlbnQuaXNDb3VudGFibGUoKSA/IGJpbmFyeS5CSVQyIDogMFxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgaXMgdXNlZCB0byBtYXJrIHRoZSBpdGVtIGFzIGFuIGluZGV4ZWQgZmFzdC1zZWFyY2ggbWFya2VyXG4gICAqXG4gICAqIEB0eXBlIHtib29sZWFufVxuICAgKi9cbiAgc2V0IG1hcmtlciAoaXNNYXJrZWQpIHtcbiAgICBpZiAoKCh0aGlzLmluZm8gJiBiaW5hcnkuQklUNCkgPiAwKSAhPT0gaXNNYXJrZWQpIHtcbiAgICAgIHRoaXMuaW5mbyBePSBiaW5hcnkuQklUNFxuICAgIH1cbiAgfVxuXG4gIGdldCBtYXJrZXIgKCkge1xuICAgIHJldHVybiAodGhpcy5pbmZvICYgYmluYXJ5LkJJVDQpID4gMFxuICB9XG5cbiAgLyoqXG4gICAqIElmIHRydWUsIGRvIG5vdCBnYXJiYWdlIGNvbGxlY3QgdGhpcyBJdGVtLlxuICAgKi9cbiAgZ2V0IGtlZXAgKCkge1xuICAgIHJldHVybiAodGhpcy5pbmZvICYgYmluYXJ5LkJJVDEpID4gMFxuICB9XG5cbiAgc2V0IGtlZXAgKGRvS2VlcCkge1xuICAgIGlmICh0aGlzLmtlZXAgIT09IGRvS2VlcCkge1xuICAgICAgdGhpcy5pbmZvIF49IGJpbmFyeS5CSVQxXG4gICAgfVxuICB9XG5cbiAgZ2V0IGNvdW50YWJsZSAoKSB7XG4gICAgcmV0dXJuICh0aGlzLmluZm8gJiBiaW5hcnkuQklUMikgPiAwXG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciB0aGlzIGl0ZW0gd2FzIGRlbGV0ZWQgb3Igbm90LlxuICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICovXG4gIGdldCBkZWxldGVkICgpIHtcbiAgICByZXR1cm4gKHRoaXMuaW5mbyAmIGJpbmFyeS5CSVQzKSA+IDBcbiAgfVxuXG4gIHNldCBkZWxldGVkIChkb0RlbGV0ZSkge1xuICAgIGlmICh0aGlzLmRlbGV0ZWQgIT09IGRvRGVsZXRlKSB7XG4gICAgICB0aGlzLmluZm8gXj0gYmluYXJ5LkJJVDNcbiAgICB9XG4gIH1cblxuICBtYXJrRGVsZXRlZCAoKSB7XG4gICAgdGhpcy5pbmZvIHw9IGJpbmFyeS5CSVQzXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBjcmVhdG9yIGNsaWVudElEIG9mIHRoZSBtaXNzaW5nIG9wIG9yIGRlZmluZSBtaXNzaW5nIGl0ZW1zIGFuZCByZXR1cm4gbnVsbC5cbiAgICpcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtTdHJ1Y3RTdG9yZX0gc3RvcmVcbiAgICogQHJldHVybiB7bnVsbCB8IG51bWJlcn1cbiAgICovXG4gIGdldE1pc3NpbmcgKHRyYW5zYWN0aW9uLCBzdG9yZSkge1xuICAgIGlmICh0aGlzLm9yaWdpbiAmJiB0aGlzLm9yaWdpbi5jbGllbnQgIT09IHRoaXMuaWQuY2xpZW50ICYmIHRoaXMub3JpZ2luLmNsb2NrID49IGdldFN0YXRlKHN0b3JlLCB0aGlzLm9yaWdpbi5jbGllbnQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcmlnaW4uY2xpZW50XG4gICAgfVxuICAgIGlmICh0aGlzLnJpZ2h0T3JpZ2luICYmIHRoaXMucmlnaHRPcmlnaW4uY2xpZW50ICE9PSB0aGlzLmlkLmNsaWVudCAmJiB0aGlzLnJpZ2h0T3JpZ2luLmNsb2NrID49IGdldFN0YXRlKHN0b3JlLCB0aGlzLnJpZ2h0T3JpZ2luLmNsaWVudCkpIHtcbiAgICAgIHJldHVybiB0aGlzLnJpZ2h0T3JpZ2luLmNsaWVudFxuICAgIH1cbiAgICBpZiAodGhpcy5wYXJlbnQgJiYgdGhpcy5wYXJlbnQuY29uc3RydWN0b3IgPT09IElEICYmIHRoaXMuaWQuY2xpZW50ICE9PSB0aGlzLnBhcmVudC5jbGllbnQgJiYgdGhpcy5wYXJlbnQuY2xvY2sgPj0gZ2V0U3RhdGUoc3RvcmUsIHRoaXMucGFyZW50LmNsaWVudCkpIHtcbiAgICAgIHJldHVybiB0aGlzLnBhcmVudC5jbGllbnRcbiAgICB9XG5cbiAgICAvLyBXZSBoYXZlIGFsbCBtaXNzaW5nIGlkcywgbm93IGZpbmQgdGhlIGl0ZW1zXG5cbiAgICBpZiAodGhpcy5vcmlnaW4pIHtcbiAgICAgIHRoaXMubGVmdCA9IGdldEl0ZW1DbGVhbkVuZCh0cmFuc2FjdGlvbiwgc3RvcmUsIHRoaXMub3JpZ2luKVxuICAgICAgdGhpcy5vcmlnaW4gPSB0aGlzLmxlZnQubGFzdElkXG4gICAgfVxuICAgIGlmICh0aGlzLnJpZ2h0T3JpZ2luKSB7XG4gICAgICB0aGlzLnJpZ2h0ID0gZ2V0SXRlbUNsZWFuU3RhcnQodHJhbnNhY3Rpb24sIHRoaXMucmlnaHRPcmlnaW4pXG4gICAgICB0aGlzLnJpZ2h0T3JpZ2luID0gdGhpcy5yaWdodC5pZFxuICAgIH1cbiAgICBpZiAoKHRoaXMubGVmdCAmJiB0aGlzLmxlZnQuY29uc3RydWN0b3IgPT09IEdDKSB8fCAodGhpcy5yaWdodCAmJiB0aGlzLnJpZ2h0LmNvbnN0cnVjdG9yID09PSBHQykpIHtcbiAgICAgIHRoaXMucGFyZW50ID0gbnVsbFxuICAgIH0gZWxzZSBpZiAoIXRoaXMucGFyZW50KSB7XG4gICAgICAvLyBvbmx5IHNldCBwYXJlbnQgaWYgdGhpcyBzaG91bGRuJ3QgYmUgZ2FyYmFnZSBjb2xsZWN0ZWRcbiAgICAgIGlmICh0aGlzLmxlZnQgJiYgdGhpcy5sZWZ0LmNvbnN0cnVjdG9yID09PSBJdGVtKSB7XG4gICAgICAgIHRoaXMucGFyZW50ID0gdGhpcy5sZWZ0LnBhcmVudFxuICAgICAgICB0aGlzLnBhcmVudFN1YiA9IHRoaXMubGVmdC5wYXJlbnRTdWJcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5yaWdodCAmJiB0aGlzLnJpZ2h0LmNvbnN0cnVjdG9yID09PSBJdGVtKSB7XG4gICAgICAgIHRoaXMucGFyZW50ID0gdGhpcy5yaWdodC5wYXJlbnRcbiAgICAgICAgdGhpcy5wYXJlbnRTdWIgPSB0aGlzLnJpZ2h0LnBhcmVudFN1YlxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodGhpcy5wYXJlbnQuY29uc3RydWN0b3IgPT09IElEKSB7XG4gICAgICBjb25zdCBwYXJlbnRJdGVtID0gZ2V0SXRlbShzdG9yZSwgdGhpcy5wYXJlbnQpXG4gICAgICBpZiAocGFyZW50SXRlbS5jb25zdHJ1Y3RvciA9PT0gR0MpIHtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBudWxsXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnBhcmVudCA9IC8qKiBAdHlwZSB7Q29udGVudFR5cGV9ICovIChwYXJlbnRJdGVtLmNvbnRlbnQpLnR5cGVcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICBpbnRlZ3JhdGUgKHRyYW5zYWN0aW9uLCBvZmZzZXQpIHtcbiAgICBpZiAob2Zmc2V0ID4gMCkge1xuICAgICAgdGhpcy5pZC5jbG9jayArPSBvZmZzZXRcbiAgICAgIHRoaXMubGVmdCA9IGdldEl0ZW1DbGVhbkVuZCh0cmFuc2FjdGlvbiwgdHJhbnNhY3Rpb24uZG9jLnN0b3JlLCBjcmVhdGVJRCh0aGlzLmlkLmNsaWVudCwgdGhpcy5pZC5jbG9jayAtIDEpKVxuICAgICAgdGhpcy5vcmlnaW4gPSB0aGlzLmxlZnQubGFzdElkXG4gICAgICB0aGlzLmNvbnRlbnQgPSB0aGlzLmNvbnRlbnQuc3BsaWNlKG9mZnNldClcbiAgICAgIHRoaXMubGVuZ3RoIC09IG9mZnNldFxuICAgIH1cblxuICAgIGlmICh0aGlzLnBhcmVudCkge1xuICAgICAgaWYgKCghdGhpcy5sZWZ0ICYmICghdGhpcy5yaWdodCB8fCB0aGlzLnJpZ2h0LmxlZnQgIT09IG51bGwpKSB8fCAodGhpcy5sZWZ0ICYmIHRoaXMubGVmdC5yaWdodCAhPT0gdGhpcy5yaWdodCkpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEB0eXBlIHtJdGVtfG51bGx9XG4gICAgICAgICAqL1xuICAgICAgICBsZXQgbGVmdCA9IHRoaXMubGVmdFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAdHlwZSB7SXRlbXxudWxsfVxuICAgICAgICAgKi9cbiAgICAgICAgbGV0IG9cbiAgICAgICAgLy8gc2V0IG8gdG8gdGhlIGZpcnN0IGNvbmZsaWN0aW5nIGl0ZW1cbiAgICAgICAgaWYgKGxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICBvID0gbGVmdC5yaWdodFxuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucGFyZW50U3ViICE9PSBudWxsKSB7XG4gICAgICAgICAgbyA9IC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovICh0aGlzLnBhcmVudCkuX21hcC5nZXQodGhpcy5wYXJlbnRTdWIpIHx8IG51bGxcbiAgICAgICAgICB3aGlsZSAobyAhPT0gbnVsbCAmJiBvLmxlZnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG8gPSBvLmxlZnRcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbyA9IC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovICh0aGlzLnBhcmVudCkuX3N0YXJ0XG4gICAgICAgIH1cbiAgICAgICAgLy8gVE9ETzogdXNlIHNvbWV0aGluZyBsaWtlIERlbGV0ZVNldCBoZXJlIChhIHRyZWUgaW1wbGVtZW50YXRpb24gd291bGQgYmUgYmVzdClcbiAgICAgICAgLy8gQHRvZG8gdXNlIGdsb2JhbCBzZXQgZGVmaW5pdGlvbnNcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEB0eXBlIHtTZXQ8SXRlbT59XG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBjb25mbGljdGluZ0l0ZW1zID0gbmV3IFNldCgpXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAdHlwZSB7U2V0PEl0ZW0+fVxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgaXRlbXNCZWZvcmVPcmlnaW4gPSBuZXcgU2V0KClcbiAgICAgICAgLy8gTGV0IGMgaW4gY29uZmxpY3RpbmdJdGVtcywgYiBpbiBpdGVtc0JlZm9yZU9yaWdpblxuICAgICAgICAvLyAqKip7b3JpZ2lufWJiYmJ7dGhpc317YyxifXtjLGJ9e299KioqXG4gICAgICAgIC8vIE5vdGUgdGhhdCBjb25mbGljdGluZ0l0ZW1zIGlzIGEgc3Vic2V0IG9mIGl0ZW1zQmVmb3JlT3JpZ2luXG4gICAgICAgIHdoaWxlIChvICE9PSBudWxsICYmIG8gIT09IHRoaXMucmlnaHQpIHtcbiAgICAgICAgICBpdGVtc0JlZm9yZU9yaWdpbi5hZGQobylcbiAgICAgICAgICBjb25mbGljdGluZ0l0ZW1zLmFkZChvKVxuICAgICAgICAgIGlmIChjb21wYXJlSURzKHRoaXMub3JpZ2luLCBvLm9yaWdpbikpIHtcbiAgICAgICAgICAgIC8vIGNhc2UgMVxuICAgICAgICAgICAgaWYgKG8uaWQuY2xpZW50IDwgdGhpcy5pZC5jbGllbnQpIHtcbiAgICAgICAgICAgICAgbGVmdCA9IG9cbiAgICAgICAgICAgICAgY29uZmxpY3RpbmdJdGVtcy5jbGVhcigpXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvbXBhcmVJRHModGhpcy5yaWdodE9yaWdpbiwgby5yaWdodE9yaWdpbikpIHtcbiAgICAgICAgICAgICAgLy8gdGhpcyBhbmQgbyBhcmUgY29uZmxpY3RpbmcgYW5kIHBvaW50IHRvIHRoZSBzYW1lIGludGVncmF0aW9uIHBvaW50cy4gVGhlIGlkIGRlY2lkZXMgd2hpY2ggaXRlbSBjb21lcyBmaXJzdC5cbiAgICAgICAgICAgICAgLy8gU2luY2UgdGhpcyBpcyB0byB0aGUgbGVmdCBvZiBvLCB3ZSBjYW4gYnJlYWsgaGVyZVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfSAvLyBlbHNlLCBvIG1pZ2h0IGJlIGludGVncmF0ZWQgYmVmb3JlIGFuIGl0ZW0gdGhhdCB0aGlzIGNvbmZsaWN0cyB3aXRoLiBJZiBzbywgd2Ugd2lsbCBmaW5kIGl0IGluIHRoZSBuZXh0IGl0ZXJhdGlvbnNcbiAgICAgICAgICB9IGVsc2UgaWYgKG8ub3JpZ2luICE9PSBudWxsICYmIGl0ZW1zQmVmb3JlT3JpZ2luLmhhcyhnZXRJdGVtKHRyYW5zYWN0aW9uLmRvYy5zdG9yZSwgby5vcmlnaW4pKSkgeyAvLyB1c2UgZ2V0SXRlbSBpbnN0ZWFkIG9mIGdldEl0ZW1DbGVhbkVuZCBiZWNhdXNlIHdlIGRvbid0IHdhbnQgLyBuZWVkIHRvIHNwbGl0IGl0ZW1zLlxuICAgICAgICAgICAgLy8gY2FzZSAyXG4gICAgICAgICAgICBpZiAoIWNvbmZsaWN0aW5nSXRlbXMuaGFzKGdldEl0ZW0odHJhbnNhY3Rpb24uZG9jLnN0b3JlLCBvLm9yaWdpbikpKSB7XG4gICAgICAgICAgICAgIGxlZnQgPSBvXG4gICAgICAgICAgICAgIGNvbmZsaWN0aW5nSXRlbXMuY2xlYXIoKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH1cbiAgICAgICAgICBvID0gby5yaWdodFxuICAgICAgICB9XG4gICAgICAgIHRoaXMubGVmdCA9IGxlZnRcbiAgICAgIH1cbiAgICAgIC8vIHJlY29ubmVjdCBsZWZ0L3JpZ2h0ICsgdXBkYXRlIHBhcmVudCBtYXAvc3RhcnQgaWYgbmVjZXNzYXJ5XG4gICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5sZWZ0LnJpZ2h0XG4gICAgICAgIHRoaXMucmlnaHQgPSByaWdodFxuICAgICAgICB0aGlzLmxlZnQucmlnaHQgPSB0aGlzXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgclxuICAgICAgICBpZiAodGhpcy5wYXJlbnRTdWIgIT09IG51bGwpIHtcbiAgICAgICAgICByID0gLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKHRoaXMucGFyZW50KS5fbWFwLmdldCh0aGlzLnBhcmVudFN1YikgfHwgbnVsbFxuICAgICAgICAgIHdoaWxlIChyICE9PSBudWxsICYmIHIubGVmdCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgciA9IHIubGVmdFxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByID0gLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKHRoaXMucGFyZW50KS5fc3RhcnRcbiAgICAgICAgICA7LyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKHRoaXMucGFyZW50KS5fc3RhcnQgPSB0aGlzXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yaWdodCA9IHJcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMucmlnaHQubGVmdCA9IHRoaXNcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5wYXJlbnRTdWIgIT09IG51bGwpIHtcbiAgICAgICAgLy8gc2V0IGFzIGN1cnJlbnQgcGFyZW50IHZhbHVlIGlmIHJpZ2h0ID09PSBudWxsIGFuZCB0aGlzIGlzIHBhcmVudFN1YlxuICAgICAgICAvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAodGhpcy5wYXJlbnQpLl9tYXAuc2V0KHRoaXMucGFyZW50U3ViLCB0aGlzKVxuICAgICAgICBpZiAodGhpcy5sZWZ0ICE9PSBudWxsKSB7XG4gICAgICAgICAgLy8gdGhpcyBpcyB0aGUgY3VycmVudCBhdHRyaWJ1dGUgdmFsdWUgb2YgcGFyZW50LiBkZWxldGUgcmlnaHRcbiAgICAgICAgICB0aGlzLmxlZnQuZGVsZXRlKHRyYW5zYWN0aW9uKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBhZGp1c3QgbGVuZ3RoIG9mIHBhcmVudFxuICAgICAgaWYgKHRoaXMucGFyZW50U3ViID09PSBudWxsICYmIHRoaXMuY291bnRhYmxlICYmICF0aGlzLmRlbGV0ZWQpIHtcbiAgICAgICAgLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKHRoaXMucGFyZW50KS5fbGVuZ3RoICs9IHRoaXMubGVuZ3RoXG4gICAgICB9XG4gICAgICBhZGRTdHJ1Y3QodHJhbnNhY3Rpb24uZG9jLnN0b3JlLCB0aGlzKVxuICAgICAgdGhpcy5jb250ZW50LmludGVncmF0ZSh0cmFuc2FjdGlvbiwgdGhpcylcbiAgICAgIC8vIGFkZCBwYXJlbnQgdG8gdHJhbnNhY3Rpb24uY2hhbmdlZFxuICAgICAgYWRkQ2hhbmdlZFR5cGVUb1RyYW5zYWN0aW9uKHRyYW5zYWN0aW9uLCAvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAodGhpcy5wYXJlbnQpLCB0aGlzLnBhcmVudFN1YilcbiAgICAgIGlmICgoLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKHRoaXMucGFyZW50KS5faXRlbSAhPT0gbnVsbCAmJiAvKiogQHR5cGUge0Fic3RyYWN0VHlwZTxhbnk+fSAqLyAodGhpcy5wYXJlbnQpLl9pdGVtLmRlbGV0ZWQpIHx8ICh0aGlzLnBhcmVudFN1YiAhPT0gbnVsbCAmJiB0aGlzLnJpZ2h0ICE9PSBudWxsKSkge1xuICAgICAgICAvLyBkZWxldGUgaWYgcGFyZW50IGlzIGRlbGV0ZWQgb3IgaWYgdGhpcyBpcyBub3QgdGhlIGN1cnJlbnQgYXR0cmlidXRlIHZhbHVlIG9mIHBhcmVudFxuICAgICAgICB0aGlzLmRlbGV0ZSh0cmFuc2FjdGlvbilcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcGFyZW50IGlzIG5vdCBkZWZpbmVkLiBJbnRlZ3JhdGUgR0Mgc3RydWN0IGluc3RlYWRcbiAgICAgIG5ldyBHQyh0aGlzLmlkLCB0aGlzLmxlbmd0aCkuaW50ZWdyYXRlKHRyYW5zYWN0aW9uLCAwKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBuZXh0IG5vbi1kZWxldGVkIGl0ZW1cbiAgICovXG4gIGdldCBuZXh0ICgpIHtcbiAgICBsZXQgbiA9IHRoaXMucmlnaHRcbiAgICB3aGlsZSAobiAhPT0gbnVsbCAmJiBuLmRlbGV0ZWQpIHtcbiAgICAgIG4gPSBuLnJpZ2h0XG4gICAgfVxuICAgIHJldHVybiBuXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgcHJldmlvdXMgbm9uLWRlbGV0ZWQgaXRlbVxuICAgKi9cbiAgZ2V0IHByZXYgKCkge1xuICAgIGxldCBuID0gdGhpcy5sZWZ0XG4gICAgd2hpbGUgKG4gIT09IG51bGwgJiYgbi5kZWxldGVkKSB7XG4gICAgICBuID0gbi5sZWZ0XG4gICAgfVxuICAgIHJldHVybiBuXG4gIH1cblxuICAvKipcbiAgICogQ29tcHV0ZXMgdGhlIGxhc3QgY29udGVudCBhZGRyZXNzIG9mIHRoaXMgSXRlbS5cbiAgICovXG4gIGdldCBsYXN0SWQgKCkge1xuICAgIC8vIGFsbG9jYXRpbmcgaWRzIGlzIHByZXR0eSBjb3N0bHkgYmVjYXVzZSBvZiB0aGUgYW1vdW50IG9mIGlkcyBjcmVhdGVkLCBzbyB3ZSB0cnkgdG8gcmV1c2Ugd2hlbmV2ZXIgcG9zc2libGVcbiAgICByZXR1cm4gdGhpcy5sZW5ndGggPT09IDEgPyB0aGlzLmlkIDogY3JlYXRlSUQodGhpcy5pZC5jbGllbnQsIHRoaXMuaWQuY2xvY2sgKyB0aGlzLmxlbmd0aCAtIDEpXG4gIH1cblxuICAvKipcbiAgICogVHJ5IHRvIG1lcmdlIHR3byBpdGVtc1xuICAgKlxuICAgKiBAcGFyYW0ge0l0ZW19IHJpZ2h0XG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBtZXJnZVdpdGggKHJpZ2h0KSB7XG4gICAgaWYgKFxuICAgICAgdGhpcy5jb25zdHJ1Y3RvciA9PT0gcmlnaHQuY29uc3RydWN0b3IgJiZcbiAgICAgIGNvbXBhcmVJRHMocmlnaHQub3JpZ2luLCB0aGlzLmxhc3RJZCkgJiZcbiAgICAgIHRoaXMucmlnaHQgPT09IHJpZ2h0ICYmXG4gICAgICBjb21wYXJlSURzKHRoaXMucmlnaHRPcmlnaW4sIHJpZ2h0LnJpZ2h0T3JpZ2luKSAmJlxuICAgICAgdGhpcy5pZC5jbGllbnQgPT09IHJpZ2h0LmlkLmNsaWVudCAmJlxuICAgICAgdGhpcy5pZC5jbG9jayArIHRoaXMubGVuZ3RoID09PSByaWdodC5pZC5jbG9jayAmJlxuICAgICAgdGhpcy5kZWxldGVkID09PSByaWdodC5kZWxldGVkICYmXG4gICAgICB0aGlzLnJlZG9uZSA9PT0gbnVsbCAmJlxuICAgICAgcmlnaHQucmVkb25lID09PSBudWxsICYmXG4gICAgICB0aGlzLmNvbnRlbnQuY29uc3RydWN0b3IgPT09IHJpZ2h0LmNvbnRlbnQuY29uc3RydWN0b3IgJiZcbiAgICAgIHRoaXMuY29udGVudC5tZXJnZVdpdGgocmlnaHQuY29udGVudClcbiAgICApIHtcbiAgICAgIGNvbnN0IHNlYXJjaE1hcmtlciA9IC8qKiBAdHlwZSB7QWJzdHJhY3RUeXBlPGFueT59ICovICh0aGlzLnBhcmVudCkuX3NlYXJjaE1hcmtlclxuICAgICAgaWYgKHNlYXJjaE1hcmtlcikge1xuICAgICAgICBzZWFyY2hNYXJrZXIuZm9yRWFjaChtYXJrZXIgPT4ge1xuICAgICAgICAgIGlmIChtYXJrZXIucCA9PT0gcmlnaHQpIHtcbiAgICAgICAgICAgIC8vIHJpZ2h0IGlzIGdvaW5nIHRvIGJlIFwiZm9yZ290dGVuXCIgc28gd2UgbmVlZCB0byB1cGRhdGUgdGhlIG1hcmtlclxuICAgICAgICAgICAgbWFya2VyLnAgPSB0aGlzXG4gICAgICAgICAgICAvLyBhZGp1c3QgbWFya2VyIGluZGV4XG4gICAgICAgICAgICBpZiAoIXRoaXMuZGVsZXRlZCAmJiB0aGlzLmNvdW50YWJsZSkge1xuICAgICAgICAgICAgICBtYXJrZXIuaW5kZXggLT0gdGhpcy5sZW5ndGhcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgICBpZiAocmlnaHQua2VlcCkge1xuICAgICAgICB0aGlzLmtlZXAgPSB0cnVlXG4gICAgICB9XG4gICAgICB0aGlzLnJpZ2h0ID0gcmlnaHQucmlnaHRcbiAgICAgIGlmICh0aGlzLnJpZ2h0ICE9PSBudWxsKSB7XG4gICAgICAgIHRoaXMucmlnaHQubGVmdCA9IHRoaXNcbiAgICAgIH1cbiAgICAgIHRoaXMubGVuZ3RoICs9IHJpZ2h0Lmxlbmd0aFxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogTWFyayB0aGlzIEl0ZW0gYXMgZGVsZXRlZC5cbiAgICpcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICovXG4gIGRlbGV0ZSAodHJhbnNhY3Rpb24pIHtcbiAgICBpZiAoIXRoaXMuZGVsZXRlZCkge1xuICAgICAgY29uc3QgcGFyZW50ID0gLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKHRoaXMucGFyZW50KVxuICAgICAgLy8gYWRqdXN0IHRoZSBsZW5ndGggb2YgcGFyZW50XG4gICAgICBpZiAodGhpcy5jb3VudGFibGUgJiYgdGhpcy5wYXJlbnRTdWIgPT09IG51bGwpIHtcbiAgICAgICAgcGFyZW50Ll9sZW5ndGggLT0gdGhpcy5sZW5ndGhcbiAgICAgIH1cbiAgICAgIHRoaXMubWFya0RlbGV0ZWQoKVxuICAgICAgYWRkVG9EZWxldGVTZXQodHJhbnNhY3Rpb24uZGVsZXRlU2V0LCB0aGlzLmlkLmNsaWVudCwgdGhpcy5pZC5jbG9jaywgdGhpcy5sZW5ndGgpXG4gICAgICBhZGRDaGFuZ2VkVHlwZVRvVHJhbnNhY3Rpb24odHJhbnNhY3Rpb24sIHBhcmVudCwgdGhpcy5wYXJlbnRTdWIpXG4gICAgICB0aGlzLmNvbnRlbnQuZGVsZXRlKHRyYW5zYWN0aW9uKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1N0cnVjdFN0b3JlfSBzdG9yZVxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IHBhcmVudEdDZFxuICAgKi9cbiAgZ2MgKHN0b3JlLCBwYXJlbnRHQ2QpIHtcbiAgICBpZiAoIXRoaXMuZGVsZXRlZCkge1xuICAgICAgdGhyb3cgZXJyb3IudW5leHBlY3RlZENhc2UoKVxuICAgIH1cbiAgICB0aGlzLmNvbnRlbnQuZ2Moc3RvcmUpXG4gICAgaWYgKHBhcmVudEdDZCkge1xuICAgICAgcmVwbGFjZVN0cnVjdChzdG9yZSwgdGhpcywgbmV3IEdDKHRoaXMuaWQsIHRoaXMubGVuZ3RoKSlcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jb250ZW50ID0gbmV3IENvbnRlbnREZWxldGVkKHRoaXMubGVuZ3RoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFuc2Zvcm0gdGhlIHByb3BlcnRpZXMgb2YgdGhpcyB0eXBlIHRvIGJpbmFyeSBhbmQgd3JpdGUgaXQgdG8gYW5cbiAgICogQmluYXJ5RW5jb2Rlci5cbiAgICpcbiAgICogVGhpcyBpcyBjYWxsZWQgd2hlbiB0aGlzIEl0ZW0gaXMgc2VudCB0byBhIHJlbW90ZSBwZWVyLlxuICAgKlxuICAgKiBAcGFyYW0ge1VwZGF0ZUVuY29kZXJWMSB8IFVwZGF0ZUVuY29kZXJWMn0gZW5jb2RlciBUaGUgZW5jb2RlciB0byB3cml0ZSBkYXRhIHRvLlxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICB3cml0ZSAoZW5jb2Rlciwgb2Zmc2V0KSB7XG4gICAgY29uc3Qgb3JpZ2luID0gb2Zmc2V0ID4gMCA/IGNyZWF0ZUlEKHRoaXMuaWQuY2xpZW50LCB0aGlzLmlkLmNsb2NrICsgb2Zmc2V0IC0gMSkgOiB0aGlzLm9yaWdpblxuICAgIGNvbnN0IHJpZ2h0T3JpZ2luID0gdGhpcy5yaWdodE9yaWdpblxuICAgIGNvbnN0IHBhcmVudFN1YiA9IHRoaXMucGFyZW50U3ViXG4gICAgY29uc3QgaW5mbyA9ICh0aGlzLmNvbnRlbnQuZ2V0UmVmKCkgJiBiaW5hcnkuQklUUzUpIHxcbiAgICAgIChvcmlnaW4gPT09IG51bGwgPyAwIDogYmluYXJ5LkJJVDgpIHwgLy8gb3JpZ2luIGlzIGRlZmluZWRcbiAgICAgIChyaWdodE9yaWdpbiA9PT0gbnVsbCA/IDAgOiBiaW5hcnkuQklUNykgfCAvLyByaWdodCBvcmlnaW4gaXMgZGVmaW5lZFxuICAgICAgKHBhcmVudFN1YiA9PT0gbnVsbCA/IDAgOiBiaW5hcnkuQklUNikgLy8gcGFyZW50U3ViIGlzIG5vbi1udWxsXG4gICAgZW5jb2Rlci53cml0ZUluZm8oaW5mbylcbiAgICBpZiAob3JpZ2luICE9PSBudWxsKSB7XG4gICAgICBlbmNvZGVyLndyaXRlTGVmdElEKG9yaWdpbilcbiAgICB9XG4gICAgaWYgKHJpZ2h0T3JpZ2luICE9PSBudWxsKSB7XG4gICAgICBlbmNvZGVyLndyaXRlUmlnaHRJRChyaWdodE9yaWdpbilcbiAgICB9XG4gICAgaWYgKG9yaWdpbiA9PT0gbnVsbCAmJiByaWdodE9yaWdpbiA9PT0gbnVsbCkge1xuICAgICAgY29uc3QgcGFyZW50ID0gLyoqIEB0eXBlIHtBYnN0cmFjdFR5cGU8YW55Pn0gKi8gKHRoaXMucGFyZW50KVxuICAgICAgaWYgKHBhcmVudC5faXRlbSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudEl0ZW0gPSBwYXJlbnQuX2l0ZW1cbiAgICAgICAgaWYgKHBhcmVudEl0ZW0gPT09IG51bGwpIHtcbiAgICAgICAgICAvLyBwYXJlbnQgdHlwZSBvbiB5Ll9tYXBcbiAgICAgICAgICAvLyBmaW5kIHRoZSBjb3JyZWN0IGtleVxuICAgICAgICAgIGNvbnN0IHlrZXkgPSBmaW5kUm9vdFR5cGVLZXkocGFyZW50KVxuICAgICAgICAgIGVuY29kZXIud3JpdGVQYXJlbnRJbmZvKHRydWUpIC8vIHdyaXRlIHBhcmVudFlLZXlcbiAgICAgICAgICBlbmNvZGVyLndyaXRlU3RyaW5nKHlrZXkpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW5jb2Rlci53cml0ZVBhcmVudEluZm8oZmFsc2UpIC8vIHdyaXRlIHBhcmVudCBpZFxuICAgICAgICAgIGVuY29kZXIud3JpdGVMZWZ0SUQocGFyZW50SXRlbS5pZClcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJlbnQuY29uc3RydWN0b3IgPT09IFN0cmluZykgeyAvLyB0aGlzIGVkZ2UgY2FzZSB3YXMgYWRkZWQgYnkgZGlmZmVyZW50aWFsIHVwZGF0ZXNcbiAgICAgICAgZW5jb2Rlci53cml0ZVBhcmVudEluZm8odHJ1ZSkgLy8gd3JpdGUgcGFyZW50WUtleVxuICAgICAgICBlbmNvZGVyLndyaXRlU3RyaW5nKHBhcmVudClcbiAgICAgIH0gZWxzZSBpZiAocGFyZW50LmNvbnN0cnVjdG9yID09PSBJRCkge1xuICAgICAgICBlbmNvZGVyLndyaXRlUGFyZW50SW5mbyhmYWxzZSkgLy8gd3JpdGUgcGFyZW50IGlkXG4gICAgICAgIGVuY29kZXIud3JpdGVMZWZ0SUQocGFyZW50KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXJyb3IudW5leHBlY3RlZENhc2UoKVxuICAgICAgfVxuICAgICAgaWYgKHBhcmVudFN1YiAhPT0gbnVsbCkge1xuICAgICAgICBlbmNvZGVyLndyaXRlU3RyaW5nKHBhcmVudFN1YilcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5jb250ZW50LndyaXRlKGVuY29kZXIsIG9mZnNldClcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7VXBkYXRlRGVjb2RlclYxIHwgVXBkYXRlRGVjb2RlclYyfSBkZWNvZGVyXG4gKiBAcGFyYW0ge251bWJlcn0gaW5mb1xuICovXG5leHBvcnQgY29uc3QgcmVhZEl0ZW1Db250ZW50ID0gKGRlY29kZXIsIGluZm8pID0+IGNvbnRlbnRSZWZzW2luZm8gJiBiaW5hcnkuQklUUzVdKGRlY29kZXIpXG5cbi8qKlxuICogQSBsb29rdXAgbWFwIGZvciByZWFkaW5nIEl0ZW0gY29udGVudC5cbiAqXG4gKiBAdHlwZSB7QXJyYXk8ZnVuY3Rpb24oVXBkYXRlRGVjb2RlclYxIHwgVXBkYXRlRGVjb2RlclYyKTpBYnN0cmFjdENvbnRlbnQ+fVxuICovXG5leHBvcnQgY29uc3QgY29udGVudFJlZnMgPSBbXG4gICgpID0+IHsgZXJyb3IudW5leHBlY3RlZENhc2UoKSB9LCAvLyBHQyBpcyBub3QgSXRlbUNvbnRlbnRcbiAgcmVhZENvbnRlbnREZWxldGVkLCAvLyAxXG4gIHJlYWRDb250ZW50SlNPTiwgLy8gMlxuICByZWFkQ29udGVudEJpbmFyeSwgLy8gM1xuICByZWFkQ29udGVudFN0cmluZywgLy8gNFxuICByZWFkQ29udGVudEVtYmVkLCAvLyA1XG4gIHJlYWRDb250ZW50Rm9ybWF0LCAvLyA2XG4gIHJlYWRDb250ZW50VHlwZSwgLy8gN1xuICByZWFkQ29udGVudEFueSwgLy8gOFxuICByZWFkQ29udGVudERvYywgLy8gOVxuICAoKSA9PiB7IGVycm9yLnVuZXhwZWN0ZWRDYXNlKCkgfSAvLyAxMCAtIFNraXAgaXMgbm90IEl0ZW1Db250ZW50XG5dXG5cbi8qKlxuICogRG8gbm90IGltcGxlbWVudCB0aGlzIGNsYXNzIVxuICovXG5leHBvcnQgY2xhc3MgQWJzdHJhY3RDb250ZW50IHtcbiAgLyoqXG4gICAqIEByZXR1cm4ge251bWJlcn1cbiAgICovXG4gIGdldExlbmd0aCAoKSB7XG4gICAgdGhyb3cgZXJyb3IubWV0aG9kVW5pbXBsZW1lbnRlZCgpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7QXJyYXk8YW55Pn1cbiAgICovXG4gIGdldENvbnRlbnQgKCkge1xuICAgIHRocm93IGVycm9yLm1ldGhvZFVuaW1wbGVtZW50ZWQoKVxuICB9XG5cbiAgLyoqXG4gICAqIFNob3VsZCByZXR1cm4gZmFsc2UgaWYgdGhpcyBJdGVtIGlzIHNvbWUga2luZCBvZiBtZXRhIGluZm9ybWF0aW9uXG4gICAqIChlLmcuIGZvcm1hdCBpbmZvcm1hdGlvbikuXG4gICAqXG4gICAqICogV2hldGhlciB0aGlzIEl0ZW0gc2hvdWxkIGJlIGFkZHJlc3NhYmxlIHZpYSBgeWFycmF5LmdldChpKWBcbiAgICogKiBXaGV0aGVyIHRoaXMgSXRlbSBzaG91bGQgYmUgY291bnRlZCB3aGVuIGNvbXB1dGluZyB5YXJyYXkubGVuZ3RoXG4gICAqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59XG4gICAqL1xuICBpc0NvdW50YWJsZSAoKSB7XG4gICAgdGhyb3cgZXJyb3IubWV0aG9kVW5pbXBsZW1lbnRlZCgpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7QWJzdHJhY3RDb250ZW50fVxuICAgKi9cbiAgY29weSAoKSB7XG4gICAgdGhyb3cgZXJyb3IubWV0aG9kVW5pbXBsZW1lbnRlZCgpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IF9vZmZzZXRcbiAgICogQHJldHVybiB7QWJzdHJhY3RDb250ZW50fVxuICAgKi9cbiAgc3BsaWNlIChfb2Zmc2V0KSB7XG4gICAgdGhyb3cgZXJyb3IubWV0aG9kVW5pbXBsZW1lbnRlZCgpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtBYnN0cmFjdENvbnRlbnR9IF9yaWdodFxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgbWVyZ2VXaXRoIChfcmlnaHQpIHtcbiAgICB0aHJvdyBlcnJvci5tZXRob2RVbmltcGxlbWVudGVkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSBfdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtJdGVtfSBfaXRlbVxuICAgKi9cbiAgaW50ZWdyYXRlIChfdHJhbnNhY3Rpb24sIF9pdGVtKSB7XG4gICAgdGhyb3cgZXJyb3IubWV0aG9kVW5pbXBsZW1lbnRlZCgpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtUcmFuc2FjdGlvbn0gX3RyYW5zYWN0aW9uXG4gICAqL1xuICBkZWxldGUgKF90cmFuc2FjdGlvbikge1xuICAgIHRocm93IGVycm9yLm1ldGhvZFVuaW1wbGVtZW50ZWQoKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RydWN0U3RvcmV9IF9zdG9yZVxuICAgKi9cbiAgZ2MgKF9zdG9yZSkge1xuICAgIHRocm93IGVycm9yLm1ldGhvZFVuaW1wbGVtZW50ZWQoKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VXBkYXRlRW5jb2RlclYxIHwgVXBkYXRlRW5jb2RlclYyfSBfZW5jb2RlclxuICAgKiBAcGFyYW0ge251bWJlcn0gX29mZnNldFxuICAgKi9cbiAgd3JpdGUgKF9lbmNvZGVyLCBfb2Zmc2V0KSB7XG4gICAgdGhyb3cgZXJyb3IubWV0aG9kVW5pbXBsZW1lbnRlZCgpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7bnVtYmVyfVxuICAgKi9cbiAgZ2V0UmVmICgpIHtcbiAgICB0aHJvdyBlcnJvci5tZXRob2RVbmltcGxlbWVudGVkKClcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIEFic3RyYWN0U3RydWN0LFxuICBVcGRhdGVFbmNvZGVyVjEsIFVwZGF0ZUVuY29kZXJWMiwgU3RydWN0U3RvcmUsIFRyYW5zYWN0aW9uLCBJRCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG59IGZyb20gJy4uL2ludGVybmFscy5qcydcbmltcG9ydCAqIGFzIGVycm9yIGZyb20gJ2xpYjAvZXJyb3InXG5pbXBvcnQgKiBhcyBlbmNvZGluZyBmcm9tICdsaWIwL2VuY29kaW5nJ1xuXG5leHBvcnQgY29uc3Qgc3RydWN0U2tpcFJlZk51bWJlciA9IDEwXG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGNsYXNzIFNraXAgZXh0ZW5kcyBBYnN0cmFjdFN0cnVjdCB7XG4gIGdldCBkZWxldGVkICgpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgZGVsZXRlICgpIHt9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7U2tpcH0gcmlnaHRcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIG1lcmdlV2l0aCAocmlnaHQpIHtcbiAgICBpZiAodGhpcy5jb25zdHJ1Y3RvciAhPT0gcmlnaHQuY29uc3RydWN0b3IpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgICB0aGlzLmxlbmd0aCArPSByaWdodC5sZW5ndGhcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAgICovXG4gIGludGVncmF0ZSAodHJhbnNhY3Rpb24sIG9mZnNldCkge1xuICAgIC8vIHNraXAgc3RydWN0cyBjYW5ub3QgYmUgaW50ZWdyYXRlZFxuICAgIGVycm9yLnVuZXhwZWN0ZWRDYXNlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1VwZGF0ZUVuY29kZXJWMSB8IFVwZGF0ZUVuY29kZXJWMn0gZW5jb2RlclxuICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0XG4gICAqL1xuICB3cml0ZSAoZW5jb2Rlciwgb2Zmc2V0KSB7XG4gICAgZW5jb2Rlci53cml0ZUluZm8oc3RydWN0U2tpcFJlZk51bWJlcilcbiAgICAvLyB3cml0ZSBhcyBWYXJVaW50IGJlY2F1c2UgU2tpcHMgY2FuJ3QgbWFrZSB1c2Ugb2YgcHJlZGljdGFibGUgbGVuZ3RoLWVuY29kaW5nXG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIucmVzdEVuY29kZXIsIHRoaXMubGVuZ3RoIC0gb2Zmc2V0KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7VHJhbnNhY3Rpb259IHRyYW5zYWN0aW9uXG4gICAqIEBwYXJhbSB7U3RydWN0U3RvcmV9IHN0b3JlXG4gICAqIEByZXR1cm4ge251bGwgfCBudW1iZXJ9XG4gICAqL1xuICBnZXRNaXNzaW5nICh0cmFuc2FjdGlvbiwgc3RvcmUpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG4iLCAiLyoqIGVzbGludC1lbnYgYnJvd3NlciAqL1xuXG5leHBvcnQge1xuICBEb2MsXG4gIFRyYW5zYWN0aW9uLFxuICBZQXJyYXkgYXMgQXJyYXksXG4gIFlNYXAgYXMgTWFwLFxuICBZVGV4dCBhcyBUZXh0LFxuICBZWG1sVGV4dCBhcyBYbWxUZXh0LFxuICBZWG1sSG9vayBhcyBYbWxIb29rLFxuICBZWG1sRWxlbWVudCBhcyBYbWxFbGVtZW50LFxuICBZWG1sRnJhZ21lbnQgYXMgWG1sRnJhZ21lbnQsXG4gIFlYbWxFdmVudCxcbiAgWU1hcEV2ZW50LFxuICBZQXJyYXlFdmVudCxcbiAgWVRleHRFdmVudCxcbiAgWUV2ZW50LFxuICBJdGVtLFxuICBBYnN0cmFjdFN0cnVjdCxcbiAgR0MsXG4gIFNraXAsXG4gIENvbnRlbnRCaW5hcnksXG4gIENvbnRlbnREZWxldGVkLFxuICBDb250ZW50RG9jLFxuICBDb250ZW50RW1iZWQsXG4gIENvbnRlbnRGb3JtYXQsXG4gIENvbnRlbnRKU09OLFxuICBDb250ZW50QW55LFxuICBDb250ZW50U3RyaW5nLFxuICBDb250ZW50VHlwZSxcbiAgQWJzdHJhY3RUeXBlLFxuICBnZXRUeXBlQ2hpbGRyZW4sXG4gIGNyZWF0ZVJlbGF0aXZlUG9zaXRpb25Gcm9tVHlwZUluZGV4LFxuICBjcmVhdGVSZWxhdGl2ZVBvc2l0aW9uRnJvbUpTT04sXG4gIGNyZWF0ZUFic29sdXRlUG9zaXRpb25Gcm9tUmVsYXRpdmVQb3NpdGlvbixcbiAgY29tcGFyZVJlbGF0aXZlUG9zaXRpb25zLFxuICBBYnNvbHV0ZVBvc2l0aW9uLFxuICBSZWxhdGl2ZVBvc2l0aW9uLFxuICBJRCxcbiAgY3JlYXRlSUQsXG4gIGNvbXBhcmVJRHMsXG4gIGdldFN0YXRlLFxuICBTbmFwc2hvdCxcbiAgY3JlYXRlU25hcHNob3QsXG4gIGNyZWF0ZURlbGV0ZVNldCxcbiAgY3JlYXRlRGVsZXRlU2V0RnJvbVN0cnVjdFN0b3JlLFxuICBjbGVhbnVwWVRleHRGb3JtYXR0aW5nLFxuICBzbmFwc2hvdCxcbiAgZW1wdHlTbmFwc2hvdCxcbiAgZmluZFJvb3RUeXBlS2V5LFxuICBmaW5kSW5kZXhTUyxcbiAgZ2V0SXRlbSxcbiAgZ2V0SXRlbUNsZWFuU3RhcnQsXG4gIGdldEl0ZW1DbGVhbkVuZCxcbiAgdHlwZUxpc3RUb0FycmF5U25hcHNob3QsXG4gIHR5cGVNYXBHZXRTbmFwc2hvdCxcbiAgdHlwZU1hcEdldEFsbFNuYXBzaG90LFxuICBjcmVhdGVEb2NGcm9tU25hcHNob3QsXG4gIGl0ZXJhdGVEZWxldGVkU3RydWN0cyxcbiAgYXBwbHlVcGRhdGUsXG4gIGFwcGx5VXBkYXRlVjIsXG4gIHJlYWRVcGRhdGUsXG4gIHJlYWRVcGRhdGVWMixcbiAgZW5jb2RlU3RhdGVBc1VwZGF0ZSxcbiAgZW5jb2RlU3RhdGVBc1VwZGF0ZVYyLFxuICBlbmNvZGVTdGF0ZVZlY3RvcixcbiAgVW5kb01hbmFnZXIsXG4gIGRlY29kZVNuYXBzaG90LFxuICBlbmNvZGVTbmFwc2hvdCxcbiAgZGVjb2RlU25hcHNob3RWMixcbiAgZW5jb2RlU25hcHNob3RWMixcbiAgZGVjb2RlU3RhdGVWZWN0b3IsXG4gIGxvZ1VwZGF0ZSxcbiAgbG9nVXBkYXRlVjIsXG4gIGRlY29kZVVwZGF0ZSxcbiAgZGVjb2RlVXBkYXRlVjIsXG4gIHJlbGF0aXZlUG9zaXRpb25Ub0pTT04sXG4gIGlzRGVsZXRlZCxcbiAgaXNQYXJlbnRPZixcbiAgZXF1YWxTbmFwc2hvdHMsXG4gIFBlcm1hbmVudFVzZXJEYXRhLCAvLyBAVE9ETyBleHBlcmltZW50YWxcbiAgdHJ5R2MsXG4gIHRyYW5zYWN0LFxuICBBYnN0cmFjdENvbm5lY3RvcixcbiAgbG9nVHlwZSxcbiAgbWVyZ2VVcGRhdGVzLFxuICBtZXJnZVVwZGF0ZXNWMixcbiAgcGFyc2VVcGRhdGVNZXRhLFxuICBwYXJzZVVwZGF0ZU1ldGFWMixcbiAgZW5jb2RlU3RhdGVWZWN0b3JGcm9tVXBkYXRlLFxuICBlbmNvZGVTdGF0ZVZlY3RvckZyb21VcGRhdGVWMixcbiAgZW5jb2RlUmVsYXRpdmVQb3NpdGlvbixcbiAgZGVjb2RlUmVsYXRpdmVQb3NpdGlvbixcbiAgZGlmZlVwZGF0ZSxcbiAgZGlmZlVwZGF0ZVYyLFxuICBjb252ZXJ0VXBkYXRlRm9ybWF0VjFUb1YyLFxuICBjb252ZXJ0VXBkYXRlRm9ybWF0VjJUb1YxLFxuICBvYmZ1c2NhdGVVcGRhdGUsXG4gIG9iZnVzY2F0ZVVwZGF0ZVYyLFxuICBVcGRhdGVFbmNvZGVyVjEsXG4gIFVwZGF0ZUVuY29kZXJWMixcbiAgVXBkYXRlRGVjb2RlclYxLFxuICBVcGRhdGVEZWNvZGVyVjIsXG4gIGVxdWFsRGVsZXRlU2V0cyxcbiAgbWVyZ2VEZWxldGVTZXRzLFxuICBzbmFwc2hvdENvbnRhaW5zVXBkYXRlXG59IGZyb20gJy4vaW50ZXJuYWxzLmpzJ1xuXG5jb25zdCBnbG8gPSAvKiogQHR5cGUge2FueX0gKi8gKHR5cGVvZiBnbG9iYWxUaGlzICE9PSAndW5kZWZpbmVkJ1xuICA/IGdsb2JhbFRoaXNcbiAgOiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgID8gd2luZG93XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIDogdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB7fSlcblxuY29uc3QgaW1wb3J0SWRlbnRpZmllciA9ICdfXyAkWUpTJCBfXydcblxuaWYgKGdsb1tpbXBvcnRJZGVudGlmaWVyXSA9PT0gdHJ1ZSkge1xuICAvKipcbiAgICogRGVhciByZWFkZXIgb2YgdGhpcyBtZXNzYWdlLiBQbGVhc2UgdGFrZSB0aGlzIHNlcmlvdXNseS5cbiAgICpcbiAgICogSWYgeW91IHNlZSB0aGlzIG1lc3NhZ2UsIG1ha2Ugc3VyZSB0aGF0IHlvdSBvbmx5IGltcG9ydCBvbmUgdmVyc2lvbiBvZiBZanMuIEluIG1hbnkgY2FzZXMsXG4gICAqIHlvdXIgcGFja2FnZSBtYW5hZ2VyIGluc3RhbGxzIHR3byB2ZXJzaW9ucyBvZiBZanMgdGhhdCBhcmUgdXNlZCBieSBkaWZmZXJlbnQgcGFja2FnZXMgd2l0aGluIHlvdXIgcHJvamVjdC5cbiAgICogQW5vdGhlciByZWFzb24gZm9yIHRoaXMgbWVzc2FnZSBpcyB0aGF0IHNvbWUgcGFydHMgb2YgeW91ciBwcm9qZWN0IHVzZSB0aGUgY29tbW9uanMgdmVyc2lvbiBvZiBZanNcbiAgICogYW5kIG90aGVycyB1c2UgdGhlIEVjbWFTY3JpcHQgdmVyc2lvbiBvZiBZanMuXG4gICAqXG4gICAqIFRoaXMgb2Z0ZW4gbGVhZHMgdG8gaXNzdWVzIHRoYXQgYXJlIGhhcmQgdG8gZGVidWcuIFdlIG9mdGVuIG5lZWQgdG8gcGVyZm9ybSBjb25zdHJ1Y3RvciBjaGVja3MsXG4gICAqIGUuZy4gYHN0cnVjdCBpbnN0YW5jZW9mIEdDYC4gSWYgeW91IGltcG9ydGVkIGRpZmZlcmVudCB2ZXJzaW9ucyBvZiBZanMsIGl0IGlzIGltcG9zc2libGUgZm9yIHVzIHRvXG4gICAqIGRvIHRoZSBjb25zdHJ1Y3RvciBjaGVja3MgYW55bW9yZSAtIHdoaWNoIG1pZ2h0IGJyZWFrIHRoZSBDUkRUIGFsZ29yaXRobS5cbiAgICpcbiAgICogaHR0cHM6Ly9naXRodWIuY29tL3lqcy95anMvaXNzdWVzLzQzOFxuICAgKi9cbiAgY29uc29sZS5lcnJvcignWWpzIHdhcyBhbHJlYWR5IGltcG9ydGVkLiBUaGlzIGJyZWFrcyBjb25zdHJ1Y3RvciBjaGVja3MgYW5kIHdpbGwgbGVhZCB0byBpc3N1ZXMhIC0gaHR0cHM6Ly9naXRodWIuY29tL3lqcy95anMvaXNzdWVzLzQzOCcpXG59XG5nbG9baW1wb3J0SWRlbnRpZmllcl0gPSB0cnVlXG4iLCAiLyoqXG4gKiBAbW9kdWxlIGF3YXJlbmVzcy1wcm90b2NvbFxuICovXG5cbmltcG9ydCAqIGFzIGVuY29kaW5nIGZyb20gJ2xpYjAvZW5jb2RpbmcnXG5pbXBvcnQgKiBhcyBkZWNvZGluZyBmcm9tICdsaWIwL2RlY29kaW5nJ1xuaW1wb3J0ICogYXMgdGltZSBmcm9tICdsaWIwL3RpbWUnXG5pbXBvcnQgKiBhcyBtYXRoIGZyb20gJ2xpYjAvbWF0aCdcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdsaWIwL29ic2VydmFibGUnXG5pbXBvcnQgKiBhcyBmIGZyb20gJ2xpYjAvZnVuY3Rpb24nXG5pbXBvcnQgKiBhcyBZIGZyb20gJ3lqcycgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXG5leHBvcnQgY29uc3Qgb3V0ZGF0ZWRUaW1lb3V0ID0gMzAwMDBcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBNZXRhQ2xpZW50U3RhdGVcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBNZXRhQ2xpZW50U3RhdGUuY2xvY2tcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBNZXRhQ2xpZW50U3RhdGUubGFzdFVwZGF0ZWQgdW5peCB0aW1lc3RhbXBcbiAqL1xuXG4vKipcbiAqIFRoZSBBd2FyZW5lc3MgY2xhc3MgaW1wbGVtZW50cyBhIHNpbXBsZSBzaGFyZWQgc3RhdGUgcHJvdG9jb2wgdGhhdCBjYW4gYmUgdXNlZCBmb3Igbm9uLXBlcnNpc3RlbnQgZGF0YSBsaWtlIGF3YXJlbmVzcyBpbmZvcm1hdGlvblxuICogKGN1cnNvciwgdXNlcm5hbWUsIHN0YXR1cywgLi4pLiBFYWNoIGNsaWVudCBjYW4gdXBkYXRlIGl0cyBvd24gbG9jYWwgc3RhdGUgYW5kIGxpc3RlbiB0byBzdGF0ZSBjaGFuZ2VzIG9mXG4gKiByZW1vdGUgY2xpZW50cy4gRXZlcnkgY2xpZW50IG1heSBzZXQgYSBzdGF0ZSBvZiBhIHJlbW90ZSBwZWVyIHRvIGBudWxsYCB0byBtYXJrIHRoZSBjbGllbnQgYXMgb2ZmbGluZS5cbiAqXG4gKiBFYWNoIGNsaWVudCBpcyBpZGVudGlmaWVkIGJ5IGEgdW5pcXVlIGNsaWVudCBpZCAoc29tZXRoaW5nIHdlIGJvcnJvdyBmcm9tIGBkb2MuY2xpZW50SURgKS4gQSBjbGllbnQgY2FuIG92ZXJyaWRlXG4gKiBpdHMgb3duIHN0YXRlIGJ5IHByb3BhZ2F0aW5nIGEgbWVzc2FnZSB3aXRoIGFuIGluY3JlYXNpbmcgdGltZXN0YW1wIChgY2xvY2tgKS4gSWYgc3VjaCBhIG1lc3NhZ2UgaXMgcmVjZWl2ZWQsIGl0IGlzXG4gKiBhcHBsaWVkIGlmIHRoZSBrbm93biBzdGF0ZSBvZiB0aGF0IGNsaWVudCBpcyBvbGRlciB0aGFuIHRoZSBuZXcgc3RhdGUgKGBjbG9jayA8IG5ld0Nsb2NrYCkuIElmIGEgY2xpZW50IHRoaW5rcyB0aGF0XG4gKiBhIHJlbW90ZSBjbGllbnQgaXMgb2ZmbGluZSwgaXQgbWF5IHByb3BhZ2F0ZSBhIG1lc3NhZ2Ugd2l0aFxuICogYHsgY2xvY2s6IGN1cnJlbnRDbGllbnRDbG9jaywgc3RhdGU6IG51bGwsIGNsaWVudDogcmVtb3RlQ2xpZW50IH1gLiBJZiBzdWNoIGFcbiAqIG1lc3NhZ2UgaXMgcmVjZWl2ZWQsIGFuZCB0aGUga25vd24gY2xvY2sgb2YgdGhhdCBjbGllbnQgZXF1YWxzIHRoZSByZWNlaXZlZCBjbG9jaywgaXQgd2lsbCBvdmVycmlkZSB0aGUgc3RhdGUgd2l0aCBgbnVsbGAuXG4gKlxuICogQmVmb3JlIGEgY2xpZW50IGRpc2Nvbm5lY3RzLCBpdCBzaG91bGQgcHJvcGFnYXRlIGEgYG51bGxgIHN0YXRlIHdpdGggYW4gdXBkYXRlZCBjbG9jay5cbiAqXG4gKiBBd2FyZW5lc3Mgc3RhdGVzIG11c3QgYmUgdXBkYXRlZCBldmVyeSAzMCBzZWNvbmRzLiBPdGhlcndpc2UgdGhlIEF3YXJlbmVzcyBpbnN0YW5jZSB3aWxsIGRlbGV0ZSB0aGUgY2xpZW50IHN0YXRlLlxuICpcbiAqIEBleHRlbmRzIHtPYnNlcnZhYmxlPHN0cmluZz59XG4gKi9cbmV4cG9ydCBjbGFzcyBBd2FyZW5lc3MgZXh0ZW5kcyBPYnNlcnZhYmxlIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7WS5Eb2N9IGRvY1xuICAgKi9cbiAgY29uc3RydWN0b3IgKGRvYykge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLmRvYyA9IGRvY1xuICAgIC8qKlxuICAgICAqIEB0eXBlIHtudW1iZXJ9XG4gICAgICovXG4gICAgdGhpcy5jbGllbnRJRCA9IGRvYy5jbGllbnRJRFxuICAgIC8qKlxuICAgICAqIE1hcHMgZnJvbSBjbGllbnQgaWQgdG8gY2xpZW50IHN0YXRlXG4gICAgICogQHR5cGUge01hcDxudW1iZXIsIE9iamVjdDxzdHJpbmcsIGFueT4+fVxuICAgICAqL1xuICAgIHRoaXMuc3RhdGVzID0gbmV3IE1hcCgpXG4gICAgLyoqXG4gICAgICogQHR5cGUge01hcDxudW1iZXIsIE1ldGFDbGllbnRTdGF0ZT59XG4gICAgICovXG4gICAgdGhpcy5tZXRhID0gbmV3IE1hcCgpXG4gICAgdGhpcy5fY2hlY2tJbnRlcnZhbCA9IC8qKiBAdHlwZSB7YW55fSAqLyAoc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgY29uc3Qgbm93ID0gdGltZS5nZXRVbml4VGltZSgpXG4gICAgICBpZiAodGhpcy5nZXRMb2NhbFN0YXRlKCkgIT09IG51bGwgJiYgKG91dGRhdGVkVGltZW91dCAvIDIgPD0gbm93IC0gLyoqIEB0eXBlIHt7bGFzdFVwZGF0ZWQ6bnVtYmVyfX0gKi8gKHRoaXMubWV0YS5nZXQodGhpcy5jbGllbnRJRCkpLmxhc3RVcGRhdGVkKSkge1xuICAgICAgICAvLyByZW5ldyBsb2NhbCBjbG9ja1xuICAgICAgICB0aGlzLnNldExvY2FsU3RhdGUodGhpcy5nZXRMb2NhbFN0YXRlKCkpXG4gICAgICB9XG4gICAgICAvKipcbiAgICAgICAqIEB0eXBlIHtBcnJheTxudW1iZXI+fVxuICAgICAgICovXG4gICAgICBjb25zdCByZW1vdmUgPSBbXVxuICAgICAgdGhpcy5tZXRhLmZvckVhY2goKG1ldGEsIGNsaWVudGlkKSA9PiB7XG4gICAgICAgIGlmIChjbGllbnRpZCAhPT0gdGhpcy5jbGllbnRJRCAmJiBvdXRkYXRlZFRpbWVvdXQgPD0gbm93IC0gbWV0YS5sYXN0VXBkYXRlZCAmJiB0aGlzLnN0YXRlcy5oYXMoY2xpZW50aWQpKSB7XG4gICAgICAgICAgcmVtb3ZlLnB1c2goY2xpZW50aWQpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICBpZiAocmVtb3ZlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmVtb3ZlQXdhcmVuZXNzU3RhdGVzKHRoaXMsIHJlbW92ZSwgJ3RpbWVvdXQnKVxuICAgICAgfVxuICAgIH0sIG1hdGguZmxvb3Iob3V0ZGF0ZWRUaW1lb3V0IC8gMTApKSlcbiAgICBkb2Mub24oJ2Rlc3Ryb3knLCAoKSA9PiB7XG4gICAgICB0aGlzLmRlc3Ryb3koKVxuICAgIH0pXG4gICAgdGhpcy5zZXRMb2NhbFN0YXRlKHt9KVxuICB9XG5cbiAgZGVzdHJveSAoKSB7XG4gICAgdGhpcy5lbWl0KCdkZXN0cm95JywgW3RoaXNdKVxuICAgIHRoaXMuc2V0TG9jYWxTdGF0ZShudWxsKVxuICAgIHN1cGVyLmRlc3Ryb3koKVxuICAgIGNsZWFySW50ZXJ2YWwodGhpcy5fY2hlY2tJbnRlcnZhbClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtPYmplY3Q8c3RyaW5nLGFueT58bnVsbH1cbiAgICovXG4gIGdldExvY2FsU3RhdGUgKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlcy5nZXQodGhpcy5jbGllbnRJRCkgfHwgbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZyxhbnk+fG51bGx9IHN0YXRlXG4gICAqL1xuICBzZXRMb2NhbFN0YXRlIChzdGF0ZSkge1xuICAgIGNvbnN0IGNsaWVudElEID0gdGhpcy5jbGllbnRJRFxuICAgIGNvbnN0IGN1cnJMb2NhbE1ldGEgPSB0aGlzLm1ldGEuZ2V0KGNsaWVudElEKVxuICAgIGNvbnN0IGNsb2NrID0gY3VyckxvY2FsTWV0YSA9PT0gdW5kZWZpbmVkID8gMCA6IGN1cnJMb2NhbE1ldGEuY2xvY2sgKyAxXG4gICAgY29uc3QgcHJldlN0YXRlID0gdGhpcy5zdGF0ZXMuZ2V0KGNsaWVudElEKVxuICAgIGlmIChzdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5zdGF0ZXMuZGVsZXRlKGNsaWVudElEKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YXRlcy5zZXQoY2xpZW50SUQsIHN0YXRlKVxuICAgIH1cbiAgICB0aGlzLm1ldGEuc2V0KGNsaWVudElELCB7XG4gICAgICBjbG9jayxcbiAgICAgIGxhc3RVcGRhdGVkOiB0aW1lLmdldFVuaXhUaW1lKClcbiAgICB9KVxuICAgIGNvbnN0IGFkZGVkID0gW11cbiAgICBjb25zdCB1cGRhdGVkID0gW11cbiAgICBjb25zdCBmaWx0ZXJlZFVwZGF0ZWQgPSBbXVxuICAgIGNvbnN0IHJlbW92ZWQgPSBbXVxuICAgIGlmIChzdGF0ZSA9PT0gbnVsbCkge1xuICAgICAgcmVtb3ZlZC5wdXNoKGNsaWVudElEKVxuICAgIH0gZWxzZSBpZiAocHJldlN0YXRlID09IG51bGwpIHtcbiAgICAgIGlmIChzdGF0ZSAhPSBudWxsKSB7XG4gICAgICAgIGFkZGVkLnB1c2goY2xpZW50SUQpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHVwZGF0ZWQucHVzaChjbGllbnRJRClcbiAgICAgIGlmICghZi5lcXVhbGl0eURlZXAocHJldlN0YXRlLCBzdGF0ZSkpIHtcbiAgICAgICAgZmlsdGVyZWRVcGRhdGVkLnB1c2goY2xpZW50SUQpXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChhZGRlZC5sZW5ndGggPiAwIHx8IGZpbHRlcmVkVXBkYXRlZC5sZW5ndGggPiAwIHx8IHJlbW92ZWQubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5lbWl0KCdjaGFuZ2UnLCBbeyBhZGRlZCwgdXBkYXRlZDogZmlsdGVyZWRVcGRhdGVkLCByZW1vdmVkIH0sICdsb2NhbCddKVxuICAgIH1cbiAgICB0aGlzLmVtaXQoJ3VwZGF0ZScsIFt7IGFkZGVkLCB1cGRhdGVkLCByZW1vdmVkIH0sICdsb2NhbCddKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWVsZFxuICAgKiBAcGFyYW0ge2FueX0gdmFsdWVcbiAgICovXG4gIHNldExvY2FsU3RhdGVGaWVsZCAoZmllbGQsIHZhbHVlKSB7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLmdldExvY2FsU3RhdGUoKVxuICAgIGlmIChzdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5zZXRMb2NhbFN0YXRlKHtcbiAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgIFtmaWVsZF06IHZhbHVlXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtNYXA8bnVtYmVyLE9iamVjdDxzdHJpbmcsYW55Pj59XG4gICAqL1xuICBnZXRTdGF0ZXMgKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXRlc1xuICB9XG59XG5cbi8qKlxuICogTWFyayAocmVtb3RlKSBjbGllbnRzIGFzIGluYWN0aXZlIGFuZCByZW1vdmUgdGhlbSBmcm9tIHRoZSBsaXN0IG9mIGFjdGl2ZSBwZWVycy5cbiAqIFRoaXMgY2hhbmdlIHdpbGwgYmUgcHJvcGFnYXRlZCB0byByZW1vdGUgY2xpZW50cy5cbiAqXG4gKiBAcGFyYW0ge0F3YXJlbmVzc30gYXdhcmVuZXNzXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IGNsaWVudHNcbiAqIEBwYXJhbSB7YW55fSBvcmlnaW5cbiAqL1xuZXhwb3J0IGNvbnN0IHJlbW92ZUF3YXJlbmVzc1N0YXRlcyA9IChhd2FyZW5lc3MsIGNsaWVudHMsIG9yaWdpbikgPT4ge1xuICBjb25zdCByZW1vdmVkID0gW11cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjbGllbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgY2xpZW50SUQgPSBjbGllbnRzW2ldXG4gICAgaWYgKGF3YXJlbmVzcy5zdGF0ZXMuaGFzKGNsaWVudElEKSkge1xuICAgICAgYXdhcmVuZXNzLnN0YXRlcy5kZWxldGUoY2xpZW50SUQpXG4gICAgICBpZiAoY2xpZW50SUQgPT09IGF3YXJlbmVzcy5jbGllbnRJRCkge1xuICAgICAgICBjb25zdCBjdXJNZXRhID0gLyoqIEB0eXBlIHtNZXRhQ2xpZW50U3RhdGV9ICovIChhd2FyZW5lc3MubWV0YS5nZXQoY2xpZW50SUQpKVxuICAgICAgICBhd2FyZW5lc3MubWV0YS5zZXQoY2xpZW50SUQsIHtcbiAgICAgICAgICBjbG9jazogY3VyTWV0YS5jbG9jayArIDEsXG4gICAgICAgICAgbGFzdFVwZGF0ZWQ6IHRpbWUuZ2V0VW5peFRpbWUoKVxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgcmVtb3ZlZC5wdXNoKGNsaWVudElEKVxuICAgIH1cbiAgfVxuICBpZiAocmVtb3ZlZC5sZW5ndGggPiAwKSB7XG4gICAgYXdhcmVuZXNzLmVtaXQoJ2NoYW5nZScsIFt7IGFkZGVkOiBbXSwgdXBkYXRlZDogW10sIHJlbW92ZWQgfSwgb3JpZ2luXSlcbiAgICBhd2FyZW5lc3MuZW1pdCgndXBkYXRlJywgW3sgYWRkZWQ6IFtdLCB1cGRhdGVkOiBbXSwgcmVtb3ZlZCB9LCBvcmlnaW5dKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtBd2FyZW5lc3N9IGF3YXJlbmVzc1xuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBjbGllbnRzXG4gKiBAcmV0dXJuIHtVaW50OEFycmF5fVxuICovXG5leHBvcnQgY29uc3QgZW5jb2RlQXdhcmVuZXNzVXBkYXRlID0gKGF3YXJlbmVzcywgY2xpZW50cywgc3RhdGVzID0gYXdhcmVuZXNzLnN0YXRlcykgPT4ge1xuICBjb25zdCBsZW4gPSBjbGllbnRzLmxlbmd0aFxuICBjb25zdCBlbmNvZGVyID0gZW5jb2RpbmcuY3JlYXRlRW5jb2RlcigpXG4gIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLCBsZW4pXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICBjb25zdCBjbGllbnRJRCA9IGNsaWVudHNbaV1cbiAgICBjb25zdCBzdGF0ZSA9IHN0YXRlcy5nZXQoY2xpZW50SUQpIHx8IG51bGxcbiAgICBjb25zdCBjbG9jayA9IC8qKiBAdHlwZSB7TWV0YUNsaWVudFN0YXRlfSAqLyAoYXdhcmVuZXNzLm1ldGEuZ2V0KGNsaWVudElEKSkuY2xvY2tcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2RlciwgY2xpZW50SUQpXG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIsIGNsb2NrKVxuICAgIGVuY29kaW5nLndyaXRlVmFyU3RyaW5nKGVuY29kZXIsIEpTT04uc3RyaW5naWZ5KHN0YXRlKSlcbiAgfVxuICByZXR1cm4gZW5jb2RpbmcudG9VaW50OEFycmF5KGVuY29kZXIpXG59XG5cbi8qKlxuICogTW9kaWZ5IHRoZSBjb250ZW50IG9mIGFuIGF3YXJlbmVzcyB1cGRhdGUgYmVmb3JlIHJlLWVuY29kaW5nIGl0IHRvIGFuIGF3YXJlbmVzcyB1cGRhdGUuXG4gKlxuICogVGhpcyBtaWdodCBiZSB1c2VmdWwgd2hlbiB5b3UgaGF2ZSBhIGNlbnRyYWwgc2VydmVyIHRoYXQgd2FudHMgdG8gZW5zdXJlIHRoYXQgY2xpZW50c1xuICogY2FudCBoaWphY2sgc29tZWJvZHkgZWxzZXMgaWRlbnRpdHkuXG4gKlxuICogQHBhcmFtIHtVaW50OEFycmF5fSB1cGRhdGVcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oYW55KTphbnl9IG1vZGlmeVxuICogQHJldHVybiB7VWludDhBcnJheX1cbiAqL1xuZXhwb3J0IGNvbnN0IG1vZGlmeUF3YXJlbmVzc1VwZGF0ZSA9ICh1cGRhdGUsIG1vZGlmeSkgPT4ge1xuICBjb25zdCBkZWNvZGVyID0gZGVjb2RpbmcuY3JlYXRlRGVjb2Rlcih1cGRhdGUpXG4gIGNvbnN0IGVuY29kZXIgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKClcbiAgY29uc3QgbGVuID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2RlcilcbiAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIsIGxlbilcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgIGNvbnN0IGNsaWVudElEID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2RlcilcbiAgICBjb25zdCBjbG9jayA9IGRlY29kaW5nLnJlYWRWYXJVaW50KGRlY29kZXIpXG4gICAgY29uc3Qgc3RhdGUgPSBKU09OLnBhcnNlKGRlY29kaW5nLnJlYWRWYXJTdHJpbmcoZGVjb2RlcikpXG4gICAgY29uc3QgbW9kaWZpZWRTdGF0ZSA9IG1vZGlmeShzdGF0ZSlcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2RlciwgY2xpZW50SUQpXG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIsIGNsb2NrKVxuICAgIGVuY29kaW5nLndyaXRlVmFyU3RyaW5nKGVuY29kZXIsIEpTT04uc3RyaW5naWZ5KG1vZGlmaWVkU3RhdGUpKVxuICB9XG4gIHJldHVybiBlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2Rlcilcbn1cblxuLyoqXG4gKiBAcGFyYW0ge0F3YXJlbmVzc30gYXdhcmVuZXNzXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICogQHBhcmFtIHthbnl9IG9yaWdpbiBUaGlzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGVtaXR0ZWQgY2hhbmdlIGV2ZW50XG4gKi9cbmV4cG9ydCBjb25zdCBhcHBseUF3YXJlbmVzc1VwZGF0ZSA9IChhd2FyZW5lc3MsIHVwZGF0ZSwgb3JpZ2luKSA9PiB7XG4gIGNvbnN0IGRlY29kZXIgPSBkZWNvZGluZy5jcmVhdGVEZWNvZGVyKHVwZGF0ZSlcbiAgY29uc3QgdGltZXN0YW1wID0gdGltZS5nZXRVbml4VGltZSgpXG4gIGNvbnN0IGFkZGVkID0gW11cbiAgY29uc3QgdXBkYXRlZCA9IFtdXG4gIGNvbnN0IGZpbHRlcmVkVXBkYXRlZCA9IFtdXG4gIGNvbnN0IHJlbW92ZWQgPSBbXVxuICBjb25zdCBsZW4gPSBkZWNvZGluZy5yZWFkVmFyVWludChkZWNvZGVyKVxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgY29uc3QgY2xpZW50SUQgPSBkZWNvZGluZy5yZWFkVmFyVWludChkZWNvZGVyKVxuICAgIGxldCBjbG9jayA9IGRlY29kaW5nLnJlYWRWYXJVaW50KGRlY29kZXIpXG4gICAgY29uc3Qgc3RhdGUgPSBKU09OLnBhcnNlKGRlY29kaW5nLnJlYWRWYXJTdHJpbmcoZGVjb2RlcikpXG4gICAgY29uc3QgY2xpZW50TWV0YSA9IGF3YXJlbmVzcy5tZXRhLmdldChjbGllbnRJRClcbiAgICBjb25zdCBwcmV2U3RhdGUgPSBhd2FyZW5lc3Muc3RhdGVzLmdldChjbGllbnRJRClcbiAgICBjb25zdCBjdXJyQ2xvY2sgPSBjbGllbnRNZXRhID09PSB1bmRlZmluZWQgPyAwIDogY2xpZW50TWV0YS5jbG9ja1xuICAgIGlmIChjdXJyQ2xvY2sgPCBjbG9jayB8fCAoY3VyckNsb2NrID09PSBjbG9jayAmJiBzdGF0ZSA9PT0gbnVsbCAmJiBhd2FyZW5lc3Muc3RhdGVzLmhhcyhjbGllbnRJRCkpKSB7XG4gICAgICBpZiAoc3RhdGUgPT09IG51bGwpIHtcbiAgICAgICAgLy8gbmV2ZXIgbGV0IGEgcmVtb3RlIGNsaWVudCByZW1vdmUgdGhpcyBsb2NhbCBzdGF0ZVxuICAgICAgICBpZiAoY2xpZW50SUQgPT09IGF3YXJlbmVzcy5jbGllbnRJRCAmJiBhd2FyZW5lc3MuZ2V0TG9jYWxTdGF0ZSgpICE9IG51bGwpIHtcbiAgICAgICAgICAvLyByZW1vdGUgY2xpZW50IHJlbW92ZWQgdGhlIGxvY2FsIHN0YXRlLiBEbyBub3QgcmVtb3RlIHN0YXRlLiBCcm9hZGNhc3QgYSBtZXNzYWdlIGluZGljYXRpbmdcbiAgICAgICAgICAvLyB0aGF0IHRoaXMgY2xpZW50IHN0aWxsIGV4aXN0cyBieSBpbmNyZWFzaW5nIHRoZSBjbG9ja1xuICAgICAgICAgIGNsb2NrKytcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FyZW5lc3Muc3RhdGVzLmRlbGV0ZShjbGllbnRJRClcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhcmVuZXNzLnN0YXRlcy5zZXQoY2xpZW50SUQsIHN0YXRlKVxuICAgICAgfVxuICAgICAgYXdhcmVuZXNzLm1ldGEuc2V0KGNsaWVudElELCB7XG4gICAgICAgIGNsb2NrLFxuICAgICAgICBsYXN0VXBkYXRlZDogdGltZXN0YW1wXG4gICAgICB9KVxuICAgICAgaWYgKGNsaWVudE1ldGEgPT09IHVuZGVmaW5lZCAmJiBzdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICBhZGRlZC5wdXNoKGNsaWVudElEKVxuICAgICAgfSBlbHNlIGlmIChjbGllbnRNZXRhICE9PSB1bmRlZmluZWQgJiYgc3RhdGUgPT09IG51bGwpIHtcbiAgICAgICAgcmVtb3ZlZC5wdXNoKGNsaWVudElEKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoIWYuZXF1YWxpdHlEZWVwKHN0YXRlLCBwcmV2U3RhdGUpKSB7XG4gICAgICAgICAgZmlsdGVyZWRVcGRhdGVkLnB1c2goY2xpZW50SUQpXG4gICAgICAgIH1cbiAgICAgICAgdXBkYXRlZC5wdXNoKGNsaWVudElEKVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoYWRkZWQubGVuZ3RoID4gMCB8fCBmaWx0ZXJlZFVwZGF0ZWQubGVuZ3RoID4gMCB8fCByZW1vdmVkLmxlbmd0aCA+IDApIHtcbiAgICBhd2FyZW5lc3MuZW1pdCgnY2hhbmdlJywgW3tcbiAgICAgIGFkZGVkLCB1cGRhdGVkOiBmaWx0ZXJlZFVwZGF0ZWQsIHJlbW92ZWRcbiAgICB9LCBvcmlnaW5dKVxuICB9XG4gIGlmIChhZGRlZC5sZW5ndGggPiAwIHx8IHVwZGF0ZWQubGVuZ3RoID4gMCB8fCByZW1vdmVkLmxlbmd0aCA+IDApIHtcbiAgICBhd2FyZW5lc3MuZW1pdCgndXBkYXRlJywgW3tcbiAgICAgIGFkZGVkLCB1cGRhdGVkLCByZW1vdmVkXG4gICAgfSwgb3JpZ2luXSlcbiAgfVxufVxuIiwgIi8qKlxuICogTXV0dWFsIGV4Y2x1ZGUgZm9yIEphdmFTY3JpcHQuXG4gKlxuICogQG1vZHVsZSBtdXRleFxuICovXG5cbi8qKlxuICogQGNhbGxiYWNrIG11dGV4XG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCk6dm9pZH0gY2IgT25seSBleGVjdXRlZCB3aGVuIHRoaXMgbXV0ZXggaXMgbm90IGluIHRoZSBjdXJyZW50IHN0YWNrXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCk6dm9pZH0gW2Vsc2VDYl0gRXhlY3V0ZWQgd2hlbiB0aGlzIG11dGV4IGlzIGluIHRoZSBjdXJyZW50IHN0YWNrXG4gKi9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbXV0dWFsIGV4Y2x1ZGUgZnVuY3Rpb24gd2l0aCB0aGUgZm9sbG93aW5nIHByb3BlcnR5OlxuICpcbiAqIGBgYGpzXG4gKiBjb25zdCBtdXRleCA9IGNyZWF0ZU11dGV4KClcbiAqIG11dGV4KCgpID0+IHtcbiAqICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBpbW1lZGlhdGVseSBleGVjdXRlZFxuICogICBtdXRleCgoKSA9PiB7XG4gKiAgICAgLy8gVGhpcyBmdW5jdGlvbiBpcyBub3QgZXhlY3V0ZWQsIGFzIHRoZSBtdXRleCBpcyBhbHJlYWR5IGFjdGl2ZS5cbiAqICAgfSlcbiAqIH0pXG4gKiBgYGBcbiAqXG4gKiBAcmV0dXJuIHttdXRleH0gQSBtdXR1YWwgZXhjbHVkZSBmdW5jdGlvblxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgY3JlYXRlTXV0ZXggPSAoKSA9PiB7XG4gIGxldCB0b2tlbiA9IHRydWVcbiAgcmV0dXJuIChmLCBnKSA9PiB7XG4gICAgaWYgKHRva2VuKSB7XG4gICAgICB0b2tlbiA9IGZhbHNlXG4gICAgICB0cnkge1xuICAgICAgICBmKClcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRva2VuID0gdHJ1ZVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBnKClcbiAgICB9XG4gIH1cbn1cbiIsICIvKipcbiAqIEVmZmljaWVudCBkaWZmcy5cbiAqXG4gKiBAbW9kdWxlIGRpZmZcbiAqL1xuXG5pbXBvcnQgeyBlcXVhbGl0eVN0cmljdCB9IGZyb20gJy4vZnVuY3Rpb24uanMnXG5cbi8qKlxuICogQSBTaW1wbGVEaWZmIGRlc2NyaWJlcyBhIGNoYW5nZSBvbiBhIFN0cmluZy5cbiAqXG4gKiBgYGBqc1xuICogY29uc29sZS5sb2coYSkgLy8gdGhlIG9sZCB2YWx1ZVxuICogY29uc29sZS5sb2coYikgLy8gdGhlIHVwZGF0ZWQgdmFsdWVcbiAqIC8vIEFwcGx5IGNoYW5nZXMgb2YgZGlmZiAocHNldWRvY29kZSlcbiAqIGEucmVtb3ZlKGRpZmYuaW5kZXgsIGRpZmYucmVtb3ZlKSAvLyBSZW1vdmUgYGRpZmYucmVtb3ZlYCBjaGFyYWN0ZXJzXG4gKiBhLmluc2VydChkaWZmLmluZGV4LCBkaWZmLmluc2VydCkgLy8gSW5zZXJ0IGBkaWZmLmluc2VydGBcbiAqIGEgPT09IGIgLy8gdmFsdWVzIG1hdGNoXG4gKiBgYGBcbiAqXG4gKiBAdGVtcGxhdGUge3N0cmluZ3xBcnJheTxhbnk+fSBUXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBTaW1wbGVEaWZmXG4gKiBAcHJvcGVydHkge051bWJlcn0gaW5kZXggVGhlIGluZGV4IHdoZXJlIGNoYW5nZXMgd2VyZSBhcHBsaWVkXG4gKiBAcHJvcGVydHkge051bWJlcn0gcmVtb3ZlIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBkZWxldGUgc3RhcnRpbmdcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0IGBpbmRleGAuXG4gKiBAcHJvcGVydHkge1R9IGluc2VydCBUaGUgbmV3IHRleHQgdG8gaW5zZXJ0IGF0IGBpbmRleGAgYWZ0ZXIgYXBwbHlpbmdcbiAqL1xuXG5jb25zdCBoaWdoU3Vycm9nYXRlUmVnZXggPSAvW1xcdUQ4MDAtXFx1REJGRl0vXG5jb25zdCBsb3dTdXJyb2dhdGVSZWdleCA9IC9bXFx1REMwMC1cXHVERkZGXS9cblxuLyoqXG4gKiBDcmVhdGUgYSBkaWZmIGJldHdlZW4gdHdvIHN0cmluZ3MuIFRoaXMgZGlmZiBpbXBsZW1lbnRhdGlvbiBpcyBoaWdobHlcbiAqIGVmZmljaWVudCwgYnV0IG5vdCB2ZXJ5IHNvcGhpc3RpY2F0ZWQuXG4gKlxuICogQGZ1bmN0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGEgVGhlIG9sZCB2ZXJzaW9uIG9mIHRoZSBzdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBiIFRoZSB1cGRhdGVkIHZlcnNpb24gb2YgdGhlIHN0cmluZ1xuICogQHJldHVybiB7U2ltcGxlRGlmZjxzdHJpbmc+fSBUaGUgZGlmZiBkZXNjcmlwdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IHNpbXBsZURpZmZTdHJpbmcgPSAoYSwgYikgPT4ge1xuICBsZXQgbGVmdCA9IDAgLy8gbnVtYmVyIG9mIHNhbWUgY2hhcmFjdGVycyBjb3VudGluZyBmcm9tIGxlZnRcbiAgbGV0IHJpZ2h0ID0gMCAvLyBudW1iZXIgb2Ygc2FtZSBjaGFyYWN0ZXJzIGNvdW50aW5nIGZyb20gcmlnaHRcbiAgd2hpbGUgKGxlZnQgPCBhLmxlbmd0aCAmJiBsZWZ0IDwgYi5sZW5ndGggJiYgYVtsZWZ0XSA9PT0gYltsZWZ0XSkge1xuICAgIGxlZnQrK1xuICB9XG4gIC8vIElmIHRoZSBsYXN0IHNhbWUgY2hhcmFjdGVyIGlzIGEgaGlnaCBzdXJyb2dhdGUsIHdlIG5lZWQgdG8gcm9sbGJhY2sgdG8gdGhlIHByZXZpb3VzIGNoYXJhY3RlclxuICBpZiAobGVmdCA+IDAgJiYgaGlnaFN1cnJvZ2F0ZVJlZ2V4LnRlc3QoYVtsZWZ0IC0gMV0pKSBsZWZ0LS1cbiAgd2hpbGUgKHJpZ2h0ICsgbGVmdCA8IGEubGVuZ3RoICYmIHJpZ2h0ICsgbGVmdCA8IGIubGVuZ3RoICYmIGFbYS5sZW5ndGggLSByaWdodCAtIDFdID09PSBiW2IubGVuZ3RoIC0gcmlnaHQgLSAxXSkge1xuICAgIHJpZ2h0KytcbiAgfVxuICAvLyBJZiB0aGUgbGFzdCBzYW1lIGNoYXJhY3RlciBpcyBhIGxvdyBzdXJyb2dhdGUsIHdlIG5lZWQgdG8gcm9sbGJhY2sgdG8gdGhlIHByZXZpb3VzIGNoYXJhY3RlclxuICBpZiAocmlnaHQgPiAwICYmIGxvd1N1cnJvZ2F0ZVJlZ2V4LnRlc3QoYVthLmxlbmd0aCAtIHJpZ2h0XSkpIHJpZ2h0LS1cbiAgcmV0dXJuIHtcbiAgICBpbmRleDogbGVmdCxcbiAgICByZW1vdmU6IGEubGVuZ3RoIC0gbGVmdCAtIHJpZ2h0LFxuICAgIGluc2VydDogYi5zbGljZShsZWZ0LCBiLmxlbmd0aCAtIHJpZ2h0KVxuICB9XG59XG5cbi8qKlxuICogQHRvZG8gUmVtb3ZlIGluIGZhdm9yIG9mIHNpbXBsZURpZmZTdHJpbmdcbiAqIEBkZXByZWNhdGVkXG4gKi9cbmV4cG9ydCBjb25zdCBzaW1wbGVEaWZmID0gc2ltcGxlRGlmZlN0cmluZ1xuXG4vKipcbiAqIENyZWF0ZSBhIGRpZmYgYmV0d2VlbiB0d28gYXJyYXlzLiBUaGlzIGRpZmYgaW1wbGVtZW50YXRpb24gaXMgaGlnaGx5XG4gKiBlZmZpY2llbnQsIGJ1dCBub3QgdmVyeSBzb3BoaXN0aWNhdGVkLlxuICpcbiAqIE5vdGU6IFRoaXMgaXMgYmFzaWNhbGx5IHRoZSBzYW1lIGZ1bmN0aW9uIGFzIGFib3ZlLiBBbm90aGVyIGZ1bmN0aW9uIHdhcyBjcmVhdGVkIHNvIHRoYXQgdGhlIHJ1bnRpbWVcbiAqIGNhbiBiZXR0ZXIgb3B0aW1pemUgdGhlc2UgZnVuY3Rpb24gY2FsbHMuXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAdGVtcGxhdGUgVFxuICpcbiAqIEBwYXJhbSB7QXJyYXk8VD59IGEgVGhlIG9sZCB2ZXJzaW9uIG9mIHRoZSBhcnJheVxuICogQHBhcmFtIHtBcnJheTxUPn0gYiBUaGUgdXBkYXRlZCB2ZXJzaW9uIG9mIHRoZSBhcnJheVxuICogQHBhcmFtIHtmdW5jdGlvbihULCBUKTpib29sZWFufSBbY29tcGFyZV1cbiAqIEByZXR1cm4ge1NpbXBsZURpZmY8QXJyYXk8VD4+fSBUaGUgZGlmZiBkZXNjcmlwdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IHNpbXBsZURpZmZBcnJheSA9IChhLCBiLCBjb21wYXJlID0gZXF1YWxpdHlTdHJpY3QpID0+IHtcbiAgbGV0IGxlZnQgPSAwIC8vIG51bWJlciBvZiBzYW1lIGNoYXJhY3RlcnMgY291bnRpbmcgZnJvbSBsZWZ0XG4gIGxldCByaWdodCA9IDAgLy8gbnVtYmVyIG9mIHNhbWUgY2hhcmFjdGVycyBjb3VudGluZyBmcm9tIHJpZ2h0XG4gIHdoaWxlIChsZWZ0IDwgYS5sZW5ndGggJiYgbGVmdCA8IGIubGVuZ3RoICYmIGNvbXBhcmUoYVtsZWZ0XSwgYltsZWZ0XSkpIHtcbiAgICBsZWZ0KytcbiAgfVxuICB3aGlsZSAocmlnaHQgKyBsZWZ0IDwgYS5sZW5ndGggJiYgcmlnaHQgKyBsZWZ0IDwgYi5sZW5ndGggJiYgY29tcGFyZShhW2EubGVuZ3RoIC0gcmlnaHQgLSAxXSwgYltiLmxlbmd0aCAtIHJpZ2h0IC0gMV0pKSB7XG4gICAgcmlnaHQrK1xuICB9XG4gIHJldHVybiB7XG4gICAgaW5kZXg6IGxlZnQsXG4gICAgcmVtb3ZlOiBhLmxlbmd0aCAtIGxlZnQgLSByaWdodCxcbiAgICBpbnNlcnQ6IGIuc2xpY2UobGVmdCwgYi5sZW5ndGggLSByaWdodClcbiAgfVxufVxuXG4vKipcbiAqIERpZmYgdGV4dCBhbmQgdHJ5IHRvIGRpZmYgYXQgdGhlIGN1cnJlbnQgY3Vyc29yIHBvc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhXG4gKiBAcGFyYW0ge3N0cmluZ30gYlxuICogQHBhcmFtIHtudW1iZXJ9IGN1cnNvciBUaGlzIHNob3VsZCByZWZlciB0byB0aGUgY3VycmVudCBsZWZ0IGN1cnNvci1yYW5nZSBwb3NpdGlvblxuICovXG5leHBvcnQgY29uc3Qgc2ltcGxlRGlmZlN0cmluZ1dpdGhDdXJzb3IgPSAoYSwgYiwgY3Vyc29yKSA9PiB7XG4gIGxldCBsZWZ0ID0gMCAvLyBudW1iZXIgb2Ygc2FtZSBjaGFyYWN0ZXJzIGNvdW50aW5nIGZyb20gbGVmdFxuICBsZXQgcmlnaHQgPSAwIC8vIG51bWJlciBvZiBzYW1lIGNoYXJhY3RlcnMgY291bnRpbmcgZnJvbSByaWdodFxuICAvLyBJdGVyYXRlIGxlZnQgdG8gdGhlIHJpZ2h0IHVudGlsIHdlIGZpbmQgYSBjaGFuZ2VkIGNoYXJhY3RlclxuICAvLyBGaXJzdCBpdGVyYXRpb24gY29uc2lkZXJzIHRoZSBjdXJyZW50IGN1cnNvciBwb3NpdGlvblxuICB3aGlsZSAoXG4gICAgbGVmdCA8IGEubGVuZ3RoICYmXG4gICAgbGVmdCA8IGIubGVuZ3RoICYmXG4gICAgYVtsZWZ0XSA9PT0gYltsZWZ0XSAmJlxuICAgIGxlZnQgPCBjdXJzb3JcbiAgKSB7XG4gICAgbGVmdCsrXG4gIH1cbiAgLy8gSWYgdGhlIGxhc3Qgc2FtZSBjaGFyYWN0ZXIgaXMgYSBoaWdoIHN1cnJvZ2F0ZSwgd2UgbmVlZCB0byByb2xsYmFjayB0byB0aGUgcHJldmlvdXMgY2hhcmFjdGVyXG4gIGlmIChsZWZ0ID4gMCAmJiBoaWdoU3Vycm9nYXRlUmVnZXgudGVzdChhW2xlZnQgLSAxXSkpIGxlZnQtLVxuICAvLyBJdGVyYXRlIHJpZ2h0IHRvIHRoZSBsZWZ0IHVudGlsIHdlIGZpbmQgYSBjaGFuZ2VkIGNoYXJhY3RlclxuICB3aGlsZSAoXG4gICAgcmlnaHQgKyBsZWZ0IDwgYS5sZW5ndGggJiZcbiAgICByaWdodCArIGxlZnQgPCBiLmxlbmd0aCAmJlxuICAgIGFbYS5sZW5ndGggLSByaWdodCAtIDFdID09PSBiW2IubGVuZ3RoIC0gcmlnaHQgLSAxXVxuICApIHtcbiAgICByaWdodCsrXG4gIH1cbiAgLy8gSWYgdGhlIGxhc3Qgc2FtZSBjaGFyYWN0ZXIgaXMgYSBsb3cgc3Vycm9nYXRlLCB3ZSBuZWVkIHRvIHJvbGxiYWNrIHRvIHRoZSBwcmV2aW91cyBjaGFyYWN0ZXJcbiAgaWYgKHJpZ2h0ID4gMCAmJiBsb3dTdXJyb2dhdGVSZWdleC50ZXN0KGFbYS5sZW5ndGggLSByaWdodF0pKSByaWdodC0tXG4gIC8vIFRyeSB0byBpdGVyYXRlIGxlZnQgZnVydGhlciB0byB0aGUgcmlnaHQgd2l0aG91dCBjYXJpbmcgYWJvdXQgdGhlIGN1cnJlbnQgY3Vyc29yIHBvc2l0aW9uXG4gIHdoaWxlIChcbiAgICByaWdodCArIGxlZnQgPCBhLmxlbmd0aCAmJlxuICAgIHJpZ2h0ICsgbGVmdCA8IGIubGVuZ3RoICYmXG4gICAgYVtsZWZ0XSA9PT0gYltsZWZ0XVxuICApIHtcbiAgICBsZWZ0KytcbiAgfVxuICBpZiAobGVmdCA+IDAgJiYgaGlnaFN1cnJvZ2F0ZVJlZ2V4LnRlc3QoYVtsZWZ0IC0gMV0pKSBsZWZ0LS1cbiAgcmV0dXJuIHtcbiAgICBpbmRleDogbGVmdCxcbiAgICByZW1vdmU6IGEubGVuZ3RoIC0gbGVmdCAtIHJpZ2h0LFxuICAgIGluc2VydDogYi5zbGljZShsZWZ0LCBiLmxlbmd0aCAtIHJpZ2h0KVxuICB9XG59XG4iLCAiLyoqXG4gKiBAbW9kdWxlIHNoYTI1NlxuICogU3BlYzogaHR0cHM6Ly9udmxwdWJzLm5pc3QuZ292L25pc3RwdWJzL0ZJUFMvTklTVC5GSVBTLjE4MC00LnBkZlxuICogUmVzb3VyY2VzOlxuICogLSBodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxNTAzMTUwNjE4MDcvaHR0cDovL2NzcmMubmlzdC5nb3YvZ3JvdXBzL1NUTS9jYXZwL2RvY3VtZW50cy9zaHMvc2hhMjU2LTM4NC01MTIucGRmXG4gKi9cblxuaW1wb3J0ICogYXMgYmluYXJ5IGZyb20gJy4uL2JpbmFyeS5qcydcblxuLyoqXG4gKiBAcGFyYW0ge251bWJlcn0gdyAtIGEgMzJiaXQgdWludFxuICogQHBhcmFtIHtudW1iZXJ9IHNoaWZ0XG4gKi9cbmNvbnN0IHJvdHIgPSAodywgc2hpZnQpID0+ICh3ID4+PiBzaGlmdCkgfCAodyA8PCAoMzIgLSBzaGlmdCkpXG5cbi8qKlxuICogSGVscGVyIGZvciBTSEEtMjI0ICYgU0hBLTI1Ni4gU2VlIDQuMS4yLlxuICogQHBhcmFtIHtudW1iZXJ9IHhcbiAqL1xuY29uc3Qgc3VtMHRvMjU2ID0geCA9PiByb3RyKHgsIDIpIF4gcm90cih4LCAxMykgXiByb3RyKHgsIDIyKVxuXG4vKipcbiAqIEhlbHBlciBmb3IgU0hBLTIyNCAmIFNIQS0yNTYuIFNlZSA0LjEuMi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4XG4gKi9cbmNvbnN0IHN1bTF0bzI1NiA9IHggPT4gcm90cih4LCA2KSBeIHJvdHIoeCwgMTEpIF4gcm90cih4LCAyNSlcblxuLyoqXG4gKiBIZWxwZXIgZm9yIFNIQS0yMjQgJiBTSEEtMjU2LiBTZWUgNC4xLjIuXG4gKiBAcGFyYW0ge251bWJlcn0geFxuICovXG5jb25zdCBzaWdtYTB0bzI1NiA9IHggPT4gcm90cih4LCA3KSBeIHJvdHIoeCwgMTgpIF4geCA+Pj4gM1xuXG4vKipcbiAqIEhlbHBlciBmb3IgU0hBLTIyNCAmIFNIQS0yNTYuIFNlZSA0LjEuMi5cbiAqIEBwYXJhbSB7bnVtYmVyfSB4XG4gKi9cbmNvbnN0IHNpZ21hMXRvMjU2ID0geCA9PiByb3RyKHgsIDE3KSBeIHJvdHIoeCwgMTkpIF4geCA+Pj4gMTBcblxuLy8gQHRvZG8gZG9uJ3QgaW5pdCB0aGVzZSB2YXJpYWJsZXMgZ2xvYmFsbHlcblxuLyoqXG4gKiBTZWUgNC4yLjI6IENvbnN0YW50IGZvciBzaGEyNTYgJiBzaGEyMjRcbiAqIFRoZXNlIHdvcmRzIHJlcHJlc2VudCB0aGUgZmlyc3QgdGhpcnR5LXR3byBiaXRzIG9mIHRoZSBmcmFjdGlvbmFsIHBhcnRzIG9mXG4gKiB0aGUgY3ViZSByb290cyBvZiB0aGUgZmlyc3Qgc2l4dHktZm91ciBwcmltZSBudW1iZXJzLiBJbiBoZXgsIHRoZXNlIGNvbnN0YW50IHdvcmRzIGFyZSAoZnJvbSBsZWZ0IHRvXG4gKiByaWdodClcbiAqL1xuY29uc3QgSyA9IG5ldyBVaW50MzJBcnJheShbXG4gIDB4NDI4YTJmOTgsIDB4NzEzNzQ0OTEsIDB4YjVjMGZiY2YsIDB4ZTliNWRiYTUsIDB4Mzk1NmMyNWIsIDB4NTlmMTExZjEsIDB4OTIzZjgyYTQsIDB4YWIxYzVlZDUsXG4gIDB4ZDgwN2FhOTgsIDB4MTI4MzViMDEsIDB4MjQzMTg1YmUsIDB4NTUwYzdkYzMsIDB4NzJiZTVkNzQsIDB4ODBkZWIxZmUsIDB4OWJkYzA2YTcsIDB4YzE5YmYxNzQsXG4gIDB4ZTQ5YjY5YzEsIDB4ZWZiZTQ3ODYsIDB4MGZjMTlkYzYsIDB4MjQwY2ExY2MsIDB4MmRlOTJjNmYsIDB4NGE3NDg0YWEsIDB4NWNiMGE5ZGMsIDB4NzZmOTg4ZGEsXG4gIDB4OTgzZTUxNTIsIDB4YTgzMWM2NmQsIDB4YjAwMzI3YzgsIDB4YmY1OTdmYzcsIDB4YzZlMDBiZjMsIDB4ZDVhNzkxNDcsIDB4MDZjYTYzNTEsIDB4MTQyOTI5NjcsXG4gIDB4MjdiNzBhODUsIDB4MmUxYjIxMzgsIDB4NGQyYzZkZmMsIDB4NTMzODBkMTMsIDB4NjUwYTczNTQsIDB4NzY2YTBhYmIsIDB4ODFjMmM5MmUsIDB4OTI3MjJjODUsXG4gIDB4YTJiZmU4YTEsIDB4YTgxYTY2NGIsIDB4YzI0YjhiNzAsIDB4Yzc2YzUxYTMsIDB4ZDE5MmU4MTksIDB4ZDY5OTA2MjQsIDB4ZjQwZTM1ODUsIDB4MTA2YWEwNzAsXG4gIDB4MTlhNGMxMTYsIDB4MWUzNzZjMDgsIDB4Mjc0ODc3NGMsIDB4MzRiMGJjYjUsIDB4MzkxYzBjYjMsIDB4NGVkOGFhNGEsIDB4NWI5Y2NhNGYsIDB4NjgyZTZmZjMsXG4gIDB4NzQ4ZjgyZWUsIDB4NzhhNTYzNmYsIDB4ODRjODc4MTQsIDB4OGNjNzAyMDgsIDB4OTBiZWZmZmEsIDB4YTQ1MDZjZWIsIDB4YmVmOWEzZjcsIDB4YzY3MTc4ZjJcbl0pXG5cbi8qKlxuICogU2VlIDUuMy4zLiBJbml0aWFsIGhhc2ggdmFsdWUuXG4gKlxuICogVGhlc2Ugd29yZHMgd2VyZSBvYnRhaW5lZCBieSB0YWtpbmcgdGhlIGZpcnN0IHRoaXJ0eS10d28gYml0cyBvZiB0aGUgZnJhY3Rpb25hbCBwYXJ0cyBvZiB0aGVcbiAqIHNxdWFyZSByb290cyBvZiB0aGUgZmlyc3QgZWlnaHQgcHJpbWUgbnVtYmVycy5cbiAqXG4gKiBAdG9kbyBzaG91bGRuJ3QgYmUgYSBnbG9iYWwgdmFyaWFibGVcbiAqL1xuY29uc3QgSElOSVQgPSBuZXcgVWludDMyQXJyYXkoW1xuICAweDZhMDllNjY3LCAweGJiNjdhZTg1LCAweDNjNmVmMzcyLCAweGE1NGZmNTNhLCAweDUxMGU1MjdmLCAweDliMDU2ODhjLCAweDFmODNkOWFiLCAweDViZTBjZDE5XG5dKVxuXG4vLyB0aW1lIHRvIGJlYXQ6IChsYXJnZSB2YWx1ZSA8IDQuMzVzKVxuXG5jbGFzcyBIYXNoZXIge1xuICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgY29uc3QgYnVmID0gbmV3IEFycmF5QnVmZmVyKDY0ICsgNjQgKiA0KVxuICAgIC8vIEluaXQgd29ya2luZyB2YXJpYWJsZXMgdXNpbmcgYSBzaW5nbGUgYXJyYXlidWZmZXJcbiAgICB0aGlzLl9IID0gbmV3IFVpbnQzMkFycmF5KGJ1ZiwgMCwgOClcbiAgICB0aGlzLl9ILnNldChISU5JVClcbiAgICAvLyBcIk1lc3NhZ2Ugc2NoZWR1bGVcIiAtIGEgd29ya2luZyB2YXJpYWJsZVxuICAgIHRoaXMuX1cgPSBuZXcgVWludDMyQXJyYXkoYnVmLCA2NCwgNjQpXG4gIH1cblxuICBfdXBkYXRlSGFzaCAoKSB7XG4gICAgY29uc3QgSCA9IHRoaXMuX0hcbiAgICBjb25zdCBXID0gdGhpcy5fV1xuICAgIGZvciAobGV0IHQgPSAxNjsgdCA8IDY0OyB0KyspIHtcbiAgICAgIFdbdF0gPSBzaWdtYTF0bzI1NihXW3QgLSAyXSkgKyBXW3QgLSA3XSArIHNpZ21hMHRvMjU2KFdbdCAtIDE1XSkgKyBXW3QgLSAxNl1cbiAgICB9XG4gICAgbGV0IGEgPSBIWzBdXG4gICAgbGV0IGIgPSBIWzFdXG4gICAgbGV0IGMgPSBIWzJdXG4gICAgbGV0IGQgPSBIWzNdXG4gICAgbGV0IGUgPSBIWzRdXG4gICAgbGV0IGYgPSBIWzVdXG4gICAgbGV0IGcgPSBIWzZdXG4gICAgbGV0IGggPSBIWzddXG4gICAgZm9yIChsZXQgdHQgPSAwLCBUMSwgVDI7IHR0IDwgNjQ7IHR0KyspIHtcbiAgICAgIFQxID0gKGggKyBzdW0xdG8yNTYoZSkgKyAoKGUgJiBmKSBeICh+ZSAmIGcpKSArIEtbdHRdICsgV1t0dF0pID4+PiAwXG4gICAgICBUMiA9IChzdW0wdG8yNTYoYSkgKyAoKGEgJiBiKSBeIChhICYgYykgXiAoYiAmIGMpKSkgPj4+IDBcbiAgICAgIGggPSBnXG4gICAgICBnID0gZlxuICAgICAgZiA9IGVcbiAgICAgIGUgPSAoZCArIFQxKSA+Pj4gMFxuICAgICAgZCA9IGNcbiAgICAgIGMgPSBiXG4gICAgICBiID0gYVxuICAgICAgYSA9IChUMSArIFQyKSA+Pj4gMFxuICAgIH1cbiAgICBIWzBdICs9IGFcbiAgICBIWzFdICs9IGJcbiAgICBIWzJdICs9IGNcbiAgICBIWzNdICs9IGRcbiAgICBIWzRdICs9IGVcbiAgICBIWzVdICs9IGZcbiAgICBIWzZdICs9IGdcbiAgICBIWzddICs9IGhcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgMzItYnl0ZSBoYXNoLlxuICAgKlxuICAgKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGRhdGFcbiAgICovXG4gIGRpZ2VzdCAoZGF0YSkge1xuICAgIGxldCBpID0gMFxuICAgIGZvciAoOyBpICsgNTYgPD0gZGF0YS5sZW5ndGg7KSB7XG4gICAgICAvLyB3cml0ZSBkYXRhIGluIGJpZyBlbmRpYW5lc3NcbiAgICAgIGxldCBqID0gMFxuICAgICAgZm9yICg7IGogPCAxNiAmJiBpICsgMyA8IGRhdGEubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgdGhpcy5fV1tqXSA9IGRhdGFbaSsrXSA8PCAyNCB8IGRhdGFbaSsrXSA8PCAxNiB8IGRhdGFbaSsrXSA8PCA4IHwgZGF0YVtpKytdXG4gICAgICB9XG4gICAgICBpZiAoaSAlIDY0ICE9PSAwKSB7IC8vIHRoZXJlIGlzIHN0aWxsIHJvb20gdG8gd3JpdGUgcGFydGlhbCBjb250ZW50IGFuZCB0aGUgZW5kaW5nIGJpdC5cbiAgICAgICAgdGhpcy5fVy5maWxsKDAsIGosIDE2KVxuICAgICAgICB3aGlsZSAoaSA8IGRhdGEubGVuZ3RoKSB7XG4gICAgICAgICAgdGhpcy5fV1tqXSB8PSBkYXRhW2ldIDw8ICgoMyAtIChpICUgNCkpICogOClcbiAgICAgICAgICBpKytcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9XW2pdIHw9IGJpbmFyeS5CSVQ4IDw8ICgoMyAtIChpICUgNCkpICogOClcbiAgICAgIH1cbiAgICAgIHRoaXMuX3VwZGF0ZUhhc2goKVxuICAgIH1cbiAgICAvLyBzYW1lIGNoZWNrIGFzIGVhcmxpZXIgLSB0aGUgZW5kaW5nIGJpdCBoYXMgYmVlbiB3cml0dGVuXG4gICAgY29uc3QgaXNQYWRkZWRXaXRoMSA9IGkgJSA2NCAhPT0gMFxuICAgIHRoaXMuX1cuZmlsbCgwLCAwLCAxNilcbiAgICBsZXQgaiA9IDBcbiAgICBmb3IgKDsgaSA8IGRhdGEubGVuZ3RoOyBqKyspIHtcbiAgICAgIGZvciAobGV0IGNpID0gMzsgY2kgPj0gMCAmJiBpIDwgZGF0YS5sZW5ndGg7IGNpLS0pIHtcbiAgICAgICAgdGhpcy5fV1tqXSB8PSBkYXRhW2krK10gPDwgKGNpICogOClcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gV3JpdGUgcGFkZGluZyBvZiB0aGUgbWVzc2FnZS4gU2VlIDUuMS4yLlxuICAgIGlmICghaXNQYWRkZWRXaXRoMSkge1xuICAgICAgdGhpcy5fV1tqIC0gKGkgJSA0ID09PSAwID8gMCA6IDEpXSB8PSBiaW5hcnkuQklUOCA8PCAoKDMgLSAoaSAlIDQpKSAqIDgpXG4gICAgfVxuICAgIC8vIHdyaXRlIGxlbmd0aCBvZiBtZXNzYWdlIChzaXplIGluIGJpdHMpIGFzIDY0IGJpdCB1aW50XG4gICAgLy8gQHRvZG8gdGVzdCB0aGF0IHRoaXMgd29ya3MgY29ycmVjdGx5XG4gICAgdGhpcy5fV1sxNF0gPSBkYXRhLmJ5dGVMZW5ndGggLyBiaW5hcnkuQklUMzAgLy8gc2FtZSBhcyBkYXRhLmJ5dGVMZW5ndGggPj4+IDMwIC0gYnV0IHdvcmtzIG9uIGZsb2F0c1xuICAgIHRoaXMuX1dbMTVdID0gZGF0YS5ieXRlTGVuZ3RoICogOFxuICAgIHRoaXMuX3VwZGF0ZUhhc2goKVxuICAgIC8vIGNvcnJlY3QgSCBlbmRpYW5uZXNzIHRvIHVzZSBiaWcgZW5kaWFubmVzIGFuZCByZXR1cm4gYSBVaW50OEFycmF5XG4gICAgY29uc3QgZHYgPSBuZXcgVWludDhBcnJheSgzMilcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX0gubGVuZ3RoOyBpKyspIHtcbiAgICAgIGZvciAobGV0IGNpID0gMDsgY2kgPCA0OyBjaSsrKSB7XG4gICAgICAgIGR2W2kgKiA0ICsgY2ldID0gdGhpcy5fSFtpXSA+Pj4gKDMgLSBjaSkgKiA4XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkdlxuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBhIDMyLWJ5dGUgaGFzaC5cbiAqXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IGRhdGFcbiAqL1xuZXhwb3J0IGNvbnN0IGRpZ2VzdCA9IGRhdGEgPT4gbmV3IEhhc2hlcigpLmRpZ2VzdChkYXRhKVxuIiwgImltcG9ydCB7IFBsdWdpbktleSB9IGZyb20gJ3Byb3NlbWlycm9yLXN0YXRlJyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cbi8qKlxuICogVGhlIHVuaXF1ZSBwcm9zZW1pcnJvciBwbHVnaW4ga2V5IGZvciBzeW5jUGx1Z2luXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgeVN5bmNQbHVnaW5LZXkgPSBuZXcgUGx1Z2luS2V5KCd5LXN5bmMnKVxuXG4vKipcbiAqIFRoZSB1bmlxdWUgcHJvc2VtaXJyb3IgcGx1Z2luIGtleSBmb3IgdW5kb1BsdWdpblxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHlVbmRvUGx1Z2luS2V5ID0gbmV3IFBsdWdpbktleSgneS11bmRvJylcblxuLyoqXG4gKiBUaGUgdW5pcXVlIHByb3NlbWlycm9yIHBsdWdpbiBrZXkgZm9yIGN1cnNvclBsdWdpblxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHlDdXJzb3JQbHVnaW5LZXkgPSBuZXcgUGx1Z2luS2V5KCd5anMtY3Vyc29yJylcbiIsICJpbXBvcnQgKiBhcyBzaGEyNTYgZnJvbSAnbGliMC9oYXNoL3NoYTI1NidcbmltcG9ydCAqIGFzIGJ1ZiBmcm9tICdsaWIwL2J1ZmZlcidcblxuLyoqXG4gKiBDdXN0b20gZnVuY3Rpb24gdG8gdHJhbnNmb3JtIHNoYTI1NiBoYXNoIHRvIE4gYnl0ZVxuICpcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gZGlnZXN0XG4gKi9cbmNvbnN0IF9jb252b2x1dGUgPSBkaWdlc3QgPT4ge1xuICBjb25zdCBOID0gNlxuICBmb3IgKGxldCBpID0gTjsgaSA8IGRpZ2VzdC5sZW5ndGg7IGkrKykge1xuICAgIGRpZ2VzdFtpICUgTl0gPSBkaWdlc3RbaSAlIE5dIF4gZGlnZXN0W2ldXG4gIH1cbiAgcmV0dXJuIGRpZ2VzdC5zbGljZSgwLCBOKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7YW55fSBqc29uXG4gKi9cbmV4cG9ydCBjb25zdCBoYXNoT2ZKU09OID0gKGpzb24pID0+IGJ1Zi50b0Jhc2U2NChfY29udm9sdXRlKHNoYTI1Ni5kaWdlc3QoYnVmLmVuY29kZUFueShqc29uKSkpKVxuIiwgIi8qKlxuICogQG1vZHVsZSBiaW5kaW5ncy9wcm9zZW1pcnJvclxuICovXG5cbmltcG9ydCB7IGNyZWF0ZU11dGV4IH0gZnJvbSAnbGliMC9tdXRleCdcbmltcG9ydCAqIGFzIFBNb2RlbCBmcm9tICdwcm9zZW1pcnJvci1tb2RlbCdcbmltcG9ydCB7IEFsbFNlbGVjdGlvbiwgUGx1Z2luLCBUZXh0U2VsZWN0aW9uLCBOb2RlU2VsZWN0aW9uIH0gZnJvbSBcInByb3NlbWlycm9yLXN0YXRlXCI7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbmltcG9ydCAqIGFzIG1hdGggZnJvbSAnbGliMC9tYXRoJ1xuaW1wb3J0ICogYXMgb2JqZWN0IGZyb20gJ2xpYjAvb2JqZWN0J1xuaW1wb3J0ICogYXMgc2V0IGZyb20gJ2xpYjAvc2V0J1xuaW1wb3J0IHsgc2ltcGxlRGlmZiB9IGZyb20gJ2xpYjAvZGlmZidcbmltcG9ydCAqIGFzIGVycm9yIGZyb20gJ2xpYjAvZXJyb3InXG5pbXBvcnQgeyB5U3luY1BsdWdpbktleSwgeVVuZG9QbHVnaW5LZXkgfSBmcm9tICcuL2tleXMuanMnXG5pbXBvcnQgKiBhcyBZIGZyb20gJ3lqcydcbmltcG9ydCB7XG4gIGFic29sdXRlUG9zaXRpb25Ub1JlbGF0aXZlUG9zaXRpb24sXG4gIHJlbGF0aXZlUG9zaXRpb25Ub0Fic29sdXRlUG9zaXRpb25cbn0gZnJvbSAnLi4vbGliLmpzJ1xuaW1wb3J0ICogYXMgcmFuZG9tIGZyb20gJ2xpYjAvcmFuZG9tJ1xuaW1wb3J0ICogYXMgZW52aXJvbm1lbnQgZnJvbSAnbGliMC9lbnZpcm9ubWVudCdcbmltcG9ydCAqIGFzIGRvbSBmcm9tICdsaWIwL2RvbSdcbmltcG9ydCAqIGFzIGV2ZW50bG9vcCBmcm9tICdsaWIwL2V2ZW50bG9vcCdcbmltcG9ydCAqIGFzIG1hcCBmcm9tICdsaWIwL21hcCdcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4uL3V0aWxzLmpzJ1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEJpbmRpbmdNZXRhZGF0YVxuICogQHByb3BlcnR5IHtQcm9zZW1pcnJvck1hcHBpbmd9IEJpbmRpbmdNZXRhZGF0YS5tYXBwaW5nXG4gKiBAcHJvcGVydHkge01hcDxpbXBvcnQoJ3Byb3NlbWlycm9yLW1vZGVsJykuTWFya1R5cGUsIGJvb2xlYW4+fSBCaW5kaW5nTWV0YWRhdGEuaXNPTWFyayAtIGlzIG92ZXJsYXBwaW5nIG1hcmtcbiAqL1xuXG4vKipcbiAqIEByZXR1cm4gQmluZGluZ01ldGFkYXRhXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVFbXB0eU1ldGEgPSAoKSA9PiAoe1xuICBtYXBwaW5nOiBuZXcgTWFwKCksXG4gIGlzT01hcms6IG5ldyBNYXAoKVxufSlcblxuLyoqXG4gKiBAcGFyYW0ge1kuSXRlbX0gaXRlbVxuICogQHBhcmFtIHtZLlNuYXBzaG90fSBbc25hcHNob3RdXG4gKi9cbmV4cG9ydCBjb25zdCBpc1Zpc2libGUgPSAoaXRlbSwgc25hcHNob3QpID0+XG4gIHNuYXBzaG90ID09PSB1bmRlZmluZWRcbiAgICA/ICFpdGVtLmRlbGV0ZWRcbiAgICA6IChzbmFwc2hvdC5zdi5oYXMoaXRlbS5pZC5jbGllbnQpICYmIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICAgICAgKHNuYXBzaG90LnN2LmdldChpdGVtLmlkLmNsaWVudCkpID4gaXRlbS5pZC5jbG9jayAmJlxuICAgICAgIVkuaXNEZWxldGVkKHNuYXBzaG90LmRzLCBpdGVtLmlkKSlcblxuLyoqXG4gKiBFaXRoZXIgYSBub2RlIGlmIHR5cGUgaXMgWVhtbEVsZW1lbnQgb3IgYW4gQXJyYXkgb2YgdGV4dCBub2RlcyBpZiBZWG1sVGV4dFxuICogQHR5cGVkZWYge01hcDxZLkFic3RyYWN0VHlwZTxhbnk+LCBQTW9kZWwuTm9kZSB8IEFycmF5PFBNb2RlbC5Ob2RlPj59IFByb3NlbWlycm9yTWFwcGluZ1xuICovXG5cbi8qKlxuICogQHR5cGVkZWYge09iamVjdH0gQ29sb3JEZWZcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBDb2xvckRlZi5saWdodFxuICogQHByb3BlcnR5IHtzdHJpbmd9IENvbG9yRGVmLmRhcmtcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFlTeW5jT3B0c1xuICogQHByb3BlcnR5IHtBcnJheTxDb2xvckRlZj59IFtZU3luY09wdHMuY29sb3JzXVxuICogQHByb3BlcnR5IHtNYXA8c3RyaW5nLENvbG9yRGVmPn0gW1lTeW5jT3B0cy5jb2xvck1hcHBpbmddXG4gKiBAcHJvcGVydHkge1kuUGVybWFuZW50VXNlckRhdGF8bnVsbH0gW1lTeW5jT3B0cy5wZXJtYW5lbnRVc2VyRGF0YV1cbiAqIEBwcm9wZXJ0eSB7UHJvc2VtaXJyb3JNYXBwaW5nfSBbWVN5bmNPcHRzLm1hcHBpbmddXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBbWVN5bmNPcHRzLm9uRmlyc3RSZW5kZXJdIEZpcmVkIHdoZW4gdGhlIGNvbnRlbnQgZnJvbSBZanMgaXMgaW5pdGlhbGx5IHJlbmRlcmVkIHRvIFByb3NlTWlycm9yXG4gKi9cblxuLyoqXG4gKiBAdHlwZSB7QXJyYXk8Q29sb3JEZWY+fVxuICovXG5jb25zdCBkZWZhdWx0Q29sb3JzID0gW3sgbGlnaHQ6ICcjZWNkNDQ0MzMnLCBkYXJrOiAnI2VjZDQ0NCcgfV1cblxuLyoqXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsQ29sb3JEZWY+fSBjb2xvck1hcHBpbmdcbiAqIEBwYXJhbSB7QXJyYXk8Q29sb3JEZWY+fSBjb2xvcnNcbiAqIEBwYXJhbSB7c3RyaW5nfSB1c2VyXG4gKiBAcmV0dXJuIHtDb2xvckRlZn1cbiAqL1xuY29uc3QgZ2V0VXNlckNvbG9yID0gKGNvbG9yTWFwcGluZywgY29sb3JzLCB1c2VyKSA9PiB7XG4gIC8vIEB0b2RvIGRvIG5vdCBoaXQgdGhlIHNhbWUgY29sb3IgdHdpY2UgaWYgcG9zc2libGVcbiAgaWYgKCFjb2xvck1hcHBpbmcuaGFzKHVzZXIpKSB7XG4gICAgaWYgKGNvbG9yTWFwcGluZy5zaXplIDwgY29sb3JzLmxlbmd0aCkge1xuICAgICAgY29uc3QgdXNlZENvbG9ycyA9IHNldC5jcmVhdGUoKVxuICAgICAgY29sb3JNYXBwaW5nLmZvckVhY2goKGNvbG9yKSA9PiB1c2VkQ29sb3JzLmFkZChjb2xvcikpXG4gICAgICBjb2xvcnMgPSBjb2xvcnMuZmlsdGVyKChjb2xvcikgPT4gIXVzZWRDb2xvcnMuaGFzKGNvbG9yKSlcbiAgICB9XG4gICAgY29sb3JNYXBwaW5nLnNldCh1c2VyLCByYW5kb20ub25lT2YoY29sb3JzKSlcbiAgfVxuICByZXR1cm4gLyoqIEB0eXBlIHtDb2xvckRlZn0gKi8gKGNvbG9yTWFwcGluZy5nZXQodXNlcikpXG59XG5cbi8qKlxuICogVGhpcyBwbHVnaW4gbGlzdGVucyB0byBjaGFuZ2VzIGluIHByb3NlbWlycm9yIHZpZXcgYW5kIGtlZXBzIHlYbWxTdGF0ZSBhbmQgdmlldyBpbiBzeW5jLlxuICpcbiAqIFRoaXMgcGx1Z2luIGFsc28ga2VlcHMgcmVmZXJlbmNlcyB0byB0aGUgdHlwZSBhbmQgdGhlIHNoYXJlZCBkb2N1bWVudCBzbyBvdGhlciBwbHVnaW5zIGNhbiBhY2Nlc3MgaXQuXG4gKiBAcGFyYW0ge1kuWG1sRnJhZ21lbnR9IHlYbWxGcmFnbWVudFxuICogQHBhcmFtIHtZU3luY09wdHN9IG9wdHNcbiAqIEByZXR1cm4ge2FueX0gUmV0dXJucyBhIHByb3NlbWlycm9yIHBsdWdpbiB0aGF0IGJpbmRzIHRvIHRoaXMgdHlwZVxuICovXG5leHBvcnQgY29uc3QgeVN5bmNQbHVnaW4gPSAoeVhtbEZyYWdtZW50LCB7XG4gIGNvbG9ycyA9IGRlZmF1bHRDb2xvcnMsXG4gIGNvbG9yTWFwcGluZyA9IG5ldyBNYXAoKSxcbiAgcGVybWFuZW50VXNlckRhdGEgPSBudWxsLFxuICBvbkZpcnN0UmVuZGVyID0gKCkgPT4ge30sXG4gIG1hcHBpbmdcbn0gPSB7fSkgPT4ge1xuICBsZXQgaW5pdGlhbENvbnRlbnRDaGFuZ2VkID0gZmFsc2VcbiAgY29uc3QgYmluZGluZyA9IG5ldyBQcm9zZW1pcnJvckJpbmRpbmcoeVhtbEZyYWdtZW50LCBtYXBwaW5nKVxuICBjb25zdCBwbHVnaW4gPSBuZXcgUGx1Z2luKHtcbiAgICBwcm9wczoge1xuICAgICAgZWRpdGFibGU6IChzdGF0ZSkgPT4ge1xuICAgICAgICBjb25zdCBzeW5jU3RhdGUgPSB5U3luY1BsdWdpbktleS5nZXRTdGF0ZShzdGF0ZSlcbiAgICAgICAgcmV0dXJuIHN5bmNTdGF0ZS5zbmFwc2hvdCA9PSBudWxsICYmIHN5bmNTdGF0ZS5wcmV2U25hcHNob3QgPT0gbnVsbFxuICAgICAgfVxuICAgIH0sXG4gICAga2V5OiB5U3luY1BsdWdpbktleSxcbiAgICBzdGF0ZToge1xuICAgICAgLyoqXG4gICAgICAgKiBAcmV0dXJucyB7YW55fVxuICAgICAgICovXG4gICAgICBpbml0OiAoX2luaXRhcmdzLCBfc3RhdGUpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlOiB5WG1sRnJhZ21lbnQsXG4gICAgICAgICAgZG9jOiB5WG1sRnJhZ21lbnQuZG9jLFxuICAgICAgICAgIGJpbmRpbmcsXG4gICAgICAgICAgc25hcHNob3Q6IG51bGwsXG4gICAgICAgICAgcHJldlNuYXBzaG90OiBudWxsLFxuICAgICAgICAgIGlzQ2hhbmdlT3JpZ2luOiBmYWxzZSxcbiAgICAgICAgICBpc1VuZG9SZWRvT3BlcmF0aW9uOiBmYWxzZSxcbiAgICAgICAgICBhZGRUb0hpc3Rvcnk6IHRydWUsXG4gICAgICAgICAgY29sb3JzLFxuICAgICAgICAgIGNvbG9yTWFwcGluZyxcbiAgICAgICAgICBwZXJtYW5lbnRVc2VyRGF0YVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgYXBwbHk6ICh0ciwgcGx1Z2luU3RhdGUpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbmdlID0gdHIuZ2V0TWV0YSh5U3luY1BsdWdpbktleSlcbiAgICAgICAgaWYgKGNoYW5nZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcGx1Z2luU3RhdGUgPSBPYmplY3QuYXNzaWduKHt9LCBwbHVnaW5TdGF0ZSlcbiAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBjaGFuZ2UpIHtcbiAgICAgICAgICAgIHBsdWdpblN0YXRlW2tleV0gPSBjaGFuZ2Vba2V5XVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBwbHVnaW5TdGF0ZS5hZGRUb0hpc3RvcnkgPSB0ci5nZXRNZXRhKCdhZGRUb0hpc3RvcnknKSAhPT0gZmFsc2VcbiAgICAgICAgLy8gYWx3YXlzIHNldCBpc0NoYW5nZU9yaWdpbi4gSWYgdW5kZWZpbmVkLCB0aGlzIGlzIG5vdCBjaGFuZ2Ugb3JpZ2luLlxuICAgICAgICBwbHVnaW5TdGF0ZS5pc0NoYW5nZU9yaWdpbiA9IGNoYW5nZSAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgISFjaGFuZ2UuaXNDaGFuZ2VPcmlnaW5cbiAgICAgICAgcGx1Z2luU3RhdGUuaXNVbmRvUmVkb09wZXJhdGlvbiA9IGNoYW5nZSAhPT0gdW5kZWZpbmVkICYmICEhY2hhbmdlLmlzQ2hhbmdlT3JpZ2luICYmICEhY2hhbmdlLmlzVW5kb1JlZG9PcGVyYXRpb25cbiAgICAgICAgaWYgKGJpbmRpbmcucHJvc2VtaXJyb3JWaWV3ICE9PSBudWxsKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgY2hhbmdlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgIChjaGFuZ2Uuc25hcHNob3QgIT0gbnVsbCB8fCBjaGFuZ2UucHJldlNuYXBzaG90ICE9IG51bGwpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBzbmFwc2hvdCBjaGFuZ2VkLCByZXJlbmRlciBuZXh0XG4gICAgICAgICAgICBldmVudGxvb3AudGltZW91dCgwLCAoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChiaW5kaW5nLnByb3NlbWlycm9yVmlldyA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGNoYW5nZS5yZXN0b3JlID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBiaW5kaW5nLl9yZW5kZXJTbmFwc2hvdChcbiAgICAgICAgICAgICAgICAgIGNoYW5nZS5zbmFwc2hvdCxcbiAgICAgICAgICAgICAgICAgIGNoYW5nZS5wcmV2U25hcHNob3QsXG4gICAgICAgICAgICAgICAgICBwbHVnaW5TdGF0ZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBiaW5kaW5nLl9yZW5kZXJTbmFwc2hvdChcbiAgICAgICAgICAgICAgICAgIGNoYW5nZS5zbmFwc2hvdCxcbiAgICAgICAgICAgICAgICAgIGNoYW5nZS5zbmFwc2hvdCxcbiAgICAgICAgICAgICAgICAgIHBsdWdpblN0YXRlXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC8vIHJlc2V0IHRvIGN1cnJlbnQgcHJvc2VtaXJyb3Igc3RhdGVcbiAgICAgICAgICAgICAgICBkZWxldGUgcGx1Z2luU3RhdGUucmVzdG9yZVxuICAgICAgICAgICAgICAgIGRlbGV0ZSBwbHVnaW5TdGF0ZS5zbmFwc2hvdFxuICAgICAgICAgICAgICAgIGRlbGV0ZSBwbHVnaW5TdGF0ZS5wcmV2U25hcHNob3RcbiAgICAgICAgICAgICAgICBiaW5kaW5nLm11eCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICBiaW5kaW5nLl9wcm9zZW1pcnJvckNoYW5nZWQoXG4gICAgICAgICAgICAgICAgICAgIGJpbmRpbmcucHJvc2VtaXJyb3JWaWV3LnN0YXRlLmRvY1xuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwbHVnaW5TdGF0ZVxuICAgICAgfVxuICAgIH0sXG4gICAgdmlldzogKHZpZXcpID0+IHtcbiAgICAgIGJpbmRpbmcuaW5pdFZpZXcodmlldylcbiAgICAgIGlmIChtYXBwaW5nID09IG51bGwpIHtcbiAgICAgICAgLy8gZm9yY2UgcmVyZW5kZXIgdG8gdXBkYXRlIHRoZSBiaW5kaW5ncyBtYXBwaW5nXG4gICAgICAgIGJpbmRpbmcuX2ZvcmNlUmVyZW5kZXIoKVxuICAgICAgfVxuICAgICAgb25GaXJzdFJlbmRlcigpXG4gICAgICByZXR1cm4ge1xuICAgICAgICB1cGRhdGU6ICgpID0+IHtcbiAgICAgICAgICBjb25zdCBwbHVnaW5TdGF0ZSA9IHBsdWdpbi5nZXRTdGF0ZSh2aWV3LnN0YXRlKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHBsdWdpblN0YXRlLnNuYXBzaG90ID09IG51bGwgJiYgcGx1Z2luU3RhdGUucHJldlNuYXBzaG90ID09IG51bGxcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgLy8gSWYgdGhlIGNvbnRlbnQgZG9lc24ndCBjaGFuZ2UgaW5pdGlhbGx5LCB3ZSBkb24ndCByZW5kZXIgYW55dGhpbmcgdG8gWWpzXG4gICAgICAgICAgICAgIC8vIElmIHRoZSBjb250ZW50IHdhcyBjbGVhcmVkIGJ5IGEgdXNlciBhY3Rpb24sIHdlIHdhbnQgdG8gY2F0Y2ggdGhlIGNoYW5nZSBhbmRcbiAgICAgICAgICAgICAgLy8gcmVwcmVzZW50IGl0IGluIFlqc1xuICAgICAgICAgICAgICBpbml0aWFsQ29udGVudENoYW5nZWQgfHxcbiAgICAgICAgICAgICAgdmlldy5zdGF0ZS5kb2MuY29udGVudC5maW5kRGlmZlN0YXJ0KFxuICAgICAgICAgICAgICAgIHZpZXcuc3RhdGUuZG9jLnR5cGUuY3JlYXRlQW5kRmlsbCgpLmNvbnRlbnRcbiAgICAgICAgICAgICAgKSAhPT0gbnVsbFxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGluaXRpYWxDb250ZW50Q2hhbmdlZCA9IHRydWVcbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHBsdWdpblN0YXRlLmFkZFRvSGlzdG9yeSA9PT0gZmFsc2UgJiZcbiAgICAgICAgICAgICAgICAhcGx1Z2luU3RhdGUuaXNDaGFuZ2VPcmlnaW5cbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeVVuZG9QbHVnaW5TdGF0ZSA9IHlVbmRvUGx1Z2luS2V5LmdldFN0YXRlKHZpZXcuc3RhdGUpXG4gICAgICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgICAgICogQHR5cGUge1kuVW5kb01hbmFnZXJ9XG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3QgdW0gPSB5VW5kb1BsdWdpblN0YXRlICYmIHlVbmRvUGx1Z2luU3RhdGUudW5kb01hbmFnZXJcbiAgICAgICAgICAgICAgICBpZiAodW0pIHtcbiAgICAgICAgICAgICAgICAgIHVtLnN0b3BDYXB0dXJpbmcoKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBiaW5kaW5nLm11eCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgLyoqIEB0eXBlIHtZLkRvY30gKi8gKHBsdWdpblN0YXRlLmRvYykudHJhbnNhY3QoKHRyKSA9PiB7XG4gICAgICAgICAgICAgICAgICB0ci5tZXRhLnNldCgnYWRkVG9IaXN0b3J5JywgcGx1Z2luU3RhdGUuYWRkVG9IaXN0b3J5KVxuICAgICAgICAgICAgICAgICAgYmluZGluZy5fcHJvc2VtaXJyb3JDaGFuZ2VkKHZpZXcuc3RhdGUuZG9jKVxuICAgICAgICAgICAgICAgIH0sIHlTeW5jUGx1Z2luS2V5KVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgIGJpbmRpbmcuZGVzdHJveSgpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pXG4gIHJldHVybiBwbHVnaW5cbn1cblxuLyoqXG4gKiBAcGFyYW0ge2ltcG9ydCgncHJvc2VtaXJyb3Itc3RhdGUnKS5UcmFuc2FjdGlvbn0gdHJcbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgZ2V0UmVsYXRpdmVTZWxlY3Rpb24+fSByZWxTZWxcbiAqIEBwYXJhbSB7UHJvc2VtaXJyb3JCaW5kaW5nfSBiaW5kaW5nXG4gKi9cbmNvbnN0IHJlc3RvcmVSZWxhdGl2ZVNlbGVjdGlvbiA9ICh0ciwgcmVsU2VsLCBiaW5kaW5nKSA9PiB7XG4gIGlmIChyZWxTZWwgIT09IG51bGwgJiYgcmVsU2VsLmFuY2hvciAhPT0gbnVsbCAmJiByZWxTZWwuaGVhZCAhPT0gbnVsbCkge1xuICAgIGlmIChyZWxTZWwudHlwZSA9PT0gJ2FsbCcpIHtcbiAgICAgIHRyLnNldFNlbGVjdGlvbihuZXcgQWxsU2VsZWN0aW9uKHRyLmRvYykpXG4gICAgfSBlbHNlIGlmIChyZWxTZWwudHlwZSA9PT0gJ25vZGUnKSB7XG4gICAgICBjb25zdCBhbmNob3IgPSByZWxhdGl2ZVBvc2l0aW9uVG9BYnNvbHV0ZVBvc2l0aW9uKFxuICAgICAgICBiaW5kaW5nLmRvYyxcbiAgICAgICAgYmluZGluZy50eXBlLFxuICAgICAgICByZWxTZWwuYW5jaG9yLFxuICAgICAgICBiaW5kaW5nLm1hcHBpbmdcbiAgICAgIClcbiAgICAgIHRyLnNldFNlbGVjdGlvbihjcmVhdGVTYWZlTm9kZVNlbGVjdGlvbih0ciwgYW5jaG9yKSlcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYW5jaG9yID0gcmVsYXRpdmVQb3NpdGlvblRvQWJzb2x1dGVQb3NpdGlvbihcbiAgICAgICAgYmluZGluZy5kb2MsXG4gICAgICAgIGJpbmRpbmcudHlwZSxcbiAgICAgICAgcmVsU2VsLmFuY2hvcixcbiAgICAgICAgYmluZGluZy5tYXBwaW5nXG4gICAgICApXG4gICAgICBjb25zdCBoZWFkID0gcmVsYXRpdmVQb3NpdGlvblRvQWJzb2x1dGVQb3NpdGlvbihcbiAgICAgICAgYmluZGluZy5kb2MsXG4gICAgICAgIGJpbmRpbmcudHlwZSxcbiAgICAgICAgcmVsU2VsLmhlYWQsXG4gICAgICAgIGJpbmRpbmcubWFwcGluZ1xuICAgICAgKVxuICAgICAgaWYgKGFuY2hvciAhPT0gbnVsbCAmJiBoZWFkICE9PSBudWxsKSB7XG4gICAgICAgIHRyLnNldFNlbGVjdGlvbihUZXh0U2VsZWN0aW9uLmJldHdlZW4odHIuZG9jLnJlc29sdmUoYW5jaG9yKSwgdHIuZG9jLnJlc29sdmUoaGVhZCkpKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7aW1wb3J0KCdwcm9zZW1pcnJvci1zdGF0ZScpLlRyYW5zYWN0aW9ufSB0clxuICogQHBhcmFtIHtudW1iZXJ9IHBvc1xuICogQHJldHVybnMge2ltcG9ydCgncHJvc2VtaXJyb3Itc3RhdGUnKS5TZWxlY3Rpb259XG4gKlxuICogQ3JlYXRlcyBhIE5vZGVTZWxlY3Rpb24gaWYgdGhlIHBvc2l0aW9uIHBvaW50cyB0byBhIHZhbGlkIG5vZGUsIG90aGVyd2lzZVxuICogY3JlYXRlcyBhIFRleHRTZWxlY3Rpb24gbmVhciB0aGUgcG9zaXRpb24uXG4gKi9cbmNvbnN0IGNyZWF0ZVNhZmVOb2RlU2VsZWN0aW9uID0gKHRyLCBwb3MpID0+IHtcbiAgY29uc3QgJHBvcyA9IHRyLmRvYy5yZXNvbHZlKHBvcylcbiAgaWYgKCRwb3Mubm9kZUFmdGVyKSB7XG4gICAgcmV0dXJuIE5vZGVTZWxlY3Rpb24uY3JlYXRlKHRyLmRvYywgcG9zKVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBUZXh0U2VsZWN0aW9uLm5lYXIoJHBvcylcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7UHJvc2VtaXJyb3JCaW5kaW5nfSBwbWJpbmRpbmdcbiAqIEBwYXJhbSB7aW1wb3J0KCdwcm9zZW1pcnJvci1zdGF0ZScpLkVkaXRvclN0YXRlfSBzdGF0ZVxuICovXG5leHBvcnQgY29uc3QgZ2V0UmVsYXRpdmVTZWxlY3Rpb24gPSAocG1iaW5kaW5nLCBzdGF0ZSkgPT4gKHtcbiAgdHlwZTogLyoqIEB0eXBlIHthbnl9ICovIChzdGF0ZS5zZWxlY3Rpb24pLmpzb25JRCxcbiAgYW5jaG9yOiBhYnNvbHV0ZVBvc2l0aW9uVG9SZWxhdGl2ZVBvc2l0aW9uKFxuICAgIHN0YXRlLnNlbGVjdGlvbi5hbmNob3IsXG4gICAgcG1iaW5kaW5nLnR5cGUsXG4gICAgcG1iaW5kaW5nLm1hcHBpbmdcbiAgKSxcbiAgaGVhZDogYWJzb2x1dGVQb3NpdGlvblRvUmVsYXRpdmVQb3NpdGlvbihcbiAgICBzdGF0ZS5zZWxlY3Rpb24uaGVhZCxcbiAgICBwbWJpbmRpbmcudHlwZSxcbiAgICBwbWJpbmRpbmcubWFwcGluZ1xuICApXG59KVxuXG4vKipcbiAqIEJpbmRpbmcgZm9yIHByb3NlbWlycm9yLlxuICpcbiAqIEBwcm90ZWN0ZWRcbiAqL1xuZXhwb3J0IGNsYXNzIFByb3NlbWlycm9yQmluZGluZyB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge1kuWG1sRnJhZ21lbnR9IHlYbWxGcmFnbWVudCBUaGUgYmluZCBzb3VyY2VcbiAgICogQHBhcmFtIHtQcm9zZW1pcnJvck1hcHBpbmd9IG1hcHBpbmdcbiAgICovXG4gIGNvbnN0cnVjdG9yICh5WG1sRnJhZ21lbnQsIG1hcHBpbmcgPSBuZXcgTWFwKCkpIHtcbiAgICB0aGlzLnR5cGUgPSB5WG1sRnJhZ21lbnRcbiAgICAvKipcbiAgICAgKiB0aGlzIHdpbGwgYmUgc2V0IG9uY2UgdGhlIHZpZXcgaXMgY3JlYXRlZFxuICAgICAqIEB0eXBlIHthbnl9XG4gICAgICovXG4gICAgdGhpcy5wcm9zZW1pcnJvclZpZXcgPSBudWxsXG4gICAgdGhpcy5tdXggPSBjcmVhdGVNdXRleCgpXG4gICAgdGhpcy5tYXBwaW5nID0gbWFwcGluZ1xuICAgIC8qKlxuICAgICAqIElzIG92ZXJsYXBwaW5nIG1hcmsgLSBpLmUuIG1hcmsgZG9lcyBub3QgZXhjbHVkZSBpdHNlbGYuXG4gICAgICpcbiAgICAgKiBAdHlwZSB7TWFwPGltcG9ydCgncHJvc2VtaXJyb3ItbW9kZWwnKS5NYXJrVHlwZSwgYm9vbGVhbj59XG4gICAgICovXG4gICAgdGhpcy5pc09NYXJrID0gbmV3IE1hcCgpXG4gICAgdGhpcy5fb2JzZXJ2ZUZ1bmN0aW9uID0gdGhpcy5fdHlwZUNoYW5nZWQuYmluZCh0aGlzKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtZLkRvY31cbiAgICAgKi9cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgdGhpcy5kb2MgPSB5WG1sRnJhZ21lbnQuZG9jXG4gICAgLyoqXG4gICAgICogY3VycmVudCBzZWxlY3Rpb24gYXMgcmVsYXRpdmUgcG9zaXRpb25zIGluIHRoZSBZanMgbW9kZWxcbiAgICAgKi9cbiAgICB0aGlzLmJlZm9yZVRyYW5zYWN0aW9uU2VsZWN0aW9uID0gbnVsbFxuICAgIHRoaXMuYmVmb3JlQWxsVHJhbnNhY3Rpb25zID0gKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuYmVmb3JlVHJhbnNhY3Rpb25TZWxlY3Rpb24gPT09IG51bGwgJiYgdGhpcy5wcm9zZW1pcnJvclZpZXcgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLmJlZm9yZVRyYW5zYWN0aW9uU2VsZWN0aW9uID0gZ2V0UmVsYXRpdmVTZWxlY3Rpb24oXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICB0aGlzLnByb3NlbWlycm9yVmlldy5zdGF0ZVxuICAgICAgICApXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuYWZ0ZXJBbGxUcmFuc2FjdGlvbnMgPSAoKSA9PiB7XG4gICAgICB0aGlzLmJlZm9yZVRyYW5zYWN0aW9uU2VsZWN0aW9uID0gbnVsbFxuICAgIH1cbiAgICB0aGlzLl9kb21TZWxlY3Rpb25JblZpZXcgPSBudWxsXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgdHJhbnNhY3Rpb24gZm9yIGNoYW5naW5nIHRoZSBwcm9zZW1pcnJvciBzdGF0ZS5cbiAgICpcbiAgICogQHJldHVybnNcbiAgICovXG4gIGdldCBfdHIgKCkge1xuICAgIHJldHVybiB0aGlzLnByb3NlbWlycm9yVmlldy5zdGF0ZS50ci5zZXRNZXRhKCdhZGRUb0hpc3RvcnknLCBmYWxzZSlcbiAgfVxuXG4gIF9pc0xvY2FsQ3Vyc29ySW5WaWV3ICgpIHtcbiAgICBpZiAoIXRoaXMucHJvc2VtaXJyb3JWaWV3Lmhhc0ZvY3VzKCkpIHJldHVybiBmYWxzZVxuICAgIGlmIChlbnZpcm9ubWVudC5pc0Jyb3dzZXIgJiYgdGhpcy5fZG9tU2VsZWN0aW9uSW5WaWV3ID09PSBudWxsKSB7XG4gICAgICAvLyBDYWxjdWxhdGUgdGhlIGRvbVNlbGVjdGlvbkluVmlldyBhbmQgY2xlYXIgYnkgbmV4dCB0aWNrIGFmdGVyIGFsbCBldmVudHMgYXJlIGZpbmlzaGVkXG4gICAgICBldmVudGxvb3AudGltZW91dCgwLCAoKSA9PiB7XG4gICAgICAgIHRoaXMuX2RvbVNlbGVjdGlvbkluVmlldyA9IG51bGxcbiAgICAgIH0pXG4gICAgICB0aGlzLl9kb21TZWxlY3Rpb25JblZpZXcgPSB0aGlzLl9pc0RvbVNlbGVjdGlvbkluVmlldygpXG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9kb21TZWxlY3Rpb25JblZpZXdcbiAgfVxuXG4gIF9pc0RvbVNlbGVjdGlvbkluVmlldyAoKSB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gdGhpcy5wcm9zZW1pcnJvclZpZXcuX3Jvb3QuZ2V0U2VsZWN0aW9uKClcblxuICAgIGlmIChzZWxlY3Rpb24gPT0gbnVsbCB8fCBzZWxlY3Rpb24uYW5jaG9yTm9kZSA9PSBudWxsKSByZXR1cm4gZmFsc2VcblxuICAgIGNvbnN0IHJhbmdlID0gdGhpcy5wcm9zZW1pcnJvclZpZXcuX3Jvb3QuY3JlYXRlUmFuZ2UoKVxuICAgIHJhbmdlLnNldFN0YXJ0KHNlbGVjdGlvbi5hbmNob3JOb2RlLCBzZWxlY3Rpb24uYW5jaG9yT2Zmc2V0KVxuICAgIHJhbmdlLnNldEVuZChzZWxlY3Rpb24uZm9jdXNOb2RlLCBzZWxlY3Rpb24uZm9jdXNPZmZzZXQpXG5cbiAgICAvLyBUaGlzIGlzIGEgd29ya2Fyb3VuZCBmb3IgYW4gZWRnZWNhc2Ugd2hlcmUgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IHdpbGxcbiAgICAvLyByZXR1cm4gemVybyB2YWx1ZXMgaWYgdGhlIHNlbGVjdGlvbiBpcyBjb2xsYXBzZWQgYXQgdGhlIHN0YXJ0IG9mIGEgbmV3bGluZVxuICAgIC8vIHNlZSByZWZlcmVuY2UgaGVyZTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzU5NzgwOTU0XG4gICAgY29uc3QgcmVjdHMgPSByYW5nZS5nZXRDbGllbnRSZWN0cygpXG4gICAgaWYgKHJlY3RzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgLy8gcHJvYmFibHkgYnVnZ3kgbmV3bGluZSBiZWhhdmlvciwgZXhwbGljaXRseSBzZWxlY3QgdGhlIG5vZGUgY29udGVudHNcbiAgICAgIGlmIChyYW5nZS5zdGFydENvbnRhaW5lciAmJiByYW5nZS5jb2xsYXBzZWQpIHtcbiAgICAgICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKHJhbmdlLnN0YXJ0Q29udGFpbmVyKVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGJvdW5kaW5nID0gcmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClcbiAgICBjb25zdCBkb2N1bWVudEVsZW1lbnQgPSBkb20uZG9jLmRvY3VtZW50RWxlbWVudFxuXG4gICAgcmV0dXJuIGJvdW5kaW5nLmJvdHRvbSA+PSAwICYmIGJvdW5kaW5nLnJpZ2h0ID49IDAgJiZcbiAgICAgIGJvdW5kaW5nLmxlZnQgPD1cbiAgICAgICAgKHdpbmRvdy5pbm5lcldpZHRoIHx8IGRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCB8fCAwKSAmJlxuICAgICAgYm91bmRpbmcudG9wIDw9ICh3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCB8fCAwKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7WS5TbmFwc2hvdH0gc25hcHNob3RcbiAgICogQHBhcmFtIHtZLlNuYXBzaG90fSBwcmV2U25hcHNob3RcbiAgICovXG4gIHJlbmRlclNuYXBzaG90IChzbmFwc2hvdCwgcHJldlNuYXBzaG90KSB7XG4gICAgaWYgKCFwcmV2U25hcHNob3QpIHtcbiAgICAgIHByZXZTbmFwc2hvdCA9IFkuY3JlYXRlU25hcHNob3QoWS5jcmVhdGVEZWxldGVTZXQoKSwgbmV3IE1hcCgpKVxuICAgIH1cbiAgICB0aGlzLnByb3NlbWlycm9yVmlldy5kaXNwYXRjaChcbiAgICAgIHRoaXMuX3RyLnNldE1ldGEoeVN5bmNQbHVnaW5LZXksIHsgc25hcHNob3QsIHByZXZTbmFwc2hvdCB9KVxuICAgIClcbiAgfVxuXG4gIHVucmVuZGVyU25hcHNob3QgKCkge1xuICAgIHRoaXMubWFwcGluZy5jbGVhcigpXG4gICAgdGhpcy5tdXgoKCkgPT4ge1xuICAgICAgY29uc3QgZnJhZ21lbnRDb250ZW50ID0gdGhpcy50eXBlLnRvQXJyYXkoKS5tYXAoKHQpID0+XG4gICAgICAgIGNyZWF0ZU5vZGVGcm9tWUVsZW1lbnQoXG4gICAgICAgICAgLyoqIEB0eXBlIHtZLlhtbEVsZW1lbnR9ICovICh0KSxcbiAgICAgICAgICB0aGlzLnByb3NlbWlycm9yVmlldy5zdGF0ZS5zY2hlbWEsXG4gICAgICAgICAgdGhpc1xuICAgICAgICApXG4gICAgICApLmZpbHRlcigobikgPT4gbiAhPT0gbnVsbClcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIGNvbnN0IHRyID0gdGhpcy5fdHIucmVwbGFjZShcbiAgICAgICAgMCxcbiAgICAgICAgdGhpcy5wcm9zZW1pcnJvclZpZXcuc3RhdGUuZG9jLmNvbnRlbnQuc2l6ZSxcbiAgICAgICAgbmV3IFBNb2RlbC5TbGljZShQTW9kZWwuRnJhZ21lbnQuZnJvbShmcmFnbWVudENvbnRlbnQpLCAwLCAwKVxuICAgICAgKVxuICAgICAgdHIuc2V0TWV0YSh5U3luY1BsdWdpbktleSwgeyBzbmFwc2hvdDogbnVsbCwgcHJldlNuYXBzaG90OiBudWxsIH0pXG4gICAgICB0aGlzLnByb3NlbWlycm9yVmlldy5kaXNwYXRjaCh0cilcbiAgICB9KVxuICB9XG5cbiAgX2ZvcmNlUmVyZW5kZXIgKCkge1xuICAgIHRoaXMubWFwcGluZy5jbGVhcigpXG4gICAgdGhpcy5tdXgoKCkgPT4ge1xuICAgICAgLy8gSWYgdGhpcyBpcyBhIGZvcmNlZCByZXJlbmRlciwgdGhpcyBtaWdodCBuZWl0aGVyIGhhcHBlbiBhcyBhIHBtIGNoYW5nZSBub3Igd2l0aGluIGEgWWpzXG4gICAgICAvLyB0cmFuc2FjdGlvbi4gVGhlbiB0aGUgXCJiZWZvcmUgc2VsZWN0aW9uXCIgZG9lc24ndCBleGlzdC4gSW4gdGhpcyBjYXNlLCB3ZSBuZWVkIHRvIGNyZWF0ZSBhXG4gICAgICAvLyByZWxhdGl2ZSBwb3NpdGlvbiBiZWZvcmUgcmVwbGFjaW5nIGNvbnRlbnQuIEZpeGVzICMxMjZcbiAgICAgIGNvbnN0IHNlbCA9IHRoaXMuYmVmb3JlVHJhbnNhY3Rpb25TZWxlY3Rpb24gIT09IG51bGwgPyBudWxsIDogdGhpcy5wcm9zZW1pcnJvclZpZXcuc3RhdGUuc2VsZWN0aW9uXG4gICAgICBjb25zdCBmcmFnbWVudENvbnRlbnQgPSB0aGlzLnR5cGUudG9BcnJheSgpLm1hcCgodCkgPT5cbiAgICAgICAgY3JlYXRlTm9kZUZyb21ZRWxlbWVudChcbiAgICAgICAgICAvKiogQHR5cGUge1kuWG1sRWxlbWVudH0gKi8gKHQpLFxuICAgICAgICAgIHRoaXMucHJvc2VtaXJyb3JWaWV3LnN0YXRlLnNjaGVtYSxcbiAgICAgICAgICB0aGlzXG4gICAgICAgIClcbiAgICAgICkuZmlsdGVyKChuKSA9PiBuICE9PSBudWxsKVxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgY29uc3QgdHIgPSB0aGlzLl90ci5yZXBsYWNlKFxuICAgICAgICAwLFxuICAgICAgICB0aGlzLnByb3NlbWlycm9yVmlldy5zdGF0ZS5kb2MuY29udGVudC5zaXplLFxuICAgICAgICBuZXcgUE1vZGVsLlNsaWNlKFBNb2RlbC5GcmFnbWVudC5mcm9tKGZyYWdtZW50Q29udGVudCksIDAsIDApXG4gICAgICApXG4gICAgICBpZiAoc2VsKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJZiB0aGUgUHJvc2VtaXJyb3IgZG9jdW1lbnQgd2UganVzdCBjcmVhdGVkIGZyb20gdGhpcy50eXBlIGlzXG4gICAgICAgICAqIHNtYWxsZXIgdGhhbiB0aGUgcHJldmlvdXMgZG9jdW1lbnQsIHRoZSBzZWxlY3Rpb24gbWlnaHQgYmVcbiAgICAgICAgICogb3V0IG9mIGJvdW5kLCB3aGljaCB3b3VsZCBtYWtlIFByb3NlbWlycm9yIHRocm93IGFuIGVycm9yLlxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgY2xhbXBlZEFuY2hvciA9IG1hdGgubWluKG1hdGgubWF4KHNlbC5hbmNob3IsIDApLCB0ci5kb2MuY29udGVudC5zaXplKVxuICAgICAgICBjb25zdCBjbGFtcGVkSGVhZCA9IG1hdGgubWluKG1hdGgubWF4KHNlbC5oZWFkLCAwKSwgdHIuZG9jLmNvbnRlbnQuc2l6ZSlcblxuICAgICAgICB0ci5zZXRTZWxlY3Rpb24oVGV4dFNlbGVjdGlvbi5jcmVhdGUodHIuZG9jLCBjbGFtcGVkQW5jaG9yLCBjbGFtcGVkSGVhZCkpXG4gICAgICB9XG4gICAgICB0aGlzLnByb3NlbWlycm9yVmlldy5kaXNwYXRjaChcbiAgICAgICAgdHIuc2V0TWV0YSh5U3luY1BsdWdpbktleSwgeyBpc0NoYW5nZU9yaWdpbjogdHJ1ZSwgYmluZGluZzogdGhpcyB9KVxuICAgICAgKVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtZLlNuYXBzaG90fFVpbnQ4QXJyYXl9IHNuYXBzaG90XG4gICAqIEBwYXJhbSB7WS5TbmFwc2hvdHxVaW50OEFycmF5fSBwcmV2U25hcHNob3RcbiAgICogQHBhcmFtIHtPYmplY3R9IHBsdWdpblN0YXRlXG4gICAqL1xuICBfcmVuZGVyU25hcHNob3QgKHNuYXBzaG90LCBwcmV2U25hcHNob3QsIHBsdWdpblN0YXRlKSB7XG4gICAgLyoqXG4gICAgICogVGhlIGRvY3VtZW50IHRoYXQgY29udGFpbnMgdGhlIGZ1bGwgaGlzdG9yeSBvZiB0aGlzIGRvY3VtZW50LlxuICAgICAqIEB0eXBlIHtZLkRvY31cbiAgICAgKi9cbiAgICBsZXQgaGlzdG9yeURvYyA9IHRoaXMuZG9jXG4gICAgbGV0IGhpc3RvcnlUeXBlID0gdGhpcy50eXBlXG4gICAgaWYgKCFzbmFwc2hvdCkge1xuICAgICAgc25hcHNob3QgPSBZLnNuYXBzaG90KHRoaXMuZG9jKVxuICAgIH1cbiAgICBpZiAoc25hcHNob3QgaW5zdGFuY2VvZiBVaW50OEFycmF5IHx8IHByZXZTbmFwc2hvdCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHtcbiAgICAgIGlmICghKHNuYXBzaG90IGluc3RhbmNlb2YgVWludDhBcnJheSkgfHwgIShwcmV2U25hcHNob3QgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkge1xuICAgICAgICAvLyBleHBlY3RlZCBib3RoIHNuYXBzaG90cyB0byBiZSB2MiB1cGRhdGVzXG4gICAgICAgIGVycm9yLnVuZXhwZWN0ZWRDYXNlKClcbiAgICAgIH1cbiAgICAgIGhpc3RvcnlEb2MgPSBuZXcgWS5Eb2MoeyBnYzogZmFsc2UgfSlcbiAgICAgIFkuYXBwbHlVcGRhdGVWMihoaXN0b3J5RG9jLCBwcmV2U25hcHNob3QpXG4gICAgICBwcmV2U25hcHNob3QgPSBZLnNuYXBzaG90KGhpc3RvcnlEb2MpXG4gICAgICBZLmFwcGx5VXBkYXRlVjIoaGlzdG9yeURvYywgc25hcHNob3QpXG4gICAgICBzbmFwc2hvdCA9IFkuc25hcHNob3QoaGlzdG9yeURvYylcbiAgICAgIGlmIChoaXN0b3J5VHlwZS5faXRlbSA9PT0gbnVsbCkge1xuICAgICAgICAvKipcbiAgICAgICAgICogSWYgaXMgYSByb290IHR5cGUsIHdlIG5lZWQgdG8gZmluZCB0aGUgcm9vdCBrZXkgaW4gdGhlIGluaXRpYWwgZG9jdW1lbnRcbiAgICAgICAgICogYW5kIHVzZSBpdCB0byBnZXQgdGhlIGhpc3RvcnkgdHlwZS5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IHJvb3RLZXkgPSBBcnJheS5mcm9tKHRoaXMuZG9jLnNoYXJlLmtleXMoKSkuZmluZChcbiAgICAgICAgICAoa2V5KSA9PiB0aGlzLmRvYy5zaGFyZS5nZXQoa2V5KSA9PT0gdGhpcy50eXBlXG4gICAgICAgIClcbiAgICAgICAgaGlzdG9yeVR5cGUgPSBoaXN0b3J5RG9jLmdldFhtbEZyYWdtZW50KHJvb3RLZXkpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvKipcbiAgICAgICAgICogSWYgaXQgaXMgYSBzdWIgdHlwZSwgd2UgdXNlIHRoZSBpdGVtIGlkIHRvIGZpbmQgdGhlIGhpc3RvcnkgdHlwZS5cbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGhpc3RvcnlTdHJ1Y3RzID1cbiAgICAgICAgICBoaXN0b3J5RG9jLnN0b3JlLmNsaWVudHMuZ2V0KGhpc3RvcnlUeXBlLl9pdGVtLmlkLmNsaWVudCkgPz8gW11cbiAgICAgICAgY29uc3QgaXRlbUluZGV4ID0gWS5maW5kSW5kZXhTUyhcbiAgICAgICAgICBoaXN0b3J5U3RydWN0cyxcbiAgICAgICAgICBoaXN0b3J5VHlwZS5faXRlbS5pZC5jbG9ja1xuICAgICAgICApXG4gICAgICAgIGNvbnN0IGl0ZW0gPSAvKiogQHR5cGUge1kuSXRlbX0gKi8gKGhpc3RvcnlTdHJ1Y3RzW2l0ZW1JbmRleF0pXG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSAvKiogQHR5cGUge1kuQ29udGVudFR5cGV9ICovIChpdGVtLmNvbnRlbnQpXG4gICAgICAgIGhpc3RvcnlUeXBlID0gLyoqIEB0eXBlIHtZLlhtbEZyYWdtZW50fSAqLyAoY29udGVudC50eXBlKVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBjbGVhciBtYXBwaW5nIGJlY2F1c2Ugd2UgYXJlIGdvaW5nIHRvIHJlcmVuZGVyXG4gICAgdGhpcy5tYXBwaW5nLmNsZWFyKClcbiAgICB0aGlzLm11eCgoKSA9PiB7XG4gICAgICBoaXN0b3J5RG9jLnRyYW5zYWN0KCh0cmFuc2FjdGlvbikgPT4ge1xuICAgICAgICAvLyBiZWZvcmUgcmVuZGVyaW5nLCB3ZSBhcmUgZ29pbmcgdG8gc2FuaXRpemUgb3BzIGFuZCBzcGxpdCBkZWxldGVkIG9wc1xuICAgICAgICAvLyBpZiB0aGV5IHdlcmUgZGVsZXRlZCBieSBzZXBlcmF0ZSB1c2Vycy5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEB0eXBlIHtZLlBlcm1hbmVudFVzZXJEYXRhfVxuICAgICAgICAgKi9cbiAgICAgICAgY29uc3QgcHVkID0gcGx1Z2luU3RhdGUucGVybWFuZW50VXNlckRhdGFcbiAgICAgICAgaWYgKHB1ZCkge1xuICAgICAgICAgIHB1ZC5kc3MuZm9yRWFjaCgoZHMpID0+IHtcbiAgICAgICAgICAgIFkuaXRlcmF0ZURlbGV0ZWRTdHJ1Y3RzKHRyYW5zYWN0aW9uLCBkcywgKF9pdGVtKSA9PiB7fSlcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBAcGFyYW0geydyZW1vdmVkJ3wnYWRkZWQnfSB0eXBlXG4gICAgICAgICAqIEBwYXJhbSB7WS5JRH0gaWRcbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IGNvbXB1dGVZQ2hhbmdlID0gKHR5cGUsIGlkKSA9PiB7XG4gICAgICAgICAgY29uc3QgdXNlciA9IHR5cGUgPT09ICdhZGRlZCdcbiAgICAgICAgICAgID8gcHVkLmdldFVzZXJCeUNsaWVudElkKGlkLmNsaWVudClcbiAgICAgICAgICAgIDogcHVkLmdldFVzZXJCeURlbGV0ZWRJZChpZClcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdXNlcixcbiAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICBjb2xvcjogZ2V0VXNlckNvbG9yKFxuICAgICAgICAgICAgICBwbHVnaW5TdGF0ZS5jb2xvck1hcHBpbmcsXG4gICAgICAgICAgICAgIHBsdWdpblN0YXRlLmNvbG9ycyxcbiAgICAgICAgICAgICAgdXNlclxuICAgICAgICAgICAgKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBDcmVhdGUgZG9jdW1lbnQgZnJhZ21lbnQgYW5kIHJlbmRlclxuICAgICAgICBjb25zdCBmcmFnbWVudENvbnRlbnQgPSBZLnR5cGVMaXN0VG9BcnJheVNuYXBzaG90KFxuICAgICAgICAgIGhpc3RvcnlUeXBlLFxuICAgICAgICAgIG5ldyBZLlNuYXBzaG90KHByZXZTbmFwc2hvdC5kcywgc25hcHNob3Quc3YpXG4gICAgICAgICkubWFwKCh0KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIXQuX2l0ZW0uZGVsZXRlZCB8fCBpc1Zpc2libGUodC5faXRlbSwgc25hcHNob3QpIHx8XG4gICAgICAgICAgICBpc1Zpc2libGUodC5faXRlbSwgcHJldlNuYXBzaG90KVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZU5vZGVGcm9tWUVsZW1lbnQoXG4gICAgICAgICAgICAgIHQsXG4gICAgICAgICAgICAgIHRoaXMucHJvc2VtaXJyb3JWaWV3LnN0YXRlLnNjaGVtYSxcbiAgICAgICAgICAgICAgeyBtYXBwaW5nOiBuZXcgTWFwKCksIGlzT01hcms6IG5ldyBNYXAoKSB9LFxuICAgICAgICAgICAgICBzbmFwc2hvdCxcbiAgICAgICAgICAgICAgcHJldlNuYXBzaG90LFxuICAgICAgICAgICAgICBjb21wdXRlWUNoYW5nZVxuICAgICAgICAgICAgKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBObyBuZWVkIHRvIHJlbmRlciBlbGVtZW50cyB0aGF0IGFyZSBub3QgdmlzaWJsZSBieSBlaXRoZXIgc25hcHNob3QuXG4gICAgICAgICAgICAvLyBJZiBhIGNsaWVudCBhZGRzIGFuZCBkZWxldGVzIGNvbnRlbnQgaW4gdGhlIHNhbWUgc25hcHNob3QgdGhlIGVsZW1lbnQgaXMgbm90IHZpc2libGUgYnkgZWl0aGVyIHNuYXBzaG90LlxuICAgICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgICB9XG4gICAgICAgIH0pLmZpbHRlcigobikgPT4gbiAhPT0gbnVsbClcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBjb25zdCB0ciA9IHRoaXMuX3RyLnJlcGxhY2UoXG4gICAgICAgICAgMCxcbiAgICAgICAgICB0aGlzLnByb3NlbWlycm9yVmlldy5zdGF0ZS5kb2MuY29udGVudC5zaXplLFxuICAgICAgICAgIG5ldyBQTW9kZWwuU2xpY2UoUE1vZGVsLkZyYWdtZW50LmZyb20oZnJhZ21lbnRDb250ZW50KSwgMCwgMClcbiAgICAgICAgKVxuICAgICAgICB0aGlzLnByb3NlbWlycm9yVmlldy5kaXNwYXRjaChcbiAgICAgICAgICB0ci5zZXRNZXRhKHlTeW5jUGx1Z2luS2V5LCB7IGlzQ2hhbmdlT3JpZ2luOiB0cnVlIH0pXG4gICAgICAgIClcbiAgICAgIH0sIHlTeW5jUGx1Z2luS2V5KVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtBcnJheTxZLllFdmVudDxhbnk+Pn0gZXZlbnRzXG4gICAqIEBwYXJhbSB7WS5UcmFuc2FjdGlvbn0gdHJhbnNhY3Rpb25cbiAgICovXG4gIF90eXBlQ2hhbmdlZCAoZXZlbnRzLCB0cmFuc2FjdGlvbikge1xuICAgIGlmICh0aGlzLnByb3NlbWlycm9yVmlldyA9PSBudWxsKSByZXR1cm5cbiAgICBjb25zdCBzeW5jU3RhdGUgPSB5U3luY1BsdWdpbktleS5nZXRTdGF0ZSh0aGlzLnByb3NlbWlycm9yVmlldy5zdGF0ZSlcbiAgICBpZiAoXG4gICAgICBldmVudHMubGVuZ3RoID09PSAwIHx8IHN5bmNTdGF0ZS5zbmFwc2hvdCAhPSBudWxsIHx8XG4gICAgICBzeW5jU3RhdGUucHJldlNuYXBzaG90ICE9IG51bGxcbiAgICApIHtcbiAgICAgIC8vIGRyb3Agb3V0IGlmIHNuYXBzaG90IGlzIGFjdGl2ZVxuICAgICAgdGhpcy5yZW5kZXJTbmFwc2hvdChzeW5jU3RhdGUuc25hcHNob3QsIHN5bmNTdGF0ZS5wcmV2U25hcHNob3QpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgdGhpcy5tdXgoKCkgPT4ge1xuICAgICAgLyoqXG4gICAgICAgKiBAcGFyYW0ge2FueX0gX1xuICAgICAgICogQHBhcmFtIHtZLkFic3RyYWN0VHlwZTxhbnk+fSB0eXBlXG4gICAgICAgKi9cbiAgICAgIGNvbnN0IGRlbFR5cGUgPSAoXywgdHlwZSkgPT4gdGhpcy5tYXBwaW5nLmRlbGV0ZSh0eXBlKVxuICAgICAgWS5pdGVyYXRlRGVsZXRlZFN0cnVjdHMoXG4gICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgICB0cmFuc2FjdGlvbi5kZWxldGVTZXQsXG4gICAgICAgIChzdHJ1Y3QpID0+IHtcbiAgICAgICAgICBpZiAoc3RydWN0LmNvbnN0cnVjdG9yID09PSBZLkl0ZW0pIHtcbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSAvKiogQHR5cGUge1kuQ29udGVudFR5cGV9ICovICgvKiogQHR5cGUge1kuSXRlbX0gKi8gKHN0cnVjdCkuY29udGVudCkudHlwZVxuICAgICAgICAgICAgdHlwZSAmJiB0aGlzLm1hcHBpbmcuZGVsZXRlKHR5cGUpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApXG4gICAgICB0cmFuc2FjdGlvbi5jaGFuZ2VkLmZvckVhY2goZGVsVHlwZSlcbiAgICAgIHRyYW5zYWN0aW9uLmNoYW5nZWRQYXJlbnRUeXBlcy5mb3JFYWNoKGRlbFR5cGUpXG4gICAgICBjb25zdCBmcmFnbWVudENvbnRlbnQgPSB0aGlzLnR5cGUudG9BcnJheSgpLm1hcCgodCkgPT5cbiAgICAgICAgY3JlYXRlTm9kZUlmTm90RXhpc3RzKFxuICAgICAgICAgIC8qKiBAdHlwZSB7WS5YbWxFbGVtZW50IHwgWS5YbWxIb29rfSAqLyAodCksXG4gICAgICAgICAgdGhpcy5wcm9zZW1pcnJvclZpZXcuc3RhdGUuc2NoZW1hLFxuICAgICAgICAgIHRoaXNcbiAgICAgICAgKVxuICAgICAgKS5maWx0ZXIoKG4pID0+IG4gIT09IG51bGwpXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBsZXQgdHIgPSB0aGlzLl90ci5yZXBsYWNlKFxuICAgICAgICAwLFxuICAgICAgICB0aGlzLnByb3NlbWlycm9yVmlldy5zdGF0ZS5kb2MuY29udGVudC5zaXplLFxuICAgICAgICBuZXcgUE1vZGVsLlNsaWNlKFBNb2RlbC5GcmFnbWVudC5mcm9tKGZyYWdtZW50Q29udGVudCksIDAsIDApXG4gICAgICApXG4gICAgICByZXN0b3JlUmVsYXRpdmVTZWxlY3Rpb24odHIsIHRoaXMuYmVmb3JlVHJhbnNhY3Rpb25TZWxlY3Rpb24sIHRoaXMpXG4gICAgICB0ciA9IHRyLnNldE1ldGEoeVN5bmNQbHVnaW5LZXksIHsgaXNDaGFuZ2VPcmlnaW46IHRydWUsIGlzVW5kb1JlZG9PcGVyYXRpb246IHRyYW5zYWN0aW9uLm9yaWdpbiBpbnN0YW5jZW9mIFkuVW5kb01hbmFnZXIgfSlcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5iZWZvcmVUcmFuc2FjdGlvblNlbGVjdGlvbiAhPT0gbnVsbCAmJiB0aGlzLl9pc0xvY2FsQ3Vyc29ySW5WaWV3KClcbiAgICAgICkge1xuICAgICAgICB0ci5zY3JvbGxJbnRvVmlldygpXG4gICAgICB9XG4gICAgICB0aGlzLnByb3NlbWlycm9yVmlldy5kaXNwYXRjaCh0cilcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KCdwcm9zZW1pcnJvci1tb2RlbCcpLk5vZGV9IGRvY1xuICAgKi9cbiAgX3Byb3NlbWlycm9yQ2hhbmdlZCAoZG9jKSB7XG4gICAgdGhpcy5kb2MudHJhbnNhY3QoKCkgPT4ge1xuICAgICAgdXBkYXRlWUZyYWdtZW50KHRoaXMuZG9jLCB0aGlzLnR5cGUsIGRvYywgdGhpcylcbiAgICAgIHRoaXMuYmVmb3JlVHJhbnNhY3Rpb25TZWxlY3Rpb24gPSBnZXRSZWxhdGl2ZVNlbGVjdGlvbihcbiAgICAgICAgdGhpcyxcbiAgICAgICAgdGhpcy5wcm9zZW1pcnJvclZpZXcuc3RhdGVcbiAgICAgIClcbiAgICB9LCB5U3luY1BsdWdpbktleSlcbiAgfVxuXG4gIC8qKlxuICAgKiBWaWV3IGlzIHJlYWR5IHRvIGxpc3RlbiB0byBjaGFuZ2VzLiBSZWdpc3RlciBvYnNlcnZlcnMuXG4gICAqIEBwYXJhbSB7YW55fSBwcm9zZW1pcnJvclZpZXdcbiAgICovXG4gIGluaXRWaWV3IChwcm9zZW1pcnJvclZpZXcpIHtcbiAgICBpZiAodGhpcy5wcm9zZW1pcnJvclZpZXcgIT0gbnVsbCkgdGhpcy5kZXN0cm95KClcbiAgICB0aGlzLnByb3NlbWlycm9yVmlldyA9IHByb3NlbWlycm9yVmlld1xuICAgIHRoaXMuZG9jLm9uKCdiZWZvcmVBbGxUcmFuc2FjdGlvbnMnLCB0aGlzLmJlZm9yZUFsbFRyYW5zYWN0aW9ucylcbiAgICB0aGlzLmRvYy5vbignYWZ0ZXJBbGxUcmFuc2FjdGlvbnMnLCB0aGlzLmFmdGVyQWxsVHJhbnNhY3Rpb25zKVxuICAgIHRoaXMudHlwZS5vYnNlcnZlRGVlcCh0aGlzLl9vYnNlcnZlRnVuY3Rpb24pXG4gIH1cblxuICBkZXN0cm95ICgpIHtcbiAgICBpZiAodGhpcy5wcm9zZW1pcnJvclZpZXcgPT0gbnVsbCkgcmV0dXJuXG4gICAgdGhpcy5wcm9zZW1pcnJvclZpZXcgPSBudWxsXG4gICAgdGhpcy50eXBlLnVub2JzZXJ2ZURlZXAodGhpcy5fb2JzZXJ2ZUZ1bmN0aW9uKVxuICAgIHRoaXMuZG9jLm9mZignYmVmb3JlQWxsVHJhbnNhY3Rpb25zJywgdGhpcy5iZWZvcmVBbGxUcmFuc2FjdGlvbnMpXG4gICAgdGhpcy5kb2Mub2ZmKCdhZnRlckFsbFRyYW5zYWN0aW9ucycsIHRoaXMuYWZ0ZXJBbGxUcmFuc2FjdGlvbnMpXG4gIH1cbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtZLlhtbEVsZW1lbnQgfCBZLlhtbEhvb2t9IGVsXG4gKiBAcGFyYW0ge1BNb2RlbC5TY2hlbWF9IHNjaGVtYVxuICogQHBhcmFtIHtCaW5kaW5nTWV0YWRhdGF9IG1ldGFcbiAqIEBwYXJhbSB7WS5TbmFwc2hvdH0gW3NuYXBzaG90XVxuICogQHBhcmFtIHtZLlNuYXBzaG90fSBbcHJldlNuYXBzaG90XVxuICogQHBhcmFtIHtmdW5jdGlvbigncmVtb3ZlZCcgfCAnYWRkZWQnLCBZLklEKTphbnl9IFtjb21wdXRlWUNoYW5nZV1cbiAqIEByZXR1cm4ge1BNb2RlbC5Ob2RlIHwgbnVsbH1cbiAqL1xuY29uc3QgY3JlYXRlTm9kZUlmTm90RXhpc3RzID0gKFxuICBlbCxcbiAgc2NoZW1hLFxuICBtZXRhLFxuICBzbmFwc2hvdCxcbiAgcHJldlNuYXBzaG90LFxuICBjb21wdXRlWUNoYW5nZVxuKSA9PiB7XG4gIGNvbnN0IG5vZGUgPSAvKiogQHR5cGUge1BNb2RlbC5Ob2RlfSAqLyAobWV0YS5tYXBwaW5nLmdldChlbCkpXG4gIGlmIChub2RlID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoZWwgaW5zdGFuY2VvZiBZLlhtbEVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBjcmVhdGVOb2RlRnJvbVlFbGVtZW50KFxuICAgICAgICBlbCxcbiAgICAgICAgc2NoZW1hLFxuICAgICAgICBtZXRhLFxuICAgICAgICBzbmFwc2hvdCxcbiAgICAgICAgcHJldlNuYXBzaG90LFxuICAgICAgICBjb21wdXRlWUNoYW5nZVxuICAgICAgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBlcnJvci5tZXRob2RVbmltcGxlbWVudGVkKCkgLy8gd2UgYXJlIGN1cnJlbnRseSBub3QgaGFuZGxpbmcgaG9va3NcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5vZGVcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtZLlhtbEVsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge2FueX0gc2NoZW1hXG4gKiBAcGFyYW0ge0JpbmRpbmdNZXRhZGF0YX0gbWV0YVxuICogQHBhcmFtIHtZLlNuYXBzaG90fSBbc25hcHNob3RdXG4gKiBAcGFyYW0ge1kuU25hcHNob3R9IFtwcmV2U25hcHNob3RdXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCdyZW1vdmVkJyB8ICdhZGRlZCcsIFkuSUQpOmFueX0gW2NvbXB1dGVZQ2hhbmdlXVxuICogQHJldHVybiB7UE1vZGVsLk5vZGUgfCBudWxsfSBSZXR1cm5zIG5vZGUgaWYgbm9kZSBjb3VsZCBiZSBjcmVhdGVkLiBPdGhlcndpc2UgaXQgZGVsZXRlcyB0aGUgeWpzIHR5cGUgYW5kIHJldHVybnMgbnVsbFxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlTm9kZUZyb21ZRWxlbWVudCA9IChcbiAgZWwsXG4gIHNjaGVtYSxcbiAgbWV0YSxcbiAgc25hcHNob3QsXG4gIHByZXZTbmFwc2hvdCxcbiAgY29tcHV0ZVlDaGFuZ2VcbikgPT4ge1xuICBjb25zdCBjaGlsZHJlbiA9IFtdXG4gIC8qKlxuICAgKiBAcGFyYW0ge1kuWG1sRWxlbWVudCB8IFkuWG1sVGV4dH0gdHlwZVxuICAgKi9cbiAgY29uc3QgY3JlYXRlQ2hpbGRyZW4gPSAodHlwZSkgPT4ge1xuICAgIGlmICh0eXBlIGluc3RhbmNlb2YgWS5YbWxFbGVtZW50KSB7XG4gICAgICBjb25zdCBuID0gY3JlYXRlTm9kZUlmTm90RXhpc3RzKFxuICAgICAgICB0eXBlLFxuICAgICAgICBzY2hlbWEsXG4gICAgICAgIG1ldGEsXG4gICAgICAgIHNuYXBzaG90LFxuICAgICAgICBwcmV2U25hcHNob3QsXG4gICAgICAgIGNvbXB1dGVZQ2hhbmdlXG4gICAgICApXG4gICAgICBpZiAobiAhPT0gbnVsbCkge1xuICAgICAgICBjaGlsZHJlbi5wdXNoKG4pXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIElmIHRoZSBuZXh0IHl0ZXh0IGV4aXN0cyBhbmQgd2FzIGNyZWF0ZWQgYnkgdXMsIG1vdmUgdGhlIGNvbnRlbnQgdG8gdGhlIGN1cnJlbnQgeXRleHQuXG4gICAgICAvLyBUaGlzIGlzIGEgZml4IGZvciAjMTYwIC0tIGR1cGxpY2F0aW9uIG9mIGNoYXJhY3RlcnMgd2hlbiB0d28gWS5UZXh0IGV4aXN0IG5leHQgdG8gZWFjaFxuICAgICAgLy8gb3RoZXIuXG4gICAgICBjb25zdCBuZXh0eXRleHQgPSAvKiogQHR5cGUge1kuQ29udGVudFR5cGV9ICovICh0eXBlLl9pdGVtLnJpZ2h0Py5jb250ZW50KT8udHlwZVxuICAgICAgaWYgKG5leHR5dGV4dCBpbnN0YW5jZW9mIFkuVGV4dCAmJiAhbmV4dHl0ZXh0Ll9pdGVtLmRlbGV0ZWQgJiYgbmV4dHl0ZXh0Ll9pdGVtLmlkLmNsaWVudCA9PT0gbmV4dHl0ZXh0LmRvYy5jbGllbnRJRCkge1xuICAgICAgICB0eXBlLmFwcGx5RGVsdGEoW1xuICAgICAgICAgIHsgcmV0YWluOiB0eXBlLmxlbmd0aCB9LFxuICAgICAgICAgIC4uLm5leHR5dGV4dC50b0RlbHRhKClcbiAgICAgICAgXSlcbiAgICAgICAgbmV4dHl0ZXh0LmRvYy50cmFuc2FjdCh0ciA9PiB7XG4gICAgICAgICAgbmV4dHl0ZXh0Ll9pdGVtLmRlbGV0ZSh0cilcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIC8vIG5vdyBjcmVhdGUgdGhlIHByb3NlbWlycm9yIHRleHQgbm9kZXNcbiAgICAgIGNvbnN0IG5zID0gY3JlYXRlVGV4dE5vZGVzRnJvbVlUZXh0KFxuICAgICAgICB0eXBlLFxuICAgICAgICBzY2hlbWEsXG4gICAgICAgIG1ldGEsXG4gICAgICAgIHNuYXBzaG90LFxuICAgICAgICBwcmV2U25hcHNob3QsXG4gICAgICAgIGNvbXB1dGVZQ2hhbmdlXG4gICAgICApXG4gICAgICBpZiAobnMgIT09IG51bGwpIHtcbiAgICAgICAgbnMuZm9yRWFjaCgodGV4dGNoaWxkKSA9PiB7XG4gICAgICAgICAgaWYgKHRleHRjaGlsZCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgY2hpbGRyZW4ucHVzaCh0ZXh0Y2hpbGQpXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoc25hcHNob3QgPT09IHVuZGVmaW5lZCB8fCBwcmV2U25hcHNob3QgPT09IHVuZGVmaW5lZCkge1xuICAgIGVsLnRvQXJyYXkoKS5mb3JFYWNoKGNyZWF0ZUNoaWxkcmVuKVxuICB9IGVsc2Uge1xuICAgIFkudHlwZUxpc3RUb0FycmF5U25hcHNob3QoZWwsIG5ldyBZLlNuYXBzaG90KHByZXZTbmFwc2hvdC5kcywgc25hcHNob3Quc3YpKVxuICAgICAgLmZvckVhY2goY3JlYXRlQ2hpbGRyZW4pXG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCBhdHRycyA9IGVsLmdldEF0dHJpYnV0ZXMoc25hcHNob3QpXG4gICAgaWYgKHNuYXBzaG90ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmICghaXNWaXNpYmxlKC8qKiBAdHlwZSB7WS5JdGVtfSAqLyAoZWwuX2l0ZW0pLCBzbmFwc2hvdCkpIHtcbiAgICAgICAgYXR0cnMueWNoYW5nZSA9IGNvbXB1dGVZQ2hhbmdlXG4gICAgICAgICAgPyBjb21wdXRlWUNoYW5nZSgncmVtb3ZlZCcsIC8qKiBAdHlwZSB7WS5JdGVtfSAqLyAoZWwuX2l0ZW0pLmlkKVxuICAgICAgICAgIDogeyB0eXBlOiAncmVtb3ZlZCcgfVxuICAgICAgfSBlbHNlIGlmICghaXNWaXNpYmxlKC8qKiBAdHlwZSB7WS5JdGVtfSAqLyAoZWwuX2l0ZW0pLCBwcmV2U25hcHNob3QpKSB7XG4gICAgICAgIGF0dHJzLnljaGFuZ2UgPSBjb21wdXRlWUNoYW5nZVxuICAgICAgICAgID8gY29tcHV0ZVlDaGFuZ2UoJ2FkZGVkJywgLyoqIEB0eXBlIHtZLkl0ZW19ICovIChlbC5faXRlbSkuaWQpXG4gICAgICAgICAgOiB7IHR5cGU6ICdhZGRlZCcgfVxuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBub2RlID0gc2NoZW1hLm5vZGUoZWwubm9kZU5hbWUsIGF0dHJzLCBjaGlsZHJlbilcbiAgICBtZXRhLm1hcHBpbmcuc2V0KGVsLCBub2RlKVxuICAgIHJldHVybiBub2RlXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICAvLyBhbiBlcnJvciBvY2N1cmVkIHdoaWxlIGNyZWF0aW5nIHRoZSBub2RlLiBUaGlzIGlzIHByb2JhYmx5IGEgcmVzdWx0IG9mIGEgY29uY3VycmVudCBhY3Rpb24uXG4gICAgLyoqIEB0eXBlIHtZLkRvY30gKi8gKGVsLmRvYykudHJhbnNhY3QoKHRyYW5zYWN0aW9uKSA9PiB7XG4gICAgICAvKiogQHR5cGUge1kuSXRlbX0gKi8gKGVsLl9pdGVtKS5kZWxldGUodHJhbnNhY3Rpb24pXG4gICAgfSwgeVN5bmNQbHVnaW5LZXkpXG4gICAgbWV0YS5tYXBwaW5nLmRlbGV0ZShlbClcbiAgICByZXR1cm4gbnVsbFxuICB9XG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7WS5YbWxUZXh0fSB0ZXh0XG4gKiBAcGFyYW0ge2ltcG9ydCgncHJvc2VtaXJyb3ItbW9kZWwnKS5TY2hlbWF9IHNjaGVtYVxuICogQHBhcmFtIHtCaW5kaW5nTWV0YWRhdGF9IF9tZXRhXG4gKiBAcGFyYW0ge1kuU25hcHNob3R9IFtzbmFwc2hvdF1cbiAqIEBwYXJhbSB7WS5TbmFwc2hvdH0gW3ByZXZTbmFwc2hvdF1cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oJ3JlbW92ZWQnIHwgJ2FkZGVkJywgWS5JRCk6YW55fSBbY29tcHV0ZVlDaGFuZ2VdXG4gKiBAcmV0dXJuIHtBcnJheTxQTW9kZWwuTm9kZT58bnVsbH1cbiAqL1xuY29uc3QgY3JlYXRlVGV4dE5vZGVzRnJvbVlUZXh0ID0gKFxuICB0ZXh0LFxuICBzY2hlbWEsXG4gIF9tZXRhLFxuICBzbmFwc2hvdCxcbiAgcHJldlNuYXBzaG90LFxuICBjb21wdXRlWUNoYW5nZVxuKSA9PiB7XG4gIGNvbnN0IG5vZGVzID0gW11cbiAgY29uc3QgZGVsdGFzID0gdGV4dC50b0RlbHRhKHNuYXBzaG90LCBwcmV2U25hcHNob3QsIGNvbXB1dGVZQ2hhbmdlKVxuICB0cnkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVsdGFzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBkZWx0YSA9IGRlbHRhc1tpXVxuICAgICAgbm9kZXMucHVzaChzY2hlbWEudGV4dChkZWx0YS5pbnNlcnQsIGF0dHJpYnV0ZXNUb01hcmtzKGRlbHRhLmF0dHJpYnV0ZXMsIHNjaGVtYSkpKVxuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIC8vIGFuIGVycm9yIG9jY3VyZWQgd2hpbGUgY3JlYXRpbmcgdGhlIG5vZGUuIFRoaXMgaXMgcHJvYmFibHkgYSByZXN1bHQgb2YgYSBjb25jdXJyZW50IGFjdGlvbi5cbiAgICAvKiogQHR5cGUge1kuRG9jfSAqLyAodGV4dC5kb2MpLnRyYW5zYWN0KCh0cmFuc2FjdGlvbikgPT4ge1xuICAgICAgLyoqIEB0eXBlIHtZLkl0ZW19ICovICh0ZXh0Ll9pdGVtKS5kZWxldGUodHJhbnNhY3Rpb24pXG4gICAgfSwgeVN5bmNQbHVnaW5LZXkpXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuICAvLyBAdHMtaWdub3JlXG4gIHJldHVybiBub2Rlc1xufVxuXG4vKipcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5PGFueT59IG5vZGVzIHByb3NlbWlycm9yIG5vZGVcbiAqIEBwYXJhbSB7QmluZGluZ01ldGFkYXRhfSBtZXRhXG4gKiBAcmV0dXJuIHtZLlhtbFRleHR9XG4gKi9cbmNvbnN0IGNyZWF0ZVR5cGVGcm9tVGV4dE5vZGVzID0gKG5vZGVzLCBtZXRhKSA9PiB7XG4gIGNvbnN0IHR5cGUgPSBuZXcgWS5YbWxUZXh0KClcbiAgY29uc3QgZGVsdGEgPSBub2Rlcy5tYXAoKG5vZGUpID0+ICh7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIGluc2VydDogbm9kZS50ZXh0LFxuICAgIGF0dHJpYnV0ZXM6IG1hcmtzVG9BdHRyaWJ1dGVzKG5vZGUubWFya3MsIG1ldGEpXG4gIH0pKVxuICB0eXBlLmFwcGx5RGVsdGEoZGVsdGEpXG4gIG1ldGEubWFwcGluZy5zZXQodHlwZSwgbm9kZXMpXG4gIHJldHVybiB0eXBlXG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7YW55fSBub2RlIHByb3NlbWlycm9yIG5vZGVcbiAqIEBwYXJhbSB7QmluZGluZ01ldGFkYXRhfSBtZXRhXG4gKiBAcmV0dXJuIHtZLlhtbEVsZW1lbnR9XG4gKi9cbmNvbnN0IGNyZWF0ZVR5cGVGcm9tRWxlbWVudE5vZGUgPSAobm9kZSwgbWV0YSkgPT4ge1xuICBjb25zdCB0eXBlID0gbmV3IFkuWG1sRWxlbWVudChub2RlLnR5cGUubmFtZSlcbiAgZm9yIChjb25zdCBrZXkgaW4gbm9kZS5hdHRycykge1xuICAgIGNvbnN0IHZhbCA9IG5vZGUuYXR0cnNba2V5XVxuICAgIGlmICh2YWwgIT09IG51bGwgJiYga2V5ICE9PSAneWNoYW5nZScpIHtcbiAgICAgIHR5cGUuc2V0QXR0cmlidXRlKGtleSwgdmFsKVxuICAgIH1cbiAgfVxuICB0eXBlLmluc2VydChcbiAgICAwLFxuICAgIG5vcm1hbGl6ZVBOb2RlQ29udGVudChub2RlKS5tYXAoKG4pID0+XG4gICAgICBjcmVhdGVUeXBlRnJvbVRleHRPckVsZW1lbnROb2RlKG4sIG1ldGEpXG4gICAgKVxuICApXG4gIG1ldGEubWFwcGluZy5zZXQodHlwZSwgbm9kZSlcbiAgcmV0dXJuIHR5cGVcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtQTW9kZWwuTm9kZXxBcnJheTxQTW9kZWwuTm9kZT59IG5vZGUgcHJvc2VtaXJyb3IgdGV4dCBub2RlXG4gKiBAcGFyYW0ge0JpbmRpbmdNZXRhZGF0YX0gbWV0YVxuICogQHJldHVybiB7WS5YbWxFbGVtZW50fFkuWG1sVGV4dH1cbiAqL1xuY29uc3QgY3JlYXRlVHlwZUZyb21UZXh0T3JFbGVtZW50Tm9kZSA9IChub2RlLCBtZXRhKSA9PlxuICBub2RlIGluc3RhbmNlb2YgQXJyYXlcbiAgICA/IGNyZWF0ZVR5cGVGcm9tVGV4dE5vZGVzKG5vZGUsIG1ldGEpXG4gICAgOiBjcmVhdGVUeXBlRnJvbUVsZW1lbnROb2RlKG5vZGUsIG1ldGEpXG5cbi8qKlxuICogQHBhcmFtIHthbnl9IHZhbFxuICovXG5jb25zdCBpc09iamVjdCA9ICh2YWwpID0+IHR5cGVvZiB2YWwgPT09ICdvYmplY3QnICYmIHZhbCAhPT0gbnVsbFxuXG4vKipcbiAqIEBwYXJhbSB7YW55fSBwYXR0cnNcbiAqIEBwYXJhbSB7YW55fSB5YXR0cnNcbiAqL1xuY29uc3QgZXF1YWxBdHRycyA9IChwYXR0cnMsIHlhdHRycykgPT4ge1xuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocGF0dHJzKS5maWx0ZXIoKGtleSkgPT4gcGF0dHJzW2tleV0gIT09IG51bGwpXG4gIGxldCBlcSA9XG4gICAga2V5cy5sZW5ndGggPT09XG4gICAgICBPYmplY3Qua2V5cyh5YXR0cnMpLmZpbHRlcigoa2V5KSA9PiB5YXR0cnNba2V5XSAhPT0gbnVsbCkubGVuZ3RoXG4gIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGggJiYgZXE7IGkrKykge1xuICAgIGNvbnN0IGtleSA9IGtleXNbaV1cbiAgICBjb25zdCBsID0gcGF0dHJzW2tleV1cbiAgICBjb25zdCByID0geWF0dHJzW2tleV1cbiAgICBlcSA9IGtleSA9PT0gJ3ljaGFuZ2UnIHx8IGwgPT09IHIgfHxcbiAgICAgIChpc09iamVjdChsKSAmJiBpc09iamVjdChyKSAmJiBlcXVhbEF0dHJzKGwsIHIpKVxuICB9XG4gIHJldHVybiBlcVxufVxuXG4vKipcbiAqIEB0eXBlZGVmIHtBcnJheTxBcnJheTxQTW9kZWwuTm9kZT58UE1vZGVsLk5vZGU+fSBOb3JtYWxpemVkUE5vZGVDb250ZW50XG4gKi9cblxuLyoqXG4gKiBAcGFyYW0ge2FueX0gcG5vZGVcbiAqIEByZXR1cm4ge05vcm1hbGl6ZWRQTm9kZUNvbnRlbnR9XG4gKi9cbmNvbnN0IG5vcm1hbGl6ZVBOb2RlQ29udGVudCA9IChwbm9kZSkgPT4ge1xuICBjb25zdCBjID0gcG5vZGUuY29udGVudC5jb250ZW50XG4gIGNvbnN0IHJlcyA9IFtdXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IG4gPSBjW2ldXG4gICAgaWYgKG4uaXNUZXh0KSB7XG4gICAgICBjb25zdCB0ZXh0Tm9kZXMgPSBbXVxuICAgICAgZm9yIChsZXQgdG5vZGUgPSBjW2ldOyBpIDwgYy5sZW5ndGggJiYgdG5vZGUuaXNUZXh0OyB0bm9kZSA9IGNbKytpXSkge1xuICAgICAgICB0ZXh0Tm9kZXMucHVzaCh0bm9kZSlcbiAgICAgIH1cbiAgICAgIGktLVxuICAgICAgcmVzLnB1c2godGV4dE5vZGVzKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXMucHVzaChuKVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbi8qKlxuICogQHBhcmFtIHtZLlhtbFRleHR9IHl0ZXh0XG4gKiBAcGFyYW0ge0FycmF5PGFueT59IHB0ZXh0c1xuICovXG5jb25zdCBlcXVhbFlUZXh0UFRleHQgPSAoeXRleHQsIHB0ZXh0cykgPT4ge1xuICBjb25zdCBkZWx0YSA9IHl0ZXh0LnRvRGVsdGEoKVxuICByZXR1cm4gZGVsdGEubGVuZ3RoID09PSBwdGV4dHMubGVuZ3RoICYmXG4gICAgZGVsdGEuZXZlcnkoLyoqIEB0eXBlIHsoZDphbnksaTpudW1iZXIpID0+IGJvb2xlYW59ICovIChkLCBpKSA9PlxuICAgICAgZC5pbnNlcnQgPT09IC8qKiBAdHlwZSB7YW55fSAqLyAocHRleHRzW2ldKS50ZXh0ICYmXG4gICAgICBvYmplY3Qua2V5cyhkLmF0dHJpYnV0ZXMgfHwge30pLmxlbmd0aCA9PT0gcHRleHRzW2ldLm1hcmtzLmxlbmd0aCAmJlxuICAgICAgb2JqZWN0LmV2ZXJ5KGQuYXR0cmlidXRlcywgKGF0dHIsIC8qKiBAdHlwZSB7c3RyaW5nfSAqLyB5YXR0cm5hbWUpID0+IHtcbiAgICAgICAgY29uc3QgbWFya25hbWUgPSB5YXR0cjJtYXJrbmFtZSh5YXR0cm5hbWUpXG4gICAgICAgIGNvbnN0IHBtYXJrcyA9IHB0ZXh0c1tpXS5tYXJrc1xuXG4gICAgICAgIGNvbnN0IHBtYXJrID0gcG1hcmtzLmZpbmQoLyoqIEBwYXJhbSB7YW55fSBtYXJrICovIG1hcmsgPT4gbWFyay50eXBlLm5hbWUgPT09IG1hcmtuYW1lKVxuXG4gICAgICAgIC8vIEVuc3VyZSB0aGUgcG1hcmsgaXMgcHJlc2VudCBpbiB0aGUgcHRleHRzIGJlZm9yZSBjaGVja2luZyBlcXVhbGl0eS4gV2hlbiByZXBsYWNpbmcgYSBtYXJrIHdpdGggYW5vdGhlciBtYXJrXG4gICAgICAgIC8vIHRoZSBwbWFyayB3aWxsIGJlIG1pc3NpbmcgZnJvbSB0aGUgcHRleHRzIGFuZCB0aGUgZXF1YWxBdHRycyB3aWxsIHRocm93IGFuIGVycm9yLlxuICAgICAgICBpZiAoIXBtYXJrKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZXF1YWxBdHRycyhhdHRyLCBwbWFya3MuZmluZCgvKiogQHBhcmFtIHthbnl9IG1hcmsgKi8gbWFyayA9PiBtYXJrLnR5cGUubmFtZSA9PT0gbWFya25hbWUpPy5hdHRycylcbiAgICAgIH0pXG4gICAgKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7WS5YbWxFbGVtZW50fFkuWG1sVGV4dHxZLlhtbEhvb2t9IHl0eXBlXG4gKiBAcGFyYW0ge2FueXxBcnJheTxhbnk+fSBwbm9kZVxuICovXG5jb25zdCBlcXVhbFlUeXBlUE5vZGUgPSAoeXR5cGUsIHBub2RlKSA9PiB7XG4gIGlmIChcbiAgICB5dHlwZSBpbnN0YW5jZW9mIFkuWG1sRWxlbWVudCAmJiAhKHBub2RlIGluc3RhbmNlb2YgQXJyYXkpICYmXG4gICAgbWF0Y2hOb2RlTmFtZSh5dHlwZSwgcG5vZGUpXG4gICkge1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRDb250ZW50ID0gbm9ybWFsaXplUE5vZGVDb250ZW50KHBub2RlKVxuICAgIHJldHVybiB5dHlwZS5fbGVuZ3RoID09PSBub3JtYWxpemVkQ29udGVudC5sZW5ndGggJiZcbiAgICAgIGVxdWFsQXR0cnMoeXR5cGUuZ2V0QXR0cmlidXRlcygpLCBwbm9kZS5hdHRycykgJiZcbiAgICAgIHl0eXBlLnRvQXJyYXkoKS5ldmVyeSgoeWNoaWxkLCBpKSA9PlxuICAgICAgICBlcXVhbFlUeXBlUE5vZGUoeWNoaWxkLCBub3JtYWxpemVkQ29udGVudFtpXSlcbiAgICAgIClcbiAgfVxuICByZXR1cm4geXR5cGUgaW5zdGFuY2VvZiBZLlhtbFRleHQgJiYgcG5vZGUgaW5zdGFuY2VvZiBBcnJheSAmJlxuICAgIGVxdWFsWVRleHRQVGV4dCh5dHlwZSwgcG5vZGUpXG59XG5cbi8qKlxuICogQHBhcmFtIHtQTW9kZWwuTm9kZSB8IEFycmF5PFBNb2RlbC5Ob2RlPiB8IHVuZGVmaW5lZH0gbWFwcGVkXG4gKiBAcGFyYW0ge1BNb2RlbC5Ob2RlIHwgQXJyYXk8UE1vZGVsLk5vZGU+fSBwY29udGVudFxuICovXG5jb25zdCBtYXBwZWRJZGVudGl0eSA9IChtYXBwZWQsIHBjb250ZW50KSA9PlxuICBtYXBwZWQgPT09IHBjb250ZW50IHx8XG4gIChtYXBwZWQgaW5zdGFuY2VvZiBBcnJheSAmJiBwY29udGVudCBpbnN0YW5jZW9mIEFycmF5ICYmXG4gICAgbWFwcGVkLmxlbmd0aCA9PT0gcGNvbnRlbnQubGVuZ3RoICYmIG1hcHBlZC5ldmVyeSgoYSwgaSkgPT5cbiAgICBwY29udGVudFtpXSA9PT0gYVxuICApKVxuXG4vKipcbiAqIEBwYXJhbSB7WS5YbWxFbGVtZW50fSB5dHlwZVxuICogQHBhcmFtIHtQTW9kZWwuTm9kZX0gcG5vZGVcbiAqIEBwYXJhbSB7QmluZGluZ01ldGFkYXRhfSBtZXRhXG4gKiBAcmV0dXJuIHt7IGZvdW5kTWFwcGVkQ2hpbGQ6IGJvb2xlYW4sIGVxdWFsaXR5RmFjdG9yOiBudW1iZXIgfX1cbiAqL1xuY29uc3QgY29tcHV0ZUNoaWxkRXF1YWxpdHlGYWN0b3IgPSAoeXR5cGUsIHBub2RlLCBtZXRhKSA9PiB7XG4gIGNvbnN0IHlDaGlsZHJlbiA9IHl0eXBlLnRvQXJyYXkoKVxuICBjb25zdCBwQ2hpbGRyZW4gPSBub3JtYWxpemVQTm9kZUNvbnRlbnQocG5vZGUpXG4gIGNvbnN0IHBDaGlsZENudCA9IHBDaGlsZHJlbi5sZW5ndGhcbiAgY29uc3QgeUNoaWxkQ250ID0geUNoaWxkcmVuLmxlbmd0aFxuICBjb25zdCBtaW5DbnQgPSBtYXRoLm1pbih5Q2hpbGRDbnQsIHBDaGlsZENudClcbiAgbGV0IGxlZnQgPSAwXG4gIGxldCByaWdodCA9IDBcbiAgbGV0IGZvdW5kTWFwcGVkQ2hpbGQgPSBmYWxzZVxuICBmb3IgKDsgbGVmdCA8IG1pbkNudDsgbGVmdCsrKSB7XG4gICAgY29uc3QgbGVmdFkgPSB5Q2hpbGRyZW5bbGVmdF1cbiAgICBjb25zdCBsZWZ0UCA9IHBDaGlsZHJlbltsZWZ0XVxuICAgIGlmIChtYXBwZWRJZGVudGl0eShtZXRhLm1hcHBpbmcuZ2V0KGxlZnRZKSwgbGVmdFApKSB7XG4gICAgICBmb3VuZE1hcHBlZENoaWxkID0gdHJ1ZSAvLyBkZWZpbml0ZSAoZ29vZCkgbWF0Y2ghXG4gICAgfSBlbHNlIGlmICghZXF1YWxZVHlwZVBOb2RlKGxlZnRZLCBsZWZ0UCkpIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG4gIGZvciAoOyBsZWZ0ICsgcmlnaHQgPCBtaW5DbnQ7IHJpZ2h0KyspIHtcbiAgICBjb25zdCByaWdodFkgPSB5Q2hpbGRyZW5beUNoaWxkQ250IC0gcmlnaHQgLSAxXVxuICAgIGNvbnN0IHJpZ2h0UCA9IHBDaGlsZHJlbltwQ2hpbGRDbnQgLSByaWdodCAtIDFdXG4gICAgaWYgKG1hcHBlZElkZW50aXR5KG1ldGEubWFwcGluZy5nZXQocmlnaHRZKSwgcmlnaHRQKSkge1xuICAgICAgZm91bmRNYXBwZWRDaGlsZCA9IHRydWVcbiAgICB9IGVsc2UgaWYgKCFlcXVhbFlUeXBlUE5vZGUocmlnaHRZLCByaWdodFApKSB7XG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIGVxdWFsaXR5RmFjdG9yOiBsZWZ0ICsgcmlnaHQsXG4gICAgZm91bmRNYXBwZWRDaGlsZFxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtZLlRleHR9IHl0ZXh0XG4gKi9cbmNvbnN0IHl0ZXh0VHJhbnMgPSAoeXRleHQpID0+IHtcbiAgbGV0IHN0ciA9ICcnXG4gIC8qKlxuICAgKiBAdHlwZSB7WS5JdGVtfG51bGx9XG4gICAqL1xuICBsZXQgbiA9IHl0ZXh0Ll9zdGFydFxuICBjb25zdCBuQXR0cnMgPSB7fVxuICB3aGlsZSAobiAhPT0gbnVsbCkge1xuICAgIGlmICghbi5kZWxldGVkKSB7XG4gICAgICBpZiAobi5jb3VudGFibGUgJiYgbi5jb250ZW50IGluc3RhbmNlb2YgWS5Db250ZW50U3RyaW5nKSB7XG4gICAgICAgIHN0ciArPSBuLmNvbnRlbnQuc3RyXG4gICAgICB9IGVsc2UgaWYgKG4uY29udGVudCBpbnN0YW5jZW9mIFkuQ29udGVudEZvcm1hdCkge1xuICAgICAgICBuQXR0cnNbbi5jb250ZW50LmtleV0gPSBudWxsXG4gICAgICB9XG4gICAgfVxuICAgIG4gPSBuLnJpZ2h0XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBzdHIsXG4gICAgbkF0dHJzXG4gIH1cbn1cblxuLyoqXG4gKiBAdG9kbyB0ZXN0IHRoaXMgbW9yZVxuICpcbiAqIEBwYXJhbSB7WS5UZXh0fSB5dGV4dFxuICogQHBhcmFtIHtBcnJheTxhbnk+fSBwdGV4dHNcbiAqIEBwYXJhbSB7QmluZGluZ01ldGFkYXRhfSBtZXRhXG4gKi9cbmNvbnN0IHVwZGF0ZVlUZXh0ID0gKHl0ZXh0LCBwdGV4dHMsIG1ldGEpID0+IHtcbiAgbWV0YS5tYXBwaW5nLnNldCh5dGV4dCwgcHRleHRzKVxuICBjb25zdCB7IG5BdHRycywgc3RyIH0gPSB5dGV4dFRyYW5zKHl0ZXh0KVxuICBjb25zdCBjb250ZW50ID0gcHRleHRzLm1hcCgocCkgPT4gKHtcbiAgICBpbnNlcnQ6IC8qKiBAdHlwZSB7YW55fSAqLyAocCkudGV4dCxcbiAgICBhdHRyaWJ1dGVzOiBPYmplY3QuYXNzaWduKHt9LCBuQXR0cnMsIG1hcmtzVG9BdHRyaWJ1dGVzKHAubWFya3MsIG1ldGEpKVxuICB9KSlcbiAgY29uc3QgeyBpbnNlcnQsIHJlbW92ZSwgaW5kZXggfSA9IHNpbXBsZURpZmYoXG4gICAgc3RyLFxuICAgIGNvbnRlbnQubWFwKChjKSA9PiBjLmluc2VydCkuam9pbignJylcbiAgKVxuICB5dGV4dC5kZWxldGUoaW5kZXgsIHJlbW92ZSlcbiAgeXRleHQuaW5zZXJ0KGluZGV4LCBpbnNlcnQpXG4gIHl0ZXh0LmFwcGx5RGVsdGEoXG4gICAgY29udGVudC5tYXAoKGMpID0+ICh7IHJldGFpbjogYy5pbnNlcnQubGVuZ3RoLCBhdHRyaWJ1dGVzOiBjLmF0dHJpYnV0ZXMgfSkpXG4gIClcbn1cblxuY29uc3QgaGFzaGVkTWFya05hbWVSZWdleCA9IC8oLiopKC0tW2EtekEtWjAtOSsvPV17OH0pJC9cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd9IGF0dHJOYW1lXG4gKi9cbmV4cG9ydCBjb25zdCB5YXR0cjJtYXJrbmFtZSA9IGF0dHJOYW1lID0+IGhhc2hlZE1hcmtOYW1lUmVnZXguZXhlYyhhdHRyTmFtZSk/LlsxXSA/PyBhdHRyTmFtZVxuXG4vKipcbiAqIEB0b2RvIG1vdmUgdGhpcyB0byBtYXJrc3RvYXR0cmlidXRlc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgYW55Pn0gYXR0cnNcbiAqIEBwYXJhbSB7aW1wb3J0KCdwcm9zZW1pcnJvci1tb2RlbCcpLlNjaGVtYX0gc2NoZW1hXG4gKi9cbmV4cG9ydCBjb25zdCBhdHRyaWJ1dGVzVG9NYXJrcyA9IChhdHRycywgc2NoZW1hKSA9PiB7XG4gIC8qKlxuICAgKiBAdHlwZSB7QXJyYXk8aW1wb3J0KCdwcm9zZW1pcnJvci1tb2RlbCcpLk1hcms+fVxuICAgKi9cbiAgY29uc3QgbWFya3MgPSBbXVxuICBmb3IgKGNvbnN0IG1hcmtOYW1lIGluIGF0dHJzKSB7XG4gICAgLy8gcmVtb3ZlIGhhc2hlcyBpZiBuZWNlc3NhcnlcbiAgICBtYXJrcy5wdXNoKHNjaGVtYS5tYXJrKHlhdHRyMm1hcmtuYW1lKG1hcmtOYW1lKSwgYXR0cnNbbWFya05hbWVdKSlcbiAgfVxuICByZXR1cm4gbWFya3Ncbn1cblxuLyoqXG4gKiBAcGFyYW0ge0FycmF5PGltcG9ydCgncHJvc2VtaXJyb3ItbW9kZWwnKS5NYXJrPn0gbWFya3NcbiAqIEBwYXJhbSB7QmluZGluZ01ldGFkYXRhfSBtZXRhXG4gKi9cbmNvbnN0IG1hcmtzVG9BdHRyaWJ1dGVzID0gKG1hcmtzLCBtZXRhKSA9PiB7XG4gIGNvbnN0IHBhdHRycyA9IHt9XG4gIG1hcmtzLmZvckVhY2goKG1hcmspID0+IHtcbiAgICBpZiAobWFyay50eXBlLm5hbWUgIT09ICd5Y2hhbmdlJykge1xuICAgICAgY29uc3QgaXNPdmVybGFwcGluZyA9IG1hcC5zZXRJZlVuZGVmaW5lZChtZXRhLmlzT01hcmssIG1hcmsudHlwZSwgKCkgPT4gIW1hcmsudHlwZS5leGNsdWRlcyhtYXJrLnR5cGUpKVxuICAgICAgcGF0dHJzW2lzT3ZlcmxhcHBpbmcgPyBgJHttYXJrLnR5cGUubmFtZX0tLSR7dXRpbHMuaGFzaE9mSlNPTihtYXJrLnRvSlNPTigpKX1gIDogbWFyay50eXBlLm5hbWVdID0gbWFyay5hdHRyc1xuICAgIH1cbiAgfSlcbiAgcmV0dXJuIHBhdHRyc1xufVxuXG4vKipcbiAqIFVwZGF0ZSBhIHlEb20gbm9kZSBieSBzeW5jaW5nIHRoZSBjdXJyZW50IGNvbnRlbnQgb2YgdGhlIHByb3NlbWlycm9yIG5vZGUuXG4gKlxuICogVGhpcyBpcyBhIHktcHJvc2VtaXJyb3IgaW50ZXJuYWwgZmVhdHVyZSB0aGF0IHlvdSBjYW4gdXNlIGF0IHlvdXIgb3duIHJpc2suXG4gKlxuICogQHByaXZhdGVcbiAqIEB1bnN0YWJsZVxuICpcbiAqIEBwYXJhbSB7e3RyYW5zYWN0OiBGdW5jdGlvbn19IHlcbiAqIEBwYXJhbSB7WS5YbWxGcmFnbWVudH0geURvbUZyYWdtZW50XG4gKiBAcGFyYW0ge2FueX0gcE5vZGVcbiAqIEBwYXJhbSB7QmluZGluZ01ldGFkYXRhfSBtZXRhXG4gKi9cbmV4cG9ydCBjb25zdCB1cGRhdGVZRnJhZ21lbnQgPSAoeSwgeURvbUZyYWdtZW50LCBwTm9kZSwgbWV0YSkgPT4ge1xuICBpZiAoXG4gICAgeURvbUZyYWdtZW50IGluc3RhbmNlb2YgWS5YbWxFbGVtZW50ICYmXG4gICAgeURvbUZyYWdtZW50Lm5vZGVOYW1lICE9PSBwTm9kZS50eXBlLm5hbWVcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdub2RlIG5hbWUgbWlzbWF0Y2ghJylcbiAgfVxuICBtZXRhLm1hcHBpbmcuc2V0KHlEb21GcmFnbWVudCwgcE5vZGUpXG4gIC8vIHVwZGF0ZSBhdHRyaWJ1dGVzXG4gIGlmICh5RG9tRnJhZ21lbnQgaW5zdGFuY2VvZiBZLlhtbEVsZW1lbnQpIHtcbiAgICBjb25zdCB5RG9tQXR0cnMgPSB5RG9tRnJhZ21lbnQuZ2V0QXR0cmlidXRlcygpXG4gICAgY29uc3QgcEF0dHJzID0gcE5vZGUuYXR0cnNcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBwQXR0cnMpIHtcbiAgICAgIGlmIChwQXR0cnNba2V5XSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoeURvbUF0dHJzW2tleV0gIT09IHBBdHRyc1trZXldICYmIGtleSAhPT0gJ3ljaGFuZ2UnKSB7XG4gICAgICAgICAgeURvbUZyYWdtZW50LnNldEF0dHJpYnV0ZShrZXksIHBBdHRyc1trZXldKVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB5RG9tRnJhZ21lbnQucmVtb3ZlQXR0cmlidXRlKGtleSlcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gcmVtb3ZlIGFsbCBrZXlzIHRoYXQgYXJlIG5vIGxvbmdlciBpbiBwQXR0cnNcbiAgICBmb3IgKGNvbnN0IGtleSBpbiB5RG9tQXR0cnMpIHtcbiAgICAgIGlmIChwQXR0cnNba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHlEb21GcmFnbWVudC5yZW1vdmVBdHRyaWJ1dGUoa2V5KVxuICAgICAgfVxuICAgIH1cbiAgfVxuICAvLyB1cGRhdGUgY2hpbGRyZW5cbiAgY29uc3QgcENoaWxkcmVuID0gbm9ybWFsaXplUE5vZGVDb250ZW50KHBOb2RlKVxuICBjb25zdCBwQ2hpbGRDbnQgPSBwQ2hpbGRyZW4ubGVuZ3RoXG4gIGNvbnN0IHlDaGlsZHJlbiA9IHlEb21GcmFnbWVudC50b0FycmF5KClcbiAgY29uc3QgeUNoaWxkQ250ID0geUNoaWxkcmVuLmxlbmd0aFxuICBjb25zdCBtaW5DbnQgPSBtYXRoLm1pbihwQ2hpbGRDbnQsIHlDaGlsZENudClcbiAgbGV0IGxlZnQgPSAwXG4gIGxldCByaWdodCA9IDBcbiAgLy8gZmluZCBudW1iZXIgb2YgbWF0Y2hpbmcgZWxlbWVudHMgZnJvbSBsZWZ0XG4gIGZvciAoOyBsZWZ0IDwgbWluQ250OyBsZWZ0KyspIHtcbiAgICBjb25zdCBsZWZ0WSA9IHlDaGlsZHJlbltsZWZ0XVxuICAgIGNvbnN0IGxlZnRQID0gcENoaWxkcmVuW2xlZnRdXG4gICAgaWYgKCFtYXBwZWRJZGVudGl0eShtZXRhLm1hcHBpbmcuZ2V0KGxlZnRZKSwgbGVmdFApKSB7XG4gICAgICBpZiAoZXF1YWxZVHlwZVBOb2RlKGxlZnRZLCBsZWZ0UCkpIHtcbiAgICAgICAgLy8gdXBkYXRlIG1hcHBpbmdcbiAgICAgICAgbWV0YS5tYXBwaW5nLnNldChsZWZ0WSwgbGVmdFApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cbiAgfVxuICAvLyBmaW5kIG51bWJlciBvZiBtYXRjaGluZyBlbGVtZW50cyBmcm9tIHJpZ2h0XG4gIGZvciAoOyByaWdodCArIGxlZnQgKyAxIDwgbWluQ250OyByaWdodCsrKSB7XG4gICAgY29uc3QgcmlnaHRZID0geUNoaWxkcmVuW3lDaGlsZENudCAtIHJpZ2h0IC0gMV1cbiAgICBjb25zdCByaWdodFAgPSBwQ2hpbGRyZW5bcENoaWxkQ250IC0gcmlnaHQgLSAxXVxuICAgIGlmICghbWFwcGVkSWRlbnRpdHkobWV0YS5tYXBwaW5nLmdldChyaWdodFkpLCByaWdodFApKSB7XG4gICAgICBpZiAoZXF1YWxZVHlwZVBOb2RlKHJpZ2h0WSwgcmlnaHRQKSkge1xuICAgICAgICAvLyB1cGRhdGUgbWFwcGluZ1xuICAgICAgICBtZXRhLm1hcHBpbmcuc2V0KHJpZ2h0WSwgcmlnaHRQKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgeS50cmFuc2FjdCgoKSA9PiB7XG4gICAgLy8gdHJ5IHRvIGNvbXBhcmUgYW5kIHVwZGF0ZVxuICAgIHdoaWxlICh5Q2hpbGRDbnQgLSBsZWZ0IC0gcmlnaHQgPiAwICYmIHBDaGlsZENudCAtIGxlZnQgLSByaWdodCA+IDApIHtcbiAgICAgIGNvbnN0IGxlZnRZID0geUNoaWxkcmVuW2xlZnRdXG4gICAgICBjb25zdCBsZWZ0UCA9IHBDaGlsZHJlbltsZWZ0XVxuICAgICAgY29uc3QgcmlnaHRZID0geUNoaWxkcmVuW3lDaGlsZENudCAtIHJpZ2h0IC0gMV1cbiAgICAgIGNvbnN0IHJpZ2h0UCA9IHBDaGlsZHJlbltwQ2hpbGRDbnQgLSByaWdodCAtIDFdXG4gICAgICBpZiAobGVmdFkgaW5zdGFuY2VvZiBZLlhtbFRleHQgJiYgbGVmdFAgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICBpZiAoIWVxdWFsWVRleHRQVGV4dChsZWZ0WSwgbGVmdFApKSB7XG4gICAgICAgICAgdXBkYXRlWVRleHQobGVmdFksIGxlZnRQLCBtZXRhKVxuICAgICAgICB9XG4gICAgICAgIGxlZnQgKz0gMVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IHVwZGF0ZUxlZnQgPSBsZWZ0WSBpbnN0YW5jZW9mIFkuWG1sRWxlbWVudCAmJlxuICAgICAgICAgIG1hdGNoTm9kZU5hbWUobGVmdFksIGxlZnRQKVxuICAgICAgICBsZXQgdXBkYXRlUmlnaHQgPSByaWdodFkgaW5zdGFuY2VvZiBZLlhtbEVsZW1lbnQgJiZcbiAgICAgICAgICBtYXRjaE5vZGVOYW1lKHJpZ2h0WSwgcmlnaHRQKVxuICAgICAgICBpZiAodXBkYXRlTGVmdCAmJiB1cGRhdGVSaWdodCkge1xuICAgICAgICAgIC8vIGRlY2lkZSB3aGljaCB3aGljaCBlbGVtZW50IHRvIHVwZGF0ZVxuICAgICAgICAgIGNvbnN0IGVxdWFsaXR5TGVmdCA9IGNvbXB1dGVDaGlsZEVxdWFsaXR5RmFjdG9yKFxuICAgICAgICAgICAgLyoqIEB0eXBlIHtZLlhtbEVsZW1lbnR9ICovIChsZWZ0WSksXG4gICAgICAgICAgICAvKiogQHR5cGUge1BNb2RlbC5Ob2RlfSAqLyAobGVmdFApLFxuICAgICAgICAgICAgbWV0YVxuICAgICAgICAgIClcbiAgICAgICAgICBjb25zdCBlcXVhbGl0eVJpZ2h0ID0gY29tcHV0ZUNoaWxkRXF1YWxpdHlGYWN0b3IoXG4gICAgICAgICAgICAvKiogQHR5cGUge1kuWG1sRWxlbWVudH0gKi8gKHJpZ2h0WSksXG4gICAgICAgICAgICAvKiogQHR5cGUge1BNb2RlbC5Ob2RlfSAqLyAocmlnaHRQKSxcbiAgICAgICAgICAgIG1ldGFcbiAgICAgICAgICApXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgZXF1YWxpdHlMZWZ0LmZvdW5kTWFwcGVkQ2hpbGQgJiYgIWVxdWFsaXR5UmlnaHQuZm91bmRNYXBwZWRDaGlsZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdXBkYXRlUmlnaHQgPSBmYWxzZVxuICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAhZXF1YWxpdHlMZWZ0LmZvdW5kTWFwcGVkQ2hpbGQgJiYgZXF1YWxpdHlSaWdodC5mb3VuZE1hcHBlZENoaWxkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB1cGRhdGVMZWZ0ID0gZmFsc2VcbiAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgZXF1YWxpdHlMZWZ0LmVxdWFsaXR5RmFjdG9yIDwgZXF1YWxpdHlSaWdodC5lcXVhbGl0eUZhY3RvclxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdXBkYXRlTGVmdCA9IGZhbHNlXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVwZGF0ZVJpZ2h0ID0gZmFsc2VcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVwZGF0ZUxlZnQpIHtcbiAgICAgICAgICB1cGRhdGVZRnJhZ21lbnQoXG4gICAgICAgICAgICB5LFxuICAgICAgICAgICAgLyoqIEB0eXBlIHtZLlhtbEZyYWdtZW50fSAqLyAobGVmdFkpLFxuICAgICAgICAgICAgLyoqIEB0eXBlIHtQTW9kZWwuTm9kZX0gKi8gKGxlZnRQKSxcbiAgICAgICAgICAgIG1ldGFcbiAgICAgICAgICApXG4gICAgICAgICAgbGVmdCArPSAxXG4gICAgICAgIH0gZWxzZSBpZiAodXBkYXRlUmlnaHQpIHtcbiAgICAgICAgICB1cGRhdGVZRnJhZ21lbnQoXG4gICAgICAgICAgICB5LFxuICAgICAgICAgICAgLyoqIEB0eXBlIHtZLlhtbEZyYWdtZW50fSAqLyAocmlnaHRZKSxcbiAgICAgICAgICAgIC8qKiBAdHlwZSB7UE1vZGVsLk5vZGV9ICovIChyaWdodFApLFxuICAgICAgICAgICAgbWV0YVxuICAgICAgICAgIClcbiAgICAgICAgICByaWdodCArPSAxXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWV0YS5tYXBwaW5nLmRlbGV0ZSh5RG9tRnJhZ21lbnQuZ2V0KGxlZnQpKVxuICAgICAgICAgIHlEb21GcmFnbWVudC5kZWxldGUobGVmdCwgMSlcbiAgICAgICAgICB5RG9tRnJhZ21lbnQuaW5zZXJ0KGxlZnQsIFtcbiAgICAgICAgICAgIGNyZWF0ZVR5cGVGcm9tVGV4dE9yRWxlbWVudE5vZGUobGVmdFAsIG1ldGEpXG4gICAgICAgICAgXSlcbiAgICAgICAgICBsZWZ0ICs9IDFcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCB5RGVsTGVuID0geUNoaWxkQ250IC0gbGVmdCAtIHJpZ2h0XG4gICAgaWYgKFxuICAgICAgeUNoaWxkQ250ID09PSAxICYmIHBDaGlsZENudCA9PT0gMCAmJiB5Q2hpbGRyZW5bMF0gaW5zdGFuY2VvZiBZLlhtbFRleHRcbiAgICApIHtcbiAgICAgIG1ldGEubWFwcGluZy5kZWxldGUoeUNoaWxkcmVuWzBdKVxuICAgICAgLy8gRWRnZSBjYXNlIGhhbmRsaW5nIGh0dHBzOi8vZ2l0aHViLmNvbS95anMveS1wcm9zZW1pcnJvci9pc3N1ZXMvMTA4XG4gICAgICAvLyBPbmx5IGRlbGV0ZSB0aGUgY29udGVudCBvZiB0aGUgWS5UZXh0IHRvIHJldGFpbiByZW1vdGUgY2hhbmdlcyBvbiB0aGUgc2FtZSBZLlRleHQgb2JqZWN0XG4gICAgICB5Q2hpbGRyZW5bMF0uZGVsZXRlKDAsIHlDaGlsZHJlblswXS5sZW5ndGgpXG4gICAgfSBlbHNlIGlmICh5RGVsTGVuID4gMCkge1xuICAgICAgeURvbUZyYWdtZW50LnNsaWNlKGxlZnQsIGxlZnQgKyB5RGVsTGVuKS5mb3JFYWNoKHR5cGUgPT4gbWV0YS5tYXBwaW5nLmRlbGV0ZSh0eXBlKSlcbiAgICAgIHlEb21GcmFnbWVudC5kZWxldGUobGVmdCwgeURlbExlbilcbiAgICB9XG4gICAgaWYgKGxlZnQgKyByaWdodCA8IHBDaGlsZENudCkge1xuICAgICAgY29uc3QgaW5zID0gW11cbiAgICAgIGZvciAobGV0IGkgPSBsZWZ0OyBpIDwgcENoaWxkQ250IC0gcmlnaHQ7IGkrKykge1xuICAgICAgICBpbnMucHVzaChjcmVhdGVUeXBlRnJvbVRleHRPckVsZW1lbnROb2RlKHBDaGlsZHJlbltpXSwgbWV0YSkpXG4gICAgICB9XG4gICAgICB5RG9tRnJhZ21lbnQuaW5zZXJ0KGxlZnQsIGlucylcbiAgICB9XG4gIH0sIHlTeW5jUGx1Z2luS2V5KVxufVxuXG4vKipcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtZLlhtbEVsZW1lbnR9IHlFbGVtZW50XG4gKiBAcGFyYW0ge2FueX0gcE5vZGUgUHJvc2VtaXJyb3IgTm9kZVxuICovXG5jb25zdCBtYXRjaE5vZGVOYW1lID0gKHlFbGVtZW50LCBwTm9kZSkgPT5cbiAgIShwTm9kZSBpbnN0YW5jZW9mIEFycmF5KSAmJiB5RWxlbWVudC5ub2RlTmFtZSA9PT0gcE5vZGUudHlwZS5uYW1lXG4iLCAiaW1wb3J0IHsgdXBkYXRlWUZyYWdtZW50LCBjcmVhdGVOb2RlRnJvbVlFbGVtZW50LCB5YXR0cjJtYXJrbmFtZSwgY3JlYXRlRW1wdHlNZXRhIH0gZnJvbSAnLi9wbHVnaW5zL3N5bmMtcGx1Z2luLmpzJyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5pbXBvcnQgeyB5U3luY1BsdWdpbktleSB9IGZyb20gJy4vcGx1Z2lucy9rZXlzLmpzJ1xuaW1wb3J0ICogYXMgWSBmcm9tICd5anMnXG5pbXBvcnQgeyBFZGl0b3JWaWV3IH0gZnJvbSAncHJvc2VtaXJyb3ItdmlldycgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuaW1wb3J0IHsgTm9kZSwgU2NoZW1hLCBGcmFnbWVudCB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5pbXBvcnQgKiBhcyBlcnJvciBmcm9tICdsaWIwL2Vycm9yJ1xuaW1wb3J0ICogYXMgbWFwIGZyb20gJ2xpYjAvbWFwJ1xuaW1wb3J0ICogYXMgZXZlbnRsb29wIGZyb20gJ2xpYjAvZXZlbnRsb29wJ1xuXG4vKipcbiAqIEVpdGhlciBhIG5vZGUgaWYgdHlwZSBpcyBZWG1sRWxlbWVudCBvciBhbiBBcnJheSBvZiB0ZXh0IG5vZGVzIGlmIFlYbWxUZXh0XG4gKiBAdHlwZWRlZiB7TWFwPFkuQWJzdHJhY3RUeXBlLCBOb2RlIHwgQXJyYXk8Tm9kZT4+fSBQcm9zZW1pcnJvck1hcHBpbmdcbiAqL1xuXG4vKipcbiAqIElzIG51bGwgaWYgbm8gdGltZW91dCBpcyBpbiBwcm9ncmVzcy5cbiAqIElzIGRlZmluZWQgaWYgYSB0aW1lb3V0IGlzIGluIHByb2dyZXNzLlxuICogTWFwcyBmcm9tIHZpZXdcbiAqIEB0eXBlIHtNYXA8RWRpdG9yVmlldywgTWFwPGFueSwgYW55Pj58bnVsbH1cbiAqL1xubGV0IHZpZXdzVG9VcGRhdGUgPSBudWxsXG5cbmNsYXNzIE1ldGFFbnRyeSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0VkaXRvclZpZXd9IHZpZXdcbiAgICogQHBhcmFtIHthbnl9IGtleVxuICAgKiBAcGFyYW0ge2FueX0gdmFsdWVcbiAgICovXG4gIGNvbnN0cnVjdG9yICh2aWV3LCBrZXksIHZhbHVlKSB7XG4gICAgdGhpcy52aWV3ID0gdmlld1xuICAgIHRoaXMua2V5ID0ga2V5XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlXG4gIH1cblxuICBhcHBseSAoKSB7XG4gICAgY29uc3Qgc3luY1N0YXRlID0geVN5bmNQbHVnaW5LZXkuZ2V0U3RhdGUodGhpcy52aWV3LnN0YXRlKVxuICAgIGlmIChzeW5jU3RhdGUgJiYgc3luY1N0YXRlLmJpbmRpbmcgJiYgIXN5bmNTdGF0ZS5iaW5kaW5nLmlzRGVzdHJveWVkKSB7XG4gICAgICBjb25zdCB0ciA9IHRoaXMudmlldy5zdGF0ZS50clxuICAgICAgdHIuc2V0TWV0YSh0aGlzLmtleSwgdGhpcy52YWx1ZSlcbiAgICAgIHRoaXMudmlldy5kaXNwYXRjaCh0cilcbiAgICB9XG4gIH1cbn1cblxuY2xhc3MgTWV0YUVudHJpZXNRdWV1ZSB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5PE1ldGFFbnRyeT59IFtlbnRyaWVzPVtdXVxuICAgKi9cbiAgY29uc3RydWN0b3IgKGVudHJpZXMgPSBbXSkge1xuICAgIHRoaXMuZW50cmllcyA9IGVudHJpZXNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtNZXRhRW50cnl8dW5kZWZpbmVkfVxuICAgKi9cbiAgZ2V0Rmlyc3QgKCkge1xuICAgIHJldHVybiB0aGlzLmVudHJpZXNbMF1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtNZXRhRW50cnl8dW5kZWZpbmVkfVxuICAgKi9cbiAgZGVxdWV1ZUZpcnN0ICgpIHtcbiAgICByZXR1cm4gdGhpcy5lbnRyaWVzLnNoaWZ0KClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaXNFbXB0eSAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZW50cmllcy5sZW5ndGggPT09IDBcbiAgfVxuXG4gIHN0YXRpYyBmcm9tVmlld3NUb1VwZGF0ZSAoKSB7XG4gICAgY29uc3QgdXBzID0gLyoqIEB0eXBlIHtNYXA8RWRpdG9yVmlldywgTWFwPGFueSwgYW55Pj59ICovICh2aWV3c1RvVXBkYXRlKVxuICAgIHZpZXdzVG9VcGRhdGUgPSBudWxsXG4gICAgY29uc3QgZW50cmllcyA9IFtdXG4gICAgdXBzLmZvckVhY2goKG1ldGFzLCB2aWV3KSA9PiB7XG4gICAgICBtZXRhcy5mb3JFYWNoKCh2YWx1ZSwga2V5KSA9PiB7XG4gICAgICAgIGVudHJpZXMucHVzaChuZXcgTWV0YUVudHJ5KHZpZXcsIGtleSwgdmFsdWUpKVxuICAgICAgfSlcbiAgICB9KVxuICAgIHJldHVybiBuZXcgTWV0YUVudHJpZXNRdWV1ZShlbnRyaWVzKVxuICB9XG59XG5cbi8qKlxuICogRGlzcGF0Y2ggcXVldWVkIHBsdWdpbiBtZXRhZGF0YSBpbiBvcmRlciwgcmV0cnlpbmcgb25seSB0aGUgcmVtYWluaW5nXG4gKiBlbnRyaWVzIGlmIGEgdHJhbnNhY3Rpb24gYmVjb21lcyBzdGFsZSB3aGlsZSB0aGUgYXN5bmMgcXVldWUgaXMgZmx1c2hpbmcuXG4gKlxuICogQ3Vyc29yIGF3YXJlbmVzcyB1cGRhdGVzIGFyZSBkZWNvcmF0aW9uLW9ubHkgcmVmcmVzaGVzLiBJZiBhIHJlYWwgZG9jdW1lbnRcbiAqIHRyYW5zYWN0aW9uIGxhbmRzIGJlZm9yZSBvbmUgb2YgdGhlc2UgcXVldWVkIG1ldGEgdHJhbnNhY3Rpb25zIGlzIGFwcGxpZWQsXG4gKiBQcm9zZU1pcnJvciBjYW4gcmVqZWN0IGl0IHdpdGggYSBSYW5nZUVycm9yLiBJbiB0aGF0IGNhc2Ugd2UgcmVzY2hlZHVsZSB0aGVcbiAqIHJlbWFpbmluZyBlbnRyaWVzIG9uIHRoZSBuZXh0IHRpY2suIElmIHRoZSBmaXJzdCByZW1haW5pbmcgZW50cnkgZmFpbHMgYWdhaW5cbiAqIG9uIHJldHJ5LCB3ZSBkcm9wIHRoYXQgZW50cnkgYW5kIGNvbnRpbnVlIHdpdGggdGhlIHJlc3Qgb2YgdGhlIHF1ZXVlIGluc3RlYWRcbiAqIG9mIHJldHJ5aW5nIGZvcmV2ZXIgb3IgY3Jhc2hpbmcgdGhlIGVkaXRvci5cbiAqXG4gKiBAcGFyYW0ge01ldGFFbnRyaWVzUXVldWV9IFttZXRhRW50cmllcz1NZXRhRW50cmllc1F1ZXVlLmZyb21WaWV3c1RvVXBkYXRlKCldXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc1JldHJ5PWZhbHNlXVxuICovXG5jb25zdCB1cGRhdGVNZXRhcyA9IChtZXRhRW50cmllcyA9IE1ldGFFbnRyaWVzUXVldWUuZnJvbVZpZXdzVG9VcGRhdGUoKSwgaXNSZXRyeSA9IGZhbHNlKSA9PiB7XG4gIGxldCBpc0ZpcnN0ID0gdHJ1ZVxuICB3aGlsZSAoIW1ldGFFbnRyaWVzLmlzRW1wdHkoKSkge1xuICAgIGNvbnN0IG1ldGFFbnRyeSA9IG1ldGFFbnRyaWVzLmdldEZpcnN0KClcbiAgICB0cnkge1xuICAgICAgbWV0YUVudHJ5LmFwcGx5KClcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIC8vIFByb3NlTWlycm9yIHRocm93cyBhIFJhbmdlRXJyb3Igd2hlbiB0aGlzIHRyYW5zYWN0aW9uIHdhcyBjcmVhdGVkIGZyb21cbiAgICAgIC8vIGFuIG9sZGVyIHN0YXRlIGFuZCBhbm90aGVyIHRyYW5zYWN0aW9uIGNoYW5nZWQgdGhlIGRvY3VtZW50IGJlZm9yZSB0aGlzXG4gICAgICAvLyBtZXRhLW9ubHkgZGlzcGF0Y2ggd2FzIGFwcGxpZWQgKFwiQXBwbHlpbmcgYSBtaXNtYXRjaGVkIHRyYW5zYWN0aW9uXCIpLlxuICAgICAgaWYgKGVyciBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpIHtcbiAgICAgICAgaWYgKGlzUmV0cnkgJiYgaXNGaXJzdCkge1xuICAgICAgICAgIC8vIERyb3AgdGhlIHJlcGVhdGVkbHkgc3RhbGUgZW50cnkgc28gdGhlIHF1ZXVlIGNhbiBjb250aW51ZSBmbHVzaGluZy5cbiAgICAgICAgICBtZXRhRW50cmllcy5kZXF1ZXVlRmlyc3QoKVxuICAgICAgICB9XG4gICAgICAgIGlmICghbWV0YUVudHJpZXMuaXNFbXB0eSgpKSB7XG4gICAgICAgICAgZXZlbnRsb29wLnRpbWVvdXQoMCwgKCkgPT4gdXBkYXRlTWV0YXMobWV0YUVudHJpZXMsIHRydWUpKVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgdGhyb3cgZXJyXG4gICAgfVxuICAgIGlzRmlyc3QgPSBmYWxzZVxuICAgIG1ldGFFbnRyaWVzLmRlcXVldWVGaXJzdCgpXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNldE1ldGEgPSAodmlldywga2V5LCB2YWx1ZSkgPT4ge1xuICBpZiAoIXZpZXdzVG9VcGRhdGUpIHtcbiAgICB2aWV3c1RvVXBkYXRlID0gbmV3IE1hcCgpXG4gICAgLy8gQXdhcmVuZXNzIGxpc3RlbmVycyBjYW4gZmlyZSBpbiBidXJzdHMsIHNvIGJhdGNoIHRoZW0gaW50byBvbmUgdGljay5cbiAgICBldmVudGxvb3AudGltZW91dCgwLCB1cGRhdGVNZXRhcylcbiAgfVxuICBtYXAuc2V0SWZVbmRlZmluZWQodmlld3NUb1VwZGF0ZSwgdmlldywgbWFwLmNyZWF0ZSkuc2V0KGtleSwgdmFsdWUpXG59XG5cbi8qKlxuICogVHJhbnNmb3JtcyBhIFByb3NlbWlycm9yIGJhc2VkIGFic29sdXRlIHBvc2l0aW9uIHRvIGEgWWpzIEN1cnNvciAocmVsYXRpdmUgcG9zaXRpb24gaW4gdGhlIFlqcyBtb2RlbCkuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IHBvc1xuICogQHBhcmFtIHtZLlhtbEZyYWdtZW50fSB0eXBlXG4gKiBAcGFyYW0ge1Byb3NlbWlycm9yTWFwcGluZ30gbWFwcGluZ1xuICogQHJldHVybiB7YW55fSByZWxhdGl2ZSBwb3NpdGlvblxuICovXG5leHBvcnQgY29uc3QgYWJzb2x1dGVQb3NpdGlvblRvUmVsYXRpdmVQb3NpdGlvbiA9IChwb3MsIHR5cGUsIG1hcHBpbmcpID0+IHtcbiAgaWYgKHBvcyA9PT0gMCkge1xuICAgIHJldHVybiBZLmNyZWF0ZVJlbGF0aXZlUG9zaXRpb25Gcm9tVHlwZUluZGV4KHR5cGUsIDAsIC0xKVxuICB9XG4gIC8qKlxuICAgKiBAdHlwZSB7YW55fVxuICAgKi9cbiAgbGV0IG4gPSB0eXBlLl9maXJzdCA9PT0gbnVsbCA/IG51bGwgOiAvKiogQHR5cGUge1kuQ29udGVudFR5cGV9ICovICh0eXBlLl9maXJzdC5jb250ZW50KS50eXBlXG4gIHdoaWxlIChuICE9PSBudWxsICYmIHR5cGUgIT09IG4pIHtcbiAgICBpZiAobiBpbnN0YW5jZW9mIFkuWG1sVGV4dCkge1xuICAgICAgaWYgKG4uX2xlbmd0aCA+PSBwb3MpIHtcbiAgICAgICAgcmV0dXJuIFkuY3JlYXRlUmVsYXRpdmVQb3NpdGlvbkZyb21UeXBlSW5kZXgobiwgcG9zLCAtMSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBvcyAtPSBuLl9sZW5ndGhcbiAgICAgIH1cbiAgICAgIGlmIChuLl9pdGVtICE9PSBudWxsICYmIG4uX2l0ZW0ubmV4dCAhPT0gbnVsbCkge1xuICAgICAgICBuID0gLyoqIEB0eXBlIHtZLkNvbnRlbnRUeXBlfSAqLyAobi5faXRlbS5uZXh0LmNvbnRlbnQpLnR5cGVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICBuID0gbi5faXRlbSA9PT0gbnVsbCA/IG51bGwgOiBuLl9pdGVtLnBhcmVudFxuICAgICAgICAgIHBvcy0tXG4gICAgICAgIH0gd2hpbGUgKG4gIT09IHR5cGUgJiYgbiAhPT0gbnVsbCAmJiBuLl9pdGVtICE9PSBudWxsICYmIG4uX2l0ZW0ubmV4dCA9PT0gbnVsbClcbiAgICAgICAgaWYgKG4gIT09IG51bGwgJiYgbiAhPT0gdHlwZSkge1xuICAgICAgICAgIC8vIEB0cy1nbm9yZSB3ZSBrbm93IHRoYXQgbi5uZXh0ICE9PSBudWxsIGJlY2F1c2Ugb2YgYWJvdmUgbG9vcCBjb25kaXRpdGlvblxuICAgICAgICAgIG4gPSBuLl9pdGVtID09PSBudWxsID8gbnVsbCA6IC8qKiBAdHlwZSB7WS5Db250ZW50VHlwZX0gKi8gKC8qKiBAdHlwZSBZLkl0ZW0gKi8gKG4uX2l0ZW0ubmV4dCkuY29udGVudCkudHlwZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHBOb2RlU2l6ZSA9IC8qKiBAdHlwZSB7YW55fSAqLyAobWFwcGluZy5nZXQobikgfHwgeyBub2RlU2l6ZTogMCB9KS5ub2RlU2l6ZVxuICAgICAgaWYgKG4uX2ZpcnN0ICE9PSBudWxsICYmIHBvcyA8IHBOb2RlU2l6ZSkge1xuICAgICAgICBuID0gLyoqIEB0eXBlIHtZLkNvbnRlbnRUeXBlfSAqLyAobi5fZmlyc3QuY29udGVudCkudHlwZVxuICAgICAgICBwb3MtLVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHBvcyA9PT0gMSAmJiBuLl9sZW5ndGggPT09IDAgJiYgcE5vZGVTaXplID4gMSkge1xuICAgICAgICAgIC8vIGVkZ2UgY2FzZSwgc2hvdWxkIGVuZCBpbiB0aGlzIHBhcmFncmFwaFxuICAgICAgICAgIHJldHVybiBuZXcgWS5SZWxhdGl2ZVBvc2l0aW9uKG4uX2l0ZW0gPT09IG51bGwgPyBudWxsIDogbi5faXRlbS5pZCwgbi5faXRlbSA9PT0gbnVsbCA/IFkuZmluZFJvb3RUeXBlS2V5KG4pIDogbnVsbCwgbnVsbClcbiAgICAgICAgfVxuICAgICAgICBwb3MgLT0gcE5vZGVTaXplXG4gICAgICAgIGlmIChuLl9pdGVtICE9PSBudWxsICYmIG4uX2l0ZW0ubmV4dCAhPT0gbnVsbCkge1xuICAgICAgICAgIG4gPSAvKiogQHR5cGUge1kuQ29udGVudFR5cGV9ICovIChuLl9pdGVtLm5leHQuY29udGVudCkudHlwZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChwb3MgPT09IDApIHtcbiAgICAgICAgICAgIC8vIHNldCB0byBlbmQgb2Ygbi5wYXJlbnRcbiAgICAgICAgICAgIG4gPSBuLl9pdGVtID09PSBudWxsID8gbiA6IG4uX2l0ZW0ucGFyZW50XG4gICAgICAgICAgICByZXR1cm4gbmV3IFkuUmVsYXRpdmVQb3NpdGlvbihuLl9pdGVtID09PSBudWxsID8gbnVsbCA6IG4uX2l0ZW0uaWQsIG4uX2l0ZW0gPT09IG51bGwgPyBZLmZpbmRSb290VHlwZUtleShuKSA6IG51bGwsIG51bGwpXG4gICAgICAgICAgfVxuICAgICAgICAgIGRvIHtcbiAgICAgICAgICAgIG4gPSAvKiogQHR5cGUge1kuSXRlbX0gKi8gKG4uX2l0ZW0pLnBhcmVudFxuICAgICAgICAgICAgcG9zLS1cbiAgICAgICAgICB9IHdoaWxlIChuICE9PSB0eXBlICYmIC8qKiBAdHlwZSB7WS5JdGVtfSAqLyAobi5faXRlbSkubmV4dCA9PT0gbnVsbClcbiAgICAgICAgICAvLyBpZiBuIGlzIG51bGwgYXQgdGhpcyBwb2ludCwgd2UgaGF2ZSBhbiB1bmV4cGVjdGVkIGNhc2VcbiAgICAgICAgICBpZiAobiAhPT0gdHlwZSkge1xuICAgICAgICAgICAgLy8gV2Uga25vdyB0aGF0IG4uX2l0ZW0ubmV4dCBpcyBkZWZpbmVkIGJlY2F1c2Ugb2YgYWJvdmUgbG9vcCBjb25kaXRpb25cbiAgICAgICAgICAgIG4gPSAvKiogQHR5cGUge1kuQ29udGVudFR5cGV9ICovICgvKiogQHR5cGUge1kuSXRlbX0gKi8gKC8qKiBAdHlwZSB7WS5JdGVtfSAqLyAobi5faXRlbSkubmV4dCkuY29udGVudCkudHlwZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobiA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgZXJyb3IudW5leHBlY3RlZENhc2UoKVxuICAgIH1cbiAgICBpZiAocG9zID09PSAwICYmIG4uY29uc3RydWN0b3IgIT09IFkuWG1sVGV4dCAmJiBuICE9PSB0eXBlKSB7IC8vIFRPRE86IHNldCB0byA8PSAwXG4gICAgICByZXR1cm4gY3JlYXRlUmVsYXRpdmVQb3NpdGlvbihuLl9pdGVtLnBhcmVudCwgbi5faXRlbSlcbiAgICB9XG4gIH1cbiAgcmV0dXJuIFkuY3JlYXRlUmVsYXRpdmVQb3NpdGlvbkZyb21UeXBlSW5kZXgodHlwZSwgdHlwZS5fbGVuZ3RoLCAtMSlcbn1cblxuY29uc3QgY3JlYXRlUmVsYXRpdmVQb3NpdGlvbiA9ICh0eXBlLCBpdGVtKSA9PiB7XG4gIGxldCB0eXBlaWQgPSBudWxsXG4gIGxldCB0bmFtZSA9IG51bGxcbiAgaWYgKHR5cGUuX2l0ZW0gPT09IG51bGwpIHtcbiAgICB0bmFtZSA9IFkuZmluZFJvb3RUeXBlS2V5KHR5cGUpXG4gIH0gZWxzZSB7XG4gICAgdHlwZWlkID0gWS5jcmVhdGVJRCh0eXBlLl9pdGVtLmlkLmNsaWVudCwgdHlwZS5faXRlbS5pZC5jbG9jaylcbiAgfVxuICByZXR1cm4gbmV3IFkuUmVsYXRpdmVQb3NpdGlvbih0eXBlaWQsIHRuYW1lLCBpdGVtLmlkKVxufVxuXG4vKipcbiAqIEBwYXJhbSB7WS5Eb2N9IHlcbiAqIEBwYXJhbSB7WS5YbWxGcmFnbWVudH0gZG9jdW1lbnRUeXBlIFRvcCBsZXZlbCB0eXBlIHRoYXQgaXMgYm91bmQgdG8gcFZpZXdcbiAqIEBwYXJhbSB7YW55fSByZWxQb3MgRW5jb2RlZCBZanMgYmFzZWQgcmVsYXRpdmUgcG9zaXRpb25cbiAqIEBwYXJhbSB7UHJvc2VtaXJyb3JNYXBwaW5nfSBtYXBwaW5nXG4gKiBAcmV0dXJuIHtudWxsfG51bWJlcn1cbiAqL1xuZXhwb3J0IGNvbnN0IHJlbGF0aXZlUG9zaXRpb25Ub0Fic29sdXRlUG9zaXRpb24gPSAoeSwgZG9jdW1lbnRUeXBlLCByZWxQb3MsIG1hcHBpbmcpID0+IHtcbiAgY29uc3QgZGVjb2RlZFBvcyA9IFkuY3JlYXRlQWJzb2x1dGVQb3NpdGlvbkZyb21SZWxhdGl2ZVBvc2l0aW9uKHJlbFBvcywgeSlcbiAgaWYgKGRlY29kZWRQb3MgPT09IG51bGwgfHwgKGRlY29kZWRQb3MudHlwZSAhPT0gZG9jdW1lbnRUeXBlICYmICFZLmlzUGFyZW50T2YoZG9jdW1lbnRUeXBlLCBkZWNvZGVkUG9zLnR5cGUuX2l0ZW0pKSkge1xuICAgIHJldHVybiBudWxsXG4gIH1cbiAgbGV0IHR5cGUgPSBkZWNvZGVkUG9zLnR5cGVcbiAgbGV0IHBvcyA9IDBcbiAgaWYgKHR5cGUuY29uc3RydWN0b3IgPT09IFkuWG1sVGV4dCkge1xuICAgIHBvcyA9IGRlY29kZWRQb3MuaW5kZXhcbiAgfSBlbHNlIGlmICh0eXBlLl9pdGVtID09PSBudWxsIHx8ICF0eXBlLl9pdGVtLmRlbGV0ZWQpIHtcbiAgICBsZXQgbiA9IHR5cGUuX2ZpcnN0XG4gICAgbGV0IGkgPSAwXG4gICAgd2hpbGUgKGkgPCB0eXBlLl9sZW5ndGggJiYgaSA8IGRlY29kZWRQb3MuaW5kZXggJiYgbiAhPT0gbnVsbCkge1xuICAgICAgaWYgKCFuLmRlbGV0ZWQpIHtcbiAgICAgICAgY29uc3QgdCA9IC8qKiBAdHlwZSB7WS5Db250ZW50VHlwZX0gKi8gKG4uY29udGVudCkudHlwZVxuICAgICAgICBpKytcbiAgICAgICAgaWYgKHQgaW5zdGFuY2VvZiBZLlhtbFRleHQpIHtcbiAgICAgICAgICBwb3MgKz0gdC5fbGVuZ3RoXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcG9zICs9IC8qKiBAdHlwZSB7YW55fSAqLyAobWFwcGluZy5nZXQodCkpLm5vZGVTaXplXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG4gPSAvKiogQHR5cGUge1kuSXRlbX0gKi8gKG4ucmlnaHQpXG4gICAgfVxuICAgIHBvcyArPSAxIC8vIGluY3JlYXNlIGJlY2F1c2Ugd2UgZ28gb3V0IG9mIG5cbiAgfVxuICB3aGlsZSAodHlwZSAhPT0gZG9jdW1lbnRUeXBlICYmIHR5cGUuX2l0ZW0gIT09IG51bGwpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgY29uc3QgcGFyZW50ID0gdHlwZS5faXRlbS5wYXJlbnRcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgaWYgKHBhcmVudC5faXRlbSA9PT0gbnVsbCB8fCAhcGFyZW50Ll9pdGVtLmRlbGV0ZWQpIHtcbiAgICAgIHBvcyArPSAxIC8vIHRoZSBzdGFydCB0YWdcbiAgICAgIGxldCBuID0gLyoqIEB0eXBlIHtZLkFic3RyYWN0VHlwZX0gKi8gKHBhcmVudCkuX2ZpcnN0XG4gICAgICAvLyBub3cgaXRlcmF0ZSB1bnRpbCB3ZSBmb3VuZCB0eXBlXG4gICAgICB3aGlsZSAobiAhPT0gbnVsbCkge1xuICAgICAgICBjb25zdCBjb250ZW50VHlwZSA9IC8qKiBAdHlwZSB7WS5Db250ZW50VHlwZX0gKi8gKG4uY29udGVudCkudHlwZVxuICAgICAgICBpZiAoY29udGVudFR5cGUgPT09IHR5cGUpIHtcbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG4gICAgICAgIGlmICghbi5kZWxldGVkKSB7XG4gICAgICAgICAgaWYgKGNvbnRlbnRUeXBlIGluc3RhbmNlb2YgWS5YbWxUZXh0KSB7XG4gICAgICAgICAgICBwb3MgKz0gY29udGVudFR5cGUuX2xlbmd0aFxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwb3MgKz0gLyoqIEB0eXBlIHthbnl9ICovIChtYXBwaW5nLmdldChjb250ZW50VHlwZSkpLm5vZGVTaXplXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG4gPSBuLnJpZ2h0XG4gICAgICB9XG4gICAgfVxuICAgIHR5cGUgPSAvKiogQHR5cGUge1kuQWJzdHJhY3RUeXBlfSAqLyAocGFyZW50KVxuICB9XG4gIHJldHVybiBwb3MgLSAxIC8vIHdlIGRvbid0IGNvdW50IHRoZSBtb3N0IG91dGVyIHRhZywgYmVjYXVzZSBpdCBpcyBhIGZyYWdtZW50XG59XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbiBmb3IgY29udmVydGluZyBhbiBZLkZyYWdtZW50IHRvIGEgUHJvc2VNaXJyb3IgZnJhZ21lbnQuXG4gKlxuICogQHBhcmFtIHtZLlhtbEZyYWdtZW50fSB5WG1sRnJhZ21lbnRcbiAqIEBwYXJhbSB7U2NoZW1hfSBzY2hlbWFcbiAqL1xuZXhwb3J0IGNvbnN0IHlYbWxGcmFnbWVudFRvUHJvc2VNaXJyb3JGcmFnbWVudCA9ICh5WG1sRnJhZ21lbnQsIHNjaGVtYSkgPT4ge1xuICBjb25zdCBmcmFnbWVudENvbnRlbnQgPSB5WG1sRnJhZ21lbnQudG9BcnJheSgpLm1hcCgodCkgPT5cbiAgICBjcmVhdGVOb2RlRnJvbVlFbGVtZW50KFxuICAgICAgLyoqIEB0eXBlIHtZLlhtbEVsZW1lbnR9ICovICh0KSxcbiAgICAgIHNjaGVtYSxcbiAgICAgIGNyZWF0ZUVtcHR5TWV0YSgpXG4gICAgKVxuICApLmZpbHRlcigobikgPT4gbiAhPT0gbnVsbClcbiAgcmV0dXJuIEZyYWdtZW50LmZyb21BcnJheShmcmFnbWVudENvbnRlbnQpXG59XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbiBmb3IgY29udmVydGluZyBhbiBZLkZyYWdtZW50IHRvIGEgUHJvc2VNaXJyb3Igbm9kZS5cbiAqXG4gKiBAcGFyYW0ge1kuWG1sRnJhZ21lbnR9IHlYbWxGcmFnbWVudFxuICogQHBhcmFtIHtTY2hlbWF9IHNjaGVtYVxuICovXG5leHBvcnQgY29uc3QgeVhtbEZyYWdtZW50VG9Qcm9zZU1pcnJvclJvb3ROb2RlID0gKHlYbWxGcmFnbWVudCwgc2NoZW1hKSA9PlxuICBzY2hlbWEudG9wTm9kZVR5cGUuY3JlYXRlKG51bGwsIHlYbWxGcmFnbWVudFRvUHJvc2VNaXJyb3JGcmFnbWVudCh5WG1sRnJhZ21lbnQsIHNjaGVtYSkpXG5cbi8qKlxuICogVGhlIGluaXRpYWwgUHJvc2VNaXJyb3IgY29udGVudCBzaG91bGQgYmUgc3VwcGxpZWQgYnkgWWpzLiBUaGlzIGZ1bmN0aW9uIHRyYW5zZm9ybXMgYSBZLkZyYWdtZW50XG4gKiB0byBhIFByb3NlTWlycm9yIERvYyBub2RlIGFuZCBjcmVhdGVzIGEgbWFwcGluZyB0aGF0IGlzIHVzZWQgYnkgdGhlIHN5bmMgcGx1Z2luLlxuICpcbiAqIEBwYXJhbSB7WS5YbWxGcmFnbWVudH0geVhtbEZyYWdtZW50XG4gKiBAcGFyYW0ge1NjaGVtYX0gc2NoZW1hXG4gKlxuICogQHRvZG8gZGVwcmVjYXRlIG1hcHBpbmcgcHJvcGVydHlcbiAqL1xuZXhwb3J0IGNvbnN0IGluaXRQcm9zZU1pcnJvckRvYyA9ICh5WG1sRnJhZ21lbnQsIHNjaGVtYSkgPT4ge1xuICBjb25zdCBtZXRhID0gY3JlYXRlRW1wdHlNZXRhKClcbiAgY29uc3QgZnJhZ21lbnRDb250ZW50ID0geVhtbEZyYWdtZW50LnRvQXJyYXkoKS5tYXAoKHQpID0+XG4gICAgY3JlYXRlTm9kZUZyb21ZRWxlbWVudChcbiAgICAgIC8qKiBAdHlwZSB7WS5YbWxFbGVtZW50fSAqLyAodCksXG4gICAgICBzY2hlbWEsXG4gICAgICBtZXRhXG4gICAgKVxuICApLmZpbHRlcigobikgPT4gbiAhPT0gbnVsbClcbiAgY29uc3QgZG9jID0gc2NoZW1hLnRvcE5vZGVUeXBlLmNyZWF0ZShudWxsLCBGcmFnbWVudC5mcm9tQXJyYXkoZnJhZ21lbnRDb250ZW50KSlcbiAgcmV0dXJuIHsgZG9jLCBtZXRhLCBtYXBwaW5nOiBtZXRhLm1hcHBpbmcgfVxufVxuXG4vKipcbiAqIFV0aWxpdHkgbWV0aG9kIHRvIGNvbnZlcnQgYSBQcm9zZW1pcnJvciBEb2MgTm9kZSBpbnRvIGEgWS5Eb2MuXG4gKlxuICogVGhpcyBjYW4gYmUgdXNlZCB3aGVuIGltcG9ydGluZyBleGlzdGluZyBjb250ZW50IHRvIFkuRG9jIGZvciB0aGUgZmlyc3QgdGltZSxcbiAqIG5vdGUgdGhhdCB0aGlzIHNob3VsZCBub3QgYmUgdXNlZCB0byByZWh5ZHJhdGUgYSBZLkRvYyBmcm9tIGEgZGF0YWJhc2Ugb25jZVxuICogY29sbGFib3JhdGlvbiBoYXMgYmVndW4gYXMgYWxsIGhpc3Rvcnkgd2lsbCBiZSBsb3N0XG4gKlxuICogQHBhcmFtIHtOb2RlfSBkb2NcbiAqIEBwYXJhbSB7c3RyaW5nfSB4bWxGcmFnbWVudFxuICogQHJldHVybiB7WS5Eb2N9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm9zZW1pcnJvclRvWURvYyAoZG9jLCB4bWxGcmFnbWVudCA9ICdwcm9zZW1pcnJvcicpIHtcbiAgY29uc3QgeWRvYyA9IG5ldyBZLkRvYygpXG4gIGNvbnN0IHR5cGUgPSAvKiogQHR5cGUge1kuWG1sRnJhZ21lbnR9ICovICh5ZG9jLmdldCh4bWxGcmFnbWVudCwgWS5YbWxGcmFnbWVudCkpXG4gIGlmICghdHlwZS5kb2MpIHtcbiAgICByZXR1cm4geWRvY1xuICB9XG5cbiAgcHJvc2VtaXJyb3JUb1lYbWxGcmFnbWVudChkb2MsIHR5cGUpXG4gIHJldHVybiB0eXBlLmRvY1xufVxuXG4vKipcbiAqIFV0aWxpdHkgbWV0aG9kIHRvIHVwZGF0ZSBhbiBlbXB0eSBZLlhtbEZyYWdtZW50IHdpdGggY29udGVudCBmcm9tIGEgUHJvc2VtaXJyb3IgRG9jIE5vZGUuXG4gKlxuICogVGhpcyBjYW4gYmUgdXNlZCB3aGVuIGltcG9ydGluZyBleGlzdGluZyBjb250ZW50IHRvIFkuRG9jIGZvciB0aGUgZmlyc3QgdGltZSxcbiAqIG5vdGUgdGhhdCB0aGlzIHNob3VsZCBub3QgYmUgdXNlZCB0byByZWh5ZHJhdGUgYSBZLkRvYyBmcm9tIGEgZGF0YWJhc2Ugb25jZVxuICogY29sbGFib3JhdGlvbiBoYXMgYmVndW4gYXMgYWxsIGhpc3Rvcnkgd2lsbCBiZSBsb3N0XG4gKlxuICogTm90ZTogVGhlIFkuWG1sRnJhZ21lbnQgZG9lcyBub3QgbmVlZCB0byBiZSBwYXJ0IG9mIGEgWS5Eb2MgZG9jdW1lbnQgYXQgdGhlIHRpbWUgdGhhdCB0aGlzXG4gKiBtZXRob2QgaXMgY2FsbGVkLCBidXQgaXQgbXVzdCBiZSBhZGRlZCBiZWZvcmUgYW55IG90aGVyIG9wZXJhdGlvbnMgYXJlIHBlcmZvcm1lZCBvbiBpdC5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IGRvYyBwcm9zZW1pcnJvciBkb2N1bWVudC5cbiAqIEBwYXJhbSB7WS5YbWxGcmFnbWVudH0gW3htbEZyYWdtZW50XSBJZiBzdXBwbGllZCwgYW4geG1sIGZyYWdtZW50IHRvIGJlXG4gKiAgIHBvcHVsYXRlZCBmcm9tIHRoZSBwcm9zZW1pcnJvciBzdGF0ZTsgb3RoZXJ3aXNlIGEgbmV3IFhtbEZyYWdtZW50IHdpbGwgYmUgY3JlYXRlZC5cbiAqIEByZXR1cm4ge1kuWG1sRnJhZ21lbnR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm9zZW1pcnJvclRvWVhtbEZyYWdtZW50IChkb2MsIHhtbEZyYWdtZW50KSB7XG4gIGNvbnN0IHR5cGUgPSB4bWxGcmFnbWVudCB8fCBuZXcgWS5YbWxGcmFnbWVudCgpXG4gIGNvbnN0IHlkb2MgPSB0eXBlLmRvYyA/IHR5cGUuZG9jIDogeyB0cmFuc2FjdDogKHRyYW5zYWN0aW9uKSA9PiB0cmFuc2FjdGlvbih1bmRlZmluZWQpIH1cbiAgdXBkYXRlWUZyYWdtZW50KHlkb2MsIHR5cGUsIGRvYywgeyBtYXBwaW5nOiBuZXcgTWFwKCksIGlzT01hcms6IG5ldyBNYXAoKSB9KVxuICByZXR1cm4gdHlwZVxufVxuXG4vKipcbiAqIFV0aWxpdHkgbWV0aG9kIHRvIGNvbnZlcnQgUHJvc2VtaXJyb3IgY29tcGF0aWJsZSBKU09OIGludG8gYSBZLkRvYy5cbiAqXG4gKiBUaGlzIGNhbiBiZSB1c2VkIHdoZW4gaW1wb3J0aW5nIGV4aXN0aW5nIGNvbnRlbnQgdG8gWS5Eb2MgZm9yIHRoZSBmaXJzdCB0aW1lLFxuICogbm90ZSB0aGF0IHRoaXMgc2hvdWxkIG5vdCBiZSB1c2VkIHRvIHJlaHlkcmF0ZSBhIFkuRG9jIGZyb20gYSBkYXRhYmFzZSBvbmNlXG4gKiBjb2xsYWJvcmF0aW9uIGhhcyBiZWd1biBhcyBhbGwgaGlzdG9yeSB3aWxsIGJlIGxvc3RcbiAqXG4gKiBAcGFyYW0ge1NjaGVtYX0gc2NoZW1hXG4gKiBAcGFyYW0ge2FueX0gc3RhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSB4bWxGcmFnbWVudFxuICogQHJldHVybiB7WS5Eb2N9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm9zZW1pcnJvckpTT05Ub1lEb2MgKHNjaGVtYSwgc3RhdGUsIHhtbEZyYWdtZW50ID0gJ3Byb3NlbWlycm9yJykge1xuICBjb25zdCBkb2MgPSBOb2RlLmZyb21KU09OKHNjaGVtYSwgc3RhdGUpXG4gIHJldHVybiBwcm9zZW1pcnJvclRvWURvYyhkb2MsIHhtbEZyYWdtZW50KVxufVxuXG4vKipcbiAqIFV0aWxpdHkgbWV0aG9kIHRvIGNvbnZlcnQgUHJvc2VtaXJyb3IgY29tcGF0aWJsZSBKU09OIHRvIGEgWS5YbWxGcmFnbWVudFxuICpcbiAqIFRoaXMgY2FuIGJlIHVzZWQgd2hlbiBpbXBvcnRpbmcgZXhpc3RpbmcgY29udGVudCB0byBZLkRvYyBmb3IgdGhlIGZpcnN0IHRpbWUsXG4gKiBub3RlIHRoYXQgdGhpcyBzaG91bGQgbm90IGJlIHVzZWQgdG8gcmVoeWRyYXRlIGEgWS5Eb2MgZnJvbSBhIGRhdGFiYXNlIG9uY2VcbiAqIGNvbGxhYm9yYXRpb24gaGFzIGJlZ3VuIGFzIGFsbCBoaXN0b3J5IHdpbGwgYmUgbG9zdFxuICpcbiAqIEBwYXJhbSB7U2NoZW1hfSBzY2hlbWFcbiAqIEBwYXJhbSB7YW55fSBzdGF0ZVxuICogQHBhcmFtIHtZLlhtbEZyYWdtZW50fSBbeG1sRnJhZ21lbnRdIElmIHN1cHBsaWVkLCBhbiB4bWwgZnJhZ21lbnQgdG8gYmVcbiAqICAgcG9wdWxhdGVkIGZyb20gdGhlIHByb3NlbWlycm9yIHN0YXRlOyBvdGhlcndpc2UgYSBuZXcgWG1sRnJhZ21lbnQgd2lsbCBiZSBjcmVhdGVkLlxuICogQHJldHVybiB7WS5YbWxGcmFnbWVudH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHByb3NlbWlycm9ySlNPTlRvWVhtbEZyYWdtZW50IChzY2hlbWEsIHN0YXRlLCB4bWxGcmFnbWVudCkge1xuICBjb25zdCBkb2MgPSBOb2RlLmZyb21KU09OKHNjaGVtYSwgc3RhdGUpXG4gIHJldHVybiBwcm9zZW1pcnJvclRvWVhtbEZyYWdtZW50KGRvYywgeG1sRnJhZ21lbnQpXG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgVXNlIGB5WG1sRnJhZ21lbnRUb1Byb3NlTWlycm9yUm9vdE5vZGVgIGluc3RlYWRcbiAqXG4gKiBVdGlsaXR5IG1ldGhvZCB0byBjb252ZXJ0IGEgWS5Eb2MgdG8gYSBQcm9zZW1pcnJvciBEb2Mgbm9kZS5cbiAqXG4gKiBAcGFyYW0ge1NjaGVtYX0gc2NoZW1hXG4gKiBAcGFyYW0ge1kuRG9jfSB5ZG9jXG4gKiBAcmV0dXJuIHtOb2RlfVxuICovXG5leHBvcnQgZnVuY3Rpb24geURvY1RvUHJvc2VtaXJyb3IgKHNjaGVtYSwgeWRvYykge1xuICBjb25zdCBzdGF0ZSA9IHlEb2NUb1Byb3NlbWlycm9ySlNPTih5ZG9jKVxuICByZXR1cm4gTm9kZS5mcm9tSlNPTihzY2hlbWEsIHN0YXRlKVxufVxuXG4vKipcbiAqXG4gKiBAZGVwcmVjYXRlZCBVc2UgYHlYbWxGcmFnbWVudFRvUHJvc2VNaXJyb3JSb290Tm9kZWAgaW5zdGVhZFxuICpcbiAqIFV0aWxpdHkgbWV0aG9kIHRvIGNvbnZlcnQgYSBZLlhtbEZyYWdtZW50IHRvIGEgUHJvc2VtaXJyb3IgRG9jIG5vZGUuXG4gKlxuICogQHBhcmFtIHtTY2hlbWF9IHNjaGVtYVxuICogQHBhcmFtIHtZLlhtbEZyYWdtZW50fSB4bWxGcmFnbWVudFxuICogQHJldHVybiB7Tm9kZX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHlYbWxGcmFnbWVudFRvUHJvc2VtaXJyb3IgKHNjaGVtYSwgeG1sRnJhZ21lbnQpIHtcbiAgY29uc3Qgc3RhdGUgPSB5WG1sRnJhZ21lbnRUb1Byb3NlbWlycm9ySlNPTih4bWxGcmFnbWVudClcbiAgcmV0dXJuIE5vZGUuZnJvbUpTT04oc2NoZW1hLCBzdGF0ZSlcbn1cblxuLyoqXG4gKlxuICogQGRlcHJlY2F0ZWQgVXNlIGB5WG1sRnJhZ21lbnRUb1Byb3NlTWlycm9yUm9vdE5vZGVgIGluc3RlYWRcbiAqXG4gKiBVdGlsaXR5IG1ldGhvZCB0byBjb252ZXJ0IGEgWS5Eb2MgdG8gUHJvc2VtaXJyb3IgY29tcGF0aWJsZSBKU09OLlxuICpcbiAqIEBwYXJhbSB7WS5Eb2N9IHlkb2NcbiAqIEBwYXJhbSB7c3RyaW5nfSB4bWxGcmFnbWVudFxuICogQHJldHVybiB7UmVjb3JkPHN0cmluZywgYW55Pn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHlEb2NUb1Byb3NlbWlycm9ySlNPTiAoXG4gIHlkb2MsXG4gIHhtbEZyYWdtZW50ID0gJ3Byb3NlbWlycm9yJ1xuKSB7XG4gIHJldHVybiB5WG1sRnJhZ21lbnRUb1Byb3NlbWlycm9ySlNPTih5ZG9jLmdldFhtbEZyYWdtZW50KHhtbEZyYWdtZW50KSlcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBVc2UgYHlYbWxGcmFnbWVudFRvUHJvc2VNaXJyb3JSb290Tm9kZWAgaW5zdGVhZFxuICpcbiAqIFV0aWxpdHkgbWV0aG9kIHRvIGNvbnZlcnQgYSBZLkRvYyB0byBQcm9zZW1pcnJvciBjb21wYXRpYmxlIEpTT04uXG4gKlxuICogQHBhcmFtIHtZLlhtbEZyYWdtZW50fSB4bWxGcmFnbWVudCBUaGUgZnJhZ21lbnQsIHdoaWNoIG11c3QgYmUgcGFydCBvZiBhIFkuRG9jLlxuICogQHJldHVybiB7UmVjb3JkPHN0cmluZywgYW55Pn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHlYbWxGcmFnbWVudFRvUHJvc2VtaXJyb3JKU09OICh4bWxGcmFnbWVudCkge1xuICBjb25zdCBpdGVtcyA9IHhtbEZyYWdtZW50LnRvQXJyYXkoKVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1kuQWJzdHJhY3RUeXBlfSBpdGVtXG4gICAqL1xuICBjb25zdCBzZXJpYWxpemUgPSBpdGVtID0+IHtcbiAgICAvKipcbiAgICAgKiBAdHlwZSB7T2JqZWN0fSBOb2RlT2JqZWN0XG4gICAgICogQHByb3BlcnR5IHtzdHJpbmd9IE5vZGVPYmplY3QudHlwZVxuICAgICAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgc3RyaW5nPj19IE5vZGVPYmplY3QuYXR0cnNcbiAgICAgKiBAcHJvcGVydHkge0FycmF5PE5vZGVPYmplY3Q+PX0gTm9kZU9iamVjdC5jb250ZW50XG4gICAgICovXG4gICAgbGV0IHJlc3BvbnNlXG5cbiAgICAvLyBUT0RPOiBNdXN0IGJlIGEgYmV0dGVyIHdheSB0byBkZXRlY3QgdGV4dCBub2RlcyB0aGFuIHRoaXNcbiAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIFkuWG1sVGV4dCkge1xuICAgICAgY29uc3QgZGVsdGEgPSBpdGVtLnRvRGVsdGEoKVxuICAgICAgcmVzcG9uc2UgPSBkZWx0YS5tYXAoLyoqIEBwYXJhbSB7YW55fSBkICovIChkKSA9PiB7XG4gICAgICAgIGNvbnN0IHRleHQgPSB7XG4gICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgIHRleHQ6IGQuaW5zZXJ0XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGQuYXR0cmlidXRlcykge1xuICAgICAgICAgIHRleHQubWFya3MgPSBPYmplY3Qua2V5cyhkLmF0dHJpYnV0ZXMpLm1hcCgodHlwZV8pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGF0dHJzID0gZC5hdHRyaWJ1dGVzW3R5cGVfXVxuICAgICAgICAgICAgY29uc3QgdHlwZSA9IHlhdHRyMm1hcmtuYW1lKHR5cGVfKVxuICAgICAgICAgICAgY29uc3QgbWFyayA9IHtcbiAgICAgICAgICAgICAgdHlwZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKGF0dHJzKSkge1xuICAgICAgICAgICAgICBtYXJrLmF0dHJzID0gYXR0cnNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBtYXJrXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGV4dFxuICAgICAgfSlcbiAgICB9IGVsc2UgaWYgKGl0ZW0gaW5zdGFuY2VvZiBZLlhtbEVsZW1lbnQpIHtcbiAgICAgIHJlc3BvbnNlID0ge1xuICAgICAgICB0eXBlOiBpdGVtLm5vZGVOYW1lXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGF0dHJzID0gaXRlbS5nZXRBdHRyaWJ1dGVzKClcbiAgICAgIGlmIChPYmplY3Qua2V5cyhhdHRycykubGVuZ3RoKSB7XG4gICAgICAgIHJlc3BvbnNlLmF0dHJzID0gYXR0cnNcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hpbGRyZW4gPSBpdGVtLnRvQXJyYXkoKVxuICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgICByZXNwb25zZS5jb250ZW50ID0gY2hpbGRyZW4ubWFwKHNlcmlhbGl6ZSkuZmxhdCgpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGV4cGVjdGVkIGVpdGhlciBZLlhtbEVsZW1lbnQgb3IgWS5YbWxUZXh0XG4gICAgICBlcnJvci51bmV4cGVjdGVkQ2FzZSgpXG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3BvbnNlXG4gIH1cblxuICByZXR1cm4ge1xuICAgIHR5cGU6ICdkb2MnLFxuICAgIGNvbnRlbnQ6IGl0ZW1zLm1hcChzZXJpYWxpemUpXG4gIH1cbn1cbiIsICJpbXBvcnQgKiBhcyBZIGZyb20gJ3lqcydcbmltcG9ydCB7IERlY29yYXRpb24sIERlY29yYXRpb25TZXQgfSBmcm9tIFwicHJvc2VtaXJyb3Itdmlld1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5pbXBvcnQgeyBQbHVnaW4gfSBmcm9tIFwicHJvc2VtaXJyb3Itc3RhdGVcIjsgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuaW1wb3J0IHsgQXdhcmVuZXNzIH0gZnJvbSBcInktcHJvdG9jb2xzL2F3YXJlbmVzc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5pbXBvcnQge1xuICBhYnNvbHV0ZVBvc2l0aW9uVG9SZWxhdGl2ZVBvc2l0aW9uLFxuICByZWxhdGl2ZVBvc2l0aW9uVG9BYnNvbHV0ZVBvc2l0aW9uLFxuICBzZXRNZXRhXG59IGZyb20gJy4uL2xpYi5qcydcbmltcG9ydCB7IHlDdXJzb3JQbHVnaW5LZXksIHlTeW5jUGx1Z2luS2V5IH0gZnJvbSAnLi9rZXlzLmpzJ1xuXG5pbXBvcnQgKiBhcyBtYXRoIGZyb20gJ2xpYjAvbWF0aCdcblxuLyoqXG4gKiBEZWZhdWx0IGF3YXJlbmVzcyBzdGF0ZSBmaWx0ZXJcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gY3VycmVudENsaWVudElkIGN1cnJlbnQgY2xpZW50IGlkXG4gKiBAcGFyYW0ge251bWJlcn0gdXNlckNsaWVudElkIHVzZXIgY2xpZW50IGlkXG4gKiBAcGFyYW0ge2FueX0gX3VzZXIgdXNlciBkYXRhXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgY29uc3QgZGVmYXVsdEF3YXJlbmVzc1N0YXRlRmlsdGVyID0gKFxuICBjdXJyZW50Q2xpZW50SWQsXG4gIHVzZXJDbGllbnRJZCxcbiAgX3VzZXJcbikgPT4gY3VycmVudENsaWVudElkICE9PSB1c2VyQ2xpZW50SWRcblxuLyoqXG4gKiBEZWZhdWx0IGdlbmVyYXRvciBmb3IgYSBjdXJzb3IgZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7YW55fSB1c2VyIHVzZXIgZGF0YVxuICogQHJldHVybiB7SFRNTEVsZW1lbnR9XG4gKi9cbmV4cG9ydCBjb25zdCBkZWZhdWx0Q3Vyc29yQnVpbGRlciA9ICh1c2VyKSA9PiB7XG4gIGNvbnN0IGN1cnNvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKVxuICBjdXJzb3IuY2xhc3NMaXN0LmFkZCgnUHJvc2VNaXJyb3IteWpzLWN1cnNvcicpXG4gIGN1cnNvci5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgYGJvcmRlci1jb2xvcjogJHt1c2VyLmNvbG9yfWApXG4gIGNvbnN0IHVzZXJEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuICB1c2VyRGl2LnNldEF0dHJpYnV0ZSgnc3R5bGUnLCBgYmFja2dyb3VuZC1jb2xvcjogJHt1c2VyLmNvbG9yfWApXG4gIHVzZXJEaXYuaW5zZXJ0QmVmb3JlKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHVzZXIubmFtZSksIG51bGwpXG4gIGNvbnN0IG5vbmJyZWFraW5nU3BhY2UxID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoJ1xcdTIwNjAnKVxuICBjb25zdCBub25icmVha2luZ1NwYWNlMiA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKCdcXHUyMDYwJylcbiAgY3Vyc29yLmluc2VydEJlZm9yZShub25icmVha2luZ1NwYWNlMSwgbnVsbClcbiAgY3Vyc29yLmluc2VydEJlZm9yZSh1c2VyRGl2LCBudWxsKVxuICBjdXJzb3IuaW5zZXJ0QmVmb3JlKG5vbmJyZWFraW5nU3BhY2UyLCBudWxsKVxuICByZXR1cm4gY3Vyc29yXG59XG5cbi8qKlxuICogRGVmYXVsdCBnZW5lcmF0b3IgZm9yIHRoZSBzZWxlY3Rpb24gYXR0cmlidXRlc1xuICpcbiAqIEBwYXJhbSB7YW55fSB1c2VyIHVzZXIgZGF0YVxuICogQHJldHVybiB7aW1wb3J0KCdwcm9zZW1pcnJvci12aWV3JykuRGVjb3JhdGlvbkF0dHJzfVxuICovXG5leHBvcnQgY29uc3QgZGVmYXVsdFNlbGVjdGlvbkJ1aWxkZXIgPSAodXNlcikgPT4ge1xuICByZXR1cm4ge1xuICAgIHN0eWxlOiBgYmFja2dyb3VuZC1jb2xvcjogJHt1c2VyLmNvbG9yfTcwYCxcbiAgICBjbGFzczogJ1Byb3NlTWlycm9yLXlqcy1zZWxlY3Rpb24nXG4gIH1cbn1cblxuY29uc3QgcnhWYWxpZENvbG9yID0gL14jWzAtOWEtZkEtRl17Nn0kL1xuXG4vKipcbiAqIEBwYXJhbSB7YW55fSBzdGF0ZVxuICogQHBhcmFtIHtBd2FyZW5lc3N9IGF3YXJlbmVzc1xuICogQHBhcmFtIHtmdW5jdGlvbihudW1iZXIsIG51bWJlciwgYW55KTpib29sZWFufSBhd2FyZW5lc3NGaWx0ZXJcbiAqIEBwYXJhbSB7KHVzZXI6IHsgbmFtZTogc3RyaW5nLCBjb2xvcjogc3RyaW5nIH0sIGNsaWVudElkOiBudW1iZXIpID0+IEVsZW1lbnR9IGNyZWF0ZUN1cnNvclxuICogQHBhcmFtIHsodXNlcjogeyBuYW1lOiBzdHJpbmcsIGNvbG9yOiBzdHJpbmcgfSwgY2xpZW50SWQ6IG51bWJlcikgPT4gaW1wb3J0KCdwcm9zZW1pcnJvci12aWV3JykuRGVjb3JhdGlvbkF0dHJzfSBjcmVhdGVTZWxlY3Rpb25cbiAqIEByZXR1cm4ge2FueX0gRGVjb3JhdGlvblNldFxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlRGVjb3JhdGlvbnMgPSAoXG4gIHN0YXRlLFxuICBhd2FyZW5lc3MsXG4gIGF3YXJlbmVzc0ZpbHRlcixcbiAgY3JlYXRlQ3Vyc29yLFxuICBjcmVhdGVTZWxlY3Rpb25cbikgPT4ge1xuICBjb25zdCB5c3RhdGUgPSB5U3luY1BsdWdpbktleS5nZXRTdGF0ZShzdGF0ZSlcbiAgaWYgKHlzdGF0ZSA9PSBudWxsIHx8IHlzdGF0ZS5kb2MgPT0gbnVsbCB8fCB5c3RhdGUuYmluZGluZyA9PSBudWxsKSB7XG4gICAgcmV0dXJuIERlY29yYXRpb25TZXQuY3JlYXRlKHN0YXRlLmRvYywgW10pXG4gIH1cbiAgY29uc3QgeSA9IHlzdGF0ZS5kb2NcbiAgY29uc3QgZGVjb3JhdGlvbnMgPSBbXVxuICBpZiAoXG4gICAgeXN0YXRlLnNuYXBzaG90ICE9IG51bGwgfHxcbiAgICB5c3RhdGUucHJldlNuYXBzaG90ICE9IG51bGwgfHxcbiAgICB5c3RhdGUuYmluZGluZy5tYXBwaW5nLnNpemUgPT09IDBcbiAgKSB7XG4gICAgLy8gZG8gbm90IHJlbmRlciBjdXJzb3JzIHdoaWxlIHNuYXBzaG90IGlzIGFjdGl2ZVxuICAgIHJldHVybiBEZWNvcmF0aW9uU2V0LmNyZWF0ZShzdGF0ZS5kb2MsIFtdKVxuICB9XG4gIGF3YXJlbmVzcy5nZXRTdGF0ZXMoKS5mb3JFYWNoKChhdywgY2xpZW50SWQpID0+IHtcbiAgICBpZiAoIWF3YXJlbmVzc0ZpbHRlcih5LmNsaWVudElELCBjbGllbnRJZCwgYXcpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBgYXdgIGNhbiBiZSBudWxsIHdoZW4gYSBjbGllbnQgZGlzY29ubmVjdHMsIHNvIHdlIGd1YXJkIGFnYWluc3QgaXRcbiAgICAvLyBiZWZvcmUgcmVhZGluZyBgY3Vyc29yYCB0byBhdm9pZCBhIFR5cGVFcnJvci5cbiAgICBpZiAoYXcgJiYgYXcuY3Vyc29yICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IHVzZXIgPSBhdy51c2VyIHx8IHt9XG4gICAgICBpZiAodXNlci5jb2xvciA9PSBudWxsKSB7XG4gICAgICAgIHVzZXIuY29sb3IgPSAnI2ZmYTUwMCdcbiAgICAgIH0gZWxzZSBpZiAoIXJ4VmFsaWRDb2xvci50ZXN0KHVzZXIuY29sb3IpKSB7XG4gICAgICAgIC8vIFdlIG9ubHkgc3VwcG9ydCA2LWRpZ2l0IFJHQiBjb2xvcnMgaW4geS1wcm9zZW1pcnJvclxuICAgICAgICBjb25zb2xlLndhcm4oJ0EgdXNlciB1c2VzIGFuIHVuc3VwcG9ydGVkIGNvbG9yIGZvcm1hdCcsIHVzZXIpXG4gICAgICB9XG4gICAgICBpZiAodXNlci5uYW1lID09IG51bGwpIHtcbiAgICAgICAgdXNlci5uYW1lID0gYFVzZXI6ICR7Y2xpZW50SWR9YFxuICAgICAgfVxuICAgICAgbGV0IGFuY2hvciA9IHJlbGF0aXZlUG9zaXRpb25Ub0Fic29sdXRlUG9zaXRpb24oXG4gICAgICAgIHksXG4gICAgICAgIHlzdGF0ZS50eXBlLFxuICAgICAgICBZLmNyZWF0ZVJlbGF0aXZlUG9zaXRpb25Gcm9tSlNPTihhdy5jdXJzb3IuYW5jaG9yKSxcbiAgICAgICAgeXN0YXRlLmJpbmRpbmcubWFwcGluZ1xuICAgICAgKVxuICAgICAgbGV0IGhlYWQgPSByZWxhdGl2ZVBvc2l0aW9uVG9BYnNvbHV0ZVBvc2l0aW9uKFxuICAgICAgICB5LFxuICAgICAgICB5c3RhdGUudHlwZSxcbiAgICAgICAgWS5jcmVhdGVSZWxhdGl2ZVBvc2l0aW9uRnJvbUpTT04oYXcuY3Vyc29yLmhlYWQpLFxuICAgICAgICB5c3RhdGUuYmluZGluZy5tYXBwaW5nXG4gICAgICApXG4gICAgICBpZiAoYW5jaG9yICE9PSBudWxsICYmIGhlYWQgIT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgbWF4c2l6ZSA9IG1hdGgubWF4KHN0YXRlLmRvYy5jb250ZW50LnNpemUgLSAxLCAwKVxuICAgICAgICBhbmNob3IgPSBtYXRoLm1pbihhbmNob3IsIG1heHNpemUpXG4gICAgICAgIGhlYWQgPSBtYXRoLm1pbihoZWFkLCBtYXhzaXplKVxuICAgICAgICBkZWNvcmF0aW9ucy5wdXNoKFxuICAgICAgICAgIERlY29yYXRpb24ud2lkZ2V0KGhlYWQsICgpID0+IGNyZWF0ZUN1cnNvcih1c2VyLCBjbGllbnRJZCksIHtcbiAgICAgICAgICAgIGtleTogY2xpZW50SWQgKyAnJyxcbiAgICAgICAgICAgIHNpZGU6IDEwXG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgICBjb25zdCBmcm9tID0gbWF0aC5taW4oYW5jaG9yLCBoZWFkKVxuICAgICAgICBjb25zdCB0byA9IG1hdGgubWF4KGFuY2hvciwgaGVhZClcbiAgICAgICAgZGVjb3JhdGlvbnMucHVzaChcbiAgICAgICAgICBEZWNvcmF0aW9uLmlubGluZShmcm9tLCB0bywgY3JlYXRlU2VsZWN0aW9uKHVzZXIsIGNsaWVudElkKSwge1xuICAgICAgICAgICAgaW5jbHVzaXZlRW5kOiB0cnVlLFxuICAgICAgICAgICAgaW5jbHVzaXZlU3RhcnQ6IGZhbHNlXG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cbiAgfSlcbiAgcmV0dXJuIERlY29yYXRpb25TZXQuY3JlYXRlKHN0YXRlLmRvYywgZGVjb3JhdGlvbnMpXG59XG5cbi8qKlxuICogQSBwcm9zZW1pcnJvciBwbHVnaW4gdGhhdCBsaXN0ZW5zIHRvIGF3YXJlbmVzcyBpbmZvcm1hdGlvbiBvbiBZanMuXG4gKiBUaGlzIHJlcXVpcmVzIHRoYXQgYSBgcHJvc2VtaXJyb3JQbHVnaW5gIGlzIGFsc28gYm91bmQgdG8gdGhlIHByb3NlbWlycm9yLlxuICpcbiAqIEBwdWJsaWNcbiAqIEBwYXJhbSB7QXdhcmVuZXNzfSBhd2FyZW5lc3NcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRzXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKGFueSwgYW55LCBhbnkpOmJvb2xlYW59IFtvcHRzLmF3YXJlbmVzc1N0YXRlRmlsdGVyXVxuICogQHBhcmFtIHsodXNlcjogYW55LCBjbGllbnRJZDogbnVtYmVyKSA9PiBIVE1MRWxlbWVudH0gW29wdHMuY3Vyc29yQnVpbGRlcl1cbiAqIEBwYXJhbSB7KHVzZXI6IGFueSwgY2xpZW50SWQ6IG51bWJlcikgPT4gaW1wb3J0KCdwcm9zZW1pcnJvci12aWV3JykuRGVjb3JhdGlvbkF0dHJzfSBbb3B0cy5zZWxlY3Rpb25CdWlsZGVyXVxuICogQHBhcmFtIHtmdW5jdGlvbihhbnkpOmFueX0gW29wdHMuZ2V0U2VsZWN0aW9uXVxuICogQHBhcmFtIHtzdHJpbmd9IFtjdXJzb3JTdGF0ZUZpZWxkXSBCeSBkZWZhdWx0IGFsbCBlZGl0b3IgYmluZGluZ3MgdXNlIHRoZSBhd2FyZW5lc3MgJ2N1cnNvcicgZmllbGQgdG8gcHJvcGFnYXRlIGN1cnNvciBpbmZvcm1hdGlvbi5cbiAqIEByZXR1cm4ge2FueX1cbiAqL1xuZXhwb3J0IGNvbnN0IHlDdXJzb3JQbHVnaW4gPSAoXG4gIGF3YXJlbmVzcyxcbiAge1xuICAgIGF3YXJlbmVzc1N0YXRlRmlsdGVyID0gZGVmYXVsdEF3YXJlbmVzc1N0YXRlRmlsdGVyLFxuICAgIGN1cnNvckJ1aWxkZXIgPSBkZWZhdWx0Q3Vyc29yQnVpbGRlcixcbiAgICBzZWxlY3Rpb25CdWlsZGVyID0gZGVmYXVsdFNlbGVjdGlvbkJ1aWxkZXIsXG4gICAgZ2V0U2VsZWN0aW9uID0gKHN0YXRlKSA9PiBzdGF0ZS5zZWxlY3Rpb25cbiAgfSA9IHt9LFxuICBjdXJzb3JTdGF0ZUZpZWxkID0gJ2N1cnNvcidcbikgPT5cbiAgbmV3IFBsdWdpbih7XG4gICAga2V5OiB5Q3Vyc29yUGx1Z2luS2V5LFxuICAgIHN0YXRlOiB7XG4gICAgICBpbml0IChfLCBzdGF0ZSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlRGVjb3JhdGlvbnMoXG4gICAgICAgICAgc3RhdGUsXG4gICAgICAgICAgYXdhcmVuZXNzLFxuICAgICAgICAgIGF3YXJlbmVzc1N0YXRlRmlsdGVyLFxuICAgICAgICAgIGN1cnNvckJ1aWxkZXIsXG4gICAgICAgICAgc2VsZWN0aW9uQnVpbGRlclxuICAgICAgICApXG4gICAgICB9LFxuICAgICAgYXBwbHkgKHRyLCBwcmV2U3RhdGUsIF9vbGRTdGF0ZSwgbmV3U3RhdGUpIHtcbiAgICAgICAgY29uc3QgeXN0YXRlID0geVN5bmNQbHVnaW5LZXkuZ2V0U3RhdGUobmV3U3RhdGUpXG4gICAgICAgIGNvbnN0IHlDdXJzb3JTdGF0ZSA9IHRyLmdldE1ldGEoeUN1cnNvclBsdWdpbktleSlcbiAgICAgICAgaWYgKFxuICAgICAgICAgICh5c3RhdGUgJiYgeXN0YXRlLmlzQ2hhbmdlT3JpZ2luKSB8fFxuICAgICAgICAgICh5Q3Vyc29yU3RhdGUgJiYgeUN1cnNvclN0YXRlLmF3YXJlbmVzc1VwZGF0ZWQpXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBjcmVhdGVEZWNvcmF0aW9ucyhcbiAgICAgICAgICAgIG5ld1N0YXRlLFxuICAgICAgICAgICAgYXdhcmVuZXNzLFxuICAgICAgICAgICAgYXdhcmVuZXNzU3RhdGVGaWx0ZXIsXG4gICAgICAgICAgICBjdXJzb3JCdWlsZGVyLFxuICAgICAgICAgICAgc2VsZWN0aW9uQnVpbGRlclxuICAgICAgICAgIClcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJldlN0YXRlLm1hcCh0ci5tYXBwaW5nLCB0ci5kb2MpXG4gICAgICB9XG4gICAgfSxcbiAgICBwcm9wczoge1xuICAgICAgZGVjb3JhdGlvbnM6IChzdGF0ZSkgPT4ge1xuICAgICAgICByZXR1cm4geUN1cnNvclBsdWdpbktleS5nZXRTdGF0ZShzdGF0ZSlcbiAgICAgIH1cbiAgICB9LFxuICAgIHZpZXc6ICh2aWV3KSA9PiB7XG4gICAgICBjb25zdCBhd2FyZW5lc3NMaXN0ZW5lciA9ICgpID0+IHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBpZiAodmlldy5kb2NWaWV3KSB7XG4gICAgICAgICAgc2V0TWV0YSh2aWV3LCB5Q3Vyc29yUGx1Z2luS2V5LCB7IGF3YXJlbmVzc1VwZGF0ZWQ6IHRydWUgfSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgdXBkYXRlQ3Vyc29ySW5mbyA9ICgpID0+IHtcbiAgICAgICAgY29uc3QgeXN0YXRlID0geVN5bmNQbHVnaW5LZXkuZ2V0U3RhdGUodmlldy5zdGF0ZSlcbiAgICAgICAgLy8gYHlzdGF0ZWAgaXMgdW5kZWZpbmVkIGR1cmluZyBzeW5jLXBsdWdpbiBpbml0IGFuZCBZLkRvYyB0cmFuc2l0aW9ucztcbiAgICAgICAgLy8gcmVhZGluZyBmcm9tIGl0IGhlcmUgd291bGQgdGhyb3cgYW5kIGJyZWFrIGN1cnNvciB0cmFja2luZyBmb3IgdGhlIHZpZXcuXG4gICAgICAgIGlmICgheXN0YXRlIHx8ICF5c3RhdGUuYmluZGluZykgcmV0dXJuXG4gICAgICAgIC8vIEBub3RlIFdlIG1ha2UgaW1wbGljaXQgY2hlY2tzIHdoZW4gY2hlY2tpbmcgZm9yIHRoZSBjdXJzb3IgcHJvcGVydHlcbiAgICAgICAgY29uc3QgY3VycmVudCA9IGF3YXJlbmVzcy5nZXRMb2NhbFN0YXRlKCkgfHwge31cbiAgICAgICAgaWYgKHZpZXcuaGFzRm9jdXMoKSkge1xuICAgICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IGdldFNlbGVjdGlvbih2aWV3LnN0YXRlKVxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEB0eXBlIHtZLlJlbGF0aXZlUG9zaXRpb259XG4gICAgICAgICAgICovXG4gICAgICAgICAgY29uc3QgYW5jaG9yID0gYWJzb2x1dGVQb3NpdGlvblRvUmVsYXRpdmVQb3NpdGlvbihcbiAgICAgICAgICAgIHNlbGVjdGlvbi5hbmNob3IsXG4gICAgICAgICAgICB5c3RhdGUudHlwZSxcbiAgICAgICAgICAgIHlzdGF0ZS5iaW5kaW5nLm1hcHBpbmdcbiAgICAgICAgICApXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQHR5cGUge1kuUmVsYXRpdmVQb3NpdGlvbn1cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBjb25zdCBoZWFkID0gYWJzb2x1dGVQb3NpdGlvblRvUmVsYXRpdmVQb3NpdGlvbihcbiAgICAgICAgICAgIHNlbGVjdGlvbi5oZWFkLFxuICAgICAgICAgICAgeXN0YXRlLnR5cGUsXG4gICAgICAgICAgICB5c3RhdGUuYmluZGluZy5tYXBwaW5nXG4gICAgICAgICAgKVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGN1cnJlbnQuY3Vyc29yID09IG51bGwgfHxcbiAgICAgICAgICAgICFZLmNvbXBhcmVSZWxhdGl2ZVBvc2l0aW9ucyhcbiAgICAgICAgICAgICAgWS5jcmVhdGVSZWxhdGl2ZVBvc2l0aW9uRnJvbUpTT04oY3VycmVudC5jdXJzb3IuYW5jaG9yKSxcbiAgICAgICAgICAgICAgYW5jaG9yXG4gICAgICAgICAgICApIHx8XG4gICAgICAgICAgICAhWS5jb21wYXJlUmVsYXRpdmVQb3NpdGlvbnMoXG4gICAgICAgICAgICAgIFkuY3JlYXRlUmVsYXRpdmVQb3NpdGlvbkZyb21KU09OKGN1cnJlbnQuY3Vyc29yLmhlYWQpLFxuICAgICAgICAgICAgICBoZWFkXG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBhd2FyZW5lc3Muc2V0TG9jYWxTdGF0ZUZpZWxkKGN1cnNvclN0YXRlRmllbGQsIHtcbiAgICAgICAgICAgICAgYW5jaG9yLFxuICAgICAgICAgICAgICBoZWFkXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBjdXJyZW50LmN1cnNvciAhPSBudWxsICYmXG4gICAgICAgICAgcmVsYXRpdmVQb3NpdGlvblRvQWJzb2x1dGVQb3NpdGlvbihcbiAgICAgICAgICAgIHlzdGF0ZS5kb2MsXG4gICAgICAgICAgICB5c3RhdGUudHlwZSxcbiAgICAgICAgICAgIFkuY3JlYXRlUmVsYXRpdmVQb3NpdGlvbkZyb21KU09OKGN1cnJlbnQuY3Vyc29yLmFuY2hvciksXG4gICAgICAgICAgICB5c3RhdGUuYmluZGluZy5tYXBwaW5nXG4gICAgICAgICAgKSAhPT0gbnVsbFxuICAgICAgICApIHtcbiAgICAgICAgICAvLyBkZWxldGUgY3Vyc29yIGluZm9ybWF0aW9uIGlmIGN1cnJlbnQgY3Vyc29yIGluZm9ybWF0aW9uIGlzIG93bmVkIGJ5IHRoaXMgZWRpdG9yIGJpbmRpbmdcbiAgICAgICAgICBhd2FyZW5lc3Muc2V0TG9jYWxTdGF0ZUZpZWxkKGN1cnNvclN0YXRlRmllbGQsIG51bGwpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGF3YXJlbmVzcy5vbignY2hhbmdlJywgYXdhcmVuZXNzTGlzdGVuZXIpXG4gICAgICB2aWV3LmRvbS5hZGRFdmVudExpc3RlbmVyKCdmb2N1c2luJywgdXBkYXRlQ3Vyc29ySW5mbylcbiAgICAgIHZpZXcuZG9tLmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3Vzb3V0JywgdXBkYXRlQ3Vyc29ySW5mbylcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHVwZGF0ZTogdXBkYXRlQ3Vyc29ySW5mbyxcbiAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgIHZpZXcuZG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3VzaW4nLCB1cGRhdGVDdXJzb3JJbmZvKVxuICAgICAgICAgIHZpZXcuZG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2ZvY3Vzb3V0JywgdXBkYXRlQ3Vyc29ySW5mbylcbiAgICAgICAgICBhd2FyZW5lc3Mub2ZmKCdjaGFuZ2UnLCBhd2FyZW5lc3NMaXN0ZW5lcilcbiAgICAgICAgICBhd2FyZW5lc3Muc2V0TG9jYWxTdGF0ZUZpZWxkKGN1cnNvclN0YXRlRmllbGQsIG51bGwpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0pXG4iLCAiaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblxuaW1wb3J0IHsgZ2V0UmVsYXRpdmVTZWxlY3Rpb24gfSBmcm9tICcuL3N5bmMtcGx1Z2luLmpzJ1xuaW1wb3J0IHsgVW5kb01hbmFnZXIsIEl0ZW0sIENvbnRlbnRUeXBlLCBYbWxFbGVtZW50LCBUZXh0IH0gZnJvbSAneWpzJ1xuaW1wb3J0IHsgeVVuZG9QbHVnaW5LZXksIHlTeW5jUGx1Z2luS2V5IH0gZnJvbSAnLi9rZXlzLmpzJ1xuXG5leHBvcnQgY29uc3QgdW5kbyA9IHN0YXRlID0+IHtcbiAgY29uc3QgdW5kb01hbmFnZXIgPSB5VW5kb1BsdWdpbktleS5nZXRTdGF0ZShzdGF0ZSkudW5kb01hbmFnZXJcbiAgaWYgKHVuZG9NYW5hZ2VyICE9IG51bGwpIHtcbiAgICB1bmRvTWFuYWdlci51bmRvKClcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCByZWRvID0gc3RhdGUgPT4ge1xuICBjb25zdCB1bmRvTWFuYWdlciA9IHlVbmRvUGx1Z2luS2V5LmdldFN0YXRlKHN0YXRlKS51bmRvTWFuYWdlclxuICBpZiAodW5kb01hbmFnZXIgIT0gbnVsbCkge1xuICAgIHVuZG9NYW5hZ2VyLnJlZG8oKVxuICAgIHJldHVybiB0cnVlXG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRQcm90ZWN0ZWROb2RlcyA9IG5ldyBTZXQoWydwYXJhZ3JhcGgnXSlcblxuZXhwb3J0IGNvbnN0IGRlZmF1bHREZWxldGVGaWx0ZXIgPSAoaXRlbSwgcHJvdGVjdGVkTm9kZXMpID0+ICEoaXRlbSBpbnN0YW5jZW9mIEl0ZW0pIHx8XG4hKGl0ZW0uY29udGVudCBpbnN0YW5jZW9mIENvbnRlbnRUeXBlKSB8fFxuIShpdGVtLmNvbnRlbnQudHlwZSBpbnN0YW5jZW9mIFRleHQgfHxcbiAgKGl0ZW0uY29udGVudC50eXBlIGluc3RhbmNlb2YgWG1sRWxlbWVudCAmJiBwcm90ZWN0ZWROb2Rlcy5oYXMoaXRlbS5jb250ZW50LnR5cGUubm9kZU5hbWUpKSkgfHxcbml0ZW0uY29udGVudC50eXBlLl9sZW5ndGggPT09IDBcblxuZXhwb3J0IGNvbnN0IHlVbmRvUGx1Z2luID0gKHsgcHJvdGVjdGVkTm9kZXMgPSBkZWZhdWx0UHJvdGVjdGVkTm9kZXMsIHRyYWNrZWRPcmlnaW5zID0gW10sIHVuZG9NYW5hZ2VyID0gbnVsbCB9ID0ge30pID0+IG5ldyBQbHVnaW4oe1xuICBrZXk6IHlVbmRvUGx1Z2luS2V5LFxuICBzdGF0ZToge1xuICAgIGluaXQ6IChpbml0YXJncywgc3RhdGUpID0+IHtcbiAgICAgIC8vIFRPRE86IGNoZWNrIGlmIHBsdWdpbiBvcmRlciBtYXRjaGVzIGFuZCBmaXhcbiAgICAgIGNvbnN0IHlzdGF0ZSA9IHlTeW5jUGx1Z2luS2V5LmdldFN0YXRlKHN0YXRlKVxuICAgICAgbGV0IF91bmRvTWFuYWdlciA9IHVuZG9NYW5hZ2VyXG4gICAgICBpZiAoIV91bmRvTWFuYWdlcikge1xuICAgICAgICAvLyBZLlVuZG9NYW5hZ2VyIHJlZ2lzdGVycyBhIGBkb2Mub24oJ2Rlc3Ryb3knLCDigKYpYCBsaXN0ZW5lciBpbiBpdHNcbiAgICAgICAgLy8gY29uc3RydWN0b3IgdGhhdCBVbmRvTWFuYWdlci5kZXN0cm95KCkgbmV2ZXIgcmVtb3Zlcy4gV2hlbiB0aGUgZG9jXG4gICAgICAgIC8vIG91dGxpdmVzIHRoZSBlZGl0b3IgKGUuZy4gc2V2ZXJhbCBlZGl0b3JzIHNoYXJpbmcgb25lIHByb3ZpZGVyKSwgdGhhdFxuICAgICAgICAvLyBsaXN0ZW5lciBrZWVwcyB0aGUgVW5kb01hbmFnZXIg4oCUIGFuZCBldmVyeXRoaW5nIGl0IHJlZmVyZW5jZXMg4oCUXG4gICAgICAgIC8vIHJlYWNoYWJsZSBmcm9tIHRoZSBkb2MsIGxlYWtpbmcgbWVtb3J5IG9uIGV2ZXJ5IGVkaXRvciBkZXN0cm95LlxuICAgICAgICAvLyBXZSBvbmx5IG93biB0aGUgbGlmZWN5Y2xlIG9mIGEgbWFuYWdlciB3ZSBjcmVhdGUgaGVyZSwgc28gY2FwdHVyZSB0aGVcbiAgICAgICAgLy8gbGlzdGVuZXIocykgaXQgYWRkcyBhbmQgcmVtb3ZlIHRoZW0gd2hlbiB0aGUgcGx1Z2luIHZpZXcgaXMgZGVzdHJveWVkLlxuICAgICAgICBjb25zdCBkb2MgPSB5c3RhdGUuZG9jXG4gICAgICAgIGNvbnN0IGRlc3Ryb3lMaXN0ZW5lcnNCZWZvcmUgPSBuZXcgU2V0KGRvYyA/IGRvYy5fb2JzZXJ2ZXJzLmdldCgnZGVzdHJveScpIDogW10pXG4gICAgICAgIF91bmRvTWFuYWdlciA9IG5ldyBVbmRvTWFuYWdlcih5c3RhdGUudHlwZSwge1xuICAgICAgICAgIHRyYWNrZWRPcmlnaW5zOiBuZXcgU2V0KFt5U3luY1BsdWdpbktleV0uY29uY2F0KHRyYWNrZWRPcmlnaW5zKSksXG4gICAgICAgICAgZGVsZXRlRmlsdGVyOiAoaXRlbSkgPT4gZGVmYXVsdERlbGV0ZUZpbHRlcihpdGVtLCBwcm90ZWN0ZWROb2RlcyksXG4gICAgICAgICAgY2FwdHVyZVRyYW5zYWN0aW9uOiB0ciA9PiB0ci5tZXRhLmdldCgnYWRkVG9IaXN0b3J5JykgIT09IGZhbHNlXG4gICAgICAgIH0pXG4gICAgICAgIGNvbnN0IGRlc3Ryb3lMaXN0ZW5lcnNBZnRlciA9IGRvYyA/IGRvYy5fb2JzZXJ2ZXJzLmdldCgnZGVzdHJveScpIDogbmV3IFNldCgpXG4gICAgICAgIF91bmRvTWFuYWdlci5feVRpcHRhcERvY0Rlc3Ryb3lMaXN0ZW5lcnMgPSBBcnJheS5mcm9tKGRlc3Ryb3lMaXN0ZW5lcnNBZnRlciB8fCBbXSlcbiAgICAgICAgICAuZmlsdGVyKGxpc3RlbmVyID0+ICFkZXN0cm95TGlzdGVuZXJzQmVmb3JlLmhhcyhsaXN0ZW5lcikpXG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICB1bmRvTWFuYWdlcjogX3VuZG9NYW5hZ2VyLFxuICAgICAgICBwcmV2U2VsOiBudWxsLFxuICAgICAgICBoYXNVbmRvT3BzOiBfdW5kb01hbmFnZXIudW5kb1N0YWNrLmxlbmd0aCA+IDAsXG4gICAgICAgIGhhc1JlZG9PcHM6IF91bmRvTWFuYWdlci5yZWRvU3RhY2subGVuZ3RoID4gMFxuICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICogQHJldHVybnMge2FueX1cbiAgICAgKi9cbiAgICBhcHBseTogKHRyLCB2YWwsIG9sZFN0YXRlLCBzdGF0ZSkgPT4ge1xuICAgICAgY29uc3QgYmluZGluZyA9IHlTeW5jUGx1Z2luS2V5LmdldFN0YXRlKHN0YXRlKS5iaW5kaW5nXG4gICAgICBjb25zdCB1bmRvTWFuYWdlciA9IHZhbC51bmRvTWFuYWdlclxuICAgICAgY29uc3QgaGFzVW5kb09wcyA9IHVuZG9NYW5hZ2VyLnVuZG9TdGFjay5sZW5ndGggPiAwXG4gICAgICBjb25zdCBoYXNSZWRvT3BzID0gdW5kb01hbmFnZXIucmVkb1N0YWNrLmxlbmd0aCA+IDBcbiAgICAgIGlmIChiaW5kaW5nKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdW5kb01hbmFnZXIsXG4gICAgICAgICAgcHJldlNlbDogZ2V0UmVsYXRpdmVTZWxlY3Rpb24oYmluZGluZywgb2xkU3RhdGUpLFxuICAgICAgICAgIGhhc1VuZG9PcHMsXG4gICAgICAgICAgaGFzUmVkb09wc1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaGFzVW5kb09wcyAhPT0gdmFsLmhhc1VuZG9PcHMgfHwgaGFzUmVkb09wcyAhPT0gdmFsLmhhc1JlZG9PcHMpIHtcbiAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgdmFsLCB7XG4gICAgICAgICAgICBoYXNVbmRvT3BzOiB1bmRvTWFuYWdlci51bmRvU3RhY2subGVuZ3RoID4gMCxcbiAgICAgICAgICAgIGhhc1JlZG9PcHM6IHVuZG9NYW5hZ2VyLnJlZG9TdGFjay5sZW5ndGggPiAwXG4gICAgICAgICAgfSlcbiAgICAgICAgfSBlbHNlIHsgLy8gbm90aGluZyBjaGFuZ2VkXG4gICAgICAgICAgcmV0dXJuIHZhbFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9LFxuICB2aWV3OiB2aWV3ID0+IHtcbiAgICBjb25zdCB5c3RhdGUgPSB5U3luY1BsdWdpbktleS5nZXRTdGF0ZSh2aWV3LnN0YXRlKVxuICAgIGNvbnN0IHVuZG9NYW5hZ2VyID0geVVuZG9QbHVnaW5LZXkuZ2V0U3RhdGUodmlldy5zdGF0ZSkudW5kb01hbmFnZXJcbiAgICB1bmRvTWFuYWdlci5vbignc3RhY2staXRlbS1hZGRlZCcsICh7IHN0YWNrSXRlbSB9KSA9PiB7XG4gICAgICBjb25zdCBiaW5kaW5nID0geXN0YXRlLmJpbmRpbmdcbiAgICAgIGlmIChiaW5kaW5nKSB7XG4gICAgICAgIHN0YWNrSXRlbS5tZXRhLnNldChiaW5kaW5nLCB5VW5kb1BsdWdpbktleS5nZXRTdGF0ZSh2aWV3LnN0YXRlKS5wcmV2U2VsKVxuICAgICAgfVxuICAgIH0pXG4gICAgdW5kb01hbmFnZXIub24oJ3N0YWNrLWl0ZW0tcG9wcGVkJywgKHsgc3RhY2tJdGVtIH0pID0+IHtcbiAgICAgIGNvbnN0IGJpbmRpbmcgPSB5c3RhdGUuYmluZGluZ1xuICAgICAgaWYgKGJpbmRpbmcpIHtcbiAgICAgICAgYmluZGluZy5iZWZvcmVUcmFuc2FjdGlvblNlbGVjdGlvbiA9IHN0YWNrSXRlbS5tZXRhLmdldChiaW5kaW5nKSB8fCBiaW5kaW5nLmJlZm9yZVRyYW5zYWN0aW9uU2VsZWN0aW9uXG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4ge1xuICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICB1bmRvTWFuYWdlci5kZXN0cm95KClcbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBkb2MgJ2Rlc3Ryb3knIGxpc3RlbmVyIFkuVW5kb01hbmFnZXIgZmFpbHMgdG8gY2xlYW4gdXBcbiAgICAgICAgLy8gKG9ubHkgZm9yIG1hbmFnZXJzIHdlIGNyZWF0ZWQg4oCUIHNlZSBzdGF0ZS5pbml0IGFib3ZlKS5cbiAgICAgICAgY29uc3QgbGVha2VkRGVzdHJveUxpc3RlbmVycyA9IHVuZG9NYW5hZ2VyLl95VGlwdGFwRG9jRGVzdHJveUxpc3RlbmVyc1xuICAgICAgICBpZiAobGVha2VkRGVzdHJveUxpc3RlbmVycyAmJiB1bmRvTWFuYWdlci5kb2MpIHtcbiAgICAgICAgICBsZWFrZWREZXN0cm95TGlzdGVuZXJzLmZvckVhY2gobGlzdGVuZXIgPT4gdW5kb01hbmFnZXIuZG9jLm9mZignZGVzdHJveScsIGxpc3RlbmVyKSlcbiAgICAgICAgICB1bmRvTWFuYWdlci5feVRpcHRhcERvY0Rlc3Ryb3lMaXN0ZW5lcnMgPSBudWxsXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbn0pXG4iLCAiaW1wb3J0IHsgRXh0ZW5zaW9uIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHR5cGUgeyBFZGl0b3JWaWV3IH0gZnJvbSAnQHRpcHRhcC9wbS92aWV3J1xuaW1wb3J0IHsgcmVkbywgdW5kbywgeVN5bmNQbHVnaW4sIHlVbmRvUGx1Z2luLCB5VW5kb1BsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAveS10aXB0YXAnXG5pbXBvcnQgdHlwZSB7IERvYywgVW5kb01hbmFnZXIsIFhtbEZyYWdtZW50IH0gZnJvbSAneWpzJ1xuXG5pbXBvcnQge1xuICBjcmVhdGVNYXBwYWJsZVBvc2l0aW9uLFxuICBnZXRVcGRhdGVkUG9zaXRpb24sXG59IGZyb20gJy4vaGVscGVycy9Db2xsYWJvcmF0aW9uTWFwcGFibGVQb3NpdGlvbi5qcydcbmltcG9ydCB7IGlzQ2hhbmdlT3JpZ2luIH0gZnJvbSAnLi9oZWxwZXJzL2lzQ2hhbmdlT3JpZ2luLmpzJ1xuXG50eXBlIFlTeW5jT3B0cyA9IFBhcmFtZXRlcnM8dHlwZW9mIHlTeW5jUGx1Z2luPlsxXVxudHlwZSBZVW5kb09wdHMgPSBQYXJhbWV0ZXJzPHR5cGVvZiB5VW5kb1BsdWdpbj5bMF1cblxuZXhwb3J0IGludGVyZmFjZSBDb2xsYWJvcmF0aW9uU3RvcmFnZSB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIGNvbGxhYm9yYXRpb24gaXMgY3VycmVudGx5IGRpc2FibGVkLlxuICAgKiBEaXNhYmxpbmcgY29sbGFib3JhdGlvbiB3aWxsIHByZXZlbnQgYW55IGNoYW5nZXMgZnJvbSBiZWluZyBzeW5jZWQgd2l0aCBvdGhlciB1c2Vycy5cbiAgICovXG4gIGlzRGlzYWJsZWQ6IGJvb2xlYW5cbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGNvbGxhYm9yYXRpb246IHtcbiAgICAgIC8qKlxuICAgICAgICogVW5kbyByZWNlbnQgY2hhbmdlc1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnVuZG8oKVxuICAgICAgICovXG4gICAgICB1bmRvOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgICAvKipcbiAgICAgICAqIFJlYXBwbHkgcmV2ZXJ0ZWQgY2hhbmdlc1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnJlZG8oKVxuICAgICAgICovXG4gICAgICByZWRvOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG5cbiAgaW50ZXJmYWNlIFN0b3JhZ2Uge1xuICAgIGNvbGxhYm9yYXRpb246IENvbGxhYm9yYXRpb25TdG9yYWdlXG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb2xsYWJvcmF0aW9uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBBbiBpbml0aWFsaXplZCBZLmpzIGRvY3VtZW50LlxuICAgKiBAZXhhbXBsZSBuZXcgWS5Eb2MoKVxuICAgKi9cbiAgZG9jdW1lbnQ/OiBEb2MgfCBudWxsXG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgYSBZLmpzIGZyYWdtZW50LCBjYW4gYmUgY2hhbmdlZCB0byBzeW5jIG11bHRpcGxlIGZpZWxkcyB3aXRoIG9uZSBZLmpzIGRvY3VtZW50LlxuICAgKiBAZGVmYXVsdCAnZGVmYXVsdCdcbiAgICogQGV4YW1wbGUgJ215LWN1c3RvbS1maWVsZCdcbiAgICovXG4gIGZpZWxkPzogc3RyaW5nXG5cbiAgLyoqXG4gICAqIEEgcmF3IFkuanMgZnJhZ21lbnQsIGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgYGRvY3VtZW50YCBhbmQgYGZpZWxkYC5cbiAgICogQGV4YW1wbGUgbmV3IFkuRG9jKCkuZ2V0WG1sRnJhZ21lbnQoJ2JvZHknKVxuICAgKi9cbiAgZnJhZ21lbnQ/OiBYbWxGcmFnbWVudCB8IG51bGxcblxuICAvKipcbiAgICogVGhlIGNvbGxhYm9yYXRpb24gcHJvdmlkZXIuXG4gICAqIEBkZWZhdWx0IG51bGxcbiAgICovXG4gIHByb3ZpZGVyPzogYW55IHwgbnVsbFxuXG4gIC8qKlxuICAgKiBGaXJlZCB3aGVuIHRoZSBjb250ZW50IGZyb20gWWpzIGlzIGluaXRpYWxseSByZW5kZXJlZCB0byBUaXB0YXAuXG4gICAqL1xuICBvbkZpcnN0UmVuZGVyPzogKCkgPT4gdm9pZFxuXG4gIC8qKlxuICAgKiBPcHRpb25zIGZvciB0aGUgWWpzIHN5bmMgcGx1Z2luLlxuICAgKi9cbiAgeVN5bmNPcHRpb25zPzogWVN5bmNPcHRzXG5cbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIHRoZSBZanMgdW5kbyBwbHVnaW4uXG4gICAqL1xuICB5VW5kb09wdGlvbnM/OiBZVW5kb09wdHNcbn1cblxuLyoqXG4gKiBUaGlzIGV4dGVuc2lvbiBhbGxvd3MgeW91IHRvIGNvbGxhYm9yYXRlIHdpdGggb3RoZXJzIGluIHJlYWwtdGltZS5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2FwaS9leHRlbnNpb25zL2NvbGxhYm9yYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IENvbGxhYm9yYXRpb24gPSBFeHRlbnNpb24uY3JlYXRlPENvbGxhYm9yYXRpb25PcHRpb25zLCBDb2xsYWJvcmF0aW9uU3RvcmFnZT4oe1xuICBuYW1lOiAnY29sbGFib3JhdGlvbicsXG5cbiAgcHJpb3JpdHk6IDEwMDAsXG5cbiAgYWRkT3B0aW9ucygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZG9jdW1lbnQ6IG51bGwsXG4gICAgICBmaWVsZDogJ2RlZmF1bHQnLFxuICAgICAgZnJhZ21lbnQ6IG51bGwsXG4gICAgICBwcm92aWRlcjogbnVsbCxcbiAgICB9XG4gIH0sXG5cbiAgYWRkU3RvcmFnZSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgaXNEaXNhYmxlZDogZmFsc2UsXG4gICAgfVxuICB9LFxuXG4gIG9uQ3JlYXRlKCkge1xuICAgIGlmICh0aGlzLmVkaXRvci5leHRlbnNpb25NYW5hZ2VyLmV4dGVuc2lvbnMuZmluZChleHRlbnNpb24gPT4gZXh0ZW5zaW9uLm5hbWUgPT09ICd1bmRvUmVkbycpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdbdGlwdGFwIHdhcm5dOiBcIkB0aXB0YXAvZXh0ZW5zaW9uLWNvbGxhYm9yYXRpb25cIiBjb21lcyB3aXRoIGl0cyBvd24gaGlzdG9yeSBzdXBwb3J0IGFuZCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIFwiQHRpcHRhcC9leHRlbnNpb24tdW5kby1yZWRvXCIuJyxcbiAgICAgIClcbiAgICB9XG4gIH0sXG5cbiAgb25CZWZvcmVDcmVhdGUoKSB7XG4gICAgdGhpcy5lZGl0b3IudXRpbHMuZ2V0VXBkYXRlZFBvc2l0aW9uID0gKHBvc2l0aW9uLCB0cmFuc2FjdGlvbikgPT5cbiAgICAgIGdldFVwZGF0ZWRQb3NpdGlvbihwb3NpdGlvbiwgdHJhbnNhY3Rpb24sIHRoaXMuZWRpdG9yLnN0YXRlKVxuICAgIHRoaXMuZWRpdG9yLnV0aWxzLmNyZWF0ZU1hcHBhYmxlUG9zaXRpb24gPSBwb3NpdGlvbiA9PlxuICAgICAgY3JlYXRlTWFwcGFibGVQb3NpdGlvbihwb3NpdGlvbiwgdGhpcy5lZGl0b3Iuc3RhdGUpXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHVuZG86XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IHRyLCBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgICAgICAgIHRyLnNldE1ldGEoJ3ByZXZlbnREaXNwYXRjaCcsIHRydWUpXG5cbiAgICAgICAgICBjb25zdCB1bmRvTWFuYWdlcjogVW5kb01hbmFnZXIgPSB5VW5kb1BsdWdpbktleS5nZXRTdGF0ZShzdGF0ZSkudW5kb01hbmFnZXJcblxuICAgICAgICAgIGlmICh1bmRvTWFuYWdlci51bmRvU3RhY2subGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWRpc3BhdGNoKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB1bmRvKHN0YXRlKVxuICAgICAgICB9LFxuICAgICAgcmVkbzpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgdHIsIHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgICAgICAgdHIuc2V0TWV0YSgncHJldmVudERpc3BhdGNoJywgdHJ1ZSlcblxuICAgICAgICAgIGNvbnN0IHVuZG9NYW5hZ2VyOiBVbmRvTWFuYWdlciA9IHlVbmRvUGx1Z2luS2V5LmdldFN0YXRlKHN0YXRlKS51bmRvTWFuYWdlclxuXG4gICAgICAgICAgaWYgKHVuZG9NYW5hZ2VyLnJlZG9TdGFjay5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghZGlzcGF0Y2gpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHJlZG8oc3RhdGUpXG4gICAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnTW9kLXonOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy51bmRvKCksXG4gICAgICAnTW9kLXknOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5yZWRvKCksXG4gICAgICAnU2hpZnQtTW9kLXonOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5yZWRvKCksXG4gICAgfVxuICB9LFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICBjb25zdCBmcmFnbWVudCA9IHRoaXMub3B0aW9ucy5mcmFnbWVudFxuICAgICAgPyB0aGlzLm9wdGlvbnMuZnJhZ21lbnRcbiAgICAgIDogKHRoaXMub3B0aW9ucy5kb2N1bWVudCBhcyBEb2MpLmdldFhtbEZyYWdtZW50KHRoaXMub3B0aW9ucy5maWVsZClcblxuICAgIC8vIFF1aWNrIGZpeCB1bnRpbCB0aGVyZSBpcyBhbiBvZmZpY2lhbCBpbXBsZW1lbnRhdGlvbiAodGhhbmtzIHRvIEBoYW1mbHgpLlxuICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20veWpzL3ktcHJvc2VtaXJyb3IvaXNzdWVzLzExNCBhbmQgaHR0cHM6Ly9naXRodWIuY29tL3lqcy95LXByb3NlbWlycm9yL2lzc3Vlcy8xMDJcbiAgICBjb25zdCB5VW5kb1BsdWdpbkluc3RhbmNlID0geVVuZG9QbHVnaW4odGhpcy5vcHRpb25zLnlVbmRvT3B0aW9ucylcbiAgICBjb25zdCBvcmlnaW5hbFVuZG9QbHVnaW5WaWV3ID0geVVuZG9QbHVnaW5JbnN0YW5jZS5zcGVjLnZpZXdcblxuICAgIHlVbmRvUGx1Z2luSW5zdGFuY2Uuc3BlYy52aWV3ID0gKHZpZXc6IEVkaXRvclZpZXcpID0+IHtcbiAgICAgIGNvbnN0IHsgdW5kb01hbmFnZXIgfSA9IHlVbmRvUGx1Z2luS2V5LmdldFN0YXRlKHZpZXcuc3RhdGUpXG5cbiAgICAgIGlmICh1bmRvTWFuYWdlci5yZXN0b3JlKSB7XG4gICAgICAgIHVuZG9NYW5hZ2VyLnJlc3RvcmUoKVxuICAgICAgICB1bmRvTWFuYWdlci5yZXN0b3JlID0gKCkgPT4ge1xuICAgICAgICAgIC8vIG5vb3BcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCB2aWV3UmV0ID0gb3JpZ2luYWxVbmRvUGx1Z2luVmlldyA/IG9yaWdpbmFsVW5kb1BsdWdpblZpZXcodmlldykgOiB1bmRlZmluZWRcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGVzdHJveTogKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGhhc1VuZG9NYW5TZWxmID0gdW5kb01hbmFnZXIudHJhY2tlZE9yaWdpbnMuaGFzKHVuZG9NYW5hZ2VyKVxuICAgICAgICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlcnNjb3JlLWRhbmdsZVxuICAgICAgICAgIGNvbnN0IG9ic2VydmVycyA9IHVuZG9NYW5hZ2VyLl9vYnNlcnZlcnNcblxuICAgICAgICAgIHVuZG9NYW5hZ2VyLnJlc3RvcmUgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoaGFzVW5kb01hblNlbGYpIHtcbiAgICAgICAgICAgICAgdW5kb01hbmFnZXIudHJhY2tlZE9yaWdpbnMuYWRkKHVuZG9NYW5hZ2VyKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB1bmRvTWFuYWdlci5kb2Mub24oJ2FmdGVyVHJhbnNhY3Rpb24nLCB1bmRvTWFuYWdlci5hZnRlclRyYW5zYWN0aW9uSGFuZGxlcilcbiAgICAgICAgICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlcnNjb3JlLWRhbmdsZVxuICAgICAgICAgICAgdW5kb01hbmFnZXIuX29ic2VydmVycyA9IG9ic2VydmVyc1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh2aWV3UmV0Py5kZXN0cm95KSB7XG4gICAgICAgICAgICB2aWV3UmV0LmRlc3Ryb3koKVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB5U3luY1BsdWdpbk9wdGlvbnM6IFlTeW5jT3B0cyA9IHtcbiAgICAgIC4uLnRoaXMub3B0aW9ucy55U3luY09wdGlvbnMsXG4gICAgICBvbkZpcnN0UmVuZGVyOiB0aGlzLm9wdGlvbnMub25GaXJzdFJlbmRlcixcbiAgICB9XG5cbiAgICBjb25zdCB5U3luY1BsdWdpbkluc3RhbmNlID0geVN5bmNQbHVnaW4oZnJhZ21lbnQsIHlTeW5jUGx1Z2luT3B0aW9ucylcblxuICAgIHJldHVybiBbXG4gICAgICB5U3luY1BsdWdpbkluc3RhbmNlLFxuICAgICAgeVVuZG9QbHVnaW5JbnN0YW5jZSxcbiAgICAgIC8vIE9ubHkgYWRkIHRoZSBmaWx0ZXJJbnZhbGlkQ29udGVudCBwbHVnaW4gaWYgY29udGVudCBjaGVja2luZyBpcyBlbmFibGVkXG4gICAgICB0aGlzLmVkaXRvci5vcHRpb25zLmVuYWJsZUNvbnRlbnRDaGVjayAmJlxuICAgICAgICBuZXcgUGx1Z2luKHtcbiAgICAgICAgICBrZXk6IG5ldyBQbHVnaW5LZXkoJ2ZpbHRlckludmFsaWRDb250ZW50JyksXG4gICAgICAgICAgZmlsdGVyVHJhbnNhY3Rpb246IHRyYW5zYWN0aW9uID0+IHtcbiAgICAgICAgICAgIGlmICghaXNDaGFuZ2VPcmlnaW4odHJhbnNhY3Rpb24pKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlLmlzRGlzYWJsZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXRyYW5zYWN0aW9uLmRvY0NoYW5nZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHRyYW5zYWN0aW9uLmRvYy5jaGVjaygpXG4gICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICB0aGlzLnN0b3JhZ2UuaXNEaXNhYmxlZCA9IHRydWVcbiAgICAgICAgICAgICAgdGhpcy5lZGl0b3IuZW1pdCgnY29udGVudEVycm9yJywge1xuICAgICAgICAgICAgICAgIGVycm9yOiBlcnJvciBhcyBFcnJvcixcbiAgICAgICAgICAgICAgICBlZGl0b3I6IHRoaXMuZWRpdG9yLFxuICAgICAgICAgICAgICAgIGRpc2FibGVDb2xsYWJvcmF0aW9uOiAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICBmcmFnbWVudC5kb2M/LmRlc3Ryb3koKVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC8vIEFsbG93IHRoZSB0cmFuc2FjdGlvbiBzbyBQcm9zZU1pcnJvciBzdGF0ZSBzdGF5cyBpbiBzeW5jIHdpdGggWWpzXG4gICAgICAgICAgICAgIC8vIChZanMgdHJhbnNhY3Rpb25zIGNhbm5vdCBiZSBjYW5jZWxsZWQpLiBSZXR1cm5pbmcgZmFsc2Ugd291bGQgY2F1c2VcbiAgICAgICAgICAgICAgLy8gYSBzdGF0ZSBtaXNtYXRjaCBhbmQgcHJldmVudCBvbkNvbnRlbnRFcnJvciBmcm9tIHdvcmtpbmcgcHJvcGVybHkuXG4gICAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgXS5maWx0ZXIoQm9vbGVhbilcbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHtcbiAgdHlwZSBHZXRVcGRhdGVkUG9zaXRpb25SZXN1bHQsXG4gIGdldFVwZGF0ZWRQb3NpdGlvbiBhcyBjb3JlR2V0VXBkYXRlZFBvc2l0aW9uLFxuICBNYXBwYWJsZVBvc2l0aW9uLFxufSBmcm9tICdAdGlwdGFwL2NvcmUnXG5pbXBvcnQgdHlwZSB7IEVkaXRvclN0YXRlLCBUcmFuc2FjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IGlzQ2hhbmdlT3JpZ2luIH0gZnJvbSAnLi9pc0NoYW5nZU9yaWdpbi5qcydcbmltcG9ydCB7XG4gIHR5cGUgWVJlbGF0aXZlUG9zaXRpb24sXG4gIGdldFlBYnNvbHV0ZVBvc2l0aW9uLFxuICBnZXRZUmVsYXRpdmVQb3NpdGlvbixcbn0gZnJvbSAnLi95UmVsYXRpdmVQb3NpdGlvbi5qcydcblxuLyoqXG4gKiBBIE1hcHBhYmxlUG9zaXRpb24gc3ViY2xhc3MgdGhhdCBpbmNsdWRlcyBZLmpzIHJlbGF0aXZlIHBvc2l0aW9uIGluZm9ybWF0aW9uXG4gKiB0byB0cmFjayBwb3NpdGlvbnMgaW4gY29sbGFib3JhdGl2ZSB0cmFuc2FjdGlvbnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBDb2xsYWJvcmF0aW9uTWFwcGFibGVQb3NpdGlvbiBleHRlbmRzIE1hcHBhYmxlUG9zaXRpb24ge1xuICAvKipcbiAgICogVGhlIFkuanMgcmVsYXRpdmUgcG9zaXRpb24gdXNlZCBmb3IgbWFwcGluZyBwb3NpdGlvbnMgaW4gY29sbGFib3JhdGl2ZSBlZGl0aW5nLlxuICAgKi9cbiAgcHVibGljIHlSZWxhdGl2ZVBvc2l0aW9uOiBZUmVsYXRpdmVQb3NpdGlvblxuXG4gIGNvbnN0cnVjdG9yKHBvc2l0aW9uOiBudW1iZXIsIHlSZWxhdGl2ZVBvc2l0aW9uOiBZUmVsYXRpdmVQb3NpdGlvbikge1xuICAgIHN1cGVyKHBvc2l0aW9uKVxuICAgIHRoaXMueVJlbGF0aXZlUG9zaXRpb24gPSB5UmVsYXRpdmVQb3NpdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBDb2xsYWJvcmF0aW9uTWFwcGFibGVQb3NpdGlvbiBmcm9tIGEgSlNPTiBvYmplY3QuXG4gICAqL1xuICBzdGF0aWMgZnJvbUpTT04oanNvbjogYW55KTogQ29sbGFib3JhdGlvbk1hcHBhYmxlUG9zaXRpb24ge1xuICAgIHJldHVybiBuZXcgQ29sbGFib3JhdGlvbk1hcHBhYmxlUG9zaXRpb24oanNvbi5wb3NpdGlvbiwganNvbi55UmVsYXRpdmVQb3NpdGlvbilcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0aGUgQ29sbGFib3JhdGlvbk1hcHBhYmxlUG9zaXRpb24gdG8gYSBKU09OIG9iamVjdC5cbiAgICovXG4gIHRvSlNPTigpOiBhbnkge1xuICAgIHJldHVybiB7XG4gICAgICBwb3NpdGlvbjogdGhpcy5wb3NpdGlvbixcbiAgICAgIHlSZWxhdGl2ZVBvc2l0aW9uOiB0aGlzLnlSZWxhdGl2ZVBvc2l0aW9uLFxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBNYXBwYWJsZVBvc2l0aW9uIGZyb20gYSBwb3NpdGlvbiBudW1iZXIuXG4gKiBUaGlzIGlzIHRoZSBjb2xsYWJvcmF0aW9uIGltcGxlbWVudGF0aW9uIHRoYXQgcmV0dXJucyBhIENvbGxhYm9yYXRpb25NYXBwYWJsZVBvc2l0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTWFwcGFibGVQb3NpdGlvbihcbiAgcG9zaXRpb246IG51bWJlcixcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuKTogQ29sbGFib3JhdGlvbk1hcHBhYmxlUG9zaXRpb24ge1xuICBjb25zdCB5UmVsYXRpdmVQb3NpdGlvbiA9IGdldFlSZWxhdGl2ZVBvc2l0aW9uKHN0YXRlLCBwb3NpdGlvbilcbiAgcmV0dXJuIG5ldyBDb2xsYWJvcmF0aW9uTWFwcGFibGVQb3NpdGlvbihwb3NpdGlvbiwgeVJlbGF0aXZlUG9zaXRpb24pXG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbmV3IHBvc2l0aW9uIGFmdGVyIGFwcGx5aW5nIGEgdHJhbnNhY3Rpb24uIEhhbmRsZXMgYm90aCBZLmpzXG4gKiB0cmFuc2FjdGlvbnMgYW5kIHJlZ3VsYXIgdHJhbnNhY3Rpb25zLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VXBkYXRlZFBvc2l0aW9uKFxuICBwb3NpdGlvbjogTWFwcGFibGVQb3NpdGlvbixcbiAgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uLFxuICBzdGF0ZTogRWRpdG9yU3RhdGUsXG4pOiBHZXRVcGRhdGVkUG9zaXRpb25SZXN1bHQge1xuICBjb25zdCB5UmVsYXRpdmVQb3NpdGlvbiA9XG4gICAgcG9zaXRpb24gaW5zdGFuY2VvZiBDb2xsYWJvcmF0aW9uTWFwcGFibGVQb3NpdGlvbiA/IHBvc2l0aW9uLnlSZWxhdGl2ZVBvc2l0aW9uIDogbnVsbFxuXG4gIGlmIChpc0NoYW5nZU9yaWdpbih0cmFuc2FjdGlvbikgJiYgeVJlbGF0aXZlUG9zaXRpb24pIHtcbiAgICBjb25zdCBhYnNvbHV0ZVBvc2l0aW9uID0gZ2V0WUFic29sdXRlUG9zaXRpb24oc3RhdGUsIHlSZWxhdGl2ZVBvc2l0aW9uKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHBvc2l0aW9uOiBuZXcgQ29sbGFib3JhdGlvbk1hcHBhYmxlUG9zaXRpb24oYWJzb2x1dGVQb3NpdGlvbiwgeVJlbGF0aXZlUG9zaXRpb24pLFxuICAgICAgbWFwUmVzdWx0OiBudWxsLFxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJlc3VsdCA9IGNvcmVHZXRVcGRhdGVkUG9zaXRpb24ocG9zaXRpb24sIHRyYW5zYWN0aW9uKVxuXG4gIGNvbnN0IGFic29sdXRlUG9zaXRpb24gPSByZXN1bHQucG9zaXRpb24ucG9zaXRpb25cblxuICByZXR1cm4ge1xuICAgIHBvc2l0aW9uOiBuZXcgQ29sbGFib3JhdGlvbk1hcHBhYmxlUG9zaXRpb24oXG4gICAgICBhYnNvbHV0ZVBvc2l0aW9uLFxuICAgICAgeVJlbGF0aXZlUG9zaXRpb24gPz8gZ2V0WVJlbGF0aXZlUG9zaXRpb24oc3RhdGUsIGFic29sdXRlUG9zaXRpb24pLFxuICAgICksXG4gICAgbWFwUmVzdWx0OiByZXN1bHQubWFwUmVzdWx0LFxuICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBUcmFuc2FjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgeyB5U3luY1BsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAveS10aXB0YXAnXG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdHJhbnNhY3Rpb24gd2FzIG9yaWdpbmF0ZWQgZnJvbSBhIFlqcyBjaGFuZ2UuXG4gKiBAcGFyYW0ge1RyYW5zYWN0aW9ufSB0cmFuc2FjdGlvbiAtIFRoZSB0cmFuc2FjdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSAtIFRydWUgaWYgdGhlIHRyYW5zYWN0aW9uIHdhcyBvcmlnaW5hdGVkIGZyb20gYSBZanMgY2hhbmdlLCBmYWxzZSBvdGhlcndpc2UuXG4gKiBAZXhhbXBsZVxuICogY29uc3QgdHJhbnNhY3Rpb24gPSBuZXcgVHJhbnNhY3Rpb24oZG9jKVxuICogY29uc3QgaXNPcmlnaW4gPSBpc0NoYW5nZU9yaWdpbih0cmFuc2FjdGlvbikgLy8gcmV0dXJucyBmYWxzZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDaGFuZ2VPcmlnaW4odHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uKTogYm9vbGVhbiB7XG4gIHJldHVybiAhIXRyYW5zYWN0aW9uLmdldE1ldGEoeVN5bmNQbHVnaW5LZXkpXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBFZGl0b3JTdGF0ZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQge1xuICBhYnNvbHV0ZVBvc2l0aW9uVG9SZWxhdGl2ZVBvc2l0aW9uLFxuICByZWxhdGl2ZVBvc2l0aW9uVG9BYnNvbHV0ZVBvc2l0aW9uLFxuICB5U3luY1BsdWdpbktleSxcbn0gZnJvbSAnQHRpcHRhcC95LXRpcHRhcCdcblxuLyoqXG4gKiBBIHR5cGUgdGhhdCByZXByZXNlbnRzIGEgWS5qcyByZWxhdGl2ZSBwb3NpdGlvbi4gVXNlZCB0byBtYXAgYSBwb3NpdGlvbiBmcm9tXG4gKiBhIHRyYW5zYWN0aW9uLCBoYW5kbGluZyBib3RoIFlqcyBjaGFuZ2VzIGFuZCByZWd1bGFyIHRyYW5zYWN0aW9ucy5cbiAqXG4gKiBJZiB0aGUgZWRpdG9yIGlzIG5vdCBjb2xsYWJvcmF0aXZlLCB0aGUgdmFsdWUgY2FuIGJlIGBudWxsYC5cbiAqL1xuZXhwb3J0IHR5cGUgWVJlbGF0aXZlUG9zaXRpb24gPSBhbnlcblxuLyoqXG4gKiBDb252ZXJ0cyBhIFkuanMgcmVsYXRpdmUgcG9zaXRpb24gdG8gYSBwb3NpdGlvbiBpbiB0aGUgVGlwdGFwIGRvY3VtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0WUFic29sdXRlUG9zaXRpb24oc3RhdGU6IEVkaXRvclN0YXRlLCByZWxhdGl2ZVBvczogWVJlbGF0aXZlUG9zaXRpb24pOiBudW1iZXIge1xuICAvLyB5c3RhdGUgaXMgbmV2ZXIgbnVsbCBiZWNhdXNlIHdlJ3ZlIGNoZWNrZWQgaXQgYmVmb3JlIGNhbGxpbmcgdGhpcyBmdW5jdGlvblxuICBjb25zdCB5c3RhdGUgPSB5U3luY1BsdWdpbktleS5nZXRTdGF0ZShzdGF0ZSlcbiAgcmV0dXJuIChcbiAgICByZWxhdGl2ZVBvc2l0aW9uVG9BYnNvbHV0ZVBvc2l0aW9uKFxuICAgICAgeXN0YXRlLmRvYyxcbiAgICAgIHlzdGF0ZS50eXBlLFxuICAgICAgcmVsYXRpdmVQb3MsXG4gICAgICB5c3RhdGUuYmluZGluZy5tYXBwaW5nLFxuICAgICkgfHwgMFxuICApXG59XG5cbi8qKlxuICogQ29udmVydHMgYSBwb3NpdGlvbiBpbiB0aGUgVGlwdGFwIGRvY3VtZW50IHRvIGEgWS5qcyByZWxhdGl2ZSBwb3NpdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFlSZWxhdGl2ZVBvc2l0aW9uKHN0YXRlOiBFZGl0b3JTdGF0ZSwgYWJzb2x1dGVQb3M6IG51bWJlcik6IFlSZWxhdGl2ZVBvc2l0aW9uIHtcbiAgLy8geXN0YXRlIGlzIG5ldmVyIG51bGwgYmVjYXVzZSB3ZSd2ZSBjaGVja2VkIGl0IGJlZm9yZSBjYWxsaW5nIHRoaXMgZnVuY3Rpb25cbiAgY29uc3QgeXN0YXRlID0geVN5bmNQbHVnaW5LZXkuZ2V0U3RhdGUoc3RhdGUpXG4gIHJldHVybiBhYnNvbHV0ZVBvc2l0aW9uVG9SZWxhdGl2ZVBvc2l0aW9uKGFic29sdXRlUG9zLCB5c3RhdGUudHlwZSwgeXN0YXRlLmJpbmRpbmcubWFwcGluZylcbn1cbiIsICJpbXBvcnQgeyBDb2xsYWJvcmF0aW9uIH0gZnJvbSAnLi9jb2xsYWJvcmF0aW9uLmpzJ1xuXG5leHBvcnQgKiBmcm9tICcuL2NvbGxhYm9yYXRpb24uanMnXG5leHBvcnQgKiBmcm9tICcuL2hlbHBlcnMvQ29sbGFib3JhdGlvbk1hcHBhYmxlUG9zaXRpb24uanMnXG5leHBvcnQgKiBmcm9tICcuL2hlbHBlcnMvaXNDaGFuZ2VPcmlnaW4uanMnXG5cbmV4cG9ydCBkZWZhdWx0IENvbGxhYm9yYXRpb25cbiIsICJpbXBvcnQgeyBQbGFjZWhvbGRlciB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9ucydcblxuZXhwb3J0IHR5cGUgeyBQbGFjZWhvbGRlck9wdGlvbnMgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbnMnXG5leHBvcnQgeyBQbGFjZWhvbGRlciB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9ucydcblxuZXhwb3J0IGRlZmF1bHQgUGxhY2Vob2xkZXJcbiIsICJpbXBvcnQgeyBUYXNrTGlzdCB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLWxpc3QnXG5cbmV4cG9ydCB0eXBlIHsgVGFza0xpc3RPcHRpb25zIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tbGlzdCdcbmV4cG9ydCB7IFRhc2tMaXN0IH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tbGlzdCdcblxuZXhwb3J0IGRlZmF1bHQgVGFza0xpc3RcbiIsICJpbXBvcnQgeyBUYXNrSXRlbSB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLWxpc3QnXG5cbmV4cG9ydCB0eXBlIHsgVGFza0l0ZW1PcHRpb25zIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tbGlzdCdcbmV4cG9ydCB7IFRhc2tJdGVtIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tbGlzdCdcblxuZXhwb3J0IGRlZmF1bHQgVGFza0l0ZW1cbiIsICIvLyBCZWNhdXNlIHdvcmtpbmcgd2l0aCByb3cgYW5kIGNvbHVtbi1zcGFubmluZyBjZWxscyBpcyBub3QgcXVpdGVcbi8vIHRyaXZpYWwsIHRoaXMgY29kZSBidWlsZHMgdXAgYSBkZXNjcmlwdGl2ZSBzdHJ1Y3R1cmUgZm9yIGEgZ2l2ZW5cbi8vIHRhYmxlIG5vZGUuIFRoZSBzdHJ1Y3R1cmVzIGFyZSBjYWNoZWQgd2l0aCB0aGUgKHBlcnNpc3RlbnQpIHRhYmxlXG4vLyBub2RlcyBhcyBrZXksIHNvIHRoYXQgdGhleSBvbmx5IGhhdmUgdG8gYmUgcmVjb21wdXRlZCB3aGVuIHRoZVxuLy8gY29udGVudCBvZiB0aGUgdGFibGUgY2hhbmdlcy5cbi8vXG4vLyBUaGlzIGRvZXMgbWVhbiB0aGF0IHRoZXkgaGF2ZSB0byBzdG9yZSB0YWJsZS1yZWxhdGl2ZSwgbm90XG4vLyBkb2N1bWVudC1yZWxhdGl2ZSBwb3NpdGlvbnMuIFNvIGNvZGUgdGhhdCB1c2VzIHRoZW0gd2lsbCB0eXBpY2FsbHlcbi8vIGNvbXB1dGUgdGhlIHN0YXJ0IHBvc2l0aW9uIG9mIHRoZSB0YWJsZSBhbmQgb2Zmc2V0IHBvc2l0aW9ucyBwYXNzZWRcbi8vIHRvIG9yIGdvdHRlbiBmcm9tIHRoaXMgc3RydWN0dXJlIGJ5IHRoYXQgYW1vdW50LlxuaW1wb3J0IHR5cGUgeyBBdHRycywgTm9kZSB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcblxuaW1wb3J0IHR5cGUgeyBDZWxsQXR0cnMgfSBmcm9tICcuL3V0aWwnO1xuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgQ29sV2lkdGhzID0gbnVtYmVyW107XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBQcm9ibGVtID1cbiAgfCB7XG4gICAgICB0eXBlOiAnY29sd2lkdGggbWlzbWF0Y2gnO1xuICAgICAgcG9zOiBudW1iZXI7XG4gICAgICBjb2x3aWR0aDogQ29sV2lkdGhzO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnY29sbGlzaW9uJztcbiAgICAgIHBvczogbnVtYmVyO1xuICAgICAgcm93OiBudW1iZXI7XG4gICAgICBuOiBudW1iZXI7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdtaXNzaW5nJztcbiAgICAgIHJvdzogbnVtYmVyO1xuICAgICAgbjogbnVtYmVyO1xuICAgIH1cbiAgfCB7XG4gICAgICB0eXBlOiAnb3Zlcmxvbmdfcm93c3Bhbic7XG4gICAgICBwb3M6IG51bWJlcjtcbiAgICAgIG46IG51bWJlcjtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3plcm9fc2l6ZWQnO1xuICAgIH07XG5cbmxldCByZWFkRnJvbUNhY2hlOiAoa2V5OiBOb2RlKSA9PiBUYWJsZU1hcCB8IHVuZGVmaW5lZDtcbmxldCBhZGRUb0NhY2hlOiAoa2V5OiBOb2RlLCB2YWx1ZTogVGFibGVNYXApID0+IFRhYmxlTWFwO1xuXG4vLyBQcmVmZXIgdXNpbmcgYSB3ZWFrIG1hcCB0byBjYWNoZSB0YWJsZSBtYXBzLiBGYWxsIGJhY2sgb24gYVxuLy8gZml4ZWQtc2l6ZSBjYWNoZSBpZiB0aGF0J3Mgbm90IHN1cHBvcnRlZC5cbmlmICh0eXBlb2YgV2Vha01hcCAhPSAndW5kZWZpbmVkJykge1xuICBsZXQgY2FjaGUgPSBuZXcgV2Vha01hcDxOb2RlLCBUYWJsZU1hcD4oKTtcbiAgcmVhZEZyb21DYWNoZSA9IChrZXkpID0+IGNhY2hlLmdldChrZXkpO1xuICBhZGRUb0NhY2hlID0gKGtleSwgdmFsdWUpID0+IHtcbiAgICBjYWNoZS5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xufSBlbHNlIHtcbiAgY29uc3QgY2FjaGU6IChOb2RlIHwgVGFibGVNYXApW10gPSBbXTtcbiAgY29uc3QgY2FjaGVTaXplID0gMTA7XG4gIGxldCBjYWNoZVBvcyA9IDA7XG4gIHJlYWRGcm9tQ2FjaGUgPSAoa2V5KSA9PiB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjYWNoZS5sZW5ndGg7IGkgKz0gMilcbiAgICAgIGlmIChjYWNoZVtpXSA9PSBrZXkpIHJldHVybiBjYWNoZVtpICsgMV0gYXMgVGFibGVNYXA7XG4gIH07XG4gIGFkZFRvQ2FjaGUgPSAoa2V5LCB2YWx1ZSkgPT4ge1xuICAgIGlmIChjYWNoZVBvcyA9PSBjYWNoZVNpemUpIGNhY2hlUG9zID0gMDtcbiAgICBjYWNoZVtjYWNoZVBvcysrXSA9IGtleTtcbiAgICByZXR1cm4gKGNhY2hlW2NhY2hlUG9zKytdID0gdmFsdWUpO1xuICB9O1xufVxuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZWN0IHtcbiAgbGVmdDogbnVtYmVyO1xuICB0b3A6IG51bWJlcjtcbiAgcmlnaHQ6IG51bWJlcjtcbiAgYm90dG9tOiBudW1iZXI7XG59XG5cbi8qKlxuICogQSB0YWJsZSBtYXAgZGVzY3JpYmVzIHRoZSBzdHJ1Y3R1cmUgb2YgYSBnaXZlbiB0YWJsZS4gVG8gYXZvaWRcbiAqIHJlY29tcHV0aW5nIHRoZW0gYWxsIHRoZSB0aW1lLCB0aGV5IGFyZSBjYWNoZWQgcGVyIHRhYmxlIG5vZGUuIFRvXG4gKiBiZSBhYmxlIHRvIGRvIHRoYXQsIHBvc2l0aW9ucyBzYXZlZCBpbiB0aGUgbWFwIGFyZSByZWxhdGl2ZSB0byB0aGVcbiAqIHN0YXJ0IG9mIHRoZSB0YWJsZSwgcmF0aGVyIHRoYW4gdGhlIHN0YXJ0IG9mIHRoZSBkb2N1bWVudC5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBUYWJsZU1hcCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgY29sdW1uc1xuICAgICAqL1xuICAgIHB1YmxpYyB3aWR0aDogbnVtYmVyLFxuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2Ygcm93c1xuICAgICAqL1xuICAgIHB1YmxpYyBoZWlnaHQ6IG51bWJlcixcbiAgICAvKipcbiAgICAgKiBBIHdpZHRoICogaGVpZ2h0IGFycmF5IHdpdGggdGhlIHN0YXJ0IHBvc2l0aW9uIG9mXG4gICAgICogdGhlIGNlbGwgY292ZXJpbmcgdGhhdCBwYXJ0IG9mIHRoZSB0YWJsZSBpbiBlYWNoIHNsb3RcbiAgICAgKi9cbiAgICBwdWJsaWMgbWFwOiBudW1iZXJbXSxcbiAgICAvKipcbiAgICAgKiBBbiBvcHRpb25hbCBhcnJheSBvZiBwcm9ibGVtcyAoY2VsbCBvdmVybGFwIG9yIG5vbi1yZWN0YW5ndWxhclxuICAgICAqIHNoYXBlKSBmb3IgdGhlIHRhYmxlLCB1c2VkIGJ5IHRoZSB0YWJsZSBub3JtYWxpemVyLlxuICAgICAqL1xuICAgIHB1YmxpYyBwcm9ibGVtczogUHJvYmxlbVtdIHwgbnVsbCxcbiAgKSB7fVxuXG4gIC8vIEZpbmQgdGhlIGRpbWVuc2lvbnMgb2YgdGhlIGNlbGwgYXQgdGhlIGdpdmVuIHBvc2l0aW9uLlxuICBmaW5kQ2VsbChwb3M6IG51bWJlcik6IFJlY3Qge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5tYXAubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGN1clBvcyA9IHRoaXMubWFwW2ldO1xuICAgICAgaWYgKGN1clBvcyAhPSBwb3MpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCBsZWZ0ID0gaSAlIHRoaXMud2lkdGg7XG4gICAgICBjb25zdCB0b3AgPSAoaSAvIHRoaXMud2lkdGgpIHwgMDtcbiAgICAgIGxldCByaWdodCA9IGxlZnQgKyAxO1xuICAgICAgbGV0IGJvdHRvbSA9IHRvcCArIDE7XG5cbiAgICAgIGZvciAobGV0IGogPSAxOyByaWdodCA8IHRoaXMud2lkdGggJiYgdGhpcy5tYXBbaSArIGpdID09IGN1clBvczsgaisrKSB7XG4gICAgICAgIHJpZ2h0Kys7XG4gICAgICB9XG4gICAgICBmb3IgKFxuICAgICAgICBsZXQgaiA9IDE7XG4gICAgICAgIGJvdHRvbSA8IHRoaXMuaGVpZ2h0ICYmIHRoaXMubWFwW2kgKyB0aGlzLndpZHRoICogal0gPT0gY3VyUG9zO1xuICAgICAgICBqKytcbiAgICAgICkge1xuICAgICAgICBib3R0b20rKztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHsgbGVmdCwgdG9wLCByaWdodCwgYm90dG9tIH07XG4gICAgfVxuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBObyBjZWxsIHdpdGggb2Zmc2V0ICR7cG9zfSBmb3VuZGApO1xuICB9XG5cbiAgLy8gRmluZCB0aGUgbGVmdCBzaWRlIG9mIHRoZSBjZWxsIGF0IHRoZSBnaXZlbiBwb3NpdGlvbi5cbiAgY29sQ291bnQocG9zOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5tYXAubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICh0aGlzLm1hcFtpXSA9PSBwb3MpIHtcbiAgICAgICAgcmV0dXJuIGkgJSB0aGlzLndpZHRoO1xuICAgICAgfVxuICAgIH1cbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgTm8gY2VsbCB3aXRoIG9mZnNldCAke3Bvc30gZm91bmRgKTtcbiAgfVxuXG4gIC8vIEZpbmQgdGhlIG5leHQgY2VsbCBpbiB0aGUgZ2l2ZW4gZGlyZWN0aW9uLCBzdGFydGluZyBmcm9tIHRoZSBjZWxsXG4gIC8vIGF0IGBwb3NgLCBpZiBhbnkuXG4gIG5leHRDZWxsKHBvczogbnVtYmVyLCBheGlzOiAnaG9yaXonIHwgJ3ZlcnQnLCBkaXI6IG51bWJlcik6IG51bGwgfCBudW1iZXIge1xuICAgIGNvbnN0IHsgbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tIH0gPSB0aGlzLmZpbmRDZWxsKHBvcyk7XG4gICAgaWYgKGF4aXMgPT0gJ2hvcml6Jykge1xuICAgICAgaWYgKGRpciA8IDAgPyBsZWZ0ID09IDAgOiByaWdodCA9PSB0aGlzLndpZHRoKSByZXR1cm4gbnVsbDtcbiAgICAgIHJldHVybiB0aGlzLm1hcFt0b3AgKiB0aGlzLndpZHRoICsgKGRpciA8IDAgPyBsZWZ0IC0gMSA6IHJpZ2h0KV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChkaXIgPCAwID8gdG9wID09IDAgOiBib3R0b20gPT0gdGhpcy5oZWlnaHQpIHJldHVybiBudWxsO1xuICAgICAgcmV0dXJuIHRoaXMubWFwW2xlZnQgKyB0aGlzLndpZHRoICogKGRpciA8IDAgPyB0b3AgLSAxIDogYm90dG9tKV07XG4gICAgfVxuICB9XG5cbiAgLy8gR2V0IHRoZSByZWN0YW5nbGUgc3Bhbm5pbmcgdGhlIHR3byBnaXZlbiBjZWxscy5cbiAgcmVjdEJldHdlZW4oYTogbnVtYmVyLCBiOiBudW1iZXIpOiBSZWN0IHtcbiAgICBjb25zdCB7XG4gICAgICBsZWZ0OiBsZWZ0QSxcbiAgICAgIHJpZ2h0OiByaWdodEEsXG4gICAgICB0b3A6IHRvcEEsXG4gICAgICBib3R0b206IGJvdHRvbUEsXG4gICAgfSA9IHRoaXMuZmluZENlbGwoYSk7XG4gICAgY29uc3Qge1xuICAgICAgbGVmdDogbGVmdEIsXG4gICAgICByaWdodDogcmlnaHRCLFxuICAgICAgdG9wOiB0b3BCLFxuICAgICAgYm90dG9tOiBib3R0b21CLFxuICAgIH0gPSB0aGlzLmZpbmRDZWxsKGIpO1xuICAgIHJldHVybiB7XG4gICAgICBsZWZ0OiBNYXRoLm1pbihsZWZ0QSwgbGVmdEIpLFxuICAgICAgdG9wOiBNYXRoLm1pbih0b3BBLCB0b3BCKSxcbiAgICAgIHJpZ2h0OiBNYXRoLm1heChyaWdodEEsIHJpZ2h0QiksXG4gICAgICBib3R0b206IE1hdGgubWF4KGJvdHRvbUEsIGJvdHRvbUIpLFxuICAgIH07XG4gIH1cblxuICAvLyBSZXR1cm4gdGhlIHBvc2l0aW9uIG9mIGFsbCBjZWxscyB0aGF0IGhhdmUgdGhlIHRvcCBsZWZ0IGNvcm5lciBpblxuICAvLyB0aGUgZ2l2ZW4gcmVjdGFuZ2xlLlxuICBjZWxsc0luUmVjdChyZWN0OiBSZWN0KTogbnVtYmVyW10ge1xuICAgIGNvbnN0IHJlc3VsdDogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCBzZWVuOiBSZWNvcmQ8bnVtYmVyLCBib29sZWFuPiA9IHt9O1xuICAgIGZvciAobGV0IHJvdyA9IHJlY3QudG9wOyByb3cgPCByZWN0LmJvdHRvbTsgcm93KyspIHtcbiAgICAgIGZvciAobGV0IGNvbCA9IHJlY3QubGVmdDsgY29sIDwgcmVjdC5yaWdodDsgY29sKyspIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSByb3cgKiB0aGlzLndpZHRoICsgY29sO1xuICAgICAgICBjb25zdCBwb3MgPSB0aGlzLm1hcFtpbmRleF07XG5cbiAgICAgICAgaWYgKHNlZW5bcG9zXSkgY29udGludWU7XG4gICAgICAgIHNlZW5bcG9zXSA9IHRydWU7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIChjb2wgPT0gcmVjdC5sZWZ0ICYmIGNvbCAmJiB0aGlzLm1hcFtpbmRleCAtIDFdID09IHBvcykgfHxcbiAgICAgICAgICAocm93ID09IHJlY3QudG9wICYmIHJvdyAmJiB0aGlzLm1hcFtpbmRleCAtIHRoaXMud2lkdGhdID09IHBvcylcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnB1c2gocG9zKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIFJldHVybiB0aGUgcG9zaXRpb24gYXQgd2hpY2ggdGhlIGNlbGwgYXQgdGhlIGdpdmVuIHJvdyBhbmQgY29sdW1uXG4gIC8vIHN0YXJ0cywgb3Igd291bGQgc3RhcnQsIGlmIGEgY2VsbCBzdGFydGVkIHRoZXJlLlxuICBwb3NpdGlvbkF0KHJvdzogbnVtYmVyLCBjb2w6IG51bWJlciwgdGFibGU6IE5vZGUpOiBudW1iZXIge1xuICAgIGZvciAobGV0IGkgPSAwLCByb3dTdGFydCA9IDA7IDsgaSsrKSB7XG4gICAgICBjb25zdCByb3dFbmQgPSByb3dTdGFydCArIHRhYmxlLmNoaWxkKGkpLm5vZGVTaXplO1xuICAgICAgaWYgKGkgPT0gcm93KSB7XG4gICAgICAgIGxldCBpbmRleCA9IGNvbCArIHJvdyAqIHRoaXMud2lkdGg7XG4gICAgICAgIGNvbnN0IHJvd0VuZEluZGV4ID0gKHJvdyArIDEpICogdGhpcy53aWR0aDtcbiAgICAgICAgLy8gU2tpcCBwYXN0IGNlbGxzIGZyb20gcHJldmlvdXMgcm93cyAodmlhIHJvd3NwYW4pXG4gICAgICAgIHdoaWxlIChpbmRleCA8IHJvd0VuZEluZGV4ICYmIHRoaXMubWFwW2luZGV4XSA8IHJvd1N0YXJ0KSBpbmRleCsrO1xuICAgICAgICByZXR1cm4gaW5kZXggPT0gcm93RW5kSW5kZXggPyByb3dFbmQgLSAxIDogdGhpcy5tYXBbaW5kZXhdO1xuICAgICAgfVxuICAgICAgcm93U3RhcnQgPSByb3dFbmQ7XG4gICAgfVxuICB9XG5cbiAgLy8gRmluZCB0aGUgdGFibGUgbWFwIGZvciB0aGUgZ2l2ZW4gdGFibGUgbm9kZS5cbiAgc3RhdGljIGdldCh0YWJsZTogTm9kZSk6IFRhYmxlTWFwIHtcbiAgICByZXR1cm4gcmVhZEZyb21DYWNoZSh0YWJsZSkgfHwgYWRkVG9DYWNoZSh0YWJsZSwgY29tcHV0ZU1hcCh0YWJsZSkpO1xuICB9XG59XG5cbi8vIENvbXB1dGUgYSB0YWJsZSBtYXAuXG5mdW5jdGlvbiBjb21wdXRlTWFwKHRhYmxlOiBOb2RlKTogVGFibGVNYXAge1xuICBpZiAodGFibGUudHlwZS5zcGVjLnRhYmxlUm9sZSAhPSAndGFibGUnKVxuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdOb3QgYSB0YWJsZSBub2RlOiAnICsgdGFibGUudHlwZS5uYW1lKTtcbiAgY29uc3Qgd2lkdGggPSBmaW5kV2lkdGgodGFibGUpLFxuICAgIGhlaWdodCA9IHRhYmxlLmNoaWxkQ291bnQ7XG4gIGNvbnN0IG1hcCA9IFtdO1xuICBsZXQgbWFwUG9zID0gMDtcbiAgbGV0IHByb2JsZW1zOiBQcm9ibGVtW10gfCBudWxsID0gbnVsbDtcbiAgY29uc3QgY29sV2lkdGhzOiBDb2xXaWR0aHMgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDAsIGUgPSB3aWR0aCAqIGhlaWdodDsgaSA8IGU7IGkrKykgbWFwW2ldID0gMDtcblxuICBmb3IgKGxldCByb3cgPSAwLCBwb3MgPSAwOyByb3cgPCBoZWlnaHQ7IHJvdysrKSB7XG4gICAgY29uc3Qgcm93Tm9kZSA9IHRhYmxlLmNoaWxkKHJvdyk7XG4gICAgcG9zKys7XG4gICAgZm9yIChsZXQgaSA9IDA7IDsgaSsrKSB7XG4gICAgICB3aGlsZSAobWFwUG9zIDwgbWFwLmxlbmd0aCAmJiBtYXBbbWFwUG9zXSAhPSAwKSBtYXBQb3MrKztcbiAgICAgIGlmIChpID09IHJvd05vZGUuY2hpbGRDb3VudCkgYnJlYWs7XG4gICAgICBjb25zdCBjZWxsTm9kZSA9IHJvd05vZGUuY2hpbGQoaSk7XG4gICAgICBjb25zdCB7IGNvbHNwYW4sIHJvd3NwYW4sIGNvbHdpZHRoIH0gPSBjZWxsTm9kZS5hdHRycztcbiAgICAgIGZvciAobGV0IGggPSAwOyBoIDwgcm93c3BhbjsgaCsrKSB7XG4gICAgICAgIGlmIChoICsgcm93ID49IGhlaWdodCkge1xuICAgICAgICAgIChwcm9ibGVtcyB8fCAocHJvYmxlbXMgPSBbXSkpLnB1c2goe1xuICAgICAgICAgICAgdHlwZTogJ292ZXJsb25nX3Jvd3NwYW4nLFxuICAgICAgICAgICAgcG9zLFxuICAgICAgICAgICAgbjogcm93c3BhbiAtIGgsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgc3RhcnQgPSBtYXBQb3MgKyBoICogd2lkdGg7XG4gICAgICAgIGZvciAobGV0IHcgPSAwOyB3IDwgY29sc3BhbjsgdysrKSB7XG4gICAgICAgICAgaWYgKG1hcFtzdGFydCArIHddID09IDApIG1hcFtzdGFydCArIHddID0gcG9zO1xuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIChwcm9ibGVtcyB8fCAocHJvYmxlbXMgPSBbXSkpLnB1c2goe1xuICAgICAgICAgICAgICB0eXBlOiAnY29sbGlzaW9uJyxcbiAgICAgICAgICAgICAgcm93LFxuICAgICAgICAgICAgICBwb3MsXG4gICAgICAgICAgICAgIG46IGNvbHNwYW4gLSB3LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgY29uc3QgY29sVyA9IGNvbHdpZHRoICYmIGNvbHdpZHRoW3ddO1xuICAgICAgICAgIGlmIChjb2xXKSB7XG4gICAgICAgICAgICBjb25zdCB3aWR0aEluZGV4ID0gKChzdGFydCArIHcpICUgd2lkdGgpICogMixcbiAgICAgICAgICAgICAgcHJldiA9IGNvbFdpZHRoc1t3aWR0aEluZGV4XTtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgcHJldiA9PSBudWxsIHx8XG4gICAgICAgICAgICAgIChwcmV2ICE9IGNvbFcgJiYgY29sV2lkdGhzW3dpZHRoSW5kZXggKyAxXSA9PSAxKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGNvbFdpZHRoc1t3aWR0aEluZGV4XSA9IGNvbFc7XG4gICAgICAgICAgICAgIGNvbFdpZHRoc1t3aWR0aEluZGV4ICsgMV0gPSAxO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChwcmV2ID09IGNvbFcpIHtcbiAgICAgICAgICAgICAgY29sV2lkdGhzW3dpZHRoSW5kZXggKyAxXSsrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbWFwUG9zICs9IGNvbHNwYW47XG4gICAgICBwb3MgKz0gY2VsbE5vZGUubm9kZVNpemU7XG4gICAgfVxuICAgIGNvbnN0IGV4cGVjdGVkUG9zID0gKHJvdyArIDEpICogd2lkdGg7XG4gICAgbGV0IG1pc3NpbmcgPSAwO1xuICAgIHdoaWxlIChtYXBQb3MgPCBleHBlY3RlZFBvcykgaWYgKG1hcFttYXBQb3MrK10gPT0gMCkgbWlzc2luZysrO1xuICAgIGlmIChtaXNzaW5nKVxuICAgICAgKHByb2JsZW1zIHx8IChwcm9ibGVtcyA9IFtdKSkucHVzaCh7IHR5cGU6ICdtaXNzaW5nJywgcm93LCBuOiBtaXNzaW5nIH0pO1xuICAgIHBvcysrO1xuICB9XG5cbiAgaWYgKHdpZHRoID09PSAwIHx8IGhlaWdodCA9PT0gMClcbiAgICAocHJvYmxlbXMgfHwgKHByb2JsZW1zID0gW10pKS5wdXNoKHsgdHlwZTogJ3plcm9fc2l6ZWQnIH0pO1xuXG4gIGNvbnN0IHRhYmxlTWFwID0gbmV3IFRhYmxlTWFwKHdpZHRoLCBoZWlnaHQsIG1hcCwgcHJvYmxlbXMpO1xuICBsZXQgYmFkV2lkdGhzID0gZmFsc2U7XG5cbiAgLy8gRm9yIGNvbHVtbnMgdGhhdCBoYXZlIGRlZmluZWQgd2lkdGhzLCBidXQgd2hvc2Ugd2lkdGhzIGRpc2FncmVlXG4gIC8vIGJldHdlZW4gcm93cywgZml4IHVwIHRoZSBjZWxscyB3aG9zZSB3aWR0aCBkb2Vzbid0IG1hdGNoIHRoZVxuICAvLyBjb21wdXRlZCBvbmUuXG4gIGZvciAobGV0IGkgPSAwOyAhYmFkV2lkdGhzICYmIGkgPCBjb2xXaWR0aHMubGVuZ3RoOyBpICs9IDIpXG4gICAgaWYgKGNvbFdpZHRoc1tpXSAhPSBudWxsICYmIGNvbFdpZHRoc1tpICsgMV0gPCBoZWlnaHQpIGJhZFdpZHRocyA9IHRydWU7XG4gIGlmIChiYWRXaWR0aHMpIGZpbmRCYWRDb2xXaWR0aHModGFibGVNYXAsIGNvbFdpZHRocywgdGFibGUpO1xuXG4gIHJldHVybiB0YWJsZU1hcDtcbn1cblxuZnVuY3Rpb24gZmluZFdpZHRoKHRhYmxlOiBOb2RlKTogbnVtYmVyIHtcbiAgbGV0IHdpZHRoID0gLTE7XG4gIGxldCBoYXNSb3dTcGFuID0gZmFsc2U7XG4gIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IHRhYmxlLmNoaWxkQ291bnQ7IHJvdysrKSB7XG4gICAgY29uc3Qgcm93Tm9kZSA9IHRhYmxlLmNoaWxkKHJvdyk7XG4gICAgbGV0IHJvd1dpZHRoID0gMDtcbiAgICBpZiAoaGFzUm93U3BhbilcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgcm93OyBqKyspIHtcbiAgICAgICAgY29uc3QgcHJldlJvdyA9IHRhYmxlLmNoaWxkKGopO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXZSb3cuY2hpbGRDb3VudDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgY2VsbCA9IHByZXZSb3cuY2hpbGQoaSk7XG4gICAgICAgICAgaWYgKGogKyBjZWxsLmF0dHJzLnJvd3NwYW4gPiByb3cpIHJvd1dpZHRoICs9IGNlbGwuYXR0cnMuY29sc3BhbjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93Tm9kZS5jaGlsZENvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IGNlbGwgPSByb3dOb2RlLmNoaWxkKGkpO1xuICAgICAgcm93V2lkdGggKz0gY2VsbC5hdHRycy5jb2xzcGFuO1xuICAgICAgaWYgKGNlbGwuYXR0cnMucm93c3BhbiA+IDEpIGhhc1Jvd1NwYW4gPSB0cnVlO1xuICAgIH1cbiAgICBpZiAod2lkdGggPT0gLTEpIHdpZHRoID0gcm93V2lkdGg7XG4gICAgZWxzZSBpZiAod2lkdGggIT0gcm93V2lkdGgpIHdpZHRoID0gTWF0aC5tYXgod2lkdGgsIHJvd1dpZHRoKTtcbiAgfVxuICByZXR1cm4gd2lkdGg7XG59XG5cbmZ1bmN0aW9uIGZpbmRCYWRDb2xXaWR0aHMoXG4gIG1hcDogVGFibGVNYXAsXG4gIGNvbFdpZHRoczogQ29sV2lkdGhzLFxuICB0YWJsZTogTm9kZSxcbik6IHZvaWQge1xuICBpZiAoIW1hcC5wcm9ibGVtcykgbWFwLnByb2JsZW1zID0gW107XG4gIGNvbnN0IHNlZW46IFJlY29yZDxudW1iZXIsIGJvb2xlYW4+ID0ge307XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbWFwLm1hcC5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHBvcyA9IG1hcC5tYXBbaV07XG4gICAgaWYgKHNlZW5bcG9zXSkgY29udGludWU7XG4gICAgc2Vlbltwb3NdID0gdHJ1ZTtcbiAgICBjb25zdCBub2RlID0gdGFibGUubm9kZUF0KHBvcyk7XG4gICAgaWYgKCFub2RlKSB7XG4gICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgTm8gY2VsbCB3aXRoIG9mZnNldCAke3Bvc30gZm91bmRgKTtcbiAgICB9XG5cbiAgICBsZXQgdXBkYXRlZCA9IG51bGw7XG4gICAgY29uc3QgYXR0cnMgPSBub2RlLmF0dHJzIGFzIENlbGxBdHRycztcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IGF0dHJzLmNvbHNwYW47IGorKykge1xuICAgICAgY29uc3QgY29sID0gKGkgKyBqKSAlIG1hcC53aWR0aDtcbiAgICAgIGNvbnN0IGNvbFdpZHRoID0gY29sV2lkdGhzW2NvbCAqIDJdO1xuICAgICAgaWYgKFxuICAgICAgICBjb2xXaWR0aCAhPSBudWxsICYmXG4gICAgICAgICghYXR0cnMuY29sd2lkdGggfHwgYXR0cnMuY29sd2lkdGhbal0gIT0gY29sV2lkdGgpXG4gICAgICApXG4gICAgICAgICh1cGRhdGVkIHx8ICh1cGRhdGVkID0gZnJlc2hDb2xXaWR0aChhdHRycykpKVtqXSA9IGNvbFdpZHRoO1xuICAgIH1cbiAgICBpZiAodXBkYXRlZClcbiAgICAgIG1hcC5wcm9ibGVtcy51bnNoaWZ0KHtcbiAgICAgICAgdHlwZTogJ2NvbHdpZHRoIG1pc21hdGNoJyxcbiAgICAgICAgcG9zLFxuICAgICAgICBjb2x3aWR0aDogdXBkYXRlZCxcbiAgICAgIH0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZyZXNoQ29sV2lkdGgoYXR0cnM6IEF0dHJzKTogQ29sV2lkdGhzIHtcbiAgaWYgKGF0dHJzLmNvbHdpZHRoKSByZXR1cm4gYXR0cnMuY29sd2lkdGguc2xpY2UoKTtcbiAgY29uc3QgcmVzdWx0OiBDb2xXaWR0aHMgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRycy5jb2xzcGFuOyBpKyspIHJlc3VsdC5wdXNoKDApO1xuICByZXR1cm4gcmVzdWx0O1xufVxuIiwgIi8vIEhlbHBlciBmb3IgY3JlYXRpbmcgYSBzY2hlbWEgdGhhdCBzdXBwb3J0cyB0YWJsZXMuXG5cbmltcG9ydCB0eXBlIHtcbiAgQXR0cmlidXRlU3BlYyxcbiAgQXR0cnMsXG4gIE5vZGUsXG4gIE5vZGVTcGVjLFxuICBOb2RlVHlwZSxcbiAgU2NoZW1hLFxufSBmcm9tICdwcm9zZW1pcnJvci1tb2RlbCc7XG5cbmltcG9ydCB0eXBlIHsgQ2VsbEF0dHJzLCBNdXRhYmxlQXR0cnMgfSBmcm9tICcuL3V0aWwnO1xuXG5mdW5jdGlvbiBnZXRDZWxsQXR0cnMoZG9tOiBIVE1MRWxlbWVudCB8IHN0cmluZywgZXh0cmFBdHRyczogQXR0cnMpOiBBdHRycyB7XG4gIGlmICh0eXBlb2YgZG9tID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGNvbnN0IHdpZHRoQXR0ciA9IGRvbS5nZXRBdHRyaWJ1dGUoJ2RhdGEtY29sd2lkdGgnKTtcbiAgY29uc3Qgd2lkdGhzID1cbiAgICB3aWR0aEF0dHIgJiYgL15cXGQrKCxcXGQrKSokLy50ZXN0KHdpZHRoQXR0cilcbiAgICAgID8gd2lkdGhBdHRyLnNwbGl0KCcsJykubWFwKChzKSA9PiBOdW1iZXIocykpXG4gICAgICA6IG51bGw7XG4gIGNvbnN0IGNvbHNwYW4gPSBOdW1iZXIoZG9tLmdldEF0dHJpYnV0ZSgnY29sc3BhbicpIHx8IDEpO1xuICBjb25zdCByZXN1bHQ6IE11dGFibGVBdHRycyA9IHtcbiAgICBjb2xzcGFuLFxuICAgIHJvd3NwYW46IE51bWJlcihkb20uZ2V0QXR0cmlidXRlKCdyb3dzcGFuJykgfHwgMSksXG4gICAgY29sd2lkdGg6IHdpZHRocyAmJiB3aWR0aHMubGVuZ3RoID09IGNvbHNwYW4gPyB3aWR0aHMgOiBudWxsLFxuICB9IHNhdGlzZmllcyBDZWxsQXR0cnM7XG4gIGZvciAoY29uc3QgcHJvcCBpbiBleHRyYUF0dHJzKSB7XG4gICAgY29uc3QgZ2V0dGVyID0gZXh0cmFBdHRyc1twcm9wXS5nZXRGcm9tRE9NO1xuICAgIGNvbnN0IHZhbHVlID0gZ2V0dGVyICYmIGdldHRlcihkb20pO1xuICAgIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgICByZXN1bHRbcHJvcF0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gc2V0Q2VsbEF0dHJzKG5vZGU6IE5vZGUsIGV4dHJhQXR0cnM6IEF0dHJzKTogQXR0cnMge1xuICBjb25zdCBhdHRyczogTXV0YWJsZUF0dHJzID0ge307XG4gIGlmIChub2RlLmF0dHJzLmNvbHNwYW4gIT0gMSkgYXR0cnMuY29sc3BhbiA9IG5vZGUuYXR0cnMuY29sc3BhbjtcbiAgaWYgKG5vZGUuYXR0cnMucm93c3BhbiAhPSAxKSBhdHRycy5yb3dzcGFuID0gbm9kZS5hdHRycy5yb3dzcGFuO1xuICBpZiAobm9kZS5hdHRycy5jb2x3aWR0aClcbiAgICBhdHRyc1snZGF0YS1jb2x3aWR0aCddID0gbm9kZS5hdHRycy5jb2x3aWR0aC5qb2luKCcsJyk7XG4gIGZvciAoY29uc3QgcHJvcCBpbiBleHRyYUF0dHJzKSB7XG4gICAgY29uc3Qgc2V0dGVyID0gZXh0cmFBdHRyc1twcm9wXS5zZXRET01BdHRyO1xuICAgIGlmIChzZXR0ZXIpIHNldHRlcihub2RlLmF0dHJzW3Byb3BdLCBhdHRycyk7XG4gIH1cbiAgcmV0dXJuIGF0dHJzO1xufVxuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgZ2V0RnJvbURPTSA9IChkb206IEhUTUxFbGVtZW50KSA9PiB1bmtub3duO1xuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgc2V0RE9NQXR0ciA9ICh2YWx1ZTogdW5rbm93biwgYXR0cnM6IE11dGFibGVBdHRycykgPT4gdm9pZDtcblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2VsbEF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogVGhlIGF0dHJpYnV0ZSdzIGRlZmF1bHQgdmFsdWUuXG4gICAqL1xuICBkZWZhdWx0OiB1bmtub3duO1xuXG4gIC8qKlxuICAgKiBBIGZ1bmN0aW9uIG9yIHR5cGUgbmFtZSB1c2VkIHRvIHZhbGlkYXRlIHZhbHVlcyBvZiB0aGlzIGF0dHJpYnV0ZS5cbiAgICpcbiAgICogU2VlIFt2YWxpZGF0ZV0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLkF0dHJpYnV0ZVNwZWMudmFsaWRhdGUpLlxuICAgKi9cbiAgdmFsaWRhdGU/OiBzdHJpbmcgfCAoKHZhbHVlOiB1bmtub3duKSA9PiB2b2lkKTtcblxuICAvKipcbiAgICogQSBmdW5jdGlvbiB0byByZWFkIHRoZSBhdHRyaWJ1dGUncyB2YWx1ZSBmcm9tIGEgRE9NIG5vZGUuXG4gICAqL1xuICBnZXRGcm9tRE9NPzogZ2V0RnJvbURPTTtcblxuICAvKipcbiAgICogQSBmdW5jdGlvbiB0byBhZGQgdGhlIGF0dHJpYnV0ZSdzIHZhbHVlIHRvIGFuIGF0dHJpYnV0ZVxuICAgKiBvYmplY3QgdGhhdCdzIHVzZWQgdG8gcmVuZGVyIHRoZSBjZWxsJ3MgRE9NLlxuICAgKi9cbiAgc2V0RE9NQXR0cj86IHNldERPTUF0dHI7XG59XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlTm9kZXNPcHRpb25zIHtcbiAgLyoqXG4gICAqIEEgZ3JvdXAgbmFtZSAoc29tZXRoaW5nIGxpa2UgYFwiYmxvY2tcImApIHRvIGFkZCB0byB0aGUgdGFibGVcbiAgICogbm9kZSB0eXBlLlxuICAgKi9cbiAgdGFibGVHcm91cD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGNvbnRlbnQgZXhwcmVzc2lvbiBmb3IgdGFibGUgY2VsbHMuXG4gICAqL1xuICBjZWxsQ29udGVudDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIGF0dHJpYnV0ZXMgdG8gYWRkIHRvIGNlbGxzLiBNYXBzIGF0dHJpYnV0ZSBuYW1lcyB0b1xuICAgKiBvYmplY3RzIHdpdGggdGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzOlxuICAgKi9cbiAgY2VsbEF0dHJpYnV0ZXM6IHsgW2tleTogc3RyaW5nXTogQ2VsbEF0dHJpYnV0ZXMgfTtcbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCB0eXBlIFRhYmxlTm9kZXMgPSBSZWNvcmQ8XG4gICd0YWJsZScgfCAndGFibGVfcm93JyB8ICd0YWJsZV9jZWxsJyB8ICd0YWJsZV9oZWFkZXInLFxuICBOb2RlU3BlY1xuPjtcblxuZnVuY3Rpb24gdmFsaWRhdGVDb2x3aWR0aCh2YWx1ZTogdW5rbm93bikge1xuICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NvbHdpZHRoIG11c3QgYmUgbnVsbCBvciBhbiBhcnJheScpO1xuICB9XG4gIGZvciAoY29uc3QgaXRlbSBvZiB2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgaXRlbSAhPT0gJ251bWJlcicpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ2NvbHdpZHRoIG11c3QgYmUgbnVsbCBvciBhbiBhcnJheSBvZiBudW1iZXJzJyk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBjcmVhdGVzIGEgc2V0IG9mIFtub2RlXG4gKiBzcGVjc10oaHR0cDovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuU2NoZW1hU3BlYy5ub2RlcykgZm9yXG4gKiBgdGFibGVgLCBgdGFibGVfcm93YCwgYW5kIGB0YWJsZV9jZWxsYCBub2RlcyB0eXBlcyBhcyB1c2VkIGJ5IHRoaXNcbiAqIG1vZHVsZS4gVGhlIHJlc3VsdCBjYW4gdGhlbiBiZSBhZGRlZCB0byB0aGUgc2V0IG9mIG5vZGVzIHdoZW5cbiAqIGNyZWF0aW5nIGEgc2NoZW1hLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRhYmxlTm9kZXMob3B0aW9uczogVGFibGVOb2Rlc09wdGlvbnMpOiBUYWJsZU5vZGVzIHtcbiAgY29uc3QgZXh0cmFBdHRycyA9IG9wdGlvbnMuY2VsbEF0dHJpYnV0ZXMgfHwge307XG4gIGNvbnN0IGNlbGxBdHRyczogUmVjb3JkPHN0cmluZywgQXR0cmlidXRlU3BlYz4gPSB7XG4gICAgY29sc3BhbjogeyBkZWZhdWx0OiAxLCB2YWxpZGF0ZTogJ251bWJlcicgfSxcbiAgICByb3dzcGFuOiB7IGRlZmF1bHQ6IDEsIHZhbGlkYXRlOiAnbnVtYmVyJyB9LFxuICAgIGNvbHdpZHRoOiB7IGRlZmF1bHQ6IG51bGwsIHZhbGlkYXRlOiB2YWxpZGF0ZUNvbHdpZHRoIH0sXG4gIH07XG4gIGZvciAoY29uc3QgcHJvcCBpbiBleHRyYUF0dHJzKVxuICAgIGNlbGxBdHRyc1twcm9wXSA9IHtcbiAgICAgIGRlZmF1bHQ6IGV4dHJhQXR0cnNbcHJvcF0uZGVmYXVsdCxcbiAgICAgIHZhbGlkYXRlOiBleHRyYUF0dHJzW3Byb3BdLnZhbGlkYXRlLFxuICAgIH07XG5cbiAgcmV0dXJuIHtcbiAgICB0YWJsZToge1xuICAgICAgY29udGVudDogJ3RhYmxlX3JvdysnLFxuICAgICAgdGFibGVSb2xlOiAndGFibGUnLFxuICAgICAgaXNvbGF0aW5nOiB0cnVlLFxuICAgICAgZ3JvdXA6IG9wdGlvbnMudGFibGVHcm91cCxcbiAgICAgIHBhcnNlRE9NOiBbeyB0YWc6ICd0YWJsZScgfV0sXG4gICAgICB0b0RPTSgpIHtcbiAgICAgICAgcmV0dXJuIFsndGFibGUnLCBbJ3Rib2R5JywgMF1dO1xuICAgICAgfSxcbiAgICB9LFxuICAgIHRhYmxlX3Jvdzoge1xuICAgICAgY29udGVudDogJyh0YWJsZV9jZWxsIHwgdGFibGVfaGVhZGVyKSonLFxuICAgICAgdGFibGVSb2xlOiAncm93JyxcbiAgICAgIHBhcnNlRE9NOiBbeyB0YWc6ICd0cicgfV0sXG4gICAgICB0b0RPTSgpIHtcbiAgICAgICAgcmV0dXJuIFsndHInLCAwXTtcbiAgICAgIH0sXG4gICAgfSxcbiAgICB0YWJsZV9jZWxsOiB7XG4gICAgICBjb250ZW50OiBvcHRpb25zLmNlbGxDb250ZW50LFxuICAgICAgYXR0cnM6IGNlbGxBdHRycyxcbiAgICAgIHRhYmxlUm9sZTogJ2NlbGwnLFxuICAgICAgaXNvbGF0aW5nOiB0cnVlLFxuICAgICAgcGFyc2VET006IFtcbiAgICAgICAgeyB0YWc6ICd0ZCcsIGdldEF0dHJzOiAoZG9tKSA9PiBnZXRDZWxsQXR0cnMoZG9tLCBleHRyYUF0dHJzKSB9LFxuICAgICAgXSxcbiAgICAgIHRvRE9NKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIFsndGQnLCBzZXRDZWxsQXR0cnMobm9kZSwgZXh0cmFBdHRycyksIDBdO1xuICAgICAgfSxcbiAgICB9LFxuICAgIHRhYmxlX2hlYWRlcjoge1xuICAgICAgY29udGVudDogb3B0aW9ucy5jZWxsQ29udGVudCxcbiAgICAgIGF0dHJzOiBjZWxsQXR0cnMsXG4gICAgICB0YWJsZVJvbGU6ICdoZWFkZXJfY2VsbCcsXG4gICAgICBpc29sYXRpbmc6IHRydWUsXG4gICAgICBwYXJzZURPTTogW1xuICAgICAgICB7IHRhZzogJ3RoJywgZ2V0QXR0cnM6IChkb20pID0+IGdldENlbGxBdHRycyhkb20sIGV4dHJhQXR0cnMpIH0sXG4gICAgICBdLFxuICAgICAgdG9ET00obm9kZSkge1xuICAgICAgICByZXR1cm4gWyd0aCcsIHNldENlbGxBdHRycyhub2RlLCBleHRyYUF0dHJzKSwgMF07XG4gICAgICB9LFxuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBUYWJsZVJvbGUgPSAndGFibGUnIHwgJ3JvdycgfCAnY2VsbCcgfCAnaGVhZGVyX2NlbGwnO1xuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRhYmxlTm9kZVR5cGVzKHNjaGVtYTogU2NoZW1hKTogUmVjb3JkPFRhYmxlUm9sZSwgTm9kZVR5cGU+IHtcbiAgbGV0IHJlc3VsdCA9IHNjaGVtYS5jYWNoZWQudGFibGVOb2RlVHlwZXM7XG4gIGlmICghcmVzdWx0KSB7XG4gICAgcmVzdWx0ID0gc2NoZW1hLmNhY2hlZC50YWJsZU5vZGVUeXBlcyA9IHt9O1xuICAgIGZvciAoY29uc3QgbmFtZSBpbiBzY2hlbWEubm9kZXMpIHtcbiAgICAgIGNvbnN0IHR5cGUgPSBzY2hlbWEubm9kZXNbbmFtZV0sXG4gICAgICAgIHJvbGUgPSB0eXBlLnNwZWMudGFibGVSb2xlO1xuICAgICAgaWYgKHJvbGUpIHJlc3VsdFtyb2xlXSA9IHR5cGU7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG4iLCAiLy8gVmFyaW91cyBoZWxwZXIgZnVuY3Rpb24gZm9yIHdvcmtpbmcgd2l0aCB0YWJsZXNcblxuaW1wb3J0IHR5cGUgeyBBdHRycywgTm9kZSwgUmVzb2x2ZWRQb3MgfSBmcm9tICdwcm9zZW1pcnJvci1tb2RlbCc7XG5pbXBvcnQgdHlwZSB7IEVkaXRvclN0YXRlLCBOb2RlU2VsZWN0aW9uIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuaW1wb3J0IHsgUGx1Z2luS2V5IH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuXG5pbXBvcnQgdHlwZSB7IENlbGxTZWxlY3Rpb24gfSBmcm9tICcuL2NlbGxzZWxlY3Rpb24nO1xuaW1wb3J0IHsgdGFibGVOb2RlVHlwZXMgfSBmcm9tICcuL3NjaGVtYSc7XG5pbXBvcnQgdHlwZSB7IFJlY3QgfSBmcm9tICcuL3RhYmxlbWFwJztcbmltcG9ydCB7IFRhYmxlTWFwIH0gZnJvbSAnLi90YWJsZW1hcCc7XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBNdXRhYmxlQXR0cnMgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2VsbEF0dHJzIHtcbiAgY29sc3BhbjogbnVtYmVyO1xuICByb3dzcGFuOiBudW1iZXI7XG4gIGNvbHdpZHRoOiBudW1iZXJbXSB8IG51bGw7XG59XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgdGFibGVFZGl0aW5nS2V5ID0gbmV3IFBsdWdpbktleTxudW1iZXI+KCdzZWxlY3RpbmdDZWxscycpO1xuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNlbGxBcm91bmQoJHBvczogUmVzb2x2ZWRQb3MpOiBSZXNvbHZlZFBvcyB8IG51bGwge1xuICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aCAtIDE7IGQgPiAwOyBkLS0pXG4gICAgaWYgKCRwb3Mubm9kZShkKS50eXBlLnNwZWMudGFibGVSb2xlID09ICdyb3cnKVxuICAgICAgcmV0dXJuICRwb3Mubm9kZSgwKS5yZXNvbHZlKCRwb3MuYmVmb3JlKGQgKyAxKSk7XG4gIHJldHVybiBudWxsO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2VsbFdyYXBwaW5nKCRwb3M6IFJlc29sdmVkUG9zKTogbnVsbCB8IE5vZGUge1xuICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aDsgZCA+IDA7IGQtLSkge1xuICAgIC8vIFNvbWV0aW1lcyB0aGUgY2VsbCBjYW4gYmUgaW4gdGhlIHNhbWUgZGVwdGguXG4gICAgY29uc3Qgcm9sZSA9ICRwb3Mubm9kZShkKS50eXBlLnNwZWMudGFibGVSb2xlO1xuICAgIGlmIChyb2xlID09PSAnY2VsbCcgfHwgcm9sZSA9PT0gJ2hlYWRlcl9jZWxsJykgcmV0dXJuICRwb3Mubm9kZShkKTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0luVGFibGUoc3RhdGU6IEVkaXRvclN0YXRlKTogYm9vbGVhbiB7XG4gIGNvbnN0ICRoZWFkID0gc3RhdGUuc2VsZWN0aW9uLiRoZWFkO1xuICBmb3IgKGxldCBkID0gJGhlYWQuZGVwdGg7IGQgPiAwOyBkLS0pXG4gICAgaWYgKCRoZWFkLm5vZGUoZCkudHlwZS5zcGVjLnRhYmxlUm9sZSA9PSAncm93JykgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdGlvbkNlbGwoc3RhdGU6IEVkaXRvclN0YXRlKTogUmVzb2x2ZWRQb3Mge1xuICBjb25zdCBzZWwgPSBzdGF0ZS5zZWxlY3Rpb24gYXMgQ2VsbFNlbGVjdGlvbiB8IE5vZGVTZWxlY3Rpb247XG4gIGlmICgnJGFuY2hvckNlbGwnIGluIHNlbCAmJiBzZWwuJGFuY2hvckNlbGwpIHtcbiAgICByZXR1cm4gc2VsLiRhbmNob3JDZWxsLnBvcyA+IHNlbC4kaGVhZENlbGwucG9zXG4gICAgICA/IHNlbC4kYW5jaG9yQ2VsbFxuICAgICAgOiBzZWwuJGhlYWRDZWxsO1xuICB9IGVsc2UgaWYgKFxuICAgICdub2RlJyBpbiBzZWwgJiZcbiAgICBzZWwubm9kZSAmJlxuICAgIHNlbC5ub2RlLnR5cGUuc3BlYy50YWJsZVJvbGUgPT0gJ2NlbGwnXG4gICkge1xuICAgIHJldHVybiBzZWwuJGFuY2hvcjtcbiAgfVxuICBjb25zdCAkY2VsbCA9IGNlbGxBcm91bmQoc2VsLiRoZWFkKSB8fCBjZWxsTmVhcihzZWwuJGhlYWQpO1xuICBpZiAoJGNlbGwpIHtcbiAgICByZXR1cm4gJGNlbGw7XG4gIH1cbiAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYE5vIGNlbGwgZm91bmQgYXJvdW5kIHBvc2l0aW9uICR7c2VsLmhlYWR9YCk7XG59XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gY2VsbE5lYXIoJHBvczogUmVzb2x2ZWRQb3MpOiBSZXNvbHZlZFBvcyB8IHVuZGVmaW5lZCB7XG4gIGZvciAoXG4gICAgbGV0IGFmdGVyID0gJHBvcy5ub2RlQWZ0ZXIsIHBvcyA9ICRwb3MucG9zO1xuICAgIGFmdGVyO1xuICAgIGFmdGVyID0gYWZ0ZXIuZmlyc3RDaGlsZCwgcG9zKytcbiAgKSB7XG4gICAgY29uc3Qgcm9sZSA9IGFmdGVyLnR5cGUuc3BlYy50YWJsZVJvbGU7XG4gICAgaWYgKHJvbGUgPT0gJ2NlbGwnIHx8IHJvbGUgPT0gJ2hlYWRlcl9jZWxsJykgcmV0dXJuICRwb3MuZG9jLnJlc29sdmUocG9zKTtcbiAgfVxuICBmb3IgKFxuICAgIGxldCBiZWZvcmUgPSAkcG9zLm5vZGVCZWZvcmUsIHBvcyA9ICRwb3MucG9zO1xuICAgIGJlZm9yZTtcbiAgICBiZWZvcmUgPSBiZWZvcmUubGFzdENoaWxkLCBwb3MtLVxuICApIHtcbiAgICBjb25zdCByb2xlID0gYmVmb3JlLnR5cGUuc3BlYy50YWJsZVJvbGU7XG4gICAgaWYgKHJvbGUgPT0gJ2NlbGwnIHx8IHJvbGUgPT0gJ2hlYWRlcl9jZWxsJylcbiAgICAgIHJldHVybiAkcG9zLmRvYy5yZXNvbHZlKHBvcyAtIGJlZm9yZS5ub2RlU2l6ZSk7XG4gIH1cbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb2ludHNBdENlbGwoJHBvczogUmVzb2x2ZWRQb3MpOiBib29sZWFuIHtcbiAgcmV0dXJuICRwb3MucGFyZW50LnR5cGUuc3BlYy50YWJsZVJvbGUgPT0gJ3JvdycgJiYgISEkcG9zLm5vZGVBZnRlcjtcbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb3ZlQ2VsbEZvcndhcmQoJHBvczogUmVzb2x2ZWRQb3MpOiBSZXNvbHZlZFBvcyB7XG4gIHJldHVybiAkcG9zLm5vZGUoMCkucmVzb2x2ZSgkcG9zLnBvcyArICRwb3Mubm9kZUFmdGVyIS5ub2RlU2l6ZSk7XG59XG5cbi8qKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpblNhbWVUYWJsZSgkY2VsbEE6IFJlc29sdmVkUG9zLCAkY2VsbEI6IFJlc29sdmVkUG9zKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgJGNlbGxBLmRlcHRoID09ICRjZWxsQi5kZXB0aCAmJlxuICAgICRjZWxsQS5wb3MgPj0gJGNlbGxCLnN0YXJ0KC0xKSAmJlxuICAgICRjZWxsQS5wb3MgPD0gJGNlbGxCLmVuZCgtMSlcbiAgKTtcbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kQ2VsbCgkcG9zOiBSZXNvbHZlZFBvcyk6IFJlY3Qge1xuICByZXR1cm4gVGFibGVNYXAuZ2V0KCRwb3Mubm9kZSgtMSkpLmZpbmRDZWxsKCRwb3MucG9zIC0gJHBvcy5zdGFydCgtMSkpO1xufVxuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbENvdW50KCRwb3M6IFJlc29sdmVkUG9zKTogbnVtYmVyIHtcbiAgcmV0dXJuIFRhYmxlTWFwLmdldCgkcG9zLm5vZGUoLTEpKS5jb2xDb3VudCgkcG9zLnBvcyAtICRwb3Muc3RhcnQoLTEpKTtcbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBuZXh0Q2VsbChcbiAgJHBvczogUmVzb2x2ZWRQb3MsXG4gIGF4aXM6ICdob3JpeicgfCAndmVydCcsXG4gIGRpcjogbnVtYmVyLFxuKTogUmVzb2x2ZWRQb3MgfCBudWxsIHtcbiAgY29uc3QgdGFibGUgPSAkcG9zLm5vZGUoLTEpO1xuICBjb25zdCBtYXAgPSBUYWJsZU1hcC5nZXQodGFibGUpO1xuICBjb25zdCB0YWJsZVN0YXJ0ID0gJHBvcy5zdGFydCgtMSk7XG5cbiAgY29uc3QgbW92ZWQgPSBtYXAubmV4dENlbGwoJHBvcy5wb3MgLSB0YWJsZVN0YXJ0LCBheGlzLCBkaXIpO1xuICByZXR1cm4gbW92ZWQgPT0gbnVsbCA/IG51bGwgOiAkcG9zLm5vZGUoMCkucmVzb2x2ZSh0YWJsZVN0YXJ0ICsgbW92ZWQpO1xufVxuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUNvbFNwYW4oYXR0cnM6IENlbGxBdHRycywgcG9zOiBudW1iZXIsIG4gPSAxKTogQ2VsbEF0dHJzIHtcbiAgY29uc3QgcmVzdWx0OiBDZWxsQXR0cnMgPSB7IC4uLmF0dHJzLCBjb2xzcGFuOiBhdHRycy5jb2xzcGFuIC0gbiB9O1xuXG4gIGlmIChyZXN1bHQuY29sd2lkdGgpIHtcbiAgICByZXN1bHQuY29sd2lkdGggPSByZXN1bHQuY29sd2lkdGguc2xpY2UoKTtcbiAgICByZXN1bHQuY29sd2lkdGguc3BsaWNlKHBvcywgbik7XG4gICAgaWYgKCFyZXN1bHQuY29sd2lkdGguc29tZSgodykgPT4gdyA+IDApKSByZXN1bHQuY29sd2lkdGggPSBudWxsO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkQ29sU3BhbihhdHRyczogQ2VsbEF0dHJzLCBwb3M6IG51bWJlciwgbiA9IDEpOiBBdHRycyB7XG4gIGNvbnN0IHJlc3VsdCA9IHsgLi4uYXR0cnMsIGNvbHNwYW46IGF0dHJzLmNvbHNwYW4gKyBuIH07XG4gIGlmIChyZXN1bHQuY29sd2lkdGgpIHtcbiAgICByZXN1bHQuY29sd2lkdGggPSByZXN1bHQuY29sd2lkdGguc2xpY2UoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykgcmVzdWx0LmNvbHdpZHRoLnNwbGljZShwb3MsIDAsIDApO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gY29sdW1uSXNIZWFkZXIoXG4gIG1hcDogVGFibGVNYXAsXG4gIHRhYmxlOiBOb2RlLFxuICBjb2w6IG51bWJlcixcbik6IGJvb2xlYW4ge1xuICBjb25zdCBoZWFkZXJDZWxsID0gdGFibGVOb2RlVHlwZXModGFibGUudHlwZS5zY2hlbWEpLmhlYWRlcl9jZWxsO1xuICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCBtYXAuaGVpZ2h0OyByb3crKylcbiAgICBpZiAodGFibGUubm9kZUF0KG1hcC5tYXBbY29sICsgcm93ICogbWFwLndpZHRoXSkhLnR5cGUgIT0gaGVhZGVyQ2VsbClcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRydWU7XG59XG4iLCAiLy8gVGhpcyBmaWxlIGRlZmluZXMgYSBQcm9zZU1pcnJvciBzZWxlY3Rpb24gc3ViY2xhc3MgdGhhdCBtb2RlbHNcbi8vIHRhYmxlIGNlbGwgc2VsZWN0aW9ucy4gVGhlIHRhYmxlIHBsdWdpbiBuZWVkcyB0byBiZSBhY3RpdmUgdG8gd2lyZVxuLy8gaW4gdGhlIHVzZXIgaW50ZXJhY3Rpb24gcGFydCBvZiB0YWJsZSBzZWxlY3Rpb25zIChzbyB0aGF0IHlvdVxuLy8gYWN0dWFsbHkgZ2V0IHN1Y2ggc2VsZWN0aW9ucyB3aGVuIHlvdSBzZWxlY3QgYWNyb3NzIGNlbGxzKS5cblxuaW1wb3J0IHR5cGUgeyBOb2RlLCBSZXNvbHZlZFBvcyB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB7IEZyYWdtZW50LCBTbGljZSB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUsIFRyYW5zYWN0aW9uIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuaW1wb3J0IHtcbiAgTm9kZVNlbGVjdGlvbixcbiAgU2VsZWN0aW9uLFxuICBTZWxlY3Rpb25SYW5nZSxcbiAgVGV4dFNlbGVjdGlvbixcbn0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuaW1wb3J0IHR5cGUgeyBNYXBwYWJsZSB9IGZyb20gJ3Byb3NlbWlycm9yLXRyYW5zZm9ybSc7XG5pbXBvcnQgdHlwZSB7IERlY29yYXRpb25Tb3VyY2UgfSBmcm9tICdwcm9zZW1pcnJvci12aWV3JztcbmltcG9ydCB7IERlY29yYXRpb24sIERlY29yYXRpb25TZXQgfSBmcm9tICdwcm9zZW1pcnJvci12aWV3JztcblxuaW1wb3J0IHsgVGFibGVNYXAgfSBmcm9tICcuL3RhYmxlbWFwJztcbmltcG9ydCB0eXBlIHsgQ2VsbEF0dHJzIH0gZnJvbSAnLi91dGlsJztcbmltcG9ydCB7IGluU2FtZVRhYmxlLCBwb2ludHNBdENlbGwsIHJlbW92ZUNvbFNwYW4gfSBmcm9tICcuL3V0aWwnO1xuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZWxsU2VsZWN0aW9uSlNPTiB7XG4gIHR5cGU6IHN0cmluZztcbiAgYW5jaG9yOiBudW1iZXI7XG4gIGhlYWQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBBIFtgU2VsZWN0aW9uYF0oaHR0cDovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuU2VsZWN0aW9uKVxuICogc3ViY2xhc3MgdGhhdCByZXByZXNlbnRzIGEgY2VsbCBzZWxlY3Rpb24gc3Bhbm5pbmcgcGFydCBvZiBhIHRhYmxlLlxuICogV2l0aCB0aGUgcGx1Z2luIGVuYWJsZWQsIHRoZXNlIHdpbGwgYmUgY3JlYXRlZCB3aGVuIHRoZSB1c2VyXG4gKiBzZWxlY3RzIGFjcm9zcyBjZWxscywgYW5kIHdpbGwgYmUgZHJhd24gYnkgZ2l2aW5nIHNlbGVjdGVkIGNlbGxzIGFcbiAqIGBzZWxlY3RlZENlbGxgIENTUyBjbGFzcy5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBDZWxsU2VsZWN0aW9uIGV4dGVuZHMgU2VsZWN0aW9uIHtcbiAgLy8gQSByZXNvbHZlZCBwb3NpdGlvbiBwb2ludGluZyBfaW4gZnJvbnQgb2ZfIHRoZSBhbmNob3IgY2VsbCAodGhlIG9uZVxuICAvLyB0aGF0IGRvZXNuJ3QgbW92ZSB3aGVuIGV4dGVuZGluZyB0aGUgc2VsZWN0aW9uKS5cbiAgcHVibGljICRhbmNob3JDZWxsOiBSZXNvbHZlZFBvcztcblxuICAvLyBBIHJlc29sdmVkIHBvc2l0aW9uIHBvaW50aW5nIGluIGZyb250IG9mIHRoZSBoZWFkIGNlbGwgKHRoZSBvbmVcbiAgLy8gbW92ZXMgd2hlbiBleHRlbmRpbmcgdGhlIHNlbGVjdGlvbikuXG4gIHB1YmxpYyAkaGVhZENlbGw6IFJlc29sdmVkUG9zO1xuXG4gIC8vIEEgdGFibGUgc2VsZWN0aW9uIGlzIGlkZW50aWZpZWQgYnkgaXRzIGFuY2hvciBhbmQgaGVhZCBjZWxscy4gVGhlXG4gIC8vIHBvc2l0aW9ucyBnaXZlbiB0byB0aGlzIGNvbnN0cnVjdG9yIHNob3VsZCBwb2ludCBfYmVmb3JlXyB0d29cbiAgLy8gY2VsbHMgaW4gdGhlIHNhbWUgdGFibGUuIFRoZXkgbWF5IGJlIHRoZSBzYW1lLCB0byBzZWxlY3QgYSBzaW5nbGVcbiAgLy8gY2VsbC5cbiAgY29uc3RydWN0b3IoJGFuY2hvckNlbGw6IFJlc29sdmVkUG9zLCAkaGVhZENlbGw6IFJlc29sdmVkUG9zID0gJGFuY2hvckNlbGwpIHtcbiAgICBjb25zdCB0YWJsZSA9ICRhbmNob3JDZWxsLm5vZGUoLTEpO1xuICAgIGNvbnN0IG1hcCA9IFRhYmxlTWFwLmdldCh0YWJsZSk7XG4gICAgY29uc3QgdGFibGVTdGFydCA9ICRhbmNob3JDZWxsLnN0YXJ0KC0xKTtcbiAgICBjb25zdCByZWN0ID0gbWFwLnJlY3RCZXR3ZWVuKFxuICAgICAgJGFuY2hvckNlbGwucG9zIC0gdGFibGVTdGFydCxcbiAgICAgICRoZWFkQ2VsbC5wb3MgLSB0YWJsZVN0YXJ0LFxuICAgICk7XG5cbiAgICBjb25zdCBkb2MgPSAkYW5jaG9yQ2VsbC5ub2RlKDApO1xuICAgIGNvbnN0IGNlbGxzID0gbWFwXG4gICAgICAuY2VsbHNJblJlY3QocmVjdClcbiAgICAgIC5maWx0ZXIoKHApID0+IHAgIT0gJGhlYWRDZWxsLnBvcyAtIHRhYmxlU3RhcnQpO1xuICAgIC8vIE1ha2UgdGhlIGhlYWQgY2VsbCB0aGUgZmlyc3QgcmFuZ2UsIHNvIHRoYXQgaXQgY291bnRzIGFzIHRoZVxuICAgIC8vIHByaW1hcnkgcGFydCBvZiB0aGUgc2VsZWN0aW9uXG4gICAgY2VsbHMudW5zaGlmdCgkaGVhZENlbGwucG9zIC0gdGFibGVTdGFydCk7XG4gICAgY29uc3QgcmFuZ2VzID0gY2VsbHMubWFwKChwb3MpID0+IHtcbiAgICAgIGNvbnN0IGNlbGwgPSB0YWJsZS5ub2RlQXQocG9zKTtcbiAgICAgIGlmICghY2VsbCkge1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgTm8gY2VsbCB3aXRoIG9mZnNldCAke3Bvc30gZm91bmRgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZyb20gPSB0YWJsZVN0YXJ0ICsgcG9zICsgMTtcbiAgICAgIHJldHVybiBuZXcgU2VsZWN0aW9uUmFuZ2UoXG4gICAgICAgIGRvYy5yZXNvbHZlKGZyb20pLFxuICAgICAgICBkb2MucmVzb2x2ZShmcm9tICsgY2VsbC5jb250ZW50LnNpemUpLFxuICAgICAgKTtcbiAgICB9KTtcbiAgICBzdXBlcihyYW5nZXNbMF0uJGZyb20sIHJhbmdlc1swXS4kdG8sIHJhbmdlcyk7XG4gICAgdGhpcy4kYW5jaG9yQ2VsbCA9ICRhbmNob3JDZWxsO1xuICAgIHRoaXMuJGhlYWRDZWxsID0gJGhlYWRDZWxsO1xuICB9XG5cbiAgcHVibGljIG1hcChkb2M6IE5vZGUsIG1hcHBpbmc6IE1hcHBhYmxlKTogQ2VsbFNlbGVjdGlvbiB8IFNlbGVjdGlvbiB7XG4gICAgY29uc3QgJGFuY2hvckNlbGwgPSBkb2MucmVzb2x2ZShtYXBwaW5nLm1hcCh0aGlzLiRhbmNob3JDZWxsLnBvcykpO1xuICAgIGNvbnN0ICRoZWFkQ2VsbCA9IGRvYy5yZXNvbHZlKG1hcHBpbmcubWFwKHRoaXMuJGhlYWRDZWxsLnBvcykpO1xuICAgIGlmIChcbiAgICAgIHBvaW50c0F0Q2VsbCgkYW5jaG9yQ2VsbCkgJiZcbiAgICAgIHBvaW50c0F0Q2VsbCgkaGVhZENlbGwpICYmXG4gICAgICBpblNhbWVUYWJsZSgkYW5jaG9yQ2VsbCwgJGhlYWRDZWxsKVxuICAgICkge1xuICAgICAgY29uc3QgdGFibGVDaGFuZ2VkID0gdGhpcy4kYW5jaG9yQ2VsbC5ub2RlKC0xKSAhPSAkYW5jaG9yQ2VsbC5ub2RlKC0xKTtcbiAgICAgIGlmICh0YWJsZUNoYW5nZWQgJiYgdGhpcy5pc1Jvd1NlbGVjdGlvbigpKVxuICAgICAgICByZXR1cm4gQ2VsbFNlbGVjdGlvbi5yb3dTZWxlY3Rpb24oJGFuY2hvckNlbGwsICRoZWFkQ2VsbCk7XG4gICAgICBlbHNlIGlmICh0YWJsZUNoYW5nZWQgJiYgdGhpcy5pc0NvbFNlbGVjdGlvbigpKVxuICAgICAgICByZXR1cm4gQ2VsbFNlbGVjdGlvbi5jb2xTZWxlY3Rpb24oJGFuY2hvckNlbGwsICRoZWFkQ2VsbCk7XG4gICAgICBlbHNlIHJldHVybiBuZXcgQ2VsbFNlbGVjdGlvbigkYW5jaG9yQ2VsbCwgJGhlYWRDZWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIFRleHRTZWxlY3Rpb24uYmV0d2VlbigkYW5jaG9yQ2VsbCwgJGhlYWRDZWxsKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSByZWN0YW5ndWxhciBzbGljZSBvZiB0YWJsZSByb3dzIGNvbnRhaW5pbmcgdGhlIHNlbGVjdGVkXG4gIC8vIGNlbGxzLlxuICBwdWJsaWMgb3ZlcnJpZGUgY29udGVudCgpOiBTbGljZSB7XG4gICAgY29uc3QgdGFibGUgPSB0aGlzLiRhbmNob3JDZWxsLm5vZGUoLTEpO1xuICAgIGNvbnN0IG1hcCA9IFRhYmxlTWFwLmdldCh0YWJsZSk7XG4gICAgY29uc3QgdGFibGVTdGFydCA9IHRoaXMuJGFuY2hvckNlbGwuc3RhcnQoLTEpO1xuXG4gICAgY29uc3QgcmVjdCA9IG1hcC5yZWN0QmV0d2VlbihcbiAgICAgIHRoaXMuJGFuY2hvckNlbGwucG9zIC0gdGFibGVTdGFydCxcbiAgICAgIHRoaXMuJGhlYWRDZWxsLnBvcyAtIHRhYmxlU3RhcnQsXG4gICAgKTtcbiAgICBjb25zdCBzZWVuOiBSZWNvcmQ8bnVtYmVyLCBib29sZWFuPiA9IHt9O1xuICAgIGNvbnN0IHJvd3MgPSBbXTtcbiAgICBmb3IgKGxldCByb3cgPSByZWN0LnRvcDsgcm93IDwgcmVjdC5ib3R0b207IHJvdysrKSB7XG4gICAgICBjb25zdCByb3dDb250ZW50ID0gW107XG4gICAgICBmb3IgKFxuICAgICAgICBsZXQgaW5kZXggPSByb3cgKiBtYXAud2lkdGggKyByZWN0LmxlZnQsIGNvbCA9IHJlY3QubGVmdDtcbiAgICAgICAgY29sIDwgcmVjdC5yaWdodDtcbiAgICAgICAgY29sKyssIGluZGV4KytcbiAgICAgICkge1xuICAgICAgICBjb25zdCBwb3MgPSBtYXAubWFwW2luZGV4XTtcbiAgICAgICAgaWYgKHNlZW5bcG9zXSkgY29udGludWU7XG4gICAgICAgIHNlZW5bcG9zXSA9IHRydWU7XG5cbiAgICAgICAgY29uc3QgY2VsbFJlY3QgPSBtYXAuZmluZENlbGwocG9zKTtcbiAgICAgICAgbGV0IGNlbGwgPSB0YWJsZS5ub2RlQXQocG9zKTtcbiAgICAgICAgaWYgKCFjZWxsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYE5vIGNlbGwgd2l0aCBvZmZzZXQgJHtwb3N9IGZvdW5kYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBleHRyYUxlZnQgPSByZWN0LmxlZnQgLSBjZWxsUmVjdC5sZWZ0O1xuICAgICAgICBjb25zdCBleHRyYVJpZ2h0ID0gY2VsbFJlY3QucmlnaHQgLSByZWN0LnJpZ2h0O1xuXG4gICAgICAgIGlmIChleHRyYUxlZnQgPiAwIHx8IGV4dHJhUmlnaHQgPiAwKSB7XG4gICAgICAgICAgbGV0IGF0dHJzID0gY2VsbC5hdHRycyBhcyBDZWxsQXR0cnM7XG4gICAgICAgICAgaWYgKGV4dHJhTGVmdCA+IDApIHtcbiAgICAgICAgICAgIGF0dHJzID0gcmVtb3ZlQ29sU3BhbihhdHRycywgMCwgZXh0cmFMZWZ0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGV4dHJhUmlnaHQgPiAwKSB7XG4gICAgICAgICAgICBhdHRycyA9IHJlbW92ZUNvbFNwYW4oXG4gICAgICAgICAgICAgIGF0dHJzLFxuICAgICAgICAgICAgICBhdHRycy5jb2xzcGFuIC0gZXh0cmFSaWdodCxcbiAgICAgICAgICAgICAgZXh0cmFSaWdodCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjZWxsUmVjdC5sZWZ0IDwgcmVjdC5sZWZ0KSB7XG4gICAgICAgICAgICBjZWxsID0gY2VsbC50eXBlLmNyZWF0ZUFuZEZpbGwoYXR0cnMpO1xuICAgICAgICAgICAgaWYgKCFjZWxsKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFxuICAgICAgICAgICAgICAgIGBDb3VsZCBub3QgY3JlYXRlIGNlbGwgd2l0aCBhdHRycyAke0pTT04uc3RyaW5naWZ5KGF0dHJzKX1gLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjZWxsID0gY2VsbC50eXBlLmNyZWF0ZShhdHRycywgY2VsbC5jb250ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNlbGxSZWN0LnRvcCA8IHJlY3QudG9wIHx8IGNlbGxSZWN0LmJvdHRvbSA+IHJlY3QuYm90dG9tKSB7XG4gICAgICAgICAgY29uc3QgYXR0cnMgPSB7XG4gICAgICAgICAgICAuLi5jZWxsLmF0dHJzLFxuICAgICAgICAgICAgcm93c3BhbjpcbiAgICAgICAgICAgICAgTWF0aC5taW4oY2VsbFJlY3QuYm90dG9tLCByZWN0LmJvdHRvbSkgLVxuICAgICAgICAgICAgICBNYXRoLm1heChjZWxsUmVjdC50b3AsIHJlY3QudG9wKSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGlmIChjZWxsUmVjdC50b3AgPCByZWN0LnRvcCkge1xuICAgICAgICAgICAgY2VsbCA9IGNlbGwudHlwZS5jcmVhdGVBbmRGaWxsKGF0dHJzKSE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNlbGwgPSBjZWxsLnR5cGUuY3JlYXRlKGF0dHJzLCBjZWxsLmNvbnRlbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByb3dDb250ZW50LnB1c2goY2VsbCk7XG4gICAgICB9XG4gICAgICByb3dzLnB1c2godGFibGUuY2hpbGQocm93KS5jb3B5KEZyYWdtZW50LmZyb20ocm93Q29udGVudCkpKTtcbiAgICB9XG5cbiAgICBjb25zdCBmcmFnbWVudCA9XG4gICAgICB0aGlzLmlzQ29sU2VsZWN0aW9uKCkgJiYgdGhpcy5pc1Jvd1NlbGVjdGlvbigpID8gdGFibGUgOiByb3dzO1xuICAgIHJldHVybiBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbShmcmFnbWVudCksIDEsIDEpO1xuICB9XG5cbiAgcHVibGljIG92ZXJyaWRlIHJlcGxhY2UodHI6IFRyYW5zYWN0aW9uLCBjb250ZW50OiBTbGljZSA9IFNsaWNlLmVtcHR5KTogdm9pZCB7XG4gICAgY29uc3QgbWFwRnJvbSA9IHRyLnN0ZXBzLmxlbmd0aCxcbiAgICAgIHJhbmdlcyA9IHRoaXMucmFuZ2VzO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB7ICRmcm9tLCAkdG8gfSA9IHJhbmdlc1tpXSxcbiAgICAgICAgbWFwcGluZyA9IHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSk7XG4gICAgICB0ci5yZXBsYWNlKFxuICAgICAgICBtYXBwaW5nLm1hcCgkZnJvbS5wb3MpLFxuICAgICAgICBtYXBwaW5nLm1hcCgkdG8ucG9zKSxcbiAgICAgICAgaSA/IFNsaWNlLmVtcHR5IDogY29udGVudCxcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHNlbCA9IFNlbGVjdGlvbi5maW5kRnJvbShcbiAgICAgIHRyLmRvYy5yZXNvbHZlKHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSkubWFwKHRoaXMudG8pKSxcbiAgICAgIC0xLFxuICAgICk7XG4gICAgaWYgKHNlbCkgdHIuc2V0U2VsZWN0aW9uKHNlbCk7XG4gIH1cblxuICBwdWJsaWMgb3ZlcnJpZGUgcmVwbGFjZVdpdGgodHI6IFRyYW5zYWN0aW9uLCBub2RlOiBOb2RlKTogdm9pZCB7XG4gICAgdGhpcy5yZXBsYWNlKHRyLCBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbShub2RlKSwgMCwgMCkpO1xuICB9XG5cbiAgcHVibGljIGZvckVhY2hDZWxsKGY6IChub2RlOiBOb2RlLCBwb3M6IG51bWJlcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIGNvbnN0IHRhYmxlID0gdGhpcy4kYW5jaG9yQ2VsbC5ub2RlKC0xKTtcbiAgICBjb25zdCBtYXAgPSBUYWJsZU1hcC5nZXQodGFibGUpO1xuICAgIGNvbnN0IHRhYmxlU3RhcnQgPSB0aGlzLiRhbmNob3JDZWxsLnN0YXJ0KC0xKTtcblxuICAgIGNvbnN0IGNlbGxzID0gbWFwLmNlbGxzSW5SZWN0KFxuICAgICAgbWFwLnJlY3RCZXR3ZWVuKFxuICAgICAgICB0aGlzLiRhbmNob3JDZWxsLnBvcyAtIHRhYmxlU3RhcnQsXG4gICAgICAgIHRoaXMuJGhlYWRDZWxsLnBvcyAtIHRhYmxlU3RhcnQsXG4gICAgICApLFxuICAgICk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjZWxscy5sZW5ndGg7IGkrKykge1xuICAgICAgZih0YWJsZS5ub2RlQXQoY2VsbHNbaV0pISwgdGFibGVTdGFydCArIGNlbGxzW2ldKTtcbiAgICB9XG4gIH1cblxuICAvLyBUcnVlIGlmIHRoaXMgc2VsZWN0aW9uIGdvZXMgYWxsIHRoZSB3YXkgZnJvbSB0aGUgdG9wIHRvIHRoZVxuICAvLyBib3R0b20gb2YgdGhlIHRhYmxlLlxuICBwdWJsaWMgaXNDb2xTZWxlY3Rpb24oKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYW5jaG9yVG9wID0gdGhpcy4kYW5jaG9yQ2VsbC5pbmRleCgtMSk7XG4gICAgY29uc3QgaGVhZFRvcCA9IHRoaXMuJGhlYWRDZWxsLmluZGV4KC0xKTtcbiAgICBpZiAoTWF0aC5taW4oYW5jaG9yVG9wLCBoZWFkVG9wKSA+IDApIHJldHVybiBmYWxzZTtcblxuICAgIGNvbnN0IGFuY2hvckJvdHRvbSA9IGFuY2hvclRvcCArIHRoaXMuJGFuY2hvckNlbGwubm9kZUFmdGVyIS5hdHRycy5yb3dzcGFuO1xuICAgIGNvbnN0IGhlYWRCb3R0b20gPSBoZWFkVG9wICsgdGhpcy4kaGVhZENlbGwubm9kZUFmdGVyIS5hdHRycy5yb3dzcGFuO1xuXG4gICAgcmV0dXJuIChcbiAgICAgIE1hdGgubWF4KGFuY2hvckJvdHRvbSwgaGVhZEJvdHRvbSkgPT0gdGhpcy4kaGVhZENlbGwubm9kZSgtMSkuY2hpbGRDb3VudFxuICAgICk7XG4gIH1cblxuICAvLyBSZXR1cm5zIHRoZSBzbWFsbGVzdCBjb2x1bW4gc2VsZWN0aW9uIHRoYXQgY292ZXJzIHRoZSBnaXZlbiBhbmNob3JcbiAgLy8gYW5kIGhlYWQgY2VsbC5cbiAgcHVibGljIHN0YXRpYyBjb2xTZWxlY3Rpb24oXG4gICAgJGFuY2hvckNlbGw6IFJlc29sdmVkUG9zLFxuICAgICRoZWFkQ2VsbDogUmVzb2x2ZWRQb3MgPSAkYW5jaG9yQ2VsbCxcbiAgKTogQ2VsbFNlbGVjdGlvbiB7XG4gICAgY29uc3QgdGFibGUgPSAkYW5jaG9yQ2VsbC5ub2RlKC0xKTtcbiAgICBjb25zdCBtYXAgPSBUYWJsZU1hcC5nZXQodGFibGUpO1xuICAgIGNvbnN0IHRhYmxlU3RhcnQgPSAkYW5jaG9yQ2VsbC5zdGFydCgtMSk7XG5cbiAgICBjb25zdCBhbmNob3JSZWN0ID0gbWFwLmZpbmRDZWxsKCRhbmNob3JDZWxsLnBvcyAtIHRhYmxlU3RhcnQpO1xuICAgIGNvbnN0IGhlYWRSZWN0ID0gbWFwLmZpbmRDZWxsKCRoZWFkQ2VsbC5wb3MgLSB0YWJsZVN0YXJ0KTtcbiAgICBjb25zdCBkb2MgPSAkYW5jaG9yQ2VsbC5ub2RlKDApO1xuXG4gICAgaWYgKGFuY2hvclJlY3QudG9wIDw9IGhlYWRSZWN0LnRvcCkge1xuICAgICAgaWYgKGFuY2hvclJlY3QudG9wID4gMClcbiAgICAgICAgJGFuY2hvckNlbGwgPSBkb2MucmVzb2x2ZSh0YWJsZVN0YXJ0ICsgbWFwLm1hcFthbmNob3JSZWN0LmxlZnRdKTtcbiAgICAgIGlmIChoZWFkUmVjdC5ib3R0b20gPCBtYXAuaGVpZ2h0KVxuICAgICAgICAkaGVhZENlbGwgPSBkb2MucmVzb2x2ZShcbiAgICAgICAgICB0YWJsZVN0YXJ0ICtcbiAgICAgICAgICAgIG1hcC5tYXBbbWFwLndpZHRoICogKG1hcC5oZWlnaHQgLSAxKSArIGhlYWRSZWN0LnJpZ2h0IC0gMV0sXG4gICAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChoZWFkUmVjdC50b3AgPiAwKVxuICAgICAgICAkaGVhZENlbGwgPSBkb2MucmVzb2x2ZSh0YWJsZVN0YXJ0ICsgbWFwLm1hcFtoZWFkUmVjdC5sZWZ0XSk7XG4gICAgICBpZiAoYW5jaG9yUmVjdC5ib3R0b20gPCBtYXAuaGVpZ2h0KVxuICAgICAgICAkYW5jaG9yQ2VsbCA9IGRvYy5yZXNvbHZlKFxuICAgICAgICAgIHRhYmxlU3RhcnQgK1xuICAgICAgICAgICAgbWFwLm1hcFttYXAud2lkdGggKiAobWFwLmhlaWdodCAtIDEpICsgYW5jaG9yUmVjdC5yaWdodCAtIDFdLFxuICAgICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IENlbGxTZWxlY3Rpb24oJGFuY2hvckNlbGwsICRoZWFkQ2VsbCk7XG4gIH1cblxuICAvLyBUcnVlIGlmIHRoaXMgc2VsZWN0aW9uIGdvZXMgYWxsIHRoZSB3YXkgZnJvbSB0aGUgbGVmdCB0byB0aGVcbiAgLy8gcmlnaHQgb2YgdGhlIHRhYmxlLlxuICBwdWJsaWMgaXNSb3dTZWxlY3Rpb24oKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdGFibGUgPSB0aGlzLiRhbmNob3JDZWxsLm5vZGUoLTEpO1xuICAgIGNvbnN0IG1hcCA9IFRhYmxlTWFwLmdldCh0YWJsZSk7XG4gICAgY29uc3QgdGFibGVTdGFydCA9IHRoaXMuJGFuY2hvckNlbGwuc3RhcnQoLTEpO1xuXG4gICAgY29uc3QgYW5jaG9yTGVmdCA9IG1hcC5jb2xDb3VudCh0aGlzLiRhbmNob3JDZWxsLnBvcyAtIHRhYmxlU3RhcnQpO1xuICAgIGNvbnN0IGhlYWRMZWZ0ID0gbWFwLmNvbENvdW50KHRoaXMuJGhlYWRDZWxsLnBvcyAtIHRhYmxlU3RhcnQpO1xuICAgIGlmIChNYXRoLm1pbihhbmNob3JMZWZ0LCBoZWFkTGVmdCkgPiAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICBjb25zdCBhbmNob3JSaWdodCA9IGFuY2hvckxlZnQgKyB0aGlzLiRhbmNob3JDZWxsLm5vZGVBZnRlciEuYXR0cnMuY29sc3BhbjtcbiAgICBjb25zdCBoZWFkUmlnaHQgPSBoZWFkTGVmdCArIHRoaXMuJGhlYWRDZWxsLm5vZGVBZnRlciEuYXR0cnMuY29sc3BhbjtcbiAgICByZXR1cm4gTWF0aC5tYXgoYW5jaG9yUmlnaHQsIGhlYWRSaWdodCkgPT0gbWFwLndpZHRoO1xuICB9XG5cbiAgcHVibGljIGVxKG90aGVyOiB1bmtub3duKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIG90aGVyIGluc3RhbmNlb2YgQ2VsbFNlbGVjdGlvbiAmJlxuICAgICAgb3RoZXIuJGFuY2hvckNlbGwucG9zID09IHRoaXMuJGFuY2hvckNlbGwucG9zICYmXG4gICAgICBvdGhlci4kaGVhZENlbGwucG9zID09IHRoaXMuJGhlYWRDZWxsLnBvc1xuICAgICk7XG4gIH1cblxuICAvLyBSZXR1cm5zIHRoZSBzbWFsbGVzdCByb3cgc2VsZWN0aW9uIHRoYXQgY292ZXJzIHRoZSBnaXZlbiBhbmNob3JcbiAgLy8gYW5kIGhlYWQgY2VsbC5cbiAgcHVibGljIHN0YXRpYyByb3dTZWxlY3Rpb24oXG4gICAgJGFuY2hvckNlbGw6IFJlc29sdmVkUG9zLFxuICAgICRoZWFkQ2VsbDogUmVzb2x2ZWRQb3MgPSAkYW5jaG9yQ2VsbCxcbiAgKTogQ2VsbFNlbGVjdGlvbiB7XG4gICAgY29uc3QgdGFibGUgPSAkYW5jaG9yQ2VsbC5ub2RlKC0xKTtcbiAgICBjb25zdCBtYXAgPSBUYWJsZU1hcC5nZXQodGFibGUpO1xuICAgIGNvbnN0IHRhYmxlU3RhcnQgPSAkYW5jaG9yQ2VsbC5zdGFydCgtMSk7XG5cbiAgICBjb25zdCBhbmNob3JSZWN0ID0gbWFwLmZpbmRDZWxsKCRhbmNob3JDZWxsLnBvcyAtIHRhYmxlU3RhcnQpO1xuICAgIGNvbnN0IGhlYWRSZWN0ID0gbWFwLmZpbmRDZWxsKCRoZWFkQ2VsbC5wb3MgLSB0YWJsZVN0YXJ0KTtcbiAgICBjb25zdCBkb2MgPSAkYW5jaG9yQ2VsbC5ub2RlKDApO1xuXG4gICAgaWYgKGFuY2hvclJlY3QubGVmdCA8PSBoZWFkUmVjdC5sZWZ0KSB7XG4gICAgICBpZiAoYW5jaG9yUmVjdC5sZWZ0ID4gMClcbiAgICAgICAgJGFuY2hvckNlbGwgPSBkb2MucmVzb2x2ZShcbiAgICAgICAgICB0YWJsZVN0YXJ0ICsgbWFwLm1hcFthbmNob3JSZWN0LnRvcCAqIG1hcC53aWR0aF0sXG4gICAgICAgICk7XG4gICAgICBpZiAoaGVhZFJlY3QucmlnaHQgPCBtYXAud2lkdGgpXG4gICAgICAgICRoZWFkQ2VsbCA9IGRvYy5yZXNvbHZlKFxuICAgICAgICAgIHRhYmxlU3RhcnQgKyBtYXAubWFwW21hcC53aWR0aCAqIChoZWFkUmVjdC50b3AgKyAxKSAtIDFdLFxuICAgICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaGVhZFJlY3QubGVmdCA+IDApXG4gICAgICAgICRoZWFkQ2VsbCA9IGRvYy5yZXNvbHZlKHRhYmxlU3RhcnQgKyBtYXAubWFwW2hlYWRSZWN0LnRvcCAqIG1hcC53aWR0aF0pO1xuICAgICAgaWYgKGFuY2hvclJlY3QucmlnaHQgPCBtYXAud2lkdGgpXG4gICAgICAgICRhbmNob3JDZWxsID0gZG9jLnJlc29sdmUoXG4gICAgICAgICAgdGFibGVTdGFydCArIG1hcC5tYXBbbWFwLndpZHRoICogKGFuY2hvclJlY3QudG9wICsgMSkgLSAxXSxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBDZWxsU2VsZWN0aW9uKCRhbmNob3JDZWxsLCAkaGVhZENlbGwpO1xuICB9XG5cbiAgcHVibGljIHRvSlNPTigpOiBDZWxsU2VsZWN0aW9uSlNPTiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdjZWxsJyxcbiAgICAgIGFuY2hvcjogdGhpcy4kYW5jaG9yQ2VsbC5wb3MsXG4gICAgICBoZWFkOiB0aGlzLiRoZWFkQ2VsbC5wb3MsXG4gICAgfTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgb3ZlcnJpZGUgZnJvbUpTT04oXG4gICAgZG9jOiBOb2RlLFxuICAgIGpzb246IENlbGxTZWxlY3Rpb25KU09OLFxuICApOiBDZWxsU2VsZWN0aW9uIHtcbiAgICByZXR1cm4gbmV3IENlbGxTZWxlY3Rpb24oZG9jLnJlc29sdmUoanNvbi5hbmNob3IpLCBkb2MucmVzb2x2ZShqc29uLmhlYWQpKTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGUoXG4gICAgZG9jOiBOb2RlLFxuICAgIGFuY2hvckNlbGw6IG51bWJlcixcbiAgICBoZWFkQ2VsbDogbnVtYmVyID0gYW5jaG9yQ2VsbCxcbiAgKTogQ2VsbFNlbGVjdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBDZWxsU2VsZWN0aW9uKGRvYy5yZXNvbHZlKGFuY2hvckNlbGwpLCBkb2MucmVzb2x2ZShoZWFkQ2VsbCkpO1xuICB9XG5cbiAgcHVibGljIG92ZXJyaWRlIGdldEJvb2ttYXJrKCk6IENlbGxCb29rbWFyayB7XG4gICAgcmV0dXJuIG5ldyBDZWxsQm9va21hcmsodGhpcy4kYW5jaG9yQ2VsbC5wb3MsIHRoaXMuJGhlYWRDZWxsLnBvcyk7XG4gIH1cbn1cblxuQ2VsbFNlbGVjdGlvbi5wcm90b3R5cGUudmlzaWJsZSA9IGZhbHNlO1xuXG5TZWxlY3Rpb24uanNvbklEKCdjZWxsJywgQ2VsbFNlbGVjdGlvbik7XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY2xhc3MgQ2VsbEJvb2ttYXJrIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGFuY2hvcjogbnVtYmVyLFxuICAgIHB1YmxpYyBoZWFkOiBudW1iZXIsXG4gICkge31cblxuICBtYXAobWFwcGluZzogTWFwcGFibGUpOiBDZWxsQm9va21hcmsge1xuICAgIHJldHVybiBuZXcgQ2VsbEJvb2ttYXJrKG1hcHBpbmcubWFwKHRoaXMuYW5jaG9yKSwgbWFwcGluZy5tYXAodGhpcy5oZWFkKSk7XG4gIH1cblxuICByZXNvbHZlKGRvYzogTm9kZSk6IENlbGxTZWxlY3Rpb24gfCBTZWxlY3Rpb24ge1xuICAgIGNvbnN0ICRhbmNob3JDZWxsID0gZG9jLnJlc29sdmUodGhpcy5hbmNob3IpLFxuICAgICAgJGhlYWRDZWxsID0gZG9jLnJlc29sdmUodGhpcy5oZWFkKTtcbiAgICBpZiAoXG4gICAgICAkYW5jaG9yQ2VsbC5wYXJlbnQudHlwZS5zcGVjLnRhYmxlUm9sZSA9PSAncm93JyAmJlxuICAgICAgJGhlYWRDZWxsLnBhcmVudC50eXBlLnNwZWMudGFibGVSb2xlID09ICdyb3cnICYmXG4gICAgICAkYW5jaG9yQ2VsbC5pbmRleCgpIDwgJGFuY2hvckNlbGwucGFyZW50LmNoaWxkQ291bnQgJiZcbiAgICAgICRoZWFkQ2VsbC5pbmRleCgpIDwgJGhlYWRDZWxsLnBhcmVudC5jaGlsZENvdW50ICYmXG4gICAgICBpblNhbWVUYWJsZSgkYW5jaG9yQ2VsbCwgJGhlYWRDZWxsKVxuICAgIClcbiAgICAgIHJldHVybiBuZXcgQ2VsbFNlbGVjdGlvbigkYW5jaG9yQ2VsbCwgJGhlYWRDZWxsKTtcbiAgICBlbHNlIHJldHVybiBTZWxlY3Rpb24ubmVhcigkaGVhZENlbGwsIDEpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkcmF3Q2VsbFNlbGVjdGlvbihzdGF0ZTogRWRpdG9yU3RhdGUpOiBEZWNvcmF0aW9uU291cmNlIHwgbnVsbCB7XG4gIGlmICghKHN0YXRlLnNlbGVjdGlvbiBpbnN0YW5jZW9mIENlbGxTZWxlY3Rpb24pKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgY2VsbHM6IERlY29yYXRpb25bXSA9IFtdO1xuICBzdGF0ZS5zZWxlY3Rpb24uZm9yRWFjaENlbGwoKG5vZGUsIHBvcykgPT4ge1xuICAgIGNlbGxzLnB1c2goXG4gICAgICBEZWNvcmF0aW9uLm5vZGUocG9zLCBwb3MgKyBub2RlLm5vZGVTaXplLCB7IGNsYXNzOiAnc2VsZWN0ZWRDZWxsJyB9KSxcbiAgICApO1xuICB9KTtcbiAgcmV0dXJuIERlY29yYXRpb25TZXQuY3JlYXRlKHN0YXRlLmRvYywgY2VsbHMpO1xufVxuXG5mdW5jdGlvbiBpc0NlbGxCb3VuZGFyeVNlbGVjdGlvbih7ICRmcm9tLCAkdG8gfTogVGV4dFNlbGVjdGlvbikge1xuICBpZiAoJGZyb20ucG9zID09ICR0by5wb3MgfHwgJGZyb20ucG9zIDwgJHRvLnBvcyAtIDYpIHJldHVybiBmYWxzZTsgLy8gQ2hlYXAgZWxpbWluYXRpb25cbiAgbGV0IGFmdGVyRnJvbSA9ICRmcm9tLnBvcztcbiAgbGV0IGJlZm9yZVRvID0gJHRvLnBvcztcbiAgbGV0IGRlcHRoID0gJGZyb20uZGVwdGg7XG4gIGZvciAoOyBkZXB0aCA+PSAwOyBkZXB0aC0tLCBhZnRlckZyb20rKylcbiAgICBpZiAoJGZyb20uYWZ0ZXIoZGVwdGggKyAxKSA8ICRmcm9tLmVuZChkZXB0aCkpIGJyZWFrO1xuICBmb3IgKGxldCBkID0gJHRvLmRlcHRoOyBkID49IDA7IGQtLSwgYmVmb3JlVG8tLSlcbiAgICBpZiAoJHRvLmJlZm9yZShkICsgMSkgPiAkdG8uc3RhcnQoZCkpIGJyZWFrO1xuICByZXR1cm4gKFxuICAgIGFmdGVyRnJvbSA9PSBiZWZvcmVUbyAmJlxuICAgIC9yb3d8dGFibGUvLnRlc3QoJGZyb20ubm9kZShkZXB0aCkudHlwZS5zcGVjLnRhYmxlUm9sZSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gaXNUZXh0U2VsZWN0aW9uQWNyb3NzQ2VsbHMoeyAkZnJvbSwgJHRvIH06IFRleHRTZWxlY3Rpb24pIHtcbiAgbGV0IGZyb21DZWxsQm91bmRhcnlOb2RlOiBOb2RlIHwgdW5kZWZpbmVkO1xuICBsZXQgdG9DZWxsQm91bmRhcnlOb2RlOiBOb2RlIHwgdW5kZWZpbmVkO1xuXG4gIGZvciAobGV0IGkgPSAkZnJvbS5kZXB0aDsgaSA+IDA7IGktLSkge1xuICAgIGNvbnN0IG5vZGUgPSAkZnJvbS5ub2RlKGkpO1xuICAgIGlmIChcbiAgICAgIG5vZGUudHlwZS5zcGVjLnRhYmxlUm9sZSA9PT0gJ2NlbGwnIHx8XG4gICAgICBub2RlLnR5cGUuc3BlYy50YWJsZVJvbGUgPT09ICdoZWFkZXJfY2VsbCdcbiAgICApIHtcbiAgICAgIGZyb21DZWxsQm91bmRhcnlOb2RlID0gbm9kZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGZvciAobGV0IGkgPSAkdG8uZGVwdGg7IGkgPiAwOyBpLS0pIHtcbiAgICBjb25zdCBub2RlID0gJHRvLm5vZGUoaSk7XG4gICAgaWYgKFxuICAgICAgbm9kZS50eXBlLnNwZWMudGFibGVSb2xlID09PSAnY2VsbCcgfHxcbiAgICAgIG5vZGUudHlwZS5zcGVjLnRhYmxlUm9sZSA9PT0gJ2hlYWRlcl9jZWxsJ1xuICAgICkge1xuICAgICAgdG9DZWxsQm91bmRhcnlOb2RlID0gbm9kZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmcm9tQ2VsbEJvdW5kYXJ5Tm9kZSAhPT0gdG9DZWxsQm91bmRhcnlOb2RlICYmICR0by5wYXJlbnRPZmZzZXQgPT09IDA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVTZWxlY3Rpb24oXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgdHI6IFRyYW5zYWN0aW9uIHwgdW5kZWZpbmVkLFxuICBhbGxvd1RhYmxlTm9kZVNlbGVjdGlvbjogYm9vbGVhbixcbik6IFRyYW5zYWN0aW9uIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc2VsID0gKHRyIHx8IHN0YXRlKS5zZWxlY3Rpb247XG4gIGNvbnN0IGRvYyA9ICh0ciB8fCBzdGF0ZSkuZG9jO1xuICBsZXQgbm9ybWFsaXplOiBTZWxlY3Rpb24gfCB1bmRlZmluZWQ7XG4gIGxldCByb2xlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGlmIChzZWwgaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uICYmIChyb2xlID0gc2VsLm5vZGUudHlwZS5zcGVjLnRhYmxlUm9sZSkpIHtcbiAgICBpZiAocm9sZSA9PSAnY2VsbCcgfHwgcm9sZSA9PSAnaGVhZGVyX2NlbGwnKSB7XG4gICAgICBub3JtYWxpemUgPSBDZWxsU2VsZWN0aW9uLmNyZWF0ZShkb2MsIHNlbC5mcm9tKTtcbiAgICB9IGVsc2UgaWYgKHJvbGUgPT0gJ3JvdycpIHtcbiAgICAgIGNvbnN0ICRjZWxsID0gZG9jLnJlc29sdmUoc2VsLmZyb20gKyAxKTtcbiAgICAgIG5vcm1hbGl6ZSA9IENlbGxTZWxlY3Rpb24ucm93U2VsZWN0aW9uKCRjZWxsLCAkY2VsbCk7XG4gICAgfSBlbHNlIGlmICghYWxsb3dUYWJsZU5vZGVTZWxlY3Rpb24pIHtcbiAgICAgIGNvbnN0IG1hcCA9IFRhYmxlTWFwLmdldChzZWwubm9kZSk7XG4gICAgICBjb25zdCBzdGFydCA9IHNlbC5mcm9tICsgMTtcbiAgICAgIGNvbnN0IGxhc3RDZWxsID0gc3RhcnQgKyBtYXAubWFwW21hcC53aWR0aCAqIG1hcC5oZWlnaHQgLSAxXTtcbiAgICAgIG5vcm1hbGl6ZSA9IENlbGxTZWxlY3Rpb24uY3JlYXRlKGRvYywgc3RhcnQgKyAxLCBsYXN0Q2VsbCk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHNlbCBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24gJiYgaXNDZWxsQm91bmRhcnlTZWxlY3Rpb24oc2VsKSkge1xuICAgIG5vcm1hbGl6ZSA9IFRleHRTZWxlY3Rpb24uY3JlYXRlKGRvYywgc2VsLmZyb20pO1xuICB9IGVsc2UgaWYgKHNlbCBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24gJiYgaXNUZXh0U2VsZWN0aW9uQWNyb3NzQ2VsbHMoc2VsKSkge1xuICAgIG5vcm1hbGl6ZSA9IFRleHRTZWxlY3Rpb24uY3JlYXRlKGRvYywgc2VsLiRmcm9tLnN0YXJ0KCksIHNlbC4kZnJvbS5lbmQoKSk7XG4gIH1cbiAgaWYgKG5vcm1hbGl6ZSkgKHRyIHx8ICh0ciA9IHN0YXRlLnRyKSkuc2V0U2VsZWN0aW9uKG5vcm1hbGl6ZSk7XG4gIHJldHVybiB0cjtcbn1cbiIsICIvLyBUaGlzIGZpbGUgZGVmaW5lcyBoZWxwZXJzIGZvciBub3JtYWxpemluZyB0YWJsZXMsIG1ha2luZyBzdXJlIG5vXG4vLyBjZWxscyBvdmVybGFwICh3aGljaCBjYW4gaGFwcGVuLCBpZiB5b3UgaGF2ZSB0aGUgd3JvbmcgY29sLSBhbmRcbi8vIHJvd3NwYW5zKSBhbmQgdGhhdCBlYWNoIHJvdyBoYXMgdGhlIHNhbWUgd2lkdGguIFVzZXMgdGhlIHByb2JsZW1zXG4vLyByZXBvcnRlZCBieSBgVGFibGVNYXBgLlxuXG5pbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tICdwcm9zZW1pcnJvci1tb2RlbCc7XG5pbXBvcnQgdHlwZSB7IEVkaXRvclN0YXRlLCBUcmFuc2FjdGlvbiB9IGZyb20gJ3Byb3NlbWlycm9yLXN0YXRlJztcbmltcG9ydCB7IFBsdWdpbktleSB9IGZyb20gJ3Byb3NlbWlycm9yLXN0YXRlJztcblxuaW1wb3J0IHR5cGUgeyBUYWJsZVJvbGUgfSBmcm9tICcuL3NjaGVtYSc7XG5pbXBvcnQgeyB0YWJsZU5vZGVUeXBlcyB9IGZyb20gJy4vc2NoZW1hJztcbmltcG9ydCB7IFRhYmxlTWFwIH0gZnJvbSAnLi90YWJsZW1hcCc7XG5pbXBvcnQgdHlwZSB7IENlbGxBdHRycyB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgeyByZW1vdmVDb2xTcGFuIH0gZnJvbSAnLi91dGlsJztcblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBmaXhUYWJsZXNLZXkgPSBuZXcgUGx1Z2luS2V5PHsgZml4VGFibGVzOiBib29sZWFuIH0+KCdmaXgtdGFibGVzJyk7XG5cbi8qKlxuICogSGVscGVyIGZvciBpdGVyYXRpbmcgdGhyb3VnaCB0aGUgbm9kZXMgaW4gYSBkb2N1bWVudCB0aGF0IGNoYW5nZWRcbiAqIGNvbXBhcmVkIHRvIHRoZSBnaXZlbiBwcmV2aW91cyBkb2N1bWVudC4gVXNlZnVsIGZvciBhdm9pZGluZ1xuICogZHVwbGljYXRlIHdvcmsgb24gZWFjaCB0cmFuc2FjdGlvbi5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmZ1bmN0aW9uIGNoYW5nZWREZXNjZW5kYW50cyhcbiAgb2xkOiBOb2RlLFxuICBjdXI6IE5vZGUsXG4gIG9mZnNldDogbnVtYmVyLFxuICBmOiAobm9kZTogTm9kZSwgcG9zOiBudW1iZXIpID0+IHZvaWQsXG4pOiB2b2lkIHtcbiAgY29uc3Qgb2xkU2l6ZSA9IG9sZC5jaGlsZENvdW50LFxuICAgIGN1clNpemUgPSBjdXIuY2hpbGRDb3VudDtcbiAgb3V0ZXI6IGZvciAobGV0IGkgPSAwLCBqID0gMDsgaSA8IGN1clNpemU7IGkrKykge1xuICAgIGNvbnN0IGNoaWxkID0gY3VyLmNoaWxkKGkpO1xuICAgIGZvciAobGV0IHNjYW4gPSBqLCBlID0gTWF0aC5taW4ob2xkU2l6ZSwgaSArIDMpOyBzY2FuIDwgZTsgc2NhbisrKSB7XG4gICAgICBpZiAob2xkLmNoaWxkKHNjYW4pID09IGNoaWxkKSB7XG4gICAgICAgIGogPSBzY2FuICsgMTtcbiAgICAgICAgb2Zmc2V0ICs9IGNoaWxkLm5vZGVTaXplO1xuICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgIH1cbiAgICB9XG4gICAgZihjaGlsZCwgb2Zmc2V0KTtcbiAgICBpZiAoaiA8IG9sZFNpemUgJiYgb2xkLmNoaWxkKGopLnNhbWVNYXJrdXAoY2hpbGQpKVxuICAgICAgY2hhbmdlZERlc2NlbmRhbnRzKG9sZC5jaGlsZChqKSwgY2hpbGQsIG9mZnNldCArIDEsIGYpO1xuICAgIGVsc2UgY2hpbGQubm9kZXNCZXR3ZWVuKDAsIGNoaWxkLmNvbnRlbnQuc2l6ZSwgZiwgb2Zmc2V0ICsgMSk7XG4gICAgb2Zmc2V0ICs9IGNoaWxkLm5vZGVTaXplO1xuICB9XG59XG5cbi8qKlxuICogSW5zcGVjdCBhbGwgdGFibGVzIGluIHRoZSBnaXZlbiBzdGF0ZSdzIGRvY3VtZW50IGFuZCByZXR1cm4gYVxuICogdHJhbnNhY3Rpb24gdGhhdCBmaXhlcyB0aGVtLCBpZiBuZWNlc3NhcnkuIElmIGBvbGRTdGF0ZWAgd2FzXG4gKiBwcm92aWRlZCwgdGhhdCBpcyBhc3N1bWVkIHRvIGhvbGQgYSBwcmV2aW91cywga25vd24tZ29vZCBzdGF0ZSxcbiAqIHdoaWNoIHdpbGwgYmUgdXNlZCB0byBhdm9pZCByZS1zY2FubmluZyB1bmNoYW5nZWQgcGFydHMgb2YgdGhlXG4gKiBkb2N1bWVudC5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaXhUYWJsZXMoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgb2xkU3RhdGU/OiBFZGl0b3JTdGF0ZSxcbik6IFRyYW5zYWN0aW9uIHwgdW5kZWZpbmVkIHtcbiAgbGV0IHRyOiBUcmFuc2FjdGlvbiB8IHVuZGVmaW5lZDtcbiAgY29uc3QgY2hlY2sgPSAobm9kZTogTm9kZSwgcG9zOiBudW1iZXIpID0+IHtcbiAgICBpZiAobm9kZS50eXBlLnNwZWMudGFibGVSb2xlID09ICd0YWJsZScpXG4gICAgICB0ciA9IGZpeFRhYmxlKHN0YXRlLCBub2RlLCBwb3MsIHRyKTtcbiAgfTtcbiAgaWYgKCFvbGRTdGF0ZSkgc3RhdGUuZG9jLmRlc2NlbmRhbnRzKGNoZWNrKTtcbiAgZWxzZSBpZiAob2xkU3RhdGUuZG9jICE9IHN0YXRlLmRvYylcbiAgICBjaGFuZ2VkRGVzY2VuZGFudHMob2xkU3RhdGUuZG9jLCBzdGF0ZS5kb2MsIDAsIGNoZWNrKTtcbiAgcmV0dXJuIHRyO1xufVxuXG4vLyBGaXggdGhlIGdpdmVuIHRhYmxlLCBpZiBuZWNlc3NhcnkuIFdpbGwgYXBwZW5kIHRvIHRoZSB0cmFuc2FjdGlvblxuLy8gaXQgd2FzIGdpdmVuLCBpZiBub24tbnVsbCwgb3IgY3JlYXRlIGEgbmV3IG9uZSBpZiBuZWNlc3NhcnkuXG5leHBvcnQgZnVuY3Rpb24gZml4VGFibGUoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgdGFibGU6IE5vZGUsXG4gIHRhYmxlUG9zOiBudW1iZXIsXG4gIHRyOiBUcmFuc2FjdGlvbiB8IHVuZGVmaW5lZCxcbik6IFRyYW5zYWN0aW9uIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgbWFwID0gVGFibGVNYXAuZ2V0KHRhYmxlKTtcbiAgaWYgKCFtYXAucHJvYmxlbXMpIHJldHVybiB0cjtcbiAgaWYgKCF0cikgdHIgPSBzdGF0ZS50cjtcblxuICAvLyBUcmFjayB3aGljaCByb3dzIHdlIG11c3QgYWRkIGNlbGxzIHRvLCBzbyB0aGF0IHdlIGNhbiBhZGp1c3QgdGhhdFxuICAvLyB3aGVuIGZpeGluZyBjb2xsaXNpb25zLlxuICBjb25zdCBtdXN0QWRkOiBudW1iZXJbXSA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG1hcC5oZWlnaHQ7IGkrKykgbXVzdEFkZC5wdXNoKDApO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG1hcC5wcm9ibGVtcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHByb2IgPSBtYXAucHJvYmxlbXNbaV07XG4gICAgaWYgKHByb2IudHlwZSA9PSAnY29sbGlzaW9uJykge1xuICAgICAgY29uc3QgY2VsbCA9IHRhYmxlLm5vZGVBdChwcm9iLnBvcyk7XG4gICAgICBpZiAoIWNlbGwpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgYXR0cnMgPSBjZWxsLmF0dHJzIGFzIENlbGxBdHRycztcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgYXR0cnMucm93c3BhbjsgaisrKSBtdXN0QWRkW3Byb2Iucm93ICsgal0gKz0gcHJvYi5uO1xuICAgICAgdHIuc2V0Tm9kZU1hcmt1cChcbiAgICAgICAgdHIubWFwcGluZy5tYXAodGFibGVQb3MgKyAxICsgcHJvYi5wb3MpLFxuICAgICAgICBudWxsLFxuICAgICAgICByZW1vdmVDb2xTcGFuKGF0dHJzLCBhdHRycy5jb2xzcGFuIC0gcHJvYi5uLCBwcm9iLm4pLFxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHByb2IudHlwZSA9PSAnbWlzc2luZycpIHtcbiAgICAgIG11c3RBZGRbcHJvYi5yb3ddICs9IHByb2IubjtcbiAgICB9IGVsc2UgaWYgKHByb2IudHlwZSA9PSAnb3Zlcmxvbmdfcm93c3BhbicpIHtcbiAgICAgIGNvbnN0IGNlbGwgPSB0YWJsZS5ub2RlQXQocHJvYi5wb3MpO1xuICAgICAgaWYgKCFjZWxsKSBjb250aW51ZTtcbiAgICAgIHRyLnNldE5vZGVNYXJrdXAodHIubWFwcGluZy5tYXAodGFibGVQb3MgKyAxICsgcHJvYi5wb3MpLCBudWxsLCB7XG4gICAgICAgIC4uLmNlbGwuYXR0cnMsXG4gICAgICAgIHJvd3NwYW46IGNlbGwuYXR0cnMucm93c3BhbiAtIHByb2IubixcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAocHJvYi50eXBlID09ICdjb2x3aWR0aCBtaXNtYXRjaCcpIHtcbiAgICAgIGNvbnN0IGNlbGwgPSB0YWJsZS5ub2RlQXQocHJvYi5wb3MpO1xuICAgICAgaWYgKCFjZWxsKSBjb250aW51ZTtcbiAgICAgIHRyLnNldE5vZGVNYXJrdXAodHIubWFwcGluZy5tYXAodGFibGVQb3MgKyAxICsgcHJvYi5wb3MpLCBudWxsLCB7XG4gICAgICAgIC4uLmNlbGwuYXR0cnMsXG4gICAgICAgIGNvbHdpZHRoOiBwcm9iLmNvbHdpZHRoLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChwcm9iLnR5cGUgPT0gJ3plcm9fc2l6ZWQnKSB7XG4gICAgICBjb25zdCBwb3MgPSB0ci5tYXBwaW5nLm1hcCh0YWJsZVBvcyk7XG4gICAgICB0ci5kZWxldGUocG9zLCBwb3MgKyB0YWJsZS5ub2RlU2l6ZSk7XG4gICAgfVxuICB9XG4gIGxldCBmaXJzdCwgbGFzdDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtdXN0QWRkLmxlbmd0aDsgaSsrKVxuICAgIGlmIChtdXN0QWRkW2ldKSB7XG4gICAgICBpZiAoZmlyc3QgPT0gbnVsbCkgZmlyc3QgPSBpO1xuICAgICAgbGFzdCA9IGk7XG4gICAgfVxuICAvLyBBZGQgdGhlIG5lY2Vzc2FyeSBjZWxscywgdXNpbmcgYSBoZXVyaXN0aWMgZm9yIHdoZXRoZXIgdG8gYWRkIHRoZVxuICAvLyBjZWxscyBhdCB0aGUgc3RhcnQgb3IgZW5kIG9mIHRoZSByb3dzIChpZiBpdCBsb29rcyBsaWtlIGEgJ2JpdGUnXG4gIC8vIHdhcyB0YWtlbiBvdXQgb2YgdGhlIHRhYmxlLCBhZGQgY2VsbHMgYXQgdGhlIHN0YXJ0IG9mIHRoZSByb3dcbiAgLy8gYWZ0ZXIgdGhlIGJpdGUuIE90aGVyd2lzZSBhZGQgdGhlbSBhdCB0aGUgZW5kKS5cbiAgZm9yIChsZXQgaSA9IDAsIHBvcyA9IHRhYmxlUG9zICsgMTsgaSA8IG1hcC5oZWlnaHQ7IGkrKykge1xuICAgIGNvbnN0IHJvdyA9IHRhYmxlLmNoaWxkKGkpO1xuICAgIGNvbnN0IGVuZCA9IHBvcyArIHJvdy5ub2RlU2l6ZTtcbiAgICBjb25zdCBhZGQgPSBtdXN0QWRkW2ldO1xuICAgIGlmIChhZGQgPiAwKSB7XG4gICAgICBsZXQgcm9sZTogVGFibGVSb2xlID0gJ2NlbGwnO1xuICAgICAgaWYgKHJvdy5maXJzdENoaWxkKSB7XG4gICAgICAgIHJvbGUgPSByb3cuZmlyc3RDaGlsZC50eXBlLnNwZWMudGFibGVSb2xlO1xuICAgICAgfVxuICAgICAgY29uc3Qgbm9kZXM6IE5vZGVbXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBhZGQ7IGorKykge1xuICAgICAgICBjb25zdCBub2RlID0gdGFibGVOb2RlVHlwZXMoc3RhdGUuc2NoZW1hKVtyb2xlXS5jcmVhdGVBbmRGaWxsKCk7XG5cbiAgICAgICAgaWYgKG5vZGUpIG5vZGVzLnB1c2gobm9kZSk7XG4gICAgICB9XG4gICAgICBjb25zdCBzaWRlID0gKGkgPT0gMCB8fCBmaXJzdCA9PSBpIC0gMSkgJiYgbGFzdCA9PSBpID8gcG9zICsgMSA6IGVuZCAtIDE7XG4gICAgICB0ci5pbnNlcnQodHIubWFwcGluZy5tYXAoc2lkZSksIG5vZGVzKTtcbiAgICB9XG4gICAgcG9zID0gZW5kO1xuICB9XG4gIHJldHVybiB0ci5zZXRNZXRhKGZpeFRhYmxlc0tleSwgeyBmaXhUYWJsZXM6IHRydWUgfSk7XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuXG5pbXBvcnQgeyBUYWJsZU1hcCB9IGZyb20gJy4uL3RhYmxlbWFwJztcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgdHJhbnNmb3JtIHRoZSB0YWJsZSBub2RlIGludG8gYSBtYXRyaXggb2Ygcm93cyBhbmQgY29sdW1uc1xuICogcmVzcGVjdGluZyBtZXJnZWQgY2VsbHMsIGZvciBleGFtcGxlIHRoaXMgdGFibGU6XG4gKlxuICogYGBgXG4gKiDilIzilIDilIDilIDilIDilIDilIDilKzilIDilIDilIDilIDilIDilIDilKzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJBcbiAqIOKUgiAgQTEgIOKUgiAgQjEgIOKUgiAgICAgQzEgICAgICDilIJcbiAqIOKUnOKUgOKUgOKUgOKUgOKUgOKUgOKUvOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUgOKUgOKUpFxuICog4pSCICBBMiAg4pSCICAgICBCMiAgICAgIOKUgiAgICAgIOKUglxuICog4pSc4pSA4pSA4pSA4pSA4pSA4pSA4pS84pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSkICBEMSAg4pSCXG4gKiDilIIgIEEzICDilIIgIEIzICDilIIgIEMzICDilIIgICAgICDilIJcbiAqIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUmFxuICogYGBgXG4gKlxuICogd2lsbCBiZSBjb252ZXJ0ZWQgdG8gdGhlIGJlbG93OlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIFtcbiAqICAgW0ExLCBCMSwgQzEsIG51bGxdLFxuICogICBbQTIsIEIyLCBudWxsLCBEMV0sXG4gKiAgIFtBMywgQjMsIEMzLCBudWxsXSxcbiAqIF1cbiAqIGBgYFxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0VGFibGVOb2RlVG9BcnJheU9mUm93cyhcbiAgdGFibGVOb2RlOiBOb2RlLFxuKTogKE5vZGUgfCBudWxsKVtdW10ge1xuICBjb25zdCBtYXAgPSBUYWJsZU1hcC5nZXQodGFibGVOb2RlKTtcbiAgY29uc3Qgcm93czogKE5vZGUgfCBudWxsKVtdW10gPSBbXTtcbiAgY29uc3Qgcm93Q291bnQgPSBtYXAuaGVpZ2h0O1xuICBjb25zdCBjb2xDb3VudCA9IG1hcC53aWR0aDtcbiAgZm9yIChsZXQgcm93SW5kZXggPSAwOyByb3dJbmRleCA8IHJvd0NvdW50OyByb3dJbmRleCsrKSB7XG4gICAgY29uc3Qgcm93OiAoTm9kZSB8IG51bGwpW10gPSBbXTtcbiAgICBmb3IgKGxldCBjb2xJbmRleCA9IDA7IGNvbEluZGV4IDwgY29sQ291bnQ7IGNvbEluZGV4KyspIHtcbiAgICAgIGNvbnN0IGNlbGxJbmRleCA9IHJvd0luZGV4ICogY29sQ291bnQgKyBjb2xJbmRleDtcbiAgICAgIGNvbnN0IGNlbGxQb3MgPSBtYXAubWFwW2NlbGxJbmRleF07XG4gICAgICBpZiAocm93SW5kZXggPiAwKSB7XG4gICAgICAgIGNvbnN0IHRvcENlbGxJbmRleCA9IGNlbGxJbmRleCAtIGNvbENvdW50O1xuICAgICAgICBjb25zdCB0b3BDZWxsUG9zID0gbWFwLm1hcFt0b3BDZWxsSW5kZXhdO1xuICAgICAgICBpZiAoY2VsbFBvcyA9PT0gdG9wQ2VsbFBvcykge1xuICAgICAgICAgIHJvdy5wdXNoKG51bGwpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoY29sSW5kZXggPiAwKSB7XG4gICAgICAgIGNvbnN0IGxlZnRDZWxsSW5kZXggPSBjZWxsSW5kZXggLSAxO1xuICAgICAgICBjb25zdCBsZWZ0Q2VsbFBvcyA9IG1hcC5tYXBbbGVmdENlbGxJbmRleF07XG4gICAgICAgIGlmIChjZWxsUG9zID09PSBsZWZ0Q2VsbFBvcykge1xuICAgICAgICAgIHJvdy5wdXNoKG51bGwpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByb3cucHVzaCh0YWJsZU5vZGUubm9kZUF0KGNlbGxQb3MpKTtcbiAgICB9XG4gICAgcm93cy5wdXNoKHJvdyk7XG4gIH1cblxuICByZXR1cm4gcm93cztcbn1cblxuLyoqXG4gKiBDb252ZXJ0IGFuIGFycmF5IG9mIHJvd3MgdG8gYSB0YWJsZSBub2RlLlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydEFycmF5T2ZSb3dzVG9UYWJsZU5vZGUoXG4gIHRhYmxlTm9kZTogTm9kZSxcbiAgYXJyYXlPZk5vZGVzOiAoTm9kZSB8IG51bGwpW11bXSxcbik6IE5vZGUge1xuICBjb25zdCBuZXdSb3dzOiBOb2RlW10gPSBbXTtcbiAgY29uc3QgbWFwID0gVGFibGVNYXAuZ2V0KHRhYmxlTm9kZSk7XG4gIGNvbnN0IHJvd0NvdW50ID0gbWFwLmhlaWdodDtcbiAgY29uc3QgY29sQ291bnQgPSBtYXAud2lkdGg7XG4gIGZvciAobGV0IHJvd0luZGV4ID0gMDsgcm93SW5kZXggPCByb3dDb3VudDsgcm93SW5kZXgrKykge1xuICAgIGNvbnN0IG9sZFJvdzogTm9kZSA9IHRhYmxlTm9kZS5jaGlsZChyb3dJbmRleCk7XG4gICAgY29uc3QgbmV3Q2VsbHM6IE5vZGVbXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgY29sSW5kZXggPSAwOyBjb2xJbmRleCA8IGNvbENvdW50OyBjb2xJbmRleCsrKSB7XG4gICAgICBjb25zdCBjZWxsID0gYXJyYXlPZk5vZGVzW3Jvd0luZGV4XVtjb2xJbmRleF07XG4gICAgICBpZiAoIWNlbGwpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNlbGxQb3MgPSBtYXAubWFwW3Jvd0luZGV4ICogbWFwLndpZHRoICsgY29sSW5kZXhdO1xuICAgICAgY29uc3Qgb2xkQ2VsbCA9IHRhYmxlTm9kZS5ub2RlQXQoY2VsbFBvcyk7XG4gICAgICBpZiAoIW9sZENlbGwpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5ld0NlbGwgPSBvbGRDZWxsLnR5cGUuY3JlYXRlQ2hlY2tlZChcbiAgICAgICAgY2VsbC5hdHRycyxcbiAgICAgICAgY2VsbC5jb250ZW50LFxuICAgICAgICBjZWxsLm1hcmtzLFxuICAgICAgKTtcbiAgICAgIG5ld0NlbGxzLnB1c2gobmV3Q2VsbCk7XG4gICAgfVxuXG4gICAgY29uc3QgbmV3Um93ID0gb2xkUm93LnR5cGUuY3JlYXRlQ2hlY2tlZChcbiAgICAgIG9sZFJvdy5hdHRycyxcbiAgICAgIG5ld0NlbGxzLFxuICAgICAgb2xkUm93Lm1hcmtzLFxuICAgICk7XG4gICAgbmV3Um93cy5wdXNoKG5ld1Jvdyk7XG4gIH1cblxuICBjb25zdCBuZXdUYWJsZSA9IHRhYmxlTm9kZS50eXBlLmNyZWF0ZUNoZWNrZWQoXG4gICAgdGFibGVOb2RlLmF0dHJzLFxuICAgIG5ld1Jvd3MsXG4gICAgdGFibGVOb2RlLm1hcmtzLFxuICApO1xuICByZXR1cm4gbmV3VGFibGU7XG59XG4iLCAiLyoqXG4gKiBNb3ZlIGEgcm93IGluIGFuIGFycmF5IG9mIHJvd3MuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb3ZlUm93SW5BcnJheU9mUm93czxUPihcbiAgcm93czogVFtdLFxuICBpbmRleGVzT3JpZ2luOiBudW1iZXJbXSxcbiAgaW5kZXhlc1RhcmdldDogbnVtYmVyW10sXG4gIGRpcmVjdGlvbk92ZXJyaWRlOiAtMSB8IDEgfCAwLFxuKTogVFtdIHtcbiAgY29uc3QgZGlyZWN0aW9uID0gaW5kZXhlc09yaWdpblswXSA+IGluZGV4ZXNUYXJnZXRbMF0gPyAtMSA6IDE7XG5cbiAgY29uc3Qgcm93c0V4dHJhY3RlZCA9IHJvd3Muc3BsaWNlKGluZGV4ZXNPcmlnaW5bMF0sIGluZGV4ZXNPcmlnaW4ubGVuZ3RoKTtcbiAgY29uc3QgcG9zaXRpb25PZmZzZXQgPSByb3dzRXh0cmFjdGVkLmxlbmd0aCAlIDIgPT09IDAgPyAxIDogMDtcbiAgbGV0IHRhcmdldDogbnVtYmVyO1xuXG4gIGlmIChkaXJlY3Rpb25PdmVycmlkZSA9PT0gLTEgJiYgZGlyZWN0aW9uID09PSAxKSB7XG4gICAgdGFyZ2V0ID0gaW5kZXhlc1RhcmdldFswXSAtIDE7XG4gIH0gZWxzZSBpZiAoZGlyZWN0aW9uT3ZlcnJpZGUgPT09IDEgJiYgZGlyZWN0aW9uID09PSAtMSkge1xuICAgIHRhcmdldCA9IGluZGV4ZXNUYXJnZXRbaW5kZXhlc1RhcmdldC5sZW5ndGggLSAxXSAtIHBvc2l0aW9uT2Zmc2V0ICsgMTtcbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQgPVxuICAgICAgZGlyZWN0aW9uID09PSAtMVxuICAgICAgICA/IGluZGV4ZXNUYXJnZXRbMF1cbiAgICAgICAgOiBpbmRleGVzVGFyZ2V0W2luZGV4ZXNUYXJnZXQubGVuZ3RoIC0gMV0gLSBwb3NpdGlvbk9mZnNldDtcbiAgfVxuXG4gIHJvd3Muc3BsaWNlKHRhcmdldCwgMCwgLi4ucm93c0V4dHJhY3RlZCk7XG4gIHJldHVybiByb3dzO1xufVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZSwgUmVzb2x2ZWRQb3MgfSBmcm9tICdwcm9zZW1pcnJvci1tb2RlbCc7XG5pbXBvcnQgdHlwZSB7IFNlbGVjdGlvbiB9IGZyb20gJ3Byb3NlbWlycm9yLXN0YXRlJztcblxuaW1wb3J0IHsgQ2VsbFNlbGVjdGlvbiB9IGZyb20gJy4uL2NlbGxzZWxlY3Rpb24nO1xuaW1wb3J0IHsgY2VsbEFyb3VuZCwgY2VsbE5lYXIsIGluU2FtZVRhYmxlIH0gZnJvbSAnLi4vdXRpbCc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBvYmplY3QgaXMgYSBgQ2VsbFNlbGVjdGlvbmAgaW5zdGFuY2UuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIGlzQ2VsbFNlbGVjdGlvbih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIENlbGxTZWxlY3Rpb24ge1xuICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBDZWxsU2VsZWN0aW9uO1xufVxuXG4vKipcbiAqIEZpbmQgdGhlIGNsb3Nlc3QgdGFibGUgbm9kZSBmb3IgYSBnaXZlbiBwb3NpdGlvbi5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kVGFibGUoJHBvczogUmVzb2x2ZWRQb3MpOiBGaW5kTm9kZVJlc3VsdCB8IG51bGwge1xuICByZXR1cm4gZmluZFBhcmVudE5vZGUoKG5vZGUpID0+IG5vZGUudHlwZS5zcGVjLnRhYmxlUm9sZSA9PT0gJ3RhYmxlJywgJHBvcyk7XG59XG5cbi8qKlxuICogVHJ5IHRvIGZpbmQgdGhlIGFuY2hvciBhbmQgaGVhZCBjZWxsIGluIHRoZSBzYW1lIHRhYmxlIGJ5IHVzaW5nIHRoZSBnaXZlblxuICogYW5jaG9yIGFuZCBoZWFkIGFzIGhpdCBwb2ludHMsIG9yIGZhbGxiYWNrIHRvIHRoZSBzZWxlY3Rpb24ncyBhbmNob3IgYW5kXG4gKiBoZWFkLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRDZWxsUmFuZ2UoXG4gIHNlbGVjdGlvbjogU2VsZWN0aW9uLFxuICBhbmNob3JIaXQ/OiBudW1iZXIsXG4gIGhlYWRIaXQ/OiBudW1iZXIsXG4pOiBbUmVzb2x2ZWRQb3MsIFJlc29sdmVkUG9zXSB8IG51bGwge1xuICBpZiAoYW5jaG9ySGl0ID09IG51bGwgJiYgaGVhZEhpdCA9PSBudWxsICYmIGlzQ2VsbFNlbGVjdGlvbihzZWxlY3Rpb24pKSB7XG4gICAgcmV0dXJuIFtzZWxlY3Rpb24uJGFuY2hvckNlbGwsIHNlbGVjdGlvbi4kaGVhZENlbGxdO1xuICB9XG5cbiAgY29uc3QgYW5jaG9yOiBudW1iZXIgPSBhbmNob3JIaXQgPz8gaGVhZEhpdCA/PyBzZWxlY3Rpb24uYW5jaG9yO1xuICBjb25zdCBoZWFkOiBudW1iZXIgPSBoZWFkSGl0ID8/IGFuY2hvckhpdCA/PyBzZWxlY3Rpb24uaGVhZDtcblxuICBjb25zdCBkb2MgPSBzZWxlY3Rpb24uJGhlYWQuZG9jO1xuXG4gIGNvbnN0ICRhbmNob3JDZWxsID0gZmluZENlbGxQb3MoZG9jLCBhbmNob3IpO1xuICBjb25zdCAkaGVhZENlbGwgPSBmaW5kQ2VsbFBvcyhkb2MsIGhlYWQpO1xuXG4gIGlmICgkYW5jaG9yQ2VsbCAmJiAkaGVhZENlbGwgJiYgaW5TYW1lVGFibGUoJGFuY2hvckNlbGwsICRoZWFkQ2VsbCkpIHtcbiAgICByZXR1cm4gWyRhbmNob3JDZWxsLCAkaGVhZENlbGxdO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFRyeSB0byBmaW5kIGEgcmVzb2x2ZWQgcG9zIG9mIGEgY2VsbCBieSB1c2luZyB0aGUgZ2l2ZW4gcG9zIGFzIGEgaGl0IHBvaW50LlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRDZWxsUG9zKGRvYzogTm9kZSwgcG9zOiBudW1iZXIpOiBSZXNvbHZlZFBvcyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0ICRwb3MgPSBkb2MucmVzb2x2ZShwb3MpO1xuICByZXR1cm4gY2VsbEFyb3VuZCgkcG9zKSB8fCBjZWxsTmVhcigkcG9zKTtcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgZmluZGluZyBhIHBhcmVudCBub2RlLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBGaW5kTm9kZVJlc3VsdCB7XG4gIC8qKlxuICAgKiBUaGUgY2xvc2VzdCBwYXJlbnQgbm9kZSB0aGF0IHNhdGlzZmllcyB0aGUgcHJlZGljYXRlLlxuICAgKi9cbiAgbm9kZTogTm9kZTtcblxuICAvKipcbiAgICogVGhlIHBvc2l0aW9uIGRpcmVjdGx5IGJlZm9yZSB0aGUgbm9kZS5cbiAgICovXG4gIHBvczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgcG9zaXRpb24gYXQgdGhlIHN0YXJ0IG9mIHRoZSBub2RlLlxuICAgKi9cbiAgc3RhcnQ6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGRlcHRoIG9mIHRoZSBub2RlLlxuICAgKi9cbiAgZGVwdGg6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBjbG9zZXN0IHBhcmVudCBub2RlIHRoYXQgc2F0aXNmaWVzIHRoZSBwcmVkaWNhdGUuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmZ1bmN0aW9uIGZpbmRQYXJlbnROb2RlKFxuICAvKipcbiAgICogVGhlIHByZWRpY2F0ZSB0byB0ZXN0IHRoZSBwYXJlbnQgbm9kZS5cbiAgICovXG4gIHByZWRpY2F0ZTogKG5vZGU6IE5vZGUpID0+IGJvb2xlYW4sXG4gIC8qKlxuICAgKiBUaGUgcG9zaXRpb24gdG8gc3RhcnQgc2VhcmNoaW5nIGZyb20uXG4gICAqL1xuICAkcG9zOiBSZXNvbHZlZFBvcyxcbik6IEZpbmROb2RlUmVzdWx0IHwgbnVsbCB7XG4gIGZvciAobGV0IGRlcHRoID0gJHBvcy5kZXB0aDsgZGVwdGggPj0gMDsgZGVwdGggLT0gMSkge1xuICAgIGNvbnN0IG5vZGUgPSAkcG9zLm5vZGUoZGVwdGgpO1xuXG4gICAgaWYgKHByZWRpY2F0ZShub2RlKSkge1xuICAgICAgY29uc3QgcG9zID0gZGVwdGggPT09IDAgPyAwIDogJHBvcy5iZWZvcmUoZGVwdGgpO1xuICAgICAgY29uc3Qgc3RhcnQgPSAkcG9zLnN0YXJ0KGRlcHRoKTtcbiAgICAgIHJldHVybiB7IG5vZGUsIHBvcywgc3RhcnQsIGRlcHRoIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBTZWxlY3Rpb24gfSBmcm9tICdwcm9zZW1pcnJvci1zdGF0ZSc7XG5cbmltcG9ydCB7IFRhYmxlTWFwIH0gZnJvbSAnLi4vdGFibGVtYXAnO1xuXG5pbXBvcnQgdHlwZSB7IEZpbmROb2RlUmVzdWx0IH0gZnJvbSAnLi9xdWVyeSc7XG5pbXBvcnQgeyBmaW5kVGFibGUgfSBmcm9tICcuL3F1ZXJ5JztcblxuLyoqXG4gKiBSZXR1cm5zIGFuIGFycmF5IG9mIGNlbGxzIGluIGEgY29sdW1uIGF0IHRoZSBzcGVjaWZpZWQgY29sdW1uIGluZGV4LlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2VsbHNJbkNvbHVtbihcbiAgY29sdW1uSW5kZXg6IG51bWJlcixcbiAgc2VsZWN0aW9uOiBTZWxlY3Rpb24sXG4pOiBGaW5kTm9kZVJlc3VsdFtdIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgdGFibGUgPSBmaW5kVGFibGUoc2VsZWN0aW9uLiRmcm9tKTtcbiAgaWYgKCF0YWJsZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IG1hcCA9IFRhYmxlTWFwLmdldCh0YWJsZS5ub2RlKTtcblxuICBpZiAoY29sdW1uSW5kZXggPCAwIHx8IGNvbHVtbkluZGV4ID4gbWFwLndpZHRoIC0gMSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGNlbGxzID0gbWFwLmNlbGxzSW5SZWN0KHtcbiAgICBsZWZ0OiBjb2x1bW5JbmRleCxcbiAgICByaWdodDogY29sdW1uSW5kZXggKyAxLFxuICAgIHRvcDogMCxcbiAgICBib3R0b206IG1hcC5oZWlnaHQsXG4gIH0pO1xuXG4gIHJldHVybiBjZWxscy5tYXAoKG5vZGVQb3MpID0+IHtcbiAgICBjb25zdCBub2RlID0gdGFibGUubm9kZS5ub2RlQXQobm9kZVBvcykhO1xuICAgIGNvbnN0IHBvcyA9IG5vZGVQb3MgKyB0YWJsZS5zdGFydDtcbiAgICByZXR1cm4geyBwb3MsIHN0YXJ0OiBwb3MgKyAxLCBub2RlLCBkZXB0aDogdGFibGUuZGVwdGggKyAyIH07XG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgYW4gYXJyYXkgb2YgY2VsbHMgaW4gYSByb3cgYXQgdGhlIHNwZWNpZmllZCByb3cgaW5kZXguXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDZWxsc0luUm93KFxuICByb3dJbmRleDogbnVtYmVyLFxuICBzZWxlY3Rpb246IFNlbGVjdGlvbixcbik6IEZpbmROb2RlUmVzdWx0W10gfCB1bmRlZmluZWQge1xuICBjb25zdCB0YWJsZSA9IGZpbmRUYWJsZShzZWxlY3Rpb24uJGZyb20pO1xuICBpZiAoIXRhYmxlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgbWFwID0gVGFibGVNYXAuZ2V0KHRhYmxlLm5vZGUpO1xuXG4gIGlmIChyb3dJbmRleCA8IDAgfHwgcm93SW5kZXggPiBtYXAuaGVpZ2h0IC0gMSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGNlbGxzID0gbWFwLmNlbGxzSW5SZWN0KHtcbiAgICBsZWZ0OiAwLFxuICAgIHJpZ2h0OiBtYXAud2lkdGgsXG4gICAgdG9wOiByb3dJbmRleCxcbiAgICBib3R0b206IHJvd0luZGV4ICsgMSxcbiAgfSk7XG5cbiAgcmV0dXJuIGNlbGxzLm1hcCgobm9kZVBvcykgPT4ge1xuICAgIGNvbnN0IG5vZGUgPSB0YWJsZS5ub2RlLm5vZGVBdChub2RlUG9zKSE7XG4gICAgY29uc3QgcG9zID0gbm9kZVBvcyArIHRhYmxlLnN0YXJ0O1xuICAgIHJldHVybiB7IHBvcywgc3RhcnQ6IHBvcyArIDEsIG5vZGUsIGRlcHRoOiB0YWJsZS5kZXB0aCArIDIgfTtcbiAgfSk7XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBSZXNvbHZlZFBvcyB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB0eXBlIHsgVHJhbnNhY3Rpb24gfSBmcm9tICdwcm9zZW1pcnJvci1zdGF0ZSc7XG5cbmltcG9ydCB7IGdldENlbGxzSW5Db2x1bW4sIGdldENlbGxzSW5Sb3cgfSBmcm9tICcuL2dldC1jZWxscyc7XG5cbmV4cG9ydCB0eXBlIENlbGxTZWxlY3Rpb25SYW5nZSA9IHtcbiAgJGFuY2hvcjogUmVzb2x2ZWRQb3M7XG4gICRoZWFkOiBSZXNvbHZlZFBvcztcbiAgLy8gYW4gYXJyYXkgb2YgY29sdW1uL3JvdyBpbmRleGVzXG4gIGluZGV4ZXM6IG51bWJlcltdO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgcmFuZ2Ugb2YgcmVjdGFuZ3VsYXIgc2VsZWN0aW9uIHNwYW5uaW5nIGFsbCBtZXJnZWQgY2VsbHMgYXJvdW5kIGFcbiAqIGNvbHVtbiBhdCBpbmRleCBgY29sdW1uSW5kZXhgLlxuICpcbiAqIE9yaWdpbmFsIGltcGxlbWVudGF0aW9uIGZyb20gQXRsYXNzaWFuIChBcGFjaGUgTGljZW5zZSAyLjApXG4gKlxuICogaHR0cHM6Ly9iaXRidWNrZXQub3JnL2F0bGFzc2lhbi9hdGxhc3NpYW4tZnJvbnRlbmQtbWlycm9yL3NyYy81ZjkxY2I4NzFlODI0OGJjM2JhZTVkZGMzMGJiOWZkOTIwMGZhZGJiL2VkaXRvci9lZGl0b3ItdGFibGVzL3NyYy91dGlscy9nZXQtc2VsZWN0aW9uLXJhbmdlLWluLWNvbHVtbi50cyNlZGl0b3IvZWRpdG9yLXRhYmxlcy9zcmMvdXRpbHMvZ2V0LXNlbGVjdGlvbi1yYW5nZS1pbi1jb2x1bW4udHNcbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNlbGVjdGlvblJhbmdlSW5Db2x1bW4oXG4gIHRyOiBUcmFuc2FjdGlvbixcbiAgc3RhcnRDb2xJbmRleDogbnVtYmVyLFxuICBlbmRDb2xJbmRleDogbnVtYmVyID0gc3RhcnRDb2xJbmRleCxcbik6IENlbGxTZWxlY3Rpb25SYW5nZSB8IHVuZGVmaW5lZCB7XG4gIGxldCBzdGFydEluZGV4ID0gc3RhcnRDb2xJbmRleDtcbiAgbGV0IGVuZEluZGV4ID0gZW5kQ29sSW5kZXg7XG5cbiAgLy8gbG9va2luZyBmb3Igc2VsZWN0aW9uIHN0YXJ0IGNvbHVtbiAoc3RhcnRJbmRleClcbiAgZm9yIChsZXQgaSA9IHN0YXJ0Q29sSW5kZXg7IGkgPj0gMDsgaS0tKSB7XG4gICAgY29uc3QgY2VsbHMgPSBnZXRDZWxsc0luQ29sdW1uKGksIHRyLnNlbGVjdGlvbik7XG4gICAgaWYgKGNlbGxzKSB7XG4gICAgICBjZWxscy5mb3JFYWNoKChjZWxsKSA9PiB7XG4gICAgICAgIGNvbnN0IG1heWJlRW5kSW5kZXggPSBjZWxsLm5vZGUuYXR0cnMuY29sc3BhbiArIGkgLSAxO1xuICAgICAgICBpZiAobWF5YmVFbmRJbmRleCA+PSBzdGFydEluZGV4KSB7XG4gICAgICAgICAgc3RhcnRJbmRleCA9IGk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1heWJlRW5kSW5kZXggPiBlbmRJbmRleCkge1xuICAgICAgICAgIGVuZEluZGV4ID0gbWF5YmVFbmRJbmRleDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIC8vIGxvb2tpbmcgZm9yIHNlbGVjdGlvbiBlbmQgY29sdW1uIChlbmRJbmRleClcbiAgZm9yIChsZXQgaSA9IHN0YXJ0Q29sSW5kZXg7IGkgPD0gZW5kSW5kZXg7IGkrKykge1xuICAgIGNvbnN0IGNlbGxzID0gZ2V0Q2VsbHNJbkNvbHVtbihpLCB0ci5zZWxlY3Rpb24pO1xuICAgIGlmIChjZWxscykge1xuICAgICAgY2VsbHMuZm9yRWFjaCgoY2VsbCkgPT4ge1xuICAgICAgICBjb25zdCBtYXliZUVuZEluZGV4ID0gY2VsbC5ub2RlLmF0dHJzLmNvbHNwYW4gKyBpIC0gMTtcbiAgICAgICAgaWYgKGNlbGwubm9kZS5hdHRycy5jb2xzcGFuID4gMSAmJiBtYXliZUVuZEluZGV4ID4gZW5kSW5kZXgpIHtcbiAgICAgICAgICBlbmRJbmRleCA9IG1heWJlRW5kSW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIGZpbHRlciBvdXQgY29sdW1ucyB3aXRob3V0IGNlbGxzICh3aGVyZSBhbGwgcm93cyBoYXZlIGNvbHNwYW4gPiAxIGluIHRoZSBzYW1lIGNvbHVtbilcbiAgY29uc3QgaW5kZXhlcyA9IFtdO1xuICBmb3IgKGxldCBpID0gc3RhcnRJbmRleDsgaSA8PSBlbmRJbmRleDsgaSsrKSB7XG4gICAgY29uc3QgbWF5YmVDZWxscyA9IGdldENlbGxzSW5Db2x1bW4oaSwgdHIuc2VsZWN0aW9uKTtcbiAgICBpZiAobWF5YmVDZWxscyAmJiBtYXliZUNlbGxzLmxlbmd0aCA+IDApIHtcbiAgICAgIGluZGV4ZXMucHVzaChpKTtcbiAgICB9XG4gIH1cbiAgc3RhcnRJbmRleCA9IGluZGV4ZXNbMF07XG4gIGVuZEluZGV4ID0gaW5kZXhlc1tpbmRleGVzLmxlbmd0aCAtIDFdO1xuXG4gIGNvbnN0IGZpcnN0U2VsZWN0ZWRDb2x1bW5DZWxscyA9IGdldENlbGxzSW5Db2x1bW4oc3RhcnRJbmRleCwgdHIuc2VsZWN0aW9uKTtcbiAgY29uc3QgZmlyc3RSb3dDZWxscyA9IGdldENlbGxzSW5Sb3coMCwgdHIuc2VsZWN0aW9uKTtcbiAgaWYgKCFmaXJzdFNlbGVjdGVkQ29sdW1uQ2VsbHMgfHwgIWZpcnN0Um93Q2VsbHMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCAkYW5jaG9yID0gdHIuZG9jLnJlc29sdmUoXG4gICAgZmlyc3RTZWxlY3RlZENvbHVtbkNlbGxzW2ZpcnN0U2VsZWN0ZWRDb2x1bW5DZWxscy5sZW5ndGggLSAxXS5wb3MsXG4gICk7XG5cbiAgbGV0IGhlYWRDZWxsO1xuICBmb3IgKGxldCBpID0gZW5kSW5kZXg7IGkgPj0gc3RhcnRJbmRleDsgaS0tKSB7XG4gICAgY29uc3QgY29sdW1uQ2VsbHMgPSBnZXRDZWxsc0luQ29sdW1uKGksIHRyLnNlbGVjdGlvbik7XG4gICAgaWYgKGNvbHVtbkNlbGxzICYmIGNvbHVtbkNlbGxzLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAobGV0IGogPSBmaXJzdFJvd0NlbGxzLmxlbmd0aCAtIDE7IGogPj0gMDsgai0tKSB7XG4gICAgICAgIGlmIChmaXJzdFJvd0NlbGxzW2pdLnBvcyA9PT0gY29sdW1uQ2VsbHNbMF0ucG9zKSB7XG4gICAgICAgICAgaGVhZENlbGwgPSBjb2x1bW5DZWxsc1swXTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGhlYWRDZWxsKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpZiAoIWhlYWRDZWxsKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgJGhlYWQgPSB0ci5kb2MucmVzb2x2ZShoZWFkQ2VsbC5wb3MpO1xuICByZXR1cm4geyAkYW5jaG9yLCAkaGVhZCwgaW5kZXhlcyB9O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSByYW5nZSBvZiByZWN0YW5ndWxhciBzZWxlY3Rpb24gc3Bhbm5pbmcgYWxsIG1lcmdlZCBjZWxscyBhcm91bmQgYVxuICogcm93IGF0IGluZGV4IGByb3dJbmRleGAuXG4gKlxuICogT3JpZ2luYWwgaW1wbGVtZW50YXRpb24gZnJvbSBBdGxhc3NpYW4gKEFwYWNoZSBMaWNlbnNlIDIuMClcbiAqXG4gKiBodHRwczovL2JpdGJ1Y2tldC5vcmcvYXRsYXNzaWFuL2F0bGFzc2lhbi1mcm9udGVuZC1taXJyb3Ivc3JjLzVmOTFjYjg3MWU4MjQ4YmMzYmFlNWRkYzMwYmI5ZmQ5MjAwZmFkYmIvZWRpdG9yL2VkaXRvci10YWJsZXMvc3JjL3V0aWxzL2dldC1zZWxlY3Rpb24tcmFuZ2UtaW4tcm93LnRzI2VkaXRvci9lZGl0b3ItdGFibGVzL3NyYy91dGlscy9nZXQtc2VsZWN0aW9uLXJhbmdlLWluLXJvdy50c1xuICpcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VsZWN0aW9uUmFuZ2VJblJvdyhcbiAgdHI6IFRyYW5zYWN0aW9uLFxuICBzdGFydFJvd0luZGV4OiBudW1iZXIsXG4gIGVuZFJvd0luZGV4OiBudW1iZXIgPSBzdGFydFJvd0luZGV4LFxuKTogQ2VsbFNlbGVjdGlvblJhbmdlIHwgdW5kZWZpbmVkIHtcbiAgbGV0IHN0YXJ0SW5kZXggPSBzdGFydFJvd0luZGV4O1xuICBsZXQgZW5kSW5kZXggPSBlbmRSb3dJbmRleDtcblxuICAvLyBsb29raW5nIGZvciBzZWxlY3Rpb24gc3RhcnQgcm93IChzdGFydEluZGV4KVxuICBmb3IgKGxldCBpID0gc3RhcnRSb3dJbmRleDsgaSA+PSAwOyBpLS0pIHtcbiAgICBjb25zdCBjZWxscyA9IGdldENlbGxzSW5Sb3coaSwgdHIuc2VsZWN0aW9uKTtcbiAgICBpZiAoY2VsbHMpIHtcbiAgICAgIGNlbGxzLmZvckVhY2goKGNlbGwpID0+IHtcbiAgICAgICAgY29uc3QgbWF5YmVFbmRJbmRleCA9IGNlbGwubm9kZS5hdHRycy5yb3dzcGFuICsgaSAtIDE7XG4gICAgICAgIGlmIChtYXliZUVuZEluZGV4ID49IHN0YXJ0SW5kZXgpIHtcbiAgICAgICAgICBzdGFydEluZGV4ID0gaTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWF5YmVFbmRJbmRleCA+IGVuZEluZGV4KSB7XG4gICAgICAgICAgZW5kSW5kZXggPSBtYXliZUVuZEluZGV4O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgLy8gbG9va2luZyBmb3Igc2VsZWN0aW9uIGVuZCByb3cgKGVuZEluZGV4KVxuICBmb3IgKGxldCBpID0gc3RhcnRSb3dJbmRleDsgaSA8PSBlbmRJbmRleDsgaSsrKSB7XG4gICAgY29uc3QgY2VsbHMgPSBnZXRDZWxsc0luUm93KGksIHRyLnNlbGVjdGlvbik7XG4gICAgaWYgKGNlbGxzKSB7XG4gICAgICBjZWxscy5mb3JFYWNoKChjZWxsKSA9PiB7XG4gICAgICAgIGNvbnN0IG1heWJlRW5kSW5kZXggPSBjZWxsLm5vZGUuYXR0cnMucm93c3BhbiArIGkgLSAxO1xuICAgICAgICBpZiAoY2VsbC5ub2RlLmF0dHJzLnJvd3NwYW4gPiAxICYmIG1heWJlRW5kSW5kZXggPiBlbmRJbmRleCkge1xuICAgICAgICAgIGVuZEluZGV4ID0gbWF5YmVFbmRJbmRleDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gZmlsdGVyIG91dCByb3dzIHdpdGhvdXQgY2VsbHMgKHdoZXJlIGFsbCBjb2x1bW5zIGhhdmUgcm93c3BhbiA+IDEgaW4gdGhlIHNhbWUgcm93KVxuICBjb25zdCBpbmRleGVzID0gW107XG4gIGZvciAobGV0IGkgPSBzdGFydEluZGV4OyBpIDw9IGVuZEluZGV4OyBpKyspIHtcbiAgICBjb25zdCBtYXliZUNlbGxzID0gZ2V0Q2VsbHNJblJvdyhpLCB0ci5zZWxlY3Rpb24pO1xuICAgIGlmIChtYXliZUNlbGxzICYmIG1heWJlQ2VsbHMubGVuZ3RoID4gMCkge1xuICAgICAgaW5kZXhlcy5wdXNoKGkpO1xuICAgIH1cbiAgfVxuICBzdGFydEluZGV4ID0gaW5kZXhlc1swXTtcbiAgZW5kSW5kZXggPSBpbmRleGVzW2luZGV4ZXMubGVuZ3RoIC0gMV07XG5cbiAgY29uc3QgZmlyc3RTZWxlY3RlZFJvd0NlbGxzID0gZ2V0Q2VsbHNJblJvdyhzdGFydEluZGV4LCB0ci5zZWxlY3Rpb24pO1xuICBjb25zdCBmaXJzdENvbHVtbkNlbGxzID0gZ2V0Q2VsbHNJbkNvbHVtbigwLCB0ci5zZWxlY3Rpb24pO1xuICBpZiAoIWZpcnN0U2VsZWN0ZWRSb3dDZWxscyB8fCAhZmlyc3RDb2x1bW5DZWxscykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0ICRhbmNob3IgPSB0ci5kb2MucmVzb2x2ZShcbiAgICBmaXJzdFNlbGVjdGVkUm93Q2VsbHNbZmlyc3RTZWxlY3RlZFJvd0NlbGxzLmxlbmd0aCAtIDFdLnBvcyxcbiAgKTtcblxuICBsZXQgaGVhZENlbGw7XG4gIGZvciAobGV0IGkgPSBlbmRJbmRleDsgaSA+PSBzdGFydEluZGV4OyBpLS0pIHtcbiAgICBjb25zdCByb3dDZWxscyA9IGdldENlbGxzSW5Sb3coaSwgdHIuc2VsZWN0aW9uKTtcbiAgICBpZiAocm93Q2VsbHMgJiYgcm93Q2VsbHMubGVuZ3RoID4gMCkge1xuICAgICAgZm9yIChsZXQgaiA9IGZpcnN0Q29sdW1uQ2VsbHMubGVuZ3RoIC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgICAgaWYgKGZpcnN0Q29sdW1uQ2VsbHNbal0ucG9zID09PSByb3dDZWxsc1swXS5wb3MpIHtcbiAgICAgICAgICBoZWFkQ2VsbCA9IHJvd0NlbGxzWzBdO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaGVhZENlbGwpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmICghaGVhZENlbGwpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCAkaGVhZCA9IHRyLmRvYy5yZXNvbHZlKGhlYWRDZWxsLnBvcyk7XG4gIHJldHVybiB7ICRhbmNob3IsICRoZWFkLCBpbmRleGVzIH07XG59XG4iLCAiLyoqXG4gKiBUcmFuc3Bvc2VzIGEgMkQgYXJyYXkgYnkgZmxpcHBpbmcgY29sdW1ucyB0byByb3dzLlxuICpcbiAqIFRyYW5zcG9zaXRpb24gaXMgYSBmYW1pbGlhciBhbGdlYnJhIGNvbmNlcHQgd2hlcmUgdGhlIG1hdHJpeCBpcyBmbGlwcGVkXG4gKiBhbG9uZyBpdHMgZGlhZ29uYWwuIEZvciBtb3JlIGRldGFpbHMsIHNlZTpcbiAqIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1RyYW5zcG9zZVxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiBjb25zdCBhcnIgPSBbXG4gKiAgIFsnYTEnLCAnYTInLCAnYTMnXSxcbiAqICAgWydiMScsICdiMicsICdiMyddLFxuICogICBbJ2MxJywgJ2MyJywgJ2MzJ10sXG4gKiAgIFsnZDEnLCAnZDInLCAnZDMnXSxcbiAqIF07XG4gKlxuICogY29uc3QgcmVzdWx0ID0gdHJhbnNwb3NlKGFycik7XG4gKiByZXN1bHQgPT09IFtcbiAqICAgWydhMScsICdiMScsICdjMScsICdkMSddLFxuICogICBbJ2EyJywgJ2IyJywgJ2MyJywgJ2QyJ10sXG4gKiAgIFsnYTMnLCAnYjMnLCAnYzMnLCAnZDMnXSxcbiAqIF1cbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNwb3NlPFQ+KGFycmF5OiBUW11bXSk6IFRbXVtdIHtcbiAgcmV0dXJuIGFycmF5WzBdLm1hcCgoXywgaSkgPT4ge1xuICAgIHJldHVybiBhcnJheS5tYXAoKGNvbHVtbikgPT4gY29sdW1uW2ldKTtcbiAgfSk7XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuaW1wb3J0IHR5cGUgeyBUcmFuc2FjdGlvbiB9IGZyb20gJ3Byb3NlbWlycm9yLXN0YXRlJztcblxuaW1wb3J0IHsgQ2VsbFNlbGVjdGlvbiB9IGZyb20gJy4uL2NlbGxzZWxlY3Rpb24nO1xuaW1wb3J0IHsgVGFibGVNYXAgfSBmcm9tICcuLi90YWJsZW1hcCc7XG5cbmltcG9ydCB7XG4gIGNvbnZlcnRBcnJheU9mUm93c1RvVGFibGVOb2RlLFxuICBjb252ZXJ0VGFibGVOb2RlVG9BcnJheU9mUm93cyxcbn0gZnJvbSAnLi9jb252ZXJ0JztcbmltcG9ydCB7IG1vdmVSb3dJbkFycmF5T2ZSb3dzIH0gZnJvbSAnLi9tb3ZlLXJvdy1pbi1hcnJheS1vZi1yb3dzJztcbmltcG9ydCB7IGZpbmRUYWJsZSB9IGZyb20gJy4vcXVlcnknO1xuaW1wb3J0IHsgZ2V0U2VsZWN0aW9uUmFuZ2VJbkNvbHVtbiB9IGZyb20gJy4vc2VsZWN0aW9uLXJhbmdlJztcbmltcG9ydCB7IHRyYW5zcG9zZSB9IGZyb20gJy4vdHJhbnNwb3NlJztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciBtb3ZpbmcgYSBjb2x1bW4gaW4gYSB0YWJsZS5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb3ZlQ29sdW1uUGFyYW1zIHtcbiAgdHI6IFRyYW5zYWN0aW9uO1xuICBvcmlnaW5JbmRleDogbnVtYmVyO1xuICB0YXJnZXRJbmRleDogbnVtYmVyO1xuICBzZWxlY3Q6IGJvb2xlYW47XG4gIHBvczogbnVtYmVyO1xufVxuXG4vKipcbiAqIE1vdmUgYSBjb2x1bW4gZnJvbSBpbmRleCBgb3JpZ2luYCB0byBpbmRleCBgdGFyZ2V0YC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vdmVDb2x1bW4obW92ZUNvbFBhcmFtczogTW92ZUNvbHVtblBhcmFtcyk6IGJvb2xlYW4ge1xuICBjb25zdCB7IHRyLCBvcmlnaW5JbmRleCwgdGFyZ2V0SW5kZXgsIHNlbGVjdCwgcG9zIH0gPSBtb3ZlQ29sUGFyYW1zO1xuICBjb25zdCAkcG9zID0gdHIuZG9jLnJlc29sdmUocG9zKTtcbiAgY29uc3QgdGFibGUgPSBmaW5kVGFibGUoJHBvcyk7XG4gIGlmICghdGFibGUpIHJldHVybiBmYWxzZTtcblxuICBjb25zdCBpbmRleGVzT3JpZ2luQ29sdW1uID0gZ2V0U2VsZWN0aW9uUmFuZ2VJbkNvbHVtbihcbiAgICB0cixcbiAgICBvcmlnaW5JbmRleCxcbiAgKT8uaW5kZXhlcztcbiAgY29uc3QgaW5kZXhlc1RhcmdldENvbHVtbiA9IGdldFNlbGVjdGlvblJhbmdlSW5Db2x1bW4oXG4gICAgdHIsXG4gICAgdGFyZ2V0SW5kZXgsXG4gICk/LmluZGV4ZXM7XG5cbiAgaWYgKCFpbmRleGVzT3JpZ2luQ29sdW1uIHx8ICFpbmRleGVzVGFyZ2V0Q29sdW1uKSByZXR1cm4gZmFsc2U7XG5cbiAgaWYgKGluZGV4ZXNPcmlnaW5Db2x1bW4uaW5jbHVkZXModGFyZ2V0SW5kZXgpKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3QgbmV3VGFibGUgPSBtb3ZlVGFibGVDb2x1bW4oXG4gICAgdGFibGUubm9kZSxcbiAgICBpbmRleGVzT3JpZ2luQ29sdW1uLFxuICAgIGluZGV4ZXNUYXJnZXRDb2x1bW4sXG4gICAgMCxcbiAgKTtcblxuICB0ci5yZXBsYWNlV2l0aCh0YWJsZS5wb3MsIHRhYmxlLnBvcyArIHRhYmxlLm5vZGUubm9kZVNpemUsIG5ld1RhYmxlKTtcblxuICBpZiAoIXNlbGVjdCkgcmV0dXJuIHRydWU7XG5cbiAgY29uc3QgbWFwID0gVGFibGVNYXAuZ2V0KG5ld1RhYmxlKTtcbiAgY29uc3Qgc3RhcnQgPSB0YWJsZS5zdGFydDtcbiAgY29uc3QgaW5kZXggPSB0YXJnZXRJbmRleDtcbiAgY29uc3QgbGFzdENlbGwgPSBtYXAucG9zaXRpb25BdChtYXAuaGVpZ2h0IC0gMSwgaW5kZXgsIG5ld1RhYmxlKTtcbiAgY29uc3QgJGxhc3RDZWxsID0gdHIuZG9jLnJlc29sdmUoc3RhcnQgKyBsYXN0Q2VsbCk7XG5cbiAgY29uc3QgZmlyc3RDZWxsID0gbWFwLnBvc2l0aW9uQXQoMCwgaW5kZXgsIG5ld1RhYmxlKTtcbiAgY29uc3QgJGZpcnN0Q2VsbCA9IHRyLmRvYy5yZXNvbHZlKHN0YXJ0ICsgZmlyc3RDZWxsKTtcblxuICB0ci5zZXRTZWxlY3Rpb24oQ2VsbFNlbGVjdGlvbi5jb2xTZWxlY3Rpb24oJGxhc3RDZWxsLCAkZmlyc3RDZWxsKSk7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBtb3ZlVGFibGVDb2x1bW4oXG4gIHRhYmxlOiBOb2RlLFxuICBpbmRleGVzT3JpZ2luOiBudW1iZXJbXSxcbiAgaW5kZXhlc1RhcmdldDogbnVtYmVyW10sXG4gIGRpcmVjdGlvbjogLTEgfCAxIHwgMCxcbikge1xuICBsZXQgcm93cyA9IHRyYW5zcG9zZShjb252ZXJ0VGFibGVOb2RlVG9BcnJheU9mUm93cyh0YWJsZSkpO1xuXG4gIHJvd3MgPSBtb3ZlUm93SW5BcnJheU9mUm93cyhyb3dzLCBpbmRleGVzT3JpZ2luLCBpbmRleGVzVGFyZ2V0LCBkaXJlY3Rpb24pO1xuICByb3dzID0gdHJhbnNwb3NlKHJvd3MpO1xuXG4gIHJldHVybiBjb252ZXJ0QXJyYXlPZlJvd3NUb1RhYmxlTm9kZSh0YWJsZSwgcm93cyk7XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuaW1wb3J0IHR5cGUgeyBUcmFuc2FjdGlvbiB9IGZyb20gJ3Byb3NlbWlycm9yLXN0YXRlJztcblxuaW1wb3J0IHsgQ2VsbFNlbGVjdGlvbiB9IGZyb20gJy4uL2NlbGxzZWxlY3Rpb24nO1xuaW1wb3J0IHsgVGFibGVNYXAgfSBmcm9tICcuLi90YWJsZW1hcCc7XG5cbmltcG9ydCB7XG4gIGNvbnZlcnRBcnJheU9mUm93c1RvVGFibGVOb2RlLFxuICBjb252ZXJ0VGFibGVOb2RlVG9BcnJheU9mUm93cyxcbn0gZnJvbSAnLi9jb252ZXJ0JztcbmltcG9ydCB7IG1vdmVSb3dJbkFycmF5T2ZSb3dzIH0gZnJvbSAnLi9tb3ZlLXJvdy1pbi1hcnJheS1vZi1yb3dzJztcbmltcG9ydCB7IGZpbmRUYWJsZSB9IGZyb20gJy4vcXVlcnknO1xuaW1wb3J0IHsgZ2V0U2VsZWN0aW9uUmFuZ2VJblJvdyB9IGZyb20gJy4vc2VsZWN0aW9uLXJhbmdlJztcblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciBtb3ZpbmcgYSByb3cgaW4gYSB0YWJsZS5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNb3ZlUm93UGFyYW1zIHtcbiAgdHI6IFRyYW5zYWN0aW9uO1xuICBvcmlnaW5JbmRleDogbnVtYmVyO1xuICB0YXJnZXRJbmRleDogbnVtYmVyO1xuICBzZWxlY3Q6IGJvb2xlYW47XG4gIHBvczogbnVtYmVyO1xufVxuXG4vKipcbiAqIE1vdmUgYSByb3cgZnJvbSBpbmRleCBgb3JpZ2luYCB0byBpbmRleCBgdGFyZ2V0YC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vdmVSb3cobW92ZVJvd1BhcmFtczogTW92ZVJvd1BhcmFtcyk6IGJvb2xlYW4ge1xuICBjb25zdCB7IHRyLCBvcmlnaW5JbmRleCwgdGFyZ2V0SW5kZXgsIHNlbGVjdCwgcG9zIH0gPSBtb3ZlUm93UGFyYW1zO1xuICBjb25zdCAkcG9zID0gdHIuZG9jLnJlc29sdmUocG9zKTtcbiAgY29uc3QgdGFibGUgPSBmaW5kVGFibGUoJHBvcyk7XG4gIGlmICghdGFibGUpIHJldHVybiBmYWxzZTtcblxuICBjb25zdCBpbmRleGVzT3JpZ2luUm93ID0gZ2V0U2VsZWN0aW9uUmFuZ2VJblJvdyh0ciwgb3JpZ2luSW5kZXgpPy5pbmRleGVzO1xuICBjb25zdCBpbmRleGVzVGFyZ2V0Um93ID0gZ2V0U2VsZWN0aW9uUmFuZ2VJblJvdyh0ciwgdGFyZ2V0SW5kZXgpPy5pbmRleGVzO1xuXG4gIGlmICghaW5kZXhlc09yaWdpblJvdyB8fCAhaW5kZXhlc1RhcmdldFJvdykgcmV0dXJuIGZhbHNlO1xuXG4gIGlmIChpbmRleGVzT3JpZ2luUm93LmluY2x1ZGVzKHRhcmdldEluZGV4KSkgcmV0dXJuIGZhbHNlO1xuXG4gIGNvbnN0IG5ld1RhYmxlID0gbW92ZVRhYmxlUm93KFxuICAgIHRhYmxlLm5vZGUsXG4gICAgaW5kZXhlc09yaWdpblJvdyxcbiAgICBpbmRleGVzVGFyZ2V0Um93LFxuICAgIDAsXG4gICk7XG5cbiAgdHIucmVwbGFjZVdpdGgodGFibGUucG9zLCB0YWJsZS5wb3MgKyB0YWJsZS5ub2RlLm5vZGVTaXplLCBuZXdUYWJsZSk7XG5cbiAgaWYgKCFzZWxlY3QpIHJldHVybiB0cnVlO1xuXG4gIGNvbnN0IG1hcCA9IFRhYmxlTWFwLmdldChuZXdUYWJsZSk7XG4gIGNvbnN0IHN0YXJ0ID0gdGFibGUuc3RhcnQ7XG4gIGNvbnN0IGluZGV4ID0gdGFyZ2V0SW5kZXg7XG4gIGNvbnN0IGxhc3RDZWxsID0gbWFwLnBvc2l0aW9uQXQoaW5kZXgsIG1hcC53aWR0aCAtIDEsIG5ld1RhYmxlKTtcbiAgY29uc3QgJGxhc3RDZWxsID0gdHIuZG9jLnJlc29sdmUoc3RhcnQgKyBsYXN0Q2VsbCk7XG5cbiAgY29uc3QgZmlyc3RDZWxsID0gbWFwLnBvc2l0aW9uQXQoaW5kZXgsIDAsIG5ld1RhYmxlKTtcbiAgY29uc3QgJGZpcnN0Q2VsbCA9IHRyLmRvYy5yZXNvbHZlKHN0YXJ0ICsgZmlyc3RDZWxsKTtcblxuICB0ci5zZXRTZWxlY3Rpb24oQ2VsbFNlbGVjdGlvbi5yb3dTZWxlY3Rpb24oJGxhc3RDZWxsLCAkZmlyc3RDZWxsKSk7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBtb3ZlVGFibGVSb3coXG4gIHRhYmxlOiBOb2RlLFxuICBpbmRleGVzT3JpZ2luOiBudW1iZXJbXSxcbiAgaW5kZXhlc1RhcmdldDogbnVtYmVyW10sXG4gIGRpcmVjdGlvbjogLTEgfCAxIHwgMCxcbikge1xuICBsZXQgcm93cyA9IGNvbnZlcnRUYWJsZU5vZGVUb0FycmF5T2ZSb3dzKHRhYmxlKTtcblxuICByb3dzID0gbW92ZVJvd0luQXJyYXlPZlJvd3Mocm93cywgaW5kZXhlc09yaWdpbiwgaW5kZXhlc1RhcmdldCwgZGlyZWN0aW9uKTtcblxuICByZXR1cm4gY29udmVydEFycmF5T2ZSb3dzVG9UYWJsZU5vZGUodGFibGUsIHJvd3MpO1xufVxuIiwgIi8vIFRoaXMgZmlsZSBkZWZpbmVzIGEgbnVtYmVyIG9mIHRhYmxlLXJlbGF0ZWQgY29tbWFuZHMuXG5cbmltcG9ydCB0eXBlIHsgTm9kZSwgTm9kZVR5cGUsIFJlc29sdmVkUG9zIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuaW1wb3J0IHsgRnJhZ21lbnQsIFNsaWNlIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuaW1wb3J0IHR5cGUgeyBDb21tYW5kLCBFZGl0b3JTdGF0ZSwgVHJhbnNhY3Rpb24gfSBmcm9tICdwcm9zZW1pcnJvci1zdGF0ZSc7XG5pbXBvcnQgeyBUZXh0U2VsZWN0aW9uIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuXG5pbXBvcnQgeyBDZWxsU2VsZWN0aW9uIH0gZnJvbSAnLi9jZWxsc2VsZWN0aW9uJztcbmltcG9ydCB0eXBlIHsgRGlyZWN0aW9uIH0gZnJvbSAnLi9pbnB1dCc7XG5pbXBvcnQgdHlwZSB7IFRhYmxlUm9sZSB9IGZyb20gJy4vc2NoZW1hJztcbmltcG9ydCB7IHRhYmxlTm9kZVR5cGVzIH0gZnJvbSAnLi9zY2hlbWEnO1xuaW1wb3J0IHR5cGUgeyBSZWN0IH0gZnJvbSAnLi90YWJsZW1hcCc7XG5pbXBvcnQgeyBUYWJsZU1hcCB9IGZyb20gJy4vdGFibGVtYXAnO1xuaW1wb3J0IHR5cGUgeyBDZWxsQXR0cnMgfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IHtcbiAgYWRkQ29sU3BhbixcbiAgY2VsbEFyb3VuZCxcbiAgY2VsbFdyYXBwaW5nLFxuICBjb2x1bW5Jc0hlYWRlcixcbiAgaXNJblRhYmxlLFxuICBtb3ZlQ2VsbEZvcndhcmQsXG4gIHJlbW92ZUNvbFNwYW4sXG4gIHNlbGVjdGlvbkNlbGwsXG59IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgeyBtb3ZlQ29sdW1uIH0gZnJvbSAnLi91dGlscy9tb3ZlLWNvbHVtbic7XG5pbXBvcnQgeyBtb3ZlUm93IH0gZnJvbSAnLi91dGlscy9tb3ZlLXJvdyc7XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBUYWJsZVJlY3QgPSBSZWN0ICYge1xuICB0YWJsZVN0YXJ0OiBudW1iZXI7XG4gIG1hcDogVGFibGVNYXA7XG4gIHRhYmxlOiBOb2RlO1xufTtcblxuLyoqXG4gKiBIZWxwZXIgdG8gZ2V0IHRoZSBzZWxlY3RlZCByZWN0YW5nbGUgaW4gYSB0YWJsZSwgaWYgYW55LiBBZGRzIHRhYmxlXG4gKiBtYXAsIHRhYmxlIG5vZGUsIGFuZCB0YWJsZSBzdGFydCBvZmZzZXQgdG8gdGhlIG9iamVjdCBmb3JcbiAqIGNvbnZlbmllbmNlLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdGVkUmVjdChzdGF0ZTogRWRpdG9yU3RhdGUpOiBUYWJsZVJlY3Qge1xuICBjb25zdCBzZWwgPSBzdGF0ZS5zZWxlY3Rpb247XG4gIGNvbnN0ICRwb3MgPSBzZWxlY3Rpb25DZWxsKHN0YXRlKTtcbiAgY29uc3QgdGFibGUgPSAkcG9zLm5vZGUoLTEpO1xuICBjb25zdCB0YWJsZVN0YXJ0ID0gJHBvcy5zdGFydCgtMSk7XG4gIGNvbnN0IG1hcCA9IFRhYmxlTWFwLmdldCh0YWJsZSk7XG4gIGNvbnN0IHJlY3QgPVxuICAgIHNlbCBpbnN0YW5jZW9mIENlbGxTZWxlY3Rpb25cbiAgICAgID8gbWFwLnJlY3RCZXR3ZWVuKFxuICAgICAgICAgIHNlbC4kYW5jaG9yQ2VsbC5wb3MgLSB0YWJsZVN0YXJ0LFxuICAgICAgICAgIHNlbC4kaGVhZENlbGwucG9zIC0gdGFibGVTdGFydCxcbiAgICAgICAgKVxuICAgICAgOiBtYXAuZmluZENlbGwoJHBvcy5wb3MgLSB0YWJsZVN0YXJ0KTtcbiAgcmV0dXJuIHsgLi4ucmVjdCwgdGFibGVTdGFydCwgbWFwLCB0YWJsZSB9O1xufVxuXG4vKipcbiAqIEFkZCBhIGNvbHVtbiBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24gaW4gYSB0YWJsZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb2x1bW4oXG4gIHRyOiBUcmFuc2FjdGlvbixcbiAgeyBtYXAsIHRhYmxlU3RhcnQsIHRhYmxlIH06IFRhYmxlUmVjdCxcbiAgY29sOiBudW1iZXIsXG4pOiBUcmFuc2FjdGlvbiB7XG4gIGxldCByZWZDb2x1bW46IG51bWJlciB8IG51bGwgPSBjb2wgPiAwID8gLTEgOiAwO1xuICBpZiAoY29sdW1uSXNIZWFkZXIobWFwLCB0YWJsZSwgY29sICsgcmVmQ29sdW1uKSkge1xuICAgIHJlZkNvbHVtbiA9IGNvbCA9PSAwIHx8IGNvbCA9PSBtYXAud2lkdGggPyBudWxsIDogMDtcbiAgfVxuXG4gIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IG1hcC5oZWlnaHQ7IHJvdysrKSB7XG4gICAgY29uc3QgaW5kZXggPSByb3cgKiBtYXAud2lkdGggKyBjb2w7XG4gICAgLy8gSWYgdGhpcyBwb3NpdGlvbiBmYWxscyBpbnNpZGUgYSBjb2wtc3Bhbm5pbmcgY2VsbFxuICAgIGlmIChjb2wgPiAwICYmIGNvbCA8IG1hcC53aWR0aCAmJiBtYXAubWFwW2luZGV4IC0gMV0gPT0gbWFwLm1hcFtpbmRleF0pIHtcbiAgICAgIGNvbnN0IHBvcyA9IG1hcC5tYXBbaW5kZXhdO1xuICAgICAgY29uc3QgY2VsbCA9IHRhYmxlLm5vZGVBdChwb3MpITtcbiAgICAgIHRyLnNldE5vZGVNYXJrdXAoXG4gICAgICAgIHRyLm1hcHBpbmcubWFwKHRhYmxlU3RhcnQgKyBwb3MpLFxuICAgICAgICBudWxsLFxuICAgICAgICBhZGRDb2xTcGFuKGNlbGwuYXR0cnMgYXMgQ2VsbEF0dHJzLCBjb2wgLSBtYXAuY29sQ291bnQocG9zKSksXG4gICAgICApO1xuICAgICAgLy8gU2tpcCBhaGVhZCBpZiByb3dzcGFuID4gMVxuICAgICAgcm93ICs9IGNlbGwuYXR0cnMucm93c3BhbiAtIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHR5cGUgPVxuICAgICAgICByZWZDb2x1bW4gPT0gbnVsbFxuICAgICAgICAgID8gdGFibGVOb2RlVHlwZXModGFibGUudHlwZS5zY2hlbWEpLmNlbGxcbiAgICAgICAgICA6IHRhYmxlLm5vZGVBdChtYXAubWFwW2luZGV4ICsgcmVmQ29sdW1uXSkhLnR5cGU7XG4gICAgICBjb25zdCBwb3MgPSBtYXAucG9zaXRpb25BdChyb3csIGNvbCwgdGFibGUpO1xuICAgICAgdHIuaW5zZXJ0KHRyLm1hcHBpbmcubWFwKHRhYmxlU3RhcnQgKyBwb3MpLCB0eXBlLmNyZWF0ZUFuZEZpbGwoKSEpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHI7XG59XG5cbi8qKlxuICogQ29tbWFuZCB0byBhZGQgYSBjb2x1bW4gYmVmb3JlIHRoZSBjb2x1bW4gd2l0aCB0aGUgc2VsZWN0aW9uLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZENvbHVtbkJlZm9yZShcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuICBkaXNwYXRjaD86ICh0cjogVHJhbnNhY3Rpb24pID0+IHZvaWQsXG4pOiBib29sZWFuIHtcbiAgaWYgKCFpc0luVGFibGUoc3RhdGUpKSByZXR1cm4gZmFsc2U7XG4gIGlmIChkaXNwYXRjaCkge1xuICAgIGNvbnN0IHJlY3QgPSBzZWxlY3RlZFJlY3Qoc3RhdGUpO1xuICAgIGRpc3BhdGNoKGFkZENvbHVtbihzdGF0ZS50ciwgcmVjdCwgcmVjdC5sZWZ0KSk7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogQ29tbWFuZCB0byBhZGQgYSBjb2x1bW4gYWZ0ZXIgdGhlIGNvbHVtbiB3aXRoIHRoZSBzZWxlY3Rpb24uXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkQ29sdW1uQWZ0ZXIoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgZGlzcGF0Y2g/OiAodHI6IFRyYW5zYWN0aW9uKSA9PiB2b2lkLFxuKTogYm9vbGVhbiB7XG4gIGlmICghaXNJblRhYmxlKHN0YXRlKSkgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGlzcGF0Y2gpIHtcbiAgICBjb25zdCByZWN0ID0gc2VsZWN0ZWRSZWN0KHN0YXRlKTtcbiAgICBkaXNwYXRjaChhZGRDb2x1bW4oc3RhdGUudHIsIHJlY3QsIHJlY3QucmlnaHQpKTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVDb2x1bW4oXG4gIHRyOiBUcmFuc2FjdGlvbixcbiAgeyBtYXAsIHRhYmxlLCB0YWJsZVN0YXJ0IH06IFRhYmxlUmVjdCxcbiAgY29sOiBudW1iZXIsXG4pIHtcbiAgY29uc3QgbWFwU3RhcnQgPSB0ci5tYXBwaW5nLm1hcHMubGVuZ3RoO1xuICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCBtYXAuaGVpZ2h0OyApIHtcbiAgICBjb25zdCBpbmRleCA9IHJvdyAqIG1hcC53aWR0aCArIGNvbDtcbiAgICBjb25zdCBwb3MgPSBtYXAubWFwW2luZGV4XTtcbiAgICBjb25zdCBjZWxsID0gdGFibGUubm9kZUF0KHBvcykhO1xuICAgIGNvbnN0IGF0dHJzID0gY2VsbC5hdHRycyBhcyBDZWxsQXR0cnM7XG4gICAgLy8gSWYgdGhpcyBpcyBwYXJ0IG9mIGEgY29sLXNwYW5uaW5nIGNlbGxcbiAgICBpZiAoXG4gICAgICAoY29sID4gMCAmJiBtYXAubWFwW2luZGV4IC0gMV0gPT0gcG9zKSB8fFxuICAgICAgKGNvbCA8IG1hcC53aWR0aCAtIDEgJiYgbWFwLm1hcFtpbmRleCArIDFdID09IHBvcylcbiAgICApIHtcbiAgICAgIHRyLnNldE5vZGVNYXJrdXAoXG4gICAgICAgIHRyLm1hcHBpbmcuc2xpY2UobWFwU3RhcnQpLm1hcCh0YWJsZVN0YXJ0ICsgcG9zKSxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgcmVtb3ZlQ29sU3BhbihhdHRycywgY29sIC0gbWFwLmNvbENvdW50KHBvcykpLFxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgc3RhcnQgPSB0ci5tYXBwaW5nLnNsaWNlKG1hcFN0YXJ0KS5tYXAodGFibGVTdGFydCArIHBvcyk7XG4gICAgICB0ci5kZWxldGUoc3RhcnQsIHN0YXJ0ICsgY2VsbC5ub2RlU2l6ZSk7XG4gICAgfVxuICAgIHJvdyArPSBhdHRycy5yb3dzcGFuO1xuICB9XG59XG5cbi8qKlxuICogQ29tbWFuZCBmdW5jdGlvbiB0aGF0IHJlbW92ZXMgdGhlIHNlbGVjdGVkIGNvbHVtbnMgZnJvbSBhIHRhYmxlLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlbGV0ZUNvbHVtbihcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuICBkaXNwYXRjaD86ICh0cjogVHJhbnNhY3Rpb24pID0+IHZvaWQsXG4pOiBib29sZWFuIHtcbiAgaWYgKCFpc0luVGFibGUoc3RhdGUpKSByZXR1cm4gZmFsc2U7XG4gIGlmIChkaXNwYXRjaCkge1xuICAgIGNvbnN0IHJlY3QgPSBzZWxlY3RlZFJlY3Qoc3RhdGUpO1xuICAgIGNvbnN0IHRyID0gc3RhdGUudHI7XG4gICAgaWYgKHJlY3QubGVmdCA9PSAwICYmIHJlY3QucmlnaHQgPT0gcmVjdC5tYXAud2lkdGgpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gcmVjdC5yaWdodCAtIDE7IDsgaS0tKSB7XG4gICAgICByZW1vdmVDb2x1bW4odHIsIHJlY3QsIGkpO1xuICAgICAgaWYgKGkgPT0gcmVjdC5sZWZ0KSBicmVhaztcbiAgICAgIGNvbnN0IHRhYmxlID0gcmVjdC50YWJsZVN0YXJ0XG4gICAgICAgID8gdHIuZG9jLm5vZGVBdChyZWN0LnRhYmxlU3RhcnQgLSAxKVxuICAgICAgICA6IHRyLmRvYztcbiAgICAgIGlmICghdGFibGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ05vIHRhYmxlIGZvdW5kJyk7XG4gICAgICB9XG4gICAgICByZWN0LnRhYmxlID0gdGFibGU7XG4gICAgICByZWN0Lm1hcCA9IFRhYmxlTWFwLmdldCh0YWJsZSk7XG4gICAgfVxuICAgIGRpc3BhdGNoKHRyKTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByb3dJc0hlYWRlcihtYXA6IFRhYmxlTWFwLCB0YWJsZTogTm9kZSwgcm93OiBudW1iZXIpOiBib29sZWFuIHtcbiAgY29uc3QgaGVhZGVyQ2VsbCA9IHRhYmxlTm9kZVR5cGVzKHRhYmxlLnR5cGUuc2NoZW1hKS5oZWFkZXJfY2VsbDtcbiAgZm9yIChsZXQgY29sID0gMDsgY29sIDwgbWFwLndpZHRoOyBjb2wrKylcbiAgICBpZiAodGFibGUubm9kZUF0KG1hcC5tYXBbY29sICsgcm93ICogbWFwLndpZHRoXSk/LnR5cGUgIT0gaGVhZGVyQ2VsbClcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkUm93KFxuICB0cjogVHJhbnNhY3Rpb24sXG4gIHsgbWFwLCB0YWJsZVN0YXJ0LCB0YWJsZSB9OiBUYWJsZVJlY3QsXG4gIHJvdzogbnVtYmVyLFxuKTogVHJhbnNhY3Rpb24ge1xuICBsZXQgcm93UG9zID0gdGFibGVTdGFydDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3c7IGkrKykgcm93UG9zICs9IHRhYmxlLmNoaWxkKGkpLm5vZGVTaXplO1xuICBjb25zdCBjZWxscyA9IFtdO1xuICBsZXQgcmVmUm93OiBudW1iZXIgfCBudWxsID0gcm93ID4gMCA/IC0xIDogMDtcbiAgaWYgKHJvd0lzSGVhZGVyKG1hcCwgdGFibGUsIHJvdyArIHJlZlJvdykpXG4gICAgcmVmUm93ID0gcm93ID09IDAgfHwgcm93ID09IG1hcC5oZWlnaHQgPyBudWxsIDogMDtcbiAgZm9yIChsZXQgY29sID0gMCwgaW5kZXggPSBtYXAud2lkdGggKiByb3c7IGNvbCA8IG1hcC53aWR0aDsgY29sKyssIGluZGV4KyspIHtcbiAgICAvLyBDb3ZlcmVkIGJ5IGEgcm93c3BhbiBjZWxsXG4gICAgaWYgKFxuICAgICAgcm93ID4gMCAmJlxuICAgICAgcm93IDwgbWFwLmhlaWdodCAmJlxuICAgICAgbWFwLm1hcFtpbmRleF0gPT0gbWFwLm1hcFtpbmRleCAtIG1hcC53aWR0aF1cbiAgICApIHtcbiAgICAgIGNvbnN0IHBvcyA9IG1hcC5tYXBbaW5kZXhdO1xuICAgICAgY29uc3QgYXR0cnMgPSB0YWJsZS5ub2RlQXQocG9zKSEuYXR0cnM7XG4gICAgICB0ci5zZXROb2RlTWFya3VwKHRhYmxlU3RhcnQgKyBwb3MsIG51bGwsIHtcbiAgICAgICAgLi4uYXR0cnMsXG4gICAgICAgIHJvd3NwYW46IGF0dHJzLnJvd3NwYW4gKyAxLFxuICAgICAgfSk7XG4gICAgICBjb2wgKz0gYXR0cnMuY29sc3BhbiAtIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHR5cGUgPVxuICAgICAgICByZWZSb3cgPT0gbnVsbFxuICAgICAgICAgID8gdGFibGVOb2RlVHlwZXModGFibGUudHlwZS5zY2hlbWEpLmNlbGxcbiAgICAgICAgICA6IHRhYmxlLm5vZGVBdChtYXAubWFwW2luZGV4ICsgcmVmUm93ICogbWFwLndpZHRoXSk/LnR5cGU7XG4gICAgICBjb25zdCBub2RlID0gdHlwZT8uY3JlYXRlQW5kRmlsbCgpO1xuICAgICAgaWYgKG5vZGUpIGNlbGxzLnB1c2gobm9kZSk7XG4gICAgfVxuICB9XG4gIHRyLmluc2VydChyb3dQb3MsIHRhYmxlTm9kZVR5cGVzKHRhYmxlLnR5cGUuc2NoZW1hKS5yb3cuY3JlYXRlKG51bGwsIGNlbGxzKSk7XG4gIHJldHVybiB0cjtcbn1cblxuLyoqXG4gKiBBZGQgYSB0YWJsZSByb3cgYmVmb3JlIHRoZSBzZWxlY3Rpb24uXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkUm93QmVmb3JlKFxuICBzdGF0ZTogRWRpdG9yU3RhdGUsXG4gIGRpc3BhdGNoPzogKHRyOiBUcmFuc2FjdGlvbikgPT4gdm9pZCxcbik6IGJvb2xlYW4ge1xuICBpZiAoIWlzSW5UYWJsZShzdGF0ZSkpIHJldHVybiBmYWxzZTtcbiAgaWYgKGRpc3BhdGNoKSB7XG4gICAgY29uc3QgcmVjdCA9IHNlbGVjdGVkUmVjdChzdGF0ZSk7XG4gICAgZGlzcGF0Y2goYWRkUm93KHN0YXRlLnRyLCByZWN0LCByZWN0LnRvcCkpO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIEFkZCBhIHRhYmxlIHJvdyBhZnRlciB0aGUgc2VsZWN0aW9uLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFJvd0FmdGVyKFxuICBzdGF0ZTogRWRpdG9yU3RhdGUsXG4gIGRpc3BhdGNoPzogKHRyOiBUcmFuc2FjdGlvbikgPT4gdm9pZCxcbik6IGJvb2xlYW4ge1xuICBpZiAoIWlzSW5UYWJsZShzdGF0ZSkpIHJldHVybiBmYWxzZTtcbiAgaWYgKGRpc3BhdGNoKSB7XG4gICAgY29uc3QgcmVjdCA9IHNlbGVjdGVkUmVjdChzdGF0ZSk7XG4gICAgZGlzcGF0Y2goYWRkUm93KHN0YXRlLnRyLCByZWN0LCByZWN0LmJvdHRvbSkpO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVJvdyhcbiAgdHI6IFRyYW5zYWN0aW9uLFxuICB7IG1hcCwgdGFibGUsIHRhYmxlU3RhcnQgfTogVGFibGVSZWN0LFxuICByb3c6IG51bWJlcixcbik6IHZvaWQge1xuICBsZXQgcm93UG9zID0gMDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3c7IGkrKykgcm93UG9zICs9IHRhYmxlLmNoaWxkKGkpLm5vZGVTaXplO1xuICBjb25zdCBuZXh0Um93ID0gcm93UG9zICsgdGFibGUuY2hpbGQocm93KS5ub2RlU2l6ZTtcblxuICBjb25zdCBtYXBGcm9tID0gdHIubWFwcGluZy5tYXBzLmxlbmd0aDtcbiAgdHIuZGVsZXRlKHJvd1BvcyArIHRhYmxlU3RhcnQsIG5leHRSb3cgKyB0YWJsZVN0YXJ0KTtcblxuICBjb25zdCBzZWVuID0gbmV3IFNldDxudW1iZXI+KCk7XG5cbiAgZm9yIChsZXQgY29sID0gMCwgaW5kZXggPSByb3cgKiBtYXAud2lkdGg7IGNvbCA8IG1hcC53aWR0aDsgY29sKyssIGluZGV4KyspIHtcbiAgICBjb25zdCBwb3MgPSBtYXAubWFwW2luZGV4XTtcblxuICAgIC8vIFNraXAgY2VsbHMgdGhhdCBhcmUgY2hlY2tlZCBhbHJlYWR5XG4gICAgaWYgKHNlZW4uaGFzKHBvcykpIGNvbnRpbnVlO1xuICAgIHNlZW4uYWRkKHBvcyk7XG5cbiAgICBpZiAocm93ID4gMCAmJiBwb3MgPT0gbWFwLm1hcFtpbmRleCAtIG1hcC53aWR0aF0pIHtcbiAgICAgIC8vIElmIHRoaXMgY2VsbCBzdGFydHMgaW4gdGhlIHJvdyBhYm92ZSwgc2ltcGx5IHJlZHVjZSBpdHMgcm93c3BhblxuICAgICAgY29uc3QgYXR0cnMgPSB0YWJsZS5ub2RlQXQocG9zKSEuYXR0cnMgYXMgQ2VsbEF0dHJzO1xuICAgICAgdHIuc2V0Tm9kZU1hcmt1cCh0ci5tYXBwaW5nLnNsaWNlKG1hcEZyb20pLm1hcChwb3MgKyB0YWJsZVN0YXJ0KSwgbnVsbCwge1xuICAgICAgICAuLi5hdHRycyxcbiAgICAgICAgcm93c3BhbjogYXR0cnMucm93c3BhbiAtIDEsXG4gICAgICB9KTtcbiAgICAgIGNvbCArPSBhdHRycy5jb2xzcGFuIC0gMTtcbiAgICB9IGVsc2UgaWYgKHJvdyA8IG1hcC5oZWlnaHQgJiYgcG9zID09IG1hcC5tYXBbaW5kZXggKyBtYXAud2lkdGhdKSB7XG4gICAgICAvLyBFbHNlLCBpZiBpdCBjb250aW51ZXMgaW4gdGhlIHJvdyBiZWxvdywgaXQgaGFzIHRvIGJlIG1vdmVkIGRvd25cbiAgICAgIGNvbnN0IGNlbGwgPSB0YWJsZS5ub2RlQXQocG9zKSE7XG4gICAgICBjb25zdCBhdHRycyA9IGNlbGwuYXR0cnMgYXMgQ2VsbEF0dHJzO1xuICAgICAgY29uc3QgY29weSA9IGNlbGwudHlwZS5jcmVhdGUoXG4gICAgICAgIHsgLi4uYXR0cnMsIHJvd3NwYW46IGNlbGwuYXR0cnMucm93c3BhbiAtIDEgfSxcbiAgICAgICAgY2VsbC5jb250ZW50LFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG5ld1BvcyA9IG1hcC5wb3NpdGlvbkF0KHJvdyArIDEsIGNvbCwgdGFibGUpO1xuICAgICAgdHIuaW5zZXJ0KHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSkubWFwKHRhYmxlU3RhcnQgKyBuZXdQb3MpLCBjb3B5KTtcbiAgICAgIGNvbCArPSBhdHRycy5jb2xzcGFuIC0gMTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmUgdGhlIHNlbGVjdGVkIHJvd3MgZnJvbSBhIHRhYmxlLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlbGV0ZVJvdyhcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuICBkaXNwYXRjaD86ICh0cjogVHJhbnNhY3Rpb24pID0+IHZvaWQsXG4pOiBib29sZWFuIHtcbiAgaWYgKCFpc0luVGFibGUoc3RhdGUpKSByZXR1cm4gZmFsc2U7XG4gIGlmIChkaXNwYXRjaCkge1xuICAgIGNvbnN0IHJlY3QgPSBzZWxlY3RlZFJlY3Qoc3RhdGUpLFxuICAgICAgdHIgPSBzdGF0ZS50cjtcbiAgICBpZiAocmVjdC50b3AgPT0gMCAmJiByZWN0LmJvdHRvbSA9PSByZWN0Lm1hcC5oZWlnaHQpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gcmVjdC5ib3R0b20gLSAxOyA7IGktLSkge1xuICAgICAgcmVtb3ZlUm93KHRyLCByZWN0LCBpKTtcbiAgICAgIGlmIChpID09IHJlY3QudG9wKSBicmVhaztcbiAgICAgIGNvbnN0IHRhYmxlID0gcmVjdC50YWJsZVN0YXJ0XG4gICAgICAgID8gdHIuZG9jLm5vZGVBdChyZWN0LnRhYmxlU3RhcnQgLSAxKVxuICAgICAgICA6IHRyLmRvYztcbiAgICAgIGlmICghdGFibGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ05vIHRhYmxlIGZvdW5kJyk7XG4gICAgICB9XG4gICAgICByZWN0LnRhYmxlID0gdGFibGU7XG4gICAgICByZWN0Lm1hcCA9IFRhYmxlTWFwLmdldChyZWN0LnRhYmxlKTtcbiAgICB9XG4gICAgZGlzcGF0Y2godHIpO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBpc0VtcHR5KGNlbGw6IE5vZGUpOiBib29sZWFuIHtcbiAgY29uc3QgYyA9IGNlbGwuY29udGVudDtcblxuICByZXR1cm4gKFxuICAgIGMuY2hpbGRDb3VudCA9PSAxICYmIGMuY2hpbGQoMCkuaXNUZXh0YmxvY2sgJiYgYy5jaGlsZCgwKS5jaGlsZENvdW50ID09IDBcbiAgKTtcbn1cblxuZnVuY3Rpb24gY2VsbHNPdmVybGFwUmVjdGFuZ2xlKHsgd2lkdGgsIGhlaWdodCwgbWFwIH06IFRhYmxlTWFwLCByZWN0OiBSZWN0KSB7XG4gIGxldCBpbmRleFRvcCA9IHJlY3QudG9wICogd2lkdGggKyByZWN0LmxlZnQsXG4gICAgaW5kZXhMZWZ0ID0gaW5kZXhUb3A7XG4gIGxldCBpbmRleEJvdHRvbSA9IChyZWN0LmJvdHRvbSAtIDEpICogd2lkdGggKyByZWN0LmxlZnQsXG4gICAgaW5kZXhSaWdodCA9IGluZGV4VG9wICsgKHJlY3QucmlnaHQgLSByZWN0LmxlZnQgLSAxKTtcbiAgZm9yIChsZXQgaSA9IHJlY3QudG9wOyBpIDwgcmVjdC5ib3R0b207IGkrKykge1xuICAgIGlmIChcbiAgICAgIChyZWN0LmxlZnQgPiAwICYmIG1hcFtpbmRleExlZnRdID09IG1hcFtpbmRleExlZnQgLSAxXSkgfHxcbiAgICAgIChyZWN0LnJpZ2h0IDwgd2lkdGggJiYgbWFwW2luZGV4UmlnaHRdID09IG1hcFtpbmRleFJpZ2h0ICsgMV0pXG4gICAgKVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgaW5kZXhMZWZ0ICs9IHdpZHRoO1xuICAgIGluZGV4UmlnaHQgKz0gd2lkdGg7XG4gIH1cbiAgZm9yIChsZXQgaSA9IHJlY3QubGVmdDsgaSA8IHJlY3QucmlnaHQ7IGkrKykge1xuICAgIGlmIChcbiAgICAgIChyZWN0LnRvcCA+IDAgJiYgbWFwW2luZGV4VG9wXSA9PSBtYXBbaW5kZXhUb3AgLSB3aWR0aF0pIHx8XG4gICAgICAocmVjdC5ib3R0b20gPCBoZWlnaHQgJiYgbWFwW2luZGV4Qm90dG9tXSA9PSBtYXBbaW5kZXhCb3R0b20gKyB3aWR0aF0pXG4gICAgKVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgaW5kZXhUb3ArKztcbiAgICBpbmRleEJvdHRvbSsrO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBNZXJnZSB0aGUgc2VsZWN0ZWQgY2VsbHMgaW50byBhIHNpbmdsZSBjZWxsLiBPbmx5IGF2YWlsYWJsZSB3aGVuXG4gKiB0aGUgc2VsZWN0ZWQgY2VsbHMnIG91dGxpbmUgZm9ybXMgYSByZWN0YW5nbGUuXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VDZWxscyhcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuICBkaXNwYXRjaD86ICh0cjogVHJhbnNhY3Rpb24pID0+IHZvaWQsXG4pOiBib29sZWFuIHtcbiAgY29uc3Qgc2VsID0gc3RhdGUuc2VsZWN0aW9uO1xuICBpZiAoXG4gICAgIShzZWwgaW5zdGFuY2VvZiBDZWxsU2VsZWN0aW9uKSB8fFxuICAgIHNlbC4kYW5jaG9yQ2VsbC5wb3MgPT0gc2VsLiRoZWFkQ2VsbC5wb3NcbiAgKVxuICAgIHJldHVybiBmYWxzZTtcbiAgY29uc3QgcmVjdCA9IHNlbGVjdGVkUmVjdChzdGF0ZSksXG4gICAgeyBtYXAgfSA9IHJlY3Q7XG4gIGlmIChjZWxsc092ZXJsYXBSZWN0YW5nbGUobWFwLCByZWN0KSkgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGlzcGF0Y2gpIHtcbiAgICBjb25zdCB0ciA9IHN0YXRlLnRyO1xuICAgIGNvbnN0IHNlZW46IFJlY29yZDxudW1iZXIsIGJvb2xlYW4+ID0ge307XG4gICAgbGV0IGNvbnRlbnQgPSBGcmFnbWVudC5lbXB0eTtcbiAgICBsZXQgbWVyZ2VkUG9zOiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgbGV0IG1lcmdlZENlbGw6IE5vZGUgfCB1bmRlZmluZWQ7XG4gICAgZm9yIChsZXQgcm93ID0gcmVjdC50b3A7IHJvdyA8IHJlY3QuYm90dG9tOyByb3crKykge1xuICAgICAgZm9yIChsZXQgY29sID0gcmVjdC5sZWZ0OyBjb2wgPCByZWN0LnJpZ2h0OyBjb2wrKykge1xuICAgICAgICBjb25zdCBjZWxsUG9zID0gbWFwLm1hcFtyb3cgKiBtYXAud2lkdGggKyBjb2xdO1xuICAgICAgICBjb25zdCBjZWxsID0gcmVjdC50YWJsZS5ub2RlQXQoY2VsbFBvcyk7XG4gICAgICAgIGlmIChzZWVuW2NlbGxQb3NdIHx8ICFjZWxsKSBjb250aW51ZTtcbiAgICAgICAgc2VlbltjZWxsUG9zXSA9IHRydWU7XG4gICAgICAgIGlmIChtZXJnZWRQb3MgPT0gbnVsbCkge1xuICAgICAgICAgIG1lcmdlZFBvcyA9IGNlbGxQb3M7XG4gICAgICAgICAgbWVyZ2VkQ2VsbCA9IGNlbGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKCFpc0VtcHR5KGNlbGwpKSBjb250ZW50ID0gY29udGVudC5hcHBlbmQoY2VsbC5jb250ZW50KTtcbiAgICAgICAgICBjb25zdCBtYXBwZWQgPSB0ci5tYXBwaW5nLm1hcChjZWxsUG9zICsgcmVjdC50YWJsZVN0YXJ0KTtcbiAgICAgICAgICB0ci5kZWxldGUobWFwcGVkLCBtYXBwZWQgKyBjZWxsLm5vZGVTaXplKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobWVyZ2VkUG9zID09IG51bGwgfHwgbWVyZ2VkQ2VsbCA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICB0ci5zZXROb2RlTWFya3VwKG1lcmdlZFBvcyArIHJlY3QudGFibGVTdGFydCwgbnVsbCwge1xuICAgICAgLi4uYWRkQ29sU3BhbihcbiAgICAgICAgbWVyZ2VkQ2VsbC5hdHRycyBhcyBDZWxsQXR0cnMsXG4gICAgICAgIG1lcmdlZENlbGwuYXR0cnMuY29sc3BhbixcbiAgICAgICAgcmVjdC5yaWdodCAtIHJlY3QubGVmdCAtIG1lcmdlZENlbGwuYXR0cnMuY29sc3BhbixcbiAgICAgICksXG4gICAgICByb3dzcGFuOiByZWN0LmJvdHRvbSAtIHJlY3QudG9wLFxuICAgIH0pO1xuICAgIGlmIChjb250ZW50LnNpemUgPiAwKSB7XG4gICAgICBjb25zdCBlbmQgPSBtZXJnZWRQb3MgKyAxICsgbWVyZ2VkQ2VsbC5jb250ZW50LnNpemU7XG4gICAgICBjb25zdCBzdGFydCA9IGlzRW1wdHkobWVyZ2VkQ2VsbCkgPyBtZXJnZWRQb3MgKyAxIDogZW5kO1xuICAgICAgdHIucmVwbGFjZVdpdGgoc3RhcnQgKyByZWN0LnRhYmxlU3RhcnQsIGVuZCArIHJlY3QudGFibGVTdGFydCwgY29udGVudCk7XG4gICAgfVxuICAgIHRyLnNldFNlbGVjdGlvbihcbiAgICAgIG5ldyBDZWxsU2VsZWN0aW9uKHRyLmRvYy5yZXNvbHZlKG1lcmdlZFBvcyArIHJlY3QudGFibGVTdGFydCkpLFxuICAgICk7XG4gICAgZGlzcGF0Y2godHIpO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIFNwbGl0IGEgc2VsZWN0ZWQgY2VsbCwgd2hvc2Ugcm93cGFuIG9yIGNvbHNwYW4gaXMgZ3JlYXRlciB0aGFuIG9uZSxcbiAqIGludG8gc21hbGxlciBjZWxscy4gVXNlIHRoZSBmaXJzdCBjZWxsIHR5cGUgZm9yIHRoZSBuZXcgY2VsbHMuXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gc3BsaXRDZWxsKFxuICBzdGF0ZTogRWRpdG9yU3RhdGUsXG4gIGRpc3BhdGNoPzogKHRyOiBUcmFuc2FjdGlvbikgPT4gdm9pZCxcbik6IGJvb2xlYW4ge1xuICBjb25zdCBub2RlVHlwZXMgPSB0YWJsZU5vZGVUeXBlcyhzdGF0ZS5zY2hlbWEpO1xuICByZXR1cm4gc3BsaXRDZWxsV2l0aFR5cGUoKHsgbm9kZSB9KSA9PiB7XG4gICAgcmV0dXJuIG5vZGVUeXBlc1tub2RlLnR5cGUuc3BlYy50YWJsZVJvbGUgYXMgVGFibGVSb2xlXTtcbiAgfSkoc3RhdGUsIGRpc3BhdGNoKTtcbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR2V0Q2VsbFR5cGVPcHRpb25zIHtcbiAgbm9kZTogTm9kZTtcbiAgcm93OiBudW1iZXI7XG4gIGNvbDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFNwbGl0IGEgc2VsZWN0ZWQgY2VsbCwgd2hvc2Ugcm93cGFuIG9yIGNvbHNwYW4gaXMgZ3JlYXRlciB0aGFuIG9uZSxcbiAqIGludG8gc21hbGxlciBjZWxscyB3aXRoIHRoZSBjZWxsIHR5cGUgKHRoLCB0ZCkgcmV0dXJuZWQgYnkgZ2V0VHlwZSBmdW5jdGlvbi5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzcGxpdENlbGxXaXRoVHlwZShcbiAgZ2V0Q2VsbFR5cGU6IChvcHRpb25zOiBHZXRDZWxsVHlwZU9wdGlvbnMpID0+IE5vZGVUeXBlLFxuKTogQ29tbWFuZCB7XG4gIHJldHVybiAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgY29uc3Qgc2VsID0gc3RhdGUuc2VsZWN0aW9uO1xuICAgIGxldCBjZWxsTm9kZTogTm9kZSB8IG51bGwgfCB1bmRlZmluZWQ7XG4gICAgbGV0IGNlbGxQb3M6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICBpZiAoIShzZWwgaW5zdGFuY2VvZiBDZWxsU2VsZWN0aW9uKSkge1xuICAgICAgY2VsbE5vZGUgPSBjZWxsV3JhcHBpbmcoc2VsLiRmcm9tKTtcbiAgICAgIGlmICghY2VsbE5vZGUpIHJldHVybiBmYWxzZTtcbiAgICAgIGNlbGxQb3MgPSBjZWxsQXJvdW5kKHNlbC4kZnJvbSk/LnBvcztcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHNlbC4kYW5jaG9yQ2VsbC5wb3MgIT0gc2VsLiRoZWFkQ2VsbC5wb3MpIHJldHVybiBmYWxzZTtcbiAgICAgIGNlbGxOb2RlID0gc2VsLiRhbmNob3JDZWxsLm5vZGVBZnRlcjtcbiAgICAgIGNlbGxQb3MgPSBzZWwuJGFuY2hvckNlbGwucG9zO1xuICAgIH1cbiAgICBpZiAoY2VsbE5vZGUgPT0gbnVsbCB8fCBjZWxsUG9zID09IG51bGwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGNlbGxOb2RlLmF0dHJzLmNvbHNwYW4gPT0gMSAmJiBjZWxsTm9kZS5hdHRycy5yb3dzcGFuID09IDEpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICBsZXQgYmFzZUF0dHJzID0gY2VsbE5vZGUuYXR0cnM7XG4gICAgICBjb25zdCBhdHRycyA9IFtdO1xuICAgICAgY29uc3QgY29sd2lkdGggPSBiYXNlQXR0cnMuY29sd2lkdGg7XG4gICAgICBpZiAoYmFzZUF0dHJzLnJvd3NwYW4gPiAxKSBiYXNlQXR0cnMgPSB7IC4uLmJhc2VBdHRycywgcm93c3BhbjogMSB9O1xuICAgICAgaWYgKGJhc2VBdHRycy5jb2xzcGFuID4gMSkgYmFzZUF0dHJzID0geyAuLi5iYXNlQXR0cnMsIGNvbHNwYW46IDEgfTtcbiAgICAgIGNvbnN0IHJlY3QgPSBzZWxlY3RlZFJlY3Qoc3RhdGUpLFxuICAgICAgICB0ciA9IHN0YXRlLnRyO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0OyBpKyspXG4gICAgICAgIGF0dHJzLnB1c2goXG4gICAgICAgICAgY29sd2lkdGhcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIC4uLmJhc2VBdHRycyxcbiAgICAgICAgICAgICAgICBjb2x3aWR0aDogY29sd2lkdGggJiYgY29sd2lkdGhbaV0gPyBbY29sd2lkdGhbaV1dIDogbnVsbCxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiBiYXNlQXR0cnMsXG4gICAgICAgICk7XG4gICAgICBsZXQgbGFzdENlbGw7XG4gICAgICBmb3IgKGxldCByb3cgPSByZWN0LnRvcDsgcm93IDwgcmVjdC5ib3R0b207IHJvdysrKSB7XG4gICAgICAgIGxldCBwb3MgPSByZWN0Lm1hcC5wb3NpdGlvbkF0KHJvdywgcmVjdC5sZWZ0LCByZWN0LnRhYmxlKTtcbiAgICAgICAgaWYgKHJvdyA9PSByZWN0LnRvcCkgcG9zICs9IGNlbGxOb2RlLm5vZGVTaXplO1xuICAgICAgICBmb3IgKGxldCBjb2wgPSByZWN0LmxlZnQsIGkgPSAwOyBjb2wgPCByZWN0LnJpZ2h0OyBjb2wrKywgaSsrKSB7XG4gICAgICAgICAgaWYgKGNvbCA9PSByZWN0LmxlZnQgJiYgcm93ID09IHJlY3QudG9wKSBjb250aW51ZTtcbiAgICAgICAgICB0ci5pbnNlcnQoXG4gICAgICAgICAgICAobGFzdENlbGwgPSB0ci5tYXBwaW5nLm1hcChwb3MgKyByZWN0LnRhYmxlU3RhcnQsIDEpKSxcbiAgICAgICAgICAgIGdldENlbGxUeXBlKHsgbm9kZTogY2VsbE5vZGUsIHJvdywgY29sIH0pLmNyZWF0ZUFuZEZpbGwoYXR0cnNbaV0pISxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0ci5zZXROb2RlTWFya3VwKFxuICAgICAgICBjZWxsUG9zLFxuICAgICAgICBnZXRDZWxsVHlwZSh7IG5vZGU6IGNlbGxOb2RlLCByb3c6IHJlY3QudG9wLCBjb2w6IHJlY3QubGVmdCB9KSxcbiAgICAgICAgYXR0cnNbMF0sXG4gICAgICApO1xuICAgICAgaWYgKHNlbCBpbnN0YW5jZW9mIENlbGxTZWxlY3Rpb24pXG4gICAgICAgIHRyLnNldFNlbGVjdGlvbihcbiAgICAgICAgICBuZXcgQ2VsbFNlbGVjdGlvbihcbiAgICAgICAgICAgIHRyLmRvYy5yZXNvbHZlKHNlbC4kYW5jaG9yQ2VsbC5wb3MpLFxuICAgICAgICAgICAgbGFzdENlbGwgPyB0ci5kb2MucmVzb2x2ZShsYXN0Q2VsbCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIGRpc3BhdGNoKHRyKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGNvbW1hbmQgdGhhdCBzZXRzIHRoZSBnaXZlbiBhdHRyaWJ1dGUgdG8gdGhlIGdpdmVuIHZhbHVlLFxuICogYW5kIGlzIG9ubHkgYXZhaWxhYmxlIHdoZW4gdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBjZWxsIGRvZXNuJ3RcbiAqIGFscmVhZHkgaGF2ZSB0aGF0IGF0dHJpYnV0ZSBzZXQgdG8gdGhhdCB2YWx1ZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRDZWxsQXR0cihuYW1lOiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogQ29tbWFuZCB7XG4gIHJldHVybiBmdW5jdGlvbiAoc3RhdGUsIGRpc3BhdGNoKSB7XG4gICAgaWYgKCFpc0luVGFibGUoc3RhdGUpKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgJGNlbGwgPSBzZWxlY3Rpb25DZWxsKHN0YXRlKTtcbiAgICBpZiAoJGNlbGwubm9kZUFmdGVyIS5hdHRyc1tuYW1lXSA9PT0gdmFsdWUpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgIGNvbnN0IHRyID0gc3RhdGUudHI7XG4gICAgICBpZiAoc3RhdGUuc2VsZWN0aW9uIGluc3RhbmNlb2YgQ2VsbFNlbGVjdGlvbilcbiAgICAgICAgc3RhdGUuc2VsZWN0aW9uLmZvckVhY2hDZWxsKChub2RlLCBwb3MpID0+IHtcbiAgICAgICAgICBpZiAobm9kZS5hdHRyc1tuYW1lXSAhPT0gdmFsdWUpXG4gICAgICAgICAgICB0ci5zZXROb2RlTWFya3VwKHBvcywgbnVsbCwge1xuICAgICAgICAgICAgICAuLi5ub2RlLmF0dHJzLFxuICAgICAgICAgICAgICBbbmFtZV06IHZhbHVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgZWxzZVxuICAgICAgICB0ci5zZXROb2RlTWFya3VwKCRjZWxsLnBvcywgbnVsbCwge1xuICAgICAgICAgIC4uLiRjZWxsLm5vZGVBZnRlciEuYXR0cnMsXG4gICAgICAgICAgW25hbWVdOiB2YWx1ZSxcbiAgICAgICAgfSk7XG4gICAgICBkaXNwYXRjaCh0cik7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xufVxuXG5mdW5jdGlvbiBkZXByZWNhdGVkX3RvZ2dsZUhlYWRlcih0eXBlOiBUb2dnbGVIZWFkZXJUeXBlKTogQ29tbWFuZCB7XG4gIHJldHVybiBmdW5jdGlvbiAoc3RhdGUsIGRpc3BhdGNoKSB7XG4gICAgaWYgKCFpc0luVGFibGUoc3RhdGUpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICBjb25zdCB0eXBlcyA9IHRhYmxlTm9kZVR5cGVzKHN0YXRlLnNjaGVtYSk7XG4gICAgICBjb25zdCByZWN0ID0gc2VsZWN0ZWRSZWN0KHN0YXRlKSxcbiAgICAgICAgdHIgPSBzdGF0ZS50cjtcbiAgICAgIGNvbnN0IGNlbGxzID0gcmVjdC5tYXAuY2VsbHNJblJlY3QoXG4gICAgICAgIHR5cGUgPT0gJ2NvbHVtbidcbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgbGVmdDogcmVjdC5sZWZ0LFxuICAgICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICAgIHJpZ2h0OiByZWN0LnJpZ2h0LFxuICAgICAgICAgICAgICBib3R0b206IHJlY3QubWFwLmhlaWdodCxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IHR5cGUgPT0gJ3JvdydcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIGxlZnQ6IDAsXG4gICAgICAgICAgICAgICAgdG9wOiByZWN0LnRvcCxcbiAgICAgICAgICAgICAgICByaWdodDogcmVjdC5tYXAud2lkdGgsXG4gICAgICAgICAgICAgICAgYm90dG9tOiByZWN0LmJvdHRvbSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiByZWN0LFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG5vZGVzID0gY2VsbHMubWFwKChwb3MpID0+IHJlY3QudGFibGUubm9kZUF0KHBvcykhKTtcbiAgICAgIGZvciAoXG4gICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgaSA8IGNlbGxzLmxlbmd0aDtcbiAgICAgICAgaSsrIC8vIFJlbW92ZSBoZWFkZXJzLCBpZiBhbnlcbiAgICAgIClcbiAgICAgICAgaWYgKG5vZGVzW2ldLnR5cGUgPT0gdHlwZXMuaGVhZGVyX2NlbGwpXG4gICAgICAgICAgdHIuc2V0Tm9kZU1hcmt1cChcbiAgICAgICAgICAgIHJlY3QudGFibGVTdGFydCArIGNlbGxzW2ldLFxuICAgICAgICAgICAgdHlwZXMuY2VsbCxcbiAgICAgICAgICAgIG5vZGVzW2ldLmF0dHJzLFxuICAgICAgICAgICk7XG4gICAgICBpZiAodHIuc3RlcHMubGVuZ3RoID09PSAwKVxuICAgICAgICBmb3IgKFxuICAgICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgICBpIDwgY2VsbHMubGVuZ3RoO1xuICAgICAgICAgIGkrKyAvLyBObyBoZWFkZXJzIHJlbW92ZWQsIGFkZCBpbnN0ZWFkXG4gICAgICAgIClcbiAgICAgICAgICB0ci5zZXROb2RlTWFya3VwKFxuICAgICAgICAgICAgcmVjdC50YWJsZVN0YXJ0ICsgY2VsbHNbaV0sXG4gICAgICAgICAgICB0eXBlcy5oZWFkZXJfY2VsbCxcbiAgICAgICAgICAgIG5vZGVzW2ldLmF0dHJzLFxuICAgICAgICAgICk7XG4gICAgICBkaXNwYXRjaCh0cik7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xufVxuXG5mdW5jdGlvbiBpc0hlYWRlckVuYWJsZWRCeVR5cGUoXG4gIHR5cGU6ICdyb3cnIHwgJ2NvbHVtbicsXG4gIHJlY3Q6IFRhYmxlUmVjdCxcbiAgdHlwZXM6IFJlY29yZDxzdHJpbmcsIE5vZGVUeXBlPixcbik6IGJvb2xlYW4ge1xuICAvLyBHZXQgY2VsbCBwb3NpdGlvbnMgZm9yIGZpcnN0IHJvdyBvciBmaXJzdCBjb2x1bW5cbiAgY29uc3QgY2VsbFBvc2l0aW9ucyA9IHJlY3QubWFwLmNlbGxzSW5SZWN0KHtcbiAgICBsZWZ0OiAwLFxuICAgIHRvcDogMCxcbiAgICByaWdodDogdHlwZSA9PSAncm93JyA/IHJlY3QubWFwLndpZHRoIDogMSxcbiAgICBib3R0b206IHR5cGUgPT0gJ2NvbHVtbicgPyByZWN0Lm1hcC5oZWlnaHQgOiAxLFxuICB9KTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGNlbGxQb3NpdGlvbnMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjZWxsID0gcmVjdC50YWJsZS5ub2RlQXQoY2VsbFBvc2l0aW9uc1tpXSk7XG4gICAgaWYgKGNlbGwgJiYgY2VsbC50eXBlICE9PSB0eXBlcy5oZWFkZXJfY2VsbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgVG9nZ2xlSGVhZGVyVHlwZSA9ICdjb2x1bW4nIHwgJ3JvdycgfCAnY2VsbCc7XG5cbi8qKlxuICogVG9nZ2xlcyBiZXR3ZWVuIHJvdy9jb2x1bW4gaGVhZGVyIGFuZCBub3JtYWwgY2VsbHMgKE9ubHkgYXBwbGllcyB0byBmaXJzdCByb3cvY29sdW1uKS5cbiAqIEZvciBkZXByZWNhdGVkIGJlaGF2aW9yIHBhc3MgYHVzZURlcHJlY2F0ZWRMb2dpY2AgaW4gb3B0aW9ucyB3aXRoIHRydWUuXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gdG9nZ2xlSGVhZGVyKFxuICB0eXBlOiBUb2dnbGVIZWFkZXJUeXBlLFxuICBvcHRpb25zPzogeyB1c2VEZXByZWNhdGVkTG9naWM6IGJvb2xlYW4gfSxcbik6IENvbW1hbmQge1xuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7IHVzZURlcHJlY2F0ZWRMb2dpYzogZmFsc2UgfTtcblxuICBpZiAob3B0aW9ucy51c2VEZXByZWNhdGVkTG9naWMpIHJldHVybiBkZXByZWNhdGVkX3RvZ2dsZUhlYWRlcih0eXBlKTtcblxuICByZXR1cm4gZnVuY3Rpb24gKHN0YXRlLCBkaXNwYXRjaCkge1xuICAgIGlmICghaXNJblRhYmxlKHN0YXRlKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgY29uc3QgdHlwZXMgPSB0YWJsZU5vZGVUeXBlcyhzdGF0ZS5zY2hlbWEpO1xuICAgICAgY29uc3QgcmVjdCA9IHNlbGVjdGVkUmVjdChzdGF0ZSksXG4gICAgICAgIHRyID0gc3RhdGUudHI7XG5cbiAgICAgIGNvbnN0IGlzSGVhZGVyUm93RW5hYmxlZCA9IGlzSGVhZGVyRW5hYmxlZEJ5VHlwZSgncm93JywgcmVjdCwgdHlwZXMpO1xuICAgICAgY29uc3QgaXNIZWFkZXJDb2x1bW5FbmFibGVkID0gaXNIZWFkZXJFbmFibGVkQnlUeXBlKFxuICAgICAgICAnY29sdW1uJyxcbiAgICAgICAgcmVjdCxcbiAgICAgICAgdHlwZXMsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpc0hlYWRlckVuYWJsZWQgPVxuICAgICAgICB0eXBlID09PSAnY29sdW1uJ1xuICAgICAgICAgID8gaXNIZWFkZXJSb3dFbmFibGVkXG4gICAgICAgICAgOiB0eXBlID09PSAncm93J1xuICAgICAgICAgICAgPyBpc0hlYWRlckNvbHVtbkVuYWJsZWRcbiAgICAgICAgICAgIDogZmFsc2U7XG5cbiAgICAgIGNvbnN0IHNlbGVjdGlvblN0YXJ0c0F0ID0gaXNIZWFkZXJFbmFibGVkID8gMSA6IDA7XG5cbiAgICAgIGNvbnN0IGNlbGxzUmVjdCA9XG4gICAgICAgIHR5cGUgPT0gJ2NvbHVtbidcbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgbGVmdDogMCxcbiAgICAgICAgICAgICAgdG9wOiBzZWxlY3Rpb25TdGFydHNBdCxcbiAgICAgICAgICAgICAgcmlnaHQ6IDEsXG4gICAgICAgICAgICAgIGJvdHRvbTogcmVjdC5tYXAuaGVpZ2h0LFxuICAgICAgICAgICAgfVxuICAgICAgICAgIDogdHlwZSA9PSAncm93J1xuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgbGVmdDogc2VsZWN0aW9uU3RhcnRzQXQsXG4gICAgICAgICAgICAgICAgdG9wOiAwLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiByZWN0Lm1hcC53aWR0aCxcbiAgICAgICAgICAgICAgICBib3R0b206IDEsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDogcmVjdDtcblxuICAgICAgY29uc3QgbmV3VHlwZSA9XG4gICAgICAgIHR5cGUgPT0gJ2NvbHVtbidcbiAgICAgICAgICA/IGlzSGVhZGVyQ29sdW1uRW5hYmxlZFxuICAgICAgICAgICAgPyB0eXBlcy5jZWxsXG4gICAgICAgICAgICA6IHR5cGVzLmhlYWRlcl9jZWxsXG4gICAgICAgICAgOiB0eXBlID09ICdyb3cnXG4gICAgICAgICAgICA/IGlzSGVhZGVyUm93RW5hYmxlZFxuICAgICAgICAgICAgICA/IHR5cGVzLmNlbGxcbiAgICAgICAgICAgICAgOiB0eXBlcy5oZWFkZXJfY2VsbFxuICAgICAgICAgICAgOiB0eXBlcy5jZWxsO1xuXG4gICAgICByZWN0Lm1hcC5jZWxsc0luUmVjdChjZWxsc1JlY3QpLmZvckVhY2goKHJlbGF0aXZlQ2VsbFBvcykgPT4ge1xuICAgICAgICBjb25zdCBjZWxsUG9zID0gcmVsYXRpdmVDZWxsUG9zICsgcmVjdC50YWJsZVN0YXJ0O1xuICAgICAgICBjb25zdCBjZWxsID0gdHIuZG9jLm5vZGVBdChjZWxsUG9zKTtcblxuICAgICAgICBpZiAoY2VsbCkge1xuICAgICAgICAgIHRyLnNldE5vZGVNYXJrdXAoY2VsbFBvcywgbmV3VHlwZSwgY2VsbC5hdHRycyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBkaXNwYXRjaCh0cik7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xufVxuXG4vKipcbiAqIFRvZ2dsZXMgd2hldGhlciB0aGUgc2VsZWN0ZWQgcm93IGNvbnRhaW5zIGhlYWRlciBjZWxscy5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCB0b2dnbGVIZWFkZXJSb3c6IENvbW1hbmQgPSB0b2dnbGVIZWFkZXIoJ3JvdycsIHtcbiAgdXNlRGVwcmVjYXRlZExvZ2ljOiB0cnVlLFxufSk7XG5cbi8qKlxuICogVG9nZ2xlcyB3aGV0aGVyIHRoZSBzZWxlY3RlZCBjb2x1bW4gY29udGFpbnMgaGVhZGVyIGNlbGxzLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IHRvZ2dsZUhlYWRlckNvbHVtbjogQ29tbWFuZCA9IHRvZ2dsZUhlYWRlcignY29sdW1uJywge1xuICB1c2VEZXByZWNhdGVkTG9naWM6IHRydWUsXG59KTtcblxuLyoqXG4gKiBUb2dnbGVzIHdoZXRoZXIgdGhlIHNlbGVjdGVkIGNlbGxzIGFyZSBoZWFkZXIgY2VsbHMuXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgdG9nZ2xlSGVhZGVyQ2VsbDogQ29tbWFuZCA9IHRvZ2dsZUhlYWRlcignY2VsbCcsIHtcbiAgdXNlRGVwcmVjYXRlZExvZ2ljOiB0cnVlLFxufSk7XG5cbmZ1bmN0aW9uIGZpbmROZXh0Q2VsbCgkY2VsbDogUmVzb2x2ZWRQb3MsIGRpcjogRGlyZWN0aW9uKTogbnVtYmVyIHwgbnVsbCB7XG4gIGlmIChkaXIgPCAwKSB7XG4gICAgY29uc3QgYmVmb3JlID0gJGNlbGwubm9kZUJlZm9yZTtcbiAgICBpZiAoYmVmb3JlKSByZXR1cm4gJGNlbGwucG9zIC0gYmVmb3JlLm5vZGVTaXplO1xuICAgIGZvciAoXG4gICAgICBsZXQgcm93ID0gJGNlbGwuaW5kZXgoLTEpIC0gMSwgcm93RW5kID0gJGNlbGwuYmVmb3JlKCk7XG4gICAgICByb3cgPj0gMDtcbiAgICAgIHJvdy0tXG4gICAgKSB7XG4gICAgICBjb25zdCByb3dOb2RlID0gJGNlbGwubm9kZSgtMSkuY2hpbGQocm93KTtcbiAgICAgIGNvbnN0IGxhc3RDaGlsZCA9IHJvd05vZGUubGFzdENoaWxkO1xuICAgICAgaWYgKGxhc3RDaGlsZCkge1xuICAgICAgICByZXR1cm4gcm93RW5kIC0gMSAtIGxhc3RDaGlsZC5ub2RlU2l6ZTtcbiAgICAgIH1cbiAgICAgIHJvd0VuZCAtPSByb3dOb2RlLm5vZGVTaXplO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoJGNlbGwuaW5kZXgoKSA8ICRjZWxsLnBhcmVudC5jaGlsZENvdW50IC0gMSkge1xuICAgICAgcmV0dXJuICRjZWxsLnBvcyArICRjZWxsLm5vZGVBZnRlciEubm9kZVNpemU7XG4gICAgfVxuICAgIGNvbnN0IHRhYmxlID0gJGNlbGwubm9kZSgtMSk7XG4gICAgZm9yIChcbiAgICAgIGxldCByb3cgPSAkY2VsbC5pbmRleEFmdGVyKC0xKSwgcm93U3RhcnQgPSAkY2VsbC5hZnRlcigpO1xuICAgICAgcm93IDwgdGFibGUuY2hpbGRDb3VudDtcbiAgICAgIHJvdysrXG4gICAgKSB7XG4gICAgICBjb25zdCByb3dOb2RlID0gdGFibGUuY2hpbGQocm93KTtcbiAgICAgIGlmIChyb3dOb2RlLmNoaWxkQ291bnQpIHJldHVybiByb3dTdGFydCArIDE7XG4gICAgICByb3dTdGFydCArPSByb3dOb2RlLm5vZGVTaXplO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgY29tbWFuZCBmb3Igc2VsZWN0aW5nIHRoZSBuZXh0IChkaXJlY3Rpb249MSkgb3IgcHJldmlvdXNcbiAqIChkaXJlY3Rpb249LTEpIGNlbGwgaW4gYSB0YWJsZS5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnb1RvTmV4dENlbGwoZGlyZWN0aW9uOiBEaXJlY3Rpb24pOiBDb21tYW5kIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChzdGF0ZSwgZGlzcGF0Y2gpIHtcbiAgICBpZiAoIWlzSW5UYWJsZShzdGF0ZSkpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBjZWxsID0gZmluZE5leHRDZWxsKHNlbGVjdGlvbkNlbGwoc3RhdGUpLCBkaXJlY3Rpb24pO1xuICAgIGlmIChjZWxsID09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgIGNvbnN0ICRjZWxsID0gc3RhdGUuZG9jLnJlc29sdmUoY2VsbCk7XG4gICAgICBkaXNwYXRjaChcbiAgICAgICAgc3RhdGUudHJcbiAgICAgICAgICAuc2V0U2VsZWN0aW9uKFRleHRTZWxlY3Rpb24uYmV0d2VlbigkY2VsbCwgbW92ZUNlbGxGb3J3YXJkKCRjZWxsKSkpXG4gICAgICAgICAgLnNjcm9sbEludG9WaWV3KCksXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcbn1cblxuLyoqXG4gKiBEZWxldGVzIHRoZSB0YWJsZSBhcm91bmQgdGhlIHNlbGVjdGlvbiwgaWYgYW55LlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlbGV0ZVRhYmxlKFxuICBzdGF0ZTogRWRpdG9yU3RhdGUsXG4gIGRpc3BhdGNoPzogKHRyOiBUcmFuc2FjdGlvbikgPT4gdm9pZCxcbik6IGJvb2xlYW4ge1xuICBjb25zdCAkcG9zID0gc3RhdGUuc2VsZWN0aW9uLiRhbmNob3I7XG4gIGZvciAobGV0IGQgPSAkcG9zLmRlcHRoOyBkID4gMDsgZC0tKSB7XG4gICAgY29uc3Qgbm9kZSA9ICRwb3Mubm9kZShkKTtcbiAgICBpZiAobm9kZS50eXBlLnNwZWMudGFibGVSb2xlID09ICd0YWJsZScpIHtcbiAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgZGlzcGF0Y2goXG4gICAgICAgICAgc3RhdGUudHIuZGVsZXRlKCRwb3MuYmVmb3JlKGQpLCAkcG9zLmFmdGVyKGQpKS5zY3JvbGxJbnRvVmlldygpLFxuICAgICAgICApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBEZWxldGVzIHRoZSBjb250ZW50IG9mIHRoZSBzZWxlY3RlZCBjZWxscywgaWYgdGhleSBhcmUgbm90IGVtcHR5LlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlbGV0ZUNlbGxTZWxlY3Rpb24oXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgZGlzcGF0Y2g/OiAodHI6IFRyYW5zYWN0aW9uKSA9PiB2b2lkLFxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IHNlbCA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgaWYgKCEoc2VsIGluc3RhbmNlb2YgQ2VsbFNlbGVjdGlvbikpIHJldHVybiBmYWxzZTtcbiAgaWYgKGRpc3BhdGNoKSB7XG4gICAgY29uc3QgdHIgPSBzdGF0ZS50cjtcbiAgICBjb25zdCBiYXNlQ29udGVudCA9IHRhYmxlTm9kZVR5cGVzKHN0YXRlLnNjaGVtYSkuY2VsbC5jcmVhdGVBbmRGaWxsKCkhXG4gICAgICAuY29udGVudDtcbiAgICBzZWwuZm9yRWFjaENlbGwoKGNlbGwsIHBvcykgPT4ge1xuICAgICAgaWYgKCFjZWxsLmNvbnRlbnQuZXEoYmFzZUNvbnRlbnQpKVxuICAgICAgICB0ci5yZXBsYWNlKFxuICAgICAgICAgIHRyLm1hcHBpbmcubWFwKHBvcyArIDEpLFxuICAgICAgICAgIHRyLm1hcHBpbmcubWFwKHBvcyArIGNlbGwubm9kZVNpemUgLSAxKSxcbiAgICAgICAgICBuZXcgU2xpY2UoYmFzZUNvbnRlbnQsIDAsIDApLFxuICAgICAgICApO1xuICAgIH0pO1xuICAgIGlmICh0ci5kb2NDaGFuZ2VkKSBkaXNwYXRjaCh0cik7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgbW92ZVRhYmxlUm93XG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgaW50ZXJmYWNlIE1vdmVUYWJsZVJvd09wdGlvbnMge1xuICAvKipcbiAgICogVGhlIHNvdXJjZSByb3cgaW5kZXggdG8gbW92ZSBmcm9tLlxuICAgKi9cbiAgZnJvbTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgZGVzdGluYXRpb24gcm93IGluZGV4IHRvIG1vdmUgdG8uXG4gICAqL1xuICB0bzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHNlbGVjdCB0aGUgbW92ZWQgcm93IGFmdGVyIHRoZSBvcGVyYXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHNlbGVjdD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIHBvc2l0aW9uIHRvIHJlc29sdmUgdGFibGUgZnJvbS4gSWYgbm90IHByb3ZpZGVkLCB1c2VzIHRoZSBjdXJyZW50IHNlbGVjdGlvbi5cbiAgICovXG4gIHBvcz86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBNb3ZlIGEgdGFibGUgcm93IGZyb20gaW5kZXggYGZyb21gIHRvIGluZGV4IGB0b2AuXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgZnVuY3Rpb24gbW92ZVRhYmxlUm93KG9wdGlvbnM6IE1vdmVUYWJsZVJvd09wdGlvbnMpOiBDb21tYW5kIHtcbiAgcmV0dXJuIChzdGF0ZSwgZGlzcGF0Y2gpID0+IHtcbiAgICBjb25zdCB7XG4gICAgICBmcm9tOiBvcmlnaW5JbmRleCxcbiAgICAgIHRvOiB0YXJnZXRJbmRleCxcbiAgICAgIHNlbGVjdCA9IHRydWUsXG4gICAgICBwb3MgPSBzdGF0ZS5zZWxlY3Rpb24uZnJvbSxcbiAgICB9ID0gb3B0aW9ucztcbiAgICBjb25zdCB0ciA9IHN0YXRlLnRyO1xuICAgIGlmIChtb3ZlUm93KHsgdHIsIG9yaWdpbkluZGV4LCB0YXJnZXRJbmRleCwgc2VsZWN0LCBwb3MgfSkpIHtcbiAgICAgIGRpc3BhdGNoPy4odHIpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfTtcbn1cblxuLyoqXG4gKiBPcHRpb25zIGZvciBtb3ZlVGFibGVDb2x1bW5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTW92ZVRhYmxlQ29sdW1uT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgc291cmNlIGNvbHVtbiBpbmRleCB0byBtb3ZlIGZyb20uXG4gICAqL1xuICBmcm9tOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXN0aW5hdGlvbiBjb2x1bW4gaW5kZXggdG8gbW92ZSB0by5cbiAgICovXG4gIHRvOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc2VsZWN0IHRoZSBtb3ZlZCBjb2x1bW4gYWZ0ZXIgdGhlIG9wZXJhdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgc2VsZWN0PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogT3B0aW9uYWwgcG9zaXRpb24gdG8gcmVzb2x2ZSB0YWJsZSBmcm9tLiBJZiBub3QgcHJvdmlkZWQsIHVzZXMgdGhlIGN1cnJlbnQgc2VsZWN0aW9uLlxuICAgKi9cbiAgcG9zPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIE1vdmUgYSB0YWJsZSBjb2x1bW4gZnJvbSBpbmRleCBgZnJvbWAgdG8gaW5kZXggYHRvYC5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb3ZlVGFibGVDb2x1bW4ob3B0aW9uczogTW92ZVRhYmxlQ29sdW1uT3B0aW9ucyk6IENvbW1hbmQge1xuICByZXR1cm4gKHN0YXRlLCBkaXNwYXRjaCkgPT4ge1xuICAgIGNvbnN0IHtcbiAgICAgIGZyb206IG9yaWdpbkluZGV4LFxuICAgICAgdG86IHRhcmdldEluZGV4LFxuICAgICAgc2VsZWN0ID0gdHJ1ZSxcbiAgICAgIHBvcyA9IHN0YXRlLnNlbGVjdGlvbi5mcm9tLFxuICAgIH0gPSBvcHRpb25zO1xuICAgIGNvbnN0IHRyID0gc3RhdGUudHI7XG4gICAgaWYgKG1vdmVDb2x1bW4oeyB0ciwgb3JpZ2luSW5kZXgsIHRhcmdldEluZGV4LCBzZWxlY3QsIHBvcyB9KSkge1xuICAgICAgZGlzcGF0Y2g/Lih0cik7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9O1xufVxuIiwgIi8vIFV0aWxpdGllcyB1c2VkIGZvciBjb3B5L3Bhc3RlIGhhbmRsaW5nLlxuLy9cbi8vIFRoaXMgbW9kdWxlIGhhbmRsZXMgcGFzdGluZyBjZWxsIGNvbnRlbnQgaW50byB0YWJsZXMsIG9yIHBhc3Rpbmdcbi8vIGFueXRoaW5nIGludG8gYSBjZWxsIHNlbGVjdGlvbiwgYXMgcmVwbGFjaW5nIGEgYmxvY2sgb2YgY2VsbHMgd2l0aFxuLy8gdGhlIGNvbnRlbnQgb2YgdGhlIHNlbGVjdGlvbi4gV2hlbiBwYXN0aW5nIGNlbGxzIGludG8gYSBjZWxsLCB0aGF0XG4vLyBpbnZvbHZlcyBwbGFjaW5nIHRoZSBibG9jayBvZiBwYXN0ZWQgY29udGVudCBzbyB0aGF0IGl0cyB0b3AgbGVmdFxuLy8gYWxpZ25zIHdpdGggdGhlIHNlbGVjdGlvbiBjZWxsLCBvcHRpb25hbGx5IGV4dGVuZGluZyB0aGUgdGFibGUgdG9cbi8vIHRoZSByaWdodCBvciBib3R0b20gdG8gbWFrZSBzdXJlIGl0IGlzIGxhcmdlIGVub3VnaC4gUGFzdGluZyBpbnRvIGFcbi8vIGNlbGwgc2VsZWN0aW9uIGlzIGRpZmZlcmVudCwgaGVyZSB0aGUgY2VsbHMgaW4gdGhlIHNlbGVjdGlvbiBhcmVcbi8vIGNsaXBwZWQgdG8gdGhlIHNlbGVjdGlvbidzIHJlY3RhbmdsZSwgb3B0aW9uYWxseSByZXBlYXRpbmcgdGhlXG4vLyBwYXN0ZWQgY2VsbHMgd2hlbiB0aGV5IGFyZSBzbWFsbGVyIHRoYW4gdGhlIHNlbGVjdGlvbi5cblxuaW1wb3J0IHR5cGUgeyBOb2RlLCBOb2RlVHlwZSwgU2NoZW1hIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuaW1wb3J0IHsgRnJhZ21lbnQsIFNsaWNlIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuaW1wb3J0IHR5cGUgeyBFZGl0b3JTdGF0ZSwgVHJhbnNhY3Rpb24gfSBmcm9tICdwcm9zZW1pcnJvci1zdGF0ZSc7XG5pbXBvcnQgeyBUcmFuc2Zvcm0gfSBmcm9tICdwcm9zZW1pcnJvci10cmFuc2Zvcm0nO1xuXG5pbXBvcnQgeyBDZWxsU2VsZWN0aW9uIH0gZnJvbSAnLi9jZWxsc2VsZWN0aW9uJztcbmltcG9ydCB7IHRhYmxlTm9kZVR5cGVzIH0gZnJvbSAnLi9zY2hlbWEnO1xuaW1wb3J0IHR5cGUgeyBDb2xXaWR0aHMsIFJlY3QgfSBmcm9tICcuL3RhYmxlbWFwJztcbmltcG9ydCB7IFRhYmxlTWFwIH0gZnJvbSAnLi90YWJsZW1hcCc7XG5pbXBvcnQgdHlwZSB7IENlbGxBdHRycyB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgeyByZW1vdmVDb2xTcGFuIH0gZnJvbSAnLi91dGlsJztcblxuLyoqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IHR5cGUgQXJlYSA9IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXI7IHJvd3M6IEZyYWdtZW50W10gfTtcblxuLy8gVXRpbGl0aWVzIHRvIGhlbHAgd2l0aCBjb3B5aW5nIGFuZCBwYXN0aW5nIHRhYmxlIGNlbGxzXG5cbi8qKlxuICogR2V0IGEgcmVjdGFuZ3VsYXIgYXJlYSBvZiBjZWxscyBmcm9tIGEgc2xpY2UsIG9yIG51bGwgaWYgdGhlIG91dGVyXG4gKiBub2RlcyBvZiB0aGUgc2xpY2UgYXJlbid0IHRhYmxlIGNlbGxzIG9yIHJvd3MuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXN0ZWRDZWxscyhzbGljZTogU2xpY2UpOiBBcmVhIHwgbnVsbCB7XG4gIGlmIChzbGljZS5zaXplID09PSAwKSByZXR1cm4gbnVsbDtcbiAgbGV0IHsgY29udGVudCwgb3BlblN0YXJ0LCBvcGVuRW5kIH0gPSBzbGljZTtcbiAgd2hpbGUgKFxuICAgIGNvbnRlbnQuY2hpbGRDb3VudCA9PSAxICYmXG4gICAgKChvcGVuU3RhcnQgPiAwICYmIG9wZW5FbmQgPiAwKSB8fFxuICAgICAgY29udGVudC5jaGlsZCgwKS50eXBlLnNwZWMudGFibGVSb2xlID09ICd0YWJsZScpXG4gICkge1xuICAgIG9wZW5TdGFydC0tO1xuICAgIG9wZW5FbmQtLTtcbiAgICBjb250ZW50ID0gY29udGVudC5jaGlsZCgwKS5jb250ZW50O1xuICB9XG4gIGNvbnN0IGZpcnN0ID0gY29udGVudC5jaGlsZCgwKTtcbiAgY29uc3Qgcm9sZSA9IGZpcnN0LnR5cGUuc3BlYy50YWJsZVJvbGU7XG4gIGNvbnN0IHNjaGVtYSA9IGZpcnN0LnR5cGUuc2NoZW1hLFxuICAgIHJvd3MgPSBbXTtcbiAgaWYgKHJvbGUgPT0gJ3JvdycpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbnRlbnQuY2hpbGRDb3VudDsgaSsrKSB7XG4gICAgICBsZXQgY2VsbHMgPSBjb250ZW50LmNoaWxkKGkpLmNvbnRlbnQ7XG4gICAgICBjb25zdCBsZWZ0ID0gaSA/IDAgOiBNYXRoLm1heCgwLCBvcGVuU3RhcnQgLSAxKTtcbiAgICAgIGNvbnN0IHJpZ2h0ID0gaSA8IGNvbnRlbnQuY2hpbGRDb3VudCAtIDEgPyAwIDogTWF0aC5tYXgoMCwgb3BlbkVuZCAtIDEpO1xuICAgICAgaWYgKGxlZnQgfHwgcmlnaHQpXG4gICAgICAgIGNlbGxzID0gZml0U2xpY2UoXG4gICAgICAgICAgdGFibGVOb2RlVHlwZXMoc2NoZW1hKS5yb3csXG4gICAgICAgICAgbmV3IFNsaWNlKGNlbGxzLCBsZWZ0LCByaWdodCksXG4gICAgICAgICkuY29udGVudDtcbiAgICAgIHJvd3MucHVzaChjZWxscyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHJvbGUgPT0gJ2NlbGwnIHx8IHJvbGUgPT0gJ2hlYWRlcl9jZWxsJykge1xuICAgIHJvd3MucHVzaChcbiAgICAgIG9wZW5TdGFydCB8fCBvcGVuRW5kXG4gICAgICAgID8gZml0U2xpY2UoXG4gICAgICAgICAgICB0YWJsZU5vZGVUeXBlcyhzY2hlbWEpLnJvdyxcbiAgICAgICAgICAgIG5ldyBTbGljZShjb250ZW50LCBvcGVuU3RhcnQsIG9wZW5FbmQpLFxuICAgICAgICAgICkuY29udGVudFxuICAgICAgICA6IGNvbnRlbnQsXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4gZW5zdXJlUmVjdGFuZ3VsYXIoc2NoZW1hLCByb3dzKTtcbn1cblxuLy8gQ29tcHV0ZSB0aGUgd2lkdGggYW5kIGhlaWdodCBvZiBhIHNldCBvZiBjZWxscywgYW5kIG1ha2Ugc3VyZSBlYWNoXG4vLyByb3cgaGFzIHRoZSBzYW1lIG51bWJlciBvZiBjZWxscy5cbmZ1bmN0aW9uIGVuc3VyZVJlY3Rhbmd1bGFyKHNjaGVtYTogU2NoZW1hLCByb3dzOiBGcmFnbWVudFtdKTogQXJlYSB7XG4gIGNvbnN0IHdpZHRoczogQ29sV2lkdGhzID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHJvdyA9IHJvd3NbaV07XG4gICAgZm9yIChsZXQgaiA9IHJvdy5jaGlsZENvdW50IC0gMTsgaiA+PSAwOyBqLS0pIHtcbiAgICAgIGNvbnN0IHsgcm93c3BhbiwgY29sc3BhbiB9ID0gcm93LmNoaWxkKGopLmF0dHJzO1xuICAgICAgZm9yIChsZXQgciA9IGk7IHIgPCBpICsgcm93c3BhbjsgcisrKVxuICAgICAgICB3aWR0aHNbcl0gPSAod2lkdGhzW3JdIHx8IDApICsgY29sc3BhbjtcbiAgICB9XG4gIH1cbiAgbGV0IHdpZHRoID0gMDtcbiAgZm9yIChsZXQgciA9IDA7IHIgPCB3aWR0aHMubGVuZ3RoOyByKyspIHdpZHRoID0gTWF0aC5tYXgod2lkdGgsIHdpZHRoc1tyXSk7XG4gIGZvciAobGV0IHIgPSAwOyByIDwgd2lkdGhzLmxlbmd0aDsgcisrKSB7XG4gICAgaWYgKHIgPj0gcm93cy5sZW5ndGgpIHJvd3MucHVzaChGcmFnbWVudC5lbXB0eSk7XG4gICAgaWYgKHdpZHRoc1tyXSA8IHdpZHRoKSB7XG4gICAgICBjb25zdCBlbXB0eSA9IHRhYmxlTm9kZVR5cGVzKHNjaGVtYSkuY2VsbC5jcmVhdGVBbmRGaWxsKCkhO1xuICAgICAgY29uc3QgY2VsbHMgPSBbXTtcbiAgICAgIGZvciAobGV0IGkgPSB3aWR0aHNbcl07IGkgPCB3aWR0aDsgaSsrKSB7XG4gICAgICAgIGNlbGxzLnB1c2goZW1wdHkpO1xuICAgICAgfVxuICAgICAgcm93c1tyXSA9IHJvd3Nbcl0uYXBwZW5kKEZyYWdtZW50LmZyb20oY2VsbHMpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHsgaGVpZ2h0OiByb3dzLmxlbmd0aCwgd2lkdGgsIHJvd3MgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpdFNsaWNlKG5vZGVUeXBlOiBOb2RlVHlwZSwgc2xpY2U6IFNsaWNlKTogTm9kZSB7XG4gIGNvbnN0IG5vZGUgPSBub2RlVHlwZS5jcmVhdGVBbmRGaWxsKCkhO1xuICBjb25zdCB0ciA9IG5ldyBUcmFuc2Zvcm0obm9kZSkucmVwbGFjZSgwLCBub2RlLmNvbnRlbnQuc2l6ZSwgc2xpY2UpO1xuICByZXR1cm4gdHIuZG9jO1xufVxuXG4vKipcbiAqIENsaXAgb3IgZXh0ZW5kIChyZXBlYXQpIHRoZSBnaXZlbiBzZXQgb2YgY2VsbHMgdG8gY292ZXIgdGhlIGdpdmVuXG4gKiB3aWR0aCBhbmQgaGVpZ2h0LiBXaWxsIGNsaXAgcm93c3Bhbi9jb2xzcGFuIGNlbGxzIGF0IHRoZSBlZGdlcyB3aGVuXG4gKiB0aGV5IHN0aWNrIG91dC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsaXBDZWxscyhcbiAgeyB3aWR0aCwgaGVpZ2h0LCByb3dzIH06IEFyZWEsXG4gIG5ld1dpZHRoOiBudW1iZXIsXG4gIG5ld0hlaWdodDogbnVtYmVyLFxuKTogQXJlYSB7XG4gIGlmICh3aWR0aCAhPSBuZXdXaWR0aCkge1xuICAgIGNvbnN0IGFkZGVkOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IG5ld1Jvd3M6IEZyYWdtZW50W10gPSBbXTtcbiAgICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCByb3dzLmxlbmd0aDsgcm93KyspIHtcbiAgICAgIGNvbnN0IGZyYWcgPSByb3dzW3Jvd10sXG4gICAgICAgIGNlbGxzID0gW107XG4gICAgICBmb3IgKGxldCBjb2wgPSBhZGRlZFtyb3ddIHx8IDAsIGkgPSAwOyBjb2wgPCBuZXdXaWR0aDsgaSsrKSB7XG4gICAgICAgIGxldCBjZWxsID0gZnJhZy5jaGlsZChpICUgZnJhZy5jaGlsZENvdW50KTtcbiAgICAgICAgaWYgKGNvbCArIGNlbGwuYXR0cnMuY29sc3BhbiA+IG5ld1dpZHRoKVxuICAgICAgICAgIGNlbGwgPSBjZWxsLnR5cGUuY3JlYXRlQ2hlY2tlZChcbiAgICAgICAgICAgIHJlbW92ZUNvbFNwYW4oXG4gICAgICAgICAgICAgIGNlbGwuYXR0cnMgYXMgQ2VsbEF0dHJzLFxuICAgICAgICAgICAgICBjZWxsLmF0dHJzLmNvbHNwYW4sXG4gICAgICAgICAgICAgIGNvbCArIGNlbGwuYXR0cnMuY29sc3BhbiAtIG5ld1dpZHRoLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGNlbGwuY29udGVudCxcbiAgICAgICAgICApO1xuICAgICAgICBjZWxscy5wdXNoKGNlbGwpO1xuICAgICAgICBjb2wgKz0gY2VsbC5hdHRycy5jb2xzcGFuO1xuICAgICAgICBmb3IgKGxldCBqID0gMTsgaiA8IGNlbGwuYXR0cnMucm93c3BhbjsgaisrKVxuICAgICAgICAgIGFkZGVkW3JvdyArIGpdID0gKGFkZGVkW3JvdyArIGpdIHx8IDApICsgY2VsbC5hdHRycy5jb2xzcGFuO1xuICAgICAgfVxuICAgICAgbmV3Um93cy5wdXNoKEZyYWdtZW50LmZyb20oY2VsbHMpKTtcbiAgICB9XG4gICAgcm93cyA9IG5ld1Jvd3M7XG4gICAgd2lkdGggPSBuZXdXaWR0aDtcbiAgfVxuXG4gIGlmIChoZWlnaHQgIT0gbmV3SGVpZ2h0KSB7XG4gICAgY29uc3QgbmV3Um93cyA9IFtdO1xuICAgIGZvciAobGV0IHJvdyA9IDAsIGkgPSAwOyByb3cgPCBuZXdIZWlnaHQ7IHJvdysrLCBpKyspIHtcbiAgICAgIGNvbnN0IGNlbGxzID0gW10sXG4gICAgICAgIHNvdXJjZSA9IHJvd3NbaSAlIGhlaWdodF07XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHNvdXJjZS5jaGlsZENvdW50OyBqKyspIHtcbiAgICAgICAgbGV0IGNlbGwgPSBzb3VyY2UuY2hpbGQoaik7XG4gICAgICAgIGlmIChyb3cgKyBjZWxsLmF0dHJzLnJvd3NwYW4gPiBuZXdIZWlnaHQpXG4gICAgICAgICAgY2VsbCA9IGNlbGwudHlwZS5jcmVhdGUoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC4uLmNlbGwuYXR0cnMsXG4gICAgICAgICAgICAgIHJvd3NwYW46IE1hdGgubWF4KDEsIG5ld0hlaWdodCAtIGNlbGwuYXR0cnMucm93c3BhbiksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2VsbC5jb250ZW50LFxuICAgICAgICAgICk7XG4gICAgICAgIGNlbGxzLnB1c2goY2VsbCk7XG4gICAgICB9XG4gICAgICBuZXdSb3dzLnB1c2goRnJhZ21lbnQuZnJvbShjZWxscykpO1xuICAgIH1cbiAgICByb3dzID0gbmV3Um93cztcbiAgICBoZWlnaHQgPSBuZXdIZWlnaHQ7XG4gIH1cblxuICByZXR1cm4geyB3aWR0aCwgaGVpZ2h0LCByb3dzIH07XG59XG5cbi8vIE1ha2Ugc3VyZSBhIHRhYmxlIGhhcyBhdCBsZWFzdCB0aGUgZ2l2ZW4gd2lkdGggYW5kIGhlaWdodC4gUmV0dXJuXG4vLyB0cnVlIGlmIHNvbWV0aGluZyB3YXMgY2hhbmdlZC5cbmZ1bmN0aW9uIGdyb3dUYWJsZShcbiAgdHI6IFRyYW5zYWN0aW9uLFxuICBtYXA6IFRhYmxlTWFwLFxuICB0YWJsZTogTm9kZSxcbiAgc3RhcnQ6IG51bWJlcixcbiAgd2lkdGg6IG51bWJlcixcbiAgaGVpZ2h0OiBudW1iZXIsXG4gIG1hcEZyb206IG51bWJlcixcbik6IGJvb2xlYW4ge1xuICBjb25zdCBzY2hlbWEgPSB0ci5kb2MudHlwZS5zY2hlbWE7XG4gIGNvbnN0IHR5cGVzID0gdGFibGVOb2RlVHlwZXMoc2NoZW1hKTtcbiAgbGV0IGVtcHR5O1xuICBsZXQgZW1wdHlIZWFkO1xuICBpZiAod2lkdGggPiBtYXAud2lkdGgpIHtcbiAgICBmb3IgKGxldCByb3cgPSAwLCByb3dFbmQgPSAwOyByb3cgPCBtYXAuaGVpZ2h0OyByb3crKykge1xuICAgICAgY29uc3Qgcm93Tm9kZSA9IHRhYmxlLmNoaWxkKHJvdyk7XG4gICAgICByb3dFbmQgKz0gcm93Tm9kZS5ub2RlU2l6ZTtcbiAgICAgIGNvbnN0IGNlbGxzOiBOb2RlW10gPSBbXTtcbiAgICAgIGxldCBhZGQ6IE5vZGU7XG4gICAgICBpZiAocm93Tm9kZS5sYXN0Q2hpbGQgPT0gbnVsbCB8fCByb3dOb2RlLmxhc3RDaGlsZC50eXBlID09IHR5cGVzLmNlbGwpXG4gICAgICAgIGFkZCA9IGVtcHR5IHx8IChlbXB0eSA9IHR5cGVzLmNlbGwuY3JlYXRlQW5kRmlsbCgpISk7XG4gICAgICBlbHNlIGFkZCA9IGVtcHR5SGVhZCB8fCAoZW1wdHlIZWFkID0gdHlwZXMuaGVhZGVyX2NlbGwuY3JlYXRlQW5kRmlsbCgpISk7XG4gICAgICBmb3IgKGxldCBpID0gbWFwLndpZHRoOyBpIDwgd2lkdGg7IGkrKykgY2VsbHMucHVzaChhZGQpO1xuICAgICAgdHIuaW5zZXJ0KHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSkubWFwKHJvd0VuZCAtIDEgKyBzdGFydCksIGNlbGxzKTtcbiAgICB9XG4gIH1cbiAgaWYgKGhlaWdodCA+IG1hcC5oZWlnaHQpIHtcbiAgICBjb25zdCBjZWxscyA9IFtdO1xuICAgIGZvciAoXG4gICAgICBsZXQgaSA9IDAsIHN0YXJ0ID0gKG1hcC5oZWlnaHQgLSAxKSAqIG1hcC53aWR0aDtcbiAgICAgIGkgPCBNYXRoLm1heChtYXAud2lkdGgsIHdpZHRoKTtcbiAgICAgIGkrK1xuICAgICkge1xuICAgICAgY29uc3QgaGVhZGVyID1cbiAgICAgICAgaSA+PSBtYXAud2lkdGhcbiAgICAgICAgICA/IGZhbHNlXG4gICAgICAgICAgOiB0YWJsZS5ub2RlQXQobWFwLm1hcFtzdGFydCArIGldKSEudHlwZSA9PSB0eXBlcy5oZWFkZXJfY2VsbDtcbiAgICAgIGNlbGxzLnB1c2goXG4gICAgICAgIGhlYWRlclxuICAgICAgICAgID8gZW1wdHlIZWFkIHx8IChlbXB0eUhlYWQgPSB0eXBlcy5oZWFkZXJfY2VsbC5jcmVhdGVBbmRGaWxsKCkhKVxuICAgICAgICAgIDogZW1wdHkgfHwgKGVtcHR5ID0gdHlwZXMuY2VsbC5jcmVhdGVBbmRGaWxsKCkhKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgZW1wdHlSb3cgPSB0eXBlcy5yb3cuY3JlYXRlKG51bGwsIEZyYWdtZW50LmZyb20oY2VsbHMpKSxcbiAgICAgIHJvd3MgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gbWFwLmhlaWdodDsgaSA8IGhlaWdodDsgaSsrKSByb3dzLnB1c2goZW1wdHlSb3cpO1xuICAgIHRyLmluc2VydCh0ci5tYXBwaW5nLnNsaWNlKG1hcEZyb20pLm1hcChzdGFydCArIHRhYmxlLm5vZGVTaXplIC0gMiksIHJvd3MpO1xuICB9XG4gIHJldHVybiAhIShlbXB0eSB8fCBlbXB0eUhlYWQpO1xufVxuXG4vLyBNYWtlIHN1cmUgdGhlIGdpdmVuIGxpbmUgKGxlZnQsIHRvcCkgdG8gKHJpZ2h0LCB0b3ApIGRvZXNuJ3QgY3Jvc3Ncbi8vIGFueSByb3dzcGFuIGNlbGxzIGJ5IHNwbGl0dGluZyBjZWxscyB0aGF0IGNyb3NzIGl0LiBSZXR1cm4gdHJ1ZSBpZlxuLy8gc29tZXRoaW5nIGNoYW5nZWQuXG5mdW5jdGlvbiBpc29sYXRlSG9yaXpvbnRhbChcbiAgdHI6IFRyYW5zYWN0aW9uLFxuICBtYXA6IFRhYmxlTWFwLFxuICB0YWJsZTogTm9kZSxcbiAgc3RhcnQ6IG51bWJlcixcbiAgbGVmdDogbnVtYmVyLFxuICByaWdodDogbnVtYmVyLFxuICB0b3A6IG51bWJlcixcbiAgbWFwRnJvbTogbnVtYmVyLFxuKTogYm9vbGVhbiB7XG4gIGlmICh0b3AgPT0gMCB8fCB0b3AgPT0gbWFwLmhlaWdodCkgcmV0dXJuIGZhbHNlO1xuICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgZm9yIChsZXQgY29sID0gbGVmdDsgY29sIDwgcmlnaHQ7IGNvbCsrKSB7XG4gICAgY29uc3QgaW5kZXggPSB0b3AgKiBtYXAud2lkdGggKyBjb2wsXG4gICAgICBwb3MgPSBtYXAubWFwW2luZGV4XTtcbiAgICBpZiAobWFwLm1hcFtpbmRleCAtIG1hcC53aWR0aF0gPT0gcG9zKSB7XG4gICAgICBmb3VuZCA9IHRydWU7XG4gICAgICBjb25zdCBjZWxsID0gdGFibGUubm9kZUF0KHBvcykhO1xuICAgICAgY29uc3QgeyB0b3A6IGNlbGxUb3AsIGxlZnQ6IGNlbGxMZWZ0IH0gPSBtYXAuZmluZENlbGwocG9zKTtcbiAgICAgIHRyLnNldE5vZGVNYXJrdXAodHIubWFwcGluZy5zbGljZShtYXBGcm9tKS5tYXAocG9zICsgc3RhcnQpLCBudWxsLCB7XG4gICAgICAgIC4uLmNlbGwuYXR0cnMsXG4gICAgICAgIHJvd3NwYW46IHRvcCAtIGNlbGxUb3AsXG4gICAgICB9KTtcbiAgICAgIHRyLmluc2VydChcbiAgICAgICAgdHIubWFwcGluZy5zbGljZShtYXBGcm9tKS5tYXAobWFwLnBvc2l0aW9uQXQodG9wLCBjZWxsTGVmdCwgdGFibGUpKSxcbiAgICAgICAgY2VsbC50eXBlLmNyZWF0ZUFuZEZpbGwoe1xuICAgICAgICAgIC4uLmNlbGwuYXR0cnMsXG4gICAgICAgICAgcm93c3BhbjogY2VsbFRvcCArIGNlbGwuYXR0cnMucm93c3BhbiAtIHRvcCxcbiAgICAgICAgfSkhLFxuICAgICAgKTtcbiAgICAgIGNvbCArPSBjZWxsLmF0dHJzLmNvbHNwYW4gLSAxO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZm91bmQ7XG59XG5cbi8vIE1ha2Ugc3VyZSB0aGUgZ2l2ZW4gbGluZSAobGVmdCwgdG9wKSB0byAobGVmdCwgYm90dG9tKSBkb2Vzbid0XG4vLyBjcm9zcyBhbnkgY29sc3BhbiBjZWxscyBieSBzcGxpdHRpbmcgY2VsbHMgdGhhdCBjcm9zcyBpdC4gUmV0dXJuXG4vLyB0cnVlIGlmIHNvbWV0aGluZyBjaGFuZ2VkLlxuZnVuY3Rpb24gaXNvbGF0ZVZlcnRpY2FsKFxuICB0cjogVHJhbnNhY3Rpb24sXG4gIG1hcDogVGFibGVNYXAsXG4gIHRhYmxlOiBOb2RlLFxuICBzdGFydDogbnVtYmVyLFxuICB0b3A6IG51bWJlcixcbiAgYm90dG9tOiBudW1iZXIsXG4gIGxlZnQ6IG51bWJlcixcbiAgbWFwRnJvbTogbnVtYmVyLFxuKTogYm9vbGVhbiB7XG4gIGlmIChsZWZ0ID09IDAgfHwgbGVmdCA9PSBtYXAud2lkdGgpIHJldHVybiBmYWxzZTtcbiAgbGV0IGZvdW5kID0gZmFsc2U7XG4gIGZvciAobGV0IHJvdyA9IHRvcDsgcm93IDwgYm90dG9tOyByb3crKykge1xuICAgIGNvbnN0IGluZGV4ID0gcm93ICogbWFwLndpZHRoICsgbGVmdCxcbiAgICAgIHBvcyA9IG1hcC5tYXBbaW5kZXhdO1xuICAgIGlmIChtYXAubWFwW2luZGV4IC0gMV0gPT0gcG9zKSB7XG4gICAgICBmb3VuZCA9IHRydWU7XG4gICAgICBjb25zdCBjZWxsID0gdGFibGUubm9kZUF0KHBvcykhO1xuICAgICAgY29uc3QgY2VsbExlZnQgPSBtYXAuY29sQ291bnQocG9zKTtcbiAgICAgIGNvbnN0IHVwZGF0ZVBvcyA9IHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSkubWFwKHBvcyArIHN0YXJ0KTtcbiAgICAgIHRyLnNldE5vZGVNYXJrdXAoXG4gICAgICAgIHVwZGF0ZVBvcyxcbiAgICAgICAgbnVsbCxcbiAgICAgICAgcmVtb3ZlQ29sU3BhbihcbiAgICAgICAgICBjZWxsLmF0dHJzIGFzIENlbGxBdHRycyxcbiAgICAgICAgICBsZWZ0IC0gY2VsbExlZnQsXG4gICAgICAgICAgY2VsbC5hdHRycy5jb2xzcGFuIC0gKGxlZnQgLSBjZWxsTGVmdCksXG4gICAgICAgICksXG4gICAgICApO1xuICAgICAgdHIuaW5zZXJ0KFxuICAgICAgICB1cGRhdGVQb3MgKyBjZWxsLm5vZGVTaXplLFxuICAgICAgICBjZWxsLnR5cGUuY3JlYXRlQW5kRmlsbChcbiAgICAgICAgICByZW1vdmVDb2xTcGFuKGNlbGwuYXR0cnMgYXMgQ2VsbEF0dHJzLCAwLCBsZWZ0IC0gY2VsbExlZnQpLFxuICAgICAgICApISxcbiAgICAgICk7XG4gICAgICByb3cgKz0gY2VsbC5hdHRycy5yb3dzcGFuIC0gMTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZvdW5kO1xufVxuXG4vKipcbiAqIEluc2VydCB0aGUgZ2l2ZW4gc2V0IG9mIGNlbGxzIChhcyByZXR1cm5lZCBieSBgcGFzdGVkQ2VsbHNgKSBpbnRvIGFcbiAqIHRhYmxlLCBhdCB0aGUgcG9zaXRpb24gcG9pbnRlZCBhdCBieSByZWN0LlxuICpcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5zZXJ0Q2VsbHMoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgZGlzcGF0Y2g6ICh0cjogVHJhbnNhY3Rpb24pID0+IHZvaWQsXG4gIHRhYmxlU3RhcnQ6IG51bWJlcixcbiAgcmVjdDogUmVjdCxcbiAgY2VsbHM6IEFyZWEsXG4pOiB2b2lkIHtcbiAgbGV0IHRhYmxlID0gdGFibGVTdGFydCA/IHN0YXRlLmRvYy5ub2RlQXQodGFibGVTdGFydCAtIDEpIDogc3RhdGUuZG9jO1xuICBpZiAoIXRhYmxlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyB0YWJsZSBmb3VuZCcpO1xuICB9XG4gIGxldCBtYXAgPSBUYWJsZU1hcC5nZXQodGFibGUpO1xuICBjb25zdCB7IHRvcCwgbGVmdCB9ID0gcmVjdDtcbiAgY29uc3QgcmlnaHQgPSBsZWZ0ICsgY2VsbHMud2lkdGgsXG4gICAgYm90dG9tID0gdG9wICsgY2VsbHMuaGVpZ2h0O1xuICBjb25zdCB0ciA9IHN0YXRlLnRyO1xuICBsZXQgbWFwRnJvbSA9IDA7XG5cbiAgZnVuY3Rpb24gcmVjb21wKCk6IHZvaWQge1xuICAgIHRhYmxlID0gdGFibGVTdGFydCA/IHRyLmRvYy5ub2RlQXQodGFibGVTdGFydCAtIDEpIDogdHIuZG9jO1xuICAgIGlmICghdGFibGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gdGFibGUgZm91bmQnKTtcbiAgICB9XG4gICAgbWFwID0gVGFibGVNYXAuZ2V0KHRhYmxlKTtcbiAgICBtYXBGcm9tID0gdHIubWFwcGluZy5tYXBzLmxlbmd0aDtcbiAgfVxuXG4gIC8vIFByZXBhcmUgdGhlIHRhYmxlIHRvIGJlIGxhcmdlIGVub3VnaCBhbmQgbm90IGhhdmUgYW55IGNlbGxzXG4gIC8vIGNyb3NzaW5nIHRoZSBib3VuZGFyaWVzIG9mIHRoZSByZWN0YW5nbGUgdGhhdCB3ZSB3YW50IHRvXG4gIC8vIGluc2VydCBpbnRvLiBJZiBhbnl0aGluZyBhYm91dCBpdCBjaGFuZ2VzLCByZWNvbXB1dGUgdGhlIHRhYmxlXG4gIC8vIG1hcCBzbyB0aGF0IHN1YnNlcXVlbnQgb3BlcmF0aW9ucyBjYW4gc2VlIHRoZSBjdXJyZW50IHNoYXBlLlxuICBpZiAoZ3Jvd1RhYmxlKHRyLCBtYXAsIHRhYmxlLCB0YWJsZVN0YXJ0LCByaWdodCwgYm90dG9tLCBtYXBGcm9tKSkgcmVjb21wKCk7XG4gIGlmIChpc29sYXRlSG9yaXpvbnRhbCh0ciwgbWFwLCB0YWJsZSwgdGFibGVTdGFydCwgbGVmdCwgcmlnaHQsIHRvcCwgbWFwRnJvbSkpXG4gICAgcmVjb21wKCk7XG4gIGlmIChcbiAgICBpc29sYXRlSG9yaXpvbnRhbCh0ciwgbWFwLCB0YWJsZSwgdGFibGVTdGFydCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgbWFwRnJvbSlcbiAgKVxuICAgIHJlY29tcCgpO1xuICBpZiAoaXNvbGF0ZVZlcnRpY2FsKHRyLCBtYXAsIHRhYmxlLCB0YWJsZVN0YXJ0LCB0b3AsIGJvdHRvbSwgbGVmdCwgbWFwRnJvbSkpXG4gICAgcmVjb21wKCk7XG4gIGlmIChpc29sYXRlVmVydGljYWwodHIsIG1hcCwgdGFibGUsIHRhYmxlU3RhcnQsIHRvcCwgYm90dG9tLCByaWdodCwgbWFwRnJvbSkpXG4gICAgcmVjb21wKCk7XG5cbiAgZm9yIChsZXQgcm93ID0gdG9wOyByb3cgPCBib3R0b207IHJvdysrKSB7XG4gICAgY29uc3QgZnJvbSA9IG1hcC5wb3NpdGlvbkF0KHJvdywgbGVmdCwgdGFibGUpLFxuICAgICAgdG8gPSBtYXAucG9zaXRpb25BdChyb3csIHJpZ2h0LCB0YWJsZSk7XG4gICAgdHIucmVwbGFjZShcbiAgICAgIHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSkubWFwKGZyb20gKyB0YWJsZVN0YXJ0KSxcbiAgICAgIHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSkubWFwKHRvICsgdGFibGVTdGFydCksXG4gICAgICBuZXcgU2xpY2UoY2VsbHMucm93c1tyb3cgLSB0b3BdLCAwLCAwKSxcbiAgICApO1xuICB9XG4gIHJlY29tcCgpO1xuICB0ci5zZXRTZWxlY3Rpb24oXG4gICAgbmV3IENlbGxTZWxlY3Rpb24oXG4gICAgICB0ci5kb2MucmVzb2x2ZSh0YWJsZVN0YXJ0ICsgbWFwLnBvc2l0aW9uQXQodG9wLCBsZWZ0LCB0YWJsZSkpLFxuICAgICAgdHIuZG9jLnJlc29sdmUodGFibGVTdGFydCArIG1hcC5wb3NpdGlvbkF0KGJvdHRvbSAtIDEsIHJpZ2h0IC0gMSwgdGFibGUpKSxcbiAgICApLFxuICApO1xuICBkaXNwYXRjaCh0cik7XG59XG4iLCAiLy8gVGhpcyBmaWxlIGRlZmluZXMgYSBudW1iZXIgb2YgaGVscGVycyBmb3Igd2lyaW5nIHVwIHVzZXIgaW5wdXQgdG9cbi8vIHRhYmxlLXJlbGF0ZWQgZnVuY3Rpb25hbGl0eS5cblxuaW1wb3J0IHsga2V5ZG93bkhhbmRsZXIgfSBmcm9tICdwcm9zZW1pcnJvci1rZXltYXAnO1xuaW1wb3J0IHR5cGUgeyBSZXNvbHZlZFBvcywgU2xpY2UgfSBmcm9tICdwcm9zZW1pcnJvci1tb2RlbCc7XG5pbXBvcnQgeyBGcmFnbWVudCB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB0eXBlIHsgQ29tbWFuZCwgRWRpdG9yU3RhdGUsIFRyYW5zYWN0aW9uIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuaW1wb3J0IHsgU2VsZWN0aW9uLCBUZXh0U2VsZWN0aW9uIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuaW1wb3J0IHR5cGUgeyBFZGl0b3JWaWV3IH0gZnJvbSAncHJvc2VtaXJyb3Itdmlldyc7XG5cbmltcG9ydCB7IENlbGxTZWxlY3Rpb24gfSBmcm9tICcuL2NlbGxzZWxlY3Rpb24nO1xuaW1wb3J0IHsgZGVsZXRlQ2VsbFNlbGVjdGlvbiB9IGZyb20gJy4vY29tbWFuZHMnO1xuaW1wb3J0IHsgY2xpcENlbGxzLCBmaXRTbGljZSwgaW5zZXJ0Q2VsbHMsIHBhc3RlZENlbGxzIH0gZnJvbSAnLi9jb3B5cGFzdGUnO1xuaW1wb3J0IHsgdGFibGVOb2RlVHlwZXMgfSBmcm9tICcuL3NjaGVtYSc7XG5pbXBvcnQgeyBUYWJsZU1hcCB9IGZyb20gJy4vdGFibGVtYXAnO1xuaW1wb3J0IHtcbiAgY2VsbEFyb3VuZCxcbiAgaW5TYW1lVGFibGUsXG4gIGlzSW5UYWJsZSxcbiAgbmV4dENlbGwsXG4gIHNlbGVjdGlvbkNlbGwsXG4gIHRhYmxlRWRpdGluZ0tleSxcbn0gZnJvbSAnLi91dGlsJztcblxudHlwZSBBeGlzID0gJ2hvcml6JyB8ICd2ZXJ0JztcblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCB0eXBlIERpcmVjdGlvbiA9IC0xIHwgMTtcblxuZXhwb3J0IGNvbnN0IGhhbmRsZUtleURvd24gPSBrZXlkb3duSGFuZGxlcih7XG4gIEFycm93TGVmdDogYXJyb3coJ2hvcml6JywgLTEpLFxuICBBcnJvd1JpZ2h0OiBhcnJvdygnaG9yaXonLCAxKSxcbiAgQXJyb3dVcDogYXJyb3coJ3ZlcnQnLCAtMSksXG4gIEFycm93RG93bjogYXJyb3coJ3ZlcnQnLCAxKSxcblxuICAnU2hpZnQtQXJyb3dMZWZ0Jzogc2hpZnRBcnJvdygnaG9yaXonLCAtMSksXG4gICdTaGlmdC1BcnJvd1JpZ2h0Jzogc2hpZnRBcnJvdygnaG9yaXonLCAxKSxcbiAgJ1NoaWZ0LUFycm93VXAnOiBzaGlmdEFycm93KCd2ZXJ0JywgLTEpLFxuICAnU2hpZnQtQXJyb3dEb3duJzogc2hpZnRBcnJvdygndmVydCcsIDEpLFxuXG4gIEJhY2tzcGFjZTogZGVsZXRlQ2VsbFNlbGVjdGlvbixcbiAgJ01vZC1CYWNrc3BhY2UnOiBkZWxldGVDZWxsU2VsZWN0aW9uLFxuICBEZWxldGU6IGRlbGV0ZUNlbGxTZWxlY3Rpb24sXG4gICdNb2QtRGVsZXRlJzogZGVsZXRlQ2VsbFNlbGVjdGlvbixcbn0pO1xuXG5mdW5jdGlvbiBtYXliZVNldFNlbGVjdGlvbihcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuICBkaXNwYXRjaDogdW5kZWZpbmVkIHwgKCh0cjogVHJhbnNhY3Rpb24pID0+IHZvaWQpLFxuICBzZWxlY3Rpb246IFNlbGVjdGlvbixcbik6IGJvb2xlYW4ge1xuICBpZiAoc2VsZWN0aW9uLmVxKHN0YXRlLnNlbGVjdGlvbikpIHJldHVybiBmYWxzZTtcbiAgaWYgKGRpc3BhdGNoKSBkaXNwYXRjaChzdGF0ZS50ci5zZXRTZWxlY3Rpb24oc2VsZWN0aW9uKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcnJvdyhheGlzOiBBeGlzLCBkaXI6IERpcmVjdGlvbik6IENvbW1hbmQge1xuICByZXR1cm4gKHN0YXRlLCBkaXNwYXRjaCwgdmlldykgPT4ge1xuICAgIGlmICghdmlldykgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHNlbCA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICBpZiAoc2VsIGluc3RhbmNlb2YgQ2VsbFNlbGVjdGlvbikge1xuICAgICAgcmV0dXJuIG1heWJlU2V0U2VsZWN0aW9uKFxuICAgICAgICBzdGF0ZSxcbiAgICAgICAgZGlzcGF0Y2gsXG4gICAgICAgIFNlbGVjdGlvbi5uZWFyKHNlbC4kaGVhZENlbGwsIGRpciksXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoYXhpcyAhPSAnaG9yaXonICYmICFzZWwuZW1wdHkpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBlbmQgPSBhdEVuZE9mQ2VsbCh2aWV3LCBheGlzLCBkaXIpO1xuICAgIGlmIChlbmQgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChheGlzID09ICdob3JpeicpIHtcbiAgICAgIHJldHVybiBtYXliZVNldFNlbGVjdGlvbihcbiAgICAgICAgc3RhdGUsXG4gICAgICAgIGRpc3BhdGNoLFxuICAgICAgICBTZWxlY3Rpb24ubmVhcihzdGF0ZS5kb2MucmVzb2x2ZShzZWwuaGVhZCArIGRpciksIGRpciksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCAkY2VsbCA9IHN0YXRlLmRvYy5yZXNvbHZlKGVuZCk7XG4gICAgICBjb25zdCAkbmV4dCA9IG5leHRDZWxsKCRjZWxsLCBheGlzLCBkaXIpO1xuICAgICAgbGV0IG5ld1NlbDtcbiAgICAgIGlmICgkbmV4dCkgbmV3U2VsID0gU2VsZWN0aW9uLm5lYXIoJG5leHQsIDEpO1xuICAgICAgZWxzZSBpZiAoZGlyIDwgMClcbiAgICAgICAgbmV3U2VsID0gU2VsZWN0aW9uLm5lYXIoc3RhdGUuZG9jLnJlc29sdmUoJGNlbGwuYmVmb3JlKC0xKSksIC0xKTtcbiAgICAgIGVsc2UgbmV3U2VsID0gU2VsZWN0aW9uLm5lYXIoc3RhdGUuZG9jLnJlc29sdmUoJGNlbGwuYWZ0ZXIoLTEpKSwgMSk7XG4gICAgICByZXR1cm4gbWF5YmVTZXRTZWxlY3Rpb24oc3RhdGUsIGRpc3BhdGNoLCBuZXdTZWwpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gc2hpZnRBcnJvdyhheGlzOiBBeGlzLCBkaXI6IERpcmVjdGlvbik6IENvbW1hbmQge1xuICByZXR1cm4gKHN0YXRlLCBkaXNwYXRjaCwgdmlldykgPT4ge1xuICAgIGlmICghdmlldykgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHNlbCA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICBsZXQgY2VsbFNlbDogQ2VsbFNlbGVjdGlvbjtcbiAgICBpZiAoc2VsIGluc3RhbmNlb2YgQ2VsbFNlbGVjdGlvbikge1xuICAgICAgY2VsbFNlbCA9IHNlbDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZW5kID0gYXRFbmRPZkNlbGwodmlldywgYXhpcywgZGlyKTtcbiAgICAgIGlmIChlbmQgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICAgICAgY2VsbFNlbCA9IG5ldyBDZWxsU2VsZWN0aW9uKHN0YXRlLmRvYy5yZXNvbHZlKGVuZCkpO1xuICAgIH1cblxuICAgIGNvbnN0ICRoZWFkID0gbmV4dENlbGwoY2VsbFNlbC4kaGVhZENlbGwsIGF4aXMsIGRpcik7XG4gICAgaWYgKCEkaGVhZCkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBtYXliZVNldFNlbGVjdGlvbihcbiAgICAgIHN0YXRlLFxuICAgICAgZGlzcGF0Y2gsXG4gICAgICBuZXcgQ2VsbFNlbGVjdGlvbihjZWxsU2VsLiRhbmNob3JDZWxsLCAkaGVhZCksXG4gICAgKTtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZVRyaXBsZUNsaWNrKHZpZXc6IEVkaXRvclZpZXcsIHBvczogbnVtYmVyKTogYm9vbGVhbiB7XG4gIGNvbnN0IGRvYyA9IHZpZXcuc3RhdGUuZG9jLFxuICAgICRjZWxsID0gY2VsbEFyb3VuZChkb2MucmVzb2x2ZShwb3MpKTtcbiAgaWYgKCEkY2VsbCkgcmV0dXJuIGZhbHNlO1xuICB2aWV3LmRpc3BhdGNoKHZpZXcuc3RhdGUudHIuc2V0U2VsZWN0aW9uKG5ldyBDZWxsU2VsZWN0aW9uKCRjZWxsKSkpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVQYXN0ZShcbiAgdmlldzogRWRpdG9yVmlldyxcbiAgXzogQ2xpcGJvYXJkRXZlbnQsXG4gIHNsaWNlOiBTbGljZSxcbik6IGJvb2xlYW4ge1xuICBpZiAoIWlzSW5UYWJsZSh2aWV3LnN0YXRlKSkgcmV0dXJuIGZhbHNlO1xuICBsZXQgY2VsbHMgPSBwYXN0ZWRDZWxscyhzbGljZSk7XG4gIGNvbnN0IHNlbCA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uO1xuICBpZiAoc2VsIGluc3RhbmNlb2YgQ2VsbFNlbGVjdGlvbikge1xuICAgIGlmICghY2VsbHMpXG4gICAgICBjZWxscyA9IHtcbiAgICAgICAgd2lkdGg6IDEsXG4gICAgICAgIGhlaWdodDogMSxcbiAgICAgICAgcm93czogW1xuICAgICAgICAgIEZyYWdtZW50LmZyb20oXG4gICAgICAgICAgICBmaXRTbGljZSh0YWJsZU5vZGVUeXBlcyh2aWV3LnN0YXRlLnNjaGVtYSkuY2VsbCwgc2xpY2UpLFxuICAgICAgICAgICksXG4gICAgICAgIF0sXG4gICAgICB9O1xuICAgIGNvbnN0IHRhYmxlID0gc2VsLiRhbmNob3JDZWxsLm5vZGUoLTEpO1xuICAgIGNvbnN0IHN0YXJ0ID0gc2VsLiRhbmNob3JDZWxsLnN0YXJ0KC0xKTtcbiAgICBjb25zdCByZWN0ID0gVGFibGVNYXAuZ2V0KHRhYmxlKS5yZWN0QmV0d2VlbihcbiAgICAgIHNlbC4kYW5jaG9yQ2VsbC5wb3MgLSBzdGFydCxcbiAgICAgIHNlbC4kaGVhZENlbGwucG9zIC0gc3RhcnQsXG4gICAgKTtcbiAgICBjZWxscyA9IGNsaXBDZWxscyhjZWxscywgcmVjdC5yaWdodCAtIHJlY3QubGVmdCwgcmVjdC5ib3R0b20gLSByZWN0LnRvcCk7XG4gICAgaW5zZXJ0Q2VsbHModmlldy5zdGF0ZSwgdmlldy5kaXNwYXRjaCwgc3RhcnQsIHJlY3QsIGNlbGxzKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChjZWxscykge1xuICAgIGNvbnN0ICRjZWxsID0gc2VsZWN0aW9uQ2VsbCh2aWV3LnN0YXRlKTtcbiAgICBjb25zdCBzdGFydCA9ICRjZWxsLnN0YXJ0KC0xKTtcbiAgICBpbnNlcnRDZWxscyhcbiAgICAgIHZpZXcuc3RhdGUsXG4gICAgICB2aWV3LmRpc3BhdGNoLFxuICAgICAgc3RhcnQsXG4gICAgICBUYWJsZU1hcC5nZXQoJGNlbGwubm9kZSgtMSkpLmZpbmRDZWxsKCRjZWxsLnBvcyAtIHN0YXJ0KSxcbiAgICAgIGNlbGxzLFxuICAgICk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYW5kbGVNb3VzZURvd24oXG4gIHZpZXc6IEVkaXRvclZpZXcsXG4gIHN0YXJ0RXZlbnQ6IE1vdXNlRXZlbnQsXG4pOiB2b2lkIHtcbiAgLy8gT25seSBoYW5kbGUgbW91c2UgZG93biBldmVudHMgZm9yIHRoZSBtYWluIGJ1dHRvbiAodXN1YWxseSB0aGUgbGVmdCBidXR0b24pLlxuICAvLyBUaGlzIGVuc3VyZXMgdGhhdCB0aGUgY2VsbCBzZWxlY3Rpb24gd29uJ3QgYmUgdHJpZ2dlcmVkIHdoZW4gdHJ5aW5nIHRvIG9wZW5cbiAgLy8gdGhlIGNvbnRleHQgbWVudS5cbiAgaWYgKHN0YXJ0RXZlbnQuYnV0dG9uICE9IDApIHJldHVybjtcblxuICBpZiAoc3RhcnRFdmVudC5jdHJsS2V5IHx8IHN0YXJ0RXZlbnQubWV0YUtleSkgcmV0dXJuO1xuXG4gIGNvbnN0IHN0YXJ0RE9NQ2VsbCA9IGRvbUluQ2VsbCh2aWV3LCBzdGFydEV2ZW50LnRhcmdldCBhcyBOb2RlKTtcbiAgbGV0ICRhbmNob3I7XG4gIGlmIChzdGFydEV2ZW50LnNoaWZ0S2V5ICYmIHZpZXcuc3RhdGUuc2VsZWN0aW9uIGluc3RhbmNlb2YgQ2VsbFNlbGVjdGlvbikge1xuICAgIC8vIEFkZGluZyB0byBhbiBleGlzdGluZyBjZWxsIHNlbGVjdGlvblxuICAgIHNldENlbGxTZWxlY3Rpb24odmlldy5zdGF0ZS5zZWxlY3Rpb24uJGFuY2hvckNlbGwsIHN0YXJ0RXZlbnQpO1xuICAgIHN0YXJ0RXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfSBlbHNlIGlmIChcbiAgICBzdGFydEV2ZW50LnNoaWZ0S2V5ICYmXG4gICAgc3RhcnRET01DZWxsICYmXG4gICAgKCRhbmNob3IgPSBjZWxsQXJvdW5kKHZpZXcuc3RhdGUuc2VsZWN0aW9uLiRhbmNob3IpKSAhPSBudWxsICYmXG4gICAgY2VsbFVuZGVyTW91c2Uodmlldywgc3RhcnRFdmVudCk/LnBvcyAhPSAkYW5jaG9yLnBvc1xuICApIHtcbiAgICAvLyBBZGRpbmcgdG8gYSBzZWxlY3Rpb24gdGhhdCBzdGFydHMgaW4gYW5vdGhlciBjZWxsIChjYXVzaW5nIGFcbiAgICAvLyBjZWxsIHNlbGVjdGlvbiB0byBiZSBjcmVhdGVkKS5cbiAgICBzZXRDZWxsU2VsZWN0aW9uKCRhbmNob3IsIHN0YXJ0RXZlbnQpO1xuICAgIHN0YXJ0RXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfSBlbHNlIGlmICghc3RhcnRET01DZWxsKSB7XG4gICAgLy8gTm90IGluIGEgY2VsbCwgbGV0IHRoZSBkZWZhdWx0IGJlaGF2aW9yIGhhcHBlbi5cbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBDcmVhdGUgYW5kIGRpc3BhdGNoIGEgY2VsbCBzZWxlY3Rpb24gYmV0d2VlbiB0aGUgZ2l2ZW4gYW5jaG9yIGFuZFxuICAvLyB0aGUgcG9zaXRpb24gdW5kZXIgdGhlIG1vdXNlLlxuICBmdW5jdGlvbiBzZXRDZWxsU2VsZWN0aW9uKCRhbmNob3I6IFJlc29sdmVkUG9zLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGxldCAkaGVhZCA9IGNlbGxVbmRlck1vdXNlKHZpZXcsIGV2ZW50KTtcbiAgICBjb25zdCBzdGFydGluZyA9IHRhYmxlRWRpdGluZ0tleS5nZXRTdGF0ZSh2aWV3LnN0YXRlKSA9PSBudWxsO1xuICAgIGlmICghJGhlYWQgfHwgIWluU2FtZVRhYmxlKCRhbmNob3IsICRoZWFkKSkge1xuICAgICAgaWYgKHN0YXJ0aW5nKSAkaGVhZCA9ICRhbmNob3I7XG4gICAgICBlbHNlIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gbmV3IENlbGxTZWxlY3Rpb24oJGFuY2hvciwgJGhlYWQpO1xuICAgIGlmIChzdGFydGluZyB8fCAhdmlldy5zdGF0ZS5zZWxlY3Rpb24uZXEoc2VsZWN0aW9uKSkge1xuICAgICAgY29uc3QgdHIgPSB2aWV3LnN0YXRlLnRyLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pO1xuICAgICAgaWYgKHN0YXJ0aW5nKSB0ci5zZXRNZXRhKHRhYmxlRWRpdGluZ0tleSwgJGFuY2hvci5wb3MpO1xuICAgICAgdmlldy5kaXNwYXRjaCh0cik7XG4gICAgfVxuICB9XG5cbiAgLy8gU3RvcCBsaXN0ZW5pbmcgdG8gbW91c2UgbW90aW9uIGV2ZW50cy5cbiAgZnVuY3Rpb24gc3RvcCgpOiB2b2lkIHtcbiAgICB2aWV3LnJvb3QucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHN0b3ApO1xuICAgIHZpZXcucm9vdC5yZW1vdmVFdmVudExpc3RlbmVyKCdkcmFnc3RhcnQnLCBzdG9wKTtcbiAgICB2aWV3LnJvb3QucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgbW92ZSk7XG4gICAgaWYgKHRhYmxlRWRpdGluZ0tleS5nZXRTdGF0ZSh2aWV3LnN0YXRlKSAhPSBudWxsKVxuICAgICAgdmlldy5kaXNwYXRjaCh2aWV3LnN0YXRlLnRyLnNldE1ldGEodGFibGVFZGl0aW5nS2V5LCAtMSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gbW92ZShfZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZXZlbnQgPSBfZXZlbnQgYXMgTW91c2VFdmVudDtcbiAgICBjb25zdCBhbmNob3IgPSB0YWJsZUVkaXRpbmdLZXkuZ2V0U3RhdGUodmlldy5zdGF0ZSk7XG4gICAgbGV0ICRhbmNob3I7XG4gICAgaWYgKGFuY2hvciAhPSBudWxsKSB7XG4gICAgICAvLyBDb250aW51aW5nIGFuIGV4aXN0aW5nIGNyb3NzLWNlbGwgc2VsZWN0aW9uXG4gICAgICAkYW5jaG9yID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShhbmNob3IpO1xuICAgIH0gZWxzZSBpZiAoZG9tSW5DZWxsKHZpZXcsIGV2ZW50LnRhcmdldCBhcyBOb2RlKSAhPSBzdGFydERPTUNlbGwpIHtcbiAgICAgIC8vIE1vdmluZyBvdXQgb2YgdGhlIGluaXRpYWwgY2VsbCAtLSBzdGFydCBhIG5ldyBjZWxsIHNlbGVjdGlvblxuICAgICAgJGFuY2hvciA9IGNlbGxVbmRlck1vdXNlKHZpZXcsIHN0YXJ0RXZlbnQpO1xuICAgICAgaWYgKCEkYW5jaG9yKSByZXR1cm4gc3RvcCgpO1xuICAgIH1cbiAgICBpZiAoJGFuY2hvcikgc2V0Q2VsbFNlbGVjdGlvbigkYW5jaG9yLCBldmVudCk7XG4gIH1cblxuICB2aWV3LnJvb3QuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHN0b3ApO1xuICB2aWV3LnJvb3QuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ3N0YXJ0Jywgc3RvcCk7XG4gIHZpZXcucm9vdC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBtb3ZlKTtcbn1cblxuLy8gQ2hlY2sgd2hldGhlciB0aGUgY3Vyc29yIGlzIGF0IHRoZSBlbmQgb2YgYSBjZWxsIChzbyB0aGF0IGZ1cnRoZXJcbi8vIG1vdGlvbiB3b3VsZCBtb3ZlIG91dCBvZiB0aGUgY2VsbClcbmZ1bmN0aW9uIGF0RW5kT2ZDZWxsKHZpZXc6IEVkaXRvclZpZXcsIGF4aXM6IEF4aXMsIGRpcjogbnVtYmVyKTogbnVsbCB8IG51bWJlciB7XG4gIGlmICghKHZpZXcuc3RhdGUuc2VsZWN0aW9uIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvbikpIHJldHVybiBudWxsO1xuICBjb25zdCB7ICRoZWFkIH0gPSB2aWV3LnN0YXRlLnNlbGVjdGlvbjtcbiAgZm9yIChsZXQgZCA9ICRoZWFkLmRlcHRoIC0gMTsgZCA+PSAwOyBkLS0pIHtcbiAgICBjb25zdCBwYXJlbnQgPSAkaGVhZC5ub2RlKGQpLFxuICAgICAgaW5kZXggPSBkaXIgPCAwID8gJGhlYWQuaW5kZXgoZCkgOiAkaGVhZC5pbmRleEFmdGVyKGQpO1xuICAgIGlmIChpbmRleCAhPSAoZGlyIDwgMCA/IDAgOiBwYXJlbnQuY2hpbGRDb3VudCkpIHJldHVybiBudWxsO1xuICAgIGlmIChcbiAgICAgIHBhcmVudC50eXBlLnNwZWMudGFibGVSb2xlID09ICdjZWxsJyB8fFxuICAgICAgcGFyZW50LnR5cGUuc3BlYy50YWJsZVJvbGUgPT0gJ2hlYWRlcl9jZWxsJ1xuICAgICkge1xuICAgICAgY29uc3QgY2VsbFBvcyA9ICRoZWFkLmJlZm9yZShkKTtcbiAgICAgIGNvbnN0IGRpclN0cjogJ3VwJyB8ICdkb3duJyB8ICdsZWZ0JyB8ICdyaWdodCcgPVxuICAgICAgICBheGlzID09ICd2ZXJ0JyA/IChkaXIgPiAwID8gJ2Rvd24nIDogJ3VwJykgOiBkaXIgPiAwID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgICAgIHJldHVybiB2aWV3LmVuZE9mVGV4dGJsb2NrKGRpclN0cikgPyBjZWxsUG9zIDogbnVsbDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGRvbUluQ2VsbCh2aWV3OiBFZGl0b3JWaWV3LCBkb206IE5vZGUgfCBudWxsKTogTm9kZSB8IG51bGwge1xuICBmb3IgKDsgZG9tICYmIGRvbSAhPSB2aWV3LmRvbTsgZG9tID0gZG9tLnBhcmVudE5vZGUpIHtcbiAgICBpZiAoZG9tLm5vZGVOYW1lID09ICdURCcgfHwgZG9tLm5vZGVOYW1lID09ICdUSCcpIHtcbiAgICAgIHJldHVybiBkb207XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBjZWxsVW5kZXJNb3VzZShcbiAgdmlldzogRWRpdG9yVmlldyxcbiAgZXZlbnQ6IE1vdXNlRXZlbnQsXG4pOiBSZXNvbHZlZFBvcyB8IG51bGwge1xuICBjb25zdCBtb3VzZVBvcyA9IHZpZXcucG9zQXRDb29yZHMoe1xuICAgIGxlZnQ6IGV2ZW50LmNsaWVudFgsXG4gICAgdG9wOiBldmVudC5jbGllbnRZLFxuICB9KTtcbiAgaWYgKCFtb3VzZVBvcykgcmV0dXJuIG51bGw7XG4gIC8vIFByZWZlciBgaW5zaWRlYCBwb3NpdGlvbiBmb3IgYmV0dGVyIGFjY3VyYWN5IHdpdGggbWVyZ2VkIGNlbGxzIChyb3dzcGFuL2NvbHNwYW4pLFxuICAvLyBidXQgZmFsbCBiYWNrIHRvIGBwb3NgIGlmIGBpbnNpZGVgIGRvZXNuJ3QgcmVzb2x2ZSB0byBhIHZhbGlkIGNlbGxcbiAgbGV0IHsgaW5zaWRlLCBwb3MgfSA9IG1vdXNlUG9zO1xuICByZXR1cm4gKFxuICAgIChpbnNpZGUgPj0gMCAmJiBjZWxsQXJvdW5kKHZpZXcuc3RhdGUuZG9jLnJlc29sdmUoaW5zaWRlKSkpIHx8XG4gICAgY2VsbEFyb3VuZCh2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKHBvcykpXG4gICk7XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuaW1wb3J0IHR5cGUgeyBOb2RlVmlldywgVmlld011dGF0aW9uUmVjb3JkIH0gZnJvbSAncHJvc2VtaXJyb3Itdmlldyc7XG5cbmltcG9ydCB0eXBlIHsgQ2VsbEF0dHJzIH0gZnJvbSAnLi91dGlsJztcblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBUYWJsZVZpZXcgaW1wbGVtZW50cyBOb2RlVmlldyB7XG4gIHB1YmxpYyBkb206IEhUTUxEaXZFbGVtZW50O1xuICBwdWJsaWMgdGFibGU6IEhUTUxUYWJsZUVsZW1lbnQ7XG4gIHB1YmxpYyBjb2xncm91cDogSFRNTFRhYmxlQ29sRWxlbWVudDtcbiAgcHVibGljIGNvbnRlbnRET006IEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBub2RlOiBOb2RlLFxuICAgIHB1YmxpYyBkZWZhdWx0Q2VsbE1pbldpZHRoOiBudW1iZXIsXG4gICkge1xuICAgIHRoaXMuZG9tID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5kb20uY2xhc3NOYW1lID0gJ3RhYmxlV3JhcHBlcic7XG4gICAgdGhpcy50YWJsZSA9IHRoaXMuZG9tLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RhYmxlJykpO1xuICAgIHRoaXMudGFibGUuc3R5bGUuc2V0UHJvcGVydHkoXG4gICAgICAnLS1kZWZhdWx0LWNlbGwtbWluLXdpZHRoJyxcbiAgICAgIGAke2RlZmF1bHRDZWxsTWluV2lkdGh9cHhgLFxuICAgICk7XG4gICAgdGhpcy5jb2xncm91cCA9IHRoaXMudGFibGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY29sZ3JvdXAnKSk7XG4gICAgdXBkYXRlQ29sdW1uc09uUmVzaXplKG5vZGUsIHRoaXMuY29sZ3JvdXAsIHRoaXMudGFibGUsIGRlZmF1bHRDZWxsTWluV2lkdGgpO1xuICAgIHRoaXMuY29udGVudERPTSA9IHRoaXMudGFibGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGJvZHknKSk7XG4gIH1cblxuICB1cGRhdGUobm9kZTogTm9kZSk6IGJvb2xlYW4ge1xuICAgIGlmIChub2RlLnR5cGUgIT0gdGhpcy5ub2RlLnR5cGUpIHJldHVybiBmYWxzZTtcbiAgICB0aGlzLm5vZGUgPSBub2RlO1xuICAgIHVwZGF0ZUNvbHVtbnNPblJlc2l6ZShcbiAgICAgIG5vZGUsXG4gICAgICB0aGlzLmNvbGdyb3VwLFxuICAgICAgdGhpcy50YWJsZSxcbiAgICAgIHRoaXMuZGVmYXVsdENlbGxNaW5XaWR0aCxcbiAgICApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWdub3JlTXV0YXRpb24ocmVjb3JkOiBWaWV3TXV0YXRpb25SZWNvcmQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgcmVjb3JkLnR5cGUgPT0gJ2F0dHJpYnV0ZXMnICYmXG4gICAgICAocmVjb3JkLnRhcmdldCA9PSB0aGlzLnRhYmxlIHx8IHRoaXMuY29sZ3JvdXAuY29udGFpbnMocmVjb3JkLnRhcmdldCkpXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUNvbHVtbnNPblJlc2l6ZShcbiAgbm9kZTogTm9kZSxcbiAgY29sZ3JvdXA6IEhUTUxUYWJsZUNvbEVsZW1lbnQsXG4gIHRhYmxlOiBIVE1MVGFibGVFbGVtZW50LFxuICBkZWZhdWx0Q2VsbE1pbldpZHRoOiBudW1iZXIsXG4gIG92ZXJyaWRlQ29sPzogbnVtYmVyLFxuICBvdmVycmlkZVZhbHVlPzogbnVtYmVyLFxuKTogdm9pZCB7XG4gIGxldCB0b3RhbFdpZHRoID0gMDtcbiAgbGV0IGZpeGVkV2lkdGggPSB0cnVlO1xuICBsZXQgbmV4dERPTSA9IGNvbGdyb3VwLmZpcnN0Q2hpbGQgYXMgSFRNTEVsZW1lbnQ7XG4gIGNvbnN0IHJvdyA9IG5vZGUuZmlyc3RDaGlsZDtcbiAgaWYgKCFyb3cpIHJldHVybjtcblxuICBmb3IgKGxldCBpID0gMCwgY29sID0gMDsgaSA8IHJvdy5jaGlsZENvdW50OyBpKyspIHtcbiAgICBjb25zdCB7IGNvbHNwYW4sIGNvbHdpZHRoIH0gPSByb3cuY2hpbGQoaSkuYXR0cnMgYXMgQ2VsbEF0dHJzO1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgY29sc3BhbjsgaisrLCBjb2wrKykge1xuICAgICAgY29uc3QgaGFzV2lkdGggPVxuICAgICAgICBvdmVycmlkZUNvbCA9PSBjb2wgPyBvdmVycmlkZVZhbHVlIDogY29sd2lkdGggJiYgY29sd2lkdGhbal07XG4gICAgICBjb25zdCBjc3NXaWR0aCA9IGhhc1dpZHRoID8gaGFzV2lkdGggKyAncHgnIDogJyc7XG4gICAgICB0b3RhbFdpZHRoICs9IGhhc1dpZHRoIHx8IGRlZmF1bHRDZWxsTWluV2lkdGg7XG4gICAgICBpZiAoIWhhc1dpZHRoKSBmaXhlZFdpZHRoID0gZmFsc2U7XG4gICAgICBpZiAoIW5leHRET00pIHtcbiAgICAgICAgY29uc3QgY29sID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY29sJyk7XG4gICAgICAgIGNvbC5zdHlsZS53aWR0aCA9IGNzc1dpZHRoO1xuICAgICAgICBjb2xncm91cC5hcHBlbmRDaGlsZChjb2wpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKG5leHRET00uc3R5bGUud2lkdGggIT0gY3NzV2lkdGgpIHtcbiAgICAgICAgICBuZXh0RE9NLnN0eWxlLndpZHRoID0gY3NzV2lkdGg7XG4gICAgICAgIH1cbiAgICAgICAgbmV4dERPTSA9IG5leHRET00ubmV4dFNpYmxpbmcgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgd2hpbGUgKG5leHRET00pIHtcbiAgICBjb25zdCBhZnRlciA9IG5leHRET00ubmV4dFNpYmxpbmc7XG4gICAgbmV4dERPTS5wYXJlbnROb2RlPy5yZW1vdmVDaGlsZChuZXh0RE9NKTtcbiAgICBuZXh0RE9NID0gYWZ0ZXIgYXMgSFRNTEVsZW1lbnQ7XG4gIH1cblxuICBpZiAoZml4ZWRXaWR0aCkge1xuICAgIHRhYmxlLnN0eWxlLndpZHRoID0gdG90YWxXaWR0aCArICdweCc7XG4gICAgdGFibGUuc3R5bGUubWluV2lkdGggPSAnJztcbiAgfSBlbHNlIHtcbiAgICB0YWJsZS5zdHlsZS53aWR0aCA9ICcnO1xuICAgIHRhYmxlLnN0eWxlLm1pbldpZHRoID0gdG90YWxXaWR0aCArICdweCc7XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IEF0dHJzLCBOb2RlIGFzIFByb3NlbWlycm9yTm9kZSB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB0eXBlIHsgRWRpdG9yU3RhdGUsIFRyYW5zYWN0aW9uIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tICdwcm9zZW1pcnJvci1zdGF0ZSc7XG5pbXBvcnQgdHlwZSB7IEVkaXRvclZpZXcsIE5vZGVWaWV3IH0gZnJvbSAncHJvc2VtaXJyb3Itdmlldyc7XG5pbXBvcnQgeyBEZWNvcmF0aW9uLCBEZWNvcmF0aW9uU2V0IH0gZnJvbSAncHJvc2VtaXJyb3Itdmlldyc7XG5cbmltcG9ydCB7IHRhYmxlTm9kZVR5cGVzIH0gZnJvbSAnLi9zY2hlbWEnO1xuaW1wb3J0IHsgVGFibGVNYXAgfSBmcm9tICcuL3RhYmxlbWFwJztcbmltcG9ydCB7IFRhYmxlVmlldywgdXBkYXRlQ29sdW1uc09uUmVzaXplIH0gZnJvbSAnLi90YWJsZXZpZXcnO1xuaW1wb3J0IHR5cGUgeyBDZWxsQXR0cnMgfSBmcm9tICcuL3V0aWwnO1xuaW1wb3J0IHsgY2VsbEFyb3VuZCwgcG9pbnRzQXRDZWxsIH0gZnJvbSAnLi91dGlsJztcblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBjb2x1bW5SZXNpemluZ1BsdWdpbktleSA9IG5ldyBQbHVnaW5LZXk8UmVzaXplU3RhdGU+KFxuICAndGFibGVDb2x1bW5SZXNpemluZycsXG4pO1xuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgQ29sdW1uUmVzaXppbmdPcHRpb25zID0ge1xuICBoYW5kbGVXaWR0aD86IG51bWJlcjtcbiAgLyoqXG4gICAqIE1pbmltdW0gd2lkdGggb2YgYSBjZWxsIC9jb2x1bW4uIFRoZSBjb2x1bW4gY2Fubm90IGJlIHJlc2l6ZWQgc21hbGxlciB0aGFuIHRoaXMuXG4gICAqL1xuICBjZWxsTWluV2lkdGg/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBtaW5XaWR0aCBvZiBhIGNlbGwgLyBjb2x1bW4gd2hlbiBpdCBkb2Vzbid0IGhhdmUgYW4gZXhwbGljaXQgd2lkdGggKGkuZS46IGl0IGhhcyBub3QgYmVlbiByZXNpemVkIG1hbnVhbGx5KVxuICAgKi9cbiAgZGVmYXVsdENlbGxNaW5XaWR0aD86IG51bWJlcjtcbiAgbGFzdENvbHVtblJlc2l6YWJsZT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBBIGN1c3RvbSBub2RlIHZpZXcgZm9yIHRoZSByZW5kZXJpbmcgdGFibGUgbm9kZXMuIEJ5IGRlZmF1bHQsIHRoZSBwbHVnaW5cbiAgICogdXNlcyB0aGUge0BsaW5rIFRhYmxlVmlld30gY2xhc3MuIFlvdSBjYW4gZXhwbGljaXRseSBzZXQgdGhpcyB0byBgbnVsbGAgdG9cbiAgICogbm90IHVzZSBhIGN1c3RvbSBub2RlIHZpZXcuXG4gICAqL1xuICBWaWV3PzpcbiAgICB8IChuZXcgKFxuICAgICAgICBub2RlOiBQcm9zZW1pcnJvck5vZGUsXG4gICAgICAgIGNlbGxNaW5XaWR0aDogbnVtYmVyLFxuICAgICAgICB2aWV3OiBFZGl0b3JWaWV3LFxuICAgICAgKSA9PiBOb2RlVmlldylcbiAgICB8IG51bGw7XG59O1xuXG4vKipcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgRHJhZ2dpbmcgPSB7IHN0YXJ0WDogbnVtYmVyOyBzdGFydFdpZHRoOiBudW1iZXIgfTtcblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb2x1bW5SZXNpemluZyh7XG4gIGhhbmRsZVdpZHRoID0gNSxcbiAgY2VsbE1pbldpZHRoID0gMjUsXG4gIGRlZmF1bHRDZWxsTWluV2lkdGggPSAxMDAsXG4gIFZpZXcgPSBUYWJsZVZpZXcsXG4gIGxhc3RDb2x1bW5SZXNpemFibGUgPSB0cnVlLFxufTogQ29sdW1uUmVzaXppbmdPcHRpb25zID0ge30pOiBQbHVnaW4ge1xuICBjb25zdCBwbHVnaW4gPSBuZXcgUGx1Z2luPFJlc2l6ZVN0YXRlPih7XG4gICAga2V5OiBjb2x1bW5SZXNpemluZ1BsdWdpbktleSxcbiAgICBzdGF0ZToge1xuICAgICAgaW5pdChfLCBzdGF0ZSkge1xuICAgICAgICBjb25zdCBub2RlVmlld3MgPSBwbHVnaW4uc3BlYz8ucHJvcHM/Lm5vZGVWaWV3cztcbiAgICAgICAgY29uc3QgdGFibGVOYW1lID0gdGFibGVOb2RlVHlwZXMoc3RhdGUuc2NoZW1hKS50YWJsZS5uYW1lO1xuICAgICAgICBpZiAoVmlldyAmJiBub2RlVmlld3MpIHtcbiAgICAgICAgICBub2RlVmlld3NbdGFibGVOYW1lXSA9IChub2RlLCB2aWV3KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFZpZXcobm9kZSwgZGVmYXVsdENlbGxNaW5XaWR0aCwgdmlldyk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFJlc2l6ZVN0YXRlKC0xLCBmYWxzZSk7XG4gICAgICB9LFxuICAgICAgYXBwbHkodHIsIHByZXYpIHtcbiAgICAgICAgcmV0dXJuIHByZXYuYXBwbHkodHIpO1xuICAgICAgfSxcbiAgICB9LFxuICAgIHByb3BzOiB7XG4gICAgICBhdHRyaWJ1dGVzOiAoc3RhdGUpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0+IHtcbiAgICAgICAgY29uc3QgcGx1Z2luU3RhdGUgPSBjb2x1bW5SZXNpemluZ1BsdWdpbktleS5nZXRTdGF0ZShzdGF0ZSk7XG4gICAgICAgIHJldHVybiBwbHVnaW5TdGF0ZSAmJiBwbHVnaW5TdGF0ZS5hY3RpdmVIYW5kbGUgPiAtMVxuICAgICAgICAgID8geyBjbGFzczogJ3Jlc2l6ZS1jdXJzb3InIH1cbiAgICAgICAgICA6IHt9O1xuICAgICAgfSxcblxuICAgICAgaGFuZGxlRE9NRXZlbnRzOiB7XG4gICAgICAgIG1vdXNlbW92ZTogKHZpZXcsIGV2ZW50KSA9PiB7XG4gICAgICAgICAgaGFuZGxlTW91c2VNb3ZlKHZpZXcsIGV2ZW50LCBoYW5kbGVXaWR0aCwgbGFzdENvbHVtblJlc2l6YWJsZSk7XG4gICAgICAgIH0sXG4gICAgICAgIG1vdXNlbGVhdmU6ICh2aWV3KSA9PiB7XG4gICAgICAgICAgaGFuZGxlTW91c2VMZWF2ZSh2aWV3KTtcbiAgICAgICAgfSxcbiAgICAgICAgbW91c2Vkb3duOiAodmlldywgZXZlbnQpID0+IHtcbiAgICAgICAgICBoYW5kbGVNb3VzZURvd24odmlldywgZXZlbnQsIGNlbGxNaW5XaWR0aCwgZGVmYXVsdENlbGxNaW5XaWR0aCk7XG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICBkZWNvcmF0aW9uczogKHN0YXRlKSA9PiB7XG4gICAgICAgIGNvbnN0IHBsdWdpblN0YXRlID0gY29sdW1uUmVzaXppbmdQbHVnaW5LZXkuZ2V0U3RhdGUoc3RhdGUpO1xuICAgICAgICBpZiAocGx1Z2luU3RhdGUgJiYgcGx1Z2luU3RhdGUuYWN0aXZlSGFuZGxlID4gLTEpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlRGVjb3JhdGlvbnMoc3RhdGUsIHBsdWdpblN0YXRlLmFjdGl2ZUhhbmRsZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIG5vZGVWaWV3czoge30sXG4gICAgfSxcbiAgfSk7XG4gIHJldHVybiBwbHVnaW47XG59XG5cbi8qKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY2xhc3MgUmVzaXplU3RhdGUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgYWN0aXZlSGFuZGxlOiBudW1iZXIsXG4gICAgcHVibGljIGRyYWdnaW5nOiBEcmFnZ2luZyB8IGZhbHNlLFxuICApIHt9XG5cbiAgYXBwbHkodHI6IFRyYW5zYWN0aW9uKTogUmVzaXplU3RhdGUge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdGhpcy1hbGlhc1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcztcbiAgICBjb25zdCBhY3Rpb24gPSB0ci5nZXRNZXRhKGNvbHVtblJlc2l6aW5nUGx1Z2luS2V5KTtcbiAgICBpZiAoYWN0aW9uICYmIGFjdGlvbi5zZXRIYW5kbGUgIT0gbnVsbClcbiAgICAgIHJldHVybiBuZXcgUmVzaXplU3RhdGUoYWN0aW9uLnNldEhhbmRsZSwgZmFsc2UpO1xuICAgIGlmIChhY3Rpb24gJiYgYWN0aW9uLnNldERyYWdnaW5nICE9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gbmV3IFJlc2l6ZVN0YXRlKHN0YXRlLmFjdGl2ZUhhbmRsZSwgYWN0aW9uLnNldERyYWdnaW5nKTtcbiAgICBpZiAoc3RhdGUuYWN0aXZlSGFuZGxlID4gLTEgJiYgdHIuZG9jQ2hhbmdlZCkge1xuICAgICAgbGV0IGhhbmRsZSA9IHRyLm1hcHBpbmcubWFwKHN0YXRlLmFjdGl2ZUhhbmRsZSwgLTEpO1xuICAgICAgaWYgKCFwb2ludHNBdENlbGwodHIuZG9jLnJlc29sdmUoaGFuZGxlKSkpIHtcbiAgICAgICAgaGFuZGxlID0gLTE7XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFJlc2l6ZVN0YXRlKGhhbmRsZSwgc3RhdGUuZHJhZ2dpbmcpO1xuICAgIH1cbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlTW91c2VNb3ZlKFxuICB2aWV3OiBFZGl0b3JWaWV3LFxuICBldmVudDogTW91c2VFdmVudCxcbiAgaGFuZGxlV2lkdGg6IG51bWJlcixcbiAgbGFzdENvbHVtblJlc2l6YWJsZTogYm9vbGVhbixcbik6IHZvaWQge1xuICBpZiAoIXZpZXcuZWRpdGFibGUpIHJldHVybjtcblxuICBjb25zdCBwbHVnaW5TdGF0ZSA9IGNvbHVtblJlc2l6aW5nUGx1Z2luS2V5LmdldFN0YXRlKHZpZXcuc3RhdGUpO1xuICBpZiAoIXBsdWdpblN0YXRlKSByZXR1cm47XG5cbiAgaWYgKCFwbHVnaW5TdGF0ZS5kcmFnZ2luZykge1xuICAgIGNvbnN0IHRhcmdldCA9IGRvbUNlbGxBcm91bmQoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KTtcbiAgICBsZXQgY2VsbCA9IC0xO1xuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgIGNvbnN0IHsgbGVmdCwgcmlnaHQgfSA9IHRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGlmIChldmVudC5jbGllbnRYIC0gbGVmdCA8PSBoYW5kbGVXaWR0aClcbiAgICAgICAgY2VsbCA9IGVkZ2VDZWxsKHZpZXcsIGV2ZW50LCAnbGVmdCcsIGhhbmRsZVdpZHRoKTtcbiAgICAgIGVsc2UgaWYgKHJpZ2h0IC0gZXZlbnQuY2xpZW50WCA8PSBoYW5kbGVXaWR0aClcbiAgICAgICAgY2VsbCA9IGVkZ2VDZWxsKHZpZXcsIGV2ZW50LCAncmlnaHQnLCBoYW5kbGVXaWR0aCk7XG4gICAgfVxuXG4gICAgaWYgKGNlbGwgIT0gcGx1Z2luU3RhdGUuYWN0aXZlSGFuZGxlKSB7XG4gICAgICBpZiAoIWxhc3RDb2x1bW5SZXNpemFibGUgJiYgY2VsbCAhPT0gLTEpIHtcbiAgICAgICAgY29uc3QgJGNlbGwgPSB2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKGNlbGwpO1xuICAgICAgICBjb25zdCB0YWJsZSA9ICRjZWxsLm5vZGUoLTEpO1xuICAgICAgICBjb25zdCBtYXAgPSBUYWJsZU1hcC5nZXQodGFibGUpO1xuICAgICAgICBjb25zdCB0YWJsZVN0YXJ0ID0gJGNlbGwuc3RhcnQoLTEpO1xuICAgICAgICBjb25zdCBjb2wgPVxuICAgICAgICAgIG1hcC5jb2xDb3VudCgkY2VsbC5wb3MgLSB0YWJsZVN0YXJ0KSArXG4gICAgICAgICAgJGNlbGwubm9kZUFmdGVyIS5hdHRycy5jb2xzcGFuIC1cbiAgICAgICAgICAxO1xuXG4gICAgICAgIGlmIChjb2wgPT0gbWFwLndpZHRoIC0gMSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB1cGRhdGVIYW5kbGUodmlldywgY2VsbCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGhhbmRsZU1vdXNlTGVhdmUodmlldzogRWRpdG9yVmlldyk6IHZvaWQge1xuICBpZiAoIXZpZXcuZWRpdGFibGUpIHJldHVybjtcblxuICBjb25zdCBwbHVnaW5TdGF0ZSA9IGNvbHVtblJlc2l6aW5nUGx1Z2luS2V5LmdldFN0YXRlKHZpZXcuc3RhdGUpO1xuICBpZiAocGx1Z2luU3RhdGUgJiYgcGx1Z2luU3RhdGUuYWN0aXZlSGFuZGxlID4gLTEgJiYgIXBsdWdpblN0YXRlLmRyYWdnaW5nKVxuICAgIHVwZGF0ZUhhbmRsZSh2aWV3LCAtMSk7XG59XG5cbmZ1bmN0aW9uIGhhbmRsZU1vdXNlRG93bihcbiAgdmlldzogRWRpdG9yVmlldyxcbiAgZXZlbnQ6IE1vdXNlRXZlbnQsXG4gIGNlbGxNaW5XaWR0aDogbnVtYmVyLFxuICBkZWZhdWx0Q2VsbE1pbldpZHRoOiBudW1iZXIsXG4pOiBib29sZWFuIHtcbiAgaWYgKCF2aWV3LmVkaXRhYmxlKSByZXR1cm4gZmFsc2U7XG5cbiAgY29uc3Qgd2luID0gdmlldy5kb20ub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyA/PyB3aW5kb3c7XG5cbiAgY29uc3QgcGx1Z2luU3RhdGUgPSBjb2x1bW5SZXNpemluZ1BsdWdpbktleS5nZXRTdGF0ZSh2aWV3LnN0YXRlKTtcbiAgaWYgKCFwbHVnaW5TdGF0ZSB8fCBwbHVnaW5TdGF0ZS5hY3RpdmVIYW5kbGUgPT0gLTEgfHwgcGx1Z2luU3RhdGUuZHJhZ2dpbmcpXG4gICAgcmV0dXJuIGZhbHNlO1xuXG4gIGNvbnN0IGNlbGwgPSB2aWV3LnN0YXRlLmRvYy5ub2RlQXQocGx1Z2luU3RhdGUuYWN0aXZlSGFuZGxlKSE7XG4gIGNvbnN0IHdpZHRoID0gY3VycmVudENvbFdpZHRoKHZpZXcsIHBsdWdpblN0YXRlLmFjdGl2ZUhhbmRsZSwgY2VsbC5hdHRycyk7XG4gIHZpZXcuZGlzcGF0Y2goXG4gICAgdmlldy5zdGF0ZS50ci5zZXRNZXRhKGNvbHVtblJlc2l6aW5nUGx1Z2luS2V5LCB7XG4gICAgICBzZXREcmFnZ2luZzogeyBzdGFydFg6IGV2ZW50LmNsaWVudFgsIHN0YXJ0V2lkdGg6IHdpZHRoIH0sXG4gICAgfSksXG4gICk7XG5cbiAgZnVuY3Rpb24gZmluaXNoKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgd2luLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBmaW5pc2gpO1xuICAgIHdpbi5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBtb3ZlKTtcbiAgICBjb25zdCBwbHVnaW5TdGF0ZSA9IGNvbHVtblJlc2l6aW5nUGx1Z2luS2V5LmdldFN0YXRlKHZpZXcuc3RhdGUpO1xuICAgIGlmIChwbHVnaW5TdGF0ZT8uZHJhZ2dpbmcpIHtcbiAgICAgIHVwZGF0ZUNvbHVtbldpZHRoKFxuICAgICAgICB2aWV3LFxuICAgICAgICBwbHVnaW5TdGF0ZS5hY3RpdmVIYW5kbGUsXG4gICAgICAgIGRyYWdnZWRXaWR0aChwbHVnaW5TdGF0ZS5kcmFnZ2luZywgZXZlbnQsIGNlbGxNaW5XaWR0aCksXG4gICAgICApO1xuICAgICAgdmlldy5kaXNwYXRjaChcbiAgICAgICAgdmlldy5zdGF0ZS50ci5zZXRNZXRhKGNvbHVtblJlc2l6aW5nUGx1Z2luS2V5LCB7IHNldERyYWdnaW5nOiBudWxsIH0pLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBtb3ZlKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCFldmVudC53aGljaCkgcmV0dXJuIGZpbmlzaChldmVudCk7XG4gICAgY29uc3QgcGx1Z2luU3RhdGUgPSBjb2x1bW5SZXNpemluZ1BsdWdpbktleS5nZXRTdGF0ZSh2aWV3LnN0YXRlKTtcbiAgICBpZiAoIXBsdWdpblN0YXRlKSByZXR1cm47XG4gICAgaWYgKHBsdWdpblN0YXRlLmRyYWdnaW5nKSB7XG4gICAgICBjb25zdCBkcmFnZ2VkID0gZHJhZ2dlZFdpZHRoKHBsdWdpblN0YXRlLmRyYWdnaW5nLCBldmVudCwgY2VsbE1pbldpZHRoKTtcbiAgICAgIGRpc3BsYXlDb2x1bW5XaWR0aChcbiAgICAgICAgdmlldyxcbiAgICAgICAgcGx1Z2luU3RhdGUuYWN0aXZlSGFuZGxlLFxuICAgICAgICBkcmFnZ2VkLFxuICAgICAgICBkZWZhdWx0Q2VsbE1pbldpZHRoLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBkaXNwbGF5Q29sdW1uV2lkdGgoXG4gICAgdmlldyxcbiAgICBwbHVnaW5TdGF0ZS5hY3RpdmVIYW5kbGUsXG4gICAgd2lkdGgsXG4gICAgZGVmYXVsdENlbGxNaW5XaWR0aCxcbiAgKTtcblxuICB3aW4uYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIGZpbmlzaCk7XG4gIHdpbi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBtb3ZlKTtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGN1cnJlbnRDb2xXaWR0aChcbiAgdmlldzogRWRpdG9yVmlldyxcbiAgY2VsbFBvczogbnVtYmVyLFxuICB7IGNvbHNwYW4sIGNvbHdpZHRoIH06IEF0dHJzLFxuKTogbnVtYmVyIHtcbiAgY29uc3Qgd2lkdGggPSBjb2x3aWR0aCAmJiBjb2x3aWR0aFtjb2x3aWR0aC5sZW5ndGggLSAxXTtcbiAgaWYgKHdpZHRoKSByZXR1cm4gd2lkdGg7XG4gIGNvbnN0IGRvbSA9IHZpZXcuZG9tQXRQb3MoY2VsbFBvcyk7XG4gIGNvbnN0IG5vZGUgPSBkb20ubm9kZS5jaGlsZE5vZGVzW2RvbS5vZmZzZXRdIGFzIEhUTUxFbGVtZW50O1xuICBsZXQgZG9tV2lkdGggPSBub2RlLm9mZnNldFdpZHRoLFxuICAgIHBhcnRzID0gY29sc3BhbjtcbiAgaWYgKGNvbHdpZHRoKVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29sc3BhbjsgaSsrKVxuICAgICAgaWYgKGNvbHdpZHRoW2ldKSB7XG4gICAgICAgIGRvbVdpZHRoIC09IGNvbHdpZHRoW2ldO1xuICAgICAgICBwYXJ0cy0tO1xuICAgICAgfVxuICByZXR1cm4gZG9tV2lkdGggLyBwYXJ0cztcbn1cblxuZnVuY3Rpb24gZG9tQ2VsbEFyb3VuZCh0YXJnZXQ6IEhUTUxFbGVtZW50IHwgbnVsbCk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gIHdoaWxlICh0YXJnZXQgJiYgdGFyZ2V0Lm5vZGVOYW1lICE9ICdURCcgJiYgdGFyZ2V0Lm5vZGVOYW1lICE9ICdUSCcpXG4gICAgdGFyZ2V0ID1cbiAgICAgIHRhcmdldC5jbGFzc0xpc3QgJiYgdGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucygnUHJvc2VNaXJyb3InKVxuICAgICAgICA/IG51bGxcbiAgICAgICAgOiAodGFyZ2V0LnBhcmVudE5vZGUgYXMgSFRNTEVsZW1lbnQpO1xuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBlZGdlQ2VsbChcbiAgdmlldzogRWRpdG9yVmlldyxcbiAgZXZlbnQ6IE1vdXNlRXZlbnQsXG4gIHNpZGU6ICdsZWZ0JyB8ICdyaWdodCcsXG4gIGhhbmRsZVdpZHRoOiBudW1iZXIsXG4pOiBudW1iZXIge1xuICAvLyBwb3NBdENvb3JkcyByZXR1cm5zIGluY29uc2lzdGVudCBwb3NpdGlvbnMgd2hlbiBjdXJzb3IgaXMgbW92aW5nXG4gIC8vIGFjcm9zcyBhIGNvbGxhcHNlZCB0YWJsZSBib3JkZXIuIFVzZSBhbiBvZmZzZXQgdG8gYWRqdXN0IHRoZVxuICAvLyB0YXJnZXQgdmlld3BvcnQgY29vcmRpbmF0ZXMgYXdheSBmcm9tIHRoZSB0YWJsZSBib3JkZXIuXG4gIGNvbnN0IG9mZnNldCA9IHNpZGUgPT0gJ3JpZ2h0JyA/IC1oYW5kbGVXaWR0aCA6IGhhbmRsZVdpZHRoO1xuICBjb25zdCBmb3VuZCA9IHZpZXcucG9zQXRDb29yZHMoe1xuICAgIGxlZnQ6IGV2ZW50LmNsaWVudFggKyBvZmZzZXQsXG4gICAgdG9wOiBldmVudC5jbGllbnRZLFxuICB9KTtcbiAgaWYgKCFmb3VuZCkgcmV0dXJuIC0xO1xuICBjb25zdCB7IHBvcyB9ID0gZm91bmQ7XG4gIGNvbnN0ICRjZWxsID0gY2VsbEFyb3VuZCh2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKHBvcykpO1xuICBpZiAoISRjZWxsKSByZXR1cm4gLTE7XG4gIGlmIChzaWRlID09ICdyaWdodCcpIHJldHVybiAkY2VsbC5wb3M7XG4gIGNvbnN0IG1hcCA9IFRhYmxlTWFwLmdldCgkY2VsbC5ub2RlKC0xKSksXG4gICAgc3RhcnQgPSAkY2VsbC5zdGFydCgtMSk7XG4gIGNvbnN0IGluZGV4ID0gbWFwLm1hcC5pbmRleE9mKCRjZWxsLnBvcyAtIHN0YXJ0KTtcbiAgcmV0dXJuIGluZGV4ICUgbWFwLndpZHRoID09IDAgPyAtMSA6IHN0YXJ0ICsgbWFwLm1hcFtpbmRleCAtIDFdO1xufVxuXG5mdW5jdGlvbiBkcmFnZ2VkV2lkdGgoXG4gIGRyYWdnaW5nOiBEcmFnZ2luZyxcbiAgZXZlbnQ6IE1vdXNlRXZlbnQsXG4gIHJlc2l6ZU1pbldpZHRoOiBudW1iZXIsXG4pOiBudW1iZXIge1xuICBjb25zdCBvZmZzZXQgPSBldmVudC5jbGllbnRYIC0gZHJhZ2dpbmcuc3RhcnRYO1xuICByZXR1cm4gTWF0aC5tYXgocmVzaXplTWluV2lkdGgsIGRyYWdnaW5nLnN0YXJ0V2lkdGggKyBvZmZzZXQpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVIYW5kbGUodmlldzogRWRpdG9yVmlldywgdmFsdWU6IG51bWJlcik6IHZvaWQge1xuICB2aWV3LmRpc3BhdGNoKFxuICAgIHZpZXcuc3RhdGUudHIuc2V0TWV0YShjb2x1bW5SZXNpemluZ1BsdWdpbktleSwgeyBzZXRIYW5kbGU6IHZhbHVlIH0pLFxuICApO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVDb2x1bW5XaWR0aChcbiAgdmlldzogRWRpdG9yVmlldyxcbiAgY2VsbDogbnVtYmVyLFxuICB3aWR0aDogbnVtYmVyLFxuKTogdm9pZCB7XG4gIGNvbnN0ICRjZWxsID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShjZWxsKTtcbiAgY29uc3QgdGFibGUgPSAkY2VsbC5ub2RlKC0xKSxcbiAgICBtYXAgPSBUYWJsZU1hcC5nZXQodGFibGUpLFxuICAgIHN0YXJ0ID0gJGNlbGwuc3RhcnQoLTEpO1xuICBjb25zdCBjb2wgPVxuICAgIG1hcC5jb2xDb3VudCgkY2VsbC5wb3MgLSBzdGFydCkgKyAkY2VsbC5ub2RlQWZ0ZXIhLmF0dHJzLmNvbHNwYW4gLSAxO1xuICBjb25zdCB0ciA9IHZpZXcuc3RhdGUudHI7XG4gIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IG1hcC5oZWlnaHQ7IHJvdysrKSB7XG4gICAgY29uc3QgbWFwSW5kZXggPSByb3cgKiBtYXAud2lkdGggKyBjb2w7XG4gICAgLy8gUm93c3Bhbm5pbmcgY2VsbCB0aGF0IGhhcyBhbHJlYWR5IGJlZW4gaGFuZGxlZFxuICAgIGlmIChyb3cgJiYgbWFwLm1hcFttYXBJbmRleF0gPT0gbWFwLm1hcFttYXBJbmRleCAtIG1hcC53aWR0aF0pIGNvbnRpbnVlO1xuICAgIGNvbnN0IHBvcyA9IG1hcC5tYXBbbWFwSW5kZXhdO1xuICAgIGNvbnN0IGF0dHJzID0gdGFibGUubm9kZUF0KHBvcykhLmF0dHJzIGFzIENlbGxBdHRycztcbiAgICBjb25zdCBpbmRleCA9IGF0dHJzLmNvbHNwYW4gPT0gMSA/IDAgOiBjb2wgLSBtYXAuY29sQ291bnQocG9zKTtcbiAgICBpZiAoYXR0cnMuY29sd2lkdGggJiYgYXR0cnMuY29sd2lkdGhbaW5kZXhdID09IHdpZHRoKSBjb250aW51ZTtcbiAgICBjb25zdCBjb2x3aWR0aCA9IGF0dHJzLmNvbHdpZHRoXG4gICAgICA/IGF0dHJzLmNvbHdpZHRoLnNsaWNlKClcbiAgICAgIDogemVyb2VzKGF0dHJzLmNvbHNwYW4pO1xuICAgIGNvbHdpZHRoW2luZGV4XSA9IHdpZHRoO1xuICAgIHRyLnNldE5vZGVNYXJrdXAoc3RhcnQgKyBwb3MsIG51bGwsIHsgLi4uYXR0cnMsIGNvbHdpZHRoOiBjb2x3aWR0aCB9KTtcbiAgfVxuICBpZiAodHIuZG9jQ2hhbmdlZCkgdmlldy5kaXNwYXRjaCh0cik7XG59XG5cbmZ1bmN0aW9uIGRpc3BsYXlDb2x1bW5XaWR0aChcbiAgdmlldzogRWRpdG9yVmlldyxcbiAgY2VsbDogbnVtYmVyLFxuICB3aWR0aDogbnVtYmVyLFxuICBkZWZhdWx0Q2VsbE1pbldpZHRoOiBudW1iZXIsXG4pOiB2b2lkIHtcbiAgY29uc3QgJGNlbGwgPSB2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKGNlbGwpO1xuICBjb25zdCB0YWJsZSA9ICRjZWxsLm5vZGUoLTEpLFxuICAgIHN0YXJ0ID0gJGNlbGwuc3RhcnQoLTEpO1xuICBjb25zdCBjb2wgPVxuICAgIFRhYmxlTWFwLmdldCh0YWJsZSkuY29sQ291bnQoJGNlbGwucG9zIC0gc3RhcnQpICtcbiAgICAkY2VsbC5ub2RlQWZ0ZXIhLmF0dHJzLmNvbHNwYW4gLVxuICAgIDE7XG4gIGxldCBkb206IE5vZGUgfCBudWxsID0gdmlldy5kb21BdFBvcygkY2VsbC5zdGFydCgtMSkpLm5vZGU7XG4gIHdoaWxlIChkb20gJiYgZG9tLm5vZGVOYW1lICE9ICdUQUJMRScpIHtcbiAgICBkb20gPSBkb20ucGFyZW50Tm9kZTtcbiAgfVxuICBpZiAoIWRvbSkgcmV0dXJuO1xuICB1cGRhdGVDb2x1bW5zT25SZXNpemUoXG4gICAgdGFibGUsXG4gICAgZG9tLmZpcnN0Q2hpbGQgYXMgSFRNTFRhYmxlQ29sRWxlbWVudCxcbiAgICBkb20gYXMgSFRNTFRhYmxlRWxlbWVudCxcbiAgICBkZWZhdWx0Q2VsbE1pbldpZHRoLFxuICAgIGNvbCxcbiAgICB3aWR0aCxcbiAgKTtcbn1cblxuZnVuY3Rpb24gemVyb2VzKG46IG51bWJlcik6IDBbXSB7XG4gIHJldHVybiBBcnJheShuKS5maWxsKDApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlRGVjb3JhdGlvbnMoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgY2VsbDogbnVtYmVyLFxuKTogRGVjb3JhdGlvblNldCB7XG4gIGNvbnN0IGRlY29yYXRpb25zID0gW107XG4gIGNvbnN0ICRjZWxsID0gc3RhdGUuZG9jLnJlc29sdmUoY2VsbCk7XG4gIGNvbnN0IHRhYmxlID0gJGNlbGwubm9kZSgtMSk7XG4gIGlmICghdGFibGUpIHtcbiAgICByZXR1cm4gRGVjb3JhdGlvblNldC5lbXB0eTtcbiAgfVxuICBjb25zdCBtYXAgPSBUYWJsZU1hcC5nZXQodGFibGUpO1xuICBjb25zdCBzdGFydCA9ICRjZWxsLnN0YXJ0KC0xKTtcbiAgY29uc3QgY29sID1cbiAgICBtYXAuY29sQ291bnQoJGNlbGwucG9zIC0gc3RhcnQpICsgJGNlbGwubm9kZUFmdGVyIS5hdHRycy5jb2xzcGFuIC0gMTtcbiAgZm9yIChsZXQgcm93ID0gMDsgcm93IDwgbWFwLmhlaWdodDsgcm93KyspIHtcbiAgICBjb25zdCBpbmRleCA9IGNvbCArIHJvdyAqIG1hcC53aWR0aDtcbiAgICAvLyBGb3IgcG9zaXRpb25zIHRoYXQgaGF2ZSBlaXRoZXIgYSBkaWZmZXJlbnQgY2VsbCBvciB0aGUgZW5kXG4gICAgLy8gb2YgdGhlIHRhYmxlIHRvIHRoZWlyIHJpZ2h0LCBhbmQgZWl0aGVyIHRoZSB0b3Agb2YgdGhlIHRhYmxlIG9yXG4gICAgLy8gYSBkaWZmZXJlbnQgY2VsbCBhYm92ZSB0aGVtLCBhZGQgYSBkZWNvcmF0aW9uXG4gICAgaWYgKFxuICAgICAgKGNvbCA9PSBtYXAud2lkdGggLSAxIHx8IG1hcC5tYXBbaW5kZXhdICE9IG1hcC5tYXBbaW5kZXggKyAxXSkgJiZcbiAgICAgIChyb3cgPT0gMCB8fCBtYXAubWFwW2luZGV4XSAhPSBtYXAubWFwW2luZGV4IC0gbWFwLndpZHRoXSlcbiAgICApIHtcbiAgICAgIGNvbnN0IGNlbGxQb3MgPSBtYXAubWFwW2luZGV4XTtcbiAgICAgIGNvbnN0IHBvcyA9IHN0YXJ0ICsgY2VsbFBvcyArIHRhYmxlLm5vZGVBdChjZWxsUG9zKSEubm9kZVNpemUgLSAxO1xuICAgICAgY29uc3QgZG9tID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICBkb20uY2xhc3NOYW1lID0gJ2NvbHVtbi1yZXNpemUtaGFuZGxlJztcbiAgICAgIGlmIChjb2x1bW5SZXNpemluZ1BsdWdpbktleS5nZXRTdGF0ZShzdGF0ZSk/LmRyYWdnaW5nKSB7XG4gICAgICAgIGRlY29yYXRpb25zLnB1c2goXG4gICAgICAgICAgRGVjb3JhdGlvbi5ub2RlKFxuICAgICAgICAgICAgc3RhcnQgKyBjZWxsUG9zLFxuICAgICAgICAgICAgc3RhcnQgKyBjZWxsUG9zICsgdGFibGUubm9kZUF0KGNlbGxQb3MpIS5ub2RlU2l6ZSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgY2xhc3M6ICdjb2x1bW4tcmVzaXplLWRyYWdnaW5nJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgZGVjb3JhdGlvbnMucHVzaChEZWNvcmF0aW9uLndpZGdldChwb3MsIGRvbSkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gRGVjb3JhdGlvblNldC5jcmVhdGUoc3RhdGUuZG9jLCBkZWNvcmF0aW9ucyk7XG59XG4iLCAiLy8gVGhpcyBmaWxlIGRlZmluZXMgYSBwbHVnaW4gdGhhdCBoYW5kbGVzIHRoZSBkcmF3aW5nIG9mIGNlbGxcbi8vIHNlbGVjdGlvbnMgYW5kIHRoZSBiYXNpYyB1c2VyIGludGVyYWN0aW9ucyBmb3IgY3JlYXRpbmcgYW5kIHdvcmtpbmdcbi8vIHdpdGggc3VjaCBzZWxlY3Rpb25zLiBJdCBhbHNvIG1ha2VzIHN1cmUgdGhhdCwgYWZ0ZXIgZWFjaFxuLy8gdHJhbnNhY3Rpb24sIHRoZSBzaGFwZXMgb2YgdGFibGVzIGFyZSBub3JtYWxpemVkIHRvIGJlIHJlY3Rhbmd1bGFyXG4vLyBhbmQgbm90IGNvbnRhaW4gb3ZlcmxhcHBpbmcgY2VsbHMuXG5cbmltcG9ydCB7IFBsdWdpbiB9IGZyb20gJ3Byb3NlbWlycm9yLXN0YXRlJztcblxuaW1wb3J0IHsgZHJhd0NlbGxTZWxlY3Rpb24sIG5vcm1hbGl6ZVNlbGVjdGlvbiB9IGZyb20gJy4vY2VsbHNlbGVjdGlvbic7XG5pbXBvcnQgeyBmaXhUYWJsZXMsIGZpeFRhYmxlc0tleSB9IGZyb20gJy4vZml4dGFibGVzJztcbmltcG9ydCB7XG4gIGhhbmRsZUtleURvd24sXG4gIGhhbmRsZU1vdXNlRG93bixcbiAgaGFuZGxlUGFzdGUsXG4gIGhhbmRsZVRyaXBsZUNsaWNrLFxufSBmcm9tICcuL2lucHV0JztcbmltcG9ydCB7IHRhYmxlRWRpdGluZ0tleSB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCB7IENlbGxCb29rbWFyaywgQ2VsbFNlbGVjdGlvbiB9IGZyb20gJy4vY2VsbHNlbGVjdGlvbic7XG5leHBvcnQgdHlwZSB7IENlbGxTZWxlY3Rpb25KU09OIH0gZnJvbSAnLi9jZWxsc2VsZWN0aW9uJztcbmV4cG9ydCB7XG4gIGNvbHVtblJlc2l6aW5nLFxuICBjb2x1bW5SZXNpemluZ1BsdWdpbktleSxcbiAgUmVzaXplU3RhdGUsXG59IGZyb20gJy4vY29sdW1ucmVzaXppbmcnO1xuZXhwb3J0IHR5cGUgeyBDb2x1bW5SZXNpemluZ09wdGlvbnMsIERyYWdnaW5nIH0gZnJvbSAnLi9jb2x1bW5yZXNpemluZyc7XG5leHBvcnQgKiBmcm9tICcuL2NvbW1hbmRzJztcbmV4cG9ydCB7XG4gIGNsaXBDZWxscyBhcyBfX2NsaXBDZWxscyxcbiAgaW5zZXJ0Q2VsbHMgYXMgX19pbnNlcnRDZWxscyxcbiAgcGFzdGVkQ2VsbHMgYXMgX19wYXN0ZWRDZWxscyxcbn0gZnJvbSAnLi9jb3B5cGFzdGUnO1xuZXhwb3J0IHR5cGUgeyBBcmVhIGFzIF9fQXJlYSB9IGZyb20gJy4vY29weXBhc3RlJztcbmV4cG9ydCB0eXBlIHsgRGlyZWN0aW9uIH0gZnJvbSAnLi9pbnB1dCc7XG5leHBvcnQgeyB0YWJsZU5vZGVzLCB0YWJsZU5vZGVUeXBlcyB9IGZyb20gJy4vc2NoZW1hJztcbmV4cG9ydCB0eXBlIHtcbiAgQ2VsbEF0dHJpYnV0ZXMsXG4gIGdldEZyb21ET00sXG4gIHNldERPTUF0dHIsXG4gIFRhYmxlTm9kZXMsXG4gIFRhYmxlTm9kZXNPcHRpb25zLFxuICBUYWJsZVJvbGUsXG59IGZyb20gJy4vc2NoZW1hJztcbmV4cG9ydCB7IFRhYmxlTWFwIH0gZnJvbSAnLi90YWJsZW1hcCc7XG5leHBvcnQgdHlwZSB7IENvbFdpZHRocywgUHJvYmxlbSwgUmVjdCB9IGZyb20gJy4vdGFibGVtYXAnO1xuZXhwb3J0IHsgVGFibGVWaWV3LCB1cGRhdGVDb2x1bW5zT25SZXNpemUgfSBmcm9tICcuL3RhYmxldmlldyc7XG5leHBvcnQge1xuICBhZGRDb2xTcGFuLFxuICBjZWxsQXJvdW5kLFxuICBjZWxsTmVhcixcbiAgY29sQ291bnQsXG4gIGNvbHVtbklzSGVhZGVyLFxuICBmaW5kQ2VsbCxcbiAgaW5TYW1lVGFibGUsXG4gIGlzSW5UYWJsZSxcbiAgbW92ZUNlbGxGb3J3YXJkLFxuICBuZXh0Q2VsbCxcbiAgcG9pbnRzQXRDZWxsLFxuICByZW1vdmVDb2xTcGFuLFxuICBzZWxlY3Rpb25DZWxsLFxufSBmcm9tICcuL3V0aWwnO1xuZXhwb3J0IHR5cGUgeyBNdXRhYmxlQXR0cnMgfSBmcm9tICcuL3V0aWwnO1xuZXhwb3J0IHsgZmluZENlbGxQb3MsIGZpbmRDZWxsUmFuZ2UsIGZpbmRUYWJsZSB9IGZyb20gJy4vdXRpbHMvcXVlcnknO1xuZXhwb3J0IHR5cGUgeyBGaW5kTm9kZVJlc3VsdCB9IGZyb20gJy4vdXRpbHMvcXVlcnknO1xuZXhwb3J0IHsgZml4VGFibGVzLCBmaXhUYWJsZXNLZXksIGhhbmRsZVBhc3RlLCB0YWJsZUVkaXRpbmdLZXkgfTtcblxuLyoqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCB0eXBlIFRhYmxlRWRpdGluZ09wdGlvbnMgPSB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGFsbG93IHRhYmxlIG5vZGUgc2VsZWN0aW9uLlxuICAgKlxuICAgKiBCeSBkZWZhdWx0LCBhbnkgbm9kZSBzZWxlY3Rpb24gd3JhcHBpbmcgYSB0YWJsZSB3aWxsIGJlIGNvbnZlcnRlZCBpbnRvIGFcbiAgICogQ2VsbFNlbGVjdGlvbiB3cmFwcGluZyBhbGwgY2VsbHMgaW4gdGhlIHRhYmxlLiBZb3UgY2FuIHBhc3MgYHRydWVgIHRvIGFsbG93XG4gICAqIHRoZSBzZWxlY3Rpb24gdG8gcmVtYWluIGEgTm9kZVNlbGVjdGlvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGFsbG93VGFibGVOb2RlU2VsZWN0aW9uPzogYm9vbGVhbjtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIFtwbHVnaW5dKGh0dHA6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLlBsdWdpbilcbiAqIHRoYXQsIHdoZW4gYWRkZWQgdG8gYW4gZWRpdG9yLCBlbmFibGVzIGNlbGwtc2VsZWN0aW9uLCBoYW5kbGVzXG4gKiBjZWxsLWJhc2VkIGNvcHkvcGFzdGUsIGFuZCBtYWtlcyBzdXJlIHRhYmxlcyBzdGF5IHdlbGwtZm9ybWVkIChlYWNoXG4gKiByb3cgaGFzIHRoZSBzYW1lIHdpZHRoLCBhbmQgY2VsbHMgZG9uJ3Qgb3ZlcmxhcCkuXG4gKlxuICogWW91IHNob3VsZCBwcm9iYWJseSBwdXQgdGhpcyBwbHVnaW4gbmVhciB0aGUgZW5kIG9mIHlvdXIgYXJyYXkgb2ZcbiAqIHBsdWdpbnMsIHNpbmNlIGl0IGhhbmRsZXMgbW91c2UgYW5kIGFycm93IGtleSBldmVudHMgaW4gdGFibGVzXG4gKiByYXRoZXIgYnJvYWRseSwgYW5kIG90aGVyIHBsdWdpbnMsIGxpa2UgdGhlIGdhcCBjdXJzb3Igb3IgdGhlXG4gKiBjb2x1bW4td2lkdGggZHJhZ2dpbmcgcGx1Z2luLCBtaWdodCB3YW50IHRvIGdldCBhIHR1cm4gZmlyc3QgdG9cbiAqIHBlcmZvcm0gbW9yZSBzcGVjaWZpYyBiZWhhdmlvci5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0YWJsZUVkaXRpbmcoe1xuICBhbGxvd1RhYmxlTm9kZVNlbGVjdGlvbiA9IGZhbHNlLFxufTogVGFibGVFZGl0aW5nT3B0aW9ucyA9IHt9KTogUGx1Z2luIHtcbiAgcmV0dXJuIG5ldyBQbHVnaW4oe1xuICAgIGtleTogdGFibGVFZGl0aW5nS2V5LFxuXG4gICAgLy8gVGhpcyBwaWVjZSBvZiBzdGF0ZSBpcyB1c2VkIHRvIHJlbWVtYmVyIHdoZW4gYSBtb3VzZS1kcmFnXG4gICAgLy8gY2VsbC1zZWxlY3Rpb24gaXMgaGFwcGVuaW5nLCBzbyB0aGF0IGl0IGNhbiBjb250aW51ZSBldmVuIGFzXG4gICAgLy8gdHJhbnNhY3Rpb25zICh3aGljaCBtaWdodCBtb3ZlIGl0cyBhbmNob3IgY2VsbCkgY29tZSBpbi5cbiAgICBzdGF0ZToge1xuICAgICAgaW5pdCgpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9LFxuICAgICAgYXBwbHkodHIsIGN1cikge1xuICAgICAgICBjb25zdCBzZXQgPSB0ci5nZXRNZXRhKHRhYmxlRWRpdGluZ0tleSk7XG4gICAgICAgIGlmIChzZXQgIT0gbnVsbCkgcmV0dXJuIHNldCA9PSAtMSA/IG51bGwgOiBzZXQ7XG4gICAgICAgIGlmIChjdXIgPT0gbnVsbCB8fCAhdHIuZG9jQ2hhbmdlZCkgcmV0dXJuIGN1cjtcbiAgICAgICAgY29uc3QgeyBkZWxldGVkLCBwb3MgfSA9IHRyLm1hcHBpbmcubWFwUmVzdWx0KGN1cik7XG4gICAgICAgIHJldHVybiBkZWxldGVkID8gbnVsbCA6IHBvcztcbiAgICAgIH0sXG4gICAgfSxcblxuICAgIHByb3BzOiB7XG4gICAgICBkZWNvcmF0aW9uczogZHJhd0NlbGxTZWxlY3Rpb24sXG5cbiAgICAgIGhhbmRsZURPTUV2ZW50czoge1xuICAgICAgICBtb3VzZWRvd246IGhhbmRsZU1vdXNlRG93bixcbiAgICAgIH0sXG5cbiAgICAgIGNyZWF0ZVNlbGVjdGlvbkJldHdlZW4odmlldykge1xuICAgICAgICByZXR1cm4gdGFibGVFZGl0aW5nS2V5LmdldFN0YXRlKHZpZXcuc3RhdGUpICE9IG51bGxcbiAgICAgICAgICA/IHZpZXcuc3RhdGUuc2VsZWN0aW9uXG4gICAgICAgICAgOiBudWxsO1xuICAgICAgfSxcblxuICAgICAgaGFuZGxlVHJpcGxlQ2xpY2ssXG5cbiAgICAgIGhhbmRsZUtleURvd24sXG5cbiAgICAgIGhhbmRsZVBhc3RlLFxuICAgIH0sXG5cbiAgICBhcHBlbmRUcmFuc2FjdGlvbihfLCBvbGRTdGF0ZSwgc3RhdGUpIHtcbiAgICAgIHJldHVybiBub3JtYWxpemVTZWxlY3Rpb24oXG4gICAgICAgIHN0YXRlLFxuICAgICAgICBmaXhUYWJsZXMoc3RhdGUsIG9sZFN0YXRlKSxcbiAgICAgICAgYWxsb3dUYWJsZU5vZGVTZWxlY3Rpb24sXG4gICAgICApO1xuICAgIH0sXG4gIH0pO1xufVxuIiwgImltcG9ydCAnLi4vdHlwZXMuanMnXG5cbmltcG9ydCB7IG1lcmdlQXR0cmlidXRlcywgTm9kZSB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuaW1wb3J0IHsgY3JlYXRlQWxpZ25BdHRyaWJ1dGUgfSBmcm9tICcuLi91dGlsaXRpZXMvcGFyc2VBbGlnbi5qcydcblxuZXhwb3J0IGludGVyZmFjZSBUYWJsZUNlbGxPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBIVE1MIGF0dHJpYnV0ZXMgZm9yIGEgdGFibGUgY2VsbCBub2RlLlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAZXhhbXBsZSB7IGNsYXNzOiAnZm9vJyB9XG4gICAqL1xuICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PlxufVxuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gY3JlYXRlIHRhYmxlIGNlbGxzLlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9ub2Rlcy90YWJsZS1jZWxsXG4gKi9cbmV4cG9ydCBjb25zdCBUYWJsZUNlbGwgPSBOb2RlLmNyZWF0ZTxUYWJsZUNlbGxPcHRpb25zPih7XG4gIG5hbWU6ICd0YWJsZUNlbGwnLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgY29udGVudDogJ2Jsb2NrKycsXG5cbiAgYWRkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29sc3Bhbjoge1xuICAgICAgICBkZWZhdWx0OiAxLFxuICAgICAgfSxcbiAgICAgIHJvd3NwYW46IHtcbiAgICAgICAgZGVmYXVsdDogMSxcbiAgICAgIH0sXG4gICAgICBjb2x3aWR0aDoge1xuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgICBwYXJzZUhUTUw6IGVsZW1lbnQgPT4ge1xuICAgICAgICAgIGNvbnN0IGNvbHdpZHRoID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2NvbHdpZHRoJylcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IGNvbHdpZHRoID8gY29sd2lkdGguc3BsaXQoJywnKS5tYXAod2lkdGggPT4gcGFyc2VJbnQod2lkdGgsIDEwKSkgOiBudWxsXG5cbiAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBubyBjb2x3aWR0aCBhdHRyaWJ1dGUgb24gdGhlIGNlbGwsIHRyeSB0byBnZXQgaXQgZnJvbSB0aGUgY29sZ3JvdXBcbiAgICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBjb2xzID0gZWxlbWVudC5jbG9zZXN0KCd0YWJsZScpPy5xdWVyeVNlbGVjdG9yQWxsKCdjb2xncm91cCA+IGNvbCcpXG4gICAgICAgICAgICBjb25zdCBjZWxsSW5kZXggPSBBcnJheS5mcm9tKGVsZW1lbnQucGFyZW50RWxlbWVudD8uY2hpbGRyZW4gfHwgW10pLmluZGV4T2YoZWxlbWVudClcblxuICAgICAgICAgICAgaWYgKGNlbGxJbmRleCAmJiBjZWxsSW5kZXggPiAtMSAmJiBjb2xzICYmIGNvbHNbY2VsbEluZGV4XSkge1xuICAgICAgICAgICAgICBjb25zdCBjb2xXaWR0aCA9IGNvbHNbY2VsbEluZGV4XS5nZXRBdHRyaWJ1dGUoJ3dpZHRoJylcbiAgICAgICAgICAgICAgcmV0dXJuIGNvbFdpZHRoID8gW3BhcnNlSW50KGNvbFdpZHRoLCAxMCldIDogbnVsbFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB2YWx1ZVxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFsaWduOiBjcmVhdGVBbGlnbkF0dHJpYnV0ZSgpLFxuICAgIH1cbiAgfSxcblxuICB0YWJsZVJvbGU6ICdjZWxsJyxcblxuICBpc29sYXRpbmc6IHRydWUsXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbeyB0YWc6ICd0ZCcgfV1cbiAgfSxcblxuICByZW5kZXJIVE1MKHsgSFRNTEF0dHJpYnV0ZXMgfSkge1xuICAgIHJldHVybiBbJ3RkJywgbWVyZ2VBdHRyaWJ1dGVzKHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcywgSFRNTEF0dHJpYnV0ZXMpLCAwXVxuICB9LFxufSlcbiIsICJpbXBvcnQgdHlwZSB7IEF0dHJpYnV0ZSB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuLyoqXG4gKiBTdXBwb3J0ZWQgdGFibGUgY2VsbCBhbGlnbm1lbnQgdmFsdWVzXG4gKi9cbmV4cG9ydCBlbnVtIFRhYmxlQ2VsbEFsaWduIHtcbiAgTGVmdCA9ICdsZWZ0JyxcbiAgUmlnaHQgPSAncmlnaHQnLFxuICBDZW50ZXIgPSAnY2VudGVyJyxcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgdW5rbm93biBpbnB1dCBpbnRvIGEgc3VwcG9ydGVkIHRhYmxlIGFsaWdubWVudFxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIEEgcG90ZW50aWFsIGFsaWdubWVudCB2YWx1ZVxuICogQHJldHVybnMgQSB2YWxpZCBUYWJsZUNlbGxBbGlnbiB2YWx1ZSBvciBudWxsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVUYWJsZUNlbGxBbGlnbih2YWx1ZTogdW5rbm93bik6IFRhYmxlQ2VsbEFsaWduIHwgbnVsbCB7XG4gIGlmIChcbiAgICB2YWx1ZSA9PT0gVGFibGVDZWxsQWxpZ24uTGVmdCB8fFxuICAgIHZhbHVlID09PSBUYWJsZUNlbGxBbGlnbi5SaWdodCB8fFxuICAgIHZhbHVlID09PSBUYWJsZUNlbGxBbGlnbi5DZW50ZXJcbiAgKSB7XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICByZXR1cm4gbnVsbFxufVxuXG4vKipcbiAqIFBhcnNlIHRhYmxlIGNlbGwgYWxpZ25tZW50IGZyb20gYW4gSFRNTCBlbGVtZW50XG4gKlxuICogUHJlZmVycyBpbmxpbmUgc3R5bGUgKCR7XCJgXCJ9dGV4dC1hbGlnbiR7XCJgXCJ9KSBhbmQgZmFsbHMgYmFjayB0byB0aGUgbGVnYWN5XG4gKiAke1wiYFwifWFsaWduJHtcImBcIn0gYXR0cmlidXRlLlxuICpcbiAqIEBwYXJhbSBlbGVtZW50IC0gVGhlIHRhYmxlIGNlbGwvaGVhZGVyIERPTSBlbGVtZW50XG4gKiBAcmV0dXJucyBBIHZhbGlkIFRhYmxlQ2VsbEFsaWduIHZhbHVlIG9yIG51bGxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlQWxpZ24oZWxlbWVudDogSFRNTEVsZW1lbnQpOiBUYWJsZUNlbGxBbGlnbiB8IG51bGwge1xuICBjb25zdCBzdHlsZUFsaWduID0gKGVsZW1lbnQuc3R5bGUudGV4dEFsaWduIHx8ICcnKS50cmltKCkudG9Mb3dlckNhc2UoKVxuICBjb25zdCBhdHRyQWxpZ24gPSAoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2FsaWduJykgfHwgJycpLnRyaW0oKS50b0xvd2VyQ2FzZSgpXG4gIGNvbnN0IGFsaWduID0gc3R5bGVBbGlnbiB8fCBhdHRyQWxpZ25cblxuICByZXR1cm4gbm9ybWFsaXplVGFibGVDZWxsQWxpZ24oYWxpZ24pXG59XG5cbi8qKlxuICogTm9ybWFsaXplIGFsaWdubWVudCBmcm9tIGEgZ2VuZXJpYyBhdHRycyBvYmplY3QgdGhhdCBtYXkgaW5jbHVkZSBhbiBhbGlnbiBmaWVsZFxuICpcbiAqIEBwYXJhbSBhdHRyaWJ1dGVzIC0gQSBub2RlIGF0dHJzLWxpa2Ugb2JqZWN0IHdpdGggYW4gb3B0aW9uYWwgYWxpZ24gZmllbGRcbiAqIEByZXR1cm5zIEEgdmFsaWQgVGFibGVDZWxsQWxpZ24gdmFsdWUgb3IgbnVsbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVRhYmxlQ2VsbEFsaWduRnJvbUF0dHJpYnV0ZXMoXG4gIGF0dHJpYnV0ZXM6IHsgYWxpZ24/OiBUYWJsZUNlbGxBbGlnbiB9IHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IFRhYmxlQ2VsbEFsaWduIHwgbnVsbCB7XG4gIHJldHVybiBub3JtYWxpemVUYWJsZUNlbGxBbGlnbihhdHRyaWJ1dGVzPy5hbGlnbilcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSByZXVzYWJsZSBUaXB0YXAgYXR0cmlidXRlIGNvbmZpZyBmb3IgdGFibGUgYWxpZ25tZW50XG4gKlxuICogQHJldHVybnMgQSBUaXB0YXAgQXR0cmlidXRlIGRlZmluaXRpb24gdGhhdCBwYXJzZXMgYW5kIHJlbmRlcnMgdGFibGUgYWxpZ25tZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBbGlnbkF0dHJpYnV0ZSgpOiBBdHRyaWJ1dGUge1xuICByZXR1cm4ge1xuICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgcGFyc2VIVE1MOiAoZWxlbWVudDogSFRNTEVsZW1lbnQpID0+IHBhcnNlQWxpZ24oZWxlbWVudCksXG4gICAgcmVuZGVySFRNTDogKGF0dHJpYnV0ZXM6IHsgYWxpZ24/OiBUYWJsZUNlbGxBbGlnbiB8IG51bGwgfSkgPT4ge1xuICAgICAgaWYgKCFhdHRyaWJ1dGVzLmFsaWduKSB7XG4gICAgICAgIHJldHVybiB7fVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdHlsZTogYHRleHQtYWxpZ246ICR7YXR0cmlidXRlcy5hbGlnbn1gLFxuICAgICAgfVxuICAgIH0sXG4gIH1cbn1cbiIsICJpbXBvcnQgJy4uL3R5cGVzLmpzJ1xuXG5pbXBvcnQgeyBtZXJnZUF0dHJpYnV0ZXMsIE5vZGUgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5cbmltcG9ydCB7IGNyZWF0ZUFsaWduQXR0cmlidXRlIH0gZnJvbSAnLi4vdXRpbGl0aWVzL3BhcnNlQWxpZ24uanMnXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGFibGVIZWFkZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBIVE1MIGF0dHJpYnV0ZXMgZm9yIGEgdGFibGUgaGVhZGVyIG5vZGUuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG59XG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBjcmVhdGUgdGFibGUgaGVhZGVycy5cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvbm9kZXMvdGFibGUtaGVhZGVyXG4gKi9cbmV4cG9ydCBjb25zdCBUYWJsZUhlYWRlciA9IE5vZGUuY3JlYXRlPFRhYmxlSGVhZGVyT3B0aW9ucz4oe1xuICBuYW1lOiAndGFibGVIZWFkZXInLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgY29udGVudDogJ2Jsb2NrKycsXG5cbiAgYWRkQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgY29sc3Bhbjoge1xuICAgICAgICBkZWZhdWx0OiAxLFxuICAgICAgfSxcbiAgICAgIHJvd3NwYW46IHtcbiAgICAgICAgZGVmYXVsdDogMSxcbiAgICAgIH0sXG4gICAgICBjb2x3aWR0aDoge1xuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgICBwYXJzZUhUTUw6IGVsZW1lbnQgPT4ge1xuICAgICAgICAgIGNvbnN0IGNvbHdpZHRoID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2NvbHdpZHRoJylcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IGNvbHdpZHRoID8gY29sd2lkdGguc3BsaXQoJywnKS5tYXAod2lkdGggPT4gcGFyc2VJbnQod2lkdGgsIDEwKSkgOiBudWxsXG5cbiAgICAgICAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBhbGlnbjogY3JlYXRlQWxpZ25BdHRyaWJ1dGUoKSxcbiAgICB9XG4gIH0sXG5cbiAgdGFibGVSb2xlOiAnaGVhZGVyX2NlbGwnLFxuXG4gIGlzb2xhdGluZzogdHJ1ZSxcblxuICBwYXJzZUhUTUwoKSB7XG4gICAgcmV0dXJuIFt7IHRhZzogJ3RoJyB9XVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgcmV0dXJuIFsndGgnLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyksIDBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuaW1wb3J0IHR5cGUgeyBUYWJsZUNlbGxPcHRpb25zIH0gZnJvbSAnLi4vY2VsbC9pbmRleC5qcydcbmltcG9ydCB7IFRhYmxlQ2VsbCB9IGZyb20gJy4uL2NlbGwvaW5kZXguanMnXG5pbXBvcnQgdHlwZSB7IFRhYmxlSGVhZGVyT3B0aW9ucyB9IGZyb20gJy4uL2hlYWRlci9pbmRleC5qcydcbmltcG9ydCB7IFRhYmxlSGVhZGVyIH0gZnJvbSAnLi4vaGVhZGVyL2luZGV4LmpzJ1xuaW1wb3J0IHR5cGUgeyBUYWJsZVJvd09wdGlvbnMgfSBmcm9tICcuLi9yb3cvaW5kZXguanMnXG5pbXBvcnQgeyBUYWJsZVJvdyB9IGZyb20gJy4uL3Jvdy9pbmRleC5qcydcbmltcG9ydCB0eXBlIHsgVGFibGVPcHRpb25zIH0gZnJvbSAnLi4vdGFibGUvaW5kZXguanMnXG5pbXBvcnQgeyBUYWJsZSB9IGZyb20gJy4uL3RhYmxlL2luZGV4LmpzJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFRhYmxlS2l0T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSB0YWJsZSBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSB0YWJsZTogZmFsc2VcbiAgICovXG4gIHRhYmxlOiBQYXJ0aWFsPFRhYmxlT3B0aW9ucz4gfCBmYWxzZVxuICAvKipcbiAgICogSWYgc2V0IHRvIGZhbHNlLCB0aGUgdGFibGUgZXh0ZW5zaW9uIHdpbGwgbm90IGJlIHJlZ2lzdGVyZWRcbiAgICogQGV4YW1wbGUgdGFibGVDZWxsOiBmYWxzZVxuICAgKi9cbiAgdGFibGVDZWxsOiBQYXJ0aWFsPFRhYmxlQ2VsbE9wdGlvbnM+IHwgZmFsc2VcbiAgLyoqXG4gICAqIElmIHNldCB0byBmYWxzZSwgdGhlIHRhYmxlIGV4dGVuc2lvbiB3aWxsIG5vdCBiZSByZWdpc3RlcmVkXG4gICAqIEBleGFtcGxlIHRhYmxlSGVhZGVyOiBmYWxzZVxuICAgKi9cbiAgdGFibGVIZWFkZXI6IFBhcnRpYWw8VGFibGVIZWFkZXJPcHRpb25zPiB8IGZhbHNlXG4gIC8qKlxuICAgKiBJZiBzZXQgdG8gZmFsc2UsIHRoZSB0YWJsZSBleHRlbnNpb24gd2lsbCBub3QgYmUgcmVnaXN0ZXJlZFxuICAgKiBAZXhhbXBsZSB0YWJsZVJvdzogZmFsc2VcbiAgICovXG4gIHRhYmxlUm93OiBQYXJ0aWFsPFRhYmxlUm93T3B0aW9ucz4gfCBmYWxzZVxufVxuXG4vKipcbiAqIFRoZSB0YWJsZSBraXQgaXMgYSBjb2xsZWN0aW9uIG9mIHRhYmxlIGVkaXRvciBleHRlbnNpb25zLlxuICpcbiAqIEl04oCZcyBhIGdvb2Qgc3RhcnRpbmcgcG9pbnQgZm9yIGJ1aWxkaW5nIHlvdXIgb3duIHRhYmxlIGluIFRpcHRhcC5cbiAqL1xuZXhwb3J0IGNvbnN0IFRhYmxlS2l0ID0gRXh0ZW5zaW9uLmNyZWF0ZTxUYWJsZUtpdE9wdGlvbnM+KHtcbiAgbmFtZTogJ3RhYmxlS2l0JyxcblxuICBhZGRFeHRlbnNpb25zKCkge1xuICAgIGNvbnN0IGV4dGVuc2lvbnMgPSBbXVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy50YWJsZSAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChUYWJsZS5jb25maWd1cmUodGhpcy5vcHRpb25zLnRhYmxlKSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5vcHRpb25zLnRhYmxlQ2VsbCAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChUYWJsZUNlbGwuY29uZmlndXJlKHRoaXMub3B0aW9ucy50YWJsZUNlbGwpKVxuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMudGFibGVIZWFkZXIgIT09IGZhbHNlKSB7XG4gICAgICBleHRlbnNpb25zLnB1c2goVGFibGVIZWFkZXIuY29uZmlndXJlKHRoaXMub3B0aW9ucy50YWJsZUhlYWRlcikpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy50YWJsZVJvdyAhPT0gZmFsc2UpIHtcbiAgICAgIGV4dGVuc2lvbnMucHVzaChUYWJsZVJvdy5jb25maWd1cmUodGhpcy5vcHRpb25zLnRhYmxlUm93KSlcbiAgICB9XG5cbiAgICByZXR1cm4gZXh0ZW5zaW9uc1xuICB9LFxufSlcbiIsICJpbXBvcnQgJy4uL3R5cGVzLmpzJ1xuXG5pbXBvcnQgeyBtZXJnZUF0dHJpYnV0ZXMsIE5vZGUgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5cbmV4cG9ydCBpbnRlcmZhY2UgVGFibGVSb3dPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBIVE1MIGF0dHJpYnV0ZXMgZm9yIGEgdGFibGUgcm93IG5vZGUuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG59XG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBjcmVhdGUgdGFibGUgcm93cy5cbiAqIEBzZWUgaHR0cHM6Ly93d3cudGlwdGFwLmRldi9hcGkvbm9kZXMvdGFibGUtcm93XG4gKi9cbmV4cG9ydCBjb25zdCBUYWJsZVJvdyA9IE5vZGUuY3JlYXRlPFRhYmxlUm93T3B0aW9ucz4oe1xuICBuYW1lOiAndGFibGVSb3cnLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgY29udGVudDogJyh0YWJsZUNlbGwgfCB0YWJsZUhlYWRlcikqJyxcblxuICB0YWJsZVJvbGU6ICdyb3cnLFxuXG4gIHBhcnNlSFRNTCgpIHtcbiAgICByZXR1cm4gW3sgdGFnOiAndHInIH1dXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICByZXR1cm4gWyd0cicsIG1lcmdlQXR0cmlidXRlcyh0aGlzLm9wdGlvbnMuSFRNTEF0dHJpYnV0ZXMsIEhUTUxBdHRyaWJ1dGVzKSwgMF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0ICcuLi90eXBlcy5qcydcblxuaW1wb3J0IHtcbiAgdHlwZSBKU09OQ29udGVudCxcbiAgdHlwZSBNYXJrZG93blRva2VuLFxuICBjYWxsT3JSZXR1cm4sXG4gIGdldEV4dGVuc2lvbkZpZWxkLFxuICBtZXJnZUF0dHJpYnV0ZXMsXG4gIE5vZGUsXG59IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB0eXBlIHsgRE9NT3V0cHV0U3BlYywgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgVGV4dFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQge1xuICBhZGRDb2x1bW5BZnRlcixcbiAgYWRkQ29sdW1uQmVmb3JlLFxuICBhZGRSb3dBZnRlcixcbiAgYWRkUm93QmVmb3JlLFxuICBDZWxsU2VsZWN0aW9uLFxuICBjb2x1bW5SZXNpemluZyxcbiAgZGVsZXRlQ29sdW1uLFxuICBkZWxldGVSb3csXG4gIGRlbGV0ZVRhYmxlLFxuICBmaXhUYWJsZXMsXG4gIGdvVG9OZXh0Q2VsbCxcbiAgbWVyZ2VDZWxscyxcbiAgc2V0Q2VsbEF0dHIsXG4gIHNwbGl0Q2VsbCxcbiAgdGFibGVFZGl0aW5nLFxuICB0b2dnbGVIZWFkZXIsXG4gIHRvZ2dsZUhlYWRlckNlbGwsXG59IGZyb20gJ0B0aXB0YXAvcG0vdGFibGVzJ1xuaW1wb3J0IHR5cGUgeyBFZGl0b3JWaWV3LCBOb2RlVmlldyB9IGZyb20gJ0B0aXB0YXAvcG0vdmlldydcblxuaW1wb3J0IHsgdHlwZSBUYWJsZUNlbGxBbGlnbiwgbm9ybWFsaXplVGFibGVDZWxsQWxpZ24gfSBmcm9tICcuLi91dGlsaXRpZXMvcGFyc2VBbGlnbi5qcydcbmltcG9ydCB7IFRhYmxlVmlldyB9IGZyb20gJy4vVGFibGVWaWV3LmpzJ1xuaW1wb3J0IHsgY3JlYXRlQ29sR3JvdXAgfSBmcm9tICcuL3V0aWxpdGllcy9jcmVhdGVDb2xHcm91cC5qcydcbmltcG9ydCB7IGNyZWF0ZVRhYmxlIH0gZnJvbSAnLi91dGlsaXRpZXMvY3JlYXRlVGFibGUuanMnXG5pbXBvcnQgeyBkZWxldGVUYWJsZVdoZW5BbGxDZWxsc1NlbGVjdGVkIH0gZnJvbSAnLi91dGlsaXRpZXMvZGVsZXRlVGFibGVXaGVuQWxsQ2VsbHNTZWxlY3RlZC5qcydcbmltcG9ydCByZW5kZXJUYWJsZVRvTWFya2Rvd24gZnJvbSAnLi91dGlsaXRpZXMvbWFya2Rvd24uanMnXG5cbnR5cGUgTWFya2Rvd25UYWJsZVRva2VuID0ge1xuICBhbGlnbj86IEFycmF5PFRhYmxlQ2VsbEFsaWduIHwgbnVsbD5cbiAgaGVhZGVyPzogeyB0b2tlbnM6IE1hcmtkb3duVG9rZW5bXTsgYWxpZ24/OiBUYWJsZUNlbGxBbGlnbiB8IG51bGwgfVtdXG4gIHJvd3M/OiB7IHRva2VuczogTWFya2Rvd25Ub2tlbltdOyBhbGlnbj86IFRhYmxlQ2VsbEFsaWduIHwgbnVsbCB9W11bXVxufSAmIE1hcmtkb3duVG9rZW5cblxuZXhwb3J0IGludGVyZmFjZSBUYWJsZU9wdGlvbnMge1xuICAvKipcbiAgICogSFRNTCBhdHRyaWJ1dGVzIGZvciB0aGUgdGFibGUgZWxlbWVudC5cbiAgICogQGRlZmF1bHQge31cbiAgICogQGV4YW1wbGUgeyBjbGFzczogJ2ZvbycgfVxuICAgKi9cbiAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT5cblxuICAvKipcbiAgICogRW5hYmxlcyB0aGUgcmVzaXppbmcgb2YgdGFibGVzLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKiBAZXhhbXBsZSB0cnVlXG4gICAqL1xuICByZXNpemFibGU6IGJvb2xlYW5cblxuICAvKipcbiAgICogQ29udHJvbHMgd2hldGhlciB0aGUgdGFibGUgc2hvdWxkIGJlIHdyYXBwZWQgaW4gYSBkaXYgd2l0aCBjbGFzcyBcInRhYmxlV3JhcHBlclwiIHdoZW4gcmVuZGVyZWQuXG4gICAqIEluIGVkaXRhYmxlIG1vZGUgd2l0aCByZXNpemFibGUgdGFibGVzLCB0aGlzIHdyYXBwZXIgaXMgYWx3YXlzIHByZXNlbnQgdmlhIFRhYmxlVmlldy5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGV4YW1wbGUgdHJ1ZVxuICAgKi9cbiAgcmVuZGVyV3JhcHBlcjogYm9vbGVhblxuXG4gIC8qKlxuICAgKiBUaGUgd2lkdGggb2YgdGhlIHJlc2l6ZSBoYW5kbGUuXG4gICAqIEBkZWZhdWx0IDVcbiAgICogQGV4YW1wbGUgMTBcbiAgICovXG4gIGhhbmRsZVdpZHRoOiBudW1iZXJcblxuICAvKipcbiAgICogVGhlIG1pbmltdW0gd2lkdGggb2YgYSBjZWxsLlxuICAgKiBAZGVmYXVsdCAyNVxuICAgKiBAZXhhbXBsZSA1MFxuICAgKi9cbiAgY2VsbE1pbldpZHRoOiBudW1iZXJcblxuICAvKipcbiAgICogVGhlIG5vZGUgdmlldyB0byByZW5kZXIgdGhlIHRhYmxlLlxuICAgKiBAZGVmYXVsdCBUYWJsZVZpZXdcbiAgICovXG4gIFZpZXc6XG4gICAgfCAobmV3IChcbiAgICAgICAgbm9kZTogUHJvc2VNaXJyb3JOb2RlLFxuICAgICAgICBjZWxsTWluV2lkdGg6IG51bWJlcixcbiAgICAgICAgdmlldzogRWRpdG9yVmlldyxcbiAgICAgICAgSFRNTEF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgICAgKSA9PiBOb2RlVmlldylcbiAgICB8IG51bGxcblxuICAvKipcbiAgICogRW5hYmxlcyB0aGUgcmVzaXppbmcgb2YgdGhlIGxhc3QgY29sdW1uLlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqIEBleGFtcGxlIGZhbHNlXG4gICAqL1xuICBsYXN0Q29sdW1uUmVzaXphYmxlOiBib29sZWFuXG5cbiAgLyoqXG4gICAqIEFsbG93IHRhYmxlIG5vZGUgc2VsZWN0aW9uLlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKiBAZXhhbXBsZSB0cnVlXG4gICAqL1xuICBhbGxvd1RhYmxlTm9kZVNlbGVjdGlvbjogYm9vbGVhblxufVxuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgdGFibGU6IHtcbiAgICAgIC8qKlxuICAgICAgICogSW5zZXJ0IGEgdGFibGVcbiAgICAgICAqIEBwYXJhbSBvcHRpb25zIFRoZSB0YWJsZSBhdHRyaWJ1dGVzXG4gICAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBjb21tYW5kIHdhcyBzdWNjZXNzZnVsLCBvdGhlcndpc2UgZmFsc2VcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5pbnNlcnRUYWJsZSh7IHJvd3M6IDMsIGNvbHM6IDMsIHdpdGhIZWFkZXJSb3c6IHRydWUgfSlcbiAgICAgICAqL1xuICAgICAgaW5zZXJ0VGFibGU6IChvcHRpb25zPzoge1xuICAgICAgICByb3dzPzogbnVtYmVyXG4gICAgICAgIGNvbHM/OiBudW1iZXJcbiAgICAgICAgd2l0aEhlYWRlclJvdz86IGJvb2xlYW5cbiAgICAgIH0pID0+IFJldHVyblR5cGVcblxuICAgICAgLyoqXG4gICAgICAgKiBBZGQgYSBjb2x1bW4gYmVmb3JlIHRoZSBjdXJyZW50IGNvbHVtblxuICAgICAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29tbWFuZCB3YXMgc3VjY2Vzc2Z1bCwgb3RoZXJ3aXNlIGZhbHNlXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuYWRkQ29sdW1uQmVmb3JlKClcbiAgICAgICAqL1xuICAgICAgYWRkQ29sdW1uQmVmb3JlOiAoKSA9PiBSZXR1cm5UeXBlXG5cbiAgICAgIC8qKlxuICAgICAgICogQWRkIGEgY29sdW1uIGFmdGVyIHRoZSBjdXJyZW50IGNvbHVtblxuICAgICAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29tbWFuZCB3YXMgc3VjY2Vzc2Z1bCwgb3RoZXJ3aXNlIGZhbHNlXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuYWRkQ29sdW1uQWZ0ZXIoKVxuICAgICAgICovXG4gICAgICBhZGRDb2x1bW5BZnRlcjogKCkgPT4gUmV0dXJuVHlwZVxuXG4gICAgICAvKipcbiAgICAgICAqIERlbGV0ZSB0aGUgY3VycmVudCBjb2x1bW5cbiAgICAgICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGNvbW1hbmQgd2FzIHN1Y2Nlc3NmdWwsIG90aGVyd2lzZSBmYWxzZVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmRlbGV0ZUNvbHVtbigpXG4gICAgICAgKi9cbiAgICAgIGRlbGV0ZUNvbHVtbjogKCkgPT4gUmV0dXJuVHlwZVxuXG4gICAgICAvKipcbiAgICAgICAqIEFkZCBhIHJvdyBiZWZvcmUgdGhlIGN1cnJlbnQgcm93XG4gICAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBjb21tYW5kIHdhcyBzdWNjZXNzZnVsLCBvdGhlcndpc2UgZmFsc2VcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5hZGRSb3dCZWZvcmUoKVxuICAgICAgICovXG4gICAgICBhZGRSb3dCZWZvcmU6ICgpID0+IFJldHVyblR5cGVcblxuICAgICAgLyoqXG4gICAgICAgKiBBZGQgYSByb3cgYWZ0ZXIgdGhlIGN1cnJlbnQgcm93XG4gICAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBjb21tYW5kIHdhcyBzdWNjZXNzZnVsLCBvdGhlcndpc2UgZmFsc2VcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5hZGRSb3dBZnRlcigpXG4gICAgICAgKi9cbiAgICAgIGFkZFJvd0FmdGVyOiAoKSA9PiBSZXR1cm5UeXBlXG5cbiAgICAgIC8qKlxuICAgICAgICogRGVsZXRlIHRoZSBjdXJyZW50IHJvd1xuICAgICAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29tbWFuZCB3YXMgc3VjY2Vzc2Z1bCwgb3RoZXJ3aXNlIGZhbHNlXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuZGVsZXRlUm93KClcbiAgICAgICAqL1xuICAgICAgZGVsZXRlUm93OiAoKSA9PiBSZXR1cm5UeXBlXG5cbiAgICAgIC8qKlxuICAgICAgICogRGVsZXRlIHRoZSBjdXJyZW50IHRhYmxlXG4gICAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBjb21tYW5kIHdhcyBzdWNjZXNzZnVsLCBvdGhlcndpc2UgZmFsc2VcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5kZWxldGVUYWJsZSgpXG4gICAgICAgKi9cbiAgICAgIGRlbGV0ZVRhYmxlOiAoKSA9PiBSZXR1cm5UeXBlXG5cbiAgICAgIC8qKlxuICAgICAgICogTWVyZ2UgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBjZWxsc1xuICAgICAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29tbWFuZCB3YXMgc3VjY2Vzc2Z1bCwgb3RoZXJ3aXNlIGZhbHNlXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMubWVyZ2VDZWxscygpXG4gICAgICAgKi9cbiAgICAgIG1lcmdlQ2VsbHM6ICgpID0+IFJldHVyblR5cGVcblxuICAgICAgLyoqXG4gICAgICAgKiBTcGxpdCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIGNlbGxcbiAgICAgICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGNvbW1hbmQgd2FzIHN1Y2Nlc3NmdWwsIG90aGVyd2lzZSBmYWxzZVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNwbGl0Q2VsbCgpXG4gICAgICAgKi9cbiAgICAgIHNwbGl0Q2VsbDogKCkgPT4gUmV0dXJuVHlwZVxuXG4gICAgICAvKipcbiAgICAgICAqIFRvZ2dsZSB0aGUgaGVhZGVyIGNvbHVtblxuICAgICAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29tbWFuZCB3YXMgc3VjY2Vzc2Z1bCwgb3RoZXJ3aXNlIGZhbHNlXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudG9nZ2xlSGVhZGVyQ29sdW1uKClcbiAgICAgICAqL1xuICAgICAgdG9nZ2xlSGVhZGVyQ29sdW1uOiAoKSA9PiBSZXR1cm5UeXBlXG5cbiAgICAgIC8qKlxuICAgICAgICogVG9nZ2xlIHRoZSBoZWFkZXIgcm93XG4gICAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBjb21tYW5kIHdhcyBzdWNjZXNzZnVsLCBvdGhlcndpc2UgZmFsc2VcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVIZWFkZXJSb3coKVxuICAgICAgICovXG4gICAgICB0b2dnbGVIZWFkZXJSb3c6ICgpID0+IFJldHVyblR5cGVcblxuICAgICAgLyoqXG4gICAgICAgKiBUb2dnbGUgdGhlIGhlYWRlciBjZWxsXG4gICAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBjb21tYW5kIHdhcyBzdWNjZXNzZnVsLCBvdGhlcndpc2UgZmFsc2VcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVIZWFkZXJDZWxsKClcbiAgICAgICAqL1xuICAgICAgdG9nZ2xlSGVhZGVyQ2VsbDogKCkgPT4gUmV0dXJuVHlwZVxuXG4gICAgICAvKipcbiAgICAgICAqIE1lcmdlIG9yIHNwbGl0IHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgY2VsbHNcbiAgICAgICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGNvbW1hbmQgd2FzIHN1Y2Nlc3NmdWwsIG90aGVyd2lzZSBmYWxzZVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLm1lcmdlT3JTcGxpdCgpXG4gICAgICAgKi9cbiAgICAgIG1lcmdlT3JTcGxpdDogKCkgPT4gUmV0dXJuVHlwZVxuXG4gICAgICAvKipcbiAgICAgICAqIFNldCBhIGNlbGwgYXR0cmlidXRlXG4gICAgICAgKiBAcGFyYW0gbmFtZSBUaGUgYXR0cmlidXRlIG5hbWVcbiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgYXR0cmlidXRlIHZhbHVlXG4gICAgICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBjb21tYW5kIHdhcyBzdWNjZXNzZnVsLCBvdGhlcndpc2UgZmFsc2VcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5zZXRDZWxsQXR0cmlidXRlKCdhbGlnbicsICdyaWdodCcpXG4gICAgICAgKi9cbiAgICAgIHNldENlbGxBdHRyaWJ1dGU6IChuYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnkpID0+IFJldHVyblR5cGVcblxuICAgICAgLyoqXG4gICAgICAgKiBNb3ZlcyB0aGUgc2VsZWN0aW9uIHRvIHRoZSBuZXh0IGNlbGxcbiAgICAgICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGNvbW1hbmQgd2FzIHN1Y2Nlc3NmdWwsIG90aGVyd2lzZSBmYWxzZVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmdvVG9OZXh0Q2VsbCgpXG4gICAgICAgKi9cbiAgICAgIGdvVG9OZXh0Q2VsbDogKCkgPT4gUmV0dXJuVHlwZVxuXG4gICAgICAvKipcbiAgICAgICAqIE1vdmVzIHRoZSBzZWxlY3Rpb24gdG8gdGhlIHByZXZpb3VzIGNlbGxcbiAgICAgICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGNvbW1hbmQgd2FzIHN1Y2Nlc3NmdWwsIG90aGVyd2lzZSBmYWxzZVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmdvVG9QcmV2aW91c0NlbGwoKVxuICAgICAgICovXG4gICAgICBnb1RvUHJldmlvdXNDZWxsOiAoKSA9PiBSZXR1cm5UeXBlXG5cbiAgICAgIC8qKlxuICAgICAgICogVHJ5IHRvIGZpeCB0aGUgdGFibGUgc3RydWN0dXJlIGlmIG5lY2Vzc2FyeVxuICAgICAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY29tbWFuZCB3YXMgc3VjY2Vzc2Z1bCwgb3RoZXJ3aXNlIGZhbHNlXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuZml4VGFibGVzKClcbiAgICAgICAqL1xuICAgICAgZml4VGFibGVzOiAoKSA9PiBSZXR1cm5UeXBlXG5cbiAgICAgIC8qKlxuICAgICAgICogU2V0IGEgY2VsbCBzZWxlY3Rpb24gaW5zaWRlIHRoZSBjdXJyZW50IHRhYmxlXG4gICAgICAgKiBAcGFyYW0gcG9zaXRpb24gVGhlIGNlbGwgcG9zaXRpb25cbiAgICAgICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGNvbW1hbmQgd2FzIHN1Y2Nlc3NmdWwsIG90aGVyd2lzZSBmYWxzZVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldENlbGxTZWxlY3Rpb24oeyBhbmNob3JDZWxsOiAxLCBoZWFkQ2VsbDogMiB9KVxuICAgICAgICovXG4gICAgICBzZXRDZWxsU2VsZWN0aW9uOiAocG9zaXRpb246IHsgYW5jaG9yQ2VsbDogbnVtYmVyOyBoZWFkQ2VsbD86IG51bWJlciB9KSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBjcmVhdGUgdGFibGVzLlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9ub2Rlcy90YWJsZVxuICovXG5leHBvcnQgY29uc3QgVGFibGUgPSBOb2RlLmNyZWF0ZTxUYWJsZU9wdGlvbnM+KHtcbiAgbmFtZTogJ3RhYmxlJyxcblxuICAvLyBAdHMtaWdub3JlXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICAgIHJlc2l6YWJsZTogZmFsc2UsXG4gICAgICByZW5kZXJXcmFwcGVyOiBmYWxzZSxcbiAgICAgIGhhbmRsZVdpZHRoOiA1LFxuICAgICAgY2VsbE1pbldpZHRoOiAyNSxcbiAgICAgIC8vIFRPRE86IGZpeFxuICAgICAgVmlldzogVGFibGVWaWV3LFxuICAgICAgbGFzdENvbHVtblJlc2l6YWJsZTogdHJ1ZSxcbiAgICAgIGFsbG93VGFibGVOb2RlU2VsZWN0aW9uOiBmYWxzZSxcbiAgICB9XG4gIH0sXG5cbiAgY29udGVudDogJ3RhYmxlUm93KycsXG5cbiAgdGFibGVSb2xlOiAndGFibGUnLFxuXG4gIGlzb2xhdGluZzogdHJ1ZSxcblxuICBncm91cDogJ2Jsb2NrJyxcblxuICBwYXJzZUhUTUwoKSB7XG4gICAgcmV0dXJuIFt7IHRhZzogJ3RhYmxlJyB9XVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBub2RlLCBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgY29uc3QgeyBjb2xncm91cCwgdGFibGVXaWR0aCwgdGFibGVNaW5XaWR0aCB9ID0gY3JlYXRlQ29sR3JvdXAobm9kZSwgdGhpcy5vcHRpb25zLmNlbGxNaW5XaWR0aClcblxuICAgIGNvbnN0IHVzZXJTdHlsZXMgPSBIVE1MQXR0cmlidXRlcy5zdHlsZSBhcyBzdHJpbmcgfCB1bmRlZmluZWRcblxuICAgIGZ1bmN0aW9uIGdldFRhYmxlU3R5bGUoKSB7XG4gICAgICBpZiAodXNlclN0eWxlcykge1xuICAgICAgICByZXR1cm4gdXNlclN0eWxlc1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGFibGVXaWR0aCA/IGB3aWR0aDogJHt0YWJsZVdpZHRofWAgOiBgbWluLXdpZHRoOiAke3RhYmxlTWluV2lkdGh9YFxuICAgIH1cblxuICAgIGNvbnN0IHRhYmxlOiBET01PdXRwdXRTcGVjID0gW1xuICAgICAgJ3RhYmxlJyxcbiAgICAgIG1lcmdlQXR0cmlidXRlcyh0aGlzLm9wdGlvbnMuSFRNTEF0dHJpYnV0ZXMsIEhUTUxBdHRyaWJ1dGVzLCB7XG4gICAgICAgIHN0eWxlOiBnZXRUYWJsZVN0eWxlKCksXG4gICAgICB9KSxcbiAgICAgIGNvbGdyb3VwLFxuICAgICAgWyd0Ym9keScsIDBdLFxuICAgIF1cblxuICAgIHJldHVybiB0aGlzLm9wdGlvbnMucmVuZGVyV3JhcHBlciA/IFsnZGl2JywgeyBjbGFzczogJ3RhYmxlV3JhcHBlcicgfSwgdGFibGVdIDogdGFibGVcbiAgfSxcblxuICBwYXJzZU1hcmtkb3duOiAodG9rZW46IE1hcmtkb3duVGFibGVUb2tlbiwgaCkgPT4ge1xuICAgIGNvbnN0IHJvd3MgPSBbXVxuICAgIGNvbnN0IGFsaWdubWVudHMgPSBBcnJheS5pc0FycmF5KHRva2VuLmFsaWduKSA/IHRva2VuLmFsaWduIDogW11cblxuICAgIGlmICh0b2tlbi5oZWFkZXIpIHtcbiAgICAgIGNvbnN0IGhlYWRlckNlbGxzOiBKU09OQ29udGVudFtdID0gW11cblxuICAgICAgdG9rZW4uaGVhZGVyLmZvckVhY2goKGNlbGwsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGFsaWduID0gbm9ybWFsaXplVGFibGVDZWxsQWxpZ24oYWxpZ25tZW50c1tpbmRleF0gPz8gY2VsbC5hbGlnbilcbiAgICAgICAgY29uc3QgYXR0cnMgPSBhbGlnbiA/IHsgYWxpZ24gfSA6IHt9XG5cbiAgICAgICAgaGVhZGVyQ2VsbHMucHVzaChcbiAgICAgICAgICBoLmNyZWF0ZU5vZGUoJ3RhYmxlSGVhZGVyJywgYXR0cnMsIFtcbiAgICAgICAgICAgIHsgdHlwZTogJ3BhcmFncmFwaCcsIGNvbnRlbnQ6IGgucGFyc2VJbmxpbmUoY2VsbC50b2tlbnMpIH0sXG4gICAgICAgICAgXSksXG4gICAgICAgIClcbiAgICAgIH0pXG5cbiAgICAgIHJvd3MucHVzaChoLmNyZWF0ZU5vZGUoJ3RhYmxlUm93Jywge30sIGhlYWRlckNlbGxzKSlcbiAgICB9XG5cbiAgICBpZiAodG9rZW4ucm93cykge1xuICAgICAgdG9rZW4ucm93cy5mb3JFYWNoKHJvdyA9PiB7XG4gICAgICAgIGNvbnN0IGJvZHlDZWxsczogSlNPTkNvbnRlbnRbXSA9IFtdXG4gICAgICAgIHJvdy5mb3JFYWNoKChjZWxsLCBpbmRleCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGFsaWduID0gbm9ybWFsaXplVGFibGVDZWxsQWxpZ24oYWxpZ25tZW50c1tpbmRleF0gPz8gY2VsbC5hbGlnbilcbiAgICAgICAgICBjb25zdCBhdHRycyA9IGFsaWduID8geyBhbGlnbiB9IDoge31cblxuICAgICAgICAgIGJvZHlDZWxscy5wdXNoKFxuICAgICAgICAgICAgaC5jcmVhdGVOb2RlKCd0YWJsZUNlbGwnLCBhdHRycywgW1xuICAgICAgICAgICAgICB7IHR5cGU6ICdwYXJhZ3JhcGgnLCBjb250ZW50OiBoLnBhcnNlSW5saW5lKGNlbGwudG9rZW5zKSB9LFxuICAgICAgICAgICAgXSksXG4gICAgICAgICAgKVxuICAgICAgICB9KVxuICAgICAgICByb3dzLnB1c2goaC5jcmVhdGVOb2RlKCd0YWJsZVJvdycsIHt9LCBib2R5Q2VsbHMpKVxuICAgICAgfSlcbiAgICB9XG5cbiAgICByZXR1cm4gaC5jcmVhdGVOb2RlKCd0YWJsZScsIHVuZGVmaW5lZCwgcm93cylcbiAgfSxcblxuICByZW5kZXJNYXJrZG93bjogKG5vZGUsIGgpID0+IHtcbiAgICByZXR1cm4gcmVuZGVyVGFibGVUb01hcmtkb3duKG5vZGUsIGgpXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGluc2VydFRhYmxlOlxuICAgICAgICAoeyByb3dzID0gMywgY29scyA9IDMsIHdpdGhIZWFkZXJSb3cgPSB0cnVlIH0gPSB7fSkgPT5cbiAgICAgICAgKHsgdHIsIGRpc3BhdGNoLCBlZGl0b3IgfSkgPT4ge1xuICAgICAgICAgIGNvbnN0IG5vZGUgPSBjcmVhdGVUYWJsZShlZGl0b3Iuc2NoZW1hLCByb3dzLCBjb2xzLCB3aXRoSGVhZGVyUm93KVxuXG4gICAgICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgICAgICBjb25zdCBvZmZzZXQgPSB0ci5zZWxlY3Rpb24uZnJvbSArIDFcblxuICAgICAgICAgICAgdHIucmVwbGFjZVNlbGVjdGlvbldpdGgobm9kZSlcbiAgICAgICAgICAgICAgLnNjcm9sbEludG9WaWV3KClcbiAgICAgICAgICAgICAgLnNldFNlbGVjdGlvbihUZXh0U2VsZWN0aW9uLm5lYXIodHIuZG9jLnJlc29sdmUob2Zmc2V0KSkpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSxcbiAgICAgIGFkZENvbHVtbkJlZm9yZTpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gYWRkQ29sdW1uQmVmb3JlKHN0YXRlLCBkaXNwYXRjaClcbiAgICAgICAgfSxcbiAgICAgIGFkZENvbHVtbkFmdGVyOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBhZGRDb2x1bW5BZnRlcihzdGF0ZSwgZGlzcGF0Y2gpXG4gICAgICAgIH0sXG4gICAgICBkZWxldGVDb2x1bW46XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGRlbGV0ZUNvbHVtbihzdGF0ZSwgZGlzcGF0Y2gpXG4gICAgICAgIH0sXG4gICAgICBhZGRSb3dCZWZvcmU6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGFkZFJvd0JlZm9yZShzdGF0ZSwgZGlzcGF0Y2gpXG4gICAgICAgIH0sXG4gICAgICBhZGRSb3dBZnRlcjpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gYWRkUm93QWZ0ZXIoc3RhdGUsIGRpc3BhdGNoKVxuICAgICAgICB9LFxuICAgICAgZGVsZXRlUm93OlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBkZWxldGVSb3coc3RhdGUsIGRpc3BhdGNoKVxuICAgICAgICB9LFxuICAgICAgZGVsZXRlVGFibGU6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGRlbGV0ZVRhYmxlKHN0YXRlLCBkaXNwYXRjaClcbiAgICAgICAgfSxcbiAgICAgIG1lcmdlQ2VsbHM6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIG1lcmdlQ2VsbHMoc3RhdGUsIGRpc3BhdGNoKVxuICAgICAgICB9LFxuICAgICAgc3BsaXRDZWxsOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBzcGxpdENlbGwoc3RhdGUsIGRpc3BhdGNoKVxuICAgICAgICB9LFxuICAgICAgdG9nZ2xlSGVhZGVyQ29sdW1uOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgICAgICAgIHJldHVybiB0b2dnbGVIZWFkZXIoJ2NvbHVtbicpKHN0YXRlLCBkaXNwYXRjaClcbiAgICAgICAgfSxcbiAgICAgIHRvZ2dsZUhlYWRlclJvdzpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gdG9nZ2xlSGVhZGVyKCdyb3cnKShzdGF0ZSwgZGlzcGF0Y2gpXG4gICAgICAgIH0sXG4gICAgICB0b2dnbGVIZWFkZXJDZWxsOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgICAgICAgIHJldHVybiB0b2dnbGVIZWFkZXJDZWxsKHN0YXRlLCBkaXNwYXRjaClcbiAgICAgICAgfSxcbiAgICAgIG1lcmdlT3JTcGxpdDpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICAgICAgICBpZiAobWVyZ2VDZWxscyhzdGF0ZSwgZGlzcGF0Y2gpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBzcGxpdENlbGwoc3RhdGUsIGRpc3BhdGNoKVxuICAgICAgICB9LFxuICAgICAgc2V0Q2VsbEF0dHJpYnV0ZTpcbiAgICAgICAgKG5hbWUsIHZhbHVlKSA9PlxuICAgICAgICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBzZXRDZWxsQXR0cihuYW1lLCB2YWx1ZSkoc3RhdGUsIGRpc3BhdGNoKVxuICAgICAgICB9LFxuICAgICAgZ29Ub05leHRDZWxsOlxuICAgICAgICAoKSA9PlxuICAgICAgICAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICAgICAgICAgIHJldHVybiBnb1RvTmV4dENlbGwoMSkoc3RhdGUsIGRpc3BhdGNoKVxuICAgICAgICB9LFxuICAgICAgZ29Ub1ByZXZpb3VzQ2VsbDpcbiAgICAgICAgKCkgPT5cbiAgICAgICAgKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgICAgICAgICByZXR1cm4gZ29Ub05leHRDZWxsKC0xKShzdGF0ZSwgZGlzcGF0Y2gpXG4gICAgICAgIH0sXG4gICAgICBmaXhUYWJsZXM6XG4gICAgICAgICgpID0+XG4gICAgICAgICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgICAgICBmaXhUYWJsZXMoc3RhdGUpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfSxcbiAgICAgIHNldENlbGxTZWxlY3Rpb246XG4gICAgICAgIHBvc2l0aW9uID0+XG4gICAgICAgICh7IHRyLCBkaXNwYXRjaCB9KSA9PiB7XG4gICAgICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3Rpb24gPSBDZWxsU2VsZWN0aW9uLmNyZWF0ZSh0ci5kb2MsIHBvc2l0aW9uLmFuY2hvckNlbGwsIHBvc2l0aW9uLmhlYWRDZWxsKVxuXG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24oc2VsZWN0aW9uKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBUYWI6ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuZWRpdG9yLmNvbW1hbmRzLmdvVG9OZXh0Q2VsbCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5lZGl0b3IuY2FuKCkuYWRkUm93QWZ0ZXIoKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZWRpdG9yLmNoYWluKCkuYWRkUm93QWZ0ZXIoKS5nb1RvTmV4dENlbGwoKS5ydW4oKVxuICAgICAgfSxcbiAgICAgICdTaGlmdC1UYWInOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5nb1RvUHJldmlvdXNDZWxsKCksXG4gICAgICBCYWNrc3BhY2U6IGRlbGV0ZVRhYmxlV2hlbkFsbENlbGxzU2VsZWN0ZWQsXG4gICAgICAnTW9kLUJhY2tzcGFjZSc6IGRlbGV0ZVRhYmxlV2hlbkFsbENlbGxzU2VsZWN0ZWQsXG4gICAgICBEZWxldGU6IGRlbGV0ZVRhYmxlV2hlbkFsbENlbGxzU2VsZWN0ZWQsXG4gICAgICAnTW9kLURlbGV0ZSc6IGRlbGV0ZVRhYmxlV2hlbkFsbENlbGxzU2VsZWN0ZWQsXG4gICAgfVxuICB9LFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICBjb25zdCBpc1Jlc2l6YWJsZSA9IHRoaXMub3B0aW9ucy5yZXNpemFibGUgJiYgdGhpcy5lZGl0b3IuaXNFZGl0YWJsZVxuXG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLihpc1Jlc2l6YWJsZVxuICAgICAgICA/IFtcbiAgICAgICAgICAgIGNvbHVtblJlc2l6aW5nKHtcbiAgICAgICAgICAgICAgaGFuZGxlV2lkdGg6IHRoaXMub3B0aW9ucy5oYW5kbGVXaWR0aCxcbiAgICAgICAgICAgICAgY2VsbE1pbldpZHRoOiB0aGlzLm9wdGlvbnMuY2VsbE1pbldpZHRoLFxuICAgICAgICAgICAgICBkZWZhdWx0Q2VsbE1pbldpZHRoOiB0aGlzLm9wdGlvbnMuY2VsbE1pbldpZHRoLFxuICAgICAgICAgICAgICBWaWV3OiB0aGlzLm9wdGlvbnMuVmlldyxcbiAgICAgICAgICAgICAgbGFzdENvbHVtblJlc2l6YWJsZTogdGhpcy5vcHRpb25zLmxhc3RDb2x1bW5SZXNpemFibGUsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdXG4gICAgICAgIDogW10pLFxuICAgICAgdGFibGVFZGl0aW5nKHtcbiAgICAgICAgYWxsb3dUYWJsZU5vZGVTZWxlY3Rpb246IHRoaXMub3B0aW9ucy5hbGxvd1RhYmxlTm9kZVNlbGVjdGlvbixcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcblxuICBhZGROb2RlVmlldygpIHtcbiAgICAvLyBXaGVuIHJlc2l6YWJsZSwgdGhlIGNvbHVtblJlc2l6aW5nIHBsdWdpbiByZWdpc3RlcnMgaXRzIG93biBOb2RlVmlldy5cbiAgICAvLyBXZSBvbmx5IHJlZ2lzdGVyIG9uZSBoZXJlIGZvciB0aGUgbm9uLXJlc2l6YWJsZSBjYXNlIHNvIHRoYXRcbiAgICAvLyA8Y29sZ3JvdXA+IHN0YXlzIGluIHN5bmMgd2l0aCBjb2x1bW4gY2hhbmdlcyAoaXNzdWUgIzcwMTUpLlxuICAgIGNvbnN0IGlzUmVzaXphYmxlID0gdGhpcy5vcHRpb25zLnJlc2l6YWJsZSAmJiB0aGlzLmVkaXRvci5pc0VkaXRhYmxlXG4gICAgY29uc3QgVmlldyA9IHRoaXMub3B0aW9ucy5WaWV3XG5cbiAgICBpZiAoaXNSZXNpemFibGUgfHwgIVZpZXcpIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgcmV0dXJuICh7IG5vZGUsIHZpZXcsIEhUTUxBdHRyaWJ1dGVzIH0pID0+IHtcbiAgICAgIGNvbnN0IG1lcmdlZEF0dHJpYnV0ZXMgPSBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcylcblxuICAgICAgcmV0dXJuIG5ldyBWaWV3KG5vZGUsIHRoaXMub3B0aW9ucy5jZWxsTWluV2lkdGgsIHZpZXcsIG1lcmdlZEF0dHJpYnV0ZXMpIGFzIE5vZGVWaWV3XG4gICAgfVxuICB9LFxuXG4gIGV4dGVuZE5vZGVTY2hlbWEoZXh0ZW5zaW9uKSB7XG4gICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgIG5hbWU6IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgb3B0aW9uczogZXh0ZW5zaW9uLm9wdGlvbnMsXG4gICAgICBzdG9yYWdlOiBleHRlbnNpb24uc3RvcmFnZSxcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgdGFibGVSb2xlOiBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQoZXh0ZW5zaW9uLCAndGFibGVSb2xlJywgY29udGV4dCkpLFxuICAgIH1cbiAgfSxcbn0pXG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGdldENvbFN0eWxlRGVjbGFyYXRpb24oXG4gIG1pbldpZHRoOiBudW1iZXIsXG4gIHdpZHRoOiBudW1iZXIgfCB1bmRlZmluZWQsXG4pOiBbc3RyaW5nLCBzdHJpbmddIHtcbiAgaWYgKHdpZHRoKSB7XG4gICAgLy8gYXBwbHkgdGhlIHN0b3JlZCB3aWR0aCB1bmxlc3MgaXQgaXMgYmVsb3cgdGhlIGNvbmZpZ3VyZWQgbWluaW11bSBjZWxsIHdpZHRoXG4gICAgcmV0dXJuIFsnd2lkdGgnLCBgJHtNYXRoLm1heCh3aWR0aCwgbWluV2lkdGgpfXB4YF1cbiAgfVxuXG4gIC8vIHNldCB0aGUgbWluaW11bSB3aXRoIG9uIHRoZSBjb2x1bW4gaWYgaXQgaGFzIG5vIHN0b3JlZCB3aWR0aFxuICByZXR1cm4gWydtaW4td2lkdGgnLCBgJHttaW5XaWR0aH1weGBdXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgdHlwZSB7IEVkaXRvclZpZXcsIE5vZGVWaWV3LCBWaWV3TXV0YXRpb25SZWNvcmQgfSBmcm9tICdAdGlwdGFwL3BtL3ZpZXcnXG5cbmltcG9ydCB7IGdldENvbFN0eWxlRGVjbGFyYXRpb24gfSBmcm9tICcuL3V0aWxpdGllcy9jb2xTdHlsZS5qcydcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUNvbHVtbnMoXG4gIG5vZGU6IFByb3NlTWlycm9yTm9kZSxcbiAgY29sZ3JvdXA6IEhUTUxUYWJsZUNvbEVsZW1lbnQsIC8vIDxjb2xncm91cD4gaGFzIHRoZSBzYW1lIHByb3RvdHlwZSBhcyA8Y29sPlxuICB0YWJsZTogSFRNTFRhYmxlRWxlbWVudCxcbiAgY2VsbE1pbldpZHRoOiBudW1iZXIsXG4gIG92ZXJyaWRlQ29sPzogbnVtYmVyLFxuICBvdmVycmlkZVZhbHVlPzogbnVtYmVyLFxuKSB7XG4gIGxldCB0b3RhbFdpZHRoID0gMFxuICBsZXQgZml4ZWRXaWR0aCA9IHRydWVcbiAgbGV0IG5leHRET00gPSBjb2xncm91cC5maXJzdENoaWxkXG4gIGNvbnN0IHJvdyA9IG5vZGUuZmlyc3RDaGlsZFxuXG4gIGlmIChyb3cgIT09IG51bGwpIHtcbiAgICBmb3IgKGxldCBpID0gMCwgY29sID0gMDsgaSA8IHJvdy5jaGlsZENvdW50OyBpICs9IDEpIHtcbiAgICAgIGNvbnN0IHsgY29sc3BhbiwgY29sd2lkdGggfSA9IHJvdy5jaGlsZChpKS5hdHRyc1xuXG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvbHNwYW47IGogKz0gMSwgY29sICs9IDEpIHtcbiAgICAgICAgY29uc3QgaGFzV2lkdGggPVxuICAgICAgICAgIG92ZXJyaWRlQ29sID09PSBjb2wgPyBvdmVycmlkZVZhbHVlIDogKChjb2x3aWR0aCAmJiBjb2x3aWR0aFtqXSkgYXMgbnVtYmVyIHwgdW5kZWZpbmVkKVxuICAgICAgICBjb25zdCBjc3NXaWR0aCA9IGhhc1dpZHRoID8gYCR7aGFzV2lkdGh9cHhgIDogJydcblxuICAgICAgICB0b3RhbFdpZHRoICs9IGhhc1dpZHRoIHx8IGNlbGxNaW5XaWR0aFxuXG4gICAgICAgIGlmICghaGFzV2lkdGgpIHtcbiAgICAgICAgICBmaXhlZFdpZHRoID0gZmFsc2VcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghbmV4dERPTSkge1xuICAgICAgICAgIGNvbnN0IGNvbEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjb2wnKVxuXG4gICAgICAgICAgY29uc3QgW3Byb3BlcnR5S2V5LCBwcm9wZXJ0eVZhbHVlXSA9IGdldENvbFN0eWxlRGVjbGFyYXRpb24oY2VsbE1pbldpZHRoLCBoYXNXaWR0aClcblxuICAgICAgICAgIGNvbEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkocHJvcGVydHlLZXksIHByb3BlcnR5VmFsdWUpXG5cbiAgICAgICAgICBjb2xncm91cC5hcHBlbmRDaGlsZChjb2xFbGVtZW50KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICgobmV4dERPTSBhcyBIVE1MVGFibGVDb2xFbGVtZW50KS5zdHlsZS53aWR0aCAhPT0gY3NzV2lkdGgpIHtcbiAgICAgICAgICAgIGNvbnN0IFtwcm9wZXJ0eUtleSwgcHJvcGVydHlWYWx1ZV0gPSBnZXRDb2xTdHlsZURlY2xhcmF0aW9uKGNlbGxNaW5XaWR0aCwgaGFzV2lkdGgpXG5cbiAgICAgICAgICAgIDsobmV4dERPTSBhcyBIVE1MVGFibGVDb2xFbGVtZW50KS5zdHlsZS5zZXRQcm9wZXJ0eShwcm9wZXJ0eUtleSwgcHJvcGVydHlWYWx1ZSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBuZXh0RE9NID0gbmV4dERPTS5uZXh0U2libGluZ1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgd2hpbGUgKG5leHRET00pIHtcbiAgICBjb25zdCBhZnRlciA9IG5leHRET00ubmV4dFNpYmxpbmdcblxuICAgIG5leHRET00ucGFyZW50Tm9kZT8ucmVtb3ZlQ2hpbGQobmV4dERPTSlcbiAgICBuZXh0RE9NID0gYWZ0ZXJcbiAgfVxuXG4gIC8vIENoZWNrIGlmIHVzZXIgaGFzIHNldCBhIHdpZHRoIHN0eWxlIG9uIHRoZSB0YWJsZSBub2RlXG4gIGNvbnN0IGhhc1VzZXJXaWR0aCA9XG4gICAgbm9kZS5hdHRycy5zdHlsZSAmJlxuICAgIHR5cGVvZiBub2RlLmF0dHJzLnN0eWxlID09PSAnc3RyaW5nJyAmJlxuICAgIC9cXGJ3aWR0aFxccyo6L2kudGVzdChub2RlLmF0dHJzLnN0eWxlKVxuXG4gIGlmIChmaXhlZFdpZHRoICYmICFoYXNVc2VyV2lkdGgpIHtcbiAgICB0YWJsZS5zdHlsZS53aWR0aCA9IGAke3RvdGFsV2lkdGh9cHhgXG4gICAgdGFibGUuc3R5bGUubWluV2lkdGggPSAnJ1xuICB9IGVsc2Uge1xuICAgIHRhYmxlLnN0eWxlLndpZHRoID0gJydcbiAgICB0YWJsZS5zdHlsZS5taW5XaWR0aCA9IGAke3RvdGFsV2lkdGh9cHhgXG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFRhYmxlVmlldyBpbXBsZW1lbnRzIE5vZGVWaWV3IHtcbiAgbm9kZTogUHJvc2VNaXJyb3JOb2RlXG5cbiAgY2VsbE1pbldpZHRoOiBudW1iZXJcblxuICBkb206IEhUTUxEaXZFbGVtZW50XG5cbiAgdGFibGU6IEhUTUxUYWJsZUVsZW1lbnRcblxuICBjb2xncm91cDogSFRNTFRhYmxlQ29sRWxlbWVudFxuXG4gIGNvbnRlbnRET006IEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50XG5cbiAgY29uc3RydWN0b3IoXG4gICAgbm9kZTogUHJvc2VNaXJyb3JOb2RlLFxuICAgIGNlbGxNaW5XaWR0aDogbnVtYmVyLFxuICAgIF92aWV3PzogRWRpdG9yVmlldyxcbiAgICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9LFxuICApIHtcbiAgICB0aGlzLm5vZGUgPSBub2RlXG4gICAgdGhpcy5jZWxsTWluV2lkdGggPSBjZWxsTWluV2lkdGhcbiAgICB0aGlzLmRvbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgdGhpcy5kb20uY2xhc3NOYW1lID0gJ3RhYmxlV3JhcHBlcidcbiAgICB0aGlzLnRhYmxlID0gdGhpcy5kb20uYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGFibGUnKSlcblxuICAgIC8vIEFwcGx5IGV4dGVuc2lvbi1jb25maWd1cmVkIEhUTUxBdHRyaWJ1dGVzIHRvIHRoZSB0YWJsZSBlbGVtZW50XG4gICAgLy8gKGUuZy4gY2xhc3MsIGRhdGEtKiBzZXQgdmlhIFRhYmxlLmNvbmZpZ3VyZSh7IEhUTUxBdHRyaWJ1dGVzIH0pKVxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKEhUTUxBdHRyaWJ1dGVzKSkge1xuICAgICAgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ3N0eWxlJykge1xuICAgICAgICAgIHRoaXMudGFibGUuc3R5bGUuY3NzVGV4dCA9IFN0cmluZyh2YWx1ZSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnRhYmxlLnNldEF0dHJpYnV0ZShrZXksIFN0cmluZyh2YWx1ZSkpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBcHBseSB1c2VyIHN0eWxlcyBmcm9tIHRoZSBQcm9zZU1pcnJvciBkb2N1bWVudCBub2RlLlxuICAgIC8vIFRoaXMgbWF5IGNvbWUgZnJvbSBIVE1MIHBhcnNpbmcgKGUuZy4gPHRhYmxlIHN0eWxlPVwiLi4uXCI+KSBhbmQgc2hvdWxkXG4gICAgLy8gb3ZlcnJpZGUgYW55IHN0eWxlIHNldCB2aWEgZXh0ZW5zaW9uLWNvbmZpZ3VyZWQgSFRNTEF0dHJpYnV0ZXMgYWJvdmUuXG4gICAgaWYgKG5vZGUuYXR0cnMuc3R5bGUpIHtcbiAgICAgIHRoaXMudGFibGUuc3R5bGUuY3NzVGV4dCA9IG5vZGUuYXR0cnMuc3R5bGVcbiAgICB9XG5cbiAgICB0aGlzLmNvbGdyb3VwID0gdGhpcy50YWJsZS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjb2xncm91cCcpKVxuICAgIHVwZGF0ZUNvbHVtbnMobm9kZSwgdGhpcy5jb2xncm91cCwgdGhpcy50YWJsZSwgY2VsbE1pbldpZHRoKVxuICAgIHRoaXMuY29udGVudERPTSA9IHRoaXMudGFibGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGJvZHknKSlcbiAgfVxuXG4gIHVwZGF0ZShub2RlOiBQcm9zZU1pcnJvck5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlICE9PSB0aGlzLm5vZGUudHlwZSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgdGhpcy5ub2RlID0gbm9kZVxuICAgIHVwZGF0ZUNvbHVtbnMobm9kZSwgdGhpcy5jb2xncm91cCwgdGhpcy50YWJsZSwgdGhpcy5jZWxsTWluV2lkdGgpXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgaWdub3JlTXV0YXRpb24obXV0YXRpb246IFZpZXdNdXRhdGlvblJlY29yZCkge1xuICAgIGNvbnN0IHRhcmdldCA9IG11dGF0aW9uLnRhcmdldCBhcyBOb2RlXG4gICAgY29uc3QgaXNJbnNpZGVXcmFwcGVyID0gdGhpcy5kb20uY29udGFpbnModGFyZ2V0KVxuICAgIGNvbnN0IGlzSW5zaWRlQ29udGVudCA9IHRoaXMuY29udGVudERPTS5jb250YWlucyh0YXJnZXQpXG5cbiAgICBpZiAoaXNJbnNpZGVXcmFwcGVyICYmICFpc0luc2lkZUNvbnRlbnQpIHtcbiAgICAgIGlmIChcbiAgICAgICAgbXV0YXRpb24udHlwZSA9PT0gJ2F0dHJpYnV0ZXMnIHx8XG4gICAgICAgIG11dGF0aW9uLnR5cGUgPT09ICdjaGlsZExpc3QnIHx8XG4gICAgICAgIG11dGF0aW9uLnR5cGUgPT09ICdjaGFyYWN0ZXJEYXRhJ1xuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IERPTU91dHB1dFNwZWMsIE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgZ2V0Q29sU3R5bGVEZWNsYXJhdGlvbiB9IGZyb20gJy4vY29sU3R5bGUuanMnXG5cbmV4cG9ydCB0eXBlIENvbEdyb3VwID1cbiAgfCB7XG4gICAgICBjb2xncm91cDogRE9NT3V0cHV0U3BlY1xuICAgICAgdGFibGVXaWR0aDogc3RyaW5nXG4gICAgICB0YWJsZU1pbldpZHRoOiBzdHJpbmdcbiAgICB9XG4gIHwgUmVjb3JkPHN0cmluZywgbmV2ZXI+XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNvbGdyb3VwIGVsZW1lbnQgZm9yIGEgdGFibGUgbm9kZSBpbiBQcm9zZU1pcnJvci5cbiAqXG4gKiBAcGFyYW0gbm9kZSAtIFRoZSBQcm9zZU1pcnJvciBub2RlIHJlcHJlc2VudGluZyB0aGUgdGFibGUuXG4gKiBAcGFyYW0gY2VsbE1pbldpZHRoIC0gVGhlIG1pbmltdW0gd2lkdGggb2YgYSBjZWxsIGluIHRoZSB0YWJsZS5cbiAqIEBwYXJhbSBvdmVycmlkZUNvbCAtIChPcHRpb25hbCkgVGhlIGluZGV4IG9mIHRoZSBjb2x1bW4gdG8gb3ZlcnJpZGUgdGhlIHdpZHRoIG9mLlxuICogQHBhcmFtIG92ZXJyaWRlVmFsdWUgLSAoT3B0aW9uYWwpIFRoZSB3aWR0aCB2YWx1ZSB0byB1c2UgZm9yIHRoZSBvdmVycmlkZGVuIGNvbHVtbi5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBjb2xncm91cCBlbGVtZW50LCB0aGUgdG90YWwgd2lkdGggb2YgdGhlIHRhYmxlLCBhbmQgdGhlIG1pbmltdW0gd2lkdGggb2YgdGhlIHRhYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29sR3JvdXAobm9kZTogUHJvc2VNaXJyb3JOb2RlLCBjZWxsTWluV2lkdGg6IG51bWJlcik6IENvbEdyb3VwXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29sR3JvdXAoXG4gIG5vZGU6IFByb3NlTWlycm9yTm9kZSxcbiAgY2VsbE1pbldpZHRoOiBudW1iZXIsXG4gIG92ZXJyaWRlQ29sOiBudW1iZXIsXG4gIG92ZXJyaWRlVmFsdWU6IG51bWJlcixcbik6IENvbEdyb3VwXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ29sR3JvdXAoXG4gIG5vZGU6IFByb3NlTWlycm9yTm9kZSxcbiAgY2VsbE1pbldpZHRoOiBudW1iZXIsXG4gIG92ZXJyaWRlQ29sPzogbnVtYmVyLFxuICBvdmVycmlkZVZhbHVlPzogbnVtYmVyLFxuKTogQ29sR3JvdXAge1xuICBsZXQgdG90YWxXaWR0aCA9IDBcbiAgbGV0IGZpeGVkV2lkdGggPSB0cnVlXG4gIGNvbnN0IGNvbHM6IERPTU91dHB1dFNwZWNbXSA9IFtdXG4gIGNvbnN0IHJvdyA9IG5vZGUuZmlyc3RDaGlsZFxuXG4gIGlmICghcm93KSB7XG4gICAgcmV0dXJuIHt9XG4gIH1cblxuICBmb3IgKGxldCBpID0gMCwgY29sID0gMDsgaSA8IHJvdy5jaGlsZENvdW50OyBpICs9IDEpIHtcbiAgICBjb25zdCB7IGNvbHNwYW4sIGNvbHdpZHRoIH0gPSByb3cuY2hpbGQoaSkuYXR0cnNcblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgY29sc3BhbjsgaiArPSAxLCBjb2wgKz0gMSkge1xuICAgICAgY29uc3QgaGFzV2lkdGggPVxuICAgICAgICBvdmVycmlkZUNvbCA9PT0gY29sID8gb3ZlcnJpZGVWYWx1ZSA6IGNvbHdpZHRoICYmIChjb2x3aWR0aFtqXSBhcyBudW1iZXIgfCB1bmRlZmluZWQpXG5cbiAgICAgIHRvdGFsV2lkdGggKz0gaGFzV2lkdGggfHwgY2VsbE1pbldpZHRoXG5cbiAgICAgIGlmICghaGFzV2lkdGgpIHtcbiAgICAgICAgZml4ZWRXaWR0aCA9IGZhbHNlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IFtwcm9wZXJ0eSwgdmFsdWVdID0gZ2V0Q29sU3R5bGVEZWNsYXJhdGlvbihjZWxsTWluV2lkdGgsIGhhc1dpZHRoKVxuXG4gICAgICBjb2xzLnB1c2goWydjb2wnLCB7IHN0eWxlOiBgJHtwcm9wZXJ0eX06ICR7dmFsdWV9YCB9XSlcbiAgICB9XG4gIH1cblxuICBjb25zdCB0YWJsZVdpZHRoID0gZml4ZWRXaWR0aCA/IGAke3RvdGFsV2lkdGh9cHhgIDogJydcbiAgY29uc3QgdGFibGVNaW5XaWR0aCA9IGZpeGVkV2lkdGggPyAnJyA6IGAke3RvdGFsV2lkdGh9cHhgXG5cbiAgY29uc3QgY29sZ3JvdXA6IERPTU91dHB1dFNwZWMgPSBbJ2NvbGdyb3VwJywge30sIC4uLmNvbHNdXG5cbiAgcmV0dXJuIHsgY29sZ3JvdXAsIHRhYmxlV2lkdGgsIHRhYmxlTWluV2lkdGggfVxufVxuIiwgImltcG9ydCB0eXBlIHsgRnJhZ21lbnQsIE5vZGUgYXMgUHJvc2VtaXJyb3JOb2RlLCBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDZWxsKFxuICBjZWxsVHlwZTogTm9kZVR5cGUsXG4gIGNlbGxDb250ZW50PzogRnJhZ21lbnQgfCBQcm9zZW1pcnJvck5vZGUgfCBBcnJheTxQcm9zZW1pcnJvck5vZGU+LFxuKTogUHJvc2VtaXJyb3JOb2RlIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gIGlmIChjZWxsQ29udGVudCkge1xuICAgIHJldHVybiBjZWxsVHlwZS5jcmVhdGVDaGVja2VkKG51bGwsIGNlbGxDb250ZW50KVxuICB9XG5cbiAgcmV0dXJuIGNlbGxUeXBlLmNyZWF0ZUFuZEZpbGwoKVxufVxuIiwgImltcG9ydCB0eXBlIHsgTm9kZVR5cGUsIFNjaGVtYSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUYWJsZU5vZGVUeXBlcyhzY2hlbWE6IFNjaGVtYSk6IHsgW2tleTogc3RyaW5nXTogTm9kZVR5cGUgfSB7XG4gIGlmIChzY2hlbWEuY2FjaGVkLnRhYmxlTm9kZVR5cGVzKSB7XG4gICAgcmV0dXJuIHNjaGVtYS5jYWNoZWQudGFibGVOb2RlVHlwZXNcbiAgfVxuXG4gIGNvbnN0IHJvbGVzOiB7IFtrZXk6IHN0cmluZ106IE5vZGVUeXBlIH0gPSB7fVxuXG4gIE9iamVjdC5rZXlzKHNjaGVtYS5ub2RlcykuZm9yRWFjaCh0eXBlID0+IHtcbiAgICBjb25zdCBub2RlVHlwZSA9IHNjaGVtYS5ub2Rlc1t0eXBlXVxuXG4gICAgaWYgKG5vZGVUeXBlLnNwZWMudGFibGVSb2xlKSB7XG4gICAgICByb2xlc1tub2RlVHlwZS5zcGVjLnRhYmxlUm9sZV0gPSBub2RlVHlwZVxuICAgIH1cbiAgfSlcblxuICBzY2hlbWEuY2FjaGVkLnRhYmxlTm9kZVR5cGVzID0gcm9sZXNcblxuICByZXR1cm4gcm9sZXNcbn1cbiIsICJpbXBvcnQgdHlwZSB7IEZyYWdtZW50LCBOb2RlIGFzIFByb3NlbWlycm9yTm9kZSwgU2NoZW1hIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgY3JlYXRlQ2VsbCB9IGZyb20gJy4vY3JlYXRlQ2VsbC5qcydcbmltcG9ydCB7IGdldFRhYmxlTm9kZVR5cGVzIH0gZnJvbSAnLi9nZXRUYWJsZU5vZGVUeXBlcy5qcydcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVRhYmxlKFxuICBzY2hlbWE6IFNjaGVtYSxcbiAgcm93c0NvdW50OiBudW1iZXIsXG4gIGNvbHNDb3VudDogbnVtYmVyLFxuICB3aXRoSGVhZGVyUm93OiBib29sZWFuLFxuICBjZWxsQ29udGVudD86IEZyYWdtZW50IHwgUHJvc2VtaXJyb3JOb2RlIHwgQXJyYXk8UHJvc2VtaXJyb3JOb2RlPixcbik6IFByb3NlbWlycm9yTm9kZSB7XG4gIGNvbnN0IHR5cGVzID0gZ2V0VGFibGVOb2RlVHlwZXMoc2NoZW1hKVxuICBjb25zdCBoZWFkZXJDZWxsczogUHJvc2VtaXJyb3JOb2RlW10gPSBbXVxuICBjb25zdCBjZWxsczogUHJvc2VtaXJyb3JOb2RlW10gPSBbXVxuXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBjb2xzQ291bnQ7IGluZGV4ICs9IDEpIHtcbiAgICBjb25zdCBjZWxsID0gY3JlYXRlQ2VsbCh0eXBlcy5jZWxsLCBjZWxsQ29udGVudClcblxuICAgIGlmIChjZWxsKSB7XG4gICAgICBjZWxscy5wdXNoKGNlbGwpXG4gICAgfVxuXG4gICAgaWYgKHdpdGhIZWFkZXJSb3cpIHtcbiAgICAgIGNvbnN0IGhlYWRlckNlbGwgPSBjcmVhdGVDZWxsKHR5cGVzLmhlYWRlcl9jZWxsLCBjZWxsQ29udGVudClcblxuICAgICAgaWYgKGhlYWRlckNlbGwpIHtcbiAgICAgICAgaGVhZGVyQ2VsbHMucHVzaChoZWFkZXJDZWxsKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHJvd3M6IFByb3NlbWlycm9yTm9kZVtdID0gW11cblxuICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgcm93c0NvdW50OyBpbmRleCArPSAxKSB7XG4gICAgcm93cy5wdXNoKHR5cGVzLnJvdy5jcmVhdGVDaGVja2VkKG51bGwsIHdpdGhIZWFkZXJSb3cgJiYgaW5kZXggPT09IDAgPyBoZWFkZXJDZWxscyA6IGNlbGxzKSlcbiAgfVxuXG4gIHJldHVybiB0eXBlcy50YWJsZS5jcmVhdGVDaGVja2VkKG51bGwsIHJvd3MpXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBLZXlib2FyZFNob3J0Y3V0Q29tbWFuZCB9IGZyb20gJ0B0aXB0YXAvY29yZSdcbmltcG9ydCB7IGZpbmRQYXJlbnROb2RlQ2xvc2VzdFRvUG9zIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5pbXBvcnQgeyBpc0NlbGxTZWxlY3Rpb24gfSBmcm9tICcuL2lzQ2VsbFNlbGVjdGlvbi5qcydcblxuZXhwb3J0IGNvbnN0IGRlbGV0ZVRhYmxlV2hlbkFsbENlbGxzU2VsZWN0ZWQ6IEtleWJvYXJkU2hvcnRjdXRDb21tYW5kID0gKHsgZWRpdG9yIH0pID0+IHtcbiAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IGVkaXRvci5zdGF0ZVxuXG4gIGlmICghaXNDZWxsU2VsZWN0aW9uKHNlbGVjdGlvbikpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGxldCBjZWxsQ291bnQgPSAwXG4gIGNvbnN0IHRhYmxlID0gZmluZFBhcmVudE5vZGVDbG9zZXN0VG9Qb3Moc2VsZWN0aW9uLnJhbmdlc1swXS4kZnJvbSwgbm9kZSA9PiB7XG4gICAgcmV0dXJuIG5vZGUudHlwZS5uYW1lID09PSAndGFibGUnXG4gIH0pXG5cbiAgdGFibGU/Lm5vZGUuZGVzY2VuZGFudHMobm9kZSA9PiB7XG4gICAgaWYgKG5vZGUudHlwZS5uYW1lID09PSAndGFibGUnKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAoWyd0YWJsZUNlbGwnLCAndGFibGVIZWFkZXInXS5pbmNsdWRlcyhub2RlLnR5cGUubmFtZSkpIHtcbiAgICAgIGNlbGxDb3VudCArPSAxXG4gICAgfVxuICB9KVxuXG4gIGNvbnN0IGFsbENlbGxzU2VsZWN0ZWQgPSBjZWxsQ291bnQgPT09IHNlbGVjdGlvbi5yYW5nZXMubGVuZ3RoXG5cbiAgaWYgKCFhbGxDZWxsc1NlbGVjdGVkKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBlZGl0b3IuY29tbWFuZHMuZGVsZXRlVGFibGUoKVxuXG4gIHJldHVybiB0cnVlXG59XG4iLCAiaW1wb3J0IHsgQ2VsbFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vdGFibGVzJ1xuXG5leHBvcnQgZnVuY3Rpb24gaXNDZWxsU2VsZWN0aW9uKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgQ2VsbFNlbGVjdGlvbiB7XG4gIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIENlbGxTZWxlY3Rpb25cbn1cbiIsICJpbXBvcnQgdHlwZSB7IEpTT05Db250ZW50LCBNYXJrZG93blJlbmRlcmVySGVscGVycyB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuaW1wb3J0IHtcbiAgdHlwZSBUYWJsZUNlbGxBbGlnbiBhcyBUYWJsZUNlbGxBbGlnblR5cGUsXG4gIG5vcm1hbGl6ZVRhYmxlQ2VsbEFsaWduRnJvbUF0dHJpYnV0ZXMsXG4gIFRhYmxlQ2VsbEFsaWduLFxufSBmcm9tICcuLi8uLi91dGlsaXRpZXMvcGFyc2VBbGlnbi5qcydcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfQ0VMTF9MSU5FX1NFUEFSQVRPUiA9ICdcXHUwMDFGJ1xuXG5mdW5jdGlvbiBjb2xsYXBzZVdoaXRlc3BhY2Uoczogc3RyaW5nKSB7XG4gIHJldHVybiAocyB8fCAnJykucmVwbGFjZSgvXFxzKy9nLCAnICcpLnRyaW0oKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyVGFibGVUb01hcmtkb3duKFxuICBub2RlOiBKU09OQ29udGVudCxcbiAgaDogTWFya2Rvd25SZW5kZXJlckhlbHBlcnMsXG4gIG9wdGlvbnM6IHsgY2VsbExpbmVTZXBhcmF0b3I/OiBzdHJpbmcgfSA9IHt9LFxuKSB7XG4gIGNvbnN0IGNlbGxTZXAgPSBvcHRpb25zLmNlbGxMaW5lU2VwYXJhdG9yID8/IERFRkFVTFRfQ0VMTF9MSU5FX1NFUEFSQVRPUlxuXG4gIGlmICghbm9kZSB8fCAhbm9kZS5jb250ZW50IHx8IG5vZGUuY29udGVudC5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gJydcbiAgfVxuXG4gIC8vIEJ1aWxkIHJvd3M6IGVhY2ggY2VsbCBpcyB7IHRleHQsIGlzSGVhZGVyLCBhbGlnbiB9XG4gIGNvbnN0IHJvd3M6IHsgdGV4dDogc3RyaW5nOyBpc0hlYWRlcjogYm9vbGVhbjsgYWxpZ246IFRhYmxlQ2VsbEFsaWduVHlwZSB8IG51bGwgfVtdW10gPSBbXVxuXG4gIG5vZGUuY29udGVudC5mb3JFYWNoKHJvd05vZGUgPT4ge1xuICAgIGNvbnN0IGNlbGxzOiB7IHRleHQ6IHN0cmluZzsgaXNIZWFkZXI6IGJvb2xlYW47IGFsaWduOiBUYWJsZUNlbGxBbGlnblR5cGUgfCBudWxsIH1bXSA9IFtdXG5cbiAgICBpZiAocm93Tm9kZS5jb250ZW50KSB7XG4gICAgICByb3dOb2RlLmNvbnRlbnQuZm9yRWFjaChjZWxsTm9kZSA9PiB7XG4gICAgICAgIGxldCByYXcgPSAnJ1xuXG4gICAgICAgIGlmIChjZWxsTm9kZS5jb250ZW50ICYmIEFycmF5LmlzQXJyYXkoY2VsbE5vZGUuY29udGVudCkgJiYgY2VsbE5vZGUuY29udGVudC5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgLy8gUmVuZGVyIGVhY2ggZGlyZWN0IGNoaWxkIHNlcGFyYXRlbHkgYW5kIGpvaW4gd2l0aCBzZXBhcmF0b3Igc28gd2UgY2FuIHNwbGl0IGFnYWluIGxhdGVyXG4gICAgICAgICAgY29uc3QgcGFydHMgPSBjZWxsTm9kZS5jb250ZW50Lm1hcChjaGlsZCA9PlxuICAgICAgICAgICAgaC5yZW5kZXJDaGlsZHJlbihjaGlsZCBhcyB1bmtub3duIGFzIEpTT05Db250ZW50KSxcbiAgICAgICAgICApXG4gICAgICAgICAgcmF3ID0gcGFydHMuam9pbihjZWxsU2VwKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJhdyA9IGNlbGxOb2RlLmNvbnRlbnRcbiAgICAgICAgICAgID8gaC5yZW5kZXJDaGlsZHJlbihjZWxsTm9kZS5jb250ZW50IGFzIHVua25vd24gYXMgSlNPTkNvbnRlbnRbXSlcbiAgICAgICAgICAgIDogJydcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRleHQgPSBjb2xsYXBzZVdoaXRlc3BhY2UocmF3KVxuICAgICAgICBjb25zdCBpc0hlYWRlciA9IGNlbGxOb2RlLnR5cGUgPT09ICd0YWJsZUhlYWRlcidcbiAgICAgICAgY29uc3QgYWxpZ24gPSBub3JtYWxpemVUYWJsZUNlbGxBbGlnbkZyb21BdHRyaWJ1dGVzKGNlbGxOb2RlLmF0dHJzKVxuXG4gICAgICAgIGNlbGxzLnB1c2goeyB0ZXh0LCBpc0hlYWRlciwgYWxpZ24gfSlcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgcm93cy5wdXNoKGNlbGxzKVxuICB9KVxuXG4gIGNvbnN0IGNvbHVtbkNvdW50ID0gcm93cy5yZWR1Y2UoKG1heCwgcikgPT4gTWF0aC5tYXgobWF4LCByLmxlbmd0aCksIDApXG5cbiAgaWYgKGNvbHVtbkNvdW50ID09PSAwKSB7XG4gICAgcmV0dXJuICcnXG4gIH1cblxuICAvLyBDb21wdXRlIG1heCB3aWR0aCBmb3IgZWFjaCBjb2x1bW5cbiAgY29uc3QgY29sV2lkdGhzID0gQXJyYXkuZnJvbTxudW1iZXI+KHsgbGVuZ3RoOiBjb2x1bW5Db3VudCB9KS5maWxsKDApXG5cbiAgcm93cy5mb3JFYWNoKHIgPT4ge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29sdW1uQ291bnQ7IGkgKz0gMSkge1xuICAgICAgY29uc3QgY2VsbCA9IHJbaV0/LnRleHQgfHwgJydcbiAgICAgIGNvbnN0IGxlbiA9IGNlbGwubGVuZ3RoXG4gICAgICBpZiAobGVuID4gY29sV2lkdGhzW2ldKSB7XG4gICAgICAgIGNvbFdpZHRoc1tpXSA9IGxlblxuICAgICAgfVxuXG4gICAgICBpZiAoY29sV2lkdGhzW2ldIDwgMykge1xuICAgICAgICBjb2xXaWR0aHNbaV0gPSAzXG4gICAgICB9XG4gICAgfVxuICB9KVxuXG4gIGNvbnN0IHBhZCA9IChzOiBzdHJpbmcsIHdpZHRoOiBudW1iZXIpID0+IHMgKyAnICcucmVwZWF0KE1hdGgubWF4KDAsIHdpZHRoIC0gcy5sZW5ndGgpKVxuXG4gIGNvbnN0IGhlYWRlclJvdyA9IHJvd3NbMF1cbiAgY29uc3QgaGFzSGVhZGVyID0gaGVhZGVyUm93LnNvbWUoYyA9PiBjLmlzSGVhZGVyKVxuICBjb25zdCBjb2xBbGlnbm1lbnRzOiBBcnJheTxUYWJsZUNlbGxBbGlnblR5cGUgfCBudWxsPiA9IEFycmF5LmZyb208VGFibGVDZWxsQWxpZ25UeXBlIHwgbnVsbD4oe1xuICAgIGxlbmd0aDogY29sdW1uQ291bnQsXG4gIH0pLmZpbGwobnVsbClcblxuICByb3dzLmZvckVhY2gociA9PiB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2x1bW5Db3VudDsgaSArPSAxKSB7XG4gICAgICBpZiAoIWNvbEFsaWdubWVudHNbaV0gJiYgcltpXT8uYWxpZ24pIHtcbiAgICAgICAgY29sQWxpZ25tZW50c1tpXSA9IHJbaV0uYWxpZ25cbiAgICAgIH1cbiAgICB9XG4gIH0pXG5cbiAgbGV0IG91dCA9ICdcXG4nXG5cbiAgLy8gUmVuZGVyIGhlYWRlcjogaWYgdGhlIGRvY3VtZW50IGhhcyBhIGhlYWRlciByb3cgKHRhYmxlSGVhZGVyIGNlbGxzKSB1c2UgaXQsXG4gIC8vIG90aGVyd2lzZSBlbWl0IGFuIGVtcHR5IGhlYWRlciByb3cgc28gbW9zdCBNYXJrZG93biBwYXJzZXJzIHdpbGwgcmVjb2duaXplXG4gIC8vIHRoZSB0YWJsZSAodGhpcyBtYWtlcyByb3VuZHRyaXBwaW5nIHRvIE1hcmtkb3duIC0+IEpTT04gbW9yZSByZWxpYWJsZSkuXG4gIGNvbnN0IGhlYWRlclRleHRzID0gQXJyYXkuZnJvbTxudW1iZXI+KHsgbGVuZ3RoOiBjb2x1bW5Db3VudCB9KS5tYXAoKF8sIGkpID0+XG4gICAgaGFzSGVhZGVyID8gKGhlYWRlclJvd1tpXSAmJiBoZWFkZXJSb3dbaV0udGV4dCkgfHwgJycgOiAnJyxcbiAgKVxuXG4gIG91dCArPSBgfCAke2hlYWRlclRleHRzLm1hcCgodCwgaSkgPT4gcGFkKHQsIGNvbFdpZHRoc1tpXSkpLmpvaW4oJyB8ICcpfSB8XFxuYFxuXG4gIC8vIFNlcGFyYXRvciAodXNlIGF0IGxlYXN0IDMgZGFzaGVzIHBlciBjb2x1bW4gYW5kIGluY2x1ZGUgYWxpZ25tZW50IG1hcmtlcnMpXG4gIG91dCArPSBgfCAke2NvbFdpZHRoc1xuICAgIC5tYXAoKHcsIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBkYXNoQ291bnQgPSBNYXRoLm1heCgzLCB3KVxuICAgICAgY29uc3QgYWxpZ25tZW50ID0gY29sQWxpZ25tZW50c1tpbmRleF1cblxuICAgICAgaWYgKGFsaWdubWVudCA9PT0gVGFibGVDZWxsQWxpZ24uTGVmdCkge1xuICAgICAgICByZXR1cm4gYDokeyctJy5yZXBlYXQoZGFzaENvdW50KX1gXG4gICAgICB9XG5cbiAgICAgIGlmIChhbGlnbm1lbnQgPT09IFRhYmxlQ2VsbEFsaWduLlJpZ2h0KSB7XG4gICAgICAgIHJldHVybiBgJHsnLScucmVwZWF0KGRhc2hDb3VudCl9OmBcbiAgICAgIH1cblxuICAgICAgaWYgKGFsaWdubWVudCA9PT0gVGFibGVDZWxsQWxpZ24uQ2VudGVyKSB7XG4gICAgICAgIHJldHVybiBgOiR7Jy0nLnJlcGVhdChkYXNoQ291bnQpfTpgXG4gICAgICB9XG5cbiAgICAgIHJldHVybiAnLScucmVwZWF0KGRhc2hDb3VudClcbiAgICB9KVxuICAgIC5qb2luKCcgfCAnKX0gfFxcbmBcblxuICAvLyBCb2R5IHJvd3M6IGlmIHdlIGhhZCBhIGhlYWRlciwgc2tpcCB0aGUgZmlyc3Qgcm93OyBvdGhlcndpc2UgcmVuZGVyIGFsbCByb3dzXG4gIGNvbnN0IGJvZHkgPSBoYXNIZWFkZXIgPyByb3dzLnNsaWNlKDEpIDogcm93c1xuICBib2R5LmZvckVhY2gociA9PiB7XG4gICAgb3V0ICs9IGB8ICR7QXJyYXkuZnJvbTxudW1iZXI+KHsgbGVuZ3RoOiBjb2x1bW5Db3VudCB9KVxuICAgICAgLmZpbGwoMClcbiAgICAgIC5tYXAoKF8sIGkpID0+IHBhZCgocltpXSAmJiByW2ldLnRleHQpIHx8ICcnLCBjb2xXaWR0aHNbaV0pKVxuICAgICAgLmpvaW4oJyB8ICcpfSB8XFxuYFxuICB9KVxuXG4gIHJldHVybiBvdXRcbn1cblxuZXhwb3J0IGRlZmF1bHQgcmVuZGVyVGFibGVUb01hcmtkb3duXG4iLCAiaW1wb3J0IHsgVGFibGVSb3cgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi10YWJsZSdcblxuZXhwb3J0IHR5cGUgeyBUYWJsZVJvd09wdGlvbnMgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi10YWJsZSdcbmV4cG9ydCB7IFRhYmxlUm93IH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tdGFibGUnXG5cbmV4cG9ydCBkZWZhdWx0IFRhYmxlUm93XG4iLCAiaW1wb3J0IHsgVGFibGVIZWFkZXIgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi10YWJsZSdcblxuZXhwb3J0IHR5cGUgeyBUYWJsZUhlYWRlck9wdGlvbnMgfSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi10YWJsZSdcbmV4cG9ydCB7IFRhYmxlSGVhZGVyIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tdGFibGUnXG5cbmV4cG9ydCBkZWZhdWx0IFRhYmxlSGVhZGVyXG4iLCAiaW1wb3J0IHsgVGFibGVDZWxsIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tdGFibGUnXG5cbmV4cG9ydCB0eXBlIHsgVGFibGVDZWxsT3B0aW9ucyB9IGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLXRhYmxlJ1xuZXhwb3J0IHsgVGFibGVDZWxsIH0gZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tdGFibGUnXG5cbmV4cG9ydCBkZWZhdWx0IFRhYmxlQ2VsbFxuIiwgImltcG9ydCB0eXBlIHsgTWFya2VkT3B0aW9ucyB9IGZyb20gJy4vTWFya2VkT3B0aW9ucy50cyc7XG5cbi8qKlxuICogR2V0cyB0aGUgb3JpZ2luYWwgbWFya2VkIGRlZmF1bHQgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF9nZXREZWZhdWx0czxQYXJzZXJPdXRwdXQgPSBzdHJpbmcsIFJlbmRlcmVyT3V0cHV0ID0gc3RyaW5nPigpOiBNYXJrZWRPcHRpb25zPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+IHtcbiAgcmV0dXJuIHtcbiAgICBhc3luYzogZmFsc2UsXG4gICAgYnJlYWtzOiBmYWxzZSxcbiAgICBleHRlbnNpb25zOiBudWxsLFxuICAgIGdmbTogdHJ1ZSxcbiAgICBob29rczogbnVsbCxcbiAgICBwZWRhbnRpYzogZmFsc2UsXG4gICAgcmVuZGVyZXI6IG51bGwsXG4gICAgc2lsZW50OiBmYWxzZSxcbiAgICB0b2tlbml6ZXI6IG51bGwsXG4gICAgd2Fsa1Rva2VuczogbnVsbCxcbiAgfTtcbn1cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5leHBvcnQgbGV0IF9kZWZhdWx0czogTWFya2VkT3B0aW9uczxhbnksIGFueT4gPSBfZ2V0RGVmYXVsdHMoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNoYW5nZURlZmF1bHRzPFBhcnNlck91dHB1dCA9IHN0cmluZywgUmVuZGVyZXJPdXRwdXQgPSBzdHJpbmc+KG5ld0RlZmF1bHRzOiBNYXJrZWRPcHRpb25zPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+KSB7XG4gIF9kZWZhdWx0cyA9IG5ld0RlZmF1bHRzO1xufVxuIiwgImNvbnN0IG5vb3BUZXN0ID0geyBleGVjOiAoKSA9PiBudWxsIH0gYXMgdW5rbm93biBhcyBSZWdFeHA7XG5cbmZ1bmN0aW9uIGNhY2hlZEluZGVudFJlZ2V4KGNyZWF0ZVJlZ2V4OiAoaW5kZW50OiBudW1iZXIpID0+IFJlZ0V4cCkge1xuICBjb25zdCBjYWNoZTogUmVnRXhwW10gPSBbXTtcbiAgcmV0dXJuIChpbmRlbnQ6IG51bWJlcikgPT4ge1xuICAgIGNvbnN0IGNhY2hlSW5kZXggPSBNYXRoLm1heCgwLCBNYXRoLm1pbigzLCBpbmRlbnQgLSAxKSk7XG4gICAgbGV0IHJlZ2V4ID0gY2FjaGVbY2FjaGVJbmRleF07XG4gICAgaWYgKCFyZWdleCkge1xuICAgICAgcmVnZXggPSBjcmVhdGVSZWdleChjYWNoZUluZGV4KTtcbiAgICAgIGNhY2hlW2NhY2hlSW5kZXhdID0gcmVnZXg7XG4gICAgfVxuICAgIHJldHVybiByZWdleDtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZWRpdChyZWdleDogc3RyaW5nIHwgUmVnRXhwLCBvcHQgPSAnJykge1xuICBsZXQgc291cmNlID0gdHlwZW9mIHJlZ2V4ID09PSAnc3RyaW5nJyA/IHJlZ2V4IDogcmVnZXguc291cmNlO1xuICBjb25zdCBvYmogPSB7XG4gICAgcmVwbGFjZTogKG5hbWU6IHN0cmluZyB8IFJlZ0V4cCwgdmFsOiBzdHJpbmcgfCBSZWdFeHApID0+IHtcbiAgICAgIGxldCB2YWxTb3VyY2UgPSB0eXBlb2YgdmFsID09PSAnc3RyaW5nJyA/IHZhbCA6IHZhbC5zb3VyY2U7XG4gICAgICB2YWxTb3VyY2UgPSB2YWxTb3VyY2UucmVwbGFjZShvdGhlci5jYXJldCwgJyQxJyk7XG4gICAgICBzb3VyY2UgPSBzb3VyY2UucmVwbGFjZShuYW1lLCB2YWxTb3VyY2UpO1xuICAgICAgcmV0dXJuIG9iajtcbiAgICB9LFxuICAgIGdldFJlZ2V4OiAoKSA9PiB7XG4gICAgICByZXR1cm4gbmV3IFJlZ0V4cChzb3VyY2UsIG9wdCk7XG4gICAgfSxcbiAgfTtcbiAgcmV0dXJuIG9iajtcbn1cblxuLy8gdXNlIGEgZGVmYXVsdCB2YXJpYWJsZSB0byBlbnN1cmUgdGhlIHJlZ2V4IGlzIGV2YWx1YXRlZCBvbiBjbGllbnQgYW4gbm90IHJlbW92ZWQgYnkgbWluaWZpZXJzXG5jb25zdCBzdXBwb3J0c0xvb2tiZWhpbmQgPSAoKGEgPSAnJykgPT4ge1xudHJ5IHtcbiAgcmV0dXJuICEhbmV3IFJlZ0V4cCgnKD88PTEpKD88ITEpJyArIGEpO1xufSBjYXRjaCB7XG4gIC8vIFNlZSBicm93c2VyIHN1cHBvcnQgaGVyZTpcbiAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvUmVndWxhcl9leHByZXNzaW9ucy9Mb29rYmVoaW5kX2Fzc2VydGlvblxuICByZXR1cm4gZmFsc2U7XG59XG59KSgpO1xuXG5leHBvcnQgY29uc3Qgb3RoZXIgPSB7XG4gIGNvZGVSZW1vdmVJbmRlbnQ6IC9eKD86IHsxLDR9fCB7MCwzfVxcdCkvZ20sXG4gIG91dHB1dExpbmtSZXBsYWNlOiAvXFxcXChbXFxbXFxdXSkvZyxcbiAgaW5kZW50Q29kZUNvbXBlbnNhdGlvbjogL14oXFxzKykoPzpgYGApLyxcbiAgYmVnaW5uaW5nU3BhY2U6IC9eXFxzKy8sXG4gIGVuZGluZ0hhc2g6IC8jJC8sXG4gIHN0YXJ0aW5nU3BhY2VDaGFyOiAvXiAvLFxuICBlbmRpbmdTcGFjZUNoYXI6IC8gJC8sXG4gIG5vblNwYWNlQ2hhcjogL1teIF0vLFxuICBuZXdMaW5lQ2hhckdsb2JhbDogL1xcbi9nLFxuICB0YWJDaGFyR2xvYmFsOiAvXFx0L2csXG4gIG11bHRpcGxlU3BhY2VHbG9iYWw6IC9cXHMrL2csXG4gIGJsYW5rTGluZTogL15bIFxcdF0qJC8sXG4gIGRvdWJsZUJsYW5rTGluZTogL1xcblsgXFx0XSpcXG5bIFxcdF0qJC8sXG4gIGJsb2NrcXVvdGVTdGFydDogL14gezAsM30+LyxcbiAgYmxvY2txdW90ZVNldGV4dFJlcGxhY2U6IC9cXG4gezAsM30oKD86PSt8LSspICopKD89XFxufCQpL2csXG4gIGJsb2NrcXVvdGVTZXRleHRSZXBsYWNlMjogL14gezAsM30+WyBcXHRdPy9nbSxcbiAgbGlzdFJlcGxhY2VOZXN0aW5nOiAvXiB7MSw0fSg/PSggezR9KSpbXiBdKS9nLFxuICBsaXN0SXNUYXNrOiAvXlxcW1sgeFhdXFxdICtcXFMvLFxuICBsaXN0UmVwbGFjZVRhc2s6IC9eXFxbWyB4WF1cXF0gKy8sXG4gIGxpc3RUYXNrQ2hlY2tib3g6IC9cXFtbIHhYXVxcXS8sXG4gIGFueUxpbmU6IC9cXG4uKlxcbi8sXG4gIGhyZWZCcmFja2V0czogL148KC4qKT4kLyxcbiAgdGFibGVEZWxpbWl0ZXI6IC9bOnxdLyxcbiAgdGFibGVBbGlnbkNoYXJzOiAvXlxcfHxcXHwgKiQvZyxcbiAgdGFibGVSb3dCbGFua0xpbmU6IC9cXG5bIFxcdF0qJC8sXG4gIHRhYmxlQWxpZ25SaWdodDogL14gKi0rOiAqJC8sXG4gIHRhYmxlQWxpZ25DZW50ZXI6IC9eICo6LSs6ICokLyxcbiAgdGFibGVBbGlnbkxlZnQ6IC9eICo6LSsgKiQvLFxuICBzdGFydEFUYWc6IC9ePGEgL2ksXG4gIGVuZEFUYWc6IC9ePFxcL2E+L2ksXG4gIHN0YXJ0UHJlU2NyaXB0VGFnOiAvXjwocHJlfGNvZGV8a2JkfHNjcmlwdCkoXFxzfD4pL2ksXG4gIGVuZFByZVNjcmlwdFRhZzogL148XFwvKHByZXxjb2RlfGtiZHxzY3JpcHQpKFxcc3w+KS9pLFxuICBzdGFydEFuZ2xlQnJhY2tldDogL148LyxcbiAgZW5kQW5nbGVCcmFja2V0OiAvPiQvLFxuICBwZWRhbnRpY0hyZWZUaXRsZTogL14oW14nXCJdKlteXFxzXSlcXHMrKFsnXCJdKSguKilcXDIvLFxuICB1bmljb2RlQWxwaGFOdW1lcmljOiAvW1xccHtMfVxccHtOfV0vdSxcbiAgZXNjYXBlVGVzdDogL1smPD5cIiddLyxcbiAgZXNjYXBlUmVwbGFjZTogL1smPD5cIiddL2csXG4gIGVzY2FwZVRlc3ROb0VuY29kZTogL1s8PlwiJ118Jig/ISgjXFxkezEsN318I1tYeF1bYS1mQS1GMC05XXsxLDZ9fFxcdyspOykvLFxuICBlc2NhcGVSZXBsYWNlTm9FbmNvZGU6IC9bPD5cIiddfCYoPyEoI1xcZHsxLDd9fCNbWHhdW2EtZkEtRjAtOV17MSw2fXxcXHcrKTspL2csXG4gIGNhcmV0OiAvKF58W15cXFtdKVxcXi9nLFxuICBwZXJjZW50RGVjb2RlOiAvJTI1L2csXG4gIGZpbmRQaXBlOiAvXFx8L2csXG4gIHNwbGl0UGlwZTogLyBcXHwvLFxuICBzbGFzaFBpcGU6IC9cXFxcXFx8L2csXG4gIGNhcnJpYWdlUmV0dXJuOiAvXFxyXFxufFxcci9nLFxuICBzcGFjZUxpbmU6IC9eICskL2dtLFxuICBub3RTcGFjZVN0YXJ0OiAvXlxcUyovLFxuICBlbmRpbmdOZXdsaW5lOiAvXFxuJC8sXG4gIGxpc3RJdGVtUmVnZXg6IChidWxsOiBzdHJpbmcpID0+IG5ldyBSZWdFeHAoYF4oIHswLDN9JHtidWxsfSkoKD86W1xcdCBdW15cXFxcbl0qKT8oPzpcXFxcbnwkKSlgKSxcbiAgbmV4dEJ1bGxldFJlZ2V4OiBjYWNoZWRJbmRlbnRSZWdleCgoaW5kZW50OiBudW1iZXIpID0+IG5ldyBSZWdFeHAoYF4gezAsJHtpbmRlbnR9fSg/OlsqKy1dfFxcXFxkezEsOX1bLildKSgoPzpbIFxcdF1bXlxcXFxuXSopPyg/OlxcXFxufCQpKWApKSxcbiAgaHJSZWdleDogY2FjaGVkSW5kZW50UmVnZXgoKGluZGVudDogbnVtYmVyKSA9PiBuZXcgUmVnRXhwKGBeIHswLCR7aW5kZW50fX0oKD86LSAqKXszLH18KD86XyAqKXszLH18KD86XFxcXCogKil7Myx9KSg/OlxcXFxuK3wkKWApKSxcbiAgZmVuY2VzQmVnaW5SZWdleDogY2FjaGVkSW5kZW50UmVnZXgoKGluZGVudDogbnVtYmVyKSA9PiBuZXcgUmVnRXhwKGBeIHswLCR7aW5kZW50fX0oPzpcXGBcXGBcXGB8fn5+KWApKSxcbiAgaGVhZGluZ0JlZ2luUmVnZXg6IGNhY2hlZEluZGVudFJlZ2V4KChpbmRlbnQ6IG51bWJlcikgPT4gbmV3IFJlZ0V4cChgXiB7MCwke2luZGVudH19I2ApKSxcbiAgaHRtbEJlZ2luUmVnZXg6IGNhY2hlZEluZGVudFJlZ2V4KChpbmRlbnQ6IG51bWJlcikgPT4gbmV3IFJlZ0V4cChgXiB7MCwke2luZGVudH19PCg/OlthLXpdLio+fCEtLSlgLCAnaScpKSxcbiAgYmxvY2txdW90ZUJlZ2luUmVnZXg6IGNhY2hlZEluZGVudFJlZ2V4KChpbmRlbnQ6IG51bWJlcikgPT4gbmV3IFJlZ0V4cChgXiB7MCwke2luZGVudH19PmApKSxcbn07XG5cbi8qKlxuICogQmxvY2stTGV2ZWwgR3JhbW1hclxuICovXG5cbmNvbnN0IG5ld2xpbmUgPSAvXig/OlsgXFx0XSooPzpcXG58JCkpKy87XG5jb25zdCBibG9ja0NvZGUgPSAvXigoPzogezR9fCB7MCwzfVxcdClbXlxcbl0rKD86XFxuKD86WyBcXHRdKig/OlxcbnwkKSkqKT8pKy87XG5jb25zdCBmZW5jZXMgPSAvXiB7MCwzfShgezMsfSg/PVteYFxcbl0qKD86XFxufCQpKXx+ezMsfSkoW15cXG5dKikoPzpcXG58JCkoPzp8KFtcXHNcXFNdKj8pKD86XFxufCQpKSg/OiB7MCwzfVxcMVt+YF0qICooPz1cXG58JCl8JCkvO1xuY29uc3QgaHIgPSAvXiB7MCwzfSgoPzotW1xcdCBdKil7Myx9fCg/Ol9bIFxcdF0qKXszLH18KD86XFwqWyBcXHRdKil7Myx9KSg/Olxcbit8JCkvO1xuY29uc3QgaGVhZGluZyA9IC9eIHswLDN9KCN7MSw2fSkoPz1cXHN8JCkoLiopKD86XFxuK3wkKS87XG5jb25zdCBidWxsZXQgPSAvIHswLDN9KD86WyorLV18XFxkezEsOX1bLildKS87XG5jb25zdCBsaGVhZGluZ0NvcmUgPSAvXig/IWJ1bGwgfGJsb2NrQ29kZXxmZW5jZXN8YmxvY2txdW90ZXxoZWFkaW5nfGh0bWx8dGFibGUpKCg/Oi58XFxuKD8hXFxzKj9cXG58YnVsbCB8YmxvY2tDb2RlfGZlbmNlc3xibG9ja3F1b3RlfGhlYWRpbmd8aHRtbHx0YWJsZSkpKz8pXFxuIHswLDN9KD0rfC0rKSAqKD86XFxuK3wkKS87XG5jb25zdCBsaGVhZGluZyA9IGVkaXQobGhlYWRpbmdDb3JlKVxuICAucmVwbGFjZSgvYnVsbC9nLCBidWxsZXQpIC8vIGxpc3RzIGNhbiBpbnRlcnJ1cHRcbiAgLnJlcGxhY2UoL2Jsb2NrQ29kZS9nLCAvKD86IHs0fXwgezAsM31cXHQpLykgLy8gaW5kZW50ZWQgY29kZSBibG9ja3MgY2FuIGludGVycnVwdFxuICAucmVwbGFjZSgvZmVuY2VzL2csIC8gezAsM30oPzpgezMsfXx+ezMsfSkvKSAvLyBmZW5jZWQgY29kZSBibG9ja3MgY2FuIGludGVycnVwdFxuICAucmVwbGFjZSgvYmxvY2txdW90ZS9nLCAvIHswLDN9Pi8pIC8vIGJsb2NrcXVvdGUgY2FuIGludGVycnVwdFxuICAucmVwbGFjZSgvaGVhZGluZy9nLCAvIHswLDN9I3sxLDZ9LykgLy8gQVRYIGhlYWRpbmcgY2FuIGludGVycnVwdFxuICAucmVwbGFjZSgvaHRtbC9nLCAvIHswLDN9PFteXFxuPl0rPlxcbi8pIC8vIGJsb2NrIGh0bWwgY2FuIGludGVycnVwdFxuICAucmVwbGFjZSgvXFx8dGFibGUvZywgJycpIC8vIHRhYmxlIG5vdCBpbiBjb21tb25tYXJrXG4gIC5nZXRSZWdleCgpO1xuY29uc3QgbGhlYWRpbmdHZm0gPSBlZGl0KGxoZWFkaW5nQ29yZSlcbiAgLnJlcGxhY2UoL2J1bGwvZywgYnVsbGV0KSAvLyBsaXN0cyBjYW4gaW50ZXJydXB0XG4gIC5yZXBsYWNlKC9ibG9ja0NvZGUvZywgLyg/OiB7NH18IHswLDN9XFx0KS8pIC8vIGluZGVudGVkIGNvZGUgYmxvY2tzIGNhbiBpbnRlcnJ1cHRcbiAgLnJlcGxhY2UoL2ZlbmNlcy9nLCAvIHswLDN9KD86YHszLH18fnszLH0pLykgLy8gZmVuY2VkIGNvZGUgYmxvY2tzIGNhbiBpbnRlcnJ1cHRcbiAgLnJlcGxhY2UoL2Jsb2NrcXVvdGUvZywgLyB7MCwzfT4vKSAvLyBibG9ja3F1b3RlIGNhbiBpbnRlcnJ1cHRcbiAgLnJlcGxhY2UoL2hlYWRpbmcvZywgLyB7MCwzfSN7MSw2fS8pIC8vIEFUWCBoZWFkaW5nIGNhbiBpbnRlcnJ1cHRcbiAgLnJlcGxhY2UoL2h0bWwvZywgLyB7MCwzfTxbXlxcbj5dKz5cXG4vKSAvLyBibG9jayBodG1sIGNhbiBpbnRlcnJ1cHRcbiAgLnJlcGxhY2UoL3RhYmxlL2csIC8gezAsM31cXHw/KD86WzpcXC0gXSpcXHwpK1tcXDpcXC0gXSpcXG4vKSAvLyB0YWJsZSBjYW4gaW50ZXJydXB0XG4gIC5nZXRSZWdleCgpO1xuY29uc3QgX3BhcmFncmFwaCA9IC9eKFteXFxuXSsoPzpcXG4oPyFocnxoZWFkaW5nfGxoZWFkaW5nfGJsb2NrcXVvdGV8ZmVuY2VzfGxpc3R8aHRtbHx0YWJsZXwgK1xcbilbXlxcbl0rKSopLztcbmNvbnN0IGJsb2NrVGV4dCA9IC9eW15cXG5dKy87XG5jb25zdCBfYmxvY2tMYWJlbCA9IC8oPyFcXHMqXFxdKSg/OlxcXFxbXFxzXFxTXXxbXlxcW1xcXVxcXFxdKSsvO1xuY29uc3QgZGVmID0gZWRpdCgvXiB7MCwzfVxcWyhsYWJlbClcXF06ICooPzpcXG5bIFxcdF0qKT8oW148XFxzXVteXFxzXSp8PC4qPz4pKD86KD86ICsoPzpcXG5bIFxcdF0qKT98ICpcXG5bIFxcdF0qKSh0aXRsZSkpPyAqKD86XFxuK3wkKS8pXG4gIC5yZXBsYWNlKCdsYWJlbCcsIF9ibG9ja0xhYmVsKVxuICAucmVwbGFjZSgndGl0bGUnLCAvKD86XCIoPzpcXFxcXCI/fFteXCJcXFxcXSkqXCJ8J1teJ1xcbl0qKD86XFxuW14nXFxuXSspKlxcbj8nfFxcKFteKCldKlxcKSkvKVxuICAuZ2V0UmVnZXgoKTtcblxuY29uc3QgbGlzdCA9IGVkaXQoL14oYnVsbCkoWyBcXHRdW15cXG5dKj8pPyg/OlxcbnwkKS8pXG4gIC5yZXBsYWNlKC9idWxsL2csIGJ1bGxldClcbiAgLmdldFJlZ2V4KCk7XG5cbmNvbnN0IF90YWcgPSAnYWRkcmVzc3xhcnRpY2xlfGFzaWRlfGJhc2V8YmFzZWZvbnR8YmxvY2txdW90ZXxib2R5fGNhcHRpb24nXG4gICsgJ3xjZW50ZXJ8Y29sfGNvbGdyb3VwfGRkfGRldGFpbHN8ZGlhbG9nfGRpcnxkaXZ8ZGx8ZHR8ZmllbGRzZXR8ZmlnY2FwdGlvbidcbiAgKyAnfGZpZ3VyZXxmb290ZXJ8Zm9ybXxmcmFtZXxmcmFtZXNldHxoWzEtNl18aGVhZHxoZWFkZXJ8aHJ8aHRtbHxpZnJhbWUnXG4gICsgJ3xsZWdlbmR8bGl8bGlua3xtYWlufG1lbnV8bWVudWl0ZW18bWV0YXxuYXZ8bm9mcmFtZXN8b2x8b3B0Z3JvdXB8b3B0aW9uJ1xuICArICd8cHxwYXJhbXxzZWFyY2h8c2VjdGlvbnxzdW1tYXJ5fHRhYmxlfHRib2R5fHRkfHRmb290fHRofHRoZWFkfHRpdGxlJ1xuICArICd8dHJ8dHJhY2t8dWwnO1xuY29uc3QgX2NvbW1lbnQgPSAvPCEtLSg/Oi0/PnxbXFxzXFxTXSo/KD86LS0+fCQpKS87XG5jb25zdCBodG1sID0gZWRpdChcbiAgJ14gezAsM30oPzonIC8vIG9wdGlvbmFsIGluZGVudGF0aW9uXG4rICc8KHNjcmlwdHxwcmV8c3R5bGV8dGV4dGFyZWEpW1xcXFxzPl1bXFxcXHNcXFxcU10qPyg/OjwvXFxcXDE+W15cXFxcbl0qXFxcXG4rfCQpJyAvLyAoMSlcbisgJ3xjb21tZW50W15cXFxcbl0qKFxcXFxuK3wkKScgLy8gKDIpXG4rICd8PFxcXFw/W1xcXFxzXFxcXFNdKj8oPzpcXFxcPz5cXFxcbip8JCknIC8vICgzKVxuKyAnfDwhW0EtWl1bXFxcXHNcXFxcU10qPyg/Oj5cXFxcbip8JCknIC8vICg0KVxuKyAnfDwhXFxcXFtDREFUQVxcXFxbW1xcXFxzXFxcXFNdKj8oPzpcXFxcXVxcXFxdPlxcXFxuKnwkKScgLy8gKDUpXG4rICd8PC8/KHRhZykoPzogK3xcXFxcbnwvPz4pW1xcXFxzXFxcXFNdKj8oPzooPzpcXFxcblsgXFx0XSopK1xcXFxufCQpJyAvLyAoNilcbisgJ3w8KD8hc2NyaXB0fHByZXxzdHlsZXx0ZXh0YXJlYSkoW2Etel1bXFxcXHctXSopKD86YXR0cmlidXRlKSo/ICovPz4oPz1bIFxcXFx0XSooPzpcXFxcbnwkKSlbXFxcXHNcXFxcU10qPyg/Oig/OlxcXFxuWyBcXHRdKikrXFxcXG58JCknIC8vICg3KSBvcGVuIHRhZ1xuKyAnfDwvKD8hc2NyaXB0fHByZXxzdHlsZXx0ZXh0YXJlYSlbYS16XVtcXFxcdy1dKlxcXFxzKj4oPz1bIFxcXFx0XSooPzpcXFxcbnwkKSlbXFxcXHNcXFxcU10qPyg/Oig/OlxcXFxuWyBcXHRdKikrXFxcXG58JCknIC8vICg3KSBjbG9zaW5nIHRhZ1xuKyAnKScsICdpJylcbiAgLnJlcGxhY2UoJ2NvbW1lbnQnLCBfY29tbWVudClcbiAgLnJlcGxhY2UoJ3RhZycsIF90YWcpXG4gIC5yZXBsYWNlKCdhdHRyaWJ1dGUnLCAvICtbYS16QS1aOl9dW1xcdy46LV0qKD86ICo9ICpcIlteXCJcXG5dKlwifCAqPSAqJ1teJ1xcbl0qJ3wgKj0gKlteXFxzXCInPTw+YF0rKT8vKVxuICAuZ2V0UmVnZXgoKTtcblxuY29uc3QgcGFyYWdyYXBoID0gZWRpdChfcGFyYWdyYXBoKVxuICAucmVwbGFjZSgnaHInLCBocilcbiAgLnJlcGxhY2UoJ2hlYWRpbmcnLCAnIHswLDN9I3sxLDZ9KD86XFxcXHN8JCknKVxuICAucmVwbGFjZSgnfGxoZWFkaW5nJywgJycpIC8vIHNldGV4dCBoZWFkaW5ncyBkb24ndCBpbnRlcnJ1cHQgY29tbW9ubWFyayBwYXJhZ3JhcGhzXG4gIC5yZXBsYWNlKCd8dGFibGUnLCAnJylcbiAgLnJlcGxhY2UoJ2Jsb2NrcXVvdGUnLCAnIHswLDN9PicpXG4gIC5yZXBsYWNlKCdmZW5jZXMnLCAnIHswLDN9KD86YHszLH0oPz1bXmBcXFxcbl0qXFxcXG4pfH57Myx9KVteXFxcXG5dKlxcXFxuJylcbiAgLnJlcGxhY2UoJ2xpc3QnLCAnIHswLDN9KD86WyorLV18MVsuKV0pWyBcXFxcdF0rW14gXFxcXHRcXFxcbl0nKSAvLyBvbmx5IG5vbi1lbXB0eSBsaXN0cyBzdGFydGluZyBmcm9tIDEgY2FuIGludGVycnVwdFxuICAucmVwbGFjZSgnaHRtbCcsICc8Lz8oPzp0YWcpKD86ICt8XFxcXG58Lz8+KXw8KD86c2NyaXB0fHByZXxzdHlsZXx0ZXh0YXJlYXwhLS0pJylcbiAgLnJlcGxhY2UoJ3RhZycsIF90YWcpIC8vIHBhcnMgY2FuIGJlIGludGVycnVwdGVkIGJ5IHR5cGUgKDYpIGh0bWwgYmxvY2tzXG4gIC5nZXRSZWdleCgpO1xuXG5jb25zdCBibG9ja3F1b3RlID0gZWRpdCgvXiggezAsM30+ID8ocGFyYWdyYXBofFteXFxuXSopKD86XFxufCQpKSsvKVxuICAucmVwbGFjZSgncGFyYWdyYXBoJywgcGFyYWdyYXBoKVxuICAuZ2V0UmVnZXgoKTtcblxuLyoqXG4gKiBOb3JtYWwgQmxvY2sgR3JhbW1hclxuICovXG5cbmNvbnN0IGJsb2NrTm9ybWFsID0ge1xuICBibG9ja3F1b3RlLFxuICBjb2RlOiBibG9ja0NvZGUsXG4gIGRlZixcbiAgZmVuY2VzLFxuICBoZWFkaW5nLFxuICBocixcbiAgaHRtbCxcbiAgbGhlYWRpbmcsXG4gIGxpc3QsXG4gIG5ld2xpbmUsXG4gIHBhcmFncmFwaCxcbiAgdGFibGU6IG5vb3BUZXN0LFxuICB0ZXh0OiBibG9ja1RleHQsXG59O1xuXG50eXBlIEJsb2NrS2V5cyA9IGtleW9mIHR5cGVvZiBibG9ja05vcm1hbDtcblxuLyoqXG4gKiBHRk0gQmxvY2sgR3JhbW1hclxuICovXG5cbmNvbnN0IGdmbVRhYmxlID0gZWRpdChcbiAgJ14gKihbXlxcXFxuIF0uKilcXFxcbicgLy8gSGVhZGVyXG4rICcgezAsM30oKD86XFxcXHwgKik/Oj8tKzo/ICooPzpcXFxcfCAqOj8tKzo/ICopKig/OlxcXFx8ICopPyknIC8vIEFsaWduXG4rICcoPzpcXFxcbigoPzooPyEgKlxcXFxufGhyfGhlYWRpbmd8YmxvY2txdW90ZXxjb2RlfGZlbmNlc3xsaXN0fGh0bWwpLiooPzpcXFxcbnwkKSkqKVxcXFxuKnwkKScpIC8vIENlbGxzXG4gIC5yZXBsYWNlKCdocicsIGhyKVxuICAucmVwbGFjZSgnaGVhZGluZycsICcgezAsM30jezEsNn0oPzpcXFxcc3wkKScpXG4gIC5yZXBsYWNlKCdibG9ja3F1b3RlJywgJyB7MCwzfT4nKVxuICAucmVwbGFjZSgnY29kZScsICcoPzogezR9fCB7MCwzfVxcdClbXlxcXFxuXScpXG4gIC5yZXBsYWNlKCdmZW5jZXMnLCAnIHswLDN9KD86YHszLH0oPz1bXmBcXFxcbl0qXFxcXG4pfH57Myx9KVteXFxcXG5dKlxcXFxuJylcbiAgLnJlcGxhY2UoJ2xpc3QnLCAnIHswLDN9KD86WyorLV18MVsuKV0pWyBcXFxcdF0nKSAvLyBhbnkgYnVsbGV0IGVuZHMgdGhlIHRhYmxlIHJvd3NcbiAgLnJlcGxhY2UoJ2h0bWwnLCAnPC8/KD86dGFnKSg/OiArfFxcXFxufC8/Pil8PCg/OnNjcmlwdHxwcmV8c3R5bGV8dGV4dGFyZWF8IS0tKScpXG4gIC5yZXBsYWNlKCd0YWcnLCBfdGFnKSAvLyB0YWJsZXMgY2FuIGJlIGludGVycnVwdGVkIGJ5IHR5cGUgKDYpIGh0bWwgYmxvY2tzXG4gIC5nZXRSZWdleCgpO1xuXG5jb25zdCBibG9ja0dmbTogUmVjb3JkPEJsb2NrS2V5cywgUmVnRXhwPiA9IHtcbiAgLi4uYmxvY2tOb3JtYWwsXG4gIGxoZWFkaW5nOiBsaGVhZGluZ0dmbSxcbiAgdGFibGU6IGdmbVRhYmxlLFxuICBwYXJhZ3JhcGg6IGVkaXQoX3BhcmFncmFwaClcbiAgICAucmVwbGFjZSgnaHInLCBocilcbiAgICAucmVwbGFjZSgnaGVhZGluZycsICcgezAsM30jezEsNn0oPzpcXFxcc3wkKScpXG4gICAgLnJlcGxhY2UoJ3xsaGVhZGluZycsICcnKSAvLyBzZXRleHQgaGVhZGluZ3MgZG9uJ3QgaW50ZXJydXB0IGNvbW1vbm1hcmsgcGFyYWdyYXBoc1xuICAgIC5yZXBsYWNlKCd0YWJsZScsIGdmbVRhYmxlKSAvLyBpbnRlcnJ1cHQgcGFyYWdyYXBocyB3aXRoIHRhYmxlXG4gICAgLnJlcGxhY2UoJ2Jsb2NrcXVvdGUnLCAnIHswLDN9PicpXG4gICAgLnJlcGxhY2UoJ2ZlbmNlcycsICcgezAsM30oPzpgezMsfSg/PVteYFxcXFxuXSpcXFxcbil8fnszLH0pW15cXFxcbl0qXFxcXG4nKVxuICAgIC5yZXBsYWNlKCdsaXN0JywgJyB7MCwzfSg/OlsqKy1dfDFbLildKVsgXFxcXHRdK1teIFxcXFx0XFxcXG5dJykgLy8gb25seSBub24tZW1wdHkgbGlzdHMgc3RhcnRpbmcgZnJvbSAxIGNhbiBpbnRlcnJ1cHRcbiAgICAucmVwbGFjZSgnaHRtbCcsICc8Lz8oPzp0YWcpKD86ICt8XFxcXG58Lz8+KXw8KD86c2NyaXB0fHByZXxzdHlsZXx0ZXh0YXJlYXwhLS0pJylcbiAgICAucmVwbGFjZSgndGFnJywgX3RhZykgLy8gcGFycyBjYW4gYmUgaW50ZXJydXB0ZWQgYnkgdHlwZSAoNikgaHRtbCBibG9ja3NcbiAgICAuZ2V0UmVnZXgoKSxcbn07XG5cbi8qKlxuICogUGVkYW50aWMgZ3JhbW1hciAob3JpZ2luYWwgSm9obiBHcnViZXIncyBsb29zZSBtYXJrZG93biBzcGVjaWZpY2F0aW9uKVxuICovXG5cbmNvbnN0IGJsb2NrUGVkYW50aWM6IFJlY29yZDxCbG9ja0tleXMsIFJlZ0V4cD4gPSB7XG4gIC4uLmJsb2NrTm9ybWFsLFxuICBodG1sOiBlZGl0KFxuICAgICdeICooPzpjb21tZW50ICooPzpcXFxcbnxcXFxccyokKSdcbiAgICArICd8PCh0YWcpW1xcXFxzXFxcXFNdKz88L1xcXFwxPiAqKD86XFxcXG57Mix9fFxcXFxzKiQpJyAvLyBjbG9zZWQgdGFnXG4gICAgKyAnfDx0YWcoPzpcIlteXCJdKlwifFxcJ1teXFwnXSpcXCd8XFxcXHNbXlxcJ1wiLz5cXFxcc10qKSo/Lz8+ICooPzpcXFxcbnsyLH18XFxcXHMqJCkpJylcbiAgICAucmVwbGFjZSgnY29tbWVudCcsIF9jb21tZW50KVxuICAgIC5yZXBsYWNlKC90YWcvZywgJyg/ISg/OidcbiAgICAgICsgJ2F8ZW18c3Ryb25nfHNtYWxsfHN8Y2l0ZXxxfGRmbnxhYmJyfGRhdGF8dGltZXxjb2RlfHZhcnxzYW1wfGtiZHxzdWInXG4gICAgICArICd8c3VwfGl8Ynx1fG1hcmt8cnVieXxydHxycHxiZGl8YmRvfHNwYW58YnJ8d2JyfGluc3xkZWx8aW1nKSdcbiAgICAgICsgJ1xcXFxiKVxcXFx3Kyg/ITp8W15cXFxcd1xcXFxzQF0qQClcXFxcYicpXG4gICAgLmdldFJlZ2V4KCksXG4gIGRlZjogL14gKlxcWyhbXlxcXV0rKVxcXTogKjw/KFteXFxzPl0rKT4/KD86ICsoW1wiKF1bXlxcbl0rW1wiKV0pKT8gKig/Olxcbit8JCkvLFxuICBoZWFkaW5nOiAvXigjezEsNn0pKC4qKSg/Olxcbit8JCkvLFxuICBmZW5jZXM6IG5vb3BUZXN0LCAvLyBmZW5jZXMgbm90IHN1cHBvcnRlZFxuICBsaGVhZGluZzogL14oLis/KVxcbiB7MCwzfSg9K3wtKykgKig/Olxcbit8JCkvLFxuICBwYXJhZ3JhcGg6IGVkaXQoX3BhcmFncmFwaClcbiAgICAucmVwbGFjZSgnaHInLCBocilcbiAgICAucmVwbGFjZSgnaGVhZGluZycsICcgKiN7MSw2fSAqW15cXG5dJylcbiAgICAucmVwbGFjZSgnbGhlYWRpbmcnLCBsaGVhZGluZylcbiAgICAucmVwbGFjZSgnfHRhYmxlJywgJycpXG4gICAgLnJlcGxhY2UoJ2Jsb2NrcXVvdGUnLCAnIHswLDN9PicpXG4gICAgLnJlcGxhY2UoJ3xmZW5jZXMnLCAnJylcbiAgICAucmVwbGFjZSgnfGxpc3QnLCAnJylcbiAgICAucmVwbGFjZSgnfGh0bWwnLCAnJylcbiAgICAucmVwbGFjZSgnfHRhZycsICcnKVxuICAgIC5nZXRSZWdleCgpLFxufTtcblxuLyoqXG4gKiBJbmxpbmUtTGV2ZWwgR3JhbW1hclxuICovXG5cbmNvbnN0IGVzY2FwZSA9IC9eXFxcXChbIVwiIyQlJicoKSorLFxcLS4vOjs8PT4/QFxcW1xcXVxcXFxeX2B7fH1+XSkvO1xuY29uc3QgaW5saW5lQ29kZSA9IC9eKGArKShbXmBdfFteYF1bXFxzXFxTXSo/W15gXSlcXDEoPyFgKS87XG5jb25zdCBiciA9IC9eKCB7Mix9fFxcXFwpXFxuKD8hXFxzKiQpLztcbmNvbnN0IGlubGluZVRleHQgPSAvXihgK3xbXmBdKSg/Oig/PSB7Mix9XFxuKXxbXFxzXFxTXSo/KD86KD89W1xcXFw8IVxcW2AqX118XFxiX3wkKXxbXiBdKD89IHsyLH1cXG4pKSkvO1xuXG4vLyBsaXN0IG9mIHVuaWNvZGUgcHVuY3R1YXRpb24gbWFya3MsIHBsdXMgYW55IG1pc3NpbmcgY2hhcmFjdGVycyBmcm9tIENvbW1vbk1hcmsgc3BlY1xuY29uc3QgX3B1bmN0dWF0aW9uID0gL1tcXHB7UH1cXHB7U31dL3U7XG5jb25zdCBfcHVuY3R1YXRpb25PclNwYWNlID0gL1tcXHNcXHB7UH1cXHB7U31dL3U7XG5jb25zdCBfbm90UHVuY3R1YXRpb25PclNwYWNlID0gL1teXFxzXFxwe1B9XFxwe1N9XS91O1xuY29uc3QgcHVuY3R1YXRpb24gPSBlZGl0KC9eKCg/IVsqX10pcHVuY3RTcGFjZSkvLCAndScpXG4gIC5yZXBsYWNlKC9wdW5jdFNwYWNlL2csIF9wdW5jdHVhdGlvbk9yU3BhY2UpLmdldFJlZ2V4KCk7XG5cbi8vIEdGTSBhbGxvd3MgfiBpbnNpZGUgc3Ryb25nIGFuZCBlbSBmb3Igc3RyaWtldGhyb3VnaFxuY29uc3QgX3B1bmN0dWF0aW9uR2ZtU3Ryb25nRW0gPSAvKD8hfilbXFxwe1B9XFxwe1N9XS91O1xuY29uc3QgX3B1bmN0dWF0aW9uT3JTcGFjZUdmbVN0cm9uZ0VtID0gLyg/IX4pW1xcc1xccHtQfVxccHtTfV0vdTtcbmNvbnN0IF9ub3RQdW5jdHVhdGlvbk9yU3BhY2VHZm1TdHJvbmdFbSA9IC8oPzpbXlxcc1xccHtQfVxccHtTfV18fikvdTtcblxuLy8gc2VxdWVuY2VzIGVtIHNob3VsZCBza2lwIG92ZXIgW3RpdGxlXShsaW5rKSwgYGNvZGVgLCA8aHRtbD5cbmNvbnN0IGJsb2NrU2tpcCA9IGVkaXQoL2xpbmt8cHJlY29kZS1jb2RlfGh0bWwvLCAnZycpXG4gIC5yZXBsYWNlKCdsaW5rJywgL1xcWyg/OlteXFxbXFxdYF18KD88YT5gKylbXmBdK1xcazxhPig/IWApKSo/XFxdXFwoKD86XFxcXFtcXHNcXFNdfFteXFxcXFxcKFxcKV18XFwoKD86XFxcXFtcXHNcXFNdfFteXFxcXFxcKFxcKV0pKlxcKSkqXFwpLylcbiAgLnJlcGxhY2UoJ3ByZWNvZGUtJywgc3VwcG9ydHNMb29rYmVoaW5kID8gJyg/PCFgKSgpJyA6ICcoXl58W15gXSknKVxuICAucmVwbGFjZSgnY29kZScsIC8oPzxiPmArKVteYF0rXFxrPGI+KD8hYCkvKVxuICAucmVwbGFjZSgnaHRtbCcsIC88KD8hIClbXjw+XSo/Pi8pXG4gIC5nZXRSZWdleCgpO1xuXG5jb25zdCBlbVN0cm9uZ0xEZWxpbUNvcmUgPSAvXig/OlxcKisoPzooKD8hXFwqKXB1bmN0KXwoW15cXHMqXSkpPyl8Xl8rKD86KCg/IV8pcHVuY3QpfChbXlxcc19dKSk/LztcblxuY29uc3QgZW1TdHJvbmdMRGVsaW0gPSBlZGl0KGVtU3Ryb25nTERlbGltQ29yZSwgJ3UnKVxuICAucmVwbGFjZSgvcHVuY3QvZywgX3B1bmN0dWF0aW9uKVxuICAuZ2V0UmVnZXgoKTtcblxuY29uc3QgZW1TdHJvbmdMRGVsaW1HZm0gPSBlZGl0KGVtU3Ryb25nTERlbGltQ29yZSwgJ3UnKVxuICAucmVwbGFjZSgvcHVuY3QvZywgX3B1bmN0dWF0aW9uR2ZtU3Ryb25nRW0pXG4gIC5nZXRSZWdleCgpO1xuXG5jb25zdCBlbVN0cm9uZ1JEZWxpbUFzdENvcmUgPVxuICAnXlteXypdKj9fX1teXypdKj9cXFxcKlteXypdKj8oPz1fXyknIC8vIFNraXAgb3JwaGFuIGluc2lkZSBzdHJvbmdcbisgJ3xbXipdKyg/PVteKl0pJyAvLyBDb25zdW1lIHRvIGRlbGltXG4rICd8KD8hXFxcXCopcHVuY3QoXFxcXCorKSg/PVtcXFxcc118JCknIC8vICgxKSAjKioqIGNhbiBvbmx5IGJlIGEgUmlnaHQgRGVsaW1pdGVyXG4rICd8bm90UHVuY3RTcGFjZShcXFxcKispKD8hXFxcXCopKD89cHVuY3RTcGFjZXwkKScgLy8gKDIpIGEqKiojLCBhKioqIGNhbiBvbmx5IGJlIGEgUmlnaHQgRGVsaW1pdGVyXG4rICd8KD8hXFxcXCopcHVuY3RTcGFjZShcXFxcKispKD89bm90UHVuY3RTcGFjZSknIC8vICgzKSAjKioqYSwgKioqYSBjYW4gb25seSBiZSBMZWZ0IERlbGltaXRlclxuKyAnfFtcXFxcc10oXFxcXCorKSg/IVxcXFwqKSg/PXB1bmN0KScgLy8gKDQpICoqKiMgY2FuIG9ubHkgYmUgTGVmdCBEZWxpbWl0ZXJcbisgJ3woPyFcXFxcKilwdW5jdChcXFxcKispKD8hXFxcXCopKD89cHVuY3QpJyAvLyAoNSkgIyoqKiMgY2FuIGJlIGVpdGhlciBMZWZ0IG9yIFJpZ2h0IERlbGltaXRlclxuKyAnfG5vdFB1bmN0U3BhY2UoXFxcXCorKSg/PW5vdFB1bmN0U3BhY2UpJzsgLy8gKDYpIGEqKiphIGNhbiBiZSBlaXRoZXIgTGVmdCBvciBSaWdodCBEZWxpbWl0ZXJcblxuY29uc3QgZW1TdHJvbmdSRGVsaW1Bc3QgPSBlZGl0KGVtU3Ryb25nUkRlbGltQXN0Q29yZSwgJ2d1JylcbiAgLnJlcGxhY2UoL25vdFB1bmN0U3BhY2UvZywgX25vdFB1bmN0dWF0aW9uT3JTcGFjZSlcbiAgLnJlcGxhY2UoL3B1bmN0U3BhY2UvZywgX3B1bmN0dWF0aW9uT3JTcGFjZSlcbiAgLnJlcGxhY2UoL3B1bmN0L2csIF9wdW5jdHVhdGlvbilcbiAgLmdldFJlZ2V4KCk7XG5cbmNvbnN0IGVtU3Ryb25nUkRlbGltQXN0R2ZtID0gZWRpdChlbVN0cm9uZ1JEZWxpbUFzdENvcmUsICdndScpXG4gIC5yZXBsYWNlKC9ub3RQdW5jdFNwYWNlL2csIF9ub3RQdW5jdHVhdGlvbk9yU3BhY2VHZm1TdHJvbmdFbSlcbiAgLnJlcGxhY2UoL3B1bmN0U3BhY2UvZywgX3B1bmN0dWF0aW9uT3JTcGFjZUdmbVN0cm9uZ0VtKVxuICAucmVwbGFjZSgvcHVuY3QvZywgX3B1bmN0dWF0aW9uR2ZtU3Ryb25nRW0pXG4gIC5nZXRSZWdleCgpO1xuXG4vLyAoNikgTm90IGFsbG93ZWQgZm9yIF9cbmNvbnN0IGVtU3Ryb25nUkRlbGltVW5kID0gZWRpdChcbiAgJ15bXl8qXSo/XFxcXCpcXFxcKlteXypdKj9fW15fKl0qPyg/PVxcXFwqXFxcXCopJyAvLyBTa2lwIG9ycGhhbiBpbnNpZGUgc3Ryb25nXG4rICd8W15fXSsoPz1bXl9dKScgLy8gQ29uc3VtZSB0byBkZWxpbVxuKyAnfCg/IV8pcHVuY3QoXyspKD89W1xcXFxzXXwkKScgLy8gKDEpICNfX18gY2FuIG9ubHkgYmUgYSBSaWdodCBEZWxpbWl0ZXJcbisgJ3xub3RQdW5jdFNwYWNlKF8rKSg/IV8pKD89cHVuY3RTcGFjZXwkKScgLy8gKDIpIGFfX18jLCBhX19fIGNhbiBvbmx5IGJlIGEgUmlnaHQgRGVsaW1pdGVyXG4rICd8KD8hXylwdW5jdFNwYWNlKF8rKSg/PW5vdFB1bmN0U3BhY2UpJyAvLyAoMykgI19fX2EsIF9fX2EgY2FuIG9ubHkgYmUgTGVmdCBEZWxpbWl0ZXJcbisgJ3xbXFxcXHNdKF8rKSg/IV8pKD89cHVuY3QpJyAvLyAoNCkgX19fIyBjYW4gb25seSBiZSBMZWZ0IERlbGltaXRlclxuKyAnfCg/IV8pcHVuY3QoXyspKD8hXykoPz1wdW5jdCknLCAnZ3UnKSAvLyAoNSkgI19fXyMgY2FuIGJlIGVpdGhlciBMZWZ0IG9yIFJpZ2h0IERlbGltaXRlclxuICAucmVwbGFjZSgvbm90UHVuY3RTcGFjZS9nLCBfbm90UHVuY3R1YXRpb25PclNwYWNlKVxuICAucmVwbGFjZSgvcHVuY3RTcGFjZS9nLCBfcHVuY3R1YXRpb25PclNwYWNlKVxuICAucmVwbGFjZSgvcHVuY3QvZywgX3B1bmN0dWF0aW9uKVxuICAuZ2V0UmVnZXgoKTtcblxuLy8gVGlsZGUgbGVmdCBkZWxpbWl0ZXIgZm9yIHN0cmlrZXRocm91Z2ggKHNpbWlsYXIgdG8gZW1TdHJvbmdMRGVsaW0gZm9yIGFzdGVyaXNrKVxuY29uc3QgZGVsTERlbGltID0gZWRpdCgvXn5+Pyg/OigoPyF+KXB1bmN0KXxbXlxcc35dKS8sICd1JylcbiAgLnJlcGxhY2UoL3B1bmN0L2csIF9wdW5jdHVhdGlvbilcbiAgLmdldFJlZ2V4KCk7XG5cbi8vIFRpbGRlIGRlbGltaXRlciBwYXR0ZXJucyBmb3Igc3RyaWtldGhyb3VnaCAoc2ltaWxhciB0byBhc3RlcmlzaylcbmNvbnN0IGRlbFJEZWxpbUNvcmUgPVxuICAnXltefl0rKD89W15+XSknIC8vIENvbnN1bWUgdG8gZGVsaW1cbisgJ3woPyF+KXB1bmN0KH5+PykoPz1bXFxcXHNdfCQpJyAvLyAoMSkgI35+IGNhbiBvbmx5IGJlIGEgUmlnaHQgRGVsaW1pdGVyXG4rICd8bm90UHVuY3RTcGFjZSh+fj8pKD8hfikoPz1wdW5jdFNwYWNlfCQpJyAvLyAoMikgYX5+IywgYX5+IGNhbiBvbmx5IGJlIGEgUmlnaHQgRGVsaW1pdGVyXG4rICd8KD8hfilwdW5jdFNwYWNlKH5+PykoPz1ub3RQdW5jdFNwYWNlKScgLy8gKDMpICN+fmEsIH5+YSBjYW4gb25seSBiZSBMZWZ0IERlbGltaXRlclxuKyAnfFtcXFxcc10ofn4/KSg/IX4pKD89cHVuY3QpJyAvLyAoNCkgfn4jIGNhbiBvbmx5IGJlIExlZnQgRGVsaW1pdGVyXG4rICd8KD8hfilwdW5jdCh+fj8pKD8hfikoPz1wdW5jdCknIC8vICg1KSAjfn4jIGNhbiBiZSBlaXRoZXIgTGVmdCBvciBSaWdodCBEZWxpbWl0ZXJcbisgJ3xub3RQdW5jdFNwYWNlKH5+PykoPz1ub3RQdW5jdFNwYWNlKSc7IC8vICg2KSBhfn5hIGNhbiBiZSBlaXRoZXIgTGVmdCBvciBSaWdodCBEZWxpbWl0ZXJcblxuY29uc3QgZGVsUkRlbGltID0gZWRpdChkZWxSRGVsaW1Db3JlLCAnZ3UnKVxuICAucmVwbGFjZSgvbm90UHVuY3RTcGFjZS9nLCBfbm90UHVuY3R1YXRpb25PclNwYWNlKVxuICAucmVwbGFjZSgvcHVuY3RTcGFjZS9nLCBfcHVuY3R1YXRpb25PclNwYWNlKVxuICAucmVwbGFjZSgvcHVuY3QvZywgX3B1bmN0dWF0aW9uKVxuICAuZ2V0UmVnZXgoKTtcblxuY29uc3QgYW55UHVuY3R1YXRpb24gPSBlZGl0KC9cXFxcKHB1bmN0KS8sICdndScpXG4gIC5yZXBsYWNlKC9wdW5jdC9nLCBfcHVuY3R1YXRpb24pXG4gIC5nZXRSZWdleCgpO1xuXG5jb25zdCBhdXRvbGluayA9IGVkaXQoL148KHNjaGVtZTpbXlxcc1xceDAwLVxceDFmPD5dKnxlbWFpbCk+LylcbiAgLnJlcGxhY2UoJ3NjaGVtZScsIC9bYS16QS1aXVthLXpBLVowLTkrLi1dezEsMzF9LylcbiAgLnJlcGxhY2UoJ2VtYWlsJywgL1thLXpBLVowLTkuISMkJSYnKisvPT9eX2B7fH1+LV0rKEApW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/KD86XFwuW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/KSsoPyFbLV9dKS8pXG4gIC5nZXRSZWdleCgpO1xuXG5jb25zdCBfaW5saW5lQ29tbWVudCA9IGVkaXQoX2NvbW1lbnQpLnJlcGxhY2UoJyg/Oi0tPnwkKScsICctLT4nKS5nZXRSZWdleCgpO1xuY29uc3QgdGFnID0gZWRpdChcbiAgJ15jb21tZW50J1xuICAgICsgJ3xePC9bYS16QS1aXVtcXFxcdzotXSpcXFxccyo+JyAvLyBzZWxmLWNsb3NpbmcgdGFnXG4gICAgKyAnfF48W2EtekEtWl1bXFxcXHctXSooPzphdHRyaWJ1dGUpKj9cXFxccyovPz4nIC8vIG9wZW4gdGFnXG4gICAgKyAnfF48XFxcXD9bXFxcXHNcXFxcU10qP1xcXFw/PicgLy8gcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiwgZS5nLiA8P3BocCA/PlxuICAgICsgJ3xePCFbYS16QS1aXStcXFxcc1tcXFxcc1xcXFxTXSo/PicgLy8gZGVjbGFyYXRpb24sIGUuZy4gPCFET0NUWVBFIGh0bWw+XG4gICAgKyAnfF48IVxcXFxbQ0RBVEFcXFxcW1tcXFxcc1xcXFxTXSo/XFxcXF1cXFxcXT4nKSAvLyBDREFUQSBzZWN0aW9uXG4gIC5yZXBsYWNlKCdjb21tZW50JywgX2lubGluZUNvbW1lbnQpXG4gIC5yZXBsYWNlKCdhdHRyaWJ1dGUnLCAvXFxzK1thLXpBLVo6X11bXFx3LjotXSooPzpcXHMqPVxccypcIlteXCJdKlwifFxccyo9XFxzKidbXiddKid8XFxzKj1cXHMqW15cXHNcIic9PD5gXSspPy8pXG4gIC5nZXRSZWdleCgpO1xuXG5jb25zdCBfaW5saW5lTGFiZWwgPSAvKD86XFxbKD86XFxcXFtcXHNcXFNdfFteXFxbXFxdXFxcXF0pKlxcXXxcXFxcW1xcc1xcU118YCsoPyFgKVteYF0qP2ArKD8hYCl8YGArKD89XFxdKXxbXlxcW1xcXVxcXFxgXSkqPy87XG5cbmNvbnN0IGxpbmsgPSBlZGl0KC9eIT9cXFsobGFiZWwpXFxdXFwoXFxzKihocmVmKSg/Oig/OlsgXFx0XSsoPzpcXG5bIFxcdF0qKT98XFxuWyBcXHRdKikodGl0bGUpKT9cXHMqXFwpLylcbiAgLnJlcGxhY2UoJ2xhYmVsJywgX2lubGluZUxhYmVsKVxuICAucmVwbGFjZSgnaHJlZicsIC88KD86XFxcXC58W15cXG48PlxcXFxdKSs+fFteIFxcdFxcblxceDAwLVxceDFmXSovKVxuICAucmVwbGFjZSgndGl0bGUnLCAvXCIoPzpcXFxcXCI/fFteXCJcXFxcXSkqXCJ8Jyg/OlxcXFwnP3xbXidcXFxcXSkqJ3xcXCgoPzpcXFxcXFwpP3xbXilcXFxcXSkqXFwpLylcbiAgLmdldFJlZ2V4KCk7XG5cbmNvbnN0IHJlZmxpbmsgPSBlZGl0KC9eIT9cXFsobGFiZWwpXFxdXFxbKHJlZilcXF0vKVxuICAucmVwbGFjZSgnbGFiZWwnLCBfaW5saW5lTGFiZWwpXG4gIC5yZXBsYWNlKCdyZWYnLCBfYmxvY2tMYWJlbClcbiAgLmdldFJlZ2V4KCk7XG5cbmNvbnN0IG5vbGluayA9IGVkaXQoL14hP1xcWyhyZWYpXFxdKD86XFxbXFxdKT8vKVxuICAucmVwbGFjZSgncmVmJywgX2Jsb2NrTGFiZWwpXG4gIC5nZXRSZWdleCgpO1xuXG5jb25zdCByZWZsaW5rU2VhcmNoID0gZWRpdCgncmVmbGlua3xub2xpbmsoPyFcXFxcKCknLCAnZycpXG4gIC5yZXBsYWNlKCdyZWZsaW5rJywgcmVmbGluaylcbiAgLnJlcGxhY2UoJ25vbGluaycsIG5vbGluaylcbiAgLmdldFJlZ2V4KCk7XG5cbmNvbnN0IF9jYXNlSW5zZW5zaXRpdmVQcm90b2NvbCA9IC9baEhdW3RUXVt0VF1bcFBdW3NTXT98W2ZGXVt0VF1bcFBdLztcblxuLyoqXG4gKiBOb3JtYWwgSW5saW5lIEdyYW1tYXJcbiAqL1xuXG5jb25zdCBpbmxpbmVOb3JtYWwgPSB7XG4gIF9iYWNrcGVkYWw6IG5vb3BUZXN0LCAvLyBvbmx5IHVzZWQgZm9yIEdGTSB1cmxcbiAgYW55UHVuY3R1YXRpb24sXG4gIGF1dG9saW5rLFxuICBibG9ja1NraXAsXG4gIGJyLFxuICBjb2RlOiBpbmxpbmVDb2RlLFxuICBkZWw6IG5vb3BUZXN0LFxuICBkZWxMRGVsaW06IG5vb3BUZXN0LFxuICBkZWxSRGVsaW06IG5vb3BUZXN0LFxuICBlbVN0cm9uZ0xEZWxpbSxcbiAgZW1TdHJvbmdSRGVsaW1Bc3QsXG4gIGVtU3Ryb25nUkRlbGltVW5kLFxuICBlc2NhcGUsXG4gIGxpbmssXG4gIG5vbGluayxcbiAgcHVuY3R1YXRpb24sXG4gIHJlZmxpbmssXG4gIHJlZmxpbmtTZWFyY2gsXG4gIHRhZyxcbiAgdGV4dDogaW5saW5lVGV4dCxcbiAgdXJsOiBub29wVGVzdCxcbn07XG5cbnR5cGUgSW5saW5lS2V5cyA9IGtleW9mIHR5cGVvZiBpbmxpbmVOb3JtYWw7XG5cbi8qKlxuICogUGVkYW50aWMgSW5saW5lIEdyYW1tYXJcbiAqL1xuXG5jb25zdCBpbmxpbmVQZWRhbnRpYzogUmVjb3JkPElubGluZUtleXMsIFJlZ0V4cD4gPSB7XG4gIC4uLmlubGluZU5vcm1hbCxcbiAgbGluazogZWRpdCgvXiE/XFxbKGxhYmVsKVxcXVxcKCguKj8pXFwpLylcbiAgICAucmVwbGFjZSgnbGFiZWwnLCBfaW5saW5lTGFiZWwpXG4gICAgLmdldFJlZ2V4KCksXG4gIHJlZmxpbms6IGVkaXQoL14hP1xcWyhsYWJlbClcXF1cXHMqXFxbKFteXFxdXSopXFxdLylcbiAgICAucmVwbGFjZSgnbGFiZWwnLCBfaW5saW5lTGFiZWwpXG4gICAgLmdldFJlZ2V4KCksXG59O1xuXG4vKipcbiAqIEdGTSBJbmxpbmUgR3JhbW1hclxuICovXG5cbmNvbnN0IGlubGluZUdmbTogUmVjb3JkPElubGluZUtleXMsIFJlZ0V4cD4gPSB7XG4gIC4uLmlubGluZU5vcm1hbCxcbiAgZW1TdHJvbmdSRGVsaW1Bc3Q6IGVtU3Ryb25nUkRlbGltQXN0R2ZtLFxuICBlbVN0cm9uZ0xEZWxpbTogZW1TdHJvbmdMRGVsaW1HZm0sXG4gIGRlbExEZWxpbSxcbiAgZGVsUkRlbGltLFxuICB1cmw6IGVkaXQoL14oKD86cHJvdG9jb2wpOlxcL1xcL3x3d3dcXC4pKD86W2EtekEtWjAtOVxcLV0rXFwuPykrW15cXHM8XSp8XmVtYWlsLylcbiAgICAucmVwbGFjZSgncHJvdG9jb2wnLCBfY2FzZUluc2Vuc2l0aXZlUHJvdG9jb2wpXG4gICAgLnJlcGxhY2UoJ2VtYWlsJywgL1tBLVphLXowLTkuXystXSsoQClbYS16QS1aMC05LV9dKyg/OlxcLlthLXpBLVowLTktX10qW2EtekEtWjAtOV0pKyg/IVstX10pLylcbiAgICAuZ2V0UmVnZXgoKSxcbiAgX2JhY2twZWRhbDogLyg/OltePyEuLDo7Kl8nXCJ+KCkmXSt8XFwoW14pXSpcXCl8Jig/IVthLXpBLVowLTldKzskKXxbPyEuLDo7Kl8nXCJ+KV0rKD8hJCkpKy8sXG4gIGRlbDogL14ofn4/KSg/PVteXFxzfl0pKCg/OlxcXFxbXFxzXFxTXXxbXlxcXFxdKSo/KD86XFxcXFtcXHNcXFNdfFteXFxzflxcXFxdKSlcXDEoPz1bXn5dfCQpLyxcbiAgdGV4dDogZWRpdCgvXihbYH5dK3xbXmB+XSkoPzooPz0gezIsfVxcbil8KD89W2EtekEtWjAtOS4hIyQlJicqK1xcLz0/X2B7XFx8fX4tXStAKXxbXFxzXFxTXSo/KD86KD89W1xcXFw8IVxcW2Aqfl9dfFxcYl98cHJvdG9jb2w6XFwvXFwvfHd3d1xcLnwkKXxbXiBdKD89IHsyLH1cXG4pfFteYS16QS1aMC05LiEjJCUmJyorXFwvPT9fYHtcXHx9fi1dKD89W2EtekEtWjAtOS4hIyQlJicqK1xcLz0/X2B7XFx8fX4tXStAKSkpLylcbiAgICAucmVwbGFjZSgncHJvdG9jb2wnLCBfY2FzZUluc2Vuc2l0aXZlUHJvdG9jb2wpXG4gICAgLmdldFJlZ2V4KCksXG59O1xuXG4vKipcbiAqIEdGTSArIExpbmUgQnJlYWtzIElubGluZSBHcmFtbWFyXG4gKi9cblxuY29uc3QgaW5saW5lQnJlYWtzOiBSZWNvcmQ8SW5saW5lS2V5cywgUmVnRXhwPiA9IHtcbiAgLi4uaW5saW5lR2ZtLFxuICBicjogZWRpdChicikucmVwbGFjZSgnezIsfScsICcqJykuZ2V0UmVnZXgoKSxcbiAgdGV4dDogZWRpdChpbmxpbmVHZm0udGV4dClcbiAgICAucmVwbGFjZSgnXFxcXGJfJywgJ1xcXFxiX3wgezIsfVxcXFxuJylcbiAgICAucmVwbGFjZSgvXFx7MixcXH0vZywgJyonKVxuICAgIC5nZXRSZWdleCgpLFxufTtcblxuLyoqXG4gKiBleHBvcnRzXG4gKi9cblxuZXhwb3J0IGNvbnN0IGJsb2NrID0ge1xuICBub3JtYWw6IGJsb2NrTm9ybWFsLFxuICBnZm06IGJsb2NrR2ZtLFxuICBwZWRhbnRpYzogYmxvY2tQZWRhbnRpYyxcbn07XG5cbmV4cG9ydCBjb25zdCBpbmxpbmUgPSB7XG4gIG5vcm1hbDogaW5saW5lTm9ybWFsLFxuICBnZm06IGlubGluZUdmbSxcbiAgYnJlYWtzOiBpbmxpbmVCcmVha3MsXG4gIHBlZGFudGljOiBpbmxpbmVQZWRhbnRpYyxcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUnVsZXMge1xuICBvdGhlcjogdHlwZW9mIG90aGVyXG4gIGJsb2NrOiBSZWNvcmQ8QmxvY2tLZXlzLCBSZWdFeHA+XG4gIGlubGluZTogUmVjb3JkPElubGluZUtleXMsIFJlZ0V4cD5cbn1cbiIsICJpbXBvcnQgeyBvdGhlciB9IGZyb20gJy4vcnVsZXMudHMnO1xuXG4vKipcbiAqIEhlbHBlcnNcbiAqL1xuY29uc3QgZXNjYXBlUmVwbGFjZW1lbnRzOiB7IFtpbmRleDogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICcmJzogJyZhbXA7JyxcbiAgJzwnOiAnJmx0OycsXG4gICc+JzogJyZndDsnLFxuICAnXCInOiAnJnF1b3Q7JyxcbiAgXCInXCI6ICcmIzM5OycsXG59O1xuY29uc3QgZ2V0RXNjYXBlUmVwbGFjZW1lbnQgPSAoY2g6IHN0cmluZykgPT4gZXNjYXBlUmVwbGFjZW1lbnRzW2NoXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZUh0bWxFbnRpdGllcyhodG1sOiBzdHJpbmcsIGVuY29kZT86IGJvb2xlYW4pIHtcbiAgaWYgKGVuY29kZSkge1xuICAgIGlmIChvdGhlci5lc2NhcGVUZXN0LnRlc3QoaHRtbCkpIHtcbiAgICAgIHJldHVybiBodG1sLnJlcGxhY2Uob3RoZXIuZXNjYXBlUmVwbGFjZSwgZ2V0RXNjYXBlUmVwbGFjZW1lbnQpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAob3RoZXIuZXNjYXBlVGVzdE5vRW5jb2RlLnRlc3QoaHRtbCkpIHtcbiAgICAgIHJldHVybiBodG1sLnJlcGxhY2Uob3RoZXIuZXNjYXBlUmVwbGFjZU5vRW5jb2RlLCBnZXRFc2NhcGVSZXBsYWNlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGh0bWw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhblVybChocmVmOiBzdHJpbmcpIHtcbiAgdHJ5IHtcbiAgICBocmVmID0gZW5jb2RlVVJJKGhyZWYpLnJlcGxhY2Uob3RoZXIucGVyY2VudERlY29kZSwgJyUnKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIGhyZWY7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzcGxpdENlbGxzKHRhYmxlUm93OiBzdHJpbmcsIGNvdW50PzogbnVtYmVyKSB7XG4gIC8vIGVuc3VyZSB0aGF0IGV2ZXJ5IGNlbGwtZGVsaW1pdGluZyBwaXBlIGhhcyBhIHNwYWNlXG4gIC8vIGJlZm9yZSBpdCB0byBkaXN0aW5ndWlzaCBpdCBmcm9tIGFuIGVzY2FwZWQgcGlwZVxuICBjb25zdCByb3cgPSB0YWJsZVJvdy5yZXBsYWNlKG90aGVyLmZpbmRQaXBlLCAobWF0Y2gsIG9mZnNldCwgc3RyKSA9PiB7XG4gICAgICBsZXQgZXNjYXBlZCA9IGZhbHNlO1xuICAgICAgbGV0IGN1cnIgPSBvZmZzZXQ7XG4gICAgICB3aGlsZSAoLS1jdXJyID49IDAgJiYgc3RyW2N1cnJdID09PSAnXFxcXCcpIGVzY2FwZWQgPSAhZXNjYXBlZDtcbiAgICAgIGlmIChlc2NhcGVkKSB7XG4gICAgICAgIC8vIG9kZCBudW1iZXIgb2Ygc2xhc2hlcyBtZWFucyB8IGlzIGVzY2FwZWRcbiAgICAgICAgLy8gc28gd2UgbGVhdmUgaXQgYWxvbmVcbiAgICAgICAgcmV0dXJuICd8JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGFkZCBzcGFjZSBiZWZvcmUgdW5lc2NhcGVkIHxcbiAgICAgICAgcmV0dXJuICcgfCc7XG4gICAgICB9XG4gICAgfSksXG4gICAgY2VsbHMgPSByb3cuc3BsaXQob3RoZXIuc3BsaXRQaXBlKTtcbiAgbGV0IGkgPSAwO1xuXG4gIC8vIEZpcnN0L2xhc3QgY2VsbCBpbiBhIHJvdyBjYW5ub3QgYmUgZW1wdHkgaWYgaXQgaGFzIG5vIGxlYWRpbmcvdHJhaWxpbmcgcGlwZVxuICBpZiAoIWNlbGxzWzBdLnRyaW0oKSkge1xuICAgIGNlbGxzLnNoaWZ0KCk7XG4gIH1cbiAgaWYgKGNlbGxzLmxlbmd0aCA+IDAgJiYgIWNlbGxzLmF0KC0xKT8udHJpbSgpKSB7XG4gICAgY2VsbHMucG9wKCk7XG4gIH1cblxuICBpZiAoY291bnQpIHtcbiAgICBpZiAoY2VsbHMubGVuZ3RoID4gY291bnQpIHtcbiAgICAgIGNlbGxzLnNwbGljZShjb3VudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoaWxlIChjZWxscy5sZW5ndGggPCBjb3VudCkgY2VsbHMucHVzaCgnJyk7XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IGkgPCBjZWxscy5sZW5ndGg7IGkrKykge1xuICAgIC8vIGxlYWRpbmcgb3IgdHJhaWxpbmcgd2hpdGVzcGFjZSBpcyBpZ25vcmVkIHBlciB0aGUgZ2ZtIHNwZWNcbiAgICBjZWxsc1tpXSA9IGNlbGxzW2ldLnRyaW0oKS5yZXBsYWNlKG90aGVyLnNsYXNoUGlwZSwgJ3wnKTtcbiAgfVxuICByZXR1cm4gY2VsbHM7XG59XG5cbi8qKlxuICogUmVtb3ZlIHRyYWlsaW5nICdjJ3MuIEVxdWl2YWxlbnQgdG8gc3RyLnJlcGxhY2UoL2MqJC8sICcnKS5cbiAqIC9jKiQvIGlzIHZ1bG5lcmFibGUgdG8gUkVET1MuXG4gKlxuICogQHBhcmFtIHN0clxuICogQHBhcmFtIGNcbiAqIEBwYXJhbSBpbnZlcnQgUmVtb3ZlIHN1ZmZpeCBvZiBub24tYyBjaGFycyBpbnN0ZWFkLiBEZWZhdWx0IGZhbHNleS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJ0cmltKHN0cjogc3RyaW5nLCBjOiBzdHJpbmcsIGludmVydD86IGJvb2xlYW4pIHtcbiAgY29uc3QgbCA9IHN0ci5sZW5ndGg7XG4gIGlmIChsID09PSAwKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgLy8gTGVuZ3RoIG9mIHN1ZmZpeCBtYXRjaGluZyB0aGUgaW52ZXJ0IGNvbmRpdGlvbi5cbiAgbGV0IHN1ZmZMZW4gPSAwO1xuXG4gIC8vIFN0ZXAgbGVmdCB1bnRpbCB3ZSBmYWlsIHRvIG1hdGNoIHRoZSBpbnZlcnQgY29uZGl0aW9uLlxuICB3aGlsZSAoc3VmZkxlbiA8IGwpIHtcbiAgICBjb25zdCBjdXJyQ2hhciA9IHN0ci5jaGFyQXQobCAtIHN1ZmZMZW4gLSAxKTtcbiAgICBpZiAoY3VyckNoYXIgPT09IGMgJiYgIWludmVydCkge1xuICAgICAgc3VmZkxlbisrO1xuICAgIH0gZWxzZSBpZiAoY3VyckNoYXIgIT09IGMgJiYgaW52ZXJ0KSB7XG4gICAgICBzdWZmTGVuKys7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzdHIuc2xpY2UoMCwgbCAtIHN1ZmZMZW4pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdHJpbVRyYWlsaW5nQmxhbmtMaW5lcyhzdHI6IHN0cmluZykge1xuICBjb25zdCBsaW5lcyA9IHN0ci5zcGxpdCgnXFxuJyk7XG4gIGxldCBlbmQgPSBsaW5lcy5sZW5ndGggLSAxO1xuICB3aGlsZSAoZW5kID49IDAgJiYgb3RoZXIuYmxhbmtMaW5lLnRlc3QobGluZXNbZW5kXSkpIHtcbiAgICBlbmQtLTtcbiAgfVxuICBpZiAobGluZXMubGVuZ3RoIC0gZW5kIDw9IDIpIHtcbiAgICAvLyB3ZSB3YW50IHRvIGtlZXAgc2luZ2xlIHRyYWlsaW5nIGJsYW5rIGxpbmVzXG4gICAgcmV0dXJuIHN0cjtcbiAgfVxuXG4gIHJldHVybiBsaW5lcy5zbGljZSgwLCBlbmQgKyAxKS5qb2luKCdcXG4nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRDbG9zaW5nQnJhY2tldChzdHI6IHN0cmluZywgYjogc3RyaW5nKSB7XG4gIGlmIChzdHIuaW5kZXhPZihiWzFdKSA9PT0gLTEpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICBsZXQgbGV2ZWwgPSAwO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIGlmIChzdHJbaV0gPT09ICdcXFxcJykge1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSBpZiAoc3RyW2ldID09PSBiWzBdKSB7XG4gICAgICBsZXZlbCsrO1xuICAgIH0gZWxzZSBpZiAoc3RyW2ldID09PSBiWzFdKSB7XG4gICAgICBsZXZlbC0tO1xuICAgICAgaWYgKGxldmVsIDwgMCkge1xuICAgICAgICByZXR1cm4gaTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKGxldmVsID4gMCkge1xuICAgIHJldHVybiAtMjtcbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4cGFuZFRhYnMobGluZTogc3RyaW5nLCBpbmRlbnQgPSAwKSB7XG4gIGxldCBjb2wgPSBpbmRlbnQ7XG4gIGxldCBleHBhbmRlZCA9ICcnO1xuICBmb3IgKGNvbnN0IGNoYXIgb2YgbGluZSkge1xuICAgIGlmIChjaGFyID09PSAnXFx0Jykge1xuICAgICAgY29uc3QgYWRkZWQgPSA0IC0gKGNvbCAlIDQpO1xuICAgICAgZXhwYW5kZWQgKz0gJyAnLnJlcGVhdChhZGRlZCk7XG4gICAgICBjb2wgKz0gYWRkZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV4cGFuZGVkICs9IGNoYXI7XG4gICAgICBjb2wrKztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXhwYW5kZWQ7XG59XG4iLCAiaW1wb3J0IHsgX2RlZmF1bHRzIH0gZnJvbSAnLi9kZWZhdWx0cy50cyc7XG5pbXBvcnQge1xuICBydHJpbSxcbiAgc3BsaXRDZWxscyxcbiAgZmluZENsb3NpbmdCcmFja2V0LFxuICBleHBhbmRUYWJzLFxuICB0cmltVHJhaWxpbmdCbGFua0xpbmVzLFxufSBmcm9tICcuL2hlbHBlcnMudHMnO1xuaW1wb3J0IHR5cGUgeyBSdWxlcyB9IGZyb20gJy4vcnVsZXMudHMnO1xuaW1wb3J0IHR5cGUgeyBfTGV4ZXIgfSBmcm9tICcuL0xleGVyLnRzJztcbmltcG9ydCB0eXBlIHsgTGlua3MsIFRva2VucywgVG9rZW4gfSBmcm9tICcuL1Rva2Vucy50cyc7XG5pbXBvcnQgdHlwZSB7IE1hcmtlZE9wdGlvbnMgfSBmcm9tICcuL01hcmtlZE9wdGlvbnMudHMnO1xuXG5mdW5jdGlvbiBvdXRwdXRMaW5rKGNhcDogc3RyaW5nW10sIGxpbms6IFBpY2s8VG9rZW5zLkxpbmssICdocmVmJyB8ICd0aXRsZSc+LCByYXc6IHN0cmluZywgbGV4ZXI6IF9MZXhlciwgcnVsZXM6IFJ1bGVzKTogVG9rZW5zLkxpbmsgfCBUb2tlbnMuSW1hZ2Uge1xuICBjb25zdCBocmVmID0gbGluay5ocmVmO1xuICBjb25zdCB0aXRsZSA9IGxpbmsudGl0bGUgfHwgbnVsbDtcbiAgY29uc3QgdGV4dCA9IGNhcFsxXS5yZXBsYWNlKHJ1bGVzLm90aGVyLm91dHB1dExpbmtSZXBsYWNlLCAnJDEnKTtcblxuICBsZXhlci5zdGF0ZS5pbkxpbmsgPSB0cnVlO1xuICBjb25zdCB0b2tlbjogVG9rZW5zLkxpbmsgfCBUb2tlbnMuSW1hZ2UgPSB7XG4gICAgdHlwZTogY2FwWzBdLmNoYXJBdCgwKSA9PT0gJyEnID8gJ2ltYWdlJyA6ICdsaW5rJyxcbiAgICByYXcsXG4gICAgaHJlZixcbiAgICB0aXRsZSxcbiAgICB0ZXh0LFxuICAgIHRva2VuczogbGV4ZXIuaW5saW5lVG9rZW5zKHRleHQpLFxuICB9O1xuICBsZXhlci5zdGF0ZS5pbkxpbmsgPSBmYWxzZTtcbiAgcmV0dXJuIHRva2VuO1xufVxuXG5mdW5jdGlvbiBpbmRlbnRDb2RlQ29tcGVuc2F0aW9uKHJhdzogc3RyaW5nLCB0ZXh0OiBzdHJpbmcsIHJ1bGVzOiBSdWxlcykge1xuICBjb25zdCBtYXRjaEluZGVudFRvQ29kZSA9IHJhdy5tYXRjaChydWxlcy5vdGhlci5pbmRlbnRDb2RlQ29tcGVuc2F0aW9uKTtcblxuICBpZiAobWF0Y2hJbmRlbnRUb0NvZGUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gdGV4dDtcbiAgfVxuXG4gIGNvbnN0IGluZGVudFRvQ29kZSA9IG1hdGNoSW5kZW50VG9Db2RlWzFdO1xuXG4gIHJldHVybiB0ZXh0XG4gICAgLnNwbGl0KCdcXG4nKVxuICAgIC5tYXAobm9kZSA9PiB7XG4gICAgICBjb25zdCBtYXRjaEluZGVudEluTm9kZSA9IG5vZGUubWF0Y2gocnVsZXMub3RoZXIuYmVnaW5uaW5nU3BhY2UpO1xuICAgICAgaWYgKG1hdGNoSW5kZW50SW5Ob2RlID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBbaW5kZW50SW5Ob2RlXSA9IG1hdGNoSW5kZW50SW5Ob2RlO1xuXG4gICAgICBpZiAoaW5kZW50SW5Ob2RlLmxlbmd0aCA+PSBpbmRlbnRUb0NvZGUubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBub2RlLnNsaWNlKGluZGVudFRvQ29kZS5sZW5ndGgpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbm9kZTtcbiAgICB9KVxuICAgIC5qb2luKCdcXG4nKTtcbn1cblxuLyoqXG4gKiBUb2tlbml6ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIF9Ub2tlbml6ZXI8UGFyc2VyT3V0cHV0ID0gc3RyaW5nLCBSZW5kZXJlck91dHB1dCA9IHN0cmluZz4ge1xuICBvcHRpb25zOiBNYXJrZWRPcHRpb25zPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+O1xuICBydWxlcyE6IFJ1bGVzOyAvLyBzZXQgYnkgdGhlIGxleGVyXG4gIGxleGVyITogX0xleGVyPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+OyAvLyBzZXQgYnkgdGhlIGxleGVyXG5cbiAgY29uc3RydWN0b3Iob3B0aW9ucz86IE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4pIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IF9kZWZhdWx0cztcbiAgfVxuXG4gIHNwYWNlKHNyYzogc3RyaW5nKTogVG9rZW5zLlNwYWNlIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLm5ld2xpbmUuZXhlYyhzcmMpO1xuICAgIGlmIChjYXAgJiYgY2FwWzBdLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdzcGFjZScsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBjb2RlKHNyYzogc3RyaW5nKTogVG9rZW5zLkNvZGUgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNhcCA9IHRoaXMucnVsZXMuYmxvY2suY29kZS5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgY29uc3QgcmF3ID0gdGhpcy5vcHRpb25zLnBlZGFudGljXG4gICAgICAgID8gY2FwWzBdXG4gICAgICAgIDogdHJpbVRyYWlsaW5nQmxhbmtMaW5lcyhjYXBbMF0pO1xuICAgICAgY29uc3QgdGV4dCA9IHJhdy5yZXBsYWNlKHRoaXMucnVsZXMub3RoZXIuY29kZVJlbW92ZUluZGVudCwgJycpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2NvZGUnLFxuICAgICAgICByYXcsXG4gICAgICAgIGNvZGVCbG9ja1N0eWxlOiAnaW5kZW50ZWQnLFxuICAgICAgICB0ZXh0LFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBmZW5jZXMoc3JjOiBzdHJpbmcpOiBUb2tlbnMuQ29kZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5mZW5jZXMuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIGNvbnN0IHJhdyA9IGNhcFswXTtcbiAgICAgIGNvbnN0IHRleHQgPSBpbmRlbnRDb2RlQ29tcGVuc2F0aW9uKHJhdywgY2FwWzNdIHx8ICcnLCB0aGlzLnJ1bGVzKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2NvZGUnLFxuICAgICAgICByYXcsXG4gICAgICAgIGxhbmc6IGNhcFsyXSA/IGNhcFsyXS50cmltKCkucmVwbGFjZSh0aGlzLnJ1bGVzLmlubGluZS5hbnlQdW5jdHVhdGlvbiwgJyQxJykgOiBjYXBbMl0sXG4gICAgICAgIHRleHQsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGhlYWRpbmcoc3JjOiBzdHJpbmcpOiBUb2tlbnMuSGVhZGluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5oZWFkaW5nLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICBsZXQgdGV4dCA9IGNhcFsyXS50cmltKCk7XG5cbiAgICAgIC8vIHJlbW92ZSB0cmFpbGluZyAjc1xuICAgICAgaWYgKHRoaXMucnVsZXMub3RoZXIuZW5kaW5nSGFzaC50ZXN0KHRleHQpKSB7XG4gICAgICAgIGNvbnN0IHRyaW1tZWQgPSBydHJpbSh0ZXh0LCAnIycpO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBlZGFudGljKSB7XG4gICAgICAgICAgdGV4dCA9IHRyaW1tZWQudHJpbSgpO1xuICAgICAgICB9IGVsc2UgaWYgKCF0cmltbWVkIHx8IHRoaXMucnVsZXMub3RoZXIuZW5kaW5nU3BhY2VDaGFyLnRlc3QodHJpbW1lZCkpIHtcbiAgICAgICAgICAvLyBDb21tb25NYXJrIHJlcXVpcmVzIHNwYWNlIGJlZm9yZSB0cmFpbGluZyAjc1xuICAgICAgICAgIHRleHQgPSB0cmltbWVkLnRyaW0oKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnaGVhZGluZycsXG4gICAgICAgIHJhdzogcnRyaW0oY2FwWzBdLCAnXFxuJyksXG4gICAgICAgIGRlcHRoOiBjYXBbMV0ubGVuZ3RoLFxuICAgICAgICB0ZXh0LFxuICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lKHRleHQpLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBocihzcmM6IHN0cmluZyk6IFRva2Vucy5IciB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5oci5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2hyJyxcbiAgICAgICAgcmF3OiBydHJpbShjYXBbMF0sICdcXG4nKSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgYmxvY2txdW90ZShzcmM6IHN0cmluZyk6IFRva2Vucy5CbG9ja3F1b3RlIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLmJsb2NrcXVvdGUuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIGxldCBsaW5lcyA9IHJ0cmltKGNhcFswXSwgJ1xcbicpLnNwbGl0KCdcXG4nKTtcbiAgICAgIGxldCByYXcgPSAnJztcbiAgICAgIGxldCB0ZXh0ID0gJyc7XG4gICAgICBjb25zdCB0b2tlbnM6IFRva2VuW10gPSBbXTtcblxuICAgICAgd2hpbGUgKGxpbmVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbGV0IGluQmxvY2txdW90ZSA9IGZhbHNlO1xuICAgICAgICBjb25zdCBjdXJyZW50TGluZXMgPSBbXTtcblxuICAgICAgICBsZXQgaTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgLy8gZ2V0IGxpbmVzIHVwIHRvIGEgY29udGludWF0aW9uXG4gICAgICAgICAgaWYgKHRoaXMucnVsZXMub3RoZXIuYmxvY2txdW90ZVN0YXJ0LnRlc3QobGluZXNbaV0pKSB7XG4gICAgICAgICAgICBjdXJyZW50TGluZXMucHVzaChsaW5lc1tpXSk7XG4gICAgICAgICAgICBpbkJsb2NrcXVvdGUgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoIWluQmxvY2txdW90ZSkge1xuICAgICAgICAgICAgY3VycmVudExpbmVzLnB1c2gobGluZXNbaV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGluZXMgPSBsaW5lcy5zbGljZShpKTtcblxuICAgICAgICBjb25zdCBjdXJyZW50UmF3ID0gY3VycmVudExpbmVzLmpvaW4oJ1xcbicpO1xuICAgICAgICBjb25zdCBjdXJyZW50VGV4dCA9IGN1cnJlbnRSYXdcbiAgICAgICAgICAvLyBwcmVjZWRlIHNldGV4dCBjb250aW51YXRpb24gd2l0aCA0IHNwYWNlcyBzbyBpdCBpc24ndCBhIHNldGV4dFxuICAgICAgICAgIC5yZXBsYWNlKHRoaXMucnVsZXMub3RoZXIuYmxvY2txdW90ZVNldGV4dFJlcGxhY2UsICdcXG4gICAgJDEnKVxuICAgICAgICAgIC5yZXBsYWNlKHRoaXMucnVsZXMub3RoZXIuYmxvY2txdW90ZVNldGV4dFJlcGxhY2UyLCAnJyk7XG4gICAgICAgIHJhdyA9IHJhdyA/IGAke3Jhd31cXG4ke2N1cnJlbnRSYXd9YCA6IGN1cnJlbnRSYXc7XG4gICAgICAgIHRleHQgPSB0ZXh0ID8gYCR7dGV4dH1cXG4ke2N1cnJlbnRUZXh0fWAgOiBjdXJyZW50VGV4dDtcblxuICAgICAgICAvLyBwYXJzZSBibG9ja3F1b3RlIGxpbmVzIGFzIHRvcCBsZXZlbCB0b2tlbnNcbiAgICAgICAgLy8gbWVyZ2UgcGFyYWdyYXBocyBpZiB0aGlzIGlzIGEgY29udGludWF0aW9uXG4gICAgICAgIGNvbnN0IHRvcCA9IHRoaXMubGV4ZXIuc3RhdGUudG9wO1xuICAgICAgICB0aGlzLmxleGVyLnN0YXRlLnRvcCA9IHRydWU7XG4gICAgICAgIHRoaXMubGV4ZXIuYmxvY2tUb2tlbnMoY3VycmVudFRleHQsIHRva2VucywgdHJ1ZSk7XG4gICAgICAgIHRoaXMubGV4ZXIuc3RhdGUudG9wID0gdG9wO1xuXG4gICAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIGNvbnRpbnVhdGlvbiB0aGVuIHdlIGFyZSBkb25lXG4gICAgICAgIGlmIChsaW5lcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGxhc3RUb2tlbiA9IHRva2Vucy5hdCgtMSk7XG5cbiAgICAgICAgaWYgKGxhc3RUb2tlbj8udHlwZSA9PT0gJ2NvZGUnKSB7XG4gICAgICAgICAgLy8gYmxvY2txdW90ZSBjb250aW51YXRpb24gY2Fubm90IGJlIHByZWNlZGVkIGJ5IGEgY29kZSBibG9ja1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2UgaWYgKGxhc3RUb2tlbj8udHlwZSA9PT0gJ2Jsb2NrcXVvdGUnKSB7XG4gICAgICAgICAgLy8gaW5jbHVkZSBjb250aW51YXRpb24gaW4gbmVzdGVkIGJsb2NrcXVvdGVcbiAgICAgICAgICBjb25zdCBvbGRUb2tlbiA9IGxhc3RUb2tlbiBhcyBUb2tlbnMuQmxvY2txdW90ZTtcbiAgICAgICAgICBjb25zdCBuZXdUZXh0ID0gb2xkVG9rZW4ucmF3ICsgJ1xcbicgKyBsaW5lcy5qb2luKCdcXG4nKTtcbiAgICAgICAgICBjb25zdCBuZXdUb2tlbiA9IHRoaXMuYmxvY2txdW90ZShuZXdUZXh0KSE7XG4gICAgICAgICAgdG9rZW5zW3Rva2Vucy5sZW5ndGggLSAxXSA9IG5ld1Rva2VuO1xuXG4gICAgICAgICAgcmF3ID0gcmF3LnN1YnN0cmluZygwLCByYXcubGVuZ3RoIC0gb2xkVG9rZW4ucmF3Lmxlbmd0aCkgKyBuZXdUb2tlbi5yYXc7XG4gICAgICAgICAgdGV4dCA9IHRleHQuc3Vic3RyaW5nKDAsIHRleHQubGVuZ3RoIC0gb2xkVG9rZW4udGV4dC5sZW5ndGgpICsgbmV3VG9rZW4udGV4dDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIGlmIChsYXN0VG9rZW4/LnR5cGUgPT09ICdsaXN0Jykge1xuICAgICAgICAgIC8vIGluY2x1ZGUgY29udGludWF0aW9uIGluIG5lc3RlZCBsaXN0XG4gICAgICAgICAgY29uc3Qgb2xkVG9rZW4gPSBsYXN0VG9rZW4gYXMgVG9rZW5zLkxpc3Q7XG4gICAgICAgICAgY29uc3QgbmV3VGV4dCA9IG9sZFRva2VuLnJhdyArICdcXG4nICsgbGluZXMuam9pbignXFxuJyk7XG4gICAgICAgICAgY29uc3QgbmV3VG9rZW4gPSB0aGlzLmxpc3QobmV3VGV4dCkhO1xuICAgICAgICAgIHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV0gPSBuZXdUb2tlbjtcblxuICAgICAgICAgIHJhdyA9IHJhdy5zdWJzdHJpbmcoMCwgcmF3Lmxlbmd0aCAtIGxhc3RUb2tlbi5yYXcubGVuZ3RoKSArIG5ld1Rva2VuLnJhdztcbiAgICAgICAgICB0ZXh0ID0gdGV4dC5zdWJzdHJpbmcoMCwgdGV4dC5sZW5ndGggLSBvbGRUb2tlbi5yYXcubGVuZ3RoKSArIG5ld1Rva2VuLnJhdztcbiAgICAgICAgICBsaW5lcyA9IG5ld1RleHQuc3Vic3RyaW5nKHRva2Vucy5hdCgtMSkhLnJhdy5sZW5ndGgpLnNwbGl0KCdcXG4nKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnYmxvY2txdW90ZScsXG4gICAgICAgIHJhdyxcbiAgICAgICAgdG9rZW5zLFxuICAgICAgICB0ZXh0LFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBsaXN0KHNyYzogc3RyaW5nKTogVG9rZW5zLkxpc3QgfCB1bmRlZmluZWQge1xuICAgIGxldCBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLmxpc3QuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIGxldCBidWxsID0gY2FwWzFdLnRyaW0oKTtcbiAgICAgIGNvbnN0IGlzb3JkZXJlZCA9IGJ1bGwubGVuZ3RoID4gMTtcblxuICAgICAgY29uc3QgbGlzdDogVG9rZW5zLkxpc3QgPSB7XG4gICAgICAgIHR5cGU6ICdsaXN0JyxcbiAgICAgICAgcmF3OiAnJyxcbiAgICAgICAgb3JkZXJlZDogaXNvcmRlcmVkLFxuICAgICAgICBzdGFydDogaXNvcmRlcmVkID8gK2J1bGwuc2xpY2UoMCwgLTEpIDogJycsXG4gICAgICAgIGxvb3NlOiBmYWxzZSxcbiAgICAgICAgaXRlbXM6IFtdLFxuICAgICAgfTtcblxuICAgICAgYnVsbCA9IGlzb3JkZXJlZCA/IGBcXFxcZHsxLDl9XFxcXCR7YnVsbC5zbGljZSgtMSl9YCA6IGBcXFxcJHtidWxsfWA7XG5cbiAgICAgIGlmICh0aGlzLm9wdGlvbnMucGVkYW50aWMpIHtcbiAgICAgICAgYnVsbCA9IGlzb3JkZXJlZCA/IGJ1bGwgOiAnWyorLV0nO1xuICAgICAgfVxuXG4gICAgICAvLyBHZXQgbmV4dCBsaXN0IGl0ZW1cbiAgICAgIGNvbnN0IGl0ZW1SZWdleCA9IHRoaXMucnVsZXMub3RoZXIubGlzdEl0ZW1SZWdleChidWxsKTtcbiAgICAgIGxldCBlbmRzV2l0aEJsYW5rTGluZSA9IGZhbHNlO1xuICAgICAgLy8gQ2hlY2sgaWYgY3VycmVudCBidWxsZXQgcG9pbnQgY2FuIHN0YXJ0IGEgbmV3IExpc3QgSXRlbVxuICAgICAgd2hpbGUgKHNyYykge1xuICAgICAgICBsZXQgZW5kRWFybHkgPSBmYWxzZTtcbiAgICAgICAgbGV0IHJhdyA9ICcnO1xuICAgICAgICBsZXQgaXRlbUNvbnRlbnRzID0gJyc7XG4gICAgICAgIGlmICghKGNhcCA9IGl0ZW1SZWdleC5leGVjKHNyYykpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5ydWxlcy5ibG9jay5oci50ZXN0KHNyYykpIHsgLy8gRW5kIGxpc3QgaWYgYnVsbGV0IHdhcyBhY3R1YWxseSBIUiAocG9zc2libHkgbW92ZSBpbnRvIGl0ZW1SZWdleD8pXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICByYXcgPSBjYXBbMF07XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcocmF3Lmxlbmd0aCk7XG5cbiAgICAgICAgbGV0IGxpbmUgPSBleHBhbmRUYWJzKGNhcFsyXS5zcGxpdCgnXFxuJywgMSlbMF0sIGNhcFsxXS5sZW5ndGgpO1xuICAgICAgICBsZXQgbmV4dExpbmUgPSBzcmMuc3BsaXQoJ1xcbicsIDEpWzBdO1xuICAgICAgICBsZXQgYmxhbmtMaW5lID0gIWxpbmUudHJpbSgpO1xuXG4gICAgICAgIGxldCBpbmRlbnQgPSAwO1xuICAgICAgICBpZiAodGhpcy5vcHRpb25zLnBlZGFudGljKSB7XG4gICAgICAgICAgaW5kZW50ID0gMjtcbiAgICAgICAgICBpdGVtQ29udGVudHMgPSBsaW5lLnRyaW1TdGFydCgpO1xuICAgICAgICB9IGVsc2UgaWYgKGJsYW5rTGluZSkge1xuICAgICAgICAgIGluZGVudCA9IGNhcFsxXS5sZW5ndGggKyAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGluZGVudCA9IGxpbmUuc2VhcmNoKHRoaXMucnVsZXMub3RoZXIubm9uU3BhY2VDaGFyKTsgLy8gRmluZCBmaXJzdCBub24tc3BhY2UgY2hhclxuICAgICAgICAgIGluZGVudCA9IGluZGVudCA+IDQgPyAxIDogaW5kZW50OyAvLyBUcmVhdCBpbmRlbnRlZCBjb2RlIGJsb2NrcyAoPiA0IHNwYWNlcykgYXMgaGF2aW5nIG9ubHkgMSBpbmRlbnRcbiAgICAgICAgICBpdGVtQ29udGVudHMgPSBsaW5lLnNsaWNlKGluZGVudCk7XG4gICAgICAgICAgaW5kZW50ICs9IGNhcFsxXS5sZW5ndGg7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYmxhbmtMaW5lICYmIHRoaXMucnVsZXMub3RoZXIuYmxhbmtMaW5lLnRlc3QobmV4dExpbmUpKSB7IC8vIEl0ZW1zIGJlZ2luIHdpdGggYXQgbW9zdCBvbmUgYmxhbmsgbGluZVxuICAgICAgICAgIHJhdyArPSBuZXh0TGluZSArICdcXG4nO1xuICAgICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcobmV4dExpbmUubGVuZ3RoICsgMSk7XG4gICAgICAgICAgZW5kRWFybHkgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFlbmRFYXJseSkge1xuICAgICAgICAgIGNvbnN0IG5leHRCdWxsZXRSZWdleCA9IHRoaXMucnVsZXMub3RoZXIubmV4dEJ1bGxldFJlZ2V4KGluZGVudCk7XG4gICAgICAgICAgY29uc3QgaHJSZWdleCA9IHRoaXMucnVsZXMub3RoZXIuaHJSZWdleChpbmRlbnQpO1xuICAgICAgICAgIGNvbnN0IGZlbmNlc0JlZ2luUmVnZXggPSB0aGlzLnJ1bGVzLm90aGVyLmZlbmNlc0JlZ2luUmVnZXgoaW5kZW50KTtcbiAgICAgICAgICBjb25zdCBoZWFkaW5nQmVnaW5SZWdleCA9IHRoaXMucnVsZXMub3RoZXIuaGVhZGluZ0JlZ2luUmVnZXgoaW5kZW50KTtcbiAgICAgICAgICBjb25zdCBodG1sQmVnaW5SZWdleCA9IHRoaXMucnVsZXMub3RoZXIuaHRtbEJlZ2luUmVnZXgoaW5kZW50KTtcbiAgICAgICAgICBjb25zdCBibG9ja3F1b3RlQmVnaW5SZWdleCA9IHRoaXMucnVsZXMub3RoZXIuYmxvY2txdW90ZUJlZ2luUmVnZXgoaW5kZW50KTtcblxuICAgICAgICAgIC8vIENoZWNrIGlmIGZvbGxvd2luZyBsaW5lcyBzaG91bGQgYmUgaW5jbHVkZWQgaW4gTGlzdCBJdGVtXG4gICAgICAgICAgd2hpbGUgKHNyYykge1xuICAgICAgICAgICAgY29uc3QgcmF3TGluZSA9IHNyYy5zcGxpdCgnXFxuJywgMSlbMF07XG4gICAgICAgICAgICBsZXQgbmV4dExpbmVXaXRob3V0VGFicztcbiAgICAgICAgICAgIG5leHRMaW5lID0gcmF3TGluZTtcblxuICAgICAgICAgICAgLy8gUmUtYWxpZ24gdG8gZm9sbG93IGNvbW1vbm1hcmsgbmVzdGluZyBydWxlc1xuICAgICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYykge1xuICAgICAgICAgICAgICBuZXh0TGluZSA9IG5leHRMaW5lLnJlcGxhY2UodGhpcy5ydWxlcy5vdGhlci5saXN0UmVwbGFjZU5lc3RpbmcsICcgICcpO1xuICAgICAgICAgICAgICBuZXh0TGluZVdpdGhvdXRUYWJzID0gbmV4dExpbmU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBuZXh0TGluZVdpdGhvdXRUYWJzID0gbmV4dExpbmUucmVwbGFjZSh0aGlzLnJ1bGVzLm90aGVyLnRhYkNoYXJHbG9iYWwsICcgICAgJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEVuZCBsaXN0IGl0ZW0gaWYgZm91bmQgY29kZSBmZW5jZXNcbiAgICAgICAgICAgIGlmIChmZW5jZXNCZWdpblJlZ2V4LnRlc3QobmV4dExpbmUpKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFbmQgbGlzdCBpdGVtIGlmIGZvdW5kIHN0YXJ0IG9mIG5ldyBoZWFkaW5nXG4gICAgICAgICAgICBpZiAoaGVhZGluZ0JlZ2luUmVnZXgudGVzdChuZXh0TGluZSkpIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEVuZCBsaXN0IGl0ZW0gaWYgZm91bmQgc3RhcnQgb2YgaHRtbCBibG9ja1xuICAgICAgICAgICAgaWYgKGh0bWxCZWdpblJlZ2V4LnRlc3QobmV4dExpbmUpKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBFbmQgbGlzdCBpdGVtIGlmIGZvdW5kIHN0YXJ0IG9mIGJsb2NrcXVvdGVcbiAgICAgICAgICAgIGlmIChibG9ja3F1b3RlQmVnaW5SZWdleC50ZXN0KG5leHRMaW5lKSkge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRW5kIGxpc3QgaXRlbSBpZiBmb3VuZCBzdGFydCBvZiBuZXcgYnVsbGV0XG4gICAgICAgICAgICBpZiAobmV4dEJ1bGxldFJlZ2V4LnRlc3QobmV4dExpbmUpKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBIb3Jpem9udGFsIHJ1bGUgZm91bmRcbiAgICAgICAgICAgIGlmIChoclJlZ2V4LnRlc3QobmV4dExpbmUpKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobmV4dExpbmVXaXRob3V0VGFicy5zZWFyY2godGhpcy5ydWxlcy5vdGhlci5ub25TcGFjZUNoYXIpID49IGluZGVudCB8fCAhbmV4dExpbmUudHJpbSgpKSB7IC8vIERlZGVudCBpZiBwb3NzaWJsZVxuICAgICAgICAgICAgICBpdGVtQ29udGVudHMgKz0gJ1xcbicgKyBuZXh0TGluZVdpdGhvdXRUYWJzLnNsaWNlKGluZGVudCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBub3QgZW5vdWdoIGluZGVudGF0aW9uXG4gICAgICAgICAgICAgIGlmIChibGFua0xpbmUpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIHBhcmFncmFwaCBjb250aW51YXRpb24gdW5sZXNzIGxhc3QgbGluZSB3YXMgYSBkaWZmZXJlbnQgYmxvY2sgbGV2ZWwgZWxlbWVudFxuICAgICAgICAgICAgICBpZiAobGluZS5yZXBsYWNlKHRoaXMucnVsZXMub3RoZXIudGFiQ2hhckdsb2JhbCwgJyAgICAnKS5zZWFyY2godGhpcy5ydWxlcy5vdGhlci5ub25TcGFjZUNoYXIpID49IDQpIHsgLy8gaW5kZW50ZWQgY29kZSBibG9ja1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChmZW5jZXNCZWdpblJlZ2V4LnRlc3QobGluZSkpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoaGVhZGluZ0JlZ2luUmVnZXgudGVzdChsaW5lKSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChoclJlZ2V4LnRlc3QobGluZSkpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGl0ZW1Db250ZW50cyArPSAnXFxuJyArIG5leHRMaW5lO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBibGFua0xpbmUgPSAhbmV4dExpbmUudHJpbSgpO1xuXG4gICAgICAgICAgICByYXcgKz0gcmF3TGluZSArICdcXG4nO1xuICAgICAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyhyYXdMaW5lLmxlbmd0aCArIDEpO1xuICAgICAgICAgICAgbGluZSA9IG5leHRMaW5lV2l0aG91dFRhYnMuc2xpY2UoaW5kZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWxpc3QubG9vc2UpIHtcbiAgICAgICAgICAvLyBJZiB0aGUgcHJldmlvdXMgaXRlbSBlbmRlZCB3aXRoIGEgYmxhbmsgbGluZSwgdGhlIGxpc3QgaXMgbG9vc2VcbiAgICAgICAgICBpZiAoZW5kc1dpdGhCbGFua0xpbmUpIHtcbiAgICAgICAgICAgIGxpc3QubG9vc2UgPSB0cnVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5ydWxlcy5vdGhlci5kb3VibGVCbGFua0xpbmUudGVzdChyYXcpKSB7XG4gICAgICAgICAgICBlbmRzV2l0aEJsYW5rTGluZSA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGlzdC5pdGVtcy5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAnbGlzdF9pdGVtJyxcbiAgICAgICAgICByYXcsXG4gICAgICAgICAgdGFzazogISF0aGlzLm9wdGlvbnMuZ2ZtICYmIHRoaXMucnVsZXMub3RoZXIubGlzdElzVGFzay50ZXN0KGl0ZW1Db250ZW50cyksXG4gICAgICAgICAgbG9vc2U6IGZhbHNlLFxuICAgICAgICAgIHRleHQ6IGl0ZW1Db250ZW50cyxcbiAgICAgICAgICB0b2tlbnM6IFtdLFxuICAgICAgICB9KTtcblxuICAgICAgICBsaXN0LnJhdyArPSByYXc7XG4gICAgICB9XG5cbiAgICAgIC8vIERvIG5vdCBjb25zdW1lIG5ld2xpbmVzIGF0IGVuZCBvZiBmaW5hbCBpdGVtLiBBbHRlcm5hdGl2ZWx5LCBtYWtlIGl0ZW1SZWdleCAqc3RhcnQqIHdpdGggYW55IG5ld2xpbmVzIHRvIHNpbXBsaWZ5L3NwZWVkIHVwIGVuZHNXaXRoQmxhbmtMaW5lIGxvZ2ljXG4gICAgICBjb25zdCBsYXN0SXRlbSA9IGxpc3QuaXRlbXMuYXQoLTEpO1xuICAgICAgaWYgKGxhc3RJdGVtKSB7XG4gICAgICAgIGxhc3RJdGVtLnJhdyA9IGxhc3RJdGVtLnJhdy50cmltRW5kKCk7XG4gICAgICAgIGxhc3RJdGVtLnRleHQgPSBsYXN0SXRlbS50ZXh0LnRyaW1FbmQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIG5vdCBhIGxpc3Qgc2luY2UgdGhlcmUgd2VyZSBubyBpdGVtc1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBsaXN0LnJhdyA9IGxpc3QucmF3LnRyaW1FbmQoKTtcblxuICAgICAgLy8gSXRlbSBjaGlsZCB0b2tlbnMgaGFuZGxlZCBoZXJlIGF0IGVuZCBiZWNhdXNlIHdlIG5lZWRlZCB0byBoYXZlIHRoZSBmaW5hbCBpdGVtIHRvIHRyaW0gaXQgZmlyc3RcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBsaXN0Lml0ZW1zKSB7XG4gICAgICAgIHRoaXMubGV4ZXIuc3RhdGUudG9wID0gZmFsc2U7XG4gICAgICAgIGl0ZW0udG9rZW5zID0gdGhpcy5sZXhlci5ibG9ja1Rva2VucyhpdGVtLnRleHQsIFtdKTtcbiAgICAgICAgY29uc3QgaXRlbVRva2VuID0gaXRlbS50b2tlbnNbMF07XG4gICAgICAgIGlmIChpdGVtLnRhc2sgJiYgKGl0ZW1Ub2tlbj8udHlwZSA9PT0gJ3RleHQnIHx8IGl0ZW1Ub2tlbj8udHlwZSA9PT0gJ3BhcmFncmFwaCcpKSB7XG4gICAgICAgICAgLy8gUmVtb3ZlIGNoZWNrYm94IG1hcmtkb3duIGZyb20gaXRlbSB0b2tlbnNcbiAgICAgICAgICBpdGVtLnRleHQgPSBpdGVtLnRleHQucmVwbGFjZSh0aGlzLnJ1bGVzLm90aGVyLmxpc3RSZXBsYWNlVGFzaywgJycpO1xuICAgICAgICAgIGl0ZW1Ub2tlbi5yYXcgPSBpdGVtVG9rZW4ucmF3LnJlcGxhY2UodGhpcy5ydWxlcy5vdGhlci5saXN0UmVwbGFjZVRhc2ssICcnKTtcbiAgICAgICAgICBpdGVtVG9rZW4udGV4dCA9IGl0ZW1Ub2tlbi50ZXh0LnJlcGxhY2UodGhpcy5ydWxlcy5vdGhlci5saXN0UmVwbGFjZVRhc2ssICcnKTtcbiAgICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5sZXhlci5pbmxpbmVRdWV1ZS5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgaWYgKHRoaXMucnVsZXMub3RoZXIubGlzdElzVGFzay50ZXN0KHRoaXMubGV4ZXIuaW5saW5lUXVldWVbaV0uc3JjKSkge1xuICAgICAgICAgICAgICB0aGlzLmxleGVyLmlubGluZVF1ZXVlW2ldLnNyYyA9IHRoaXMubGV4ZXIuaW5saW5lUXVldWVbaV0uc3JjLnJlcGxhY2UodGhpcy5ydWxlcy5vdGhlci5saXN0UmVwbGFjZVRhc2ssICcnKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgdGFza1JhdyA9IHRoaXMucnVsZXMub3RoZXIubGlzdFRhc2tDaGVja2JveC5leGVjKGl0ZW0ucmF3KTtcbiAgICAgICAgICBpZiAodGFza1Jhdykge1xuICAgICAgICAgICAgY29uc3QgY2hlY2tib3hUb2tlbjogVG9rZW5zLkNoZWNrYm94ID0ge1xuICAgICAgICAgICAgICB0eXBlOiAnY2hlY2tib3gnLFxuICAgICAgICAgICAgICByYXc6IHRhc2tSYXdbMF0gKyAnICcsXG4gICAgICAgICAgICAgIGNoZWNrZWQ6IHRhc2tSYXdbMF0gIT09ICdbIF0nLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGl0ZW0uY2hlY2tlZCA9IGNoZWNrYm94VG9rZW4uY2hlY2tlZDtcbiAgICAgICAgICAgIGlmIChsaXN0Lmxvb3NlKSB7XG4gICAgICAgICAgICAgIGlmIChpdGVtLnRva2Vuc1swXSAmJiBbJ3BhcmFncmFwaCcsICd0ZXh0J10uaW5jbHVkZXMoaXRlbS50b2tlbnNbMF0udHlwZSkgJiYgJ3Rva2VucycgaW4gaXRlbS50b2tlbnNbMF0gJiYgaXRlbS50b2tlbnNbMF0udG9rZW5zKSB7XG4gICAgICAgICAgICAgICAgaXRlbS50b2tlbnNbMF0ucmF3ID0gY2hlY2tib3hUb2tlbi5yYXcgKyBpdGVtLnRva2Vuc1swXS5yYXc7XG4gICAgICAgICAgICAgICAgaXRlbS50b2tlbnNbMF0udGV4dCA9IGNoZWNrYm94VG9rZW4ucmF3ICsgaXRlbS50b2tlbnNbMF0udGV4dDtcbiAgICAgICAgICAgICAgICBpdGVtLnRva2Vuc1swXS50b2tlbnMudW5zaGlmdChjaGVja2JveFRva2VuKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpdGVtLnRva2Vucy51bnNoaWZ0KHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdwYXJhZ3JhcGgnLFxuICAgICAgICAgICAgICAgICAgcmF3OiBjaGVja2JveFRva2VuLnJhdyxcbiAgICAgICAgICAgICAgICAgIHRleHQ6IGNoZWNrYm94VG9rZW4ucmF3LFxuICAgICAgICAgICAgICAgICAgdG9rZW5zOiBbY2hlY2tib3hUb2tlbl0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGl0ZW0udG9rZW5zLnVuc2hpZnQoY2hlY2tib3hUb2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGl0ZW0udGFzaykge1xuICAgICAgICAgIGl0ZW0udGFzayA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFsaXN0Lmxvb3NlKSB7XG4gICAgICAgICAgLy8gQ2hlY2sgaWYgbGlzdCBzaG91bGQgYmUgbG9vc2VcbiAgICAgICAgICBjb25zdCBzcGFjZXJzID0gaXRlbS50b2tlbnMuZmlsdGVyKHQgPT4gdC50eXBlID09PSAnc3BhY2UnKTtcbiAgICAgICAgICBjb25zdCBoYXNNdWx0aXBsZUxpbmVCcmVha3MgPSBzcGFjZXJzLmxlbmd0aCA+IDAgJiYgc3BhY2Vycy5zb21lKHQgPT4gdGhpcy5ydWxlcy5vdGhlci5hbnlMaW5lLnRlc3QodC5yYXcpKTtcblxuICAgICAgICAgIGxpc3QubG9vc2UgPSBoYXNNdWx0aXBsZUxpbmVCcmVha3M7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU2V0IGFsbCBpdGVtcyB0byBsb29zZSBpZiBsaXN0IGlzIGxvb3NlXG4gICAgICBpZiAobGlzdC5sb29zZSkge1xuICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgbGlzdC5pdGVtcykge1xuICAgICAgICAgIGl0ZW0ubG9vc2UgPSB0cnVlO1xuICAgICAgICAgIGZvciAoY29uc3QgdG9rZW4gb2YgaXRlbS50b2tlbnMpIHtcbiAgICAgICAgICAgIGlmICh0b2tlbi50eXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgICAgICAgdG9rZW4udHlwZSA9ICdwYXJhZ3JhcGgnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbGlzdDtcbiAgICB9XG4gIH1cblxuICBodG1sKHNyYzogc3RyaW5nKTogVG9rZW5zLkhUTUwgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNhcCA9IHRoaXMucnVsZXMuYmxvY2suaHRtbC5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgY29uc3QgcmF3ID0gdHJpbVRyYWlsaW5nQmxhbmtMaW5lcyhjYXBbMF0pO1xuICAgICAgY29uc3QgdG9rZW46IFRva2Vucy5IVE1MID0ge1xuICAgICAgICB0eXBlOiAnaHRtbCcsXG4gICAgICAgIGJsb2NrOiB0cnVlLFxuICAgICAgICByYXcsXG4gICAgICAgIHByZTogY2FwWzFdID09PSAncHJlJyB8fCBjYXBbMV0gPT09ICdzY3JpcHQnIHx8IGNhcFsxXSA9PT0gJ3N0eWxlJyxcbiAgICAgICAgdGV4dDogcmF3LFxuICAgICAgfTtcbiAgICAgIHJldHVybiB0b2tlbjtcbiAgICB9XG4gIH1cblxuICBkZWYoc3JjOiBzdHJpbmcpOiBUb2tlbnMuRGVmIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLmRlZi5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgY29uc3QgdGFnID0gY2FwWzFdLnRvTG93ZXJDYXNlKCkucmVwbGFjZSh0aGlzLnJ1bGVzLm90aGVyLm11bHRpcGxlU3BhY2VHbG9iYWwsICcgJyk7XG4gICAgICBjb25zdCBocmVmID0gY2FwWzJdID8gY2FwWzJdLnJlcGxhY2UodGhpcy5ydWxlcy5vdGhlci5ocmVmQnJhY2tldHMsICckMScpLnJlcGxhY2UodGhpcy5ydWxlcy5pbmxpbmUuYW55UHVuY3R1YXRpb24sICckMScpIDogJyc7XG4gICAgICBjb25zdCB0aXRsZSA9IGNhcFszXSA/IGNhcFszXS5zdWJzdHJpbmcoMSwgY2FwWzNdLmxlbmd0aCAtIDEpLnJlcGxhY2UodGhpcy5ydWxlcy5pbmxpbmUuYW55UHVuY3R1YXRpb24sICckMScpIDogY2FwWzNdO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2RlZicsXG4gICAgICAgIHRhZyxcbiAgICAgICAgcmF3OiBydHJpbShjYXBbMF0sICdcXG4nKSxcbiAgICAgICAgaHJlZixcbiAgICAgICAgdGl0bGUsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHRhYmxlKHNyYzogc3RyaW5nKTogVG9rZW5zLlRhYmxlIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjYXAgPSB0aGlzLnJ1bGVzLmJsb2NrLnRhYmxlLmV4ZWMoc3JjKTtcbiAgICBpZiAoIWNhcCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5ydWxlcy5vdGhlci50YWJsZURlbGltaXRlci50ZXN0KGNhcFsyXSkpIHtcbiAgICAgIC8vIGRlbGltaXRlciByb3cgbXVzdCBoYXZlIGEgcGlwZSAofCkgb3IgY29sb24gKDopIG90aGVyd2lzZSBpdCBpcyBhIHNldGV4dCBoZWFkaW5nXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaGVhZGVycyA9IHNwbGl0Q2VsbHMoY2FwWzFdKTtcbiAgICBjb25zdCBhbGlnbnMgPSBjYXBbMl0ucmVwbGFjZSh0aGlzLnJ1bGVzLm90aGVyLnRhYmxlQWxpZ25DaGFycywgJycpLnNwbGl0KCd8Jyk7XG4gICAgY29uc3Qgcm93cyA9IGNhcFszXT8udHJpbSgpID8gY2FwWzNdLnJlcGxhY2UodGhpcy5ydWxlcy5vdGhlci50YWJsZVJvd0JsYW5rTGluZSwgJycpLnNwbGl0KCdcXG4nKSA6IFtdO1xuXG4gICAgY29uc3QgaXRlbTogVG9rZW5zLlRhYmxlID0ge1xuICAgICAgdHlwZTogJ3RhYmxlJyxcbiAgICAgIHJhdzogcnRyaW0oY2FwWzBdLCAnXFxuJyksXG4gICAgICBoZWFkZXI6IFtdLFxuICAgICAgYWxpZ246IFtdLFxuICAgICAgcm93czogW10sXG4gICAgfTtcblxuICAgIGlmIChoZWFkZXJzLmxlbmd0aCAhPT0gYWxpZ25zLmxlbmd0aCkge1xuICAgICAgLy8gaGVhZGVyIGFuZCBhbGlnbiBjb2x1bW5zIG11c3QgYmUgZXF1YWwsIHJvd3MgY2FuIGJlIGRpZmZlcmVudC5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGFsaWduIG9mIGFsaWducykge1xuICAgICAgaWYgKHRoaXMucnVsZXMub3RoZXIudGFibGVBbGlnblJpZ2h0LnRlc3QoYWxpZ24pKSB7XG4gICAgICAgIGl0ZW0uYWxpZ24ucHVzaCgncmlnaHQnKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5ydWxlcy5vdGhlci50YWJsZUFsaWduQ2VudGVyLnRlc3QoYWxpZ24pKSB7XG4gICAgICAgIGl0ZW0uYWxpZ24ucHVzaCgnY2VudGVyJyk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMucnVsZXMub3RoZXIudGFibGVBbGlnbkxlZnQudGVzdChhbGlnbikpIHtcbiAgICAgICAgaXRlbS5hbGlnbi5wdXNoKCdsZWZ0Jyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpdGVtLmFsaWduLnB1c2gobnVsbCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWFkZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpdGVtLmhlYWRlci5wdXNoKHtcbiAgICAgICAgdGV4dDogaGVhZGVyc1tpXSxcbiAgICAgICAgdG9rZW5zOiB0aGlzLmxleGVyLmlubGluZShoZWFkZXJzW2ldKSxcbiAgICAgICAgaGVhZGVyOiB0cnVlLFxuICAgICAgICBhbGlnbjogaXRlbS5hbGlnbltpXSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgIGl0ZW0ucm93cy5wdXNoKHNwbGl0Q2VsbHMocm93LCBpdGVtLmhlYWRlci5sZW5ndGgpLm1hcCgoY2VsbCwgaSkgPT4ge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRleHQ6IGNlbGwsXG4gICAgICAgICAgdG9rZW5zOiB0aGlzLmxleGVyLmlubGluZShjZWxsKSxcbiAgICAgICAgICBoZWFkZXI6IGZhbHNlLFxuICAgICAgICAgIGFsaWduOiBpdGVtLmFsaWduW2ldLFxuICAgICAgICB9O1xuICAgICAgfSkpO1xuICAgIH1cblxuICAgIHJldHVybiBpdGVtO1xuICB9XG5cbiAgbGhlYWRpbmcoc3JjOiBzdHJpbmcpOiBUb2tlbnMuSGVhZGluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5saGVhZGluZy5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgY29uc3QgdGV4dCA9IGNhcFsxXS50cmltKCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnaGVhZGluZycsXG4gICAgICAgIHJhdzogcnRyaW0oY2FwWzBdLCAnXFxuJyksXG4gICAgICAgIGRlcHRoOiBjYXBbMl0uY2hhckF0KDApID09PSAnPScgPyAxIDogMixcbiAgICAgICAgdGV4dCxcbiAgICAgICAgdG9rZW5zOiB0aGlzLmxleGVyLmlubGluZSh0ZXh0KSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcGFyYWdyYXBoKHNyYzogc3RyaW5nKTogVG9rZW5zLlBhcmFncmFwaCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2FwID0gdGhpcy5ydWxlcy5ibG9jay5wYXJhZ3JhcGguZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIGNvbnN0IHRleHQgPSBjYXBbMV0uY2hhckF0KGNhcFsxXS5sZW5ndGggLSAxKSA9PT0gJ1xcbidcbiAgICAgICAgPyBjYXBbMV0uc2xpY2UoMCwgLTEpXG4gICAgICAgIDogY2FwWzFdO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3BhcmFncmFwaCcsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0ZXh0LFxuICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lKHRleHQpLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICB0ZXh0KHNyYzogc3RyaW5nKTogVG9rZW5zLlRleHQgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNhcCA9IHRoaXMucnVsZXMuYmxvY2sudGV4dC5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgdGV4dDogY2FwWzBdLFxuICAgICAgICB0b2tlbnM6IHRoaXMubGV4ZXIuaW5saW5lKGNhcFswXSksXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGVzY2FwZShzcmM6IHN0cmluZyk6IFRva2Vucy5Fc2NhcGUgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLmVzY2FwZS5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ2VzY2FwZScsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICB0ZXh0OiBjYXBbMV0sXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHRhZyhzcmM6IHN0cmluZyk6IFRva2Vucy5UYWcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLnRhZy5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgaWYgKCF0aGlzLmxleGVyLnN0YXRlLmluTGluayAmJiB0aGlzLnJ1bGVzLm90aGVyLnN0YXJ0QVRhZy50ZXN0KGNhcFswXSkpIHtcbiAgICAgICAgdGhpcy5sZXhlci5zdGF0ZS5pbkxpbmsgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmxleGVyLnN0YXRlLmluTGluayAmJiB0aGlzLnJ1bGVzLm90aGVyLmVuZEFUYWcudGVzdChjYXBbMF0pKSB7XG4gICAgICAgIHRoaXMubGV4ZXIuc3RhdGUuaW5MaW5rID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMubGV4ZXIuc3RhdGUuaW5SYXdCbG9jayAmJiB0aGlzLnJ1bGVzLm90aGVyLnN0YXJ0UHJlU2NyaXB0VGFnLnRlc3QoY2FwWzBdKSkge1xuICAgICAgICB0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2sgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2sgJiYgdGhpcy5ydWxlcy5vdGhlci5lbmRQcmVTY3JpcHRUYWcudGVzdChjYXBbMF0pKSB7XG4gICAgICAgIHRoaXMubGV4ZXIuc3RhdGUuaW5SYXdCbG9jayA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnaHRtbCcsXG4gICAgICAgIHJhdzogY2FwWzBdLFxuICAgICAgICBpbkxpbms6IHRoaXMubGV4ZXIuc3RhdGUuaW5MaW5rLFxuICAgICAgICBpblJhd0Jsb2NrOiB0aGlzLmxleGVyLnN0YXRlLmluUmF3QmxvY2ssXG4gICAgICAgIGJsb2NrOiBmYWxzZSxcbiAgICAgICAgdGV4dDogY2FwWzBdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBsaW5rKHNyYzogc3RyaW5nKTogVG9rZW5zLkxpbmsgfCBUb2tlbnMuSW1hZ2UgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLmxpbmsuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIGNvbnN0IHRyaW1tZWRVcmwgPSBjYXBbMl0udHJpbSgpO1xuICAgICAgaWYgKCF0aGlzLm9wdGlvbnMucGVkYW50aWMgJiYgdGhpcy5ydWxlcy5vdGhlci5zdGFydEFuZ2xlQnJhY2tldC50ZXN0KHRyaW1tZWRVcmwpKSB7XG4gICAgICAgIC8vIGNvbW1vbm1hcmsgcmVxdWlyZXMgbWF0Y2hpbmcgYW5nbGUgYnJhY2tldHNcbiAgICAgICAgaWYgKCEodGhpcy5ydWxlcy5vdGhlci5lbmRBbmdsZUJyYWNrZXQudGVzdCh0cmltbWVkVXJsKSkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBlbmRpbmcgYW5nbGUgYnJhY2tldCBjYW5ub3QgYmUgZXNjYXBlZFxuICAgICAgICBjb25zdCBydHJpbVNsYXNoID0gcnRyaW0odHJpbW1lZFVybC5zbGljZSgwLCAtMSksICdcXFxcJyk7XG4gICAgICAgIGlmICgodHJpbW1lZFVybC5sZW5ndGggLSBydHJpbVNsYXNoLmxlbmd0aCkgJSAyID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBmaW5kIGNsb3NpbmcgcGFyZW50aGVzaXNcbiAgICAgICAgY29uc3QgbGFzdFBhcmVuSW5kZXggPSBmaW5kQ2xvc2luZ0JyYWNrZXQoY2FwWzJdLCAnKCknKTtcbiAgICAgICAgaWYgKGxhc3RQYXJlbkluZGV4ID09PSAtMikge1xuICAgICAgICAgIC8vIG1vcmUgb3BlbiBwYXJlbnMgdGhhbiBjbG9zZWRcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGFzdFBhcmVuSW5kZXggPiAtMSkge1xuICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gY2FwWzBdLmluZGV4T2YoJyEnKSA9PT0gMCA/IDUgOiA0O1xuICAgICAgICAgIGNvbnN0IGxpbmtMZW4gPSBzdGFydCArIGNhcFsxXS5sZW5ndGggKyBsYXN0UGFyZW5JbmRleDtcbiAgICAgICAgICBjYXBbMl0gPSBjYXBbMl0uc3Vic3RyaW5nKDAsIGxhc3RQYXJlbkluZGV4KTtcbiAgICAgICAgICBjYXBbMF0gPSBjYXBbMF0uc3Vic3RyaW5nKDAsIGxpbmtMZW4pLnRyaW0oKTtcbiAgICAgICAgICBjYXBbM10gPSAnJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGV0IGhyZWYgPSBjYXBbMl07XG4gICAgICBsZXQgdGl0bGUgPSAnJztcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMucGVkYW50aWMpIHtcbiAgICAgICAgLy8gc3BsaXQgcGVkYW50aWMgaHJlZiBhbmQgdGl0bGVcbiAgICAgICAgY29uc3QgbGluayA9IHRoaXMucnVsZXMub3RoZXIucGVkYW50aWNIcmVmVGl0bGUuZXhlYyhocmVmKTtcblxuICAgICAgICBpZiAobGluaykge1xuICAgICAgICAgIGhyZWYgPSBsaW5rWzFdO1xuICAgICAgICAgIHRpdGxlID0gbGlua1szXTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGl0bGUgPSBjYXBbM10gPyBjYXBbM10uc2xpY2UoMSwgLTEpIDogJyc7XG4gICAgICB9XG5cbiAgICAgIGhyZWYgPSBocmVmLnRyaW0oKTtcbiAgICAgIGlmICh0aGlzLnJ1bGVzLm90aGVyLnN0YXJ0QW5nbGVCcmFja2V0LnRlc3QoaHJlZikpIHtcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYyAmJiAhKHRoaXMucnVsZXMub3RoZXIuZW5kQW5nbGVCcmFja2V0LnRlc3QodHJpbW1lZFVybCkpKSB7XG4gICAgICAgICAgLy8gcGVkYW50aWMgYWxsb3dzIHN0YXJ0aW5nIGFuZ2xlIGJyYWNrZXQgd2l0aG91dCBlbmRpbmcgYW5nbGUgYnJhY2tldFxuICAgICAgICAgIGhyZWYgPSBocmVmLnNsaWNlKDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhyZWYgPSBocmVmLnNsaWNlKDEsIC0xKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIG91dHB1dExpbmsoY2FwLCB7XG4gICAgICAgIGhyZWY6IGhyZWYgPyBocmVmLnJlcGxhY2UodGhpcy5ydWxlcy5pbmxpbmUuYW55UHVuY3R1YXRpb24sICckMScpIDogaHJlZixcbiAgICAgICAgdGl0bGU6IHRpdGxlID8gdGl0bGUucmVwbGFjZSh0aGlzLnJ1bGVzLmlubGluZS5hbnlQdW5jdHVhdGlvbiwgJyQxJykgOiB0aXRsZSxcbiAgICAgIH0sIGNhcFswXSwgdGhpcy5sZXhlciwgdGhpcy5ydWxlcyk7XG4gICAgfVxuICB9XG5cbiAgcmVmbGluayhzcmM6IHN0cmluZywgbGlua3M6IExpbmtzKTogVG9rZW5zLkxpbmsgfCBUb2tlbnMuSW1hZ2UgfCBUb2tlbnMuVGV4dCB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IGNhcDtcbiAgICBpZiAoKGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLnJlZmxpbmsuZXhlYyhzcmMpKVxuICAgICAgfHwgKGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLm5vbGluay5leGVjKHNyYykpKSB7XG4gICAgICBjb25zdCBsaW5rU3RyaW5nID0gKGNhcFsyXSB8fCBjYXBbMV0pLnJlcGxhY2UodGhpcy5ydWxlcy5vdGhlci5tdWx0aXBsZVNwYWNlR2xvYmFsLCAnICcpO1xuICAgICAgY29uc3QgbGluayA9IGxpbmtzW2xpbmtTdHJpbmcudG9Mb3dlckNhc2UoKV07XG4gICAgICBpZiAoIWxpbmspIHtcbiAgICAgICAgY29uc3QgdGV4dCA9IGNhcFswXS5jaGFyQXQoMCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICAgIHJhdzogdGV4dCxcbiAgICAgICAgICB0ZXh0LFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG91dHB1dExpbmsoY2FwLCBsaW5rLCBjYXBbMF0sIHRoaXMubGV4ZXIsIHRoaXMucnVsZXMpO1xuICAgIH1cbiAgfVxuXG4gIGVtU3Ryb25nKHNyYzogc3RyaW5nLCBtYXNrZWRTcmM6IHN0cmluZywgcHJldkNoYXIgPSAnJyk6IFRva2Vucy5FbSB8IFRva2Vucy5TdHJvbmcgfCB1bmRlZmluZWQge1xuICAgIGxldCBtYXRjaCA9IHRoaXMucnVsZXMuaW5saW5lLmVtU3Ryb25nTERlbGltLmV4ZWMoc3JjKTtcbiAgICBpZiAoIW1hdGNoKSByZXR1cm47XG4gICAgaWYgKCFtYXRjaFsxXSAmJiAhbWF0Y2hbMl0gJiYgIW1hdGNoWzNdICYmICFtYXRjaFs0XSkgcmV0dXJuO1xuXG4gICAgLy8gXyBjYW4ndCBiZSBiZXR3ZWVuIHR3byBhbHBoYW51bWVyaWNzLiBcXHB7TH1cXHB7Tn0gaW5jbHVkZXMgbm9uLWVuZ2xpc2ggYWxwaGFiZXQvbnVtYmVycyBhcyB3ZWxsXG4gICAgaWYgKG1hdGNoWzRdICYmIHByZXZDaGFyLm1hdGNoKHRoaXMucnVsZXMub3RoZXIudW5pY29kZUFscGhhTnVtZXJpYykpIHJldHVybjtcblxuICAgIGNvbnN0IG5leHRDaGFyID0gbWF0Y2hbMV0gfHwgbWF0Y2hbM10gfHwgJyc7XG5cbiAgICBpZiAoIW5leHRDaGFyIHx8ICFwcmV2Q2hhciB8fCB0aGlzLnJ1bGVzLmlubGluZS5wdW5jdHVhdGlvbi5leGVjKHByZXZDaGFyKSkge1xuICAgICAgLy8gdW5pY29kZSBSZWdleCBjb3VudHMgZW1vamkgYXMgMSBjaGFyOyBzcHJlYWQgaW50byBhcnJheSBmb3IgcHJvcGVyIGNvdW50ICh1c2VkIG11bHRpcGxlIHRpbWVzIGJlbG93KVxuICAgICAgY29uc3QgbExlbmd0aCA9IFsuLi5tYXRjaFswXV0ubGVuZ3RoIC0gMTtcbiAgICAgIGxldCByRGVsaW0sIHJMZW5ndGgsIGRlbGltVG90YWwgPSBsTGVuZ3RoLCBtaWREZWxpbVRvdGFsID0gMDtcblxuICAgICAgY29uc3QgZW5kUmVnID0gbWF0Y2hbMF1bMF0gPT09ICcqJyA/IHRoaXMucnVsZXMuaW5saW5lLmVtU3Ryb25nUkRlbGltQXN0IDogdGhpcy5ydWxlcy5pbmxpbmUuZW1TdHJvbmdSRGVsaW1VbmQ7XG4gICAgICBlbmRSZWcubGFzdEluZGV4ID0gMDtcblxuICAgICAgLy8gQ2xpcCBtYXNrZWRTcmMgdG8gc2FtZSBzZWN0aW9uIG9mIHN0cmluZyBhcyBzcmMgKG1vdmUgdG8gbGV4ZXI/KVxuICAgICAgbWFza2VkU3JjID0gbWFza2VkU3JjLnNsaWNlKC0xICogc3JjLmxlbmd0aCArIGxMZW5ndGgpO1xuXG4gICAgICB3aGlsZSAoKG1hdGNoID0gZW5kUmVnLmV4ZWMobWFza2VkU3JjKSkgIT09IG51bGwpIHtcbiAgICAgICAgckRlbGltID0gbWF0Y2hbMV0gfHwgbWF0Y2hbMl0gfHwgbWF0Y2hbM10gfHwgbWF0Y2hbNF0gfHwgbWF0Y2hbNV0gfHwgbWF0Y2hbNl07XG5cbiAgICAgICAgaWYgKCFyRGVsaW0pIGNvbnRpbnVlOyAvLyBza2lwIHNpbmdsZSAqIGluIF9fYWJjKmFiY19fXG5cbiAgICAgICAgckxlbmd0aCA9IFsuLi5yRGVsaW1dLmxlbmd0aDtcblxuICAgICAgICBpZiAobWF0Y2hbM10gfHwgbWF0Y2hbNF0pIHsgLy8gZm91bmQgYW5vdGhlciBMZWZ0IERlbGltXG4gICAgICAgICAgZGVsaW1Ub3RhbCArPSByTGVuZ3RoO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2UgaWYgKG1hdGNoWzVdIHx8IG1hdGNoWzZdKSB7IC8vIGVpdGhlciBMZWZ0IG9yIFJpZ2h0IERlbGltXG4gICAgICAgICAgaWYgKGxMZW5ndGggJSAzICYmICEoKGxMZW5ndGggKyByTGVuZ3RoKSAlIDMpKSB7XG4gICAgICAgICAgICBtaWREZWxpbVRvdGFsICs9IHJMZW5ndGg7XG4gICAgICAgICAgICBjb250aW51ZTsgLy8gQ29tbW9uTWFyayBFbXBoYXNpcyBSdWxlcyA5LTEwXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZGVsaW1Ub3RhbCAtPSByTGVuZ3RoO1xuXG4gICAgICAgIGlmIChkZWxpbVRvdGFsID4gMCkgY29udGludWU7IC8vIEhhdmVuJ3QgZm91bmQgZW5vdWdoIGNsb3NpbmcgZGVsaW1pdGVyc1xuXG4gICAgICAgIC8vIFJlbW92ZSBleHRyYSBjaGFyYWN0ZXJzLiAqYSoqKiAtPiAqYSpcbiAgICAgICAgckxlbmd0aCA9IE1hdGgubWluKHJMZW5ndGgsIHJMZW5ndGggKyBkZWxpbVRvdGFsICsgbWlkRGVsaW1Ub3RhbCk7XG4gICAgICAgIC8vIGNoYXIgbGVuZ3RoIGNhbiBiZSA+MSBmb3IgdW5pY29kZSBjaGFyYWN0ZXJzO1xuICAgICAgICBjb25zdCBsYXN0Q2hhckxlbmd0aCA9IFsuLi5tYXRjaFswXV1bMF0ubGVuZ3RoO1xuICAgICAgICBjb25zdCByYXcgPSBzcmMuc2xpY2UoMCwgbExlbmd0aCArIG1hdGNoLmluZGV4ICsgbGFzdENoYXJMZW5ndGggKyByTGVuZ3RoKTtcblxuICAgICAgICAvLyBDcmVhdGUgYGVtYCBpZiBzbWFsbGVzdCBkZWxpbWl0ZXIgaGFzIG9kZCBjaGFyIGNvdW50LiAqYSoqKlxuICAgICAgICBpZiAoTWF0aC5taW4obExlbmd0aCwgckxlbmd0aCkgJSAyKSB7XG4gICAgICAgICAgY29uc3QgdGV4dCA9IHJhdy5zbGljZSgxLCAtMSk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHR5cGU6ICdlbScsXG4gICAgICAgICAgICByYXcsXG4gICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgdG9rZW5zOiB0aGlzLmxleGVyLmlubGluZVRva2Vucyh0ZXh0KSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3JlYXRlICdzdHJvbmcnIGlmIHNtYWxsZXN0IGRlbGltaXRlciBoYXMgZXZlbiBjaGFyIGNvdW50LiAqKmEqKipcbiAgICAgICAgY29uc3QgdGV4dCA9IHJhdy5zbGljZSgyLCAtMik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogJ3N0cm9uZycsXG4gICAgICAgICAgcmF3LFxuICAgICAgICAgIHRleHQsXG4gICAgICAgICAgdG9rZW5zOiB0aGlzLmxleGVyLmlubGluZVRva2Vucyh0ZXh0KSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb2Rlc3BhbihzcmM6IHN0cmluZyk6IFRva2Vucy5Db2Rlc3BhbiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2FwID0gdGhpcy5ydWxlcy5pbmxpbmUuY29kZS5leGVjKHNyYyk7XG4gICAgaWYgKGNhcCkge1xuICAgICAgbGV0IHRleHQgPSBjYXBbMl0ucmVwbGFjZSh0aGlzLnJ1bGVzLm90aGVyLm5ld0xpbmVDaGFyR2xvYmFsLCAnICcpO1xuICAgICAgY29uc3QgaGFzTm9uU3BhY2VDaGFycyA9IHRoaXMucnVsZXMub3RoZXIubm9uU3BhY2VDaGFyLnRlc3QodGV4dCk7XG4gICAgICBjb25zdCBoYXNTcGFjZUNoYXJzT25Cb3RoRW5kcyA9IHRoaXMucnVsZXMub3RoZXIuc3RhcnRpbmdTcGFjZUNoYXIudGVzdCh0ZXh0KSAmJiB0aGlzLnJ1bGVzLm90aGVyLmVuZGluZ1NwYWNlQ2hhci50ZXN0KHRleHQpO1xuICAgICAgaWYgKGhhc05vblNwYWNlQ2hhcnMgJiYgaGFzU3BhY2VDaGFyc09uQm90aEVuZHMpIHtcbiAgICAgICAgdGV4dCA9IHRleHQuc3Vic3RyaW5nKDEsIHRleHQubGVuZ3RoIC0gMSk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnY29kZXNwYW4nLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgdGV4dCxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgYnIoc3JjOiBzdHJpbmcpOiBUb2tlbnMuQnIgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLmJyLmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiAnYnInLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgZGVsKHNyYzogc3RyaW5nLCBtYXNrZWRTcmM6IHN0cmluZywgcHJldkNoYXIgPSAnJyk6IFRva2Vucy5EZWwgfCB1bmRlZmluZWQge1xuICAgIGxldCBtYXRjaCA9IHRoaXMucnVsZXMuaW5saW5lLmRlbExEZWxpbS5leGVjKHNyYyk7XG4gICAgaWYgKCFtYXRjaCkgcmV0dXJuO1xuXG4gICAgY29uc3QgbmV4dENoYXIgPSBtYXRjaFsxXSB8fCAnJztcblxuICAgIGlmICghbmV4dENoYXIgfHwgIXByZXZDaGFyIHx8IHRoaXMucnVsZXMuaW5saW5lLnB1bmN0dWF0aW9uLmV4ZWMocHJldkNoYXIpKSB7XG4gICAgICAvLyB1bmljb2RlIFJlZ2V4IGNvdW50cyBlbW9qaSBhcyAxIGNoYXI7IHNwcmVhZCBpbnRvIGFycmF5IGZvciBwcm9wZXIgY291bnRcbiAgICAgIGNvbnN0IGxMZW5ndGggPSBbLi4ubWF0Y2hbMF1dLmxlbmd0aCAtIDE7XG4gICAgICBsZXQgckRlbGltLCByTGVuZ3RoLCBkZWxpbVRvdGFsID0gbExlbmd0aDtcblxuICAgICAgY29uc3QgZW5kUmVnID0gdGhpcy5ydWxlcy5pbmxpbmUuZGVsUkRlbGltO1xuICAgICAgZW5kUmVnLmxhc3RJbmRleCA9IDA7XG5cbiAgICAgIC8vIENsaXAgbWFza2VkU3JjIHRvIHNhbWUgc2VjdGlvbiBvZiBzdHJpbmcgYXMgc3JjXG4gICAgICBtYXNrZWRTcmMgPSBtYXNrZWRTcmMuc2xpY2UoLTEgKiBzcmMubGVuZ3RoICsgbExlbmd0aCk7XG5cbiAgICAgIHdoaWxlICgobWF0Y2ggPSBlbmRSZWcuZXhlYyhtYXNrZWRTcmMpKSAhPT0gbnVsbCkge1xuICAgICAgICByRGVsaW0gPSBtYXRjaFsxXSB8fCBtYXRjaFsyXSB8fCBtYXRjaFszXSB8fCBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCBtYXRjaFs2XTtcblxuICAgICAgICBpZiAoIXJEZWxpbSkgY29udGludWU7XG5cbiAgICAgICAgckxlbmd0aCA9IFsuLi5yRGVsaW1dLmxlbmd0aDtcblxuICAgICAgICBpZiAockxlbmd0aCAhPT0gbExlbmd0aCkgY29udGludWU7XG5cbiAgICAgICAgaWYgKG1hdGNoWzNdIHx8IG1hdGNoWzRdKSB7IC8vIGZvdW5kIGFub3RoZXIgTGVmdCBEZWxpbVxuICAgICAgICAgIGRlbGltVG90YWwgKz0gckxlbmd0aDtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGRlbGltVG90YWwgLT0gckxlbmd0aDtcblxuICAgICAgICBpZiAoZGVsaW1Ub3RhbCA+IDApIGNvbnRpbnVlOyAvLyBIYXZlbid0IGZvdW5kIGVub3VnaCBjbG9zaW5nIGRlbGltaXRlcnNcblxuICAgICAgICAvLyBSZW1vdmUgZXh0cmEgY2hhcmFjdGVyc1xuICAgICAgICByTGVuZ3RoID0gTWF0aC5taW4ockxlbmd0aCwgckxlbmd0aCArIGRlbGltVG90YWwpO1xuICAgICAgICAvLyBjaGFyIGxlbmd0aCBjYW4gYmUgPjEgZm9yIHVuaWNvZGUgY2hhcmFjdGVyc1xuICAgICAgICBjb25zdCBsYXN0Q2hhckxlbmd0aCA9IFsuLi5tYXRjaFswXV1bMF0ubGVuZ3RoO1xuICAgICAgICBjb25zdCByYXcgPSBzcmMuc2xpY2UoMCwgbExlbmd0aCArIG1hdGNoLmluZGV4ICsgbGFzdENoYXJMZW5ndGggKyByTGVuZ3RoKTtcblxuICAgICAgICAvLyBDcmVhdGUgZGVsIHRva2VuIC0gb25seSBzaW5nbGUgfiBvciBkb3VibGUgfn4gc3VwcG9ydGVkXG4gICAgICAgIGNvbnN0IHRleHQgPSByYXcuc2xpY2UobExlbmd0aCwgLWxMZW5ndGgpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6ICdkZWwnLFxuICAgICAgICAgIHJhdyxcbiAgICAgICAgICB0ZXh0LFxuICAgICAgICAgIHRva2VuczogdGhpcy5sZXhlci5pbmxpbmVUb2tlbnModGV4dCksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXV0b2xpbmsoc3JjOiBzdHJpbmcpOiBUb2tlbnMuTGluayB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2FwID0gdGhpcy5ydWxlcy5pbmxpbmUuYXV0b2xpbmsuZXhlYyhzcmMpO1xuICAgIGlmIChjYXApIHtcbiAgICAgIGxldCB0ZXh0LCBocmVmO1xuICAgICAgaWYgKGNhcFsyXSA9PT0gJ0AnKSB7XG4gICAgICAgIHRleHQgPSBjYXBbMV07XG4gICAgICAgIGhyZWYgPSAnbWFpbHRvOicgKyB0ZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGV4dCA9IGNhcFsxXTtcbiAgICAgICAgaHJlZiA9IHRleHQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdsaW5rJyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIHRleHQsXG4gICAgICAgIGhyZWYsXG4gICAgICAgIHRva2VuczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgIHJhdzogdGV4dCxcbiAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgdXJsKHNyYzogc3RyaW5nKTogVG9rZW5zLkxpbmsgfCB1bmRlZmluZWQge1xuICAgIGxldCBjYXA7XG4gICAgaWYgKGNhcCA9IHRoaXMucnVsZXMuaW5saW5lLnVybC5leGVjKHNyYykpIHtcbiAgICAgIGxldCB0ZXh0LCBocmVmO1xuICAgICAgaWYgKGNhcFsyXSA9PT0gJ0AnKSB7XG4gICAgICAgIHRleHQgPSBjYXBbMF07XG4gICAgICAgIGhyZWYgPSAnbWFpbHRvOicgKyB0ZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZG8gZXh0ZW5kZWQgYXV0b2xpbmsgcGF0aCB2YWxpZGF0aW9uXG4gICAgICAgIGxldCBwcmV2Q2FwWmVybztcbiAgICAgICAgZG8ge1xuICAgICAgICAgIHByZXZDYXBaZXJvID0gY2FwWzBdO1xuICAgICAgICAgIGNhcFswXSA9IHRoaXMucnVsZXMuaW5saW5lLl9iYWNrcGVkYWwuZXhlYyhjYXBbMF0pPy5bMF0gPz8gJyc7XG4gICAgICAgIH0gd2hpbGUgKHByZXZDYXBaZXJvICE9PSBjYXBbMF0pO1xuICAgICAgICB0ZXh0ID0gY2FwWzBdO1xuICAgICAgICBpZiAoY2FwWzFdID09PSAnd3d3LicpIHtcbiAgICAgICAgICBocmVmID0gJ2h0dHA6Ly8nICsgY2FwWzBdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGhyZWYgPSBjYXBbMF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdsaW5rJyxcbiAgICAgICAgcmF3OiBjYXBbMF0sXG4gICAgICAgIHRleHQsXG4gICAgICAgIGhyZWYsXG4gICAgICAgIHRva2VuczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgIHJhdzogdGV4dCxcbiAgICAgICAgICAgIHRleHQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgaW5saW5lVGV4dChzcmM6IHN0cmluZyk6IFRva2Vucy5UZXh0IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjYXAgPSB0aGlzLnJ1bGVzLmlubGluZS50ZXh0LmV4ZWMoc3JjKTtcbiAgICBpZiAoY2FwKSB7XG4gICAgICBjb25zdCBlc2NhcGVkID0gdGhpcy5sZXhlci5zdGF0ZS5pblJhd0Jsb2NrO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICByYXc6IGNhcFswXSxcbiAgICAgICAgdGV4dDogY2FwWzBdLFxuICAgICAgICBlc2NhcGVkLFxuICAgICAgfTtcbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBfVG9rZW5pemVyIH0gZnJvbSAnLi9Ub2tlbml6ZXIudHMnO1xuaW1wb3J0IHsgX2RlZmF1bHRzIH0gZnJvbSAnLi9kZWZhdWx0cy50cyc7XG5pbXBvcnQgeyBvdGhlciwgYmxvY2ssIGlubGluZSB9IGZyb20gJy4vcnVsZXMudHMnO1xuaW1wb3J0IHR5cGUgeyBUb2tlbiwgVG9rZW5zTGlzdCwgVG9rZW5zIH0gZnJvbSAnLi9Ub2tlbnMudHMnO1xuaW1wb3J0IHR5cGUgeyBNYXJrZWRPcHRpb25zIH0gZnJvbSAnLi9NYXJrZWRPcHRpb25zLnRzJztcblxuLyoqXG4gKiBCbG9jayBMZXhlclxuICovXG5leHBvcnQgY2xhc3MgX0xleGVyPFBhcnNlck91dHB1dCA9IHN0cmluZywgUmVuZGVyZXJPdXRwdXQgPSBzdHJpbmc+IHtcbiAgdG9rZW5zOiBUb2tlbnNMaXN0O1xuICBvcHRpb25zOiBNYXJrZWRPcHRpb25zPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+O1xuICBzdGF0ZToge1xuICAgIGluTGluazogYm9vbGVhbjtcbiAgICBpblJhd0Jsb2NrOiBib29sZWFuO1xuICAgIHRvcDogYm9vbGVhbjtcbiAgfTtcblxuICBwdWJsaWMgaW5saW5lUXVldWU6IHsgc3JjOiBzdHJpbmcsIHRva2VuczogVG9rZW5bXSB9W107XG5cbiAgcHJpdmF0ZSB0b2tlbml6ZXI6IF9Ub2tlbml6ZXI8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD47XG5cbiAgY29uc3RydWN0b3Iob3B0aW9ucz86IE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4pIHtcbiAgICAvLyBUb2tlbkxpc3QgY2Fubm90IGJlIGNyZWF0ZWQgaW4gb25lIGdvXG4gICAgdGhpcy50b2tlbnMgPSBbXSBhcyB1bmtub3duIGFzIFRva2Vuc0xpc3Q7XG4gICAgdGhpcy50b2tlbnMubGlua3MgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwgX2RlZmF1bHRzO1xuICAgIHRoaXMub3B0aW9ucy50b2tlbml6ZXIgPSB0aGlzLm9wdGlvbnMudG9rZW5pemVyIHx8IG5ldyBfVG9rZW5pemVyPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+KCk7XG4gICAgdGhpcy50b2tlbml6ZXIgPSB0aGlzLm9wdGlvbnMudG9rZW5pemVyO1xuICAgIHRoaXMudG9rZW5pemVyLm9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgdGhpcy50b2tlbml6ZXIubGV4ZXIgPSB0aGlzO1xuICAgIHRoaXMuaW5saW5lUXVldWUgPSBbXTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgaW5MaW5rOiBmYWxzZSxcbiAgICAgIGluUmF3QmxvY2s6IGZhbHNlLFxuICAgICAgdG9wOiB0cnVlLFxuICAgIH07XG5cbiAgICBjb25zdCBydWxlcyA9IHtcbiAgICAgIG90aGVyLFxuICAgICAgYmxvY2s6IGJsb2NrLm5vcm1hbCxcbiAgICAgIGlubGluZTogaW5saW5lLm5vcm1hbCxcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYykge1xuICAgICAgcnVsZXMuYmxvY2sgPSBibG9jay5wZWRhbnRpYztcbiAgICAgIHJ1bGVzLmlubGluZSA9IGlubGluZS5wZWRhbnRpYztcbiAgICB9IGVsc2UgaWYgKHRoaXMub3B0aW9ucy5nZm0pIHtcbiAgICAgIHJ1bGVzLmJsb2NrID0gYmxvY2suZ2ZtO1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5icmVha3MpIHtcbiAgICAgICAgcnVsZXMuaW5saW5lID0gaW5saW5lLmJyZWFrcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJ1bGVzLmlubGluZSA9IGlubGluZS5nZm07XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudG9rZW5pemVyLnJ1bGVzID0gcnVsZXM7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3NlIFJ1bGVzXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJ1bGVzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBibG9jayxcbiAgICAgIGlubGluZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRpYyBMZXggTWV0aG9kXG4gICAqL1xuICBzdGF0aWMgbGV4PFBhcnNlck91dHB1dCA9IHN0cmluZywgUmVuZGVyZXJPdXRwdXQgPSBzdHJpbmc+KHNyYzogc3RyaW5nLCBvcHRpb25zPzogTWFya2VkT3B0aW9uczxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0Pikge1xuICAgIGNvbnN0IGxleGVyID0gbmV3IF9MZXhlcjxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0PihvcHRpb25zKTtcbiAgICByZXR1cm4gbGV4ZXIubGV4KHNyYyk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGljIExleCBJbmxpbmUgTWV0aG9kXG4gICAqL1xuICBzdGF0aWMgbGV4SW5saW5lPFBhcnNlck91dHB1dCA9IHN0cmluZywgUmVuZGVyZXJPdXRwdXQgPSBzdHJpbmc+KHNyYzogc3RyaW5nLCBvcHRpb25zPzogTWFya2VkT3B0aW9uczxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0Pikge1xuICAgIGNvbnN0IGxleGVyID0gbmV3IF9MZXhlcjxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0PihvcHRpb25zKTtcbiAgICByZXR1cm4gbGV4ZXIuaW5saW5lVG9rZW5zKHNyYyk7XG4gIH1cblxuICAvKipcbiAgICogUHJlcHJvY2Vzc2luZ1xuICAgKi9cbiAgbGV4KHNyYzogc3RyaW5nKSB7XG4gICAgc3JjID0gc3JjLnJlcGxhY2Uob3RoZXIuY2FycmlhZ2VSZXR1cm4sICdcXG4nKTtcblxuICAgIHRoaXMuYmxvY2tUb2tlbnMoc3JjLCB0aGlzLnRva2Vucyk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuaW5saW5lUXVldWUubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5leHQgPSB0aGlzLmlubGluZVF1ZXVlW2ldO1xuICAgICAgdGhpcy5pbmxpbmVUb2tlbnMobmV4dC5zcmMsIG5leHQudG9rZW5zKTtcbiAgICB9XG4gICAgdGhpcy5pbmxpbmVRdWV1ZSA9IFtdO1xuXG4gICAgcmV0dXJuIHRoaXMudG9rZW5zO1xuICB9XG5cbiAgLyoqXG4gICAqIExleGluZ1xuICAgKi9cbiAgYmxvY2tUb2tlbnMoc3JjOiBzdHJpbmcsIHRva2Vucz86IFRva2VuW10sIGxhc3RQYXJhZ3JhcGhDbGlwcGVkPzogYm9vbGVhbik6IFRva2VuW107XG4gIGJsb2NrVG9rZW5zKHNyYzogc3RyaW5nLCB0b2tlbnM/OiBUb2tlbnNMaXN0LCBsYXN0UGFyYWdyYXBoQ2xpcHBlZD86IGJvb2xlYW4pOiBUb2tlbnNMaXN0O1xuICBibG9ja1Rva2VucyhzcmM6IHN0cmluZywgdG9rZW5zOiBUb2tlbltdID0gW10sIGxhc3RQYXJhZ3JhcGhDbGlwcGVkID0gZmFsc2UpIHtcbiAgICB0aGlzLnRva2VuaXplci5sZXhlciA9IHRoaXM7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5wZWRhbnRpYykge1xuICAgICAgc3JjID0gc3JjLnJlcGxhY2Uob3RoZXIudGFiQ2hhckdsb2JhbCwgJyAgICAnKS5yZXBsYWNlKG90aGVyLnNwYWNlTGluZSwgJycpO1xuICAgIH1cblxuICAgIGxldCBzcmNMZW5ndGggPSBJbmZpbml0eTtcbiAgICB3aGlsZSAoc3JjKSB7XG4gICAgICBpZiAoc3JjLmxlbmd0aCA8IHNyY0xlbmd0aCkge1xuICAgICAgICBzcmNMZW5ndGggPSBzcmMubGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5pbmZpbml0ZUxvb3BFcnJvcihzcmMuY2hhckNvZGVBdCgwKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBsZXQgdG9rZW46IFRva2Vucy5HZW5lcmljIHwgdW5kZWZpbmVkO1xuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnM/LmJsb2NrPy5zb21lKChleHRUb2tlbml6ZXIpID0+IHtcbiAgICAgICAgaWYgKHRva2VuID0gZXh0VG9rZW5pemVyLmNhbGwoeyBsZXhlcjogdGhpcyB9LCBzcmMsIHRva2VucykpIHtcbiAgICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gbmV3bGluZVxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuc3BhY2Uoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICBjb25zdCBsYXN0VG9rZW4gPSB0b2tlbnMuYXQoLTEpO1xuICAgICAgICBpZiAodG9rZW4ucmF3Lmxlbmd0aCA9PT0gMSAmJiBsYXN0VG9rZW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIGlmIHRoZXJlJ3MgYSBzaW5nbGUgXFxuIGFzIGEgc3BhY2VyLCBpdCdzIHRlcm1pbmF0aW5nIHRoZSBsYXN0IGxpbmUsXG4gICAgICAgICAgLy8gc28gbW92ZSBpdCB0aGVyZSBzbyB0aGF0IHdlIGRvbid0IGdldCB1bm5lY2Vzc2FyeSBwYXJhZ3JhcGggdGFnc1xuICAgICAgICAgIGxhc3RUb2tlbi5yYXcgKz0gJ1xcbic7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBjb2RlXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5jb2RlKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgY29uc3QgbGFzdFRva2VuID0gdG9rZW5zLmF0KC0xKTtcbiAgICAgICAgLy8gQW4gaW5kZW50ZWQgY29kZSBibG9jayBjYW5ub3QgaW50ZXJydXB0IGEgcGFyYWdyYXBoLlxuICAgICAgICBpZiAobGFzdFRva2VuPy50eXBlID09PSAncGFyYWdyYXBoJyB8fCBsYXN0VG9rZW4/LnR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgICAgIGxhc3RUb2tlbi5yYXcgKz0gKGxhc3RUb2tlbi5yYXcuZW5kc1dpdGgoJ1xcbicpID8gJycgOiAnXFxuJykgKyB0b2tlbi5yYXc7XG4gICAgICAgICAgbGFzdFRva2VuLnRleHQgKz0gJ1xcbicgKyB0b2tlbi50ZXh0O1xuICAgICAgICAgIHRoaXMuaW5saW5lUXVldWUuYXQoLTEpIS5zcmMgPSBsYXN0VG9rZW4udGV4dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGZlbmNlc1xuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuZmVuY2VzKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gaGVhZGluZ1xuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuaGVhZGluZyhzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGhyXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5ocihzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGJsb2NrcXVvdGVcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmJsb2NrcXVvdGUoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBsaXN0XG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5saXN0KHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gaHRtbFxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuaHRtbChzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGRlZlxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuZGVmKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgY29uc3QgbGFzdFRva2VuID0gdG9rZW5zLmF0KC0xKTtcbiAgICAgICAgaWYgKGxhc3RUb2tlbj8udHlwZSA9PT0gJ3BhcmFncmFwaCcgfHwgbGFzdFRva2VuPy50eXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgICBsYXN0VG9rZW4ucmF3ICs9IChsYXN0VG9rZW4ucmF3LmVuZHNXaXRoKCdcXG4nKSA/ICcnIDogJ1xcbicpICsgdG9rZW4ucmF3O1xuICAgICAgICAgIGxhc3RUb2tlbi50ZXh0ICs9ICdcXG4nICsgdG9rZW4ucmF3O1xuICAgICAgICAgIHRoaXMuaW5saW5lUXVldWUuYXQoLTEpIS5zcmMgPSBsYXN0VG9rZW4udGV4dDtcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy50b2tlbnMubGlua3NbdG9rZW4udGFnXSkge1xuICAgICAgICAgIHRoaXMudG9rZW5zLmxpbmtzW3Rva2VuLnRhZ10gPSB7XG4gICAgICAgICAgICBocmVmOiB0b2tlbi5ocmVmLFxuICAgICAgICAgICAgdGl0bGU6IHRva2VuLnRpdGxlLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyB0YWJsZSAoZ2ZtKVxuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIudGFibGUoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBsaGVhZGluZ1xuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIubGhlYWRpbmcoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyB0b3AtbGV2ZWwgcGFyYWdyYXBoXG4gICAgICAvLyBwcmV2ZW50IHBhcmFncmFwaCBjb25zdW1pbmcgZXh0ZW5zaW9ucyBieSBjbGlwcGluZyAnc3JjJyB0byBleHRlbnNpb24gc3RhcnRcbiAgICAgIGxldCBjdXRTcmMgPSBzcmM7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnM/LnN0YXJ0QmxvY2spIHtcbiAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSBJbmZpbml0eTtcbiAgICAgICAgY29uc3QgdGVtcFNyYyA9IHNyYy5zbGljZSgxKTtcbiAgICAgICAgbGV0IHRlbXBTdGFydDtcbiAgICAgICAgdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuc3RhcnRCbG9jay5mb3JFYWNoKChnZXRTdGFydEluZGV4KSA9PiB7XG4gICAgICAgICAgdGVtcFN0YXJ0ID0gZ2V0U3RhcnRJbmRleC5jYWxsKHsgbGV4ZXI6IHRoaXMgfSwgdGVtcFNyYyk7XG4gICAgICAgICAgaWYgKHR5cGVvZiB0ZW1wU3RhcnQgPT09ICdudW1iZXInICYmIHRlbXBTdGFydCA+PSAwKSB7XG4gICAgICAgICAgICBzdGFydEluZGV4ID0gTWF0aC5taW4oc3RhcnRJbmRleCwgdGVtcFN0YXJ0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoc3RhcnRJbmRleCA8IEluZmluaXR5ICYmIHN0YXJ0SW5kZXggPj0gMCkge1xuICAgICAgICAgIGN1dFNyYyA9IHNyYy5zdWJzdHJpbmcoMCwgc3RhcnRJbmRleCArIDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5zdGF0ZS50b3AgJiYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIucGFyYWdyYXBoKGN1dFNyYykpKSB7XG4gICAgICAgIGNvbnN0IGxhc3RUb2tlbiA9IHRva2Vucy5hdCgtMSk7XG4gICAgICAgIGlmIChsYXN0UGFyYWdyYXBoQ2xpcHBlZCAmJiBsYXN0VG9rZW4/LnR5cGUgPT09ICdwYXJhZ3JhcGgnKSB7XG4gICAgICAgICAgbGFzdFRva2VuLnJhdyArPSAobGFzdFRva2VuLnJhdy5lbmRzV2l0aCgnXFxuJykgPyAnJyA6ICdcXG4nKSArIHRva2VuLnJhdztcbiAgICAgICAgICBsYXN0VG9rZW4udGV4dCArPSAnXFxuJyArIHRva2VuLnRleHQ7XG4gICAgICAgICAgdGhpcy5pbmxpbmVRdWV1ZS5wb3AoKTtcbiAgICAgICAgICB0aGlzLmlubGluZVF1ZXVlLmF0KC0xKSEuc3JjID0gbGFzdFRva2VuLnRleHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RQYXJhZ3JhcGhDbGlwcGVkID0gY3V0U3JjLmxlbmd0aCAhPT0gc3JjLmxlbmd0aDtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIHRleHRcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLnRleHQoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICBjb25zdCBsYXN0VG9rZW4gPSB0b2tlbnMuYXQoLTEpO1xuICAgICAgICBpZiAobGFzdFRva2VuPy50eXBlID09PSAndGV4dCcpIHtcbiAgICAgICAgICBsYXN0VG9rZW4ucmF3ICs9IChsYXN0VG9rZW4ucmF3LmVuZHNXaXRoKCdcXG4nKSA/ICcnIDogJ1xcbicpICsgdG9rZW4ucmF3O1xuICAgICAgICAgIGxhc3RUb2tlbi50ZXh0ICs9ICdcXG4nICsgdG9rZW4udGV4dDtcbiAgICAgICAgICB0aGlzLmlubGluZVF1ZXVlLnBvcCgpO1xuICAgICAgICAgIHRoaXMuaW5saW5lUXVldWUuYXQoLTEpIS5zcmMgPSBsYXN0VG9rZW4udGV4dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChzcmMpIHtcbiAgICAgICAgdGhpcy5pbmZpbml0ZUxvb3BFcnJvcihzcmMuY2hhckNvZGVBdCgwKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc3RhdGUudG9wID0gdHJ1ZTtcbiAgICByZXR1cm4gdG9rZW5zO1xuICB9XG5cbiAgaW5saW5lKHNyYzogc3RyaW5nLCB0b2tlbnM6IFRva2VuW10gPSBbXSkge1xuICAgIHRoaXMuaW5saW5lUXVldWUucHVzaCh7IHNyYywgdG9rZW5zIH0pO1xuICAgIHJldHVybiB0b2tlbnM7XG4gIH1cblxuICAvKipcbiAgICogTGV4aW5nL0NvbXBpbGluZ1xuICAgKi9cbiAgaW5saW5lVG9rZW5zKHNyYzogc3RyaW5nLCB0b2tlbnM6IFRva2VuW10gPSBbXSk6IFRva2VuW10ge1xuICAgIHRoaXMudG9rZW5pemVyLmxleGVyID0gdGhpcztcbiAgICAvLyBTdHJpbmcgd2l0aCBsaW5rcyBtYXNrZWQgdG8gYXZvaWQgaW50ZXJmZXJlbmNlIHdpdGggZW0gYW5kIHN0cm9uZ1xuICAgIGxldCBtYXNrZWRTcmMgPSBzcmM7XG4gICAgbGV0IG1hdGNoOiBSZWdFeHBFeGVjQXJyYXkgfCBudWxsID0gbnVsbDtcblxuICAgIC8vIE1hc2sgb3V0IHJlZmxpbmtzXG4gICAgaWYgKHRoaXMudG9rZW5zLmxpbmtzKSB7XG4gICAgICBjb25zdCBsaW5rcyA9IE9iamVjdC5rZXlzKHRoaXMudG9rZW5zLmxpbmtzKTtcbiAgICAgIGlmIChsaW5rcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHdoaWxlICgobWF0Y2ggPSB0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUucmVmbGlua1NlYXJjaC5leGVjKG1hc2tlZFNyYykpICE9PSBudWxsKSB7XG4gICAgICAgICAgaWYgKGxpbmtzLmluY2x1ZGVzKG1hdGNoWzBdLnNsaWNlKG1hdGNoWzBdLmxhc3RJbmRleE9mKCdbJykgKyAxLCAtMSkpKSB7XG4gICAgICAgICAgICBtYXNrZWRTcmMgPSBtYXNrZWRTcmMuc2xpY2UoMCwgbWF0Y2guaW5kZXgpXG4gICAgICAgICAgICAgICsgJ1snICsgJ2EnLnJlcGVhdChtYXRjaFswXS5sZW5ndGggLSAyKSArICddJ1xuICAgICAgICAgICAgICArIG1hc2tlZFNyYy5zbGljZSh0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUucmVmbGlua1NlYXJjaC5sYXN0SW5kZXgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE1hc2sgb3V0IGVzY2FwZWQgY2hhcmFjdGVyc1xuICAgIHdoaWxlICgobWF0Y2ggPSB0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUuYW55UHVuY3R1YXRpb24uZXhlYyhtYXNrZWRTcmMpKSAhPT0gbnVsbCkge1xuICAgICAgbWFza2VkU3JjID0gbWFza2VkU3JjLnNsaWNlKDAsIG1hdGNoLmluZGV4KSArICcrKycgKyBtYXNrZWRTcmMuc2xpY2UodGhpcy50b2tlbml6ZXIucnVsZXMuaW5saW5lLmFueVB1bmN0dWF0aW9uLmxhc3RJbmRleCk7XG4gICAgfVxuXG4gICAgLy8gTWFzayBvdXQgb3RoZXIgYmxvY2tzXG4gICAgbGV0IG9mZnNldDtcbiAgICB3aGlsZSAoKG1hdGNoID0gdGhpcy50b2tlbml6ZXIucnVsZXMuaW5saW5lLmJsb2NrU2tpcC5leGVjKG1hc2tlZFNyYykpICE9PSBudWxsKSB7XG4gICAgICBvZmZzZXQgPSBtYXRjaFsyXSA/IG1hdGNoWzJdLmxlbmd0aCA6IDA7XG4gICAgICBtYXNrZWRTcmMgPSBtYXNrZWRTcmMuc2xpY2UoMCwgbWF0Y2guaW5kZXggKyBvZmZzZXQpICsgJ1snICsgJ2EnLnJlcGVhdChtYXRjaFswXS5sZW5ndGggLSBvZmZzZXQgLSAyKSArICddJyArIG1hc2tlZFNyYy5zbGljZSh0aGlzLnRva2VuaXplci5ydWxlcy5pbmxpbmUuYmxvY2tTa2lwLmxhc3RJbmRleCk7XG4gICAgfVxuXG4gICAgLy8gTWFzayBvdXQgYmxvY2tzIGZyb20gZXh0ZW5zaW9uc1xuICAgIG1hc2tlZFNyYyA9IHRoaXMub3B0aW9ucy5ob29rcz8uZW1TdHJvbmdNYXNrPy5jYWxsKHsgbGV4ZXI6IHRoaXMgfSwgbWFza2VkU3JjKSA/PyBtYXNrZWRTcmM7XG5cbiAgICBsZXQga2VlcFByZXZDaGFyID0gZmFsc2U7XG4gICAgbGV0IHByZXZDaGFyID0gJyc7XG4gICAgbGV0IHNyY0xlbmd0aCA9IEluZmluaXR5O1xuICAgIHdoaWxlIChzcmMpIHtcbiAgICAgIGlmIChzcmMubGVuZ3RoIDwgc3JjTGVuZ3RoKSB7XG4gICAgICAgIHNyY0xlbmd0aCA9IHNyYy5sZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmluZmluaXRlTG9vcEVycm9yKHNyYy5jaGFyQ29kZUF0KDApKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmICgha2VlcFByZXZDaGFyKSB7XG4gICAgICAgIHByZXZDaGFyID0gJyc7XG4gICAgICB9XG4gICAgICBrZWVwUHJldkNoYXIgPSBmYWxzZTtcblxuICAgICAgbGV0IHRva2VuOiBUb2tlbnMuR2VuZXJpYyB8IHVuZGVmaW5lZDtcblxuICAgICAgLy8gZXh0ZW5zaW9uc1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5leHRlbnNpb25zPy5pbmxpbmU/LnNvbWUoKGV4dFRva2VuaXplcikgPT4ge1xuICAgICAgICBpZiAodG9rZW4gPSBleHRUb2tlbml6ZXIuY2FsbCh7IGxleGVyOiB0aGlzIH0sIHNyYywgdG9rZW5zKSkge1xuICAgICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBlc2NhcGVcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmVzY2FwZShzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIHRhZ1xuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIudGFnKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gbGlua1xuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIubGluayhzcmMpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIHJlZmxpbmssIG5vbGlua1xuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIucmVmbGluayhzcmMsIHRoaXMudG9rZW5zLmxpbmtzKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICBjb25zdCBsYXN0VG9rZW4gPSB0b2tlbnMuYXQoLTEpO1xuICAgICAgICBpZiAodG9rZW4udHlwZSA9PT0gJ3RleHQnICYmIGxhc3RUb2tlbj8udHlwZSA9PT0gJ3RleHQnKSB7XG4gICAgICAgICAgbGFzdFRva2VuLnJhdyArPSB0b2tlbi5yYXc7XG4gICAgICAgICAgbGFzdFRva2VuLnRleHQgKz0gdG9rZW4udGV4dDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGVtICYgc3Ryb25nXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5lbVN0cm9uZyhzcmMsIG1hc2tlZFNyYywgcHJldkNoYXIpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGNvZGVcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmNvZGVzcGFuKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gYnJcbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmJyKHNyYykpIHtcbiAgICAgICAgc3JjID0gc3JjLnN1YnN0cmluZyh0b2tlbi5yYXcubGVuZ3RoKTtcbiAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gZGVsIChnZm0pXG4gICAgICBpZiAodG9rZW4gPSB0aGlzLnRva2VuaXplci5kZWwoc3JjLCBtYXNrZWRTcmMsIHByZXZDaGFyKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBhdXRvbGlua1xuICAgICAgaWYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIuYXV0b2xpbmsoc3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyB1cmwgKGdmbSlcbiAgICAgIGlmICghdGhpcy5zdGF0ZS5pbkxpbmsgJiYgKHRva2VuID0gdGhpcy50b2tlbml6ZXIudXJsKHNyYykpKSB7XG4gICAgICAgIHNyYyA9IHNyYy5zdWJzdHJpbmcodG9rZW4ucmF3Lmxlbmd0aCk7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIHRleHRcbiAgICAgIC8vIHByZXZlbnQgaW5saW5lVGV4dCBjb25zdW1pbmcgZXh0ZW5zaW9ucyBieSBjbGlwcGluZyAnc3JjJyB0byBleHRlbnNpb24gc3RhcnRcbiAgICAgIGxldCBjdXRTcmMgPSBzcmM7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnM/LnN0YXJ0SW5saW5lKSB7XG4gICAgICAgIGxldCBzdGFydEluZGV4ID0gSW5maW5pdHk7XG4gICAgICAgIGNvbnN0IHRlbXBTcmMgPSBzcmMuc2xpY2UoMSk7XG4gICAgICAgIGxldCB0ZW1wU3RhcnQ7XG4gICAgICAgIHRoaXMub3B0aW9ucy5leHRlbnNpb25zLnN0YXJ0SW5saW5lLmZvckVhY2goKGdldFN0YXJ0SW5kZXgpID0+IHtcbiAgICAgICAgICB0ZW1wU3RhcnQgPSBnZXRTdGFydEluZGV4LmNhbGwoeyBsZXhlcjogdGhpcyB9LCB0ZW1wU3JjKTtcbiAgICAgICAgICBpZiAodHlwZW9mIHRlbXBTdGFydCA9PT0gJ251bWJlcicgJiYgdGVtcFN0YXJ0ID49IDApIHtcbiAgICAgICAgICAgIHN0YXJ0SW5kZXggPSBNYXRoLm1pbihzdGFydEluZGV4LCB0ZW1wU3RhcnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChzdGFydEluZGV4IDwgSW5maW5pdHkgJiYgc3RhcnRJbmRleCA+PSAwKSB7XG4gICAgICAgICAgY3V0U3JjID0gc3JjLnN1YnN0cmluZygwLCBzdGFydEluZGV4ICsgMSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0b2tlbiA9IHRoaXMudG9rZW5pemVyLmlubGluZVRleHQoY3V0U3JjKSkge1xuICAgICAgICBzcmMgPSBzcmMuc3Vic3RyaW5nKHRva2VuLnJhdy5sZW5ndGgpO1xuICAgICAgICBpZiAodG9rZW4ucmF3LnNsaWNlKC0xKSAhPT0gJ18nKSB7IC8vIFRyYWNrIHByZXZDaGFyIGJlZm9yZSBzdHJpbmcgb2YgX19fXyBzdGFydGVkXG4gICAgICAgICAgcHJldkNoYXIgPSB0b2tlbi5yYXcuc2xpY2UoLTEpO1xuICAgICAgICB9XG4gICAgICAgIGtlZXBQcmV2Q2hhciA9IHRydWU7XG4gICAgICAgIGNvbnN0IGxhc3RUb2tlbiA9IHRva2Vucy5hdCgtMSk7XG4gICAgICAgIGlmIChsYXN0VG9rZW4/LnR5cGUgPT09ICd0ZXh0Jykge1xuICAgICAgICAgIGxhc3RUb2tlbi5yYXcgKz0gdG9rZW4ucmF3O1xuICAgICAgICAgIGxhc3RUb2tlbi50ZXh0ICs9IHRva2VuLnRleHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG9rZW5zLnB1c2godG9rZW4pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3JjKSB7XG4gICAgICAgIHRoaXMuaW5maW5pdGVMb29wRXJyb3Ioc3JjLmNoYXJDb2RlQXQoMCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdG9rZW5zO1xuICB9XG5cbiAgcHJpdmF0ZSBpbmZpbml0ZUxvb3BFcnJvcihieXRlOiBudW1iZXIpIHtcbiAgICBjb25zdCBlcnJNc2cgPSAnSW5maW5pdGUgbG9vcCBvbiBieXRlOiAnICsgYnl0ZTtcbiAgICBpZiAodGhpcy5vcHRpb25zLnNpbGVudCkge1xuICAgICAgY29uc29sZS5lcnJvcihlcnJNc2cpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyTXNnKTtcbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBfZGVmYXVsdHMgfSBmcm9tICcuL2RlZmF1bHRzLnRzJztcbmltcG9ydCB7XG4gIGNsZWFuVXJsLFxuICBlc2NhcGVIdG1sRW50aXRpZXMsXG59IGZyb20gJy4vaGVscGVycy50cyc7XG5pbXBvcnQgeyBvdGhlciB9IGZyb20gJy4vcnVsZXMudHMnO1xuaW1wb3J0IHR5cGUgeyBNYXJrZWRPcHRpb25zIH0gZnJvbSAnLi9NYXJrZWRPcHRpb25zLnRzJztcbmltcG9ydCB0eXBlIHsgVG9rZW5zIH0gZnJvbSAnLi9Ub2tlbnMudHMnO1xuaW1wb3J0IHR5cGUgeyBfUGFyc2VyIH0gZnJvbSAnLi9QYXJzZXIudHMnO1xuXG4vKipcbiAqIFJlbmRlcmVyXG4gKi9cbmV4cG9ydCBjbGFzcyBfUmVuZGVyZXI8UGFyc2VyT3V0cHV0ID0gc3RyaW5nLCBSZW5kZXJlck91dHB1dCA9IHN0cmluZz4ge1xuICBvcHRpb25zOiBNYXJrZWRPcHRpb25zPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+O1xuICBwYXJzZXIhOiBfUGFyc2VyPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+OyAvLyBzZXQgYnkgdGhlIHBhcnNlclxuICBjb25zdHJ1Y3RvcihvcHRpb25zPzogTWFya2VkT3B0aW9uczxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0Pikge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwgX2RlZmF1bHRzO1xuICB9XG5cbiAgc3BhY2UodG9rZW46IFRva2Vucy5TcGFjZSk6IFJlbmRlcmVyT3V0cHV0IHtcbiAgICByZXR1cm4gJycgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICBjb2RlKHsgdGV4dCwgbGFuZywgZXNjYXBlZCB9OiBUb2tlbnMuQ29kZSk6IFJlbmRlcmVyT3V0cHV0IHtcbiAgICBjb25zdCBsYW5nU3RyaW5nID0gKGxhbmcgfHwgJycpLm1hdGNoKG90aGVyLm5vdFNwYWNlU3RhcnQpPy5bMF07XG5cbiAgICBjb25zdCBjb2RlID0gdGV4dC5yZXBsYWNlKG90aGVyLmVuZGluZ05ld2xpbmUsICcnKSArICdcXG4nO1xuXG4gICAgaWYgKCFsYW5nU3RyaW5nKSB7XG4gICAgICByZXR1cm4gJzxwcmU+PGNvZGU+J1xuICAgICAgICArIChlc2NhcGVkID8gY29kZSA6IGVzY2FwZUh0bWxFbnRpdGllcyhjb2RlLCB0cnVlKSlcbiAgICAgICAgKyAnPC9jb2RlPjwvcHJlPlxcbicgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gICAgfVxuXG4gICAgcmV0dXJuICc8cHJlPjxjb2RlIGNsYXNzPVwibGFuZ3VhZ2UtJ1xuICAgICAgKyBlc2NhcGVIdG1sRW50aXRpZXMobGFuZ1N0cmluZylcbiAgICAgICsgJ1wiPidcbiAgICAgICsgKGVzY2FwZWQgPyBjb2RlIDogZXNjYXBlSHRtbEVudGl0aWVzKGNvZGUsIHRydWUpKVxuICAgICAgKyAnPC9jb2RlPjwvcHJlPlxcbicgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICBibG9ja3F1b3RlKHsgdG9rZW5zIH06IFRva2Vucy5CbG9ja3F1b3RlKTogUmVuZGVyZXJPdXRwdXQge1xuICAgIGNvbnN0IGJvZHkgPSB0aGlzLnBhcnNlci5wYXJzZSh0b2tlbnMpO1xuICAgIHJldHVybiBgPGJsb2NrcXVvdGU+XFxuJHtib2R5fTwvYmxvY2txdW90ZT5cXG5gIGFzIFJlbmRlcmVyT3V0cHV0O1xuICB9XG5cbiAgaHRtbCh7IHRleHQgfTogVG9rZW5zLkhUTUwgfCBUb2tlbnMuVGFnKTogUmVuZGVyZXJPdXRwdXQge1xuICAgIHJldHVybiB0ZXh0IGFzIFJlbmRlcmVyT3V0cHV0O1xuICB9XG5cbiAgZGVmKHRva2VuOiBUb2tlbnMuRGVmKTogUmVuZGVyZXJPdXRwdXQge1xuICAgIHJldHVybiAnJyBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGhlYWRpbmcoeyB0b2tlbnMsIGRlcHRoIH06IFRva2Vucy5IZWFkaW5nKTogUmVuZGVyZXJPdXRwdXQge1xuICAgIHJldHVybiBgPGgke2RlcHRofT4ke3RoaXMucGFyc2VyLnBhcnNlSW5saW5lKHRva2Vucyl9PC9oJHtkZXB0aH0+XFxuYCBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGhyKHRva2VuOiBUb2tlbnMuSHIpOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuICc8aHI+XFxuJyBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGxpc3QodG9rZW46IFRva2Vucy5MaXN0KTogUmVuZGVyZXJPdXRwdXQge1xuICAgIGNvbnN0IG9yZGVyZWQgPSB0b2tlbi5vcmRlcmVkO1xuICAgIGNvbnN0IHN0YXJ0ID0gdG9rZW4uc3RhcnQ7XG5cbiAgICBsZXQgYm9keSA9ICcnO1xuICAgIGZvciAobGV0IGogPSAwOyBqIDwgdG9rZW4uaXRlbXMubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSB0b2tlbi5pdGVtc1tqXTtcbiAgICAgIGJvZHkgKz0gdGhpcy5saXN0aXRlbShpdGVtKTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlID0gb3JkZXJlZCA/ICdvbCcgOiAndWwnO1xuICAgIGNvbnN0IHN0YXJ0QXR0ciA9IChvcmRlcmVkICYmIHN0YXJ0ICE9PSAxKSA/ICgnIHN0YXJ0PVwiJyArIHN0YXJ0ICsgJ1wiJykgOiAnJztcbiAgICByZXR1cm4gJzwnICsgdHlwZSArIHN0YXJ0QXR0ciArICc+XFxuJyArIGJvZHkgKyAnPC8nICsgdHlwZSArICc+XFxuJyBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGxpc3RpdGVtKGl0ZW06IFRva2Vucy5MaXN0SXRlbSk6IFJlbmRlcmVyT3V0cHV0IHtcbiAgICByZXR1cm4gYDxsaT4ke3RoaXMucGFyc2VyLnBhcnNlKGl0ZW0udG9rZW5zKX08L2xpPlxcbmAgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICBjaGVja2JveCh7IGNoZWNrZWQgfTogVG9rZW5zLkNoZWNrYm94KTogUmVuZGVyZXJPdXRwdXQge1xuICAgIHJldHVybiAnPGlucHV0ICdcbiAgICAgICsgKGNoZWNrZWQgPyAnY2hlY2tlZD1cIlwiICcgOiAnJylcbiAgICAgICsgJ2Rpc2FibGVkPVwiXCIgdHlwZT1cImNoZWNrYm94XCI+ICcgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICBwYXJhZ3JhcGgoeyB0b2tlbnMgfTogVG9rZW5zLlBhcmFncmFwaCk6IFJlbmRlcmVyT3V0cHV0IHtcbiAgICByZXR1cm4gYDxwPiR7dGhpcy5wYXJzZXIucGFyc2VJbmxpbmUodG9rZW5zKX08L3A+XFxuYCBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIHRhYmxlKHRva2VuOiBUb2tlbnMuVGFibGUpOiBSZW5kZXJlck91dHB1dCB7XG4gICAgbGV0IGhlYWRlciA9ICcnO1xuXG4gICAgLy8gaGVhZGVyXG4gICAgbGV0IGNlbGwgPSAnJztcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRva2VuLmhlYWRlci5sZW5ndGg7IGorKykge1xuICAgICAgY2VsbCArPSB0aGlzLnRhYmxlY2VsbCh0b2tlbi5oZWFkZXJbal0pO1xuICAgIH1cbiAgICBoZWFkZXIgKz0gdGhpcy50YWJsZXJvdyh7IHRleHQ6IGNlbGwgYXMgUGFyc2VyT3V0cHV0IH0pO1xuXG4gICAgbGV0IGJvZHkgPSAnJztcbiAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRva2VuLnJvd3MubGVuZ3RoOyBqKyspIHtcbiAgICAgIGNvbnN0IHJvdyA9IHRva2VuLnJvd3Nbal07XG5cbiAgICAgIGNlbGwgPSAnJztcbiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgcm93Lmxlbmd0aDsgaysrKSB7XG4gICAgICAgIGNlbGwgKz0gdGhpcy50YWJsZWNlbGwocm93W2tdKTtcbiAgICAgIH1cblxuICAgICAgYm9keSArPSB0aGlzLnRhYmxlcm93KHsgdGV4dDogY2VsbCBhcyBQYXJzZXJPdXRwdXQgfSk7XG4gICAgfVxuICAgIGlmIChib2R5KSBib2R5ID0gYDx0Ym9keT4ke2JvZHl9PC90Ym9keT5gO1xuXG4gICAgcmV0dXJuICc8dGFibGU+XFxuJ1xuICAgICAgKyAnPHRoZWFkPlxcbidcbiAgICAgICsgaGVhZGVyXG4gICAgICArICc8L3RoZWFkPlxcbidcbiAgICAgICsgYm9keVxuICAgICAgKyAnPC90YWJsZT5cXG4nIGFzIFJlbmRlcmVyT3V0cHV0O1xuICB9XG5cbiAgdGFibGVyb3coeyB0ZXh0IH06IFRva2Vucy5UYWJsZVJvdzxQYXJzZXJPdXRwdXQ+KTogUmVuZGVyZXJPdXRwdXQge1xuICAgIHJldHVybiBgPHRyPlxcbiR7dGV4dH08L3RyPlxcbmAgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICB0YWJsZWNlbGwodG9rZW46IFRva2Vucy5UYWJsZUNlbGwpOiBSZW5kZXJlck91dHB1dCB7XG4gICAgY29uc3QgY29udGVudCA9IHRoaXMucGFyc2VyLnBhcnNlSW5saW5lKHRva2VuLnRva2Vucyk7XG4gICAgY29uc3QgdHlwZSA9IHRva2VuLmhlYWRlciA/ICd0aCcgOiAndGQnO1xuICAgIGNvbnN0IHRhZyA9IHRva2VuLmFsaWduXG4gICAgICA/IGA8JHt0eXBlfSBhbGlnbj1cIiR7dG9rZW4uYWxpZ259XCI+YFxuICAgICAgOiBgPCR7dHlwZX0+YDtcbiAgICByZXR1cm4gdGFnICsgY29udGVudCArIGA8LyR7dHlwZX0+XFxuYCBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIC8qKlxuICAgKiBzcGFuIGxldmVsIHJlbmRlcmVyXG4gICAqL1xuICBzdHJvbmcoeyB0b2tlbnMgfTogVG9rZW5zLlN0cm9uZyk6IFJlbmRlcmVyT3V0cHV0IHtcbiAgICByZXR1cm4gYDxzdHJvbmc+JHt0aGlzLnBhcnNlci5wYXJzZUlubGluZSh0b2tlbnMpfTwvc3Ryb25nPmAgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICBlbSh7IHRva2VucyB9OiBUb2tlbnMuRW0pOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuIGA8ZW0+JHt0aGlzLnBhcnNlci5wYXJzZUlubGluZSh0b2tlbnMpfTwvZW0+YCBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGNvZGVzcGFuKHsgdGV4dCB9OiBUb2tlbnMuQ29kZXNwYW4pOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuIGA8Y29kZT4ke2VzY2FwZUh0bWxFbnRpdGllcyh0ZXh0LCB0cnVlKX08L2NvZGU+YCBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGJyKHRva2VuOiBUb2tlbnMuQnIpOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuICc8YnI+JyBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGRlbCh7IHRva2VucyB9OiBUb2tlbnMuRGVsKTogUmVuZGVyZXJPdXRwdXQge1xuICAgIHJldHVybiBgPGRlbD4ke3RoaXMucGFyc2VyLnBhcnNlSW5saW5lKHRva2Vucyl9PC9kZWw+YCBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGxpbmsoeyBocmVmLCB0aXRsZSwgdG9rZW5zIH06IFRva2Vucy5MaW5rKTogUmVuZGVyZXJPdXRwdXQge1xuICAgIGNvbnN0IHRleHQgPSB0aGlzLnBhcnNlci5wYXJzZUlubGluZSh0b2tlbnMpIGFzIHN0cmluZztcbiAgICBjb25zdCBjbGVhbkhyZWYgPSBjbGVhblVybChocmVmKTtcbiAgICBpZiAoY2xlYW5IcmVmID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gdGV4dCBhcyBSZW5kZXJlck91dHB1dDtcbiAgICB9XG4gICAgaHJlZiA9IGNsZWFuSHJlZjtcbiAgICBsZXQgb3V0ID0gJzxhIGhyZWY9XCInICsgaHJlZiArICdcIic7XG4gICAgaWYgKHRpdGxlKSB7XG4gICAgICBvdXQgKz0gJyB0aXRsZT1cIicgKyAoZXNjYXBlSHRtbEVudGl0aWVzKHRpdGxlKSkgKyAnXCInO1xuICAgIH1cbiAgICBvdXQgKz0gJz4nICsgdGV4dCArICc8L2E+JztcbiAgICByZXR1cm4gb3V0IGFzIFJlbmRlcmVyT3V0cHV0O1xuICB9XG5cbiAgaW1hZ2UoeyBocmVmLCB0aXRsZSwgdGV4dCwgdG9rZW5zIH06IFRva2Vucy5JbWFnZSk6IFJlbmRlcmVyT3V0cHV0IHtcbiAgICBpZiAodG9rZW5zKSB7XG4gICAgICB0ZXh0ID0gdGhpcy5wYXJzZXIucGFyc2VJbmxpbmUodG9rZW5zLCB0aGlzLnBhcnNlci50ZXh0UmVuZGVyZXIpIGFzIHN0cmluZztcbiAgICB9XG4gICAgY29uc3QgY2xlYW5IcmVmID0gY2xlYW5VcmwoaHJlZik7XG4gICAgaWYgKGNsZWFuSHJlZiA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGVzY2FwZUh0bWxFbnRpdGllcyh0ZXh0KSBhcyBSZW5kZXJlck91dHB1dDtcbiAgICB9XG4gICAgaHJlZiA9IGNsZWFuSHJlZjtcblxuICAgIGxldCBvdXQgPSBgPGltZyBzcmM9XCIke2hyZWZ9XCIgYWx0PVwiJHtlc2NhcGVIdG1sRW50aXRpZXModGV4dCl9XCJgO1xuICAgIGlmICh0aXRsZSkge1xuICAgICAgb3V0ICs9IGAgdGl0bGU9XCIke2VzY2FwZUh0bWxFbnRpdGllcyh0aXRsZSl9XCJgO1xuICAgIH1cbiAgICBvdXQgKz0gJz4nO1xuICAgIHJldHVybiBvdXQgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICB0ZXh0KHRva2VuOiBUb2tlbnMuVGV4dCB8IFRva2Vucy5Fc2NhcGUpOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuICd0b2tlbnMnIGluIHRva2VuICYmIHRva2VuLnRva2Vuc1xuICAgICAgPyB0aGlzLnBhcnNlci5wYXJzZUlubGluZSh0b2tlbi50b2tlbnMpIGFzIHVua25vd24gYXMgUmVuZGVyZXJPdXRwdXRcbiAgICAgIDogKCdlc2NhcGVkJyBpbiB0b2tlbiAmJiB0b2tlbi5lc2NhcGVkID8gdG9rZW4udGV4dCBhcyBSZW5kZXJlck91dHB1dCA6IGVzY2FwZUh0bWxFbnRpdGllcyh0b2tlbi50ZXh0KSBhcyBSZW5kZXJlck91dHB1dCk7XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IFRva2VucyB9IGZyb20gJy4vVG9rZW5zLnRzJztcblxuLyoqXG4gKiBUZXh0UmVuZGVyZXJcbiAqIHJldHVybnMgb25seSB0aGUgdGV4dHVhbCBwYXJ0IG9mIHRoZSB0b2tlblxuICovXG5leHBvcnQgY2xhc3MgX1RleHRSZW5kZXJlcjxSZW5kZXJlck91dHB1dCA9IHN0cmluZz4ge1xuICAvLyBubyBuZWVkIGZvciBibG9jayBsZXZlbCByZW5kZXJlcnNcbiAgc3Ryb25nKHsgdGV4dCB9OiBUb2tlbnMuU3Ryb25nKTogUmVuZGVyZXJPdXRwdXQge1xuICAgIHJldHVybiB0ZXh0IGFzIFJlbmRlcmVyT3V0cHV0O1xuICB9XG5cbiAgZW0oeyB0ZXh0IH06IFRva2Vucy5FbSk6IFJlbmRlcmVyT3V0cHV0IHtcbiAgICByZXR1cm4gdGV4dCBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGNvZGVzcGFuKHsgdGV4dCB9OiBUb2tlbnMuQ29kZXNwYW4pOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuIHRleHQgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICBkZWwoeyB0ZXh0IH06IFRva2Vucy5EZWwpOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuIHRleHQgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICBodG1sKHsgdGV4dCB9OiBUb2tlbnMuSFRNTCB8IFRva2Vucy5UYWcpOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuIHRleHQgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICB0ZXh0KHsgdGV4dCB9OiBUb2tlbnMuVGV4dCB8IFRva2Vucy5Fc2NhcGUgfCBUb2tlbnMuVGFnKTogUmVuZGVyZXJPdXRwdXQge1xuICAgIHJldHVybiB0ZXh0IGFzIFJlbmRlcmVyT3V0cHV0O1xuICB9XG5cbiAgbGluayh7IHRleHQgfTogVG9rZW5zLkxpbmspOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuICcnICsgdGV4dCBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGltYWdlKHsgdGV4dCB9OiBUb2tlbnMuSW1hZ2UpOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuICcnICsgdGV4dCBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxuXG4gIGJyKCk6IFJlbmRlcmVyT3V0cHV0IHtcbiAgICByZXR1cm4gJycgYXMgUmVuZGVyZXJPdXRwdXQ7XG4gIH1cblxuICBjaGVja2JveCh7IHJhdyB9OiBUb2tlbnMuQ2hlY2tib3gpOiBSZW5kZXJlck91dHB1dCB7XG4gICAgcmV0dXJuIHJhdyBhcyBSZW5kZXJlck91dHB1dDtcbiAgfVxufVxuIiwgImltcG9ydCB7IF9SZW5kZXJlciB9IGZyb20gJy4vUmVuZGVyZXIudHMnO1xuaW1wb3J0IHsgX1RleHRSZW5kZXJlciB9IGZyb20gJy4vVGV4dFJlbmRlcmVyLnRzJztcbmltcG9ydCB7IF9kZWZhdWx0cyB9IGZyb20gJy4vZGVmYXVsdHMudHMnO1xuaW1wb3J0IHR5cGUgeyBNYXJrZWRUb2tlbiwgVG9rZW4sIFRva2VucyB9IGZyb20gJy4vVG9rZW5zLnRzJztcbmltcG9ydCB0eXBlIHsgTWFya2VkT3B0aW9ucyB9IGZyb20gJy4vTWFya2VkT3B0aW9ucy50cyc7XG5cbi8qKlxuICogUGFyc2luZyAmIENvbXBpbGluZ1xuICovXG5leHBvcnQgY2xhc3MgX1BhcnNlcjxQYXJzZXJPdXRwdXQgPSBzdHJpbmcsIFJlbmRlcmVyT3V0cHV0ID0gc3RyaW5nPiB7XG4gIG9wdGlvbnM6IE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD47XG4gIHJlbmRlcmVyOiBfUmVuZGVyZXI8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD47XG4gIHRleHRSZW5kZXJlcjogX1RleHRSZW5kZXJlcjxSZW5kZXJlck91dHB1dD47XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM/OiBNYXJrZWRPcHRpb25zPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+KSB7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCBfZGVmYXVsdHM7XG4gICAgdGhpcy5vcHRpb25zLnJlbmRlcmVyID0gdGhpcy5vcHRpb25zLnJlbmRlcmVyIHx8IG5ldyBfUmVuZGVyZXI8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4oKTtcbiAgICB0aGlzLnJlbmRlcmVyID0gdGhpcy5vcHRpb25zLnJlbmRlcmVyO1xuICAgIHRoaXMucmVuZGVyZXIub3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICB0aGlzLnJlbmRlcmVyLnBhcnNlciA9IHRoaXM7XG4gICAgdGhpcy50ZXh0UmVuZGVyZXIgPSBuZXcgX1RleHRSZW5kZXJlcjxSZW5kZXJlck91dHB1dD4oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGF0aWMgUGFyc2UgTWV0aG9kXG4gICAqL1xuICBzdGF0aWMgcGFyc2U8UGFyc2VyT3V0cHV0ID0gc3RyaW5nLCBSZW5kZXJlck91dHB1dCA9IHN0cmluZz4odG9rZW5zOiBUb2tlbltdLCBvcHRpb25zPzogTWFya2VkT3B0aW9uczxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0Pikge1xuICAgIGNvbnN0IHBhcnNlciA9IG5ldyBfUGFyc2VyPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+KG9wdGlvbnMpO1xuICAgIHJldHVybiBwYXJzZXIucGFyc2UodG9rZW5zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGF0aWMgUGFyc2UgSW5saW5lIE1ldGhvZFxuICAgKi9cbiAgc3RhdGljIHBhcnNlSW5saW5lPFBhcnNlck91dHB1dCA9IHN0cmluZywgUmVuZGVyZXJPdXRwdXQgPSBzdHJpbmc+KHRva2VuczogVG9rZW5bXSwgb3B0aW9ucz86IE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4pIHtcbiAgICBjb25zdCBwYXJzZXIgPSBuZXcgX1BhcnNlcjxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0PihvcHRpb25zKTtcbiAgICByZXR1cm4gcGFyc2VyLnBhcnNlSW5saW5lKHRva2Vucyk7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgTG9vcFxuICAgKi9cbiAgcGFyc2UodG9rZW5zOiBUb2tlbltdKTogUGFyc2VyT3V0cHV0IHtcbiAgICB0aGlzLnJlbmRlcmVyLnBhcnNlciA9IHRoaXM7XG4gICAgbGV0IG91dCA9ICcnO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b2tlbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGFueVRva2VuID0gdG9rZW5zW2ldO1xuXG4gICAgICAvLyBSdW4gYW55IHJlbmRlcmVyIGV4dGVuc2lvbnNcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuZXh0ZW5zaW9ucz8ucmVuZGVyZXJzPy5bYW55VG9rZW4udHlwZV0pIHtcbiAgICAgICAgY29uc3QgZ2VuZXJpY1Rva2VuID0gYW55VG9rZW4gYXMgVG9rZW5zLkdlbmVyaWM7XG4gICAgICAgIGNvbnN0IHJldCA9IHRoaXMub3B0aW9ucy5leHRlbnNpb25zLnJlbmRlcmVyc1tnZW5lcmljVG9rZW4udHlwZV0uY2FsbCh7IHBhcnNlcjogdGhpcyB9LCBnZW5lcmljVG9rZW4pO1xuICAgICAgICBpZiAocmV0ICE9PSBmYWxzZSB8fCAhWydzcGFjZScsICdocicsICdoZWFkaW5nJywgJ2NvZGUnLCAndGFibGUnLCAnYmxvY2txdW90ZScsICdsaXN0JywgJ2h0bWwnLCAnZGVmJywgJ3BhcmFncmFwaCcsICd0ZXh0J10uaW5jbHVkZXMoZ2VuZXJpY1Rva2VuLnR5cGUpKSB7XG4gICAgICAgICAgb3V0ICs9IHJldCB8fCAnJztcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCB0b2tlbiA9IGFueVRva2VuIGFzIE1hcmtlZFRva2VuO1xuXG4gICAgICBzd2l0Y2ggKHRva2VuLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnc3BhY2UnOiB7XG4gICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuc3BhY2UodG9rZW4pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2hyJzoge1xuICAgICAgICAgIG91dCArPSB0aGlzLnJlbmRlcmVyLmhyKHRva2VuKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdoZWFkaW5nJzoge1xuICAgICAgICAgIG91dCArPSB0aGlzLnJlbmRlcmVyLmhlYWRpbmcodG9rZW4pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2NvZGUnOiB7XG4gICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuY29kZSh0b2tlbik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAndGFibGUnOiB7XG4gICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIudGFibGUodG9rZW4pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2Jsb2NrcXVvdGUnOiB7XG4gICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuYmxvY2txdW90ZSh0b2tlbik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnbGlzdCc6IHtcbiAgICAgICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci5saXN0KHRva2VuKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdjaGVja2JveCc6IHtcbiAgICAgICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci5jaGVja2JveCh0b2tlbik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnaHRtbCc6IHtcbiAgICAgICAgICBvdXQgKz0gdGhpcy5yZW5kZXJlci5odG1sKHRva2VuKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdkZWYnOiB7XG4gICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIuZGVmKHRva2VuKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdwYXJhZ3JhcGgnOiB7XG4gICAgICAgICAgb3V0ICs9IHRoaXMucmVuZGVyZXIucGFyYWdyYXBoKHRva2VuKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICd0ZXh0Jzoge1xuICAgICAgICAgIG91dCArPSB0aGlzLnJlbmRlcmVyLnRleHQodG9rZW4pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgIGNvbnN0IGVyck1zZyA9ICdUb2tlbiB3aXRoIFwiJyArIHRva2VuLnR5cGUgKyAnXCIgdHlwZSB3YXMgbm90IGZvdW5kLic7XG4gICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaWxlbnQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyTXNnKTtcbiAgICAgICAgICAgIHJldHVybiAnJyBhcyBQYXJzZXJPdXRwdXQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJNc2cpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXQgYXMgUGFyc2VyT3V0cHV0O1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIElubGluZSBUb2tlbnNcbiAgICovXG4gIHBhcnNlSW5saW5lKHRva2VuczogVG9rZW5bXSwgcmVuZGVyZXI6IF9SZW5kZXJlcjxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0PiB8IF9UZXh0UmVuZGVyZXI8UmVuZGVyZXJPdXRwdXQ+ID0gdGhpcy5yZW5kZXJlcik6IFBhcnNlck91dHB1dCB7XG4gICAgdGhpcy5yZW5kZXJlci5wYXJzZXIgPSB0aGlzO1xuICAgIGxldCBvdXQgPSAnJztcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdG9rZW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBhbnlUb2tlbiA9IHRva2Vuc1tpXTtcblxuICAgICAgLy8gUnVuIGFueSByZW5kZXJlciBleHRlbnNpb25zXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmV4dGVuc2lvbnM/LnJlbmRlcmVycz8uW2FueVRva2VuLnR5cGVdKSB7XG4gICAgICAgIGNvbnN0IHJldCA9IHRoaXMub3B0aW9ucy5leHRlbnNpb25zLnJlbmRlcmVyc1thbnlUb2tlbi50eXBlXS5jYWxsKHsgcGFyc2VyOiB0aGlzIH0sIGFueVRva2VuKTtcbiAgICAgICAgaWYgKHJldCAhPT0gZmFsc2UgfHwgIVsnZXNjYXBlJywgJ2h0bWwnLCAnbGluaycsICdpbWFnZScsICdzdHJvbmcnLCAnZW0nLCAnY29kZXNwYW4nLCAnYnInLCAnZGVsJywgJ3RleHQnXS5pbmNsdWRlcyhhbnlUb2tlbi50eXBlKSkge1xuICAgICAgICAgIG91dCArPSByZXQgfHwgJyc7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgdG9rZW4gPSBhbnlUb2tlbiBhcyBNYXJrZWRUb2tlbjtcblxuICAgICAgc3dpdGNoICh0b2tlbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ2VzY2FwZSc6IHtcbiAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIudGV4dCh0b2tlbik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnaHRtbCc6IHtcbiAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIuaHRtbCh0b2tlbik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnbGluayc6IHtcbiAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIubGluayh0b2tlbik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnaW1hZ2UnOiB7XG4gICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmltYWdlKHRva2VuKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdjaGVja2JveCc6IHtcbiAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIuY2hlY2tib3godG9rZW4pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ3N0cm9uZyc6IHtcbiAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIuc3Ryb25nKHRva2VuKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdlbSc6IHtcbiAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIuZW0odG9rZW4pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ2NvZGVzcGFuJzoge1xuICAgICAgICAgIG91dCArPSByZW5kZXJlci5jb2Rlc3Bhbih0b2tlbik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnYnInOiB7XG4gICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmJyKHRva2VuKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjYXNlICdkZWwnOiB7XG4gICAgICAgICAgb3V0ICs9IHJlbmRlcmVyLmRlbCh0b2tlbik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAndGV4dCc6IHtcbiAgICAgICAgICBvdXQgKz0gcmVuZGVyZXIudGV4dCh0b2tlbik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgIGNvbnN0IGVyck1zZyA9ICdUb2tlbiB3aXRoIFwiJyArIHRva2VuLnR5cGUgKyAnXCIgdHlwZSB3YXMgbm90IGZvdW5kLic7XG4gICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaWxlbnQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyTXNnKTtcbiAgICAgICAgICAgIHJldHVybiAnJyBhcyBQYXJzZXJPdXRwdXQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJNc2cpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb3V0IGFzIFBhcnNlck91dHB1dDtcbiAgfVxufVxuIiwgImltcG9ydCB7IF9kZWZhdWx0cyB9IGZyb20gJy4vZGVmYXVsdHMudHMnO1xuaW1wb3J0IHsgX0xleGVyIH0gZnJvbSAnLi9MZXhlci50cyc7XG5pbXBvcnQgeyBfUGFyc2VyIH0gZnJvbSAnLi9QYXJzZXIudHMnO1xuaW1wb3J0IHR5cGUgeyBNYXJrZWRPcHRpb25zIH0gZnJvbSAnLi9NYXJrZWRPcHRpb25zLnRzJztcbmltcG9ydCB0eXBlIHsgVG9rZW4sIFRva2Vuc0xpc3QgfSBmcm9tICcuL1Rva2Vucy50cyc7XG5cbmV4cG9ydCBjbGFzcyBfSG9va3M8UGFyc2VyT3V0cHV0ID0gc3RyaW5nLCBSZW5kZXJlck91dHB1dCA9IHN0cmluZz4ge1xuICBvcHRpb25zOiBNYXJrZWRPcHRpb25zPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+O1xuICBibG9jaz86IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3Iob3B0aW9ucz86IE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4pIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zIHx8IF9kZWZhdWx0cztcbiAgfVxuXG4gIHN0YXRpYyBwYXNzVGhyb3VnaEhvb2tzID0gbmV3IFNldChbXG4gICAgJ3ByZXByb2Nlc3MnLFxuICAgICdwb3N0cHJvY2VzcycsXG4gICAgJ3Byb2Nlc3NBbGxUb2tlbnMnLFxuICAgICdlbVN0cm9uZ01hc2snLFxuICBdKTtcblxuICBzdGF0aWMgcGFzc1Rocm91Z2hIb29rc1Jlc3BlY3RBc3luYyA9IG5ldyBTZXQoW1xuICAgICdwcmVwcm9jZXNzJyxcbiAgICAncG9zdHByb2Nlc3MnLFxuICAgICdwcm9jZXNzQWxsVG9rZW5zJyxcbiAgXSk7XG5cbiAgLyoqXG4gICAqIFByb2Nlc3MgbWFya2Rvd24gYmVmb3JlIG1hcmtlZFxuICAgKi9cbiAgcHJlcHJvY2VzcyhtYXJrZG93bjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG1hcmtkb3duO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2Nlc3MgSFRNTCBhZnRlciBtYXJrZWQgaXMgZmluaXNoZWRcbiAgICovXG4gIHBvc3Rwcm9jZXNzKGh0bWw6IFBhcnNlck91dHB1dCkge1xuICAgIHJldHVybiBodG1sO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2Nlc3MgYWxsIHRva2VucyBiZWZvcmUgd2FsayB0b2tlbnNcbiAgICovXG4gIHByb2Nlc3NBbGxUb2tlbnModG9rZW5zOiBUb2tlbltdIHwgVG9rZW5zTGlzdCkge1xuICAgIHJldHVybiB0b2tlbnM7XG4gIH1cblxuICAvKipcbiAgICogTWFzayBjb250ZW50cyB0aGF0IHNob3VsZCBub3QgYmUgaW50ZXJwcmV0ZWQgYXMgZW0vc3Ryb25nIGRlbGltaXRlcnNcbiAgICovXG4gIGVtU3Ryb25nTWFzayhzcmM6IHN0cmluZykge1xuICAgIHJldHVybiBzcmM7XG4gIH1cblxuICAvKipcbiAgICogUHJvdmlkZSBmdW5jdGlvbiB0byB0b2tlbml6ZSBtYXJrZG93blxuICAgKi9cbiAgcHJvdmlkZUxleGVyKGJsb2NrID0gdGhpcy5ibG9jaykge1xuICAgIHJldHVybiBibG9jayA/IF9MZXhlci5sZXggOiBfTGV4ZXIubGV4SW5saW5lO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb3ZpZGUgZnVuY3Rpb24gdG8gcGFyc2UgdG9rZW5zXG4gICAqL1xuICBwcm92aWRlUGFyc2VyKGJsb2NrID0gdGhpcy5ibG9jaykge1xuICAgIHJldHVybiBibG9jayA/IF9QYXJzZXIucGFyc2U8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4gOiBfUGFyc2VyLnBhcnNlSW5saW5lPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+O1xuICB9XG59XG4iLCAiaW1wb3J0IHsgX2dldERlZmF1bHRzIH0gZnJvbSAnLi9kZWZhdWx0cy50cyc7XG5pbXBvcnQgeyBfTGV4ZXIgfSBmcm9tICcuL0xleGVyLnRzJztcbmltcG9ydCB7IF9QYXJzZXIgfSBmcm9tICcuL1BhcnNlci50cyc7XG5pbXBvcnQgeyBfSG9va3MgfSBmcm9tICcuL0hvb2tzLnRzJztcbmltcG9ydCB7IF9SZW5kZXJlciB9IGZyb20gJy4vUmVuZGVyZXIudHMnO1xuaW1wb3J0IHsgX1Rva2VuaXplciB9IGZyb20gJy4vVG9rZW5pemVyLnRzJztcbmltcG9ydCB7IF9UZXh0UmVuZGVyZXIgfSBmcm9tICcuL1RleHRSZW5kZXJlci50cyc7XG5pbXBvcnQgeyBlc2NhcGVIdG1sRW50aXRpZXMgfSBmcm9tICcuL2hlbHBlcnMudHMnO1xuaW1wb3J0IHR5cGUgeyBNYXJrZWRFeHRlbnNpb24sIE1hcmtlZE9wdGlvbnMgfSBmcm9tICcuL01hcmtlZE9wdGlvbnMudHMnO1xuaW1wb3J0IHR5cGUgeyBUb2tlbiwgVG9rZW5zLCBUb2tlbnNMaXN0IH0gZnJvbSAnLi9Ub2tlbnMudHMnO1xuXG5leHBvcnQgdHlwZSBNYXliZVByb21pc2UgPSB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcblxudHlwZSBVbmtub3duRnVuY3Rpb24gPSAoLi4uYXJnczogdW5rbm93bltdKSA9PiB1bmtub3duO1xudHlwZSBHZW5lcmljUmVuZGVyZXJGdW5jdGlvbiA9ICguLi5hcmdzOiB1bmtub3duW10pID0+IHN0cmluZyB8IGZhbHNlO1xuXG5leHBvcnQgY2xhc3MgTWFya2VkPFBhcnNlck91dHB1dCA9IHN0cmluZywgUmVuZGVyZXJPdXRwdXQgPSBzdHJpbmc+IHtcbiAgZGVmYXVsdHMgPSBfZ2V0RGVmYXVsdHM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4oKTtcbiAgb3B0aW9ucyA9IHRoaXMuc2V0T3B0aW9ucztcblxuICBwYXJzZSA9IHRoaXMucGFyc2VNYXJrZG93bih0cnVlKTtcbiAgcGFyc2VJbmxpbmUgPSB0aGlzLnBhcnNlTWFya2Rvd24oZmFsc2UpO1xuXG4gIFBhcnNlciA9IF9QYXJzZXI8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD47XG4gIFJlbmRlcmVyID0gX1JlbmRlcmVyPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+O1xuICBUZXh0UmVuZGVyZXIgPSBfVGV4dFJlbmRlcmVyPFJlbmRlcmVyT3V0cHV0PjtcbiAgTGV4ZXIgPSBfTGV4ZXI7XG4gIFRva2VuaXplciA9IF9Ub2tlbml6ZXI8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD47XG4gIEhvb2tzID0gX0hvb2tzPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+O1xuXG4gIGNvbnN0cnVjdG9yKC4uLmFyZ3M6IE1hcmtlZEV4dGVuc2lvbjxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0PltdKSB7XG4gICAgdGhpcy51c2UoLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogUnVuIGNhbGxiYWNrIGZvciBldmVyeSB0b2tlblxuICAgKi9cbiAgd2Fsa1Rva2Vucyh0b2tlbnM6IFRva2VuW10gfCBUb2tlbnNMaXN0LCBjYWxsYmFjazogKHRva2VuOiBUb2tlbikgPT4gTWF5YmVQcm9taXNlIHwgTWF5YmVQcm9taXNlW10pIHtcbiAgICBsZXQgdmFsdWVzOiBNYXliZVByb21pc2VbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgdG9rZW4gb2YgdG9rZW5zKSB7XG4gICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KGNhbGxiYWNrLmNhbGwodGhpcywgdG9rZW4pKTtcbiAgICAgIHN3aXRjaCAodG9rZW4udHlwZSkge1xuICAgICAgICBjYXNlICd0YWJsZSc6IHtcbiAgICAgICAgICBjb25zdCB0YWJsZVRva2VuID0gdG9rZW4gYXMgVG9rZW5zLlRhYmxlO1xuICAgICAgICAgIGZvciAoY29uc3QgY2VsbCBvZiB0YWJsZVRva2VuLmhlYWRlcikge1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdCh0aGlzLndhbGtUb2tlbnMoY2VsbC50b2tlbnMsIGNhbGxiYWNrKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGZvciAoY29uc3Qgcm93IG9mIHRhYmxlVG9rZW4ucm93cykge1xuICAgICAgICAgICAgZm9yIChjb25zdCBjZWxsIG9mIHJvdykge1xuICAgICAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KHRoaXMud2Fsa1Rva2VucyhjZWxsLnRva2VucywgY2FsbGJhY2spKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAnbGlzdCc6IHtcbiAgICAgICAgICBjb25zdCBsaXN0VG9rZW4gPSB0b2tlbiBhcyBUb2tlbnMuTGlzdDtcbiAgICAgICAgICB2YWx1ZXMgPSB2YWx1ZXMuY29uY2F0KHRoaXMud2Fsa1Rva2VucyhsaXN0VG9rZW4uaXRlbXMsIGNhbGxiYWNrKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgIGNvbnN0IGdlbmVyaWNUb2tlbiA9IHRva2VuIGFzIFRva2Vucy5HZW5lcmljO1xuICAgICAgICAgIGlmICh0aGlzLmRlZmF1bHRzLmV4dGVuc2lvbnM/LmNoaWxkVG9rZW5zPy5bZ2VuZXJpY1Rva2VuLnR5cGVdKSB7XG4gICAgICAgICAgICB0aGlzLmRlZmF1bHRzLmV4dGVuc2lvbnMuY2hpbGRUb2tlbnNbZ2VuZXJpY1Rva2VuLnR5cGVdLmZvckVhY2goKGNoaWxkVG9rZW5zKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHRva2VucyA9IGdlbmVyaWNUb2tlbltjaGlsZFRva2Vuc10uZmxhdChJbmZpbml0eSkgYXMgVG9rZW5bXSB8IFRva2Vuc0xpc3Q7XG4gICAgICAgICAgICAgIHZhbHVlcyA9IHZhbHVlcy5jb25jYXQodGhpcy53YWxrVG9rZW5zKHRva2VucywgY2FsbGJhY2spKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZ2VuZXJpY1Rva2VuLnRva2Vucykge1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdCh0aGlzLndhbGtUb2tlbnMoZ2VuZXJpY1Rva2VuLnRva2VucywgY2FsbGJhY2spKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG4gIHVzZSguLi5hcmdzOiBNYXJrZWRFeHRlbnNpb248UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD5bXSkge1xuICAgIGNvbnN0IGV4dGVuc2lvbnM6IE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD5bJ2V4dGVuc2lvbnMnXSA9IHRoaXMuZGVmYXVsdHMuZXh0ZW5zaW9ucyB8fCB7IHJlbmRlcmVyczoge30sIGNoaWxkVG9rZW5zOiB7fSB9O1xuXG4gICAgYXJncy5mb3JFYWNoKChwYWNrKSA9PiB7XG4gICAgICAvLyBjb3B5IG9wdGlvbnMgdG8gbmV3IG9iamVjdFxuICAgICAgY29uc3Qgb3B0cyA9IHsgLi4ucGFjayB9IGFzIE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD47XG5cbiAgICAgIC8vIHNldCBhc3luYyB0byB0cnVlIGlmIGl0IHdhcyBzZXQgdG8gdHJ1ZSBiZWZvcmVcbiAgICAgIG9wdHMuYXN5bmMgPSB0aGlzLmRlZmF1bHRzLmFzeW5jIHx8IG9wdHMuYXN5bmMgfHwgZmFsc2U7XG5cbiAgICAgIC8vID09LS0gUGFyc2UgXCJhZGRvblwiIGV4dGVuc2lvbnMgLS09PSAvL1xuICAgICAgaWYgKHBhY2suZXh0ZW5zaW9ucykge1xuICAgICAgICBwYWNrLmV4dGVuc2lvbnMuZm9yRWFjaCgoZXh0KSA9PiB7XG4gICAgICAgICAgaWYgKCFleHQubmFtZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdleHRlbnNpb24gbmFtZSByZXF1aXJlZCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoJ3JlbmRlcmVyJyBpbiBleHQpIHsgLy8gUmVuZGVyZXIgZXh0ZW5zaW9uc1xuICAgICAgICAgICAgY29uc3QgcHJldlJlbmRlcmVyID0gZXh0ZW5zaW9ucy5yZW5kZXJlcnNbZXh0Lm5hbWVdO1xuICAgICAgICAgICAgaWYgKHByZXZSZW5kZXJlcikge1xuICAgICAgICAgICAgICAvLyBSZXBsYWNlIGV4dGVuc2lvbiB3aXRoIGZ1bmMgdG8gcnVuIG5ldyBleHRlbnNpb24gYnV0IGZhbGwgYmFjayBpZiBmYWxzZVxuICAgICAgICAgICAgICBleHRlbnNpb25zLnJlbmRlcmVyc1tleHQubmFtZV0gPSBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJldCA9IGV4dC5yZW5kZXJlci5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgICAgICBpZiAocmV0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgcmV0ID0gcHJldlJlbmRlcmVyLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZXh0ZW5zaW9ucy5yZW5kZXJlcnNbZXh0Lm5hbWVdID0gZXh0LnJlbmRlcmVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoJ3Rva2VuaXplcicgaW4gZXh0KSB7IC8vIFRva2VuaXplciBFeHRlbnNpb25zXG4gICAgICAgICAgICBpZiAoIWV4dC5sZXZlbCB8fCAoZXh0LmxldmVsICE9PSAnYmxvY2snICYmIGV4dC5sZXZlbCAhPT0gJ2lubGluZScpKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcImV4dGVuc2lvbiBsZXZlbCBtdXN0IGJlICdibG9jaycgb3IgJ2lubGluZSdcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBleHRMZXZlbCA9IGV4dGVuc2lvbnNbZXh0LmxldmVsXTtcbiAgICAgICAgICAgIGlmIChleHRMZXZlbCkge1xuICAgICAgICAgICAgICBleHRMZXZlbC51bnNoaWZ0KGV4dC50b2tlbml6ZXIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZXh0ZW5zaW9uc1tleHQubGV2ZWxdID0gW2V4dC50b2tlbml6ZXJdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGV4dC5zdGFydCkgeyAvLyBGdW5jdGlvbiB0byBjaGVjayBmb3Igc3RhcnQgb2YgdG9rZW5cbiAgICAgICAgICAgICAgaWYgKGV4dC5sZXZlbCA9PT0gJ2Jsb2NrJykge1xuICAgICAgICAgICAgICAgIGlmIChleHRlbnNpb25zLnN0YXJ0QmxvY2spIHtcbiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnMuc3RhcnRCbG9jay5wdXNoKGV4dC5zdGFydCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnMuc3RhcnRCbG9jayA9IFtleHQuc3RhcnRdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChleHQubGV2ZWwgPT09ICdpbmxpbmUnKSB7XG4gICAgICAgICAgICAgICAgaWYgKGV4dGVuc2lvbnMuc3RhcnRJbmxpbmUpIHtcbiAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbnMuc3RhcnRJbmxpbmUucHVzaChleHQuc3RhcnQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBleHRlbnNpb25zLnN0YXJ0SW5saW5lID0gW2V4dC5zdGFydF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICgnY2hpbGRUb2tlbnMnIGluIGV4dCAmJiBleHQuY2hpbGRUb2tlbnMpIHsgLy8gQ2hpbGQgdG9rZW5zIHRvIGJlIHZpc2l0ZWQgYnkgd2Fsa1Rva2Vuc1xuICAgICAgICAgICAgZXh0ZW5zaW9ucy5jaGlsZFRva2Vuc1tleHQubmFtZV0gPSBleHQuY2hpbGRUb2tlbnM7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgb3B0cy5leHRlbnNpb25zID0gZXh0ZW5zaW9ucztcbiAgICAgIH1cblxuICAgICAgLy8gPT0tLSBQYXJzZSBcIm92ZXJ3cml0ZVwiIGV4dGVuc2lvbnMgLS09PSAvL1xuICAgICAgaWYgKHBhY2sucmVuZGVyZXIpIHtcbiAgICAgICAgY29uc3QgcmVuZGVyZXIgPSB0aGlzLmRlZmF1bHRzLnJlbmRlcmVyIHx8IG5ldyBfUmVuZGVyZXI8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4odGhpcy5kZWZhdWx0cyk7XG4gICAgICAgIGZvciAoY29uc3QgcHJvcCBpbiBwYWNrLnJlbmRlcmVyKSB7XG4gICAgICAgICAgaWYgKCEocHJvcCBpbiByZW5kZXJlcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgcmVuZGVyZXIgJyR7cHJvcH0nIGRvZXMgbm90IGV4aXN0YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChbJ29wdGlvbnMnLCAncGFyc2VyJ10uaW5jbHVkZXMocHJvcCkpIHtcbiAgICAgICAgICAgIC8vIGlnbm9yZSBvcHRpb25zIHByb3BlcnR5XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgcmVuZGVyZXJQcm9wID0gcHJvcCBhcyBFeGNsdWRlPGtleW9mIF9SZW5kZXJlcjxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0PiwgJ29wdGlvbnMnIHwgJ3BhcnNlcic+O1xuICAgICAgICAgIGNvbnN0IHJlbmRlcmVyRnVuYyA9IHBhY2sucmVuZGVyZXJbcmVuZGVyZXJQcm9wXSBhcyBHZW5lcmljUmVuZGVyZXJGdW5jdGlvbjtcbiAgICAgICAgICBjb25zdCBwcmV2UmVuZGVyZXIgPSByZW5kZXJlcltyZW5kZXJlclByb3BdIGFzIEdlbmVyaWNSZW5kZXJlckZ1bmN0aW9uO1xuICAgICAgICAgIC8vIFJlcGxhY2UgcmVuZGVyZXIgd2l0aCBmdW5jIHRvIHJ1biBleHRlbnNpb24sIGJ1dCBmYWxsIGJhY2sgaWYgZmFsc2VcbiAgICAgICAgICByZW5kZXJlcltyZW5kZXJlclByb3BdID0gKC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICAgICAgICAgICAgbGV0IHJldCA9IHJlbmRlcmVyRnVuYy5hcHBseShyZW5kZXJlciwgYXJncyk7XG4gICAgICAgICAgICBpZiAocmV0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICByZXQgPSBwcmV2UmVuZGVyZXIuYXBwbHkocmVuZGVyZXIsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIChyZXQgfHwgJycpIGFzIFJlbmRlcmVyT3V0cHV0O1xuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgb3B0cy5yZW5kZXJlciA9IHJlbmRlcmVyO1xuICAgICAgfVxuICAgICAgaWYgKHBhY2sudG9rZW5pemVyKSB7XG4gICAgICAgIGNvbnN0IHRva2VuaXplciA9IHRoaXMuZGVmYXVsdHMudG9rZW5pemVyIHx8IG5ldyBfVG9rZW5pemVyPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+KHRoaXMuZGVmYXVsdHMpO1xuICAgICAgICBmb3IgKGNvbnN0IHByb3AgaW4gcGFjay50b2tlbml6ZXIpIHtcbiAgICAgICAgICBpZiAoIShwcm9wIGluIHRva2VuaXplcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdG9rZW5pemVyICcke3Byb3B9JyBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoWydvcHRpb25zJywgJ3J1bGVzJywgJ2xleGVyJ10uaW5jbHVkZXMocHJvcCkpIHtcbiAgICAgICAgICAgIC8vIGlnbm9yZSBvcHRpb25zLCBydWxlcywgYW5kIGxleGVyIHByb3BlcnRpZXNcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCB0b2tlbml6ZXJQcm9wID0gcHJvcCBhcyBFeGNsdWRlPGtleW9mIF9Ub2tlbml6ZXI8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4sICdvcHRpb25zJyB8ICdydWxlcycgfCAnbGV4ZXInPjtcbiAgICAgICAgICBjb25zdCB0b2tlbml6ZXJGdW5jID0gcGFjay50b2tlbml6ZXJbdG9rZW5pemVyUHJvcF0gYXMgVW5rbm93bkZ1bmN0aW9uO1xuICAgICAgICAgIGNvbnN0IHByZXZUb2tlbml6ZXIgPSB0b2tlbml6ZXJbdG9rZW5pemVyUHJvcF0gYXMgVW5rbm93bkZ1bmN0aW9uO1xuICAgICAgICAgIC8vIFJlcGxhY2UgdG9rZW5pemVyIHdpdGggZnVuYyB0byBydW4gZXh0ZW5zaW9uLCBidXQgZmFsbCBiYWNrIGlmIGZhbHNlXG4gICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBjYW5ub3QgdHlwZSB0b2tlbml6ZXIgZnVuY3Rpb24gZHluYW1pY2FsbHlcbiAgICAgICAgICB0b2tlbml6ZXJbdG9rZW5pemVyUHJvcF0gPSAoLi4uYXJnczogdW5rbm93bltdKSA9PiB7XG4gICAgICAgICAgICBsZXQgcmV0ID0gdG9rZW5pemVyRnVuYy5hcHBseSh0b2tlbml6ZXIsIGFyZ3MpO1xuICAgICAgICAgICAgaWYgKHJldCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgcmV0ID0gcHJldlRva2VuaXplci5hcHBseSh0b2tlbml6ZXIsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIG9wdHMudG9rZW5pemVyID0gdG9rZW5pemVyO1xuICAgICAgfVxuXG4gICAgICAvLyA9PS0tIFBhcnNlIEhvb2tzIGV4dGVuc2lvbnMgLS09PSAvL1xuICAgICAgaWYgKHBhY2suaG9va3MpIHtcbiAgICAgICAgY29uc3QgaG9va3MgPSB0aGlzLmRlZmF1bHRzLmhvb2tzIHx8IG5ldyBfSG9va3M8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4oKTtcbiAgICAgICAgZm9yIChjb25zdCBwcm9wIGluIHBhY2suaG9va3MpIHtcbiAgICAgICAgICBpZiAoIShwcm9wIGluIGhvb2tzKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBob29rICcke3Byb3B9JyBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoWydvcHRpb25zJywgJ2Jsb2NrJ10uaW5jbHVkZXMocHJvcCkpIHtcbiAgICAgICAgICAgIC8vIGlnbm9yZSBvcHRpb25zIGFuZCBibG9jayBwcm9wZXJ0aWVzXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgaG9va3NQcm9wID0gcHJvcCBhcyBFeGNsdWRlPGtleW9mIF9Ib29rczxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0PiwgJ29wdGlvbnMnIHwgJ2Jsb2NrJz47XG4gICAgICAgICAgY29uc3QgaG9va3NGdW5jID0gcGFjay5ob29rc1tob29rc1Byb3BdIGFzIFVua25vd25GdW5jdGlvbjtcbiAgICAgICAgICBjb25zdCBwcmV2SG9vayA9IGhvb2tzW2hvb2tzUHJvcF0gYXMgVW5rbm93bkZ1bmN0aW9uO1xuICAgICAgICAgIGlmIChfSG9va3MucGFzc1Rocm91Z2hIb29rcy5oYXMocHJvcCkpIHtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2Fubm90IHR5cGUgaG9vayBmdW5jdGlvbiBkeW5hbWljYWxseVxuICAgICAgICAgICAgaG9va3NbaG9va3NQcm9wXSA9IChhcmc6IHVua25vd24pID0+IHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdHMuYXN5bmMgJiYgX0hvb2tzLnBhc3NUaHJvdWdoSG9va3NSZXNwZWN0QXN5bmMuaGFzKHByb3ApKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChhc3luYygpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJldCA9IGF3YWl0IGhvb2tzRnVuYy5jYWxsKGhvb2tzLCBhcmcpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHByZXZIb29rLmNhbGwoaG9va3MsIHJldCk7XG4gICAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNvbnN0IHJldCA9IGhvb2tzRnVuYy5jYWxsKGhvb2tzLCBhcmcpO1xuICAgICAgICAgICAgICByZXR1cm4gcHJldkhvb2suY2FsbChob29rcywgcmV0KTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgY2Fubm90IHR5cGUgaG9vayBmdW5jdGlvbiBkeW5hbWljYWxseVxuICAgICAgICAgICAgaG9va3NbaG9va3NQcm9wXSA9ICguLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdHMuYXN5bmMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gKGFzeW5jKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgbGV0IHJldCA9IGF3YWl0IGhvb2tzRnVuYy5hcHBseShob29rcywgYXJncyk7XG4gICAgICAgICAgICAgICAgICBpZiAocmV0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICByZXQgPSBhd2FpdCBwcmV2SG9vay5hcHBseShob29rcywgYXJncyk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgICAgICAgICAgIH0pKCk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBsZXQgcmV0ID0gaG9va3NGdW5jLmFwcGx5KGhvb2tzLCBhcmdzKTtcbiAgICAgICAgICAgICAgaWYgKHJldCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXQgPSBwcmV2SG9vay5hcHBseShob29rcywgYXJncyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHJldDtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIG9wdHMuaG9va3MgPSBob29rcztcbiAgICAgIH1cblxuICAgICAgLy8gPT0tLSBQYXJzZSBXYWxrVG9rZW5zIGV4dGVuc2lvbnMgLS09PSAvL1xuICAgICAgaWYgKHBhY2sud2Fsa1Rva2Vucykge1xuICAgICAgICBjb25zdCB3YWxrVG9rZW5zID0gdGhpcy5kZWZhdWx0cy53YWxrVG9rZW5zO1xuICAgICAgICBjb25zdCBwYWNrV2Fsa3Rva2VucyA9IHBhY2sud2Fsa1Rva2VucztcbiAgICAgICAgb3B0cy53YWxrVG9rZW5zID0gZnVuY3Rpb24odG9rZW4pIHtcbiAgICAgICAgICBsZXQgdmFsdWVzOiBNYXliZVByb21pc2VbXSA9IFtdO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKHBhY2tXYWxrdG9rZW5zLmNhbGwodGhpcywgdG9rZW4pKTtcbiAgICAgICAgICBpZiAod2Fsa1Rva2Vucykge1xuICAgICAgICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdCh3YWxrVG9rZW5zLmNhbGwodGhpcywgdG9rZW4pKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlcztcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5kZWZhdWx0cyA9IHsgLi4udGhpcy5kZWZhdWx0cywgLi4ub3B0cyB9O1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBzZXRPcHRpb25zKG9wdDogTWFya2VkT3B0aW9uczxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0Pikge1xuICAgIHRoaXMuZGVmYXVsdHMgPSB7IC4uLnRoaXMuZGVmYXVsdHMsIC4uLm9wdCB9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGV4ZXIoc3JjOiBzdHJpbmcsIG9wdGlvbnM/OiBNYXJrZWRPcHRpb25zPFBhcnNlck91dHB1dCwgUmVuZGVyZXJPdXRwdXQ+KSB7XG4gICAgcmV0dXJuIF9MZXhlci5sZXgoc3JjLCBvcHRpb25zID8/IHRoaXMuZGVmYXVsdHMpO1xuICB9XG5cbiAgcGFyc2VyKHRva2VuczogVG9rZW5bXSwgb3B0aW9ucz86IE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4pIHtcbiAgICByZXR1cm4gX1BhcnNlci5wYXJzZTxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0Pih0b2tlbnMsIG9wdGlvbnMgPz8gdGhpcy5kZWZhdWx0cyk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTWFya2Rvd24oYmxvY2tUeXBlOiBib29sZWFuKSB7XG4gICAgdHlwZSBvdmVybG9hZGVkUGFyc2UgPSB7XG4gICAgICAoc3JjOiBzdHJpbmcsIG9wdGlvbnM6IE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4gJiB7IGFzeW5jOiB0cnVlIH0pOiBQcm9taXNlPFBhcnNlck91dHB1dD47XG4gICAgICAoc3JjOiBzdHJpbmcsIG9wdGlvbnM6IE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4gJiB7IGFzeW5jOiBmYWxzZSB9KTogUGFyc2VyT3V0cHV0O1xuICAgICAgKHNyYzogc3RyaW5nLCBvcHRpb25zPzogTWFya2VkT3B0aW9uczxQYXJzZXJPdXRwdXQsIFJlbmRlcmVyT3V0cHV0PiB8IG51bGwpOiBQYXJzZXJPdXRwdXQgfCBQcm9taXNlPFBhcnNlck91dHB1dD47XG4gICAgfTtcblxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgcGFyc2U6IG92ZXJsb2FkZWRQYXJzZSA9IChzcmM6IHN0cmluZywgb3B0aW9ucz86IE1hcmtlZE9wdGlvbnM8UGFyc2VyT3V0cHV0LCBSZW5kZXJlck91dHB1dD4gfCBudWxsKTogYW55ID0+IHtcbiAgICAgIGNvbnN0IG9yaWdPcHQgPSB7IC4uLm9wdGlvbnMgfTtcbiAgICAgIGNvbnN0IG9wdCA9IHsgLi4udGhpcy5kZWZhdWx0cywgLi4ub3JpZ09wdCB9O1xuXG4gICAgICBjb25zdCB0aHJvd0Vycm9yID0gdGhpcy5vbkVycm9yKCEhb3B0LnNpbGVudCwgISFvcHQuYXN5bmMpO1xuXG4gICAgICAvLyB0aHJvdyBlcnJvciBpZiBhbiBleHRlbnNpb24gc2V0IGFzeW5jIHRvIHRydWUgYnV0IHBhcnNlIHdhcyBjYWxsZWQgd2l0aCBhc3luYzogZmFsc2VcbiAgICAgIGlmICh0aGlzLmRlZmF1bHRzLmFzeW5jID09PSB0cnVlICYmIG9yaWdPcHQuYXN5bmMgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKG5ldyBFcnJvcignbWFya2VkKCk6IFRoZSBhc3luYyBvcHRpb24gd2FzIHNldCB0byB0cnVlIGJ5IGFuIGV4dGVuc2lvbi4gUmVtb3ZlIGFzeW5jOiBmYWxzZSBmcm9tIHRoZSBwYXJzZSBvcHRpb25zIG9iamVjdCB0byByZXR1cm4gYSBQcm9taXNlLicpKTtcbiAgICAgIH1cblxuICAgICAgLy8gdGhyb3cgZXJyb3IgaW4gY2FzZSBvZiBub24gc3RyaW5nIGlucHV0XG4gICAgICBpZiAodHlwZW9mIHNyYyA9PT0gJ3VuZGVmaW5lZCcgfHwgc3JjID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKG5ldyBFcnJvcignbWFya2VkKCk6IGlucHV0IHBhcmFtZXRlciBpcyB1bmRlZmluZWQgb3IgbnVsbCcpKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2Ygc3JjICE9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihuZXcgRXJyb3IoJ21hcmtlZCgpOiBpbnB1dCBwYXJhbWV0ZXIgaXMgb2YgdHlwZSAnXG4gICAgICAgICAgKyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3JjKSArICcsIHN0cmluZyBleHBlY3RlZCcpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdC5ob29rcykge1xuICAgICAgICBvcHQuaG9va3Mub3B0aW9ucyA9IG9wdDtcbiAgICAgICAgb3B0Lmhvb2tzLmJsb2NrID0gYmxvY2tUeXBlO1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0LmFzeW5jKSB7XG4gICAgICAgIHJldHVybiAoYXN5bmMoKSA9PiB7XG4gICAgICAgICAgY29uc3QgcHJvY2Vzc2VkU3JjID0gb3B0Lmhvb2tzID8gYXdhaXQgb3B0Lmhvb2tzLnByZXByb2Nlc3Moc3JjKSA6IHNyYztcbiAgICAgICAgICBjb25zdCBsZXhlciA9IG9wdC5ob29rcyA/IGF3YWl0IG9wdC5ob29rcy5wcm92aWRlTGV4ZXIoYmxvY2tUeXBlKSA6IChibG9ja1R5cGUgPyBfTGV4ZXIubGV4IDogX0xleGVyLmxleElubGluZSk7XG4gICAgICAgICAgY29uc3QgdG9rZW5zID0gYXdhaXQgbGV4ZXIocHJvY2Vzc2VkU3JjLCBvcHQpO1xuICAgICAgICAgIGNvbnN0IHByb2Nlc3NlZFRva2VucyA9IG9wdC5ob29rcyA/IGF3YWl0IG9wdC5ob29rcy5wcm9jZXNzQWxsVG9rZW5zKHRva2VucykgOiB0b2tlbnM7XG4gICAgICAgICAgaWYgKG9wdC53YWxrVG9rZW5zKSB7XG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbCh0aGlzLndhbGtUb2tlbnMocHJvY2Vzc2VkVG9rZW5zLCBvcHQud2Fsa1Rva2VucykpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBwYXJzZXIgPSBvcHQuaG9va3MgPyBhd2FpdCBvcHQuaG9va3MucHJvdmlkZVBhcnNlcihibG9ja1R5cGUpIDogKGJsb2NrVHlwZSA/IF9QYXJzZXIucGFyc2UgOiBfUGFyc2VyLnBhcnNlSW5saW5lKTtcbiAgICAgICAgICBjb25zdCBodG1sID0gYXdhaXQgcGFyc2VyKHByb2Nlc3NlZFRva2Vucywgb3B0KTtcbiAgICAgICAgICByZXR1cm4gb3B0Lmhvb2tzID8gYXdhaXQgb3B0Lmhvb2tzLnBvc3Rwcm9jZXNzKGh0bWwpIDogaHRtbDtcbiAgICAgICAgfSkoKS5jYXRjaCh0aHJvd0Vycm9yKTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKG9wdC5ob29rcykge1xuICAgICAgICAgIHNyYyA9IG9wdC5ob29rcy5wcmVwcm9jZXNzKHNyYykgYXMgc3RyaW5nO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGxleGVyID0gb3B0Lmhvb2tzID8gb3B0Lmhvb2tzLnByb3ZpZGVMZXhlcihibG9ja1R5cGUpIDogKGJsb2NrVHlwZSA/IF9MZXhlci5sZXggOiBfTGV4ZXIubGV4SW5saW5lKTtcbiAgICAgICAgbGV0IHRva2VucyA9IGxleGVyKHNyYywgb3B0KTtcbiAgICAgICAgaWYgKG9wdC5ob29rcykge1xuICAgICAgICAgIHRva2VucyA9IG9wdC5ob29rcy5wcm9jZXNzQWxsVG9rZW5zKHRva2Vucyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdC53YWxrVG9rZW5zKSB7XG4gICAgICAgICAgdGhpcy53YWxrVG9rZW5zKHRva2Vucywgb3B0LndhbGtUb2tlbnMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlciA9IG9wdC5ob29rcyA/IG9wdC5ob29rcy5wcm92aWRlUGFyc2VyKGJsb2NrVHlwZSkgOiAoYmxvY2tUeXBlID8gX1BhcnNlci5wYXJzZSA6IF9QYXJzZXIucGFyc2VJbmxpbmUpO1xuICAgICAgICBsZXQgaHRtbCA9IHBhcnNlcih0b2tlbnMsIG9wdCk7XG4gICAgICAgIGlmIChvcHQuaG9va3MpIHtcbiAgICAgICAgICBodG1sID0gb3B0Lmhvb2tzLnBvc3Rwcm9jZXNzKGh0bWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBodG1sO1xuICAgICAgfSBjYXRjaChlKSB7XG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKGUgYXMgRXJyb3IpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gcGFyc2U7XG4gIH1cblxuICBwcml2YXRlIG9uRXJyb3Ioc2lsZW50OiBib29sZWFuLCBhc3luYzogYm9vbGVhbikge1xuICAgIHJldHVybiAoZTogRXJyb3IpOiBzdHJpbmcgfCBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgZS5tZXNzYWdlICs9ICdcXG5QbGVhc2UgcmVwb3J0IHRoaXMgdG8gaHR0cHM6Ly9naXRodWIuY29tL21hcmtlZGpzL21hcmtlZC4nO1xuXG4gICAgICBpZiAoc2lsZW50KSB7XG4gICAgICAgIGNvbnN0IG1zZyA9ICc8cD5BbiBlcnJvciBvY2N1cnJlZDo8L3A+PHByZT4nXG4gICAgICAgICAgKyBlc2NhcGVIdG1sRW50aXRpZXMoZS5tZXNzYWdlICsgJycsIHRydWUpXG4gICAgICAgICAgKyAnPC9wcmU+JztcbiAgICAgICAgaWYgKGFzeW5jKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShtc2cpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtc2c7XG4gICAgICB9XG5cbiAgICAgIGlmIChhc3luYykge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlO1xuICAgIH07XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBfTGV4ZXIgfSBmcm9tICcuL0xleGVyLnRzJztcbmltcG9ydCB7IF9QYXJzZXIgfSBmcm9tICcuL1BhcnNlci50cyc7XG5pbXBvcnQgeyBfVG9rZW5pemVyIH0gZnJvbSAnLi9Ub2tlbml6ZXIudHMnO1xuaW1wb3J0IHsgX1JlbmRlcmVyIH0gZnJvbSAnLi9SZW5kZXJlci50cyc7XG5pbXBvcnQgeyBfVGV4dFJlbmRlcmVyIH0gZnJvbSAnLi9UZXh0UmVuZGVyZXIudHMnO1xuaW1wb3J0IHsgX0hvb2tzIH0gZnJvbSAnLi9Ib29rcy50cyc7XG5pbXBvcnQgeyBNYXJrZWQgfSBmcm9tICcuL0luc3RhbmNlLnRzJztcbmltcG9ydCB7XG4gIF9nZXREZWZhdWx0cyxcbiAgY2hhbmdlRGVmYXVsdHMsXG4gIF9kZWZhdWx0cyxcbn0gZnJvbSAnLi9kZWZhdWx0cy50cyc7XG5pbXBvcnQgdHlwZSB7IE1hcmtlZEV4dGVuc2lvbiwgTWFya2VkT3B0aW9ucyB9IGZyb20gJy4vTWFya2VkT3B0aW9ucy50cyc7XG5pbXBvcnQgdHlwZSB7IFRva2VuLCBUb2tlbnNMaXN0IH0gZnJvbSAnLi9Ub2tlbnMudHMnO1xuaW1wb3J0IHR5cGUgeyBNYXliZVByb21pc2UgfSBmcm9tICcuL0luc3RhbmNlLnRzJztcblxuY29uc3QgbWFya2VkSW5zdGFuY2UgPSBuZXcgTWFya2VkKCk7XG5cbi8qKlxuICogQ29tcGlsZXMgbWFya2Rvd24gdG8gSFRNTCBhc3luY2hyb25vdXNseS5cbiAqXG4gKiBAcGFyYW0gc3JjIFN0cmluZyBvZiBtYXJrZG93biBzb3VyY2UgdG8gYmUgY29tcGlsZWRcbiAqIEBwYXJhbSBvcHRpb25zIEhhc2ggb2Ygb3B0aW9ucywgaGF2aW5nIGFzeW5jOiB0cnVlXG4gKiBAcmV0dXJuIFByb21pc2Ugb2Ygc3RyaW5nIG9mIGNvbXBpbGVkIEhUTUxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcmtlZChzcmM6IHN0cmluZywgb3B0aW9uczogTWFya2VkT3B0aW9ucyAmIHsgYXN5bmM6IHRydWUgfSk6IFByb21pc2U8c3RyaW5nPjtcblxuLyoqXG4gKiBDb21waWxlcyBtYXJrZG93biB0byBIVE1MLlxuICpcbiAqIEBwYXJhbSBzcmMgU3RyaW5nIG9mIG1hcmtkb3duIHNvdXJjZSB0byBiZSBjb21waWxlZFxuICogQHBhcmFtIG9wdGlvbnMgT3B0aW9uYWwgaGFzaCBvZiBvcHRpb25zXG4gKiBAcmV0dXJuIFN0cmluZyBvZiBjb21waWxlZCBIVE1MLiBXaWxsIGJlIGEgUHJvbWlzZSBvZiBzdHJpbmcgaWYgYXN5bmMgaXMgc2V0IHRvIHRydWUgYnkgYW55IGV4dGVuc2lvbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZWQoc3JjOiBzdHJpbmcsIG9wdGlvbnM6IE1hcmtlZE9wdGlvbnMgJiB7IGFzeW5jOiBmYWxzZSB9KTogc3RyaW5nO1xuZXhwb3J0IGZ1bmN0aW9uIG1hcmtlZChzcmM6IHN0cmluZywgb3B0aW9uczogTWFya2VkT3B0aW9ucyAmIHsgYXN5bmM6IHRydWUgfSk6IFByb21pc2U8c3RyaW5nPjtcbmV4cG9ydCBmdW5jdGlvbiBtYXJrZWQoc3JjOiBzdHJpbmcsIG9wdGlvbnM/OiBNYXJrZWRPcHRpb25zIHwgbnVsbCk6IHN0cmluZyB8IFByb21pc2U8c3RyaW5nPjtcbmV4cG9ydCBmdW5jdGlvbiBtYXJrZWQoc3JjOiBzdHJpbmcsIG9wdD86IE1hcmtlZE9wdGlvbnMgfCBudWxsKTogc3RyaW5nIHwgUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIG1hcmtlZEluc3RhbmNlLnBhcnNlKHNyYywgb3B0KTtcbn1cblxuLyoqXG4gKiBTZXRzIHRoZSBkZWZhdWx0IG9wdGlvbnMuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgSGFzaCBvZiBvcHRpb25zXG4gKi9cbm1hcmtlZC5vcHRpb25zID1cbiAgbWFya2VkLnNldE9wdGlvbnMgPSBmdW5jdGlvbihvcHRpb25zOiBNYXJrZWRPcHRpb25zKSB7XG4gICAgbWFya2VkSW5zdGFuY2Uuc2V0T3B0aW9ucyhvcHRpb25zKTtcbiAgICBtYXJrZWQuZGVmYXVsdHMgPSBtYXJrZWRJbnN0YW5jZS5kZWZhdWx0cztcbiAgICBjaGFuZ2VEZWZhdWx0cyhtYXJrZWQuZGVmYXVsdHMpO1xuICAgIHJldHVybiBtYXJrZWQ7XG4gIH07XG5cbi8qKlxuICogR2V0cyB0aGUgb3JpZ2luYWwgbWFya2VkIGRlZmF1bHQgb3B0aW9ucy5cbiAqL1xubWFya2VkLmdldERlZmF1bHRzID0gX2dldERlZmF1bHRzO1xuXG5tYXJrZWQuZGVmYXVsdHMgPSBfZGVmYXVsdHM7XG5cbi8qKlxuICogVXNlIEV4dGVuc2lvblxuICovXG5cbm1hcmtlZC51c2UgPSBmdW5jdGlvbiguLi5hcmdzOiBNYXJrZWRFeHRlbnNpb25bXSkge1xuICBtYXJrZWRJbnN0YW5jZS51c2UoLi4uYXJncyk7XG4gIG1hcmtlZC5kZWZhdWx0cyA9IG1hcmtlZEluc3RhbmNlLmRlZmF1bHRzO1xuICBjaGFuZ2VEZWZhdWx0cyhtYXJrZWQuZGVmYXVsdHMpO1xuICByZXR1cm4gbWFya2VkO1xufTtcblxuLyoqXG4gKiBSdW4gY2FsbGJhY2sgZm9yIGV2ZXJ5IHRva2VuXG4gKi9cblxubWFya2VkLndhbGtUb2tlbnMgPSBmdW5jdGlvbih0b2tlbnM6IFRva2VuW10gfCBUb2tlbnNMaXN0LCBjYWxsYmFjazogKHRva2VuOiBUb2tlbikgPT4gTWF5YmVQcm9taXNlIHwgTWF5YmVQcm9taXNlW10pIHtcbiAgcmV0dXJuIG1hcmtlZEluc3RhbmNlLndhbGtUb2tlbnModG9rZW5zLCBjYWxsYmFjayk7XG59O1xuXG4vKipcbiAqIENvbXBpbGVzIG1hcmtkb3duIHRvIEhUTUwgd2l0aG91dCBlbmNsb3NpbmcgYHBgIHRhZy5cbiAqXG4gKiBAcGFyYW0gc3JjIFN0cmluZyBvZiBtYXJrZG93biBzb3VyY2UgdG8gYmUgY29tcGlsZWRcbiAqIEBwYXJhbSBvcHRpb25zIEhhc2ggb2Ygb3B0aW9uc1xuICogQHJldHVybiBTdHJpbmcgb2YgY29tcGlsZWQgSFRNTFxuICovXG5tYXJrZWQucGFyc2VJbmxpbmUgPSBtYXJrZWRJbnN0YW5jZS5wYXJzZUlubGluZTtcblxuLyoqXG4gKiBFeHBvc2VcbiAqL1xubWFya2VkLlBhcnNlciA9IF9QYXJzZXI7XG5tYXJrZWQucGFyc2VyID0gX1BhcnNlci5wYXJzZTtcbm1hcmtlZC5SZW5kZXJlciA9IF9SZW5kZXJlcjtcbm1hcmtlZC5UZXh0UmVuZGVyZXIgPSBfVGV4dFJlbmRlcmVyO1xubWFya2VkLkxleGVyID0gX0xleGVyO1xubWFya2VkLmxleGVyID0gX0xleGVyLmxleDtcbm1hcmtlZC5Ub2tlbml6ZXIgPSBfVG9rZW5pemVyO1xubWFya2VkLkhvb2tzID0gX0hvb2tzO1xubWFya2VkLnBhcnNlID0gbWFya2VkO1xuXG5leHBvcnQgY29uc3Qgb3B0aW9ucyA9IG1hcmtlZC5vcHRpb25zO1xuZXhwb3J0IGNvbnN0IHNldE9wdGlvbnMgPSBtYXJrZWQuc2V0T3B0aW9ucztcbmV4cG9ydCBjb25zdCB1c2UgPSBtYXJrZWQudXNlO1xuZXhwb3J0IGNvbnN0IHdhbGtUb2tlbnMgPSBtYXJrZWQud2Fsa1Rva2VucztcbmV4cG9ydCBjb25zdCBwYXJzZUlubGluZSA9IG1hcmtlZC5wYXJzZUlubGluZTtcbmV4cG9ydCBjb25zdCBwYXJzZSA9IG1hcmtlZDtcbmV4cG9ydCBjb25zdCBwYXJzZXIgPSBfUGFyc2VyLnBhcnNlO1xuZXhwb3J0IGNvbnN0IGxleGVyID0gX0xleGVyLmxleDtcbmV4cG9ydCB7IF9kZWZhdWx0cyBhcyBkZWZhdWx0cywgX2dldERlZmF1bHRzIGFzIGdldERlZmF1bHRzIH0gZnJvbSAnLi9kZWZhdWx0cy50cyc7XG5leHBvcnQgeyBfTGV4ZXIgYXMgTGV4ZXIgfSBmcm9tICcuL0xleGVyLnRzJztcbmV4cG9ydCB7IF9QYXJzZXIgYXMgUGFyc2VyIH0gZnJvbSAnLi9QYXJzZXIudHMnO1xuZXhwb3J0IHsgX1Rva2VuaXplciBhcyBUb2tlbml6ZXIgfSBmcm9tICcuL1Rva2VuaXplci50cyc7XG5leHBvcnQgeyBfUmVuZGVyZXIgYXMgUmVuZGVyZXIgfSBmcm9tICcuL1JlbmRlcmVyLnRzJztcbmV4cG9ydCB7IF9UZXh0UmVuZGVyZXIgYXMgVGV4dFJlbmRlcmVyIH0gZnJvbSAnLi9UZXh0UmVuZGVyZXIudHMnO1xuZXhwb3J0IHsgX0hvb2tzIGFzIEhvb2tzIH0gZnJvbSAnLi9Ib29rcy50cyc7XG5leHBvcnQgeyBNYXJrZWQgfSBmcm9tICcuL0luc3RhbmNlLnRzJztcbmV4cG9ydCB0eXBlICogZnJvbSAnLi9NYXJrZWRPcHRpb25zLnRzJztcbmV4cG9ydCB0eXBlICogZnJvbSAnLi9Ub2tlbnMudHMnO1xuIiwgImZ1bmN0aW9uIGV4dGVuZChkZXN0aW5hdGlvbikge1xuICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07XG4gICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIGRlc3RpbmF0aW9uW2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRlc3RpbmF0aW9uO1xufVxuZnVuY3Rpb24gcmVwZWF0KGNoYXJhY3RlciwgY291bnQpIHtcbiAgcmV0dXJuIEFycmF5KGNvdW50ICsgMSkuam9pbihjaGFyYWN0ZXIpO1xufVxuZnVuY3Rpb24gdHJpbUxlYWRpbmdOZXdsaW5lcyhzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9eXFxuKi8sICcnKTtcbn1cbmZ1bmN0aW9uIHRyaW1UcmFpbGluZ05ld2xpbmVzKHN0cmluZykge1xuICAvLyBhdm9pZCBtYXRjaC1hdC1lbmQgcmVnZXhwIGJvdHRsZW5lY2ssIHNlZSAjMzcwXG4gIHZhciBpbmRleEVuZCA9IHN0cmluZy5sZW5ndGg7XG4gIHdoaWxlIChpbmRleEVuZCA+IDAgJiYgc3RyaW5nW2luZGV4RW5kIC0gMV0gPT09ICdcXG4nKSBpbmRleEVuZC0tO1xuICByZXR1cm4gc3RyaW5nLnN1YnN0cmluZygwLCBpbmRleEVuZCk7XG59XG5mdW5jdGlvbiB0cmltTmV3bGluZXMoc3RyaW5nKSB7XG4gIHJldHVybiB0cmltVHJhaWxpbmdOZXdsaW5lcyh0cmltTGVhZGluZ05ld2xpbmVzKHN0cmluZykpO1xufVxudmFyIGJsb2NrRWxlbWVudHMgPSBbJ0FERFJFU1MnLCAnQVJUSUNMRScsICdBU0lERScsICdBVURJTycsICdCTE9DS1FVT1RFJywgJ0JPRFknLCAnQ0FOVkFTJywgJ0NFTlRFUicsICdERCcsICdESVInLCAnRElWJywgJ0RMJywgJ0RUJywgJ0ZJRUxEU0VUJywgJ0ZJR0NBUFRJT04nLCAnRklHVVJFJywgJ0ZPT1RFUicsICdGT1JNJywgJ0ZSQU1FU0VUJywgJ0gxJywgJ0gyJywgJ0gzJywgJ0g0JywgJ0g1JywgJ0g2JywgJ0hFQURFUicsICdIR1JPVVAnLCAnSFInLCAnSFRNTCcsICdJU0lOREVYJywgJ0xJJywgJ01BSU4nLCAnTUVOVScsICdOQVYnLCAnTk9GUkFNRVMnLCAnTk9TQ1JJUFQnLCAnT0wnLCAnT1VUUFVUJywgJ1AnLCAnUFJFJywgJ1NFQ1RJT04nLCAnVEFCTEUnLCAnVEJPRFknLCAnVEQnLCAnVEZPT1QnLCAnVEgnLCAnVEhFQUQnLCAnVFInLCAnVUwnXTtcbmZ1bmN0aW9uIGlzQmxvY2sobm9kZSkge1xuICByZXR1cm4gaXMobm9kZSwgYmxvY2tFbGVtZW50cyk7XG59XG52YXIgdm9pZEVsZW1lbnRzID0gWydBUkVBJywgJ0JBU0UnLCAnQlInLCAnQ09MJywgJ0NPTU1BTkQnLCAnRU1CRUQnLCAnSFInLCAnSU1HJywgJ0lOUFVUJywgJ0tFWUdFTicsICdMSU5LJywgJ01FVEEnLCAnUEFSQU0nLCAnU09VUkNFJywgJ1RSQUNLJywgJ1dCUiddO1xuZnVuY3Rpb24gaXNWb2lkKG5vZGUpIHtcbiAgcmV0dXJuIGlzKG5vZGUsIHZvaWRFbGVtZW50cyk7XG59XG5mdW5jdGlvbiBoYXNWb2lkKG5vZGUpIHtcbiAgcmV0dXJuIGhhcyhub2RlLCB2b2lkRWxlbWVudHMpO1xufVxudmFyIG1lYW5pbmdmdWxXaGVuQmxhbmtFbGVtZW50cyA9IFsnQScsICdUQUJMRScsICdUSEVBRCcsICdUQk9EWScsICdURk9PVCcsICdUSCcsICdURCcsICdJRlJBTUUnLCAnU0NSSVBUJywgJ0FVRElPJywgJ1ZJREVPJ107XG5mdW5jdGlvbiBpc01lYW5pbmdmdWxXaGVuQmxhbmsobm9kZSkge1xuICByZXR1cm4gaXMobm9kZSwgbWVhbmluZ2Z1bFdoZW5CbGFua0VsZW1lbnRzKTtcbn1cbmZ1bmN0aW9uIGhhc01lYW5pbmdmdWxXaGVuQmxhbmsobm9kZSkge1xuICByZXR1cm4gaGFzKG5vZGUsIG1lYW5pbmdmdWxXaGVuQmxhbmtFbGVtZW50cyk7XG59XG5mdW5jdGlvbiBpcyhub2RlLCB0YWdOYW1lcykge1xuICByZXR1cm4gdGFnTmFtZXMuaW5kZXhPZihub2RlLm5vZGVOYW1lKSA+PSAwO1xufVxuZnVuY3Rpb24gaGFzKG5vZGUsIHRhZ05hbWVzKSB7XG4gIHJldHVybiBub2RlLmdldEVsZW1lbnRzQnlUYWdOYW1lICYmIHRhZ05hbWVzLnNvbWUoZnVuY3Rpb24gKHRhZ05hbWUpIHtcbiAgICByZXR1cm4gbm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZSh0YWdOYW1lKS5sZW5ndGg7XG4gIH0pO1xufVxudmFyIG1hcmtkb3duRXNjYXBlcyA9IFtbL1xcXFwvZywgJ1xcXFxcXFxcJ10sIFsvXFwqL2csICdcXFxcKiddLCBbL14tL2csICdcXFxcLSddLCBbL15cXCsgL2csICdcXFxcKyAnXSwgWy9eKD0rKS9nLCAnXFxcXCQxJ10sIFsvXigjezEsNn0pIC9nLCAnXFxcXCQxICddLCBbL2AvZywgJ1xcXFxgJ10sIFsvXn5+fi9nLCAnXFxcXH5+fiddLCBbL1xcWy9nLCAnXFxcXFsnXSwgWy9cXF0vZywgJ1xcXFxdJ10sIFsvXj4vZywgJ1xcXFw+J10sIFsvXy9nLCAnXFxcXF8nXSwgWy9eKFxcZCspXFwuIC9nLCAnJDFcXFxcLiAnXV07XG5mdW5jdGlvbiBlc2NhcGVNYXJrZG93bihzdHJpbmcpIHtcbiAgcmV0dXJuIG1hcmtkb3duRXNjYXBlcy5yZWR1Y2UoZnVuY3Rpb24gKGFjY3VtdWxhdG9yLCBlc2NhcGUpIHtcbiAgICByZXR1cm4gYWNjdW11bGF0b3IucmVwbGFjZShlc2NhcGVbMF0sIGVzY2FwZVsxXSk7XG4gIH0sIHN0cmluZyk7XG59XG5cbnZhciBydWxlcyA9IHt9O1xucnVsZXMucGFyYWdyYXBoID0ge1xuICBmaWx0ZXI6ICdwJyxcbiAgcmVwbGFjZW1lbnQ6IGZ1bmN0aW9uIChjb250ZW50KSB7XG4gICAgcmV0dXJuICdcXG5cXG4nICsgY29udGVudCArICdcXG5cXG4nO1xuICB9XG59O1xucnVsZXMubGluZUJyZWFrID0ge1xuICBmaWx0ZXI6ICdicicsXG4gIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSwgb3B0aW9ucykge1xuICAgIHJldHVybiBvcHRpb25zLmJyICsgJ1xcbic7XG4gIH1cbn07XG5ydWxlcy5oZWFkaW5nID0ge1xuICBmaWx0ZXI6IFsnaDEnLCAnaDInLCAnaDMnLCAnaDQnLCAnaDUnLCAnaDYnXSxcbiAgcmVwbGFjZW1lbnQ6IGZ1bmN0aW9uIChjb250ZW50LCBub2RlLCBvcHRpb25zKSB7XG4gICAgdmFyIGhMZXZlbCA9IE51bWJlcihub2RlLm5vZGVOYW1lLmNoYXJBdCgxKSk7XG4gICAgaWYgKG9wdGlvbnMuaGVhZGluZ1N0eWxlID09PSAnc2V0ZXh0JyAmJiBoTGV2ZWwgPCAzKSB7XG4gICAgICB2YXIgdW5kZXJsaW5lID0gcmVwZWF0KGhMZXZlbCA9PT0gMSA/ICc9JyA6ICctJywgY29udGVudC5sZW5ndGgpO1xuICAgICAgcmV0dXJuICdcXG5cXG4nICsgY29udGVudCArICdcXG4nICsgdW5kZXJsaW5lICsgJ1xcblxcbic7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAnXFxuXFxuJyArIHJlcGVhdCgnIycsIGhMZXZlbCkgKyAnICcgKyBjb250ZW50ICsgJ1xcblxcbic7XG4gICAgfVxuICB9XG59O1xucnVsZXMuYmxvY2txdW90ZSA9IHtcbiAgZmlsdGVyOiAnYmxvY2txdW90ZScsXG4gIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCkge1xuICAgIGNvbnRlbnQgPSB0cmltTmV3bGluZXMoY29udGVudCkucmVwbGFjZSgvXi9nbSwgJz4gJyk7XG4gICAgcmV0dXJuICdcXG5cXG4nICsgY29udGVudCArICdcXG5cXG4nO1xuICB9XG59O1xucnVsZXMubGlzdCA9IHtcbiAgZmlsdGVyOiBbJ3VsJywgJ29sJ10sXG4gIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSkge1xuICAgIHZhciBwYXJlbnQgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgaWYgKHBhcmVudC5ub2RlTmFtZSA9PT0gJ0xJJyAmJiBwYXJlbnQubGFzdEVsZW1lbnRDaGlsZCA9PT0gbm9kZSkge1xuICAgICAgcmV0dXJuICdcXG4nICsgY29udGVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuICdcXG5cXG4nICsgY29udGVudCArICdcXG5cXG4nO1xuICAgIH1cbiAgfVxufTtcbnJ1bGVzLmxpc3RJdGVtID0ge1xuICBmaWx0ZXI6ICdsaScsXG4gIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSwgb3B0aW9ucykge1xuICAgIHZhciBwcmVmaXggPSBvcHRpb25zLmJ1bGxldExpc3RNYXJrZXIgKyAnICAgJztcbiAgICB2YXIgcGFyZW50ID0gbm9kZS5wYXJlbnROb2RlO1xuICAgIGlmIChwYXJlbnQubm9kZU5hbWUgPT09ICdPTCcpIHtcbiAgICAgIHZhciBzdGFydCA9IHBhcmVudC5nZXRBdHRyaWJ1dGUoJ3N0YXJ0Jyk7XG4gICAgICB2YXIgaW5kZXggPSBBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHBhcmVudC5jaGlsZHJlbiwgbm9kZSk7XG4gICAgICBwcmVmaXggPSAoc3RhcnQgPyBOdW1iZXIoc3RhcnQpICsgaW5kZXggOiBpbmRleCArIDEpICsgJy4gICc7XG4gICAgfVxuICAgIHZhciBpc1BhcmFncmFwaCA9IC9cXG4kLy50ZXN0KGNvbnRlbnQpO1xuICAgIGNvbnRlbnQgPSB0cmltTmV3bGluZXMoY29udGVudCkgKyAoaXNQYXJhZ3JhcGggPyAnXFxuJyA6ICcnKTtcbiAgICBjb250ZW50ID0gY29udGVudC5yZXBsYWNlKC9cXG4vZ20sICdcXG4nICsgJyAnLnJlcGVhdChwcmVmaXgubGVuZ3RoKSk7IC8vIGluZGVudFxuICAgIHJldHVybiBwcmVmaXggKyBjb250ZW50ICsgKG5vZGUubmV4dFNpYmxpbmcgPyAnXFxuJyA6ICcnKTtcbiAgfVxufTtcbnJ1bGVzLmluZGVudGVkQ29kZUJsb2NrID0ge1xuICBmaWx0ZXI6IGZ1bmN0aW9uIChub2RlLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIG9wdGlvbnMuY29kZUJsb2NrU3R5bGUgPT09ICdpbmRlbnRlZCcgJiYgbm9kZS5ub2RlTmFtZSA9PT0gJ1BSRScgJiYgbm9kZS5maXJzdENoaWxkICYmIG5vZGUuZmlyc3RDaGlsZC5ub2RlTmFtZSA9PT0gJ0NPREUnO1xuICB9LFxuICByZXBsYWNlbWVudDogZnVuY3Rpb24gKGNvbnRlbnQsIG5vZGUsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gJ1xcblxcbiAgICAnICsgbm9kZS5maXJzdENoaWxkLnRleHRDb250ZW50LnJlcGxhY2UoL1xcbi9nLCAnXFxuICAgICcpICsgJ1xcblxcbic7XG4gIH1cbn07XG5ydWxlcy5mZW5jZWRDb2RlQmxvY2sgPSB7XG4gIGZpbHRlcjogZnVuY3Rpb24gKG5vZGUsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gb3B0aW9ucy5jb2RlQmxvY2tTdHlsZSA9PT0gJ2ZlbmNlZCcgJiYgbm9kZS5ub2RlTmFtZSA9PT0gJ1BSRScgJiYgbm9kZS5maXJzdENoaWxkICYmIG5vZGUuZmlyc3RDaGlsZC5ub2RlTmFtZSA9PT0gJ0NPREUnO1xuICB9LFxuICByZXBsYWNlbWVudDogZnVuY3Rpb24gKGNvbnRlbnQsIG5vZGUsIG9wdGlvbnMpIHtcbiAgICB2YXIgY2xhc3NOYW1lID0gbm9kZS5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSgnY2xhc3MnKSB8fCAnJztcbiAgICB2YXIgbGFuZ3VhZ2UgPSAoY2xhc3NOYW1lLm1hdGNoKC9sYW5ndWFnZS0oXFxTKykvKSB8fCBbbnVsbCwgJyddKVsxXTtcbiAgICB2YXIgY29kZSA9IG5vZGUuZmlyc3RDaGlsZC50ZXh0Q29udGVudDtcbiAgICB2YXIgZmVuY2VDaGFyID0gb3B0aW9ucy5mZW5jZS5jaGFyQXQoMCk7XG4gICAgdmFyIGZlbmNlU2l6ZSA9IDM7XG4gICAgdmFyIGZlbmNlSW5Db2RlUmVnZXggPSBuZXcgUmVnRXhwKCdeJyArIGZlbmNlQ2hhciArICd7Myx9JywgJ2dtJyk7XG4gICAgdmFyIG1hdGNoO1xuICAgIHdoaWxlIChtYXRjaCA9IGZlbmNlSW5Db2RlUmVnZXguZXhlYyhjb2RlKSkge1xuICAgICAgaWYgKG1hdGNoWzBdLmxlbmd0aCA+PSBmZW5jZVNpemUpIHtcbiAgICAgICAgZmVuY2VTaXplID0gbWF0Y2hbMF0ubGVuZ3RoICsgMTtcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIGZlbmNlID0gcmVwZWF0KGZlbmNlQ2hhciwgZmVuY2VTaXplKTtcbiAgICByZXR1cm4gJ1xcblxcbicgKyBmZW5jZSArIGxhbmd1YWdlICsgJ1xcbicgKyBjb2RlLnJlcGxhY2UoL1xcbiQvLCAnJykgKyAnXFxuJyArIGZlbmNlICsgJ1xcblxcbic7XG4gIH1cbn07XG5ydWxlcy5ob3Jpem9udGFsUnVsZSA9IHtcbiAgZmlsdGVyOiAnaHInLFxuICByZXBsYWNlbWVudDogZnVuY3Rpb24gKGNvbnRlbnQsIG5vZGUsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gJ1xcblxcbicgKyBvcHRpb25zLmhyICsgJ1xcblxcbic7XG4gIH1cbn07XG5ydWxlcy5pbmxpbmVMaW5rID0ge1xuICBmaWx0ZXI6IGZ1bmN0aW9uIChub2RlLCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIG9wdGlvbnMubGlua1N0eWxlID09PSAnaW5saW5lZCcgJiYgbm9kZS5ub2RlTmFtZSA9PT0gJ0EnICYmIG5vZGUuZ2V0QXR0cmlidXRlKCdocmVmJyk7XG4gIH0sXG4gIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSkge1xuICAgIHZhciBocmVmID0gZXNjYXBlTGlua0Rlc3RpbmF0aW9uKG5vZGUuZ2V0QXR0cmlidXRlKCdocmVmJykpO1xuICAgIHZhciB0aXRsZSA9IGVzY2FwZUxpbmtUaXRsZShjbGVhbkF0dHJpYnV0ZShub2RlLmdldEF0dHJpYnV0ZSgndGl0bGUnKSkpO1xuICAgIHZhciB0aXRsZVBhcnQgPSB0aXRsZSA/ICcgXCInICsgdGl0bGUgKyAnXCInIDogJyc7XG4gICAgcmV0dXJuICdbJyArIGNvbnRlbnQgKyAnXSgnICsgaHJlZiArIHRpdGxlUGFydCArICcpJztcbiAgfVxufTtcbnJ1bGVzLnJlZmVyZW5jZUxpbmsgPSB7XG4gIGZpbHRlcjogZnVuY3Rpb24gKG5vZGUsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gb3B0aW9ucy5saW5rU3R5bGUgPT09ICdyZWZlcmVuY2VkJyAmJiBub2RlLm5vZGVOYW1lID09PSAnQScgJiYgbm9kZS5nZXRBdHRyaWJ1dGUoJ2hyZWYnKTtcbiAgfSxcbiAgcmVwbGFjZW1lbnQ6IGZ1bmN0aW9uIChjb250ZW50LCBub2RlLCBvcHRpb25zKSB7XG4gICAgdmFyIGhyZWYgPSBlc2NhcGVMaW5rRGVzdGluYXRpb24obm9kZS5nZXRBdHRyaWJ1dGUoJ2hyZWYnKSk7XG4gICAgdmFyIHRpdGxlID0gY2xlYW5BdHRyaWJ1dGUobm9kZS5nZXRBdHRyaWJ1dGUoJ3RpdGxlJykpO1xuICAgIGlmICh0aXRsZSkgdGl0bGUgPSAnIFwiJyArIGVzY2FwZUxpbmtUaXRsZSh0aXRsZSkgKyAnXCInO1xuICAgIHZhciByZXBsYWNlbWVudDtcbiAgICB2YXIgcmVmZXJlbmNlO1xuICAgIHN3aXRjaCAob3B0aW9ucy5saW5rUmVmZXJlbmNlU3R5bGUpIHtcbiAgICAgIGNhc2UgJ2NvbGxhcHNlZCc6XG4gICAgICAgIHJlcGxhY2VtZW50ID0gJ1snICsgY29udGVudCArICddW10nO1xuICAgICAgICByZWZlcmVuY2UgPSAnWycgKyBjb250ZW50ICsgJ106ICcgKyBocmVmICsgdGl0bGU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnc2hvcnRjdXQnOlxuICAgICAgICByZXBsYWNlbWVudCA9ICdbJyArIGNvbnRlbnQgKyAnXSc7XG4gICAgICAgIHJlZmVyZW5jZSA9ICdbJyArIGNvbnRlbnQgKyAnXTogJyArIGhyZWYgKyB0aXRsZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB2YXIgaWQgPSB0aGlzLnJlZmVyZW5jZXMubGVuZ3RoICsgMTtcbiAgICAgICAgcmVwbGFjZW1lbnQgPSAnWycgKyBjb250ZW50ICsgJ11bJyArIGlkICsgJ10nO1xuICAgICAgICByZWZlcmVuY2UgPSAnWycgKyBpZCArICddOiAnICsgaHJlZiArIHRpdGxlO1xuICAgIH1cbiAgICB0aGlzLnJlZmVyZW5jZXMucHVzaChyZWZlcmVuY2UpO1xuICAgIHJldHVybiByZXBsYWNlbWVudDtcbiAgfSxcbiAgcmVmZXJlbmNlczogW10sXG4gIGFwcGVuZDogZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICB2YXIgcmVmZXJlbmNlcyA9ICcnO1xuICAgIGlmICh0aGlzLnJlZmVyZW5jZXMubGVuZ3RoKSB7XG4gICAgICByZWZlcmVuY2VzID0gJ1xcblxcbicgKyB0aGlzLnJlZmVyZW5jZXMuam9pbignXFxuJykgKyAnXFxuXFxuJztcbiAgICAgIHRoaXMucmVmZXJlbmNlcyA9IFtdOyAvLyBSZXNldCByZWZlcmVuY2VzXG4gICAgfVxuICAgIHJldHVybiByZWZlcmVuY2VzO1xuICB9XG59O1xucnVsZXMuZW1waGFzaXMgPSB7XG4gIGZpbHRlcjogWydlbScsICdpJ10sXG4gIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSwgb3B0aW9ucykge1xuICAgIGlmICghY29udGVudC50cmltKCkpIHJldHVybiAnJztcbiAgICByZXR1cm4gb3B0aW9ucy5lbURlbGltaXRlciArIGNvbnRlbnQgKyBvcHRpb25zLmVtRGVsaW1pdGVyO1xuICB9XG59O1xucnVsZXMuc3Ryb25nID0ge1xuICBmaWx0ZXI6IFsnc3Ryb25nJywgJ2InXSxcbiAgcmVwbGFjZW1lbnQ6IGZ1bmN0aW9uIChjb250ZW50LCBub2RlLCBvcHRpb25zKSB7XG4gICAgaWYgKCFjb250ZW50LnRyaW0oKSkgcmV0dXJuICcnO1xuICAgIHJldHVybiBvcHRpb25zLnN0cm9uZ0RlbGltaXRlciArIGNvbnRlbnQgKyBvcHRpb25zLnN0cm9uZ0RlbGltaXRlcjtcbiAgfVxufTtcbnJ1bGVzLmNvZGUgPSB7XG4gIGZpbHRlcjogZnVuY3Rpb24gKG5vZGUpIHtcbiAgICB2YXIgaGFzU2libGluZ3MgPSBub2RlLnByZXZpb3VzU2libGluZyB8fCBub2RlLm5leHRTaWJsaW5nO1xuICAgIHZhciBpc0NvZGVCbG9jayA9IG5vZGUucGFyZW50Tm9kZS5ub2RlTmFtZSA9PT0gJ1BSRScgJiYgIWhhc1NpYmxpbmdzO1xuICAgIHJldHVybiBub2RlLm5vZGVOYW1lID09PSAnQ09ERScgJiYgIWlzQ29kZUJsb2NrO1xuICB9LFxuICByZXBsYWNlbWVudDogZnVuY3Rpb24gKGNvbnRlbnQpIHtcbiAgICBpZiAoIWNvbnRlbnQpIHJldHVybiAnJztcbiAgICBjb250ZW50ID0gY29udGVudC5yZXBsYWNlKC9cXHI/XFxufFxcci9nLCAnICcpO1xuICAgIHZhciBleHRyYVNwYWNlID0gL15gfF4gLio/W14gXS4qICR8YCQvLnRlc3QoY29udGVudCkgPyAnICcgOiAnJztcbiAgICB2YXIgZGVsaW1pdGVyID0gJ2AnO1xuICAgIHZhciBtYXRjaGVzID0gY29udGVudC5tYXRjaCgvYCsvZ20pIHx8IFtdO1xuICAgIHdoaWxlIChtYXRjaGVzLmluZGV4T2YoZGVsaW1pdGVyKSAhPT0gLTEpIGRlbGltaXRlciA9IGRlbGltaXRlciArICdgJztcbiAgICByZXR1cm4gZGVsaW1pdGVyICsgZXh0cmFTcGFjZSArIGNvbnRlbnQgKyBleHRyYVNwYWNlICsgZGVsaW1pdGVyO1xuICB9XG59O1xucnVsZXMuaW1hZ2UgPSB7XG4gIGZpbHRlcjogJ2ltZycsXG4gIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSkge1xuICAgIHZhciBhbHQgPSBlc2NhcGVNYXJrZG93bihjbGVhbkF0dHJpYnV0ZShub2RlLmdldEF0dHJpYnV0ZSgnYWx0JykpKTtcbiAgICB2YXIgc3JjID0gZXNjYXBlTGlua0Rlc3RpbmF0aW9uKG5vZGUuZ2V0QXR0cmlidXRlKCdzcmMnKSB8fCAnJyk7XG4gICAgdmFyIHRpdGxlID0gY2xlYW5BdHRyaWJ1dGUobm9kZS5nZXRBdHRyaWJ1dGUoJ3RpdGxlJykpO1xuICAgIHZhciB0aXRsZVBhcnQgPSB0aXRsZSA/ICcgXCInICsgZXNjYXBlTGlua1RpdGxlKHRpdGxlKSArICdcIicgOiAnJztcbiAgICByZXR1cm4gc3JjID8gJyFbJyArIGFsdCArICddJyArICcoJyArIHNyYyArIHRpdGxlUGFydCArICcpJyA6ICcnO1xuICB9XG59O1xuZnVuY3Rpb24gY2xlYW5BdHRyaWJ1dGUoYXR0cmlidXRlKSB7XG4gIHJldHVybiBhdHRyaWJ1dGUgPyBhdHRyaWJ1dGUucmVwbGFjZSgvKFxcbitcXHMqKSsvZywgJ1xcbicpIDogJyc7XG59XG5mdW5jdGlvbiBlc2NhcGVMaW5rRGVzdGluYXRpb24oZGVzdGluYXRpb24pIHtcbiAgdmFyIGVzY2FwZWQgPSBkZXN0aW5hdGlvbi5yZXBsYWNlKC8oWzw+KCldKS9nLCAnXFxcXCQxJyk7XG4gIHJldHVybiBlc2NhcGVkLmluZGV4T2YoJyAnKSA+PSAwID8gJzwnICsgZXNjYXBlZCArICc+JyA6IGVzY2FwZWQ7XG59XG5mdW5jdGlvbiBlc2NhcGVMaW5rVGl0bGUodGl0bGUpIHtcbiAgcmV0dXJuIHRpdGxlLnJlcGxhY2UoL1wiL2csICdcXFxcXCInKTtcbn1cblxuLyoqXG4gKiBNYW5hZ2VzIGEgY29sbGVjdGlvbiBvZiBydWxlcyB1c2VkIHRvIGNvbnZlcnQgSFRNTCB0byBNYXJrZG93blxuICovXG5cbmZ1bmN0aW9uIFJ1bGVzKG9wdGlvbnMpIHtcbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgdGhpcy5fa2VlcCA9IFtdO1xuICB0aGlzLl9yZW1vdmUgPSBbXTtcbiAgdGhpcy5ibGFua1J1bGUgPSB7XG4gICAgcmVwbGFjZW1lbnQ6IG9wdGlvbnMuYmxhbmtSZXBsYWNlbWVudFxuICB9O1xuICB0aGlzLmtlZXBSZXBsYWNlbWVudCA9IG9wdGlvbnMua2VlcFJlcGxhY2VtZW50O1xuICB0aGlzLmRlZmF1bHRSdWxlID0ge1xuICAgIHJlcGxhY2VtZW50OiBvcHRpb25zLmRlZmF1bHRSZXBsYWNlbWVudFxuICB9O1xuICB0aGlzLmFycmF5ID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvcHRpb25zLnJ1bGVzKSB0aGlzLmFycmF5LnB1c2gob3B0aW9ucy5ydWxlc1trZXldKTtcbn1cblJ1bGVzLnByb3RvdHlwZSA9IHtcbiAgYWRkOiBmdW5jdGlvbiAoa2V5LCBydWxlKSB7XG4gICAgdGhpcy5hcnJheS51bnNoaWZ0KHJ1bGUpO1xuICB9LFxuICBrZWVwOiBmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgdGhpcy5fa2VlcC51bnNoaWZ0KHtcbiAgICAgIGZpbHRlcjogZmlsdGVyLFxuICAgICAgcmVwbGFjZW1lbnQ6IHRoaXMua2VlcFJlcGxhY2VtZW50XG4gICAgfSk7XG4gIH0sXG4gIHJlbW92ZTogZnVuY3Rpb24gKGZpbHRlcikge1xuICAgIHRoaXMuX3JlbW92ZS51bnNoaWZ0KHtcbiAgICAgIGZpbHRlcjogZmlsdGVyLFxuICAgICAgcmVwbGFjZW1lbnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuICAgIH0pO1xuICB9LFxuICBmb3JOb2RlOiBmdW5jdGlvbiAobm9kZSkge1xuICAgIGlmIChub2RlLmlzQmxhbmspIHJldHVybiB0aGlzLmJsYW5rUnVsZTtcbiAgICB2YXIgcnVsZTtcbiAgICBpZiAocnVsZSA9IGZpbmRSdWxlKHRoaXMuYXJyYXksIG5vZGUsIHRoaXMub3B0aW9ucykpIHJldHVybiBydWxlO1xuICAgIGlmIChydWxlID0gZmluZFJ1bGUodGhpcy5fa2VlcCwgbm9kZSwgdGhpcy5vcHRpb25zKSkgcmV0dXJuIHJ1bGU7XG4gICAgaWYgKHJ1bGUgPSBmaW5kUnVsZSh0aGlzLl9yZW1vdmUsIG5vZGUsIHRoaXMub3B0aW9ucykpIHJldHVybiBydWxlO1xuICAgIHJldHVybiB0aGlzLmRlZmF1bHRSdWxlO1xuICB9LFxuICBmb3JFYWNoOiBmdW5jdGlvbiAoZm4pIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYXJyYXkubGVuZ3RoOyBpKyspIGZuKHRoaXMuYXJyYXlbaV0sIGkpO1xuICB9XG59O1xuZnVuY3Rpb24gZmluZFJ1bGUocnVsZXMsIG5vZGUsIG9wdGlvbnMpIHtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBydWxlcy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBydWxlID0gcnVsZXNbaV07XG4gICAgaWYgKGZpbHRlclZhbHVlKHJ1bGUsIG5vZGUsIG9wdGlvbnMpKSByZXR1cm4gcnVsZTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gZmlsdGVyVmFsdWUocnVsZSwgbm9kZSwgb3B0aW9ucykge1xuICB2YXIgZmlsdGVyID0gcnVsZS5maWx0ZXI7XG4gIGlmICh0eXBlb2YgZmlsdGVyID09PSAnc3RyaW5nJykge1xuICAgIGlmIChmaWx0ZXIgPT09IG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSkgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShmaWx0ZXIpKSB7XG4gICAgaWYgKGZpbHRlci5pbmRleE9mKG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSkgPiAtMSkgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGZpbHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGlmIChmaWx0ZXIuY2FsbChydWxlLCBub2RlLCBvcHRpb25zKSkgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignYGZpbHRlcmAgbmVlZHMgdG8gYmUgYSBzdHJpbmcsIGFycmF5LCBvciBmdW5jdGlvbicpO1xuICB9XG59XG5cbi8qKlxuICogVGhlIGNvbGxhcHNlV2hpdGVzcGFjZSBmdW5jdGlvbiBpcyBhZGFwdGVkIGZyb20gY29sbGFwc2Utd2hpdGVzcGFjZVxuICogYnkgTHVjIFRoZXZlbmFyZC5cbiAqXG4gKiBUaGUgTUlUIExpY2Vuc2UgKE1JVClcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTQgTHVjIFRoZXZlbmFyZCA8bHVjdGhldmVuYXJkQGdtYWlsLmNvbT5cbiAqXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4gKlxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuICpcbiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gKiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTlxuICogVEhFIFNPRlRXQVJFLlxuICovXG5cbi8qKlxuICogY29sbGFwc2VXaGl0ZXNwYWNlKG9wdGlvbnMpIHJlbW92ZXMgZXh0cmFuZW91cyB3aGl0ZXNwYWNlIGZyb20gYW4gdGhlIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gY29sbGFwc2VXaGl0ZXNwYWNlKG9wdGlvbnMpIHtcbiAgdmFyIGVsZW1lbnQgPSBvcHRpb25zLmVsZW1lbnQ7XG4gIHZhciBpc0Jsb2NrID0gb3B0aW9ucy5pc0Jsb2NrO1xuICB2YXIgaXNWb2lkID0gb3B0aW9ucy5pc1ZvaWQ7XG4gIHZhciBpc1ByZSA9IG9wdGlvbnMuaXNQcmUgfHwgZnVuY3Rpb24gKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gJ1BSRSc7XG4gIH07XG4gIGlmICghZWxlbWVudC5maXJzdENoaWxkIHx8IGlzUHJlKGVsZW1lbnQpKSByZXR1cm47XG4gIHZhciBwcmV2VGV4dCA9IG51bGw7XG4gIHZhciBrZWVwTGVhZGluZ1dzID0gZmFsc2U7XG4gIHZhciBwcmV2ID0gbnVsbDtcbiAgdmFyIG5vZGUgPSBuZXh0KHByZXYsIGVsZW1lbnQsIGlzUHJlKTtcbiAgd2hpbGUgKG5vZGUgIT09IGVsZW1lbnQpIHtcbiAgICBpZiAobm9kZS5ub2RlVHlwZSA9PT0gMyB8fCBub2RlLm5vZGVUeXBlID09PSA0KSB7XG4gICAgICAvLyBOb2RlLlRFWFRfTk9ERSBvciBOb2RlLkNEQVRBX1NFQ1RJT05fTk9ERVxuICAgICAgdmFyIHRleHQgPSBub2RlLmRhdGEucmVwbGFjZSgvWyBcXHJcXG5cXHRdKy9nLCAnICcpO1xuICAgICAgaWYgKCghcHJldlRleHQgfHwgLyAkLy50ZXN0KHByZXZUZXh0LmRhdGEpKSAmJiAha2VlcExlYWRpbmdXcyAmJiB0ZXh0WzBdID09PSAnICcpIHtcbiAgICAgICAgdGV4dCA9IHRleHQuc3Vic3RyKDEpO1xuICAgICAgfVxuXG4gICAgICAvLyBgdGV4dGAgbWlnaHQgYmUgZW1wdHkgYXQgdGhpcyBwb2ludC5cbiAgICAgIGlmICghdGV4dCkge1xuICAgICAgICBub2RlID0gcmVtb3ZlKG5vZGUpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIG5vZGUuZGF0YSA9IHRleHQ7XG4gICAgICBwcmV2VGV4dCA9IG5vZGU7XG4gICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09PSAxKSB7XG4gICAgICAvLyBOb2RlLkVMRU1FTlRfTk9ERVxuICAgICAgaWYgKGlzQmxvY2sobm9kZSkgfHwgbm9kZS5ub2RlTmFtZSA9PT0gJ0JSJykge1xuICAgICAgICBpZiAocHJldlRleHQpIHtcbiAgICAgICAgICBwcmV2VGV4dC5kYXRhID0gcHJldlRleHQuZGF0YS5yZXBsYWNlKC8gJC8sICcnKTtcbiAgICAgICAgfVxuICAgICAgICBwcmV2VGV4dCA9IG51bGw7XG4gICAgICAgIGtlZXBMZWFkaW5nV3MgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAoaXNWb2lkKG5vZGUpIHx8IGlzUHJlKG5vZGUpKSB7XG4gICAgICAgIC8vIEF2b2lkIHRyaW1taW5nIHNwYWNlIGFyb3VuZCBub24tYmxvY2ssIG5vbi1CUiB2b2lkIGVsZW1lbnRzIGFuZCBpbmxpbmUgUFJFLlxuICAgICAgICBwcmV2VGV4dCA9IG51bGw7XG4gICAgICAgIGtlZXBMZWFkaW5nV3MgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmIChwcmV2VGV4dCkge1xuICAgICAgICAvLyBEcm9wIHByb3RlY3Rpb24gaWYgc2V0IHByZXZpb3VzbHkuXG4gICAgICAgIGtlZXBMZWFkaW5nV3MgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZSA9IHJlbW92ZShub2RlKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB2YXIgbmV4dE5vZGUgPSBuZXh0KHByZXYsIG5vZGUsIGlzUHJlKTtcbiAgICBwcmV2ID0gbm9kZTtcbiAgICBub2RlID0gbmV4dE5vZGU7XG4gIH1cbiAgaWYgKHByZXZUZXh0KSB7XG4gICAgcHJldlRleHQuZGF0YSA9IHByZXZUZXh0LmRhdGEucmVwbGFjZSgvICQvLCAnJyk7XG4gICAgaWYgKCFwcmV2VGV4dC5kYXRhKSB7XG4gICAgICByZW1vdmUocHJldlRleHQpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIHJlbW92ZShub2RlKSByZW1vdmVzIHRoZSBnaXZlbiBub2RlIGZyb20gdGhlIERPTSBhbmQgcmV0dXJucyB0aGVcbiAqIG5leHQgbm9kZSBpbiB0aGUgc2VxdWVuY2UuXG4gKlxuICogQHBhcmFtIHtOb2RlfSBub2RlXG4gKiBAcmV0dXJuIHtOb2RlfSBub2RlXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZShub2RlKSB7XG4gIHZhciBuZXh0ID0gbm9kZS5uZXh0U2libGluZyB8fCBub2RlLnBhcmVudE5vZGU7XG4gIG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChub2RlKTtcbiAgcmV0dXJuIG5leHQ7XG59XG5cbi8qKlxuICogbmV4dChwcmV2LCBjdXJyZW50LCBpc1ByZSkgcmV0dXJucyB0aGUgbmV4dCBub2RlIGluIHRoZSBzZXF1ZW5jZSwgZ2l2ZW4gdGhlXG4gKiBjdXJyZW50IGFuZCBwcmV2aW91cyBub2Rlcy5cbiAqXG4gKiBAcGFyYW0ge05vZGV9IHByZXZcbiAqIEBwYXJhbSB7Tm9kZX0gY3VycmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXNQcmVcbiAqIEByZXR1cm4ge05vZGV9XG4gKi9cbmZ1bmN0aW9uIG5leHQocHJldiwgY3VycmVudCwgaXNQcmUpIHtcbiAgaWYgKHByZXYgJiYgcHJldi5wYXJlbnROb2RlID09PSBjdXJyZW50IHx8IGlzUHJlKGN1cnJlbnQpKSB7XG4gICAgcmV0dXJuIGN1cnJlbnQubmV4dFNpYmxpbmcgfHwgY3VycmVudC5wYXJlbnROb2RlO1xuICB9XG4gIHJldHVybiBjdXJyZW50LmZpcnN0Q2hpbGQgfHwgY3VycmVudC5uZXh0U2libGluZyB8fCBjdXJyZW50LnBhcmVudE5vZGU7XG59XG5cbi8qXG4gKiBTZXQgdXAgd2luZG93IGZvciBOb2RlLmpzXG4gKi9cblxudmFyIHJvb3QgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHt9O1xuXG4vKlxuICogUGFyc2luZyBIVE1MIHN0cmluZ3NcbiAqL1xuXG5mdW5jdGlvbiBjYW5QYXJzZUhUTUxOYXRpdmVseSgpIHtcbiAgdmFyIFBhcnNlciA9IHJvb3QuRE9NUGFyc2VyO1xuICB2YXIgY2FuUGFyc2UgPSBmYWxzZTtcblxuICAvLyBBZGFwdGVkIGZyb20gaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vMTEyOTAzMVxuICAvLyBGaXJlZm94L09wZXJhL0lFIHRocm93IGVycm9ycyBvbiB1bnN1cHBvcnRlZCB0eXBlc1xuICB0cnkge1xuICAgIC8vIFdlYktpdCByZXR1cm5zIG51bGwgb24gdW5zdXBwb3J0ZWQgdHlwZXNcbiAgICBpZiAobmV3IFBhcnNlcigpLnBhcnNlRnJvbVN0cmluZygnJywgJ3RleHQvaHRtbCcpKSB7XG4gICAgICBjYW5QYXJzZSA9IHRydWU7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7fVxuICByZXR1cm4gY2FuUGFyc2U7XG59XG5mdW5jdGlvbiBjcmVhdGVIVE1MUGFyc2VyKCkge1xuICB2YXIgUGFyc2VyID0gZnVuY3Rpb24gKCkge307XG4gIHtcbiAgICBpZiAoc2hvdWxkVXNlQWN0aXZlWCgpKSB7XG4gICAgICBQYXJzZXIucHJvdG90eXBlLnBhcnNlRnJvbVN0cmluZyA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICAgICAgdmFyIGRvYyA9IG5ldyB3aW5kb3cuQWN0aXZlWE9iamVjdCgnaHRtbGZpbGUnKTtcbiAgICAgICAgZG9jLmRlc2lnbk1vZGUgPSAnb24nOyAvLyBkaXNhYmxlIG9uLXBhZ2Ugc2NyaXB0c1xuICAgICAgICBkb2Mub3BlbigpO1xuICAgICAgICBkb2Mud3JpdGUoc3RyaW5nKTtcbiAgICAgICAgZG9jLmNsb3NlKCk7XG4gICAgICAgIHJldHVybiBkb2M7XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBQYXJzZXIucHJvdG90eXBlLnBhcnNlRnJvbVN0cmluZyA9IGZ1bmN0aW9uIChzdHJpbmcpIHtcbiAgICAgICAgdmFyIGRvYyA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCgnJyk7XG4gICAgICAgIGRvYy5vcGVuKCk7XG4gICAgICAgIGRvYy53cml0ZShzdHJpbmcpO1xuICAgICAgICBkb2MuY2xvc2UoKTtcbiAgICAgICAgcmV0dXJuIGRvYztcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiBQYXJzZXI7XG59XG5mdW5jdGlvbiBzaG91bGRVc2VBY3RpdmVYKCkge1xuICB2YXIgdXNlQWN0aXZlWCA9IGZhbHNlO1xuICB0cnkge1xuICAgIGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCgnJykub3BlbigpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKHJvb3QuQWN0aXZlWE9iamVjdCkgdXNlQWN0aXZlWCA9IHRydWU7XG4gIH1cbiAgcmV0dXJuIHVzZUFjdGl2ZVg7XG59XG52YXIgSFRNTFBhcnNlciA9IGNhblBhcnNlSFRNTE5hdGl2ZWx5KCkgPyByb290LkRPTVBhcnNlciA6IGNyZWF0ZUhUTUxQYXJzZXIoKTtcblxuZnVuY3Rpb24gUm9vdE5vZGUoaW5wdXQsIG9wdGlvbnMpIHtcbiAgdmFyIHJvb3Q7XG4gIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIGRvYyA9IGh0bWxQYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcoXG4gICAgLy8gRE9NIHBhcnNlcnMgYXJyYW5nZSBlbGVtZW50cyBpbiB0aGUgPGhlYWQ+IGFuZCA8Ym9keT4uXG4gICAgLy8gV3JhcHBpbmcgaW4gYSBjdXN0b20gZWxlbWVudCBlbnN1cmVzIGVsZW1lbnRzIGFyZSByZWxpYWJseSBhcnJhbmdlZCBpblxuICAgIC8vIGEgc2luZ2xlIGVsZW1lbnQuXG4gICAgJzx4LXR1cm5kb3duIGlkPVwidHVybmRvd24tcm9vdFwiPicgKyBpbnB1dCArICc8L3gtdHVybmRvd24+JywgJ3RleHQvaHRtbCcpO1xuICAgIHJvb3QgPSBkb2MuZ2V0RWxlbWVudEJ5SWQoJ3R1cm5kb3duLXJvb3QnKTtcbiAgfSBlbHNlIHtcbiAgICByb290ID0gaW5wdXQuY2xvbmVOb2RlKHRydWUpO1xuICB9XG4gIGNvbGxhcHNlV2hpdGVzcGFjZSh7XG4gICAgZWxlbWVudDogcm9vdCxcbiAgICBpc0Jsb2NrOiBpc0Jsb2NrLFxuICAgIGlzVm9pZDogaXNWb2lkLFxuICAgIGlzUHJlOiBvcHRpb25zLnByZWZvcm1hdHRlZENvZGUgPyBpc1ByZU9yQ29kZSA6IG51bGxcbiAgfSk7XG4gIHJldHVybiByb290O1xufVxudmFyIF9odG1sUGFyc2VyO1xuZnVuY3Rpb24gaHRtbFBhcnNlcigpIHtcbiAgX2h0bWxQYXJzZXIgPSBfaHRtbFBhcnNlciB8fCBuZXcgSFRNTFBhcnNlcigpO1xuICByZXR1cm4gX2h0bWxQYXJzZXI7XG59XG5mdW5jdGlvbiBpc1ByZU9yQ29kZShub2RlKSB7XG4gIHJldHVybiBub2RlLm5vZGVOYW1lID09PSAnUFJFJyB8fCBub2RlLm5vZGVOYW1lID09PSAnQ09ERSc7XG59XG5cbmZ1bmN0aW9uIE5vZGUobm9kZSwgb3B0aW9ucykge1xuICBub2RlLmlzQmxvY2sgPSBpc0Jsb2NrKG5vZGUpO1xuICBub2RlLmlzQ29kZSA9IG5vZGUubm9kZU5hbWUgPT09ICdDT0RFJyB8fCBub2RlLnBhcmVudE5vZGUuaXNDb2RlO1xuICBub2RlLmlzQmxhbmsgPSBpc0JsYW5rKG5vZGUpO1xuICBub2RlLmZsYW5raW5nV2hpdGVzcGFjZSA9IGZsYW5raW5nV2hpdGVzcGFjZShub2RlLCBvcHRpb25zKTtcbiAgcmV0dXJuIG5vZGU7XG59XG5mdW5jdGlvbiBpc0JsYW5rKG5vZGUpIHtcbiAgcmV0dXJuICFpc1ZvaWQobm9kZSkgJiYgIWlzTWVhbmluZ2Z1bFdoZW5CbGFuayhub2RlKSAmJiAvXlxccyokL2kudGVzdChub2RlLnRleHRDb250ZW50KSAmJiAhaGFzVm9pZChub2RlKSAmJiAhaGFzTWVhbmluZ2Z1bFdoZW5CbGFuayhub2RlKTtcbn1cbmZ1bmN0aW9uIGZsYW5raW5nV2hpdGVzcGFjZShub2RlLCBvcHRpb25zKSB7XG4gIGlmIChub2RlLmlzQmxvY2sgfHwgb3B0aW9ucy5wcmVmb3JtYXR0ZWRDb2RlICYmIG5vZGUuaXNDb2RlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxlYWRpbmc6ICcnLFxuICAgICAgdHJhaWxpbmc6ICcnXG4gICAgfTtcbiAgfVxuICB2YXIgZWRnZXMgPSBlZGdlV2hpdGVzcGFjZShub2RlLnRleHRDb250ZW50KTtcblxuICAvLyBhYmFuZG9uIGxlYWRpbmcgQVNDSUkgV1MgaWYgbGVmdC1mbGFua2VkIGJ5IEFTQ0lJIFdTXG4gIGlmIChlZGdlcy5sZWFkaW5nQXNjaWkgJiYgaXNGbGFua2VkQnlXaGl0ZXNwYWNlKCdsZWZ0Jywgbm9kZSwgb3B0aW9ucykpIHtcbiAgICBlZGdlcy5sZWFkaW5nID0gZWRnZXMubGVhZGluZ05vbkFzY2lpO1xuICB9XG5cbiAgLy8gYWJhbmRvbiB0cmFpbGluZyBBU0NJSSBXUyBpZiByaWdodC1mbGFua2VkIGJ5IEFTQ0lJIFdTXG4gIGlmIChlZGdlcy50cmFpbGluZ0FzY2lpICYmIGlzRmxhbmtlZEJ5V2hpdGVzcGFjZSgncmlnaHQnLCBub2RlLCBvcHRpb25zKSkge1xuICAgIGVkZ2VzLnRyYWlsaW5nID0gZWRnZXMudHJhaWxpbmdOb25Bc2NpaTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGxlYWRpbmc6IGVkZ2VzLmxlYWRpbmcsXG4gICAgdHJhaWxpbmc6IGVkZ2VzLnRyYWlsaW5nXG4gIH07XG59XG5mdW5jdGlvbiBlZGdlV2hpdGVzcGFjZShzdHJpbmcpIHtcbiAgdmFyIG0gPSBzdHJpbmcubWF0Y2goL14oKFsgXFx0XFxyXFxuXSopKFxccyopKSg/Oig/PVxcUylbXFxzXFxTXSpcXFMpPygoXFxzKj8pKFsgXFx0XFxyXFxuXSopKSQvKTtcbiAgcmV0dXJuIHtcbiAgICBsZWFkaW5nOiBtWzFdLFxuICAgIC8vIHdob2xlIHN0cmluZyBmb3Igd2hpdGVzcGFjZS1vbmx5IHN0cmluZ3NcbiAgICBsZWFkaW5nQXNjaWk6IG1bMl0sXG4gICAgbGVhZGluZ05vbkFzY2lpOiBtWzNdLFxuICAgIHRyYWlsaW5nOiBtWzRdLFxuICAgIC8vIGVtcHR5IGZvciB3aGl0ZXNwYWNlLW9ubHkgc3RyaW5nc1xuICAgIHRyYWlsaW5nTm9uQXNjaWk6IG1bNV0sXG4gICAgdHJhaWxpbmdBc2NpaTogbVs2XVxuICB9O1xufVxuZnVuY3Rpb24gaXNGbGFua2VkQnlXaGl0ZXNwYWNlKHNpZGUsIG5vZGUsIG9wdGlvbnMpIHtcbiAgdmFyIHNpYmxpbmc7XG4gIHZhciByZWdFeHA7XG4gIHZhciBpc0ZsYW5rZWQ7XG4gIGlmIChzaWRlID09PSAnbGVmdCcpIHtcbiAgICBzaWJsaW5nID0gbm9kZS5wcmV2aW91c1NpYmxpbmc7XG4gICAgcmVnRXhwID0gLyAkLztcbiAgfSBlbHNlIHtcbiAgICBzaWJsaW5nID0gbm9kZS5uZXh0U2libGluZztcbiAgICByZWdFeHAgPSAvXiAvO1xuICB9XG4gIGlmIChzaWJsaW5nKSB7XG4gICAgaWYgKHNpYmxpbmcubm9kZVR5cGUgPT09IDMpIHtcbiAgICAgIGlzRmxhbmtlZCA9IHJlZ0V4cC50ZXN0KHNpYmxpbmcubm9kZVZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKG9wdGlvbnMucHJlZm9ybWF0dGVkQ29kZSAmJiBzaWJsaW5nLm5vZGVOYW1lID09PSAnQ09ERScpIHtcbiAgICAgIGlzRmxhbmtlZCA9IGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoc2libGluZy5ub2RlVHlwZSA9PT0gMSAmJiAhaXNCbG9jayhzaWJsaW5nKSkge1xuICAgICAgaXNGbGFua2VkID0gcmVnRXhwLnRlc3Qoc2libGluZy50ZXh0Q29udGVudCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBpc0ZsYW5rZWQ7XG59XG5cbnZhciByZWR1Y2UgPSBBcnJheS5wcm90b3R5cGUucmVkdWNlO1xuZnVuY3Rpb24gVHVybmRvd25TZXJ2aWNlKG9wdGlvbnMpIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFR1cm5kb3duU2VydmljZSkpIHJldHVybiBuZXcgVHVybmRvd25TZXJ2aWNlKG9wdGlvbnMpO1xuICB2YXIgZGVmYXVsdHMgPSB7XG4gICAgcnVsZXM6IHJ1bGVzLFxuICAgIGhlYWRpbmdTdHlsZTogJ3NldGV4dCcsXG4gICAgaHI6ICcqICogKicsXG4gICAgYnVsbGV0TGlzdE1hcmtlcjogJyonLFxuICAgIGNvZGVCbG9ja1N0eWxlOiAnaW5kZW50ZWQnLFxuICAgIGZlbmNlOiAnYGBgJyxcbiAgICBlbURlbGltaXRlcjogJ18nLFxuICAgIHN0cm9uZ0RlbGltaXRlcjogJyoqJyxcbiAgICBsaW5rU3R5bGU6ICdpbmxpbmVkJyxcbiAgICBsaW5rUmVmZXJlbmNlU3R5bGU6ICdmdWxsJyxcbiAgICBicjogJyAgJyxcbiAgICBwcmVmb3JtYXR0ZWRDb2RlOiBmYWxzZSxcbiAgICBibGFua1JlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSkge1xuICAgICAgcmV0dXJuIG5vZGUuaXNCbG9jayA/ICdcXG5cXG4nIDogJyc7XG4gICAgfSxcbiAgICBrZWVwUmVwbGFjZW1lbnQ6IGZ1bmN0aW9uIChjb250ZW50LCBub2RlKSB7XG4gICAgICByZXR1cm4gbm9kZS5pc0Jsb2NrID8gJ1xcblxcbicgKyBub2RlLm91dGVySFRNTCArICdcXG5cXG4nIDogbm9kZS5vdXRlckhUTUw7XG4gICAgfSxcbiAgICBkZWZhdWx0UmVwbGFjZW1lbnQ6IGZ1bmN0aW9uIChjb250ZW50LCBub2RlKSB7XG4gICAgICByZXR1cm4gbm9kZS5pc0Jsb2NrID8gJ1xcblxcbicgKyBjb250ZW50ICsgJ1xcblxcbicgOiBjb250ZW50O1xuICAgIH1cbiAgfTtcbiAgdGhpcy5vcHRpb25zID0gZXh0ZW5kKHt9LCBkZWZhdWx0cywgb3B0aW9ucyk7XG4gIHRoaXMucnVsZXMgPSBuZXcgUnVsZXModGhpcy5vcHRpb25zKTtcbn1cblR1cm5kb3duU2VydmljZS5wcm90b3R5cGUgPSB7XG4gIC8qKlxuICAgKiBUaGUgZW50cnkgcG9pbnQgZm9yIGNvbnZlcnRpbmcgYSBzdHJpbmcgb3IgRE9NIG5vZGUgdG8gTWFya2Rvd25cbiAgICogQHB1YmxpY1xuICAgKiBAcGFyYW0ge1N0cmluZ3xIVE1MRWxlbWVudH0gaW5wdXQgVGhlIHN0cmluZyBvciBET00gbm9kZSB0byBjb252ZXJ0XG4gICAqIEByZXR1cm5zIEEgTWFya2Rvd24gcmVwcmVzZW50YXRpb24gb2YgdGhlIGlucHV0XG4gICAqIEB0eXBlIFN0cmluZ1xuICAgKi9cblxuICB0dXJuZG93bjogZnVuY3Rpb24gKGlucHV0KSB7XG4gICAgaWYgKCFjYW5Db252ZXJ0KGlucHV0KSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihpbnB1dCArICcgaXMgbm90IGEgc3RyaW5nLCBvciBhbiBlbGVtZW50L2RvY3VtZW50L2ZyYWdtZW50IG5vZGUuJyk7XG4gICAgfVxuICAgIGlmIChpbnB1dCA9PT0gJycpIHJldHVybiAnJztcbiAgICB2YXIgb3V0cHV0ID0gcHJvY2Vzcy5jYWxsKHRoaXMsIG5ldyBSb290Tm9kZShpbnB1dCwgdGhpcy5vcHRpb25zKSk7XG4gICAgcmV0dXJuIHBvc3RQcm9jZXNzLmNhbGwodGhpcywgb3V0cHV0KTtcbiAgfSxcbiAgLyoqXG4gICAqIEFkZCBvbmUgb3IgbW9yZSBwbHVnaW5zXG4gICAqIEBwdWJsaWNcbiAgICogQHBhcmFtIHtGdW5jdGlvbnxBcnJheX0gcGx1Z2luIFRoZSBwbHVnaW4gb3IgYXJyYXkgb2YgcGx1Z2lucyB0byBhZGRcbiAgICogQHJldHVybnMgVGhlIFR1cm5kb3duIGluc3RhbmNlIGZvciBjaGFpbmluZ1xuICAgKiBAdHlwZSBPYmplY3RcbiAgICovXG5cbiAgdXNlOiBmdW5jdGlvbiAocGx1Z2luKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGx1Z2luKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwbHVnaW4ubGVuZ3RoOyBpKyspIHRoaXMudXNlKHBsdWdpbltpXSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGx1Z2luID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwbHVnaW4odGhpcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3BsdWdpbiBtdXN0IGJlIGEgRnVuY3Rpb24gb3IgYW4gQXJyYXkgb2YgRnVuY3Rpb25zJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICAvKipcbiAgICogQWRkcyBhIHJ1bGVcbiAgICogQHB1YmxpY1xuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IFRoZSB1bmlxdWUga2V5IG9mIHRoZSBydWxlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBydWxlIFRoZSBydWxlXG4gICAqIEByZXR1cm5zIFRoZSBUdXJuZG93biBpbnN0YW5jZSBmb3IgY2hhaW5pbmdcbiAgICogQHR5cGUgT2JqZWN0XG4gICAqL1xuXG4gIGFkZFJ1bGU6IGZ1bmN0aW9uIChrZXksIHJ1bGUpIHtcbiAgICB0aGlzLnJ1bGVzLmFkZChrZXksIHJ1bGUpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICAvKipcbiAgICogS2VlcCBhIG5vZGUgKGFzIEhUTUwpIHRoYXQgbWF0Y2hlcyB0aGUgZmlsdGVyXG4gICAqIEBwdWJsaWNcbiAgICogQHBhcmFtIHtTdHJpbmd8QXJyYXl8RnVuY3Rpb259IGZpbHRlciBUaGUgdW5pcXVlIGtleSBvZiB0aGUgcnVsZVxuICAgKiBAcmV0dXJucyBUaGUgVHVybmRvd24gaW5zdGFuY2UgZm9yIGNoYWluaW5nXG4gICAqIEB0eXBlIE9iamVjdFxuICAgKi9cblxuICBrZWVwOiBmdW5jdGlvbiAoZmlsdGVyKSB7XG4gICAgdGhpcy5ydWxlcy5rZWVwKGZpbHRlcik7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIC8qKlxuICAgKiBSZW1vdmUgYSBub2RlIHRoYXQgbWF0Y2hlcyB0aGUgZmlsdGVyXG4gICAqIEBwdWJsaWNcbiAgICogQHBhcmFtIHtTdHJpbmd8QXJyYXl8RnVuY3Rpb259IGZpbHRlciBUaGUgdW5pcXVlIGtleSBvZiB0aGUgcnVsZVxuICAgKiBAcmV0dXJucyBUaGUgVHVybmRvd24gaW5zdGFuY2UgZm9yIGNoYWluaW5nXG4gICAqIEB0eXBlIE9iamVjdFxuICAgKi9cblxuICByZW1vdmU6IGZ1bmN0aW9uIChmaWx0ZXIpIHtcbiAgICB0aGlzLnJ1bGVzLnJlbW92ZShmaWx0ZXIpO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICAvKipcbiAgICogRXNjYXBlcyBNYXJrZG93biBzeW50YXhcbiAgICogQHB1YmxpY1xuICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyaW5nIFRoZSBzdHJpbmcgdG8gZXNjYXBlXG4gICAqIEByZXR1cm5zIEEgc3RyaW5nIHdpdGggTWFya2Rvd24gc3ludGF4IGVzY2FwZWRcbiAgICogQHR5cGUgU3RyaW5nXG4gICAqL1xuXG4gIGVzY2FwZTogZnVuY3Rpb24gKHN0cmluZykge1xuICAgIHJldHVybiBlc2NhcGVNYXJrZG93bihzdHJpbmcpO1xuICB9XG59O1xuXG4vKipcbiAqIFJlZHVjZXMgYSBET00gbm9kZSBkb3duIHRvIGl0cyBNYXJrZG93biBzdHJpbmcgZXF1aXZhbGVudFxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IHBhcmVudE5vZGUgVGhlIG5vZGUgdG8gY29udmVydFxuICogQHJldHVybnMgQSBNYXJrZG93biByZXByZXNlbnRhdGlvbiBvZiB0aGUgbm9kZVxuICogQHR5cGUgU3RyaW5nXG4gKi9cblxuZnVuY3Rpb24gcHJvY2VzcyhwYXJlbnROb2RlKSB7XG4gIHZhciBzZWxmID0gdGhpcztcbiAgcmV0dXJuIHJlZHVjZS5jYWxsKHBhcmVudE5vZGUuY2hpbGROb2RlcywgZnVuY3Rpb24gKG91dHB1dCwgbm9kZSkge1xuICAgIG5vZGUgPSBuZXcgTm9kZShub2RlLCBzZWxmLm9wdGlvbnMpO1xuICAgIHZhciByZXBsYWNlbWVudCA9ICcnO1xuICAgIGlmIChub2RlLm5vZGVUeXBlID09PSAzKSB7XG4gICAgICByZXBsYWNlbWVudCA9IG5vZGUuaXNDb2RlID8gbm9kZS5ub2RlVmFsdWUgOiBzZWxmLmVzY2FwZShub2RlLm5vZGVWYWx1ZSk7XG4gICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09PSAxKSB7XG4gICAgICByZXBsYWNlbWVudCA9IHJlcGxhY2VtZW50Rm9yTm9kZS5jYWxsKHNlbGYsIG5vZGUpO1xuICAgIH1cbiAgICByZXR1cm4gam9pbihvdXRwdXQsIHJlcGxhY2VtZW50KTtcbiAgfSwgJycpO1xufVxuXG4vKipcbiAqIEFwcGVuZHMgc3RyaW5ncyBhcyBlYWNoIHJ1bGUgcmVxdWlyZXMgYW5kIHRyaW1zIHRoZSBvdXRwdXRcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge1N0cmluZ30gb3V0cHV0IFRoZSBjb252ZXJzaW9uIG91dHB1dFxuICogQHJldHVybnMgQSB0cmltbWVkIHZlcnNpb24gb2YgdGhlIG91cHV0XG4gKiBAdHlwZSBTdHJpbmdcbiAqL1xuXG5mdW5jdGlvbiBwb3N0UHJvY2VzcyhvdXRwdXQpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLnJ1bGVzLmZvckVhY2goZnVuY3Rpb24gKHJ1bGUpIHtcbiAgICBpZiAodHlwZW9mIHJ1bGUuYXBwZW5kID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBvdXRwdXQgPSBqb2luKG91dHB1dCwgcnVsZS5hcHBlbmQoc2VsZi5vcHRpb25zKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dHB1dC5yZXBsYWNlKC9eW1xcdFxcclxcbl0rLywgJycpLnJlcGxhY2UoL1tcXHRcXHJcXG5cXHNdKyQvLCAnJyk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYW4gZWxlbWVudCBub2RlIHRvIGl0cyBNYXJrZG93biBlcXVpdmFsZW50XG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbm9kZSBUaGUgbm9kZSB0byBjb252ZXJ0XG4gKiBAcmV0dXJucyBBIE1hcmtkb3duIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBub2RlXG4gKiBAdHlwZSBTdHJpbmdcbiAqL1xuXG5mdW5jdGlvbiByZXBsYWNlbWVudEZvck5vZGUobm9kZSkge1xuICB2YXIgcnVsZSA9IHRoaXMucnVsZXMuZm9yTm9kZShub2RlKTtcbiAgdmFyIGNvbnRlbnQgPSBwcm9jZXNzLmNhbGwodGhpcywgbm9kZSk7XG4gIHZhciB3aGl0ZXNwYWNlID0gbm9kZS5mbGFua2luZ1doaXRlc3BhY2U7XG4gIGlmICh3aGl0ZXNwYWNlLmxlYWRpbmcgfHwgd2hpdGVzcGFjZS50cmFpbGluZykgY29udGVudCA9IGNvbnRlbnQudHJpbSgpO1xuICByZXR1cm4gd2hpdGVzcGFjZS5sZWFkaW5nICsgcnVsZS5yZXBsYWNlbWVudChjb250ZW50LCBub2RlLCB0aGlzLm9wdGlvbnMpICsgd2hpdGVzcGFjZS50cmFpbGluZztcbn1cblxuLyoqXG4gKiBKb2lucyByZXBsYWNlbWVudCB0byB0aGUgY3VycmVudCBvdXRwdXQgd2l0aCBhcHByb3ByaWF0ZSBudW1iZXIgb2YgbmV3IGxpbmVzXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtTdHJpbmd9IG91dHB1dCBUaGUgY3VycmVudCBjb252ZXJzaW9uIG91dHB1dFxuICogQHBhcmFtIHtTdHJpbmd9IHJlcGxhY2VtZW50IFRoZSBzdHJpbmcgdG8gYXBwZW5kIHRvIHRoZSBvdXRwdXRcbiAqIEByZXR1cm5zIEpvaW5lZCBvdXRwdXRcbiAqIEB0eXBlIFN0cmluZ1xuICovXG5cbmZ1bmN0aW9uIGpvaW4ob3V0cHV0LCByZXBsYWNlbWVudCkge1xuICB2YXIgczEgPSB0cmltVHJhaWxpbmdOZXdsaW5lcyhvdXRwdXQpO1xuICB2YXIgczIgPSB0cmltTGVhZGluZ05ld2xpbmVzKHJlcGxhY2VtZW50KTtcbiAgdmFyIG5scyA9IE1hdGgubWF4KG91dHB1dC5sZW5ndGggLSBzMS5sZW5ndGgsIHJlcGxhY2VtZW50Lmxlbmd0aCAtIHMyLmxlbmd0aCk7XG4gIHZhciBzZXBhcmF0b3IgPSAnXFxuXFxuJy5zdWJzdHJpbmcoMCwgbmxzKTtcbiAgcmV0dXJuIHMxICsgc2VwYXJhdG9yICsgczI7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGFuIGlucHV0IGNhbiBiZSBjb252ZXJ0ZWRcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge1N0cmluZ3xIVE1MRWxlbWVudH0gaW5wdXQgRGVzY3JpYmUgdGhpcyBwYXJhbWV0ZXJcbiAqIEByZXR1cm5zIERlc2NyaWJlIHdoYXQgaXQgcmV0dXJuc1xuICogQHR5cGUgU3RyaW5nfE9iamVjdHxBcnJheXxCb29sZWFufE51bWJlclxuICovXG5cbmZ1bmN0aW9uIGNhbkNvbnZlcnQoaW5wdXQpIHtcbiAgcmV0dXJuIGlucHV0ICE9IG51bGwgJiYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycgfHwgaW5wdXQubm9kZVR5cGUgJiYgKGlucHV0Lm5vZGVUeXBlID09PSAxIHx8IGlucHV0Lm5vZGVUeXBlID09PSA5IHx8IGlucHV0Lm5vZGVUeXBlID09PSAxMSkpO1xufVxuXG5leHBvcnQgeyBUdXJuZG93blNlcnZpY2UgYXMgZGVmYXVsdCB9O1xuIiwgInZhciBoaWdobGlnaHRSZWdFeHAgPSAvaGlnaGxpZ2h0LSg/OnRleHR8c291cmNlKS0oW2EtejAtOV0rKS87XG5cbmZ1bmN0aW9uIGhpZ2hsaWdodGVkQ29kZUJsb2NrICh0dXJuZG93blNlcnZpY2UpIHtcbiAgdHVybmRvd25TZXJ2aWNlLmFkZFJ1bGUoJ2hpZ2hsaWdodGVkQ29kZUJsb2NrJywge1xuICAgIGZpbHRlcjogZnVuY3Rpb24gKG5vZGUpIHtcbiAgICAgIHZhciBmaXJzdENoaWxkID0gbm9kZS5maXJzdENoaWxkO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgbm9kZS5ub2RlTmFtZSA9PT0gJ0RJVicgJiZcbiAgICAgICAgaGlnaGxpZ2h0UmVnRXhwLnRlc3Qobm9kZS5jbGFzc05hbWUpICYmXG4gICAgICAgIGZpcnN0Q2hpbGQgJiZcbiAgICAgICAgZmlyc3RDaGlsZC5ub2RlTmFtZSA9PT0gJ1BSRSdcbiAgICAgIClcbiAgICB9LFxuICAgIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSwgb3B0aW9ucykge1xuICAgICAgdmFyIGNsYXNzTmFtZSA9IG5vZGUuY2xhc3NOYW1lIHx8ICcnO1xuICAgICAgdmFyIGxhbmd1YWdlID0gKGNsYXNzTmFtZS5tYXRjaChoaWdobGlnaHRSZWdFeHApIHx8IFtudWxsLCAnJ10pWzFdO1xuXG4gICAgICByZXR1cm4gKFxuICAgICAgICAnXFxuXFxuJyArIG9wdGlvbnMuZmVuY2UgKyBsYW5ndWFnZSArICdcXG4nICtcbiAgICAgICAgbm9kZS5maXJzdENoaWxkLnRleHRDb250ZW50ICtcbiAgICAgICAgJ1xcbicgKyBvcHRpb25zLmZlbmNlICsgJ1xcblxcbidcbiAgICAgIClcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBzdHJpa2V0aHJvdWdoICh0dXJuZG93blNlcnZpY2UpIHtcbiAgdHVybmRvd25TZXJ2aWNlLmFkZFJ1bGUoJ3N0cmlrZXRocm91Z2gnLCB7XG4gICAgZmlsdGVyOiBbJ2RlbCcsICdzJywgJ3N0cmlrZSddLFxuICAgIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCkge1xuICAgICAgcmV0dXJuICd+JyArIGNvbnRlbnQgKyAnfidcbiAgICB9XG4gIH0pO1xufVxuXG52YXIgaW5kZXhPZiA9IEFycmF5LnByb3RvdHlwZS5pbmRleE9mO1xudmFyIGV2ZXJ5ID0gQXJyYXkucHJvdG90eXBlLmV2ZXJ5O1xudmFyIHJ1bGVzID0ge307XG5cbnJ1bGVzLnRhYmxlQ2VsbCA9IHtcbiAgZmlsdGVyOiBbJ3RoJywgJ3RkJ10sXG4gIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSkge1xuICAgIHJldHVybiBjZWxsKGNvbnRlbnQsIG5vZGUpXG4gIH1cbn07XG5cbnJ1bGVzLnRhYmxlUm93ID0ge1xuICBmaWx0ZXI6ICd0cicsXG4gIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSkge1xuICAgIHZhciBib3JkZXJDZWxscyA9ICcnO1xuICAgIHZhciBhbGlnbk1hcCA9IHsgbGVmdDogJzotLScsIHJpZ2h0OiAnLS06JywgY2VudGVyOiAnOi06JyB9O1xuXG4gICAgaWYgKGlzSGVhZGluZ1Jvdyhub2RlKSkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBub2RlLmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGJvcmRlciA9ICctLS0nO1xuICAgICAgICB2YXIgYWxpZ24gPSAoXG4gICAgICAgICAgbm9kZS5jaGlsZE5vZGVzW2ldLmdldEF0dHJpYnV0ZSgnYWxpZ24nKSB8fCAnJ1xuICAgICAgICApLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgICAgaWYgKGFsaWduKSBib3JkZXIgPSBhbGlnbk1hcFthbGlnbl0gfHwgYm9yZGVyO1xuXG4gICAgICAgIGJvcmRlckNlbGxzICs9IGNlbGwoYm9yZGVyLCBub2RlLmNoaWxkTm9kZXNbaV0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gJ1xcbicgKyBjb250ZW50ICsgKGJvcmRlckNlbGxzID8gJ1xcbicgKyBib3JkZXJDZWxscyA6ICcnKVxuICB9XG59O1xuXG5ydWxlcy50YWJsZSA9IHtcbiAgLy8gT25seSBjb252ZXJ0IHRhYmxlcyB3aXRoIGEgaGVhZGluZyByb3cuXG4gIC8vIFRhYmxlcyB3aXRoIG5vIGhlYWRpbmcgcm93IGFyZSBrZXB0IHVzaW5nIGBrZWVwYCAoc2VlIGJlbG93KS5cbiAgZmlsdGVyOiBmdW5jdGlvbiAobm9kZSkge1xuICAgIHJldHVybiBub2RlLm5vZGVOYW1lID09PSAnVEFCTEUnICYmIGlzSGVhZGluZ1Jvdyhub2RlLnJvd3NbMF0pXG4gIH0sXG5cbiAgcmVwbGFjZW1lbnQ6IGZ1bmN0aW9uIChjb250ZW50KSB7XG4gICAgLy8gRW5zdXJlIHRoZXJlIGFyZSBubyBibGFuayBsaW5lc1xuICAgIGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2UoJ1xcblxcbicsICdcXG4nKTtcbiAgICByZXR1cm4gJ1xcblxcbicgKyBjb250ZW50ICsgJ1xcblxcbidcbiAgfVxufTtcblxucnVsZXMudGFibGVTZWN0aW9uID0ge1xuICBmaWx0ZXI6IFsndGhlYWQnLCAndGJvZHknLCAndGZvb3QnXSxcbiAgcmVwbGFjZW1lbnQ6IGZ1bmN0aW9uIChjb250ZW50KSB7XG4gICAgcmV0dXJuIGNvbnRlbnRcbiAgfVxufTtcblxuLy8gQSB0ciBpcyBhIGhlYWRpbmcgcm93IGlmOlxuLy8gLSB0aGUgcGFyZW50IGlzIGEgVEhFQURcbi8vIC0gb3IgaWYgaXRzIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgVEFCTEUgb3IgdGhlIGZpcnN0IFRCT0RZIChwb3NzaWJseVxuLy8gICBmb2xsb3dpbmcgYSBibGFuayBUSEVBRClcbi8vIC0gYW5kIGV2ZXJ5IGNlbGwgaXMgYSBUSFxuZnVuY3Rpb24gaXNIZWFkaW5nUm93ICh0cikge1xuICB2YXIgcGFyZW50Tm9kZSA9IHRyLnBhcmVudE5vZGU7XG4gIHJldHVybiAoXG4gICAgcGFyZW50Tm9kZS5ub2RlTmFtZSA9PT0gJ1RIRUFEJyB8fFxuICAgIChcbiAgICAgIHBhcmVudE5vZGUuZmlyc3RDaGlsZCA9PT0gdHIgJiZcbiAgICAgIChwYXJlbnROb2RlLm5vZGVOYW1lID09PSAnVEFCTEUnIHx8IGlzRmlyc3RUYm9keShwYXJlbnROb2RlKSkgJiZcbiAgICAgIGV2ZXJ5LmNhbGwodHIuY2hpbGROb2RlcywgZnVuY3Rpb24gKG4pIHsgcmV0dXJuIG4ubm9kZU5hbWUgPT09ICdUSCcgfSlcbiAgICApXG4gIClcbn1cblxuZnVuY3Rpb24gaXNGaXJzdFRib2R5IChlbGVtZW50KSB7XG4gIHZhciBwcmV2aW91c1NpYmxpbmcgPSBlbGVtZW50LnByZXZpb3VzU2libGluZztcbiAgcmV0dXJuIChcbiAgICBlbGVtZW50Lm5vZGVOYW1lID09PSAnVEJPRFknICYmIChcbiAgICAgICFwcmV2aW91c1NpYmxpbmcgfHxcbiAgICAgIChcbiAgICAgICAgcHJldmlvdXNTaWJsaW5nLm5vZGVOYW1lID09PSAnVEhFQUQnICYmXG4gICAgICAgIC9eXFxzKiQvaS50ZXN0KHByZXZpb3VzU2libGluZy50ZXh0Q29udGVudClcbiAgICAgIClcbiAgICApXG4gIClcbn1cblxuZnVuY3Rpb24gY2VsbCAoY29udGVudCwgbm9kZSkge1xuICB2YXIgaW5kZXggPSBpbmRleE9mLmNhbGwobm9kZS5wYXJlbnROb2RlLmNoaWxkTm9kZXMsIG5vZGUpO1xuICB2YXIgcHJlZml4ID0gJyAnO1xuICBpZiAoaW5kZXggPT09IDApIHByZWZpeCA9ICd8ICc7XG4gIHJldHVybiBwcmVmaXggKyBjb250ZW50ICsgJyB8J1xufVxuXG5mdW5jdGlvbiB0YWJsZXMgKHR1cm5kb3duU2VydmljZSkge1xuICB0dXJuZG93blNlcnZpY2Uua2VlcChmdW5jdGlvbiAobm9kZSkge1xuICAgIHJldHVybiBub2RlLm5vZGVOYW1lID09PSAnVEFCTEUnICYmICFpc0hlYWRpbmdSb3cobm9kZS5yb3dzWzBdKVxuICB9KTtcbiAgZm9yICh2YXIga2V5IGluIHJ1bGVzKSB0dXJuZG93blNlcnZpY2UuYWRkUnVsZShrZXksIHJ1bGVzW2tleV0pO1xufVxuXG5mdW5jdGlvbiB0YXNrTGlzdEl0ZW1zICh0dXJuZG93blNlcnZpY2UpIHtcbiAgdHVybmRvd25TZXJ2aWNlLmFkZFJ1bGUoJ3Rhc2tMaXN0SXRlbXMnLCB7XG4gICAgZmlsdGVyOiBmdW5jdGlvbiAobm9kZSkge1xuICAgICAgcmV0dXJuIG5vZGUudHlwZSA9PT0gJ2NoZWNrYm94JyAmJiBub2RlLnBhcmVudE5vZGUubm9kZU5hbWUgPT09ICdMSSdcbiAgICB9LFxuICAgIHJlcGxhY2VtZW50OiBmdW5jdGlvbiAoY29udGVudCwgbm9kZSkge1xuICAgICAgcmV0dXJuIChub2RlLmNoZWNrZWQgPyAnW3hdJyA6ICdbIF0nKSArICcgJ1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdmbSAodHVybmRvd25TZXJ2aWNlKSB7XG4gIHR1cm5kb3duU2VydmljZS51c2UoW1xuICAgIGhpZ2hsaWdodGVkQ29kZUJsb2NrLFxuICAgIHN0cmlrZXRocm91Z2gsXG4gICAgdGFibGVzLFxuICAgIHRhc2tMaXN0SXRlbXNcbiAgXSk7XG59XG5cbmV4cG9ydCB7IGdmbSwgaGlnaGxpZ2h0ZWRDb2RlQmxvY2ssIHN0cmlrZXRocm91Z2gsIHRhYmxlcywgdGFza0xpc3RJdGVtcyB9O1xuIiwgIi8qIGVzbGludC1lbnYgYnJvd3NlciAqL1xuXG4vKipcbiAqIEhlbHBlcnMgZm9yIGNyb3NzLXRhYiBjb21tdW5pY2F0aW9uIHVzaW5nIGJyb2FkY2FzdGNoYW5uZWwgd2l0aCBMb2NhbFN0b3JhZ2UgZmFsbGJhY2suXG4gKlxuICogYGBganNcbiAqIC8vIEluIGJyb3dzZXIgd2luZG93IEE6XG4gKiBicm9hZGNhc3RjaGFubmVsLnN1YnNjcmliZSgnbXkgZXZlbnRzJywgZGF0YSA9PiBjb25zb2xlLmxvZyhkYXRhKSlcbiAqIGJyb2FkY2FzdGNoYW5uZWwucHVibGlzaCgnbXkgZXZlbnRzJywgJ0hlbGxvIHdvcmxkIScpIC8vID0+IEE6ICdIZWxsbyB3b3JsZCEnIGZpcmVzIHN5bmNocm9ub3VzbHkgaW4gc2FtZSB0YWJcbiAqXG4gKiAvLyBJbiBicm93c2VyIHdpbmRvdyBCOlxuICogYnJvYWRjYXN0Y2hhbm5lbC5wdWJsaXNoKCdteSBldmVudHMnLCAnaGVsbG8gZnJvbSB0YWIgQicpIC8vID0+IEE6ICdoZWxsbyBmcm9tIHRhYiBCJ1xuICogYGBgXG4gKlxuICogQG1vZHVsZSBicm9hZGNhc3RjaGFubmVsXG4gKi9cblxuLy8gQHRvZG8gYmVmb3JlIG5leHQgbWFqb3I6IHVzZSBVaW50OEFycmF5IGluc3RlYWQgYXMgYnVmZmVyIG9iamVjdFxuXG5pbXBvcnQgKiBhcyBtYXAgZnJvbSAnLi9tYXAuanMnXG5pbXBvcnQgKiBhcyBzZXQgZnJvbSAnLi9zZXQuanMnXG5pbXBvcnQgKiBhcyBidWZmZXIgZnJvbSAnLi9idWZmZXIuanMnXG5pbXBvcnQgKiBhcyBzdG9yYWdlIGZyb20gJy4vc3RvcmFnZS5qcydcblxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBDaGFubmVsXG4gKiBAcHJvcGVydHkge1NldDxmdW5jdGlvbihhbnksIGFueSk6YW55Pn0gQ2hhbm5lbC5zdWJzXG4gKiBAcHJvcGVydHkge2FueX0gQ2hhbm5lbC5iY1xuICovXG5cbi8qKlxuICogQHR5cGUge01hcDxzdHJpbmcsIENoYW5uZWw+fVxuICovXG5jb25zdCBjaGFubmVscyA9IG5ldyBNYXAoKVxuXG4vKiBjOCBpZ25vcmUgc3RhcnQgKi9cbmNsYXNzIExvY2FsU3RvcmFnZVBvbHlmaWxsIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByb29tXG4gICAqL1xuICBjb25zdHJ1Y3RvciAocm9vbSkge1xuICAgIHRoaXMucm9vbSA9IHJvb21cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7bnVsbHxmdW5jdGlvbih7ZGF0YTpVaW50OEFycmF5fSk6dm9pZH1cbiAgICAgKi9cbiAgICB0aGlzLm9ubWVzc2FnZSA9IG51bGxcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2FueX0gZVxuICAgICAqL1xuICAgIHRoaXMuX29uQ2hhbmdlID0gZSA9PiBlLmtleSA9PT0gcm9vbSAmJiB0aGlzLm9ubWVzc2FnZSAhPT0gbnVsbCAmJiB0aGlzLm9ubWVzc2FnZSh7IGRhdGE6IGJ1ZmZlci5mcm9tQmFzZTY0KGUubmV3VmFsdWUgfHwgJycpIH0pXG4gICAgc3RvcmFnZS5vbkNoYW5nZSh0aGlzLl9vbkNoYW5nZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZcbiAgICovXG4gIHBvc3RNZXNzYWdlIChidWYpIHtcbiAgICBzdG9yYWdlLnZhclN0b3JhZ2Uuc2V0SXRlbSh0aGlzLnJvb20sIGJ1ZmZlci50b0Jhc2U2NChidWZmZXIuY3JlYXRlVWludDhBcnJheUZyb21BcnJheUJ1ZmZlcihidWYpKSlcbiAgfVxuXG4gIGNsb3NlICgpIHtcbiAgICBzdG9yYWdlLm9mZkNoYW5nZSh0aGlzLl9vbkNoYW5nZSlcbiAgfVxufVxuLyogYzggaWdub3JlIHN0b3AgKi9cblxuLy8gVXNlIEJyb2FkY2FzdENoYW5uZWwgb3IgUG9seWZpbGxcbi8qIGM4IGlnbm9yZSBuZXh0ICovXG5jb25zdCBCQyA9IHR5cGVvZiBCcm9hZGNhc3RDaGFubmVsID09PSAndW5kZWZpbmVkJyA/IExvY2FsU3RvcmFnZVBvbHlmaWxsIDogQnJvYWRjYXN0Q2hhbm5lbFxuXG4vKipcbiAqIEBwYXJhbSB7c3RyaW5nfSByb29tXG4gKiBAcmV0dXJuIHtDaGFubmVsfVxuICovXG5jb25zdCBnZXRDaGFubmVsID0gcm9vbSA9PlxuICBtYXAuc2V0SWZVbmRlZmluZWQoY2hhbm5lbHMsIHJvb20sICgpID0+IHtcbiAgICBjb25zdCBzdWJzID0gc2V0LmNyZWF0ZSgpXG4gICAgY29uc3QgYmMgPSBuZXcgQkMocm9vbSlcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge3tkYXRhOkFycmF5QnVmZmVyfX0gZVxuICAgICAqL1xuICAgIC8qIGM4IGlnbm9yZSBuZXh0ICovXG4gICAgYmMub25tZXNzYWdlID0gZSA9PiBzdWJzLmZvckVhY2goc3ViID0+IHN1YihlLmRhdGEsICdicm9hZGNhc3RjaGFubmVsJykpXG4gICAgcmV0dXJuIHtcbiAgICAgIGJjLCBzdWJzXG4gICAgfVxuICB9KVxuXG4vKipcbiAqIFN1YnNjcmliZSB0byBnbG9iYWwgYHB1Ymxpc2hgIGV2ZW50cy5cbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7c3RyaW5nfSByb29tXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKGFueSwgYW55KTphbnl9IGZcbiAqL1xuZXhwb3J0IGNvbnN0IHN1YnNjcmliZSA9IChyb29tLCBmKSA9PiB7XG4gIGdldENoYW5uZWwocm9vbSkuc3Vicy5hZGQoZilcbiAgcmV0dXJuIGZcbn1cblxuLyoqXG4gKiBVbnN1YnNjcmliZSBmcm9tIGBwdWJsaXNoYCBnbG9iYWwgZXZlbnRzLlxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IHJvb21cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oYW55LCBhbnkpOmFueX0gZlxuICovXG5leHBvcnQgY29uc3QgdW5zdWJzY3JpYmUgPSAocm9vbSwgZikgPT4ge1xuICBjb25zdCBjaGFubmVsID0gZ2V0Q2hhbm5lbChyb29tKVxuICBjb25zdCB1bnN1YnNjcmliZWQgPSBjaGFubmVsLnN1YnMuZGVsZXRlKGYpXG4gIGlmICh1bnN1YnNjcmliZWQgJiYgY2hhbm5lbC5zdWJzLnNpemUgPT09IDApIHtcbiAgICBjaGFubmVsLmJjLmNsb3NlKClcbiAgICBjaGFubmVscy5kZWxldGUocm9vbSlcbiAgfVxuICByZXR1cm4gdW5zdWJzY3JpYmVkXG59XG5cbi8qKlxuICogUHVibGlzaCBkYXRhIHRvIGFsbCBzdWJzY3JpYmVycyAoaW5jbHVkaW5nIHN1YnNjcmliZXJzIG9uIHRoaXMgdGFiKVxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IHJvb21cbiAqIEBwYXJhbSB7YW55fSBkYXRhXG4gKiBAcGFyYW0ge2FueX0gW29yaWdpbl1cbiAqL1xuZXhwb3J0IGNvbnN0IHB1Ymxpc2ggPSAocm9vbSwgZGF0YSwgb3JpZ2luID0gbnVsbCkgPT4ge1xuICBjb25zdCBjID0gZ2V0Q2hhbm5lbChyb29tKVxuICBjLmJjLnBvc3RNZXNzYWdlKGRhdGEpXG4gIGMuc3Vicy5mb3JFYWNoKHN1YiA9PiBzdWIoZGF0YSwgb3JpZ2luKSlcbn1cbiIsICIvKipcbiAqIEBtb2R1bGUgc3luYy1wcm90b2NvbFxuICovXG5cbmltcG9ydCAqIGFzIGVuY29kaW5nIGZyb20gJ2xpYjAvZW5jb2RpbmcnXG5pbXBvcnQgKiBhcyBkZWNvZGluZyBmcm9tICdsaWIwL2RlY29kaW5nJ1xuaW1wb3J0ICogYXMgWSBmcm9tICd5anMnXG5cbi8qKlxuICogQHR5cGVkZWYge01hcDxudW1iZXIsIG51bWJlcj59IFN0YXRlTWFwXG4gKi9cblxuLyoqXG4gKiBDb3JlIFlqcyBkZWZpbmVzIHR3byBtZXNzYWdlIHR5cGVzOlxuICogXHUyMDIyIFlqc1N5bmNTdGVwMTogSW5jbHVkZXMgdGhlIFN0YXRlIFNldCBvZiB0aGUgc2VuZGluZyBjbGllbnQuIFdoZW4gcmVjZWl2ZWQsIHRoZSBjbGllbnQgc2hvdWxkIHJlcGx5IHdpdGggWWpzU3luY1N0ZXAyLlxuICogXHUyMDIyIFlqc1N5bmNTdGVwMjogSW5jbHVkZXMgYWxsIG1pc3Npbmcgc3RydWN0cyBhbmQgdGhlIGNvbXBsZXRlIGRlbGV0ZSBzZXQuIFdoZW4gcmVjZWl2ZWQsIHRoZSBjbGllbnQgaXMgYXNzdXJlZCB0aGF0IGl0XG4gKiAgIHJlY2VpdmVkIGFsbCBpbmZvcm1hdGlvbiBmcm9tIHRoZSByZW1vdGUgY2xpZW50LlxuICpcbiAqIEluIGEgcGVlci10by1wZWVyIG5ldHdvcmssIHlvdSBtYXkgd2FudCB0byBpbnRyb2R1Y2UgYSBTeW5jRG9uZSBtZXNzYWdlIHR5cGUuIEJvdGggcGFydGllcyBzaG91bGQgaW5pdGlhdGUgdGhlIGNvbm5lY3Rpb25cbiAqIHdpdGggU3luY1N0ZXAxLiBXaGVuIGEgY2xpZW50IHJlY2VpdmVkIFN5bmNTdGVwMiwgaXQgc2hvdWxkIHJlcGx5IHdpdGggU3luY0RvbmUuIFdoZW4gdGhlIGxvY2FsIGNsaWVudCByZWNlaXZlZCBib3RoXG4gKiBTeW5jU3RlcDIgYW5kIFN5bmNEb25lLCBpdCBpcyBhc3N1cmVkIHRoYXQgaXQgaXMgc3luY2VkIHRvIHRoZSByZW1vdGUgY2xpZW50LlxuICpcbiAqIEluIGEgY2xpZW50LXNlcnZlciBtb2RlbCwgeW91IHdhbnQgdG8gaGFuZGxlIHRoaXMgZGlmZmVyZW50bHk6IFRoZSBjbGllbnQgc2hvdWxkIGluaXRpYXRlIHRoZSBjb25uZWN0aW9uIHdpdGggU3luY1N0ZXAxLlxuICogV2hlbiB0aGUgc2VydmVyIHJlY2VpdmVzIFN5bmNTdGVwMSwgaXQgc2hvdWxkIHJlcGx5IHdpdGggU3luY1N0ZXAyIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IFN5bmNTdGVwMS4gVGhlIGNsaWVudCByZXBsaWVzXG4gKiB3aXRoIFN5bmNTdGVwMiB3aGVuIGl0IHJlY2VpdmVzIFN5bmNTdGVwMS4gT3B0aW9uYWxseSB0aGUgc2VydmVyIG1heSBzZW5kIGEgU3luY0RvbmUgYWZ0ZXIgaXQgcmVjZWl2ZWQgU3luY1N0ZXAyLCBzbyB0aGVcbiAqIGNsaWVudCBrbm93cyB0aGF0IHRoZSBzeW5jIGlzIGZpbmlzaGVkLiAgVGhlcmUgYXJlIHR3byByZWFzb25zIGZvciB0aGlzIG1vcmUgZWxhYm9yYXRlZCBzeW5jIG1vZGVsOiAxLiBUaGlzIHByb3RvY29sIGNhblxuICogZWFzaWx5IGJlIGltcGxlbWVudGVkIG9uIHRvcCBvZiBodHRwIGFuZCB3ZWJzb2NrZXRzLiAyLiBUaGUgc2VydmVyIHNob3VsZCBvbmx5IHJlcGx5IHRvIHJlcXVlc3RzLCBhbmQgbm90IGluaXRpYXRlIHRoZW0uXG4gKiBUaGVyZWZvcmUgaXQgaXMgbmVjZXNzYXJ5IHRoYXQgdGhlIGNsaWVudCBpbml0aWF0ZXMgdGhlIHN5bmMuXG4gKlxuICogQ29uc3RydWN0aW9uIG9mIGEgbWVzc2FnZTpcbiAqIFttZXNzYWdlVHlwZSA6IHZhclVpbnQsIG1lc3NhZ2UgZGVmaW5pdGlvbi4uXVxuICpcbiAqIE5vdGU6IEEgbWVzc2FnZSBkb2VzIG5vdCBpbmNsdWRlIGluZm9ybWF0aW9uIGFib3V0IHRoZSByb29tIG5hbWUuIFRoaXMgbXVzdCB0byBiZSBoYW5kbGVkIGJ5IHRoZSB1cHBlciBsYXllciBwcm90b2NvbCFcbiAqXG4gKiBzdHJpbmdpZnlbbWVzc2FnZVR5cGVdIHN0cmluZ2lmaWVzIGEgbWVzc2FnZSBkZWZpbml0aW9uIChtZXNzYWdlVHlwZSBpcyBhbHJlYWR5IHJlYWQgZnJvbSB0aGUgYnVmZmZlcilcbiAqL1xuXG5leHBvcnQgY29uc3QgbWVzc2FnZVlqc1N5bmNTdGVwMSA9IDBcbmV4cG9ydCBjb25zdCBtZXNzYWdlWWpzU3luY1N0ZXAyID0gMVxuZXhwb3J0IGNvbnN0IG1lc3NhZ2VZanNVcGRhdGUgPSAyXG5cbi8qKlxuICogQ3JlYXRlIGEgc3luYyBzdGVwIDEgbWVzc2FnZSBiYXNlZCBvbiB0aGUgc3RhdGUgb2YgdGhlIGN1cnJlbnQgc2hhcmVkIGRvY3VtZW50LlxuICpcbiAqIEBwYXJhbSB7ZW5jb2RpbmcuRW5jb2Rlcn0gZW5jb2RlclxuICogQHBhcmFtIHtZLkRvY30gZG9jXG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZVN5bmNTdGVwMSA9IChlbmNvZGVyLCBkb2MpID0+IHtcbiAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIsIG1lc3NhZ2VZanNTeW5jU3RlcDEpXG4gIGNvbnN0IHN2ID0gWS5lbmNvZGVTdGF0ZVZlY3Rvcihkb2MpXG4gIGVuY29kaW5nLndyaXRlVmFyVWludDhBcnJheShlbmNvZGVyLCBzdilcbn1cblxuLyoqXG4gKiBAcGFyYW0ge2VuY29kaW5nLkVuY29kZXJ9IGVuY29kZXJcbiAqIEBwYXJhbSB7WS5Eb2N9IGRvY1xuICogQHBhcmFtIHtVaW50OEFycmF5fSBbZW5jb2RlZFN0YXRlVmVjdG9yXVxuICovXG5leHBvcnQgY29uc3Qgd3JpdGVTeW5jU3RlcDIgPSAoZW5jb2RlciwgZG9jLCBlbmNvZGVkU3RhdGVWZWN0b3IpID0+IHtcbiAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIsIG1lc3NhZ2VZanNTeW5jU3RlcDIpXG4gIGVuY29kaW5nLndyaXRlVmFyVWludDhBcnJheShlbmNvZGVyLCBZLmVuY29kZVN0YXRlQXNVcGRhdGUoZG9jLCBlbmNvZGVkU3RhdGVWZWN0b3IpKVxufVxuXG4vKipcbiAqIFJlYWQgU3luY1N0ZXAxIG1lc3NhZ2UgYW5kIHJlcGx5IHdpdGggU3luY1N0ZXAyLlxuICpcbiAqIEBwYXJhbSB7ZGVjb2RpbmcuRGVjb2Rlcn0gZGVjb2RlciBUaGUgcmVwbHkgdG8gdGhlIHJlY2VpdmVkIG1lc3NhZ2VcbiAqIEBwYXJhbSB7ZW5jb2RpbmcuRW5jb2Rlcn0gZW5jb2RlciBUaGUgcmVjZWl2ZWQgbWVzc2FnZVxuICogQHBhcmFtIHtZLkRvY30gZG9jXG4gKi9cbmV4cG9ydCBjb25zdCByZWFkU3luY1N0ZXAxID0gKGRlY29kZXIsIGVuY29kZXIsIGRvYykgPT5cbiAgd3JpdGVTeW5jU3RlcDIoZW5jb2RlciwgZG9jLCBkZWNvZGluZy5yZWFkVmFyVWludDhBcnJheShkZWNvZGVyKSlcblxuLyoqXG4gKiBSZWFkIGFuZCBhcHBseSBTdHJ1Y3RzIGFuZCB0aGVuIERlbGV0ZVN0b3JlIHRvIGEgeSBpbnN0YW5jZS5cbiAqXG4gKiBAcGFyYW0ge2RlY29kaW5nLkRlY29kZXJ9IGRlY29kZXJcbiAqIEBwYXJhbSB7WS5Eb2N9IGRvY1xuICogQHBhcmFtIHthbnl9IHRyYW5zYWN0aW9uT3JpZ2luXG4gKiBAcGFyYW0geyhlcnJvcjpFcnJvcik9PmFueX0gW2Vycm9ySGFuZGxlcl1cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRTeW5jU3RlcDIgPSAoZGVjb2RlciwgZG9jLCB0cmFuc2FjdGlvbk9yaWdpbiwgZXJyb3JIYW5kbGVyKSA9PiB7XG4gIHRyeSB7XG4gICAgWS5hcHBseVVwZGF0ZShkb2MsIGRlY29kaW5nLnJlYWRWYXJVaW50OEFycmF5KGRlY29kZXIpLCB0cmFuc2FjdGlvbk9yaWdpbilcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3JIYW5kbGVyICE9IG51bGwpIGVycm9ySGFuZGxlcigvKiogQHR5cGUge0Vycm9yfSAqLyAoZXJyb3IpKVxuICAgIC8vIFRoaXMgY2F0Y2hlcyBlcnJvcnMgdGhhdCBhcmUgdGhyb3duIGJ5IGV2ZW50IGhhbmRsZXJzXG4gICAgY29uc29sZS5lcnJvcignQ2F1Z2h0IGVycm9yIHdoaWxlIGhhbmRsaW5nIGEgWWpzIHVwZGF0ZScsIGVycm9yKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtlbmNvZGluZy5FbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge1VpbnQ4QXJyYXl9IHVwZGF0ZVxuICovXG5leHBvcnQgY29uc3Qgd3JpdGVVcGRhdGUgPSAoZW5jb2RlciwgdXBkYXRlKSA9PiB7XG4gIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLCBtZXNzYWdlWWpzVXBkYXRlKVxuICBlbmNvZGluZy53cml0ZVZhclVpbnQ4QXJyYXkoZW5jb2RlciwgdXBkYXRlKVxufVxuXG4vKipcbiAqIFJlYWQgYW5kIGFwcGx5IFN0cnVjdHMgYW5kIHRoZW4gRGVsZXRlU3RvcmUgdG8gYSB5IGluc3RhbmNlLlxuICpcbiAqIEBwYXJhbSB7ZGVjb2RpbmcuRGVjb2Rlcn0gZGVjb2RlclxuICogQHBhcmFtIHtZLkRvY30gZG9jXG4gKiBAcGFyYW0ge2FueX0gdHJhbnNhY3Rpb25PcmlnaW5cbiAqIEBwYXJhbSB7KGVycm9yOkVycm9yKT0+YW55fSBbZXJyb3JIYW5kbGVyXVxuICovXG5leHBvcnQgY29uc3QgcmVhZFVwZGF0ZSA9IHJlYWRTeW5jU3RlcDJcblxuLyoqXG4gKiBAcGFyYW0ge2RlY29kaW5nLkRlY29kZXJ9IGRlY29kZXIgQSBtZXNzYWdlIHJlY2VpdmVkIGZyb20gYW5vdGhlciBjbGllbnRcbiAqIEBwYXJhbSB7ZW5jb2RpbmcuRW5jb2Rlcn0gZW5jb2RlciBUaGUgcmVwbHkgbWVzc2FnZS4gRG9lcyBub3QgbmVlZCB0byBiZSBzZW50IGlmIGVtcHR5LlxuICogQHBhcmFtIHtZLkRvY30gZG9jXG4gKiBAcGFyYW0ge2FueX0gdHJhbnNhY3Rpb25PcmlnaW5cbiAqIEBwYXJhbSB7KGVycm9yOkVycm9yKT0+YW55fSBbZXJyb3JIYW5kbGVyXSBPcHRpb25hbCBlcnJvciBoYW5kbGVyIHRoYXQgY2F0Y2hlcyBlcnJvcnMgd2hlbiByZWFkaW5nIFlqcyBtZXNzYWdlcy5cbiAqL1xuZXhwb3J0IGNvbnN0IHJlYWRTeW5jTWVzc2FnZSA9IChkZWNvZGVyLCBlbmNvZGVyLCBkb2MsIHRyYW5zYWN0aW9uT3JpZ2luLCBlcnJvckhhbmRsZXIpID0+IHtcbiAgY29uc3QgbWVzc2FnZVR5cGUgPSBkZWNvZGluZy5yZWFkVmFyVWludChkZWNvZGVyKVxuICBzd2l0Y2ggKG1lc3NhZ2VUeXBlKSB7XG4gICAgY2FzZSBtZXNzYWdlWWpzU3luY1N0ZXAxOlxuICAgICAgcmVhZFN5bmNTdGVwMShkZWNvZGVyLCBlbmNvZGVyLCBkb2MpXG4gICAgICBicmVha1xuICAgIGNhc2UgbWVzc2FnZVlqc1N5bmNTdGVwMjpcbiAgICAgIHJlYWRTeW5jU3RlcDIoZGVjb2RlciwgZG9jLCB0cmFuc2FjdGlvbk9yaWdpbiwgZXJyb3JIYW5kbGVyKVxuICAgICAgYnJlYWtcbiAgICBjYXNlIG1lc3NhZ2VZanNVcGRhdGU6XG4gICAgICByZWFkVXBkYXRlKGRlY29kZXIsIGRvYywgdHJhbnNhY3Rpb25PcmlnaW4sIGVycm9ySGFuZGxlcilcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBtZXNzYWdlIHR5cGUnKVxuICB9XG4gIHJldHVybiBtZXNzYWdlVHlwZVxufVxuIiwgIlxuaW1wb3J0ICogYXMgWSBmcm9tICd5anMnIC8vIGVzbGludC1kaXNhYmxlLWxpbmVcbmltcG9ydCAqIGFzIGVuY29kaW5nIGZyb20gJ2xpYjAvZW5jb2RpbmcnXG5pbXBvcnQgKiBhcyBkZWNvZGluZyBmcm9tICdsaWIwL2RlY29kaW5nJ1xuXG5leHBvcnQgY29uc3QgbWVzc2FnZVBlcm1pc3Npb25EZW5pZWQgPSAwXG5cbi8qKlxuICogQHBhcmFtIHtlbmNvZGluZy5FbmNvZGVyfSBlbmNvZGVyXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVhc29uXG4gKi9cbmV4cG9ydCBjb25zdCB3cml0ZVBlcm1pc3Npb25EZW5pZWQgPSAoZW5jb2RlciwgcmVhc29uKSA9PiB7XG4gIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLCBtZXNzYWdlUGVybWlzc2lvbkRlbmllZClcbiAgZW5jb2Rpbmcud3JpdGVWYXJTdHJpbmcoZW5jb2RlciwgcmVhc29uKVxufVxuXG4vKipcbiAqIEBjYWxsYmFjayBQZXJtaXNzaW9uRGVuaWVkSGFuZGxlclxuICogQHBhcmFtIHthbnl9IHlcbiAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb25cbiAqL1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge2RlY29kaW5nLkRlY29kZXJ9IGRlY29kZXJcbiAqIEBwYXJhbSB7WS5Eb2N9IHlcbiAqIEBwYXJhbSB7UGVybWlzc2lvbkRlbmllZEhhbmRsZXJ9IHBlcm1pc3Npb25EZW5pZWRIYW5kbGVyXG4gKi9cbmV4cG9ydCBjb25zdCByZWFkQXV0aE1lc3NhZ2UgPSAoZGVjb2RlciwgeSwgcGVybWlzc2lvbkRlbmllZEhhbmRsZXIpID0+IHtcbiAgc3dpdGNoIChkZWNvZGluZy5yZWFkVmFyVWludChkZWNvZGVyKSkge1xuICAgIGNhc2UgbWVzc2FnZVBlcm1pc3Npb25EZW5pZWQ6IHBlcm1pc3Npb25EZW5pZWRIYW5kbGVyKHksIGRlY29kaW5nLnJlYWRWYXJTdHJpbmcoZGVjb2RlcikpXG4gIH1cbn1cbiIsICIvKipcbiAqIFV0aWxpdHkgbW9kdWxlIHRvIHdvcmsgd2l0aCB1cmxzLlxuICpcbiAqIEBtb2R1bGUgdXJsXG4gKi9cblxuaW1wb3J0ICogYXMgb2JqZWN0IGZyb20gJy4vb2JqZWN0LmpzJ1xuXG4vKipcbiAqIFBhcnNlIHF1ZXJ5IHBhcmFtZXRlcnMgZnJvbSBhbiB1cmwuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybFxuICogQHJldHVybiB7T2JqZWN0PHN0cmluZyxzdHJpbmc+fVxuICovXG5leHBvcnQgY29uc3QgZGVjb2RlUXVlcnlQYXJhbXMgPSB1cmwgPT4ge1xuICAvKipcbiAgICogQHR5cGUge09iamVjdDxzdHJpbmcsc3RyaW5nPn1cbiAgICovXG4gIGNvbnN0IHF1ZXJ5ID0ge31cbiAgY29uc3QgdXJsUXVlcnlTcGxpdCA9IHVybC5zcGxpdCgnPycpXG4gIGNvbnN0IHBhaXJzID0gdXJsUXVlcnlTcGxpdFt1cmxRdWVyeVNwbGl0Lmxlbmd0aCAtIDFdLnNwbGl0KCcmJylcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYWlycy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGl0ZW0gPSBwYWlyc1tpXVxuICAgIGlmIChpdGVtLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHBhaXIgPSBpdGVtLnNwbGl0KCc9JylcbiAgICAgIHF1ZXJ5W2RlY29kZVVSSUNvbXBvbmVudChwYWlyWzBdKV0gPSBkZWNvZGVVUklDb21wb25lbnQocGFpclsxXSB8fCAnJylcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHF1ZXJ5XG59XG5cbi8qKlxuICogQHBhcmFtIHtPYmplY3Q8c3RyaW5nLHN0cmluZz59IHBhcmFtc1xuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgZW5jb2RlUXVlcnlQYXJhbXMgPSBwYXJhbXMgPT5cbiAgb2JqZWN0Lm1hcChwYXJhbXMsICh2YWwsIGtleSkgPT4gYCR7ZW5jb2RlVVJJQ29tcG9uZW50KGtleSl9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KHZhbCl9YCkuam9pbignJicpXG4iLCAiLyoqXG4gKiBAbW9kdWxlIHByb3ZpZGVyL3dlYnNvY2tldFxuICovXG5cbi8qIGVzbGludC1lbnYgYnJvd3NlciAqL1xuXG5pbXBvcnQgKiBhcyBZIGZyb20gJ3lqcycgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuaW1wb3J0ICogYXMgYmMgZnJvbSAnbGliMC9icm9hZGNhc3RjaGFubmVsJ1xuaW1wb3J0ICogYXMgdGltZSBmcm9tICdsaWIwL3RpbWUnXG5pbXBvcnQgKiBhcyBlbmNvZGluZyBmcm9tICdsaWIwL2VuY29kaW5nJ1xuaW1wb3J0ICogYXMgZGVjb2RpbmcgZnJvbSAnbGliMC9kZWNvZGluZydcbmltcG9ydCAqIGFzIHN5bmNQcm90b2NvbCBmcm9tICd5LXByb3RvY29scy9zeW5jJ1xuaW1wb3J0ICogYXMgYXV0aFByb3RvY29sIGZyb20gJ3ktcHJvdG9jb2xzL2F1dGgnXG5pbXBvcnQgKiBhcyBhd2FyZW5lc3NQcm90b2NvbCBmcm9tICd5LXByb3RvY29scy9hd2FyZW5lc3MnXG5pbXBvcnQgeyBPYnNlcnZhYmxlVjIgfSBmcm9tICdsaWIwL29ic2VydmFibGUnXG5pbXBvcnQgKiBhcyBtYXRoIGZyb20gJ2xpYjAvbWF0aCdcbmltcG9ydCAqIGFzIHVybCBmcm9tICdsaWIwL3VybCdcbmltcG9ydCAqIGFzIGVudiBmcm9tICdsaWIwL2Vudmlyb25tZW50J1xuXG5leHBvcnQgY29uc3QgbWVzc2FnZVN5bmMgPSAwXG5leHBvcnQgY29uc3QgbWVzc2FnZVF1ZXJ5QXdhcmVuZXNzID0gM1xuZXhwb3J0IGNvbnN0IG1lc3NhZ2VBd2FyZW5lc3MgPSAxXG5leHBvcnQgY29uc3QgbWVzc2FnZUF1dGggPSAyXG5cbi8qKlxuICogICAgICAgICAgICAgICAgICAgICAgIGVuY29kZXIsICAgICAgICAgIGRlY29kZXIsICAgICAgICAgIHByb3ZpZGVyLCAgICAgICAgICBlbWl0U3luY2VkLCBtZXNzYWdlVHlwZVxuICogQHR5cGUge0FycmF5PGZ1bmN0aW9uKGVuY29kaW5nLkVuY29kZXIsIGRlY29kaW5nLkRlY29kZXIsIFdlYnNvY2tldFByb3ZpZGVyLCBib29sZWFuLCAgICBudW1iZXIpOnZvaWQ+fVxuICovXG5jb25zdCBtZXNzYWdlSGFuZGxlcnMgPSBbXVxuXG5tZXNzYWdlSGFuZGxlcnNbbWVzc2FnZVN5bmNdID0gKFxuICBlbmNvZGVyLFxuICBkZWNvZGVyLFxuICBwcm92aWRlcixcbiAgZW1pdFN5bmNlZCxcbiAgX21lc3NhZ2VUeXBlXG4pID0+IHtcbiAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIsIG1lc3NhZ2VTeW5jKVxuICBjb25zdCBzeW5jTWVzc2FnZVR5cGUgPSBzeW5jUHJvdG9jb2wucmVhZFN5bmNNZXNzYWdlKFxuICAgIGRlY29kZXIsXG4gICAgZW5jb2RlcixcbiAgICBwcm92aWRlci5kb2MsXG4gICAgcHJvdmlkZXJcbiAgKVxuICBpZiAoXG4gICAgZW1pdFN5bmNlZCAmJiBzeW5jTWVzc2FnZVR5cGUgPT09IHN5bmNQcm90b2NvbC5tZXNzYWdlWWpzU3luY1N0ZXAyICYmXG4gICAgIXByb3ZpZGVyLnN5bmNlZFxuICApIHtcbiAgICBwcm92aWRlci5zeW5jZWQgPSB0cnVlXG4gIH1cbn1cblxubWVzc2FnZUhhbmRsZXJzW21lc3NhZ2VRdWVyeUF3YXJlbmVzc10gPSAoXG4gIGVuY29kZXIsXG4gIF9kZWNvZGVyLFxuICBwcm92aWRlcixcbiAgX2VtaXRTeW5jZWQsXG4gIF9tZXNzYWdlVHlwZVxuKSA9PiB7XG4gIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLCBtZXNzYWdlQXdhcmVuZXNzKVxuICBlbmNvZGluZy53cml0ZVZhclVpbnQ4QXJyYXkoXG4gICAgZW5jb2RlcixcbiAgICBhd2FyZW5lc3NQcm90b2NvbC5lbmNvZGVBd2FyZW5lc3NVcGRhdGUoXG4gICAgICBwcm92aWRlci5hd2FyZW5lc3MsXG4gICAgICBBcnJheS5mcm9tKHByb3ZpZGVyLmF3YXJlbmVzcy5nZXRTdGF0ZXMoKS5rZXlzKCkpXG4gICAgKVxuICApXG59XG5cbm1lc3NhZ2VIYW5kbGVyc1ttZXNzYWdlQXdhcmVuZXNzXSA9IChcbiAgX2VuY29kZXIsXG4gIGRlY29kZXIsXG4gIHByb3ZpZGVyLFxuICBfZW1pdFN5bmNlZCxcbiAgX21lc3NhZ2VUeXBlXG4pID0+IHtcbiAgYXdhcmVuZXNzUHJvdG9jb2wuYXBwbHlBd2FyZW5lc3NVcGRhdGUoXG4gICAgcHJvdmlkZXIuYXdhcmVuZXNzLFxuICAgIGRlY29kaW5nLnJlYWRWYXJVaW50OEFycmF5KGRlY29kZXIpLFxuICAgIHByb3ZpZGVyXG4gIClcbn1cblxubWVzc2FnZUhhbmRsZXJzW21lc3NhZ2VBdXRoXSA9IChcbiAgX2VuY29kZXIsXG4gIGRlY29kZXIsXG4gIHByb3ZpZGVyLFxuICBfZW1pdFN5bmNlZCxcbiAgX21lc3NhZ2VUeXBlXG4pID0+IHtcbiAgYXV0aFByb3RvY29sLnJlYWRBdXRoTWVzc2FnZShcbiAgICBkZWNvZGVyLFxuICAgIHByb3ZpZGVyLmRvYyxcbiAgICAoX3lkb2MsIHJlYXNvbikgPT4gcGVybWlzc2lvbkRlbmllZEhhbmRsZXIocHJvdmlkZXIsIHJlYXNvbilcbiAgKVxufVxuXG4vLyBAdG9kbyAtIHRoaXMgc2hvdWxkIGRlcGVuZCBvbiBhd2FyZW5lc3Mub3V0ZGF0ZWRUaW1lXG5jb25zdCBtZXNzYWdlUmVjb25uZWN0VGltZW91dCA9IDMwMDAwXG5cbi8qKlxuICogQHBhcmFtIHtXZWJzb2NrZXRQcm92aWRlcn0gcHJvdmlkZXJcbiAqIEBwYXJhbSB7c3RyaW5nfSByZWFzb25cbiAqL1xuY29uc3QgcGVybWlzc2lvbkRlbmllZEhhbmRsZXIgPSAocHJvdmlkZXIsIHJlYXNvbikgPT5cbiAgY29uc29sZS53YXJuKGBQZXJtaXNzaW9uIGRlbmllZCB0byBhY2Nlc3MgJHtwcm92aWRlci51cmx9LlxcbiR7cmVhc29ufWApXG5cbi8qKlxuICogQHBhcmFtIHtXZWJzb2NrZXRQcm92aWRlcn0gcHJvdmlkZXJcbiAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGVtaXRTeW5jZWRcbiAqIEByZXR1cm4ge2VuY29kaW5nLkVuY29kZXJ9XG4gKi9cbmNvbnN0IHJlYWRNZXNzYWdlID0gKHByb3ZpZGVyLCBidWYsIGVtaXRTeW5jZWQpID0+IHtcbiAgY29uc3QgZGVjb2RlciA9IGRlY29kaW5nLmNyZWF0ZURlY29kZXIoYnVmKVxuICBjb25zdCBlbmNvZGVyID0gZW5jb2RpbmcuY3JlYXRlRW5jb2RlcigpXG4gIGNvbnN0IG1lc3NhZ2VUeXBlID0gZGVjb2RpbmcucmVhZFZhclVpbnQoZGVjb2RlcilcbiAgY29uc3QgbWVzc2FnZUhhbmRsZXIgPSBwcm92aWRlci5tZXNzYWdlSGFuZGxlcnNbbWVzc2FnZVR5cGVdXG4gIGlmICgvKiogQHR5cGUge2FueX0gKi8gKG1lc3NhZ2VIYW5kbGVyKSkge1xuICAgIG1lc3NhZ2VIYW5kbGVyKGVuY29kZXIsIGRlY29kZXIsIHByb3ZpZGVyLCBlbWl0U3luY2VkLCBtZXNzYWdlVHlwZSlcbiAgfSBlbHNlIHtcbiAgICBjb25zb2xlLmVycm9yKCdVbmFibGUgdG8gY29tcHV0ZSBtZXNzYWdlJylcbiAgfVxuICByZXR1cm4gZW5jb2RlclxufVxuXG4vKipcbiAqIE91dHNvdXJjZSB0aGlzIGZ1bmN0aW9uIHNvIHRoYXQgYSBuZXcgd2Vic29ja2V0IGNvbm5lY3Rpb24gaXMgY3JlYXRlZCBpbW1lZGlhdGVseS5cbiAqIEkgc3VzcGVjdCB0aGF0IHRoZSBgd3Mub25jbG9zZWAgZXZlbnQgaXMgbm90IGFsd2F5cyBmaXJlZCBpZiB0aGVyZSBhcmUgbmV0d29yayBpc3N1ZXMuXG4gKlxuICogQHBhcmFtIHtXZWJzb2NrZXRQcm92aWRlcn0gcHJvdmlkZXJcbiAqIEBwYXJhbSB7V2ViU29ja2V0fSB3c1xuICogQHBhcmFtIHtDbG9zZUV2ZW50IHwgbnVsbH0gZXZlbnRcbiAqL1xuY29uc3QgY2xvc2VXZWJzb2NrZXRDb25uZWN0aW9uID0gKHByb3ZpZGVyLCB3cywgZXZlbnQpID0+IHtcbiAgaWYgKHdzID09PSBwcm92aWRlci53cykge1xuICAgIHByb3ZpZGVyLmVtaXQoJ2Nvbm5lY3Rpb24tY2xvc2UnLCBbZXZlbnQsIHByb3ZpZGVyXSlcbiAgICBwcm92aWRlci53cyA9IG51bGxcbiAgICB3cy5jbG9zZSgpXG4gICAgcHJvdmlkZXIud3Njb25uZWN0aW5nID0gZmFsc2VcbiAgICBpZiAocHJvdmlkZXIud3Njb25uZWN0ZWQpIHtcbiAgICAgIHByb3ZpZGVyLndzY29ubmVjdGVkID0gZmFsc2VcbiAgICAgIHByb3ZpZGVyLnN5bmNlZCA9IGZhbHNlXG4gICAgICAvLyB1cGRhdGUgYXdhcmVuZXNzIChhbGwgdXNlcnMgZXhjZXB0IGxvY2FsIGxlZnQpXG4gICAgICBhd2FyZW5lc3NQcm90b2NvbC5yZW1vdmVBd2FyZW5lc3NTdGF0ZXMoXG4gICAgICAgIHByb3ZpZGVyLmF3YXJlbmVzcyxcbiAgICAgICAgQXJyYXkuZnJvbShwcm92aWRlci5hd2FyZW5lc3MuZ2V0U3RhdGVzKCkua2V5cygpKS5maWx0ZXIoKGNsaWVudCkgPT5cbiAgICAgICAgICBjbGllbnQgIT09IHByb3ZpZGVyLmRvYy5jbGllbnRJRFxuICAgICAgICApLFxuICAgICAgICBwcm92aWRlclxuICAgICAgKVxuICAgICAgcHJvdmlkZXIuZW1pdCgnc3RhdHVzJywgW3tcbiAgICAgICAgc3RhdHVzOiAnZGlzY29ubmVjdGVkJ1xuICAgICAgfV0pXG4gICAgfSBlbHNlIHtcbiAgICAgIHByb3ZpZGVyLndzVW5zdWNjZXNzZnVsUmVjb25uZWN0cysrXG4gICAgfVxuICAgIC8vIFN0YXJ0IHdpdGggbm8gcmVjb25uZWN0IHRpbWVvdXQgYW5kIGluY3JlYXNlIHRpbWVvdXQgYnlcbiAgICAvLyB1c2luZyBleHBvbmVudGlhbCBiYWNrb2ZmIHN0YXJ0aW5nIHdpdGggMTAwbXNcbiAgICBzZXRUaW1lb3V0KFxuICAgICAgc2V0dXBXUyxcbiAgICAgIG1hdGgubWluKFxuICAgICAgICBtYXRoLnBvdygyLCBwcm92aWRlci53c1Vuc3VjY2Vzc2Z1bFJlY29ubmVjdHMpICogMTAwLFxuICAgICAgICBwcm92aWRlci5tYXhCYWNrb2ZmVGltZVxuICAgICAgKSxcbiAgICAgIHByb3ZpZGVyXG4gICAgKVxuICB9XG59XG5cbi8qKlxuICogQHBhcmFtIHtXZWJzb2NrZXRQcm92aWRlcn0gcHJvdmlkZXJcbiAqL1xuY29uc3Qgc2V0dXBXUyA9IChwcm92aWRlcikgPT4ge1xuICBpZiAocHJvdmlkZXIuc2hvdWxkQ29ubmVjdCAmJiBwcm92aWRlci53cyA9PT0gbnVsbCkge1xuICAgIGNvbnN0IHdlYnNvY2tldCA9IG5ldyBwcm92aWRlci5fV1MocHJvdmlkZXIudXJsLCBwcm92aWRlci5wcm90b2NvbHMpXG4gICAgd2Vic29ja2V0LmJpbmFyeVR5cGUgPSAnYXJyYXlidWZmZXInXG4gICAgcHJvdmlkZXIud3MgPSB3ZWJzb2NrZXRcbiAgICBwcm92aWRlci53c2Nvbm5lY3RpbmcgPSB0cnVlXG4gICAgcHJvdmlkZXIud3Njb25uZWN0ZWQgPSBmYWxzZVxuICAgIHByb3ZpZGVyLnN5bmNlZCA9IGZhbHNlXG5cbiAgICB3ZWJzb2NrZXQub25tZXNzYWdlID0gKGV2ZW50KSA9PiB7XG4gICAgICBwcm92aWRlci53c0xhc3RNZXNzYWdlUmVjZWl2ZWQgPSB0aW1lLmdldFVuaXhUaW1lKClcbiAgICAgIGNvbnN0IGVuY29kZXIgPSByZWFkTWVzc2FnZShwcm92aWRlciwgbmV3IFVpbnQ4QXJyYXkoZXZlbnQuZGF0YSksIHRydWUpXG4gICAgICBpZiAoZW5jb2RpbmcubGVuZ3RoKGVuY29kZXIpID4gMSkge1xuICAgICAgICB3ZWJzb2NrZXQuc2VuZChlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlcikpXG4gICAgICB9XG4gICAgfVxuICAgIHdlYnNvY2tldC5vbmVycm9yID0gKGV2ZW50KSA9PiB7XG4gICAgICBwcm92aWRlci5lbWl0KCdjb25uZWN0aW9uLWVycm9yJywgW2V2ZW50LCBwcm92aWRlcl0pXG4gICAgfVxuICAgIHdlYnNvY2tldC5vbmNsb3NlID0gKGV2ZW50KSA9PiB7XG4gICAgICBjbG9zZVdlYnNvY2tldENvbm5lY3Rpb24ocHJvdmlkZXIsIHdlYnNvY2tldCwgZXZlbnQpXG4gICAgfVxuICAgIHdlYnNvY2tldC5vbm9wZW4gPSAoKSA9PiB7XG4gICAgICBwcm92aWRlci53c0xhc3RNZXNzYWdlUmVjZWl2ZWQgPSB0aW1lLmdldFVuaXhUaW1lKClcbiAgICAgIHByb3ZpZGVyLndzY29ubmVjdGluZyA9IGZhbHNlXG4gICAgICBwcm92aWRlci53c2Nvbm5lY3RlZCA9IHRydWVcbiAgICAgIHByb3ZpZGVyLndzVW5zdWNjZXNzZnVsUmVjb25uZWN0cyA9IDBcbiAgICAgIHByb3ZpZGVyLmVtaXQoJ3N0YXR1cycsIFt7XG4gICAgICAgIHN0YXR1czogJ2Nvbm5lY3RlZCdcbiAgICAgIH1dKVxuICAgICAgLy8gYWx3YXlzIHNlbmQgc3luYyBzdGVwIDEgd2hlbiBjb25uZWN0ZWRcbiAgICAgIGNvbnN0IGVuY29kZXIgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKClcbiAgICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLCBtZXNzYWdlU3luYylcbiAgICAgIHN5bmNQcm90b2NvbC53cml0ZVN5bmNTdGVwMShlbmNvZGVyLCBwcm92aWRlci5kb2MpXG4gICAgICB3ZWJzb2NrZXQuc2VuZChlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlcikpXG4gICAgICAvLyBicm9hZGNhc3QgbG9jYWwgYXdhcmVuZXNzIHN0YXRlXG4gICAgICBpZiAocHJvdmlkZXIuYXdhcmVuZXNzLmdldExvY2FsU3RhdGUoKSAhPT0gbnVsbCkge1xuICAgICAgICBjb25zdCBlbmNvZGVyQXdhcmVuZXNzU3RhdGUgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKClcbiAgICAgICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXJBd2FyZW5lc3NTdGF0ZSwgbWVzc2FnZUF3YXJlbmVzcylcbiAgICAgICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50OEFycmF5KFxuICAgICAgICAgIGVuY29kZXJBd2FyZW5lc3NTdGF0ZSxcbiAgICAgICAgICBhd2FyZW5lc3NQcm90b2NvbC5lbmNvZGVBd2FyZW5lc3NVcGRhdGUocHJvdmlkZXIuYXdhcmVuZXNzLCBbXG4gICAgICAgICAgICBwcm92aWRlci5kb2MuY2xpZW50SURcbiAgICAgICAgICBdKVxuICAgICAgICApXG4gICAgICAgIHdlYnNvY2tldC5zZW5kKGVuY29kaW5nLnRvVWludDhBcnJheShlbmNvZGVyQXdhcmVuZXNzU3RhdGUpKVxuICAgICAgfVxuICAgIH1cbiAgICBwcm92aWRlci5lbWl0KCdzdGF0dXMnLCBbe1xuICAgICAgc3RhdHVzOiAnY29ubmVjdGluZydcbiAgICB9XSlcbiAgfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7V2Vic29ja2V0UHJvdmlkZXJ9IHByb3ZpZGVyXG4gKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBidWZcbiAqL1xuY29uc3QgYnJvYWRjYXN0TWVzc2FnZSA9IChwcm92aWRlciwgYnVmKSA9PiB7XG4gIGNvbnN0IHdzID0gcHJvdmlkZXIud3NcbiAgaWYgKHByb3ZpZGVyLndzY29ubmVjdGVkICYmIHdzICYmIHdzLnJlYWR5U3RhdGUgPT09IHdzLk9QRU4pIHtcbiAgICB3cy5zZW5kKGJ1ZilcbiAgfVxuICBpZiAocHJvdmlkZXIuYmNjb25uZWN0ZWQpIHtcbiAgICBiYy5wdWJsaXNoKHByb3ZpZGVyLmJjQ2hhbm5lbCwgYnVmLCBwcm92aWRlcilcbiAgfVxufVxuXG4vKipcbiAqIFdlYnNvY2tldCBQcm92aWRlciBmb3IgWWpzLiBDcmVhdGVzIGEgd2Vic29ja2V0IGNvbm5lY3Rpb24gdG8gc3luYyB0aGUgc2hhcmVkIGRvY3VtZW50LlxuICogVGhlIGRvY3VtZW50IG5hbWUgaXMgYXR0YWNoZWQgdG8gdGhlIHByb3ZpZGVkIHVybC4gSS5lLiB0aGUgZm9sbG93aW5nIGV4YW1wbGVcbiAqIGNyZWF0ZXMgYSB3ZWJzb2NrZXQgY29ubmVjdGlvbiB0byBodHRwOi8vbG9jYWxob3N0OjEyMzQvbXktZG9jdW1lbnQtbmFtZVxuICpcbiAqIEBleGFtcGxlXG4gKiAgIGltcG9ydCAqIGFzIFkgZnJvbSAneWpzJ1xuICogICBpbXBvcnQgeyBXZWJzb2NrZXRQcm92aWRlciB9IGZyb20gJ3ktd2Vic29ja2V0J1xuICogICBjb25zdCBkb2MgPSBuZXcgWS5Eb2MoKVxuICogICBjb25zdCBwcm92aWRlciA9IG5ldyBXZWJzb2NrZXRQcm92aWRlcignaHR0cDovL2xvY2FsaG9zdDoxMjM0JywgJ215LWRvY3VtZW50LW5hbWUnLCBkb2MpXG4gKlxuICogQGV4dGVuZHMge09ic2VydmFibGVWMjx7ICdjb25uZWN0aW9uLWNsb3NlJzogKGV2ZW50OiBDbG9zZUV2ZW50IHwgbnVsbCwgIHByb3ZpZGVyOiBXZWJzb2NrZXRQcm92aWRlcikgPT4gYW55LCAnc3RhdHVzJzogKGV2ZW50OiB7IHN0YXR1czogJ2Nvbm5lY3RlZCcgfCAnZGlzY29ubmVjdGVkJyB8ICdjb25uZWN0aW5nJyB9KSA9PiBhbnksICdjb25uZWN0aW9uLWVycm9yJzogKGV2ZW50OiBFdmVudCwgcHJvdmlkZXI6IFdlYnNvY2tldFByb3ZpZGVyKSA9PiBhbnksICdzeW5jJzogKHN0YXRlOiBib29sZWFuKSA9PiBhbnkgfT59XG4gKi9cbmV4cG9ydCBjbGFzcyBXZWJzb2NrZXRQcm92aWRlciBleHRlbmRzIE9ic2VydmFibGVWMiB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2VydmVyVXJsXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByb29tbmFtZVxuICAgKiBAcGFyYW0ge1kuRG9jfSBkb2NcbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdHNcbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5jb25uZWN0XVxuICAgKiBAcGFyYW0ge2F3YXJlbmVzc1Byb3RvY29sLkF3YXJlbmVzc30gW29wdHMuYXdhcmVuZXNzXVxuICAgKiBAcGFyYW0ge09iamVjdDxzdHJpbmcsc3RyaW5nPn0gW29wdHMucGFyYW1zXSBzcGVjaWZ5IHVybCBwYXJhbWV0ZXJzXG4gICAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gW29wdHMucHJvdG9jb2xzXSBzcGVjaWZ5IHdlYnNvY2tldCBwcm90b2NvbHNcbiAgICogQHBhcmFtIHt0eXBlb2YgV2ViU29ja2V0fSBbb3B0cy5XZWJTb2NrZXRQb2x5ZmlsbF0gT3B0aW9uYWxsIHByb3ZpZGUgYSBXZWJTb2NrZXQgcG9seWZpbGxcbiAgICogQHBhcmFtIHtudW1iZXJ9IFtvcHRzLnJlc3luY0ludGVydmFsXSBSZXF1ZXN0IHNlcnZlciBzdGF0ZSBldmVyeSBgcmVzeW5jSW50ZXJ2YWxgIG1pbGxpc2Vjb25kc1xuICAgKiBAcGFyYW0ge251bWJlcn0gW29wdHMubWF4QmFja29mZlRpbWVdIE1heGltdW0gYW1vdW50IG9mIHRpbWUgdG8gd2FpdCBiZWZvcmUgdHJ5aW5nIHRvIHJlY29ubmVjdCAod2UgdHJ5IHRvIHJlY29ubmVjdCB1c2luZyBleHBvbmVudGlhbCBiYWNrb2ZmKVxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLmRpc2FibGVCY10gRGlzYWJsZSBjcm9zcy10YWIgQnJvYWRjYXN0Q2hhbm5lbCBjb21tdW5pY2F0aW9uXG4gICAqL1xuICBjb25zdHJ1Y3RvciAoc2VydmVyVXJsLCByb29tbmFtZSwgZG9jLCB7XG4gICAgY29ubmVjdCA9IHRydWUsXG4gICAgYXdhcmVuZXNzID0gbmV3IGF3YXJlbmVzc1Byb3RvY29sLkF3YXJlbmVzcyhkb2MpLFxuICAgIHBhcmFtcyA9IHt9LFxuICAgIHByb3RvY29scyA9IFtdLFxuICAgIFdlYlNvY2tldFBvbHlmaWxsID0gV2ViU29ja2V0LFxuICAgIHJlc3luY0ludGVydmFsID0gLTEsXG4gICAgbWF4QmFja29mZlRpbWUgPSAyNTAwLFxuICAgIGRpc2FibGVCYyA9IGZhbHNlXG4gIH0gPSB7fSkge1xuICAgIHN1cGVyKClcbiAgICAvLyBlbnN1cmUgdGhhdCBzZXJ2ZXJVcmwgZG9lcyBub3QgZW5kIHdpdGggL1xuICAgIHdoaWxlIChzZXJ2ZXJVcmxbc2VydmVyVXJsLmxlbmd0aCAtIDFdID09PSAnLycpIHtcbiAgICAgIHNlcnZlclVybCA9IHNlcnZlclVybC5zbGljZSgwLCBzZXJ2ZXJVcmwubGVuZ3RoIC0gMSlcbiAgICB9XG4gICAgdGhpcy5zZXJ2ZXJVcmwgPSBzZXJ2ZXJVcmxcbiAgICB0aGlzLmJjQ2hhbm5lbCA9IHNlcnZlclVybCArICcvJyArIHJvb21uYW1lXG4gICAgdGhpcy5tYXhCYWNrb2ZmVGltZSA9IG1heEJhY2tvZmZUaW1lXG4gICAgLyoqXG4gICAgICogVGhlIHNwZWNpZmllZCB1cmwgcGFyYW1ldGVycy4gVGhpcyBjYW4gYmUgc2FmZWx5IHVwZGF0ZWQuIFRoZSBjaGFuZ2VkIHBhcmFtZXRlcnMgd2lsbCBiZSB1c2VkXG4gICAgICogd2hlbiBhIG5ldyBjb25uZWN0aW9uIGlzIGVzdGFibGlzaGVkLlxuICAgICAqIEB0eXBlIHtPYmplY3Q8c3RyaW5nLHN0cmluZz59XG4gICAgICovXG4gICAgdGhpcy5wYXJhbXMgPSBwYXJhbXNcbiAgICB0aGlzLnByb3RvY29scyA9IHByb3RvY29sc1xuICAgIHRoaXMucm9vbW5hbWUgPSByb29tbmFtZVxuICAgIHRoaXMuZG9jID0gZG9jXG4gICAgdGhpcy5fV1MgPSBXZWJTb2NrZXRQb2x5ZmlsbFxuICAgIHRoaXMuYXdhcmVuZXNzID0gYXdhcmVuZXNzXG4gICAgdGhpcy53c2Nvbm5lY3RlZCA9IGZhbHNlXG4gICAgdGhpcy53c2Nvbm5lY3RpbmcgPSBmYWxzZVxuICAgIHRoaXMuYmNjb25uZWN0ZWQgPSBmYWxzZVxuICAgIHRoaXMuZGlzYWJsZUJjID0gZGlzYWJsZUJjXG4gICAgdGhpcy53c1Vuc3VjY2Vzc2Z1bFJlY29ubmVjdHMgPSAwXG4gICAgdGhpcy5tZXNzYWdlSGFuZGxlcnMgPSBtZXNzYWdlSGFuZGxlcnMuc2xpY2UoKVxuICAgIC8qKlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIHRoaXMuX3N5bmNlZCA9IGZhbHNlXG4gICAgLyoqXG4gICAgICogQHR5cGUge1dlYlNvY2tldD99XG4gICAgICovXG4gICAgdGhpcy53cyA9IG51bGxcbiAgICB0aGlzLndzTGFzdE1lc3NhZ2VSZWNlaXZlZCA9IDBcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRvIGNvbm5lY3QgdG8gb3RoZXIgcGVlcnMgb3Igbm90XG4gICAgICogQHR5cGUge2Jvb2xlYW59XG4gICAgICovXG4gICAgdGhpcy5zaG91bGRDb25uZWN0ID0gY29ubmVjdFxuXG4gICAgLyoqXG4gICAgICogQHR5cGUge251bWJlcn1cbiAgICAgKi9cbiAgICB0aGlzLl9yZXN5bmNJbnRlcnZhbCA9IDBcbiAgICBpZiAocmVzeW5jSW50ZXJ2YWwgPiAwKSB7XG4gICAgICB0aGlzLl9yZXN5bmNJbnRlcnZhbCA9IC8qKiBAdHlwZSB7YW55fSAqLyAoc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy53cyAmJiB0aGlzLndzLnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOKSB7XG4gICAgICAgICAgLy8gcmVzZW5kIHN5bmMgc3RlcCAxXG4gICAgICAgICAgY29uc3QgZW5jb2RlciA9IGVuY29kaW5nLmNyZWF0ZUVuY29kZXIoKVxuICAgICAgICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLCBtZXNzYWdlU3luYylcbiAgICAgICAgICBzeW5jUHJvdG9jb2wud3JpdGVTeW5jU3RlcDEoZW5jb2RlciwgZG9jKVxuICAgICAgICAgIHRoaXMud3Muc2VuZChlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlcikpXG4gICAgICAgIH1cbiAgICAgIH0sIHJlc3luY0ludGVydmFsKSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge0FycmF5QnVmZmVyfSBkYXRhXG4gICAgICogQHBhcmFtIHthbnl9IG9yaWdpblxuICAgICAqL1xuICAgIHRoaXMuX2JjU3Vic2NyaWJlciA9IChkYXRhLCBvcmlnaW4pID0+IHtcbiAgICAgIGlmIChvcmlnaW4gIT09IHRoaXMpIHtcbiAgICAgICAgY29uc3QgZW5jb2RlciA9IHJlYWRNZXNzYWdlKHRoaXMsIG5ldyBVaW50OEFycmF5KGRhdGEpLCBmYWxzZSlcbiAgICAgICAgaWYgKGVuY29kaW5nLmxlbmd0aChlbmNvZGVyKSA+IDEpIHtcbiAgICAgICAgICBiYy5wdWJsaXNoKHRoaXMuYmNDaGFubmVsLCBlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlciksIHRoaXMpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogTGlzdGVucyB0byBZanMgdXBkYXRlcyBhbmQgc2VuZHMgdGhlbSB0byByZW1vdGUgcGVlcnMgKHdzIGFuZCBicm9hZGNhc3RjaGFubmVsKVxuICAgICAqIEBwYXJhbSB7VWludDhBcnJheX0gdXBkYXRlXG4gICAgICogQHBhcmFtIHthbnl9IG9yaWdpblxuICAgICAqL1xuICAgIHRoaXMuX3VwZGF0ZUhhbmRsZXIgPSAodXBkYXRlLCBvcmlnaW4pID0+IHtcbiAgICAgIGlmIChvcmlnaW4gIT09IHRoaXMpIHtcbiAgICAgICAgY29uc3QgZW5jb2RlciA9IGVuY29kaW5nLmNyZWF0ZUVuY29kZXIoKVxuICAgICAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2RlciwgbWVzc2FnZVN5bmMpXG4gICAgICAgIHN5bmNQcm90b2NvbC53cml0ZVVwZGF0ZShlbmNvZGVyLCB1cGRhdGUpXG4gICAgICAgIGJyb2FkY2FzdE1lc3NhZ2UodGhpcywgZW5jb2RpbmcudG9VaW50OEFycmF5KGVuY29kZXIpKVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmRvYy5vbigndXBkYXRlJywgdGhpcy5fdXBkYXRlSGFuZGxlcilcbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge2FueX0gY2hhbmdlZFxuICAgICAqIEBwYXJhbSB7YW55fSBfb3JpZ2luXG4gICAgICovXG4gICAgdGhpcy5fYXdhcmVuZXNzVXBkYXRlSGFuZGxlciA9ICh7IGFkZGVkLCB1cGRhdGVkLCByZW1vdmVkIH0sIF9vcmlnaW4pID0+IHtcbiAgICAgIGNvbnN0IGNoYW5nZWRDbGllbnRzID0gYWRkZWQuY29uY2F0KHVwZGF0ZWQpLmNvbmNhdChyZW1vdmVkKVxuICAgICAgY29uc3QgZW5jb2RlciA9IGVuY29kaW5nLmNyZWF0ZUVuY29kZXIoKVxuICAgICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50KGVuY29kZXIsIG1lc3NhZ2VBd2FyZW5lc3MpXG4gICAgICBlbmNvZGluZy53cml0ZVZhclVpbnQ4QXJyYXkoXG4gICAgICAgIGVuY29kZXIsXG4gICAgICAgIGF3YXJlbmVzc1Byb3RvY29sLmVuY29kZUF3YXJlbmVzc1VwZGF0ZShhd2FyZW5lc3MsIGNoYW5nZWRDbGllbnRzKVxuICAgICAgKVxuICAgICAgYnJvYWRjYXN0TWVzc2FnZSh0aGlzLCBlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlcikpXG4gICAgfVxuICAgIHRoaXMuX2V4aXRIYW5kbGVyID0gKCkgPT4ge1xuICAgICAgYXdhcmVuZXNzUHJvdG9jb2wucmVtb3ZlQXdhcmVuZXNzU3RhdGVzKFxuICAgICAgICB0aGlzLmF3YXJlbmVzcyxcbiAgICAgICAgW2RvYy5jbGllbnRJRF0sXG4gICAgICAgICdhcHAgY2xvc2VkJ1xuICAgICAgKVxuICAgIH1cbiAgICBpZiAoZW52LmlzTm9kZSAmJiB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHByb2Nlc3Mub24oJ2V4aXQnLCB0aGlzLl9leGl0SGFuZGxlcilcbiAgICB9XG4gICAgYXdhcmVuZXNzLm9uKCd1cGRhdGUnLCB0aGlzLl9hd2FyZW5lc3NVcGRhdGVIYW5kbGVyKVxuICAgIHRoaXMuX2NoZWNrSW50ZXJ2YWwgPSAvKiogQHR5cGUge2FueX0gKi8gKHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy53c2Nvbm5lY3RlZCAmJlxuICAgICAgICBtZXNzYWdlUmVjb25uZWN0VGltZW91dCA8XG4gICAgICAgICAgdGltZS5nZXRVbml4VGltZSgpIC0gdGhpcy53c0xhc3RNZXNzYWdlUmVjZWl2ZWRcbiAgICAgICkge1xuICAgICAgICAvLyBubyBtZXNzYWdlIHJlY2VpdmVkIGluIGEgbG9uZyB0aW1lIC0gbm90IGV2ZW4geW91ciBvd24gYXdhcmVuZXNzXG4gICAgICAgIC8vIHVwZGF0ZXMgKHdoaWNoIGFyZSB1cGRhdGVkIGV2ZXJ5IDE1IHNlY29uZHMpXG4gICAgICAgIGNsb3NlV2Vic29ja2V0Q29ubmVjdGlvbih0aGlzLCAvKiogQHR5cGUge1dlYlNvY2tldH0gKi8gKHRoaXMud3MpLCBudWxsKVxuICAgICAgfVxuICAgIH0sIG1lc3NhZ2VSZWNvbm5lY3RUaW1lb3V0IC8gMTApKVxuICAgIGlmIChjb25uZWN0KSB7XG4gICAgICB0aGlzLmNvbm5lY3QoKVxuICAgIH1cbiAgfVxuXG4gIGdldCB1cmwgKCkge1xuICAgIGNvbnN0IGVuY29kZWRQYXJhbXMgPSB1cmwuZW5jb2RlUXVlcnlQYXJhbXModGhpcy5wYXJhbXMpXG4gICAgcmV0dXJuIHRoaXMuc2VydmVyVXJsICsgJy8nICsgdGhpcy5yb29tbmFtZSArXG4gICAgICAoZW5jb2RlZFBhcmFtcy5sZW5ndGggPT09IDAgPyAnJyA6ICc/JyArIGVuY29kZWRQYXJhbXMpXG4gIH1cblxuICAvKipcbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqL1xuICBnZXQgc3luY2VkICgpIHtcbiAgICByZXR1cm4gdGhpcy5fc3luY2VkXG4gIH1cblxuICBzZXQgc3luY2VkIChzdGF0ZSkge1xuICAgIGlmICh0aGlzLl9zeW5jZWQgIT09IHN0YXRlKSB7XG4gICAgICB0aGlzLl9zeW5jZWQgPSBzdGF0ZVxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgdGhpcy5lbWl0KCdzeW5jZWQnLCBbc3RhdGVdKVxuICAgICAgdGhpcy5lbWl0KCdzeW5jJywgW3N0YXRlXSlcbiAgICB9XG4gIH1cblxuICBkZXN0cm95ICgpIHtcbiAgICBpZiAodGhpcy5fcmVzeW5jSW50ZXJ2YWwgIT09IDApIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5fcmVzeW5jSW50ZXJ2YWwpXG4gICAgfVxuICAgIGNsZWFySW50ZXJ2YWwodGhpcy5fY2hlY2tJbnRlcnZhbClcbiAgICB0aGlzLmRpc2Nvbm5lY3QoKVxuICAgIGlmIChlbnYuaXNOb2RlICYmIHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcHJvY2Vzcy5vZmYoJ2V4aXQnLCB0aGlzLl9leGl0SGFuZGxlcilcbiAgICB9XG4gICAgdGhpcy5hd2FyZW5lc3Mub2ZmKCd1cGRhdGUnLCB0aGlzLl9hd2FyZW5lc3NVcGRhdGVIYW5kbGVyKVxuICAgIHRoaXMuZG9jLm9mZigndXBkYXRlJywgdGhpcy5fdXBkYXRlSGFuZGxlcilcbiAgICBzdXBlci5kZXN0cm95KClcbiAgfVxuXG4gIGNvbm5lY3RCYyAoKSB7XG4gICAgaWYgKHRoaXMuZGlzYWJsZUJjKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKCF0aGlzLmJjY29ubmVjdGVkKSB7XG4gICAgICBiYy5zdWJzY3JpYmUodGhpcy5iY0NoYW5uZWwsIHRoaXMuX2JjU3Vic2NyaWJlcilcbiAgICAgIHRoaXMuYmNjb25uZWN0ZWQgPSB0cnVlXG4gICAgfVxuICAgIC8vIHNlbmQgc3luYyBzdGVwMSB0byBiY1xuICAgIC8vIHdyaXRlIHN5bmMgc3RlcCAxXG4gICAgY29uc3QgZW5jb2RlclN5bmMgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKClcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2RlclN5bmMsIG1lc3NhZ2VTeW5jKVxuICAgIHN5bmNQcm90b2NvbC53cml0ZVN5bmNTdGVwMShlbmNvZGVyU3luYywgdGhpcy5kb2MpXG4gICAgYmMucHVibGlzaCh0aGlzLmJjQ2hhbm5lbCwgZW5jb2RpbmcudG9VaW50OEFycmF5KGVuY29kZXJTeW5jKSwgdGhpcylcbiAgICAvLyBicm9hZGNhc3QgbG9jYWwgc3RhdGVcbiAgICBjb25zdCBlbmNvZGVyU3RhdGUgPSBlbmNvZGluZy5jcmVhdGVFbmNvZGVyKClcbiAgICBlbmNvZGluZy53cml0ZVZhclVpbnQoZW5jb2RlclN0YXRlLCBtZXNzYWdlU3luYylcbiAgICBzeW5jUHJvdG9jb2wud3JpdGVTeW5jU3RlcDIoZW5jb2RlclN0YXRlLCB0aGlzLmRvYylcbiAgICBiYy5wdWJsaXNoKHRoaXMuYmNDaGFubmVsLCBlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlclN0YXRlKSwgdGhpcylcbiAgICAvLyB3cml0ZSBxdWVyeUF3YXJlbmVzc1xuICAgIGNvbnN0IGVuY29kZXJBd2FyZW5lc3NRdWVyeSA9IGVuY29kaW5nLmNyZWF0ZUVuY29kZXIoKVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyQXdhcmVuZXNzUXVlcnksIG1lc3NhZ2VRdWVyeUF3YXJlbmVzcylcbiAgICBiYy5wdWJsaXNoKFxuICAgICAgdGhpcy5iY0NoYW5uZWwsXG4gICAgICBlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlckF3YXJlbmVzc1F1ZXJ5KSxcbiAgICAgIHRoaXNcbiAgICApXG4gICAgLy8gYnJvYWRjYXN0IGxvY2FsIGF3YXJlbmVzcyBzdGF0ZVxuICAgIGNvbnN0IGVuY29kZXJBd2FyZW5lc3NTdGF0ZSA9IGVuY29kaW5nLmNyZWF0ZUVuY29kZXIoKVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyQXdhcmVuZXNzU3RhdGUsIG1lc3NhZ2VBd2FyZW5lc3MpXG4gICAgZW5jb2Rpbmcud3JpdGVWYXJVaW50OEFycmF5KFxuICAgICAgZW5jb2RlckF3YXJlbmVzc1N0YXRlLFxuICAgICAgYXdhcmVuZXNzUHJvdG9jb2wuZW5jb2RlQXdhcmVuZXNzVXBkYXRlKHRoaXMuYXdhcmVuZXNzLCBbXG4gICAgICAgIHRoaXMuZG9jLmNsaWVudElEXG4gICAgICBdKVxuICAgIClcbiAgICBiYy5wdWJsaXNoKFxuICAgICAgdGhpcy5iY0NoYW5uZWwsXG4gICAgICBlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlckF3YXJlbmVzc1N0YXRlKSxcbiAgICAgIHRoaXNcbiAgICApXG4gIH1cblxuICBkaXNjb25uZWN0QmMgKCkge1xuICAgIC8vIGJyb2FkY2FzdCBtZXNzYWdlIHdpdGggbG9jYWwgYXdhcmVuZXNzIHN0YXRlIHNldCB0byBudWxsIChpbmRpY2F0aW5nIGRpc2Nvbm5lY3QpXG4gICAgY29uc3QgZW5jb2RlciA9IGVuY29kaW5nLmNyZWF0ZUVuY29kZXIoKVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludChlbmNvZGVyLCBtZXNzYWdlQXdhcmVuZXNzKVxuICAgIGVuY29kaW5nLndyaXRlVmFyVWludDhBcnJheShcbiAgICAgIGVuY29kZXIsXG4gICAgICBhd2FyZW5lc3NQcm90b2NvbC5lbmNvZGVBd2FyZW5lc3NVcGRhdGUodGhpcy5hd2FyZW5lc3MsIFtcbiAgICAgICAgdGhpcy5kb2MuY2xpZW50SURcbiAgICAgIF0sIG5ldyBNYXAoKSlcbiAgICApXG4gICAgYnJvYWRjYXN0TWVzc2FnZSh0aGlzLCBlbmNvZGluZy50b1VpbnQ4QXJyYXkoZW5jb2RlcikpXG4gICAgaWYgKHRoaXMuYmNjb25uZWN0ZWQpIHtcbiAgICAgIGJjLnVuc3Vic2NyaWJlKHRoaXMuYmNDaGFubmVsLCB0aGlzLl9iY1N1YnNjcmliZXIpXG4gICAgICB0aGlzLmJjY29ubmVjdGVkID0gZmFsc2VcbiAgICB9XG4gIH1cblxuICBkaXNjb25uZWN0ICgpIHtcbiAgICB0aGlzLnNob3VsZENvbm5lY3QgPSBmYWxzZVxuICAgIHRoaXMuZGlzY29ubmVjdEJjKClcbiAgICBpZiAodGhpcy53cyAhPT0gbnVsbCkge1xuICAgICAgY2xvc2VXZWJzb2NrZXRDb25uZWN0aW9uKHRoaXMsIHRoaXMud3MsIG51bGwpXG4gICAgfVxuICB9XG5cbiAgY29ubmVjdCAoKSB7XG4gICAgdGhpcy5zaG91bGRDb25uZWN0ID0gdHJ1ZVxuICAgIGlmICghdGhpcy53c2Nvbm5lY3RlZCAmJiB0aGlzLndzID09PSBudWxsKSB7XG4gICAgICBzZXR1cFdTKHRoaXMpXG4gICAgICB0aGlzLmNvbm5lY3RCYygpXG4gICAgfVxuICB9XG59XG4iLCAiaW1wb3J0IHsgcmVxdWVzdFVybCB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHR5cGUge1xuICBBdHRhY2htZW50LFxuICBBdHRhY2htZW50TGlzdFJlc3BvbnNlLFxuICBDcmVhdGVEb2N1bWVudFJlc3BvbnNlLFxuICBDcmVhdGVGb2xkZXJSZXNwb25zZSxcbiAgRGV2aWNlUG9sbFJlc3BvbnNlLFxuICBEZXZpY2VTdGFydFJlc3BvbnNlLFxuICBNZVJlc3BvbnNlLFxuICBSZW1vdGVEb2N1bWVudFdpdGhDb250ZW50LFxuICBSZW1vdGVUcmVlLFxuICBTZWFyY2hSZXNwb25zZSxcbiAgV3JpdGVSZXN1bHQsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBjbGFzcyBQYWdlZGVuQXBpRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlYWRvbmx5IHN0YXR1czogbnVtYmVyLFxuICAgIHJlYWRvbmx5IGJvZHk6IHVua25vd24sXG4gICkge1xuICAgIHN1cGVyKGBQYWdlZGVuIEFQSSBlcnJvciAke3N0YXR1c31gKTtcbiAgICB0aGlzLm5hbWUgPSBcIlBhZ2VkZW5BcGlFcnJvclwiO1xuICB9XG5cbiAgZ2V0IGNvZGUoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy5ib2R5ICYmIHR5cGVvZiB0aGlzLmJvZHkgPT09IFwib2JqZWN0XCIgJiYgXCJlcnJvclwiIGluIHRoaXMuYm9keSkge1xuICAgICAgcmV0dXJuIFN0cmluZygodGhpcy5ib2R5IGFzIHsgZXJyb3I6IHVua25vd24gfSkuZXJyb3IpO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgZ2V0IGN1cnJlbnRWZXJzaW9uKCk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICh0aGlzLmJvZHkgJiYgdHlwZW9mIHRoaXMuYm9keSA9PT0gXCJvYmplY3RcIiAmJiBcImN1cnJlbnRWZXJzaW9uXCIgaW4gdGhpcy5ib2R5KSB7XG4gICAgICBjb25zdCB2YWx1ZSA9ICh0aGlzLmJvZHkgYXMgeyBjdXJyZW50VmVyc2lvbjogdW5rbm93biB9KS5jdXJyZW50VmVyc2lvbjtcbiAgICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZSA6IG51bGw7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWVzdFRyYW5zcG9ydCB7XG4gIHJlcXVlc3Qob3B0aW9uczoge1xuICAgIHVybDogc3RyaW5nO1xuICAgIG1ldGhvZDogc3RyaW5nO1xuICAgIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAgIGJvZHk/OiBzdHJpbmcgfCBBcnJheUJ1ZmZlcjtcbiAgfSk6IFByb21pc2U8eyBzdGF0dXM6IG51bWJlcjsgdGV4dDogc3RyaW5nOyBhcnJheUJ1ZmZlcj86IEFycmF5QnVmZmVyIH0+O1xufVxuXG5leHBvcnQgY2xhc3MgT2JzaWRpYW5SZXF1ZXN0VHJhbnNwb3J0IGltcGxlbWVudHMgUmVxdWVzdFRyYW5zcG9ydCB7XG4gIGFzeW5jIHJlcXVlc3Qob3B0aW9uczogeyB1cmw6IHN0cmluZzsgbWV0aG9kOiBzdHJpbmc7IGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+OyBib2R5Pzogc3RyaW5nIHwgQXJyYXlCdWZmZXIgfSkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFVybChvcHRpb25zKTtcbiAgICByZXR1cm4geyBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cywgdGV4dDogcmVzcG9uc2UudGV4dCwgYXJyYXlCdWZmZXI6IHJlc3BvbnNlLmFycmF5QnVmZmVyIH07XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFBhZ2VkZW5BcGlDbGllbnQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNlcnZlclVybDogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdG9rZW46IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRyYW5zcG9ydDogUmVxdWVzdFRyYW5zcG9ydCA9IG5ldyBPYnNpZGlhblJlcXVlc3RUcmFuc3BvcnQoKSxcbiAgKSB7fVxuXG4gIG1lKCk6IFByb21pc2U8TWVSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QoXCJHRVRcIiwgXCIvbWVcIik7XG4gIH1cblxuICBhc3luYyB2YWxpZGF0ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLm1lKCk7XG4gIH1cblxuICB0cmVlKHdvcmtzcGFjZUlkOiBzdHJpbmcpOiBQcm9taXNlPFJlbW90ZVRyZWU+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KFwiR0VUXCIsIGAvZG9jdW1lbnRzL3RyZWU/d29ya3NwYWNlSWQ9JHtlbmNvZGVVUklDb21wb25lbnQod29ya3NwYWNlSWQpfWApO1xuICB9XG5cbiAgZG9jdW1lbnQoaWQ6IHN0cmluZyk6IFByb21pc2U8UmVtb3RlRG9jdW1lbnRXaXRoQ29udGVudD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QoXCJHRVRcIiwgYC9kb2N1bWVudHMvJHtlbmNvZGVVUklDb21wb25lbnQoaWQpfWApO1xuICB9XG5cbiAgY3JlYXRlRm9sZGVyKGJvZHk6IHsgd29ya3NwYWNlSWQ6IHN0cmluZzsgcGFyZW50Rm9sZGVySWQ6IHN0cmluZyB8IG51bGw7IG5hbWU6IHN0cmluZzsgc2x1Zzogc3RyaW5nIH0pOiBQcm9taXNlPENyZWF0ZUZvbGRlclJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChcIlBPU1RcIiwgXCIvZm9sZGVyc1wiLCBib2R5KTtcbiAgfVxuXG4gIGNyZWF0ZURvY3VtZW50KGJvZHk6IHsgd29ya3NwYWNlSWQ6IHN0cmluZzsgZm9sZGVySWQ6IHN0cmluZzsgdGl0bGU6IHN0cmluZzsgc2x1Zzogc3RyaW5nOyBjb250ZW50OiBzdHJpbmcgfSk6IFByb21pc2U8Q3JlYXRlRG9jdW1lbnRSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QoXCJQT1NUXCIsIFwiL2RvY3VtZW50c1wiLCBib2R5KTtcbiAgfVxuXG4gIHB1c2goZG9jdW1lbnRJZDogc3RyaW5nLCBib2R5OiB7IGJhc2VWZXJzaW9uOiBzdHJpbmc7IGNoZWNrc3VtOiBzdHJpbmc7IGNvbnRlbnQ6IHN0cmluZyB9KTogUHJvbWlzZTxXcml0ZVJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QoXCJQT1NUXCIsIGAvZG9jdW1lbnRzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGRvY3VtZW50SWQpfS9wdXNoYCwgYm9keSk7XG4gIH1cblxuICBzZWFyY2god29ya3NwYWNlSWQ6IHN0cmluZywgcTogc3RyaW5nLCBsaW1pdCA9IDIwKTogUHJvbWlzZTxTZWFyY2hSZXNwb25zZT4ge1xuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoeyB3b3Jrc3BhY2VJZCwgcSwgbGltaXQ6IFN0cmluZyhsaW1pdCkgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChcIkdFVFwiLCBgL3NlYXJjaD8ke3BhcmFtcy50b1N0cmluZygpfWApO1xuICB9XG5cbiAgZGV2aWNlU3RhcnQoKTogUHJvbWlzZTxEZXZpY2VTdGFydFJlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChcIlBPU1RcIiwgXCIvYXV0aC9kZXZpY2Uvc3RhcnRcIiwgdW5kZWZpbmVkLCB7IGF1dGg6IGZhbHNlIH0pO1xuICB9XG5cbiAgZGV2aWNlUG9sbChkZXZpY2VDb2RlOiBzdHJpbmcpOiBQcm9taXNlPERldmljZVBvbGxSZXNwb25zZT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QoXCJQT1NUXCIsIFwiL2F1dGgvZGV2aWNlL3BvbGxcIiwgeyBkZXZpY2VDb2RlIH0sIHsgYXV0aDogZmFsc2UgfSk7XG4gIH1cblxuICBhdHRhY2htZW50cyhkb2N1bWVudElkOiBzdHJpbmcpOiBQcm9taXNlPEF0dGFjaG1lbnRMaXN0UmVzcG9uc2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KFwiR0VUXCIsIGAvZG9jdW1lbnRzLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGRvY3VtZW50SWQpfS9hdHRhY2htZW50c2ApO1xuICB9XG5cbiAgdXBsb2FkQXR0YWNobWVudChkb2N1bWVudElkOiBzdHJpbmcsIGZpbGVuYW1lOiBzdHJpbmcsIGRhdGE6IEFycmF5QnVmZmVyLCBjb250ZW50VHlwZSA9IFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCIpOiBQcm9taXNlPEF0dGFjaG1lbnQ+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KFwiUE9TVFwiLCBgL2RvY3VtZW50cy8ke2VuY29kZVVSSUNvbXBvbmVudChkb2N1bWVudElkKX0vYXR0YWNobWVudHM/ZmlsZW5hbWU9JHtlbmNvZGVVUklDb21wb25lbnQoZmlsZW5hbWUpfWAsIGRhdGEsIHtcbiAgICAgIGNvbnRlbnRUeXBlLFxuICAgICAgcmF3OiB0cnVlLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZG93bmxvYWRBdHRhY2htZW50KGF0dGFjaG1lbnRJZDogc3RyaW5nKTogUHJvbWlzZTxBcnJheUJ1ZmZlcj4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5yYXdSZXF1ZXN0KFwiR0VUXCIsIGAvYXR0YWNobWVudHMvJHtlbmNvZGVVUklDb21wb25lbnQoYXR0YWNobWVudElkKX1gKTtcbiAgICBpZiAocmVzcG9uc2UuYXJyYXlCdWZmZXIpIHJldHVybiByZXNwb25zZS5hcnJheUJ1ZmZlcjtcbiAgICByZXR1cm4gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHJlc3BvbnNlLnRleHQpLmJ1ZmZlcjtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZUF0dGFjaG1lbnQoYXR0YWNobWVudElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnJlcXVlc3QoXCJERUxFVEVcIiwgYC9hdHRhY2htZW50cy8ke2VuY29kZVVSSUNvbXBvbmVudChhdHRhY2htZW50SWQpfWApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZXF1ZXN0PFQ+KFxuICAgIG1ldGhvZDogc3RyaW5nLFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBib2R5PzogdW5rbm93bixcbiAgICBvcHRpb25zOiB7IGF1dGg/OiBib29sZWFuOyBjb250ZW50VHlwZT86IHN0cmluZzsgcmF3PzogYm9vbGVhbiB9ID0ge30sXG4gICk6IFByb21pc2U8VD4ge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5yYXdSZXF1ZXN0KG1ldGhvZCwgcGF0aCwgYm9keSwgb3B0aW9ucyk7XG4gICAgY29uc3QganNvbiA9IHNhZmVKc29uKHJlc3BvbnNlLnRleHQpO1xuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPCAyMDAgfHwgcmVzcG9uc2Uuc3RhdHVzID49IDMwMCkge1xuICAgICAgdGhyb3cgbmV3IFBhZ2VkZW5BcGlFcnJvcihyZXNwb25zZS5zdGF0dXMsIGpzb24pO1xuICAgIH1cbiAgICByZXR1cm4ganNvbiBhcyBUO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByYXdSZXF1ZXN0KFxuICAgIG1ldGhvZDogc3RyaW5nLFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBib2R5PzogdW5rbm93bixcbiAgICBvcHRpb25zOiB7IGF1dGg/OiBib29sZWFuOyBjb250ZW50VHlwZT86IHN0cmluZzsgcmF3PzogYm9vbGVhbiB9ID0ge30sXG4gICk6IFByb21pc2U8eyBzdGF0dXM6IG51bWJlcjsgdGV4dDogc3RyaW5nOyBhcnJheUJ1ZmZlcj86IEFycmF5QnVmZmVyIH0+IHtcbiAgICBjb25zdCBoZWFkZXJzID0ge1xuICAgICAgLi4uKG9wdGlvbnMuYXV0aCA9PT0gZmFsc2UgfHwgIXRoaXMudG9rZW4gPyB7fSA6IHsgYXV0aG9yaXphdGlvbjogYEJlYXJlciAke3RoaXMudG9rZW59YCB9KSxcbiAgICAgIC4uLihib2R5ID09PSB1bmRlZmluZWQgPyB7fSA6IHsgXCJjb250ZW50LXR5cGVcIjogb3B0aW9ucy5jb250ZW50VHlwZSA/PyBcImFwcGxpY2F0aW9uL2pzb25cIiB9KSxcbiAgICB9O1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy50cmFuc3BvcnQucmVxdWVzdCh7XG4gICAgICBtZXRob2QsXG4gICAgICB1cmw6IGAke3RoaXMuc2VydmVyVXJsLnJlcGxhY2UoL1xcLyskLywgXCJcIil9L2FwaSR7cGF0aH1gLFxuICAgICAgaGVhZGVycyxcbiAgICAgIGJvZHk6IGJvZHkgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IG9wdGlvbnMucmF3ID8gKGJvZHkgYXMgQXJyYXlCdWZmZXIpIDogSlNPTi5zdHJpbmdpZnkoYm9keSksXG4gICAgfSk7XG4gICAgaWYgKHJlc3BvbnNlLnN0YXR1cyA8IDIwMCB8fCByZXNwb25zZS5zdGF0dXMgPj0gMzAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFnZWRlbkFwaUVycm9yKHJlc3BvbnNlLnN0YXR1cywgc2FmZUpzb24ocmVzcG9uc2UudGV4dCkpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2FmZUpzb24odGV4dDogc3RyaW5nKTogdW5rbm93biB7XG4gIGlmICghdGV4dCkgcmV0dXJuIG51bGw7XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UodGV4dCk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB0ZXh0O1xuICB9XG59XG4iLCAiaW1wb3J0IHR5cGUgeyBEYXRhQWRhcHRlciB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHR5cGUgeyBTZXJ2ZXJNZXRhQXR0YWNobWVudEVudHJ5LCBTZXJ2ZXJNZXRhRW50cnksIFNlcnZlck1ldGFGaWxlIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IGNsYXNzIFNlcnZlck1ldGFTdG9yZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGF0aDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYWRhcHRlcjogUGljazxEYXRhQWRhcHRlciwgXCJleGlzdHNcIiB8IFwicmVhZFwiIHwgXCJ3cml0ZVwiPixcbiAgICBwbHVnaW5EaXI6IHN0cmluZyxcbiAgKSB7XG4gICAgdGhpcy5wYXRoID0gYCR7cGx1Z2luRGlyLnJlcGxhY2UoL1xcLyskLywgXCJcIil9Ly5zZXJ2ZXItbWV0YS5qc29uYDtcbiAgfVxuXG4gIGdldCBmaWxlUGF0aCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnBhdGg7XG4gIH1cblxuICBhc3luYyByZWFkKCk6IFByb21pc2U8U2VydmVyTWV0YUZpbGU+IHtcbiAgICBpZiAoIShhd2FpdCB0aGlzLmFkYXB0ZXIuZXhpc3RzKHRoaXMucGF0aCkpKSByZXR1cm4geyBkb2N1bWVudHM6IHt9LCBhdHRhY2htZW50czoge30gfTtcbiAgICBjb25zdCByYXcgPSBhd2FpdCB0aGlzLmFkYXB0ZXIucmVhZCh0aGlzLnBhdGgpO1xuICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UocmF3KSBhcyBQYXJ0aWFsPFNlcnZlck1ldGFGaWxlPjtcbiAgICByZXR1cm4geyBkb2N1bWVudHM6IHBhcnNlZC5kb2N1bWVudHMgPz8ge30sIGF0dGFjaG1lbnRzOiBwYXJzZWQuYXR0YWNobWVudHMgPz8ge30gfTtcbiAgfVxuXG4gIGFzeW5jIHdyaXRlKG1ldGE6IFNlcnZlck1ldGFGaWxlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5hZGFwdGVyLndyaXRlKHRoaXMucGF0aCwgSlNPTi5zdHJpbmdpZnkobWV0YSwgbnVsbCwgMikpO1xuICB9XG5cbiAgYXN5bmMgbGlzdCgpOiBQcm9taXNlPFNlcnZlck1ldGFFbnRyeVtdPiB7XG4gICAgY29uc3QgbWV0YSA9IGF3YWl0IHRoaXMucmVhZCgpO1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKG1ldGEuZG9jdW1lbnRzKTtcbiAgfVxuXG4gIGFzeW5jIGdldEJ5TG9jYWxQYXRoKGxvY2FsUGF0aDogc3RyaW5nKTogUHJvbWlzZTxTZXJ2ZXJNZXRhRW50cnkgfCBudWxsPiB7XG4gICAgY29uc3QgbWV0YSA9IGF3YWl0IHRoaXMucmVhZCgpO1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKG1ldGEuZG9jdW1lbnRzKS5maW5kKChlbnRyeSkgPT4gZW50cnkubG9jYWxQYXRoID09PSBsb2NhbFBhdGgpID8/IG51bGw7XG4gIH1cblxuICBhc3luYyB1cHNlcnQoZW50cnk6IFNlcnZlck1ldGFFbnRyeSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1ldGEgPSBhd2FpdCB0aGlzLnJlYWQoKTtcbiAgICBtZXRhLmRvY3VtZW50c1tlbnRyeS5kb2N1bWVudElkXSA9IGVudHJ5O1xuICAgIGF3YWl0IHRoaXMud3JpdGUobWV0YSk7XG4gIH1cblxuICBhc3luYyBsaXN0QXR0YWNobWVudHMoKTogUHJvbWlzZTxTZXJ2ZXJNZXRhQXR0YWNobWVudEVudHJ5W10+IHtcbiAgICBjb25zdCBtZXRhID0gYXdhaXQgdGhpcy5yZWFkKCk7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXMobWV0YS5hdHRhY2htZW50cyA/PyB7fSk7XG4gIH1cblxuICBhc3luYyBsaXN0QXR0YWNobWVudHNGb3JEb2N1bWVudChkb2N1bWVudElkOiBzdHJpbmcpOiBQcm9taXNlPFNlcnZlck1ldGFBdHRhY2htZW50RW50cnlbXT4ge1xuICAgIGNvbnN0IG1ldGEgPSBhd2FpdCB0aGlzLnJlYWQoKTtcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhtZXRhLmF0dGFjaG1lbnRzID8/IHt9KS5maWx0ZXIoKGVudHJ5KSA9PiBlbnRyeS5kb2N1bWVudElkID09PSBkb2N1bWVudElkKTtcbiAgfVxuXG4gIGFzeW5jIHVwc2VydEF0dGFjaG1lbnQoZW50cnk6IFNlcnZlck1ldGFBdHRhY2htZW50RW50cnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtZXRhID0gYXdhaXQgdGhpcy5yZWFkKCk7XG4gICAgbWV0YS5hdHRhY2htZW50cyA/Pz0ge307XG4gICAgbWV0YS5hdHRhY2htZW50c1tlbnRyeS5hdHRhY2htZW50SWRdID0gZW50cnk7XG4gICAgYXdhaXQgdGhpcy53cml0ZShtZXRhKTtcbiAgfVxuXG4gIGFzeW5jIHJlbW92ZUF0dGFjaG1lbnQoYXR0YWNobWVudElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtZXRhID0gYXdhaXQgdGhpcy5yZWFkKCk7XG4gICAgaWYgKCFtZXRhLmF0dGFjaG1lbnRzKSByZXR1cm47XG4gICAgZGVsZXRlIG1ldGEuYXR0YWNobWVudHNbYXR0YWNobWVudElkXTtcbiAgICBhd2FpdCB0aGlzLndyaXRlKG1ldGEpO1xuICB9XG59XG4iLCAiaW1wb3J0IHsgbm9ybWFsaXplUGF0aCB9IGZyb20gXCJvYnNpZGlhblwiO1xuaW1wb3J0IHR5cGUgeyBQYWdlZGVuQXBpQ2xpZW50IH0gZnJvbSBcIi4vYXBpLWNsaWVudFwiO1xuaW1wb3J0IHsgUGFnZWRlbkFwaUVycm9yIH0gZnJvbSBcIi4vYXBpLWNsaWVudFwiO1xuaW1wb3J0IHsgY2Fub25pY2FsaXplLCBjaGVja3N1bSB9IGZyb20gXCIuL2NoZWNrc3VtXCI7XG5pbXBvcnQgdHlwZSB7IEF0dGFjaG1lbnQsIFJlbW90ZURvY3VtZW50LCBSZW1vdGVEb2N1bWVudFdpdGhDb250ZW50LCBSZW1vdGVGb2xkZXIsIFJlbW90ZVRyZWUsIFNlcnZlck1ldGFBdHRhY2htZW50RW50cnksIFNlcnZlck1ldGFFbnRyeSwgV3JpdGVSZXN1bHQgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZhdWx0TGlrZSB7XG4gIHJlYWQocGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+O1xuICB3cml0ZShwYXRoOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gIHJlYWRCaW5hcnk/KHBhdGg6IHN0cmluZyk6IFByb21pc2U8QXJyYXlCdWZmZXI+O1xuICB3cml0ZUJpbmFyeT8ocGF0aDogc3RyaW5nLCBjb250ZW50OiBBcnJheUJ1ZmZlcik6IFByb21pc2U8dm9pZD47XG4gIGV4aXN0cyhwYXRoOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+O1xuICBta2RpcihwYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1ldGFTdG9yZUxpa2Uge1xuICBsaXN0KCk6IFByb21pc2U8U2VydmVyTWV0YUVudHJ5W10+O1xuICBnZXRCeUxvY2FsUGF0aChwYXRoOiBzdHJpbmcpOiBQcm9taXNlPFNlcnZlck1ldGFFbnRyeSB8IG51bGw+O1xuICB1cHNlcnQoZW50cnk6IFNlcnZlck1ldGFFbnRyeSk6IFByb21pc2U8dm9pZD47XG4gIGxpc3RBdHRhY2htZW50c0ZvckRvY3VtZW50Pyhkb2N1bWVudElkOiBzdHJpbmcpOiBQcm9taXNlPFNlcnZlck1ldGFBdHRhY2htZW50RW50cnlbXT47XG4gIHVwc2VydEF0dGFjaG1lbnQ/KGVudHJ5OiBTZXJ2ZXJNZXRhQXR0YWNobWVudEVudHJ5KTogUHJvbWlzZTx2b2lkPjtcbiAgcmVtb3ZlQXR0YWNobWVudD8oYXR0YWNobWVudElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN5bmNEZXBzIHtcbiAgYXBpOiBQaWNrPFBhZ2VkZW5BcGlDbGllbnQsIFwiZG9jdW1lbnRcIiB8IFwicHVzaFwiPiAmXG4gICAgUGFydGlhbDxQaWNrPFBhZ2VkZW5BcGlDbGllbnQsIFwiYXR0YWNobWVudHNcIiB8IFwidXBsb2FkQXR0YWNobWVudFwiIHwgXCJkb3dubG9hZEF0dGFjaG1lbnRcIiB8IFwiZGVsZXRlQXR0YWNobWVudFwiPj47XG4gIHZhdWx0OiBWYXVsdExpa2U7XG4gIG1ldGE6IE1ldGFTdG9yZUxpa2U7XG4gIHJlbW90ZURvY3NGb2xkZXI6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVSZW1vdGVEZXBzIGV4dGVuZHMgU3luY0RlcHMge1xuICBhcGk6IFN5bmNEZXBzW1wiYXBpXCJdICYgUGljazxQYWdlZGVuQXBpQ2xpZW50LCBcInRyZWVcIiB8IFwiY3JlYXRlRm9sZGVyXCIgfCBcImNyZWF0ZURvY3VtZW50XCI+O1xuICB3b3Jrc3BhY2VJZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhY2tncm91bmRTeW5jRGVwcyBleHRlbmRzIFN5bmNEZXBzIHtcbiAgYXBpOiBTeW5jRGVwc1tcImFwaVwiXSAmIFBhcnRpYWw8UGljazxQYWdlZGVuQXBpQ2xpZW50LCBcInRyZWVcIiB8IFwiY3JlYXRlRm9sZGVyXCIgfCBcImNyZWF0ZURvY3VtZW50XCI+PjtcbiAgd29ya3NwYWNlSWQ/OiBzdHJpbmc7XG4gIGxvY2FsTWFya2Rvd25QYXRocz86ICgpID0+IFByb21pc2U8c3RyaW5nW10+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERvd25sb2FkUmVzdWx0IHtcbiAgbG9jYWxQYXRoOiBzdHJpbmc7XG4gIG1ldGE6IFNlcnZlck1ldGFFbnRyeTtcbiAgYXR0YWNobWVudHM6IEF0dGFjaG1lbnRTeW5jU3VtbWFyeTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQdXNoUmVzdWx0IHtcbiAgc3RhdHVzOiBcInB1c2hlZFwiIHwgXCJjcmVhdGVkXCIgfCBcImJsb2NrZWRfdmlld2VyXCIgfCBcImNvbmZsaWN0XCI7XG4gIHJlc3VsdD86IFdyaXRlUmVzdWx0O1xuICBjb25mbGljdFBhdGg/OiBzdHJpbmc7XG4gIHNlcnZlclBhdGg/OiBzdHJpbmc7XG4gIG1ldGE/OiBTZXJ2ZXJNZXRhRW50cnk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb2NhbFBhdGhGb3JSZW1vdGUocmVtb3RlRG9jc0ZvbGRlcjogc3RyaW5nLCByZW1vdGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCB3aXRob3V0TGVhZGluZ1NsYXNoID0gcmVtb3RlUGF0aC5yZXBsYWNlKC9eXFwvKy8sIFwiXCIpO1xuICBjb25zdCB3aXRoRXh0ZW5zaW9uID0gd2l0aG91dExlYWRpbmdTbGFzaC5lbmRzV2l0aChcIi5tZFwiKSA/IHdpdGhvdXRMZWFkaW5nU2xhc2ggOiBgJHt3aXRob3V0TGVhZGluZ1NsYXNofS5tZGA7XG4gIHJldHVybiBub3JtYWxpemVQYXRoKGAke3JlbW90ZURvY3NGb2xkZXJ9LyR7d2l0aEV4dGVuc2lvbn1gKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuc3VyZUZvbGRlcih2YXVsdDogVmF1bHRMaWtlLCBmb2xkZXJQYXRoOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgcGFydHMgPSBub3JtYWxpemVQYXRoKGZvbGRlclBhdGgpLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gIGxldCBjdXJyZW50ID0gXCJcIjtcbiAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgY3VycmVudCA9IGN1cnJlbnQgPyBgJHtjdXJyZW50fS8ke3BhcnR9YCA6IHBhcnQ7XG4gICAgaWYgKCEoYXdhaXQgdmF1bHQuZXhpc3RzKGN1cnJlbnQpKSkgYXdhaXQgdmF1bHQubWtkaXIoY3VycmVudCk7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvd25sb2FkRG9jdW1lbnQoZGVwczogU3luY0RlcHMsIGRvYzogUGljazxSZW1vdGVEb2N1bWVudCwgXCJpZFwiPik6IFByb21pc2U8RG93bmxvYWRSZXN1bHQ+IHtcbiAgY29uc3QgcmVtb3RlID0gYXdhaXQgZGVwcy5hcGkuZG9jdW1lbnQoZG9jLmlkKTtcbiAgY29uc3QgbG9jYWxQYXRoID0gbG9jYWxQYXRoRm9yUmVtb3RlKGRlcHMucmVtb3RlRG9jc0ZvbGRlciwgcmVtb3RlLnBhdGgpO1xuICBjb25zdCBwYXJlbnQgPSBsb2NhbFBhdGguc3BsaXQoXCIvXCIpLnNsaWNlKDAsIC0xKS5qb2luKFwiL1wiKTtcbiAgaWYgKHBhcmVudCkgYXdhaXQgZW5zdXJlRm9sZGVyKGRlcHMudmF1bHQsIHBhcmVudCk7XG4gIGNvbnN0IGNvbnRlbnQgPSBjYW5vbmljYWxpemUocmVtb3RlLmNvbnRlbnQpO1xuICBhd2FpdCBkZXBzLnZhdWx0LndyaXRlKGxvY2FsUGF0aCwgY29udGVudCk7XG4gIGNvbnN0IG1ldGEgPSBtZXRhRnJvbVJlbW90ZShyZW1vdGUsIGxvY2FsUGF0aCk7XG4gIGF3YWl0IGRlcHMubWV0YS51cHNlcnQobWV0YSk7XG4gIGNvbnN0IGF0dGFjaG1lbnRzID0gaGFzQXR0YWNobWVudFN1cHBvcnQoZGVwcykgPyBhd2FpdCBzeW5jRG9jdW1lbnRBdHRhY2htZW50cyhkZXBzLCBtZXRhLCBjb250ZW50KSA6IGVtcHR5QXR0YWNobWVudFN1bW1hcnkoKTtcbiAgcmV0dXJuIHsgbG9jYWxQYXRoLCBtZXRhLCBhdHRhY2htZW50cyB9O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHVzaExvY2FsRG9jdW1lbnQoZGVwczogU3luY0RlcHMsIGxvY2FsUGF0aDogc3RyaW5nKTogUHJvbWlzZTxQdXNoUmVzdWx0PiB7XG4gIGNvbnN0IG1ldGEgPSBhd2FpdCBkZXBzLm1ldGEuZ2V0QnlMb2NhbFBhdGgobG9jYWxQYXRoKTtcbiAgaWYgKCFtZXRhKSB0aHJvdyBuZXcgRXJyb3IoXCJUaGlzIGZpbGUgaXMgbm90IGxpbmtlZCB0byBhIFBhZ2VkZW4gZG9jdW1lbnQuXCIpO1xuICBpZiAobWV0YS5wZXJtaXNzaW9uID09PSBcInZpZXdlclwiKSByZXR1cm4geyBzdGF0dXM6IFwiYmxvY2tlZF92aWV3ZXJcIiB9O1xuXG4gIGNvbnN0IGNvbnRlbnQgPSBjYW5vbmljYWxpemUoYXdhaXQgZGVwcy52YXVsdC5yZWFkKGxvY2FsUGF0aCkpO1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGRlcHMuYXBpLnB1c2gobWV0YS5kb2N1bWVudElkLCB7XG4gICAgICBiYXNlVmVyc2lvbjogbWV0YS5iYXNlVmVyc2lvbixcbiAgICAgIGNoZWNrc3VtOiBhd2FpdCBjaGVja3N1bShjb250ZW50KSxcbiAgICAgIGNvbnRlbnQsXG4gICAgfSk7XG4gICAgY29uc3QgbmV4dE1ldGEgPSB7IC4uLm1ldGEsIGJhc2VWZXJzaW9uOiByZXN1bHQudmVyc2lvbiwgY2hlY2tzdW06IHJlc3VsdC5jaGVja3N1bSwgdXBkYXRlZEF0OiByZXN1bHQudXBkYXRlZEF0IH07XG4gICAgYXdhaXQgZGVwcy5tZXRhLnVwc2VydChuZXh0TWV0YSk7XG4gICAgaWYgKGhhc0F0dGFjaG1lbnRTdXBwb3J0KGRlcHMpKSBhd2FpdCBzeW5jRG9jdW1lbnRBdHRhY2htZW50cyhkZXBzLCBuZXh0TWV0YSwgY29udGVudCk7XG4gICAgcmV0dXJuIHsgc3RhdHVzOiBcInB1c2hlZFwiLCByZXN1bHQgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBQYWdlZGVuQXBpRXJyb3IgJiYgZXJyb3Iuc3RhdHVzID09PSA0MDkpIHtcbiAgICAgIGNvbnN0IHNlcnZlciA9IGF3YWl0IGRlcHMuYXBpLmRvY3VtZW50KG1ldGEuZG9jdW1lbnRJZCk7XG4gICAgICBjb25zdCBjb25mbGljdFBhdGggPSBhd2FpdCB3cml0ZUNvbmZsaWN0RmlsZShkZXBzLnZhdWx0LCBsb2NhbFBhdGgsIHNlcnZlcik7XG4gICAgICBhd2FpdCBkZXBzLm1ldGEudXBzZXJ0KHsgLi4ubWV0YSwgYmFzZVZlcnNpb246IHNlcnZlci52ZXJzaW9uID8/IG1ldGEuYmFzZVZlcnNpb24sIGNoZWNrc3VtOiBzZXJ2ZXIuY2hlY2tzdW0gPz8gbWV0YS5jaGVja3N1bSwgcGVybWlzc2lvbjogc2VydmVyLnBlcm1pc3Npb24sIHVwZGF0ZWRBdDogc2VydmVyLnVwZGF0ZWRBdCB9KTtcbiAgICAgIHJldHVybiB7IHN0YXR1czogXCJjb25mbGljdFwiLCBjb25mbGljdFBhdGgsIHNlcnZlclBhdGg6IHNlcnZlci5wYXRoIH07XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwdXNoT3JDcmVhdGVMb2NhbERvY3VtZW50KGRlcHM6IENyZWF0ZVJlbW90ZURlcHMsIGxvY2FsUGF0aDogc3RyaW5nKTogUHJvbWlzZTxQdXNoUmVzdWx0PiB7XG4gIGNvbnN0IG1ldGEgPSBhd2FpdCBkZXBzLm1ldGEuZ2V0QnlMb2NhbFBhdGgobG9jYWxQYXRoKTtcbiAgaWYgKG1ldGEpIHJldHVybiBwdXNoTG9jYWxEb2N1bWVudChkZXBzLCBsb2NhbFBhdGgpO1xuICByZXR1cm4gY3JlYXRlUmVtb3RlRG9jdW1lbnRGcm9tTG9jYWwoZGVwcywgbG9jYWxQYXRoKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVJlbW90ZURvY3VtZW50RnJvbUxvY2FsKGRlcHM6IENyZWF0ZVJlbW90ZURlcHMsIGxvY2FsUGF0aDogc3RyaW5nKTogUHJvbWlzZTxQdXNoUmVzdWx0PiB7XG4gIGNvbnN0IGNvbnRlbnQgPSBjYW5vbmljYWxpemUoYXdhaXQgZGVwcy52YXVsdC5yZWFkKGxvY2FsUGF0aCkpO1xuICBjb25zdCB0cmVlID0gYXdhaXQgZGVwcy5hcGkudHJlZShkZXBzLndvcmtzcGFjZUlkKTtcbiAgY29uc3QgdGFyZ2V0ID0gdGFyZ2V0UGF0aEZvckxvY2FsKGRlcHMucmVtb3RlRG9jc0ZvbGRlciwgbG9jYWxQYXRoKTtcbiAgY29uc3QgZXhpc3RpbmdQYXRoID0gdGFyZ2V0LmRvY3VtZW50UGF0aDtcbiAgaWYgKHRyZWUuZG9jdW1lbnRzLnNvbWUoKGRvYykgPT4gdHJpbVNsYXNoZXMoZG9jLnBhdGgpID09PSBleGlzdGluZ1BhdGgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBBIFBhZ2VkZW4gZG9jdW1lbnQgYWxyZWFkeSBleGlzdHMgYXQgXCIke2V4aXN0aW5nUGF0aH1cIi4gRG93bmxvYWQgaXQgZmlyc3QgdG8gbGluayB0aGlzIGxvY2FsIG5vdGUgc2FmZWx5LmApO1xuICB9XG5cbiAgY29uc3QgZm9sZGVyID0gYXdhaXQgZW5zdXJlUmVtb3RlRm9sZGVyUGF0aChkZXBzLmFwaSwgZGVwcy53b3Jrc3BhY2VJZCwgdHJlZSwgdGFyZ2V0LmZvbGRlclNlZ21lbnRzKTtcbiAgY29uc3QgY3JlYXRlZCA9IGF3YWl0IGRlcHMuYXBpLmNyZWF0ZURvY3VtZW50KHtcbiAgICB3b3Jrc3BhY2VJZDogZGVwcy53b3Jrc3BhY2VJZCxcbiAgICBmb2xkZXJJZDogZm9sZGVyLmlkLFxuICAgIHRpdGxlOiBmcm9udG1hdHRlclRpdGxlKGNvbnRlbnQpID8/IHRhcmdldC50aXRsZSxcbiAgICBzbHVnOiB0YXJnZXQuZG9jdW1lbnRTbHVnLFxuICAgIGNvbnRlbnQsXG4gIH0pO1xuICBjb25zdCByZW1vdGUgPSBhd2FpdCBkZXBzLmFwaS5kb2N1bWVudChjcmVhdGVkLmlkKTtcbiAgY29uc3QgbWV0YSA9IG1ldGFGcm9tUmVtb3RlKHJlbW90ZSwgbG9jYWxQYXRoKTtcbiAgYXdhaXQgZGVwcy5tZXRhLnVwc2VydChtZXRhKTtcbiAgaWYgKGhhc0F0dGFjaG1lbnRTdXBwb3J0KGRlcHMpKSBhd2FpdCBzeW5jRG9jdW1lbnRBdHRhY2htZW50cyhkZXBzLCBtZXRhLCBjb250ZW50KTtcbiAgcmV0dXJuIHtcbiAgICBzdGF0dXM6IFwiY3JlYXRlZFwiLFxuICAgIHJlc3VsdDogeyBpZDogcmVtb3RlLmlkLCB2ZXJzaW9uOiBtZXRhLmJhc2VWZXJzaW9uLCBjaGVja3N1bTogbWV0YS5jaGVja3N1bSwgdXBkYXRlZEF0OiBtZXRhLnVwZGF0ZWRBdCB9LFxuICAgIG1ldGEsXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHdyaXRlQ29uZmxpY3RGaWxlKHZhdWx0OiBWYXVsdExpa2UsIGxvY2FsUGF0aDogc3RyaW5nLCBzZXJ2ZXI6IFJlbW90ZURvY3VtZW50V2l0aENvbnRlbnQpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBzdGVtID0gbG9jYWxQYXRoLnJlcGxhY2UoL1xcLm1kJC9pLCBcIlwiKTtcbiAgY29uc3QgY29uZmxpY3RQYXRoID0gbm9ybWFsaXplUGF0aChgJHtzdGVtfS5jb25mbGljdC5tZGApO1xuICBhd2FpdCB2YXVsdC53cml0ZShjb25mbGljdFBhdGgsIGNhbm9uaWNhbGl6ZShzZXJ2ZXIuY29udGVudCkpO1xuICByZXR1cm4gY29uZmxpY3RQYXRoO1xufVxuXG5mdW5jdGlvbiBtZXRhRnJvbVJlbW90ZShyZW1vdGU6IFJlbW90ZURvY3VtZW50V2l0aENvbnRlbnQsIGxvY2FsUGF0aDogc3RyaW5nKTogU2VydmVyTWV0YUVudHJ5IHtcbiAgaWYgKCFyZW1vdGUudmVyc2lvbiB8fCAhcmVtb3RlLmNoZWNrc3VtKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiUmVtb3RlIGRvY3VtZW50IGlzIG1pc3NpbmcgdmVyc2lvbiBtZXRhZGF0YS5cIik7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBkb2N1bWVudElkOiByZW1vdGUuaWQsXG4gICAgbG9jYWxQYXRoLFxuICAgIHJlbW90ZVBhdGg6IHJlbW90ZS5wYXRoLFxuICAgIHRpdGxlOiByZW1vdGUudGl0bGUsXG4gICAgYmFzZVZlcnNpb246IHJlbW90ZS52ZXJzaW9uLFxuICAgIGNoZWNrc3VtOiByZW1vdGUuY2hlY2tzdW0sXG4gICAgcGVybWlzc2lvbjogcmVtb3RlLnBlcm1pc3Npb24sXG4gICAgdXBkYXRlZEF0OiByZW1vdGUudXBkYXRlZEF0LFxuICB9O1xufVxuXG5hc3luYyBmdW5jdGlvbiBlbnN1cmVSZW1vdGVGb2xkZXJQYXRoKFxuICBhcGk6IFBpY2s8UGFnZWRlbkFwaUNsaWVudCwgXCJjcmVhdGVGb2xkZXJcIj4sXG4gIHdvcmtzcGFjZUlkOiBzdHJpbmcsXG4gIHRyZWU6IFJlbW90ZVRyZWUsXG4gIGZvbGRlclNlZ21lbnRzOiBzdHJpbmdbXSxcbik6IFByb21pc2U8UmVtb3RlRm9sZGVyPiB7XG4gIGNvbnN0IGZvbGRlckJ5UGF0aCA9IG5ldyBNYXAodHJlZS5mb2xkZXJzLm1hcCgoZm9sZGVyKSA9PiBbdHJpbVNsYXNoZXMoZm9sZGVyLnBhdGgpLCBmb2xkZXJdKSk7XG4gIGxldCBwYXJlbnQ6IFJlbW90ZUZvbGRlciB8IG51bGwgPSBudWxsO1xuICBsZXQgY3VycmVudFBhdGggPSBcIlwiO1xuXG4gIGZvciAoY29uc3Qgc2VnbWVudCBvZiBmb2xkZXJTZWdtZW50cykge1xuICAgIGNvbnN0IHNsdWcgPSBzbHVnaWZ5KHNlZ21lbnQpO1xuICAgIGN1cnJlbnRQYXRoID0gY3VycmVudFBhdGggPyBgJHtjdXJyZW50UGF0aH0vJHtzbHVnfWAgOiBzbHVnO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gZm9sZGVyQnlQYXRoLmdldChjdXJyZW50UGF0aCk7XG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICBwYXJlbnQgPSBleGlzdGluZztcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCBjcmVhdGVkID0gYXdhaXQgYXBpLmNyZWF0ZUZvbGRlcih7XG4gICAgICB3b3Jrc3BhY2VJZCxcbiAgICAgIHBhcmVudEZvbGRlcklkOiBwYXJlbnQ/LmlkID8/IG51bGwsXG4gICAgICBuYW1lOiBzZWdtZW50LFxuICAgICAgc2x1ZyxcbiAgICB9KTtcbiAgICBwYXJlbnQgPSB7XG4gICAgICBpZDogY3JlYXRlZC5pZCxcbiAgICAgIHBhcmVudEZvbGRlcklkOiBwYXJlbnQ/LmlkID8/IG51bGwsXG4gICAgICBuYW1lOiBzZWdtZW50LFxuICAgICAgc2x1ZyxcbiAgICAgIHBhdGg6IHRyaW1TbGFzaGVzKGNyZWF0ZWQucGF0aCksXG4gICAgICBwZXJtaXNzaW9uOiBcIm1hbmFnZXJcIixcbiAgICB9O1xuICAgIGZvbGRlckJ5UGF0aC5zZXQoY3VycmVudFBhdGgsIHBhcmVudCk7XG4gIH1cblxuICBpZiAoIXBhcmVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkNyZWF0ZSB0aGUgbm90ZSBpbnNpZGUgYSBmb2xkZXIgc28gUGFnZWRlbiBrbm93cyB3aGVyZSB0byBwbGFjZSBpdC5cIik7XG4gIH1cbiAgcmV0dXJuIHBhcmVudDtcbn1cblxuZnVuY3Rpb24gdGFyZ2V0UGF0aEZvckxvY2FsKHJlbW90ZURvY3NGb2xkZXI6IHN0cmluZywgbG9jYWxQYXRoOiBzdHJpbmcpIHtcbiAgY29uc3Qgbm9ybWFsaXplZExvY2FsID0gbm9ybWFsaXplUGF0aChsb2NhbFBhdGgpO1xuICBjb25zdCBub3JtYWxpemVkUm9vdCA9IG5vcm1hbGl6ZVBhdGgocmVtb3RlRG9jc0ZvbGRlcikucmVwbGFjZSgvXFwvKyQvLCBcIlwiKTtcbiAgY29uc3QgcmVsYXRpdmVQYXRoID0gbm9ybWFsaXplZExvY2FsID09PSBub3JtYWxpemVkUm9vdFxuICAgID8gXCJcIlxuICAgIDogbm9ybWFsaXplZExvY2FsLnN0YXJ0c1dpdGgoYCR7bm9ybWFsaXplZFJvb3R9L2ApXG4gICAgICA/IG5vcm1hbGl6ZWRMb2NhbC5zbGljZShub3JtYWxpemVkUm9vdC5sZW5ndGggKyAxKVxuICAgICAgOiBub3JtYWxpemVkTG9jYWw7XG4gIGNvbnN0IHBhcnRzID0gcmVsYXRpdmVQYXRoLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gIGNvbnN0IGZpbGVuYW1lID0gcGFydHMucG9wKCkgPz8gXCJ1bnRpdGxlZC5tZFwiO1xuICBjb25zdCBmb2xkZXJTZWdtZW50cyA9IHBhcnRzLm1hcCgocGFydCkgPT4gcGFydC5yZXBsYWNlKC9cXC5tZCQvaSwgXCJcIikpO1xuICBjb25zdCB0aXRsZSA9IGZpbGVuYW1lLnJlcGxhY2UoL1xcLm1kJC9pLCBcIlwiKSB8fCBcIlVudGl0bGVkXCI7XG4gIGNvbnN0IGRvY3VtZW50U2x1ZyA9IHNsdWdpZnkoZmlsZW5hbWUpO1xuICBjb25zdCBkb2N1bWVudFBhdGggPSBbLi4uZm9sZGVyU2VnbWVudHMubWFwKHNsdWdpZnkpLCBgJHtkb2N1bWVudFNsdWd9Lm1kYF0uZmlsdGVyKEJvb2xlYW4pLmpvaW4oXCIvXCIpO1xuICByZXR1cm4geyBmb2xkZXJTZWdtZW50cywgdGl0bGUsIGRvY3VtZW50U2x1ZywgZG9jdW1lbnRQYXRoIH07XG59XG5cbmZ1bmN0aW9uIGZyb250bWF0dGVyVGl0bGUoY29udGVudDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmICghY29udGVudC5zdGFydHNXaXRoKFwiLS0tXFxuXCIpKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgZW5kID0gY29udGVudC5pbmRleE9mKFwiXFxuLS0tXCIsIDQpO1xuICBpZiAoZW5kID09PSAtMSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHJhdyA9IGNvbnRlbnQuc2xpY2UoNCwgZW5kKTtcbiAgZm9yIChjb25zdCBsaW5lIG9mIHJhdy5zcGxpdChcIlxcblwiKSkge1xuICAgIGNvbnN0IG1hdGNoID0gbGluZS5tYXRjaCgvXnRpdGxlOlxccyooLispJC9pKTtcbiAgICBpZiAoIW1hdGNoPy5bMV0pIGNvbnRpbnVlO1xuICAgIHJldHVybiBtYXRjaFsxXS50cmltKCkucmVwbGFjZSgvXlsnXCJdfFsnXCJdJC9nLCBcIlwiKSB8fCBudWxsO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBzbHVnaWZ5KHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBzbHVnID0gdmFsdWVcbiAgICAubm9ybWFsaXplKFwiTkZLRFwiKVxuICAgIC5yZXBsYWNlKC9bXFx1MDMwMC1cXHUwMzZmXS9nLCBcIlwiKVxuICAgIC50b0xvd2VyQ2FzZSgpXG4gICAgLnJlcGxhY2UoL1xcLm1kJC9pLCBcIlwiKVxuICAgIC5yZXBsYWNlKC9bXmEtejAtOV0rL2csIFwiLVwiKVxuICAgIC5yZXBsYWNlKC9eLSt8LSskL2csIFwiXCIpO1xuICByZXR1cm4gc2x1ZyB8fCBcInVudGl0bGVkXCI7XG59XG5cbmZ1bmN0aW9uIHRyaW1TbGFzaGVzKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBwYXRoLnJlcGxhY2UoL15cXC8rfFxcLyskL2csIFwiXCIpO1xufVxuXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gQmFja2dyb3VuZCBzeW5jIChNaWxlc3RvbmUgNikuIFB1cmUgb3JjaGVzdHJhdGlvbiBvdmVyIHRoZSBzYW1lIHByaW1pdGl2ZXMgdGhlIG1hbnVhbFxuLy8gY29tbWFuZHMgdXNlLCBzbyBiZWhhdmlvdXIgKGNhbm9uaWNhbGl6YXRpb24sIG9wYXF1ZSB2ZXJzaW9uLCA0MDkgXHUyMTkyICouY29uZmxpY3QubWQsIG5ldmVyXG4vLyBvdmVyd3JpdGUgbG9jYWwpIHN0YXlzIGlkZW50aWNhbC4gVGhlIE9ic2lkaWFuLWZhY2luZyBlbmdpbmUgaW4gbWFpbi50cyBvbmx5IHdpcmVzIGxpZmVjeWNsZSxcbi8vIGV2ZW50cywgZGVib3VuY2UsIHN0YXR1cywgYW5kIHRoZSBhcHBseWluZ1JlbW90ZVdyaXRlIGd1YXJkIGFyb3VuZCB0aGVzZS5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5leHBvcnQgdHlwZSBEb2NTeW5jU3RhdHVzID1cbiAgfCBcInVuY2hhbmdlZFwiXG4gIHwgXCJjcmVhdGVkXCJcbiAgfCBcInB1bGxlZFwiXG4gIHwgXCJwdXNoZWRcIlxuICB8IFwiY29uZmxpY3RcIlxuICB8IFwiY29uZmxpY3RfcGVuZGluZ1wiXG4gIHwgXCJibG9ja2VkX3ZpZXdlclwiXG4gIHwgXCJtaXNzaW5nX2xvY2FsXCJcbiAgfCBcImdvbmVcIjtcblxuLy8gVGhlIHNlcnZlciBjb3B5IG9mIGFuIHVucmVzb2x2ZWQgY29uZmxpY3QgaXMgd3JpdHRlbiBiZXNpZGUgdGhlIGxvY2FsIGZpbGUgYXMgYDxuYW1lPi5jb25mbGljdC5tZGAuXG5leHBvcnQgZnVuY3Rpb24gY29uZmxpY3RTaWJsaW5nUGF0aChsb2NhbFBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtsb2NhbFBhdGgucmVwbGFjZSgvXFwubWQkL2ksIFwiXCIpfS5jb25mbGljdC5tZGA7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRG9jU3luY1Jlc3VsdCB7XG4gIGRvY3VtZW50SWQ6IHN0cmluZztcbiAgbG9jYWxQYXRoOiBzdHJpbmc7XG4gIHN0YXR1czogRG9jU3luY1N0YXR1cztcbiAgY29uZmxpY3RQYXRoPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFN5bmNQYXNzU3VtbWFyeSB7XG4gIHVuY2hhbmdlZDogbnVtYmVyO1xuICBjcmVhdGVkOiBudW1iZXI7XG4gIHB1bGxlZDogbnVtYmVyO1xuICBwdXNoZWQ6IG51bWJlcjtcbiAgY29uZmxpY3RzOiBudW1iZXI7XG4gIGNvbmZsaWN0c1BlbmRpbmc6IG51bWJlcjtcbiAgYmxvY2tlZFZpZXdlcjogbnVtYmVyO1xuICBtaXNzaW5nTG9jYWw6IG51bWJlcjtcbiAgZ29uZTogbnVtYmVyO1xuICBhdHRhY2htZW50c0Rvd25sb2FkZWQ6IG51bWJlcjtcbiAgYXR0YWNobWVudHNVcGxvYWRlZDogbnVtYmVyO1xuICBhdHRhY2htZW50c0RlbGV0ZWQ6IG51bWJlcjtcbiAgZXJyb3JzOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXR0YWNobWVudFN5bmNTdW1tYXJ5IHtcbiAgZG93bmxvYWRlZDogbnVtYmVyO1xuICB1cGxvYWRlZDogbnVtYmVyO1xuICBkZWxldGVkOiBudW1iZXI7XG4gIHNraXBwZWQ6IG51bWJlcjtcbn1cblxuLy8gUmVjb25jaWxlIG9uZSBsaW5rZWQgZG9jdW1lbnQuIERlY2lzaW9uIHRhYmxlOlxuLy8gICBsb2NhbCBkaXZlcmdlZCAoY2hlY2tzdW0gIT0gdHJhY2tlZCkgIC0+IHB1c2ggKGEgc3RhbGUgYmFzZSB5aWVsZHMgYSBjbGVhbiA0MDkgLT4gY29uZmxpY3QpXG4vLyAgIHNlcnZlciBtb3ZlZCAmIGxvY2FsIHVuY2hhbmdlZCAgICAgICAgIC0+IHB1bGwgKHdyaXRlIHNlcnZlciBjb250ZW50LCBhZHZhbmNlIG1ldGEpXG4vLyAgIHNlcnZlciBtb3ZlZCAmIGxvY2FsIG1pc3NpbmcgICAgICAgICAgIC0+IHB1bGwgKHJlLW1hdGVyaWFsaXplIHRoZSBmaWxlKVxuLy8gICBvdGhlcndpc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT4gdW5jaGFuZ2VkXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc3luY0xpbmtlZERvY3VtZW50KGRlcHM6IFN5bmNEZXBzLCBlbnRyeTogU2VydmVyTWV0YUVudHJ5KTogUHJvbWlzZTxEb2NTeW5jUmVzdWx0PiB7XG4gIGNvbnN0IGJhc2UgPSB7IGRvY3VtZW50SWQ6IGVudHJ5LmRvY3VtZW50SWQsIGxvY2FsUGF0aDogZW50cnkubG9jYWxQYXRoIH07XG5cbiAgbGV0IHJlbW90ZTogUmVtb3RlRG9jdW1lbnRXaXRoQ29udGVudDtcbiAgdHJ5IHtcbiAgICByZW1vdGUgPSBhd2FpdCBkZXBzLmFwaS5kb2N1bWVudChlbnRyeS5kb2N1bWVudElkKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAvLyBFeGlzdGVuY2UtaGlkaW5nOiBhIGRlbGV0ZWQgZG9jdW1lbnQgb3IgYSByZXZva2VkIGdyYW50IHJldHVybnMgNDA0LiBSZXBvcnQgaXQgYXMgZ29uZSBhbmRcbiAgICAvLyBsZWF2ZSB0aGUgbG9jYWwgZmlsZSB1bnRvdWNoZWQgKHRoZSB1c2VyIGtlZXBzIHRoZWlyIGNvcHkpOyBkb24ndCByZXRyeS1sb29wLlxuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFBhZ2VkZW5BcGlFcnJvciAmJiBlcnJvci5zdGF0dXMgPT09IDQwNCkgcmV0dXJuIHsgLi4uYmFzZSwgc3RhdHVzOiBcImdvbmVcIiB9O1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgY29uc3Qgc2VydmVyTW92ZWQgPSAocmVtb3RlLnZlcnNpb24gPz8gXCJcIikgIT09IGVudHJ5LmJhc2VWZXJzaW9uO1xuICBjb25zdCBsb2NhbEV4aXN0cyA9IGF3YWl0IGRlcHMudmF1bHQuZXhpc3RzKGVudHJ5LmxvY2FsUGF0aCk7XG5cbiAgLy8gQSBwcmV2aW91c2x5LXJlY29yZGVkIGNvbmZsaWN0IGZyZWV6ZXMgdGhlIGRvY3VtZW50IHVudGlsIHRoZSB1c2VyIHJlc29sdmVzIGl0IChkZWxldGVzIHRoZVxuICAvLyAqLmNvbmZsaWN0Lm1kIHNpYmxpbmcpLiBXaXRob3V0IHRoaXMsIGJhY2tncm91bmQgYXV0by1wdXNoIHdvdWxkIHNpbGVudGx5IHB1c2ggdGhlIGxvY2FsIHNpZGVcbiAgLy8gb24gdGhlIG5leHQgcGFzcyBhbmQgZGlzY2FyZCB0aGUgc2VydmVyIGNoYW5nZXMgdGhlIHVzZXIgbmV2ZXIgcmVjb25jaWxlZC5cbiAgaWYgKGF3YWl0IGRlcHMudmF1bHQuZXhpc3RzKGNvbmZsaWN0U2libGluZ1BhdGgoZW50cnkubG9jYWxQYXRoKSkpIHtcbiAgICByZXR1cm4geyAuLi5iYXNlLCBzdGF0dXM6IFwiY29uZmxpY3RfcGVuZGluZ1wiLCBjb25mbGljdFBhdGg6IGNvbmZsaWN0U2libGluZ1BhdGgoZW50cnkubG9jYWxQYXRoKSB9O1xuICB9XG5cbiAgbGV0IGxvY2FsQ2Fub25pY2FsID0gXCJcIjtcbiAgaWYgKGxvY2FsRXhpc3RzKSB7XG4gICAgbG9jYWxDYW5vbmljYWwgPSBjYW5vbmljYWxpemUoYXdhaXQgZGVwcy52YXVsdC5yZWFkKGVudHJ5LmxvY2FsUGF0aCkpO1xuICAgIGNvbnN0IGxvY2FsRGl2ZXJnZWQgPSAoYXdhaXQgY2hlY2tzdW0obG9jYWxDYW5vbmljYWwpKSAhPT0gZW50cnkuY2hlY2tzdW07XG4gICAgaWYgKGxvY2FsRGl2ZXJnZWQpIHtcbiAgICAgIC8vIFJlY29uY2lsZSBwZXJtaXNzaW9uIGZyb20gdGhlIGxpdmUgZmV0Y2g6IGEgZG93bmdyYWRlIHRvIHZpZXdlciBtZWFucyB3ZSBtdXN0IE5PVCBwdXNoLFxuICAgICAgLy8gZXZlbiBpZiB0aGUgc3RvcmVkIG1ldGEgc3RpbGwgc2F5cyBlZGl0b3IuXG4gICAgICBpZiAocmVtb3RlLnBlcm1pc3Npb24gPT09IFwidmlld2VyXCIpIHtcbiAgICAgICAgaWYgKHNlcnZlck1vdmVkKSB7XG4gICAgICAgICAgY29uc3QgY29uZmxpY3RQYXRoID0gYXdhaXQgd3JpdGVDb25mbGljdEZpbGUoZGVwcy52YXVsdCwgZW50cnkubG9jYWxQYXRoLCByZW1vdGUpO1xuICAgICAgICAgIGF3YWl0IGRlcHMubWV0YS51cHNlcnQobWV0YUZyb21SZW1vdGUocmVtb3RlLCBlbnRyeS5sb2NhbFBhdGgpKTtcbiAgICAgICAgICByZXR1cm4geyAuLi5iYXNlLCBzdGF0dXM6IFwiY29uZmxpY3RcIiwgY29uZmxpY3RQYXRoIH07XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgZGVwcy5tZXRhLnVwc2VydCh7IC4uLmVudHJ5LCBwZXJtaXNzaW9uOiBcInZpZXdlclwiIH0pO1xuICAgICAgICByZXR1cm4geyAuLi5iYXNlLCBzdGF0dXM6IFwiYmxvY2tlZF92aWV3ZXJcIiB9O1xuICAgICAgfVxuICAgICAgY29uc3QgcHVzaGVkID0gYXdhaXQgcHVzaExvY2FsRG9jdW1lbnQoZGVwcywgZW50cnkubG9jYWxQYXRoKTtcbiAgICAgIGlmIChwdXNoZWQuc3RhdHVzID09PSBcInB1c2hlZFwiKSByZXR1cm4geyAuLi5iYXNlLCBzdGF0dXM6IFwicHVzaGVkXCIgfTtcbiAgICAgIGlmIChwdXNoZWQuc3RhdHVzID09PSBcImNvbmZsaWN0XCIpIHJldHVybiB7IC4uLmJhc2UsIHN0YXR1czogXCJjb25mbGljdFwiLCBjb25mbGljdFBhdGg6IHB1c2hlZC5jb25mbGljdFBhdGggfTtcbiAgICAgIHJldHVybiB7IC4uLmJhc2UsIHN0YXR1czogXCJibG9ja2VkX3ZpZXdlclwiIH07XG4gICAgfVxuICB9XG5cbiAgaWYgKCFsb2NhbEV4aXN0cykge1xuICAgIC8vIFRoZSB1c2VyIGRlbGV0ZWQgYSB0cmFja2VkIGZpbGUgbG9jYWxseTsgZG9uJ3QgcmVzdXJyZWN0IGl0LiBMZWF2ZSBtZXRhIHNvIGEgbWFudWFsXG4gICAgLy8gcmUtZG93bmxvYWQgY2FuIHJlLWxpbmsgaXQuXG4gICAgcmV0dXJuIHsgLi4uYmFzZSwgc3RhdHVzOiBcIm1pc3NpbmdfbG9jYWxcIiB9O1xuICB9XG5cbiAgaWYgKHNlcnZlck1vdmVkKSB7XG4gICAgLy8gUmUtcmVhZCBpbW1lZGlhdGVseSBiZWZvcmUgd3JpdGluZyB0byBjbG9zZSB0aGUgVE9DVE9VIHdpbmRvdyBiZXR3ZWVuIHRoZSBkaXZlcmdlbmNlIGNoZWNrXG4gICAgLy8gYWJvdmUgYW5kIHRoZSB3cml0ZTogaWYgdGhlIGZpbGUgY2hhbmdlZCBpbiBiZXR3ZWVuLCB0cmVhdCBpdCBhcyBhIGNvbmZsaWN0LCBuZXZlciBjbG9iYmVyLlxuICAgIGNvbnN0IGZyZXNoID0gY2Fub25pY2FsaXplKGF3YWl0IGRlcHMudmF1bHQucmVhZChlbnRyeS5sb2NhbFBhdGgpKTtcbiAgICBpZiAoKGF3YWl0IGNoZWNrc3VtKGZyZXNoKSkgIT09IGVudHJ5LmNoZWNrc3VtKSB7XG4gICAgICBjb25zdCBjb25mbGljdFBhdGggPSBhd2FpdCB3cml0ZUNvbmZsaWN0RmlsZShkZXBzLnZhdWx0LCBlbnRyeS5sb2NhbFBhdGgsIHJlbW90ZSk7XG4gICAgICBhd2FpdCBkZXBzLm1ldGEudXBzZXJ0KG1ldGFGcm9tUmVtb3RlKHJlbW90ZSwgZW50cnkubG9jYWxQYXRoKSk7XG4gICAgICByZXR1cm4geyAuLi5iYXNlLCBzdGF0dXM6IFwiY29uZmxpY3RcIiwgY29uZmxpY3RQYXRoIH07XG4gICAgfVxuICAgIGF3YWl0IGFwcGx5UmVtb3RlUHVsbChkZXBzLCBlbnRyeS5sb2NhbFBhdGgsIHJlbW90ZSk7XG4gICAgcmV0dXJuIHsgLi4uYmFzZSwgc3RhdHVzOiBcInB1bGxlZFwiIH07XG4gIH1cblxuICAvLyBVbmNoYW5nZWQgY29udGVudDsgc3RpbGwgcmVjb25jaWxlIGEgcGVybWlzc2lvbiBjaGFuZ2Ugc28gdGhlIFVJL2dhdGluZyBzdGF5cyBhY2N1cmF0ZS5cbiAgaWYgKHJlbW90ZS5wZXJtaXNzaW9uICE9PSBlbnRyeS5wZXJtaXNzaW9uKSB7XG4gICAgYXdhaXQgZGVwcy5tZXRhLnVwc2VydCh7IC4uLmVudHJ5LCBwZXJtaXNzaW9uOiByZW1vdGUucGVybWlzc2lvbiB9KTtcbiAgfVxuICBpZiAoaGFzQXR0YWNobWVudFN1cHBvcnQoZGVwcykpIHtcbiAgICBhd2FpdCBzeW5jRG9jdW1lbnRBdHRhY2htZW50cyhkZXBzLCB7IC4uLmVudHJ5LCBwZXJtaXNzaW9uOiByZW1vdGUucGVybWlzc2lvbiB9LCBsb2NhbENhbm9uaWNhbCk7XG4gIH1cbiAgcmV0dXJuIHsgLi4uYmFzZSwgc3RhdHVzOiBcInVuY2hhbmdlZFwiIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFwcGx5UmVtb3RlUHVsbChkZXBzOiBTeW5jRGVwcywgbG9jYWxQYXRoOiBzdHJpbmcsIHJlbW90ZTogUmVtb3RlRG9jdW1lbnRXaXRoQ29udGVudCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwYXJlbnQgPSBsb2NhbFBhdGguc3BsaXQoXCIvXCIpLnNsaWNlKDAsIC0xKS5qb2luKFwiL1wiKTtcbiAgaWYgKHBhcmVudCkgYXdhaXQgZW5zdXJlRm9sZGVyKGRlcHMudmF1bHQsIHBhcmVudCk7XG4gIGNvbnN0IGNvbnRlbnQgPSBjYW5vbmljYWxpemUocmVtb3RlLmNvbnRlbnQpO1xuICBhd2FpdCBkZXBzLnZhdWx0LndyaXRlKGxvY2FsUGF0aCwgY29udGVudCk7XG4gIGNvbnN0IG1ldGEgPSBtZXRhRnJvbVJlbW90ZShyZW1vdGUsIGxvY2FsUGF0aCk7XG4gIGF3YWl0IGRlcHMubWV0YS51cHNlcnQobWV0YSk7XG4gIGlmIChoYXNBdHRhY2htZW50U3VwcG9ydChkZXBzKSkgYXdhaXQgc3luY0RvY3VtZW50QXR0YWNobWVudHMoZGVwcywgbWV0YSwgY29udGVudCk7XG59XG5cbi8vIFJ1biBvbmUgcGFzcyBvdmVyIGV2ZXJ5IGxpbmtlZCBkb2N1bWVudC4gUGVyLWRvY3VtZW50IGVycm9ycyBhcmUgaXNvbGF0ZWQgc28gb25lIGZhaWx1cmVcbi8vIChvciBvbmUgb2ZmbGluZSBkb2N1bWVudCkgZG9lcyBub3QgYWJvcnQgdGhlIHJlc3Qgb2YgdGhlIHBhc3MuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuQmFja2dyb3VuZFN5bmNQYXNzKFxuICBkZXBzOiBCYWNrZ3JvdW5kU3luY0RlcHMsXG4gIG9uUmVzdWx0PzogKHJlc3VsdDogRG9jU3luY1Jlc3VsdCkgPT4gdm9pZCxcbik6IFByb21pc2U8U3luY1Bhc3NTdW1tYXJ5PiB7XG4gIGNvbnN0IHN1bW1hcnk6IFN5bmNQYXNzU3VtbWFyeSA9IHtcbiAgICB1bmNoYW5nZWQ6IDAsXG4gICAgY3JlYXRlZDogMCxcbiAgICBwdWxsZWQ6IDAsXG4gICAgcHVzaGVkOiAwLFxuICAgIGNvbmZsaWN0czogMCxcbiAgICBjb25mbGljdHNQZW5kaW5nOiAwLFxuICAgIGJsb2NrZWRWaWV3ZXI6IDAsXG4gICAgbWlzc2luZ0xvY2FsOiAwLFxuICAgIGdvbmU6IDAsXG4gICAgYXR0YWNobWVudHNEb3dubG9hZGVkOiAwLFxuICAgIGF0dGFjaG1lbnRzVXBsb2FkZWQ6IDAsXG4gICAgYXR0YWNobWVudHNEZWxldGVkOiAwLFxuICAgIGVycm9yczogMCxcbiAgfTtcbiAgY29uc3QgZW50cmllcyA9IGF3YWl0IGRlcHMubWV0YS5saXN0KCk7XG4gIGNvbnN0IGxpbmtlZExvY2FsUGF0aHMgPSBuZXcgU2V0KGVudHJpZXMubWFwKChlbnRyeSkgPT4gbm9ybWFsaXplUGF0aChlbnRyeS5sb2NhbFBhdGgpKSk7XG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzeW5jTGlua2VkRG9jdW1lbnQoZGVwcywgZW50cnkpO1xuICAgICAgb25SZXN1bHQ/LihyZXN1bHQpO1xuICAgICAgc3dpdGNoIChyZXN1bHQuc3RhdHVzKSB7XG4gICAgICAgIGNhc2UgXCJ1bmNoYW5nZWRcIjogc3VtbWFyeS51bmNoYW5nZWQgKz0gMTsgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJjcmVhdGVkXCI6IHN1bW1hcnkuY3JlYXRlZCArPSAxOyBicmVhaztcbiAgICAgICAgY2FzZSBcInB1bGxlZFwiOiBzdW1tYXJ5LnB1bGxlZCArPSAxOyBicmVhaztcbiAgICAgICAgY2FzZSBcInB1c2hlZFwiOiBzdW1tYXJ5LnB1c2hlZCArPSAxOyBicmVhaztcbiAgICAgICAgY2FzZSBcImNvbmZsaWN0XCI6IHN1bW1hcnkuY29uZmxpY3RzICs9IDE7IGJyZWFrO1xuICAgICAgICBjYXNlIFwiY29uZmxpY3RfcGVuZGluZ1wiOiBzdW1tYXJ5LmNvbmZsaWN0c1BlbmRpbmcgKz0gMTsgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJibG9ja2VkX3ZpZXdlclwiOiBzdW1tYXJ5LmJsb2NrZWRWaWV3ZXIgKz0gMTsgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJtaXNzaW5nX2xvY2FsXCI6IHN1bW1hcnkubWlzc2luZ0xvY2FsICs9IDE7IGJyZWFrO1xuICAgICAgICBjYXNlIFwiZ29uZVwiOiBzdW1tYXJ5LmdvbmUgKz0gMTsgYnJlYWs7XG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICBzdW1tYXJ5LmVycm9ycyArPSAxO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjYW5DcmVhdGVVbmxpbmtlZExvY2FsRG9jdW1lbnRzKGRlcHMpKSB7XG4gICAgZm9yIChjb25zdCBsb2NhbFBhdGggb2YgYXdhaXQgZGVwcy5sb2NhbE1hcmtkb3duUGF0aHMoKSkge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFBhdGggPSBub3JtYWxpemVQYXRoKGxvY2FsUGF0aCk7XG4gICAgICBpZiAobGlua2VkTG9jYWxQYXRocy5oYXMobm9ybWFsaXplZFBhdGgpIHx8IG5vcm1hbGl6ZWRQYXRoLmVuZHNXaXRoKFwiLmNvbmZsaWN0Lm1kXCIpKSBjb250aW51ZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNyZWF0ZVJlbW90ZURvY3VtZW50RnJvbUxvY2FsKGRlcHMsIG5vcm1hbGl6ZWRQYXRoKTtcbiAgICAgICAgaWYgKHJlc3VsdC5tZXRhKSBsaW5rZWRMb2NhbFBhdGhzLmFkZChub3JtYWxpemVQYXRoKHJlc3VsdC5tZXRhLmxvY2FsUGF0aCkpO1xuICAgICAgICBzdW1tYXJ5LmNyZWF0ZWQgKz0gMTtcbiAgICAgICAgb25SZXN1bHQ/Lih7IGRvY3VtZW50SWQ6IHJlc3VsdC5tZXRhPy5kb2N1bWVudElkID8/IFwiXCIsIGxvY2FsUGF0aDogbm9ybWFsaXplZFBhdGgsIHN0YXR1czogXCJjcmVhdGVkXCIgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgc3VtbWFyeS5lcnJvcnMgKz0gMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN1bW1hcnk7XG59XG5cbmZ1bmN0aW9uIGNhbkNyZWF0ZVVubGlua2VkTG9jYWxEb2N1bWVudHMoZGVwczogQmFja2dyb3VuZFN5bmNEZXBzKTogZGVwcyBpcyBDcmVhdGVSZW1vdGVEZXBzICYgeyBsb2NhbE1hcmtkb3duUGF0aHM6ICgpID0+IFByb21pc2U8c3RyaW5nW10+IH0ge1xuICByZXR1cm4gQm9vbGVhbihkZXBzLndvcmtzcGFjZUlkICYmIGRlcHMubG9jYWxNYXJrZG93blBhdGhzICYmIGRlcHMuYXBpLnRyZWUgJiYgZGVwcy5hcGkuY3JlYXRlRm9sZGVyICYmIGRlcHMuYXBpLmNyZWF0ZURvY3VtZW50KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN5bmNEb2N1bWVudEF0dGFjaG1lbnRzKFxuICBkZXBzOiBTeW5jRGVwcyxcbiAgZW50cnk6IFNlcnZlck1ldGFFbnRyeSxcbiAgbWFya2Rvd24/OiBzdHJpbmcsXG4pOiBQcm9taXNlPEF0dGFjaG1lbnRTeW5jU3VtbWFyeT4ge1xuICBjb25zdCBhcGkgPSByZXF1aXJlQXR0YWNobWVudEFwaShkZXBzKTtcbiAgY29uc3QgbWV0YSA9IHJlcXVpcmVBdHRhY2htZW50TWV0YShkZXBzKTtcbiAgY29uc3QgdmF1bHQgPSByZXF1aXJlQmluYXJ5VmF1bHQoZGVwcyk7XG4gIGNvbnN0IHN1bW1hcnkgPSBlbXB0eUF0dGFjaG1lbnRTdW1tYXJ5KCk7XG4gIGNvbnN0IHJlbW90ZSA9IGF3YWl0IGFwaS5hdHRhY2htZW50cyhlbnRyeS5kb2N1bWVudElkKTtcbiAgY29uc3QgdHJhY2tlZCA9IGF3YWl0IG1ldGEubGlzdEF0dGFjaG1lbnRzRm9yRG9jdW1lbnQoZW50cnkuZG9jdW1lbnRJZCk7XG4gIGNvbnN0IHRyYWNrZWRCeUlkID0gbmV3IE1hcCh0cmFja2VkLm1hcCgoaXRlbSkgPT4gW2l0ZW0uYXR0YWNobWVudElkLCBpdGVtXSkpO1xuICBjb25zdCByZW1vdGVCeUlkID0gbmV3IE1hcChyZW1vdGUuYXR0YWNobWVudHMubWFwKChpdGVtKSA9PiBbaXRlbS5pZCwgaXRlbV0pKTtcbiAgY29uc3QgY29udGVudCA9IG1hcmtkb3duID8/IChhd2FpdCBkZXBzLnZhdWx0LmV4aXN0cyhlbnRyeS5sb2NhbFBhdGgpID8gYXdhaXQgZGVwcy52YXVsdC5yZWFkKGVudHJ5LmxvY2FsUGF0aCkgOiBcIlwiKTtcbiAgY29uc3QgcmVmZXJlbmNlZCA9IGVudHJ5LnBlcm1pc3Npb24gPT09IFwidmlld2VyXCIgPyBuZXcgU2V0PHN0cmluZz4oKSA6IGV4dHJhY3RBdHRhY2htZW50UGF0aHMoY29udGVudCwgZW50cnkubG9jYWxQYXRoKTtcblxuICBmb3IgKGNvbnN0IG9sZCBvZiB0cmFja2VkKSB7XG4gICAgaWYgKCFyZW1vdGVCeUlkLmhhcyhvbGQuYXR0YWNobWVudElkKSkgYXdhaXQgbWV0YS5yZW1vdmVBdHRhY2htZW50KG9sZC5hdHRhY2htZW50SWQpO1xuICB9XG5cbiAgaWYgKGVudHJ5LnBlcm1pc3Npb24gIT09IFwidmlld2VyXCIpIHtcbiAgICBmb3IgKGNvbnN0IG9sZCBvZiB0cmFja2VkKSB7XG4gICAgICBpZiAoIXJlbW90ZUJ5SWQuaGFzKG9sZC5hdHRhY2htZW50SWQpIHx8IHJlZmVyZW5jZWQuaGFzKG9sZC5sb2NhbFBhdGgpIHx8IChhd2FpdCBkZXBzLnZhdWx0LmV4aXN0cyhvbGQubG9jYWxQYXRoKSkpIGNvbnRpbnVlO1xuICAgICAgYXdhaXQgYXBpLmRlbGV0ZUF0dGFjaG1lbnQob2xkLmF0dGFjaG1lbnRJZCk7XG4gICAgICBhd2FpdCBtZXRhLnJlbW92ZUF0dGFjaG1lbnQob2xkLmF0dGFjaG1lbnRJZCk7XG4gICAgICByZW1vdGVCeUlkLmRlbGV0ZShvbGQuYXR0YWNobWVudElkKTtcbiAgICAgIHN1bW1hcnkuZGVsZXRlZCArPSAxO1xuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgYXR0YWNobWVudCBvZiByZW1vdGUuYXR0YWNobWVudHMpIHtcbiAgICBpZiAoIXJlbW90ZUJ5SWQuaGFzKGF0dGFjaG1lbnQuaWQpKSBjb250aW51ZTtcbiAgICBjb25zdCBsb2NhbFBhdGggPSB0cmFja2VkQnlJZC5nZXQoYXR0YWNobWVudC5pZCk/LmxvY2FsUGF0aCA/PyBhdHRhY2htZW50TG9jYWxQYXRoKGVudHJ5LmxvY2FsUGF0aCwgYXR0YWNobWVudC5maWxlbmFtZSk7XG4gICAgaWYgKCEoYXdhaXQgZGVwcy52YXVsdC5leGlzdHMobG9jYWxQYXRoKSkgfHwgdHJhY2tlZEJ5SWQuZ2V0KGF0dGFjaG1lbnQuaWQpPy5zaGEyNTYgIT09IGF0dGFjaG1lbnQuc2hhMjU2KSB7XG4gICAgICBhd2FpdCBlbnN1cmVQYXJlbnQoZGVwcy52YXVsdCwgbG9jYWxQYXRoKTtcbiAgICAgIGF3YWl0IHZhdWx0LndyaXRlQmluYXJ5KGxvY2FsUGF0aCwgYXdhaXQgYXBpLmRvd25sb2FkQXR0YWNobWVudChhdHRhY2htZW50LmlkKSk7XG4gICAgICBzdW1tYXJ5LmRvd25sb2FkZWQgKz0gMTtcbiAgICB9XG4gICAgYXdhaXQgbWV0YS51cHNlcnRBdHRhY2htZW50KG1ldGFGcm9tQXR0YWNobWVudChlbnRyeS5kb2N1bWVudElkLCBsb2NhbFBhdGgsIGF0dGFjaG1lbnQpKTtcbiAgfVxuXG4gIGlmIChlbnRyeS5wZXJtaXNzaW9uID09PSBcInZpZXdlclwiKSByZXR1cm4gc3VtbWFyeTtcbiAgY29uc3QgdHJhY2tlZEJ5UGF0aCA9IG5ldyBNYXAoKGF3YWl0IG1ldGEubGlzdEF0dGFjaG1lbnRzRm9yRG9jdW1lbnQoZW50cnkuZG9jdW1lbnRJZCkpLm1hcCgoaXRlbSkgPT4gW2l0ZW0ubG9jYWxQYXRoLCBpdGVtXSkpO1xuXG4gIGZvciAoY29uc3QgbG9jYWxQYXRoIG9mIHJlZmVyZW5jZWQpIHtcbiAgICBpZiAoIShhd2FpdCBkZXBzLnZhdWx0LmV4aXN0cyhsb2NhbFBhdGgpKSkge1xuICAgICAgc3VtbWFyeS5za2lwcGVkICs9IDE7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgYnl0ZXMgPSBhd2FpdCB2YXVsdC5yZWFkQmluYXJ5KGxvY2FsUGF0aCk7XG4gICAgY29uc3Qgc2hhMjU2ID0gYXdhaXQgc2hhMjU2SGV4KGJ5dGVzKTtcbiAgICBjb25zdCBleGlzdGluZyA9IHRyYWNrZWRCeVBhdGguZ2V0KGxvY2FsUGF0aCk7XG4gICAgaWYgKGV4aXN0aW5nPy5zaGEyNTYgPT09IHNoYTI1Nikge1xuICAgICAgc3VtbWFyeS5za2lwcGVkICs9IDE7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgdXBsb2FkZWQgPSBhd2FpdCBhcGkudXBsb2FkQXR0YWNobWVudChlbnRyeS5kb2N1bWVudElkLCBsb2NhbFBhdGguc3BsaXQoXCIvXCIpLnBvcCgpID8/IFwiYXR0YWNobWVudFwiLCBieXRlcywgY29udGVudFR5cGVGb3JQYXRoKGxvY2FsUGF0aCkpO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgYXdhaXQgYXBpLmRlbGV0ZUF0dGFjaG1lbnQoZXhpc3RpbmcuYXR0YWNobWVudElkKTtcbiAgICAgIGF3YWl0IG1ldGEucmVtb3ZlQXR0YWNobWVudChleGlzdGluZy5hdHRhY2htZW50SWQpO1xuICAgICAgc3VtbWFyeS5kZWxldGVkICs9IDE7XG4gICAgfVxuICAgIGF3YWl0IG1ldGEudXBzZXJ0QXR0YWNobWVudChtZXRhRnJvbUF0dGFjaG1lbnQoZW50cnkuZG9jdW1lbnRJZCwgbG9jYWxQYXRoLCB1cGxvYWRlZCkpO1xuICAgIHN1bW1hcnkudXBsb2FkZWQgKz0gMTtcbiAgfVxuXG4gIHJldHVybiBzdW1tYXJ5O1xufVxuXG5mdW5jdGlvbiBlbXB0eUF0dGFjaG1lbnRTdW1tYXJ5KCk6IEF0dGFjaG1lbnRTeW5jU3VtbWFyeSB7XG4gIHJldHVybiB7IGRvd25sb2FkZWQ6IDAsIHVwbG9hZGVkOiAwLCBkZWxldGVkOiAwLCBza2lwcGVkOiAwIH07XG59XG5cbmZ1bmN0aW9uIGhhc0F0dGFjaG1lbnRTdXBwb3J0KGRlcHM6IFN5bmNEZXBzKTogYm9vbGVhbiB7XG4gIHJldHVybiBCb29sZWFuKFxuICAgIGRlcHMuYXBpLmF0dGFjaG1lbnRzICYmXG4gICAgICBkZXBzLmFwaS51cGxvYWRBdHRhY2htZW50ICYmXG4gICAgICBkZXBzLmFwaS5kb3dubG9hZEF0dGFjaG1lbnQgJiZcbiAgICAgIGRlcHMuYXBpLmRlbGV0ZUF0dGFjaG1lbnQgJiZcbiAgICAgIGRlcHMudmF1bHQucmVhZEJpbmFyeSAmJlxuICAgICAgZGVwcy52YXVsdC53cml0ZUJpbmFyeSAmJlxuICAgICAgZGVwcy5tZXRhLmxpc3RBdHRhY2htZW50c0ZvckRvY3VtZW50ICYmXG4gICAgICBkZXBzLm1ldGEudXBzZXJ0QXR0YWNobWVudCAmJlxuICAgICAgZGVwcy5tZXRhLnJlbW92ZUF0dGFjaG1lbnQsXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJlcXVpcmVBdHRhY2htZW50QXBpKGRlcHM6IFN5bmNEZXBzKTogUmVxdWlyZWQ8UGljazxQYWdlZGVuQXBpQ2xpZW50LCBcImF0dGFjaG1lbnRzXCIgfCBcInVwbG9hZEF0dGFjaG1lbnRcIiB8IFwiZG93bmxvYWRBdHRhY2htZW50XCIgfCBcImRlbGV0ZUF0dGFjaG1lbnRcIj4+IHtcbiAgaWYgKCFkZXBzLmFwaS5hdHRhY2htZW50cyB8fCAhZGVwcy5hcGkudXBsb2FkQXR0YWNobWVudCB8fCAhZGVwcy5hcGkuZG93bmxvYWRBdHRhY2htZW50IHx8ICFkZXBzLmFwaS5kZWxldGVBdHRhY2htZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiQXR0YWNobWVudCBzeW5jIHJlcXVpcmVzIGF0dGFjaG1lbnQgQVBJIG1ldGhvZHMuXCIpO1xuICB9XG4gIHJldHVybiBkZXBzLmFwaSBhcyBSZXF1aXJlZDxQaWNrPFBhZ2VkZW5BcGlDbGllbnQsIFwiYXR0YWNobWVudHNcIiB8IFwidXBsb2FkQXR0YWNobWVudFwiIHwgXCJkb3dubG9hZEF0dGFjaG1lbnRcIiB8IFwiZGVsZXRlQXR0YWNobWVudFwiPj47XG59XG5cbmZ1bmN0aW9uIHJlcXVpcmVBdHRhY2htZW50TWV0YShkZXBzOiBTeW5jRGVwcyk6IFJlcXVpcmVkPFBpY2s8TWV0YVN0b3JlTGlrZSwgXCJsaXN0QXR0YWNobWVudHNGb3JEb2N1bWVudFwiIHwgXCJ1cHNlcnRBdHRhY2htZW50XCIgfCBcInJlbW92ZUF0dGFjaG1lbnRcIj4+IHtcbiAgaWYgKCFkZXBzLm1ldGEubGlzdEF0dGFjaG1lbnRzRm9yRG9jdW1lbnQgfHwgIWRlcHMubWV0YS51cHNlcnRBdHRhY2htZW50IHx8ICFkZXBzLm1ldGEucmVtb3ZlQXR0YWNobWVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIkF0dGFjaG1lbnQgc3luYyByZXF1aXJlcyBhdHRhY2htZW50IG1ldGFkYXRhIG1ldGhvZHMuXCIpO1xuICB9XG4gIHJldHVybiBkZXBzLm1ldGEgYXMgUmVxdWlyZWQ8UGljazxNZXRhU3RvcmVMaWtlLCBcImxpc3RBdHRhY2htZW50c0ZvckRvY3VtZW50XCIgfCBcInVwc2VydEF0dGFjaG1lbnRcIiB8IFwicmVtb3ZlQXR0YWNobWVudFwiPj47XG59XG5cbmZ1bmN0aW9uIHJlcXVpcmVCaW5hcnlWYXVsdChkZXBzOiBTeW5jRGVwcyk6IFJlcXVpcmVkPFBpY2s8VmF1bHRMaWtlLCBcInJlYWRCaW5hcnlcIiB8IFwid3JpdGVCaW5hcnlcIj4+IHtcbiAgaWYgKCFkZXBzLnZhdWx0LnJlYWRCaW5hcnkgfHwgIWRlcHMudmF1bHQud3JpdGVCaW5hcnkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJBdHRhY2htZW50IHN5bmMgcmVxdWlyZXMgYmluYXJ5IHZhdWx0IG1ldGhvZHMuXCIpO1xuICB9XG4gIHJldHVybiBkZXBzLnZhdWx0IGFzIFJlcXVpcmVkPFBpY2s8VmF1bHRMaWtlLCBcInJlYWRCaW5hcnlcIiB8IFwid3JpdGVCaW5hcnlcIj4+O1xufVxuXG5mdW5jdGlvbiBtZXRhRnJvbUF0dGFjaG1lbnQoZG9jdW1lbnRJZDogc3RyaW5nLCBsb2NhbFBhdGg6IHN0cmluZywgYXR0YWNobWVudDogQXR0YWNobWVudCk6IFNlcnZlck1ldGFBdHRhY2htZW50RW50cnkge1xuICByZXR1cm4ge1xuICAgIGF0dGFjaG1lbnRJZDogYXR0YWNobWVudC5pZCxcbiAgICBkb2N1bWVudElkLFxuICAgIGxvY2FsUGF0aCxcbiAgICBmaWxlbmFtZTogYXR0YWNobWVudC5maWxlbmFtZSxcbiAgICBzaGEyNTY6IGF0dGFjaG1lbnQuc2hhMjU2LFxuICAgIHNpemU6IGF0dGFjaG1lbnQuc2l6ZSxcbiAgICBjb250ZW50VHlwZTogYXR0YWNobWVudC5jb250ZW50VHlwZSxcbiAgICBjcmVhdGVkQXQ6IGF0dGFjaG1lbnQuY3JlYXRlZEF0LFxuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRhY2htZW50TG9jYWxQYXRoKGRvY3VtZW50UGF0aDogc3RyaW5nLCBmaWxlbmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcGFyZW50ID0gZG9jdW1lbnRQYXRoLnNwbGl0KFwiL1wiKS5zbGljZSgwLCAtMSkuam9pbihcIi9cIik7XG4gIHJldHVybiBub3JtYWxpemVQYXRoKGAke3BhcmVudH0vJHtmaWxlbmFtZX1gKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZW5zdXJlUGFyZW50KHZhdWx0OiBWYXVsdExpa2UsIHBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwYXJlbnQgPSBwYXRoLnNwbGl0KFwiL1wiKS5zbGljZSgwLCAtMSkuam9pbihcIi9cIik7XG4gIGlmIChwYXJlbnQpIGF3YWl0IGVuc3VyZUZvbGRlcih2YXVsdCwgcGFyZW50KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3RBdHRhY2htZW50UGF0aHMobWFya2Rvd246IHN0cmluZywgZG9jdW1lbnRQYXRoOiBzdHJpbmcpOiBTZXQ8c3RyaW5nPiB7XG4gIGNvbnN0IHBhcmVudCA9IGRvY3VtZW50UGF0aC5zcGxpdChcIi9cIikuc2xpY2UoMCwgLTEpLmpvaW4oXCIvXCIpO1xuICBjb25zdCBvdXQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3QgcHVzaCA9IChyYXc6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IHRhcmdldCA9IHJhdy50cmltKCk7XG4gICAgaWYgKCF0YXJnZXQgfHwgdGFyZ2V0LnN0YXJ0c1dpdGgoXCIjXCIpIHx8IC9eW2Etel1bYS16MC05Ky4tXSo6L2kudGVzdCh0YXJnZXQpIHx8IHRhcmdldC5lbmRzV2l0aChcIi5tZFwiKSkgcmV0dXJuO1xuICAgIGNvbnN0IGNsZWFuID0gdGFyZ2V0LnNwbGl0KC9bPyNdLylbMF0gPz8gXCJcIjtcbiAgICBpZiAoIWNsZWFuKSByZXR1cm47XG4gICAgb3V0LmFkZChub3JtYWxpemVQYXRoKGNsZWFuLnN0YXJ0c1dpdGgoXCIvXCIpID8gY2xlYW4uc2xpY2UoMSkgOiBgJHtwYXJlbnR9LyR7Y2xlYW59YCkpO1xuICB9O1xuICBmb3IgKGNvbnN0IG1hdGNoIG9mIG1hcmtkb3duLm1hdGNoQWxsKC8hXFxbW15cXF1dKl1cXCgoW14pXSspXFwpfFxcW1teXFxdXStdXFwoKFteKV0rKVxcKS9nKSkge1xuICAgIHB1c2gobWF0Y2hbMV0gPz8gbWF0Y2hbMl0gPz8gXCJcIik7XG4gIH1cbiAgZm9yIChjb25zdCBtYXRjaCBvZiBtYXJrZG93bi5tYXRjaEFsbCgvIVxcW1xcWyhbXlxcXXwjXSspKD86I1teXFxdfF0rKT8oPzpcXHxbXlxcXV0rKT9dXS9nKSkge1xuICAgIHB1c2gobWF0Y2hbMV0gPz8gXCJcIik7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2hhMjU2SGV4KGJ5dGVzOiBBcnJheUJ1ZmZlcik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGhhc2ggPSBhd2FpdCBjcnlwdG8uc3VidGxlLmRpZ2VzdChcIlNIQS0yNTZcIiwgYnl0ZXMpO1xuICByZXR1cm4gWy4uLm5ldyBVaW50OEFycmF5KGhhc2gpXS5tYXAoKGIpID0+IGIudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIFwiMFwiKSkuam9pbihcIlwiKTtcbn1cblxuZnVuY3Rpb24gY29udGVudFR5cGVGb3JQYXRoKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGV4dCA9IHBhdGguc3BsaXQoXCIuXCIpLnBvcCgpPy50b0xvd2VyQ2FzZSgpO1xuICBpZiAoZXh0ID09PSBcInBuZ1wiKSByZXR1cm4gXCJpbWFnZS9wbmdcIjtcbiAgaWYgKGV4dCA9PT0gXCJqcGdcIiB8fCBleHQgPT09IFwianBlZ1wiKSByZXR1cm4gXCJpbWFnZS9qcGVnXCI7XG4gIGlmIChleHQgPT09IFwiZ2lmXCIpIHJldHVybiBcImltYWdlL2dpZlwiO1xuICBpZiAoZXh0ID09PSBcIndlYnBcIikgcmV0dXJuIFwiaW1hZ2Uvd2VicFwiO1xuICBpZiAoZXh0ID09PSBcInN2Z1wiKSByZXR1cm4gXCJpbWFnZS9zdmcreG1sXCI7XG4gIGlmIChleHQgPT09IFwicGRmXCIpIHJldHVybiBcImFwcGxpY2F0aW9uL3BkZlwiO1xuICByZXR1cm4gXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1cIjtcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gY2Fub25pY2FsaXplKGNvbnRlbnQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBjb250ZW50LnJlcGxhY2UoL1xcclxcbi9nLCBcIlxcblwiKS5yZXBsYWNlKC9cXHIvZywgXCJcXG5cIikucmVwbGFjZSgvXFxuKiQvLCBcIlwiKSArIFwiXFxuXCI7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjaGVja3N1bShjb250ZW50OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBpZiAoIWdsb2JhbFRoaXMuY3J5cHRvPy5zdWJ0bGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJXZWIgQ3J5cHRvIGlzIHJlcXVpcmVkIHRvIGNvbXB1dGUgUGFnZWRlbiBjaGVja3N1bXMuXCIpO1xuICB9XG4gIGNvbnN0IGJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGNhbm9uaWNhbGl6ZShjb250ZW50KSk7XG4gIGNvbnN0IGRpZ2VzdCA9IGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5kaWdlc3QoXCJTSEEtMjU2XCIsIGJ5dGVzKTtcbiAgY29uc3QgaGV4ID0gWy4uLm5ldyBVaW50OEFycmF5KGRpZ2VzdCldLm1hcCgoYnl0ZSkgPT4gYnl0ZS50b1N0cmluZygxNikucGFkU3RhcnQoMiwgXCIwXCIpKS5qb2luKFwiXCIpO1xuICByZXR1cm4gYHNoYTI1Njoke2hleH1gO1xufVxuIiwgIi8vIFNtYWxsLCBmcmFtZXdvcmstZnJlZSBjb25jdXJyZW5jeSBoZWxwZXJzIHVzZWQgYnkgdGhlIGJhY2tncm91bmQtc3luYyBlbmdpbmUuIEtlcHQgcHVyZSBzb1xuLy8gdGhlIGxvb3Atc2FmZXR5IGFuZCBkZWJvdW5jZSBiZWhhdmlvdXIgY2FuIGJlIHVuaXQtdGVzdGVkIHdpdGhvdXQgYW4gT2JzaWRpYW4gcnVudGltZS5cblxuLyoqXG4gKiBTZXJpYWxpc2VzIGFzeW5jIHBhc3NlcyBzbyBvbmx5IG9uZSBydW5zIGF0IGEgdGltZS4gSWYgYHJ1bigpYCBpcyBjYWxsZWQgd2hpbGUgYSBwYXNzIGlzIGluXG4gKiBmbGlnaHQsIGV4YWN0bHkgb25lIGZvbGxvdy11cCBwYXNzIGlzIHF1ZXVlZCAoZnVydGhlciBjYWxscyBjb2xsYXBzZSBpbnRvIHRoYXQgc2luZ2xlIHBlbmRpbmdcbiAqIHJ1bikgXHUyMDE0IHNvIG92ZXJsYXBwaW5nIHRyaWdnZXJzIChzdGFydHVwICsgaW50ZXJ2YWwgKyBhIG1vZGlmeSBldmVudCkgbmV2ZXIgcmFjZSB0aGUgQVBJLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU3luY1J1bm5lcihwYXNzOiAoKSA9PiBQcm9taXNlPHZvaWQ+KTogeyBydW46ICgpID0+IFByb21pc2U8dm9pZD47IGlzUnVubmluZzogKCkgPT4gYm9vbGVhbiB9IHtcbiAgbGV0IGluRmxpZ2h0ID0gZmFsc2U7XG4gIGxldCBwZW5kaW5nID0gZmFsc2U7XG4gIGFzeW5jIGZ1bmN0aW9uIHJ1bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoaW5GbGlnaHQpIHtcbiAgICAgIHBlbmRpbmcgPSB0cnVlOyAvLyBjb2xsYXBzZSBhbGwgb3ZlcmxhcHBpbmcgdHJpZ2dlcnMgaW50byBhIHNpbmdsZSBmb2xsb3ctdXBcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaW5GbGlnaHQgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICAvLyBMb29wIChub3QgcmVjdXJzaW9uKSBzbyBzdXN0YWluZWQgdHJpZ2dlcnMgY2FuJ3QgYnVpbGQgYW4gdW5ib3VuZGVkIHByb21pc2UgY2hhaW4uXG4gICAgICBkbyB7XG4gICAgICAgIHBlbmRpbmcgPSBmYWxzZTtcbiAgICAgICAgYXdhaXQgcGFzcygpO1xuICAgICAgfSB3aGlsZSAocGVuZGluZyk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGluRmxpZ2h0ID0gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB7IHJ1biwgaXNSdW5uaW5nOiAoKSA9PiBpbkZsaWdodCB9O1xufVxuXG4vKipcbiAqIFBlci1rZXkgZGVib3VuY2VyOiByZXBlYXRlZCBgc2NoZWR1bGUoa2V5LCBmbilgIGNhbGxzIHdpdGhpbiBgbXNgIGNvbGxhcHNlIGludG8gYSBzaW5nbGVcbiAqIHRyYWlsaW5nIGludm9jYXRpb24gb2YgdGhlIG1vc3QgcmVjZW50IGBmbmAgZm9yIHRoYXQga2V5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRGVib3VuY2VyKG1zOiBudW1iZXIpOiB7XG4gIHNjaGVkdWxlOiAoa2V5OiBzdHJpbmcsIGZuOiAoKSA9PiB2b2lkKSA9PiB2b2lkO1xuICBjYW5jZWw6IChrZXk6IHN0cmluZykgPT4gdm9pZDtcbiAgY2FuY2VsQWxsOiAoKSA9PiB2b2lkO1xufSB7XG4gIGNvbnN0IHRpbWVycyA9IG5ldyBNYXA8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0Pj4oKTtcbiAgZnVuY3Rpb24gY2FuY2VsKGtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aW1lcnMuZ2V0KGtleSk7XG4gICAgaWYgKGV4aXN0aW5nICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNsZWFyVGltZW91dChleGlzdGluZyk7XG4gICAgICB0aW1lcnMuZGVsZXRlKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgc2NoZWR1bGUoa2V5OiBzdHJpbmcsIGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICBjYW5jZWwoa2V5KTtcbiAgICAgIHRpbWVycy5zZXQoXG4gICAgICAgIGtleSxcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGltZXJzLmRlbGV0ZShrZXkpO1xuICAgICAgICAgIGZuKCk7XG4gICAgICAgIH0sIG1zKSxcbiAgICAgICk7XG4gICAgfSxcbiAgICBjYW5jZWwsXG4gICAgY2FuY2VsQWxsKCk6IHZvaWQge1xuICAgICAgZm9yIChjb25zdCB0aW1lciBvZiB0aW1lcnMudmFsdWVzKCkpIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICB0aW1lcnMuY2xlYXIoKTtcbiAgICB9LFxuICB9O1xufVxuIiwgImltcG9ydCB7IG5vcm1hbGl6ZVBhdGggfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB0eXBlIHsgUGFnZWRlbkFwaUNsaWVudCB9IGZyb20gXCIuL2FwaS1jbGllbnRcIjtcbmltcG9ydCB7IGNhbm9uaWNhbGl6ZSB9IGZyb20gXCIuL2NoZWNrc3VtXCI7XG5pbXBvcnQgdHlwZSB7IFJlbW90ZUZvbGRlciwgUmVtb3RlVHJlZSwgU2VydmVyTWV0YUVudHJ5IH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB0eXBlIHsgTWV0YVN0b3JlTGlrZSwgVmF1bHRMaWtlIH0gZnJvbSBcIi4vc3luY1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZhdWx0SW1wb3J0RmlsZSB7XG4gIHBhdGg6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBleHRlbnNpb246IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWYXVsdEltcG9ydFByZXZpZXcge1xuICB0YXJnZXRSb290TmFtZTogc3RyaW5nO1xuICB0YXJnZXRSb290U2x1Zzogc3RyaW5nO1xuICBub3RlczogbnVtYmVyO1xuICBhdHRhY2htZW50czogbnVtYmVyO1xuICBza2lwcGVkOiBudW1iZXI7XG4gIGNvbmZsaWN0czogc3RyaW5nW107XG4gIHdhcm5pbmdzOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWYXVsdEltcG9ydFJlcG9ydCBleHRlbmRzIFZhdWx0SW1wb3J0UHJldmlldyB7XG4gIGZvbGRlcnNDcmVhdGVkOiBudW1iZXI7XG4gIGRvY3VtZW50c0NyZWF0ZWQ6IG51bWJlcjtcbiAgZG9jdW1lbnRzU2tpcHBlZDogbnVtYmVyO1xuICBhdHRhY2htZW50c1VwbG9hZGVkOiBudW1iZXI7XG4gIGF0dGFjaG1lbnRXYXJuaW5nczogc3RyaW5nW107XG4gIHJvd3M6IEltcG9ydFJlcG9ydFJvd1tdO1xufVxuXG5leHBvcnQgdHlwZSBJbXBvcnRSZXBvcnRSb3cgPVxuICB8IHsgcGF0aDogc3RyaW5nOyBzdGF0dXM6IFwiY3JlYXRlZFwiOyBtZXNzYWdlOiBzdHJpbmcgfVxuICB8IHsgcGF0aDogc3RyaW5nOyBzdGF0dXM6IFwic2tpcHBlZFwiOyBtZXNzYWdlOiBzdHJpbmcgfVxuICB8IHsgcGF0aDogc3RyaW5nOyBzdGF0dXM6IFwid2FybmluZ1wiOyBtZXNzYWdlOiBzdHJpbmcgfTtcblxuaW50ZXJmYWNlIEltcG9ydERlcHMge1xuICBhcGk6IFBpY2s8UGFnZWRlbkFwaUNsaWVudCwgXCJ0cmVlXCIgfCBcImNyZWF0ZUZvbGRlclwiIHwgXCJjcmVhdGVEb2N1bWVudFwiIHwgXCJkb2N1bWVudFwiIHwgXCJ1cGxvYWRBdHRhY2htZW50XCI+O1xuICB2YXVsdDogUGljazxWYXVsdExpa2UsIFwicmVhZFwiIHwgXCJyZWFkQmluYXJ5XCI+O1xuICBtZXRhOiBQaWNrPE1ldGFTdG9yZUxpa2UsIFwidXBzZXJ0XCI+O1xuICB3b3Jrc3BhY2VJZDogc3RyaW5nO1xuICBmaWxlczogVmF1bHRJbXBvcnRGaWxlW107XG4gIHRhcmdldFJvb3ROYW1lOiBzdHJpbmc7XG4gIHJlbW90ZVRyZWU/OiBSZW1vdGVUcmVlO1xuICBvblByb2dyZXNzPzogKGN1cnJlbnQ6IG51bWJlciwgdG90YWw6IG51bWJlcikgPT4gdm9pZDtcbn1cblxuaW50ZXJmYWNlIEltcG9ydGFibGVGaWxlcyB7XG4gIG5vdGVzOiBWYXVsdEltcG9ydEZpbGVbXTtcbiAgYXR0YWNobWVudHM6IFZhdWx0SW1wb3J0RmlsZVtdO1xuICBza2lwcGVkOiBudW1iZXI7XG59XG5cbmNvbnN0IERFRkFVTFRfUk9PVF9OQU1FID0gXCJJbXBvcnRlZCBmcm9tIE9ic2lkaWFuXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFZhdWx0SW1wb3J0UHJldmlldyhmaWxlczogVmF1bHRJbXBvcnRGaWxlW10sIHJlbW90ZVRyZWU6IFJlbW90ZVRyZWUsIHRhcmdldFJvb3ROYW1lID0gREVGQVVMVF9ST09UX05BTUUpOiBWYXVsdEltcG9ydFByZXZpZXcge1xuICBjb25zdCBpbXBvcnRhYmxlID0gc3BsaXRJbXBvcnRhYmxlRmlsZXMoZmlsZXMpO1xuICBjb25zdCB0YXJnZXRSb290U2x1ZyA9IHNsdWdpZnkodGFyZ2V0Um9vdE5hbWUpO1xuICBjb25zdCByZW1vdGVEb2N1bWVudFBhdGhzID0gbmV3IFNldChyZW1vdGVUcmVlLmRvY3VtZW50cy5tYXAoKGRvYykgPT4gdHJpbVNsYXNoZXMoZG9jLnBhdGgpKSk7XG4gIGNvbnN0IGNvbmZsaWN0cyA9IGltcG9ydGFibGUubm90ZXNcbiAgICAubWFwKChmaWxlKSA9PiByZW1vdGVQYXRoRm9yTm90ZShmaWxlLnBhdGgsIHRhcmdldFJvb3RTbHVnKSlcbiAgICAuZmlsdGVyKChwYXRoKSA9PiByZW1vdGVEb2N1bWVudFBhdGhzLmhhcyhwYXRoKSlcbiAgICAuc29ydCgpO1xuXG4gIGNvbnN0IHdhcm5pbmdzID0gY29uZmxpY3RzLmxlbmd0aFxuICAgID8gW2Ake2NvbmZsaWN0cy5sZW5ndGh9IG5vdGUke2NvbmZsaWN0cy5sZW5ndGggPT09IDEgPyBcIlwiIDogXCJzXCJ9IGFscmVhZHkgZXhpc3QgaW4gUGFnZWRlbiBhbmQgd2lsbCBiZSBza2lwcGVkLmBdXG4gICAgOiBbXTtcblxuICByZXR1cm4ge1xuICAgIHRhcmdldFJvb3ROYW1lLFxuICAgIHRhcmdldFJvb3RTbHVnLFxuICAgIG5vdGVzOiBpbXBvcnRhYmxlLm5vdGVzLmxlbmd0aCxcbiAgICBhdHRhY2htZW50czogaW1wb3J0YWJsZS5hdHRhY2htZW50cy5sZW5ndGgsXG4gICAgc2tpcHBlZDogaW1wb3J0YWJsZS5za2lwcGVkLFxuICAgIGNvbmZsaWN0cyxcbiAgICB3YXJuaW5ncyxcbiAgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGltcG9ydFZhdWx0VG9QYWdlZGVuKGRlcHM6IEltcG9ydERlcHMpOiBQcm9taXNlPFZhdWx0SW1wb3J0UmVwb3J0PiB7XG4gIGNvbnN0IHJlbW90ZVRyZWUgPSBkZXBzLnJlbW90ZVRyZWUgPz8gKGF3YWl0IGRlcHMuYXBpLnRyZWUoZGVwcy53b3Jrc3BhY2VJZCkpO1xuICBjb25zdCBwcmV2aWV3ID0gYnVpbGRWYXVsdEltcG9ydFByZXZpZXcoZGVwcy5maWxlcywgcmVtb3RlVHJlZSwgZGVwcy50YXJnZXRSb290TmFtZSk7XG4gIGNvbnN0IGltcG9ydGFibGUgPSBzcGxpdEltcG9ydGFibGVGaWxlcyhkZXBzLmZpbGVzKTtcbiAgY29uc3QgYXR0YWNobWVudEluZGV4ID0gYnVpbGRBdHRhY2htZW50SW5kZXgoaW1wb3J0YWJsZS5hdHRhY2htZW50cyk7XG4gIGNvbnN0IGZvbGRlckJ5UGF0aCA9IG5ldyBNYXAocmVtb3RlVHJlZS5mb2xkZXJzLm1hcCgoZm9sZGVyKSA9PiBbdHJpbVNsYXNoZXMoZm9sZGVyLnBhdGgpLCBmb2xkZXJdKSk7XG4gIGNvbnN0IGRvY3VtZW50UGF0aHMgPSBuZXcgU2V0KHJlbW90ZVRyZWUuZG9jdW1lbnRzLm1hcCgoZG9jKSA9PiB0cmltU2xhc2hlcyhkb2MucGF0aCkpKTtcbiAgY29uc3QgdGFyZ2V0Um9vdFNsdWcgPSBwcmV2aWV3LnRhcmdldFJvb3RTbHVnO1xuICBsZXQgZm9sZGVyc0NyZWF0ZWQgPSAwO1xuICBsZXQgZG9jdW1lbnRzQ3JlYXRlZCA9IDA7XG4gIGxldCBkb2N1bWVudHNTa2lwcGVkID0gMDtcbiAgbGV0IGF0dGFjaG1lbnRzVXBsb2FkZWQgPSAwO1xuICBjb25zdCBhdHRhY2htZW50V2FybmluZ3M6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHJvd3M6IEltcG9ydFJlcG9ydFJvd1tdID0gW107XG5cbiAgYXN5bmMgZnVuY3Rpb24gZW5zdXJlUmVtb3RlRm9sZGVyKGxvY2FsRGlyOiBzdHJpbmcpOiBQcm9taXNlPFJlbW90ZUZvbGRlcj4ge1xuICAgIGNvbnN0IHNlZ21lbnRzID0gbG9jYWxEaXIuc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgICBsZXQgcGFyZW50OiBSZW1vdGVGb2xkZXIgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgY3VycmVudFBhdGggPSBcIlwiO1xuXG4gICAgY29uc3Qgcm9vdFBhdGggPSB0YXJnZXRSb290U2x1ZztcbiAgICBwYXJlbnQgPSBmb2xkZXJCeVBhdGguZ2V0KHJvb3RQYXRoKSA/PyBudWxsO1xuICAgIGlmICghcGFyZW50KSB7XG4gICAgICBjb25zdCBjcmVhdGVkID0gYXdhaXQgZGVwcy5hcGkuY3JlYXRlRm9sZGVyKHtcbiAgICAgICAgd29ya3NwYWNlSWQ6IGRlcHMud29ya3NwYWNlSWQsXG4gICAgICAgIHBhcmVudEZvbGRlcklkOiBudWxsLFxuICAgICAgICBuYW1lOiBkZXBzLnRhcmdldFJvb3ROYW1lLFxuICAgICAgICBzbHVnOiB0YXJnZXRSb290U2x1ZyxcbiAgICAgIH0pO1xuICAgICAgcGFyZW50ID0gZm9sZGVyRnJvbUNyZWF0ZShjcmVhdGVkLmlkLCBudWxsLCBkZXBzLnRhcmdldFJvb3ROYW1lLCB0YXJnZXRSb290U2x1ZywgY3JlYXRlZC5wYXRoKTtcbiAgICAgIGZvbGRlckJ5UGF0aC5zZXQocm9vdFBhdGgsIHBhcmVudCk7XG4gICAgICBmb2xkZXJzQ3JlYXRlZCArPSAxO1xuICAgIH1cbiAgICBjdXJyZW50UGF0aCA9IHJvb3RQYXRoO1xuXG4gICAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7XG4gICAgICBjb25zdCBzbHVnID0gc2x1Z2lmeShzZWdtZW50KTtcbiAgICAgIGN1cnJlbnRQYXRoID0gYCR7Y3VycmVudFBhdGh9LyR7c2x1Z31gO1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBmb2xkZXJCeVBhdGguZ2V0KGN1cnJlbnRQYXRoKTtcbiAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICBwYXJlbnQgPSBleGlzdGluZztcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBjcmVhdGVkID0gYXdhaXQgZGVwcy5hcGkuY3JlYXRlRm9sZGVyKHtcbiAgICAgICAgd29ya3NwYWNlSWQ6IGRlcHMud29ya3NwYWNlSWQsXG4gICAgICAgIHBhcmVudEZvbGRlcklkOiBwYXJlbnQuaWQsXG4gICAgICAgIG5hbWU6IHNlZ21lbnQsXG4gICAgICAgIHNsdWcsXG4gICAgICB9KTtcbiAgICAgIHBhcmVudCA9IGZvbGRlckZyb21DcmVhdGUoY3JlYXRlZC5pZCwgcGFyZW50LmlkLCBzZWdtZW50LCBzbHVnLCBjcmVhdGVkLnBhdGgpO1xuICAgICAgZm9sZGVyQnlQYXRoLnNldChjdXJyZW50UGF0aCwgcGFyZW50KTtcbiAgICAgIGZvbGRlcnNDcmVhdGVkICs9IDE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhcmVudDtcbiAgfVxuXG4gIGxldCBub3RlSW5kZXggPSAwO1xuICBmb3IgKGNvbnN0IG5vdGUgb2YgaW1wb3J0YWJsZS5ub3Rlcykge1xuICAgIG5vdGVJbmRleCsrO1xuICAgIGRlcHMub25Qcm9ncmVzcz8uKG5vdGVJbmRleCwgaW1wb3J0YWJsZS5ub3Rlcy5sZW5ndGgpO1xuICAgIGNvbnN0IHJlbW90ZVBhdGggPSByZW1vdGVQYXRoRm9yTm90ZShub3RlLnBhdGgsIHRhcmdldFJvb3RTbHVnKTtcbiAgICBpZiAoZG9jdW1lbnRQYXRocy5oYXMocmVtb3RlUGF0aCkpIHtcbiAgICAgIGRvY3VtZW50c1NraXBwZWQgKz0gMTtcbiAgICAgIHJvd3MucHVzaCh7IHBhdGg6IG5vdGUucGF0aCwgc3RhdHVzOiBcInNraXBwZWRcIiwgbWVzc2FnZTogXCJBIGRvY3VtZW50IHdpdGggdGhpcyBwYXRoIGFscmVhZHkgZXhpc3RzLlwiIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IGxvY2FsRGlyID0gZGlybmFtZShub3RlLnBhdGgpO1xuICAgIGNvbnN0IGZvbGRlciA9IGF3YWl0IGVuc3VyZVJlbW90ZUZvbGRlcihsb2NhbERpcik7XG4gICAgY29uc3QgY29udGVudCA9IGNhbm9uaWNhbGl6ZShhd2FpdCBkZXBzLnZhdWx0LnJlYWQobm90ZS5wYXRoKSk7XG4gICAgY29uc3QgdGl0bGUgPSBmcm9udG1hdHRlclRpdGxlKGNvbnRlbnQpID8/IChiYXNlbmFtZShub3RlLnBhdGgpLnJlcGxhY2UoL1xcLm1kJC9pLCBcIlwiKSB8fCBcIlVudGl0bGVkXCIpO1xuICAgIGNvbnN0IGNyZWF0ZWQgPSBhd2FpdCBkZXBzLmFwaS5jcmVhdGVEb2N1bWVudCh7XG4gICAgICB3b3Jrc3BhY2VJZDogZGVwcy53b3Jrc3BhY2VJZCxcbiAgICAgIGZvbGRlcklkOiBmb2xkZXIuaWQsXG4gICAgICB0aXRsZSxcbiAgICAgIHNsdWc6IHNsdWdpZnkoYmFzZW5hbWUobm90ZS5wYXRoKS5yZXBsYWNlKC9cXC5tZCQvaSwgXCJcIikpLFxuICAgICAgY29udGVudCxcbiAgICB9KTtcbiAgICBkb2N1bWVudFBhdGhzLmFkZCh0cmltU2xhc2hlcyhjcmVhdGVkLnBhdGgpKTtcbiAgICBjb25zdCByZW1vdGUgPSBhd2FpdCBkZXBzLmFwaS5kb2N1bWVudChjcmVhdGVkLmlkKTtcbiAgICBhd2FpdCBkZXBzLm1ldGEudXBzZXJ0KG1ldGFGcm9tSW1wb3J0ZWRSZW1vdGUocmVtb3RlLCBub3RlLnBhdGgpKTtcbiAgICBkb2N1bWVudHNDcmVhdGVkICs9IDE7XG4gICAgcm93cy5wdXNoKHsgcGF0aDogbm90ZS5wYXRoLCBzdGF0dXM6IFwiY3JlYXRlZFwiLCBtZXNzYWdlOiBgQ3JlYXRlZCAke2NyZWF0ZWQucGF0aH1gIH0pO1xuXG4gICAgY29uc3QgcmVmcyA9IGV4dHJhY3RBdHRhY2htZW50UmVmcyhjb250ZW50KTtcbiAgICBjb25zdCB1cGxvYWRlZEZvckRvYyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGZvciAoY29uc3QgcmVmIG9mIHJlZnMpIHtcbiAgICAgIGNvbnN0IGF0dGFjaG1lbnQgPSByZXNvbHZlQXR0YWNobWVudFJlZihyZWYsIG5vdGUucGF0aCwgYXR0YWNobWVudEluZGV4KTtcbiAgICAgIGlmICghYXR0YWNobWVudCB8fCB1cGxvYWRlZEZvckRvYy5oYXMoYXR0YWNobWVudC5wYXRoKSkgY29udGludWU7XG4gICAgICB1cGxvYWRlZEZvckRvYy5hZGQoYXR0YWNobWVudC5wYXRoKTtcbiAgICAgIGlmICghZGVwcy52YXVsdC5yZWFkQmluYXJ5KSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBgQ2Fubm90IHVwbG9hZCAke2F0dGFjaG1lbnQucGF0aH06IHRoaXMgdmF1bHQgYWRhcHRlciBkb2VzIG5vdCBzdXBwb3J0IGJpbmFyeSByZWFkcy5gO1xuICAgICAgICBhdHRhY2htZW50V2FybmluZ3MucHVzaChtZXNzYWdlKTtcbiAgICAgICAgcm93cy5wdXNoKHsgcGF0aDogYXR0YWNobWVudC5wYXRoLCBzdGF0dXM6IFwid2FybmluZ1wiLCBtZXNzYWdlIH0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGJ5dGVzID0gYXdhaXQgZGVwcy52YXVsdC5yZWFkQmluYXJ5KGF0dGFjaG1lbnQucGF0aCk7XG4gICAgICAgIGF3YWl0IHVwbG9hZEF0dGFjaG1lbnRXaXRoUmV0cnkoZGVwcy5hcGksIHJlbW90ZS5pZCwgYmFzZW5hbWUoYXR0YWNobWVudC5wYXRoKSwgYnl0ZXMsIG1pbWVUeXBlRm9yUGF0aChhdHRhY2htZW50LnBhdGgpKTtcbiAgICAgICAgYXR0YWNobWVudHNVcGxvYWRlZCArPSAxO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IGBDb3VsZCBub3QgdXBsb2FkICR7YXR0YWNobWVudC5wYXRofTogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFwidW5rbm93biBlcnJvclwifWA7XG4gICAgICAgIGF0dGFjaG1lbnRXYXJuaW5ncy5wdXNoKG1lc3NhZ2UpO1xuICAgICAgICByb3dzLnB1c2goeyBwYXRoOiBhdHRhY2htZW50LnBhdGgsIHN0YXR1czogXCJ3YXJuaW5nXCIsIG1lc3NhZ2UgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5wcmV2aWV3LFxuICAgIGZvbGRlcnNDcmVhdGVkLFxuICAgIGRvY3VtZW50c0NyZWF0ZWQsXG4gICAgZG9jdW1lbnRzU2tpcHBlZCxcbiAgICBhdHRhY2htZW50c1VwbG9hZGVkLFxuICAgIGF0dGFjaG1lbnRXYXJuaW5ncyxcbiAgICByb3dzLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEF0dGFjaG1lbnRSZWZzKG1hcmtkb3duOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHJlZnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3Qgb2JzaWRpYW5FbWJlZCA9IC8hXFxbXFxbKFteXFxdI3xdKykoPzpbI3xdW15cXF1dKik/XFxdXFxdL2c7XG4gIGNvbnN0IG1hcmtkb3duSW1hZ2UgPSAvIVxcW1teXFxdXSpdXFwoKD8hW2Etel1bYS16MC05Ky4tXSo6KShbXilcXHNdKykoPzpcXHMrXCJbXlwiXSpcIik/XFwpL2dpO1xuXG4gIGZvciAoY29uc3QgbWF0Y2ggb2YgbWFya2Rvd24ubWF0Y2hBbGwob2JzaWRpYW5FbWJlZCkpIHtcbiAgICBpZiAobWF0Y2hbMV0pIHJlZnMuYWRkKG1hdGNoWzFdKTtcbiAgfVxuICBmb3IgKGNvbnN0IG1hdGNoIG9mIG1hcmtkb3duLm1hdGNoQWxsKG1hcmtkb3duSW1hZ2UpKSB7XG4gICAgaWYgKG1hdGNoWzFdKSByZWZzLmFkZChkZWNvZGVVUklDb21wb25lbnQobWF0Y2hbMV0pKTtcbiAgfVxuICByZXR1cm4gWy4uLnJlZnNdO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2x1Z2lmeSh2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgc2x1ZyA9IHZhbHVlXG4gICAgLm5vcm1hbGl6ZShcIk5GS0RcIilcbiAgICAucmVwbGFjZSgvW1xcdTAzMDAtXFx1MDM2Zl0vZywgXCJcIilcbiAgICAudG9Mb3dlckNhc2UoKVxuICAgIC5yZXBsYWNlKC9cXC5tZCQvaSwgXCJcIilcbiAgICAucmVwbGFjZSgvW15hLXowLTldKy9nLCBcIi1cIilcbiAgICAucmVwbGFjZSgvXi0rfC0rJC9nLCBcIlwiKTtcbiAgcmV0dXJuIHNsdWcgfHwgXCJ1bnRpdGxlZFwiO1xufVxuXG5mdW5jdGlvbiBzcGxpdEltcG9ydGFibGVGaWxlcyhmaWxlczogVmF1bHRJbXBvcnRGaWxlW10pOiBJbXBvcnRhYmxlRmlsZXMge1xuICBsZXQgc2tpcHBlZCA9IDA7XG4gIGNvbnN0IG5vdGVzOiBWYXVsdEltcG9ydEZpbGVbXSA9IFtdO1xuICBjb25zdCBhdHRhY2htZW50czogVmF1bHRJbXBvcnRGaWxlW10gPSBbXTtcbiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgY29uc3QgcGF0aCA9IG5vcm1hbGl6ZVBhdGgoZmlsZS5wYXRoKTtcbiAgICBpZiAoaXNJZ25vcmVkUGF0aChwYXRoKSkge1xuICAgICAgc2tpcHBlZCArPSAxO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChmaWxlLmV4dGVuc2lvbi50b0xvd2VyQ2FzZSgpID09PSBcIm1kXCIpIHtcbiAgICAgIGlmIChwYXRoLmVuZHNXaXRoKFwiLmNvbmZsaWN0Lm1kXCIpKSBza2lwcGVkICs9IDE7XG4gICAgICBlbHNlIG5vdGVzLnB1c2goeyAuLi5maWxlLCBwYXRoIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBhdHRhY2htZW50cy5wdXNoKHsgLi4uZmlsZSwgcGF0aCB9KTtcbiAgICB9XG4gIH1cbiAgbm90ZXMuc29ydCgoYSwgYikgPT4gYS5wYXRoLmxvY2FsZUNvbXBhcmUoYi5wYXRoKSk7XG4gIGF0dGFjaG1lbnRzLnNvcnQoKGEsIGIpID0+IGEucGF0aC5sb2NhbGVDb21wYXJlKGIucGF0aCkpO1xuICByZXR1cm4geyBub3RlcywgYXR0YWNobWVudHMsIHNraXBwZWQgfTtcbn1cblxuZnVuY3Rpb24gaXNJZ25vcmVkUGF0aChwYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIHBhdGguc3RhcnRzV2l0aChcIi5vYnNpZGlhbi9cIikgfHwgcGF0aC5zdGFydHNXaXRoKFwiLnRyYXNoL1wiKSB8fCBwYXRoLnN0YXJ0c1dpdGgoXCIuZ2l0L1wiKTtcbn1cblxuZnVuY3Rpb24gYnVpbGRBdHRhY2htZW50SW5kZXgoZmlsZXM6IFZhdWx0SW1wb3J0RmlsZVtdKSB7XG4gIGNvbnN0IGJ5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBWYXVsdEltcG9ydEZpbGU+KCk7XG4gIGNvbnN0IGJ5TmFtZSA9IG5ldyBNYXA8c3RyaW5nLCBWYXVsdEltcG9ydEZpbGVbXT4oKTtcbiAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgYnlQYXRoLnNldChmaWxlLnBhdGgsIGZpbGUpO1xuICAgIGNvbnN0IGxpc3QgPSBieU5hbWUuZ2V0KGZpbGUubmFtZSkgPz8gW107XG4gICAgbGlzdC5wdXNoKGZpbGUpO1xuICAgIGJ5TmFtZS5zZXQoZmlsZS5uYW1lLCBsaXN0KTtcbiAgfVxuICByZXR1cm4geyBieVBhdGgsIGJ5TmFtZSB9O1xufVxuXG5mdW5jdGlvbiByZXNvbHZlQXR0YWNobWVudFJlZihcbiAgcmVmOiBzdHJpbmcsXG4gIG5vdGVQYXRoOiBzdHJpbmcsXG4gIGluZGV4OiBSZXR1cm5UeXBlPHR5cGVvZiBidWlsZEF0dGFjaG1lbnRJbmRleD4sXG4pOiBWYXVsdEltcG9ydEZpbGUgfCBudWxsIHtcbiAgY29uc3QgY2xlYW5SZWYgPSBub3JtYWxpemVQYXRoKHJlZi5yZXBsYWNlKC9ePHw+JC9nLCBcIlwiKSk7XG4gIGNvbnN0IG5vdGVEaXIgPSBkaXJuYW1lKG5vdGVQYXRoKTtcbiAgY29uc3QgY2FuZGlkYXRlcyA9IFtcbiAgICBub3JtYWxpemVQYXRoKGAke25vdGVEaXJ9LyR7Y2xlYW5SZWZ9YCksXG4gICAgY2xlYW5SZWYsXG4gIF07XG4gIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICBjb25zdCBmb3VuZCA9IGluZGV4LmJ5UGF0aC5nZXQoY2FuZGlkYXRlKTtcbiAgICBpZiAoZm91bmQpIHJldHVybiBmb3VuZDtcbiAgfVxuICBjb25zdCBieU5hbWUgPSBpbmRleC5ieU5hbWUuZ2V0KGJhc2VuYW1lKGNsZWFuUmVmKSk7XG4gIGlmIChieU5hbWU/Lmxlbmd0aCkgcmV0dXJuIGJ5TmFtZVswXSA/PyBudWxsO1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gcmVtb3RlUGF0aEZvck5vdGUocGF0aDogc3RyaW5nLCB0YXJnZXRSb290U2x1Zzogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgbG9jYWxEaXIgPSBkaXJuYW1lKHBhdGgpXG4gICAgLnNwbGl0KFwiL1wiKVxuICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAubWFwKHNsdWdpZnkpXG4gICAgLmpvaW4oXCIvXCIpO1xuICBjb25zdCBkb2NTbHVnID0gc2x1Z2lmeShiYXNlbmFtZShwYXRoKSk7XG4gIHJldHVybiBbdGFyZ2V0Um9vdFNsdWcsIGxvY2FsRGlyLCBgJHtkb2NTbHVnfS5tZGBdLmZpbHRlcihCb29sZWFuKS5qb2luKFwiL1wiKTtcbn1cblxuZnVuY3Rpb24gZnJvbnRtYXR0ZXJUaXRsZShjb250ZW50OiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKCFjb250ZW50LnN0YXJ0c1dpdGgoXCItLS1cXG5cIikpIHJldHVybiBudWxsO1xuICBjb25zdCBlbmQgPSBjb250ZW50LmluZGV4T2YoXCJcXG4tLS1cIiwgNCk7XG4gIGlmIChlbmQgPT09IC0xKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgcmF3ID0gY29udGVudC5zbGljZSg0LCBlbmQpO1xuICBmb3IgKGNvbnN0IGxpbmUgb2YgcmF3LnNwbGl0KFwiXFxuXCIpKSB7XG4gICAgY29uc3QgbWF0Y2ggPSBsaW5lLm1hdGNoKC9edGl0bGU6XFxzKiguKykkL2kpO1xuICAgIGlmICghbWF0Y2g/LlsxXSkgY29udGludWU7XG4gICAgcmV0dXJuIG1hdGNoWzFdLnRyaW0oKS5yZXBsYWNlKC9eWydcIl18WydcIl0kL2csIFwiXCIpIHx8IG51bGw7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVwbG9hZEF0dGFjaG1lbnRXaXRoUmV0cnkoXG4gIGFwaTogUGljazxQYWdlZGVuQXBpQ2xpZW50LCBcInVwbG9hZEF0dGFjaG1lbnRcIj4sXG4gIGRvY3VtZW50SWQ6IHN0cmluZyxcbiAgbmFtZTogc3RyaW5nLFxuICBieXRlczogQXJyYXlCdWZmZXIsXG4gIG1pbWVUeXBlOiBzdHJpbmcsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgdHJ5IHtcbiAgICBhd2FpdCBhcGkudXBsb2FkQXR0YWNobWVudChkb2N1bWVudElkLCBuYW1lLCBieXRlcywgbWltZVR5cGUpO1xuICB9IGNhdGNoIChmaXJzdEVycm9yKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGFwaS51cGxvYWRBdHRhY2htZW50KGRvY3VtZW50SWQsIG5hbWUsIGJ5dGVzLCBtaW1lVHlwZSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICB0aHJvdyBmaXJzdEVycm9yO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBmb2xkZXJGcm9tQ3JlYXRlKGlkOiBzdHJpbmcsIHBhcmVudEZvbGRlcklkOiBzdHJpbmcgfCBudWxsLCBuYW1lOiBzdHJpbmcsIHNsdWc6IHN0cmluZywgcGF0aDogc3RyaW5nKTogUmVtb3RlRm9sZGVyIHtcbiAgcmV0dXJuIHtcbiAgICBpZCxcbiAgICBwYXJlbnRGb2xkZXJJZCxcbiAgICBuYW1lLFxuICAgIHNsdWcsXG4gICAgcGF0aDogdHJpbVNsYXNoZXMocGF0aCksXG4gICAgcGVybWlzc2lvbjogXCJtYW5hZ2VyXCIsXG4gIH07XG59XG5cbmZ1bmN0aW9uIG1ldGFGcm9tSW1wb3J0ZWRSZW1vdGUocmVtb3RlOiB7IGlkOiBzdHJpbmc7IHBhdGg6IHN0cmluZzsgdGl0bGU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIHwgbnVsbDsgY2hlY2tzdW06IHN0cmluZyB8IG51bGw7IHBlcm1pc3Npb246IFNlcnZlck1ldGFFbnRyeVtcInBlcm1pc3Npb25cIl07IHVwZGF0ZWRBdDogc3RyaW5nIH0sIGxvY2FsUGF0aDogc3RyaW5nKTogU2VydmVyTWV0YUVudHJ5IHtcbiAgaWYgKCFyZW1vdGUudmVyc2lvbiB8fCAhcmVtb3RlLmNoZWNrc3VtKSB0aHJvdyBuZXcgRXJyb3IoXCJJbXBvcnRlZCBkb2N1bWVudCBpcyBtaXNzaW5nIHZlcnNpb24gbWV0YWRhdGEuXCIpO1xuICByZXR1cm4ge1xuICAgIGRvY3VtZW50SWQ6IHJlbW90ZS5pZCxcbiAgICBsb2NhbFBhdGgsXG4gICAgcmVtb3RlUGF0aDogcmVtb3RlLnBhdGgsXG4gICAgdGl0bGU6IHJlbW90ZS50aXRsZSxcbiAgICBiYXNlVmVyc2lvbjogcmVtb3RlLnZlcnNpb24sXG4gICAgY2hlY2tzdW06IHJlbW90ZS5jaGVja3N1bSxcbiAgICBwZXJtaXNzaW9uOiByZW1vdGUucGVybWlzc2lvbixcbiAgICB1cGRhdGVkQXQ6IHJlbW90ZS51cGRhdGVkQXQsXG4gIH07XG59XG5cbmZ1bmN0aW9uIG1pbWVUeXBlRm9yUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBleHQgPSBwYXRoLnNwbGl0KFwiLlwiKS5wb3AoKT8udG9Mb3dlckNhc2UoKTtcbiAgaWYgKGV4dCA9PT0gXCJwbmdcIikgcmV0dXJuIFwiaW1hZ2UvcG5nXCI7XG4gIGlmIChleHQgPT09IFwianBnXCIgfHwgZXh0ID09PSBcImpwZWdcIikgcmV0dXJuIFwiaW1hZ2UvanBlZ1wiO1xuICBpZiAoZXh0ID09PSBcImdpZlwiKSByZXR1cm4gXCJpbWFnZS9naWZcIjtcbiAgaWYgKGV4dCA9PT0gXCJ3ZWJwXCIpIHJldHVybiBcImltYWdlL3dlYnBcIjtcbiAgaWYgKGV4dCA9PT0gXCJtcDRcIikgcmV0dXJuIFwidmlkZW8vbXA0XCI7XG4gIGlmIChleHQgPT09IFwid2VibVwiKSByZXR1cm4gXCJ2aWRlby93ZWJtXCI7XG4gIGlmIChleHQgPT09IFwibW92XCIpIHJldHVybiBcInZpZGVvL3F1aWNrdGltZVwiO1xuICBpZiAoZXh0ID09PSBcInBkZlwiKSByZXR1cm4gXCJhcHBsaWNhdGlvbi9wZGZcIjtcbiAgcmV0dXJuIFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCI7XG59XG5cbmZ1bmN0aW9uIGRpcm5hbWUocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IG5vcm1hbGl6ZVBhdGgocGF0aCk7XG4gIGNvbnN0IGluZGV4ID0gbm9ybWFsaXplZC5sYXN0SW5kZXhPZihcIi9cIik7XG4gIHJldHVybiBpbmRleCA9PT0gLTEgPyBcIlwiIDogbm9ybWFsaXplZC5zbGljZSgwLCBpbmRleCk7XG59XG5cbmZ1bmN0aW9uIGJhc2VuYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBub3JtYWxpemVQYXRoKHBhdGgpLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbikucG9wKCkgPz8gXCJcIjtcbn1cblxuZnVuY3Rpb24gdHJpbVNsYXNoZXMocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhdGgucmVwbGFjZSgvXlxcLyt8XFwvKyQvZywgXCJcIik7XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxJQUFBQSxtQkFXTzs7O0FDVFAsU0FBUyxXQUFXLFNBQVM7QUFDM0IsT0FBSyxVQUFV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STtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUNQO0FBRU8sSUFBSSxRQUFRO0FBQUEsRUFDakIsSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osSUFBSTtBQUFBLEVBQ0osS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUFBLEVBQ0wsS0FBSztBQUNQO0FBRUEsSUFBSUUsT0FBTSxPQUFPLGFBQWEsZUFBZSxNQUFNLEtBQUssVUFBVSxRQUFRO0FBQzFFLElBQUlD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QUlBLE9BQU07QUFNMUQsSUFBTSxjQUFjLENBQUFBLE9BQUssS0FBS0EsSUFBRyxFQUFFLElBQUksS0FBS0EsSUFBRyxFQUFFLElBQUlBLE9BQU07QUFVM0QsSUFBTSxJQUFJLElBQUksWUFBWTtBQUFBLEVBQ3hCO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQ3BGO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQ3BGO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQ3BGO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQ3BGO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQ3BGO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQ3BGO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQ3BGO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUN0RixDQUFDO0FBVUQsSUFBTSxRQUFRLElBQUksWUFBWTtBQUFBLEVBQzVCO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUFBLEVBQVk7QUFBQSxFQUFZO0FBQUEsRUFBWTtBQUN0RixDQUFDO0FBSUQsSUFBTSxTQUFO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aEQsU0FBTyxFQUFPLE1BQU0sVUFBVSxFQUFFLE9BQU8sTUFBTSxDQUFDO0FBQ2hEO0FBRUEsU0FBUyxlQUFlLE1BQXNCO0FBQzVDLFFBQU0sV0FBVyxTQUFTLFNBQVMsSUFBSSxFQUFFLFFBQVE7QUFDakQsU0FBTyxXQUFXLEdBQUcsUUFBUTtBQUFBLElBQU87QUFDdEM7IiwKICAibmFtZXMiOiBbImltcG9ydF9vYnNpZGlhbiIsICJmb3VuZCIsICJtYXAiLCAiYiIsICJqIiwgInNpemUiLCAiX0ZyYWdtZW50IiwgImZyb20iLCAidGV4dCIsICJmaXJzdCIsICJsYXN0IiwgImNvcHkiLCAiZm91bmQiLCAiX01hcmsiLCAiXyIsICJfU2xpY2UiLCAic2xpY2UiLCAiX1Jlc29sdmVkUG9zIiwgIm5leHQiLCAiZCIsICJkb2MiLCAiX05vZGUiLCAibWF0Y2giLCAibSIsICJiYXNlIiwgIl9Db250ZW50TWF0Y2giLCAiaSIsICJtaW4iLCAibWF4IiwgInR5cGUiLCAibmZhIiwgImVkZ2UiLCAiZXhwciIsICJub2RlIiwgInN0YXRlcyIsICJkZWZhdWx0cyIsICJuYW1lIiwgIm1hcmsiLCAiRE9NUGFyc2VyIiwgInJ1bGVzIiwgInN0eWxlIiwgIndyYXAiLCAic3BhY2UiLCAiX1N0ZXBNYXAiLCAiZGVsIiwgImZyb20iLCAibWFwIiwgIm0iLCAiaWQiLCAiX1N0ZXBSZXN1bHQiLCAiZG9jIiwgInNsaWNlIiwgIl9BZGRNYXJrU3RlcCIsICJwYXJlbnQiLCAiX1JlbW92ZU1hcmtTdGVwIiwgIl9BZGROb2RlTWFya1N0ZXAiLCAiX1JlbW92ZU5vZGVNYXJrU3RlcCIsICJfUmVwbGFjZVN0ZXAiLCAiX1JlcGxhY2VBcm91bmRTdGVwIiwgIm5leHQiLCAidHIiLCAiZm91bmQiLCAic3R5bGUiLCAiaiIsICJtYXRjaCIsICJkIiwgImJhc2UiLCAiaW5kZXgiLCAiam9pbmFibGUiLCAiYiIsICJmaXJzdCIsICJ3cmFwIiwgIm1hdGNoZXMiLCAidHlwZSIsICJjbG9zZSIsICJsYXN0IiwgIl9BdHRyU3RlcCIsICJfRG9jQXR0clN0ZXAiLCAiVHJhbnNmb3JtRXJyb3IiLCAiX3QiLCAidHIiLCAiZnJvbSIsICJmb3VuZCIsICJkb2MiLCAiaWQiLCAiX1RleHRTZWxlY3Rpb24iLCAiX1RleHRCb29rbWFyayIsICJfTm9kZVNlbGVjdGlvbiIsICJfTm9kZUJvb2ttYXJrIiwgIl9BbGxTZWxlY3Rpb24iLCAidGV4dCIsICJsYXN0IiwgIm1hcCIsICJzbGljZSIsICJfIiwgImoiLCAibSIsICJ0ciIsICJlbXB0eSIsICJsaWZ0IiwgIm1hdGNoIiwgImQiLCAiZmlyc3QiLCAibWF0Y2giLCAid3JhcCIsICJ0ciIsICJzZXRCbG9ja1R5cGUiLCAiZnJvbSIsICJ0ciIsICJkb2MiLCAid3JhcCIsICJmb3VuZCIsICJmaXJzdCIsICJ0ciIsICJzbGljZSIsICJmcm9tIiwgImRvYyIsICJ4IiwgInkiLCAiXyIsICJtYWMiLCAiZWxlbWVudCIsICJqIiwgIm5leHQiLCAiZmlyc3QiLCAic2l6ZSIsICJpIiwgImVudGVyIiwgImJhc2UiLCAidGV4dCIsICJ3cmFwIiwgImNvcHkiLCAic3BlYyIsICJtIiwgImIiLCAiZm91bmQiLCAicHJlTWF0Y2giLCAibWF0Y2hlcyIsICJkIiwgIm1pbiIsICJtYXgiLCAiZW1wdHkiLCAidHIiLCAic2xpY2UiLCAiRE9NUGFyc2VyIiwgImRvbSIsICJtYXRjaCIsICJldmVudCIsICJoYW5kbGVycyIsICJzZWwiLCAiY3V0IiwgImlzTm9kZSIsICJOb2RlVHlwZSIsICJvbGRPZmZzZXQiLCAibmV4dENlbGwiLCAiZmluZCIsICJhbmNob3IiLCAiZnJvbSIsICJmb3VuZCIsICJwcm9wIiwgInRleHQiLCAic2xpY2UiLCAidHIiLCAiYiIsICJfIiwgIm1hYyIsICJpZSIsICJtYWMiLCAid2luZG93cyIsICJzaGlmdCIsICJtYXAiLCAiY29weSIsICJkb2MiLCAidHIiLCAiY29tbWFuZCIsICJhcmdzIiwgInJ1biIsICJfX2V4cG9ydCIsICJjcmVhdGVQYXJhZ3JhcGhOZWFyIiwgImRlbGV0ZVJhbmdlIiwgImRlbGV0ZVNlbGVjdGlvbiIsICJleGl0Q29kZSIsICJqb2luQmFja3dhcmQiLCAiam9pbkRvd24iLCAiam9pbkZvcndhcmQiLCAiam9pblRleHRibG9ja0JhY2t3YXJkIiwgImpvaW5UZXh0YmxvY2tGb3J3YXJkIiwgImpvaW5VcCIsICJsaWZ0IiwgImxpZnRFbXB0eUJsb2NrIiwgImxpZnRMaXN0SXRlbSIsICJuZXdsaW5lSW5Db2RlIiwgInNlbGVjdEFsbCIsICJzZWxlY3ROb2RlQmFja3dhcmQiLCAic2VsZWN0Tm9kZUZvcndhcmQiLCAic2VsZWN0UGFyZW50Tm9kZSIsICJzZWxlY3RUZXh0YmxvY2tFbmQiLCAic2VsZWN0VGV4dGJsb2NrU3RhcnQiLCAic2lua0xpc3RJdGVtIiwgInNwbGl0QmxvY2siLCAid3JhcEluIiwgIndyYXBJbkxpc3QiLCAiZnJvbSIsICJrZXlzIiwgIm1hcmsiLCAiVGV4dFNlbGVjdGlvbiIsICJtaW4iLCAibWF4IiwgIkRPTVBhcnNlciIsICJzZWxlY3Rpb25Ub0luc2VydGlvbkVuZCIsICJsYXN0IiwgIm1hcCIsICJTZWxlY3Rpb24iLCAidiIsICJGcmFnbWVudCIsICJ0ZXh0IiwgImlzVGV4dFNlbGVjdGlvbiIsICJoYXNDb250ZW50IiwgImpvaW5Qb2ludCIsICJvcmlnaW5hbENvbW1hbmQiLCAibm9ybWFsaXplS2V5TmFtZSIsICJzaGlmdCIsICJlbXB0eSIsICJpc0FjdGl2ZSIsICJkb2N1bWVudCIsICJkZWZhdWx0QmxvY2tBdCIsICJtYXRjaCIsICJsZW5ndGgiLCAiU2NoZW1hIiwgImIiLCAiZnJvbSIsICJ0ZXh0IiwgImdldFRleHQiLCAiZnJvbSIsICJub2RlIiwgIl8iLCAiZnJvbSIsICJkb2MiLCAiZW1wdHkiLCAicmFuZ2UiLCAicGFyZW50Tm9kZSIsICJ0ciIsICJlbXB0eSIsICJmcm9tIiwgInNldEJsb2NrVHlwZSIsICJkb2MiLCAiTm9kZVNlbGVjdGlvbiIsICJUZXh0U2VsZWN0aW9uIiwgInNpbmtMaXN0SXRlbSIsICJzcGxpdEJsb2NrIiwgImRlZmF1bHRCbG9ja0F0IiwgImZpcnN0IiwgIndyYXAiLCAiRnJhZ21lbnQiLCAiZCIsICJuZXdOZXh0VHlwZUF0dHJpYnV0ZXMiLCAibmV4dFR5cGUiLCAiY2FuU3BsaXQiLCAiaXNBY3RpdmUiLCAiaiIsICJ3cmFwSW4iLCAid3JhcEluTGlzdCIsICJhcmdzIiwgInRleHQiLCAiZmluZCIsICJydWxlcyIsICJtYXRjaCIsICJNYXJrIiwgIm0iLCAicmVtb3ZlTWFyayIsICJtYXRjaGVzIiwgInJ1biIsICJoYW5kbGVycyIsICJfZSIsICJQbHVnaW4iLCAidG8iLCAibmV4dCIsICJfX2V4cG9ydCIsICJiIiwgIl9hIiwgIl9iIiwgIl9jIiwgIlBsdWdpbktleSIsICJfIiwgInNsaWNlIiwgImhhbmRsZUJhY2tzcGFjZSIsICJTZWxlY3Rpb24iLCAiaGFuZGxlRGVsZXRlIiwgImlzRW1wdHkiLCAiZWxlbWVudCIsICJpc0Jsb2NrIiwgImlzSW5saW5lIiwgInN0eWxlIiwgImZvY3VzIiwgImJsdXIiLCAiZ2V0VGV4dCIsICJtYXRjaCIsICJ0ciIsICJjYW5Kb2luIiwgIk5vZGVTZWxlY3Rpb24iLCAibWF0Y2giLCAiX19leHBvcnQiLCAibWF0Y2giLCAicGFyc2VBdHRyaWJ1dGVzIiwgInNlcmlhbGl6ZUF0dHJpYnV0ZXMiLCAiaCIsICJsIiwgIm5leHRJbmRlbnQiLCAiZG9jIiwgInRyIiwgImZyb20iLCAiTm9kZSIsICJtYXRjaCIsICJ0ciIsICJmaW5kRGlmZlN0YXJ0IiwgImIiLCAiaiIsICJmaW5kRGlmZkVuZCIsICJzaXplIiwgIkZyYWdtZW50IiwgImZyb20iLCAidGV4dCIsICJmaXJzdCIsICJsYXN0IiwgImNvcHkiLCAiZm91bmQiLCAicmV0SW5kZXgiLCAiY29tcGFyZURlZXAiLCAiTWFyayIsICJfTWFyayIsICJfIiwgIlJlcGxhY2VFcnJvciIsICJTbGljZSIsICJpbnNlcnRJbnRvIiwgInJlbW92ZVJhbmdlIiwgInJlcGxhY2UiLCAic2xpY2UiLCAicmVwbGFjZU91dGVyIiwgImNsb3NlIiwgInJlcGxhY2VUd29XYXkiLCAicHJlcGFyZVNsaWNlRm9yUmVwbGFjZSIsICJyZXBsYWNlVGhyZWVXYXkiLCAiY2hlY2tKb2luIiwgImpvaW5hYmxlIiwgImFkZE5vZGUiLCAiYWRkUmFuZ2UiLCAiUmVzb2x2ZWRQb3MiLCAibmV4dCIsICJkIiwgIk5vZGVSYW5nZSIsICJkb2MiLCAicmVzb2x2ZUNhY2hlIiwgIlJlc29sdmVDYWNoZSIsICJyZXNvbHZlQ2FjaGVTaXplIiwgImVtcHR5QXR0cnMiLCAiTm9kZSIsICJfTm9kZSIsICJ3cmFwTWFya3MiLCAibWF0Y2giLCAibSIsICJDb250ZW50TWF0Y2giLCAiVG9rZW5TdHJlYW0iLCAicGFyc2VFeHByIiwgImRmYSIsICJuZmEiLCAiY2hlY2tGb3JEZWFkRW5kcyIsICJpIiwgInBhcnNlRXhwclNlcSIsICJwYXJzZUV4cHJTdWJzY3JpcHQiLCAicGFyc2VFeHByQXRvbSIsICJwYXJzZUV4cHJSYW5nZSIsICJwYXJzZU51bSIsICJtaW4iLCAibWF4IiwgInJlc29sdmVOYW1lIiwgInR5cGUiLCAiZWRnZSIsICJleHByIiwgImNtcCIsICJudWxsRnJvbSIsICJub2RlIiwgInN0YXRlcyIsICJsb3dlcjE2IiwgImZhY3RvcjE2IiwgIm1ha2VSZWNvdmVyIiwgInJlY292ZXJJbmRleCIsICJyZWNvdmVyT2Zmc2V0IiwgIkRFTF9CRUZPUkUiLCAiREVMX0FGVEVSIiwgIkRFTF9BQ1JPU1MiLCAiREVMX1NJREUiLCAiTWFwUmVzdWx0IiwgIlN0ZXBNYXAiLCAiZGVsIiwgInN0ZXBzQnlJRCIsICJTdGVwIiwgImlkIiwgIlN0ZXBSZXN1bHQiLCAibWFwRnJhZ21lbnQiLCAiQWRkTWFya1N0ZXAiLCAicGFyZW50IiwgIlJlbW92ZU1hcmtTdGVwIiwgIkFkZE5vZGVNYXJrU3RlcCIsICJSZW1vdmVOb2RlTWFya1N0ZXAiLCAiUmVwbGFjZVN0ZXAiLCAiY29udGVudEJldHdlZW4iLCAiUmVwbGFjZUFyb3VuZFN0ZXAiLCAiQXR0clN0ZXAiLCAiRG9jQXR0clN0ZXAiLCAiVHJhbnNmb3JtRXJyb3IiLCAiY2xhc3Nlc0J5SWQiLCAiU2VsZWN0aW9uIiwgIlNlbGVjdGlvblJhbmdlIiwgInRyIiwgInNlbGVjdGlvblRvSW5zZXJ0aW9uRW5kIiwgIlRleHRTZWxlY3Rpb24iLCAiZmluZFNlbGVjdGlvbkluIiwgIkFsbFNlbGVjdGlvbiIsICJ3YXJuZWRBYm91dFRleHRTZWxlY3Rpb24iLCAiY2hlY2tUZXh0U2VsZWN0aW9uIiwgIlRleHRCb29rbWFyayIsICJOb2RlU2VsZWN0aW9uIiwgIk5vZGVCb29rbWFyayIsICJBbGxCb29rbWFyayIsICJtYXAiLCAiYmluZCIsICJGaWVsZERlc2MiLCAiYmFzZUZpZWxkcyIsICJoIiwgIk1hcmsiLCAiaCIsICJ0ZXh0IiwgIm1hdGNoIiwgIm1hdGNoZXMiLCAiTWFyayIsICJoIiwgImVsZW1lbnQiLCAiaCIsICJlbXB0eSIsICJ0ciIsICJmcm9tIiwgInRleHQiLCAiX2EiLCAiZG9jIiwgIm1hdGNoIiwgImgiLCAidHIiLCAiaCIsICJ0ciIsICJzdGFySW5wdXRSZWdleCIsICJzdGFyUGFzdGVSZWdleCIsICJ1bmRlcnNjb3JlSW5wdXRSZWdleCIsICJ1bmRlcnNjb3JlUGFzdGVSZWdleCIsICJNYXJrIiwgImgiLCAibmV4dFN0YXRlIiwgIm5leHQiLCAiTmwiLCAiYiIsICJmaXJzdCIsICJuZXh0IiwgInNjaGVtZSIsICJydW4iLCAic2NoZW1lIiwgInJ1biIsICJ0ciIsICJQbHVnaW4iLCAiUGx1Z2luS2V5IiwgInJvb3QiLCAic2xpY2UiLCAiZW1wdHkiLCAiTWFyayIsICJlbGVtZW50IiwgImgiLCAidGV4dCIsICJmaW5kIiwgIm1hdGNoIiwgImgiLCAidHIiLCAiaGFuZGxlRGVsZXRlIiwgInRleHQiLCAiTm9kZSIsICJtZXJnZUF0dHJpYnV0ZXMiLCAiX19leHBvcnQiLCAiaGFuZGxlQmFja3NwYWNlIiwgImlzTm9kZUFjdGl2ZSIsICJnZXROb2RlVHlwZSIsICJFeHRlbnNpb24iLCAibWF0Y2giLCAiTGlzdEl0ZW1OYW1lIiwgIlRleHRTdHlsZU5hbWUiLCAiZWxlbWVudCIsICJ3cmFwcGluZ0lucHV0UnVsZSIsICJpbnB1dFJlZ2V4IiwgInJlbmRlck5lc3RlZE1hcmtkb3duQ29udGVudCIsICJoIiwgImlucHV0UmVnZXgiLCAiTWFyayIsICJzdHlsZSIsICJoIiwgIlRleHQiLCAiTWFyayIsICJzdHlsZSIsICJtYXRjaCIsICJpc0Jsb2NrIiwgInJlY3QiLCAidGltZW91dCIsICJkb2MiLCAibmV4dCIsICJkIiwgInRyIiwgIlJvcGVTZXF1ZW5jZSIsICJmcm9tIiwgImZvckVhY2giLCAiTGVhZiIsICJBcHBlbmQiLCAiYXBwZW5kSW5uZXIiLCAiZGlzdF9kZWZhdWx0IiwgIm5leHQiLCAibWFwIiwgImZyb20iLCAibGFzdCIsICJkaXN0X2RlZmF1bHQiLCAiaGlzdG9yeSIsICJ0ciIsICJyZWRvIiwgInRyIiwgImNvbW1hbmQiLCAicmVkbyIsICJ0ZXh0IiwgIndvcmQiLCAiZnJvbSIsICJ0ciIsICJFeHRlbnNpb24iLCAiUGx1Z2luIiwgIlBsdWdpbktleSIsICJkb2MiLCAiRGVjb3JhdGlvbiIsICJpc0VtcHR5IiwgIkRlY29yYXRpb25TZXQiLCAic3R5bGUiLCAiZWxlbWVudCIsICJyb290IiwgIngiLCAiU2VsZWN0aW9uIiwgIl8iLCAiVGV4dCIsICJpbmRleF9kZWZhdWx0IiwgImNvcHkiLCAibSIsICJ2IiwgIm1hcCIsICJjcmVhdGUiLCAiZnJvbSIsICJjcmVhdGUiLCAiYXJncyIsICJmcm9tIiwgImIiLCAiaXNOYU4iLCAicGFyc2VJbnQiLCAibWF0Y2giLCAiZCIsICJrZXlzIiwgInYiLCAidiIsICJ2IiwgImNyZWF0ZSIsICJjcmVhdGUiLCAiY3JlYXRlIiwgInYiLCAiYiIsICJrZXlzIiwgImZvckVhY2giLCAibWFwIiwgImtleXMiLCAiZXZlcnkiLCAiYiIsICJhcmdzIiwgImIiLCAibGVuZ3RoIiwgImNyZWF0ZSIsICJtaW4iLCAibWF4IiwgIm1pbiIsICJtYXgiLCAibWluIiwgIm1heCIsICJvbmVPZiIsICJoYXMiLCAiYiIsICJldmVyeSIsICJTY2hlbWEiLCAidiIsICJTY2hlbWEiLCAiZXZlcnkiLCAia2V5cyIsICJ2IiwgImFyZ3MiLCAiU2NoZW1hIiwgInYiLCAiU2NoZW1hIiwgInYiLCAiJGpzb24iLCAiY3JlYXRlIiwgImgiLCAib25lT2YiLCAiZG9jIiwgIm0iLCAibWFwIiwgImRvYyIsICJ0aW1lb3V0IiwgImNyZWF0ZSIsICJjcmVhdGUiLCAiYXJncyIsICJjcmVhdGUiLCAiYXJncyIsICJzdHlsZSIsICJ3YXJuIiwgImNyZWF0ZSIsICJuZXh0IiwgImRlbCIsICJpZCIsICJiIiwgImoiLCAibGVuZ3RoIiwgIm5leHQiLCAiZnJvbSIsICJpIiwgImNyZWF0ZSIsICJmcm9tIiwgImRvYyIsICJpZCIsICJhbnkiLCAiYiIsICJpIiwgIkl0ZW0iLCAiZG9jIiwgImZyb20iLCAiYiIsICJsIiwgImciLCAiaWQiLCAiZG9jIiwgIkl0ZW0iLCAiZG9jIiwgInNuYXBzaG90IiwgImNyZWF0ZSIsICJmaW5kIiwgImlkIiwgIkl0ZW0iLCAiVHJhbnNhY3Rpb24iLCAiZG9jIiwgImNyZWF0ZSIsICJzdHJ1Y3QiLCAiZG9jIiwgImkiLCAiaGFzQ29udGVudCIsICJUcmFuc2FjdGlvbiIsICJ0ciIsICJJdGVtIiwgIndhcm4iLCAiSXRlbSIsICJuZXh0IiwgImNyZWF0ZSIsICJrZXlzIiwgImxvZyIsICJ3YXJuIiwgImIiLCAibSIsICJ5IiwgInNuYXBzaG90IiwgImRvYyIsICJJdGVtIiwgImNyZWF0ZSIsICJsZW5ndGgiLCAic25hcHNob3QiLCAidiIsICJ5IiwgImxlbmd0aCIsICJtYXAiLCAiYiIsICJkb2MiLCAiSXRlbSIsICJ0ZXh0IiwgImNvcHkiLCAicm9vdCIsICJmaXJzdCIsICJlbGVtZW50IiwgIm5leHQiLCAiZnJvbSIsICJjcmVhdGUiLCAiZm9yRWFjaCIsICJrZXlzIiwgImoiLCAiaWQiLCAiaXRlbSIsICJkb2MiLCAicmVtb3ZlIiwgImciLCAiYiIsICJ3IiwgInNoaWZ0IiwgIngiLCAiSCIsICJXIiwgImIiLCAiZCIsICJnIiwgImgiLCAidHQiLCAiaiIsICJpIiwgImRpZ2VzdCIsICJOIiwgImlzVmlzaWJsZSIsICJzbmFwc2hvdCIsICJjcmVhdGUiLCAidHIiLCAiZG9jIiwgImlkIiwgIl8iLCAiSXRlbSIsICJ0ZXh0IiwgImlzT2JqZWN0IiwgImVxdWFsQXR0cnMiLCAia2V5cyIsICJsIiwgImQiLCAiZXZlcnkiLCAicmVtb3ZlIiwgInV0aWxzLmhhc2hPZkpTT04iLCAieSIsICJjcmVhdGVSZWxhdGl2ZVBvc2l0aW9uIiwgInkiLCAidW5kbyIsICJyZWRvIiwgIkl0ZW0iLCAiZG9jIiwgInRyIiwgInVuZG9NYW5hZ2VyIiwgInlTeW5jUGx1Z2luS2V5IiwgImNyZWF0ZU1hcHBhYmxlUG9zaXRpb24iLCAiZ2V0VXBkYXRlZFBvc2l0aW9uIiwgImFic29sdXRlUG9zaXRpb24iLCAidHIiLCAidW5kbyIsICJyZWRvIiwgImluZGV4X2RlZmF1bHQiLCAiaW5kZXhfZGVmYXVsdCIsICJpbmRleF9kZWZhdWx0IiwgImluZGV4X2RlZmF1bHQiLCAicmVhZEZyb21DYWNoZTogKGtleTogTm9kZSkgPT4gVGFibGVNYXAgfCB1bmRlZmluZWQiLCAiYWRkVG9DYWNoZTogKGtleTogTm9kZSwgdmFsdWU6IFRhYmxlTWFwKSA9PiBUYWJsZU1hcCIsICJjYWNoZTogKE5vZGUgfCBUYWJsZU1hcClbXSIsICJ3aWR0aDogbnVtYmVyIiwgImhlaWdodDogbnVtYmVyIiwgIm1hcDogbnVtYmVyW10iLCAicHJvYmxlbXM6IFByb2JsZW1bXSB8IG51bGwiLCAibWFwIiwgImoiLCAiYiIsICJyZXN1bHQ6IG51bWJlcltdIiwgInNlZW46IFJlY29yZDxudW1iZXIsIGJvb2xlYW4+IiwgImNvbFdpZHRoczogQ29sV2lkdGhzIiwgImgiLCAidyIsICJjZWxsIiwgInJlc3VsdDogQ29sV2lkdGhzIiwgImQiLCAibWFwIiwgInJlc3VsdDogQ2VsbEF0dHJzIiwgInciLCAiQ2VsbFNlbGVjdGlvbiIsICJkb2MiLCAiY2VsbCIsICJmcm9tIiwgInNlZW46IFJlY29yZDxudW1iZXIsIGJvb2xlYW4+IiwgInRyIiwgIkNlbGxCb29rbWFyayIsICJhbmNob3I6IG51bWJlciIsICJoZWFkOiBudW1iZXIiLCAiY2VsbHM6IERlY29yYXRpb25bXSIsICJkIiwgImZyb21DZWxsQm91bmRhcnlOb2RlOiBOb2RlIHwgdW5kZWZpbmVkIiwgInRvQ2VsbEJvdW5kYXJ5Tm9kZTogTm9kZSB8IHVuZGVmaW5lZCIsICJub3JtYWxpemU6IFNlbGVjdGlvbiB8IHVuZGVmaW5lZCIsICJyb2xlOiBzdHJpbmcgfCB1bmRlZmluZWQiLCAibm9ybWFsaXplIiwgImoiLCAidHI6IFRyYW5zYWN0aW9uIHwgdW5kZWZpbmVkIiwgIm11c3RBZGQ6IG51bWJlcltdIiwgImZpcnN0IiwgImxhc3QiLCAicm9sZTogVGFibGVSb2xlIiwgIm5vZGVzOiBOb2RlW10iLCAibWFwIiwgInRyIiwgInJlZkNvbHVtbjogbnVtYmVyIHwgbnVsbCIsICJjZWxsIiwgInJlZlJvdzogbnVtYmVyIHwgbnVsbCIsICJjb3B5IiwgImlzRW1wdHkiLCAic2VlbjogUmVjb3JkPG51bWJlciwgYm9vbGVhbj4iLCAibWVyZ2VkUG9zOiBudW1iZXIgfCB1bmRlZmluZWQiLCAibWVyZ2VkQ2VsbDogTm9kZSB8IHVuZGVmaW5lZCIsICJjZWxsTm9kZTogTm9kZSB8IG51bGwgfCB1bmRlZmluZWQiLCAiY2VsbFBvczogbnVtYmVyIHwgdW5kZWZpbmVkIiwgInRvZ2dsZUhlYWRlclJvdzogQ29tbWFuZCIsICJ0b2dnbGVIZWFkZXJDb2x1bW46IENvbW1hbmQiLCAidG9nZ2xlSGVhZGVyQ2VsbDogQ29tbWFuZCIsICJkIiwgInNsaWNlIiwgImZpcnN0IiwgIndpZHRoczogQ29sV2lkdGhzIiwgImoiLCAiZW1wdHkiLCAiYWRkZWQ6IG51bWJlcltdIiwgIm5ld1Jvd3M6IEZyYWdtZW50W10iLCAiY2VsbCIsICJ0ciIsICJtYXAiLCAiY2VsbHM6IE5vZGVbXSIsICJhZGQ6IE5vZGUiLCAic3RhcnQiLCAiZm91bmQiLCAiZnJvbSIsICJoYW5kbGVLZXlEb3duIiwgImFycm93IiwgImNlbGxTZWw6IENlbGxTZWxlY3Rpb24iLCAiaGFuZGxlVHJpcGxlQ2xpY2siLCAiZG9jIiwgIl8iLCAiaGFuZGxlTW91c2VEb3duIiwgIiRhbmNob3IiLCAiZCIsICJkaXJTdHI6ICd1cCcgfCAnZG93bicgfCAnbGVmdCcgfCAncmlnaHQnIiwgIm5vZGU6IE5vZGUiLCAiZGVmYXVsdENlbGxNaW5XaWR0aDogbnVtYmVyIiwgImNvbCIsICJSZXNpemVTdGF0ZSIsICJhY3RpdmVIYW5kbGU6IG51bWJlciIsICJkcmFnZ2luZzogRHJhZ2dpbmcgfCBmYWxzZSIsICJwbHVnaW5TdGF0ZSIsICJldmVudCIsICJkb206IE5vZGUgfCBudWxsIiwgImVsZW1lbnQiLCAiTm9kZSIsICJtZXJnZUF0dHJpYnV0ZXMiLCAiaiIsICJUYWJsZVZpZXciLCAiY2VsbCIsICJoIiwgInRleHQiLCAibWF4IiwgIl9hIiwgIl8iLCAidyIsICJ0ciIsICJDZWxsU2VsZWN0aW9uIiwgImluZGV4X2RlZmF1bHQiLCAiaW5kZXhfZGVmYXVsdCIsICJpbmRleF9kZWZhdWx0IiwgIl9nZXREZWZhdWx0cyIsICJfZGVmYXVsdHMiLCAiY2hhbmdlRGVmYXVsdHMiLCAibmV3RGVmYXVsdHMiLCAibm9vcFRlc3QiLCAiY2FjaGVkSW5kZW50UmVnZXgiLCAiY3JlYXRlUmVnZXgiLCAiY2FjaGUiLCAiaW5kZW50IiwgImNhY2hlSW5kZXgiLCAicmVnZXgiLCAiZWRpdCIsICJvcHQiLCAic291cmNlIiwgIm9iaiIsICJuYW1lIiwgInZhbCIsICJ2YWxTb3VyY2UiLCAib3RoZXIiLCAic3VwcG9ydHNMb29rYmVoaW5kIiwgImEiLCAiYnVsbCIsICJuZXdsaW5lIiwgImJsb2NrQ29kZSIsICJmZW5jZXMiLCAiaHIiLCAiaGVhZGluZyIsICJidWxsZXQiLCAibGhlYWRpbmdDb3JlIiwgImxoZWFkaW5nIiwgImxoZWFkaW5nR2ZtIiwgIl9wYXJhZ3JhcGgiLCAiYmxvY2tUZXh0IiwgIl9ibG9ja0xhYmVsIiwgImRlZiIsICJsaXN0IiwgIl90YWciLCAiX2NvbW1lbnQiLCAiaHRtbCIsICJwYXJhZ3JhcGgiLCAiYmxvY2txdW90ZSIsICJibG9ja05vcm1hbCIsICJnZm1UYWJsZSIsICJibG9ja0dmbSIsICJibG9ja1BlZGFudGljIiwgImVzY2FwZSIsICJpbmxpbmVDb2RlIiwgImJyIiwgImlubGluZVRleHQiLCAiX3B1bmN0dWF0aW9uIiwgIl9wdW5jdHVhdGlvbk9yU3BhY2UiLCAiX25vdFB1bmN0dWF0aW9uT3JTcGFjZSIsICJwdW5jdHVhdGlvbiIsICJfcHVuY3R1YXRpb25HZm1TdHJvbmdFbSIsICJfcHVuY3R1YXRpb25PclNwYWNlR2ZtU3Ryb25nRW0iLCAiX25vdFB1bmN0dWF0aW9uT3JTcGFjZUdmbVN0cm9uZ0VtIiwgImJsb2NrU2tpcCIsICJlbVN0cm9uZ0xEZWxpbUNvcmUiLCAiZW1TdHJvbmdMRGVsaW0iLCAiZW1TdHJvbmdMRGVsaW1HZm0iLCAiZW1TdHJvbmdSRGVsaW1Bc3RDb3JlIiwgImVtU3Ryb25nUkRlbGltQXN0IiwgImVtU3Ryb25nUkRlbGltQXN0R2ZtIiwgImVtU3Ryb25nUkRlbGltVW5kIiwgImRlbExEZWxpbSIsICJkZWxSRGVsaW1Db3JlIiwgImRlbFJEZWxpbSIsICJhbnlQdW5jdHVhdGlvbiIsICJhdXRvbGluayIsICJfaW5saW5lQ29tbWVudCIsICJ0YWciLCAiX2lubGluZUxhYmVsIiwgImxpbmsiLCAicmVmbGluayIsICJub2xpbmsiLCAicmVmbGlua1NlYXJjaCIsICJfY2FzZUluc2Vuc2l0aXZlUHJvdG9jb2wiLCAiaW5saW5lTm9ybWFsIiwgImlubGluZVBlZGFudGljIiwgImlubGluZUdmbSIsICJpbmxpbmVCcmVha3MiLCAiYmxvY2siLCAiaW5saW5lIiwgImVzY2FwZVJlcGxhY2VtZW50cyIsICJnZXRFc2NhcGVSZXBsYWNlbWVudCIsICJjaCIsICJlc2NhcGVIdG1sRW50aXRpZXMiLCAiZW5jb2RlIiwgImNsZWFuVXJsIiwgImhyZWYiLCAic3BsaXRDZWxscyIsICJ0YWJsZVJvdyIsICJjb3VudCIsICJyb3ciLCAibWF0Y2giLCAib2Zmc2V0IiwgInN0ciIsICJlc2NhcGVkIiwgImN1cnIiLCAiY2VsbHMiLCAiaSIsICJydHJpbSIsICJjIiwgImludmVydCIsICJsIiwgInN1ZmZMZW4iLCAiY3VyckNoYXIiLCAidHJpbVRyYWlsaW5nQmxhbmtMaW5lcyIsICJsaW5lcyIsICJlbmQiLCAiZmluZENsb3NpbmdCcmFja2V0IiwgImIiLCAibGV2ZWwiLCAiZXhwYW5kVGFicyIsICJsaW5lIiwgImNvbCIsICJleHBhbmRlZCIsICJjaGFyIiwgImFkZGVkIiwgIm91dHB1dExpbmsiLCAiY2FwIiwgInJhdyIsICJsZXhlciIsICJydWxlcyIsICJ0aXRsZSIsICJ0ZXh0IiwgInRva2VuIiwgImluZGVudENvZGVDb21wZW5zYXRpb24iLCAibWF0Y2hJbmRlbnRUb0NvZGUiLCAiaW5kZW50VG9Db2RlIiwgIm5vZGUiLCAibWF0Y2hJbmRlbnRJbk5vZGUiLCAiaW5kZW50SW5Ob2RlIiwgIl9Ub2tlbml6ZXIiLCAib3B0aW9ucyIsICJzcmMiLCAidHJpbW1lZCIsICJ0b2tlbnMiLCAiaW5CbG9ja3F1b3RlIiwgImN1cnJlbnRMaW5lcyIsICJjdXJyZW50UmF3IiwgImN1cnJlbnRUZXh0IiwgInRvcCIsICJsYXN0VG9rZW4iLCAib2xkVG9rZW4iLCAibmV3VGV4dCIsICJuZXdUb2tlbiIsICJpc29yZGVyZWQiLCAiaXRlbVJlZ2V4IiwgImVuZHNXaXRoQmxhbmtMaW5lIiwgImVuZEVhcmx5IiwgIml0ZW1Db250ZW50cyIsICJuZXh0TGluZSIsICJibGFua0xpbmUiLCAibmV4dEJ1bGxldFJlZ2V4IiwgImhyUmVnZXgiLCAiZmVuY2VzQmVnaW5SZWdleCIsICJoZWFkaW5nQmVnaW5SZWdleCIsICJodG1sQmVnaW5SZWdleCIsICJibG9ja3F1b3RlQmVnaW5SZWdleCIsICJyYXdMaW5lIiwgIm5leHRMaW5lV2l0aG91dFRhYnMiLCAibGFzdEl0ZW0iLCAiaXRlbSIsICJpdGVtVG9rZW4iLCAidGFza1JhdyIsICJjaGVja2JveFRva2VuIiwgInNwYWNlcnMiLCAidCIsICJoYXNNdWx0aXBsZUxpbmVCcmVha3MiLCAiaGVhZGVycyIsICJhbGlnbnMiLCAicm93cyIsICJhbGlnbiIsICJjZWxsIiwgInRyaW1tZWRVcmwiLCAicnRyaW1TbGFzaCIsICJsYXN0UGFyZW5JbmRleCIsICJsaW5rTGVuIiwgImxpbmtzIiwgImxpbmtTdHJpbmciLCAibWFza2VkU3JjIiwgInByZXZDaGFyIiwgImxMZW5ndGgiLCAickRlbGltIiwgInJMZW5ndGgiLCAiZGVsaW1Ub3RhbCIsICJtaWREZWxpbVRvdGFsIiwgImVuZFJlZyIsICJsYXN0Q2hhckxlbmd0aCIsICJoYXNOb25TcGFjZUNoYXJzIiwgImhhc1NwYWNlQ2hhcnNPbkJvdGhFbmRzIiwgInByZXZDYXBaZXJvIiwgIl9MZXhlciIsICJfX0xleGVyIiwgIm5leHQiLCAibGFzdFBhcmFncmFwaENsaXBwZWQiLCAic3JjTGVuZ3RoIiwgImV4dFRva2VuaXplciIsICJjdXRTcmMiLCAic3RhcnRJbmRleCIsICJ0ZW1wU3JjIiwgInRlbXBTdGFydCIsICJnZXRTdGFydEluZGV4IiwgImtlZXBQcmV2Q2hhciIsICJieXRlIiwgImVyck1zZyIsICJfUmVuZGVyZXIiLCAibGFuZyIsICJsYW5nU3RyaW5nIiwgImNvZGUiLCAiZGVwdGgiLCAib3JkZXJlZCIsICJzdGFydCIsICJib2R5IiwgImoiLCAidHlwZSIsICJzdGFydEF0dHIiLCAiY2hlY2tlZCIsICJoZWFkZXIiLCAiayIsICJjb250ZW50IiwgImNsZWFuSHJlZiIsICJvdXQiLCAiX1RleHRSZW5kZXJlciIsICJfUGFyc2VyIiwgIl9fUGFyc2VyIiwgImFueVRva2VuIiwgImdlbmVyaWNUb2tlbiIsICJyZXQiLCAicmVuZGVyZXIiLCAiX0hvb2tzIiwgIm1hcmtkb3duIiwgIk1hcmtlZCIsICJhcmdzIiwgImNhbGxiYWNrIiwgInZhbHVlcyIsICJ0YWJsZVRva2VuIiwgImxpc3RUb2tlbiIsICJjaGlsZFRva2VucyIsICJleHRlbnNpb25zIiwgInBhY2siLCAib3B0cyIsICJleHQiLCAicHJldlJlbmRlcmVyIiwgImV4dExldmVsIiwgInByb3AiLCAicmVuZGVyZXJQcm9wIiwgInJlbmRlcmVyRnVuYyIsICJ0b2tlbml6ZXIiLCAidG9rZW5pemVyUHJvcCIsICJ0b2tlbml6ZXJGdW5jIiwgInByZXZUb2tlbml6ZXIiLCAiaG9va3MiLCAiaG9va3NQcm9wIiwgImhvb2tzRnVuYyIsICJwcmV2SG9vayIsICJhcmciLCAid2Fsa1Rva2VucyIsICJwYWNrV2Fsa3Rva2VucyIsICJibG9ja1R5cGUiLCAib3JpZ09wdCIsICJ0aHJvd0Vycm9yIiwgInByb2Nlc3NlZFNyYyIsICJwcm9jZXNzZWRUb2tlbnMiLCAiZSIsICJzaWxlbnQiLCAiYXN5bmMiLCAibXNnIiwgIm1hcmtlZEluc3RhbmNlIiwgIm1hcmtlZCIsICJzZXRPcHRpb25zIiwgInVzZSIsICJwYXJzZUlubGluZSIsICJwYXJzZXIiLCAiX1BhcnNlciIsICJsZXhlciIsICJfTGV4ZXIiLCAicmVwZWF0IiwgImVzY2FwZSIsICJtYXRjaCIsICJpZCIsICJtYXRjaGVzIiwgInJ1bGVzIiwgImNvbGxhcHNlV2hpdGVzcGFjZSIsICJlbGVtZW50IiwgImlzQmxvY2siLCAiaXNWb2lkIiwgIm5vZGUiLCAidGV4dCIsICJuZXh0IiwgImRvYyIsICJyb290IiwgIk5vZGUiLCAibSIsICJkZWZhdWx0cyIsICJwcm9jZXNzIiwgInBhcmVudE5vZGUiLCAiam9pbiIsICJ3aGl0ZXNwYWNlIiwgImV2ZXJ5IiwgInJ1bGVzIiwgInRyIiwgInBhcmVudE5vZGUiLCAiZWxlbWVudCIsICJjcmVhdGUiLCAiZG9jIiwgInkiLCAicGVybWlzc2lvbkRlbmllZEhhbmRsZXIiLCAicGFyYW1zIiwgIm1hcCIsICJkb2MiLCAicGFyYW1zIiwgImlkIiwgInEiLCAicGFyYW1zIiwgInRleHQiLCAiaW1wb3J0X29ic2lkaWFuIiwgImRpZ2VzdCIsICJkb2MiLCAibWF0Y2giLCAiYmFzZSIsICJiIiwgInJ1biIsICJpbXBvcnRfb2JzaWRpYW4iLCAic2x1Z2lmeSIsICJkb2MiLCAidHJpbVNsYXNoZXMiLCAiZnJvbnRtYXR0ZXJUaXRsZSIsICJtYXRjaCIsICJiIiwgImZvdW5kIiwgImlkIiwgImJhc2UiLCAidGV4dCIsICJkb2MiLCAibWUiLCAiZCIsICJpbmRleF9kZWZhdWx0IiwgInEiLCAiYiIsICJyb290Il0KfQo= diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..3d2bf85 --- /dev/null +++ b/manifest.json @@ -0,0 +1,9 @@ +{ + "id": "pageden", + "name": "Pageden", + "version": "0.1.0", + "minAppVersion": "1.5.0", + "description": "Edit your team's server-owned Markdown documents from Obsidian.", + "author": "ccfiel", + "isDesktopOnly": false +} diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..b470306 --- /dev/null +++ b/styles.css @@ -0,0 +1,78 @@ +.pageden-live-view { + display: flex; + flex-direction: column; + height: 100%; +} + +.pageden-live-header { + align-items: flex-start; + border-bottom: 1px solid var(--background-modifier-border); + display: flex; + gap: 12px; + justify-content: space-between; + padding: 14px 18px 10px; +} + +.pageden-live-header h2 { + margin: 0; +} + +.pageden-live-header p { + color: var(--text-muted); + margin: 4px 0 0; +} + +.pageden-live-status { + background: var(--background-modifier-border); + border-radius: 999px; + color: var(--text-muted); + font-size: 12px; + padding: 4px 9px; + white-space: nowrap; +} + +.pageden-live-toolbar { + align-items: center; + border-bottom: 1px solid var(--background-modifier-border); + display: flex; + flex-wrap: wrap; + gap: 6px; + padding: 8px 18px; +} + +.pageden-live-button { + background: var(--background-secondary); + border: 1px solid var(--background-modifier-border); + border-radius: 6px; + color: var(--text-normal); + font-size: 13px; + min-height: 30px; + padding: 4px 9px; +} + +.pageden-live-button:hover { + background: var(--background-modifier-hover); +} + +.pageden-live-editor { + flex: 1; + overflow: auto; + padding: 18px; +} + +.pageden-live-prosemirror { + margin: 0 auto; + max-width: 760px; + min-height: 100%; + outline: none; +} + +.pageden-live-prosemirror p { + margin: 0.35rem 0; +} + +.pageden-live-prosemirror h1, +.pageden-live-prosemirror h2, +.pageden-live-prosemirror h3 { + margin: 1rem 0 0.45rem; +} diff --git a/versions.json b/versions.json new file mode 100644 index 0000000..708016d --- /dev/null +++ b/versions.json @@ -0,0 +1,3 @@ +{ + "0.1.0": "1.5.0" +}