UNPKG

@fly/edge

Version:
115 lines 14.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.githubPages = void 0; /** * @module Backends */ const proxy_1 = require("../proxy"); const util_1 = require("../util"); const errors = require("../errors"); /** * Creates a fetch-like proxy function for making requests to GitHub pages * hosted sites. * * Example: * * ```typescript * import { githubPages } from "./src/backends"; * const backend = githubPages({ * owner: "superfly", * repo: "edge", * hostname: "docs.fly.io" * }); * ``` * @param config The Github repository to proxy to * @module Backends */ function githubPages(options) { const config = _normalizeOptions(options); let ghFetch = buildGithubPagesProxy(config); let buildTime = 0; // first failure might need a retry const c = config; const fn = async function githubPagesFetch(req, init) { const original = ghFetch; if (typeof req === "string") { req = new Request(req, init); } console.debug("ghpages starting fetch:", req.url, buildTime); let resp = await ghFetch(req, init); console.debug("ghpages resp status:", resp.status); if (resp.status === 404 && ghFetch.proxyConfig.hostname) { // hostname might've been cleared const url = new URL(req.url); const diff = Date.now() - buildTime; if ((url.pathname === "/" && diff > 10000) // retry after 10s for root || diff > 30000) { // wait 5min for everything else console.debug("ghpages hostname request got 404:", c.hostname); c.hostname = undefined; ghFetch = buildGithubPagesProxy(c); } } if (resp.status === 301 && !ghFetch.proxyConfig.hostname) { // 301s happen when you request <org>.github.io/<repo> and need a custom domain let location = resp.headers.get("location"); if (location) { const url = new URL(location); c.hostname = url.hostname; ghFetch = buildGithubPagesProxy(c); console.debug("ghpages found hostname:", c); } } if (original !== ghFetch) { // underlying proxy function changed, store it and retry console.debug("ghpages got a new fetch fn"); self.proxyConfig = ghFetch.proxyConfig; resp = await ghFetch(req, init); } return resp; }; let self = Object.assign(fn, { proxyConfig: ghFetch.proxyConfig }); return self; } exports.githubPages = githubPages; githubPages.normalizeOptions = _normalizeOptions; function _normalizeOptions(input) { const options = { owner: "", repository: "" }; if (typeof input === "string" && input.includes("/")) { [options.owner, options.repository] = input.split("/"); } else if (util_1.isObject(input)) { util_1.merge(options, input, ["owner", "repository", "hostname"]); } else { throw errors.invalidInput("options must be a GitHubPagesOptions object or `owner/repo` string"); } if (!options.owner) { throw errors.invalidProperty("owner", "is required"); } if (!options.repository) { throw errors.invalidProperty("repository", "is required"); } return options; } function buildGithubPagesProxy(options) { const { owner, repository, hostname } = options; const ghHost = `${owner}.github.io`; const headers = { host: ghHost, "x-forwarded-host": false }; let path = `/${repository}/`; if (hostname) { path = '/'; // no repo path when hostname exists headers.host = hostname; } console.debug("ghpages creating proxy:", `https://${ghHost}${path}`, { headers: headers, stripPath: path }); const fn = proxy_1.proxy(`https://${ghHost}${path}`, { headers: headers, stripPath: path }); return Object.assign(fn, { proxyConfig: options }); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0aHViX3BhZ2VzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2JhY2tlbmRzL2dpdGh1Yl9wYWdlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7R0FFRztBQUNILG9DQUFnRDtBQUNoRCxrQ0FBMEM7QUFDMUMsb0NBQW9DO0FBa0JwQzs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILFNBQWdCLFdBQVcsQ0FBQyxPQUFvQztJQUM5RCxNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUUxQyxJQUFJLE9BQU8sR0FBRyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUMzQyxJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUEsQ0FBQyxtQ0FBbUM7SUFFckQsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFBO0lBRWhCLE1BQU0sRUFBRSxHQUFHLEtBQUssVUFBVSxnQkFBZ0IsQ0FBQyxHQUFnQixFQUFFLElBQWtCO1FBQzdFLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQTtRQUN4QixJQUFHLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBQztZQUN6QixHQUFHLEdBQUcsSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFBO1NBQzdCO1FBQ0QsT0FBTyxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFBO1FBQzVELElBQUksSUFBSSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQTtRQUNuQyxPQUFPLENBQUMsS0FBSyxDQUFDLHNCQUFzQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNsRCxJQUFHLElBQUksQ0FBQyxNQUFNLEtBQUssR0FBRyxJQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFDO1lBQ3JELGlDQUFpQztZQUNqQyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDNUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVMsQ0FBQTtZQUNuQyxJQUNFLENBQUMsR0FBRyxDQUFDLFFBQVEsS0FBSyxHQUFHLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLDJCQUEyQjttQkFDaEUsSUFBSSxHQUFHLEtBQUssRUFBQyxFQUFFLGdDQUFnQztnQkFHakQsT0FBTyxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUE7Z0JBQzlELENBQUMsQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFBO2dCQUN0QixPQUFPLEdBQUcscUJBQXFCLENBQUMsQ0FBQyxDQUFDLENBQUE7YUFDbkM7U0FDRjtRQUNELElBQUcsSUFBSSxDQUFDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBQztZQUN0RCwrRUFBK0U7WUFDL0UsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUE7WUFDM0MsSUFBRyxRQUFRLEVBQUM7Z0JBQ1YsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUE7Z0JBQzdCLENBQUMsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQTtnQkFDekIsT0FBTyxHQUFHLHFCQUFxQixDQUFDLENBQUMsQ0FBQyxDQUFBO2dCQUNsQyxPQUFPLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFLENBQUMsQ0FBQyxDQUFBO2FBQzVDO1NBQ0Y7UUFDRCxJQUFHLFFBQVEsS0FBSyxPQUFPLEVBQUM7WUFDdEIsd0RBQXdEO1lBQ3hELE9BQU8sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLENBQUMsQ0FBQTtZQUMzQyxJQUFJLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUE7WUFDdEMsSUFBSSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQTtTQUNoQztRQUNELE9BQU8sSUFBSSxDQUFBO0lBQ2IsQ0FBQyxDQUFBO0lBRUQsSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsT0FBTyxDQUFDLFdBQVcsRUFBQyxDQUFDLENBQUE7SUFDakUsT0FBTyxJQUFJLENBQUE7QUFDYixDQUFDO0FBbkRELGtDQW1EQztBQUVELFdBQVcsQ0FBQyxnQkFBZ0IsR0FBRyxpQkFBaUIsQ0FBQztBQUVqRCxTQUFTLGlCQUFpQixDQUFDLEtBQWM7SUFDdkMsTUFBTSxPQUFPLEdBQXVCLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFFbEUsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUNwRCxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDeEQ7U0FBTSxJQUFJLGVBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUMxQixZQUFLLENBQUMsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztLQUM1RDtTQUFNO1FBQ0wsTUFBTSxNQUFNLENBQUMsWUFBWSxDQUFDLG9FQUFvRSxDQUFDLENBQUM7S0FDakc7SUFFRCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRTtRQUNsQixNQUFNLE1BQU0sQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0tBQ3REO0lBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUU7UUFDdkIsTUFBTSxNQUFNLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQztLQUMzRDtJQUVELE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxTQUFTLHFCQUFxQixDQUFDLE9BQTJCO0lBQ3hELE1BQU0sRUFBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBQyxHQUFHLE9BQU8sQ0FBQTtJQUM3QyxNQUFNLE1BQU0sR0FBRyxHQUFHLEtBQUssWUFBWSxDQUFBO0lBQ25DLE1BQU0sT0FBTyxHQUFHO1FBQ2QsSUFBSSxFQUFFLE1BQU07UUFDWixrQkFBa0IsRUFBRSxLQUFLO0tBQzFCLENBQUE7SUFDRCxJQUFJLElBQUksR0FBSSxJQUFJLFVBQVUsR0FBRyxDQUFBO0lBRTdCLElBQUcsUUFBUSxFQUFDO1FBQ1YsSUFBSSxHQUFHLEdBQUcsQ0FBQSxDQUFDLG9DQUFvQztRQUMvQyxPQUFPLENBQUMsSUFBSSxHQUFHLFFBQVEsQ0FBQTtLQUN4QjtJQUVELE9BQU8sQ0FBQyxLQUFLLENBQUMseUJBQXlCLEVBQUUsV0FBVyxNQUFNLEdBQUcsSUFBSSxFQUFFLEVBQUU7UUFDbkUsT0FBTyxFQUFFLE9BQU87UUFDaEIsU0FBUyxFQUFFLElBQUk7S0FDaEIsQ0FBQyxDQUFBO0lBQ0YsTUFBTSxFQUFFLEdBQUcsYUFBSyxDQUFDLFdBQVcsTUFBTSxHQUFHLElBQUksRUFBRSxFQUFFO1FBQzNDLE9BQU8sRUFBRSxPQUFPO1FBQ2hCLFNBQVMsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQTtJQUVGLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLENBQUUsQ0FBQTtBQUNyRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIEJhY2tlbmRzXG4gKi9cbmltcG9ydCB7IHByb3h5LCBQcm94eUZ1bmN0aW9uIH0gZnJvbSBcIi4uL3Byb3h5XCI7XG5pbXBvcnQgeyBpc09iamVjdCwgbWVyZ2UgfSBmcm9tIFwiLi4vdXRpbFwiO1xuaW1wb3J0ICogYXMgZXJyb3JzIGZyb20gXCIuLi9lcnJvcnNcIjtcblxuXG4vKipcbiAqIEdpdEh1YiBSZXBvc2l0b3J5IGluZm9ybWF0aW9uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdpdEh1YlBhZ2VzT3B0aW9ucyB7XG5cbiAgLyoqIFJlcG9zaXRvcnkgb3duZXIgKi9cbiAgb3duZXI6IHN0cmluZyxcblxuICAvKiogUmVwb3NpdG9yeSBuYW1lIDxyZXBvc2l0b3J5PiBmb3JtYXQgKi9cbiAgcmVwb3NpdG9yeTogc3RyaW5nLFxuXG4gIC8qKiBUaGUgY3VzdG9tIGhvc3RuYW1lIG9uIHJlcG9zaXRvcnkgKi9cbiAgaG9zdG5hbWU/OiBzdHJpbmdcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgZmV0Y2gtbGlrZSBwcm94eSBmdW5jdGlvbiBmb3IgbWFraW5nIHJlcXVlc3RzIHRvIEdpdEh1YiBwYWdlc1xuICogaG9zdGVkIHNpdGVzLlxuICogXG4gKiBFeGFtcGxlOlxuICogXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBnaXRodWJQYWdlcyB9IGZyb20gXCIuL3NyYy9iYWNrZW5kc1wiO1xuICogY29uc3QgYmFja2VuZCA9IGdpdGh1YlBhZ2VzKHtcbiAqICBvd25lcjogXCJzdXBlcmZseVwiLFxuICogIHJlcG86IFwiZWRnZVwiLFxuICogIGhvc3RuYW1lOiBcImRvY3MuZmx5LmlvXCJcbiAqIH0pO1xuICogYGBgXG4gKiBAcGFyYW0gY29uZmlnIFRoZSBHaXRodWIgcmVwb3NpdG9yeSB0byBwcm94eSB0b1xuICogQG1vZHVsZSBCYWNrZW5kc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2l0aHViUGFnZXMob3B0aW9uczogR2l0SHViUGFnZXNPcHRpb25zIHwgc3RyaW5nKTogUHJveHlGdW5jdGlvbjxHaXRIdWJQYWdlc09wdGlvbnM+IHtcbiAgY29uc3QgY29uZmlnID0gX25vcm1hbGl6ZU9wdGlvbnMob3B0aW9ucyk7XG5cbiAgbGV0IGdoRmV0Y2ggPSBidWlsZEdpdGh1YlBhZ2VzUHJveHkoY29uZmlnKVxuICBsZXQgYnVpbGRUaW1lID0gMCAvLyBmaXJzdCBmYWlsdXJlIG1pZ2h0IG5lZWQgYSByZXRyeVxuXG4gIGNvbnN0IGMgPSBjb25maWdcblxuICBjb25zdCBmbiA9IGFzeW5jIGZ1bmN0aW9uIGdpdGh1YlBhZ2VzRmV0Y2gocmVxOiBSZXF1ZXN0SW5mbywgaW5pdD86IFJlcXVlc3RJbml0KSB7XG4gICAgY29uc3Qgb3JpZ2luYWwgPSBnaEZldGNoXG4gICAgaWYodHlwZW9mIHJlcSA9PT0gXCJzdHJpbmdcIil7XG4gICAgICByZXEgPSBuZXcgUmVxdWVzdChyZXEsIGluaXQpXG4gICAgfVxuICAgIGNvbnNvbGUuZGVidWcoXCJnaHBhZ2VzIHN0YXJ0aW5nIGZldGNoOlwiLCByZXEudXJsLCBidWlsZFRpbWUpXG4gICAgbGV0IHJlc3AgPSBhd2FpdCBnaEZldGNoKHJlcSwgaW5pdClcbiAgICBjb25zb2xlLmRlYnVnKFwiZ2hwYWdlcyByZXNwIHN0YXR1czpcIiwgcmVzcC5zdGF0dXMpXG4gICAgaWYocmVzcC5zdGF0dXMgPT09IDQwNCAmJiBnaEZldGNoLnByb3h5Q29uZmlnLmhvc3RuYW1lKXtcbiAgICAgIC8vIGhvc3RuYW1lIG1pZ2h0J3ZlIGJlZW4gY2xlYXJlZFxuICAgICAgY29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsKVxuICAgICAgY29uc3QgZGlmZiA9IERhdGUubm93KCkgLSBidWlsZFRpbWVcbiAgICAgIGlmKFxuICAgICAgICAodXJsLnBhdGhuYW1lID09PSBcIi9cIiAmJiBkaWZmID4gMTAwMDApIC8vIHJldHJ5IGFmdGVyIDEwcyBmb3Igcm9vdFxuICAgICAgIHx8IGRpZmYgPiAzMDAwMCl7IC8vIHdhaXQgNW1pbiBmb3IgZXZlcnl0aGluZyBlbHNlXG5cblxuICAgICAgICBjb25zb2xlLmRlYnVnKFwiZ2hwYWdlcyBob3N0bmFtZSByZXF1ZXN0IGdvdCA0MDQ6XCIsIGMuaG9zdG5hbWUpXG4gICAgICAgIGMuaG9zdG5hbWUgPSB1bmRlZmluZWRcbiAgICAgICAgZ2hGZXRjaCA9IGJ1aWxkR2l0aHViUGFnZXNQcm94eShjKVxuICAgICAgfVxuICAgIH1cbiAgICBpZihyZXNwLnN0YXR1cyA9PT0gMzAxICYmICFnaEZldGNoLnByb3h5Q29uZmlnLmhvc3RuYW1lKXtcbiAgICAgIC8vIDMwMXMgaGFwcGVuIHdoZW4geW91IHJlcXVlc3QgPG9yZz4uZ2l0aHViLmlvLzxyZXBvPiBhbmQgbmVlZCBhIGN1c3RvbSBkb21haW5cbiAgICAgIGxldCBsb2NhdGlvbiA9IHJlc3AuaGVhZGVycy5nZXQoXCJsb2NhdGlvblwiKVxuICAgICAgaWYobG9jYXRpb24pe1xuICAgICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKGxvY2F0aW9uKVxuICAgICAgICBjLmhvc3RuYW1lID0gdXJsLmhvc3RuYW1lXG4gICAgICAgIGdoRmV0Y2ggPSBidWlsZEdpdGh1YlBhZ2VzUHJveHkoYylcbiAgICAgICAgY29uc29sZS5kZWJ1ZyhcImdocGFnZXMgZm91bmQgaG9zdG5hbWU6XCIsIGMpXG4gICAgICB9XG4gICAgfVxuICAgIGlmKG9yaWdpbmFsICE9PSBnaEZldGNoKXtcbiAgICAgIC8vIHVuZGVybHlpbmcgcHJveHkgZnVuY3Rpb24gY2hhbmdlZCwgc3RvcmUgaXQgYW5kIHJldHJ5XG4gICAgICBjb25zb2xlLmRlYnVnKFwiZ2hwYWdlcyBnb3QgYSBuZXcgZmV0Y2ggZm5cIilcbiAgICAgIHNlbGYucHJveHlDb25maWcgPSBnaEZldGNoLnByb3h5Q29uZmlnXG4gICAgICByZXNwID0gYXdhaXQgZ2hGZXRjaChyZXEsIGluaXQpXG4gICAgfVxuICAgIHJldHVybiByZXNwXG4gIH1cblxuICBsZXQgc2VsZiA9IE9iamVjdC5hc3NpZ24oZm4sIHsgcHJveHlDb25maWc6IGdoRmV0Y2gucHJveHlDb25maWd9KVxuICByZXR1cm4gc2VsZlxufVxuXG5naXRodWJQYWdlcy5ub3JtYWxpemVPcHRpb25zID0gX25vcm1hbGl6ZU9wdGlvbnM7XG5cbmZ1bmN0aW9uIF9ub3JtYWxpemVPcHRpb25zKGlucHV0OiB1bmtub3duKTogR2l0SHViUGFnZXNPcHRpb25zIHtcbiAgY29uc3Qgb3B0aW9uczogR2l0SHViUGFnZXNPcHRpb25zID0geyBvd25lcjogXCJcIiwgcmVwb3NpdG9yeTogXCJcIiB9O1xuXG4gIGlmICh0eXBlb2YgaW5wdXQgPT09IFwic3RyaW5nXCIgJiYgaW5wdXQuaW5jbHVkZXMoXCIvXCIpKSB7XG4gICAgW29wdGlvbnMub3duZXIsIG9wdGlvbnMucmVwb3NpdG9yeV0gPSBpbnB1dC5zcGxpdChcIi9cIik7XG4gIH0gZWxzZSBpZiAoaXNPYmplY3QoaW5wdXQpKSB7XG4gICAgbWVyZ2Uob3B0aW9ucywgaW5wdXQsIFtcIm93bmVyXCIsIFwicmVwb3NpdG9yeVwiLCBcImhvc3RuYW1lXCJdKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBlcnJvcnMuaW52YWxpZElucHV0KFwib3B0aW9ucyBtdXN0IGJlIGEgR2l0SHViUGFnZXNPcHRpb25zIG9iamVjdCBvciBgb3duZXIvcmVwb2Agc3RyaW5nXCIpO1xuICB9XG5cbiAgaWYgKCFvcHRpb25zLm93bmVyKSB7XG4gICAgdGhyb3cgZXJyb3JzLmludmFsaWRQcm9wZXJ0eShcIm93bmVyXCIsIFwiaXMgcmVxdWlyZWRcIik7XG4gIH1cbiAgaWYgKCFvcHRpb25zLnJlcG9zaXRvcnkpIHtcbiAgICB0aHJvdyBlcnJvcnMuaW52YWxpZFByb3BlcnR5KFwicmVwb3NpdG9yeVwiLCBcImlzIHJlcXVpcmVkXCIpO1xuICB9XG5cbiAgcmV0dXJuIG9wdGlvbnM7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkR2l0aHViUGFnZXNQcm94eShvcHRpb25zOiBHaXRIdWJQYWdlc09wdGlvbnMpOiBQcm94eUZ1bmN0aW9uPEdpdEh1YlBhZ2VzT3B0aW9ucz4ge1xuICBjb25zdCB7b3duZXIsIHJlcG9zaXRvcnksIGhvc3RuYW1lfSA9IG9wdGlvbnNcbiAgY29uc3QgZ2hIb3N0ID0gYCR7b3duZXJ9LmdpdGh1Yi5pb2BcbiAgY29uc3QgaGVhZGVycyA9IHtcbiAgICBob3N0OiBnaEhvc3QsXG4gICAgXCJ4LWZvcndhcmRlZC1ob3N0XCI6IGZhbHNlXG4gIH1cbiAgbGV0IHBhdGggID0gYC8ke3JlcG9zaXRvcnl9L2BcbiAgXG4gIGlmKGhvc3RuYW1lKXtcbiAgICBwYXRoID0gJy8nIC8vIG5vIHJlcG8gcGF0aCB3aGVuIGhvc3RuYW1lIGV4aXN0c1xuICAgIGhlYWRlcnMuaG9zdCA9IGhvc3RuYW1lXG4gIH1cblxuICBjb25zb2xlLmRlYnVnKFwiZ2hwYWdlcyBjcmVhdGluZyBwcm94eTpcIiwgYGh0dHBzOi8vJHtnaEhvc3R9JHtwYXRofWAsIHtcbiAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgIHN0cmlwUGF0aDogcGF0aFxuICB9KVxuICBjb25zdCBmbiA9IHByb3h5KGBodHRwczovLyR7Z2hIb3N0fSR7cGF0aH1gLCB7XG4gICAgaGVhZGVyczogaGVhZGVycyxcbiAgICBzdHJpcFBhdGg6IHBhdGhcbiAgfSlcblxuICByZXR1cm4gT2JqZWN0LmFzc2lnbihmbiwgeyBwcm94eUNvbmZpZzogb3B0aW9ucyB9IClcbn0iXX0=