From 962b51feecb346fdc5230ded535f5f48e549e2a2 Mon Sep 17 00:00:00 2001 From: cybor2001 Date: Thu, 2 Jul 2026 17:50:11 +0200 Subject: [PATCH 1/6] feat: add dark mode, interactive editing, and export capabilities to BC3 budget parser. --- index.html => index.php | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename index.html => index.php (100%) diff --git a/index.html b/index.php similarity index 100% rename from index.html rename to index.php From e3774dc932066cc0e142aaa0a253a20072c862e2 Mon Sep 17 00:00:00 2001 From: cybor2001 Date: Thu, 2 Jul 2026 17:50:27 +0200 Subject: [PATCH 2/6] feat: add dependencies and update frontend to support file parsing and document generation --- BC3Parser.php | 49 +- app.js | 1692 ++++++++++++- chart.min.js | 14 + diagnostico.html | 62 + ejemplos (2).bc3 | 4200 +++++++++++++++++++++++++++++++++ index.php | 157 +- jspdf.plugin.autotable.min.js | 10 + jspdf.umd.min.js | 398 ++++ presupuesto_ejemplo.bc3 | 12 + run.bat | 16 + style.css | 1819 +++++++++----- xlsx.full.min.js | 22 + 12 files changed, 7828 insertions(+), 623 deletions(-) create mode 100644 chart.min.js create mode 100644 diagnostico.html create mode 100644 ejemplos (2).bc3 create mode 100644 jspdf.plugin.autotable.min.js create mode 100644 jspdf.umd.min.js create mode 100644 presupuesto_ejemplo.bc3 create mode 100644 run.bat create mode 100644 xlsx.full.min.js diff --git a/BC3Parser.php b/BC3Parser.php index a568930..43af142 100644 --- a/BC3Parser.php +++ b/BC3Parser.php @@ -93,7 +93,8 @@ public function parse() return [ 'properties' => $this->properties, 'concepts' => $this->concepts, - 'root_nodes' => $this->getRootNodes() + 'root_nodes' => $this->getRootNodes(), + 'original_text' => $content ]; } @@ -146,12 +147,17 @@ private function parseConcept($parts) if (!$code) return; + $priceRaw = $parts[3] ?? '0'; + $price = floatval(str_replace(',', '.', $priceRaw)); + $type = intval($parts[5] ?? 0); + $this->concepts[$code] = [ 'code' => $code, 'unit' => $parts[1] ?? '', 'summary' => $parts[2] ?? '', - 'price' => $parts[3] ?? 0, + 'price' => $price, 'date' => $parts[4] ?? '', // Concept date + 'type' => $type, 'children' => [], 'decomposition' => [], // For ~D 'description' => '' // For ~T @@ -333,16 +339,40 @@ private function parseDecomposition($parts) if (strlen($childCode) === 0 || $childCode === '|') continue; - // Slot 2 + // Slot 2: Factor $factor1Raw = $items[$i + 1] ?? ''; - // Slot 3 + // Slot 3: Rendimiento o Tipo $factor2Raw = $items[$i + 2] ?? ''; - $f1 = ($factor1Raw === '') ? 1.0 : floatval(str_replace(',', '.', $factor1Raw)); - $f2 = ($factor2Raw === '') ? 1.0 : floatval(str_replace(',', '.', $factor2Raw)); + // Determinar el factor real. + // Si el segundo campo tiene valor, lo usamos. Si no, si el primer campo tiene valor, lo usamos. + // Esto da soporte a formatos con dobles barras como mo001\\3.62 + $f1 = ($factor1Raw === '') ? null : floatval(str_replace(',', '.', $factor1Raw)); + $f2 = ($factor2Raw === '') ? null : floatval(str_replace(',', '.', $factor2Raw)); + + $factor = 1.0; + if ($f2 !== null) { + $factor = $f2; + } elseif ($f1 !== null) { + $factor = $f1; + } - // Combined factor - $factor = $f1 * $f2; + // El tipo de recurso se lee principalmente desde la definición del concepto, + // pero si no se encuentra, podemos deducirlo por el prefijo del código del elemento hijo. + $type = 0; + if (isset($this->concepts[$childCode])) { + $type = $this->concepts[$childCode]['type'] ?? 0; + } + if ($type === 0) { + $lowerCode = strtolower($childCode); + if (strpos($lowerCode, 'mo') === 0 || strpos($lowerCode, 'mano') === 0) { + $type = 1; + } elseif (strpos($lowerCode, 'mq') === 0 || strpos($lowerCode, 'maq') === 0) { + $type = 2; + } elseif (strpos($lowerCode, 'mt') === 0 || strpos($lowerCode, 'mat') === 0) { + $type = 3; + } + } // Advance index by 2 (so loop increments by 1 total 3) $i += 2; @@ -350,7 +380,8 @@ private function parseDecomposition($parts) $this->concepts[$parentCode]['children'][] = $childCode; $this->concepts[$parentCode]['decomposition'][] = [ 'code' => $childCode, - 'factor' => $factor + 'factor' => $factor, + 'type' => $type ]; } } diff --git a/app.js b/app.js index 368970e..e4c8e33 100644 --- a/app.js +++ b/app.js @@ -1,9 +1,11 @@ // 1. File Input Change const fileInput = document.getElementById('bc3file'); +let currentFileName = "presupuesto.bc3"; if (fileInput) { fileInput.addEventListener('change', function (e) { if (this.files && this.files.length > 0) { - document.getElementById('fileName').textContent = this.files[0].name; + currentFileName = this.files[0].name; + document.getElementById('fileName').textContent = currentFileName; } }); } @@ -73,11 +75,36 @@ if (uploadForm) { } let parsedData = null; +let originalFileText = ""; +const expandedNodes = new Set(); + +// Historial para Deshacer/Rehacer (Ctrl+Z / Ctrl+Y) +let stateHistory = []; +let historyIndex = -1; + +// Estado de Comparación y Coeficientes +let compareData = null; +let compareActive = false; +let globalCoeffs = { gg: 13, bi: 6, baja: 0 }; +let typeChartInstance = null; +let chaptersChartInstance = null; // Drill-down navigation state let navigationStack = []; // Stack of { code, title } objects let currentLevel = null; // null = root level, or code of current parent +// Obtener la descomposición de un concepto con factores +function getConceptDecomposition(concept) { + if (!concept) return []; + if (Array.isArray(concept.decomposition) && concept.decomposition.length > 0) { + return concept.decomposition; + } + if (Array.isArray(concept.children) && concept.children.length > 0) { + return concept.children.map(c => ({ code: c, factor: 1 })); + } + return []; +} + // Check if we're in mobile mode function isMobileMode() { return window.innerWidth <= 768; @@ -191,22 +218,21 @@ function renderCurrentLevel() { const roots = Array.isArray(parsedData.root_nodes) ? parsedData.root_nodes : Object.values(parsedData.root_nodes); roots.forEach(code => { const rootNode = createNode(code, true, 0, 1, true); // true = mobile mode - rootList.appendChild(rootNode); + if (rootNode) { + rootList.appendChild(rootNode); + } }); } else { // Show children of current level const concept = parsedData.concepts[currentLevel]; if (concept) { - let decomposition = []; - if (Array.isArray(concept.decomposition) && concept.decomposition.length > 0) { - decomposition = concept.decomposition; - } else if (Array.isArray(concept.children) && concept.children.length > 0) { - decomposition = concept.children.map(c => ({ code: c, factor: 1 })); - } + const decomposition = getConceptDecomposition(concept); decomposition.forEach(item => { - const childNode = createNode(item.code, false, 0, item.factor, true); // true = mobile mode - rootList.appendChild(childNode); + const childNode = createNode(item.code, false, 0, item.factor, true, item.type || 0); // true = mobile mode + if (childNode) { + rootList.appendChild(childNode); + } }); } } @@ -215,7 +241,9 @@ function renderCurrentLevel() { const roots = Array.isArray(parsedData.root_nodes) ? parsedData.root_nodes : Object.values(parsedData.root_nodes); roots.forEach(code => { const rootNode = createNode(code, true, 0, 1, false); // false = desktop mode - rootList.appendChild(rootNode); + if (rootNode) { + rootList.appendChild(rootNode); + } }); } @@ -290,11 +318,58 @@ function updateGridTemplate() { function renderApp(data) { parsedData = data; + originalFileText = data.original_text || ""; + expandedNodes.clear(); + + // Inicializar historial + stateHistory = [JSON.stringify(parsedData)]; + historyIndex = 0; + updateUndoRedoButtonsState(); // Reset navigation state navigationStack = []; currentLevel = null; + // Show control buttons + const sBtn = document.getElementById('saveBtn'); + const exportDrop = document.getElementById('exportDropdown'); + const cBtn = document.getElementById('compareBtn'); + const dBtn = document.getElementById('dashboardBtn'); + if (sBtn) sBtn.style.display = 'inline-block'; + if (exportDrop) exportDrop.style.display = 'inline-block'; + if (cBtn) cBtn.style.display = 'inline-block'; + if (dBtn) dBtn.style.display = 'inline-block'; + + // Resetear comparador y coeficientes al cargar un nuevo presupuesto + compareData = null; + compareActive = false; + const compResults = document.getElementById('compareResults'); + if (compResults) compResults.style.display = 'none'; + const totalPecDisplay = document.getElementById('budgetTotalPEC'); + if (totalPecDisplay) totalPecDisplay.style.display = 'none'; + const toggleCoeffs = document.getElementById('toggleCoeffsBtn'); + if (toggleCoeffs) toggleCoeffs.style.display = 'inline-block'; + const coeffsPanel = document.getElementById('coeffsPanel'); + if (coeffsPanel) coeffsPanel.style.display = 'none'; + + // Restablecer valores de inputs de coeficientes a los valores por defecto + const ggIn = document.getElementById('coeffGG'); + const biIn = document.getElementById('coeffBI'); + const bajaIn = document.getElementById('coeffBaja'); + if (ggIn) ggIn.value = 13; + if (biIn) biIn.value = 6; + if (bajaIn) bajaIn.value = 0; + globalCoeffs = { gg: 13, bi: 6, baja: 0 }; + + // Mostrar barra de filtros + const filterBar = document.getElementById('filterBar'); + if (filterBar) filterBar.style.display = 'flex'; + + // Recalcular todo el presupuesto de abajo hacia arriba inmediatamente al cargar + recalculateAll(); + + updateTotalBudgetDisplay(); + // Render Project Info (only if elements exist - for standalone viewer) const info = document.getElementById('projectInfo'); if (info) { @@ -463,7 +538,12 @@ function filterTree(text) { * @param {number} qty - Quantity of this node in the parent context (factor) * @param {boolean} mobileMode - Whether to render in mobile drill-down mode */ -function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false) { +function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false, type = 0) { + // Validar si el nodo debe mostrarse según filtros activos + if (typeof shouldShowNode === 'function' && !shouldShowNode(code)) { + return null; + } + const concept = parsedData.concepts[code]; if (!concept) { console.warn('Missing concept:', code); @@ -481,13 +561,8 @@ function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false let decomposition = []; // Helper to get decomposition with factors - if (Array.isArray(concept.decomposition) && concept.decomposition.length > 0) { - decomposition = concept.decomposition; - hasChildren = true; - } else if (Array.isArray(concept.children) && concept.children.length > 0) { - // Fallback if decomposition is missing but children exist (should verify parser) - // Convert strict references to decomposition-like objects with factor 1 - decomposition = concept.children.map(c => ({ code: c, factor: 1 })); + decomposition = getConceptDecomposition(concept); + if (decomposition.length > 0) { hasChildren = true; } @@ -537,7 +612,7 @@ function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false // Usually leaves don't have arrows. if (hasChildren) { toggle.style.opacity = '1'; - if (isRoot) toggle.classList.add('expanded'); + if (isRoot || expandedNodes.has(code)) toggle.classList.add('expanded'); } else { toggle.style.opacity = '0'; // Invisible but keeps alignment if fixed width // Or display none? If display none, text shifts left. Better to keep placeholder or use opacity. @@ -551,6 +626,30 @@ function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false codeSpan.textContent = concept.code.replace(/#+\s*$/, ''); colCode.appendChild(codeSpan); + // Add resource type badge if type is defined (1=MO, 2=MAQ, 3=MAT, 4=SUB) + if (type > 0 && type <= 4) { + const badge = document.createElement('span'); + badge.className = 'badge'; + if (type === 1) { + badge.classList.add('badge-mo'); + badge.textContent = 'MO'; + badge.title = 'Mano de obra'; + } else if (type === 2) { + badge.classList.add('badge-maq'); + badge.textContent = 'MAQ'; + badge.title = 'Maquinaria'; + } else if (type === 3) { + badge.classList.add('badge-mat'); + badge.textContent = 'MAT'; + badge.title = 'Material'; + } else if (type === 4) { + badge.classList.add('badge-sub'); + badge.textContent = 'SUB'; + badge.title = 'Subcontrato'; + } + colCode.appendChild(badge); + } + // 2. Column: Unit // 3. Column: Unit @@ -558,10 +657,44 @@ function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false colUnit.className = 'col-unit'; colUnit.textContent = concept.unit; - // 4. Column: Summary + // 4. Column: Summary (Editable) const colSummary = document.createElement('div'); colSummary.className = 'col-summary'; colSummary.textContent = concept.summary || '(Sin título)'; + + colSummary.contentEditable = "true"; + colSummary.addEventListener('click', (e) => { + e.stopPropagation(); // Evitar expandir/contraer la fila al editar + }); + + colSummary.addEventListener('keydown', (e) => { + if (e.key === 'Enter') { + e.preventDefault(); // Evitar salto de línea + + const newSummary = colSummary.textContent.trim(); + if (newSummary && concept.summary !== newSummary) { + concept.summary = newSummary; + + // Actualizar panel de detalles si coincide el código + const detCodeEl = document.getElementById('detCode'); + const detSummaryEl = document.getElementById('detSummary'); + if (detCodeEl && detSummaryEl && detCodeEl.textContent === concept.code.replace(/#+\s*$/, '')) { + detSummaryEl.textContent = newSummary; + } + } + colSummary.blur(); + } + }); + + colSummary.addEventListener('blur', () => { + const newSummary = colSummary.textContent.trim(); + if (newSummary && newSummary !== concept.summary) { + concept.summary = newSummary; + saveHistoryState(); + } else { + colSummary.textContent = concept.summary || '(Sin título)'; + } + }); // Values const priceVal = parseFloat(concept.price); @@ -573,11 +706,99 @@ function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false colQty.className = 'col-quantity'; colQty.textContent = isNaN(qtyVal) ? '' : qtyVal.toLocaleString('es-ES', { minimumFractionDigits: 3 }); - // 6. Column: Price + // 6. Column: Price (Editable solo para partidas, no capítulos/raíces) const colPrice = document.createElement('div'); colPrice.className = 'col-price'; colPrice.textContent = isNaN(priceVal) ? '' : priceVal.toLocaleString('es-ES', { minimumFractionDigits: 2 }); + // Agregar desviación si el comparador está activo + if (compareActive && compareData && compareData[code]) { + const compConcept = compareData[code]; + const mainPrice = parseFloat(concept.price) || 0; + const compPrice = parseFloat(compConcept.price) || 0; + if (mainPrice !== compPrice) { + const diffPrice = mainPrice - compPrice; + const pct = compPrice === 0 ? 0 : (diffPrice / compPrice) * 100; + const badge = document.createElement('span'); + badge.className = 'dev-badge ' + (diffPrice >= 0 ? 'dev-up' : 'dev-down'); + badge.textContent = `${diffPrice >= 0 ? '+' : ''}${pct.toFixed(1)}%`; + colPrice.appendChild(badge); + } + } + + const isEditablePrice = !concept.code.endsWith('#'); + if (isEditablePrice) { + colPrice.contentEditable = "true"; + colPrice.addEventListener('click', (e) => { + e.stopPropagation(); // Evitar expandir/contraer la fila al editar + }); + + colPrice.addEventListener('focus', () => { + // Mostrar número simple sin formatear para edición cómoda + const rawPrice = parseFloat(concept.price) || 0; + colPrice.textContent = rawPrice; + + // Seleccionar todo el texto + const range = document.createRange(); + range.selectNodeContents(colPrice); + const sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + }); + + colPrice.addEventListener('keydown', (e) => { + if (e.key === 'Enter') { + e.preventDefault(); // Evitar salto de línea + + const valText = colPrice.textContent.trim().replace(',', '.'); + const newVal = parseFloat(valText); + + if (!isNaN(newVal) && newVal >= 0) { + if (parseFloat(concept.price) !== newVal) { + concept.price = newVal; + concept.isManualPrice = true; // Bloquear precio manual + recalculateAll(); + + const scrollPos = document.getElementById('treeContent').scrollTop; + renderCurrentLevel(); + document.getElementById('treeContent').scrollTop = scrollPos; + + updateTotalBudgetDisplay(); + saveHistoryState(); + return; // Retornar ya que re-renderiza y destruye el foco + } + } + colPrice.blur(); + } + }); + + colPrice.addEventListener('blur', () => { + const valText = colPrice.textContent.trim().replace(',', '.'); + const newVal = parseFloat(valText); + + if (!isNaN(newVal) && newVal >= 0) { + if (parseFloat(concept.price) !== newVal) { + concept.price = newVal; + concept.isManualPrice = true; // Bloquear precio manual + recalculateAll(); + + const scrollPos = document.getElementById('treeContent').scrollTop; + renderCurrentLevel(); + document.getElementById('treeContent').scrollTop = scrollPos; + + updateTotalBudgetDisplay(); + saveHistoryState(); + } + } else { + // Revertir al valor original si no es número válido + const prevPrice = parseFloat(concept.price) || 0; + colPrice.textContent = prevPrice.toLocaleString('es-ES', { minimumFractionDigits: 2 }); + } + }); + } else { + colPrice.contentEditable = "false"; + } + // 7. Column: Amount (Importe) const colAmount = document.createElement('div'); colAmount.className = 'col-amount'; @@ -600,8 +821,8 @@ function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false // Click handlers row.onclick = (e) => { - // Prevent triggering if we clicked a link or input (just in case) - if (e.target.tagName === 'INPUT' || e.target.tagName === 'A') return; + // Prevent triggering if we clicked a link, input or editable price + if (e.target.tagName === 'INPUT' || e.target.tagName === 'A' || e.target.classList.contains('col-price')) return; // Mobile mode behavior if (mobileMode) { @@ -636,9 +857,11 @@ function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false if (isVisible) { childrenContainer.classList.remove('visible'); toggle.classList.remove('expanded'); + expandedNodes.delete(code); // Guardar estado } else { childrenContainer.classList.add('visible'); toggle.classList.add('expanded'); + expandedNodes.add(code); // Guardar estado } } } @@ -652,7 +875,9 @@ function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false if (hasChildren) { const childrenContainer = document.createElement('div'); childrenContainer.className = 'tree-node-children'; - if (isRoot) { + + const isNodeExpanded = isRoot || expandedNodes.has(code); + if (isNodeExpanded) { childrenContainer.classList.add('visible'); } @@ -684,7 +909,10 @@ function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false // Only render children in desktop mode (in mobile, we navigate to them) if (!mobileMode) { decomposition.forEach(item => { - childrenContainer.appendChild(createNode(item.code, false, depth + 1, item.factor, mobileMode)); + const childNode = createNode(item.code, false, depth + 1, item.factor, mobileMode, item.type || 0); + if (childNode) { + childrenContainer.appendChild(childNode); + } }); } @@ -699,7 +927,7 @@ function createNode(code, isRoot = false, depth = 0, qty = 1, mobileMode = false * createMeasurementTable * Renders a full HTML table for measurements with calculations. */ -function createMeasurementTable(measurements) { +function createMeasurementTable(measurements, concept = null) { const container = document.createElement('div'); container.className = 'measurements-container'; @@ -723,20 +951,14 @@ function createMeasurementTable(measurements) { const tbody = document.createElement('tbody'); let total = 0; - measurements.forEach(m => { + measurements.forEach((m, idx) => { const tr = document.createElement('tr'); - // Calculate Partial - // Logic: Empty values imply 1 for multiplication usually, UNLESS all dims are empty? - // User said "Cuando un valor sea nulo se asumirá un valor 1". - - const u = m.units === '' ? 1 : parseFloat(m.units.replace(',', '.')); - const l = m.l === '' ? 1 : parseFloat(m.l.replace(',', '.')); - const w = m.w === '' ? 1 : parseFloat(m.w.replace(',', '.')); - const h = m.h === '' ? 1 : parseFloat(m.h.replace(',', '.')); + const u = m.units === '' ? 1 : parseFloat(m.units.toString().replace(',', '.')); + const l = m.l === '' ? 1 : parseFloat(m.l.toString().replace(',', '.')); + const w = m.w === '' ? 1 : parseFloat(m.w.toString().replace(',', '.')); + const h = m.h === '' ? 1 : parseFloat(m.h.toString().replace(',', '.')); - // Default to 1 if parsing failed (NaN), or strictly 1? - // Let's assume valid numbers or 1. const vU = isNaN(u) ? 1 : u; const vL = isNaN(l) ? 1 : l; const vW = isNaN(w) ? 1 : w; @@ -745,14 +967,86 @@ function createMeasurementTable(measurements) { const partial = vU * vL * vW * vH; total += partial; - tr.innerHTML = ` - ${m.label || ''} - ${m.units || ''} - ${m.l || ''} - ${m.w || ''} - ${m.h || ''} - ${partial.toLocaleString('es-ES', { minimumFractionDigits: 2, maximumFractionDigits: 3 })} - `; + // Celdas Editables (Solo si concept está presente y es editable) + const isEditable = concept && !concept.code.endsWith('#'); + + // Descripción + const tdLabel = document.createElement('td'); + tdLabel.textContent = m.label || ''; + if (isEditable) { + tdLabel.className = 'm-cell-editable'; + tdLabel.contentEditable = 'true'; + tdLabel.addEventListener('blur', () => { + m.label = tdLabel.textContent.trim(); + }); + tdLabel.addEventListener('keydown', (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + tdLabel.blur(); + } + }); + } + + // Celdas numéricas editables + function createNumericCell(fieldValue, fieldName) { + const td = document.createElement('td'); + td.className = 'numeric'; + td.textContent = fieldValue === '' ? '' : parseFloat(fieldValue).toLocaleString('es-ES'); + + if (isEditable) { + td.className += ' m-cell-editable'; + td.contentEditable = 'true'; + + td.addEventListener('focus', () => { + // Cargar número crudo sin formatear para editar cómodamente + td.textContent = fieldValue === '' ? '' : parseFloat(fieldValue); + }); + + td.addEventListener('keydown', (e) => { + if (e.key === 'Enter') { + e.preventDefault(); + td.blur(); + } + }); + + td.addEventListener('blur', () => { + const rawText = td.textContent.trim().replace(',', '.'); + let val = parseFloat(rawText); + + if (rawText === '') { + m[fieldName] = ''; + } else if (!isNaN(val)) { + m[fieldName] = val; + } else { + // Revertir + td.textContent = fieldValue === '' ? '' : parseFloat(fieldValue).toLocaleString('es-ES'); + return; + } + + // Recalcular + recalculateMeasurements(concept); + }); + } + + return td; + } + + const tdUnits = createNumericCell(m.units, 'units'); + const tdL = createNumericCell(m.l, 'l'); + const tdW = createNumericCell(m.w, 'w'); + const tdH = createNumericCell(m.h, 'h'); + + const tdPartial = document.createElement('td'); + tdPartial.className = 'numeric'; + tdPartial.innerHTML = `${partial.toLocaleString('es-ES', { minimumFractionDigits: 2, maximumFractionDigits: 3 })}`; + + tr.appendChild(tdLabel); + tr.appendChild(tdUnits); + tr.appendChild(tdL); + tr.appendChild(tdW); + tr.appendChild(tdH); + tr.appendChild(tdPartial); + tbody.appendChild(tr); }); @@ -761,7 +1055,7 @@ function createMeasurementTable(measurements) { trTotal.className = 'total-row'; trTotal.innerHTML = ` TOTAL: - ${total.toLocaleString('es-ES', { minimumFractionDigits: 2, maximumFractionDigits: 3 })} + ${total.toLocaleString('es-ES', { minimumFractionDigits: 2, maximumFractionDigits: 3 })} `; tbody.appendChild(trTotal); @@ -830,7 +1124,7 @@ function showMobileDetails(code, container) { tableTitle.textContent = 'Líneas de Medición'; detailsContainer.appendChild(tableTitle); - const msTable = createMeasurementTable(concept.measurements); + const msTable = createMeasurementTable(concept.measurements, concept); detailsContainer.appendChild(msTable); } @@ -854,6 +1148,19 @@ function showDetails(code) { // Description: Prefer ~T description, fallback to Summary document.getElementById('detDescription').innerHTML = (concept.description || concept.summary).replace(/\n/g, '
'); + // Mediciones en Panel de Escritorio + const msSection = document.getElementById('detMeasurementsSection'); + const msDiv = document.getElementById('detMeasurements'); + if (msSection && msDiv) { + if (concept.measurements && concept.measurements.length > 0) { + msSection.style.display = 'block'; + msDiv.innerHTML = ''; + msDiv.appendChild(createMeasurementTable(concept.measurements, concept)); + } else { + msSection.style.display = 'none'; + } + } + // Decomposition Table const tbody = document.getElementById('detDecomposition'); tbody.innerHTML = ''; @@ -890,3 +1197,1292 @@ function showDetails(code) { // Usually they match. If not, maybe show warning or just stated. document.getElementById('detTotalCost').textContent = statedPrice.toLocaleString('es-ES', { style: 'currency', currency: 'EUR' }); } + +/* ========================================================================== + Lógica de Recálculo, Modo Oscuro, Drag & Drop y Exportación BC3 + ========================================================================== */ + +// Recálculo recursivo de precios ascendente +function recalculateConceptPrice(code, visited = new Set()) { + if (visited.has(code)) { + return parseFloat(parsedData.concepts[code].price) || 0; + } + visited.add(code); + + const concept = parsedData.concepts[code]; + if (!concept) return 0; + + let decomposition = getConceptDecomposition(concept); + + if (decomposition.length > 0 && !concept.isManualPrice) { + let sum = 0; + decomposition.forEach(item => { + const childPrice = recalculateConceptPrice(item.code, visited); + sum += childPrice * parseFloat(item.factor); + }); + concept.price = sum; + } + + return parseFloat(concept.price) || 0; +} + +function recalculateAll() { + if (!parsedData) return; + const visited = new Set(); + const roots = Array.isArray(parsedData.root_nodes) ? parsedData.root_nodes : Object.values(parsedData.root_nodes); + roots.forEach(rootCode => { + recalculateConceptPrice(rootCode, visited); + }); +} + +function calculateTotalBudget() { + if (!parsedData) return 0; + let total = 0; + const roots = Array.isArray(parsedData.root_nodes) ? parsedData.root_nodes : Object.values(parsedData.root_nodes); + roots.forEach(code => { + const concept = parsedData.concepts[code]; + if (concept) { + total += parseFloat(concept.price) || 0; + } + }); + return total; +} + +function updateTotalBudgetDisplay() { + const totalEl = document.getElementById('budgetTotal'); + const totalPecEl = document.getElementById('budgetTotalPEC'); + const toggleCoeffsBtn = document.getElementById('toggleCoeffsBtn'); + + if (totalEl) { + const pem = calculateTotalBudget(); + + // Actualizar PEM + totalEl.textContent = `PEM: ${pem.toLocaleString('es-ES', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} €`; + + // Mostrar botón de coeficientes + if (toggleCoeffsBtn) toggleCoeffsBtn.style.display = 'inline-block'; + + // Calcular PEC + const gg = globalCoeffs.gg / 100; + const bi = globalCoeffs.bi / 100; + const baja = globalCoeffs.baja / 100; + + // PEC = (PEM * (1 + GG + BI)) * (1 + Baja) + const pemWithCoeffs = pem * (1 + gg + bi); + const pec = pemWithCoeffs * (1 + baja); + + if (totalPecEl) { + totalPecEl.textContent = `PEC: ${pec.toLocaleString('es-ES', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} €`; + totalPecEl.style.display = 'inline-block'; + } + } +} + +// Reconstrucción del archivo BC3 +function generateModifiedBC3() { + if (!originalFileText) return ""; + + const lines = originalFileText.split(/\r?\n/); + const modifiedLines = []; + let skipLinesUntilNonSlash = false; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const trimmed = line.trim(); + + if (skipLinesUntilNonSlash) { + if (trimmed.startsWith('\\')) { + // Saltar las líneas de medición originales + continue; + } else { + skipLinesUntilNonSlash = false; + } + } + + if (trimmed.startsWith('~C|')) { + const parts = trimmed.split('|'); + const code = parts[1]; + if (code && parsedData.concepts[code]) { + const concept = parsedData.concepts[code]; + parts[4] = parseFloat(concept.price).toFixed(2); + parts[3] = concept.summary || ""; + modifiedLines.push(parts.join('|')); + } else { + modifiedLines.push(line); + } + } else if (trimmed.startsWith('~D|')) { + const parts = trimmed.split('|'); + const parentCode = parts[1]; + const parentConcept = parsedData.concepts[parentCode]; + if (parentConcept && parentConcept.decomposition && parentConcept.decomposition.length > 0) { + const decompParts = []; + parentConcept.decomposition.forEach(item => { + decompParts.push(item.code); + decompParts.push(parseFloat(item.factor).toFixed(3)); + decompParts.push(item.type || 0); + }); + parts[2] = decompParts.join('\\') + '\\'; + modifiedLines.push(parts.join('|')); + } else { + modifiedLines.push(line); + } + } else if (trimmed.startsWith('~M|')) { + const parts = trimmed.split('|'); + // Formato: ~M|PARENT\CHILD|1\1\1\1\|TOTAL_SUM| + const parentChild = parts[1]; // e.g. "01#\01.01" + const childCode = parentChild.split('\\')[1]; + const concept = parsedData.concepts[childCode]; + + if (concept && concept.measurements && concept.measurements.length > 0) { + // Escribir la línea principal ~M + const totalSum = parseFloat(concept.quantity) || 0; + parts[3] = totalSum.toFixed(3); + modifiedLines.push(parts.join('|')); + + // Escribir las sublíneas de mediciones editadas + concept.measurements.forEach(m => { + const label = m.label || ""; + const units = m.units === '' ? "" : parseFloat(m.units).toFixed(3); + const l = m.l === '' ? "" : parseFloat(m.l).toFixed(3); + const w = m.w === '' ? "" : parseFloat(m.w).toFixed(3); + const h = m.h === '' ? "" : parseFloat(m.h).toFixed(3); + + // Formato FIEBDC: \Label\Units\L\W\H\ + modifiedLines.push(`\\${label}\\${units}\\${l}\\${w}\\${h}\\`); + }); + + // Activar el salto de las líneas de medición originales que siguen + skipLinesUntilNonSlash = true; + } else { + modifiedLines.push(line); + } + } else if (trimmed.startsWith('~V|')) { + // Actualizar la codificación a UTF-8 para garantizar legibilidad + const parts = trimmed.split('|'); + if (parts.length >= 6) { + parts[5] = "UTF-8"; + } + modifiedLines.push(parts.join('|')); + } else { + modifiedLines.push(line); + } + } + + return modifiedLines.join('\r\n'); +} + +// Botón Guardar +const saveBtn = document.getElementById('saveBtn'); +if (saveBtn) { + saveBtn.addEventListener('click', () => { + if (!parsedData) { + alert("No hay datos de archivo cargados."); + return; + } + const content = generateModifiedBC3(); + if (!content) { + alert("Error al generar el archivo modificado."); + return; + } + + const blob = new Blob([content], { type: "text/plain;charset=utf-8" }); + const link = document.createElement("a"); + + const baseName = currentFileName.replace(/\.[^/.]+$/, ""); + link.href = URL.createObjectURL(blob); + link.download = `${baseName}_modificado.bc3`; + + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }); +} + +// Función para exportar a PDF (DIN A4 esquematizado) +function exportToPdf() { + if (!parsedData) { + alert("No hay datos de archivo cargados."); + return; + } + + // Importar jsPDF y jspdf-autotable (desde window) + let jsPDFConstructor = null; + if (window.jspdf && window.jspdf.jsPDF) { + jsPDFConstructor = window.jspdf.jsPDF; + } else if (window.jsPDF) { + jsPDFConstructor = window.jsPDF; + } + + if (!jsPDFConstructor) { + alert("La librería PDF no se cargó correctamente. Por favor verifica tu conexión a internet."); + return; + } + + // Crear documento A4 (p = portrait, mm = milímetros, a4 = DIN A4) + const doc = new jsPDFConstructor({ + orientation: 'portrait', + unit: 'mm', + format: 'a4' + }); + + // Validar extensión AutoTable + if (typeof doc.autoTable !== 'function') { + alert("La extensión de tablas para PDF (AutoTable) no está disponible. Por favor recarga la página."); + return; + } + + // Título del presupuesto + const budgetTitle = parsedData.properties.description || "Presupuesto sin título"; + const budgetOwner = parsedData.properties.owner || ""; + const totalBudgetAmount = calculateTotalBudget(); + + // 1. Título y bloque de metadatos en la primera página + doc.setFont("helvetica", "bold"); + doc.setFontSize(16); + doc.setTextColor(128, 0, 32); // Granate + doc.text("PRESUPUESTO DE OBRA", 15, 20); + + doc.setFont("helvetica", "normal"); + doc.setFontSize(9); + doc.setTextColor(60, 60, 60); + doc.text(`Proyecto: ${budgetTitle}`, 15, 26); + if (budgetOwner) { + doc.text(`Propietario: ${budgetOwner}`, 15, 31); + doc.text(`Fecha de exportación: ${new Date().toLocaleDateString('es-ES')}`, 15, 36); + } else { + doc.text(`Fecha de exportación: ${new Date().toLocaleDateString('es-ES')}`, 15, 31); + } + + doc.setFont("helvetica", "bold"); + doc.setFontSize(10); + doc.setTextColor(22, 163, 74); // Verde para el total + const formattedTotalStr = totalBudgetAmount.toLocaleString('es-ES', { style: 'currency', currency: 'EUR' }); + doc.text(`TOTAL PRESUPUESTO: ${formattedTotalStr}`, 15, budgetOwner ? 41 : 36); + + // Línea divisoria en granate + doc.setDrawColor(128, 0, 32); // Granate + doc.setLineWidth(0.5); + doc.line(15, budgetOwner ? 44 : 39, 195, budgetOwner ? 44 : 39); + + // 2. Extraer datos del presupuesto en un formato plano + const dataRows = []; + + // Función recursiva para recorrer solo Capítulos, Subcapítulos y Partidas + function extractRowsRecursively(code, depth = 0, qty = 1) { + const concept = parsedData.concepts[code]; + if (!concept) return; + + const isChapter = concept.code.endsWith('#') || concept.is_root; + const priceVal = parseFloat(concept.price) || 0; + const qtyVal = parseFloat(qty) || 0; + const amountVal = priceVal * qtyVal; + + // Sangrar el resumen visualmente según la profundidad + const indent = " ".repeat(depth); + const summaryText = indent + (concept.summary || '(Sin título)'); + + const qtyStr = (qtyVal === 0 || isChapter) ? '' : qtyVal.toLocaleString('es-ES', { minimumFractionDigits: 3, maximumFractionDigits: 3 }); + const priceStr = (priceVal === 0 || isChapter) ? '' : priceVal.toLocaleString('es-ES', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + ' €'; + const amountStr = (amountVal === 0) ? '' : amountVal.toLocaleString('es-ES', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + ' €'; + + dataRows.push({ + code: concept.code.replace(/#+\s*$/, ''), + unit: concept.unit || '', + summary: summaryText, + qty: qtyStr, + price: priceStr, + amount: amountStr, + depth: depth + }); + + // Recorrer los hijos si es un capítulo + if (isChapter) { + const children = getConceptDecomposition(concept); + children.forEach(child => { + extractRowsRecursively(child.code, depth + 1, child.factor); + }); + } + } + + const roots = Array.isArray(parsedData.root_nodes) ? parsedData.root_nodes : Object.values(parsedData.root_nodes); + roots.forEach(rootCode => { + extractRowsRecursively(rootCode, 0, 1); + }); + + // 3. Generar la tabla usando AutoTable + doc.autoTable({ + startY: budgetOwner ? 48 : 43, + margin: { left: 15, right: 15, bottom: 20 }, + theme: 'plain', + styles: { + fontSize: 7.5, + cellPadding: 2, + lineColor: [220, 220, 220], + lineWidth: 0.1, + textColor: [40, 40, 40], + font: 'helvetica' + }, + columnStyles: { + 0: { cellWidth: 20 }, // Código + 1: { cellWidth: 10, halign: 'center' }, // Unidad + 2: { cellWidth: 'auto' }, // Resumen/Descripción + 3: { cellWidth: 18, halign: 'right' }, // Cantidad + 4: { cellWidth: 22, halign: 'right' }, // Precio + 5: { cellWidth: 25, halign: 'right' } // Importe + }, + head: [['Código', 'Ud', 'Resumen', 'Cant.', 'Precio', 'Importe']], + headStyles: { + fillColor: [128, 0, 32], // Granate institucional + textColor: [255, 255, 255], + fontStyle: 'bold', + fontSize: 8.5, + lineWidth: 0 + }, + body: dataRows.map(r => [r.code, r.unit, r.summary, r.qty, r.price, r.amount]), + + // Estilos específicos por fila (Capítulos vs Partidas) + didParseCell: function (data) { + if (data.row.section !== 'body') return; + + const rowIndex = data.row.index; + const rowData = dataRows[rowIndex]; + + if (rowData) { + // Si es capítulo raíz (depth = 0) + if (rowData.depth === 0) { + data.cell.styles.fillColor = [240, 240, 240]; + data.cell.styles.fontStyle = 'bold'; + data.cell.styles.textColor = [0, 0, 0]; + } + // Si es un capítulo intermedio (depth = 1) + else if (rowData.depth === 1) { + data.cell.styles.fillColor = [248, 248, 248]; + data.cell.styles.fontStyle = 'bold'; + } + // Si es un subcapítulo/partida sangrado + else if (rowData.depth >= 2 && data.column.index === 2) { + // Solo el texto del resumen en negrita si no tiene precio (es decir, es un subcapítulo) + if (rowData.price === '') { + data.cell.styles.fontStyle = 'bold'; + } + } + } + } + }); + + // 4. Estampar encabezados y pies de página (Página X de Y) en todas las hojas creadas + const totalPages = doc.internal.getNumberOfPages(); + for (let i = 1; i <= totalPages; i++) { + doc.setPage(i); + + // Dibujar encabezado en páginas después de la primera + if (i > 1) { + doc.setFont("helvetica", "normal"); + doc.setFontSize(8); + doc.setTextColor(120, 120, 120); + doc.text(budgetTitle.substring(0, 50) + (budgetTitle.length > 50 ? '...' : ''), 15, 10); + doc.text("PRESUPUESTO DE OBRA", 195 - doc.getTextWidth("PRESUPUESTO DE OBRA"), 10); + + // Línea superior de cabecera + doc.setDrawColor(200, 200, 200); + doc.setLineWidth(0.2); + doc.line(15, 12, 195, 12); + } + + // Pie de página (Footer) + doc.setFont("helvetica", "normal"); + doc.setFontSize(8); + doc.setTextColor(120, 120, 120); + + // Línea inferior de pie + doc.setDrawColor(200, 200, 200); + doc.setLineWidth(0.2); + doc.line(15, 282, 195, 282); + + // Textos pie de página + doc.text("© Licencia Open Source - Software Libre y de Derechos Abiertos | V.1 by Jose Manuel Caamaño", 15, 287); + + const pageStr = `Página ${i} de ${totalPages}`; + doc.text(pageStr, 195 - doc.getTextWidth(pageStr), 287); + } + + // Guardar/Descargar el PDF + const baseName = currentFileName.replace(/\.[^/.]+$/, ""); + doc.save(`${baseName}_presupuesto.pdf`); +} + +// Modo Oscuro +const themeToggleBtn = document.getElementById('themeToggle'); +if (themeToggleBtn) { + if (localStorage.getItem('theme') === 'dark' || + (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) { + document.body.classList.add('dark-theme'); + themeToggleBtn.textContent = '☀️'; + } else { + document.body.classList.remove('dark-theme'); + themeToggleBtn.textContent = '🌙'; + } + + themeToggleBtn.addEventListener('click', () => { + const isDark = document.body.classList.toggle('dark-theme'); + themeToggleBtn.textContent = isDark ? '☀️' : '🌙'; + localStorage.setItem('theme', isDark ? 'dark' : 'light'); + }); +} + +// Drag & Drop +const dragOverlay = document.getElementById('dragOverlay'); + +window.addEventListener('dragenter', (e) => { + e.preventDefault(); + if (dragOverlay) dragOverlay.style.display = 'flex'; +}); + +window.addEventListener('dragover', (e) => { + e.preventDefault(); +}); + +if (dragOverlay) { + dragOverlay.addEventListener('dragleave', (e) => { + if (e.relatedTarget === null || !dragOverlay.contains(e.relatedTarget)) { + dragOverlay.style.display = 'none'; + } + }); + + dragOverlay.addEventListener('drop', async (e) => { + e.preventDefault(); + dragOverlay.style.display = 'none'; + + const files = e.dataTransfer.files; + if (files && files.length > 0) { + const file = files[0]; + if (!file.name.endsWith('.bc3')) { + alert('Por favor, selecciona un archivo con extensión .bc3'); + return; + } + + currentFileName = file.name; + const fileNameEl = document.getElementById('fileName'); + if (fileNameEl) fileNameEl.textContent = currentFileName; + + // Simular subida idéntica al formulario + const formData = new FormData(); + formData.append('bc3file', file); + + const processBtn = document.querySelector('.process-btn'); + const originalText = processBtn ? processBtn.textContent : 'Procesar'; + if (processBtn) { + processBtn.textContent = 'Procesando...'; + processBtn.disabled = true; + } + + try { + const response = await fetch('upload.php', { + method: 'POST', + body: formData + }); + const result = await response.json(); + if (result.success) { + renderApp(result.data); + } else { + alert('Error: ' + (result.error || 'Unknown error')); + } + } catch (err) { + console.error(err); + alert('Error procesando el archivo'); + } finally { + if (processBtn) { + processBtn.textContent = originalText; + processBtn.disabled = false; + } + } + } + }); +} + +/* ========================================================================== + Nuevas Funcionalidades: Dashboard, Mediciones, Excel, Comparar y Coeficientes + ========================================================================== */ + +// 1. Auxiliar para actualizar factores de descomposición del padre al cambiar mediciones +function updateParentDecompositionFactor(childCode, newFactor) { + Object.values(parsedData.concepts).forEach(parentConcept => { + if (parentConcept.decomposition && parentConcept.decomposition.length > 0) { + parentConcept.decomposition.forEach(item => { + if (item.code === childCode) { + item.factor = newFactor; + } + }); + } + }); +} + +// 2. Recalcular cantidad del concepto basado en mediciones y actualizar +function recalculateMeasurements(concept) { + if (!concept || !concept.measurements) return; + + let total = 0; + concept.measurements.forEach(m => { + const u = m.units === '' ? 1 : parseFloat(m.units.toString().replace(',', '.')); + const l = m.l === '' ? 1 : parseFloat(m.l.toString().replace(',', '.')); + const w = m.w === '' ? 1 : parseFloat(m.w.toString().replace(',', '.')); + const h = m.h === '' ? 1 : parseFloat(m.h.toString().replace(',', '.')); + + const vU = isNaN(u) ? 1 : u; + const vL = isNaN(l) ? 1 : l; + const vW = isNaN(w) ? 1 : w; + const vH = isNaN(h) ? 1 : h; + + total += vU * vL * vW * vH; + }); + + // Actualizar el factor en el padre + updateParentDecompositionFactor(concept.code, total); + + // Guardar cantidad del concepto + concept.quantity = total; + + // Recalcular todo en cascada + recalculateAll(); + + // Actualizar el árbol visual + const scrollPos = document.getElementById('treeContent').scrollTop; + renderCurrentLevel(); + document.getElementById('treeContent').scrollTop = scrollPos; + + // Refrescar panel de detalles para ver reflejado el nuevo TOTAL + showDetails(concept.code); + updateTotalBudgetDisplay(); + saveHistoryState(); +} + +// 3. Exportación a Excel con SheetJS y Fórmulas +function exportToExcel() { + if (!parsedData) { + alert("No hay datos de archivo cargados."); + return; + } + + if (typeof XLSX === 'undefined') { + alert("La librería de Excel (SheetJS) no se cargó correctamente. Por favor verifica tu conexión a internet."); + return; + } + + const roots = Array.isArray(parsedData.root_nodes) ? parsedData.root_nodes : Object.values(parsedData.root_nodes); + const excelRows = []; + let currentRow = 2; // Fila 1 es cabecera + const rowChildrenMap = {}; + + function collectRows(code, depth = 0, qty = 1, parentRowIndex = null) { + const concept = parsedData.concepts[code]; + if (!concept) return; + + const isChapter = concept.code.endsWith('#') || concept.is_root; + const myRowIndex = currentRow++; + + if (parentRowIndex !== null) { + if (!rowChildrenMap[parentRowIndex]) rowChildrenMap[parentRowIndex] = []; + rowChildrenMap[parentRowIndex].push(myRowIndex); + } + + const priceVal = parseFloat(concept.price) || 0; + const qtyVal = parseFloat(qty) || 0; + + excelRows.push({ + rowIndex: myRowIndex, + code: concept.code.replace(/#+\s*$/, ''), + unit: concept.unit || '', + summary: " ".repeat(depth) + (concept.summary || '(Sin título)'), + qty: isChapter ? '' : qtyVal, + price: isChapter ? '' : priceVal, + isChapter: isChapter, + depth: depth + }); + + if (isChapter) { + const children = getConceptDecomposition(concept); + children.forEach(child => { + collectRows(child.code, depth + 1, child.factor, myRowIndex); + }); + } + } + + roots.forEach(rootCode => { + collectRows(rootCode, 0, 1, null); + }); + + const wb = XLSX.utils.book_new(); + const wsData = [ + ['Código', 'Ud', 'Resumen', 'Cantidad', 'Precio', 'Importe'] + ]; + + excelRows.forEach(row => { + wsData.push([ + row.code, + row.unit, + row.summary, + row.qty, + row.price, + '' // Fórmula + ]); + }); + + const ws = XLSX.utils.aoa_to_sheet(wsData); + + // Inyectar fórmulas y formatos + excelRows.forEach(row => { + const cellRef = `F${row.rowIndex}`; + if (row.isChapter) { + const childRows = rowChildrenMap[row.rowIndex]; + if (childRows && childRows.length > 0) { + const sumTerms = childRows.map(rIndex => `F${rIndex}`).join('+'); + ws[cellRef] = { f: sumTerms }; + } else { + ws[cellRef] = { v: 0 }; + } + } else { + ws[cellRef] = { f: `D${row.rowIndex}*E${row.rowIndex}` }; + } + }); + + // Formatear números + for (let r = 2; r <= excelRows.length + 1; r++) { + if (ws[`D${r}`] && ws[`D${r}`].v !== '') ws[`D${r}`].z = '#,##0.000'; + if (ws[`E${r}`] && ws[`E${r}`].v !== '') ws[`E${r}`].z = '#,##0.00 €'; + if (ws[`F${r}`]) ws[`F${r}`].z = '#,##0.00 €'; + } + + ws['!cols'] = [ + { wch: 15 }, // Código + { wch: 6 }, // Ud + { wch: 60 }, // Resumen + { wch: 12 }, // Cantidad + { wch: 12 }, // Precio + { wch: 15 } // Importe + ]; + + XLSX.utils.book_append_sheet(wb, ws, "Presupuesto"); + + // Guardar/Descargar el Excel + const baseName = currentFileName.replace(/\.[^/.]+$/, ""); + XLSX.writeFile(wb, `${baseName}_presupuesto.xlsx`); +} + +// 4. Lógica de Dashboard y Gráficos +function calculateResourceDistribution() { + const distribution = { MO: 0, MAQ: 0, MAT: 0, SUB: 0 }; + + function traverse(code, accumulatedQty) { + const concept = parsedData.concepts[code]; + if (!concept) return; + + const isChapter = concept.code.endsWith('#') || concept.is_root; + const children = getConceptDecomposition(concept); + + if (isChapter) { + children.forEach(child => { + traverse(child.code, accumulatedQty * (parseFloat(child.factor) || 1)); + }); + } else { + if (concept.decomposition && concept.decomposition.length > 0) { + concept.decomposition.forEach(item => { + const childConcept = parsedData.concepts[item.code]; + const childPrice = childConcept ? (parseFloat(childConcept.price) || 0) : 0; + const itemFactor = parseFloat(item.factor) || 0; + const itemType = item.type; // 1=MO, 2=MAQ, 3=MAT, 4=SUB + const totalCost = itemFactor * childPrice * accumulatedQty; + + if (itemType === 1) distribution.MO += totalCost; + else if (itemType === 2) distribution.MAQ += totalCost; + else if (itemType === 3) distribution.MAT += totalCost; + else distribution.SUB += totalCost; + }); + } else { + const price = parseFloat(concept.price) || 0; + const totalCost = price * accumulatedQty; + distribution.SUB += totalCost; + } + } + } + + const roots = Array.isArray(parsedData.root_nodes) ? parsedData.root_nodes : Object.values(parsedData.root_nodes); + roots.forEach(rootCode => { + traverse(rootCode, 1.0); + }); + + return distribution; +} + +function getTopChapters() { + const roots = Array.isArray(parsedData.root_nodes) ? parsedData.root_nodes : Object.values(parsedData.root_nodes); + const chapters = []; + + roots.forEach(rootCode => { + const concept = parsedData.concepts[rootCode]; + if (concept) { + const children = getConceptDecomposition(concept); + + children.forEach(child => { + const childConcept = parsedData.concepts[child.code]; + if (childConcept) { + chapters.push({ + summary: childConcept.summary || childConcept.code, + cost: (parseFloat(childConcept.price) || 0) * (parseFloat(child.factor) || 1) + }); + } + }); + } + }); + + if (chapters.length === 0) { + roots.forEach(rootCode => { + const concept = parsedData.concepts[rootCode]; + if (concept) { + chapters.push({ + summary: concept.summary || concept.code, + cost: parseFloat(concept.price) || 0 + }); + } + }); + } + + return chapters.sort((a, b) => b.cost - a.cost).slice(0, 5); +} + +function renderCharts() { + const dist = calculateResourceDistribution(); + const topCaps = getTopChapters(); + + if (typeChartInstance) typeChartInstance.destroy(); + if (chaptersChartInstance) chaptersChartInstance.destroy(); + + const isDark = document.body.classList.contains('dark-theme'); + const labelColor = isDark ? '#e2e8f0' : '#1e293b'; + + const ctx1 = document.getElementById('resourceTypeChart').getContext('2d'); + typeChartInstance = new Chart(ctx1, { + type: 'doughnut', + data: { + labels: ['Mano de Obra (MO)', 'Maquinaria (MAQ)', 'Materiales (MAT)', 'Otros/Subcontratas (SUB)'], + datasets: [{ + data: [dist.MO, dist.MAQ, dist.MAT, dist.SUB], + backgroundColor: ['#ef4444', '#d97706', '#3b82f6', '#a855f7'], + borderWidth: 1 + }] + }, + options: { + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { + position: 'bottom', + labels: { color: labelColor } + } + } + } + }); + + const ctx2 = document.getElementById('chaptersCostChart').getContext('2d'); + chaptersChartInstance = new Chart(ctx2, { + type: 'bar', + data: { + labels: topCaps.map(c => c.summary.substring(0, 25) + (c.summary.length > 25 ? '...' : '')), + datasets: [{ + label: 'Coste en Euros (€)', + data: topCaps.map(c => c.cost), + backgroundColor: '#800020', + borderRadius: 4 + }] + }, + options: { + indexAxis: 'y', + responsive: true, + maintainAspectRatio: false, + plugins: { + legend: { display: false } + }, + scales: { + x: { ticks: { color: labelColor } }, + y: { ticks: { color: labelColor } } + } + } + }); +} + +// 5. Comparador: Estadísticas de Diferencias +function calculateCompareStats() { + if (!parsedData || !compareData) return; + + let modifiedCount = 0; + const totalMain = calculateTotalBudget(); + let totalCompare = 0; + + const roots = Array.isArray(parsedData.root_nodes) ? parsedData.root_nodes : Object.values(parsedData.root_nodes); + roots.forEach(code => { + const compConcept = compareData[code]; + if (compConcept) { + totalCompare += parseFloat(compConcept.price) || 0; + } + }); + + const diffTotal = totalMain - totalCompare; + const pctDiff = totalCompare === 0 ? 0 : (diffTotal / totalCompare) * 100; + + Object.keys(parsedData.concepts).forEach(code => { + const mainConcept = parsedData.concepts[code]; + const compConcept = compareData[code]; + if (mainConcept && compConcept) { + if (parseFloat(mainConcept.price) !== parseFloat(compConcept.price) || mainConcept.summary !== compConcept.summary) { + modifiedCount++; + } + } + }); + + const resultsDiv = document.getElementById('compareResults'); + if (resultsDiv) resultsDiv.style.display = 'block'; + + const diffValEl = document.getElementById('compareTotalDiff'); + if (diffValEl) { + const formattedDiff = diffTotal.toLocaleString('es-ES', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + ' €'; + const formattedPct = pctDiff.toLocaleString('es-ES', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + ' %'; + diffValEl.textContent = `${diffTotal >= 0 ? '+' : ''}${formattedDiff} (${diffTotal >= 0 ? '+' : ''}${formattedPct})`; + diffValEl.className = 'stat-value ' + (diffTotal >= 0 ? 'pec-total' : 'clear-compare-btn'); + } + + const modCountEl = document.getElementById('compareModifiedCount'); + if (modCountEl) modCountEl.textContent = modifiedCount; +} + +// 6. Filtros: Comprobación de visibilidad de nodos y expansión +function shouldShowNode(code) { + if (!parsedData) return true; + const concept = parsedData.concepts[code]; + if (!concept) return true; + + const isChapter = concept.code.endsWith('#') || concept.is_root; + if (isChapter) { + return hasVisibleChildren(code); + } + + // Filtro por Importe + const costFilterVal = document.getElementById('costFilter').value; + if (costFilterVal !== 'all') { + const limit = parseFloat(costFilterVal); + const price = parseFloat(concept.price) || 0; + const quantity = parseFloat(concept.quantity) || 1.0; + const cost = price * quantity; + if (cost <= limit) return false; + } + + // Filtro por Tipo de Recurso + const resourceFilterVal = document.getElementById('resourceFilter').value; + if (resourceFilterVal !== 'all') { + if (concept.decomposition && concept.decomposition.length > 0) { + const hasResourceType = concept.decomposition.some(item => { + if (resourceFilterVal === 'mo' && item.type === 1) return true; + if (resourceFilterVal === 'maq' && item.type === 2) return true; + if (resourceFilterVal === 'mat' && item.type === 3) return true; + if (resourceFilterVal === 'sub' && item.type === 4) return true; + return false; + }); + if (!hasResourceType) return false; + } else { + if (resourceFilterVal !== 'sub') return false; // Tratar sin descomposición como subcontrata + } + } + + return true; +} + +function hasVisibleChildren(code) { + const concept = parsedData.concepts[code]; + if (!concept) return false; + + const isChapter = concept.code.endsWith('#') || concept.is_root; + if (!isChapter) { + // Para nodos hoja (partidas), validamos el filtro en sí + const costFilterVal = document.getElementById('costFilter').value; + const resourceFilterVal = document.getElementById('resourceFilter').value; + if (costFilterVal === 'all' && resourceFilterVal === 'all') return true; + + const price = parseFloat(concept.price) || 0; + const quantity = parseFloat(concept.quantity) || 1.0; + const cost = price * quantity; + + if (costFilterVal !== 'all' && cost <= parseFloat(costFilterVal)) return false; + + if (resourceFilterVal !== 'all') { + if (concept.decomposition && concept.decomposition.length > 0) { + return concept.decomposition.some(item => { + if (resourceFilterVal === 'mo' && item.type === 1) return true; + if (resourceFilterVal === 'maq' && item.type === 2) return true; + if (resourceFilterVal === 'mat' && item.type === 3) return true; + if (resourceFilterVal === 'sub' && item.type === 4) return true; + return false; + }); + } else { + return resourceFilterVal === 'sub'; + } + } + return true; + } + + const children = getConceptDecomposition(concept); + + return children.some(child => hasVisibleChildren(child.code)); +} + +// 7. Enlazar Eventos de Nuevas Funcionalidades (Dropdown de Exportación) +const exportDropdown = document.getElementById('exportDropdown'); +if (exportDropdown) { + const toggleBtn = exportDropdown.querySelector('.dropdown-toggle'); + if (toggleBtn) { + toggleBtn.addEventListener('click', (e) => { + e.stopPropagation(); + exportDropdown.classList.toggle('show'); + }); + } +} + +// Cerrar dropdown al hacer click fuera +window.addEventListener('click', (e) => { + const expDrop = document.getElementById('exportDropdown'); + if (expDrop && !expDrop.contains(e.target)) { + expDrop.classList.remove('show'); + } +}); + +const exportPdfBtn = document.getElementById('exportPdfBtn'); +const exportExcelBtn = document.getElementById('exportExcelBtn'); + +if (exportPdfBtn) { + exportPdfBtn.addEventListener('click', () => { + const expDrop = document.getElementById('exportDropdown'); + if (expDrop) expDrop.classList.remove('show'); + exportToPdf(); + }); +} + +if (exportExcelBtn) { + exportExcelBtn.addEventListener('click', () => { + const expDrop = document.getElementById('exportDropdown'); + if (expDrop) expDrop.classList.remove('show'); + exportToExcel(); + }); +} + +// Dashboard modal toggling +const dashboardBtn = document.getElementById('dashboardBtn'); +const dashboardModal = document.getElementById('dashboardModal'); +const closeDashboardBtn = document.getElementById('closeDashboardBtn'); + +if (dashboardBtn && dashboardModal && closeDashboardBtn) { + dashboardBtn.addEventListener('click', () => { + dashboardModal.style.display = 'flex'; + setTimeout(renderCharts, 50); + }); + + closeDashboardBtn.addEventListener('click', () => { + dashboardModal.style.display = 'none'; + }); + + window.addEventListener('click', (e) => { + if (e.target === dashboardModal) { + dashboardModal.style.display = 'none'; + } + }); +} + +// Compare modal toggling and upload +const compareBtn = document.getElementById('compareBtn'); +const compareModal = document.getElementById('compareModal'); +const closeCompareBtn = document.getElementById('closeCompareBtn'); +const runCompareBtn = document.getElementById('runCompareBtn'); +const compareFileInput = document.getElementById('compareFileInput'); +const clearCompareBtn = document.getElementById('clearCompareBtn'); + +if (compareBtn && compareModal && closeCompareBtn) { + compareBtn.addEventListener('click', () => { + compareModal.style.display = 'flex'; + }); + + closeCompareBtn.addEventListener('click', () => { + compareModal.style.display = 'none'; + }); + + window.addEventListener('click', (e) => { + if (e.target === compareModal) { + compareModal.style.display = 'none'; + } + }); +} + +if (runCompareBtn && compareFileInput) { + runCompareBtn.addEventListener('click', async () => { + if (!compareFileInput.files.length) { + alert("Por favor selecciona un archivo .bc3 para comparar"); + return; + } + + const formData = new FormData(); + formData.append('bc3file', compareFileInput.files[0]); + + runCompareBtn.textContent = 'Comparando...'; + runCompareBtn.disabled = true; + + try { + const response = await fetch('upload.php', { + method: 'POST', + body: formData + }); + const result = await response.json(); + + if (result.success) { + compareData = result.data.concepts; + compareActive = true; + + calculateCompareStats(); + renderCurrentLevel(); + updateTotalBudgetDisplay(); + + compareModal.style.display = 'none'; + } else { + alert("Error al cargar el archivo de comparación: " + result.error); + } + } catch (err) { + console.error(err); + alert("Error de conexión con el servidor"); + } finally { + runCompareBtn.textContent = 'Cargar y Comparar'; + runCompareBtn.disabled = false; + } + }); +} + +if (clearCompareBtn) { + clearCompareBtn.addEventListener('click', () => { + compareActive = false; + compareData = null; + document.getElementById('compareResults').style.display = 'none'; + renderCurrentLevel(); + updateTotalBudgetDisplay(); + }); +} + +// Filtros avanzados y expansión +const expandAllBtn = document.getElementById('expandAllBtn'); +const collapseAllBtn = document.getElementById('collapseAllBtn'); +const costFilter = document.getElementById('costFilter'); +const resourceFilter = document.getElementById('resourceFilter'); + +if (expandAllBtn) { + expandAllBtn.addEventListener('click', () => { + if (!parsedData) return; + Object.keys(parsedData.concepts).forEach(code => { + if (code.endsWith('#')) { + expandedNodes.add(code); + } + }); + renderCurrentLevel(); + }); +} + +if (collapseAllBtn) { + collapseAllBtn.addEventListener('click', () => { + expandedNodes.clear(); + renderCurrentLevel(); + }); +} + +if (costFilter) { + costFilter.addEventListener('change', () => { + renderCurrentLevel(); + }); +} + +if (resourceFilter) { + resourceFilter.addEventListener('change', () => { + renderCurrentLevel(); + }); +} + +// Coeficientes globales (PEM vs PEC) +const toggleCoeffsBtn = document.getElementById('toggleCoeffsBtn'); +const coeffsPanel = document.getElementById('coeffsPanel'); +const applyCoeffsBtn = document.getElementById('applyCoeffsBtn'); + +if (toggleCoeffsBtn && coeffsPanel) { + toggleCoeffsBtn.addEventListener('click', () => { + if (coeffsPanel.style.display === 'none') { + coeffsPanel.style.display = 'block'; + } else { + coeffsPanel.style.display = 'none'; + } + }); +} + +if (applyCoeffsBtn) { + applyCoeffsBtn.addEventListener('click', () => { + const ggVal = parseFloat(document.getElementById('coeffGG').value) || 0; + const biVal = parseFloat(document.getElementById('coeffBI').value) || 0; + const bajaVal = parseFloat(document.getElementById('coeffBaja').value) || 0; + + globalCoeffs.gg = ggVal; + globalCoeffs.bi = biVal; + globalCoeffs.baja = bajaVal; + + updateTotalBudgetDisplay(); + coeffsPanel.style.display = 'none'; + }); +} + +/* ========================================================================== + Historial de Cambios: Deshacer (Ctrl+Z) y Rehacer (Ctrl+Y) + ========================================================================== */ + +function saveHistoryState() { + if (!parsedData) return; + + // Si el usuario hace un cambio nuevo estando en medio del historial, cortamos los estados futuros + if (historyIndex < stateHistory.length - 1) { + stateHistory = stateHistory.slice(0, historyIndex + 1); + } + + // Clonar el estado actual de parsedData + stateHistory.push(JSON.stringify(parsedData)); + + // Limitar el historial a los últimos 50 estados para evitar consumo excesivo de memoria + if (stateHistory.length > 50) { + stateHistory.shift(); + } + + historyIndex = stateHistory.length - 1; + updateUndoRedoButtonsState(); +} + +function undo() { + if (historyIndex > 0) { + historyIndex--; + parsedData = JSON.parse(stateHistory[historyIndex]); + + // Recalcular todo en cascada y repintar + recalculateAll(); + renderCurrentLevel(); + updateTotalBudgetDisplay(); + + // Si hay una partida activa en el panel de detalles, refrescarla + const detCodeEl = document.getElementById('detCode'); + if (detCodeEl && detCodeEl.textContent) { + const rawCode = Object.keys(parsedData.concepts).find(c => c.replace(/#+\s*$/, '') === detCodeEl.textContent); + if (rawCode) showDetails(rawCode); + } + + updateUndoRedoButtonsState(); + showNotification("Deshacer: Cambio revertido"); + } +} + +function redo() { + if (historyIndex < stateHistory.length - 1) { + historyIndex++; + parsedData = JSON.parse(stateHistory[historyIndex]); + + // Recalcular todo en cascada y repintar + recalculateAll(); + renderCurrentLevel(); + updateTotalBudgetDisplay(); + + // Si hay una partida activa en el panel de detalles, refrescarla + const detCodeEl = document.getElementById('detCode'); + if (detCodeEl && detCodeEl.textContent) { + const rawCode = Object.keys(parsedData.concepts).find(c => c.replace(/#+\s*$/, '') === detCodeEl.textContent); + if (rawCode) showDetails(rawCode); + } + + updateUndoRedoButtonsState(); + showNotification("Rehacer: Cambio restaurado"); + } +} + +function updateUndoRedoButtonsState() { + const undoBtn = document.getElementById('undoBtn'); + const redoBtn = document.getElementById('redoBtn'); + + if (undoBtn) { + undoBtn.disabled = (historyIndex <= 0); + } + if (redoBtn) { + redoBtn.disabled = (historyIndex >= stateHistory.length - 1); + } +} + +// Mostrar notificación en pantalla estilo Toast flotante +function showNotification(message) { + let container = document.getElementById('notificationContainer'); + if (!container) { + container = document.createElement('div'); + container.id = 'notificationContainer'; + container.style.position = 'fixed'; + container.style.bottom = '20px'; + container.style.right = '20px'; + container.style.zIndex = '9999'; + container.style.display = 'flex'; + container.style.flexDirection = 'column'; + container.style.gap = '10px'; + document.body.appendChild(container); + } + + const toast = document.createElement('div'); + toast.textContent = message; + toast.style.backgroundColor = 'var(--text-primary)'; + toast.style.color = 'var(--bg-color)'; + toast.style.padding = '10px 20px'; + toast.style.borderRadius = '6px'; + toast.style.boxShadow = '0 10px 15px -3px rgba(0, 0, 0, 0.2)'; + toast.style.fontSize = '0.85rem'; + toast.style.fontWeight = '500'; + toast.style.opacity = '0'; + toast.style.transform = 'translateY(10px)'; + toast.style.transition = 'all 0.2s ease-out'; + + container.appendChild(toast); + + setTimeout(() => { + toast.style.opacity = '1'; + toast.style.transform = 'translateY(0)'; + }, 10); + + setTimeout(() => { + toast.style.opacity = '0'; + toast.style.transform = 'translateY(10px)'; + setTimeout(() => { + toast.remove(); + }, 200); + }, 2000); +} + +// Atajos de teclado (Ctrl+Z y Ctrl+Y) +window.addEventListener('keydown', (e) => { + const isCtrl = e.ctrlKey || e.metaKey; + if (isCtrl) { + if (e.key.toLowerCase() === 'z') { + e.preventDefault(); + undo(); + } else if (e.key.toLowerCase() === 'y') { + e.preventDefault(); + redo(); + } + } +}); + +// Enlazar clics de botones +const undoBtn = document.getElementById('undoBtn'); +const redoBtn = document.getElementById('redoBtn'); + +if (undoBtn) { + undoBtn.addEventListener('click', undo); +} +if (redoBtn) { + redoBtn.addEventListener('click', redo); +} + diff --git a/chart.min.js b/chart.min.js new file mode 100644 index 0000000..008464f --- /dev/null +++ b/chart.min.js @@ -0,0 +1,14 @@ +/*! + * Chart.js v4.5.1 + * https://www.chartjs.org + * (c) 2025 Chart.js Contributors + * Released under the MIT License + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chart=e()}(this,(function(){"use strict";var t=Object.freeze({__proto__:null,get Colors(){return Jo},get Decimation(){return ta},get Filler(){return ba},get Legend(){return Ma},get SubTitle(){return Pa},get Title(){return ka},get Tooltip(){return Na}});function e(){}const i=(()=>{let t=0;return()=>t++})();function s(t){return null==t}function n(t){if(Array.isArray&&Array.isArray(t))return!0;const e=Object.prototype.toString.call(t);return"[object"===e.slice(0,7)&&"Array]"===e.slice(-6)}function o(t){return null!==t&&"[object Object]"===Object.prototype.toString.call(t)}function a(t){return("number"==typeof t||t instanceof Number)&&isFinite(+t)}function r(t,e){return a(t)?t:e}function l(t,e){return void 0===t?e:t}const h=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100:+t/e,c=(t,e)=>"string"==typeof t&&t.endsWith("%")?parseFloat(t)/100*e:+t;function d(t,e,i){if(t&&"function"==typeof t.call)return t.apply(i,e)}function u(t,e,i,s){let a,r,l;if(n(t))if(r=t.length,s)for(a=r-1;a>=0;a--)e.call(i,t[a],a);else for(a=0;at,x:t=>t.x,y:t=>t.y};function v(t){const e=t.split("."),i=[];let s="";for(const t of e)s+=t,s.endsWith("\\")?s=s.slice(0,-1)+".":(i.push(s),s="");return i}function M(t,e){const i=y[e]||(y[e]=function(t){const e=v(t);return t=>{for(const i of e){if(""===i)break;t=t&&t[i]}return t}}(e));return i(t)}function w(t){return t.charAt(0).toUpperCase()+t.slice(1)}const k=t=>void 0!==t,S=t=>"function"==typeof t,P=(t,e)=>{if(t.size!==e.size)return!1;for(const i of t)if(!e.has(i))return!1;return!0};function D(t){return"mouseup"===t.type||"click"===t.type||"contextmenu"===t.type}const C=Math.PI,O=2*C,A=O+C,T=Number.POSITIVE_INFINITY,L=C/180,E=C/2,R=C/4,I=2*C/3,z=Math.log10,F=Math.sign;function V(t,e,i){return Math.abs(t-e)t-e)).pop(),e}function N(t){return!function(t){return"symbol"==typeof t||"object"==typeof t&&null!==t&&!(Symbol.toPrimitive in t||"toString"in t||"valueOf"in t)}(t)&&!isNaN(parseFloat(t))&&isFinite(t)}function H(t,e){const i=Math.round(t);return i-e<=t&&i+e>=t}function j(t,e,i){let s,n,o;for(s=0,n=t.length;sl&&h=Math.min(e,i)-s&&t<=Math.max(e,i)+s}function et(t,e,i){i=i||(i=>t[i]1;)s=o+n>>1,i(s)?o=s:n=s;return{lo:o,hi:n}}const it=(t,e,i,s)=>et(t,i,s?s=>{const n=t[s][e];return nt[s][e]et(t,i,(s=>t[s][e]>=i));function nt(t,e,i){let s=0,n=t.length;for(;ss&&t[n-1]>i;)n--;return s>0||n{const i="_onData"+w(e),s=t[e];Object.defineProperty(t,e,{configurable:!0,enumerable:!1,value(...e){const n=s.apply(this,e);return t._chartjs.listeners.forEach((t=>{"function"==typeof t[i]&&t[i](...e)})),n}})})))}function rt(t,e){const i=t._chartjs;if(!i)return;const s=i.listeners,n=s.indexOf(e);-1!==n&&s.splice(n,1),s.length>0||(ot.forEach((e=>{delete t[e]})),delete t._chartjs)}function lt(t){const e=new Set(t);return e.size===t.length?t:Array.from(e)}const ht="undefined"==typeof window?function(t){return t()}:window.requestAnimationFrame;function ct(t,e){let i=[],s=!1;return function(...n){i=n,s||(s=!0,ht.call(window,(()=>{s=!1,t.apply(e,i)})))}}function dt(t,e){let i;return function(...s){return e?(clearTimeout(i),i=setTimeout(t,e,s)):t.apply(this,s),e}}const ut=t=>"start"===t?"left":"end"===t?"right":"center",ft=(t,e,i)=>"start"===t?e:"end"===t?i:(e+i)/2,gt=(t,e,i,s)=>t===(s?"left":"right")?i:"center"===t?(e+i)/2:e;function pt(t,e,i){const n=e.length;let o=0,a=n;if(t._sorted){const{iScale:r,vScale:l,_parsed:h}=t,c=t.dataset&&t.dataset.options?t.dataset.options.spanGaps:null,d=r.axis,{min:u,max:f,minDefined:g,maxDefined:p}=r.getUserBounds();if(g){if(o=Math.min(it(h,d,u).lo,i?n:it(e,d,r.getPixelForValue(u)).lo),c){const t=h.slice(0,o+1).reverse().findIndex((t=>!s(t[l.axis])));o-=Math.max(0,t)}o=Z(o,0,n-1)}if(p){let t=Math.max(it(h,r.axis,f,!0).hi+1,i?0:it(e,d,r.getPixelForValue(f),!0).hi+1);if(c){const e=h.slice(t-1).findIndex((t=>!s(t[l.axis])));t+=Math.max(0,e)}a=Z(t,o,n)-o}else a=n-o}return{start:o,count:a}}function mt(t){const{xScale:e,yScale:i,_scaleRanges:s}=t,n={xmin:e.min,xmax:e.max,ymin:i.min,ymax:i.max};if(!s)return t._scaleRanges=n,!0;const o=s.xmin!==e.min||s.xmax!==e.max||s.ymin!==i.min||s.ymax!==i.max;return Object.assign(s,n),o}class xt{constructor(){this._request=null,this._charts=new Map,this._running=!1,this._lastDate=void 0}_notify(t,e,i,s){const n=e.listeners[s],o=e.duration;n.forEach((s=>s({chart:t,initial:e.initial,numSteps:o,currentStep:Math.min(i-e.start,o)})))}_refresh(){this._request||(this._running=!0,this._request=ht.call(window,(()=>{this._update(),this._request=null,this._running&&this._refresh()})))}_update(t=Date.now()){let e=0;this._charts.forEach(((i,s)=>{if(!i.running||!i.items.length)return;const n=i.items;let o,a=n.length-1,r=!1;for(;a>=0;--a)o=n[a],o._active?(o._total>i.duration&&(i.duration=o._total),o.tick(t),r=!0):(n[a]=n[n.length-1],n.pop());r&&(s.draw(),this._notify(s,i,t,"progress")),n.length||(i.running=!1,this._notify(s,i,t,"complete"),i.initial=!1),e+=n.length})),this._lastDate=t,0===e&&(this._running=!1)}_getAnims(t){const e=this._charts;let i=e.get(t);return i||(i={running:!1,initial:!0,items:[],listeners:{complete:[],progress:[]}},e.set(t,i)),i}listen(t,e,i){this._getAnims(t).listeners[e].push(i)}add(t,e){e&&e.length&&this._getAnims(t).items.push(...e)}has(t){return this._getAnims(t).items.length>0}start(t){const e=this._charts.get(t);e&&(e.running=!0,e.start=Date.now(),e.duration=e.items.reduce(((t,e)=>Math.max(t,e._duration)),0),this._refresh())}running(t){if(!this._running)return!1;const e=this._charts.get(t);return!!(e&&e.running&&e.items.length)}stop(t){const e=this._charts.get(t);if(!e||!e.items.length)return;const i=e.items;let s=i.length-1;for(;s>=0;--s)i[s].cancel();e.items=[],this._notify(t,e,Date.now(),"complete")}remove(t){return this._charts.delete(t)}}var bt=new xt; +/*! + * @kurkle/color v0.3.2 + * https://github.com/kurkle/color#readme + * (c) 2023 Jukka Kurkela + * Released under the MIT License + */function _t(t){return t+.5|0}const yt=(t,e,i)=>Math.max(Math.min(t,i),e);function vt(t){return yt(_t(2.55*t),0,255)}function Mt(t){return yt(_t(255*t),0,255)}function wt(t){return yt(_t(t/2.55)/100,0,1)}function kt(t){return yt(_t(100*t),0,100)}const St={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},Pt=[..."0123456789ABCDEF"],Dt=t=>Pt[15&t],Ct=t=>Pt[(240&t)>>4]+Pt[15&t],Ot=t=>(240&t)>>4==(15&t);function At(t){var e=(t=>Ot(t.r)&&Ot(t.g)&&Ot(t.b)&&Ot(t.a))(t)?Dt:Ct;return t?"#"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):"")(t.a,e):void 0}const Tt=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function Lt(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function Et(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function Rt(t,e,i){const s=Lt(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function It(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e>16&255,o>>8&255,255&o]}return t}(),Ht.transparent=[0,0,0,0]);const e=Ht[t.toLowerCase()];return e&&{r:e[0],g:e[1],b:e[2],a:4===e.length?e[3]:255}}const $t=/^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/;const Yt=t=>t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055,Ut=t=>t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4);function Xt(t,e,i){if(t){let s=It(t);s[e]=Math.max(0,Math.min(s[e]+s[e]*i,0===e?360:1)),s=Ft(s),t.r=s[0],t.g=s[1],t.b=s[2]}}function qt(t,e){return t?Object.assign(e||{},t):t}function Kt(t){var e={r:0,g:0,b:0,a:255};return Array.isArray(t)?t.length>=3&&(e={r:t[0],g:t[1],b:t[2],a:255},t.length>3&&(e.a=Mt(t[3]))):(e=qt(t,{r:0,g:0,b:0,a:1})).a=Mt(e.a),e}function Gt(t){return"r"===t.charAt(0)?function(t){const e=$t.exec(t);let i,s,n,o=255;if(e){if(e[7]!==i){const t=+e[7];o=e[8]?vt(t):yt(255*t,0,255)}return i=+e[1],s=+e[3],n=+e[5],i=255&(e[2]?vt(i):yt(i,0,255)),s=255&(e[4]?vt(s):yt(s,0,255)),n=255&(e[6]?vt(n):yt(n,0,255)),{r:i,g:s,b:n,a:o}}}(t):Bt(t)}class Jt{constructor(t){if(t instanceof Jt)return t;const e=typeof t;let i;var s,n,o;"object"===e?i=Kt(t):"string"===e&&(o=(s=t).length,"#"===s[0]&&(4===o||5===o?n={r:255&17*St[s[1]],g:255&17*St[s[2]],b:255&17*St[s[3]],a:5===o?17*St[s[4]]:255}:7!==o&&9!==o||(n={r:St[s[1]]<<4|St[s[2]],g:St[s[3]]<<4|St[s[4]],b:St[s[5]]<<4|St[s[6]],a:9===o?St[s[7]]<<4|St[s[8]]:255})),i=n||jt(t)||Gt(t)),this._rgb=i,this._valid=!!i}get valid(){return this._valid}get rgb(){var t=qt(this._rgb);return t&&(t.a=wt(t.a)),t}set rgb(t){this._rgb=Kt(t)}rgbString(){return this._valid?(t=this._rgb)&&(t.a<255?`rgba(${t.r}, ${t.g}, ${t.b}, ${wt(t.a)})`:`rgb(${t.r}, ${t.g}, ${t.b})`):void 0;var t}hexString(){return this._valid?At(this._rgb):void 0}hslString(){return this._valid?function(t){if(!t)return;const e=It(t),i=e[0],s=kt(e[1]),n=kt(e[2]);return t.a<255?`hsla(${i}, ${s}%, ${n}%, ${wt(t.a)})`:`hsl(${i}, ${s}%, ${n}%)`}(this._rgb):void 0}mix(t,e){if(t){const i=this.rgb,s=t.rgb;let n;const o=e===n?.5:e,a=2*o-1,r=i.a-s.a,l=((a*r==-1?a:(a+r)/(1+a*r))+1)/2;n=1-l,i.r=255&l*i.r+n*s.r+.5,i.g=255&l*i.g+n*s.g+.5,i.b=255&l*i.b+n*s.b+.5,i.a=o*i.a+(1-o)*s.a,this.rgb=i}return this}interpolate(t,e){return t&&(this._rgb=function(t,e,i){const s=Ut(wt(t.r)),n=Ut(wt(t.g)),o=Ut(wt(t.b));return{r:Mt(Yt(s+i*(Ut(wt(e.r))-s))),g:Mt(Yt(n+i*(Ut(wt(e.g))-n))),b:Mt(Yt(o+i*(Ut(wt(e.b))-o))),a:t.a+i*(e.a-t.a)}}(this._rgb,t._rgb,e)),this}clone(){return new Jt(this.rgb)}alpha(t){return this._rgb.a=Mt(t),this}clearer(t){return this._rgb.a*=1-t,this}greyscale(){const t=this._rgb,e=_t(.3*t.r+.59*t.g+.11*t.b);return t.r=t.g=t.b=e,this}opaquer(t){return this._rgb.a*=1+t,this}negate(){const t=this._rgb;return t.r=255-t.r,t.g=255-t.g,t.b=255-t.b,this}lighten(t){return Xt(this._rgb,2,t),this}darken(t){return Xt(this._rgb,2,-t),this}saturate(t){return Xt(this._rgb,1,t),this}desaturate(t){return Xt(this._rgb,1,-t),this}rotate(t){return function(t,e){var i=It(t);i[0]=Vt(i[0]+e),i=Ft(i),t.r=i[0],t.g=i[1],t.b=i[2]}(this._rgb,t),this}}function Zt(t){if(t&&"object"==typeof t){const e=t.toString();return"[object CanvasPattern]"===e||"[object CanvasGradient]"===e}return!1}function Qt(t){return Zt(t)?t:new Jt(t)}function te(t){return Zt(t)?t:new Jt(t).saturate(.5).darken(.1).hexString()}const ee=["x","y","borderWidth","radius","tension"],ie=["color","borderColor","backgroundColor"];const se=new Map;function ne(t,e,i){return function(t,e){e=e||{};const i=t+JSON.stringify(e);let s=se.get(i);return s||(s=new Intl.NumberFormat(t,e),se.set(i,s)),s}(e,i).format(t)}const oe={values:t=>n(t)?t:""+t,numeric(t,e,i){if(0===t)return"0";const s=this.chart.options.locale;let n,o=t;if(i.length>1){const e=Math.max(Math.abs(i[0].value),Math.abs(i[i.length-1].value));(e<1e-4||e>1e15)&&(n="scientific"),o=function(t,e){let i=e.length>3?e[2].value-e[1].value:e[1].value-e[0].value;Math.abs(i)>=1&&t!==Math.floor(t)&&(i=t-Math.floor(t));return i}(t,i)}const a=z(Math.abs(o)),r=isNaN(a)?1:Math.max(Math.min(-1*Math.floor(a),20),0),l={notation:n,minimumFractionDigits:r,maximumFractionDigits:r};return Object.assign(l,this.options.ticks.format),ne(t,s,l)},logarithmic(t,e,i){if(0===t)return"0";const s=i[e].significand||t/Math.pow(10,Math.floor(z(t)));return[1,2,3,5,10,15].includes(s)||e>.8*i.length?oe.numeric.call(this,t,e,i):""}};var ae={formatters:oe};const re=Object.create(null),le=Object.create(null);function he(t,e){if(!e)return t;const i=e.split(".");for(let e=0,s=i.length;et.chart.platform.getDevicePixelRatio(),this.elements={},this.events=["mousemove","mouseout","click","touchstart","touchmove"],this.font={family:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",size:12,style:"normal",lineHeight:1.2,weight:null},this.hover={},this.hoverBackgroundColor=(t,e)=>te(e.backgroundColor),this.hoverBorderColor=(t,e)=>te(e.borderColor),this.hoverColor=(t,e)=>te(e.color),this.indexAxis="x",this.interaction={mode:"nearest",intersect:!0,includeInvisible:!1},this.maintainAspectRatio=!0,this.onHover=null,this.onClick=null,this.parsing=!0,this.plugins={},this.responsive=!0,this.scale=void 0,this.scales={},this.showLine=!0,this.drawActiveElementsOnTop=!0,this.describe(t),this.apply(e)}set(t,e){return ce(this,t,e)}get(t){return he(this,t)}describe(t,e){return ce(le,t,e)}override(t,e){return ce(re,t,e)}route(t,e,i,s){const n=he(this,t),a=he(this,i),r="_"+e;Object.defineProperties(n,{[r]:{value:n[e],writable:!0},[e]:{enumerable:!0,get(){const t=this[r],e=a[s];return o(t)?Object.assign({},e,t):l(t,e)},set(t){this[r]=t}}})}apply(t){t.forEach((t=>t(this)))}}var ue=new de({_scriptable:t=>!t.startsWith("on"),_indexable:t=>"events"!==t,hover:{_fallback:"interaction"},interaction:{_scriptable:!1,_indexable:!1}},[function(t){t.set("animation",{delay:void 0,duration:1e3,easing:"easeOutQuart",fn:void 0,from:void 0,loop:void 0,to:void 0,type:void 0}),t.describe("animation",{_fallback:!1,_indexable:!1,_scriptable:t=>"onProgress"!==t&&"onComplete"!==t&&"fn"!==t}),t.set("animations",{colors:{type:"color",properties:ie},numbers:{type:"number",properties:ee}}),t.describe("animations",{_fallback:"animation"}),t.set("transitions",{active:{animation:{duration:400}},resize:{animation:{duration:0}},show:{animations:{colors:{from:"transparent"},visible:{type:"boolean",duration:0}}},hide:{animations:{colors:{to:"transparent"},visible:{type:"boolean",easing:"linear",fn:t=>0|t}}}})},function(t){t.set("layout",{autoPadding:!0,padding:{top:0,right:0,bottom:0,left:0}})},function(t){t.set("scale",{display:!0,offset:!1,reverse:!1,beginAtZero:!1,bounds:"ticks",clip:!0,grace:0,grid:{display:!0,lineWidth:1,drawOnChartArea:!0,drawTicks:!0,tickLength:8,tickWidth:(t,e)=>e.lineWidth,tickColor:(t,e)=>e.color,offset:!1},border:{display:!0,dash:[],dashOffset:0,width:1},title:{display:!1,text:"",padding:{top:4,bottom:4}},ticks:{minRotation:0,maxRotation:50,mirror:!1,textStrokeWidth:0,textStrokeColor:"",padding:3,display:!0,autoSkip:!0,autoSkipPadding:3,labelOffset:0,callback:ae.formatters.values,minor:{},major:{},align:"center",crossAlign:"near",showLabelBackdrop:!1,backdropColor:"rgba(255, 255, 255, 0.75)",backdropPadding:2}}),t.route("scale.ticks","color","","color"),t.route("scale.grid","color","","borderColor"),t.route("scale.border","color","","borderColor"),t.route("scale.title","color","","color"),t.describe("scale",{_fallback:!1,_scriptable:t=>!t.startsWith("before")&&!t.startsWith("after")&&"callback"!==t&&"parser"!==t,_indexable:t=>"borderDash"!==t&&"tickBorderDash"!==t&&"dash"!==t}),t.describe("scales",{_fallback:"scale"}),t.describe("scale.ticks",{_scriptable:t=>"backdropPadding"!==t&&"callback"!==t,_indexable:t=>"backdropPadding"!==t})}]);function fe(){return"undefined"!=typeof window&&"undefined"!=typeof document}function ge(t){let e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e}function pe(t,e,i){let s;return"string"==typeof t?(s=parseInt(t,10),-1!==t.indexOf("%")&&(s=s/100*e.parentNode[i])):s=t,s}const me=t=>t.ownerDocument.defaultView.getComputedStyle(t,null);function xe(t,e){return me(t).getPropertyValue(e)}const be=["top","right","bottom","left"];function _e(t,e,i){const s={};i=i?"-"+i:"";for(let n=0;n<4;n++){const o=be[n];s[o]=parseFloat(t[e+"-"+o+i])||0}return s.width=s.left+s.right,s.height=s.top+s.bottom,s}const ye=(t,e,i)=>(t>0||e>0)&&(!i||!i.shadowRoot);function ve(t,e){if("native"in t)return t;const{canvas:i,currentDevicePixelRatio:s}=e,n=me(i),o="border-box"===n.boxSizing,a=_e(n,"padding"),r=_e(n,"border","width"),{x:l,y:h,box:c}=function(t,e){const i=t.touches,s=i&&i.length?i[0]:t,{offsetX:n,offsetY:o}=s;let a,r,l=!1;if(ye(n,o,t.target))a=n,r=o;else{const t=e.getBoundingClientRect();a=s.clientX-t.left,r=s.clientY-t.top,l=!0}return{x:a,y:r,box:l}}(t,i),d=a.left+(c&&r.left),u=a.top+(c&&r.top);let{width:f,height:g}=e;return o&&(f-=a.width+r.width,g-=a.height+r.height),{x:Math.round((l-d)/f*i.width/s),y:Math.round((h-u)/g*i.height/s)}}const Me=t=>Math.round(10*t)/10;function we(t,e,i,s){const n=me(t),o=_e(n,"margin"),a=pe(n.maxWidth,t,"clientWidth")||T,r=pe(n.maxHeight,t,"clientHeight")||T,l=function(t,e,i){let s,n;if(void 0===e||void 0===i){const o=t&&ge(t);if(o){const t=o.getBoundingClientRect(),a=me(o),r=_e(a,"border","width"),l=_e(a,"padding");e=t.width-l.width-r.width,i=t.height-l.height-r.height,s=pe(a.maxWidth,o,"clientWidth"),n=pe(a.maxHeight,o,"clientHeight")}else e=t.clientWidth,i=t.clientHeight}return{width:e,height:i,maxWidth:s||T,maxHeight:n||T}}(t,e,i);let{width:h,height:c}=l;if("content-box"===n.boxSizing){const t=_e(n,"border","width"),e=_e(n,"padding");h-=e.width+t.width,c-=e.height+t.height}h=Math.max(0,h-o.width),c=Math.max(0,s?h/s:c-o.height),h=Me(Math.min(h,a,l.maxWidth)),c=Me(Math.min(c,r,l.maxHeight)),h&&!c&&(c=Me(h/2));return(void 0!==e||void 0!==i)&&s&&l.height&&c>l.height&&(c=l.height,h=Me(Math.floor(c*s))),{width:h,height:c}}function ke(t,e,i){const s=e||1,n=Me(t.height*s),o=Me(t.width*s);t.height=Me(t.height),t.width=Me(t.width);const a=t.canvas;return a.style&&(i||!a.style.height&&!a.style.width)&&(a.style.height=`${t.height}px`,a.style.width=`${t.width}px`),(t.currentDevicePixelRatio!==s||a.height!==n||a.width!==o)&&(t.currentDevicePixelRatio=s,a.height=n,a.width=o,t.ctx.setTransform(s,0,0,s,0,0),!0)}const Se=function(){let t=!1;try{const e={get passive(){return t=!0,!1}};fe()&&(window.addEventListener("test",null,e),window.removeEventListener("test",null,e))}catch(t){}return t}();function Pe(t,e){const i=xe(t,e),s=i&&i.match(/^(\d+)(\.\d+)?px$/);return s?+s[1]:void 0}function De(t){return!t||s(t.size)||s(t.family)?null:(t.style?t.style+" ":"")+(t.weight?t.weight+" ":"")+t.size+"px "+t.family}function Ce(t,e,i,s,n){let o=e[n];return o||(o=e[n]=t.measureText(n).width,i.push(n)),o>s&&(s=o),s}function Oe(t,e,i,s){let o=(s=s||{}).data=s.data||{},a=s.garbageCollect=s.garbageCollect||[];s.font!==e&&(o=s.data={},a=s.garbageCollect=[],s.font=e),t.save(),t.font=e;let r=0;const l=i.length;let h,c,d,u,f;for(h=0;hi.length){for(h=0;h0&&t.stroke()}}function Re(t,e,i){return i=i||.5,!e||t&&t.x>e.left-i&&t.xe.top-i&&t.y0&&""!==r.strokeColor;let c,d;for(t.save(),t.font=a.string,function(t,e){e.translation&&t.translate(e.translation[0],e.translation[1]),s(e.rotation)||t.rotate(e.rotation),e.color&&(t.fillStyle=e.color),e.textAlign&&(t.textAlign=e.textAlign),e.textBaseline&&(t.textBaseline=e.textBaseline)}(t,r),c=0;ct[0])){const o=i||t;void 0===s&&(s=ti("_fallback",t));const a={[Symbol.toStringTag]:"Object",_cacheable:!0,_scopes:t,_rootScopes:o,_fallback:s,_getTarget:n,override:i=>je([i,...t],e,o,s)};return new Proxy(a,{deleteProperty:(e,i)=>(delete e[i],delete e._keys,delete t[0][i],!0),get:(i,s)=>qe(i,s,(()=>function(t,e,i,s){let n;for(const o of e)if(n=ti(Ue(o,t),i),void 0!==n)return Xe(t,n)?Ze(i,s,t,n):n}(s,e,t,i))),getOwnPropertyDescriptor:(t,e)=>Reflect.getOwnPropertyDescriptor(t._scopes[0],e),getPrototypeOf:()=>Reflect.getPrototypeOf(t[0]),has:(t,e)=>ei(t).includes(e),ownKeys:t=>ei(t),set(t,e,i){const s=t._storage||(t._storage=n());return t[e]=s[e]=i,delete t._keys,!0}})}function $e(t,e,i,s){const a={_cacheable:!1,_proxy:t,_context:e,_subProxy:i,_stack:new Set,_descriptors:Ye(t,s),setContext:e=>$e(t,e,i,s),override:n=>$e(t.override(n),e,i,s)};return new Proxy(a,{deleteProperty:(e,i)=>(delete e[i],delete t[i],!0),get:(t,e,i)=>qe(t,e,(()=>function(t,e,i){const{_proxy:s,_context:a,_subProxy:r,_descriptors:l}=t;let h=s[e];S(h)&&l.isScriptable(e)&&(h=function(t,e,i,s){const{_proxy:n,_context:o,_subProxy:a,_stack:r}=i;if(r.has(t))throw new Error("Recursion detected: "+Array.from(r).join("->")+"->"+t);r.add(t);let l=e(o,a||s);r.delete(t),Xe(t,l)&&(l=Ze(n._scopes,n,t,l));return l}(e,h,t,i));n(h)&&h.length&&(h=function(t,e,i,s){const{_proxy:n,_context:a,_subProxy:r,_descriptors:l}=i;if(void 0!==a.index&&s(t))return e[a.index%e.length];if(o(e[0])){const i=e,s=n._scopes.filter((t=>t!==i));e=[];for(const o of i){const i=Ze(s,n,t,o);e.push($e(i,a,r&&r[t],l))}}return e}(e,h,t,l.isIndexable));Xe(e,h)&&(h=$e(h,a,r&&r[e],l));return h}(t,e,i))),getOwnPropertyDescriptor:(e,i)=>e._descriptors.allKeys?Reflect.has(t,i)?{enumerable:!0,configurable:!0}:void 0:Reflect.getOwnPropertyDescriptor(t,i),getPrototypeOf:()=>Reflect.getPrototypeOf(t),has:(e,i)=>Reflect.has(t,i),ownKeys:()=>Reflect.ownKeys(t),set:(e,i,s)=>(t[i]=s,delete e[i],!0)})}function Ye(t,e={scriptable:!0,indexable:!0}){const{_scriptable:i=e.scriptable,_indexable:s=e.indexable,_allKeys:n=e.allKeys}=t;return{allKeys:n,scriptable:i,indexable:s,isScriptable:S(i)?i:()=>i,isIndexable:S(s)?s:()=>s}}const Ue=(t,e)=>t?t+w(e):e,Xe=(t,e)=>o(e)&&"adapters"!==t&&(null===Object.getPrototypeOf(e)||e.constructor===Object);function qe(t,e,i){if(Object.prototype.hasOwnProperty.call(t,e)||"constructor"===e)return t[e];const s=i();return t[e]=s,s}function Ke(t,e,i){return S(t)?t(e,i):t}const Ge=(t,e)=>!0===t?e:"string"==typeof t?M(e,t):void 0;function Je(t,e,i,s,n){for(const o of e){const e=Ge(i,o);if(e){t.add(e);const o=Ke(e._fallback,i,n);if(void 0!==o&&o!==i&&o!==s)return o}else if(!1===e&&void 0!==s&&i!==s)return null}return!1}function Ze(t,e,i,s){const a=e._rootScopes,r=Ke(e._fallback,i,s),l=[...t,...a],h=new Set;h.add(s);let c=Qe(h,l,i,r||i,s);return null!==c&&((void 0===r||r===i||(c=Qe(h,l,r,c,s),null!==c))&&je(Array.from(h),[""],a,r,(()=>function(t,e,i){const s=t._getTarget();e in s||(s[e]={});const a=s[e];if(n(a)&&o(i))return i;return a||{}}(e,i,s))))}function Qe(t,e,i,s,n){for(;i;)i=Je(t,e,i,s,n);return i}function ti(t,e){for(const i of e){if(!i)continue;const e=i[t];if(void 0!==e)return e}}function ei(t){let e=t._keys;return e||(e=t._keys=function(t){const e=new Set;for(const i of t)for(const t of Object.keys(i).filter((t=>!t.startsWith("_"))))e.add(t);return Array.from(e)}(t._scopes)),e}function ii(t,e,i,s){const{iScale:n}=t,{key:o="r"}=this._parsing,a=new Array(s);let r,l,h,c;for(r=0,l=s;re"x"===t?"y":"x";function ai(t,e,i,s){const n=t.skip?e:t,o=e,a=i.skip?e:i,r=q(o,n),l=q(a,o);let h=r/(r+l),c=l/(r+l);h=isNaN(h)?0:h,c=isNaN(c)?0:c;const d=s*h,u=s*c;return{previous:{x:o.x-d*(a.x-n.x),y:o.y-d*(a.y-n.y)},next:{x:o.x+u*(a.x-n.x),y:o.y+u*(a.y-n.y)}}}function ri(t,e="x"){const i=oi(e),s=t.length,n=Array(s).fill(0),o=Array(s);let a,r,l,h=ni(t,0);for(a=0;a!t.skip))),"monotone"===e.cubicInterpolationMode)ri(t,n);else{let i=s?t[t.length-1]:t[0];for(o=0,a=t.length;o0===t||1===t,di=(t,e,i)=>-Math.pow(2,10*(t-=1))*Math.sin((t-e)*O/i),ui=(t,e,i)=>Math.pow(2,-10*t)*Math.sin((t-e)*O/i)+1,fi={linear:t=>t,easeInQuad:t=>t*t,easeOutQuad:t=>-t*(t-2),easeInOutQuad:t=>(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1),easeInCubic:t=>t*t*t,easeOutCubic:t=>(t-=1)*t*t+1,easeInOutCubic:t=>(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2),easeInQuart:t=>t*t*t*t,easeOutQuart:t=>-((t-=1)*t*t*t-1),easeInOutQuart:t=>(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2),easeInQuint:t=>t*t*t*t*t,easeOutQuint:t=>(t-=1)*t*t*t*t+1,easeInOutQuint:t=>(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2),easeInSine:t=>1-Math.cos(t*E),easeOutSine:t=>Math.sin(t*E),easeInOutSine:t=>-.5*(Math.cos(C*t)-1),easeInExpo:t=>0===t?0:Math.pow(2,10*(t-1)),easeOutExpo:t=>1===t?1:1-Math.pow(2,-10*t),easeInOutExpo:t=>ci(t)?t:t<.5?.5*Math.pow(2,10*(2*t-1)):.5*(2-Math.pow(2,-10*(2*t-1))),easeInCirc:t=>t>=1?t:-(Math.sqrt(1-t*t)-1),easeOutCirc:t=>Math.sqrt(1-(t-=1)*t),easeInOutCirc:t=>(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1),easeInElastic:t=>ci(t)?t:di(t,.075,.3),easeOutElastic:t=>ci(t)?t:ui(t,.075,.3),easeInOutElastic(t){const e=.1125;return ci(t)?t:t<.5?.5*di(2*t,e,.45):.5+.5*ui(2*t-1,e,.45)},easeInBack(t){const e=1.70158;return t*t*((e+1)*t-e)},easeOutBack(t){const e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack(t){let e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:t=>1-fi.easeOutBounce(1-t),easeOutBounce(t){const e=7.5625,i=2.75;return t<1/i?e*t*t:t<2/i?e*(t-=1.5/i)*t+.75:t<2.5/i?e*(t-=2.25/i)*t+.9375:e*(t-=2.625/i)*t+.984375},easeInOutBounce:t=>t<.5?.5*fi.easeInBounce(2*t):.5*fi.easeOutBounce(2*t-1)+.5};function gi(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:t.y+i*(e.y-t.y)}}function pi(t,e,i,s){return{x:t.x+i*(e.x-t.x),y:"middle"===s?i<.5?t.y:e.y:"after"===s?i<1?t.y:e.y:i>0?e.y:t.y}}function mi(t,e,i,s){const n={x:t.cp2x,y:t.cp2y},o={x:e.cp1x,y:e.cp1y},a=gi(t,n,i),r=gi(n,o,i),l=gi(o,e,i),h=gi(a,r,i),c=gi(r,l,i);return gi(h,c,i)}const xi=/^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/,bi=/^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/;function _i(t,e){const i=(""+t).match(xi);if(!i||"normal"===i[1])return 1.2*e;switch(t=+i[2],i[3]){case"px":return t;case"%":t/=100}return e*t}const yi=t=>+t||0;function vi(t,e){const i={},s=o(e),n=s?Object.keys(e):e,a=o(t)?s?i=>l(t[i],t[e[i]]):e=>t[e]:()=>t;for(const t of n)i[t]=yi(a(t));return i}function Mi(t){return vi(t,{top:"y",right:"x",bottom:"y",left:"x"})}function wi(t){return vi(t,["topLeft","topRight","bottomLeft","bottomRight"])}function ki(t){const e=Mi(t);return e.width=e.left+e.right,e.height=e.top+e.bottom,e}function Si(t,e){t=t||{},e=e||ue.font;let i=l(t.size,e.size);"string"==typeof i&&(i=parseInt(i,10));let s=l(t.style,e.style);s&&!(""+s).match(bi)&&(console.warn('Invalid font style specified: "'+s+'"'),s=void 0);const n={family:l(t.family,e.family),lineHeight:_i(l(t.lineHeight,e.lineHeight),i),size:i,style:s,weight:l(t.weight,e.weight),string:""};return n.string=De(n),n}function Pi(t,e,i,s){let o,a,r,l=!0;for(o=0,a=t.length;oi&&0===t?0:t+e;return{min:a(s,-Math.abs(o)),max:a(n,o)}}function Ci(t,e){return Object.assign(Object.create(t),e)}function Oi(t,e,i){return t?function(t,e){return{x:i=>t+t+e-i,setWidth(t){e=t},textAlign:t=>"center"===t?t:"right"===t?"left":"right",xPlus:(t,e)=>t-e,leftForLtr:(t,e)=>t-e}}(e,i):{x:t=>t,setWidth(t){},textAlign:t=>t,xPlus:(t,e)=>t+e,leftForLtr:(t,e)=>t}}function Ai(t,e){let i,s;"ltr"!==e&&"rtl"!==e||(i=t.canvas.style,s=[i.getPropertyValue("direction"),i.getPropertyPriority("direction")],i.setProperty("direction",e,"important"),t.prevTextDirection=s)}function Ti(t,e){void 0!==e&&(delete t.prevTextDirection,t.canvas.style.setProperty("direction",e[0],e[1]))}function Li(t){return"angle"===t?{between:J,compare:K,normalize:G}:{between:tt,compare:(t,e)=>t-e,normalize:t=>t}}function Ei({start:t,end:e,count:i,loop:s,style:n}){return{start:t%i,end:e%i,loop:s&&(e-t+1)%i==0,style:n}}function Ri(t,e,i){if(!i)return[t];const{property:s,start:n,end:o}=i,a=e.length,{compare:r,between:l,normalize:h}=Li(s),{start:c,end:d,loop:u,style:f}=function(t,e,i){const{property:s,start:n,end:o}=i,{between:a,normalize:r}=Li(s),l=e.length;let h,c,{start:d,end:u,loop:f}=t;if(f){for(d+=l,u+=l,h=0,c=l;hb||l(n,x,p)&&0!==r(n,x),v=()=>!b||0===r(o,p)||l(o,x,p);for(let t=c,i=c;t<=d;++t)m=e[t%a],m.skip||(p=h(m[s]),p!==x&&(b=l(p,n,o),null===_&&y()&&(_=0===r(p,n)?t:i),null!==_&&v()&&(g.push(Ei({start:_,end:t,loop:u,count:a,style:f})),_=null),i=t,x=p));return null!==_&&g.push(Ei({start:_,end:d,loop:u,count:a,style:f})),g}function Ii(t,e){const i=[],s=t.segments;for(let n=0;nn&&t[o%e].skip;)o--;return o%=e,{start:n,end:o}}(i,n,o,s);if(!0===s)return Fi(t,[{start:a,end:r,loop:o}],i,e);return Fi(t,function(t,e,i,s){const n=t.length,o=[];let a,r=e,l=t[e];for(a=e+1;a<=i;++a){const i=t[a%n];i.skip||i.stop?l.skip||(s=!1,o.push({start:e%n,end:(a-1)%n,loop:s}),e=r=i.stop?a:null):(r=a,l.skip&&(e=a)),l=i}return null!==r&&o.push({start:e%n,end:r%n,loop:s}),o}(i,a,r!s(t[e.axis])));n.lo-=Math.max(0,a);const r=i.slice(n.hi).findIndex((t=>!s(t[e.axis])));n.hi+=Math.max(0,r)}return n}if(o._sharedOptions){const t=a[0],s="function"==typeof t.getRange&&t.getRange(e);if(s){const t=r(a,e,i-s),n=r(a,e,i+s);return{lo:t.lo,hi:n.hi}}}}return{lo:0,hi:a.length-1}}function $i(t,e,i,s,n){const o=t.getSortedVisibleDatasetMetas(),a=i[e];for(let t=0,i=o.length;t{t[a]&&t[a](e[i],n)&&(o.push({element:t,datasetIndex:s,index:l}),r=r||t.inRange(e.x,e.y,n))})),s&&!r?[]:o}var Ki={evaluateInteractionItems:$i,modes:{index(t,e,i,s){const n=ve(e,t),o=i.axis||"x",a=i.includeInvisible||!1,r=i.intersect?Yi(t,n,o,s,a):Xi(t,n,o,!1,s,a),l=[];return r.length?(t.getSortedVisibleDatasetMetas().forEach((t=>{const e=r[0].index,i=t.data[e];i&&!i.skip&&l.push({element:i,datasetIndex:t.index,index:e})})),l):[]},dataset(t,e,i,s){const n=ve(e,t),o=i.axis||"xy",a=i.includeInvisible||!1;let r=i.intersect?Yi(t,n,o,s,a):Xi(t,n,o,!1,s,a);if(r.length>0){const e=r[0].datasetIndex,i=t.getDatasetMeta(e).data;r=[];for(let t=0;tYi(t,ve(e,t),i.axis||"xy",s,i.includeInvisible||!1),nearest(t,e,i,s){const n=ve(e,t),o=i.axis||"xy",a=i.includeInvisible||!1;return Xi(t,n,o,i.intersect,s,a)},x:(t,e,i,s)=>qi(t,ve(e,t),"x",i.intersect,s),y:(t,e,i,s)=>qi(t,ve(e,t),"y",i.intersect,s)}};const Gi=["left","top","right","bottom"];function Ji(t,e){return t.filter((t=>t.pos===e))}function Zi(t,e){return t.filter((t=>-1===Gi.indexOf(t.pos)&&t.box.axis===e))}function Qi(t,e){return t.sort(((t,i)=>{const s=e?i:t,n=e?t:i;return s.weight===n.weight?s.index-n.index:s.weight-n.weight}))}function ts(t,e){const i=function(t){const e={};for(const i of t){const{stack:t,pos:s,stackWeight:n}=i;if(!t||!Gi.includes(s))continue;const o=e[t]||(e[t]={count:0,placed:0,weight:0,size:0});o.count++,o.weight+=n}return e}(t),{vBoxMaxWidth:s,hBoxMaxHeight:n}=e;let o,a,r;for(o=0,a=t.length;o{s[t]=Math.max(e[t],i[t])})),s}return s(t?["left","right"]:["top","bottom"])}function os(t,e,i,s){const n=[];let o,a,r,l,h,c;for(o=0,a=t.length,h=0;ot.box.fullSize)),!0),s=Qi(Ji(e,"left"),!0),n=Qi(Ji(e,"right")),o=Qi(Ji(e,"top"),!0),a=Qi(Ji(e,"bottom")),r=Zi(e,"x"),l=Zi(e,"y");return{fullSize:i,leftAndTop:s.concat(o),rightAndBottom:n.concat(l).concat(a).concat(r),chartArea:Ji(e,"chartArea"),vertical:s.concat(n).concat(l),horizontal:o.concat(a).concat(r)}}(t.boxes),l=r.vertical,h=r.horizontal;u(t.boxes,(t=>{"function"==typeof t.beforeLayout&&t.beforeLayout()}));const c=l.reduce(((t,e)=>e.box.options&&!1===e.box.options.display?t:t+1),0)||1,d=Object.freeze({outerWidth:e,outerHeight:i,padding:n,availableWidth:o,availableHeight:a,vBoxMaxWidth:o/2/c,hBoxMaxHeight:a/2}),f=Object.assign({},n);is(f,ki(s));const g=Object.assign({maxPadding:f,w:o,h:a,x:n.left,y:n.top},n),p=ts(l.concat(h),d);os(r.fullSize,g,d,p),os(l,g,d,p),os(h,g,d,p)&&os(l,g,d,p),function(t){const e=t.maxPadding;function i(i){const s=Math.max(e[i]-t[i],0);return t[i]+=s,s}t.y+=i("top"),t.x+=i("left"),i("right"),i("bottom")}(g),rs(r.leftAndTop,g,d,p),g.x+=g.w,g.y+=g.h,rs(r.rightAndBottom,g,d,p),t.chartArea={left:g.left,top:g.top,right:g.left+g.w,bottom:g.top+g.h,height:g.h,width:g.w},u(r.chartArea,(e=>{const i=e.box;Object.assign(i,t.chartArea),i.update(g.w,g.h,{left:0,top:0,right:0,bottom:0})}))}};class hs{acquireContext(t,e){}releaseContext(t){return!1}addEventListener(t,e,i){}removeEventListener(t,e,i){}getDevicePixelRatio(){return 1}getMaximumSize(t,e,i,s){return e=Math.max(0,e||t.width),i=i||t.height,{width:e,height:Math.max(0,s?Math.floor(e/s):i)}}isAttached(t){return!0}updateConfig(t){}}class cs extends hs{acquireContext(t){return t&&t.getContext&&t.getContext("2d")||null}updateConfig(t){t.options.animation=!1}}const ds="$chartjs",us={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"},fs=t=>null===t||""===t;const gs=!!Se&&{passive:!0};function ps(t,e,i){t&&t.canvas&&t.canvas.removeEventListener(e,i,gs)}function ms(t,e){for(const i of t)if(i===e||i.contains(e))return!0}function xs(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ms(i.addedNodes,s),e=e&&!ms(i.removedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}function bs(t,e,i){const s=t.canvas,n=new MutationObserver((t=>{let e=!1;for(const i of t)e=e||ms(i.removedNodes,s),e=e&&!ms(i.addedNodes,s);e&&i()}));return n.observe(document,{childList:!0,subtree:!0}),n}const _s=new Map;let ys=0;function vs(){const t=window.devicePixelRatio;t!==ys&&(ys=t,_s.forEach(((e,i)=>{i.currentDevicePixelRatio!==t&&e()})))}function Ms(t,e,i){const s=t.canvas,n=s&&ge(s);if(!n)return;const o=ct(((t,e)=>{const s=n.clientWidth;i(t,e),s{const e=t[0],i=e.contentRect.width,s=e.contentRect.height;0===i&&0===s||o(i,s)}));return a.observe(n),function(t,e){_s.size||window.addEventListener("resize",vs),_s.set(t,e)}(t,o),a}function ws(t,e,i){i&&i.disconnect(),"resize"===e&&function(t){_s.delete(t),_s.size||window.removeEventListener("resize",vs)}(t)}function ks(t,e,i){const s=t.canvas,n=ct((e=>{null!==t.ctx&&i(function(t,e){const i=us[t.type]||t.type,{x:s,y:n}=ve(t,e);return{type:i,chart:e,native:t,x:void 0!==s?s:null,y:void 0!==n?n:null}}(e,t))}),t);return function(t,e,i){t&&t.addEventListener(e,i,gs)}(s,e,n),n}class Ss extends hs{acquireContext(t,e){const i=t&&t.getContext&&t.getContext("2d");return i&&i.canvas===t?(function(t,e){const i=t.style,s=t.getAttribute("height"),n=t.getAttribute("width");if(t[ds]={initial:{height:s,width:n,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",i.boxSizing=i.boxSizing||"border-box",fs(n)){const e=Pe(t,"width");void 0!==e&&(t.width=e)}if(fs(s))if(""===t.style.height)t.height=t.width/(e||2);else{const e=Pe(t,"height");void 0!==e&&(t.height=e)}}(t,e),i):null}releaseContext(t){const e=t.canvas;if(!e[ds])return!1;const i=e[ds].initial;["height","width"].forEach((t=>{const n=i[t];s(n)?e.removeAttribute(t):e.setAttribute(t,n)}));const n=i.style||{};return Object.keys(n).forEach((t=>{e.style[t]=n[t]})),e.width=e.width,delete e[ds],!0}addEventListener(t,e,i){this.removeEventListener(t,e);const s=t.$proxies||(t.$proxies={}),n={attach:xs,detach:bs,resize:Ms}[e]||ks;s[e]=n(t,e,i)}removeEventListener(t,e){const i=t.$proxies||(t.$proxies={}),s=i[e];if(!s)return;({attach:ws,detach:ws,resize:ws}[e]||ps)(t,e,s),i[e]=void 0}getDevicePixelRatio(){return window.devicePixelRatio}getMaximumSize(t,e,i,s){return we(t,e,i,s)}isAttached(t){const e=t&&ge(t);return!(!e||!e.isConnected)}}function Ps(t){return!fe()||"undefined"!=typeof OffscreenCanvas&&t instanceof OffscreenCanvas?cs:Ss}var Ds=Object.freeze({__proto__:null,BasePlatform:hs,BasicPlatform:cs,DomPlatform:Ss,_detectPlatform:Ps});const Cs="transparent",Os={boolean:(t,e,i)=>i>.5?e:t,color(t,e,i){const s=Qt(t||Cs),n=s.valid&&Qt(e||Cs);return n&&n.valid?n.mix(s,i).hexString():e},number:(t,e,i)=>t+(e-t)*i};class As{constructor(t,e,i,s){const n=e[i];s=Pi([t.to,s,n,t.from]);const o=Pi([t.from,n,s]);this._active=!0,this._fn=t.fn||Os[t.type||typeof o],this._easing=fi[t.easing]||fi.linear,this._start=Math.floor(Date.now()+(t.delay||0)),this._duration=this._total=Math.floor(t.duration),this._loop=!!t.loop,this._target=e,this._prop=i,this._from=o,this._to=s,this._promises=void 0}active(){return this._active}update(t,e,i){if(this._active){this._notify(!1);const s=this._target[this._prop],n=i-this._start,o=this._duration-n;this._start=i,this._duration=Math.floor(Math.max(o,t.duration)),this._total+=n,this._loop=!!t.loop,this._to=Pi([t.to,e,s,t.from]),this._from=Pi([t.from,s,e])}}cancel(){this._active&&(this.tick(Date.now()),this._active=!1,this._notify(!1))}tick(t){const e=t-this._start,i=this._duration,s=this._prop,n=this._from,o=this._loop,a=this._to;let r;if(this._active=n!==a&&(o||e1?2-r:r,r=this._easing(Math.min(1,Math.max(0,r))),this._target[s]=this._fn(n,a,r))}wait(){const t=this._promises||(this._promises=[]);return new Promise(((e,i)=>{t.push({res:e,rej:i})}))}_notify(t){const e=t?"res":"rej",i=this._promises||[];for(let t=0;t{const a=t[s];if(!o(a))return;const r={};for(const t of e)r[t]=a[t];(n(a.properties)&&a.properties||[s]).forEach((t=>{t!==s&&i.has(t)||i.set(t,r)}))}))}_animateOptions(t,e){const i=e.options,s=function(t,e){if(!e)return;let i=t.options;if(!i)return void(t.options=e);i.$shared&&(t.options=i=Object.assign({},i,{$shared:!1,$animations:{}}));return i}(t,i);if(!s)return[];const n=this._createAnimations(s,i);return i.$shared&&function(t,e){const i=[],s=Object.keys(e);for(let e=0;e{t.options=i}),(()=>{})),n}_createAnimations(t,e){const i=this._properties,s=[],n=t.$animations||(t.$animations={}),o=Object.keys(e),a=Date.now();let r;for(r=o.length-1;r>=0;--r){const l=o[r];if("$"===l.charAt(0))continue;if("options"===l){s.push(...this._animateOptions(t,e));continue}const h=e[l];let c=n[l];const d=i.get(l);if(c){if(d&&c.active()){c.update(d,h,a);continue}c.cancel()}d&&d.duration?(n[l]=c=new As(d,t,l,h),s.push(c)):t[l]=h}return s}update(t,e){if(0===this._properties.size)return void Object.assign(t,e);const i=this._createAnimations(t,e);return i.length?(bt.add(this._chart,i),!0):void 0}}function Ls(t,e){const i=t&&t.options||{},s=i.reverse,n=void 0===i.min?e:0,o=void 0===i.max?e:0;return{start:s?o:n,end:s?n:o}}function Es(t,e){const i=[],s=t._getSortedDatasetMetas(e);let n,o;for(n=0,o=s.length;n0||!i&&e<0)return n.index}return null}function Vs(t,e){const{chart:i,_cachedMeta:s}=t,n=i._stacks||(i._stacks={}),{iScale:o,vScale:a,index:r}=s,l=o.axis,h=a.axis,c=function(t,e,i){return`${t.id}.${e.id}.${i.stack||i.type}`}(o,a,s),d=e.length;let u;for(let t=0;ti[t].axis===e)).shift()}function Ws(t,e){const i=t.controller.index,s=t.vScale&&t.vScale.axis;if(s){e=e||t._parsed;for(const t of e){const e=t._stacks;if(!e||void 0===e[s]||void 0===e[s][i])return;delete e[s][i],void 0!==e[s]._visualValues&&void 0!==e[s]._visualValues[i]&&delete e[s]._visualValues[i]}}}const Ns=t=>"reset"===t||"none"===t,Hs=(t,e)=>e?t:Object.assign({},t);class js{static defaults={};static datasetElementType=null;static dataElementType=null;constructor(t,e){this.chart=t,this._ctx=t.ctx,this.index=e,this._cachedDataOpts={},this._cachedMeta=this.getMeta(),this._type=this._cachedMeta.type,this.options=void 0,this._parsing=!1,this._data=void 0,this._objectData=void 0,this._sharedOptions=void 0,this._drawStart=void 0,this._drawCount=void 0,this.enableOptionSharing=!1,this.supportsDecimation=!1,this.$context=void 0,this._syncList=[],this.datasetElementType=new.target.datasetElementType,this.dataElementType=new.target.dataElementType,this.initialize()}initialize(){const t=this._cachedMeta;this.configure(),this.linkScales(),t._stacked=Is(t.vScale,t),this.addElements(),this.options.fill&&!this.chart.isPluginEnabled("filler")&&console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options")}updateIndex(t){this.index!==t&&Ws(this._cachedMeta),this.index=t}linkScales(){const t=this.chart,e=this._cachedMeta,i=this.getDataset(),s=(t,e,i,s)=>"x"===t?e:"r"===t?s:i,n=e.xAxisID=l(i.xAxisID,Bs(t,"x")),o=e.yAxisID=l(i.yAxisID,Bs(t,"y")),a=e.rAxisID=l(i.rAxisID,Bs(t,"r")),r=e.indexAxis,h=e.iAxisID=s(r,n,o,a),c=e.vAxisID=s(r,o,n,a);e.xScale=this.getScaleForId(n),e.yScale=this.getScaleForId(o),e.rScale=this.getScaleForId(a),e.iScale=this.getScaleForId(h),e.vScale=this.getScaleForId(c)}getDataset(){return this.chart.data.datasets[this.index]}getMeta(){return this.chart.getDatasetMeta(this.index)}getScaleForId(t){return this.chart.scales[t]}_getOtherScale(t){const e=this._cachedMeta;return t===e.iScale?e.vScale:e.iScale}reset(){this._update("reset")}_destroy(){const t=this._cachedMeta;this._data&&rt(this._data,this),t._stacked&&Ws(t)}_dataCheck(){const t=this.getDataset(),e=t.data||(t.data=[]),i=this._data;if(o(e)){const t=this._cachedMeta;this._data=function(t,e){const{iScale:i,vScale:s}=e,n="x"===i.axis?"x":"y",o="x"===s.axis?"x":"y",a=Object.keys(t),r=new Array(a.length);let l,h,c;for(l=0,h=a.length;l0&&i._parsed[t-1];if(!1===this._parsing)i._parsed=s,i._sorted=!0,d=s;else{d=n(s[t])?this.parseArrayData(i,s,t,e):o(s[t])?this.parseObjectData(i,s,t,e):this.parsePrimitiveData(i,s,t,e);const a=()=>null===c[l]||f&&c[l]t&&!e.hidden&&e._stacked&&{keys:Es(i,!0),values:null})(e,i,this.chart),h={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY},{min:c,max:d}=function(t){const{min:e,max:i,minDefined:s,maxDefined:n}=t.getUserBounds();return{min:s?e:Number.NEGATIVE_INFINITY,max:n?i:Number.POSITIVE_INFINITY}}(r);let u,f;function g(){f=s[u];const e=f[r.axis];return!a(f[t.axis])||c>e||d=0;--u)if(!g()){this.updateRangeFromParsed(h,t,f,l);break}return h}getAllParsedValues(t){const e=this._cachedMeta._parsed,i=[];let s,n,o;for(s=0,n=e.length;s=0&&tthis.getContext(i,s,e)),c);return f.$shared&&(f.$shared=r,n[o]=Object.freeze(Hs(f,r))),f}_resolveAnimations(t,e,i){const s=this.chart,n=this._cachedDataOpts,o=`animation-${e}`,a=n[o];if(a)return a;let r;if(!1!==s.options.animation){const s=this.chart.config,n=s.datasetAnimationScopeKeys(this._type,e),o=s.getOptionScopes(this.getDataset(),n);r=s.createResolver(o,this.getContext(t,i,e))}const l=new Ts(s,r&&r.animations);return r&&r._cacheable&&(n[o]=Object.freeze(l)),l}getSharedOptions(t){if(t.$shared)return this._sharedOptions||(this._sharedOptions=Object.assign({},t))}includeOptions(t,e){return!e||Ns(t)||this.chart._animationsDisabled}_getSharedOptions(t,e){const i=this.resolveDataElementOptions(t,e),s=this._sharedOptions,n=this.getSharedOptions(i),o=this.includeOptions(e,n)||n!==s;return this.updateSharedOptions(n,e,i),{sharedOptions:n,includeOptions:o}}updateElement(t,e,i,s){Ns(s)?Object.assign(t,i):this._resolveAnimations(e,s).update(t,i)}updateSharedOptions(t,e,i){t&&!Ns(e)&&this._resolveAnimations(void 0,e).update(t,i)}_setStyle(t,e,i,s){t.active=s;const n=this.getStyle(e,s);this._resolveAnimations(e,i,s).update(t,{options:!s&&this.getSharedOptions(n)||n})}removeHoverStyle(t,e,i){this._setStyle(t,i,"active",!1)}setHoverStyle(t,e,i){this._setStyle(t,i,"active",!0)}_removeDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!1)}_setDatasetHoverStyle(){const t=this._cachedMeta.dataset;t&&this._setStyle(t,void 0,"active",!0)}_resyncElements(t){const e=this._data,i=this._cachedMeta.data;for(const[t,e,i]of this._syncList)this[t](e,i);this._syncList=[];const s=i.length,n=e.length,o=Math.min(n,s);o&&this.parse(0,o),n>s?this._insertElements(s,n-s,t):n{for(t.length+=e,a=t.length-1;a>=o;a--)t[a]=t[a-e]};for(r(n),a=t;a{s[t]=i[t]&&i[t].active()?i[t]._to:this[t]})),s}}function Ys(t,e){const i=t.options.ticks,n=function(t){const e=t.options.offset,i=t._tickSize(),s=t._length/i+(e?0:1),n=t._maxLength/i;return Math.floor(Math.min(s,n))}(t),o=Math.min(i.maxTicksLimit||n,n),a=i.major.enabled?function(t){const e=[];let i,s;for(i=0,s=t.length;io)return function(t,e,i,s){let n,o=0,a=i[0];for(s=Math.ceil(s),n=0;nn)return e}return Math.max(n,1)}(a,e,o);if(r>0){let t,i;const n=r>1?Math.round((h-l)/(r-1)):null;for(Us(e,c,d,s(n)?0:l-n,l),t=0,i=r-1;t"top"===e||"left"===e?t[e]+i:t[e]-i,qs=(t,e)=>Math.min(e||t,t);function Ks(t,e){const i=[],s=t.length/e,n=t.length;let o=0;for(;oa+r)))return h}function Js(t){return t.drawTicks?t.tickLength:0}function Zs(t,e){if(!t.display)return 0;const i=Si(t.font,e),s=ki(t.padding);return(n(t.text)?t.text.length:1)*i.lineHeight+s.height}function Qs(t,e,i){let s=ut(t);return(i&&"right"!==e||!i&&"right"===e)&&(s=(t=>"left"===t?"right":"right"===t?"left":t)(s)),s}class tn extends $s{constructor(t){super(),this.id=t.id,this.type=t.type,this.options=void 0,this.ctx=t.ctx,this.chart=t.chart,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this._margins={left:0,right:0,top:0,bottom:0},this.maxWidth=void 0,this.maxHeight=void 0,this.paddingTop=void 0,this.paddingBottom=void 0,this.paddingLeft=void 0,this.paddingRight=void 0,this.axis=void 0,this.labelRotation=void 0,this.min=void 0,this.max=void 0,this._range=void 0,this.ticks=[],this._gridLineItems=null,this._labelItems=null,this._labelSizes=null,this._length=0,this._maxLength=0,this._longestTextCache={},this._startPixel=void 0,this._endPixel=void 0,this._reversePixels=!1,this._userMax=void 0,this._userMin=void 0,this._suggestedMax=void 0,this._suggestedMin=void 0,this._ticksLength=0,this._borderValue=0,this._cache={},this._dataLimitsCached=!1,this.$context=void 0}init(t){this.options=t.setContext(this.getContext()),this.axis=t.axis,this._userMin=this.parse(t.min),this._userMax=this.parse(t.max),this._suggestedMin=this.parse(t.suggestedMin),this._suggestedMax=this.parse(t.suggestedMax)}parse(t,e){return t}getUserBounds(){let{_userMin:t,_userMax:e,_suggestedMin:i,_suggestedMax:s}=this;return t=r(t,Number.POSITIVE_INFINITY),e=r(e,Number.NEGATIVE_INFINITY),i=r(i,Number.POSITIVE_INFINITY),s=r(s,Number.NEGATIVE_INFINITY),{min:r(t,i),max:r(e,s),minDefined:a(t),maxDefined:a(e)}}getMinMax(t){let e,{min:i,max:s,minDefined:n,maxDefined:o}=this.getUserBounds();if(n&&o)return{min:i,max:s};const a=this.getMatchingVisibleMetas();for(let r=0,l=a.length;rs?s:i,s=n&&i>s?i:s,{min:r(i,r(s,i)),max:r(s,r(i,s))}}getPadding(){return{left:this.paddingLeft||0,top:this.paddingTop||0,right:this.paddingRight||0,bottom:this.paddingBottom||0}}getTicks(){return this.ticks}getLabels(){const t=this.chart.data;return this.options.labels||(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels||[]}getLabelItems(t=this.chart.chartArea){return this._labelItems||(this._labelItems=this._computeLabelItems(t))}beforeLayout(){this._cache={},this._dataLimitsCached=!1}beforeUpdate(){d(this.options.beforeUpdate,[this])}update(t,e,i){const{beginAtZero:s,grace:n,ticks:o}=this.options,a=o.sampleSize;this.beforeUpdate(),this.maxWidth=t,this.maxHeight=e,this._margins=i=Object.assign({left:0,right:0,top:0,bottom:0},i),this.ticks=null,this._labelSizes=null,this._gridLineItems=null,this._labelItems=null,this.beforeSetDimensions(),this.setDimensions(),this.afterSetDimensions(),this._maxLength=this.isHorizontal()?this.width+i.left+i.right:this.height+i.top+i.bottom,this._dataLimitsCached||(this.beforeDataLimits(),this.determineDataLimits(),this.afterDataLimits(),this._range=Di(this,n,s),this._dataLimitsCached=!0),this.beforeBuildTicks(),this.ticks=this.buildTicks()||[],this.afterBuildTicks();const r=a=n||i<=1||!this.isHorizontal())return void(this.labelRotation=s);const h=this._getLabelSizes(),c=h.widest.width,d=h.highest.height,u=Z(this.chart.width-c,0,this.maxWidth);o=t.offset?this.maxWidth/i:u/(i-1),c+6>o&&(o=u/(i-(t.offset?.5:1)),a=this.maxHeight-Js(t.grid)-e.padding-Zs(t.title,this.chart.options.font),r=Math.sqrt(c*c+d*d),l=Y(Math.min(Math.asin(Z((h.highest.height+6)/o,-1,1)),Math.asin(Z(a/r,-1,1))-Math.asin(Z(d/r,-1,1)))),l=Math.max(s,Math.min(n,l))),this.labelRotation=l}afterCalculateLabelRotation(){d(this.options.afterCalculateLabelRotation,[this])}afterAutoSkip(){}beforeFit(){d(this.options.beforeFit,[this])}fit(){const t={width:0,height:0},{chart:e,options:{ticks:i,title:s,grid:n}}=this,o=this._isVisible(),a=this.isHorizontal();if(o){const o=Zs(s,e.options.font);if(a?(t.width=this.maxWidth,t.height=Js(n)+o):(t.height=this.maxHeight,t.width=Js(n)+o),i.display&&this.ticks.length){const{first:e,last:s,widest:n,highest:o}=this._getLabelSizes(),r=2*i.padding,l=$(this.labelRotation),h=Math.cos(l),c=Math.sin(l);if(a){const e=i.mirror?0:c*n.width+h*o.height;t.height=Math.min(this.maxHeight,t.height+e+r)}else{const e=i.mirror?0:h*n.width+c*o.height;t.width=Math.min(this.maxWidth,t.width+e+r)}this._calculatePadding(e,s,c,h)}}this._handleMargins(),a?(this.width=this._length=e.width-this._margins.left-this._margins.right,this.height=t.height):(this.width=t.width,this.height=this._length=e.height-this._margins.top-this._margins.bottom)}_calculatePadding(t,e,i,s){const{ticks:{align:n,padding:o},position:a}=this.options,r=0!==this.labelRotation,l="top"!==a&&"x"===this.axis;if(this.isHorizontal()){const a=this.getPixelForTick(0)-this.left,h=this.right-this.getPixelForTick(this.ticks.length-1);let c=0,d=0;r?l?(c=s*t.width,d=i*e.height):(c=i*t.height,d=s*e.width):"start"===n?d=e.width:"end"===n?c=t.width:"inner"!==n&&(c=t.width/2,d=e.width/2),this.paddingLeft=Math.max((c-a+o)*this.width/(this.width-a),0),this.paddingRight=Math.max((d-h+o)*this.width/(this.width-h),0)}else{let i=e.height/2,s=t.height/2;"start"===n?(i=0,s=t.height):"end"===n&&(i=e.height,s=0),this.paddingTop=i+o,this.paddingBottom=s+o}}_handleMargins(){this._margins&&(this._margins.left=Math.max(this.paddingLeft,this._margins.left),this._margins.top=Math.max(this.paddingTop,this._margins.top),this._margins.right=Math.max(this.paddingRight,this._margins.right),this._margins.bottom=Math.max(this.paddingBottom,this._margins.bottom))}afterFit(){d(this.options.afterFit,[this])}isHorizontal(){const{axis:t,position:e}=this.options;return"top"===e||"bottom"===e||"x"===t}isFullSize(){return this.options.fullSize}_convertTicksToLabels(t){let e,i;for(this.beforeTickToLabelConversion(),this.generateTickLabels(t),e=0,i=t.length;e{const i=t.gc,s=i.length/2;let n;if(s>e){for(n=0;n({width:r[t]||0,height:l[t]||0});return{first:P(0),last:P(e-1),widest:P(k),highest:P(S),widths:r,heights:l}}getLabelForValue(t){return t}getPixelForValue(t,e){return NaN}getValueForPixel(t){}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getPixelForDecimal(t){this._reversePixels&&(t=1-t);const e=this._startPixel+t*this._length;return Q(this._alignToPixels?Ae(this.chart,e,0):e)}getDecimalForPixel(t){const e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e}getBasePixel(){return this.getPixelForValue(this.getBaseValue())}getBaseValue(){const{min:t,max:e}=this;return t<0&&e<0?e:t>0&&e>0?t:0}getContext(t){const e=this.ticks||[];if(t>=0&&ta*s?a/i:r/s:r*s0}_computeGridLineItems(t){const e=this.axis,i=this.chart,s=this.options,{grid:n,position:a,border:r}=s,h=n.offset,c=this.isHorizontal(),d=this.ticks.length+(h?1:0),u=Js(n),f=[],g=r.setContext(this.getContext()),p=g.display?g.width:0,m=p/2,x=function(t){return Ae(i,t,p)};let b,_,y,v,M,w,k,S,P,D,C,O;if("top"===a)b=x(this.bottom),w=this.bottom-u,S=b-m,D=x(t.top)+m,O=t.bottom;else if("bottom"===a)b=x(this.top),D=t.top,O=x(t.bottom)-m,w=b+m,S=this.top+u;else if("left"===a)b=x(this.right),M=this.right-u,k=b-m,P=x(t.left)+m,C=t.right;else if("right"===a)b=x(this.left),P=t.left,C=x(t.right)-m,M=b+m,k=this.left+u;else if("x"===e){if("center"===a)b=x((t.top+t.bottom)/2+.5);else if(o(a)){const t=Object.keys(a)[0],e=a[t];b=x(this.chart.scales[t].getPixelForValue(e))}D=t.top,O=t.bottom,w=b+m,S=w+u}else if("y"===e){if("center"===a)b=x((t.left+t.right)/2);else if(o(a)){const t=Object.keys(a)[0],e=a[t];b=x(this.chart.scales[t].getPixelForValue(e))}M=b-m,k=M-u,P=t.left,C=t.right}const A=l(s.ticks.maxTicksLimit,d),T=Math.max(1,Math.ceil(d/A));for(_=0;_0&&(o-=s/2)}d={left:o,top:n,width:s+e.width,height:i+e.height,color:t.backdropColor}}x.push({label:v,font:P,textOffset:O,options:{rotation:m,color:i,strokeColor:o,strokeWidth:h,textAlign:f,textBaseline:A,translation:[M,w],backdrop:d}})}return x}_getXAxisLabelAlignment(){const{position:t,ticks:e}=this.options;if(-$(this.labelRotation))return"top"===t?"left":"right";let i="center";return"start"===e.align?i="left":"end"===e.align?i="right":"inner"===e.align&&(i="inner"),i}_getYAxisLabelAlignment(t){const{position:e,ticks:{crossAlign:i,mirror:s,padding:n}}=this.options,o=t+n,a=this._getLabelSizes().widest.width;let r,l;return"left"===e?s?(l=this.right+n,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l+=a)):(l=this.right-o,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l=this.left)):"right"===e?s?(l=this.left+n,"near"===i?r="right":"center"===i?(r="center",l-=a/2):(r="left",l-=a)):(l=this.left+o,"near"===i?r="left":"center"===i?(r="center",l+=a/2):(r="right",l=this.right)):r="right",{textAlign:r,x:l}}_computeLabelArea(){if(this.options.ticks.mirror)return;const t=this.chart,e=this.options.position;return"left"===e||"right"===e?{top:0,left:this.left,bottom:t.height,right:this.right}:"top"===e||"bottom"===e?{top:this.top,left:0,bottom:this.bottom,right:t.width}:void 0}drawBackground(){const{ctx:t,options:{backgroundColor:e},left:i,top:s,width:n,height:o}=this;e&&(t.save(),t.fillStyle=e,t.fillRect(i,s,n,o),t.restore())}getLineWidthForValue(t){const e=this.options.grid;if(!this._isVisible()||!e.display)return 0;const i=this.ticks.findIndex((e=>e.value===t));if(i>=0){return e.setContext(this.getContext(i)).lineWidth}return 0}drawGrid(t){const e=this.options.grid,i=this.ctx,s=this._gridLineItems||(this._gridLineItems=this._computeGridLineItems(t));let n,o;const a=(t,e,s)=>{s.width&&s.color&&(i.save(),i.lineWidth=s.width,i.strokeStyle=s.color,i.setLineDash(s.borderDash||[]),i.lineDashOffset=s.borderDashOffset,i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(e.x,e.y),i.stroke(),i.restore())};if(e.display)for(n=0,o=s.length;n{this.drawBackground(),this.drawGrid(t),this.drawTitle()}},{z:s,draw:()=>{this.drawBorder()}},{z:e,draw:t=>{this.drawLabels(t)}}]:[{z:e,draw:t=>{this.draw(t)}}]}getMatchingVisibleMetas(t){const e=this.chart.getSortedVisibleDatasetMetas(),i=this.axis+"AxisID",s=[];let n,o;for(n=0,o=e.length;n{const s=i.split("."),n=s.pop(),o=[t].concat(s).join("."),a=e[i].split("."),r=a.pop(),l=a.join(".");ue.route(o,n,l,r)}))}(e,t.defaultRoutes);t.descriptors&&ue.describe(e,t.descriptors)}(t,o,i),this.override&&ue.override(t.id,t.overrides)),o}get(t){return this.items[t]}unregister(t){const e=this.items,i=t.id,s=this.scope;i in e&&delete e[i],s&&i in ue[s]&&(delete ue[s][i],this.override&&delete re[i])}}class sn{constructor(){this.controllers=new en(js,"datasets",!0),this.elements=new en($s,"elements"),this.plugins=new en(Object,"plugins"),this.scales=new en(tn,"scales"),this._typedRegistries=[this.controllers,this.scales,this.elements]}add(...t){this._each("register",t)}remove(...t){this._each("unregister",t)}addControllers(...t){this._each("register",t,this.controllers)}addElements(...t){this._each("register",t,this.elements)}addPlugins(...t){this._each("register",t,this.plugins)}addScales(...t){this._each("register",t,this.scales)}getController(t){return this._get(t,this.controllers,"controller")}getElement(t){return this._get(t,this.elements,"element")}getPlugin(t){return this._get(t,this.plugins,"plugin")}getScale(t){return this._get(t,this.scales,"scale")}removeControllers(...t){this._each("unregister",t,this.controllers)}removeElements(...t){this._each("unregister",t,this.elements)}removePlugins(...t){this._each("unregister",t,this.plugins)}removeScales(...t){this._each("unregister",t,this.scales)}_each(t,e,i){[...e].forEach((e=>{const s=i||this._getRegistryForType(e);i||s.isForType(e)||s===this.plugins&&e.id?this._exec(t,s,e):u(e,(e=>{const s=i||this._getRegistryForType(e);this._exec(t,s,e)}))}))}_exec(t,e,i){const s=w(t);d(i["before"+s],[],i),e[t](i),d(i["after"+s],[],i)}_getRegistryForType(t){for(let e=0;et.filter((t=>!e.some((e=>t.plugin.id===e.plugin.id))));this._notify(s(e,i),t,"stop"),this._notify(s(i,e),t,"start")}}function an(t,e){return e||!1!==t?!0===t?{}:t:null}function rn(t,{plugin:e,local:i},s,n){const o=t.pluginScopeKeys(e),a=t.getOptionScopes(s,o);return i&&e.defaults&&a.push(e.defaults),t.createResolver(a,n,[""],{scriptable:!1,indexable:!1,allKeys:!0})}function ln(t,e){const i=ue.datasets[t]||{};return((e.datasets||{})[t]||{}).indexAxis||e.indexAxis||i.indexAxis||"x"}function hn(t){if("x"===t||"y"===t||"r"===t)return t}function cn(t,...e){if(hn(t))return t;for(const s of e){const e=s.axis||("top"===(i=s.position)||"bottom"===i?"x":"left"===i||"right"===i?"y":void 0)||t.length>1&&hn(t[0].toLowerCase());if(e)return e}var i;throw new Error(`Cannot determine type of '${t}' axis. Please provide 'axis' or 'position' option.`)}function dn(t,e,i){if(i[e+"AxisID"]===t)return{axis:e}}function un(t,e){const i=re[t.type]||{scales:{}},s=e.scales||{},n=ln(t.type,e),a=Object.create(null);return Object.keys(s).forEach((e=>{const r=s[e];if(!o(r))return console.error(`Invalid scale configuration for scale: ${e}`);if(r._proxy)return console.warn(`Ignoring resolver passed as options for scale: ${e}`);const l=cn(e,r,function(t,e){if(e.data&&e.data.datasets){const i=e.data.datasets.filter((e=>e.xAxisID===t||e.yAxisID===t));if(i.length)return dn(t,"x",i[0])||dn(t,"y",i[0])}return{}}(e,t),ue.scales[r.type]),h=function(t,e){return t===e?"_index_":"_value_"}(l,n),c=i.scales||{};a[e]=b(Object.create(null),[{axis:l},r,c[l],c[h]])})),t.data.datasets.forEach((i=>{const n=i.type||t.type,o=i.indexAxis||ln(n,e),r=(re[n]||{}).scales||{};Object.keys(r).forEach((t=>{const e=function(t,e){let i=t;return"_index_"===t?i=e:"_value_"===t&&(i="x"===e?"y":"x"),i}(t,o),n=i[e+"AxisID"]||e;a[n]=a[n]||Object.create(null),b(a[n],[{axis:e},s[n],r[t]])}))})),Object.keys(a).forEach((t=>{const e=a[t];b(e,[ue.scales[e.type],ue.scale])})),a}function fn(t){const e=t.options||(t.options={});e.plugins=l(e.plugins,{}),e.scales=un(t,e)}function gn(t){return(t=t||{}).datasets=t.datasets||[],t.labels=t.labels||[],t}const pn=new Map,mn=new Set;function xn(t,e){let i=pn.get(t);return i||(i=e(),pn.set(t,i),mn.add(i)),i}const bn=(t,e,i)=>{const s=M(e,i);void 0!==s&&t.add(s)};class _n{constructor(t){this._config=function(t){return(t=t||{}).data=gn(t.data),fn(t),t}(t),this._scopeCache=new Map,this._resolverCache=new Map}get platform(){return this._config.platform}get type(){return this._config.type}set type(t){this._config.type=t}get data(){return this._config.data}set data(t){this._config.data=gn(t)}get options(){return this._config.options}set options(t){this._config.options=t}get plugins(){return this._config.plugins}update(){const t=this._config;this.clearCache(),fn(t)}clearCache(){this._scopeCache.clear(),this._resolverCache.clear()}datasetScopeKeys(t){return xn(t,(()=>[[`datasets.${t}`,""]]))}datasetAnimationScopeKeys(t,e){return xn(`${t}.transition.${e}`,(()=>[[`datasets.${t}.transitions.${e}`,`transitions.${e}`],[`datasets.${t}`,""]]))}datasetElementScopeKeys(t,e){return xn(`${t}-${e}`,(()=>[[`datasets.${t}.elements.${e}`,`datasets.${t}`,`elements.${e}`,""]]))}pluginScopeKeys(t){const e=t.id;return xn(`${this.type}-plugin-${e}`,(()=>[[`plugins.${e}`,...t.additionalOptionScopes||[]]]))}_cachedScopes(t,e){const i=this._scopeCache;let s=i.get(t);return s&&!e||(s=new Map,i.set(t,s)),s}getOptionScopes(t,e,i){const{options:s,type:n}=this,o=this._cachedScopes(t,i),a=o.get(e);if(a)return a;const r=new Set;e.forEach((e=>{t&&(r.add(t),e.forEach((e=>bn(r,t,e)))),e.forEach((t=>bn(r,s,t))),e.forEach((t=>bn(r,re[n]||{},t))),e.forEach((t=>bn(r,ue,t))),e.forEach((t=>bn(r,le,t)))}));const l=Array.from(r);return 0===l.length&&l.push(Object.create(null)),mn.has(e)&&o.set(e,l),l}chartOptionScopes(){const{options:t,type:e}=this;return[t,re[e]||{},ue.datasets[e]||{},{type:e},ue,le]}resolveNamedOptions(t,e,i,s=[""]){const o={$shared:!0},{resolver:a,subPrefixes:r}=yn(this._resolverCache,t,s);let l=a;if(function(t,e){const{isScriptable:i,isIndexable:s}=Ye(t);for(const o of e){const e=i(o),a=s(o),r=(a||e)&&t[o];if(e&&(S(r)||vn(r))||a&&n(r))return!0}return!1}(a,e)){o.$shared=!1;l=$e(a,i=S(i)?i():i,this.createResolver(t,i,r))}for(const t of e)o[t]=l[t];return o}createResolver(t,e,i=[""],s){const{resolver:n}=yn(this._resolverCache,t,i);return o(e)?$e(n,e,void 0,s):n}}function yn(t,e,i){let s=t.get(e);s||(s=new Map,t.set(e,s));const n=i.join();let o=s.get(n);if(!o){o={resolver:je(e,i),subPrefixes:i.filter((t=>!t.toLowerCase().includes("hover")))},s.set(n,o)}return o}const vn=t=>o(t)&&Object.getOwnPropertyNames(t).some((e=>S(t[e])));const Mn=["top","bottom","left","right","chartArea"];function wn(t,e){return"top"===t||"bottom"===t||-1===Mn.indexOf(t)&&"x"===e}function kn(t,e){return function(i,s){return i[t]===s[t]?i[e]-s[e]:i[t]-s[t]}}function Sn(t){const e=t.chart,i=e.options.animation;e.notifyPlugins("afterRender"),d(i&&i.onComplete,[t],e)}function Pn(t){const e=t.chart,i=e.options.animation;d(i&&i.onProgress,[t],e)}function Dn(t){return fe()&&"string"==typeof t?t=document.getElementById(t):t&&t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t}const Cn={},On=t=>{const e=Dn(t);return Object.values(Cn).filter((t=>t.canvas===e)).pop()};function An(t,e,i){const s=Object.keys(t);for(const n of s){const s=+n;if(s>=e){const o=t[n];delete t[n],(i>0||s>e)&&(t[s+i]=o)}}}class Tn{static defaults=ue;static instances=Cn;static overrides=re;static registry=nn;static version="4.5.1";static getChart=On;static register(...t){nn.add(...t),Ln()}static unregister(...t){nn.remove(...t),Ln()}constructor(t,e){const s=this.config=new _n(e),n=Dn(t),o=On(n);if(o)throw new Error("Canvas is already in use. Chart with ID '"+o.id+"' must be destroyed before the canvas with ID '"+o.canvas.id+"' can be reused.");const a=s.createResolver(s.chartOptionScopes(),this.getContext());this.platform=new(s.platform||Ps(n)),this.platform.updateConfig(s);const r=this.platform.acquireContext(n,a.aspectRatio),l=r&&r.canvas,h=l&&l.height,c=l&&l.width;this.id=i(),this.ctx=r,this.canvas=l,this.width=c,this.height=h,this._options=a,this._aspectRatio=this.aspectRatio,this._layers=[],this._metasets=[],this._stacks=void 0,this.boxes=[],this.currentDevicePixelRatio=void 0,this.chartArea=void 0,this._active=[],this._lastEvent=void 0,this._listeners={},this._responsiveListeners=void 0,this._sortedMetasets=[],this.scales={},this._plugins=new on,this.$proxies={},this._hiddenIndices={},this.attached=!1,this._animationsDisabled=void 0,this.$context=void 0,this._doResize=dt((t=>this.update(t)),a.resizeDelay||0),this._dataChanges=[],Cn[this.id]=this,r&&l?(bt.listen(this,"complete",Sn),bt.listen(this,"progress",Pn),this._initialize(),this.attached&&this.update()):console.error("Failed to create chart: can't acquire context from the given item")}get aspectRatio(){const{options:{aspectRatio:t,maintainAspectRatio:e},width:i,height:n,_aspectRatio:o}=this;return s(t)?e&&o?o:n?i/n:null:t}get data(){return this.config.data}set data(t){this.config.data=t}get options(){return this._options}set options(t){this.config.options=t}get registry(){return nn}_initialize(){return this.notifyPlugins("beforeInit"),this.options.responsive?this.resize():ke(this,this.options.devicePixelRatio),this.bindEvents(),this.notifyPlugins("afterInit"),this}clear(){return Te(this.canvas,this.ctx),this}stop(){return bt.stop(this),this}resize(t,e){bt.running(this)?this._resizeBeforeDraw={width:t,height:e}:this._resize(t,e)}_resize(t,e){const i=this.options,s=this.canvas,n=i.maintainAspectRatio&&this.aspectRatio,o=this.platform.getMaximumSize(s,t,e,n),a=i.devicePixelRatio||this.platform.getDevicePixelRatio(),r=this.width?"resize":"attach";this.width=o.width,this.height=o.height,this._aspectRatio=this.aspectRatio,ke(this,a,!0)&&(this.notifyPlugins("resize",{size:o}),d(i.onResize,[this,o],this),this.attached&&this._doResize(r)&&this.render())}ensureScalesHaveIDs(){u(this.options.scales||{},((t,e)=>{t.id=e}))}buildOrUpdateScales(){const t=this.options,e=t.scales,i=this.scales,s=Object.keys(i).reduce(((t,e)=>(t[e]=!1,t)),{});let n=[];e&&(n=n.concat(Object.keys(e).map((t=>{const i=e[t],s=cn(t,i),n="r"===s,o="x"===s;return{options:i,dposition:n?"chartArea":o?"bottom":"left",dtype:n?"radialLinear":o?"category":"linear"}})))),u(n,(e=>{const n=e.options,o=n.id,a=cn(o,n),r=l(n.type,e.dtype);void 0!==n.position&&wn(n.position,a)===wn(e.dposition)||(n.position=e.dposition),s[o]=!0;let h=null;if(o in i&&i[o].type===r)h=i[o];else{h=new(nn.getScale(r))({id:o,type:r,ctx:this.ctx,chart:this}),i[h.id]=h}h.init(n,t)})),u(s,((t,e)=>{t||delete i[e]})),u(i,(t=>{ls.configure(this,t,t.options),ls.addBox(this,t)}))}_updateMetasets(){const t=this._metasets,e=this.data.datasets.length,i=t.length;if(t.sort(((t,e)=>t.index-e.index)),i>e){for(let t=e;te.length&&delete this._stacks,t.forEach(((t,i)=>{0===e.filter((e=>e===t._dataset)).length&&this._destroyDatasetMeta(i)}))}buildOrUpdateControllers(){const t=[],e=this.data.datasets;let i,s;for(this._removeUnreferencedMetasets(),i=0,s=e.length;i{this.getDatasetMeta(e).controller.reset()}),this)}reset(){this._resetElements(),this.notifyPlugins("reset")}update(t){const e=this.config;e.update();const i=this._options=e.createResolver(e.chartOptionScopes(),this.getContext()),s=this._animationsDisabled=!i.animation;if(this._updateScales(),this._checkEventBindings(),this._updateHiddenIndices(),this._plugins.invalidate(),!1===this.notifyPlugins("beforeUpdate",{mode:t,cancelable:!0}))return;const n=this.buildOrUpdateControllers();this.notifyPlugins("beforeElementsUpdate");let o=0;for(let t=0,e=this.data.datasets.length;t{t.reset()})),this._updateDatasets(t),this.notifyPlugins("afterUpdate",{mode:t}),this._layers.sort(kn("z","_idx"));const{_active:a,_lastEvent:r}=this;r?this._eventHandler(r,!0):a.length&&this._updateHoverStyles(a,a,!0),this.render()}_updateScales(){u(this.scales,(t=>{ls.removeBox(this,t)})),this.ensureScalesHaveIDs(),this.buildOrUpdateScales()}_checkEventBindings(){const t=this.options,e=new Set(Object.keys(this._listeners)),i=new Set(t.events);P(e,i)&&!!this._responsiveListeners===t.responsive||(this.unbindEvents(),this.bindEvents())}_updateHiddenIndices(){const{_hiddenIndices:t}=this,e=this._getUniformDataChanges()||[];for(const{method:i,start:s,count:n}of e){An(t,s,"_removeElements"===i?-n:n)}}_getUniformDataChanges(){const t=this._dataChanges;if(!t||!t.length)return;this._dataChanges=[];const e=this.data.datasets.length,i=e=>new Set(t.filter((t=>t[0]===e)).map(((t,e)=>e+","+t.splice(1).join(",")))),s=i(0);for(let t=1;tt.split(","))).map((t=>({method:t[1],start:+t[2],count:+t[3]})))}_updateLayout(t){if(!1===this.notifyPlugins("beforeLayout",{cancelable:!0}))return;ls.update(this,this.width,this.height,t);const e=this.chartArea,i=e.width<=0||e.height<=0;this._layers=[],u(this.boxes,(t=>{i&&"chartArea"===t.position||(t.configure&&t.configure(),this._layers.push(...t._layers()))}),this),this._layers.forEach(((t,e)=>{t._idx=e})),this.notifyPlugins("afterLayout")}_updateDatasets(t){if(!1!==this.notifyPlugins("beforeDatasetsUpdate",{mode:t,cancelable:!0})){for(let t=0,e=this.data.datasets.length;t=0;--e)this._drawDataset(t[e]);this.notifyPlugins("afterDatasetsDraw")}_drawDataset(t){const e=this.ctx,i={meta:t,index:t.index,cancelable:!0},s=Ni(this,t);!1!==this.notifyPlugins("beforeDatasetDraw",i)&&(s&&Ie(e,s),t.controller.draw(),s&&ze(e),i.cancelable=!1,this.notifyPlugins("afterDatasetDraw",i))}isPointInArea(t){return Re(t,this.chartArea,this._minPadding)}getElementsAtEventForMode(t,e,i,s){const n=Ki.modes[e];return"function"==typeof n?n(this,t,i,s):[]}getDatasetMeta(t){const e=this.data.datasets[t],i=this._metasets;let s=i.filter((t=>t&&t._dataset===e)).pop();return s||(s={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e&&e.order||0,index:t,_dataset:e,_parsed:[],_sorted:!1},i.push(s)),s}getContext(){return this.$context||(this.$context=Ci(null,{chart:this,type:"chart"}))}getVisibleDatasetCount(){return this.getSortedVisibleDatasetMetas().length}isDatasetVisible(t){const e=this.data.datasets[t];if(!e)return!1;const i=this.getDatasetMeta(t);return"boolean"==typeof i.hidden?!i.hidden:!e.hidden}setDatasetVisibility(t,e){this.getDatasetMeta(t).hidden=!e}toggleDataVisibility(t){this._hiddenIndices[t]=!this._hiddenIndices[t]}getDataVisibility(t){return!this._hiddenIndices[t]}_updateVisibility(t,e,i){const s=i?"show":"hide",n=this.getDatasetMeta(t),o=n.controller._resolveAnimations(void 0,s);k(e)?(n.data[e].hidden=!i,this.update()):(this.setDatasetVisibility(t,i),o.update(n,{visible:i}),this.update((e=>e.datasetIndex===t?s:void 0)))}hide(t,e){this._updateVisibility(t,e,!1)}show(t,e){this._updateVisibility(t,e,!0)}_destroyDatasetMeta(t){const e=this._metasets[t];e&&e.controller&&e.controller._destroy(),delete this._metasets[t]}_stop(){let t,e;for(this.stop(),bt.remove(this),t=0,e=this.data.datasets.length;t{e.addEventListener(this,i,s),t[i]=s},s=(t,e,i)=>{t.offsetX=e,t.offsetY=i,this._eventHandler(t)};u(this.options.events,(t=>i(t,s)))}bindResponsiveEvents(){this._responsiveListeners||(this._responsiveListeners={});const t=this._responsiveListeners,e=this.platform,i=(i,s)=>{e.addEventListener(this,i,s),t[i]=s},s=(i,s)=>{t[i]&&(e.removeEventListener(this,i,s),delete t[i])},n=(t,e)=>{this.canvas&&this.resize(t,e)};let o;const a=()=>{s("attach",a),this.attached=!0,this.resize(),i("resize",n),i("detach",o)};o=()=>{this.attached=!1,s("resize",n),this._stop(),this._resize(0,0),i("attach",a)},e.isAttached(this.canvas)?a():o()}unbindEvents(){u(this._listeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._listeners={},u(this._responsiveListeners,((t,e)=>{this.platform.removeEventListener(this,e,t)})),this._responsiveListeners=void 0}updateHoverStyle(t,e,i){const s=i?"set":"remove";let n,o,a,r;for("dataset"===e&&(n=this.getDatasetMeta(t[0].datasetIndex),n.controller["_"+s+"DatasetHoverStyle"]()),a=0,r=t.length;a{const i=this.getDatasetMeta(t);if(!i)throw new Error("No dataset found at index "+t);return{datasetIndex:t,element:i.data[e],index:e}}));!f(i,e)&&(this._active=i,this._lastEvent=null,this._updateHoverStyles(i,e))}notifyPlugins(t,e,i){return this._plugins.notify(this,t,e,i)}isPluginEnabled(t){return 1===this._plugins._cache.filter((e=>e.plugin.id===t)).length}_updateHoverStyles(t,e,i){const s=this.options.hover,n=(t,e)=>t.filter((t=>!e.some((e=>t.datasetIndex===e.datasetIndex&&t.index===e.index)))),o=n(e,t),a=i?t:n(t,e);o.length&&this.updateHoverStyle(o,s.mode,!1),a.length&&s.mode&&this.updateHoverStyle(a,s.mode,!0)}_eventHandler(t,e){const i={event:t,replay:e,cancelable:!0,inChartArea:this.isPointInArea(t)},s=e=>(e.options.events||this.options.events).includes(t.native.type);if(!1===this.notifyPlugins("beforeEvent",i,s))return;const n=this._handleEvent(t,e,i.inChartArea);return i.cancelable=!1,this.notifyPlugins("afterEvent",i,s),(n||i.changed)&&this.render(),this}_handleEvent(t,e,i){const{_active:s=[],options:n}=this,o=e,a=this._getActiveElements(t,s,i,o),r=D(t),l=function(t,e,i,s){return i&&"mouseout"!==t.type?s?e:t:null}(t,this._lastEvent,i,r);i&&(this._lastEvent=null,d(n.onHover,[t,a,this],this),r&&d(n.onClick,[t,a,this],this));const h=!f(a,s);return(h||e)&&(this._active=a,this._updateHoverStyles(a,s,e)),this._lastEvent=l,h}_getActiveElements(t,e,i,s){if("mouseout"===t.type)return[];if(!i)return e;const n=this.options.hover;return this.getElementsAtEventForMode(t,n.mode,n,s)}}function Ln(){return u(Tn.instances,(t=>t._plugins.invalidate()))}function En(){throw new Error("This method is not implemented: Check that a complete date adapter is provided.")}class Rn{static override(t){Object.assign(Rn.prototype,t)}options;constructor(t){this.options=t||{}}init(){}formats(){return En()}parse(){return En()}format(){return En()}add(){return En()}diff(){return En()}startOf(){return En()}endOf(){return En()}}var In={_date:Rn};function zn(t){const e=t.iScale,i=function(t,e){if(!t._cache.$bar){const i=t.getMatchingVisibleMetas(e);let s=[];for(let e=0,n=i.length;et-e)))}return t._cache.$bar}(e,t.type);let s,n,o,a,r=e._length;const l=()=>{32767!==o&&-32768!==o&&(k(a)&&(r=Math.min(r,Math.abs(o-a)||r)),a=o)};for(s=0,n=i.length;sMath.abs(r)&&(l=r,h=a),e[i.axis]=h,e._custom={barStart:l,barEnd:h,start:n,end:o,min:a,max:r}}(t,e,i,s):e[i.axis]=i.parse(t,s),e}function Vn(t,e,i,s){const n=t.iScale,o=t.vScale,a=n.getLabels(),r=n===o,l=[];let h,c,d,u;for(h=i,c=i+s;ht.x,i="left",s="right"):(e=t.base"spacing"!==t,_indexable:t=>"spacing"!==t&&!t.startsWith("borderDash")&&!t.startsWith("hoverBorderDash")};static overrides={aspectRatio:1,plugins:{legend:{labels:{generateLabels(t){const e=t.data,{labels:{pointStyle:i,textAlign:s,color:n,useBorderRadius:o,borderRadius:a}}=t.legend.options;return e.labels.length&&e.datasets.length?e.labels.map(((e,r)=>{const l=t.getDatasetMeta(0).controller.getStyle(r);return{text:e,fillStyle:l.backgroundColor,fontColor:n,hidden:!t.getDataVisibility(r),lineDash:l.borderDash,lineDashOffset:l.borderDashOffset,lineJoin:l.borderJoinStyle,lineWidth:l.borderWidth,strokeStyle:l.borderColor,textAlign:s,pointStyle:i,borderRadius:o&&(a||l.borderRadius),index:r}})):[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}}}};constructor(t,e){super(t,e),this.enableOptionSharing=!0,this.innerRadius=void 0,this.outerRadius=void 0,this.offsetX=void 0,this.offsetY=void 0}linkScales(){}parse(t,e){const i=this.getDataset().data,s=this._cachedMeta;if(!1===this._parsing)s._parsed=i;else{let n,a,r=t=>+i[t];if(o(i[t])){const{key:t="value"}=this._parsing;r=e=>+M(i[e],t)}for(n=t,a=t+e;nJ(t,r,l,!0)?1:Math.max(e,e*i,s,s*i),g=(t,e,s)=>J(t,r,l,!0)?-1:Math.min(e,e*i,s,s*i),p=f(0,h,d),m=f(E,c,u),x=g(C,h,d),b=g(C+E,c,u);s=(p-x)/2,n=(m-b)/2,o=-(p+x)/2,a=-(m+b)/2}return{ratioX:s,ratioY:n,offsetX:o,offsetY:a}}(u,d,r),x=(i.width-o)/f,b=(i.height-o)/g,_=Math.max(Math.min(x,b)/2,0),y=c(this.options.radius,_),v=(y-Math.max(y*r,0))/this._getVisibleDatasetWeightTotal();this.offsetX=p*y,this.offsetY=m*y,s.total=this.calculateTotal(),this.outerRadius=y-v*this._getRingWeightOffset(this.index),this.innerRadius=Math.max(this.outerRadius-v*l,0),this.updateElements(n,0,n.length,t)}_circumference(t,e){const i=this.options,s=this._cachedMeta,n=this._getCircumference();return e&&i.animation.animateRotate||!this.chart.getDataVisibility(t)||null===s._parsed[t]||s.data[t].hidden?0:this.calculateCircumference(s._parsed[t]*n/O)}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.chartArea,r=o.options.animation,l=(a.left+a.right)/2,h=(a.top+a.bottom)/2,c=n&&r.animateScale,d=c?0:this.innerRadius,u=c?0:this.outerRadius,{sharedOptions:f,includeOptions:g}=this._getSharedOptions(e,s);let p,m=this._getRotation();for(p=0;p0&&!isNaN(t)?O*(Math.abs(t)/e):0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=ne(e._parsed[t],i.options.locale);return{label:s[t]||"",value:n}}getMaxBorderWidth(t){let e=0;const i=this.chart;let s,n,o,a,r;if(!t)for(s=0,n=i.data.datasets.length;s{const o=t.getDatasetMeta(0).controller.getStyle(n);return{text:e,fillStyle:o.backgroundColor,strokeStyle:o.borderColor,fontColor:s,lineWidth:o.borderWidth,pointStyle:i,hidden:!t.getDataVisibility(n),index:n}}))}return[]}},onClick(t,e,i){i.chart.toggleDataVisibility(e.index),i.chart.update()}}},scales:{r:{type:"radialLinear",angleLines:{display:!1},beginAtZero:!0,grid:{circular:!0},pointLabels:{display:!1},startAngle:0}}};constructor(t,e){super(t,e),this.innerRadius=void 0,this.outerRadius=void 0}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart,s=i.data.labels||[],n=ne(e._parsed[t].r,i.options.locale);return{label:s[t]||"",value:n}}parseObjectData(t,e,i,s){return ii.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta.data;this._updateRadius(),this.updateElements(e,0,e.length,t)}getMinMax(){const t=this._cachedMeta,e={min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY};return t.data.forEach(((t,i)=>{const s=this.getParsed(i).r;!isNaN(s)&&this.chart.getDataVisibility(i)&&(se.max&&(e.max=s))})),e}_updateRadius(){const t=this.chart,e=t.chartArea,i=t.options,s=Math.min(e.right-e.left,e.bottom-e.top),n=Math.max(s/2,0),o=(n-Math.max(i.cutoutPercentage?n/100*i.cutoutPercentage:1,0))/t.getVisibleDatasetCount();this.outerRadius=n-o*this.index,this.innerRadius=this.outerRadius-o}updateElements(t,e,i,s){const n="reset"===s,o=this.chart,a=o.options.animation,r=this._cachedMeta.rScale,l=r.xCenter,h=r.yCenter,c=r.getIndexAngle(0)-.5*C;let d,u=c;const f=360/this.countVisibleElements();for(d=0;d{!isNaN(this.getParsed(i).r)&&this.chart.getDataVisibility(i)&&e++})),e}_computeAngle(t,e,i){return this.chart.getDataVisibility(t)?$(this.resolveDataElementOptions(t,e).angle||i):0}}var Un=Object.freeze({__proto__:null,BarController:class extends js{static id="bar";static defaults={datasetElementType:!1,dataElementType:"bar",categoryPercentage:.8,barPercentage:.9,grouped:!0,animations:{numbers:{type:"number",properties:["x","y","base","width","height"]}}};static overrides={scales:{_index_:{type:"category",offset:!0,grid:{offset:!0}},_value_:{type:"linear",beginAtZero:!0}}};parsePrimitiveData(t,e,i,s){return Vn(t,e,i,s)}parseArrayData(t,e,i,s){return Vn(t,e,i,s)}parseObjectData(t,e,i,s){const{iScale:n,vScale:o}=t,{xAxisKey:a="x",yAxisKey:r="y"}=this._parsing,l="x"===n.axis?a:r,h="x"===o.axis?a:r,c=[];let d,u,f,g;for(d=i,u=i+s;dt.controller.options.grouped)),o=i.options.stacked,a=[],r=this._cachedMeta.controller.getParsed(e),l=r&&r[i.axis],h=t=>{const e=t._parsed.find((t=>t[i.axis]===l)),n=e&&e[t.vScale.axis];if(s(n)||isNaN(n))return!0};for(const i of n)if((void 0===e||!h(i))&&((!1===o||-1===a.indexOf(i.stack)||void 0===o&&void 0===i.stack)&&a.push(i.stack),i.index===t))break;return a.length||a.push(void 0),a}_getStackCount(t){return this._getStacks(void 0,t).length}_getAxisCount(){return this._getAxis().length}getFirstScaleIdForIndexAxis(){const t=this.chart.scales,e=this.chart.options.indexAxis;return Object.keys(t).filter((i=>t[i].axis===e)).shift()}_getAxis(){const t={},e=this.getFirstScaleIdForIndexAxis();for(const i of this.chart.data.datasets)t[l("x"===this.chart.options.indexAxis?i.xAxisID:i.yAxisID,e)]=!0;return Object.keys(t)}_getStackIndex(t,e,i){const s=this._getStacks(t,i),n=void 0!==e?s.indexOf(e):-1;return-1===n?s.length-1:n}_getRuler(){const t=this.options,e=this._cachedMeta,i=e.iScale,s=[];let n,o;for(n=0,o=e.data.length;n=i?1:-1)}(u,e,r)*a,f===r&&(x-=u/2);const t=e.getPixelForDecimal(0),s=e.getPixelForDecimal(1),o=Math.min(t,s),h=Math.max(t,s);x=Math.max(Math.min(x,h),o),d=x+u,i&&!c&&(l._stacks[e.axis]._visualValues[n]=e.getValueForPixel(d)-e.getValueForPixel(x))}if(x===e.getPixelForValue(r)){const t=F(u)*e.getLineWidthForValue(r)/2;x+=t,u-=t}return{size:u,base:x,head:d,center:d+u/2}}_calculateBarIndexPixels(t,e){const i=e.scale,n=this.options,o=n.skipNull,a=l(n.maxBarThickness,1/0);let r,h;const c=this._getAxisCount();if(e.grouped){const i=o?this._getStackCount(t):e.stackCount,d="flex"===n.barThickness?function(t,e,i,s){const n=e.pixels,o=n[t];let a=t>0?n[t-1]:null,r=t=0;--i)e=Math.max(e,t[i].size(this.resolveDataElementOptions(i))/2);return e>0&&e}getLabelAndValue(t){const e=this._cachedMeta,i=this.chart.data.labels||[],{xScale:s,yScale:n}=e,o=this.getParsed(t),a=s.getLabelForValue(o.x),r=n.getLabelForValue(o.y),l=o._custom;return{label:i[t]||"",value:"("+a+", "+r+(l?", "+l:"")+")"}}update(t){const e=this._cachedMeta.data;this.updateElements(e,0,e.length,t)}updateElements(t,e,i,s){const n="reset"===s,{iScale:o,vScale:a}=this._cachedMeta,{sharedOptions:r,includeOptions:l}=this._getSharedOptions(e,s),h=o.axis,c=a.axis;for(let d=e;d0&&this.getParsed(e-1);for(let i=0;i<_;++i){const g=t[i],_=x?g:{};if(i=b){_.skip=!0;continue}const v=this.getParsed(i),M=s(v[f]),w=_[u]=a.getPixelForValue(v[u],i),k=_[f]=o||M?r.getBasePixel():r.getPixelForValue(l?this.applyStack(r,v,l):v[f],i);_.skip=isNaN(w)||isNaN(k)||M,_.stop=i>0&&Math.abs(v[u]-y[u])>m,p&&(_.parsed=v,_.raw=h.data[i]),d&&(_.options=c||this.resolveDataElementOptions(i,g.active?"active":n)),x||this.updateElement(g,i,_,n),y=v}}getMaxOverflow(){const t=this._cachedMeta,e=t.dataset,i=e.options&&e.options.borderWidth||0,s=t.data||[];if(!s.length)return i;const n=s[0].size(this.resolveDataElementOptions(0)),o=s[s.length-1].size(this.resolveDataElementOptions(s.length-1));return Math.max(i,n,o)/2}draw(){const t=this._cachedMeta;t.dataset.updateControlPoints(this.chart.chartArea,t.iScale.axis),super.draw()}},PieController:class extends $n{static id="pie";static defaults={cutout:0,rotation:0,circumference:360,radius:"100%"}},PolarAreaController:Yn,RadarController:class extends js{static id="radar";static defaults={datasetElementType:"line",dataElementType:"point",indexAxis:"r",showLine:!0,elements:{line:{fill:"start"}}};static overrides={aspectRatio:1,scales:{r:{type:"radialLinear"}}};getLabelAndValue(t){const e=this._cachedMeta.vScale,i=this.getParsed(t);return{label:e.getLabels()[t],value:""+e.getLabelForValue(i[e.axis])}}parseObjectData(t,e,i,s){return ii.bind(this)(t,e,i,s)}update(t){const e=this._cachedMeta,i=e.dataset,s=e.data||[],n=e.iScale.getLabels();if(i.points=s,"resize"!==t){const e=this.resolveDatasetElementOptions(t);this.options.showLine||(e.borderWidth=0);const o={_loop:!0,_fullLoop:n.length===s.length,options:e};this.updateElement(i,void 0,o,t)}this.updateElements(s,0,s.length,t)}updateElements(t,e,i,s){const n=this._cachedMeta.rScale,o="reset"===s;for(let a=e;a0&&this.getParsed(e-1);for(let c=e;c0&&Math.abs(i[f]-_[f])>x,m&&(p.parsed=i,p.raw=h.data[c]),u&&(p.options=d||this.resolveDataElementOptions(c,e.active?"active":n)),b||this.updateElement(e,c,p,n),_=i}this.updateSharedOptions(d,n,c)}getMaxOverflow(){const t=this._cachedMeta,e=t.data||[];if(!this.options.showLine){let t=0;for(let i=e.length-1;i>=0;--i)t=Math.max(t,e[i].size(this.resolveDataElementOptions(i))/2);return t>0&&t}const i=t.dataset,s=i.options&&i.options.borderWidth||0;if(!e.length)return s;const n=e[0].size(this.resolveDataElementOptions(0)),o=e[e.length-1].size(this.resolveDataElementOptions(e.length-1));return Math.max(s,n,o)/2}}});function Xn(t,e,i,s){const n=vi(t.options.borderRadius,["outerStart","outerEnd","innerStart","innerEnd"]);const o=(i-e)/2,a=Math.min(o,s*e/2),r=t=>{const e=(i-Math.min(o,t))*s/2;return Z(t,0,Math.min(o,e))};return{outerStart:r(n.outerStart),outerEnd:r(n.outerEnd),innerStart:Z(n.innerStart,0,a),innerEnd:Z(n.innerEnd,0,a)}}function qn(t,e,i,s){return{x:i+t*Math.cos(e),y:s+t*Math.sin(e)}}function Kn(t,e,i,s,n,o){const{x:a,y:r,startAngle:l,pixelMargin:h,innerRadius:c}=e,d=Math.max(e.outerRadius+s+i-h,0),u=c>0?c+s+i+h:0;let f=0;const g=n-l;if(s){const t=((c>0?c-s:0)+(d>0?d-s:0))/2;f=(g-(0!==t?g*t/(t+s):g))/2}const p=(g-Math.max(.001,g*d-i/C)/d)/2,m=l+p+f,x=n-p-f,{outerStart:b,outerEnd:_,innerStart:y,innerEnd:v}=Xn(e,u,d,x-m),M=d-b,w=d-_,k=m+b/M,S=x-_/w,P=u+y,D=u+v,O=m+y/P,A=x-v/D;if(t.beginPath(),o){const e=(k+S)/2;if(t.arc(a,r,d,k,e),t.arc(a,r,d,e,S),_>0){const e=qn(w,S,a,r);t.arc(e.x,e.y,_,S,x+E)}const i=qn(D,x,a,r);if(t.lineTo(i.x,i.y),v>0){const e=qn(D,A,a,r);t.arc(e.x,e.y,v,x+E,A+Math.PI)}const s=(x-v/u+(m+y/u))/2;if(t.arc(a,r,u,x-v/u,s,!0),t.arc(a,r,u,s,m+y/u,!0),y>0){const e=qn(P,O,a,r);t.arc(e.x,e.y,y,O+Math.PI,m-E)}const n=qn(M,m,a,r);if(t.lineTo(n.x,n.y),b>0){const e=qn(M,k,a,r);t.arc(e.x,e.y,b,m-E,k)}}else{t.moveTo(a,r);const e=Math.cos(k)*d+a,i=Math.sin(k)*d+r;t.lineTo(e,i);const s=Math.cos(S)*d+a,n=Math.sin(S)*d+r;t.lineTo(s,n)}t.closePath()}function Gn(t,e,i,s,n){const{fullCircles:o,startAngle:a,circumference:r,options:l}=e,{borderWidth:h,borderJoinStyle:c,borderDash:d,borderDashOffset:u,borderRadius:f}=l,g="inner"===l.borderAlign;if(!h)return;t.setLineDash(d||[]),t.lineDashOffset=u,g?(t.lineWidth=2*h,t.lineJoin=c||"round"):(t.lineWidth=h,t.lineJoin=c||"bevel");let p=e.endAngle;if(o){Kn(t,e,i,s,p,n);for(let e=0;en?(h=n/l,t.arc(o,a,l,i+h,s-h,!0)):t.arc(o,a,n,i+E,s-E),t.closePath(),t.clip()}(t,e,p),l.selfJoin&&p-a>=C&&0===f&&"miter"!==c&&function(t,e,i){const{startAngle:s,x:n,y:o,outerRadius:a,innerRadius:r,options:l}=e,{borderWidth:h,borderJoinStyle:c}=l,d=Math.min(h/a,G(s-i));if(t.beginPath(),t.arc(n,o,a-h/2,s+d/2,i-d/2),r>0){const e=Math.min(h/r,G(s-i));t.arc(n,o,r+h/2,i-e/2,s+e/2,!0)}else{const e=Math.min(h/2,a*G(s-i));if("round"===c)t.arc(n,o,e,i-C/2,s+C/2,!0);else if("bevel"===c){const a=2*e*e,r=-a*Math.cos(i+C/2)+n,l=-a*Math.sin(i+C/2)+o,h=a*Math.cos(s+C/2)+n,c=a*Math.sin(s+C/2)+o;t.lineTo(r,l),t.lineTo(h,c)}}t.closePath(),t.moveTo(0,0),t.rect(0,0,t.canvas.width,t.canvas.height),t.clip("evenodd")}(t,e,p),o||(Kn(t,e,i,s,p,n),t.stroke())}function Jn(t,e,i=e){t.lineCap=l(i.borderCapStyle,e.borderCapStyle),t.setLineDash(l(i.borderDash,e.borderDash)),t.lineDashOffset=l(i.borderDashOffset,e.borderDashOffset),t.lineJoin=l(i.borderJoinStyle,e.borderJoinStyle),t.lineWidth=l(i.borderWidth,e.borderWidth),t.strokeStyle=l(i.borderColor,e.borderColor)}function Zn(t,e,i){t.lineTo(i.x,i.y)}function Qn(t,e,i={}){const s=t.length,{start:n=0,end:o=s-1}=i,{start:a,end:r}=e,l=Math.max(n,a),h=Math.min(o,r),c=nr&&o>r;return{count:s,start:l,loop:e.loop,ilen:h(a+(h?r-t:t))%o,_=()=>{f!==g&&(t.lineTo(m,g),t.lineTo(m,f),t.lineTo(m,p))};for(l&&(d=n[b(0)],t.moveTo(d.x,d.y)),c=0;c<=r;++c){if(d=n[b(c)],d.skip)continue;const e=d.x,i=d.y,s=0|e;s===u?(ig&&(g=i),m=(x*m+e)/++x):(_(),t.lineTo(e,i),u=s,x=0,f=g=i),p=i}_()}function io(t){const e=t.options,i=e.borderDash&&e.borderDash.length;return!(t._decimated||t._loop||e.tension||"monotone"===e.cubicInterpolationMode||e.stepped||i)?eo:to}const so="function"==typeof Path2D;function no(t,e,i,s){so&&!e.options.segment?function(t,e,i,s){let n=e._path;n||(n=e._path=new Path2D,e.path(n,i,s)&&n.closePath()),Jn(t,e.options),t.stroke(n)}(t,e,i,s):function(t,e,i,s){const{segments:n,options:o}=e,a=io(e);for(const r of n)Jn(t,o,r.style),t.beginPath(),a(t,e,r,{start:i,end:i+s-1})&&t.closePath(),t.stroke()}(t,e,i,s)}class oo extends $s{static id="line";static defaults={borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",borderWidth:3,capBezierPoints:!0,cubicInterpolationMode:"default",fill:!1,spanGaps:!1,stepped:!1,tension:0};static defaultRoutes={backgroundColor:"backgroundColor",borderColor:"borderColor"};static descriptors={_scriptable:!0,_indexable:t=>"borderDash"!==t&&"fill"!==t};constructor(t){super(),this.animated=!0,this.options=void 0,this._chart=void 0,this._loop=void 0,this._fullLoop=void 0,this._path=void 0,this._points=void 0,this._segments=void 0,this._decimated=!1,this._pointsUpdated=!1,this._datasetIndex=void 0,t&&Object.assign(this,t)}updateControlPoints(t,e){const i=this.options;if((i.tension||"monotone"===i.cubicInterpolationMode)&&!i.stepped&&!this._pointsUpdated){const s=i.spanGaps?this._loop:this._fullLoop;hi(this._points,i,t,s,e),this._pointsUpdated=!0}}set points(t){this._points=t,delete this._segments,delete this._path,this._pointsUpdated=!1}get points(){return this._points}get segments(){return this._segments||(this._segments=zi(this,this.options.segment))}first(){const t=this.segments,e=this.points;return t.length&&e[t[0].start]}last(){const t=this.segments,e=this.points,i=t.length;return i&&e[t[i-1].end]}interpolate(t,e){const i=this.options,s=t[e],n=this.points,o=Ii(this,{property:e,start:s,end:s});if(!o.length)return;const a=[],r=function(t){return t.stepped?pi:t.tension||"monotone"===t.cubicInterpolationMode?mi:gi}(i);let l,h;for(l=0,h=o.length;l"borderDash"!==t};circumference;endAngle;fullCircles;innerRadius;outerRadius;pixelMargin;startAngle;constructor(t){super(),this.options=void 0,this.circumference=void 0,this.startAngle=void 0,this.endAngle=void 0,this.innerRadius=void 0,this.outerRadius=void 0,this.pixelMargin=0,this.fullCircles=0,t&&Object.assign(this,t)}inRange(t,e,i){const s=this.getProps(["x","y"],i),{angle:n,distance:o}=X(s,{x:t,y:e}),{startAngle:a,endAngle:r,innerRadius:h,outerRadius:c,circumference:d}=this.getProps(["startAngle","endAngle","innerRadius","outerRadius","circumference"],i),u=(this.options.spacing+this.options.borderWidth)/2,f=l(d,r-a),g=J(n,a,r)&&a!==r,p=f>=O||g,m=tt(o,h+u,c+u);return p&&m}getCenterPoint(t){const{x:e,y:i,startAngle:s,endAngle:n,innerRadius:o,outerRadius:a}=this.getProps(["x","y","startAngle","endAngle","innerRadius","outerRadius"],t),{offset:r,spacing:l}=this.options,h=(s+n)/2,c=(o+a+l+r)/2;return{x:e+Math.cos(h)*c,y:i+Math.sin(h)*c}}tooltipPosition(t){return this.getCenterPoint(t)}draw(t){const{options:e,circumference:i}=this,s=(e.offset||0)/4,n=(e.spacing||0)/2,o=e.circular;if(this.pixelMargin="inner"===e.borderAlign?.33:0,this.fullCircles=i>O?Math.floor(i/O):0,0===i||this.innerRadius<0||this.outerRadius<0)return;t.save();const a=(this.startAngle+this.endAngle)/2;t.translate(Math.cos(a)*s,Math.sin(a)*s);const r=s*(1-Math.sin(Math.min(C,i||0)));t.fillStyle=e.backgroundColor,t.strokeStyle=e.borderColor,function(t,e,i,s,n){const{fullCircles:o,startAngle:a,circumference:r}=e;let l=e.endAngle;if(o){Kn(t,e,i,s,l,n);for(let e=0;e("string"==typeof e?(i=t.push(e)-1,s.unshift({index:i,label:e})):isNaN(e)&&(i=null),i))(t,e,i,s);return n!==t.lastIndexOf(e)?i:n}function mo(t){const e=this.getLabels();return t>=0&&ts=e?s:t,a=t=>n=i?n:t;if(t){const t=F(s),e=F(n);t<0&&e<0?a(0):t>0&&e>0&&o(0)}if(s===n){let e=0===n?1:Math.abs(.05*n);a(n+e),t||o(s-e)}this.min=s,this.max=n}getTickLimit(){const t=this.options.ticks;let e,{maxTicksLimit:i,stepSize:s}=t;return s?(e=Math.ceil(this.max/s)-Math.floor(this.min/s)+1,e>1e3&&(console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`),e=1e3)):(e=this.computeTickLimit(),i=i||11),i&&(e=Math.min(i,e)),e}computeTickLimit(){return Number.POSITIVE_INFINITY}buildTicks(){const t=this.options,e=t.ticks;let i=this.getTickLimit();i=Math.max(2,i);const n=function(t,e){const i=[],{bounds:n,step:o,min:a,max:r,precision:l,count:h,maxTicks:c,maxDigits:d,includeBounds:u}=t,f=o||1,g=c-1,{min:p,max:m}=e,x=!s(a),b=!s(r),_=!s(h),y=(m-p)/(d+1);let v,M,w,k,S=B((m-p)/g/f)*f;if(S<1e-14&&!x&&!b)return[{value:p},{value:m}];k=Math.ceil(m/S)-Math.floor(p/S),k>g&&(S=B(k*S/g/f)*f),s(l)||(v=Math.pow(10,l),S=Math.ceil(S*v)/v),"ticks"===n?(M=Math.floor(p/S)*S,w=Math.ceil(m/S)*S):(M=p,w=m),x&&b&&o&&H((r-a)/o,S/1e3)?(k=Math.round(Math.min((r-a)/S,c)),S=(r-a)/k,M=a,w=r):_?(M=x?a:M,w=b?r:w,k=h-1,S=(w-M)/k):(k=(w-M)/S,k=V(k,Math.round(k),S/1e3)?Math.round(k):Math.ceil(k));const P=Math.max(U(S),U(M));v=Math.pow(10,s(l)?P:l),M=Math.round(M*v)/v,w=Math.round(w*v)/v;let D=0;for(x&&(u&&M!==a?(i.push({value:a}),Mr)break;i.push({value:t})}return b&&u&&w!==r?i.length&&V(i[i.length-1].value,r,xo(r,y,t))?i[i.length-1].value=r:i.push({value:r}):b&&w!==r||i.push({value:w}),i}({maxTicks:i,bounds:t.bounds,min:t.min,max:t.max,precision:e.precision,step:e.stepSize,count:e.count,maxDigits:this._maxDigits(),horizontal:this.isHorizontal(),minRotation:e.minRotation||0,includeBounds:!1!==e.includeBounds},this._range||this);return"ticks"===t.bounds&&j(n,this,"value"),t.reverse?(n.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),n}configure(){const t=this.ticks;let e=this.min,i=this.max;if(super.configure(),this.options.offset&&t.length){const s=(i-e)/Math.max(t.length-1,1)/2;e-=s,i+=s}this._startValue=e,this._endValue=i,this._valueRange=i-e}getLabelForValue(t){return ne(t,this.chart.options.locale,this.options.ticks.format)}}class _o extends bo{static id="linear";static defaults={ticks:{callback:ae.formatters.numeric}};determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=a(t)?t:0,this.max=a(e)?e:1,this.handleTickRangeOptions()}computeTickLimit(){const t=this.isHorizontal(),e=t?this.width:this.height,i=$(this.options.ticks.minRotation),s=(t?Math.sin(i):Math.cos(i))||.001,n=this._resolveTickFontOptions(0);return Math.ceil(e/Math.min(40,n.lineHeight/s))}getPixelForValue(t){return null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getValueForPixel(t){return this._startValue+this.getDecimalForPixel(t)*this._valueRange}}const yo=t=>Math.floor(z(t)),vo=(t,e)=>Math.pow(10,yo(t)+e);function Mo(t){return 1===t/Math.pow(10,yo(t))}function wo(t,e,i){const s=Math.pow(10,i),n=Math.floor(t/s);return Math.ceil(e/s)-n}function ko(t,{min:e,max:i}){e=r(t.min,e);const s=[],n=yo(e);let o=function(t,e){let i=yo(e-t);for(;wo(t,e,i)>10;)i++;for(;wo(t,e,i)<10;)i--;return Math.min(i,yo(t))}(e,i),a=o<0?Math.pow(10,Math.abs(o)):1;const l=Math.pow(10,o),h=n>o?Math.pow(10,n):0,c=Math.round((e-h)*a)/a,d=Math.floor((e-h)/l/10)*l*10;let u=Math.floor((c-d)/Math.pow(10,o)),f=r(t.min,Math.round((h+d+u*Math.pow(10,o))*a)/a);for(;f=10?u=u<15?15:20:u++,u>=20&&(o++,u=2,a=o>=0?1:a),f=Math.round((h+d+u*Math.pow(10,o))*a)/a;const g=r(t.max,f);return s.push({value:g,major:Mo(g),significand:u}),s}class So extends tn{static id="logarithmic";static defaults={ticks:{callback:ae.formatters.logarithmic,major:{enabled:!0}}};constructor(t){super(t),this.start=void 0,this.end=void 0,this._startValue=void 0,this._valueRange=0}parse(t,e){const i=bo.prototype.parse.apply(this,[t,e]);if(0!==i)return a(i)&&i>0?i:null;this._zero=!0}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!0);this.min=a(t)?Math.max(0,t):null,this.max=a(e)?Math.max(0,e):null,this.options.beginAtZero&&(this._zero=!0),this._zero&&this.min!==this._suggestedMin&&!a(this._userMin)&&(this.min=t===vo(this.min,0)?vo(this.min,-1):vo(this.min,0)),this.handleTickRangeOptions()}handleTickRangeOptions(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let i=this.min,s=this.max;const n=e=>i=t?i:e,o=t=>s=e?s:t;i===s&&(i<=0?(n(1),o(10)):(n(vo(i,-1)),o(vo(s,1)))),i<=0&&n(vo(s,-1)),s<=0&&o(vo(i,1)),this.min=i,this.max=s}buildTicks(){const t=this.options,e=ko({min:this._userMin,max:this._userMax},this);return"ticks"===t.bounds&&j(e,this,"value"),t.reverse?(e.reverse(),this.start=this.max,this.end=this.min):(this.start=this.min,this.end=this.max),e}getLabelForValue(t){return void 0===t?"0":ne(t,this.chart.options.locale,this.options.ticks.format)}configure(){const t=this.min;super.configure(),this._startValue=z(t),this._valueRange=z(this.max)-z(t)}getPixelForValue(t){return void 0!==t&&0!==t||(t=this.min),null===t||isNaN(t)?NaN:this.getPixelForDecimal(t===this.min?0:(z(t)-this._startValue)/this._valueRange)}getValueForPixel(t){const e=this.getDecimalForPixel(t);return Math.pow(10,this._startValue+e*this._valueRange)}}function Po(t){const e=t.ticks;if(e.display&&t.display){const t=ki(e.backdropPadding);return l(e.font&&e.font.size,ue.font.size)+t.height}return 0}function Do(t,e,i,s,n){return t===s||t===n?{start:e-i/2,end:e+i/2}:tn?{start:e-i,end:e}:{start:e,end:e+i}}function Co(t){const e={l:t.left+t._padding.left,r:t.right-t._padding.right,t:t.top+t._padding.top,b:t.bottom-t._padding.bottom},i=Object.assign({},e),s=[],o=[],a=t._pointLabels.length,r=t.options.pointLabels,l=r.centerPointLabels?C/a:0;for(let u=0;ue.r&&(r=(s.end-e.r)/o,t.r=Math.max(t.r,e.r+r)),n.starte.b&&(l=(n.end-e.b)/a,t.b=Math.max(t.b,e.b+l))}function Ao(t,e,i){const s=t.drawingArea,{extra:n,additionalAngle:o,padding:a,size:r}=i,l=t.getPointPosition(e,s+n+a,o),h=Math.round(Y(G(l.angle+E))),c=function(t,e,i){90===i||270===i?t-=e/2:(i>270||i<90)&&(t-=e);return t}(l.y,r.h,h),d=function(t){if(0===t||180===t)return"center";if(t<180)return"left";return"right"}(h),u=function(t,e,i){"right"===i?t-=e:"center"===i&&(t-=e/2);return t}(l.x,r.w,d);return{visible:!0,x:l.x,y:c,textAlign:d,left:u,top:c,right:u+r.w,bottom:c+r.h}}function To(t,e){if(!e)return!0;const{left:i,top:s,right:n,bottom:o}=t;return!(Re({x:i,y:s},e)||Re({x:i,y:o},e)||Re({x:n,y:s},e)||Re({x:n,y:o},e))}function Lo(t,e,i){const{left:n,top:o,right:a,bottom:r}=i,{backdropColor:l}=e;if(!s(l)){const i=wi(e.borderRadius),s=ki(e.backdropPadding);t.fillStyle=l;const h=n-s.left,c=o-s.top,d=a-n+s.width,u=r-o+s.height;Object.values(i).some((t=>0!==t))?(t.beginPath(),He(t,{x:h,y:c,w:d,h:u,radius:i}),t.fill()):t.fillRect(h,c,d,u)}}function Eo(t,e,i,s){const{ctx:n}=t;if(i)n.arc(t.xCenter,t.yCenter,e,0,O);else{let i=t.getPointPosition(0,e);n.moveTo(i.x,i.y);for(let o=1;ot,padding:5,centerPointLabels:!1}};static defaultRoutes={"angleLines.color":"borderColor","pointLabels.color":"color","ticks.color":"color"};static descriptors={angleLines:{_fallback:"grid"}};constructor(t){super(t),this.xCenter=void 0,this.yCenter=void 0,this.drawingArea=void 0,this._pointLabels=[],this._pointLabelItems=[]}setDimensions(){const t=this._padding=ki(Po(this.options)/2),e=this.width=this.maxWidth-t.width,i=this.height=this.maxHeight-t.height;this.xCenter=Math.floor(this.left+e/2+t.left),this.yCenter=Math.floor(this.top+i/2+t.top),this.drawingArea=Math.floor(Math.min(e,i)/2)}determineDataLimits(){const{min:t,max:e}=this.getMinMax(!1);this.min=a(t)&&!isNaN(t)?t:0,this.max=a(e)&&!isNaN(e)?e:0,this.handleTickRangeOptions()}computeTickLimit(){return Math.ceil(this.drawingArea/Po(this.options))}generateTickLabels(t){bo.prototype.generateTickLabels.call(this,t),this._pointLabels=this.getLabels().map(((t,e)=>{const i=d(this.options.pointLabels.callback,[t,e],this);return i||0===i?i:""})).filter(((t,e)=>this.chart.getDataVisibility(e)))}fit(){const t=this.options;t.display&&t.pointLabels.display?Co(this):this.setCenterPoint(0,0,0,0)}setCenterPoint(t,e,i,s){this.xCenter+=Math.floor((t-e)/2),this.yCenter+=Math.floor((i-s)/2),this.drawingArea-=Math.min(this.drawingArea/2,Math.max(t,e,i,s))}getIndexAngle(t){return G(t*(O/(this._pointLabels.length||1))+$(this.options.startAngle||0))}getDistanceFromCenterForValue(t){if(s(t))return NaN;const e=this.drawingArea/(this.max-this.min);return this.options.reverse?(this.max-t)*e:(t-this.min)*e}getValueForDistanceFromCenter(t){if(s(t))return NaN;const e=t/(this.drawingArea/(this.max-this.min));return this.options.reverse?this.max-e:this.min+e}getPointLabelContext(t){const e=this._pointLabels||[];if(t>=0&&t=0;n--){const e=t._pointLabelItems[n];if(!e.visible)continue;const o=s.setContext(t.getPointLabelContext(n));Lo(i,o,e);const a=Si(o.font),{x:r,y:l,textAlign:h}=e;Ne(i,t._pointLabels[n],r,l+a.lineHeight/2,a,{color:o.color,textAlign:h,textBaseline:"middle"})}}(this,o),s.display&&this.ticks.forEach(((t,e)=>{if(0!==e||0===e&&this.min<0){r=this.getDistanceFromCenterForValue(t.value);const i=this.getContext(e),a=s.setContext(i),l=n.setContext(i);!function(t,e,i,s,n){const o=t.ctx,a=e.circular,{color:r,lineWidth:l}=e;!a&&!s||!r||!l||i<0||(o.save(),o.strokeStyle=r,o.lineWidth=l,o.setLineDash(n.dash||[]),o.lineDashOffset=n.dashOffset,o.beginPath(),Eo(t,i,a,s),o.closePath(),o.stroke(),o.restore())}(this,a,r,o,l)}})),i.display){for(t.save(),a=o-1;a>=0;a--){const s=i.setContext(this.getPointLabelContext(a)),{color:n,lineWidth:o}=s;o&&n&&(t.lineWidth=o,t.strokeStyle=n,t.setLineDash(s.borderDash),t.lineDashOffset=s.borderDashOffset,r=this.getDistanceFromCenterForValue(e.reverse?this.min:this.max),l=this.getPointPosition(a,r),t.beginPath(),t.moveTo(this.xCenter,this.yCenter),t.lineTo(l.x,l.y),t.stroke())}t.restore()}}drawBorder(){}drawLabels(){const t=this.ctx,e=this.options,i=e.ticks;if(!i.display)return;const s=this.getIndexAngle(0);let n,o;t.save(),t.translate(this.xCenter,this.yCenter),t.rotate(s),t.textAlign="center",t.textBaseline="middle",this.ticks.forEach(((s,a)=>{if(0===a&&this.min>=0&&!e.reverse)return;const r=i.setContext(this.getContext(a)),l=Si(r.font);if(n=this.getDistanceFromCenterForValue(this.ticks[a].value),r.showLabelBackdrop){t.font=l.string,o=t.measureText(s.label).width,t.fillStyle=r.backdropColor;const e=ki(r.backdropPadding);t.fillRect(-o/2-e.left,-n-l.size/2-e.top,o+e.width,l.size+e.height)}Ne(t,s.label,0,-n,l,{color:r.color,strokeColor:r.textStrokeColor,strokeWidth:r.textStrokeWidth})})),t.restore()}drawTitle(){}}const Io={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},zo=Object.keys(Io);function Fo(t,e){return t-e}function Vo(t,e){if(s(e))return null;const i=t._adapter,{parser:n,round:o,isoWeekday:r}=t._parseOpts;let l=e;return"function"==typeof n&&(l=n(l)),a(l)||(l="string"==typeof n?i.parse(l,n):i.parse(l)),null===l?null:(o&&(l="week"!==o||!N(r)&&!0!==r?i.startOf(l,o):i.startOf(l,"isoWeek",r)),+l)}function Bo(t,e,i,s){const n=zo.length;for(let o=zo.indexOf(t);o=e?i[s]:i[n]]=!0}}else t[e]=!0}function No(t,e,i){const s=[],n={},o=e.length;let a,r;for(a=0;a=0&&(e[l].major=!0);return e}(t,s,n,i):s}class Ho extends tn{static id="time";static defaults={bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{source:"auto",callback:!1,major:{enabled:!1}}};constructor(t){super(t),this._cache={data:[],labels:[],all:[]},this._unit="day",this._majorUnit=void 0,this._offsets={},this._normalized=!1,this._parseOpts=void 0}init(t,e={}){const i=t.time||(t.time={}),s=this._adapter=new In._date(t.adapters.date);s.init(e),b(i.displayFormats,s.formats()),this._parseOpts={parser:i.parser,round:i.round,isoWeekday:i.isoWeekday},super.init(t),this._normalized=e.normalized}parse(t,e){return void 0===t?null:Vo(this,t)}beforeLayout(){super.beforeLayout(),this._cache={data:[],labels:[],all:[]}}determineDataLimits(){const t=this.options,e=this._adapter,i=t.time.unit||"day";let{min:s,max:n,minDefined:o,maxDefined:r}=this.getUserBounds();function l(t){o||isNaN(t.min)||(s=Math.min(s,t.min)),r||isNaN(t.max)||(n=Math.max(n,t.max))}o&&r||(l(this._getLabelBounds()),"ticks"===t.bounds&&"labels"===t.ticks.source||l(this.getMinMax(!1))),s=a(s)&&!isNaN(s)?s:+e.startOf(Date.now(),i),n=a(n)&&!isNaN(n)?n:+e.endOf(Date.now(),i)+1,this.min=Math.min(s,n-1),this.max=Math.max(s+1,n)}_getLabelBounds(){const t=this.getLabelTimestamps();let e=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;return t.length&&(e=t[0],i=t[t.length-1]),{min:e,max:i}}buildTicks(){const t=this.options,e=t.time,i=t.ticks,s="labels"===i.source?this.getLabelTimestamps():this._generate();"ticks"===t.bounds&&s.length&&(this.min=this._userMin||s[0],this.max=this._userMax||s[s.length-1]);const n=this.min,o=nt(s,n,this.max);return this._unit=e.unit||(i.autoSkip?Bo(e.minUnit,this.min,this.max,this._getLabelCapacity(n)):function(t,e,i,s,n){for(let o=zo.length-1;o>=zo.indexOf(i);o--){const i=zo[o];if(Io[i].common&&t._adapter.diff(n,s,i)>=e-1)return i}return zo[i?zo.indexOf(i):0]}(this,o.length,e.minUnit,this.min,this.max)),this._majorUnit=i.major.enabled&&"year"!==this._unit?function(t){for(let e=zo.indexOf(t)+1,i=zo.length;e+t.value)))}initOffsets(t=[]){let e,i,s=0,n=0;this.options.offset&&t.length&&(e=this.getDecimalForValue(t[0]),s=1===t.length?1-e:(this.getDecimalForValue(t[1])-e)/2,i=this.getDecimalForValue(t[t.length-1]),n=1===t.length?i:(i-this.getDecimalForValue(t[t.length-2]))/2);const o=t.length<3?.5:.25;s=Z(s,0,o),n=Z(n,0,o),this._offsets={start:s,end:n,factor:1/(s+1+n)}}_generate(){const t=this._adapter,e=this.min,i=this.max,s=this.options,n=s.time,o=n.unit||Bo(n.minUnit,e,i,this._getLabelCapacity(e)),a=l(s.ticks.stepSize,1),r="week"===o&&n.isoWeekday,h=N(r)||!0===r,c={};let d,u,f=e;if(h&&(f=+t.startOf(f,"isoWeek",r)),f=+t.startOf(f,h?"day":o),t.diff(i,e,o)>1e5*a)throw new Error(e+" and "+i+" are too far apart with stepSize of "+a+" "+o);const g="data"===s.ticks.source&&this.getDataTimestamps();for(d=f,u=0;d+t))}getLabelForValue(t){const e=this._adapter,i=this.options.time;return i.tooltipFormat?e.format(t,i.tooltipFormat):e.format(t,i.displayFormats.datetime)}format(t,e){const i=this.options.time.displayFormats,s=this._unit,n=e||i[s];return this._adapter.format(t,n)}_tickFormatFunction(t,e,i,s){const n=this.options,o=n.ticks.callback;if(o)return d(o,[t,e,i],this);const a=n.time.displayFormats,r=this._unit,l=this._majorUnit,h=r&&a[r],c=l&&a[l],u=i[e],f=l&&c&&u&&u.major;return this._adapter.format(t,s||(f?c:h))}generateTickLabels(t){let e,i,s;for(e=0,i=t.length;e0?a:1}getDataTimestamps(){let t,e,i=this._cache.data||[];if(i.length)return i;const s=this.getMatchingVisibleMetas();if(this._normalized&&s.length)return this._cache.data=s[0].controller.getAllParsedValues(this);for(t=0,e=s.length;t=t[r].pos&&e<=t[l].pos&&({lo:r,hi:l}=it(t,"pos",e)),({pos:s,time:o}=t[r]),({pos:n,time:a}=t[l])):(e>=t[r].time&&e<=t[l].time&&({lo:r,hi:l}=it(t,"time",e)),({time:s,pos:o}=t[r]),({time:n,pos:a}=t[l]));const h=n-s;return h?o+(a-o)*(e-s)/h:o}var $o=Object.freeze({__proto__:null,CategoryScale:class extends tn{static id="category";static defaults={ticks:{callback:mo}};constructor(t){super(t),this._startValue=void 0,this._valueRange=0,this._addedLabels=[]}init(t){const e=this._addedLabels;if(e.length){const t=this.getLabels();for(const{index:i,label:s}of e)t[i]===s&&t.splice(i,1);this._addedLabels=[]}super.init(t)}parse(t,e){if(s(t))return null;const i=this.getLabels();return((t,e)=>null===t?null:Z(Math.round(t),0,e))(e=isFinite(e)&&i[e]===t?e:po(i,t,l(e,t),this._addedLabels),i.length-1)}determineDataLimits(){const{minDefined:t,maxDefined:e}=this.getUserBounds();let{min:i,max:s}=this.getMinMax(!0);"ticks"===this.options.bounds&&(t||(i=0),e||(s=this.getLabels().length-1)),this.min=i,this.max=s}buildTicks(){const t=this.min,e=this.max,i=this.options.offset,s=[];let n=this.getLabels();n=0===t&&e===n.length-1?n:n.slice(t,e+1),this._valueRange=Math.max(n.length-(i?0:1),1),this._startValue=this.min-(i?.5:0);for(let i=t;i<=e;i++)s.push({value:i});return s}getLabelForValue(t){return mo.call(this,t)}configure(){super.configure(),this.isHorizontal()||(this._reversePixels=!this._reversePixels)}getPixelForValue(t){return"number"!=typeof t&&(t=this.parse(t)),null===t?NaN:this.getPixelForDecimal((t-this._startValue)/this._valueRange)}getPixelForTick(t){const e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t].value)}getValueForPixel(t){return Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange)}getBasePixel(){return this.bottom}},LinearScale:_o,LogarithmicScale:So,RadialLinearScale:Ro,TimeScale:Ho,TimeSeriesScale:class extends Ho{static id="timeseries";static defaults=Ho.defaults;constructor(t){super(t),this._table=[],this._minPos=void 0,this._tableRange=void 0}initOffsets(){const t=this._getTimestampsForTable(),e=this._table=this.buildLookupTable(t);this._minPos=jo(e,this.min),this._tableRange=jo(e,this.max)-this._minPos,super.initOffsets(t)}buildLookupTable(t){const{min:e,max:i}=this,s=[],n=[];let o,a,r,l,h;for(o=0,a=t.length;o=e&&l<=i&&s.push(l);if(s.length<2)return[{time:e,pos:0},{time:i,pos:1}];for(o=0,a=s.length;ot-e))}_getTimestampsForTable(){let t=this._cache.all||[];if(t.length)return t;const e=this.getDataTimestamps(),i=this.getLabelTimestamps();return t=e.length&&i.length?this.normalize(e.concat(i)):e.length?e:i,t=this._cache.all=t,t}getDecimalForValue(t){return(jo(this._table,t)-this._minPos)/this._tableRange}getValueForPixel(t){const e=this._offsets,i=this.getDecimalForPixel(t)/e.factor-e.end;return jo(this._table,i*this._tableRange+this._minPos,!0)}}});const Yo=["rgb(54, 162, 235)","rgb(255, 99, 132)","rgb(255, 159, 64)","rgb(255, 205, 86)","rgb(75, 192, 192)","rgb(153, 102, 255)","rgb(201, 203, 207)"],Uo=Yo.map((t=>t.replace("rgb(","rgba(").replace(")",", 0.5)")));function Xo(t){return Yo[t%Yo.length]}function qo(t){return Uo[t%Uo.length]}function Ko(t){let e=0;return(i,s)=>{const n=t.getDatasetMeta(s).controller;n instanceof $n?e=function(t,e){return t.backgroundColor=t.data.map((()=>Xo(e++))),e}(i,e):n instanceof Yn?e=function(t,e){return t.backgroundColor=t.data.map((()=>qo(e++))),e}(i,e):n&&(e=function(t,e){return t.borderColor=Xo(e),t.backgroundColor=qo(e),++e}(i,e))}}function Go(t){let e;for(e in t)if(t[e].borderColor||t[e].backgroundColor)return!0;return!1}var Jo={id:"colors",defaults:{enabled:!0,forceOverride:!1},beforeLayout(t,e,i){if(!i.enabled)return;const{data:{datasets:s},options:n}=t.config,{elements:o}=n,a=Go(s)||(r=n)&&(r.borderColor||r.backgroundColor)||o&&Go(o)||"rgba(0,0,0,0.1)"!==ue.borderColor||"rgba(0,0,0,0.1)"!==ue.backgroundColor;var r;if(!i.forceOverride&&a)return;const l=Ko(t);s.forEach(l)}};function Zo(t){if(t._decimated){const e=t._data;delete t._decimated,delete t._data,Object.defineProperty(t,"data",{configurable:!0,enumerable:!0,writable:!0,value:e})}}function Qo(t){t.data.datasets.forEach((t=>{Zo(t)}))}var ta={id:"decimation",defaults:{algorithm:"min-max",enabled:!1},beforeElementsUpdate:(t,e,i)=>{if(!i.enabled)return void Qo(t);const n=t.width;t.data.datasets.forEach(((e,o)=>{const{_data:a,indexAxis:r}=e,l=t.getDatasetMeta(o),h=a||e.data;if("y"===Pi([r,t.options.indexAxis]))return;if(!l.controller.supportsDecimation)return;const c=t.scales[l.xAxisID];if("linear"!==c.type&&"time"!==c.type)return;if(t.options.parsing)return;let{start:d,count:u}=function(t,e){const i=e.length;let s,n=0;const{iScale:o}=t,{min:a,max:r,minDefined:l,maxDefined:h}=o.getUserBounds();return l&&(n=Z(it(e,o.axis,a).lo,0,i-1)),s=h?Z(it(e,o.axis,r).hi+1,n,i)-n:i-n,{start:n,count:s}}(l,h);if(u<=(i.threshold||4*n))return void Zo(e);let f;switch(s(a)&&(e._data=h,delete e.data,Object.defineProperty(e,"data",{configurable:!0,enumerable:!0,get:function(){return this._decimated},set:function(t){this._data=t}})),i.algorithm){case"lttb":f=function(t,e,i,s,n){const o=n.samples||s;if(o>=i)return t.slice(e,e+i);const a=[],r=(i-2)/(o-2);let l=0;const h=e+i-1;let c,d,u,f,g,p=e;for(a[l++]=t[p],c=0;cu&&(u=f,d=t[s],g=s);a[l++]=d,p=g}return a[l++]=t[h],a}(h,d,u,n,i);break;case"min-max":f=function(t,e,i,n){let o,a,r,l,h,c,d,u,f,g,p=0,m=0;const x=[],b=e+i-1,_=t[e].x,y=t[b].x-_;for(o=e;og&&(g=l,d=o),p=(m*p+a.x)/++m;else{const i=o-1;if(!s(c)&&!s(d)){const e=Math.min(c,d),s=Math.max(c,d);e!==u&&e!==i&&x.push({...t[e],x:p}),s!==u&&s!==i&&x.push({...t[s],x:p})}o>0&&i!==u&&x.push(t[i]),x.push(a),h=e,m=0,f=g=l,c=d=u=o}}return x}(h,d,u,n);break;default:throw new Error(`Unsupported decimation algorithm '${i.algorithm}'`)}e._decimated=f}))},destroy(t){Qo(t)}};function ea(t,e,i,s){if(s)return;let n=e[t],o=i[t];return"angle"===t&&(n=G(n),o=G(o)),{property:t,start:n,end:o}}function ia(t,e,i){for(;e>t;e--){const t=i[e];if(!isNaN(t.x)&&!isNaN(t.y))break}return e}function sa(t,e,i,s){return t&&e?s(t[i],e[i]):t?t[i]:e?e[i]:0}function na(t,e){let i=[],s=!1;return n(t)?(s=!0,i=t):i=function(t,e){const{x:i=null,y:s=null}=t||{},n=e.points,o=[];return e.segments.forEach((({start:t,end:e})=>{e=ia(t,e,n);const a=n[t],r=n[e];null!==s?(o.push({x:a.x,y:s}),o.push({x:r.x,y:s})):null!==i&&(o.push({x:i,y:a.y}),o.push({x:i,y:r.y}))})),o}(t,e),i.length?new oo({points:i,options:{tension:0},_loop:s,_fullLoop:s}):null}function oa(t){return t&&!1!==t.fill}function aa(t,e,i){let s=t[e].fill;const n=[e];let o;if(!i)return s;for(;!1!==s&&-1===n.indexOf(s);){if(!a(s))return s;if(o=t[s],!o)return!1;if(o.visible)return s;n.push(s),s=o.fill}return!1}function ra(t,e,i){const s=function(t){const e=t.options,i=e.fill;let s=l(i&&i.target,i);void 0===s&&(s=!!e.backgroundColor);if(!1===s||null===s)return!1;if(!0===s)return"origin";return s}(t);if(o(s))return!isNaN(s.value)&&s;let n=parseFloat(s);return a(n)&&Math.floor(n)===n?function(t,e,i,s){"-"!==t&&"+"!==t||(i=e+i);if(i===e||i<0||i>=s)return!1;return i}(s[0],e,n,i):["origin","start","end","stack","shape"].indexOf(s)>=0&&s}function la(t,e,i){const s=[];for(let n=0;n=0;--e){const i=n[e].$filler;i&&(i.line.updateControlPoints(o,i.axis),s&&i.fill&&ua(t.ctx,i,o))}},beforeDatasetsDraw(t,e,i){if("beforeDatasetsDraw"!==i.drawTime)return;const s=t.getSortedVisibleDatasetMetas();for(let e=s.length-1;e>=0;--e){const i=s[e].$filler;oa(i)&&ua(t.ctx,i,t.chartArea)}},beforeDatasetDraw(t,e,i){const s=e.meta.$filler;oa(s)&&"beforeDatasetDraw"===i.drawTime&&ua(t.ctx,s,t.chartArea)},defaults:{propagate:!0,drawTime:"beforeDatasetDraw"}};const _a=(t,e)=>{let{boxHeight:i=e,boxWidth:s=e}=t;return t.usePointStyle&&(i=Math.min(i,e),s=t.pointStyleWidth||Math.min(s,e)),{boxWidth:s,boxHeight:i,itemHeight:Math.max(e,i)}};class ya extends $s{constructor(t){super(),this._added=!1,this.legendHitBoxes=[],this._hoveredItem=null,this.doughnutMode=!1,this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this.legendItems=void 0,this.columnSizes=void 0,this.lineWidths=void 0,this.maxHeight=void 0,this.maxWidth=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.height=void 0,this.width=void 0,this._margins=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e,i){this.maxWidth=t,this.maxHeight=e,this._margins=i,this.setDimensions(),this.buildLabels(),this.fit()}setDimensions(){this.isHorizontal()?(this.width=this.maxWidth,this.left=this._margins.left,this.right=this.width):(this.height=this.maxHeight,this.top=this._margins.top,this.bottom=this.height)}buildLabels(){const t=this.options.labels||{};let e=d(t.generateLabels,[this.chart],this)||[];t.filter&&(e=e.filter((e=>t.filter(e,this.chart.data)))),t.sort&&(e=e.sort(((e,i)=>t.sort(e,i,this.chart.data)))),this.options.reverse&&e.reverse(),this.legendItems=e}fit(){const{options:t,ctx:e}=this;if(!t.display)return void(this.width=this.height=0);const i=t.labels,s=Si(i.font),n=s.size,o=this._computeTitleHeight(),{boxWidth:a,itemHeight:r}=_a(i,n);let l,h;e.font=s.string,this.isHorizontal()?(l=this.maxWidth,h=this._fitRows(o,n,a,r)+10):(h=this.maxHeight,l=this._fitCols(o,s,a,r)+10),this.width=Math.min(l,t.maxWidth||this.maxWidth),this.height=Math.min(h,t.maxHeight||this.maxHeight)}_fitRows(t,e,i,s){const{ctx:n,maxWidth:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.lineWidths=[0],h=s+a;let c=t;n.textAlign="left",n.textBaseline="middle";let d=-1,u=-h;return this.legendItems.forEach(((t,f)=>{const g=i+e/2+n.measureText(t.text).width;(0===f||l[l.length-1]+g+2*a>o)&&(c+=h,l[l.length-(f>0?0:1)]=0,u+=h,d++),r[f]={left:0,top:u,row:d,width:g,height:s},l[l.length-1]+=g+a})),c}_fitCols(t,e,i,s){const{ctx:n,maxHeight:o,options:{labels:{padding:a}}}=this,r=this.legendHitBoxes=[],l=this.columnSizes=[],h=o-t;let c=a,d=0,u=0,f=0,g=0;return this.legendItems.forEach(((t,o)=>{const{itemWidth:p,itemHeight:m}=function(t,e,i,s,n){const o=function(t,e,i,s){let n=t.text;n&&"string"!=typeof n&&(n=n.reduce(((t,e)=>t.length>e.length?t:e)));return e+i.size/2+s.measureText(n).width}(s,t,e,i),a=function(t,e,i){let s=t;"string"!=typeof e.text&&(s=va(e,i));return s}(n,s,e.lineHeight);return{itemWidth:o,itemHeight:a}}(i,e,n,t,s);o>0&&u+m+2*a>h&&(c+=d+a,l.push({width:d,height:u}),f+=d+a,g++,d=u=0),r[o]={left:f,top:u,col:g,width:p,height:m},d=Math.max(d,p),u+=m+a})),c+=d,l.push({width:d,height:u}),c}adjustHitBoxes(){if(!this.options.display)return;const t=this._computeTitleHeight(),{legendHitBoxes:e,options:{align:i,labels:{padding:s},rtl:n}}=this,o=Oi(n,this.left,this.width);if(this.isHorizontal()){let n=0,a=ft(i,this.left+s,this.right-this.lineWidths[n]);for(const r of e)n!==r.row&&(n=r.row,a=ft(i,this.left+s,this.right-this.lineWidths[n])),r.top+=this.top+t+s,r.left=o.leftForLtr(o.x(a),r.width),a+=r.width+s}else{let n=0,a=ft(i,this.top+t+s,this.bottom-this.columnSizes[n].height);for(const r of e)r.col!==n&&(n=r.col,a=ft(i,this.top+t+s,this.bottom-this.columnSizes[n].height)),r.top=a,r.left+=this.left+s,r.left=o.leftForLtr(o.x(r.left),r.width),a+=r.height+s}}isHorizontal(){return"top"===this.options.position||"bottom"===this.options.position}draw(){if(this.options.display){const t=this.ctx;Ie(t,this),this._draw(),ze(t)}}_draw(){const{options:t,columnSizes:e,lineWidths:i,ctx:s}=this,{align:n,labels:o}=t,a=ue.color,r=Oi(t.rtl,this.left,this.width),h=Si(o.font),{padding:c}=o,d=h.size,u=d/2;let f;this.drawTitle(),s.textAlign=r.textAlign("left"),s.textBaseline="middle",s.lineWidth=.5,s.font=h.string;const{boxWidth:g,boxHeight:p,itemHeight:m}=_a(o,d),x=this.isHorizontal(),b=this._computeTitleHeight();f=x?{x:ft(n,this.left+c,this.right-i[0]),y:this.top+c+b,line:0}:{x:this.left+c,y:ft(n,this.top+b+c,this.bottom-e[0].height),line:0},Ai(this.ctx,t.textDirection);const _=m+c;this.legendItems.forEach(((y,v)=>{s.strokeStyle=y.fontColor,s.fillStyle=y.fontColor;const M=s.measureText(y.text).width,w=r.textAlign(y.textAlign||(y.textAlign=o.textAlign)),k=g+u+M;let S=f.x,P=f.y;r.setWidth(this.width),x?v>0&&S+k+c>this.right&&(P=f.y+=_,f.line++,S=f.x=ft(n,this.left+c,this.right-i[f.line])):v>0&&P+_>this.bottom&&(S=f.x=S+e[f.line].width+c,f.line++,P=f.y=ft(n,this.top+b+c,this.bottom-e[f.line].height));if(function(t,e,i){if(isNaN(g)||g<=0||isNaN(p)||p<0)return;s.save();const n=l(i.lineWidth,1);if(s.fillStyle=l(i.fillStyle,a),s.lineCap=l(i.lineCap,"butt"),s.lineDashOffset=l(i.lineDashOffset,0),s.lineJoin=l(i.lineJoin,"miter"),s.lineWidth=n,s.strokeStyle=l(i.strokeStyle,a),s.setLineDash(l(i.lineDash,[])),o.usePointStyle){const a={radius:p*Math.SQRT2/2,pointStyle:i.pointStyle,rotation:i.rotation,borderWidth:n},l=r.xPlus(t,g/2);Ee(s,a,l,e+u,o.pointStyleWidth&&g)}else{const o=e+Math.max((d-p)/2,0),a=r.leftForLtr(t,g),l=wi(i.borderRadius);s.beginPath(),Object.values(l).some((t=>0!==t))?He(s,{x:a,y:o,w:g,h:p,radius:l}):s.rect(a,o,g,p),s.fill(),0!==n&&s.stroke()}s.restore()}(r.x(S),P,y),S=gt(w,S+g+u,x?S+k:this.right,t.rtl),function(t,e,i){Ne(s,i.text,t,e+m/2,h,{strikethrough:i.hidden,textAlign:r.textAlign(i.textAlign)})}(r.x(S),P,y),x)f.x+=k+c;else if("string"!=typeof y.text){const t=h.lineHeight;f.y+=va(y,t)+c}else f.y+=_})),Ti(this.ctx,t.textDirection)}drawTitle(){const t=this.options,e=t.title,i=Si(e.font),s=ki(e.padding);if(!e.display)return;const n=Oi(t.rtl,this.left,this.width),o=this.ctx,a=e.position,r=i.size/2,l=s.top+r;let h,c=this.left,d=this.width;if(this.isHorizontal())d=Math.max(...this.lineWidths),h=this.top+l,c=ft(t.align,c,this.right-d);else{const e=this.columnSizes.reduce(((t,e)=>Math.max(t,e.height)),0);h=l+ft(t.align,this.top,this.bottom-e-t.labels.padding-this._computeTitleHeight())}const u=ft(a,c,c+d);o.textAlign=n.textAlign(ut(a)),o.textBaseline="middle",o.strokeStyle=e.color,o.fillStyle=e.color,o.font=i.string,Ne(o,e.text,u,h,i)}_computeTitleHeight(){const t=this.options.title,e=Si(t.font),i=ki(t.padding);return t.display?e.lineHeight+i.height:0}_getLegendItemAt(t,e){let i,s,n;if(tt(t,this.left,this.right)&&tt(e,this.top,this.bottom))for(n=this.legendHitBoxes,i=0;it.chart.options.color,boxWidth:40,padding:10,generateLabels(t){const e=t.data.datasets,{labels:{usePointStyle:i,pointStyle:s,textAlign:n,color:o,useBorderRadius:a,borderRadius:r}}=t.legend.options;return t._getSortedDatasetMetas().map((t=>{const l=t.controller.getStyle(i?0:void 0),h=ki(l.borderWidth);return{text:e[t.index].label,fillStyle:l.backgroundColor,fontColor:o,hidden:!t.visible,lineCap:l.borderCapStyle,lineDash:l.borderDash,lineDashOffset:l.borderDashOffset,lineJoin:l.borderJoinStyle,lineWidth:(h.width+h.height)/4,strokeStyle:l.borderColor,pointStyle:s||l.pointStyle,rotation:l.rotation,textAlign:n||l.textAlign,borderRadius:a&&(r||l.borderRadius),datasetIndex:t.index}}),this)}},title:{color:t=>t.chart.options.color,display:!1,position:"center",text:""}},descriptors:{_scriptable:t=>!t.startsWith("on"),labels:{_scriptable:t=>!["generateLabels","filter","sort"].includes(t)}}};class wa extends $s{constructor(t){super(),this.chart=t.chart,this.options=t.options,this.ctx=t.ctx,this._padding=void 0,this.top=void 0,this.bottom=void 0,this.left=void 0,this.right=void 0,this.width=void 0,this.height=void 0,this.position=void 0,this.weight=void 0,this.fullSize=void 0}update(t,e){const i=this.options;if(this.left=0,this.top=0,!i.display)return void(this.width=this.height=this.right=this.bottom=0);this.width=this.right=t,this.height=this.bottom=e;const s=n(i.text)?i.text.length:1;this._padding=ki(i.padding);const o=s*Si(i.font).lineHeight+this._padding.height;this.isHorizontal()?this.height=o:this.width=o}isHorizontal(){const t=this.options.position;return"top"===t||"bottom"===t}_drawArgs(t){const{top:e,left:i,bottom:s,right:n,options:o}=this,a=o.align;let r,l,h,c=0;return this.isHorizontal()?(l=ft(a,i,n),h=e+t,r=n-i):("left"===o.position?(l=i+t,h=ft(a,s,e),c=-.5*C):(l=n-t,h=ft(a,e,s),c=.5*C),r=s-e),{titleX:l,titleY:h,maxWidth:r,rotation:c}}draw(){const t=this.ctx,e=this.options;if(!e.display)return;const i=Si(e.font),s=i.lineHeight/2+this._padding.top,{titleX:n,titleY:o,maxWidth:a,rotation:r}=this._drawArgs(s);Ne(t,e.text,0,0,i,{color:e.color,maxWidth:a,rotation:r,textAlign:ut(e.align),textBaseline:"middle",translation:[n,o]})}}var ka={id:"title",_element:wa,start(t,e,i){!function(t,e){const i=new wa({ctx:t.ctx,options:e,chart:t});ls.configure(t,i,e),ls.addBox(t,i),t.titleBlock=i}(t,i)},stop(t){const e=t.titleBlock;ls.removeBox(t,e),delete t.titleBlock},beforeUpdate(t,e,i){const s=t.titleBlock;ls.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"bold"},fullSize:!0,padding:10,position:"top",text:"",weight:2e3},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Sa=new WeakMap;var Pa={id:"subtitle",start(t,e,i){const s=new wa({ctx:t.ctx,options:i,chart:t});ls.configure(t,s,i),ls.addBox(t,s),Sa.set(t,s)},stop(t){ls.removeBox(t,Sa.get(t)),Sa.delete(t)},beforeUpdate(t,e,i){const s=Sa.get(t);ls.configure(t,s,i),s.options=i},defaults:{align:"center",display:!1,font:{weight:"normal"},fullSize:!0,padding:0,position:"top",text:"",weight:1500},defaultRoutes:{color:"color"},descriptors:{_scriptable:!0,_indexable:!1}};const Da={average(t){if(!t.length)return!1;let e,i,s=new Set,n=0,o=0;for(e=0,i=t.length;et+e))/s.size,y:n/o}},nearest(t,e){if(!t.length)return!1;let i,s,n,o=e.x,a=e.y,r=Number.POSITIVE_INFINITY;for(i=0,s=t.length;i-1?t.split("\n"):t}function Aa(t,e){const{element:i,datasetIndex:s,index:n}=e,o=t.getDatasetMeta(s).controller,{label:a,value:r}=o.getLabelAndValue(n);return{chart:t,label:a,parsed:o.getParsed(n),raw:t.data.datasets[s].data[n],formattedValue:r,dataset:o.getDataset(),dataIndex:n,datasetIndex:s,element:i}}function Ta(t,e){const i=t.chart.ctx,{body:s,footer:n,title:o}=t,{boxWidth:a,boxHeight:r}=e,l=Si(e.bodyFont),h=Si(e.titleFont),c=Si(e.footerFont),d=o.length,f=n.length,g=s.length,p=ki(e.padding);let m=p.height,x=0,b=s.reduce(((t,e)=>t+e.before.length+e.lines.length+e.after.length),0);if(b+=t.beforeBody.length+t.afterBody.length,d&&(m+=d*h.lineHeight+(d-1)*e.titleSpacing+e.titleMarginBottom),b){m+=g*(e.displayColors?Math.max(r,l.lineHeight):l.lineHeight)+(b-g)*l.lineHeight+(b-1)*e.bodySpacing}f&&(m+=e.footerMarginTop+f*c.lineHeight+(f-1)*e.footerSpacing);let _=0;const y=function(t){x=Math.max(x,i.measureText(t).width+_)};return i.save(),i.font=h.string,u(t.title,y),i.font=l.string,u(t.beforeBody.concat(t.afterBody),y),_=e.displayColors?a+2+e.boxPadding:0,u(s,(t=>{u(t.before,y),u(t.lines,y),u(t.after,y)})),_=0,i.font=c.string,u(t.footer,y),i.restore(),x+=p.width,{width:x,height:m}}function La(t,e,i,s){const{x:n,width:o}=i,{width:a,chartArea:{left:r,right:l}}=t;let h="center";return"center"===s?h=n<=(r+l)/2?"left":"right":n<=o/2?h="left":n>=a-o/2&&(h="right"),function(t,e,i,s){const{x:n,width:o}=s,a=i.caretSize+i.caretPadding;return"left"===t&&n+o+a>e.width||"right"===t&&n-o-a<0||void 0}(h,t,e,i)&&(h="center"),h}function Ea(t,e,i){const s=i.yAlign||e.yAlign||function(t,e){const{y:i,height:s}=e;return it.height-s/2?"bottom":"center"}(t,i);return{xAlign:i.xAlign||e.xAlign||La(t,e,i,s),yAlign:s}}function Ra(t,e,i,s){const{caretSize:n,caretPadding:o,cornerRadius:a}=t,{xAlign:r,yAlign:l}=i,h=n+o,{topLeft:c,topRight:d,bottomLeft:u,bottomRight:f}=wi(a);let g=function(t,e){let{x:i,width:s}=t;return"right"===e?i-=s:"center"===e&&(i-=s/2),i}(e,r);const p=function(t,e,i){let{y:s,height:n}=t;return"top"===e?s+=i:s-="bottom"===e?n+i:n/2,s}(e,l,h);return"center"===l?"left"===r?g+=h:"right"===r&&(g-=h):"left"===r?g-=Math.max(c,u)+n:"right"===r&&(g+=Math.max(d,f)+n),{x:Z(g,0,s.width-e.width),y:Z(p,0,s.height-e.height)}}function Ia(t,e,i){const s=ki(i.padding);return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-s.right:t.x+s.left}function za(t){return Ca([],Oa(t))}function Fa(t,e){const i=e&&e.dataset&&e.dataset.tooltip&&e.dataset.tooltip.callbacks;return i?t.override(i):t}const Va={beforeTitle:e,title(t){if(t.length>0){const e=t[0],i=e.chart.data.labels,s=i?i.length:0;if(this&&this.options&&"dataset"===this.options.mode)return e.dataset.label||"";if(e.label)return e.label;if(s>0&&e.dataIndex{const e={before:[],lines:[],after:[]},n=Fa(i,t);Ca(e.before,Oa(Ba(n,"beforeLabel",this,t))),Ca(e.lines,Ba(n,"label",this,t)),Ca(e.after,Oa(Ba(n,"afterLabel",this,t))),s.push(e)})),s}getAfterBody(t,e){return za(Ba(e.callbacks,"afterBody",this,t))}getFooter(t,e){const{callbacks:i}=e,s=Ba(i,"beforeFooter",this,t),n=Ba(i,"footer",this,t),o=Ba(i,"afterFooter",this,t);let a=[];return a=Ca(a,Oa(s)),a=Ca(a,Oa(n)),a=Ca(a,Oa(o)),a}_createItems(t){const e=this._active,i=this.chart.data,s=[],n=[],o=[];let a,r,l=[];for(a=0,r=e.length;at.filter(e,s,n,i)))),t.itemSort&&(l=l.sort(((e,s)=>t.itemSort(e,s,i)))),u(l,(e=>{const i=Fa(t.callbacks,e);s.push(Ba(i,"labelColor",this,e)),n.push(Ba(i,"labelPointStyle",this,e)),o.push(Ba(i,"labelTextColor",this,e))})),this.labelColors=s,this.labelPointStyles=n,this.labelTextColors=o,this.dataPoints=l,l}update(t,e){const i=this.options.setContext(this.getContext()),s=this._active;let n,o=[];if(s.length){const t=Da[i.position].call(this,s,this._eventPosition);o=this._createItems(i),this.title=this.getTitle(o,i),this.beforeBody=this.getBeforeBody(o,i),this.body=this.getBody(o,i),this.afterBody=this.getAfterBody(o,i),this.footer=this.getFooter(o,i);const e=this._size=Ta(this,i),a=Object.assign({},t,e),r=Ea(this.chart,i,a),l=Ra(i,a,r,this.chart);this.xAlign=r.xAlign,this.yAlign=r.yAlign,n={opacity:1,x:l.x,y:l.y,width:e.width,height:e.height,caretX:t.x,caretY:t.y}}else 0!==this.opacity&&(n={opacity:0});this._tooltipItems=o,this.$context=void 0,n&&this._resolveAnimations().update(this,n),t&&i.external&&i.external.call(this,{chart:this.chart,tooltip:this,replay:e})}drawCaret(t,e,i,s){const n=this.getCaretPosition(t,i,s);e.lineTo(n.x1,n.y1),e.lineTo(n.x2,n.y2),e.lineTo(n.x3,n.y3)}getCaretPosition(t,e,i){const{xAlign:s,yAlign:n}=this,{caretSize:o,cornerRadius:a}=i,{topLeft:r,topRight:l,bottomLeft:h,bottomRight:c}=wi(a),{x:d,y:u}=t,{width:f,height:g}=e;let p,m,x,b,_,y;return"center"===n?(_=u+g/2,"left"===s?(p=d,m=p-o,b=_+o,y=_-o):(p=d+f,m=p+o,b=_-o,y=_+o),x=p):(m="left"===s?d+Math.max(r,h)+o:"right"===s?d+f-Math.max(l,c)-o:this.caretX,"top"===n?(b=u,_=b-o,p=m-o,x=m+o):(b=u+g,_=b+o,p=m+o,x=m-o),y=b),{x1:p,x2:m,x3:x,y1:b,y2:_,y3:y}}drawTitle(t,e,i){const s=this.title,n=s.length;let o,a,r;if(n){const l=Oi(i.rtl,this.x,this.width);for(t.x=Ia(this,i.titleAlign,i),e.textAlign=l.textAlign(i.titleAlign),e.textBaseline="middle",o=Si(i.titleFont),a=i.titleSpacing,e.fillStyle=i.titleColor,e.font=o.string,r=0;r0!==t))?(t.beginPath(),t.fillStyle=n.multiKeyBackground,He(t,{x:e,y:g,w:h,h:l,radius:r}),t.fill(),t.stroke(),t.fillStyle=a.backgroundColor,t.beginPath(),He(t,{x:i,y:g+1,w:h-2,h:l-2,radius:r}),t.fill()):(t.fillStyle=n.multiKeyBackground,t.fillRect(e,g,h,l),t.strokeRect(e,g,h,l),t.fillStyle=a.backgroundColor,t.fillRect(i,g+1,h-2,l-2))}t.fillStyle=this.labelTextColors[i]}drawBody(t,e,i){const{body:s}=this,{bodySpacing:n,bodyAlign:o,displayColors:a,boxHeight:r,boxWidth:l,boxPadding:h}=i,c=Si(i.bodyFont);let d=c.lineHeight,f=0;const g=Oi(i.rtl,this.x,this.width),p=function(i){e.fillText(i,g.x(t.x+f),t.y+d/2),t.y+=d+n},m=g.textAlign(o);let x,b,_,y,v,M,w;for(e.textAlign=o,e.textBaseline="middle",e.font=c.string,t.x=Ia(this,m,i),e.fillStyle=i.bodyColor,u(this.beforeBody,p),f=a&&"right"!==m?"center"===o?l/2+h:l+2+h:0,y=0,M=s.length;y0&&e.stroke()}_updateAnimationTarget(t){const e=this.chart,i=this.$animations,s=i&&i.x,n=i&&i.y;if(s||n){const i=Da[t.position].call(this,this._active,this._eventPosition);if(!i)return;const o=this._size=Ta(this,t),a=Object.assign({},i,this._size),r=Ea(e,t,a),l=Ra(t,a,r,e);s._to===l.x&&n._to===l.y||(this.xAlign=r.xAlign,this.yAlign=r.yAlign,this.width=o.width,this.height=o.height,this.caretX=i.x,this.caretY=i.y,this._resolveAnimations().update(this,l))}}_willRender(){return!!this.opacity}draw(t){const e=this.options.setContext(this.getContext());let i=this.opacity;if(!i)return;this._updateAnimationTarget(e);const s={width:this.width,height:this.height},n={x:this.x,y:this.y};i=Math.abs(i)<.001?0:i;const o=ki(e.padding),a=this.title.length||this.beforeBody.length||this.body.length||this.afterBody.length||this.footer.length;e.enabled&&a&&(t.save(),t.globalAlpha=i,this.drawBackground(n,t,s,e),Ai(t,e.textDirection),n.y+=o.top,this.drawTitle(n,t,e),this.drawBody(n,t,e),this.drawFooter(n,t,e),Ti(t,e.textDirection),t.restore())}getActiveElements(){return this._active||[]}setActiveElements(t,e){const i=this._active,s=t.map((({datasetIndex:t,index:e})=>{const i=this.chart.getDatasetMeta(t);if(!i)throw new Error("Cannot find a dataset at index "+t);return{datasetIndex:t,element:i.data[e],index:e}})),n=!f(i,s),o=this._positionChanged(s,e);(n||o)&&(this._active=s,this._eventPosition=e,this._ignoreReplayEvents=!0,this.update(!0))}handleEvent(t,e,i=!0){if(e&&this._ignoreReplayEvents)return!1;this._ignoreReplayEvents=!1;const s=this.options,n=this._active||[],o=this._getActiveElements(t,n,e,i),a=this._positionChanged(o,t),r=e||!f(o,n)||a;return r&&(this._active=o,(s.enabled||s.external)&&(this._eventPosition={x:t.x,y:t.y},this.update(!0,e))),r}_getActiveElements(t,e,i,s){const n=this.options;if("mouseout"===t.type)return[];if(!s)return e.filter((t=>this.chart.data.datasets[t.datasetIndex]&&void 0!==this.chart.getDatasetMeta(t.datasetIndex).controller.getParsed(t.index)));const o=this.chart.getElementsAtEventForMode(t,n.mode,n,i);return n.reverse&&o.reverse(),o}_positionChanged(t,e){const{caretX:i,caretY:s,options:n}=this,o=Da[n.position].call(this,t,e);return!1!==o&&(i!==o.x||s!==o.y)}}var Na={id:"tooltip",_element:Wa,positioners:Da,afterInit(t,e,i){i&&(t.tooltip=new Wa({chart:t,options:i}))},beforeUpdate(t,e,i){t.tooltip&&t.tooltip.initialize(i)},reset(t,e,i){t.tooltip&&t.tooltip.initialize(i)},afterDraw(t){const e=t.tooltip;if(e&&e._willRender()){const i={tooltip:e};if(!1===t.notifyPlugins("beforeTooltipDraw",{...i,cancelable:!0}))return;e.draw(t.ctx),t.notifyPlugins("afterTooltipDraw",i)}},afterEvent(t,e){if(t.tooltip){const i=e.replay;t.tooltip.handleEvent(e.event,i,e.inChartArea)&&(e.changed=!0)}},defaults:{enabled:!0,external:null,position:"average",backgroundColor:"rgba(0,0,0,0.8)",titleColor:"#fff",titleFont:{weight:"bold"},titleSpacing:2,titleMarginBottom:6,titleAlign:"left",bodyColor:"#fff",bodySpacing:2,bodyFont:{},bodyAlign:"left",footerColor:"#fff",footerSpacing:2,footerMarginTop:6,footerFont:{weight:"bold"},footerAlign:"left",padding:6,caretPadding:2,caretSize:5,cornerRadius:6,boxHeight:(t,e)=>e.bodyFont.size,boxWidth:(t,e)=>e.bodyFont.size,multiKeyBackground:"#fff",displayColors:!0,boxPadding:0,borderColor:"rgba(0,0,0,0)",borderWidth:0,animation:{duration:400,easing:"easeOutQuart"},animations:{numbers:{type:"number",properties:["x","y","width","height","caretX","caretY"]},opacity:{easing:"linear",duration:200}},callbacks:Va},defaultRoutes:{bodyFont:"font",footerFont:"font",titleFont:"font"},descriptors:{_scriptable:t=>"filter"!==t&&"itemSort"!==t&&"external"!==t,_indexable:!1,callbacks:{_scriptable:!1,_indexable:!1},animation:{_fallback:!1},animations:{_fallback:"animation"}},additionalOptionScopes:["interaction"]};return Tn.register(Un,$o,go,t),Tn.helpers={...Hi},Tn._adapters=In,Tn.Animation=As,Tn.Animations=Ts,Tn.animator=bt,Tn.controllers=nn.controllers.items,Tn.DatasetController=js,Tn.Element=$s,Tn.elements=go,Tn.Interaction=Ki,Tn.layouts=ls,Tn.platforms=Ds,Tn.Scale=tn,Tn.Ticks=ae,Object.assign(Tn,Un,$o,go,t,Ds),Tn.Chart=Tn,"undefined"!=typeof window&&(window.Chart=Tn),Tn})); +//# sourceMappingURL=chart.umd.min.js.map diff --git a/diagnostico.html b/diagnostico.html new file mode 100644 index 0000000..f8064b8 --- /dev/null +++ b/diagnostico.html @@ -0,0 +1,62 @@ + + + + +Diagnostico Export + + +

Diagnostico de Librerias de Exportacion (LOCAL)

+
Cargando...
+ + + + + + + + + + diff --git a/ejemplos (2).bc3 b/ejemplos (2).bc3 new file mode 100644 index 0000000..8547dd1 --- /dev/null +++ b/ejemplos (2).bc3 @@ -0,0 +1,4200 @@ +~V|CYPE INGENIEROS, S.A.|FIEBDC-3/2002|ARQUIMEDES||ANSI| +~K|\2\2\2\2\2\2\2\EUR\|2\13\6\\18|\2\\\2\\2\2\2\\2\2\EUR\|| +~C|REHABILITACION_ABEGONDO##||Rehabilitacion de vivienda unifamiliar en Abegondo. A Corua|110800.87|250315|0| +~D|REHABILITACION_ABEGONDO## +|@SinRef#\\1 +\0#\\1 +\D#\\1 +\A#\\1 +\E#\\1 +\F#\\1 +\P#\\1 +\I#\\1 +\N#\\1 +\Q#\\1 +\R#\\1 +\S#\\1 +\G#\\1 +\X#\\1 +\Y#\\1 +\15#\\1 +\| +~C|%|%|Medios auxiliares|0|160415|4| +~C|%0200|%|Medios auxiliares|0|060415|4| +~C|%0300|%|Medios auxiliares|0|150415|4| +~C|%0400|%|Medios auxiliares|0|060415|4| +~C|0#||Actuaciones previas|628.75|250315|0| +~D|0# +|0A#\\1 +\0D#\\1 +\| +~C|0A#||Desconexin de acometidas|117.75|250315|0| +~D|0A# +|0AS010\\1 +\0AE010\\1 +\0AF010\\1 +\| +~C|0AE010|Ud|Desconexin de acometida area de la instalacin elctrica del e|58.26|250315|0| +~T|0AE010|Desconexin de acometida area de la instalacin elctrica del edificio.| +~D|0AE010 +|mo001\\3.62 +\%0200\\0.02 +\| +~C|0AF010|Ud|Desconexin de acometida de la red de agua potable del edificio.|14.48|250315|0| +~T|0AF010|Desconexin de acometida de la red de agua potable del edificio.| +~D|0AF010 +|mo004\\0.9 +\%0200\\0.02 +\| +~C|0AS010|Ud|Desconexin de acometida de la instalacin de saneamiento del ed|42.7|250315|0| +~T|0AS010|Desconexin de acometida de la instalacin de saneamiento del edificio.| +~D|0AS010 +|mo011\\1.81 +\mo004\\0.9 +\%0200\\0.02 +\| +~C|0D#||Desratizacin, desinfeccin y eliminacin de plantas|511|250315|0| +~D|0D# +|0DP030\\100 +\0DP020\\1200 +\| +~C|0DP020|m|Desbroce de arbustos y hierbas, en el interior y en el exterior|0.36|250315|0| +~T|0DP020|Desbroce de arbustos y hierbas, en el interior y en el exterior del edificio, con desbrozadora.| +~D|0DP020 +|mq09bro010\\0.04 +\mo059\\0.01 +\mo060\\0.01 +\%0200\\0.02 +\| +~C|0DP030|m|Limpieza de arbustos y hierbas sitas en paramento vertical.|0.66|250315|0| +~T|0DP030|Limpieza de arbustos y hierbas sitas en paramento vertical.| +~D|0DP030 +|mt48pla030\\0.01 +\mq09pla010\\0.02 +\mo059\\0.01 +\mo060\\0.02 +\%0200\\0.02 +\| +~C|15#||Cierre de parcela|1417|250315|0| +~T|15#|Cierre de parcela| +~D|15# +|UVT010\\100 +\Pa8\\1 +\| +~C|@SinRef#||Conceptos no empleados en ninguna descomposicin|0||0| +~D|@SinRef# +|EHX010\\0 +\ISS010\\0 +\PTZ010\\0 +\RSG020b\\0 +\SMS010c\\0 +\YCB040\\0 +\YCF010\\0 +\YCK020\\0 +\YCM020\\0 +\YCN010\\0 +\YCR020\\0 +\YCV010\\0 +\YIC010b\\0 +\YID010\\0 +\YID020\\0 +\YIJ010b\\0 +\YIM010c\\0 +\YIM020\\0 +\YIP010c\\0 +\YIU010\\0 +\op00ato010\\0 +\op00cep010\\0 +\op00cla010\\0 +\op00fre010\\0 +\op00gra010\\0 +\op00roz010\\0 +\op00sie010\\0 +\| +~C|A#||Acondicionamiento del terreno|5726.74|250315|0| +~D|A# +|AD#\\1 +\AS#\\1 +\AN#\\1 +\| +~C|AD#||Movimiento de tierras|706.51|250315|0| +~D|AD# +|ADL005\\93.84 +\ADE010\\35.54 +\ADR010\\12.27 +\| +~C|ADE010|m|Excavacin en zanjas|12.82|250315|0| +~T|ADE010|Excavacin en zanjas para instalaciones en cualquier tipo de terreno, con medios manuales, retirada de los materiales excavados y carga a camin.| +~D|ADE010 +|mo060\\0.9 +\%0200\\0.02 +\| +~C|ADL005|m|Desbroce y limpieza del terreno|2.19|250315|0| +~T|ADL005|Desbroce y limpieza del terreno, hasta una profundidad mnima de 25 cm, con medios manuales, retirada de los materiales excavados y carga a camin, sin incluir transporte a vertedero autorizado.| +~D|ADL005 +|mq09bro010\\0.03 +\mo060\\0.15 +\%0200\\0.02 +\| +~C|ADR010|m|Relleno principal de zanjas|2.59|250315|0| +~T|ADR010|Relleno principal de zanjas para instalaciones, con tierra de la propia excavacin, y compactacin al 95% del Proctor Modificado mediante equipo manual con bandeja vibrante.| +~D|ADR010 +|mt01var010\\1.1 +\mq04dua020b\\0.11 +\mq02rod010bb\\0.17 +\mq02cia020\\0.01 +\mq04cab010c\\0.02 +\mo060\\0.08 +\%0200\\0.02 +\| +~C|AN#||Nivelacin|4115.26|250315|0| +~D|AN# +|ANS020\\207.19 +\ANE010\\148.03 +\ANS010\\148.03 +\CSV010\\4.5 +\| +~C|ANE010|m|Encachado de 20 cm en caja para base de solera|3.28|250315|0| +~T|ANE010|Encachado de 20 cm en caja para base de solera, con aporte de grava de cantera de piedra caliza, 40/70 mm y compactacin mediante equipo manual con bandeja vibrante.| +~D|ANE010 +|mt01are010a\\0.22 +\mq01pan010\\0.01 +\mq02rod010bb\\0.02 +\mq02cia020\\0.02 +\mo060\\0.1 +\%0200\\0.02 +\| +~C|ANS010|m|Solera de hormign armado HA-25/B/20/IIa de 15 cm de espesor|7.77|250315|0| +~T|ANS010|Solera de hormign armado HA-25/B/20/IIa fabricado en central y vertido con cubilote, de 15 cm de espesor, extendido y vibrado manual, armada con malla electrosoldada ME 20x20 de 5 mm, acero B 500 T 6x2,20 UNE-EN 10080, colocada sobre separadores homologados, para base de un solado.| +~D|ANS010 +|mt07aco020e\\2 +\mt07ame010ad\\1.2 +\mt10haf010bga\\0.16 +\mt16pea020ab\\0.05 +\mq04dua020b\\0.04 +\mq06vib020\\0.12 +\mo011\\0.05 +\mo046\\0.05 +\mo060\\0.03 +\%0200\\0.02 +\| +~C|ANS020|m|Solera ventilada de hormign|9.01|250315|0| +~T|ANS020|Solera ventilada de hormign, con encofrado perdido de polipropileno reforzado, de 15+4 cm de canto, hormign HA-25/B/20/IIa fabricado en central y vertido con bomba; mallazo ME 15x15, 5 mm, acero B 500 T 6x2,20 UNE-EN 10080, en capa de compresin de 4 cm de espesor.i/pp de colocacion de barrera de vapor en los encuentros perimetrales| +~D|ANS020 +|mt07cid010aah\\1.05 +\mt07ame010ab\\1.1 +\mt10haf010bga\\0.07 +\mq06vib020\\0.11 +\mo011\\0.04 +\mo046\\0.04 +\mo060\\0.04 +\%0200\\0.02 +\| +~C|AS#||Red de saneamiento horizontal|904.97|250315|0| +~D|AS# +|ASA010\\2 +\ASB010\\2 +\ASB020\\1 +\ASA010b\\1 +\ASC010\\69.54 +\| +~C|ASA010|Ud|Arqueta de paso, de obra de fbrica|43.46|250315|0| +~T|ASA010|Arqueta de paso, de obra de fbrica, no registrable, de dimensiones interiores 40x40x50 cm.| +~D|ASA010 +|mt10hmf010abe\\0.15 +\mt04lma010a\\80 +\mt09mor010c\\0.03 +\mt11var110\\1 +\mt09mor010f\\0.01 +\mt04lvg020b\\2 +\mt07ame010bb\\0.31 +\mt10haf010cbb\\0.03 +\mo011\\0.7 +\mo060\\0.5 +\%0200\\0.02 +\| +~C|ASA010b|Ud|Arqueta a pie de bajante, de obra de fbrica|44.47|250315|0| +~T|ASA010b|Arqueta a pie de bajante, de obra de fbrica, no registrable, de dimensiones interiores 40x40x50 cm.| +~D|ASA010b +|mt10hmf010abe\\0.16 +\mt04lma010a\\80 +\mt09mor010c\\0.03 +\mt11ppl010a\\1 +\mt09mor010f\\0.01 +\mt04lvg020b\\2 +\mt07ame010bb\\0.31 +\mt10haf010cbb\\0.03 +\mo011\\0.74 +\mo060\\0.53 +\%0200\\0.02 +\| +~C|ASB010|m|Acometida general de saneamiento|37.98|250315|0| +~T|ASB010|Acometida general de saneamiento a la red general del municipio, de PVC liso, serie SN-4, rigidez anular nominal 4 kN/m, de 200 mm de dimetro, pegado mediante adhesivo.| +~D|ASB010 +|mt01ara010\\0.39 +\mt11tpb030ad\\1.05 +\mt11var009\\0.08 +\mt11var010\\0.04 +\mt10hmf010agc\\0.09 +\mq05pdm010b\\0.93 +\mq05mai030\\0.93 +\mq01ret020a\\0.04 +\mq02rop020\\0.29 +\mo029\\0.55 +\mo059\\0.28 +\mo004\\0.06 +\mo055\\0.06 +\%0400\\0.04 +\| +~C|ASB020|Ud|Conexin de la acometida del edificio|71.06|250315|0| +~T|ASB020|Conexin de la acometida del edificio a la red general de saneamiento del municipio.| +~D|ASB020 +|mt09mor010c\\0.07 +\mt11var200\\1 +\mq05pdm110\\1.37 +\mq05mai030\\2.74 +\mo011\\1.39 +\mo059\\2.09 +\%0200\\0.02 +\| +~C|ASC010|m|Colector enterrado de saneamiento, sin arquetas|8.75|250315|0| +~T|ASC010|Colector enterrado de saneamiento, sin arquetas, mediante sistema integral registrable, de PVC liso, serie SN-4, rigidez anular nominal 4 kN/m, de 125 mm de dimetro, con junta elstica.| +~D|ASC010 +|mt01ara010\\0.31 +\mt11tpb020bb\\1.05 +\mt11tpb021bb\\1 +\mq04dua020b\\0.04 +\mq02rop020\\0.25 +\mq02cia020\\0.04 +\mo011\\0.03 +\mo060\\0.07 +\mo004\\0.05 +\mo055\\0.02 +\%0200\\0.02 +\| +~C|CAV010|m|Zuncho de apoyo de cerramiento|78.58|250315|0| +~T|CAV010|Zuncho de HA-25/B/20/IIa fabricado en central, acero UNE-EN 10080 B 500 S, cuanta 120 kg/m.| +~D|CAV010 +|mt07aco020a\\10 +\mt07aco010c\\120 +\mt10haf010bga\\1.05 +\mo011\\0.03 +\mo060\\0.03 +\%0200\\0.02 +\| +~C|CSV010|m|Zapata corrida de cimentacin de cierre de parcela|117.95|060415|0| +~T|CSV010|Zapata corrida de cimentacin para cierre, de hormign armado, realizada con hormign HA-25/B/20/IIa fabricado en central, y vertido desde camin, y acero UNE-EN 10080 B 500 S, cuanta 100 kg/m.| +~D|CSV010 +|mt07aco020a\\7 +\mt07aco010c\\100 +\mt10haf010nea\\1.1 +\mo041\\0.26 +\mo084\\0.26 +\%0200\\0.02 +\| +~C|D#||Demoliciones|9390.12|250315|0| +~D|D# +|DE#\\1 +\DF#\\1 +\DP#\\1 +\DI#\\1 +\DQ#\\1 +\DR#\\1 +\DS#\\1 +\| +~C|DE#||Estructuras|2237.47|250315|0| +~D|DE# +|DEC040\\2.66 +\DEM020\\119.31 +\DEM050\\126.1 +\DEM060\\8.8 +\DEM130b\\5 +\DEH020\\10.9 +\| +~C|DEC040|m|Demolicin de pilastra de mampostera|45.59|250315|0| +~T|DEC040|Demolicin de pilastra de mampostera concertada a una cara vista de piedra caliza, con mortero, con medios manuales y carga manual de escombros sobre camin o contenedor.| +~D|DEC040 +|mo060\\3.2 +\%0200\\0.02 +\| +~C|DEF041|m|Apertura de hueco en muro de piedra|60.66|250315|0| +~T|DEF041|Apertura de hueco en muro de piedra con martillo neumtico compresor, y carga manual de escombros a camin o contenedor.| +~D|DEF041 +|mq05mai030\\3.01 +\mq05pdm110\\1.51 +\mo059\\1.87 +\mo060\\1.65 +\%0200\\0.02 +\| +~C|DEH020|m|Demolicin de losa maciza de hormign|18.79|250315|0| +~T|DEH020|Demolicin de losa maciza de hormign armado de hasta 20 cm de espesor, con medios manuales, martillo neumtico compresor y equipo de oxicorte, y carga manual de escombros sobre camin o contenedor.| +~D|DEH020 +|mq05mai030\\1.23 +\mq05pdm110\\0.62 +\mq08sol010\\0.38 +\mo010\\0.14 +\mo059\\0.45 +\mo060\\0.34 +\%0200\\0.02 +\| +~C|DEM020|m|Demolicin de forjado de viguetas de madera con entarimado|7.42|250315|0| +~T|DEM020|Demolicin de forjado de viguetas de madera y entrevigado de tablero de madera machihembrado, con medios manuales y motosierra, y carga manual de escombros sobre camin o contenedor.| +~D|DEM020 +|mq09sie010\\1.19 +\mo059\\0.4 +\%0200\\0.02 +\| +~C|DEM050|m|Demolicin de viga de madera|5.48|250315|0| +~T|DEM050|Demolicin de viga de madera de hasta 1000 cm de seccin y hasta 4 m de longitud media, con medios manuales y motosierra y carga manual de escombros sobre camin o contenedor.| +~D|DEM050 +|mq09sie010\\0.34 +\mo059\\0.12 +\mo060\\0.23 +\%0200\\0.02 +\| +~C|DEM060|m|Demolicin de escalera de madera|5.23|250315|0| +~T|DEM060|Demolicin de escalera de estructura, peldaos y barandilla de madera con medios manuales y motosierra, y carga manual de escombros sobre camin o contenedor.| +~D|DEM060 +|mq09sie010\\0.67 +\mo059\\0.22 +\mo060\\0.08 +\%0200\\0.02 +\| +~C|DEM130b|m|Desmontaje de can de 15x15 cm de seccin|48.99|250315|0| +~T|DEM130b|Desmontaje de can de 15x15 cm de seccin, de armadura de madera en cubierta, con medios manuales y motosierra y carga manual de escombros sobre camin o contenedor.| +~D|DEM130b +|mq09sie010\\1.2 +\mo031\\1.62 +\mo060\\1.62 +\%0200\\0.02 +\| +~C|DF#||Fachadas|1674.66|250315|0| +~D|DF# +|DFC010\\19 +\DFD020\\11.8 +\DFD090\\19 +\DFR080\\74.95 +\DPT020b\\172.22 +\DEF041\\11.08 +\| +~C|DFC010|Ud|Levantado de carpintera acristalada de madera|3.42|250315|0| +~T|DFC010|Levantado de carpintera acristalada de madera de cualquier tipo situada en fachada, de menos de 3 m de superficie, con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DFC010 +|mo060\\0.24 +\%0200\\0.02 +\| +~C|DFD020|m|Levantado de barandilla metlica recta, de 100 cm de altura|2.83|250315|0| +~T|DFD020|Levantado de barandilla metlica recta, de 100 cm de altura, situada en balcn o terraza de fachada y recibida en obra de fbrica, con medios manuales y equipo de oxicorte, y carga manual de escombros sobre camin o contenedor.| +~D|DFD020 +|mq08sol010\\0.15 +\mo010\\0.05 +\mo060\\0.11 +\%0200\\0.02 +\| +~C|DFD090|m|Desmontaje de contraventana de madera|2.16|250315|0| +~T|DFD090|Desmontaje de contraventana de madera, con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DFD090 +|mo009\\0.07 +\mo032\\0.07 +\%0200\\0.02 +\| +~C|DFR080|m|Demolicin de cornisa de piedra natural|3.89|250315|0| +~T|DFR080|Demolicin de cornisa de piedra natural, con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DFR080 +|mo011\\0.13 +\mo060\\0.13 +\%0200\\0.02 +\| +~C|DI#||Instalaciones|272.55|250315|0| +~D|DI# +|DIC100\\1 +\DIE060\\1 +\DIE010\\1 +\DIE011\\1 +\DIF105\\1 +\| +~C|DIC100|Ud|Desmontaje de instalacin de calefaccin|86.23|250315|0| +~T|DIC100|Desmontaje de instalacin de calefaccin, en vivienda unifamiliar de 140 m de superficie construida; con medios manuales y carga manual del material desmontado sobre camin o contenedor.| +~D|DIC100 +|mo053\\3.91 +\mo060\\1.96 +\%0200\\0.02 +\| +~C|DIE010|Ud|Desmontaje de caja de proteccin y medida|4.55|250315|0| +~T|DIE010|Desmontaje de caja de proteccin y medida, con medios manuales y carga manual del material desmontado sobre camin o contenedor.| +~D|DIE010 +|mo001\\0.19 +\mo052\\0.1 +\%0200\\0.02 +\| +~C|DIE011|Ud|Desmontaje de contador elctrico individual|5.65|250315|0| +~T|DIE011|Desmontaje de contador elctrico individual, con medios manuales y carga manual del material desmontado sobre camin o contenedor.| +~D|DIE011 +|mo001\\0.24 +\mo052\\0.12 +\%0200\\0.02 +\| +~C|DIE060|Ud|Desmontaje de red de instalacin elctrica|70.03|250315|0| +~T|DIE060|Desmontaje de red de instalacin elctrica interior fija en superficie, en vivienda unifamiliar de 140 m de superficie construida; con medios manuales y carga manual del material desmontado sobre camin o contenedor.| +~D|DIE060 +|mo052\\1.61 +\mo060\\3.23 +\%0200\\0.02 +\| +~C|DIF105|Ud|Desmontaje de red de instalacin interior de agua|100.75|250315|0| +~T|DIF105|Desmontaje de red de instalacin interior de agua, colocada superficialmente, que da servicio a una superficie de 140 m, con medios manuales y carga manual del material desmontado sobre camin o contenedor.| +~D|DIF105 +|mo004\\3.32 +\mo060\\3.32 +\%0200\\0.02 +\| +~C|DP#||Particiones y trasdosados|434.73|250315|0| +~D|DP# +|DPE100\\1 +\DPE010\\3 +\DPP020\\12 +\DPT020\\194.18 +\| +~C|DPE010|m|Levantado de carpintera de madera de puerta|4.93|250315|0| +~T|DPE010|Levantado de carpintera de madera de puerta de entrada a vivienda, cercos o precercos, galces, tapajuntas, hoja y herrajes de colgar, de cierre y de seguridad, con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DPE010 +|mo060\\0.17 +\mo059\\0.17 +\%0200\\0.02 +\| +~C|DPE100|Ud|Levantado de portn de madera|24.41|250315|0| +~T|DPE100|Levantado de portn de madera con piezas de gran escuadra, hojas, cercos o precercos, galces, tapajuntas y herrajes de colgar, de cierre y de seguridad, con medios manuales y carga manual del material desmontado sobre camin o contenedor.| +~D|DPE100 +|mo008\\0.79 +\mo031\\0.79 +\%0200\\0.02 +\| +~C|DPP020|Ud|Desmontaje de hoja de puerta interior|2.11|250315|0| +~T|DPP020|Desmontaje de hoja de puerta interior de paso de carpintera de madera, galces, tapajuntas y herrajes, con medios manuales y carga manual del material desmontado sobre camin o contenedor.| +~D|DPP020 +|mo031\\0.14 +\%0200\\0.02 +\| +~C|DPT020|m|Demolicin de particin interior de fbrica revestida|1.86|250315|0| +~T|DPT020|Demolicin de particin interior de fbrica revestida, formada por ladrillo hueco doble de 7/9 cm de espesor, con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DPT020 +|mo060\\0.13 +\%0200\\0.02 +\| +~C|DPT020b|m|Demolicin de muror de bloque de hormign|3.13|250315|0| +~T|DPT020b|Demolicin de muro de fbrica, formada por bloque de hormign de 25 cm de espesor, con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DPT020b +|mo060\\0.22 +\%0200\\0.02 +\| +~C|DQ#||Cubiertas|3025.12|250315|0| +~D|DQ# +|DQC040\\430.02 +\DQF030\\273.84 +\DQF040\\273.84 +\DQC030\\142.89 +\DQR010\\3 +\| +~C|DQC030|m|Desmontaje de cobertura de placas de fibrocemento|10.06|060415|0| +~T|DQC030|Desmontaje de cobertura de placas de fibrocemento con amianto y elementos de fijacin, sujeta mecnicamente sobre correa estructural a menos de 20 m de altura, en cubierta inclinada a un agua con una pendiente media del 30%; plastificado, etiquetado y paletizado de las placas con medios y equipos adecuados, y carga mecnica del material desmontado sobre camin.| +~D|DQC030 +|mt51cub020aaa\\1 +\%0200\\0.02 +\| +~C|DQC040|m|Arranque de cobertura de teja cermica curva|1.49|250315|0| +~T|DQC040|Arranque de cobertura de teja cermica curva y elementos de fijacin, colocada con mortero a menos de 20 m de altura, en cubierta inclinada a dos aguas con una pendiente media del 30%; con medios manuales y carga manual de escombros sobre camin o contenedor.| +~D|DQC040 +|mo011\\0.05 +\mo060\\0.05 +\%0200\\0.02 +\| +~C|DQF030|m|Desmontaje de solera de tablero|1.14|250315|0| +~T|DQF030|Desmontaje de solera de tablero de madera y elementos de fijacin, situada a menos de 20 m de altura en cubierta inclinada a dos aguas con una pendiente media del 30%, con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DQF030 +|mo060\\0.08 +\%0200\\0.02 +\| +~C|DQF040|m|Desmontaje de enrastrelado simple|2|250315|0| +~T|DQF040|Desmontaje de enrastrelado simple de madera y elementos de fijacin, situado a menos de 20 m de altura en cubierta inclinada a dos aguas con una pendiente media del 30%, con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DQF040 +|mo060\\0.14 +\%0200\\0.02 +\| +~C|DQR010|Ud|Demolicin de forrado de conductos de instalaciones|9.53|250315|0| +~T|DQR010|Demolicin de forrado de conductos de instalaciones en cubierta inclinada, formado por fbrica de ladrillo cermico perforado para revestir, de 50x50 cm de seccin y 100 cm de altura; con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DQR010 +|mo011\\0.41 +\mo046\\0.21 +\%0200\\0.02 +\| +~C|DR#||Revestimientos|1651.79|250315|0| +~D|DR# +|DRF010\\306.59 +\DRS080\\192.2 +\DRT010\\84.2 +\| +~C|DRF010|m|Picado de enfoscado de cal y cemento|3.56|250315|0| +~T|DRF010|Picado de enfoscado de cal y cemento, aplicado sobre paramento vertical exterior de hasta 3 m de altura, con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DRF010 +|mo060\\0.25 +\%0200\\0.02 +\| +~C|DRS080|m|Demolicin de base para pavimento|1.87|250315|0| +~T|DRS080|Demolicin de base para pavimento de solera seca existente en el interior del edificio, con martillo neumtico compresor, y carga manual de escombros sobre camin o contenedor.| +~D|DRS080 +|mq05mai030\\0.11 +\mq05pdm010a\\0.06 +\mo059\\0.04 +\mo060\\0.07 +\%0200\\0.02 +\| +~C|DRT010|m|Arranque de cielo raso de caizo|2|250315|0| +~T|DRT010|Arranque de cielo raso de caizo enlucido con yeso, con medios manuales, y carga manual de escombros sobre camin o contenedor.| +~D|DRT010 +|mo060\\0.14 +\%0200\\0.02 +\| +~C|DS#||Equipamiento|93.8|250315|0| +~D|DS# +|DSC020\\5.1 +\DSM010\\1 +\DSM010b\\1 +\| +~C|DSC020|m|Desmontaje de conjunto de mobiliario de cocina|15.32|250315|0| +~T|DSC020|Desmontaje de conjunto de mobiliario de cocina y accesorios, con medios manuales, y carga manual del material desmontado sobre camin o contenedor.| +~D|DSC020 +|mo011\\0.39 +\mo046\\0.39 +\mo060\\0.24 +\%0200\\0.02 +\| +~C|DSM010|Ud|Desmontaje de lavabo|6.96|250315|0| +~T|DSM010|Desmontaje de lavabo con pedestal, grifera y accesorios, con medios manuales y carga manual del material desmontado sobre camin o contenedor.| +~D|DSM010 +|mo004\\0.22 +\mo060\\0.24 +\%0200\\0.02 +\| +~C|DSM010b|Ud|Desmontaje de inodoro|6.85|250315|0| +~T|DSM010b|Desmontaje de inodoro con tanque bajo, y accesorios, con medios manuales y carga manual del material desmontado sobre camin o contenedor.| +~D|DSM010b +|mo004\\0.24 +\mo060\\0.21 +\%0200\\0.02 +\| +~C|E#||Estructuras|15656.56|250315|0| +~D|E# +|EA#\\1 +\EH#\\1 +\EM#\\1 +\| +~C|EA#||Acero|1659.04|250315|0| +~D|EA# +|EAV010\\1998.84 +\| +~C|EAV010|kg|Acero S275JR en vigas, con piezas simples de perfiles laminados|0.81|250315|0| +~T|EAV010|Acero S275JR en vigas, con piezas simples de perfiles laminados en caliente de las series IPN, IPE, UPN, HEA, HEB o HEM con uniones soldadas.| +~D|EAV010 +|mt07ala010b\\1.05 +\mt27pfi010\\0.05 +\mo012\\0.01 +\mo033\\0.01 +\%0200\\0.02 +\| +~C|EH#||Hormign armado|9356.25|250315|0| +~D|EH# +|EHV010\\5.95 +\CAV010\\0.94 +\EHX011\\116.57 +\| +~C|EHV010|m|Zuncho perimetral de cubierta|159.55|250315|0| +~T|EHV010|Zuncho de hormign armado, HA-25/B/20/IIa fabricado en central y vertido con cubilote, acero UNE-EN 10080 B 500 S, cuanta 150 kg/m, encofrado de madera, en planta de hasta 3 m de altura libre.| +~D|EHV010 +|mt08eva010a\\5.2 +\mt07aco020c\\4 +\mt07aco010c\\150 +\mt10haf010bga\\1 +\mo011\\0.15 +\mo046\\0.18 +\mo060\\0.09 +\%0200\\0.02 +\| +~C|EHX010|m|Forjado de losa mixta, canto 10 cm, con chapa colaborante|45.69|070415|0| +~T|EHX010|Forjado de losa mixta, canto 10 cm, con chapa colaborante de acero galvanizado de 1,00 mm de espesor, 59 mm de canto y 150 mm de intereje; HA-25/B/12/IIa fabricado en central y vertido con cubilote; volumen total de hormign 0,062 m/m; acero UNE-EN 10080 B 500 S, con una cuanta total de 1 kg/m; mallazo ME 15x30, 6 mm, acero B 500 T 6x2,20 UNE-EN 10080.| +~C|EHX011|m|Forjado de canto 15 cm, con chapa colaborante|69.91|060415|0| +~T|EHX011|Losa mixta, canto 15 cm, con chapa colaborante de acero galvanizado de 1,00 mm de espesor, 59 mm de canto y 150 mm de intereje, y hormign armado realizado con hormign HA-25/B/20/IIa fabricado en central, y vertido con cubilote, volumen total de hormign 0,112 m/m, acero UNE-EN 10080 B 500 S, con una cuanta total de 1 kg/m, y malla electrosoldada ME 15x30 6-6 B 500 T 6x2,20 UNE-EN 10080.i/pp de anclaje perimetral mediante perfil en L 120-11 de 30cm colocado cada 50cm tomado al cerramiento existente con taco tipo Hilti hva-has M12 con resina epoxi cada 20cm segn planos de proyecto.| +~D|EHX011 +|mt07pcl010cai\\1.05 +\mt07aco020k\\3 +\mt07aco010c\\1 +\mt07ame010h\\1.15 +\mt10haf010nea\\0.11 +\mt07cem010a\\10 +\mt07cem020\\20 +\mt07cem030\\20 +\mo041\\0.49 +\mo084\\0.35 +\%0200\\0.02 +\| +~C|EM#||Madera|4641.27|250315|0| +~D|EM# +|EMV010\\4.08 +\EMW020\\1 +\EMV110\\8.07 +\Pa11\\1 +\| +~C|EMV010|m|Viga de madera aserrada de pino silvestre|198.03|250315|0| +~T|EMV010|Viga de madera aserrada de pino silvestre (Pinus Sylvestris L.) Espaa, de 10x10 a 15x30 cm de seccin y hasta 6 m de longitud, calidad MEG, clase resistente C-18, proteccin de la madera con clase de penetracin P2, trabajada en taller.| +~D|EMV010 +|mt07mee015aab\\1 +\mo008\\3.4 +\mo031\\1.67 +\%0200\\0.02 +\| +~C|EMV110|m|Viga de madera laminada encolada homognea|461.48|250315|0| +~T|EMV110|Viga de madera laminada encolada homognea, de 33 45 mm de espesor de las lminas y seccin constante, de 20x100 cm de seccin y hasta 15 m de longitud, clase resistente GL-24h y proteccin de la madera con clase de penetracin P1 y P2, trabajada en taller.| +~D|EMV110 +|mt07mee115aab\\1 +\mq07gte010c\\4.15 +\mo008\\2.55 +\mo031\\1.26 +\%0200\\0.02 +\| +~C|EMW020|m|Sustitucin de cargadero existente en hueco de muro, de madera|18.16|250315|0| +~T|EMW020|Sustitucin de cargadero existente en hueco de muro, de madera en mal estado o deteriorada, por un cargadero de madera aserrada de pino silvestre (Pinus Sylvestris L.) Espaa, calidad MEG, clase resistente C-18, proteccin de la madera con clase de penetracin P2, trabajado en taller, de 20x20 cm de seccin, colocado sobre capa de mortero hidrfugo M-15.| +~D|EMW020 +|mt07mee019aab\\0.05 +\mt09moe010c\\0.01 +\mo008\\0.3 +\mo011\\0.3 +\mo060\\0.12 +\%0200\\0.02 +\| +~C|F#||Fachadas|15029.74|250315|0| +~D|F# +|FF#\\1 +\FC#\\1 +\FD#\\1 +\FV#\\1 +\FZ#\\1 +\| +~C|FC#||Carpintera exterior|10251.54|250315|0| +~D|FC# +|FCM020\\4 +\FCM020b\\1 +\FCM020c\\1 +\FCM020d\\1 +\FCM020e\\1 +\FCM020f\\3 +\FCM020g\\1 +\FCM020h\\1 +\FCM020i\\1 +\FCM020j\\6 +\FCM020k\\2 +\FCM020l\\1 +\FCM020q\\1 +\FCM020m\\1 +\FCM020n\\2 +\FCM020o\\3 +\FCM020p\\1 +\FDG010\\1 +\| +~C|FCM020|Ud|Carpintera exterior en madera de iroko , de 100x155 cm.|182.68|250315|0| +~T|FCM020|Carpintera exterior en madera de iroko, barnizada de 100x155 cm.Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020 +|mt22aap010ab\\5.1 +\mt22atc010dec\\10.2 +\mt23xpm010\\20.15 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\15.5 +\mt22xcc015bb\\1.58 +\mo008\\0.76 +\mo031\\0.76 +\%0200\\0.02 +\| +~C|FCM020b|Ud|Carpintera exterior en madera de iroko , de 50x85 cm.|58.05|250315|0| +~T|FCM020b|Carpintera exterior en madera de iroko barnizada, de 50x85 cm.Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020b +|mt22atc010dec\\5.4 +\mt23xpm010\\5.53 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\4.25 +\mt22xcc015bb\\0.43 +\mo008\\0.21 +\mo031\\0.21 +\%0200\\0.02 +\| +~C|FCM020c|Ud|Carpintera exterior corredera en madera de iroko , de 400x81 cm|302.58|250315|0| +~T|FCM020c|Carpintera exterior corredeera en madera de iroko barnizada , de 400x81 cm.Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020c +|mt22atc010dec\\9.4 +\mt23xpm010\\16.58 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\12.75 +\mt22xcc015bb\\3.24 +\mo008\\0.63 +\mo031\\0.63 +\%0200\\0.02 +\| +~C|FCM020d|Ud|Carpintera exterior en madera de iroko , de 624x240 cm.|1285.69|250315|0| +~T|FCM020d|Carpintera exterior en madera de iroko barnizada , de 624x240 cm.formada por un fijo de 187cm de ancho por 240cm de alto y dos puertas correderas con guia inferior de 208x240cm. Con herrajes de acero inoxidable mate con manilla en exterior e interior y cerradura de seguridad.Segn planos de proyecto.| +~D|FCM020d +|mt22aap010ab\\7.8 +\mt22atc010dec\\15.6 +\mt23xpm010\\46.8 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\36 +\mt22xcc015bb\\14.97 +\mo008\\1.77 +\mo031\\1.77 +\%0200\\0.02 +\| +~C|FCM020e|Ud|Carpintera exterior en madera de iroko, de 115x138 cm.|184.41|250315|0| +~T|FCM020e|Carpintera exterior en madera de iroko barnizada, de 115x138 cm. Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020e +|mt22atc010dec\\10.2 +\mt23xpm010\\20.93 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\16.1 +\mt22xcc015bb\\1.64 +\mo008\\0.79 +\mo031\\0.79 +\%0200\\0.02 +\| +~C|FCM020f|Ud|Carpintera exterior en madera de iroko, de 115x145 cm.|190.62|250315|0| +~T|FCM020f|Carpintera exterior en madera de iroko barnizada para barnizar, de 115x145 cm. Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020f +|mt22atc010dec\\10.4 +\mt23xpm010\\21.68 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\16.68 +\mt22xcc015bb\\1.7 +\mo008\\0.82 +\mo031\\0.82 +\%0200\\0.02 +\| +~C|FCM020g|Ud|Carpintera exterior en madera de iroko , de 481x240 cm.|988.55|250315|0| +~T|FCM020g|Carpintera exterior en madera de iroko barnizada, de 481x240 cm. Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020g +|mt22atc010dec\\15.6 +\mt23xpm010\\46.8 +\mt22xcc015bb\\11.47 +\mo008\\1.77 +\mo031\\1.77 +\%0200\\0.02 +\| +~C|FCM020h|Ud|Carpintera exterior en madera de iroko , de 495x240 cm.|1042.81|250315|0| +~T|FCM020h|Carpintera exterior en madera de iroko barnizada , de 495x240 cm. Con herrajes de acero inoxidable mate con manilla en exterior e interior. Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020h +|mt22aap010ab\\7.8 +\mt22atc010dec\\15.6 +\mt23xpm010\\46.8 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\36 +\mt22xcc015bb\\11.88 +\mo008\\1.77 +\mo031\\1.77 +\%0200\\0.02 +\| +~C|FCM020i|Ud|Carpintera exterior en madera de iroko, de 112x211 cm.|268.11|250315|0| +~T|FCM020i|Carpintera exterior en madera de iroko barnizada, de 112x211 cm.Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020i +|mt22atc010dec\\13.2 +\mt23xpm010\\32.76 +\mt23xpm020\\4 +\mt22xcc015bb\\2.57 +\mo008\\1.24 +\mo031\\1.24 +\%0200\\0.02 +\| +~C|FCM020j|Ud|Carpintera exterior en madera de iroko , de 115x155 cm.|203.07|250315|0| +~T|FCM020j|Carpintera exterior en madera de iroko barnizada, de 115x155 cm. Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020j +|mt22atc010dec\\10.8 +\mt23xpm010\\23.17 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\17.83 +\mt22xcc015bb\\1.82 +\mo008\\0.88 +\mo031\\0.88 +\%0200\\0.02 +\| +~C|FCM020k|Ud|Carpintera exterior en madera de iroko, de 100x155 cm.|178.57|250315|0| +~T|FCM020k|Carpintera exterior en madera de iroko barnizada, de 100x155 cm. Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020k +|mt22atc010dec\\10.2 +\mt23xpm010\\20.15 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\15.5 +\mt22xcc015bb\\1.58 +\mo008\\0.76 +\mo031\\0.76 +\%0200\\0.02 +\| +~C|FCM020l|Ud|Carpintera exterior en madera de iroko , de 90x210 cm.|220.87|250315|0| +~T|FCM020l|Carpintera exterior en madera maciza de iroko barnizada , de 90x210 cm.Con herrajes en acero inox.mate y tiradores en acero mate interior y exterior. Con cerradura de seguridad.| +~D|FCM020l +|mt22aap010ab\\6 +\mt22atc010dec\\12 +\mt23xpm010\\24.57 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\18.9 +\mt22xcc015bb\\1.93 +\mo008\\0.93 +\mo031\\0.93 +\%0200\\0.02 +\| +~C|FCM020m|Ud|Carpintera exterior en madera de irok, de 130x210 cm.|301.28|250315|0| +~T|FCM020m|Carpintera exterior en madera de iroko, barnizada de 130x210 cm. formada por dos hojas macizas abatibles.I/pp de tapetas, tiradores y herrajes.Totalamente finalizada.| +~D|FCM020m +|mt22atc010dec\\13.6 +\mt23xpm010\\35.49 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\27.3 +\mt22xcc015bb\\2.78 +\mo008\\1.34 +\mo031\\1.34 +\%0200\\0.02 +\| +~C|FCM020n|Ud|Carpintera exterior en madera de iroko, de 130x210 cm. con fijo|301.28|250315|0| +~T|FCM020n|Carpintera exterior en madera de iroko barnizada, de 130x210 cm.formada por una hoja maciza y una acristalada, abatibles.I/pp de tapetas, tiradores y herrajes.Totalamente finalizada.| +~D|FCM020n +|mt22atc010dec\\13.6 +\mt23xpm010\\35.49 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\27.3 +\mt22xcc015bb\\2.78 +\mo008\\1.34 +\mo031\\1.34 +\%0200\\0.02 +\| +~C|FCM020o|Ud|Carpintera exterior en madera de irok, de 85x210 cm.|205.12|250315|0| +~T|FCM020o|Carpintera exterior en madera de iroko barnizada, de 85x210 cm. Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020o +|mt22atc010dec\\11.8 +\mt23xpm010\\23.21 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\17.85 +\mt22xcc015bb\\1.82 +\mo008\\0.88 +\mo031\\0.88 +\%0200\\0.02 +\| +~C|FCM020p|Ud|Carpintera exterior en madera de iroko, de 110x210 cm.|280.25|250315|0| +~T|FCM020p|Carpintera exterior en madera de iroko barnizada, de 110x210 cm.,formada por dos hojas macizas abatibles. Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020p +|mt22atc010dec\\13.2 +\mt23xpm010\\32.76 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\25.2 +\mt22xcc015bb\\2.57 +\mo008\\1.24 +\mo031\\1.24 +\%0200\\0.02 +\| +~C|FCM020q|Ud|Carpintera exterior en madera de iroko barnizada, para puerta a|499.01|250315|0| +~T|FCM020q|Carpintera exterior en madera de iroko para barnizar, para puerta practicable acristalada de una hoja de 90x240 cm.Segn planos de proyecto. I/pp de tapetas, tiradores y herrajes en acero inox.Totalamente finalizada.| +~D|FCM020q +|mt22aap010b\\6.6 +\mt22atc010dA\\13.2 +\mt23xpm010\\28.08 +\mt23xpm020\\4 +\mt23xpm030\\2 +\mt23xpm040\\1 +\mt23xpm050\\21.6 +\mt22xcc015d\\2.2 +\mo016\\2.23 +\mo053\\2.23 +\%0200\\0.02 +\| +~C|FD#||Defensas de exteriores|2594.35|250315|0| +~D|FD# +|FDV030\\4 +\FDV030b\\1 +\FDV030c\\3 +\FDV030d\\6 +\FDV030e\\2 +\FDV030f\\1 +\Pa3\\14.46 +\PDB010\\1 +\Pa9\\1 +\| +~C|FDA005|m|Antepecho de pasarela|116.69|060415|0| +~T|FDA005|Antepecho de 1 m de altura de 12 cm de espesor de fbrica, de ladrillo cermico hueco,de 24x15x12 cm, recibida con mortero de cemento M-7,5, enfoscado a ambos lados con mortero de cemento , con albardilla superior en madera maciza de iroko de 20mm de espesor con acanaladura de 10mm para goteron a ambos lados.I/pp. de flejes para su anclaje al soporte y a los muros laterales.| +~D|FDA005 +|mt04lac010d\\34.13 +\mt09mor010d\\0.02 +\mt20ahp010j\\1.05 +\mt09mor010c\\0.1 +\mt26dpa010a\\1.05 +\mt09mor010c\\0.01 +\mt27pfi050\\1 +\mo020\\2.47 +\mo073\\1.23 +\%0200\\0.02 +\| +~C|FDG010|Ud|Puerta abatible/pivotante de una hoja para almacen local, 240x23|522.88|250315|0| +~T|FDG010|Puerta abatible/pivotante de una hoja para almacen local, 240x238 cm, formada por estructura de acero galvanizado interior y terminada al exterior por panel liso acanalado de madera de iroko, con puerta interior peatonal de dos hojas con apertura al interior. Apertura manual con preinstalacion elctrica para mecanismos electronicos..I/pp de tapetas, tiradores y herrajes.Totalamente finalizada.| +~D|FDG010 +|mt26pga010aac\\1 +\mo009\\0.52 +\mo032\\0.52 +\%0200\\0.02 +\| +~C|FDV030|Ud|Contraventana mallorquina,de 90x135 cm, colocada en ventana.|129.8|250315|0| +~T|FDV030|Contraventana mallorquina, exterior, de madera de iroko barnizada, con dos hojas de lamas fijas, de 90x135 cm, colocada en ventana.Segn planos de proyecto. I/pp de tiradores y herrajes para cierre en acero inox.Totalamente finalizada.| +~D|FDV030 +|mt22xcv030aab\\1.4 +\mt22xcv031ab\\1 +\mo008\\0.17 +\mo031\\0.17 +\%0200\\0.02 +\| +~C|FDV030b|Ud|Contraventana mallorquina,de 115x140 cm, colocada en ventana.|148.18|250315|0| +~T|FDV030b|Contraventana mallorquina, exterior, de madera de iroko barnizada, con dos hojas de lamas fijas, de 115x140 cm, colocada en ventana. Segn planos de proyecto. I/pp de tiradores y herrajes para cierre en acero inox.Totalamente finalizada.| +~D|FDV030b +|mt22xcv030aab\\1.61 +\mt22xcv031ab\\1 +\mo008\\0.19 +\mo031\\0.19 +\%0200\\0.02 +\| +~C|FDV030c|Ud|Contraventana mallorquina,de 95x125 cm, colocada en ventana.|153.57|250315|0| +~T|FDV030c|Contraventana mallorquina, exterior, de madera de iroko barnizada, con dos hojas de lamas fijas, de 95x125 cm, colocada en ventana. Segn planos de proyecto. I/pp de tiradores y herrajes para cierre en acero inox.Totalamente finalizada.| +~D|FDV030c +|mt22xcv030aab\\1.67 +\mt22xcv031ab\\1 +\mo008\\0.2 +\mo031\\0.2 +\%0200\\0.02 +\| +~C|FDV030d|Ud|Contraventana mallorquina, de 95x135 cm, colocada en ventana.|163.19|250315|0| +~T|FDV030d|Contraventana mallorquina, exterior, de madera de iroko barnizada, con dos hojas de lamas fijas, de 95x135 cm, colocada en ventana. Segn planos de proyecto. I/pp de tiradores y herrajes para cierre en acero inox.Totalamente finalizada.| +~D|FDV030d +|mt22xcv030aab\\1.78 +\mt22xcv031ab\\1 +\mo008\\0.21 +\mo031\\0.21 +\%0200\\0.02 +\| +~C|FDV030e|Ud|Contraventana mallorquina,de 80x135 cm, colocada en ventana.|143.1|250315|0| +~T|FDV030e|Contraventana mallorquina, exterior, de madera de iroko barnizada, con dos hojas de lamas fijas, de 80x135 cm, colocada en ventana. Segn planos de proyecto. I/pp de tiradores y herrajes para cierre en acero inox.Totalamente finalizada.| +~D|FDV030e +|mt22xcv030aab\\1.55 +\mt22xcv031ab\\1 +\mo008\\0.19 +\mo031\\0.19 +\%0200\\0.02 +\| +~C|FDV030f|Ud|Contraventana mallorquina, exterior de 40x75 cm, colocada en ven|106.5|250315|0| +~T|FDV030f|Contraventana mallorquina, exterior, de madera de iroko barnizada, con una hoja de lamas fijas, de 40x75 cm, colocada en ventana. Segn planos de proyecto. I/pp de tiradores y herrajes para cierre en acero inox.Totalamente finalizada.| +~D|FDV030f +|mt22xcv030b\\0.3 +\mt22xcv031a\\1 +\mo016\\0.09 +\mo053\\0.09 +\%0200\\0.02 +\| +~C|FF#||Fbricas y trasdosados|660.56|250315|0| +~D|FF# +|FFZ020\\50.93 +\| +~C|FFZ020|m|Hoja exterior de cerramiento de fachada|12.72|250315|0| +~T|FFZ020|Hoja exterior de cerramiento de fachada, de 20 cm de espesor de fbrica, de bloque hueco de hormign, para revestir, color gris, 40x20x20 cm, resistencia normalizada R10 (10 N/mm), recibida con mortero de cemento M-7,5.| +~D|FFZ020 +|mt02bhg010aad\\12.6 +\mt09mor010d\\0.02 +\mt08adt010\\0.09 +\mt07aco010c\\2.5 +\mt02bhg012a\\5 +\mo011\\0.26 +\mo060\\0.13 +\%0300\\0.03 +\| +~C|FV#||Vidrios|885.58|300315|0| +~D|FV# +|FVC010b\\58.14 +\FVS010\\7.24 +\| +~C|FVC010b|m|Doble acristalamiento estndar, 4/12/4, con calzos y sellado con|12.82|300315|0| +~T|FVC010b|Doble acristalamiento estndar, 4/12/4, con calzos y sellado continuo.| +~D|FVC010b +|mt21veg011aaa\\1.01 +\mt21vva015\\0.58 +\mt21vva021\\1 +\mo028\\0.17 +\mo057\\0.17 +\%0200\\0.02 +\| +~C|FVS010|m|Vidrio laminar de seguridad 4+4 mm, butiral de polivinilo incolo|16.94|300315|0| +~T|FVS010|Vidrio laminar de seguridad 4+4 mm, butiral de polivinilo incoloro.| +~D|FVS010 +|mt21ves010ab\\1.01 +\mt21vva015\\0.29 +\mt21vva021\\1 +\mo028\\0.18 +\mo057\\0.18 +\%0200\\0.02 +\| +~C|FZ#||Limpieza y tratamientos superficiales|637.71|250315|0| +~D|FZ# +|FZB040\\306.59 +\| +~C|FZB040|m|Limpieza mecnica de fachada con lanza de agua a presin|2.04|250315|0| +~T|FZB040|Limpieza mecnica de fachada de fbrica de mampostera en estado de conservacin regular, mediante la aplicacin sobre la superficie de lanza de agua a presin, considerando un grado de complejidad medio.| +~D|FZB040 +|mt08aaa010a\\0.5 +\mt27prb010\\0.15 +\mq08lch020c\\0.32 +\mo059\\0.04 +\mo011\\0.06 +\%0200\\0.02 +\| +~C|G#||Gestin de residuos|1953.75|060415|0| +~D|G# +|GT#\\1 +\GR#\\1 +\| +~C|GR#||Transporte de residuos inertes|1714.6|060415|0| +~D|GR# +|GRA010\\1 +\GRA010b\\2 +\GRA010c\\1 +\GRA010d\\1 +\GRA010e\\1 +\GRA010f\\1 +\GRA010g\\1 +\GRA010h\\1 +\| +~C|GRA010|Ud|Transporte de residuos inertes de hormign|128.08|060415|0| +~T|GRA010|Transporte de residuos inertes de hormign producidos en obras de construccin y/o demolicin, con contenedor de 7 m, a vertedero especfico, instalacin de tratamiento de residuos de construccin y demolicin externa a la obra o centro de valorizacin o eliminacin de residuos.| +~D|GRA010 +|mq04res010ag\\1.11 +\%0200\\0.02 +\| +~C|GRA010b|Ud|Transporte de residuos inertes de ladrillos, tejas y materiales|128.1|060415|0| +~T|GRA010b|Transporte de residuos inertes de ladrillos, tejas y materiales cermicos, producidos en obras de construccin y/o demolicin, con contenedor de 7 m, a vertedero especfico, instalacin de tratamiento de residuos de construccin y demolicin externa a la obra o centro de valorizacin o eliminacin de residuos.| +~D|GRA010b +|mq04res010bg\\1.11 +\%0200\\0.02 +\| +~C|GRA010c|Ud|Transporte de residuos inertes de madera|208.11|060415|0| +~T|GRA010c|Transporte de residuos inertes de madera producidos en obras de construccin y/o demolicin, con contenedor de 7 m, a vertedero especfico, instalacin de tratamiento de residuos de construccin y demolicin externa a la obra o centro de valorizacin o eliminacin de residuos.| +~D|GRA010c +|mq04res010dg\\1.11 +\%0200\\0.02 +\| +~C|GRA010d|Ud|Transporte de residuos inertes vtreos|208.12|060415|0| +~T|GRA010d|Transporte de residuos inertes vtreos producidos en obras de construccin y/o demolicin, con contenedor de 7 m, a vertedero especfico, instalacin de tratamiento de residuos de construccin y demolicin externa a la obra o centro de valorizacin o eliminacin de residuos.| +~D|GRA010d +|mq04res010eg\\1.11 +\%0200\\0.02 +\| +~C|GRA010e|Ud|Transporte de residuos inertes plsticos|208.11|060415|0| +~T|GRA010e|Transporte de residuos inertes plsticos producidos en obras de construccin y/o demolicin, con contenedor de 7 m, a vertedero especfico, instalacin de tratamiento de residuos de construccin y demolicin externa a la obra o centro de valorizacin o eliminacin de residuos.| +~D|GRA010e +|mq04res010fg\\1.11 +\%0200\\0.02 +\| +~C|GRA010f|Ud|Transporte de residuos inertes de papel y cartn|208.11|060415|0| +~T|GRA010f|Transporte de residuos inertes de papel y cartn, producidos en obras de construccin y/o demolicin, con contenedor de 7 m, a vertedero especfico, instalacin de tratamiento de residuos de construccin y demolicin externa a la obra o centro de valorizacin o eliminacin de residuos.| +~D|GRA010f +|mq04res010gg\\1.11 +\%0200\\0.02 +\| +~C|GRA010g|Ud|Transporte de residuos inertes metlicos|208.11|060415|0| +~T|GRA010g|Transporte de residuos inertes metlicos producidos en obras de construccin y/o demolicin, con contenedor de 7 m, a vertedero especfico, instalacin de tratamiento de residuos de construccin y demolicin externa a la obra o centro de valorizacin o eliminacin de residuos.| +~D|GRA010g +|mq04res010hg\\1.11 +\%0200\\0.02 +\| +~C|GRA010h|Ud|Transporte de mezcla sin clasificar de residuos inertes|256.16|060415|0| +~T|GRA010h|Transporte de mezcla sin clasificar de residuos inertes producidos en obras de construccin y/o demolicin, con contenedor de 7 m, a vertedero especfico, instalacin de tratamiento de residuos de construccin y demolicin externa a la obra o centro de valorizacin o eliminacin de residuos.| +~D|GRA010h +|mq04res010cg\\1.11 +\%0200\\0.02 +\| +~C|GT#||Transporte de tierras|239.15|060415|0| +~D|GT# +|GTA010\\125.87 +\| +~C|GTA010|m|Transporte de tierras con camin a vertedero especfico|1.86|060415|0| +~T|GTA010|Transporte de tierras con camin a vertedero especfico, instalacin de tratamiento de residuos de construccin y demolicin externa a la obra o centro de valorizacin o eliminacin de residuos, situado a una distancia mxima de 10 km.| +~D|GTA010 +|mq04cab010c\\0.11 +\%0200\\0.02 +\| +~C|I#||Instalaciones|10632.89|250315|0| +~D|I# +|IL#\\1 +\IA#\\1 +\IC#\\1 +\IE#\\1 +\IF#\\1 +\II#\\1 +\IS#\\1 +\| +~C|IA#||Audiovisuales|282.88|250315|0| +~D|IA# +|IAA031\\1 +\IAA034b\\1 +\IAA034c\\1 +\IAA039\\1 +\IAA100\\21.46 +\IAA100b\\15 +\IAA115\\1 +\IAA120\\2 +\IAF070\\42.92 +\IAF090\\2 +\IAV020\\1 +\| +~C|IAA031|Ud|Mstil para fijacin|29.72|060415|0| +~T|IAA031|Mstil para fijacin de 3 antenas, de 3 m de altura y 40 mm de dimetro.| +~D|IAA031 +|mt40saf010acb\\1 +\mt40saf011abb\\2 +\mo000\\0.45 +\mo030\\0.45 +\%0200\\0.02 +\| +~C|IAA034b|Ud|Antena exterior DAB|12.99|060415|0| +~T|IAA034b|Antena exterior DAB para captacin de seales de radiodifusin sonora digital procedentes de emisiones terrenales, de 0 dB de ganancia.| +~D|IAA034b +|mt40ecf020aaa\\1 +\mo000\\0.2 +\mo030\\0.2 +\%0200\\0.02 +\| +~C|IAA034c|Ud|Antena exterior UHF|25.2|060415|0| +~T|IAA034c|Antena exterior UHF para captacin de seales de televisin analgica, televisin digital terrestre (TDT) y televisin de alta definicin (HDTV) procedentes de emisiones terrenales, canales del 21 al 69, de 17 dB de ganancia.| +~D|IAA034c +|mt40ecf030acb\\1 +\mo000\\0.2 +\mo030\\0.2 +\%0200\\0.02 +\| +~C|IAA039|Ud|Amplificador de mstil, de 3 entradas, BI/FM/BIII-UHF-FI.|29.02|060415|0| +~T|IAA039|Amplificador de mstil, de 3 entradas, BI/FM/BIII-UHF-FI.| +~D|IAA039 +|mt40eaf011aa\\1 +\mt40eaf040aab\\1 +\mt40eaf100aa\\1 +\mt40www040\\1 +\mo000\\0.2 +\mo030\\0.2 +\%0200\\0.02 +\| +~C|IAA100|m|Cable coaxial RG-6, de 75 Ohm|0.65|060415|0| +~T|IAA100|Cable coaxial RG-6, de 75 Ohm, con conductor central de cobre de 1,15 mm de dimetro y cubierta exterior de PVC de 6,9 mm de dimetro, de 0,285 dB/m de atenuacin a 2150 MHz.| +~D|IAA100 +|mt40cfr010aaa\\1 +\mo000\\0.01 +\mo030\\0.01 +\%0200\\0.02 +\| +~C|IAA100b|m|Cable coaxial RG-6, de 75 Ohm|0.65|060415|0| +~T|IAA100b|Cable coaxial RG-6, de 75 Ohm, con conductor central de cobre de 1,15 mm de dimetro y cubierta exterior de PE de 6,9 mm de dimetro, de 0,285 dB/m de atenuacin a 2150 MHz.| +~D|IAA100b +|mt40cfr010aaa\\1 +\mo000\\0.01 +\mo030\\0.01 +\%0200\\0.02 +\| +~C|IAA115|Ud|Distribuidor de 5-2400 MHz de 4 salidas con punto de acceso a us|4.5|060415|0| +~T|IAA115|Distribuidor de 5-2400 MHz de 4 salidas con punto de acceso a usuario (PAU).| +~D|IAA115 +|mt40irf026acc\\1 +\mo000\\0.04 +\mo030\\0.04 +\%0200\\0.02 +\| +~C|IAA120|Ud|Toma separadora doble, TV/R-SAT, de 5-2400 MHz.|3.85|060415|0| +~T|IAA120|Toma separadora doble, TV/R-SAT, de 5-2400 MHz.| +~D|IAA120 +|mt40irf050aab\\1 +\mo000\\0.1 +\%0200\\0.02 +\| +~C|IAF070|m|Cable rgido U/UTP de 4 pares de cobre,|0.46|060415|0| +~T|IAF070|Cable rgido U/UTP de 4 pares de cobre, categora 6, con vaina exterior de PVC de 6,2 mm de dimetro.| +~D|IAF070 +|mt40cpt010aa\\1 +\mt40www040\\0.05 +\mo000\\0.01 +\mo030\\0.01 +\%0200\\0.02 +\| +~C|IAF090|Ud|Toma simple con conector tipo RJ45 de 8 contactos, categora 6.|6.87|060415|0| +~T|IAF090|Toma simple con conector tipo RJ45 de 8 contactos, categora 6.| +~D|IAF090 +|mt40dpt060a\\1 +\mo000\\0.07 +\%0200\\0.02 +\| +~C|IAV020|Ud|Portero electrnico para vivienda unifamiliar.|111.1|250315|0| +~T|IAV020|Portero electrnico para vivienda unifamiliar.| +~D|IAV020 +|mt35aia010aab\\25 +\mt40pea010\\25 +\mt40pek110\\1 +\mt40www040\\2 +\mo001\\1.25 +\mo052\\1.25 +\%0200\\0.02 +\| +~C|IC#||Calefaccin, climatizacin y A.C.S.|6209.94|250315|0| +~D|IC# +|ICQ015\\1 +\ICO001\\7 +\ICS010\\116.38 +\ICE040\\4 +\ICE040b\\6 +\ICE040c\\3 +\| +~C|ICE040|Ud|Radiador de aluminio inyectado, de 4 elementos|40.55|250315|0| +~T|ICE040|Radiador de aluminio inyectado, con 298,8 kcal/h de emisin calorfica, de 4 elementos, de 425 mm de altura, con frontal plano, para instalacin con sistema bitubo, con llave de paso termosttica.| +~D|ICE040 +|mt38emi010aaa\\4 +\mt38emi011a\\1 +\mt38emi013\\1 +\mo002\\0.14 +\mo053\\0.14 +\%0200\\0.02 +\| +~C|ICE040b|Ud|Radiador de aluminio inyectado,de 6 elementos|51.59|250315|0| +~T|ICE040b|Radiador de aluminio inyectado, con 448,2 kcal/h de emisin calorfica, de 6 elementos, de 425 mm de altura, con frontal plano, para instalacin con sistema bitubo, con llave de paso termosttica.| +~D|ICE040b +|mt38emi010aaa\\6 +\mt38emi011a\\1 +\mt38emi013\\1 +\mo002\\0.18 +\mo053\\0.18 +\%0200\\0.02 +\| +~C|ICE040c|Ud|Radiador de aluminio inyectado,de 10 elementos|73.7|250315|0| +~T|ICE040c|Radiador de aluminio inyectado, con 747 kcal/h de emisin calorfica, de 10 elementos, de 425 mm de altura, con frontal plano, para instalacin con sistema bitubo, con llave de paso termosttica.| +~D|ICE040c +|mt38emi010aaa\\10 +\mt38emi011a\\1 +\mt38emi013\\1 +\mo002\\0.26 +\mo053\\0.26 +\%0200\\0.02 +\| +~C|ICO001|m|Conducto de evacuacin de los productos de la combustin|10.53|250315|0| +~T|ICO001|Conducto de evacuacin de los productos de la combustin| +~D|ICO001 +|mt20chn031aa\\1 +\mt20chn030aac\\1 +\mo002\\0.16 +\mo053\\0.16 +\%0200\\0.02 +\| +~C|ICO015|m|Chimenea modular metlica|91.95|060415|0| +~T|ICO015|Chimenea modular metlica, de doble pared, pared interior de acero inoxidable AISI 316L de 125 mm de dimetro y pared exterior de acero aluminizado, con aislamiento entre paredes mediante manta de fibra cermica de alta densidad de 25 mm de espesor, instalada en el interior del edificio, para hogar o estufa a lea, carbn, briquetas o pellets.| +~D|ICO015 +|mt20cmn126a\\1 +\mt20cmn125ac\\1 +\mo003\\0.33 +\mo095\\0.33 +\%0200\\0.02 +\| +~C|ICQ015|Ud|Caldera para la combustin de pellets, potencia nominal de 16 kW|4494.44|250315|0| +~T|ICQ015|Caldera para la combustin de pellets, potencia nominal de 16 kW, modelo Pelletstar-BioControl 20 "HERZ", con sistema de elevacin de la temperatura de retorno por encima de 55C, compuesto por vlvula reguladora y bomba de circulacin RS 25/6, regulador de tiro de 150 mm de dimetro, limitador trmico de seguridad.| +~D|ICQ015 +|mt38cbh012bbf\\1 +\mt38cbh097b\\1 +\mt38cbh085ba\\1 +\mt38cbh096ba\\1 +\mt38cbh100bb\\1 +\mo002\\1.26 +\mo053\\1.26 +\%0200\\0.02 +\| +~C|ICS010|m|Tubera de distribucin de agua caliente de calefaccin|7.11|250315|0| +~T|ICS010|Tubera de distribucin de agua caliente de calefaccin formada por tubo de acero negro, con soldadura longitudinal por resistencia elctrica, de 1/2" DN 15 mm de dimetro, una mano de imprimacin antioxidante, colocada superficialmente en el interior del edificio.| +~D|ICS010 +|mt08tan330b\\1 +\mt08tan010be\\1 +\mt27pfi030\\0.01 +\mo002\\0.14 +\mo053\\0.18 +\%0200\\0.02 +\| +~C|IE#||Elctricas|1202.67|250315|0| +~D|IE# +|IEP010\\1 +\IEP030\\1 +\IEC010\\1 +\IED010\\14.17 +\IEI015\\1 +\| +~C|IEC010|Ud|Caja de proteccin y medida CPM1-S2, de hasta 63 A de intensidad|59.81|250315|0| +~T|IEC010|Caja de proteccin y medida CPM1-S2, de hasta 63 A de intensidad, para 1 contador monofsico, instalada en el interior de hornacina mural, en vivienda unifamiliar o local.| +~D|IEC010 +|mt35cgp010aab\\1 +\mt35cgp040ah\\3 +\mt35cgp040af\\1 +\mt35www010\\1 +\mo011\\0.12 +\mo060\\0.12 +\mo001\\0.2 +\mo052\\0.2 +\%0200\\0.02 +\| +~C|IED010|m|Derivacin individual monofsica fija en superficie para viviend|4.87|250315|0| +~T|IED010|Derivacin individual monofsica fija en superficie para vivienda, formada por cables unipolares con conductores de cobre, ES07Z1-K (AS) 3G10 mm, siendo su tensin asignada de 450/750 V, bajo tubo protector de PVC rgido, blindado, de 32 mm de dimetro.| +~D|IED010 +|mt35aia090aaa\\1 +\mt35cun020e\\3 +\mt35der011aa\\1 +\mt35www010\\0.2 +\mo001\\0.03 +\mo052\\0.03 +\%0200\\0.02 +\| +~C|IEI015|Ud|Red elctrica de distribucin interior de una vivienda unifamili|901.8|250315|0| +~T|IEI015|Red elctrica de distribucin interior de una vivienda unifamiliar con electrificacin elevada, con las siguientes estancias: acceso, vestbulo, pasillo, comedor, 2 dormitorios dobles, bao, aseo, cocina, galera, terraza, compuesta de: cuadro general de mando y proteccin; circuitos interiores con cableado bajo tubo protector: C1, C2, C3, C4, C5, 2 C8, C10; mecanismos gama bsica (tecla o tapa y marco: blanco; embellecedor: blanco).| +~D|IEI015 +|mt35cgm040aca\\1 +\mt35cgm021aab\\1 +\mt35cgm029aah\\1 +\mt35cgm029aab\\2 +\mt35cgm021abb\\1 +\mt35cgm021abb\\3 +\mt35cgm021abb\\1 +\mt35cgm021abb\\3 +\mt35aia010aaa\\114.54 +\mt35aia010aab\\144.42 +\mt35aia010aac\\41.5 +\mt35aia080aaa\\8.3 +\mt35caj020a\\8 +\mt35caj020b\\3 +\mt35caj010a\\42 +\mt35caj010b\\18 +\mt35caj011\\1 +\mt35cun040aba\\414 +\mt35cun040acb\\324 +\mt35cun040add\\30 +\mt35cun040aec\\54 +\mt35cun040afb\\90 +\mt35cun040aid\\120 +\mt35cun040akb\\54 +\mt33seg100aa\\7 +\mt33seg111aa\\1 +\mt33seg101aa\\1 +\mt33seg102aa\\10 +\mt33seg103aa\\3 +\mt33seg104aa\\1 +\mt33seg105aa\\1 +\mt33seg107aa\\32 +\mt33seg107bb\\3 +\mt33sem117aaa\\1 +\mt33seg110aa\\1 +\mt33seg504a\\2 +\mt35www010\\4 +\mo001\\7.97 +\mo052\\7.97 +\%0200\\0.02 +\| +~C|IEP010|Ud|Red de toma de tierra para estructura de hormign del edificio c|134.12|250315|0| +~T|IEP010|Red de toma de tierra para estructura de hormign del edificio con 55 m de conductor de cobre desnudo de 35 mm.| +~D|IEP010 +|mt35ttc010ab\\55 +\mt35tte020a\\3 +\mt35tts010c\\3 +\mt35www020\\1 +\mo001\\0.57 +\mo052\\0.57 +\%0200\\0.02 +\| +~C|IEP030|Ud|Red de equipotencialidad en cuarto hmedo.|14.31|250315|0| +~T|IEP030|Red de equipotencialidad en cuarto hmedo.| +~D|IEP030 +|mt35ttc020ac\\7 +\mt35ttc030\\5 +\mt35www020\\0.25 +\mo001\\0.32 +\mo052\\0.32 +\%0200\\0.02 +\| +~C|IF#||Fontanera|778.13|250315|0| +~D|IF# +|IFA010\\1 +\IFB010\\1 +\IFC010\\1 +\IFI010\\1 +\IFI010b\\1 +\IFI010c\\1 +\IFI010d\\1 +\| +~C|IFA010|Ud|Acometida enterrada de abastecimiento de agua potable|129.33|250315|0| +~T|IFA010|Acometida enterrada de abastecimiento de agua potable de 4 m de longitud, formada por tubo de polietileno de alta densidad banda azul (PE-100), de 25 mm de dimetro exterior, PN=16 atm y llave de corte alojada en arqueta prefabricada de polipropileno.| +~D|IFA010 +|mt10hmf010agc\\0.11 +\mt01ara010\\0.44 +\mt37tpa012b\\1 +\mt37tpa011b\\4 +\mt11arp100a\\1 +\mt11arp050ac\\1 +\mt37sve030c\\1 +\mt10hmf010agc\\0.3 +\mq05pdm010b\\1.3 +\mq05mai030\\1.3 +\mo011\\0.04 +\mo029\\0.86 +\mo060\\0.47 +\mo004\\2.87 +\mo055\\1.44 +\%0400\\0.04 +\| +~C|IFB010|Ud|Alimentacin de agua potable|12.11|250315|0| +~T|IFB010|Alimentacin de agua potable de 8 m de longitud, colocada superficialmente, formada por tubo de polietileno reticulado (PE-X), de 20 mm de dimetro exterior, serie 5, PN=6 atm.| +~D|IFB010 +|mt37tpu400ab\\8 +\mt37tpu010abg\\8 +\mo004\\0.13 +\mo055\\0.13 +\%0200\\0.02 +\| +~C|IFC010|Ud|Preinstalacin de contador general de agua|23.7|250315|0| +~T|IFC010|Preinstalacin de contador general de agua de 1/2" DN 15 mm, colocado en hornacina, con llave de corte general de compuerta.| +~D|IFC010 +|mt37svc010a\\2 +\mt37www060b\\1 +\mt37sgl012a\\1 +\mt37svr010a\\1 +\mt37aar010a\\1 +\mt37www010\\1 +\mo004\\0.32 +\mo055\\0.16 +\%0400\\0.04 +\| +~C|IFI010|Ud|Instalacin interior de fontanera para aseo|142.15|250315|0| +~T|IFI010|Instalacin interior de fontanera para aseo con dotacin para: inodoro, lavabo sencillo, realizada con polietileno reticulado (PE-X), para la red de agua fra y caliente.| +~D|IFI010 +|mt37tpu400aa\\8.1 +\mt37tpu010aag\\8.1 +\mt37tpu400ab\\15 +\mt37tpu010abg\\15 +\mt37avu150ab\\2 +\mo004\\1.82 +\mo055\\1.82 +\%0200\\0.02 +\| +~C|IFI010b|Ud|Instalacin interior de fontanera para cuarto de bao|195.05|250315|0| +~T|IFI010b|Instalacin interior de fontanera para cuarto de bao con dotacin para: inodoro, lavabo sencillo, baera, bid, realizada con polietileno reticulado (PE-X), para la red de agua fra y caliente.| +~D|IFI010b +|mt37tpu400aa\\13.5 +\mt37tpu010aag\\13.5 +\mt37tpu400ab\\5.4 +\mt37tpu010abg\\5.4 +\mt37tpu400ab\\8.5 +\mt37tpu010abg\\8.5 +\mt37tpu400ac\\8.5 +\mt37tpu010acg\\8.5 +\mt37avu150ab\\1 +\mt37avu150ac\\1 +\mo004\\2.83 +\mo055\\2.83 +\%0200\\0.02 +\| +~C|IFI010c|Ud|Instalacin interior de fontanera para cocina|134.88|250315|0| +~T|IFI010c|Instalacin interior de fontanera para cocina con dotacin para: fregadero, toma y llave de paso para lavavajillas, realizada con polietileno reticulado (PE-X), para la red de agua fra y caliente.| +~D|IFI010c +|mt37tpu400aa\\8.1 +\mt37tpu010aag\\8.1 +\mt37tpu400ab\\11 +\mt37tpu010abg\\11 +\mt37avu150ab\\2 +\mt31gcg070a\\1 +\mo004\\1.5 +\mo055\\1.5 +\%0200\\0.02 +\| +~C|IFI010d|Ud|Instalacin interior de fontanera para lavadero|125.66|250315|0| +~T|IFI010d|Instalacin interior de fontanera para galera con dotacin para: lavadero, toma y llave de paso para lavadora, realizada con polietileno reticulado (PE-X), para la red de agua fra y caliente.| +~D|IFI010d +|mt37tpu400aa\\2.7 +\mt37tpu010aag\\2.7 +\mt37tpu400ab\\5.4 +\mt37tpu010abg\\5.4 +\mt37tpu400ab\\8 +\mt37tpu010abg\\8 +\mt37avu150ab\\2 +\mt31gcg070a\\1 +\mo004\\1.27 +\mo055\\1.27 +\%0200\\0.02 +\| +~C|II#||Iluminacin|0|150415|0| +~D|II# +|Pa4\\1 +\| +~C|IL#||Infraestructura de telecomunicaciones|89.74|250315|0| +~D|IL# +|ILA020\\5 +\ILE030\\3 +\ILS010\\10 +\ILI001\\1 +\| +~C|ILA020|m|Canalizacin externa|6.61|250315|0| +~T|ILA020|Canalizacin externa enterrada formada por 3 tubos de polietileno de 63 mm de dimetro, en edificacin de hasta 4 PAU.| +~D|ILA020 +|mt35aia070aaa\\3 +\mt40iva020d\\1.18 +\mt10hmf010agc\\0.07 +\mt40www050\\0.3 +\mo011\\0.03 +\mo060\\0.03 +\%0200\\0.02 +\| +~C|ILE030|m|Canalizacin de enlace|2.58|060415|0| +~T|ILE030|Canalizacin de enlace superior empotrada formada por 2 tubos de polipropileno flexible, corrugados de 40 mm de dimetro, para vivienda unifamiliar.| +~D|ILE030 +|mt35aia060aaa\\2 +\mt40iva030\\2.4 +\mt40www050\\0.2 +\mo000\\0.01 +\mo030\\0.02 +\%0200\\0.02 +\| +~C|ILI001|Ud|Registro de terminacin de red|20.54|060415|0| +~T|ILI001|Registro de terminacin de red, formado por caja de plstico para empotrar en tabique y disposicin del equipamiento principalmente en vertical.| +~D|ILI001 +|mt40irt020aa\\1 +\mt40www050\\0.5 +\mo000\\0.1 +\mo030\\0.1 +\%0200\\0.02 +\| +~C|ILS010|m|Canalizacin secundaria|2.67|060415|0| +~T|ILS010|Canalizacin secundaria empotrada en tramo comunitario, formada por 4 tubos de PVC flexible, corrugados, reforzados de 32 mm de dimetro, en edificacin de hasta 3 PAU.| +~D|ILS010 +|mt35aia020aad\\4 +\mt40iva030\\4.8 +\mt40www050\\0.4 +\mo000\\0.03 +\mo030\\0.03 +\%0200\\0.02 +\| +~C|IS#||Salubridad|2069.53|250315|0| +~D|IS# +|ISB010\\3.25 +\ISB010b\\6.5 +\ISD010\\1 +\ISD010b\\2 +\ISD010c\\1 +\ISH010c\\3 +\ISK010\\1 +\ISK030\\1 +\ISV020\\5.22 +\ICO015\\16 +\| +~C|ISB010|m|Bajante interior de la red de evacuacin de aguas residuales|6.86|250315|0| +~T|ISB010|Bajante interior de la red de evacuacin de aguas residuales, formada por PVC, serie B, de 90 mm de dimetro, unin pegada con adhesivo.| +~D|ISB010 +|mt36tit400af\\1 +\mt36tit010afi\\1 +\mt11var009\\0.03 +\mt11var010\\0.01 +\mo004\\0.05 +\mo055\\0.02 +\%0200\\0.02 +\| +~C|ISB010b|m|Bajante interior de la red de evacuacin de aguas residuales|8.99|250315|0| +~T|ISB010b|Bajante interior de la red de evacuacin de aguas residuales, formada por PVC, serie B, de 125 mm de dimetro, unin pegada con adhesivo.| +~D|ISB010b +|mt36tit400ah\\1 +\mt36tit010ahi\\1 +\mt11var009\\0.05 +\mt11var010\\0.02 +\mo004\\0.07 +\mo055\\0.03 +\%0200\\0.02 +\| +~C|ISD010|Ud|Red interior de evacuacin para aseo|60.79|250315|0| +~T|ISD010|Red interior de evacuacin para aseo con dotacin para: inodoro, lavabo sencillo, realizada con tubo de PVC, serie B para la red de desages.| +~D|ISD010 +|mt36tit010abc\\2.65 +\mt36tit010agc\\2.13 +\mt11var009\\0.28 +\mt11var010\\0.14 +\mo004\\1.91 +\mo055\\0.96 +\%0200\\0.02 +\| +~C|ISD010b|Ud|Red interior de evacuacin para cuarto de bao|103.77|250315|0| +~T|ISD010b|Red interior de evacuacin para cuarto de bao con dotacin para: inodoro, lavabo sencillo, baera, bid, realizada con tubo de PVC, serie B para la red de desages.| +~D|ISD010b +|mt36tit010abc\\4.8 +\mt36tit010abc\\1.65 +\mt36tit010agc\\2.13 +\mt11var009\\0.45 +\mt11var010\\0.22 +\mo004\\3.44 +\mo055\\1.72 +\%0200\\0.02 +\| +~C|ISD010c|Ud|Red interior de evacuacin para cocina|49.19|250315|0| +~T|ISD010c|Red interior de evacuacin para cocina con dotacin para: fregadero, toma de desage para lavavajillas, realizada con tubo de PVC, serie B para la red de desages.| +~D|ISD010c +|mt36tit010abc\\4.3 +\mt30del010aaa\\1 +\mt11var009\\0.22 +\mt11var010\\0.11 +\mo004\\1.72 +\mo055\\0.86 +\%0200\\0.02 +\| +~C|ISH010c|Ud|Boca de extraccin, graduable|10.44|260315|0| +~T|ISH010c|Boca de extraccin, graduable, caudal mximo 19 l/s, de 125 mm de dimetro de conexin y 165 mm de dimetro exterior, para paredes o techos de locales hmedos (cocina), para ventilacin hbrida.| +~D|ISH010c +|mt20svg050aab\\1 +\mo006\\0.06 +\mo048\\0.06 +\%0200\\0.02 +\| +~C|ISK010|Ud|Extractor de cocina|34.61|250315|0| +~T|ISK010|Extractor de cocina, de dimensiones 218x127x304 mm, velocidad 2250 r.p.m., caudal de descarga libre 250 m/h, con tramo de conexin de tubo flexible de aluminio.| +~D|ISK010 +|mt32exs010a\\1 +\mt20cme020ad\\3 +\mo001\\0.08 +\mo052\\0.08 +\%0200\\0.02 +\| +~C|ISK030|Ud|Aspirador giratorio con sombrero dinmico|74.33|260315|0| +~T|ISK030|Aspirador giratorio con sombrero dinmico, de aluminio (Dureza H-24), para conducto de salida de 250 mm de dimetro exterior.| +~D|ISK030 +|mt20cve010aaa\\1 +\mo006\\0.06 +\mo048\\0.03 +\%0200\\0.02 +\| +~C|ISS010|m|Colector enterrado de PVC, serie B, de 160 mm de dimetro, unin|0|060415|0| +~T|ISS010|Colector suspendido de PVC, serie B, de 160 mm de dimetro, unin pegada con adhesivo.| +~C|ISV020|m|Conducto circular de chapa de acero galvanizado|3.68|260315|0| +~T|ISV020|Conducto circular de chapa de acero galvanizado de pared simple lisa, de 100 mm de dimetro y 0,6 mm de espesor de chapa, colocado en posicin horizontal, para instalacin de ventilacin.| +~D|ISV020 +|mt20cvg410a\\1 +\mt20cvg010aad\\1 +\mo006\\0.05 +\mo048\\0.03 +\%0200\\0.02 +\| +~C|N#||Aislamientos e impermeabilizaciones|2488.21|060415|0| +~D|N# +|NA#\\1 +\NI#\\1 +\| +~C|NA#||Aislamientos|1780.91|060415|0| +~D|NA# +|NAF010\\319.49 +\NAP020\\123.51 +\NAL050\\98.51 +\NAT010\\5.7 +\| +~C|NAF010|m|Aislamiento por el interior en fachada de poliuretano proyectado|2.77|060415|0| +~T|NAF010|Aislamiento por el interior en fachada de doble hoja de fbrica cara vista formado por espuma rgida de poliuretano proyectado de 30 mm de espesor mnimo, 30 kg/m de densidad mnima, aplicado mediante proyeccin mecnica.| +~D|NAF010 +|mt16pop010ac\\1 +\%0200\\0.02 +\| +~C|NAL050|m|Aislamiento trmico de suelos|5.65|060415|0| +~T|NAL050|Aislamiento trmico de suelos flotantes formado por panel rgido de poliestireno extruido, de superficie lisa y mecanizado lateral recto, de 40 mm de espesor, resistencia a compresin >= 300 kPa, resistencia trmica 1,2 mK/W, conductividad trmica 0,034 W/(mK), cubierto con un film de polietileno de 0,2 mm de espesor, preparado para recibir una solera de mortero u hormign (no incluida en este precio).| +~D|NAL050 +|mt16pxa010p\\1.05 +\mt17poa010b\\1.05 +\mt16aaa030\\0.4 +\mo050\\0.04 +\mo093\\0.04 +\%0200\\0.02 +\| +~C|NAP020|m|Aislamiento intermedio en entramados autoportantes|2.17|060415|0| +~T|NAP020|Aislamiento intermedio en entramados autoportantes de placas constituido por: panel semirrgido de lana mineral, espesor 65 mm colocado entre montantes.| +~D|NAP020 +|mt16lra060b\\1 +\mo050\\0.02 +\mo093\\0.02 +\%0200\\0.02 +\| +~C|NAT010|m|Aislamiento sobre falso techo|6.25|060415|0| +~T|NAT010|Aislamiento sobre falso techo formado por panel semirrgido de lana mineral, segn UNE-EN 13162, no revestido, de 40 mm de espesor.| +~D|NAT010 +|mt16lra020na\\1.05 +\mo050\\0.08 +\mo093\\0.08 +\%0200\\0.02 +\| +~C|NI#||Impermeabilizaciones|707.3|060415|0| +~D|NI# +|NIG040\\192.2 +\| +~C|NIG040|m|Impermeabilizacin de solera mediante lmina de PVC|3.61|060415|0| +~T|NIG040|Impermeabilizacin de solera mediante lmina de PVC extendida en rollo| +~D|NIG040 +|mt15dan010abj\\1.05 +\mo018\\0.1 +\mo039\\0.1 +\%0200\\0.02 +\| +~C|P#||Particiones|9722.1|250315|0| +~D|P# +|PA#\\1 +\PD#\\1 +\PP#\\1 +\PT#\\1 +\PR#\\1 +\| +~C|PA#||Armarios|1393.62|250315|0| +~D|PA# +|PAF010\\1 +\PAF010b\\1 +\PAF010c\\1 +\PAF010d\\1 +\| +~C|PAF010|Ud|Armario prefabricado para empotrar de siete hojas abatibles|400.63|250315|0| +~T|PAF010|Armario prefabricado para empotrar de siete hojas abatibles, de 250x290x60 cm de tablero melamnico.Segn planos de proyecto| +~D|PAF010 +|mt22eap010dl\\2 +\mo008\\1.05 +\mo031\\0.53 +\%0200\\0.02 +\| +~C|PAF010b|Ud|Armario prefabricado para empotrar de cuatro hojas abatibles|178.61|250315|0| +~T|PAF010b|Armario prefabricado para empotrar de cuatro hojas abatibles, de 250x170x60 cm de tablero melamnico.Segn planos de proyecto| +~D|PAF010b +|mt22eap010ch\\1 +\mo008\\0.87 +\mo031\\0.44 +\%0200\\0.02 +\| +~C|PAF010c|Ud|Armario prefabricado para empotrar de seis hojas abatibles|336.82|250315|0| +~T|PAF010c|Armario prefabricado para empotrar de tres hojas abatibles, de 250x250x60 cm de tablero melamnico.Segn planos de proyecto| +~D|PAF010c +|mt22eap010ch\\2 +\mo008\\0.87 +\mo031\\0.44 +\%0200\\0.02 +\| +~C|PAF010d|Ud|Mueble estantera de tablero melamnico.|450.24|250315|0| +~T|PAF010d|Mueble estantera de tablero melamnico. Con nucleo de aglomerado y melamina superficial con espesor de balda de 5cm.Segn planos de proyecto| +~D|PAF010d +|mt22eap010ds\\2 +\mo008\\1.05 +\mo031\\0.53 +\%0200\\0.02 +\| +~C|PD#||Defensas interiores|357.22|250315|0| +~D|PD# +|PDB010b\\7.24 +\Pa13\\14.16 +\| +~C|PDB010|m|Barandilla de fabrica de ladrillo para reparacion de escalera ex|43.57|250315|0| +~T|PDB010|Barandilla de fabrica de ladrillo para reparacion de escalera exterior con LHS de 6cm, tomado con mortero de cemento, enfoscado por su cara interior. I/pp de flejes metlicos para union con barandilla existente| +~D|PDB010 +|mt26aaa031\\1 +\mt26dbe010aaa\\1 +\mo060\\0.09 +\mo009\\0.52 +\mo032\\0.52 +\%0200\\0.02 +\| +~C|PDB010b|m|Barandilla metlica de tubo hueco de acero laminado en fro de 9|48.37|250315|0| +~T|PDB010b|Barandilla metlica de tubo hueco de acero laminado en fro de 90 cm de altura. Segn proyecto| +~D|PDB010b +|mt26aaa031\\1 +\mt26dbe040aaa\\1 +\mo060\\0.1 +\mo009\\0.52 +\mo032\\0.52 +\mo028\\0.14 +\mo057\\0.14 +\%0200\\0.02 +\| +~C|PEH010b|Ud|Puerta blindada de entrada|480.64|250315|0| +~T|PEH010b|Puerta blindada de entrada de 203x82,5x4,5 cm, hoja de tablero aglomerado, chapado con iroko, barnizada en taller; precerco de pino pas de 130x40 mm; galces de MDF rechapado de iroko de 130x20 mm; tapajuntas de MDF rechapado de iroko de 70x10 mm.| +~D|PEH010b +|mt22aap011wa\\1 +\mt22aga010deo\\5.1 +\mt22ata010adr\\10.4 +\mt23ppa020a\\1 +\mt22pxh011db\\1 +\mt23ppa030\\1 +\mt23hax010a\\1 +\mt23hax020a\\1 +\mt23hax100a\\1 +\mo016\\1.94 +\mo053\\1.94 +\%0200\\0.02 +\| +~C|PP#||Puertas de paso interiores|889.1|250315|0| +~D|PP# +|PPM010\\5 +\PEH010b\\1 +\| +~C|PPM010|Ud|Puerta de paso ciega|78.21|250315|0| +~T|PPM010|Puerta de paso ciega, de una hoja de 203x82,5x3,5 cm, de tablero aglomerado directo, barnizada en taller, de iroko, modelo con moldura recta; precerco de pino pas de 90x35 mm; galces de MDF, con rechapado de madera, de iroko de 90x20 mm; tapajuntas de MDF, con rechapado de madera, de iroko de 70x10 mm.| +~D|PPM010 +|mt22aap011daa\\1 +\mt22aga010dbd\\5.1 +\mt22ata010dba\\10.4 +\mt22pxf020aad\\1 +\mt23ibl010bab\\3 +\mt23ppb031\\18 +\mt23ppb200\\1 +\mt23hbl010aaa\\1 +\mo008\\0.43 +\mo031\\0.43 +\%0200\\0.02 +\| +~C|PR#||Remates|25.6|250315|0| +~D|PR# +|PRF010\\2 +\| +~C|PRF010|m|Forrado de chimeneas|12.55|250315|0| +~T|PRF010|Forrado de conducto de ventilacin en rincn de tabiquera, de 50x100 cm, con ladrillo cermico hueco (borgoa), para revestir, 24x11,5x6 cm, recibido con mortero de cemento M-5.| +~D|PRF010 +|mt04lac010b\\48 +\mt09mor010c\\0.01 +\mo011\\0.47 +\mo060\\0.23 +\%0200\\0.02 +\| +~C|PSY010d|m|Tabique mltiple (12,5+12,5+70+12,5+12,5)/600 (70) hidrofugado/h|18.44|060415|0| +~T|PSY010d|Tabique mltiple (12,5+12,5+70+12,5+12,5)/600 (70) (1 hidrofugado + 1 normal + 1 normal + 1 hidrofugado) con placas de yeso laminado, sobre banda acstica, formado por una estructura simple, con disposicin normal "N" de los montantes; 120 mm de espesor total.| +~D|PSY010d +|mt12psg041c\\1.2 +\mt12psg070d\\0.7 +\mt12psg060d\\2 +\mt12psg010a\\1.05 +\mt12psg010p\\1.05 +\mt12psg010a\\1.05 +\mt12psg010p\\1.05 +\mt12psg081b\\13 +\mt12psg081c\\29 +\mt12psg220\\1.6 +\mt12psg035a\\0.2 +\mt12psg030a\\1 +\mt12psg040a\\3.2 +\mo049\\0.16 +\mo092\\0.16 +\%0200\\0.02 +\| +~C|PSY010e|m|Tabique mltiple (12,5+12,5+70+12,5+12,5)/600 (70) ( normal/hidr|17.29|060415|0| +~T|PSY010e|Tabique mltiple (12,5+12,5+70+12,5+12,5)/600 (70) (1 normal + 1 normal + 1 normal + 1 hidrofugado) con placas de yeso laminado, sobre banda acstica, formado por una estructura simple, con disposicin normal "N" de los montantes; 120 mm de espesor total.| +~D|PSY010e +|mt12psg041c\\1.2 +\mt12psg070d\\0.7 +\mt12psg060d\\2 +\mt12psg010a\\1.05 +\mt12psg010a\\1.05 +\mt12psg010a\\1.05 +\mt12psg010p\\1.05 +\mt12psg081b\\13 +\mt12psg081c\\29 +\mt12psg220\\1.6 +\mt12psg035a\\0.2 +\mt12psg030a\\1 +\mt12psg040a\\3.2 +\mo049\\0.16 +\mo092\\0.16 +\%0200\\0.02 +\| +~C|PSY010f|m|Tabique mltiple (12,5+12,5+70+12,5+12,5)/600 (70) (normal/norma|16.14|060415|0| +~T|PSY010f|Tabique mltiple (12,5+12,5+70+12,5+12,5)/600 (70) (1 normal + 1 normal + 1 normal + 1 normal) con placas de yeso laminado, sobre banda acstica, formado por una estructura simple, con disposicin normal "N" de los montantes; 120 mm de espesor total.| +~D|PSY010f +|mt12psg041c\\1.2 +\mt12psg070d\\0.7 +\mt12psg060d\\2 +\mt12psg010a\\1.05 +\mt12psg010a\\1.05 +\mt12psg010a\\1.05 +\mt12psg010a\\1.05 +\mt12psg081b\\13 +\mt12psg081c\\29 +\mt12psg220\\1.6 +\mt12psg035a\\0.2 +\mt12psg030a\\1 +\mt12psg040a\\3.2 +\mo049\\0.16 +\mo092\\0.16 +\%0200\\0.02 +\| +~C|PT#||Tabiques|7056.56|260315|0| +~D|PT# +|PTW015\\319.49 +\PSY010d\\9.24 +\PSY010e\\32.2 +\PSY010f\\82.07 +\FDA005\\10.38 +\| +~C|PTW015|m|Trasdosado autoportante interior|11.44|260315|0| +~T|PTW015|Trasdosado autoportante libre sobre particin interior, W 626 "KNAUF", realizado con dos placas de yeso laminado - /15 Standard (A) + 15 impregnada (H)/, anclada a los forjados mediante estructura formada por canales y montantes; 78 mm de espesor total, separacin entre montantes 600 mm.| +~D|PTW015 +|mt12pik015\\0.15 +\mt12pfk020c\\0.7 +\mt12pfk010c\\2 +\mt12pck020b\\1.2 +\mt12ppk010ab\\1.05 +\mt12ppk010db\\1.05 +\mt12ptk010ad\\6 +\mt12ptk010af\\14 +\mt12psg220\\1.6 +\mt12pik010b\\0.4 +\mt12pck010a\\1.6 +\mo006\\0.18 +\mo048\\0.06 +\%0200\\0.02 +\| +~C|PTZ010|m|Hoja de particin interior de 8 cm de espesor de fbrica de ladr|13.11|060415|0| +~T|PTZ010|Hoja de particin interior de 8 cm de espesor de fbrica, de ladrillo cermico hueco (cubo), para revestir, 24x11,5x8 cm, recibida con mortero de cemento M-5.| +~D|PTZ010 +|mt04lac010c\\34.65 +\mt09mor010c\\0.01 +\mo011\\0.45 +\mo060\\0.22 +\%0200\\0.02 +\| +~C|Pa10|ud|Formacion de chimenea en cubierta inclinada|0|150415|3| +~T|Pa10|Formacion de chimenea en cubierta con ladrillo semimacizo a 1/2 pie, enfoscado con mortero de cemento fratasado y pintura de fachada. I/pp de encuentro con cubierta inclinada mediante realizacion de medias caas, impermeabilizacion de encuentros con teja cermica y pintura al clorocaucho. I/pp de sombrerete de lamas de acero lacado. Completamente finalizada.| +~C|Pa11|ud|Tirante de acero en cerchas|0|160415|3| +~T|Pa11|Unin articulada en clave de prtico mediante conectores atravesados por pernos roscados cuyas cabezas se embeben en cajeado practicado en las vigas de madera para una correcta transmisin de esfuerzos, compuesto por barra de dimetro 10mm de acero de calidad S275JR para tirante, anclado en vigas de madera aserrada de calidad C18, i/pp. de elementos de fijacin y apriete.i/pp de mecanizado y cajeado de vigas. Totalmente finalizadas y puesta en servicio, segn planos de proyecto.| +~C|Pa13|m|Barras de proteccion de huecos|0|150415|3| +~T|Pa13|Barras de acero inox. mate de diametro 10mm para la proteccion de huecos de ventanas de plantas altas| +~C|Pa3|m2|Cierre fijo de lamas de Iroko|0|150415|3| +~T|Pa3|Cierre exterior de lamas de Iroko barnizado satinado formado por piezas de seccin 3x9cm colocadas cada 9cm, clavadas a bastidor perimtral de madera de iroko de seccion rectangular de 3x9cm| +~C|Pa4||Luminarias exterior e interior|0|150415|3| +~T|Pa4|Partida alzada para luminarias interiores y exteriores de vivienda| +~C|Pa6|m|Peldaeado de tablero de madera|0|150415|3| +~T|Pa6|Peldaeado de escalera mediante tablero de madera de iroko o similar de 5cm de espesor, barnizado y atornillado a estructura metlica| +~C|Pa7|ud|Cocina completa|0|150415|3| +~T|Pa7|Partida alzada para cocina completa compuesta por muebles bajos y altos acabado en melamina con tiradoes en acero mate. Encimera de granito nacional de 2cm de especor con zocalo de 7cm. Horno, vitrocermica y campana extractora serie Balay o similar de gran formato. Distribucion segn proyecto.| +~C|Pa8|ud|Reparacion de cierre existente|0|150415|3| +~T|Pa8|Partida alzada para reparacin de muro de cierre existente mediante limpieza y desbroce vegetal, retacando con mortero bastardo de cemento y cal la cara interior, superior y exterior del muro para el tapado de grietas. En cierre frontal izquierdo incluye repicado de mortero existente, nuevo enfoscado de cemento y pintura blanca de fachada.| +~C|Pa9|ud|Reparacin de escalera Edificio A|0|150415|3| +~T|Pa9|Reparacion de escalera de Edificio A, consistente en picado del peldaeado actual, nivelacion de peldaos con material ceramico y mortero de cemento. Huellas, tabicas y zocalos mediante piezas de granito Silvestre abujardado de 2cm de espesor, tomado con mortero de cemento.| +~C|Q#||Cubiertas|16183.49|250315|0| +~D|Q# +|QA#\\1 +\QT#\\1 +\| +~C|QA#||Planas|557.86|250315|0| +~D|QA# +|QTZ010\\12.67 +\| +~C|QT#||Inclinadas|15625.63|250315|0| +~D|QT# +|QTT210\\235.05 +\QTT020\\120.54 +\Pa10\\3 +\| +~C|QTT020|m|Cubierta inclinada sobre espacio no habitable|28.88|250315|0| +~T|QTT020|Cubierta inclinada de tejas cermicas, sobre espacio no habitable, con una pendiente media del 30%, compuesta de: formacin de pendientes: tableros de partculas de madera, con tratamiento hidrfugo y bordes machihembrados, de 18 mm de espesor; impermeabilizacin: placa bajo teja, cobertura: teja cermica curva, 40x19x16 cm, color rojo, fijada con clavos galvanizados sobre rastreles de madera.| +~D|QTT020 +|mt07tdm010e\\1.05 +\mt50spa101\\0.15 +\mt13lpo010fh\\1.25 +\mt13lpo034b\\3 +\mt13blw010d\\3 +\mt13blw131\\6 +\mt13tac010a\\31.4 +\mt13tac013a\\0.1 +\mt13blw102\\4.5 +\mo010\\0.52 +\mo075\\0.52 +\%0200\\0.02 +\| +~C|QTT210|m|Cubierta inclinada sobre espacio habitable|50.36|250315|0| +~T|QTT210|Cubierta inclinada con una pendiente media del 45%, compuesta de: formacin de pendientes: panel sndwich para cubiertas, modelo TFcH/9-60-19 "THERMOCHIP", compuesto de: cara exterior de tablero de aglomerado hidrfugo de 19 mm de espesor, ncleo aislante de poliestireno extruido Styrofoam IBF de 60 mm de espesor, cara interior de tablero contrachapado fenlico de 9 mm de espesor, chapado con castao, sobre entramado estructural (no incluido en este precio); impermeabilizacin: placa bajo teja BT 235 "ONDULINE"; cobertura: teja cermica curva, 40x19x16 cm, color rojo; fijada con espuma de poliuretano.| +~D|QTT210 +|mt13eag011aac\\1.09 +\mt13eag020\\5 +\mt13eag030\\1 +\mt13bto010e\\1.25 +\mt13bto020a\\0.3 +\mt13lpo034a\\3 +\mt13bto025a\\0.1 +\mt13tac010aa\\25.6 +\mt13tac011a\\0.32 +\mt13tac010aa\\0.4 +\mt13tac010aa\\1.73 +\mt13tac013a\\0.1 +\mo011\\0.42 +\mo046\\0.42 +\mo060\\0.21 +\%0200\\0.02 +\| +~C|QTZ010|m|Cubierta zinctitanio|43.17|250315|0| +~T|QTZ010|Cubierta inclinada con una pendiente media del 5%, formada por estructura portante (no incluida en este precio), film de polietileno que acta como barrera de vapor y panel flexible y ligero de lana de roca volcnica, segn UNE-EN 13162, no revestido, de 40 mm de espesor como aislamiento trmico, dispuesto entre cabios de madera de 80x120 mm de seccin. Cobertura compuesta por bandeja de zinctitanio, "RHEINZINK" Clic System, acabado natural, de 0,7 mm de espesor, ejecutado mediante el sistema de junta de listn a partir de material en banda de 650 mm de desarrollo, 565 mm entre ejes y juntas de 47 mm de altura, fijada mecnicamente sobre tablero OSB de virutas orientadas intercalando entre ambos una lmina de separacin estructurada.| +~D|QTZ010 +|mt17poa010a\\1.05 +\mt07mee040c\\1.3 +\mt13eag023\\10.58 +\mt16lra020aba\\1.05 +\mt13blm020\\1.05 +\mt13blm030\\12.5 +\mt20wwr030\\1.05 +\mt13ccz030baa\\1.07 +\mo011\\0.15 +\mo046\\0.03 +\mo059\\0.12 +\%0200\\0.02 +\| +~C|R#||Revestimientos|19501.1|250315|0| +~D|R# +|RA#\\1 +\RE#\\1 +\RF#\\1 +\RI#\\1 +\RM#\\1 +\RN#\\1 +\RP#\\1 +\RS#\\1 +\RT#\\1 +\| +~C|RA#||Alicatados|1375.68|060415|0| +~D|RA# +|RAG012\\142.41 +\| +~C|RAG012|m|Alicatado con azulejo liso, 1/0/-/-, 20x20 cm|9.47|060415|0| +~T|RAG012|Alicatado con azulejo liso, 1/0/-/-, 20x20 cm, 8 /m, colocado sobre una superficie soporte de placas de yeso laminado en paramentos interiores, mediante adhesivo cementoso normal, C1, gris, sin junta (separacin entre 1,5 y 3 mm); cantoneras de PVC.| +~D|RAG012 +|mt09mcr021baa\\3 +\mt19awa010\\0.5 +\mt19aba010aaa\\1.05 +\mt09lec010b\\0.01 +\mo015\\0.15 +\mo036\\0.15 +\%0200\\0.02 +\| +~C|RE#||Escaleras|0|150415|0| +~D|RE# +|Pa6\\17 +\| +~C|RF#||Pinturas en paramentos exteriores|1546.81|010415|0| +~D|RF# +|RFP010\\316.97 +\| +~C|RFP010|m|Revestimiento decorativo de fachadas con pintura plstica lisa|4.78|010415|0| +~T|RFP010|Revestimiento decorativo de fachadas con pintura plstica lisa, para la realizacin de la capa de acabado en revestimientos continuos bicapa; limpieza y lijado previo del soporte de mortero tradicional, en buen estado de conservacin, mano de fondo y dos manos de acabado (rendimiento: 0,1 l/m cada mano).| +~D|RFP010 +|mt27pij100aaa\\0.2 +\mt27pij020aba\\0.2 +\mo024\\0.1 +\mo045\\0.1 +\%0200\\0.02 +\| +~C|RI#||Pinturas en paramentos interiores|3154.28|010415|0| +~D|RI# +|RIP035\\817.17 +\| +~C|RIP035|m|Pintura plstica sobre paramentos horizontales y verticales inte|3.78|010415|0| +~T|RIP035|Pintura plstica con textura lisa, color blanco, acabado mate, sobre paramentos horizontales y verticales interiores de yeso proyectado o placas de yeso laminado, mano de fondo y dos manos de acabado (rendimiento: 0,125 l/m cada mano).| +~D|RIP035 +|mt27pfj010aaa\\0.18 +\mt27pij040aaa\\0.25 +\mo024\\0.08 +\mo045\\0.09 +\%0200\\0.02 +\| +~C|RM#||Pinturas sobre soporte de madera|58.3|010415|0| +~D|RM# +|RME020\\12.3 +\| +~C|RME020|m|Esmalte sinttico, color blanco, acabado satinado|4.65|010415|0| +~T|RME020|Esmalte sinttico, color blanco, acabado satinado, sobre superficie de carpintera interior de madera, preparacin del soporte, mano de fondo (rendimiento: 0,111 l/m) y dos manos de acabado con esmalte sinttico (rendimiento: 0,091 l/m cada mano).| +~D|RME020 +|mt27plj010aaa\\0.11 +\mt27esj020aaa\\0.18 +\mo024\\0.14 +\mo045\\0.03 +\%0200\\0.02 +\| +~C|RN#||Pinturas sobre soporte metlico|65.6|010415|0| +~D|RN# +|RNP010\\10 +\| +~C|RNP010|m|Pintura plstica sobre soporte metlico Hemmerite o similar|6.43|010415|0| +~T|RNP010|Pintura plstica con textura lisa, color a elegir, acabado mate, sobre soporte prelacado y/o pintado con toda la superficie en buen estado, de metal, lavado a alta presin con agua y una solucin de agua y leja al 10%, aclarado y secado, aplicacin de dos manos de acabado con pintura (rendimiento: 0,25 l/m cada mano).| +~D|RNP010 +|mt27pfc030a\\0.3 +\mt27pir090aaa\\0.5 +\mo024\\0.08 +\mo045\\0.08 +\%0200\\0.02 +\| +~C|RP#||Conglomerados tradicionales|3559.78|250315|0| +~D|RP# +|RPE010\\306.59 +\RPE005\\112.75 +\RPG011\\112.75 +\| +~C|RPE005|m|Enfoscado de cemento, a buena vista|5.49|250315|0| +~T|RPE005|Enfoscado de cemento, a buena vista, aplicado sobre un paramento vertical interior, hasta 3 m de altura, acabado superficial rugoso, con mortero de cemento M-5, previa colocacin de malla antilcalis en cambios de material y en los frentes de forjado.| +~D|RPE005 +|mt09mor010c\\0.02 +\mt09var030aaa\\0.21 +\mo011\\0.19 +\mo060\\0.1 +\%0200\\0.02 +\| +~C|RPE010|m|Enfoscado de cemento exterior, armado y reforzado con malla anti|9|250315|0| +~T|RPE010|Enfoscado de cemento, a buena vista, aplicado sobre un paramento vertical exterior, acabado superficial rugoso, con mortero de cemento hidrfugo M-5, armado y reforzado con malla antilcalis incluso en los cambios de material y en los frentes de forjado, previa aplicacin de una primera capa de mortero de agarre sobre el paramento.| +~D|RPE010 +|mt09mor010f\\0.01 +\mt09moe010a\\0.02 +\mt09var030aaa\\1.26 +\mo011\\0.28 +\mo060\\0.18 +\%0200\\0.02 +\| +~C|RPG011|m|Enlucido de yeso de aplicacin en capa fina|0.99|060415|0| +~T|RPG011|Enlucido de yeso de aplicacin en capa fina C6, en una superficie previamente guarnecida, sobre paramento vertical, de hasta 3 m de altura.| +~D|RPG011 +|mt09pye010a\\0.01 +\mo019\\0.03 +\mo040\\0.01 +\%0200\\0.02 +\| +~C|RS#||Suelos y pavimentos|9400.95|250315|0| +~D|RS# +|RSB010\\224.66 +\RSG011\\150.91 +\RSM022\\29.18 +\RSY050\\29.18 +\RSP011\\78.85 +\RSM040\\87.3 +\RSG020\\60.09 +\RSM050\\77.76 +\RSP020\\44.59 +\RSG010\\17.95 +\RSM021\\14 +\| +~C|RSB010|m|Recrecido de mortero M-10 de 5 cm de espesor|5.65|250315|0| +~T|RSB010|Base para pavimento, de mortero M-10 de 5 cm de espesor, maestreada y fratasada.| +~D|RSB010 +|mt09mor010e\\0.05 +\mt16pea020aa\\0.05 +\mo011\\0.09 +\mo060\\0.1 +\%0200\\0.02 +\| +~C|RSG010|m|Solado de baldosas cermicas de gres porcelnico|18.36|060415|0| +~T|RSG010|Solado de baldosas cermicas de gres porcelnico, pulido 2/0/-/-, de 30x30 cm, 8 /m, recibidas con adhesivo cementoso normal, C1 sin ninguna caracterstica adicional, color gris y rejuntadas con lechada de cemento blanco, L, BL-V 22,5, para junta mnima (entre 1,5 y 3 mm), coloreada con la misma tonalidad de las piezas.| +~D|RSG010 +|mt09mcr021g\\3 +\mt18bcp010bae\\1.05 +\mt08cem040a\\1 +\mt09lec010b\\0.01 +\mo022\\0.39 +\mo056\\0.19 +\%0200\\0.02 +\| +~C|RSG011|m|Solado de baldosas cermicas de gres rstico|8.93|060415|0| +~T|RSG011|Solado de baldosas cermicas de gres rstico, 2/0/-/-, de 30x30 cm, 8 /m, recibidas con mortero de cemento M-5 de 3 cm de espesor y rejuntadas con lechada de cemento blanco, L, BL-V 22,5, para junta mnima (entre 1,5 y 3 mm), coloreada con la misma tonalidad de las piezas.| +~D|RSG011 +|mt09mor010c\\0.03 +\mt18bcr010baa\\1.05 +\mt08cem040a\\1 +\mt09lec010b\\0.01 +\mo014\\0.14 +\mo035\\0.07 +\%0200\\0.02 +\| +~C|RSG020|m|Rodapi cermico de gres rstico|5.39|060415|0| +~T|RSG020|Rodapi cermico de gres rstico, de 7 cm, 3 /m, recibido con adhesivo cementoso de uso exclusivo para interiores, Ci sin ninguna caracterstica adicional, gris y rejuntado con mortero de juntas cementoso, CG1, para junta mnima (entre 1,5 y 3 mm), con la misma tonalidad de las piezas.| +~D|RSG020 +|mt09mcr021a\\0.1 +\mt18rcr010a30\\1.05 +\mt09mcr060c\\0.01 +\mo022\\0.16 +\%0200\\0.02 +\| +~C|RSG020b|m|Rodapi cermico de gres porcelnico|5.42|140415|0| +~T|RSG020b|Rodapi cermico de gres porcelnico, pulido de 7 cm, 3 /m, recibido con adhesivo cementoso de uso exclusivo para interiores, Ci sin ninguna caracterstica adicional, gris y rejuntado con mortero de juntas cementoso, CG1, para junta mnima (entre 1,5 y 3 mm), con la misma tonalidad de las piezas.| +~D|RSG020b +|mt09mcr021a\\0.1 +\mt18rcp010a30\\1.05 +\mt09mcr060c\\0.01 +\mo022\\0.16 +\%0200\\0.02 +\| +~C|RSM021|m|Pavimento de tarima flotante|74.4|010415|0| +~T|RSM021|Pavimento de tarima flotante de tablas de madera maciza de roble, de 22 mm, ensambladas mediante clips y colocadas a rompejuntas sobre estructura metalica| +~D|RSM021 +|mt17poa011a\\1.1 +\mt16aaa030\\0.44 +\mt18mta020k\\1.02 +\mt18mva021\\1 +\mt18mva100\\13 +\mo024\\0.38 +\mo058\\0.38 +\%0200\\0.02 +\| +~C|RSM022|m|Pavimento de tarima para exterior con rastreles|31.32|060415|0| +~T|RSM022|Pavimento de tarima para exterior, con sistema de fijacin oculta, formado por tablas de madera maciza, de teca o similar, de 28x145x800/2800 mm, sin tratar, para lijado y aceitado en obra; resistencia al deslizamiento clase 3, segn CTE DB SU, fijadas sobre rastreles de madera de pino Suecia, de 50x38 mm, tratado en autoclave, con clasificacin de uso clase 4, segn UNE-EN 335-1, separados entre ellos 40 cm y fijados al soporte mediante pelladas de mortero de cemento.| +~D|RSM022 +|mt18mva015b\\3 +\mt18mta030bga\\1.05 +\mt18mva021\\1 +\mt18mta050\\22 +\mo016\\0.26 +\mo037\\0.26 +\%0200\\0.02 +\| +~C|RSM040|m|Pavimento de parquet flotante de roble|12.84|060415|0| +~T|RSM040|Pavimento de parquet flotante de lamas de 2180x200x14 mm, con una capa superior de madera de roble, ensambladas con adhesivo, colocadas sobre lmina de espuma de polietileno de alta densidad de 3 mm de espesor.| +~D|RSM040 +|mt17poa011aa\\1.1 +\mt16aaa030\\0.44 +\mt18mpg011aaa\\1.05 +\mt18mva070\\0.05 +\mo016\\0.18 +\mo037\\0.1 +\%0200\\0.02 +\| +~C|RSM050|m|Rodapi de MDF acabado roble 6x1,2 cm.|3.19|010415|0| +~T|RSM050|Rodapi de MDF acabado roble 6x1,2 cm.| +~D|RSM050 +|mt18rma030j\\1.05 +\mo024\\0.11 +\%0200\\0.02 +\| +~C|RSP011|m|Solado de baldosas de granito|26.91|060415|0| +~T|RSP011|Solado de baldosas de granito Silvestre, para interiores, 60x40x2 cm, acabado pulido, recibidas con mortero de cemento, con arena de miga M-5 y rejuntadas con mortero de juntas cementoso, CG1, para junta mnima (entre 1,5 y 3 mm), con la misma tonalidad de las piezas.| +~D|RSP011 +|mt09mor011b\\0.03 +\mt18bgn010tba\\1.05 +\mt09mcr060c\\0.15 +\mo014\\0.17 +\mo035\\0.17 +\%0200\\0.02 +\| +~C|RSP020|m|Rodapi de granito Silvestre GT, 7x1 cm|6.93|060415|0| +~T|RSP020|Rodapi de granito Silvestre GT, 7x1 cm, pulido, recibido con adhesivo cementoso mejorado, C2 y rejuntado con mortero de juntas cementoso, CG1, para junta mnima (entre 1,5 y 3 mm), con la misma tonalidad de las piezas.| +~D|RSP020 +|mt18rgn010ua\\1.05 +\mt09mcr210\\0.56 +\mt09mcr060c\\0.08 +\mo022\\0.26 +\%0200\\0.02 +\| +~C|RSY050|m|Lijado y aceitado de tarima|6.54|010415|0| +~T|RSY050|Reparacin de pavimento de madera maciza mediante lijado mecnico, eliminando la capa superficial y posterior formacin de capa de proteccin incolora y brillante compuesta por una mano de fondo con barniz inodoro al agua, a base de resinas acrlicas (rendimiento: 0,2 l/m) y dos manos de acabado con barniz al agua a poro cerrado o aceite de linaza, (rendimiento: 0,091 l/m cada mano).| +~D|RSY050 +|mt27baj020aaa\\0.2 +\mt27baj010aaa\\0.18 +\mq08war160\\0.21 +\mo024\\0.14 +\mo045\\0.14 +\%0200\\0.02 +\| +~C|RT#||Falsos techos|339.7|260315|0| +~D|RT# +|RTC015\\36.1 +\| +~C|RTC015|m|Falso techo continuo liso|9.23|260315|0| +~T|RTC015|Falso techo continuo liso suspendido con estructura metlica (12,5+27+27), formado por una placa de yeso laminado A / UNE-EN 520 - 1200 / longitud / 13 / borde afinado.| +~D|RTC015 +|mt12psg160a\\0.4 +\mt12psg220\\2 +\mt12psg210a\\1.2 +\mt12psg210b\\1.2 +\mt12psg210c\\1.2 +\mt12psg190\\1.2 +\mt12psg050c\\3.2 +\mt12psg215b\\0.6 +\mt12psg215a\\2.3 +\mt12psg010aa\\1 +\mt12psg081ab\\17 +\mt12psg041\\0.4 +\mt12psg030a\\0.3 +\mt12psg030a\\0.4 +\mt12psg040a\\0.45 +\mo006\\0.13 +\mo048\\0.05 +\%0200\\0.02 +\| +~C|S#||Sealizacin y equipamiento|970.69|250315|0| +~D|S# +|SM#\\1 +\SC#\\1 +\| +~C|SC#||Cocinas/galeras|0|150415|0| +~D|SC# +|Pa7\\1 +\| +~C|SM#||Baos|970.69|250315|0| +~D|SM# +|SMS010\\1 +\SMS010b\\1 +\SMS010d\\1 +\| +~C|SMS010|Ud|Conjunto de aparatos sanitarios y griferias para aseo|216.4|250315|0| +~T|SMS010|Inodoro de porcelana sanitaria, con tanque bajo, serie bsica, color blanco; lavabo de porcelana sanitaria, con pedestal, serie bsica, color blanco, de 650x510 mm con grifera monomando, acabado cromado, con aireador; plato de ducha acrlico gama bsica, color, de 150x70 cm, con juego de desage provisto de grifera monomando serie bsica, acabado cromado.| +~D|SMS010 +|mt30ips010aa\\1 +\mt30lps010aaa\\1 +\mt30pas010bab\\1 +\mt31gmg010aaa\\1 +\mt31gmg050aa\\1 +\mt36www005aa\\1 +\mt30lla010\\2 +\mt30lla020\\1 +\mt38tew010a\\1 +\mo004\\1.05 +\mo055\\0.7 +\%0200\\0.02 +\| +~C|SMS010b|Ud|Conjunto de aparatos sanitarios para bao1|354.09|250315|0| +~T|SMS010b|Inodoro de porcelana sanitaria, con tanque bajo, serie bsica, color blanco; lavabo de porcelana sanitaria, de semiempotrar, serie bsica, color blanco, de 650x515 mm con grifera monomando, acabado cromado, con aireador; bid de porcelana sanitaria serie bsica, color blanco, sin tapa y grifera monomando, acabado cromado, con aireador; plato de ducha acrlico gama bsica, color, de 115x70 cm, con juego de desage provisto de grifera monomando serie bsica, acabado cromado.| +~D|SMS010b +|mt30ips010aa\\1 +\mt30lps030aaa\\2 +\mt30bps010aaa\\1 +\mt30pas010bab\\1 +\mt31gmg010aaa\\2 +\mt31gmg020aaa\\1 +\mt31gmg050aa\\1 +\mt36www005aa\\3 +\mt30lla010\\6 +\mt30lla020\\1 +\mt38tew010a\\1 +\mo004\\1.65 +\mo055\\1.1 +\%0200\\0.02 +\| +~C|SMS010c|Ud|Conjunto de aparatos sanitarios para bao2|884.77|310315|0| +~T|SMS010c|Inodoro de porcelana sanitaria, con tanque bajo, serie bsica, color blanco; lavabo de porcelana sanitaria, de semiempotrar, serie bsica, color blanco, de 650x515 mm con grifera monomando, acabado cromado, con aireador; bid de porcelana sanitaria serie bsica, color blanco, sin tapa y grifera monomando, acabado cromado, con aireador; baera acrlica gama bsica, color blanco, de 140x70 cm, con faldn frontal, equipada con grifera monomando serie bsica, acabado cromado.| +~C|SMS010d|Ud|Conjunto de aparatos sanitarios para bao2|381.17|060415|0| +~T|SMS010d|Inodoro de porcelana sanitaria, con tanque bajo, serie bsica, color blanco; lavabo de porcelana sanitaria, con pedestal, serie bsica, color blanco, de 650x510 mm con grifera monomando, acabado cromado, con aireador; bid de porcelana sanitaria serie bsica, color blanco, sin tapa y grifera monomando, acabado cromado, con aireador; baera acrlica gama bsica color blanco, de 140x70 cm, equipada con grifera monomando serie bsica, acabado cromado; plato de ducha acrlico gama bsica color, de 70x70 cm, con juego de desage provisto de grifera monomando serie bsica, acabado cromado.| +~D|SMS010d +|mt30ips010a\\1 +\mt30lps010aa\\1 +\mt30bps010a\\1 +\mt30bas010a\\1 +\mt30pas010d\\1 +\mt31gmg010a\\1 +\mt31gmg020a\\1 +\mt31gmg040a\\1 +\mt31gmg050a\\1 +\mt36www005a\\2 +\mt30lla010\\4 +\mt30lla020\\1 +\mt38tew010a\\1 +\mt30dba020\\1 +\mo007\\1.73 +\mo099\\1.15 +\%0200\\0.02 +\| +~C|UVT010|m|Cerramiento de parcela formado por malla de simple torsin|13.89|250315|0| +~T|UVT010|Cerramiento de parcela formado por malla de simple torsin, de 40 mm de paso de malla y 2/3 mm de dimetro, acabado galvanizado y plastificado en color verde RAL 6015 y montantes de postes de acero pintado, de 48 mm de dimetro y 1,5 m de altura.| +~D|UVT010 +|mt52vst030d\\0.22 +\mt52vst030l\\0.06 +\mt52vst030t\\0.04 +\mt52vst030B\\0.2 +\mt52vst010nx\\1.8 +\mt10hmf010Mm\\0.02 +\mo105\\0.1 +\mo010\\0.09 +\mo075\\0.09 +\%0300\\0.03 +\| +~C|X#||Control de calidad y ensayos|402.2|060415|0| +~D|X# +|XE#\\1 +\XM#\\1 +\| +~C|XE#||Estructuras de hormign|295.53|060415|0| +~D|XE# +|XEB010\\3 +\XEB020\\1 +\XEM010\\1 +\XEM020\\1 +\XEH010\\1 +\| +~C|XEB010|Ud|Ensayo sobre una muestra de barras de acero corrugado|41.42|060415|0| +~T|XEB010|Ensayo sobre una muestra de barras de acero corrugado de un mismo lote, con determinacin de: seccin media equivalente, caractersticas geomtricas del corrugado, doblado/desdoblado.| +~D|XEB010 +|mt49arb040\\1 +\mt49arb010\\1 +\mt49arb020\\1 +\%0200\\0.02 +\| +~C|XEB020|Ud|Ensayo sobre una muestra de barras de acero corrugado|26.39|060415|0| +~T|XEB020|Ensayo sobre una muestra de barras de acero corrugado de cada dimetro, con determinacin de caractersticas mecnicas.| +~D|XEB020 +|mt49arb050\\1 +\%0200\\0.02 +\| +~C|XEH010|Ud|Ensayode: consistencia del hormign fresco|45.02|060415|0| +~T|XEH010|Ensayo sobre una muestra de hormign con determinacin de: consistencia del hormign fresco mediante el mtodo de asentamiento del cono de Abrams y resistencia caracterstica a compresin del hormign endurecido mediante control estadstico con fabricacin de seis probetas, curado, refrentado y rotura a compresin.| +~D|XEH010 +|mt49hob020ca\\1 +\%0200\\0.02 +\| +~C|XEM010|Ud|Ensayo sobre una muestra de mallas electrosoldadas|67.65|060415|0| +~T|XEM010|Ensayo sobre una muestra de mallas electrosoldadas con determinacin de: seccin media equivalente, caractersticas geomtricas del corrugado, doblado/desdoblado, carga de despegue.| +~D|XEM010 +|mt49arm040\\1 +\mt49arm010\\1 +\mt49arm020\\1 +\mt49arm050\\1 +\%0200\\0.02 +\| +~C|XEM020|Ud|Ensayo sobre una muestra de una malla electrosoldada|26.41|060415|0| +~T|XEM020|Ensayo sobre una muestra de una malla electrosoldada de cada dimetro, con determinacin de caractersticas mecnicas.| +~D|XEM020 +|mt49arm060\\1 +\%0200\\0.02 +\| +~C|XM#||Estructuras metlicas|106.67|060415|0| +~D|XM# +|XMP010\\1 +\| +~C|XMP010|Ud|Ensayo destructivo sobre una muestra de perfil laminado|104.58|060415|0| +~T|XMP010|Ensayo destructivo sobre una muestra de perfil laminado, con determinacin de: lmite elstico aparente, resistencia a traccin, mdulo de elasticidad, alargamiento y estriccin; doblado a 180.| +~D|XMP010 +|mt49des010\\1 +\mt49pma020\\1 +\mt49pma050\\1 +\mt49pma080\\1 +\mt49pma030\\1 +\%0200\\0.02 +\| +~C|Y#||Seguridad y salud|1097.53|250315|0| +~D|Y# +|YC#\\1 +\YF#\\1 +\YI#\\1 +\YM#\\1 +\YP#\\1 +\YS#\\1 +\| +~C|YC#||Sistemas de proteccin colectiva|459.02|250315|0| +~D|YC# +|YCE030\\0.4 +\YCF050\\67.68 +\YCI010\\1 +\YCM070\\3 +\YCS010\\2 +\YCS020\\1 +\YCU010\\1 +\| +~C|YCB040|Ud|Pasarela de acero, de 1,50 m de longitud para anchura mxima de|0|060415|0| +~T|YCB040|Pasarela de acero, de 1,50 m de longitud para anchura mxima de zanja de 0,9 m, anchura til de 0,87 m, barandillas laterales de 1 m de altura, amortizable en 20 usos, para proteccin de paso peatonal sobre zanjas abiertas.| +~C|YCE030|m|Sistema provisional de proteccin de hueco|4.12|250315|0| +~T|YCE030|Sistema provisional de proteccin de hueco de escalera en construccin, de 1 m de altura, formado por barandilla principal e intermedia de tubo de acero de 25 mm de dimetro y rodapi de tabloncillo de madera de 15x5,2 cm, todo ello sujeto a guardacuerpos telescpicos de acero, fijados por apriete. Amortizables los guardacuerpos en 8 usos, las barandillas en 10 usos y los rodapis en 4 usos.| +~D|YCE030 +|mt50spb030aab\\0.09 +\mt50spb050a\\0.08 +\mt50spa050bb\\0.01 +\mo011\\0.07 +\mo060\\0.07 +\%0200\\0.02 +\| +~C|YCF010|m|Sistema provisional de proteccin de borde de forjado, clase A,|0|060415|0| +~T|YCF010|Sistema provisional de proteccin de borde de forjado, clase A, de 1 m de altura, formado por barandilla principal e intermedia de tubo de acero de 25 mm de dimetro y rodapi metlico, todo ello sujeto a guardacuerpos fijos de acero, fijados al forjado con base plstica embebida en el hormign. Amortizables los guardacuerpos en 8 usos, las barandillas en 10 usos y los rodapis en 10 usos.| +~C|YCF050|m|Sistema V de red de seguridad|3.96|250315|0| +~T|YCF050|Sistema V de red de seguridad UNE-EN 1263-1 V A2 M100 D M, primera puesta, colocada verticalmente con pescantes tipo horca fijos de acero, anclados al forjado mediante horquillas de acero corrugado B 500 S. Amortizable la red en 10 puestas y los pescantes en 15 usos.| +~D|YCF050 +|mt50jpr050aaa\\0.01 +\mt50jpr060aaa\\0.02 +\mt07aco010c\\0.08 +\mt50jpr040ac\\2.14 +\mt50jpr080aa\\0.22 +\mt50jpr070ab\\0.11 +\mo011\\0.06 +\mo060\\0.06 +\%0200\\0.02 +\| +~C|YCI010|m|Repercusin de sistema anticadas|0.37|250315|0| +~T|YCI010|Repercusin de sistema anticadas para colocacin de superficie de encofrado por m de forjado.| +~D|YCI010 +|mt50sph060b\\1 +\mt50sph061b\\1 +\mt50sph062b\\1 +\mo011\\0.01 +\mo060\\0.01 +\%0200\\0.02 +\| +~C|YCK020|Ud|Proteccin de hueco de ventana de entre 95 y 165 cm de anchura e|0|060415|0| +~T|YCK020|Proteccin de hueco de ventana de entre 95 y 165 cm de anchura en cerramiento exterior, mediante dos tubos metlicos extensibles, amortizables en 20 usos.| +~C|YCM020|m|Marquesina de proteccin del acceso al edificio ante la posible|0|060415|0| +~T|YCM020|Marquesina de proteccin del acceso al edificio ante la posible cada de objetos formada por estructura metlica tubular de 1,50 m de ancho y 3,00 m de altura y plataforma de tablero de madera de 22 mm de espesor, con rodapi. Amortizable la estructura en 8 usos y la plataforma en 4 usos.| +~C|YCM070|m|Plataforma de trabajo en voladizo de madera|15.37|250315|0| +~T|YCM070|Plataforma de trabajo en voladizo de madera, de 0,60 m de anchura til, barandilla lateral de 1,00 m de altura, colocada sobre una estructura portante formada por puntales metlicos arriostrados entre s. Amortizable la plataforma en 3 usos y los puntales en 15 usos.| +~D|YCM070 +|mt50spa050cc\\0.03 +\mt50spa050bb\\0.01 +\mt50spa050aa\\0.01 +\mt50spa101\\0.05 +\mt50spa080ba\\0.29 +\mt50spa080bb\\0.06 +\mt50spa080bc\\0.06 +\mo011\\0.23 +\mo046\\0.23 +\%0200\\0.02 +\| +~C|YCN010|m|Pasarela peatonal en voladizo, de 0,60 m de anchura til, de pro|0|060415|0| +~T|YCN010|Pasarela peatonal en voladizo, de 0,60 m de anchura til, de proteccin perimetral de cubierta, formada por plataforma de chapa perforada de acero galvanizado anclada sobre soportes retrctiles metlicos empotrados en el frente de forjado de la planta de cubierta, barandilla principal e intermedia de tubo de acero de 25 mm de dimetro y rodapi metlico, todo ello sujeto a guardacuerpos telescpicos de acero. Amortizable la plataforma en 8 usos, los guardacuerpos en 8 usos, las barandillas en 10 usos y los rodapis en 10 usos.| +~C|YCR020|m|Vallado provisional de solar, de 2 m de altura, compuesto por pa|0|060415|0| +~T|YCR020|Vallado provisional de solar, de 2 m de altura, compuesto por paneles opacos de chapa perfilada nervada de acero S320 GD galvanizado de 0,6 mm espesor y 30 mm altura de cresta y perfiles huecos de seccin cuadrada de acero S275JR, de 60x60x1,5 mm, de 2,8 m de longitud, anclados al terreno mediante dados de hormign HM-20/P/20/I, cada 2,0 m. Amortizables los paneles en 10 usos y los perfiles en 5 usos.| +~C|YCS010|Ud|Lmpara porttil de mano|2.07|250315|0| +~T|YCS010|Lmpara porttil de mano, amortizable en 3 usos.| +~D|YCS010 +|mt50spe010\\0.33 +\mo052\\0.04 +\%0200\\0.02 +\| +~C|YCS020|Ud|Cuadro general de obra|122.98|250315|0| +~T|YCS020|Cuadro general de obra, potencia mxima 10 kW, amortizable en 4 usos.| +~D|YCS020 +|mt50spe020b\\0.25 +\mo001\\0.45 +\mo052\\0.45 +\%0200\\0.02 +\| +~C|YCU010|Ud|Extintor porttil de polvo qumico ABC|6.7|250315|0| +~T|YCU010|Extintor porttil de polvo qumico ABC polivalente antibrasa, con presin incorporada, de eficacia 21A-113B-C, con 6 kg de agente extintor, amortizable en 3 usos.| +~D|YCU010 +|mt41ixi010a\\0.33 +\mo060\\0.04 +\%0200\\0.02 +\| +~C|YCV010|m|Bajante para vertido de escombros, compuesta por 3 tubos y 1 emb|0|060415|0| +~T|YCV010|Bajante para vertido de escombros, compuesta por 3 tubos y 1 embocadura de polietileno, de 49 cm de dimetro superior y 40 cm de dimetro inferior, por cada planta de hasta 3 m de altura libre, amortizable en 5 usos.| +~C|YF#||Formacin|33.65|060415|0| +~D|YF# +|YFF020\\1 +\| +~C|YFF020|Ud|Hora de charla para formacin de Seguridad y Salud en el Trabajo|32.99|060415|0| +~T|YFF020|Hora de charla para formacin de Seguridad y Salud en el Trabajo.| +~D|YFF020 +|mt50mas020\\1 +\%0200\\0.02 +\| +~C|YI#||Equipos de proteccin individual|186.65|060415|0| +~D|YI# +|YIC010\\8 +\YID020b\\1 +\YIJ010\\1 +\YIJ010c\\1 +\YIM010\\12 +\YIM010b\\4 +\YIM040\\1 +\YIO010\\5 +\YIO020\\2 +\YIP010\\2 +\YIP010b\\6 +\YIP020\\1 +\YIP030\\6 +\YIU020\\6 +\YIU030\\4 +\YIU040\\2 +\YIU050\\4 +\YIV010\\1 +\YIV020\\1 +\| +~C|YIC010|Ud|Casco de proteccin, amortizable en 10 usos.|0.09|060415|0| +~T|YIC010|Casco de proteccin, amortizable en 10 usos.| +~D|YIC010 +|mt50epc020bfj\\0.1 +\%0200\\0.02 +\| +~C|YIC010b|Ud|Casco aislante elctrico, amortizable en 10 usos.|0|060415|0| +~T|YIC010b|Casco aislante elctrico, amortizable en 10 usos.| +~C|YID010|Ud|Sistema anticadas compuesto por un conector bsico (clase B), a|0|060415|0| +~T|YID010|Sistema anticadas compuesto por un conector bsico (clase B), amortizable en 3 usos; un dispositivo anticadas deslizante sobre lnea de anclaje flexible, amortizable en 3 usos; una cuerda de fibra de longitud fija como elemento de amarre, amortizable en 4 usos; un absorbedor de energa, amortizable en 4 usos y un arns anticadas con un punto de amarre, amortizable en 4 usos.| +~C|YID020|Ud|Sistema de sujecin y retencin compuesto por un conector bsico|0|060415|0| +~T|YID020|Sistema de sujecin y retencin compuesto por un conector bsico (clase B), amortizable en 3 usos; una cuerda de fibra de longitud fija como elemento de amarre, amortizable en 4 usos; un absorbedor de energa, amortizable en 4 usos y un arns de asiento, amortizable en 4 usos.| +~C|YID020b|Ud|Sistema de sujecin y retencin|23.4|060415|0| +~T|YID020b|Sistema de sujecin y retencin compuesto por un conector bsico (clase B), amortizable en 3 usos; una cuerda de fibra de longitud fija como elemento de amarre, amortizable en 4 usos; un absorbedor de energa, amortizable en 4 usos y un cinturn de sujecin y retencin, amortizable en 4 usos.| +~D|YID020b +|mt50epd010ac\\0.33 +\mt50epd012aad\\0.25 +\mt50epd013d\\0.25 +\mt50epd015bd\\0.25 +\%0200\\0.02 +\| +~C|YIJ010|Ud|Gafas de proteccin con montura integral|1.47|060415|0| +~T|YIJ010|Gafas de proteccin con montura integral, resistentes a polvo grueso, amortizable en 5 usos.| +~D|YIJ010 +|mt50epj010cbc\\0.2 +\%0200\\0.02 +\| +~C|YIJ010b|Ud|Gafas de proteccin con montura integral, resistentes a impactos|0|060415|0| +~T|YIJ010b|Gafas de proteccin con montura integral, resistentes a impactos de partculas a gran velocidad y media energa, a temperaturas extremas, amortizable en 5 usos.| +~C|YIJ010c|Ud|Pantalla de proteccin facial|1.68|060415|0| +~T|YIJ010c|Pantalla de proteccin facial, resistente a impactos de partculas a gran velocidad y media energa, a temperaturas extremas, amortizable en 5 usos.| +~D|YIJ010c +|mt50epj010mcc\\0.2 +\%0200\\0.02 +\| +~C|YIM010|Ud|Par de guantes contra riesgos mecnicos|1.4|060415|0| +~T|YIM010|Par de guantes contra riesgos mecnicos amortizable en 4 usos.| +~D|YIM010 +|mt50epm010acd\\0.25 +\%0200\\0.02 +\| +~C|YIM010b|Ud|Par de guantes para trabajos elctricos de baja tensin|4.34|060415|0| +~T|YIM010b|Par de guantes para trabajos elctricos de baja tensin, amortizable en 4 usos.| +~D|YIM010b +|mt50epm010ead\\0.25 +\%0200\\0.02 +\| +~C|YIM010c|Ud|Par de guantes resistentes al fuego amortizable en 4 usos.|0|060415|0| +~T|YIM010c|Par de guantes resistentes al fuego amortizable en 4 usos.| +~C|YIM020|Ud|Par de manoplas resistentes al fuego amortizable en 4 usos.|0|060415|0| +~T|YIM020|Par de manoplas resistentes al fuego amortizable en 4 usos.| +~C|YIM040|Ud|Protector de manos para puntero, amortizable en 4 usos.|0.35|060415|0| +~T|YIM040|Protector de manos para puntero, amortizable en 4 usos.| +~D|YIM040 +|mt50epm070d\\0.25 +\%0200\\0.02 +\| +~C|YIO010|Ud|Juego de orejeras, estndar, con atenuacin acstica|0.41|060415|0| +~T|YIO010|Juego de orejeras, estndar, con atenuacin acstica de 15 dB, amortizable en 10 usos.| +~D|YIO010 +|mt50epo010aaj\\0.1 +\%0200\\0.02 +\| +~C|YIO020|Ud|Juego de tapones desechables|0.01|060415|0| +~T|YIO020|Juego de tapones desechables, moldeables, con atenuacin acstica de 31 dB, amortizable en 1 uso.| +~D|YIO020 +|mt50epo020aaa\\1 +\%0200\\0.02 +\| +~C|YIP010|Ud|Par de botas de media caa de trabajo|7.12|060415|0| +~T|YIP010|Par de botas de media caa de trabajo, con resistencia al deslizamiento, zona del tacn cerrada, resistente a la penetracin y absorcin de agua, con cdigo de designacin OB, amortizable en 2 usos.| +~D|YIP010 +|mt50epp010cab\\0.5 +\%0200\\0.02 +\| +~C|YIP010b|Ud|Par de botas bajas de trabajo|7.12|060415|0| +~T|YIP010b|Par de botas bajas de trabajo, con resistencia al deslizamiento, zona del tacn cerrada, resistente a la perforacin, con cdigo de designacin OB, amortizable en 2 usos.| +~D|YIP010b +|mt50epp010cab\\0.5 +\%0200\\0.02 +\| +~C|YIP010c|Ud|Par de zapatos de trabajo, con resistencia al deslizamiento, zon|0|060415|0| +~T|YIP010c|Par de zapatos de trabajo, con resistencia al deslizamiento, zona del tacn cerrada, aislante, con cdigo de designacin OB, amortizable en 2 usos.| +~C|YIP020|Ud|Par de polainas para extincin de incendios, amortizable en 3 us|9.47|060415|0| +~T|YIP020|Par de polainas para extincin de incendios, amortizable en 3 usos.| +~D|YIP020 +|mt50epp020bc\\0.33 +\%0200\\0.02 +\| +~C|YIP030|Ud|Par de plantillas resistentes a la perforacin, amortizable en 1|2.71|060415|0| +~T|YIP030|Par de plantillas resistentes a la perforacin, amortizable en 1 uso.| +~D|YIP030 +|mt50epp030a\\1 +\%0200\\0.02 +\| +~C|YIU010|Ud|Mono de proteccin para trabajos expuestos al calor o las llamas|0|060415|0| +~T|YIU010|Mono de proteccin para trabajos expuestos al calor o las llamas, sometidos a una temperatura ambiente hasta 100C, amortizable en 3 usos.| +~C|YIU020|Ud|Mono de proteccin para trabajos expuestos a la lluvia, amortiza|2.43|060415|0| +~T|YIU020|Mono de proteccin para trabajos expuestos a la lluvia, amortizable en 5 usos.| +~D|YIU020 +|mt50epu025aae\\0.2 +\%0200\\0.02 +\| +~C|YIU030|Ud|Chaleco de alta visibilidad, de material reflectante, amortizabl|1.91|060415|0| +~T|YIU030|Chaleco de alta visibilidad, de material reflectante, amortizable en 5 usos.| +~D|YIU030 +|mt50epu030bdc\\0.2 +\%0200\\0.02 +\| +~C|YIU040|Ud|Bolsa portaherramientas, amortizable en 10 usos.|1.01|060415|0| +~T|YIU040|Bolsa portaherramientas, amortizable en 10 usos.| +~D|YIU040 +|mt50epu040j\\0.1 +\%0200\\0.02 +\| +~C|YIU050|Ud|Faja de proteccin lumbar, amortizable en 4 usos.|1.98|060415|0| +~T|YIU050|Faja de proteccin lumbar, amortizable en 4 usos.| +~D|YIU050 +|mt50epu050d\\0.25 +\%0200\\0.02 +\| +~C|YIV010|Ud|Equipo de proteccin respiratoria|3.61|060415|0| +~T|YIV010|Equipo de proteccin respiratoria (EPR), filtrante no asistido, compuesto por una mascarilla, de media mscara, amortizable en 3 usos y un filtro contra partculas, de eficacia media (P2), amortizable en 3 usos.| +~D|YIV010 +|mt50epv010bad\\0.33 +\mt50epv011abd\\0.33 +\%0200\\0.02 +\| +~C|YIV020|Ud|Mascarilla autofiltrante contra partculas, FFP1, amortizable en|0.68|060415|0| +~T|YIV020|Mascarilla autofiltrante contra partculas, FFP1, amortizable en 1 uso.| +~D|YIV020 +|mt50epv020aba\\1 +\%0200\\0.02 +\| +~C|YM#||Medicina preventiva y primeros auxilios|186.8|250315|0| +~D|YM# +|YMM010\\1 +\YMM011\\1 +\YMM020\\1 +\YMR010\\2 +\| +~C|YMM010|Ud|Botiqun de urgencia en caseta de obra.|41.38|250315|0| +~T|YMM010|Botiqun de urgencia en caseta de obra.| +~D|YMM010 +|mt50eca010\\1 +\mo060\\0.08 +\%0200\\0.02 +\| +~C|YMM011|Ud|Reposicin de material de botiqun de urgencia en caseta de obra|41.24|060415|0| +~T|YMM011|Reposicin de material de botiqun de urgencia en caseta de obra.| +~D|YMM011 +|mt50eca011\\1 +\%0200\\0.02 +\| +~C|YMM020|Ud|Camilla porttil para evacuaciones.|14.89|060415|0| +~T|YMM020|Camilla porttil para evacuaciones.| +~D|YMM020 +|mt50eca020\\0.25 +\%0200\\0.02 +\| +~C|YMR010|Ud|Reconocimiento mdico anual al trabajador.|42.81|060415|0| +~T|YMR010|Reconocimiento mdico anual al trabajador.| +~D|YMR010 +|mt50man010\\1 +\%0200\\0.02 +\| +~C|YP#||Instalaciones provisionales de higiene y bienestar|151.48|060415|0| +~D|YP# +|YPC210\\2 +\| +~C|YPC210|m|Adaptacin de local existente como caseta provisional para aseos|74.25|060415|0| +~T|YPC210|Adaptacin de local existente como caseta provisional para aseos en obra.| +~D|YPC210 +|mt50cat010a\\1 +\%0200\\0.02 +\| +~C|YS#||Sealizacin provisional de obras|79.93|250315|0| +~D|YS# +|YSB050\\75.89 +\YSV010\\1 +\YSN010\\45.54 +\YSS020\\1 +\YSS030\\1 +\| +~C|YSB050|m|Cinta para balizamiento|0.46|250315|0| +~T|YSB050|Cinta para balizamiento, de material plstico, de 8 cm de anchura, impresa por ambas caras en franjas de color amarillo y negro.| +~D|YSB050 +|mt50bal010aaa\\1.1 +\mo060\\0.03 +\%0200\\0.02 +\| +~C|YSN010|Ud|Bandern para sealizacin|0.73|250315|0| +~T|YSN010|Bandern para sealizacin, de material textil, de 40x50 cm, de color rojo y vstago de madera de 1 m, amortizable en 5 usos.| +~D|YSN010 +|mt50bal020\\0.2 +\mo060\\0.01 +\%0200\\0.02 +\| +~C|YSS020|Ud|Cartel general indicativo de riesgos|2.84|250315|0| +~T|YSS020|Cartel general indicativo de riesgos, de PVC serigrafiado, de 990x670 mm, amortizable en 3 usos, fijado con bridas.| +~D|YSS020 +|mt50les020aa\\0.33 +\mt50spr046\\6 +\mo060\\0.09 +\%0200\\0.02 +\| +~C|YSS030|Ud|Seal de advertencia|1.46|250315|0| +~T|YSS030|Seal de advertencia, de PVC serigrafiado, de 297x210 mm, con pictograma negro de forma triangular sobre fondo amarillo, amortizable en 3 usos, fijada con bridas.| +~D|YSS030 +|mt50les030aaf\\0.33 +\mt50spr046\\4 +\mo060\\0.07 +\%0200\\0.02 +\| +~C|YSV010|Ud|Seal provisional de obra de|6.05|250315|0| +~T|YSV010|Seal provisional de obra usos, el poste en 5 usos y el pie en 5 usos.| +~D|YSV010 +|mt50les010aba\\0.2 +\mt50les040a\\0.2 +\mt50les060\\0.2 +\mo060\\0.09 +\%0200\\0.02 +\| +~C|mo000|h|Oficial 1 instalador de telecomunicaciones.|15.78|160415|1| +~C|mo001|h|Oficial 1 electricista.|15.78|250315|1| +~C|mo002|h|Oficial 1 calefactor.|15.78|310315|1| +~C|mo003|h|Oficial 1 calefactor.|16.87|130415|1| +~C|mo004|h|Oficial 1 fontanero.|15.78|250315|1| +~C|mo006|h|Oficial 1 montador.|15.78|260315|1| +~C|mo007|h|Oficial 1 fontanero.|16.87|070415|1| +~C|mo008|h|Oficial 1 carpintero.|15.53|250315|1| +~C|mo009|h|Oficial 1 cerrajero.|15.52|250315|1| +~C|mo010|h|Oficial 1 soldador.|15.52|250315|1| +~C|mo011|h|Oficial 1 construccin.|15.28|250315|1| +~C|mo012|h|Oficial 1 montador de estructura metlica.|15.28|250315|1| +~C|mo014|h|Oficial 1 solador.|15.28|060415|1| +~C|mo015|h|Oficial 1 alicatador.|15.28|060415|1| +~C|mo016|h|Oficial 1 instalador de pavimentos de madera.|15.28|060415|1| +~C|mo018|h|Oficial 1 aplicador de lminas impermeabilizantes.|15.28|060415|1| +~C|mo019|h|Oficial 1 yesero.|15.28|060415|1| +~C|mo020|h|Oficial 1 construccin en trabajos de albailera.|16.33|150415|1| +~C|mo022|h|Oficial 1 solador.|16.33|130415|1| +~C|mo024|h|Oficial 1 pintor.|15.28|010415|1| +~C|mo028|h|Oficial 1 cristalero.|15.17|300315|1| +~C|mo029|h|Oficial 2 construccin.|15.05|250315|1| +~C|mo030|h|Ayudante instalador de telecomunicaciones.|14.62|160415|1| +~C|mo031|h|Ayudante carpintero.|14.76|250315|1| +~C|mo032|h|Ayudante cerrajero.|14.7|250315|1| +~C|mo033|h|Ayudante montador de estructura metlica.|14.65|250315|1| +~C|mo035|h|Ayudante solador.|14.65|060415|1| +~C|mo036|h|Ayudante alicatador.|14.65|060415|1| +~C|mo037|h|Ayudante instalador de pavimentos de madera.|14.65|060415|1| +~C|mo039|h|Ayudante aplicador de lminas impermeabilizantes.|14.65|060415|1| +~C|mo040|h|Ayudante yesero.|14.65|060415|1| +~C|mo041|h|Oficial 1 estructurista.|17.15|130415|1| +~C|mo045|h|Ayudante pintor.|14.65|010415|1| +~C|mo046|h|Ayudante construccin.|14.65|250315|1| +~C|mo048|h|Ayudante montador.|14.65|260315|1| +~C|mo049|h|Oficial 1 montador de prefabricados interiores.|16.87|070415|1| +~C|mo050|h|Oficial 1 montador de aislamientos.|16.87|070415|1| +~C|mo052|h|Ayudante electricista.|14.62|250315|1| +~C|mo053|h|Ayudante calefactor.|14.62|250315|1| +~C|mo055|h|Ayudante fontanero.|14.62|290315|1| +~C|mo056|h|Ayudante solador.|15.65|130415|1| +~C|mo057|h|Ayudante cristalero.|14.85|300315|1| +~C|mo058|h|Ayudante instalador de pavimentos de madera.|15.65|150415|1| +~C|mo059|h|Pen especializado construccin.|14.47|250315|1| +~C|mo060|h|Pen ordinario construccin.|13.97|250315|1| +~C|mo073|h|Ayudante construccin en trabajos de albailera.|15.65|150415|1| +~C|mo075|h|Ayudante montador.|15.65|070415|1| +~C|mo084|h|Ayudante estructurista.|16.43|130415|1| +~C|mo092|h|Ayudante montador de prefabricados interiores.|15.65|070415|1| +~C|mo093|h|Ayudante montador de aislamientos.|15.65|070415|1| +~C|mo095|h|Ayudante calefactor.|15.63|130415|1| +~C|mo099|h|Ayudante fontanero.|15.63|070415|1| +~C|mo105|h|Pen ordinario construccin.|15.14|130415|1| +~C|mq01pan010|h|Pala cargadora sobre neumticos 85 CV/1,2 m.|19.04|150415|2| +~C|mq01ret020a|h|Retrocargadora sobre neumticos 75 CV.|15.24|150415|2| +~C|mq02cia020|h|Camin con cuba de agua.|14.81|150415|2| +~C|mq02rod010bb|h|Bandeja vibrante de 300 kg, anchura de trabajo 70 cm, reversible|2.63|150415|2| +~C|mq02rop020|h|Pisn vibrante de 80 kg, con placa de 30x30 cm, tipo rana.|3.48|150415|2| +~C|mq04cab010c|h|Camin basculante de 12 t de carga.|16.51|150415|2| +~C|mq04dua020b|h|Dumper autocargable de 2 t de carga til, con mecanismo hidruli|3.81|150415|2| +~C|mq04res010ag|Ud|Carga y cambio de contenedor de 7 m, para recogida de residuos|113.13|160415|2| +~C|mq04res010bg|Ud|Carga y cambio de contenedor de 7 m, para recogida de residuos|113.14|160415|2| +~C|mq04res010cg|Ud|Carga y cambio de contenedor de 7 m, para recogida de mezcla si|226.25|160415|2| +~C|mq04res010dg|Ud|Carga y cambio de contenedor de 7 m, para recogida de residuos|183.81|160415|2| +~C|mq04res010eg|Ud|Carga y cambio de contenedor de 7 m, para recogida de residuos|183.82|160415|2| +~C|mq04res010fg|Ud|Carga y cambio de contenedor de 7 m, para recogida de residuos|183.81|160415|2| +~C|mq04res010gg|Ud|Carga y cambio de contenedor de 7 m, para recogida de residuos|183.81|160415|2| +~C|mq04res010hg|Ud|Carga y cambio de contenedor de 7 m, para recogida de residuos|183.81|160415|2| +~C|mq05mai030|h|Martillo neumtico.|1.68|150415|2| +~C|mq05pdm010a|h|Compresor porttil elctrico 2 m/min de caudal.|1.57|150415|2| +~C|mq05pdm010b|h|Compresor porttil elctrico 5 m/min de caudal.|2.84|150415|2| +~C|mq05pdm110|h|Compresor porttil diesel media presin 10 m/min.|2.85|150415|2| +~C|mq06vib020|h|Regla vibrante de 3 m.|1.92|150415|2| +~C|mq07gte010c|h|Gra autopropulsada de brazo telescpico con una capacidad de el|24.15|160415|2| +~C|mq08lch020c|h|Equipo de chorro de agua a presin, con adaptador para lanza de|0.77|150415|2| +~C|mq08sol010|h|Equipo de oxicorte, con acetileno como combustible y oxgeno com|3.03|150415|2| +~C|mq08war160|h|Lijadora de aplicacin en pavimentos de madera, equipada con rod|1.75|150415|2| +~C|mq09bro010|h|Desbrozadora equipada con disco de dientes de sierra, de 0,42 kW|1.64|150415|2| +~C|mq09pla010|h|Bomba manual de pistn para tratamientos fitosanitarios y herbic|9.04|150415|2| +~C|mq09sie010|h|Motosierra a gasolina, de 50 cm de espada y 3,2 CV de potencia.|1.24|150415|2| +~C|mt01ara010|m|Arena de 0 a 5 mm de dimetro.|4.93|150415|3| +~C|mt01are010a|m|Grava de cantera de piedra caliza, de 40 a 70 mm de dimetro.|5.81|150415|3| +~C|mt01var010|m|Cinta plastificada.|0.06|150415|3| +~C|mt02bhg010aad|Ud|Bloque hueco de hormign, para revestir, color gris, 40x20x20 cm|0.31|150415|3| +~C|mt02bhg012a|Ud|Plaqueta de hormign gris, 20x17x4 cm, para revestir.|0.13|150415|3| +~C|mt04lac010b|Ud|Ladrillo cermico hueco (borgoa), para revestir, 24x11,5x6 cm,|0.03|150415|3| +~C|mt04lac010c|Ud|Ladrillo cermico hueco (cubo), para revestir, 24x11,5x8 cm, seg|0.07|070415|3| +~C|mt04lac010d|Ud|Ladrillo cermico hueco (cubo doble), para revestir, 24x15x12 cm|0.18|150415|3| +~C|mt04lma010a|Ud|Ladrillo cermico macizo de elaboracin mecnica para revestir,|0.16|150415|3| +~C|mt04lvg020b|Ud|Tablero cermico hueco machihembrado, para revestir, 80x25x3,5 c|0.2|150415|3| +~C|mt07aco010c|kg|Acero en barras corrugadas, UNE-EN 10080 B 500 S, elaborado en t|0.38|150415|3| +~C|mt07aco020a|Ud|Separador de plstico rgido, homologado para cimentaciones.|0.05|150415|3| +~C|mt07aco020c|Ud|Separador de plstico rgido, homologado para vigas.|0.03|160415|3| +~C|mt07aco020e|Ud|Separador de plstico rgido, homologado para soleras.|0.02|150415|3| +~C|mt07aco020k|Ud|Separador de plstico rgido, homologado para losas mixtas.|0.02|160415|3| +~C|mt07ala010b|kg|Acero laminado UNE-EN 10025 S275JR, en perfiles laminados en cal|0.33|160415|3| +~C|mt07ame010ab|m|Malla electrosoldada ME 15x15 5-5 B 500 T 6x2,20 UNE-EN 10080.|0.74|150415|3| +~C|mt07ame010ad|m|Malla electrosoldada ME 20x20 5-5 B 500 T 6x2,20 UNE-EN 10080.|0.57|150415|3| +~C|mt07ame010bb|m|Malla electrosoldada ME 15x15 6-6 B 500 T 6x2,20 UNE-EN 10080.|1.09|150415|3| +~C|mt07ame010h|m|Malla electrosoldada ME 15x30 6-6 B 500 T 6x2,20 UNE-EN 10080.|1.55|160415|3| +~C|mt07cem010a|Ud|Conector en "L", de acero galvanizado, de 5 cm de altura, para f|0.45|160415|3| +~C|mt07cem020|Ud|Clavos de acero galvanizado, para aplicacin con pistola.|0.09|160415|3| +~C|mt07cem030|Ud|Cartucho de plvora para fijacin por disparo con clavadora.|0.04|160415|3| +~C|mt07cid010aah|m|Encofrado perdido, de polipropileno reciclado, para soleras y fo|3.86|150415|3| +~C|mt07mee015aab|m|Madera aserrada de pino silvestre (Pinus Sylvestris L.) Espaa c|116.7|160415|3| +~C|mt07mee019aab|m|Madera aserrada de pino silvestre (Pinus Sylvestris L.) Espaa c|131.38|160415|3| +~C|mt07mee040c|m|Cabio de madera de pino silvestre, de 80x120 mm|1.85|150415|3| +~C|mt07mee115aab|m|Madera laminada encolada homognea, de 33 45 mm de espesor de|294.01|160415|3| +~C|mt07pcl010cai|m|Perfil de chapa de acero galvanizado de 1,00 mm de espesor, 59 m|36.39|160415|3| +~C|mt07tdm010e|m|Tablero de partculas de madera, con tratamiento hidrfugo y bor|2.47|150415|3| +~C|mt08aaa010a|m|Agua.|0.15|150415|3| +~C|mt08adt010|kg|Aditivo hidrfugo para impermeabilizacin de morteros.|0.42|150415|3| +~C|mt08cem040a|kg|Cemento blanco BL-22,5 X, para pavimentacin, en sacos, segn UN|0.06|150415|3| +~C|mt08eva010a|m|Encofrado y desencofrado continuo con puntales, sopandas metlic|12.4|160415|3| +~C|mt08tan010be|m|Tubo de acero negro, con soldadura longitudinal por resistencia|1.95|150415|3| +~C|mt08tan330b|Ud|Material auxiliar para montaje y sujecin a la obra de las tuber|0.14|150415|3| +~C|mt09lec010b|m|Lechada de cemento blanco BL 22,5 X.|64.5|150415|3| +~C|mt09mcr021a|kg|Adhesivo cementoso de uso exclusivo para interiores, Ci, color g|0.19|150415|3| +~C|mt09mcr021baa|kg|Adhesivo cementoso normal, C1, segn UNE-EN 12004, color gris.|0.14|150415|3| +~C|mt09mcr021g|kg|Adhesivo cementoso normal, C1 segn UNE-EN 12004, color gris.|0.3|150415|3| +~C|mt09mcr060c|kg|Mortero de juntas cementoso, CG1, para junta mnima entre 1,5 y|0.29|150415|3| +~C|mt09mcr210|kg|Adhesivo cementoso mejorado, C2 TE, con deslizamiento reducido y|0.97|150415|3| +~C|mt09moe010a|m|Mortero de cemento CEM II/B-P 32,5 N, hidrfugo, tipo M-5, confe|30.29|150415|3| +~C|mt09moe010c|m|Mortero de cemento CEM II/B-P 32,5 N, hidrfugo, tipo M-15, conf|31.42|160415|3| +~C|mt09mor010c|m|Mortero de cemento CEM II/B-P 32,5 N tipo M-5, confeccionado en|47.38|150415|3| +~C|mt09mor010d|m|Mortero de cemento CEM II/B-P 32,5 N tipo M-7,5, confeccionado e|50.25|150415|3| +~C|mt09mor010e|m|Mortero de cemento CEM II/B-P 32,5 N tipo M-10, confeccionado en|54.77|150415|3| +~C|mt09mor010f|m|Mortero de cemento CEM II/B-P 32,5 N tipo M-15, confeccionado en|61.34|150415|3| +~C|mt09mor011b|m|Mortero de cemento CEM II/B-P 32,5 N tipo M-5, confeccionado en|47.41|150415|3| +~C|mt09pye010a|m|Pasta de yeso para aplicacin en capa fina C6, segn UNE-EN 1327|36.39|150415|3| +~C|mt09var030aaa|m|Malla de fibra de vidrio tejida, con impregnacin de PVC, de 10x|0.64|150415|3| +~C|mt10haf010bga|m|Hormign HA-25/B/20/IIa, fabricado en central vertido con cubilo|28.63|150415|3| +~C|mt10haf010cbb|m|Hormign HA-30/B/20/IIb+Qb, fabricado en central con cemento SR,|40.17|150415|3| +~C|mt10haf010nea|m|Hormign HA-25/B/20/IIa, fabricado en central.|62.33|150415|3| +~C|mt10hmf010Mm|m|Hormign HM-20/B/20/I, fabricado en central.|59.28|150415|3| +~C|mt10hmf010abe|m|Hormign HM-30/B/20/I+Qb, fabricado en central, con cemento SR,|38.03|150415|3| +~C|mt10hmf010agc|m|Hormign HM-20/B/20/I, fabricado en central, vertido con cubilot|27.24|150415|3| +~C|mt11arp050ac|Ud|Tapa de PVC, para arquetas de fontanera de 30x30 cm.|5.55|150415|3| +~C|mt11arp100a|Ud|Arqueta prefabricada de polipropileno, 30x30x30 cm.|6.78|150415|3| +~C|mt11ppl010a|Ud|Codo 45 de PVC liso, D=125 mm.|2.03|150415|3| +~C|mt11tpb020bb|m|Tubo de PVC liso, para saneamiento enterrado sin presin, serie|2.17|150415|3| +~C|mt11tpb021bb|Ud|Repercusin, por m de tubera, de accesorios, uniones y piezas e|0.64|150415|3| +~C|mt11tpb030ad|m|Tubo de PVC liso, para saneamiento enterrado sin presin, serie|10.98|150415|3| +~C|mt11var009|l|Lquido limpiador para pegado mediante adhesivo de tubos y acces|3.93|150415|3| +~C|mt11var010|l|Adhesivo para tubos y accesorios de PVC.|8.31|150415|3| +~C|mt11var110|Ud|Conjunto de piezas de PVC para realizar en el fondo de la arquet|2.44|150415|3| +~C|mt11var200|Ud|Material para ejecucin de junta flexible en el empalme de la ac|6.37|150415|3| +~C|mt12pck010a|m|Cinta de juntas "KNAUF" de 50 mm de anchura.|0.01|150415|3| +~C|mt12pck020b|m|Banda acstica de dilatacin "KNAUF" de 50 mm de anchura.|0.1|150415|3| +~C|mt12pfk010c|m|Montante 48/35 "KNAUF" de acero galvanizado, segn UNE-EN 14195.|0.54|150415|3| +~C|mt12pfk020c|m|Canal 48/30 "KNAUF" de acero galvanizado, segn UNE-EN 14195.|0.44|150415|3| +~C|mt12pik010b|kg|Pasta de juntas Jointfiller F-1 GLS "KNAUF", segn UNE-EN 13963.|0.53|150415|3| +~C|mt12pik015|kg|Pasta de agarre Perlfix "KNAUF", segn UNE-EN 14496.|0.24|150415|3| +~C|mt12ppk010ab|m|Placa de yeso laminado A / UNE-EN 520 - 1200 / longitud / 15 / b|2.09|150415|3| +~C|mt12ppk010db|m|Placa de yeso laminado H / UNE-EN 520 - 1200 / longitud / 15 / b|3.12|150415|3| +~C|mt12psg010a|m|Placa de yeso laminado A / UNE-EN 520 - 1200 / longitud / 12,5 /|1.81|150415|3| +~C|mt12psg010aa|m|Placa de yeso laminado A / UNE-EN 520 - 1200 / longitud / 13 / b|1.76|150415|3| +~C|mt12psg010p|m|Placa de yeso laminado H / UNE-EN 520 - 1200 / longitud / 12,5 /|2.89|150415|3| +~C|mt12psg030a|kg|Pasta para juntas, segn UNE-EN 13963.|0.49|150415|3| +~C|mt12psg035a|kg|Pasta de agarre, segn UNE-EN 14496.|0.24|150415|3| +~C|mt12psg040a|m|Cinta de juntas.|0.01|150415|3| +~C|mt12psg041|m|Banda acstica de dilatacin de 50 mm de anchura.|0.1|150415|3| +~C|mt12psg041c|m|Banda acstica de dilatacin de 70 mm de anchura.|0.17|150415|3| +~C|mt12psg050c|m|Maestra 60/27 de chapa de acero galvanizado, de ancho 60 mm, seg|0.52|150415|3| +~C|mt12psg060d|m|Montante de perfil galvanizado de ancho 70 mm, segn UNE-EN 1419|0.73|150415|3| +~C|mt12psg070d|m|Canal ral de perfil galvanizado para entramados de fijacin de|0.45|150415|3| +~C|mt12psg081ab|Ud|Tornillo autoperforante 3,5x25 mm.|0.01|150415|3| +~C|mt12psg081b|Ud|Tornillo autoperforante 3,5x25 mm.|0.01|150415|3| +~C|mt12psg081c|Ud|Tornillo autoperforante 3,5x35 mm.|0.01|150415|3| +~C|mt12psg160a|m|Perfil de acero galvanizado, en U, de 30 mm.|0.54|150415|3| +~C|mt12psg190|Ud|Varilla de cuelgue.|0.2|150415|3| +~C|mt12psg210a|Ud|Cuelgue para falsos techos suspendidos.|0.37|150415|3| +~C|mt12psg210b|Ud|Seguro para la fijacin del cuelgue, en falsos techos suspendido|0.06|150415|3| +~C|mt12psg210c|Ud|Conexin superior para fijar la varilla al cuelgue, en falsos te|0.44|150415|3| +~C|mt12psg215a|Ud|Caballete para maestra 60/27.|0.26|150415|3| +~C|mt12psg215b|Ud|Conector para maestra 60/27.|0.21|150415|3| +~C|mt12psg220|Ud|Fijacin compuesta por taco y tornillo 5x27.|0.03|150415|3| +~C|mt12ptk010ad|Ud|Tornillo autoperforante TN "KNAUF" 3,5x25.|0.01|150415|3| +~C|mt12ptk010af|Ud|Tornillo autoperforante TN "KNAUF" 3,5x35.|0.01|150415|3| +~C|mt13blm020|m|Tablero OSB de virutas orientadas, calidad hidrfuga 3 o superio|3.29|150415|3| +~C|mt13blm030|Ud|Clavo de acero para fijacin de tablero de madera a soporte de m|0.02|150415|3| +~C|mt13blw010d|m|Rastrel de madera de pino gallego tratado o pino rojo, 42x27 mm,|0.2|150415|3| +~C|mt13blw102|Ud|Clavo galvanizado para sujecin de tejas a rastrel.|0.02|150415|3| +~C|mt13blw131|Ud|Tornillo para sujecin de rastrel.|0.11|150415|3| +~C|mt13bto010e|m|Placa bajo teja, asfltica, impermeable, BT 235 "ONDULINE", arma|2.87|150415|3| +~C|mt13bto020a|m|Lmina autoadhesiva autoprotegida, Ondufilm "ONDULINE", para el|1.37|150415|3| +~C|mt13bto025a|Ud|Masilla de poliuretano, Onduflex 300 (300 c.c.) "ONDULINE".|2.24|150415|3| +~C|mt13ccz030baa|m|Bandeja de zinctitanio, "RHEINZINK" Clic System, acabado natural|25.9|150415|3| +~C|mt13eag011aac|m|Panel sndwich para cubiertas, modelo TFcH/9-60-19 "THERMOCHIP",|23.92|150415|3| +~C|mt13eag020|Ud|Tornillo autotaladrante no oxidable para fijacin de paneles sn|0.03|150415|3| +~C|mt13eag023|Ud|Clavo de acero para fijacin de rastrel de madera a soporte de h|0.03|150415|3| +~C|mt13eag030|m|Banda impermeabilizante autoadhesiva para impermeabilizacin de|0.2|150415|3| +~C|mt13lpo010fh|m|Placa asfltica 15 ondas de perfil ondulado y color rojo tricapa|3.67|150415|3| +~C|mt13lpo034a|Ud|Clavo, Espiral "ONDULINE", con arandela.|0.03|150415|3| +~C|mt13lpo034b|Ud|Clavo, con arandela, para fijacin de placa bajo teja.|0.03|150415|3| +~C|mt13tac010a|Ud|Teja cermica curva, 40x19x16 cm, color rojo, segn UNE-EN 1304.|0.1|150415|3| +~C|mt13tac010aa|Ud|Teja cermica curva, 40x19x16 cm, color rojo, segn UNE-EN 1304.|0.1|150415|3| +~C|mt13tac011a|Ud|Pieza cermica de caballete, curva, color rojo, segn UNE-EN 130|0.31|150415|3| +~C|mt13tac013a|Ud|Teja cermica de ventilacin, curva, color rojo, segn UNE-EN 13|2.67|150415|3| +~C|mt15dan010abj|m|Lmina impermeabilizante flexible, tipo PVC|0.51|150415|3| +~C|mt16aaa030|m|Cinta autoadhesiva para sellado de juntas.|0.13|150415|3| +~C|mt16lra020aba|m|Panel flexible y ligero de lana de roca volcnica, segn UNE-EN|1.01|150415|3| +~C|mt16lra020na|m|Panel semirrgido de lana mineral, segn UNE-EN 13162, no revest|3.36|150415|3| +~C|mt16lra060b|m|Panel semirrgido de lana mineral, espesor 65 mm, segn UNE-EN 1|1.48|150415|3| +~C|mt16pea020aa|m|Panel rgido de poliestireno expandido, segn UNE-EN 13163, meca|0.38|150415|3| +~C|mt16pea020ab|m|Panel rgido de poliestireno expandido, segn UNE-EN 13163, meca|0.55|150415|3| +~C|mt16pop010ac|m|Suministro y aplicacin de espuma rgida de poliuretano proyecta|2.72|150415|3| +~C|mt16pxa010p|m|Panel rgido de poliestireno extruido, segn UNE-EN 13164, de su|3.92|150415|3| +~C|mt17poa010a|m|Film de polietileno de 0,15 mm de espesor.|0.06|150415|3| +~C|mt17poa010b|m|Film de polietileno de 0,20 mm de espesor.|0.07|150415|3| +~C|mt17poa011a|m|Lmina de espuma de polietileno de alta densidad de 3 mm de espe|0.54|150415|3| +~C|mt17poa011aa|m|Lmina de espuma de polietileno de alta densidad de 3 mm de espe|0.23|150415|3| +~C|mt18bcp010bae|m|Baldosa cermica de gres porcelnico 2/0/-/-, 30x30 cm, acabado|6.71|150415|3| +~C|mt18bcr010baa|m|Baldosa cermica de gres rstico 2/0/-/-, 30x30 cm, 8,00 /m, s|3.29|150415|3| +~C|mt18bgn010tba|m|Baldosa de granito nacional, Silvestre, 60x40x2 cm, acabado puli|18.89|150415|3| +~C|mt18mpg011aaa|m|Lama machihembrada de 2180x200x14 mm, para parquet flotante de m|7.65|150415|3| +~C|mt18mta020k|m|Tarima flotante en tablas de madera maciza de roble, de 22 mm de|57.59|150415|3| +~C|mt18mta030bga|m|Tablas de madera maciza, de teca, de 28x145x800/2800 mm, sin tra|17.39|150415|3| +~C|mt18mta050|Ud|Kit de ensamble para tarima exterior de madera maciza, compuesto|0.1|150415|3| +~C|mt18mva015b|m|Rastrel de madera de pino Suecia, de 50x38 mm, tratado en autocl|0.53|150415|3| +~C|mt18mva021|Ud|Material auxiliar para colocacin de tarima flotante con clips.|0.88|150415|3| +~C|mt18mva070|l|Adhesivo tipo D3 (antihumedad).|0.65|150415|3| +~C|mt18mva100|Ud|Clip para fijacin de tabla de madera en tarima flotante.|0.07|150415|3| +~C|mt18rcp010a30|m|Rodapi cermico de gres porcelnico, acabado pulido, 7 cm, 3,00|2.55|140415|3| +~C|mt18rcr010a30|m|Rodapi cermico de gres rstico, 7 cm, 3,00/m.|2.52|150415|3| +~C|mt18rgn010ua|m|Rodapi de granito nacional, Silvestre GT, 7x1 cm, cara y cantos|1.89|150415|3| +~C|mt18rma030j|m|Rodapi de MDF acabado en madera de roble, 6x1,2 cm, barnizado e|1.38|150415|3| +~C|mt19aba010aaa|m|Baldosa cermica de azulejo liso 1/0/-/-, 20x20 cm, 8,00 /m, s|3.29|150415|3| +~C|mt19awa010|m|Cantonera de PVC en esquinas alicatadas.|0.54|150415|3| +~C|mt20ahp010j|m|Albardilla prefabricada de hormign de color blanco, para cubric|9.8|150415|3| +~C|mt20chn030aac|m|Tubo de pared simple de chapa de acero con recubrimiento de esma|5.09|150415|3| +~C|mt20chn031aa|Ud|Material auxiliar para montaje y sujecin a la obra de los condu|0.37|150415|3| +~C|mt20cme020ad|m|Tubo de aluminio natural flexible, de 110 mm de dimetro, inclus|1.05|150415|3| +~C|mt20cmn125ac|m|Tubo de doble pared, compuesto por pared interior de acero inoxi|75.97|150415|3| +~C|mt20cmn126a|Ud|Material auxiliar para montaje y sujecin a la obra de los tubos|3.45|150415|3| +~C|mt20cve010aaa|Ud|Aspirador giratorio con sombrero dinmico, de aluminio (Dureza H|71.48|150415|3| +~C|mt20cvg010aad|m|Tubo de chapa de acero galvanizado de pared simple lisa, autocon|2.28|150415|3| +~C|mt20cvg410a|Ud|Material auxiliar para montaje y sujecin a la obra de los condu|0.1|150415|3| +~C|mt20svg050aab|Ud|Boca de extraccin, graduable, de chapa galvanizada lacada en co|8.41|150415|3| +~C|mt20wwr030|m|Lmina de separacin compuesta por lmina de difusin abierta (f|2.47|150415|3| +~C|mt21veg011aaa|m|Doble acristalamiento estndar, conjunto formado por vidrio exte|6.32|150415|3| +~C|mt21ves010ab|m|Vidrio laminar de seguridad compuesto por dos lunas de 4 mm de e|10.3|150415|3| +~C|mt21vva015|Ud|Cartucho de silicona sinttica incolora de 310 ml (rendimiento a|0.99|150415|3| +~C|mt21vva021|Ud|Material auxiliar para la colocacin de vidrios.|0.52|150415|3| +~C|mt22aap010ab|m|Precerco, pino pas, 70x35 mm, con elementos de fijacin.|0.79|150415|3| +~C|mt22aap010b|m|Precerco, pino pas, 70x35 mm, con elementos de fijacin.|1.62|150415|3| +~C|mt22aap011daa|Ud|Precerco de madera de pino, 90x35 mm, para puerta de una hoja, c|7.14|150415|3| +~C|mt22aap011wa|Ud|Precerco de madera de pino, 130x40 mm, para puerta de una hoja,|24.06|150415|3| +~C|mt22aga010dbd|m|Galce de MDF, con rechapado de madera, iroko, 90x20 mm, barnizad|1.54|150415|3| +~C|mt22aga010deo|m|Galce de MDF, con rechapado de madera, iroko, 130x20 mm, para ba|2.99|150415|3| +~C|mt22ata010adr|m|Tapajuntas de MDF, con rechapado de madera, iroko, 70x10 mm, par|0.95|150415|3| +~C|mt22ata010dba|m|Tapajuntas de MDF, con rechapado de madera, iroko, 70x10 mm, bar|0.65|150415|3| +~C|mt22atc010dA|m|Tapajuntas macizo, iroko, 70x15 mm, para barnizar.|4.08|150415|3| +~C|mt22atc010dec|m|Tapajuntas macizo, iroko, 70x15 mm, para barnizar.|2|150415|3| +~C|mt22eap010ch|Ud|Block de armario prefabricado para empotrar de tres hojas abatib|155.11|150415|3| +~C|mt22eap010dl|Ud|Block de armario prefabricado para empotrar de cuatro hojas abat|184.32|150415|3| +~C|mt22eap010ds|Ud|Block de armario prefabricado para empotrar de cuatro hojas abat|208.64|150415|3| +~C|mt22pxf020aad|Ud|Puerta de paso ciega de iroko, de 203x82,5x3,5 cm, con tablero a|32.45|150415|3| +~C|mt22pxh011db|Ud|Puerta blindada de entrada de tablero aglomerado, chapado con ir|137.13|150415|3| +~C|mt22xcc015bb|m|Carpintera exterior sin gua de persiana, en madera de iroko pa|77.06|150415|3| +~C|mt22xcc015d|m|Carpintera exterior sin gua de persiana, de madera de iroko pa|157.42|150415|3| +~C|mt22xcv030aab|m|Contraventana mallorquina formada por lamas fijas, de madera de|82.99|150415|3| +~C|mt22xcv030b|m|Contraventana mallorquina formada por lamas fijas, de madera de|299.51|150415|3| +~C|mt22xcv031a|Ud|Accesorios, herrajes de colgar y apertura, tornillera de acero|11.86|150415|3| +~C|mt22xcv031ab|Ud|Accesorios, herrajes de colgar y apertura, tornillera de acero|5.91|150415|3| +~C|mt23hax010a|Ud|Juego de manivela y escudo largo en el interior, en acero inoxid|65.56|150415|3| +~C|mt23hax020a|Ud|Tirador exterior con escudo en acero inoxidable Marino AISI 316L|47.83|150415|3| +~C|mt23hax100a|Ud|Mirilla ptica gran angular de 14 mm de dimetro y 35 a 60 mm de|2.1|150415|3| +~C|mt23hbl010aaa|Ud|Juego de manivela y escudo largo de latn negro brillo, serie b|3.34|150415|3| +~C|mt23ibl010bab|Ud|Pernio de 100x58 mm, con remate, en latn negro brillo, para pue|0.31|150415|3| +~C|mt23ppa020a|Ud|Cerradura de alta seguridad, para embutir (palancas), de tres pu|75.97|150415|3| +~C|mt23ppa030|Ud|Bisagra de alta seguridad, antipalanca, con 8 rodamientos, altur|35.44|150415|3| +~C|mt23ppb031|Ud|Tornillo de latn 21/35 mm.|0.03|150415|3| +~C|mt23ppb200|Ud|Cerradura de embutir, frente, accesorios y tornillos de atado, p|4.64|150415|3| +~C|mt23xpm010|Ud|Tornillo de ensamble zinc/pavn.|0.01|150415|3| +~C|mt23xpm020|Ud|Imn de cierre reforzado.|0.13|150415|3| +~C|mt23xpm030|Ud|Tirador ventana/balconera de latn.|0.75|150415|3| +~C|mt23xpm040|Ud|Cremona por tabla para ventana y balconera. Varilla vista. Acaba|3.34|150415|3| +~C|mt23xpm050|Ud|Pernio de latn plano 80x52 mm.|0.28|150415|3| +~C|mt26aaa031|Ud|Repercusin, por m de barandilla, de elementos de fijacin sobre|0.84|150415|3| +~C|mt26dbe010aaa|m|Barandilla metlica de tubo hueco de acero laminado en fro de 9|24.91|150415|3| +~C|mt26dbe040aaa|m|Barandilla metlica de tubo hueco de acero laminado en fro de 9|25.27|150415|3| +~C|mt26dpa010a|m|Pasamanos metlico en remate de antepecho, formado por tubo huec|21.26|150415|3| +~C|mt26pga010aac|Ud|Puerta abatible/pivotante de una hoja para garaje, 250x250 cm, f|496.92|150415|3| +~C|mt27baj010aaa|l|Barniz al agua para interior, a poro cerrado, acabado brillante,|6.26|150415|3| +~C|mt27baj020aaa|l|Barniz de fondo al agua para interior, acabado brillante, a base|3.61|150415|3| +~C|mt27esj020aaa|l|Esmalte sinttico satinado para interior a base de resinas alcd|7.25|150415|3| +~C|mt27pfc030a|l|Solucin de agua y leja al 10%.|2.06|150415|3| +~C|mt27pfi010|l|Imprimacin de secado rpido, formulada con resinas alqudicas m|2.89|160415|3| +~C|mt27pfi030|kg|Imprimacin antioxidante con poliuretano.|3.85|150415|3| +~C|mt27pfi050|kg|Imprimacin SHOP-PRIMER a base de resinas pigmentadas con xido|9.84|150415|3| +~C|mt27pfj010aaa|l|Imprimacin selladora para interior con resinas acrlicas en dis|3.23|150415|3| +~C|mt27pij020aba|l|Pintura plstica para exterior a base de un copolmero acrlico-|3.83|150415|3| +~C|mt27pij040aaa|l|Pintura plstica para interior en dispersin acuosa, lavable, ti|2.35|150415|3| +~C|mt27pij100aaa|l|Pintura autolimpiable a base de resinas de Pliolite y disolvente|4.58|150415|3| +~C|mt27pir090aaa|l|Pintura plstica a base de copolmeros acrlicos en dispersin a|6.57|150415|3| +~C|mt27plj010aaa|l|Imprimacin selladora para interior, formulada con resinas alcd|6.06|150415|3| +~C|mt27prb010|kg|Protector qumico insecticida-fungicida.|1.14|150415|3| +~C|mt30bas010a|Ud|Baera acrlica gama bsica, color blanco, de 140x70 cm, sin asa|46.22|150415|3| +~C|mt30bps010a|Ud|Bid de porcelana sanitaria serie bsica, color blanco, sin tapa|14.23|150415|3| +~C|mt30bps010aaa|Ud|Bid de porcelana sanitaria serie bsica, color blanco, sin tapa|14.23|150415|3| +~C|mt30dba020|Ud|Desage automtico de latn-cobre para baera, acabado cromado.|32.38|150415|3| +~C|mt30del010aaa|Ud|Toma de desage para electrodomstico, con enlace mixto macho de|0.47|150415|3| +~C|mt30ips010a|Ud|Inodoro de porcelana sanitaria, con tanque bajo, serie bsica, c|52.75|150415|3| +~C|mt30ips010aa|Ud|Inodoro de porcelana sanitaria, con tanque bajo, serie bsica, c|52.75|150415|3| +~C|mt30lla010|Ud|Llave de regulacin de 1/2", para lavabo o bid, acabado cromado|5.22|150415|3| +~C|mt30lla020|Ud|Llave de regulacin de 1/2", para inodoro, acabado cromado.|5.96|150415|3| +~C|mt30lps010aa|Ud|Lavabo de porcelana sanitaria, con pedestal, serie bsica, color|21.76|150415|3| +~C|mt30lps010aaa|Ud|Lavabo de porcelana sanitaria, con pedestal, serie bsica, color|21.76|150415|3| +~C|mt30lps030aaa|Ud|Lavabo de porcelana sanitaria, de semiempotrar, serie bsica, co|32.23|150415|3| +~C|mt30pas010bab|Ud|Plato de ducha acrlico gama bsica, color, de 80x80 cm, con jue|54.61|150415|3| +~C|mt30pas010d|Ud|Plato de ducha acrlico gama bsica, color, de 75x75 cm, con jue|50.61|150415|3| +~C|mt31gcg070a|Ud|Llave de paso para lavadora o lavavajillas, para roscar, serie b|6.57|150415|3| +~C|mt31gmg010a|Ud|Grifera monomando con cartucho cermico para lavabo, serie bsi|19.6|150415|3| +~C|mt31gmg010aaa|Ud|Grifera monomando con cartucho cermico para lavabo, serie bsi|19.6|150415|3| +~C|mt31gmg020a|Ud|Grifera monomando con cartucho cermico para bid, serie bsica|20.38|150415|3| +~C|mt31gmg020aaa|Ud|Grifera monomando con cartucho cermico para bid, serie bsica|20.38|150415|3| +~C|mt31gmg040a|Ud|Grifera monomando con cartucho cermico para bao/ducha, serie|20.58|150415|3| +~C|mt31gmg050a|Ud|Grifera monomando con cartucho cermico para ducha, serie bsic|18.12|150415|3| +~C|mt31gmg050aa|Ud|Grifera monomando con cartucho cermico para ducha, serie bsic|18.13|150415|3| +~C|mt32exs010a|Ud|Extractor de cocina, de dimensiones 218x127x304 mm, velocidad 22|28.35|150415|3| +~C|mt33seg100aa|Ud|Interruptor unipolar, gama bsica, con tecla simple y marco de 1|2.4|150415|3| +~C|mt33seg101aa|Ud|Interruptor bipolar, gama bsica, con tecla bipolar y marco de 1|4.35|150415|3| +~C|mt33seg102aa|Ud|Conmutador, serie bsica, con tecla simple y marco de 1 elemento|2.56|150415|3| +~C|mt33seg103aa|Ud|Conmutador de cruce, gama bsica, con tecla simple y marco de 1|4.7|150415|3| +~C|mt33seg104aa|Ud|Pulsador, gama bsica, con tecla con smbolo de timbre y marco d|2.7|150415|3| +~C|mt33seg105aa|Ud|Zumbador 230 V, gama bsica, con tapa y marco de 1 elemento de c|8.51|150415|3| +~C|mt33seg107aa|Ud|Base de enchufe de 16 A 2P+T, gama bsica, con tapa y marco de 1|2.56|150415|3| +~C|mt33seg107bb|Ud|Base de enchufe de 16 A 2P+T, gama bsica, con tapa de color bla|1.38|150415|3| +~C|mt33seg110aa|Ud|Base de enchufe de 25 A 2P+T y 250 V para cocina, gama bsica, c|4.82|150415|3| +~C|mt33seg111aa|Ud|Doble interruptor, gama bsica, con tecla doble y marco de 1 ele|3.69|150415|3| +~C|mt33seg504a|Ud|Base de enchufe de 16 A 2P+T monobloc estanca, para instalacin|3.97|150415|3| +~C|mt33sem117aaa|Ud|Marco horizontal de 3 elementos, gama bsica de color blanco.|2.67|150415|3| +~C|mt35aia010aaa|m|Tubo curvable de PVC, corrugado, de color negro, de 16 mm de di|0.08|150415|3| +~C|mt35aia010aab|m|Tubo curvable de PVC, corrugado, de color negro, de 20 mm de di|0.09|150415|3| +~C|mt35aia010aac|m|Tubo curvable de PVC, corrugado, de color negro, de 25 mm de di|0.13|150415|3| +~C|mt35aia020aad|m|Tubo curvable de PVC, transversalmente elstico, corrugado, forr|0.31|150415|3| +~C|mt35aia060aaa|m|Tubo curvable de polipropileno de doble pared (interior lisa y e|0.92|150415|3| +~C|mt35aia070aaa|m|Tubo curvable, suministrado en rollo, de polietileno de doble pa|0.91|150415|3| +~C|mt35aia080aaa|m|Tubo curvable, suministrado en rollo, de polietileno de doble pa|0.57|150415|3| +~C|mt35aia090aaa|m|Tubo rgido de PVC, roscable, curvable en caliente, de color neg|0.7|150415|3| +~C|mt35caj010a|Ud|Caja de empotrar universal, enlace por los 2 lados.|0.1|150415|3| +~C|mt35caj010b|Ud|Caja de empotrar universal, enlace por los 4 lados.|0.2|150415|3| +~C|mt35caj011|Ud|Caja de empotrar para toma de 25 A (especial para toma de corrie|0.82|150415|3| +~C|mt35caj020a|Ud|Caja de derivacin para empotrar de 105x105 mm, con grado de pro|0.73|150415|3| +~C|mt35caj020b|Ud|Caja de derivacin para empotrar de 105x165 mm, con grado de pro|0.93|150415|3| +~C|mt35cgm021aab|Ud|Interruptor general automtico (IGA), con 6 kA de poder de corte|17.29|150415|3| +~C|mt35cgm021abb|Ud|Interruptor automtico magnetotrmico, con 6 kA de poder de cort|5.78|150415|3| +~C|mt35cgm029aab|Ud|Interruptor diferencial instantneo, 2P/40A/30mA, de 2 mdulos,|38.51|150415|3| +~C|mt35cgm029aah|Ud|Interruptor diferencial instantneo, 2P/40A/300mA, de 2 mdulos,|37.5|150415|3| +~C|mt35cgm040aca|Ud|Caja empotrable con puerta opaca, para alojamiento del interrupt|11.5|150415|3| +~C|mt35cgp010aab|Ud|Caja de proteccin y medida CPM1-S2, de hasta 63 A de intensidad|40.24|150415|3| +~C|mt35cgp040af|m|Tubo de PVC liso, serie B, de 110 mm de dimetro exterior y 3,2|1.53|150415|3| +~C|mt35cgp040ah|m|Tubo de PVC liso, serie B, de 160 mm de dimetro exterior y 3,2|2.23|150415|3| +~C|mt35cun020e|m|Cable unipolar ES07Z1-K (AS), no propagador de la llama, con con|1|150415|3| +~C|mt35cun040aba|m|Cable unipolar H07V-K con conductor multifilar de cobre clase 5|0.11|150415|3| +~C|mt35cun040acb|m|Cable unipolar H07V-K con conductor multifilar de cobre clase 5|0.2|150415|3| +~C|mt35cun040add|m|Cable unipolar H07V-K con conductor multifilar de cobre clase 5|0.46|150415|3| +~C|mt35cun040aec|m|Cable unipolar H07V-K con conductor multifilar de cobre clase 5|0.31|150415|3| +~C|mt35cun040afb|m|Cable unipolar H07V-K con conductor multifilar de cobre clase 5|0.2|150415|3| +~C|mt35cun040aid|m|Cable unipolar H07V-K con conductor multifilar de cobre clase 5|0.45|150415|3| +~C|mt35cun040akb|m|Cable unipolar H07V-K con conductor multifilar de cobre clase 5|0.19|150415|3| +~C|mt35der011aa|m|Conductor de cobre de 1,5 mm de seccin, para hilo de mando, de|0.04|150415|3| +~C|mt35ttc010ab|m|Conductor de cobre desnudo, de 35 mm.|1.15|150415|3| +~C|mt35ttc020ac|m|Conductor rgido unipolar de cobre, aislado, 750 V y 4 mm de se|0.19|150415|3| +~C|mt35ttc030|Ud|Abrazadera de latn.|0.57|150415|3| +~C|mt35tte020a|Ud|Placa de cobre electroltico puro para toma de tierra, de 300x10|15.38|150415|3| +~C|mt35tts010c|Ud|Soldadura aluminotrmica del cable conductor a la placa.|1.44|150415|3| +~C|mt35www010|Ud|Material auxiliar para instalaciones elctricas.|0.59|150415|3| +~C|mt35www020|Ud|Material auxiliar para instalaciones de toma de tierra.|0.46|150415|3| +~C|mt36tit010abc|m|Tubo de PVC, serie B, de 40 mm de dimetro y 3 mm de espesor, se|1.46|150415|3| +~C|mt36tit010afi|m|Tubo de PVC, serie B, de 90 mm de dimetro y 3,2 mm de espesor,|4.93|150415|3| +~C|mt36tit010agc|m|Tubo de PVC, serie B, de 110 mm de dimetro y 3,2 mm de espesor,|4.36|150415|3| +~C|mt36tit010ahi|m|Tubo de PVC, serie B, de 125 mm de dimetro y 3,2 mm de espesor,|6.24|150415|3| +~C|mt36tit400af|Ud|Material auxiliar para montaje y sujecin a la obra de las tuber|0.52|150415|3| +~C|mt36tit400ah|Ud|Material auxiliar para montaje y sujecin a la obra de las tuber|0.66|150415|3| +~C|mt36www005a|Ud|Acoplamiento a pared acodado con plafn, de PVC, serie B, acabad|0.95|150415|3| +~C|mt36www005aa|Ud|Acoplamiento a pared acodado con plafn, de PVC, serie B, acabad|0.94|150415|3| +~C|mt37aar010a|Ud|Marco y tapa de fundicin dctil de 30x30 cm, segn Compaa Sum|4.86|150415|3| +~C|mt37avu150ab|Ud|Vlvula de asiento, de bronce, de 20 mm de dimetro, con dos ele|31.27|150415|3| +~C|mt37avu150ac|Ud|Vlvula de asiento, de bronce, de 25 mm de dimetro, con dos ele|34.04|150415|3| +~C|mt37sgl012a|Ud|Grifo de comprobacin de latn, para roscar, de 1/2".|2.03|150415|3| +~C|mt37svc010a|Ud|Vlvula de compuerta de latn fundido, para roscar, de 1/2".|2.39|150415|3| +~C|mt37sve030c|Ud|Vlvula de esfera de latn niquelado para roscar de 3/4", con ma|2.33|150415|3| +~C|mt37svr010a|Ud|Vlvula de retencin de latn para roscar de 1/2".|1.17|150415|3| +~C|mt37tpa011b|m|Acometida de polietileno de alta densidad banda azul (PE-100), d|0.47|150415|3| +~C|mt37tpa012b|Ud|Collarn de toma en carga de PP, para tubo de polietileno de alt|2.15|150415|3| +~C|mt37tpu010aag|m|Tubo de polietileno reticulado (PE-X), de 16 mm de dimetro exte|0.8|150415|3| +~C|mt37tpu010abg|m|Tubo de polietileno reticulado (PE-X), de 20 mm de dimetro exte|0.97|150415|3| +~C|mt37tpu010acg|m|Tubo de polietileno reticulado (PE-X), de 25 mm de dimetro exte|1.72|150415|3| +~C|mt37tpu400aa|Ud|Material auxiliar para montaje y sujecin a la obra de las tuber|0.02|150415|3| +~C|mt37tpu400ab|Ud|Material auxiliar para montaje y sujecin a la obra de las tuber|0.02|150415|3| +~C|mt37tpu400ac|Ud|Material auxiliar para montaje y sujecin a la obra de las tuber|0.05|150415|3| +~C|mt37www010|Ud|Material auxiliar para instalaciones de fontanera.|0.54|150415|3| +~C|mt37www060b|Ud|Filtro retenedor de residuos de latn, con tamiz de acero inoxid|2.02|150415|3| +~C|mt38cbh012bbf|Ud|Caldera para la combustin de pellets, potencia nominal de 6,2 a|3912.93|150415|3| +~C|mt38cbh085ba|Ud|Sistema de elevacin de la temperatura de retorno por encima de|151.57|150415|3| +~C|mt38cbh096ba|Ud|Regulador de tiro de 150 mm de dimetro, para caldera "HERZ".|126.92|150415|3| +~C|mt38cbh097b|Ud|Limitador trmico de seguridad, para caldera "HERZ".|32.83|150415|3| +~C|mt38cbh100bb|Ud|Puesta en marcha y formacin en el manejo de caldera de biomasa|143.76|150415|3| +~C|mt38emi010aaa|Ud|Elemento para radiador de aluminio inyectado en instalaciones de|4.81|150415|3| +~C|mt38emi011a|Ud|Kit para montaje de radiador de aluminio inyectado, compuesto po|5.65|150415|3| +~C|mt38emi013|Ud|Kit para conexin de radiador de aluminio inyectado a la tubera|10.6|150415|3| +~C|mt38tew010a|Ud|Latiguillo flexible de 20 cm y 1/2" de dimetro.|1.17|150415|3| +~C|mt40cfr010aaa|m|Cable coaxial RG-6, de 75 Ohm de impedancia caracterstica media|0.33|150415|3| +~C|mt40cpt010aa|m|Cable rgido U/UTP de 4 pares de cobre, categora 6, con conduct|0.12|150415|3| +~C|mt40dpt060a|Ud|Toma simple con conector tipo RJ45 de 8 contactos, categora 6,|5.64|150415|3| +~C|mt40eaf011aa|Ud|Amplificador de mstil, de 3 entradas, BI/FM/BIII-UHF-FI, de 35|12.28|150415|3| +~C|mt40eaf040aab|Ud|Fuente de alimentacin, de una salida, de 250 mA de intensidad m|8.74|150415|3| +~C|mt40eaf100aa|Ud|Carga resistiva de 75 Ohm, para cierre.|0.87|150415|3| +~C|mt40ecf020aaa|Ud|Antena exterior DAB para captacin de seales de radiodifusin s|6.66|150415|3| +~C|mt40ecf030acb|Ud|Antena exterior UHF para captacin de seales de televisin anal|18.63|150415|3| +~C|mt40irf026acc|Ud|Distribuidor de 5-2400 MHz de 4 salidas con punto de acceso a us|3.2|150415|3| +~C|mt40irf050aab|Ud|Toma separadora doble, TV/R-SAT, de 5-2400 MHz, con embellecedor|2.19|150415|3| +~C|mt40irt020aa|Ud|Caja de plstico de registro de terminacin de red para instalac|16.81|150415|3| +~C|mt40iva020d|Ud|Soporte separador de tubos de PVC rgido de 63 mm de dimetro.|0.67|150415|3| +~C|mt40iva030|m|Hilo gua de polipropileno de 3 mm de dimetro.|0.05|150415|3| +~C|mt40pea010|m|Manguera de telefona, 6 hilos de 0,5 mm.|0.35|150415|3| +~C|mt40pek110|Ud|Kit de portero electrnico para vivienda unifamiliar, compuesto|58.95|150415|3| +~C|mt40saf010acb|Ud|Mstil de antena de 3 m de alto, para unin por enchufe, fabrica|10.08|150415|3| +~C|mt40saf011abb|Ud|Garra de anclaje a obra en L para mstil, para colocacin en sup|2.69|150415|3| +~C|mt40www040|Ud|Material auxiliar para instalaciones audiovisuales.|0.48|150415|3| +~C|mt40www050|Ud|Material auxiliar para infraestructura de telecomunicaciones.|0.58|150415|3| +~C|mt41ixi010a|Ud|Extintor porttil de polvo qumico ABC polivalente antibrasa, co|18.21|150415|3| +~C|mt48pla030|l|Herbicida de contacto para la destruccin de plantas herbceas.|4.97|150415|3| +~C|mt49arb010|Ud|Ensayo para determinar las caractersticas geomtricas del corru|19.27|160415|3| +~C|mt49arb020|Ud|Ensayo para determinar la presencia o ausencia de grietas median|8.28|160415|3| +~C|mt49arb040|Ud|Ensayo para determinar la seccin media equivalente sobre una mu|13.06|160415|3| +~C|mt49arb050|Ud|Ensayo para determinar las siguientes caractersticas mecnicas:|25.87|160415|3| +~C|mt49arm010|Ud|Ensayo para determinar las caractersticas geomtricas del corru|19.24|160415|3| +~C|mt49arm020|Ud|Ensayo para determinar la presencia o ausencia de grietas median|8.23|160415|3| +~C|mt49arm040|Ud|Ensayo para determinar la seccin media equivalente sobre una mu|13.01|160415|3| +~C|mt49arm050|Ud|Ensayo para determinar la carga de despegue de los nudos sobre u|25.84|160415|3| +~C|mt49arm060|Ud|Ensayo para determinar las siguientes caractersticas mecnicas:|25.89|160415|3| +~C|mt49des010|Ud|Repercusin de desplazamiento a obra para la toma de muestras.|0.31|160415|3| +~C|mt49hob020ca|Ud|Ensayo para determinar la consistencia del hormign fresco media|44.14|160415|3| +~C|mt49pma020|Ud|Toma en obra de muestras de perfil laminado en estructura metli|15.68|160415|3| +~C|mt49pma030|Ud|Informe de resultados de los ensayos realizados sobre una muestr|47.11|160415|3| +~C|mt49pma050|Ud|Ensayo a traccin para determinar el lmite elstico aparente, l|27.53|160415|3| +~C|mt49pma080|Ud|Ensayo de doblado a 180 sobre una muestra de perfil laminado en|11.9|160415|3| +~C|mt50bal010aaa|m|Cinta para balizamiento, de material plstico, de 8 cm de anchur|0.03|150415|3| +~C|mt50bal020|Ud|Bandern para sealizacin, de material textil, con recubrimient|2.88|150415|3| +~C|mt50cat010a|m|Adaptacin de local existente como caseta provisional de obra, p|72.79|150415|3| +~C|mt50eca010|Ud|Botiqun de urgencia.|39.45|150415|3| +~C|mt50eca011|Ud|Reposicin de botiqun de urgencia.|40.43|150415|3| +~C|mt50eca020|Ud|Camilla porttil para evacuaciones.|58.39|150415|3| +~C|mt50epc020bfj|Ud|Casco de proteccin, EPI de categora II, segn UNE-EN 397 y UNE|0.93|150415|3| +~C|mt50epd010ac|Ud|Conector bsico (clase B), EPI de categora III, segn UNE-EN 36|6.19|150415|3| +~C|mt50epd012aad|Ud|Cuerda de fibra como elemento de amarre, de longitud fija, EPI d|26.21|150415|3| +~C|mt50epd013d|Ud|Absorbedor de energa, EPI de categora III, segn UNE-EN 355, c|37.41|150415|3| +~C|mt50epd015bd|Ud|Cinturn de sujecin y retencin, EPI de categora III, segn UN|20|150415|3| +~C|mt50epj010cbc|Ud|Gafas de proteccin con montura integral, resistentes a polvo gr|7.22|150415|3| +~C|mt50epj010mcc|Ud|Pantalla de proteccin facial, resistente a impactos de partcul|8.23|150415|3| +~C|mt50epm010acd|Ud|Par de guantes contra riesgos mecnicos EPI de categora II, seg|5.49|150415|3| +~C|mt50epm010ead|Ud|Par de guantes para trabajos elctricos de baja tensin, EPI de|17.01|150415|3| +~C|mt50epm070d|Ud|Protector de manos para puntero, EPI de categora I, segn UNE-E|1.35|150415|3| +~C|mt50epo010aaj|Ud|Juego de orejeras, estndar, con atenuacin acstica de 15 dB, E|3.97|150415|3| +~C|mt50epo020aaa|Ud|Juego de tapones desechables, moldeables, con atenuacin acstic|0.01|150415|3| +~C|mt50epp010cab|Ud|Par de botas bajas de trabajo, sin puntera resistente a impactos|13.96|150415|3| +~C|mt50epp020bc|Ud|Par de polainas para extincin de incendios, EPI de categora II|28.13|150415|3| +~C|mt50epp030a|Ud|Par de plantillas resistentes a la perforacin, EPI de categora|2.66|150415|3| +~C|mt50epu025aae|Ud|Mono de proteccin para trabajos expuestos a la lluvia, EPI de c|11.92|150415|3| +~C|mt50epu030bdc|Ud|Chaleco de alta visibilidad, de material reflectante, EPI de cat|9.33|150415|3| +~C|mt50epu040j|Ud|Bolsa portaherramientas, EPI de categora II, segn UNE-EN 340,|9.88|150415|3| +~C|mt50epu050d|Ud|Faja de proteccin lumbar con amplio soporte abdominal y sujeci|7.77|150415|3| +~C|mt50epv010bad|Ud|Mascarilla, de media mscara, EPI de categora III, segn UNE-EN|9.47|150415|3| +~C|mt50epv011abd|Ud|Filtro contra partculas, de eficacia media (P2), EPI de categor|1.24|150415|3| +~C|mt50epv020aba|Ud|Mascarilla autofiltrante contra partculas, FFP1, EPI de categor|0.67|150415|3| +~C|mt50jpr040ac|Ud|Anclaje expansivo de 8x60 mm, de acero galvanizado en caliente.|0.23|150415|3| +~C|mt50jpr050aaa|Ud|Red de seguridad UNE-EN 1263-1 V A2 M100 D M de poliamida de alt|55.79|150415|3| +~C|mt50jpr060aaa|Ud|Pescante tipo horca fijo de 8x2 m con tubo de 60x60x3 mm, fabric|49.82|150415|3| +~C|mt50jpr070ab|m|Cuerda de unin UNE-EN 1263-1 O de polipropileno de alta tenacid|0.06|150415|3| +~C|mt50jpr080aa|m|Cuerda de atado UNE-EN 1263-1 G de polipropileno de alta tenacid|0.14|150415|3| +~C|mt50les010aba|Ud|Seal provisional de obra de chapa de acero galvanizado, de peli|13.29|150415|3| +~C|mt50les020aa|Ud|Cartel general indicativo de riesgos, de PVC serigrafiado, de 99|4.41|150415|3| +~C|mt50les030aaf|Ud|Seal de advertencia, de PVC serigrafiado, de 297x210 mm, con pi|1.24|150415|3| +~C|mt50les040a|Ud|Poste de acero galvanizado de 80x40x2 mm y 145 cm de altura.|5.74|150415|3| +~C|mt50les060|Ud|Pie porttil en cruz de acero galvanizado, para seal provisiona|4.31|150415|3| +~C|mt50man010|Ud|Reconocimiento mdico obligatorio anual al trabajador.|41.97|150415|3| +~C|mt50mas020|Ud|Coste de la hora de charla para formacin de Seguridad y Salud e|32.34|150415|3| +~C|mt50spa050aa|m|Tabla de madera de pino, dimensiones 12x2,7 cm.|123.26|150415|3| +~C|mt50spa050bb|m|Tabloncillo de madera de pino, dimensiones 15x5,2 cm.|121.2|150415|3| +~C|mt50spa050cc|m|Tabln de madera de pino, dimensiones 20x7,2 cm.|125.31|150415|3| +~C|mt50spa080ba|Ud|Puntal metlico telescpico, 3,00 m de altura.|4.47|150415|3| +~C|mt50spa080bb|Ud|Puntal metlico telescpico, 4,00 m de altura.|5.23|150415|3| +~C|mt50spa080bc|Ud|Puntal metlico telescpico, 5,00 m de altura.|6.02|150415|3| +~C|mt50spa101|kg|Clavos de acero.|0.47|150415|3| +~C|mt50spb030aab|Ud|Guardacuerpos telescpico de seguridad fabricado en acero de pri|6.87|150415|3| +~C|mt50spb050a|Ud|Barandilla para guardacuerpos matrizada, de tubo de acero pintad|1.97|150415|3| +~C|mt50spe010|Ud|Lmpara porttil de mano, con cesto protector, mango aislante, c|4.38|150415|3| +~C|mt50spe020b|Ud|Cuadro general de mando y proteccin de obra para una potencia m|427.56|150415|3| +~C|mt50sph060b|m|Repercusin de elementos en venta de sistema anticadas para mon|0.03|150415|3| +~C|mt50sph061b|m|Repercusin de elementos en alquiler de sistema anticadas para|0.01|150415|3| +~C|mt50sph062b|m|Repercusin de material fungible de sistema anticadas para mont|0.03|150415|3| +~C|mt50spr046|Ud|Brida de nylon, de 4,8x200 mm.|0.01|150415|3| +~C|mt51cub020aaa|m|Desmontaje de cobertura de placas de fibrocemento con amianto y|9.86|150415|3| +~C|mt52vst010nx|m|Malla de simple torsin, de 40 mm de paso de malla y 2/3 mm de d|1.62|150415|3| +~C|mt52vst030B|Ud|Poste en escuadra de tubo de acero galvanizado y pintado, de 48|11.22|150415|3| +~C|mt52vst030d|Ud|Poste intermedio de tubo de acero galvanizado y pintado, de 48 m|8.34|150415|3| +~C|mt52vst030l|Ud|Poste interior de refuerzo de tubo de acero galvanizado y pintad|8.97|150415|3| +~C|mt52vst030t|Ud|Poste extremo de tubo de acero galvanizado y pintado, de 48 mm d|11.19|150415|3| +~C|op00ato010||Atornillador.|0|060415|0| +~C|op00cep010||Garlopa.|0|250315|0| +~C|op00cla010||Clavadora.|0|250315|0| +~C|op00fre010||Fresadora.|0|290315|0| +~C|op00gra010||Grapadora.|0|270315|0| +~C|op00roz010||Rozadora.|0|060415|0| +~C|op00sie010||Sierra de calar.|0|270315|0| +~M|0A#\0AS010|2\1\1\|1|| +~M|0A#\0AE010|2\1\2\|1|| +~M|0A#\0AF010|2\1\3\|1|| +~M|0D#\0DP030|2\2\1\|100| +\Edificio A. (superficie aproximada)\1\60.00\\\ +\Edificio B. (superficie aproximada)\1\40.00\\\| +~M|0D#\0DP020|2\2\2\|1200|| +~M|DE#\DEC040|3\1\1\|2.66| +\Pilastra de fachada\1\0.90\\2.95\| +~M|DE#\DEM020|3\1\2\|119.31| +\Edificio B. Forjado planta alta\1\26.05\\\ +\Edificio A. Forjado planta alta\1\93.26\\\| +~M|DE#\DEM050|3\1\3\|126.1| +\Vigas de madera de cubierta de lavadero y alpendre\1\2.51\\\ +\\1\2.41\\\ +\\1\2.41\\\ +\\1\2.36\\\ +\\1\2.46\\\ +\\1\2.51\\\ +\\1\2.41\\\ +\\1\5.68\\\ +\\1\4.92\\\ +\\1\4.77\\\ +\\1\4.82\\\ +\\1\4.98\\\ +\\1\20.84\\\ +\\1\20.97\\\ +\\1\20.98\\\ +\\1\21.07\\\| +~M|DE#\DEM060|3\1\4\|8.8| +\Escalera Edificio A\1\4.00\1.20\\ +\Escalera Edificio B\1\4.00\1.00\\| +~M|DE#\DEM130b|3\1\5\|5| +\Can de madera en soporte de forjado de balcon edificio A\5\\\\| +~M|DE#\DEH020|3\1\6\|10.9| +\Balcon edificio A\1\10.90\\\| +~M|DF#\DFC010|3\2\1\|19| +\Edificio A\13\\\\ +\Edificio B\6\\\\| +~M|DF#\DFD020|3\2\2\|11.8| +\Edificio A\\\\\ +\barandilla de hierro en fachada\1\11.80\\\| +~M|DF#\DFD090|3\2\3\|19| +\Edificio A\13\\\\ +\Edifio B\6\\\\| +~M|DF#\DFR080|3\2\4\|74.95| +\Edificio A\\\\\ +\Cornisa perimetral de pizarra\1\48.95\\\ +\Edificio B\\\\\ +\Cornisa perimetral de pizarra\1\26.00\\\| +~M|DF#\DPT020b|3\2\5\|172.22| +\Edificio B\\\\\ +\Planta baja (altura media)\1\46.65\\3.10\ +\\1\4.45\\3.10\ +\\1\4.45\\3.10\| +~M|DF#\DEF041|3\2\6\|11.08| +\Edificio A\1\1.22\\2.50\ +\pasarela\1\2.21\\2.50\ +\Edificio B\\\\\ +\pasarela\1\1.00\\2.50\| +~M|DP#\DPE100|3\3\1\|1|| +~M|DP#\DPE010|3\3\2\|3|| +~M|DP#\DPP020|3\3\3\|12|| +~M|DP#\DPT020|3\3\4\|194.18| +\Edificio A\\\\\ +\Planta baja\\\\\ +\tabiqueria\1\7.58\\2.60\ +\\1\2.43\\2.60\ +\\1\6.15\\2.60\ +\\1\2.37\\2.60\ +\\1\4.30\\2.60\ +\\1\4.30\\2.60\ +\\1\2.50\\2.60\ +\Planta alta\\\\\ +\tabiquera (altura media)\1\6.15\\3.31\ +\\1\6.15\\3.31\ +\\1\6.55\\3.31\ +\\1\4.24\\3.31\ +\\1\2.29\\3.31\ +\\1\2.90\\3.31\ +\Edificio B\\\\\ +\Planta baja\\\\\ +\tabiquera\1\3.45\\2.60\ +\\1\1.65\\2.60\ +\\1\3.95\\2.60\| +~M|DI#\DIC100|3\4\1\|1|| +~M|DI#\DIE060|3\4\2\|1|| +~M|DI#\DIE010|3\4\3\|1|| +~M|DI#\DIE011|3\4\4\|1|| +~M|DI#\DIF105|3\4\5\|1|| +~M|DQ#\DQC040|3\5\1\|430.02| +\Edificio A\\\\\ +\Cubierta\1\129.11\1.07\\ +\Porche\1\68.40\1.07\\ +\Edificio B\\\\\ +\Cubierta\1\42.24\1.07\\ +\Porche\1\16.17\1.07\\ +\Alpendre\1\145.96\1.07\\| +~M|DQ#\DQF030|3\5\2\|273.84| +\Edificio A\\\\\ +\Cubierta\1\129.11\1.07\\ +\Porche\1\68.40\1.07\\ +\Edificio B\\\\\ +\Cubierta\1\42.24\1.07\\ +\Porche\1\16.17\1.07\\| +~M|DQ#\DQF040|3\5\3\|273.84| +\Edificio A\\\\\ +\Cubierta\1\129.11\1.07\\ +\Porche\1\68.40\1.07\\ +\Edificio B\\\\\ +\Cubierta\1\42.24\1.07\\ +\Porche\1\16.17\1.07\\| +~M|DQ#\DQC030|3\5\4\|142.89| +\Alpendre\1\133.54\1.07\\| +~M|DQ#\DQR010|3\5\5\|3| +\Chimenea Edificio A\1\\\\ +\Chimenea Edificio B\1\\\\ +\Deposito Edificio A\1\\\\| +~M|DR#\DRF010|3\6\1\|306.59| +\EDIFICIO A\\\\\ +\Alzado este\1\87.75\\\ +\a deducir huecos:\\\\\ +\v10\2\-1.18\\\ +\puerta balconera\1\-1.90\\\ +\p6\1\-2.30\\\ +\p4\1\-2.59\\\ +\v5\1\-1.03\\\ +\p7\1\-5.45\\\ +\Alzado norte\1\39.66\\\ +\Porche\1\9.01\\\ +\a deducir huecos:\1\-0.17\\\ +\v6\1\-1.19\\\ +\v1\1\-1.22\\\ +\v1\1\-1.22\\\ +\Alzado oeste\1\89.33\\\ +\a deducir huecos:\\\\\ +\v11\2\-1.08\\\ +\v10\3\-1.28\\\ +\p5\1\-1.83\\\ +\p4\1\-2.62\\\ +\Alzado sur\1\43.78\\\ +\a deducir huecos\\\\\ +\p5\1\-1.69\\\ +\ventana\1\-0.54\\\ +\Edificio B\\\\\ +\Alzado este\1\33.87\\\ +\Porche\1\9.01\\\ +\Alzado norte\1\36.49\1.15\\ +\a deducir huecos\\\\\ +\v6\1\-0.89\\\ +\v1\1\-0.81\\\ +\Alzado oeste\1\33.27\\\ +\a deducir huecos\\\\\ +\v6\1\-1.19\\\ +\v1\1\-1.22\\\ +\Alzado sur\1\-37.95\1.15\\ +\a deducir huecos\\\\\ +\ventana superior\1\-1.19\\\| +~M|DR#\DRS080|3\6\2\|192.2| +\Edificio B\\\\\ +\Garaje\1\54.19\\\ +\Edificio A\\\\\ +\Instalaciones\1\10.88\\\ +\Aseo e instalaciones\1\10.88\\\ +\Despensa\1\14.85\\\ +\Local y despensa\1\101.40\\\| +~M|DR#\DRT010|3\6\3\|84.2| +\Edificio A\\\\\ +\Consulta\1\9.75\\\ +\Hall\1\13.57\\\ +\Consulta\1\15.03\\\ +\Consulta\1\14.10\\\ +\Almacen\1\7.17\\\ +\Escaleras\1\2.26\\\ +\Edificio B\\\\\ +\Cocina\1\16.18\\\ +\Aseo\1\3.30\\\ +\\1\2.84\\\| +~M|DS#\DSC020|3\7\1\|5.1| +\Cocina actual\1\5.10\\\| +~M|DS#\DSM010|3\7\2\|1|| +~M|DS#\DSM010b|3\7\3\|1|| +~M|AD#\ADL005|4\1\1\|93.84| +\Pavimento exterior entre viviendas\1\93.84\\\| +~M|AD#\ADE010|4\1\2\|35.54| +\Zanjas de saneamiento\1\20.86\0.30\0.60\ +\\1\1.20\0.30\0.60\ +\\1\8.53\0.30\0.60\ +\\1\13.43\0.30\0.60\ +\\1\11.05\0.30\0.60\ +\\1\7.84\0.30\0.60\ +\Edificio B bajo nuevo cerramiento\1\10.40\0.30\0.30\ +\Zona pavimento exterior\1\93.84\\0.20\ +\Perimetro sin cerramiento\1\50.00\0.30\0.30\| +~M|AD#\ADR010|4\1\3\|12.27| +\Zanjas de saneamiento\1\20.86\0.30\0.60\ +\\1\1.20\0.30\0.60\ +\\1\8.53\0.30\0.60\ +\\1\13.43\0.30\0.60\ +\\1\11.05\0.30\0.60\ +\\1\7.84\0.30\0.60\ +\Edificio B bajo nuevo cerramiento\1\10.40\0.30\0.30\| +~M|AS#\ASA010|4\2\1\|2|| +~M|AS#\ASB010|4\2\2\|2|| +~M|AS#\ASB020|4\2\3\|1|| +~M|AS#\ASA010b|4\2\4\|1|| +~M|AS#\ASC010|4\2\5\|69.54| +\Edificio A\1\11.14\\\ +\\1\10.49\\\ +\Edificio B\1\3.67\\\ +\\1\9.24\\\ +\Pluviales exteriores\1\25.00\\\ +\A arqueta general\1\10.00\\\| +~M|AN#\ANS020|4\3\1\|207.19| +\Edificio B. Planta baja\1\69.18\\\ +\Edificio A\\\\\ +\Instalaciones\1\10.88\\\ +\Aseo e instalaciones\1\10.88\\\ +\Despensa\1\14.85\\\ +\Local y despensa\1\101.40\\\| +~M|AN#\ANE010|4\3\2\|148.03| +\Edificio B\\\\\ +\Garaje\1\54.19\\\ +\Pavimento exterior\1\93.84\\\| +~M|AN#\ANS010|4\3\3\|148.03| +\Edificio B\\\\\ +\Garaje\1\54.19\\\ +\Pavimento exterior\1\93.84\\\| +~M|AN#\CSV010|4\3\4\|4.5| +\Perimetro sin cerramiento\1\50.00\0.30\0.30\| +~M|EA#\EAV010|5\1\1\|1998.84| +\Edificio A\\\\\ +\Perfileria pasarela. HEB 140\4\5.50\\33.70\ +\IPE 240 Cierre porche\1\3.90\\30.70\ +\IPE 240 Dintel interior hueco muro\1\1.75\\30.70\ +\IPE 240 Almacen\2\4.80\\30.70\ +\LD 120 perimetrales\1\13.20\0.50\\ +\\1\53.90\0.50\\ +\\1\4.20\0.50\\ +\\1\4.20\0.50\\ +\Cubierta pasarela HEB 140\1\5.20\\33.70\ +\Edificio B\1\5.60\\33.70\ +\IPE 240 altillo\1\5.50\\33.70\ +\IPE escalera\1\6.00\\33.70\| +~M|EH#\EHV010|5\2\1\|5.95| +\Edificio A Cubierta\2\16.61\0.40\0.30\ +\Nombre medicin\2\8.16\0.40\0.30\| +~M|EH#\CAV010|5\2\2\|0.94| +\Edificio B bajo nuevo cerramiento\1\10.40\0.30\0.30\| +~M|EH#\EHX011|5\2\3\|116.57| +\Edificio A\1\95.94\\\ +\pasarela y terraza\1\20.63\\\| +~M|EM#\EMV010|5\3\1\|4.08| +\Edificio A\\\\\ +\Vigas forjado techo planta baja\7\3.93\0.14\0.26\ +\Vigas cubierta\10\3.84\0.14\0.26\ +\Cumbrera\1\16.45\0.20\0.20\ +\Edificio B\\\\\ +\Techo planta baja\8\3.05\0.10\0.15\ +\Cubierta\4\3.05\0.14\0.26\ +\Cumbrera\3\1.75\0.20\0.20\| +~M|EM#\EMW020|5\3\2\|1| +\partida a valorar en obra\1\\\\| +~M|EM#\EMV110|5\3\3\|8.07| +\Edificio B\7\16.96\0.20\0.34\| +~M|EM#\Pa11|5\3\4\|1| +\tirante\1\\\\| +~M|FF#\FFZ020|6\1\1\|50.93| +\Edificio B\\\\\ +\Cierre salon\1\8.90\\2.80\ +\Reparacion y cierre muro exterior\1\9.29\\2.80\| +~M|FC#\FCM020|6\2\1\|4| +\V1\4\\\\| +~M|FC#\FCM020b|6\2\2\|1| +\V2\1\\\\| +~M|FC#\FCM020c|6\2\3\|1| +\V3\1\\\\| +~M|FC#\FCM020d|6\2\4\|1| +\V4\1\\\\| +~M|FC#\FCM020e|6\2\5\|1| +\V5\1\\\\| +~M|FC#\FCM020f|6\2\6\|3| +\V6\3\\\\| +~M|FC#\FCM020g|6\2\7\|1| +\V7\1\\\\| +~M|FC#\FCM020h|6\2\8\|1| +\V8\1\\\\| +~M|FC#\FCM020i|6\2\9\|1| +\V9\1\\\\| +~M|FC#\FCM020j|6\2\10\|6| +\V10\6\\\\| +~M|FC#\FCM020k|6\2\11\|2| +\V11\2\\\\| +~M|FC#\FCM020l|6\2\12\|1| +\P1\1\\\\| +~M|FC#\FCM020q|6\2\13\|1| +\P2\1\\\\| +~M|FC#\FCM020m|6\2\14\|1| +\P3\1\\\\| +~M|FC#\FCM020n|6\2\15\|2| +\P4\2\\\\| +~M|FC#\FCM020o|6\2\16\|3| +\P5\3\\\\| +~M|FC#\FCM020p|6\2\17\|1| +\P6\1\\\\| +~M|FC#\FDG010|6\2\18\|1| +\P7\1\\\\| +~M|FD#\FDV030|6\3\1\|4| +\V1\4\\\\| +~M|FD#\FDV030b|6\3\2\|1| +\V5\1\\\\| +~M|FD#\FDV030c|6\3\3\|3| +\V6\3\\\\| +~M|FD#\FDV030d|6\3\4\|6| +\V10\6\\\\| +~M|FD#\FDV030e|6\3\5\|2| +\V11\2\\\\| +~M|FD#\FDV030f|6\3\6\|1| +\V2\1\\\\| +~M|FD#\Pa3|6\3\7\|14.46| +\CF2 (pasarela alzado norte)\1\4.78\\2.40\ +\CF1Edificio B Planta baja(sobre ventana V3)\1\3.99\\0.75\| +~M|FD#\PDB010|6\3\8\|1| +\Edificio A. Barandilla de escalera acceso planta alta\1\\\\| +~M|FD#\Pa9|6\3\9\|1|| +~M|FV#\FVC010b|6\4\1\|58.14| +\V1\4\6.00\0.35\0.41\ +\V2\1\0.40\\0.75\ +\V3\2\1.92\\0.65\ +\V4v\2\2.08\\2.35\ +\V4f\1\1.87\\2.35\ +\V5\1\6.00\0.38\0.35\ +\V6\3\6.00\0.38\0.37\ +\V7\1\4.78\\2.34\ +\V8\2\2.40\\2.22\ +\V9\1\1.05\\2.04\ +\V10\6\6.00\0.38\0.41\ +\V11\2\6.00\0.30\0.41\ +\P2\1\0.80\\2.35\ +\P4\2\0.35\\2.05\| +~M|FV#\FVS010|6\4\2\|7.24| +\Edificio B, barandilla planta alta\1\7.24\\1.00\| +~M|FZ#\FZB040|6\5\1\|306.59| +\EDIFICIO A\\\\\ +\Alzado este\1\87.75\\\ +\a deducir huecos:\\\\\ +\v10\2\-1.18\\\ +\puerta balconera\1\-1.90\\\ +\p6\1\-2.30\\\ +\p4\1\-2.59\\\ +\v5\1\-1.03\\\ +\p7\1\-5.45\\\ +\Alzado norte\1\39.66\\\ +\Porche\1\9.01\\\ +\a deducir huecos:\1\-0.17\\\ +\v6\1\-1.19\\\ +\v1\1\-1.22\\\ +\v1\1\-1.22\\\ +\Alzado oeste\1\89.33\\\ +\a deducir huecos:\\\\\ +\v11\2\-1.08\\\ +\v10\3\-1.28\\\ +\p5\1\-1.83\\\ +\p4\1\-2.62\\\ +\Alzado sur\1\43.78\\\ +\a deducir huecos\\\\\ +\p5\1\-1.69\\\ +\ventana\1\-0.54\\\ +\Edificio B\\\\\ +\Alzado este\1\33.87\\\ +\Porche\1\9.01\\\ +\Alzado norte\1\36.49\1.15\\ +\a deducir huecos\\\\\ +\v6\1\-0.89\\\ +\v1\1\-0.81\\\ +\Alzado oeste\1\33.27\\\ +\a deducir huecos\\\\\ +\v6\1\-1.19\\\ +\v1\1\-1.22\\\ +\Alzado sur\1\-37.95\1.15\\ +\a deducir huecos\\\\\ +\ventana superior\1\-1.19\\\| +~M|PA#\PAF010|7\1\1\|1| +\A1\1\\\\| +~M|PA#\PAF010b|7\1\2\|1| +\A2\1\\\\| +~M|PA#\PAF010c|7\1\3\|1| +\A3\1\\\\| +~M|PA#\PAF010d|7\1\4\|1| +\A4\1\\\\| +~M|PD#\PDB010b|7\2\1\|7.24| +\Edificio B, barandilla planta alta\1\7.24\\1.00\| +~M|PD#\Pa13|7\2\2\|14.16| +\V6\2\1.18\\\ +\V10\10\1.18\\\| +~M|PP#\PPM010|7\3\1\|5| +\PI1\5\\\\| +~M|PP#\PEH010b|7\3\2\|1| +\PB1\1\\\\| +~M|PT#\PTW015|7\4\1\|319.49| +\Edificio A\\\\\ +\Planta baja\\\\\ +\aseo\1\9.46\\2.50\ +\Planta alta\\\\\ +\Trasdosado interior fachada (altura media)\1\43.66\\3.31\ +\Edificio B\\\\\ +\Planta baja\\\\\ +\Trasdosado muro interior\1\12.66\\2.50\ +\Separacion con garaje\1\6.05\\2.50\ +\\1\14.81\\2.50\ +\Planta alta\\\\\ +\Trasdosado muro interior (altura media)\1\20.40\\3.31\| +~M|PT#\PSY010d|7\4\2\|9.24| +\Edificio A\\\\\ +\divisoria baos\1\2.80\\3.30\| +~M|PT#\PSY010e|7\4\3\|32.2| +\Edificio A\\\\\ +\entre dormitorio ppal. y baos\1\4.88\\3.30\ +\entre dormitorio y baos\1\4.88\\3.30\| +~M|PT#\PSY010f|7\4\4\|82.07| +\Edificio A\\\\\ +\pasillo\1\10.63\\3.30\ +\armario1\1\3.60\\3.30\ +\armario2\1\2.40\\3.30\ +\armario3\1\3.20\\3.30\ +\entre dormitorio y sala\1\5.04\\3.30\| +~M|PT#\FDA005|7\4\5\|10.38| +\Pasarela\2\5.19\\1.00\| +~M|PR#\PRF010|7\5\1\|2|| +~M|IL#\ILA020|8\1\1\|5|| +~M|IL#\ILE030|8\1\2\|3|| +~M|IL#\ILS010|8\1\3\|10|| +~M|IL#\ILI001|8\1\4\|1|| +~M|IA#\IAA031|8\2\1\|1|| +~M|IA#\IAA034b|8\2\2\|1|| +~M|IA#\IAA034c|8\2\3\|1|| +~M|IA#\IAA039|8\2\4\|1|| +~M|IA#\IAA100|8\2\5\|21.46|| +~M|IA#\IAA100b|8\2\6\|15| +\Red exterior\1\15.00\\\| +~M|IA#\IAA115|8\2\7\|1|| +~M|IA#\IAA120|8\2\8\|2|| +~M|IA#\IAF070|8\2\9\|42.92| +\\1\21.46\\\ +\\1\21.46\\\| +~M|IA#\IAF090|8\2\10\|2|| +~M|IA#\IAV020|8\2\11\|1|| +~M|IC#\ICQ015|8\3\1\|1|| +~M|IC#\ICO001|8\3\2\|7| +\tubera de extraccion de combustion caldera pellets\1\\\7.00\| +~M|IC#\ICS010|8\3\3\|116.38|| +~M|IC#\ICE040|8\3\4\|4| +\Aseo\1\\\\ +\Pasarela\1\\\\ +\baos\2\\\\| +~M|IC#\ICE040b|8\3\5\|6| +\Cocina\1\\\\ +\Dormitorios\2\\\\ +\Vestbulo - pasillo\1\\\\ +\Biblioteca\1\\\\ +\Sala\1\\\\| +~M|IC#\ICE040c|8\3\6\|3| +\Salon\2\\\\ +\Sala\1\\\\| +~M|IE#\IEP010|8\4\1\|1|| +~M|IE#\IEP030|8\4\2\|1|| +~M|IE#\IEC010|8\4\3\|1|| +~M|IE#\IED010|8\4\4\|14.17|| +~M|IE#\IEI015|8\4\5\|1|| +~M|IF#\IFA010|8\5\1\|1|| +~M|IF#\IFB010|8\5\2\|1|| +~M|IF#\IFC010|8\5\3\|1|| +~M|IF#\IFI010|8\5\4\|1|| +~M|IF#\IFI010b|8\5\5\|1|| +~M|IF#\IFI010c|8\5\6\|1|| +~M|IF#\IFI010d|8\5\7\|1|| +~M|II#\Pa4|8\6\1\|1|| +~M|IS#\ISB010|8\7\1\|3.25| +\Cocinas\1\3.25\\\| +~M|IS#\ISB010b|8\7\2\|6.5| +\Fecales\1\6.50\\\| +~M|IS#\ISD010|8\7\3\|1| +\Edificio A\\\\\ +\Aseo\1\\\\| +~M|IS#\ISD010b|8\7\4\|2| +\Edificio A\\\\\ +\baos\2\\\\| +~M|IS#\ISD010c|8\7\5\|1|| +~M|IS#\ISH010c|8\7\6\|3|| +~M|IS#\ISK010|8\7\7\|1|| +~M|IS#\ISK030|8\7\8\|1|| +~M|IS#\ISV020|8\7\9\|5.22|| +~M|IS#\ICO015|8\7\10\|16| +\Chimenea para estufa de salon\1\4.50\\\ +\Chimenea para estufa de sala\1\4.50\\\ +\Chimenea para estufa de local\1\7.00\\\| +~M|NA#\NAF010|9\1\1\|319.49| +\Edificio A\\\\\ +\Planta baja\\\\\ +\aseo\1\9.46\\2.50\ +\Planta alta\\\\\ +\Trasdosado interior fachada (altura media)\1\43.66\\3.31\ +\Edificio B\\\\\ +\Planta baja\\\\\ +\Trasdosado muro interior\1\12.66\\2.50\ +\\1\6.05\\2.50\ +\\1\14.81\\2.50\ +\Planta alta\\\\\ +\Trasdosado muro interior (altura media)\1\20.40\\3.31\| +~M|NA#\NAP020|9\1\2\|123.51| +\Edificio A\\\\\ +\divisoria baos\1\2.80\\3.30\ +\entre dormitorio ppal. y baos\1\4.88\\3.30\ +\entre dormitorio y baos\1\4.88\\3.30\ +\pasillo\1\10.63\\3.30\ +\armario1\1\3.60\\3.30\ +\armario2\1\2.40\\3.30\ +\armario3\1\3.20\\3.30\ +\entre dormitorio y sala\1\5.04\\3.30\| +~M|NA#\NAL050|9\1\3\|98.51| +\Edificio A\\\\\ +\Planta alta\1\98.51\\\| +~M|NA#\NAT010|9\1\4\|5.7| +\Edificio A\\\\\ +\aseo\1\5.70\\\| +~M|NI#\NIG040|9\2\1\|192.2| +\Soleras interiores\\\\\ +\Edificio B\\\\\ +\Garaje\1\54.19\\\ +\Edificio A\\\\\ +\Instalaciones\1\10.88\\\ +\Aseo e instalaciones\1\10.88\\\ +\Despensa\1\14.85\\\ +\Local y despensa\1\101.40\\\| +~M|QA#\QTZ010|10\1\1\|12.67| +\Cubierta pasarela\1\12.67\\\| +~M|QT#\QTT210|10\2\1\|235.05| +\Edificio A\\\\\ +\Cubierta planta alta\1\129.11\\1.07\ +\Edificio B\\\\\ +\Cubierta salon\1\48.29\\1.07\ +\Cubierta planta alta\1\42.27\\1.07\| +~M|QT#\QTT020|10\2\2\|120.54| +\Edificio A\\\\\ +\Planta baja\1\51.47\\1.07\ +\Edificio B\\\\\ +\Garaje\1\61.19\\1.07\| +~M|QT#\Pa10|10\2\3\|3|| +~M|RA#\RAG012|11\1\1\|142.41| +\Edificio A\\\\\ +\Planta baja\\\\\ +\Aseo\1\10.46\\2.80\ +\Planta alta\\\\\ +\Bao 1\1\10.90\\2.80\ +\Bao 2\1\9.75\\2.80\ +\Edificio B\\\\\ +\Planta baja\\\\\ +\Cocina\1\19.75\\2.80\| +~M|RE#\Pa6|11\2\1\|17| +\Edificio B\\\\\ +\escalera\17\\\\| +~M|RF#\RFP010|11\3\1\|316.97| +\EDIFICIO A\\\\\ +\Alzado este\1\87.75\\\ +\a deducir huecos:\\\\\ +\v10\2\-1.18\\\ +\puerta balconera\1\-1.90\\\ +\p6\1\-2.30\\\ +\p4\1\-2.59\\\ +\v5\1\-1.03\\\ +\p7\1\-5.45\\\ +\Alzado norte\1\39.66\\\ +\Porche\1\9.01\\\ +\a deducir huecos:\1\-0.17\\\ +\v6\1\-1.19\\\ +\v1\1\-1.22\\\ +\v1\1\-1.22\\\ +\Alzado oeste\1\89.33\\\ +\a deducir huecos:\\\\\ +\v11\2\-1.08\\\ +\v10\3\-1.28\\\ +\p5\1\-1.83\\\ +\p4\1\-2.62\\\ +\Alzado sur\1\43.78\\\ +\a deducir huecos\\\\\ +\p5\1\-1.69\\\ +\ventana\1\-0.54\\\ +\Edificio B\\\\\ +\Alzado este\1\33.87\\\ +\Porche\1\9.01\\\ +\Pasarela\2\5.19\\1.00\ +\Alzado norte\1\36.49\1.15\\ +\a deducir huecos\\\\\ +\v6\1\-0.89\\\ +\v1\1\-0.81\\\ +\Alzado oeste\1\33.27\\\ +\a deducir huecos\\\\\ +\v6\1\-1.19\\\ +\v1\1\-1.22\\\ +\Alzado sur\1\-37.95\1.15\\ +\a deducir huecos\\\\\ +\ventana superior\1\-1.19\\\| +~M|RI#\RIP035|11\4\1\|817.17| +\paredes:\\\\\ +\Edificio A\\\\\ +\Planta baja\\\\\ +\local vacio\1\32.32\\2.80\ +\almacen\1\22.59\\2.80\ +\instalaciones\1\13.20\\2.80\ +\almacen\1\9.45\\2.80\ +\almacen\1\16.15\\2.80\ +\Planta alta\\\\\ +\Trasdosado interior fachada (altura media)\1\43.66\\3.31\ +\Edificio B\\\\\ +\Planta baja\\\\\ +\Trasdosado muro interior\1\12.66\\2.50\ +\\1\6.05\\2.50\ +\\1\14.81\\2.50\ +\Planta alta\\\\\ +\Trasdosado muro interior (altura media)\1\20.40\\3.31\ +1\\\\\\ +\Edificio A planta alta\\\\\ +\pasillo\1\10.63\\3.30\ +\armario1\1\3.60\\3.30\ +\armario2\1\2.40\\3.30\ +\armario3\1\3.20\\3.30\ +\entre dormitorio ppal. y baos\1\4.88\\3.30\ +\entre dormitorio y baos\1\4.88\\3.30\ +\entre dormitorio y sala\2\5.04\\3.30\ +\divisoria baos\1\2.80\\3.30\ +1\\\\\\ +\Techos\\\\\ +\Edificio A\\\\\ +\planta baja\\\\\ +\local vacio\1\59.80\\\ +\almacen\1\28.60\\\ +\intalaciones\1\10.90\\\ +\almacen\1\4.55\\\ +\almacen\1\14.95\\\ +1\\\\\\ +2\\\\\\| +~M|RM#\RME020|11\5\1\|12.3| +\Edificio A\\\\\ +\Vigas existentes techo planta baja\2\6.15\1.00\1.00\| +~M|RN#\RNP010|11\6\1\|10| +\Estructura exterior e interior de pasarela\10\\\\| +~M|RP#\RPE010|11\7\1\|306.59| +\Enfoscados exteriores\\\\\ +\EDIFICIO A\\\\\ +\Alzado este\1\87.75\\\ +\a deducir huecos:\\\\\ +\v10\2\-1.18\\\ +\puerta balconera\1\-1.90\\\ +\p6\1\-2.30\\\ +\p4\1\-2.59\\\ +\v5\1\-1.03\\\ +\p7\1\-5.45\\\ +\Alzado norte\1\39.66\\\ +\Porche\1\9.01\\\ +\a deducir huecos:\1\-0.17\\\ +\v6\1\-1.19\\\ +\v1\1\-1.22\\\ +\v1\1\-1.22\\\ +\Alzado oeste\1\89.33\\\ +\a deducir huecos:\\\\\ +\v11\2\-1.08\\\ +\v10\3\-1.28\\\ +\p5\1\-1.83\\\ +\p4\1\-2.62\\\ +\Alzado sur\1\43.78\\\ +\a deducir huecos\\\\\ +\p5\1\-1.69\\\ +\ventana\1\-0.54\\\ +\Edificio B\\\\\ +\Alzado este\1\33.87\\\ +\Porche\1\9.01\\\ +\Alzado norte\1\36.49\1.15\\ +\a deducir huecos\\\\\ +\v6\1\-0.89\\\ +\v1\1\-0.81\\\ +\Alzado oeste\1\33.27\\\ +\a deducir huecos\\\\\ +\v6\1\-1.19\\\ +\v1\1\-1.22\\\ +\Alzado sur\1\-37.95\1.15\\ +\a deducir huecos\\\\\ +\ventana superior\1\-1.19\\\| +~M|RP#\RPE005|11\7\2\|112.75| +\Edificio B\\\\\ +\ampliacion salon\1\6.20\\3.10\ +\garaje\1\30.17\\3.10\| +~M|RP#\RPG011|11\7\3\|112.75| +\Edificio B\\\\\ +\ampliacion salon\1\6.20\\3.10\ +\garaje\1\30.17\\3.10\| +~M|RS#\RSB010|11\8\1\|224.66| +\Edificio A\\\\\ +\insatalaciones\1\10.90\\\ +\almacen\1\4.55\\\ +\almacen\1\14.95\\\ +\aseo\1\5.70\\\ +\Planta alta\1\95.94\\\ +\Pasarela y terraza\1\21.69\\\ +\Edificio B\\\\\ +\Planta baja\1\70.93\\\| +~M|RS#\RSG011|11\8\2\|150.91| +\Pavimento exterior de rodadura\1\66.32\\\ +\garaje\1\54.19\\\ +\Edificio A\\\\\ +\instalaciones\1\10.90\\\ +\almacen1\1\4.55\\\ +\almacen2\1\14.95\\\| +~M|RS#\RSM022|11\8\3\|29.18| +\terraza planta alta pasalera\1\11.95\\\ +\Patio exterior\1\17.23\\\| +~M|RS#\RSY050|11\8\4\|29.18| +\Patio exterior\1\17.23\\\ +\terraza planta alta pasalera\1\11.95\\\| +~M|RS#\RSP011|11\8\5\|78.85| +\Edificio B\\\\\ +\cocina\1\22.80\\\ +\salon\1\42.40\\\ +\patio\1\13.65\\\| +~M|RS#\RSM040|11\8\6\|87.3| +\Edificio A\\\\\ +\pasillo\1\16.40\\\ +\dormitorio\1\17.40\\\ +\dormitorio\1\16.00\\\ +\sala\1\30.70\\\ +\pasarela\1\6.80\\\| +~M|RS#\RSG020|11\8\7\|60.09| +\edificio A\\\\\ +\instalaciones\1\13.20\\\ +\almacen\1\9.25\\\ +\almacen\1\16.08\\\ +\edificio B\\\\\ +\garaje\1\21.56\\\| +~M|RS#\RSM050|11\8\8\|77.76| +\Edificio A\\\\\ +\Pasillo\1\23.66\\\ +\dormitorio\1\16.69\\\ +\dormitorio\1\16.11\\\ +\sala\1\21.30\\\| +~M|RS#\RSP020|11\8\9\|44.59| +\Edificio B cocina y salon\1\44.59\\\| +~M|RS#\RSG010|11\8\10\|17.95| +\Edificio A\\\\\ +\planta baja aseo\1\5.70\\\ +\planta alta bao 1\1\6.35\\\ +\planta alta bao2\1\5.90\\\| +~M|RS#\RSM021|11\8\11\|14| +\Edificio B\\\\\ +\biblioteca\1\14.00\\\| +~M|RT#\RTC015|11\9\1\|36.1| +\Techos\\\\\ +\Edificio A\\\\\ +\planta baja\\\\\ +\aseo\1\5.70\\\ +\instalaciones\1\10.90\\\ +\almacen\1\4.55\\\ +\almacen\1\14.95\\\| +~M|SM#\SMS010|12\1\1\|1| +\Edificio A\\\\\ +\aseo planta baja\1\\\\| +~M|SM#\SMS010b|12\1\2\|1| +\Edificio A\\\\\ +\Bao 1\1\\\\| +~M|SM#\SMS010d|12\1\3\|1| +\Edificio 1\\\\\ +\Bao 2\1\\\\| +~M|SC#\Pa7|12\2\1\|1|| +~M|GT#\GTA010|13\1\1\|125.87| +\Desbroce y limpieza del terreno\1.3\62.50\\\ +\Zapatas aisladas\1.22\16.20\\\ +\Vigas de atado\1.22\11.52\\\ +\Apoyo de forjado sanitario\1.22\8.05\\\ +\Apoyo de forjado sanitario\1.22\0.72\\\ +\Saneamiento en la urbanizacin\1.22\2.49\\\ +\Tierra seleccionada para relleno\-1\2.93\\\| +~M|GR#\GRA010|13\2\1\|1|| +~M|GR#\GRA010b|13\2\2\|2|| +~M|GR#\GRA010c|13\2\3\|1|| +~M|GR#\GRA010d|13\2\4\|1|| +~M|GR#\GRA010e|13\2\5\|1|| +~M|GR#\GRA010f|13\2\6\|1|| +~M|GR#\GRA010g|13\2\7\|1|| +~M|GR#\GRA010h|13\2\8\|1|| +~M|XE#\XEB010|14\1\1\|3| +\B 500 S (Serie fina)\1\\\\ +\B 500 S (Serie media)\1\\\\ +\B 500 S (Serie gruesa)\1\\\\| +~M|XE#\XEB020|14\1\2\|1|| +~M|XE#\XEM010|14\1\3\|1| +\Serie fina\1\\\\| +~M|XE#\XEM020|14\1\4\|1|| +~M|XE#\XEH010|14\1\5\|1| +\Elementos a flexin (HA-25/B/20/IIa)\1\\\\| +~M|XM#\XMP010|14\2\1\|1|| +~M|YC#\YCE030|15\1\1\|0.4| +\\1\0.40\\\| +~M|YC#\YCF050|15\1\2\|67.68|| +~M|YC#\YCI010|15\1\3\|1|| +~M|YC#\YCM070|15\1\4\|3|| +~M|YC#\YCS010|15\1\5\|2|| +~M|YC#\YCS020|15\1\6\|1|| +~M|YC#\YCU010|15\1\7\|1|| +~M|YF#\YFF020|15\2\1\|1|| +~M|YI#\YIC010|15\3\1\|8|| +~M|YI#\YID020b|15\3\2\|1|| +~M|YI#\YIJ010|15\3\3\|1|| +~M|YI#\YIJ010c|15\3\4\|1|| +~M|YI#\YIM010|15\3\5\|12|| +~M|YI#\YIM010b|15\3\6\|4|| +~M|YI#\YIM040|15\3\7\|1|| +~M|YI#\YIO010|15\3\8\|5|| +~M|YI#\YIO020|15\3\9\|2|| +~M|YI#\YIP010|15\3\10\|2|| +~M|YI#\YIP010b|15\3\11\|6|| +~M|YI#\YIP020|15\3\12\|1|| +~M|YI#\YIP030|15\3\13\|6|| +~M|YI#\YIU020|15\3\14\|6|| +~M|YI#\YIU030|15\3\15\|4|| +~M|YI#\YIU040|15\3\16\|2|| +~M|YI#\YIU050|15\3\17\|4|| +~M|YI#\YIV010|15\3\18\|1|| +~M|YI#\YIV020|15\3\19\|1|| +~M|YM#\YMM010|15\4\1\|1|| +~M|YM#\YMM011|15\4\2\|1|| +~M|YM#\YMM020|15\4\3\|1|| +~M|YM#\YMR010|15\4\4\|2|| +~M|YP#\YPC210|15\5\1\|2|| +~M|YS#\YSB050|15\6\1\|75.89|| +~M|YS#\YSV010|15\6\2\|1|| +~M|YS#\YSN010|15\6\3\|45.54|| +~M|YS#\YSS020|15\6\4\|1|| +~M|YS#\YSS030|15\6\5\|1|| +~M|15#\UVT010|16\1\|100| +\Estimacin perimetro de parcela\1\100.00\\\| +~M|15#\Pa8|16\2\|1| +\Cierre de parcela\1\\\\| diff --git a/index.php b/index.php index 390146a..c93c429 100644 --- a/index.php +++ b/index.php @@ -1,3 +1,8 @@ + @@ -5,7 +10,7 @@ Visualizador BC3 Premium - + @@ -15,22 +20,61 @@
+ + + + + + + +
+ + + + + + + - + + + + + \ No newline at end of file diff --git a/jspdf.plugin.autotable.min.js b/jspdf.plugin.autotable.min.js new file mode 100644 index 0000000..1329a29 --- /dev/null +++ b/jspdf.plugin.autotable.min.js @@ -0,0 +1,10 @@ +/*! + * + * jsPDF AutoTable plugin v3.5.29 + * + * Copyright (c) 2023 Simon Bengtsson, https://github.com/simonbengtsson/jsPDF-AutoTable + * Licensed under the MIT License. + * http://opensource.org/licenses/mit-license + * + */ +!function(t,e){if("object"==typeof exports&&"object"==typeof module)module.exports=e(function(){try{return require("jspdf")}catch(t){}}());else if("function"==typeof define&&define.amd)define(["jspdf"],e);else{var n="object"==typeof exports?e(function(){try{return require("jspdf")}catch(t){}}()):e(t.jspdf);for(var o in n)("object"==typeof exports?exports:t)[o]=n[o]}}("undefined"!=typeof globalThis?globalThis:void 0!==this?this:"undefined"!=typeof window?window:"undefined"!=typeof self?self:global,(function(t){return function(){"use strict";var e={662:function(t,e){var n,o=this&&this.__extends||(n=function(t,e){return n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},n(t,e)},function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function o(){this.constructor=t}n(t,e),t.prototype=null===e?Object.create(e):(o.prototype=e.prototype,new o)});Object.defineProperty(e,"__esModule",{value:!0}),e.CellHookData=e.HookData=void 0;var r=function(t,e,n){this.table=e,this.pageNumber=e.pageNumber,this.pageCount=this.pageNumber,this.settings=e.settings,this.cursor=n,this.doc=t.getDocument()};e.HookData=r;var i=function(t){function e(e,n,o,r,i,l){var a=t.call(this,e,n,l)||this;return a.cell=o,a.row=r,a.column=i,a.section=r.section,a}return o(e,t),e}(r);e.CellHookData=i},790:function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var o=n(148),r=n(938),i=n(323),l=n(587),a=n(49),s=n(858);e.default=function(t){t.API.autoTable=function(){for(var t,e=[],n=0;n {}}) instead."),t.API.autoTable.globalDefaults||(t.API.autoTable.globalDefaults={}),t.API.autoTable.globalDefaults.addPageContent=e,this},t.API.autoTableAddPage=function(){return console.error("Use of deprecated function: autoTableAddPage. Use doc.addPage()"),this.addPage(),this}}},938:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t,e,n,o,r){o=o||{};var i=1.15,l=r.internal.scaleFactor,a=r.internal.getFontSize()/l,s="",u=1;if("middle"!==o.valign&&"bottom"!==o.valign&&"center"!==o.halign&&"right"!==o.halign||(u=(s="string"==typeof t?t.split(/\r\n|\r|\n/g):t).length||1),n+=a*(2-i),"middle"===o.valign?n-=u/2*a*i:"bottom"===o.valign&&(n-=u*a*i),"center"===o.halign||"right"===o.halign){var d=a;if("center"===o.halign&&(d*=.5),s&&u>=1){for(var h=0;h0,o=e||0===e;return n&&o?"DF":n?"S":o?"F":null}Object.defineProperty(e,"__esModule",{value:!0}),e.parseSpacing=e.getFillStyle=e.addTableBorder=e.getStringWidth=void 0,e.getStringWidth=function(t,e,n){return n.applyStyles(e,!0),(Array.isArray(t)?t:[t]).map((function(t){return n.getTextWidth(t)})).reduce((function(t,e){return Math.max(t,e)}),0)},e.addTableBorder=function(t,e,o,r){var i=e.settings.tableLineWidth,l=e.settings.tableLineColor;t.applyStyles({lineWidth:i,lineColor:l});var a=n(i,!1);a&&t.rect(o.x,o.y,e.getWidth(t.pageSize().width),r.y-o.y,a)},e.getFillStyle=n,e.parseSpacing=function(t,e){var n,o,r,i;if(t=t||e,Array.isArray(t)){if(t.length>=4)return{top:t[0],right:t[1],bottom:t[2],left:t[3]};if(3===t.length)return{top:t[0],right:t[1],bottom:t[2],left:t[1]};if(2===t.length)return{top:t[0],right:t[1],bottom:t[0],left:t[1]};t=1===t.length?t[0]:e}return"object"==typeof t?("number"==typeof t.vertical&&(t.top=t.vertical,t.bottom=t.vertical),"number"==typeof t.horizontal&&(t.right=t.horizontal,t.left=t.horizontal),{left:null!==(n=t.left)&&void 0!==n?n:e,top:null!==(o=t.top)&&void 0!==o?o:e,right:null!==(r=t.right)&&void 0!==r?r:e,bottom:null!==(i=t.bottom)&&void 0!==i?i:e}):("number"!=typeof t&&(t=e),{top:t,right:t,bottom:t,left:t})}},913:function(t,e){var n,o=this&&this.__extends||(n=function(t,e){return n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])},n(t,e)},function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function o(){this.constructor=t}n(t,e),t.prototype=null===e?Object.create(e):(o.prototype=e.prototype,new o)});Object.defineProperty(e,"__esModule",{value:!0}),e.getTheme=e.defaultStyles=e.HtmlRowInput=e.FONT_ROW_RATIO=void 0,e.FONT_ROW_RATIO=1.15;var r=function(t){function e(e){var n=t.call(this)||this;return n._element=e,n}return o(e,t),e}(Array);e.HtmlRowInput=r,e.defaultStyles=function(t){return{font:"helvetica",fontStyle:"normal",overflow:"linebreak",fillColor:!1,textColor:20,halign:"left",valign:"top",fontSize:10,cellPadding:5/t,lineColor:200,lineWidth:0,cellWidth:"auto",minCellHeight:0,minCellWidth:0}},e.getTheme=function(t){return{striped:{table:{fillColor:255,textColor:80,fontStyle:"normal"},head:{textColor:255,fillColor:[41,128,185],fontStyle:"bold"},body:{},foot:{textColor:255,fillColor:[41,128,185],fontStyle:"bold"},alternateRow:{fillColor:245}},grid:{table:{fillColor:255,textColor:80,fontStyle:"normal",lineWidth:.1},head:{textColor:255,fillColor:[26,188,156],fontStyle:"bold",lineWidth:0},body:{},foot:{textColor:255,fillColor:[26,188,156],fontStyle:"bold",lineWidth:0},alternateRow:{}},plain:{head:{fontStyle:"bold"},foot:{fontStyle:"bold"}}}[t]}},259:function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0}),e.parseCss=void 0;var o=n(200);function r(t,e){var n=i(t,e);if(!n)return null;var o=n.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d*\.?\d*))?\)$/);if(!o||!Array.isArray(o))return null;var r=[parseInt(o[1]),parseInt(o[2]),parseInt(o[3])];return 0===parseInt(o[4])||isNaN(r[0])||isNaN(r[1])||isNaN(r[2])?null:r}function i(t,e){var n=e(t);return"rgba(0, 0, 0, 0)"===n||"transparent"===n||"initial"===n||"inherit"===n?null==t.parentElement?null:i(t.parentElement,e):n}e.parseCss=function(t,e,n,i,l){var a={},s=96/72,u=r(e,(function(t){return l.getComputedStyle(t).backgroundColor}));null!=u&&(a.fillColor=u);var d=r(e,(function(t){return l.getComputedStyle(t).color}));null!=d&&(a.textColor=d);var h=r(e,(function(t){return l.getComputedStyle(t).borderTopColor}));null!=h&&(a.lineColor=h);var c=function(t,e){var n=[t.paddingTop,t.paddingRight,t.paddingBottom,t.paddingLeft],r=96/(72/e),i=(parseInt(t.lineHeight)-parseInt(t.fontSize))/e/2,l=n.map((function(t){return parseInt(t||"0")/r})),a=(0,o.parseSpacing)(l,0);i>a.top&&(a.top=i);i>a.bottom&&(a.bottom=i);return a}(i,n);c&&(a.cellPadding=c);var f=parseInt(i.borderTopWidth||"");(f=f/s/n)&&(a.lineWidth=f);var p=["left","right","center","justify"];-1!==p.indexOf(i.textAlign)&&(a.halign=i.textAlign),-1!==(p=["middle","bottom","top"]).indexOf(i.verticalAlign)&&(a.valign=i.verticalAlign);var g=parseInt(i.fontSize||"");isNaN(g)||(a.fontSize=g/s);var y=function(t){var e="";("bold"===t.fontWeight||"bolder"===t.fontWeight||parseInt(t.fontWeight)>=700)&&(e="bold");"italic"!==t.fontStyle&&"oblique"!==t.fontStyle||(e+="italic");return e}(i);y&&(a.fontStyle=y);var v=(i.fontFamily||"").toLowerCase();return-1!==t.indexOf(v)&&(a.font=v),a}},323:function(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.DocHandler=void 0;var n={},o=function(){function t(t){this.jsPDFDocument=t,this.userStyles={textColor:t.getTextColor?this.jsPDFDocument.getTextColor():0,fontSize:t.internal.getFontSize(),fontStyle:t.internal.getFont().fontStyle,font:t.internal.getFont().fontName,lineWidth:t.getLineWidth?this.jsPDFDocument.getLineWidth():0,lineColor:t.getDrawColor?this.jsPDFDocument.getDrawColor():0}}return t.setDefaults=function(t,e){void 0===e&&(e=null),e?e.__autoTableDocumentDefaults=t:n=t},t.unifyColor=function(t){return Array.isArray(t)?t:"number"==typeof t?[t,t,t]:"string"==typeof t?[t]:null},t.prototype.applyStyles=function(e,n){var o,r,i;void 0===n&&(n=!1),e.fontStyle&&this.jsPDFDocument.setFontStyle&&this.jsPDFDocument.setFontStyle(e.fontStyle);var l=this.jsPDFDocument.internal.getFont(),a=l.fontStyle,s=l.fontName;if(e.font&&(s=e.font),e.fontStyle){a=e.fontStyle;var u=this.getFontList()[s];u&&-1===u.indexOf(a)&&(this.jsPDFDocument.setFontStyle&&this.jsPDFDocument.setFontStyle(u[0]),a=u[0])}if(this.jsPDFDocument.setFont(s,a),e.fontSize&&this.jsPDFDocument.setFontSize(e.fontSize),!n){var d=t.unifyColor(e.fillColor);d&&(o=this.jsPDFDocument).setFillColor.apply(o,d),(d=t.unifyColor(e.textColor))&&(r=this.jsPDFDocument).setTextColor.apply(r,d),(d=t.unifyColor(e.lineColor))&&(i=this.jsPDFDocument).setDrawColor.apply(i,d),"number"==typeof e.lineWidth&&this.jsPDFDocument.setLineWidth(e.lineWidth)}},t.prototype.splitTextToSize=function(t,e,n){return this.jsPDFDocument.splitTextToSize(t,e,n)},t.prototype.rect=function(t,e,n,o,r){return this.jsPDFDocument.rect(t,e,n,o,r)},t.prototype.getLastAutoTable=function(){return this.jsPDFDocument.lastAutoTable||null},t.prototype.getTextWidth=function(t){return this.jsPDFDocument.getTextWidth(t)},t.prototype.getDocument=function(){return this.jsPDFDocument},t.prototype.setPage=function(t){this.jsPDFDocument.setPage(t)},t.prototype.addPage=function(){return this.jsPDFDocument.addPage()},t.prototype.getFontList=function(){return this.jsPDFDocument.getFontList()},t.prototype.getGlobalOptions=function(){return n||{}},t.prototype.getDocumentOptions=function(){return this.jsPDFDocument.__autoTableDocumentDefaults||{}},t.prototype.pageSize=function(){var t=this.jsPDFDocument.internal.pageSize;return null==t.width&&(t={width:t.getWidth(),height:t.getHeight()}),t},t.prototype.scaleFactor=function(){return this.jsPDFDocument.internal.scaleFactor},t.prototype.pageNumber=function(){var t=this.jsPDFDocument.internal.getCurrentPageInfo();return t?t.pageNumber:this.jsPDFDocument.internal.getNumberOfPages()},t}();e.DocHandler=o},148:function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0}),e.parseHtml=void 0;var o=n(259),r=n(913);function i(t,e,n,i,a,s){for(var u=new r.HtmlRowInput(i),d=0;d0&&(a||"none"!==p.display))return u}function l(t){var e=t.cloneNode(!0);return e.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/ +/g," "),e.innerHTML=e.innerHTML.split(/\/).map((function(t){return t.trim()})).join("\n"),e.innerText||e.textContent||""}e.parseHtml=function(t,e,n,o,r){var l,a,s;void 0===o&&(o=!1),void 0===r&&(r=!1),s="string"==typeof e?n.document.querySelector(e):e;var u=Object.keys(t.getFontList()),d=t.scaleFactor(),h=[],c=[],f=[];if(!s)return console.error("Html table could not be found with input: ",e),{head:h,body:c,foot:f};for(var p=0;p0?"_".concat(i):"")};r.push(l)}})),r}(r,i,l);return{columns:u,head:r,body:i,foot:l}}(n,h,d);return{id:e.tableId,content:g,hooks:f,styles:c,settings:p}}},291:function(t,e){function n(t){t.rowHeight?(console.error("Use of deprecated style rowHeight. It is renamed to minCellHeight."),t.minCellHeight||(t.minCellHeight=t.rowHeight)):t.columnWidth&&(console.error("Use of deprecated style columnWidth. It is renamed to cellWidth."),t.cellWidth||(t.cellWidth=t.columnWidth))}Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(t,e,o,r){for(var i=function(e){e&&"object"!=typeof e&&console.error("The options parameter should be of type object, is: "+typeof e),void 0!==e.extendWidth&&(e.tableWidth=e.extendWidth?"auto":"wrap",console.error("Use of deprecated option: extendWidth, use tableWidth instead.")),void 0!==e.margins&&(void 0===e.margin&&(e.margin=e.margins),console.error("Use of deprecated option: margins, use margin instead.")),e.startY&&"number"!=typeof e.startY&&(console.error("Invalid value for startY option",e.startY),delete e.startY),!e.didDrawPage&&(e.afterPageContent||e.beforePageContent||e.afterPageAdd)&&(console.error("The afterPageContent, beforePageContent and afterPageAdd hooks are deprecated. Use didDrawPage instead"),e.didDrawPage=function(n){t.applyStyles(t.userStyles),e.beforePageContent&&e.beforePageContent(n),t.applyStyles(t.userStyles),e.afterPageContent&&e.afterPageContent(n),t.applyStyles(t.userStyles),e.afterPageAdd&&n.pageNumber>1&&n.afterPageAdd(n),t.applyStyles(t.userStyles)}),["createdHeaderCell","drawHeaderRow","drawRow","drawHeaderCell"].forEach((function(t){e[t]&&console.error('The "'.concat(t,'" hook has changed in version 3.0, check the changelog for how to migrate.'))})),[["showFoot","showFooter"],["showHead","showHeader"],["didDrawPage","addPageContent"],["didParseCell","createdCell"],["headStyles","headerStyles"]].forEach((function(t){var n=t[0],o=t[1];e[o]&&(console.error("Use of deprecated option ".concat(o,". Use ").concat(n," instead")),e[n]=e[o])})),[["padding","cellPadding"],["lineHeight","rowHeight"],"fontSize","overflow"].forEach((function(t){var n="string"==typeof t?t:t[0],o="string"==typeof t?t:t[1];void 0!==e[n]&&(void 0===e.styles[o]&&(e.styles[o]=e[n]),console.error("Use of deprecated option: "+n+", use the style "+o+" instead."))}));for(var o=0,r=["styles","bodyStyles","headStyles","footStyles"];o1})).length>0},t.prototype.canEntireRowFit=function(t,e){return this.getMaxCellHeight(e)<=t},t.prototype.getMinimumRowHeight=function(t,e){var n=this;return t.reduce((function(t,r){var i=n.cells[r.index];if(!i)return 0;var l=i.styles.fontSize/e.scaleFactor()*o.FONT_ROW_RATIO,a=i.padding("vertical")+l;return a>t?a:t}),0)},t}();e.Row=a;var s=function(){function t(t,e,n){var o,r;this.contentHeight=0,this.contentWidth=0,this.wrappedWidth=0,this.minReadableWidth=0,this.minWidth=0,this.width=0,this.height=0,this.x=0,this.y=0,this.styles=e,this.section=n,this.raw=t;var i=t;null==t||"object"!=typeof t||Array.isArray(t)?(this.rowSpan=1,this.colSpan=1):(this.rowSpan=t.rowSpan||1,this.colSpan=t.colSpan||1,i=null!==(r=null!==(o=t.content)&&void 0!==o?o:t.title)&&void 0!==r?r:t,t._element&&(this.raw=t._element));var l=null!=i?""+i:"";this.text=l.split(/\r\n|\r|\n/g)}return t.prototype.getTextPos=function(){var t,e;if("top"===this.styles.valign)t=this.y+this.padding("top");else if("bottom"===this.styles.valign)t=this.y+this.height-this.padding("bottom");else{var n=this.height-this.padding("vertical");t=this.y+n/2+this.padding("top")}if("right"===this.styles.halign)e=this.x+this.width-this.padding("right");else if("center"===this.styles.halign){var o=this.width-this.padding("horizontal");e=this.x+o/2+this.padding("left")}else e=this.x+this.padding("left");return{x:e,y:t}},t.prototype.getContentHeight=function(t){var e=(Array.isArray(this.text)?this.text.length:1)*(this.styles.fontSize/t*o.FONT_ROW_RATIO)+this.padding("vertical");return Math.max(e,this.styles.minCellHeight)},t.prototype.padding=function(t){var e=(0,i.parseSpacing)(this.styles.cellPadding,0);return"vertical"===t?e.top+e.bottom:"horizontal"===t?e.left+e.right:e[t]},t}();e.Cell=s;var u=function(){function t(t,e,n){this.wrappedWidth=0,this.minReadableWidth=0,this.minWidth=0,this.width=0,this.dataKey=t,this.raw=e,this.index=n}return t.prototype.getMaxCustomCellWidth=function(t){for(var e=0,n=0,o=t.allRows();n0?n:null}function d(t,e,n,o,r,i,s){var u,d=(0,l.getTheme)(o);"head"===t?u=r.headStyles:"body"===t?u=r.bodyStyles:"foot"===t&&(u=r.footStyles);var h=(0,a.assign)({},d.table,d[t],r.styles,u),c=r.columnStyles[e.dataKey]||r.columnStyles[e.index]||{},f="body"===t?c:{},p="body"===t&&n%2==0?(0,a.assign)({},d.alternateRow,r.alternateRowStyles):{},g=(0,l.defaultStyles)(i),y=(0,a.assign)({},g,h,p,f);return(0,a.assign)(y,s)}e.createTable=function(t,e){var n=new o.DocHandler(t),l=function(t,e){var n=t.content,o=function(t){return t.map((function(t,e){var n,o,i;return i="object"==typeof t&&null!==(o=null!==(n=t.dataKey)&&void 0!==n?n:t.key)&&void 0!==o?o:e,new r.Column(i,t,e)}))}(n.columns);if(0===n.head.length){(i=u(o,"head"))&&n.head.push(i)}if(0===n.foot.length){var i;(i=u(o,"foot"))&&n.foot.push(i)}var l=t.settings.theme,a=t.styles;return{columns:o,head:s("head",n.head,o,a,l,e),body:s("body",n.body,o,a,l,e),foot:s("foot",n.foot,o,a,l,e)}}(e,n.scaleFactor()),a=new r.Table(e,l);return(0,i.calculateWidths)(n,a),n.applyStyles(n.userStyles),a}},49:function(t,e,n){var o=this&&this.__spreadArray||function(t,e,n){if(n||2===arguments.length)for(var o,r=0,i=e.length;rl)return console.error("Will not be able to print row ".concat(e.index," correctly since it's minimum height is larger than page height")),!0;if(!s)return!1;var u=e.hasRowSpan(o.columns);return e.getMaxCellHeight(o.columns)>l?(u&&console.error("The content of row ".concat(e.index," will not be drawn correctly since drawing rows with a height larger than the page height and has cells with rowspans is not supported.")),!0):!u&&"avoid"!==o.settings.rowPageBreak}(t,n,u,e)){var d=function(t,e,n,o){var r={};t.spansMultiplePages=!0,t.height=0;for(var i=0,a=0,u=n.columns;af&&(c.text=m.text.splice(f,m.text.length));var p=o.scaleFactor();m.contentHeight=m.getContentHeight(p),m.contentHeight>=e&&(m.contentHeight=e,c.styles.minCellHeight-=e),m.contentHeight>t.height&&(t.height=m.contentHeight),c.contentHeight=c.getContentHeight(p),c.contentHeight>i&&(i=c.contentHeight),r[d.index]=c}}var g=new l.Row(t.raw,-1,t.section,r,!0);g.height=i;for(var y=0,v=n.columns;yp.pageSize().height)&&(y(p),l.y=r.top);var v=(0,s.assign)({},l);e.startPageNumber=p.pageNumber(),!0===n.horizontalPageBreak?function(t,e,n,o){var r=d.default.calculateAllColumnsCanFitInPage(t,e);r.map((function(r,i){t.applyStyles(t.userStyles),i>0?g(t,e,n,o,r.columns):function(t,e,n,o){var r=e.settings;t.applyStyles(t.userStyles),("firstPage"===r.showHead||"everyPage"===r.showHead)&&e.head.forEach((function(r){return f(t,e,r,n,o)}))}(t,e,o,r.columns),function(t,e,n,o,r){t.applyStyles(t.userStyles),e.body.forEach((function(i,l){var a=l===e.body.length-1;c(t,e,i,a,n,o,r)}))}(t,e,n,o,r.columns),function(t,e,n,o){var r=e.settings;t.applyStyles(t.userStyles),("lastPage"===r.showFoot||"everyPage"===r.showFoot)&&e.foot.forEach((function(r){return f(t,e,r,n,o)}))}(t,e,o,r.columns)}))}(p,e,v,l):(p.applyStyles(p.userStyles),"firstPage"!==n.showHead&&"everyPage"!==n.showHead||e.head.forEach((function(t){return f(p,e,t,l,e.columns)})),p.applyStyles(p.userStyles),e.body.forEach((function(t,n){var o=n===e.body.length-1;c(p,e,t,o,v,l,e.columns)})),p.applyStyles(p.userStyles),"lastPage"!==n.showFoot&&"everyPage"!==n.showFoot||e.foot.forEach((function(t){return f(p,e,t,l,e.columns)}))),(0,i.addTableBorder)(p,e,v,l),e.callEndPageHooks(p,l),e.finalY=l.y,t.lastAutoTable=e,t.previousAutoTable=e,t.autoTable&&(t.autoTable.previous=e),p.applyStyles(p.userStyles)},e.addPage=g},435:function(t,e,n){Object.defineProperty(e,"__esModule",{value:!0});var o=n(200),r=function(t,e){var n=(0,o.parseSpacing)(e.settings.margin,0);return t.pageSize().width-(n.left+n.right)},i=function(t,e,n){void 0===n&&(n={});var o=r(t,e),i=e.settings.horizontalPageBreakRepeat,l=null,a=[],s=[],u=e.columns.length,d=n&&n.start?n.start:0;for(null!=i&&(l=e.columns.find((function(t){return t.dataKey===i||t.index===i})))&&(a.push(l.index),s.push(e.columns[l.index]),o-=l.wrappedWidth);dn(t)}));c.length&&(e=i(c,e,n))}return e}function l(t,e,n,r,i){return t.map((function(t){return function(t,e,n,r,i){var l=1e4*r.scaleFactor();if(e=Math.ceil(e*l)/l,e>=(0,o.getStringWidth)(t,n,r))return t;for(;e<(0,o.getStringWidth)(t+i,n,r)&&!(t.length<=1);)t=t.substring(0,t.length-1);return t.trim()+i}(t,e,n,r,i)}))}e.calculateWidths=function(t,e){!function(t,e){var n=t.scaleFactor(),i=e.settings.horizontalPageBreak,l=r.default.getPageAvailableWidth(t,e);e.allRows().forEach((function(r){for(var a=0,s=e.columns;al?(d.minWidth=l,d.wrappedWidth=l):(d.minWidth=d.contentWidth,d.wrappedWidth=d.contentWidth);else{var p=10/n;d.minWidth=d.styles.minCellWidth||p,d.wrappedWidth=d.contentWidth,d.minWidth>d.wrappedWidth&&(d.wrappedWidth=d.minWidth)}}}})),e.allRows().forEach((function(t){for(var n=0,o=e.columns;n1&&!r.minWidth&&(r.minWidth=i.minWidth),i.colSpan>1&&!r.wrappedWidth&&(r.wrappedWidth=i.minWidth))}}))}(t,e);var n=[],a=0;e.columns.forEach((function(t){var o=t.getMaxCustomCellWidth(e);o?t.width=o:(t.width=t.wrappedWidth,n.push(t)),a+=t.width}));var s=e.getWidth(t.pageSize().width)-a;s&&(s=i(n,s,(function(t){return Math.max(t.minReadableWidth,t.minWidth)}))),s&&(s=i(n,s,(function(t){return t.minWidth}))),s=Math.abs(s),!e.settings.horizontalPageBreak&&s>.1/t.scaleFactor()&&(s=s<1?s:Math.round(s),console.error("Of the table content, ".concat(s," units width could not fit page"))),function(t){for(var e=t.allRows(),n=0;n1&&t.columns[a+1])i+=s.width,delete o.cells[s.index];else if(r){var u=r;delete o.cells[s.index],r=null,u.width=s.width+i}else{if(!(u=o.cells[s.index]))continue;if(l=u.colSpan,i=0,u.colSpan>1){r=u,i+=s.width;continue}u.width=s.width+i}}}(e),function(t,e){for(var n={count:0,height:0},o=0,r=t.allRows();o1&&n.count*n.height0&&n.height>f&&(f=n.height),f>i.height&&(i.height=f)}}n.count--}}(e,t),function(t){for(var e={},n=1,o=t.allRows(),r=0;r1)n--,delete i.cells[s.index];else if(u)u.cell.height+=i.height,n=u.cell.colSpan,delete i.cells[s.index],u.left--,u.left<=1&&delete e[s.index];else{var d=i.cells[s.index];if(!d)continue;if(d.height=i.height,d.rowSpan>1){var h=o.length-r,c=d.rowSpan>h?h:d.rowSpan;e[s.index]={cell:d,left:c,row:i}}}}}(e)},e.resizeColumns=i,e.ellipsize=l},84:function(e){if(void 0===t){var n=new Error("Cannot find module 'undefined'");throw n.code="MODULE_NOT_FOUND",n}e.exports=t}},n={};function o(t){var r=n[t];if(void 0!==r)return r.exports;var i=n[t]={exports:{}};return e[t].call(i.exports,i,i.exports,o),i.exports}var r={};return function(){var t=r;Object.defineProperty(t,"__esModule",{value:!0}),t.Cell=t.Column=t.Row=t.Table=t.CellHookData=t.__drawTable=t.__createTable=t.applyPlugin=void 0;var e=o(790),n=o(587),i=o(49),l=o(858),a=o(287);Object.defineProperty(t,"Table",{enumerable:!0,get:function(){return a.Table}});var s=o(662);Object.defineProperty(t,"CellHookData",{enumerable:!0,get:function(){return s.CellHookData}});var u=o(287);function d(t){(0,e.default)(t)}Object.defineProperty(t,"Cell",{enumerable:!0,get:function(){return u.Cell}}),Object.defineProperty(t,"Column",{enumerable:!0,get:function(){return u.Column}}),Object.defineProperty(t,"Row",{enumerable:!0,get:function(){return u.Row}}),t.applyPlugin=d,t.__createTable=function(t,e){var o=(0,n.parseInput)(t,e);return(0,l.createTable)(t,o)},t.__drawTable=function(t,e){(0,i.drawTable)(t,e)};try{var h=o(84);h.jsPDF&&(h=h.jsPDF),d(h)}catch(t){}t.default=function(t,e){var o=(0,n.parseInput)(t,e),r=(0,l.createTable)(t,o);(0,i.drawTable)(t,r)}}(),r}()})); \ No newline at end of file diff --git a/jspdf.umd.min.js b/jspdf.umd.min.js new file mode 100644 index 0000000..a9781f1 --- /dev/null +++ b/jspdf.umd.min.js @@ -0,0 +1,398 @@ +/** @license + * + * jsPDF - PDF Document creation from JavaScript + * Version 2.5.1 Built on 2022-01-28T15:37:57.789Z + * CommitID 00000000 + * + * Copyright (c) 2010-2021 James Hall , https://github.com/MrRio/jsPDF + * 2015-2021 yWorks GmbH, http://www.yworks.com + * 2015-2021 Lukas Holländer , https://github.com/HackbrettXXX + * 2016-2018 Aras Abbasi + * 2010 Aaron Spike, https://github.com/acspike + * 2012 Willow Systems Corporation, https://github.com/willowsystems + * 2012 Pablo Hess, https://github.com/pablohess + * 2012 Florian Jenett, https://github.com/fjenett + * 2013 Warren Weckesser, https://github.com/warrenweckesser + * 2013 Youssef Beddad, https://github.com/lifof + * 2013 Lee Driscoll, https://github.com/lsdriscoll + * 2013 Stefan Slonevskiy, https://github.com/stefslon + * 2013 Jeremy Morel, https://github.com/jmorel + * 2013 Christoph Hartmann, https://github.com/chris-rock + * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria + * 2014 James Makes, https://github.com/dollaruw + * 2014 Diego Casorran, https://github.com/diegocr + * 2014 Steven Spungin, https://github.com/Flamenco + * 2014 Kenneth Glassey, https://github.com/Gavvers + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Contributor(s): + * siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango, + * kim3er, mfo, alnorth, Flamenco + */ + +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).jspdf={})}(this,(function(t){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var r=function(){return"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this}();function n(){r.console&&"function"==typeof r.console.log&&r.console.log.apply(r.console,arguments)}var i={log:n,warn:function(t){r.console&&("function"==typeof r.console.warn?r.console.warn.apply(r.console,arguments):n.call(null,arguments))},error:function(t){r.console&&("function"==typeof r.console.error?r.console.error.apply(r.console,arguments):n(t))}};function a(t,e,r){var n=new XMLHttpRequest;n.open("GET",t),n.responseType="blob",n.onload=function(){l(n.response,e,r)},n.onerror=function(){i.error("could not download file")},n.send()}function o(t){var e=new XMLHttpRequest;e.open("HEAD",t,!1);try{e.send()}catch(t){}return e.status>=200&&e.status<=299}function s(t){try{t.dispatchEvent(new MouseEvent("click"))}catch(r){var e=document.createEvent("MouseEvents");e.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),t.dispatchEvent(e)}}var c,u,l=r.saveAs||("object"!==("undefined"==typeof window?"undefined":e(window))||window!==r?function(){}:"undefined"!=typeof HTMLAnchorElement&&"download"in HTMLAnchorElement.prototype?function(t,e,n){var i=r.URL||r.webkitURL,c=document.createElement("a");e=e||t.name||"download",c.download=e,c.rel="noopener","string"==typeof t?(c.href=t,c.origin!==location.origin?o(c.href)?a(t,e,n):s(c,c.target="_blank"):s(c)):(c.href=i.createObjectURL(t),setTimeout((function(){i.revokeObjectURL(c.href)}),4e4),setTimeout((function(){s(c)}),0))}:"msSaveOrOpenBlob"in navigator?function(t,r,n){if(r=r||t.name||"download","string"==typeof t)if(o(t))a(t,r,n);else{var c=document.createElement("a");c.href=t,c.target="_blank",setTimeout((function(){s(c)}))}else navigator.msSaveOrOpenBlob(function(t,r){return void 0===r?r={autoBom:!1}:"object"!==e(r)&&(i.warn("Deprecated: Expected third argument to be a object"),r={autoBom:!r}),r.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(t.type)?new Blob([String.fromCharCode(65279),t],{type:t.type}):t}(t,n),r)}:function(t,n,i,o){if((o=o||open("","_blank"))&&(o.document.title=o.document.body.innerText="downloading..."),"string"==typeof t)return a(t,n,i);var s="application/octet-stream"===t.type,c=/constructor/i.test(r.HTMLElement)||r.safari,u=/CriOS\/[\d]+/.test(navigator.userAgent);if((u||s&&c)&&"object"===("undefined"==typeof FileReader?"undefined":e(FileReader))){var l=new FileReader;l.onloadend=function(){var t=l.result;t=u?t:t.replace(/^data:[^;]*;/,"data:attachment/file;"),o?o.location.href=t:location=t,o=null},l.readAsDataURL(t)}else{var h=r.URL||r.webkitURL,f=h.createObjectURL(t);o?o.location=f:location.href=f,o=null,setTimeout((function(){h.revokeObjectURL(f)}),4e4)}}); +/** + * A class to parse color values + * @author Stoyan Stefanov + * {@link http://www.phpied.com/rgb-color-parser-in-javascript/} + * @license Use it if you like it + */function h(t){var e;t=t||"",this.ok=!1,"#"==t.charAt(0)&&(t=t.substr(1,6));t={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dodgerblue:"1e90ff",feldspar:"d19275",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgrey:"d3d3d3",lightgreen:"90ee90",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslateblue:"8470ff",lightslategray:"778899",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"00ff00",limegreen:"32cd32",linen:"faf0e6",magenta:"ff00ff",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370d8",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"d87093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",red:"ff0000",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",violetred:"d02090",wheat:"f5deb3",white:"ffffff",whitesmoke:"f5f5f5",yellow:"ffff00",yellowgreen:"9acd32"}[t=(t=t.replace(/ /g,"")).toLowerCase()]||t;for(var r=[{re:/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,example:["rgb(123, 234, 45)","rgb(255,234,245)"],process:function(t){return[parseInt(t[1]),parseInt(t[2]),parseInt(t[3])]}},{re:/^(\w{2})(\w{2})(\w{2})$/,example:["#00ff00","336699"],process:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/^(\w{1})(\w{1})(\w{1})$/,example:["#fb0","f0f"],process:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}}],n=0;n255?255:this.r,this.g=this.g<0||isNaN(this.g)?0:this.g>255?255:this.g,this.b=this.b<0||isNaN(this.b)?0:this.b>255?255:this.b,this.toRGB=function(){return"rgb("+this.r+", "+this.g+", "+this.b+")"},this.toHex=function(){var t=this.r.toString(16),e=this.g.toString(16),r=this.b.toString(16);return 1==t.length&&(t="0"+t),1==e.length&&(e="0"+e),1==r.length&&(r="0"+r),"#"+t+e+r}} +/** + * @license + * Joseph Myers does not specify a particular license for his work. + * + * Author: Joseph Myers + * Accessed from: http://www.myersdaily.org/joseph/javascript/md5.js + * + * Modified by: Owen Leong + */ +function f(t,e){var r=t[0],n=t[1],i=t[2],a=t[3];r=p(r,n,i,a,e[0],7,-680876936),a=p(a,r,n,i,e[1],12,-389564586),i=p(i,a,r,n,e[2],17,606105819),n=p(n,i,a,r,e[3],22,-1044525330),r=p(r,n,i,a,e[4],7,-176418897),a=p(a,r,n,i,e[5],12,1200080426),i=p(i,a,r,n,e[6],17,-1473231341),n=p(n,i,a,r,e[7],22,-45705983),r=p(r,n,i,a,e[8],7,1770035416),a=p(a,r,n,i,e[9],12,-1958414417),i=p(i,a,r,n,e[10],17,-42063),n=p(n,i,a,r,e[11],22,-1990404162),r=p(r,n,i,a,e[12],7,1804603682),a=p(a,r,n,i,e[13],12,-40341101),i=p(i,a,r,n,e[14],17,-1502002290),r=g(r,n=p(n,i,a,r,e[15],22,1236535329),i,a,e[1],5,-165796510),a=g(a,r,n,i,e[6],9,-1069501632),i=g(i,a,r,n,e[11],14,643717713),n=g(n,i,a,r,e[0],20,-373897302),r=g(r,n,i,a,e[5],5,-701558691),a=g(a,r,n,i,e[10],9,38016083),i=g(i,a,r,n,e[15],14,-660478335),n=g(n,i,a,r,e[4],20,-405537848),r=g(r,n,i,a,e[9],5,568446438),a=g(a,r,n,i,e[14],9,-1019803690),i=g(i,a,r,n,e[3],14,-187363961),n=g(n,i,a,r,e[8],20,1163531501),r=g(r,n,i,a,e[13],5,-1444681467),a=g(a,r,n,i,e[2],9,-51403784),i=g(i,a,r,n,e[7],14,1735328473),r=m(r,n=g(n,i,a,r,e[12],20,-1926607734),i,a,e[5],4,-378558),a=m(a,r,n,i,e[8],11,-2022574463),i=m(i,a,r,n,e[11],16,1839030562),n=m(n,i,a,r,e[14],23,-35309556),r=m(r,n,i,a,e[1],4,-1530992060),a=m(a,r,n,i,e[4],11,1272893353),i=m(i,a,r,n,e[7],16,-155497632),n=m(n,i,a,r,e[10],23,-1094730640),r=m(r,n,i,a,e[13],4,681279174),a=m(a,r,n,i,e[0],11,-358537222),i=m(i,a,r,n,e[3],16,-722521979),n=m(n,i,a,r,e[6],23,76029189),r=m(r,n,i,a,e[9],4,-640364487),a=m(a,r,n,i,e[12],11,-421815835),i=m(i,a,r,n,e[15],16,530742520),r=v(r,n=m(n,i,a,r,e[2],23,-995338651),i,a,e[0],6,-198630844),a=v(a,r,n,i,e[7],10,1126891415),i=v(i,a,r,n,e[14],15,-1416354905),n=v(n,i,a,r,e[5],21,-57434055),r=v(r,n,i,a,e[12],6,1700485571),a=v(a,r,n,i,e[3],10,-1894986606),i=v(i,a,r,n,e[10],15,-1051523),n=v(n,i,a,r,e[1],21,-2054922799),r=v(r,n,i,a,e[8],6,1873313359),a=v(a,r,n,i,e[15],10,-30611744),i=v(i,a,r,n,e[6],15,-1560198380),n=v(n,i,a,r,e[13],21,1309151649),r=v(r,n,i,a,e[4],6,-145523070),a=v(a,r,n,i,e[11],10,-1120210379),i=v(i,a,r,n,e[2],15,718787259),n=v(n,i,a,r,e[9],21,-343485551),t[0]=S(r,t[0]),t[1]=S(n,t[1]),t[2]=S(i,t[2]),t[3]=S(a,t[3])}function d(t,e,r,n,i,a){return e=S(S(e,t),S(n,a)),S(e<>>32-i,r)}function p(t,e,r,n,i,a,o){return d(e&r|~e&n,t,e,i,a,o)}function g(t,e,r,n,i,a,o){return d(e&n|r&~n,t,e,i,a,o)}function m(t,e,r,n,i,a,o){return d(e^r^n,t,e,i,a,o)}function v(t,e,r,n,i,a,o){return d(r^(e|~n),t,e,i,a,o)}function b(t){var e,r=t.length,n=[1732584193,-271733879,-1732584194,271733878];for(e=64;e<=t.length;e+=64)f(n,y(t.substring(e-64,e)));t=t.substring(e-64);var i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(e=0;e>2]|=t.charCodeAt(e)<<(e%4<<3);if(i[e>>2]|=128<<(e%4<<3),e>55)for(f(n,i),e=0;e<16;e++)i[e]=0;return i[14]=8*r,f(n,i),n}function y(t){var e,r=[];for(e=0;e<64;e+=4)r[e>>2]=t.charCodeAt(e)+(t.charCodeAt(e+1)<<8)+(t.charCodeAt(e+2)<<16)+(t.charCodeAt(e+3)<<24);return r}c=r.atob.bind(r),u=r.btoa.bind(r);var w="0123456789abcdef".split("");function N(t){for(var e="",r=0;r<4;r++)e+=w[t>>8*r+4&15]+w[t>>8*r&15];return e}function L(t){return String.fromCharCode((255&t)>>0,(65280&t)>>8,(16711680&t)>>16,(4278190080&t)>>24)}function A(t){return function(t){return t.map(L).join("")}(b(t))}var x="5d41402abc4b2a76b9719d911017c592"!=function(t){for(var e=0;e>16)+(e>>16)+(r>>16)<<16|65535&r}return t+e&4294967295} +/** + * @license + * FPDF is released under a permissive license: there is no usage restriction. + * You may embed it freely in your application (commercial or not), with or + * without modifications. + * + * Reference: http://www.fpdf.org/en/script/script37.php + */function _(t,e){var r,n,i,a;if(t!==r){for(var o=(i=t,a=1+(256/t.length>>0),new Array(a+1).join(i)),s=[],c=0;c<256;c++)s[c]=c;var u=0;for(c=0;c<256;c++){var l=s[c];u=(u+l+o.charCodeAt(c))%256,s[c]=s[u],s[u]=l}r=t,n=s}else s=n;var h=e.length,f=0,d=0,p="";for(c=0;c€/\f©þdSiz";var a=(e+this.padding).substr(0,32),o=(r+this.padding).substr(0,32);this.O=this.processOwnerPassword(a,o),this.P=-(1+(255^i)),this.encryptionKey=A(a+this.O+this.lsbFirstWord(this.P)+this.hexToBytes(n)).substr(0,5),this.U=_(this.encryptionKey,this.padding)}function F(t){if(/[^\u0000-\u00ff]/.test(t))throw new Error("Invalid PDF Name Object: "+t+", Only accept ASCII characters.");for(var e="",r=t.length,n=0;n126)e+="#"+("0"+i.toString(16)).slice(-2);else e+=t[n]}return e}function I(t){if("object"!==e(t))throw new Error("Invalid Context passed to initialize PubSub (jsPDF-module)");var n={};this.subscribe=function(t,e,r){if(r=r||!1,"string"!=typeof t||"function"!=typeof e||"boolean"!=typeof r)throw new Error("Invalid arguments passed to PubSub.subscribe (jsPDF-module)");n.hasOwnProperty(t)||(n[t]={});var i=Math.random().toString(35);return n[t][i]=[e,!!r],i},this.unsubscribe=function(t){for(var e in n)if(n[e][t])return delete n[e][t],0===Object.keys(n[e]).length&&delete n[e],!0;return!1},this.publish=function(e){if(n.hasOwnProperty(e)){var a=Array.prototype.slice.call(arguments,1),o=[];for(var s in n[e]){var c=n[e][s];try{c[0].apply(t,a)}catch(t){r.console&&i.error("jsPDF PubSub Error",t.message,t)}c[1]&&o.push(s)}o.length&&o.forEach(this.unsubscribe)}},this.getTopics=function(){return n}}function C(t){if(!(this instanceof C))return new C(t);var e="opacity,stroke-opacity".split(",");for(var r in t)t.hasOwnProperty(r)&&e.indexOf(r)>=0&&(this[r]=t[r]);this.id="",this.objectNumber=-1}function j(t,e){this.gState=t,this.matrix=e,this.id="",this.objectNumber=-1}function O(t,e,r,n,i){if(!(this instanceof O))return new O(t,e,r,n,i);this.type="axial"===t?2:3,this.coords=e,this.colors=r,j.call(this,n,i)}function B(t,e,r,n,i){if(!(this instanceof B))return new B(t,e,r,n,i);this.boundingBox=t,this.xStep=e,this.yStep=r,this.stream="",this.cloneIndex=0,j.call(this,n,i)}function M(t){var n,a="string"==typeof arguments[0]?arguments[0]:"p",o=arguments[1],s=arguments[2],c=arguments[3],f=[],d=1,p=16,g="S",m=null;"object"===e(t=t||{})&&(a=t.orientation,o=t.unit||o,s=t.format||s,c=t.compress||t.compressPdf||c,null!==(m=t.encryption||null)&&(m.userPassword=m.userPassword||"",m.ownerPassword=m.ownerPassword||"",m.userPermissions=m.userPermissions||[]),d="number"==typeof t.userUnit?Math.abs(t.userUnit):1,void 0!==t.precision&&(n=t.precision),void 0!==t.floatPrecision&&(p=t.floatPrecision),g=t.defaultPathOperation||"S"),f=t.filters||(!0===c?["FlateEncode"]:f),o=o||"mm",a=(""+(a||"P")).toLowerCase();var v=t.putOnlyUsedFonts||!1,b={},y={internal:{},__private__:{}};y.__private__.PubSub=I;var w="1.3",N=y.__private__.getPdfVersion=function(){return w};y.__private__.setPdfVersion=function(t){w=t};var L={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]};y.__private__.getPageFormats=function(){return L};var A=y.__private__.getPageFormat=function(t){return L[t]};s=s||"a4";var x={COMPAT:"compat",ADVANCED:"advanced"},S=x.COMPAT;function _(){this.saveGraphicsState(),ht(new Vt(_t,0,0,-_t,0,Rr()*_t).toString()+" cm"),this.setFontSize(this.getFontSize()/_t),g="n",S=x.ADVANCED}function P(){this.restoreGraphicsState(),g="S",S=x.COMPAT}var j=y.__private__.combineFontStyleAndFontWeight=function(t,e){if("bold"==t&&"normal"==e||"bold"==t&&400==e||"normal"==t&&"italic"==e||"bold"==t&&"italic"==e)throw new Error("Invalid Combination of fontweight and fontstyle");return e&&(t=400==e||"normal"===e?"italic"===t?"italic":"normal":700!=e&&"bold"!==e||"normal"!==t?(700==e?"bold":e)+""+t:"bold"),t};y.advancedAPI=function(t){var e=S===x.COMPAT;return e&&_.call(this),"function"!=typeof t||(t(this),e&&P.call(this)),this},y.compatAPI=function(t){var e=S===x.ADVANCED;return e&&P.call(this),"function"!=typeof t||(t(this),e&&_.call(this)),this},y.isAdvancedAPI=function(){return S===x.ADVANCED};var E,q=function(t){if(S!==x.ADVANCED)throw new Error(t+" is only available in 'advanced' API mode. You need to call advancedAPI() first.")},D=y.roundToPrecision=y.__private__.roundToPrecision=function(t,e){var r=n||e;if(isNaN(t)||isNaN(r))throw new Error("Invalid argument passed to jsPDF.roundToPrecision");return t.toFixed(r).replace(/0+$/,"")};E=y.hpf=y.__private__.hpf="number"==typeof p?function(t){if(isNaN(t))throw new Error("Invalid argument passed to jsPDF.hpf");return D(t,p)}:"smart"===p?function(t){if(isNaN(t))throw new Error("Invalid argument passed to jsPDF.hpf");return D(t,t>-1&&t<1?16:5)}:function(t){if(isNaN(t))throw new Error("Invalid argument passed to jsPDF.hpf");return D(t,16)};var R=y.f2=y.__private__.f2=function(t){if(isNaN(t))throw new Error("Invalid argument passed to jsPDF.f2");return D(t,2)},T=y.__private__.f3=function(t){if(isNaN(t))throw new Error("Invalid argument passed to jsPDF.f3");return D(t,3)},U=y.scale=y.__private__.scale=function(t){if(isNaN(t))throw new Error("Invalid argument passed to jsPDF.scale");return S===x.COMPAT?t*_t:S===x.ADVANCED?t:void 0},z=function(t){return S===x.COMPAT?Rr()-t:S===x.ADVANCED?t:void 0},H=function(t){return U(z(t))};y.__private__.setPrecision=y.setPrecision=function(t){"number"==typeof parseInt(t,10)&&(n=parseInt(t,10))};var W,V="00000000000000000000000000000000",G=y.__private__.getFileId=function(){return V},Y=y.__private__.setFileId=function(t){return V=void 0!==t&&/^[a-fA-F0-9]{32}$/.test(t)?t.toUpperCase():V.split("").map((function(){return"ABCDEF0123456789".charAt(Math.floor(16*Math.random()))})).join(""),null!==m&&(Ye=new k(m.userPermissions,m.userPassword,m.ownerPassword,V)),V};y.setFileId=function(t){return Y(t),this},y.getFileId=function(){return G()};var J=y.__private__.convertDateToPDFDate=function(t){var e=t.getTimezoneOffset(),r=e<0?"+":"-",n=Math.floor(Math.abs(e/60)),i=Math.abs(e%60),a=[r,Q(n),"'",Q(i),"'"].join("");return["D:",t.getFullYear(),Q(t.getMonth()+1),Q(t.getDate()),Q(t.getHours()),Q(t.getMinutes()),Q(t.getSeconds()),a].join("")},X=y.__private__.convertPDFDateToDate=function(t){var e=parseInt(t.substr(2,4),10),r=parseInt(t.substr(6,2),10)-1,n=parseInt(t.substr(8,2),10),i=parseInt(t.substr(10,2),10),a=parseInt(t.substr(12,2),10),o=parseInt(t.substr(14,2),10);return new Date(e,r,n,i,a,o,0)},K=y.__private__.setCreationDate=function(t){var e;if(void 0===t&&(t=new Date),t instanceof Date)e=J(t);else{if(!/^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\+0[0-9]|\+1[0-4]|-0[0-9]|-1[0-1])'(0[0-9]|[1-5][0-9])'?$/.test(t))throw new Error("Invalid argument passed to jsPDF.setCreationDate");e=t}return W=e},Z=y.__private__.getCreationDate=function(t){var e=W;return"jsDate"===t&&(e=X(W)),e};y.setCreationDate=function(t){return K(t),this},y.getCreationDate=function(t){return Z(t)};var $,Q=y.__private__.padd2=function(t){return("0"+parseInt(t)).slice(-2)},tt=y.__private__.padd2Hex=function(t){return("00"+(t=t.toString())).substr(t.length)},et=0,rt=[],nt=[],it=0,at=[],ot=[],st=!1,ct=nt,ut=function(){et=0,it=0,nt=[],rt=[],at=[],Qt=Kt(),te=Kt()};y.__private__.setCustomOutputDestination=function(t){st=!0,ct=t};var lt=function(t){st||(ct=t)};y.__private__.resetCustomOutputDestination=function(){st=!1,ct=nt};var ht=y.__private__.out=function(t){return t=t.toString(),it+=t.length+1,ct.push(t),ct},ft=y.__private__.write=function(t){return ht(1===arguments.length?t.toString():Array.prototype.join.call(arguments," "))},dt=y.__private__.getArrayBuffer=function(t){for(var e=t.length,r=new ArrayBuffer(e),n=new Uint8Array(r);e--;)n[e]=t.charCodeAt(e);return r},pt=[["Helvetica","helvetica","normal","WinAnsiEncoding"],["Helvetica-Bold","helvetica","bold","WinAnsiEncoding"],["Helvetica-Oblique","helvetica","italic","WinAnsiEncoding"],["Helvetica-BoldOblique","helvetica","bolditalic","WinAnsiEncoding"],["Courier","courier","normal","WinAnsiEncoding"],["Courier-Bold","courier","bold","WinAnsiEncoding"],["Courier-Oblique","courier","italic","WinAnsiEncoding"],["Courier-BoldOblique","courier","bolditalic","WinAnsiEncoding"],["Times-Roman","times","normal","WinAnsiEncoding"],["Times-Bold","times","bold","WinAnsiEncoding"],["Times-Italic","times","italic","WinAnsiEncoding"],["Times-BoldItalic","times","bolditalic","WinAnsiEncoding"],["ZapfDingbats","zapfdingbats","normal",null],["Symbol","symbol","normal",null]];y.__private__.getStandardFonts=function(){return pt};var gt=t.fontSize||16;y.__private__.setFontSize=y.setFontSize=function(t){return gt=S===x.ADVANCED?t/_t:t,this};var mt,vt=y.__private__.getFontSize=y.getFontSize=function(){return S===x.COMPAT?gt:gt*_t},bt=t.R2L||!1;y.__private__.setR2L=y.setR2L=function(t){return bt=t,this},y.__private__.getR2L=y.getR2L=function(){return bt};var yt,wt=y.__private__.setZoomMode=function(t){var e=[void 0,null,"fullwidth","fullheight","fullpage","original"];if(/^(?:\d+\.\d*|\d*\.\d+|\d+)%$/.test(t))mt=t;else if(isNaN(t)){if(-1===e.indexOf(t))throw new Error('zoom must be Integer (e.g. 2), a percentage Value (e.g. 300%) or fullwidth, fullheight, fullpage, original. "'+t+'" is not recognized.');mt=t}else mt=parseInt(t,10)};y.__private__.getZoomMode=function(){return mt};var Nt,Lt=y.__private__.setPageMode=function(t){if(-1==[void 0,null,"UseNone","UseOutlines","UseThumbs","FullScreen"].indexOf(t))throw new Error('Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. "'+t+'" is not recognized.');yt=t};y.__private__.getPageMode=function(){return yt};var At=y.__private__.setLayoutMode=function(t){if(-1==[void 0,null,"continuous","single","twoleft","tworight","two"].indexOf(t))throw new Error('Layout mode must be one of continuous, single, twoleft, tworight. "'+t+'" is not recognized.');Nt=t};y.__private__.getLayoutMode=function(){return Nt},y.__private__.setDisplayMode=y.setDisplayMode=function(t,e,r){return wt(t),At(e),Lt(r),this};var xt={title:"",subject:"",author:"",keywords:"",creator:""};y.__private__.getDocumentProperty=function(t){if(-1===Object.keys(xt).indexOf(t))throw new Error("Invalid argument passed to jsPDF.getDocumentProperty");return xt[t]},y.__private__.getDocumentProperties=function(){return xt},y.__private__.setDocumentProperties=y.setProperties=y.setDocumentProperties=function(t){for(var e in xt)xt.hasOwnProperty(e)&&t[e]&&(xt[e]=t[e]);return this},y.__private__.setDocumentProperty=function(t,e){if(-1===Object.keys(xt).indexOf(t))throw new Error("Invalid arguments passed to jsPDF.setDocumentProperty");return xt[t]=e};var St,_t,Pt,kt,Ft,It={},Ct={},jt=[],Ot={},Bt={},Mt={},Et={},qt=null,Dt=0,Rt=[],Tt=new I(y),Ut=t.hotfixes||[],zt={},Ht={},Wt=[],Vt=function t(e,r,n,i,a,o){if(!(this instanceof t))return new t(e,r,n,i,a,o);isNaN(e)&&(e=1),isNaN(r)&&(r=0),isNaN(n)&&(n=0),isNaN(i)&&(i=1),isNaN(a)&&(a=0),isNaN(o)&&(o=0),this._matrix=[e,r,n,i,a,o]};Object.defineProperty(Vt.prototype,"sx",{get:function(){return this._matrix[0]},set:function(t){this._matrix[0]=t}}),Object.defineProperty(Vt.prototype,"shy",{get:function(){return this._matrix[1]},set:function(t){this._matrix[1]=t}}),Object.defineProperty(Vt.prototype,"shx",{get:function(){return this._matrix[2]},set:function(t){this._matrix[2]=t}}),Object.defineProperty(Vt.prototype,"sy",{get:function(){return this._matrix[3]},set:function(t){this._matrix[3]=t}}),Object.defineProperty(Vt.prototype,"tx",{get:function(){return this._matrix[4]},set:function(t){this._matrix[4]=t}}),Object.defineProperty(Vt.prototype,"ty",{get:function(){return this._matrix[5]},set:function(t){this._matrix[5]=t}}),Object.defineProperty(Vt.prototype,"a",{get:function(){return this._matrix[0]},set:function(t){this._matrix[0]=t}}),Object.defineProperty(Vt.prototype,"b",{get:function(){return this._matrix[1]},set:function(t){this._matrix[1]=t}}),Object.defineProperty(Vt.prototype,"c",{get:function(){return this._matrix[2]},set:function(t){this._matrix[2]=t}}),Object.defineProperty(Vt.prototype,"d",{get:function(){return this._matrix[3]},set:function(t){this._matrix[3]=t}}),Object.defineProperty(Vt.prototype,"e",{get:function(){return this._matrix[4]},set:function(t){this._matrix[4]=t}}),Object.defineProperty(Vt.prototype,"f",{get:function(){return this._matrix[5]},set:function(t){this._matrix[5]=t}}),Object.defineProperty(Vt.prototype,"rotation",{get:function(){return Math.atan2(this.shx,this.sx)}}),Object.defineProperty(Vt.prototype,"scaleX",{get:function(){return this.decompose().scale.sx}}),Object.defineProperty(Vt.prototype,"scaleY",{get:function(){return this.decompose().scale.sy}}),Object.defineProperty(Vt.prototype,"isIdentity",{get:function(){return 1===this.sx&&(0===this.shy&&(0===this.shx&&(1===this.sy&&(0===this.tx&&0===this.ty))))}}),Vt.prototype.join=function(t){return[this.sx,this.shy,this.shx,this.sy,this.tx,this.ty].map(E).join(t)},Vt.prototype.multiply=function(t){var e=t.sx*this.sx+t.shy*this.shx,r=t.sx*this.shy+t.shy*this.sy,n=t.shx*this.sx+t.sy*this.shx,i=t.shx*this.shy+t.sy*this.sy,a=t.tx*this.sx+t.ty*this.shx+this.tx,o=t.tx*this.shy+t.ty*this.sy+this.ty;return new Vt(e,r,n,i,a,o)},Vt.prototype.decompose=function(){var t=this.sx,e=this.shy,r=this.shx,n=this.sy,i=this.tx,a=this.ty,o=Math.sqrt(t*t+e*e),s=(t/=o)*r+(e/=o)*n;r-=t*s,n-=e*s;var c=Math.sqrt(r*r+n*n);return s/=c,t*(n/=c)>16&255,i=u>>8&255,a=255&u}if(void 0===i||void 0===o&&n===i&&i===a)if("string"==typeof n)r=n+" "+s[0];else switch(t.precision){case 2:r=R(n/255)+" "+s[0];break;case 3:default:r=T(n/255)+" "+s[0]}else if(void 0===o||"object"===e(o)){if(o&&!isNaN(o.a)&&0===o.a)return r=["1.","1.","1.",s[1]].join(" ");if("string"==typeof n)r=[n,i,a,s[1]].join(" ");else switch(t.precision){case 2:r=[R(n/255),R(i/255),R(a/255),s[1]].join(" ");break;default:case 3:r=[T(n/255),T(i/255),T(a/255),s[1]].join(" ")}}else if("string"==typeof n)r=[n,i,a,o,s[2]].join(" ");else switch(t.precision){case 2:r=[R(n),R(i),R(a),R(o),s[2]].join(" ");break;case 3:default:r=[T(n),T(i),T(a),T(o),s[2]].join(" ")}return r},ne=y.__private__.getFilters=function(){return f},ie=y.__private__.putStream=function(t){var e=(t=t||{}).data||"",r=t.filters||ne(),n=t.alreadyAppliedFilters||[],i=t.addLength1||!1,a=e.length,o=t.objectId,s=function(t){return t};if(null!==m&&void 0===o)throw new Error("ObjectId must be passed to putStream for file encryption");null!==m&&(s=Ye.encryptor(o,0));var c={};!0===r&&(r=["FlateEncode"]);var u=t.additionalKeyValues||[],l=(c=void 0!==M.API.processDataByFilters?M.API.processDataByFilters(e,r):{data:e,reverseChain:[]}).reverseChain+(Array.isArray(n)?n.join(" "):n.toString());if(0!==c.data.length&&(u.push({key:"Length",value:c.data.length}),!0===i&&u.push({key:"Length1",value:a})),0!=l.length)if(l.split("/").length-1==1)u.push({key:"Filter",value:l});else{u.push({key:"Filter",value:"["+l+"]"});for(var h=0;h>"),0!==c.data.length&&(ht("stream"),ht(s(c.data)),ht("endstream"))},ae=y.__private__.putPage=function(t){var e=t.number,r=t.data,n=t.objId,i=t.contentsObjId;Zt(n,!0),ht("<>"),ht("endobj");var a=r.join("\n");return S===x.ADVANCED&&(a+="\nQ"),Zt(i,!0),ie({data:a,filters:ne(),objectId:i}),ht("endobj"),n},oe=y.__private__.putPages=function(){var t,e,r=[];for(t=1;t<=Dt;t++)Rt[t].objId=Kt(),Rt[t].contentsObjId=Kt();for(t=1;t<=Dt;t++)r.push(ae({number:t,data:ot[t],objId:Rt[t].objId,contentsObjId:Rt[t].contentsObjId,mediaBox:Rt[t].mediaBox,cropBox:Rt[t].cropBox,bleedBox:Rt[t].bleedBox,trimBox:Rt[t].trimBox,artBox:Rt[t].artBox,userUnit:Rt[t].userUnit,rootDictionaryObjId:Qt,resourceDictionaryObjId:te}));Zt(Qt,!0),ht("<>"),ht("endobj"),Tt.publish("postPutPages")},se=function(t){Tt.publish("putFont",{font:t,out:ht,newObject:Xt,putStream:ie}),!0!==t.isAlreadyPutted&&(t.objectNumber=Xt(),ht("<<"),ht("/Type /Font"),ht("/BaseFont /"+F(t.postScriptName)),ht("/Subtype /Type1"),"string"==typeof t.encoding&&ht("/Encoding /"+t.encoding),ht("/FirstChar 32"),ht("/LastChar 255"),ht(">>"),ht("endobj"))},ce=function(){for(var t in It)It.hasOwnProperty(t)&&(!1===v||!0===v&&b.hasOwnProperty(t))&&se(It[t])},ue=function(t){t.objectNumber=Xt();var e=[];e.push({key:"Type",value:"/XObject"}),e.push({key:"Subtype",value:"/Form"}),e.push({key:"BBox",value:"["+[E(t.x),E(t.y),E(t.x+t.width),E(t.y+t.height)].join(" ")+"]"}),e.push({key:"Matrix",value:"["+t.matrix.toString()+"]"});var r=t.pages[1].join("\n");ie({data:r,additionalKeyValues:e,objectId:t.objectNumber}),ht("endobj")},le=function(){for(var t in zt)zt.hasOwnProperty(t)&&ue(zt[t])},he=function(t,e){var r,n=[],i=1/(e-1);for(r=0;r<1;r+=i)n.push(r);if(n.push(1),0!=t[0].offset){var a={offset:0,color:t[0].color};t.unshift(a)}if(1!=t[t.length-1].offset){var o={offset:1,color:t[t.length-1].color};t.push(o)}for(var s="",c=0,u=0;ut[c+1].offset;)c++;var l=t[c].offset,h=(r-l)/(t[c+1].offset-l),f=t[c].color,d=t[c+1].color;s+=tt(Math.round((1-h)*f[0]+h*d[0]).toString(16))+tt(Math.round((1-h)*f[1]+h*d[1]).toString(16))+tt(Math.round((1-h)*f[2]+h*d[2]).toString(16))}return s.trim()},fe=function(t,e){e||(e=21);var r=Xt(),n=he(t.colors,e),i=[];i.push({key:"FunctionType",value:"0"}),i.push({key:"Domain",value:"[0.0 1.0]"}),i.push({key:"Size",value:"["+e+"]"}),i.push({key:"BitsPerSample",value:"8"}),i.push({key:"Range",value:"[0.0 1.0 0.0 1.0 0.0 1.0]"}),i.push({key:"Decode",value:"[0.0 1.0 0.0 1.0 0.0 1.0]"}),ie({data:n,additionalKeyValues:i,alreadyAppliedFilters:["/ASCIIHexDecode"],objectId:r}),ht("endobj"),t.objectNumber=Xt(),ht("<< /ShadingType "+t.type),ht("/ColorSpace /DeviceRGB");var a="/Coords ["+E(parseFloat(t.coords[0]))+" "+E(parseFloat(t.coords[1]))+" ";2===t.type?a+=E(parseFloat(t.coords[2]))+" "+E(parseFloat(t.coords[3])):a+=E(parseFloat(t.coords[2]))+" "+E(parseFloat(t.coords[3]))+" "+E(parseFloat(t.coords[4]))+" "+E(parseFloat(t.coords[5])),ht(a+="]"),t.matrix&&ht("/Matrix ["+t.matrix.toString()+"]"),ht("/Function "+r+" 0 R"),ht("/Extend [true true]"),ht(">>"),ht("endobj")},de=function(t,e){var r=Kt(),n=Xt();e.push({resourcesOid:r,objectOid:n}),t.objectNumber=n;var i=[];i.push({key:"Type",value:"/Pattern"}),i.push({key:"PatternType",value:"1"}),i.push({key:"PaintType",value:"1"}),i.push({key:"TilingType",value:"1"}),i.push({key:"BBox",value:"["+t.boundingBox.map(E).join(" ")+"]"}),i.push({key:"XStep",value:E(t.xStep)}),i.push({key:"YStep",value:E(t.yStep)}),i.push({key:"Resources",value:r+" 0 R"}),t.matrix&&i.push({key:"Matrix",value:"["+t.matrix.toString()+"]"}),ie({data:t.stream,additionalKeyValues:i,objectId:t.objectNumber}),ht("endobj")},pe=function(t){var e;for(e in Ot)Ot.hasOwnProperty(e)&&(Ot[e]instanceof O?fe(Ot[e]):Ot[e]instanceof B&&de(Ot[e],t))},ge=function(t){for(var e in t.objectNumber=Xt(),ht("<<"),t)switch(e){case"opacity":ht("/ca "+R(t[e]));break;case"stroke-opacity":ht("/CA "+R(t[e]))}ht(">>"),ht("endobj")},me=function(){var t;for(t in Mt)Mt.hasOwnProperty(t)&&ge(Mt[t])},ve=function(){for(var t in ht("/XObject <<"),zt)zt.hasOwnProperty(t)&&zt[t].objectNumber>=0&&ht("/"+t+" "+zt[t].objectNumber+" 0 R");Tt.publish("putXobjectDict"),ht(">>")},be=function(){Ye.oid=Xt(),ht("<<"),ht("/Filter /Standard"),ht("/V "+Ye.v),ht("/R "+Ye.r),ht("/U <"+Ye.toHexString(Ye.U)+">"),ht("/O <"+Ye.toHexString(Ye.O)+">"),ht("/P "+Ye.P),ht(">>"),ht("endobj")},ye=function(){for(var t in ht("/Font <<"),It)It.hasOwnProperty(t)&&(!1===v||!0===v&&b.hasOwnProperty(t))&&ht("/"+t+" "+It[t].objectNumber+" 0 R");ht(">>")},we=function(){if(Object.keys(Ot).length>0){for(var t in ht("/Shading <<"),Ot)Ot.hasOwnProperty(t)&&Ot[t]instanceof O&&Ot[t].objectNumber>=0&&ht("/"+t+" "+Ot[t].objectNumber+" 0 R");Tt.publish("putShadingPatternDict"),ht(">>")}},Ne=function(t){if(Object.keys(Ot).length>0){for(var e in ht("/Pattern <<"),Ot)Ot.hasOwnProperty(e)&&Ot[e]instanceof y.TilingPattern&&Ot[e].objectNumber>=0&&Ot[e].objectNumber>")}},Le=function(){if(Object.keys(Mt).length>0){var t;for(t in ht("/ExtGState <<"),Mt)Mt.hasOwnProperty(t)&&Mt[t].objectNumber>=0&&ht("/"+t+" "+Mt[t].objectNumber+" 0 R");Tt.publish("putGStateDict"),ht(">>")}},Ae=function(t){Zt(t.resourcesOid,!0),ht("<<"),ht("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"),ye(),we(),Ne(t.objectOid),Le(),ve(),ht(">>"),ht("endobj")},xe=function(){var t=[];ce(),me(),le(),pe(t),Tt.publish("putResources"),t.forEach(Ae),Ae({resourcesOid:te,objectOid:Number.MAX_SAFE_INTEGER}),Tt.publish("postPutResources")},Se=function(){Tt.publish("putAdditionalObjects");for(var t=0;t>8&&(c=!0);t=s.join("")}for(r=t.length;void 0===c&&0!==r;)t.charCodeAt(r-1)>>8&&(c=!0),r--;if(!c)return t;for(s=e.noBOM?[]:[254,255],r=0,n=t.length;r>8)>>8)throw new Error("Character at position "+r+" of string '"+t+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");s.push(l),s.push(u-(l<<8))}return String.fromCharCode.apply(void 0,s)},Ce=y.__private__.pdfEscape=y.pdfEscape=function(t,e){return Ie(t,e).replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},je=y.__private__.beginPage=function(t){ot[++Dt]=[],Rt[Dt]={objId:0,contentsObjId:0,userUnit:Number(d),artBox:null,bleedBox:null,cropBox:null,trimBox:null,mediaBox:{bottomLeftX:0,bottomLeftY:0,topRightX:Number(t[0]),topRightY:Number(t[1])}},Me(Dt),lt(ot[$])},Oe=function(t,e){var r,n,o;switch(a=e||a,"string"==typeof t&&(r=A(t.toLowerCase()),Array.isArray(r)&&(n=r[0],o=r[1])),Array.isArray(t)&&(n=t[0]*_t,o=t[1]*_t),isNaN(n)&&(n=s[0],o=s[1]),(n>14400||o>14400)&&(i.warn("A page in a PDF can not be wider or taller than 14400 userUnit. jsPDF limits the width/height to 14400"),n=Math.min(14400,n),o=Math.min(14400,o)),s=[n,o],a.substr(0,1)){case"l":o>n&&(s=[o,n]);break;case"p":n>o&&(s=[o,n])}je(s),pr(fr),ht(Lr),0!==kr&&ht(kr+" J"),0!==Fr&&ht(Fr+" j"),Tt.publish("addPage",{pageNumber:Dt})},Be=function(t){t>0&&t<=Dt&&(ot.splice(t,1),Rt.splice(t,1),Dt--,$>Dt&&($=Dt),this.setPage($))},Me=function(t){t>0&&t<=Dt&&($=t)},Ee=y.__private__.getNumberOfPages=y.getNumberOfPages=function(){return ot.length-1},qe=function(t,e,r){var n,a=void 0;return r=r||{},t=void 0!==t?t:It[St].fontName,e=void 0!==e?e:It[St].fontStyle,n=t.toLowerCase(),void 0!==Ct[n]&&void 0!==Ct[n][e]?a=Ct[n][e]:void 0!==Ct[t]&&void 0!==Ct[t][e]?a=Ct[t][e]:!1===r.disableWarning&&i.warn("Unable to look up font label for font '"+t+"', '"+e+"'. Refer to getFontList() for available fonts."),a||r.noFallback||null==(a=Ct.times[e])&&(a=Ct.times.normal),a},De=y.__private__.putInfo=function(){var t=Xt(),e=function(t){return t};for(var r in null!==m&&(e=Ye.encryptor(t,0)),ht("<<"),ht("/Producer ("+Ce(e("jsPDF "+M.version))+")"),xt)xt.hasOwnProperty(r)&&xt[r]&&ht("/"+r.substr(0,1).toUpperCase()+r.substr(1)+" ("+Ce(e(xt[r]))+")");ht("/CreationDate ("+Ce(e(W))+")"),ht(">>"),ht("endobj")},Re=y.__private__.putCatalog=function(t){var e=(t=t||{}).rootDictionaryObjId||Qt;switch(Xt(),ht("<<"),ht("/Type /Catalog"),ht("/Pages "+e+" 0 R"),mt||(mt="fullwidth"),mt){case"fullwidth":ht("/OpenAction [3 0 R /FitH null]");break;case"fullheight":ht("/OpenAction [3 0 R /FitV null]");break;case"fullpage":ht("/OpenAction [3 0 R /Fit]");break;case"original":ht("/OpenAction [3 0 R /XYZ null null 1]");break;default:var r=""+mt;"%"===r.substr(r.length-1)&&(mt=parseInt(mt)/100),"number"==typeof mt&&ht("/OpenAction [3 0 R /XYZ null null "+R(mt)+"]")}switch(Nt||(Nt="continuous"),Nt){case"continuous":ht("/PageLayout /OneColumn");break;case"single":ht("/PageLayout /SinglePage");break;case"two":case"twoleft":ht("/PageLayout /TwoColumnLeft");break;case"tworight":ht("/PageLayout /TwoColumnRight")}yt&&ht("/PageMode /"+yt),Tt.publish("putCatalog"),ht(">>"),ht("endobj")},Te=y.__private__.putTrailer=function(){ht("trailer"),ht("<<"),ht("/Size "+(et+1)),ht("/Root "+et+" 0 R"),ht("/Info "+(et-1)+" 0 R"),null!==m&&ht("/Encrypt "+Ye.oid+" 0 R"),ht("/ID [ <"+V+"> <"+V+"> ]"),ht(">>")},Ue=y.__private__.putHeader=function(){ht("%PDF-"+w),ht("%ºß¬à")},ze=y.__private__.putXRef=function(){var t="0000000000";ht("xref"),ht("0 "+(et+1)),ht("0000000000 65535 f ");for(var e=1;e<=et;e++){"function"==typeof rt[e]?ht((t+rt[e]()).slice(-10)+" 00000 n "):void 0!==rt[e]?ht((t+rt[e]).slice(-10)+" 00000 n "):ht("0000000000 00000 n ")}},He=y.__private__.buildDocument=function(){ut(),lt(nt),Tt.publish("buildDocument"),Ue(),oe(),Se(),xe(),null!==m&&be(),De(),Re();var t=it;return ze(),Te(),ht("startxref"),ht(""+t),ht("%%EOF"),lt(ot[$]),nt.join("\n")},We=y.__private__.getBlob=function(t){return new Blob([dt(t)],{type:"application/pdf"})},Ve=y.output=y.__private__.output=Fe((function(t,e){switch("string"==typeof(e=e||{})?e={filename:e}:e.filename=e.filename||"generated.pdf",t){case void 0:return He();case"save":y.save(e.filename);break;case"arraybuffer":return dt(He());case"blob":return We(He());case"bloburi":case"bloburl":if(void 0!==r.URL&&"function"==typeof r.URL.createObjectURL)return r.URL&&r.URL.createObjectURL(We(He()))||void 0;i.warn("bloburl is not supported by your system, because URL.createObjectURL is not supported by your browser.");break;case"datauristring":case"dataurlstring":var n="",a=He();try{n=u(a)}catch(t){n=u(unescape(encodeURIComponent(a)))}return"data:application/pdf;filename="+e.filename+";base64,"+n;case"pdfobjectnewwindow":if("[object Window]"===Object.prototype.toString.call(r)){var o="https://cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js",s=' integrity="sha512-4ze/a9/4jqu+tX9dfOqJYSvyYd5M6qum/3HpCLr+/Jqf0whc37VUbkpNGHR7/8pSnCFw47T1fmIpwBV7UySh3g==" crossorigin="anonymous"';e.pdfObjectUrl&&(o=e.pdfObjectUrl,s="");var c=' -``` - -### Personalización - -- **Estilos**: Modifica las variables CSS en `:root` de `style.css` para adaptar colores -- **Columnas**: Ajusta `grid-template-columns` en `.tree-header` y `.tree-node-row` -- **Endpoint**: Si cambias la ruta de `upload.php`, actualiza el fetch en `app.js` +## Licencia -### Dependencias +GNU Affero General Public License v3.0 (AGPLv3). -- PHP 7.4+ con extensión `mbstring` -- Ninguna dependencia JavaScript externa +--- -## Creado por +## Sobre el Proyecto Original -BC3php es una herramienta creada por [System Arquitectura](https://www.systemarquitectura.com), empresa con sede en Málaga especializada en proyectos de arquitectura industrial, logística, corporativa y residencial. +BC3php fue creado por **System Arquitectura** (https://www.systemarquitectura.com), empresa con sede en Malaga especializada en proyectos de arquitectura industrial, logistica, corporativa y residencial. -Su enfoque combina diseño, tecnología y sostenibilidad desde las fases tempranas del proyecto, con una visión técnica y estratégica orientada a mejorar el rendimiento de las organizaciones y su relación con el entorno. +Esta version ampliada mantiene todos los creditos del autor original y anade funcionalidades avanzadas orientadas al uso profesional diario del Arquitecto Tecnico y Director de Obra. -## Licencia +## 👨‍💻 Autor de la versión mejorada -Este proyecto se distribuye bajo la licencia GNU Affero General Public License v3.0 (AGPLv3). +Jose Manuel Caamaño González | Arquitecto Técnico & BIM Manager. +Digital Product Lead | ConTech & Digital Twin SaaS | BIM, Energy Modeling & Sustainability | Data Analytics (SQL, Power BI) -## Autor +Hecho con código y café desde A Coruña. ☕ -- LinkedIn: https://www.linkedin.com/in/rafaroa/ -- Blog: https://rafarq.com -- Podcast: https://rafarq.com/podcast -- X: https://x.com/rafaelroa -- Instagram: https://www.instagram.com/r4f4r04/ +Jose Manuel Caamaño González | [LinkedIn](https://www.linkedin.com/in/jmcaamanog/) diff --git a/app.js b/app.js index e4c8e33..7278de0 100644 --- a/app.js +++ b/app.js @@ -339,6 +339,8 @@ function renderApp(data) { if (exportDrop) exportDrop.style.display = 'inline-block'; if (cBtn) cBtn.style.display = 'inline-block'; if (dBtn) dBtn.style.display = 'inline-block'; + const pBtn = document.getElementById('planningBtn'); + if (pBtn) pBtn.style.display = 'inline-block'; // Resetear comparador y coeficientes al cargar un nuevo presupuesto compareData = null; @@ -2482,7 +2484,678 @@ const redoBtn = document.getElementById('redoBtn'); if (undoBtn) { undoBtn.addEventListener('click', undo); } -if (redoBtn) { - redoBtn.addEventListener('click', redo); + +// ============================================================ +// MÓDULO PLANNING — DIAGRAMA DE GANTT INTERACTIVO +// ============================================================ + +// Estado Gantt: { taskId: { startWeek, durationWeeks, collapsed } } +let ganttState = {}; +let ganttTasks = []; +let ganttStartDate = new Date(); +let ganttTotalWeeks = 26; +const GANTT_WEEK_PX = 44; // ancho de cada semana en px +let ganttLeftColWidth = 280; // ancho columna tareas en px (redimensionable) +let ganttColDrag = null; // estado drag de la columna + +// Clave localStorage basada en el nombre del fichero cargado +function ganttStorageKey() { + return 'gantt_' + currentFileName.replace(/\s+/g, '_').replace(/[^a-zA-Z0-9_\.]/g, ''); +} + +// Guardar estado en localStorage +function ganttSave() { + try { + localStorage.setItem(ganttStorageKey(), JSON.stringify({ + startDate: ganttStartDate.toISOString(), + totalWeeks: ganttTotalWeeks, + state: ganttState + })); + } catch (e) { /* cuota excedida — ignorar */ } +} + +// Cargar estado desde localStorage +function ganttLoad() { + try { + const raw = localStorage.getItem(ganttStorageKey()); + if (!raw) return false; + const saved = JSON.parse(raw); + if (saved.startDate) ganttStartDate = new Date(saved.startDate); + if (saved.totalWeeks) ganttTotalWeeks = saved.totalWeeks; + if (saved.state) ganttState = saved.state; + return true; + } catch (e) { return false; } +} + +// Extraer tareas hasta nivel 3 desde parsedData +function getGanttTasks() { + const tasks = []; + if (!parsedData) return tasks; + const roots = Array.isArray(parsedData.root_nodes) + ? parsedData.root_nodes + : Object.values(parsedData.root_nodes); + + function addTask(code, depth, parentId) { + if (depth > 3) return; + const concept = parsedData.concepts[code]; + if (!concept) return; + const id = code; + const price = parseFloat(concept.price) || 0; + const children = getConceptDecomposition(concept); + const hasKids = children.length > 0 && depth < 3; + + tasks.push({ + id, + code: concept.code.replace(/#+\s*$/, ''), + summary: concept.summary || concept.code, + depth, + parentId, + price, + hasKids + }); + + if (hasKids) { + children.forEach(child => addTask(child.code, depth + 1, id)); + } + } + + roots.forEach(code => addTask(code, 1, null)); + return tasks; +} + +// Distribución inicial automática (proporcional al coste) +function initGanttStateAuto(tasks, totalWeeks) { + const total = tasks.filter(t => t.depth === 1).reduce((s, t) => s + t.price, 0) || 1; + let cursor = 1; + + tasks.forEach(task => { + if (ganttState[task.id]) return; // ya guardado + if (task.depth === 1) { + const proportion = task.price / total; + const dur = Math.max(1, Math.round(proportion * totalWeeks)); + ganttState[task.id] = { startWeek: cursor, durationWeeks: dur, collapsed: false }; + cursor += dur; + } + }); + + // Subcapítulos: distribuidos dentro del padre + tasks.forEach(task => { + if (ganttState[task.id]) return; + if (task.depth > 1 && task.parentId && ganttState[task.parentId]) { + const parent = ganttState[task.parentId]; + const siblings = tasks.filter(t => t.parentId === task.parentId); + const idx = siblings.indexOf(task); + const dur = Math.max(1, Math.round(parent.durationWeeks / siblings.length)); + const start = parent.startWeek + idx * dur; + ganttState[task.id] = { + startWeek: Math.min(start, parent.startWeek + parent.durationWeeks - 1), + durationWeeks: dur, + collapsed: false + }; + } + }); +} + +// Calcular fecha de una semana relativa a ganttStartDate +function weekToDate(weekNum) { + const d = new Date(ganttStartDate); + d.setDate(d.getDate() + (weekNum - 1) * 7); + return d; +} + +function formatDate(d) { + return d.toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit', year: 'numeric' }); +} + +// Generar cabecera del timeline (meses + semanas) +function buildGanttHeader(totalWeeks) { + const monthRow = document.createElement('div'); + monthRow.className = 'gantt-header-months'; + const weekRow = document.createElement('div'); + weekRow.className = 'gantt-header-weeks'; + + let lastMonth = null; + let monthSpan = 0; + let monthCells = []; + + for (let w = 1; w <= totalWeeks; w++) { + const date = weekToDate(w); + const month = date.toLocaleDateString('es-ES', { month: 'short', year: '2-digit' }); + + const wCell = document.createElement('div'); + wCell.className = 'gantt-week-cell'; + wCell.textContent = 'S' + w; + wCell.title = formatDate(date); + weekRow.appendChild(wCell); + + if (month !== lastMonth) { + if (lastMonth !== null) { + const mCell = document.createElement('div'); + mCell.className = 'gantt-month-cell'; + mCell.textContent = lastMonth; + mCell.style.width = (monthSpan * GANTT_WEEK_PX) + 'px'; + monthCells.push(mCell); + } + lastMonth = month; + monthSpan = 1; + } else { + monthSpan++; + } + } + if (lastMonth) { + const mCell = document.createElement('div'); + mCell.className = 'gantt-month-cell'; + mCell.textContent = lastMonth; + mCell.style.width = (monthSpan * GANTT_WEEK_PX) + 'px'; + monthCells.push(mCell); + } + monthCells.forEach(c => monthRow.appendChild(c)); + + return { monthRow, weekRow }; +} + +// Renderizar el modal completo del Gantt +function renderPlanningModal() { + if (!parsedData) { alert('Carga primero un presupuesto BC3.'); return; } + + ganttTasks = getGanttTasks(); + const loaded = ganttLoad(); + if (!loaded || Object.keys(ganttState).length === 0) { + ganttState = {}; + initGanttStateAuto(ganttTasks, ganttTotalWeeks); + ganttSave(); + } + + const modal = document.getElementById('planningModal'); + if (!modal) return; + modal.style.display = 'flex'; + + rebuildGanttDOM(); +} + +function rebuildGanttDOM() { + const container = document.getElementById('ganttContainer'); + if (!container) return; + container.innerHTML = ''; + + const totalWeeks = ganttTotalWeeks; + + // ---- Cabecera grid ---- + const tableWrap = document.createElement('div'); + tableWrap.className = 'gantt-table-wrap'; + + // Columna izquierda: nombres de tarea (ancho redimensionable) + const leftCol = document.createElement('div'); + leftCol.className = 'gantt-left-col'; + leftCol.style.width = ganttLeftColWidth + 'px'; + leftCol.style.minWidth = ganttLeftColWidth + 'px'; + + const leftHeader = document.createElement('div'); + leftHeader.className = 'gantt-left-header'; + leftHeader.textContent = 'Tarea'; + leftCol.appendChild(leftHeader); + + // Handle de resize en el borde derecho de la columna + const colResizeHandle = document.createElement('div'); + colResizeHandle.className = 'gantt-col-resize-handle'; + colResizeHandle.title = 'Arrastrar para cambiar el ancho de la columna'; + colResizeHandle.addEventListener('mousedown', e => { + e.preventDefault(); + ganttColDrag = { startX: e.clientX, startWidth: ganttLeftColWidth }; + document.addEventListener('mousemove', doGanttColResize); + document.addEventListener('mouseup', stopGanttColResize); + }); + leftCol.appendChild(colResizeHandle); + + // Columna derecha: timeline + const rightCol = document.createElement('div'); + rightCol.className = 'gantt-right-col'; + + const { monthRow, weekRow } = buildGanttHeader(totalWeeks); + const headerWrap = document.createElement('div'); + headerWrap.className = 'gantt-header-wrap'; + headerWrap.appendChild(monthRow); + headerWrap.appendChild(weekRow); + rightCol.appendChild(headerWrap); + + // Filas de tareas + const bodyWrap = document.createElement('div'); + bodyWrap.className = 'gantt-body'; + + ganttTasks.forEach(task => { + const st = ganttState[task.id]; + if (!st) return; + + // Verificar si el padre está colapsado + if (task.parentId && ganttState[task.parentId] && ganttState[task.parentId].collapsed) { + return; + } + + // Fila nombre + const nameRow = document.createElement('div'); + nameRow.className = 'gantt-name-row gantt-depth-' + task.depth; + nameRow.dataset.taskId = task.id; + + if (task.hasKids) { + const toggle = document.createElement('span'); + toggle.className = 'gantt-toggle'; + toggle.textContent = st.collapsed ? '▶' : '▼'; + toggle.addEventListener('click', () => { + ganttState[task.id].collapsed = !ganttState[task.id].collapsed; + ganttSave(); + rebuildGanttDOM(); + }); + nameRow.appendChild(toggle); + } else { + const spacer = document.createElement('span'); + spacer.className = 'gantt-toggle-spacer'; + nameRow.appendChild(spacer); + } + + const nameSpan = document.createElement('span'); + nameSpan.className = 'gantt-task-name'; + nameSpan.title = task.summary + ' — ' + task.price.toLocaleString('es-ES', { minimumFractionDigits: 2 }) + ' €'; + nameSpan.textContent = task.summary; + nameRow.appendChild(nameSpan); + leftCol.appendChild(nameRow); + + // Fila barra + const barRow = document.createElement('div'); + barRow.className = 'gantt-bar-row'; + barRow.style.width = (totalWeeks * GANTT_WEEK_PX) + 'px'; + barRow.dataset.taskId = task.id; + + // Grid de fondo + for (let w = 1; w <= totalWeeks; w++) { + const cell = document.createElement('div'); + cell.className = 'gantt-bg-cell' + (w % 4 === 0 ? ' gantt-bg-month-end' : ''); + barRow.appendChild(cell); + } + + // Barra de la tarea + const bar = document.createElement('div'); + bar.className = 'gantt-bar gantt-bar-depth-' + task.depth; + bar.dataset.taskId = task.id; + positionBar(bar, st.startWeek, st.durationWeeks, totalWeeks); + + const resizeL = document.createElement('div'); + resizeL.className = 'gantt-resize gantt-resize-l'; + resizeL.addEventListener('mousedown', e => startGanttDrag(e, task.id, 'left')); + + const barLabel = document.createElement('span'); + barLabel.className = 'gantt-bar-label'; + barLabel.textContent = task.summary.length > 18 ? task.summary.slice(0, 16) + '…' : task.summary; + + const resizeR = document.createElement('div'); + resizeR.className = 'gantt-resize gantt-resize-r'; + resizeR.addEventListener('mousedown', e => startGanttDrag(e, task.id, 'right')); + + bar.appendChild(resizeL); + bar.appendChild(barLabel); + bar.appendChild(resizeR); + bar.addEventListener('mousedown', e => { + if (e.target === resizeL || e.target === resizeR) return; + startGanttDrag(e, task.id, 'move'); + }); + + barRow.appendChild(bar); + bodyWrap.appendChild(barRow); + }); + + rightCol.appendChild(bodyWrap); + tableWrap.appendChild(leftCol); + tableWrap.appendChild(rightCol); + container.appendChild(tableWrap); + + // Sincronizar scroll vertical entre columnas + const rightScroll = rightCol.querySelector('.gantt-body') || rightCol; + leftCol.addEventListener('scroll', () => { rightCol.scrollTop = leftCol.scrollTop; }); } +function positionBar(barEl, startWeek, durationWeeks, totalWeeks) { + const left = (startWeek - 1) * GANTT_WEEK_PX; + const width = Math.max(GANTT_WEEK_PX * 0.5, durationWeeks * GANTT_WEEK_PX - 2); + barEl.style.left = left + 'px'; + barEl.style.width = width + 'px'; +} + +// ---- Resize columna izquierda ---- +function doGanttColResize(e) { + if (!ganttColDrag) return; + const newWidth = Math.max(140, Math.min(520, ganttColDrag.startWidth + (e.clientX - ganttColDrag.startX))); + ganttLeftColWidth = newWidth; + // Actualizar columna izquierda en vivo sin rerenderizar + const leftColEl = document.querySelector('#ganttContainer .gantt-left-col'); + if (leftColEl) { + leftColEl.style.width = newWidth + 'px'; + leftColEl.style.minWidth = newWidth + 'px'; + } +} +function stopGanttColResize() { + ganttColDrag = null; + document.removeEventListener('mousemove', doGanttColResize); + document.removeEventListener('mouseup', stopGanttColResize); +} + +// ---- Drag & Drop del Gantt ---- +let ganttDrag = null; + +function startGanttDrag(e, taskId, mode) { + e.preventDefault(); + e.stopPropagation(); + const st = ganttState[taskId]; + if (!st) return; + + // Buscar el parentId de esta tarea para aplicar clamping jerárquico + const taskObj = ganttTasks.find(t => t.id === taskId); + const parentId = taskObj ? taskObj.parentId : null; + + ganttDrag = { + taskId, mode, parentId, + startX: e.clientX, + origStart: st.startWeek, + origDur: st.durationWeeks + }; + + document.addEventListener('mousemove', doGanttDrag); + document.addEventListener('mouseup', stopGanttDrag); +} + +function doGanttDrag(e) { + if (!ganttDrag) return; + const { taskId, mode, parentId, startX, origStart, origDur } = ganttDrag; + const dx = e.clientX - startX; + const weeksDelta = Math.round(dx / GANTT_WEEK_PX); + const st = ganttState[taskId]; + const total = ganttTotalWeeks; + + // Límites del padre (si existe) — la tarea hija nunca puede salir de ellos + const pst = parentId && ganttState[parentId]; + const pMin = pst ? pst.startWeek : 1; + const pMax = pst ? pst.startWeek + pst.durationWeeks - 1 : total; + + if (mode === 'move') { + const raw = Math.max(pMin, Math.min(pMax - origDur + 1, origStart + weeksDelta)); + st.startWeek = raw; + st.durationWeeks = Math.min(origDur, pMax - raw + 1); + } else if (mode === 'right') { + const maxDur = pMax - st.startWeek + 1; + st.durationWeeks = Math.max(1, Math.min(maxDur, origDur + weeksDelta)); + } else if (mode === 'left') { + const newStart = Math.max(pMin, Math.min(origStart + origDur - 1, origStart + weeksDelta)); + const newDur = origStart + origDur - newStart; + st.startWeek = newStart; + st.durationWeeks = Math.max(1, Math.min(newDur, pMax - newStart + 1)); + } + + // Actualizar barra en DOM sin rerenderizar todo + const bar = document.querySelector(`.gantt-bar[data-task-id="${taskId}"]`); + if (bar) positionBar(bar, st.startWeek, st.durationWeeks, total); +} + +function stopGanttDrag() { + if (!ganttDrag) return; + ganttSave(); + ganttDrag = null; + document.removeEventListener('mousemove', doGanttDrag); + document.removeEventListener('mouseup', stopGanttDrag); +} + +// ---- Exportar Gantt a Excel (tabla estructurada) ---- +function exportGanttToExcel() { + if (typeof XLSX === 'undefined') { alert('Librería Excel no disponible.'); return; } + const wb = XLSX.utils.book_new(); + + const rows = [['Nivel', 'Código', 'Tarea', 'Semana Inicio', 'Fecha Inicio', 'Semana Fin', 'Fecha Fin', 'Duración (sem.)', 'Duración (días)', 'Importe (€)']]; + + ganttTasks.forEach(task => { + const st = ganttState[task.id]; + if (!st) return; + const startDate = weekToDate(st.startWeek); + const endDate = weekToDate(st.startWeek + st.durationWeeks); + rows.push([ + task.depth, + task.code, + task.summary, + st.startWeek, + formatDate(startDate), + formatDate(endDate), + st.startWeek + st.durationWeeks - 1, + st.durationWeeks, + st.durationWeeks * 7, + parseFloat(task.price.toFixed(2)) + ]); + }); + + const ws = XLSX.utils.aoa_to_sheet(rows); + ws['!cols'] = [ + { wch: 6 }, { wch: 14 }, { wch: 45 }, { wch: 14 }, { wch: 14 }, + { wch: 12 }, { wch: 14 }, { wch: 16 }, { wch: 14 }, { wch: 14 } + ]; + // Cabecera en negrita + const headerRange = XLSX.utils.decode_range(ws['!ref']); + for (let C = headerRange.s.c; C <= headerRange.e.c; C++) { + const cell = ws[XLSX.utils.encode_cell({ r: 0, c: C })]; + if (cell) cell.s = { font: { bold: true } }; + } + + XLSX.utils.book_append_sheet(wb, ws, 'Planning Gantt'); + const baseName = currentFileName.replace(/\.[^/.]+$/, ''); + XLSX.writeFile(wb, baseName + '_planning.xlsx'); +} + +// ---- Exportar Gantt a PDF (A4 landscape, 26 sem/página) ---- +function exportGanttToPdf() { + const JsPDF = (window.jspdf && window.jspdf.jsPDF) ? window.jspdf.jsPDF : window.jsPDF; + if (!JsPDF) { alert('Librería PDF no disponible.'); return; } + + const doc = new JsPDF({ orientation: 'landscape', unit: 'mm', format: 'a4' }); + const WEEKS_PER_PAGE = 26; + const TASK_COL_W = 65; // mm columna tareas + const WEEK_W = (297 - TASK_COL_W - 20) / WEEKS_PER_PAGE; // mm por semana + const ROW_H = 7; // mm por fila + const HEADER_H = 14; // mm cabecera + const MARGIN = 10; // mm márgenes + const PAGE_W = 297; + const PAGE_H = 210; + + const totalPages = Math.ceil(ganttTotalWeeks / WEEKS_PER_PAGE); + + for (let page = 0; page < totalPages; page++) { + if (page > 0) doc.addPage(); + const weekStart = page * WEEKS_PER_PAGE + 1; + const weekEnd = Math.min(weekStart + WEEKS_PER_PAGE - 1, ganttTotalWeeks); + + // Título + doc.setFontSize(10); + doc.setFont('helvetica', 'bold'); + const projectTitle = (parsedData.properties && parsedData.properties.description) || currentFileName.replace(/\.[^/.]+$/, ''); + doc.text('PLANNING: ' + projectTitle, MARGIN, MARGIN - 2); + doc.setFontSize(8); + doc.setFont('helvetica', 'normal'); + doc.text('Semanas ' + weekStart + '–' + weekEnd + ' | Página ' + (page + 1) + ' de ' + totalPages, PAGE_W - MARGIN, MARGIN - 2, { align: 'right' }); + + let y = MARGIN; + + // Cabecera: columna tareas + semanas + doc.setFillColor(80, 20, 40); + doc.rect(MARGIN, y, TASK_COL_W, HEADER_H / 2, 'F'); + doc.setTextColor(255, 255, 255); + doc.setFontSize(7); + doc.setFont('helvetica', 'bold'); + doc.text('Tarea', MARGIN + 2, y + HEADER_H / 2 - 2); + + // Cabecera semanas + for (let w = weekStart; w <= weekEnd; w++) { + const x = MARGIN + TASK_COL_W + (w - weekStart) * WEEK_W; + doc.setFillColor(80, 20, 40); + doc.rect(x, y, WEEK_W, HEADER_H / 2, 'F'); + doc.setTextColor(255, 255, 255); + doc.setFontSize(5.5); + doc.text('S' + w, x + WEEK_W / 2, y + HEADER_H / 2 - 2, { align: 'center' }); + } + // Subrow: meses + let mX = MARGIN + TASK_COL_W; + let mMonth = null; let mStart = mX; + for (let w = weekStart; w <= weekEnd; w++) { + const dt = weekToDate(w); + const mon = dt.toLocaleDateString('es-ES', { month: 'short' }); + if (mon !== mMonth) { + if (mMonth) { + doc.setFillColor(120, 40, 60); + doc.rect(mStart, y + HEADER_H / 2, mX - mStart, HEADER_H / 2, 'F'); + doc.setTextColor(255, 255, 255); + doc.setFontSize(5.5); + doc.text(mMonth, mStart + (mX - mStart) / 2, y + HEADER_H - 2, { align: 'center' }); + } + mMonth = mon; mStart = mX; + } + mX += WEEK_W; + } + if (mMonth) { + doc.setFillColor(120, 40, 60); + doc.rect(mStart, y + HEADER_H / 2, mX - mStart, HEADER_H / 2, 'F'); + doc.setTextColor(255, 255, 255); + doc.setFontSize(5.5); + doc.text(mMonth, mStart + (mX - mStart) / 2, y + HEADER_H - 2, { align: 'center' }); + } + + y += HEADER_H; + + // Filas de tareas + doc.setFont('helvetica', 'normal'); + let rowIdx = 0; + ganttTasks.forEach(task => { + const st = ganttState[task.id]; + if (!st) return; + if (task.parentId && ganttState[task.parentId] && ganttState[task.parentId].collapsed) return; + + const ry = y + rowIdx * ROW_H; + if (ry + ROW_H > PAGE_H - MARGIN) return; + + // Fondo alternado + doc.setFillColor(rowIdx % 2 === 0 ? 252 : 245, rowIdx % 2 === 0 ? 252 : 245, rowIdx % 2 === 0 ? 252 : 245); + doc.rect(MARGIN, ry, PAGE_W - 2 * MARGIN, ROW_H, 'F'); + + // Texto tarea (sangría por nivel) + const indent = (task.depth - 1) * 3; + doc.setFontSize(task.depth === 1 ? 6.5 : 5.5); + doc.setFont('helvetica', task.depth === 1 ? 'bold' : 'normal'); + doc.setTextColor(30, 30, 30); + const label = task.summary.length > 38 ? task.summary.slice(0, 36) + '…' : task.summary; + doc.text(label, MARGIN + 2 + indent, ry + ROW_H - 2); + + // Barra + const barStart = st.startWeek; + const barDur = st.durationWeeks; + const visStart = Math.max(weekStart, barStart); + const visEnd = Math.min(weekEnd, barStart + barDur - 1); + + if (visEnd >= visStart) { + const bx = MARGIN + TASK_COL_W + (visStart - weekStart) * WEEK_W; + const bw = (visEnd - visStart + 1) * WEEK_W - 1; + const bh = ROW_H - 2; + const colors = [[128, 0, 32], [180, 60, 80], [200, 100, 110]]; + const c = colors[Math.min(task.depth - 1, 2)]; + doc.setFillColor(c[0], c[1], c[2]); + doc.roundedRect(bx, ry + 1, bw, bh, 1, 1, 'F'); + } + + // Grid vertical de semanas + doc.setDrawColor(220, 220, 220); + doc.setLineWidth(0.1); + for (let w = weekStart; w <= weekEnd; w++) { + const wx = MARGIN + TASK_COL_W + (w - weekStart) * WEEK_W; + doc.line(wx, ry, wx, ry + ROW_H); + } + + rowIdx++; + }); + + // Borde general + doc.setDrawColor(180, 180, 180); + doc.setLineWidth(0.3); + doc.rect(MARGIN, MARGIN, PAGE_W - 2 * MARGIN, PAGE_H - 2 * MARGIN); + + // Pie de página + doc.setFontSize(6); + doc.setTextColor(150, 150, 150); + doc.text('Generado por BC3 Viewer — ' + new Date().toLocaleDateString('es-ES'), MARGIN, PAGE_H - MARGIN + 4); + } + + const baseName = currentFileName.replace(/\.[^/.]+$/, ''); + doc.save(baseName + '_planning.pdf'); +} + +// ---- Inicializar eventos del modal Planning ---- +const planningBtn = document.getElementById('planningBtn'); +const planningModal = document.getElementById('planningModal'); +const closePlanningBtn = document.getElementById('closePlanningBtn'); +const ganttStartDateInput = document.getElementById('ganttStartDate'); +const ganttWeeksInput = document.getElementById('ganttWeeks'); +const ganttResetBtn = document.getElementById('ganttResetBtn'); +const exportGanttPdfBtn = document.getElementById('exportGanttPdfBtn'); +const exportGanttExcelBtn = document.getElementById('exportGanttExcelBtn'); + +if (planningBtn) { + planningBtn.addEventListener('click', () => { + // Inicializar fecha y semanas antes de renderizar + if (ganttStartDateInput && ganttStartDateInput.value) { + ganttStartDate = new Date(ganttStartDateInput.value); + } else if (ganttStartDateInput) { + ganttStartDate = new Date(); + const iso = ganttStartDate.toISOString().split('T')[0]; + ganttStartDateInput.value = iso; + } + if (ganttWeeksInput && ganttWeeksInput.value) { + ganttTotalWeeks = parseInt(ganttWeeksInput.value) || 26; + } + renderPlanningModal(); + }); +} + +if (closePlanningBtn && planningModal) { + closePlanningBtn.addEventListener('click', () => { + planningModal.style.display = 'none'; + }); +} + +if (planningModal) { + planningModal.addEventListener('click', e => { + if (e.target === planningModal) planningModal.style.display = 'none'; + }); +} + +if (ganttStartDateInput) { + ganttStartDateInput.addEventListener('change', () => { + ganttStartDate = new Date(ganttStartDateInput.value); + if (planningModal && planningModal.style.display !== 'none') rebuildGanttDOM(); + ganttSave(); + }); +} + +if (ganttWeeksInput) { + ganttWeeksInput.addEventListener('change', () => { + ganttTotalWeeks = Math.max(4, Math.min(156, parseInt(ganttWeeksInput.value) || 26)); + ganttWeeksInput.value = ganttTotalWeeks; + if (planningModal && planningModal.style.display !== 'none') rebuildGanttDOM(); + ganttSave(); + }); +} + +if (ganttResetBtn) { + ganttResetBtn.addEventListener('click', () => { + if (!confirm('¿Reiniciar el planning? Se perderá la distribución actual.')) return; + ganttState = {}; + initGanttStateAuto(ganttTasks, ganttTotalWeeks); + ganttSave(); + rebuildGanttDOM(); + }); +} + +if (exportGanttPdfBtn) { + exportGanttPdfBtn.addEventListener('click', exportGanttToPdf); +} +if (exportGanttExcelBtn) { + exportGanttExcelBtn.addEventListener('click', exportGanttToExcel); +} diff --git a/index.php b/index.php index c93c429..4ccc3a7 100644 --- a/index.php +++ b/index.php @@ -21,6 +21,7 @@
+
+ + +