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