@datagrok-libraries/bio 5.20.0 → 5.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "access": "public"
5
5
  },
6
6
  "friendlyName": "Datagrok bio library",
7
- "version": "5.20.0",
7
+ "version": "5.21.0",
8
8
  "description": "",
9
9
  "dependencies": {
10
10
  "@datagrok-libraries/gridext": "^1.3.22",
@@ -29,6 +29,6 @@ export declare class VdRegion {
29
29
  /** Interface for VdRegionsViewer from @datagrok/bio to unbind dependency to Bio package */
30
30
  export interface IVdRegionsViewer extends IViewer {
31
31
  init(): Promise<void>;
32
- setDf(mlbDf: DG.DataFrame, regions: VdRegion[]): Promise<void>;
32
+ setData(mlbDf: DG.DataFrame, regions: VdRegion[]): Promise<void>;
33
33
  }
34
34
  //# sourceMappingURL=vd-regions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vd-regions.d.ts","sourceRoot":"","sources":["vd-regions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAEtC,OAAO,EAAC,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAIzC,oBAAY,YAAY;IACtB,OAAO,YAAY;IACnB,EAAE,cAAc;IAChB,GAAG,QAAQ;CACZ;AAED;;GAEG;AACH,qBAAa,QAAQ;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IAExB;;;;;;;;OAQG;gBACS,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EACxE,iBAAiB,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM;CAQrD;AAED,2FAA2F;AAC3F,MAAM,WAAW,gBAAiB,SAAQ,OAAO;IAC/C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE"}
1
+ {"version":3,"file":"vd-regions.d.ts","sourceRoot":"","sources":["vd-regions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAEtC,OAAO,EAAC,OAAO,EAAC,MAAM,kBAAkB,CAAC;AAIzC,oBAAY,YAAY;IACtB,OAAO,YAAY;IACnB,EAAE,cAAc;IAChB,GAAG,QAAQ;CACZ;AAED;;GAEG;AACH,qBAAa,QAAQ;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IAExB;;;;;;;;OAQG;gBACS,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EACxE,iBAAiB,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM;CAQrD;AAED,2FAA2F;AAC3F,MAAM,WAAW,gBAAiB,SAAQ,OAAO;IAC/C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE"}
package/src/vd-regions.js CHANGED
@@ -27,4 +27,4 @@ export class VdRegion {
27
27
  this.positionEndName = positionEndName;
28
28
  }
29
29
  }
30
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmQtcmVnaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInZkLXJlZ2lvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEscURBQXFEO0FBRXJELE1BQU0sQ0FBTixJQUFZLFlBSVg7QUFKRCxXQUFZLFlBQVk7SUFDdEIsbUNBQW1CLENBQUE7SUFDbkIsZ0NBQWdCLENBQUE7SUFDaEIsMkJBQVcsQ0FBQTtBQUNiLENBQUMsRUFKVyxZQUFZLEtBQVosWUFBWSxRQUl2QjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFFBQVE7SUFRbkI7Ozs7Ozs7O09BUUc7SUFDSCxZQUFZLElBQWtCLEVBQUUsSUFBWSxFQUFFLEtBQWEsRUFBRSxLQUFhLEVBQ3hFLGlCQUF5QixFQUFFLGVBQXVCO1FBQ2xELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQztRQUMzQyxJQUFJLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztJQUN6QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuXG5pbXBvcnQge0lWaWV3ZXJ9IGZyb20gJy4vdmlld2Vycy92aWV3ZXInO1xuXG4vLyBEYXRhIHN0cnVjdHVyZXMgZm9yIFYtRG9tYWluIHJlZ2lvbnMgb2YgYW50aWJvZGllc1xuXG5leHBvcnQgZW51bSBWZFJlZ2lvblR5cGUge1xuICBVbmtub3duID0gJ3Vua25vd24nLFxuICBGUiA9ICdmcmFtZXdvcmsnLFxuICBDRFIgPSAnY2RyJyxcbn1cblxuLyoqIERlc2NyaWJlcyBWLURPTUFJTiAoSUcgYW5kIFRSKSByZWdpb24gKG9mIG11bHRpcGxlIGFsaWdubWVudClcbiAqIGh0dHBzOi8vd3d3LmltZ3Qub3JnL0lNR1RTY2llbnRpZmljQ2hhcnQvTnVtYmVyaW5nL0lNR1RJR1ZMc3VwZXJmYW1pbHkuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgVmRSZWdpb24ge1xuICB0eXBlOiBWZFJlZ2lvblR5cGU7XG4gIG5hbWU6IHN0cmluZztcbiAgY2hhaW46IHN0cmluZztcbiAgb3JkZXI6IG51bWJlcjtcbiAgcG9zaXRpb25TdGFydE5hbWU6IHN0cmluZztcbiAgcG9zaXRpb25FbmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIHN0YXJ0IGFuZCBwb3NpdGlvbiBhcmUgc3RyaW5ncyBiZWNhdXNlIHRoZXkgY29ycmVzcG9uZCB0byBwb3NpdGlvbiBuYW1lcyBhcyBjb2x1bW4gbmFtZXMgaW4gQU5BUkNJIG91dHB1dFxuICAgKiBAcGFyYW0ge1ZkUmVnaW9uVHlwZX0gdHlwZSAgVHlwZSBvZiB0aGUgcmVnaW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lICBOYW1lIG9mIHRoZSByZWdpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IGNoYWluXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcmRlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gcG9zaXRpb25TdGFydE5hbWUgIFJlZ2lvbiBzdGFydCBwb3NpdGlvbiAoaW5jbHVzaXZlKVxuICAgKiBAcGFyYW0ge3N0cmluZ30gcG9zaXRpb25FbmROYW1lICBSZWdpb24gZW5kIHBvc2l0aW9uIChpbmNsdXNpdmUpXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih0eXBlOiBWZFJlZ2lvblR5cGUsIG5hbWU6IHN0cmluZywgY2hhaW46IHN0cmluZywgb3JkZXI6IG51bWJlcixcbiAgICBwb3NpdGlvblN0YXJ0TmFtZTogc3RyaW5nLCBwb3NpdGlvbkVuZE5hbWU6IHN0cmluZykge1xuICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLmNoYWluID0gY2hhaW47XG4gICAgdGhpcy5vcmRlciA9IG9yZGVyO1xuICAgIHRoaXMucG9zaXRpb25TdGFydE5hbWUgPSBwb3NpdGlvblN0YXJ0TmFtZTtcbiAgICB0aGlzLnBvc2l0aW9uRW5kTmFtZSA9IHBvc2l0aW9uRW5kTmFtZTtcbiAgfVxufVxuXG4vKiogSW50ZXJmYWNlIGZvciBWZFJlZ2lvbnNWaWV3ZXIgZnJvbSBAZGF0YWdyb2svYmlvIHRvIHVuYmluZCBkZXBlbmRlbmN5IHRvIEJpbyBwYWNrYWdlICovXG5leHBvcnQgaW50ZXJmYWNlIElWZFJlZ2lvbnNWaWV3ZXIgZXh0ZW5kcyBJVmlld2VyIHtcbiAgaW5pdCgpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIHNldERmKG1sYkRmOiBERy5EYXRhRnJhbWUsIHJlZ2lvbnM6IFZkUmVnaW9uW10pOiBQcm9taXNlPHZvaWQ+O1xufSJdfQ==
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmQtcmVnaW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInZkLXJlZ2lvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEscURBQXFEO0FBRXJELE1BQU0sQ0FBTixJQUFZLFlBSVg7QUFKRCxXQUFZLFlBQVk7SUFDdEIsbUNBQW1CLENBQUE7SUFDbkIsZ0NBQWdCLENBQUE7SUFDaEIsMkJBQVcsQ0FBQTtBQUNiLENBQUMsRUFKVyxZQUFZLEtBQVosWUFBWSxRQUl2QjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFFBQVE7SUFRbkI7Ozs7Ozs7O09BUUc7SUFDSCxZQUFZLElBQWtCLEVBQUUsSUFBWSxFQUFFLEtBQWEsRUFBRSxLQUFhLEVBQ3hFLGlCQUF5QixFQUFFLGVBQXVCO1FBQ2xELElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxpQkFBaUIsQ0FBQztRQUMzQyxJQUFJLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQztJQUN6QyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuXG5pbXBvcnQge0lWaWV3ZXJ9IGZyb20gJy4vdmlld2Vycy92aWV3ZXInO1xuXG4vLyBEYXRhIHN0cnVjdHVyZXMgZm9yIFYtRG9tYWluIHJlZ2lvbnMgb2YgYW50aWJvZGllc1xuXG5leHBvcnQgZW51bSBWZFJlZ2lvblR5cGUge1xuICBVbmtub3duID0gJ3Vua25vd24nLFxuICBGUiA9ICdmcmFtZXdvcmsnLFxuICBDRFIgPSAnY2RyJyxcbn1cblxuLyoqIERlc2NyaWJlcyBWLURPTUFJTiAoSUcgYW5kIFRSKSByZWdpb24gKG9mIG11bHRpcGxlIGFsaWdubWVudClcbiAqIGh0dHBzOi8vd3d3LmltZ3Qub3JnL0lNR1RTY2llbnRpZmljQ2hhcnQvTnVtYmVyaW5nL0lNR1RJR1ZMc3VwZXJmYW1pbHkuaHRtbFxuICovXG5leHBvcnQgY2xhc3MgVmRSZWdpb24ge1xuICB0eXBlOiBWZFJlZ2lvblR5cGU7XG4gIG5hbWU6IHN0cmluZztcbiAgY2hhaW46IHN0cmluZztcbiAgb3JkZXI6IG51bWJlcjtcbiAgcG9zaXRpb25TdGFydE5hbWU6IHN0cmluZztcbiAgcG9zaXRpb25FbmROYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIHN0YXJ0IGFuZCBwb3NpdGlvbiBhcmUgc3RyaW5ncyBiZWNhdXNlIHRoZXkgY29ycmVzcG9uZCB0byBwb3NpdGlvbiBuYW1lcyBhcyBjb2x1bW4gbmFtZXMgaW4gQU5BUkNJIG91dHB1dFxuICAgKiBAcGFyYW0ge1ZkUmVnaW9uVHlwZX0gdHlwZSAgVHlwZSBvZiB0aGUgcmVnaW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lICBOYW1lIG9mIHRoZSByZWdpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IGNoYWluXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcmRlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gcG9zaXRpb25TdGFydE5hbWUgIFJlZ2lvbiBzdGFydCBwb3NpdGlvbiAoaW5jbHVzaXZlKVxuICAgKiBAcGFyYW0ge3N0cmluZ30gcG9zaXRpb25FbmROYW1lICBSZWdpb24gZW5kIHBvc2l0aW9uIChpbmNsdXNpdmUpXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih0eXBlOiBWZFJlZ2lvblR5cGUsIG5hbWU6IHN0cmluZywgY2hhaW46IHN0cmluZywgb3JkZXI6IG51bWJlcixcbiAgICBwb3NpdGlvblN0YXJ0TmFtZTogc3RyaW5nLCBwb3NpdGlvbkVuZE5hbWU6IHN0cmluZykge1xuICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICB0aGlzLmNoYWluID0gY2hhaW47XG4gICAgdGhpcy5vcmRlciA9IG9yZGVyO1xuICAgIHRoaXMucG9zaXRpb25TdGFydE5hbWUgPSBwb3NpdGlvblN0YXJ0TmFtZTtcbiAgICB0aGlzLnBvc2l0aW9uRW5kTmFtZSA9IHBvc2l0aW9uRW5kTmFtZTtcbiAgfVxufVxuXG4vKiogSW50ZXJmYWNlIGZvciBWZFJlZ2lvbnNWaWV3ZXIgZnJvbSBAZGF0YWdyb2svYmlvIHRvIHVuYmluZCBkZXBlbmRlbmN5IHRvIEJpbyBwYWNrYWdlICovXG5leHBvcnQgaW50ZXJmYWNlIElWZFJlZ2lvbnNWaWV3ZXIgZXh0ZW5kcyBJVmlld2VyIHtcbiAgaW5pdCgpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIHNldERhdGEobWxiRGY6IERHLkRhdGFGcmFtZSwgcmVnaW9uczogVmRSZWdpb25bXSk6IFByb21pc2U8dm9pZD47XG59XG4iXX0=
@@ -0,0 +1,5 @@
1
+ export declare enum PositionHeight {
2
+ Entropy = "Entropy",
3
+ full = "100%"
4
+ }
5
+ //# sourceMappingURL=web-logo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-logo.d.ts","sourceRoot":"","sources":["web-logo.ts"],"names":[],"mappings":"AAIA,oBAAY,cAAc;IACxB,OAAO,YAAY;IACnB,IAAI,SAAS;CACd"}
@@ -0,0 +1,6 @@
1
+ export var PositionHeight;
2
+ (function (PositionHeight) {
3
+ PositionHeight["Entropy"] = "Entropy";
4
+ PositionHeight["full"] = "100%";
5
+ })(PositionHeight || (PositionHeight = {}));
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLWxvZ28uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ3ZWItbG9nby50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxNQUFNLENBQU4sSUFBWSxjQUdYO0FBSEQsV0FBWSxjQUFjO0lBQ3hCLHFDQUFtQixDQUFBO0lBQ25CLCtCQUFhLENBQUE7QUFDZixDQUFDLEVBSFcsY0FBYyxLQUFkLGNBQWMsUUFHekIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBncm9rIGZyb20gJ2RhdGFncm9rLWFwaS9ncm9rJztcbmltcG9ydCAqIGFzIHVpIGZyb20gJ2RhdGFncm9rLWFwaS91aSc7XG5pbXBvcnQgKiBhcyBERyBmcm9tICdkYXRhZ3Jvay1hcGkvZGcnO1xuXG5leHBvcnQgZW51bSBQb3NpdGlvbkhlaWdodCB7XG4gIEVudHJvcHkgPSAnRW50cm9weScsXG4gIGZ1bGwgPSAnMTAwJScsXG59Il19
@@ -1,128 +0,0 @@
1
- import * as DG from 'datagrok-api/dg';
2
- import { SeqPalette } from '../seq-palettes';
3
- export declare enum PositionHeight {
4
- Entropy = "Entropy",
5
- full = "100%"
6
- }
7
- declare global {
8
- interface HTMLCanvasElement {
9
- getCursorPosition(event: MouseEvent, r: number): DG.Point;
10
- }
11
- }
12
- export declare class PositionMonomerInfo {
13
- /** Sequences count with monomer in position */
14
- count: number;
15
- /** Remember screen coords rect */
16
- bounds: DG.Rect;
17
- constructor(count?: number, bounds?: DG.Rect);
18
- }
19
- export declare class PositionInfo {
20
- readonly name: string;
21
- freq: {
22
- [m: string]: PositionMonomerInfo;
23
- };
24
- rowCount: number;
25
- sumForHeightCalc: number;
26
- /** freq = {}, rowCount = 0
27
- * @param {string} name Name of position ('111A', '111.1', etc)
28
- * @param {number} sumForHeightCalc Sum of all monomer counts for height calculation
29
- * @param {number} rowCount Count of elements in column
30
- * @param {string[]} freq frequency of monomers in position
31
- */
32
- constructor(name: string, freq?: {
33
- [m: string]: PositionMonomerInfo;
34
- }, rowCount?: number, sumForHeightCalc?: number);
35
- }
36
- export declare class WebLogoViewer extends DG.JsViewer {
37
- static residuesSet: string;
38
- private static viewerCount;
39
- private readonly viewerId;
40
- private unitsHandler;
41
- private initialized;
42
- protected cp: SeqPalette | null;
43
- private host?;
44
- private msgHost?;
45
- private canvas;
46
- private slider;
47
- private readonly textBaseline;
48
- private axisHeight;
49
- private seqCol;
50
- private splitter;
51
- private positions;
52
- private rowsMasked;
53
- private rowsNull;
54
- private visibleSlider;
55
- private allowResize;
56
- private turnOfResizeForOneSetValue;
57
- private _positionWidth;
58
- positionWidth: number;
59
- minHeight: number;
60
- backgroundColor: number;
61
- maxHeight: number;
62
- skipEmptySequences: boolean;
63
- sequenceColumnName: string | null;
64
- positionMarginState: string;
65
- positionMargin: number;
66
- startPositionName: string | null;
67
- endPositionName: string | null;
68
- fixWidth: boolean;
69
- verticalAlignment: string | null;
70
- horizontalAlignment: string | null;
71
- fitArea: boolean;
72
- shrinkEmptyTail: boolean;
73
- skipEmptyPositions: boolean;
74
- positionHeight: string;
75
- private positionNames;
76
- private startPosition;
77
- private endPosition;
78
- /** For startPosition equals to endPosition Length is 1 */
79
- private get Length();
80
- /** Calculate new position data basic on {@link positionMarginState} and {@link positionMargin} */
81
- private get positionWidthWithMargin();
82
- private get positionMarginValue();
83
- /** Count of position rendered for calculations countOfRenderPositions */
84
- private get countOfRenderPositions();
85
- private get canvasWidthWithRatio();
86
- /** Position of start rendering */
87
- private get firstVisibleIndex();
88
- private viewSubs;
89
- constructor();
90
- private init;
91
- /** Handler of changing size WebLogo */
92
- private rootOnSizeChanged;
93
- /** Assigns {@link seqCol} and {@link cp} based on {@link sequenceColumnName} and calls {@link render}().
94
- */
95
- private updateSeqCol;
96
- /** Updates {@link positionNames} and calculates {@link startPosition} and {@link endPosition}.
97
- */
98
- private updatePositions;
99
- private get widthArea();
100
- private get heightArea();
101
- private get xScale();
102
- private get yScale();
103
- private checkIsHideSlider;
104
- setSliderVisibility(visible: boolean): void;
105
- /** Updates {@link slider}, needed to set slider options and to update slider position. */
106
- private updateSlider;
107
- /** Handler of property change events. */
108
- onPropertyChanged(property: DG.Property): void;
109
- /** Add filter handlers when table is a attached */
110
- onTableAttached(): void;
111
- /** Remove all handlers when table is a detach */
112
- detach(): Promise<void>;
113
- /** Helper function for rendering */
114
- protected _nullSequence(fillerResidue?: string): string;
115
- /** Helper function for remove empty positions */
116
- protected removeWhere(array: Array<any>, predicate: (T: any) => boolean): Array<any>;
117
- /** Function for removing empty positions */
118
- protected _removeEmptyPositions(): void;
119
- protected _calculate(r: number): void;
120
- /** Render WebLogo sensitive to changes in params of rendering
121
- *@param {boolean} recalc - indicates that need to recalculate data for rendering
122
- */
123
- render(recalc?: boolean): void;
124
- /** Calculate canvas size an positionWidth and updates properties */
125
- private calcSize;
126
- getAlphabetSize(): number;
127
- }
128
- //# sourceMappingURL=web-logo-viewer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"web-logo-viewer.d.ts","sourceRoot":"","sources":["web-logo-viewer.ts"],"names":[],"mappings":"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"}
@@ -1,676 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import * as grok from 'datagrok-api/grok';
11
- import * as ui from 'datagrok-api/ui';
12
- import * as DG from 'datagrok-api/dg';
13
- import wu from 'wu';
14
- import * as rxjs from 'rxjs';
15
- import { UnitsHandler } from '../utils/units-handler';
16
- import { getSplitter, monomerToShort, pickUpPalette, pickUpSeqCol } from '../utils/macromolecule';
17
- export var PositionHeight;
18
- (function (PositionHeight) {
19
- PositionHeight["Entropy"] = "Entropy";
20
- PositionHeight["full"] = "100%";
21
- })(PositionHeight || (PositionHeight = {}));
22
- /**@param {MouseEvent} event
23
- * @param {number} r devicePixelRation
24
- * @return {DG.Point} canvas related cursor position
25
- */
26
- HTMLCanvasElement.prototype.getCursorPosition = function (event, r) {
27
- const rect = this.getBoundingClientRect();
28
- return new DG.Point((event.clientX - rect.left) * r, (event.clientY - rect.top) * r);
29
- };
30
- DG.Rect.prototype.contains = function (x, y) {
31
- return this.left <= x && x <= this.right && this.top <= y && y <= this.bottom;
32
- };
33
- export class PositionMonomerInfo {
34
- constructor(count = 0, bounds = new DG.Rect(0, 0, 0, 0)) {
35
- this.count = count;
36
- this.bounds = bounds;
37
- }
38
- }
39
- export class PositionInfo {
40
- /** freq = {}, rowCount = 0
41
- * @param {string} name Name of position ('111A', '111.1', etc)
42
- * @param {number} sumForHeightCalc Sum of all monomer counts for height calculation
43
- * @param {number} rowCount Count of elements in column
44
- * @param {string[]} freq frequency of monomers in position
45
- */
46
- constructor(name, freq = {}, rowCount = 0, sumForHeightCalc = 0) {
47
- this.name = name;
48
- this.freq = freq;
49
- this.rowCount = rowCount;
50
- this.sumForHeightCalc = sumForHeightCalc;
51
- }
52
- }
53
- export class WebLogoViewer extends DG.JsViewer {
54
- /** For startPosition equals to endPosition Length is 1 */
55
- get Length() {
56
- if (this.skipEmptyPositions) {
57
- return this.positions.length;
58
- }
59
- return this.startPosition <= this.endPosition ? this.endPosition - this.startPosition + 1 : 0;
60
- }
61
- /** Calculate new position data basic on {@link positionMarginState} and {@link positionMargin} */
62
- get positionWidthWithMargin() {
63
- return this._positionWidth + this.positionMarginValue;
64
- }
65
- get positionMarginValue() {
66
- var _a;
67
- if ((this.positionMarginState === 'auto') && (((_a = this.unitsHandler) === null || _a === void 0 ? void 0 : _a.getAlphabetIsMultichar()) === true)) {
68
- return this.positionMargin;
69
- }
70
- if (this.positionMarginState === 'enable') {
71
- return this.positionMargin;
72
- }
73
- return 0;
74
- }
75
- /** Count of position rendered for calculations countOfRenderPositions */
76
- get countOfRenderPositions() {
77
- if (this.host == null) {
78
- return 0;
79
- }
80
- const r = window.devicePixelRatio;
81
- if (r > 1) {
82
- return this.canvasWidthWithRatio / this.positionWidthWithMargin;
83
- }
84
- else {
85
- return this.canvas.width / (this.positionWidthWithMargin * r);
86
- }
87
- }
88
- get canvasWidthWithRatio() {
89
- return this.canvas.width * window.devicePixelRatio;
90
- }
91
- /** Position of start rendering */
92
- get firstVisibleIndex() {
93
- return (this.visibleSlider) ? Math.floor(this.slider.min) : 0;
94
- }
95
- constructor() {
96
- super();
97
- this.viewerId = -1;
98
- this.initialized = false;
99
- // private readonly colorScheme: ColorScheme = ColorSchemes[NucleotidesWebLogo.residuesSet];
100
- this.cp = null;
101
- this.axisHeight = 12;
102
- this.seqCol = null;
103
- this.splitter = null;
104
- // private maxLength: number = 100;
105
- this.positions = [];
106
- this.rowsMasked = 0;
107
- this.rowsNull = 0;
108
- this.visibleSlider = false;
109
- this.allowResize = true;
110
- this.turnOfResizeForOneSetValue = false;
111
- this.backgroundColor = 0xFFFFFFFF;
112
- this.positionMargin = 0;
113
- this.positionNames = [];
114
- this.startPosition = -1;
115
- this.endPosition = -1;
116
- this.viewSubs = [];
117
- this.viewerId = WebLogoViewer.viewerCount;
118
- WebLogoViewer.viewerCount += 1;
119
- this.textBaseline = 'top';
120
- this.unitsHandler = null;
121
- this.backgroundColor = this.int('backgroundColor', 0xFFFFFFFF);
122
- this._positionWidth = this.positionWidth = this.float('positionWidth', 16 /*,
123
- {editor: 'slider', min: 4, max: 64, postfix: 'px'}*/);
124
- this.minHeight = this.float('minHeight', 50 /*,
125
- {editor: 'slider', min: 25, max: 250, postfix: 'px'}*/);
126
- this.maxHeight = this.float('maxHeight', 100 /*,
127
- {editor: 'slider', min: 25, max: 500, postfix: 'px'}*/);
128
- this.skipEmptySequences = this.bool('skipEmptySequences', true);
129
- this.sequenceColumnName = this.string('sequenceColumnName', null);
130
- this.startPositionName = this.string('startPositionName', null);
131
- this.endPositionName = this.string('endPositionName', null);
132
- this.fixWidth = this.bool('fixWidth', false);
133
- this.verticalAlignment = this.string('verticalAlignment', 'middle', { choices: ['top', 'middle', 'bottom'] });
134
- this.horizontalAlignment = this.string('horizontalAlignment', 'center', { choices: ['left', 'center', 'right'] });
135
- this.fitArea = this.bool('fitArea', true);
136
- this.shrinkEmptyTail = this.bool('shrinkEmptyTail', true);
137
- this.skipEmptyPositions = this.bool('skipEmptyPositions', false);
138
- this.positionMarginState = this.string('positionMarginState', 'auto', { choices: ['auto', 'enable', 'off'] });
139
- let defaultValueForPositionMargin = 0;
140
- if (this.positionMarginState === 'auto') {
141
- defaultValueForPositionMargin = 4;
142
- }
143
- this.positionMargin = this.int('positionMargin', defaultValueForPositionMargin, { min: 0, max: 16 });
144
- this.positionHeight = this.string('positionHeight', PositionHeight.full, { choices: [PositionHeight.full, PositionHeight.Entropy] });
145
- const style = { style: 'barbell' };
146
- this.slider = ui.rangeSlider(0, 100, 0, 20, false, style);
147
- this.canvas = ui.canvas();
148
- this.canvas.style.width = '100%';
149
- }
150
- init() {
151
- if (this.initialized) {
152
- console.error('WebLogo second initialization!');
153
- return;
154
- }
155
- this.initialized = true;
156
- this.helpUrl = '/help/visualize/viewers/web-logo.md';
157
- this.msgHost = ui.div('No message');
158
- this.msgHost.style.display = 'none';
159
- this.canvas = ui.canvas();
160
- this.canvas.style.width = '100%';
161
- //this.slider.setShowHandles(false);
162
- this.slider.root.style.position = 'absolute';
163
- this.slider.root.style.zIndex = '999';
164
- this.slider.root.style.display = 'none';
165
- this.slider.root.style.height = '0.7em';
166
- this.visibleSlider = false;
167
- this.slider.onValuesChanged.subscribe(() => {
168
- if ((this.host == null)) {
169
- return;
170
- }
171
- /* Resize slider if we can resize do that */
172
- if ((this.allowResize) && (!this.turnOfResizeForOneSetValue) &&
173
- (this.visibleSlider)) {
174
- const countOfPositions = Math.ceil(this.slider.max - this.slider.min);
175
- const calculatedWidth = (this.canvas.width / countOfPositions) - this.positionMarginValue;
176
- // saving positionWidth value global (even if slider is not visible)
177
- this.positionWidth = calculatedWidth;
178
- this._positionWidth = calculatedWidth;
179
- }
180
- this.turnOfResizeForOneSetValue = false;
181
- this.render(true);
182
- });
183
- this.host = ui.div([this.msgHost, this.canvas]);
184
- this.host.style.justifyContent = 'center';
185
- this.host.style.alignItems = 'center';
186
- this.host.style.position = 'relative';
187
- this.host.style.setProperty('overflow', 'hidden', 'important');
188
- const getMonomer = (p) => {
189
- const calculatedX = p.x + this.firstVisibleIndex * this.positionWidthWithMargin;
190
- const jPos = Math.floor(p.x / this.positionWidthWithMargin + this.firstVisibleIndex);
191
- const position = this.positions[jPos];
192
- if (position === void 0)
193
- return [jPos, null, null];
194
- const monomer = Object.keys(position.freq)
195
- .find((m) => position.freq[m].bounds.contains(calculatedX, p.y));
196
- if (monomer === undefined)
197
- return [jPos, null, null];
198
- return [jPos, monomer, position.freq[monomer]];
199
- };
200
- const correctMonomerFilter = (iRow, monomer, jPos) => {
201
- const seq = this.seqCol.get(iRow);
202
- const seqM = seq ? this.splitter(seq)[this.startPosition + jPos] : null;
203
- return ((seqM === monomer) || (seqM === '' && monomer === '-')) && this.dataFrame.filter.get(iRow);
204
- };
205
- rxjs.fromEvent(this.canvas, 'mousemove').subscribe((e) => {
206
- const args = e;
207
- const r = window.devicePixelRatio;
208
- const cursorP = this.canvas.getCursorPosition(args, r);
209
- const [jPos, monomer] = getMonomer(cursorP);
210
- if (this.dataFrame && this.seqCol && this.splitter && monomer) {
211
- const rowCount = wu.count().take(this.dataFrame.rowCount).filter(function (iRow) {
212
- return correctMonomerFilter(iRow, monomer, jPos);
213
- }).reduce((count, iRow) => count + 1, 0);
214
- ui.tooltip.show(ui.div([ui.div(`${monomer}`), ui.div(`${rowCount} rows`)]), args.x + 16, args.y + 16);
215
- }
216
- else {
217
- ui.tooltip.hide();
218
- }
219
- });
220
- rxjs.fromEvent(this.canvas, 'mousedown').subscribe((e) => {
221
- const args = e;
222
- const r = window.devicePixelRatio;
223
- const [jPos, monomer] = getMonomer(this.canvas.getCursorPosition(args, r));
224
- // prevents deselect all rows if we miss monomer bounds
225
- if (this.dataFrame && this.seqCol && this.splitter && monomer) {
226
- this.dataFrame.selection.init(function (iRow) {
227
- return correctMonomerFilter(iRow, monomer, jPos);
228
- });
229
- }
230
- });
231
- rxjs.fromEvent(this.canvas, 'wheel').subscribe((e) => {
232
- if (!this.visibleSlider)
233
- return;
234
- const countOfScrollPositions = (e.deltaY / 100) * Math.max(Math.floor((this.countOfRenderPositions) / 2), 1);
235
- this.slider.scrollBy(this.slider.min + countOfScrollPositions);
236
- });
237
- this.viewSubs.push(ui.onSizeChanged(this.root).subscribe(this.rootOnSizeChanged.bind(this)));
238
- this.root.append(this.host);
239
- this.root.append(this.slider.root);
240
- this._calculate(window.devicePixelRatio);
241
- this.updateSlider();
242
- this.render(true);
243
- }
244
- /** Handler of changing size WebLogo */
245
- rootOnSizeChanged() {
246
- this._calculate(window.devicePixelRatio);
247
- this.updateSlider();
248
- this.render(true);
249
- }
250
- /** Assigns {@link seqCol} and {@link cp} based on {@link sequenceColumnName} and calls {@link render}().
251
- */
252
- updateSeqCol() {
253
- if (this.dataFrame) {
254
- this.seqCol = this.sequenceColumnName ? this.dataFrame.col(this.sequenceColumnName) : null;
255
- if (this.seqCol == null) {
256
- this.seqCol = pickUpSeqCol(this.dataFrame);
257
- this.sequenceColumnName = this.seqCol ? this.seqCol.name : null;
258
- }
259
- if (this.seqCol) {
260
- const units = this.seqCol.getTag(DG.TAGS.UNITS);
261
- const separator = this.seqCol.getTag("separator" /* TAGS.separator */);
262
- this.splitter = getSplitter(units, separator);
263
- this.unitsHandler = new UnitsHandler(this.seqCol);
264
- this.updatePositions();
265
- this.cp = pickUpPalette(this.seqCol);
266
- }
267
- else {
268
- this.splitter = null;
269
- this.positionNames = [];
270
- this.startPosition = -1;
271
- this.endPosition = -1;
272
- this.cp = null;
273
- }
274
- }
275
- this.render();
276
- }
277
- /** Updates {@link positionNames} and calculates {@link startPosition} and {@link endPosition}.
278
- */
279
- updatePositions() {
280
- if (!this.seqCol)
281
- return;
282
- let categories;
283
- if (this.shrinkEmptyTail) {
284
- const indices = this.dataFrame.filter.getSelectedIndexes();
285
- categories = Array.from(new Set(Array.from(Array(indices.length).keys()).map((i) => this.seqCol.get(indices[i]))));
286
- }
287
- else {
288
- categories = this.seqCol.categories;
289
- }
290
- const maxLength = categories.length > 0 ? Math.max(...categories.map((s) => s !== null ? this.splitter(s).length : 0)) : 0;
291
- // Get position names from data column tag 'positionNames'
292
- const positionNamesTxt = this.seqCol.getTag('positionNames');
293
- // Fallback if 'positionNames' tag is not provided
294
- this.positionNames = positionNamesTxt ? positionNamesTxt.split(', ').map((n) => n.trim()) :
295
- [...Array(maxLength).keys()].map((jPos) => `${jPos + 1}`);
296
- this.startPosition = (this.startPositionName && this.positionNames &&
297
- this.positionNames.includes(this.startPositionName)) ?
298
- this.positionNames.indexOf(this.startPositionName) : 0;
299
- this.endPosition = (this.endPositionName && this.positionNames &&
300
- this.positionNames.includes(this.endPositionName)) ?
301
- this.positionNames.indexOf(this.endPositionName) : (maxLength - 1);
302
- }
303
- get widthArea() {
304
- return this.Length * this.positionWidth / window.devicePixelRatio;
305
- }
306
- get heightArea() {
307
- return Math.min(this.maxHeight, Math.max(this.minHeight, this.root.clientHeight));
308
- }
309
- get xScale() {
310
- return this.widthArea > 0 ? (this.root.clientWidth - this.Length * this.positionMarginValue) / this.widthArea : 0;
311
- }
312
- get yScale() {
313
- return this.root.clientHeight / this.heightArea;
314
- }
315
- checkIsHideSlider() {
316
- let showSliderWithFitArea = true;
317
- const minScale = Math.min(this.xScale, this.yScale);
318
- if (((minScale == this.xScale) || (minScale <= 1)) && (this.fitArea)) {
319
- showSliderWithFitArea = false;
320
- }
321
- return ((this.fixWidth || Math.ceil(this.canvas.width / this.positionWidthWithMargin) >= this.Length) || (showSliderWithFitArea));
322
- }
323
- setSliderVisibility(visible) {
324
- if (visible) {
325
- this.slider.root.style.display = 'inherit';
326
- this.visibleSlider = true;
327
- }
328
- else {
329
- this.slider.root.style.display = 'none';
330
- this.visibleSlider = false;
331
- }
332
- }
333
- /** Updates {@link slider}, needed to set slider options and to update slider position. */
334
- updateSlider() {
335
- if (this.checkIsHideSlider()) {
336
- this.setSliderVisibility(false);
337
- }
338
- else {
339
- this.setSliderVisibility(true);
340
- }
341
- if ((this.slider != null) && (this.canvas != null)) {
342
- const diffEndScrollAndSliderMin = Math.max(0, Math.floor(this.slider.min + this.canvas.width / this.positionWidthWithMargin) - this.Length);
343
- let newMin = Math.floor(this.slider.min - diffEndScrollAndSliderMin);
344
- let newMax = Math.floor(this.slider.min - diffEndScrollAndSliderMin) + Math.floor(this.canvas.width / this.positionWidthWithMargin);
345
- if (this.checkIsHideSlider()) {
346
- newMin = 0;
347
- newMax = Math.max(newMin, this.Length - 1);
348
- }
349
- this.turnOfResizeForOneSetValue = true;
350
- this.slider.setValues(0, this.Length, newMin, newMax);
351
- }
352
- }
353
- /** Handler of property change events. */
354
- onPropertyChanged(property) {
355
- super.onPropertyChanged(property);
356
- switch (property.name) {
357
- case 'sequenceColumnName':
358
- this.updateSeqCol();
359
- break;
360
- case 'startPositionName':
361
- this.updateSeqCol();
362
- break;
363
- case 'endPositionName':
364
- this.updateSeqCol();
365
- break;
366
- case 'positionWidth':
367
- this._positionWidth = this.positionWidth;
368
- this.updateSlider();
369
- break;
370
- case 'fixWidth':
371
- this.updateSlider();
372
- break;
373
- case 'fitArea':
374
- this.updateSlider();
375
- break;
376
- case 'shrinkEmptyTail':
377
- this.updatePositions();
378
- break;
379
- case 'skipEmptyPositions':
380
- this.updatePositions();
381
- break;
382
- case 'positionMargin':
383
- this.updateSlider();
384
- break;
385
- }
386
- this.render(true);
387
- }
388
- /** Add filter handlers when table is a attached */
389
- onTableAttached() {
390
- super.onTableAttached();
391
- const dataFrameTxt = this.dataFrame ? 'data' : 'null';
392
- console.debug(`bio: WebLogo<${this.viewerId}>.onTableAttached( dataFrame = ${dataFrameTxt} ) start`);
393
- this.updateSeqCol();
394
- if (this.dataFrame !== void 0) {
395
- this.subs.push(this.dataFrame.selection.onChanged.subscribe((_) => this.render()));
396
- this.subs.push(this.dataFrame.filter.onChanged.subscribe((_) => {
397
- this.updatePositions();
398
- this.render();
399
- }));
400
- }
401
- this.init();
402
- console.debug(`bio: WebLogo<${this.viewerId}>.onTableAttached() end`);
403
- }
404
- /** Remove all handlers when table is a detach */
405
- detach() {
406
- const _super = Object.create(null, {
407
- detach: { get: () => super.detach }
408
- });
409
- return __awaiter(this, void 0, void 0, function* () {
410
- const dataFrameTxt = `${this.dataFrame ? 'data' : 'null'}`;
411
- console.debug(`bio: WebLogo<${this.viewerId}>.onTableAttached( dataFrame = ${dataFrameTxt} ) start`);
412
- _super.detach.call(this);
413
- this.viewSubs.forEach((sub) => sub.unsubscribe());
414
- this.host.remove();
415
- this.msgHost = undefined;
416
- this.host = undefined;
417
- this.initialized = false;
418
- console.debug(`bio: WebLogo<${this.viewerId}>.onTableAttached() end`);
419
- });
420
- }
421
- /** Helper function for rendering */
422
- _nullSequence(fillerResidue = 'X') {
423
- if (!this.skipEmptySequences)
424
- return new Array(this.Length).fill(fillerResidue).join('');
425
- return '';
426
- }
427
- /** Helper function for remove empty positions */
428
- // TODO: use this function in from core
429
- removeWhere(array, predicate) {
430
- let length = array.length;
431
- let updateIterator = 0;
432
- for (let deleteIterator = 0; deleteIterator < length; deleteIterator++) {
433
- if (!predicate(array[deleteIterator])) {
434
- array[updateIterator] = array[deleteIterator];
435
- updateIterator++;
436
- }
437
- }
438
- array.length = updateIterator;
439
- return array;
440
- }
441
- /** Function for removing empty positions */
442
- _removeEmptyPositions() {
443
- if (this.skipEmptyPositions) {
444
- this.removeWhere(this.positions, item => { var _a; return ((_a = item === null || item === void 0 ? void 0 : item.freq['-']) === null || _a === void 0 ? void 0 : _a.count) === item.rowCount; });
445
- }
446
- }
447
- _calculate(r) {
448
- if (!this.host || !this.seqCol || !this.dataFrame)
449
- return;
450
- this.unitsHandler = new UnitsHandler(this.seqCol);
451
- this.calcSize();
452
- this.positions = new Array(this.startPosition <= this.endPosition ? this.endPosition - this.startPosition + 1 : 0);
453
- for (let jPos = 0; jPos < this.Length; jPos++) {
454
- const posName = this.positionNames[this.startPosition + jPos];
455
- this.positions[jPos] = new PositionInfo(posName);
456
- }
457
- // 2022-05-05 askalkin instructed to show WebLogo based on filter (not selection)
458
- const indices = this.dataFrame.filter.getSelectedIndexes();
459
- // const indices = this.dataFrame.selection.trueCount > 0 ? this.dataFrame.selection.getSelectedIndexes() :
460
- // this.dataFrame.filter.getSelectedIndexes();
461
- this.rowsMasked = indices.length;
462
- this.rowsNull = 0;
463
- for (const i of indices) {
464
- let s = (this.seqCol.get(i));
465
- if (!s) {
466
- s = this._nullSequence();
467
- ++this.rowsNull;
468
- }
469
- const seqM = this.splitter(s);
470
- for (let jPos = 0; jPos < this.Length; jPos++) {
471
- const pmInfo = this.positions[jPos].freq;
472
- const m = seqM[this.startPosition + jPos] || '-';
473
- if (!(m in pmInfo))
474
- pmInfo[m] = new PositionMonomerInfo();
475
- pmInfo[m].count++;
476
- }
477
- }
478
- //#region Polish freq counts
479
- for (let jPos = 0; jPos < this.Length; jPos++) {
480
- // delete this.positions[jPos].freq['-'];
481
- this.positions[jPos].rowCount = 0;
482
- for (const m in this.positions[jPos].freq)
483
- this.positions[jPos].rowCount += this.positions[jPos].freq[m].count;
484
- if (this.positionHeight == PositionHeight.Entropy) {
485
- this.positions[jPos].sumForHeightCalc = 0;
486
- for (const m in this.positions[jPos].freq) {
487
- const pn = this.positions[jPos].freq[m].count / this.positions[jPos].rowCount;
488
- this.positions[jPos].sumForHeightCalc += -pn * Math.log2(pn);
489
- }
490
- }
491
- }
492
- //#endregion
493
- this._removeEmptyPositions();
494
- const absoluteMaxHeight = this.canvas.height - this.axisHeight * r;
495
- //#region Calculate screen
496
- for (let jPos = 0; jPos < this.Length; jPos++) {
497
- const freq = this.positions[jPos].freq;
498
- const rowCount = this.positions[jPos].rowCount;
499
- const alphabetSize = this.getAlphabetSize();
500
- if ((this.positionHeight == PositionHeight.Entropy) && (alphabetSize == null)) {
501
- grok.shell.error('WebLogo: alphabet is undefined.');
502
- }
503
- const maxHeight = (this.positionHeight == PositionHeight.Entropy) ? (absoluteMaxHeight * (Math.log2(alphabetSize) - (this.positions[jPos].sumForHeightCalc)) / Math.log2(alphabetSize)) : absoluteMaxHeight;
504
- let y = this.axisHeight * r + (absoluteMaxHeight - maxHeight - 1);
505
- const entries = Object.entries(freq).sort((a, b) => {
506
- if (a[0] !== '-' && b[0] !== '-')
507
- return b[1].count - a[1].count;
508
- else if (a[0] === '-' && b[0] === '-')
509
- return 0;
510
- else if (a[0] === '-')
511
- return -1;
512
- else /* (b[0] === '-') */
513
- return +1;
514
- });
515
- for (const entry of entries) {
516
- const pmInfo = entry[1];
517
- // const m: string = entry[0];
518
- const h = maxHeight * pmInfo.count / rowCount;
519
- pmInfo.bounds = new DG.Rect(jPos * this.positionWidthWithMargin, y, this._positionWidth, h);
520
- y += h;
521
- }
522
- }
523
- //#endregion
524
- }
525
- /** Render WebLogo sensitive to changes in params of rendering
526
- *@param {boolean} recalc - indicates that need to recalculate data for rendering
527
- */
528
- render(recalc = true) {
529
- var _a;
530
- if (this.msgHost) {
531
- if (this.seqCol && !this.cp) {
532
- this.msgHost.innerText = `Unknown palette (column semType: '${this.seqCol.semType}').`;
533
- this.msgHost.style.display = '';
534
- }
535
- else {
536
- this.msgHost.style.display = 'none';
537
- }
538
- }
539
- if (!this.seqCol || !this.dataFrame || !this.cp || this.startPosition === -1 || this.endPosition === -1 || this.host == null || this.slider == null)
540
- return;
541
- const g = this.canvas.getContext('2d');
542
- if (!g)
543
- return;
544
- this.slider.root.style.width = `${this.host.clientWidth}px`;
545
- const r = window.devicePixelRatio;
546
- if (recalc)
547
- this._calculate(r);
548
- g.resetTransform();
549
- g.fillStyle = DG.Color.toHtml(this.backgroundColor);
550
- g.fillRect(0, 0, this.canvas.width, this.canvas.height);
551
- g.textBaseline = this.textBaseline;
552
- const maxCountOfRowsRendered = this.countOfRenderPositions + 1;
553
- const firstVisibleIndex = (this.visibleSlider) ? Math.floor(this.slider.min) : 0;
554
- const lastVisibleIndex = Math.min(this.Length, firstVisibleIndex + maxCountOfRowsRendered);
555
- //#region Plot positionNames
556
- const positionFontSize = 10 * r;
557
- g.resetTransform();
558
- g.fillStyle = 'black';
559
- g.textAlign = 'center';
560
- g.font = `${positionFontSize.toFixed(1)}px Roboto, Roboto Local, sans-serif`;
561
- const posNameMaxWidth = Math.max(...this.positions.map((pos) => g.measureText(pos.name).width));
562
- const hScale = posNameMaxWidth < (this._positionWidth - 2) ? 1 : (this._positionWidth - 2) / posNameMaxWidth;
563
- for (let jPos = this.firstVisibleIndex; jPos < lastVisibleIndex; jPos++) {
564
- const pos = this.positions[jPos];
565
- g.resetTransform();
566
- g.setTransform(hScale, 0, 0, 1, jPos * this.positionWidthWithMargin + this._positionWidth / 2 - this.positionWidthWithMargin * firstVisibleIndex, 0);
567
- g.fillText(pos.name, 0, 0);
568
- }
569
- //#endregion Plot positionNames
570
- const fontStyle = '16px Roboto, Roboto Local, sans-serif';
571
- // Hacks to scale uppercase characters to target rectangle
572
- const uppercaseLetterAscent = 0.25;
573
- const uppercaseLetterHeight = 12.2;
574
- for (let jPos = this.firstVisibleIndex; jPos < lastVisibleIndex; jPos++) {
575
- for (const [monomer, pmInfo] of Object.entries(this.positions[jPos].freq)) {
576
- if (monomer !== '-') {
577
- const monomerTxt = monomerToShort(monomer, 5);
578
- const b = pmInfo.bounds;
579
- const left = b.left - this.positionWidthWithMargin * this.firstVisibleIndex;
580
- g.resetTransform();
581
- g.strokeStyle = 'lightgray';
582
- g.lineWidth = 1;
583
- g.rect(left, b.top, b.width, b.height);
584
- g.fillStyle = (_a = this.cp.get(monomer)) !== null && _a !== void 0 ? _a : this.cp.get('other');
585
- g.textAlign = 'left';
586
- g.font = fontStyle;
587
- //g.fillRect(b.left, b.top, b.width, b.height);
588
- const mTm = g.measureText(monomerTxt);
589
- g.setTransform(b.width / mTm.width, 0, 0, b.height / uppercaseLetterHeight, left, b.top);
590
- g.fillText(monomerTxt, 0, -uppercaseLetterAscent);
591
- }
592
- }
593
- }
594
- }
595
- /** Calculate canvas size an positionWidth and updates properties */
596
- calcSize() {
597
- if (!this.host)
598
- return;
599
- const r = window.devicePixelRatio;
600
- let width = this.widthArea;
601
- let height = this.heightArea;
602
- if ((this.fitArea) && (!this.visibleSlider)) {
603
- const scale = Math.max(1, Math.min(this.xScale, this.yScale));
604
- width = width * scale;
605
- height = height * scale;
606
- this._positionWidth = this.positionWidth * scale;
607
- }
608
- width = this.Length * this.positionWidthWithMargin / r;
609
- this.canvas.width = this.root.clientWidth * r;
610
- this.canvas.style.width = `${this.root.clientWidth}px`;
611
- // const canvasHeight: number = width > this.root.clientWidth ? height - 8 : height;
612
- this.host.style.setProperty('height', `${height}px`);
613
- const canvasHeight = this.host.clientHeight;
614
- this.canvas.height = canvasHeight * r;
615
- // Adjust host and root width
616
- if (this.fixWidth) {
617
- // full width for canvas host and root
618
- this.root.style.width = this.host.style.width = `${width}px`;
619
- this.root.style.height = `${height}px`;
620
- this.root.style.overflow = 'hidden';
621
- this.host.style.setProperty('overflow-y', 'hidden', 'important');
622
- }
623
- else {
624
- // allow scroll canvas in root
625
- this.root.style.width = this.host.style.width = '100%';
626
- this.host.style.overflowX = 'auto!important';
627
- this.host.style.setProperty('text-align', this.horizontalAlignment);
628
- const sliderHeight = this.visibleSlider ? 10 : 0;
629
- // vertical alignment
630
- let hostTopMargin = 0;
631
- switch (this.verticalAlignment) {
632
- case 'top':
633
- hostTopMargin = 0;
634
- break;
635
- case 'middle':
636
- hostTopMargin = Math.max(0, (this.root.clientHeight - height) / 2);
637
- break;
638
- case 'bottom':
639
- hostTopMargin = Math.max(0, this.root.clientHeight - height - sliderHeight);
640
- break;
641
- }
642
- // horizontal alignment
643
- let hostLeftMargin = 0;
644
- switch (this.horizontalAlignment) {
645
- case 'left':
646
- hostLeftMargin = 0;
647
- break;
648
- case 'center':
649
- hostLeftMargin = Math.max(0, (this.root.clientWidth - width) / 2);
650
- break;
651
- case 'right':
652
- hostLeftMargin = Math.max(0, this.root.clientWidth - width);
653
- break;
654
- }
655
- this.host.style.setProperty('margin-top', `${hostTopMargin}px`, 'important');
656
- this.host.style.setProperty('margin-left', `${hostLeftMargin}px`, 'important');
657
- if (this.slider != null) {
658
- this.slider.root.style.setProperty('margin-top', `${hostTopMargin + canvasHeight}px`, 'important');
659
- }
660
- if (this.root.clientHeight <= height) {
661
- this.host.style.setProperty('height', `${this.root.clientHeight}px`);
662
- this.host.style.setProperty('overflow-y', null);
663
- }
664
- else {
665
- this.host.style.setProperty('overflow-y', 'hidden', 'important');
666
- }
667
- }
668
- }
669
- getAlphabetSize() {
670
- var _a, _b;
671
- return (_b = (_a = this.unitsHandler) === null || _a === void 0 ? void 0 : _a.getAlphabetSize()) !== null && _b !== void 0 ? _b : 0;
672
- }
673
- }
674
- WebLogoViewer.residuesSet = 'nucleotides';
675
- WebLogoViewer.viewerCount = -1;
676
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLWxvZ28tdmlld2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsid2ViLWxvZ28tdmlld2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLE9BQU8sS0FBSyxJQUFJLE1BQU0sbUJBQW1CLENBQUM7QUFDMUMsT0FBTyxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN0QyxPQUFPLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXRDLE9BQU8sRUFBRSxNQUFNLElBQUksQ0FBQztBQUNwQixPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUk3QixPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFFcEQsT0FBTyxFQUFDLFdBQVcsRUFBRSxjQUFjLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBcUIsTUFBTSx3QkFBd0IsQ0FBQztBQUVwSCxNQUFNLENBQU4sSUFBWSxjQUdYO0FBSEQsV0FBWSxjQUFjO0lBQ3hCLHFDQUFtQixDQUFBO0lBQ25CLCtCQUFhLENBQUE7QUFDZixDQUFDLEVBSFcsY0FBYyxLQUFkLGNBQWMsUUFHekI7QUFRRDs7O0dBR0c7QUFDSCxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEdBQUcsVUFBUyxLQUFpQixFQUFFLENBQVM7SUFDbkYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7SUFDMUMsT0FBTyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN2RixDQUFDLENBQUM7QUFFRixFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEdBQUcsVUFBUyxDQUFTLEVBQUUsQ0FBUztJQUN4RCxPQUFPLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDO0FBQ2hGLENBQUMsQ0FBQztBQUVGLE1BQU0sT0FBTyxtQkFBbUI7SUFPOUIsWUFBWSxRQUFnQixDQUFDLEVBQUUsU0FBa0IsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0RSxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0NBQ0Y7QUFFRCxNQUFNLE9BQU8sWUFBWTtJQU12Qjs7Ozs7T0FLRztJQUNILFlBQVksSUFBWSxFQUFFLE9BQTZDLEVBQUUsRUFBRSxXQUFtQixDQUFDLEVBQUUsbUJBQTJCLENBQUM7UUFDM0gsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO0lBQzNDLENBQUM7Q0FDRjtBQUVELE1BQU0sT0FBTyxhQUFjLFNBQVEsRUFBRSxDQUFDLFFBQVE7SUF3RDVDLDBEQUEwRDtJQUMxRCxJQUFZLE1BQU07UUFDaEIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUU7WUFDM0IsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztTQUM5QjtRQUNELE9BQU8sSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEcsQ0FBQztJQUVELGtHQUFrRztJQUNsRyxJQUFZLHVCQUF1QjtRQUNqQyxPQUFPLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDO0lBQ3hELENBQUM7SUFFRCxJQUFZLG1CQUFtQjs7UUFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsS0FBSyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUEsTUFBQSxJQUFJLENBQUMsWUFBWSwwQ0FBRSxzQkFBc0IsRUFBRSxNQUFLLElBQUksQ0FBQyxFQUFFO1lBQ25HLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQztTQUM1QjtRQUNELElBQUksSUFBSSxDQUFDLG1CQUFtQixLQUFLLFFBQVEsRUFBRTtZQUN6QyxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7U0FDNUI7UUFFRCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRCx5RUFBeUU7SUFDekUsSUFBWSxzQkFBc0I7UUFDaEMsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksRUFBRTtZQUNyQixPQUFPLENBQUMsQ0FBQztTQUNWO1FBQ0QsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDO1FBQ2xDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUNULE9BQU8sSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQztTQUNqRTthQUFNO1lBQ0wsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxDQUFDLENBQUMsQ0FBQztTQUMvRDtJQUNILENBQUM7SUFFRCxJQUFZLG9CQUFvQjtRQUM5QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztJQUNyRCxDQUFDO0lBR0Qsa0NBQWtDO0lBQ2xDLElBQVksaUJBQWlCO1FBQzNCLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFJRDtRQUNFLEtBQUssRUFBRSxDQUFDO1FBdEdPLGFBQVEsR0FBVyxDQUFDLENBQUMsQ0FBQztRQUUvQixnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUVyQyw0RkFBNEY7UUFDbEYsT0FBRSxHQUFzQixJQUFJLENBQUM7UUFRL0IsZUFBVSxHQUFXLEVBQUUsQ0FBQztRQUV4QixXQUFNLEdBQTZCLElBQUksQ0FBQztRQUN4QyxhQUFRLEdBQXdCLElBQUksQ0FBQztRQUM3QyxtQ0FBbUM7UUFDM0IsY0FBUyxHQUFtQixFQUFFLENBQUM7UUFFL0IsZUFBVSxHQUFXLENBQUMsQ0FBQztRQUN2QixhQUFRLEdBQVcsQ0FBQyxDQUFDO1FBQ3JCLGtCQUFhLEdBQVksS0FBSyxDQUFDO1FBQy9CLGdCQUFXLEdBQVksSUFBSSxDQUFDO1FBQzVCLCtCQUEwQixHQUFZLEtBQUssQ0FBQztRQU03QyxvQkFBZSxHQUFXLFVBQVUsQ0FBQztRQUtyQyxtQkFBYyxHQUFXLENBQUMsQ0FBQztRQVcxQixrQkFBYSxHQUFhLEVBQUUsQ0FBQztRQUU3QixrQkFBYSxHQUFXLENBQUMsQ0FBQyxDQUFDO1FBRTNCLGdCQUFXLEdBQVcsQ0FBQyxDQUFDLENBQUM7UUFpRHpCLGFBQVEsR0FBbUIsRUFBRSxDQUFDO1FBS3BDLElBQUksQ0FBQyxRQUFRLEdBQUcsYUFBYSxDQUFDLFdBQVcsQ0FBQztRQUMxQyxhQUFhLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQztRQUUvQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQztRQUMxQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUV6QixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsaUJBQWlCLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQTs4REFDbkIsQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFBO2dFQUNhLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQTtnRUFDWSxDQUFDLENBQUM7UUFFMUQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFbEUsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDaEUsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTVELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFN0MsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLEVBQUUsUUFBUSxFQUNoRSxFQUFDLE9BQU8sRUFBRSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLEVBQUMsQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLHFCQUFxQixFQUFFLFFBQVEsRUFDcEUsRUFBQyxPQUFPLEVBQUUsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxFQUFDLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNqRSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxxQkFBcUIsRUFBRSxNQUFNLEVBQ2xFLEVBQUMsT0FBTyxFQUFFLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBQyxDQUFDLENBQUM7UUFDeEMsSUFBSSw2QkFBNkIsR0FBRyxDQUFDLENBQUM7UUFDdEMsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEtBQUssTUFBTSxFQUFFO1lBQ3ZDLDZCQUE2QixHQUFHLENBQUMsQ0FBQztTQUNuQztRQUNELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSw2QkFBNkIsRUFBRSxFQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBQyxDQUFDLENBQUM7UUFDbkcsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFLGNBQWMsQ0FBQyxJQUFJLEVBQUUsRUFBQyxPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFBQyxDQUFDLENBQUM7UUFFbkksTUFBTSxLQUFLLEdBQWtCLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUM7SUFDbkMsQ0FBQztJQUVPLElBQUk7UUFDVixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDcEIsT0FBTyxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFDO1lBQ2hELE9BQU87U0FDUjtRQUVELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxPQUFPLEdBQUcscUNBQXFDLENBQUM7UUFFckQsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFFcEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQztRQUVqQyxvQ0FBb0M7UUFDcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUM7UUFDN0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFDeEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUM7UUFFeEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFFM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUN6QyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRTtnQkFDdkIsT0FBTzthQUNSO1lBQ0QsNENBQTRDO1lBQzVDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQywwQkFBMEIsQ0FBQztnQkFDMUQsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUU7Z0JBQ3RCLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN0RSxNQUFNLGVBQWUsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLGdCQUFnQixDQUFDLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDO2dCQUMxRixvRUFBb0U7Z0JBQ3BFLElBQUksQ0FBQyxhQUFhLEdBQUcsZUFBZSxDQUFDO2dCQUNyQyxJQUFJLENBQUMsY0FBYyxHQUFHLGVBQWUsQ0FBQzthQUN2QztZQUNELElBQUksQ0FBQywwQkFBMEIsR0FBRyxLQUFLLENBQUM7WUFDeEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQixDQUFDLENBQUMsQ0FBQztRQUdILElBQUksQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFFaEQsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxHQUFHLFFBQVEsQ0FBQztRQUMxQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUM7UUFDdEMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxRQUFRLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFFL0QsTUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFXLEVBQXVELEVBQUU7WUFDdEYsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDO1lBQ2hGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDckYsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUV0QyxJQUFJLFFBQVEsS0FBSyxLQUFLLENBQUM7Z0JBQ3JCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRTVCLE1BQU0sT0FBTyxHQUF1QixNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7aUJBQzNELElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuRSxJQUFJLE9BQU8sS0FBSyxTQUFTO2dCQUN2QixPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUU1QixPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDakQsQ0FBQyxDQUFDO1FBRUYsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLElBQVksRUFBRSxPQUFlLEVBQUUsSUFBWSxFQUFFLEVBQUU7WUFDM0UsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbkMsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUN6RSxPQUFPLENBQUMsQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssRUFBRSxJQUFJLE9BQU8sS0FBSyxHQUFHLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyRyxDQUFDLENBQUM7UUFFRixJQUFJLENBQUMsU0FBUyxDQUFhLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBYSxFQUFFLEVBQUU7WUFDL0UsTUFBTSxJQUFJLEdBQUcsQ0FBZSxDQUFDO1lBRTdCLE1BQU0sQ0FBQyxHQUFXLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztZQUMxQyxNQUFNLE9BQU8sR0FBYSxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNqRSxNQUFNLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM1QyxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLE9BQU8sRUFBRTtnQkFDN0QsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFTLElBQUk7b0JBQzVFLE9BQU8sb0JBQW9CLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDbkQsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFTLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDakQsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxRQUFRLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO2FBQ3ZHO2lCQUFNO2dCQUNMLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7YUFDbkI7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxTQUFTLENBQWEsSUFBSSxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFhLEVBQUUsRUFBRTtZQUMvRSxNQUFNLElBQUksR0FBRyxDQUFlLENBQUM7WUFDN0IsTUFBTSxDQUFDLEdBQVcsTUFBTSxDQUFDLGdCQUFnQixDQUFDO1lBQzFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFM0UsdURBQXVEO1lBQ3ZELElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksT0FBTyxFQUFFO2dCQUM3RCxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBUyxJQUFJO29CQUN6QyxPQUFPLG9CQUFvQixDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ25ELENBQUMsQ0FBQyxDQUFDO2FBQ0o7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxTQUFTLENBQWEsSUFBSSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFhLEVBQUUsRUFBRTtZQUMzRSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWE7Z0JBQ3JCLE9BQU87WUFDVCxNQUFNLHNCQUFzQixHQUFHLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM3RyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxzQkFBc0IsQ0FBQyxDQUFDO1FBRWpFLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTdGLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRW5DLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEIsQ0FBQztJQUVELHVDQUF1QztJQUMvQixpQkFBaUI7UUFDdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQixDQUFDO0lBRUQ7T0FDRztJQUNLLFlBQVk7UUFDbEIsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ2xCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQzNGLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLEVBQUU7Z0JBQ3ZCLElBQUksQ0FBQyxNQUFNLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDM0MsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7YUFDakU7WUFDRCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ2YsTUFBTSxLQUFLLEdBQVcsSUFBSSxDQUFDLE1BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDekQsTUFBTSxTQUFTLEdBQVcsSUFBSSxDQUFDLE1BQU8sQ0FBQyxNQUFNLGtDQUFnQixDQUFDO2dCQUM5RCxJQUFJLENBQUMsUUFBUSxHQUFHLFdBQVcsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQzlDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUVsRCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxFQUFFLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUN0QztpQkFBTTtnQkFDTCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztnQkFDckIsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RCLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDO2FBQ2hCO1NBQ0Y7UUFDRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFDaEIsQ0FBQztJQUVEO09BQ0c7SUFDSyxlQUFlO1FBQ3JCLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTTtZQUNkLE9BQU87UUFFVCxJQUFJLFVBQThCLENBQUM7UUFDbkMsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQ3hCLE1BQU0sT0FBTyxHQUFlLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDdkUsVUFBVSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQzdCLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDL0Y7YUFBTTtZQUNMLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztTQUNyQztRQUNELE1BQU0sU0FBUyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FDbEUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFekQsMERBQTBEO1FBQzFELE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDN0Qsa0RBQWtEO1FBQ2xELElBQUksQ0FBQyxhQUFhLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDekYsQ0FBQyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUU1RCxJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsSUFBSSxDQUFDLGlCQUFpQixJQUFJLElBQUksQ0FBQyxhQUFhO1lBQ2hFLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0RCxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxhQUFhO1lBQzVELElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQsSUFBWSxTQUFTO1FBQ25CLE9BQU8sSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztJQUNwRSxDQUFDO0lBRUQsSUFBWSxVQUFVO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDcEYsQ0FBQztJQUVELElBQVksTUFBTTtRQUNoQixPQUFPLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BILENBQUM7SUFFRCxJQUFZLE1BQU07UUFDaEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ2xELENBQUM7SUFFTyxpQkFBaUI7UUFDdkIsSUFBSSxxQkFBcUIsR0FBRyxJQUFJLENBQUM7UUFDakMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVwRCxJQUFJLENBQUMsQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFDcEUscUJBQXFCLEdBQUcsS0FBSyxDQUFDO1NBQy9CO1FBQ0QsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQztJQUNwSSxDQUFDO0lBRUQsbUJBQW1CLENBQUMsT0FBZ0I7UUFDbEMsSUFBSSxPQUFPLEVBQUU7WUFDWCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLFNBQVMsQ0FBQztZQUMzQyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztTQUMzQjthQUFNO1lBQ0wsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7WUFDeEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7U0FDNUI7SUFDSCxDQUFDO0lBRUQsMEZBQTBGO0lBQ2xGLFlBQVk7UUFDbEIsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsRUFBRTtZQUM1QixJQUFJLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDakM7YUFBTTtZQUNMLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNoQztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsRUFBRTtZQUNsRCxNQUFNLHlCQUF5QixHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUMxQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNoRyxJQUFJLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxHQUFHLHlCQUF5QixDQUFDLENBQUM7WUFDckUsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyx5QkFBeUIsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLENBQUM7WUFDcEksSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsRUFBRTtnQkFDNUIsTUFBTSxHQUFHLENBQUMsQ0FBQztnQkFDWCxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQzthQUM1QztZQUNELElBQUksQ0FBQywwQkFBMEIsR0FBRyxJQUFJLENBQUM7WUFDdkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQ2xDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztTQUNuQjtJQUNILENBQUM7SUFFRCx5Q0FBeUM7SUFDekIsaUJBQWlCLENBQUMsUUFBcUI7UUFDckQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWxDLFFBQVEsUUFBUSxDQUFDLElBQUksRUFBRTtZQUN2QixLQUFLLG9CQUFvQjtnQkFDdkIsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNwQixNQUFNO1lBQ1IsS0FBSyxtQkFBbUI7Z0JBQ3RCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDcEIsTUFBTTtZQUNSLEtBQUssaUJBQWlCO2dCQUNwQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3BCLE1BQU07WUFDUixLQUFLLGVBQWU7Z0JBQ2xCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztnQkFDekMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUNwQixNQUFNO1lBQ1IsS0FBSyxVQUFVO2dCQUNiLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDcEIsTUFBTTtZQUNSLEtBQUssU0FBUztnQkFDWixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3BCLE1BQU07WUFDUixLQUFLLGlCQUFpQjtnQkFDcEIsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUN2QixNQUFNO1lBQ1IsS0FBSyxvQkFBb0I7Z0JBQ3ZCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDdkIsTUFBTTtZQUNSLEtBQUssZ0JBQWdCO2dCQUNuQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3BCLE1BQU07U0FDUDtRQUVELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDcEIsQ0FBQztJQUVELG9EQUFvRDtJQUNwQyxlQUFlO1FBQzdCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUV4QixNQUFNLFlBQVksR0FBVyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUM5RCxPQUFPLENBQUMsS0FBSyxDQUFDLGdCQUFnQixJQUFJLENBQUMsUUFBUSxrQ0FBa0MsWUFBWSxVQUFVLENBQUMsQ0FBQztRQUVyRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFcEIsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLEtBQUssQ0FBQyxFQUFFO1lBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDbkYsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO2dCQUM3RCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNoQixDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ0w7UUFFRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDWixPQUFPLENBQUMsS0FBSyxDQUFDLGdCQUFnQixJQUFJLENBQUMsUUFBUSx5QkFBeUIsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFFRCxrREFBa0Q7SUFDNUIsTUFBTTs7Ozs7WUFDMUIsTUFBTSxZQUFZLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzNELE9BQU8sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxRQUFRLGtDQUFrQyxZQUFZLFVBQVUsQ0FBQyxDQUFDO1lBQ3JHLE9BQU0sTUFBTSxZQUFHO1lBRWYsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO1lBQ2xELElBQUksQ0FBQyxJQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDcEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxTQUFTLENBQUM7WUFDekIsSUFBSSxDQUFDLElBQUksR0FBRyxTQUFTLENBQUM7WUFFdEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7WUFDekIsT0FBTyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLFFBQVEseUJBQXlCLENBQUMsQ0FBQztRQUN4RSxDQUFDO0tBQUE7SUFFRCxvQ0FBb0M7SUFDMUIsYUFBYSxDQUFDLGFBQWEsR0FBRyxHQUFHO1FBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCO1lBQzFCLE9BQU8sSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFN0QsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsaURBQWlEO0lBQ2pELHVDQUF1QztJQUM3QixXQUFXLENBQUMsS0FBaUIsRUFBRSxTQUE4QjtRQUNyRSxJQUFJLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQzFCLElBQUksY0FBYyxHQUFHLENBQUMsQ0FBQztRQUN2QixLQUFLLElBQUksY0FBYyxHQUFHLENBQUMsRUFBRSxjQUFjLEdBQUcsTUFBTSxFQUFFLGNBQWMsRUFBRSxFQUFFO1lBQ3RFLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3JDLEtBQUssQ0FBQyxjQUFjLENBQUMsR0FBRyxLQUFLLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQzlDLGNBQWMsRUFBRSxDQUFDO2FBQ2xCO1NBQ0Y7UUFDRCxLQUFLLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQztRQUM5QixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFHRCw0Q0FBNEM7SUFDbEMscUJBQXFCO1FBQzdCLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQzNCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsRUFBRSxXQUFDLE9BQUEsQ0FBQSxNQUFBLElBQUksYUFBSixJQUFJLHVCQUFKLElBQUksQ0FBRSxJQUFJLENBQUMsR0FBRyxDQUFDLDBDQUFFLEtBQUssTUFBSyxJQUFJLENBQUMsUUFBUSxDQUFBLEVBQUEsQ0FBQyxDQUFDO1NBQ3BGO0lBQ0gsQ0FBQztJQUVTLFVBQVUsQ0FBQyxDQUFTO1FBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTO1lBQy9DLE9BQU87UUFDVCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVsRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFFaEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25ILEtBQUssSUFBSSxJQUFJLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFO1lBQzdDLE1BQU0sT0FBTyxHQUFXLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUN0RSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ2xEO1FBRUQsaUZBQWlGO1FBQ2pGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDM0QsMkdBQTJHO1FBQzNHLGdEQUFnRDtRQUVoRCxJQUFJLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7UUFFbEIsS0FBSyxNQUFNLENBQUMsSUFBSSxPQUFPLEVBQUU7WUFDdkIsSUFBSSxDQUFDLEdBQW1CLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUU3QyxJQUFJLENBQUMsQ0FBQyxFQUFFO2dCQUNOLENBQUMsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7Z0JBQ3pCLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQzthQUNqQjtZQUVELE1BQU0sSUFBSSxHQUFhLElBQUksQ0FBQyxRQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekMsS0FBSyxJQUFJLElBQUksR0FBRyxDQUFDLEVBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUU7Z0JBQzdDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDO2dCQUN6QyxNQUFNLENBQUMsR0FBVyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUM7Z0JBQ3pELElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUM7b0JBQ2hCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLG1CQUFtQixFQUFFLENBQUM7Z0JBQ3hDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQzthQUNuQjtTQUNGO1FBRUQsNEJBQTRCO1FBQzVCLEtBQUssSUFBSSxJQUFJLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFO1lBQzdDLHlDQUF5QztZQUV6QyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7WUFDbEMsS0FBSyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUk7Z0JBQ3ZDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztZQUN0RSxJQUFJLElBQUksQ0FBQyxjQUFjLElBQUksY0FBYyxDQUFDLE9BQU8sRUFBRTtnQkFDakQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7Z0JBQzFDLEtBQUssTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUU7b0JBQ3pDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQztvQkFDOUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2lCQUM5RDthQUNGO1NBQ0Y7UUFDRCxZQUFZO1FBQ1osSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFFN0IsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUVuRSwwQkFBMEI7UUFDMUIsS0FBSyxJQUFJLElBQUksR0FBRyxDQUFDLEVBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUU7WUFDN0MsTUFBTSxJQUFJLEdBQXlDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQzdFLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDO1lBQy9DLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUM1QyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsSUFBSSxjQUFjLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLEVBQUU7Z0JBQzdFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7YUFDckQ7WUFFRCxNQUFNLFNBQVMsR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLElBQUksY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsaUJBQWlCLENBQUM7WUFFNU0sSUFBSSxDQUFDLEdBQVcsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsR0FBRyxTQUFTLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFMUUsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2pELElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRztvQkFDOUIsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7cUJBQzVCLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRztvQkFDbkMsT0FBTyxDQUFDLENBQUM7cUJBQ04sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRztvQkFDbkIsT0FBTyxDQUFDLENBQUMsQ0FBQztxQkFDUCxvQkFBb0I7b0JBQ3ZCLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDZCxDQUFDLENBQUMsQ0FBQztZQUNILEtBQUssTUFBTSxLQUFLLElBQUksT0FBTyxFQUFFO2dCQUMzQixNQUFNLE1BQU0sR0FBd0IsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUM3Qyw4QkFBOEI7Z0JBQzlCLE1BQU0sQ0FBQyxHQUFXLFNBQVMsR0FBRyxNQUFNLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQztnQkFFdEQsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDNUYsQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNSO1NBQ0Y7UUFDRCxZQUFZO0lBRWQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJOztRQUNsQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDaEIsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRTtnQkFDM0IsSUFBSSxDQUFDLE9BQVEsQ0FBQyxTQUFTLEdBQUcscUNBQXFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxLQUFLLENBQUM7Z0JBQ3hGLElBQUksQ0FBQyxPQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7YUFDbEM7aUJBQU07Z0JBQ0wsSUFBSSxDQUFDLE9BQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQzthQUN0QztTQUNGO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsYUFBYSxLQUFLLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxXQUFXLEtBQUssQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJO1lBQ2pKLE9BQU87UUFFVCxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsQ0FBQztZQUFFLE9BQU87UUFFZixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQztRQUU1RCxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUM7UUFFbEMsSUFBSSxNQUFNO1lBQ1IsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVyQixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDbkIsQ0FBQyxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDcEQsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBRW5DLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixHQUFHLENBQUMsQ0FBQztRQUMvRCxNQUFNLGlCQUFpQixHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqRixNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxpQkFBaUIsR0FBRyxzQkFBc0IsQ0FBQyxDQUFDO1FBRTNGLDRCQUE0QjtRQUM1QixNQUFNLGdCQUFnQixHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ25CLENBQUMsQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDO1FBQ3RCLENBQUMsQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLHFDQUFxQyxDQUFDO1FBQzdFLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUNoRyxNQUFNLE1BQU0sR0FBRyxlQUFlLEdBQUcsQ0FBQyxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUMsR0FBRyxlQUFlLENBQUM7UUFFN0csS0FBSyxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxHQUFHLGdCQUFnQixFQUFFLElBQUksRUFBRSxFQUFFO1lBQ3ZFLE1BQU0sR0FBRyxHQUFpQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9DLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNuQixDQUFDLENBQUMsWUFBWSxDQUNaLE1BQU0sRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFDZixJQUFJLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixHQUFHLElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN2SCxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQzVCO1FBQ0QsK0JBQStCO1FBQy9CLE1BQU0sU0FBUyxHQUFHLHVDQUF1QyxDQUFDO1FBQzFELDBEQUEwRDtRQUMxRCxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQztRQUNuQyxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQztRQUNuQyxLQUFLLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLEdBQUcsZ0JBQWdCLEVBQUUsSUFBSSxFQUFFLEVBQUU7WUFDdkUsS0FBSyxNQUFNLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDekUsSUFBSSxPQUFPLEtBQUssR0FBRyxFQUFFO29CQUNuQixNQUFNLFVBQVUsR0FBRyxjQUFjLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUM5QyxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO29CQUN4QixNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUM7b0JBRTVFLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztvQkFDbkIsQ0FBQyxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7b0JBQzVCLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO29CQUNoQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUN2QyxDQUFDLENBQUMsU0FBUyxHQUFHLE1BQUEsSUFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLG1DQUFJLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUMzRCxDQUFDLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQztvQkFDckIsQ0FBQyxDQUFDLElBQUksR0FBRyxTQUFTLENBQUM7b0JBQ25CLCtDQUErQztvQkFDL0MsTUFBTSxHQUFHLEdBQWdCLENBQUMsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBRW5ELENBQUMsQ0FBQyxZQUFZLENBQ1osQ0FBQyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sR0FBRyxxQkFBcUIsRUFDM0QsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDZixDQUFDLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO2lCQUNuRDthQUNGO1NBQ0Y7SUFDSCxDQUFDO0lBRUQsb0VBQW9FO0lBQzVELFFBQVE7UUFDZCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk7WUFDWixPQUFPO1FBRVQsTUFBTSxDQUFDLEdBQVcsTUFBTSxDQUFDLGdCQUFnQixDQUFDO1FBRTFDLElBQUksS0FBSyxHQUFXLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDbkMsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUU3QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUU7WUFDM0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQzlELEtBQUssR0FBRyxLQUFLLEdBQUcsS0FBSyxDQUFDO1lBQ3RCLE1BQU0sR0FBRyxNQUFNLEdBQUcsS0FBSyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7U0FDbEQ7UUFFRCxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsdUJBQXVCLEdBQUcsQ0FBQyxDQUFDO1FBRXZELElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDO1FBRXZELG9GQUFvRjtRQUNwRixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUNyRCxNQUFNLFlBQVksR0FBVyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUNwRCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBRXRDLDZCQUE2QjtRQUM3QixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDakIsc0NBQXNDO1lBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsR0FBRyxLQUFLLElBQUksQ0FBQztZQUM3RCxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQztZQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1lBQ3BDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1NBQ2xFO2FBQU07WUFDTCw4QkFBOEI7WUFDOUIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUM7WUFDdkQsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLGdCQUFnQixDQUFDO1lBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFFcEUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFakQscUJBQXFCO1lBQ3JCLElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQztZQUN0QixRQUFRLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDaEMsS0FBSyxLQUFLO29CQUNSLGFBQWEsR0FBRyxDQUFDLENBQUM7b0JBQ2xCLE1BQU07Z0JBQ1IsS0FBSyxRQUFRO29CQUNYLGFBQWEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO29CQUNuRSxNQUFNO2dCQUNSLEtBQUssUUFBUTtvQkFDWCxhQUFhLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEdBQUcsTUFBTSxHQUFHLFlBQVksQ0FBQyxDQUFDO29CQUM1RSxNQUFNO2FBQ1A7WUFDRCx1QkFBdUI7WUFDdkIsSUFBSSxjQUFjLEdBQUcsQ0FBQyxDQUFDO1lBQ3ZCLFFBQVEsSUFBSSxDQUFDLG1CQUFtQixFQUFFO2dCQUNsQyxLQUFLLE1BQU07b0JBQ1QsY0FBYyxHQUFHLENBQUMsQ0FBQztvQkFDbkIsTUFBTTtnQkFDUixLQUFLLFFBQVE7b0JBQ1gsY0FBYyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQ2xFLE1BQU07Z0JBQ1IsS0FBSyxPQUFPO29CQUNWLGNBQWMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsQ0FBQztvQkFDNUQsTUFBTTthQUNQO1lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxHQUFHLGFBQWEsSUFBSSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1lBQzdFLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsR0FBRyxjQUFjLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztZQUMvRSxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxFQUFFO2dCQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLFlBQVksRUFBRSxHQUFHLGFBQWEsR0FBRyxZQUFZLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQzthQUNwRztZQUVELElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksTUFBTSxFQUFFO2dCQUNwQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxDQUFDO2dCQUNyRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDO2FBQ2pEO2lCQUFNO2dCQUNMLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxZQUFZLEVBQUUsUUFBUSxFQUFFLFdBQVcsQ0FBQyxDQUFDO2FBQ2xFO1NBQ0Y7SUFDSCxDQUFDO0lBRU0sZUFBZTs7UUFDcEIsT0FBTyxNQUFBLE1BQUEsSUFBSSxDQUFDLFlBQVksMENBQUUsZUFBZSxFQUFFLG1DQUFJLENBQUMsQ0FBQztJQUNuRCxDQUFDOztBQXh2QmEseUJBQVcsR0FBRyxhQUFhLENBQUM7QUFDM0IseUJBQVcsR0FBVyxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGdyb2sgZnJvbSAnZGF0YWdyb2stYXBpL2dyb2snO1xuaW1wb3J0ICogYXMgdWkgZnJvbSAnZGF0YWdyb2stYXBpL3VpJztcbmltcG9ydCAqIGFzIERHIGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5cbmltcG9ydCB3dSBmcm9tICd3dSc7XG5pbXBvcnQgKiBhcyByeGpzIGZyb20gJ3J4anMnO1xuXG5pbXBvcnQge1NlcVBhbGV0dGV9IGZyb20gJy4uL3NlcS1wYWxldHRlcyc7XG5pbXBvcnQge1N1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1VuaXRzSGFuZGxlcn0gZnJvbSAnLi4vdXRpbHMvdW5pdHMtaGFuZGxlcic7XG5pbXBvcnQge1NsaWRlck9wdGlvbnN9IGZyb20gJ2RhdGFncm9rLWFwaS9kZyc7XG5pbXBvcnQge2dldFNwbGl0dGVyLCBtb25vbWVyVG9TaG9ydCwgcGlja1VwUGFsZXR0ZSwgcGlja1VwU2VxQ29sLCBTcGxpdHRlckZ1bmMsIFRBR1N9IGZyb20gJy4uL3V0aWxzL21hY3JvbW9sZWN1bGUnO1xuXG5leHBvcnQgZW51bSBQb3NpdGlvbkhlaWdodCB7XG4gIEVudHJvcHkgPSAnRW50cm9weScsXG4gIGZ1bGwgPSAnMTAwJScsXG59XG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIEhUTUxDYW52YXNFbGVtZW50IHtcbiAgICBnZXRDdXJzb3JQb3NpdGlvbihldmVudDogTW91c2VFdmVudCwgcjogbnVtYmVyKTogREcuUG9pbnQ7XG4gIH1cbn1cblxuLyoqQHBhcmFtIHtNb3VzZUV2ZW50fSBldmVudFxuICogQHBhcmFtIHtudW1iZXJ9IHIgZGV2aWNlUGl4ZWxSYXRpb25cbiAqIEByZXR1cm4ge0RHLlBvaW50fSBjYW52YXMgcmVsYXRlZCBjdXJzb3IgcG9zaXRpb25cbiAqL1xuSFRNTENhbnZhc0VsZW1lbnQucHJvdG90eXBlLmdldEN1cnNvclBvc2l0aW9uID0gZnVuY3Rpb24oZXZlbnQ6IE1vdXNlRXZlbnQsIHI6IG51bWJlcik6IERHLlBvaW50IHtcbiAgY29uc3QgcmVjdCA9IHRoaXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIHJldHVybiBuZXcgREcuUG9pbnQoKGV2ZW50LmNsaWVudFggLSByZWN0LmxlZnQpICogciwgKGV2ZW50LmNsaWVudFkgLSByZWN0LnRvcCkgKiByKTtcbn07XG5cbkRHLlJlY3QucHJvdG90eXBlLmNvbnRhaW5zID0gZnVuY3Rpb24oeDogbnVtYmVyLCB5OiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIHRoaXMubGVmdCA8PSB4ICYmIHggPD0gdGhpcy5yaWdodCAmJiB0aGlzLnRvcCA8PSB5ICYmIHkgPD0gdGhpcy5ib3R0b207XG59O1xuXG5leHBvcnQgY2xhc3MgUG9zaXRpb25Nb25vbWVySW5mbyB7XG4gIC8qKiBTZXF1ZW5jZXMgY291bnQgd2l0aCBtb25vbWVyIGluIHBvc2l0aW9uICovXG4gIGNvdW50OiBudW1iZXI7XG5cbiAgLyoqIFJlbWVtYmVyIHNjcmVlbiBjb29yZHMgcmVjdCAqL1xuICBib3VuZHM6IERHLlJlY3Q7XG5cbiAgY29uc3RydWN0b3IoY291bnQ6IG51bWJlciA9IDAsIGJvdW5kczogREcuUmVjdCA9IG5ldyBERy5SZWN0KDAsIDAsIDAsIDApKSB7XG4gICAgdGhpcy5jb3VudCA9IGNvdW50O1xuICAgIHRoaXMuYm91bmRzID0gYm91bmRzO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBQb3NpdGlvbkluZm8ge1xuICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICBmcmVxOiB7IFttOiBzdHJpbmddOiBQb3NpdGlvbk1vbm9tZXJJbmZvIH07XG4gIHJvd0NvdW50OiBudW1iZXI7XG4gIHN1bUZvckhlaWdodENhbGM6IG51bWJlcjtcblxuICAvKiogZnJlcSA9IHt9LCByb3dDb3VudCA9IDBcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgTmFtZSBvZiBwb3NpdGlvbiAoJzExMUEnLCAnMTExLjEnLCBldGMpXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdW1Gb3JIZWlnaHRDYWxjIFN1bSBvZiBhbGwgbW9ub21lciBjb3VudHMgZm9yIGhlaWdodCBjYWxjdWxhdGlvblxuICAgKiBAcGFyYW0ge251bWJlcn0gcm93Q291bnQgQ291bnQgb2YgZWxlbWVudHMgaW4gY29sdW1uXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IGZyZXEgZnJlcXVlbmN5IG9mIG1vbm9tZXJzIGluIHBvc2l0aW9uXG4gICAqL1xuICBjb25zdHJ1Y3RvcihuYW1lOiBzdHJpbmcsIGZyZXE6IHsgW206IHN0cmluZ106IFBvc2l0aW9uTW9ub21lckluZm8gfSA9IHt9LCByb3dDb3VudDogbnVtYmVyID0gMCwgc3VtRm9ySGVpZ2h0Q2FsYzogbnVtYmVyID0gMCkge1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5mcmVxID0gZnJlcTtcbiAgICB0aGlzLnJvd0NvdW50ID0gcm93Q291bnQ7XG4gICAgdGhpcy5zdW1Gb3JIZWlnaHRDYWxjID0gc3VtRm9ySGVpZ2h0Q2FsYztcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgV2ViTG9nb1ZpZXdlciBleHRlbmRzIERHLkpzVmlld2VyIHtcbiAgcHVibGljIHN0YXRpYyByZXNpZHVlc1NldCA9ICdudWNsZW90aWRlcyc7XG4gIHByaXZhdGUgc3RhdGljIHZpZXdlckNvdW50OiBudW1iZXIgPSAtMTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHZpZXdlcklkOiBudW1iZXIgPSAtMTtcbiAgcHJpdmF0ZSB1bml0c0hhbmRsZXI6IFVuaXRzSGFuZGxlciB8IG51bGw7XG4gIHByaXZhdGUgaW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvLyBwcml2YXRlIHJlYWRvbmx5IGNvbG9yU2NoZW1lOiBDb2xvclNjaGVtZSA9IENvbG9yU2NoZW1lc1tOdWNsZW90aWRlc1dlYkxvZ28ucmVzaWR1ZXNTZXRdO1xuICBwcm90ZWN0ZWQgY3A6IFNlcVBhbGV0dGUgfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIGhvc3Q/OiBIVE1MRGl2RWxlbWVudDtcbiAgcHJpdmF0ZSBtc2dIb3N0PzogSFRNTEVsZW1lbnQ7XG4gIHByaXZhdGUgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudDtcbiAgcHJpdmF0ZSBzbGlkZXI6IERHLlJhbmdlU2xpZGVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHRleHRCYXNlbGluZTogQ2FudmFzVGV4dEJhc2VsaW5lO1xuXG4gIHByaXZhdGUgYXhpc0hlaWdodDogbnVtYmVyID0gMTI7XG5cbiAgcHJpdmF0ZSBzZXFDb2w6IERHLkNvbHVtbjxzdHJpbmc+IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc3BsaXR0ZXI6IFNwbGl0dGVyRnVuYyB8IG51bGwgPSBudWxsO1xuICAvLyBwcml2YXRlIG1heExlbmd0aDogbnVtYmVyID0gMTAwO1xuICBwcml2YXRlIHBvc2l0aW9uczogUG9zaXRpb25JbmZvW10gPSBbXTtcblxuICBwcml2YXRlIHJvd3NNYXNrZWQ6IG51bWJlciA9IDA7XG4gIHByaXZhdGUgcm93c051bGw6IG51bWJlciA9IDA7XG4gIHByaXZhdGUgdmlzaWJsZVNsaWRlcjogYm9vbGVhbiA9IGZhbHNlO1xuICBwcml2YXRlIGFsbG93UmVzaXplOiBib29sZWFuID0gdHJ1ZTtcbiAgcHJpdmF0ZSB0dXJuT2ZSZXNpemVGb3JPbmVTZXRWYWx1ZTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIFZpZXdlcidzIHByb3BlcnRpZXMgKGxpa2VseSB0aGV5IHNob3VsZCBiZSBwdWJsaWMgc28gdGhhdCB0aGV5IGNhbiBiZSBzZXQgb3V0c2lkZSlcbiAgcHJpdmF0ZSBfcG9zaXRpb25XaWR0aDogbnVtYmVyO1xuICBwdWJsaWMgcG9zaXRpb25XaWR0aDogbnVtYmVyO1xuICBwdWJsaWMgbWluSGVpZ2h0OiBudW1iZXI7XG4gIHB1YmxpYyBiYWNrZ3JvdW5kQ29sb3I6IG51bWJlciA9IDB4RkZGRkZGRkY7XG4gIHB1YmxpYyBtYXhIZWlnaHQ6IG51bWJlcjtcbiAgcHVibGljIHNraXBFbXB0eVNlcXVlbmNlczogYm9vbGVhbjtcbiAgcHVibGljIHNlcXVlbmNlQ29sdW1uTmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgcHVibGljIHBvc2l0aW9uTWFyZ2luU3RhdGU6IHN0cmluZztcbiAgcHVibGljIHBvc2l0aW9uTWFyZ2luOiBudW1iZXIgPSAwO1xuICBwdWJsaWMgc3RhcnRQb3NpdGlvbk5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHB1YmxpYyBlbmRQb3NpdGlvbk5hbWU6IHN0cmluZyB8IG51bGw7XG4gIHB1YmxpYyBmaXhXaWR0aDogYm9vbGVhbjtcbiAgcHVibGljIHZlcnRpY2FsQWxpZ25tZW50OiBzdHJpbmcgfCBudWxsO1xuICBwdWJsaWMgaG9yaXpvbnRhbEFsaWdubWVudDogc3RyaW5nIHwgbnVsbDtcbiAgcHVibGljIGZpdEFyZWE6IGJvb2xlYW47XG4gIHB1YmxpYyBzaHJpbmtFbXB0eVRhaWw6IGJvb2xlYW47XG4gIHB1YmxpYyBza2lwRW1wdHlQb3NpdGlvbnM6IGJvb2xlYW47XG4gIHB1YmxpYyBwb3NpdGlvbkhlaWdodDogc3RyaW5nO1xuXG4gIHByaXZhdGUgcG9zaXRpb25OYW1lczogc3RyaW5nW10gPSBbXTtcblxuICBwcml2YXRlIHN0YXJ0UG9zaXRpb246IG51bWJlciA9IC0xO1xuXG4gIHByaXZhdGUgZW5kUG9zaXRpb246IG51bWJlciA9IC0xO1xuXG4gIC8qKiBGb3Igc3RhcnRQb3NpdGlvbiBlcXVhbHMgdG8gZW5kUG9zaXRpb24gTGVuZ3RoIGlzIDEgKi9cbiAgcHJpdmF0ZSBnZXQgTGVuZ3RoKCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuc2tpcEVtcHR5UG9zaXRpb25zKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnMubGVuZ3RoO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zdGFydFBvc2l0aW9uIDw9IHRoaXMuZW5kUG9zaXRpb24gPyB0aGlzLmVuZFBvc2l0aW9uIC0gdGhpcy5zdGFydFBvc2l0aW9uICsgMSA6IDA7XG4gIH1cblxuICAvKiogQ2FsY3VsYXRlIG5ldyBwb3NpdGlvbiBkYXRhIGJhc2ljIG9uIHtAbGluayBwb3NpdGlvbk1hcmdpblN0YXRlfSBhbmQge0BsaW5rIHBvc2l0aW9uTWFyZ2lufSAqL1xuICBwcml2YXRlIGdldCBwb3NpdGlvbldpZHRoV2l0aE1hcmdpbigpIHtcbiAgICByZXR1cm4gdGhpcy5fcG9zaXRpb25XaWR0aCArIHRoaXMucG9zaXRpb25NYXJnaW5WYWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IHBvc2l0aW9uTWFyZ2luVmFsdWUoKSB7XG4gICAgaWYgKCh0aGlzLnBvc2l0aW9uTWFyZ2luU3RhdGUgPT09ICdhdXRvJykgJiYgKHRoaXMudW5pdHNIYW5kbGVyPy5nZXRBbHBoYWJldElzTXVsdGljaGFyKCkgPT09IHRydWUpKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3NpdGlvbk1hcmdpbjtcbiAgICB9XG4gICAgaWYgKHRoaXMucG9zaXRpb25NYXJnaW5TdGF0ZSA9PT0gJ2VuYWJsZScpIHtcbiAgICAgIHJldHVybiB0aGlzLnBvc2l0aW9uTWFyZ2luO1xuICAgIH1cblxuICAgIHJldHVybiAwO1xuICB9XG5cbiAgLyoqIENvdW50IG9mIHBvc2l0aW9uIHJlbmRlcmVkIGZvciBjYWxjdWxhdGlvbnMgY291bnRPZlJlbmRlclBvc2l0aW9ucyAqL1xuICBwcml2YXRlIGdldCBjb3VudE9mUmVuZGVyUG9zaXRpb25zKCkge1xuICAgIGlmICh0aGlzLmhvc3QgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIGNvbnN0IHIgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgICBpZiAociA+IDEpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhbnZhc1dpZHRoV2l0aFJhdGlvIC8gdGhpcy5wb3NpdGlvbldpZHRoV2l0aE1hcmdpbjtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuY2FudmFzLndpZHRoIC8gKHRoaXMucG9zaXRpb25XaWR0aFdpdGhNYXJnaW4gKiByKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldCBjYW52YXNXaWR0aFdpdGhSYXRpbygpIHtcbiAgICByZXR1cm4gdGhpcy5jYW52YXMud2lkdGggKiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgfVxuXG5cbiAgLyoqIFBvc2l0aW9uIG9mIHN0YXJ0IHJlbmRlcmluZyAqL1xuICBwcml2YXRlIGdldCBmaXJzdFZpc2libGVJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiAodGhpcy52aXNpYmxlU2xpZGVyKSA/IE1hdGguZmxvb3IodGhpcy5zbGlkZXIubWluKSA6IDA7XG4gIH1cblxuICBwcml2YXRlIHZpZXdTdWJzOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLnZpZXdlcklkID0gV2ViTG9nb1ZpZXdlci52aWV3ZXJDb3VudDtcbiAgICBXZWJMb2dvVmlld2VyLnZpZXdlckNvdW50ICs9IDE7XG5cbiAgICB0aGlzLnRleHRCYXNlbGluZSA9ICd0b3AnO1xuICAgIHRoaXMudW5pdHNIYW5kbGVyID0gbnVsbDtcblxuICAgIHRoaXMuYmFja2dyb3VuZENvbG9yID0gdGhpcy5pbnQoJ2JhY2tncm91bmRDb2xvcicsIDB4RkZGRkZGRkYpO1xuICAgIHRoaXMuX3Bvc2l0aW9uV2lkdGggPSB0aGlzLnBvc2l0aW9uV2lkdGggPSB0aGlzLmZsb2F0KCdwb3NpdGlvbldpZHRoJywgMTYvKixcbiAgICAgIHtlZGl0b3I6ICdzbGlkZXInLCBtaW46IDQsIG1heDogNjQsIHBvc3RmaXg6ICdweCd9Ki8pO1xuICAgIHRoaXMubWluSGVpZ2h0ID0gdGhpcy5mbG9hdCgnbWluSGVpZ2h0JywgNTAvKixcbiAgICAgIHtlZGl0b3I6ICdzbGlkZXInLCBtaW46IDI1LCBtYXg6IDI1MCwgcG9zdGZpeDogJ3B4J30qLyk7XG4gICAgdGhpcy5tYXhIZWlnaHQgPSB0aGlzLmZsb2F0KCdtYXhIZWlnaHQnLCAxMDAvKixcbiAgICAgIHtlZGl0b3I6ICdzbGlkZXInLCBtaW46IDI1LCBtYXg6IDUwMCwgcG9zdGZpeDogJ3B4J30qLyk7XG5cbiAgICB0aGlzLnNraXBFbXB0eVNlcXVlbmNlcyA9IHRoaXMuYm9vbCgnc2tpcEVtcHR5U2VxdWVuY2VzJywgdHJ1ZSk7XG4gICAgdGhpcy5zZXF1ZW5jZUNvbHVtbk5hbWUgPSB0aGlzLnN0cmluZygnc2VxdWVuY2VDb2x1bW5OYW1lJywgbnVsbCk7XG5cbiAgICB0aGlzLnN0YXJ0UG9zaXRpb25OYW1lID0gdGhpcy5zdHJpbmcoJ3N0YXJ0UG9zaXRpb25OYW1lJywgbnVsbCk7XG4gICAgdGhpcy5lbmRQb3NpdGlvbk5hbWUgPSB0aGlzLnN0cmluZygnZW5kUG9zaXRpb25OYW1lJywgbnVsbCk7XG5cbiAgICB0aGlzLmZpeFdpZHRoID0gdGhpcy5ib29sKCdmaXhXaWR0aCcsIGZhbHNlKTtcblxuICAgIHRoaXMudmVydGljYWxBbGlnbm1lbnQgPSB0aGlzLnN0cmluZygndmVydGljYWxBbGlnbm1lbnQnLCAnbWlkZGxlJyxcbiAgICAgIHtjaG9pY2VzOiBbJ3RvcCcsICdtaWRkbGUnLCAnYm90dG9tJ119KTtcbiAgICB0aGlzLmhvcml6b250YWxBbGlnbm1lbnQgPSB0aGlzLnN0cmluZygnaG9yaXpvbnRhbEFsaWdubWVudCcsICdjZW50ZXInLFxuICAgICAge2Nob2ljZXM6IFsnbGVmdCcsICdjZW50ZXInLCAncmlnaHQnXX0pO1xuICAgIHRoaXMuZml0QXJlYSA9IHRoaXMuYm9vbCgnZml0QXJlYScsIHRydWUpO1xuICAgIHRoaXMuc2hyaW5rRW1wdHlUYWlsID0gdGhpcy5ib29sKCdzaHJpbmtFbXB0eVRhaWwnLCB0cnVlKTtcbiAgICB0aGlzLnNraXBFbXB0eVBvc2l0aW9ucyA9IHRoaXMuYm9vbCgnc2tpcEVtcHR5UG9zaXRpb25zJywgZmFsc2UpO1xuICAgIHRoaXMucG9zaXRpb25NYXJnaW5TdGF0ZSA9IHRoaXMuc3RyaW5nKCdwb3NpdGlvbk1hcmdpblN0YXRlJywgJ2F1dG8nLFxuICAgICAge2Nob2ljZXM6IFsnYXV0bycsICdlbmFibGUnLCAnb2ZmJ119KTtcbiAgICBsZXQgZGVmYXVsdFZhbHVlRm9yUG9zaXRpb25NYXJnaW4gPSAwO1xuICAgIGlmICh0aGlzLnBvc2l0aW9uTWFyZ2luU3RhdGUgPT09ICdhdXRvJykge1xuICAgICAgZGVmYXVsdFZhbHVlRm9yUG9zaXRpb25NYXJnaW4gPSA0O1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9uTWFyZ2luID0gdGhpcy5pbnQoJ3Bvc2l0aW9uTWFyZ2luJywgZGVmYXVsdFZhbHVlRm9yUG9zaXRpb25NYXJnaW4sIHttaW46IDAsIG1heDogMTZ9KTtcbiAgICB0aGlzLnBvc2l0aW9uSGVpZ2h0ID0gdGhpcy5zdHJpbmcoJ3Bvc2l0aW9uSGVpZ2h0JywgUG9zaXRpb25IZWlnaHQuZnVsbCwge2Nob2ljZXM6IFtQb3NpdGlvbkhlaWdodC5mdWxsLCBQb3NpdGlvbkhlaWdodC5FbnRyb3B5XX0pO1xuXG4gICAgY29uc3Qgc3R5bGU6IFNsaWRlck9wdGlvbnMgPSB7c3R5bGU6ICdiYXJiZWxsJ307XG4gICAgdGhpcy5zbGlkZXIgPSB1aS5yYW5nZVNsaWRlcigwLCAxMDAsIDAsIDIwLCBmYWxzZSwgc3R5bGUpO1xuICAgIHRoaXMuY2FudmFzID0gdWkuY2FudmFzKCk7XG4gICAgdGhpcy5jYW52YXMuc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gIH1cblxuICBwcml2YXRlIGluaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaW5pdGlhbGl6ZWQpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1dlYkxvZ28gc2Vjb25kIGluaXRpYWxpemF0aW9uIScpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuICAgIHRoaXMuaGVscFVybCA9ICcvaGVscC92aXN1YWxpemUvdmlld2Vycy93ZWItbG9nby5tZCc7XG5cbiAgICB0aGlzLm1zZ0hvc3QgPSB1aS5kaXYoJ05vIG1lc3NhZ2UnKTtcbiAgICB0aGlzLm1zZ0hvc3Quc3R5bGUuZGlzcGxheSA9ICdub25lJztcblxuICAgIHRoaXMuY2FudmFzID0gdWkuY2FudmFzKCk7XG4gICAgdGhpcy5jYW52YXMuc3R5bGUud2lkdGggPSAnMTAwJSc7XG5cbiAgICAvL3RoaXMuc2xpZGVyLnNldFNob3dIYW5kbGVzKGZhbHNlKTtcbiAgICB0aGlzLnNsaWRlci5yb290LnN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICB0aGlzLnNsaWRlci5yb290LnN0eWxlLnpJbmRleCA9ICc5OTknO1xuICAgIHRoaXMuc2xpZGVyLnJvb3Quc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICB0aGlzLnNsaWRlci5yb290LnN0eWxlLmhlaWdodCA9ICcwLjdlbSc7XG5cbiAgICB0aGlzLnZpc2libGVTbGlkZXIgPSBmYWxzZTtcblxuICAgIHRoaXMuc2xpZGVyLm9uVmFsdWVzQ2hhbmdlZC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgaWYgKCh0aGlzLmhvc3QgPT0gbnVsbCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLyogUmVzaXplIHNsaWRlciBpZiB3ZSBjYW4gcmVzaXplIGRvIHRoYXQgKi9cbiAgICAgIGlmICgodGhpcy5hbGxvd1Jlc2l6ZSkgJiYgKCF0aGlzLnR1cm5PZlJlc2l6ZUZvck9uZVNldFZhbHVlKSAmJlxuICAgICAgICAodGhpcy52aXNpYmxlU2xpZGVyKSkge1xuICAgICAgICBjb25zdCBjb3VudE9mUG9zaXRpb25zID0gTWF0aC5jZWlsKHRoaXMuc2xpZGVyLm1heCAtIHRoaXMuc2xpZGVyLm1pbik7XG4gICAgICAgIGNvbnN0IGNhbGN1bGF0ZWRXaWR0aCA9ICh0aGlzLmNhbnZhcy53aWR0aCAvIGNvdW50T2ZQb3NpdGlvbnMpIC0gdGhpcy5wb3NpdGlvbk1hcmdpblZhbHVlO1xuICAgICAgICAvLyBzYXZpbmcgcG9zaXRpb25XaWR0aCB2YWx1ZSBnbG9iYWwgKGV2ZW4gaWYgc2xpZGVyIGlzIG5vdCB2aXNpYmxlKVxuICAgICAgICB0aGlzLnBvc2l0aW9uV2lkdGggPSBjYWxjdWxhdGVkV2lkdGg7XG4gICAgICAgIHRoaXMuX3Bvc2l0aW9uV2lkdGggPSBjYWxjdWxhdGVkV2lkdGg7XG4gICAgICB9XG4gICAgICB0aGlzLnR1cm5PZlJlc2l6ZUZvck9uZVNldFZhbHVlID0gZmFsc2U7XG4gICAgICB0aGlzLnJlbmRlcih0cnVlKTtcbiAgICB9KTtcblxuXG4gICAgdGhpcy5ob3N0ID0gdWkuZGl2KFt0aGlzLm1zZ0hvc3QsIHRoaXMuY2FudmFzXSk7XG5cbiAgICB0aGlzLmhvc3Quc3R5bGUuanVzdGlmeUNvbnRlbnQgPSAnY2VudGVyJztcbiAgICB0aGlzLmhvc3Quc3R5bGUuYWxpZ25JdGVtcyA9ICdjZW50ZXInO1xuICAgIHRoaXMuaG9zdC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgdGhpcy5ob3N0LnN0eWxlLnNldFByb3BlcnR5KCdvdmVyZmxvdycsICdoaWRkZW4nLCAnaW1wb3J0YW50Jyk7XG5cbiAgICBjb25zdCBnZXRNb25vbWVyID0gKHA6IERHLlBvaW50KTogW251bWJlciwgc3RyaW5nIHwgbnVsbCwgUG9zaXRpb25Nb25vbWVySW5mbyB8IG51bGxdID0+IHtcbiAgICAgIGNvbnN0IGNhbGN1bGF0ZWRYID0gcC54ICsgdGhpcy5maXJzdFZpc2libGVJbmRleCAqIHRoaXMucG9zaXRpb25XaWR0aFdpdGhNYXJnaW47XG4gICAgICBjb25zdCBqUG9zID0gTWF0aC5mbG9vcihwLnggLyB0aGlzLnBvc2l0aW9uV2lkdGhXaXRoTWFyZ2luICsgdGhpcy5maXJzdFZpc2libGVJbmRleCk7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMucG9zaXRpb25zW2pQb3NdO1xuXG4gICAgICBpZiAocG9zaXRpb24gPT09IHZvaWQgMClcbiAgICAgICAgcmV0dXJuIFtqUG9zLCBudWxsLCBudWxsXTtcblxuICAgICAgY29uc3QgbW9ub21lcjogc3RyaW5nIHwgdW5kZWZpbmVkID0gT2JqZWN0LmtleXMocG9zaXRpb24uZnJlcSlcbiAgICAgICAgLmZpbmQoKG0pID0+IHBvc2l0aW9uLmZyZXFbbV0uYm91bmRzLmNvbnRhaW5zKGNhbGN1bGF0ZWRYLCBwLnkpKTtcbiAgICAgIGlmIChtb25vbWVyID09PSB1bmRlZmluZWQpXG4gICAgICAgIHJldHVybiBbalBvcywgbnVsbCwgbnVsbF07XG5cbiAgICAgIHJldHVybiBbalBvcywgbW9ub21lciwgcG9zaXRpb24uZnJlcVttb25vbWVyXV07XG4gICAgfTtcblxuICAgIGNvbnN0IGNvcnJlY3RNb25vbWVyRmlsdGVyID0gKGlSb3c6IG51bWJlciwgbW9ub21lcjogc3RyaW5nLCBqUG9zOiBudW1iZXIpID0+IHtcbiAgICAgIGNvbnN0IHNlcSA9IHRoaXMuc2VxQ29sIS5nZXQoaVJvdyk7XG4gICAgICBjb25zdCBzZXFNID0gc2VxID8gdGhpcy5zcGxpdHRlciEoc2VxKVt0aGlzLnN0YXJ0UG9zaXRpb24gKyBqUG9zXSA6IG51bGw7XG4gICAgICByZXR1cm4gKChzZXFNID09PSBtb25vbWVyKSB8fCAoc2VxTSA9PT0gJycgJiYgbW9ub21lciA9PT0gJy0nKSkgJiYgdGhpcy5kYXRhRnJhbWUuZmlsdGVyLmdldChpUm93KTtcbiAgICB9O1xuXG4gICAgcnhqcy5mcm9tRXZlbnQ8TW91c2VFdmVudD4odGhpcy5jYW52YXMsICdtb3VzZW1vdmUnKS5zdWJzY3JpYmUoKGU6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGFyZ3MgPSBlIGFzIE1vdXNlRXZlbnQ7XG5cbiAgICAgIGNvbnN0IHI6IG51bWJlciA9IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICAgICAgY29uc3QgY3Vyc29yUDogREcuUG9pbnQgPSB0aGlzLmNhbnZhcy5nZXRDdXJzb3JQb3NpdGlvbihhcmdzLCByKTtcbiAgICAgIGNvbnN0IFtqUG9zLCBtb25vbWVyXSA9IGdldE1vbm9tZXIoY3Vyc29yUCk7XG4gICAgICBpZiAodGhpcy5kYXRhRnJhbWUgJiYgdGhpcy5zZXFDb2wgJiYgdGhpcy5zcGxpdHRlciAmJiBtb25vbWVyKSB7XG4gICAgICAgIGNvbnN0IHJvd0NvdW50ID0gd3UuY291bnQoKS50YWtlKHRoaXMuZGF0YUZyYW1lLnJvd0NvdW50KS5maWx0ZXIoZnVuY3Rpb24oaVJvdykge1xuICAgICAgICAgIHJldHVybiBjb3JyZWN0TW9ub21lckZpbHRlcihpUm93LCBtb25vbWVyLCBqUG9zKTtcbiAgICAgICAgfSkucmVkdWNlPG51bWJlcj4oKGNvdW50LCBpUm93KSA9PiBjb3VudCArIDEsIDApO1xuICAgICAgICB1aS50b29sdGlwLnNob3codWkuZGl2KFt1aS5kaXYoYCR7bW9ub21lcn1gKSwgdWkuZGl2KGAke3Jvd0NvdW50fSByb3dzYCldKSwgYXJncy54ICsgMTYsIGFyZ3MueSArIDE2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVpLnRvb2x0aXAuaGlkZSgpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcnhqcy5mcm9tRXZlbnQ8TW91c2VFdmVudD4odGhpcy5jYW52YXMsICdtb3VzZWRvd24nKS5zdWJzY3JpYmUoKGU6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGFyZ3MgPSBlIGFzIE1vdXNlRXZlbnQ7XG4gICAgICBjb25zdCByOiBudW1iZXIgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbiAgICAgIGNvbnN0IFtqUG9zLCBtb25vbWVyXSA9IGdldE1vbm9tZXIodGhpcy5jYW52YXMuZ2V0Q3Vyc29yUG9zaXRpb24oYXJncywgcikpO1xuXG4gICAgICAvLyBwcmV2ZW50cyBkZXNlbGVjdCBhbGwgcm93cyBpZiB3ZSBtaXNzIG1vbm9tZXIgYm91bmRzXG4gICAgICBpZiAodGhpcy5kYXRhRnJhbWUgJiYgdGhpcy5zZXFDb2wgJiYgdGhpcy5zcGxpdHRlciAmJiBtb25vbWVyKSB7XG4gICAgICAgIHRoaXMuZGF0YUZyYW1lLnNlbGVjdGlvbi5pbml0KGZ1bmN0aW9uKGlSb3cpIHtcbiAgICAgICAgICByZXR1cm4gY29ycmVjdE1vbm9tZXJGaWx0ZXIoaVJvdywgbW9ub21lciwgalBvcyk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcnhqcy5mcm9tRXZlbnQ8V2hlZWxFdmVudD4odGhpcy5jYW52YXMsICd3aGVlbCcpLnN1YnNjcmliZSgoZTogV2hlZWxFdmVudCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLnZpc2libGVTbGlkZXIpXG4gICAgICAgIHJldHVybjtcbiAgICAgIGNvbnN0IGNvdW50T2ZTY3JvbGxQb3NpdGlvbnMgPSAoZS5kZWx0YVkgLyAxMDApICogTWF0aC5tYXgoTWF0aC5mbG9vcigodGhpcy5jb3VudE9mUmVuZGVyUG9zaXRpb25zKSAvIDIpLCAxKTtcbiAgICAgIHRoaXMuc2xpZGVyLnNjcm9sbEJ5KHRoaXMuc2xpZGVyLm1pbiArIGNvdW50T2ZTY3JvbGxQb3NpdGlvbnMpO1xuXG4gICAgfSk7XG5cbiAgICB0aGlzLnZpZXdTdWJzLnB1c2godWkub25TaXplQ2hhbmdlZCh0aGlzLnJvb3QpLnN1YnNjcmliZSh0aGlzLnJvb3RPblNpemVDaGFuZ2VkLmJpbmQodGhpcykpKTtcblxuICAgIHRoaXMucm9vdC5hcHBlbmQodGhpcy5ob3N0KTtcbiAgICB0aGlzLnJvb3QuYXBwZW5kKHRoaXMuc2xpZGVyLnJvb3QpO1xuXG4gICAgdGhpcy5fY2FsY3VsYXRlKHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKTtcbiAgICB0aGlzLnVwZGF0ZVNsaWRlcigpO1xuICAgIHRoaXMucmVuZGVyKHRydWUpO1xuICB9XG5cbiAgLyoqIEhhbmRsZXIgb2YgY2hhbmdpbmcgc2l6ZSBXZWJMb2dvICovXG4gIHByaXZhdGUgcm9vdE9uU2l6ZUNoYW5nZWQoKTogdm9pZCB7XG4gICAgdGhpcy5fY2FsY3VsYXRlKHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKTtcbiAgICB0aGlzLnVwZGF0ZVNsaWRlcigpO1xuICAgIHRoaXMucmVuZGVyKHRydWUpO1xuICB9XG5cbiAgLyoqIEFzc2lnbnMge0BsaW5rIHNlcUNvbH0gYW5kIHtAbGluayBjcH0gYmFzZWQgb24ge0BsaW5rIHNlcXVlbmNlQ29sdW1uTmFtZX0gYW5kIGNhbGxzIHtAbGluayByZW5kZXJ9KCkuXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZVNlcUNvbCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5kYXRhRnJhbWUpIHtcbiAgICAgIHRoaXMuc2VxQ29sID0gdGhpcy5zZXF1ZW5jZUNvbHVtbk5hbWUgPyB0aGlzLmRhdGFGcmFtZS5jb2wodGhpcy5zZXF1ZW5jZUNvbHVtbk5hbWUpIDogbnVsbDtcbiAgICAgIGlmICh0aGlzLnNlcUNvbCA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMuc2VxQ29sID0gcGlja1VwU2VxQ29sKHRoaXMuZGF0YUZyYW1lKTtcbiAgICAgICAgdGhpcy5zZXF1ZW5jZUNvbHVtbk5hbWUgPSB0aGlzLnNlcUNvbCA/IHRoaXMuc2VxQ29sLm5hbWUgOiBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuc2VxQ29sKSB7XG4gICAgICAgIGNvbnN0IHVuaXRzOiBzdHJpbmcgPSB0aGlzLnNlcUNvbCEuZ2V0VGFnKERHLlRBR1MuVU5JVFMpO1xuICAgICAgICBjb25zdCBzZXBhcmF0b3I6IHN0cmluZyA9IHRoaXMuc2VxQ29sIS5nZXRUYWcoVEFHUy5zZXBhcmF0b3IpO1xuICAgICAgICB0aGlzLnNwbGl0dGVyID0gZ2V0U3BsaXR0ZXIodW5pdHMsIHNlcGFyYXRvcik7XG4gICAgICAgIHRoaXMudW5pdHNIYW5kbGVyID0gbmV3IFVuaXRzSGFuZGxlcih0aGlzLnNlcUNvbCk7XG5cbiAgICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbnMoKTtcbiAgICAgICAgdGhpcy5jcCA9IHBpY2tVcFBhbGV0dGUodGhpcy5zZXFDb2wpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zcGxpdHRlciA9IG51bGw7XG4gICAgICAgIHRoaXMucG9zaXRpb25OYW1lcyA9IFtdO1xuICAgICAgICB0aGlzLnN0YXJ0UG9zaXRpb24gPSAtMTtcbiAgICAgICAgdGhpcy5lbmRQb3NpdGlvbiA9IC0xO1xuICAgICAgICB0aGlzLmNwID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBVcGRhdGVzIHtAbGluayBwb3NpdGlvbk5hbWVzfSBhbmQgY2FsY3VsYXRlcyB7QGxpbmsgc3RhcnRQb3NpdGlvbn0gYW5kIHtAbGluayBlbmRQb3NpdGlvbn0uXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZVBvc2l0aW9ucygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2VxQ29sKVxuICAgICAgcmV0dXJuO1xuXG4gICAgbGV0IGNhdGVnb3JpZXM6IChzdHJpbmcgfCBudWxsKSBbXTtcbiAgICBpZiAodGhpcy5zaHJpbmtFbXB0eVRhaWwpIHtcbiAgICAgIGNvbnN0IGluZGljZXM6IEludDMyQXJyYXkgPSB0aGlzLmRhdGFGcmFtZS5maWx0ZXIuZ2V0U2VsZWN0ZWRJbmRleGVzKCk7XG4gICAgICBjYXRlZ29yaWVzID0gQXJyYXkuZnJvbShuZXcgU2V0KFxuICAgICAgICBBcnJheS5mcm9tKEFycmF5KGluZGljZXMubGVuZ3RoKS5rZXlzKCkpLm1hcCgoaTogbnVtYmVyKSA9PiB0aGlzLnNlcUNvbCEuZ2V0KGluZGljZXNbaV0pKSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjYXRlZ29yaWVzID0gdGhpcy5zZXFDb2wuY2F0ZWdvcmllcztcbiAgICB9XG4gICAgY29uc3QgbWF4TGVuZ3RoID0gY2F0ZWdvcmllcy5sZW5ndGggPiAwID8gTWF0aC5tYXgoLi4uY2F0ZWdvcmllcy5tYXAoXG4gICAgICAocykgPT4gcyAhPT0gbnVsbCA/IHRoaXMuc3BsaXR0ZXIhKHMpLmxlbmd0aCA6IDApKSA6IDA7XG5cbiAgICAvLyBHZXQgcG9zaXRpb24gbmFtZXMgZnJvbSBkYXRhIGNvbHVtbiB0YWcgJ3Bvc2l0aW9uTmFtZXMnXG4gICAgY29uc3QgcG9zaXRpb25OYW1lc1R4dCA9IHRoaXMuc2VxQ29sLmdldFRhZygncG9zaXRpb25OYW1lcycpO1xuICAgIC8vIEZhbGxiYWNrIGlmICdwb3NpdGlvbk5hbWVzJyB0YWcgaXMgbm90IHByb3ZpZGVkXG4gICAgdGhpcy5wb3NpdGlvbk5hbWVzID0gcG9zaXRpb25OYW1lc1R4dCA/IHBvc2l0aW9uTmFtZXNUeHQuc3BsaXQoJywgJykubWFwKChuKSA9PiBuLnRyaW0oKSkgOlxuICAgICAgWy4uLkFycmF5KG1heExlbmd0aCkua2V5cygpXS5tYXAoKGpQb3MpID0+IGAke2pQb3MgKyAxfWApO1xuXG4gICAgdGhpcy5zdGFydFBvc2l0aW9uID0gKHRoaXMuc3RhcnRQb3NpdGlvbk5hbWUgJiYgdGhpcy5wb3NpdGlvbk5hbWVzICYmXG4gICAgICB0aGlzLnBvc2l0aW9uTmFtZXMuaW5jbHVkZXModGhpcy5zdGFydFBvc2l0aW9uTmFtZSkpID9cbiAgICAgIHRoaXMucG9zaXRpb25OYW1lcy5pbmRleE9mKHRoaXMuc3RhcnRQb3NpdGlvbk5hbWUpIDogMDtcbiAgICB0aGlzLmVuZFBvc2l0aW9uID0gKHRoaXMuZW5kUG9zaXRpb25OYW1lICYmIHRoaXMucG9zaXRpb25OYW1lcyAmJlxuICAgICAgdGhpcy5wb3NpdGlvbk5hbWVzLmluY2x1ZGVzKHRoaXMuZW5kUG9zaXRpb25OYW1lKSkgP1xuICAgICAgdGhpcy5wb3NpdGlvbk5hbWVzLmluZGV4T2YodGhpcy5lbmRQb3NpdGlvbk5hbWUpIDogKG1heExlbmd0aCAtIDEpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgd2lkdGhBcmVhKCkge1xuICAgIHJldHVybiB0aGlzLkxlbmd0aCAqIHRoaXMucG9zaXRpb25XaWR0aCAvIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgaGVpZ2h0QXJlYSgpIHtcbiAgICByZXR1cm4gTWF0aC5taW4odGhpcy5tYXhIZWlnaHQsIE1hdGgubWF4KHRoaXMubWluSGVpZ2h0LCB0aGlzLnJvb3QuY2xpZW50SGVpZ2h0KSk7XG4gIH1cblxuICBwcml2YXRlIGdldCB4U2NhbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMud2lkdGhBcmVhID4gMCA/ICh0aGlzLnJvb3QuY2xpZW50V2lkdGggLSB0aGlzLkxlbmd0aCAqIHRoaXMucG9zaXRpb25NYXJnaW5WYWx1ZSkgLyB0aGlzLndpZHRoQXJlYSA6IDA7XG4gIH1cblxuICBwcml2YXRlIGdldCB5U2NhbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucm9vdC5jbGllbnRIZWlnaHQgLyB0aGlzLmhlaWdodEFyZWE7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrSXNIaWRlU2xpZGVyKCk6IGJvb2xlYW4ge1xuICAgIGxldCBzaG93U2xpZGVyV2l0aEZpdEFyZWEgPSB0cnVlO1xuICAgIGNvbnN0IG1pblNjYWxlID0gTWF0aC5taW4odGhpcy54U2NhbGUsIHRoaXMueVNjYWxlKTtcblxuICAgIGlmICgoKG1pblNjYWxlID09IHRoaXMueFNjYWxlKSB8fCAobWluU2NhbGUgPD0gMSkpICYmICh0aGlzLmZpdEFyZWEpKSB7XG4gICAgICBzaG93U2xpZGVyV2l0aEZpdEFyZWEgPSBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuICgodGhpcy5maXhXaWR0aCB8fCBNYXRoLmNlaWwodGhpcy5jYW52YXMud2lkdGggLyB0aGlzLnBvc2l0aW9uV2lkdGhXaXRoTWFyZ2luKSA+PSB0aGlzLkxlbmd0aCkgfHwgKHNob3dTbGlkZXJXaXRoRml0QXJlYSkpO1xuICB9XG5cbiAgc2V0U2xpZGVyVmlzaWJpbGl0eSh2aXNpYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHZpc2libGUpIHtcbiAgICAgIHRoaXMuc2xpZGVyLnJvb3Quc3R5bGUuZGlzcGxheSA9ICdpbmhlcml0JztcbiAgICAgIHRoaXMudmlzaWJsZVNsaWRlciA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2xpZGVyLnJvb3Quc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIHRoaXMudmlzaWJsZVNsaWRlciA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBVcGRhdGVzIHtAbGluayBzbGlkZXJ9LCBuZWVkZWQgdG8gc2V0IHNsaWRlciBvcHRpb25zIGFuZCB0byB1cGRhdGUgc2xpZGVyIHBvc2l0aW9uLiAqL1xuICBwcml2YXRlIHVwZGF0ZVNsaWRlcigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jaGVja0lzSGlkZVNsaWRlcigpKSB7XG4gICAgICB0aGlzLnNldFNsaWRlclZpc2liaWxpdHkoZmFsc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFNsaWRlclZpc2liaWxpdHkodHJ1ZSk7XG4gICAgfVxuICAgIGlmICgodGhpcy5zbGlkZXIgIT0gbnVsbCkgJiYgKHRoaXMuY2FudmFzICE9IG51bGwpKSB7XG4gICAgICBjb25zdCBkaWZmRW5kU2Nyb2xsQW5kU2xpZGVyTWluID0gTWF0aC5tYXgoMCxcbiAgICAgICAgTWF0aC5mbG9vcih0aGlzLnNsaWRlci5taW4gKyB0aGlzLmNhbnZhcy53aWR0aCAvIHRoaXMucG9zaXRpb25XaWR0aFdpdGhNYXJnaW4pIC0gdGhpcy5MZW5ndGgpO1xuICAgICAgbGV0IG5ld01pbiA9IE1hdGguZmxvb3IodGhpcy5zbGlkZXIubWluIC0gZGlmZkVuZFNjcm9sbEFuZFNsaWRlck1pbik7XG4gICAgICBsZXQgbmV3TWF4ID0gTWF0aC5mbG9vcih0aGlzLnNsaWRlci5taW4gLSBkaWZmRW5kU2Nyb2xsQW5kU2xpZGVyTWluKSArIE1hdGguZmxvb3IodGhpcy5jYW52YXMud2lkdGggLyB0aGlzLnBvc2l0aW9uV2lkdGhXaXRoTWFyZ2luKTtcbiAgICAgIGlmICh0aGlzLmNoZWNrSXNIaWRlU2xpZGVyKCkpIHtcbiAgICAgICAgbmV3TWluID0gMDtcbiAgICAgICAgbmV3TWF4ID0gTWF0aC5tYXgobmV3TWluLCB0aGlzLkxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgICAgdGhpcy50dXJuT2ZSZXNpemVGb3JPbmVTZXRWYWx1ZSA9IHRydWU7XG4gICAgICB0aGlzLnNsaWRlci5zZXRWYWx1ZXMoMCwgdGhpcy5MZW5ndGgsXG4gICAgICAgIG5ld01pbiwgbmV3TWF4KTtcbiAgICB9XG4gIH1cblxuICAvKiogSGFuZGxlciBvZiBwcm9wZXJ0eSBjaGFuZ2UgZXZlbnRzLiAqL1xuICBwdWJsaWMgb3ZlcnJpZGUgb25Qcm9wZXJ0eUNoYW5nZWQocHJvcGVydHk6IERHLlByb3BlcnR5KTogdm9pZCB7XG4gICAgc3VwZXIub25Qcm9wZXJ0eUNoYW5nZWQocHJvcGVydHkpO1xuXG4gICAgc3dpdGNoIChwcm9wZXJ0eS5uYW1lKSB7XG4gICAgY2FzZSAnc2VxdWVuY2VDb2x1bW5OYW1lJzpcbiAgICAgIHRoaXMudXBkYXRlU2VxQ29sKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdzdGFydFBvc2l0aW9uTmFtZSc6XG4gICAgICB0aGlzLnVwZGF0ZVNlcUNvbCgpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZW5kUG9zaXRpb25OYW1lJzpcbiAgICAgIHRoaXMudXBkYXRlU2VxQ29sKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwb3NpdGlvbldpZHRoJzpcbiAgICAgIHRoaXMuX3Bvc2l0aW9uV2lkdGggPSB0aGlzLnBvc2l0aW9uV2lkdGg7XG4gICAgICB0aGlzLnVwZGF0ZVNsaWRlcigpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZml4V2lkdGgnOlxuICAgICAgdGhpcy51cGRhdGVTbGlkZXIoKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2ZpdEFyZWEnOlxuICAgICAgdGhpcy51cGRhdGVTbGlkZXIoKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3Nocmlua0VtcHR5VGFpbCc6XG4gICAgICB0aGlzLnVwZGF0ZVBvc2l0aW9ucygpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnc2tpcEVtcHR5UG9zaXRpb25zJzpcbiAgICAgIHRoaXMudXBkYXRlUG9zaXRpb25zKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdwb3NpdGlvbk1hcmdpbic6XG4gICAgICB0aGlzLnVwZGF0ZVNsaWRlcigpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdGhpcy5yZW5kZXIodHJ1ZSk7XG4gIH1cblxuICAvKiogQWRkIGZpbHRlciBoYW5kbGVycyB3aGVuIHRhYmxlIGlzIGEgYXR0YWNoZWQgICovXG4gIHB1YmxpYyBvdmVycmlkZSBvblRhYmxlQXR0YWNoZWQoKSB7XG4gICAgc3VwZXIub25UYWJsZUF0dGFjaGVkKCk7XG5cbiAgICBjb25zdCBkYXRhRnJhbWVUeHQ6IHN0cmluZyA9IHRoaXMuZGF0YUZyYW1lID8gJ2RhdGEnIDogJ251bGwnO1xuICAgIGNvbnNvbGUuZGVidWcoYGJpbzogV2ViTG9nbzwke3RoaXMudmlld2VySWR9Pi5vblRhYmxlQXR0YWNoZWQoIGRhdGFGcmFtZSA9ICR7ZGF0YUZyYW1lVHh0fSApIHN0YXJ0YCk7XG5cbiAgICB0aGlzLnVwZGF0ZVNlcUNvbCgpO1xuXG4gICAgaWYgKHRoaXMuZGF0YUZyYW1lICE9PSB2b2lkIDApIHtcbiAgICAgIHRoaXMuc3Vicy5wdXNoKHRoaXMuZGF0YUZyYW1lLnNlbGVjdGlvbi5vbkNoYW5nZWQuc3Vic2NyaWJlKChfKSA9PiB0aGlzLnJlbmRlcigpKSk7XG4gICAgICB0aGlzLnN1YnMucHVzaCh0aGlzLmRhdGFGcmFtZS5maWx0ZXIub25DaGFuZ2VkLnN1YnNjcmliZSgoXykgPT4ge1xuICAgICAgICB0aGlzLnVwZGF0ZVBvc2l0aW9ucygpO1xuICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgfSkpO1xuICAgIH1cblxuICAgIHRoaXMuaW5pdCgpO1xuICAgIGNvbnNvbGUuZGVidWcoYGJpbzogV2ViTG9nbzwke3RoaXMudmlld2VySWR9Pi5vblRhYmxlQXR0YWNoZWQoKSBlbmRgKTtcbiAgfVxuXG4gIC8qKiBSZW1vdmUgYWxsIGhhbmRsZXJzIHdoZW4gdGFibGUgaXMgYSBkZXRhY2ggICovXG4gIHB1YmxpYyBvdmVycmlkZSBhc3luYyBkZXRhY2goKSB7XG4gICAgY29uc3QgZGF0YUZyYW1lVHh0ID0gYCR7dGhpcy5kYXRhRnJhbWUgPyAnZGF0YScgOiAnbnVsbCd9YDtcbiAgICBjb25zb2xlLmRlYnVnKGBiaW86IFdlYkxvZ288JHt0aGlzLnZpZXdlcklkfT4ub25UYWJsZUF0dGFjaGVkKCBkYXRhRnJhbWUgPSAke2RhdGFGcmFtZVR4dH0gKSBzdGFydGApO1xuICAgIHN1cGVyLmRldGFjaCgpO1xuXG4gICAgdGhpcy52aWV3U3Vicy5mb3JFYWNoKChzdWIpID0+IHN1Yi51bnN1YnNjcmliZSgpKTtcbiAgICB0aGlzLmhvc3QhLnJlbW92ZSgpO1xuICAgIHRoaXMubXNnSG9zdCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmhvc3QgPSB1bmRlZmluZWQ7XG5cbiAgICB0aGlzLmluaXRpYWxpemVkID0gZmFsc2U7XG4gICAgY29uc29sZS5kZWJ1ZyhgYmlvOiBXZWJMb2dvPCR7dGhpcy52aWV3ZXJJZH0+Lm9uVGFibGVBdHRhY2hlZCgpIGVuZGApO1xuICB9XG5cbiAgLyoqIEhlbHBlciBmdW5jdGlvbiBmb3IgcmVuZGVyaW5nICovXG4gIHByb3RlY3RlZCBfbnVsbFNlcXVlbmNlKGZpbGxlclJlc2lkdWUgPSAnWCcpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5za2lwRW1wdHlTZXF1ZW5jZXMpXG4gICAgICByZXR1cm4gbmV3IEFycmF5KHRoaXMuTGVuZ3RoKS5maWxsKGZpbGxlclJlc2lkdWUpLmpvaW4oJycpO1xuXG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgLyoqIEhlbHBlciBmdW5jdGlvbiBmb3IgcmVtb3ZlIGVtcHR5IHBvc2l0aW9ucyAqL1xuICAvLyBUT0RPOiB1c2UgdGhpcyBmdW5jdGlvbiBpbiBmcm9tIGNvcmVcbiAgcHJvdGVjdGVkIHJlbW92ZVdoZXJlKGFycmF5OiBBcnJheTxhbnk+LCBwcmVkaWNhdGU6IChUOiBhbnkpID0+IGJvb2xlYW4pOiBBcnJheTxhbnk+IHtcbiAgICBsZXQgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICAgIGxldCB1cGRhdGVJdGVyYXRvciA9IDA7XG4gICAgZm9yIChsZXQgZGVsZXRlSXRlcmF0b3IgPSAwOyBkZWxldGVJdGVyYXRvciA8IGxlbmd0aDsgZGVsZXRlSXRlcmF0b3IrKykge1xuICAgICAgaWYgKCFwcmVkaWNhdGUoYXJyYXlbZGVsZXRlSXRlcmF0b3JdKSkge1xuICAgICAgICBhcnJheVt1cGRhdGVJdGVyYXRvcl0gPSBhcnJheVtkZWxldGVJdGVyYXRvcl07XG4gICAgICAgIHVwZGF0ZUl0ZXJhdG9yKys7XG4gICAgICB9XG4gICAgfVxuICAgIGFycmF5Lmxlbmd0aCA9IHVwZGF0ZUl0ZXJhdG9yO1xuICAgIHJldHVybiBhcnJheTtcbiAgfVxuXG5cbiAgLyoqIEZ1bmN0aW9uIGZvciByZW1vdmluZyBlbXB0eSBwb3NpdGlvbnMgKi9cbiAgcHJvdGVjdGVkIF9yZW1vdmVFbXB0eVBvc2l0aW9ucygpIHtcbiAgICBpZiAodGhpcy5za2lwRW1wdHlQb3NpdGlvbnMpIHtcbiAgICAgIHRoaXMucmVtb3ZlV2hlcmUodGhpcy5wb3NpdGlvbnMsIGl0ZW0gPT4gaXRlbT8uZnJlcVsnLSddPy5jb3VudCA9PT0gaXRlbS5yb3dDb3VudCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF9jYWxjdWxhdGUocjogbnVtYmVyKSB7XG4gICAgaWYgKCF0aGlzLmhvc3QgfHwgIXRoaXMuc2VxQ29sIHx8ICF0aGlzLmRhdGFGcmFtZSlcbiAgICAgIHJldHVybjtcbiAgICB0aGlzLnVuaXRzSGFuZGxlciA9IG5ldyBVbml0c0hhbmRsZXIodGhpcy5zZXFDb2wpO1xuXG4gICAgdGhpcy5jYWxjU2l6ZSgpO1xuXG4gICAgdGhpcy5wb3NpdGlvbnMgPSBuZXcgQXJyYXkodGhpcy5zdGFydFBvc2l0aW9uIDw9IHRoaXMuZW5kUG9zaXRpb24gPyB0aGlzLmVuZFBvc2l0aW9uIC0gdGhpcy5zdGFydFBvc2l0aW9uICsgMSA6IDApO1xuICAgIGZvciAobGV0IGpQb3MgPSAwOyBqUG9zIDwgdGhpcy5MZW5ndGg7IGpQb3MrKykge1xuICAgICAgY29uc3QgcG9zTmFtZTogc3RyaW5nID0gdGhpcy5wb3NpdGlvbk5hbWVzW3RoaXMuc3RhcnRQb3NpdGlvbiArIGpQb3NdO1xuICAgICAgdGhpcy5wb3NpdGlvbnNbalBvc10gPSBuZXcgUG9zaXRpb25JbmZvKHBvc05hbWUpO1xuICAgIH1cblxuICAgIC8vIDIwMjItMDUtMDUgYXNrYWxraW4gaW5zdHJ1Y3RlZCB0byBzaG93IFdlYkxvZ28gYmFzZWQgb24gZmlsdGVyIChub3Qgc2VsZWN0aW9uKVxuICAgIGNvbnN0IGluZGljZXMgPSB0aGlzLmRhdGFGcmFtZS5maWx0ZXIuZ2V0U2VsZWN0ZWRJbmRleGVzKCk7XG4gICAgLy8gY29uc3QgaW5kaWNlcyA9IHRoaXMuZGF0YUZyYW1lLnNlbGVjdGlvbi50cnVlQ291bnQgPiAwID8gdGhpcy5kYXRhRnJhbWUuc2VsZWN0aW9uLmdldFNlbGVjdGVkSW5kZXhlcygpIDpcbiAgICAvLyAgIHRoaXMuZGF0YUZyYW1lLmZpbHRlci5nZXRTZWxlY3RlZEluZGV4ZXMoKTtcblxuICAgIHRoaXMucm93c01hc2tlZCA9IGluZGljZXMubGVuZ3RoO1xuICAgIHRoaXMucm93c051bGwgPSAwO1xuXG4gICAgZm9yIChjb25zdCBpIG9mIGluZGljZXMpIHtcbiAgICAgIGxldCBzOiBzdHJpbmcgPSA8c3RyaW5nPih0aGlzLnNlcUNvbC5nZXQoaSkpO1xuXG4gICAgICBpZiAoIXMpIHtcbiAgICAgICAgcyA9IHRoaXMuX251bGxTZXF1ZW5jZSgpO1xuICAgICAgICArK3RoaXMucm93c051bGw7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNlcU06IHN0cmluZ1tdID0gdGhpcy5zcGxpdHRlciEocyk7XG4gICAgICBmb3IgKGxldCBqUG9zID0gMDsgalBvcyA8IHRoaXMuTGVuZ3RoOyBqUG9zKyspIHtcbiAgICAgICAgY29uc3QgcG1JbmZvID0gdGhpcy5wb3NpdGlvbnNbalBvc10uZnJlcTtcbiAgICAgICAgY29uc3QgbTogc3RyaW5nID0gc2VxTVt0aGlzLnN0YXJ0UG9zaXRpb24gKyBqUG9zXSB8fCAnLSc7XG4gICAgICAgIGlmICghKG0gaW4gcG1JbmZvKSlcbiAgICAgICAgICBwbUluZm9bbV0gPSBuZXcgUG9zaXRpb25Nb25vbWVySW5mbygpO1xuICAgICAgICBwbUluZm9bbV0uY291bnQrKztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyNyZWdpb24gUG9saXNoIGZyZXEgY291bnRzXG4gICAgZm9yIChsZXQgalBvcyA9IDA7IGpQb3MgPCB0aGlzLkxlbmd0aDsgalBvcysrKSB7XG4gICAgICAvLyBkZWxldGUgdGhpcy5wb3NpdGlvbnNbalBvc10uZnJlcVsnLSddO1xuXG4gICAgICB0aGlzLnBvc2l0aW9uc1tqUG9zXS5yb3dDb3VudCA9IDA7XG4gICAgICBmb3IgKGNvbnN0IG0gaW4gdGhpcy5wb3NpdGlvbnNbalBvc10uZnJlcSlcbiAgICAgICAgdGhpcy5wb3NpdGlvbnNbalBvc10ucm93Q291bnQgKz0gdGhpcy5wb3NpdGlvbnNbalBvc10uZnJlcVttXS5jb3VudDtcbiAgICAgIGlmICh0aGlzLnBvc2l0aW9uSGVpZ2h0ID09IFBvc2l0aW9uSGVpZ2h0LkVudHJvcHkpIHtcbiAgICAgICAgdGhpcy5wb3NpdGlvbnNbalBvc10uc3VtRm9ySGVpZ2h0Q2FsYyA9IDA7XG4gICAgICAgIGZvciAoY29uc3QgbSBpbiB0aGlzLnBvc2l0aW9uc1tqUG9zXS5mcmVxKSB7XG4gICAgICAgICAgY29uc3QgcG4gPSB0aGlzLnBvc2l0aW9uc1tqUG9zXS5mcmVxW21dLmNvdW50IC8gdGhpcy5wb3NpdGlvbnNbalBvc10ucm93Q291bnQ7XG4gICAgICAgICAgdGhpcy5wb3NpdGlvbnNbalBvc10uc3VtRm9ySGVpZ2h0Q2FsYyArPSAtcG4gKiBNYXRoLmxvZzIocG4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8vI2VuZHJlZ2lvblxuICAgIHRoaXMuX3JlbW92ZUVtcHR5UG9zaXRpb25zKCk7XG5cbiAgICBjb25zdCBhYnNvbHV0ZU1heEhlaWdodCA9IHRoaXMuY2FudmFzLmhlaWdodCAtIHRoaXMuYXhpc0hlaWdodCAqIHI7XG5cbiAgICAvLyNyZWdpb24gQ2FsY3VsYXRlIHNjcmVlblxuICAgIGZvciAobGV0IGpQb3MgPSAwOyBqUG9zIDwgdGhpcy5MZW5ndGg7IGpQb3MrKykge1xuICAgICAgY29uc3QgZnJlcTogeyBbYzogc3RyaW5nXTogUG9zaXRpb25Nb25vbWVySW5mbyB9ID0gdGhpcy5wb3NpdGlvbnNbalBvc10uZnJlcTtcbiAgICAgIGNvbnN0IHJvd0NvdW50ID0gdGhpcy5wb3NpdGlvbnNbalBvc10ucm93Q291bnQ7XG4gICAgICBjb25zdCBhbHBoYWJldFNpemUgPSB0aGlzLmdldEFscGhhYmV0U2l6ZSgpO1xuICAgICAgaWYgKCh0aGlzLnBvc2l0aW9uSGVpZ2h0ID09IFBvc2l0aW9uSGVpZ2h0LkVudHJvcHkpICYmIChhbHBoYWJldFNpemUgPT0gbnVsbCkpIHtcbiAgICAgICAgZ3Jvay5zaGVsbC5lcnJvcignV2ViTG9nbzogYWxwaGFiZXQgaXMgdW5kZWZpbmVkLicpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtYXhIZWlnaHQgPSAodGhpcy5wb3NpdGlvbkhlaWdodCA9PSBQb3NpdGlvbkhlaWdodC5FbnRyb3B5KSA/IChhYnNvbHV0ZU1heEhlaWdodCAqIChNYXRoLmxvZzIoYWxwaGFiZXRTaXplKSAtICh0aGlzLnBvc2l0aW9uc1tqUG9zXS5zdW1Gb3JIZWlnaHRDYWxjKSkgLyBNYXRoLmxvZzIoYWxwaGFiZXRTaXplKSkgOiBhYnNvbHV0ZU1heEhlaWdodDtcblxuICAgICAgbGV0IHk6IG51bWJlciA9IHRoaXMuYXhpc0hlaWdodCAqIHIgKyAoYWJzb2x1dGVNYXhIZWlnaHQgLSBtYXhIZWlnaHQgLSAxKTtcblxuICAgICAgY29uc3QgZW50cmllcyA9IE9iamVjdC5lbnRyaWVzKGZyZXEpLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgaWYgKGFbMF0gIT09ICctJyAmJiBiWzBdICE9PSAnLScpXG4gICAgICAgICAgcmV0dXJuIGJbMV0uY291bnQgLSBhWzFdLmNvdW50O1xuICAgICAgICBlbHNlIGlmIChhWzBdID09PSAnLScgJiYgYlswXSA9PT0gJy0nKVxuICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICBlbHNlIGlmIChhWzBdID09PSAnLScpXG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICBlbHNlIC8qIChiWzBdID09PSAnLScpICovXG4gICAgICAgICAgcmV0dXJuICsxO1xuICAgICAgfSk7XG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgICAgY29uc3QgcG1JbmZvOiBQb3NpdGlvbk1vbm9tZXJJbmZvID0gZW50cnlbMV07XG4gICAgICAgIC8vIGNvbnN0IG06IHN0cmluZyA9IGVudHJ5WzBdO1xuICAgICAgICBjb25zdCBoOiBudW1iZXIgPSBtYXhIZWlnaHQgKiBwbUluZm8uY291bnQgLyByb3dDb3VudDtcblxuICAgICAgICBwbUluZm8uYm91bmRzID0gbmV3IERHLlJlY3QoalBvcyAqIHRoaXMucG9zaXRpb25XaWR0aFdpdGhNYXJnaW4sIHksIHRoaXMuX3Bvc2l0aW9uV2lkdGgsIGgpO1xuICAgICAgICB5ICs9IGg7XG4gICAgICB9XG4gICAgfVxuICAgIC8vI2VuZHJlZ2lvblxuXG4gIH1cblxuICAvKiogUmVuZGVyIFdlYkxvZ28gc2Vuc2l0aXZlIHRvIGNoYW5nZXMgaW4gcGFyYW1zIG9mIHJlbmRlcmluZ1xuICAgKkBwYXJhbSB7Ym9vbGVhbn0gcmVjYWxjIC0gaW5kaWNhdGVzIHRoYXQgbmVlZCB0byByZWNhbGN1bGF0ZSBkYXRhIGZvciByZW5kZXJpbmdcbiAgICovXG4gIHJlbmRlcihyZWNhbGMgPSB0cnVlKSB7XG4gICAgaWYgKHRoaXMubXNnSG9zdCkge1xuICAgICAgaWYgKHRoaXMuc2VxQ29sICYmICF0aGlzLmNwKSB7XG4gICAgICAgIHRoaXMubXNnSG9zdCEuaW5uZXJUZXh0ID0gYFVua25vd24gcGFsZXR0ZSAoY29sdW1uIHNlbVR5cGU6ICcke3RoaXMuc2VxQ29sLnNlbVR5cGV9JykuYDtcbiAgICAgICAgdGhpcy5tc2dIb3N0IS5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm1zZ0hvc3QhLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnNlcUNvbCB8fCAhdGhpcy5kYXRhRnJhbWUgfHwgIXRoaXMuY3AgfHwgdGhpcy5zdGFydFBvc2l0aW9uID09PSAtMSB8fCB0aGlzLmVuZFBvc2l0aW9uID09PSAtMSB8fCB0aGlzLmhvc3QgPT0gbnVsbCB8fCB0aGlzLnNsaWRlciA9PSBudWxsKVxuICAgICAgcmV0dXJuO1xuXG4gICAgY29uc3QgZyA9IHRoaXMuY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgaWYgKCFnKSByZXR1cm47XG5cbiAgICB0aGlzLnNsaWRlci5yb290LnN0eWxlLndpZHRoID0gYCR7dGhpcy5ob3N0LmNsaWVudFdpZHRofXB4YDtcblxuICAgIGNvbnN0IHIgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcblxuICAgIGlmIChyZWNhbGMpXG4gICAgICB0aGlzLl9jYWxjdWxhdGUocik7XG5cbiAgICBnLnJlc2V0VHJhbnNmb3JtKCk7XG4gICAgZy5maWxsU3R5bGUgPSBERy5Db2xvci50b0h0bWwodGhpcy5iYWNrZ3JvdW5kQ29sb3IpO1xuICAgIGcuZmlsbFJlY3QoMCwgMCwgdGhpcy5jYW52YXMud2lkdGgsIHRoaXMuY2FudmFzLmhlaWdodCk7XG4gICAgZy50ZXh0QmFzZWxpbmUgPSB0aGlzLnRleHRCYXNlbGluZTtcblxuICAgIGNvbnN0IG1heENvdW50T2ZSb3dzUmVuZGVyZWQgPSB0aGlzLmNvdW50T2ZSZW5kZXJQb3NpdGlvbnMgKyAxO1xuICAgIGNvbnN0IGZpcnN0VmlzaWJsZUluZGV4ID0gKHRoaXMudmlzaWJsZVNsaWRlcikgPyBNYXRoLmZsb29yKHRoaXMuc2xpZGVyLm1pbikgOiAwO1xuICAgIGNvbnN0IGxhc3RWaXNpYmxlSW5kZXggPSBNYXRoLm1pbih0aGlzLkxlbmd0aCwgZmlyc3RWaXNpYmxlSW5kZXggKyBtYXhDb3VudE9mUm93c1JlbmRlcmVkKTtcblxuICAgIC8vI3JlZ2lvbiBQbG90IHBvc2l0aW9uTmFtZXNcbiAgICBjb25zdCBwb3NpdGlvbkZvbnRTaXplID0gMTAgKiByO1xuICAgIGcucmVzZXRUcmFuc2Zvcm0oKTtcbiAgICBnLmZpbGxTdHlsZSA9ICdibGFjayc7XG4gICAgZy50ZXh0QWxpZ24gPSAnY2VudGVyJztcbiAgICBnLmZvbnQgPSBgJHtwb3NpdGlvbkZvbnRTaXplLnRvRml4ZWQoMSl9cHggUm9ib3RvLCBSb2JvdG8gTG9jYWwsIHNhbnMtc2VyaWZgO1xuICAgIGNvbnN0IHBvc05hbWVNYXhXaWR0aCA9IE1hdGgubWF4KC4uLnRoaXMucG9zaXRpb25zLm1hcCgocG9zKSA9PiBnLm1lYXN1cmVUZXh0KHBvcy5uYW1lKS53aWR0aCkpO1xuICAgIGNvbnN0IGhTY2FsZSA9IHBvc05hbWVNYXhXaWR0aCA8ICh0aGlzLl9wb3NpdGlvbldpZHRoIC0gMikgPyAxIDogKHRoaXMuX3Bvc2l0aW9uV2lkdGggLSAyKSAvIHBvc05hbWVNYXhXaWR0aDtcblxuICAgIGZvciAobGV0IGpQb3MgPSB0aGlzLmZpcnN0VmlzaWJsZUluZGV4OyBqUG9zIDwgbGFzdFZpc2libGVJbmRleDsgalBvcysrKSB7XG4gICAgICBjb25zdCBwb3M6IFBvc2l0aW9uSW5mbyA9IHRoaXMucG9zaXRpb25zW2pQb3NdO1xuICAgICAgZy5yZXNldFRyYW5zZm9ybSgpO1xuICAgICAgZy5zZXRUcmFuc2Zvcm0oXG4gICAgICAgIGhTY2FsZSwgMCwgMCwgMSxcbiAgICAgICAgalBvcyAqIHRoaXMucG9zaXRpb25XaWR0aFdpdGhNYXJnaW4gKyB0aGlzLl9wb3NpdGlvbldpZHRoIC8gMiAtIHRoaXMucG9zaXRpb25XaWR0aFdpdGhNYXJnaW4gKiBmaXJzdFZpc2libGVJbmRleCwgMCk7XG4gICAgICBnLmZpbGxUZXh0KHBvcy5uYW1lLCAwLCAwKTtcbiAgICB9XG4gICAgLy8jZW5kcmVnaW9uIFBsb3QgcG9zaXRpb25OYW1lc1xuICAgIGNvbnN0IGZvbnRTdHlsZSA9ICcxNnB4IFJvYm90bywgUm9ib3RvIExvY2FsLCBzYW5zLXNlcmlmJztcbiAgICAvLyBIYWNrcyB0byBzY2FsZSB1cHBlcmNhc2UgY2hhcmFjdGVycyB0byB0YXJnZXQgcmVjdGFuZ2xlXG4gICAgY29uc3QgdXBwZXJjYXNlTGV0dGVyQXNjZW50ID0gMC4yNTtcbiAgICBjb25zdCB1cHBlcmNhc2VMZXR0ZXJIZWlnaHQgPSAxMi4yO1xuICAgIGZvciAobGV0IGpQb3MgPSB0aGlzLmZpcnN0VmlzaWJsZUluZGV4OyBqUG9zIDwgbGFzdFZpc2libGVJbmRleDsgalBvcysrKSB7XG4gICAgICBmb3IgKGNvbnN0IFttb25vbWVyLCBwbUluZm9dIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMucG9zaXRpb25zW2pQb3NdLmZyZXEpKSB7XG4gICAgICAgIGlmIChtb25vbWVyICE9PSAnLScpIHtcbiAgICAgICAgICBjb25zdCBtb25vbWVyVHh0ID0gbW9ub21lclRvU2hvcnQobW9ub21lciwgNSk7XG4gICAgICAgICAgY29uc3QgYiA9IHBtSW5mby5ib3VuZHM7XG4gICAgICAgICAgY29uc3QgbGVmdCA9IGIubGVmdCAtIHRoaXMucG9zaXRpb25XaWR0aFdpdGhNYXJnaW4gKiB0aGlzLmZpcnN0VmlzaWJsZUluZGV4O1xuXG4gICAgICAgICAgZy5yZXNldFRyYW5zZm9ybSgpO1xuICAgICAgICAgIGcuc3Ryb2tlU3R5bGUgPSAnbGlnaHRncmF5JztcbiAgICAgICAgICBnLmxpbmVXaWR0aCA9IDE7XG4gICAgICAgICAgZy5yZWN0KGxlZnQsIGIudG9wLCBiLndpZHRoLCBiLmhlaWdodCk7XG4gICAgICAgICAgZy5maWxsU3R5bGUgPSB0aGlzLmNwLmdldChtb25vbWVyKSA/PyB0aGlzLmNwLmdldCgnb3RoZXInKTtcbiAgICAgICAgICBnLnRleHRBbGlnbiA9ICdsZWZ0JztcbiAgICAgICAgICBnLmZvbnQgPSBmb250U3R5bGU7XG4gICAgICAgICAgLy9nLmZpbGxSZWN0KGIubGVmdCwgYi50b3AsIGIud2lkdGgsIGIuaGVpZ2h0KTtcbiAgICAgICAgICBjb25zdCBtVG06IFRleHRNZXRyaWNzID0gZy5tZWFzdXJlVGV4dChtb25vbWVyVHh0KTtcblxuICAgICAgICAgIGcuc2V0VHJhbnNmb3JtKFxuICAgICAgICAgICAgYi53aWR0aCAvIG1UbS53aWR0aCwgMCwgMCwgYi5oZWlnaHQgLyB1cHBlcmNhc2VMZXR0ZXJIZWlnaHQsXG4gICAgICAgICAgICBsZWZ0LCBiLnRvcCk7XG4gICAgICAgICAgZy5maWxsVGV4dChtb25vbWVyVHh0LCAwLCAtdXBwZXJjYXNlTGV0dGVyQXNjZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKiBDYWxjdWxhdGUgY2FudmFzIHNpemUgYW4gcG9zaXRpb25XaWR0aCBhbmQgdXBkYXRlcyBwcm9wZXJ0aWVzICovXG4gIHByaXZhdGUgY2FsY1NpemUoKSB7XG4gICAgaWYgKCF0aGlzLmhvc3QpXG4gICAgICByZXR1cm47XG5cbiAgICBjb25zdCByOiBudW1iZXIgPSB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcblxuICAgIGxldCB3aWR0aDogbnVtYmVyID0gdGhpcy53aWR0aEFyZWE7XG4gICAgbGV0IGhlaWdodCA9IHRoaXMuaGVpZ2h0QXJlYTtcblxuICAgIGlmICgodGhpcy5maXRBcmVhKSAmJiAoIXRoaXMudmlzaWJsZVNsaWRlcikpIHtcbiAgICAgIGNvbnN0IHNjYWxlID0gTWF0aC5tYXgoMSwgTWF0aC5taW4odGhpcy54U2NhbGUsIHRoaXMueVNjYWxlKSk7XG4gICAgICB3aWR0aCA9IHdpZHRoICogc2NhbGU7XG4gICAgICBoZWlnaHQgPSBoZWlnaHQgKiBzY2FsZTtcbiAgICAgIHRoaXMuX3Bvc2l0aW9uV2lkdGggPSB0aGlzLnBvc2l0aW9uV2lkdGggKiBzY2FsZTtcbiAgICB9XG5cbiAgICB3aWR0aCA9IHRoaXMuTGVuZ3RoICogdGhpcy5wb3NpdGlvbldpZHRoV2l0aE1hcmdpbiAvIHI7XG5cbiAgICB0aGlzLmNhbnZhcy53aWR0aCA9IHRoaXMucm9vdC5jbGllbnRXaWR0aCAqIHI7XG4gICAgdGhpcy5jYW52YXMuc3R5bGUud2lkdGggPSBgJHt0aGlzLnJvb3QuY2xpZW50V2lkdGh9cHhgO1xuXG4gICAgLy8gY29uc3QgY2FudmFzSGVpZ2h0OiBudW1iZXIgPSB3aWR0aCA+IHRoaXMucm9vdC5jbGllbnRXaWR0aCA/IGhlaWdodCAtIDggOiBoZWlnaHQ7XG4gICAgdGhpcy5ob3N0LnN0eWxlLnNldFByb3BlcnR5KCdoZWlnaHQnLCBgJHtoZWlnaHR9cHhgKTtcbiAgICBjb25zdCBjYW52YXNIZWlnaHQ6IG51bWJlciA9IHRoaXMuaG9zdC5jbGllbnRIZWlnaHQ7XG4gICAgdGhpcy5jYW52YXMuaGVpZ2h0ID0gY2FudmFzSGVpZ2h0ICogcjtcblxuICAgIC8vIEFkanVzdCBob3N0IGFuZCByb290IHdpZHRoXG4gICAgaWYgKHRoaXMuZml4V2lkdGgpIHtcbiAgICAgIC8vIGZ1bGwgd2lkdGggZm9yIGNhbnZhcyBob3N0IGFuZCByb290XG4gICAgICB0aGlzLnJvb3Quc3R5bGUud2lkdGggPSB0aGlzLmhvc3Quc3R5bGUud2lkdGggPSBgJHt3aWR0aH1weGA7XG4gICAgICB0aGlzLnJvb3Quc3R5bGUuaGVpZ2h0ID0gYCR7aGVpZ2h0fXB4YDtcbiAgICAgIHRoaXMucm9vdC5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nO1xuICAgICAgdGhpcy5ob3N0LnN0eWxlLnNldFByb3BlcnR5KCdvdmVyZmxvdy15JywgJ2hpZGRlbicsICdpbXBvcnRhbnQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gYWxsb3cgc2Nyb2xsIGNhbnZhcyBpbiByb290XG4gICAgICB0aGlzLnJvb3Quc3R5bGUud2lkdGggPSB0aGlzLmhvc3Quc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gICAgICB0aGlzLmhvc3Quc3R5bGUub3ZlcmZsb3dYID0gJ2F1dG8haW1wb3J0YW50JztcbiAgICAgIHRoaXMuaG9zdC5zdHlsZS5zZXRQcm9wZXJ0eSgndGV4dC1hbGlnbicsIHRoaXMuaG9yaXpvbnRhbEFsaWdubWVudCk7XG5cbiAgICAgIGNvbnN0IHNsaWRlckhlaWdodCA9IHRoaXMudmlzaWJsZVNsaWRlciA/IDEwIDogMDtcblxuICAgICAgLy8gdmVydGljYWwgYWxpZ25tZW50XG4gICAgICBsZXQgaG9zdFRvcE1hcmdpbiA9IDA7XG4gICAgICBzd2l0Y2ggKHRoaXMudmVydGljYWxBbGlnbm1lbnQpIHtcbiAgICAgIGNhc2UgJ3RvcCc6XG4gICAgICAgIGhvc3RUb3BNYXJnaW4gPSAwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ21pZGRsZSc6XG4gICAgICAgIGhvc3RUb3BNYXJnaW4gPSBNYXRoLm1heCgwLCAodGhpcy5yb290LmNsaWVudEhlaWdodCAtIGhlaWdodCkgLyAyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICBob3N0VG9wTWFyZ2luID0gTWF0aC5tYXgoMCwgdGhpcy5yb290LmNsaWVudEhlaWdodCAtIGhlaWdodCAtIHNsaWRlckhlaWdodCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgLy8gaG9yaXpvbnRhbCBhbGlnbm1lbnRcbiAgICAgIGxldCBob3N0TGVmdE1hcmdpbiA9IDA7XG4gICAgICBzd2l0Y2ggKHRoaXMuaG9yaXpvbnRhbEFsaWdubWVudCkge1xuICAgICAgY2FzZSAnbGVmdCc6XG4gICAgICAgIGhvc3RMZWZ0TWFyZ2luID0gMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjZW50ZXInOlxuICAgICAgICBob3N0TGVmdE1hcmdpbiA9IE1hdGgubWF4KDAsICh0aGlzLnJvb3QuY2xpZW50V2lkdGggLSB3aWR0aCkgLyAyKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgIGhvc3RMZWZ0TWFyZ2luID0gTWF0aC5tYXgoMCwgdGhpcy5yb290LmNsaWVudFdpZHRoIC0gd2lkdGgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHRoaXMuaG9zdC5zdHlsZS5zZXRQcm9wZXJ0eSgnbWFyZ2luLXRvcCcsIGAke2hvc3RUb3BNYXJnaW59cHhgLCAnaW1wb3J0YW50Jyk7XG4gICAgICB0aGlzLmhvc3Quc3R5bGUuc2V0UHJvcGVydHkoJ21hcmdpbi1sZWZ0JywgYCR7aG9zdExlZnRNYXJnaW59cHhgLCAnaW1wb3J0YW50Jyk7XG4gICAgICBpZiAodGhpcy5zbGlkZXIgIT0gbnVsbCkge1xuICAgICAgICB0aGlzLnNsaWRlci5yb290LnN0eWxlLnNldFByb3BlcnR5KCdtYXJnaW4tdG9wJywgYCR7aG9zdFRvcE1hcmdpbiArIGNhbnZhc0hlaWdodH1weGAsICdpbXBvcnRhbnQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucm9vdC5jbGllbnRIZWlnaHQgPD0gaGVpZ2h0KSB7XG4gICAgICAgIHRoaXMuaG9zdC5zdHlsZS5zZXRQcm9wZXJ0eSgnaGVpZ2h0JywgYCR7dGhpcy5yb290LmNsaWVudEhlaWdodH1weGApO1xuICAgICAgICB0aGlzLmhvc3Quc3R5bGUuc2V0UHJvcGVydHkoJ292ZXJmbG93LXknLCBudWxsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaG9zdC5zdHlsZS5zZXRQcm9wZXJ0eSgnb3ZlcmZsb3cteScsICdoaWRkZW4nLCAnaW1wb3J0YW50Jyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldEFscGhhYmV0U2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnVuaXRzSGFuZGxlcj8uZ2V0QWxwaGFiZXRTaXplKCkgPz8gMDtcbiAgfVxufVxuIl19