UNPKG

@fin.cx/einvoice

Version:

A TypeScript module for creating, manipulating, and embedding XML data within PDF files specifically tailored for electronic invoice (einvoice) packages.

555 lines 54.4 kB
import { UBLEncoder } from '../generic/ubl.encoder.js';
import { DOMParser, XMLSerializer } from '../../../plugins.js';
/**
 * Encoder for XRechnung (UBL) format
 * Extends the generic UBL encoder with XRechnung-specific customizations
 */
export class XRechnungEncoder extends UBLEncoder {
    /**
     * Encodes a credit note into XRechnung XML
     * @param creditNote Credit note to encode
     * @returns XRechnung XML string
     */
    async encodeCreditNote(creditNote) {
        // First get the base UBL XML
        const baseXml = await super.encodeCreditNote(creditNote);
        // Parse and modify for XRechnung
        const doc = new DOMParser().parseFromString(baseXml, 'application/xml');
        this.applyXRechnungCustomizations(doc, creditNote);
        // Serialize back to string
        return new XMLSerializer().serializeToString(doc);
    }
    /**
     * Encodes a debit note (invoice) into XRechnung XML
     * @param debitNote Debit note to encode
     * @returns XRechnung XML string
     */
    async encodeDebitNote(debitNote) {
        // First get the base UBL XML
        const baseXml = await super.encodeDebitNote(debitNote);
        // Parse and modify for XRechnung
        const doc = new DOMParser().parseFromString(baseXml, 'application/xml');
        this.applyXRechnungCustomizations(doc, debitNote);
        // Serialize back to string
        return new XMLSerializer().serializeToString(doc);
    }
    /**
     * Applies XRechnung-specific customizations to the document
     * @param doc XML document
     * @param invoice Invoice data
     */
    applyXRechnungCustomizations(doc, invoice) {
        const root = doc.documentElement;
        // Extract metadata if available
        const metadata = invoice.metadata?.extensions;
        // Update Customization ID to XRechnung 2.0
        const customizationId = root.getElementsByTagName('cbc:CustomizationID')[0];
        if (customizationId) {
            customizationId.textContent = 'urn:cen.eu:en16931:2017#compliant#urn:xoev-de:kosit:standard:xrechnung_2.0';
        }
        // Add or update Buyer Reference (required for XRechnung)
        let buyerRef = root.getElementsByTagName('cbc:BuyerReference')[0];
        const buyerReferenceValue = invoice.buyerReference || metadata?.businessReferences?.buyerReference || invoice.id;
        if (!buyerRef) {
            // Find where to insert it (after DocumentCurrencyCode)
            const currencyCode = root.getElementsByTagName('cbc:DocumentCurrencyCode')[0];
            if (currencyCode) {
                buyerRef = doc.createElement('cbc:BuyerReference');
                buyerRef.textContent = buyerReferenceValue;
                currencyCode.parentNode.insertBefore(buyerRef, currencyCode.nextSibling);
            }
        }
        else if (!buyerRef.textContent || buyerRef.textContent.trim() === '') {
            buyerRef.textContent = buyerReferenceValue;
        }
        // Update payment terms to German
        const paymentTermsNotes = root.getElementsByTagName('cac:PaymentTerms');
        if (paymentTermsNotes.length > 0) {
            const noteElement = paymentTermsNotes[0].getElementsByTagName('cbc:Note')[0];
            if (noteElement && noteElement.textContent) {
                noteElement.textContent = `Zahlung innerhalb von ${invoice.dueInDays || 30} Tagen`;
            }
        }
        // Add electronic address for parties if available
        this.addElectronicAddressToParty(doc, 'cac:AccountingSupplierParty', invoice.from);
        this.addElectronicAddressToParty(doc, 'cac:AccountingCustomerParty', invoice.to);
        // Ensure payment reference is set
        const paymentMeans = root.getElementsByTagName('cac:PaymentMeans')[0];
        if (paymentMeans) {
            let paymentId = paymentMeans.getElementsByTagName('cbc:PaymentID')[0];
            if (!paymentId) {
                paymentId = doc.createElement('cbc:PaymentID');
                paymentId.textContent = invoice.id;
                paymentMeans.appendChild(paymentId);
            }
        }
        // Add country code handling for German addresses
        this.fixGermanCountryCodes(doc);
        // Preserve business references from metadata
        this.addBusinessReferences(doc, metadata?.businessReferences);
        // Preserve payment information from metadata
        this.enhancePaymentInformation(doc, metadata?.paymentInformation);
        // Preserve date information from metadata
        this.addDateInformation(doc, metadata?.dateInformation);
        // Enhance party information with contact details
        this.enhancePartyInformation(doc, invoice);
        // Enhance line items with metadata
        this.enhanceLineItems(doc, invoice);
    }
    /**
     * Adds electronic address to party if not already present
     * @param doc XML document
     * @param partyType Party type selector
     * @param party Party data
     */
    addElectronicAddressToParty(doc, partyType, party) {
        const partyContainer = doc.getElementsByTagName(partyType)[0];
        if (!partyContainer)
            return;
        const partyElement = partyContainer.getElementsByTagName('cac:Party')[0];
        if (!partyElement)
            return;
        // Check if electronic address already exists
        const existingEndpoint = partyElement.getElementsByTagName('cbc:EndpointID')[0];
        if (!existingEndpoint && party.electronicAddress) {
            // Add electronic address at the beginning of party element
            const endpointNode = doc.createElement('cbc:EndpointID');
            endpointNode.setAttribute('schemeID', party.electronicAddress.scheme || '0204');
            endpointNode.textContent = party.electronicAddress.value;
            // Insert as first child of party element
            if (partyElement.firstChild) {
                partyElement.insertBefore(endpointNode, partyElement.firstChild);
            }
            else {
                partyElement.appendChild(endpointNode);
            }
        }
        // Add GLN (Global Location Number) if available
        if (party.gln && !existingEndpoint) {
            const endpointNode = doc.createElement('cbc:EndpointID');
            endpointNode.setAttribute('schemeID', '0088'); // GLN scheme ID
            endpointNode.textContent = party.gln;
            // Insert as first child of party element
            if (partyElement.firstChild) {
                partyElement.insertBefore(endpointNode, partyElement.firstChild);
            }
            else {
                partyElement.appendChild(endpointNode);
            }
        }
        // Add PartyIdentification for additional identifiers
        if (party.additionalIdentifiers) {
            for (const identifier of party.additionalIdentifiers) {
                const partyId = doc.createElement('cac:PartyIdentification');
                const id = doc.createElement('cbc:ID');
                if (identifier.scheme) {
                    id.setAttribute('schemeID', identifier.scheme);
                }
                id.textContent = identifier.value;
                partyId.appendChild(id);
                // Insert after EndpointID or at beginning
                const endpoint = partyElement.getElementsByTagName('cbc:EndpointID')[0];
                if (endpoint && endpoint.nextSibling) {
                    partyElement.insertBefore(partyId, endpoint.nextSibling);
                }
                else if (partyElement.firstChild) {
                    partyElement.insertBefore(partyId, partyElement.firstChild);
                }
                else {
                    partyElement.appendChild(partyId);
                }
            }
        }
        // Add company registration number to PartyLegalEntity
        if (party.registrationDetails?.registrationId) {
            let legalEntity = partyElement.getElementsByTagName('cac:PartyLegalEntity')[0];
            if (!legalEntity) {
                legalEntity = doc.createElement('cac:PartyLegalEntity');
                // Insert after PostalAddress
                const postalAddress = partyElement.getElementsByTagName('cac:PostalAddress')[0];
                if (postalAddress && postalAddress.nextSibling) {
                    partyElement.insertBefore(legalEntity, postalAddress.nextSibling);
                }
                else {
                    partyElement.appendChild(legalEntity);
                }
            }
            // Add registration name if not present
            if (!legalEntity.getElementsByTagName('cbc:RegistrationName')[0]) {
                const regName = doc.createElement('cbc:RegistrationName');
                regName.textContent = party.registrationDetails.registrationName || party.name;
                legalEntity.appendChild(regName);
            }
            // Add company ID if not present
            if (!legalEntity.getElementsByTagName('cbc:CompanyID')[0]) {
                const companyId = doc.createElement('cbc:CompanyID');
                companyId.textContent = party.registrationDetails.registrationId;
                legalEntity.appendChild(companyId);
            }
        }
    }
    /**
     * Fixes German country codes in the document
     * @param doc XML document
     */
    fixGermanCountryCodes(doc) {
        const countryNodes = doc.getElementsByTagName('cbc:IdentificationCode');
        for (let i = 0; i < countryNodes.length; i++) {
            const node = countryNodes[i];
            if (node.textContent) {
                const text = node.textContent.toLowerCase();
                if (text === 'germany' || text === 'deutschland' || text === 'de') {
                    node.textContent = 'DE';
                }
                else if (text.length > 2) {
                    // Try to use first 2 characters as country code
                    node.textContent = text.substring(0, 2).toUpperCase();
                }
            }
        }
    }
    /**
     * Adds business references from metadata to the document
     * @param doc XML document
     * @param businessReferences Business references from metadata
     */
    addBusinessReferences(doc, businessReferences) {
        if (!businessReferences)
            return;
        const root = doc.documentElement;
        // Add OrderReference
        if (businessReferences.orderReference && !root.getElementsByTagName('cac:OrderReference')[0]) {
            const orderRef = doc.createElement('cac:OrderReference');
            const orderId = doc.createElement('cbc:ID');
            orderId.textContent = businessReferences.orderReference;
            orderRef.appendChild(orderId);
            // Insert after DocumentCurrencyCode
            const currencyCode = root.getElementsByTagName('cbc:DocumentCurrencyCode')[0];
            if (currencyCode && currencyCode.parentNode) {
                currencyCode.parentNode.insertBefore(orderRef, currencyCode.nextSibling);
            }
        }
        // Add ContractDocumentReference
        if (businessReferences.contractReference && !root.getElementsByTagName('cac:ContractDocumentReference')[0]) {
            const contractRef = doc.createElement('cac:ContractDocumentReference');
            const contractId = doc.createElement('cbc:ID');
            contractId.textContent = businessReferences.contractReference;
            contractRef.appendChild(contractId);
            // Insert after OrderReference or DocumentCurrencyCode
            const orderRef = root.getElementsByTagName('cac:OrderReference')[0];
            const insertAfter = orderRef || root.getElementsByTagName('cbc:DocumentCurrencyCode')[0];
            if (insertAfter && insertAfter.parentNode) {
                insertAfter.parentNode.insertBefore(contractRef, insertAfter.nextSibling);
            }
        }
        // Add ProjectReference
        if (businessReferences.projectReference && !root.getElementsByTagName('cac:ProjectReference')[0]) {
            const projectRef = doc.createElement('cac:ProjectReference');
            const projectId = doc.createElement('cbc:ID');
            projectId.textContent = businessReferences.projectReference;
            projectRef.appendChild(projectId);
            // Insert after ContractDocumentReference or other refs
            const contractRef = root.getElementsByTagName('cac:ContractDocumentReference')[0];
            const orderRef = root.getElementsByTagName('cac:OrderReference')[0];
            const insertAfter = contractRef || orderRef || root.getElementsByTagName('cbc:DocumentCurrencyCode')[0];
            if (insertAfter && insertAfter.parentNode) {
                insertAfter.parentNode.insertBefore(projectRef, insertAfter.nextSibling);
            }
        }
    }
    /**
     * Enhances payment information from metadata
     * @param doc XML document
     * @param paymentInfo Payment information from metadata
     */
    enhancePaymentInformation(doc, paymentInfo) {
        if (!paymentInfo)
            return;
        const root = doc.documentElement;
        let paymentMeans = root.getElementsByTagName('cac:PaymentMeans')[0];
        // Create PaymentMeans if it doesn't exist
        if (!paymentMeans) {
            paymentMeans = doc.createElement('cac:PaymentMeans');
            // Insert before TaxTotal
            const taxTotal = root.getElementsByTagName('cac:TaxTotal')[0];
            if (taxTotal && taxTotal.parentNode) {
                taxTotal.parentNode.insertBefore(paymentMeans, taxTotal);
            }
        }
        // Add PaymentMeansCode
        if (paymentInfo.paymentMeansCode && !paymentMeans.getElementsByTagName('cbc:PaymentMeansCode')[0]) {
            const meansCode = doc.createElement('cbc:PaymentMeansCode');
            meansCode.textContent = paymentInfo.paymentMeansCode;
            paymentMeans.appendChild(meansCode);
        }
        // Add PaymentID
        if (paymentInfo.paymentID && !paymentMeans.getElementsByTagName('cbc:PaymentID')[0]) {
            const paymentId = doc.createElement('cbc:PaymentID');
            paymentId.textContent = paymentInfo.paymentID;
            paymentMeans.appendChild(paymentId);
        }
        // Add PaymentDueDate
        if (paymentInfo.paymentDueDate && !paymentMeans.getElementsByTagName('cbc:PaymentDueDate')[0]) {
            const dueDate = doc.createElement('cbc:PaymentDueDate');
            dueDate.textContent = paymentInfo.paymentDueDate;
            paymentMeans.appendChild(dueDate);
        }
        // Add IBAN and BIC
        if (paymentInfo.iban || paymentInfo.bic) {
            let payeeAccount = paymentMeans.getElementsByTagName('cac:PayeeFinancialAccount')[0];
            if (!payeeAccount) {
                payeeAccount = doc.createElement('cac:PayeeFinancialAccount');
                paymentMeans.appendChild(payeeAccount);
            }
            // Add IBAN
            if (paymentInfo.iban && !payeeAccount.getElementsByTagName('cbc:ID')[0]) {
                const iban = doc.createElement('cbc:ID');
                iban.textContent = paymentInfo.iban;
                payeeAccount.appendChild(iban);
            }
            // Add account name (must come after ID but before FinancialInstitutionBranch)
            if (paymentInfo.accountName && !payeeAccount.getElementsByTagName('cbc:Name')[0]) {
                const accountName = doc.createElement('cbc:Name');
                accountName.textContent = paymentInfo.accountName;
                // Insert after ID but before FinancialInstitutionBranch
                const id = payeeAccount.getElementsByTagName('cbc:ID')[0];
                const finInstBranch = payeeAccount.getElementsByTagName('cac:FinancialInstitutionBranch')[0];
                if (finInstBranch) {
                    payeeAccount.insertBefore(accountName, finInstBranch);
                }
                else if (id && id.nextSibling) {
                    payeeAccount.insertBefore(accountName, id.nextSibling);
                }
                else {
                    payeeAccount.appendChild(accountName);
                }
            }
            // Add BIC and bank name
            if (paymentInfo.bic || paymentInfo.bankName) {
                let finInstBranch = payeeAccount.getElementsByTagName('cac:FinancialInstitutionBranch')[0];
                if (!finInstBranch) {
                    finInstBranch = doc.createElement('cac:FinancialInstitutionBranch');
                    payeeAccount.appendChild(finInstBranch);
                }
                // Add BIC as branch ID
                if (paymentInfo.bic && !finInstBranch.getElementsByTagName('cbc:ID')[0]) {
                    const bicElement = doc.createElement('cbc:ID');
                    bicElement.textContent = paymentInfo.bic;
                    finInstBranch.appendChild(bicElement);
                }
                // Add bank name
                if (paymentInfo.bankName && !finInstBranch.getElementsByTagName('cbc:Name')[0]) {
                    const bankNameElement = doc.createElement('cbc:Name');
                    bankNameElement.textContent = paymentInfo.bankName;
                    finInstBranch.appendChild(bankNameElement);
                }
            }
        }
        // Add payment terms with discount if available
        if (paymentInfo.paymentTermsNote && paymentInfo.paymentTermsNote.includes('early payment')) {
            let paymentTerms = root.getElementsByTagName('cac:PaymentTerms')[0];
            if (!paymentTerms) {
                paymentTerms = doc.createElement('cac:PaymentTerms');
                // Insert before PaymentMeans
                const paymentMeans = root.getElementsByTagName('cac:PaymentMeans')[0];
                if (paymentMeans && paymentMeans.parentNode) {
                    paymentMeans.parentNode.insertBefore(paymentTerms, paymentMeans);
                }
            }
            // Update or add note
            let note = paymentTerms.getElementsByTagName('cbc:Note')[0];
            if (!note) {
                note = doc.createElement('cbc:Note');
                paymentTerms.appendChild(note);
            }
            note.textContent = paymentInfo.paymentTermsNote;
            // Add discount percent if available
            if (paymentInfo.discountPercent && !paymentTerms.getElementsByTagName('cbc:SettlementDiscountPercent')[0]) {
                const discountElement = doc.createElement('cbc:SettlementDiscountPercent');
                discountElement.textContent = paymentInfo.discountPercent;
                paymentTerms.appendChild(discountElement);
            }
        }
    }
    /**
     * Adds date information from metadata
     * @param doc XML document
     * @param dateInfo Date information from metadata
     */
    addDateInformation(doc, dateInfo) {
        if (!dateInfo)
            return;
        const root = doc.documentElement;
        // Add InvoicePeriod
        if ((dateInfo.periodStart || dateInfo.periodEnd) && !root.getElementsByTagName('cac:InvoicePeriod')[0]) {
            const invoicePeriod = doc.createElement('cac:InvoicePeriod');
            if (dateInfo.periodStart) {
                const startDate = doc.createElement('cbc:StartDate');
                startDate.textContent = dateInfo.periodStart;
                invoicePeriod.appendChild(startDate);
            }
            if (dateInfo.periodEnd) {
                const endDate = doc.createElement('cbc:EndDate');
                endDate.textContent = dateInfo.periodEnd;
                invoicePeriod.appendChild(endDate);
            }
            // Insert after business references or DocumentCurrencyCode
            const projectRef = root.getElementsByTagName('cac:ProjectReference')[0];
            const contractRef = root.getElementsByTagName('cac:ContractDocumentReference')[0];
            const orderRef = root.getElementsByTagName('cac:OrderReference')[0];
            const insertAfter = projectRef || contractRef || orderRef || root.getElementsByTagName('cbc:DocumentCurrencyCode')[0];
            if (insertAfter && insertAfter.parentNode) {
                insertAfter.parentNode.insertBefore(invoicePeriod, insertAfter.nextSibling);
            }
        }
        // Add Delivery with ActualDeliveryDate
        if (dateInfo.deliveryDate && !root.getElementsByTagName('cac:Delivery')[0]) {
            const delivery = doc.createElement('cac:Delivery');
            const deliveryDate = doc.createElement('cbc:ActualDeliveryDate');
            deliveryDate.textContent = dateInfo.deliveryDate;
            delivery.appendChild(deliveryDate);
            // Insert before PaymentMeans
            const paymentMeans = root.getElementsByTagName('cac:PaymentMeans')[0];
            if (paymentMeans && paymentMeans.parentNode) {
                paymentMeans.parentNode.insertBefore(delivery, paymentMeans);
            }
        }
    }
    /**
     * Enhances party information with contact details from metadata
     * @param doc XML document
     * @param invoice Invoice data
     */
    enhancePartyInformation(doc, invoice) {
        // Enhance supplier party
        this.addContactToParty(doc, 'cac:AccountingSupplierParty', invoice.from?.metadata?.contactInformation);
        // Enhance customer party
        this.addContactToParty(doc, 'cac:AccountingCustomerParty', invoice.to?.metadata?.contactInformation);
    }
    /**
     * Adds contact information to a party
     * @param doc XML document
     * @param partySelector Party selector
     * @param contactInfo Contact information from metadata
     */
    addContactToParty(doc, partySelector, contactInfo) {
        if (!contactInfo)
            return;
        const partyContainer = doc.getElementsByTagName(partySelector)[0];
        if (!partyContainer)
            return;
        const party = partyContainer.getElementsByTagName('cac:Party')[0];
        if (!party)
            return;
        // Check if Contact already exists
        let contact = party.getElementsByTagName('cac:Contact')[0];
        if (!contact && (contactInfo.name || contactInfo.phone || contactInfo.email)) {
            contact = doc.createElement('cac:Contact');
            // Insert after PartyName
            const partyName = party.getElementsByTagName('cac:PartyName')[0];
            if (partyName && partyName.parentNode) {
                partyName.parentNode.insertBefore(contact, partyName.nextSibling);
            }
            else {
                party.appendChild(contact);
            }
        }
        if (contact) {
            // Add contact name
            if (contactInfo.name && !contact.getElementsByTagName('cbc:Name')[0]) {
                const name = doc.createElement('cbc:Name');
                name.textContent = contactInfo.name;
                contact.appendChild(name);
            }
            // Add telephone
            if (contactInfo.phone && !contact.getElementsByTagName('cbc:Telephone')[0]) {
                const phone = doc.createElement('cbc:Telephone');
                phone.textContent = contactInfo.phone;
                contact.appendChild(phone);
            }
            // Add email
            if (contactInfo.email && !contact.getElementsByTagName('cbc:ElectronicMail')[0]) {
                const email = doc.createElement('cbc:ElectronicMail');
                email.textContent = contactInfo.email;
                contact.appendChild(email);
            }
        }
    }
    /**
     * Enhances line items with metadata
     * @param doc XML document
     * @param invoice Invoice data
     */
    enhanceLineItems(doc, invoice) {
        const invoiceLines = doc.getElementsByTagName('cac:InvoiceLine');
        for (let i = 0; i < invoiceLines.length && i < invoice.items.length; i++) {
            const line = invoiceLines[i];
            const item = invoice.items[i];
            const itemMetadata = item.metadata;
            if (!itemMetadata)
                continue;
            const itemElement = line.getElementsByTagName('cac:Item')[0];
            if (!itemElement)
                continue;
            // Add item description
            if (itemMetadata.description && !itemElement.getElementsByTagName('cbc:Description')[0]) {
                const desc = doc.createElement('cbc:Description');
                desc.textContent = itemMetadata.description;
                // Insert before Name
                const name = itemElement.getElementsByTagName('cbc:Name')[0];
                if (name && name.parentNode) {
                    name.parentNode.insertBefore(desc, name);
                }
                else {
                    itemElement.appendChild(desc);
                }
            }
            // Add SellersItemIdentification
            if (itemMetadata.buyerItemID && !itemElement.getElementsByTagName('cac:SellersItemIdentification')[0]) {
                const sellerId = doc.createElement('cac:SellersItemIdentification');
                const id = doc.createElement('cbc:ID');
                id.textContent = item.articleNumber || itemMetadata.buyerItemID;
                sellerId.appendChild(id);
                itemElement.appendChild(sellerId);
            }
            // Add BuyersItemIdentification
            if (itemMetadata.buyerItemID && !itemElement.getElementsByTagName('cac:BuyersItemIdentification')[0]) {
                const buyerId = doc.createElement('cac:BuyersItemIdentification');
                const id = doc.createElement('cbc:ID');
                id.textContent = itemMetadata.buyerItemID;
                buyerId.appendChild(id);
                itemElement.appendChild(buyerId);
            }
            // Add StandardItemIdentification
            if (itemMetadata.standardItemID && !itemElement.getElementsByTagName('cac:StandardItemIdentification')[0]) {
                const standardId = doc.createElement('cac:StandardItemIdentification');
                const id = doc.createElement('cbc:ID');
                id.textContent = itemMetadata.standardItemID;
                standardId.appendChild(id);
                itemElement.appendChild(standardId);
            }
            // Add CommodityClassification
            if (itemMetadata.commodityClassification && !itemElement.getElementsByTagName('cac:CommodityClassification')[0]) {
                const classification = doc.createElement('cac:CommodityClassification');
                const code = doc.createElement('cbc:ItemClassificationCode');
                code.textContent = itemMetadata.commodityClassification;
                classification.appendChild(code);
                itemElement.appendChild(classification);
            }
            // Add additional item properties
            if (itemMetadata.additionalProperties) {
                for (const [propName, propValue] of Object.entries(itemMetadata.additionalProperties)) {
                    const additionalProp = doc.createElement('cac:AdditionalItemProperty');
                    const nameElement = doc.createElement('cbc:Name');
                    nameElement.textContent = propName;
                    additionalProp.appendChild(nameElement);
                    const valueElement = doc.createElement('cbc:Value');
                    valueElement.textContent = propValue;
                    additionalProp.appendChild(valueElement);
                    itemElement.appendChild(additionalProp);
                }
            }
        }
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieHJlY2hudW5nLmVuY29kZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90cy9mb3JtYXRzL3VibC94cmVjaG51bmcveHJlY2hudW5nLmVuY29kZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXZELE9BQU8sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFL0Q7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGdCQUFpQixTQUFRLFVBQVU7SUFDOUM7Ozs7T0FJRztJQUNPLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxVQUF1QjtRQUN0RCw2QkFBNkI7UUFDN0IsTUFBTSxPQUFPLEdBQUcsTUFBTSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFekQsaUNBQWlDO1FBQ2pDLE1BQU0sR0FBRyxHQUFHLElBQUksU0FBUyxFQUFFLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3hFLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxHQUFHLEVBQUUsVUFBaUMsQ0FBQyxDQUFDO1FBRTFFLDJCQUEyQjtRQUMzQixPQUFPLElBQUksYUFBYSxFQUFFLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVEOzs7O09BSUc7SUFDTyxLQUFLLENBQUMsZUFBZSxDQUFDLFNBQXFCO1FBQ25ELDZCQUE2QjtRQUM3QixNQUFNLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFdkQsaUNBQWlDO1FBQ2pDLE1BQU0sR0FBRyxHQUFHLElBQUksU0FBUyxFQUFFLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3hFLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxHQUFHLEVBQUUsU0FBZ0MsQ0FB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