diff --git a/packages/api/src/app.ts b/packages/api/src/app.ts
index f4e664ceb..878683eae 100644
--- a/packages/api/src/app.ts
+++ b/packages/api/src/app.ts
@@ -45,6 +45,7 @@ const plugins = [
'@nocobase/plugin-action-logs',
// '@nocobase/plugin-file-manager',
'@nocobase/plugin-permissions',
+ '@nocobase/plugin-export',
// '@nocobase/plugin-automations',
// '@nocobase/plugin-china-region',
];
diff --git a/packages/client/package.json b/packages/client/package.json
index 8faf1d0f0..ded5d7cb3 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -33,12 +33,14 @@
"html-react-parser": "^1.2.7",
"lodash": "^4.17.21",
"monaco-editor": "^0.25.2",
+ "react-big-calendar": "^0.33.6",
"react-dnd": "^14.0.2",
"react-dnd-html5-backend": "^14.0.0",
"react-dnd-preview": "^6.0.2",
"react-dnd-touch-backend": "^14.0.0",
"react-helmet": "^6.1.0",
"react-hooks-global-state": "^1.0.1",
+ "react-modal-hook": "^3.0.0",
"umi-request": "^1.3.5"
}
}
diff --git a/packages/client/src/resource.ts b/packages/client/src/resource.ts
index eef38dcf2..efb9c416d 100644
--- a/packages/client/src/resource.ts
+++ b/packages/client/src/resource.ts
@@ -99,6 +99,40 @@ export class Resource {
});
}
+ export(options: any) {
+ const { resourceName } = this.options;
+ const { columns, ...others } = options;
+ const url = `${resourceName}:export`;
+ return request(url, {
+ method: 'post',
+ params: {
+ columns: JSON.stringify(columns),
+ ...others,
+ },
+ parseResponse: false,
+ responseType: 'blob'
+ }).then(async (response: Response) => {
+ const filename = decodeURI(response.headers.get('Content-Disposition').replace('attachment; filename=', ''));
+ // ReadableStream
+ let res = new Response(response.body);
+ let blob = await res.blob();
+ let url = URL.createObjectURL(blob);
+ let a = document.createElement('a');
+ a.style.display = 'none';
+ a.href = url;
+ a.download = filename;
+ document.body.appendChild(a);
+ a.click();
+ // cleanup
+ URL.revokeObjectURL(url);
+ document.body.removeChild(a);
+ a = null;
+ blob = null;
+ url = null;
+ res = null;
+ });
+ }
+
destroy(filter: any) {
const { resourceName } = this.options;
const url = `${resourceName}:destroy`;
diff --git a/packages/client/src/schemas/table/index.tsx b/packages/client/src/schemas/table/index.tsx
index 95c8a4e47..26a1aabf3 100644
--- a/packages/client/src/schemas/table/index.tsx
+++ b/packages/client/src/schemas/table/index.tsx
@@ -220,6 +220,52 @@ const useTableDestroyAction = () => {
};
};
+const useTableExportAction = () => {
+ const {
+ resource,
+ field,
+ service,
+ selectedRowKeys,
+ setSelectedRowKeys,
+ refresh,
+ schema,
+ props: { refreshRequestOnChange, rowKey },
+ } = useTable();
+ const ctx = useContext(TableRowContext);
+
+ const actionField = useField();
+ const fieldNames = actionField.componentProps.fieldNames || [];
+ const { getField } = useCollectionContext();
+
+ const columns = fieldNames
+ .map((name) => {
+ const f = getField(name);
+ return {
+ title: f?.uiSchema.title,
+ name,
+ sort: f?.sort,
+ };
+ })
+ .sort((a, b) => a.sort - b.sort);
+
+ return {
+ async run() {
+ const rowKeys = selectedRowKeys || [];
+ const { filter = {}, ...others } = service.params[0];
+ if (rowKeys.length) {
+ filter[`${rowKey}.in`] = rowKeys;
+ }
+ await resource.export({
+ ...others,
+ columns,
+ perPage: -1,
+ page: 1,
+ filter,
+ });
+ },
+ };
+};
+
const useTableRowRecord = () => {
const ctx = useContext(TableRowContext);
return ctx.record;
@@ -817,7 +863,24 @@ function generateActionSchema(type) {
fieldNames: [],
},
},
- export: {},
+ export: {
+ key: uid(),
+ type: 'void',
+ name: uid(),
+ title: '导出',
+ 'x-align': 'right',
+ 'x-decorator': 'AddNew.Displayed',
+ 'x-decorator-props': {
+ displayName: 'export',
+ },
+ 'x-action-type': 'export',
+ 'x-component': 'Action',
+ 'x-designable-bar': 'Table.ExportActionDesignableBar',
+ 'x-component-props': {
+ fieldNames: [],
+ useAction: '{{ Table.useTableExportAction }}',
+ },
+ },
create: {
key: uid(),
type: 'void',
@@ -993,7 +1056,7 @@ function AddActionButton() {
{[
{ title: '筛选', name: 'filter' },
- // { title: '导出', name: 'export' },
+ { title: '导出', name: 'export' },
{ title: '新增', name: 'create' },
{ title: '删除', name: 'destroy' },
].map((item) => (
@@ -1394,6 +1457,124 @@ Table.Filter.DesignableBar = () => {
);
};
+Table.ExportActionDesignableBar = () => {
+ const { schema, remove, refresh, insertAfter } = useDesignable();
+ const [visible, setVisible] = useState(false);
+ const displayed = useDisplayedMapContext();
+ const { fields } = useCollectionContext();
+ const field = useField();
+ let fieldNames = field.componentProps.fieldNames || [];
+ if (fieldNames.length === 0) {
+ fieldNames = fields.map((field) => field.name);
+ }
+ return (
+
+ {
+ e.stopPropagation();
+ }}
+ className={cls('designable-bar-actions', { active: visible })}
+ >
+
+ {
+ setVisible(visible);
+ }}
+ overlay={
+
+ }
+ >
+
+
+
+
+ );
+};
+
Table.Operation = observer((props: any) => {
const { designable, schema } = useDesignable();
return (
@@ -2094,6 +2275,7 @@ Table.useTableFilterAction = useTableFilterAction;
Table.useTableCreateAction = useTableCreateAction;
Table.useTableUpdateAction = useTableUpdateAction;
Table.useTableDestroyAction = useTableDestroyAction;
+Table.useTableExportAction = useTableExportAction;
Table.useTableIndex = useTableIndex;
Table.useTableRowRecord = useTableRowRecord;
Table.SimpleDesignableBar = SimpleDesignableBar;
diff --git a/packages/plugin-export/.npmignore b/packages/plugin-export/.npmignore
new file mode 100644
index 000000000..461574b2f
--- /dev/null
+++ b/packages/plugin-export/.npmignore
@@ -0,0 +1,7 @@
+node_modules
+*.log
+docs
+__tests__
+tsconfig.json
+src
+.fatherrc.ts
\ No newline at end of file
diff --git a/packages/plugin-export/package.json b/packages/plugin-export/package.json
new file mode 100644
index 000000000..c737c1623
--- /dev/null
+++ b/packages/plugin-export/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "@nocobase/plugin-export",
+ "version": "0.4.0-alpha.7",
+ "main": "lib/index.js",
+ "license": "MIT",
+ "devDependencies": {
+ "@types/node-xlsx": "^0.15.1"
+ },
+ "dependencies": {
+ "@nocobase/actions": "^0.4.0-alpha.7",
+ "@nocobase/database": "^0.4.0-alpha.7",
+ "@nocobase/resourcer": "^0.4.0-alpha.7",
+ "node-xlsx": "^0.16.1"
+ },
+ "peerDependencies": {
+ "@nocobase/plugin-collections": "*",
+ "@nocobase/plugin-permissions": "*"
+ }
+}
diff --git a/packages/plugin-export/src/actions/export.ts b/packages/plugin-export/src/actions/export.ts
new file mode 100644
index 000000000..521ab4760
--- /dev/null
+++ b/packages/plugin-export/src/actions/export.ts
@@ -0,0 +1,70 @@
+import xlsx from 'node-xlsx';
+import { actions } from '@nocobase/actions';
+import render from '../renders';
+
+async function _export(ctx: actions.Context, next: actions.Next) {
+ let { columns } = ctx.action.params;
+ if (typeof columns === 'string') {
+ columns = JSON.parse(columns);
+ }
+ ctx.action.mergeParams({
+ 'fields[appends]': columns.map((column: any) => column.name).join(','),
+ }, {
+ payload: 'replace',
+ });
+ console.log({ columns });
+ await actions.common.list(ctx, async () => {
+ const {
+ db,
+ action: {
+ params: {
+ resourceName
+ }
+ },
+ body,
+ } = ctx;
+
+ const table = db.getTable(resourceName);
+ const tableOptions = table.getOptions();
+
+ let fields = body.rows.length
+ ? Object.keys(body.rows[0].get())
+ .map(key => tableOptions.fields.find(({ name }) => name === key))
+ .filter(item => item && !item.developerMode)
+ .sort((a, b) => a.sort - b.sort)
+ : [];
+
+ if (columns && columns.length) {
+ fields = columns.map(column => {
+ const field = table.getField(column.name);
+ return {
+ ...field.options,
+ ...column,
+ };
+ });
+ }
+
+ const { rows, ranges } = render({
+ fields,
+ data: body.rows
+ }, ctx);
+
+ ctx.body = xlsx.build([{
+ name: tableOptions.title,
+ data: rows,
+ options: {
+ '!merges': ranges
+ }
+ }]);
+
+ ctx.set({
+ 'Content-Type': 'application/octet-stream',
+ // to avoid "invalid character" error in header (RFC)
+ 'Content-Disposition': `attachment; filename=${encodeURI(tableOptions.title||tableOptions.name)}.xlsx`
+ });
+ });
+
+ await next();
+}
+
+export default _export;
diff --git a/packages/plugin-export/src/renders/index.ts b/packages/plugin-export/src/renders/index.ts
new file mode 100644
index 000000000..e5e104faf
--- /dev/null
+++ b/packages/plugin-export/src/renders/index.ts
@@ -0,0 +1,162 @@
+import * as renders from './renders';
+
+function getInterfaceRender(name: string): Function {
+ return renders[name] || renders._;
+}
+
+function renderHeader(params, ctx) {
+ const {
+ fields,
+ headers = [],
+ rowIndex = 0
+ } = params;
+
+ let { colIndex = 0 } = params;
+
+ if (!headers[rowIndex]) {
+ headers.push([]);
+ }
+ const row = headers[rowIndex];
+
+ fields.forEach((field, i) => {
+ const nextColIndex = colIndex + i;
+ row.push({
+ field,
+ rowIndex,
+ colIndex: nextColIndex
+ });
+ if (field.interface === 'subTable') {
+ const subTable = ctx.db.getTable(field.target);
+ const subFields = subTable.getOptions().fields.filter(field => Boolean(field.__index));
+ renderHeader({
+ fields: subFields,
+ headers,
+ rowIndex: rowIndex + 1,
+ colIndex: nextColIndex
+ }, ctx);
+ colIndex += subFields.length;
+ }
+ });
+
+ Object.assign(params, { headers });
+}
+
+function renderRows({ fields, data }, ctx) {
+ return data.reduce((result, row) => {
+ const thisRow = [];
+ const rowIndex = 0;
+ let colOffset = 0;
+ fields.forEach((field, i) => {
+ if (!thisRow[rowIndex]) {
+ thisRow.push([]);
+ }
+ const cells = thisRow[rowIndex];
+ if (field.interface !== 'subTable') {
+ const render = getInterfaceRender(field.interface);
+ cells.push({
+ value: render(field, row),
+ rowIndex: result.length + rowIndex,
+ colIndex: i + colOffset
+ });
+ return;
+ }
+
+ const subTable = ctx.db.getTable(field.target);
+ const subFields = subTable.getOptions().fields.filter(item => Boolean(item.__index));
+ const subRows = renderRows({ fields: subFields, data: row.get(field.name) || [] }, ctx);
+
+ // const { rows: subRowGroups } = subTableRows;
+ subRows.forEach((cells, j) => {
+ const subRowIndex = rowIndex + j;
+ if (!thisRow[subRowIndex]) {
+ thisRow.push([]);
+ }
+ const subCells = thisRow[subRowIndex];
+ subCells.push(...cells.map(cell => ({
+ ...cell,
+ rowIndex: result.length + subRowIndex,
+ colIndex: cell.colIndex + i
+ })));
+ });
+ colOffset += subFields.length;
+ });
+
+ thisRow.forEach((cells) => {
+ cells.forEach(cell => {
+ const relRowIndex = cell.rowIndex - result.length;
+ Object.assign(cell, {
+ rowSpan: relRowIndex >= thisRow.length - 1
+ || thisRow[relRowIndex + 1].find(item => item.colIndex === cell.colIndex)
+ ? 1
+ : thisRow.length - relRowIndex
+ });
+ });
+ });
+
+ return result.concat(thisRow);
+ }, []);
+}
+
+export default function({ fields, data }, ctx) {
+ const headers = [];
+ renderHeader({
+ fields,
+ headers
+ }, ctx);
+ const ranges = [];
+ // 计算全表最大的列索引(由于无论如何最大列都是单个单元格,所以等价于长度)
+ const maxColIndex = Math.max(...headers.map(row => row[row.length - 1].colIndex));
+ // 遍历所有单元格,计算需要合并的坐标范围
+ headers.forEach((row, rowIndex) => {
+ row.forEach((cell, cellIndex) => {
+ // 跨行合并的行数为
+ cell.rowSpan = cell.rowIndex >= headers.length - 1
+ || headers[cell.rowIndex + 1].find(item => item.colIndex === cell.colIndex)
+ ? 1
+ : headers.length - cell.rowIndex;
+
+ const nextCell = headers.slice(0, rowIndex + 1)
+ .map(r => r.find(item => item.colIndex > cell.colIndex))
+ .filter(c => Boolean(c))
+ .reduce((min, c) => min && Math.min(min.colIndex, c.colIndex) === min.colIndex ? min : c, null);
+ cell.colSpan = nextCell
+ ? nextCell.colIndex - cell.colIndex
+ : maxColIndex - cell.colIndex + 1;
+
+ if (cell.rowSpan > 1 || cell.colSpan > 1) {
+ ranges.push({
+ s: { c: cell.colIndex, r: cell.rowIndex },
+ e: { c: cell.colIndex + cell.colSpan - 1, r: cell.rowIndex + cell.rowSpan - 1 }
+ });
+ }
+ });
+ });
+
+ const rows = renderRows({ fields, data }, ctx)
+ .map(row => {
+ const cells = Array(maxColIndex).fill(null);
+ row.forEach(cell => {
+ cells.splice(cell.colIndex, 1, cell.value);
+ if (cell.rowSpan > 1) {
+ ranges.push({
+ s: { c: cell.colIndex, r: cell.rowIndex + headers.length },
+ e: { c: cell.colIndex, r: cell.rowIndex + cell.rowSpan - 1 + headers.length }
+ });
+ }
+ });
+ return cells;
+ });
+
+ return {
+ rows: [
+ ...headers.map(row => {
+ // 补齐无数据单元格,以供合并
+ const cells = Array(maxColIndex).fill(null);
+ row.forEach(cell => cells.splice(cell.colIndex, 1, cell.field.title))
+ return cells;
+ }),
+ ...rows
+ ],
+ ranges
+ };
+}
diff --git a/packages/plugin-export/src/renders/renders.ts b/packages/plugin-export/src/renders/renders.ts
new file mode 100644
index 000000000..a8da3a0e3
--- /dev/null
+++ b/packages/plugin-export/src/renders/renders.ts
@@ -0,0 +1,60 @@
+import moment from 'moment';
+
+export function _(field, row) {
+ return row.get(field.name);
+}
+
+export function datetime(field, row) {
+ const value = row.get(field.name);
+ return moment(value).format(field.showTime ? `${field.dateFormat} ${field.timeFormat}` : field.dateFormat);
+}
+
+export function percent(field, row) {
+ const value = row.get(field.name);
+ return value && `${value}%`;
+}
+
+export function boolean(field, row) {
+ const value = row.get(field.name);
+ // TODO(feature): i18n
+ return value ? '是' : '否';
+}
+
+export function select(field, row) {
+ const value = row.get(field.name);
+ const option = field.dataSource.find(item => item.value === value);
+ return option && option.label;
+}
+
+export function multipleSelect(field, row) {
+ const values = row.get(field.name);
+ return values && values.map(value => {
+ const option = field.dataSource.find(item => item.value === value);
+ return option && option.label;
+ });
+}
+
+export const radio = select;
+
+export const checkboxes = multipleSelect;
+
+export function subTable(field, row) {
+ // TODO: need title field to be defined
+ return (row.get(field.name) || []).map(item => item[field.sourceKey]);
+}
+
+export function linkTo(field, row) {
+ return (row.get(field.name) || []).map(item => item[field.labelField]);
+}
+
+export function attachment(field, row) {
+ return (row.get(field.name) || []).map(item => item[field.url]).join(' ');
+}
+
+export function chinaRegion(field, row) {
+ const value = row.get(field.name);
+ const values = (Array.isArray(value) ? value : [value]).sort((a, b) =>
+ a.level !== b.level ? a.level - b.level : a.sort - b.sort,
+ );
+ return values.map(item => item.name).join('/');
+}
diff --git a/packages/plugin-export/src/server.ts b/packages/plugin-export/src/server.ts
new file mode 100644
index 000000000..42c4db145
--- /dev/null
+++ b/packages/plugin-export/src/server.ts
@@ -0,0 +1,28 @@
+import Resourcer from '@nocobase/resourcer';
+import _export from './actions/export';
+
+export const ACTION_NAME_EXPORT = 'export';
+
+export default async function (options = {}) {
+ const resourcer: Resourcer = this.resourcer;
+
+ resourcer.registerActionHandler(ACTION_NAME_EXPORT, _export);
+
+ // TODO(temp): 继承 list 权限的临时写法
+ resourcer.use(async (ctx, next) => {
+ if (ctx.action.params.actionName === ACTION_NAME_EXPORT) {
+ ctx.action.mergeParams({
+ actionName: 'list'
+ });
+
+ console.log('action name in export has been rewritten to:', ctx.action.params.actionName);
+
+ const permissionPlugin = ctx.app.getPluginInstance('@nocobase/plugin-permissions');
+ if (permissionPlugin) {
+ return permissionPlugin.middleware(ctx, next);
+ }
+ }
+
+ await next();
+ });
+}
diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts
index 74b6dc460..5bf71159c 100644
--- a/packages/server/src/index.ts
+++ b/packages/server/src/index.ts
@@ -20,7 +20,9 @@ export default {
const app = new Application(options);
app.use(bodyParser());
- app.use(cors());
+ app.use(cors({
+ exposeHeaders: ['content-disposition'],
+ }));
app.resourcer.registerActionHandlers({ ...actions.common, ...actions.associate });
diff --git a/yarn.lock b/yarn.lock
index 4bf0ef53f..63dc52e41 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1695,6 +1695,13 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.14.6", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.7":
+ version "7.15.3"
+ resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.3.tgz#2e1c2880ca118e5b2f9988322bd8a7656a32502b"
+ integrity sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
"@babel/template@^7.10.4", "@babel/template@^7.12.7", "@babel/template@^7.14.5", "@babel/template@^7.3.3", "@babel/template@^7.4.0", "@babel/template@^7.4.4":
version "7.14.5"
resolved "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4"
@@ -3258,6 +3265,11 @@
dependencies:
"@octokit/openapi-types" "^7.3.2"
+"@popperjs/core@^2.5.3":
+ version "2.9.3"
+ resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.9.3.tgz#8b68da1ebd7fc603999cf6ebee34a4899a14b88e"
+ integrity sha512-xDu17cEfh7Kid/d95kB6tZsLOmSWKCZKtprnhVepjsSaCij+lM3mItSJDuuHDMbCWTh8Ejmebwb+KONcCJ0eXQ==
+
"@qixian.cs/path-to-regexp@^6.1.0":
version "6.1.0"
resolved "https://registry.npmjs.org/@qixian.cs/path-to-regexp/-/path-to-regexp-6.1.0.tgz#6b84ad01596332aba95fa29d2e70104698cd5c45"
@@ -3278,6 +3290,13 @@
resolved "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz#a3031eb54129f2c66b2753f8404266ec7bf67f0a"
integrity sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==
+"@restart/hooks@^0.3.25":
+ version "0.3.27"
+ resolved "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.27.tgz#91f356d66d4699a8cd8b3d008402708b6a9dc505"
+ integrity sha512-s984xV/EapUIfkjlf8wz9weP2O9TNKR96C68FfMEy2bE69+H4cNv3RD4Mf97lW7Htt7PjZrYTjSC8f3SB9VCXw==
+ dependencies:
+ dequal "^2.0.2"
+
"@rollup/plugin-babel@5.2.1":
version "5.2.1"
resolved "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.2.1.tgz#20fc8f8864dc0eaa1c5578408459606808f72924"
@@ -3779,6 +3798,11 @@
dependencies:
"@types/node" "*"
+"@types/node-xlsx@^0.15.1":
+ version "0.15.2"
+ resolved "https://registry.npmjs.org/@types/node-xlsx/-/node-xlsx-0.15.2.tgz#1371c4af8fe2b6626253f8b85719adfe88355b20"
+ integrity sha512-rG1SmpWvSkse23rL/5bgej5yQ2y+WoWMrKE3iE4upuHWQwzdLCYEkrwr1pMZDx642R/tJCDGGUig7U/cT24Ecg==
+
"@types/node@*", "@types/node@>= 8":
version "15.12.2"
resolved "https://registry.npmjs.org/@types/node/-/node-15.12.2.tgz#1f2b42c4be7156ff4a6f914b2fb03d05fa84e38d"
@@ -3892,7 +3916,7 @@
"@types/history" "*"
"@types/react" "*"
-"@types/react@*", "@types/react@^16.9.43", "@types/react@^17.0.0":
+"@types/react@*", "@types/react@>=16.9.11", "@types/react@^16.9.43", "@types/react@^17.0.0":
version "17.0.11"
resolved "https://registry.npmjs.org/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451"
integrity sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA==
@@ -3943,6 +3967,11 @@
resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e"
integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==
+"@types/warning@^3.0.0":
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52"
+ integrity sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=
+
"@types/yargs-parser@*":
version "20.2.0"
resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9"
@@ -4520,6 +4549,14 @@ address@>=0.0.1, address@^1.0.0:
resolved "https://registry.npmjs.org/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6"
integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==
+adler-32@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/adler-32/-/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25"
+ integrity sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU=
+ dependencies:
+ exit-on-epipe "~1.0.1"
+ printj "~1.1.0"
+
agent-base@4, agent-base@^4.3.0:
version "4.3.0"
resolved "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
@@ -5670,6 +5707,11 @@ buffer-from@1.x, buffer-from@^1.0.0:
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
+buffer-from@^1.1.1:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
+ integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
+
buffer-writer@2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04"
@@ -5925,6 +5967,15 @@ center-align@^0.1.1:
align-text "^0.1.3"
lazy-cache "^1.0.3"
+cfb@^1.1.4:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/cfb/-/cfb-1.2.0.tgz#6a4d0872b525ed60349e1ef51fb4b0bf73eca9a8"
+ integrity sha512-sXMvHsKCICVR3Naq+J556K+ExBo9n50iKl6LGarlnvuA2035uMlGA/qVrc0wQtow5P1vJEw9UyrKLCbtIKz+TQ==
+ dependencies:
+ adler-32 "~1.2.0"
+ crc-32 "~1.2.0"
+ printj "~1.1.2"
+
chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -6224,6 +6275,11 @@ cloneable-readable@^1.0.0:
process-nextick-args "^2.0.0"
readable-stream "^2.3.5"
+clsx@^1.0.4:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
+ integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==
+
co-body@^6.0.0:
version "6.1.0"
resolved "https://registry.npmjs.org/co-body/-/co-body-6.1.0.tgz#d87a8efc3564f9bfe3aced8ef5cd04c7a8766547"
@@ -6258,6 +6314,14 @@ code-point-at@^1.0.0:
resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
+codepage@~1.14.0:
+ version "1.14.0"
+ resolved "https://registry.npmjs.org/codepage/-/codepage-1.14.0.tgz#8cbe25481323559d7d307571b0fff91e7a1d2f99"
+ integrity sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k=
+ dependencies:
+ commander "~2.14.1"
+ exit-on-epipe "~1.0.1"
+
collect-v8-coverage@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59"
@@ -6351,6 +6415,16 @@ commander@^2.19.0, commander@^2.20.0:
resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+commander@~2.14.1:
+ version "2.14.1"
+ resolved "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa"
+ integrity sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==
+
+commander@~2.17.1:
+ version "2.17.1"
+ resolved "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf"
+ integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==
+
commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@@ -6709,6 +6783,14 @@ cosmiconfig@^7.0.0:
path-type "^4.0.0"
yaml "^1.10.0"
+crc-32@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208"
+ integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==
+ dependencies:
+ exit-on-epipe "~1.0.1"
+ printj "~1.1.0"
+
create-ecdh@^4.0.0:
version "4.0.4"
resolved "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
@@ -7157,6 +7239,11 @@ data-urls@^2.0.0:
whatwg-mimetype "^2.3.0"
whatwg-url "^8.0.0"
+date-arithmetic@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.npmjs.org/date-arithmetic/-/date-arithmetic-4.1.0.tgz#e5d6434e9deb71f79760a37b729e4a515e730ddf"
+ integrity sha512-QWxYLR5P/6GStZcdem+V1xoto6DMadYWpMXU82ES3/RfR3Wdwr3D0+be7mgOJ+Ov0G9D5Dmb9T17sNLQYj9XOg==
+
date-fns@^2.0.1:
version "2.23.0"
resolved "https://registry.nlark.com/date-fns/download/date-fns-2.23.0.tgz?cache=0&sync_timestamp=1627020353586&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdate-fns%2Fdownload%2Fdate-fns-2.23.0.tgz#4e886c941659af0cf7b30fafdd1eaa37e88788a9"
@@ -7388,6 +7475,11 @@ deprecation@^2.0.0, deprecation@^2.3.1:
resolved "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
+dequal@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d"
+ integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==
+
des.js@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
@@ -7520,6 +7612,14 @@ dom-align@1.x, dom-align@^1.7.0:
resolved "https://registry.npmjs.org/dom-align/-/dom-align-1.12.2.tgz#0f8164ebd0c9c21b0c790310493cd855892acd4b"
integrity sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==
+dom-helpers@^5.1.0, dom-helpers@^5.2.0:
+ version "5.2.1"
+ resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
+ integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
+ dependencies:
+ "@babel/runtime" "^7.8.7"
+ csstype "^3.0.2"
+
dom-serializer@0:
version "0.2.2"
resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
@@ -8373,6 +8473,11 @@ exenv@^1.2.0:
resolved "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d"
integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=
+exit-on-epipe@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692"
+ integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==
+
exit@^0.1.2:
version "0.1.2"
resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
@@ -8590,6 +8695,11 @@ fecha@~4.2.0:
resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce"
integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==
+fflate@^0.3.8:
+ version "0.3.11"
+ resolved "https://registry.npmjs.org/fflate/-/fflate-0.3.11.tgz#2c440d7180fdeb819e64898d8858af327b042a5d"
+ integrity sha512-Rr5QlUeGN1mbOHlaqcSYMKVpPbgLy0AWT/W0EHxA6NGI12yO1jpoui2zBBvU2G824ltM6Ut8BFgfHSBGfkmS0A==
+
figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
version "3.5.2"
resolved "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
@@ -8797,6 +8907,11 @@ formstream@^1.1.0:
mime "^2.5.2"
pause-stream "~0.0.11"
+frac@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b"
+ integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==
+
fragment-cache@^0.2.1:
version "0.2.1"
resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19"
@@ -12098,6 +12213,11 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
+lodash-es@^4.17.11:
+ version "4.17.21"
+ resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
+ integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
+
lodash._reinterpolate@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
@@ -13297,6 +13417,15 @@ node-schedule@^2.0.0:
long-timeout "0.1.1"
sorted-array-functions "^1.3.0"
+node-xlsx@^0.16.1:
+ version "0.16.2"
+ resolved "https://registry.npmjs.org/node-xlsx/-/node-xlsx-0.16.2.tgz#40f580187eae0e032cac96e958e97cb6ceca09f6"
+ integrity sha512-ZT3Y4Zg2BFC2UWdp9B/6x3GqrFL0Bf0cXKy9IyhcwlKbcDAf5GuPAPSqrWFQK68NIpfTNA1Kr/NNjpwYxUgHTA==
+ dependencies:
+ "@babel/runtime" "^7.14.6"
+ buffer-from "^1.1.1"
+ xlsx "^0.17.0"
+
nodemon@^2.0.12:
version "2.0.12"
resolved "https://registry.npmjs.org/nodemon/-/nodemon-2.0.12.tgz#5dae4e162b617b91f1873b3bfea215dd71e144d5"
@@ -15098,6 +15227,11 @@ pretty-format@^26.6.2:
ansi-styles "^4.0.0"
react-is "^17.0.1"
+printj@~1.1.0, printj@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222"
+ integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==
+
prism-react-renderer@^1.1.1:
version "1.2.1"
resolved "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.2.1.tgz#392460acf63540960e5e3caa699d851264e99b89"
@@ -15880,6 +16014,23 @@ react-attr-converter@^0.3.1:
resolved "https://registry.npmjs.org/react-attr-converter/-/react-attr-converter-0.3.1.tgz#4a2abf6d907b7ddae4d862dfec80e489ce41ad6e"
integrity sha512-dSxo2Mn6Zx4HajeCeQNLefwEO4kNtV/0E682R1+ZTyFRPqxDa5zYb5qM/ocqw9Bxr/kFQO0IUiqdV7wdHw+Cdg==
+react-big-calendar@^0.33.6:
+ version "0.33.6"
+ resolved "https://registry.npmjs.org/react-big-calendar/-/react-big-calendar-0.33.6.tgz#87594b4ce54b4f3cc7f69d52f2d34ddf6b2eb00b"
+ integrity sha512-4crVUE1W7+zIUfbfrXxd9nDOVktwn8M8Ffrjd39r9zFIveZu1zhrWwi+qqu46EQw2xRnb+mFx+mcwUozkqYlkA==
+ dependencies:
+ "@babel/runtime" "^7.1.5"
+ clsx "^1.0.4"
+ date-arithmetic "^4.1.0"
+ dom-helpers "^5.1.0"
+ invariant "^2.2.4"
+ lodash "^4.17.11"
+ lodash-es "^4.17.11"
+ memoize-one "^5.1.1"
+ prop-types "^15.7.2"
+ react-overlays "^4.1.1"
+ uncontrollable "^7.0.0"
+
react-dnd-html5-backend@^14.0.0:
version "14.0.0"
resolved "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-14.0.0.tgz#28d660a2ad1e07447c34a65cd25f7de8f1657194"
@@ -15990,6 +16141,11 @@ react-lifecycles-compat@^3.0.4:
resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
+react-modal-hook@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.npmjs.org/react-modal-hook/-/react-modal-hook-3.0.0.tgz#24b2ff2acf288ef25c11e4fb11b329458a823ea3"
+ integrity sha512-mNkJwgEtOoIabuILlWnGAto993WVkimZASBWk/rAGZ6tNIqjx4faQtNdr/X31vw+QGfKhspXc4vPi1jbfkk2Yg==
+
react-native-swipeout@^2.2.2:
version "2.3.6"
resolved "https://registry.npmjs.org/react-native-swipeout/-/react-native-swipeout-2.3.6.tgz#47dac8a835825cf3f2eef9e495574a3d9ab6d3fa"
@@ -15999,6 +16155,20 @@ react-native-swipeout@^2.2.2:
prop-types "^15.5.10"
react-tween-state "^0.1.5"
+react-overlays@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.npmjs.org/react-overlays/-/react-overlays-4.1.1.tgz#0060107cbe1c5171a744ccda3fbf0556d064bc5f"
+ integrity sha512-WtJifh081e6M24KnvTQoNjQEpz7HoLxqt8TwZM7LOYIkYJ8i/Ly1Xi7RVte87ZVnmqQ4PFaFiNHZhSINPSpdBQ==
+ dependencies:
+ "@babel/runtime" "^7.12.1"
+ "@popperjs/core" "^2.5.3"
+ "@restart/hooks" "^0.3.25"
+ "@types/warning" "^3.0.0"
+ dom-helpers "^5.2.0"
+ prop-types "^15.7.2"
+ uncontrollable "^7.0.0"
+ warning "^4.0.3"
+
react-property@1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/react-property/-/react-property-1.0.1.tgz#4ae4211557d0a0ae050a71aa8ad288c074bea4e6"
@@ -17685,6 +17855,13 @@ sqlstring@^2.3.2:
resolved "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.2.tgz#cdae7169389a1375b18e885f2e60b3e460809514"
integrity sha512-vF4ZbYdKS8OnoJAWBmMxCQDkiEBkGQYU7UZPtL8flbDRSNkhaXvRJ279ZtI6M+zDaQovVU4tuRgzK5fVhvFAhg==
+ssf@~0.11.2:
+ version "0.11.2"
+ resolved "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c"
+ integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==
+ dependencies:
+ frac "~1.1.2"
+
sshpk@^1.7.0:
version "1.16.1"
resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
@@ -18911,6 +19088,16 @@ unc-path-regex@^0.1.2:
resolved "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo=
+uncontrollable@^7.0.0:
+ version "7.2.1"
+ resolved "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz#1fa70ba0c57a14d5f78905d533cf63916dc75738"
+ integrity sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==
+ dependencies:
+ "@babel/runtime" "^7.6.3"
+ "@types/react" ">=16.9.11"
+ invariant "^2.2.4"
+ react-lifecycles-compat "^3.0.4"
+
undefsafe@^2.0.3:
version "2.0.3"
resolved "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae"
@@ -19658,11 +19845,21 @@ wkx@^0.5.0:
dependencies:
"@types/node" "*"
+wmf@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da"
+ integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==
+
word-wrap@^1.2.3, word-wrap@~1.2.3:
version "1.2.3"
resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
+word@~0.3.0:
+ version "0.3.0"
+ resolved "https://registry.npmjs.org/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961"
+ integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==
+
wordwrap@0.0.2:
version "0.0.2"
resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
@@ -19785,6 +19982,22 @@ xdg-basedir@^4.0.0:
resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13"
integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==
+xlsx@^0.17.0:
+ version "0.17.0"
+ resolved "https://registry.npmjs.org/xlsx/-/xlsx-0.17.0.tgz#028176a0140967dcee1817d221678461e47481c8"
+ integrity sha512-bZ36FSACiAyjoldey1+7it50PMlDp1pcAJrZKcVZHzKd8BC/z6TQ/QAN8onuqcepifqSznR6uKnjPhaGt6ig9A==
+ dependencies:
+ adler-32 "~1.2.0"
+ cfb "^1.1.4"
+ codepage "~1.14.0"
+ commander "~2.17.1"
+ crc-32 "~1.2.0"
+ exit-on-epipe "~1.0.1"
+ fflate "^0.3.8"
+ ssf "~0.11.2"
+ wmf "~1.0.1"
+ word "~0.3.0"
+
xml-name-validator@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"