diff --git a/packages/customWidgets/signature-web/.prettierignore b/packages/customWidgets/signature-web/.prettierignore deleted file mode 100644 index 1b45dc70bf..0000000000 --- a/packages/customWidgets/signature-web/.prettierignore +++ /dev/null @@ -1,4 +0,0 @@ -dist -node_modules -tests - diff --git a/packages/customWidgets/signature-web/CHANGELOG.md b/packages/customWidgets/signature-web/CHANGELOG.md deleted file mode 100644 index 27766cd15d..0000000000 --- a/packages/customWidgets/signature-web/CHANGELOG.md +++ /dev/null @@ -1,27 +0,0 @@ -# Changelog - -All notable changes to this widget will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -## [1.0.8] - 2026-02-20 - -### Fixed - -- We fixed and issue with the widget not working correctly in some newer version of Studio Pro. - -### Added - -- We added a license file and a readme documenting all open source dependencies used in this package. - -## [1.0.7] - 2025-01-15 - -### Changed - -- We updated the light and dark icons and tiles for the widget. - -### Fixed - -- We fixed an issue where the widget was failing to save signatures on Hybrid apps. diff --git a/packages/customWidgets/signature-web/README.md b/packages/customWidgets/signature-web/README.md deleted file mode 100644 index 3d5647cf4c..0000000000 --- a/packages/customWidgets/signature-web/README.md +++ /dev/null @@ -1 +0,0 @@ -Please see [Signature](https://docs.mendix.com/appstore/widgets/signature) in the Mendix documentation for details. diff --git a/packages/customWidgets/signature-web/cypress/.eslintrc.json b/packages/customWidgets/signature-web/cypress/.eslintrc.json deleted file mode 100644 index e98e5a04cb..0000000000 --- a/packages/customWidgets/signature-web/cypress/.eslintrc.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "root": true, - "extends": ["@mendix/eslint-config-web-widgets/cypress"] -} diff --git a/packages/customWidgets/signature-web/cypress/integration/Signature.spec.js b/packages/customWidgets/signature-web/cypress/integration/Signature.spec.js deleted file mode 100644 index f6de512d27..0000000000 --- a/packages/customWidgets/signature-web/cypress/integration/Signature.spec.js +++ /dev/null @@ -1,11 +0,0 @@ -describe("Signature", () => { - it("renders canvas", () => { - cy.visit("/"); - cy.get(".widget-signature-canvas").should("be.visible"); - }); - - it("renders grid", () => { - cy.visit("/p/GridSize"); - cy.get(".widget-signature-grid").get("svg").should("be.visible"); - }); -}); diff --git a/packages/customWidgets/signature-web/cypress/support/e2e.js b/packages/customWidgets/signature-web/cypress/support/e2e.js deleted file mode 100644 index 5f49ab7003..0000000000 --- a/packages/customWidgets/signature-web/cypress/support/e2e.js +++ /dev/null @@ -1 +0,0 @@ -import "../../../../../configs/e2e/cypress/support/command"; diff --git a/packages/customWidgets/signature-web/dependencies.json b/packages/customWidgets/signature-web/dependencies.json deleted file mode 100644 index 3184818562..0000000000 --- a/packages/customWidgets/signature-web/dependencies.json +++ /dev/null @@ -1 +0,0 @@ -[{ "classnames": { "version": "2.5.1", "url": null } }, { "signature_pad": { "version": "5.1.3", "url": null } }] diff --git a/packages/customWidgets/signature-web/dependencies.txt b/packages/customWidgets/signature-web/dependencies.txt deleted file mode 100644 index 532a7495d2..0000000000 --- a/packages/customWidgets/signature-web/dependencies.txt +++ /dev/null @@ -1,67 +0,0 @@ -Name: classnames -Version: 2.5.1 -License: MIT -Private: false -Description: A simple utility for conditionally joining classNames together -Repository: git+https://github.com/JedWatson/classnames.git -Author: Jed Watson -Homepage: https://github.com/JedWatson/classnames#readme -License Copyright: -=== - -The MIT License (MIT) - -Copyright (c) 2018 Jed Watson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ---- - -Name: signature_pad -Version: 5.1.3 -License: MIT -Private: false -Description: Library for drawing smooth signatures. -Repository: git+https://github.com/szimek/signature_pad.git -Author: Szymon Nowak (https://github.com/szimek) -Homepage: https://github.com/szimek/signature_pad -License Copyright: -=== - -MIT License - -Copyright (c) 2018 Szymon Nowak - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/customWidgets/signature-web/package.json b/packages/customWidgets/signature-web/package.json deleted file mode 100644 index 2e16f88806..0000000000 --- a/packages/customWidgets/signature-web/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "@mendix/signature-web", - "widgetName": "Signature", - "version": "1.0.8", - "description": "A signature pad for capturing signatures", - "copyright": "© Mendix Technology BV 2025. All rights reserved.", - "license": "Apache-2.0", - "repository": { - "type": "git", - "url": "https://github.com/mendix/web-widgets.git" - }, - "mxpackage": { - "name": "Signature", - "type": "widget", - "mpkName": "Signature.mpk" - }, - "packagePath": "com.mendix.widget.custom", - "marketplace": { - "minimumMXVersion": "7.13.1", - "appName": "Signature", - "appNumber": 107984 - }, - "testProject": { - "githubUrl": "https://github.com/mendix/testProjects", - "branchName": "signature-web" - }, - "scripts": { - "build": "ts-node --project scripts/tsconfig.json scripts/build.ts development", - "create-gh-release": "rui-create-gh-release", - "format": "prettier --ignore-path ./node_modules/@mendix/prettier-config-web-widgets/global-prettierignore --write .", - "lint": "eslint src/ package.json", - "publish-marketplace": "rui-publish-marketplace", - "release": "node scripts/generate-dependencies.js && ts-node --project scripts/tsconfig.json scripts/build.ts production", - "test": "echo 'TODO: Migrate tests'", - "update-changelog": "rui-update-changelog-widget", - "verify": "rui-verify-package-format" - }, - "dependencies": { - "classnames": "^2.5.1", - "signature_pad": "5.1.3" - }, - "devDependencies": { - "@mendix/automation-utils": "workspace:*", - "@mendix/eslint-config-web-widgets": "workspace:*", - "@mendix/pluggable-widgets-tools": "*", - "@mendix/prettier-config-web-widgets": "workspace:*", - "copy-webpack-plugin": "^11.0.0", - "css-loader": "^6.7.3", - "eslint": "^9.39.3", - "jest-canvas-mock": "^2.4.0", - "loader-utils": "1.4.2", - "mendix-client": "^7.15.8", - "mini-css-extract-plugin": "^2.7.2", - "sass-loader": "^13.2.0", - "to-string-loader": "^1.1.6", - "ts-loader": "^9.4.2", - "ts-node": "^10.9.2", - "typescript": "<5.2.0", - "webpack": "^5.75.0", - "webpack-cli": "^5.0.1" - }, - "jest": { - "setupFiles": [ - "jest-canvas-mock" - ] - } -} diff --git a/packages/customWidgets/signature-web/scripts/build.ts b/packages/customWidgets/signature-web/scripts/build.ts deleted file mode 100755 index 766f3b4a88..0000000000 --- a/packages/customWidgets/signature-web/scripts/build.ts +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env ts-node-script - -import { cp, mkdir, zip, exec } from "@mendix/automation-utils/shell"; -import { logStep, removeDist, runWidgetSteps, WidgetStepParams } from "@mendix/automation-utils/steps"; -import { dirname, join } from "node:path"; - -const [, , env] = process.argv; -const isProd = env === "production"; -const copyToProject = !isProd && process.env.MX_PROJECT_PATH; - -async function createMPK({ config }: WidgetStepParams): Promise { - logStep("Create mpk"); - const { paths, output } = config; - mkdir("-p", dirname(output.files.mpk)); - await zip(paths.tmp, output.files.mpk); -} - -async function main(): Promise { - await runWidgetSteps({ - packagePath: process.cwd(), - steps: [ - removeDist, - async () => { - logStep("Bundling"); - await exec(`webpack -c webpack.config.js`); - }, - createMPK, - async ({ config }) => { - if (copyToProject) { - logStep("Copy widget to targetProject"); - const dir = join(config.paths.targetProject, "widgets"); - mkdir("-p", dir); - cp(config.output.files.mpk, dir); - } - } - ] - }); -} - -main().catch(err => { - console.error(err); - process.exit(1); -}); diff --git a/packages/customWidgets/signature-web/scripts/generate-dependencies.js b/packages/customWidgets/signature-web/scripts/generate-dependencies.js deleted file mode 100755 index d094ec90a5..0000000000 --- a/packages/customWidgets/signature-web/scripts/generate-dependencies.js +++ /dev/null @@ -1,268 +0,0 @@ -#!/usr/bin/env node - -const { execSync } = require("child_process"); -const fs = require("fs"); -const path = require("path"); - -/** - * Generate dependencies.json and dependencies.txt from package.json using pnpm to get actual installed versions - * - * Usage: node generate-dependencies.js [path-to-package.json] - */ - -function getPackageJsonPath() { - const arg = process.argv[2]; - if (arg) { - return path.resolve(arg); - } - // Default to package.json in current directory - return path.resolve(process.cwd(), "package.json"); -} - -function readPackageJson(packageJsonPath) { - if (!fs.existsSync(packageJsonPath)) { - console.error(`Error: package.json not found at ${packageJsonPath}`); - process.exit(1); - } - - try { - const content = fs.readFileSync(packageJsonPath, "utf8"); - return JSON.parse(content); - } catch (error) { - console.error(`Error reading or parsing package.json: ${error.message}`); - process.exit(1); - } -} - -function getInstalledVersion(packageName, packageDir) { - try { - // Use pnpm list to get the actual installed version - // --depth 0 to only show direct dependencies - // --json for parseable output - const output = execSync(`pnpm list "${packageName}" --depth 0 --json`, { - cwd: packageDir, - encoding: "utf8", - stdio: ["pipe", "pipe", "pipe"] - }); - - const result = JSON.parse(output); - - // pnpm list returns an array of project results - if (Array.isArray(result) && result.length > 0) { - const dependencies = result[0].dependencies || {}; - if (dependencies[packageName]) { - const version = dependencies[packageName].version; - // Remove any leading 'v' if present - return version.replace(/^v/, ""); - } - } - - return null; - } catch (error) { - // If pnpm list fails, try reading from node_modules - try { - const nodeModulesPath = path.join(packageDir, "node_modules", packageName, "package.json"); - if (fs.existsSync(nodeModulesPath)) { - const pkgContent = JSON.parse(fs.readFileSync(nodeModulesPath, "utf8")); - return pkgContent.version; - } - } catch (innerError) { - // Ignore - } - - console.warn(`Warning: Could not determine installed version for ${packageName}`); - return null; - } -} - -function getPackageMetadata(packageName, version) { - try { - // Use pnpm view to get package metadata from npm registry - const output = execSync(`pnpm view "${packageName}@${version}" --json`, { - encoding: "utf8", - stdio: ["pipe", "pipe", "pipe"] - }); - - const metadata = JSON.parse(output); - - return { - name: metadata.name || packageName, - version: metadata.version || version, - license: metadata.license || "UNKNOWN", - private: metadata.private || false, - description: metadata.description || "", - repository: formatRepository(metadata.repository), - author: metadata.author || "", - homepage: metadata.homepage || "" - }; - } catch (error) { - console.warn(`Warning: Could not fetch metadata for ${packageName}@${version}`); - return { - name: packageName, - version: version, - license: "UNKNOWN", - private: false, - description: "", - repository: "", - author: "", - homepage: "" - }; - } -} - -function formatRepository(repo) { - if (!repo) return "undefined"; - if (typeof repo === "string") return repo; - if (repo.url) return repo.url; - return "undefined"; -} - -function getLicenseText(packageName, version, packageDir) { - // Try to find LICENSE file in node_modules - const possiblePaths = [ - path.join(packageDir, "node_modules", packageName, "LICENSE"), - path.join(packageDir, "node_modules", packageName, "LICENSE.md"), - path.join(packageDir, "node_modules", packageName, "LICENSE.txt"), - path.join(packageDir, "node_modules", packageName, "license"), - path.join(packageDir, "node_modules", packageName, "license.md"), - path.join(packageDir, "node_modules", packageName, "license.txt") - ]; - - for (const licensePath of possiblePaths) { - if (fs.existsSync(licensePath)) { - try { - return fs.readFileSync(licensePath, "utf8").trim(); - } catch (error) { - // Continue to next path - } - } - } - - // If not found in node_modules, try pnpm's virtual store - const pnpmStorePath = path.join( - packageDir, - "..", - "..", - "node_modules", - ".pnpm", - `${packageName}@${version}`, - "node_modules", - packageName - ); - - for (const filename of ["LICENSE", "LICENSE.md", "LICENSE.txt", "license", "license.md", "license.txt"]) { - const licensePath = path.join(pnpmStorePath, filename); - if (fs.existsSync(licensePath)) { - try { - return fs.readFileSync(licensePath, "utf8").trim(); - } catch (error) { - // Continue - } - } - } - - return null; -} - -function generateDependenciesJson(packageJsonPath) { - const packageJson = readPackageJson(packageJsonPath); - const packageDir = path.dirname(packageJsonPath); - - const dependencies = packageJson.dependencies || {}; - const dependencyNames = Object.keys(dependencies); - - if (dependencyNames.length === 0) { - console.log("No dependencies found in package.json"); - return { jsonData: [], detailedData: [] }; - } - - console.log(`Found ${dependencyNames.length} dependencies, resolving versions...`); - - const jsonData = []; - const detailedData = []; - - for (const depName of dependencyNames) { - const version = getInstalledVersion(depName, packageDir); - - if (version) { - // Add to JSON format - jsonData.push({ - [depName]: { - version: version, - url: null - } - }); - - // Fetch metadata for TXT format - const metadata = getPackageMetadata(depName, version); - const licenseText = getLicenseText(depName, version, packageDir); - - detailedData.push({ - ...metadata, - licenseText - }); - - console.log(` ✓ ${depName}@${version}`); - } else { - console.warn(` ✗ ${depName} - version not found`); - } - } - - return { jsonData, detailedData }; -} - -function generateDependenciesTxt(detailedData) { - const sections = []; - - for (const dep of detailedData) { - const lines = []; - - lines.push(`Name: ${dep.name}`); - lines.push(`Version: ${dep.version}`); - lines.push(`License: ${dep.license}`); - lines.push(`Private: ${dep.private}`); - lines.push(`Description: ${dep.description}`); - lines.push(`Repository: ${dep.repository}`); - - if (dep.author) { - lines.push(`Author: ${dep.author}`); - } - - if (dep.homepage) { - lines.push(`Homepage: ${dep.homepage}`); - } - - if (dep.licenseText) { - lines.push("License Copyright:"); - lines.push("==="); - lines.push(""); - lines.push(dep.licenseText); - } - - sections.push(lines.join("\n")); - } - - return sections.join("\n\n---\n\n"); -} - -function main() { - const packageJsonPath = getPackageJsonPath(); - const jsonOutputPath = path.join(process.cwd(), "dependencies.json"); - const txtOutputPath = path.join(process.cwd(), "dependencies.txt"); - - console.log(`Reading package.json from: ${packageJsonPath}`); - - const { jsonData, detailedData } = generateDependenciesJson(packageJsonPath); - - // Write dependencies.json - fs.writeFileSync(jsonOutputPath, JSON.stringify(jsonData)); - console.log(`\n✓ Generated dependencies.json at: ${jsonOutputPath}`); - console.log(` Total dependencies: ${jsonData.length}`); - - // Write dependencies.txt - const txtContent = generateDependenciesTxt(detailedData); - fs.writeFileSync(txtOutputPath, txtContent + "\n"); - console.log(`✓ Generated dependencies.txt at: ${txtOutputPath}`); -} - -main(); diff --git a/packages/customWidgets/signature-web/scripts/tsconfig.json b/packages/customWidgets/signature-web/scripts/tsconfig.json deleted file mode 100644 index eeb4a6cc48..0000000000 --- a/packages/customWidgets/signature-web/scripts/tsconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "@mendix/automation-utils/tsconfig" -} diff --git a/packages/customWidgets/signature-web/src/Signature.webmodeler.ts b/packages/customWidgets/signature-web/src/Signature.webmodeler.ts deleted file mode 100644 index a8115fd77b..0000000000 --- a/packages/customWidgets/signature-web/src/Signature.webmodeler.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Component, createElement, ReactNode } from "react"; -import Utils from "./utils/Utils"; -import { SignatureContainerProps } from "./components/SignatureContainer"; -import { Signature, SignatureProps } from "./components/Signature"; - -declare function require(name: string): string; - -type VisibilityMap = { - [P in keyof T]: any; -}; - -export class preview extends Component { - render(): ReactNode { - return createElement(Signature, this.transformProps(this.props)); - } - - private transformProps(props: SignatureContainerProps): SignatureProps { - return { - className: props.class, - heightUnit: props.heightUnit, - height: props.height, - widthUnit: props.widthUnit, - width: props.width, - gridCellWidth: props.gridCellWidth, - gridCellHeight: props.gridCellHeight, - gridBorderColor: props.gridBorderColor, - gridBorderWidth: props.gridBorderWidth, - penColor: props.penColor, - penType: props.penType, - showGrid: props.showGrid, - clearSignature: false, - readOnly: false, - wrapperStyle: Utils.parseStyle(props.style) - }; - } -} - -export function getPreviewCss(): string { - return require("./ui/Signature.scss"); -} - -export function getVisibleProperties( - valueMap: SignatureContainerProps, - visibilityMap: VisibilityMap -): VisibilityMap { - if (!valueMap.showGrid) { - visibilityMap.gridBorderColor = false; - visibilityMap.gridBorderWidth = false; - visibilityMap.gridCellHeight = false; - visibilityMap.gridCellWidth = false; - } - - return visibilityMap; -} diff --git a/packages/customWidgets/signature-web/src/Signature.xml b/packages/customWidgets/signature-web/src/Signature.xml deleted file mode 100644 index bbafe26d42..0000000000 --- a/packages/customWidgets/signature-web/src/Signature.xml +++ /dev/null @@ -1,87 +0,0 @@ - - - Signature - A signature pad for capturing signatures - - iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAACHZJREFUeAHtmwls1FUex+dNW2ZgVgSvGneDeCVKjUc8MGrchF0PioKoBWwR8apoYNWK7rq7WbqoKJj1IijWKLW25WiiQBXwTjRGSDxjC7XqxljZuFaF6NLOtDPz389vmPffN68zZYzjHOy85OX9jvef+X2/7/eu/7QeT7EUGSgyUGSgyECRgf9bBlShI587d66/r69vJTjOpbaXlZUtamlp+SFdXN50O+Zrvz179jzgOM7V1GOotw4ODu6oqqqanm68BZ0BM2fOPAPQW6lDBlIptR77/La2tp3DkTHkweE655Ovvr6+NBqNNiQDL3FivxQStkPSzcgpB7pgCdi+ffut4DzFHBQAD5o6wEdD0gpIeAHCkmJNajQ/JB/l6urqI4mr3owN8M0lJSWnYnvHtIsMEZVdXV1n2XbRC5IAFroVgAoYgL5Hr1u9enVnRUWF7AYbDF9M9Hq9vbZN9IIjgBX+CuKeYoG5k8UuBrC7u3s8vgss/8bW1tZPLVtMLSgCampqRpPqj1hA3lq3bt3T2hYOhx9DHql1aXnmghkzZlxu2rRcUASQ+ktI9SN08LQDpPaNAHTEBsgr8V9o+GMiNj+1ZdasWafbvoIhgOAnEvxNJgCAL127du0OsXEiHEPzkOm3ZF8kErnbshXGGhDf859gFM0B+3TUqFFLNCBOhEvxl2udNgRBfzR0Ec+x9MIgoKOjYxXgTjaDZ8u7qbGxMSg2Ul+A3WD6AX8v9UvL1mfqIpuM2r680En98QCpsYIJQ8ihYqutrS1DfgLRPO117d69+0EOQW6GxJ/fGG/dJu8JYN7Kqm6Ck+DlGNzKlrht165di9ErxBgvDoTdOHbsWMmIo7QR2yBELdO6bku1kI8tAGcS1+QUsQkpZ8ar2wWgqwD6EfU517hXWMlZ4TPLlr9TIL6qP2wGDKiQqSeRe+lzByTche9g7Uf/gTVDMmVIydspwEuO+4n2cCPiAYDIQrgIkGHD7or46wAawHCLa9wrLOWY/K1li6l5SQAL39mArDUDBtx9pPAn1MXIJ+KLmn7krzkRNrM23MOzfsO3Ez3l+SDvCNB7PgDchQ/A3eXl5fdpUOgLkc3Ywz6fbwrXXsmQ2bqftPT9G6T1mzZTNj/EtOdM7uzsXMiIyQibZd7y5ctj85+F8Vz815lOQP69ubn5fUZ/GT4XE/aOCRMmNJp9bdll2XbkQueefzTn/Q6+273MAOIZUnuuxCN7Ptveh4gTRJeCfweg5cXIb6kvi00X7gmVHJU3az1Z67KVzJltm32TA9y3fr//dh0Hhxs52rrgkR25DEHQILK9x7++L/DyuXlzDkhxk1vY1NT0nQRK6h9L8xeRdYGgp9asWfMWh6WrsEkW6CK3wzu1MlybF1NA9ny2vS5SuVwHC7g3GNlJWoegV/D/Xuu031BPCAQCfVyEPkEeZ/haWfjs47Ph/p+YF1MgxU1ung4T8LMt8B5Svw6Q3/PsAvqZ4EOcBRIyRX9OsjbnBCS7yRHoEuZvtwRM6h8E+Aet4F/B3xK3/cHyrWBafGHZUqo5JSDVTY5o5RQYK0yFBxBiNz8xoAcZfffFCHrsbVCss8ezm/beuJxWk1MCWNXvIErzJidBzyO1B0QgO85j9K8R2Sh3M/qfG7pMla8gogdiqmVaGL59ijlbBDm1HcPB5WMiNPf8VSx810rUpP4Imo+ox4seL51cc09taGiQbS8jJWcZAPjHQeCCR5abnBxxdfkTggk+ds/PJHj5opwQwOhW893nSwBGuV2nLyfC47D/2fCJ+CTZ8bZl+9lq1gkA3FiiftSK/DXAP6ttHIdXIvu0zvz+N7/7S0ZkvGSdAI67W0BhvqwIAs5d1Vkb5uCfZCG9jV92dlm2jKhZJWDBggU+5vkZZuSsBT5IWYRdzZkz52Daf5h+Rv8lUn+1acuknNW7QG9vr1xkEnYeACpA17DlXYzvXeohBsD+0tLSmw0942JWM4BLi7ywSFUOxPE7y7mY1P+nZcuomlUCGOyT0o2evh3s+QnTId1nf0q/rBJAqg+XAWbcdHVqM73nm1+g5awSkG4G0G8b2+I7Oshfss0aAbzpPYJRNRe4ZLiigF9DP/krj6yUtHeByhedw51wqMVxPKcp5WmcONVXV69U1Ixy8obgfN5SLWKh/5cqVbM3TfHJWT9WADVs+gNcLjM18oZHP5ONNq0MqOp0Rjjh4POAmATAA2lv2bYxWG8GeNGGUBX25RB0CO1JzmB00/SXnMN0H/b7lAQAXv6m75Rsg5fY0iLgP5+FBNhZGoy0jkf9tXJjaJrIU14I8RrbWSWyLlzSfxMMBtvq33B0lskZIKEAPEidz0Fnur4HJHTIgrJPAirb+69ndBJ+pYnFxckNe1Pl+oGJkYjzPH+LJj9JJRRIO2/rj6HYVgZQeVnhFvQdvLqaCPgVrjEHQsKpzP7+i9sHzoxEo28C1L2Y2H2UR0Ud3k7bdlP3lnhrAk2zX8f2HMDlivvsmDFj7mKb6zP75UJOSYDMX1L4fUbx125gSu3xKk9DNOrc5tosAX9z1FGs4s54w9Wz5dKR4ww9b8SkIyfzVuZvAvhYyOqaTVP9dewCzyRDgH1r4Fj/dUp5LyMz+nUfWE5JtO6TqzYpATJvZf6aQZG6y7ZM87WJrXy0fx4A30v0e74u8/gvb6tQA5unjfhAeT0zIGQnfXo8XjV0DTEfzqE8ZGQq20PV0Ui0JSEmpV49YKrvojalItp+SbszLhwJvslqfyTk8A8KJZWbp5Vl/I2N/r5fqh2SAYC/P/HL1BcjA75ZJnjxt1+ivvxVwH+yKlEXjvT5ji9E8IJjSAZMXt/fI3v4XifzWHnPkZQWfX8sQzIgPl97YOYrVvSq/Rn8/jigRUxFBooM/DQG/gsvjT4tCJQ8SgAAAABJRU5ErkJggg== - - - - Type - Pen - - - Fountain pen - Ball point pen - Highlight marker - - - - Color - Pen - Color of the line e.g. green, #00FF00, rgb(0,255,0) - - - Has signature - Canvas - Optional boolean attribute, which will be set to true after the canvas is signed. When the attribute is set to false, the signature is cleared, but will not clear the stored image - - - - - - Width unit - Canvas - - - Percentage - Pixels - - - - Width - Canvas - - - - Height unit - Canvas - 'Percentage of width' is the aspect ratio, 'Pixels' is absolute. Warning: When using 'Percentage of parent' the parent container must have an absolute height, else nothing is displayed. - - Percentage of width - Pixels - Percentage of parent - - - - Height - Canvas - - - - Show background grid - Grid - - - - Line color - Grid - - - - Cell height - Grid - Grid column size - - - Cell width - Grid - Grid row size - - - Line width - Grid - Grid border line width (pixels) - - - diff --git a/packages/customWidgets/signature-web/src/components/Alert.tsx b/packages/customWidgets/signature-web/src/components/Alert.tsx deleted file mode 100644 index 189ef0aaf9..0000000000 --- a/packages/customWidgets/signature-web/src/components/Alert.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { FC, PropsWithChildren } from "react"; -import classNames from "classnames"; - -export interface AlertProps extends PropsWithChildren { - bootstrapStyle?: "default" | "primary" | "success" | "info" | "warning" | "danger"; - className?: string; -} - -export const Alert: FC = ({ bootstrapStyle = "danger", className, children }) => - children ?
{children}
: null; - -Alert.displayName = "Alert"; diff --git a/packages/customWidgets/signature-web/src/components/Signature.tsx b/packages/customWidgets/signature-web/src/components/Signature.tsx deleted file mode 100644 index 23f2f552f6..0000000000 --- a/packages/customWidgets/signature-web/src/components/Signature.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import { PureComponent, ReactNode } from "react"; -import SignaturePad, { Options } from "signature_pad"; -import classNames from "classnames"; - -import { Alert } from "./Alert"; -import { Grid } from "./Grid"; -import { Dimensions, SizeContainer } from "./SizeContainer"; - -import "../ui/Signature.scss"; - -export interface SignatureProps extends Dimensions { - className: string; - alertMessage?: string; - clearSignature: boolean; - showGrid: boolean; - gridCellWidth: number; - gridCellHeight: number; - gridBorderColor: string; - gridBorderWidth: number; - penType: penOptions; - penColor: string; - onSignEndAction?: (imageUrl?: string) => void; - wrapperStyle?: object; - readOnly: boolean; -} - -export type penOptions = "fountain" | "ballpoint" | "marker"; - -export class Signature extends PureComponent { - private canvasNode: HTMLCanvasElement | null = null; - private signaturePad: SignaturePad | undefined; - - render(): ReactNode { - const { className, alertMessage, wrapperStyle } = this.props; - - return ( - - {alertMessage} - - { - this.canvasNode = node; - }} - /> - - ); - } - - componentDidMount(): void { - if (this.canvasNode) { - this.signaturePad = new SignaturePad(this.canvasNode, { - penColor: this.props.penColor, - ...this.signaturePadOptions() - }); - this.signaturePad.addEventListener("endStroke", this.handleSignEnd); - if (this.props.readOnly) { - this.signaturePad.off(); - } - } - } - - componentWillUnmount(): void { - this.signaturePad?.removeEventListener("endStroked", this.handleSignEnd); - } - - UNSAFE_componentWillReceiveProps(nextProps: SignatureProps): void { - if (this.signaturePad) { - const { clearSignature, readOnly } = this.props; - if (nextProps.clearSignature !== clearSignature && clearSignature) { - this.signaturePad.clear(); - } - if (nextProps.readOnly !== readOnly) { - if (nextProps.readOnly) { - this.signaturePad.off(); - } else { - this.signaturePad.on(); - } - } - } - } - - private onResize = (): void => { - if (this.canvasNode && this.signaturePad) { - const data = this.signaturePad.toData(); - this.canvasNode.width = - this.canvasNode && this.canvasNode.parentElement ? this.canvasNode.parentElement.offsetWidth : 0; - this.canvasNode.height = - this.canvasNode && this.canvasNode.parentElement ? this.canvasNode.parentElement.offsetHeight : 0; - this.signaturePad.clear(); - this.signaturePad.fromData(data); - } - }; - - private signaturePadOptions(): Options { - let options: Options = {}; - if (this.props.penType === "fountain") { - options = { minWidth: 0.6, maxWidth: 2.6, velocityFilterWeight: 0.6 }; - } else if (this.props.penType === "ballpoint") { - options = { minWidth: 1.4, maxWidth: 1.5, velocityFilterWeight: 1.5 }; - } else if (this.props.penType === "marker") { - options = { minWidth: 2, maxWidth: 4, velocityFilterWeight: 0.9 }; - } - return options; - } - - private handleSignEnd = (): void => { - if (this.props.onSignEndAction && this.signaturePad) { - this.props.onSignEndAction(this.signaturePad.toDataURL()); - } - }; -} diff --git a/packages/customWidgets/signature-web/src/components/SignatureContainer.ts b/packages/customWidgets/signature-web/src/components/SignatureContainer.ts deleted file mode 100644 index 6cb94d6166..0000000000 --- a/packages/customWidgets/signature-web/src/components/SignatureContainer.ts +++ /dev/null @@ -1,202 +0,0 @@ -import { Component, createElement, ReactNode } from "react"; - -import { Dimensions } from "./SizeContainer"; -import Utils from "../utils/Utils"; -import { penOptions, Signature } from "./Signature"; - -interface WrapperProps { - class: string; - mxObject?: mendix.lib.MxObject; - mxform: mxui.lib.form._FormBase; - style?: string; - friendlyId: string; - readOnly: boolean; -} - -export interface SignatureContainerProps extends WrapperProps, Dimensions { - hasSignatureAttribute: string; - showGrid: boolean; - gridBorderColor: string; - gridCellHeight: number; - gridCellWidth: number; - gridBorderWidth: number; - penType: penOptions; - penColor: string; -} - -interface SignatureContainerState { - alertMessage: string; - hasSignature: boolean; -} - -export default class SignatureContainer extends Component { - private subscriptionHandles: number[] = []; - private base64Uri = ""; - private formHandle?: number; - - readonly state = { - alertMessage: "", - hasSignature: false - }; - - constructor(props: SignatureContainerProps) { - super(props); - this.resetSubscriptions(props.mxObject); - } - - render(): ReactNode { - return createElement(Signature, { - ...(this.props as SignatureContainerProps), - wrapperStyle: Utils.parseStyle(this.props.style), - readOnly: this.isReadOnly(), - alertMessage: this.state.alertMessage, - clearSignature: this.state.hasSignature, - onSignEndAction: this.handleSignEnd, - className: this.props.class - }); - } - - UNSAFE_componentWillReceiveProps(newProps: SignatureContainerProps): void { - if (newProps.mxObject) { - const alertMessage = this.validateProps(newProps.mxObject); - - if (alertMessage) { - this.setState({ alertMessage }); - } - } - } - - componentDidUpdate(): void { - this.resetSubscriptions(this.props.mxObject); - } - - componentDidMount(): void { - this.formHandle = this.props.mxform.listen("submit", callback => this.saveDocument(callback)); - } - - componentWillUnmount(): void { - if (this.formHandle) { - this.props.mxform.unlisten(this.formHandle); - } - this.subscriptionHandles.forEach(window.mx.data.unsubscribe); - } - - private handleSignEnd = (base64Uri: string): void => { - const { mxObject } = this.props; - - if (mxObject && !this.state.hasSignature) { - mxObject.set(this.props.hasSignatureAttribute, true); - } - this.base64Uri = base64Uri; - if (base64Uri) { - this.setState({ hasSignature: true }); - } - }; - - private isReadOnly(): boolean { - const { mxObject, readOnly } = this.props; - - return !mxObject || readOnly || mxObject.isReadonlyAttr("Contents"); - } - - private saveDocument(callback: () => void): void { - if (this.base64Uri && this.state.hasSignature && this.props.mxObject) { - const error = function (callback: any): void { - return mx.ui.error("Error saving signature: " + callback.message); - }; - // @ts-expect-error cordova specific code - const cdv = window.cordova; - if (cdv) { - // @ts-expect-error cordova specific code - const options = new FileUploadOptions(); - options.fileKey = "blob"; - options.fileName = this.generateFileName(this.props.mxObject); - options.mimeType = "image/png"; - options.chunkedMode = false; - const headers = { - Accept: "application/json", - // @ts-expect-error cordova specific code - "X-Csrf-Token": mx.session.sessionData.csrftoken, - "X-Mx-ReqToken": new Date().getTime() - }; - options.headers = headers; - const isHttps = mx.remoteUrl.includes("https"); - const remoteUrlWithoutScheme = decodeURIComponent(mx.remoteUrl.replace(/.*_http[s]?_proxy_/, "")); - const remoteUrl = (isHttps ? "https://" : "http://") + remoteUrlWithoutScheme; - const guid = this.props.mxObject.getGuid(); - const dataUri = this.base64Uri; - - mx.data.commit({ - mxobj: this.props.mxObject, - callback() { - // @ts-expect-error cordova specific code - const ft = new FileTransfer(); - const fileUploadUrl = remoteUrl + "file?guid=" + guid; - ft.upload(dataUri, fileUploadUrl, callback, error, options); - }, - error - }); - } else { - mx.data.saveDocument( - this.props.mxObject.getGuid(), - this.generateFileName(this.props.mxObject), - {}, - Utils.convertUrlToBlob(this.base64Uri), - callback, - error => mx.ui.error("Error saving signature: " + error.message) - ); - } - } else { - callback(); - } - } - - private generateFileName(mxObject: mendix.lib.MxObject): string { - const currentName = mxObject.get("Name") as string; - if (currentName) { - return currentName; - } - return `signature${Math.floor(Math.random() * 1000000)}.png`; - } - - validateProps(mxObject: mendix.lib.MxObject): string { - let errorMessage = ""; - - if (mxObject && !mxObject.inheritsFrom("System.Image")) { - errorMessage = `${this.props.friendlyId}: ${mxObject.getEntity()} does not inherit from "System.Image".`; - } - - return errorMessage; - } - - private resetSubscriptions(mxObject?: mendix.lib.MxObject): void { - this.subscriptionHandles.forEach(window.mx.data.unsubscribe); - this.subscriptionHandles = []; - - if (mxObject) { - this.subscriptionHandles.push( - window.mx.data.subscribe({ - guid: mxObject.getGuid(), - callback: () => this.updateCanvasState() - }) - ); - this.subscriptionHandles.push( - mx.data.subscribe({ - guid: mxObject.getGuid(), - attr: this.props.hasSignatureAttribute, - callback: () => this.updateCanvasState() - }) - ); - } - } - - private updateCanvasState = (): void => { - const { mxObject, hasSignatureAttribute } = this.props; - if (hasSignatureAttribute) { - const hasSignature = !!mxObject && (mxObject.get(hasSignatureAttribute) as boolean); - if (this.state.hasSignature !== hasSignature) { - this.setState({ hasSignature }); - } - } - }; -} diff --git a/packages/customWidgets/signature-web/src/components/SizeContainer.ts b/packages/customWidgets/signature-web/src/components/SizeContainer.ts deleted file mode 100644 index 1292751c64..0000000000 --- a/packages/customWidgets/signature-web/src/components/SizeContainer.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { createElement, CSSProperties, FC, PropsWithChildren } from "react"; -import classNames from "classnames"; -import { useResizeObserver } from "../utils/useResizeObserver"; - -export type HeightUnitType = "percentageOfWidth" | "percentageOfParent" | "pixels"; - -export type WidthUnitType = "percentage" | "pixels"; - -export interface Dimensions { - widthUnit: WidthUnitType; - width: number; - heightUnit: HeightUnitType; - height: number; -} - -export interface SizeProps extends Dimensions, PropsWithChildren { - className: string; - classNameInner?: string; - readOnly?: boolean; - style?: CSSProperties; - onResize?: () => void; -} - -export const SizeContainer: FC = ({ - className, - classNameInner, - widthUnit, - width, - heightUnit, - height, - children, - style, - readOnly = false, - onResize -}) => { - const ref = useResizeObserver(() => onResize?.()); - - const styleWidth = widthUnit === "percentage" ? `${width}%` : `${width}px`; - return createElement( - "div", - { - ref, - className: classNames(className, "size-box"), - style: { - position: "relative", - width: styleWidth, - ...getHeight(heightUnit, height, widthUnit, width), - ...style - } - }, - createElement( - "div", - { - className: classNames("size-box-inner", classNameInner), - readOnly, - disabled: readOnly, - style: { - position: "absolute", - top: "0", - right: "0", - bottom: "0", - left: "0" - } - }, - children - ) - ); -}; - -SizeContainer.displayName = "SizeContainer"; - -const getHeight = ( - heightUnit: HeightUnitType, - height: number, - widthUnit: WidthUnitType, - width: number -): CSSProperties => { - const style: CSSProperties = {}; - if (heightUnit === "percentageOfWidth") { - const ratio = (height / 100) * width; - if (widthUnit === "percentage") { - style.height = "auto"; - style.paddingBottom = `${ratio}%`; - } else { - style.height = `${ratio}px`; - } - } else if (heightUnit === "pixels") { - style.height = `${height}px`; - } else if (heightUnit === "percentageOfParent") { - style.height = `${height}%`; - } - - return style; -}; diff --git a/packages/customWidgets/signature-web/src/utils/useResizeObserver.ts b/packages/customWidgets/signature-web/src/utils/useResizeObserver.ts deleted file mode 100644 index 2e2a35423e..0000000000 --- a/packages/customWidgets/signature-web/src/utils/useResizeObserver.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { RefObject, useLayoutEffect, useRef } from "react"; - -type callbackFn = (target: T, entry: ResizeObserverEntry) => void; - -export function useResizeObserver(callback: callbackFn): RefObject { - const ref = useRef(null); - - useLayoutEffect(() => { - const element = ref?.current; - - if (!element) { - return; - } - - const observer = new ResizeObserver(entries => { - callback(element, entries[0]); - }); - - observer.observe(element); - return () => { - observer.disconnect(); - }; - }, [callback, ref]); - - return ref; -} diff --git a/packages/customWidgets/signature-web/webpack.config.js b/packages/customWidgets/signature-web/webpack.config.js deleted file mode 100644 index ea880ebf8c..0000000000 --- a/packages/customWidgets/signature-web/webpack.config.js +++ /dev/null @@ -1,96 +0,0 @@ -const webpack = require("webpack"); -const path = require("path"); -const CopyWebpackPlugin = require("copy-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); - -const name = "signature"; -const widgetName = "Signature"; - -const widgetConfig = { - mode: "production", - devtool: false, - externals: ["react", "react-dom", "react/jsx-runtime"], - entry: "./src/components/SignatureContainer.ts", - output: { - path: path.resolve(__dirname, "dist/tmp"), - filename: `com/mendix/widget/custom/${name}/${widgetName}.js`, - libraryTarget: "amd", - publicPath: "/widgets/" - }, - resolve: { - extensions: [".ts", ".js", ".tsx", ".jsx"], - alias: { - tests: path.resolve(__dirname, "./tests") - } - }, - module: { - rules: [ - { - test: /\.tsx?$/, - use: "ts-loader" - }, - { - test: /\.(sa|sc|c)ss$/, - use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"] - } - ] - }, - plugins: [ - new MiniCssExtractPlugin({ - filename: `com/mendix/widget/custom/${name}/ui/${widgetName}.css` - }), - new CopyWebpackPlugin({ - patterns: [ - { - from: path.join(process.cwd(), "src/**/*.xml").replace(/\\/g, "/"), - toType: "template", - to: "./[name][ext]" - }, - { - from: `src/${widgetName}.@(tile|icon)@(.dark|).png`, - to: "./[name][ext]", - toType: "template" - }, - { - from: `dependencies.(json|txt)`, - to: "./[name][ext]", - toType: "template" - }, - { - from: `../../../LICENSE`, - to: "./License.txt", - toType: "template" - } - ] - }) - ] -}; - -const previewConfig = { - mode: "production", - devtool: false, - externals: ["react", "react-dom"], - entry: `./src/${widgetName}.webmodeler.ts`, - output: { - path: path.resolve(__dirname, "dist/tmp"), - filename: `${widgetName}.webmodeler.js`, - libraryTarget: "commonjs" - }, - resolve: { - extensions: [".ts", ".js", ".tsx", ".jsx"] - }, - module: { - rules: [ - { - test: /\.tsx?$/, - loader: "ts-loader" - }, - { - test: /\.(sa|sc|c)ss$/, - use: ["to-string-loader", "css-loader", "sass-loader"] - } - ] - } -}; - -module.exports = [widgetConfig, previewConfig]; diff --git a/packages/customWidgets/signature-web/.prettierrc.js b/packages/pluggableWidgets/signature-web/.prettierrc.js similarity index 100% rename from packages/customWidgets/signature-web/.prettierrc.js rename to packages/pluggableWidgets/signature-web/.prettierrc.js diff --git a/packages/pluggableWidgets/signature-web/CHANGELOG.md b/packages/pluggableWidgets/signature-web/CHANGELOG.md new file mode 100644 index 0000000000..cb0f65ef9b --- /dev/null +++ b/packages/pluggableWidgets/signature-web/CHANGELOG.md @@ -0,0 +1,41 @@ +# Changelog + +All notable changes to this widget will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [1.3.0] - 2026-02-25 + +### Fixed + +- We fixed an issue with burst action execution which was still happening in some cases. + +## [1.2.0] - 2025-11-07 + +### Fixed + +- We fixed an issue with burst executon in inactive tabs. + +### Changed + +- Repeated execution is not executing next action if previous execution is not yet finished. + +## [1.1.0] - 2025-08-12 + +### Added + +- Added support for using expressions to configure both delay and repeat interval values during component load. Expression support was also extended to delay values when attributes change dynamically. + +## [1.0.1] - 2024-04-25 + +### Fixed + +- We fixed issues where event not fired with MF/NF having parameters. + +## [1.0.0] - 2024-03-19 + +### Added + +- initial version of app events with component load and attribute change listener. diff --git a/packages/pluggableWidgets/signature-web/README.md b/packages/pluggableWidgets/signature-web/README.md new file mode 100644 index 0000000000..2dbdab3de0 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/README.md @@ -0,0 +1,3 @@ + + +Please see [Signature](https://docs.mendix.com/appstore/widgets/) in the Mendix documentation for details. diff --git a/packages/pluggableWidgets/signature-web/cypress.config.cjs b/packages/pluggableWidgets/signature-web/cypress.config.cjs new file mode 100644 index 0000000000..f5388c3dfd --- /dev/null +++ b/packages/pluggableWidgets/signature-web/cypress.config.cjs @@ -0,0 +1 @@ +module.exports = require("@mendix/run-e2e/cypress.config.cjs"); diff --git a/packages/customWidgets/signature-web/eslint.config.mjs b/packages/pluggableWidgets/signature-web/eslint.config.mjs similarity index 100% rename from packages/customWidgets/signature-web/eslint.config.mjs rename to packages/pluggableWidgets/signature-web/eslint.config.mjs diff --git a/packages/pluggableWidgets/signature-web/package.json b/packages/pluggableWidgets/signature-web/package.json new file mode 100644 index 0000000000..e475140fd3 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/package.json @@ -0,0 +1,63 @@ +{ + "name": "@mendix/signature-web", + "widgetName": "Signature", + "version": "2.0.0", + "description": "Signature widget for Mendix Web", + "copyright": "© Mendix Technology BV 2026. All rights reserved.", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/mendix/web-widgets.git" + }, + "config": { + "developmentPort": 3000, + "mendixHost": "http://localhost:8080" + }, + "mxpackage": { + "name": "Signature", + "type": "widget", + "mpkName": "com.mendix.widget.web.signature.mpk" + }, + "packagePath": "com.mendix.widget.web", + "marketplace": { + "minimumMXVersion": "11.8.0", + "appNumber": 107984, + "appName": "Signature", + "reactReady": true + }, + "testProject": { + "githubUrl": "https://github.com/mendix/testProjects", + "branchName": "signature-web" + }, + "scripts": { + "build": "pluggable-widgets-tools build:web", + "create-gh-release": "rui-create-gh-release", + "create-translation": "rui-create-translation", + "dev": "pluggable-widgets-tools start:web", + "e2e": "echo \"Skipping this e2e test\"", + "e2edev": "run-e2e dev --with-preps", + "format": "prettier --ignore-path ./node_modules/@mendix/prettier-config-web-widgets/global-prettierignore --write .", + "lint": "eslint src/ package.json", + "publish-marketplace": "rui-publish-marketplace", + "release": "pluggable-widgets-tools release:web", + "start": "pluggable-widgets-tools start:server", + "test": "pluggable-widgets-tools test:unit:web", + "update-changelog": "rui-update-changelog-widget", + "verify": "rui-verify-package-format" + }, + "dependencies": { + "classnames": "^2.5.1", + "signature_pad": "^5.1.3" + }, + "devDependencies": { + "@mendix/automation-utils": "workspace:*", + "@mendix/eslint-config-web-widgets": "workspace:*", + "@mendix/pluggable-widgets-tools": "workspace:*", + "@mendix/prettier-config-web-widgets": "workspace:*", + "@mendix/run-e2e": "workspace:*", + "@mendix/widget-plugin-component-kit": "workspace:*", + "@mendix/widget-plugin-hooks": "workspace:*", + "@mendix/widget-plugin-platform": "workspace:*", + "@mendix/widget-plugin-test-utils": "workspace:*" + } +} diff --git a/packages/pluggableWidgets/signature-web/rollup.config.mjs b/packages/pluggableWidgets/signature-web/rollup.config.mjs new file mode 100644 index 0000000000..688a1a7197 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/rollup.config.mjs @@ -0,0 +1,5 @@ +import copyFiles from "@mendix/rollup-web-widgets/copyFiles.mjs"; + +export default args => { + return copyFiles(args); +}; diff --git a/packages/pluggableWidgets/signature-web/src/Signature.editorConfig.ts b/packages/pluggableWidgets/signature-web/src/Signature.editorConfig.ts new file mode 100644 index 0000000000..010305208d --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/Signature.editorConfig.ts @@ -0,0 +1,56 @@ +import { hidePropertiesIn, hidePropertyIn, Properties } from "@mendix/pluggable-widgets-tools"; +import { + container, + rowLayout, + structurePreviewPalette, + StructurePreviewProps, + svgImage, + text +} from "@mendix/widget-plugin-platform/preview/structure-preview-api"; +import { SignaturePreviewProps } from "../typings/SignatureProps"; + +import SignaturePreviewSVG from "./assets/Signature.icon.svg"; +import SignaturePreviewDarkSVG from "./assets/Signature.icon.dark.svg"; + +export function getProperties( + values: SignaturePreviewProps, + defaultProperties: Properties /* , target: Platform*/ +): Properties { + if (values.heightUnit === "auto") { + hidePropertyIn(defaultProperties, values, "height"); + } else { + hidePropertiesIn(defaultProperties, values, [ + "minHeight", + "minHeightUnit", + "maxHeight", + "maxHeightUnit", + "overflowY" + ]); + } + + if (values.minHeightUnit === "none") { + hidePropertyIn(defaultProperties, values, "minHeight"); + } + + if (values.maxHeightUnit === "none") { + hidePropertiesIn(defaultProperties, values, ["maxHeight", "overflowY"]); + } + + return defaultProperties; +} + +export function getPreview(_values: SignaturePreviewProps, isDarkMode: boolean): StructurePreviewProps { + const palette = structurePreviewPalette[isDarkMode ? "dark" : "light"]; + const normalSVG = isDarkMode ? SignaturePreviewDarkSVG : SignaturePreviewSVG; + const variant = normalSVG; + const doc = decodeURIComponent(variant.replace("data:image/svg+xml,", "")); + + return rowLayout({ columnSize: "grow", borders: true, backgroundColor: palette.background.containerFill })( + container()(), + rowLayout({ grow: 2, padding: 8 })( + svgImage({ width: 15, height: 15 })(doc), + text({ fontColor: palette.text.primary, grow: 10 })("Signature") + ), + container()() + ); +} diff --git a/packages/pluggableWidgets/signature-web/src/Signature.editorPreview.tsx b/packages/pluggableWidgets/signature-web/src/Signature.editorPreview.tsx new file mode 100644 index 0000000000..04f42a5348 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/Signature.editorPreview.tsx @@ -0,0 +1,7 @@ +import { ReactElement } from "react"; +import { SignaturePreviewProps } from "typings/SignatureProps"; +import classNames from "classnames"; + +export function preview(_props: SignaturePreviewProps): ReactElement { + return
{"Signature"}
; +} diff --git a/packages/customWidgets/signature-web/src/Signature.icon.dark.png b/packages/pluggableWidgets/signature-web/src/Signature.icon.dark.png similarity index 100% rename from packages/customWidgets/signature-web/src/Signature.icon.dark.png rename to packages/pluggableWidgets/signature-web/src/Signature.icon.dark.png diff --git a/packages/customWidgets/signature-web/src/Signature.icon.png b/packages/pluggableWidgets/signature-web/src/Signature.icon.png similarity index 100% rename from packages/customWidgets/signature-web/src/Signature.icon.png rename to packages/pluggableWidgets/signature-web/src/Signature.icon.png diff --git a/packages/customWidgets/signature-web/src/Signature.tile.dark.png b/packages/pluggableWidgets/signature-web/src/Signature.tile.dark.png similarity index 100% rename from packages/customWidgets/signature-web/src/Signature.tile.dark.png rename to packages/pluggableWidgets/signature-web/src/Signature.tile.dark.png diff --git a/packages/customWidgets/signature-web/src/Signature.tile.png b/packages/pluggableWidgets/signature-web/src/Signature.tile.png similarity index 100% rename from packages/customWidgets/signature-web/src/Signature.tile.png rename to packages/pluggableWidgets/signature-web/src/Signature.tile.png diff --git a/packages/pluggableWidgets/signature-web/src/Signature.tsx b/packages/pluggableWidgets/signature-web/src/Signature.tsx new file mode 100644 index 0000000000..02b57c5787 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/Signature.tsx @@ -0,0 +1,9 @@ +import { ReactElement } from "react"; +import { SignatureContainerProps } from "../typings/SignatureProps"; +import { SignatureComponent } from "./components/Signature"; +import "./ui/Signature.scss"; + +export default function Signature(props: SignatureContainerProps): ReactElement { + const { class: className } = props; + return ; +} diff --git a/packages/pluggableWidgets/signature-web/src/Signature.xml b/packages/pluggableWidgets/signature-web/src/Signature.xml new file mode 100644 index 0000000000..a076b0f8ac --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/Signature.xml @@ -0,0 +1,137 @@ + + + Signature + Signature + https://docs.mendix.com/appstore/widgets/signature + + + + + Image value + + + + Has signature + Optional boolean attribute, which will be set to true after the canvas is signed. When the attribute is set to false, the signature is cleared, but will not clear the stored image + + + + + + + + + Type + + + Fountain pen + Ball point pen + Highlight marker + + + + Color + Color of the line e.g. green, #00FF00, rgb(0,255,0) + + + + + + + Width unit + + + Pixels + Percentage + + + + Width + + + + Height unit + + + Auto + Pixels + Percentage + Viewport + + + + Height + + + + Minimum Height unit + + + None + Pixels + Percentage + Viewport + + + + Minimum height + + + + Maximum Height unit + + + None + Pixels + Percentage + Viewport + + + + Maximum height + + + + Vertical Overflow + + + Auto + Scroll + Hidden + + + + + + + On sign end + Action that is executed when the user finishes signing. The action will receive the signature image as a parameter. + + + + + + + + Show background grid + + + + Line color + + + + Cell height + Grid column size + + + Cell width + Grid row size + + + Line width + Grid border line width (pixels) + + + + diff --git a/packages/pluggableWidgets/signature-web/src/__tests__/Signature.spec.tsx b/packages/pluggableWidgets/signature-web/src/__tests__/Signature.spec.tsx new file mode 100644 index 0000000000..32dcfffae1 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/__tests__/Signature.spec.tsx @@ -0,0 +1,64 @@ +import "@testing-library/jest-dom"; +import { render, screen } from "@testing-library/react"; +import { ReactElement } from "react"; +import { SignatureContainerProps } from "../../typings/SignatureProps"; +import Signature from "../Signature"; + +const mockSignatureComponent = jest.fn((_props: unknown) =>
); + +jest.mock("../components/Signature", () => ({ + SignatureComponent: (props: unknown): ReactElement => mockSignatureComponent(props) +})); + +describe("Signature", () => { + const imageSource = { + setValue: jest.fn() + } as unknown as SignatureContainerProps["imageSource"]; + + const defaultProps: SignatureContainerProps = { + name: "signature", + class: "mx-signature", + tabIndex: 0, + imageSource, + hasSignatureAttribute: undefined, + penType: "ballpoint", + penColor: "#000000", + widthUnit: "pixels", + width: 300, + heightUnit: "pixels", + height: 200, + minHeightUnit: "none", + minHeight: 0, + maxHeightUnit: "none", + maxHeight: 0, + overflowY: "auto", + showGrid: true, + gridBorderColor: "#cccccc", + gridCellHeight: 20, + gridCellWidth: 20, + gridBorderWidth: 1 + }; + + beforeEach(() => { + mockSignatureComponent.mockClear(); + }); + + it("renders SignatureComponent", () => { + render(); + + expect(screen.getByTestId("signature-component")).toBeInTheDocument(); + }); + + it("passes derived and default props to SignatureComponent", () => { + render(); + + expect(mockSignatureComponent).toHaveBeenCalledTimes(1); + expect(mockSignatureComponent.mock.calls[0][0]).toEqual( + expect.objectContaining({ + ...defaultProps, + className: defaultProps.class, + imageSource + }) + ); + }); +}); diff --git a/packages/pluggableWidgets/signature-web/src/assets/Signature.icon.dark.svg b/packages/pluggableWidgets/signature-web/src/assets/Signature.icon.dark.svg new file mode 100644 index 0000000000..f0e5b9d88d --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/assets/Signature.icon.dark.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/pluggableWidgets/signature-web/src/assets/Signature.icon.svg b/packages/pluggableWidgets/signature-web/src/assets/Signature.icon.svg new file mode 100644 index 0000000000..70ddbb28d9 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/assets/Signature.icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/pluggableWidgets/signature-web/src/assets/Signature.tile.dark.svg b/packages/pluggableWidgets/signature-web/src/assets/Signature.tile.dark.svg new file mode 100644 index 0000000000..6c072ae7ff --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/assets/Signature.tile.dark.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/pluggableWidgets/signature-web/src/assets/Signature.tile.svg b/packages/pluggableWidgets/signature-web/src/assets/Signature.tile.svg new file mode 100644 index 0000000000..b39521a425 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/assets/Signature.tile.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/pluggableWidgets/signature-web/src/assets/icons.tsx b/packages/pluggableWidgets/signature-web/src/assets/icons.tsx new file mode 100644 index 0000000000..c9c1c4b118 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/assets/icons.tsx @@ -0,0 +1,15 @@ +import { ReactElement } from "react"; +export function EventsIcon({ isActive }: { isActive?: boolean }): ReactElement { + return ( + + + + + + ); +} diff --git a/packages/customWidgets/signature-web/src/components/Grid.tsx b/packages/pluggableWidgets/signature-web/src/components/Grid.tsx similarity index 76% rename from packages/customWidgets/signature-web/src/components/Grid.tsx rename to packages/pluggableWidgets/signature-web/src/components/Grid.tsx index b4928668ca..4680abd84b 100644 --- a/packages/customWidgets/signature-web/src/components/Grid.tsx +++ b/packages/pluggableWidgets/signature-web/src/components/Grid.tsx @@ -1,22 +1,14 @@ -import { FC } from "react"; +import { FC, useId } from "react"; export interface GridBackgroundProps { gridCellWidth: number; gridCellHeight: number; gridBorderColor: string; gridBorderWidth: number; - showGrid?: boolean; } -export const Grid: FC = ({ - gridCellWidth, - gridCellHeight, - gridBorderColor, - gridBorderWidth, - showGrid = true -}) => { - // eslint-disable-next-line react-hooks/purity - const id = `grid${Math.floor(Math.random() * 1000000)}`; - return showGrid ? ( +export const Grid: FC = ({ gridCellWidth, gridCellHeight, gridBorderColor, gridBorderWidth }) => { + const id = useId(); + return ( @@ -40,7 +32,7 @@ export const Grid: FC = ({ - ) : null; + ); }; Grid.displayName = "Grid"; diff --git a/packages/pluggableWidgets/signature-web/src/components/Signature.tsx b/packages/pluggableWidgets/signature-web/src/components/Signature.tsx new file mode 100644 index 0000000000..90bfc0d0d9 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/components/Signature.tsx @@ -0,0 +1,45 @@ +import classNames from "classnames"; +import { ReactElement } from "react"; + +import { useSignaturePad } from "src/utils/useSignaturePad"; +import { Alert } from "@mendix/widget-plugin-component-kit/Alert"; +import { If } from "@mendix/widget-plugin-component-kit/If"; +import { Grid } from "./Grid"; +import { SizeContainer } from "./SizeContainer"; +import { SignatureProps } from "../utils/customTypes"; +import Utils from "../utils/Utils"; + +export function SignatureComponent(props: SignatureProps): ReactElement { + const { className, alertMessage, wrapperStyle, imageSource, onSignEndAction } = props; + const readOnly = imageSource.readOnly; + const showGrid = props.showGrid && !readOnly; + + const handleSignEnd = (imageDataUrl?: string): void => { + if (imageDataUrl) { + imageSource.setValue(Utils.convertUrlToBlob(imageDataUrl)); + } + + // Trigger microflow to update signature attribute + if (onSignEndAction && !onSignEndAction.isExecuting && onSignEndAction.canExecute) { + onSignEndAction.execute({ signatureImage: imageDataUrl }); + } + }; + + const { canvasRef, onResize } = useSignaturePad(props, handleSignEnd); + + return ( + + {alertMessage} + + + + + + ); +} diff --git a/packages/pluggableWidgets/signature-web/src/components/SizeContainer.ts b/packages/pluggableWidgets/signature-web/src/components/SizeContainer.ts new file mode 100644 index 0000000000..c8d7e48db4 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/components/SizeContainer.ts @@ -0,0 +1,48 @@ +import { createElement, CSSProperties, FC, PropsWithChildren } from "react"; +import classNames from "classnames"; +import { useResizeObserver } from "@mendix/widget-plugin-hooks/useResizeObserver"; +import { constructWrapperStyle, DimensionsProps } from "../utils/dimensions"; + +export interface SizeProps extends DimensionsProps, PropsWithChildren { + className: string; + classNameInner?: string; + readOnly?: boolean; + style?: CSSProperties; + onResize?: () => void; +} + +export const SizeContainer: FC = (props: SizeProps) => { + const { className, children, classNameInner, readOnly = false, style, onResize } = props; + const ref = useResizeObserver(() => onResize?.()); + const wrapperStyle = constructWrapperStyle(props); + return createElement( + "div", + { + ref, + className: classNames(className, "size-box"), + style: { + position: "relative", + ...wrapperStyle, + ...style + } + }, + createElement( + "div", + { + className: classNames("size-box-inner", classNameInner), + readOnly, + disabled: readOnly, + style: { + position: "absolute", + top: "0", + right: "0", + bottom: "0", + left: "0" + } + }, + children + ) + ); +}; + +SizeContainer.displayName = "SizeContainer"; diff --git a/packages/customWidgets/signature-web/src/package.xml b/packages/pluggableWidgets/signature-web/src/package.xml similarity index 69% rename from packages/customWidgets/signature-web/src/package.xml rename to packages/pluggableWidgets/signature-web/src/package.xml index c6977cb8b1..7eb2568aee 100644 --- a/packages/customWidgets/signature-web/src/package.xml +++ b/packages/pluggableWidgets/signature-web/src/package.xml @@ -1,11 +1,11 @@ - + - + diff --git a/packages/customWidgets/signature-web/src/ui/Signature.scss b/packages/pluggableWidgets/signature-web/src/ui/Signature.scss similarity index 100% rename from packages/customWidgets/signature-web/src/ui/Signature.scss rename to packages/pluggableWidgets/signature-web/src/ui/Signature.scss diff --git a/packages/customWidgets/signature-web/src/utils/Utils.ts b/packages/pluggableWidgets/signature-web/src/utils/Utils.ts similarity index 57% rename from packages/customWidgets/signature-web/src/utils/Utils.ts rename to packages/pluggableWidgets/signature-web/src/utils/Utils.ts index 81b741ebf4..d3b2ed3a19 100644 --- a/packages/customWidgets/signature-web/src/utils/Utils.ts +++ b/packages/pluggableWidgets/signature-web/src/utils/Utils.ts @@ -1,21 +1,5 @@ // eslint-disable-next-line @typescript-eslint/no-extraneous-class export default class Utils { - static parseStyle(style = ""): { [key: string]: string } { - try { - return style.split(";").reduce<{ [key: string]: string }>((styleObject, line) => { - const pair = line.split(":"); - if (pair.length === 2) { - const name = pair[0].trim().replace(/(-.)/g, match => match[1].toUpperCase()); - styleObject[name] = pair[1].trim(); - } - return styleObject; - }, {}); - } catch (error) { - window.console.log("Failed to parse style", style, error); - } - return {}; - } - static convertUrlToBlob(base64Uri: string): Blob { const contentType = "image/png"; const sliceSize = 512; diff --git a/packages/pluggableWidgets/signature-web/src/utils/customTypes.ts b/packages/pluggableWidgets/signature-web/src/utils/customTypes.ts new file mode 100644 index 0000000000..202cf6f3f7 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/utils/customTypes.ts @@ -0,0 +1,13 @@ +import { PenTypeEnum, SignatureContainerProps } from "../../typings/SignatureProps"; + +export interface SignatureProps extends SignatureContainerProps { + className: string; + alertMessage?: string; + gridCellWidth: number; + gridCellHeight: number; + gridBorderColor: string; + gridBorderWidth: number; + penType: PenTypeEnum; + penColor: string; + wrapperStyle?: object; +} diff --git a/packages/pluggableWidgets/signature-web/src/utils/dimensions.ts b/packages/pluggableWidgets/signature-web/src/utils/dimensions.ts new file mode 100644 index 0000000000..85d47afce1 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/utils/dimensions.ts @@ -0,0 +1,53 @@ +import { CSSProperties } from "react"; + +export type WidthUnitEnum = "pixels" | "percentage"; + +export type HeightUnitEnum = "auto" | "pixels" | "percentageOfParent" | "percentageOfView"; + +export type MinHeightUnitEnum = "none" | "pixels" | "percentageOfParent" | "percentageOfView"; + +export type MaxHeightUnitEnum = "none" | "pixels" | "percentageOfParent" | "percentageOfView"; + +export type OverflowYEnum = "auto" | "scroll" | "hidden"; + +export type DimensionsProps = { + widthUnit: WidthUnitEnum; + width: number; + heightUnit: HeightUnitEnum; + height: number; + minHeightUnit: MinHeightUnitEnum; + minHeight: number; + maxHeightUnit: MaxHeightUnitEnum; + maxHeight: number; + overflowY: OverflowYEnum; +}; + +function getHeightScale(height: number, heightUnit: "pixels" | "percentageOfParent" | "percentageOfView"): string { + return `${height}${heightUnit === "pixels" ? "px" : heightUnit === "percentageOfView" ? "vh" : "%"}`; +} + +export function constructWrapperStyle(props: DimensionsProps): CSSProperties { + const { widthUnit, heightUnit, minHeightUnit, maxHeightUnit, width, height, minHeight, maxHeight, overflowY } = + props; + + const wrapperStyle: Pick = + {}; + + wrapperStyle.width = `${width}${widthUnit === "pixels" ? "px" : "%"}`; + if (heightUnit === "auto") { + wrapperStyle.height = "auto"; + + if (minHeightUnit !== "none") { + wrapperStyle.minHeight = getHeightScale(minHeight, minHeightUnit); + } + + if (maxHeightUnit !== "none") { + wrapperStyle.maxHeight = getHeightScale(maxHeight, maxHeightUnit); + wrapperStyle.overflowY = overflowY; + } + } else { + wrapperStyle.height = getHeightScale(height, heightUnit); + } + + return wrapperStyle; +} diff --git a/packages/pluggableWidgets/signature-web/src/utils/useSignaturePad.ts b/packages/pluggableWidgets/signature-web/src/utils/useSignaturePad.ts new file mode 100644 index 0000000000..1aa3ed902c --- /dev/null +++ b/packages/pluggableWidgets/signature-web/src/utils/useSignaturePad.ts @@ -0,0 +1,105 @@ +import { RefObject, useCallback, useEffect, useMemo, useRef } from "react"; +import SignaturePad, { Options } from "signature_pad"; +import { SignatureProps } from "./customTypes"; + +function usePrevious(value: T): T | null { + const ref = useRef(null); + useEffect(() => { + ref.current = value; + }, [value]); + return ref.current; +} + +export function useSignaturePad( + props: Pick, + onSignEnd?: (imageDataURL?: string) => void +): { + signaturePadRef: RefObject; + canvasRef: RefObject; + onResize?: () => void; +} { + const { imageSource, hasSignatureAttribute, penType, penColor } = props; + const readOnly = imageSource.readOnly; + const signaturePadRef = useRef(null); + const canvasRef = useRef(null); + const isSignatureInitialized = useRef(false); + const hasSignature = usePrevious(hasSignatureAttribute?.value ?? false) ?? false; + + const signaturePadOptions: Options = useMemo(() => { + let options: Options = {}; + if (penType === "fountain") { + options = { minWidth: 0.6, maxWidth: 2.6, velocityFilterWeight: 0.6 }; + } else if (penType === "ballpoint") { + options = { minWidth: 1.4, maxWidth: 1.5, velocityFilterWeight: 1.5 }; + } else if (penType === "marker") { + options = { minWidth: 2, maxWidth: 4, velocityFilterWeight: 0.9 }; + } + return options; + }, [penType]); + + const handleSignEnd = useCallback(() => { + const imageDataUrl = signaturePadRef.current?.toDataURL(); + + if (hasSignatureAttribute) { + hasSignatureAttribute.setValue(!signaturePadRef.current?.isEmpty()); + } + if (imageDataUrl && onSignEnd) { + onSignEnd(imageDataUrl); + } + }, [hasSignatureAttribute, onSignEnd]); + + // Toggle readonly condition on signature pad when imageSource.readOnly changes + useEffect(() => { + if (readOnly) { + signaturePadRef.current?.off(); + } else { + signaturePadRef.current?.on(); + } + }, [readOnly]); + + const onResize = (): void => { + if (canvasRef.current && signaturePadRef.current) { + const data = signaturePadRef.current.toData(); + canvasRef.current.width = + canvasRef.current && canvasRef.current.parentElement ? canvasRef.current.parentElement.offsetWidth : 0; + canvasRef.current.height = + canvasRef.current && canvasRef.current.parentElement ? canvasRef.current.parentElement.offsetHeight : 0; + signaturePadRef.current.clear(); + signaturePadRef.current.fromData(data); + } + }; + + // Clear signature pad when hasSignature value changes from true to false + useEffect(() => { + if (hasSignatureAttribute?.status === "available") { + if (hasSignatureAttribute?.value !== hasSignature) { + if (hasSignature === true) { + signaturePadRef.current?.clear(); + } + } + } + }, [hasSignature, hasSignatureAttribute?.status, hasSignatureAttribute?.value]); + + // Initialize signature pad + useEffect(() => { + if (canvasRef.current) { + // only instantiate when all data is loaded properly to avoid unnecessary re-instantiations + const canInstantiateSignaturePad = + signaturePadRef.current === null && + (imageSource?.status === "available" ? imageSource.value?.uri : imageSource.status === "unavailable"); + if (canInstantiateSignaturePad && !isSignatureInitialized.current) { + signaturePadRef.current = new SignaturePad(canvasRef.current, { + penColor, + ...signaturePadOptions + }); + signaturePadRef.current.addEventListener("endStroke", handleSignEnd); + if (readOnly) { + signaturePadRef.current?.off(); + } + isSignatureInitialized.current = true; + } + } + }, [handleSignEnd, penColor, readOnly, signaturePadOptions, imageSource, hasSignatureAttribute]); + + return { signaturePadRef, canvasRef, onResize }; +} diff --git a/packages/customWidgets/signature-web/tsconfig.json b/packages/pluggableWidgets/signature-web/tsconfig.json similarity index 63% rename from packages/customWidgets/signature-web/tsconfig.json rename to packages/pluggableWidgets/signature-web/tsconfig.json index b6e01a9e22..7aa60df0c9 100644 --- a/packages/customWidgets/signature-web/tsconfig.json +++ b/packages/pluggableWidgets/signature-web/tsconfig.json @@ -1,15 +1,15 @@ { + "include": ["./src", "./typings"], "compilerOptions": { - "rootDir": "./", - "outDir": "dist/tsc/", + "baseUrl": "./", "noEmitOnError": true, "sourceMap": true, "module": "esnext", - "target": "es5", - "lib": ["es2015", "dom"], + "target": "es6", + "lib": ["esnext", "dom"], + "types": ["jest", "node"], "moduleResolution": "node", "declaration": false, - "removeComments": true, "noLib": false, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, @@ -18,11 +18,13 @@ "skipLibCheck": true, "noUnusedLocals": true, "noUnusedParameters": true, + "jsx": "react-jsx", "allowSyntheticDefaultImports": true, "esModuleInterop": true, - "jsx": "react-jsx" - }, - "files": ["./node_modules/mendix-client/index.d.ts"], - "include": ["./src", "./typings"], - "exclude": ["dist/", "node_modules/", "tests/", "scripts/"] + "useUnknownInCatchVariables": false, + "exactOptionalPropertyTypes": false, + "paths": { + "react-hot-loader/root": ["./hot-typescript.ts"] + } + } } diff --git a/packages/pluggableWidgets/signature-web/typings/SignatureProps.d.ts b/packages/pluggableWidgets/signature-web/typings/SignatureProps.d.ts new file mode 100644 index 0000000000..a1add0ff87 --- /dev/null +++ b/packages/pluggableWidgets/signature-web/typings/SignatureProps.d.ts @@ -0,0 +1,77 @@ +/** + * This file was generated from Signature.xml + * WARNING: All changes made to this file will be overwritten + * @author Mendix Widgets Framework Team + */ +import { CSSProperties } from "react"; +import { ActionValue, EditableValue, EditableImageValue, Option, WebImage } from "mendix"; + +export type PenTypeEnum = "fountain" | "ballpoint" | "marker"; + +export type WidthUnitEnum = "pixels" | "percentage"; + +export type HeightUnitEnum = "auto" | "pixels" | "percentageOfParent" | "percentageOfView"; + +export type MinHeightUnitEnum = "none" | "pixels" | "percentageOfParent" | "percentageOfView"; + +export type MaxHeightUnitEnum = "none" | "pixels" | "percentageOfParent" | "percentageOfView"; + +export type OverflowYEnum = "auto" | "scroll" | "hidden"; + +export interface SignatureContainerProps { + name: string; + class: string; + style?: CSSProperties; + tabIndex?: number; + imageSource: EditableImageValue; + hasSignatureAttribute?: EditableValue; + penType: PenTypeEnum; + penColor: string; + widthUnit: WidthUnitEnum; + width: number; + heightUnit: HeightUnitEnum; + height: number; + minHeightUnit: MinHeightUnitEnum; + minHeight: number; + maxHeightUnit: MaxHeightUnitEnum; + maxHeight: number; + overflowY: OverflowYEnum; + onSignEndAction?: ActionValue<{ signatureImage: Option }>; + showGrid: boolean; + gridBorderColor: string; + gridCellHeight: number; + gridCellWidth: number; + gridBorderWidth: number; +} + +export interface SignaturePreviewProps { + /** + * @deprecated Deprecated since version 9.18.0. Please use class property instead. + */ + className: string; + class: string; + style: string; + styleObject?: CSSProperties; + readOnly: boolean; + renderMode: "design" | "xray" | "structure"; + translate: (text: string) => string; + imageSource: { type: "static"; imageUrl: string; } | { type: "dynamic"; entity: string; } | null; + hasSignatureAttribute: string; + penType: PenTypeEnum; + penColor: string; + widthUnit: WidthUnitEnum; + width: number | null; + heightUnit: HeightUnitEnum; + height: number | null; + minHeightUnit: MinHeightUnitEnum; + minHeight: number | null; + maxHeightUnit: MaxHeightUnitEnum; + maxHeight: number | null; + overflowY: OverflowYEnum; + onSignEndAction: {} | null; + showGrid: boolean; + gridBorderColor: string; + gridCellHeight: number | null; + gridCellWidth: number | null; + gridBorderWidth: number | null; +} diff --git a/packages/pluggableWidgets/signature-web/typings/declare-svg.ts b/packages/pluggableWidgets/signature-web/typings/declare-svg.ts new file mode 100644 index 0000000000..e6958d5a9f --- /dev/null +++ b/packages/pluggableWidgets/signature-web/typings/declare-svg.ts @@ -0,0 +1,4 @@ +declare module "*.svg" { + const content: string; + export = content; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb562c6e32..1445dc59d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -245,70 +245,6 @@ importers: specifier: ^5.0.1 version: 5.0.1 - packages/customWidgets/signature-web: - dependencies: - classnames: - specifier: ^2.5.1 - version: 2.5.1 - signature_pad: - specifier: 5.1.3 - version: 5.1.3 - devDependencies: - '@mendix/automation-utils': - specifier: workspace:* - version: link:../../../automation/utils - '@mendix/eslint-config-web-widgets': - specifier: workspace:* - version: link:../../shared/eslint-config-web-widgets - '@mendix/pluggable-widgets-tools': - specifier: 11.8.0 - version: 11.8.0(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(eslint@9.39.3(jiti@2.6.1))(jest-util@30.2.0)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.29.0)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) - '@mendix/prettier-config-web-widgets': - specifier: workspace:* - version: link:../../shared/prettier-config-web-widgets - copy-webpack-plugin: - specifier: ^11.0.0 - version: 11.0.0(webpack@5.102.1) - css-loader: - specifier: ^6.7.3 - version: 6.11.0(webpack@5.102.1) - eslint: - specifier: ^9.39.3 - version: 9.39.3(jiti@2.6.1) - jest-canvas-mock: - specifier: ^2.4.0 - version: 2.5.2 - loader-utils: - specifier: ^1.4.2 - version: 1.4.2 - mendix-client: - specifier: ^7.15.8 - version: 7.15.8 - mini-css-extract-plugin: - specifier: ^2.7.2 - version: 2.9.4(webpack@5.102.1) - sass-loader: - specifier: ^13.2.0 - version: 13.3.3(sass@1.93.2)(webpack@5.102.1) - to-string-loader: - specifier: ^1.1.6 - version: 1.2.0 - ts-loader: - specifier: ^9.4.2 - version: 9.5.4(typescript@5.9.3)(webpack@5.102.1) - ts-node: - specifier: 10.9.2 - version: 10.9.2(@swc/core@1.13.5)(@types/node@22.14.1)(typescript@5.9.3) - typescript: - specifier: '>5.8.0' - version: 5.9.3 - webpack: - specifier: ^5.75.0 - version: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - webpack-cli: - specifier: ^5.0.1 - version: 5.1.4(webpack@5.102.1) - packages/modules/calendar: dependencies: '@mendix/calendar-web': @@ -2299,6 +2235,43 @@ importers: specifier: ^7.0.3 version: 7.0.3 + packages/pluggableWidgets/signature-web: + dependencies: + classnames: + specifier: ^2.5.1 + version: 2.5.1 + signature_pad: + specifier: ^5.1.3 + version: 5.1.3 + devDependencies: + '@mendix/automation-utils': + specifier: workspace:* + version: link:../../../automation/utils + '@mendix/eslint-config-web-widgets': + specifier: workspace:* + version: link:../../shared/eslint-config-web-widgets + '@mendix/pluggable-widgets-tools': + specifier: 11.8.0 + version: 11.8.0(@jest/transform@29.7.0)(@jest/types@30.2.0)(@swc/core@1.13.5)(@types/babel__core@7.20.5)(@types/node@22.14.1)(eslint@9.39.3(jiti@2.6.1))(jest-util@30.2.0)(prettier@3.8.1)(react-dom@18.3.1(react@18.3.1))(react-native@0.82.0(@babel/core@7.29.0)(@types/react@19.2.2)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + '@mendix/prettier-config-web-widgets': + specifier: workspace:* + version: link:../../shared/prettier-config-web-widgets + '@mendix/run-e2e': + specifier: workspace:* + version: link:../../../automation/run-e2e + '@mendix/widget-plugin-component-kit': + specifier: workspace:* + version: link:../../shared/widget-plugin-component-kit + '@mendix/widget-plugin-hooks': + specifier: workspace:* + version: link:../../shared/widget-plugin-hooks + '@mendix/widget-plugin-platform': + specifier: workspace:* + version: link:../../shared/widget-plugin-platform + '@mendix/widget-plugin-test-utils': + specifier: workspace:* + version: link:../../shared/widget-plugin-test-utils + packages/pluggableWidgets/skiplink-web: dependencies: '@floating-ui/react': @@ -3952,10 +3925,6 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@discoveryjs/json-ext@0.5.7': - resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} - engines: {node: '>=10.0.0'} - '@eslint-community/eslint-utils@4.9.0': resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4951,15 +4920,9 @@ packages: '@types/deep-equal@1.0.4': resolution: {integrity: sha512-tqdiS4otQP4KmY0PR3u6KbZ5EWvhNdUoS/jc93UuK23C220lOZ/9TvjfxdPcKvqwwDVtmtSCrnr0p/2dirAxkA==} - '@types/dojo@1.9.48': - resolution: {integrity: sha512-+/wltO++J0mmLoPa+mqElzilBahIfSY5Lz3o7RJkyIB0GDPnWhw3RUxU+xuZRCJE7uOFnNgqTdL76n/E0wDJ5w==} - '@types/enzyme@3.10.19': resolution: {integrity: sha512-kIfCo6/DdpgCHgmrLgPTugjzbZ46BUK8S2IP0kYo8+62LD2l1k8mSVsc+zQYNTdjDRoh2E9Spxu6F1NnEiW38Q==} - '@types/eslint-scope@3.7.7': - resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} - '@types/eslint@9.6.1': resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} @@ -5222,85 +5185,9 @@ packages: react: '>=18.0.0 <19.0.0' react-dom: '>=18.0.0 <19.0.0' - '@webassemblyjs/ast@1.14.1': - resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} - - '@webassemblyjs/floating-point-hex-parser@1.13.2': - resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} - - '@webassemblyjs/helper-api-error@1.13.2': - resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} - - '@webassemblyjs/helper-buffer@1.14.1': - resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} - - '@webassemblyjs/helper-numbers@1.13.2': - resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} - - '@webassemblyjs/helper-wasm-bytecode@1.13.2': - resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} - - '@webassemblyjs/helper-wasm-section@1.14.1': - resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} - - '@webassemblyjs/ieee754@1.13.2': - resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} - - '@webassemblyjs/leb128@1.13.2': - resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} - - '@webassemblyjs/utf8@1.13.2': - resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} - - '@webassemblyjs/wasm-edit@1.14.1': - resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} - - '@webassemblyjs/wasm-gen@1.14.1': - resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} - - '@webassemblyjs/wasm-opt@1.14.1': - resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} - - '@webassemblyjs/wasm-parser@1.14.1': - resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} - - '@webassemblyjs/wast-printer@1.14.1': - resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - - '@webpack-cli/configtest@2.1.1': - resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} - engines: {node: '>=14.15.0'} - peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x - - '@webpack-cli/info@2.0.2': - resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==} - engines: {node: '>=14.15.0'} - peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x - - '@webpack-cli/serve@2.0.5': - resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==} - engines: {node: '>=14.15.0'} - peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x - webpack-dev-server: '*' - peerDependenciesMeta: - webpack-dev-server: - optional: true - '@xml-tools/parser@1.0.11': resolution: {integrity: sha512-aKqQ077XnR+oQtHJlrAflaZaL7qZsulWc/i/ZEooar5JiWj1eLt0+Wg28cpa+XLney107wXqneC+oG1IZvxkTA==} - '@xtuc/ieee754@1.2.0': - resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} - - '@xtuc/long@4.2.2': - resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} - '@zxing/library@0.21.3': resolution: {integrity: sha512-hZHqFe2JyH/ZxviJZosZjV+2s6EDSY0O24R+FQmlWZBZXP9IqMo7S3nb3+2LBWxodJQkSurdQGnqE7KXqrYgow==} engines: {node: '>= 10.4.0'} @@ -5334,12 +5221,6 @@ packages: acorn-globals@7.0.1: resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} - acorn-import-phases@1.0.4: - resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} - engines: {node: '>=10.13.0'} - peerDependencies: - acorn: ^8.14.0 - acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -5372,14 +5253,6 @@ packages: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - ajv-formats@3.0.1: resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} peerDependencies: @@ -5388,11 +5261,6 @@ packages: ajv: optional: true - ajv-keywords@5.1.0: - resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} - peerDependencies: - ajv: ^8.8.2 - ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -5641,10 +5509,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - baseline-browser-mapping@2.8.16: - resolution: {integrity: sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==} - hasBin: true - big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} @@ -5700,11 +5564,6 @@ packages: brandi@5.0.0: resolution: {integrity: sha512-oztvITQgvuFb2K+NWdHLx0mMH8TGO3ASrQ43FZzmfiq5rCj0DRlsuZ6Efi/yeu3hyGx/Y+Z1xLGp2qzDWpiNYA==} - browserslist@4.26.3: - resolution: {integrity: sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - browserslist@4.28.1: resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -5757,9 +5616,6 @@ packages: caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} - caniuse-lite@1.0.30001750: - resolution: {integrity: sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ==} - caniuse-lite@1.0.30001778: resolution: {integrity: sha512-PN7uxFL+ExFJO61aVmP1aIEG4i9whQd4eoSCebav62UwDyp5OHh06zN4jqKSMePVgxHifCw1QJxdRkA1Pisekg==} @@ -5811,10 +5667,6 @@ packages: engines: {node: '>=12.13.0'} hasBin: true - chrome-trace-event@1.0.4: - resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} - engines: {node: '>=6.0'} - chromium-edge-launcher@0.2.0: resolution: {integrity: sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg==} @@ -5916,9 +5768,6 @@ packages: colorette@1.4.0: resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} - colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - colors@1.4.0: resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} engines: {node: '>=0.1.90'} @@ -6024,12 +5873,6 @@ packages: engines: {node: '>=10'} hasBin: true - copy-webpack-plugin@11.0.0: - resolution: {integrity: sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==} - engines: {node: '>= 14.15.0'} - peerDependencies: - webpack: ^5.1.0 - core-js-compat@3.46.0: resolution: {integrity: sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==} @@ -6118,18 +5961,6 @@ packages: css-global-keywords@1.0.1: resolution: {integrity: sha512-X1xgQhkZ9n94WDwntqst5D/FKkmiU0GlJSFZSV3kLvyJ1WC5VeyoXDOuleUD+SIuH9C7W05is++0Woh0CGfKjQ==} - css-loader@6.11.0: - resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} - engines: {node: '>= 12.13.0'} - peerDependencies: - '@rspack/core': 0.x || 1.x - webpack: ^5.0.0 - peerDependenciesMeta: - '@rspack/core': - optional: true - webpack: - optional: true - css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} @@ -6155,9 +5986,6 @@ packages: engines: {node: '>=4'} hasBin: true - cssfontparser@1.2.1: - resolution: {integrity: sha512-6tun4LoZnj7VN6YeegOVb67KBX/7JJsqvj+pv3ZA7F878/eN33AbGa5b/S/wXxS/tcp8nc40xRUrsPlxIyNUPg==} - cssnano-preset-default@5.2.14: resolution: {integrity: sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==} engines: {node: ^10 || ^12 || >=14.0} @@ -6518,9 +6346,6 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.237: - resolution: {integrity: sha512-icUt1NvfhGLar5lSWH3tHNzablaA5js3HVHacQimfP8ViEBOQv+L7DKEuHdbTZ0SKCO1ogTJTIL1Gwk9S6Qvcg==} - electron-to-chromium@1.5.313: resolution: {integrity: sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA==} @@ -6558,10 +6383,6 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.18.3: - resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} - engines: {node: '>=10.13.0'} - enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} @@ -6581,11 +6402,6 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} - envinfo@7.18.0: - resolution: {integrity: sha512-02QGCLRW+Jb8PC270ic02lat+N57iBaWsvHjcJViqp6UVupRB+Vsg7brYPTqEFXvsdTql3KnSczv5ModZFpl8Q==} - engines: {node: '>=4'} - hasBin: true - errno@0.1.8: resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} hasBin: true @@ -6615,9 +6431,6 @@ packages: resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} engines: {node: '>= 0.4'} - es-module-lexer@1.7.0: - resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} @@ -6957,10 +6770,6 @@ packages: resolution: {integrity: sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==} hasBin: true - fastest-levenshtein@1.0.16: - resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} - engines: {node: '>= 4.9.1'} - fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -7032,10 +6841,6 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} @@ -7199,9 +7004,6 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me @@ -7253,10 +7055,6 @@ packages: resolution: {integrity: sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==} engines: {node: '>=8'} - globby@13.2.2: - resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - glsl-inject-defines@1.0.3: resolution: {integrity: sha512-W49jIhuDtF6w+7wCMcClk27a2hq8znvHtlGnrYkSWEr8tHe9eA2dcnohlcAmxLYBSpSSdzOkRdyPTrx9fw49+A==} @@ -7526,10 +7324,6 @@ packages: resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} engines: {node: '>= 0.10'} - interpret@3.1.1: - resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} - engines: {node: '>=10.13.0'} - invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} @@ -7813,9 +7607,6 @@ packages: resolution: {integrity: sha512-YIThBuHzaIIcjxeuLmPD40SjxkEcc8i//sGMDKCgkRMVgIwRJf5qyExtlJpQeh7pkeoBSOe6lQEdg+/9uKg9mw==} hasBin: true - jest-canvas-mock@2.5.2: - resolution: {integrity: sha512-vgnpPupjOL6+L5oJXzxTxFrlGEIbHdZqFU+LFNdtLxZ3lRDCl17FlTMM7IatoRQkrcyOTMlDinjUguqmQ6bR2A==} - jest-changed-files@29.7.0: resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7972,10 +7763,6 @@ packages: resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - jest-worker@27.5.1: - resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} - engines: {node: '>= 10.13.0'} - jest-worker@29.7.0: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -8164,10 +7951,6 @@ packages: engines: {node: '>=8.0.0'} hasBin: true - loader-runner@4.3.1: - resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} - engines: {node: '>=6.11.5'} - loader-utils@1.4.2: resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==} engines: {node: '>=4.0.0'} @@ -8361,9 +8144,6 @@ packages: memoize-one@6.0.0: resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} - mendix-client@7.15.8: - resolution: {integrity: sha512-RazCdCHoLVNKUUeKDkSkIL6Lxx6fUaa4iiy+Ltp9ra8mLQhwyNqD33TIN7YZJ3HDjHc3eWh9cjiZWwh6Jg/cQg==} - mendix@10.24.75382: resolution: {integrity: sha512-ICMxqkWUejsc3KeFD9BJYvC+T4soi/NB2iapwWPC7oN0lCrFx36upzwI4rU77oMdRHsrVSsFVYLBy7sJJOABHw==} @@ -8498,12 +8278,6 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - mini-css-extract-plugin@2.9.4: - resolution: {integrity: sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==} - engines: {node: '>= 12.13.0'} - peerDependencies: - webpack: ^5.0.0 - mini-svg-data-uri@1.4.4: resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} hasBin: true @@ -8571,9 +8345,6 @@ packages: moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} - moo-color@1.0.3: - resolution: {integrity: sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==} - mouse-change@1.4.0: resolution: {integrity: sha512-vpN0s+zLL2ykyyUDh+fayu9Xkor5v/zRD9jhSqjRS1cJTGS0+oakVZzNm5n19JvvEj0you+MXlYTpNxUDQUjkQ==} @@ -8660,9 +8431,6 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-releases@2.0.23: - resolution: {integrity: sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==} - node-releases@2.0.36: resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} @@ -9562,10 +9330,6 @@ packages: resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} engines: {node: '>= 0.10'} - rechoir@0.8.0: - resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} - engines: {node: '>= 10.13.0'} - recursive-copy@2.0.14: resolution: {integrity: sha512-K8WNY8f8naTpfbA+RaXmkaQuD1IeW9EgNEfyGxSqqTQukpVtoOKros9jUqbpEsSw59YOmpd8nCBgtqJZy5nvog==} @@ -9782,25 +9546,6 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass-loader@13.3.3: - resolution: {integrity: sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==} - engines: {node: '>= 14.15.0'} - peerDependencies: - fibers: '>= 3.1.0' - node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - sass: ^1.3.0 - sass-embedded: '*' - webpack: ^5.0.0 - peerDependenciesMeta: - fibers: - optional: true - node-sass: - optional: true - sass: - optional: true - sass-embedded: - optional: true - sass@1.93.2: resolution: {integrity: sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==} engines: {node: '>=14.0.0'} @@ -9823,10 +9568,6 @@ packages: scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - schema-utils@4.3.3: - resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} - engines: {node: '>= 10.13.0'} - semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -9971,10 +9712,6 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slash@4.0.0: - resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} - engines: {node: '>=12'} - smob@1.5.0: resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} @@ -10007,10 +9744,6 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} - spawn-command@0.0.2: resolution: {integrity: sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==} @@ -10245,10 +9978,6 @@ packages: tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} - tapable@2.3.0: - resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} - engines: {node: '>=6'} - tar-fs@2.1.4: resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} @@ -10256,22 +9985,6 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} - terser-webpack-plugin@5.3.14: - resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@swc/core': '*' - esbuild: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - esbuild: - optional: true - uglify-js: - optional: true - terser@5.44.0: resolution: {integrity: sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==} engines: {node: '>=10'} @@ -10341,9 +10054,6 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - to-string-loader@1.2.0: - resolution: {integrity: sha512-KsWUL8FccgBW9FPFm4vYoQbOOcO5m6hKOGYoXjbseD9/4Ft+ravXN5jolQ9kTKYcK4zPt1j+khx97GPGnVoi6A==} - toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -10404,13 +10114,6 @@ packages: jest-util: optional: true - ts-loader@9.5.4: - resolution: {integrity: sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==} - engines: {node: '>=12.0.0'} - peerDependencies: - typescript: '>5.8.0' - webpack: ^5.0.0 - ts-node@10.9.2: resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true @@ -10596,12 +10299,6 @@ packages: unquote@1.1.1: resolution: {integrity: sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==} - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -10679,10 +10376,6 @@ packages: warning@4.0.3: resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} - watchpack@2.4.4: - resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} - engines: {node: '>=10.13.0'} - wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} @@ -10703,41 +10396,6 @@ packages: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} - webpack-cli@5.1.4: - resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==} - engines: {node: '>=14.15.0'} - hasBin: true - peerDependencies: - '@webpack-cli/generators': '*' - webpack: 5.x.x - webpack-bundle-analyzer: '*' - webpack-dev-server: '*' - peerDependenciesMeta: - '@webpack-cli/generators': - optional: true - webpack-bundle-analyzer: - optional: true - webpack-dev-server: - optional: true - - webpack-merge@5.10.0: - resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} - engines: {node: '>=10.0.0'} - - webpack-sources@3.3.3: - resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} - engines: {node: '>=10.13.0'} - - webpack@5.102.1: - resolution: {integrity: sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - whatwg-encoding@2.0.0: resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} engines: {node: '>=12'} @@ -10783,9 +10441,6 @@ packages: engines: {node: ^16.13.0 || >=18.0.0} hasBin: true - wildcard@2.0.1: - resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} - word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -11011,8 +10666,8 @@ snapshots: '@babel/generator@7.28.3': dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 @@ -11229,22 +10884,22 @@ snapshots: '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.29.0)': dependencies: @@ -11269,67 +10924,67 @@ snapshots: '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.29.0)': dependencies: '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': dependencies: @@ -11872,8 +11527,8 @@ snapshots: '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.29.0 - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@babel/template@7.28.6': dependencies: @@ -12134,8 +11789,6 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@discoveryjs/json-ext@0.5.7': {} - '@eslint-community/eslint-utils@4.9.0(eslint@9.39.3(jiti@2.6.1))': dependencies: eslint: 9.39.3(jiti@2.6.1) @@ -12625,7 +12278,7 @@ snapshots: identity-obj-proxy: 3.0.0 jasmine: 3.99.0 jasmine-core: 3.99.1 - jest: 29.7.0(@types/node@22.14.1)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.14.1)(typescript@5.9.3)) + jest: 29.7.0(@types/node@22.14.1) jest-environment-jsdom: 29.7.0 jest-jasmine2: 29.7.0 jest-junit: 13.2.0 @@ -13300,7 +12953,7 @@ snapshots: react-test-renderer: 19.2.4(react@18.3.1) redent: 3.0.0 optionalDependencies: - jest: 29.7.0(@types/node@22.14.1)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.14.1)(typescript@5.9.3)) + jest: 29.7.0(@types/node@22.14.1) '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -13364,24 +13017,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.28.0 '@types/babel__generator@7.27.0': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.29.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.4 - '@babel/types': 7.28.4 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__traverse@7.28.0': dependencies: - '@babel/types': 7.28.4 + '@babel/types': 7.29.0 '@types/big.js@6.2.2': {} @@ -13399,22 +13052,16 @@ snapshots: '@types/deep-equal@1.0.4': {} - '@types/dojo@1.9.48': {} - '@types/enzyme@3.10.19': dependencies: '@types/cheerio': 0.22.35 '@types/react': 19.2.2 - '@types/eslint-scope@3.7.7': - dependencies: - '@types/eslint': 9.6.1 - '@types/estree': 1.0.8 - '@types/eslint@9.6.1': dependencies: '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 + optional: true '@types/estree@1.0.8': {} @@ -13779,105 +13426,10 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@webassemblyjs/ast@1.14.1': - dependencies: - '@webassemblyjs/helper-numbers': 1.13.2 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - - '@webassemblyjs/floating-point-hex-parser@1.13.2': {} - - '@webassemblyjs/helper-api-error@1.13.2': {} - - '@webassemblyjs/helper-buffer@1.14.1': {} - - '@webassemblyjs/helper-numbers@1.13.2': - dependencies: - '@webassemblyjs/floating-point-hex-parser': 1.13.2 - '@webassemblyjs/helper-api-error': 1.13.2 - '@xtuc/long': 4.2.2 - - '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} - - '@webassemblyjs/helper-wasm-section@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/wasm-gen': 1.14.1 - - '@webassemblyjs/ieee754@1.13.2': - dependencies: - '@xtuc/ieee754': 1.2.0 - - '@webassemblyjs/leb128@1.13.2': - dependencies: - '@xtuc/long': 4.2.2 - - '@webassemblyjs/utf8@1.13.2': {} - - '@webassemblyjs/wasm-edit@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/helper-wasm-section': 1.14.1 - '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/wasm-opt': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - '@webassemblyjs/wast-printer': 1.14.1 - - '@webassemblyjs/wasm-gen@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/ieee754': 1.13.2 - '@webassemblyjs/leb128': 1.13.2 - '@webassemblyjs/utf8': 1.13.2 - - '@webassemblyjs/wasm-opt@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - - '@webassemblyjs/wasm-parser@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-api-error': 1.13.2 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/ieee754': 1.13.2 - '@webassemblyjs/leb128': 1.13.2 - '@webassemblyjs/utf8': 1.13.2 - - '@webassemblyjs/wast-printer@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@xtuc/long': 4.2.2 - - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.102.1)': - dependencies: - webpack: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.102.1) - - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.102.1)': - dependencies: - webpack: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.102.1) - - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack@5.102.1)': - dependencies: - webpack: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack@5.102.1) - '@xml-tools/parser@1.0.11': dependencies: chevrotain: 7.1.1 - '@xtuc/ieee754@1.2.0': {} - - '@xtuc/long@4.2.2': {} - '@zxing/library@0.21.3': dependencies: ts-custom-error: 3.3.1 @@ -13912,10 +13464,6 @@ snapshots: acorn: 8.15.0 acorn-walk: 8.3.4 - acorn-import-phases@1.0.4(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -13942,19 +13490,10 @@ snapshots: agent-base@7.1.4: {} - ajv-formats@2.1.1(ajv@8.17.1): - optionalDependencies: - ajv: 8.17.1 - ajv-formats@3.0.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 - ajv-keywords@5.1.0(ajv@8.17.1): - dependencies: - ajv: 8.17.1 - fast-deep-equal: 3.1.3 - ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -14169,7 +13708,7 @@ snapshots: babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -14179,8 +13718,8 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.4 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.28.0 @@ -14257,8 +13796,6 @@ snapshots: baseline-browser-mapping@2.10.0: {} - baseline-browser-mapping@2.8.16: {} - big.js@5.2.2: {} big.js@6.2.2: {} @@ -14322,14 +13859,6 @@ snapshots: brandi@5.0.0: {} - browserslist@4.26.3: - dependencies: - baseline-browser-mapping: 2.8.16 - caniuse-lite: 1.0.30001750 - electron-to-chromium: 1.5.237 - node-releases: 2.0.23 - update-browserslist-db: 1.1.3(browserslist@4.26.3) - browserslist@4.28.1: dependencies: baseline-browser-mapping: 2.10.0 @@ -14382,13 +13911,11 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.26.3 - caniuse-lite: 1.0.30001750 + browserslist: 4.28.1 + caniuse-lite: 1.0.30001778 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 - caniuse-lite@1.0.30001750: {} - caniuse-lite@1.0.30001778: {} canvas-fit@1.5.0: @@ -14451,8 +13978,6 @@ snapshots: transitivePeerDependencies: - supports-color - chrome-trace-event@1.0.4: {} - chromium-edge-launcher@0.2.0: dependencies: '@types/node': 22.14.1 @@ -14568,8 +14093,6 @@ snapshots: colorette@1.4.0: {} - colorette@2.0.20: {} - colors@1.4.0: {} combined-stream@1.0.8: @@ -14676,16 +14199,6 @@ snapshots: glob: 10.5.0 glob-parent: 6.0.2 - copy-webpack-plugin@11.0.0(webpack@5.102.1): - dependencies: - fast-glob: 3.3.3 - glob-parent: 6.0.2 - globby: 13.2.2 - normalize-path: 3.0.0 - schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - webpack: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - core-js-compat@3.46.0: dependencies: browserslist: 4.28.1 @@ -14783,19 +14296,6 @@ snapshots: css-global-keywords@1.0.1: {} - css-loader@6.11.0(webpack@5.102.1): - dependencies: - icss-utils: 5.1.0(postcss@8.5.6) - postcss: 8.5.6 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.6) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.6) - postcss-modules-scope: 3.2.1(postcss@8.5.6) - postcss-modules-values: 4.0.0(postcss@8.5.6) - postcss-value-parser: 4.2.0 - semver: 7.7.3 - optionalDependencies: - webpack: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - css-select@4.3.0: dependencies: boolbase: 1.0.0 @@ -14819,8 +14319,6 @@ snapshots: cssesc@3.0.0: {} - cssfontparser@1.2.1: {} - cssnano-preset-default@5.2.14(postcss@8.5.6): dependencies: css-declaration-sorter: 6.4.1(postcss@8.5.6) @@ -15201,8 +14699,6 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.237: {} - electron-to-chromium@1.5.313: {} element-size@1.1.1: {} @@ -15229,11 +14725,6 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.18.3: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.0 - enquirer@2.4.1: dependencies: ansi-colors: 4.1.3 @@ -15247,8 +14738,6 @@ snapshots: env-paths@2.2.1: {} - envinfo@7.18.0: {} - errno@0.1.8: dependencies: prr: 1.0.1 @@ -15353,8 +14842,6 @@ snapshots: iterator.prototype: 1.1.5 safe-array-concat: 1.1.3 - es-module-lexer@1.7.0: {} - es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 @@ -15789,8 +15276,6 @@ snapshots: dependencies: strnum: 1.1.2 - fastest-levenshtein@1.0.16: {} - fastq@1.19.1: dependencies: reusify: 1.1.0 @@ -15880,8 +15365,6 @@ snapshots: flatted: 3.4.2 keyv: 4.5.4 - flat@5.0.2: {} - flatted@3.4.2: {} flatten-vertex-data@1.0.2: @@ -16067,8 +15550,6 @@ snapshots: dependencies: is-glob: 4.0.3 - glob-to-regexp@0.4.1: {} - glob@10.5.0: dependencies: foreground-child: 3.3.1 @@ -16137,14 +15618,6 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 - globby@13.2.2: - dependencies: - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 4.0.0 - glsl-inject-defines@1.0.3: dependencies: glsl-token-inject-block: 1.1.0 @@ -16440,8 +15913,6 @@ snapshots: interpret@1.4.0: {} - interpret@3.1.1: {} - invariant@2.2.4: dependencies: loose-envify: 1.4.0 @@ -16648,7 +16119,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.29.0 - '@babel/parser': 7.28.4 + '@babel/parser': 7.29.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -16658,7 +16129,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 7.29.0 - '@babel/parser': 7.28.4 + '@babel/parser': 7.29.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.7.4 @@ -16710,11 +16181,6 @@ snapshots: glob: 7.2.3 jasmine-core: 3.99.1 - jest-canvas-mock@2.5.2: - dependencies: - cssfontparser: 1.2.1 - moo-color: 1.0.3 - jest-changed-files@29.7.0: dependencies: execa: 5.1.1 @@ -17092,12 +16558,6 @@ snapshots: jest-util: 29.7.0 string-length: 4.0.2 - jest-worker@27.5.1: - dependencies: - '@types/node': 22.14.1 - merge-stream: 2.0.0 - supports-color: 8.1.1 - jest-worker@29.7.0: dependencies: '@types/node': 22.14.1 @@ -17105,6 +16565,18 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 + jest@29.7.0(@types/node@22.14.1): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.14.1)(typescript@5.9.3)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@22.14.1)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.14.1)(typescript@5.9.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest@29.7.0(@types/node@22.14.1)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.14.1)(typescript@5.9.3)): dependencies: '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.14.1)(typescript@5.9.3)) @@ -17321,8 +16793,6 @@ snapshots: - bufferutil - utf-8-validate - loader-runner@4.3.1: {} - loader-utils@1.4.2: dependencies: big.js: 5.2.2 @@ -17537,11 +17007,6 @@ snapshots: memoize-one@6.0.0: {} - mendix-client@7.15.8: - dependencies: - '@types/big.js': 6.2.2 - '@types/dojo': 1.9.48 - mendix@10.24.75382: dependencies: '@types/big.js': 6.2.2 @@ -17768,12 +17233,6 @@ snapshots: min-indent@1.0.1: {} - mini-css-extract-plugin@2.9.4(webpack@5.102.1): - dependencies: - schema-utils: 4.3.3 - tapable: 2.3.0 - webpack: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - mini-svg-data-uri@1.4.4: {} minimatch@10.2.4: @@ -17840,10 +17299,6 @@ snapshots: moment@2.30.1: {} - moo-color@1.0.3: - dependencies: - color-name: 1.1.4 - mouse-change@1.4.0: dependencies: mouse-event: 1.0.5 @@ -17913,8 +17368,6 @@ snapshots: node-int64@0.4.0: {} - node-releases@2.0.23: {} - node-releases@2.0.36: {} nopt@7.2.1: @@ -18286,7 +17739,7 @@ snapshots: postcss-colormin@5.3.1(postcss@8.5.6): dependencies: - browserslist: 4.26.3 + browserslist: 4.28.1 caniuse-api: 3.0.0 colord: 2.9.3 postcss: 8.5.6 @@ -18294,7 +17747,7 @@ snapshots: postcss-convert-values@5.1.3(postcss@8.5.6): dependencies: - browserslist: 4.26.3 + browserslist: 4.28.1 postcss: 8.5.6 postcss-value-parser: 4.2.0 @@ -18344,7 +17797,7 @@ snapshots: postcss-merge-rules@5.1.4(postcss@8.5.6): dependencies: - browserslist: 4.26.3 + browserslist: 4.28.1 caniuse-api: 3.0.0 cssnano-utils: 3.1.0(postcss@8.5.6) postcss: 8.5.6 @@ -18364,7 +17817,7 @@ snapshots: postcss-minify-params@5.1.4(postcss@8.5.6): dependencies: - browserslist: 4.26.3 + browserslist: 4.28.1 cssnano-utils: 3.1.0(postcss@8.5.6) postcss: 8.5.6 postcss-value-parser: 4.2.0 @@ -18438,7 +17891,7 @@ snapshots: postcss-normalize-unicode@5.1.1(postcss@8.5.6): dependencies: - browserslist: 4.26.3 + browserslist: 4.28.1 postcss: 8.5.6 postcss-value-parser: 4.2.0 @@ -18461,7 +17914,7 @@ snapshots: postcss-reduce-initial@5.1.2(postcss@8.5.6): dependencies: - browserslist: 4.26.3 + browserslist: 4.28.1 caniuse-api: 3.0.0 postcss: 8.5.6 @@ -18973,10 +18426,6 @@ snapshots: dependencies: resolve: 1.22.10 - rechoir@0.8.0: - dependencies: - resolve: 1.22.11 - recursive-copy@2.0.14: dependencies: errno: 0.1.8 @@ -19301,13 +18750,6 @@ snapshots: safer-buffer@2.1.2: {} - sass-loader@13.3.3(sass@1.93.2)(webpack@5.102.1): - dependencies: - neo-async: 2.6.2 - webpack: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - optionalDependencies: - sass: 1.93.2 - sass@1.93.2: dependencies: chokidar: 4.0.3 @@ -19330,13 +18772,6 @@ snapshots: scheduler@0.27.0: {} - schema-utils@4.3.3: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - ajv-keywords: 5.1.0(ajv@8.17.1) - semver@5.7.2: {} semver@6.3.1: {} @@ -19517,8 +18952,6 @@ snapshots: slash@3.0.0: {} - slash@4.0.0: {} - smob@1.5.0: {} sort-object-keys@1.1.3: {} @@ -19551,8 +18984,6 @@ snapshots: source-map@0.6.1: {} - source-map@0.7.6: {} - spawn-command@0.0.2: {} spdx-compare@1.0.0: @@ -19744,7 +19175,7 @@ snapshots: stylehacks@5.1.1(postcss@8.5.6): dependencies: - browserslist: 4.26.3 + browserslist: 4.28.1 postcss: 8.5.6 postcss-selector-parser: 6.1.2 @@ -19811,8 +19242,6 @@ snapshots: tabbable@6.2.0: {} - tapable@2.3.0: {} - tar-fs@2.1.4: dependencies: chownr: 1.1.4 @@ -19829,17 +19258,6 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - terser-webpack-plugin@5.3.14(@swc/core@1.13.5)(webpack@5.102.1): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - jest-worker: 27.5.1 - schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - terser: 5.44.0 - webpack: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - optionalDependencies: - '@swc/core': 1.13.5 - terser@5.44.0: dependencies: '@jridgewell/source-map': 0.3.11 @@ -19907,10 +19325,6 @@ snapshots: dependencies: is-number: 7.0.0 - to-string-loader@1.2.0: - dependencies: - loader-utils: 1.4.2 - toidentifier@1.0.1: {} topojson-client@3.1.0: @@ -19943,7 +19357,7 @@ snapshots: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 handlebars: 4.7.8 - jest: 29.7.0(@types/node@22.14.1)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.14.1)(typescript@5.9.3)) + jest: 29.7.0(@types/node@22.14.1) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 @@ -19958,16 +19372,6 @@ snapshots: babel-jest: 29.7.0(@babel/core@7.29.0) jest-util: 30.2.0 - ts-loader@9.5.4(typescript@5.9.3)(webpack@5.102.1): - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.18.3 - micromatch: 4.0.8 - semver: 7.7.3 - source-map: 0.7.6 - typescript: 5.9.3 - webpack: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.14.1)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -20154,12 +19558,6 @@ snapshots: unquote@1.1.1: {} - update-browserslist-db@1.1.3(browserslist@4.26.3): - dependencies: - browserslist: 4.26.3 - escalade: 3.2.0 - picocolors: 1.1.1 - update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: browserslist: 4.28.1 @@ -20236,11 +19634,6 @@ snapshots: dependencies: loose-envify: 1.4.0 - watchpack@2.4.4: - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - wcwidth@1.0.1: dependencies: defaults: 1.0.4 @@ -20257,65 +19650,6 @@ snapshots: webidl-conversions@7.0.0: {} - webpack-cli@5.1.4(webpack@5.102.1): - dependencies: - '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.102.1) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.102.1) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack@5.102.1) - colorette: 2.0.20 - commander: 10.0.1 - cross-spawn: 7.0.6 - envinfo: 7.18.0 - fastest-levenshtein: 1.0.16 - import-local: 3.2.0 - interpret: 3.1.1 - rechoir: 0.8.0 - webpack: 5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4) - webpack-merge: 5.10.0 - - webpack-merge@5.10.0: - dependencies: - clone-deep: 4.0.1 - flat: 5.0.2 - wildcard: 2.0.1 - - webpack-sources@3.3.3: {} - - webpack@5.102.1(@swc/core@1.13.5)(webpack-cli@5.1.4): - dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.15.0 - acorn-import-phases: 1.0.4(acorn@8.15.0) - browserslist: 4.26.3 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.3 - es-module-lexer: 1.7.0 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.1 - mime-types: 2.1.35(patch_hash=f54449b9273bc9e74fb67a14fcd001639d788d038b7eb0b5f43c10dff2b1adfb) - neo-async: 2.6.2 - schema-utils: 4.3.3 - tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(@swc/core@1.13.5)(webpack@5.102.1) - watchpack: 2.4.4 - webpack-sources: 3.3.3 - optionalDependencies: - webpack-cli: 5.1.4(webpack@5.102.1) - transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - whatwg-encoding@2.0.0: dependencies: iconv-lite: 0.6.3 @@ -20383,8 +19717,6 @@ snapshots: dependencies: isexe: 3.1.5 - wildcard@2.0.1: {} - word-wrap@1.2.5: {} wordwrap@1.0.0: {}