UNPKG

facturacionelectronicapy-xmlsign

Version:

Módulo NodeJs para la firma de Archivo XML para la Facturación Electrónica en Paraguay

290 lines 25.3 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const find_java_home_1 = __importDefault(require("find-java-home")); const { exec } = require("child_process"); var fs = require("fs"); class XMLDsig { constructor() { } /** * Firma con Java, retornando el documento firmado en el buffer de salida * @param xml * @param tag * @returns */ signDocument(xml, tag, file, passphase) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { find_java_home_1.default({ allowJre: true }, (err, java8Path) => { java8Path += "/bin/java"; if (err) return console.log(err); //Comentar esta linea al llevar a Produccion, por que aqui trae java 6 if (process.env.java8_home) { //java8Path = `"C:\\Program Files\\Java\\jdk1.8.0_221\\bin\\java"`; java8Path = `${process.env.java8_home}`; } const classPath = "" + __dirname + ""; //const tmpXMLToSign = "" + __dirname + "/xml_sign_temp.xml"; const tmpXMLToSign = "" + __dirname + "/xml_sign_temp_" + Math.round(Math.random() * 999999) + ".xml"; fs.writeFileSync(tmpXMLToSign, xml, { encoding: "utf8" }); if (process.platform === "linux") { passphase = passphase.replace(/\$/g, "\\$"); } let fullCommand = `"${java8Path}" -Dfile.encoding=IBM850 -classpath "${classPath}" SignXML "${tmpXMLToSign}" "${file}" "${passphase}" "${tag}"`; //console.log("fullCommand", fullCommand); exec(fullCommand, { encoding: "UTF-8" }, (error, stdout, stderr) => { let entro = 0; if (entro == 0) { //Evita hacer 2 veces reject if (stderr) { entro++; console.log(stderr.cmd); stderr.code = stderr.killed = stderr.signal = stderr.cmd = null; if (!stderr.startsWith("Picked up JAVA_TOOL_OPTIONS")) { //Warning que no debe ser tomado com error reject(stderr); } } } if (entro == 0) { //Evita hacer 2 veces reject if (error) { entro++; console.log(error.cmd); error.code = error.killed = error.signal = error.cmd = null; if (!error.startsWith("Picked up JAVA_TOOL_OPTIONS")) { //Warning que no debe ser tomado com error reject(error); } } } try { fs.unlinkSync(tmpXMLToSign); } catch (err) { } resolve(`${stdout}`); }); }); })); }); } /** * Firma con Java, varios documentos al mismo tiempo * @param xml * @param tag * @returns */ signDocuments(xmls, tag, file, passphase) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { //console.log("A firmar", xml); find_java_home_1.default({ allowJre: true }, (err, java8Path) => { java8Path += "/bin/java"; if (err) return console.log(err); //Comentar esta linea al llevar a Produccion, por que aqui trae java 6 if (process.env.java8_home) { //java8Path = `"C:\\Program Files\\Java\\jdk1.8.0_221\\bin\\java"`; java8Path = `${process.env.java8_home}`; } const classPath = "" + __dirname + ""; //const tmpXMLToSign = "" + __dirname + "/xml_sign_temp.xml"; const arrayNameFiles = new Array(); for (let i = 0; i < xmls.length; i++) { const xml = xmls[i]; const tmpXMLToSign = "" + __dirname + "/xml_sign_temp_" + Math.round(Math.random() * 999999) + ".xml"; fs.writeFileSync(tmpXMLToSign, xml, { encoding: "utf8" }); arrayNameFiles.push(tmpXMLToSign); } if (process.platform === "linux") { passphase = passphase.replace(/\$/g, "\\$"); } let fullCommand = `"${java8Path}" -Dfile.encoding=IBM850 -classpath "${classPath}" SignXMLFiles "${arrayNameFiles.join(",")}" "${file}" "${passphase}" "${tag}"`; //console.log("fullCommand", fullCommand); exec(fullCommand, { encoding: "UTF-8" }, (error, stdout, stderr) => { let stdOutProcesed = stdout; /*console.log("error", error); console.log("stdout", stdout); console.log("stderr", stderr); */ if (stdOutProcesed.includes("_SEPARATOR_")) { //Por si haya algun log que quedo en la colita, entonces elimina ese stdOutProcesed = stdout.substring(0, stdout.lastIndexOf("_SEPARATOR_") + 11); } let entro = 0; if (entro == 0) { if (stderr) { if (!stdOutProcesed.includes("_SEPARATOR_")) { entro++; //console.log("stderr", stderr, typeof stderr); //console.log(stderr.cmd); /*stderr.code = stderr.killed = stderr.signal = stderr.cmd = null; */ if (!stderr.startsWith("Picked up JAVA_TOOL_OPTIONS")) { //Warning que no debe ser tomado com error reject(new Error(stderr)); return; } } } } if (entro == 0) { if (error) { if (!stdOutProcesed.includes("_SEPARATOR_")) { entro++; console.log(error.cmd); error.code = error.killed = error.signal = error.cmd = null; if (!stderr.startsWith("Picked up JAVA_TOOL_OPTIONS")) { //Warning que no debe ser tomado com error reject(error); return; } } } } try { for (let i = 0; i < arrayNameFiles.length; i++) { const nameFile = arrayNameFiles[i]; fs.unlinkSync(nameFile); } //file removed } catch (err) { console.error("Error al borrar referencias ", err); } resolve(`${stdOutProcesed}`); }); }); })); }); } /** * Firma el XML del Evento con Java * @param xml * @param tag * @returns */ signEvento(xml, tag, file, passphase) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { find_java_home_1.default({ allowJre: true }, (err, java8Path) => { java8Path += "/bin/java"; if (err) return console.log(err); //Comentar esta linea al llevar a Produccion, por que aqui trae java 6 if (process.env.java8_home) { //java8Path = `"C:\\Program Files\\Java\\jdk1.8.0_221\\bin\\java"`; java8Path = `${process.env.java8_home}`; } const classPath = "" + __dirname + ""; const tmpXMLToSign = "" + __dirname + "/xml_sign_temp.xml"; fs.writeFileSync(tmpXMLToSign, xml, { encoding: "utf8" }); if (process.platform === "linux") { passphase = passphase.replace(/\$/g, "\\$"); } let fullCommand = `"${java8Path}" -Dfile.encoding=IBM850 -classpath "${classPath}" SignXMLEvento "${tmpXMLToSign}" "${file}" "${passphase}"`; exec(fullCommand, { encoding: "UTF-8" }, (error, stdout, stderr) => { if (error) { if (!error.startsWith("Picked up JAVA_TOOL_OPTIONS")) { //Warning que no debe ser tomado com error reject(error); } } if (stderr) { if (!stderr.startsWith("Picked up JAVA_TOOL_OPTIONS")) { //Warning que no debe ser tomado com error reject(stderr); } } try { fs.unlinkSync(tmpXMLToSign); //file removed } catch (err) { console.error(err); } resolve(`${stdout}`); }); }); })); }); } /** * Firma con Java, retornando el documento firmado en el buffer de salida * @param xml * @param tag * @returns */ getExpiration(file, passphase) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { find_java_home_1.default({ allowJre: true }, (err, java8Path) => { java8Path += "/bin/java"; if (err) return console.log(err); //Comentar esta linea al llevar a Produccion, por que aqui trae java 6 if (process.env.java8_home) { //java8Path = `"C:\\Program Files\\Java\\jdk1.8.0_221\\bin\\java"`; java8Path = `${process.env.java8_home}`; } const classPath = "" + __dirname + ""; if (process.platform === "linux") { passphase = passphase.replace(/\$/g, "\\$"); } let fullCommand = `"${java8Path}" -Dfile.encoding=IBM850 -classpath "${classPath}" CertExpiration "${file}" "${passphase}"`; exec(fullCommand, { encoding: "UTF-8" }, (error, stdout, stderr) => { if (error) { if (!error.startsWith("Picked up JAVA_TOOL_OPTIONS")) { //Warning que no debe ser tomado com error reject(new Error(error)); } } if (stderr) { if (!stderr.startsWith("Picked up JAVA_TOOL_OPTIONS")) { //Warning que no debe ser tomado com error reject(new Error(stderr)); } } try { //file removed } catch (err) { console.error(err); } let respuestaJson = {}; if (stdout && (stdout + "").startsWith("{")) { respuestaJson = JSON.parse(`${stdout}`); } resolve(respuestaJson); }); }); })); }); } } exports.default = new XMLDsig(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiWE1MRHNpZ0phdmEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvWE1MRHNpZ0phdmEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvRUFBMEM7QUFFMUMsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUMxQyxJQUFJLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFFdkIsTUFBTSxPQUFPO0lBQ1gsZ0JBQWUsQ0FBQztJQUVoQjs7Ozs7T0FLRztJQUNHLFlBQVksQ0FBQyxHQUFXLEVBQUUsR0FBUSxFQUFFLElBQVMsRUFBRSxTQUFjOztZQUNqRSxPQUFPLElBQUksT0FBTyxDQUFDLENBQU8sT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUMzQyx3QkFBWSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBUSxFQUFFLFNBQWMsRUFBRSxFQUFFO29CQUM1RCxTQUFTLElBQUksV0FBVyxDQUFDO29CQUN6QixJQUFJLEdBQUc7d0JBQUUsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUVqQyxzRUFBc0U7b0JBQ3RFLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUU7d0JBQzFCLG1FQUFtRTt3QkFDbkUsU0FBUyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztxQkFDekM7b0JBRUQsTUFBTSxTQUFTLEdBQUcsRUFBRSxHQUFHLFNBQVMsR0FBRyxFQUFFLENBQUM7b0JBQ3RDLDZEQUE2RDtvQkFDN0QsTUFBTSxZQUFZLEdBQ2hCLEVBQUU7d0JBQ0YsU0FBUzt3QkFDVCxpQkFBaUI7d0JBQ2pCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQzt3QkFDbEMsTUFBTSxDQUFDO29CQUVULEVBQUUsQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO29CQUUxRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxFQUFFO3dCQUNoQyxTQUFTLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7cUJBQzdDO29CQUVELElBQUksV0FBVyxHQUFHLElBQUksU0FBUyx3Q0FBd0MsU0FBUyxjQUFjLFlBQVksTUFBTSxJQUFJLE1BQU0sU0FBUyxNQUFNLEdBQUcsR0FBRyxDQUFDO29CQUNoSiwwQ0FBMEM7b0JBQzFDLElBQUksQ0FDRixXQUFXLEVBQ1gsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLEVBQ3JCLENBQUMsS0FBVSxFQUFFLE1BQVcsRUFBRSxNQUFXLEVBQUUsRUFBRTt3QkFDdkMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO3dCQUNkLElBQUksS0FBSyxJQUFJLENBQUMsRUFBRTs0QkFDZCw0QkFBNEI7NEJBQzVCLElBQUksTUFBTSxFQUFFO2dDQUNWLEtBQUssRUFBRSxDQUFDO2dDQUVSLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dDQUN4QixNQUFNLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQztnQ0FFaEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsNkJBQTZCLENBQUMsRUFBRTtvQ0FDckQsMENBQTBDO29DQUMxQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7aUNBQ2hCOzZCQUNGO3lCQUNGO3dCQUVELElBQUksS0FBSyxJQUFJLENBQUMsRUFBRTs0QkFDZCw0QkFBNEI7NEJBQzVCLElBQUksS0FBSyxFQUFFO2dDQUNULEtBQUssRUFBRSxDQUFDO2dDQUNSLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dDQUN2QixLQUFLLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQztnQ0FFNUQsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsNkJBQTZCLENBQUMsRUFBRTtvQ0FDcEQsMENBQTBDO29DQUMxQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7aUNBQ2Y7NkJBQ0Y7eUJBQ0Y7d0JBRUQsSUFBSTs0QkFDRixFQUFFLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO3lCQUM3Qjt3QkFBQyxPQUFPLEdBQUcsRUFBRSxHQUFFO3dCQUVoQixPQUFPLENBQUMsR0FBRyxNQUFNLEVBQUUsQ0FBQyxDQUFDO29CQUN2QixDQUFDLENBQ0YsQ0FBQztnQkFDSixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQSxDQUFDLENBQUM7UUFDTCxDQUFDO0tBQUE7SUFFRDs7Ozs7T0FLRztJQUNHLGFBQWEsQ0FBQyxJQUFnQixFQUFFLEdBQVEsRUFBRSxJQUFTLEVBQUUsU0FBYzs7WUFDdkUsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFPLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtnQkFDM0MsK0JBQStCO2dCQUUvQix3QkFBWSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBUSxFQUFFLFNBQWMsRUFBRSxFQUFFO29CQUM1RCxTQUFTLElBQUksV0FBVyxDQUFDO29CQUN6QixJQUFJLEdBQUc7d0JBQUUsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUVqQyxzRUFBc0U7b0JBQ3RFLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUU7d0JBQzFCLG1FQUFtRTt3QkFDbkUsU0FBUyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztxQkFDekM7b0JBRUQsTUFBTSxTQUFTLEdBQUcsRUFBRSxHQUFHLFNBQVMsR0FBRyxFQUFFLENBQUM7b0JBQ3RDLDZEQUE2RDtvQkFDN0QsTUFBTSxjQUFjLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztvQkFFbkMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7d0JBQ3BDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQzt3QkFFcEIsTUFBTSxZQUFZLEdBQ2hCLEVBQUU7NEJBQ0YsU0FBUzs0QkFDVCxpQkFBaUI7NEJBQ2pCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQzs0QkFDbEMsTUFBTSxDQUFDO3dCQUVULEVBQUUsQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO3dCQUUxRCxjQUFjLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO3FCQUNuQztvQkFFRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssT0FBTyxFQUFFO3dCQUNoQyxTQUFTLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7cUJBQzdDO29CQUVELElBQUksV0FBVyxHQUFHLElBQUksU0FBUyx3Q0FBd0MsU0FBUyxtQkFBbUIsY0FBYyxDQUFDLElBQUksQ0FDcEgsR0FBRyxDQUNKLE1BQU0sSUFBSSxNQUFNLFNBQVMsTUFBTSxHQUFHLEdBQUcsQ0FBQztvQkFDdkMsMENBQTBDO29CQUMxQyxJQUFJLENBQ0YsV0FBVyxFQUNYLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUNyQixDQUFDLEtBQVUsRUFBRSxNQUFXLEVBQUUsTUFBVyxFQUFFLEVBQUU7d0JBQ3ZDLElBQUksY0FBYyxHQUFHLE1BQU0sQ0FBQzt3QkFDNUI7OzswQkFHRTt3QkFDRixJQUFJLGNBQWMsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEVBQUU7NEJBQzFDLG9FQUFvRTs0QkFDcEUsY0FBYyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQy9CLENBQUMsRUFDRCxNQUFNLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsQ0FDdkMsQ0FBQzt5QkFDSDt3QkFDRCxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7d0JBQ2QsSUFBSSxLQUFLLElBQUksQ0FBQyxFQUFFOzRCQUNkLElBQUksTUFBTSxFQUFFO2dDQUNWLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFO29DQUMzQyxLQUFLLEVBQUUsQ0FBQztvQ0FDUiwrQ0FBK0M7b0NBQy9DLDBCQUEwQjtvQ0FFMUI7Ozs7O3NDQUtFO29DQUNGLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLDZCQUE2QixDQUFDLEVBQUU7d0NBQ3JELDBDQUEwQzt3Q0FDMUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7d0NBQzFCLE9BQU87cUNBQ1I7aUNBQ0Y7NkJBQ0Y7eUJBQ0Y7d0JBQ0QsSUFBSSxLQUFLLElBQUksQ0FBQyxFQUFFOzRCQUNkLElBQUksS0FBSyxFQUFFO2dDQUNULElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxFQUFFO29DQUMzQyxLQUFLLEVBQUUsQ0FBQztvQ0FDUixPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztvQ0FDdkIsS0FBSyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUM7b0NBRTVELElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLDZCQUE2QixDQUFDLEVBQUU7d0NBQ3JELDBDQUEwQzt3Q0FDMUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO3dDQUNkLE9BQU87cUNBQ1I7aUNBQ0Y7NkJBQ0Y7eUJBQ0Y7d0JBRUQsSUFBSTs0QkFDRixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtnQ0FDOUMsTUFBTSxRQUFRLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dDQUNuQyxFQUFFLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDOzZCQUN6Qjs0QkFDRCxjQUFjO3lCQUNmO3dCQUFDLE9BQU8sR0FBRyxFQUFFOzRCQUNaLE9BQU8sQ0FBQyxLQUFLLENBQUMsOEJBQThCLEVBQUUsR0FBRyxDQUFDLENBQUM7eUJBQ3BEO3dCQUVELE9BQU8sQ0FBQyxHQUFHLGNBQWMsRUFBRSxDQUFDLENBQUM7b0JBQy9CLENBQUMsQ0FDRixDQUFDO2dCQUNKLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQyxDQUFBLENBQUMsQ0FBQztRQUNMLENBQUM7S0FBQTtJQUVEOzs7OztPQUtHO0lBQ0csVUFBVSxDQUFDLEdBQVcsRUFBRSxHQUFRLEVBQUUsSUFBUyxFQUFFLFNBQWM7O1lBQy9ELE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBTyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQzNDLHdCQUFZLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFRLEVBQUUsU0FBYyxFQUFFLEVBQUU7b0JBQzVELFNBQVMsSUFBSSxXQUFXLENBQUM7b0JBQ3pCLElBQUksR0FBRzt3QkFBRSxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBRWpDLHNFQUFzRTtvQkFDdEUsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRTt3QkFDMUIsbUVBQW1FO3dCQUNuRSxTQUFTLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDO3FCQUN6QztvQkFFRCxNQUFNLFNBQVMsR0FBRyxFQUFFLEdBQUcsU0FBUyxHQUFHLEVBQUUsQ0FBQztvQkFDdEMsTUFBTSxZQUFZLEdBQUcsRUFBRSxHQUFHLFNBQVMsR0FBRyxvQkFBb0IsQ0FBQztvQkFFM0QsRUFBRSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsR0FBRyxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7b0JBRTFELElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUU7d0JBQ2hDLFNBQVMsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztxQkFDN0M7b0JBRUQsSUFBSSxXQUFXLEdBQUcsSUFBSSxTQUFTLHdDQUF3QyxTQUFTLG9CQUFvQixZQUFZLE1BQU0sSUFBSSxNQUFNLFNBQVMsR0FBRyxDQUFDO29CQUM3SSxJQUFJLENBQ0YsV0FBVyxFQUNYLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxFQUNyQixDQUFDLEtBQVUsRUFBRSxNQUFXLEVBQUUsTUFBVyxFQUFFLEVBQUU7d0JBQ3ZDLElBQUksS0FBSyxFQUFFOzRCQUNULElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLDZCQUE2QixDQUFDLEVBQUU7Z0NBQ3BELDBDQUEwQztnQ0FDMUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDOzZCQUNmO3lCQUNGO3dCQUNELElBQUksTUFBTSxFQUFFOzRCQUNWLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLDZCQUE2QixDQUFDLEVBQUU7Z0NBQ3JELDBDQUEwQztnQ0FDMUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDOzZCQUNoQjt5QkFDRjt3QkFFRCxJQUFJOzRCQUNGLEVBQUUsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7NEJBQzVCLGNBQWM7eUJBQ2Y7d0JBQUMsT0FBTyxHQUFHLEVBQUU7NEJBQ1osT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQzt5QkFDcEI7d0JBRUQsT0FBTyxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsQ0FBQztvQkFDdkIsQ0FBQyxDQUNGLENBQUM7Z0JBQ0osQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDLENBQUEsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztLQUFBO0lBRUQ7Ozs7O09BS0c7SUFDRyxhQUFhLENBQUMsSUFBUyxFQUFFLFNBQWM7O1lBQzNDLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBTyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQzNDLHdCQUFZLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFRLEVBQUUsU0FBYyxFQUFFLEVBQUU7b0JBQzVELFNBQVMsSUFBSSxXQUFXLENBQUM7b0JBQ3pCLElBQUksR0FBRzt3QkFBRSxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBRWpDLHNFQUFzRTtvQkFDdEUsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRTt3QkFDMUIsbUVBQW1FO3dCQUNuRSxTQUFTLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDO3FCQUN6QztvQkFFRCxNQUFNLFNBQVMsR0FBRyxFQUFFLEdBQUcsU0FBUyxHQUFHLEVBQUUsQ0FBQztvQkFFdEMsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU8sRUFBRTt3QkFDaEMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO3FCQUM3QztvQkFFRCxJQUFJLFdBQVcsR0FBRyxJQUFJLFNBQVMsd0NBQXdDLFNBQVMscUJBQXFCLElBQUksTUFBTSxTQUFTLEdBQUcsQ0FBQztvQkFDNUgsSUFBSSxDQUNGLFdBQVcsRUFDWCxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsRUFDckIsQ0FBQyxLQUFVLEVBQUUsTUFBVyxFQUFFLE1BQVcsRUFBRSxFQUFFO3dCQUN2QyxJQUFJLEtBQUssRUFBRTs0QkFDVCxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyw2QkFBNkIsQ0FBQyxFQUFFO2dDQUNwRCwwQ0FBMEM7Z0NBQzFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDOzZCQUMxQjt5QkFDRjt3QkFDRCxJQUFJLE1BQU0sRUFBRTs0QkFDVixJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyw2QkFBNkIsQ0FBQyxFQUFFO2dDQUNyRCwwQ0FBMEM7Z0NBQzFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDOzZCQUMzQjt5QkFDRjt3QkFFRCxJQUFJOzRCQUNGLGNBQWM7eUJBQ2Y7d0JBQUMsT0FBTyxHQUFHLEVBQUU7NEJBQ1osT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQzt5QkFDcEI7d0JBRUQsSUFBSSxhQUFhLEdBQUcsRUFBRSxDQUFDO3dCQUN2QixJQUFJLE1BQU0sSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUMsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUU7NEJBQzNDLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUMsQ0FBQzt5QkFDekM7d0JBQ0QsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO29CQUN6QixDQUFDLENBQ0YsQ0FBQztnQkFDSixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQSxDQUFDLENBQUM7UUFDTCxDQUFDO0tBQUE7Q0FDRjtBQUVELGtCQUFlLElBQUksT0FBTyxFQUFFLENBQUMifQ==