@cute-dw/core
Version:
This TypeScript library is the main part of a more powerfull package designed for the fast WEB software development. The cornerstone of the library is the **DataStore** class, which might be useful when you need a full control of the data, but do not need
200 lines • 21.3 kB
JavaScript
import { Comparator } from "../../util/Comparator";
import { BinaryTreeNode } from "./BinaryTreeNode";
/**
* In computer science, binary search trees (BST), sometimes called ordered or sorted binary trees,
* are a particular type of container: data structures that store "items" (such as numbers, names etc.)
* in memory. They allow fast lookup, addition and removal of items, and can be used to implement
* either dynamic sets of items, or lookup tables that allow finding an item by its key
* (e.g., finding the phone number of a person by name).
*/
export class BinarySearchTree {
constructor(comparator) {
this.root = null;
this.keyComparator = comparator ?? Comparator.getInstance();
}
clear() {
this.forEach((value, key) => { this.remove(key); });
}
count() {
let nCount = 0;
this.forEach(() => nCount++);
return nCount;
}
height() {
if (this.root) {
return this.root.height;
}
return 0;
}
/**
* Test the tree for empness
* @returns _true_ if the tree doesn't have child nodes, else _false_
*/
isEmpty() {
return (this.root == null);
}
/**
* Inserts a new element to the tree
* @param {K} key
* @param {*} value
* @returns {BinaryTreeNode}
*/
add(key, value) {
if (this.root) {
return this.root.add(key, value);
}
this.root = new BinaryTreeNode(key, value, this.keyComparator);
return this.root;
}
/**
* @param {*} key
* @return {boolean}
*/
contains(key) {
if (this.root)
return this.root.contains(key);
return false;
}
/**
*
* @param key
* @returns
*/
get(key) {
if (this.root) {
const node = this.root.findNode(key);
if (node) {
return node.value;
}
}
return undefined;
}
/**
* @param {K} key
* @returns {Element|undefined}
*/
remove(key) {
if (this.root) {
const removedNode = this.root.remove(key);
if (removedNode) {
return removedNode.value;
}
}
return undefined;
}
/**
* @return {string}
*/
toString() {
if (this.root)
return this.root.toString();
return "";
}
/**
* Executes a `callBack` function for each entry in this dictionary
* @param callBack Function to call on each tree item
* @param thisArg An object to which the `this` keyword can refer in the `callBack` function. If `thisArg` is omitted, undefined is used as the `this` value
*/
forEach(callBack, thisArg) {
if (this.root) {
this.root.traverse().forEach(node => callBack(node.value, node.key, node), thisArg);
}
}
/**
* Gets an array of the children keys for the specified `key`
* @param key
* @returns
*/
childrenKeys(key) {
let keys = [];
const keyNode = this.root?.findNode(key);
if (keyNode) {
keyNode.traverse("PreOrder!").forEach(node => keys.push(node.key), this);
}
return keys.slice(1);
}
/**
* Gets an array of the parent keys for the specified `key`
* @param key
* @returns
*/
parentKeys(key) {
let keys = [];
const keyNode = this.root?.findNode(key);
if (keyNode) {
/*
let it = keyNode.traverseUpIterator();
let res: IteratorResult<BinaryTreeNode<K,V>>;
res = it.next();
while (!res.done) {
keys.push(res.value.key);
res = it.next();
}
*/
for (let node of keyNode.traverseUpIterator()) {
keys.push(node.key);
}
}
return keys.reverse();
}
/** Returns the first (lowest) key currently in this map */
firstKey() {
if (this.root) {
return this.root.findMin().key;
}
return undefined;
}
/** Returns the last (highest) key currently in this map */
lastKey() {
if (this.root) {
return this.root.findMax().key;
}
return undefined;
}
keySet() {
let set = new Set();
this.forEach((value, key) => set.add(key));
return set;
}
keys() {
if (this.root) {
return this.root.traverse().map(node => node.key);
}
return [];
}
values() {
if (this.root) {
return this.root.traverse().map(node => node.value);
}
return [];
}
*[Symbol.iterator]() {
if (this.root) {
yield* this.root.traverseDownIterator();
}
}
print(parentNode = null, indent = 0) {
parentNode = parentNode ?? this.root;
if (parentNode) {
let height;
let output = parentNode.key + "\r\n";
if (parentNode.left) {
height = parentNode.left.height;
output += "LEFT\r\n";
for (let node of parentNode.left.traverseDownIterator("PreOrder!")) {
output += "\t".repeat(height - node.height - 1 + node.parent.direction + node.direction) + node.key + (node.direction == 1 ? "R" : "L") + "\r\n";
}
}
if (parentNode.right) {
height = parentNode.right.height;
output += "RIGHT\r\n";
for (let node of parentNode.right.traverseDownIterator("PreOrder!")) {
output += "\t".repeat(height - node.height - 1 + node.parent.direction + node.direction) + node.key + (node.direction == 1 ? "R" : "L") + "\r\n";
}
}
return output;
}
return "";
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmluYXJ5U2VhcmNoVHJlZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2N1dGUtY29yZS9zcmMvbGliL2NvbGxlY3Rpb25zL3RyZWUvQmluYXJ5U2VhcmNoVHJlZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFbkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRWxEOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxnQkFBZ0I7SUFJM0IsWUFBWSxVQUEwQjtRQUg1QixTQUFJLEdBQWdDLElBQUksQ0FBQztRQUlqRCxJQUFJLENBQUMsYUFBYSxHQUFHLFVBQVUsSUFBSSxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDOUQsQ0FBQztJQUVELEtBQUs7UUFDSCxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFFRCxLQUFLO1FBQ0gsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFFLEVBQUUsQ0FBQSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQzNCLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxNQUFNO1FBQ0osSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ2IsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztTQUN6QjtRQUNELE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUVEOzs7T0FHRztJQUNILE9BQU87UUFDTCxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBQ0Q7Ozs7O09BS0c7SUFD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QUMsb0JBQW9CLENBQUMsV0FBVyxDQUFDLEVBQUU7b0JBQ25FLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxHQUFFLENBQUMsR0FBRSxJQUFJLENBQUMsTUFBTyxDQUFDLFNBQVMsR0FBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUUsQ0FBQyxDQUFBLENBQUMsQ0FBQSxHQUFHLENBQUEsQ0FBQyxDQUFBLEdBQUcsQ0FBQyxHQUFHLE1BQU0sQ0FBQztpQkFDMUk7YUFDRjtZQUNELE9BQU8sTUFBTSxDQUFDO1NBQ2Y7UUFDRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7Q0FFRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBhcmF0b3IgfSBmcm9tIFwiLi4vLi4vdXRpbC9Db21wYXJhdG9yXCI7XHJcbmltcG9ydCB7IEVsZW1lbnQgfSBmcm9tIFwiLi4vQ29sbGVjdGlvblwiO1xyXG5pbXBvcnQgeyBCaW5hcnlUcmVlTm9kZSB9IGZyb20gXCIuL0JpbmFyeVRyZWVOb2RlXCI7XHJcblxyXG4vKipcclxuICogSW4gY29tcHV0ZXIgc2NpZW5jZSwgYmluYXJ5IHNlYXJjaCB0cmVlcyAoQlNUKSwgc29tZXRpbWVzIGNhbGxlZCBvcmRlcmVkIG9yIHNvcnRlZCBiaW5hcnkgdHJlZXMsXHJcbiAqIGFyZSBhIHBhcnRpY3VsYXIgdHlwZSBvZiBjb250YWluZXI6IGRhdGEgc3RydWN0dXJlcyB0aGF0IHN0b3JlIFwiaXRlbXNcIiAoc3VjaCBhcyBudW1iZXJzLCBuYW1lcyBldGMuKVxyXG4gKiBpbiBtZW1vcnkuIFRoZXkgYWxsb3cgZmFzdCBsb29rdXAsIGFkZGl0aW9uIGFuZCByZW1vdmFsIG9mIGl0ZW1zLCBhbmQgY2FuIGJlIHVzZWQgdG8gaW1wbGVtZW50XHJcbiAqIGVpdGhlciBkeW5hbWljIHNldHMgb2YgaXRlbXMsIG9yIGxvb2t1cCB0YWJsZXMgdGhhdCBhbGxvdyBmaW5kaW5nIGFuIGl0ZW0gYnkgaXRzIGtleVxyXG4gKiAoZS5nLiwgZmluZGluZyB0aGUgcGhvbmUgbnVtYmVyIG9mIGEgcGVyc29uIGJ5IG5hbWUpLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEJpbmFyeVNlYXJjaFRyZWU8SywgVj1LPiB7XHJcbiAgcHJvdGVjdGVkIHJvb3Q6IEJpbmFyeVRyZWVOb2RlPEssIFY+IHwgbnVsbCA9IG51bGw7XHJcbiAgcmVhZG9ubHkga2V5Q29tcGFyYXRvcjogQ29tcGFyYXRvcjxLPjtcclxuXHJcbiAgY29uc3RydWN0b3IoY29tcGFyYXRvcj86IENvbXBhcmF0b3I8Sz4pIHtcclxuICAgIHRoaXMua2V5Q29tcGFyYXRvciA9IGNvbXBhcmF0b3IgPz8gQ29tcGFyYXRvci5nZXRJbnN0YW5jZSgpO1xyXG4gIH1cclxuXHJcbiAgY2xlYXIoKTogdm9pZCB7XHJcbiAgICB0aGlzLmZvckVhY2goKHZhbHVlLCBrZXkpID0+IHsgdGhpcy5yZW1vdmUoa2V5KSB9KTtcclxuICB9XHJcblxyXG4gIGNvdW50KCk6IG51bWJlciB7XHJcbiAgICBsZXQgbkNvdW50ID0gMDtcclxuICAgIHRoaXMuZm9yRWFjaCgoKT0+bkNvdW50KyspO1xyXG4gICAgcmV0dXJuIG5Db3VudDtcclxuICB9XHJcblxyXG4gIGhlaWdodCgpOiBudW1iZXIge1xyXG4gICAgaWYgKHRoaXMucm9vdCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5yb290LmhlaWdodDtcclxuICAgIH1cclxuICAgIHJldHVybiAwO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGVzdCB0aGUgdHJlZSBmb3IgZW1wbmVzc1xyXG4gICAqIEByZXR1cm5zIF90cnVlXyBpZiB0aGUgdHJlZSBkb2Vzbid0IGhhdmUgY2hpbGQgbm9kZXMsIGVsc2UgX2ZhbHNlX1xyXG4gICAqL1xyXG4gIGlzRW1wdHkoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gKHRoaXMucm9vdCA9PSBudWxsKTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogSW5zZXJ0cyBhIG5ldyBlbGVtZW50IHRvIHRoZSB0cmVlXHJcbiAgICogQHBhcmFtIHtLfSBrZXlcclxuICAgKiBAcGFyYW0geyp9IHZhbHVlXHJcbiAgICogQHJldHVybnMge0JpbmFyeVRyZWVOb2RlfVxyXG4gICAqL1xyXG4gIGFkZChrZXk6IEssIHZhbHVlOiBFbGVtZW50PFY+KTogQmluYXJ5VHJlZU5vZGU8SywgVj4ge1xyXG4gICAgaWYgKHRoaXMucm9vdCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5yb290LmFkZChrZXksIHZhbHVlKTtcclxuICAgIH1cclxuICAgIHRoaXMucm9vdCA9IG5ldyBCaW5hcnlUcmVlTm9kZTxLLCBWPihrZXksIHZhbHVlLCB0aGlzLmtleUNvbXBhcmF0b3IpO1xyXG4gICAgcmV0dXJuIHRoaXMucm9vdDtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogQHBhcmFtIHsqfSBrZXlcclxuICAgKiBAcmV0dXJuIHtib29sZWFufVxyXG4gICAqL1xyXG4gIGNvbnRhaW5zKGtleTogSyk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKHRoaXMucm9vdClcclxuICAgICAgcmV0dXJuIHRoaXMucm9vdC5jb250YWlucyhrZXkpO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuICAvKipcclxuICAgKlxyXG4gICAqIEBwYXJhbSBrZXlcclxuICAgKiBAcmV0dXJuc1xyXG4gICAqL1xyXG4gIGdldChrZXk6IEspOiBFbGVtZW50PFY+IHwgdW5kZWZpbmVkIHtcclxuICAgIGlmICh0aGlzLnJvb3QpIHtcclxuICAgICAgY29uc3Qgbm9kZSA9IHRoaXMucm9vdC5maW5kTm9kZShrZXkpO1xyXG4gICAgICBpZiAobm9kZSkge1xyXG4gICAgICAgIHJldHVybiBub2RlLnZhbHVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBAcGFyYW0ge0t9IGtleVxyXG4gICAqIEByZXR1cm5zIHtFbGVtZW50fHVuZGVmaW5lZH1cclxuICAgKi9cclxuICByZW1vdmUoa2V5OiBLKTogRWxlbWVudDxWPiB8IHVuZGVmaW5lZCB7XHJcbiAgICBpZiAodGhpcy5yb290KSB7XHJcbiAgICAgIGNvbnN0IHJlbW92ZWROb2RlID0gdGhpcy5yb290LnJlbW92ZShrZXkpO1xyXG4gICAgICBpZiAocmVtb3ZlZE5vZGUpIHtcclxuICAgICAgICByZXR1cm4gcmVtb3ZlZE5vZGUudmFsdWU7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEByZXR1cm4ge3N0cmluZ31cclxuICAgKi9cclxuICB0b1N0cmluZygpOiBzdHJpbmcge1xyXG4gICAgaWYgKHRoaXMucm9vdClcclxuICAgICAgcmV0dXJuIHRoaXMucm9vdC50b1N0cmluZygpO1xyXG4gICAgcmV0dXJuIFwiXCI7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEV4ZWN1dGVzIGEgYGNhbGxCYWNrYCBmdW5jdGlvbiBmb3IgZWFjaCBlbnRyeSBpbiB0aGlzIGRpY3Rpb25hcnlcclxuICAgKiBAcGFyYW0gY2FsbEJhY2sgIEZ1bmN0aW9uIHRvIGNhbGwgb24gZWFjaCB0cmVlIGl0ZW1cclxuICAgKiBAcGFyYW0gdGhpc0FyZyAgIEFuIG9iamVjdCB0byB3aGljaCB0aGUgYHRoaXNgIGtleXdvcmQgY2FuIHJlZmVyIGluIHRoZSBgY2FsbEJhY2tgIGZ1bmN0aW9uLiBJZiBgdGhpc0FyZ2AgaXMgb21pdHRlZCwgdW5kZWZpbmVkIGlzIHVzZWQgYXMgdGhlIGB0aGlzYCB2YWx1ZVxyXG4gICAqL1xyXG4gIGZvckVhY2goY2FsbEJhY2s6ICh2YWx1ZTogRWxlbWVudDxWPiwga2V5OiBLLCBub2RlOiBCaW5hcnlUcmVlTm9kZTxLLCBWPikgPT4gdm9pZCwgdGhpc0FyZz86IGFueSk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMucm9vdCkge1xyXG4gICAgICB0aGlzLnJvb3QudHJhdmVyc2UoKS5mb3JFYWNoKG5vZGUgPT4gY2FsbEJhY2sobm9kZS52YWx1ZSwgbm9kZS5rZXksIG5vZGUpLCB0aGlzQXJnKTtcclxuICAgIH1cclxuICB9XHJcbiAgLyoqXHJcbiAgICogR2V0cyBhbiBhcnJheSBvZiB0aGUgY2hpbGRyZW4ga2V5cyBmb3IgdGhlIHNwZWNpZmllZCBga2V5YFxyXG4gICAqIEBwYXJhbSBrZXlcclxuICAgKiBAcmV0dXJuc1xyXG4gICAqL1xyXG4gIGNoaWxkcmVuS2V5cyhrZXk6IEspOiBBcnJheTxLPiB7XHJcbiAgICBsZXQga2V5czogS1tdID0gW107XHJcbiAgICBjb25zdCBrZXlOb2RlID0gdGhpcy5yb290Py5maW5kTm9kZShrZXkpO1xyXG4gICAgaWYgKGtleU5vZGUpIHtcclxuICAgICAga2V5Tm9kZS50cmF2ZXJzZShcIlByZU9yZGVyIVwiKS5mb3JFYWNoKG5vZGUgPT4ga2V5cy5wdXNoKG5vZGUua2V5KSwgdGhpcyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4ga2V5cy5zbGljZSgxKTtcclxuICB9XHJcbiAgLyoqXHJcbiAgICogR2V0cyBhbiBhcnJheSBvZiB0aGUgcGFyZW50IGtleXMgZm9yIHRoZSBzcGVjaWZpZWQgYGtleWBcclxuICAgKiBAcGFyYW0ga2V5XHJcbiAgICogQHJldHVybnNcclxuICAgKi9cclxuICBwYXJlbnRLZXlzKGtleTogSyk6IEFycmF5PEs+IHtcclxuICAgIGxldCBrZXlzOiBLW10gPSBbXTtcclxuICAgIGNvbnN0IGtleU5vZGUgPSB0aGlzLnJvb3Q/LmZpbmROb2RlKGtleSk7XHJcbiAgICBpZiAoa2V5Tm9kZSkge1xyXG4gICAgICAvKlxyXG4gICAgICBsZXQgaXQgPSBrZXlOb2RlLnRyYXZlcnNlVXBJdGVyYXRvcigpO1xyXG4gICAgICBsZXQgcmVzOiBJdGVyYXRvclJlc3VsdDxCaW5hcnlUcmVlTm9kZTxLLFY+PjtcclxuICAgICAgcmVzID0gaXQubmV4dCgpO1xyXG4gICAgICB3aGlsZSAoIXJlcy5kb25lKSB7XHJcbiAgICAgICAga2V5cy5wdXNoKHJlcy52YWx1ZS5rZXkpO1xyXG4gICAgICAgIHJlcyA9IGl0Lm5leHQoKTtcclxuICAgICAgfVxyXG4gICAgICAqL1xyXG4gICAgICBmb3IgKGxldCBub2RlIG9mIGtleU5vZGUudHJhdmVyc2VVcEl0ZXJhdG9yKCkpIHtcclxuICAgICAgICBrZXlzLnB1c2gobm9kZS5rZXkpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4ga2V5cy5yZXZlcnNlKCk7XHJcbiAgfVxyXG4gIC8qKiBSZXR1cm5zIHRoZSBmaXJzdCAobG93ZXN0KSBrZXkgY3VycmVudGx5IGluIHRoaXMgbWFwICovXHJcbiAgZmlyc3RLZXkoKTogSyB8IHVuZGVmaW5lZCB7XHJcbiAgICBpZiAodGhpcy5yb290KSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnJvb3QuZmluZE1pbigpLmtleTtcclxuICAgIH1cclxuICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgfVxyXG4gIC8qKiBSZXR1cm5zIHRoZSBsYXN0IChoaWdoZXN0KSBrZXkgY3VycmVudGx5IGluIHRoaXMgbWFwICovXHJcbiAgbGFzdEtleSgpOiBLIHwgdW5kZWZpbmVkIHtcclxuICAgIGlmICh0aGlzLnJvb3QpIHtcclxuICAgICAgcmV0dXJuIHRoaXMucm9vdC5maW5kTWF4KCkua2V5O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICB9XHJcblxyXG4gIGtleVNldCgpOiBTZXQ8Sz4ge1xyXG4gICAgbGV0IHNldCA9IG5ldyBTZXQ8Sz4oKTtcclxuICAgIHRoaXMuZm9yRWFjaCgodmFsdWUsIGtleSkgPT4gc2V0LmFkZChrZXkpKTtcclxuICAgIHJldHVybiBzZXQ7XHJcbiAgfVxyXG5cclxuICBrZXlzKCk6IEFycmF5PEs+IHtcclxuICAgIGlmICh0aGlzLnJvb3QpIHtcclxuICAgICAgcmV0dXJuIHRoaXMucm9vdC50cmF2ZXJzZSgpLm1hcChub2RlID0+IG5vZGUua2V5KTtcclxuICAgIH1cclxuICAgIHJldHVybiBbXTtcclxuICB9XHJcblxyXG4gIHZhbHVlcygpOiBBcnJheTxFbGVtZW50PFY+PiB7XHJcbiAgICBpZiAodGhpcy5yb290KSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnJvb3QudHJhdmVyc2UoKS5tYXAobm9kZSA9PiBub2RlLnZhbHVlKTtcclxuICAgIH1cclxuICAgIHJldHVybiBbXTtcclxuICB9XHJcblxyXG4gICpbU3ltYm9sLml0ZXJhdG9yXSgpOiBJdGVyYWJsZUl0ZXJhdG9yPEJpbmFyeVRyZWVOb2RlPEssIFY+PiB7XHJcbiAgICBpZiAodGhpcy5yb290KSB7XHJcbiAgICAgIHlpZWxkKiB0aGlzLnJvb3QudHJhdmVyc2VEb3duSXRlcmF0b3IoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaW50KHBhcmVudE5vZGU6IEJpbmFyeVRyZWVOb2RlPEssIFY+IHwgbnVsbCA9IG51bGwsIGluZGVudDogbnVtYmVyID0gMCk6IHN0cmluZyB7XHJcbiAgICBwYXJlbnROb2RlID0gcGFyZW50Tm9kZSA/PyB0aGlzLnJvb3Q7XHJcbiAgICBpZiAocGFyZW50Tm9kZSkge1xyXG4gICAgICBsZXQgaGVpZ2h0XHJcbiAgICAgIGxldCBvdXRwdXQgPSBwYXJlbnROb2RlLmtleStcIlxcclxcblwiO1xyXG4gICAgICBpZiAocGFyZW50Tm9kZS5sZWZ0KSB7XHJcbiAgICAgICAgaGVpZ2h0ID0gcGFyZW50Tm9kZS5sZWZ0LmhlaWdodDtcclxuICAgICAgICBvdXRwdXQgKz0gXCJMRUZUXFxyXFxuXCI7XHJcbiAgICAgICAgZm9yIChsZXQgbm9kZSBvZiBwYXJlbnROb2RlLmxlZnQudHJhdmVyc2VEb3duSXRlcmF0b3IoXCJQcmVPcmRlciFcIikpIHtcclxuICAgICAgICAgIG91dHB1dCArPSBcIlxcdFwiLnJlcGVhdChoZWlnaHQgLSBub2RlLmhlaWdodCAtMSsgbm9kZS5wYXJlbnQhLmRpcmVjdGlvbiArIG5vZGUuZGlyZWN0aW9uKSArIG5vZGUua2V5ICsgKG5vZGUuZGlyZWN0aW9uPT0xP1wiUlwiOlwiTFwiKSArIFwiXFxyXFxuXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmIChwYXJlbnROb2RlLnJpZ2h0KSB7XHJcbiAgICAgICAgaGVpZ2h0ID0gcGFyZW50Tm9kZS5yaWdodC5oZWlnaHQ7XHJcbiAgICAgICAgb3V0cHV0ICs9IFwiUklHSFRcXHJcXG5cIjtcclxuICAgICAgICBmb3IgKGxldCBub2RlIG9mIHBhcmVudE5vZGUucmlnaHQudHJhdmVyc2VEb3duSXRlcmF0b3IoXCJQcmVPcmRlciFcIikpIHtcclxuICAgICAgICAgIG91dHB1dCArPSBcIlxcdFwiLnJlcGVhdChoZWlnaHQgLSBub2RlLmhlaWdodCAtMSsgbm9kZS5wYXJlbnQhLmRpcmVjdGlvbiArbm9kZS5kaXJlY3Rpb24pICsgbm9kZS5rZXkgKyAobm9kZS5kaXJlY3Rpb249PTE/XCJSXCI6XCJMXCIpICsgXCJcXHJcXG5cIjtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIG91dHB1dDtcclxuICAgIH1cclxuICAgIHJldHVybiBcIlwiO1xyXG4gIH1cclxuXHJcbn1cclxuIl19