UNPKG

cnpmcore

Version:

Private NPM Registry for Enterprise

186 lines 15.1 kB
import os from 'node:os'; import path from 'node:path'; import { InternalServerError } from 'egg/errors'; import { PROXY_CACHE_DIR_NAME } from "../../common/constants.js"; import dayjs from "../../common/dayjs.js"; import { TaskState, TaskType } from "../../common/enum/Task.js"; import { EntityUtil } from "../util/EntityUtil.js"; import { Entity } from "./Entity.js"; import { isPkgManifest } from "./Package.js"; export const HOST_NAME = os.hostname(); export const PID = process.pid; export class Task extends Entity { constructor(data) { super(data); this.taskId = data.taskId; this.type = data.type; this.state = data.state; this.targetName = data.targetName; this.authorId = data.authorId; this.authorIp = data.authorIp; this.data = data.data; this.logPath = data.logPath ?? ''; this.logStorePosition = data.logStorePosition ?? ''; this.attempts = data.attempts ?? 0; this.error = data.error ?? ''; this.bizId = data.bizId; } resetLogPath() { this.logPath = `${path.dirname(this.logPath)}/${dayjs().format('DDHHmm')}-${this.taskId}-${this.attempts}.log`; this.logStorePosition = ''; } setExecuteWorker() { this.data.taskWorker = `${HOST_NAME}:${PID}`; } static create(data) { const newData = EntityUtil.defaultData(data, 'taskId'); return new Task(newData); } static createSyncPackage(fullname, options) { const data = { type: TaskType.SyncPackage, state: TaskState.Waiting, targetName: fullname, authorId: options?.authorId ?? '', authorIp: options?.authorIp ?? '', data: { // task execute worker taskWorker: '', tips: options?.tips, registryId: options?.registryId ?? '', skipDependencies: options?.skipDependencies, syncDownloadData: options?.syncDownloadData, forceSyncHistory: options?.forceSyncHistory, force: options?.force, specificVersions: options?.specificVersions, }, }; const task = this.create(data); task.logPath = `/packages/${fullname}/syncs/${dayjs().format('YYYY/MM/DDHHmm')}-${task.taskId}.log`; return task; } static createChangesStream(targetName, registryId = '', since = '') { const data = { type: TaskType.ChangesStream, state: TaskState.Waiting, targetName, authorId: `pid_${PID}`, authorIp: HOST_NAME, data: { // task execute worker taskWorker: '', registryId, since, }, }; return this.create(data); } updateSyncData({ lastSince, taskCount, lastPackage }) { const syncData = this.data; // 更新任务记录信息 syncData.since = lastSince; syncData.task_count = (syncData.task_count || 0) + taskCount; if (taskCount > 0) { syncData.last_package = lastPackage; syncData.last_package_created = new Date(); } } static createCreateHookTask(hookEvent) { const data = { type: TaskType.CreateHook, state: TaskState.Waiting, targetName: hookEvent.fullname, authorId: `pid_${process.pid}`, authorIp: os.hostname(), bizId: `CreateHook:${hookEvent.changeId}`, data: { // task execute worker taskWorker: '', hookEvent, }, }; const task = this.create(data); task.logPath = `/packages/${hookEvent.fullname}/hooks/${dayjs().format('YYYY/MM/DDHHmm')}-${task.taskId}.log`; return task; } static createTriggerHookTask(hookEvent, hookId) { const data = { type: TaskType.TriggerHook, state: TaskState.Waiting, targetName: hookEvent.fullname, authorId: `pid_${process.pid}`, bizId: `TriggerHook:${hookEvent.changeId}:${hookId}`, authorIp: os.hostname(), data: { // task execute worker taskWorker: '', hookEvent, hookId, }, }; const task = this.create(data); task.logPath = `/packages/${hookEvent.fullname}/hooks/${dayjs().format('YYYY/MM/DDHHmm')}-${task.taskId}.log`; return task; } static createSyncBinary(targetName, lastData) { const data = { type: TaskType.SyncBinary, state: TaskState.Waiting, targetName, authorId: `pid_${PID}`, authorIp: HOST_NAME, bizId: `SyncBinary:${targetName}`, data: { // task execute worker taskWorker: '', ...lastData, }, }; const task = this.create(data); task.logPath = `/binaries/${targetName}/syncs/${dayjs().format('YYYY/MM/DDHHmm')}-${task.taskId}.log`; return task; } needMergeWhenWaiting() { // 历史任务补偿时,将 shouldNotMerge 设置为 true,避免合并 // 补偿任务单独执行 if (this.data.shouldNotMerge === true) { return false; } // 仅合并二进制镜像与 npm 包 return [TaskType.SyncBinary, TaskType.SyncPackage].includes(this.type); } static createUpdateProxyCache(targetName, options) { if (!isPkgManifest(options.fileType)) { throw new InternalServerError('should not update package version manifest.'); } const filePath = `/${PROXY_CACHE_DIR_NAME}/${options.fullname}/${options.fileType}`; const data = { type: TaskType.UpdateProxyCache, state: TaskState.Waiting, targetName, authorId: `pid_${PID}`, authorIp: HOST_NAME, data: { taskWorker: '', fullname: options.fullname, version: options?.version, fileType: options.fileType, filePath, }, }; const task = this.create(data); task.logPath = `/${PROXY_CACHE_DIR_NAME}/${options.fullname}/update-manifest-log/${options.fileType.split('.json')[0]}-${dayjs().format('YYYY/MM/DDHHmm')}-${task.taskId}.log`; return task; } start() { const condition = { taskId: this.taskId, attempts: this.attempts, }; this.setExecuteWorker(); this.state = TaskState.Processing; this.attempts += 1; return condition; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVGFzay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2FwcC9jb3JlL2VudGl0eS9UYXNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFFN0IsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRWpELE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pFLE9BQU8sS0FBSyxNQUFNLHVCQUF1QixDQUFDO0FBQzFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFVBQVUsRUFBaUIsTUFBTSx1QkFBdUIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsTUFBTSxFQUFtQixNQUFNLGFBQWEsQ0FBQztBQUV0RCxPQUFPLEVBQUUsYUFBYSxFQUFtQixNQUFNLGNBQWMsQ0FBQztBQUU5RCxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDO0FBMEYvQixNQUFNLE9BQU8sSUFBNEMsU0FBUSxNQUFNO0lBZXJFLFlBQVksSUFBaUI7UUFDM0IsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ1osSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzFCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDeEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztRQUM5QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDOUIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxFQUFFLENBQUM7UUFDcEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQzlCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztJQUMxQixDQUFDO0lBRU0sWUFBWTtRQUNqQixJQUFJLENBQUMsT0FBTyxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLFFBQVEsTUFBTSxDQUFDO1FBQy9HLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVNLGdCQUFnQjtRQUNyQixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxHQUFHLFNBQVMsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUMvQyxDQUFDO0lBRU8sTUFBTSxDQUFDLE1BQU0sQ0FBeUIsSUFBcUM7UUFDakYsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDdkQsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRU0sTUFBTSxDQUFDLGlCQUFpQixDQUFDLFFBQWdCLEVBQUUsT0FBZ0M7UUFDaEYsTUFBTSxJQUFJLEdBQUc7WUFDWCxJQUFJLEVBQUUsUUFBUSxDQUFDLFdBQVc7WUFDMUIsS0FBSyxFQUFFLFNBQVMsQ0FBQyxPQUFPO1lBQ3hCLFVBQVUsRUFBRSxRQUFRO1lBQ3BCLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxJQUFJLEVBQUU7WUFDakMsUUFBUSxFQUFFLE9BQU8sRUFBRSxRQUFRLElBQUksRUFBRTtZQUNqQyxJQUFJLEVBQUU7Z0JBQ0osc0JBQXNCO2dCQUN0QixVQUFVLEVBQUUsRUFBRTtnQkFDZCxJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUk7Z0JBQ25CLFVBQVUsRUFBRSxPQUFPLEVBQUUsVUFBVSxJQUFJLEVBQUU7Z0JBQ3JDLGdCQUFnQixFQUFFLE9BQU8sRUFBRSxnQkFBZ0I7Z0JBQzNDLGdCQUFnQixFQUFFLE9BQU8sRUFBRSxnQkFBZ0I7Z0JBQzNDLGdCQUFnQixFQUFFLE9BQU8sRUFBRSxnQkFBZ0I7Z0JBQzNDLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSztnQkFDckIsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLGdCQUFnQjthQUM1QztTQUNGLENBQUM7UUFDRixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPLEdBQUcsYUFBYSxRQUFRLFVBQVUsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sTUFBTSxDQUFDO1FBQ3BHLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVNLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxVQUFrQixFQUFFLFVBQVUsR0FBRyxFQUFFLEVBQUUsS0FBSyxHQUFHLEVBQUU7UUFDL0UsTUFBTSxJQUFJLEdBQUc7WUFDWCxJQUFJLEVBQUUsUUFBUSxDQUFDLGFBQWE7WUFDNUIsS0FBSyxFQUFFLFNBQVMsQ0FBQyxPQUFPO1lBQ3hCLFVBQVU7WUFDVixRQUFRLEVBQUUsT0FBTyxHQUFHLEVBQUU7WUFDdEIsUUFBUSxFQUFFLFNBQVM7WUFDbkIsSUFBSSxFQUFFO2dCQUNKLHNCQUFzQjtnQkFDdEIsVUFBVSxFQUFFLEVBQUU7Z0JBQ2QsVUFBVTtnQkFDVixLQUFLO2FBQ047U0FDRixDQUFDO1FBQ0YsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBc0IsQ0FBQztJQUNoRCxDQUFDO0lBRU0sY0FBYyxDQUFDLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQVk7UUFDbkUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQXdDLENBQUM7UUFDL0QsV0FBVztRQUNYLFFBQVEsQ0FBQyxLQUFLLEdBQUcsU0FBUyxDQUFDO1FBQzNCLFFBQVEsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxRQUFRLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQyxHQUFHLFNBQVMsQ0FBQztRQUU3RCxJQUFJLFNBQVMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNsQixRQUFRLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztZQUNwQyxRQUFRLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUM3QyxDQUFDO0lBQ0gsQ0FBQztJQUVNLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxTQUFvQjtRQUNyRCxNQUFNLElBQUksR0FBRztZQUNYLElBQUksRUFBRSxRQUFRLENBQUMsVUFBVTtZQUN6QixLQUFLLEVBQUUsU0FBUyxDQUFDLE9BQU87WUFDeEIsVUFBVSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1lBQzlCLFFBQVEsRUFBRSxPQUFPLE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDOUIsUUFBUSxFQUFFLEVBQUUsQ0FBQyxRQUFRLEVBQUU7WUFDdkIsS0FBSyxFQUFFLGNBQWMsU0FBUyxDQUFDLFFBQVEsRUFBRTtZQUN6QyxJQUFJLEVBQUU7Z0JBQ0osc0JBQXNCO2dCQUN0QixVQUFVLEVBQUUsRUFBRTtnQkFDZCxTQUFTO2FBQ1Y7U0FDRixDQUFDO1FBQ0YsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsT0FBTyxHQUFHLGFBQWEsU0FBUyxDQUFDLFFBQVEsVUFBVSxLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxNQUFNLENBQUM7UUFDOUcsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU0sTUFBTSxDQUFDLHFCQUFxQixDQUFDLFNBQW9CLEVBQUUsTUFBYztRQUN0RSxNQUFNLElBQUksR0FBRztZQUNYLElBQUksRUFBRSxRQUFRLENBQUMsV0FBVztZQUMxQixLQUFLLEVBQUUsU0FBUyxDQUFDLE9BQU87WUFDeEIsVUFBVSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1lBQzlCLFFBQVEsRUFBRSxPQUFPLE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDOUIsS0FBSyxFQUFFLGVBQWUsU0FBUyxDQUFDLFFBQVEsSUFBSSxNQUFNLEVBQUU7WUFDcEQsUUFBUSxFQUFFLEVBQUUsQ0FBQyxRQUFRLEVBQUU7WUFDdkIsSUFBSSxFQUFFO2dCQUNKLHNCQUFzQjtnQkFDdEIsVUFBVSxFQUFFLEVBQUU7Z0JBQ2QsU0FBUztnQkFDVCxNQUFNO2FBQ1A7U0FDRixDQUFDO1FBQ0YsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsT0FBTyxHQUFHLGFBQWEsU0FBUyxDQUFDLFFBQVEsVUFBVSxLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxNQUFNLENBQUM7UUFDOUcsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU0sTUFBTSxDQUFDLGdCQUFnQixDQUFDLFVBQWtCLEVBQUUsUUFBa0M7UUFDbkYsTUFBTSxJQUFJLEdBQUc7WUFDWCxJQUFJLEVBQUUsUUFBUSxDQUFDLFVBQVU7WUFDekIsS0FBSyxFQUFFLFNBQVMsQ0FBQyxPQUFPO1lBQ3hCLFVBQVU7WUFDVixRQUFRLEVBQUUsT0FBTyxHQUFHLEVBQUU7WUFDdEIsUUFBUSxFQUFFLFNBQVM7WUFDbkIsS0FBSyxFQUFFLGNBQWMsVUFBVSxFQUFFO1lBQ2pDLElBQUksRUFBRTtnQkFDSixzQkFBc0I7Z0JBQ3RCLFVBQVUsRUFBRSxFQUFFO2dCQUNkLEdBQUcsUUFBUTthQUNaO1NBQ0YsQ0FBQztRQUNGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDL0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxhQUFhLFVBQVUsVUFBVSxLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxNQUFNLENBQUM7UUFDdEcsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsb0JBQW9CO1FBQ2xCLHlDQUF5QztRQUN6QyxXQUFXO1FBQ1gsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUN0QyxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFDRCxrQkFBa0I7UUFDbEIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDekUsQ0FBQztJQUVNLE1BQU0sQ0FBQyxzQkFBc0IsQ0FDbEMsVUFBa0IsRUFDbEIsT0FBb0M7UUFFcEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUNyQyxNQUFNLElBQUksbUJBQW1CLENBQUMsNkNBQTZDLENBQUMsQ0FBQztRQUMvRSxDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxvQkFBb0IsSUFBSSxPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNwRixNQUFNLElBQUksR0FBRztZQUNYLElBQUksRUFBRSxRQUFRLENBQUMsZ0JBQWdCO1lBQy9CLEtBQUssRUFBRSxTQUFTLENBQUMsT0FBTztZQUN4QixVQUFVO1lBQ1YsUUFBUSxFQUFFLE9BQU8sR0FBRyxFQUFFO1lBQ3RCLFFBQVEsRUFBRSxTQUFTO1lBQ25CLElBQUksRUFBRTtnQkFDSixVQUFVLEVBQUUsRUFBRTtnQkFDZCxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVE7Z0JBQzFCLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTztnQkFDekIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO2dCQUMxQixRQUFRO2FBQ1Q7U0FDRixDQUFDO1FBQ0YsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksb0JBQW9CLElBQUksT0FBTyxDQUFDLFFBQVEsd0JBQXdCLE9BQU8sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLE1BQU0sQ0FBQztRQUMvSyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxLQUFLO1FBQ0gsTUFBTSxTQUFTLEdBQUc7WUFDaEIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtTQUN4QixDQUFDO1FBQ0YsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDO1FBQ25CLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7Q0FDRiJ9