UNPKG

@nlabs/lex

Version:
277 lines (276 loc) 38.5 kB
/** * Copyright (c) 2018-Present, Nitrogen Labs, Inc. * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. */ import { transform } from '@swc/core'; import { execa } from 'execa'; import { existsSync, lstatSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'fs'; import { sync as globSync } from 'glob'; import { extname as pathExtname, join as pathJoin, relative as pathRelative, resolve as pathResolve, dirname } from 'path'; import { LexConfig } from '../../LexConfig.js'; import { checkLinkedModules, copyConfiguredFiles, copyFiles, createSpinner, getFilesByExt, removeFiles } from '../../utils/app.js'; import { getDirName, resolveBinaryPath } from '../../utils/file.js'; import { log } from '../../utils/log.js'; export const hasFileType = (startPath, ext)=>{ if (!existsSync(startPath)) { return false; } const files = readdirSync(startPath); return files.some((file)=>{ const filename = pathJoin(startPath, file); const fileExt = pathExtname(filename); const stat = lstatSync(filename); if (stat.isDirectory()) { return hasFileType(filename, ext); } return ext.includes(fileExt); }); }; export const compile = async (cmd, callback = ()=>({}))=>{ const { cliName = 'Lex', config, format = 'esm', outputPath, quiet, remove, sourcePath, watch } = cmd; const spinner = createSpinner(quiet); log(`${cliName} compiling...`, 'info', quiet); await LexConfig.parseConfig(cmd); const { outputFullPath, sourceFullPath, swc: swcConfig, useTypescript } = LexConfig.config; const outputDir = outputPath ? pathResolve(process.cwd(), outputPath) : outputFullPath || pathResolve(process.cwd(), './lib'); const sourceDir = sourcePath ? pathResolve(process.cwd(), `./${sourcePath}`) : sourceFullPath || ''; const dirName = getDirName(); checkLinkedModules(); if (remove) { await removeFiles(outputDir); } if (useTypescript) { const typescriptPath = resolveBinaryPath('tsc', 'typescript'); if (!typescriptPath) { log(`\n${cliName} Error: TypeScript binary not found in Lex's node_modules or monorepo root`, 'error', quiet); log('Please reinstall Lex or check your installation.', 'info', quiet); return 1; } const typescriptOptions = config ? [ '-p', config, '--emitDeclarationOnly', '--skipLibCheck' ] // User provided custom config, but still only emit declarations : (()=>{ const globOptions = { absolute: true, cwd: sourceDir, dot: false, nodir: true }; const tsFiles = globSync('**/!(*.spec|*.test|*.integration).ts', globOptions); const tsxFiles = globSync('**/!(*.spec|*.test|*.integration).tsx', globOptions); const allSourceFiles = [ ...tsFiles, ...tsxFiles ]; return [ ...LexConfig.getTypeScriptDeclarationFlags(), ...allSourceFiles ]; })(); spinner.start('Generating TypeScript declarations...'); try { const result = await execa(typescriptPath, typescriptOptions, { all: true, cwd: process.cwd(), encoding: 'utf8', reject: false }); if (result.exitCode !== 0) { const hasDeclarations = result.all?.includes('Writing') || result.all?.includes('Declaration') || false; const errorOutput = result.stderr || result.stdout || result.all || 'Unknown error'; if (!hasDeclarations) { log(`\n${cliName} Error: TypeScript declaration generation failed`, 'error', quiet); log(`\nExit Code: ${result.exitCode}`, 'error', quiet); log(`\nTypeScript Command: ${typescriptPath} ${typescriptOptions.join(' ')}`, 'error', quiet); log(`\nError Output:\n${errorOutput}`, 'error', quiet); const errorLines = errorOutput.split('\n').filter((line)=>line.includes('error TS') || line.includes('Error:') || line.trim().startsWith('src/') || line.trim().startsWith('TS')); if (errorLines.length > 0) { log('\nKey Errors:', 'error', quiet); errorLines.slice(0, 10).forEach((line)=>{ log(` ${line}`, 'error', quiet); }); if (errorLines.length > 10) { log(` ... and ${errorLines.length - 10} more errors`, 'error', quiet); } } spinner.fail('TypeScript declaration generation failed.'); } else { log(`\n${cliName} Warning: TypeScript declaration generation completed with errors`, 'warn', quiet); if (!quiet && errorOutput) { log(`\nWarnings:\n${errorOutput}`, 'warn', quiet); } spinner.succeed('TypeScript declarations generated (with warnings).'); } } else { spinner.succeed('Successfully generated TypeScript declarations!'); } } catch (error) { log(`\n${cliName} Error: TypeScript declaration generation exception`, 'error', quiet); log(`\nError: ${error.message}`, 'error', quiet); if (error instanceof Error && error.stack) { log(`\nStack:\n${error.stack}`, 'error', quiet); } spinner.fail('TypeScript declaration generation had issues, continuing...'); } } const globOptions = { absolute: true, cwd: sourceDir, dot: false, nodir: true, nosort: true }; const tsFiles = globSync('**/!(*.spec|*.test|*.integration).ts*', globOptions); const jsFiles = globSync('**/!(*.spec|*.test|*.integration).js', globOptions); const sourceFiles = [ ...tsFiles, ...jsFiles ]; const cssFiles = getFilesByExt('.css', LexConfig.config); if (cssFiles.length) { const postcssPath = resolveBinaryPath('postcss', 'postcss-cli'); if (!postcssPath) { log(`\n${cliName} Error: PostCSS binary not found in Lex's node_modules or monorepo root`, 'error', quiet); log('Please reinstall Lex or check your installation.', 'info', quiet); return 1; } const postcssOptions = [ `${sourceDir}/**/**.css`, '--base', sourceDir, '--dir', outputDir, '--config', pathResolve(dirName, '../../postcss.config.js') ]; try { await execa(postcssPath, postcssOptions, { encoding: 'utf8' }); spinner.succeed(`Successfully formatted ${cssFiles.length} css files!`); } catch (error) { log(`\n${cliName} Error: ${error.message}`, 'error', quiet); spinner.fail('Failed formatting css.'); callback(1); return 1; } } const gifFiles = getFilesByExt('.gif', LexConfig.config); const jpgFiles = getFilesByExt('.jpg', LexConfig.config); const pngFiles = getFilesByExt('.png', LexConfig.config); const svgFiles = getFilesByExt('.svg', LexConfig.config); const imageFiles = [ ...gifFiles, ...jpgFiles, ...pngFiles, ...svgFiles ]; if (imageFiles.length) { try { await copyFiles(imageFiles, 'image', spinner, LexConfig.config); } catch (error) { log(`\n${cliName} Error: ${error.message}`, 'error', quiet); spinner.fail('Failed to move images to output directory.'); callback(1); return 1; } } const ttfFiles = getFilesByExt('.ttf', LexConfig.config); const otfFiles = getFilesByExt('.otf', LexConfig.config); const woffFiles = getFilesByExt('.woff', LexConfig.config); const woff2Files = getFilesByExt('.woff2', LexConfig.config); const fontFiles = [ ...ttfFiles, ...otfFiles, ...woffFiles, ...woff2Files ]; if (fontFiles.length) { try { await copyFiles(fontFiles, 'font', spinner, LexConfig.config); } catch (error) { log(`\n${cliName} Error: ${error.message}`, 'error', quiet); spinner.fail('Failed to move fonts to output directory.'); callback(1); return 1; } } const mdFiles = getFilesByExt('.md', LexConfig.config); if (mdFiles.length) { try { await copyFiles(mdFiles, 'documents', spinner, LexConfig.config); } catch (error) { log(`\n${cliName} Error: ${error.message}`, 'error', quiet); spinner.fail('Failed to move docs to output directory.'); callback(1); return 1; } } if (sourceFiles.length === 0) { log(`\n${cliName} Warning: No source files found to compile in ${sourceDir}`, 'warn', quiet); spinner.succeed('No files to compile.'); callback(0); return 0; } spinner.start(watch ? 'Watching for changes...' : 'Compiling with SWC...'); try { const transformPromises = sourceFiles.map(async (file)=>{ const fileRelativeToSource = pathRelative(sourceDir, file); const sourcePath = file; const outputFile = fileRelativeToSource.replace(/\.(ts|tsx)$/, '.js'); const outputPath = pathResolve(outputDir, outputFile); const outputDirPath = dirname(outputPath); if (!existsSync(outputDirPath)) { mkdirSync(outputDirPath, { recursive: true }); } const sourceCode = readFileSync(sourcePath, 'utf8'); const isTSX = file.endsWith('.tsx'); const swcOptions = { ...swcConfig, filename: file, module: { type: format === 'cjs' ? 'commonjs' : swcConfig?.module?.type || 'es6', ...swcConfig?.module }, sourceMaps: swcConfig?.sourceMaps || 'inline' }; const result = await transform(sourceCode, swcOptions); writeFileSync(outputPath, result.code); }); await Promise.all(transformPromises); spinner.succeed('Compile completed successfully!'); } catch (error) { log(`\n${cliName} Error: SWC compilation failed`, 'error', quiet); log(`\nError: ${error.message}`, 'error', quiet); if (error instanceof Error) { if (error.stack) { log(`\nStack Trace:\n${error.stack}`, 'error', quiet); } if ('filename' in error || 'file' in error) { log(`\nFile: ${error.filename || error.file}`, 'error', quiet); } } if (!quiet) { // eslint-disable-next-line no-console console.error('\nFull Error Details:', error); } spinner.fail('Code compiling failed.'); callback(1); return 1; } try { await copyConfiguredFiles(spinner, LexConfig.config, quiet); } catch (copyError) { log(`\n${cliName} Error: Failed to copy configured files: ${copyError.message}`, 'error', quiet); spinner.fail('Failed to copy configured files.'); callback(1); return 1; } callback(0); return 0; }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jb21tYW5kcy9jb21waWxlL2NvbXBpbGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7dHJhbnNmb3JtfSBmcm9tICdAc3djL2NvcmUnO1xuaW1wb3J0IHtleGVjYX0gZnJvbSAnZXhlY2EnO1xuaW1wb3J0IHtleGlzdHNTeW5jLCBsc3RhdFN5bmMsIHJlYWRkaXJTeW5jLCByZWFkRmlsZVN5bmMsIHdyaXRlRmlsZVN5bmMsIG1rZGlyU3luY30gZnJvbSAnZnMnO1xuaW1wb3J0IHtzeW5jIGFzIGdsb2JTeW5jfSBmcm9tICdnbG9iJztcbmltcG9ydCB7ZXh0bmFtZSBhcyBwYXRoRXh0bmFtZSwgam9pbiBhcyBwYXRoSm9pbiwgcmVsYXRpdmUgYXMgcGF0aFJlbGF0aXZlLCByZXNvbHZlIGFzIHBhdGhSZXNvbHZlLCBkaXJuYW1lfSBmcm9tICdwYXRoJztcblxuaW1wb3J0IHtMZXhDb25maWd9IGZyb20gJy4uLy4uL0xleENvbmZpZy5qcyc7XG5pbXBvcnQge2NoZWNrTGlua2VkTW9kdWxlcywgY29weUNvbmZpZ3VyZWRGaWxlcywgY29weUZpbGVzLCBjcmVhdGVTcGlubmVyLCBnZXRGaWxlc0J5RXh0LCByZW1vdmVGaWxlc30gZnJvbSAnLi4vLi4vdXRpbHMvYXBwLmpzJztcbmltcG9ydCB7Z2V0RGlyTmFtZSwgcmVzb2x2ZUJpbmFyeVBhdGh9IGZyb20gJy4uLy4uL3V0aWxzL2ZpbGUuanMnO1xuaW1wb3J0IHtsb2d9IGZyb20gJy4uLy4uL3V0aWxzL2xvZy5qcyc7XG5cbmltcG9ydCB0eXBlIHtTV0NPcHRpb25zfSBmcm9tICcuLi8uLi9MZXhDb25maWcuanMnO1xuXG5leHBvcnQgY29uc3QgaGFzRmlsZVR5cGUgPSAoc3RhcnRQYXRoOiBzdHJpbmcsIGV4dDogc3RyaW5nW10pOiBib29sZWFuID0+IHtcbiAgaWYoIWV4aXN0c1N5bmMoc3RhcnRQYXRoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IGZpbGVzOiBzdHJpbmdbXSA9IHJlYWRkaXJTeW5jKHN0YXJ0UGF0aCk7XG5cbiAgcmV0dXJuIGZpbGVzLnNvbWUoKGZpbGU6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IGZpbGVuYW1lOiBzdHJpbmcgPSBwYXRoSm9pbihzdGFydFBhdGgsIGZpbGUpO1xuICAgIGNvbnN0IGZpbGVFeHQ6IHN0cmluZyA9IHBhdGhFeHRuYW1lKGZpbGVuYW1lKTtcbiAgICBjb25zdCBzdGF0ID0gbHN0YXRTeW5jKGZpbGVuYW1lKTtcblxuICAgIGlmKHN0YXQuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgcmV0dXJuIGhhc0ZpbGVUeXBlKGZpbGVuYW1lLCBleHQpO1xuICAgIH1cblxuICAgIHJldHVybiBleHQuaW5jbHVkZXMoZmlsZUV4dCk7XG4gIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGNvbXBpbGUgPSBhc3luYyAoY21kOiBhbnksIGNhbGxiYWNrOiBhbnkgPSAoKSA9PiAoe30pKTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgY29uc3Qge1xuICAgIGNsaU5hbWUgPSAnTGV4JyxcbiAgICBjb25maWcsXG4gICAgZm9ybWF0ID0gJ2VzbScsXG4gICAgb3V0cHV0UGF0aCxcbiAgICBxdWlldCxcbiAgICByZW1vdmUsXG4gICAgc291cmNlUGF0aCxcbiAgICB3YXRjaFxuICB9ID0gY21kO1xuICBjb25zdCBzcGlubmVyID0gY3JlYXRlU3Bpbm5lcihxdWlldCk7XG5cbiAgbG9nKGAke2NsaU5hbWV9IGNvbXBpbGluZy4uLmAsICdpbmZvJywgcXVpZXQpO1xuXG4gIGF3YWl0IExleENvbmZpZy5wYXJzZUNvbmZpZyhjbWQpO1xuXG4gIGNvbnN0IHtvdXRwdXRGdWxsUGF0aCwgc291cmNlRnVsbFBhdGgsIHN3Yzogc3djQ29uZmlnLCB1c2VUeXBlc2NyaXB0fSA9IExleENvbmZpZy5jb25maWc7XG4gIGNvbnN0IG91dHB1dERpcjogc3RyaW5nID0gb3V0cHV0UGF0aFxuICAgID8gcGF0aFJlc29sdmUocHJvY2Vzcy5jd2QoKSwgb3V0cHV0UGF0aClcbiAgICA6IChvdXRwdXRGdWxsUGF0aCB8fCBwYXRoUmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnLi9saWInKSk7XG4gIGNvbnN0IHNvdXJjZURpcjogc3RyaW5nID0gc291cmNlUGF0aCA/IHBhdGhSZXNvbHZlKHByb2Nlc3MuY3dkKCksIGAuLyR7c291cmNlUGF0aH1gKSA6IHNvdXJjZUZ1bGxQYXRoIHx8ICcnO1xuICBjb25zdCBkaXJOYW1lID0gZ2V0RGlyTmFtZSgpO1xuXG4gIGNoZWNrTGlua2VkTW9kdWxlcygpO1xuXG4gIGlmKHJlbW92ZSkge1xuICAgIGF3YWl0IHJlbW92ZUZpbGVzKG91dHB1dERpcik7XG4gIH1cblxuICBpZih1c2VUeXBlc2NyaXB0KSB7XG4gICAgY29uc3QgdHlwZXNjcmlwdFBhdGg6IHN0cmluZyA9IHJlc29sdmVCaW5hcnlQYXRoKCd0c2MnLCAndHlwZXNjcmlwdCcpO1xuXG4gICAgaWYoIXR5cGVzY3JpcHRQYXRoKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IFR5cGVTY3JpcHQgYmluYXJ5IG5vdCBmb3VuZCBpbiBMZXgncyBub2RlX21vZHVsZXMgb3IgbW9ub3JlcG8gcm9vdGAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgIGxvZygnUGxlYXNlIHJlaW5zdGFsbCBMZXggb3IgY2hlY2sgeW91ciBpbnN0YWxsYXRpb24uJywgJ2luZm8nLCBxdWlldCk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG5cbiAgICBjb25zdCB0eXBlc2NyaXB0T3B0aW9uczogc3RyaW5nW10gPSBjb25maWdcbiAgICAgID8gWyctcCcsIGNvbmZpZywgJy0tZW1pdERlY2xhcmF0aW9uT25seScsICctLXNraXBMaWJDaGVjayddIC8vIFVzZXIgcHJvdmlkZWQgY3VzdG9tIGNvbmZpZywgYnV0IHN0aWxsIG9ubHkgZW1pdCBkZWNsYXJhdGlvbnNcbiAgICAgIDogKCgpID0+IHtcbiAgICAgICAgY29uc3QgZ2xvYk9wdGlvbnMgPSB7XG4gICAgICAgICAgYWJzb2x1dGU6IHRydWUsXG4gICAgICAgICAgY3dkOiBzb3VyY2VEaXIsXG4gICAgICAgICAgZG90OiBmYWxzZSxcbiAgICAgICAgICBub2RpcjogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB0c0ZpbGVzID0gZ2xvYlN5bmMoJyoqLyEoKi5zcGVjfCoudGVzdHwqLmludGVncmF0aW9uKS50cycsIGdsb2JPcHRpb25zKTtcbiAgICAgICAgY29uc3QgdHN4RmlsZXMgPSBnbG9iU3luYygnKiovISgqLnNwZWN8Ki50ZXN0fCouaW50ZWdyYXRpb24pLnRzeCcsIGdsb2JPcHRpb25zKTtcbiAgICAgICAgY29uc3QgYWxsU291cmNlRmlsZXMgPSBbLi4udHNGaWxlcywgLi4udHN4RmlsZXNdO1xuXG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgLi4uTGV4Q29uZmlnLmdldFR5cGVTY3JpcHREZWNsYXJhdGlvbkZsYWdzKCksXG4gICAgICAgICAgLi4uYWxsU291cmNlRmlsZXNcbiAgICAgICAgXTtcbiAgICAgIH0pKCk7XG5cbiAgICBzcGlubmVyLnN0YXJ0KCdHZW5lcmF0aW5nIFR5cGVTY3JpcHQgZGVjbGFyYXRpb25zLi4uJyk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZXhlY2EodHlwZXNjcmlwdFBhdGgsIHR5cGVzY3JpcHRPcHRpb25zLCB7XG4gICAgICAgIGFsbDogdHJ1ZSxcbiAgICAgICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgICAgICByZWplY3Q6IGZhbHNlXG4gICAgICB9KTtcblxuICAgICAgaWYocmVzdWx0LmV4aXRDb2RlICE9PSAwKSB7XG4gICAgICAgIGNvbnN0IGhhc0RlY2xhcmF0aW9ucyA9IHJlc3VsdC5hbGw/LmluY2x1ZGVzKCdXcml0aW5nJykgfHwgcmVzdWx0LmFsbD8uaW5jbHVkZXMoJ0RlY2xhcmF0aW9uJykgfHwgZmFsc2U7XG4gICAgICAgIGNvbnN0IGVycm9yT3V0cHV0ID0gcmVzdWx0LnN0ZGVyciB8fCByZXN1bHQuc3Rkb3V0IHx8IHJlc3VsdC5hbGwgfHwgJ1Vua25vd24gZXJyb3InO1xuXG4gICAgICAgIGlmKCFoYXNEZWNsYXJhdGlvbnMpIHtcbiAgICAgICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IFR5cGVTY3JpcHQgZGVjbGFyYXRpb24gZ2VuZXJhdGlvbiBmYWlsZWRgLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICAgICAgbG9nKGBcXG5FeGl0IENvZGU6ICR7cmVzdWx0LmV4aXRDb2RlfWAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgICAgICBsb2coYFxcblR5cGVTY3JpcHQgQ29tbWFuZDogJHt0eXBlc2NyaXB0UGF0aH0gJHt0eXBlc2NyaXB0T3B0aW9ucy5qb2luKCcgJyl9YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgICAgICAgIGxvZyhgXFxuRXJyb3IgT3V0cHV0OlxcbiR7ZXJyb3JPdXRwdXR9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICAgICAgY29uc3QgZXJyb3JMaW5lcyA9IGVycm9yT3V0cHV0LnNwbGl0KCdcXG4nKS5maWx0ZXIoKGxpbmUpID0+XG4gICAgICAgICAgICBsaW5lLmluY2x1ZGVzKCdlcnJvciBUUycpIHx8XG4gICAgICAgICAgICBsaW5lLmluY2x1ZGVzKCdFcnJvcjonKSB8fFxuICAgICAgICAgICAgbGluZS50cmltKCkuc3RhcnRzV2l0aCgnc3JjLycpIHx8XG4gICAgICAgICAgICBsaW5lLnRyaW0oKS5zdGFydHNXaXRoKCdUUycpXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmKGVycm9yTGluZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgbG9nKCdcXG5LZXkgRXJyb3JzOicsICdlcnJvcicsIHF1aWV0KTtcblxuICAgICAgICAgICAgZXJyb3JMaW5lcy5zbGljZSgwLCAxMCkuZm9yRWFjaCgobGluZSkgPT4ge1xuICAgICAgICAgICAgICBsb2coYCAgJHtsaW5lfWAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZihlcnJvckxpbmVzLmxlbmd0aCA+IDEwKSB7XG4gICAgICAgICAgICAgIGxvZyhgICAuLi4gYW5kICR7ZXJyb3JMaW5lcy5sZW5ndGggLSAxMH0gbW9yZSBlcnJvcnNgLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgc3Bpbm5lci5mYWlsKCdUeXBlU2NyaXB0IGRlY2xhcmF0aW9uIGdlbmVyYXRpb24gZmFpbGVkLicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBXYXJuaW5nOiBUeXBlU2NyaXB0IGRlY2xhcmF0aW9uIGdlbmVyYXRpb24gY29tcGxldGVkIHdpdGggZXJyb3JzYCwgJ3dhcm4nLCBxdWlldCk7XG5cbiAgICAgICAgICBpZighcXVpZXQgJiYgZXJyb3JPdXRwdXQpIHtcbiAgICAgICAgICAgIGxvZyhgXFxuV2FybmluZ3M6XFxuJHtlcnJvck91dHB1dH1gLCAnd2FybicsIHF1aWV0KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzcGlubmVyLnN1Y2NlZWQoJ1R5cGVTY3JpcHQgZGVjbGFyYXRpb25zIGdlbmVyYXRlZCAod2l0aCB3YXJuaW5ncykuJyk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNwaW5uZXIuc3VjY2VlZCgnU3VjY2Vzc2Z1bGx5IGdlbmVyYXRlZCBUeXBlU2NyaXB0IGRlY2xhcmF0aW9ucyEnKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IFR5cGVTY3JpcHQgZGVjbGFyYXRpb24gZ2VuZXJhdGlvbiBleGNlcHRpb25gLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICBsb2coYFxcbkVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBpZihlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLnN0YWNrKSB7XG4gICAgICAgIGxvZyhgXFxuU3RhY2s6XFxuJHtlcnJvci5zdGFja31gLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIHNwaW5uZXIuZmFpbCgnVHlwZVNjcmlwdCBkZWNsYXJhdGlvbiBnZW5lcmF0aW9uIGhhZCBpc3N1ZXMsIGNvbnRpbnVpbmcuLi4nKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBnbG9iT3B0aW9ucyA9IHtcbiAgICBhYnNvbHV0ZTogdHJ1ZSxcbiAgICBjd2Q6IHNvdXJjZURpcixcbiAgICBkb3Q6IGZhbHNlLFxuICAgIG5vZGlyOiB0cnVlLFxuICAgIG5vc29ydDogdHJ1ZVxuICB9O1xuICBjb25zdCB0c0ZpbGVzOiBzdHJpbmdbXSA9IGdsb2JTeW5jKCcqKi8hKCouc3BlY3wqLnRlc3R8Ki5pbnRlZ3JhdGlvbikudHMqJywgZ2xvYk9wdGlvbnMpO1xuICBjb25zdCBqc0ZpbGVzOiBzdHJpbmdbXSA9IGdsb2JTeW5jKCcqKi8hKCouc3BlY3wqLnRlc3R8Ki5pbnRlZ3JhdGlvbikuanMnLCBnbG9iT3B0aW9ucyk7XG4gIGNvbnN0IHNvdXJjZUZpbGVzOiBzdHJpbmdbXSA9IFsuLi50c0ZpbGVzLCAuLi5qc0ZpbGVzXTtcblxuICBjb25zdCBjc3NGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcuY3NzJywgTGV4Q29uZmlnLmNvbmZpZyk7XG5cbiAgaWYoY3NzRmlsZXMubGVuZ3RoKSB7XG4gICAgY29uc3QgcG9zdGNzc1BhdGg6IHN0cmluZyA9IHJlc29sdmVCaW5hcnlQYXRoKCdwb3N0Y3NzJywgJ3Bvc3Rjc3MtY2xpJyk7XG5cbiAgICBpZighcG9zdGNzc1BhdGgpIHtcbiAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogUG9zdENTUyBiaW5hcnkgbm90IGZvdW5kIGluIExleCdzIG5vZGVfbW9kdWxlcyBvciBtb25vcmVwbyByb290YCwgJ2Vycm9yJywgcXVpZXQpO1xuICAgICAgbG9nKCdQbGVhc2UgcmVpbnN0YWxsIExleCBvciBjaGVjayB5b3VyIGluc3RhbGxhdGlvbi4nLCAnaW5mbycsIHF1aWV0KTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIGNvbnN0IHBvc3Rjc3NPcHRpb25zOiBzdHJpbmdbXSA9IFtcbiAgICAgIGAke3NvdXJjZURpcn0vKiovKiouY3NzYCxcbiAgICAgICctLWJhc2UnLFxuICAgICAgc291cmNlRGlyLFxuICAgICAgJy0tZGlyJyxcbiAgICAgIG91dHB1dERpcixcbiAgICAgICctLWNvbmZpZycsXG4gICAgICBwYXRoUmVzb2x2ZShkaXJOYW1lLCAnLi4vLi4vcG9zdGNzcy5jb25maWcuanMnKVxuICAgIF07XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgZXhlY2EocG9zdGNzc1BhdGgsIHBvc3Rjc3NPcHRpb25zLCB7ZW5jb2Rpbmc6ICd1dGY4J30pO1xuICAgICAgc3Bpbm5lci5zdWNjZWVkKGBTdWNjZXNzZnVsbHkgZm9ybWF0dGVkICR7Y3NzRmlsZXMubGVuZ3RofSBjc3MgZmlsZXMhYCk7XG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCBmb3JtYXR0aW5nIGNzcy4nKTtcblxuICAgICAgY2FsbGJhY2soMSk7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBnaWZGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcuZ2lmJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IGpwZ0ZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy5qcGcnLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3QgcG5nRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLnBuZycsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCBzdmdGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcuc3ZnJywgTGV4Q29uZmlnLmNvbmZpZyk7XG4gIGNvbnN0IGltYWdlRmlsZXM6IHN0cmluZ1tdID0gWy4uLmdpZkZpbGVzLCAuLi5qcGdGaWxlcywgLi4ucG5nRmlsZXMsIC4uLnN2Z0ZpbGVzXTtcblxuICBpZihpbWFnZUZpbGVzLmxlbmd0aCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjb3B5RmlsZXMoaW1hZ2VGaWxlcywgJ2ltYWdlJywgc3Bpbm5lciwgTGV4Q29uZmlnLmNvbmZpZyk7XG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgbG9nKGBcXG4ke2NsaU5hbWV9IEVycm9yOiAke2Vycm9yLm1lc3NhZ2V9YCwgJ2Vycm9yJywgcXVpZXQpO1xuXG4gICAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCB0byBtb3ZlIGltYWdlcyB0byBvdXRwdXQgZGlyZWN0b3J5LicpO1xuXG4gICAgICBjYWxsYmFjaygxKTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHR0ZkZpbGVzOiBzdHJpbmdbXSA9IGdldEZpbGVzQnlFeHQoJy50dGYnLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3Qgb3RmRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLm90ZicsIExleENvbmZpZy5jb25maWcpO1xuICBjb25zdCB3b2ZmRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLndvZmYnLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3Qgd29mZjJGaWxlczogc3RyaW5nW10gPSBnZXRGaWxlc0J5RXh0KCcud29mZjInLCBMZXhDb25maWcuY29uZmlnKTtcbiAgY29uc3QgZm9udEZpbGVzOiBzdHJpbmdbXSA9IFsuLi50dGZGaWxlcywgLi4ub3RmRmlsZXMsIC4uLndvZmZGaWxlcywgLi4ud29mZjJGaWxlc107XG5cbiAgaWYoZm9udEZpbGVzLmxlbmd0aCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjb3B5RmlsZXMoZm9udEZpbGVzLCAnZm9udCcsIHNwaW5uZXIsIExleENvbmZpZy5jb25maWcpO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgICAgc3Bpbm5lci5mYWlsKCdGYWlsZWQgdG8gbW92ZSBmb250cyB0byBvdXRwdXQgZGlyZWN0b3J5LicpO1xuXG4gICAgICBjYWxsYmFjaygxKTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG1kRmlsZXM6IHN0cmluZ1tdID0gZ2V0RmlsZXNCeUV4dCgnLm1kJywgTGV4Q29uZmlnLmNvbmZpZyk7XG5cbiAgaWYobWRGaWxlcy5sZW5ndGgpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29weUZpbGVzKG1kRmlsZXMsICdkb2N1bWVudHMnLCBzcGlubmVyLCBMZXhDb25maWcuY29uZmlnKTtcbiAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6ICR7ZXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICAgIHNwaW5uZXIuZmFpbCgnRmFpbGVkIHRvIG1vdmUgZG9jcyB0byBvdXRwdXQgZGlyZWN0b3J5LicpO1xuXG4gICAgICBjYWxsYmFjaygxKTtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfVxuXG4gIGlmKHNvdXJjZUZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBXYXJuaW5nOiBObyBzb3VyY2UgZmlsZXMgZm91bmQgdG8gY29tcGlsZSBpbiAke3NvdXJjZURpcn1gLCAnd2FybicsIHF1aWV0KTtcbiAgICBzcGlubmVyLnN1Y2NlZWQoJ05vIGZpbGVzIHRvIGNvbXBpbGUuJyk7XG4gICAgY2FsbGJhY2soMCk7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBzcGlubmVyLnN0YXJ0KHdhdGNoID8gJ1dhdGNoaW5nIGZvciBjaGFuZ2VzLi4uJyA6ICdDb21waWxpbmcgd2l0aCBTV0MuLi4nKTtcblxuICB0cnkge1xuICAgIGNvbnN0IHRyYW5zZm9ybVByb21pc2VzID0gc291cmNlRmlsZXMubWFwKGFzeW5jIChmaWxlKSA9PiB7XG4gICAgICBjb25zdCBmaWxlUmVsYXRpdmVUb1NvdXJjZSA9IHBhdGhSZWxhdGl2ZShzb3VyY2VEaXIsIGZpbGUpO1xuICAgICAgY29uc3Qgc291cmNlUGF0aCA9IGZpbGU7XG4gICAgICBjb25zdCBvdXRwdXRGaWxlID0gZmlsZVJlbGF0aXZlVG9Tb3VyY2UucmVwbGFjZSgvXFwuKHRzfHRzeCkkLywgJy5qcycpO1xuICAgICAgY29uc3Qgb3V0cHV0UGF0aCA9IHBhdGhSZXNvbHZlKG91dHB1dERpciwgb3V0cHV0RmlsZSk7XG4gICAgICBjb25zdCBvdXRwdXREaXJQYXRoID0gZGlybmFtZShvdXRwdXRQYXRoKTtcblxuICAgICAgaWYoIWV4aXN0c1N5bmMob3V0cHV0RGlyUGF0aCkpIHtcbiAgICAgICAgbWtkaXJTeW5jKG91dHB1dERpclBhdGgsIHtyZWN1cnNpdmU6IHRydWV9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgc291cmNlQ29kZSA9IHJlYWRGaWxlU3luYyhzb3VyY2VQYXRoLCAndXRmOCcpO1xuICAgICAgY29uc3QgaXNUU1ggPSBmaWxlLmVuZHNXaXRoKCcudHN4Jyk7XG4gICAgICBjb25zdCBzd2NPcHRpb25zOiBQYXJ0aWFsPFNXQ09wdGlvbnM+ID0ge1xuICAgICAgICAuLi5zd2NDb25maWcsXG4gICAgICAgIGZpbGVuYW1lOiBmaWxlLFxuICAgICAgICBtb2R1bGU6IHtcbiAgICAgICAgICB0eXBlOiBmb3JtYXQgPT09ICdjanMnID8gJ2NvbW1vbmpzJyBhcyBjb25zdCA6IChzd2NDb25maWc/Lm1vZHVsZT8udHlwZSBhcyAnZXM2JyB8fCAnZXM2JyksXG4gICAgICAgICAgLi4uc3djQ29uZmlnPy5tb2R1bGVcbiAgICAgICAgfSxcbiAgICAgICAgc291cmNlTWFwczogc3djQ29uZmlnPy5zb3VyY2VNYXBzIHx8ICdpbmxpbmUnXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0cmFuc2Zvcm0oc291cmNlQ29kZSwgc3djT3B0aW9ucyk7XG5cbiAgICAgIHdyaXRlRmlsZVN5bmMob3V0cHV0UGF0aCwgcmVzdWx0LmNvZGUpO1xuICAgIH0pO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwodHJhbnNmb3JtUHJvbWlzZXMpO1xuXG4gICAgc3Bpbm5lci5zdWNjZWVkKCdDb21waWxlIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkhJyk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2coYFxcbiR7Y2xpTmFtZX0gRXJyb3I6IFNXQyBjb21waWxhdGlvbiBmYWlsZWRgLCAnZXJyb3InLCBxdWlldCk7XG4gICAgbG9nKGBcXG5FcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsICdlcnJvcicsIHF1aWV0KTtcblxuICAgIGlmKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGlmKGVycm9yLnN0YWNrKSB7XG4gICAgICAgIGxvZyhgXFxuU3RhY2sgVHJhY2U6XFxuJHtlcnJvci5zdGFja31gLCAnZXJyb3InLCBxdWlldCk7XG4gICAgICB9XG5cbiAgICAgIGlmKCdmaWxlbmFtZScgaW4gZXJyb3IgfHwgJ2ZpbGUnIGluIGVycm9yKSB7XG4gICAgICAgIGxvZyhgXFxuRmlsZTogJHsoZXJyb3IgYXMgYW55KS5maWxlbmFtZSB8fCAoZXJyb3IgYXMgYW55KS5maWxlfWAsICdlcnJvcicsIHF1aWV0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZighcXVpZXQpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBjb25zb2xlLmVycm9yKCdcXG5GdWxsIEVycm9yIERldGFpbHM6JywgZXJyb3IpO1xuICAgIH1cblxuICAgIHNwaW5uZXIuZmFpbCgnQ29kZSBjb21waWxpbmcgZmFpbGVkLicpO1xuXG4gICAgY2FsbGJhY2soMSk7XG4gICAgcmV0dXJuIDE7XG4gIH1cblxuICB0cnkge1xuICAgIGF3YWl0IGNvcHlDb25maWd1cmVkRmlsZXMoc3Bpbm5lciwgTGV4Q29uZmlnLmNvbmZpZywgcXVpZXQpO1xuICB9IGNhdGNoKGNvcHlFcnJvcikge1xuICAgIGxvZyhgXFxuJHtjbGlOYW1lfSBFcnJvcjogRmFpbGVkIHRvIGNvcHkgY29uZmlndXJlZCBmaWxlczogJHtjb3B5RXJyb3IubWVzc2FnZX1gLCAnZXJyb3InLCBxdWlldCk7XG5cbiAgICBzcGlubmVyLmZhaWwoJ0ZhaWxlZCB0byBjb3B5IGNvbmZpZ3VyZWQgZmlsZXMuJyk7XG5cbiAgICBjYWxsYmFjaygxKTtcbiAgICByZXR1cm4gMTtcbiAgfVxuXG4gIGNhbGxiYWNrKDApO1xuICByZXR1cm4gMDtcbn07Il0sIm5hbWVzIjpbInRyYW5zZm9ybSIsImV4ZWNhIiwiZXhpc3RzU3luYyIsImxzdGF0U3luYyIsInJlYWRkaXJTeW5jIiwicmVhZEZpbGVTeW5jIiwid3JpdGVGaWxlU3luYyIsIm1rZGlyU3luYyIsInN5bmMiLCJnbG9iU3luYyIsImV4dG5hbWUiLCJwYXRoRXh0bmFtZSIsImpvaW4iLCJwYXRoSm9pbiIsInJlbGF0aXZlIiwicGF0aFJlbGF0aXZlIiwicmVzb2x2ZSIsInBhdGhSZXNvbHZlIiwiZGlybmFtZSIsIkxleENvbmZpZyIsImNoZWNrTGlua2VkTW9kdWxlcyIsImNvcHlDb25maWd1cmVkRmlsZXMiLCJjb3B5RmlsZXMiLCJjcmVhdGVTcGlubmVyIiwiZ2V0RmlsZXNCeUV4dCIsInJlbW92ZUZpbGVzIiwiZ2V0RGlyTmFtZSIsInJlc29sdmVCaW5hcnlQYXRoIiwibG9nIiwiaGFzRmlsZVR5cGUiLCJzdGFydFBhdGgiLCJleHQiLCJmaWxlcyIsInNvbWUiLCJmaWxlIiwiZmlsZW5hbWUiLCJmaWxlRXh0Iiwic3RhdCIsImlzRGlyZWN0b3J5IiwiaW5jbHVkZXMiLCJjb21waWxlIiwiY21kIiwiY2FsbGJhY2siLCJjbGlOYW1lIiwiY29uZmlnIiwiZm9ybWF0Iiwib3V0cHV0UGF0aCIsInF1aWV0IiwicmVtb3ZlIiwic291cmNlUGF0aCIsIndhdGNoIiwic3Bpbm5lciIsInBhcnNlQ29uZmlnIiwib3V0cHV0RnVsbFBhdGgiLCJzb3VyY2VGdWxsUGF0aCIsInN3YyIsInN3Y0NvbmZpZyIsInVzZVR5cGVzY3JpcHQiLCJvdXRwdXREaXIiLCJwcm9jZXNzIiwiY3dkIiwic291cmNlRGlyIiwiZGlyTmFtZSIsInR5cGVzY3JpcHRQYXRoIiwidHlwZXNjcmlwdE9wdGlvbnMiLCJnbG9iT3B0aW9ucyIsImFic29sdXRlIiwiZG90Iiwibm9kaXIiLCJ0c0ZpbGVzIiwidHN4RmlsZXMiLCJhbGxTb3VyY2VGaWxlcyIsImdldFR5cGVTY3JpcHREZWNsYXJhdGlvbkZsYWdzIiwic3RhcnQiLCJyZXN1bHQiLCJhbGwiLCJlbmNvZGluZyIsInJlamVjdCIsImV4aXRDb2RlIiwiaGFzRGVjbGFyYXRpb25zIiwiZXJyb3JPdXRwdXQiLCJzdGRlcnIiLCJzdGRvdXQiLCJlcnJvckxpbmVzIiwic3BsaXQiLCJmaWx0ZXIiLCJsaW5lIiwidHJpbSIsInN0YXJ0c1dpdGgiLCJsZW5ndGgiLCJzbGljZSIsImZvckVhY2giLCJmYWlsIiwic3VjY2VlZCIsImVycm9yIiwibWVzc2FnZSIsIkVycm9yIiwic3RhY2siLCJub3NvcnQiLCJqc0ZpbGVzIiwic291cmNlRmlsZXMiLCJjc3NGaWxlcyIsInBvc3Rjc3NQYXRoIiwicG9zdGNzc09wdGlvbnMiLCJnaWZGaWxlcyIsImpwZ0ZpbGVzIiwicG5nRmlsZXMiLCJzdmdGaWxlcyIsImltYWdlRmlsZXMiLCJ0dGZGaWxlcyIsIm90ZkZpbGVzIiwid29mZkZpbGVzIiwid29mZjJGaWxlcyIsImZvbnRGaWxlcyIsIm1kRmlsZXMiLCJ0cmFuc2Zvcm1Qcm9taXNlcyIsIm1hcCIsImZpbGVSZWxhdGl2ZVRvU291cmNlIiwib3V0cHV0RmlsZSIsInJlcGxhY2UiLCJvdXRwdXREaXJQYXRoIiwicmVjdXJzaXZlIiwic291cmNlQ29kZSIsImlzVFNYIiwiZW5kc1dpdGgiLCJzd2NPcHRpb25zIiwibW9kdWxlIiwidHlwZSIsInNvdXJjZU1hcHMiLCJjb2RlIiwiUHJvbWlzZSIsImNvbnNvbGUiLCJjb3B5RXJyb3IiXSwibWFwcGluZ3MiOiJBQUFBOzs7Q0FHQyxHQUNELFNBQVFBLFNBQVMsUUFBTyxZQUFZO0FBQ3BDLFNBQVFDLEtBQUssUUFBTyxRQUFRO0FBQzVCLFNBQVFDLFVBQVUsRUFBRUMsU0FBUyxFQUFFQyxXQUFXLEVBQUVDLFlBQVksRUFBRUMsYUFBYSxFQUFFQyxTQUFTLFFBQU8sS0FBSztBQUM5RixTQUFRQyxRQUFRQyxRQUFRLFFBQU8sT0FBTztBQUN0QyxTQUFRQyxXQUFXQyxXQUFXLEVBQUVDLFFBQVFDLFFBQVEsRUFBRUMsWUFBWUMsWUFBWSxFQUFFQyxXQUFXQyxXQUFXLEVBQUVDLE9BQU8sUUFBTyxPQUFPO0FBRXpILFNBQVFDLFNBQVMsUUFBTyxxQkFBcUI7QUFDN0MsU0FBUUMsa0JBQWtCLEVBQUVDLG1CQUFtQixFQUFFQyxTQUFTLEVBQUVDLGFBQWEsRUFBRUMsYUFBYSxFQUFFQyxXQUFXLFFBQU8scUJBQXFCO0FBQ2pJLFNBQVFDLFVBQVUsRUFBRUMsaUJBQWlCLFFBQU8sc0JBQXNCO0FBQ2xFLFNBQVFDLEdBQUcsUUFBTyxxQkFBcUI7QUFJdkMsT0FBTyxNQUFNQyxjQUFjLENBQUNDLFdBQW1CQztJQUM3QyxJQUFHLENBQUM3QixXQUFXNEIsWUFBWTtRQUN6QixPQUFPO0lBQ1Q7SUFFQSxNQUFNRSxRQUFrQjVCLFlBQVkwQjtJQUVwQyxPQUFPRSxNQUFNQyxJQUFJLENBQUMs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