diff --git a/.platform/hooks/predeploy/01-install-dd.sh b/.platform/hooks/predeploy/01-install-dd.sh
new file mode 100644
index 000000000..e6a85046a
--- /dev/null
+++ b/.platform/hooks/predeploy/01-install-dd.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+DD_API_KEY=58d91898a70c6fd659f6eea768a57976 DD_SITE="us3.datadoghq.com" bash -c "$(curl -L https://install.datadoghq.com/scripts/install_script_agent7.sh)"
+
+echo "Datadog agent installed."
diff --git a/Dockerfile b/Dockerfile
index b1d253808..16e9d2159 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -7,7 +7,6 @@ RUN dnf install -y git \
&& dnf install -y nodejs \
&& dnf clean all
-
# Install dependencies required by node-canvas
RUN dnf install -y \
gcc \
@@ -19,9 +18,22 @@ RUN dnf install -y \
libpng-devel \
make \
python3 \
+ fontconfig \
+ freetype \
python3-pip \
+ wget \
+ unzip \
&& dnf clean all
+# Install Montserrat fonts
+RUN cd /tmp \
+ && wget https://images.imex.online/fonts/montserrat.zip -O montserrat.zip \
+ && unzip montserrat.zip -d montserrat \
+ && mv montserrat/montserrat/*.ttf /usr/share/fonts \
+ && fc-cache -fv \
+ && rm -rf /tmp/montserrat /tmp/montserrat.zip \
+ && echo "Montserrat fonts installed and cached successfully."
+
# Set the working directory
WORKDIR /app
diff --git a/client/src/components/owner-detail-form/owner-detail-form.component.jsx b/client/src/components/owner-detail-form/owner-detail-form.component.jsx
index 419de25fa..5de4231f7 100644
--- a/client/src/components/owner-detail-form/owner-detail-form.component.jsx
+++ b/client/src/components/owner-detail-form/owner-detail-form.component.jsx
@@ -25,6 +25,9 @@ export default function OwnerDetailFormComponent({ form, loading }) {
+
+
+
diff --git a/client/src/graphql/owners.queries.js b/client/src/graphql/owners.queries.js
index e28fc8aa2..d169263f4 100644
--- a/client/src/graphql/owners.queries.js
+++ b/client/src/graphql/owners.queries.js
@@ -48,6 +48,7 @@ export const QUERY_OWNER_BY_ID = gql`
query QUERY_OWNER_BY_ID($id: uuid!) {
owners_by_pk(id: $id) {
id
+ accountingid
allow_text_message
ownr_addr1
ownr_addr2
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 289e2ffc9..40ead1d37 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -2397,6 +2397,7 @@
"selectexistingornew": "Select an existing owner record or create a new one. "
},
"fields": {
+ "accountingid": "Accounting ID",
"address": "Address",
"allow_text_message": "Permission to Text?",
"name": "Name",
@@ -3060,6 +3061,7 @@
"production_not_production_status": "Production not in Production Status",
"production_over_time": "Production Level over Time",
"psr_by_make": "Percent of Sales by Vehicle Make",
+ "purchase_return_ratio_excel": "Purchase & Return Ratio - Excel",
"purchase_return_ratio_grouped_by_vendor_detail": "Purchase & Return Ratio by Vendor (Detail)",
"purchase_return_ratio_grouped_by_vendor_summary": "Purchase & Return Ratio by Vendor (Summary)",
"purchases_by_cost_center_detail": "Purchases by Cost Center (Detail)",
@@ -3085,6 +3087,7 @@
"timetickets": "Time Tickets",
"timetickets_employee": "Employee Time Tickets",
"timetickets_summary": "Time Tickets Summary",
+ "total_loss_jobs": "Jobs Marked as Total Loss",
"unclaimed_hrs": "Unflagged Hours",
"void_ros": "Void ROs",
"work_in_progress_committed_labour": "Work in Progress - Committed Labor",
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 741e255ec..ac9c43a37 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -2397,6 +2397,7 @@
"selectexistingornew": ""
},
"fields": {
+ "accountingid": "",
"address": "Dirección",
"allow_text_message": "Permiso de texto?",
"name": "Nombre",
@@ -3060,6 +3061,7 @@
"production_not_production_status": "",
"production_over_time": "",
"psr_by_make": "",
+ "purchase_return_ratio_excel": "",
"purchase_return_ratio_grouped_by_vendor_detail": "",
"purchase_return_ratio_grouped_by_vendor_summary": "",
"purchases_by_cost_center_detail": "",
@@ -3085,6 +3087,7 @@
"timetickets": "",
"timetickets_employee": "",
"timetickets_summary": "",
+ "total_loss_jobs": "",
"unclaimed_hrs": "",
"void_ros": "",
"work_in_progress_committed_labour": "",
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index b75d48500..d43c5d424 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -2397,6 +2397,7 @@
"selectexistingornew": ""
},
"fields": {
+ "accountingid": "",
"address": "Adresse",
"allow_text_message": "Autorisation de texte?",
"name": "Prénom",
@@ -3060,6 +3061,7 @@
"production_not_production_status": "",
"production_over_time": "",
"psr_by_make": "",
+ "purchase_return_ratio_excel": "",
"purchase_return_ratio_grouped_by_vendor_detail": "",
"purchase_return_ratio_grouped_by_vendor_summary": "",
"purchases_by_cost_center_detail": "",
@@ -3085,6 +3087,7 @@
"timetickets": "",
"timetickets_employee": "",
"timetickets_summary": "",
+ "total_loss_jobs": "",
"unclaimed_hrs": "",
"void_ros": "",
"work_in_progress_committed_labour": "",
diff --git a/client/src/utils/TemplateConstants.js b/client/src/utils/TemplateConstants.js
index fcf10422d..80edfdb8d 100644
--- a/client/src/utils/TemplateConstants.js
+++ b/client/src/utils/TemplateConstants.js
@@ -2182,6 +2182,30 @@ export const TemplateList = (type, context) => {
},
group: "payroll",
adp_payroll: true
+ },
+ purchase_return_ratio_excel: {
+ title: i18n.t("reportcenter.templates.purchase_return_ratio_excel"),
+ subject: i18n.t("reportcenter.templates.purchase_return_ratio_excel"),
+ key: "purchase_return_ratio_excel",
+ //idtype: "vendor",
+ reporttype: "excel",
+ disabled: false,
+ rangeFilter: {
+ object: i18n.t("reportcenter.labels.objects.bills"),
+ field: i18n.t("bills.fields.date")
+ },
+ group: "purchases"
+ },
+ total_loss_jobs: {
+ title: i18n.t("reportcenter.templates.total_loss_jobs"),
+ subject: i18n.t("reportcenter.templates.total_loss_jobs"),
+ key: "total_loss_jobs",
+ disabled: false,
+ rangeFilter: {
+ object: i18n.t("reportcenter.labels.objects.jobs"),
+ field: i18n.t("jobs.fields.date_open")
+ },
+ group: "jobs"
}
}
: {}),
diff --git a/package-lock.json b/package-lock.json
index 9d215dd9a..fd2169355 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -31,6 +31,7 @@
"cors": "2.8.5",
"crisp-status-reporter": "^1.2.2",
"csrf": "^3.1.0",
+ "dd-trace": "^5.28.0",
"dinero.js": "^1.9.1",
"dotenv": "^16.4.5",
"express": "^4.21.1",
@@ -41,6 +42,7 @@
"intuit-oauth": "^4.1.3",
"ioredis": "^5.4.1",
"json-2-csv": "^5.5.6",
+ "juice": "^11.0.0",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"moment-timezone": "^0.5.46",
@@ -52,6 +54,7 @@
"recursive-diff": "^1.0.9",
"redis": "^4.7.0",
"rimraf": "^6.0.1",
+ "skia-canvas": "^2.0.0",
"soap": "^1.1.6",
"socket.io": "^4.8.1",
"socket.io-adapter": "^2.5.5",
@@ -1647,6 +1650,114 @@
"kuler": "^2.0.0"
}
},
+ "node_modules/@datadog/libdatadog": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@datadog/libdatadog/-/libdatadog-0.2.2.tgz",
+ "integrity": "sha512-rTWo96mEPTY5UbtGoFj8/wY0uKSViJhsPg/Z6aoFWBFXQ8b45Ix2e/yvf92AAwrhG+gPLTxEqTXh3kef2dP8Ow==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@datadog/native-appsec": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.3.0.tgz",
+ "integrity": "sha512-RYHbSJ/MwJcJaLzaCaZvUyNLUKFbMshayIiv4ckpFpQJDiq1T8t9iM2k7008s75g1vRuXfsRNX7MaLn4aoFuWA==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-gyp-build": "^3.9.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@datadog/native-iast-rewriter": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.5.0.tgz",
+ "integrity": "sha512-WRu34A3Wwp6oafX8KWNAbedtDaaJO+nzfYQht7pcJKjyC2ggfPeF7SoP+eDo9wTn4/nQwEOscSR4hkJqTRlpXQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "lru-cache": "^7.14.0",
+ "node-gyp-build": "^4.5.0"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@datadog/native-iast-rewriter/node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": {
+ "version": "4.8.4",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
+ "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
+ "license": "MIT",
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
+ "node_modules/@datadog/native-iast-taint-tracking": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.2.0.tgz",
+ "integrity": "sha512-Mc6FzCoyvU5yXLMsMS9yKnEqJMWoImAukJXolNWCTm+JQYCMf2yMsJ8pBAm7KyZKliamM9rCn7h7Tr2H3lXwjA==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-gyp-build": "^3.9.0"
+ }
+ },
+ "node_modules/@datadog/native-metrics": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-3.0.1.tgz",
+ "integrity": "sha512-0GuMyYyXf+Qpb/F+Fcekz58f2mO37lit9U3jMbWY/m8kac44gCPABzL5q3gWbdH+hWgqYfQoEYsdNDGSrKfwoQ==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-addon-api": "^6.1.0",
+ "node-gyp-build": "^3.9.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@datadog/pprof": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.4.1.tgz",
+ "integrity": "sha512-IvpL96e/cuh8ugP5O8Czdup7XQOLHeIDgM5pac5W7Lc1YzGe5zTtebKFpitvb1CPw1YY+1qFx0pWGgKP2kOfHg==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "delay": "^5.0.0",
+ "node-gyp-build": "<4.0",
+ "p-limit": "^3.1.0",
+ "pprof-format": "^2.1.0",
+ "source-map": "^0.7.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@datadog/pprof/node_modules/source-map": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
+ "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@datadog/sketches-js": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@datadog/sketches-js/-/sketches-js-2.1.1.tgz",
+ "integrity": "sha512-d5RjycE+MObE/hU+8OM5Zp4VjTwiPLRa8299fj7muOmR16fb942z8byoMbCErnGh0lBevvgkGrLclQDvINbIyg==",
+ "license": "Apache-2.0"
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
@@ -1690,13 +1801,13 @@
}
},
"node_modules/@eslint/config-array": {
- "version": "0.19.0",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.0.tgz",
- "integrity": "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==",
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz",
+ "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@eslint/object-schema": "^2.1.4",
+ "@eslint/object-schema": "^2.1.5",
"debug": "^4.3.1",
"minimatch": "^3.1.2"
},
@@ -1729,11 +1840,14 @@
}
},
"node_modules/@eslint/core": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.0.tgz",
- "integrity": "sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==",
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz",
+ "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==",
"dev": true,
"license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
@@ -1823,9 +1937,9 @@
}
},
"node_modules/@eslint/object-schema": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz",
- "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==",
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz",
+ "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@@ -1833,9 +1947,9 @@
}
},
"node_modules/@eslint/plugin-kit": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz",
- "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==",
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz",
+ "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -2278,6 +2392,15 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
+ "node_modules/@isaacs/ttlcache": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@isaacs/ttlcache/-/ttlcache-1.4.1.tgz",
+ "integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/@jonkemp/package-utils": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@jonkemp/package-utils/-/package-utils-1.0.8.tgz",
@@ -2493,6 +2616,30 @@
"node": ">=8.0.0"
}
},
+ "node_modules/@opentelemetry/core": {
+ "version": "1.29.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.29.0.tgz",
+ "integrity": "sha512-gmT7vAreXl0DTHD2rVZcw3+l2g84+5XiHIqdBUxXbExymPCvSsGOpiwMmn8nkiJur28STV31wnhIDrzWDPzjfA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@opentelemetry/semantic-conventions": "1.28.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.28.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz",
+ "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -2506,36 +2653,31 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
- "license": "BSD-3-Clause",
- "optional": true
+ "license": "BSD-3-Clause"
},
"node_modules/@protobufjs/base64": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
- "license": "BSD-3-Clause",
- "optional": true
+ "license": "BSD-3-Clause"
},
"node_modules/@protobufjs/codegen": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
- "license": "BSD-3-Clause",
- "optional": true
+ "license": "BSD-3-Clause"
},
"node_modules/@protobufjs/eventemitter": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
- "license": "BSD-3-Clause",
- "optional": true
+ "license": "BSD-3-Clause"
},
"node_modules/@protobufjs/fetch": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
"license": "BSD-3-Clause",
- "optional": true,
"dependencies": {
"@protobufjs/aspromise": "^1.1.1",
"@protobufjs/inquire": "^1.1.0"
@@ -2545,36 +2687,31 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
- "license": "BSD-3-Clause",
- "optional": true
+ "license": "BSD-3-Clause"
},
"node_modules/@protobufjs/inquire": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
- "license": "BSD-3-Clause",
- "optional": true
+ "license": "BSD-3-Clause"
},
"node_modules/@protobufjs/path": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
- "license": "BSD-3-Clause",
- "optional": true
+ "license": "BSD-3-Clause"
},
"node_modules/@protobufjs/pool": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
- "license": "BSD-3-Clause",
- "optional": true
+ "license": "BSD-3-Clause"
},
"node_modules/@protobufjs/utf8": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
- "license": "BSD-3-Clause",
- "optional": true
+ "license": "BSD-3-Clause"
},
"node_modules/@redis/bloom": {
"version": "1.2.0",
@@ -3670,6 +3807,15 @@
"node": ">=0.4.0"
}
},
+ "node_modules/acorn-import-attributes": {
+ "version": "1.9.5",
+ "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
+ "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^8"
+ }
+ },
"node_modules/acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
@@ -3716,6 +3862,15 @@
"url": "https://github.com/sponsors/epoberezkin"
}
},
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -4261,6 +4416,15 @@
"node": ">=6"
}
},
+ "node_modules/cargo-cp-artifact": {
+ "version": "0.1.9",
+ "resolved": "https://registry.npmjs.org/cargo-cp-artifact/-/cargo-cp-artifact-0.1.9.tgz",
+ "integrity": "sha512-6F+UYzTaGB+awsTXg0uSJA1/b/B3DDJzpKVRu0UmyI7DmNeaAl2RFHuTGIN6fEgpadRxoXGb7gbC1xo4C3IdyA==",
+ "license": "MIT",
+ "bin": {
+ "cargo-cp-artifact": "bin/cargo-cp-artifact.js"
+ }
+ },
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -4343,6 +4507,12 @@
"node": ">=10"
}
},
+ "node_modules/cjs-module-lexer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz",
+ "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==",
+ "license": "MIT"
+ },
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -4454,6 +4624,15 @@
"node": ">= 0.8"
}
},
+ "node_modules/commander": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+ "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/component-emitter": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
@@ -4752,6 +4931,12 @@
"node": ">= 8"
}
},
+ "node_modules/crypto-randomuuid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-randomuuid/-/crypto-randomuuid-1.0.0.tgz",
+ "integrity": "sha512-/RC5F4l1SCqD/jazwUF6+t34Cd8zTSAGZ7rvvZu1whZUhD2a5MOGKjSGowoGcpj/cbVZk1ZODIooJEQQq3nNAA==",
+ "license": "MIT"
+ },
"node_modules/csrf": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/csrf/-/csrf-3.1.0.tgz",
@@ -4887,6 +5072,77 @@
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
"integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
},
+ "node_modules/dc-polyfill": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/dc-polyfill/-/dc-polyfill-0.1.6.tgz",
+ "integrity": "sha512-UV33cugmCC49a5uWAApM+6Ev9ZdvIUMTrtCO9fj96TPGOQiea54oeO3tiEVdVeo3J9N2UdJEmbS4zOkkEA35uQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.17"
+ }
+ },
+ "node_modules/dd-trace": {
+ "version": "5.28.0",
+ "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.28.0.tgz",
+ "integrity": "sha512-jyF7JLx2Yw16MHcD97sYKXbVd7ZT1hKJ5/NkRRGeG9cgen5+d/ilIvfzgh2qRjeow+9a5ligoZoUOYJ3nYn9hw==",
+ "hasInstallScript": true,
+ "license": "(Apache-2.0 OR BSD-3-Clause)",
+ "dependencies": {
+ "@datadog/libdatadog": "^0.2.2",
+ "@datadog/native-appsec": "8.3.0",
+ "@datadog/native-iast-rewriter": "2.5.0",
+ "@datadog/native-iast-taint-tracking": "3.2.0",
+ "@datadog/native-metrics": "^3.0.1",
+ "@datadog/pprof": "5.4.1",
+ "@datadog/sketches-js": "^2.1.0",
+ "@isaacs/ttlcache": "^1.4.1",
+ "@opentelemetry/api": ">=1.0.0 <1.9.0",
+ "@opentelemetry/core": "^1.14.0",
+ "crypto-randomuuid": "^1.0.0",
+ "dc-polyfill": "^0.1.4",
+ "ignore": "^5.2.4",
+ "import-in-the-middle": "1.11.2",
+ "int64-buffer": "^0.1.9",
+ "istanbul-lib-coverage": "3.2.0",
+ "jest-docblock": "^29.7.0",
+ "koalas": "^1.0.2",
+ "limiter": "1.1.5",
+ "lodash.sortby": "^4.7.0",
+ "lru-cache": "^7.14.0",
+ "module-details-from-path": "^1.0.3",
+ "msgpack-lite": "^0.1.26",
+ "opentracing": ">=0.12.1",
+ "path-to-regexp": "^0.1.10",
+ "pprof-format": "^2.1.0",
+ "protobufjs": "^7.2.5",
+ "retry": "^0.13.1",
+ "rfdc": "^1.3.1",
+ "semver": "^7.5.4",
+ "shell-quote": "^1.8.1",
+ "tlhunter-sorted-set": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/dd-trace/node_modules/@opentelemetry/api": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz",
+ "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/dd-trace/node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/debug": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
@@ -4985,6 +5241,18 @@
"node": ">= 6"
}
},
+ "node_modules/delay": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz",
+ "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -5041,6 +5309,15 @@
"node": ">=8"
}
},
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/dev-null": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/dev-null/-/dev-null-0.1.1.tgz",
@@ -5217,6 +5494,31 @@
"node": ">= 0.8"
}
},
+ "node_modules/encoding-sniffer": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
+ "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "^0.6.3",
+ "whatwg-encoding": "^3.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
+ }
+ },
+ "node_modules/encoding-sniffer/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -5447,6 +5749,18 @@
"node": ">=6"
}
},
+ "node_modules/escape-goat": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz",
+ "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -5822,6 +6136,12 @@
"node": ">= 0.6"
}
},
+ "node_modules/event-lite": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/event-lite/-/event-lite-0.1.3.tgz",
+ "integrity": "sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw==",
+ "license": "MIT"
+ },
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
@@ -6942,11 +7262,30 @@
"node": ">=0.10.0"
}
},
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">= 4"
@@ -6969,6 +7308,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/import-in-the-middle": {
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.11.2.tgz",
+ "integrity": "sha512-gK6Rr6EykBcc6cVWRSBR5TWf8nn6hZMYSRYqCcHa0l0d1fPK7JSYo6+Mlmck76jIX9aL/IZ71c06U2VpFwl1zA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "acorn": "^8.8.2",
+ "acorn-import-attributes": "^1.9.5",
+ "cjs-module-lexer": "^1.2.2",
+ "module-details-from-path": "^1.0.3"
+ }
+ },
"node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@@ -7010,6 +7361,12 @@
"node": ">=8"
}
},
+ "node_modules/int64-buffer": {
+ "version": "0.1.10",
+ "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz",
+ "integrity": "sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==",
+ "license": "MIT"
+ },
"node_modules/internal-slot": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
@@ -7508,6 +7865,15 @@
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
},
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/iterator.prototype": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.3.tgz",
@@ -7588,6 +7954,18 @@
"integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==",
"dev": true
},
+ "node_modules/jest-docblock": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz",
+ "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==",
+ "license": "MIT",
+ "dependencies": {
+ "detect-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
"node_modules/jose": {
"version": "4.15.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
@@ -7754,6 +8132,69 @@
"node": ">=4.0"
}
},
+ "node_modules/juice": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/juice/-/juice-11.0.0.tgz",
+ "integrity": "sha512-sGF8hPz9/Wg+YXbaNDqc1Iuoaw+J/P9lBHNQKXAGc9pPNjCd4fyPai0Zxj7MRtdjMr0lcgk5PjEIkP2b8R9F3w==",
+ "license": "MIT",
+ "dependencies": {
+ "cheerio": "^1.0.0",
+ "commander": "^12.1.0",
+ "mensch": "^0.3.4",
+ "slick": "^1.12.2",
+ "web-resource-inliner": "^7.0.0"
+ },
+ "bin": {
+ "juice": "bin/juice"
+ },
+ "engines": {
+ "node": ">=18.17"
+ }
+ },
+ "node_modules/juice/node_modules/cheerio": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
+ "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
+ "license": "MIT",
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.1.0",
+ "encoding-sniffer": "^0.2.0",
+ "htmlparser2": "^9.1.0",
+ "parse5": "^7.1.2",
+ "parse5-htmlparser2-tree-adapter": "^7.0.0",
+ "parse5-parser-stream": "^7.1.2",
+ "undici": "^6.19.5",
+ "whatwg-mimetype": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18.17"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/juice/node_modules/htmlparser2": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
+ "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.1.0",
+ "entities": "^4.5.0"
+ }
+ },
"node_modules/jwa": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
@@ -7801,6 +8242,15 @@
"json-buffer": "3.0.1"
}
},
+ "node_modules/koalas": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/koalas/-/koalas-1.0.2.tgz",
+ "integrity": "sha512-RYhBbYaTTTHId3l6fnMZc3eGQNW6FVCqMG6AMwA5I1Mafr6AflaXeoi6x3xQuATRotGYRLk6+1ELZH4dstFNOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/kuler": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
@@ -7943,6 +8393,12 @@
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
},
+ "node_modules/lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==",
+ "license": "MIT"
+ },
"node_modules/logform": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz",
@@ -7964,8 +8420,7 @@
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
"integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==",
- "license": "Apache-2.0",
- "optional": true
+ "license": "Apache-2.0"
},
"node_modules/loose-envify": {
"version": "1.4.0",
@@ -8052,6 +8507,12 @@
"cssom": "^0.5.0"
}
},
+ "node_modules/mensch": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz",
+ "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==",
+ "license": "MIT"
+ },
"node_modules/merge-descriptors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
@@ -8179,6 +8640,12 @@
"mkdirp": "bin/cmd.js"
}
},
+ "node_modules/module-details-from-path": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz",
+ "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==",
+ "license": "MIT"
+ },
"node_modules/moment": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
@@ -8204,6 +8671,21 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
+ "node_modules/msgpack-lite": {
+ "version": "0.1.26",
+ "resolved": "https://registry.npmjs.org/msgpack-lite/-/msgpack-lite-0.1.26.tgz",
+ "integrity": "sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==",
+ "license": "MIT",
+ "dependencies": {
+ "event-lite": "^0.1.1",
+ "ieee754": "^1.1.8",
+ "int64-buffer": "^0.1.9",
+ "isarray": "^1.0.0"
+ },
+ "bin": {
+ "msgpack": "bin/msgpack"
+ }
+ },
"node_modules/multer": {
"version": "1.4.5-lts.1",
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz",
@@ -8249,6 +8731,12 @@
"node": ">= 0.4.0"
}
},
+ "node_modules/node-addon-api": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
+ "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
+ "license": "MIT"
+ },
"node_modules/node-eta": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/node-eta/-/node-eta-0.9.0.tgz",
@@ -8281,6 +8769,17 @@
"node": ">= 6.13.0"
}
},
+ "node_modules/node-gyp-build": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.9.0.tgz",
+ "integrity": "sha512-zLcTg6P4AbcHPq465ZMFNXx7XpKKJh+7kkN699NiQWisR2uWYOWNWqRHAmbnmKiL4e9aLSlmy5U7rEMUXV59+A==",
+ "license": "MIT",
+ "bin": {
+ "node-gyp-build": "bin.js",
+ "node-gyp-build-optional": "optional.js",
+ "node-gyp-build-test": "build-test.js"
+ }
+ },
"node_modules/node-mailjet": {
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/node-mailjet/-/node-mailjet-6.0.6.tgz",
@@ -8530,6 +9029,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/opentracing": {
+ "version": "0.14.7",
+ "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz",
+ "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/optionator": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
@@ -8550,7 +9058,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"yocto-queue": "^0.1.0"
@@ -8628,6 +9135,12 @@
"node": ">=6"
}
},
+ "node_modules/parenthesis": {
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/parenthesis/-/parenthesis-3.1.8.tgz",
+ "integrity": "sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw==",
+ "license": "MIT"
+ },
"node_modules/parse5": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
@@ -8651,6 +9164,18 @@
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
+ "node_modules/parse5-parser-stream": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+ "license": "MIT",
+ "dependencies": {
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -8660,6 +9185,12 @@
"node": ">= 0.8"
}
},
+ "node_modules/path-browserify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
+ "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
+ "license": "MIT"
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -8749,6 +9280,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/pprof-format": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pprof-format/-/pprof-format-2.1.0.tgz",
+ "integrity": "sha512-0+G5bHH0RNr8E5hoZo/zJYsL92MhkZjwrHp3O2IxmY8RJL9ooKeuZ8Tm0ZNBw5sGZ9TiM71sthTjWoR2Vf5/xw==",
+ "license": "MIT"
+ },
"node_modules/prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
@@ -8828,7 +9365,6 @@
"integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==",
"hasInstallScript": true,
"license": "BSD-3-Clause",
- "optional": true,
"dependencies": {
"@protobufjs/aspromise": "^1.1.2",
"@protobufjs/base64": "^1.1.2",
@@ -9154,7 +9690,6 @@
"resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
"integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
"license": "MIT",
- "optional": true,
"engines": {
"node": ">= 4"
}
@@ -9174,6 +9709,12 @@
"node": ">=14"
}
},
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "license": "MIT"
+ },
"node_modules/rimraf": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
@@ -9444,7 +9985,6 @@
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
"integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -9515,6 +10055,73 @@
"is-arrayish": "^0.3.1"
}
},
+ "node_modules/skia-canvas": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/skia-canvas/-/skia-canvas-2.0.0.tgz",
+ "integrity": "sha512-wpYkmr9mCxBme5HAnlm6YOEiuaN9tIm9CL+HN8e5AFD4K2FAJXCcWiWvc9+LM8jUXt+AyYXgiwUTBxdQ6P+PEg==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "dependencies": {
+ "@mapbox/node-pre-gyp": "^1.0.11",
+ "cargo-cp-artifact": "^0.1",
+ "glob": "^11.0.0",
+ "path-browserify": "^1.0.1",
+ "simple-get": "^4.0.1",
+ "string-split-by": "^1.0.0"
+ }
+ },
+ "node_modules/skia-canvas/node_modules/decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "mimic-response": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/skia-canvas/node_modules/mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/skia-canvas/node_modules/simple-get": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+ "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "decompress-response": "^6.0.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ }
+ },
"node_modules/slick": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz",
@@ -9907,6 +10514,15 @@
}
]
},
+ "node_modules/string-split-by": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/string-split-by/-/string-split-by-1.0.0.tgz",
+ "integrity": "sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A==",
+ "license": "MIT",
+ "dependencies": {
+ "parenthesis": "^3.1.5"
+ }
+ },
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
@@ -10342,6 +10958,12 @@
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
},
+ "node_modules/tlhunter-sorted-set": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/tlhunter-sorted-set/-/tlhunter-sorted-set-0.1.0.tgz",
+ "integrity": "sha512-eGYW4bjf1DtrHzUYxYfAcSytpOkA44zsr7G2n3PV7yOUR23vmkGe3LL4R+1jL9OsXtbsFOwe8XtbCrabeaEFnw==",
+ "license": "MIT"
+ },
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
@@ -10560,6 +11182,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/undici": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz",
+ "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.17"
+ }
+ },
"node_modules/undici-types": {
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
@@ -10631,6 +11262,15 @@
"uuid": "dist/bin/uuid"
}
},
+ "node_modules/valid-data-url": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz",
+ "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -10655,6 +11295,131 @@
"node": ">=6.0"
}
},
+ "node_modules/web-resource-inliner": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-7.0.0.tgz",
+ "integrity": "sha512-NlfnGF8MY9ZUwFjyq3vOUBx7KwF8bmE+ywR781SB0nWB6MoMxN4BA8gtgP1KGTZo/O/AyWJz7HZpR704eaj4mg==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^4.1.1",
+ "escape-goat": "^3.0.0",
+ "htmlparser2": "^5.0.0",
+ "mime": "^2.4.6",
+ "valid-data-url": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/dom-serializer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/dom-serializer/node_modules/domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/domhandler": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz",
+ "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/domutils/node_modules/domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "license": "BSD-2-Clause",
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/htmlparser2": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-5.0.1.tgz",
+ "integrity": "sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^3.3.0",
+ "domutils": "^2.4.2",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/htmlparser2?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/mime": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
@@ -10683,6 +11448,30 @@
"node": ">=0.8.0"
}
},
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-encoding/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/whatwg-mimetype": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
@@ -11063,7 +11852,6 @@
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=10"
diff --git a/package.json b/package.json
index 890a346f1..cd9ec1870 100644
--- a/package.json
+++ b/package.json
@@ -41,6 +41,7 @@
"cors": "2.8.5",
"crisp-status-reporter": "^1.2.2",
"csrf": "^3.1.0",
+ "dd-trace": "^5.28.0",
"dinero.js": "^1.9.1",
"dotenv": "^16.4.5",
"express": "^4.21.1",
@@ -51,6 +52,7 @@
"intuit-oauth": "^4.1.3",
"ioredis": "^5.4.1",
"json-2-csv": "^5.5.6",
+ "juice": "^11.0.0",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"moment-timezone": "^0.5.46",
@@ -62,6 +64,7 @@
"recursive-diff": "^1.0.9",
"redis": "^4.7.0",
"rimraf": "^6.0.1",
+ "skia-canvas": "^2.0.0",
"soap": "^1.1.6",
"socket.io": "^4.8.1",
"socket.io-adapter": "^2.5.5",
diff --git a/server.js b/server.js
index e72dbf530..d37ef2b0e 100644
--- a/server.js
+++ b/server.js
@@ -4,6 +4,14 @@ require("dotenv").config({
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
});
+if (process.env.NODE_ENV) {
+ const tracer = require("dd-trace").init({
+ profiling: true,
+ env: process.env.NODE_ENV,
+ service: "bodyshop-api"
+ });
+}
+
const cors = require("cors");
const http = require("http");
const Redis = require("ioredis");
diff --git a/server/accounting/qbo/qbo-receivables.js b/server/accounting/qbo/qbo-receivables.js
index f57c6711a..c7c74928b 100644
--- a/server/accounting/qbo/qbo-receivables.js
+++ b/server/accounting/qbo/qbo-receivables.js
@@ -328,6 +328,7 @@ async function InsertOwner(oauthClient, qbo_realmId, req, job, isThreeTier, pare
PostalCode: job.ownr_zip,
CountrySubDivisionCode: job.ownr_st
},
+ ...(job.ownr_ea ? { BillEmail: { Address: job.ownr_ea.trim() } } : {}),
...(isThreeTier
? {
Job: true,
@@ -395,7 +396,7 @@ async function InsertJob(oauthClient, qbo_realmId, req, job, parentTierRef) {
PostalCode: job.ownr_zip,
CountrySubDivisionCode: job.ownr_st
},
-
+ ...(job.ownr_ea ? { BillEmail: { Address: job.ownr_ea.trim() } } : {}),
Job: true,
ParentRef: {
value: parentTierRef.Id
@@ -556,7 +557,8 @@ async function InsertInvoice(oauthClient, qbo_realmId, req, job, bodyshop, paren
Line3: `${job.ownr_city || ""}, ${job.ownr_st || ""} ${job.ownr_zip || ""}`.trim(),
Line2: job.ownr_addr1 || "",
Line1: `${job.ownr_fn || ""} ${job.ownr_ln || ""} ${job.ownr_co_nm || ""}`
- }
+ },
+ ...(job.ownr_ea ? { BillEmail: { Address: job.ownr_ea.trim() } } : {})
};
logger.log("qbo-receivable-objectlog", "DEBUG", req.user.email, job.id, {
@@ -673,7 +675,8 @@ async function InsertInvoiceMultiPayerInvoice(
Line3: `${job.ownr_city || ""}, ${job.ownr_st || ""} ${job.ownr_zip || ""}`.trim(),
Line2: job.ownr_addr1 || "",
Line1: `${job.ownr_fn || ""} ${job.ownr_ln || ""} ${job.ownr_co_nm || ""}`
- }
+ },
+ ...(job.ownr_ea ? { BillEmail: { Address: job.ownr_ea.trim() } } : {})
};
logger.log("qbo-receivable-objectlog", "DEBUG", req.user.email, job.id, {
diff --git a/server/middleware/validateCanvasInputMiddleware.js b/server/middleware/validateCanvasInputMiddleware.js
new file mode 100644
index 000000000..a03bb12ec
--- /dev/null
+++ b/server/middleware/validateCanvasInputMiddleware.js
@@ -0,0 +1,32 @@
+const { isObject } = require("lodash");
+
+const validateCanvasInputMiddleware = (req, res, next) => {
+ const { values, keys, override, w, h } = req.body;
+
+ if (!Array.isArray(values) || !Array.isArray(keys)) {
+ return res.status(400).send("Invalid input: 'values' and 'keys' must be arrays.");
+ }
+
+ if (values.some((value) => typeof value !== "number")) {
+ return res.status(400).send("Invalid input: 'values' must be an array of numbers.");
+ }
+
+ if (keys.some((key) => typeof key !== "string")) {
+ return res.status(400).send("Invalid input: 'keys' must be an array of strings.");
+ }
+
+ if (override && !isObject(override)) {
+ return res.status(400).send("Override must be an object");
+ }
+
+ if (w && (!Number.isFinite(w) || w <= 0)) {
+ return res.status(400).send("Width must be a positive number");
+ }
+ if (h && (!Number.isFinite(h) || h <= 0)) {
+ return res.status(400).send("Height must be a positive number");
+ }
+
+ next(); // Proceed to the next middleware or route handler
+};
+
+module.exports = validateCanvasInputMiddleware;
diff --git a/server/render/canvas-handler.js b/server/render/canvas-handler.js
index 0af2a7f53..5b810dd73 100644
--- a/server/render/canvas-handler.js
+++ b/server/render/canvas-handler.js
@@ -1,43 +1,31 @@
const { createCanvas } = require("canvas");
+const { Canvas, FontLibrary } = require("skia-canvas");
const Chart = require("chart.js/auto");
-const logger = require("../utils/logger");
const { backgroundColors, borderColors } = require("./canvas-colors");
-const { isObject, defaultsDeep, isNumber } = require("lodash");
+const { defaultsDeep, isNumber } = require("lodash");
-exports.canvastest = function (req, res) {
- //console.log("Incoming test request.", req);
- res.status(200).send("OK");
-};
+const CANVAS_QUEUE_LIMIT = 100;
-exports.canvas = function (req, res) {
- const { w, h, values, keys, override } = req.body;
- //console.log("Incoming Canvas Request:", w, h, values, keys, override);
- logger.log("inbound-canvas-creation", "debug", "jsr", null, { w, h, values, keys, override });
- // Gate required values
- if (!values || !keys) {
- res.status(400).send("Missing required data");
- return;
- }
+let isProcessing = false;
+const requestQueue = [];
- // Override must be an object if it exists
- if (override && !isObject(override)) {
- res.status(400).send("Override must be an object");
- return;
- }
+try {
+ FontLibrary.use("Montserrat", [
+ "/usr/share/fonts/Montserrat-Regular.ttf",
+ "/usr/share/fonts/Montserrat-Bold.ttf",
+ "/usr/share/fonts/Montserrat-Italic.ttf"
+ ]);
+} catch (error) {
+ console.error(
+ "Error loading fonts Skia Canvas Fonts, please be sure to install Montserrat font package",
+ error.message
+ );
+}
- // Set the default Width and Height
- let [width, height] = [500, 275];
-
- // Allow for custom width and height
- if (isNumber(w)) {
- width = w;
- }
- if (isNumber(h)) {
- height = h;
- }
-
- const configuration = {
+// Utility to create a chart configuration
+const getChartConfiguration = (keys, values, override) => {
+ const defaultConfiguration = {
type: "doughnut",
data: {
labels: keys,
@@ -53,6 +41,7 @@ exports.canvas = function (req, res) {
options: {
devicePixelRatio: 4,
responsive: false,
+ animation: false,
maintainAspectRatio: true,
circumference: 180,
rotation: -90,
@@ -73,21 +62,88 @@ exports.canvas = function (req, res) {
}
};
- // If we have a valid override object, merge it with the default configuration object.
- // This allows for you to override the default configuration with a custom one.
- const defaults = () => {
- if (!override || !isObject(override)) {
- return configuration;
- }
- return defaultsDeep(override, configuration);
- };
-
- res.status(200).send(
- (() => {
- const canvas = createCanvas(width, height);
- const ctx = canvas.getContext("2d");
- new Chart(ctx, defaults());
- return canvas.toDataURL();
- })()
- );
+ return defaultsDeep(override || {}, defaultConfiguration);
+};
+
+const processCanvasRequest = async (req, res, isSkia = false) => {
+ const { logger } = req;
+ const { w, h, values, keys, override } = req.body;
+
+ logger.log("inbound-canvas-creation", "debug", "jsr", null, { w, h, values, keys, override });
+
+ // Default width and height
+ const width = isNumber(w) && w > 0 ? w : 500;
+ const height = isNumber(h) && h > 0 ? h : 275;
+
+ const configuration = getChartConfiguration(keys, values, override);
+
+ // Placeholders to allow fine control over GAC
+ let canvas = null;
+ let ctx = null;
+ let chart = null;
+ let chartImage = null;
+
+ try {
+ // Create the canvas
+ canvas = isSkia ? new Canvas(width, height) : createCanvas(width, height);
+ ctx = canvas.getContext("2d");
+
+ // Render the chart
+ chart = new Chart(ctx, configuration);
+
+ // Generate and send the image
+ chartImage = isSkia ? (await canvas.toBuffer("image/png")).toString("base64") : canvas.toDataURL();
+
+ res.status(200).send(isSkia ? `data:image/png;base64,${chartImage}` : chartImage);
+ } catch (error) {
+ // Log the error and send the response
+ logger.log("canvas-error", "error", "jsr", null, { error: error.message });
+ res.status(500).send("Failed to generate canvas.");
+ } finally {
+ // Cleanup resources
+ if (chart) {
+ chart.destroy();
+ }
+ ctx = null; // Explicitly nullify for garbage collection
+ canvas = null; // Explicitly nullify for garbage collection
+ chartImage = null;
+ }
+};
+
+const enqueueRequest = (req, res, isSkia) => {
+ if (requestQueue.length >= CANVAS_QUEUE_LIMIT) {
+ res.status(503).send("Server is busy. Please try again later.");
+ return false;
+ }
+ requestQueue.push({ req, res, isSkia });
+ req.logger.log("inbound-canvas-creation-queue", "debug", "jsr", null, { queue: requestQueue.length });
+ return true;
+};
+
+const processNextInQueue = async () => {
+ while (requestQueue.length > 0) {
+ const { req, res, isSkia } = requestQueue.shift();
+ try {
+ await processCanvasRequest(req, res, isSkia);
+ } catch (err) {
+ console.error("canvas-queue-error", "error", "jsr", null, { error: err.message });
+ }
+ }
+ isProcessing = false;
+};
+
+exports.canvastest = function (req, res) {
+ res.status(200).send("OK");
+};
+
+exports.canvas = async (req, res) => {
+ if (isProcessing || !enqueueRequest(req, res, false)) return;
+ isProcessing = true;
+ processNextInQueue().catch((err) => console.error("canvas-processing-error", { error: err.message }));
+};
+
+exports.canvasSkia = async (req, res) => {
+ if (isProcessing || !enqueueRequest(req, res, true)) return;
+ isProcessing = true;
+ processNextInQueue().catch((err) => console.error("canvas-processing-error", { error: err.message }));
};
diff --git a/server/render/inlinecss.js b/server/render/inlinecss.js
index 07fb68052..74700b210 100644
--- a/server/render/inlinecss.js
+++ b/server/render/inlinecss.js
@@ -3,24 +3,36 @@ require("dotenv").config({
path: path.resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`)
});
const logger = require("../utils/logger");
-const inlineCssTool = require("inline-css");
+//const inlineCssTool = require("inline-css");
+const juice = require("juice");
-exports.inlinecss = (req, res) => {
+exports.inlinecss = async (req, res) => {
//Perform request validation
-
logger.log("email-inline-css", "DEBUG", req.user.email, null, null);
const { html, url } = req.body;
-
- inlineCssTool(html, { url: url })
- .then((inlinedHtml) => {
- res.send(inlinedHtml);
- })
- .catch((error) => {
- logger.log("email-inline-css-error", "ERROR", req.user.email, null, {
- error
- });
-
- res.send(error);
+ try {
+ const inlinedHtml = juice(html, {
+ applyAttributesTableElements: false,
+ preserveMediaQueries: false,
+ applyWidthAttributes: false
});
+ res.send(inlinedHtml);
+ } catch (error) {
+ logger.log("email-inline-css-error", "ERROR", req.user.email, null, {
+ error
+ });
+ res.send(error.message);
+ }
+
+ // inlineCssTool(html, { url: url })
+ // .then((inlinedHtml) => {
+ // res.send(inlinedHtml);
+ // })
+ // .catch((error) => {
+ // logger.log("email-inline-css-error", "ERROR", req.user.email, null, {
+ // error
+ // });
+
+ // });
};
diff --git a/server/routes/renderRoutes.js b/server/routes/renderRoutes.js
index 13288d989..c1423f698 100644
--- a/server/routes/renderRoutes.js
+++ b/server/routes/renderRoutes.js
@@ -2,10 +2,12 @@ const express = require("express");
const router = express.Router();
const { inlinecss } = require("../render/inlinecss");
const validateFirebaseIdTokenMiddleware = require("../middleware/validateFirebaseIdTokenMiddleware");
-const { canvas } = require("../render/canvas-handler");
+const { canvas, canvasSkia } = require("../render/canvas-handler");
+const validateCanvasInputMiddleware = require("../middleware/validateCanvasInputMiddleware");
// Define the route for inline CSS rendering
router.post("/inlinecss", validateFirebaseIdTokenMiddleware, inlinecss);
-router.post("/canvas", validateFirebaseIdTokenMiddleware, canvas);
+router.post("/canvas", [validateFirebaseIdTokenMiddleware, validateCanvasInputMiddleware], canvas);
+router.post("/canvas-skia", [validateFirebaseIdTokenMiddleware, validateCanvasInputMiddleware], canvasSkia);
module.exports = router;