. esportazione lista catalogo direttamente in EXCEL, e scelta dei campi.

This commit is contained in:
Surya Paolo
2025-07-10 00:43:28 +02:00
parent be0d7efca2
commit 2ce8a72286
16 changed files with 375 additions and 70 deletions

View File

@@ -92,7 +92,8 @@
"workbox-precaching": "^7.3.0",
"workbox-routing": "^7.3.0",
"workbox-strategies": "^7.3.0",
"workbox-window": "^7.3.0"
"workbox-window": "^7.3.0",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@eslint/js": "^9.28.0",

View File

@@ -1,11 +1,11 @@
VITE_APP_ID="16"
VITE_APP_URL="https://test.piuchebuono.app"
VITE_MONGODB_HOST="https://test.freeplanet.app:3001"
VITE_LOGO_REG='piuchebuono-logo-full.png'
VITE_APP_URL="https://test.riso.app"
VITE_MONGODB_HOST="https://test.riso.app:3001"
VITE_LOGO_REG='riso-logo-full.png'
VITE_PUBLICKEY_PUSH="BGXRf1TgcqocqD6J7qnRgCG7AvM2lxAoW7peb7UEzB4SxBb6DxGRdJ0UvD9ewnrB9KrSrh0-aDCODXBm7sZ1DDs"
VITE_DEBUG="1"
VITE_VUE_APP_ISTEST=1
DIRECTORY_LOCAL=newfreeplanet
DIRECTORY_SERVER=test.freeplanet_serverside
SERVERDIR_WEBSITE="test.piuchebuono.app"
SERVERDIR_WEBSITE="test.riso.app"
SERVERPW_WEBSITE="pwdadmin@1AOK"

View File

@@ -29,34 +29,33 @@
"postinstall": "quasar prepare"
},
"dependencies": {
"@cubejs-client/core": "^1.2.26",
"@quasar/extras": "^1.16.17",
"@cubejs-client/core": "^1.3.21",
"@quasar/extras": "^1.17.0",
"@quasar/quasar-ui-qcalendar": "^4.1.2",
"@types/jsbarcode": "^3.11.4",
"@types/leaflet": "^1.9.17",
"@vue/compat": "^3.5.13",
"@vue/compiler-sfc": "^3.5.13",
"@types/leaflet": "^1.9.18",
"@vue/compat": "^3.5.16",
"@vue/compiler-sfc": "^3.5.16",
"@vuelidate/core": "^2.0.3",
"@vuelidate/validators": "^2.0.4",
"acorn": "^8.14.1",
"acorn": "^8.15.0",
"animate.css": "^4.1.1",
"apexcharts": "^4.7.0",
"autoprefixer": "^10.4.21",
"axios": "^1.8.4",
"axios": "^1.9.0",
"bcryptjs": "^3.0.2",
"chart.js": "^4.4.8",
"core-js": "^3.41.0",
"chart.js": "^4.4.9",
"core-js": "^3.43.0",
"crypto-browserify": "^3.12.1",
"date-fns": "^4.1.0",
"echarts": "5.6.0",
"eslint-plugin-n": "^17.16.2",
"eslint-plugin-n": "^17.19.0",
"eslint-plugin-quasar": "^1.1.0",
"graphql": "^16.10.0",
"graphql-tag": "^2.12.6",
"gsap": "^3.12.7",
"gsap": "^3.13.0",
"html2pdf.js": "^0.10.3",
"jquery": "^3.7.1",
"js-cookie": "^3.0.5",
"jsbarcode": "^3.11.6",
"jsbarcode": "^3.12.1",
"leaflet": "^1.9.4",
"leaflet-routing-machine": "^3.2.12",
"leaflet.markercluster": "^1.5.3",
@@ -64,30 +63,29 @@
"lodash": "^4.17.21",
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
"pinia": "^3.0.1",
"qrcode-vue3": "^1.7.1",
"pinia": "^3.0.3",
"quasar": "^2.18.1",
"quasar-extras": "^2.0.9",
"register-service-worker": "^1.7.2",
"scrollreveal": "^4.0.9",
"typescript-eslint": "^8.27.0",
"vee-validate": "^4.15.0",
"vue": "^3.5.13",
"typescript-eslint": "^8.34.0",
"vee-validate": "^4.15.1",
"vue": "^3.5.16",
"vue-class-component": "^8.0.0-rc.1",
"vue-country-code": "^1.1.3",
"vue-echarts": "^7.0.3",
"vue-i18n": "^11.1.2",
"vue-i18n": "^11.1.5",
"vue-idb": "^0.2.0",
"vue-image-zoomer": "^2.4.4",
"vue-property-decorator": "^10.0.0-rc.3",
"vue-router": "^4.5.0",
"vue-router": "^4.5.1",
"vue-scroll-reveal": "^2.1.0",
"vue-social-sharing": "^4.0.0-alpha4",
"vue-svgicon": "^4.0.0-alpha.3",
"vue-timeago3": "^2.3.2",
"vue2-dragula": "^2.5.5",
"vue3-pdf-app": "^1.0.3",
"vue3-apexcharts": "^1.8.0",
"vue3-qr-reader": "^1.0.0",
"vuedraggable": "^4.1.0",
"vuex": "^4.1.0",
"vuex-router-sync": "^6.0.0-rc.1",
"workbox-core": "^7.3.0",
@@ -97,41 +95,41 @@
"workbox-window": "^7.3.0"
},
"devDependencies": {
"@eslint/js": "^9.23.0",
"@intlify/unplugin-vue-i18n": "^6.0.5",
"@quasar/app-vite": "^2.1.4",
"@eslint/js": "^9.28.0",
"@intlify/unplugin-vue-i18n": "^6.0.8",
"@quasar/app-vite": "^2.2.1",
"@types/google.maps": "^3.58.1",
"@types/jest": "^29.5.14",
"@types/js-cookie": "^3.0.6",
"@types/node": "^22.13.11",
"@types/node": "^24.0.1",
"@types/nprogress": "^0.2.3",
"@types/vue-tel-input": "^2.1.7",
"@types/vuelidate": "^0.7.22",
"@vue/devtools": "^7.7.2",
"@vue/devtools": "^7.7.6",
"@vue/eslint-config-prettier": "^10.2.0",
"@vue/eslint-config-typescript": "^14.5.0",
"autoprefixer": "^10.4.21",
"eslint": "9",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-vue": "^10.0.0",
"eslint-plugin-vue": "^10.2.0",
"file-loader": "^6.2.0",
"globals": "^16.0.0",
"http-proxy-middleware": "^3.0.3",
"jest": "^29.7.0",
"globals": "^16.2.0",
"http-proxy-middleware": "^3.0.5",
"jest": "^30.0.0",
"json-loader": "^0.5.7",
"nodemon": "^3.1.9",
"npm-check-updates": "^17.1.16",
"parcel": "^2.14.1",
"postcss": "^8.5.3",
"nodemon": "^3.1.10",
"npm-check-updates": "^18.0.1",
"parcel": "^2.15.2",
"postcss": "^8.5.5",
"postcss-loader": "^8.1.1",
"prettier": "3",
"strip-ansi": "=7.1.0",
"ts-jest": "^29.2.6",
"typescript": "5.7.3",
"vite-plugin-checker": "^0.9.1",
"ts-jest": "^29.4.0",
"typescript": "5.8.3",
"vite-plugin-checker": "^0.9.3",
"vue-cli-plugin-element-ui": "^1.1.4",
"vue-eslint-parser": "^10.1.1",
"vue-tsc": "^2.2.8",
"vue-eslint-parser": "^10.1.3",
"vue-tsc": "^2.2.10",
"vueify": "^9.4.1",
"workbox-build": "^7.3.0"
},

View File

@@ -1 +1 @@
TERMINA DI LAVORARE SU gruppomacro.app: (Sovrascrivo!)
TERMINA DI LAVORARE SU riso.app: (Sovrascrivo!)

View File

@@ -15,6 +15,7 @@ export default ({ router }) => {
userAgent,
username: userStore.my?.username,
userId: userStore.my?._id,
referrer: document?.referrer || '',
};
// Invia il tracciamento al backend

View File

View File

@@ -0,0 +1,70 @@
import {
PropType,
computed,
defineComponent,
onMounted,
ref,
watch,
reactive,
} from 'vue';
import * as XLSX from 'xlsx';
export default defineComponent({
name: 'CCsvToXls',
emits: [],
components: {},
props: {},
setup(props, { emit }) {
const xlsFile = ref<string | null>(null);
const selectFile = () => {
const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
fileInput?.click();
};
const onFileChange = (event: Event) => {
const fileInput = event.target as HTMLInputElement;
const file = fileInput?.files ? fileInput.files[0] : null;
if (file && file.type === 'text/csv') {
convertCSVToXLS(file);
} else {
alert('Seleziona un file CSV valido!');
}
};
const convertCSVToXLS = (file: File) => {
const reader = new FileReader();
reader.onload = (e: ProgressEvent<FileReader>) => {
const csvData = e.target?.result as string;
// Usa SheetJS per leggere il CSV
const worksheet = XLSX.utils.csv_to_sheet(csvData);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
// Converte in file Excel (XLS)
const xlsBlob = XLSX.write(workbook, {
bookType: 'xls', // Specifica il formato 'xls'
type: 'blob',
});
// Crea un URL per il file XLS generato
xlsFile.value = URL.createObjectURL(xlsBlob);
};
reader.readAsText(file);
};
function mounted() {}
onMounted(mounted);
return {
onFileChange,
selectFile,
xlsFile,
};
},
});

View File

@@ -0,0 +1,24 @@
<template>
<div>
<q-btn label="Carica CSV" @click="selectFile" color="primary" />
<input
type="file"
ref="csvFile"
accept=".csv"
@change="onFileChange"
style="display: none"
/>
<q-btn
v-if="xlsFile"
:href="xlsFile"
download="converted-file.xls"
label="Scarica XLS"
color="secondary"
/>
</div>
</template>
<script lang="ts" src="./CCsvToXls.ts"></script>
<style lang="scss" scoped>
@import './CCsvToXls.scss';
</style>

View File

@@ -0,0 +1 @@
export { default as CCsvToXls } from './CCsvToXls.vue'

View File

@@ -186,8 +186,6 @@
side
v-if="visu === costanti.USER_CIRCUITS && tools.isUserOk()"
>
fidoConcessoUtente: {{ fidoConcessoUtente }}
myuser: {{ myuser }}
<q-item-label>
<q-btn
rounded

View File

@@ -33,6 +33,8 @@ import { CViewTable } from '../CViewTable';
import { CLabel } from '../CLabel';
import { useI18n } from 'vue-i18n';
import * as XLSX from 'xlsx';
export default defineComponent({
name: 'CProductTable',
emits: ['update:lista_prodotti', 'update:optcatalogo', 'rigenera', 'addtolist'],
@@ -80,6 +82,11 @@ export default defineComponent({
required: false,
default: () => ({}),
},
title: {
type: String,
required: false,
default: 'Lista',
},
},
setup(props, { emit }) {
// Copia locale della lista_prodotti per manipolazione interna
@@ -93,6 +100,8 @@ export default defineComponent({
const searchText = ref('');
const fabexp = ref('');
const arrordersCart = ref(<IOrderCart[]>[]);
const globalStore = useGlobalStore();
@@ -118,6 +127,9 @@ export default defineComponent({
const addstr = ref('');
const showDialogExport = ref(false);
const selectedExportColumns = ref([]);
const optionscatalogo = ref(<any>{ maxlength: 0 });
function handleUpdate(newList) {
@@ -320,6 +332,7 @@ export default defineComponent({
field: 'validato',
align: 'left',
style: '',
noexp: true,
visu: costanti.VISUCAMPI.PER_EDITORE,
},
{
@@ -328,6 +341,7 @@ export default defineComponent({
field: 'scraped',
align: 'left',
style: '',
noexp: true,
visu: costanti.VISUCAMPI.PER_EDITORE,
},
{
@@ -336,6 +350,7 @@ export default defineComponent({
field: 'scraped_error',
align: 'left',
style: '',
noexp: true,
visu: costanti.VISUCAMPI.PER_EDITORE,
},
{
@@ -497,6 +512,10 @@ export default defineComponent({
);
});
const allColumnsToExported = computed(() => {
return allColumnsComputed.value.filter((col) => !col.noexp);
});
async function mounted() {
//myorder = ProductStore.createMyOrder()
// ProductStore.initproduct(myorder);
@@ -532,6 +551,7 @@ export default defineComponent({
};
const savedColumns = tools.getCookie(addstr.value + 'selColCat_2');
selectedExportColumns.value = tools.getCookie(addstr.value + 'Exp_Columns');
if (savedColumns) {
selectedColumns.value = savedColumns;
}
@@ -673,11 +693,11 @@ export default defineComponent({
case 'prezzo':
// return element.price ? '€ ' + element.price.toFixed(2) : '';
const add = colexport ? '' : '&nbsp;'
const add = colexport ? '' : '&nbsp;';
return '€' + add + element.arrvariazioni?.[0]?.price?.toFixed(2);
case 'prezzo_sconto':
const add2 = colexport ? '' : '&nbsp;'
const add2 = colexport ? '' : '&nbsp;';
// return element.sale_price ? '€ ' + element.sale_price.toFixed(2) : '';
return '€' + add2 + element.arrvariazioni?.[0]?.sale_price?.toFixed(2);
@@ -982,6 +1002,10 @@ export default defineComponent({
);
};
const saveSelectedColumnsExport = (column: string[]) => {
tools.setCookie(addstr.value + 'Exp_Columns', JSON.stringify(column));
};
// 9. Watcher per salvare automaticamente le preferenze quando cambiano
watch(
() => selectedColumns.value,
@@ -1190,26 +1214,31 @@ export default defineComponent({
}
}
function exportToCSV() {
function exportToCSV(
title: string = 'lista_',
columns: any[],
separatore: string = '\t'
) {
saveSelectedColumnsExport(columns);
const csvContent = [
selectedColumns.value
.filter((col) => !allColumns.value.find((c) => c.name === col)?.noexp)
columns
.filter((col) => !columns.find((c) => c.name === col)?.noexp)
.map((col) => getColumnLabelByName(col))
.join('|'),
.join(separatore),
...internalProducts.value.map((product: any) => {
return selectedColumns.value
.filter((col) => !allColumns.value.find((c) => c.name === col)?.noexp)
return columns
.filter((col) => !columns.find((c) => c.name === col)?.noexp)
.map((col: string) => {
const field = { field: col };
return field.field === 'pos'
? internalProducts.value.indexOf(product) + 1
: getFieldValue(product, field, true);
})
.join('|');
.join(separatore);
}),
].join('\r\n');
const filename = 'prodotti_' + new Date().toISOString().slice(0, 10) + '.csv';
const filename = title + new Date().toISOString().slice(0, 10) + '.csv';
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
const url = URL.createObjectURL(blob);
@@ -1223,6 +1252,60 @@ export default defineComponent({
document.body.removeChild(link);
}
function exportToXLSAfterCSV(
title: string = 'lista',
columns: any[],
separatore: string = '\t'
) {
saveSelectedColumnsExport(columns);
const csvContent = [
columns
.filter((col) => !columns.find((c) => c.name === col)?.noexp)
.map((col) => getColumnLabelByName(col))
.join(separatore),
...internalProducts.value.map((product: any) => {
return columns
.filter((col) => !columns.find((c) => c.name === col)?.noexp)
.map((col: string) => {
const field = { field: col };
return field.field === 'pos'
? internalProducts.value.indexOf(product) + 1
: getFieldValue(product, field, true);
})
.join(separatore);
}),
].join('\r\n');
// Creazione del file XLS dopo il CSV
exportToXLS(csvContent, title);
}
function exportToXLS(csvContent: string, title: string) {
// Usa SheetJS per creare il file XLS a partire dal CSV
const worksheet = XLSX.utils.aoa_to_sheet(
csvContent.split('\r\n').map((line) => line.split('\t'))
);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
// Genera il file XLS
const xlsData = XLSX.write(workbook, { bookType: 'xls', type: 'array' });
// Crea il Blob correttamente con il tipo MIME
const xlsBlob = new Blob([xlsData], { type: 'application/vnd.ms-excel' });
// Crea un URL per il file XLS
const xlsFilename = `${title}${new Date().toISOString().slice(0, 10)}.xls`;
const xlsUrl = URL.createObjectURL(xlsBlob);
// Crea un link per scaricare il file
const link = document.createElement('a');
link.href = xlsUrl;
link.download = xlsFilename;
link.click();
}
function isSortable(field: string): boolean {
return (
allColumns && !allColumns.value.find((col) => col.name === field)?.notsortable
@@ -1361,6 +1444,7 @@ export default defineComponent({
getFieldClick,
handleUpdate,
exportToCSV,
exportToXLSAfterCSV,
isSortable,
getImageByElement,
isVisibleEditBtn,
@@ -1373,6 +1457,10 @@ export default defineComponent({
searchProducts,
searchText,
isElementVisible,
fabexp,
showDialogExport,
selectedExportColumns,
allColumnsToExported,
};
},
});

View File

@@ -15,12 +15,11 @@
placeholder="Cerca titolo se presente in lista"
class="col-12 col-md-6"
:style="{ 'min-width': '300px' }"
>
</q-input>
<div
v-if="searchText"
class="row justify-center q-mx-auto q-pa-sm text-caption text-red-7 "
class="row justify-center q-mx-auto q-pa-sm text-caption text-red-7"
>
Lista filtrata con il termine "{{ searchText }}"
</div>
@@ -45,14 +44,81 @@
<q-icon name="settings" />
</template>
</q-select>
<q-dialog
v-model="showDialogExport"
>
<q-card style="min-width: 400px">
<q-card-section>
<div class="text-h6">Esporta {{ title }}</div>
</q-card-section>
<q-card-section class="q-pt-none">
<q-markup-table
separator="cell"
flat
bordered
>
<thead>
<tr>
<th
class="text-left"
style="width: 30px"
>
Sel
</th>
<th class="text-left">Colonna</th>
</tr>
</thead>
<tbody>
<tr
v-for="(col, idx) in allColumnsToExported"
:key="idx"
>
<td class="text-left">
<q-checkbox
v-model="selectedExportColumns"
:val="col.name"
/>
</td>
<td class="text-left">{{ col.label }}</td>
</tr>
</tbody>
</q-markup-table>
</q-card-section>
<q-card-actions
align="right"
class="text-primary"
>
<q-btn
flat
label="Annulla"
v-close-popup
/>
<q-btn
@click="exportToXLSAfterCSV(title, selectedExportColumns)"
color="primary"
icon="fas fa-file-excel"
label="Esporta in Excel"
flat
v-close-popup
/>
<q-btn
@click="exportToCSV(title, selectedExportColumns)"
color="primary"
icon="fas fa-file-csv"
label="Esporta in CSV"
flat
v-close-popup
/>
</q-card-actions>
</q-card>
</q-dialog>
<q-btn
class="q-ml-md float-right"
flat
outline
color="primary"
color="positive"
icon="archive"
label="Esporta Lista"
@click="exportToCSV"
label="Esporta"
flat
dense
@click="showDialogExport = true"
/>
</div>
</div>
@@ -149,7 +215,7 @@
/>
</span>
</td>
<td v-else-if="field.name === 'addtocart' && isColumnVisible('addtocart') ">
<td v-else-if="field.name === 'addtocart' && isColumnVisible('addtocart')">
<q-btn
icon-right="fas fa-cart-plus"
color="positive"
@@ -183,7 +249,8 @@
<td
v-else-if="
field.name === 'addtolist' &&
isColumnVisible('addtolist') && isElementVisible('addtolist', element)
isColumnVisible('addtolist') &&
isElementVisible('addtolist', element)
"
>
<q-btn

View File

@@ -7761,6 +7761,7 @@ export const tools = {
if (userStore.my.profile.manage_mygroups) {
const ris = userStore.my.profile.manage_mygroups.find((grp: IMyGroup) => {
if (grp.groupname === groupname) {
return true;
}
});

View File

@@ -252,6 +252,7 @@
:idcatalog="myCatalog._id"
table="products"
@rigenera="generaListaLibri()"
:title="getTitoloCatalogo()"
/>
</q-tab-panel>
<q-tab-panel
@@ -1860,6 +1861,7 @@
:optcatalogo="optcatalogo"
table="products"
@rigenera="generaListaLibri()"
:title="getTitoloCatalogo()"
@addtolist="(elem) => addProductToList(elem, shared_consts.WHERE_INSERT.ONTOP)"
/>
</q-tab-panel>

View File

@@ -48,6 +48,7 @@
table="catalogs"
:optcatalogo="optcatalogo"
:idcatalog="idPage"
:title="getTitoloRaccolta()"
/>
</q-tab-panel>

View File

@@ -4092,6 +4092,11 @@ acorn@^8.15.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816"
integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
adler-32@~1.3.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.3.1.tgz#1dbf0b36dda0012189a32b3679061932df1821e2"
integrity sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==
ajv-keywords@^3.5.2:
version "3.5.2"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
@@ -4877,6 +4882,14 @@ canvg@^3.0.6:
stackblur-canvas "^2.0.0"
svg-pathdata "^6.0.3"
cfb@~1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.2.2.tgz#94e687628c700e5155436dac05f74e08df23bc44"
integrity sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==
dependencies:
adler-32 "~1.3.0"
crc-32 "~1.2.0"
chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -5046,6 +5059,11 @@ coa@~1.0.1:
dependencies:
q "^1.1.2"
codepage@~1.15.0:
version "1.15.0"
resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.15.0.tgz#2e00519024b39424ec66eeb3ec07227e692618ab"
integrity sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==
collect-v8-coverage@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9"
@@ -5275,7 +5293,7 @@ cosmiconfig@^9.0.0:
js-yaml "^4.1.0"
parse-json "^5.2.0"
crc-32@^1.2.0:
crc-32@^1.2.0, crc-32@~1.2.0, crc-32@~1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff"
integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
@@ -6653,6 +6671,11 @@ forwarded@0.2.0:
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
frac@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b"
integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==
fraction.js@^4.3.7:
version "4.3.7"
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
@@ -10709,6 +10732,13 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
ssf@~0.11.2:
version "0.11.2"
resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c"
integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==
dependencies:
frac "~1.1.2"
stack-trace@^1.0.0-pre2:
version "1.0.0-pre2"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-1.0.0-pre2.tgz#46a83a79f1b287807e9aaafc6a5dd8bcde626f9c"
@@ -11970,11 +12000,21 @@ wildcard@^2.0.1:
resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67"
integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==
wmf@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da"
integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==
word-wrap@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
word@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961"
integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==
workbox-background-sync@7.3.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-7.3.0.tgz#b6340731a8d5b42b9e75a8a87c8806928e6e6303"
@@ -12187,6 +12227,19 @@ ws@~8.17.1:
resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
xlsx@^0.18.5:
version "0.18.5"
resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.18.5.tgz#16711b9113c848076b8a177022799ad356eba7d0"
integrity sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==
dependencies:
adler-32 "~1.3.0"
cfb "~1.2.1"
codepage "~1.15.0"
crc-32 "~1.2.1"
ssf "~0.11.2"
wmf "~1.0.1"
word "~0.3.0"
xml-name-validator@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"