@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 +6 -0
- package/build/base/board.d.ts +53 -38
- package/build/base/board.js +84 -63
- package/build/base/controller.d.ts +37 -26
- package/build/base/controller.js +31 -24
- package/build/bitBoard/bitBoard.d.ts +37 -34
- package/build/bitBoard/bitBoard.js +15 -12
- package/build/bitBoard/intBitBoard.d.ts +22 -22
- package/build/bitBoard/intBitBoard.js +16 -16
- package/build/bitBoard/longInt.d.ts +47 -40
- package/build/bitBoard/longInt.js +40 -37
- package/build/bitBoard/longIntBitBoard.d.ts +26 -26
- package/build/bitBoard/longIntBitBoard.js +16 -16
- package/build/console.d.ts +2 -3
- package/build/console.js +3 -4
- package/build/games/connect4/board.d.ts +12 -5
- package/build/games/connect4/board.js +12 -6
- package/build/games/connect4/controller.d.ts +16 -9
- package/build/games/connect4/controller.js +19 -11
- package/build/games/tictactoe/board.d.ts +5 -2
- package/build/games/tictactoe/board.js +5 -2
- package/build/games/tictactoe/controller.d.ts +15 -10
- package/build/games/tictactoe/controller.js +18 -12
- package/eslint.config.js +1 -1
- package/package.json +6 -7
- package/patches/eventemitter3@5.0.1.patch +0 -68
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)
|
package/build/base/board.d.ts
CHANGED
|
@@ -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
|
-
/**
|
|
21
|
-
|
|
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
|
|
26
|
-
/** The height of the board. */
|
|
27
|
-
protected readonly
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
*
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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;
|
package/build/base/board.js
CHANGED
|
@@ -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
|
-
/**
|
|
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
|
-
|
|
10
|
-
/** The height of the board. */
|
|
11
|
-
|
|
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.
|
|
27
|
-
this.
|
|
29
|
+
this.width = width;
|
|
30
|
+
this.height = height;
|
|
28
31
|
this.numberOfPlayerBoards = playerBoardCount;
|
|
29
32
|
this.numberOfBoards = this.numberOfPlayerBoards + extraBoardCount;
|
|
30
|
-
const totalBits = this.
|
|
31
|
-
this.bitBoard = (totalBits > 32
|
|
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
|
-
/**
|
|
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.
|
|
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.
|
|
43
|
-
2 ** (this.
|
|
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.
|
|
53
|
+
: 2 ** (this.width * this.height) - 1);
|
|
46
54
|
return isFull.equals(fullValue);
|
|
47
55
|
}
|
|
48
|
-
/**
|
|
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.
|
|
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
|
-
*
|
|
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
|
-
/**
|
|
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.
|
|
80
|
-
for (let x = 0; x < this.
|
|
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
|
-
/**
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
188
|
+
for (let x = 0; x < this.width; x++) {
|
|
173
189
|
const cell = { x, y };
|
|
174
|
-
const bar = x === this.
|
|
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.
|
|
213
|
+
if (length > Math.max(this.width, this.height))
|
|
198
214
|
return 0;
|
|
199
|
-
const DIRECTIONS = [
|
|
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.
|
|
214
|
-
for (let y = 0; y < this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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==
|