UNPKG

ness

Version:

✪ No-effort static sites deployed to your AWS account.

241 lines 37.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildNextApp = exports.readInvalidationPathsFromManifest = exports.reduceInvalidationPaths = void 0; const crypto = __importStar(require("crypto")); const fs = __importStar(require("fs-extra")); const path = __importStar(require("path")); const archiver_1 = __importDefault(require("archiver")); const glob = __importStar(require("glob")); const lambda_at_edge_1 = require("@sls-next/lambda-at-edge"); const nextBuildDir = '.ness/.next'; const nextLambdaDir = '.ness/.next/__lambdas'; const PUBLIC_DIR_CACHE_CONTROL = 'public, max-age=31536000, must-revalidate'; const IMMUTABLE_CACHE_CONTROL = 'public, max-age=31536000, immutable'; const SERVER_CACHE_CONTROL = 'public, max-age=0, s-maxage=2678400, must-revalidate'; const filterNonExistentPathKeys = (config) => { return Object.keys(config).reduce((newConfig, nextConfigKey) => ({ ...newConfig, ...(fs.pathExistsSync(config[nextConfigKey].path) ? { [nextConfigKey]: config[nextConfigKey] } : {}), }), {}); }; const readAssetsDirectory = (dir) => { const publicFiles = path.join(dir, 'public'); const staticFiles = path.join(dir, 'static'); const staticPages = path.join(dir, 'static-pages'); const nextData = path.join(dir, '_next', 'data'); const nextStatic = path.join(dir, '_next', 'static'); return filterNonExistentPathKeys({ publicFiles: { path: publicFiles, cacheControl: PUBLIC_DIR_CACHE_CONTROL, prefix: path.relative(dir, publicFiles) + '/', }, staticFiles: { path: staticFiles, cacheControl: PUBLIC_DIR_CACHE_CONTROL, prefix: path.relative(dir, staticFiles) + '/', }, staticPages: { path: staticPages, cacheControl: SERVER_CACHE_CONTROL, prefix: path.relative(dir, staticPages) + '/', }, nextData: { path: nextData, cacheControl: SERVER_CACHE_CONTROL, prefix: path.relative(dir, nextData) + '/', }, nextStatic: { path: nextStatic, cacheControl: IMMUTABLE_CACHE_CONTROL, prefix: path.relative(dir, nextStatic) + '/', }, }); }; /** * We don't need to invalidate sub paths if a parent has a wild card * invalidation. i.e. if `/users/*` exists, we don't need to invalidate `/users/details/*` */ const reduceInvalidationPaths = (invalidationPaths) => { const wildCardDirectories = invalidationPaths .filter((invalidationPath) => invalidationPath.endsWith('/*')) .map((invalidationPath) => invalidationPath.replace('/*', '')); return invalidationPaths.filter((invalidationPath) => { return !wildCardDirectories.some((wildCardDirectory) => invalidationPath.startsWith(wildCardDirectory) && invalidationPath !== `${wildCardDirectory}*` && invalidationPath !== `${wildCardDirectory}/*` && wildCardDirectory !== invalidationPath); }); }; exports.reduceInvalidationPaths = reduceInvalidationPaths; const dynamicPathToInvalidationPath = (dynamicPath) => { const [base] = dynamicPath.split('/:'); const [firstSegment] = base.split('/['); // Ensure this is posix path as CloudFront needs forward slash in invalidation return path.posix.join(firstSegment || '/', '*'); }; const readInvalidationPathsFromManifest = (manifest) => { var _a, _b; return [ ...Object.keys(manifest.pages.html.dynamic).map(dynamicPathToInvalidationPath), ...Object.keys(manifest.pages.html.nonDynamic), ...Object.keys(manifest.pages.ssr.dynamic).map(dynamicPathToInvalidationPath), ...Object.keys(manifest.pages.ssr.nonDynamic), ...Object.keys(((_a = manifest.pages.ssg) === null || _a === void 0 ? void 0 : _a.dynamic) || {}).map(dynamicPathToInvalidationPath), ...Object.keys(((_b = manifest.pages.ssg) === null || _b === void 0 ? void 0 : _b.nonDynamic) || {}), ]; }; exports.readInvalidationPathsFromManifest = readInvalidationPathsFromManifest; async function readJsonFile(pathToFile) { try { await fs.access(pathToFile); const contents = await fs.readFile(pathToFile, { encoding: 'utf-8' }); return JSON.parse(contents); } catch (_a) { return undefined; } } const getNextApiBuildManifest = async () => { return readJsonFile(path.join(nextBuildDir, 'api-lambda/manifest.json')); }; const getNextDefaultManifest = async () => { return readJsonFile(path.join(nextBuildDir, 'default-lambda/manifest.json')); }; const getNextImageBuildManifest = async () => { return readJsonFile(path.join(nextBuildDir, 'image-lambda/manifest.json')); }; const getNextRoutesManifest = async () => { return readJsonFile(path.join(nextBuildDir, 'default-lambda/routes-manifest.json')); }; const getNextPrerenderManifest = async () => { return readJsonFile(path.join(nextBuildDir, 'default-lambda/prerender-manifest.json')); }; function zipDirectory(directory, outputFile) { return new Promise(async (resolve, reject) => { // The below options are needed to support following symlinks when building zip files: // - nodir: This will prevent symlinks themselves from being copied into the zip. // - follow: This will follow symlinks and copy the files within. const globOptions = { dot: true, nodir: true, follow: true, cwd: directory, }; const files = glob.sync('**', globOptions); // The output here is already sorted const shasum = crypto.createHash('sha256'); const output = fs.createWriteStream(outputFile); const archive = (0, archiver_1.default)('zip'); archive.on('warning', reject); archive.on('error', reject); archive.on('data', (data) => { shasum.update(data); }); // archive has been finalized and the output file descriptor has closed, resolve promise // this has to be done before calling `finalize` since the events may fire immediately after. // see https://www.npmjs.com/package/archiver output.once('close', () => { const hash = shasum.digest('hex'); resolve(hash); }); archive.pipe(output); // Append files serially to ensure file order for (const file of files) { const fullPath = path.resolve(directory, file); const [data, stat] = await Promise.all([fs.readFile(fullPath), fs.stat(fullPath)]); archive.append(data, { name: file, mode: stat.mode, }); } await archive.finalize(); }); } const buildNextApp = async (entry = process.cwd()) => { const buildDir = path.resolve(entry, nextBuildDir); await fs.remove(buildDir); const builder = new lambda_at_edge_1.Builder(entry, nextBuildDir, { args: ['build'] }); await builder.build(); const [defaultManifest, apiBuildManifest, imageBuildManifest, routesManifest, prerenderManifest] = await Promise.all([ getNextDefaultManifest(), getNextApiBuildManifest(), getNextImageBuildManifest(), getNextRoutesManifest(), getNextPrerenderManifest(), ]); const lambdaBuildDir = path.resolve(entry, nextLambdaDir); await fs.mkdir(lambdaBuildDir, { recursive: true }); const zipLambda = async (lambdaName) => { const zipped = path.join(lambdaBuildDir, `${lambdaName}.zip`); const hash = await zipDirectory(path.join(buildDir, lambdaName), zipped); const output = path.join(lambdaBuildDir, `${lambdaName}.${hash}.zip`); await fs.rename(zipped, output); return path.basename(output); }; const pathPattern = (pattern) => { const { basePath } = routesManifest || {}; return basePath && basePath.length > 0 ? `${basePath.slice(1)}/${pattern}` : pattern; }; const defaultLambdaPath = await zipLambda('default-lambda'); let apiLambdaPath = undefined; let imageLambdaPath = undefined; let regenerationLambdaPath = undefined; const apis = apiBuildManifest === null || apiBuildManifest === void 0 ? void 0 : apiBuildManifest.apis; const hasApi = apis && (Object.keys(apis.nonDynamic).length > 0 || Object.keys(apis.dynamic).length > 0); if (hasApi) { apiLambdaPath = await zipLambda('api-lambda'); } const hasImages = !!imageBuildManifest; if (hasImages) { imageLambdaPath = await zipLambda('image-lambda'); } const hasISRPages = prerenderManifest && Object.keys(prerenderManifest.routes).some((key) => typeof prerenderManifest.routes[key].initialRevalidateSeconds === 'number'); if (hasISRPages) { regenerationLambdaPath = await zipLambda('regeneration-lambda'); } const assetsDir = path.join(buildDir, 'assets'); const assets = readAssetsDirectory(assetsDir); return { lambdaBuildDir, defaultLambdaPath, apiLambdaPath, imageLambdaPath, regenerationLambdaPath, assets, imagePath: hasImages ? pathPattern('_next/image*') : undefined, dataPath: pathPattern('_next/data/*'), basePath: pathPattern('_next/*'), staticPath: pathPattern('static/*'), apiPath: hasApi ? pathPattern('api/*') : undefined, invalidationPaths: defaultManifest ? (0, exports.reduceInvalidationPaths)((0, exports.readInvalidationPathsFromManifest)(defaultManifest)) : undefined, }; }; exports.buildNextApp = buildNextApp; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9uZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQ0FBZ0M7QUFDaEMsNkNBQThCO0FBQzlCLDJDQUE0QjtBQUU1Qix3REFBK0I7QUFDL0IsMkNBQTRCO0FBQzVCLDZEQUFnRDtBQUdoRCxNQUFNLFlBQVksR0FBRyxhQUFhLENBQUE7QUFDbEMsTUFBTSxhQUFhLEdBQUcsdUJBQXVCLENBQUE7QUE4RzdDLE1BQU0sd0JBQXdCLEdBQUcsMkNBQTJDLENBQUE7QUFDNUUsTUFBTSx1QkFBdUIsR0FBRyxxQ0FBcUMsQ0FBQTtBQUNyRSxNQUFNLG9CQUFvQixHQUFHLHNEQUFzRCxDQUFBO0FBV25GLE1BQU0seUJBQXlCLEdBQUcsQ0FBQyxNQUFtQixFQUFFLEVBQUU7SUFDeEQsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FDL0IsQ0FBQyxTQUFTLEVBQUUsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzdCLEdBQUcsU0FBUztRQUNaLEdBQUcsQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFDL0MsQ0FBQyxDQUFDLEVBQUMsQ0FBQyxhQUFhLENBQUMsRUFBRSxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUM7WUFDMUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUNSLENBQUMsRUFDRixFQUFpQixDQUNsQixDQUFBO0FBQ0gsQ0FBQyxDQUFBO0FBRUQsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLEdBQVcsRUFBZSxFQUFFO0lBQ3ZELE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFBO0lBQzVDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxF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QUUsV0FBVyxDQUFDLGNBQWMsQ0FBQztRQUNyQyxRQUFRLEVBQUUsV0FBVyxDQUFDLFNBQVMsQ0FBQztRQUNoQyxVQUFVLEVBQUUsV0FBVyxDQUFDLFVBQVUsQ0FBQztRQUNuQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7UUFDbEQsaUJBQWlCLEVBQUUsZUFBZTtZQUNoQyxDQUFDLENBQUMsSUFBQSwrQkFBdUIsRUFBQyxJQUFBLHlDQUFpQyxFQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzdFLENBQUMsQ0FBQyxTQUFTO0tBQ2QsQ0FBQTtBQUNILENBQUMsQ0FBQTtBQTlFWSxRQUFBLFlBQVksZ0JBOEV4QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nXG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy1leHRyYSdcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCdcblxuaW1wb3J0IGFyY2hpdmVyIGZyb20gJ2FyY2hpdmVyJ1xuaW1wb3J0ICogYXMgZ2xvYiBmcm9tICdnbG9iJ1xuaW1wb3J0IHtCdWlsZGVyfSBmcm9tICdAc2xzLW5leHQvbGFtYmRhLWF0LWVkZ2UnXG5pbXBvcnQge1ByZVJlbmRlcmVkTWFuaWZlc3R9IGZyb20gJ0BzbHMtbmV4dC9jb3JlJ1xuXG5jb25zdCBuZXh0QnVpbGREaXIgPSAnLm5lc3MvLm5leHQnXG5jb25zdCBuZXh0TGFtYmRhRGlyID0gJy5uZXNzLy5uZXh0L19fbGFtYmRhcydcblxuZXhwb3J0IHR5cGUgRHluYW1pY1BhZ2VLZXlWYWx1ZSA9IHtcbiAgW2tleTogc3RyaW5nXToge1xuICAgIGZpbGU6IHN0cmluZ1xuICAgIHJlZ2V4OiBzdHJpbmdcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBPcmlnaW5SZXF1ZXN0QXBpSGFuZGxlck1hbmlmZXN0ID0ge1xuICBhcGlzOiB7XG4gICAgZHluYW1pYzogRHluYW1pY1BhZ2VLZXlWYWx1ZVxuICAgIG5vbkR5bmFtaWM6IHtcbiAgICAgIFtrZXk6IHN0cmluZ106IHN0cmluZ1xuICAgIH1cbiAgfVxuICBkb21haW5SZWRpcmVjdHM6IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdcbiAgfVxuICBlbmFibGVIVFRQQ29tcHJlc3Npb246IGJvb2xlYW5cbiAgYXV0aGVudGljYXRpb24/OiB7XG4gICAgdXNlcm5hbWU6IHN0cmluZ1xuICAgIHBhc3N3b3JkOiBzdHJpbmdcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBPcmlnaW5SZXF1ZXN0RGVmYXVsdEhhbmRsZXJNYW5pZmVzdCA9IHtcbiAgYnVpbGRJZDogc3RyaW5nXG4gIGxvZ0xhbWJkYUV4ZWN1dGlvblRpbWVzOiBib29sZWFuXG4gIHBhZ2VzOiB7XG4gICAgc3NyOiB7XG4gICAgICBkeW5hbWljOiBEeW5hbWljUGFnZUtleVZhbHVlXG4gICAgICBub25EeW5hbWljOiB7XG4gICAgICAgIFtrZXk6IHN0cmluZ106IHN0cmluZ1xuICAgICAgfVxuICAgIH1cbiAgICBodG1sOiB7XG4gICAgICBub25EeW5hbWljOiB7XG4gICAgICAgIFtwYXRoOiBzdHJpbmddOiBzdHJpbmdcbiAgICAgIH1cbiAgICAgIGR5bmFtaWM6IER5bmFtaWNQYWdlS2V5VmFsdWVcbiAgICB9XG4gICAgc3NnOiB7XG4gICAgICBub25EeW5hbWljOiB7XG4gICAgICAgIFtwYXRoOiBzdHJpbmddOiB1bmtub3duXG4gICAgICB9XG4gICAgICBkeW5hbWljOiB7XG4gICAgICAgIFtwYXRoOiBzdHJpbmddOiB1bmtub3duXG4gICAgICB9XG4gICAgfVxuICB9XG4gIHB1YmxpY0ZpbGVzOiB7XG4gICAgW2tleTogc3RyaW5nXTogc3RyaW5nXG4gIH1cbiAgdHJhaWxpbmdTbGFzaDogYm9vbGVhblxuICBlbmFibGVIVFRQQ29tcHJlc3Npb246IGJvb2xlYW5cbiAgZG9tYWluUmVkaXJlY3RzOiB7XG4gICAgW2tleTogc3RyaW5nXTogc3RyaW5nXG4gIH1cbiAgYXV0aGVudGljYXRpb24/OiB7XG4gICAgdXNlcm5hbWU6IHN0cmluZ1xuICAgIHBhc3N3b3JkOiBzdHJpbmdcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBPcmlnaW5SZXF1ZXN0SW1hZ2VIYW5kbGVyTWFuaWZlc3QgPSB7XG4gIGVuYWJsZUhUVFBDb21wcmVzc2lvbjogYm9vbGVhblxuICBkb21haW5SZWRpcmVjdHM6IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdcbiAgfVxufVxuXG5leHBvcnQgdHlwZSBSZWRpcmVjdERhdGEgPSB7XG4gIHN0YXR1c0NvZGU6IG51bWJlclxuICBzb3VyY2U6IHN0cmluZ1xuICBkZXN0aW5hdGlvbjogc3RyaW5nXG4gIHJlZ2V4OiBzdHJpbmdcbiAgaW50ZXJuYWw/OiBib29sZWFuXG59XG5cbmV4cG9ydCB0eXBlIFJld3JpdGVEYXRhID0ge1xuICBzb3VyY2U6IHN0cmluZ1xuICBkZXN0aW5hdGlvbjogc3RyaW5nXG4gIHJlZ2V4OiBzdHJpbmdcbn1cblxuZXhwb3J0IHR5cGUgSGVhZGVyID0ge1xuICBrZXk6IHN0cmluZ1xuICB2YWx1ZTogc3RyaW5nXG59XG5cbmV4cG9ydCB0eXBlIEhlYWRlckRhdGEgPSB7XG4gIHNvdXJjZTogc3RyaW5nXG4gIGhlYWRlcnM6IEhlYWRlcltdXG4gIHJlZ2V4OiBzdHJpbmdcbn1cblxuZXhwb3J0IHR5cGUgSTE4bkRhdGEgPSB7XG4gIGxvY2FsZXM6IHN0cmluZ1tdXG4gIGRlZmF1bHRMb2NhbGU6IHN0cmluZ1xufVxuXG5leHBvcnQgdHlwZSBSb3V0ZXNNYW5pZmVzdCA9IHtcbiAgYmFzZVBhdGg6IHN0cmluZ1xuICByZWRpcmVjdHM6IFJlZGlyZWN0RGF0YVtdXG4gIHJld3JpdGVzOiBSZXdyaXRlRGF0YVtdXG4gIGhlYWRlcnM6IEhlYWRlckRhdGFbXVxuICBpMThuPzogSTE4bkRhdGFcbn1cblxuY29uc3QgUFVCTElDX0RJUl9DQUNIRV9DT05UUk9MID0gJ3B1YmxpYywgbWF4LWFnZT0zMTUzNjAwMCwgbXVzdC1yZXZhbGlkYXRlJ1xuY29uc3QgSU1NVVRBQkxFX0NBQ0hFX0NPTlRST0wgPSAncHVibGljLCBtYXgtYWdlPTMxNTM2MDAwLCBpbW11dGFibGUnXG5jb25zdCBTRVJWRVJfQ0FDSEVfQ09OVFJPTCA9ICdwdWJsaWMsIG1heC1hZ2U9MCwgcy1tYXhhZ2U9MjY3ODQwMCwgbXVzdC1yZXZhbGlkYXRlJ1xuXG50eXBlIENhY2hlQ29uZmlnID0gUmVjb3JkPFxuICBzdHJpbmcsXG4gIHtcbiAgICBjYWNoZUNvbnRyb2w6IHN0cmluZ1xuICAgIHBhdGg6IHN0cmluZ1xuICAgIHByZWZpeDogc3RyaW5nXG4gIH1cbj5cblxuY29uc3QgZmlsdGVyTm9uRXhpc3RlbnRQYXRoS2V5cyA9IChjb25maWc6IENhY2hlQ29uZmlnKSA9PiB7XG4gIHJldHVybiBPYmplY3Qua2V5cyhjb25maWcpLnJlZHVjZShcbiAgICAobmV3Q29uZmlnLCBuZXh0Q29uZmlnS2V5KSA9PiAoe1xuICAgICAgLi4ubmV3Q29uZmlnLFxuICAgICAgLi4uKGZzLnBhdGhFeGlzdHNTeW5jKGNvbmZpZ1tuZXh0Q29uZmlnS2V5XS5wYXRoKVxuICAgICAgICA/IHtbbmV4dENvbmZpZ0tleV06IGNvbmZpZ1tuZXh0Q29uZmlnS2V5XX1cbiAgICAgICAgOiB7fSksXG4gICAgfSksXG4gICAge30gYXMgQ2FjaGVDb25maWcsXG4gIClcbn1cblxuY29uc3QgcmVhZEFzc2V0c0RpcmVjdG9yeSA9IChkaXI6IHN0cmluZyk6IENhY2hlQ29uZmlnID0+IHtcbiAgY29uc3QgcHVibGljRmlsZXMgPSBwYXRoLmpvaW4oZGlyLCAncHVibGljJylcbiAgY29uc3Qgc3RhdGljRmlsZXMgPSBwYXRoLmpvaW4oZGlyLCAnc3RhdGljJylcbiAgY29uc3Qgc3RhdGljUGFnZXMgPSBwYXRoLmpvaW4oZGlyLCAnc3RhdGljLXBhZ2VzJylcbiAgY29uc3QgbmV4dERhdGEgPSBwYXRoLmpvaW4oZGlyLCAnX25leHQnLCAnZGF0YScpXG4gIGNvbnN0IG5leHRTdGF0aWMgPSBwYXRoLmpvaW4oZGlyLCAnX25leHQnLCAnc3RhdGljJylcblxuICByZXR1cm4gZmlsdGVyTm9uRXhpc3RlbnRQYXRoS2V5cyh7XG4gICAgcHVibGljRmlsZXM6IHtcbiAgICAgIHBhdGg6IHB1YmxpY0ZpbGVzLFxuICAgICAgY2FjaGVDb250cm9sOiBQVUJMSUNfRElSX0NBQ0hFX0NPTlRST0wsXG4gICAgICBwcmVmaXg6IHBhdGgucmVsYXRpdmUoZGlyLCBwdWJsaWNGaWxlcykgKyAnLycsXG4gICAgfSxcbiAgICBzdGF0aWNGaWxlczoge1xuICAgICAgcGF0aDogc3RhdGljRmlsZXMsXG4gICAgICBjYWNoZUNvbnRyb2w6IFBVQkxJQ19ESVJfQ0FDSEVfQ09OVFJPTCxcbiAgICAgIHByZWZpeDogcGF0aC5yZWxhdGl2ZShkaXIsIHN0YXRpY0ZpbGVzKSArICcvJyxcbiAgICB9LFxuICAgIHN0YXRpY1BhZ2VzOiB7XG4gICAgICBwYXRoOiBzdGF0aWNQYWdlcyxcbiAgICAgIGNhY2hlQ29udHJvbDogU0VSVkVSX0NBQ0hFX0NPTlRST0wsXG4gICAgICBwcmVmaXg6IHBhdGgucmVsYXRpdmUoZGlyLCBzdGF0aWNQYWdlcykgKyAnLycsXG4gICAgfSxcbiAgICBuZXh0RGF0YToge1xuICAgICAgcGF0aDogbmV4dERhdGEsXG4gICAgICBjYWNoZUNvbnRyb2w6IFNFUlZFUl9DQUNIRV9DT05UUk9MLFxuICAgICAgcHJlZml4OiBwYXRoLnJlbGF0aXZlKGRpciwgbmV4dERhdGEpICsgJy8nLFxuICAgIH0sXG4gICAgbmV4dFN0YXRpYzoge1xuICAgICAgcGF0aDogbmV4dFN0YXRpYyxcbiAgICAgIGNhY2hlQ29udHJvbDogSU1NVVRBQkxFX0NBQ0hFX0NPTlRST0wsXG4gICAgICBwcmVmaXg6IHBhdGgucmVsYXRpdmUoZGlyLCBuZXh0U3RhdGljKSArICcvJyxcbiAgICB9LFxuICB9KVxufVxuXG4vKipcbiAqIFdlIGRvbid0IG5lZWQgdG8gaW52YWxpZGF0ZSBzdWIgcGF0aHMgaWYgYSBwYXJlbnQgaGFzIGEgd2lsZCBjYXJkXG4gKiBpbnZhbGlkYXRpb24uIGkuZS4gaWYgYC91c2Vycy8qYCBleGlzdHMsIHdlIGRvbid0IG5lZWQgdG8gaW52YWxpZGF0ZSBgL3VzZXJzL2RldGFpbHMvKmBcbiAqL1xuZXhwb3J0IGNvbnN0IHJlZHVjZUludmFsaWRhdGlvblBhdGhzID0gKGludmFsaWRhdGlvblBhdGhzOiBzdHJpbmdbXSk6IHN0cmluZ1tdID0+IHtcbiAgY29uc3Qgd2lsZENhcmREaXJlY3RvcmllcyA9IGludmFsaWRhdGlvblBhdGhzXG4gICAgLmZpbHRlcigoaW52YWxpZGF0aW9uUGF0aCkgPT4gaW52YWxpZGF0aW9uUGF0aC5lbmRzV2l0aCgnLyonKSlcbiAgICAubWFwKChpbnZhbGlkYXRpb25QYXRoKSA9PiBpbnZhbGlkYXRpb25QYXRoLnJlcGxhY2UoJy8qJywgJycpKVxuXG4gIHJldHVybiBpbnZhbGlkYXRpb25QYXRocy5maWx0ZXIoKGludmFsaWRhdGlvblBhdGgpID0+IHtcbiAgICByZXR1cm4gIXdpbGRDYXJkRGlyZWN0b3JpZXMuc29tZShcbiAgICAgICh3aWxkQ2FyZERpcmVjdG9yeSkgPT5cbiAgICAgICAgaW52YWxpZGF0aW9uUGF0aC5zdGFydHNXaXRoKHdpbGRDYXJkRGlyZWN0b3J5KSAmJlxuICAgICAgICBpbnZhbGlkYXRpb25QYXRoICE9PSBgJHt3aWxkQ2FyZERpcmVjdG9yeX0qYCAmJlxuICAgICAgICBpbnZhbGlkYXRpb25QYXRoICE9PSBgJHt3aWxkQ2FyZERpcmVjdG9yeX0vKmAgJiZcbiAgICAgICAgd2lsZENhcmREaXJlY3RvcnkgIT09IGludmFsaWRhdGlvblBhdGgsXG4gICAgKVxuICB9KVxufVxuXG5jb25zdCBkeW5hbWljUGF0aFRvSW52YWxpZGF0aW9uUGF0aCA9IChkeW5hbWljUGF0aDogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IFtiYXNlXSA9IGR5bmFtaWNQYXRoLnNwbGl0KCcvOicpXG4gIGNvbnN0IFtmaXJzdFNlZ21lbnRdID0gYmFzZS5zcGxpdCgnL1snKVxuICAvLyBFbnN1cmUgdGhpcyBpcyBwb3NpeCBwYXRoIGFzIENsb3VkRnJvbnQgbmVlZHMgZm9yd2FyZCBzbGFzaCBpbiBpbnZhbGlkYXRpb25cbiAgcmV0dXJuIHBhdGgucG9zaXguam9pbihmaXJzdFNlZ21lbnQgfHwgJy8nLCAnKicpXG59XG5cbmV4cG9ydCBjb25zdCByZWFkSW52YWxpZGF0aW9uUGF0aHNGcm9tTWFuaWZlc3QgPSAoXG4gIG1hbmlmZXN0OiBPcmlnaW5SZXF1ZXN0RGVmYXVsdEhhbmRsZXJNYW5pZmVzdCxcbik6IHN0cmluZ1tdID0+IHtcbiAgcmV0dXJuIFtcbiAgICAuLi5PYmplY3Qua2V5cyhtYW5pZmVzdC5wYWdlcy5odG1sLmR5bmFtaWMpLm1hcChkeW5hbWljUGF0aFRvSW52YWxpZGF0aW9uUGF0aCksXG4gICAgLi4uT2JqZWN0LmtleXMobWFuaWZlc3QucGFnZXMuaHRtbC5ub25EeW5hbWljKSxcbiAgICAuLi5PYmplY3Qua2V5cyhtYW5pZmVzdC5wYWdlcy5zc3IuZHluYW1pYykubWFwKGR5bmFtaWNQYXRoVG9JbnZhbGlkYXRpb25QYXRoKSxcbiAgICAuLi5PYmplY3Qua2V5cyhtYW5pZmVzdC5wYWdlcy5zc3Iubm9uRHluYW1pYyksXG4gICAgLi4uT2JqZWN0LmtleXMobWFuaWZlc3QucGFnZXMuc3NnPy5keW5hbWljIHx8IHt9KS5tYXAoZHluYW1pY1BhdGhUb0ludmFsaWRhdGlvblBhdGgpLFxuICAgIC4uLk9iamVjdC5rZXlzKG1hbmlmZXN0LnBhZ2VzLnNzZz8ubm9uRHluYW1pYyB8fCB7fSksXG4gIF1cbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZEpzb25GaWxlPFQ+KHBhdGhUb0ZpbGU6IHN0cmluZyk6IFByb21pc2U8VCB8IHVuZGVmaW5lZD4ge1xuICB0cnkge1xuICAgIGF3YWl0IGZzLmFjY2VzcyhwYXRoVG9GaWxlKVxuICAgIGNvbnN0IGNvbnRlbnRzID0gYXdhaXQgZnMucmVhZEZpbGUocGF0aFRvRmlsZSwge2VuY29kaW5nOiAndXRmLTgnfSlcbiAgICByZXR1cm4gSlNPTi5wYXJzZShjb250ZW50cykgYXMgVFxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuY29uc3QgZ2V0TmV4dEFwaUJ1aWxkTWFuaWZlc3QgPSBhc3luYyAoKTogUHJvbWlzZTxPcmlnaW5SZXF1ZXN0QXBpSGFuZGxlck1hbmlmZXN0IHwgdW5kZWZpbmVkPiA9PiB7XG4gIHJldHVybiByZWFkSnNvbkZpbGUocGF0aC5qb2luKG5leHRCdWlsZERpciwgJ2FwaS1sYW1iZGEvbWFuaWZlc3QuanNvbicpKVxufVxuXG5jb25zdCBnZXROZXh0RGVmYXVsdE1hbmlmZXN0ID0gYXN5bmMgKCk6IFByb21pc2U8XG4gIE9yaWdpblJlcXVlc3REZWZhdWx0SGFuZGxlck1hbmlmZXN0IHwgdW5kZWZpbmVkXG4+ID0+IHtcbiAgcmV0dXJuIHJlYWRKc29uRmlsZShwYXRoLmpvaW4obmV4dEJ1aWxkRGlyLCAnZGVmYXVsdC1sYW1iZGEvbWFuaWZlc3QuanNvbicpKVxufVxuXG5jb25zdCBnZXROZXh0SW1hZ2VCdWlsZE1hbmlmZXN0ID0gYXN5bmMgKCk6IFByb21pc2U8XG4gIE9yaWdpblJlcXVlc3RJbWFnZUhhbmRsZXJNYW5pZmVzdCB8IHVuZGVmaW5lZFxuPiA9PiB7XG4gIHJldHVybiByZWFkSnNvbkZpbGUocGF0aC5qb2luKG5leHRCdWlsZERpciwgJ2ltYWdlLWxhbWJkYS9tYW5pZmVzdC5qc29uJykpXG59XG5cbmNvbnN0IGdldE5leHRSb3V0ZXNNYW5pZmVzdCA9IGFzeW5jICgpOiBQcm9taXNlPFJvdXRlc01hbmlmZXN0IHwgdW5kZWZpbmVkPiA9PiB7XG4gIHJldHVybiByZWFkSnNvbkZpbGUocGF0aC5qb2luKG5leHRCdWlsZERpciwgJ2RlZmF1bHQtbGFtYmRhL3JvdXRlcy1tYW5pZmVzdC5qc29uJykpXG59XG5cbmNvbnN0IGdldE5leHRQcmVyZW5kZXJNYW5pZmVzdCA9IGFzeW5jICgpOiBQcm9taXNlPFByZVJlbmRlcmVkTWFuaWZlc3QgfCB1bmRlZmluZWQ+ID0+IHtcbiAgcmV0dXJuIHJlYWRKc29uRmlsZShwYXRoLmpvaW4obmV4dEJ1aWxkRGlyLCAnZGVmYXVsdC1sYW1iZGEvcHJlcmVuZGVyLW1hbmlmZXN0Lmpzb24nKSlcbn1cblxuZnVuY3Rpb24gemlwRGlyZWN0b3J5KGRpcmVjdG9yeTogc3RyaW5nLCBvdXRwdXRGaWxlOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoYXN5bmMgKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIC8vIFRoZSBiZWxvdyBvcHRpb25zIGFyZSBuZWVkZWQgdG8gc3VwcG9ydCBmb2xsb3dpbmcgc3ltbGlua3Mgd2hlbiBidWlsZGluZyB6aXAgZmlsZXM6XG4gICAgLy8gLSBub2RpcjogVGhpcyB3aWxsIHByZXZlbnQgc3ltbGlua3MgdGhlbXNlbHZlcyBmcm9tIGJlaW5nIGNvcGllZCBpbnRvIHRoZSB6aXAuXG4gICAgLy8gLSBmb2xsb3c6IFRoaXMgd2lsbCBmb2xsb3cgc3ltbGlua3MgYW5kIGNvcHkgdGhlIGZpbGVzIHdpdGhpbi5cbiAgICBjb25zdCBnbG9iT3B0aW9ucyA9IHtcbiAgICAgIGRvdDogdHJ1ZSxcbiAgICAgIG5vZGlyOiB0cnVlLFxuICAgICAgZm9sbG93OiB0cnVlLFxuICAgICAgY3dkOiBkaXJlY3RvcnksXG4gICAgfVxuICAgIGNvbnN0IGZpbGVzID0gZ2xvYi5zeW5jKCcqKicsIGdsb2JPcHRpb25zKSAvLyBUaGUgb3V0cHV0IGhlcmUgaXMgYWxyZWFkeSBzb3J0ZWRcblxuICAgIGNvbnN0IHNoYXN1bSA9IGNyeXB0by5jcmVhdGVIYXNoKCdzaGEyNTYnKVxuICAgIGNvbnN0IG91dHB1dCA9IGZzLmNyZWF0ZVdyaXRlU3RyZWFtKG91dHB1dEZpbGUpXG5cbiAgICBjb25zdCBhcmNoaXZlID0gYXJjaGl2ZXIoJ3ppcCcpXG4gICAgYXJjaGl2ZS5vbignd2FybmluZycsIHJlamVjdClcbiAgICBhcmNoaXZlLm9uKCdlcnJvcicsIHJlamVjdClcbiAgICBhcmNoaXZlLm9uKCdkYXRhJywgKGRhdGEpID0+IHtcbiAgICAgIHNoYXN1bS51cGRhdGUoZGF0YSlcbiAgICB9KVxuXG4gICAgLy8gYXJjaGl2ZSBoYXMgYmVlbiBmaW5hbGl6ZWQgYW5kIHRoZSBvdXRwdXQgZmlsZSBkZXNjcmlwdG9yIGhhcyBjbG9zZWQsIHJlc29sdmUgcHJvbWlzZVxuICAgIC8vIHRoaXMgaGFzIHRvIGJlIGRvbmUgYmVmb3JlIGNhbGxpbmcgYGZpbmFsaXplYCBzaW5jZSB0aGUgZXZlbnRzIG1heSBmaXJlIGltbWVkaWF0ZWx5IGFmdGVyLlxuICAgIC8vIHNlZSBodHRwczovL3d3dy5ucG1qcy5jb20vcGFja2FnZS9hcmNoaXZlclxuICAgIG91dHB1dC5vbmNlKCdjbG9zZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGhhc2ggPSBzaGFzdW0uZGlnZXN0KCdoZXgnKVxuICAgICAgcmVzb2x2ZShoYXNoKVxuICAgIH0pXG5cbiAgICBhcmNoaXZlLnBpcGUob3V0cHV0KVxuXG4gICAgLy8gQXBwZW5kIGZpbGVzIHNlcmlhbGx5IHRvIGVuc3VyZSBmaWxlIG9yZGVyXG4gICAgZm9yIChjb25zdCBmaWxlIG9mIGZpbGVzKSB7XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGgucmVzb2x2ZShkaXJlY3RvcnksIGZpbGUpXG4gICAgICBjb25zdCBbZGF0YSwgc3RhdF0gPSBhd2FpdCBQcm9taXNlLmFsbChbZnMucmVhZEZpbGUoZnVsbFBhdGgpLCBmcy5zdGF0KGZ1bGxQYXRoKV0pXG4gICAgICBhcmNoaXZlLmFwcGVuZChkYXRhLCB7XG4gICAgICAgIG5hbWU6IGZpbGUsXG4gICAgICAgIG1vZGU6IHN0YXQubW9kZSxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgYXdhaXQgYXJjaGl2ZS5maW5hbGl6ZSgpXG4gIH0pXG59XG5cbmV4cG9ydCB0eXBlIE5leHRCdWlsZCA9IHtcbiAgbGFtYmRhQnVpbGREaXI6IHN0cmluZ1xuICBkZWZhdWx0TGFtYmRhUGF0aDogc3RyaW5nXG4gIGltYWdlTGFtYmRhUGF0aD86IHN0cmluZ1xuICBhcGlMYW1iZGFQYXRoPzogc3RyaW5nXG4gIHJlZ2VuZXJhdGlvbkxhbWJkYVBhdGg/OiBzdHJpbmdcbiAgYXNzZXRzOiBDYWNoZUNvbmZpZ1xuICBiYXNlUGF0aDogc3RyaW5nXG4gIHN0YXRpY1BhdGg6IHN0cmluZ1xuICBkYXRhUGF0aDogc3RyaW5nXG4gIGltYWdlUGF0aD86IHN0cmluZ1xuICBhcGlQYXRoPzogc3RyaW5nXG4gIGludmFsaWRhdGlvblBhdGhzPzogc3RyaW5nW11cbn1cblxuZXhwb3J0IGNvbnN0IGJ1aWxkTmV4dEFwcCA9IGFzeW5jIChlbnRyeTogc3RyaW5nID0gcHJvY2Vzcy5jd2QoKSk6IFByb21pc2U8TmV4dEJ1aWxkPiA9PiB7XG4gIGNvbnN0IGJ1aWxkRGlyID0gcGF0aC5yZXNvbHZlKGVudHJ5LCBuZXh0QnVpbGREaXIpXG4gIGF3YWl0IGZzLnJlbW92ZShidWlsZERpcilcblxuICBjb25zdCBidWlsZGVyID0gbmV3IEJ1aWxkZXIoZW50cnksIG5leHRCdWlsZERpciwge2FyZ3M6IFsnYnVpbGQnXX0pXG4gIGF3YWl0IGJ1aWxkZXIuYnVpbGQoKVxuXG4gIGNvbnN0IFtkZWZhdWx0TWFuaWZlc3QsIGFwaUJ1aWxkTWFuaWZlc3QsIGltYWdlQnVpbGRNYW5pZmVzdCwgcm91dGVzTWFuaWZlc3QsIHByZXJlbmRlck1hbmlmZXN0XSA9XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgZ2V0TmV4dERlZmF1bHRNYW5pZmVzdCgpLFxuICAgICAgZ2V0TmV4dEFwaUJ1aWxkTWFuaWZlc3QoKSxcbiAgICAgIGdldE5leHRJbWFnZUJ1aWxkTWFuaWZlc3QoKSxcbiAgICAgIGdldE5leHRSb3V0ZXNNYW5pZmVzdCgpLFxuICAgICAgZ2V0TmV4dFByZXJlbmRlck1hbmlmZXN0KCksXG4gICAgXSlcblxuICBjb25zdCBsYW1iZGFCdWlsZERpciA9IHBhdGgucmVzb2x2ZShlbnRyeSwgbmV4dExhbWJkYURpcilcbiAgYXdhaXQgZnMubWtkaXIobGFtYmRhQnVpbGREaXIsIHtyZWN1cnNpdmU6IHRydWV9KVxuXG4gIGNvbnN0IHppcExhbWJkYSA9IGFzeW5jIChsYW1iZGFOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIGNvbnN0IHppcHBlZCA9IHBhdGguam9pbihsYW1iZGFCdWlsZERpciwgYCR7bGFtYmRhTmFtZX0uemlwYClcbiAgICBjb25zdCBoYXNoID0gYXdhaXQgemlwRGlyZWN0b3J5KHBhdGguam9pbihidWlsZERpciwgbGFtYmRhTmFtZSksIHppcHBlZClcblxuICAgIGNvbnN0IG91dHB1dCA9IHBhdGguam9pbihsYW1iZGFCdWlsZERpciwgYCR7bGFtYmRhTmFtZX0uJHtoYXNofS56aXBgKVxuICAgIGF3YWl0IGZzLnJlbmFtZSh6aXBwZWQsIG91dHB1dClcbiAgICByZXR1cm4gcGF0aC5iYXNlbmFtZShvdXRwdXQpXG4gIH1cblxuICBjb25zdCBwYXRoUGF0dGVybiA9IChwYXR0ZXJuOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IHtiYXNlUGF0aH0gPSByb3V0ZXNNYW5pZmVzdCB8fCB7fVxuICAgIHJldHVybiBiYXNlUGF0aCAmJiBiYXNlUGF0aC5sZW5ndGggPiAwID8gYCR7YmFzZVBhdGguc2xpY2UoMSl9LyR7cGF0dGVybn1gIDogcGF0dGVyblxuICB9XG5cbiAgY29uc3QgZGVmYXVsdExhbWJkYVBhdGggPSBhd2FpdCB6aXBMYW1iZGEoJ2RlZmF1bHQtbGFtYmRhJylcbiAgbGV0IGFwaUxhbWJkYVBhdGggPSB1bmRlZmluZWRcbiAgbGV0IGltYWdlTGFtYmRhUGF0aCA9IHVuZGVmaW5lZFxuICBsZXQgcmVnZW5lcmF0aW9uTGFtYmRhUGF0aCA9IHVuZGVmaW5lZFxuXG4gIGNvbnN0IGFwaXMgPSBhcGlCdWlsZE1hbmlmZXN0Py5hcGlzXG4gIGNvbnN0IGhhc0FwaSA9XG4gICAgYXBpcyAmJiAoT2JqZWN0LmtleXMoYXBpcy5ub25EeW5hbWljKS5sZW5ndGggPiAwIHx8IE9iamVjdC5rZXlzKGFwaXMuZHluYW1pYykubGVuZ3RoID4gMClcbiAgaWYgKGhhc0FwaSkge1xuICAgIGFwaUxhbWJkYVBhdGggPSBhd2FpdCB6aXBMYW1iZGEoJ2FwaS1sYW1iZGEnKVxuICB9XG5cbiAgY29uc3QgaGFzSW1hZ2VzID0gISFpbWFnZUJ1aWxkTWFuaWZlc3RcbiAgaWYgKGhhc0ltYWdlcykge1xuICAgIGltYWdlTGFtYmRhUGF0aCA9IGF3YWl0IHppcExhbWJkYSgnaW1hZ2UtbGFtYmRhJylcbiAgfVxuXG4gIGNvbnN0IGhhc0lTUlBhZ2VzID1cbiAgICBwcmVyZW5kZXJNYW5pZmVzdCAmJlxuICAgIE9iamVjdC5rZXlzKHByZXJlbmRlck1hbmlmZXN0LnJvdXRlcykuc29tZShcbiAgICAgIChrZXkpID0+IHR5cGVvZiBwcmVyZW5kZXJNYW5pZmVzdC5yb3V0ZXNba2V5XS5pbml0aWFsUmV2YWxpZGF0ZVNlY29uZHMgPT09ICdudW1iZXInLFxuICAgIClcbiAgaWYgKGhhc0lTUlBhZ2VzKSB7XG4gICAgcmVnZW5lcmF0aW9uTGFtYmRhUGF0aCA9IGF3YWl0IHppcExhbWJkYSgncmVnZW5lcmF0aW9uLWxhbWJkYScpXG4gIH1cblxuICBjb25zdCBhc3NldHNEaXIgPSBwYXRoLmpvaW4oYnVpbGREaXIsICdhc3NldHMnKVxuICBjb25zdCBhc3NldHMgPSByZWFkQXNzZXRzRGlyZWN0b3J5KGFzc2V0c0RpcilcblxuICByZXR1cm4ge1xuICAgIGxhbWJkYUJ1aWxkRGlyLFxuICAgIGRlZmF1bHRMYW1iZGFQYXRoLFxuICAgIGFwaUxhbWJkYVBhdGgsXG4gICAgaW1hZ2VMYW1iZGFQYXRoLFxuICAgIHJlZ2VuZXJhdGlvbkxhbWJkYVBhdGgsXG4gICAgYXNzZXRzLFxuICAgIGltYWdlUGF0aDogaGFzSW1hZ2VzID8gcGF0aFBhdHRlcm4oJ19uZXh0L2ltYWdlKicpIDogdW5kZWZpbmVkLFxuICAgIGRhdGFQYXRoOiBwYXRoUGF0dGVybignX25leHQvZGF0YS8qJyksXG4gICAgYmFzZVBhdGg6IHBhdGhQYXR0ZXJuKCdfbmV4dC8qJyksXG4gICAgc3RhdGljUGF0aDogcGF0aFBhdHRlcm4oJ3N0YXRpYy8qJyksXG4gICAgYXBpUGF0aDogaGFzQXBpID8gcGF0aFBhdHRlcm4oJ2FwaS8qJykgOiB1bmRlZmluZWQsXG4gICAgaW52YWxpZGF0aW9uUGF0aHM6IGRlZmF1bHRNYW5pZmVzdFxuICAgICAgPyByZWR1Y2VJbnZhbGlkYXRpb25QYXRocyhyZWFkSW52YWxpZGF0aW9uUGF0aHNGcm9tTWFuaWZlc3QoZGVmYXVsdE1hbmlmZXN0KSlcbiAgICAgIDogdW5kZWZpbmVkLFxuICB9XG59XG4iXX0=