UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

137 lines 21.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const read_file_relative_1 = require("read-file-relative"); const http_1 = require("../../utils/http"); const remotes_queue_1 = __importDefault(require("./remotes-queue")); // Const const IDLE_PAGE_SCRIPT = read_file_relative_1.readSync('../../client/browser/idle-page/index.js'); const IDLE_PAGE_STYLE = read_file_relative_1.readSync('../../client/browser/idle-page/styles.css'); const IDLE_PAGE_LOGO = read_file_relative_1.readSync('../../client/browser/idle-page/logo.svg', true); // Gateway class BrowserConnectionGateway { constructor(proxy, options = {}) { this.connections = {}; this.remotesQueue = new remotes_queue_1.default(); this.domain = proxy.server1Info.domain; this.connectUrl = `${this.domain}/browser/connect`; this.retryTestPages = options.retryTestPages; this._registerRoutes(proxy); } _dispatch(url, proxy, handler, method = 'GET') { proxy[method](url, (req, res, si, params) => { const connection = this.connections[params.id]; http_1.preventCaching(res); if (connection) handler(req, res, connection); else http_1.respond404(res); }); } _registerRoutes(proxy) { this._dispatch('/browser/connect/{id}', proxy, BrowserConnectionGateway.onConnection); this._dispatch('/browser/heartbeat/{id}', proxy, BrowserConnectionGateway.onHeartbeat); this._dispatch('/browser/idle/{id}', proxy, BrowserConnectionGateway.onIdle); this._dispatch('/browser/idle-forced/{id}', proxy, BrowserConnectionGateway.onIdleForced); this._dispatch('/browser/status/{id}', proxy, BrowserConnectionGateway.onStatusRequest); this._dispatch('/browser/status-done/{id}', proxy, BrowserConnectionGateway.onStatusRequestOnTestDone); this._dispatch('/browser/init-script/{id}', proxy, BrowserConnectionGateway.onInitScriptRequest); this._dispatch('/browser/init-script/{id}', proxy, BrowserConnectionGateway.onInitScriptResponse, 'POST'); proxy.GET('/browser/connect', (req, res) => this._connectNextRemoteBrowser(req, res)); proxy.GET('/browser/connect/', (req, res) => this._connectNextRemoteBrowser(req, res)); proxy.GET('/browser/assets/index.js', { content: IDLE_PAGE_SCRIPT, contentType: 'application/x-javascript' }); proxy.GET('/browser/assets/styles.css', { content: IDLE_PAGE_STYLE, contentType: 'text/css' }); proxy.GET('/browser/assets/logo.svg', { content: IDLE_PAGE_LOGO, contentType: 'image/svg+xml' }); } // Helpers static ensureConnectionReady(res, connection) { if (!connection.ready) { http_1.respond500(res, 'The connection is not ready yet.'); return false; } return true; } // Route handlers static onConnection(req, res, connection) { if (connection.ready) http_1.respond500(res, 'The connection is already established.'); else { const userAgent = req.headers['user-agent']; connection.establish(userAgent); http_1.redirect(res, connection.idleUrl); } } static onHeartbeat(req, res, connection) { if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { const status = connection.heartbeat(); http_1.respondWithJSON(res, status); } } static onIdle(req, res, connection) { if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) res.end(connection.renderIdlePage()); } static async onIdleForced(req, res, connection) { if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { const status = await connection.getStatus(true); http_1.redirect(res, status.url); } } static async onStatusRequest(req, res, connection) { return BrowserConnectionGateway._onStatusRequestCore(req, res, connection, false); } static async onStatusRequestOnTestDone(req, res, connection) { return BrowserConnectionGateway._onStatusRequestCore(req, res, connection, true); } static async _onStatusRequestCore(req, res, connection, isTestDone) { if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { const status = await connection.getStatus(isTestDone); http_1.respondWithJSON(res, status); } } static onInitScriptRequest(req, res, connection) { if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { const script = connection.getInitScript(); http_1.respondWithJSON(res, script); } } static onInitScriptResponse(req, res, connection) { if (BrowserConnectionGateway.ensureConnectionReady(res, connection)) { let data = ''; req.on('data', chunk => { data += chunk; }); req.on('end', () => { connection.handleInitScriptResult(data); res.end(); }); } } async _connectNextRemoteBrowser(req, res) { http_1.preventCaching(res); const remoteConnection = await this.remotesQueue.shift(); if (remoteConnection) http_1.redirect(res, remoteConnection.url); else http_1.respond500(res, 'There are no available connections to establish.'); } // API startServingConnection(connection) { this.connections[connection.id] = connection; if (connection.browserInfo.providerName === 'remote') this.remotesQueue.add(connection); } stopServingConnection(connection) { delete this.connections[connection.id]; if (connection.browserInfo.providerName === 'remote') this.remotesQueue.remove(connection); } close() { Object.keys(this.connections).forEach(id => this.connections[id].close()); } } exports.default = BrowserConnectionGateway; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0ZXdheS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL2Nvbm5lY3Rpb24vZ2F0ZXdheS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDJEQUFzRDtBQUN0RCwyQ0FBcUc7QUFDckcsb0VBQTJDO0FBRzNDLFFBQVE7QUFDUixNQUFNLGdCQUFnQixHQUFHLDZCQUFJLENBQUMseUNBQXlDLENBQUMsQ0FBQztBQUN6RSxNQUFNLGVBQWUsR0FBSSw2QkFBSSxDQUFDLDJDQUEyQyxDQUFDLENBQUM7QUFDM0UsTUFBTSxjQUFjLEdBQUssNkJBQUksQ0FBQyx5Q0FBeUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUUvRSxVQUFVO0FBQ1YsTUFBcUIsd0JBQXdCO0lBQ3pDLFlBQWEsS0FBSyxFQUFFLE9BQU8sR0FBRyxFQUFFO1FBQzVCLElBQUksQ0FBQyxXQUFXLEdBQUksRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSx1QkFBWSxFQUFFLENBQUM7UUFDdkMsSUFBSSxDQUFDLE1BQU0sR0FBUyxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQztRQUU3QyxJQUFJLENBQUMsVUFBVSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sa0JBQWtCLENBQUM7UUFFbkQsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDO1FBRTdDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVELFNBQVMsQ0FBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLEdBQUcsS0FBSztRQUMxQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDeEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENB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aW1wb3J0IHsgcmVhZFN5bmMgYXMgcmVhZCB9IGZyb20gJ3JlYWQtZmlsZS1yZWxhdGl2ZSc7XG5pbXBvcnQgeyByZXNwb25kNDA0LCByZXNwb25kNTAwLCByZXNwb25kV2l0aEpTT04sIHJlZGlyZWN0LCBwcmV2ZW50Q2FjaGluZyB9IGZyb20gJy4uLy4uL3V0aWxzL2h0dHAnO1xuaW1wb3J0IFJlbW90ZXNRdWV1ZSBmcm9tICcuL3JlbW90ZXMtcXVldWUnO1xuXG5cbi8vIENvbnN0XG5jb25zdCBJRExFX1BBR0VfU0NSSVBUID0gcmVhZCgnLi4vLi4vY2xpZW50L2Jyb3dzZXIvaWRsZS1wYWdlL2luZGV4LmpzJyk7XG5jb25zdCBJRExFX1BBR0VfU1RZTEUgID0gcmVhZCgnLi4vLi4vY2xpZW50L2Jyb3dzZXIvaWRsZS1wYWdlL3N0eWxlcy5jc3MnKTtcbmNvbnN0IElETEVfUEFHRV9MT0dPICAgPSByZWFkKCcuLi8uLi9jbGllbnQvYnJvd3Nlci9pZGxlLXBhZ2UvbG9nby5zdmcnLCB0cnVlKTtcblxuLy8gR2F0ZXdheVxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5IHtcbiAgICBjb25zdHJ1Y3RvciAocHJveHksIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb25zICA9IHt9O1xuICAgICAgICB0aGlzLnJlbW90ZXNRdWV1ZSA9IG5ldyBSZW1vdGVzUXVldWUoKTtcbiAgICAgICAgdGhpcy5kb21haW4gICAgICAgPSBwcm94eS5zZXJ2ZXIxSW5mby5kb21haW47XG5cbiAgICAgICAgdGhpcy5jb25uZWN0VXJsID0gYCR7dGhpcy5kb21haW59L2Jyb3dzZXIvY29ubmVjdGA7XG5cbiAgICAgICAgdGhpcy5yZXRyeVRlc3RQYWdlcyA9IG9wdGlvbnMucmV0cnlUZXN0UGFnZXM7XG5cbiAgICAgICAgdGhpcy5fcmVnaXN0ZXJSb3V0ZXMocHJveHkpO1xuICAgIH1cblxuICAgIF9kaXNwYXRjaCAodXJsLCBwcm94eSwgaGFuZGxlciwgbWV0aG9kID0gJ0dFVCcpIHtcbiAgICAgICAgcHJveHlbbWV0aG9kXSh1cmwsIChyZXEsIHJlcywgc2ksIHBhcmFtcykgPT4ge1xuICAgICAgICAgICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuY29ubmVjdGlvbnNbcGFyYW1zLmlkXTtcblxuICAgICAgICAgICAgcHJldmVudENhY2hpbmcocmVzKTtcblxuICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb24pXG4gICAgICAgICAgICAgICAgaGFuZGxlcihyZXEsIHJlcywgY29ubmVjdGlvbik7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgcmVzcG9uZDQwNChyZXMpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfcmVnaXN0ZXJSb3V0ZXMgKHByb3h5KSB7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9jb25uZWN0L3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Lm9uQ29ubmVjdGlvbik7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9oZWFydGJlYXQve2lkfScsIHByb3h5LCBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkub25IZWFydGJlYXQpO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgnL2Jyb3dzZXIvaWRsZS97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5vbklkbGUpO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgnL2Jyb3dzZXIvaWRsZS1mb3JjZWQve2lkfScsIHByb3h5LCBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkub25JZGxlRm9yY2VkKTtcbiAgICAgICAgdGhpcy5fZGlzcGF0Y2goJy9icm93c2VyL3N0YXR1cy97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5vblN0YXR1c1JlcXVlc3QpO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgnL2Jyb3dzZXIvc3RhdHVzLWRvbmUve2lkfScsIHByb3h5LCBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkub25TdGF0dXNSZXF1ZXN0T25UZXN0RG9uZSk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9pbml0LXNjcmlwdC97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5vbkluaXRTY3JpcHRSZXF1ZXN0KTtcbiAgICAgICAgdGhpcy5fZGlzcGF0Y2goJy9icm93c2VyL2luaXQtc2NyaXB0L3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Lm9uSW5pdFNjcmlwdFJlc3BvbnNlLCAnUE9TVCcpO1xuXG4gICAgICAgIHByb3h5LkdFVCgnL2Jyb3dzZXIvY29ubmVjdCcsIChyZXEsIHJlcykgPT4gdGhpcy5fY29ubmVjdE5leHRSZW1vdGVCcm93c2VyKHJlcSwgcmVzKSk7XG4gICAgICAgIHByb3h5LkdFVCgnL2Jyb3dzZXIvY29ubmVjdC8nLCAocmVxLCByZXMpID0+IHRoaXMuX2Nvbm5lY3ROZXh0UmVtb3RlQnJvd3NlcihyZXEsIHJlcykpO1xuXG4gICAgICAgIHByb3h5LkdFVCgnL2Jyb3dzZXIvYXNzZXRzL2luZGV4LmpzJywgeyBjb250ZW50OiBJRExFX1BBR0VfU0NSSVBULCBjb250ZW50VHlwZTogJ2FwcGxpY2F0aW9uL3gtamF2YXNjcmlwdCcgfSk7XG4gICAgICAgIHByb3h5LkdFVCgnL2Jyb3dzZXIvYXNzZXRzL3N0eWxlcy5jc3MnLCB7IGNvbnRlbnQ6IElETEVfUEFHRV9TVFlMRSwgY29udGVudFR5cGU6ICd0ZXh0L2NzcycgfSk7XG4gICAgICAgIHByb3h5LkdFVCgnL2Jyb3dzZXIvYXNzZXRzL2xvZ28uc3ZnJywgeyBjb250ZW50OiBJRExFX1BBR0VfTE9HTywgY29udGVudFR5cGU6ICdpbWFnZS9zdmcreG1sJyB9KTtcbiAgICB9XG5cbiAgICAvLyBIZWxwZXJzXG4gICAgc3RhdGljIGVuc3VyZUNvbm5lY3Rpb25SZWFkeSAocmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIGlmICghY29ubmVjdGlvbi5yZWFkeSkge1xuICAgICAgICAgICAgcmVzcG9uZDUwMChyZXMsICdUaGUgY29ubmVjdGlvbiBpcyBub3QgcmVhZHkgeWV0LicpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG5cbiAgICAvLyBSb3V0ZSBoYW5kbGVyc1xuICAgIHN0YXRpYyBvbkNvbm5lY3Rpb24gKHJlcSwgcmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIGlmIChjb25uZWN0aW9uLnJlYWR5KVxuICAgICAgICAgICAgcmVzcG9uZDUwMChyZXMsICdUaGUgY29ubmVjdGlvbiBpcyBhbHJlYWR5IGVzdGFibGlzaGVkLicpO1xuXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgdXNlckFnZW50ID0gcmVxLmhlYWRlcnNbJ3VzZXItYWdlbnQnXTtcblxuICAgICAgICAgICAgY29ubmVjdGlvbi5lc3RhYmxpc2godXNlckFnZW50KTtcbiAgICAgICAgICAgIHJlZGlyZWN0KHJlcywgY29ubmVjdGlvbi5pZGxlVXJsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBvbkhlYXJ0YmVhdCAocmVxLCByZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgY29uc3Qgc3RhdHVzID0gY29ubmVjdGlvbi5oZWFydGJlYXQoKTtcblxuICAgICAgICAgICAgcmVzcG9uZFdpdGhKU09OKHJlcywgc3RhdHVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBvbklkbGUgKHJlcSwgcmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIGlmIChCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuZW5zdXJlQ29ubmVjdGlvblJlYWR5KHJlcywgY29ubmVjdGlvbikpXG4gICAgICAgICAgICByZXMuZW5kKGNvbm5lY3Rpb24ucmVuZGVySWRsZVBhZ2UoKSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGFzeW5jIG9uSWRsZUZvcmNlZCAocmVxLCByZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgY29ubmVjdGlvbi5nZXRTdGF0dXModHJ1ZSk7XG5cbiAgICAgICAgICAgIHJlZGlyZWN0KHJlcywgc3RhdHVzLnVybCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgYXN5bmMgb25TdGF0dXNSZXF1ZXN0IChyZXEsIHJlcywgY29ubmVjdGlvbikge1xuICAgICAgICByZXR1cm4gQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9vblN0YXR1c1JlcXVlc3RDb3JlKHJlcSwgcmVzLCBjb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgc3RhdGljIGFzeW5jIG9uU3RhdHVzUmVxdWVzdE9uVGVzdERvbmUgKHJlcSwgcmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIHJldHVybiBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuX29uU3RhdHVzUmVxdWVzdENvcmUocmVxLCByZXMsIGNvbm5lY3Rpb24sIHRydWUpO1xuICAgIH1cblxuICAgIHN0YXRpYyBhc3luYyBfb25TdGF0dXNSZXF1ZXN0Q29yZSAocmVxLCByZXMsIGNvbm5lY3Rpb24sIGlzVGVzdERvbmUpIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgY29uc3Qgc3RhdHVzID0gYXdhaXQgY29ubmVjdGlvbi5nZXRTdGF0dXMoaXNUZXN0RG9uZSk7XG5cbiAgICAgICAgICAgIHJlc3BvbmRXaXRoSlNPTihyZXMsIHN0YXR1cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgb25Jbml0U2NyaXB0UmVxdWVzdCAocmVxLCByZXMsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgY29uc3Qgc2NyaXB0ID0gY29ubmVjdGlvbi5nZXRJbml0U2NyaXB0KCk7XG5cbiAgICAgICAgICAgIHJlc3BvbmRXaXRoSlNPTihyZXMsIHNjcmlwdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgb25Jbml0U2NyaXB0UmVzcG9uc2UgKHJlcSwgcmVzLCBjb25uZWN0aW9uKSB7XG4gICAgICAgIGlmIChCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuZW5zdXJlQ29ubmVjdGlvblJlYWR5KHJlcywgY29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgIGxldCBkYXRhID0gJyc7XG5cbiAgICAgICAgICAgIHJlcS5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgICAgICAgICAgICBkYXRhICs9IGNodW5rO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJlcS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaGFuZGxlSW5pdFNjcmlwdFJlc3VsdChkYXRhKTtcblxuICAgICAgICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgX2Nvbm5lY3ROZXh0UmVtb3RlQnJvd3NlciAocmVxLCByZXMpIHtcbiAgICAgICAgcHJldmVudENhY2hpbmcocmVzKTtcblxuICAgICAgICBjb25zdCByZW1vdGVDb25uZWN0aW9uID0gYXdhaXQgdGhpcy5yZW1vdGVzUXVldWUuc2hpZnQoKTtcblxuICAgICAgICBpZiAocmVtb3RlQ29ubmVjdGlvbilcbiAgICAgICAgICAgIHJlZGlyZWN0KHJlcywgcmVtb3RlQ29ubmVjdGlvbi51cmwpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXNwb25kNTAwKHJlcywgJ1RoZXJlIGFyZSBubyBhdmFpbGFibGUgY29ubmVjdGlvbnMgdG8gZXN0YWJsaXNoLicpO1xuICAgIH1cblxuICAgIC8vIEFQSVxuICAgIHN0YXJ0U2VydmluZ0Nvbm5lY3Rpb24gKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgdGhpcy5jb25uZWN0aW9uc1tjb25uZWN0aW9uLmlkXSA9IGNvbm5lY3Rpb247XG5cbiAgICAgICAgaWYgKGNvbm5lY3Rpb24uYnJvd3NlckluZm8ucHJvdmlkZXJOYW1lID09PSAncmVtb3RlJylcbiAgICAgICAgICAgIHRoaXMucmVtb3Rlc1F1ZXVlLmFkZChjb25uZWN0aW9uKTtcbiAgICB9XG5cbiAgICBzdG9wU2VydmluZ0Nvbm5lY3Rpb24gKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvbnNbY29ubmVjdGlvbi5pZF07XG5cbiAgICAgICAgaWYgKGNvbm5lY3Rpb24uYnJvd3NlckluZm8ucHJvdmlkZXJOYW1lID09PSAncmVtb3RlJylcbiAgICAgICAgICAgIHRoaXMucmVtb3Rlc1F1ZXVlLnJlbW92ZShjb25uZWN0aW9uKTtcbiAgICB9XG5cbiAgICBjbG9zZSAoKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuY29ubmVjdGlvbnMpLmZvckVhY2goaWQgPT4gdGhpcy5jb25uZWN0aW9uc1tpZF0uY2xvc2UoKSk7XG4gICAgfVxufVxuXG4iXX0=