@oathompsonjones/mini-games 1.0.7 → 1.0.9

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/TODO.md ADDED
@@ -0,0 +1,6 @@
1
+ [ ] Write this program in Rust (faster + I should learn it).
2
+ The rust program should have a few modes:
3
+ - [ ] CPU vs CPU
4
+ - [ ] Human vs CPU
5
+ - [ ] Human vs human
6
+ - [ ] Find optimal move (this will take in a game state, then calculate the most optimal move for the next player)
@@ -1,4 +1,5 @@
1
1
  import type BitBoard from "../bitBoard/bitBoard.js";
2
+ import LongInt from "../bitBoard/longInt.js";
2
3
  export type Position = {
3
4
  y: number;
4
5
  x: number;
@@ -17,14 +18,17 @@ export declare const enum GridLines {
17
18
  TBottom = "\u2534",
18
19
  Cross = "\u253C"
19
20
  }
20
- /** Represents a game board. */
21
- export default abstract class Board<T extends BitBoard = BitBoard> {
21
+ /**
22
+ * Represents a game board.
23
+ * @template T - The type of the numeric data.
24
+ */
25
+ export default abstract class Board<T extends LongInt | number> {
22
26
  /** Contains the data stored in a BitBoard. */
23
- protected readonly bitBoard: T;
24
- /** The width of the board. */
25
- protected readonly boardWidth: number;
26
- /** The height of the board. */
27
- protected readonly boardHeight: number;
27
+ protected readonly bitBoard: BitBoard<T>;
28
+ /** The width of the game board. */
29
+ protected readonly width: number;
30
+ /** The height of the game board. */
31
+ protected readonly height: number;
28
32
  /** A stack of moves. */
29
33
  protected readonly moves: number[];
30
34
  /** How many boards there are representing player positions (most likely 2). */
@@ -32,91 +36,102 @@ export default abstract class Board<T extends BitBoard = BitBoard> {
32
36
  /** Number of boards in total (most likely also 2). */
33
37
  private readonly numberOfBoards;
34
38
  /** The board states which represent a winning state. */
35
- protected abstract readonly winningStates: T[];
39
+ protected abstract readonly winningStates: Array<BitBoard<T>>;
36
40
  /**
37
41
  * Creates an instance of Board.
38
- * @param width The width of the board.
39
- * @param height The height of the board.
40
- * @param playerBoardCount How many boards there are representing player positions (most likely 2).
41
- * @param extraBoardCount Number of extra boards (most likely 0).
42
+ * @param width - The width of the game board.
43
+ * @param height - The height of the game board.
44
+ * @param playerBoardCount - How many boards there are representing player positions (most likely 2).
45
+ * @param extraBoardCount - Number of extra boards (most likely 0).
42
46
  */
43
47
  protected constructor(width: number, height: number, playerBoardCount?: number, extraBoardCount?: number);
44
- /** Calculates whether or not the board is full. */
48
+ /**
49
+ * Calculates whether or not the board is full.
50
+ * @returns Whether or not the board is full.
51
+ */
45
52
  get isFull(): boolean;
46
- /** Calculates whether or not the board is empty. */
53
+ /**
54
+ * Calculates whether or not the board is empty.
55
+ * @returns Whether or not the board is empty.
56
+ */
47
57
  get isEmpty(): boolean;
48
58
  /**
49
59
  * Calculates who the winner is.
50
- * If the game is not over, the output is false.
51
- * If there is a winner, the output is their ID.
52
- * If there is a draw, the output is null.
60
+ * @returns `false` if the game is not over, the player ID if there is a winner, and `null` if there is a draw.
53
61
  */
54
62
  get winner(): 0 | 1 | false | null;
55
- /** Calculates which cells are empty. */
63
+ /**
64
+ * Calculates which cells are empty.
65
+ * @returns The empty cells on the board.
66
+ */
56
67
  get emptyCells(): Position[];
57
68
  /** Calculates the heuristic score for a given board state. */
58
69
  abstract get heuristic(): number;
59
70
  /**
60
71
  * Makes a move on the board.
61
- * @param move The position of the move.
62
- * @param playerId The player who's making the move.
72
+ * @param move - The position of the move.
73
+ * @param playerId - The player who's making the move.
63
74
  */
64
75
  makeMove(move: Position, playerId: number): void;
65
- /** Reverses the last move. */
76
+ /**
77
+ * Reverses the last move.
78
+ * @throws {Error} - If there is no move to undo.
79
+ */
66
80
  undoLastMove(): void;
67
81
  /**
68
82
  * Checks if a move is valid.
69
- * @param move The move.
83
+ * @param move - The position of the move.
70
84
  * @returns Whether or not it's valid.
71
85
  */
72
86
  moveIsValid(move: Position): boolean;
73
87
  /**
74
88
  * Checks which player is occupying a given cell.
75
- * @param cell The cell to check.
89
+ * @param cell - The cell to check.
76
90
  * @returns If the cell is empty, the output is null, otherwise the output is the player's ID.
77
91
  */
78
92
  cellOccupier(cell: Position): number | null;
79
93
  /**
80
94
  * Creates a string representation of the board.
81
- * @param wrap Whether or not to provide a border for the board.
82
- * @param labelX Whether or not to label x.
83
- * @param labelY Whether or not to label y.
84
- * @param symbols The symbols to use as board pieces.
85
- * @param colour Whether or not to colour the pieces.
95
+ * @param wrap - Whether or not to provide a border for the board.
96
+ * @param labelX - Whether or not to label x.
97
+ * @param labelY - Whether or not to label y.
98
+ * @param symbols - The symbols to use as board pieces.
99
+ * @param colour - Whether or not to colour the pieces.
86
100
  * @returns The string representation.
101
+ * @throws {Error} - If the symbols are not the same length.
87
102
  */
88
103
  toString(wrap?: boolean, labelX?: boolean, labelY?: boolean, symbols?: string[], colour?: boolean): string;
89
104
  /**
90
105
  * Determines if a given player has a line of pieces on the board.
91
- * @param playerId The ID of the player.
92
- * @param length The number of pieces needed.
93
- * @param maxGaps The number of gaps allowed for a line to be valid. Defaults to 0.
106
+ * @param playerId - The ID of the player to check.
107
+ * @param length - The number of pieces needed.
108
+ * @param maxGaps - The number of gaps allowed for a line to be valid. Defaults to 0.
94
109
  * @returns How many lines exist.
95
110
  */
96
111
  hasLine(playerId: number, length: number, maxGaps?: number): number;
97
112
  /**
98
113
  * Gets a bit index from its coordinates and player ID.
99
- * @param move The coordinates.
100
- * @param playerId The player ID.
101
- * @returns The bit index.
114
+ * @param move - The coordinates.
115
+ * @param playerId - The player ID to use.
116
+ * @returns The bit index of the move.
102
117
  */
103
118
  protected getBitIndex(move: Position, playerId: number): number;
104
119
  /**
105
120
  * A BitBoard containing only the player's bits.
106
- * @param playerId The player's ID.
121
+ * @param playerId - The player's ID to get the board for.
107
122
  * @returns The player's bits.
108
123
  */
109
- protected getPlayerBoard(playerId: number): T;
124
+ protected getPlayerBoard(playerId: number): BitBoard<T>;
110
125
  /**
111
126
  * Gets a bit index from its coordinates.
112
- * @param move The coordinates.
127
+ * @param move - The coordinates.
113
128
  * @returns The bit index.
114
129
  */
115
130
  private getIndex;
116
131
  /**
117
132
  * Checks if a move is valid for the given board.
118
133
  * Does not check if that cell is already occupied.
119
- * @param position The position to check.
134
+ * @param position - The position to check.
120
135
  * @returns Whether or not that cell exists on the board.
121
136
  */
122
137
  private isValidPosition;
@@ -1,14 +1,17 @@
1
1
  import IntBitBoard from "../bitBoard/intBitBoard.js";
2
2
  import LongInt from "../bitBoard/longInt.js";
3
3
  import LongIntBitBoard from "../bitBoard/longIntBitBoard.js";
4
- /** Represents a game board. */
4
+ /**
5
+ * Represents a game board.
6
+ * @template T - The type of the numeric data.
7
+ */
5
8
  export default class Board {
6
9
  /** Contains the data stored in a BitBoard. */
7
10
  bitBoard;
8
- /** The width of the board. */
9
- boardWidth;
10
- /** The height of the board. */
11
- boardHeight;
11
+ /** The width of the game board. */
12
+ width;
13
+ /** The height of the game board. */
14
+ height;
12
15
  /** A stack of moves. */
13
16
  moves = [];
14
17
  /** How many boards there are representing player positions (most likely 2). */
@@ -17,38 +20,46 @@ export default class Board {
17
20
  numberOfBoards;
18
21
  /**
19
22
  * Creates an instance of Board.
20
- * @param width The width of the board.
21
- * @param height The height of the board.
22
- * @param playerBoardCount How many boards there are representing player positions (most likely 2).
23
- * @param extraBoardCount Number of extra boards (most likely 0).
23
+ * @param width - The width of the game board.
24
+ * @param height - The height of the game board.
25
+ * @param playerBoardCount - How many boards there are representing player positions (most likely 2).
26
+ * @param extraBoardCount - Number of extra boards (most likely 0).
24
27
  */
25
28
  constructor(width, height, playerBoardCount = 2, extraBoardCount = 0) {
26
- this.boardWidth = width;
27
- this.boardHeight = height;
29
+ this.width = width;
30
+ this.height = height;
28
31
  this.numberOfPlayerBoards = playerBoardCount;
29
32
  this.numberOfBoards = this.numberOfPlayerBoards + extraBoardCount;
30
- const totalBits = this.boardWidth * this.boardHeight * this.numberOfBoards;
31
- this.bitBoard = (totalBits > 32 ? new LongIntBitBoard(Math.ceil(totalBits / 32)) : new IntBitBoard());
33
+ const totalBits = this.width * this.height * this.numberOfBoards;
34
+ this.bitBoard = (totalBits > 32
35
+ ? new LongIntBitBoard(Math.ceil(totalBits / 32))
36
+ : new IntBitBoard());
32
37
  }
33
- /** Calculates whether or not the board is full. */
38
+ /**
39
+ * Calculates whether or not the board is full.
40
+ * @returns Whether or not the board is full.
41
+ */
34
42
  get isFull() {
35
43
  let isFull = (this.bitBoard instanceof LongIntBitBoard
36
- ? new LongIntBitBoard(Math.ceil(this.boardWidth * this.boardHeight / 32))
44
+ ? new LongIntBitBoard(Math.ceil(this.width * this.height / 32))
37
45
  : new IntBitBoard());
38
46
  for (let i = 0; i < this.numberOfPlayerBoards; i++)
39
47
  isFull = isFull.or(this.getPlayerBoard(i));
40
- const fullValue = this.bitBoard instanceof LongIntBitBoard
48
+ const fullValue = (this.bitBoard instanceof LongIntBitBoard
41
49
  ? new LongInt([
42
- ...Array(Math.ceil(this.boardWidth * this.boardHeight / 32) - 1).fill(~0 >>> 0),
43
- 2 ** (this.boardWidth * this.boardHeight - (Math.ceil(this.boardWidth * this.boardHeight / 32) - 1) * 32) - 1,
50
+ ...Array(Math.ceil(this.width * this.height / 32) - 1).fill(~0 >>> 0),
51
+ 2 ** (this.width * this.height - (Math.ceil(this.width * this.height / 32) - 1) * 32) - 1,
44
52
  ])
45
- : 2 ** (this.boardWidth * this.boardHeight) - 1;
53
+ : 2 ** (this.width * this.height) - 1);
46
54
  return isFull.equals(fullValue);
47
55
  }
48
- /** Calculates whether or not the board is empty. */
56
+ /**
57
+ * Calculates whether or not the board is empty.
58
+ * @returns Whether or not the board is empty.
59
+ */
49
60
  get isEmpty() {
50
61
  let isEmpty = (this.bitBoard instanceof LongIntBitBoard
51
- ? new LongIntBitBoard(Math.ceil(this.boardWidth * this.boardHeight / 32))
62
+ ? new LongIntBitBoard(Math.ceil(this.width * this.height / 32))
52
63
  : new IntBitBoard());
53
64
  for (let i = 0; i < this.numberOfPlayerBoards; i++)
54
65
  isEmpty = isEmpty.or(this.getPlayerBoard(i));
@@ -56,9 +67,7 @@ export default class Board {
56
67
  }
57
68
  /**
58
69
  * Calculates who the winner is.
59
- * If the game is not over, the output is false.
60
- * If there is a winner, the output is their ID.
61
- * If there is a draw, the output is null.
70
+ * @returns `false` if the game is not over, the player ID if there is a winner, and `null` if there is a draw.
62
71
  */
63
72
  get winner() {
64
73
  const playerOneBoard = this.getPlayerBoard(0);
@@ -73,11 +82,14 @@ export default class Board {
73
82
  return null;
74
83
  return false;
75
84
  }
76
- /** Calculates which cells are empty. */
85
+ /**
86
+ * Calculates which cells are empty.
87
+ * @returns The empty cells on the board.
88
+ */
77
89
  get emptyCells() {
78
90
  const emptyCells = [];
79
- for (let y = 0; y < this.boardHeight; y++) {
80
- for (let x = 0; x < this.boardWidth; x++) {
91
+ for (let y = 0; y < this.height; y++) {
92
+ for (let x = 0; x < this.width; x++) {
81
93
  if (this.cellOccupier({ x, y }) === null)
82
94
  emptyCells.push({ x, y });
83
95
  }
@@ -86,15 +98,18 @@ export default class Board {
86
98
  }
87
99
  /**
88
100
  * Makes a move on the board.
89
- * @param move The position of the move.
90
- * @param playerId The player who's making the move.
101
+ * @param move - The position of the move.
102
+ * @param playerId - The player who's making the move.
91
103
  */
92
104
  makeMove(move, playerId) {
93
105
  const bit = this.getBitIndex(move, playerId);
94
106
  this.moves.push(bit);
95
107
  this.bitBoard.setBit(bit);
96
108
  }
97
- /** Reverses the last move. */
109
+ /**
110
+ * Reverses the last move.
111
+ * @throws {Error} - If there is no move to undo.
112
+ */
98
113
  undoLastMove() {
99
114
  const lastMove = this.moves.pop();
100
115
  if (lastMove === undefined)
@@ -103,7 +118,7 @@ export default class Board {
103
118
  }
104
119
  /**
105
120
  * Checks if a move is valid.
106
- * @param move The move.
121
+ * @param move - The position of the move.
107
122
  * @returns Whether or not it's valid.
108
123
  */
109
124
  moveIsValid(move) {
@@ -111,7 +126,7 @@ export default class Board {
111
126
  }
112
127
  /**
113
128
  * Checks which player is occupying a given cell.
114
- * @param cell The cell to check.
129
+ * @param cell - The cell to check.
115
130
  * @returns If the cell is empty, the output is null, otherwise the output is the player's ID.
116
131
  */
117
132
  cellOccupier(cell) {
@@ -123,12 +138,13 @@ export default class Board {
123
138
  }
124
139
  /**
125
140
  * Creates a string representation of the board.
126
- * @param wrap Whether or not to provide a border for the board.
127
- * @param labelX Whether or not to label x.
128
- * @param labelY Whether or not to label y.
129
- * @param symbols The symbols to use as board pieces.
130
- * @param colour Whether or not to colour the pieces.
141
+ * @param wrap - Whether or not to provide a border for the board.
142
+ * @param labelX - Whether or not to label x.
143
+ * @param labelY - Whether or not to label y.
144
+ * @param symbols - The symbols to use as board pieces.
145
+ * @param colour - Whether or not to colour the pieces.
131
146
  * @returns The string representation.
147
+ * @throws {Error} - If the symbols are not the same length.
132
148
  */
133
149
  toString(wrap = true, labelX = true, labelY = true, symbols = ["X", "O"], colour = true) {
134
150
  if (symbols.length !== this.numberOfPlayerBoards)
@@ -139,39 +155,39 @@ export default class Board {
139
155
  const matchCellSpace = new RegExp(`.{${symbolLength + 2}}`, "gu");
140
156
  const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
141
157
  const xLabels = labelX
142
- ? `${alphabet.slice(0, this.boardWidth)
158
+ ? `${alphabet.slice(0, this.width)
143
159
  .split("")
144
160
  .map((letter) => ` ${letter.padStart(symbolLength)} `)
145
161
  .join("")
146
162
  .match(matchCellSpace)
147
163
  .join(" ")
148
- .padStart(4 * this.boardWidth - 1 + Number(wrap) + Number(labelY))}\n`
164
+ .padStart(4 * this.width - 1 + Number(wrap) + Number(labelY))}\n`
149
165
  : "";
150
166
  const topBorder = wrap
151
167
  ? `${labelY ? " " : ""}${"\u250C" /* GridLines.TopLeft */}${"\u2500" /* GridLines.Horizontal */
152
- .repeat(this.boardWidth * (symbolLength + 2))
168
+ .repeat(this.width * (symbolLength + 2))
153
169
  .match(matchCellSpace)
154
170
  .join("\u252C" /* GridLines.TTop */)}${"\u2510" /* GridLines.TopRight */}\n`
155
171
  : "";
156
172
  const bottomBorder = wrap
157
173
  ? `${labelY ? " " : ""}${"\u2514" /* GridLines.BottomLeft */}${"\u2500" /* GridLines.Horizontal */
158
- .repeat(this.boardWidth * (symbolLength + 2))
174
+ .repeat(this.width * (symbolLength + 2))
159
175
  .match(matchCellSpace)
160
176
  .join("\u2534" /* GridLines.TBottom */)}${"\u2518" /* GridLines.BottomRight */}`
161
177
  : "";
162
178
  const rowSeparator = `${labelY ? " " : ""}${wrap ? "\u251C" /* GridLines.TLeft */ : ""}${"\u2500" /* GridLines.Horizontal */
163
- .repeat(this.boardWidth * (symbolLength + 2))
179
+ .repeat(this.width * (symbolLength + 2))
164
180
  .match(matchCellSpace)
165
181
  .join("\u253C" /* GridLines.Cross */)}${wrap ? "\u2524" /* GridLines.TRight */ : ""}\n`;
166
182
  const rows = [];
167
- for (let y = 0; y < this.boardHeight; y++) {
183
+ for (let y = 0; y < this.height; y++) {
168
184
  const yLabel = labelY ? `${y + 1}` : "";
169
185
  const leftBorder = wrap ? "\u2502" /* GridLines.Vertical */ : "";
170
186
  const rightBorder = wrap ? "\u2502" /* GridLines.Vertical */ : "";
171
187
  let row = `${yLabel}${leftBorder}`;
172
- for (let x = 0; x < this.boardWidth; x++) {
188
+ for (let x = 0; x < this.width; x++) {
173
189
  const cell = { x, y };
174
- const bar = x === this.boardWidth - 1 ? "" : "\u2502" /* GridLines.Vertical */;
190
+ const bar = x === this.width - 1 ? "" : "\u2502" /* GridLines.Vertical */;
175
191
  const cellOccupier = this.cellOccupier(cell);
176
192
  if (cellOccupier === null) {
177
193
  row += ` ${" ".repeat(symbolLength)} ${bar}`;
@@ -188,15 +204,20 @@ export default class Board {
188
204
  }
189
205
  /**
190
206
  * Determines if a given player has a line of pieces on the board.
191
- * @param playerId The ID of the player.
192
- * @param length The number of pieces needed.
193
- * @param maxGaps The number of gaps allowed for a line to be valid. Defaults to 0.
207
+ * @param playerId - The ID of the player to check.
208
+ * @param length - The number of pieces needed.
209
+ * @param maxGaps - The number of gaps allowed for a line to be valid. Defaults to 0.
194
210
  * @returns How many lines exist.
195
211
  */
196
212
  hasLine(playerId, length, maxGaps = 0) {
197
- if (length > Math.max(this.boardWidth, this.boardHeight))
213
+ if (length > Math.max(this.width, this.height))
198
214
  return 0;
199
- const DIRECTIONS = [{ x: 1, y: 0 }, { x: 0, y: 1 }, { x: 1, y: 1 }, { x: 1, y: -1 }];
215
+ const DIRECTIONS = [
216
+ { x: 1, y: 0 },
217
+ { x: 0, y: 1 },
218
+ { x: 1, y: 1 },
219
+ { x: 1, y: -1 },
220
+ ];
200
221
  let lineCount = 0;
201
222
  let gaps = [0, 0, 0, 0];
202
223
  let lengths = [0, 0, 0, 0];
@@ -210,8 +231,8 @@ export default class Board {
210
231
  lengths[direction]++;
211
232
  }
212
233
  };
213
- for (let x = 0; x < this.boardWidth; x++) {
214
- for (let y = 0; y < this.boardHeight; y++) {
234
+ for (let x = 0; x < this.width; x++) {
235
+ for (let y = 0; y < this.height; y++) {
215
236
  gaps = [0, 0, 0, 0];
216
237
  lengths = [0, 0, 0, 0];
217
238
  for (let i = 0; i < length; i++) {
@@ -229,41 +250,41 @@ export default class Board {
229
250
  }
230
251
  /**
231
252
  * Gets a bit index from its coordinates and player ID.
232
- * @param move The coordinates.
233
- * @param playerId The player ID.
234
- * @returns The bit index.
253
+ * @param move - The coordinates.
254
+ * @param playerId - The player ID to use.
255
+ * @returns The bit index of the move.
235
256
  */
236
257
  getBitIndex(move, playerId) {
237
258
  const moveIndex = this.getIndex(move);
238
- const bitBoardMoveIndex = moveIndex + this.boardWidth * this.boardHeight * playerId;
259
+ const bitBoardMoveIndex = moveIndex + this.width * this.height * playerId;
239
260
  return bitBoardMoveIndex;
240
261
  }
241
262
  /**
242
263
  * A BitBoard containing only the player's bits.
243
- * @param playerId The player's ID.
264
+ * @param playerId - The player's ID to get the board for.
244
265
  * @returns The player's bits.
245
266
  */
246
267
  getPlayerBoard(playerId) {
247
268
  const totalBits = (this.bitBoard instanceof LongIntBitBoard ? this.bitBoard.data.wordCount : 1) * 32;
248
- const boardSize = this.boardWidth * this.boardHeight;
269
+ const boardSize = this.width * this.height;
249
270
  return this.bitBoard.leftShift(totalBits - boardSize * (playerId + 1)).rightShift(totalBits - boardSize);
250
271
  }
251
272
  /**
252
273
  * Gets a bit index from its coordinates.
253
- * @param move The coordinates.
274
+ * @param move - The coordinates.
254
275
  * @returns The bit index.
255
276
  */
256
277
  getIndex(move) {
257
- return this.boardWidth * move.y + move.x;
278
+ return this.width * move.y + move.x;
258
279
  }
259
280
  /**
260
281
  * Checks if a move is valid for the given board.
261
282
  * Does not check if that cell is already occupied.
262
- * @param position The position to check.
283
+ * @param position - The position to check.
263
284
  * @returns Whether or not that cell exists on the board.
264
285
  */
265
286
  isValidPosition(position) {
266
- return position.x >= 0 && position.x < this.boardWidth && position.y >= 0 && position.y < this.boardHeight;
287
+ return position.x >= 0 && position.x < this.width && position.y >= 0 && position.y < this.height;
267
288
  }
268
289
  }
269
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9hcmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYmFzZS9ib2FyZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLFdBQVcsTUFBTSw0QkFBNEIsQ0FBQztBQUNyRCxPQUFPLE9BQU8sTUFBTSx3QkFBd0IsQ0FBQztBQUM3QyxPQUFPLGVBQWUsTUFBTSxnQ0FBZ0MsQ0FBQztBQXNCN0QsK0JBQStCO0FBQy9CLE1BQU0sQ0FBQyxPQUFPLE9BQWdCLEtBQUs7SUFDL0IsOENBQThDO0lBQzNCLFFBQVEsQ0FBSTtJQUUvQiw4QkFBOEI7SUFDWCxVQUFVLENBQVM7SUFFdEMsK0JBQStCO0lBQ1osV0FBVyxDQUFTO0lBRXZDLHdCQUF3QjtJQUNMLEtBQUssR0FBYSxFQUFFLENBQUM7SUFFeEMsK0VBQStFO0lBQzlELG9CQUFvQixDQUFTO0lBRTlDLHNEQUFzRDtJQUNyQyxjQUFjLENBQVM7SUFLeEM7Ozs7OztPQU1HO0lBQ0gsWUFBc0IsS0FBYSxFQUFFLE1BQWMsRUFBRSxtQkFBMkIsQ0FBQyxFQUFFLGtCQUEwQixDQUFDO1FBQzFHLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDO1FBQzFCLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxnQkFBZ0IsQ0FBQztRQUM3QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxlQUFlLENBQUM7UUFDbEUsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7UUFFM0UsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElB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O1FBQ3JDLE1BQU0sU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsWUFBWSxlQUFlLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3JHLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUVyRCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxTQUFTLEdBQUcsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBQzdHLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssUUFBUSxDQUFDLElBQWM7UUFDM0IsT0FBTyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxlQUFlLENBQUMsUUFBa0I7UUFDdEMsT0FBTyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLElBQUksUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQy9HLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIEJpdEJvYXJkIGZyb20gXCIuLi9iaXRCb2FyZC9iaXRCb2FyZC5qc1wiO1xuaW1wb3J0IEludEJpdEJvYXJkIGZyb20gXCIuLi9iaXRCb2FyZC9pbnRCaXRCb2FyZC5qc1wiO1xuaW1wb3J0IExvbmdJbnQgZnJvbSBcIi4uL2JpdEJvYXJkL2xvbmdJbnQuanNcIjtcbmltcG9ydCBMb25nSW50Qml0Qm9hcmQgZnJvbSBcIi4uL2JpdEJvYXJkL2xvbmdJbnRCaXRCb2FyZC5qc1wiO1xuXG5leHBvcnQgdHlwZSBQb3NpdGlvbiA9IHtcbiAgICB5OiBudW1iZXI7XG4gICAgeDogbnVtYmVyO1xufTtcblxuLyoqIERlZmluZXMgdGhlIGNoYXJhY3RlcnMgdXNlZCB0byBkcmF3IGEgZ3JpZC4gKi9cbmV4cG9ydCBjb25zdCBlbnVtIEdyaWRMaW5lcyB7XG4gICAgSG9yaXpvbnRhbCA9IFwiXFx1MjUwMFwiLFxuICAgIFZlcnRpY2FsID0gXCJcXHUyNTAyXCIsXG4gICAgVG9wTGVmdCA9IFwiXFx1MjUwQ1wiLFxuICAgIFRvcFJpZ2h0ID0gXCJcXHUyNTEwXCIsXG4gICAgQm90dG9tTGVmdCA9IFwiXFx1MjUxNFwiLFxuICAgIEJvdHRvbVJpZ2h0ID0gXCJcXHUyNTE4XCIsXG4gICAgVExlZnQgPSBcIlxcdTI1MUNcIixcbiAgICBUUmlnaHQgPSBcIlxcdTI1MjRcIixcbiAgICBUVG9wID0gXCJcXHUyNTJDXCIsXG4gICAgVEJvdHRvbSA9IFwiXFx1MjUzNFwiLFxuICAgIENyb3NzID0gXCJcXHUyNTNDXCIsXG59XG5cbi8qKiBSZXByZXNlbnRzIGEgZ2FtZSBib2FyZC4gKi9cbmV4cG9ydCBkZWZhdWx0IGFic3RyYWN0IGNsYXNzIEJvYXJkPFQgZXh0ZW5kcyBCaXRCb2FyZCA9IEJpdEJvYXJkPiB7XG4gICAgLyoqIENvbnRhaW5zIHRoZSBkYXRhIHN0b3JlZCBpbiBhIEJpdEJvYXJkLiAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBiaXRCb2FyZDogVDtcblxuICAgIC8qKiBUaGUgd2lkdGggb2YgdGhlIGJvYXJkLiAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBib2FyZFdpZHRoOiBudW1iZXI7XG5cbiAgICAvKiogVGhlIGhlaWdodCBvZiB0aGUgYm9hcmQuICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGJvYXJkSGVpZ2h0OiBudW1iZXI7XG5cbiAgICAvKiogQSBzdGFjayBvZiBtb3Zlcy4gKi9cbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgbW92ZXM6IG51bWJlcltdID0gW107XG5cbiAgICAvKiogSG93IG1hbnkgYm9hcmRzIHRoZXJlIGFyZSByZXByZXNlbnRpbmcgcGxheWVyIHBvc2l0aW9ucyAobW9zdCBsaWtlbHkgMikuICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBudW1iZXJPZlBsYXllckJvYXJkczogbnVtYmVyO1xuXG4gICAgLyoqIE51bWJlciBvZiBib2FyZHMgaW4gdG90YWwgKG1vc3QgbGlrZWx5IGFsc28gMikuICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBudW1iZXJPZkJvYXJkczogbnVtYmVyO1xuXG4gICAgLyoqIFRoZSBib2FyZCBzdGF0ZXMgd2hpY2ggcmVwcmVzZW50IGEgd2lubmluZyBzdGF0ZS4gKi9cbiAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgcmVhZG9ubHkgd2lubmluZ1N0YXRlczogVFtdO1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBCb2FyZC5cbiAgICAgKiBAcGFyYW0gd2lkdGggVGhlIHdpZHRoIG9mIHRoZSBib2FyZC5cbiAgICAgKiBAcGFyYW0gaGVpZ2h0IFRoZSBoZWlnaHQgb2YgdGhlIGJvYXJkLlxuICAgICAqIEBwYXJhbSBwbGF5ZXJCb2FyZENvdW50IEhvdyBtYW55IGJvYXJkcyB0aGVyZSBhcmUgcmVwcmVzZW50aW5nIHBsYXllciBwb3NpdGlvbnMgKG1vc3QgbGlrZWx5IDIpLlxuICAgICAqIEBwYXJhbSBleHRyYUJvYXJkQ291bnQgTnVtYmVyIG9mIGV4dHJhIGJvYXJkcyAobW9zdCBsaWtlbHkgMCkuXG4gICAgICovXG4gICAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBwbGF5ZXJCb2FyZENvdW50OiBudW1iZXIgPSAyLCBleHRyYUJvYXJkQ291bnQ6IG51bWJlciA9IDApIHtcbiAgICAgICAgdGhpcy5ib2FyZFdpZHRoID0gd2lkdGg7XG4gICAgICAgIHRoaXMuYm9hcmRIZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIHRoaXMubnVtYmVyT2ZQbGF5ZXJCb2FyZHMgPSBwbGF5ZXJCb2FyZENvdW50O1xuICAgICAgICB0aGlzLm51bWJlck9mQm9hcmRzID0gdGhpcy5udW1iZXJPZlBsYXllckJvYXJkcyArIGV4dHJhQm9hcmRDb3VudDtcbiAgICAgICAgY29uc3QgdG90YWxCaXRzID0gdGhpcy5ib2FyZFdpZHRoICogdGhpcy5ib2FyZEhlaWdodCAqIHRoaXMubnVtYmVyT2ZCb2FyZHM7XG5cbiAgICAgICAgdGhpcy5iaXRCb2FyZCA9ICh0b3RhbEJpdHMgPiAzMiA/IG5ldyBMb25nSW50Qml0Qm9hcmQoTWF0aC5jZWlsKHRvdGFsQml0cyAvIDMyKSkgOiBuZXcgSW50Qml0Qm9hcmQoKSkgYXMgVDtcbiAgICB9XG5cbiAgICAvKiogQ2FsY3VsYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgYm9hcmQgaXMgZnVsbC4gKi9cbiAgICBwdWJsaWMgZ2V0IGlzRnVsbCgpOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGlzRnVsbCA9ICh0aGlzLmJpdEJvYXJkIGluc3RhbmNlb2YgTG9uZ0ludEJpdEJvYXJkXG4gICAgICAgICAgICA/IG5ldyBMb25nSW50Qml0Qm9hcmQoTWF0aC5jZWlsKHRoaXMuYm9hcmRXaWR0aCAqIHRoaXMuYm9hcmRIZWlnaHQgLyAzMikpXG4gICAgICAgICAgICA6IG5ldyBJbnRCaXRCb2FyZCgpKSBhcyBUO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5udW1iZXJPZlBsYXllckJvYXJkczsgaSsrKVxuICAgICAgICAgICAgaXNGdWxsID0gaXNGdWxsLm9yKHRoaXMuZ2V0UGxheWVyQm9hcmQoaSkpO1xuICAgICAgICBjb25zdCBmdWxsVmFsdWUgPSB0aGlzLmJpdEJvYXJkIGluc3RhbmNlb2YgTG9uZ0ludEJpdEJvYXJkXG4gICAgICAgICAgICA/IG5ldyBMb25nSW50KFtcbiAgICAgICAgICAgICAgICAuLi5BcnJheTxudW1iZXI+KE1hdGguY2VpbCh0aGlzLmJvYXJkV2lkdGggKiB0aGlzLmJvYXJkSGVpZ2h0IC8gMzIpIC0gMSkuZmlsbCh+MCA+Pj4gMCksXG4gICAgICAgICAgICAgICAgMiAqKiAodGhpcy5ib2FyZFdpZHRoICogdGhpcy5ib2FyZEhlaWdodCAtIChNYXRoLmNlaWwodGhpcy5ib2FyZFdpZHRoICogdGhpcy5ib2FyZEhlaWdodCAvIDMyKSAtIDEpICogMzIpIC0gMSxcbiAgICAgICAgICAgIF0pXG4gICAgICAgICAgICA6IDIgKiogKHRoaXMuYm9hcmRXaWR0aCAqIHRoaXMuYm9hcmRIZWlnaHQpIC0gMTtcblxuICAgICAgICByZXR1cm4gaXNGdWxsLmVxdWFscyhmdWxsVmFsdWUpO1xuICAgIH1cblxuICAgIC8qKiBDYWxjdWxhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBib2FyZCBpcyBlbXB0eS4gKi9cbiAgICBwdWJsaWMgZ2V0IGlzRW1wdHkoKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBpc0VtcHR5ID0gKHRoaXMuYml0Qm9hcmQgaW5zdGFuY2VvZiBMb25nSW50Qml0Qm9hcmRcbiAgICAgICAgICAgID8gbmV3IExvbmdJbnRCaXRCb2FyZChNYXRoLmNlaWwodGhpcy5ib2FyZFdpZHRoICogdGhpcy5ib2FyZEhlaWdodCAvIDMyKSlcbiAgICAgICAgICAgIDogbmV3IEludEJpdEJvYXJkKCkpIGFzIFQ7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm51bWJlck9mUGxheWVyQm9hcmRzOyBpKyspXG4gICAgICAgICAgICBpc0VtcHR5ID0gaXNFbXB0eS5vcih0aGlzLmdldFBsYXllckJvYXJkKGkpKTtcblxuICAgICAgICByZXR1cm4gaXNFbXB0eS5lcXVhbHMoMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB3aG8gdGhlIHdpbm5lciBpcy5cbiAgICAgKiBJZiB0aGUgZ2FtZSBpcyBub3Qgb3ZlciwgdGhlIG91dHB1dCBpcyBmYWxzZS5cbiAgICAgKiBJZiB0aGVyZSBpcyBhIHdpbm5lciwgdGhlIG91dHB1dCBpcyB0aGVpciBJRC5cbiAgICAgKiBJZiB0aGVyZSBpcyBhIGRyYXcsIHRoZSBvdXRwdXQgaXMgbnVsbC5cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHdpbm5lcigpOiAwIHwgMSB8IGZhbHNlIHwgbnVsbCB7XG4gICAgICAgIGNvbnN0IHBsYXllck9uZUJvYXJkID0gdGhpcy5nZXRQbGF5ZXJCb2FyZCgwKTtcbiAgICAgICAgY29uc3QgcGxheWVyVHdvQm9hcmQgPSB0aGlzLmdldFBsYXllckJvYXJkKDEpO1xuXG4gICAgICAgIGZvciAoY29uc3Qgc3RhdGUgb2YgdGhpcy53aW5uaW5nU3RhdGVzKSB7XG4gICAgICAgICAgICBpZiAocGxheWVyT25lQm9hcmQuYW5kKHN0YXRlKS5lcXVhbHMoc3RhdGUpKVxuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuXG4gICAgICAgICAgICBpZiAocGxheWVyVHdvQm9hcmQuYW5kKHN0YXRlKS5lcXVhbHMoc3RhdGUpKVxuICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaXNGdWxsKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8qKiBDYWxjdWxhdGVzIHdoaWNoIGNlbGxzIGFyZSBlbXB0eS4gKi9cbiAgICBwdWJsaWMgZ2V0IGVtcHR5Q2VsbHMoKTogUG9zaXRpb25bXSB7XG4gICAgICAgIGNvbnN0IGVtcHR5Q2VsbHM6IFBvc2l0aW9uW10gPSBbXTtcblxuICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHRoaXMuYm9hcmRIZWlnaHQ7IHkrKykge1xuICAgICAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCB0aGlzLmJvYXJkV2lkdGg7IHgrKykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNlbGxPY2N1cGllcih7IHgsIHkgfSkgPT09IG51bGwpXG4gICAgICAgICAgICAgICAgICAgIGVtcHR5Q2VsbHMucHVzaCh7IHgsIHkgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZW1wdHlDZWxscztcbiAgICB9XG5cbiAgICAvKiogQ2FsY3VsYXRlcyB0aGUgaGV1cmlzdGljIHNjb3JlIGZvciBhIGdpdmVuIGJvYXJkIHN0YXRlLiAqL1xuICAgIHB1YmxpYyBhYnN0cmFjdCBnZXQgaGV1cmlzdGljKCk6IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIE1ha2VzIGEgbW92ZSBvbiB0aGUgYm9hcmQuXG4gICAgICogQHBhcmFtIG1vdmUgVGhlIHBvc2l0aW9uIG9mIHRoZSBtb3ZlLlxuICAgICAqIEBwYXJhbSBwbGF5ZXJJZCBUaGUgcGxheWVyIHdobydzIG1ha2luZyB0aGUgbW92ZS5cbiAgICAgKi9cbiAgICBwdWJsaWMgbWFrZU1vdmUobW92ZTogUG9zaXRpb24sIHBsYXllcklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgYml0ID0gdGhpcy5nZXRCaXRJbmRleChtb3ZlLCBwbGF5ZXJJZCk7XG5cbiAgICAgICAgdGhpcy5tb3Zlcy5wdXNoKGJpdCk7XG4gICAgICAgIHRoaXMuYml0Qm9hcmQuc2V0Qml0KGJpdCk7XG4gICAgfVxuXG4gICAgLyoqIFJldmVyc2VzIHRoZSBsYXN0IG1vdmUuICovXG4gICAgcHVibGljIHVuZG9MYXN0TW92ZSgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgbGFzdE1vdmUgPSB0aGlzLm1vdmVzLnBvcCgpO1xuXG4gICAgICAgIGlmIChsYXN0TW92ZSA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbW92ZSB0byB1bmRvLlwiKTtcblxuICAgICAgICB0aGlzLmJpdEJvYXJkLmNsZWFyQml0KGxhc3RNb3ZlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3MgaWYgYSBtb3ZlIGlzIHZhbGlkLlxuICAgICAqIEBwYXJhbSBtb3ZlIFRoZSBtb3ZlLlxuICAgICAqIEByZXR1cm5zIFdoZXRoZXIgb3Igbm90IGl0J3MgdmFsaWQuXG4gICAgICovXG4gICAgcHVibGljIG1vdmVJc1ZhbGlkKG1vdmU6IFBvc2l0aW9uKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmlzVmFsaWRQb3NpdGlvbihtb3ZlKSAmJiB0aGlzLmNlbGxPY2N1cGllcihtb3ZlKSA9PT0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVja3Mgd2hpY2ggcGxheWVyIGlzIG9jY3VweWluZyBhIGdpdmVuIGNlbGwuXG4gICAgICogQHBhcmFtIGNlbGwgVGhlIGNlbGwgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMgSWYgdGhlIGNlbGwgaXMgZW1wdHksIHRoZSBvdXRwdXQgaXMgbnVsbCwgb3RoZXJ3aXNlIHRoZSBvdXRwdXQgaXMgdGhlIHBsYXllcidzIElELlxuICAgICAqL1xuICAgIHB1YmxpYyBjZWxsT2NjdXBpZXIoY2VsbDogUG9zaXRpb24pOiBudW1iZXIgfCBudWxsIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm51bWJlck9mUGxheWVyQm9hcmRzOyBpKyspIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmJpdEJvYXJkLmdldEJpdCh0aGlzLmdldEJpdEluZGV4KGNlbGwsIGkpKSA9PT0gMSlcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGJvYXJkLlxuICAgICAqIEBwYXJhbSB3cmFwIFdoZXRoZXIgb3Igbm90IHRvIHByb3ZpZGUgYSBib3JkZXIgZm9yIHRoZSBib2FyZC5cbiAgICAgKiBAcGFyYW0gbGFiZWxYIFdoZXRoZXIgb3Igbm90IHRvIGxhYmVsIHguXG4gICAgICogQHBhcmFtIGxhYmVsWSBXaGV0aGVyIG9yIG5vdCB0byBsYWJlbCB5LlxuICAgICAqIEBwYXJhbSBzeW1ib2xzIFRoZSBzeW1ib2xzIHRvIHVzZSBhcyBib2FyZCBwaWVjZXMuXG4gICAgICogQHBhcmFtIGNvbG91ciBXaGV0aGVyIG9yIG5vdCB0byBjb2xvdXIgdGhlIHBpZWNlcy5cbiAgICAgKiBAcmV0dXJucyBUaGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uLlxuICAgICAqL1xuICAgIHB1YmxpYyB0b1N0cmluZyhcbiAgICAgICAgd3JhcDogYm9vbGVhbiA9IHRydWUsXG4gICAgICAgIGxhYmVsWDogYm9vbGVhbiA9IHRydWUsXG4gICAgICAgIGxhYmVsWTogYm9vbGVhbiA9IHRydWUsXG4gICAgICAgIHN5bWJvbHM6IHN0cmluZ1tdID0gW1wiWFwiLCBcIk9cIl0sXG4gICAgICAgIGNvbG91cjogYm9vbGVhbiA9IHRydWUsXG4gICAgKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHN5bWJvbHMubGVuZ3RoICE9PSB0aGlzLm51bWJlck9mUGxheWVyQm9hcmRzKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVG9vIG1hbnkgc3ltYm9scy5cIik7XG5cbiAgICAgICAgY29uc3Qgc3ltYm9sTGVuZ3RoID0gc3ltYm9sc1swXSEubGVuZ3RoO1xuXG4gICAgICAgIGlmIChzeW1ib2xzLnNvbWUoKHMpID0+IHMubGVuZ3RoICE9PSBzeW1ib2xMZW5ndGgpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3ltYm9scyBtdXN0IGJlIHRoZSBzYW1lIGxlbmd0aC5cIik7XG5cbiAgICAgICAgY29uc3QgbWF0Y2hDZWxsU3BhY2UgPSBuZXcgUmVnRXhwKGAueyR7c3ltYm9sTGVuZ3RoICsgMn19YCwgXCJndVwiKTtcbiAgICAgICAgY29uc3QgYWxwaGFiZXQgPSBcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIjtcbiAgICAgICAgY29uc3QgeExhYmVscyA9IGxhYmVsWFxuICAgICAgICAgICAgPyBgJHthbHBoYWJldC5zbGljZSgwLCB0aGlzLmJvYXJkV2lkdGgpXG4gICAgICAgICAgICAgICAgLnNwbGl0KFwiXCIpXG4gICAgICAgICAgICAgICAgLm1hcCgobGV0dGVyKSA9PiBgICR7bGV0dGVyLnBhZFN0YXJ0KHN5bWJvbExlbmd0aCl9IGApXG4gICAgICAgICAgICAgICAgLmpvaW4oXCJcIilcbiAgICAgICAgICAgICAgICAubWF0Y2gobWF0Y2hDZWxsU3BhY2UpIVxuICAgICAgICAgICAgICAgIC5qb2luKFwiIFwiKVxuICAgICAgICAgICAgICAgIC5wYWRTdGFydCg0ICogdGhpcy5ib2FyZFdpZHRoIC0gMSArIE51bWJlcih3cmFwKSArIE51bWJlcihsYWJlbFkpKVxuICAgICAgICAgICAgfVxcbmBcbiAgICAgICAgICAgIDogXCJcIjtcbiAgICAgICAgY29uc3QgdG9wQm9yZGVyID0gd3JhcFxuICAgICAgICAgICAgPyBgJHtsYWJlbFkgPyBcIiBcIiA6IFwiXCJ9JHtHcmlkTGluZXMuVG9wTGVmdH0ke0dyaWRMaW5lcy5Ib3Jpem9udGFsXG4gICAgICAgICAgICAgICAgLnJlcGVhdCh0aGlzLmJvYXJkV2lkdGggKiAoc3ltYm9sTGVuZ3RoICsgMikpXG4gICAgICAgICAgICAgICAgLm1hdGNoKG1hdGNoQ2VsbFNwYWNlKSFcbiAgICAgICAgICAgICAgICAuam9pbihHcmlkTGluZXMuVFRvcCl9JHtHcmlkTGluZXMuVG9wUmlnaHR9XFxuYFxuICAgICAgICAgICAgOiBcIlwiO1xuICAgICAgICBjb25zdCBib3R0b21Cb3JkZXIgPSB3cmFwXG4gICAgICAgICAgICA/IGAke2xhYmVsWSA/IFwiIFwiIDogXCJcIn0ke0dyaWRMaW5lcy5Cb3R0b21MZWZ0fSR7R3JpZExpbmVzLkhvcml6b250YWxcbiAgICAgICAgICAgICAgICAucmVwZWF0KHRoaXMuYm9hcmRXaWR0aCAqIChzeW1ib2xMZW5ndGggKyAyKSlcbiAgICAgICAgICAgICAgICAubWF0Y2gobWF0Y2hDZWxsU3BhY2UpIVxuICAgICAgICAgICAgICAgIC5qb2luKEdyaWRMaW5lcy5UQm90dG9tKX0ke0dyaWRMaW5lcy5Cb3R0b21SaWdodH1gXG4gICAgICAgICAgICA6IFwiXCI7XG4gICAgICAgIGNvbnN0IHJvd1NlcGFyYXRvciA9IGAke2xhYmVsWSA/IFwiIFwiIDogXCJcIn0ke3dyYXAgPyBHcmlkTGluZXMuVExlZnQgOiBcIlwifSR7R3JpZExpbmVzLkhvcml6b250YWxcbiAgICAgICAgICAgIC5yZXBlYXQodGhpcy5ib2FyZFdpZHRoICogKHN5bWJvbExlbmd0aCArIDIpKVxuICAgICAgICAgICAgLm1hdGNoKG1hdGNoQ2VsbFNwYWNlKSFcbiAgICAgICAgICAgIC5qb2luKEdyaWRMaW5lcy5Dcm9zcyl9JHt3cmFwID8gR3JpZExpbmVzLlRSaWdodCA6IFwiXCJ9XFxuYDtcbiAgICAgICAgY29uc3Qgcm93czogc3RyaW5nW10gPSBbXTtcblxuICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHRoaXMuYm9hcmRIZWlnaHQ7IHkrKykge1xuICAgICAgICAgICAgY29uc3QgeUxhYmVsID0gbGFiZWxZID8gYCR7eSArIDF9YCA6IFwiXCI7XG4gICAgICAgICAgICBjb25zdCBsZWZ0Qm9yZGVyID0gd3JhcCA/IEdyaWRMaW5lcy5WZXJ0aWNhbCA6IFwiXCI7XG4gICAgICAgICAgICBjb25zdCByaWdodEJvcmRlciA9IHdyYXAgPyBHcmlkTGluZXMuVmVydGljYWwgOiBcIlwiO1xuICAgICAgICAgICAgbGV0IHJvdyA9IGAke3lMYWJlbH0ke2xlZnRCb3JkZXJ9YDtcblxuICAgICAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCB0aGlzLmJvYXJkV2lkdGg7IHgrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNlbGwgPSB7IHgsIHkgfTtcbiAgICAgICAgICAgICAgICBjb25zdCBiYXIgPSB4ID09PSB0aGlzLmJvYXJkV2lkdGggLSAxID8gXCJcIiA6IEdyaWRMaW5lcy5WZXJ0aWNhbDtcbiAgICAgICAgICAgICAgICBjb25zdCBjZWxsT2NjdXBpZXIgPSB0aGlzLmNlbGxPY2N1cGllcihjZWxsKTtcblxuICAgICAgICAgICAgICAgIGlmIChjZWxsT2NjdXBpZXIgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgcm93ICs9IGAgJHtcIiBcIi5yZXBlYXQoc3ltYm9sTGVuZ3RoKX0gJHtiYXJ9YDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByb3cgKz0gYCAke2NvbG91ciA/IGBcXHgxYlske1s5MSwgOTNdW2NlbGxPY2N1cGllcl0hfW1gIDogXCJcIn1gICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGAke3N5bWJvbHNbY2VsbE9jY3VwaWVyXX1gICtcbiAgICAgICAgICAgICAgICAgICAgICAgIGAke2NvbG91ciA/IFwiXFx4MWJbMG1cIiA6IFwiXCJ9ICR7YmFyfWA7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcm93cy5wdXNoKGAke3Jvd30ke3JpZ2h0Qm9yZGVyfVxcbmApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGAke3hMYWJlbHN9JHt0b3BCb3JkZXJ9JHtyb3dzLmpvaW4ocm93U2VwYXJhdG9yKX0ke2JvdHRvbUJvcmRlcn1gO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERldGVybWluZXMgaWYgYSBnaXZlbiBwbGF5ZXIgaGFzIGEgbGluZSBvZiBwaWVjZXMgb24gdGhlIGJvYXJkLlxuICAgICAqIEBwYXJhbSBwbGF5ZXJJZCBUaGUgSUQgb2YgdGhlIHBsYXllci5cbiAgICAgKiBAcGFyYW0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgcGllY2VzIG5lZWRlZC5cbiAgICAgKiBAcGFyYW0gbWF4R2FwcyBUaGUgbnVtYmVyIG9mIGdhcHMgYWxsb3dlZCBmb3IgYSBsaW5lIHRvIGJlIHZhbGlkLiBEZWZhdWx0cyB0byAwLlxuICAgICAqIEByZXR1cm5zIEhvdyBtYW55IGxpbmVzIGV4aXN0LlxuICAgICAqL1xuICAgIHB1YmxpYyBoYXNMaW5lKHBsYXllcklkOiBudW1iZXIsIGxlbmd0aDogbnVtYmVyLCBtYXhHYXBzOiBudW1iZXIgPSAwKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKGxlbmd0aCA+IE1hdGgubWF4KHRoaXMuYm9hcmRXaWR0aCwgdGhpcy5ib2FyZEhlaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gMDtcblxuICAgICAgICBjb25zdCBESVJFQ1RJT05TOiBbUG9zaXRpb24sIFBvc2l0aW9uLCBQb3NpdGlvbiwgUG9zaXRpb25dID0gW3sgeDogMSwgeTogMCB9LCB7IHg6IDAsIHk6IDEgfSwgeyB4OiAxLCB5OiAxIH0sIHsgeDogMSwgeTogLTEgfV07XG4gICAgICAgIGxldCBsaW5lQ291bnQgPSAwO1xuICAgICAgICBsZXQgZ2FwczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMCwgMCwgMCwgMF07XG4gICAgICAgIGxldCBsZW5ndGhzOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFswLCAwLCAwLCAwXTtcbiAgICAgICAgY29uc3QgY2hlY2tDZWxsID0gKHg6IG51bWJlciwgeTogbnVtYmVyLCBkaXJlY3Rpb246IDAgfCAxIHwgMiB8IDMpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNlbGwgPSB7IHgsIHkgfSBhcyBQb3NpdGlvbjtcblxuICAgICAgICAgICAgaWYgKHRoaXMuaXNWYWxpZFBvc2l0aW9uKGNlbGwpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2VsbE9jY3VwaWVyID0gdGhpcy5jZWxsT2NjdXBpZXIoY2VsbCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoY2VsbE9jY3VwaWVyID09PSBudWxsKVxuICAgICAgICAgICAgICAgICAgICBnYXBzW2RpcmVjdGlvbl0rKztcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChjZWxsT2NjdXBpZXIgPT09IHBsYXllcklkKVxuICAgICAgICAgICAgICAgICAgICBsZW5ndGhzW2RpcmVjdGlvbl0rKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBmb3IgKGxldCB4ID0gMDsgeCA8IHRoaXMuYm9hcmRXaWR0aDsgeCsrKSB7XG4gICAgICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHRoaXMuYm9hcmRIZWlnaHQ7IHkrKykge1xuICAgICAgICAgICAgICAgIGdhcHMgPSBbMCwgMCwgMCwgMF07XG4gICAgICAgICAgICAgICAgbGVuZ3RocyA9IFswLCAwLCAwLCAwXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwIGFzIDAgfCAxIHwgMiB8IDM7IGogPCA0OyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnYXBzW2pdID4gbWF4R2FwcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tDZWxsKHggKyBpICogRElSRUNUSU9OU1tqXS54LCB5ICsgaSAqIERJUkVDVElPTlNbal0ueSwgaik7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsZW5ndGhzW2pdID09PSBsZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZUNvdW50Kys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbGluZUNvdW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYSBiaXQgaW5kZXggZnJvbSBpdHMgY29vcmRpbmF0ZXMgYW5kIHBsYXllciBJRC5cbiAgICAgKiBAcGFyYW0gbW92ZSBUaGUgY29vcmRpbmF0ZXMuXG4gICAgICogQHBhcmFtIHBsYXllcklkIFRoZSBwbGF5ZXIgSUQuXG4gICAgICogQHJldHVybnMgVGhlIGJpdCBpbmRleC5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgZ2V0Qml0SW5kZXgobW92ZTogUG9zaXRpb24sIHBsYXllcklkOiBudW1iZXIpOiBudW1iZXIge1xuICAgICAgICBjb25zdCBtb3ZlSW5kZXggPSB0aGlzLmdldEluZGV4KG1vdmUpO1xuICAgICAgICBjb25zdCBiaXRCb2FyZE1vdmVJbmRleCA9IG1vdmVJbmRleCArIHRoaXMuYm9hcmRXaWR0aCAqIHRoaXMuYm9hcmRIZWlnaHQgKiBwbGF5ZXJJZDtcblxuICAgICAgICByZXR1cm4gYml0Qm9hcmRNb3ZlSW5kZXg7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBCaXRCb2FyZCBjb250YWluaW5nIG9ubHkgdGhlIHBsYXllcidzIGJpdHMuXG4gICAgICogQHBhcmFtIHBsYXllcklkIFRoZSBwbGF5ZXIncyBJRC5cbiAgICAgKiBAcmV0dXJucyBUaGUgcGxheWVyJ3MgYml0cy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgZ2V0UGxheWVyQm9hcmQocGxheWVySWQ6IG51bWJlcik6IFQge1xuICAgICAgICBjb25zdCB0b3RhbEJpdHMgPSAodGhpcy5iaXRCb2FyZCBpbnN0YW5jZW9mIExvbmdJbnRCaXRCb2FyZCA/IHRoaXMuYml0Qm9hcmQuZGF0YS53b3JkQ291bnQgOiAxKSAqIDMyO1xuICAgICAgICBjb25zdCBib2FyZFNpemUgPSB0aGlzLmJvYXJkV2lkdGggKiB0aGlzLmJvYXJkSGVpZ2h0O1xuXG4gICAgICAgIHJldHVybiB0aGlzLmJpdEJvYXJkLmxlZnRTaGlmdCh0b3RhbEJpdHMgLSBib2FyZFNpemUgKiAocGxheWVySWQgKyAxKSkucmlnaHRTaGlmdCh0b3RhbEJpdHMgLSBib2FyZFNpemUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYSBiaXQgaW5kZXggZnJvbSBpdHMgY29vcmRpbmF0ZXMuXG4gICAgICogQHBhcmFtIG1vdmUgVGhlIGNvb3JkaW5hdGVzLlxuICAgICAqIEByZXR1cm5zIFRoZSBiaXQgaW5kZXguXG4gICAgICovXG4gICAgcHJpdmF0ZSBnZXRJbmRleChtb3ZlOiBQb3NpdGlvbik6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLmJvYXJkV2lkdGggKiBtb3ZlLnkgKyBtb3ZlLng7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgbW92ZSBpcyB2YWxpZCBmb3IgdGhlIGdpdmVuIGJvYXJkLlxuICAgICAqIERvZXMgbm90IGNoZWNrIGlmIHRoYXQgY2VsbCBpcyBhbHJlYWR5IG9jY3VwaWVkLlxuICAgICAqIEBwYXJhbSBwb3NpdGlvbiBUaGUgcG9zaXRpb24gdG8gY2hlY2suXG4gICAgICogQHJldHVybnMgV2hldGhlciBvciBub3QgdGhhdCBjZWxsIGV4aXN0cyBvbiB0aGUgYm9hcmQuXG4gICAgICovXG4gICAgcHJpdmF0ZSBpc1ZhbGlkUG9zaXRpb24ocG9zaXRpb246IFBvc2l0aW9uKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBwb3NpdGlvbi54ID49IDAgJiYgcG9zaXRpb24ueCA8IHRoaXMuYm9hcmRXaWR0aCAmJiBwb3NpdGlvbi55ID49IDAgJiYgcG9zaXRpb24ueSA8IHRoaXMuYm9hcmRIZWlnaHQ7XG4gICAgfVxufVxuIl19
290
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9hcmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYmFzZS9ib2FyZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLFdBQVcsTUFBTSw0QkFBNEIsQ0FBQztBQUNyRCxPQUFPLE9BQU8sTUFBTSx3QkFBd0IsQ0FBQztBQUM3QyxPQUFPLGVBQWUsTUFBTSxnQ0FBZ0MsQ0FBQztBQXNCN0Q7OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBZ0IsS0FBSztJQUMvQiw4Q0FBOEM7SUFDM0IsUUFBUSxDQUFjO0lBRXpDLG1DQUFtQztJQUNoQixLQUFLLENBQVM7SUFFakMsb0NBQW9DO0lBQ2pCLE1BQU0sQ0FBUztJQUVsQyx3QkFBd0I7SUFDTCxLQUFLLEdBQWEsRUFBRSxDQUFDO0lBRXhDLCtFQUErRTtJQUM5RCxvQkFBb0IsQ0FBUztJQUU5QyxzREFBc0Q7SUFDckMsY0FBYyxDQUFTO0lBS3hDOzs7Ozs7T0FNRztJQUNILFlBQXNCLEtBQWEsRUFBRSxNQUFjLEVBQUUsbUJBQTJCLENBQUMsRUFBRSxrQkFBMEIsQ0FBQztRQUMxRyxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsb0JBQW9CLEdBQUcsZ0JBQWdCLENBQUM7UUFDN0MsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsZUFBZSxDQUFDO1FBQ2xFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBRWpFLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxTQUFTLEdBQUcsRUFBRTtZQUMzQixDQUFDLENBQUMsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDaEQsQ0FBQyxDQUFD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YyxDQUFDLFFBQWdCO1FBQ3JDLE1BQU0sU0FBUyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsWUFBWSxlQUFlLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3JHLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUUzQyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxTQUFTLEdBQUcsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxDQUFDO0lBQzdHLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssUUFBUSxDQUFDLElBQWM7UUFDM0IsT0FBTyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSyxlQUFlLENBQUMsUUFBa0I7UUFDdEMsT0FBTyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxRQUFRLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksUUFBUSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ3JHLENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIEJpdEJvYXJkIGZyb20gXCIuLi9iaXRCb2FyZC9iaXRCb2FyZC5qc1wiO1xuaW1wb3J0IEludEJpdEJvYXJkIGZyb20gXCIuLi9iaXRCb2FyZC9pbnRCaXRCb2FyZC5qc1wiO1xuaW1wb3J0IExvbmdJbnQgZnJvbSBcIi4uL2JpdEJvYXJkL2xvbmdJbnQuanNcIjtcbmltcG9ydCBMb25nSW50Qml0Qm9hcmQgZnJvbSBcIi4uL2JpdEJvYXJkL2xvbmdJbnRCaXRCb2FyZC5qc1wiO1xuXG5leHBvcnQgdHlwZSBQb3NpdGlvbiA9IHtcbiAgICB5OiBudW1iZXI7XG4gICAgeDogbnVtYmVyO1xufTtcblxuLyoqIERlZmluZXMgdGhlIGNoYXJhY3RlcnMgdXNlZCB0byBkcmF3IGEgZ3JpZC4gKi9cbmV4cG9ydCBjb25zdCBlbnVtIEdyaWRMaW5lcyB7XG4gICAgSG9yaXpvbnRhbCA9IFwiXFx1MjUwMFwiLFxuICAgIFZlcnRpY2FsID0gXCJcXHUyNTAyXCIsXG4gICAgVG9wTGVmdCA9IFwiXFx1MjUwQ1wiLFxuICAgIFRvcFJpZ2h0ID0gXCJcXHUyNTEwXCIsXG4gICAgQm90dG9tTGVmdCA9IFwiXFx1MjUxNFwiLFxuICAgIEJvdHRvbVJpZ2h0ID0gXCJcXHUyNTE4XCIsXG4gICAgVExlZnQgPSBcIlxcdTI1MUNcIixcbiAgICBUUmlnaHQgPSBcIlxcdTI1MjRcIixcbiAgICBUVG9wID0gXCJcXHUyNTJDXCIsXG4gICAgVEJvdHRvbSA9IFwiXFx1MjUzNFwiLFxuICAgIENyb3NzID0gXCJcXHUyNTNDXCIsXG59XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIGdhbWUgYm9hcmQuXG4gKiBAdGVtcGxhdGUgVCAtIFRoZSB0eXBlIG9mIHRoZSBudW1lcmljIGRhdGEuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGFic3RyYWN0IGNsYXNzIEJvYXJkPFQgZXh0ZW5kcyBMb25nSW50IHwgbnVtYmVyPiB7XG4gICAgLyoqIENvbnRhaW5zIHRoZSBkYXRhIHN0b3JlZCBpbiBhIEJpdEJvYXJkLiAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSBiaXRCb2FyZDogQml0Qm9hcmQ8VD47XG5cbiAgICAvKiogVGhlIHdpZHRoIG9mIHRoZSBnYW1lIGJvYXJkLiAqL1xuICAgIHByb3RlY3RlZCByZWFkb25seSB3aWR0aDogbnVtYmVyO1xuXG4gICAgLyoqIFRoZSBoZWlnaHQgb2YgdGhlIGdhbWUgYm9hcmQuICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGhlaWdodDogbnVtYmVyO1xuXG4gICAgLyoqIEEgc3RhY2sgb2YgbW92ZXMuICovXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IG1vdmVzOiBudW1iZXJbXSA9IFtdO1xuXG4gICAgLyoqIEhvdyBtYW55IGJvYXJkcyB0aGVyZSBhcmUgcmVwcmVzZW50aW5nIHBsYXllciBwb3NpdGlvbnMgKG1vc3QgbGlrZWx5IDIpLiAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgbnVtYmVyT2ZQbGF5ZXJCb2FyZHM6IG51bWJlcjtcblxuICAgIC8qKiBOdW1iZXIgb2YgYm9hcmRzIGluIHRvdGFsIChtb3N0IGxpa2VseSBhbHNvIDIpLiAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgbnVtYmVyT2ZCb2FyZHM6IG51bWJlcjtcblxuICAgIC8qKiBUaGUgYm9hcmQgc3RhdGVzIHdoaWNoIHJlcHJlc2VudCBhIHdpbm5pbmcgc3RhdGUuICovXG4gICAgcHJvdGVjdGVkIGFic3RyYWN0IHJlYWRvbmx5IHdpbm5pbmdTdGF0ZXM6IEFycmF5PEJpdEJvYXJkPFQ+PjtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgQm9hcmQuXG4gICAgICogQHBhcmFtIHdpZHRoIC0gVGhlIHdpZHRoIG9mIHRoZSBnYW1lIGJvYXJkLlxuICAgICAqIEBwYXJhbSBoZWlnaHQgLSBUaGUgaGVpZ2h0IG9mIHRoZSBnYW1lIGJvYXJkLlxuICAgICAqIEBwYXJhbSBwbGF5ZXJCb2FyZENvdW50IC0gSG93IG1hbnkgYm9hcmRzIHRoZXJlIGFyZSByZXByZXNlbnRpbmcgcGxheWVyIHBvc2l0aW9ucyAobW9zdCBsaWtlbHkgMikuXG4gICAgICogQHBhcmFtIGV4dHJhQm9hcmRDb3VudCAtIE51bWJlciBvZiBleHRyYSBib2FyZHMgKG1vc3QgbGlrZWx5IDApLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBjb25zdHJ1Y3Rvcih3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgcGxheWVyQm9hcmRDb3VudDogbnVtYmVyID0gMiwgZXh0cmFCb2FyZENvdW50OiBudW1iZXIgPSAwKSB7XG4gICAgICAgIHRoaXMud2lkdGggPSB3aWR0aDtcbiAgICAgICAgdGhpcy5oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgIHRoaXMubnVtYmVyT2ZQbGF5ZXJCb2FyZHMgPSBwbGF5ZXJCb2FyZENvdW50O1xuICAgICAgICB0aGlzLm51bWJlck9mQm9hcmRzID0gdGhpcy5udW1iZXJPZlBsYXllckJvYXJkcyArIGV4dHJhQm9hcmRDb3VudDtcbiAgICAgICAgY29uc3QgdG90YWxCaXRzID0gdGhpcy53aWR0aCAqIHRoaXMuaGVpZ2h0ICogdGhpcy5udW1iZXJPZkJvYXJkcztcblxuICAgICAgICB0aGlzLmJpdEJvYXJkID0gKHRvdGFsQml0cyA+IDMyXG4gICAgICAgICAgICA/IG5ldyBMb25nSW50Qml0Qm9hcmQoTWF0aC5jZWlsKHRvdGFsQml0cyAvIDMyKSlcbiAgICAgICAgICAgIDogbmV3IEludEJpdEJvYXJkKCkpIGFzIEJpdEJvYXJkPFQ+O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZXMgd2hldGhlciBvciBub3QgdGhlIGJvYXJkIGlzIGZ1bGwuXG4gICAgICogQHJldHVybnMgV2hldGhlciBvciBub3QgdGhlIGJvYXJkIGlzIGZ1bGwuXG4gICAgICovXG4gICAgcHVibGljIGdldCBpc0Z1bGwoKTogYm9vbGVhbiB7XG4gICAgICAgIGxldCBpc0Z1bGwgPSAodGhpcy5iaXRCb2FyZCBpbnN0YW5jZW9mIExvbmdJbnRCaXRCb2FyZFxuICAgICAgICAgICAgPyBuZXcgTG9uZ0ludEJpdEJvYXJkKE1hdGguY2VpbCh0aGlzLndpZHRoICogdGhpcy5oZWlnaHQgLyAzMikpXG4gICAgICAgICAgICA6IG5ldyBJbnRCaXRCb2FyZCgpKSBhcyBCaXRCb2FyZDxUPjtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubnVtYmVyT2ZQbGF5ZXJCb2FyZHM7IGkrKylcbiAgICAgICAgICAgIGlzRnVsbCA9IGlzRnVsbC5vcih0aGlzLmdldFBsYXllckJvYXJkKGkpKTtcbiAgICAgICAgY29uc3QgZnVsbFZhbHVlID0gKHRoaXMuYml0Qm9hcmQgaW5zdGFuY2VvZiBMb25nSW50Qml0Qm9hcmRcbiAgICAgICAgICAgID8gbmV3IExvbmdJbnQoW1xuICAgICAgICAgICAgICAgIC4uLkFycmF5PG51bWJlcj4oTWF0aC5jZWlsKHRoaXMud2lkdGggKiB0aGlzLmhlaWdodCAvIDMyKSAtIDEpLmZpbGwofjAgPj4+IDApLFxuICAgICAgICAgICAgICAgIDIgKiogKHRoaXMud2lkdGggKiB0aGlzLmhlaWdodCAtIChNYXRoLmNlaWwodGhpcy53aWR0aCAqIHRoaXMuaGVpZ2h0IC8gMzIpIC0gMSkgKiAzMikgLSAxLFxuICAgICAgICAgICAgXSlcbiAgICAgICAgICAgIDogMiAqKiAodGhpcy53aWR0aCAqIHRoaXMuaGVpZ2h0KSAtIDEpIGFzIFQ7XG5cbiAgICAgICAgcmV0dXJuIGlzRnVsbC5lcXVhbHMoZnVsbFZhbHVlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIHdoZXRoZXIgb3Igbm90IHRoZSBib2FyZCBpcyBlbXB0eS5cbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCB0aGUgYm9hcmQgaXMgZW1wdHkuXG4gICAgICovXG4gICAgcHVibGljIGdldCBpc0VtcHR5KCk6IGJvb2xlYW4ge1xuICAgICAgICBsZXQgaXNFbXB0eSA9ICh0aGlzLmJpdEJvYXJkIGluc3RhbmNlb2YgTG9uZ0ludEJpdEJvYXJkXG4gICAgICAgICAgICA/IG5ldyBMb25nSW50Qml0Qm9hcmQoTWF0aC5jZWlsKHRoaXMud2lkdGggKiB0aGlzLmhlaWdodCAvIDMyKSlcbiAgICAgICAgICAgIDogbmV3IEludEJpdEJvYXJkKCkpIGFzIEJpdEJvYXJkPFQ+O1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5udW1iZXJPZlBsYXllckJvYXJkczsgaSsrKVxuICAgICAgICAgICAgaXNFbXB0eSA9IGlzRW1wdHkub3IodGhpcy5nZXRQbGF5ZXJCb2FyZChpKSk7XG5cbiAgICAgICAgcmV0dXJuIGlzRW1wdHkuZXF1YWxzKDApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZXMgd2hvIHRoZSB3aW5uZXIgaXMuXG4gICAgICogQHJldHVybnMgYGZhbHNlYCBpZiB0aGUgZ2FtZSBpcyBub3Qgb3ZlciwgdGhlIHBsYXllciBJRCBpZiB0aGVyZSBpcyBhIHdpbm5lciwgYW5kIGBudWxsYCBpZiB0aGVyZSBpcyBhIGRyYXcuXG4gICAgICovXG4gICAgcHVibGljIGdldCB3aW5uZXIoKTogMCB8IDEgfCBmYWxzZSB8IG51bGwge1xuICAgICAgICBjb25zdCBwbGF5ZXJPbmVCb2FyZCA9IHRoaXMuZ2V0UGxheWVyQm9hcmQoMCk7XG4gICAgICAgIGNvbnN0IHBsYXllclR3b0JvYXJkID0gdGhpcy5nZXRQbGF5ZXJCb2FyZCgxKTtcblxuICAgICAgICBmb3IgKGNvbnN0IHN0YXRlIG9mIHRoaXMud2lubmluZ1N0YXRlcykge1xuICAgICAgICAgICAgaWYgKHBsYXllck9uZUJvYXJkLmFuZChzdGF0ZSkuZXF1YWxzKHN0YXRlKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gMDtcblxuICAgICAgICAgICAgaWYgKHBsYXllclR3b0JvYXJkLmFuZChzdGF0ZSkuZXF1YWxzKHN0YXRlKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmlzRnVsbClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGVzIHdoaWNoIGNlbGxzIGFyZSBlbXB0eS5cbiAgICAgKiBAcmV0dXJucyBUaGUgZW1wdHkgY2VsbHMgb24gdGhlIGJvYXJkLlxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgZW1wdHlDZWxscygpOiBQb3NpdGlvbltdIHtcbiAgICAgICAgY29uc3QgZW1wdHlDZWxsczogUG9zaXRpb25bXSA9IFtdO1xuXG4gICAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgdGhpcy5oZWlnaHQ7IHkrKykge1xuICAgICAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCB0aGlzLndpZHRoOyB4KyspIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jZWxsT2NjdXBpZXIoeyB4LCB5IH0pID09PSBudWxsKVxuICAgICAgICAgICAgICAgICAgICBlbXB0eUNlbGxzLnB1c2goeyB4LCB5IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVtcHR5Q2VsbHM7XG4gICAgfVxuXG4gICAgLyoqIENhbGN1bGF0ZXMgdGhlIGhldXJpc3RpYyBzY29yZSBmb3IgYSBnaXZlbiBib2FyZCBzdGF0ZS4gKi9cbiAgICBwdWJsaWMgYWJzdHJhY3QgZ2V0IGhldXJpc3RpYygpOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhIG1vdmUgb24gdGhlIGJvYXJkLlxuICAgICAqIEBwYXJhbSBtb3ZlIC0gVGhlIHBvc2l0aW9uIG9mIHRoZSBtb3ZlLlxuICAgICAqIEBwYXJhbSBwbGF5ZXJJZCAtIFRoZSBwbGF5ZXIgd2hvJ3MgbWFraW5nIHRoZSBtb3ZlLlxuICAgICAqL1xuICAgIHB1YmxpYyBtYWtlTW92ZShtb3ZlOiBQb3NpdGlvbiwgcGxheWVySWQ6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBiaXQgPSB0aGlzLmdldEJpdEluZGV4KG1vdmUsIHBsYXllcklkKTtcblxuICAgICAgICB0aGlzLm1vdmVzLnB1c2goYml0KTtcbiAgICAgICAgdGhpcy5iaXRCb2FyZC5zZXRCaXQoYml0KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZXZlcnNlcyB0aGUgbGFzdCBtb3ZlLlxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSAtIElmIHRoZXJlIGlzIG5vIG1vdmUgdG8gdW5kby5cbiAgICAgKi9cbiAgICBwdWJsaWMgdW5kb0xhc3RNb3ZlKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBsYXN0TW92ZSA9IHRoaXMubW92ZXMucG9wKCk7XG5cbiAgICAgICAgaWYgKGxhc3RNb3ZlID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBtb3ZlIHRvIHVuZG8uXCIpO1xuXG4gICAgICAgIHRoaXMuYml0Qm9hcmQuY2xlYXJCaXQobGFzdE1vdmUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyBpZiBhIG1vdmUgaXMgdmFsaWQuXG4gICAgICogQHBhcmFtIG1vdmUgLSBUaGUgcG9zaXRpb24gb2YgdGhlIG1vdmUuXG4gICAgICogQHJldHVybnMgV2hldGhlciBvciBub3QgaXQncyB2YWxpZC5cbiAgICAgKi9cbiAgICBwdWJsaWMgbW92ZUlzVmFsaWQobW92ZTogUG9zaXRpb24pOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZFBvc2l0aW9uKG1vdmUpICYmIHRoaXMuY2VsbE9jY3VwaWVyKG1vdmUpID09PSBudWxsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoZWNrcyB3aGljaCBwbGF5ZXIgaXMgb2NjdXB5aW5nIGEgZ2l2ZW4gY2VsbC5cbiAgICAgKiBAcGFyYW0gY2VsbCAtIFRoZSBjZWxsIHRvIGNoZWNrLlxuICAgICAqIEByZXR1cm5zIElmIHRoZSBjZWxsIGlzIGVtcHR5LCB0aGUgb3V0cHV0IGlzIG51bGwsIG90aGVyd2lzZSB0aGUgb3V0cHV0IGlzIHRoZSBwbGF5ZXIncyBJRC5cbiAgICAgKi9cbiAgICBwdWJsaWMgY2VsbE9jY3VwaWVyKGNlbGw6IFBvc2l0aW9uKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5udW1iZXJPZlBsYXllckJvYXJkczsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5iaXRCb2FyZC5nZXRCaXQodGhpcy5nZXRCaXRJbmRleChjZWxsLCBpKSkgPT09IDEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBib2FyZC5cbiAgICAgKiBAcGFyYW0gd3JhcCAtIFdoZXRoZXIgb3Igbm90IHRvIHByb3ZpZGUgYSBib3JkZXIgZm9yIHRoZSBib2FyZC5cbiAgICAgKiBAcGFyYW0gbGFiZWxYIC0gV2hldGhlciBvciBub3QgdG8gbGFiZWwgeC5cbiAgICAgKiBAcGFyYW0gbGFiZWxZIC0gV2hldGhlciBvciBub3QgdG8gbGFiZWwgeS5cbiAgICAgKiBAcGFyYW0gc3ltYm9scyAtIFRoZSBzeW1ib2xzIHRvIHVzZSBhcyBib2FyZCBwaWVjZXMuXG4gICAgICogQHBhcmFtIGNvbG91ciAtIFdoZXRoZXIgb3Igbm90IHRvIGNvbG91ciB0aGUgcGllY2VzLlxuICAgICAqIEByZXR1cm5zIFRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24uXG4gICAgICogQHRocm93cyB7RXJyb3J9IC0gSWYgdGhlIHN5bWJvbHMgYXJlIG5vdCB0aGUgc2FtZSBsZW5ndGguXG4gICAgICovXG4gICAgcHVibGljIHRvU3RyaW5nKFxuICAgICAgICB3cmFwOiBib29sZWFuID0gdHJ1ZSxcbiAgICAgICAgbGFiZWxYOiBib29sZWFuID0gdHJ1ZSxcbiAgICAgICAgbGFiZWxZOiBib29sZWFuID0gdHJ1ZSxcbiAgICAgICAgc3ltYm9sczogc3RyaW5nW10gPSBbXCJYXCIsIFwiT1wiXSxcbiAgICAgICAgY29sb3VyOiBib29sZWFuID0gdHJ1ZSxcbiAgICApOiBzdHJpbmcge1xuICAgICAgICBpZiAoc3ltYm9scy5sZW5ndGggIT09IHRoaXMubnVtYmVyT2ZQbGF5ZXJCb2FyZHMpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUb28gbWFueSBzeW1ib2xzLlwiKTtcblxuICAgICAgICBjb25zdCBzeW1ib2xMZW5ndGggPSBzeW1ib2xzWzBdIS5sZW5ndGg7XG5cbiAgICAgICAgaWYgKHN5bWJvbHMuc29tZSgocykgPT4gcy5sZW5ndGggIT09IHN5bWJvbExlbmd0aCkpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW1ib2xzIG11c3QgYmUgdGhlIHNhbWUgbGVuZ3RoLlwiKTtcblxuICAgICAgICBjb25zdCBtYXRjaENlbGxTcGFjZSA9IG5ldyBSZWdFeHAoYC57JHtzeW1ib2xMZW5ndGggKyAyfX1gLCBcImd1XCIpO1xuICAgICAgICBjb25zdCBhbHBoYWJldCA9IFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiO1xuICAgICAgICBjb25zdCB4TGFiZWxzID0gbGFiZWxYXG4gICAgICAgICAgICA/IGAke2FscGhhYmV0LnNsaWNlKDAsIHRoaXMud2lkdGgpXG4gICAgICAgICAgICAgICAgLnNwbGl0KFwiXCIpXG4gICAgICAgICAgICAgICAgLm1hcCgobGV0dGVyKSA9PiBgICR7bGV0dGVyLnBhZFN0YXJ0KHN5bWJvbExlbmd0aCl9IGApXG4gICAgICAgICAgICAgICAgLmpvaW4oXCJcIilcbiAgICAgICAgICAgICAgICAubWF0Y2gobWF0Y2hDZWxsU3BhY2UpIVxuICAgICAgICAgICAgICAgIC5qb2luKFwiIFwiKVxuICAgICAgICAgICAgICAgIC5wYWRTdGFydCg0ICogdGhpcy53aWR0aCAtIDEgKyBOdW1iZXIod3JhcCkgKyBOdW1iZXIobGFiZWxZKSlcbiAgICAgICAgICAgIH1cXG5gXG4gICAgICAgICAgICA6IFwiXCI7XG4gICAgICAgIGNvbnN0IHRvcEJvcmRlciA9IHdyYXBcbiAgICAgICAgICAgID8gYCR7bGFiZWxZID8gXCIgXCIgOiBcIlwifSR7R3JpZExpbmVzLlRvcExlZnR9JHtHcmlkTGluZXMuSG9yaXpvbnRhbFxuICAgICAgICAgICAgICAgIC5yZXBlYXQodGhpcy53aWR0aCAqIChzeW1ib2xMZW5ndGggKyAyKSlcbiAgICAgICAgICAgICAgICAubWF0Y2gobWF0Y2hDZWxsU3BhY2UpIVxuICAgICAgICAgICAgICAgIC5qb2luKEdyaWRMaW5lcy5UVG9wKX0ke0dyaWRMaW5lcy5Ub3BSaWdodH1cXG5gXG4gICAgICAgICAgICA6IFwiXCI7XG4gICAgICAgIGNvbnN0IGJvdHRvbUJvcmRlciA9IHdyYXBcbiAgICAgICAgICAgID8gYCR7bGFiZWxZID8gXCIgXCIgOiBcIlwifSR7R3JpZExpbmVzLkJvdHRvbUxlZnR9JHtHcmlkTGluZXMuSG9yaXpvbnRhbFxuICAgICAgICAgICAgICAgIC5yZXBlYXQodGhpcy53aWR0aCAqIChzeW1ib2xMZW5ndGggKyAyKSlcbiAgICAgICAgICAgICAgICAubWF0Y2gobWF0Y2hDZWxsU3BhY2UpIVxuICAgICAgICAgICAgICAgIC5qb2luKEdyaWRMaW5lcy5UQm90dG9tKX0ke0dyaWRMaW5lcy5Cb3R0b21SaWdodH1gXG4gICAgICAgICAgICA6IFwiXCI7XG4gICAgICAgIGNvbnN0IHJvd1NlcGFyYXRvciA9IGAke2xhYmVsWSA/IFwiIFwiIDogXCJcIn0ke3dyYXAgPyBHcmlkTGluZXMuVExlZnQgOiBcIlwifSR7R3JpZExpbmVzLkhvcml6b250YWxcbiAgICAgICAgICAgIC5yZXBlYXQodGhpcy53aWR0aCAqIChzeW1ib2xMZW5ndGggKyAyKSlcbiAgICAgICAgICAgIC5tYXRjaChtYXRjaENlbGxTcGFjZSkhXG4gICAgICAgICAgICAuam9pbihHcmlkTGluZXMuQ3Jvc3MpfSR7d3JhcCA/IEdyaWRMaW5lcy5UUmlnaHQgOiBcIlwifVxcbmA7XG4gICAgICAgIGNvbnN0IHJvd3M6IHN0cmluZ1tdID0gW107XG5cbiAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCB0aGlzLmhlaWdodDsgeSsrKSB7XG4gICAgICAgICAgICBjb25zdCB5TGFiZWwgPSBsYWJlbFkgPyBgJHt5ICsgMX1gIDogXCJcIjtcbiAgICAgICAgICAgIGNvbnN0IGxlZnRCb3JkZXIgPSB3cmFwID8gR3JpZExpbmVzLlZlcnRpY2FsIDogXCJcIjtcbiAgICAgICAgICAgIGNvbnN0IHJpZ2h0Qm9yZGVyID0gd3JhcCA/IEdyaWRMaW5lcy5WZXJ0aWNhbCA6IFwiXCI7XG4gICAgICAgICAgICBsZXQgcm93ID0gYCR7eUxhYmVsfSR7bGVmdEJvcmRlcn1gO1xuXG4gICAgICAgICAgICBmb3IgKGxldCB4ID0gMDsgeCA8IHRoaXMud2lkdGg7IHgrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNlbGwgPSB7IHgsIHkgfTtcbiAgICAgICAgICAgICAgICBjb25zdCBiYXIgPSB4ID09PSB0aGlzLndpZHRoIC0gMSA/IFwiXCIgOiBHcmlkTGluZXMuVmVydGljYWw7XG4gICAgICAgICAgICAgICAgY29uc3QgY2VsbE9jY3VwaWVyID0gdGhpcy5jZWxsT2NjdXBpZXIoY2VsbCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoY2VsbE9jY3VwaWVyID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJvdyArPSBgICR7XCIgXCIucmVwZWF0KHN5bWJvbExlbmd0aCl9ICR7YmFyfWA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcm93ICs9IGAgJHtjb2xvdXIgPyBgXFx4MWJbJHtbOTEsIDkzXVtjZWxsT2NjdXBpZXJdIX1tYCA6IFwiXCJ9YCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgJHtzeW1ib2xzW2NlbGxPY2N1cGllcl19YCArXG4gICAgICAgICAgICAgICAgICAgICAgICBgJHtjb2xvdXIgPyBcIlxceDFiWzBtXCIgOiBcIlwifSAke2Jhcn1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJvd3MucHVzaChgJHtyb3d9JHtyaWdodEJvcmRlcn1cXG5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBgJHt4TGFiZWxzfSR7dG9wQm9yZGVyfSR7cm93cy5qb2luKHJvd1NlcGFyYXRvcil9JHtib3R0b21Cb3JkZXJ9YDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmVzIGlmIGEgZ2l2ZW4gcGxheWVyIGhhcyBhIGxpbmUgb2YgcGllY2VzIG9uIHRoZSBib2FyZC5cbiAgICAgKiBAcGFyYW0gcGxheWVySWQgLSBUaGUgSUQgb2YgdGhlIHBsYXllciB0byBjaGVjay5cbiAgICAgKiBAcGFyYW0gbGVuZ3RoIC0gVGhlIG51bWJlciBvZiBwaWVjZXMgbmVlZGVkLlxuICAgICAqIEBwYXJhbSBtYXhHYXBzIC0gVGhlIG51bWJlciBvZiBnYXBzIGFsbG93ZWQgZm9yIGEgbGluZSB0byBiZSB2YWxpZC4gRGVmYXVsdHMgdG8gMC5cbiAgICAgKiBAcmV0dXJucyBIb3cgbWFueSBsaW5lcyBleGlzdC5cbiAgICAgKi9cbiAgICBwdWJsaWMgaGFzTGluZShwbGF5ZXJJZDogbnVtYmVyLCBsZW5ndGg6IG51bWJlciwgbWF4R2FwczogbnVtYmVyID0gMCk6IG51bWJlciB7XG4gICAgICAgIGlmIChsZW5ndGggPiBNYXRoLm1heCh0aGlzLndpZHRoLCB0aGlzLmhlaWdodCkpXG4gICAgICAgICAgICByZXR1cm4gMDtcblxuICAgICAgICBjb25zdCBESVJFQ1RJT05TOiBbUG9zaXRpb24sIFBvc2l0aW9uLCBQb3NpdGlvbiwgUG9zaXRpb25dID0gW1xuICAgICAgICAgICAgeyB4OiAxLCB5OiAwIH0sXG4gICAgICAgICAgICB7IHg6IDAsIHk6IDEgfSxcbiAgICAgICAgICAgIHsgeDogMSwgeTogMSB9LFxuICAgICAgICAgICAgeyB4OiAxLCB5OiAtMSB9LFxuICAgICAgICBdO1xuICAgICAgICBsZXQgbGluZUNvdW50ID0gMDtcbiAgICAgICAgbGV0IGdhcHM6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzAsIDAsIDAsIDBdO1xuICAgICAgICBsZXQgbGVuZ3RoczogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMCwgMCwgMCwgMF07XG4gICAgICAgIGNvbnN0IGNoZWNrQ2VsbCA9ICh4OiBudW1iZXIsIHk6IG51bWJlciwgZGlyZWN0aW9uOiAwIHwgMSB8IDIgfCAzKTogdm9pZCA9PiB7XG4gICAgICAgICAgICBjb25zdCBjZWxsID0geyB4LCB5IH0gYXMgUG9zaXRpb247XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmlzVmFsaWRQb3NpdGlvbihjZWxsKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNlbGxPY2N1cGllciA9IHRoaXMuY2VsbE9jY3VwaWVyKGNlbGwpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGNlbGxPY2N1cGllciA9PT0gbnVsbClcbiAgICAgICAgICAgICAgICAgICAgZ2Fwc1tkaXJlY3Rpb25dKys7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoY2VsbE9jY3VwaWVyID09PSBwbGF5ZXJJZClcbiAgICAgICAgICAgICAgICAgICAgbGVuZ3Roc1tkaXJlY3Rpb25dKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCB0aGlzLndpZHRoOyB4KyspIHtcbiAgICAgICAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgdGhpcy5oZWlnaHQ7IHkrKykge1xuICAgICAgICAgICAgICAgIGdhcHMgPSBbMCwgMCwgMCwgMF07XG4gICAgICAgICAgICAgICAgbGVuZ3RocyA9IFswLCAwLCAwLCAwXTtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwIGFzIDAgfCAxIHwgMiB8IDM7IGogPCA0OyBqKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnYXBzW2pdID4gbWF4R2FwcylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tDZWxsKHggKyBpICogRElSRUNUSU9OU1tqXS54LCB5ICsgaSAqIERJUkVDVElPTlNbal0ueSwgaik7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsZW5ndGhzW2pdID09PSBsZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGluZUNvdW50Kys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbGluZUNvdW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYSBiaXQgaW5kZXggZnJvbSBpdHMgY29vcmRpbmF0ZXMgYW5kIHBsYXllciBJRC5cbiAgICAgKiBAcGFyYW0gbW92ZSAtIFRoZSBjb29yZGluYXRlcy5cbiAgICAgKiBAcGFyYW0gcGxheWVySWQgLSBUaGUgcGxheWVyIElEIHRvIHVzZS5cbiAgICAgKiBAcmV0dXJucyBUaGUgYml0IGluZGV4IG9mIHRoZSBtb3ZlLlxuICAgICAqL1xuICAgIHByb3RlY3RlZCBnZXRCaXRJbmRleChtb3ZlOiBQb3NpdGlvbiwgcGxheWVySWQ6IG51bWJlcik6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IG1vdmVJbmRleCA9IHRoaXMuZ2V0SW5kZXgobW92ZSk7XG4gICAgICAgIGNvbnN0IGJpdEJvYXJkTW92ZUluZGV4ID0gbW92ZUluZGV4ICsgdGhpcy53aWR0aCAqIHRoaXMuaGVpZ2h0ICogcGxheWVySWQ7XG5cbiAgICAgICAgcmV0dXJuIGJpdEJvYXJkTW92ZUluZGV4O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgQml0Qm9hcmQgY29udGFpbmluZyBvbmx5IHRoZSBwbGF5ZXIncyBiaXRzLlxuICAgICAqIEBwYXJhbSBwbGF5ZXJJZCAtIFRoZSBwbGF5ZXIncyBJRCB0byBnZXQgdGhlIGJvYXJkIGZvci5cbiAgICAgKiBAcmV0dXJucyBUaGUgcGxheWVyJ3MgYml0cy5cbiAgICAgKi9cbiAgICBwcm90ZWN0ZWQgZ2V0UGxheWVyQm9hcmQocGxheWVySWQ6IG51bWJlcik6IEJpdEJvYXJkPFQ+IHtcbiAgICAgICAgY29uc3QgdG90YWxCaXRzID0gKHRoaXMuYml0Qm9hcmQgaW5zdGFuY2VvZiBMb25nSW50Qml0Qm9hcmQgPyB0aGlzLmJpdEJvYXJkLmRhdGEud29yZENvdW50IDogMSkgKiAzMjtcbiAgICAgICAgY29uc3QgYm9hcmRTaXplID0gdGhpcy53aWR0aCAqIHRoaXMuaGVpZ2h0O1xuXG4gICAgICAgIHJldHVybiB0aGlzLmJpdEJvYXJkLmxlZnRTaGlmdCh0b3RhbEJpdHMgLSBib2FyZFNpemUgKiAocGxheWVySWQgKyAxKSkucmlnaHRTaGlmdCh0b3RhbEJpdHMgLSBib2FyZFNpemUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYSBiaXQgaW5kZXggZnJvbSBpdHMgY29vcmRpbmF0ZXMuXG4gICAgICogQHBhcmFtIG1vdmUgLSBUaGUgY29vcmRpbmF0ZXMuXG4gICAgICogQHJldHVybnMgVGhlIGJpdCBpbmRleC5cbiAgICAgKi9cbiAgICBwcml2YXRlIGdldEluZGV4KG1vdmU6IFBvc2l0aW9uKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMud2lkdGggKiBtb3ZlLnkgKyBtb3ZlLng7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGEgbW92ZSBpcyB2YWxpZCBmb3IgdGhlIGdpdmVuIGJvYXJkLlxuICAgICAqIERvZXMgbm90IGNoZWNrIGlmIHRoYXQgY2VsbCBpcyBhbHJlYWR5IG9jY3VwaWVkLlxuICAgICAqIEBwYXJhbSBwb3NpdGlvbiAtIFRoZSBwb3NpdGlvbiB0byBjaGVjay5cbiAgICAgKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCB0aGF0IGNlbGwgZXhpc3RzIG9uIHRoZSBib2FyZC5cbiAgICAgKi9cbiAgICBwcml2YXRlIGlzVmFsaWRQb3NpdGlvbihwb3NpdGlvbjogUG9zaXRpb24pOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBvc2l0aW9uLnggPj0gMCAmJiBwb3NpdGlvbi54IDwgdGhpcy53aWR0aCAmJiBwb3NpdGlvbi55ID49IDAgJiYgcG9zaXRpb24ueSA8IHRoaXMuaGVpZ2h0O1xuICAgIH1cbn1cbiJdfQ==