UNPKG

ngx-snake

Version:

Snake game as an angular component, its only the core of the game... you need to add everything around it (controls, score...) yourself :)

214 lines 28.4 kB
import { Injectable } from '@angular/core'; import { BehaviorSubject, interval, ReplaySubject, Subject } from 'rxjs'; import { MoveDirections, TileState } from '../definitions'; import { filter, switchMap, take, tap } from 'rxjs/operators'; import * as i0 from "@angular/core"; const INITIAL_SPEED = 700; export class GameManagerService { constructor() { this._grid = []; this._grid$ = new ReplaySubject(1); this.grid$ = this._grid$.asObservable(); this._gameOver$ = new Subject(); this.gameOver$ = this._gameOver$; this._foodEaten$ = new Subject(); this.foodEaten$ = this._foodEaten$; this._gridSize = { h: 10, w: 10 }; this._snake = []; this._nextMoveDir = MoveDirections.RIGHT; this._moveDir = MoveDirections.RIGHT; this._food = null; this._interval$ = new BehaviorSubject(INITIAL_SPEED); this._paused = true; this._playable = true; this.signal$ = this._interval$ .asObservable() .pipe(switchMap((period) => interval(period)), filter(() => !this._paused), tap(() => this._gameCycle())); } initialize(height, width) { this._gridSize.w = width; this._gridSize.h = height; this._buildEmptyGrid(); this._initSnake(); this._drawSnake(); this._gridChanged(); this._signalSub = this.signal$.subscribe(); } ngOnDestroy() { if (this._signalSub) { this._signalSub.unsubscribe(); } } start() { if (this._playable) { this._paused = false; } } changeSpeed(period) { this._interval$.next(period); } pause() { this._paused = true; } reset() { this.pause(); this._playable = true; this._moveDir = MoveDirections.RIGHT; this._nextMoveDir = this._moveDir; this._interval$.next(INITIAL_SPEED); this._buildEmptyGrid(); this._initSnake(); this._drawSnake(); this._gridChanged(); } up() { this._moveDir !== MoveDirections.DOWN ? this._nextMoveDir = MoveDirections.UP : this._moveDir; } right() { this._moveDir !== MoveDirections.LEFT ? this._nextMoveDir = MoveDirections.RIGHT : this._moveDir; } down() { this._moveDir !== MoveDirections.UP ? this._nextMoveDir = MoveDirections.DOWN : this._moveDir; } left() { this._moveDir !== MoveDirections.RIGHT ? this._nextMoveDir = MoveDirections.LEFT : this._moveDir; } _endGame() { this._playable = false; this.pause(); this._gameOver$.next(); } _buildEmptyGrid() { const newGrid = []; for (let y = 0; y <= this._gridSize.h; y++) { const row = []; for (let x = 0; x <= this._gridSize.w; x++) { row.push(TileState.Free); } newGrid.push(row); } this._grid = newGrid; } _gridChanged() { this._grid$.next(this._grid); } _initSnake() { this._snake = []; const xCenter = Math.floor(this._gridSize.w / 2); const yCenter = Math.floor(this._gridSize.h / 2); this._snake.push({ x: xCenter, y: yCenter }); this._snake.push({ x: xCenter - 1, y: yCenter }); this._snake.push({ x: xCenter - 2, y: yCenter }); } _spawnFood() { if (!this._food) { const eligibleFields = []; for (let y = 1; y <= this._gridSize.h - 1; y++) { for (let x = 1; x <= this._gridSize.w - 1; x++) { if (this._grid[y][x] === TileState.Free) { eligibleFields.push({ x, y }); } } } const shuffled = eligibleFields.sort((a, b) => 0.5 - Math.random()); this._food = shuffled[0]; } this._grid[this._food.y][this._food.x] = TileState.Food; } _drawSnake() { const head = this._snake[0]; const tail = this._snake[this._snake.length - 1]; this._grid[head.y][head.x] = TileState.Head; for (let i = 1; i < this._snake.length - 1; i++) { const part = this._snake[i]; this._grid[part.y][part.x] = TileState.Body; } this._grid[tail.y][tail.x] = TileState.Tail; } _gameCycle() { const head = this._snake[0]; let newHead; this._moveDir = this._nextMoveDir; if (this._moveDir === MoveDirections.UP) { newHead = { x: head.x, y: head.y - 1 }; } else if (this._moveDir === MoveDirections.RIGHT) { newHead = { x: head.x + 1, y: head.y }; } else if (this._moveDir === MoveDirections.DOWN) { newHead = { x: head.x, y: head.y + 1 }; } else { // Moving left newHead = { x: head.x - 1, y: head.y }; } if (this._willCrash(newHead)) { return this._endGame(); } // position new head this._snake.unshift(newHead); if (this._willGrow(newHead)) { this._increaseSpeed(); this._foodEaten$.next(); this._food = null; } else { // drop old tail this._snake.pop(); } this._buildEmptyGrid(); this._drawSnake(); this._spawnFood(); this._gridChanged(); } /** * Checks if field is not currently occupied (is free to take) * @param newHead * @private */ _willCrash(newHead) { // Gets out of the board if (newHead.x < 0 || newHead.y < 0 || newHead.x > this._gridSize.w || newHead.y > this._gridSize.h) { return true; } const CRASHABLE_FIELDS = [ TileState.Body, TileState.Wall ]; if (CRASHABLE_FIELDS.includes(this._grid[newHead.y][newHead.x])) { return true; } // If crashing with tail then check if tail will move... if (this._grid[newHead.y][newHead.x] === TileState.Tail && this._willGrow(newHead)) { return true; } return false; } _willGrow(newHead) { if (this._food && this._food.y === newHead.y && this._food.x === newHead.x) { return true; } return false; } _increaseSpeed() { this._interval$ .pipe(take(1)) .subscribe((current) => { if (current >= 600) { this._interval$.next(current - 100); } else if (current >= 500) { this._interval$.next(current - 30); } else if (current >= 400) { this._interval$.next(current - 20); } else { this._interval$.next(current - 10); } }); } } GameManagerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: GameManagerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); GameManagerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: GameManagerService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.1", ngImport: i0, type: GameManagerService, decorators: [{ type: Injectable }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FtZS1tYW5hZ2VyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc25ha2Uvc3JjL2xpYi9zZXJ2aWNlcy9nYW1lLW1hbmFnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsVUFBVSxFQUFZLE1BQU0sZUFBZSxDQUFDO0FBQ3BELE9BQU8sRUFBQyxlQUFlLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQWUsTUFBTSxNQUFNLENBQUM7QUFDckYsT0FBTyxFQUFXLGNBQWMsRUFBRSxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuRSxPQUFPLEVBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7O0FBTTVELE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQztBQUcxQixNQUFNLE9BQU8sa0JBQWtCO0lBRC9CO1FBRVksVUFBSyxHQUFhLEVBQUUsQ0FBQztRQUNyQixXQUFNLEdBQUcsSUFBSSxhQUFhLENBQVcsQ0FBQyxDQUFDLENBQUM7UUFDekMsVUFBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFbEMsZUFBVSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDNUIsY0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7UUFFM0IsZ0JBQVcsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQzdCLGVBQVUsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBRzdCLGNBQVMsR0FBRztZQUNoQixDQUFDLEVBQUUsRUFBRTtZQUNMLENBQUMsRUFBRSxFQUFFO1NBQ1IsQ0FBQTtRQUVPLFdBQU0sR0FBZ0IsRUFBRSxDQUFDO1FBQ3pCLGlCQUFZLEdBQW1CLGNBQWMsQ0FBQyxLQUFLLENBQUM7UUFDcEQsYUFBUSxHQUFtQixjQUFjLENBQUMsS0FB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RUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3BFLElBQUksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBRTVCO1FBRUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztJQUM1RCxDQUFDO0lBRU8sVUFBVTtRQUNkLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztRQUVqRCxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztRQUU1QyxLQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzVDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUM7U0FDL0M7UUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztJQUNoRCxDQUFDO0lBRU8sVUFBVTtRQUNkLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUIsSUFBSSxPQUFhLENBQUM7UUFDbEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBQ2xDLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxjQUFjLENBQUMsRUFBRSxFQUFFO1lBQ3JDLE9BQU8sR0FBRyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1NBRTFDO2FBQU0sSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLGNBQWMsQ0FBQyxLQUFLLEVBQUU7WUFDL0MsT0FBTyxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7U0FFMUM7YUFBTSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssY0FBYyxDQUFDLElBQUksRUFBRTtZQUM5QyxPQUFPLEdBQUcsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztTQUUxQzthQUFNO1lBQ0gsY0FBYztZQUNkLE9BQU8sR0FBRyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQzFDO1FBRUQsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQzFCLE9BQU8sSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQzFCO1FBRUQsb0JBQW9CO1FBQ3BCLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTdCLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUN6QixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztTQUVyQjthQUFNO1lBQ0gsZ0JBQWdCO1lBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUM7U0FDckI7UUFFRCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxVQUFVLENBQUMsT0FBYTtRQUM1Qix3QkFBd0I7UUFDeEIsSUFBSSxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUU7WUFDaEcsT0FBTyxJQUFJLENBQUM7U0FDZjtRQUVELE1BQU0sZ0JBQWdCLEdBQXFCO1lBQ3ZDLFNBQVMsQ0FBQyxJQUFJO1lBQ2QsU0FBUyxDQUFDLElBQUk7U0FDakIsQ0FBQztRQUNGLElBQUksZ0JBQWdCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQzdELE9BQU8sSUFBSSxDQUFDO1NBQ2Y7UUFFRCx3REFBd0Q7UUFDeEQsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssU0FBUyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ2hGLE9BQU8sSUFBSSxDQUFDO1NBQ2Y7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBRU8sU0FBUyxDQUFDLE9BQWE7UUFDM0IsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLE9BQU8sQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssT0FBTyxDQUFDLENBQUMsRUFBRTtZQUN4RSxPQUFPLElBQUksQ0FBQztTQUNmO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztJQUVPLGNBQWM7UUFDbEIsSUFBSSxDQUFDLFVBQVU7YUFDVixJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ2IsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDbkIsSUFBSSxPQUFPLElBQUksR0FBRyxFQUFFO2dCQUNoQixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDLENBQUM7YUFFdkM7aUJBQU0sSUFBSSxPQUFPLElBQUksR0FBRyxFQUFFO2dCQUN2QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLENBQUM7YUFFdEM7aUJBQU0sSUFBSSxPQUFPLElBQUksR0FBRyxFQUFFO2dCQUN2QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLENBQUM7YUFFdEM7aUJBQU07Z0JBQ0gsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxDQUFDO2FBQ3RDO1FBQ0wsQ0FBQyxDQUFDLENBQUE7SUFDVixDQUFDOzsrR0ExUFEsa0JBQWtCO21IQUFsQixrQkFBa0I7MkZBQWxCLGtCQUFrQjtrQkFEOUIsVUFBVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SW5qZWN0YWJsZSwgT25EZXN0cm95fSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QmVoYXZpb3JTdWJqZWN0LCBpbnRlcnZhbCwgUmVwbGF5U3ViamVjdCwgU3ViamVjdCwgU3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCB7R2FtZUdyaWQsIE1vdmVEaXJlY3Rpb25zLCBUaWxlU3RhdGV9IGZyb20gJy4uL2RlZmluaXRpb25zJztcbmltcG9ydCB7ZmlsdGVyLCBzd2l0Y2hNYXAsIHRha2UsIHRhcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbnRlcmZhY2UgUGFydCB7XG4gICAgeDogbnVtYmVyLCB5OiBudW1iZXJcbn1cblxuY29uc3QgSU5JVElBTF9TUEVFRCA9IDcwMDtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEdhbWVNYW5hZ2VyU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gICAgcHJpdmF0ZSBfZ3JpZDogR2FtZUdyaWQgPSBbXTtcbiAgICBwcml2YXRlIF9ncmlkJCA9IG5ldyBSZXBsYXlTdWJqZWN0PEdhbWVHcmlkPigxKTtcbiAgICBwdWJsaWMgZ3JpZCQgPSB0aGlzLl9ncmlkJC5hc09ic2VydmFibGUoKTtcblxuICAgIHByaXZhdGUgX2dhbWVPdmVyJCA9IG5ldyBTdWJqZWN0KCk7XG4gICAgcHVibGljIGdhbWVPdmVyJCA9IHRoaXMuX2dhbWVPdmVyJDtcblxuICAgIHByaXZhdGUgX2Zvb2RFYXRlbiQgPSBuZXcgU3ViamVjdCgpO1xuICAgIHB1YmxpYyBmb29kRWF0ZW4kID0gdGhpcy5fZm9vZEVhdGVuJDtcblxuXG4gICAgcHJpdmF0ZSBfZ3JpZFNpemUgPSB7XG4gICAgICAgIGg6IDEwLFxuICAgICAgICB3OiAxMFxuICAgIH1cblxuICAgIHByaXZhdGUgX3NuYWtlOiBBcnJheTxQYXJ0PiA9IFtdO1xuICAgIHByaXZhdGUgX25leHRNb3ZlRGlyOiBNb3ZlRGlyZWN0aW9ucyA9IE1vdmVEaXJlY3Rpb25zLlJJR0hUO1xuICAgIHByaXZhdGUgX21vdmVEaXI6IE1vdmVEaXJlY3Rpb25zID0gTW92ZURpcmVjdGlvbnMuUklHSFQ7XG5cbiAgICBwcml2YXRlIF9mb29kOiBQYXJ0IHwgbnVsbCA9IG51bGw7XG5cbiAgICBwcml2YXRlIF9pbnRlcnZhbCQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KElOSVRJQUxfU1BFRUQpO1xuICAgIHByaXZhdGUgX3BhdXNlZCA9IHRydWU7XG4gICAgcHJpdmF0ZSBfcGxheWFibGUgPSB0cnVlO1xuICAgIHByaXZhdGUgX3NpZ25hbFN1YjogU3Vic2NyaXB0aW9uO1xuICAgIHB1YmxpYyBzaWduYWwkID0gdGhpcy5faW50ZXJ2YWwkXG4gICAgICAgIC5hc09ic2VydmFibGUoKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgocGVyaW9kKSA9PiBpbnRlcnZhbChwZXJpb2QpKSxcbiAgICAgICAgICAgIGZpbHRlcigoKSA9PiAhdGhpcy5fcGF1c2VkKSxcbiAgICAgICAgICAgIHRhcCgoKSA9PiB0aGlzLl9nYW1lQ3ljbGUoKSksXG4gICAgICAgICk7XG5cbiAgICBpbml0aWFsaXplKGhlaWdodDogbnVtYmVyLCB3aWR0aDogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuX2dyaWRTaXplLncgPSB3aWR0aDtcbiAgICAgICAgdGhpcy5fZ3JpZFNpemUuaCA9IGhlaWdodDtcblxuICAgICAgICB0aGlzLl9idWlsZEVtcHR5R3JpZCgpO1xuICAgICAgICB0aGlzLl9pbml0U25ha2UoKTtcbiAgICAgICAgdGhpcy5fZHJhd1NuYWtlKCk7XG5cbiAgICAgICAgdGhpcy5fZ3JpZENoYW5nZWQoKTtcblxuICAgICAgICB0aGlzLl9zaWduYWxTdWIgPSB0aGlzLnNpZ25hbCQuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKSB7XG4gICAgICAgIGlmICh0aGlzLl9zaWduYWxTdWIpIHtcbiAgICAgICAgICAgIHRoaXMuX3NpZ25hbFN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXJ0KCkge1xuICAgICAgICBpZiAodGhpcy5fcGxheWFibGUpIHtcbiAgICAgICAgICAgIHRoaXMuX3BhdXNlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGNoYW5nZVNwZWVkKHBlcmlvZDogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2ludGVydmFsJC5uZXh0KHBlcmlvZCk7XG4gICAgfVxuXG4gICAgcHVibGljIHBhdXNlKCkge1xuICAgICAgICB0aGlzLl9wYXVzZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHB1YmxpYyByZXNldCgpIHtcbiAgICAgICAgdGhpcy5wYXVzZSgpO1xuICAgICAgICB0aGlzLl9wbGF5YWJsZSA9IHRydWU7XG4gICAgICAgIHRoaXMuX21vdmVEaXIgPSBNb3ZlRGlyZWN0aW9ucy5SSUdIVDtcbiAgICAgICAgdGhpcy5fbmV4dE1vdmVEaXIgPSB0aGlzLl9tb3ZlRGlyO1xuICAgICAgICB0aGlzLl9pbnRlcnZhbCQubmV4dChJTklUSUFMX1NQRUVEKTtcblxuICAgICAgICB0aGlzLl9idWlsZEVtcHR5R3JpZCgpO1xuICAgICAgICB0aGlzLl9pbml0U25ha2UoKTtcbiAgICAgICAgdGhpcy5fZHJhd1NuYWtlKCk7XG5cbiAgICAgICAgdGhpcy5fZ3JpZENoYW5nZWQoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdXAoKSB7ICAgICAgIHRoaXMuX21vdmVEaXIgIT09IE1vdmVEaXJlY3Rpb25zLkRPV04gICA/IHRoaXMuX25leHRNb3ZlRGlyID0gTW92ZURpcmVjdGlvbnMuVVAgOiB0aGlzLl9tb3ZlRGlyIH1cbiAgICBwdWJsaWMgcmlnaHQoKSB7ICAgIHRoaXMuX21vdmVEaXIgIT09IE1vdmVEaXJlY3Rpb25zLkxFRlQgICA/IHRoaXMuX25leHRNb3ZlRGlyID0gTW92ZURpcmVjdGlvbnMuUklHSFQgOiB0aGlzLl9tb3ZlRGlyIH1cbiAgICBwdWJsaWMgZG93bigpIHsgICAgIHRoaXMuX21vdmVEaXIgIT09IE1vdmVEaXJlY3Rpb25zLlVQICAgICA/IHRoaXMuX25leHRNb3ZlRGlyID0gTW92ZURpcmVjdGlvbnMuRE9XTiA6IHRoaXMuX21vdmVEaXIgfVxuICAgIHB1YmxpYyBsZWZ0KCkgeyAgICAgdGhpcy5fbW92ZURpciAhPT0gTW92ZURpcmVjdGlvbnMuUklHSFQgID8gdGhpcy5fbmV4dE1vdmVEaXIgPSBNb3ZlRGlyZWN0aW9ucy5MRUZUIDogdGhpcy5fbW92ZURpciB9XG5cbiAgICBwcml2YXRlIF9lbmRHYW1lKCkge1xuICAgICAgICB0aGlzLl9wbGF5YWJsZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLnBhdXNlKCk7XG5cbiAgICAgICAgdGhpcy5fZ2FtZU92ZXIkLm5leHQoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9idWlsZEVtcHR5R3JpZCgpIHtcbiAgICAgICAgY29uc3QgbmV3R3JpZCA9IFtdO1xuICAgICAgICBmb3IobGV0IHkgPSAwOyB5IDw9IHRoaXMuX2dyaWRTaXplLmg7IHkrKykge1xuICAgICAgICAgICAgY29uc3Qgcm93ID0gW107XG4gICAgICAgICAgICBmb3IobGV0IHggPSAwOyB4IDw9IHRoaXMuX2dyaWRTaXplLnc7IHgrKykge1xuICAgICAgICAgICAgICAgIHJvdy5wdXNoKFRpbGVTdGF0ZS5GcmVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmV3R3JpZC5wdXNoKHJvdyk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9ncmlkID0gIG5ld0dyaWQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ3JpZENoYW5nZWQoKSB7XG4gICAgICAgIHRoaXMuX2dyaWQkLm5leHQodGhpcy5fZ3JpZClcbiAgICB9XG5cbiAgICBwcml2YXRlIF9pbml0U25ha2UoKSB7XG4gICAgICAgIHRoaXMuX3NuYWtlID0gW107XG5cbiAgICAgICAgY29uc3QgeENlbnRlciA9IE1hdGguZmxvb3IodGhpcy5fZ3JpZFNpemUudyAvIDIpO1xuICAgICAgICBjb25zdCB5Q2VudGVyID0gTWF0aC5mbG9vcih0aGlzLl9ncmlkU2l6ZS5oIC8gMik7XG5cbiAgICAgICAgdGhpcy5fc25ha2UucHVzaCh7IHg6IHhDZW50ZXIsIHk6IHlDZW50ZXIgfSk7XG4gICAgICAgIHRoaXMuX3NuYWtlLnB1c2goeyB4OiB4Q2VudGVyIC0gMSwgeTogeUNlbnRlciB9KTtcbiAgICAgICAgdGhpcy5fc25ha2UucHVzaCh7IHg6IHhDZW50ZXIgLSAyLCB5OiB5Q2VudGVyIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgX3NwYXduRm9vZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9mb29kKSB7XG4gICAgICAgICAgICBjb25zdCBlbGlnaWJsZUZpZWxkcyA9IFtdO1xuICAgICAgICAgICAgZm9yKGxldCB5ID0gMTsgeSA8PSB0aGlzLl9ncmlkU2l6ZS5oIC0gMTsgeSsrKSB7XG4gICAgICAgICAgICAgICAgZm9yKGxldCB4ID0gMTsgeCA8PSB0aGlzLl9ncmlkU2l6ZS53IC0gMSA7IHgrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5fZ3JpZFt5XVt4XSA9PT0gVGlsZVN0YXRlLkZyZWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsaWdpYmxlRmllbGRzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHgsIHlcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHNodWZmbGVkID0gZWxpZ2libGVGaWVsZHMuc29ydCgoYSwgYikgPT4gMC41IC0gTWF0aC5yYW5kb20oKSk7XG4gICAgICAgICAgICB0aGlzLl9mb29kID0gc2h1ZmZsZWRbMF07XG5cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2dyaWRbdGhpcy5fZm9vZC55XVt0aGlzLl9mb29kLnhdID0gVGlsZVN0YXRlLkZvb2Q7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZHJhd1NuYWtlKCkge1xuICAgICAgICBjb25zdCBoZWFkID0gdGhpcy5fc25ha2VbMF07XG4gICAgICAgIGNvbnN0IHRhaWwgPSB0aGlzLl9zbmFrZVt0aGlzLl9zbmFrZS5sZW5ndGggLSAxXTtcblxuICAgICAgICB0aGlzLl9ncmlkW2hlYWQueV1baGVhZC54XSA9IFRpbGVTdGF0ZS5IZWFkO1xuXG4gICAgICAgIGZvcihsZXQgaSA9IDE7IGkgPCB0aGlzLl9zbmFrZS5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnQgPSB0aGlzLl9zbmFrZVtpXTtcbiAgICAgICAgICAgIHRoaXMuX2dyaWRbcGFydC55XVtwYXJ0LnhdID0gVGlsZVN0YXRlLkJvZHk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9ncmlkW3RhaWwueV1bdGFpbC54XSA9IFRpbGVTdGF0ZS5UYWlsO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dhbWVDeWNsZSgpIHtcbiAgICAgICAgY29uc3QgaGVhZCA9IHRoaXMuX3NuYWtlWzBdO1xuICAgICAgICBsZXQgbmV3SGVhZDogUGFydDtcbiAgICAgICAgdGhpcy5fbW92ZURpciA9IHRoaXMuX25leHRNb3ZlRGlyO1xuICAgICAgICBpZiAodGhpcy5fbW92ZURpciA9PT0gTW92ZURpcmVjdGlvbnMuVVApIHtcbiAgICAgICAgICAgIG5ld0hlYWQgPSB7IHg6IGhlYWQueCwgeTogaGVhZC55IC0gMSB9O1xuXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fbW92ZURpciA9PT0gTW92ZURpcmVjdGlvbnMuUklHSFQpIHtcbiAgICAgICAgICAgIG5ld0hlYWQgPSB7IHg6IGhlYWQueCArIDEsIHk6IGhlYWQueSB9O1xuXG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5fbW92ZURpciA9PT0gTW92ZURpcmVjdGlvbnMuRE9XTikge1xuICAgICAgICAgICAgbmV3SGVhZCA9IHsgeDogaGVhZC54LCB5OiBoZWFkLnkgKyAxIH07XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIE1vdmluZyBsZWZ0XG4gICAgICAgICAgICBuZXdIZWFkID0geyB4OiBoZWFkLnggLSAxLCB5OiBoZWFkLnkgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl93aWxsQ3Jhc2gobmV3SGVhZCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9lbmRHYW1lKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBwb3NpdGlvbiBuZXcgaGVhZFxuICAgICAgICB0aGlzLl9zbmFrZS51bnNoaWZ0KG5ld0hlYWQpO1xuXG4gICAgICAgIGlmICh0aGlzLl93aWxsR3JvdyhuZXdIZWFkKSkge1xuICAgICAgICAgICAgdGhpcy5faW5jcmVhc2VTcGVlZCgpO1xuICAgICAgICAgICAgdGhpcy5fZm9vZEVhdGVuJC5uZXh0KCk7XG4gICAgICAgICAgICB0aGlzLl9mb29kID0gbnVsbDtcblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gZHJvcCBvbGQgdGFpbFxuICAgICAgICAgICAgdGhpcy5fc25ha2UucG9wKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9idWlsZEVtcHR5R3JpZCgpO1xuICAgICAgICB0aGlzLl9kcmF3U25ha2UoKTtcbiAgICAgICAgdGhpcy5fc3Bhd25Gb29kKCk7XG4gICAgICAgIHRoaXMuX2dyaWRDaGFuZ2VkKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIGlmIGZpZWxkIGlzIG5vdCBjdXJyZW50bHkgb2NjdXBpZWQgKGlzIGZyZWUgdG8gdGFrZSlcbiAgICAgKiBAcGFyYW0gbmV3SGVhZFxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBfd2lsbENyYXNoKG5ld0hlYWQ6IFBhcnQpOiBib29sZWFuIHtcbiAgICAgICAgLy8gR2V0cyBvdXQgb2YgdGhlIGJvYXJkXG4gICAgICAgIGlmIChuZXdIZWFkLnggPCAwIHx8IG5ld0hlYWQueSA8IDAgfHwgbmV3SGVhZC54ID4gdGhpcy5fZ3JpZFNpemUudyB8fCBuZXdIZWFkLnkgPiB0aGlzLl9ncmlkU2l6ZS5oKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IENSQVNIQUJMRV9GSUVMRFM6IEFycmF5PFRpbGVTdGF0ZT4gPSBbXG4gICAgICAgICAgICBUaWxlU3RhdGUuQm9keSxcbiAgICAgICAgICAgIFRpbGVTdGF0ZS5XYWxsXG4gICAgICAgIF07XG4gICAgICAgIGlmIChDUkFTSEFCTEVfRklFTERTLmluY2x1ZGVzKHRoaXMuX2dyaWRbbmV3SGVhZC55XVtuZXdIZWFkLnhdKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiBjcmFzaGluZyB3aXRoIHRhaWwgdGhlbiBjaGVjayBpZiB0YWlsIHdpbGwgbW92ZS4uLlxuICAgICAgICBpZiAodGhpcy5fZ3JpZFtuZXdIZWFkLnldW25ld0hlYWQueF0gPT09IFRpbGVTdGF0ZS5UYWlsICYmIHRoaXMuX3dpbGxHcm93KG5ld0hlYWQpKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF93aWxsR3JvdyhuZXdIZWFkOiBQYXJ0KTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLl9mb29kICYmIHRoaXMuX2Zvb2QueSA9PT0gbmV3SGVhZC55ICYmIHRoaXMuX2Zvb2QueCA9PT0gbmV3SGVhZC54KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfaW5jcmVhc2VTcGVlZCgpIHtcbiAgICAgICAgdGhpcy5faW50ZXJ2YWwkXG4gICAgICAgICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoY3VycmVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50ID49IDYwMCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9pbnRlcnZhbCQubmV4dChjdXJyZW50IC0gMTAwKTtcblxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudCA+PSA1MDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faW50ZXJ2YWwkLm5leHQoY3VycmVudCAtIDMwKTtcblxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudCA+PSA0MDApIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faW50ZXJ2YWwkLm5leHQoY3VycmVudCAtIDIwKTtcblxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2ludGVydmFsJC5uZXh0KGN1cnJlbnQgLSAxMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICB9XG59XG4iXX0=