123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- (function() {
- var nodeEnv = typeof require !== 'undefined' && typeof process !== 'undefined';
- var __module = nodeEnv ? module : {exports:{}};
- var __filename = 'preview-scripts/assets/script/manager/AStarManager.js';
- var __require = nodeEnv ? function (request) {
- return cc.require(request);
- } : function (request) {
- return __quick_compile_project__.require(request, __filename);
- };
- function __define (exports, require, module) {
- if (!nodeEnv) {__quick_compile_project__.registerModule(__filename, module);}"use strict";
- cc._RF.push(module, '3340f9i319GmJ0tJdpeE3DX', 'AStarManager');
- // script/manager/AStarManager.ts
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- var AStarNode = /** @class */ (function () {
- /**
- * @param x 节点横坐标
- * @param y 节点纵坐标
- */
- function AStarNode(x, y) {
- this._x = 0;
- this._y = 0;
- this.priority = 0;
- this._x = x;
- this._y = y;
- }
- Object.defineProperty(AStarNode.prototype, "x", {
- get: function () { return this._x; },
- enumerable: false,
- configurable: true
- });
- Object.defineProperty(AStarNode.prototype, "y", {
- get: function () { return this._y; },
- enumerable: false,
- configurable: true
- });
- return AStarNode;
- }());
- var Frontier = /** @class */ (function () {
- function Frontier() {
- this.arr = []; //创建字典(数组)
- }
- Frontier.prototype.put = function (node, priority) {
- node.priority = priority;
- this.arr.push(node); //添加元素
- this.arr.sort(function (a, b) { return b.priority - a.priority; });
- };
- Frontier.prototype.get = function () {
- return this.arr.pop(); //删除元素
- };
- Object.defineProperty(Frontier.prototype, "size", {
- get: function () {
- return this.arr.length;
- },
- enumerable: false,
- configurable: true
- });
- Frontier.prototype.reset = function () {
- this.arr = [];
- };
- return Frontier;
- }());
- var AStarManager = /** @class */ (function () {
- // 通过private修饰符,让类无法在外部创建新的实例
- function AStarManager() {
- this.mSize = null; // 寻路地图大小
- this.mStart = null; // 寻路起始点坐标
- this.mEnd = null; // 寻路目标点坐标
- this.mStartNode = null; // 起始点
- this.mEndNode = null; // 目标点
- this.obstacles = {};
- ///////////////////////////// 寻路开始 ////////////////////
- // 节点池
- this.nodePool = {};
- // 探索边界
- this.frontier = null;
- // 节点来向(路径)
- this.cameForm = new Map();
- // 节点当前代价
- this.costSoFar = new Map();
- this.closeList = [];
- }
- AStarManager.Instance = function () {
- if (!this.instance) {
- this.instance = new AStarManager();
- }
- return this.instance;
- };
- ;
- /**
- * 设置地图横纵最大值
- * @param size 地图大小
- * @param start 寻路起始点
- * @param end 寻路目标点
- * @param obstacles 障碍物
- */
- AStarManager.prototype.init = function (size, start, end, obstacles) {
- var _this = this;
- if (obstacles === void 0) { obstacles = []; }
- this.mSize = size;
- this.mStart = start;
- this.mEnd = end;
- this.obstacles = {};
- obstacles.forEach(function (ele) {
- _this.setObstacles(ele.x, ele.y);
- });
- this.nodePool = {};
- this.mStartNode = this.createNode(this.mStart.x, this.mStart.y);
- this.mEndNode = this.createNode(this.mEnd.x, this.mEnd.y);
- };
- AStarManager.prototype.clean = function () {
- this.mStartNode = null;
- this.mEndNode = null;
- };
- /**
- * 设置障碍物
- * @param x 障碍物横坐标
- * @param y 障碍物纵坐标
- */
- AStarManager.prototype.setObstacles = function (x, y) {
- if (!this.checkNode(x, y))
- return;
- this.obstacles[x + "_" + y] = true;
- };
- /**
- * 清除障碍物
- * @param x 障碍物横坐标
- * @param y 障碍物纵坐标
- */
- AStarManager.prototype.clearObstacles = function (x, y) {
- delete this.obstacles[x + "_" + y];
- };
- /**
- * 检查是否有障碍物
- * @param x 障碍物横坐标
- * @param y 障碍物纵坐标
- */
- AStarManager.prototype.checkObstacles = function (x, y) {
- return this.obstacles[x + "_" + y];
- };
- /**
- * 检查节点是否在地图内
- * @param x 节点横坐标
- * @param y 节点纵坐标
- */
- AStarManager.prototype.checkNode = function (x, y) {
- return x >= 0 && y >= 0 && x <= this.mSize.width && y <= this.mSize.height;
- };
- /**
- * 开始寻路
- * @param type 寻路类型,4方向或8方向
- */
- AStarManager.prototype.run = function (type) {
- if (type === void 0) { type = 4; }
- this.mType = type;
- // console.log('##### 寻路开始 #####');
- // console.log('地图大小:', this.mSize);
- // console.log('寻路类型:', this.mType + '方向');
- // console.log(`出发点X:${this.mStart.x}_Y:${this.mStart.y}`);
- // console.log(`目标点:X:${this.mEnd.x}_Y:${this.mEnd.y}`);
- // console.log('障碍物:', this.obstacles);
- var start = this.mStartNode;
- var goal = this.mEndNode;
- if (this.frontier)
- this.frontier.reset();
- else
- this.frontier = new Frontier();
- this.frontier.put(start, 0); //将起始点加入openList,表示我们从这里触发,是我们第一步可以走的点
- this.cameForm.clear();
- this.cameForm.set(start, null);
- this.costSoFar.clear();
- this.costSoFar.set(start, 0);
- this.closeList = [];
- while (this.frontier.size > 0) {
- var curr = this.frontier.get(); // 每次都取出f值最小的节点进行查找
- if (curr === goal) {
- break;
- }
- var nextList = this.getNeighbors(curr); //从openList中取出一个点作为nextNode,获取这个点下一步所有可走的点,存入nextList
- for (var _i = 0, nextList_1 = nextList; _i < nextList_1.length; _i++) { //如果nextList长度为0,说明没有路可走了;长度为大于0,则将nextList中的点都放入openList
- var next = nextList_1[_i];
- if (this.closeList.indexOf(this.getNodeKey(next.x, next.y)) < 0) {
- var nextCost = this.costSoFar.get(curr) + this.getCost(curr, next);
- // console.log("next的索引:"+this.getNodeKey(next.x,next.y)+",开销:"+nextCost+"父节点索引:"+this.getNodeKey(curr.x,curr.y))
- if (!this.costSoFar.has(next) || nextCost < this.costSoFar.get(next)) {
- this.costSoFar.set(next, nextCost);
- var preCost = this.getCost(next, goal);
- this.frontier.put(next, nextCost + preCost); //内部根据开销进行了自动排序(从小到大)
- this.cameForm.set(next, curr);
- }
- }
- }
- this.closeList.push(this.getNodeKey(curr.x, curr.y));
- }
- };
- AStarManager.prototype.getPath = function () {
- var arr = [];
- var node = this.mEndNode;
- arr.push(node);
- while (this.cameForm.has(node)) {
- node = this.cameForm.get(node);
- node && arr.push(node);
- }
- return arr;
- };
- AStarManager.prototype.getNeighbors = function (node) {
- var neighbors = [];
- if (this.mType === 8) {
- var upright = this.getNode(node.x + 1, node.y + 1);
- upright && neighbors.push(upright);
- var upleft = this.getNode(node.x - 1, node.y + 1);
- upleft && neighbors.push(upleft);
- var downleft = this.getNode(node.x - 1, node.y - 1);
- downleft && neighbors.push(downleft);
- var downright = this.getNode(node.x + 1, node.y - 1);
- downright && neighbors.push(downright);
- }
- var up = this.getNode(node.x, node.y + 1);
- up && neighbors.push(up);
- var down = this.getNode(node.x, node.y - 1);
- down && neighbors.push(down);
- var left = this.getNode(node.x - 1, node.y);
- left && neighbors.push(left);
- var right = this.getNode(node.x + 1, node.y);
- right && neighbors.push(right);
- return neighbors;
- };
- AStarManager.prototype.getCost = function (node1, node2) {
- return cc.Vec2.distance(new cc.Vec2(node1.x, node1.y), new cc.Vec2(node2.x, node2.y));
- };
- // 寻找下一个点
- AStarManager.prototype.next = function () {
- };
- AStarManager.prototype.getNode = function (x, y) {
- if (!this.checkNode(x, y))
- return;
- if (this.checkObstacles(x, y))
- return;
- var key = this.getNodeKey(x, y);
- return this.nodePool[key] || this.createNode(x, y);
- };
- AStarManager.prototype.createNode = function (x, y) {
- var key = this.getNodeKey(x, y);
- this.nodePool[key] = new AStarNode(x, y);
- return this.nodePool[key];
- };
- AStarManager.prototype.getNodeKey = function (x, y) {
- return x + "_" + y;
- };
- AStarManager.instance = null;
- return AStarManager;
- }());
- exports.default = AStarManager;
- cc._RF.pop();
- }
- if (nodeEnv) {
- __define(__module.exports, __require, __module);
- }
- else {
- __quick_compile_project__.registerModuleFunc(__filename, function () {
- __define(__module.exports, __require, __module);
- });
- }
- })();
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFzc2V0cy9zY3JpcHQvbWFuYWdlci9BU3Rhck1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtJQUtJOzs7T0FHRztJQUNILG1CQUFZLENBQVEsRUFBRSxDQUFRO1FBUnRCLE9BQUUsR0FBVSxDQUFDLENBQUM7UUFDZCxPQUFFLEdBQVUsQ0FBQyxDQUFDO1FBV3RCLGFBQVEsR0FBRyxDQUFDLENBQUM7UUFIVCxJQUFJLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNaLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2hCLENBQUM7SUFURCxzQkFBSSx3QkFBQzthQUFMLGNBQVMsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUEsQ0FBQzs7O09BQUE7SUFDekIsc0JBQUksd0JBQUM7YUFBTCxjQUFTLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBLENBQUM7OztPQUFBO0lBVTdCLGdCQUFDO0FBQUQsQ0FkQSxBQWNDLElBQUE7QUFFRDtJQUFBO1FBQ1ksUUFBRyxHQUFlLEVBQUUsQ0FBQyxDQUFBLFVBQVU7SUFpQjNDLENBQUM7SUFoQkcsc0JBQUcsR0FBSCxVQUFJLElBQWMsRUFBRSxRQUFlO1FBQy9CLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsT0FBTztRQUM1QixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFDLENBQUMsRUFBQyxDQUFDLElBQUcsT0FBQSxDQUFDLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQXZCLENBQXVCLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBQ0Qsc0JBQUcsR0FBSDtRQUNJLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFBLE1BQU07SUFDaEMsQ0FBQztJQUVELHNCQUFJLDBCQUFJ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TSxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3BELE1BQU0sSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRWpDLElBQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN0RCxRQUFRLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUVyQyxJQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDdkQsU0FBUyxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDMUM7UUFFRCxJQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM1QyxFQUFFLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUV6QixJQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM5QyxJQUFJLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUU3QixJQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM5QyxJQUFJLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUU3QixJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQyxLQUFLLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUUvQixPQUFPLFNBQVMsQ0FBQztJQUNyQixDQUFDO0lBRUQsOEJBQU8sR0FBUCxVQUFRLEtBQWUsRUFBRSxLQUFlO1FBQ3BDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFGLENBQUM7SUFFRCxTQUFTO0lBQ0YsMkJBQUksR0FBWDtJQUVBLENBQUM7SUFFTyw4QkFBTyxHQUFmLFVBQWdCLENBQVEsRUFBRSxDQUFRO1FBQzlCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7WUFBRSxPQUFPO1FBQ2xDLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQUUsT0FBTztRQUN0QyxJQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNsQyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUNPLGlDQUFVLEdBQWxCLFVBQW1CLENBQVEsRUFBRSxDQUFRO1FBQ2pDLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRU8saUNBQVUsR0FBbEIsVUFBbUIsQ0FBUSxFQUFFLENBQVE7UUFDakMsT0FBVSxDQUFDLFNBQUksQ0FBRyxDQUFDO0lBQ3ZCLENBQUM7SUExTmMscUJBQVEsR0FBZ0IsSUFBSSxDQUFDO0lBMk5oRCxtQkFBQztDQTVORCxBQTROQyxJQUFBO2tCQTVOb0IsWUFBWSIsImZpbGUiOiIiLCJzb3VyY2VSb290IjoiLyIsInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEFTdGFyTm9kZSB7XG4gICAgcHJpdmF0ZSBfeDpudW1iZXIgPSAwO1xuICAgIHByaXZhdGUgX3k6bnVtYmVyID0gMDtcbiAgICBnZXQgeCgpIHtyZXR1cm4gdGhpcy5feDt9XG4gICAgZ2V0IHkoKSB7cmV0dXJuIHRoaXMuX3k7fVxuICAgIC8qKlxuICAgICAqIEBwYXJhbSB4IOiKgueCueaoquWdkOagh1xuICAgICAqIEBwYXJhbSB5IOiKgueCuee6teWdkOagh1xuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKHg6bnVtYmVyLCB5Om51bWJlcikge1xuICAgICAgICB0aGlzLl94ID0geDtcbiAgICAgICAgdGhpcy5feSA9IHk7XG4gICAgfVxuICAgIHByaW9yaXR5ID0gMDtcbn1cblxuY2xhc3MgRnJvbnRpZXIge1xuICAgIHByaXZhdGUgYXJyOkFTdGFyTm9kZVtdID0gW107Ly/liJvlu7rlrZflhbgo5pWw57uEKVxuICAgIHB1dChub2RlOkFTdGFyTm9kZSwgcHJpb3JpdHk6bnVtYmVyKSB7XG4gICAgICAgIG5vZGUucHJpb3JpdHkgPSBwcmlvcml0eTtcbiAgICAgICAgdGhpcy5hcnIucHVzaChub2RlKTsgLy/mt7vliqDlhYPntKAgXG4gICAgICAgIHRoaXMuYXJyLnNvcnQoKGEsYik9PmIucHJpb3JpdHkgLSBhLnByaW9yaXR5KTtcbiAgICB9XG4gICAgZ2V0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hcnIucG9wKCk7Ly/liKDpmaTlhYPntKBcbiAgICB9XG5cbiAgICBnZXQgc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYXJyLmxlbmd0aDtcbiAgICB9XG5cbiAgICByZXNldCgpe1xuICAgICAgICB0aGlzLmFyciA9IFtdO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQVN0YXJNYW5hZ2Vye1xuICAgIHByaXZhdGUgc3RhdGljIGluc3RhbmNlOkFTdGFyTWFuYWdlciA9IG51bGw7XG4gICBcbiAgICBzdGF0aWMgSW5zdGFuY2UoKSB7XG4gICAgICAgIGlmICghdGhpcy5pbnN0YW5jZSkgeyBcbiAgICAgICAgICAgIHRoaXMuaW5zdGFuY2UgPSBuZXcgQVN0YXJNYW5hZ2VyKCk7IFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmluc3RhbmNlO1xuICAgIH07XG5cbiAgICAvLyDpgJrov4dwcml2YXRl5L+u6aWw56ym77yM6K6p57G75peg5rOV5Zyo5aSW6YOo5Yib5bu65paw55qE5a6e5L6LXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHsgXG5cbiAgICB9XG4gICAgXG5cbiAgICBwcml2YXRlIG1TaXplOmNjLlNpemUgPSBudWxsOyAgLy8g5a+76Lev5Zyw5Zu+5aSn5bCPXG4gICAgcHJpdmF0ZSBtU3RhcnQ6Y2MuVmVjMiA9IG51bGw7IC8vIOWvu+i3r+i1t+Wni+eCueWdkOagh1xuICAgIHByaXZhdGUgbUVuZDpjYy5WZWMyID0gbnVsbDsgICAvLyDlr7vot6/nm67moIfngrnlnZDmoIdcblxuICAgIHByaXZhdGUgbVN0YXJ0Tm9kZTpBU3Rhck5vZGUgPSBudWxsOyAvLyDotbflp4vngrlcbiAgICBwcml2YXRlIG1FbmROb2RlOkFTdGFyTm9kZSA9IG51bGw7ICAgLy8g55uu5qCH54K5XG4gICAgLyoqXG4gICAgICog6K6+572u5Zyw5Zu+5qiq57q15pyA5aSn5YC8XG4gICAgICogQHBhcmFtIHNpemUgICAgICDlnLDlm77lpKflsI9cbiAgICAgKiBAcGFyYW0gc3RhcnQgICAgIOWvu+i3r+i1t+Wni+eCuVxuICAgICAqIEBwYXJhbSBlbmQgICAgICAg5a+76Lev55uu5qCH54K5XG4gICAgICogQHBhcmFtIG9ic3RhY2xlcyDpmpznoo3nialcbiAgICAgKi9cbiAgICBwdWJsaWMgaW5pdChzaXplOmNjLlNpemUsIHN0YXJ0OmNjLlZlYzIsIGVuZDpjYy5WZWMyLCBvYnN0YWNsZXM6Y2MuVmVjMltdID0gW10pIHtcbiAgICAgICAgdGhpcy5tU2l6ZSA9IHNpemU7XG4gICAgICAgIHRoaXMubVN0YXJ0ID0gc3RhcnQ7XG4gICAgICAgIHRoaXMubUVuZCA9IGVuZDtcbiAgICAgICAgdGhpcy5vYnN0YWNsZXMgPSB7fTtcbiAgICAgICAgb2JzdGFjbGVzLmZvckVhY2goKGVsZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZXRPYnN0YWNsZXMoZWxlLngsIGVsZS55KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5ub2RlUG9vbCA9IHt9O1xuXG4gICAgICAgIHRoaXMubVN0YXJ0Tm9kZSA9IHRoaXMuY3JlYXRlTm9kZSh0aGlzLm1TdGFydC54LCB0aGlzLm1TdGFydC55KTtcbiAgICAgICAgdGhpcy5tRW5kTm9kZSAgID0gdGhpcy5jcmVhdGVOb2RlKHRoaXMubUVuZC54LCB0aGlzLm1FbmQueSk7XG4gICAgfVxuXG4gICAgcHVibGljIGNsZWFuKCl7XG4gICAgICAgIHRoaXMubVN0YXJ0Tm9kZSA9IG51bGw7XG4gICAgICAgIHRoaXMubUVuZE5vZGUgPSBudWxsO1xuICAgIH1cbiAgICBcbiAgICBwcml2YXRlIG9ic3RhY2xlczp7W3hfeTpzdHJpbmddOmJvb2xlYW59ID0ge307XG4gICAgLyoqXG4gICAgICog6K6+572u6Zqc56KN54mpXG4gICAgICogQHBhcmFtIHgg6Zqc56KN54mp5qiq5Z2Q5qCHXG4gICAgICogQHBhcmFtIHkg6Zqc56KN54mp57q15Z2Q5qCHXG4gICAgICovXG4gICAgcHVibGljIHNldE9ic3RhY2xlcyh4Om51bWJlciwgeTpudW1iZXIpIHtcbiAgICAgICAgaWYgKCF0aGlzLmNoZWNrTm9kZSh4LCB5KSkgcmV0dXJuO1xuICAgICAgICB0aGlzLm9ic3RhY2xlc1tgJHt4fV8ke3l9YF0gPSB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiDmuIXpmaTpmpznoo3nialcbiAgICAgKiBAcGFyYW0geCDpmpznoo3nianmqKrlnZDmoIdcbiAgICAgKiBAcGFyYW0geSDpmpznoo3niannurXlnZDmoIdcbiAgICAgKi9cbiAgICBwdWJsaWMgY2xlYXJPYnN0YWNsZXMoeDpudW1iZXIsIHk6bnVtYmVyKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLm9ic3RhY2xlc1tgJHt4fV8ke3l9YF07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIOajgOafpeaYr+WQpuaciemanOeijeeJqVxuICAgICAqIEBwYXJhbSB4IOmanOeijeeJqeaoquWdkOagh1xuICAgICAqIEBwYXJhbSB5IOmanOeijeeJqee6teWdkOagh1xuICAgICAqL1xuICAgIHB1YmxpYyBjaGVja09ic3RhY2xlcyh4Om51bWJlciwgeTpudW1iZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub2JzdGFjbGVzW2Ake3h9XyR7eX1gXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDmo4Dmn6XoioLngrnmmK/lkKblnKjlnLDlm77lhoVcbiAgICAgKiBAcGFyYW0geCDoioLngrnmqKrlnZDmoIdcbiAgICAgKiBAcGFyYW0geSDoioLngrnnurXlnZDmoIdcbiAgICAgKi9cbiAgICBwdWJsaWMgY2hlY2tOb2RlKHg6bnVtYmVyLCB5Om51bWJlcikge1xuICAgICAgICByZXR1cm4geCA+PSAwICYmIHkgPj0gMCAmJiB4IDw9IHRoaXMubVNpemUud2lkdGggJiYgeSA8PSB0aGlzLm1TaXplLmhlaWdodDtcbiAgICB9XG5cbiBcbiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyDlr7vot6/lvIDlp4sgLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAvLyDoioLngrnmsaBcbiAgICBwcml2YXRlIG5vZGVQb29sOntbeF95OnN0cmluZ106QVN0YXJOb2RlfSA9IHt9O1xuICAgIC8vIOaOoue0oui+ueeVjFxuICAgIHByaXZhdGUgZnJvbnRpZXI6RnJvbnRpZXIgPSBudWxsO1xuICAgIC8vIOiKgueCueadpeWQkSjot6/lvoQpXG4gICAgcHJpdmF0ZSBjYW1lRm9ybTpNYXA8QVN0YXJOb2RlLCBBU3Rhck5vZGU+ID0gbmV3IE1hcCgpO1xuICAgIC8vIOiKgueCueW9k+WJjeS7o+S7t1xuICAgIHByaXZhdGUgY29zdFNvRmFyOk1hcDxBU3Rhck5vZGUsIG51bWJlcj4gPSBuZXcgTWFwKCk7XG4gICAgLy8g5a+76Lev57G75Z6LKDTmlrnlkJHmiJY45pa55ZCRKVxuICAgIHByaXZhdGUgbVR5cGU6IDR8ODtcblxuICAgIHByaXZhdGUgY2xvc2VMaXN0OnN0cmluZ1tdID0gW107XG5cbiAgICAvKipcbiAgICAgKiDlvIDlp4vlr7vot69cbiAgICAgKiBAcGFyYW0gdHlwZSDlr7vot6/nsbvlnovvvIw05pa55ZCR5oiWOOaWueWQkVxuICAgICAqL1xuICAgIHB1YmxpYyBydW4odHlwZTo0fDggPSA0KSB7XG4gICAgICAgIHRoaXMubVR5cGUgPSB0eXBlO1xuXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCcjIyMjIyDlr7vot6/lvIDlp4sgIyMjIyMnKTtcblxuICAgICAgICAvLyBjb25zb2xlLmxvZygn5Zyw5Zu+5aSn5bCPOicsIHRoaXMubVNpemUpO1xuICAgICAgICAvLyBjb25zb2xlLmxvZygn5a+76Lev57G75Z6LOicsIHRoaXMubVR5cGUgKyAn5pa55ZCRJyk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGDlh7rlj5HngrlYOiR7dGhpcy5tU3RhcnQueH1fWToke3RoaXMubVN0YXJ0Lnl9YCk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGDnm67moIfngrk6WDoke3RoaXMubUVuZC54fV9ZOiR7dGhpcy5tRW5kLnl9YCk7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCfpmpznoo3niak6JywgdGhpcy5vYnN0YWNsZXMpO1xuXG5cbiAgICAgICAgY29uc3Qgc3RhcnQgPSB0aGlzLm1TdGFydE5vZGU7XG4gICAgICAgIGNvbnN0IGdvYWwgPSB0aGlzLm1FbmROb2RlO1xuICAgICAgICBpZiAodGhpcy5mcm9udGllcilcbiAgICAgICAgICAgIHRoaXMuZnJvbnRpZXIucmVzZXQoKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5mcm9udGllciA9IG5ldyBGcm9udGllcigpO1xuXG4gICAgICAgIHRoaXMuZnJvbnRpZXIucHV0KHN0YXJ0LCAwKTsvL+Wwhui1t+Wni+eCueWKoOWFpW9wZW5MaXN077yM6KGo56S65oiR5Lus5LuO6L+Z6YeM6Kem5Y+R77yM5piv5oiR5Lus56ys5LiA5q2l5Y+v5Lul6LWw55qE54K5XG5cbiAgICAgICAgdGhpcy5jYW1lRm9ybS5jbGVhcigpO1xuICAgICAgICB0aGlzLmNhbWVGb3JtLnNldChzdGFydCwgbnVsbCk7XG4gICAgICAgIHRoaXMuY29zdFNvRmFyLmNsZWFyKCk7XG4gICAgICAgIHRoaXMuY29zdFNvRmFyLnNldChzdGFydCwgMCk7XG4gICAgICAgIHRoaXMuY2xvc2VMaXN0ID0gW107XG5cbiAgICAgICAgd2hpbGUgKHRoaXMuZnJvbnRpZXIuc2l6ZSA+IDApIHtcbiAgICAgICAgICAgIGxldCBjdXJyID0gdGhpcy5mcm9udGllci5nZXQoKTsgIC8vIOavj+asoemDveWPluWHumblgLzmnIDlsI/nmoToioLngrnov5vooYzmn6Xmib5cbiAgICAgICAgICAgIGlmIChjdXJyID09PSBnb2FsKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgbmV4dExpc3QgPSB0aGlzLmdldE5laWdoYm9ycyhjdXJyKTsgLy/ku45vcGVuTGlzdOS4reWPluWHuuS4gOS4queCueS9nOS4um5leHROb2Rl77yM6I635Y+W6L+Z5Liq54K55LiL5LiA5q2l5omA5pyJ5Y+v6LWw55qE54K577yM5a2Y5YWlbmV4dExpc3RcbiAgICAgICAgICAgIGZvciAobGV0IG5leHQgb2YgbmV4dExpc3QpIHsvL+WmguaenG5leHRMaXN06ZW/5bqm5Li6MO+8jOivtOaYjuayoeaciei3r+WPr+i1sOS6hjvplb/luqbkuLrlpKfkuo4w77yM5YiZ5bCGbmV4dExpc3TkuK3nmoTngrnpg73mlL7lhaVvcGVuTGlzdFxuICAgICAgICAgICAgICAgIGlmKHRoaXMuY2xvc2VMaXN0LmluZGV4T2YodGhpcy5nZXROb2RlS2V5KG5leHQueCxuZXh0LnkpKSA8IDApe1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXh0Q29zdCA9IHRoaXMuY29zdFNvRmFyLmdldChjdXJyKSArIHRoaXMuZ2V0Q29zdChjdXJyLCBuZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJuZXh055qE57Si5byVOlwiK3RoaXMuZ2V0Tm9kZUtleShuZXh0LngsbmV4dC55KStcIizlvIDplIA6XCIrbmV4dENvc3QrXCLniLboioLngrnntKLlvJU6XCIrdGhpcy5nZXROb2RlS2V5KGN1cnIueCxjdXJyLnkpKVxuICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29zdFNvRmFyLmhhcyhuZXh0KSB8fCBuZXh0Q29zdCA8IHRoaXMuY29zdFNvRmFyLmdldChuZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jb3N0U29GYXIuc2V0KG5leHQsIG5leHRDb3N0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByZUNvc3QgPSB0aGlzLmdldENvc3QobmV4dCwgZ29hbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZyb250aWVyLnB1dChuZXh0LCBuZXh0Q29zdCArIHByZUNvc3QpOy8v5YaF6YOo5qC55o2u5byA6ZSA6L+b6KGM5LqG6Ieq5Yqo5o6S5bqPKOS7juWwj+WIsOWkpylcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY2FtZUZvcm0uc2V0KG5leHQsIGN1cnIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jbG9zZUxpc3QucHVzaCh0aGlzLmdldE5vZGVLZXkoY3Vyci54LGN1cnIueSkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGdldFBhdGgoKSB7XG4gICAgICAgIGNvbnN0IGFyciA9IFtdO1xuICAgICAgICBsZXQgbm9kZSA9IHRoaXMubUVuZE5vZGU7XG4gICAgICAgIGFyci5wdXNoKG5vZGUpO1xuICAgICAgICB3aGlsZSAodGhpcy5jYW1lRm9ybS5oYXMobm9kZSkpIHtcbiAgICAgICAgICAgIG5vZGUgPSB0aGlzLmNhbWVGb3JtLmdldChub2RlKTtcbiAgICAgICAgICAgIG5vZGUgJiYgYXJyLnB1c2gobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFycjtcbiAgICB9XG5cbiAgICBnZXROZWlnaGJvcnMobm9kZTpBU3Rhck5vZGUpIHtcbiAgICAgICAgY29uc3QgbmVpZ2hib3JzID0gW107XG5cbiAgICAgICAgaWYgKHRoaXMubVR5cGUgPT09IDgpIHtcbiAgICAgICAgICAgIGNvbnN0IHVwcmlnaHQgPSB0aGlzLmdldE5vZGUobm9kZS54ICsgMSwgbm9kZS55ICsgMSk7XG4gICAgICAgICAgICB1cHJpZ2h0ICYmIG5laWdoYm9ycy5wdXNoKHVwcmlnaHQpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBjb25zdCB1cGxlZnQgPSB0aGlzLmdldE5vZGUobm9kZS54IC0gMSwgbm9kZS55ICsgMSk7XG4gICAgICAgICAgICB1cGxlZnQgJiYgbmVpZ2hib3JzLnB1c2godXBsZWZ0KTtcbiAgICBcbiAgICAgICAgICAgIGNvbnN0IGRvd25sZWZ0ID0gdGhpcy5nZXROb2RlKG5vZGUueCAtIDEsIG5vZGUueSAtIDEpO1xuICAgICAgICAgICAgZG93bmxlZnQgJiYgbmVpZ2hib3JzLnB1c2goZG93bmxlZnQpO1xuICAgIFxuICAgICAgICAgICAgY29uc3QgZG93bnJpZ2h0ID0gdGhpcy5nZXROb2RlKG5vZGUueCArIDEsIG5vZGUueSAtIDEpO1xuICAgICAgICAgICAgZG93bnJpZ2h0ICYmIG5laWdoYm9ycy5wdXNoKGRvd25yaWdodCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB1cCA9IHRoaXMuZ2V0Tm9kZShub2RlLngsIG5vZGUueSArIDEpO1xuICAgICAgICB1cCAmJiBuZWlnaGJvcnMucHVzaCh1cCk7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBkb3duID0gdGhpcy5nZXROb2RlKG5vZGUueCwgbm9kZS55IC0gMSk7XG4gICAgICAgIGRvd24gJiYgbmVpZ2hib3JzLnB1c2goZG93bik7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBsZWZ0ID0gdGhpcy5nZXROb2RlKG5vZGUueCAtIDEsIG5vZGUueSk7XG4gICAgICAgIGxlZnQgJiYgbmVpZ2hib3JzLnB1c2gobGVmdCk7XG4gICAgICAgIFxuICAgICAgICBjb25zdCByaWdodCA9IHRoaXMuZ2V0Tm9kZShub2RlLnggKyAxLCBub2RlLnkpO1xuICAgICAgICByaWdodCAmJiBuZWlnaGJvcnMucHVzaChyaWdodCk7XG5cbiAgICAgICAgcmV0dXJuIG5laWdoYm9ycztcbiAgICB9XG5cbiAgICBnZXRDb3N0KG5vZGUxOkFTdGFyTm9kZSwgbm9kZTI6QVN0YXJOb2RlKSB7XG4gICAgICAgIHJldHVybiBjYy5WZWMyLmRpc3RhbmNlKG5ldyBjYy5WZWMyKG5vZGUxLngsIG5vZGUxLnkpLCBuZXcgY2MuVmVjMihub2RlMi54LCBub2RlMi55KSk7XG4gICAgfVxuXG4gICAgLy8g5a+75om+5LiL5LiA5Liq54K5XG4gICAgcHVibGljIG5leHQoKSB7XG4gICAgICAgIFxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0Tm9kZSh4Om51bWJlciwgeTpudW1iZXIpOiBBU3Rhck5vZGUge1xuICAgICAgICBpZiAoIXRoaXMuY2hlY2tOb2RlKHgsIHkpKSByZXR1cm47XG4gICAgICAgIGlmICh0aGlzLmNoZWNrT2JzdGFjbGVzKHgsIHkpKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0Tm9kZUtleSh4LCB5KTtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9kZVBvb2xba2V5XSB8fCB0aGlzLmNyZWF0ZU5vZGUoeCwgeSk7IFxuICAgIH1cbiAgICBwcml2YXRlIGNyZWF0ZU5vZGUoeDpudW1iZXIsIHk6bnVtYmVyKSB7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0Tm9kZUtleSh4LCB5KTtcbiAgICAgICAgdGhpcy5ub2RlUG9vbFtrZXldID0gbmV3IEFTdGFyTm9kZSh4LCB5KTtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9kZVBvb2xba2V5XTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldE5vZGVLZXkoeDpudW1iZXIsIHk6bnVtYmVyKSB7XG4gICAgICAgIHJldHVybiBgJHt4fV8ke3l9YDtcbiAgICB9XG59XG4iXX0=
|