mono/packages/discourse/lib/oa/howtos.js

475 lines
41 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateHowtos = exports.updateHowto = exports.importHowtos = exports.importHowto = exports.createHowtoTopic = exports.howto_content = exports.read_fragments = exports.mergeLatest = void 0;
const bluebird_1 = require("bluebird");
const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
const core_1 = require("@plastichub/core");
const strings_1 = require("@plastichub/core/strings");
const index_1 = require("../../index");
const constants_1 = require("../discourse/constants");
const lib_1 = require("./lib");
const path = require("path");
const read_1 = require("@plastichub/fs/read");
const exists_1 = require("@plastichub/fs/exists");
const write_1 = require("@plastichub/fs/write");
const fs_1 = require("@plastichub/osr-commons");
const cheerio = require("cheerio");
const users_1 = require("./users");
var escapeHtml = require('escape-html');
const dir_1 = require("@plastichub/fs/dir");
const osr_cli_commons_2 = require("@plastichub/osr-cli-commons");
const FUCKING_TOKEN = 'j7oYrkQe5nbnikCNHcfoP2DGtXKV4iHHzDFip8gGatS145g3B65UU6mI09KeFday9mY5HNQnU2jXUTe7LLkP-w';
const commons_1 = require("./commons");
const mergeLatest = (discorse, options, oa_howtos) => {
const howtos = (0, commons_1.getHowtos)();
oa_howtos.forEach((h) => {
const howto = howtos.find((tu) => {
return tu._id === h._id;
});
if (!howto) {
howtos.push(h);
}
});
(0, write_1.sync)((0, commons_1.getHowtosPath)(), howtos);
return howtos;
};
exports.mergeLatest = mergeLatest;
const updateHowtoFile = (howto) => {
const howtos = (0, commons_1.getHowtos)();
const index = howtos.findIndex((u) => u._id == howto._id);
howtos[index] = howto;
(0, write_1.sync)((0, commons_1.getHowtosPath)(), howtos);
};
const uploadImage = async (discourse, user, image, localPath) => {
if (image.data) {
return image;
}
index_1.logger.debug('uploading image:', image.name);
const upped = await discourse.uploadFile(user.f_id, localPath);
const data = upped.data;
if (data && data.id) {
image.data = data;
}
else {
index_1.logger.error('error uploading image');
}
return image;
};
const read_fragments = (src, config, prefix = '', context = '') => {
if (!(0, exists_1.sync)(src)) {
(0, dir_1.sync)(src);
}
let fragments = (0, osr_cli_commons_2.files)(src, '*.html');
fragments.map((f) => {
config[path.parse(f).name] = (0, commons_1.md_edit_wrap)((0, commons_1.toHTML)(f, true), f, prefix, context);
});
fragments = (0, osr_cli_commons_2.files)(src, '*.md');
fragments.map((f) => {
config[path.parse(f).name] = (0, commons_1.md_edit_wrap)((0, commons_1.toHTML)(f, false), f, prefix, context);
});
return config;
};
exports.read_fragments = read_fragments;
async function howto_content(howto, folder, fragments, templates) {
//const tags = data.v3_tags;
const howtoTags = [];
/*
for (const ht in howto.tags) {
const gt = tags.find((t) => t._id === ht);
if (gt) {
howtoTags.push(gt.label);
// logger.debug('resolved ' + ht + ' to ' + gt.label);
} else {
// logger.error('Cant resolve tag : ' + ht);
}
}
*/
howto.slug = howto.slug.trim();
let s = '';
let step_template = "" + templates.step;
let invalid_step_images = false;
const step_image = (i) => {
if (!i.data || !i.data.short_url) {
index_1.logger.error('invalid image : ' + i.downloadUrl + ' : ' + howto.slug);
invalid_step_images = true;
return '\n';
}
return `\n${(0, commons_1.toMDImage)(i)}`;
};
const step_file = (i) => {
const image = `/howtos/${howto.slug}/${encodeURIComponent((0, lib_1.sanitize)(i.name))}`;
return `<div class="col-sm">
<a href="${image}">
<p>${i.name}"<p/>
</a>
</div>`;
};
const step_files = (s) => {
const files = s.files.map(step_file).join('\n');
return `<div class="row">
${files}
</div>
`;
};
const step_images = (s) => {
const images = s.images.map(step_image).join('\n');
return `${images}`;
};
const step_images_gallery = (s) => {
const images = s.images.map(step_image).join('');
return `<div data-theme-tiles="1">\n${images}</div>`;
};
const step = (s, i) => {
const t = (0, strings_1.substitute)(step_template, {
title: s.title,
text: (0, commons_1.createTextLinks_)(escapeHtml(s.text.trim()).replace(/(?:\r\n|\r|\n)/g, '\n\n')),
step_number: i + 1,
images: s.images.length > 1 ? step_images_gallery(s) : step_images(s)
});
return t;
};
const steps = howto.steps.map((s, i) => step(s, i)).join('\n\n');
const attachments = howto.files.map((f) => {
return `[${(0, lib_1.sanitize)(f.name)}](${f.downloadUrl})`;
});
howto.description = (0, commons_1.removeEmojis)(howto.description);
howto.description = (0, commons_1.createTextLinks_)(howto.description);
let authorName = (howto.user && howto.user.data && howto.user.data && howto.user.data.title) ? howto.user.data.title : (howto.user ? howto.user._id : 'OSR-Plastic');
if (authorName === 'Precious Plastic Headquarters') {
authorName = 'Precious Plastic Nantes';
}
let _3dFiles = [...(0, osr_cli_commons_2.files)(path.resolve(`${folder}`), '**/**/*.step'), ...(0, osr_cli_commons_2.files)(path.resolve(`${folder}`), '**/**/*.STEP'), ...(0, osr_cli_commons_2.files)(path.resolve(`${folder}`), '**/**/*.stp')];
_3dFiles = _3dFiles.map((f) => {
return (0, osr_cli_commons_1.forward_slash)(`${howto.slug}/${path.relative(path.resolve(folder), f)}`);
});
let previews = '';
if (_3dFiles.length) {
previews += '<div class="container">';
previews += '<div class="row"><div class="col-12"><ul class="list-group">';
_3dFiles = _3dFiles.map((f) => {
return `
<li class="list-group-item">
<span>3D Step File: ${f.replace(howto.slug, '')} -
<a href="" class="iframe-lightbox-link" data-src="/howtos/${encodeURIComponent(f).replace('.STEP', '.html').
replace('.step', '.html').replace('.stp', '.html')}">
Preview</a>
</span>
</li>`;
});
previews += _3dFiles.join('');
previews += '</ul></div></div></div>';
}
if (invalid_step_images) {
return false;
}
let index = (0, strings_1.substitute)(templates.howto, {
...fragments,
image: `/howtos/${howto.slug}/${encodeURIComponent((0, lib_1.sanitize)(howto.cover_image.name))}`,
title: howto.title.trim(),
description: escapeHtml(howto.description.trim()) || "",
enabled: howto.moderation == "accepted" ? true : false,
steps: steps,
keywords: ['Precious plastic', 'Preciousplastic', 'plastichub', 'osr', ...howtoTags].join(','),
user: howto._createdBy,
files: `${attachments.join('\n')}`,
authorName: authorName,
authorUrl: `https://osr-plastic.org/users/${howto.user ? howto.user._id : 'https://osr-plastic.org/users/plastichub'}.html`,
// short: escapeHtml(howto.description.trim()).substring(0, 100) + '....',
slug: howto.slug,
previews3D: previews
});
const $ = cheerio.load(index, {
xmlMode: true
});
/*
$('a').each(function () {
const url = $(this).attr("href");
logger.debug('url : ' + url);
if(url.indexOf('dropbox')){
}
});*/
//write(index_md, pretty(index, { ocd: true }));
return (0, commons_1.removeEmojis)(index);
}
exports.howto_content = howto_content;
const createHowtoTopic = async (discourse, howto, create = true) => {
if (!howto.category || !howto.category.label) {
howto.category = commons_1.DEFAULT_HT_CATEGORY;
index_1.logger.error(`create howto : invalid category: ${howto.category} : ${howto.slug}`);
}
const user = (0, commons_1.getHowtoUser)(howto);
if (!user) {
index_1.logger.error(`create howto : invalid user : ${howto._createdBy} :: ${howto.title}`);
}
const howto_folder = (0, commons_1.kb_howto_folder)(howto);
const howto_cover_image = (0, commons_1.kb_howto_file)(howto, howto.cover_image.name);
if (!(0, exists_1.sync)(howto_folder)) {
index_1.logger.error('howto folder doesnt exists', howto.title);
}
if (!(0, exists_1.sync)(howto_cover_image)) {
index_1.logger.error('howto cover image doesnt exists', howto.title);
}
if (!user || !user.f_id) {
index_1.logger.error(`create howto : invalid user : ${howto._createdBy} :: ${howto.title}`);
return false;
}
howto.cover_image = await uploadImage(discourse, user, howto.cover_image, howto_cover_image);
updateHowtoFile(howto);
let invalid_images = false;
for (const step of howto.steps) {
let i = 0;
for await (const image of step.images) {
const image_name = (0, lib_1.sanitize)(image.name);
const imagePath = path.resolve(path.join(howto_folder, (0, lib_1.sanitize)(image_name)));
if (!(0, exists_1.sync)(imagePath)) {
index_1.logger.error('step image doesnt exists : ' + image.name + ' in ' + howto.slug);
invalid_images = true;
continue;
}
step.images[i] = await uploadImage(discourse, user, step.images[i], imagePath);
updateHowtoFile(howto);
i++;
}
}
if (invalid_images) {
index_1.logger.error('invalid images : ' + howto.slug);
return false;
}
const cat = constants_1.HT_CATS[howto.category.label];
if (!cat) {
index_1.logger.error('invalid kat');
return false;
}
const templatesRoot = path.resolve((0, fs_1.resolve)("${OSR_ROOT}/osr-templates/discourse"));
const cPath = path.resolve(`${templatesRoot}/base.json`);
index_1.logger.debug(`read config at ${cPath}`);
const config = (0, read_1.sync)(cPath, 'json');
const templates = path.resolve(`${templatesRoot}/howto`);
if (!(0, exists_1.sync)(templates)) {
index_1.logger.error(`\t Cant find templates at ${templates}, path doesn't exists`);
return;
}
let fragments = { ...config.variables };
(0, exports.read_fragments)(templates, fragments, "product_rel_path_name", "machine");
let template = (0, read_1.sync)(path.resolve(`${templates}/howto.md`), 'string');
let step = (0, read_1.sync)(path.resolve(`${templates}/step.md`), 'string');
(0, core_1.resolveConfig)(fragments);
const content = await howto_content(howto, howto_folder, fragments, {
howto: template,
step: '' + step
});
if (!content) {
index_1.logger.error('invalid content : ' + howto.slug);
return;
}
let data;
if (create) {
data = await discourse.createPost((0, lib_1.sanitize)(howto.title), content, cat);
if (data) {
index_1.logger.debug('created topic : ' + howto.title + ' : ' + data.id);
if (data && data.id) {
howto.post_id = data.id;
howto.topic_id = data.topic_id;
updateHowtoFile(howto);
try {
index_1.logger.debug('change user to ', user._id);
await discourse.changeOwner(howto.post_id, howto.topic_id, (0, users_1.get_user_name)(user));
}
catch (e) {
index_1.logger.debug('changing owner ' + howto.title + ' failed!');
howto.oF = true;
updateHowtoFile(howto);
}
}
else {
index_1.logger.debug('creating ' + howto.title + ' failed!', data.errors);
howto.post_id = 'failed';
if (data.errors) {
if (data.errors[0] && data.errors[0] === 'Title has already been used') {
index_1.logger.error('title already used : ' + howto.slug);
howto.post_id = 'already';
}
}
updateHowtoFile(howto);
}
}
}
else {
data = await discourse.updatePost(howto.post_id, content);
howto._updatedContent1 = true;
updateHowtoFile(howto);
}
};
exports.createHowtoTopic = createHowtoTopic;
const importHowto = async (discorse, howto) => {
//const howtos = getHowtos()
//const index = howtos.findIndex((u) => u._id == howto._id)
const ret = await (0, exports.createHowtoTopic)(discorse, howto);
return ret;
};
exports.importHowto = importHowto;
const importHowtos = async (discorse, options, howtos) => {
index_1.logger.debug('read howtos from ', path.resolve((0, commons_1.getHowtosPath)()));
howtos = (0, exports.mergeLatest)(discorse, options, howtos);
howtos = howtos.filter((h) => {
if (h.title === 'Build a Fishing Canoe') {
//debugger
}
if (h.post_id || h.post_id < 0) {
return false;
}
if (h.post_id === 'failed') {
index_1.logger.debug('skip failed : ' + h.slug);
return false;
}
//if (u.alreadyExists || u.invalidData) {
// return false;
//}
return true;
});
return await bluebird_1.Promise.resolve(howtos).map((h) => {
try {
return new Promise((resolve, reject) => {
setTimeout(() => {
const d = (0, exports.importHowto)(discorse, h);
if (d) {
d.then(resolve);
}
else {
reject();
}
}, 500);
});
}
catch (e) {
debugger;
index_1.logger.error('error creating howto ' + h._id, e);
}
}, { concurrency: 1 });
};
exports.importHowtos = importHowtos;
/////////////////////////////////////////////////////////////////////////
//
// Update Howtos
//
let _discorseTags;
const getDiscourseTags = async (discourse) => {
if (!_discorseTags) {
_discorseTags = await discourse.getTags();
}
return _discorseTags;
};
const updateHowto = async (discourse, howto, options) => {
const tags = (0, commons_1.read_tags)(options.src);
let howtoTags = [];
for (const ht in howto.tags) {
const t = ht;
const gt = tags.find((t) => {
return t._id === ht;
});
if (gt) {
howtoTags.push(gt.label);
}
else {
// logger.error('Cant resolve tag : ' + ht);
}
}
howtoTags.push('oa-import');
let discorseTags = await getDiscourseTags(discourse);
const cat = constants_1.HT_CATS[howto.category.label];
if (howtoTags && howtoTags.length) {
try {
const ret = await discourse.updateTopic(howto.topic_id, cat, (0, lib_1.sanitize)(howto.title), howtoTags);
index_1.logger.debug('Updating howto tags : ' + howto.title);
}
catch (error) {
index_1.logger.error('Error updating post' + howto.title, howto.topic_id, cat, howtoTags, error);
howto['updateFailed1'] = 1;
updateHowtoFile(howto);
//debugger
}
}
howto.updatedTags = true;
updateHowtoFile(howto);
const _date = howto._modified || howto._created;
if (_date) {
let date = new Date(_date);
index_1.logger.debug('update ts ' + howto.slug + ' : ' + new Date(date).toLocaleDateString());
let offset = 0;
const valueOf = date.valueOf() - (offset) * 60000;
let ts = Math.floor(valueOf / 1000);
const tUpdate = await discourse.updateTopicTimestamp(howto.topic_id, ts, FUCKING_TOKEN);
if (tUpdate) {
howto.updatedTime8 = true;
updateHowtoFile(howto);
return true;
}
}
else {
index_1.logger.error('Have no ts : ' + howto.slug);
}
};
exports.updateHowto = updateHowto;
const updateHowtos = async (discorse, options, howtos) => {
index_1.logger.debug('update howtos from ', path.resolve((0, commons_1.getHowtosPath)()));
howtos = (0, exports.mergeLatest)(discorse, options, howtos);
const forceUpdateContent = true;
const forceUpdateMeta = true;
const updateContent = true;
const updateMeta = true;
howtos = howtos.filter((h) => {
if (!h.post_id || !h.topic_id) {
return false;
}
if (h.post_id === 'failed') {
index_1.logger.debug('skip failed : ' + h.slug);
return false;
}
if (forceUpdateContent || forceUpdateMeta) {
return true;
}
if (!h._updatedContent1) {
return true;
}
if (h.updatedTags && h.updatedTime8) {
return false;
}
if (!h.updatedTags || !h.updatedTime8) {
return true;
}
return true;
});
return await bluebird_1.Promise.resolve(howtos).map((h) => {
try {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (updateContent) {
index_1.logger.debug('\t recook howto content', h.title);
let d = (0, exports.createHowtoTopic)(discorse, h, false);
d.then(() => {
if (updateMeta) {
d = (0, exports.updateHowto)(discorse, h, options);
if (d) {
d.then(resolve);
}
else {
reject();
}
}
else {
resolve(1);
}
});
}
}, 500);
});
}
catch (e) {
debugger;
index_1.logger.error('error creating howto ' + h._id, e);
}
}, { concurrency: 1 });
};
exports.updateHowtos = updateHowtos;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG93dG9zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9vYS9ob3d0b3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsdUNBQThDO0FBRTlDLGlFQUEyRDtBQUMzRCwyQ0FBZ0Q7QUFDaEQsc0RBQXFEO0FBV3JELHVDQUVvQjtBQUVwQixzREFFK0I7QUFJL0IsK0JBQXlDO0FBRXpDLDZCQUE0QjtBQUM1Qiw4Q0FBa0Q7QUFDbEQsa0RBQXNEO0FBRXRELGdEQUFvRDtBQUVwRCx1REFBd0Q7QUFFeEQsbUNBQWtDO0FBQ2xDLG1DQUFpRDtBQUVqRCxJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDeEMsNENBQWtEO0FBQ2xELGlFQUFtRDtBQUluRCxNQUFNLGFBQWEsR0FBRyx3RkFBd0YsQ0FBQTtBQUU5Ryx1Q0Fja0I7QUFFWCxNQUFNLFdBQVcsR0FBRyxDQUFDLFFBQVEsRUFBRSxPQUFpQixFQUFFLFNBQTJCLEVBQW9CLEVBQUU7SUFFdEcsTUFBTSxNQUFNLEdBQVUsSUFBQSxtQkFBUyxHQUFFLENBQUE7SUFDakMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQ3BCLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtZQUM3QixPQUFPLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQTtRQUMzQixDQUFDLENBQUMsQ0FBQTtRQUNGLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDUixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBO1NBQ2pCO0lBRUwsQ0FBQyxDQUFDLENBQUE7SUFDRixJQUFBLFlBQUssRUFBQyxJQUFBLHVCQUFhLEdBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUM5QixPQUFPLE1BQU0sQ0FBQTtBQUNqQixDQUFDLENBQUE7QUFkWSxRQUFBLFdBQVcsZUFjdkI7QUFFRCxNQUFNLGVBQWUsR0FBRyxDQUFDLEtBQUssRUFBRSxFQUFFO0lBQzlCLE1BQU0sTUFBTSxHQUFVLElBQUEsbUJBQVMsR0FBRSxDQUFBO0lBQ2pDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ3pELE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUE7SUFDckIsSUFBQSxZQUFLLEVBQUMsSUFBQSx1QkFBYSxHQUFFLEVBQUUsTUFBTSxDQUFDLENBQUE7QUFDbEMsQ0FBQyxDQUFBO0FBR0QsTUFBTSxXQUFXLEdBQUcsS0FBSyxFQUFFLFNBQXFCLEVBQUUsSUFBaUIsRUFBRSxLQUF3QixFQUFFLFNBQVMsRUFBRSxFQUFFO0lBQ3hHLElBQUksS0FBSyxDQUFDLElBQUksRUFBRTtRQUNaLE9BQU8sS0FBSyxDQUFBO0tBQ2Y7SUFDRCxjQUFNLENBQUMsS0FBSyxDQUFDLGtCQUFrQixFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM1QyxNQUFNLEtBQUssR0FBUSxNQUFNLFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQTtJQUNuRSxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO0lBQ3hCLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUU7UUFDakIsS0FBSyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7S0FDcEI7U0FBTTtRQUNILGNBQU0sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQTtLQUN4QztJQUNELE9BQU8sS0FBSyxDQUFBO0FBQ2hCLENBQUMsQ0FBQTtBQUdNLE1BQU0sY0FBYyxHQUFHLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEdBQUcsRUFBRSxFQUFFLE9BQU8sR0FBRyxFQUFFLEVBQUUsRUFBRTtJQUNyRSxJQUFJLENBQUMsSUFBQSxhQUFNLEVBQUMsR0FBRyxDQUFDLEVBQUU7UUFDZCxJQUFBLFVBQUssRUFBQyxHQUFHLENBQUMsQ0FBQztLQUNkO0lBQ0QsSUFBSSxTQUFTLEdBQUcsSUFBQSx1QkFBSyxFQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNyQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7UUFDaEIsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBQSxzQkFBWSxFQUFDLElBQUEsZ0JBQU0sRUFBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNuRixDQUFDLENBQUMsQ0FBQztJQUVILFNBQVMsR0FBRyxJQUFBLHVCQUFLLEVBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQy9CLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtRQUNoQixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFBLHNCQUFZLEVBQUMsSUFBQSxnQkFBTSxFQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3BGLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQyxDQUFBO0FBZFksUUFBQSxjQUFjLGtCQWMxQjtBQUVNLEtBQUssVUFBVSxhQUFhLENBQUMsS0FBcUIsRUFBRSxNQUFjLEVBQUUsU0FBUyxFQUFFLFNBQWM7SUFFaEcsNEJBQTRCO0lBQzVCLE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQztJQUNyQjs7Ozs7Ozs7OztFQVVGO0lBRUUsS0FBSyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBRS9CLElBQUksQ0FBQyxHQUFXLEVBQUUsQ0FBQztJQUVuQixJQUFJLGFBQWEsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQztJQUV4QyxJQUFJLG1CQUFtQixHQUFHLEtBQUssQ0FBQTtJQUUvQixNQUFNLFVBQVUsR0FBRyxDQUFDLENBQW9CLEVBQUUsRUFBRTtRQUN4QyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO1lBQzlCLGNBQU0sQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEdBQUcsQ0FBQyxDQUFDLFdBQVcsR0FBRyxLQUFLLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ3JFLG1CQUFtQixHQUFHLElBQUksQ0FBQTtZQUMxQixPQUFPLElBQUksQ0FBQTtTQUNkO1FBQ0QsT0FBTyxLQUFLLElBQUEsbUJBQVMsRUFBQyxDQUFDLENBQUMsRUFBRSxDQUFBO0lBQzlCLENBQUMsQ0FBQTtJQUVELE1BQU0sU0FBUyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUU7UUFDcEIsTUFBTSxLQUFLLEdBQUcsV0FBVyxLQUFLLENBQUMsSUFBSSxJQUFJLGtCQUFrQixDQUFDLElBQUEsY0FBUSxFQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDOUUsT0FBTzsyQkFDWSxLQUFLO3lCQUNQLENBQUMsQ0FBQyxJQUFJOzttQkFFWixDQUFBO0lBQ2YsQ0FBQyxDQUFBO0lBRUQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRTtRQUNyQixNQUFNLEtBQUssR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsT0FBTztrQkFDRyxLQUFLOztTQUVkLENBQUE7SUFDTCxDQUFDLENBQUE7SUFFRCxNQUFNLFdBQVcsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQ3RCLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuRCxPQUFPLEdBQUcsTUFBTSxFQUFFLENBQUE7SUFDdEIsQ0FBQyxDQUFBO0lBRUQsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQzlCLE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNqRCxPQUFPLCtCQUErQixNQUFNLFFBQVEsQ0FBQTtJQUN4RCxDQUFDLENBQUE7SUFFRCxNQUFNLElBQUksR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUNsQixNQUFNLENBQUMsR0FBRyxJQUFBLG9CQUFVLEVBQUMsYUFBYSxFQUFFO1lBQ2hDLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSztZQUNkLElBQUksRUFBRSxJQUFBLDBCQUFnQixFQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3BGLFdBQVcsRUFBRSxDQUFDLEdBQUcsQ0FBQztZQUNsQixNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztTQUN4RSxDQUFDLENBQUM7UUFDSCxPQUFPLENBQUMsQ0FBQztJQUNiLENBQUMsQ0FBQTtJQUVELE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUVqRSxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQ3RDLE9BQU8sSUFBSSxJQUFBLGNBQVEsRUFBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLFdBQVcsR0FBRyxDQUFBO0lBQ3BELENBQUMsQ0FBQyxDQUFBO0lBRUYsS0FBSyxDQUFDLFdBQVcsR0FBRyxJQUFBLHNCQUFZLEVBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3BELEtBQUssQ0FBQyxXQUFXLEdBQUcsSUFBQSwwQkFBZ0IsRUFBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUM7SUFFeEQsSUFBSSxVQUFVLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3JLLElBQUksVUFBVSxLQUFLLCtCQUErQixFQUFFO1FBQ2hELFVBQVUsR0FBRyx5QkFBeUIsQ0FBQztLQUMxQztJQUVELElBQUksUUFBUSxHQUFRLENBQUMsR0FBRyxJQUFBLHVCQUFLLEVBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsY0FBYyxDQUFDLEVBQUUsR0FBRyxJQUFBLHVCQUFLLEVBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsY0FBYyxDQUFDLEVBQUUsR0FBRyxJQUFBLHVCQUFLLEVBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsYUFBYSxDQUFDLENBQUMsQ0FBQztJQUVuTCxRQUFRLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQzFCLE9BQU8sSUFBQSwrQkFBYSxFQUFDLEdBQUcsS0FBSyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3BGLENBQUMsQ0FBQyxDQUFBO0lBRUYsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDO0lBQ2xCLElBQUksUUFBUSxDQUFDLE1BQU0sRUFBRTtRQUNqQixRQUFRLElBQUkseUJBQXlCLENBQUM7UUFDdEMsUUFBUSxJQUFJLDhEQUE4RCxDQUFDO1FBRTNFLFFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDMUIsT0FBTzs7c0NBRW1CLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7NEVBQ2Esa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUM7Z0JBQ3ZHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUM7OztrQkFHcEQsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO1FBRUYsUUFBUSxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDOUIsUUFBUSxJQUFJLHlCQUF5QixDQUFDO0tBQ3pDO0lBRUQsSUFBSSxtQkFBbUIsRUFBRTtRQUNyQixPQUFPLEtBQUssQ0FBQTtLQUNmO0lBRUQsSUFBSSxLQUFLLEdBQUcsSUFBQSxvQkFBVSxFQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUU7UUFDcEMsR0FBRyxTQUFTO1FBQ1osS0FBSyxFQUFFLFdBQVcsS0FBSyxDQUFDLElBQUksSUFBSSxrQkFBa0IsQ0FBQyxJQUFBLGNBQVEsRUFBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUU7UUFDdEYsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFO1FBQ3pCLFdBQVcsRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFDdkQsT0FBTyxFQUFFLEtBQUssQ0FBQyxVQUFVLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUs7UUFDdEQsS0FBSyxFQUFFLEtBQUs7UUFDWixRQUFRLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUM5RixJQUFJLEVBQUUsS0FBSyxDQUFDLFVBQVU7UUFDdEIsS0FBSyxFQUFFLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUNsQyxVQUFVLEVBQUUsVUFBVTtRQUN0QixTQUFTLEVBQUUsaUNBQWlDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQywwQ0FBMEMsT0FBTztRQUMzSCwwRUFBMEU7UUFDMUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO1FBQ2hCLFVBQVUsRUFBRSxRQUFRO0tBQ3ZCLENBQUMsQ0FBQztJQUVILE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBZSxFQUFFO1FBQ3BDLE9BQU8sRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztJQUVIOzs7Ozs7O1NBT0s7SUFFTCxnREFBZ0Q7SUFFaEQsT0FBTyxJQUFBLHNCQUFZLEVBQUMsS0FBSyxDQUFDLENBQUE7QUFFOUIsQ0FBQztBQXBKRCxzQ0FvSkM7QUFFTSxNQUFNLGdCQUFnQixHQUFHLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBcUIsRUFBRSxNQUFNLEdBQUcsSUFBSSxFQUFFLEVBQUU7SUFFdEYsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTtRQUMxQyxLQUFLLENBQUMsUUFBUSxHQUFHLDZCQUFtQixDQUFBO1FBQ3BDLGNBQU0sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLEtBQUssQ0FBQyxRQUFRLE1BQU0sS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUE7S0FDckY7SUFFRCxNQUFNLElBQUksR0FBRyxJQUFBLHNCQUFZLEVBQUMsS0FBSyxDQUFDLENBQUE7SUFDaEMsSUFBSSxDQUFDLElBQUksRUFBRTtRQUNQLGNBQU0sQ0FBQyxLQUFLLENBQUMsaUNBQWlDLEtBQUssQ0FBQyxVQUFVLE9BQU8sS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUE7S0FDdEY7SUFFRCxNQUFNLFlBQVksR0FBRyxJQUFBLHlCQUFlLEVBQUMsS0FBSyxDQUFDLENBQUE7SUFFM0MsTUFBTSxpQkFBaUIsR0FBRyxJQUFBLHVCQUFhLEVBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUE7SUFFdEUsSUFBSSxDQUFDLElBQUEsYUFBTSxFQUFDLFlBQVksQ0FBQyxFQUFFO1FBQ3ZCLGNBQU0sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO0tBQzFEO0lBRUQsSUFBSSxDQUFDLElBQUEsYUFBTSxFQUFDLGlCQUFpQixDQUFDLEVBQUU7UUFDNUIsY0FBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUE7S0FDL0Q7SUFFRCxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtRQUNyQixjQUFNLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxLQUFLLENBQUMsVUFBVSxPQUFPLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFBO1FBQ25GLE9BQU8sS0FBSyxDQUFBO0tBQ2Y7SUFFRCxLQUFLLENBQUMsV0FBVyxHQUFHLE1BQU0sV0FBVyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRSxpQkFBaUIsQ0FBQyxDQUFBO0lBRTVGLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUV0QixJQUFJLGNBQWMsR0FBRyxLQUFLLENBQUE7SUFFMUIsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFO1FBQzVCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNULElBQUksS0FBSyxFQUFFLE1BQU0sS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDbkMsTUFBTSxVQUFVLEdBQUcsSUFBQSxjQUFRLEVBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBO1lBRXZDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBQSxjQUFRLEVBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBRTdFLElBQUksQ0FBQyxJQUFBLGFBQU0sRUFBQyxTQUFTLENBQUMsRUFBRTtnQkFDcEIsY0FBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsR0FBRyxLQUFLLENBQUMsSUFBSSxHQUFHLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQzlFLGNBQWMsR0FBRyxJQUFJLENBQUE7Z0JBQ3JCLFNBQVE7YUFDWDtZQUVELElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxXQUFXLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFBO1lBQzlFLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUN0QixDQUFDLEVBQUUsQ0FBQTtTQUNOO0tBQ0o7SUFFRCxJQUFJLGNBQWMsRUFBRTtRQUNoQixjQUFNLENBQUMsS0FBSyxDQUFDLG1CQUFtQixHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUM5QyxPQUFPLEtBQUssQ0FBQTtLQUNmO0lBRUQsTUFBTSxHQUFHLEdBQUcsbUJBQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBRXpDLElBQUksQ0FBQyxHQUFHLEVBQUU7UUFDTixjQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFBO1FBQzNCLE9BQU8sS0FBSyxDQUFBO0tBQ2Y7SUFFRCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsWUFBTyxFQUFDLHFDQUFxQyxDQUFDLENBQUMsQ0FBQTtJQUNsRixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsYUFBYSxZQUFZLENBQUMsQ0FBQTtJQUV4RCxjQUFNLENBQUMsS0FBSyxDQUFDLGtCQUFrQixLQUFLLEVBQUUsQ0FBQyxDQUFBO0lBRXZDLE1BQU0sTUFBTSxHQUFHLElBQUEsV0FBSSxFQUFDLEtBQUssRUFBRSxNQUFNLENBQVEsQ0FBQTtJQUV6QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsYUFBYSxRQUFRLENBQUMsQ0FBQTtJQUV4RCxJQUFJLENBQUMsSUFBQSxhQUFNLEVBQUMsU0FBUyxDQUFDLEVBQUU7UUFDcEIsY0FBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsU0FBUyx1QkFBdUIsQ0FBQyxDQUFBO1FBQzNFLE9BQU87S0FDVjtJQUVELElBQUksU0FBUyxHQUFRLEVBQUUsR0FBRyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUE7SUFFNUMsSUFBQSxzQkFBYyxFQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxDQUFDLENBQUE7SUFFeEUsSUFBSSxRQUFRLEdBQUcsSUFBQSxXQUFJLEVBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLFNBQVMsV0FBVyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUE7SUFFcEUsSUFBSSxJQUFJLEdBQUcsSUFBQSxXQUFJLEVBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLFNBQVMsVUFBVSxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUE7SUFFL0QsSUFBQSxvQkFBYSxFQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRXpCLE1BQU0sT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUMvQixLQUFLLEVBQ0wsWUFBWSxFQUNaLFNBQVMsRUFDVDtRQUNJLEtBQUssRUFBRSxRQUFRO1FBQ2YsSUFBSSxFQUFFLEVBQUUsR0FBRyxJQUFJO0tBQ2xCLENBQUMsQ0FBQztJQUVQLElBQUksQ0FBQyxPQUFPLEVBQUU7UUFDVixjQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMvQyxPQUFNO0tBQ1Q7SUFFRCxJQUFJLElBQUksQ0FBQTtJQUNSLElBQUksTUFBTSxFQUFFO1FBQ1IsSUFBSSxHQUFHLE1BQU0sU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFBLGNBQVEsRUFBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZFLElBQUksSUFBSSxFQUFFO1lBQ04sY0FBTSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQU0sR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDbEUsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUUsRUFBRTtnQkFDakIsS0FBSyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUN4QixLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUE7Z0JBQzlCLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQTtnQkFDdEIsSUFBSTtvQkFDQSxjQUFNLENBQUMsS0FBSyxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtvQkFDekMsTUFBTSxTQUFTLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLFFBQVEsRUFBRSxJQUFBLHFCQUFhLEVBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztpQkFDbkY7Z0JBQUMsT0FBTyxDQUFDLEVBQUU7b0JBQ1IsY0FBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUMsS0FBSyxHQUFHLFVBQVUsQ0FBQyxDQUFDO29CQUMzRCxLQUFLLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQztvQkFDaEIsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFBO2lCQUN6QjthQUNKO2lCQUFNO2dCQUNILGNBQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQyxLQUFLLEdBQUcsVUFBVSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDbEUsS0FBSyxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUM7Z0JBQ3pCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtvQkFDYixJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyw2QkFBNkIsRUFBRTt3QkFDcEUsY0FBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUE7d0JBQ2xELEtBQUssQ0FBQyxPQUFPLEdBQUcsU0FBUyxDQUFDO3FCQUM3QjtpQkFDSjtnQkFDRCxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUE7YUFDekI7U0FDSjtLQUNKO1NBQU07UUFDSCxJQUFJLEdBQUcsTUFBTSxTQUFTLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDekQsS0FBSyxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQTtRQUM3QixlQUFlLENBQUMsS0FBSyxDQUFDLENBQUE7S0FDekI7QUFDTCxDQUFDLENBQUE7QUExSVksUUFBQSxnQkFBZ0Isb0JBMEk1QjtBQUlNLE1BQU0sV0FBVyxHQUFHLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBcUIsRUFBRSxFQUFFO0lBQ2pFLDRCQUE0QjtJQUM1QiwyREFBMkQ7SUFDM0QsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFBLHdCQUFnQixFQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUNuRCxPQUFPLEdBQUcsQ0FBQTtBQUNkLENBQUMsQ0FBQTtBQUxZLFFBQUEsV0FBVyxlQUt2QjtBQUVNLE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBaUIsRUFBRSxNQUF3QixFQUFFLEVBQUU7SUFFeEYsY0FBTSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsdUJBQWEsR0FBRSxDQUFDLENBQUMsQ0FBQTtJQUVoRSxNQUFNLEdBQUcsSUFBQSxtQkFBVyxFQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFFL0MsTUFBTSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtRQUV6QixJQUFJLENBQUMsQ0FBQyxLQUFLLEtBQUssdUJBQXVCLEVBQUU7WUFDckMsVUFBVTtTQUNiO1FBRUQsSUFBSSxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsQ0FBQyxPQUFpQixHQUFHLENBQUMsRUFBRTtZQUN0QyxPQUFPLEtBQUssQ0FBQztTQUNoQjtRQUVELElBQUksQ0FBQyxDQUFDLE9BQU8sS0FBSyxRQUFRLEVBQUU7WUFDeEIsY0FBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDdkMsT0FBTyxLQUFLLENBQUE7U0FDZjtRQUVELHlDQUF5QztRQUN6QyxtQkFBbUI7UUFDbkIsR0FBRztRQUNILE9BQU8sSUFBSSxDQUFBO0lBQ2YsQ0FBQyxDQUFDLENBQUE7SUFFRixPQUFPLE1BQU0sa0JBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBaUIsRUFBRSxFQUFFO1FBQzVELElBQUk7WUFDQSxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUNuQyxVQUFVLENBQUMsR0FBRyxFQUFFO29CQUNaLE1BQU0sQ0FBQyxHQUFHLElBQUEsbUJBQVcsRUFBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUE7b0JBQ2xDLElBQUksQ0FBQyxFQUFFO3dCQUNILENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7cUJBQ2xCO3lCQUFNO3dCQUNILE1BQU0sRUFBRSxDQUFBO3FCQUNYO2dCQUNMLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQTtZQUVYLENBQUMsQ0FBQyxDQUFBO1NBRUw7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNSLFFBQVEsQ0FBQztZQUNULGNBQU0sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQTtTQUNuRDtJQUNMLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0FBQzFCLENBQUMsQ0FBQTtBQTlDWSxRQUFBLFlBQVksZ0JBOEN4QjtBQUVELHlFQUF5RTtBQUN6RSxFQUFFO0FBQ0YsaUJBQWlCO0FBQ2pCLEVBQUU7QUFDRixJQUFJLGFBQWEsQ0FBQTtBQUVqQixNQUFNLGdCQUFnQixHQUFHLEtBQUssRUFBRSxTQUFxQixFQUFFLEVBQUU7SUFDckQsSUFBSSxDQUFDLGFBQWEsRUFBRTtRQUNoQixhQUFhLEdBQUcsTUFBTSxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUE7S0FDNUM7SUFFRCxPQUFPLGFBQWEsQ0FBQTtBQUN4QixDQUFDLENBQUE7QUFFTSxNQUFNLFdBQVcsR0FBRyxLQUFLLEVBQUUsU0FBcUIsRUFBRSxLQUFxQixFQUFFLE9BQWlCLEVBQUUsRUFBRTtJQUVqRyxNQUFNLElBQUksR0FBRyxJQUFBLG1CQUFTLEVBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ25DLElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQTtJQUVsQixLQUFLLE1BQU0sRUFBRSxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUU7UUFDekIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQ1osTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFO1lBQzVCLE9BQU8sQ0FBQyxDQUFDLEdBQUcsS0FBSyxFQUFFLENBQUE7UUFDdkIsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLEVBQUUsRUFBRTtZQUNKLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzVCO2FBQU07WUFDSCw0Q0FBNEM7U0FDL0M7S0FDSjtJQUVELFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7SUFFM0IsSUFBSSxZQUFZLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUVwRCxNQUFNLEdBQUcsR0FBRyxtQkFBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUE7SUFFekMsSUFBSSxTQUFTLElBQUksU0FBUyxDQUFDLE1BQU0sRUFBRTtRQUMvQixJQUFJO1lBQ0EsTUFBTSxHQUFHLEdBQUcsTUFBTSxTQUFTLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsR0FBYSxFQUFFLElBQUEsY0FBUSxFQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQTtZQUN4RyxjQUFNLENBQUMsS0FBSyxDQUFDLHdCQUF3QixHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQTtTQUN2RDtRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ1osY0FBTSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBQyxLQUFLLENBQUMsQ0FBQTtZQUN2RixLQUFLLENBQUMsZUFBZSxDQUFDLEdBQUMsQ0FBQyxDQUFBO1lBQ3hCLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUN0QixzQkFBc0I7U0FDekI7S0FFSjtJQUNELEtBQUssQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFBO0lBQ3hCLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUV0QixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsU0FBUyxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUE7SUFFL0MsSUFBSSxLQUFLLEVBQUU7UUFDUCxJQUFJLElBQUksR0FBUyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNoQyxjQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsSUFBSSxHQUFHLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUE7UUFDckYsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFBO1FBQ2QsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFBO1FBQ2pELElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFBO1FBQ25DLE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsRUFBRSxFQUFFLGFBQWEsQ0FBQyxDQUFBO1FBQ3ZGLElBQUksT0FBTyxFQUFFO1lBQ1QsS0FBSyxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUE7WUFDekIsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQ3RCLE9BQU8sSUFBSSxDQUFBO1NBQ2Q7S0FDSjtTQUFNO1FBQ0gsY0FBTSxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBO0tBQzdDO0FBQ0wsQ0FBQyxDQUFBO0FBdkRZLFFBQUEsV0FBVyxlQXVEdkI7QUFFTSxNQUFNLFlBQVksR0FBRyxLQUFLLEVBQUUsUUFBUSxFQUFFLE9BQWlCLEVBQUUsTUFBd0IsRUFBRSxFQUFFO0lBRXhGLGNBQU0sQ0FBQyxLQUFLLENBQUMscUJBQXFCLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFBLHVCQUFhLEdBQUUsQ0FBQyxDQUFDLENBQUE7SUFFbEUsTUFBTSxHQUFHLElBQUEsbUJBQVcsRUFBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBRS9DLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFBO0lBQy9CLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQTtJQUU1QixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUE7SUFDMUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFBO0lBRXZCLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7UUFFekIsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFO1lBQzNCLE9BQU8sS0FBSyxDQUFBO1NBQ2Y7UUFFRCxJQUFJLENBQUMsQ0FBQyxPQUFPLEtBQUssUUFBUSxFQUFFO1lBQ3hCLGNBQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ3ZDLE9BQU8sS0FBSyxDQUFBO1NBQ2Y7UUFFRCxJQUFJLGtCQUFrQixJQUFJLGVBQWUsRUFBRTtZQUN2QyxPQUFPLElBQUksQ0FBQTtTQUNkO1FBRUQsSUFBSSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsRUFBRTtZQUNyQixPQUFPLElBQUksQ0FBQTtTQUNkO1FBRUQsSUFBSSxDQUFDLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQyxZQUFZLEVBQUU7WUFDakMsT0FBTyxLQUFLLENBQUE7U0FDZjtRQUVELElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxJQUFJLENBQUMsQ0FBQyxDQUFDLFlBQVksRUFBRTtZQUNuQyxPQUFPLElBQUksQ0FBQTtTQUNkO1FBRUQsT0FBTyxJQUFJLENBQUE7SUFDZixDQUFDLENBQUMsQ0FBQTtJQUVGLE9BQU8sTUFBTSxrQkFBUSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFpQixFQUFFLEVBQUU7UUFDNUQsSUFBSTtZQUNBLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQ25DLFVBQVUsQ0FBQyxHQUFHLEVBQUU7b0JBQ1osSUFBSSxhQUFhLEVBQUU7d0JBQ2YsY0FBTSxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUE7d0JBQ2hELElBQUksQ0FBQyxHQUFHLElBQUEsd0JBQWdCLEVBQUMsUUFBUSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQTt3QkFDNUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7NEJBQ1IsSUFBSSxVQUFVLEVBQUU7Z0NBQ1osQ0FBQyxHQUFHLElBQUEsbUJBQVcsRUFBQyxRQUFRLEVBQUUsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFBO2dDQUNyQyxJQUFJLENBQUMsRUFBRTtvQ0FDSCxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFBO2lDQUNsQjtxQ0FBTTtvQ0FDSCxNQUFNLEVBQUUsQ0FBQTtpQ0FDWDs2QkFDSjtpQ0FBTTtnQ0FDSCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUE7NkJBQ2I7d0JBQ0wsQ0FBQyxDQUFDLENBQUE7cUJBQ0w7Z0JBQ0wsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFBO1lBQ1gsQ0FBQyxDQUFDLENBQUE7U0FFTDtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1IsUUFBUSxDQUFDO1lBQ1QsY0FBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFBO1NBQ25EO0lBQ0wsQ0FBQyxFQUFFLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUE7QUFDMUIsQ0FBQyxDQUFBO0FBdEVZLFFBQUEsWUFBWSxnQkFzRXhCIn0=