123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- (function() {
- var nodeEnv = typeof require !== 'undefined' && typeof process !== 'undefined';
- var __module = nodeEnv ? module : {exports:{}};
- var __filename = 'preview-scripts/assets/scriptMain/HotUpdate.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, 'cad1eUCkthF8avyAcwRFs+0', 'HotUpdate');
- // scriptMain/HotUpdate.ts
- "use strict";
- var __extends = (this && this.__extends) || (function () {
- var extendStatics = function (d, b) {
- extendStatics = Object.setPrototypeOf ||
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
- function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
- return extendStatics(d, b);
- };
- return function (d, b) {
- extendStatics(d, b);
- function __() { this.constructor = d; }
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
- };
- })();
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
- return c > 3 && r && Object.defineProperty(target, key, r), r;
- };
- Object.defineProperty(exports, "__esModule", { value: true });
- var _a = cc._decorator, ccclass = _a.ccclass, property = _a.property;
- var HotUpdate = /** @class */ (function (_super) {
- __extends(HotUpdate, _super);
- function HotUpdate() {
- var _this = _super !== null && _super.apply(this, arguments) || this;
- _this.txtProgress = null;
- _this.txtProgressTips = null;
- _this.gProgress = null;
- _this.imgRole = null;
- _this.progress = null;
- _this.progressBar = null;
- _this.manifestUrl = null;
- return _this;
- }
- HotUpdate.prototype.checkCb = function (event) {
- var _this = this;
- // cc.log('Code: ' + event.getEventCode());
- var isNewVersion = false;
- switch (event.getEventCode()) {
- case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
- console.log("No local manifest file found, hot update skipped.");
- break;
- case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
- case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
- console.log("Fail to download manifest file, hot update skipped.");
- break;
- case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
- console.log("Already up to date with the latest remote version.");
- this.EnterGame();
- break;
- case jsb.EventAssetsManager.NEW_VERSION_FOUND:
- console.log("New version found, please try to update.(" + this._am.getTotalBytes() + ')');
- isNewVersion = true;
- break;
- default:
- return;
- }
- this._am.setEventCallback(null);
- this._checkListener = null;
- this._updating = false;
- if (isNewVersion) {
- //有新版本,显示进度
- this.setProgress(0);
- this.hotUpdate();
- //5秒后判断是否开始下载,如果进度为0.直接进游戏,防止卡死
- this.scheduleOnce(function () {
- if (_this.progressBar.fillRange == 0) {
- _this.EnterGame();
- }
- }, 10);
- }
- };
- HotUpdate.prototype.setProgress = function (val) {
- this.gProgress.active = true;
- this.progressBar.fillRange = val;
- this.imgRole.x = -this.progress.width / 2 + val * this.progress.width;
- this.txtProgress.getComponent(cc.Label).string = Math.floor(val * 100) + "%";
- this.txtProgressTips.getComponent(cc.Label).string = "资源更新中";
- };
- HotUpdate.prototype.updateCb = function (event) {
- var needRestart = false;
- var failed = false;
- // console.log("updateCb event:"+JSON.stringify(event));
- switch (event.getEventCode()) {
- case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
- // console.log('No local manifest file found, hot update skipped.');
- failed = true;
- break;
- case jsb.EventAssetsManager.UPDATE_PROGRESSION:
- // this.panel.byteProgress.progress = event.getPercent();
- // this.panel.fileProgress.progress = event.getPercentByFile();
- // this.panel.fileLabel.string = event.getDownloadedFiles() + ' / ' + event.getTotalFiles();
- // this.panel.byteLabel.string = event.getDownloadedBytes() + ' / ' + event.getTotalBytes();
- // this.pb_hotUpdate.progress = event.getPercent();
- // this.lb_progress.string = Math.floor(event.getPercent()*100).toFixed(2) + '%';
- this.setProgress(event.getPercent());
- // var msg = event.getMessage();
- // if (msg) {
- // cc.log(event.getPercent()/100 + '% : ' + msg);
- // }
- break;
- case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
- case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
- // console.log('Fail to download manifest file, hot update skipped.');
- failed = true;
- break;
- case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
- // console.log('Already up to date with the latest remote version.');
- failed = true;
- break;
- case jsb.EventAssetsManager.UPDATE_FINISHED:
- // console.log('Update finished. ' + event.getMessage());
- needRestart = true;
- break;
- case jsb.EventAssetsManager.UPDATE_FAILED:
- // console.log('Update failed. ' + event.getMessage());
- break;
- case jsb.EventAssetsManager.ERROR_UPDATING:
- // console.log('Asset update error: ' + event.getAssetId() + ', ' + event.getMessage());
- break;
- case jsb.EventAssetsManager.ERROR_DECOMPRESS:
- // console.log("ERROR_DECOMPRESS:"+event.getMessage());
- break;
- default:
- break;
- }
- if (failed) {
- this._am.setEventCallback(null);
- this._updateListener = null;
- this._updating = false;
- this.EnterGame();
- }
- if (needRestart) {
- this._am.setEventCallback(null);
- this._updateListener = null;
- // Prepend the manifest's search path
- var searchPaths = jsb.fileUtils.getSearchPaths();
- var newPaths = this._am.getLocalManifest().getSearchPaths();
- // console.log(JSON.stringify(newPaths));
- for (var i = 0; i < newPaths.length; i++) {
- if (searchPaths.indexOf(newPaths[i]) == -1) {
- Array.prototype.unshift.apply(searchPaths, [newPaths[i]]);
- }
- }
- // This value will be retrieved and appended to the default search path during game startup,
- // please refer to samples/js-tests/main.js for detailed usage.
- // !!! Re-add the search paths in main.js is very important, otherwise, new scripts won't take effect.
- cc.sys.localStorage.setItem('HotUpdateSearchPaths', JSON.stringify(searchPaths));
- jsb.fileUtils.setSearchPaths(searchPaths);
- cc.audioEngine.stopAll();
- cc.game.restart();
- }
- };
- HotUpdate.prototype.retry = function () {
- if (!this._updating && this._canRetry) {
- this._canRetry = false;
- // console.log('Retry failed Assets...');
- this._am.downloadFailedAssets();
- }
- };
- HotUpdate.prototype.checkUpdate = function () {
- if (this._updating) {
- // console.log('Checking or updating ...');
- return;
- }
- if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
- // Resolve md5 url
- var url = this.manifestUrl.nativeUrl;
- if (cc.loader.md5Pipe) {
- url = cc.loader.md5Pipe.transformURL(url);
- }
- this._am.loadLocalManifest(url);
- }
- if (!this._am.getLocalManifest() || !this._am.getLocalManifest().isLoaded()) {
- console.log('Failed to load local manifest ...');
- this.EnterGame();
- return;
- }
- this.getLocalVersion();
- this._am.setEventCallback(this.checkCb.bind(this));
- this._am.checkUpdate();
- this._updating = true;
- };
- HotUpdate.prototype.hotUpdate = function () {
- if (this._am && !this._updating) {
- this._am.setEventCallback(this.updateCb.bind(this));
- if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
- // Resolve md5 url
- var url = this.manifestUrl.nativeUrl;
- if (cc.loader.md5Pipe) {
- url = cc.loader.md5Pipe.transformURL(url);
- }
- this._am.loadLocalManifest(url);
- }
- this._failCount = 0;
- this._am.update();
- this._updating = true;
- }
- };
- // use this for initialization
- HotUpdate.prototype.onLoad = function () {
- // Hot update is only available in Native build
- if (!cc.sys.isNative) {
- // this.EnterGame();
- return;
- }
- this._storagePath = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'blackjack-remote-asset');
- cc.log('Storage path for remote asset : ' + this._storagePath);
- // Setup your own version compare handler, versionA and B is versions in string
- // if the return value greater than 0, versionA is greater than B,
- // if the return value equals 0, versionA equals to B,
- // if the return value smaller than 0, versionA is smaller than B.
- this.versionCompareHandle = function (versionA, versionB) {
- cc.log("JS Custom Version Compare: version A is " + versionA + ', version B is ' + versionB);
- var vA = versionA.split('.');
- var vB = versionB.split('.');
- for (var i = 0; i < vA.length; ++i) {
- var a = parseInt(vA[i]);
- var b = parseInt(vB[i] || 0);
- if (a === b) {
- continue;
- }
- else {
- return a - b;
- }
- }
- if (vB.length > vA.length) {
- return -1;
- }
- else {
- return 0;
- }
- };
- // Init with empty manifest url for testing custom manifest
- this._am = new jsb.AssetsManager('', this._storagePath, this.versionCompareHandle);
- // Setup the verification callback, but we don't have md5 check function yet, so only print some message
- // Return true if the verification passed, otherwise return false
- this._am.setVerifyCallback(function (path, asset) {
- // When asset is compressed, we don't need to check its md5, because zip file have been deleted.
- var compressed = asset.compressed;
- // Retrieve the correct md5 value.
- var expectedMD5 = asset.md5;
- // asset.path is relative path and path is absolute.
- var relativePath = asset.path;
- // The size of asset file, but this value could be absent.
- var size = asset.size;
- if (compressed) {
- // console.log("Verification passed : " + relativePath);
- return true;
- }
- else {
- // console.log("Verification passed : " + relativePath + ' (' + expectedMD5 + ')');
- return true;
- }
- });
- // // console.log('Hot update is ready, please check or directly update.');
- if (cc.sys.os === cc.sys.OS_ANDROID) {
- // Some Android device may slow down the download process when concurrent tasks is too much.
- // The value may not be accurate, please do more test and find what's most suitable for your game.
- this._am.setMaxConcurrentTask(2);
- // console.log("Max concurrent tasks count have been limited to 2");
- }
- // cc.loader.loadRes('/project.manifest',(err,obj)=>{
- // if (!err) {
- // // let customManifestStr = JSON.stringify(obj);
- // let _nativeAsset = JSON.parse(obj._nativeAsset);
- // var customManifestStr = JSON.stringify({
- // 'packageUrl': _nativeAsset.packageUrl,
- // 'remoteManifestUrl': _nativeAsset.remoteManifestUrl,
- // 'remoteVersionUrl': _nativeAsset.remoteManifestUrl,
- // 'version': _nativeAsset.version,
- // 'assets': _nativeAsset.assert,
- // 'searchPaths': _nativeAsset.searchPaths
- // });
- // if (this._am.getState() === jsb.AssetsManager.State.UNINITED) {
- // var manifest = new jsb.Manifest(customManifestStr, this._storagePath);
- // this._am.loadLocalManifest(manifest, this._storagePath);
- // }
- // }
- // });
- //开始检测更新
- // this.checkUpdate();
- };
- HotUpdate.prototype.EnterGame = function () {
- // 游戏初始化
- this.getLocalVersion();
- this.scheduleOnce(function () {
- cc.director.loadScene("loading");
- }, 4);
- this._canEnterGame = true;
- };
- //获取本地版本
- HotUpdate.prototype.getLocalVersion = function () {
- var localVersion = '';
- if (this._am && this._am.getLocalManifest() && !this._updating) {
- localVersion = this._am.getLocalManifest().getVersion();
- console.log("curVersion1:" + localVersion);
- Promise.resolve().then(function () { return require("Config"); }).then(function (cfgParam) {
- var config = cfgParam.default;
- config.appVersion = localVersion;
- console.log("curVersion2:" + localVersion);
- });
- // console.log("curVersion:"+localVersion);
- }
- //return localVersion;
- };
- HotUpdate.prototype.onDestroy = function () {
- if (this._updateListener) {
- this._am.setEventCallback(null);
- this._updateListener = null;
- }
- };
- __decorate([
- property({ type: cc.Node })
- ], HotUpdate.prototype, "txtProgress", void 0);
- __decorate([
- property({ type: cc.Node })
- ], HotUpdate.prototype, "txtProgressTips", void 0);
- __decorate([
- property({ type: cc.Node })
- ], HotUpdate.prototype, "gProgress", void 0);
- __decorate([
- property({ type: cc.Node })
- ], HotUpdate.prototype, "imgRole", void 0);
- __decorate([
- property({ type: cc.Node })
- ], HotUpdate.prototype, "progress", void 0);
- __decorate([
- property({ type: cc.Sprite })
- ], HotUpdate.prototype, "progressBar", void 0);
- __decorate([
- property({ type: cc.Asset })
- ], HotUpdate.prototype, "manifestUrl", void 0);
- HotUpdate = __decorate([
- ccclass
- ], HotUpdate);
- return HotUpdate;
- }(cc.Component));
- exports.default = HotUpdate;
- ;
- 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFzc2V0cy9zY3JpcHRNYWluL0hvdFVwZGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDTSxJQUFBLEtBQXdCLEVBQUUsQ0FBQyxVQUFVLEVBQW5DLE9BQU8sYUFBQSxFQUFFLFFBQVEsY0FBa0IsQ0FBQztBQUU1QztJQUF1Qyw2QkFBWTtJQUFuRDtRQUFBLHFFQTZVQztRQTNVVSxpQkFBVyxHQUFZLElBQUksQ0FBQztRQUc1QixxQkFBZSxHQUFZLElBQUksQ0FBQztRQUdoQyxlQUFTLEdBQVksSUFBSSxDQUFDO1FBRzFCLGFBQU8sR0FBWSxJQUFJLENBQUM7UUFHeEIsY0FBUSxHQUFZLElBQUksQ0FBQztRQUd6QixpQkFBVyxHQUFjLElBQUksQ0FBQztRQUc5QixpQkFBVyxHQUFhLElBQUksQ0FBQzs7SUF5VHhDLENBQUM7SUE3U1UsMkJBQU8sR0FBZCxVQUFlLEtBQVU7UUFBekIsaUJBcUNDO1FBcENHLDJDQUEyQztRQUMzQyxJQUFJLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDekIsUUFBUSxLQUFLLENBQUMsWUFBWSxFQUFFLEVBQUU7WUFDMUIsS0FBSyxHQUFHLENBQUMsa0JBQWtCLENBQUMsdUJBQXVCO2dCQUMvQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1EQUFtRCxDQUFDLENBQUM7Z0JBQ2pFLE1BQU07WUFDVixLQUFLLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyx1QkFBdUIsQ0FBQztZQUNwRCxLQUFLLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxvQkFBb0I7Z0JBQzVDLE9BQU8sQ0FBQyxHQUFHLENBQUMscURBQXFELENBQUMsQ0FBQztnQkFDbkUsTUFBTTtZQUNWLEtBQUssR0FBRyxDQUFDLGtCQUFrQixDQUFDLGtCQUFrQjtnQkFDMUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO2dCQUNsRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2pCLE1B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QVMsR0E2VWxEO2tCQTdVb0IsU0FBUztBQTZVN0IsQ0FBQyIsImZpbGUiOiIiLCJzb3VyY2VSb290IjoiLyIsInNvdXJjZXNDb250ZW50IjpbIlxuY29uc3QgeyBjY2NsYXNzLCBwcm9wZXJ0eSB9ID0gY2MuX2RlY29yYXRvcjtcbkBjY2NsYXNzXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIb3RVcGRhdGUgZXh0ZW5kcyBjYy5Db21wb25lbnQge1xuICAgIEBwcm9wZXJ0eSh7IHR5cGU6IGNjLk5vZGUgfSlcbiAgICBwdWJsaWMgdHh0UHJvZ3Jlc3M6IGNjLk5vZGUgPSBudWxsO1xuXG4gICAgQHByb3BlcnR5KHsgdHlwZTogY2MuTm9kZSB9KVxuICAgIHB1YmxpYyB0eHRQcm9ncmVzc1RpcHM6IGNjLk5vZGUgPSBudWxsO1xuXG4gICAgQHByb3BlcnR5KHsgdHlwZTogY2MuTm9kZSB9KVxuICAgIHB1YmxpYyBnUHJvZ3Jlc3M6IGNjLk5vZGUgPSBudWxsO1xuXG4gICAgQHByb3BlcnR5KHsgdHlwZTogY2MuTm9kZSB9KVxuICAgIHB1YmxpYyBpbWdSb2xlOiBjYy5Ob2RlID0gbnVsbDtcblxuICAgIEBwcm9wZXJ0eSh7IHR5cGU6IGNjLk5vZGUgfSlcbiAgICBwdWJsaWMgcHJvZ3Jlc3M6IGNjLk5vZGUgPSBudWxsO1xuXG4gICAgQHByb3BlcnR5KHsgdHlwZTogY2MuU3ByaXRlIH0pXG4gICAgcHVibGljIHByb2dyZXNzQmFyOiBjYy5TcHJpdGUgPSBudWxsO1xuXG4gICAgQHByb3BlcnR5KHsgdHlwZTogY2MuQXNzZXQgfSlcbiAgICBwdWJsaWMgbWFuaWZlc3RVcmw6IGNjLkFzc2V0ID0gbnVsbDtcblxuICAgIF9hbTogYW55O1xuICAgIF9jaGVja0xpc3RlbmVyOiBudWxsO1xuICAgIF91cGRhdGluZzogYm9vbGVhbjtcbiAgICBfdXBkYXRlTGlzdGVuZXI6IG51bGw7XG4gICAgX2NhblJldHJ5OiBib29sZWFuO1xuICAgIF9mYWlsQ291bnQ6IG51bWJlcjtcbiAgICBfc3RvcmFnZVBhdGg6IHN0cmluZztcbiAgICB2ZXJzaW9uQ29tcGFyZUhhbmRsZTogKHZlcnNpb25BOiBhbnksIHZlcnNpb25COiBhbnkpID0+IG51bWJlcjtcbiAgICBwcml2YXRlIF9jYW5FbnRlckdhbWU6IGJvb2xlYW47XG5cbiAgICBwdWJsaWMgY2hlY2tDYihldmVudDogYW55KSB7XG4gICAgICAgIC8vIGNjLmxvZygnQ29kZTogJyArIGV2ZW50LmdldEV2ZW50Q29kZSgpKTtcbiAgICAgICAgbGV0IGlzTmV3VmVyc2lvbiA9IGZhbHNlO1xuICAgICAgICBzd2l0Y2ggKGV2ZW50LmdldEV2ZW50Q29kZSgpKSB7XG4gICAgICAgICAgICBjYXNlIGpzYi5FdmVudEFzc2V0c01hbmFnZXIuRVJST1JfTk9fTE9DQUxfTUFOSUZFU1Q6XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJObyBsb2NhbCBtYW5pZmVzdCBmaWxlIGZvdW5kLCBob3QgdXBkYXRlIHNraXBwZWQuXCIpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLkVSUk9SX0RPV05MT0FEX01BTklGRVNUOlxuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLkVSUk9SX1BBUlNFX01BTklGRVNUOlxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiRmFpbCB0byBkb3dubG9hZCBtYW5pZmVzdCBmaWxlLCBob3QgdXBkYXRlIHNraXBwZWQuXCIpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLkFMUkVBRFlfVVBfVE9fREFURTpcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkFscmVhZHkgdXAgdG8gZGF0ZSB3aXRoIHRoZSBsYXRlc3QgcmVtb3RlIHZlcnNpb24uXCIpO1xuICAgICAgICAgICAgICAgIHRoaXMuRW50ZXJHYW1lKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGpzYi5FdmVudEFzc2V0c01hbmFnZXIuTkVXX1ZFUlNJT05fRk9VTkQ6XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJOZXcgdmVyc2lvbiBmb3VuZCwgcGxlYXNlIHRyeSB0byB1cGRhdGUuKFwiICsgdGhpcy5fYW0uZ2V0VG90YWxCeXRlcygpICsgJyknKTtcbiAgICAgICAgICAgICAgICBpc05ld1ZlcnNpb24gPSB0cnVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9hbS5zZXRFdmVudENhbGxiYWNrKG51bGwpO1xuICAgICAgICB0aGlzLl9jaGVja0xpc3RlbmVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5fdXBkYXRpbmcgPSBmYWxzZTtcbiAgICAgICAgaWYgKGlzTmV3VmVyc2lvbikge1xuICAgICAgICAgICAgLy/mnInmlrDniYjmnKzvvIzmmL7npLrov5vluqZcbiAgICAgICAgICAgIHRoaXMuc2V0UHJvZ3Jlc3MoMClcbiAgICAgICAgICAgIHRoaXMuaG90VXBkYXRlKCk7XG4gICAgICAgICAgICAvLzXnp5LlkI7liKTmlq3mmK/lkKblvIDlp4vkuIvovb3vvIzlpoLmnpzov5vluqbkuLowLuebtOaOpei/m+a4uOaIj++8jOmYsuatouWNoeatu1xuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZU9uY2UoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb2dyZXNzQmFyLmZpbGxSYW5nZSA9PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuRW50ZXJHYW1lKClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAxMClcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldFByb2dyZXNzKHZhbDogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMuZ1Byb2dyZXNzLmFjdGl2ZSA9IHRydWVcbiAgICAgICAgdGhpcy5wcm9ncmVzc0Jhci5maWxsUmFuZ2UgPSB2YWxcbiAgICAgICAgdGhpcy5pbWdSb2xlLnggPSAtdGhpcy5wcm9ncmVzcy53aWR0aCAvIDIgKyB2YWwgKiB0aGlzLnByb2dyZXNzLndpZHRoXG4gICAgICAgIHRoaXMudHh0UHJvZ3Jlc3MuZ2V0Q29tcG9uZW50KGNjLkxhYmVsKS5zdHJpbmcgPSBNYXRoLmZsb29yKHZhbCAqIDEwMCkgKyBcIiVcIlxuICAgICAgICB0aGlzLnR4dFByb2dyZXNzVGlwcy5nZXRDb21wb25lbnQoY2MuTGFiZWwpLnN0cmluZyA9IFwi6LWE5rqQ5pu05paw5LitXCJcbiAgICB9XG5cbiAgICBwdWJsaWMgdXBkYXRlQ2IoZXZlbnQ6IGFueSkge1xuICAgICAgICB2YXIgbmVlZFJlc3RhcnQgPSBmYWxzZTtcbiAgICAgICAgdmFyIGZhaWxlZCA9IGZhbHNlO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhcInVwZGF0ZUNiIGV2ZW50OlwiK0pTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG4gICAgICAgIHN3aXRjaCAoZXZlbnQuZ2V0RXZlbnRDb2RlKCkpIHtcbiAgICAgICAgICAgIGNhc2UganNiLkV2ZW50QXNzZXRzTWFuYWdlci5FUlJPUl9OT19MT0NBTF9NQU5JRkVTVDpcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnTm8gbG9jYWwgbWFuaWZlc3QgZmlsZSBmb3VuZCwgaG90IHVwZGF0ZSBza2lwcGVkLicpO1xuICAgICAgICAgICAgICAgIGZhaWxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGpzYi5FdmVudEFzc2V0c01hbmFnZXIuVVBEQVRFX1BST0dSRVNTSU9OOlxuICAgICAgICAgICAgICAgIC8vIHRoaXMucGFuZWwuYnl0ZVByb2dyZXNzLnByb2dyZXNzID0gZXZlbnQuZ2V0UGVyY2VudCgpO1xuICAgICAgICAgICAgICAgIC8vIHRoaXMucGFuZWwuZmlsZVByb2dyZXNzLnByb2dyZXNzID0gZXZlbnQuZ2V0UGVyY2VudEJ5RmlsZSgpO1xuXG4gICAgICAgICAgICAgICAgLy8gdGhpcy5wYW5lbC5maWxlTGFiZWwuc3RyaW5nID0gZXZlbnQuZ2V0RG93bmxvYWRlZEZpbGVzKCkgKyAnIC8gJyArIGV2ZW50LmdldFRvdGFsRmlsZXMoKTtcbiAgICAgICAgICAgICAgICAvLyB0aGlzLnBhbmVsLmJ5dGVMYWJlbC5zdHJpbmcgPSBldmVudC5nZXREb3dubG9hZGVkQnl0ZXMoKSArICcgLyAnICsgZXZlbnQuZ2V0VG90YWxCeXRlcygpO1xuXG4gICAgICAgICAgICAgICAgLy8gdGhpcy5wYl9ob3RVcGRhdGUucHJvZ3Jlc3MgPSAgZXZlbnQuZ2V0UGVyY2VudCgpO1xuICAgICAgICAgICAgICAgIC8vIHRoaXMubGJfcHJvZ3Jlc3Muc3RyaW5nID0gTWF0aC5mbG9vcihldmVudC5nZXRQZXJjZW50KCkqMTAwKS50b0ZpeGVkKDIpICsgJyUnO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0UHJvZ3Jlc3MoZXZlbnQuZ2V0UGVyY2VudCgpKVxuICAgICAgICAgICAgICAgIC8vIHZhciBtc2cgPSBldmVudC5nZXRNZXNzYWdlKCk7XG4gICAgICAgICAgICAgICAgLy8gaWYgKG1zZykge1xuICAgICAgICAgICAgICAgIC8vICAgICBjYy5sb2coZXZlbnQuZ2V0UGVyY2VudCgpLzEwMCArICclIDogJyArIG1zZyk7XG4gICAgICAgICAgICAgICAgLy8gfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLkVSUk9SX0RPV05MT0FEX01BTklGRVNUOlxuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLkVSUk9SX1BBUlNFX01BTklGRVNUOlxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdGYWlsIHRvIGRvd25sb2FkIG1hbmlmZXN0IGZpbGUsIGhvdCB1cGRhdGUgc2tpcHBlZC4nKTtcbiAgICAgICAgICAgICAgICBmYWlsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLkFMUkVBRFlfVVBfVE9fREFURTpcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnQWxyZWFkeSB1cCB0byBkYXRlIHdpdGggdGhlIGxhdGVzdCByZW1vdGUgdmVyc2lvbi4nKTtcbiAgICAgICAgICAgICAgICBmYWlsZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLlVQREFURV9GSU5JU0hFRDpcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnVXBkYXRlIGZpbmlzaGVkLiAnICsgZXZlbnQuZ2V0TWVzc2FnZSgpKTtcbiAgICAgICAgICAgICAgICBuZWVkUmVzdGFydCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGpzYi5FdmVudEFzc2V0c01hbmFnZXIuVVBEQVRFX0ZBSUxFRDpcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnVXBkYXRlIGZhaWxlZC4gJyArIGV2ZW50LmdldE1lc3NhZ2UoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIGpzYi5FdmVudEFzc2V0c01hbmFnZXIuRVJST1JfVVBEQVRJTkc6XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ0Fzc2V0IHVwZGF0ZSBlcnJvcjogJyArIGV2ZW50LmdldEFzc2V0SWQoKSArICcsICcgKyBldmVudC5nZXRNZXNzYWdlKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBqc2IuRXZlbnRBc3NldHNNYW5hZ2VyLkVSUk9SX0RFQ09NUFJFU1M6XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJFUlJPUl9ERUNPTVBSRVNTOlwiK2V2ZW50LmdldE1lc3NhZ2UoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZhaWxlZCkge1xuICAgICAgICAgICAgdGhpcy5fYW0uc2V0RXZlbnRDYWxsYmFjayhudWxsKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0ZUxpc3RlbmVyID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0aW5nID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLkVudGVyR2FtZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5lZWRSZXN0YXJ0KSB7XG4gICAgICAgICAgICB0aGlzLl9hbS5zZXRFdmVudENhbGxiYWNrKG51bGwpO1xuICAgICAgICAgICAgdGhpcy5fdXBkYXRlTGlzdGVuZXIgPSBudWxsO1xuICAgICAgICAgICAgLy8gUHJlcGVuZCB0aGUgbWFuaWZlc3QncyBzZWFyY2ggcGF0aFxuICAgICAgICAgICAgdmFyIHNlYXJjaFBhdGhzID0ganNiLmZpbGVVdGlscy5nZXRTZWFyY2hQYXRocygpO1xuICAgICAgICAgICAgdmFyIG5ld1BhdGhzID0gdGhpcy5fYW0uZ2V0TG9jYWxNYW5pZmVzdCgpLmdldFNlYXJjaFBhdGhzKCk7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShuZXdQYXRocykpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuZXdQYXRocy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChzZWFyY2hQYXRocy5pbmRleE9mKG5ld1BhdGhzW2ldKSA9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBBcnJheS5wcm90b3R5cGUudW5zaGlmdC5hcHBseShzZWFyY2hQYXRocywgW25ld1BhdGhzW2ldXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gVGhpcyB2YWx1ZSB3aWxsIGJlIHJldHJpZXZlZCBhbmQgYXBwZW5kZWQgdG8gdGhlIGRlZmF1bHQgc2VhcmNoIHBhdGggZHVyaW5nIGdhbWUgc3RhcnR1cCxcbiAgICAgICAgICAgIC8vIHBsZWFzZSByZWZlciB0byBzYW1wbGVzL2pzLXRlc3RzL21haW4uanMgZm9yIGRldGFpbGVkIHVzYWdlLlxuICAgICAgICAgICAgLy8gISEhIFJlLWFkZCB0aGUgc2VhcmNoIHBhdGhzIGluIG1haW4uanMgaXMgdmVyeSBpbXBvcnRhbnQsIG90aGVyd2lzZSwgbmV3IHNjcmlwdHMgd29uJ3QgdGFrZSBlZmZlY3QuXG4gICAgICAgICAgICBjYy5zeXMubG9jYWxTdG9yYWdlLnNldEl0ZW0oJ0hvdFVwZGF0ZVNlYXJjaFBhdGhzJywgSlNPTi5zdHJpbmdpZnkoc2VhcmNoUGF0aHMpKTtcbiAgICAgICAgICAgIGpzYi5maWxlVXRpbHMuc2V0U2VhcmNoUGF0aHMoc2VhcmNoUGF0aHMpO1xuXG4gICAgICAgICAgICBjYy5hdWRpb0VuZ2luZS5zdG9wQWxsKCk7XG4gICAgICAgICAgICBjYy5nYW1lLnJlc3RhcnQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyByZXRyeSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl91cGRhdGluZyAmJiB0aGlzLl9jYW5SZXRyeSkge1xuICAgICAgICAgICAgdGhpcy5fY2FuUmV0cnkgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ1JldHJ5IGZhaWxlZCBBc3NldHMuLi4nKTtcbiAgICAgICAgICAgIHRoaXMuX2FtLmRvd25sb2FkRmFpbGVkQXNzZXRzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY2hlY2tVcGRhdGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl91cGRhdGluZykge1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ0NoZWNraW5nIG9yIHVwZGF0aW5nIC4uLicpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9hbS5nZXRTdGF0ZSgpID09PSBqc2IuQXNzZXRzTWFuYWdlci5TdGF0ZS5VTklOSVRFRCkge1xuICAgICAgICAgICAgLy8gUmVzb2x2ZSBtZDUgdXJsXG4gICAgICAgICAgICB2YXIgdXJsID0gdGhpcy5tYW5pZmVzdFVybC5uYXRpdmVVcmw7XG4gICAgICAgICAgICBpZiAoY2MubG9hZGVyLm1kNVBpcGUpIHtcbiAgICAgICAgICAgICAgICB1cmwgPSBjYy5sb2FkZXIubWQ1UGlwZS50cmFuc2Zvcm1VUkwodXJsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2FtLmxvYWRMb2NhbE1hbmlmZXN0KHVybCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLl9hbS5nZXRMb2NhbE1hbmlmZXN0KCkgfHwgIXRoaXMuX2FtLmdldExvY2FsTWFuaWZlc3QoKS5pc0xvYWRlZCgpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnRmFpbGVkIHRvIGxvYWQgbG9jYWwgbWFuaWZlc3QgLi4uJyk7XG4gICAgICAgICAgICB0aGlzLkVudGVyR2FtZSgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZ2V0TG9jYWxWZXJzaW9uKClcbiAgICAgICAgdGhpcy5fYW0uc2V0RXZlbnRDYWxsYmFjayh0aGlzLmNoZWNrQ2IuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgdGhpcy5fYW0uY2hlY2tVcGRhdGUoKTtcbiAgICAgICAgdGhpcy5fdXBkYXRpbmcgPSB0cnVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBob3RVcGRhdGUoKSB7XG4gICAgICAgIGlmICh0aGlzLl9hbSAmJiAhdGhpcy5fdXBkYXRpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuX2FtLnNldEV2ZW50Q2FsbGJhY2sodGhpcy51cGRhdGVDYi5iaW5kKHRoaXMpKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuX2FtLmdldFN0YXRlKCkgPT09IGpzYi5Bc3NldHNNYW5hZ2VyLlN0YXRlLlVOSU5JVEVEKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSBtZDUgdXJsXG4gICAgICAgICAgICAgICAgdmFyIHVybCA9IHRoaXMubWFuaWZlc3RVcmwubmF0aXZlVXJsO1xuICAgICAgICAgICAgICAgIGlmIChjYy5sb2FkZXIubWQ1UGlwZSkge1xuICAgICAgICAgICAgICAgICAgICB1cmwgPSBjYy5sb2FkZXIubWQ1UGlwZS50cmFuc2Zvcm1VUkwodXJsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fYW0ubG9hZExvY2FsTWFuaWZlc3QodXJsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2ZhaWxDb3VudCA9IDA7XG4gICAgICAgICAgICB0aGlzLl9hbS51cGRhdGUoKTtcbiAgICAgICAgICAgIHRoaXMuX3VwZGF0aW5nID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIHVzZSB0aGlzIGZvciBpbml0aWFsaXphdGlvblxuICAgIG9uTG9hZCgpIHtcbiAgICAgICAgLy8gSG90IHVwZGF0ZSBpcyBvbmx5IGF2YWlsYWJsZSBpbiBOYXRpdmUgYnVpbGRcbiAgICAgICAgaWYgKCFjYy5zeXMuaXNOYXRpdmUpIHtcbiAgICAgICAgICAgIC8vIHRoaXMuRW50ZXJHYW1lKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3RvcmFnZVBhdGggPSAoKGpzYi5maWxlVXRpbHMgPyBqc2IuZmlsZVV0aWxzLmdldFdyaXRhYmxlUGF0aCgpIDogJy8nKSArICdibGFja2phY2stcmVtb3RlLWFzc2V0Jyk7XG4gICAgICAgIGNjLmxvZygnU3RvcmFnZSBwYXRoIGZvciByZW1vdGUgYXNzZXQgOiAnICsgdGhpcy5fc3RvcmFnZVBhdGgpO1xuXG5cbiAgICAgICAgLy8gU2V0dXAgeW91ciBvd24gdmVyc2lvbiBjb21wYXJlIGhhbmRsZXIsIHZlcnNpb25BIGFuZCBCIGlzIHZlcnNpb25zIGluIHN0cmluZ1xuICAgICAgICAvLyBpZiB0aGUgcmV0dXJuIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLCB2ZXJzaW9uQSBpcyBncmVhdGVyIHRoYW4gQixcbiAgICAgICAgLy8gaWYgdGhlIHJldHVybiB2YWx1ZSBlcXVhbHMgMCwgdmVyc2lvbkEgZXF1YWxzIHRvIEIsXG4gICAgICAgIC8vIGlmIHRoZSByZXR1cm4gdmFsdWUgc21hbGxlciB0aGFuIDAsIHZlcnNpb25BIGlzIHNtYWxsZXIgdGhhbiBCLlxuICAgICAgICB0aGlzLnZlcnNpb25Db21wYXJlSGFuZGxlID0gZnVuY3Rpb24gKHZlcnNpb25BLCB2ZXJzaW9uQikge1xuICAgICAgICAgICAgY2MubG9nKFwiSlMgQ3VzdG9tIFZlcnNpb24gQ29tcGFyZTogdmVyc2lvbiBBIGlzIFwiICsgdmVyc2lvbkEgKyAnLCB2ZXJzaW9uIEIgaXMgJyArIHZlcnNpb25CKTtcbiAgICAgICAgICAgIHZhciB2QSA9IHZlcnNpb25BLnNwbGl0KCcuJyk7XG4gICAgICAgICAgICB2YXIgdkIgPSB2ZXJzaW9uQi5zcGxpdCgnLicpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2QS5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgIHZhciBhID0gcGFyc2VJbnQodkFbaV0pO1xuICAgICAgICAgICAgICAgIHZhciBiID0gcGFyc2VJbnQodkJbaV0gfHwgMCk7XG4gICAgICAgICAgICAgICAgaWYgKGEgPT09IGIpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYSAtIGI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHZCLmxlbmd0aCA+IHZBLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEluaXQgd2l0aCBlbXB0eSBtYW5pZmVzdCB1cmwgZm9yIHRlc3RpbmcgY3VzdG9tIG1hbmlmZXN0XG4gICAgICAgIHRoaXMuX2FtID0gbmV3IGpzYi5Bc3NldHNNYW5hZ2VyKCcnLCB0aGlzLl9zdG9yYWdlUGF0aCwgdGhpcy52ZXJzaW9uQ29tcGFyZUhhbmRsZSk7XG5cbiAgICAgICAgLy8gU2V0dXAgdGhlIHZlcmlmaWNhdGlvbiBjYWxsYmFjaywgYnV0IHdlIGRvbid0IGhhdmUgbWQ1IGNoZWNrIGZ1bmN0aW9uIHlldCwgc28gb25seSBwcmludCBzb21lIG1lc3NhZ2VcbiAgICAgICAgLy8gUmV0dXJuIHRydWUgaWYgdGhlIHZlcmlmaWNhdGlvbiBwYXNzZWQsIG90aGVyd2lzZSByZXR1cm4gZmFsc2VcbiAgICAgICAgdGhpcy5fYW0uc2V0VmVyaWZ5Q2FsbGJhY2soZnVuY3Rpb24gKHBhdGgsIGFzc2V0KSB7XG4gICAgICAgICAgICAvLyBXaGVuIGFzc2V0IGlzIGNvbXByZXNzZWQsIHdlIGRvbid0IG5lZWQgdG8gY2hlY2sgaXRzIG1kNSwgYmVjYXVzZSB6aXAgZmlsZSBoYXZlIGJlZW4gZGVsZXRlZC5cbiAgICAgICAgICAgIHZhciBjb21wcmVzc2VkID0gYXNzZXQuY29tcHJlc3NlZDtcbiAgICAgICAgICAgIC8vIFJldHJpZXZlIHRoZSBjb3JyZWN0IG1kNSB2YWx1ZS5cbiAgICAgICAgICAgIHZhciBleHBlY3RlZE1ENSA9IGFzc2V0Lm1kNTtcbiAgICAgICAgICAgIC8vIGFzc2V0LnBhdGggaXMgcmVsYXRpdmUgcGF0aCBhbmQgcGF0aCBpcyBhYnNvbHV0ZS5cbiAgICAgICAgICAgIHZhciByZWxhdGl2ZVBhdGggPSBhc3NldC5wYXRoO1xuICAgICAgICAgICAgLy8gVGhlIHNpemUgb2YgYXNzZXQgZmlsZSwgYnV0IHRoaXMgdmFsdWUgY291bGQgYmUgYWJzZW50LlxuICAgICAgICAgICAgdmFyIHNpemUgPSBhc3NldC5zaXplO1xuICAgICAgICAgICAgaWYgKGNvbXByZXNzZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlZlcmlmaWNhdGlvbiBwYXNzZWQgOiBcIiArIHJlbGF0aXZlUGF0aCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlZlcmlmaWNhdGlvbiBwYXNzZWQgOiBcIiArIHJlbGF0aXZlUGF0aCArICcgKCcgKyBleHBlY3RlZE1ENSArICcpJyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIC8vIGNvbnNvbGUubG9nKCdIb3QgdXBkYXRlIGlzIHJlYWR5LCBwbGVhc2UgY2hlY2sgb3IgZGlyZWN0bHkgdXBkYXRlLicpO1xuXG4gICAgICAgIGlmIChjYy5zeXMub3MgPT09IGNjLnN5cy5PU19BTkRST0lEKSB7XG4gICAgICAgICAgICAvLyBTb21lIEFuZHJvaWQgZGV2aWNlIG1heSBzbG93IGRvd24gdGhlIGRvd25sb2FkIHByb2Nlc3Mgd2hlbiBjb25jdXJyZW50IHRhc2tzIGlzIHRvbyBtdWNoLlxuICAgICAgICAgICAgLy8gVGhlIHZhbHVlIG1heSBub3QgYmUgYWNjdXJhdGUsIHBsZWFzZSBkbyBtb3JlIHRlc3QgYW5kIGZpbmQgd2hhdCdzIG1vc3Qgc3VpdGFibGUgZm9yIHlvdXIgZ2FtZS5cbiAgICAgICAgICAgIHRoaXMuX2FtLnNldE1heENvbmN1cnJlbnRUYXNrKDIpO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJNYXggY29uY3VycmVudCB0YXNrcyBjb3VudCBoYXZlIGJlZW4gbGltaXRlZCB0byAyXCIpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNjLmxvYWRlci5sb2FkUmVzKCcvcHJvamVjdC5tYW5pZmVzdCcsKGVycixvYmopPT57XG4gICAgICAgIC8vICAgICBpZiAoIWVycikge1xuICAgICAgICAvLyAgICAgICAgIC8vIGxldCBjdXN0b21NYW5pZmVzdFN0ciA9IEpTT04uc3RyaW5naWZ5KG9iaik7XG4gICAgICAgIC8vICAgICAgICAgbGV0IF9uYXRpdmVBc3NldCA9IEpTT04ucGFyc2Uob2JqLl9uYXRpdmVBc3NldCk7XG4gICAgICAgIC8vICAgICAgICAgdmFyIGN1c3RvbU1hbmlmZXN0U3RyID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAvLyAgICAgICAgICAgICAncGFja2FnZVVybCc6IF9uYXRpdmVBc3NldC5wYWNrYWdlVXJsLFxuICAgICAgICAvLyAgICAgICAgICAgICAncmVtb3RlTWFuaWZlc3RVcmwnOiBfbmF0aXZlQXNzZXQucmVtb3RlTWFuaWZlc3RVcmwsXG4gICAgICAgIC8vICAgICAgICAgICAgICdyZW1vdGVWZXJzaW9uVXJsJzogX25hdGl2ZUFzc2V0LnJlbW90ZU1hbmlmZXN0VXJsLFxuICAgICAgICAvLyAgICAgICAgICAgICAndmVyc2lvbic6IF9uYXRpdmVBc3NldC52ZXJzaW9uLFxuICAgICAgICAvLyAgICAgICAgICAgICAnYXNzZXRzJzogX25hdGl2ZUFzc2V0LmFzc2VydCxcbiAgICAgICAgLy8gICAgICAgICAgICAgJ3NlYXJjaFBhdGhzJzogX25hdGl2ZUFzc2V0LnNlYXJjaFBhdGhzXG4gICAgICAgIC8vICAgICAgICAgfSk7XG4gICAgICAgIC8vICAgICAgICAgaWYgKHRoaXMuX2FtLmdldFN0YXRlKCkgPT09IGpzYi5Bc3NldHNNYW5hZ2VyLlN0YXRlLlVOSU5JVEVEKSB7XG4gICAgICAgIC8vICAgICAgICAgICAgIHZhciBtYW5pZmVzdCA9IG5ldyBqc2IuTWFuaWZlc3QoY3VzdG9tTWFuaWZlc3RTdHIsIHRoaXMuX3N0b3JhZ2VQYXRoKTtcbiAgICAgICAgLy8gICAgICAgICAgICAgdGhpcy5fYW0ubG9hZExvY2FsTWFuaWZlc3QobWFuaWZlc3QsIHRoaXMuX3N0b3JhZ2VQYXRoKTtcbiAgICAgICAgLy8gICAgICAgICB9XG4gICAgICAgIC8vICAgICB9XG4gICAgICAgIC8vIH0pO1xuICAgICAgICAvL+W8gOWni+ajgOa1i+abtOaWsFxuICAgICAgICAvLyB0aGlzLmNoZWNrVXBkYXRlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIEVudGVyR2FtZSgpIHtcbiAgICAgICAgLy8g5ri45oiP5Yid5aeL5YyWXG4gICAgICAgIHRoaXMuZ2V0TG9jYWxWZXJzaW9uKCk7XG4gICAgICAgIHRoaXMuc2NoZWR1bGVPbmNlKCgpID0+IHtcbiAgICAgICAgICAgIGNjLmRpcmVjdG9yLmxvYWRTY2VuZShcImxvYWRpbmdcIilcbiAgICAgICAgfSwgNClcbiAgICAgICAgdGhpcy5fY2FuRW50ZXJHYW1lID0gdHJ1ZVxuICAgIH1cblxuICAgIC8v6I635Y+W5pys5Zyw54mI5pysXG4gICAgcHVibGljIGdldExvY2FsVmVyc2lvbigpIHtcbiAgICAgICAgbGV0IGxvY2FsVmVyc2lvbiA9ICcnO1xuICAgICAgICBpZiAodGhpcy5fYW0gJiYgdGhpcy5fYW0uZ2V0TG9jYWxNYW5pZmVzdCgpICYmICF0aGlzLl91cGRhdGluZykge1xuICAgICAgICAgICAgbG9jYWxWZXJzaW9uID0gdGhpcy5fYW0uZ2V0TG9jYWxNYW5pZmVzdCgpLmdldFZlcnNpb24oKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiY3VyVmVyc2lvbjE6XCIgKyBsb2NhbFZlcnNpb24pO1xuICAgICAgICAgICAgaW1wb3J0KFwiQ29uZmlnXCIgYXMgYW55KS50aGVuKChjZmdQYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBjb25maWcgPSBjZmdQYXJhbS5kZWZhdWx0XG4gICAgICAgICAgICAgICAgY29uZmlnLmFwcFZlcnNpb24gPSBsb2NhbFZlcnNpb25cbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcImN1clZlcnNpb24yOlwiICsgbG9jYWxWZXJzaW9uKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcImN1clZlcnNpb246XCIrbG9jYWxWZXJzaW9uKTtcbiAgICAgICAgfVxuICAgICAgICAvL3JldHVybiBsb2NhbFZlcnNpb247XG4gICAgfVxuXG4gICAgb25EZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5fdXBkYXRlTGlzdGVuZXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2FtLnNldEV2ZW50Q2FsbGJhY2sobnVsbCk7XG4gICAgICAgICAgICB0aGlzLl91cGRhdGVMaXN0ZW5lciA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG59O1xuIl19
|