UNPKG

@git.zone/cli

Version:

A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.

246 lines 20.5 kB
import * as plugins from './meta.plugins.js'; import * as paths from '../paths.js'; import * as interfaces from './meta.interfaces.js'; import { logger } from '../gitzone.logging.js'; export class Meta { cwd; dirName; filePaths; constructor(cwdArg) { this.cwd = cwdArg; this.dirName = plugins.path.basename(this.cwd); this.filePaths = { metaJson: plugins.path.join(this.cwd, './.meta.json'), gitIgnore: plugins.path.join(this.cwd, './.gitignore'), packageJson: plugins.path.join(this.cwd, './package.json'), }; } /** * the meta repo data */ metaRepoData; smartshellInstance = new plugins.smartshell.Smartshell({ executor: 'bash', }); /** * sorts the metaRepoData */ async sortMetaRepoData() { const stringifiedMetadata = plugins.smartjson.stringify(this.metaRepoData, []); this.metaRepoData = plugins.smartjson.parse(stringifiedMetadata); } /** * reads the meta file from disk */ async readDirectory() { await this.syncToRemote(true); logger.log('info', `reading directory`); const metaFileExists = await plugins.smartfs .file(this.filePaths.metaJson) .exists(); if (!metaFileExists) { throw new Error(`meta file does not exist at ${this.filePaths.metaJson}`); } const content = (await plugins.smartfs .file(this.filePaths.metaJson) .encoding('utf8') .read()); this.metaRepoData = JSON.parse(content); } /** * generates the gitignore file and stores it on disk */ async generateGitignore() { await this.sortMetaRepoData(); let gitignoreString = `# ignored repo directories\n`; gitignoreString += `.nogit/\n`; gitignoreString += `.pnpm-store/\n`; for (const key of Object.keys(this.metaRepoData.projects)) { gitignoreString = `${gitignoreString}${key}\n`; } return gitignoreString; } /** * write to disk */ async writeToDisk() { // write .meta.json to disk await plugins.smartfs .file(this.filePaths.metaJson) .encoding('utf8') .write(JSON.stringify(this.metaRepoData, null, 2)); // write .gitignore to disk await plugins.smartfs .file(this.filePaths.gitIgnore) .encoding('utf8') .write(await this.generateGitignore()); } /** * push to remote */ async syncToRemote(gitCleanArg = false) { logger.log('info', `syncing from origin master`); await this.smartshellInstance.exec(`cd ${this.cwd} && git pull origin master`); if (gitCleanArg) { logger.log('info', `cleaning the repository from old directories`); await this.smartshellInstance.exec(`cd ${this.cwd} && git clean -fd`); } logger.log('info', `syncing to remote origin master`); await this.smartshellInstance.exec(`cd ${this.cwd} && git push origin master`); } /** * update the locally cloned repositories */ async updateLocalRepos() { await this.syncToRemote(); const metaContent = (await plugins.smartfs .file(this.filePaths.metaJson) .encoding('utf8') .read()); const projects = JSON.parse(metaContent).projects; const entries = await plugins.smartfs.directory(this.cwd).list(); const preExistingFolders = []; for (const entry of entries) { try { const stats = await plugins.smartfs .file(plugins.path.join(this.cwd, entry.path)) .stat(); if (stats.isDirectory) { preExistingFolders.push(entry.name); } } catch { // Skip entries that can't be accessed } } for (const preExistingFolderArg of preExistingFolders) { if (preExistingFolderArg !== '.git' && !Object.keys(projects).find((projectFolder) => projectFolder.startsWith(preExistingFolderArg))) { const response = await plugins.smartinteraction.SmartInteract.getCliConfirmation(`Do you want to delete superfluous directory >>${preExistingFolderArg}<< ?`, true); if (response) { logger.log('warn', `Deleting >>${preExistingFolderArg}<<!`); } else { logger.log('warn', `Not deleting ${preExistingFolderArg} by request!`); } } } await this.readDirectory(); await this.sortMetaRepoData(); const missingRepos = []; for (const key of Object.keys(this.metaRepoData.projects)) { const fullPath = plugins.path.join(this.cwd, key); try { const stats = await plugins.smartfs.file(fullPath).stat(); if (stats.isDirectory) { logger.log('ok', `${key} -> is already cloned`); } else { missingRepos.push(key); } } catch { missingRepos.push(key); } } logger.log('info', `found ${missingRepos.length} missing repos`); for (const missingRepo of missingRepos) { await this.smartshellInstance.exec(`cd ${this.cwd} && git clone ${this.metaRepoData.projects[missingRepo]} ${missingRepo}`); } logger.log('info', `write changes to disk`); await this.writeToDisk(); logger.log('info', `persist changes with a git commit`); await this.smartshellInstance.exec(`cd ${this.cwd} && git add -A && git commit -m "updated structure"`); await this.syncToRemote(); // go recursive const listEntries = await plugins.smartfs.directory(this.cwd).list(); const folders = []; for (const entry of listEntries) { try { const stats = await plugins.smartfs .file(plugins.path.join(this.cwd, entry.path)) .stat(); if (stats.isDirectory) { folders.push(entry.name); } } catch { // Skip entries that can't be accessed } } const childMetaRepositories = []; for (const folder of folders) { logger.log('info', folder); } console.log('Recursion still needs to be implemented'); } // project manipulation /** * init a new meta project */ async initProject() { await this.syncToRemote(true); const fileExists = await plugins.smartfs .file(this.filePaths.metaJson) .exists(); if (!fileExists) { await plugins.smartfs .file(this.filePaths.metaJson) .encoding('utf8') .write(JSON.stringify({ projects: {}, })); logger.log(`success`, `created a new .meta.json in directory ${this.cwd}`); await plugins.smartfs .file(this.filePaths.packageJson) .encoding('utf8') .write(JSON.stringify({ name: this.dirName, version: '1.0.0', })); logger.log(`success`, `created a new package.json in directory ${this.cwd}`); } else { logger.log(`error`, `directory ${this.cwd} already has a .metaJson file. Doing nothing.`); } await this.smartshellInstance.exec(`cd ${this.cwd} && git add -A && git commit -m "feat(project): init meta project for ${this.dirName}"`); await this.updateLocalRepos(); } /** * adds a project */ async addProject(projectNameArg, gitUrlArg) { await this.readDirectory(); const existingProject = this.metaRepoData.projects[projectNameArg]; if (existingProject) { throw new Error('Project already exists! Please remove it first before adding it again.'); } this.metaRepoData.projects[projectNameArg] = gitUrlArg; await this.sortMetaRepoData(); await this.writeToDisk(); await this.smartshellInstance.exec(`cd ${this.cwd} && git add -A && git commit -m "feat(project): add ${projectNameArg}"`); await this.updateLocalRepos(); } /** * removes a project */ async removeProject(projectNameArg) { await this.readDirectory(); const existingProject = this.metaRepoData.projects[projectNameArg]; if (!existingProject) { logger.log('error', `Project ${projectNameArg} does not exist! So it cannot be removed`); return; } delete this.metaRepoData.projects[projectNameArg]; logger.log('info', 'removing project from .meta.json'); await this.sortMetaRepoData(); await this.writeToDisk(); logger.log('info', 'removing directory from cwd'); await plugins.smartfs .directory(plugins.path.join(paths.cwd, projectNameArg)) .recursive() .delete(); await this.updateLocalRepos(); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YS5jbGFzc2VzLm1ldGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9tb2RfbWV0YS9tZXRhLmNsYXNzZXMubWV0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLG1CQUFtQixDQUFDO0FBQzdDLE9BQU8sS0FBSyxLQUFLLE1BQU0sYUFBYSxDQUFDO0FBQ3JDLE9BQU8sS0FBSyxVQUFVLE1BQU0sc0JBQXNCLENBQUM7QUFFbkQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRS9DLE1BQU0sT0FBTyxJQUFJO0lBQ1IsR0FBRyxDQUFTO0lBQ1osT0FBTyxDQUFTO0lBQ2hCLFNBQVMsQ0FJZDtJQUVGLFlBQVksTUFBYztRQUN4QixJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztRQUNsQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsU0FBUyxHQUFHO1lBQ2YsUUFBUSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsY0FBYyxDQUFDO1lBQ3JELFNBQVMsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLGNBQWMsQ0FBQztZQUN0RCxXQUFXLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxnQkFBZ0IsQ0FBQztTQUMzRCxDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0ksWUFBWSxDQUEyQjtJQUN2QyxrQkFBa0IsR0FBRyxJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO1FBQzVELFFBQVEsRUFBRSxNQUFNO0tBQ2pCLENBQUMsQ0FBQztJQUVIOztPQUVHO0lBQ0ksS0FBSyxDQUFDLGdCQUFnQjtRQUMzQixNQUFNLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUNyRCxJQUFJLENBQUMsWUFBWSxFQUNqQixFQUFFLENBQ0gsQ0FBQztRQUNGLElBQUksQ0FBQyxZQUFZLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUNuRSxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsYUFBYTtRQUN4QixNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztRQUN4QyxNQUFNLGNBQWMsR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPO2FBQ3pDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQzthQUM3QixNQUFNLEVBQUUsQ0FBQztRQUNaLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLCtCQUErQixJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDNUUsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLENBQUMsTUFBTSxPQUFPLENBQUMsT0FBTzthQUNuQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUM7YUFDN0IsUUFBUSxDQUFDLE1BQU0sQ0FBQzthQUNoQixJQUFJLEVBQUUsQ0FBVyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsaUJBQWlCO1FBQzVCLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDOUIsSUFBSSxlQUFlLEdBQUcsOEJBQThCLENBQUM7UUFDckQsZUFBZSxJQUFJLFdBQVcsQ0FBQztRQUMvQixlQUFlLElBQUksZ0JBQWdCLENBQUM7UUFDcEMsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUMxRCxlQUFlLEdBQUcsR0FBRyxlQUFlLEdBQUcsR0FBRyxJQUFJLENBQUM7UUFDakQsQ0FBQztRQUNELE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxXQUFXO1FBQ3RCLDJCQUEyQjtRQUMzQixNQUFNLE9BQU8sQ0FBQyxPQUFPO2FBQ2xCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQzthQUM3QixRQUFRLENBQUMsTUFBTSxDQUFDO2FBQ2hCLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckQsMkJBQTJCO1FBQzNCLE1BQU0sT0FBTyxDQUFDLE9BQU87YUFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO2FBQzlCLFFBQVEsQ0FBQyxNQUFNLENBQUM7YUFDaEIsS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsWUFBWSxDQUFDLFdBQVcsR0FBRyxLQUFLO1FBQzNDLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLDRCQUE0QixDQUFDLENBQUM7UUFDakQsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUNoQyxNQUFNLElBQUksQ0FBQyxHQUFHLDRCQUE0QixDQUMzQyxDQUFDO1FBQ0YsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUNoQixNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSw4Q0FBOEMsQ0FBQyxDQUFDO1lBQ25FLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxHQUFHLG1CQUFtQixDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGtDQUFrQyxDQUFDLENBQUM7UUFDdkQsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUNoQyxNQUFNLElBQUksQ0FBQyxHQUFHLDRCQUE0QixDQUMzQyxDQUFDO0lBQ0osQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLGdCQUFnQjtRQUMzQixNQUFNLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMxQixNQUFNLFdBQVcsR0FBRyxDQUFDLE1BQU0sT0FBTyxDQUFDLE9BQU87YUFDdkMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDO2FBQzdCLFFBQVEsQ0FBQyxNQUFNLENBQUM7YUFDaEIsSUFBSSxFQUFFLENBQVcsQ0FBQztRQUNyQixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUNsRCxNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNqRSxNQUFNLGtCQUFrQixHQUFhLEVBQUUsQ0FBQztRQUN4QyxLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQztnQkFDSCxNQUFNLEtBQUssR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPO3FCQUNoQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7cUJBQzdDLElBQUksRUFBRSxDQUFDO2dCQUNWLElBQUksS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUN0QixrQkFBa0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN0QyxDQUFDO1lBQ0gsQ0FBQztZQUFDLE1BQU0sQ0FBQztnQkFDUCxzQ0FBc0M7WUFDeEMsQ0FBQztRQUNILENBQUM7UUFDRCxLQUFLLE1BQU0sb0JBQW9CLElBQUksa0JBQWtCLEVBQUUsQ0FBQztZQUN0RCxJQUNFLG9CQUFvQixLQUFLLE1BQU07Z0JBQy9CLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUM1QyxhQUFhLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLENBQy9DLEVBQ0QsQ0FBQztnQkFDRCxNQUFNLFFBQVEsR0FDWixNQUFNLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQzdELGlEQUFpRCxvQkFBb0IsTUFBTSxFQUMzRSxJQUFJLENBQ0wsQ0FBQztnQkFDSixJQUFJLFFBQVEsRUFBRSxDQUFDO29CQUNiLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGNBQWMsb0JBQW9CLEtBQUssQ0FBQyxDQUFDO2dCQUM5RCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sTUFBTSxDQUFDLEdBQUcsQ0FDUixNQUFNLEVBQ04sZ0JBQWdCLG9CQUFvQixjQUFjLENBQ25ELENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDM0IsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUM5QixNQUFNLFlBQVksR0FBYSxFQUFFLENBQUM7UUFDbEMsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUMxRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ2xELElBQUksQ0FBQztnQkFDSCxNQUFNLEtBQUssR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUMxRCxJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztvQkFDdEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxHQUFHLHVCQUF1QixDQUFDLENBQUM7Z0JBQ2xELENBQUM7cUJBQU0sQ0FBQztvQkFDTixZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN6QixDQUFDO1lBQ0gsQ0FBQztZQUFDLE1BQU0sQ0FBQztnQkFDUCxZQUFZLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3pCLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsU0FBUyxZQUFZLENBQUMsTUFBTSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ2pFLEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxFQUFFLENBQUM7WUFDdkMsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUNoQyxNQUFNLElBQUksQ0FBQyxHQUFHLGlCQUFpQixJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsSUFBSSxXQUFXLEVBQUUsQ0FDeEYsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1FBQzVDLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRXpCLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLG1DQUFtQyxDQUFDLENBQUM7UUFDeEQsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUNoQyxNQUFNLElBQUksQ0FBQyxHQUFHLHFEQUFxRCxDQUNwRSxDQUFDO1FBQ0YsTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFFMUIsZUFBZTtRQUNmLE1BQU0sV0FBVyxHQUFHLE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3JFLE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztRQUM3QixLQUFLLE1BQU0sS0FBSyxJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQztnQkFDSCxNQUFNLEtBQUssR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPO3FCQUNoQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7cUJBQzdDLElBQUksRUFBRSxDQUFDO2dCQUNWLElBQUksS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUN0QixPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDM0IsQ0FBQztZQUNILENBQUM7WUFBQyxNQUFNLENBQUM7Z0JBQ1Asc0NBQXNDO1lBQ3hDLENBQUM7UUFDSCxDQUFDO1FBQ0QsTUFBTSxxQkFBcUIsR0FBYSxFQUFFLENBQUM7UUFDM0MsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUM3QixNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCx1QkFBdUI7SUFFdkI7O09BRUc7SUFDSSxLQUFLLENBQUMsV0FBVztRQUN0QixNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDOUIsTUFBTSxVQUFVLEdBQUcsTUFBTSxPQUFPLENBQUMsT0FBTzthQUNyQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUM7YUFDN0IsTUFBTSxFQUFFLENBQUM7UUFDWixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsTUFBTSxPQUFPLENBQUMsT0FBTztpQkFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDO2lCQUM3QixRQUFRLENBQUMsTUFBTSxDQUFDO2lCQUNoQixLQUFLLENBQ0osSUFBSSxDQUFDLFNBQVMsQ0FBQztnQkFDYixRQUFRLEVBQUUsRUFBRTthQUNiLENBQUMsQ0FDSCxDQUFDO1lBQ0osTUFBTSxDQUFDLEdBQUcsQ0FDUixTQUFTLEVBQ1QseUNBQXlDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FDcEQsQ0FBQztZQUNGLE1BQU0sT0FBTyxDQUFDLE9BQU87aUJBQ2xCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQztpQkFDaEMsUUFBUSxDQUFDLE1BQU0sQ0FBQztpQkFDaEIsS0FBSyxDQUNKLElBQUksQ0FBQyxTQUFTLENBQUM7Z0JBQ2IsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPO2dCQUNsQixPQUFPLEVBQUUsT0FBTzthQUNqQixDQUFDLENBQ0gsQ0FBQztZQUNKLE1BQU0sQ0FBQyxHQUFHLENBQ1IsU0FBUyxFQUNULDJDQUEyQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQ3RELENBQUM7UUFDSixDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sQ0FBQyxHQUFHLENBQ1IsT0FBTyxFQUNQLGFBQWEsSUFBSSxDQUFDLEdBQUcsK0NBQStDLENBQ3JFLENBQUM7UUFDSixDQUFDO1FBQ0QsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUNoQyxNQUFNLElBQUksQ0FBQyxHQUFHLHlFQUF5RSxJQUFJLENBQUMsT0FBTyxHQUFHLENBQ3ZHLENBQUM7UUFDRixNQUFNLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxVQUFVLENBQUMsY0FBc0IsRUFBRSxTQUFTO1FBQ3ZELE1BQU0sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRTNCLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRW5FLElBQUksZUFBZSxFQUFFLENBQUM7WUFDcEIsTUFBTSxJQUFJLEtBQUssQ0FDYix3RUFBd0UsQ0FDekUsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsR0FBRyxTQUFTLENBQUM7UUFFdkQsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUM5QixNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQ2hDLE1BQU0sSUFBSSxDQUFDLEdBQUcsdURBQXVELGNBQWMsR0FBRyxDQUN2RixDQUFDO1FBQ0YsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsYUFBYSxDQUFDLGNBQXNCO1FBQy9DLE1BQU0sSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRTNCLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRW5FLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNyQixNQUFNLENBQUMsR0FBRyxDQUNSLE9BQU8sRUFDUCxXQUFXLGNBQWMsMENBQTBDLENBQ3BFLENBQUM7WUFDRixPQUFPO1FBQ1QsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7UUFFbEQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsa0NBQWtDLENBQUMsQ0FBQztRQUN2RCxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQzlCLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRXpCLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLDZCQUE2QixDQUFDLENBQUM7UUFDbEQsTUFBTSxPQUFPLENBQUMsT0FBTzthQUNsQixTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxjQUFjLENBQUMsQ0FBQzthQUN2RCxTQUFTLEVBQUU7YUFDWCxNQUFNLEVBQUUsQ0FBQztRQUNaLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDaEMsQ0FBQztDQUNGIn0=