UNPKG

bp-prism-game

Version:
257 lines 33.3 kB
import { AlienBaseClass } from '../base/alien-base/alien-base.class'; import { Alien1Class } from '../aliens/alien-1/alien-1.class'; import { ObservableTypeEnum } from '../enum/observable-type.enum'; import { AssetClass } from '../asset/asset.class'; import { Alien2Class } from '../aliens/alien-2/alien-2.class'; import { PathService } from './path.service'; import { AlienDropshipClass } from '../aliens/alien-dropship/alien-dropship.class'; /** * The invasion service */ export class InvasionService extends AssetClass { /** * The constructor */ constructor(gameService, ctx) { super(gameService, ctx, 0); this.bases = []; this.baseAliens = []; this.alienDropships = []; this.waveTotal = 0; this.dropshipCounter = 0; this.pathService = new PathService(); this.setup(); } /** * Initialize the board */ setup() { this.basePositions = this.gameService.getAlienBasePositions(); this.basePositions.map((position) => { const alienBase = new AlienBaseClass(this.gameService, this.ctx, 1); alienBase.move(position); this.bases.push(alienBase); }); this.gameService.getMasterObservable().subscribe((event) => { if (event.type === ObservableTypeEnum.alienDestroyed) { this.isLevelCompleted(); } }); } /** * Build the creep */ buildCreep() { let alienUid = 0; let baseAlienPosition = 0; this.baseAliens.map((alienWave) => { alienWave.aliens.map((alien) => { alienUid++; alien.isAnimated = false; alien.isDestroyed = false; }); }); this.alienDropships.map((alienDropship) => { alienDropship.isDestroyed = false; alienDropship.isAnimated = false; }); for (let wave = 0; wave < this.waves; wave++) { this.basePositions.map((position) => { if (!this.alienDropships[baseAlienPosition]) { this.alienDropships.push(new AlienDropshipClass(this.gameService, this.ctx, this.alienDropships.length)); } if (!this.baseAliens[baseAlienPosition]) { this.baseAliens.push({ startingPoint: position, aliens: [] }); } for (let index = this.baseAliens[baseAlienPosition].aliens.length; index < this.aliensPerWave; index++) { let alien; if (baseAlienPosition % 2 === 0) { alien = new Alien1Class(this.gameService, this.ctx, alienUid++); } else { alien = new Alien2Class(this.gameService, this.ctx, alienUid++); } alien.isAnimated = false; alien.isDestroyed = false; this.baseAliens[baseAlienPosition].aliens.push(alien); } baseAlienPosition++; }); } } /** * Shuffle the waves */ shuffle() { let currentIndex = this.basePositions.length; let temporaryValue; let randomIndex; // While there remain elements to shuffle... while (0 !== currentIndex) { // Pick a remaining element... randomIndex = Math.floor(Math.random() * currentIndex); currentIndex -= 1; // And swap it with the current element. temporaryValue = this.basePositions[currentIndex]; this.basePositions[currentIndex] = this.basePositions[randomIndex]; this.basePositions[randomIndex] = temporaryValue; } } /** * Configure the Alien drop ship * @param index the index of the dropship * @param position the position of the base */ configureAlienDropship(index, position) { this.alienDropships[index].setAlienDropshipToDeploy(); this.alienDropships[index].move(position); this.alienDropships[index].setCreepPath(this.pathService.getAlienDropShipPath({ x: 0, y: position.y }, position)); } /** * position the aliens at the starting point */ positionAliens() { this.shuffle(); let basePosition = 0; for (let wave = 0; wave < this.waves; wave++) { this.basePositions.map((position) => { this.configureAlienDropship(basePosition, position); this.baseAliens[basePosition].aliens.map((alien) => { alien.setCreepSpeed(this.alienSpeed); alien.setCreepPath(this.pathService.findShortestPath(this.gameService.convertIAssetToGameboardIAsset(position), this.gameService.getGameBoard())); }); basePosition++; }); } } /** * Determine if the level is completed */ isLevelCompleted() { this.totalAliens--; if (this.totalAliens === 0) { this.gameService.emitMasterObservableEvent({ type: ObservableTypeEnum.levelCompleted, booleanData: true }); } } /** * Animate the bases */ animateBases() { this.basePositions = this.gameService.getAlienBasePositions(); let basePositionCounter = 0; if (this.bases.length > 0) { this.basePositions.map((position) => { this.bases[basePositionCounter].move(position); basePositionCounter++; }); } } /** * Start the animations * * @param invasionSetup Set up the invasion */ initInvasion(invasionSetup) { this.aliensPerWave = invasionSetup.alienPerWave ? invasionSetup.alienPerWave : 10; this.waves = invasionSetup.waves ? invasionSetup.waves : 2; this.alienSpeed = invasionSetup.alienSpeed ? invasionSetup.alienSpeed : 500; this.waveTotal = this.basePositions.length * this.waves; this.dropshipCounter = 0; this.totalAliens = this.aliensPerWave * this.waveTotal; this.animateBases(); this.buildCreep(); this.positionAliens(); this.waveCounter = 0; this.alienReleaseCounter = 0; this.launchNextAlienDropship(); } /** * Start Alien Creep */ startAlienCreep(baseIndex, alienIndex) { if (this.baseAliens.length > 0) { this.baseAliens[baseIndex].aliens[alienIndex].isAnimated = true; } } /** * Get All Active Aliens */ getActiveAliens() { let activeAliens = []; this.baseAliens.map((alienWave) => { activeAliens = activeAliens.concat(alienWave.aliens.filter((alien) => alien.isDestroyed === false)); }); return activeAliens; } /** * Animate * @param now the current time */ animate(now = 0) { this.bases.map((base) => { base.animate(); }); if (this.stopAnimation()) { return; } this.baseAliens.map((alienWave) => { alienWave.aliens .filter((alien) => alien.isAnimated && alien.isDestroyed === false) .map((alien) => { alien.animate(now); }); }); } /** * Launch the next drop ship * @param index The index of the drop ship */ launchNextAlienDropship() { if (this.alienDropships[this.dropshipCounter]) { this.alienDropships[this.dropshipCounter].isAnimated = true; } } /** * Animate * * @param now The current animation time */ animateDropships(now = 0) { this.assetTimer.elapsed = now - this.assetTimer.start; if (this.stopAnimation()) { return; } this.alienDropships .filter((alienDropship) => alienDropship.isAnimated && alienDropship.isDestroyed === false) .map((alienDropship) => { alienDropship.animate(now); }); if (this.dropshipCounter === this.alienDropships.length) { return; } if (this.alienDropships[this.dropshipCounter].canLandAliens()) { if (this.assetTimer.elapsed > this.alienSpeed) { this.assetTimer.start = now; if (this.alienReleaseCounter === this.aliensPerWave) { this.alienDropships[this.dropshipCounter++].setAliensLanded(); this.launchNextAlienDropship(); this.waveCounter++; this.alienReleaseCounter = 0; } else { this.startAlienCreep(this.waveCounter, this.alienReleaseCounter++); } } } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52YXNpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3ByaXNtL3NyYy9saWIvc2VydmljZS9pbnZhc2lvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNyRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFOUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBSWxELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM5RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFFbkY7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZUFBZ0IsU0FBUSxVQUFVO0lBa0U3Qzs7T0FFRztJQUNILFlBQVksV0FBd0IsRUFBRSxHQUE2QjtRQUNqRSxLQUFLLENBQUMsV0FBVyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztRQUNuQixJQUFJLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7UUFFckMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ0ssS0FBSztRQUNYLElBQUksQ0FB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RyxDQUFDLENBQUMsYUFBaUMsRUFBRSxFQUFFO1lBQ3pDLGFBQWEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUU7WUFDdkQsT0FBTztTQUNSO1FBRUQsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxhQUFhLEVBQUUsRUFBRTtZQUM3RCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQzdDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQztnQkFDNUIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEtBQUssSUFBSSxDQUFDLGFBQWEsRUFBRTtvQkFDbkQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDOUQsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7b0JBQy9CLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztvQkFDbkIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLENBQUMsQ0FBQztpQkFDOUI7cUJBQU07b0JBQ0wsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUM7aUJBQ3BFO2FBQ0Y7U0FDRjtJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElBc3NldCB9IGZyb20gJy4uL2ludGVyZmFjZS9hc3NldC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgR2FtZVNlcnZpY2UgfSBmcm9tICcuL2dhbWUuc2VydmljZSc7XG5pbXBvcnQgeyBBbGllbkNsYXNzIH0gZnJvbSAnLi4vYWxpZW5zL2FsaWVuL2FsaWVuLmNsYXNzJztcbmltcG9ydCB7IEFsaWVuQmFzZUNsYXNzIH0gZnJvbSAnLi4vYmFzZS9hbGllbi1iYXNlL2FsaWVuLWJhc2UuY2xhc3MnO1xuaW1wb3J0IHsgQWxpZW4xQ2xhc3MgfSBmcm9tICcuLi9hbGllbnMvYWxpZW4tMS9hbGllbi0xLmNsYXNzJztcbmltcG9ydCB7IE9ic2VydmFibGVNb2RlbCB9IGZyb20gJy4uL21vZGVsL29ic2VydmFibGUubW9kZWwnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZVR5cGVFbnVtIH0gZnJvbSAnLi4vZW51bS9vYnNlcnZhYmxlLXR5cGUuZW51bSc7XG5pbXBvcnQgeyBBc3NldENsYXNzIH0gZnJvbSAnLi4vYXNzZXQvYXNzZXQuY2xhc3MnO1xuaW1wb3J0IHsgQWxpZW5XYXZlTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9hbGllbi9hbGllbi13YXZlLm1vZGVsJztcbmltcG9ydCB7IEludmFzaW9uU2V0dXBNb2RlbCB9IGZyb20gJy4uL21vZGVsL2ludmFzaW9uLXNldHVwLm1vZGVsJztcbmltcG9ydCB7IEJhc2VDbGFzcyB9IGZyb20gJy4uL2Jhc2UvYmFzZS5jbGFzcyc7XG5pbXBvcnQgeyBBbGllbjJDbGFzcyB9IGZyb20gJy4uL2FsaWVucy9hbGllbi0yL2FsaWVuLTIuY2xhc3MnO1xuaW1wb3J0IHsgUGF0aFNlcnZpY2UgfSBmcm9tICcuL3BhdGguc2VydmljZSc7XG5pbXBvcnQgeyBBbGllbkRyb3BzaGlwQ2xhc3MgfSBmcm9tICcuLi9hbGllbnMvYWxpZW4tZHJvcHNoaXAvYWxpZW4tZHJvcHNoaXAuY2xhc3MnO1xuXG4vKipcbiAqIFRoZSBpbnZhc2lvbiBzZXJ2aWNlXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnZhc2lvblNlcnZpY2UgZXh0ZW5kcyBBc3NldENsYXNzIHtcbiAgLyoqXG4gICAqIFRoZSBhbGllbiBiYXNlc1xuICAgKi9cbiAgcHJpdmF0ZSBiYXNlczogQWxpZW5CYXNlQ2xhc3NbXTtcblxuICAvKipcbiAgICogQWxpZW5zIGF0IGVhY2ggYmFzZVxuICAgKi9cbiAgcHJpdmF0ZSBiYXNlQWxpZW5zOiBBbGllbldhdmVNb2RlbFtdO1xuXG4gIC8qKlxuICAgKiBBbGllbnMgZHJvcCBzaGlwc1xuICAgKi9cbiAgcHJpdmF0ZSBhbGllbkRyb3BzaGlwczogQWxpZW5Ecm9wc2hpcENsYXNzW107XG5cbiAgLyoqXG4gICAqIFRoZSBhbGllbiBSZWxlYXNlIENvdW50ZXJcbiAgICovXG4gIHByaXZhdGUgYWxpZW5SZWxlYXNlQ291bnRlcjogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgd2F2ZSBjb3VudGVyXG4gICAqL1xuICBwcml2YXRlIHdhdmVDb3VudGVyOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSB0b3RhbCB3YXZlc1xuICAgKi9cbiAgcHJpdmF0ZSB3YXZlVG90YWw6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGFsaWVucyBQZXIgV2F2ZVxuICAgKi9cbiAgcHJpdmF0ZSBhbGllbnNQZXJXYXZlOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkcm9wc2hpcCBjb3VudGVyXG4gICAqL1xuICBwcml2YXRlIGRyb3BzaGlwQ291bnRlcjogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgV2F2ZVxuICAgKi9cbiAgcHJpdmF0ZSB3YXZlczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgQWxpZW4gU3BlZWRcbiAgICovXG4gIHByaXZhdGUgYWxpZW5TcGVlZDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgVG90YWwgQWxpZW5zXG4gICAqL1xuICBwcml2YXRlIHRvdGFsQWxpZW5zOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBCYXNlIFBvc2l0aW9uc1xuICAgKi9cbiAgcHJpdmF0ZSBiYXNlUG9zaXRpb25zOiBJQXNzZXRbXTtcblxuICAvKipcbiAgICogVGhlIHBhdGggc2VydmljZVxuICAgKi9cbiAgcHJpdmF0ZSBwYXRoU2VydmljZTogUGF0aFNlcnZpY2U7XG5cbiAgLyoqXG4gICAqIFRoZSBjb25zdHJ1Y3RvclxuICAgKi9cbiAgY29uc3RydWN0b3IoZ2FtZVNlcnZpY2U6IEdhbWVTZXJ2aWNlLCBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCkge1xuICAgIHN1cGVyKGdhbWVTZXJ2aWNlLCBjdHgsIDApO1xuICAgIHRoaXMuYmFzZXMgPSBbXTtcbiAgICB0aGlzLmJhc2VBbGllbnMgPSBbXTtcbiAgICB0aGlzLmFsaWVuRHJvcHNoaXBzID0gW107XG4gICAgdGhpcy53YXZlVG90YWwgPSAwO1xuICAgIHRoaXMuZHJvcHNoaXBDb3VudGVyID0gMDtcbiAgICB0aGlzLnBhdGhTZXJ2aWNlID0gbmV3IFBhdGhTZXJ2aWNlKCk7XG5cbiAgICB0aGlzLnNldHVwKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgYm9hcmRcbiAgICovXG4gIHByaXZhdGUgc2V0dXAoKTogdm9pZCB7XG4gICAgdGhpcy5iYXNlUG9zaXRpb25zID0gdGhpcy5nYW1lU2VydmljZS5nZXRBbGllbkJhc2VQb3NpdGlvbnMoKTtcblxuICAgIHRoaXMuYmFzZVBvc2l0aW9ucy5tYXAoKHBvc2l0aW9uOiBJQXNzZXQpID0+IHtcbiAgICAgIGNvbnN0IGFsaWVuQmFzZSA9IG5ldyBBbGllbkJhc2VDbGFzcyh0aGlzLmdhbWVTZXJ2aWNlLCB0aGlzLmN0eCwgMSk7XG4gICAgICBhbGllbkJhc2UubW92ZShwb3NpdGlvbik7XG4gICAgICB0aGlzLmJhc2VzLnB1c2goYWxpZW5CYXNlKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZ2FtZVNlcnZpY2UuZ2V0TWFzdGVyT2JzZXJ2YWJsZSgpLnN1YnNjcmliZSgoZXZlbnQ6IE9ic2VydmFibGVNb2RlbCkgPT4ge1xuICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IE9ic2VydmFibGVUeXBlRW51bS5hbGllbkRlc3Ryb3llZCkge1xuICAgICAgICB0aGlzLmlzTGV2ZWxDb21wbGV0ZWQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgY3JlZXBcbiAgICovXG4gIHByaXZhdGUgYnVpbGRDcmVlcCgpOiB2b2lkIHtcbiAgICBsZXQgYWxpZW5VaWQgPSAwO1xuICAgIGxldCBiYXNlQWxpZW5Qb3NpdGlvbiA9IDA7XG5cbiAgICB0aGlzLmJhc2VBbGllbnMubWFwKChhbGllbldhdmU6IEFsaWVuV2F2ZU1vZGVsKSA9PiB7XG4gICAgICBhbGllbldhdmUuYWxpZW5zLm1hcCgoYWxpZW46IEFsaWVuQ2xhc3MpID0+IHtcbiAgICAgICAgYWxpZW5VaWQrKztcbiAgICAgICAgYWxpZW4uaXNBbmltYXRlZCA9IGZhbHNlO1xuICAgICAgICBhbGllbi5pc0Rlc3Ryb3llZCA9IGZhbHNlO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsaWVuRHJvcHNoaXBzLm1hcCgoYWxpZW5Ecm9wc2hpcDogQWxpZW5Ecm9wc2hpcENsYXNzKSA9PiB7XG4gICAgICBhbGllbkRyb3BzaGlwLmlzRGVzdHJveWVkID0gZmFsc2U7XG4gICAgICBhbGllbkRyb3BzaGlwLmlzQW5pbWF0ZWQgPSBmYWxzZTtcbiAgICB9KTtcblxuICAgIGZvciAobGV0IHdhdmUgPSAwOyB3YXZlIDwgdGhpcy53YXZlczsgd2F2ZSsrKSB7XG4gICAgICB0aGlzLmJhc2VQb3NpdGlvbnMubWFwKChwb3NpdGlvbjogSUFzc2V0KSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5hbGllbkRyb3BzaGlwc1tiYXNlQWxpZW5Qb3NpdGlvbl0pIHtcbiAgICAgICAgICB0aGlzLmFsaWVuRHJvcHNoaXBzLnB1c2gobmV3IEFsaWVuRHJvcHNoaXBDbGFzcyh0aGlzLmdhbWVTZXJ2aWNlLCB0aGlzLmN0eCwgdGhpcy5hbGllbkRyb3BzaGlwcy5sZW5ndGgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5iYXNlQWxpZW5zW2Jhc2VBbGllblBvc2l0aW9uXSkge1xuICAgICAgICAgIHRoaXMuYmFzZUFsaWVucy5wdXNoKHtcbiAgICAgICAgICAgIHN0YXJ0aW5nUG9pbnQ6IHBvc2l0aW9uLFxuICAgICAgICAgICAgYWxpZW5zOiBbXVxuICAgICAgICAgIH0gYXMgQWxpZW5XYXZlTW9kZWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSB0aGlzLmJhc2VBbGllbnNbYmFzZUFsaWVuUG9zaXRpb25dLmFsaWVucy5sZW5ndGg7IGluZGV4IDwgdGhpcy5hbGllbnNQZXJXYXZlOyBpbmRleCsrKSB7XG4gICAgICAgICAgbGV0IGFsaWVuOiBBbGllbkNsYXNzO1xuICAgICAgICAgIGlmIChiYXNlQWxpZW5Qb3NpdGlvbiAlIDIgPT09IDApIHtcbiAgICAgICAgICAgIGFsaWVuID0gbmV3IEFsaWVuMUNsYXNzKHRoaXMuZ2FtZVNlcnZpY2UsIHRoaXMuY3R4LCBhbGllblVpZCsrKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWxpZW4gPSBuZXcgQWxpZW4yQ2xhc3ModGhpcy5nYW1lU2VydmljZSwgdGhpcy5jdHgsIGFsaWVuVWlkKyspO1xuICAgICAgICAgIH1cbiAgICAgICAgICBhbGllbi5pc0FuaW1hdGVkID0gZmFsc2U7XG4gICAgICAgICAgYWxpZW4uaXNEZXN0cm95ZWQgPSBmYWxzZTtcblxuICAgICAgICAgIHRoaXMuYmFzZUFsaWVuc1tiYXNlQWxpZW5Qb3NpdGlvbl0uYWxpZW5zLnB1c2goYWxpZW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgYmFzZUFsaWVuUG9zaXRpb24rKztcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTaHVmZmxlIHRoZSB3YXZlc1xuICAgKi9cbiAgcHJpdmF0ZSBzaHVmZmxlKCk6IHZvaWQge1xuICAgIGxldCBjdXJyZW50SW5kZXggPSB0aGlzLmJhc2VQb3NpdGlvbnMubGVuZ3RoO1xuICAgIGxldCB0ZW1wb3JhcnlWYWx1ZTogSUFzc2V0O1xuICAgIGxldCByYW5kb21JbmRleDogbnVtYmVyO1xuXG4gICAgLy8gV2hpbGUgdGhlcmUgcmVtYWluIGVsZW1lbnRzIHRvIHNodWZmbGUuLi5cbiAgICB3aGlsZSAoMCAhPT0gY3VycmVudEluZGV4KSB7XG4gICAgICAvLyBQaWNrIGEgcmVtYWluaW5nIGVsZW1lbnQuLi5cbiAgICAgIHJhbmRvbUluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY3VycmVudEluZGV4KTtcbiAgICAgIGN1cnJlbnRJbmRleCAtPSAxO1xuXG4gICAgICAvLyBBbmQgc3dhcCBpdCB3aXRoIHRoZSBjdXJyZW50IGVsZW1lbnQuXG4gICAgICB0ZW1wb3JhcnlWYWx1ZSA9IHRoaXMuYmFzZVBvc2l0aW9uc1tjdXJyZW50SW5kZXhdO1xuICAgICAgdGhpcy5iYXNlUG9zaXRpb25zW2N1cnJlbnRJbmRleF0gPSB0aGlzLmJhc2VQb3NpdGlvbnNbcmFuZG9tSW5kZXhdO1xuICAgICAgdGhpcy5iYXNlUG9zaXRpb25zW3JhbmRvbUluZGV4XSA9IHRlbXBvcmFyeVZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmUgdGhlIEFsaWVuIGRyb3Agc2hpcFxuICAgKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBkcm9wc2hpcFxuICAgKiBAcGFyYW0gcG9zaXRpb24gdGhlIHBvc2l0aW9uIG9mIHRoZSBiYXNlXG4gICAqL1xuICBwcml2YXRlIGNvbmZpZ3VyZUFsaWVuRHJvcHNoaXAoaW5kZXg6IG51bWJlciwgcG9zaXRpb246IElBc3NldCk6IHZvaWQge1xuICAgIHRoaXMuYWxpZW5Ecm9wc2hpcHNbaW5kZXhdLnNldEFsaWVuRHJvcHNoaXBUb0RlcGxveSgpO1xuICAgIHRoaXMuYWxpZW5Ecm9wc2hpcHNbaW5kZXhdLm1vdmUocG9zaXRpb24pO1xuICAgIHRoaXMuYWxpZW5Ecm9wc2hpcHNbaW5kZXhdLnNldENyZWVwUGF0aChcbiAgICAgIHRoaXMucGF0aFNlcnZpY2UuZ2V0QWxpZW5Ecm9wU2hpcFBhdGgoXG4gICAgICAgIHtcbiAgICAgICAgICB4OiAwLFxuICAgICAgICAgIHk6IHBvc2l0aW9uLnlcbiAgICAgICAgfSBhcyBJQXNzZXQsXG4gICAgICAgIHBvc2l0aW9uXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBwb3NpdGlvbiB0aGUgYWxpZW5zIGF0IHRoZSBzdGFydGluZyBwb2ludFxuICAgKi9cbiAgcHJpdmF0ZSBwb3NpdGlvbkFsaWVucygpOiB2b2lkIHtcbiAgICB0aGlzLnNodWZmbGUoKTtcbiAgICBsZXQgYmFzZVBvc2l0aW9uID0gMDtcblxuICAgIGZvciAobGV0IHdhdmUgPSAwOyB3YXZlIDwgdGhpcy53YXZlczsgd2F2ZSsrKSB7XG4gICAgICB0aGlzLmJhc2VQb3NpdGlvbnMubWFwKChwb3NpdGlvbjogSUFzc2V0KSA9PiB7XG4gICAgICAgIHRoaXMuY29uZmlndXJlQWxpZW5Ecm9wc2hpcChiYXNlUG9zaXRpb24sIHBvc2l0aW9uKTtcblxuICAgICAgICB0aGlzLmJhc2VBbGllbnNbYmFzZVBvc2l0aW9uXS5hbGllbnMubWFwKChhbGllbjogQWxpZW5DbGFzcykgPT4ge1xuICAgICAgICAgIGFsaWVuLnNldENyZWVwU3BlZWQodGhpcy5hbGllblNwZWVkKTtcbiAgICAgICAgICBhbGllbi5zZXRDcmVlcFBhdGgoXG4gICAgICAgICAgICB0aGlzLnBhdGhTZXJ2aWNlLmZpbmRTaG9ydGVzdFBhdGgoXG4gICAgICAgICAgICAgIHRoaXMuZ2FtZVNlcnZpY2UuY29udmVydElBc3NldFRvR2FtZWJvYXJkSUFzc2V0KHBvc2l0aW9uKSxcbiAgICAgICAgICAgICAgdGhpcy5nYW1lU2VydmljZS5nZXRHYW1lQm9hcmQoKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGJhc2VQb3NpdGlvbisrO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSBpZiB0aGUgbGV2ZWwgaXMgY29tcGxldGVkXG4gICAqL1xuICBwcml2YXRlIGlzTGV2ZWxDb21wbGV0ZWQoKTogdm9pZCB7XG4gICAgdGhpcy50b3RhbEFsaWVucy0tO1xuXG4gICAgaWYgKHRoaXMudG90YWxBbGllbnMgPT09IDApIHtcbiAgICAgIHRoaXMuZ2FtZVNlcnZpY2UuZW1pdE1hc3Rlck9ic2VydmFibGVFdmVudCh7XG4gICAgICAgIHR5cGU6IE9ic2VydmFibGVUeXBlRW51bS5sZXZlbENvbXBsZXRlZCxcbiAgICAgICAgYm9vbGVhbkRhdGE6IHRydWVcbiAgICAgIH0gYXMgT2JzZXJ2YWJsZU1vZGVsKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQW5pbWF0ZSB0aGUgYmFzZXNcbiAgICovXG4gIHByaXZhdGUgYW5pbWF0ZUJhc2VzKCk6IHZvaWQge1xuICAgIHRoaXMuYmFzZVBvc2l0aW9ucyA9IHRoaXMuZ2FtZVNlcnZpY2UuZ2V0QWxpZW5CYXNlUG9zaXRpb25zKCk7XG4gICAgbGV0IGJhc2VQb3NpdGlvbkNvdW50ZXIgPSAwO1xuICAgIGlmICh0aGlzLmJhc2VzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYmFzZVBvc2l0aW9ucy5tYXAoKHBvc2l0aW9uOiBJQXNzZXQpID0+IHtcbiAgICAgICAgdGhpcy5iYXNlc1tiYXNlUG9zaXRpb25Db3VudGVyXS5tb3ZlKHBvc2l0aW9uKTtcbiAgICAgICAgYmFzZVBvc2l0aW9uQ291bnRlcisrO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHRoZSBhbmltYXRpb25zXG4gICAqXG4gICAqIEBwYXJhbSBpbnZhc2lvblNldHVwIFNldCB1cCB0aGUgaW52YXNpb25cbiAgICovXG4gIHB1YmxpYyBpbml0SW52YXNpb24oaW52YXNpb25TZXR1cDogSW52YXNpb25TZXR1cE1vZGVsKTogdm9pZCB7XG4gICAgdGhpcy5hbGllbnNQZXJXYXZlID0gaW52YXNpb25TZXR1cC5hbGllblBlcldhdmUgPyBpbnZhc2lvblNldHVwLmFsaWVuUGVyV2F2ZSA6IDEwO1xuICAgIHRoaXMud2F2ZXMgPSBpbnZhc2lvblNldHVwLndhdmVzID8gaW52YXNpb25TZXR1cC53YXZlcyA6IDI7XG4gICAgdGhpcy5hbGllblNwZWVkID0gaW52YXNpb25TZXR1cC5hbGllblNwZWVkID8gaW52YXNpb25TZXR1cC5hbGllblNwZWVkIDogNTAwO1xuICAgIHRoaXMud2F2ZVRvdGFsID0gdGhpcy5iYXNlUG9zaXRpb25zLmxlbmd0aCAqIHRoaXMud2F2ZXM7XG4gICAgdGhpcy5kcm9wc2hpcENvdW50ZXIgPSAwO1xuICAgIHRoaXMudG90YWxBbGllbnMgPSB0aGlzLmFsaWVuc1BlcldhdmUgKiB0aGlzLndhdmVUb3RhbDtcblxuICAgIHRoaXMuYW5pbWF0ZUJhc2VzKCk7XG4gICAgdGhpcy5idWlsZENyZWVwKCk7XG4gICAgdGhpcy5wb3NpdGlvbkFsaWVucygpO1xuICAgIHRoaXMud2F2ZUNvdW50ZXIgPSAwO1xuICAgIHRoaXMuYWxpZW5SZWxlYXNlQ291bnRlciA9IDA7XG4gICAgdGhpcy5sYXVuY2hOZXh0QWxpZW5Ecm9wc2hpcCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IEFsaWVuIENyZWVwXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0QWxpZW5DcmVlcChiYXNlSW5kZXg6IG51bWJlciwgYWxpZW5JbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYmFzZUFsaWVucy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmJhc2VBbGllbnNbYmFzZUluZGV4XS5hbGllbnNbYWxpZW5JbmRleF0uaXNBbmltYXRlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBBbGwgQWN0aXZlIEFsaWVuc1xuICAgKi9cbiAgcHVibGljIGdldEFjdGl2ZUFsaWVucygpOiBBbGllbkNsYXNzW10ge1xuICAgIGxldCBhY3RpdmVBbGllbnM6IEFsaWVuQ2xhc3NbXSA9IFtdO1xuXG4gICAgdGhpcy5iYXNlQWxpZW5zLm1hcCgoYWxpZW5XYXZlOiBBbGllbldhdmVNb2RlbCkgPT4ge1xuICAgICAgYWN0aXZlQWxpZW5zID0gYWN0aXZlQWxpZW5zLmNvbmNhdChhbGllbldhdmUuYWxpZW5zLmZpbHRlcigoYWxpZW46IEFsaWVuQ2xhc3MpID0+IGFsaWVuLmlzRGVzdHJveWVkID09PSBmYWxzZSkpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGFjdGl2ZUFsaWVucztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbmltYXRlXG4gICAqIEBwYXJhbSBub3cgdGhlIGN1cnJlbnQgdGltZVxuICAgKi9cbiAgcHVibGljIGFuaW1hdGUobm93ID0gMCk6IHZvaWQge1xuICAgIHRoaXMuYmFzZXMubWFwKChiYXNlOiBCYXNlQ2xhc3MpID0+IHtcbiAgICAgIGJhc2UuYW5pbWF0ZSgpO1xuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuc3RvcEFuaW1hdGlvbigpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5iYXNlQWxpZW5zLm1hcCgoYWxpZW5XYXZlOiBBbGllbldhdmVNb2RlbCkgPT4ge1xuICAgICAgYWxpZW5XYXZlLmFsaWVuc1xuICAgICAgICAuZmlsdGVyKChhbGllbjogQWxpZW5DbGFzcykgPT4gYWxpZW4uaXNBbmltYXRlZCAmJiBhbGllbi5pc0Rlc3Ryb3llZCA9PT0gZmFsc2UpXG4gICAgICAgIC5tYXAoKGFsaWVuOiBBbGllbkNsYXNzKSA9PiB7XG4gICAgICAgICAgYWxpZW4uYW5pbWF0ZShub3cpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXVuY2ggdGhlIG5leHQgZHJvcCBzaGlwXG4gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGRyb3Agc2hpcFxuICAgKi9cbiAgcHJpdmF0ZSBsYXVuY2hOZXh0QWxpZW5Ecm9wc2hpcCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hbGllbkRyb3BzaGlwc1t0aGlzLmRyb3BzaGlwQ291bnRlcl0pIHtcbiAgICAgIHRoaXMuYWxpZW5Ecm9wc2hpcHNbdGhpcy5kcm9wc2hpcENvdW50ZXJdLmlzQW5pbWF0ZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBbmltYXRlXG4gICAqXG4gICAqIEBwYXJhbSBub3cgVGhlIGN1cnJlbnQgYW5pbWF0aW9uIHRpbWVcbiAgICovXG4gIHB1YmxpYyBhbmltYXRlRHJvcHNoaXBzKG5vdyA9IDApOiB2b2lkIHtcbiAgICB0aGlzLmFzc2V0VGltZXIuZWxhcHNlZCA9IG5vdyAtIHRoaXMuYXNzZXRUaW1lci5zdGFydDtcbiAgICBpZiAodGhpcy5zdG9wQW5pbWF0aW9uKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmFsaWVuRHJvcHNoaXBzXG4gICAgICAuZmlsdGVyKChhbGllbkRyb3BzaGlwOiBBbGllbkRyb3BzaGlwQ2xhc3MpID0+IGFsaWVuRHJvcHNoaXAuaXNBbmltYXRlZCAmJiBhbGllbkRyb3BzaGlwLmlzRGVzdHJveWVkID09PSBmYWxzZSlcbiAgICAgIC5tYXAoKGFsaWVuRHJvcHNoaXA6IEFsaWVuRHJvcHNoaXBDbGFzcykgPT4ge1xuICAgICAgICBhbGllbkRyb3BzaGlwLmFuaW1hdGUobm93KTtcbiAgICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuZHJvcHNoaXBDb3VudGVyID09PSB0aGlzLmFsaWVuRHJvcHNoaXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmFsaWVuRHJvcHNoaXBzW3RoaXMuZHJvcHNoaXBDb3VudGVyXS5jYW5MYW5kQWxpZW5zKCkpIHtcbiAgICAgIGlmICh0aGlzLmFzc2V0VGltZXIuZWxhcHNlZCA+IHRoaXMuYWxpZW5TcGVlZCkge1xuICAgICAgICB0aGlzLmFzc2V0VGltZXIuc3RhcnQgPSBub3c7XG4gICAgICAgIGlmICh0aGlzLmFsaWVuUmVsZWFzZUNvdW50ZXIgPT09IHRoaXMuYWxpZW5zUGVyV2F2ZSkge1xuICAgICAgICAgIHRoaXMuYWxpZW5Ecm9wc2hpcHNbdGhpcy5kcm9wc2hpcENvdW50ZXIrK10uc2V0QWxpZW5zTGFuZGVkKCk7XG4gICAgICAgICAgdGhpcy5sYXVuY2hOZXh0QWxpZW5Ecm9wc2hpcCgpO1xuICAgICAgICAgIHRoaXMud2F2ZUNvdW50ZXIrKztcbiAgICAgICAgICB0aGlzLmFsaWVuUmVsZWFzZUNvdW50ZXIgPSAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuc3RhcnRBbGllbkNyZWVwKHRoaXMud2F2ZUNvdW50ZXIsIHRoaXMuYWxpZW5SZWxlYXNlQ291bnRlcisrKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19