624 lines
49 KiB
JavaScript
624 lines
49 KiB
JavaScript
import * as pathUtil from 'path';
|
|
import * as fs from 'fs';
|
|
import { symlinkSync, readFileSync, createReadStream, createWriteStream } from 'fs';
|
|
import { sync as mkdirp } from 'mkdirp';
|
|
import { sync as existsSync, async as existsASync } from './exists.js';
|
|
import { create as matcher } from './utils/matcher.js';
|
|
import { normalizeFileMode as fileMode } from './utils/mode.js';
|
|
import { sync as treeWalkerSync } from './utils/tree_walker.js';
|
|
import { validateArgument, validateOptions } from './utils/validate.js';
|
|
import { sync as writeSync } from './write.js';
|
|
import { ErrDestinationExists, ErrDoesntExists } from './errors.js';
|
|
import { ErrnoException, ENodeType, ECopyFlags, ENodeOperationStatus, EError, EInspectFlags, EResolveMode, EResolve } from './interfaces.js';
|
|
import { createItem } from './inspect.js';
|
|
import { sync as rmSync } from './remove.js';
|
|
import { promisify } from './promisify.js';
|
|
import { async as iteratorAsync } from './iterator.js';
|
|
//import { ArrayIterator } from '@polymech/core/iterator';
|
|
const promisedSymlink = promisify(fs.symlink);
|
|
const promisedReadlink = promisify(fs.readlink);
|
|
const promisedUnlink = promisify(fs.unlink);
|
|
const promisedMkdirp = promisify(mkdirp);
|
|
const CPROGRESS_THRESHOLD = 1048576 * 5; // minimum file size threshold to use write progress = 5MB
|
|
export function validateInput(methodName, from, to, options) {
|
|
const methodSignature = methodName + '(from, to, [options])';
|
|
validateArgument(methodSignature, 'from', from, ['string']);
|
|
validateArgument(methodSignature, 'to', to, ['string']);
|
|
validateOptions(methodSignature, 'options', options, {
|
|
overwrite: ['boolean'],
|
|
matching: ['string', 'array of string'],
|
|
progress: ['function'],
|
|
content: ['function'],
|
|
writeProgress: ['function'],
|
|
conflictCallback: ['function'],
|
|
conflictSettings: ['object'],
|
|
throttel: ['number'],
|
|
debug: ['boolean'],
|
|
flags: ['number']
|
|
});
|
|
}
|
|
const parseOptions = (options, from) => {
|
|
const opts = options || {};
|
|
const parsedOptions = {};
|
|
parsedOptions.overwrite = opts.overwrite;
|
|
parsedOptions.progress = opts.progress;
|
|
parsedOptions.writeProgress = opts.writeProgress;
|
|
parsedOptions.content = opts.content;
|
|
parsedOptions.conflictCallback = opts.conflictCallback;
|
|
parsedOptions.conflictSettings = opts.conflictSettings;
|
|
parsedOptions.debug = opts.debug;
|
|
parsedOptions.throttel = opts.throttel;
|
|
parsedOptions.renameCallback = opts.renameCallback;
|
|
parsedOptions.flags = opts.flags || 0;
|
|
if (!opts.filter) {
|
|
if (opts.matching) {
|
|
parsedOptions.filter = matcher(from, opts.matching);
|
|
}
|
|
else {
|
|
parsedOptions.filter = () => {
|
|
return true;
|
|
};
|
|
}
|
|
}
|
|
return parsedOptions;
|
|
};
|
|
// ---------------------------------------------------------
|
|
// Sync
|
|
// ---------------------------------------------------------
|
|
const checksBeforeCopyingSync = (from, to, options = {}) => {
|
|
if (!existsSync(from)) {
|
|
throw ErrDoesntExists(from);
|
|
}
|
|
if (existsSync(to) && !options.overwrite) {
|
|
throw ErrDestinationExists(to);
|
|
}
|
|
};
|
|
async function copyFileSyncWithProgress(from, to, options = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
const started = Date.now();
|
|
let cbCalled = false;
|
|
let elapsed = Date.now();
|
|
let speed = 0;
|
|
const done = (err) => {
|
|
if (!cbCalled) {
|
|
cbCalled = true;
|
|
resolve(1);
|
|
}
|
|
};
|
|
const rd = createReadStream(from).
|
|
on('error', (err) => done(err));
|
|
/*
|
|
const str = progress({
|
|
length: fs.statSync(from).size,
|
|
time: 100
|
|
}).on('progress', (e: any) => {
|
|
elapsed = (Date.now() - started) / 1000;
|
|
speed = e.transferred / elapsed;
|
|
if (options.writeProgress) {
|
|
options.writeProgress(from, e.transferred, e.length);
|
|
}
|
|
});
|
|
*/
|
|
const wr = createWriteStream(to);
|
|
wr.on('error', (err) => done(err));
|
|
wr.on('close', done);
|
|
//rd.pipe(str).pipe(wr);
|
|
});
|
|
}
|
|
async function copyFileSync(from, to, mode, options) {
|
|
let data = readFileSync(from);
|
|
const writeOptions = {
|
|
mode: mode
|
|
};
|
|
if (options.renameCallback) {
|
|
const rename = options.renameCallback(from, to);
|
|
if (rename) {
|
|
to = rename;
|
|
}
|
|
}
|
|
if (options.content) {
|
|
data = options.content(from, data, createItem(from));
|
|
}
|
|
if (options && options.writeProgress) {
|
|
await copyFileSyncWithProgress(from, to, options);
|
|
}
|
|
else {
|
|
writeSync(to, data, writeOptions);
|
|
}
|
|
}
|
|
const copySymlinkSync = (from, to) => {
|
|
const symlinkPointsAt = fs.readlinkSync(from);
|
|
try {
|
|
symlinkSync(symlinkPointsAt, to);
|
|
}
|
|
catch (err) {
|
|
// There is already file/symlink with this name on destination location.
|
|
// Must erase it manually, otherwise system won't allow us to place symlink there.
|
|
if (err.code === 'EEXIST') {
|
|
fs.unlinkSync(to);
|
|
// Retry...
|
|
fs.symlinkSync(symlinkPointsAt, to);
|
|
}
|
|
else {
|
|
throw err;
|
|
}
|
|
}
|
|
};
|
|
async function copyItemSync(from, inspectData, to, options) {
|
|
const mode = fileMode(inspectData.mode);
|
|
if (inspectData.type === ENodeType.DIR) {
|
|
if (options.renameCallback) {
|
|
const rename = options.renameCallback(from, to);
|
|
if (rename) {
|
|
to = rename;
|
|
}
|
|
}
|
|
mkdirp(to, { mode: parseInt(mode, 8), fs: null });
|
|
}
|
|
else if (inspectData.type === ENodeType.FILE) {
|
|
await copyFileSync(from, to, mode, options);
|
|
}
|
|
else if (inspectData.type === ENodeType.SYMLINK) {
|
|
if (options.renameCallback) {
|
|
const rename = options.renameCallback(from, to);
|
|
if (rename) {
|
|
to = rename;
|
|
}
|
|
}
|
|
copySymlinkSync(from, to);
|
|
}
|
|
}
|
|
export function sync(from, to, options) {
|
|
const opts = parseOptions(options, from);
|
|
checksBeforeCopyingSync(from, to, opts);
|
|
const nodes = [];
|
|
let sizeTotal = 0;
|
|
if (options && options.flags & ECopyFlags.EMPTY) {
|
|
const dstStat = fs.statSync(to);
|
|
if (dstStat.isDirectory()) {
|
|
rmSync(to);
|
|
}
|
|
}
|
|
const visitor = (path, inspectData) => {
|
|
if (opts.filter(path)) {
|
|
nodes.push({
|
|
path: path,
|
|
item: inspectData,
|
|
dst: pathUtil.resolve(to, pathUtil.relative(from, path))
|
|
});
|
|
sizeTotal += inspectData.size;
|
|
}
|
|
};
|
|
treeWalkerSync(from, {
|
|
inspectOptions: {
|
|
mode: true,
|
|
symlinks: true
|
|
}
|
|
}, visitor);
|
|
nodes.map((item, current) => {
|
|
copyItemSync(item.path, item.item, item.dst, options);
|
|
if (opts.progress) {
|
|
opts.progress(item.path, current, nodes.length, item.item, item.dst);
|
|
}
|
|
});
|
|
}
|
|
// ---------------------------------------------------------
|
|
// Async
|
|
// ---------------------------------------------------------
|
|
/**
|
|
*
|
|
*
|
|
* @param {string} from
|
|
* @param {string} to
|
|
* @param {ICopyOptions} opts
|
|
* @returns {(Promise<IConflictSettings | any>)}
|
|
*/
|
|
const checkAsync = (from, to, opts) => {
|
|
return existsASync(from)
|
|
.then(srcPathExists => {
|
|
if (!srcPathExists) {
|
|
throw ErrDoesntExists(from);
|
|
}
|
|
else {
|
|
return existsASync(to);
|
|
}
|
|
})
|
|
.then(destPathExists => {
|
|
if (destPathExists) {
|
|
if (opts.conflictSettings) {
|
|
return Promise.resolve(opts.conflictSettings);
|
|
}
|
|
if (opts.conflictCallback) {
|
|
const promise = opts.conflictCallback(to, createItem(to), EError.EXISTS);
|
|
promise.then((settings) => {
|
|
settings.error = EError.EXISTS;
|
|
});
|
|
return promise;
|
|
}
|
|
if (!opts.overwrite) {
|
|
throw ErrDestinationExists(to);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
const copyFileAsync = (from, to, mode, options, retriedAttempt) => {
|
|
return new Promise((resolve, reject) => {
|
|
const readStream = fs.createReadStream(from);
|
|
const writeStream = fs.createWriteStream(to, { mode: mode });
|
|
readStream.on('error', reject);
|
|
writeStream.on('error', (err) => {
|
|
const toDirPath = pathUtil.dirname(to);
|
|
// Force read stream to close, since write stream errored
|
|
// read stream serves us no purpose.
|
|
readStream.resume();
|
|
if (err.code === EError.NOEXISTS && retriedAttempt === undefined) {
|
|
// Some parent directory doesn't exits. Create it and retry.
|
|
promisedMkdirp(toDirPath, null).then(() => {
|
|
// Make retry attempt only once to prevent vicious infinite loop
|
|
// (when for some obscure reason I/O will keep returning ENOENT error).
|
|
// Passing retriedAttempt = true.
|
|
copyFileAsync(from, to, mode, null, true)
|
|
.then(resolve)
|
|
.catch(reject);
|
|
});
|
|
}
|
|
else {
|
|
reject(err);
|
|
}
|
|
});
|
|
writeStream.on('finish', () => {
|
|
// feature: preserve times
|
|
if (options && options.flags & ECopyFlags.PRESERVE_TIMES) {
|
|
const sourceStat = fs.statSync(from);
|
|
fs.open(to, 'w', (err, fd) => {
|
|
if (err) {
|
|
throw err;
|
|
}
|
|
fs.futimes(fd, sourceStat.atime, sourceStat.mtime, (err2) => {
|
|
if (err2) {
|
|
throw err2;
|
|
}
|
|
fs.close(fd, null);
|
|
resolve(1);
|
|
});
|
|
});
|
|
}
|
|
else {
|
|
resolve(1);
|
|
}
|
|
});
|
|
const size = fs.statSync(from).size;
|
|
let progressStream = null;
|
|
if (options && options.writeProgress && size > CPROGRESS_THRESHOLD) {
|
|
/*
|
|
progressStream = progress({
|
|
length: fs.statSync(from).size,
|
|
time: 100 // call progress each 100 ms
|
|
});*/
|
|
let elapsed = Date.now();
|
|
let speed = 0;
|
|
const started = Date.now();
|
|
progressStream.on('progress', (e) => {
|
|
elapsed = (Date.now() - started) / 1000;
|
|
speed = e.transferred / elapsed;
|
|
options.writeProgress(from, e.transferred, e.length);
|
|
if (options.debug) {
|
|
console.log('write ' + from + ' (' + e.transferred + ' of ' + e.length);
|
|
}
|
|
});
|
|
readStream.pipe(progressStream).pipe(writeStream);
|
|
}
|
|
else {
|
|
if (options && options.debug) {
|
|
console.log('write ' + from + ' to ' + to);
|
|
}
|
|
readStream.pipe(writeStream);
|
|
}
|
|
});
|
|
};
|
|
export function copySymlinkAsync(from, to) {
|
|
return promisedReadlink(from)
|
|
.then((symlinkPointsAt) => {
|
|
return new Promise((resolve, reject) => {
|
|
promisedSymlink(symlinkPointsAt, to, null)
|
|
.then(resolve)
|
|
.catch((err) => {
|
|
if (err.code === EError.EXISTS) {
|
|
// There is already file/symlink with this name on destination location.
|
|
// Must erase it manually, otherwise system won't allow us to place symlink there.
|
|
promisedUnlink(to, null)
|
|
// Retry...
|
|
.then(() => {
|
|
return promisedSymlink(symlinkPointsAt, to, null);
|
|
})
|
|
.then(resolve, reject);
|
|
}
|
|
else {
|
|
reject(err);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
}
|
|
const copyItemAsync = (from, inspectData, to, options) => {
|
|
const mode = fileMode(inspectData.mode);
|
|
if (inspectData.type === ENodeType.DIR) {
|
|
return promisedMkdirp(to, { mode: mode });
|
|
}
|
|
else if (inspectData.type === ENodeType.FILE) {
|
|
return copyFileAsync(from, to, mode, options);
|
|
}
|
|
else if (inspectData.type === ENodeType.SYMLINK) {
|
|
return copySymlinkAsync(from, to);
|
|
}
|
|
// EInspectItemType.OTHER
|
|
return Promise.resolve();
|
|
};
|
|
// handle user side setting "THROW" and non enum values (null)
|
|
const onConflict = (from, to, options, settings) => {
|
|
switch (settings.overwrite) {
|
|
case EResolveMode.THROW: {
|
|
throw ErrDestinationExists(to);
|
|
}
|
|
case EResolveMode.OVERWRITE:
|
|
case EResolveMode.APPEND:
|
|
case EResolveMode.IF_NEWER:
|
|
case EResolveMode.ABORT:
|
|
case EResolveMode.IF_SIZE_DIFFERS:
|
|
case EResolveMode.SKIP: {
|
|
return settings.overwrite;
|
|
}
|
|
default: {
|
|
return undefined;
|
|
}
|
|
}
|
|
};
|
|
export function resolveConflict(from, to, options, resolveMode) {
|
|
if (resolveMode === undefined) {
|
|
return true;
|
|
}
|
|
const src = createItem(from);
|
|
const dst = createItem(to);
|
|
if (resolveMode === EResolveMode.SKIP) {
|
|
return false;
|
|
}
|
|
else if (resolveMode === EResolveMode.IF_NEWER) {
|
|
if (src.type === ENodeType.DIR && dst.type === ENodeType.DIR) {
|
|
return true;
|
|
}
|
|
if (dst.modifyTime.getTime() > src.modifyTime.getTime()) {
|
|
return false;
|
|
}
|
|
}
|
|
else if (resolveMode === EResolveMode.IF_SIZE_DIFFERS) {
|
|
// @TODO : not implemented: copy EInspectItemType.DIR with ECopyResolveMode.IF_SIZE_DIFFERS
|
|
if (src.type === ENodeType.DIR && dst.type === ENodeType.DIR) {
|
|
return true;
|
|
}
|
|
else if (src.type === ENodeType.FILE && dst.type === ENodeType.FILE) {
|
|
if (src.size === dst.size) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
else if (resolveMode === EResolveMode.OVERWRITE) {
|
|
return true;
|
|
}
|
|
else if (resolveMode === EResolveMode.ABORT) {
|
|
return false;
|
|
}
|
|
}
|
|
function isDone(nodes) {
|
|
let done = true;
|
|
nodes.forEach((element) => {
|
|
if (element.status !== ENodeOperationStatus.DONE) {
|
|
done = false;
|
|
}
|
|
});
|
|
return done;
|
|
}
|
|
/**
|
|
* A callback for treeWalkerStream. This is called when a node has been found.
|
|
*
|
|
* @param {string} from
|
|
* @param {string} to
|
|
* @param {*} vars
|
|
* @param {{ path: string, item: INode }} item
|
|
* @returns {Promise<void>}
|
|
*/
|
|
async function visitor(from, to, vars, item) {
|
|
const options = vars.options;
|
|
let rel;
|
|
let destPath;
|
|
if (!item) {
|
|
return;
|
|
}
|
|
rel = pathUtil.relative(from, item.path);
|
|
destPath = pathUtil.resolve(to, rel);
|
|
item.status = ENodeOperationStatus.PROCESSING;
|
|
const done = () => {
|
|
item.status = ENodeOperationStatus.DONE;
|
|
if (isDone(vars.nodes)) {
|
|
return vars.resolve(vars.result);
|
|
}
|
|
};
|
|
if (isDone(vars.nodes)) {
|
|
return vars.resolve(vars.result);
|
|
}
|
|
vars.filesInProgress += 1;
|
|
// our main function after sanity checks
|
|
const checked = (subResolveSettings) => {
|
|
item.status = ENodeOperationStatus.CHECKED;
|
|
// feature : report
|
|
if (subResolveSettings && options && options.flags && options.flags & ECopyFlags.REPORT) {
|
|
vars.result.push({
|
|
error: subResolveSettings.error,
|
|
node: item,
|
|
resolved: subResolveSettings
|
|
});
|
|
}
|
|
if (subResolveSettings) {
|
|
// if the first resolve callback returned an individual resolve settings "THIS",
|
|
// ask the user again with the same item
|
|
const always = subResolveSettings.mode === EResolve.ALWAYS;
|
|
if (always) {
|
|
options.conflictSettings = subResolveSettings;
|
|
}
|
|
let overwriteMode = subResolveSettings.overwrite;
|
|
overwriteMode = onConflict(item.path, destPath, options, subResolveSettings);
|
|
if (overwriteMode === EResolveMode.ABORT) {
|
|
vars.abort = true;
|
|
}
|
|
if (vars.abort) {
|
|
return;
|
|
}
|
|
if (!resolveConflict(item.path, destPath, options, overwriteMode)) {
|
|
done();
|
|
return;
|
|
}
|
|
}
|
|
item.status = ENodeOperationStatus.PROCESS;
|
|
copyItemAsync(item.path, item.item, destPath, options).then(() => {
|
|
vars.filesInProgress -= 1;
|
|
if (options.progress) {
|
|
if (options.progress(item.path, vars.filesInProgress, vars.filesInProgress, item.item) === false) {
|
|
vars.abort = true;
|
|
return vars.resolve();
|
|
}
|
|
}
|
|
done();
|
|
}).catch((err) => {
|
|
if (options && options.conflictCallback) {
|
|
if (err.code === EError.PERMISSION || err.code === EError.NOEXISTS) {
|
|
options.conflictCallback(item.path, createItem(destPath), err.code).then((errorResolveSettings) => {
|
|
// the user has set the conflict resolver to always, so we use the last one
|
|
if (vars.onCopyErrorResolveSettings) {
|
|
errorResolveSettings = vars.onCopyErrorResolveSettings;
|
|
}
|
|
// user said use this settings always, we track and use this last setting from now on
|
|
if (errorResolveSettings.mode === EResolve.ALWAYS && !vars.onCopyErrorResolveSettings) {
|
|
vars.onCopyErrorResolveSettings = errorResolveSettings;
|
|
}
|
|
if (errorResolveSettings.overwrite === EResolveMode.ABORT) {
|
|
vars.abort = true;
|
|
return vars.resolve();
|
|
}
|
|
if (errorResolveSettings.overwrite === EResolveMode.THROW) {
|
|
vars.abort = true;
|
|
return vars.reject(err);
|
|
}
|
|
if (errorResolveSettings.overwrite === EResolveMode.SKIP) {
|
|
vars.filesInProgress -= 1;
|
|
}
|
|
// user error, should never happen, unintended
|
|
if (errorResolveSettings.overwrite === EResolveMode.IF_NEWER ||
|
|
errorResolveSettings.overwrite === EResolveMode.IF_SIZE_DIFFERS ||
|
|
errorResolveSettings.overwrite === EResolveMode.OVERWRITE) {
|
|
vars.reject(new ErrnoException('settings make no sense : errorResolveSettings.overwrite = ' + errorResolveSettings.overwrite));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
vars.reject(err);
|
|
});
|
|
};
|
|
return checkAsync(item.path, destPath, options).then(checked);
|
|
}
|
|
function next(nodes) {
|
|
for (let i = 0; i < nodes.length; i++) {
|
|
if (nodes[i].status === ENodeOperationStatus.COLLECTED) {
|
|
return nodes[i];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* Final async copy function.
|
|
* @export
|
|
* @param {string} from
|
|
* @param {string} to
|
|
* @param {ICopyOptions} [options]
|
|
* @returns
|
|
*/
|
|
export function async(from, to, options) {
|
|
options = parseOptions(options, from);
|
|
return new Promise((resolve, reject) => {
|
|
checkAsync(from, to, options).then((resolver) => {
|
|
if (!resolver) {
|
|
resolver = options.conflictSettings || {
|
|
mode: EResolve.THIS,
|
|
overwrite: EResolveMode.OVERWRITE
|
|
};
|
|
}
|
|
else {
|
|
if (resolver.mode === EResolve.ALWAYS) {
|
|
options.conflictSettings = resolver;
|
|
}
|
|
}
|
|
let overwriteMode = resolver.overwrite;
|
|
let result = void 0;
|
|
if (options && options.flags && options.flags & ECopyFlags.REPORT) {
|
|
result = [];
|
|
}
|
|
// call onConflict to eventually throw an error
|
|
overwriteMode = onConflict(from, to, options, resolver);
|
|
// now evaluate the copy conflict settings and eventually abort
|
|
if (options && options.conflictSettings && !resolveConflict(from, to, options, overwriteMode)) {
|
|
return resolve();
|
|
}
|
|
// feature: clean before
|
|
if (options && options.flags) {
|
|
const dstStat = fs.statSync(to);
|
|
if (dstStat.isDirectory()) {
|
|
rmSync(to);
|
|
}
|
|
}
|
|
// walker variables
|
|
const visitorArgs = {
|
|
resolve: resolve,
|
|
reject: reject,
|
|
abort: false,
|
|
filesInProgress: 0,
|
|
resolveSettings: resolver,
|
|
options: options,
|
|
result: result,
|
|
nodes: [],
|
|
onCopyErrorResolveSettings: null
|
|
};
|
|
const nodes = visitorArgs.nodes;
|
|
// a function called when the treeWalkerStream or visitor has been finished
|
|
const process = function () {
|
|
visitorArgs.nodes = nodes;
|
|
if (isDone(nodes)) {
|
|
return resolve(result);
|
|
}
|
|
if (nodes.length) {
|
|
const item = next(nodes);
|
|
if (item) {
|
|
visitor(item.path, item.dst, visitorArgs, item).then(process);
|
|
}
|
|
}
|
|
};
|
|
let flags = EInspectFlags.MODE;
|
|
if (options && options.flags && options.flags & ECopyFlags.FOLLOW_SYMLINKS) {
|
|
flags |= EInspectFlags.SYMLINKS;
|
|
}
|
|
iteratorAsync(from, {
|
|
filter: options.filter,
|
|
flags: flags
|
|
}).then((it) => {
|
|
let node;
|
|
while (node = it.next()) {
|
|
nodes.push({
|
|
path: node.path,
|
|
item: node.item,
|
|
dst: pathUtil.resolve(to, pathUtil.relative(from, node.path)),
|
|
status: ENodeOperationStatus.COLLECTED
|
|
});
|
|
}
|
|
process();
|
|
});
|
|
}).catch(reject);
|
|
});
|
|
}
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29weS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb3B5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBTSxRQUFRLE1BQU0sTUFBTSxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxJQUFJLElBQUksTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRXhDLE9BQU8sRUFBRSxJQUFJLElBQUksVUFBVSxFQUFFLEtBQUssSUFBSSxXQUFXLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDdkUsT0FBTyxFQUFFLE1BQU0sSUFBSSxPQUFPLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsaUJBQWlCLElBQUksUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEUsT0FBTyxFQUFFLElBQUksSUFBSSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDeEUsT0FBTyxFQUFFLElBQUksSUFBSSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDL0MsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGVBQWUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQVduRSxPQUFRLEVBQ1AsY0FBYyxFQUNkLFNBQVMsRUFDVCxVQUFVLEVBQ1Ysb0JBQW9CLEVBQ3BCLE1BQU0sRUFDTixhQUFhLEVBQ2IsWUFBWSxFQUNaLFFBQVEsRUFDUixNQUFNLGlCQUFpQixDQUFDO0FBRTFCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDMUMsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDN0Ms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
|